summaryrefslogtreecommitdiff
path: root/src/s6-rc/s6-rc-update.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/s6-rc/s6-rc-update.c')
-rw-r--r--src/s6-rc/s6-rc-update.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c
index 5dfd0d7..d9dce7c 100644
--- a/src/s6-rc/s6-rc-update.c
+++ b/src/s6-rc/s6-rc-update.c
@@ -31,7 +31,7 @@
#define USAGE "s6-rc-update [ -n ] [ -v verbosity ] [ -t timeout ] [ -l live ] [ -f conversion_file ] [ -b ] newdb"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "build string") ;
-#define SUFFIX ":update:XXXXXX"
+#define NEWSUFFIX ":update:XXXXXX"
static char const *live = S6RC_LIVE_BASE ;
static size_t livelen = sizeof(S6RC_LIVE_BASE) - 1 ;
@@ -222,7 +222,6 @@ static inline void stuff_with_newc (int fdnewc, char const *newfn, unsigned char
static void compute_transitions (char const *convfile, unsigned char *oldstate, int fdoldc, s6rc_db_t const *olddb, unsigned char *newstate, unsigned int *invimage, int fdnewc, char const *newfn, s6rc_db_t const *newdb, stralloc *sa)
{
- size_t sabase = sa->len ;
unsigned int oldn = olddb->nshort + olddb->nlong ;
unsigned int newn = newdb->nshort + newdb->nlong ;
unsigned int newm = bitarray_div8(newn) ;
@@ -230,8 +229,8 @@ static void compute_transitions (char const *convfile, unsigned char *oldstate,
unsigned char conversion_table[oldn * newm] ;
memset(conversion_table, 0, oldn * newm) ;
stuff_with_oldc(oldstate, fdoldc, olddb, convfile, oldindex, sa) ;
- stuff_with_newc(fdnewc, newfn, conversion_table, oldstate, newstate, sa->s + sabase, oldindex, invimage, olddb, newdb) ;
- sa->len = sabase ;
+ stuff_with_newc(fdnewc, newfn, conversion_table, oldstate, newstate, sa->s, oldindex, invimage, olddb, newdb) ;
+ sa->len = 0 ;
for (;;)
{
@@ -324,10 +323,9 @@ static inline void rollback_servicedirs (char const *newlive, unsigned char cons
}
}
-static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t const *olddb, unsigned char const *newstate, s6rc_db_t const *newdb, char const *newcompiled, unsigned int *invimage, stralloc *sa)
+static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t const *olddb, unsigned char const *newstate, s6rc_db_t const *newdb, char const *newcompiled, unsigned int *invimage, char const *suffix, size_t suffixlen, stralloc *sa)
{
size_t tmpbase = satmp.len ;
- size_t sabase = sa->len ;
size_t newclen = strlen(newcompiled) ;
size_t dirlen, llen, newlen, sdlen ;
int e = 0 ;
@@ -335,34 +333,37 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co
if (sareadlink(&satmp, live) < 0) strerr_diefu2sys(111, "readlink ", live) ;
if (!s6rc_sanitize_dir(sa, live, &dirlen)) dienomem() ;
llen = sa->len ;
- if (!stralloc_catb(sa, SUFFIX, sizeof(SUFFIX))) dienomem() ;
+ if (!stralloc_catb(sa, NEWSUFFIX, sizeof(NEWSUFFIX))) dienomem() ;
newlen = --sa->len ;
- if (!mkdtemp(sa->s + sabase)) strerr_diefu2sys(111, "mkdtemp ", sa->s + sabase) ;
- if (chmod(sa->s + sabase, 0755) < 0) { e = errno ; goto err ; }
+ if (!mkdtemp(sa->s)) strerr_diefu2sys(111, "mkdtemp ", sa->s) ;
+ if (chmod(sa->s, 0755) < 0) { e = errno ; goto err ; }
{
size_t tmplen = satmp.len ;
- char fn[llen - sabase + 9] ;
+ char fn[llen + 9] ;
if (!stralloc_cats(sa, "/scandir") || !stralloc_0(sa)) { e = errno ; goto err ; }
- memcpy(fn, sa->s + sabase, llen - sabase) ;
- memcpy(fn + llen - sabase, "/scandir", 9) ;
+ memcpy(fn, sa->s, llen) ;
+ memcpy(fn + llen, "/scandir", 9) ;
if (sareadlink(&satmp, fn) < 0 || !stralloc_0(&satmp)) { e = errno ; goto err ; }
- if (symlink(satmp.s + tmplen, sa->s + sabase) < 0) { e = errno ; goto err ; }
+ if (symlink(satmp.s + tmplen, sa->s) < 0) { e = errno ; goto err ; }
satmp.len = tmplen ;
- sa->len = newlen ;
}
- if (!stralloc_cats(sa, "/state") || !stralloc_0(sa)) { e = errno ; goto err ; }
+ sa->len = newlen ;
+ if (!stralloc_catb(sa, "/suffix", 8)) { e = errno ; goto err ; }
+ if (!openwritenclose_unsafe(sa->s, suffix, suffixlen)) { e = errno ; goto err ; }
+ sa->len = newlen ;
+ if (!stralloc_catb(sa, "/state", 7)) { e = errno ; goto err ; }
{
char tmpstate[newdb->nlong + newdb->nshort] ;
unsigned int i = newdb->nlong + newdb->nshort ;
while (i--) tmpstate[i] = newstate[i] & 1 ;
- if (!openwritenclose_unsafe(sa->s + sabase, tmpstate, newdb->nlong + newdb->nshort)) { e = errno ; goto err ; }
+ if (!openwritenclose_unsafe(sa->s, tmpstate, newdb->nlong + newdb->nshort)) { e = errno ; goto err ; }
}
sa->len = newlen ;
- if (!stralloc_cats(sa, "/compiled") || !stralloc_0(sa)) { e = errno ; goto err ; }
- if (symlink(newcompiled, sa->s + sabase) < 0) goto err ;
+ if (!stralloc_catb(sa, "/compiled", 10)) { e = errno ; goto err ; }
+ if (symlink(newcompiled, sa->s) < 0) goto err ;
sa->len = newlen ;
- if (!stralloc_cats(sa, "/servicedirs") || !stralloc_0(sa)) { e = errno ; goto err ; }
- if (mkdir(sa->s + sabase, 0755) < 0) { e = errno ; goto err ; }
+ if (!stralloc_catb(sa, "/servicedirs", 13)) { e = errno ; goto err ; }
+ if (mkdir(sa->s, 0755) < 0) { e = errno ; goto err ; }
sdlen = sa->len ;
sa->s[sdlen - 1] = '/' ;
@@ -384,18 +385,18 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co
memcpy(oldfn, live, livelen) ;
memcpy(oldfn + livelen, "/servicedirs/", 13) ;
memcpy(oldfn + livelen + 13, oldname, oldnamelen + 1) ;
- if (rename(oldfn, sa->s + sabase) < 0) goto rollback ;
- if (!s6rc_servicedir_copy_online(newfn, sa->s + sabase)) { i++ ; e = errno ; goto rollback ; }
+ if (rename(oldfn, sa->s) < 0) goto rollback ;
+ if (!s6rc_servicedir_copy_online(newfn, sa->s)) { i++ ; e = errno ; goto rollback ; }
}
- else if (!s6rc_servicedir_copy_offline(newfn, sa->s + sabase)) { e = errno ; goto rollback ; }
+ else if (!s6rc_servicedir_copy_offline(newfn, sa->s)) { e = errno ; goto rollback ; }
}
sa->len = newlen ;
sa->s[sa->len++] = 0 ;
{
- char tmpfn[llen + 5 - sabase] ;
- memcpy(tmpfn, sa->s + sabase, llen - sabase) ;
- memcpy(tmpfn + llen - sabase, ".new", 5) ;
+ char tmpfn[llen + 5] ;
+ memcpy(tmpfn, sa->s, llen) ;
+ memcpy(tmpfn + llen, ".new", 5) ;
if (unlink(tmpfn) < 0 && errno != ENOENT) { e = errno ; goto rollback ; }
if (symlink(sa->s + dirlen, tmpfn) < 0) { e = errno ; goto rollback ; }
@@ -417,21 +418,21 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co
dienomem() ;
i = olddb->nlong ;
while (i--)
- s6rc_servicedir_unsupervise(sa->s + sabase, olddb->string + olddb->services[i].name, (oldstate[i] & 33) == 1) ;
- rm_rf(sa->s + sabase) ;
+ s6rc_servicedir_unsupervise(sa->s, suffix, olddb->string + olddb->services[i].name, (oldstate[i] & 33) == 1) ;
+ rm_rf(sa->s) ;
- sa->len = sabase ;
+ sa->len = 0 ;
satmp.len = tmpbase ;
return ;
rollback:
sa->len = newlen ;
sa->s[sa->len++] = 0 ;
- rollback_servicedirs(sa->s + sabase, newstate, invimage, olddb, newdb, i) ;
+ rollback_servicedirs(sa->s, newstate, invimage, olddb, newdb, i) ;
err:
sa->len = newlen ;
sa->s[sa->len++] = 0 ;
- rm_rf(sa->s + sabase) ;
+ rm_rf(sa->s) ;
errno = e ;
strerr_diefu2sys(111, "make new live directory in ", sa->s) ;
}
@@ -650,6 +651,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
int fdoldc, fdnewc ;
s6rc_db_t olddb, newdb ;
unsigned int oldn, newn ;
+ size_t suffixlen = 0 ;
char dbfn[livelen + 10] ;
tain_now_g() ;
@@ -666,8 +668,10 @@ int main (int argc, char const *const *argv, char const *const *envp)
strerr_diefu2sys(111, "take lock on ", argv[0]) ;
- /* Read the sizes of the compiled dbs */
+ /* Read the sizes of the suffix and compiled dbs */
+ if (!s6rc_livedir_suffixsize(live, &suffixlen))
+ strerr_diefu2sys(111, "read suffix size for ", live) ;
fdoldc = open_readb(dbfn) ;
if (!s6rc_db_read_sizes(fdoldc, &olddb))
strerr_diefu3sys(111, "read ", dbfn, "/n") ;
@@ -694,6 +698,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
char newstringblob[newdb.stringlen] ;
unsigned char oldstate[oldn] ;
unsigned char newstate[newn] ;
+ char suffix[suffixlen + 1] ;
int r ;
olddb.services = oldserviceblob ;
@@ -706,6 +711,15 @@ int main (int argc, char const *const *argv, char const *const *envp)
newdb.string = newstringblob ;
+ /* Read the suffix */
+
+ {
+ ssize_t rr = s6rc_livedir_suffix(live, suffix, suffixlen) ;
+ if (rr != suffixlen) strerr_diefu2sys(111, "read suffix for ", live) ;
+ suffix[suffixlen] = 0 ;
+ }
+
+
/* Read the dbs */
r = s6rc_db_read(fdoldc, &olddb) ;
@@ -791,8 +805,8 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (verbosity >= 2)
strerr_warni1x("updating state and service directories") ;
- make_new_livedir(oldstate, &olddb, newstate, &newdb, argv[0], invimage, &sa) ;
- r = s6rc_servicedir_manage_g(live, &deadline) ;
+ make_new_livedir(oldstate, &olddb, newstate, &newdb, argv[0], invimage, suffix, suffixlen, &sa) ;
+ r = s6rc_servicedir_manage_g(live, suffix, &deadline) ;
if (!r) strerr_diefu2sys(111, "manage new service directories in ", live) ;
if (r & 2) strerr_warnw3x("s6-svscan not running on ", live, "/scandir") ;