Професионален Блог

Поредният WordPress блог – що пък не? :P

Създаване на софтуерен Raid1 масив от диск с вече инсталиран линукс на него + още един

Някои ще кажат – „mission impossible“, е да, ама не 🙂
И аз така си мислех първоначално, докато моя „учител“ не ме светна, че може и ме прати да чета 😉
Машината на която ще направя въпросната манипулация е Pentium 3 с 512 ram и 2x10g диска.

Желателно е двата диска да са идентични като размер и модел.
В моя случай те са:

Disk /dev/hda - 10254 MB / 9779 MiB - WDC WD102BB
Disk /dev/hdc - 10254 MB / 9779 MiB - WDC WD102BB

Започваме с инсталиране на необходимите пакети:

server1:~# apt-get install initramfs-tools mdadm

По време на инсталацията ще бъдете попитани въпрос, на който трябва да отговорите с all
след което можете да рестартирате системата или ръчно да стартирате модулите както следва:

server1:~# modprobe md
server1:~# modprobe linear
server1:~# modprobe multipath
server1:~# modprobe raid0
server1:~# modprobe raid1
server1:~# modprobe raid5
server1:~# modprobe raid6
server1:~# modprobe raid10

За да проверите дали модулите са заредени успешно трябва да стартирате командата:

server1:~# cat /proc/mdstat

Изхода от нея трябва да изглежда така:

server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
unused devices:

Подготовка на дисковете:
В началото дяловете на дисковете изглеждаха така:

server1:~# fdisk -l

Disk /dev/hda: 10.2 GB, 10254827520 bytes
255 heads, 63 sectors/track, 1246 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x0000a606

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1        1187     9534546   83  Linux
/dev/hda2            1188        1246      473917+   5  Extended
/dev/hda5            1188        1246      473886   82  Linux swap / Solaris

Disk /dev/hdc: 10.2 GB, 10254827520 bytes
255 heads, 63 sectors/track, 1246 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000efc30

   Device Boot      Start         End      Blocks   Id  System
/dev/hdc1               1          32      257008+  82  Linux swap / Solaris
/dev/hdc2   *          33        1246     9751455   83  Linux

Поради което се наложи първо да изтрия дяловете на /dev/hdc:

server1:~# fdisk /dev/hdc

The number of cylinders for this disk is set to 1246.
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): d
Partition number (1-4): 1

Command (m for help): d
Selected partition 2

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
server1:~# fdisk /dev/hdc -l

Disk /dev/hdc: 10.2 GB, 10254827520 bytes
16 heads, 63 sectors/track, 19870 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Disk identifier: 0x000efc30

   Device Boot      Start         End      Blocks   Id  System

На диск /dev/hdc трябва да бъдат създадени идентични дялове като на /dev/hdc.
За целта се използва следната команда:

server1:~# sfdisk -d /dev/hda | sfdisk /dev/hdc
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Checking that no-one is using this disk right now ...
OK

Disk /dev/hdc: 19870 cylinders, 16 heads, 63 sectors/track
Old situation:
Units = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/hdc1          0       -       0          0    0  Empty
/dev/hdc2          0       -       0          0    0  Empty
/dev/hdc3          0       -       0          0    0  Empty
/dev/hdc4          0       -       0          0    0  Empty
New situation:
Units = sectors of 512 bytes, counting from 0

   Device Boot    Start       End   #sectors  Id  System
/dev/hdc1   *        63  19069154   19069092  83  Linux
/dev/hdc2      19069155  20016989     947835   5  Extended
/dev/hdc3             0         -          0   0  Empty
/dev/hdc4             0         -          0   0  Empty
/dev/hdc5      19069218  20016989     947772  82  Linux swap / Solaris
Warning: partition 1 does not end at a cylinder boundary

sfdisk: I don't like these partitions - nothing changed.
(If you really want this, use the --force option.)

В моя случай се наложи да използвам повторно стартиране на командата с –force ,
но това не би трябвало да се наложи при вас:

server1:~# sfdisk -d /dev/hda | sfdisk /dev/hdc --force
Checking that no-one is using this disk right now ...
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
OK                                                                

Disk /dev/hdc: 19870 cylinders, 16 heads, 63 sectors/track
Old situation:
Units = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/hdc1          0       -       0          0    0  Empty
/dev/hdc2          0       -       0          0    0  Empty
/dev/hdc3          0       -       0          0    0  Empty
/dev/hdc4          0       -       0          0    0  Empty
New situation:
Units = sectors of 512 bytes, counting from 0               

   Device Boot    Start       End   #sectors  Id  System
