When used the way you have it, halt uses reboot syscall.
halt When called with --force or when in runlevel 0 or 6, this tool invokes the reboot(2) system call itself and directly reboots the system. Otherwise this simply invokes the shutdown(8) tool with the appropriate arguments. Source: https://linux.die.net/man/8/halt
shutdown, is not a syscall but an application. It goes through other system utilities to gracefully shutdown by closing applications and daemons in a defined order (specific to OS)
From the pov of the SD Card Health, the reboot syscall will safely halt the kernel and machine, it will also sync the file system and all that so it will preserve, for most purposes, the systems ability to boot without corruption.
However, any application state that has not been saved or written to kernel buffers will be lost. shutdown will generally send signals to applications before killing them outright, reboot bypasses any process level gracefuleness.
IMO for a power consumption experiment, the small risk of corruption is not a big deal, for production use that is another matter. I have used it myself to conduct similar experiments to what you are proposing in a commercial setting. To be more sure, you can explicitly invoke sync before the hard halt
sync && halt -f
Kernel Details
reboot in this case is a system call implemented in kernel/reboot.c that will eventually trigger either machine_restart , machine_halt, or machine_poweroff in the arm specific architecture files reboot.c
Note: In kernel land shutdown is used to restart or switch kernels, and not the same as operating system shutdown utility. reboot is a system call that handles restart , halt and poweroff
The kernel differentiates between halt and poweroff but only slightly, the poweroff goes through any power management system. In the case of the BCM there is no ability to power off externally.
/**
* kernel_halt - halt the system
*
* Shutdown everything and perform a clean system halt.
*/
void kernel_halt(void)
{
kernel_shutdown_prepare(SYSTEM_HALT);
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emerg("System halted\n");
kmsg_dump(KMSG_DUMP_HALT);
machine_halt();
}
EXPORT_SYMBOL_GPL(kernel_halt);
/**
* kernel_power_off - power_off the system
*
* Shutdown everything and perform a clean system power_off.
*/
void kernel_power_off(void)
{
kernel_shutdown_prepare(SYSTEM_POWER_OFF);
if (pm_power_off_prepare)
pm_power_off_prepare();
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emerg("Power down\n");
kmsg_dump(KMSG_DUMP_POWEROFF);
machine_power_off();
}
EXPORT_SYMBOL_GPL(kernel_power_off);
(https://github.com/raspberrypi/linux/blob/rpi-4.14.y/kernel/reboot.c#L241-L268)
On the arm side this is even more straight forward, halt calls poweroff
void machine_halt(void)
{
machine_power_off();
}
/*
* Power-off simply requires that the secondary CPUs stop performing any
* activity (executing tasks, handling interrupts). smp_send_stop()
* achieves this. When the system power is turned off, it will take all CPUs
* with it.
*/
void machine_power_off(void)
{
local_irq_disable();
smp_send_stop();
if (pm_power_off)
pm_power_off();
}
I do not believe that the bcm implementation defines any further specific pm_power_off, but that would be very low level, chip clock and power management reset, well after the kernel is done closing up shop.
For an example of how this halt looks in C, see this answer on so
#include <unistd.h>
#include <linux/reboot.h>
int main() {
reboot(LINUX_REBOOT_MAGIC1,
LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_POWER_OFF, 0);
}
which is equivalent to halt --poweroff -f
synccommand and any other process which may be not be killed before the filesystems are forcibly unmounted, and I'd like to avoid cutting the SDCard power before writes to the SDC are finished to avoid corrupted blocks. Or is that possible? Maybe I don't have to worry about a race condition, maybe it kills all other processes beforesyncis run? – taigrr Aug 25 '18 at 02:58