El problema inmediato es que no sincroniza el archivo antes de reiniciar. El problema real es que llama a la llamada de sistema reboot
directamente, sin tener en cuenta qué más está sucediendo en el sistema. Lo que haces es muy similar a simplemente presionar el botón de reinicio HW; simplemente le das al kernel la oportunidad de limpiar un poco, pero luego todo se mata de la manera más difícil. Esta es una forma segura de corromper sistemas de archivos y estructuras de archivos. ¡No hagas esto!.
En su lugar, debe solicitar al sistema init que realice un reinicio completo. Llamar al reboot
syscall requiere acceso privilegiado. Entonces puedes pedirle al sistema init que se reinicie también. En la mayoría de los sistemas hay un enlace simbólico /sbin/reboot
que apunta al programa que iniciará un reinicio en buen estado si se llama a través de ese enlace simbólico. Por lo tanto, le recomiendo que reemplace su sucio reboot(RB_AUTOBOOT)
con (tenga en cuenta la doble especificación de "/sbin/reboot"
en execlp - esto es importante).
pid_t reboot_pid;
if(0 == (reboot_pid = fork())) {
execlp("/sbin/reboot", "/sbin/reboot", NULL);
exit(1); /* never reached if execlp succeeds. */
}
if(-1 == reboot_pid) {
/* fork error... deal with it somehow */
}
int reboot_status;
waitpid(reboot_pid, &reboot_status, 0);
if(!WIFEXITED(reboot_status)) {
/* reboot process did not exit sanely... deal with it somehow */
}
if(0 != WIFEXITSTATUS(reboot_status)) {
/* reboot process exited with error;
* most likely the user lacks the required privileges */
}
else {
fputs("reboot call sucessfull -- system is about to shutdown.");
/* The init system is now shutting down the system. It will signals all
* programs to terminate by sending SIGTERM, followed by SIGKILL to
* programs that didn't terminate gracefully. */
}
Hacerlo de esa manera el sistema puede cerrar de forma correcta, cerrar todos los programas que se ejecutan de una manera limpia y desmontar todos los sistemas de archivos antes de realizar el reinicio, por lo tanto keeing sistema de archivos y la integridad de los datos.
Tenga en cuenta que si espera que su programa no tenga acceso de root, entonces tendrá que saltar algunos aros; en sistemas con systemd puede enviar una solicitud de reinicio por D-Bus. Pero excepto que falle, si el usuario que ejecuta el comando no tiene privilegios de reinicio.
Enjuague (sincronice) el archivo usted mismo: http: //linux.die.net/man/2/fsync ... – ChristopheD
No estoy en desacuerdo, pero me sorprende que llamar a fclose() no sea suficiente . – larsks
@larsks Vea mis respuestas. La página man explícitamente esto. Aunque es un poco extraño – pmr