diff options
Diffstat (limited to 'src/s6-rc/s6-rc-update.c')
-rw-r--r-- | src/s6-rc/s6-rc-update.c | 82 |
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") ; |