mirror of
https://github.com/troglobit/finit.git
synced 2026-09-30 21:13:01 +07:00
Fix filesystems not unmounted at shutdown
Instead of unconditionally waiting 2 seconds for processes to die, check continuously for remaining processes, and break the loop when none remain. Turn PID 1 to a RT process with highest priority 99 during shutdown, this ensures it would not be preempted by other RT processes. Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com> Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com> Signed-off-by: Ming Liu <liu.ming50@gmail.com>
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
|
||||
#include <dirent.h>
|
||||
#include <string.h> /* strerror() */
|
||||
#include <sched.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef _LIBITE_LITE
|
||||
@@ -172,7 +173,7 @@ void unmount_regular(void);
|
||||
*
|
||||
* https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/
|
||||
*/
|
||||
void do_kill(int signo)
|
||||
void do_iterate_proc(int (*callback)(int, int *), int *context)
|
||||
{
|
||||
DIR *dirp;
|
||||
|
||||
@@ -191,6 +192,8 @@ void do_kill(int signo)
|
||||
pid = atoi(d->d_name);
|
||||
if (!pid)
|
||||
continue;
|
||||
if (pid == 1)
|
||||
continue;
|
||||
|
||||
snprintf(file, sizeof(file), "/proc/%s/cmdline", d->d_name);
|
||||
fp = fopen(file, "r");
|
||||
@@ -203,7 +206,10 @@ void do_kill(int signo)
|
||||
else if (file[0] == '@')
|
||||
_d("Skipping %s ...", &file[1]);
|
||||
else
|
||||
kill(pid, signo);
|
||||
if (callback(pid, context)) {
|
||||
print(0, "PID %d is still alive (%s)", pid, file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
@@ -211,8 +217,51 @@ void do_kill(int signo)
|
||||
}
|
||||
}
|
||||
|
||||
static int kill_callback(int pid, int *context)
|
||||
{
|
||||
kill(pid, (int)context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int status_callback(int pid, int *context)
|
||||
{
|
||||
*context = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* return value:
|
||||
* 1 - at least one process remaining
|
||||
* 0 - no processes remaining
|
||||
*/
|
||||
static int do_wait(int secs)
|
||||
{
|
||||
int has_proc;
|
||||
int tmo = 250000;
|
||||
int iterations = secs*1000*1000/tmo;
|
||||
|
||||
do {
|
||||
do_usleep(tmo);
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0)
|
||||
;
|
||||
has_proc = 0;
|
||||
iterations--;
|
||||
do_iterate_proc(status_callback, &has_proc);
|
||||
}
|
||||
while (has_proc && iterations > 0);
|
||||
|
||||
return has_proc;
|
||||
}
|
||||
|
||||
void do_shutdown(shutop_t op)
|
||||
{
|
||||
struct sched_param sched_param = { .sched_priority = 99 };
|
||||
|
||||
/*
|
||||
* On a PREEMPT-RT system, Finit must run as the highest prioritized
|
||||
* RT process to ensure it completes the shutdown sequence.
|
||||
*/
|
||||
sched_setscheduler(1, SCHED_RR, &sched_param);
|
||||
|
||||
if (sdown)
|
||||
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
|
||||
|
||||
@@ -223,9 +272,10 @@ void do_shutdown(shutop_t op)
|
||||
* Tell remaining non-monitored processes to exit, give them
|
||||
* time to exit gracefully, 2 sec was customary, we go for 1.
|
||||
*/
|
||||
do_kill(SIGTERM);
|
||||
do_sleep(1);
|
||||
do_kill(SIGKILL);
|
||||
do_iterate_proc(kill_callback, (int*)SIGTERM);
|
||||
if (do_wait(1)) {
|
||||
do_iterate_proc(kill_callback, (int*)SIGKILL);
|
||||
}
|
||||
|
||||
/* Exit plugins and API gracefully */
|
||||
plugin_exit();
|
||||
|
||||
+14
@@ -297,6 +297,20 @@ void do_sleep(unsigned int sec)
|
||||
;
|
||||
}
|
||||
|
||||
void do_usleep(unsigned int usec)
|
||||
{
|
||||
struct timespec deadline;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &deadline);
|
||||
|
||||
deadline.tv_nsec += usec * 1000;
|
||||
deadline.tv_sec += deadline.tv_nsec / 1000000000;
|
||||
deadline.tv_nsec = deadline.tv_nsec % 1000000000;
|
||||
|
||||
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0 && errno == EINTR)
|
||||
;
|
||||
}
|
||||
|
||||
/* Seconds since boot, from sysinfo() */
|
||||
long jiffies(void)
|
||||
{
|
||||
|
||||
@@ -64,6 +64,7 @@ char *sig2str (int sig);
|
||||
char *code2str (int code);
|
||||
|
||||
void do_sleep (unsigned int sec);
|
||||
void do_usleep (unsigned int usec);
|
||||
long jiffies (void);
|
||||
char *uptime (long secs, char *buf, size_t len);
|
||||
char *memsz (uint64_t sz, char *buf, size_t len);
|
||||
|
||||
Reference in New Issue
Block a user