4

In the output of ps aux, I can see the process just fine:

# ps aux | grep diff
root      7787 28.7  0.0   9368  4516 pts/3    D+   13:56  20:33 diff -qr mnt/mnt/md/ mnt/mnt2/
root     13130  0.0  0.0   6144   876 pts/4    S+   15:07   0:00 grep diff

But pidof claims not to be able to find anything:

# pidof diff
# echo $?
1

Looking at the man page, there is no info on what to do when lost a process, pidof has. /proc/7787/exe is a symlink to /usr/bin/diff and /usr/bin/diff itself is a regular file and an ELF. According to the man page, this ought to match.

Luc
  • 3,418
  • 3
  • 26
  • 37

2 Answers2

6

After some investigation with strace, it seems that pidof also checks the status of the processes. My diff process was in D state most of the time, meaning it is waiting for I/O a lot. With this knowledge, I ran pidof a bunch of times (this is within ~3 seconds):

# pidof diff
7787
# pidof diff
# pidof diff
7787
# pidof diff
# pidof diff
# pidof diff
# pidof diff
# pidof diff
# pidof diff
# pidof diff
# pidof diff
# pidof diff
# pidof diff
7787
# pidof diff
7787

It indeed returns it 'sometimes', seeming to confirm the suspicion that pidof only return processes that are not in D state.

Checking the source code of pidof in src/killall5.c (obtained using apt source sysvinit-utils), the answer lies on line 599:

if ( (strchr(process_status, 'D') != NULL) ||
     (strchr(process_status, 'Z') != NULL) ){
   /* Ignore zombie processes or processes in
      disk sleep, as attempts
      to access the stats of these will
      sometimes fail. */
Luc
  • 3,418
  • 3
  • 26
  • 37
  • So rather than sometimes failing, they elect to always fail on processes in those states. And `pidof` doesn't use any stats anyway, just shows the process ID. It can surely check the process ID and exe name, in fact this little shell command does it: `ls -l /proc/*/exe 2>/dev/null | grep "/$WHAT$"` Am I missing something? I'd like to do a git blame on this one and ask them a few pointed questions. – Sam Watkins May 03 '21 at 01:59
  • @SamWatkins By all means! I see it the same way. – Luc May 03 '21 at 07:55
3

In sysvinit 2.96 and later, pidof -z will include processes that are in disk I/O ('D') or zombie ('Z') state.

jamesy
  • 46
  • 1
  • 2
    Thanks! I checked out some more info, here are links for others that are interested: [commit that introduced the problem (Oct 2018)](http://git.savannah.nongnu.org/cgit/sysvinit.git/commit/src/killall5.c?id=1b659c8ebebd86be51095ab905293889a306ff01) | [sysvinit-utils bug report (Jun 2019)](https://savannah.nongnu.org/bugs/?56534) | [debian bug thread about the problem (Apr 2019--Oct 2021)](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=926896) – Luc Dec 06 '21 at 13:14
  • Thanks for this info. It seems that whoever changed the behaviour of `pidof` has made quite a mess of backwards-incompatibility. – Craig McQueen Dec 16 '21 at 04:31