Billy Billy - 2 months ago 17
C Question

Shutdown Linux from C program meant to be ran as init process

I'm writing a C program to do various stuff on a Linux system, then shut it down. This program will be started with the command line option

init=/path/to/program
with PID 1, and because of that, I can't use
execl("/sbin/poweroff", "poweroff", NULL);
, because the
poweroff
command doesn't shutdown the system itself, it asks the process with PID 1 to do it. So what code does
init
use to shutdown the system?

Answer

Why doesn't poweroff work?

A number of programs assume the kernel has booted with init as PID 1. On many systems init is a symbolic link to the systemd program; similarly on these systems, poweroff is often a symbolic link to the systemctl program.

In your setup, systemd is never started since you set your custom init=/path/to/program kernel parameter line. This is why the poweroff command doesn't work: systemctl is trying to contact a systemd instance which was never created.

How to power off without systemd.

The reboot function is described in the Linux Programmer's Manual. Under glibc, you can pass the RB_POWER_OFF macro constant to perform the reboot.

Note that if reboot is not preceded by a call to sync, data may be lost.

Using glibc in Linux:

#include <unistd.h>
#include <sys/reboot.h>

sync();
reboot(RB_POWER_OFF);

See also

How to restart Linux from inside a C++ program?

Comments