5505 links
  • GuiGui's Show

  • Home
  • Login
  • RSS Feed
  • Tag cloud
  • Picture wall
  • Daily
Links per page: 20 50 100
page 1 / 1
  • systemd : « status=203/EXEC » et ordonnancement des units

    TL;DR : indique à systemd l'ensemble des dépendances d'un service qu'il doit lancer, y compris les partitions qui doivent être montées au préalable. Surtout si le binaire qu'une unit systemd doit lancer est stocké sur une autre partition que la partition racine. Sans ça, tu t'exposes à un comportement aléatoire (unit démarre, unit démarre pas, unit démarre, etc.) lors du démarrage de la machine.



    Suite au déplacement sans interruption raté d'une machine virtuelle au sein d'une grappe d'hyperviseurs (migration à chaud) et à son crash, je démarre ladite machine virtuelle Red Hat 7.9. Il s'agit d'une machine de test donc je suis détendu, mais après 30 minutes, ma supervision m'indique toujours que les bases de données Oracle ne sont pas ouvertes. En effet, systemctl status oracledb indique « code=exited », « status=203/EXEC ». Pas d'info complémentaire intéressante dans l'extrait de journal également retourné par la commande.

    Une recherche dans la doc' officielle de systemd me met sur la piste que le programme à lancer est inaccessible ou non-exécutable. Pourtant, un systemctl start oracledb fonctionne. Donc le binaire est OK en temps normal… mais pas au démarrage du serveur ?

    Regardons ce que lance l'unit avec systemctl show oracledb | grep -i execstart. (On peut aussi faire systemctl show oracledb -p ExecStart. Attention à bien respecter les majuscules, sensibilité à la case, tout ça.) Il n'y a pas de programme lancé au préalable (« ExecStartPre ») qui pourrait lui aussi foirer. « ExecStart=/appli/oracle/product/19c/db/bin/dbstart ». Hum… Sur ce serveur, /appli est un volume logique LVM distinct de celui de la racine. Il est référencé dans fstab et il est monté automatiquement au démarrage. Est-il possible que systemd tente de démarrer Oracle avant le montage de /appli ?

    Un détail dans la définition de l'unit oracledb conforte cette hypothèse : « After=opt-oracle.mount ». Cette unit est explicitement conçue pour être démarrée après que /opt/oracle ait été montée. Mais, sur ce serveur, Oracle est stocké dans /appli/oracle. Oubli d'adapter l'unit systemd ?

    Une lecture de /var/log/boot.log valide définitivemnt cette hypothèse : systemd a d'abord tenté de lancer le service oracledb avant de monter /appli.

    A posteriori, je pense que c'est plus subtil que cela. La machine virtuelle crashe lors de sa migration à chaud. Au démarrage suivant, fsck est lancé. Il vérifie d'abord /, puis les autres partitions, car, dans fstab, elles ont la valeur 2 à l'attribut « fs_passno » (6e champ). En attendant, en l'absence d'information sur la dépendance, systemd lance le service oracledb. Cela explique pourquoi le démarrage d'Oracle au boot peut être effectif ou non : race condition.

    Pour régler le problème, il faut conditionner le lancement du service oracledb au montage de /appli. L'unit est stockée dans /usr/lib/systemd/system/oracledb.service. Normalement, ces units sont censées être déposées par des paquets, des installeurs, etc., et ne pas être modifiées par l'administrateur. Dans le cas présent, mes collègues ont déjà trifouillé dedans, donc je continue. Avec n'importe quel éditeur de texte, je remplace la ligne After=opt-oracle.mount par After=appli.mount.

    Si j'avais voulu faire propre, j'aurai fait systemctl edit oracledb. Cela aurait créé une surcharge de l'unit sous la forme d'un fichier stocké dans /etc/systemd/system/oracledb.service.d/override.conf. Dedans, j'aurai mis le contenu suivant :

    [Unit]
    After=appli.mount

    J'ai redémarré trois fois ce serveur (afin d'avoir des stats fiables) : 0 échec du service oracledb. \o/ Dans le journal, je vois que l'unit' oracledb est lancée immédiatement après le montage de /appli.

    N'étant pas le référent de ce serveur, j'en parle à celui-ci, afin, notamment, qu'il valide ma modif' et qu'il l'applique en prod'. Il est étonné : c'est la même unit systemd pour lancer Oracle sur tous ses serveurs et ça juste marche ailleurs. On regarde ensemble sur un autre serveur. Ce n'est pas la même unit. Celle-ci contient « After=network.target ».

    Là encore, c'est un coup de chance que cela fonctionne : on peut raisonnablement espérer que le réseau sera monté après les partitions locales. Donc si l'on demande à systemd de lancer Oracle après le réseau, on peut légitimement s'attendre à ce que ça fonctionne. Mais c'est bancal… et implicite (les pré-requis d'un service ne sont pas clairement énoncés).

    Bref, prends soin des dépendances de tes units systemd.

    Wed Apr 20 23:26:50 2022 - permalink -
    - http://shaarli.guiguishow.info/?-n5jRw
Links per page: 20 50 100
page 1 / 1
Mentions légales identiques à celles de mon blog | CC BY-SA 3.0

Shaarli - The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community