Дисклеймер: всё нижеописанное использовать вдумчиво и под свою ответственность! Шпаргалка создана для личных целей, использовать исключительно в качестве инструкции «как делать не надо». Большинство команд восстановлено по памяти, но отражают суть дела. Статья не претендует на уникальность или адекватность, но метод рабочий.
Краткое содержание:
- Изменяем размер корневой файловой системы на новой виртуалке
- Переносим снапшот LVM со старой
- Заставляем грузиться новое ядро со старой операционкой
- Рихтуем до работоспособного состояния систему в целом
Поехали!
- Создаем виртуалку в vscale.io с похожей версией операционной системы. Например, вместо Debian 6 ставим минимальный возможный Debian 7. Диск выбираем из собственных предпочтений с расчетом «чтоб влезло». Как пользоваться панелью нового облачного хостера, можно найти в официальном блоге на Хабре
- Пересобираем на новой виртуалке initrd с выходом в консоль до монтирования разделов. Для этого делаем следующее:
- Создаем папку и разворачиваем туда текущий initrd:
mkdir ~/initrd; cd ~/initrd
gunzip -c /boot/initrd.img-3.2.0-4-amd64 | cpio -i --make-directories 65923 blocks
ls -l total 44 drwxr-xr-x 2 root root 4096 Aug 22 11:20 bin drwxr-xr-x 3 root root 4096 Aug 22 11:19 conf drwxr-xr-x 6 root root 4096 Aug 22 11:21 etc -rwxr-xr-x 1 root root 6797 Aug 22 11:19 init drwxr-xr-x 6 root root 4096 Aug 22 11:19 lib drwxr-xr-x 2 root root 4096 Aug 22 11:19 lib64 drwxr-xr-x 2 root root 4096 Aug 22 11:19 run drwxr-xr-x 2 root root 4096 Aug 22 11:19 sbin drwxr-xr-x 7 root root 4096 Aug 22 11:21 scripts drwxr-xr-x 3 root root 4096 Aug 22 11:19 usr
- Кладем необходимые библиотеки и бинарники для работы с файловой системой (нам нужен fdisk, resize2fs и e2fsck):
ldd /sbin/fdisk linux-vdso.so.1 => (0x00007ffeeb96e000) libblkid.so.1 => /lib/libblkid.so.1 (0x00007fe3ba493000) libuuid.so.1 => /lib/libuuid.so.1 (0x00007fe3ba28f000) libc.so.6 => /lib/libc.so.6 (0x00007fe3b9f2d000) /lib64/ld-linux-x86-64.so.2 (0x00007fe3ba6b2000) ldd /sbin/resize2fs linux-vdso.so.1 => (0x00007ffd497ee000) libe2p.so.2 => /lib/libe2p.so.2 (0x00007f128b5b6000) libext2fs.so.2 => /lib/libext2fs.so.2 (0x00007f128b388000) libcom_err.so.2 => /lib/libcom_err.so.2 (0x00007f128b185000) libc.so.6 => /lib/libc.so.6 (0x00007f128ae23000) libpthread.so.0 => /lib/libpthread.so.0 (0x00007f128ac07000) /lib64/ld-linux-x86-64.so.2 (0x00007f128b7bd000) ldd /sbin/e2fsck linux-vdso.so.1 => (0x00007fff949f7000) libext2fs.so.2 => /lib/libext2fs.so.2 (0x00007f24ab49a000) libcom_err.so.2 => /lib/libcom_err.so.2 (0x00007f24ab297000) libblkid.so.1 => /lib/libblkid.so.1 (0x00007f24ab078000) libuuid.so.1 => /lib/libuuid.so.1 (0x00007f24aae74000) libe2p.so.2 => /lib/libe2p.so.2 (0x00007f24aac6d000) libc.so.6 => /lib/libc.so.6 (0x00007f24aa90b000) libpthread.so.0 => /lib/libpthread.so.0 (0x00007f24aa6ef000) /lib64/ld-linux-x86-64.so.2 (0x00007f24ab6c8000)
for i in libext2fs.so.2.4 libcom_err.so.2.1 libe2p.so.2.3; do cp -i /lib/x86_64-linux-gnu/$i lib/x86_64-linux-gnu/; done
cd lib/x86_64-linux-gnu/ ln -s libcom_err.so.2.1 libcom_err.so.2 ln -s libext2fs.so.2.4 libext2fs.so.2 ln -s libe2p.so.2.3 libe2p.so.2cd ~/initrd/ cp /sbin/e2fsck ~/initrd/bin/ cp /sbin/resize2fs ~/initrd/bin/ cp /sbin/fdisk ~/initrd/bin/
- Изменяем init скрипт в месте перед монтированием устройств в систему, для этого в файле scripts/local
... # FIXME This has no error checking # Mount root if [ "${FSTYPE}" != "unknown" ]; then mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} else mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} fi ...
Делаем примерно так:
#RESIZEROOTFS MODIFIED!!! DONT RUN MORE THAN ONCE _log_msg "Starting e2fsck" /bin/e2fsck -p -f -C 0 /dev/vda1 || true _log_msg "Starting shell" /bin/sh # FIXME This has no error checking # Mount root if [ "${FSTYPE}" != "unknown" ]; then mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} else mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} fi
- Далее создаем файл etc/mtab, при отстутствии которого утилиты e2fsck и resize2fs отказываются работать
touch ~/initrd/etc/mtab
- Собираем патченный initrd назад
cd ~/initrd/ find ./ | cpio -H newc -o > /tmp/initrd.cpio 64097 blocks gzip -c /tmp/initrd.cpio > /boot/initrd-resize.img
- Теперь добавим в меню GRUB новую строчку для загрузки нашего initrd, для этого не будем хардкодить, а объявим его в файле /etc/grub.d/40_custom
#!/bin/sh exec tail -n +3 $0 # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. menuentry 'Our resize initrd' --class debian --class gnu-linux --class gnu --class os { load_video insmod gzio insmod part_msdos insmod ext2 set root='(hd0,msdos1)' search --no-floppy --fs-uuid --set=root 89839485-a3d7-4d72-b96d-aba559b16634 echo 'Loading Linux 3.2.0-4-amd64 ...' linux /boot/vmlinuz-3.2.0-4-amd64 root=UUID=660f79dc-c152-4e15-ad61-7075b42de609 ro quiet echo 'Loading initial ramdisk ...' initrd /boot/initrd-resize.img }
- Обновляем список GRUB и перезагружаемся в патченный inirtd (для выбора нужного пункта в меню GRUB используем панель хостера и кнопку «Открыть консоль»)
update-grub reboot
- Создаем папку и разворачиваем туда текущий initrd:
- Пока мы искали как попасть в VNC-консоль в панели vscale, необходимый нам раздел уже был проверен автоматически скриптом, поэтому сразу уменьшаем файловую систему до 1ГБ (системе хватит, она занимает около 800МБ)
resize2fs /dev/vda1 1G
- Затем с помощью fdisk отрезаем раздел и создаем новый под LVM, оба primary, первый +1G, второй — всё остальное пространство. Не забываем поставить флаг активности на первый раздел
- На всякий случай проверяем e2fsck и подгоняем файловую систему под размер первого раздела
- Перезагружаемся назад в обычную операционку, первый пункт меню
- Ставим пакет lvm2, создаем физический раздел, группу томов и наконец логический том под систему, которую будем переносить. Размер выбираем исходя из наших нужд
apt-get install lvm2 pvcreate /dev/vda2 vgcreate vg0 /dev/vda2 lvcreate -n old_system -L10G vg0
- Идем на старый сервер в Селектеле, выключаем там swap и используем освободившееся место на диске для создания снапшота корневой файловой системы. В большинстве случаев этого должно хватить. Если раздел был невообразимо огромен, колдуем с добавлением дополнительных дисков в панели хостера и используем их
swapoff /dev/vg/swap lvremove /dev/vg/swap lvcreate --snapshot --name my_shot --size 1.9G /dev/vg/root
- Переносим наш снапшот системы в новую виртуалку
dd if=/dev/vg/my_shot bs=4096 | ssh root@new_vscale -C 'dd of=/dev/vg1/old_system bs=4096'
- Если у нас отличаются ядра (3.1.0-1.2-xen на старом и 3.2.0-4-amd64 на новом, в моем случае), то маунтим перенесенный снапшот и переносим в раздел старой системы папку /lib/modules/3.2.0-4-amd64 с новой виртуалки. Иначе после ребута в старую систему с новым ядром ничего не заведется
- При отличии версий операционных систем может вылезти еще косяк с inittab, в 6 и 7 дебианах они отличаются вот этим местом (комментим и добавляем старое поведение, иначе после загрузки системы мы в нее не залогинимся)
#new system #0:12345:respawn:/sbin/getty xvc0 9600 #old system 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6
- Теперь пробуем загружаться с этого Франкенштейна, для этого в наш /etc/grub.d/40_custom прописываем загрузку нового ядра с LVM
menuentry 'Debian GNU/Linux Old System' --class debian --class gnu-linux --class gnu --class os { load_video insmod gzio insmod part_msdos insmod ext2 set root='(hd0,msdos1)' search --no-floppy --fs-uuid --set=root 89839485-a3d7-4d72-b96d-aba559b16634 echo 'Loading Linux 3.2.0-4-amd64 ...' linux /boot/vmlinuz-3.2.0-4-amd64 root=/dev/mapper/vg0-old_system ro consoleblank=0 panic=15 echo 'Loading initial ramdisk ...' initrd /boot/initrd.img-3.2.0-4-amd64 }
- Обновляем GRUB, для автоматизации выставляем загрузку с этой строчки всегда по дефолту. Для этого правим строчку GRUB_DEFAULT=»0″ в файле /etc/default/grub на ту, которой соответствует наше творчество. Отсчет с нуля
- Если всё прошло гладко, попадаем внутрь старой системы на новом ядре. Правим сетевые параметры, ищем вхождения старого IP адреса по всей папке /etc и после внесения необходимых изменений удивляемся, что это еще и работает о_О
Ссылки: