
Как изменить корневой раздел, с которого будет загружаться Debian 10?
Я хотел бы уменьшить размер моей корневой файловой системы, которая находится на логическом томе LVM, удаленно, то есть только по SSH и без загрузки с Live CD.
Поскольку мы не можем уменьшить размер rootfs, пока она смонтирована, я решил просто клонировать существующую rootfs, загрузиться в нее и изменить размер оттуда, затем загрузиться в исходную rootfs и удалить временную.
Я попробовал в виртуальной машине с Ubuntu Server 18.04, поскольку, насколько мне известно, он использует ту же самую "boot-chain", что и Debian 10. Однако мне не удалось надежно установить клонированный раздел как root. После перезагрузки я проверил с помощью mount
и оригинальный root все еще используется, хотя
/etc/fstab
был обновлен/boot/grub/grub.cfg
был обновленinitramfs
был обновлен
Текущая конфигурация
- 1ТБ RAID1
md0
- 4ТБ RAID1
md1
- PV на
md0
- PV на
md1p1
- VG
vg0
с обоими PV - LV
root
как исходная корневая файловая система (UUIDxxx
) - LV
newroot
как временная корневая файловая система (UUIDyyy
) - ext4 на
vg0-root
(UUIDaaa
) - ext4 на
vg0-newroot
(UUIDbbb
)
/etc/fstab
был соответствующим образом изменен (заменен путь к устройству-картографу).
На данный момент я выполнил rsync-синхронизацию всего старого корня aaa
с новым корнем bbb
, заменил все вхождения UUID aaa
и xxx
на bbb
и yyy
в /boot/grub/grub.cfg
(Примечание: я не использую grub2
загрузку UEFI).
initramfs
был обновлен с помощью update-initramfs -u
(после исправления /etc/initramfs-tools/conf.d/resume
).
Именно в таком порядке. Но мои тесты в виртуальной машине либо загружались прямо в старый корень, либо перебрасывали меня в спасательную оболочку GRUB.
update-grub
распознал newroot
том и добавил соответствующие записи в grub.cfg
, выбрав их вручную при загрузке моей тестовой виртуальной машины (невозможно через SSH...), также загрузил старый корень.
Я также видел, что есть ROOT
возможность /etc/initramfs-tools/initramfs.conf
жестко закодировать корневой раздел:
Позволяет использовать необязательный root bootarg в жестком коде, когда root bootarg не может быть передан. Корневой bootarg переопределяет эту специальную настройку.
Но поскольку в моем случае есть загрузчик root, grub.cfg
эта настройка не должна вступить в силу.
Что еще нужно настроить, чтобы использовать другой UUID в качестве root при следующей загрузке?
решение1
Оказывается, я забыл заменить root= bootarg в /boot/grub/grub.cfg
...
Для полноты картины:
Как переместить корневой раздел на другой PV в LVM через SSH без Live-системы
Примечание: Всегда делайте резервные копии важных данных! Этот метод является хаком и не должен использоваться в производственных системах. В любом случае данные, записанные в период между клонированием 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 = UUID старого PV
- $pv1uuid = UUID нового PV
- $vg{0,1}uuid = UUID {старой, новой} VG
- $lv{0,1}UUID = UUID {старого,нового} LV
- $root{0,1}UUID = UUID корневой файловой системы {old,new}
- $vg{0,1} = Имя {старого,нового} VG
- $lv{0,1} = Имя {старого,нового} LV
И /etc/grub/grub.cfg
будет представлен как $grubcfg
. Для систем UEFI это, скорее всего /boot/grub2/grub.cfg
, .
Я рекомендую установить их как переменные при bash
использовании pv0uuid=xxxxxx-xxxx...
, чтобы можно было копировать и вставлять приведенные ниже команды.
Установить новый root в конфигурации 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 и заменять их вручную. Поиск имени устройства PV также рекомендуется, на всякий случай...
Клонировать корневой том
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:
- Создайте снимок корневого раздела. Убедитесь, что на нем выделено некоторое пространство, так как вы будете его изменять.
- Проверьте снимок.
- Измените размер снимка (уменьшите его) и убедитесь, что между верхней частью файловой системы и границей целевого размера логического тома есть некоторый буфер — просто чтобы перестраховаться.
- Обратно объедините снимок с вашим корневым томом rootfs.
- Перезагрузка. На этом этапе фактически происходит слияние (вероятно, во время загрузки).
- После перезагрузки уменьшите том rootfs и, возможно, снова измените размер rootfs, чтобы он заполнил все пространство до верха LV.
Есть один недостаток: вы потеряете часть данных между шагами 1 и 5, и у вас МОГУТ возникнуть некоторые несоответствия (в зависимости от используемой файловой системы) на шаге 1, поскольку вы делаете снимок в работающей файловой системе.
Удивительно, но мне это помогло.
В идеальном мире шаг 1 должен быть выполнен во время загрузки, до перемонтирования rootfs rw, чтобы снимок был чистым. Я не понял, как это сделать из dracut - инструменты, которые я пытался использовать, не работали у меня.