Миграция на работеща Debian система на нов твърд диск с LVM2

Написах тази статия с цел да улесня хората, които евентуално биха се пробвали да извършат въпросната процедура.

Историята покрай статията е следната – закупих си нов твърд диск, но т.к. нямах желание да преинсталирам цялата система реших да я мигрирам. Прецених също, че имайки вече доста дисково пространство ще е грехота да не ползвам LVM, имайки предвид предимствата, които дава.

Тук съм описал стъпките, които се оказа, че трябва да се извършат за да премине една такава миграция успешно.

ВНИМАНИЕ: Има много голям шанс да загубите данните си в следствие използване на команди и програми, цитирани в този документ. Използвайте документа на собствена отговорност.

ВНИМАНИЕ2: Навсякъде, където има използван символ ‘#’ (диез), се има предвид, че посочената команда се изпълнява като потребител root, а самият диез не се пише в командния ред!

1. Описание на дадените условия

В моя случай условията бяха следните:

20GB IDE HDD с инсталиран Debian GNU/Linux testing/unstable, без LVM
250GB SATA2 HDD – празен.

Целта беше да се прехвърли работещия Linux на новия диск и да се пусне под LVM.

2. Подготовка на диска и разделяне на дялове

В моя случай реших да „делегирам“ целия диск на LVM, оставяйки само един 200MB дял за /boot. Може би има вариант и този дял да се включи в LVM, но не мисля че си струва усилията.

И така, създаваме един първичен дял за /boot и още един първичен дял за LVM дяловете:

Примерен код на bash
# fdisk /dev/sda

 The number of cylinders for this disk is set to 30401.
 There is nothing wrong with that, but this is larger than 1024,
 and could in certain setups cause problems with:
 1) software that runs at boot time (e.g., old versions of LILO)
 2) booting and partitioning software from other OSs
 (e.g., DOS FDISK, OS/2 FDISK)

 Command (m for help): p

 Disk /dev/sda: 250.0 GB, 250059350016 bytes
 255 heads, 63 sectors/track, 30401 cylinders
 Units = cylinders of 16065 * 512 = 8225280 bytes

 Device Boot      Start         End      Blocks   Id  System

 Command (m for help): n
 Command action
 e   extended
 p   primary partition (1-4)
 p
 Partition number (1-4): 1
 First cylinder (1-30401, default 1):
 Using default value 1
 Last cylinder or +size or +sizeM or +sizeK (1-30401, default 30401): +200M

 Command (m for help): n
 Command action
 e   extended
 p   primary partition (1-4)
 p
 Partition number (1-4): 2
 First cylinder (26-30401, default 26):
 Using default value 26
 Last cylinder or +size or +sizeM or +sizeK (26-30401, default 30401):
 Using default value 30401

 Command (m for help): t
 Partition number (1-2): 2
 Hex code (type L to list codes): 8e
 Changed system type of partition 1 to 8e (Linux LVM)

 Command (m for help): p

 Disk /dev/sda: 250.0 GB, 250059350016 bytes
 255 heads, 63 sectors/track, 30401 cylinders
 Units = cylinders of 16065 * 512 = 8225280 bytes

 Device Boot      Start         End      Blocks   Id  System
 /dev/sda1               1          25      200781   83  Linux
 /dev/sda2              26       30401   243995220   83  Linux LVM

 Command (m for help): w

Създаваме файлова система на /dev/sda1:

Примерен код на bash
# mkfs.ext2 /dev/sda1

3. Подготовка на диска за работа с LVM

За работа с LVM2 в Debian трябва да се инсталира пакета lvm2 (заедно със зависимостите си). Този пакет съдържа програмите, необходими за конфигуриране на LVM2.

След като е инсталиран въпросният пакет трябва да подготвим диска за работа с LVM, а именно да създадем physical volume(s), volume group(s) и logical volume(s).

LVM може да работи с цели дискове (напр. /dev/sda), дялове (/dev/sdaX), мета-устройства (напр. софтуерен RAID) и loopback устройства. В моя случай LVM работи с дял, а именно /dev/sda2.

