web-dev-qa-db-fra.com

Comment s'assurer que systemd ne démarre pas une unité avant que udev n'ait créé le nœud de périphérique

Je veux monter un système de fichiers UBI au démarrage. Selon la configuration, le numéro de périphérique MTD peut varier d'une génération à l'autre, mais il s'agira toujours de la partition appelée add.

J'ai ajouté les fichiers suivants

# /usr/lib/udev/rules.d/76-mtd-alias.rules
ACTION!="add", GOTO="mtd_alias_end"
SUBSYSTEM=="mtd", SYMLINK="mtd-byname/$attr{name}", TAG+="systemd"
LABEL="mtd_alias_end"

cela crée des fichiers comme /dev/mtd-by-name/add en tant que lien symbolique vers le fichier /dev/mtdblockX approprié (où X dépend de la configuration).

# /usr/lib/systemd/system/mnt-data.mount
[Unit]
Description=Mount data partition
Requires=data-attach.service
After=data-attach.service
[Mount]
What=ubi0_0
Where=/mnt/data
Type=ubifs

ensemble avec

#/usr/lib/systemd/system/data-attach.service
[Unit]
Description=Attach data ubi partition

[Service]
Type=oneshot
RemainAfterExit=yes
Requires=dev-mtd\x2dbyname-add.device
After=dev-mtd\x2dbyname-add.device
ExecStart=/usr/sbin/ubiattach /dev/ubi_ctrl -p /dev/mtd-byname/add
ExecStop=/usr/sbin/ubidetach /dev/ubi_ctrl -p /dev/mtd-byname/add

Le problème est que bien que systemdne démarre le data-attach.service, il le fait toujours avant que udev n'ait créé les liens symboliques.

Une fois le système démarré, je peux voir que la device a été démarrée, bien que le montage ait échoué:

# systemctl status data-attach.service
● data-attach.service - Attach data ubi partition
   Loaded: loaded (/lib/systemd/system/data-attach.service; static; vendor preset: enabled)
   Active: failed (Result: exit-code) since Fri 2018-06-22 11:11:50 UTC; 7min ago
  Process: 164 ExecStart=/usr/sbin/ubiattach /dev/ubi_ctrl -p /dev/mtd-byname/add (code=exited, status=255)
 Main PID: 164 (code=exited, status=255)

Jun 22 11:11:50 LogiPeru ubiattach[164]: libubi: error!: cannot stat "/dev/mtd-byname/add"
Jun 22 11:11:50 LogiPeru ubiattach[164]:         error 2 (No such file or directory)
Jun 22 11:11:50 LogiPeru ubiattach[164]: ubiattach: error!: cannot attach "/dev/mtd-byname/add"
Jun 22 11:11:50 LogiPeru ubiattach[164]:            error 2 (No such file or directory)
Jun 22 11:11:50 LogiPeru systemd[1]: Starting Attach data ubi partition...
Jun 22 11:11:50 LogiPeru systemd[1]: data-attach.service: Main process exited, code=exited, status=255/n/a
Jun 22 11:11:50 LogiPeru systemd[1]: data-attach.service: Failed with result 'exit-code'.
Jun 22 11:11:50 LogiPeru systemd[1]: Failed to start Attach data ubi partition.

Mais le device s'est chargé:

# systemctl status 'dev-mtd\x2dbyname-add.device'
● dev-mtd\x2dbyname-add.device - /dev/mtd-byname/add
   Follow: unit currently follows state of sys-devices-virtual-mtd-mtd10.device
   Loaded: loaded
   Active: active (plugged) since Fri 2018-06-22 11:11:50 UTC; 10min ago
   Device: /sys/devices/virtual/mtd/mtd10
# ls -l /dev/mtd-byname/add
lrwxrwxrwx    1 root     root             8 Jun 22 11:11 /dev/mtd-byname/add -> ../mtd10

Où me suis-je trompé? Pourquoi les étiquettes Requires et After du data-attach.service sont-elles ignorées? Si j'attends que je puisse me connecter, je peux alors exécuter systemctl start mnt-data.mount et le montage réussit.

2
NickStoughton
_[Service]
<...>
Requires=dev-mtd\x2dbyname-add.device
After=dev-mtd\x2dbyname-add.device
_

Vous devez placer les directives Requires= et After= dans la section _[Unit]_ du fichier d'unité. Ils ne fonctionneront ni dans la section _[Service]_ ni dans aucune autre section.

Un conseil pour un diagnostic futur: _systemctl daemon-reload_, comme les autres verbes systemctl, écrit ses avertissements et ses erreurs uniquement dans le journal système et non dans la sortie stdout/stderr de systemctl (c'est-à-dire la console). _systemctl daemon-reload_, en particulier, signale uniquement les échecs relatifs aux erreurs critiques, comme l'échec de la communication avec systemd. Par conséquent, il peut être intéressant de vérifier manuellement le journal système avec quelque chose comme _journalctl -e _PID=1_ après toute commande systemctl.

2
intelfx