Nach einem Kernel-Update startete mein Raid nicht mehr. Recherchen ergaben, dass ein Superblock neuerdings am Ende der Platte gesucht wird (Ursache = neue mdadm-Version). Ist das Ende der Platte gleichzeitig das Ende einer Partition, ist dort kein Platz für einen Superblock. Die Partition muss um wenige MB verkleinert werden.

Aktuelle Kernel (ab 2.21.0) fangen das Problem zuverlässig auf. Die Hilfestellung aus spline.eisfair waren für mich sehr lehrreich was den Umgang mit Software-Raid betrifft, weshalb ich dieses HowTo zur Verfügung stelle. Darüber hinaus kann die beschriebene Maßnahme notwendig werden, wenn das Raid auf einen anderen Server umziehen soll. Klassische Tools, wie z.B. „gparted“, können im Raid nicht eingesetzt werden, dieses HowTo arbeitet ausschließlich mit Eisfair-Boardmitteln.

Ausgangslage

  • Software-Raid /dev/md0 bestehend aus /dev/sdc1 und /dev/sdd1
  • nach einem Neustart des Servers wird das Raid nicht mehr eingebunden
  • Setup → System Administration → Filesystems →  mdadm → Raid Management → Show Raid-Status:
    • Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath]
      unused devices: <none>
  • … → start mdadm:
    •  * Starting mdadm …Activate configuration now (y/n) [yes]?
      No RAID(MD) devices found
  • # mdadm –assemble –scan
    • mdadm: WARNING /dev/sdd1 and /dev/sdd appear to have very similar superblocks.
      If they are really different, please –zero the superblock on one\\If they are the same or overlap, please remove one from the DEVICE list in mdadm.conf.
      mdadm: No arrays found in config file or automatically
      (man beachte „/dev/sdd“ ohne 1)

Vorhandene Partitionen im Detail

# fdisk -l
Device     Boot  Start       End Sectors Size    Id  Type
/dev/sdc1  2048  1953525167  1953523120  931.5G  fd  Linux raid autodetect
/dev/sdd1  2048  1953525167  1953523120  931.5G  fd  Linux raid autodetect

Disk /dev/sdd: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x1dde783f

/dev/sdc und /dev/sdd sind identisch

Das Prinzip

  • Nach Möglichkeit wird die vorhandene Partition zunächst dem Füllstand angepasst (das erspart viel Zeit)
  • Das Raid wird an die verkleinerte Partitionsgröße angepasst
  • /dev/sdc1 wird aus dem Raid entfernt, neu partitioniert und wieder eingehängt
    • die nachfolgende Synchronisation mit /dev/sdd1 dauert einige Zeit
  • /dev/sdd1 wird aus dem Raid entfernt, neu partitioniert und wieder eingehängt
    • die nachfolgende Synchronisation mit /dev/sdd1 dauert einige Zeit
  • Raid wieder vergrößern
  • Dateisystem des Raid wieder vergrößern 
    • die nachfolgende Synchronisation mit /dev/sdd1 dauert einige Zeit

Der Raid-Verbund der 1TB-Platten mit einem Füllstand von etwa 16% stand dem Server für ca. 3 Stunden nicht zur Verfügung. Insgesamt dauerte die Maßnahme ca. 12 Stunden, das ist aber abhängig von der verwendeten Hardware.

Die Umsetzung

Zunächst wird der Füllstand geprüft:

# df /dev/md0
Filesystem  1K-blocks  Used       Available  Use%  Mounted on
dev/md0     961433544  142717184  769878288  16%   /data

Dann interessiert auch die Blockgröße des Dateisystems:

# tune2fs -l /dev/md0 | grep "Block size"
Block size:               4096

Die Platten sollten gut funktionieren (S.M.A.R.T-Werte beachten) und ein funktionierendes Backup sollte vorhanden sein.

Los geht's:

Alle Dienste mit Zugriff auf das Raid müssen gestoppt werden (z.B. Samba, Mail, Apache, Monitoring-Tools…).

Der Raid-Verbund wird ausgehängt. Ab diesem Punkt sind die Daten auf dem Server nicht mehr verfügbar:

# umount /data

Das Dateisystem wird überprüft:

# e2fsck -f -C0 /dev/md0

Auf meinem System sind 16% von 931GB belegt (= 149GB). Damit möglichst wenig fragmentiert wird, gebe ich etwas „Luft“ und verkleinere die Partition zunächst auf 190GB.

„resize2fs“ fordert Größenangaben in Blöcken an:

190GB * 1024 * 1024 * 1024 = 204010946560 Byte
204010946560 / 4096 (Blockgröße) = 49807360

# resize2fs -p /dev/md0 49807360

Der Vorgang dauert, je nachdem wie viel Daten umgelagert werden müssen, 30-90 Minuten. Danach sollte das Dateisystem nochmals geprüft werden:

# e2fsck -f -C0 /dev/md0

Das Dateisystem kann dem Server wieder zur Verfügung werden, weitere Schritte können im laufenden Betrieb ausgeführt werden.

# mount -a

Alle Dienste mit Zugriff auf das Raid können wieder gestartet werden.

Jetzt muss das Raid der neuen Partitionsgröße angepasst werden. Dazu werden zunächst eventuell aktivierte Bitmaps deaktiviert:

