Journal [Btrfs et openSUSE] Épisode 1 : sous‐volumes, snapshots et rollbacks

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
45
17
août
2017

Sommaire

Btrfs is hard

« Btrfs et openSUSE » est une série de journaux sur le système de fichiers Btrfs, basée sur ma propre expérience d’utilisateur d’openSUSE. Au menu :

  • des généralités sur Btrfs  ;
  • des noms qui pètent : sous‐volumes, snapshots, rollbacks ;
  • du snapper ;
  • du grub ;
  • de la mise à jour incrémentale ;
  • des quotas ;
  • de la maintenance ;
  • des trucs spécifiques à openSUSE ;
  • des tentatives désespérées pour rester applicable à d’autres distributions ;
  • des erreurs (pas taper) ;
  • des bogues ;
  • des cris ;
  • des larmes ;
  • et bien plus ! Ou bien moins.

Aujourd’hui, l’épisode 1 : sous‐volumes, snapshots et rollbacks.

Quelques définitions

Dictionnaire

Sous‐volume

Un sous‐volume, c’est un concept qui se situe entre celui du répertoire et celui de la partition.

D’après la FAQ du wiki Btrfs, voilà ce qu’on peut faire avec :

  • un sous‐volume peut être monté indépendamment du reste du système de fichiers ;
  • il est possible de faire un snapshot d’un sous‐volume en une seule opération atomique ;
  • on peut assigner des limites de capacité à un sous‐volume via des quotas ou autrement partager l’espace de stockage entre tous les sous‐volumes. Ainsi les sous‐volumes peuvent partager des données entre eux (à travers la déduplication et les snapshots).

On peut aussi copier des sous‐volumes d’une partition Btrfs à une autre (ce sujet aura un épisode dédié !).

Snapshot

Un snapshot — un instantané, un cliché — est un clone d’un et un seul sous‐volume à un instant t.

Du coup, c’est aussi un sous‐volume. Avec un parent : le sous‐volume original.

Rappelez‐vous l’épisode précédent : on avait dit que Btrfs se basait sur la technique du Copy‐on‐Write. Eh bien, Btrfs n’est pas seulement capable de faire des copies paresseuses de fichiers ; il est capable d’en faire pour un sous‐volume entier, comprenant maints répertoires et fichiers, et ce de façon quasi‐immédiate.

Rollback

Pour un système, un rollback est la restauration d’un état précédent de ce système.

Dans notre contexte Btrfs, cela consiste à utiliser un instantané d’un sous‐volume — un cliché pris à un instant t — à la place de ce sous‐volume. Donc revenir à un état précédent de ce sous‐volume.

Une installation d’openSUSE classique

Caméléon

Voici les sous‐volumes présents sur une openSUSE fraîchement installée. Le seul écart par rapport au partitionnement par défaut est de ne pas avoir de partition /home séparée en XFS mais simplement un sous‐volume Btrfs, pour des raisons de test.

~# btrfs subvolume list /
ID 257 gen 184 top level 5 path @
ID 258 gen 971 top level 257 path @/.snapshots
ID 259 gen 985 top level 258 path @/.snapshots/1/snapshot
ID 260 gen 184 top level 257 path @/boot/grub2/i386-pc
ID 261 gen 184 top level 257 path @/boot/grub2/x86_64-efi
ID 262 gen 972 top level 257 path @/home
ID 263 gen 184 top level 257 path @/opt
ID 264 gen 925 top level 257 path @/srv
ID 265 gen 984 top level 257 path @/tmp
ID 266 gen 925 top level 257 path @/usr/local
ID 267 gen 927 top level 257 path @/var/cache
ID 268 gen 184 top level 257 path @/var/crash
ID 269 gen 184 top level 257 path @/var/lib/libvirt/images
ID 270 gen 184 top level 257 path @/var/lib/machines
ID 271 gen 184 top level 257 path @/var/lib/mailman
ID 272 gen 184 top level 257 path @/var/lib/mariadb
ID 273 gen 184 top level 257 path @/var/lib/mysql
ID 274 gen 184 top level 257 path @/var/lib/named
ID 275 gen 184 top level 257 path @/var/lib/pgsql
ID 276 gen 986 top level 257 path @/var/log
ID 277 gen 184 top level 257 path @/var/opt
ID 278 gen 986 top level 257 path @/var/spool
ID 279 gen 984 top level 257 path @/var/tmp
~# cat /etc/fstab
UUID=a2ec9936-18fe-4910-a50b-c120726264f8 swap swap defaults 0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 / btrfs relatime         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /boot/grub2/i386-pc btrfs relatime,subvol=@/boot/grub2/i386-pc         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /boot/grub2/x86_64-efi btrfs relatime,subvol=@/boot/grub2/x86_64-efi         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /home btrfs relatime,subvol=@/home         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /opt btrfs relatime,subvol=@/opt         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /srv btrfs relatime,subvol=@/srv         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /tmp btrfs relatime,subvol=@/tmp         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /usr/local btrfs relatime,subvol=@/usr/local         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/cache btrfs relatime,subvol=@/var/cache         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/crash btrfs relatime,subvol=@/var/crash         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/libvirt/images btrfs relatime,subvol=@/var/lib/libvirt/images         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/machines btrfs relatime,subvol=@/var/lib/machines         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/mailman btrfs relatime,subvol=@/var/lib/mailman         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/mariadb btrfs relatime,subvol=@/var/lib/mariadb         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/mysql btrfs relatime,subvol=@/var/lib/mysql         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/named btrfs relatime,subvol=@/var/lib/named         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/lib/pgsql btrfs relatime,subvol=@/var/lib/pgsql         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/log btrfs relatime,subvol=@/var/log         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/opt btrfs relatime,subvol=@/var/opt         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/spool btrfs relatime,subvol=@/var/spool         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /var/tmp btrfs relatime,subvol=@/var/tmp         0 0
UUID=926a75ec-a27c-488a-aa90-ce131f6cd378 /.snapshots btrfs relatime,subvol=@/.snapshots         0 0
~#

