fix(partition): çoklu disk kurulumu — veri kaybı hatası, disk seçici, doğrulama

Kullanıcı Linux bölümlerini ayrı disklere dağıtabilmeli. Veri modeli
(ö. `CustomPartition.disk`) çoklu diski destekliyordu; UI ve job
katmanındaki boşluklar bu işi kullanamaz hale getiriyordu.

## 1. VERİ KAYBI: bölüm numaraları ayrışıyordu (jobs/partition.rs)

Asıl bulgu. Bölüm numarası İKİ AYRI YERDE bağımsız hesaplanıyordu:
  - UI: assign_partition_numbers → "en küçük boş slot"
  - Job: mkpart + part.device okuması

`parted rm` silinen bölümden sonrakileri kaydırır ve mkpart yeni
bölümü başlangıç offset'ine göre yerleştirir. Aradaki boşluk
istenen boyuta SIĞMADIĞINDA mkpart diskin sonuna yazıyor, kernel yeni
bölüme 3 veriyor — UI ise 2 demişti. FAZ C mkfs'i o aygıta
uyguluyordu, yani kullanıcının KORUMAK İSTEDİĞİ bölüm
biçimlendiriliyordu.

  - `plan_disk_layout()`: saf, test edilebilir bir fonksiyon. Diskin
    tamamını (fiziksel + yeni) görüp başlangıç offset'ine göre
    numaralandırıyor; hem yeni bölümlerin hem de silmeden sonra
    KAYAN fiziksel bölümlerin gerçek yollarını döndürüyor.
  - FAZ B artık tahmin yürütmüyor, bu planı kullanıyor.
  - FAZ C `device_map` üzerinden GERÇEK aygıtı kullanıyor; kayma
    olduğunda loglayıp doğru aygıta işliyor.
  - `disk_free_regions_mb` (aynı mantığın eski, ayrı kopyası) silindi.
  - `disk_total_mb` ve `read_physical_extents` eklendi; artık diskin
    gerçek boyutunu sysfs'ten okuyor (önce son bölümün bitişinden
    tahmin yürütülüyordu).

11 test, bunların içinde asıl regresyonu kilitleyen:
  delete_plus_create_renumbers_physical_partitions,
  deleting_on_one_disk_does_not_renumber_another,
  layouts_are_independent_per_disk.

## 2. Ekleme diyaloğunda disk seçici YOKTU (steps/partition.rs)

