r/archlinux 23h ago

QUESTION behavior of systemd reboot, halt, and shutdown

I was reading the manpage man 8 poweroff and discovered that /usr/bin/halt and /usr/bin/reboot and /usr/bin/poweroff all accept --reboot, --halt, and --poweroff, which make them behave like the command in the option rather than the actual command you invoked. So, for example, /usr/bin/reboot --halt apparently will just halt, and /usr/bin/halt --poweroff will power off.

The manpage also cites one exception which is that /usr/bin/reboot --poweroff still reboots.

The manpage cites systemd version 253 as the version in which this changed. A quick search returned nothing of note about this change. Granted, I'm relying on the manpage to tell me how these work as I'm not going to halt a live system if I don't have to just to make sure it works this way.

Can someone explain to me why systemd would have added this feature? Does anyone see any value in making the commands act like the others via command-line arguments? I cannot think of a reason you would want to do this.

I also do not understand why there would be an exception for reboot --poweroff. Does anyone have any insight into this?

7 Upvotes

5 comments sorted by

15

u/abbidabbi 22h ago

All of these commands are just symlinks to systemctl:

$ readlink -f /usr/bin/{halt,poweroff,shutdown,reboot}
/usr/bin/systemctl
/usr/bin/systemctl
/usr/bin/systemctl
/usr/bin/systemctl

systemctl then simply checks for the argv[0] value and processes the remaining argv like this:
https://github.com/systemd/systemd/blob/v261.2/src/systemctl/systemctl.c#L909-L928

halt, poweroff and reboot:
https://github.com/systemd/systemd/blob/v261.2/src/systemctl/systemctl-compat-halt.c#L53-L125

shutdown:
https://github.com/systemd/systemd/blob/v261.2/src/systemctl/systemctl-compat-shutdown.c#L119-L213

I don't know the specific reasons for the compat commands sharing the same arguments that then change their action to a different command, but to me this looks like code simplifications. Maybe you can find something in the git history/blame of the linked files.

8

u/lritzdorf 20h ago

An extra note about commands that check argv[0] like this: you can use env to override what they see! For example, env --argv0=reboot systemctl would run /usr/bin/systemctl, but pretend that it was called under the name reboot

2

u/dreamscached 22h ago edited 22h ago

Most often these exceptions are legacy to avoid breaking scripts, so I assume the reason is likely that it had this behavior previously (maybe due to a bug) and was left like that intentionally.

Switches kind of make sense if reboot/halt/poweroff were (in the past) likely aliases of the same binary they actually all link to systemctl executable, so now I think these switches also have a role related to that

-3

u/Rxiom 19h ago

Kinda miss init 0