diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libs6rc/s6rc_servicedir_copy_online.c | 60 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-update.c | 16 |
2 files changed, 74 insertions, 2 deletions
diff --git a/src/libs6rc/s6rc_servicedir_copy_online.c b/src/libs6rc/s6rc_servicedir_copy_online.c index 62d7c87..a3fa1f7 100644 --- a/src/libs6rc/s6rc_servicedir_copy_online.c +++ b/src/libs6rc/s6rc_servicedir_copy_online.c @@ -6,12 +6,14 @@ #include <unistd.h> #include <stdio.h> +#include <skalibs/direntry.h> #include <skalibs/djbunix.h> + #include <s6/servicedir.h> #include <s6-rc/s6rc-utils.h> -#include "s6rc-servicedir-internal.h" #include <s6-rc/s6rc-servicedir.h> +#include "s6rc-servicedir-internal.h" int s6rc_servicedir_copy_online (char const *src, char const *dst) { @@ -21,6 +23,8 @@ int s6rc_servicedir_copy_online (char const *src, char const *dst) unsigned int i = 0 ; int wantup = 0 ; int e ; + struct stat st ; + DIR *dir ; char srcfn[srclen + S6_SERVICEDIR_FILE_MAXLEN + 6] ; char dstfn[dstlen + S6_SERVICEDIR_FILE_MAXLEN + 6] ; char oldfn[dstlen + S6_SERVICEDIR_FILE_MAXLEN + 6] ; @@ -63,6 +67,51 @@ int s6rc_servicedir_copy_online (char const *src, char const *dst) } oldfn[dstlen + 4] = 0 ; rm_rf(oldfn) ; + + /* New files copied, now let's update the instances with the new template */ + + memcpy(oldfn + dstlen + 1, "template", 9) ; + if (stat(oldfn, &st) == 0) + { + if (!S_ISDIR(st.st_mode)) { errno = EINVAL ; goto erri ; } + memcpy(dstfn + dstlen + 1, "instances", 10) ; + dir = opendir(dstfn) ; + if (!dir) + { + mode_t m ; + if (errno != ENOENT) goto erri ; + m = umask(0) ; + if (mkdir(dstfn, 0755) == -1) { umask(m) ; goto erri ; } + dstfn[dstlen + 9] = 0 ; + if (mkdir(dstfn, 0755) == -1) { umask(m) ; goto erri ; } + umask(m) ; + } + else + { + dstfn[dstlen + 10] = '/' ; + for (;;) + { + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') + if (((d->d_name[1] == '.') && !d->d_name[2]) || !d->d_name[1]) + continue ; + { + size_t len = strlen(d->d_name) ; + char ifn[dstlen + 12 + len] ; + memcpy(ifn, dstfn, dstlen + 11) ; + memcpy(ifn + dstlen + 11, d->d_name, len + 1) ; + if (!s6rc_servicedir_copy_online(oldfn, ifn)) goto errd ; + } + } + dir_close(dir) ; + if (errno) goto erri ; + } + } + else if (errno != ENOENT) goto erri ; + s6rc_servicedir_unblock(dst, wantup) ; return 1 ; @@ -80,9 +129,18 @@ int s6rc_servicedir_copy_online (char const *src, char const *dst) strcpy(oldfn + dstlen + 5, s6rc_servicedir_file_list[i].name) ; rename(oldfn, dstfn) ; } + s6rc_servicedir_unblock(dst, wantup) ; errdir: oldfn[dstlen + 4] = 0 ; rmdir(oldfn) ; errno = e ; return 0 ; + + errd: + dir_close(dir) ; + erri: + e = errno ; + s6rc_servicedir_unblock(dst, wantup) ; + errno = e ; + return 0 ; } diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c index ced42d0..617cdfb 100644 --- a/src/s6-rc/s6-rc-update.c +++ b/src/s6-rc/s6-rc-update.c @@ -28,6 +28,7 @@ #include <s6/config.h> #include <s6/supervise.h> +#include <s6/servicedir.h> #include <s6/fdholder.h> #include <s6-rc/config.h> @@ -355,7 +356,20 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co if (rename(oldfn, sa->s + pos) < 0) goto rollback ; if (!s6rc_servicedir_copy_online(newfn, sa->s + pos)) { i++ ; goto rollback ; } } - else if (!s6rc_servicedir_copy_offline(newfn, sa->s + pos)) goto rollback ; + else + { + if (!s6rc_servicedir_copy_offline(newfn, sa->s + pos)) goto rollback ; + if (invimage[i] < olddb->nlong) + { + char const *oldname = newstate[i] & 8 ? olddb->string + olddb->services[invimage[i]].name : newdb->string + newdb->services[i].name ; + size_t oldnamelen = strlen(oldname) ; + char oldfn[livelen + 14 + oldnamelen] ; + memcpy(oldfn, live, livelen) ; + memcpy(oldfn + livelen, "/servicedirs/", 13) ; + memcpy(oldfn + livelen + 13, oldname, oldnamelen + 1) ; + if (s6_servicedir_instances_recreate_offline(oldfn, sa->s + pos) == -1) goto rollback ; + } + } } sa->len = newlen ; sa->s[sa->len] = 0 ; |