grub – This msdos-style partition label has no post-MBR gap

grub: This msdos-style partition label has no post-MBR gap; embedding won’t be possible

GNU grubNarazili ste na takýto problém so zápisom bootloadera grub na disk? Nasledovný príspevok je návodom, ako tento problém vyriešiť.

*grub-setup*
/usr/sbin/grub-setup: warn: This msdos-style partition label has no post-MBR gap; embedding won't be possible!.
/usr/sbin/grub-setup: error: embedding is not possible, but this is required when the root device is on a RAID array or LVM volume.
Installation finished. No error reported.

grub splashscreen
Pre úspešné pochopenie podstaty problému odporúčam preštudovať nasledovné odkazy:

Problém spočíva v tom, že prvá oblasť začína na sektore 1 a mala by začínať na sektore 63. Zlá partition table (PT = partition table = tabuľka oblastí) vyzerá teda takto:


*sfdisk -d /dev/sda*
# partition table of /dev/sda
unit: sectors

/dev/sda1 : start= 1, size= 208844, Id=fd, bootable
/dev/sda2 : start= 208845, size=195334335, Id=fd
/dev/sda3 : start=195543180, size=195334335, Id=fd
/dev/sda4 : start=390877515, size= 97514550, Id=fd

Ak budete kontrolovať PT cez fdisk -l /dev/sda, tak problém neodhalíte. Použite preto príkaz sfdisk -d /dev/sda.

Kedže na serveri pravdepodobne máte SW RAID, oprava sa dá spraviť za behu, len je potrebné trošku pomanipulovať s oblasťami. Najprv sériou príkazov vyhodíme disk /dev/sdb z raidu (disk sdb opravíme ako prvý):


*mdadm --fail /dev/md0 /dev/sdb1*
*mdadm --fail /dev/md1 /dev/sdb2*
...
*cat /proc/mdstat*
Personalities : [raid1]
md3 : active raid1 sda4[0] sdb4[2](F)
48757184 blocks [2/1] [U_]
md2 : active raid1 sda3[0] sdb3[2](F)
97667072 blocks [2/1] [U_]
md1 : active raid1 sda2[0] sdb2[2](F)
97667072 blocks [2/1] [U_]
md0 : active raid1 sda1[0] sdb1[2](F)
104320 blocks [2/1] [U_]
unused devices:

*mdamd –remove /dev/md0 /dev/sdb1*

*mdadm –remove /dev/md3 /dev/sdb4*
*cat /proc/mdstat*
Personalities : [raid1]
md3 : active raid1 sda4[0]
48757184 blocks [2/1] [U_]
md2 : active raid1 sda3[0]
97667072 blocks [2/1] [U_]
md1 : active raid1 sda2[0]
97667072 blocks [2/1] [U_]
md0 : active raid1 sda1[0]
104320 blocks [2/1] [U_]
unused devices:

Vyhodiť všetky oblasti z raidu je dôležité, pretože ak to nespravíme, kernel bude mať disk označený ako používaný a po zmene PT príkazom fdisk nedôjde k načítaniu novej PT kernelom. Fdisk pri pokuse zapísať novú PT zahlási nasledovný chybu:


*fdisk /dev/sdb*
...
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 or after you run partprobe(8) or kpartx(8)
Syncing disks.

Keď teda máme disk vyhodený z raidu, môžeme opraviť PT príkazom fdisk:


*fdisk /dev/sdb*
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').

Command (m for help): *p*

Disk /dev/sdb: 251.1 GB, 251059544064 bytes
255 heads, 63 sectors/track, 30522 cylinders
Units = cylinders of 16065 \* 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Device Boot Start End Blocks Id System
/dev/sdb1 \* 1 13 104422 fd Linux raid autodetect
/dev/sdb2 14 12172 97667167+ fd Linux raid autodetect
/dev/sdb3 12173 24331 97667167+ fd Linux raid autodetect
/dev/sdb4 24332 30522 49729207+ fd Linux raid autodetect
Command (m for help): *d*
Partition number (1-4): *1*

Command (m for help): *n*
Command action
e extended
p primary partition (1-4)
*p*
Selected partition *1*
First cylinder (1-30522, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-13, default 13):
Using default value 13

Command (m for help): *p*

Disk /dev/sdb: 251.1 GB, 251059544064 bytes
255 heads, 63 sectors/track, 30522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Device Boot Start End Blocks Id System
/dev/sdb1 1 13 104391 83 Linux
/dev/sdb2 14 12172 97667167+ fd Linux raid autodetect
/dev/sdb3 12173 24331 97667167+ fd Linux raid autodetect
/dev/sdb4 24332 30522 49729207+ fd Linux raid autodetect

Command (m for help): *a*
Partition number (1-4): *1*

