Sommaire
« 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 bugs
- des cris
- des larmes
- et bien plus ! ou bien moins
Aujourd'hui, l'épisode 2 : snapper et GRUB2.
snapper : un gestionnaire d'instantanés
Aperçu
snapper est un outil, sous licence GPL-2.0, pour gérer des snapshots. Il a été créé par Arvin Schnell de chez SUSE.
Ses objectifs :
- Prendre des instantanés automatiquement :
- Nettoyer les instantanés anciens automatiquement
- Fournir des commandes simples pour :
- prendre des instantanés manuellement
- comparer des instantanés
- faire des restaurations
Il se veut indépendant du système de fichiers : par exemple, snapper serait capable de prendre des instantanés avec LVM et ext4 – heu en fait non, pas ext4, c'est une blague…
Si aujourd'hui snapper est disponible sur la plupart des distributions GNU/Linux, sur openSUSE il fait partie intégrante du système. Il y a même un module YaST permettant de réaliser certaines opérations avec une interface graphique.
(avec un style début année 2000 du meilleur goût ;-))
En pratique
Lister les instantanés
Pour lister les instantanés pris par snapper :
~# snapper ls
Type | # | Pre # | Date | Utilisateur | Nettoyer | Description | Données utilisateur
-------+----+-------+---------------------------------+-------------+----------+--------------+--------------------
single | 0 | | | root | | current |
single | 68 | | sam. 12 août 2017 20:56:53 CEST | root | number | |
single | 69 | | mer. 16 août 2017 20:07:58 CEST | root | number | |
single | 70 | | jeu. 17 août 2017 21:17:25 CEST | root | number | |
pre | 71 | | ven. 18 août 2017 22:19:46 CEST | root | number | zypp(zypper) | important=no
post | 72 | 71 | ven. 18 août 2017 22:20:32 CEST | root | number | | important=no
~#
snapper repère les instantanés en fouillant dans /.snapshots/*/
à la recherche d'un fichier info.xml
. Voici par exemple le contenu de /.snapshots/70/info.xml
:
<?xml version="1.0"?>
<snapshot>
<type>single</type>
<num>70</num>
<date>2017-08-17 19:17:25</date>
<cleanup>number</cleanup>
</snapshot>
Vous noterez la présence d'une colonne « type ». snapper définit en effet trois sortes d'instantanés :
- single : un instantané classique ;
- pre : un instantané pris avant l'utilisation d'un outil pouvant modifier le système (pris au démarrage du gestionnaire de paquets par exemple).
- post : un instantané pris après l'utilisation de cet outil.
C'est une distinction propre à snapper, ça reste des snapshots Btrfs tout à fait similaires !
Créer et supprimer des instantanés
Voici la syntaxe, très simple, pour la création d'un instantané :
snapper create [-c empty-pre-post|number|timeline]
L'option -c
permet de dire à snapper que l'instantané doit être nettoyé. Sans cette option, le snapshot ne sera jamais supprimé automatiquement. Voir plus bas la partie nettoyage.
La suppression est aussi très simple :
snapper delete [-s,--sync] <id>...|<id>-<id>
On peut spécifier un ou plusieurs instantanés à supprimer : snapper delete 68
, snapper delete 68 69 70
.
On peut spécifier un intervalle : snapper delete 68-70
.
L'option -s
permet d'attendre la fin de la suppression des données avant de rendre la main ; autrement, la suppression des données se fait de manière asynchrone.
Comparer des instantanés
Trois commandes disponibles :
-
snapper status a..b
: affiche la liste des fichiers et dossiers qui ont été créés, modifiés ou supprimés entre les instantanésa
etb
. -
snapper diff a..b
: affiche le contenu des fichiers et dossiers qui ont été créés, modifiés ou supprimés entre les instantanésa
etb
. -
snapper xadiff a..b
: affiche les attributs étendus des fichiers et dossiers qui ont été… vous savez la suite.
Attention, ça peut être très très lent.
Restaurer des instantanés
Pour le système (/
) :
~# snapper rollback 2
Création d'un instantané en lecture-seule du système actuel. (Instantané 4.)
Création d'un instantané en lecture-écriture de l'instantané 2. (Instantané 5.)
Définition du sous-volume par défaut sur l'instantané 5.
#
(C'est l'équivalent des commandes Btrfs qu'on a vues dans l'épisode précédent.)
Il est également possible de faire des « restaurations à chaud ». Les sous-volumes ne sont pas échangés, seulement les fichiers sont remplacés :
snapper undochange <id> <id> [fichiers]
Nettoyage automatique
snapper introduit trois stratégies de nettoyage :
- empty-pre-post : comparaison de chaque paire d'instantanés pre/post ; si aucune différence, suppression de la paire.
- number : au delà d'un certains nombres de snapshots taggés number, les plus anciens commencent à être supprimés ; il n'y a que cette stratégie qui fasse vraiment sens pour des snapshots pris manuellement.
- timeline : c'est la même chose que number, mais réservé aux instantanés taggés timeline, c'est-à-dire pris périodiquement par snapper.
Le nettoyage automatique des instantanés se fait grâce à une tâche cron (/etc/cron.daily/suse.de-snapper
) qui appelle les commandes :
snapper cleanup empty-pre-post
snapper cleanup number
snapper cleanup timeline
Gare à la configuration !
Sur openSUSE, une configuration snapper est créée et activée à l'installation. Sinon, pour créer une configuration, la syntaxe est :
snapper [-c nom_config] <chemin_du_sous-volume>
Par exemple :
~# snapper create-config / # configuration par défaut "root"
Échec de la création de la configuration (subvolume already covered).
~# snapper --config opt create-config /opt # configuration pour un autre sous-volume
~# snapper list-configs
Configuration | Sous-volume
--------------+------------
opt | /opt
root | /
~#
Sur openSUSE, la configuration de snapper a causé bien des déboires aux utilisateurs.
~# snapper --config opt get-config
Clé | Valeur
-----------------------+-------
ALLOW_GROUPS |
ALLOW_USERS |
BACKGROUND_COMPARISON | yes # "yes" cause des crashs du démon snapper en cas de gros diffs
# entre 2 snapshots (typiquement après une grosse màj)
EMPTY_PRE_POST_CLEANUP | yes
EMPTY_PRE_POST_MIN_AGE | 1800
FSTYPE | btrfs
NUMBER_CLEANUP | yes
NUMBER_LIMIT | 50 # 50 snapshots associés à l'algo de nettoyage "number"
NUMBER_LIMIT_IMPORTANT | 10 # +10 snapshots avec l'attribut "important" à conserver
NUMBER_MIN_AGE | 1800
QGROUP |
SPACE_LIMIT | 0.5
SUBVOLUME | /opt
SYNC_ACL | no
TIMELINE_CLEANUP | yes
TIMELINE_CREATE | yes # un nouveau snapshot toutes les heures
TIMELINE_LIMIT_DAILY | 10 # garder 1 snapshot par jour sur 10 jours différents max
TIMELINE_LIMIT_HOURLY | 10 # garder 1 snapshot par heure sur 10 heures différents max
TIMELINE_LIMIT_MONTHLY | 10 # garder 1 snapshot par mois sur 10 mois différents max
TIMELINE_LIMIT_WEEKLY | 0
TIMELINE_LIMIT_YEARLY | 10 # …
TIMELINE_MIN_AGE | 1800
~#
Pour un peu qu'on soit joueur (installations/désinstallations de logiciels fréquentes), les instantanés pouvaient très vite s'accumuler avant que la tâche cron de nettoyage ne se déclenche – avec des réglages beaucoup trop laxistes.
Et l'espace disque libre de se réduire… jusqu'à rendre le système inutilisable ou presque. Surtout qu'il était et qu'il est toujours assez fréquent d'avoir de « petites » partitions racines et une partition /home
séparée beaucoup plus grande !
Ce phénomène de saturation de la partition racine par les instantanés a causé beaucoup de tort – à tort – à Btrfs et explique en grande partie, à mon avis, son rejet par bien des utilisateurs d'openSUSE.
Depuis :
- la taille de la partition racine proposée à l'installation est maintenant de 40 Go ; si inférieure, snapper est désactivé ;
- l'introduction du sous-volume
/var/cache
a permis de diminuer sensiblement la taille des snapshots (voir l'épisode précédent) ; - depuis la version 0.3, snapper utilise les quotas Btrfs pour limiter la taille prise par les snapshots – ce sont les variables
QGROUP
etSPACE_LIMIT
que vous pouvez voir dans la configuration. C'est bien plus efficace que les autres stratégie de nettoyage… mais pour cela il faut activer les quotas Btrfs, ce que l'on verra dans un prochain épisode.
En cas de souci, voici une configuration très safe pour du desktop, qui n'utilise pas les quotas :
~# snapper get-config
Clé | Valeur
-----------------------+-------
ALLOW_GROUPS |
ALLOW_USERS |
BACKGROUND_COMPARISON | no # évite au démon snapper de crasher à la première
# grosse mise à jour
EMPTY_PRE_POST_CLEANUP | yes
EMPTY_PRE_POST_MIN_AGE | 1800
FSTYPE | btrfs
NUMBER_CLEANUP | yes
NUMBER_LIMIT | 3 # c'est largement suffisant
NUMBER_LIMIT_IMPORTANT | 3 # ça aussi
NUMBER_MIN_AGE | 1800
SUBVOLUME | /
SYNC_ACL | no
TIMELINE_CLEANUP | no
TIMELINE_CREATE | no # pas de création périodique
TIMELINE_LIMIT_DAILY | 0
TIMELINE_LIMIT_HOURLY | 0
TIMELINE_LIMIT_MONTHLY | 0
TIMELINE_LIMIT_WEEKLY | 0
TIMELINE_LIMIT_YEARLY | 0
TIMELINE_MIN_AGE | 1800
~#
C'est celle que j'utilise en ce moment. La commande snapper set-config CLÉ=VALEUR
permet de modifier la configuration.
GRUB2 : booter sur du Btrfs
Le chargeur d'amorçage d'openSUSE
Attention, danger : on rentre dans de l'openSUSE-überspecifik. Deuxième danger : je ne connais pas bien GRUB. Toujours là ? Alors allons-y !
openSUSE a une collection de patchs pour le chargeur d'amorçage GRUB2 ainsi qu'une configuration personnalisée, liée à snapper, qui permettent :
- de faire des restaurations du système sans avoir à modifier la configuration du chargeur d'amorçage
- d'explorer les snapshots en lecture seule du système directement depuis le menu du chargeur d'amorçage
- de booter sur ces snapshots !
Je ne sais pas si d'autres distributions intègrent des patchs similaires et/ou une configuration de GRUB2 pour Btrfs. J'ai juste aperçu grub-btrfs, une configuration de GRUB écrite par un utilisateur d'Arch Linux. Cela pourrait être intéressant d'en discuter dans les commentaires ;-)
De jolies images
Pour vous donner envie, voici quelques captures d'écran des différents menus du GRUB d'openSUSE. La résolution est mauvaise, c'est une machine virtuelle, désolé…
- Menu principal :
- Liste des snapshots (dommage, on ne voit pas les lignes complètes avec cette faible résolution) :
- Menu d'un snapshot bootable
Comment ça marche ?
Configuration
Prenons les choses à l'envers et regardons d'abord la configuration.
Tout d'abord, le contenu du fichier /etc/grub.d/80_suse_btrfs_snapshot
est ajouté à /boot/grub2/grub.cfg
au moment de sa génération :
#! /bin/sh
set -e
if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] &&
[ "x${GRUB_FS}" = "xbtrfs" ] ; then
cat << \EOF
if [ -f "/.snapshots/grub-snapshot.cfg" ]; then
source "/.snapshots/grub-snapshot.cfg"
fi
EOF
fi
Ces quelques lignes ne font que sourcer le fichier /.snapshots/grub-snapshot.cfg
qui lui-même ne fait rien d'autre que sourcer les fichiers /.snapshots/*/grub-snapshot.cfg
:
~# cat /.snapshots/grub-snapshot.cfg
if [ -z "$extra_cmdline" ]; then
submenu "Start bootloader from a read-only snapshot" {
if [ -f "/.snapshots/72/grub-snapshot.cfg" ]; then
source "/.snapshots/72/grub-snapshot.cfg"
fi
if [ -f "/.snapshots/71/grub-snapshot.cfg" ]; then
source "/.snapshots/71/grub-snapshot.cfg"
fi
if [ -f "/.snapshots/70/grub-snapshot.cfg" ]; then
source "/.snapshots/70/grub-snapshot.cfg"
fi
if [ -f "/.snapshots/69/grub-snapshot.cfg" ]; then
source "/.snapshots/69/grub-snapshot.cfg"
fi
if [ -f "/.snapshots/68/grub-snapshot.cfg" ]; then
source "/.snapshots/68/grub-snapshot.cfg"
fi
if [ x$snapshot_found != xtrue ]; then
submenu "Not Found" { true; }
fi
}
fi
~#
C'est snapper qui se charge de modifier le fichier /.snapshots/grub-snapshot.cfg
et de rajouter le fichier /.snapshots/<id>/grub-snapshot.cfg
à la prise de l'instantané <id>
:
~# ls /.snapshots/70/
grub-snapshot.cfg info.xml snapshot
~# cat grub-snapshot.cfg
if [ -f "/.snapshots/70/snapshot/boot/grub2/grub.cfg" ]; then
snapshot_found=true
saved_subvol=$btrfs_subvol
menuentry " openSUSE Tumbleweed (4.11.8-2,2017-08-17T19:17)" "/.snapshots/70/snapshot" "/@/.snapshots/70/snapshot" {
btrfs_subvol="$3"
extra_cmdline="rootflags=subvol=$3"
export extra_cmdline
snapshot_num=70
export snapshot_num
configfile "$2/boot/grub2/grub.cfg"
btrfs_subvol=$saved_subvol
}
fi
~#
Ainsi, pas besoin de régénérer le grub.cfg
pour rajouter des instantanés en lecture seule dans les menus de GRUB.
Concernant, le menu principal, dans /boot/grub2/grub.cfg
justement :
### BEGIN /etc/grub.d/10_linux ###
menuentry 'openSUSE Tumbleweed' --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-4dcb59ef-2749-4017-94f4-d046a2cd7391' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod btrfs
set root='hd0,msdos2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos2 --hint-efi=hd0,msdos2 --hint-baremetal=ahci0,msdos2 --hint='hd0,msdos2' 4dcb59ef-2749-4017-94f4-d046a2cd7391
else
search --no-floppy --fs-uuid --set=root 4dcb59ef-2749-4017-94f4-d046a2cd7391
fi
echo 'Chargement de Linux 4.11.8-2-default…'
linux /boot/vmlinuz-4.11.8-2-default root=UUID=4dcb59ef-2749-4017-94f4-d046a2cd7391 ${extra_cmdline} resume=/dev/sda1 quiet showopts acpi_backlight=native
echo 'Chargement du disque mémoire initial…'
initrd /boot/initrd-4.11.8-2-default
}
On remarque que, pour cette entrée, les chemins vers le noyau et l'initrd ressemblent à ce que l'on peut avoir avec d'autres systèmes de fichiers : il n'y a pas de référence explicite à un sous-volume.
Pilote Btrfs : à la croisée des chemins
Au niveau de GRUB en lui-même, la série de patchs modifie le pilote Btrfs pour :
- fournir les commandes :
-
btrfs-get-default-subvol
: équivalentbtrfs subvolume get-default
. -
btrfs-info
: équivalent àbtrfs filesystem show
. -
btrfs-list-subvols
: une version simplifiée debtrfs subvolume list
. -
btrfs-mount-subvol
: permet de monter des sous-volumes.
-
- permettre de définir les variables :
-
btrfs_subvol
: nom du sous-volume à monter ; vous avez vu que c'est utilisé dans les/.snapshots/*/grub-snapshot.cfg
. -
btrfs_subvolid
: id du sous-volume à monter. -
btrfs_relative_path
: booléen indiquant à GRUB s'il doit utiliser des chemins relatifs.
-
Intéressons-nous à ce btrfs_relative_path
et à ce qu'il implique.
GRUB gère les sous-volumes Btrfs comme des répertoires.
La version upstream utilise le nom complet des sous-volumes comme un chemin absolu. Par exemple : /@/.snapshots/1/snapshot/boot/grub2/grub.cfg
, /@/.snapshots/1/snapshot/boot/vmlinuz-4.11.8-1-default
, /@/.snapshots/1/boot/initrd-4.11.8-1-default
, … Cela a l'avantage d'être clair et similaire à ce qui est fait pour les autres systèmes de fichiers qui n'ont pas de notion de sous-volume.
Le problème, c'est, si j'ai bien compris, que cela nous oblige à spécifier un sous-volume précis dans la configuration de GRUB. Or, dans le cas d'une restauration, souvenez-vous : on change de sous-volume. Du coup, avec un GRUB vanilla, on est bien obligé de régénérer sa configuration – le grub.cfg
et même le core.img
qui va chercher le grub.cfg
– pour faire une restauration qui marche ! Du moins, une restauration telle qu'on l'a faite.
openSUSE a une autre façon de faire, du moins si btrfs_relative_path
est à y
, ce qui est le cas par défaut.
L'idée est de faire en sorte que GRUB n'utilise plus un chemin complet, mais un chemin relatif par rapport au sous-volume par défaut. Avec cette façon de faire, /@/.snapshots/1/snapshot/boot/grub2/grub.cfg
devient /boot/grub2/grub.cfg
du sous-volume par défaut.
Cela évite de devoir modifier le fichier grub.cfg
et le core.img
pour chaque restauration.
Et cela explique pourquoi un simple snapper rollback
– ou les commandes Btrfs équivalentes – marche sur openSUSE, mais pas sur d'autres distributions. Si j'ai bien compris.
Bugs connus
Je vous en mets deux que j'ai eu l'occasion de rencontrer :
-
boo#1048088 : la commande
btrfs-list-subvol
ne liste que les sous-volumes descendant immédiatement deFS_TREE
. Cela marche sur les anciennes installations qui n'utilisent pas@
, mais pour les nouvelles… ben ça affiche juste@
. Pas bien méchant. Bug spécifique à openSUSE, vu qu'il n'y a pas de commandebtrfs-list-subvol
dans le projet upstream. -
boo#1049994 : l'accès au sous-volume
@/.snapshots/
n'est pas très propre ; cela empêche par exemple de booter correctement sur des snapshots qui auraient été transférés avecbtrfs send
etbtrfs receive
; on reviendra sur cela quand on parlera de sauvegarde incrémentale. Le bug est en partie upstream si j'ai bien compris.
Mais quand est-ce qu'on merge ?
Ma question favorite :-)
Le fait est que l'upstream reste sur sa position : pas de chemin relatif pour Btrfs, seulement un chemin absolu. Du coup status quo depuis 3 ans :-/ C'est dommage.
Après on peut aussi se retourner vers openSUSE : est-ce vraiment une bonne solution que d'utiliser des chemins relatifs dans GRUB2 ?
Bref : c'est pas hyper bien parti, mais espérons que les gourous de GRUB arrivent un jour à une solution qui satisfasse tout le monde !
Liens
Sur Snapper :
- La documentation openSUSE sur snapper.
- Gestion des instantanés avec snapper, commence à dater, sur Alionet.
Sur GRUB :
- Les sources du paquet grub2 d'openSUSE Tumbleweed, sur le Build Service. Les patchs relatifs à Btrfs sont préfixés par "grub2-btrfs-".
- Un fil de discussion à propos de Btrfs sur la liste de diffusion grub-devel.
# Merci
Posté par ʭ ☯ . Évalué à 4.
Excellents journaux, qui montrent que la diversité du libre a du bon. Je me demande si la gourmandise de btrfs - et donc son apétence pour de gros disques - n'a pas été son plus gros frein, dans un milieu où l'on souligne souvent la frugalité des logiciels.
Pour ma part, j'ai effectivement essayé btrfs une fois, et j'ai rempli mon disque très vite. En fouillant, j'ai compris qu'il fallait lancer manuellement une commande pour dire à btrfs de vider sa corbeille, c'était un no-go pour ma part. Revenu à ext4, je n'y ai plus touché.
⚓ À g'Auch TOUTE! http://afdgauch.online.fr
[^] # Re: Merci
Posté par Matthieu Moy (site web personnel) . Évalué à 4.
J'ai du btrfs et je n'ai jamais eu ce phénomène. En fait je ne vois pas de quelle commande tu parles. A priori, tu as du installer autre chose par dessus btrfs ou quelque chose comme ça.
[^] # Re: Merci
Posté par pralines . Évalué à 1.
j'ai été étonné aussi, j'ai un gros volume BTRFS RAID6 (oui, je suis un peu fou…) et je n'ai pas constaté ce problème,
après une petite recherche sur le nain ternet, il semble qu'il y ait (eu ?) un bug qui faisait que les fichiers effacés allaient dans une corbeille qu'on ne pouvait pas vider lorsqu'elle est située à la racine d'un sous-volume, je n'ai pas lu en détail les explications et je ne sais pas si c'est toujours d'actualité
Envoyé depuis mon Archlinux
[^] # Re: Merci
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 3.
Ou même totalement. L'été dernier les raids 5 & 6 avec btrfs étaient absolument incapables de restaurer la moindre donnée en cas de perte d'un disque dur. Il semble qu'il y ait eu quelques progrès de ce côté depuis, quoi que, mais souhaitons que vous ayez bien testé et aucune donnée critique non sauvegardée là-dessus.
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
# SNAPPER EXT4?
Posté par saltimbanque (site web personnel) . Évalué à 2.
oua cette partie m'a fait réver. Des snapshot sur tout système de fichier, ou en tout cas sur ext4.
tu écris que c'est cassé , c'est une blague ; et vu tes recherches je fais totalement confiance à ton post
mais alors est-ce que tu pense qu'il y a espoir de le corriger?
(la page snapper -> overview dit "Works with btrfs, ext4 and thin-provisioned LVM volumes")
est-ce que tu pense que snapper sera un jour applicable à d'autres FS encore?
[^] # Re: SNAPPER EXT4?
Posté par AR7 (site web personnel) . Évalué à 1.
Concernant ext4, l'implémentation faite dans snapper dépend d'une version d'ext4 patchée, réalisée dans le cadre d'un projet appelé Next4. Ce projet n'a visiblement pas abouti : wiki mort, rien de mergé, pas trouvé de trace du code. Donc à moins d'un miracle, je ne vois pas comment snapper peut marcher avec de l'ext4…
Je doute un peu que cela soit réparé, il n'y a pas trop d'activité sur #331.
Je n'ai pas regardé le code de snapper pour voir comment c'est fait, ce dont il a besoin et comment cela peut évoluer. En tout cas, je n'ai pas l'impression qu'il y ait actuellement une dynamique pour rajouter le support d'autres systèmes de fichiers.
# Coquille
Posté par AR7 (site web personnel) . Évalué à 1. Dernière modification le 25 août 2017 à 07:58.
Il y a une petite coquille au niveau du contenu du fichier
/etc/grub.d/80_suse_btrfs_snapshot
:J'avais rajouté un
\
dans mon texte car le colorateur syntaxique markdown de gedit avait un peu de mal avec cet EOF. Le vrai script est bien sûr sans\
:Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.