Search code examples
linuxrebootsystemctlpower-off

The difference both reboot and poweroff of Linux by systemctl control


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 

Solution

  • 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.