Yeni bölümün diski `state.selected_disk`'e SABİTLENİYORDU ve diyalogda
hiçbir disk kontrolü bulunmuyordu. /home'u sdb'ye koymak isteyen
kullanıcı, kurulumun GRUB hedefini de değiştirmek zorundaydı
(`selected_disk` aynı zamanda `build_custom_job_queue`'un girdisi).

  - `ManualState::add_disk` + diyaloga disk seçici
  - Düzenlemede de değiştirilebilir: bölümü başka diske taşımanın
    yolu. Taşınırsa `orig_device` temizlenir, yoksa job eski diske
    işlem yapmayı sürdürürdü.
  - Varsayılan öneriler (EFI/root/swap) artık AKTİF diskin durumuna
    göre veriliyor; önce her zaman aktif diskin bölüm sayımı
    kullanılıyordu, yeni diske geçince alakasız öneri çıkıyordu.

## 3. Hiç bölümü olmayan diskler tabloda GİZLİYDİ (steps/partition.rs)

`seen_disks` yalnızca `custom_partitions` içinden kuruluyordu. Yeni
veya bölüm tablosu olmayan bir disk ne başlık ne boş-alan satırı
gösteriyordu — kullanıcı "sdb'de ne var?" diye bakamıyor, dolayısıyla
oraya bölüm koymanın yolunu da göremiyordu. Artık `available_disks`
taranıyor ve tanımsız disklere boş-alan satırı basılıyor.

Bu satır `first_idx: None` taşıyor: tıklanırsa `selected_idx = 0`
olur ve kullanıcı BAŞKA diskin ilk bölümü seçilmiş olurdu.

## 4. Kapasite doğrulaması yanlış listeyi geziyordu (steps/partition.rs)

`manual_capacity_error` `available_disks` üzerinde yürüyordu; o
listede olmayan diske yapılan tanım hiç kontrol edilmeden geçiyordu.
Artık bölüm tanımlarının kendi `disk` alanından yürüyor.

Ayrıca "disk bağlı değil" ile "kapasite aşıldı" ayrıldı:
validate_manual_on(..., &disks) diskin gerçekten var olduğunu
kontrol ediyor, kapasite hesabı yalnızca bilinen disklerde yapılıyor
(0 MB kapasiteyle "aşıyor" demek yanıltıcıydı).

Yeni kontroller: birden fazla kök (/), disksiz tanım, bağlı olmayan
disk.

## 5. LVM PV mount ediliyordu (jobs/partition.rs)

Diyalog her tanım için mountpoint zorunlu kılıyordu; PV'nin
mountpoint'i vardı, MountCustomPartitionsJob onu mount'lamaya
çalışıyordu ("wrong fs type" → kurulumun tamamı düşüyordu) ve
FstabFromCustomPartitionsJob fstab'a ext4 satırı yazıyordu.
Artık PV mount edilmiyor, fstab'a girmiyor, mountpoint'i de
zorunlu değil.

## 6. prepare_disk seyrek düzende bölüm çözmüyordu (jobs/partition.rs)

`1..=32` numaralandırılıp İLK EKSİK bölümde `break` ediliyordu.
sda1 + sda3 olan bir diskte döngü n=2'de duruyor, sda3 hiç çözülmüyor
→ bağlı kalan bölüm yüzünden `parted mkpart` "device busy" veriyordu.
Artık gerçek bölümler lsblk'den alınıyor.

## 7. GRUB yedek yapılandırması kökü tahmin ediyordu (jobs/bootloader.rs)

generate_minimal_grub_cfg kök aygıtını `is_uefi` ile (3|2) ve seçili
disk üzerinden buluyordu. Manuel modda numaralar
assign_partition_numbers'tan gelir, üstelik kök başka bir diskte
olabilir. Artık `mounted_root_device()` ile mount noktasının arkasındaki
gerçek aygıt soruluyor. BIOS'taki sabit `set root=(hd0,msdos2)` de
gerçek kök aygıtının bölüm numarasından geliyor.

## Testler
+22: 11 plan/numaralandırma, 10 çoklu disk doğrulama, 1 LVM PV.
steps/partition.rs'te disk() ve part() yardımcıları iki test modülü
ortak kullandığı için testutil modülüne taşındı.

cargo check --all-targets : 0 hata, 0 uyarı
cargo test              : 76/76 geçti (55 → 76)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erkan IŞIK
2026-09-25 23:54:27 +03:00
parent 8d652c3a99
commit 4c68c5018e
5 changed files with 1210 additions and 183 deletions
+5
View File
@@ -119,11 +119,16 @@ summary_partition_plan = "Bölümleme"
summary_custom_partitions = "Manuel Bölümler"
mp_size_remaining = "Kalan Alan"
mp_size_available = "Kullanılabilir"
mp_target_disk = "Hedef disk"
mp_target_disk_hint = "Bu bölümün yerleşeceği disk. Kök diski değiştirmeden /home gibi bölümleri ayrı bir diske koyabilirsiniz."
mp_create_here = "Buraya Oluştur"
mp_will_delete = "silinecek"
mp_restore = "Geri Al"
mp_free_space = "Boş Alan"
mp_duplicate_mountpoint = "Aynı bağlama noktası iki bölüme birden verilmiş; her bölümün farklı bir bağlama noktası olmalı"
mp_multiple_root = "Birden fazla bölüm kök (/) olarak tanımlanmış: {disks}. Kök tek bir bölüm olmalı"
mp_partition_no_disk = "Bir bölüm tanımı için disk seçilmemiş. Her bölümün yerleşeceği diski seçin."
mp_disk_not_found = "{disk} artık bağlı değil. Bu diske yapılan bölüm tanımını kaldırın ya da diski yeniden bağlayın."
mp_bar_now = "Mevcut Durum"
mp_bar_after = "Kurulum Sonrası"