Command (m for help): *p*

Disk /dev/sdb: 251.1 GB, 251059544064 bytes
255 heads, 63 sectors/track, 30522 cylinders
Units = cylinders of 16065 \* 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Device Boot Start End Blocks Id System
/dev/sdb1 \* 1 13 104391 83 Linux
/dev/sdb2 14 12172 97667167+ fd Linux raid autodetect
/dev/sdb3 12173 24331 97667167+ fd Linux raid autodetect
/dev/sdb4 24332 30522 49729207+ fd Linux raid autodetect

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

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

Chyba WARNING: Re-reading the partition table failed with error 16: Device or resource busy. sa vo výpise nevyskytuje a môžeme teda skúsiť prepísať MBR novým grubom:


*grub-setup /dev/sdb*

Skvelé, žiadna chyba. Stačí teda doriešiť druhý disk (teda ešte /dev/sda) a sme hotoví.

Kedže sme oblasť sdb1 zmenšili, nepôjde nám ju spátne pridať do raidu /dev/md0. Spravíme to teda tak, že si obsah adresára /boot odzálohujeme, raid /dev/md0 zrušíme úplne a vytvoríme nanovo. Odzálohované dáta do neho jednoducho nakopírujeme:


*cd /
tar cvzf boot-backup.tar.gz /boot
umount /boot
mdadm --stop /dev/md0
*

Ak sme ešte nedali synchronizovať raid, tak to spravíme teraz a počkáme na vysynchronizovanie. Dokončenie procesu syncronizácie je dôležité, lebo budeme potrebovať uvoľniť ešte disk /dev/sda.

Spustite si animáciu syncronizácie disku príkazom watch cat /proc/mdstat a medzi tým môžete dumať nad tým, prečo mám na disku viacej oblastí, aj keď sú všetky typu RAID1. Dôvodov je viacero:

  1. ak sa vám po určitom čase jeden disk pokazí, kúpite už radšej väčší, lebo sa viac oplatí. Vtedy na väčšom disku vytvoríte rovnako veľké oblasti, pridáte do raidu a ostane vám jedna oblasť voľná, čakajúca na ďalší väčší disk. Máte teda väčiu flexibilitu, ak nemáte disky rovnako veľké
  2. ak dôjde k chybe disku v jednej oblasti, ostatné oblasti sú aj naďalej mirrorované a teda bezpečnosť dát je lepšia
  3. z niektorej časti disku môžete mať RAID iného typu: napr. RAID0 pre dočasné súbory


*mdam --add /dev/md1 /dev/sdb2
mdadm --add /dev/md2 /dev/sdb3
mdadm --add /dev/md3 /dev/sdb4
cat /proc/mdstat*
Personalities : [raid1]
md3 : active raid1 sdb4[2] sda4[0]
48757184 blocks [2/1] [U_]
[============>........] recovery = 60.5% (29529024/48757184) finish=6.6min speed=48409K/sec
md2 : active raid1 sdb3[1] sda3[0]
97667072 blocks [2/2] [UU]
md1 : active raid1 sdb2[1] sda2[0]
97667072 blocks [2/2] [UU]
unused devices:

Po dosynchronizovaní pokračujeme teda diskom sda:


*mdadm --fail /dev/md1 /dev/sda2*
*mdadm --fail /dev/md2 /dev/sda3*
*mdadm --fail /dev/md3 /dev/sda4*
*mdadm --remove /dev/md1 /dev/sda2*
*mdadm --remove /dev/md2 /dev/sda3*
*mdadm --remove /dev/md3 /dev/sda4*
*sfdisk -d /dev/sdb | sfdisk /dev/sda*

Posledný príkaz môžeťe použiť za predpokladu, že máte disky identické. Ak nie, postupujeme za použitia fdisku rovnako, ako v prvom prípade. Predpokladajme teda, že disky sme mali rovnaké a sfdisk nám na disku sda vytvoril rovnakú PT, ako mal disk sdb. Ostáva teda znova pridať oblasti disku sda do raidu, vytvoriť z /dev/sda1 a /dev/sdb1 nový /dev/md0 a obnoviť dáta v /boot po pripojení nového raidu /dev/md0.


*mdadm --add /dev/md1 /dev/sda2*
*mdadm --add /dev/md2 /dev/sda3*
*mdadm --add /dev/md3 /dev/sda4*
*mdadm --create --level=1 --raid-dev=2 /dev/md0 /dev/sda1 /dev/sdb1*
*mkfs.ext2 /dev/md0*
*mount /boot*
*cd / && tar xvzf /boot-backup.tar.gz*

Po spustení grub-setup sme teda hotoví a môžeme nový grub vyskúšať reštartom.

Držím palce. 🙂