Étapes préliminaires
-
avoir à peu près 4Go de RAM (pour une install Debian de base), car tmpfs va allouer la moitié de la RAM à notre manip', et on va avoir besoin d'à peu près 2Go de RAM pour copier la racine en RAM.
-
Installer le paquet
psmisc(pour fuser). Assurez-vous que lsof est installé (normalement par défaut sur une Debian) -
stopper tous les services réseau (postgres, apache, etc)
-
Démonter tous les systèmes de fichiers non-utilisés:
umount -a
Note: des erreurs sont normales, c’est le but
le but est notamment de démonter /boot si cette partition est utilisée
- Vérifier la taille minimale possible (en blocs) pour notre partition racine (ici, /dev/sda2:
resize2fs -P /dev/sda2
resize2fs 1.46.2 (28-Feb-2021)
Estimated minimum size of the filesystem: 828892
- On vérifie ensuite la taille d’un bloc:
tune2fs -l /dev/sda1 | grep -i "block size"
Block size: 4096
On peut donc calculer la taille minimale de notre partition: 4096 * 828892 = 3395141632 octets, soit ~3.4Go ici (probablement plus sur une machine de production, il s’agit ici juste d’une debian fraîchement installée).
Dans la suite, on réduira la taille de notre partition à 10Go, adaptez bien sûr en fonction du besoin.
Préparer le rootfs en RAM
- Créer un répertoire /tmproot (
mkdir /tmproot) - Ensuite, préparer le rootfs temporaire:
mount -t tmpfs none /tmproot
mkdir /tmproot/{proc,sys,dev,run,usr,var,tmp,oldroot}
cp -ax /{bin,etc,mnt,sbin,lib,lib64} /tmproot/
cp -ax /usr/{bin,sbin,lib,lib64} /tmproot/usr/
cp -ax /var/{account,empty,lib,local,lock,nis,opt,preserve,run,spool,tmp,yp} /tmproot/var/
# quelques erreurs sont normales, certains répertoires
# dans /var n'existent pas forcément
mkdir -p /tmproot/home/votreuser/.ssh
cp /home/votreuser/.ssh/authorized_keys /tmproot/home/votreuser/.ssh/
chown -R votreuser: /tmproot/home/votreuser
On vient de créer un rootfs minimal - pas de manpages (/usr/share), et juste votre clef ssh pour ne pas risquer de s’enfermer dehors pendant nos manipulations (notamment quand on va relancer SSH).
Pivoter le root sur notre tmpfs
On va pouvoir basculer sur notre rootfs. Cependant, avant:
- quittez toute session tmux en cours de fonctionnement
- et plus globalement tout utilitaire (htop, vim, tail -f, etc)
On va pouvoir utiliser pivot_root pour la bascule:
mount --make-rprivate /
pivot_root /tmproot /tmproot/oldroot
for i in dev proc sys run; do mount --move /oldroot/$i /$i; done
On relance sshd, on se déconnecte, on tue la socket de notre côté si besoin, et on se reconnecte en croisant les doigts :slight_smile:
systemctl restart sshd
systemctl status sshd
exit # on se déconnecte de la machine/VM
ssh -O exit IP_ou_Nom_de_la_machine
ssh votreuser@machine
sudo -s (etc, etc)
Stopper tout ce qui utilise encore l’ancienne partition
On récupère la liste de tous les process qui utilisent encore l’ancien root (/oldroot):
fuser -vm /oldroot
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
root 1 ...e. systemd
root 216 F..e. systemd-journal
root 238 .rce. systemd-udevd
systemd-timesync 353 .rce. systemd-timesyn
root 365 ..ce. cron
messagebus 366 ...e. dbus-daemon
root 370 F..e. rsyslogd
root 372 .rce. systemd-logind
root 416 ...e. agetty
lidstah 447 ...e. systemd
lidstah 448 ...e. (sd-pam
normalement, c’est principalement des unités systemd qui utilisent encore /oldroot
On va en obtenir la liste:
systemctl | grep running | grep service
systemctl | grep running | grep service | column -t
cron.service loaded active running Regular background program processing daemon
dbus.service loaded active running D-Bus System Message Bus
getty@tty1.service loaded active running Getty on tty1
rsyslog.service loaded active running System Logging Service
ssh.service loaded active running OpenBSD Secure Shell server
systemd-journald.service loaded active running Journal Service
systemd-logind.service loaded active running User Login Management
systemd-timesyncd.service loaded active running Network Time Synchronization
systemd-udevd.service loaded active running Rule-based Manager for Device Events and Files
user@1000.service loaded active running User Manager for UID 1000
on va donc relancer tous ces services sauf systemd-logind. On va ensuite relancer systemd lui même (fear):
systemctl daemon-reexec
On revérifie que seul le kernel utilise /oldroot:
fuser -vm /oldroot
/oldroot: root kernel mount /oldroot
lidstah 933 ...e. (sd-pam
# on tue le process résiduel:
kill -15 933
On vérifie maintenant les processes qui affichent un mount:none et soit on les relance (si gérés par systemd), soit on les tue.
grep system /proc/*/mounts | column -t | grep none
/proc/925/mounts:none /var/lib/systemd/timesync tmpfs rw,relatime 0 0
/proc/981/mounts:none /var/lib/systemd/linger tmpfs rw,relatime 0 0
# on tue donc timesync et linger, ils vont se relancer automatiquement:
kill -15 925 981
Démonter /oldroot
umount /oldroot
Redimensionnement de notre système de fichiers
On va pouvoir redimensionner notre FS racine (enfin!), 10Go ici, adaptez en fonction - on relance aussi nos unités systemd, pour faire bonne mesure:
systemctl restart cron getty@tty1 rsyslog ssh systemd-timesyncd systemd-udevd user@1000
e2fsck -f /dev/sda2
resize2fs /dev/sda2 10G
Pivoter la racine sur notre disque, à nouveau, et tout relancer proprement:
mount /dev/sda2 /oldroot
mount --make-rprivate /
pivot_root /oldroot /oldroot/tmproot
for i in dev proc sys run; do mount --move /tmproot/$i /$i;done
# relancer sshd, se déconnecter, refaire les étapes pour stopper
# ce qui utilise encore /tmproot cette fois ci, au lieu de /oldroot
umount /tmproot
rm -r /tmproot
mount -a
systemctl | grep failed
systemctl restart unités-failed
mount --make-rshared /
systemctl isolate default.target
Il ne nous reste plus qu’à redimensionner notre partition /dev/sda2 via l’utilitaire cfdisk par exemple. Ce qui veut dire, supprimer la partition, la recréer avec une taille un peu plus grande que notre resize2fs (par exemple, 15Go là où on a redimensionné notre FS à 10Go. On va le réagrandir ensuite avec un resize2fs /dev/sda2). Ouf
Si on veut créer une partition supplémentaire sur notre disque, et que l’on a moins de 4 partitions, on créera une partition primaire, sinon, on créera une partition étendue.
On peut ensuite utiliser la nouvelle partition comme /home dédié, ou l’ajouter à un VG LVM par exemple. Ici, /dev/sda4, qu’on utilise pour étendre le VG pg puis enfin pour étendre le volume logique pg/pg-data:
pvcreate /dev/sda4
vgextend pg /dev/sda4
lvextend -L+10G pg/pg-data
resize2fs /dev/mapper/pg-pg--data
Fiou