Partition / von btrfs -> ext4

Hallo zusammen,

ich habe auf einem UCS den ich vor einer ganzen Zeit (4.0 oder 4.1) installiert habe das Root-Dateisystem mit btrfs formatiert. Dadurch kann ich das Update auf 4.2 nicht durchführen da Docker ja nicht damit kann …

siehe:

Nun muss ich das Dateisystem entsprechend ändern. Da der UCS eine VM unter KVM ist sollte dies ja machbar sein. Ich wollte wie folgt vorgehen:

Der Ausgangspunkt ist:

UUID=4ae7424b-2790-42da-8991-ac677edbb228       /       btrfs   defaults        0       1
UUID=3fc78459-9d09-4cc5-b929-8a65acc03bfe       /boot   ext4    defaults,user_xattr     0       2
UUID=8fe3b11d-b00f-4b07-9f3b-e0d372c17950       /home   btrfs   defaults        0       2
UUID="05632109-9108-4b8d-b542-3011c188b304"     /data   btrfs   defaults        0       2
UUID=57b9afde-95e7-4e41-b1bb-258fbf0f7107       none    swap    sw      0       0

Nun bin ich wie folgt vorgegangen:

  • Einen Klone des Storage (ist ein LV) anlegen mit dd
  • Die UCS-VM beenden
  • Eine Neue VM mit SystemRescueCD vom ISO booten und zusätzlich die beiden virtuellen Platten (LV’s) einbinden und noch eine außreichend große Daten-Disk (LV) einbinden
  • In der Kopie des Storage die Partition für / mit ext4 formatieren
  • Die “alte” / Partition mounten
  • Die Datenplatte mounten
  • mit tar… ein gepacktes Archiv der alten / auf die Datenplatte erzeigen (wegen Symloinks)
  • Alte / aushängen
  • Neue / mounten (ist ja nun ext4)
  • Archiv darin entpacken
  • im gemounteten /mnt/etc/fstab den Eintrag auf ext4 anpassen (auch UUID , vorher auslesen)

Damit ist die VM aber noch nicht startbar. Irgendwo im bootloader muss noch stehen dass / in btrfs formatiert ist oder sonst wo?

Ich habe auch schon vom Rettungssystem aus den Bootloader neu geschrieben … Die Werte natürlich sinngemäß angepasst …

mount /dev/sda6 /mnt/
mount -o bind /dev /mnt/dev
mount -o bind /sys /mnt/sys
mount -t proc /proc /mnt/proc
mount -o bind /run /mnt/run
mount -o bind /dev/pts /mnt/dev/pts
cp /proc/mounts /mnt/etc/mtab
rm /mnt/etc/resolv.conf
cp /etc/resolv.conf /mnt/etc	#Nur wenn Netzanbindung vorhanden
chroot /mnt/ /bin/bash


Für Grub2 wird nun:

grub-install /dev/sda

[oder falls Fehler gemeldet werden]
grub-install --recheck /dev/sda

(ggf noch mit --force)

und anschließend:

update-grub2

ausgeführt.

Was habe ich vergessen/übersehen?

Viele Grüße
Sven

Moin,

in der chroot sollten auch die Initial Ramdisks neu gebaut werden: update-initramfs -u -k all

Weiterhin ist tar eine schlechte Variante zum vollständigen Kopieren von Dateien, weil das GNU tar leider weder ACLs noch erweiterte Attribute unterstützt. Damit werden z.B. Samba-ACLs nicht mit kopiert, und auch Dinge wie capabilities werden nicht übernommen. rsync ist daher besser geeignet, allerdings muss man auch dort -A -X als Optionen benutzen, um beides zu kopieren (ein -a genügt halt nicht). Beispiel einer vollständigen Kopie mit rsync: rsync -haxHAX --numeric-ids /old/ /new/

Und noch ein Tipp: wenn man grml als Rescue-CD nutzt, so gibt’s den Befehl grml-chroot, der die ganzen mount-Sachen für einen erledigt. Sehr praktisch. Die SystemRescueCD enthält vielleicht etwas ähnliches.

Gruß,
mosu

1 Like

Werde ich am Wochenende tsten

Danke für die Info aber in einer getrennten Root-Partition habe ich keine ACL’s sondern nur das Linux-System.

das klingt gut da ich für die Mount-Geschichte immer meinen Spickzettel brauche. Das werde ich mir anschauen.

Bitte diesen Hinweis von @Moritz_Bunkus nicht auf die leichte Schulter nehmen! Wird “irgendwie” kopiert, und nicht rsync mit den korrekten Parametern verwendet, handelt man sich sehr wahrscheinlich Folgeprobleme ein. Die tauchen vielleicht erst später auf, und sind dann nur sehr schwer zu debuggen.

Ok, ich werde es mit rsync machen …

Nur aus interesse: Werden beim UCS denn ACL’s in der / Partition (/boot, /var/, /home sind gesonderte Partitionen) verwendet?

Was fehlt mir wenn ich im Live-System ein tar cvfz … erstelle und dieses anschließend auf die neue Partition entpacke?

Hey,

  1. Überall dort, wo Freigaben mit Samba verwendet werden, kommen im Zweifelsfall ACLs und/oder erweiterte Attribute zum Zug.
  2. In /var kommen sie aufgrund des sysvol-Shares auf jeden Fall zum Zug.
  3. Einige Programme in den bin-Verzeichnissen (/bin, /sbin, /usr/bin, /usr/sbin) verwenden erweiterte Attribute, in denen Capabilities gespeichert werden, um dem Programm mehr Rechte zu geben, ohne dass es gleich als root ausgeführt werden muss.

