aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-10-18 00:30:27 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-10-18 00:30:27 +0000
commitebf148d99e2dab6135794149553c193abe4e675d (patch)
treeea288fb1bafff4f05ac59170f77c75ac5f3a3d6e
parent6ada80ed7e45ed630e4d9877a9b11e2dfddb4758 (diff)
downloads6-rc-ebf148d99e2dab6135794149553c193abe4e675d.tar.gz
Part four: we delete all the snapshots after set-install
Except the snapshot corresponding to the new live db, of course. Also, in order to accommodate snapshots without risking name conflicts, the real name of set foobar isn't .foobar:XXXXXX anymore, but .real.foobar:XXXXXX Now the automatic upgrade in case of major bump is complete. Next comes testing and debugging.
-rw-r--r--src/repo/s6-rc-set-install.c28
-rw-r--r--src/repo/s6-rc-set-new.c39
-rw-r--r--src/repo/s6rc_repo_moveservices.c10
-rw-r--r--src/repo/s6rc_repo_setcopy.c16
-rw-r--r--src/repo/s6rc_repo_setdelete.c8
5 files changed, 64 insertions, 37 deletions
diff --git a/src/repo/s6-rc-set-install.c b/src/repo/s6-rc-set-install.c
index 3940aba..8a07446 100644
--- a/src/repo/s6-rc-set-install.c
+++ b/src/repo/s6-rc-set-install.c
@@ -4,11 +4,11 @@
#include <skalibs/nonposix.h>
#include <skalibs/stat.h>
+#include <sys/wait.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
-#include <sys/wait.h>
#include <errno.h>
#include <skalibs/uint64.h>
@@ -19,6 +19,7 @@
#include <skalibs/strerr.h>
#include <skalibs/gol.h>
#include <skalibs/stralloc.h>
+#include <skalibs/direntry.h>
#include <skalibs/djbunix.h>
#include <skalibs/tai.h>
#include <skalibs/cspawn.h>
@@ -51,6 +52,29 @@ enum gola_e
#define DSTFNLEN(bootdir, set) (strlen(bootdir) + strlen(set) + 36)
+static void remove_snapshots_except (char const *repo, char const *snap)
+{
+ DIR *dir ;
+ size_t repolen = strlen(repo) ;
+ char src[repolen + 9] ;
+ memcpy(src, repo, repolen) ;
+ memcpy(src + repolen, "/sources", 9) ;
+ dir = opendir(src) ;
+ if (!dir) strerr_diefusys(111, "opendir ", src) ;
+ for (;;)
+ {
+ direntry *d ;
+ errno = 0 ;
+ d = readdir(dir) ;
+ if (!d) break ;
+ if (strncmp(d->d_name, ".snapshot.", 10)) continue ;
+ if (!strcmp(d->d_name, snap)) continue ;
+ s6rc_repo_setdelete(repo, d->d_name) ;
+ }
+ if (errno) strerr_diefusys(111, "readdir ", src) ;
+ dir_close(dir) ;
+}
+
static int install_needs_upgrade (char const *livedir)
{
size_t llen = strlen(livedir) ;
@@ -373,6 +397,8 @@ int main (int argc, char const *const *argv)
}
else rm_rf(olddbsa.s) ;
}
+
+ remove_snapshots_except(wgola[GOLA_REPODIR], dstfn + bootdirsa.len + 1) ;
}
_exit(0) ;
}
diff --git a/src/repo/s6-rc-set-new.c b/src/repo/s6-rc-set-new.c
index 6b20e9b..617344e 100644
--- a/src/repo/s6-rc-set-new.c
+++ b/src/repo/s6-rc-set-new.c
@@ -38,33 +38,33 @@ static inline void newset (char const *repo, char const *setname)
mode_t m ;
char atomics[repolen + 18] ;
char fn[repolen + 10 + setlen] ;
- char tmp[repolen + 18 + setlen] ;
- char rx[repolen + 25 + setlen] ;
+ char tmp[repolen + 22 + setlen] ;
+ char rx[repolen + 29 + setlen] ;
memcpy(atomics, repo, repolen) ;
memcpy(atomics + repolen, "/sources/.atomics", 18) ;
memcpy(fn, atomics, repolen + 9) ;
memcpy(fn + repolen + 9, setname, setlen + 1) ;
if (access(fn, F_OK) == -1)
{
- if (errno != ENOENT) strerr_diefu2sys(111, "access ", fn) ;
+ if (errno != ENOENT) strerr_diefusys(111, "access ", fn) ;
}
- else strerr_dief4x(100, "set ", setname, " already exists in repository ", repo) ;
+ else strerr_dief(100, "set ", setname, " already exists in repository ", repo) ;
memcpy(tmp, fn, repolen + 9) ;
- tmp[repolen + 9] = '.' ;
- memcpy(tmp + repolen + 10, setname, setlen) ;
- memcpy(tmp + repolen + 10 + setlen, ":XXXXXX", 8) ;
+ memcpy(tmp + repolen + 9, ".real.", 5) ;
+ memcpy(tmp + repolen + 14, setname, setlen) ;
+ memcpy(tmp + repolen + 14 + setlen, ":XXXXXX", 8) ;
m = umask(0) ;
- if (!mkdtemp(tmp)) strerr_diefu2sys(111, "mkdtemp ", tmp) ;
- memcpy(rx, tmp, repolen + 17 + setlen) ;
- rx[repolen + 17 + setlen] = '/' ;
+ if (!mkdtemp(tmp)) strerr_diefusys(111, "mkdtemp ", tmp) ;
+ memcpy(rx, tmp, repolen + 21 + setlen) ;
+ rx[repolen + 21 + setlen] = '/' ;
for (size_t i = 0 ; i < 4 ; i++)
{
- memcpy(rx + repolen + 18 + setlen, s6rc_repo_rxnames[i], 7) ;
+ memcpy(rx + repolen + 22 + setlen, s6rc_repo_rxnames[i], 7) ;
if (mkdir(rx, 02755) == -1)
{
umask(m) ;
cleanup(tmp) ;
- strerr_diefu2sys(111, "mkdir ", rx) ;
+ strerr_diefusys(111, "mkdir ", rx) ;
}
}
umask(m) ;
@@ -78,12 +78,12 @@ static inline void newset (char const *repo, char const *setname)
if (chmod(tmp, 02755) == -1)
{
cleanup(tmp) ;
- strerr_diefu2sys(111, "chmod ", tmp) ;
+ strerr_diefusys(111, "chmod ", tmp) ;
}
if (symlink(tmp + repolen + 9, fn) == -1)
{
cleanup(tmp) ;
- strerr_diefu4sys(111, "symlink ", tmp, " to ", fn) ;
+ strerr_diefusys(111, "symlink ", tmp, " to ", fn) ;
}
}
@@ -105,21 +105,22 @@ int main (int argc, char const *const *argv)
int fdlock ;
unsigned int verbosity = 1 ;
char const *wgola[GOLA_N] = { 0 } ;
- unsigned int golc ;
PROG = "s6-rc-set-new" ;
wgola[GOLA_REPODIR] = S6RC_REPODIR ;
- golc = gol_main(argc, argv, 0, 0, rgola, 2, 0, wgola) ;
- argc -= golc ; argv += golc ;
+ {
+ unsigned int golc = gol_main(argc, argv, 0, 0, rgola, 2, 0, wgola) ;
+ argc -= golc ; argv += golc ;
+ }
if (wgola[GOLA_VERBOSITY] && !uint0_scan(wgola[GOLA_VERBOSITY], &verbosity))
- strerr_dief1x(100, "verbosity needs to be an unsigned integer") ;
+ strerr_dief(100, "verbosity needs to be an unsigned integer") ;
if (!argc) dieusage() ;
for (unsigned int i = 0 ; i < argc ; i++) s6rc_repo_sanitize_setname(argv[i]) ;
tain_now_g() ;
fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ;
- if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ;
+ if (fdlock == -1) strerr_diefusys(111, "lock ", wgola[GOLA_REPODIR]) ;
for (unsigned int i = 0 ; i < argc ; i++)
newset(wgola[GOLA_REPODIR], argv[i]) ;
diff --git a/src/repo/s6rc_repo_moveservices.c b/src/repo/s6rc_repo_moveservices.c
index 5d0b5d1..88e1fb2 100644
--- a/src/repo/s6rc_repo_moveservices.c
+++ b/src/repo/s6rc_repo_moveservices.c
@@ -40,27 +40,27 @@ int s6rc_repo_moveservices (char const *repo, char const *set, s6rc_repo_sv cons
if (access(newfn, F_OK) == 0)
{
if (verbosity >= 2)
- strerr_warni8x("service ", storage + services[i].pos, " already existed in rxset ", s6rc_repo_rxnames[newrx], " of set ", set, " in repository ", repo) ;
+ strerr_warni("service ", storage + services[i].pos, " already existed in rxset ", s6rc_repo_rxnames[newrx], " of set ", set, " in repository ", repo) ;
}
else if (errno != ENOENT)
{
- strerr_warnfu2sys("access ", newfn) ;
+ strerr_warnfusys("access ", newfn) ;
return 0 ;
}
if (rename(oldfn, newfn) == -1)
{
- strerr_warnfu4sys("rename ", oldfn, " to ", newfn) ;
+ strerr_warnfusys("rename ", oldfn, " to ", newfn) ;
return 0 ;
}
if (verbosity >= 4)
{
- strerr_warnt10x("repository ", repo, ", set ", set, ", from rxset ", s6rc_repo_rxnames[services[i].rx], " to rxset ", s6rc_repo_rxnames[newrx], ": successfully moved service ", storage + services[i].pos) ;
+ strerr_warnt("repository ", repo, ", set ", set, ", from rxset ", s6rc_repo_rxnames[services[i].rx], " to rxset ", s6rc_repo_rxnames[newrx], ": successfully moved service ", storage + services[i].pos) ;
}
}
if (n)
{
memcpy(oldfn + repolen + 10 + setlen, ".stamp", 7) ;
- if (!touch(oldfn)) strerr_warnwu2sys("touch ", oldfn) ;
+ if (!touch(oldfn)) strerr_warnwusys("touch ", oldfn) ;
}
return 1 ;
}
diff --git a/src/repo/s6rc_repo_setcopy.c b/src/repo/s6rc_repo_setcopy.c
index 30cb042..1a964a9 100644
--- a/src/repo/s6rc_repo_setcopy.c
+++ b/src/repo/s6rc_repo_setcopy.c
@@ -25,9 +25,9 @@ int s6rc_repo_setcopy (char const *repo, char const *srcname, char const *dstnam
size_t r ;
char src[repolen + srclen + 10] ;
char dst[repolen + dstlen + 10] ;
- char realsrc[repolen + srclen + 18] ;
- char realdst[repolen + dstlen + 18] ;
- char olddst[repolen + dstlen + 18] ;
+ char realsrc[repolen + srclen + 22] ;
+ char realdst[repolen + dstlen + 22] ;
+ char olddst[repolen + dstlen + 22] ;
memcpy(src, repo, repolen) ;
memcpy(src + repolen, "/sources/", 9) ;
memcpy(src + repolen + 9, srcname, srclen + 1) ;
@@ -44,12 +44,12 @@ int s6rc_repo_setcopy (char const *repo, char const *srcname, char const *dstnam
memcpy(realsrc, src, repolen + 9) ;
r = readlink(src, realsrc + repolen + 9, srclen + 9) ;
if (r == -1) return errno ;
- if (r != srclen + 8) return -2 ;
- realsrc[repolen + srclen + 17] = 0 ;
+ if (r != srclen + 12) return -2 ;
+ realsrc[repolen + srclen + 21] = 0 ;
memcpy(realdst, dst, repolen + 9) ;
- realdst[repolen + 9] = '.' ;
- memcpy(realdst + repolen + 10, dstname, dstlen) ;
- memcpy(realdst + repolen + 10 + dstlen, ":XXXXXX", 8) ;
+ memcpy(realdst + repolen + 9, ".real.", 5) ;
+ memcpy(realdst + repolen + 14, dstname, dstlen) ;
+ memcpy(realdst + repolen + 14 + dstlen, ":XXXXXX", 8) ;
if (mkntemp(realdst) == -1) return errno ;
if (!hiercopy(realsrc, realdst))
{
diff --git a/src/repo/s6rc_repo_setdelete.c b/src/repo/s6rc_repo_setdelete.c
index a372d93..605533e 100644
--- a/src/repo/s6rc_repo_setdelete.c
+++ b/src/repo/s6rc_repo_setdelete.c
@@ -14,7 +14,7 @@ void s6rc_repo_setdelete (char const *repo, char const *set)
size_t repolen = strlen(repo) ;
size_t setlen = strlen(set) ;
ssize_t r ;
- char real[repolen + setlen + 18] ;
+ char real[repolen + setlen + 22] ;
char fn[repolen + setlen + 11] ;
memcpy(fn, repo, repolen) ;
memcpy(fn + repolen, "/sources/", 9) ;
@@ -22,9 +22,9 @@ void s6rc_repo_setdelete (char const *repo, char const *set)
if (access(fn, W_OK) == -1 && errno != ENOENT) return ;
memcpy(real, repo, repolen) ;
memcpy(real + repolen, "/sources/", 9) ;
- r = readlink(fn, real + repolen + 9, setlen + 9) ;
- if (r == -1 || r != setlen + 8) return ;
- real[repolen + setlen + 17] = 0 ;
+ r = readlink(fn, real + repolen + 9, setlen + 13) ;
+ if (r == -1 || r != setlen + 12) return ;
+ real[repolen + setlen + 21] = 0 ;
unlink_void(fn) ;
rm_rf(real) ;
}