2

How are PIDs assigned in RHEL7?
What is the probability that a PID used before boot will be assigned to a process after the reboot?

In other words, how statistically conceivable is it - on RHEL7 - that the same PID would be assigned to a process that starts after a machine's reboot, which is identical to a PID that was used before the reboot.

Edit:

Example: before a reboot, there is daemon A with PID 544, the machine is rebooted, and after the reboot, daemon A starts, and gets assigned PID 544.

  • Relating: https://unix.stackexchange.com/questions/16883/what-is-the-maximum-value-of-the-process-id and https://unix.stackexchange.com/questions/414971/pid-reuse-possibility-in-linux – Jeff Schaller Jan 31 '18 at 20:04

3 Answers3

2

If the init system is deterministic then it is highly likely that daemons started by that init system will start with the same pid across reboots, as the same code will be run each boot (though with randomization from the occasional fsck or selinux relabels or other such not-on-every-boot code).

However, systemd on RHEL7 is not deterministic: PIDs are allocated in sequence but systemd runs tasks in parallel possibly across multiple cores possibly waiting for various hardware or network services. Let's see what happens before and after to the process list:

$ ps axo pid,command | sort -n > before
$ sudo reboot
...
$ ps axo pid,command | sort -n > after
$ comm -12 before after | grep -v \\[
comm: file 1 is not in sorted order
comm: file 2 is not in sorted order
  PID COMMAND
    1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
  745 /usr/lib/systemd/systemd-logind
  864 /usr/sbin/NetworkManager --no-daemon
$ 

So that's two processes (excepting the obvious not-randomized "PID eins", and kernel threads marked with [) with the same PID. Across 30 reboots recording much the same information, it appears systemd is pretty good at randomizing the pids; during those reboots /usr/lib/systemd/systemd-logind came up at:

PID PERCENTAGE
733 5%
734 5%
737 15%
739 5%
743 5%
746 5%
748 5%
749 5%
752 10%
753 10%
755 5%
758 5%
760 5%
764 5%
771 5%
773 5%

The data was captured with a startup service:

[Unit]
Description=recordpidorder
After=getty.target

[Service]
Type=oneshot
ExecStart=/root/pidandboots

[Install]
WantedBy=multi-user.target

that ran:

#!/bin/bash
NF=/root/sequence
[[ ! -e "$NF" ]] && echo 0 > "$NF"
CUR=$(( 1 + $(< "$NF") ))
ps haxo pid,command > "/root/pidorder$CUR"
[[ $CUR -gt 30 ]] && mv /root/pidandboots /root/pidandboots.done
echo "$CUR" > "$NF"
reboot

Once the system is up and running process creation order will randomize itself as not-at-@reboot cron jobs fire, users login and run various different commands, etc. This will depend on the system, how many PIDs are created on it, etc.

So yes it is statistically conceivable that a daemon will come up at the same PID on a RedHat system that uses systemd. However, the odds will vary depending on the hardware and exact services the system offers.

thrig
  • 34,938
  • If a daemon dies and is respawned, its PID is not predictable. – Kevin Jan 31 '18 at 21:40
  • None are the same process, they maybe processes from the same image (file), but not the same process. Just because they have same name, and are from same image does not make them same process. Look at your process list you may see several instances of bash, but they are all separate processes. – ctrl-alt-delor Jan 31 '18 at 22:46
1

Short answer

100%

(I am not suggesting that it will be the same image, though init is always PID=1. Just that after a process dies, at some point its PID will be reused. )

Longer answer

They can be reused before reboot. They count up until all possible PIDs are used then start again, avoiding the ones in use.

At reboot they restart at 1 (the process init is always 1).


This is a general answer that should be true for ALL Unixs.

  • 1
    On Linux, you can control the max PID using sysctl -w kernel.pid_max=NNN, but as the answer says, that only delays the inevitable: if you run long enough, you will reuse PIDs. On my current system pid_max=32768, but I have had to increase it in the past when I had to create more processes than that, all running at the same time. – NickD Jan 31 '18 at 19:48
  • OpenBSD does not use sequential PIDs. A parent process may have PID 123 and its immediate child may have PID 84. – Kusalananda Jan 31 '18 at 22:21
  • @Kusalananda: I don't know how OpenBSD allocates PIDs. However, the second part of your statement is true of Linux (and all other Unixes) too, but that does not mean that the algorithm is not going through possible PIDs sequentially. It may be that all PIDs are taken, so it wraps around and gets 84. In practice, they may keep a range of unallocated PIDs (as FreeBSD does - or did in the version that the McKusick book describes) and when they run out, they initiate a scan for another range. Linux uses a radix tree. However the allocation is done, the main point is that PIDs are reused. – NickD Feb 01 '18 at 00:36
  • @Nick My comment was mainly about the PIDs "counting up" (as in "sequentially"/"incrementally") and "true for all Unices". It's simply not true. – Kusalananda Feb 01 '18 at 06:28
0

There is a 100% certainty that a given PID will be reused after a reboot, but there is no guarantee that a given program will get the same PID after a reboot that it had before the reboot (and in most cases, it won't).

Linux, like other UNIX systems, uses a dead-simple method for figuring out what PID a newly created process has, it just grabs the next one in numerical order after the PID used for the last process started that isn't in use. When it hits the cap specified by /proc/sys/kernel/pid_max, it starts at 1 again. Note that this sysctl is user tunable, but from a practical perspective it just limits the total number of processes on the system.

Now, there are a couple of specific exceptions to this rule. On boot, whatever your system uses as init (systemd by default on RHEL, but you can specify an arbitrary binary on the kernel command line) is always started as PID 1. On Linux specifically, PID 2 is always kthreadd, which is the core kernel process responsible for starting all other kernel threads, and a lot of kernel threads that get started very early will often consistently have the same PID across reboots too (for example, PID 4 will almost always be the softirq handler thread for CPU 0 on x86 systems), but this is dependent on the hardware configuration of the system.

  • PID for kthreadd is new-ish for Linux. Also I think, and this is somewhat a guess, that kthreadd is started before init/systemd, but PID 1 is reserved for it, as it has to have PID of 1. You can see that children of kthreadd get low numbered PIDs, so it looks like they also start before init/systemd. – ctrl-alt-delor Jan 31 '18 at 22:54
  • The PID for kthreadd got added back in 2.4 or 2.6 I believe, so it's been around for at least half a decade. You are correct though about it starting before init. It's the first execution context on the system after the bootloader hands off execution to the kernel (well, technically the second if you are using a compressed kernel image that isn't decompressed by the bootloader). – Austin Hemmelgarn Feb 01 '18 at 15:30
  • @AnstinHemmelgarn that is recent. I have been using Gnu since 1991, and with the Linux from 1997. – ctrl-alt-delor Feb 01 '18 at 16:37
  • @ctrl-alt-delor As a general rule, nobody's developing software to run on 2.4 or earlier these days (and I seriously doubt anyone is developing for 1997 vintage Linux, which if memory serves would be right around the end of the 1.x series), so it doesn't really matter much beyond historical interest that previous versions didn't have it. Keep in mind also though that 'recent' is a relative term. I don't really consider it recent, but I don't really deal with stuff on 'enterprise' release cycle timescales. – Austin Hemmelgarn Feb 01 '18 at 17:09
  • 1
    I only say it as it help to make sense of old documentation. And explains why init/systemd gets PID 1. Once upon a time it was the first process. Now parts of the system depend on it having PID 1, so it can not be moved. – ctrl-alt-delor Feb 01 '18 at 17:15