Първата стъпка е да се създаде physical volume, с който ще работи LVM:

Примерен код на bash
# pvcreate /dev/sda2

След това се създава volume група:

Примерен код на bash
# vgcreate system /dev/sda2

(system е името на групата, с което в последствие ще се обръщаме към нея. Можете да изберете друго по ваша преценка.)

Накрая създаваме логическите дялове в създадената група:

Примерен код на bash
# lvcreate -L20G -nroot system
 # lvcreate -L500M -nswap system
 # lvcreate -L100G -nhome system

С -L задаваме размер на дяла (в KB, MB, GB или TB, съответно със суфикс K, M, G или T). С -n задаваме име на дяла. Последния параметър е името на volume групата, към която да се създаде дяла.

(Не знам доколко добра идея е swap дяла да е включен в LVM, ще се радвам на коментари.)

4. Създаване на файлови системи

След като имах логическите дялове, трябваше да създам файлови системи на въпросните дялове:

Примерен код на bash
# mkfs.reiserfs /dev/system/root
 # mkfs.ext3 /dev/system/home
 # mkswap /dev/system/swap

(Забележка: избора на начин за разделяне на дялове и избора на файлова система е по желание и преценка на клиента.)

5. Създаване на нов initrd image

Това е вероятно най-важната стъпка. За да може да зареди системата от новият LVM root дял трябва да се изгенерира ново initrd изображение, което да може да активира LVM преди да е монтиран root дяла. Всъщност това става много лесно.

Първо най-добре си направете резервно копие на работещото изображение:

Примерен код на bash
# cp -a /boot/initrd.img-`uname -r` /boot/initrd.img-`uname -r`.stock

След това можете да обновите въпросното изображение ето така:

Примерен код на bash
# update-initramfs -k `uname -r` -u

Това ще включи необходимите скриптове и изпълними файлове за работа с LVM в initrd изображението.

6. Копиране на системата на новите дялове

Монтираме /home дяла от новия диск и копираме данните на потребителите на него:

Примерен код на bash
# mount /dev/system/home /mnt
 # cp -a /home/* /mnt/
 # umount /mnt

Монтираме /boot дяла (/dev/sda1) и копираме съдържанието на /boot директорията там:

Примерен код на bash
# mount /dev/sda1 /mnt
 # cp -a /boot/* /mnt/
 # umount /mnt

Копираме основната част от системата:

Примерен код на bash
# mount /dev/system/root /mnt
 # cp -a /bin /etc /initrd* /lib /opt /root /sbin /srv /tmp /usr /var /vmlinuz /mnt/

Тук пропускаме директориите /cdrom, /dev, /home, /mnt, /proc и /sys, т.к. това са точки на монтиране на други дялове или псевдо файлови системи. Тях ще създадем на ръка:

Примерен код на bash
# cd /mnt
 # mkdir cdrom dev home mnt proc sys
 # cd /
 # umount /mnt

7. Инсталиране на GRUB

Тази част е малко чувствителна към грешки.

Първо трябва да се смени пътя до root файловата система. Това става чрез промяна на kernel реда в /boot/grub/menu.lst. В моя случай трябваше да се промени реда:

Примерен код на bash
kernel	/boot/vmlinuz-2.6.17-2-k7 root=/dev/hda2 ro

на

Примерен код на bash
kernel	/boot/vmlinuz-2.6.17-2-k7 root=/dev/mapper/system-root ro

Второ, ако преди миграцията, /boot не е била на отделен дял, ще трябва да редактирате файла /boot/grub/menu.lst, като промените пътищата до ядрото и initrd изображението, така че да се получи нещо такова:

Примерен код на bash
kernel	/vmlinuz-2.6.17-2-k7 root=/dev/mapper/system-root ro
 initrd	/initrd.img-2.6.17-2-k7

Забележете, че при заредена операционна система можете да се обръщате към LVM дяловете по този начин:

/dev/system/root

или в общия случай:

/dev/<volume-group>/<logical-volume-name>

докато при подаване на root файлова система към ядрото трябва задължително да се подаде във вид:

