aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-01-17 23:07:49 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-01-17 23:07:49 +0000
commit25f4880b88f77188cc8a099832cafa814d7c2930 (patch)
tree0fea8aa3ae4fe6a9d11447e56c0b9cc00848b509
parente469b5e1acd7efe60b92678cba0a00b891a68659 (diff)
downloads6-rc-25f4880b88f77188cc8a099832cafa814d7c2930.tar.gz
Add --no-update option to s6-rc-set-install
-rw-r--r--doc/s6-rc-set-install.html7
-rw-r--r--src/repo/s6-rc-set-install.c118
2 files changed, 69 insertions, 56 deletions
diff --git a/doc/s6-rc-set-install.html b/doc/s6-rc-set-install.html
index c3051f4..8cdede9 100644
--- a/doc/s6-rc-set-install.html
+++ b/doc/s6-rc-set-install.html
@@ -88,6 +88,13 @@ is the path to that old database. It can e.g. be used by automation to keep
the possibility of rollbacks.
By default, s6-rc-set-install will delete the old live database after
successfully updating to the new one. </dd>
+
+ <dt> --no-update </dt>
+ <dd> Only copy the database from the repository and link it as boot database;
+do not run <a href="s6-rc-update.html">s6-rc-update</a>. This should <em>only</em>
+be used for a first installation, never when services are already managed with
+s6-rc &mdash; else it bypasses the check that the default enabled service set
+is actually viable, and might give an unpleasant surprise at next boot. </dd>
</dl>
<h2> Exit codes </h2>
diff --git a/src/repo/s6-rc-set-install.c b/src/repo/s6-rc-set-install.c
index 27c58cf..b81bd21 100644
--- a/src/repo/s6-rc-set-install.c
+++ b/src/repo/s6-rc-set-install.c
@@ -33,7 +33,8 @@
enum golb_e
{
GOLB_BLOCK = 0x01,
- GOLB_KEEPOLD = 0x02
+ GOLB_KEEPOLD = 0x02,
+ GOLB_NOUPDATE = 0x04,
} ;
enum gola_e
@@ -51,7 +52,8 @@ int main (int argc, char const *const *argv)
static gol_bool const rgolb[] =
{
{ .so = 'b', .lo = "block", .clear = 0, .set = GOLB_BLOCK },
- { .so = 'K', .lo = "keep-old", .clear = 0, .set = GOLB_KEEPOLD }
+ { .so = 'K', .lo = "keep-old", .clear = 0, .set = GOLB_KEEPOLD },
+ { .so = 0, .lo = "--no-update", .set = GOLB_NOUPDATE },
} ;
static gol_arg const rgola[] =
{
@@ -158,65 +160,69 @@ int main (int argc, char const *const *argv)
strerr_diefu4sys(111, "recursively copy ", cfull, " to ", dstfn) ;
}
- uargv[l++] = S6RC_BINPREFIX "s6-rc-update" ;
- if (wgolb & GOLB_BLOCK) uargv[l++] = "-b" ;
- uargv[l++] = "-v" ;
- uargv[l++] = fmtv ;
- uargv[l++] = "-l" ;
- uargv[l++] = wgola[GOLA_LIVEDIR] ;
- if (wgola[GOLA_CONVFILE])
+ if (!(wgolb & GOLB_NOUPDATE))
{
- uargv[l++] = "-f" ;
- uargv[l++] = wgola[GOLA_CONVFILE] ;
- }
- uargv[l++] = "--" ;
- uargv[l++] = dstfn ;
- uargv[l++] = 0 ;
+ uargv[l++] = S6RC_BINPREFIX "s6-rc-update" ;
+ if (wgolb & GOLB_BLOCK) uargv[l++] = "-b" ;
+ uargv[l++] = "-v" ;
+ uargv[l++] = fmtv ;
+ uargv[l++] = "-l" ;
+ uargv[l++] = wgola[GOLA_LIVEDIR] ;
+ if (wgola[GOLA_CONVFILE])
+ {
+ uargv[l++] = "-f" ;
+ uargv[l++] = wgola[GOLA_CONVFILE] ;
+ }
+ uargv[l++] = "--" ;
+ uargv[l++] = dstfn ;
+ uargv[l++] = 0 ;
- pid = cspawn(uargv[0], uargv, (char const *const *)environ, 0, 0, 0) ;
- if (!pid)
- {
- int e = errno ;
- rm_rf(dstfn) ;
- errno = e ;
- strerr_diefu2sys(111, "spawn ", uargv[0]) ;
- }
- r = wait_pid(pid, &wstat) ;
- if (r == -1) strerr_diefu3sys(111, "wait for the ", uargv[0], " process (updating may yet succeed)") ;
- if (WIFSIGNALED(wstat))
- {
- char fmt[INT_FMT] ;
- fmt[int_fmt(fmt, WTERMSIG(wstat))] = 0 ;
- strerr_dief3x(wait_estatus(wstat), uargv[0], " crashed with signal ", fmt) ;
- }
- r = WEXITSTATUS(wstat) ;
- if (r == 111)
- strerr_dief2x(111, uargv[0], " exited 111, unable to know the state of the live db or clean up") ;
- if ((r >= 3 && r <= 10) || r == 100)
- {
- int e = errno ;
- char fmt[INT_FMT] ;
- fmt[int_fmt(fmt, r)] = 0 ;
- rm_rf(dstfn) ;
- errno = e ;
- strerr_dief4x(r, uargv[0], " exited with code ", fmt, " (live database switch was NOT performed)") ;
- }
- if (olddb)
- {
- if (wgolb & GOLB_KEEPOLD)
+ pid = cspawn(uargv[0], uargv, (char const *const *)environ, 0, 0, 0) ;
+ if (!pid)
{
- if (buffer_puts(buffer_1small, olddb) == -1
- || !buffer_putflush(buffer_1small, "\n", 1))
- strerr_diefu2sys(111, "write to stdout", " (live database switch was performed)") ;
+ int e = errno ;
+ rm_rf(dstfn) ;
+ errno = e ;
+ strerr_diefu2sys(111, "spawn ", uargv[0]) ;
+ }
+ r = wait_pid(pid, &wstat) ;
+ if (r == -1) strerr_diefu3sys(111, "wait for the ", uargv[0], " process (updating may yet succeed)") ;
+ if (WIFSIGNALED(wstat))
+ {
+ char fmt[INT_FMT] ;
+ fmt[int_fmt(fmt, WTERMSIG(wstat))] = 0 ;
+ strerr_dief3x(wait_estatus(wstat), uargv[0], " crashed with signal ", fmt) ;
+ }
+ r = WEXITSTATUS(wstat) ;
+ if (r == 111)
+ strerr_dief2x(111, uargv[0], " exited 111, unable to know the state of the live db or clean up") ;
+ if ((r >= 3 && r <= 10) || r == 100)
+ {
+ int e = errno ;
+ char fmt[INT_FMT] ;
+ fmt[int_fmt(fmt, r)] = 0 ;
+ rm_rf(dstfn) ;
+ errno = e ;
+ strerr_dief4x(r, uargv[0], " exited with code ", fmt, " (live database switch was NOT performed)") ;
+ }
+ if (olddb)
+ {
+ if (wgolb & GOLB_KEEPOLD)
+ {
+ if (buffer_puts(buffer_1small, olddb) == -1
+ || !buffer_putflush(buffer_1small, "\n", 1))
+ strerr_diefu2sys(111, "write to stdout", " (live database switch was performed)") ;
+ }
+ else rm_rf(olddb) ;
+ }
+ if (r)
+ {
+ char fmt[INT_FMT] ;
+ fmt[int_fmt(fmt, r)] = 0 ;
+ strerr_dief4x(r, uargv[0], " exited with code ", fmt, " (live database switch was performed") ;
}
- else rm_rf(olddb) ;
- }
- if (r)
- {
- char fmt[INT_FMT] ;
- fmt[int_fmt(fmt, r)] = 0 ;
- strerr_dief4x(r, uargv[0], " exited with code ", fmt, " (live database switch was performed") ;
}
+
if (!atomic_symlink4(dstfn + sa.len + 1, wgola[GOLA_BOOTDB], 0, 0))
strerr_diefu6sys(111, "symlink ", dstfn + sa.len + 1, " to ", wgola[GOLA_BOOTDB], " (live database switch was performed)", " (update that link manually or next boot might fail)") ;
}