/dev/hdc1   *        63  19069154   19069092  83  Linux
/dev/hdc2      19069155  20016989     947835   5  Extended
/dev/hdc3             0         -          0   0  Empty
/dev/hdc4             0         -          0   0  Empty
/dev/hdc5      19069218  20016989     947772  82  Linux swap / Solaris
Warning: partition 1 does not end at a cylinder boundary
Successfully wrote the new partition table                            

Re-reading the partition table ...

If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
(See fdisk(8).)

Нека проверим дали всичко е коректно чрез fdisk:

server1:~# fdisk -l

Disk /dev/hda: 10.2 GB, 10254827520 bytes
255 heads, 63 sectors/track, 1246 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x0000a606                     

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1        1187     9534546   83  Linux
/dev/hda2            1188        1246      473917+   5  Extended
/dev/hda5            1188        1246      473886   82  Linux swap / Solaris

Disk /dev/hdc: 10.2 GB, 10254827520 bytes
16 heads, 63 sectors/track, 19870 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Disk identifier: 0x000efc30

   Device Boot      Start         End      Blocks   Id  System
/dev/hdc1   *           1       18918     9534546   83  Linux
/dev/hdc2           18918       19859      473917+   5  Extended
/dev/hdc5           18918       19859      473886   82  Linux swap / Solaris

В следващата стъпка ще променим типа на дяловете от диск /dev/hdc на Linux raid autodetect, като аз имам и Extended дял, който не трябва да се пипа:

server1:~# fdisk /dev/hdc

The number of cylinders for this disk is set to 19870.
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): t
Partition number (1-5): 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Command (m for help): t
Partition number (1-5): 5
Hex code (type L to list codes): fd
Changed system type of partition 5 to fd (Linux raid autodetect)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
server1:~# fdisk -l /dev/hdc

Disk /dev/hdc: 10.2 GB, 10254827520 bytes
16 heads, 63 sectors/track, 19870 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Disk identifier: 0x000efc30

   Device Boot      Start         End      Blocks   Id  System
/dev/hdc1   *           1       18918     9534546   fd  Linux raid autodetect
/dev/hdc2           18918       19859      473917+   5  Extended
/dev/hdc5           18918       19859      473886   fd  Linux raid autodetect

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

server1:~# mdadm --zero-superblock /dev/hdc1
mdadm: Unrecognised md component device - /dev/hdc1
server1:~# mdadm --zero-superblock /dev/hdc5
mdadm: Unrecognised md component device - /dev/hdc5

което значи, че всичко е чисто 🙂

Създаване на RAID масиви
Със следните команди ще създадем RAID масивите:

server1:~# mdadm --create /dev/md0 --level=1 --raid-disks=2 missing /dev/hdc1
mdadm: array /dev/md0 started.
server1:~# mdadm --create /dev/md1 --level=1 --raid-disks=2 missing /dev/hdc5
mdadm: array /dev/md1 started.

Проверяваме дали са се създали коректно с:

server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active (auto-read-only) raid1 hdc5[1]
      473792 blocks [2/1] [_U]

md0 : active (auto-read-only) raid1 hdc1[1]
      9534464 blocks [2/1] [_U]

unused devices:

Сега трябва да създадем файловата система на масивите:

server1:~# mkfs.ext3 /dev/md0
mke2fs 1.41.3 (12-Oct-2008)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
596848 inodes, 2383616 blocks
119180 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2441084928
73 block groups
32768 blocks per group, 32768 fragments per group
8176 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 38 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
server1:~# mkswap /dev/md1
Setting up swapspace version 1, size = 485158 kB
no label, UUID=4fb4e05c-78c8-4ecf-8482-63e0dc5c349b

След като сме създали масивите трябва зададем информация за тях в /etc/mdadm/mdadm.conf:

server1:~# cp /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf_orig
`/etc/mdadm/mdadm.conf' -> `/etc/mdadm/mdadm.conf_orig'
server1:~# mdadm --examine --scan >> /etc/mdadm/mdadm.conf

и проверяваме дали записа е коректен:

server1:~# cat /etc/mdadm/mdadm.conf
# mdadm.conf
#
# Please refer to mdadm.conf(5) for information about this file.
#

# by default, scan all partitions (/proc/partitions) for MD superblocks.
# alternatively, specify devices to scan, using wildcards if desired.
DEVICE partitions

# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes

# automatically tag new arrays as belonging to the local system
HOMEHOST 

# instruct the monitoring daemon where to send mail alerts
MAILADDR root

