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
How to Get Gcc to Skip Errors, But Still Output Them
"Bad Interpreter" Error Message When Trying to Run Awk Executable
Removing of Specific Line in Text File
Why a Linux Redirect Truncates the File
"Command Not Found" Piping a Variable to Cut When Output Stored in a Variable
Terminal Closes When I Source My Script (Run with Dot at the Start)
Bash Extglob Negate Not Working as I Expect
How to Enable Keep-Alive in Haproxy
Bash: Update a Variable Within a File
How to Ask Bash for the Current Options
Stop Being Root in the Middle of a Script That Was Run with Sudo
I'm Having Difficulty Understanding the Shellshock Vulnerability Verification
Jupyter Lab - Suppress Console Output
In Bash How to Split a Column in Several Column of Fixed Dimension
Docker in Wsl2 Alpine Without Docker Desktop