diff --git a/doc/config.md b/doc/config.md index bd257154..17cc40bb 100644 --- a/doc/config.md +++ b/doc/config.md @@ -850,6 +850,27 @@ Log rotation is controlled using the global `log` setting. service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon +### Misc Settings + +**Syntax:** `reboot-delay <0-60>` + +Optional delay at reboot (or shutdown or halt) to allow kernel +filesystem threads to complete after calling `sync(2)` before +rebooting. This applies primarily to filesystems that do not +have a reboot notifier implemented. At the point of writing, +the only known filesystems affected are: ubifs, jffs2. + +*Default:* 0 (disabled) + +When enabled (non-zeoro), this delay runs after file systems have been +unmounted and the root filesystem has been remounted read-only, and +sync(2) has been called, twice. + +> "On Linux, sync is only guaranteed to schedule the dirty blocks for +> writing; it can actually take a short time before all the blocks are +> finally written. + + Rescue Mode ----------- diff --git a/src/conf.c b/src/conf.c index aa1768de..00b9a516 100644 --- a/src/conf.c +++ b/src/conf.c @@ -764,6 +764,11 @@ static int parse_static(char *line, int is_rcsd) return 0; } + if (MATCH_CMD(line, "reboot-delay ", x)) { + syncsec = strtonum(strip_line(x), 0, 60, NULL); + return 0; + } + /* * Periodic check and instability index leveler, seconds */ diff --git a/src/finit.c b/src/finit.c index b5c87a68..2238db31 100644 --- a/src/finit.c +++ b/src/finit.c @@ -70,6 +70,7 @@ int rescue = 0; /* rescue mode from kernel cmdline */ int single = 0; /* single user mode from kernel cmdline */ int bootstrap = 1; /* set while bootrapping (for TTYs) */ int kerndebug = 0; /* set if /proc/sys/kernel/printk > 7 */ +int syncsec = 0; /* reboot delay */ char *finit_conf= NULL; char *finit_rcsd= NULL; char *fstab = NULL; diff --git a/src/finit.h b/src/finit.h index 090f4d98..5cebe6ab 100644 --- a/src/finit.h +++ b/src/finit.h @@ -118,6 +118,7 @@ extern int rescue; extern int single; extern int bootstrap; extern int kerndebug; +extern int syncsec; extern char *fstab; extern char *sdown; extern char *network; diff --git a/src/sig.c b/src/sig.c index 383d3142..350a3f0c 100644 --- a/src/sig.c +++ b/src/sig.c @@ -382,6 +382,20 @@ void do_shutdown(shutop_t op) print(0, "Calling hook/svc/down scripts ..."); plugin_run_hooks(HOOK_SYS_DN); + /* + * Optional reboot-delay, needed on systems running ubifs, jffs, + * or similar. From fileutils-4.0, sync(8); "On Linux, sync is + * only guaranteed to schedule the dirty blocks for writing; it + * can actually take a short time before all the blocks are + * finally written." -- https://linux.die.net/man/8/sync + */ + sync(); + if (syncsec > 0) { + print(-1, "Reboot delay, waiting for filesystem sync, %d sec", syncsec); + do_sleep(syncsec); + print(0, NULL); + } + /* Reboot via watchdog or kernel, or shutdown? */ if (op == SHUT_REBOOT) { print(0, "Rebooting ...");