# definitions of existing MD arrays

# This file was auto-generated on Thu, 14 Jan 2010 00:57:22 +0200
# by mkconf $Id$
ARRAY /dev/md0 level=raid1 num-devices=2 UUID=a09935d3:3afabe5d:1c0b12aa:49fee674
ARRAY /dev/md1 level=raid1 num-devices=2 UUID=6eaf7710:2f7c8917:1c0b12aa:49fee674

Всичко е точно за сега 🙂 .

Необходимо системата да бъде настроена за първия си рестарт.
Трябва да променим /etc/fstab като вместо стария дял от /dev/hda1 трябва да сочи към /dev/md0:

server1:~# nano /etc/fstab
# /etc/fstab: static file system information.
#
#              

proc            /proc           proc    defaults        0       0
/dev/md0       /               ext3    errors=remount-ro 0       1
/dev/md1       none            swap    sw              0       0
#/dev/hda        /media/cdrom0   udf,iso9660 user,noauto     0       0

Следват промени по GRUB – /boot/grub/menu.lst
След default 0 трябва да добавите fallback 1 за да може в случай, че GRUB не успее да бутне от първия кернел да опита с втория:

default         0
fallback        1

Копирайте частта на /boot/grub/menu.lst в която е описано от къде да бутва още веднъж над нея и променете root=/dev/hda1 с root=/dev/md0 и root (hd0,0) с root (hd1,0):

title           Debian GNU/Linux, kernel 2.6.26-2-686
root            (hd1,0)
kernel          /boot/vmlinuz-2.6.26-2-686 root=/dev/md0 ro quiet
initrd          /boot/initrd.img-2.6.26-2-686

title           Debian GNU/Linux, kernel 2.6.26-2-686
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.26-2-686 root=/dev/hda1 ro quiet
initrd          /boot/initrd.img-2.6.26-2-686

title           Debian GNU/Linux, kernel 2.6.26-2-686 (single-user mode)
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.26-2-686 root=/dev/hda1 ro single
initrd          /boot/initrd.img-2.6.26-2-686

Обновяваме ramdisk чрез:

server1:~# update-initramfs -u
update-initramfs: Generating /boot/initrd.img-2.6.26-2-686

Трябва да монтирате /dev/md0 и да копираме информацията от /dev/hda1 там:

server1:~# mkdir /mnt/md0
server1:~# mount /dev/md0 /mnt/md0
server1:~# cp -dpRx / /mnt/md0

Тъй като в момента на втория диск няма инсталиран boot loader, трябва да инсталираме такъв посредством командата grub:

server1:~# grub

grub> root (hd1,0)
 Filesystem type is ext2fs, partition type 0xfd

grub> setup (hd1)
 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 (hd1)"...  15 sectors are embedded.
succeeded
 Running "install /grub/stage1 (hd1) (hd1)1+15 p (hd1,0)/grub/stage2 /grub/menu.lst"... succeeded
Done.

grub> quit

Рестартирайте машината и стискайте палци 🙂

Системата е бутнала успешно.
Подготовка на първия диск
Oтново чрез fdisk ще промени типа на дяловете на /dev/hda. Трябва да бъде Linux raid autodetect, и Extended дяла не трябва да се пипа:

server1:~# fdisk /dev/hda

The number of cylinders for this disk is set to 1246.
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): t
Partition number (1-5): 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Command (m for help): t
Partition number (1-5): 5
Hex code (type L to list codes): fd
Changed system type of partition 5 to fd (Linux raid autodetect)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Сега трябва да добавим /dev/hda1 и /dev/hda5 към масивите:

server1:~# mdadm --add /dev/md0 /dev/hda1
mdadm: added /dev/hda1
server1:~# mdadm --add /dev/md1 /dev/hda5
mdadm: added /dev/hda5

Чрез следващата команда ще наблюдаваме как масивите се създават и синхронизират:

server1:~# watch cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda5[2] hdc5[1]
      473792 blocks [2/1] [_U]
        resync=DELAYED

md0 : active raid1 hda1[2] hdc1[1]
      9534464 blocks [2/1] [_U]
      [=>...................]  recovery =  5.7% (552320/9534464) finish=7.8min speed=19045K/sec

unused devices:

След като синхронизацията приключи, натискаме ctrl + c и продължаваме на татък.

Трябва да генерираме на ново mdamd.conf файла:

