diff --git a/src/include/66/sanitize.h b/src/include/66/sanitize.h index a166e8f22ca61d8262b9766c085552b13359c237..c1dcf0ece019335f3f2d9d549ca203267b6946c1 100644 --- a/src/include/66/sanitize.h +++ b/src/include/66/sanitize.h @@ -19,13 +19,14 @@ #include <66/service.h> #include <66/ssexec.h> +#include <66/state.h> extern int sanitize_system(ssexec_t *info) ; extern void sanitize_source(char const *name, ssexec_t *info) ; -extern void sanitize_fdholder(resolve_service_t *res, uint32_t flag) ; -extern void sanitize_livestate(resolve_service_t *res) ; -extern void sanitize_scandir(resolve_service_t *res) ; +extern int sanitize_fdholder(resolve_service_t *res, ss_state_t *sta, uint32_t flag) ; +extern int sanitize_livestate(resolve_service_t *res, ss_state_t *sta) ; +extern int sanitize_scandir(resolve_service_t *res, ss_state_t *sta) ; extern void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen) ; extern void sanitize_graph(ssexec_t *info) ; /** @Return 0 the service is already written diff --git a/src/lib66/sanitize/sanitize_fdholder.c b/src/lib66/sanitize/sanitize_fdholder.c index faa053b2ac91dcc206ae003a75089ce91ee7769d..bea1918b3fb689491b1cb3a5da2828d9a67dbe6b 100644 --- a/src/lib66/sanitize/sanitize_fdholder.c +++ b/src/lib66/sanitize/sanitize_fdholder.c @@ -33,14 +33,16 @@ #include <s6/fdholder.h> -void fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *limit) +static int fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *limit) { + log_flow() ; + size_t namelen = strlen(name) ; char fdname[SS_FDHOLDER_PIPENAME_LEN + 2 + namelen + 1] ; int fd[2] ; if (pipe(fd) < 0) - log_dieu(LOG_EXIT_SYS, "pipe") ; + log_warnu_return(LOG_EXIT_ZERO, "pipe") ; auto_strings(fdname, SS_FDHOLDER_PIPENAME, "r-", name) ; @@ -48,7 +50,7 @@ void fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *li if (!s6_fdholder_store_g(a, fd[0], fdname, limit, deadline)) { close(fd[0]) ; close(fd[1]) ; - log_dieusys(LOG_EXIT_SYS, "store fd: ", fdname) ; + log_warnusys_return(LOG_EXIT_ZERO, "store fd: ", fdname) ; } close(fd[0]) ; @@ -58,14 +60,18 @@ void fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *li log_trace("store identifier: ", fdname) ; if (!s6_fdholder_store_g(a, fd[1], fdname, limit, deadline)) { close(fd[1]) ; - log_dieusys(LOG_EXIT_SYS, "store fd: ", fdname) ; + log_warnusys_return(LOG_EXIT_ZERO, "store fd: ", fdname) ; } close(fd[1]) ; + + return 1 ; } -void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline) +static int fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline) { + log_flow() ; + size_t namelen = strlen(name) ; char fdname[SS_FDHOLDER_PIPENAME_LEN + 2 + namelen + 1] ; @@ -74,7 +80,7 @@ void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline) if (s6_fdholder_retrieve_g(a, fdname, deadline) >= 0) { log_trace("delete identifier: ", fdname) ; if (!s6_fdholder_delete_g(a, fdname, deadline)) - log_dieusys(LOG_EXIT_SYS, "delete fd: ", fdname) ; + log_warnusys_return(LOG_EXIT_ZERO, "delete fd: ", fdname) ; } fdname[strlen(SS_FDHOLDER_PIPENAME)] = 'w' ; @@ -83,8 +89,9 @@ void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline) log_trace("delete identifier: ", fdname) ; if (!s6_fdholder_delete_g(a, fdname, deadline)) - log_dieusys(LOG_EXIT_SYS, "delete fd: ", fdname) ; + log_warnusys_return(LOG_EXIT_ZERO, "delete fd: ", fdname) ; } + return 1 ; } /** * Accepted flag are @@ -93,7 +100,7 @@ void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline) * * */ -void sanitize_fdholder(resolve_service_t *res, uint32_t flag) +int sanitize_fdholder(resolve_service_t *res, ss_state_t *sta, uint32_t flag) { log_flow() ; @@ -104,22 +111,18 @@ void sanitize_fdholder(resolve_service_t *res, uint32_t flag) char *name = sa + res->logger.name ; char *socket = sa + res->live.fdholderdir ; size_t socketlen = strlen(socket) ; - ss_state_t sta = STATE_ZERO ; s6_fdholder_t a = S6_FDHOLDER_ZERO ; tain deadline = tain_infinite_relative, limit = tain_infinite_relative ; char sock[socketlen + 3] ; auto_strings(sock, socket, "/s") ; - if (!state_read(&sta, res)) - log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ; - tain_now_set_stopwatch_g() ; tain_add_g(&deadline, &deadline) ; tain_add_g(&limit, &limit) ; if (!s6_fdholder_start_g(&a, sock, &deadline)) - log_dieusys(LOG_EXIT_SYS, "connect to socket: ", sock) ; + log_warnusys_return(LOG_EXIT_ZERO, "connect to socket: ", sock) ; if (FLAGS_ISSET(flag, STATE_FLAGS_TRUE)) { @@ -128,21 +131,24 @@ void sanitize_fdholder(resolve_service_t *res, uint32_t flag) sta->torestart == STATE_FLAGS_TRUE) { log_trace("delete fdholder entry: ", name) ; - fdholder_delete(&a, name, &deadline) ; + if (!fdholder_delete(&a, name, &deadline)) + return 0 ; } log_trace("store fdholder entry: ", name) ; - fdholder_store(&a, name, &deadline, &limit) ; + if (!fdholder_store(&a, name, &deadline, &limit)) + return 0 ; } else if (FLAGS_ISSET(flag, STATE_FLAGS_FALSE)) { log_trace("delete fdholder entry: ", name) ; - fdholder_delete(&a, name, &deadline) ; + if (!fdholder_delete(&a, name, &deadline)) + return 0 ; } if (s6_fdholder_list_g(&a, &list, &deadline) < 0) - log_dieusys(LOG_EXIT_SYS, "list identifier") ; + log_warnusys_return(LOG_EXIT_ZERO, "list identifier") ; s6_fdholder_end(&a) ; @@ -168,10 +174,12 @@ void sanitize_fdholder(resolve_service_t *res, uint32_t flag) auto_strings(file, socket, "/data/autofilled") ; if (!openwritenclose_unsafe(file, list.s, list.len)) - log_dieusys(LOG_EXIT_SYS, "write file: ", file) ; + log_warnusys_return(LOG_EXIT_ZERO, "write file: ", file) ; svc_send_fdholder(socket, "twR") ; stralloc_free(&list) ; } + + return 1 ; } diff --git a/src/lib66/sanitize/sanitize_init.c b/src/lib66/sanitize/sanitize_init.c index 5ed2dc036f9a51717b001f1b87d8e406215c3f43..39a10d025ade098046402ced9e313fc61ec766e0 100644 --- a/src/lib66/sanitize/sanitize_init.c +++ b/src/lib66/sanitize/sanitize_init.c @@ -14,12 +14,15 @@ #include <string.h> #include <stdlib.h> +#include <errno.h> +#include <unistd.h>// unlink #include <oblibs/log.h> #include <oblibs/string.h> #include <oblibs/types.h> #include <oblibs/sastr.h> #include <oblibs/environ.h> +#include <oblibs/directory.h> #include <skalibs/types.h> #include <skalibs/genalloc.h> @@ -38,6 +41,36 @@ #include <66/state.h> #include <66/enum.h> #include <66/sanitize.h> +#include <66/symlink.h> + +static unsigned int toclean[SS_MAX_SERVICE + 1] ; + +void cleanup(resolve_service_t *ares, unsigned int areslen) +{ + unsigned int pos = 0 ; + int e = errno ; + ss_state_t sta = STATE_ZERO ; + + for (; pos < areslen ; pos++) { + + if (toclean[pos]) { + + if (!sanitize_fdholder(&ares[pos], &sta, STATE_FLAGS_FALSE)) + log_warnusys("sanitize fdholder directory: ", ares[pos].sa.s + ares[pos].live.fdholderdir); + + log_trace("remove directory: ", ares[pos].sa.s + ares[pos].live.servicedir) ; + if (!dir_rm_rf(ares[pos].sa.s + ares[pos].live.servicedir)) + log_warnusys("remove live directory: ", ares[pos].sa.s + ares[pos].live.servicedir) ; + + log_trace("remove symlink: ", ares[pos].sa.s + ares[pos].live.scandir) ; + unlink(ares[pos].sa.s + ares[pos].live.scandir) ; + + if (!symlink_switch(&ares[pos], SYMLINK_SOURCE)) + log_warnusys("switch service symlink to source for: ", ares[pos].sa.s + ares[pos].name) ; + } + } + errno = e ; +} void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen) { @@ -46,13 +79,14 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s ftrigr_t fifo = FTRIGR_ZERO ; uint32_t earlier ; gid_t gid = getgid() ; - int is_supervised = 0, is_init = 0, gearlier = 0 ; + int is_supervised = 0 ; unsigned int pos = 0, nsv = 0 ; unsigned int real[alen] ; unsigned int msg[areslen] ; ss_state_t sta = STATE_ZERO ; - memset(msg, 0, areslen) ; + memset(msg, 0, areslen * sizeof(unsigned int)) ; + memset(toclean, 0, SS_MAX_SERVICE + 1 * sizeof(unsigned int)) ; /* nothing to do */ if (!alen) @@ -66,20 +100,42 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s if (aresid < 0) log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ; - if (!state_read(&sta, &ares[aresid])) - log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ; - - earlier = sta.isearlier == STATE_FLAGS_TRUE ? 1 : 0 ; - char *sa = ares[aresid].sa.s ; - char *scandir = sa + ares[aresid].live.scandir ; + toclean[pos] = 1 ; + earlier = ares[aresid].earlier ; + char *scandir = ares[aresid].sa.s + ares[aresid].live.scandir ; size_t scandirlen = strlen(scandir) ; - is_init = access(sa + ares[aresid].live.statedir, F_OK) ; - if (is_init < 0 || sta.toinit == STATE_FLAGS_TRUE) - sanitize_livestate(&ares[aresid]) ; + /** try to read the state following the symlink. It may not exist yet, + * for example at boot after a hard shutdown */ + int r = state_read(&sta, &ares[aresid]) ; + + if (!symlink_switch(&ares[aresid], SYMLINK_SOURCE)) + log_dieu(LOG_EXIT_SYS, "switch service symlink to source for: ", name) ; + + if (!r && !state_read(&sta, &ares[aresid])) + log_dieu(LOG_EXIT_SYS, "read state file of: ", name, " -- please make a bug reports") ; + + //r = access(ares[aresid].sa.s + ares[aresid].live.servicedir, F_OK) ; + //if (!r) { + + //if (sta.isup == STATE_FLAGS_TRUE) + // log_die(LOG_EXIT_USER, "service: ", name, " is running and the frontend file has changed. Please use 66 reconfigure ", name, " command instead.") ; + + //log_trace("remove directory: ", ares[aresid].sa.s + ares[aresid].live.servicedir) ; + //if (!dir_rm_rf(ares[aresid].sa.s + ares[aresid].live.servicedir)) + // log_dieusys(LOG_EXIT_SYS, "remove live directory: ", ares[aresid].sa.s + ares[aresid].live.servicedir) ; + //} + + if (!sanitize_livestate(&ares[aresid], &sta)) { + cleanup(ares, areslen) ; + log_dieu(LOG_EXIT_SYS, "sanitize state directory: ", ares[aresid].sa.s + ares[aresid].name) ; + } + + if (!symlink_switch(&ares[aresid], SYMLINK_LIVE)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "switch service symlink to live for: ", name) ; + } - if (earlier) - gearlier = aresid ; /** * Bundle and module type are not a daemons. We don't need to supervise it. * Special case for Oneshot, we only deal with the scandir symlink. */ @@ -96,7 +152,10 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s if (is_supervised == -1) { - sanitize_scandir(&ares[aresid]) ; + if (!sanitize_scandir(&ares[aresid], &sta)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "sanitize_scandir directory: ", ares[aresid].sa.s + ares[aresid].live.scandir) ; + } if (ares[aresid].type == TYPE_ONESHOT) continue ; @@ -109,18 +168,30 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s auto_strings(downfile, scandir, "/down") ; log_trace("create file: ", downfile) ; int fd = open_trunc(downfile) ; - if (fd < 0) + if (fd < 0) { + cleanup(ares, areslen) ; log_dieusys(LOG_EXIT_SYS, "create file: ", downfile) ; + } fd_close(fd) ; } if (!earlier && is_supervised) { - sanitize_fdholder(&ares[aresid], STATE_FLAGS_TRUE) ; + if (!sanitize_fdholder(&ares[aresid], &sta, STATE_FLAGS_TRUE)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "sanitize fdholder directory: ", ares[aresid].sa.s + ares[aresid].live.fdholderdir) ; + } + + log_trace("create fifo: ", ares[aresid].sa.s + ares[aresid].live.eventdir) ; + if (!ftrigw_fifodir_make(ares[aresid].sa.s + ares[aresid].live.eventdir, gid, 0)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "create fifo: ", ares[aresid].sa.s + ares[aresid].live.eventdir) ; + } + } - log_trace("create fifo: ", sa + ares[aresid].live.eventdir) ; - if (!ftrigw_fifodir_make(sa + ares[aresid].live.eventdir, gid, 0)) - log_dieusys(LOG_EXIT_SYS, "create fifo: ", sa + ares[aresid].live.eventdir) ; + if (!state_write(&sta, &ares[aresid])) { + cleanup(ares, areslen) ; + log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ; } real[nsv++] = (unsigned int)aresid ; @@ -132,19 +203,28 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s if (!earlier && nsv) { uint16_t ids[nsv] ; - unsigned int nids = 0 ; - + unsigned int nids = 0, fake = 0 ; tain deadline ; - tain_now_set_stopwatch_g() ; - tain_addsec(&deadline, &STAMP, 2) ; - if (!ftrigr_startf_g(&fifo, &deadline)) + memset(ids, 0, nsv * sizeof(uint16_t)) ; + + tain_now_set_stopwatch_g() ; + /** TODO + * waiting for 3 seconds here, + * it should be the -T option if exist. + */ + tain_addsec(&deadline, &STAMP, 3) ; + + if (!ftrigr_startf_g(&fifo, &deadline)) { + cleanup(ares, areslen) ; log_dieusys(LOG_EXIT_SYS, "ftrigr") ; + } for (pos = 0 ; pos < nsv ; pos++) { if (ares[real[pos]].type == TYPE_CLASSIC) { + fake = pos ; char *sa = ares[real[pos]].sa.s ; char *eventdir = sa + ares[real[pos]].live.eventdir ; @@ -152,26 +232,32 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s /** unsubscribe automatically, options is 0 */ ids[nids] = ftrigr_subscribe_g(&fifo, eventdir, "s", 0, &deadline) ; - if (!ids[nids++]) + if (!ids[nids++]) { + cleanup(ares, areslen) ; log_dieusys(LOG_EXIT_SYS, "subcribe to fifo: ", eventdir) ; - - if (!state_messenger(&ares[real[pos]], STATE_FLAGS_TORELOAD, STATE_FLAGS_TRUE)) - log_dieusys(LOG_EXIT_SYS, "send message to state of: ", sa + ares[real[pos]].name) ; - + } } } if (nids) { - sanitize_scandir(&ares[real[0]]) ; + state_set_flag(&sta, STATE_FLAGS_TORELOAD, STATE_FLAGS_TRUE) ; + + if (!sanitize_scandir(&ares[real[fake]], &sta)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "sanitize scandir directory: ", ares[real[fake]].sa.s + ares[real[fake]].live.scandir) ; + } log_trace("waiting for events on fifo...") ; - if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0) + if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0) { + cleanup(ares, areslen) ; log_dieusys(LOG_EXIT_SYS, "wait for events") ; - + } } } + ftrigr_end(&fifo) ; + /** * We pass through here even for Bundle, Module and Oneshot. * We need to write the state file anyway. Thus can always @@ -179,33 +265,67 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s * */ for (pos = 0 ; pos < alen ; pos++) { + ss_state_t sta = STATE_ZERO ; char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[alist[pos]].vertex ; int aresid = service_resolve_array_search(ares, areslen, name) ; - if (aresid < 0) - log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ; + if (aresid < 0) { + cleanup(ares, areslen) ; + log_dieu(LOG_EXIT_SYS, "find ares id of: ", name, " -- please make a bug reports") ; + } char *sa = ares[aresid].sa.s ; + if (!state_read(&sta, &ares[aresid])) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "read status file of: ", sa + ares[aresid].name) ; + } + if (ares[aresid].type == TYPE_CLASSIC || ares[aresid].type == TYPE_ONESHOT) { log_trace("clean event directory: ", sa + ares[aresid].live.eventdir) ; if (!ftrigw_clean(sa + ares[aresid].live.eventdir)) log_warnu("clean event directory: ", sa + ares[aresid].live.eventdir) ; - } else if (ares[aresid].type == TYPE_BUNDLE || ares[aresid].type == TYPE_MODULE) { + if (ares[aresid].type == TYPE_CLASSIC && ares[aresid].logger.want) { + /** Creation of the logger destination. + * This is made here to avoid issues if the logger destination + * is on tmpfs. + */ + uid_t log_uid ; + gid_t log_gid ; + char *logrunner = ares[aresid].logger.execute.run.runas ? ares[aresid].sa.s + ares[aresid].logger.execute.run.runas : SS_LOGGER_RUNNER ; + + if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ; + } + char *dst = ares[aresid].sa.s + ares[aresid].logger.destination ; + + if (!dir_create_parent(dst, 0755)) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "create directory: ", ares[aresid].sa.s + ares[aresid].logger.destination) ; + } + + if (!ares[aresid].owner && (strcmp(ares[aresid].sa.s + ares[aresid].logger.execute.run.build, "custom"))) { + + if (chown(dst, log_uid, log_gid) == -1) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "chown: ", dst) ; + } + } + } - /** Consider Module and Bundle as supervised */ - if (!state_messenger(&ares[aresid], STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE)) - log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ; } - if (!state_messenger(&ares[aresid], STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE)) - log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ; + /** Consider Module and Bundle as supervised */ + state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE) ; + + if (!state_write(&sta, &ares[aresid])) { + cleanup(ares, areslen) ; + log_dieusys(LOG_EXIT_SYS, "write status file of: ", sa + ares[aresid].name) ; + } if (!msg[aresid]) log_info("Initialized successfully: ", name) ; } - - ftrigr_end(&fifo) ; - } diff --git a/src/lib66/sanitize/sanitize_livestate.c b/src/lib66/sanitize/sanitize_livestate.c index 9e1f56ea41a01a241e265859af03a2f5cc91238f..de22b6b45e720b2381da51a5deba8f442364ce28 100644 --- a/src/lib66/sanitize/sanitize_livestate.c +++ b/src/lib66/sanitize/sanitize_livestate.c @@ -25,6 +25,7 @@ #include <skalibs/unix-transactional.h> #include <skalibs/posixplz.h> +#include <skalibs/djbunix.h> #include <66/constants.h> #include <66/sanitize.h> @@ -33,8 +34,7 @@ #include <66/state.h> /** creation of the /run/66/state/<uid> directory */ - -static void sanitize_livestate_directory(resolve_service_t *res) +static int sanitize_livestate_directory(resolve_service_t *res) { log_flow() ; @@ -48,78 +48,72 @@ static void sanitize_livestate_directory(resolve_service_t *res) r = scan_mode(ste, S_IFDIR) ; if (r < 0) - log_diesys(LOG_EXIT_SYS, "conflicting format for: ", ste) ; + log_warn_return(LOG_EXIT_ZERO, "conflicting format for: ", ste) ; if (!r) { log_trace("create directory: ", ste) ; r = dir_create_parent(ste, 0700) ; if (!r) - log_dieusys(LOG_EXIT_SYS, "create directory: ", ste) ; + log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", ste) ; if (!yourgid(&gidowner, res->owner)) - log_dieusys(LOG_EXIT_SYS, "get gid of: ", res->sa.s + res->ownerstr) ; + log_warnusys_return(LOG_EXIT_ZERO, "get gid of: ", res->sa.s + res->ownerstr) ; if (chown(ste, res->owner, gidowner) < 0) - log_dieusys(LOG_EXIT_SYS, "chown: ", ste) ; + log_warnusys_return(LOG_EXIT_ZERO, "chown: ", ste) ; } -} -/** creation of the /run/66/state/<uid>/<service> symlink */ + return 1 ; +} -static void sanitize_livestate_service_symlink(resolve_service_t *res) +/** copy the source frontend directory to livestate */ +static int sanitize_copy_source(resolve_service_t *res) { - char *name = res->sa.s + res->name ; - size_t namelen = strlen(name) ; - size_t livelen = strlen(res->sa.s + res->live.livedir) ; - size_t ownerlen = strlen(res->sa.s + res->ownerstr) ; - size_t homelen = strlen(res->sa.s + res->path.home) ; - char sym[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ; - char dst[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ; + log_flow() ; + + char *home = res->sa.s + res->path.servicedir ; + char *live = res->sa.s + res->live.servicedir ; + char sym[strlen(live) + SS_RESOLVE_LEN + 1] ; + char dst[strlen(home) + SS_RESOLVE_LEN + 1] ; + + if (!sanitize_livestate_directory(res)) + return 0 ; + + log_trace("copy: ", home, " to: ", live) ; + if (!hiercopy(home, live)) + log_warnusys_return(LOG_EXIT_ZERO, "copy: ", home, " to: ", live) ; - auto_strings(sym, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ; + auto_strings(sym, live, SS_RESOLVE) ; + auto_strings(dst, home, SS_RESOLVE) ; - auto_strings(dst, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ; + log_trace("remove directory: ", sym) ; + if (!dir_rm_rf(sym)) + log_warnusys_return(LOG_EXIT_ZERO, "remove live directory: ", sym) ; log_trace("symlink: ", sym, " to: ", dst) ; if (!atomic_symlink(dst, sym, "livestate")) - log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ; + log_warnusys_return(LOG_EXIT_ZERO, "symlink: ", sym, " to: ", dst) ; + + return 1 ; } -void sanitize_livestate(resolve_service_t *res) +int sanitize_livestate(resolve_service_t *res, ss_state_t *sta) { log_flow() ; int r ; - char *name = res->sa.s + res->name ; - size_t namelen = strlen(name) ; - size_t livelen = strlen(res->sa.s + res->live.livedir) ; - size_t ownerlen = strlen(res->sa.s + res->owner) ; - ss_state_t sta = STATE_ZERO ; - char ste[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ; - - auto_strings(ste, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ; - - if (!state_read(&sta, res)) - log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ; - r = access(ste, F_OK) ; + r = access(res->sa.s + res->live.servicedir, F_OK) ; if (r == -1) { - sanitize_livestate_directory(res) ; - - sanitize_livestate_service_symlink(res) ; - - } else { - - if (sta.tounsupervise == STATE_FLAGS_TRUE) { - - log_trace("unlink: ", ste) ; - unlink_void(ste) ; + if (!sanitize_copy_source(res)) + return 0 ; - state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; + } else if (sta->tounsupervise == STATE_FLAGS_TRUE) { - if (!state_write(&sta, res)) - log_dieusys(LOG_EXIT_SYS, "write status file of: ", name) ; - } + log_trace("remove directory: ", res->sa.s + res->live.servicedir) ; + if (!dir_rm_rf(res->sa.s + res->live.servicedir)) + log_warnusys_return(LOG_EXIT_ZERO, "remove live directory: ", res->sa.s + res->live.servicedir) ; } + return 1 ; } diff --git a/src/lib66/sanitize/sanitize_scandir.c b/src/lib66/sanitize/sanitize_scandir.c index 4b7680e1b68e06eb7b1f5f720c0a71c4e73a0bfd..f6624d50b9eed61b17e0d3d5a44e5cc63753a73f 100644 --- a/src/lib66/sanitize/sanitize_scandir.c +++ b/src/lib66/sanitize/sanitize_scandir.c @@ -15,6 +15,7 @@ #include <string.h> #include <unistd.h> #include <stdint.h> +#include <stdlib.h> #include <sys/stat.h> // umask #include <oblibs/log.h> @@ -34,46 +35,26 @@ static void scandir_scandir_to_livestate(resolve_service_t *res) { + log_flow() ; + char *name = res->sa.s + res->name ; size_t namelen = strlen(name) ; size_t livelen = strlen(res->sa.s + res->live.livedir) ; size_t ownerlen = strlen(res->sa.s + res->ownerstr) ; char sym[livelen + SS_SCANDIR_LEN + 1 + ownerlen + 1 + namelen + 1] ; - char dst[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ; auto_strings(sym, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr, "/", name) ; - auto_strings(dst, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ; - - log_trace("symlink: ", sym, " to: ", dst) ; - if (!atomic_symlink(dst, sym, "scandir")) - log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ; + log_trace("symlink: ", sym, " to: ", res->sa.s + res->live.servicedir) ; + if (!atomic_symlink(res->sa.s + res->live.servicedir, sym, "scandir")) + log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", res->sa.s + res->live.servicedir) ; } -static void scandir_service_to_scandir(resolve_service_t *res) +int scandir_supervision_dir(resolve_service_t *res) { - char *name = res->sa.s + res->name ; - size_t namelen = strlen(name) ; - size_t homelen = strlen(res->sa.s + res->path.home) ; - size_t livelen = strlen(res->sa.s + res->live.livedir) ; - size_t ownerlen = strlen(res->sa.s + res->ownerstr) ; - - char sym[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1 + SS_SCANDIR_LEN + 1] ; - char dst[livelen + SS_SCANDIR_LEN + 1 + ownerlen + 1] ; - - auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE - , SS_SVC, "/", name, "/", SS_SCANDIR) ; - - auto_strings(dst, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr) ; - - log_trace("symlink: ", sym, " to: ", dst) ; - if (!atomic_symlink(dst, sym, "scandir")) - log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ; -} + log_flow() ; -static void compute_supervision_dir(resolve_service_t *res) -{ mode_t hmod = umask(0) ; char *event = res->sa.s + res->live.eventdir ; char *supervise = res->sa.s + res->live.supervisedir ; @@ -82,102 +63,73 @@ static void compute_supervision_dir(resolve_service_t *res) log_trace("create directory: ", event) ; int r = dir_create_parent(event, 0700) ; if (!r) - log_dieusys(LOG_EXIT_SYS, "create directory: ", event) ; - /** - * - * ISSUE: All the following means writting on a possible - * ro mountpoint, so crash occurs. - * - * */ + log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", event) ; if (chown(event, -1, getegid()) < 0) - log_dieusys(LOG_EXIT_SYS, "chown: ", event) ; + log_warnusys_return(LOG_EXIT_ZERO, "chown: ", event) ; if (chmod(event, 03730) < 0) - log_dieusys(LOG_EXIT_SYS, "chmod: ", event) ; + log_warnusys_return(LOG_EXIT_ZERO, "chmod: ", event) ; - /* supervise dir*/ + /* supervise dir */ log_trace("create directory: ", supervise) ; r = dir_create_parent(supervise, 0700) ; if (!r) - log_dieusys(LOG_EXIT_SYS, "create directory: ", event) ; + log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", event) ; umask(hmod) ; + + return 1 ; } -void sanitize_scandir(resolve_service_t *res) +int sanitize_scandir(resolve_service_t *res, ss_state_t *sta) { log_flow() ; int r ; - char *name = res->sa.s + res->name ; - uint8_t earlier = 0 ; - size_t namelen = strlen(name) ; size_t livelen = strlen(res->sa.s + res->live.livedir) ; size_t scandirlen = livelen + SS_SCANDIR_LEN + 1 + strlen(res->sa.s + res->ownerstr) ; - ss_state_t sta = STATE_ZERO ; char svcandir[scandirlen + 1] ; auto_strings(svcandir, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr) ; - if (!state_read(&sta, res)) - log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ; - r = access(res->sa.s + res->live.scandir, F_OK) ; - if (r == -1 && (sta.toinit == STATE_FLAGS_TRUE || sta.isearlier == STATE_FLAGS_TRUE)) { + if (r == -1 && (sta->toinit == STATE_FLAGS_TRUE || res->earlier)) { if (res->type == TYPE_CLASSIC) scandir_scandir_to_livestate(res) ; - scandir_service_to_scandir(res) ; - - compute_supervision_dir(res) ; - - earlier = service_is(&sta, STATE_FLAGS_ISEARLIER) == STATE_FLAGS_TRUE ? 1 : 0 ; - if (!earlier) { + if (res->earlier) { if (svc_scandir_send(svcandir, "h") <= 0) - log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ; + log_warnu_return(LOG_EXIT_ZERO, "reload scandir: ", svcandir) ; } - state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ; - state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; - state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE) ; - - if (!state_write(&sta, res)) - log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ; + state_set_flag(sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ; + state_set_flag(sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; } else { - if (service_is(&sta, STATE_FLAGS_TOUNSUPERVISE) == STATE_FLAGS_TRUE) { + if (sta->tounsupervise == STATE_FLAGS_TRUE) { - char s[livelen + SS_SCANDIR_LEN + 1 + strlen(res->sa.s + res->ownerstr) + 1 + namelen + 1] ; - auto_strings(s, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr, "/", name) ; + log_trace("remove symlink: ", res->sa.s + res->live.scandir) ; + unlink_void(res->sa.s + res->live.scandir) ; - log_trace("remove symlink: ", s) ; - unlink_void(s) ; - - state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_FALSE) ; - state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; - state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_TRUE) ; - - if (!state_write(&sta, res)) - log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ; + state_set_flag(sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_FALSE) ; + state_set_flag(sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; if (svc_scandir_send(svcandir, "an") <= 0) - log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ; + log_warnu_return(LOG_EXIT_ZERO, "reload scandir: ", svcandir) ; - } else if (service_is(&sta, STATE_FLAGS_TORELOAD) == STATE_FLAGS_TRUE) { + } else if (sta->toreload == STATE_FLAGS_TRUE) { if (svc_scandir_send(svcandir, "a") <= 0) - log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ; - - state_set_flag(&sta, STATE_FLAGS_TORELOAD, STATE_FLAGS_FALSE) ; - state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; - state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ; + log_warnu_return(LOG_EXIT_ZERO, "reload scandir: ", svcandir) ; - if (!state_write(&sta, res)) - log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ; + state_set_flag(sta, STATE_FLAGS_TORELOAD, STATE_FLAGS_FALSE) ; + state_set_flag(sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ; + state_set_flag(sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ; } } + return 1 ; } diff --git a/src/lib66/write/write_logger.c b/src/lib66/write/write_logger.c index 517d50bda6194291b4923f3b263935827ee38215..b0686e580b8eafdbbff2a994eb40a48682ada144 100644 --- a/src/lib66/write/write_logger.c +++ b/src/lib66/write/write_logger.c @@ -51,6 +51,11 @@ void write_logger(resolve_service_t *res, char const *destination, uint8_t force char *logrunner = res->execute.run.runas ? res->sa.s + res->execute.run.runas : SS_LOGGER_RUNNER ; + if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) { + parse_cleanup(res, destination, force) ; + log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ; + } + if (res->execute.timeout.kill) { if (!write_uint(destination, "timeout-kill", res->execute.timeout.kill)) { parse_cleanup(res, destination, force) ; @@ -71,30 +76,11 @@ void write_logger(resolve_service_t *res, char const *destination, uint8_t force log_dieusys(LOG_EXIT_SYS, "write uint file ", SS_NOTIFICATION) ; } - /** log destination */ - log_trace("create directory: ", res->sa.s + res->logger.destination) ; - if (!dir_create_parent(res->sa.s + res->logger.destination, 0755)) { - parse_cleanup(res, destination, force) ; - log_dieusys(LOG_EXIT_SYS, "create directory: ", res->sa.s + res->logger.destination) ; - } - /** - * ISSUE: In case of e.g. earlier service the log - * may point to a tmpfs directory. At next reboot - * the log directory will not be present. We just - * react as oneshot service making it at .run file - * with execl-toc. + /** log destination + * + * The creation of the log destination directory is made at sanitize_init + * to avoid none existing directory if the destination is on tmpfs directory */ - if (!owner && ((res->execute.run.build == BUILD_AUTO) || (!res->execute.run.build))) { - - if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) { - parse_cleanup(res, destination, force) ; - log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ; - } - if (chown(res->sa.s + res->logger.destination, log_uid, log_gid) == -1) { - parse_cleanup(res, destination, force) ; - log_dieusys(LOG_EXIT_SYS, "chown: ", res->sa.s + res->logger.destination) ; - } - } char write[strlen(destination) + 10] ; @@ -125,4 +111,12 @@ void write_logger(resolve_service_t *res, char const *destination, uint8_t force parse_cleanup(res, destination, force) ; log_dieusys(LOG_EXIT_SYS, "chmod", write) ; } + + if (!owner) { + + if (chown(write, log_uid, log_gid) == -1) { + parse_cleanup(res, destination, force) ; + log_dieusys(LOG_EXIT_SYS, "chown: ", write) ; + } + } }