# mdadm -G --bitmap=none /dev/md0

Auch das Raid benötigt etwas „Luft“ für die Partition, hier wird auf 200GiB verkleinert:

# mdadm -G -z200G /dev/md0

Die folgenden Schritte müssen für beide Platten nacheinander ausgeführt werden:

Aushängen der Redundanz:

# mdadm --fail /dev/md0 /dev/sdc1
# mdadm --remove /dev/md0 /dev/sdc1

Superblock löschen:

# mdadm --zero-superblock /dev/sdc1

Den Erfolg kann man überprüfen:

# cat /proc/mdstat

/dev/sdc1 ist im Raid nicht mehr enthalten.

Die Platte wird jetzt neu formatiert. Zuletzt war der End-Sector 1953523120. Wird der neue End-Sector auf 1953520000 gesetzt, bleiben am Ende gut 2MB freier Platz hinter der Partition:

# fdisk /dev/sdc

Command (m for help): //**d**//
Selected partition 1
Partition 1 has been deleted.

Command (m for help): //**n**//
Partition type
   p primary (0 primary, 0 extended, 4 free)
   e extended (container for logical partitions)
Select (default p): //**p**//
Partition number (1-4, default 1): 1
First sector (2048-1953525167, default 2048): 2048
Last sector, +sectors or +size{K,M,G,T,P} (2048-1953525168, default 1953525168): //**1953520000**//

Created a new partition 1 of type 'Linux' and of size xx.x GiB.

Command (m for help): //**t**//
Selected partition 1
Partition type (type L to list all types): //**fd**//
Changed type of partition 'Linux' to 'Linux raid autodetect'.
Command (m for help): //**w**//
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Das Ergebnis wird überprüft:

# cat /proc/partitions

In der Partitionstabelle ist jetzt sdc1 etwas kleiner als sdd1. Ist zu einem späteren Zeitpunkt auch sdd1 verkleinert, sind die Werte wieder identisch.

Die Partition wird nun wieder dem Raid hinzugefügt:

# mdadm --add /dev/md0 /dev/sdc1

Es folgt eine Synchronisation, die Daten von sdd1 werden dabei auf sdc1 geschrieben. Der Vorgang dauerte bei mir etwa 30 Minuten. Den Fortschritt kann man mit

# watch cat /proc/mdstat 

anzeigen lassen, CTRL-C/STRG-C bricht die Anzeige ab. Wenn fertig ist sdc1 wieder vollständig im Raid eingebunden und enthält auch wieder alle Daten.

Jetzt muss die zweite Platte /dev/sdd mit identischen Partitions-Informationen gefüttert werden:

  • d.h. alle vorangegangenen Maßnahmen mit sdd wiederholt werden (empfohlen)
  • oder dieser Abschnitt wird durchgeführt:

Kopieren der Partitionsinformationen von sdc nach sdd:
(ACHTUNG sgdisk -R erwartet als ersten Parameter das ZIEL. Eine Verwechslung zerstört alle Daten!!!)

# sgdisk -R /dev/sdd /dev/sdc

Setze neu GUIDs auf /dev/sdd:

# sgdisk -G /dev/sdd

Das Ergebnis wird überprüft:

# cat /proc/partitions

/dev/sdc1 und /dev/sdd1 sind jetzt identisch.

Ab hier wieder für beide Partitionierungs-Varianten:

Es folgt eine Synchronisierung von sdd. Prüfung mit:

# watch cat /proc/mdstat 

Wenn fertig, wird das Raid und das Dateisystem wieder vergrößert.

Vergrößerung des Raid auf die ganze Partition:

# mdadm -G -zmax /dev/md0

Vergrößerung des Dateisystem auf das ganze Raid:

# resize2fs -p /dev/md0

Hiernach wurden bei mir ca 800GB neu synchronisiert, das dauerte etwa 8 Stunden. Auch hier kann mit

# watch cat /proc/mdstat

der Fortschritt überprüft werden. Nach Abschluss können Bitmaps wieder aktiviert werden:

# mdadm -G --bitmap=internal /dev/md0

Die Verkleinerung des Raid ist damit abgeschlossen.

Das Ergebnis

# fdisk -l
Device     Boot  Start       End         Size    Id  Type
/dev/sdc1  2048  1953520000  1953517953  931.5G  fd  Linux raid autodetect
/dev/sdd1  2048  1953520000  1953517953  931.5G  fd  Linux raid autodetect

Disk /dev/md0: 931.5 GiB, 1000201125888 bytes, 1953517824 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Mit diesem Raid-Verbund startet mein Server mit jeder mdadm-Version wieder normal.

Danksagung

Ich bin keinesfalls in der Lage solche Vorgänge selbst zu erarbeiten. Meinen Dank richte ich insbesondere an Thomas Zweifel, Marcus Roeckrath, Holger Bruenjes und Stefan Welte für Analyse und Behebung meines Problems, sowie Tom Bork für die resultierende Überarbeitung des Kernels. Alle Beteiligten lieferten die für diesen Artikel notwendigen Grundlagen und erweiterten meinen Horizont deutlich.

Grundsätzlich aber auch ein „Danke“ an alle, die am Eisfair-System in irgendeiner Weise aktiv oder passiv mitwirken. Es ist und bleibt ein tolles Server-System!