The immediate problem is that you do not sync the file before performing a reboot. The actual problem is that you are calling syscall reboot
directly, not paying attention to what else is going on in the system. What you are doing is very similar to simply pressing the HW reset button; you just give the kernel an opportunity to clean the cleaning a bit, but then everything will be killed. This is a dead, surefire way to end up messing up file systems and file structures. Do not do this!
Instead, you should ask init to do a graceful reboot. Calling syscall reboot
requires privileged access. Therefore, you can simply ask to restart the init system. Most systems have a symbolic link /sbin/reboot
, which points to a program that initiates a correct reboot if called through this symbolic link. Therefore, I recommend that you replace your dirty reboot(RB_AUTOBOOT)
(note the double specification "/sbin/reboot"
in execlp - this is important).
pid_t reboot_pid; if( 0 == (reboot_pid = fork()) ) { execlp("/sbin/reboot", "/sbin/reboot", NULL); exit(1); } if( -1 == reboot_pid ) { } int reboot_status; waitpid(reboot_pid, &reboot_status, 0); if( !WIFEXITED(reboot_status) ) { } if( 0 != WIFEXITSTATUS(reboot_status) ) { } else { fputs("reboot call sucessfull -- system is about to shutdown."); }
In this way, the system can gracefully shut down, terminate all programs launched in a clean manner, and disable all file systems before performing a reboot, thereby reading the file system and data integrity.
Note that if you expect your program will not have root access, you will have to jump on some hoops; on systems with systemd, you can send a reboot request using D-Bus. But except that it fails if the user executing the command does not have reboot privileges.
source share