Comment copier un système de fichiers btrfs

17

Comment faire une copie complète du contenu d'un système de fichiers btrfs? Par copie complète, je veux dire non seulement les données actuelles , mais aussi différents sous-volumes avec leurs instantanés , préservant idéalement leurs structures CoW (c'est-à-dire: ne pas dupliquer des blocs avec le même contenu.

Il semble qu'une copie au niveau du bloc (comme avec dd) n'est pas une bonne idée, car elle duplique l'UUID, et il n'y a aucun moyen de le changer facilement , apparemment.

goncalopp
la source

Réponses:

4

Option 1 - Copie stupide des données puis modification de l'UUID

Assurez-vous que la partition source n'est pas montée et ne sera pas montée automatiquement.

Utilisez dd(lent, stupide) oupartclone.btrfs -b -s /dev/src -o /dev/target

Utilisez btrfstune -upour changer l'UUID après la copie et avant le montage.

Avertissement de perte de données : N'essayez PAS de (auto) monter l' original ou la copie jusqu'à ce que l'UUID ait changé


Option 2 - btrfs-clone

Je n'ai pas personnellement essayé btrfs-clone, mais il prétend cloner un système de fichiers BTRFS existant vers un nouveau, en clonant chaque sous-volume dans l'ordre.

Tom Hale
la source
1
Pour être complet, cela a été ajouté en option à btrfs-progs en 2015: github.com/kdave/btrfs-progs/commit/…
goncalopp
16

Je n'ai pas trouvé de solution toute faite à ce jour (2016-05-06), mais j'ai résolu le problème à mes fins, y compris la gestion de la copie sur écriture. Les étapes à « clone » /sourcepour /targetsont:

  1. Obtenir une liste des sous - volumes commandés par ogen: btrfs subvolume list -qu --sort ogen /source. Le tri est probablement suffisant pour garantir que les instantanés ou les sous-volumes qui dépendent des précédents sont traités en premier. Ceci est important pour gérer la copie sur écriture, car nous devons d'abord transférer les volumes de base.

  2. Rendez tous les sous-volumes en lecture seule à l'aide de btrfs property set -ts /source/some-volume ro true.

  3. Maintenant, pour chaque sous-volume de la liste ci-dessus, en commençant par le haut, procédez comme suit:

    1. Si le volume n'a pas d'UUID parent (affiché comme -) ou si l'UUID parent n'existe plus dans la liste, exécutez:btrfs send /source/some/volume | btrfs receive /target/some/

    2. Si le volume a un UUID parent qui existe toujours, nous aurions dû le transférer déjà à cause de --sort ogenet nous pouvons l'utiliser comme base pour éviter la duplication des données. Par conséquent, recherchez le chemin de l'UUID parent dans la liste et exécutez: btrfs send -p /source/parent/volume/ -c /source/parent/volume/ /source/some/volume/ | btrfs receive /target/some/(btrfs devinerait probablement l' -pargument automatiquement, mais je préfère être explicite).

    3. Après avoir exécuté l' une des commandes ci - dessus font la cible et la source à nouveau en lecture-écriture: btrfs property set -ts /source/some/volume ro false; btrfs property set -ts /target/some/volume ro false. Cette étape peut être ignorée si la source a été précédemment en lecture seule.

Cela devrait gérer de nombreux cas. Mises en garde:

  1. Il peut y avoir quelques complications en ce qui concerne la commande lors de l'imbrication de sous-volumes / instantanés.

  2. L'ensemble du processus est évidemment plus amusant lorsqu'il est écrit.

  3. btrfs sendaccepte plusieurs -carguments source ( ) de clone . Il peut être avantageux de spécifier non seulement le chemin du volume du parent, mais aussi ceux de tous les ancêtres ou simplement de tout volume précédemment envoyé. Cela n'a fait aucune différence ici, mais cela pourrait - juste une supposition - aider à éviter la duplication des données dans certains cas.

  4. Je ne sais pas si des méta-informations sur les instantanés ou les sous-volumes sont perdues en cours de route, mais à peu près tout ce qui est intéressant pour la plupart des cas d'utilisation devrait être conservé.

L'ensemble du processus m'a aidé à transférer un système de fichiers de 800 Go avec 3,8 Go utilisés (selon df) à une image de 10 Go avec 3,8 Go utilisés. Le transfert sans -pet -caurait utilisé environ 190 Go, la duplication des données a donc été évitée.

Thomas Luzat
la source
Réponse bien écrite, merci. Pouvez-vous expliquer ce que cela ogensignifie?
drumfire
@drumfire ogenest la "génération d'origine" du sous- volume . Je dois admettre que je ne comprends pas complètement les différences ou si l'utilisation de la génération (non d'origine) serait correcte, mais je suppose qu'un test a indiqué que cela fonctionnait mieux (éviter les doublons). La génération semble être mise à jour lors de la création d'instantanés basés sur un sous-volume, ce n'est pas le cas d'ogen. Je serais intéressé à entendre certaines conclusions. Il est probablement préférable de vérifier sur IRC ou sur la liste de diffusion Btrfs.
Thomas Luzat
2
Je viens de prendre l'algorithme de @ThomasLuzat, d'y ajouter quelques fluff (vérification d'erreur, etc.) et de le mettre ici: github.com/jernst/btrfs-copy-filesystem/blob/master/… . Cela a fonctionné pour mon problème de suppression d'un disque corrompu, et il n'y a aucune garantie que cela fonctionnera pour quelqu'un d'autre. Mais je poste cela ici de toute façon au cas où quelqu'un voudrait partir d'un autre endroit que le scratch pour coder cela. Dépend actuellement d'une nouvelle méthode UBOS mais devrait être facile à porter.
Johannes Ernst
6

J'ai créé un outil python qui peut le faire. J'ai fait cela parce que j'ai essayé l'approche de @Thomas Luzat dans ma propre implémentation et celle de @Johannes Ernst, et l'espace utilisé a doublé de 20 Go à 40 Go dans la procédure de clonage. Je pensais que quelque chose de plus efficace était nécessaire.

Considérez cet historique de système de fichiers commun:

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

Avec l'algorithme de Thomas, "courant" serait cloné en premier, et tous les instantanés (étant des instantanés d'anciens états de "courant") utiliseraient "courant" comme source / parent de clone. Évidemment, il serait préférable de baser snap3 sur snap4, snap2 sur snap3, etc.

Et ce n'est que la pointe de l'iceberg; trouver les "meilleures" sources de clones (en termes d'économie d'espace) dans un système de fichiers btrfs avec une histoire complexe n'est pas un problème trivial. J'ai trouvé 3 autres stratégies pour résoudre ce problème, qui semblent utiliser l'espace beaucoup plus efficacement. L'un a en fait abouti à des clones de taille légèrement inférieure à celle de la source.

Vous pouvez lire les détails sur la page github si vous êtes intéressé.

uncleremus
la source
2

Avec btrfs-send, ce que j'ai vu pour la dernière fois, il y avait encore des correctifs expérimentaux flottant sur la liste de diffusion btrfs.

psusi
la source
ce wiki linuxreviews.org/Btrfs a généralement de bons conseils.
dotbit