/dev/mapper/<volume-group>-<logical-volume-name>

(в конкретния случай: /dev/mapper/system-root).

Третото нещо, което трябва да се направи, е да се промени по подходящ начин параметъра root на GRUB. Самата стойност на параметъра зависи от конфигурацията на вашия BIOS, а именно от коет устройство е настроен да зарежда компютърът. В моя случай това е SATA диска, т.е. от гледна точка на GRUB той се явява (hd0). Съответно в menu.lst за записва:

Примерен код на bash
root	(hd0,0)

т.к. /boot дялът ми се намира на /dev/sda1.

Това, което остава е да инсталираме самият GRUB в MBR на SATA диска. За да извършим това коректно може да се наложи да стартираме GRUB с параметър –device-map. Чрез този параметър указваме на GRUB да прочете от файла, който му подадем, съответствията м/у Linux устройствата в системата и GRUB устройствата. В моя случай създадох файл device.map, който съдържаше следното:

В моя случай там пишеше:

Примерен код на bash
(hd0)	/dev/sda
 (hd1)	/dev/hda

като файла, в който описах нещата се казваше /root/device.map

По този начин указвам на GRUB, че въпреки, че /dev/hda е настроен в BIOS така че GRUB да го вижда като (hd0), аз искам (hd0) да е /dev/sda. Тук е добре да се уточни, че става дума за момента преди да рестартираме системата и да променим настройката в BIOS, още докато сме в системата, която е инсталирана на IDE диска.

След като сме описали това съответствие, стартираме grub по следния начин:

Примерен код на bash
# grub --device-map=/root/device.map

 GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.   For
 the   first   word,  TAB  lists  possible  command
 completions.  Anywhere else TAB lists the possible
 completions of a device/filename. ]

 grub> root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83

 grub> setup (hd0)
 Checking if "/boot/grub/stage1" exists... no
 Checking if "/grub/stage1" exists... yes
 Checking if "/grub/stage2" exists... yes
 Checking if "/grub/e2fs_stage1_5" exists... yes
 Running "embed /grub/e2fs_stage1_5 (hd0)"...  16 sectors are embedded.
 succeeded
 Running "install /grub/stage1 (hd0) (hd0)1+16 p (hd0,0)/grub/stage2 /grub/menu.lst"... succeeded
 Done.

 grub> quit

Вече имаме инсталиран GRUB в MBR на SATA диска.

Забележка: добре е новият device.map да се копира в /boot дяла (в случая /dev/sda1):

Примерен код на bash
# mount /dev/sda1 /mnt
 # cp /root/device.map /mnt/grub/
 # umount /mnt

8. Редактиране на fstab

Логично трябва да променим /etc/fstab на SATA диска, така че да отразява монтирането на LVM дяловете, вместо тези от /dev/hda:

Примерен код на bash
# mount /dev/system/root /mnt
 # vim /mnt/etc/fstab
 # umount /mnt

В моя случай новият fstab заприлича на нещо такова:

Примерен код на bash
proc /proc proc defaults 0 0
 /dev/mapper/system-root / reiserfs defaults 0 1
 /dev/sda1 /boot ext2 defaults 0 1
 /dev/mapper/system-home /home ext3 defaults 0 1
 /dev/mapper/system-swap none swap sw 0 0
 /dev/cdrom /cdrom iso9660 ro,user,noauto 0 0

9. Рестартиране на системата и промени в BIOS

Сега би трябвало да е направено всичко необходимо, за да заредим операционната система от SATA диска. Рестартираме машината, променяме в BIOS първо да зарежда от SATA диска и чакаме да се зареди новата система.

10. Възможни проблеми

  • /scripts/local-top/lvm: 36: vgchange: not foundИмате проблем с initrd изображението. Проверете дали сте изпълнили точката 5 и дали новият генериран initrd е копиран на новия /boot дял.
  • Kernel panic (unable to mount root fs)Вероятно проблема е в неправилно указание за kernel в /boot/grub/menu.lst.

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

Този сайт използва Akismet за намаляване на спама. Научете как се обработват данните ви за коментари.