
如何更改 Debian 10 的啟動根分割區?
我想從遠端減小位於 LVM 邏輯磁碟區上的根檔案系統的大小,僅透過 SSH 並且無需啟動到 Live CD。
由於我們無法在安裝時縮小 rootfs,因此我想我只需克隆現有的 rootfs,啟動到該 rootfs 並從那裡調整大小,然後啟動到原始 rootfs 並刪除臨時 rootfs。
我在使用 Ubuntu Server 18.04 的虛擬機器中進行了嘗試,因為據我所知,它使用與 Debain 10 相同的「引導鏈」。重新啟動後,我檢查了一下mount
,儘管原始根仍然被使用
/etc/fstab
已經升級/boot/grub/grub.cfg
已經升級initramfs
已經升級
目前配置
- 1TB RAID1
md0
- 4TB RAID1
md1
- 光電開啟
md0
- 光電開啟
md1p1
- VG
vg0
與兩個 PV - LV
root
作為原始根檔案系統(UUIDxxx
) - LV
newroot
作為臨時根檔案系統(UUIDyyy
) - ext4 上
vg0-root
(UUIDaaa
) - ext4 上
vg0-newroot
(UUIDbbb
)
/etc/fstab
進行了相應更改(替換了設備映射器路徑)。
到目前為止,我已將整個舊根同步aaa
到 newroot ,我用and inbbb
替換了每次出現的 UUIDaaa
和(注意:我沒有使用或 UEFI 啟動)。xxx
bbb
yyy
/boot/grub/grub.cfg
grub2
initramfs
已使用update-initramfs -u
(修復後/etc/initramfs-tools/conf.d/resume
)進行更新。
以該順序。但我在虛擬機器中的測試要么直接啟動到舊根目錄,要么將我帶入 GRUB 救援 shell。
update-grub
識別了newroot
卷並在 中添加了匹配條目grub.cfg
,在我的測試虛擬機中啟動時手動選擇它們(不可能通過 SSH...)也啟動了舊根。
我還看到有一個ROOT
選項可以對/etc/initramfs-tools/initramfs.conf
根分區進行硬編碼:
當無法傳遞根引導參數時,允許可選的根引導參數硬編碼。根 bootarg 會覆寫該特殊設定。
但由於我的這個設定中有一個 root 的 bootarg ,所以grub.cfg
應該不會生效。
為了在下次啟動時使用另一個 UUID 作為 root,還需要設定什麼?
答案1
原來我忘了替換 root= bootarg /boot/grub/grub.cfg
...
為了完整起見:
如何在沒有 Live 系統的情況下透過 SSH 將根分區移至 LVM 中的另一個 PV
注意:請務必備份重要資料!此方法是一種 hack,不應在生產系統上使用。無論如何,在 LV 克隆和從新根分區啟動之間寫入的資料始終會遺失。
在其他磁碟上建立新的LVM
fdisk /dev/sdb #Create new partition for PV (sdb1)
pvcreate /dev/sdb1
vgcreate vg1 /dev/sdb1
lvcreate -n newroot -L10G vg1 #Size has to be larger than effective usage on current root
mkfs.ext4 -L newroot /dev/mapper/vg1-newroot
收集有關新 LVM 的信息
lvdisplay
vgdisplay
pvdisplay
blkid
以下命令將引用此處提供的資訊:
- $pv0uuid = 舊 PV 的 UUID
- $pv1uuid = 新PV的UUID
- $vg{0,1}uuid = {舊,新} VG 的 UUID
- $lv{0,1}UUID = {舊,新} LV 的 UUID
- $root{0,1}UUID = {old,new} 根檔案系統的 UUID
- $vg{0,1} = {舊,新} VG 的名稱
- $lv{0,1} = {舊,新} LV 的名稱
並將/etc/grub/grub.cfg
呈現為$grubcfg
.對於 UEFI 系統來說,這是最有可能的/boot/grub2/grub.cfg
。
bash
我建議在使用中將它們設為變量,pv0uuid=xxxxxx-xxxx...
以便可以複製並貼上下面的命令。
在 GRUB 設定中設定新根
這些命令將取代 GRUB 配置中的文字:
sed -i "s/$pv0uuid/$pv1uuid/g" $grubcfg
sed -i "s/$vg0uuid/$vg1uuid/g" $grubcfg
sed -i "s/$lv0uuid/$lv1uuid/g" $grubcfg
sed -i "s/$root0uuid/$root1uuid/g" $grubcfg
sed -i "s/$vg0/$vg1/g" $grubcfg #BEWARE COMMON NAMES
sed -i "s/$lv0/$lv1/g" $grubcfg #BEWARE COMMON NAMES
sed -i "s/\/dev\/mapper\/$vg0-$lv0/\/dev\/mapper\/$vg1-$lv1/g" /etc/fstab #BEWARE COMMON NAMES
當心通用名稱:
sed
將取代每一個匹配文字的出現,因此建議手動進行這些更改,因為替換root
GRUB 或 fstab 配置中其他地方使用的單字將使其無效!
我建議使用nano
( CTRL+W
) 搜尋 VG 和 LV 名稱並手動替換它們。也建議搜尋光伏設備名稱,以防萬一...
克隆根卷
mount /dev/mapper/$vg1-$lv1 /mnt
rsync -rAa --one-file-system / /mnt/
umount /mnt
重啟
重新啟動(並祈禱)。驗證新 LV 是否已安裝到/
.
刪除舊的LVM
lvremove /dev/$vg0/*
vgremove $vg0
pvremove /dev/sda2 #Path to $pv0uuid
清理
可選,但推薦
- 最後刪除舊的 VG
/etc/lvm/archive
,否則每次啟動時都會搜尋它並導致延遲 update-grub
update-initramfs -u
筆記
在 Ubuntu 18.04 上進行測試,其他發行版可能會以不同方式處理 GRUB 配置(關於 UUID 與裝置路徑和更新命令)。
顯然,提前停止所有不必要的服務以最大程度地減少資料遺失。
可能有一種方法可以使用 systemd 目標、自訂腳本和 LVM 快照來避免(大多數)資料遺失。人們必須在重啟前的最後一刻再次$lv0
同步資料。$lv1
超出了本文的範圍...
如果/boot
不是單獨的分割區,請$grubcfg
在再次重新啟動之前仔細檢查新的根目錄。
答案2
不確定這對您是否有幫助,但這是我成功嘗試縮小 LV 上的根分區的方法:
- 建立根分區快照。確保它分配了一些空間,因為您將要更改它。
- fsck 快照。
- 調整快照的大小(縮小它)並確保在檔案系統頂部和 LV 目標大小邊界之間有一些緩衝區 - 只是為了安全起見。
- 將快照合併回您的 rootfs LV。
- 重啟。合併實際上在此時完成(可能在引導期間)。
- 重新啟動後 - 縮小 rootfs 磁碟區並可能再次調整 rootfs 大小 - 因此它會填充 LV 頂部的任何空間。
有一個缺點:您將在步驟 1 和 5 之間丟失一些數據,並且在步驟 1 中可能會出現一些不一致(取決於所使用的 FS)——當您在實時文件系統上創建快照時。
它對我來說效果出奇的好。
在理想情況下,步驟 1 將在啟動期間完成,然後再重新/掛載 rootfs rw,因此快照是乾淨的。我還沒有弄清楚如何從 dracut 中做到這一點 - 我嘗試使用的工具對我來說不起作用。