How to Make Linux Power Off When Halt Is Run

How to make linux power off when halt is run?

You should use poweroff command or halt -p. As per man 8 halt, halt command (with no arguments) doesn't guarantee to power off your machine. Reasons are described here:

halt was used before ACPI (which today will turn off the power for you)*. It would halt the system and then print a message to the effect of "it's ok to power off now". Back then there were physical on/off switches, rather than the combo ACPI controlled power button of modern computers.

*These days halt is smart enough to automatically call poweroff if ACPI is enabled. In fact, they are functionally equivalent now.

As you can see from halt tool source code, it issues reboot() system call with cmd = RB_POWER_OFF = LINUX_REBOOT_CMD_POWER_OFF.

In kernel, that system call is implemented here, and on cmd = LINUX_REBOOT_CMD_POWER_OFF, it calls:

   -> kernel_power_off()

   -> machine_power_off()

   -> pm_power_off()

halt and poweroff

Halt does just what it says: it stops the machine, leaving it in a powered-on state (which usually implies that someone has to reboot or shut it down manually afterwards). Like halt, poweroff also stops the machine, but also shut it down afterwards.

The fact that on your physical machine the halt command also shuts the machine down, might just be a tweak of your linux distribution (the proper halt behavior probably doesn't make much sense for everyday use).

Check

man halt

for details.

As for the CPU usage of your virtual machine after a halt, my half-educated guess is that since the operating system is not running on it anymore, no HLT instruction can be issued and therefore your console meter shows a 100% CPU usage (maybe your virtual machine control panel computes the CPU occupancy by checking how many HLT instructions are executed per second):

http://en.wikipedia.org/wiki/Idle_(CPU)

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

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?



Related Topics



Leave a reply



Submit