So kopieren Sie ein btrfs-Dateisystem

17

Wie kann eine vollständige Kopie des Inhalts eines btrfs-Dateisystems erstellt werden? Mit vollständiger Kopie meine ich nicht nur die aktuellen Daten , sondern auch verschiedene Subvolumes mit ihren Schnappschüssen , wobei ihre CoW-Strukturen idealerweise erhalten bleiben (dh keine Blöcke mit demselben Inhalt duplizieren.

Es scheint, dass eine Kopie auf Blockebene (wie mit dd) keine gute Idee ist, da sie die UUID dupliziert und es anscheinend keine Möglichkeit gibt, sie einfach zu ändern .

Goncalopp
quelle

Antworten:

4

Option 1 - Dumme Datenkopie, dann UUID ändern

Stellen Sie sicher, dass die Quellpartition nicht bereitgestellt ist und nicht automatisch bereitgestellt wird.

Verwenden Sie entweder dd(langsam, dumm) oderpartclone.btrfs -b -s /dev/src -o /dev/target

Verwenden Sie btrfstune -udiese Option, um die UUID nach dem Kopieren und vor dem Mounten zu ändern.

Datenverlust - Warnung : Do NOT versuchen, (auto) montieren entweder Original oder Kopie , bis die UUID hat sich geändert


Option 2 - btrfs-clone

Ich habe es nicht persönlich versucht btrfs-clone, aber es gibt vor, ein vorhandenes BTRFS-Dateisystem in ein neues zu klonen und jedes Subvolume der Reihe nach zu klonen.

Tom Hale
quelle
1
Der Vollständigkeit halber wurde dies 2015 als Option zu btrfs-progs hinzugefügt: github.com/kdave/btrfs-progs/commit/…
goncalopp
16

Ich habe bis heute (06.05.2016) keine fertige Lösung gefunden, aber das Problem für meine Zwecke gelöst, einschließlich der Copy-on-Write-Behandlung. Die Schritte zu „klonen“ /sourcezu /targetwerden:

  1. Holen Sie sich eine Liste der Subvolumes, sortiert nach ogen: btrfs subvolume list -qu --sort ogen /source. Das Sortieren reicht wahrscheinlich aus, um sicherzustellen, dass Snapshots oder Subvolumes, die von vorherigen abhängen, zuerst verarbeitet werden. Dies ist wichtig für den Umgang mit Copy-on-Write, da zuerst die Basisvolumes übertragen werden müssen.

  2. Machen Sie alle Subvolumes schreibgeschützt mit btrfs property set -ts /source/some-volume ro true.

  3. Führen Sie nun für jedes Teilvolumen aus der obigen Liste, beginnend oben, Folgendes aus:

    1. Wenn das Volume keine übergeordnete UUID (angezeigt als -) hat oder die übergeordnete UUID nicht mehr in der Liste vorhanden ist, führen Sie Folgendes aus:btrfs send /source/some/volume | btrfs receive /target/some/

    2. Wenn das Volume eine übergeordnete UUID hat, die noch vorhanden ist, sollten wir diese bereits übertragen haben, --sort ogenund wir können diese als Basis verwenden, um Datenverdopplungen zu vermeiden. Suchen Sie daher den Pfad der übergeordneten UUID in der Liste und führen Sie btrfs send -p /source/parent/volume/ -c /source/parent/volume/ /source/some/volume/ | btrfs receive /target/some/Folgendes aus : (btrfs würde das -pArgument wahrscheinlich automatisch erraten , aber ich bevorzuge es, explizit zu sein).

    3. Nachdem Sie einen der oben genannten Befehle ausgeführt haben, lassen Sie das Ziel und die Quelle erneut lesen und schreiben : btrfs property set -ts /source/some/volume ro false; btrfs property set -ts /target/some/volume ro false. Dieser Schritt kann übersprungen werden, wenn die Quelle zuvor schreibgeschützt war.

Dies sollte viele Fälle behandeln. Vorsichtsmaßnahmen:

  1. Beim Verschachteln von Subvolumes / Snapshots kann es zu Komplikationen bei der Reihenfolge kommen.

  2. Der gesamte Prozess macht offensichtlich mehr Spaß, wenn Skripte erstellt werden.

  3. btrfs sendakzeptiert mehrere clone source ( -c) Argumente. Es kann vorteilhaft sein, nicht nur den Datenträgerpfad des übergeordneten Datenträgers anzugeben, sondern auch den eines Vorfahren oder einfach eines zuvor gesendeten Datenträgers. Hier machte es keinen Unterschied, aber es könnte - nur eine Vermutung - in einigen Fällen helfen, Datenverdopplungen zu vermeiden.

  4. Ich bin mir nicht sicher, ob Metainformationen zu Snapshots oder Subvolumes auf dem Weg verloren gehen, aber fast alles, was für die meisten Anwendungsfälle interessant ist, sollte erhalten bleiben.

Der gesamte Prozess hat mir geholfen, ein 800-GB-Dateisystem mit 3,8 GB (entsprechend df) auf ein 10-GB-Image mit 3,8 GB zu übertragen. Die Übertragung ohne -pund -chätte etwa 190 GB verbraucht, sodass eine Duplizierung der Daten tatsächlich vermieden wurde.

Thomas Luzat
quelle
Gut geschriebene Antwort, danke. Können Sie erklären, was ogenbedeutet?
Trommelfeuer
@drumfire ogenist die "Ursprungsgeneration" des Subvolumens. Ich muss zugeben, dass ich die Unterschiede nicht vollständig verstehe oder ob die Verwendung der (Nicht-Ursprungs-) Generation korrekt wäre, aber ich gehe davon aus, dass ein Test ergab, dass dies besser funktioniert hat (Vermeidung von Doppelarbeit). Die Generation scheint aktualisiert zu werden, wenn Snapshots basierend auf einem Subvolume erstellt werden, ogen nicht. Ich würde gerne etwas über einige Ergebnisse erfahren. Am besten überprüfen Sie das IRC oder die Btrfs-Mailingliste.
Thomas Luzat
2
Ich habe gerade den Algorithmus von @ThomasLuzat genommen, einige Flusen hinzugefügt (Fehlerprüfung usw.) und ihn hier eingefügt: github.com/jernst/btrfs-copy-filesystem/blob/master/… . Es hat bei meinem Problem funktioniert, eine beschädigte Festplatte zu verlassen, und es gibt keine Garantie dafür, dass es für andere funktioniert. Aber ich poste dies trotzdem hier, falls jemand von einem anderen Ort als von vorne anfangen möchte, um dies zu codieren. Derzeit hängt von einer neuen UBOS-Methode ab, sollte aber einfach zu portieren sein.
Johannes Ernst
6

Ich habe ein Python-Tool erstellt, das dies kann. Ich habe dies getan, weil ich den Ansatz von @Thomas Luzat sowohl in meiner eigenen als auch in der Implementierung von @Johannes Ernst ausprobiert habe und der verwendete Speicherplatz beim Klonen von 20 GB auf 40 GB verdoppelt wurde. Ich dachte, etwas effizienteres wäre nötig.

Betrachten Sie diesen allgemeinen Dateisystemverlauf:

current ---------------------------------\
             |       |        |          |
           snap4   snap3    snap2      snap1

Mit dem Algorithmus von Thomas würde "current" zuerst geklont, und alle Snapshots (Schnappschüsse früherer Zustände von "current") würden "current" als Klonquelle / übergeordnetes Element verwenden. Offensichtlich wäre es besser, snap3 auf snap4, snap2 auf snap3 usw. zu basieren.

Und das ist nur die Spitze des Eisbergs; Das Finden der "besten" Klonquellen (in Bezug auf Platzersparnis) in einem btrfs-Dateisystem mit einem komplexen Verlauf ist ein nicht triviales Problem. Ich habe 3 andere Strategien entwickelt, um dieses Problem zu lösen, die den Raum viel effizienter zu nutzen scheinen. Man hat tatsächlich zu Klongrößen geführt, die etwas unter der der Quelle liegen.

Sie können die Details auf der Github-Seite lesen, wenn Sie interessiert sind.

uncleremus
quelle
2

Mit btrfs-send, was ich zuletzt gesehen habe, schwebten immer noch experimentelle Patches auf der btrfs-Mailingliste herum.

psusi
quelle
Dieses linuxreviews.org/Btrfs Wiki enthält normalerweise gute Hinweise.
Dotbit