====== Rétrécir un volume logique LVM (shrink) ======
===== Introduction =====
De nombreux tutoriels présentent cette opération de manière simple. Toutefois, tous ceux que j'ai consultés restent évasifs quant aux valeurs à appliquer lors des opération de rétrécissement. Tous supposent que l'on dispose d'une "marge de stockage" "suffisante" sans détailler ce que recouvre ces notions ni fournir la moindre règle de calcul.
Sur un support de stockage qui est à la limite de saturation, ces indications évasives ne sont pas suffisantes. Certes, on peut procéder par essai/erreur, en ayant pris de soin de faire une sauvegarde. Dans le meilleur des cas, cette démarche peut aboutir après "un certain nombre" d'essais((Plus ou moins longue, selon ne nombre d'essais nécessaire et le volume de données à restaurer…)). Elle peut aussi échouer, notamment si l'espace est extrêmement contraint, alors qu'elle est techniquement possible.
==== Cas d'utilisation ====
Je souhaite ajouter un volume logique à un groupe ne disposant pas de place libre. Je veux ainsi disposer de 16GiB d'espace utilisables pour étendre l'espace de swap du système d'exploitation.
Je vais devoir rétrécir un volume logique existant pour dégager l'espace nécessaire. Je choisis de rétrécir un volume contenant un système de fichiers //ext4//.
Je m'assure que l'espace disponible sur ce système de fichiers est supérieur à 16GiB((La commande //df -h// donne accès à cette information.))
Trois caractéristiques de ce cas d'utilisation vont considérablement simplifier la procédure :
* la cible est un volume consacré au **//swap//** système,
* le système de fichiers installé sur le volume à rétrécir est **//ext4//**,
* l'**intégralité de l'espace libre** est alloué au nouveau volume.
//Corollaire : dans tout autre cas, la procédure risque d'être (beaucoup) plus complexe.//
==== Résumé ====
Pour celles qui connaissent la musique mais trébuchent sur les paroles :
// Depuis le système principal
$ df -h
$ lsblk -f
# lvdisplay
//démontage du volume ou reboot sur système de secours ou live
# vgchange -a y // pour garantir que tous les volumes sont connus du système
$ lsblk // on s'assure du résultat
# umount /dev//
# tune2fs -l /dev//
# e2fsck -fy /dev//
# lvreduce --resizefs -L -G /dev// // on n'oublie pas le "-" devant le nombre !
# e2fsck -fy /dev//
// pour finir le travail
# lvcreate -l 100%FREE -n
# mkswap /dev//
==== Sources ====
Redimensionnement de volumes et de systèmes de fichiers :
* [[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/logical_volume_manager_administration/lv_reduce|Shrinking Logical Volumes]] (en) (redhat.com) [Excellente source]
* [[https://www.thegeekdiary.com/centos-rhel-how-to-create-new-lvm-based-swap-partition/|How to create new LVM based swap partition]]
* [[https://man7.org/linux/man-pages/man8/lvreduce.8.html|lvreduce(8) — Linux manual page]]
* [[https://man7.org/linux/man-pages/man8/fsadm.8.html|fsadm(8) — Linux manual page]]
* [[https://man7.org/linux/man-pages/man8/tune2fs.8.html|tune2fs(8) — Linux manual page]]
Sur la différence entre l'espace total et l'espace utilisable :
* [[https://ma.ttias.be/change-reserved-blocks-ext3-ext4-filesystem-linux/|How to change the reserved blocks on EXT3 or EXT4 filesystem in Linux]]
Sur l'intérêt et la manière de créer une partition ou un volume logique de swap:
* [[https://wiki.debian.org/fr/Swap|Swap]] (fr) (wiki.debian.org)
==== Notation ====
* "VL" désigne le volume logique que l'on souhaite rétrécir.
* "SF" désigne le système de fichiers implanté sur ce VL.
* les lignes de commande commençant par "#" doivent être lancées avec les droits de superutilisatrice
==== Démarche ====
La démarche appliquée est la suivante :
- sauvegarder les fichiers stockés sur le LV
- récupérer les caractéristiques du LV
- démonter le LV - redémarrer l'ordi si nécessaire
- contrôler l'intégrité du système de fichiers
- rétrécir le LV et le SF d'un seul coup
- contrôler l'intégrité du système de fichiers
- créer puis formater le volume de swap
===== Mise en œuvre =====
Avant toute manipulation du volume ou du système de fichier, il est vivement recommandé de sauvegarder le contenu du système de fichier((Tous les fichiers, y compris les fichiers "cachés".)).
Les opérations indiquées dans cette fiche ont été effectuées sur un système Debian-like.
==== Récupérer les caractéristiques du LV ====
S'assurer que le volume est monté, sinon le faire.
Je souhaite récupérer : le nom du groupe, le nom du volume, la taille du volume, le type de système fichiers installé sur ce volume, l'espace disponible sur ce système de fichiers.
La commande suivante affiche la capacité totale, l'espace utilisé et disponible, pour tous les volumes et partitions montées :
df -h
Elle permet également de retrouver le nom du groupe et le nom du volume. Cette information peut ne pas être limpide. Ainsi le volume "mon_volume" du groupe "mon_groupe" peut apparaître comme "/dev/mapper/mon_groupe-mon_volume".
La commande suivante affiche les systèmes de fichiers installés sur tous les volumes et partitions reconnues((Montées ou non.)) par le système((Sous Linux, dans certains cas, le système de fichiers installé et le système de fichiers monté peuvent être différents.)) :
lsblk -f
Une dernière pour afficher les informations d'identification des tous les volumes et partitions reconnues par le système :
# lvdisplay
et récupérer le "LV Path" du volume concerné. C'est ainsi que l'on désignera le LV lors des manipulations suivantes.
==== Démonter le LV ====
=== Support amovible ===
Si on intervient sur un volume logique implanté dans un support amovible (disque externe, clé USB, carte SD…), on le démonte comme on a l'habitude de la faire (//démonter//, //éjecter//, //retirer en toute sécurité//, etc.)((Les appellations varient suivant les systèmes, les versions, les interfaces graphiques…)).
=== Disque interne ===
Je m'en tiens au cas d'un poste de travail((S'il s'agit d'un serveur, j'espère que le montage ou le démontage d'un volume ne présente aucun secret pour vous…)). Si le LV se trouve sur un disque((Disque dur ou SSD.)) interne de l'ordi, je recommande de redémarrer l'ordi sur un autre système, par exemple un système "live" sur une clé USB. La question du démontage est évacuée puisque les volumes des disques internes ne seront pas montés par le système live. Dans la suite, je suppose que vous avez suivi cette recommandation((Sinon, reportez-vous aux //sources//.)).
==== Identifier le volume et ses caractéristiques ====
Avant d'intervenir sur le LV, on vérifie qu'il est reconnu et manipulable par le système et qu'il n'est pas monté. Une des avantages de LVM est que le nom du LV ainsi que celui du groupe (VG) auquel il appartient ne dépendent pas du système.
Au cas où le système ne l'aurait pas déjà fait, on active tous les groupes LVM :
# vgchange -a y
On s'assure que le volume est présent et n'est pas monté :
lsblk
==== Contrôler l'intégrité du système de fichiers ====
On effectue un contrôle préalable d'intégrité du SF que l'on va modifier :
# e2fsck -fy /dev/mon_groupe/mon_volume
==== Rétrécir le LV et le SF ====
Dans le cas d'utilisation évoquée, l'objectif final est de créé une volume de //swap//. Ce type de volume ne comportant pas de système de fichier on se trouve dans le cas simplifié où : taille du volume = taille directement utilisable.
Je souhaite disposer de 16GiB, je rétrécie donc le LV de 16GiB, sans me poser de question((Avant de me lancer, j'ai vérifié que l'espace disponible sur le SF était suffisant.)) et je rétrécis le SF du même coup :
# lvreduce --resizefs -L -16G /dev/mon_groupe/mon_volume
==== Contrôle final ====
# e2fsck -fy /dev/mon_groupe/mon_volume
==== Pour finir ====
On sort du cadre de la fiche mais il est intéressant de voir le peu qui reste à faire pour créer un volume de swap prêt à être raccordé :
# lvcreate -l 100%FREE -n nouveau_volume mon_groupe
# mkswap /dev/mon_groupe/nouveau_volume
Pour qu'il soit exploité par le système principal de l'ordi, il faudra modifier le fichier /etc/fstab de ce système en conséquence.
===== Et sinon ? =====
Que se passe-t-il si les conditions facilitatrices énumérées au début de cette fiche ne sont pas remplies ?
==== On n'utilise pas tout l'espace libéré ====
C'est l'exception la plus simple à traiter. Dans le cas d'utilisation, le LV a été rétréci de 16GiB. Il reste donc 16GiB pour créer un ou plusieurs volumes logiques en utilisant toute la place restante ou pas. Si on ne change pas d'unité (le GiB), c'est de l'arithmétique de CP. Si on créé un volume de 2 GiB et un volume de 5GiB, plus tard, on pourra encore créer un volume de 9GiB.
lvcreate -l 2G -n volume_1 mon_groupe
lvcreate -l 5G -n volume_2 mon_groupe
…
lvcreate -l 9G -n volume_3 mon_groupe
La vraie question est : que veut-on faire de ces nouveaux volumes ?
==== On veut créer un nouveau volume ext4 ====
Ce n'est pas le plus compliqué mais on perd l'égalité : taille du volume = taille directement utilisable. On doit alors considérer 3 données qui auront nécessairement des valeurs différentes : la taille du volume, la taille du système de fichiers, la taille de l'espace directement utilisable.
Les relation liant les deux derniers est la plus simple. Selon la configuration par défaut, un système de fichier ext4 réserve 5% de l'espace total pour son propre usage. On dispose donc librement de 95% du total. On peut être fâchée avec les pourcentages mais, au moins, une relation mathématique existe.
=== J'adore les pourcentages et le binaire ===
La première contrariété vient avec l'ordre de calcul. On sait de combien de GiB on veut disposer, pas de quel pourcentage d'un grand tout. Si on remet le calcul dans le sens de l'utilisatrice, le système de fichiers devra être 5,263% plus grand que l'espace disponible souhaité. C'est tout se suite moins fun. On sent confusément que 5,263% de 1GiB, ça va piquer les yeux :-| Coup de chance, si l'on peut dire, dans une configuration par défaut, cela fait un compte rond, en unités d'allocation 8-O. Concrètement, pour disposer de 1GiB exactement, soit 262 144 blocs d'allocation de 4096 octets chacun, il suffit de créer un système de fichiers d'une taille totale de 275 941 blocs. Sérieux ? :-\
== Situation critique ? ==
Si on est vraiment à l'étroit, ce qui peut arriver quand l'espace de stockage est arrivé à saturation((C'est mal, on aurait dû s'y prendre avant. Mais bon, on en est là…)), le calcul en blocs d'allocation est précis, sans surprise d'arrondis. La commande suivante donnera les caractéristiques du SF (nombre de blocs, tailles des blocs, etc.) nécessaires :
tune2fs -l /dev/mon_groupe/mon_volume
=== Calcul et bouts de ficelles ===
Dans la plupart des cas, on a plein d'espace de stockage inutilisé (comme dans le cas d'utilisation). On fera des estimations à la louche. Par exemple : j'ai besoin de 1GiB, j'ajoute 10%, il me faut donc un système de fichiers de 1.1GiB. Dans un monde créé pour les utilisatrices, il n'y aurait qu'à demander la création d'un volume de 1.1GiB. Comme annoncé au début de la section, ça ne fonctionne pas comme ça. En passant de swap à ext4, on a perdu l'égalité : taille du volume = taille du système de fichiers.
Je n'en connais pas l'explication mais tous mes systèmes de fichiers disposent de moins de place que n'en consomme le volume logique qui les héberge, même en imposant à //resizefs// de prendre toute la place disponible. Et pas de quelques malheureux Mo ou MiB… Je parle de plusieurs GiB représentant autour de 1,5% de l'espace consommé par le volume. Ce n'est rien d'autre qu'une mesure empirique que j'utilise dans mes calculs à la louche. Je veux héberger un système de fichiers de 10GiB ? Je crée un volume de 10.18 GiB et je croise les doigts((Tout est relatif. Les données ayant été sauvegardées, il sera possible de les restaurer.))…
Mon but initial était de créer un nouveau volume ext4 qui m'offrirait 16GiB d'espace utilisable. En pratique, j'applique donc deux coefficients correcteurs (5% et 1,8%) : 16 x 1,05 x 1,018 = 17,1024 que j'arrondis à 17,2GiB.
La bonne nouvelle est que la procédure exposée pour le cas d'utilisation reste valable, il suffit de remplacer la valeur 16G par 17.2G, dans la commande //lvreduce// :
lvreduce --resizefs -L -17.2G /dev/mon_groupe/mon_volume
=== Implanter un système de fichier autre que ext4 ? ===
Ce cas n'est pas traité dans cette fiche mais le principe est identique. Il faut toujours répondre aux deux mêmes questions :
- comment calculer la taille du système de fichiers qui garantira un espace utilisable déterminé ?
- quelle taille doit avoir le volume logique pour garantir l'hébergement d'un système de fichiers d'une taille donnée ?
Concernant la première, une recherche à travers les sources disponibles peut conduire à la réponse souhaitée, si elle existe. D'une part, la notion d'espace utilisable est floue. D'autre part, la garantie absolue d'un tel espace, n'est pas la seule stratégie valable en toutes circonstances, pour tous les systèmes de fichiers.
Concernant la seconde, je ne dispose pas de données empiriques portant sur d'autres systèmes de fichiers.
Il reste toujours l'expérimentation, bien qu'expérimenter en aveugle rende hasardeuse l'interprétation des comportements des systèmes… Quand l'approche calculatoire est dans l'impasse, il serait ballot de ne pas se lancer ;-) On n'a pas fait une sauvegarde (ou deux) pour le seul plaisir encombrer l'espace d'archivage LOL
==== Si le LV contient autre chose que ext4 ? ====
La procédure exposée n'est valable que si le volume que l'on doit rétrécir héberge un des systèmes de fichiers suivants : //ext2//, //ext3//, //ext4//, //ReiserFS// ou //XFS//.
Dans les autres cas, il faudra décomposer l'opération de rétrécissement en trois étapes :
- rétrécir le système de fichiers,
- rétrécir le volume logique,
- agrandir le système de fichiers à tout l'espace mis à disposition par le LV.
On se passerait volontiers de la multiplication des étapes mais là n'est pas le problème. La troisième étape ne soulève aucune difficulté((Si on a cassé le système de fichiers par l'opération précédente, le mal est fait.)). Concentrons-nous sur les deux premières.
=== Bouts de ficelles existentiels ===
Les problèmes de calcul de tailles développés dans la section précédente surgissent de nouveau. Cette fois, ils concernent le volume à rétrécir et non le volume à créer… Cela soulève deux questions liées :
* de combien **puis-je** rétrécir le système de fichiers dans perdre de données ?
* de combien **dois-je** rétrécir le système de fichiers pour qu'il ne soit pas corrompu lors du rétrécissement appliqué au volume((Les sections précédentes ont présenté la méthode de calcul et les valeurs obtenues dans 2 cas concrets : 16GiB s'il s'agit d'un //swap// et 17.2GiB s'il s'agit d'un ext4 //standard//.)) ?