Que remarque‐t‐on au premier abord ? Trois choses :

  1. il y a beaucoup de sous‐volumes (!) ;
  2. il y a un sous‐volume @ (?) ;
  3. il y a un sous‐volume @/.snapshots et un autre @/.snapshots/1/snapshot (??).

Essayons déjà de trouver des explications à ces trois points.

Pourquoi tant de sous‐volumes ?

Minions

Essayons de répondre à la question suivante : quels sous‐volumes créer à l'installation d'une distribution GNU/Linux pour permettre de faire ensuite des snapshots pertinents du système (/) ?

Un seul sous‐volume pour / ?

Moui, le problème c’est que, sur un système complet il y a des données assez « volatiles » ou qui sont beaucoup réécrites : fichiers temporaires, caches, VM, bases de données, journaux…

Il n’est pas franchement pertinent de conserver ces données à un instant t. En outre :

  • ces données sont peu propices à l’utilisation du CoW ;
  • ces données pourraient être exclues tout simplement pour les conserver tout au long de la vie du système ; typiquement les journaux système : c’est bien de garder la trace d’une restauration.

Au final, faire régulièrement des instantanés d’un tel sous‐volume géant entraînerait une fragmentation et une consommation de l’espace disque importante en plus de ne pas être suffisamment flexible pour exclure certaines données des restaurations du système.

Un sous‐volume par répertoire de haut niveau (/usr, /etc, …) ?

Moui, mais dans ce cas impossible pour un snapshot de représenter un système fonctionnel. Souvenez‐vous, un snapshot correspond à un seul sous‐volume. Cela rend compliqué la restauration du système (il faut restaurer plusieurs sous‐volumes au lieu d’un seul).

La solution actuelle sur openSUSE

Il s’agit simplement de multiplier les sous‐volumes afin de les exclure des instantanés de /, donc :

  • exit /tmp, /var/tmp : fichiers temporaires ;
  • exit /var/cache : caches ;
  • exit /var/lib/libvirt/images, /var/lib/machines : machines virtuelles ;
  • exit /var/lib/mariadb, /var/lib/mysql, /var/lib/pgsql : bases de données ;
  • exit /var/log : on veut conserver les traces d’une restauration du système ;
  • etc.

D’où le grand nombre de sous‐volumes à l’installation. Je vous l’accorde, ce n’est pas la panacée.

Personnellement, je trouve que c’est un peu bête de créer certains de ces sous‐volumes, car on ne va pas forcément les utiliser. Tous les utilisateurs ne vont pas forcément créer une base de données ni utiliser une machine virtuelle.

Je me dis qu’on pourrait essayer de créer ces sous‐volumes à l’installation de certains paquets mais ça peut devenir vite compliqué. J’ai à ce sujet le vague souvenir qu’une mise à jour de systemd m’avait créé le sous‐volume /var/lib/machines.

Par ailleurs, puisque j’ai parlé de CoW : celui‐ci est carrément désactivé pour certains sous‐volumes.