Hier ein Beispiel, was passiert, wenn man die root-Partition ohne erweiterte Attribute sichert und wiederherstellt:

[0 root@master ~] getcap /bin/ping
/bin/ping = cap_net_raw+ep
[0 root@master ~] tar cfC - /bin ping | tar xfC - /home/mbunkus
[0 root@master ~] getcap /home/mbunkus/ping
[0 root@master ~] su - mbunkus
[0 mbunkus@master ~] ./ping localhost
ping: icmp open socket: Operation not permitted
[2 mbunkus@master ~] /bin/ping -c 1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.027 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.027/0.027/0.027/0.000 ms
[0 mbunkus@master ~]

ping benötigt die Kernel-Capability für direkten Sockelzugriff, genannt cap_net_raw. Als normaler Benutzer mbunkus habe ich diese Capability normalerweise nicht. Aber mittels des Tools setcap ist für das /bin/ping-Binary nun gesetzt, dass alle, die /bin/ping ausführen dürfen, diese Capability automatisch bekommen. Kopiere ich aber das Binary mit tar, so gehen die erweiterten Attribute und damit die Capability verloren, und ich darf es damit als normaler User nicht mehr ausführen.

Die Situation rund um tar und ACLs sowie erweiterte Attribute ist leider verworren. Die GNU-Version von tar (das ist diejenige, die unter Linux normalerweise installiert ist, so auch unter Univention) enthält zwar inzwischen Unterstützung für ACLs und erweiterte Attribute, hat diese aber standardmäßig nicht aktiviert. Man muss statt dessen die zwei Optionen --acls --xattrs hinzufügen, und ich bin anscheinend zu doof, sie richtig zu benutzen:

[0 root@master ~] getcap /bin/ping
/bin/ping = cap_net_raw+ep
[0 root@master ~] tar --acls --xattrs -c -f - -C /bin ping | tar -f - --acls --xattrs -x
[0 root@master ~] getcap ping
[0 root@master ~]

Huh…

Es gibt noch eine BSD-Variante von tar. Diese unterstützt sowohl ACLs als auch erweiterte Attribute, und das ohne zusätzliche Switche. Allerdings ist diese Variante von Haus aus nicht installiert. Sie funktioniert aber glücklicherweise problemlos, wenn man sie installiert:

[0 root@master ~] apt install bsdtar
…
[0 root@master ~] bsdtar cfC - /bin ping | bsdtar xf -
ping = cap_net_raw+ep
[0 root@master ~]

Das große Problem mit bsdtar ist, dass es auf den wenigstens Rescue-CDs mit installiert ist und somit für solche Kopieraktionen wie Ihre nicht in Frage kommt.

Daher bleibt eigentlich fast nur rsync, das zum Einen seit Ewigkeiten ACLs und erweiterte Attribute unterstützt und auf allen Rescue-CDs vorhanden ist. Die Parameter kann man sich auch gut merken; ich nutz meist -haxHAX --numeric-ids (auch in Fällen, in denen --numeric-ids vielleicht nicht nötigt ist, denn es im entscheidenden Moment zu vergessen tut richtig weh, wenn z.B. anschließend diverse Dienste nicht starten, weil ihre Verzeichnisse plötzlich falsche Besitzer haben…):

[0 root@master ~] rsync -haxHAX --numeric-ids /bin/ping .
[0 root@master ~] getcap ping
ping = cap_net_raw+ep
[0 root@master ~]

LG,
mosu

Beim tar’en am Besten immer die --numeric-owner Option verwenden, sonst können beim Entpacken auf einem anderen System als dem auf dem gepackt wurde die UserIDs und GroupIDs durcheinander gewürfelt werden.
(Per default speichert tar die Namen von Onwer und Group. Diese werden beim Entpacken dann mit Hilfe von /etc/{passwd,groups} zu IDs gemappt.)

Bin gerade dran. Geht dies:

rsync -haxHAX --numeric-ids /old/ /new/

auch mit SSH da das Ziel auf einem anderen Host liegt? ALso so etwa:

rsync -e ssh -haxHAX --numeric-ids oldhost:/mnt/backup /mnt/backup/

Ich habe also zwei Live-Systeme. Auf dem neuen ist die neue virtuelle Disk / Partiton (ext4) nach /mnt/backup gemountet. Auf oldhost ist das Backup-Image der alten Platte/Partition (brtfs) auch nach /mnt/backup/

Der Befehls-Aufruf erfolg auf dem neuen. Passt das so?

Ja klar. Bei rsync kann entweder die Quelle oder das Ziel ein entfernter Host sein, auf den dann via ssh zugegriffen wird. ssh ist bei allen auch nur halbwegs modernen rsync-Versionen bereits der Standard, sodass -e ssh auch weggelassen werden kann, sprich das hier genügt bereits:

rsync -haxHAX --numeric-ids oldhost:/mnt/backup/ /mnt/backup/

Wichtig ist der trailing slash bei der Quelle, ansonsten würde im Ziel ein Unterordner namens backup unterhalb von /mnt/backup erzeugt.

Hallo zusammen,

kam leider nicht früher dazu eine Rückmeldung zu geben. Mit der RSYNC-Lösung, welche ich über zwei Live-Systeme aufgebaut habe, und chroot wie von mir beschhrieben plus den vergessenen update-initramfs… hat es problemlos funktioniert. Konnte anschließend den Master auf die aktuelle Version bringen und habe danach noch den unter dem Master liegenden KVM-Host (Debian9) durch einen UCS-Backup ausgetauscht. Nun läuft alles rund :slight_smile:

Danke für die großartige Unterstüzung!

Mastodon