From owner-dev-commits-src-branches@freebsd.org Thu Aug 26 06:44:02 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id BE935662F6A; Thu, 26 Aug 2021 06:44:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GwCxG3Z96z4S09; Thu, 26 Aug 2021 06:44:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 34B1432C2; Thu, 26 Aug 2021 06:44:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 17Q6i232042918; Thu, 26 Aug 2021 06:44:02 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 17Q6i2fv042917; Thu, 26 Aug 2021 06:44:02 GMT (envelope-from git) Date: Thu, 26 Aug 2021 06:44:02 GMT Message-Id: <202108260644.17Q6i2fv042917@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: 63c85520018a - stable/12 - init: execute /etc/rc.final after all user processes have terminated MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 63c85520018a2720c245e63a2d50d258b4e5201b Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Aug 2021 06:44:03 -0000 The branch stable/12 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=63c85520018a2720c245e63a2d50d258b4e5201b commit 63c85520018a2720c245e63a2d50d258b4e5201b Author: Kyle Evans AuthorDate: 2021-07-20 10:40:30 +0000 Commit: Kyle Evans CommitDate: 2021-08-26 06:43:37 +0000 init: execute /etc/rc.final after all user processes have terminated This can be useful for, e.g., unmounting filesystems that were needed for shutdown. Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. X-NetApp-PR: #63 (cherry picked from commit 4d1597691916240b9023ee9f15e249503abf67fd) --- sbin/init/init.8 | 17 ++++++++++++++--- sbin/init/init.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ sbin/init/pathnames.h | 1 + 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/sbin/init/init.8 b/sbin/init/init.8 index d852c32ef487..9475b1cce48f 100644 --- 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 @@ Otherwise, .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 @@ It is used for running the 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 @@ the terminal initialization information file 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 index 59bcfb6893dd..772d37b78664 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -109,6 +109,7 @@ static void disaster(int); static void revoke_ttys(void); static int runshutdown(void); static char *strk(char *); +static void runfinal(void); /* * We really need a recursive typedef... @@ -878,6 +879,8 @@ single_user(void) 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, %s", howto, strerror(errno)); @@ -2040,3 +2043,51 @@ setprocresources(const char *cname) } } #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 index 2ed366e4f7f7..7dc75ba52491 100644 --- 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"