~# lsattr -d /var/lib/{mariadb,mysql,pgsql,libvirt/images}
----------------C-- /var/lib/mariadb
----------------C-- /var/lib/mysql
----------------C-- /var/lib/pgsql
----------------C-- /var/lib/libvirt/images
~#

Le cas de @

Arobase

Je ne connais pas l’origine de ce sous‐volume.

Avant — disons en 2015, quand j’ai installé mon openSUSE Tumbleweed — on ne l’avait pas. On utilisait simplement FS_TREE, le « sous‐volume » avec l’ID 5.

Je suppose que ce FS_TREE doit être suffisamment différent des autres sous‐volumes pour lui préférer @ — qui déjà présente l’avantage d’avoir un vrai nom. Un caractère, c’est mieux que zéro.

Si vous avez des explications plus complètes sur @, n’hésitez pas à le dire dans les commentaires. ;-)

@/.snapshots et @/.snapshots/1/snapshot

Sur openSUSE, la stratégie est de mettre tous les instantanés sous le sous‐volume @/.snapshots. C’est un choix.

Plus étrange, on remarque la présence d’un premier instantané, alors que le système vient à peine d’être installé :

~# btrfs suvolume list -s /
ID 259 gen 985 top level 258 path @/.snapshots/1/snapshot
~#

Mais qu’est‐ce don’ ?

~# btrfs property /.snapshots/1/snapshot
ro=false
label=
~# mount | grep "on / "
/dev/vda2/ on / type btrfs (rw,relatime,space_cache,subvolid=259,subvol=/@/.snapshots/1/snapshot)
~# btrfs subvolume get-default /
ID 259 (@/.snapshots/1/snapshot)
~#

En clair, ce premier snapshot :

  • est le sous‐volume par défaut de / : ce n’est donc rien d’autre que notre / actuel ;
  • est en lecture‐écriture (et c’est heureux sinon on ne pourrait rien écrire sur /).

Pourquoi ne pas utiliser directement @ ?

Eh bien, c’est pour éviter d’oublier de nettoyer les données du sous‐volume initial après une première restauration.

En effet, les snapshots… ça prend de la place. Le fait d’avoir tout sous /.snapshots facilite le ménage. Mais on reparlera de ça plus tard.

Manipuler des sous‐volumes et des snapshots

Création et suppression de sous‐volumes

~# btrfs subvolume create 
btrfs subvolume create: too few arguments
usage: btrfs subvolume create [-i <qgroupid>] [<dest>/]<name>

    Create a subvolume

    Create a subvolume <name> in <dest>.  If <dest> is not given
    subvolume <name> will be created in the current directory.

    -i <qgroupid>  add the newly created subvolume to a qgroup. This
                   option can be given multiple times.

~# btrfs subvolume delete
btrfs subvolume delete: too few arguments
usage: btrfs subvolume delete [options] <subvolume> [<subvolume>...]

    Delete subvolume(s)

    Delete subvolumes from the filesystem. The corresponding directory
    is removed instantly but the data blocks are removed later.
    The deletion does not involve full commit by default due to
    performance reasons (as a consequence, the subvolume may appear again
    after a crash). Use one of the --commit options to wait until the
    operation is safely stored on the media.

    -c|--commit-after      wait for transaction commit at the end of the operation
    -C|--commit-each       wait for transaction commit after deleting each subvolume
    -v|--verbose           verbose output of operations

~#

Pas grand‐chose à dire là‐dessus.

En pratique, je n’ai créé un sous‐volume qu’une seule fois, pour rajouter /var/cache. Ce n’était pas encore un sous‐volume créé à l’installation quand j’ai installé openSUSE Tumbleweed.

Création et suppression de snapshots

~# btrfs subvolume snapshot 
btrfs subvolume snapshot: too few arguments
usage: btrfs subvolume snapshot [-r] [-i <qgroupid>] <source> <dest>|[<dest>/]<name>

    Create a snapshot of the subvolume

    Create a writable/readonly snapshot of the subvolume <source> with
    the name <name> in the <dest> directory.  If only <dest> is given,
    the subvolume will be named the basename of <source>.

    -r             create a readonly snapshot
    -i <qgroupid>  add the newly created snapshot to a qgroup. This
                   option can be given multiple times.
~#

Donc, pour créer un snapshot en lecture seule de mon système actuel :

~# mkdir -p /.snapshots/42
~# btrfs subvolume snapshot -r / /.snapshots/42/snapshot
Create a readonly snapshot of '/' in '/.snapshots/42/snapshot'
~#