server1:~# cp /etc/mdadm/mdadm.conf_orig /etc/mdadm/mdadm.conf
server1:~# mdadm --examine --scan >> /etc/mdadm/mdadm.conf
server1:~# cat /etc/mdadm/mdadm.conf
# mdadm.conf
#
# Please refer to mdadm.conf(5) for information about this file.
#

# by default, scan all partitions (/proc/partitions) for MD superblocks.
# alternatively, specify devices to scan, using wildcards if desired.
DEVICE partitions

# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes

# automatically tag new arrays as belonging to the local system
HOMEHOST

# instruct the monitoring daemon where to send mail alerts
MAILADDR root

# definitions of existing MD arrays

# This file was auto-generated on Thu, 14 Jan 2010 00:57:22 +0200
# by mkconf $Id$
ARRAY /dev/md0 level=raid1 num-devices=2 UUID=15763cb2:0a3cf6de:1c0b12aa:49fee674
ARRAY /dev/md1 level=raid1 num-devices=2 UUID=3924c0fb:af01e415:879be48a:435c75bf

Подготовка на GRUB – /boot/grub/menu.lst
В момента GRUB е настроен да бутва от /dev/hdc – (hd1,0) , но все пак ние искаме в случай, че единия диск се е „счупил“ системата да тръгне от другия.
За целта трябва да копирате вече създадената част за /dev/md0 още веднъж, но в нея заменете „hd1,0“ с „hd0,0“, a останалите менюта можете да коментирате.
Ето как изглежда при мен:

server1:~# nano /boot/grub/menu.lst
## ## End Default Options ##

title           Debian GNU/Linux RAID1, kernel 2.6.26-2-686
root            (hd1,0)
kernel          /boot/vmlinuz-2.6.26-2-686 root=/dev/md0 ro quiet
initrd          /boot/initrd.img-2.6.26-2-686

title           Debian GNU/Linux RAID1, kernel 2.6.26-2-686
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.26-2-686 root=/dev/md0 ro quiet
initrd          /boot/initrd.img-2.6.26-2-686

#title           Debian GNU/Linux RAID1, kernel 2.6.26-2-686 (single-user mode)
#root            (hd1,0)
#kernel          /boot/vmlinuz-2.6.26-2-686 root=/dev/md0 ro single
#initrd          /boot/initrd.img-2.6.26-2-686

#title          Debian GNU/Linux, kernel 2.6.26-2-686
#root           (hd0,0)
#kernel         /boot/vmlinuz-2.6.26-2-686 root=/dev/hda1 ro quiet
#initrd         /boot/initrd.img-2.6.26-2-686

#title          Debian GNU/Linux, kernel 2.6.26-2-686 (single-user mode)
#root           (hd0,0)
#kernel         /boot/vmlinuz-2.6.26-2-686 root=/dev/hda1 ro single
#initrd         /boot/initrd.img-2.6.26-2-686

### END DEBIAN AUTOMAGIC KERNELS LIST

В същия файл има korp променлива, която трябва да промените на /dev/md0 :

[...]
# kopt=root=/dev/md2 ro
[...]

Обновете отново ramdisk и рестартирайте:

server1:~# update-initramfs -u
server1:~# reboot

И това е всичко 🙂
След като системата ви се рестартира ще зареди от новосъздадения RAID1 масив.

, , , ,

3 thoughts on “Създаване на софтуерен Raid1 масив от диск с вече инсталиран линукс на него + още един

  • tiririram каза:

    Здравей,
    първо искам да кажа, че статийката е много полезна и искам да попитам слeдния въпрос:

    При създаване на файловата система за масивите кое е по удачно ext2 или ext3 и при самото създаване има ли опасност да се затрие инфото на диска който е с линукса?

    Питам защото сме пуснали един Xen serer 5.5.0 но не направихме масивите преди инсталацията, което е от съществено значение.
    Благодаря предварително :)!

  • Walker каза:

    Здравей,

    аз лично използвах ext3 като по-нова спрямо ext2, но не би трябвало да имаш проблем и с нея.
    Даже в момента като цяло предпочитам ext4, тъй като съм доволен от начина по който се държи за момента.

    Идеята като цяло е, че първоначално си имаш инсталирана ОС на единия диск, след което правиш „миграцията“ към софтуерен Raid 1, като първо си подготвяш втория диск, копираш ОС-то от първия към втория и т.н.

    Препоръчвам ти ако не си правил подобни манипулации до сега, то първо си направи един тест на цялата процедура върху тестова среда, след което предприеми действия върху работеща среда.

  • tiririram каза:

    Благодаря за отговора но за съжаление нямам машина на, която да тествам първо нещата :).

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