Niveau :      
Résumé : mysnapshot

Maintenant que vous savez comment fonctionne device-mapper, il est possible de compenser un certain manque de lvm à la main. Nous allons faire des snapshot de snapshot (merci à glandium pour la suggestion).

Voici 2 scripts permettant de faire cela. Ils s'utilisent de la manière suivante :

# En supposant que vous ayez déjà fait un premier snapshot avec lvm
# snapshot2 sera un snapshot de snapshot1
$ mysnapshot '-L 1G' vg0 snapshot1 snapshot2

# Pour supprimer le snapshot précédemment créé
$ mysnapshotrm vg0 snapshot2

Prenez ces scripts avec quelques pincettes puisque bien que testés sur mes machines, ils n'est pas garanti qu'ils fassent tout ce que vous vouliez. Par exemple, il permet d'enchaîner les snapshot, mais tel quel il va vous poser quelques problèmes pour faire des arbres de snapshot (plusieurs fois un snapshot d'un même snapshot), dans ce cas ... à vous de bosser.

Attention : contrairement à lvm, ces snapshots ne sont pas automatiquement mis en place au boot.

Un petit schéma du principe de fonctionnement des snapshots, peut-être un peu plus clair que le précédent pour ceux qui connaissent device-mapper (attention, les noms ne correspondent pas totalement à ceux du script).

lvm_snapshot2.png

Ce schéma permet aussi d'expliquer quelque chose que j'ai oublié de dire lors de l'article précédent : bien qu'il n'y ait pas de différence fondamentale entre l'orginal et le snapshot, le snapshot est le périphérique qui aura les meilleures performances en écriture.

mysnapshot :

#!/bin/sh 

# gestion des paramètres
if [ -z "$4" ]
then
        echo "usage $0 'lvmParameters' volumeGroup origin snapshot"
        exit 1
fi

lvmparams=$1
vg=$2
origin=$3
snapshot=$4

min=0
# lecture du snapshot existant pour déterminer la taille du dev final
idh=$(stat -c "%T" /dev/mapper/$vg-$origin)
id=$((0x$idh))
max=$(cat /sys/devices/virtual/block/dm-$id/size)

# on crée avec lvm l'espace pour stocker le snapshot
lvcreate -n $snapshot-cow $lvmparams  $vg

# on suspend le snapshot pour que l'activité en cours dessus ne le casse pas
dmsetup suspend $vg-$origin

# on recopie le snapshot d'origine dans un un nouveau dev (pour y accéder directement et pour le retour en arrière)
dmsetup table $vg-$origin | dmsetup create $vg-$origin-real

# on remplace le snapshot d'origine par un device qui va générer des évènements de modif (pour le 2e snapshot)
echo $min $max snapshot-origin /dev/mapper/$vg-$origin-real | dmsetup reload $vg-$origin

# on crée le nouveau snapshot qui pointe vers l'espace de stockage et vers le snapshot d'origine
echo $min $max snapshot /dev/mapper/$vg-$origin-real /dev/mapper/$vg-$snapshot--cow P 8 | dmsetup create $vg-$snapshot

# on réactive le snapshot d'origine qui est maintenant snapshotté
dmsetup resume $vg-$origin

mysnapshotrm :

#!/bin/sh

# gestion des paramètres
if [ -z "$2" ]
then
        echo "usage $0 volumeGroup snapshot"
        exit 1
fi

vg=$1
snapshot=$2

# lecture du dev du snapshot pour découvrir qui était l'original
originmm=$(dmsetup table $vg-$snapshot | cut -d " " -f 4 | sed 's/:/,[[:space:]]+/')
originvg=$(ls -l /dev/mapper | egrep "$originmm" | sed 's/.* \([^ ]*\)$/\1/')
origin=$(echo $originvg | sed "s/$vg-\(.*\)-real/\1/")

# on suspend le snapshot d'origine pour éviter de le casser
dmsetup suspend $vg-$origin

# on le restaure avec la version d'origine
dmsetup table $vg-$origin-real | dmsetup reload $vg-$origin

# et on peut le réactiver
dmsetup resume $vg-$origin

# on vire le snapshot créé
dmsetup remove $vg-$snapshot

# on vire la copie du snapshot d'origine
dmsetup remove $vg-$origin-real

# et on supprime l'espace de stockage de notre snapshot
lvremove -f /dev/$vg/$snapshot-cow

Et si vous êtes développeur lvm, si vous pouviez y intégrer l'équivalent, ça serait sympa.