J’aurais pu remplacer / par /.snapshots/1/snapshot.

Ça va très vite :

~# mkdir -p /.snapshots/43
~# time btrfs subvolume snapshot -r /.snapshots/43/snapshot
Create a readonly snapshot of '/' in '/.snapshots/43/snapshot'

real    0m0,444s
user    0m0,000s
sys     0m0,019s
~#

Enfin, un snapshot se supprime comme n’importe quel autre sous‐volume :

~# btrfs subvolume delete /.snapshots/{42,43}/snapshot
Delete subvolume (no-commit): '/.snapshots/42/snapshot'
Delete subvolume (no-commit): '/.snapshots/43/snapshot'
~# rmdir /.snapshots/{42,43}
~#

Restauration du système

1814-1830

Faire un rollback, c’est simple : c’est remplacer un sous‐volume courant par une version précédente, c’est‐à‐dire par un instantané de ce sous‐volume.

Comment pourrait-on faire ? Ça n’a pas l’air évident au premier abord. Il va falloir sans doute jouer avec le montage des sous-volumes et mv

Je simplifie le problème : ici, ce qui m’intéresse de changer, c’est le système, c’est le sous‐volume de /.
Dans ce cas, et vu notre configuration, faire une restauration revient simplement à changer le sous‐volume par défaut de /. C’est tout.

On a déjà vu quelle était la commande pour récupérer le sous‐volume par défaut :

~# btrfs subvolume get-default /
ID 259 (@/.snapshots/1/snapshot)
~#

Le setter n’est pas beaucoup plus compliqué :

~# btrfs subvolume set-default
btrfs subvolume set-default: too few arguments
usage: btrfs subvolume set-default <subvolid> <path>

    Set the default subvolume of a filesystem
~#

Mais, allez, c’est parti, on y va ! Faisons une restauration complète !
On suppose que l’instantané à restaurer existe : @/.snapshots/2/snapshot.

~# mkdir -p /.snapshots/{3,4}
~# # Création d’un instantané en lecture‐seule du système actuel.
~# btrfs subvolume snapshot -r / /.snapshots/3/snapshot
Create a readonly snapshot of '/' in '/.snapshots/3/snapshot'
~#
~# # Création d’un instantané en lecture‐écriture de l’instantané 2.
~# btrfs subvolume snapshot /.snapshots/2/snapshot /.snapshots/4
Create a snapshot of '/.snapshots/2/snapshot' in '/.snapshots/4/snapshot'
~#
~# # Définition du sous‐volume par défaut sur l’instantané 4.
~# btrfs subvolume set-default $id_snapshot_4 /
~#

Et voilà ! On peut redémarrer et booter sur notre système restauré !

Bien. Normalement, à ce moment précis, il va y avoir deux catégories de personnes :

  • celles qui vont dire : « C’est trop cooool ! » ;
  • celles qui vont dire : « Minute, papillon : il te reste encore à modifier ta configuration de GRUB pour que ça marche ! ».

Et toutes ces personnes auront raison, en un sens. Parce que tel quel, ce qu’on a fait est suffisant sur openSUSE, mais pas forcément ailleurs. Et c’est bien embêtant.

C’est si embêtant qu’on en parlera dans le prochain épisode !

That’s all folks!

Liens

Sur le wiki Btrfs :

