8

I'm using Arch Linux. I have read about systemd, and as I understand it, systemd is the first process, and it starts the rest of the processes. But when I use:

ps -aux

The result shows that /sbin/init has PID 1. And when I use:

pstree -Apn

The result shows that systemd has PID 1. Which is correct? Is /sbin/init starting systemd?

Robin Daugherty
  • 7,115
  • 4
  • 45
  • 59
James
  • 99
  • 1
  • 1
  • 5
  • 2
    An operating system built around systemd won't generally have any non-systemd `init` executable at all. Which is to say, it's entirely typical on such an OS for `/sbin/init` to *be* systemd. – Charles Duffy May 31 '17 at 02:39

1 Answers1

20

They're probably both right.

$ sudo ls -ltrh /proc/1/exe
[sudo] password for user: 
lrwxrwxrwx 1 root root 0 May 30 21:22 /proc/1/exe -> /lib/systemd/systemd

$ echo $(tr '\0' ' ' < /proc/1/cmdline )
/sbin/init splash

$ stat /sbin/init
  File: '/sbin/init' -> '/lib/systemd/systemd'
  Size: 20          Blocks: 0          IO Block: 4096   symbolic link
Device: 801h/2049d  Inode: 527481      Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-05-30 21:27:12.058023583 -0500
Modify: 2016-10-26 08:04:58.000000000 -0500
Change: 2016-11-19 11:38:45.749226284 -0600
 Birth: -

The commands above show us:

  • what is the file corresponding to pid 1's executable image?
  • what was invoked (passed to exec()) when pid 1 was started?
  • what are the characteristics of the path at /sbin/init?

On my system, /sbin/init is a symlink to "/lib/systemd/systemd". This is likely similar to your system. We can see what information ps -aux is using by straceing it.

$ strace  ps -aux
... 
open("/proc/1/cmdline", O_RDONLY)       = 6
read(6, "/sbin/init\0splash\0", 131072) = 18
read(6, "", 131054)                     = 0
close(6)                                = 0
...

and likewise for pstree:

$ strace pstree -Apn
...
getdents(3, /* 332 entries */, 32768)   = 8464
open("/proc/1/stat", O_RDONLY)          = 4
stat("/proc/1", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "1 (systemd) S 0 1 1 0 -1 4194560"..., 8192) = 192
read(4, "", 7168)                       = 0
open("/proc/1/task", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
...

So the difference in output is because they use different sources of information. /proc/1/cmdline tells us how the process was invoked. Whereas /proc/1/stat shows that the process' name is systemd.

$ cat /proc/1/stat
1 (systemd) S 0 1 1 0 -1 4194560 34371 596544 1358 3416 231 144 298 1758 20 0 1 0 4 190287872 772 18446744073709551615 1 1 0 0 0 0 671173123 4096 1260 0 0 0 17 2 0 0 12188 0 0 0 0 0 0 0 0 0 0
Brian Cain
  • 14,403
  • 3
  • 50
  • 88
  • can you explain more? I don't get it – James May 31 '17 at 02:31
  • 1
    @Seawish, what part don't you get? `/proc/1/exe` asks which executable file is being run; checking `/proc/1/cmdline` asks what command line was used to start that process; the two can be different things, and in the case the poster here describes, they're different because the command name referenced a symlink. – Charles Duffy May 31 '17 at 02:35
  • @Seawish I added more detail, let me know if it's clear or if you still need more details. – Brian Cain May 31 '17 at 02:38
  • Brian, can the process change its name (which is displayed by some ps utils)? How this method is called? Which files will be modified in `/proc/pid/`? (Firefox sometimes changes names, displayed in `top`) – osgx May 31 '17 at 02:39
  • @osgx, yes, a process can change its argv. There's no special function or method you need to call to do so -- you literally just follow the string array passed to `main()` and rewrite the memory behind it, so it's only if your software is written in a language that doesn't let you do so that you'd need something special. – Charles Duffy May 31 '17 at 02:40
  • I didn't see the description below before, now I'm understand. Thank you very much – James May 31 '17 at 02:40
  • An explanation of the history around "why" it is still named around "init" would be a useful addition to this answer. e.g. Why not have `/sbin/systemd/init` or something like that. I'm guessing it was a backwards compatible move and possibly "the only way" to pull it off. Also, https://wiki.archlinux.org/title/Systemd doesn't mention anything about `/sbin/init`, even though on Arch itself, PID is indeed `/sbin/init`. – Elijah Lynn Mar 02 '22 at 19:32
  • FWIW, on Amazon Linux 2, for PID 1, the command is `/usr/lib/systemd/systemd --switched-root --system --deserialize 21` – Elijah Lynn Mar 02 '22 at 19:47