Elargissement de /boot

Lorsque j’ai fait la première installation sur mon portable, du fait de la petite taille du disque, j’ai visé très très (trop) juste pour la partition /boot : à peine 256 Mo. Au début ça fonctionnait bien. Mais petit à petit, la taille de l’image de boot (initrd) a grandi. Un moment, je ne pouvais plus avoir que 2 noyaux installé, ce qui rendait les mises à jour vraiment pénibles puisqu’il me fallait d’abord supprimer le précédent avant de mettre le nouveau. Bref, ça ne pouvait plus continuer.

Or, classiquement, /boot était sur la première partition. Et tout le reste du disque étant chiffré, un agrandissement de cette première partition était juste impossible (si vous connaissez un moyen de déplacer une énorme partition d’un offset très inférieur à sa propre taille, je suis curieux). Le plan était donc :

  1. Faire de la place en retaillant /.
  2. Créer une nouvelle partition primaire.
  3. Déplacer /boot vers la nouvelle partition.

Préparation

On va toucher aux données, à bas niveau puisqu’on va toucher aux partitions. En cas de mauvaise manipulation, on a un gros risque de perdre les données. On va donc commencer par faire une sauvegarde.

J’ai donc commencé un backup des données utilisateur avec restic. Ensuite, j’ai doublé avec l’utilisation de clonezilla pour réaliser une image de la partition que je vais retailler.

Réduction (contexte)

Mon contexte est assez classique pour un portable : un disque chiffré. Cela se traduit par un empilement de concepts :

  1. La partition physique est gérée par cryptsetup.
  2. Ce device virtuel est utilisé comme physical volume LVM2.
  3. Le physical volume est utilisé par un volume group qui contient (enfin) le logical volume qui nous intéresse.
  4. Ce logical volume est formatté avec ext4.

Le processus est très bien décrit dans l’article ResizeEncryptedPartitions.

La mauvaise nouvelle c’est qu’il va falloir gérer la réduction dans chacune de ces couches. La seconde mauvaise nouvelle c’est que dans une approche de réduction, il va falloir gérer les tailles finement. En effet, pour réduire il faut commencer par les couches les plus profondes et remonter les couches. Mais il faut faire attention que le redimensionnement fait à un niveau soit suffisament grand pour contenir effectivement le niveau inférieur. Car autant une couche sait trouver la dimension du conteneur géré par couche supérieure, autant l’inverse n’est pas possible. Par exemple, LVM sait retrouver la taille du conteneur mis à disposition par cryptsetup, autant cryptsetup n’a aucune idée de comment s’y prendre pour retrouver la taille utile du physical volume.

Réduction (première partie)

Concrètement, on boote sur Clonezilla (qui contient les outils nécessaires) et on commence les opérations.

  1. On déchiffre le conteneur : cryptsetup luksOpen /dev/sda2 sdacrypt
  2. On réduit la taille du filesystem : resize2fs /dev/mapper/monvolume-root 104G
  3. On réduit la taille du logical volume : lvreduce -L 105G /dev/mapper/monvolume-root
  4. On réduit la taille du physical volume : pvresize --setphysicalvolumesize 106G /dev/mapper/sdacrypt

Et là, pas de bol, la commande échoue au prétexte que cannot resize to xxxxx extents as later ones are allocated, autrement dit, en réduisant la taille du logical volume j’ai fait de la place, mais cette place ne s’est pas libérée à la fin du physical volume, mais quelque part au milieu.

Défragmentation du physical volume

Il faut donc défragementer pour déplacer ce vide vers la fin du physical volume. Malheureusement, l’outillage LVM ne fournit pas d’outil pour défragmenter. Il va donc falloir le faire à la main.

Première étape : constater les dégats.

pvs -v --segments /dev/mapper/sdacrypt

Ensuite, on déplace des morceaux avec pvmove.

Dans mon cas, le vide s’était créé plutôt au début. Du coup, impossible de tout déplacer pour combler le vide en conservant la continuité des données. J’ai donc décidé de déplacer les derniers extents pour combler le vide, augmentant la fragmentation, mais tant pis.

pvmove --alloc anywhere /dev/mapper/sdacrypt:yyy-www

Réduction (seconde partie)

Une fois le vide placé en fin de physical volume, on peut réduire sa taille et reprendre le processus global.

  1. On réduit la taille du physical volume : pvresize --setphysicalvolumesize 106G /dev/mapper/sdacrypt
  2. On réduit la taille du conteneur chiffré : cryptsetup -b XYZ resize sdacrypt

Attention : la dernière étape nécessite un peu de calcul car la taille fournie est en nombre de blocs et dans mon cas les blocs étaient de 512.

On peut enfin créer une nouvelle partition primaire pour contenir le nouveau /boot avec fdisk.

Une fois toutes ces étapes effectuées, on peut recommencer en redescendant pour récupérer toutes les marges prises. De manière générale, cela consiste à relancer les outils de redimensionnement sans préciser la taille souhaitée, auquel cas ils cherchent alors la taille disponible pour maximiser leur étalement.

  1. cryptsetup resize sdacrypt
  2. pvresize /dev/mapper/sdacrypt
  3. lvresize -l +100%FREE /dev/mapper/monvolume-root
  4. resize2fs /dev/mapper/monvolume-root

Reconfiguration de Grub

La dernière étape consiste à refaire la partition /boot dans la nouvelle partition créée.

La première étape consiste à copier le contenu : après un mount dans /mnt, rsync -av /boot/ /mnt/ permettra de tout recopier.

Il faut ensuite reconfigurer le /etc/fstab. De nos jours, il est préférable d’utiliser un UUID pour cibler la partition à monter. La commande blkid permet de retrouver cette information. Une fois /etc/fstab reconfiguré, on peut monter la nouvelle partition : umount /boot && mount /boot.

Enfin, il faut réactiver Grub sur cette partition. Un update-grub profitera de la nouvelle partition montée sur /boot pour reconfigurer une partie. Mais Grub est sensible à la partition sur laquelle il est installé. Il faudra donc aussi lancer un grub-install pour que les morceaux de plus bas niveau exploitent cette nouvelle partition.

Conclusion

Le partitionnement consistant à isoler /, /boot, /home… n’est pas forcément très adapté pour un portable avec un faible stockage. Mais dès qu’il est question de chiffrer le disque, il devient nécessaire pour que /boot demeure en clair. Il conviendra donc de prendre ses précautions lors du choix des volumes.