Sur le wiki openSUSE, la liste des sous‐volumes créés par défaut.

  • # État de l'art des systèmes de fichiers

    Posté par  . Évalué à 3.

    Bonjour, merci pour ces explications.

    Je me pose une question : pourquoi préférer BTRFS aux autres systèmes de fichiers ? Comme tu l'as indiqué dans ton précédent journal, les utilisateurs voulaient du ext4 par défaut sur opensuse et red hat l'abandonne. Pourquoi donc se lancer dans ce système ?

    • [^] # Re: État de l'art des systèmes de fichiers

      Posté par  (site web personnel) . Évalué à 10.

      Ta question me laisse un peu perplexe. Personnellement, je ne préfère pas Btrfs à un autre système de fichiers :-)

      Je l'utilise simplement en ce moment parce qu'il offre des fonctionnalités qui peuvent m'être utiles et parce que je trouve intéressant d'apprendre de nouvelles choses. Que Btrfs s'impose ou non, que des gens l'apprécient ou non, je trouve qu'il y a des idées dedans qui pourront peut-être (me) servir plus tard.

      Cette série de journaux n'a pas pour but :

      • de faire une comparaison de systèmes de fichiers
      • de dire qu'il faut préférer un fs par rapport à un autre
      • d'inciter à utiliser tel ou tel fs

      J'écris juste pour présenter comment je comprends Btrfs en tant qu'utilisateur.

      Si jamais il y a des gens qui veulent découvrir Btrfs pour voir si ça pourrait leur servir, ces quelques journaux pourront peut-être leur faire gagner un peu de temps : soit à s'en détourner, soit à l'utiliser, en leur évitant d'avoir à rechercher certaines infos et trucs de base.

  • # Commentaire supprimé

    Posté par  . Évalué à 1.

    Ce commentaire a été supprimé par l’équipe de modération.

  • # Commentaire supprimé

    Posté par  . Évalué à -4.

    Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: Sur le fait qu'un snapshot ne concerne qu'un et un seul sous-volume

      Posté par  . Évalué à 1.

      Je pense que les données ne sont pas stockées "à l'intérieur" d'un sous-volume. Les données sont stockées en vrac et un sous-volume est une arborescence décrivant les répertoires, les fichiers et leurs contenus.

      Deux sous-volumes peuvent donc référencer les mêmes répertoires/fichiers ou simplement les mêmes contenus (si j'ajoute quelque chose à la suite d'un fichier, ses méta-données ont changé mais une partie du contenu est commun avec la précédente version).

  • # Le spoiler...

    Posté par  (site web personnel) . Évalué à 5. Dernière modification le 17 août 2017 à 19:10.

    … Non mais la, c'est la prison à vie et sans PC (ou alors avec Windows :) ) pour bien souffrir que tu mérites pour oser spoiler tout ce qui fait la force du film. Bon peut-être un peu moins car ça fait quand même presque 20 ans (et était déjà âgé le jour où le dessin a été fait) que le film est sorti et que ceux prévoyant de le voir l'ont déjà vu, mais sur le principe…
    (Souvenirs, souvenirs, c'était quand même une magnifique fin; mais qu'est-ce que je suis vieux)

    • [^] # Re: Le spoiler...

      Posté par  (Mastodon) . Évalué à -1.

      En même temps l'intérêt de la blague sur les spoilers du Sixième Sens c'est justement que dès les 5 premières minutes tout le monde en connaissait la fin.

      • [^] # Re: Le spoiler...

        Posté par  (Mastodon) . Évalué à 4.

        Je pense qu'il y'en a deux trois qui sont vexés parce qu'ils n'avaient encore rien compris au film 20ans après.

    • [^] # Re: Le spoiler...

      Posté par  . Évalué à 6.

      Ouai, c'est bien vrai, ça. À part ça, Dark Vador est le père de Luke Skywalker.

      • [^] # Re: Le spoiler...

        Posté par  (site web personnel) . Évalué à 7.

        Il y a pire pour être chiant en soirée : « L'expression "Sixième Sens" est un abus dans le sens où il existe beaucoup plus que cinq sens physiologiques (exemples : proprioception, thermoréception…) » (source]

        • [^] # Re: Le spoiler...

          Posté par  . Évalué à 5.

          En suivant ton lien wikipédia, on arrive sur celui des perceptions extrasensorielles où l'on trouve comme forme possible la précognition. C'est une invite à spoiler Minority report ? :-P

          Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

        • [^] # Re: Le spoiler...

          Posté par  (site web personnel) . Évalué à 6.

          Il y a aussi le sens de l'humour.

          • [^] # Re: Le spoiler...

            Posté par  . Évalué à 4.

            Les 5 sens que perd Pégase (Petit Poney) dans la série abrégée des chevaliers du zodiaque, de mémoire :
            - Le sens de l'humour (c'est pas drôle !)
            - Le sens de l'équilibre
            - Le sens des affaires
            - Le sens de la répartie (pas sûr)
            … (j'ai mauvaise mémoire)

    • [^] # Re: Le spoiler...

      Posté par  . Évalué à 5.

      Et sinon, tu savais que le Titanic n'est jamais arrivé à New-York ? ;-)

      (sauf dans "SOS fantômes 2")

      • [^] # Re: Le spoiler...

        Posté par  . Évalué à 2.

        Rha !!! Tu m'as gâché le plaisir de regarder SOS Fantôme 2 que je n'ai toujours pas vu (ni le 1 d'ailleurs).

        Cette signature est publiée sous licence WTFPL

  • # Merci !

    Posté par  (site web personnel) . Évalué à 3.

    Merci pour ces explications, j'ai enfin compris pourquoi openSUSE nous proposait tant de sous-volumes à l'installation !

    Mais effectivement c'est pas très user friendly.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.