#include "umount.h"
#include "util.h"
-#define TIMEOUT_USEC (5 * USEC_PER_SEC)
+#define TIMEOUT_USEC (5 * USEC_PER_SEC)
#define FINALIZE_ATTEMPTS 50
#define FINALIZE_CRITICAL_ATTEMPTS 10
-_noreturn_ static void freeze(void) {
- for (;;)
- pause();
-}
-
static bool ignore_proc(pid_t pid) {
if (pid == 1)
return true;
return r;
}
-
int main(int argc, char *argv[]) {
int cmd, r, retries;
bool need_umount = true, need_swapoff = true, need_loop_detach = true;
log_open();
if (getpid() != 1) {
- log_error("Not executed by init (pid-1).");
+ log_error("Not executed by init (pid 1).");
r = -EPERM;
goto error;
}
if (r < 0)
log_warning("Cannot send SIGKILL to all process: %s", strerror(r));
-
- /* preventing that we won't block umounts */
- if (chdir("/") != 0)
- log_warning("Cannot chdir(\"/\"): %m. Unmounts likely to fail.");
-
- /* umount all mountpoints, swaps, and loopback devices */
+ /* Unmount all mountpoints, swaps, and loopback devices */
retries = FINALIZE_ATTEMPTS;
while (need_umount || need_swapoff || need_loop_detach) {
if (need_umount) {
if (need_umount || need_swapoff || need_loop_detach) {
retries--;
- if (retries <= FINALIZE_CRITICAL_ATTEMPTS) {
+ if (retries == FINALIZE_CRITICAL_ATTEMPTS) {
log_warning("Approaching critical level to finalize filesystem and devices, try to kill all processes.");
rescue_send_signal(SIGTERM);
rescue_send_signal(SIGKILL);
}
if (retries > 0)
- log_info("Action still required, %d tries left", retries);
+ log_info("Action still required, %d tries left.", retries);
else {
- log_error("Tried enough but still action required need_umount=%d, need_swapoff=%d, need_loop_detach=%d", need_umount, need_swapoff, need_loop_detach);
- r = -EBUSY;
- goto error;
+ log_error("Giving up. Actions left: Umount=%s, Swap off=%s, Loop detach=%s",
+ yes_no(need_umount), yes_no(need_swapoff), yes_no(need_loop_detach));
+ break;
}
}
}
r = -r;
log_error("Critical error while doing system shutdown: %s", strerror(r));
freeze();
- return 0;
+ return EXIT_FAILURE;
}