Both reboot and poweroff are mapped to /bin/systemctl
, how does systemctl
control shutdown and restart. When entering reboot or poweroff, how does systemctl
get which command should be executed?
It looks like both reboot and poweroff are linked to /bin/systemctl
➜ /usr/bin file /usr/sbin/reboot
/usr/sbin/reboot: symbolic link to /bin/systemctl
➜ /usr/bin file /usr/sbin/poweroff
/usr/sbin/poweroff: symbolic link to /bin/systemctl
➜ /usr/bin
➜ /usr/bin
➜ /usr/bin
➜ /usr/bin uname -a
Linux mi-OptiPlex-7080 5.15.0-76-generic #83~20.04.1-Ubuntu SMP Wed Jun 21 20:23:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
➜ /usr/bin
how does systemctl control shutdown and restart
When a command is executed under Linux it receives parameters. There is a special, first or "zero" parameter, that is the name of the process executed. See man execve
.
$ bash -c 'echo $0'
bash
$ strace bash -c 'echo $0' 2>&1 | grep exec
execve("/usr/bin/bash", ["bash", "-c", "echo $0"], 0x7fff48f3f1d0 /* 115 vars */) = 0
^^^^^^^ - argument 2
^^ - argument 1
^^^^^ - argument 0
^^^^^^^^^^^^^ - process to execute
The C program that is systemctl just checks the "0"-th argument and compares the string. In pseudocode:
int main(int argc, char *argv[]) {
if (strcmp(argv[0], "poweroff") == 0) {
I_am_poweroff();
else if (strcmp(argv[0], "reboot") == 0) {
reboot();
} etc...
}
In real code this happens here https://github.com/systemd/systemd/blob/main/src/systemctl/systemctl.c#L1083 :
. You may also be interested in busybox
project.