Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148112668
D31230.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D31230.diff
View Options
diff --git a/sbin/init/init.8 b/sbin/init/init.8
--- a/sbin/init/init.8
+++ b/sbin/init/init.8
@@ -31,7 +31,7 @@
.\" @(#)init.8 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd August 6, 2019
+.Dd July 22, 2021
.Dt INIT 8
.Os
.Sh NAME
@@ -279,6 +279,14 @@
.Dq Li reboot
argument is used.
.Pp
+After all user processes have been terminated,
+.Nm
+will try to run the
+.Pa /etc/rc.final
+script.
+This script can be used to finally prepare and unmount filesystems that may have
+been needed during shutdown, for instance.
+.Pp
The role of
.Nm
is so critical that if it dies, the system will reboot itself
@@ -371,9 +379,10 @@
or
.Va init_script
if set, as well as for the
-.Pa /etc/rc
+.Pa /etc/rc ,
+.Pa /etc/rc.shutdown ,
and
-.Pa /etc/rc.shutdown
+.Pa /etc/rc.final
scripts.
The value of the corresponding
.Xr kenv 2
@@ -403,6 +412,8 @@
system startup commands
.It Pa /etc/rc.shutdown
system shutdown commands
+.It Pa /etc/rc.final
+system shutdown commands (after process termination)
.It Pa /var/log/init.log
log of
.Xr rc 8
diff --git a/sbin/init/init.c b/sbin/init/init.c
--- a/sbin/init/init.c
+++ b/sbin/init/init.c
@@ -109,6 +109,7 @@
static void revoke_ttys(void);
static int runshutdown(void);
static char *strk(char *);
+static void runfinal(void);
/*
* We really need a recursive typedef...
@@ -876,6 +877,8 @@
if (Reboot) {
/* Instead of going single user, let's reboot the machine */
sync();
+ /* Run scripts after all processes have been terminated. */
+ runfinal();
if (reboot(howto) == -1) {
emergency("reboot(%#x) failed, %m", howto);
_exit(1); /* panic and reboot */
@@ -2039,3 +2042,51 @@
}
}
#endif
+
+/*
+ * Run /etc/rc.final to execute scripts after all user processes have been
+ * terminated.
+ */
+static void
+runfinal(void)
+{
+ struct stat sb;
+ pid_t other_pid, pid;
+ sigset_t mask;
+
+ /* Avoid any surprises. */
+ alarm(0);
+
+ /* rc.final is optional. */
+ if (stat(_PATH_RUNFINAL, &sb) == -1 && errno == ENOENT)
+ return;
+ if (access(_PATH_RUNFINAL, X_OK) != 0) {
+ warning("%s exists, but not executable", _PATH_RUNFINAL);
+ return;
+ }
+
+ pid = fork();
+ if (pid == 0) {
+ /*
+ * Reopen stdin/stdout/stderr so that scripts can write to
+ * console.
+ */
+ close(0);
+ open(_PATH_DEVNULL, O_RDONLY);
+ close(1);
+ close(2);
+ open_console();
+ dup2(1, 2);
+ sigemptyset(&mask);
+ sigprocmask(SIG_SETMASK, &mask, NULL);
+ signal(SIGCHLD, SIG_DFL);
+ execl(_PATH_RUNFINAL, _PATH_RUNFINAL, NULL);
+ perror("execl(" _PATH_RUNFINAL ") failed");
+ exit(1);
+ }
+
+ /* Wait for rc.final script to exit */
+ while ((other_pid = waitpid(-1, NULL, 0)) != pid && other_pid > 0) {
+ continue;
+ }
+}
diff --git a/sbin/init/pathnames.h b/sbin/init/pathnames.h
--- a/sbin/init/pathnames.h
+++ b/sbin/init/pathnames.h
@@ -41,5 +41,6 @@
#define _PATH_SLOGGER "/sbin/session_logger"
#define _PATH_RUNCOM "/etc/rc"
#define _PATH_RUNDOWN "/etc/rc.shutdown"
+#define _PATH_RUNFINAL "/etc/rc.final"
#define _PATH_REROOT "/dev/reroot"
#define _PATH_REROOT_INIT _PATH_REROOT "/init"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 16, 9:06 PM (17 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29787701
Default Alt Text
D31230.diff (3 KB)
Attached To
Mode
D31230: init: execute /etc/rc.final after all user processes have terminated
Attached
Detach File
Event Timeline
Log In to Comment