Linux a changé. Inspiré à l'origine par Unix, il y avait certaines règles bien comprises mais pas bien appliquées que tout le monde comprenait. Les programmes faisaient de petites choses et utilisaient des tuyaux pour communiquer. Les serveurs X Windows ne fonctionnaient pas toujours sur votre ordinateur local. Rien dans /usr contribué au démarrage du système.

Ces jours-ci, nous avons systemd qui contrôle tout. Si vous exécutez Chrome sur un écran, il est verrouillé sur cet écran et il souhaite vraiment que ce soit la carte vidéo locale. Et bouger /usr vers une autre partition vous empêchera facilement de démarrer, à moins que vous ne preniez des précautions. j'ai déménagé /usr et j'ai vécu pour en parler. Si jamais vous avez besoin de le faire, vous voudrez entendre mon histoire.

Beaucoup de gens critiquent systemd – moi y compris – mais ce n’est pas vraiment la faute de systemd. C'est la perte de ces principes à mesure que nous avons plus de programmeurs et beaucoup d'entre eux sont influencés par d'autres systèmes où les choses fonctionnent différemment. Mais je ne suis pas seulement en train de déclamer. J'ai récemment eu une expérience qui m'a rappelé tout cela et, en cours de route, j'ai appris quelques choses sur l'état moderne du processus de démarrage. L'histoire commence avec un ami qui me donne un Intel Compute Stick. Mais les problèmes que j'ai rencontrés n'étaient pas spécifiques à ce matériel, mais plutôt à la façon dont les distributions Linux modernes gèrent leur processus de démarrage.

L'histoire

Comme je l'ai dit, un de mes amis m'a donné un Intel Compute Stick. C'était l'un des premiers à être assez anémique. En particulier, il n'avait que 1 Go de mémoire et 8 Go de stockage flash. Il a démarré une ancienne version d'Ubuntu et c'était, comme vous vous en doutez, assez lent. Mais j'ai aimé le facteur de forme et j'ai un nouvel atelier qui pourrait utiliser un PC permanent, j'ai donc décidé de le mettre à niveau.

Il y avait les problèmes habituels. Une mise à niveau du BIOS a cassé le réseau. La mise à niveau vers KDE Neon a corrigé le réseau, mais le noyau plus récent présentait le redoutable bogue C-State qui provoquait des blocages. Heureusement, cette solution est facile à contourner. Donc, après quelques efforts, j'ai eu un système raisonnablement fonctionnel. Sorte de.

Le problème

Le problème était les 8 Go de flash. J'ai inséré une carte SD de 64 Go, mais je ne voulais pas démarrer à partir de celle-ci. Avec Neon installé et quelques autres éléments essentiels, le flash était très proche de 100% plein. Mon plan était de bouger /opt, /home, et /usr sur la carte SD. Je pensais que ce serait facile.

