J'ai rencontré un problème étrange dans lequel une ps -o args -p <pid>
commande échoue très occasionnellement à trouver le processus en question, même s'il s'exécute définitivement sur le serveur en question. Les processus en question sont des scripts wrapper de longue durée utilisés pour lancer certaines applications Java.
Les « dans la nature » occurrences de la question semblent toujours arriver tôt le matin, donc il y a des preuves qu'il est lié à la charge du disque sur le serveur en question, car ils sont assez fortement chargés alors, mais en exécutant l' ps
en question dans une boucle serrée, je peux éventuellement reproduire le problème - une fois toutes les quelques centaines d'exécutions, j'obtiens une erreur.
En exécutant le script bash suivant, j'ai réussi à générer une sortie strace pour une exécution échouée et réussie:
while [ $? == 0 ] ; do strace -o fail.out ps -o args -p <pid> >/dev/null ; done ; strace -o good.out ps -o args -p <pid>
En comparant la sortie de fail.out
et good.out
, je peux voir que l' getdents
appel système lors de l'exécution qui échoue renvoie en quelque sorte un nombre beaucoup plus petit que le nombre réel de processus sur le système (de l'ordre de ~ 500 par rapport à ~ 1100)
grep getdents good.out
getdents(5, /* 1174 entries */, 32768) = 32760
getdents(5, /* 31 entries */, 32768) = 992
getdents(5, /* 0 entries */, 32768) = 0
grep getdents fail.out
getdents(5, /* 673 entries */, 32768) = 16728
getdents(5, /* 0 entries */, 32768) = 0
... et cette liste plus courte n'inclut pas le pid en question, il n'est donc pas trouvé.
Vous pouvez ignorer cette section, les erreurs ENOTTY sont expliquées par le commentaire de dave_thompson ci-dessous, et ne sont pas liées
En outre, l'exécution a échoué obtient des
ENOTTY
erreurs qui n'apparaissent pas dans l'exécution réussie. Vers le début de la sortie je voisioctl (1, TIOCGWINSZ, 0x7fffe19db310) = -1 ENOTTY (ioctl inapproprié pour le périphérique) ioctl (1, TCGETS, 0x7fffe19db280) = -1 ENOTTY (ioctl inapproprié pour le périphérique)
Et à la fin, je vois un seul
ioctl (1, TCGETS, 0x7fffe19db0d0) = -1 ENOTTY (ioctl inapproprié pour le périphérique)
L'échec
ioctl
à la fin se produit juste avant lesps
retours, mais il se produit après que leps
a déjà imprimé un ensemble de résultats vide, donc je ne suis pas sûr s'ils sont liés. Je sais qu'ils sont cohérents dans toutes les sorties d'échec échouées que j'ai, mais n'apparaissent pas dans celles réussies.
Je n'ai absolument aucune idée pourquoi getdents
ne trouverait pas occasionnellement la liste complète des processus, et j'ai maintenant atteint le point où je vais juste gifler un pansement sur le tout en changeant le script de contrôle qui vérifie le script wrapper en question d'appeler ps
une deuxième fois si la première échoue, mais je serais intéressé de savoir si quelqu'un a des idées sur ce qui se passe ici.
Le système en question exécute le noyau 4.16.13-1.el7.elrepo.x86_64 sur CentOS 7 et la version procps-ng 3.3.10-17.el7_5.2.x86_64
>/dev/null
sur l'invocation «échec» (dans la boucle) mais pas sur l'invocation «bonne», d'où l'ENOTTY sur le fd 1.