向左擴展分區後將文件系統向左移動
TL;博士
我有一個具有多個分區的
dd
圖像。disk.dd
最終目標是減小此dd
圖像文件的大小。在刪除並重新創建一個編號
start sector offset
比以前低的分區後(即向左擴展分區)我有一個分區,其中有一個文件系統,它primary superblock
位於該分區內的某個位置,我知道哪個扇區這primary superblock
住。我怎樣才能讓
e2fsck
這個文件系統移動到分區的開頭?這樣之後我就可以縮小這個文件系統,
resize2fs
然後從右邊縮小這個分區,即(用較低的重新創建這個分區end sector offset
)然後我將在之後的分區上重複這個過程,直到最後一個分區,有效地縮小所有分區,從而減小
dd
圖像的大小請不要建議
gparted
。我正在尋找命令行解決方案另外,我知道使用
LVM
. 但是這個遺留系統長版
我有一個
disk.dd
使用以下內容拍攝的 dd 圖像dd if=/dev/sda of=/path/to/disk.dd
具有以下佈局的系統
Disk /dev/loop15: 465.78 GiB, 500107862016 bytes, 976773168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x54093dd5 Device Boot Start End Sectors Size Id Type /dev/loop15p1 * 2048 81922047 81920000 39.1G 83 Linux /dev/loop15p2 81922048 143362047 61440000 29.3G 82 Linux swap / Solaris /dev/loop15p3 143362048 163842047 20480000 9.8G 83 Linux /dev/loop15p4 163842048 976773167 812931120 387.7G 5 Extended /dev/loop15p5 163844096 976773119 812929024 387.7G 83 Linux
現在,在不同的系統上,我
disk.dd
通過循環設備使用losetup --find --partscan disk.dd
我調整了所有
ext4
文件系統的大小resize2fs -M /dev/loopNpartX resize2fs /dev/loopNpartX FSsize
即分區
p1
,p3
和p5
有了
dumpe2fs
,我可以看到logical block size
文件系統,它是4096
所有文件系統的字節ext4
,在我上面顯示的情況下,這些文件系統託管在 3 個分區上現在,如果我在口頭上正確閱讀此內容(如果我在這裡錯了,請糾正我)
文件系統的主超級塊“通常預期”位於
0
分區的塊中所以,我可以轉儲超級塊資訊
dumpe2fs -h -o superblock=0 -o blocksize=4096 /dev/loopNpartX
現在是時候縮小分區以減小
disk.dd
文件大小了我
block count
再次使用每個文件系統dumpe2fs
fdisk
適用於設備的physical block size
ORsectors
,在我的情況下是512
字節因此,為了找到
sectors
足以容納文件系統的數量,我使用了以下公式Required Sectors = ( ( Block Count + 100 ) * Logical Block Size ) / Physical Block Size
100
充當緩衝區,以防萬一我遺漏了有關文件系統組織的一些內容,這應該足夠了我對每個文件系統都這樣做了
現在
有了
lsblk -f
,我得到了現有文件系統的 UUID使用
fdisk -l
,我得到要保持打開的boot flag
分區現在要縮小分區,我將使用刪除並重新創建它們
fdisk
– 第一個分區
start sector offset = 2048 last sector offset = 2048 + "Required Sectors" for this filesystem
– 第二分區
現有磁碟上的第二個分區是
swap
,所以我不會縮小它,只是將它向左移動start sector offset = "last sector offset" of first partition + 1 last sector offset = "start sector offset" + Total sectors as as on existing partition
然後我將其類型更改為
Swap
然後tune2fs -U
將 UUID 更改回dd
圖像上的內容– 第三分區
start sector offset = "last sector offset" of second partition + 1 last sector offset = "start sector offset" + "Required Sectors" for this filesystem
這是我卡住的地方
將第三個分區向左擴展後,該分區有一個文件系統,我知道它的起始扇區(即具有 的扇區
primary superblock
)但我不知道如何讓
e2fsck
這個文件系統在分區上更正它,以便文件系統向左移動到分區的開頭
fsck 是不可能的。在文件系統中,所有東西都有偏移量,如果你改變起始扇區,所有這些偏移量都會改變。fsck 根本無法重寫所有內容(超級塊、日誌、目錄、文件段等)的所有偏移量。即使你能做到這一點,它也只有在新的起始扇區與內部文件系統結構一致的情況下才會起作用。
所以這沒有完成。
相反,您必須使用 dd 將所有數據向左移動(本質上是 gparted 所做的)。只有完全移動文件系統,其中的偏移量才能保持不變。
原則上 dd 命令可以像這樣工作。它以不同的偏移量讀取和寫入同一設備。這僅適用於向左移動,因此 seek(寫入)必須小於skip(讀取)。512b 扇區中的所有單元(如果您指定
bs=1M
,則您的分區必須是 MiB 對齊的,並且所有單元都在 MiB 中)dd if=/dev/sdx of=/dev/sdx \ seek=newpartitionstart \ skip=oldpartitionstart \ count=filesystemsize
但是,這是非常危險的。*需要您自擔風險使用它。*請務必花時間先備份您的數據。
向右移動會更複雜。您必須向後工作,否則您會覆蓋尚未讀取的數據,並破壞過程中的所有內容。
我所知道的(或多或少)不移動數據的唯一工具是
blocks --lvmify
,它通過將現有文件系統分區轉換為 LVM 來實現。使用 LVM,您可以在邏輯上向右擴展,而它在物理上儲存在左側。如果沒有 LVM,您也可以手動設置線性設備映射,但您會遇到非標準解決方案。解決此類問題(如果您不想使用 gparted)最明智的方法是備份所有數據,然後以您喜歡的任何佈局創建新的分區和文件系統,然後恢復您的數據。
如果此 dd 映像是您的備份解決方案,請考慮改為備份文件。磁碟映像可能很難處理,特別是如果您想在之後轉換它們。
如果您的主要目標是減少映像文件的儲存需求,您可以做的是
fstrim
(對於循環安裝的文件系統 - 失去所有可用空間),或blkdiscard
(對於循環交換分區 - 失去所有數據)。如果儲存圖像的文件系統支持稀疏文件和打孔,它將使 dd 圖像使用更少的儲存空間而無需更改任何佈局,因為圖像中的任何可用空間也將被釋放用於支持文件系統。
同樣,這是危險的,如果您丟棄圖像文件的錯誤部分,圖像文件將受到不可恢復的損壞。為圖像文件創建循環設備並安裝它的簡單行為已經修改/損壞了圖像文件。
如果源磁碟是 SSD,並且它已經定期使用 fstrim,並且將修剪區域讀取為二進制零,那麼您可以首先使用
dd conv=sparse if=/dev/ssd of=ssd.img
. 這樣,任何二進制零區域都不會佔用 ssd.img 文件中的空間。請注意,conv=sparse
在還原到非零目標驅動器時,在其他方向使用時可能會導致損壞的結果。