Traditionnellement, il s'agit d'un processus simple. Tout d'abord, copiez les fichiers en utilisant quelque chose qui récupère les fichiers et les liens cachés sans les modifier. De nombreuses personnes utilisent rsync mais utilisent généralement tar. Ensuite, vous supprimez l'ancien répertoire (je le renomme d'abord, juste pour être sûr et le supprimer une fois que tout fonctionne). Enfin, vous créez un nouveau répertoire vide et changez /etc/fstab pour monter le disque au moment du démarrage.

Pour /home et /opt c'était bien. Le système démarrera sans difficulté et je l'ai fait fonctionner en un rien de temps. je savais /usr serait un peu plus difficile, mais je me suis dit que je pourrais être dans un shell root sans l'interface graphique ou simplement démarrer une clé USB et faire tout le même travail.

J'ai en fait prévu quatre montures. J'ai monté toute la SDCard à /sdcard. Ensuite, j'ai lié des montures de /sdcard/opt à /opt et /sdcard/home à /home. le /usr mount serait aussi un montage bind mais ce n’était pas aussi simple que cela.

Le plus gros problème

Mes tentatives pour bouger /usr a provoqué l'arrêt du démarrage du système. Pourquoi? Il s'avère que systemd gère le montage de ce qu'il y a /etc/fstab et systemd exige des choses dans /usr. Je pensais peut-être que systemd serait assez intelligent pour démarrer le système s’il n’avait pas à lire /etc/fstab j'ai donc décidé de monter la carte SD en utilisant les installations natives de systemd.

Systemd peut gérer un montage comme un service. Cela signifie qu'il gérera le montage et le tissera également dans les dépendances. Il est donc possible d'exiger qu'un service ou un autre montage soit prêt avant de monter un disque et, bien sûr, d'autres services et montages peuvent également dépendre de ce disque. En théorie, c’est parfait car cela n’a pas de sens d’essayer de monter /sdcard/home, par exemple, avant le montage /sdcard.

Voici la définition de montage dans /etc/systemd/system/sdcard.mount


(Unit)
Description=Main SDCard Mount
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
After=swap.target

(Mount)
What=/dev/disk/by-uuid/b3b6ac3b-2109-487c-af34-c49586412cea
Where=/sdcard
Type=ext4
Options=defaults,errors=remount-ro

(Install)
WantedBy=multi-user.target

Évidemment, l'UUID changerait en fonction de votre disque. Pas si évidemment, ce fichier doit être nommé sdcard.mount. Si le point de montage était, disons, /usr/lib alors le fichier devrait être usr-lib.mount.

Une fois ce montage effectué, vous pouvez monter /home:


(Unit)
Description=Home SDCard Mount
DefaultDependenices=no
Conflicts=umount.target
Before=local-fs.target umount.target
RequiresMountsFor=/sdcard

(Mount)
What=/sdcard/home
Where=/home
Type=none
Options=bind,x-systemd.requires-mounts-for=/sdcard

(Install)
WantedBy=multi-user.target

Notez que le montage nécessite /sdcard. Une fois que vous avez mis ces fichiers au bon endroit et rechargé les systèmes, vous pouvez démarrer ces unités et les fichiers seront montés. Vous pouvez les activer pour les faire démarrer au démarrage. le /opt L'unité est exactement la même, à l'exception des noms de fichiers.

Pas si vite!

Cela laisse toujours le problème avec /usr. Bien sûr, il est facile d'écrire l'unité, mais le problème est que systemd a besoin de certaines bibliothèques /usr donc le système refusera de démarrer. J'ai envisagé de copier les bibliothèques vers l'un ou l'autre /lib ou quelque part dans le disque RAM initial, mais après qu'il s'est avéré être assez nombreux, j'ai décidé de ne pas le faire.

J'ai finalement décidé que tout monter tôt dans le processus de démarrage serait la bonne réponse. De cette façon, systemd peut imaginer qu'il a un disque complet. J'avais en fait envisagé d'utiliser lvm pour joindre les disques ensemble, mais j'ai décidé que c'était mauvais pour de nombreuses raisons et que j'avais peut-être eu les mêmes problèmes de toute façon. Je voulais contrôler ce qu'il y avait sur la carte SD par rapport au stockage interne, il était donc temps de regarder les scripts initramfs.

Démarrage de (certains) systèmes Linux

La plupart des distributions Linux modernes ne démarrent pas directement votre système de fichiers racine. Au lieu de cela, ils ont un système de fichiers compressé qui se charge dans la RAM puis démarre. Ce système est chargé de préparer le système pour le démarrage réel. Entre autres choses, il monte le système de fichiers racine, puis pivote pour en faire la véritable racine.

Pour les distributions de style Debian, il s'agit des initramfs et vous pouvez trouver des scripts définissables par l'utilisateur dans /etc/initramfs-tools. La plupart des prédéfinis sont en /usr/share/initramfs-tools. Dans le répertoire scripts, vous verrez un certain nombre de sous-répertoires avec les suffixes -top, -bottom et -premount.

Comme vous pouvez l'imaginer, init- * se produit à l'initialisation du système et local- * se produit lorsque les disques locaux sont montés. Ne les confondez pas avec les scripts hook. Un script hook s'exécute lorsque vous construisez le système de fichiers initial. Cela aide si vous devez modifier l'environnement de démarrage de manière statique. Les scripts que nous voulons sont ceux qui s'exécutent au moment du démarrage.

Les scripts supérieurs s'exécutent en premier, suivis du prémontage, puis du bas. Ainsi init-top s'exécute en premier et init-bottom est la dernière chose qui s'exécute. Entre les deux, les autres scripts s'exécutent et par le bas local, le système de fichiers racine devrait être prêt à fonctionner.

Documentation et Gotchas

Si vous lisez la documentation, vous verrez que les scripts ont un format spécifique. Cependant, certains exemples sont trompeurs. Par exemple, le script de modèle montre l'approvisionnement /usr/share/initramfs-tools/hook-functions pour charger des fonctions communes. C'est génial si /usr existe déjà, mais pas pour nous. Certains autres scripts utilisent une copie qui se trouve dans l'environnement de démarrage, situé à /usr/share/initramfs-tools/scripts/functions. C’est ce que j’ai utilisé dans mon script:


#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}

case $1 in
prereqs)
prereqs
exit 0
;;
esac

. scripts/functions
# Note: our root is on /root right now, not /
mount /dev/mmcblk2p1 /root/sdcard
mount -o bind /root/sdcard/usr /root/usr
mount -o bind /root/sdcard/home /root/home
mount -o bind /root/sdcard/opt /root/opt

Le seul problème est que notre éventuel système de fichiers racine n’est pas à /, c'est a /root, donc les montures reflètent cela.

Le résultat

Bien sûr, j'ai dû désactiver les montages systemd pour /opt et /home bien que j'aurais pu les laisser et ne pas les mettre dans ce script. Maintenant, au moment où systemd prend le contrôle, il peut trouver toutes les choses dans /usr il veut et le système démarre. Le déplacement de ces trois répertoires m'a laissé environ 70% du stockage interne libre et n'a pris qu'une petite partie de la SDCard.

Il existe probablement de nombreuses autres façons de procéder. J'ai mentionné lvm ou vous pouvez revenir aux anciens scripts d'initialisation. Mais cela fonctionne de manière fiable et est très flexible une fois que vous avez tout compris.

La clé Intel est assez petite, mais nous avons vu plus petite. Si vous essayez cela à la maison, n'oubliez pas que la connexion aux appareils eMMC n'est pas toujours une bonne idée.

LAISSER UN COMMENTAIRE

Rédigez votre commentaire !
Entrez votre nom ici