From 237e27ce51e09084d029d588ce0b6c171c08939f Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Thu, 7 Jul 2022 21:15:14 +1100 Subject: [PATCH] revamp 66-init. Provide option to only init enabled service or disabled service or all service of a trees --- src/lib66/exec/ssexec_init.c | 243 +++++++++++++++++++++-------------- 1 file changed, 145 insertions(+), 98 deletions(-) diff --git a/src/lib66/exec/ssexec_init.c b/src/lib66/exec/ssexec_init.c index e152d5b8..4e373b71 100644 --- a/src/lib66/exec/ssexec_init.c +++ b/src/lib66/exec/ssexec_init.c @@ -17,6 +17,7 @@ #include <unistd.h>//chown #include <stdio.h> +#include <oblibs/obgetopt.h> #include <oblibs/log.h> #include <oblibs/types.h>//scan_mode #include <oblibs/directory.h> @@ -24,143 +25,189 @@ #include <oblibs/string.h> #include <skalibs/stralloc.h> -#include <skalibs/genalloc.h> #include <skalibs/djbunix.h> #include <66/utils.h> #include <66/constants.h> #include <66/tree.h> -#include <66/db.h> #include <66/svc.h> #include <66/resolve.h> #include <66/ssexec.h> -#include <66/rc.h> #include <66/state.h> +#include <66/sanitize.h> -int ssexec_init(int argc, char const *const *argv,char const *const *envp,ssexec_t *info) +static int init_parse_options(char const *opts) { - log_flow() ; + int r = get_len_until(opts, '=') ; + if (r < 0) + log_die(LOG_EXIT_USER, "invalid opts: ", opts) ; - int r, db, classic, earlier ; - ssize_t i = 0, logname = 0 ; - genalloc gares = GENALLOC_ZERO ; //resolve_service_t type - stralloc sares = STRALLOC_ZERO ; - stralloc sasvc = STRALLOC_ZERO ; - ss_state_t sta = STATE_ZERO ; - char const *exclude[1] = { 0 } ; + char tmp[9] ; - classic = db = earlier = 0 ; + auto_strings(tmp, opts + r + 1) ; - gid_t gidowner ; - if (!yourgid(&gidowner,info->owner)) log_dieusys(LOG_EXIT_SYS,"get gid") ; + if (!strcmp(tmp, "disabled")) + return 0 ; - if (argc <= 1) log_usage(usage_init) ; - if (*argv[1] == 'c') classic = 1 ; - else if (*argv[1] == 'd') db = 1 ; - else if (*argv[1] == 'b') classic = db = 1 ; - else log_die(LOG_EXIT_USER,"unknown command: ",argv[1]) ; + else if (!strcmp(tmp, "enabled")) + return 1 ; - if (!tree_get_permissions(info->tree.s,info->owner)) - log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->tree.s) ; + else + log_die(LOG_EXIT_USER, "invalid opts: ", tmp) ; - r = scan_mode(info->scandir.s,S_IFDIR) ; - if (r < 0) log_die(LOG_EXIT_SYS,info->scandir.s," conflicted format") ; - if (!r) log_die(LOG_EXIT_USER,"scandir: ",info->scandir.s," doesn't exist") ; +} - r = scandir_ok(info->scandir.s) ; - if (r != 1) earlier = 1 ; +static void doit(stralloc *sa, char const *svdirs, char const *treename, uint8_t earlier) +{ + unsigned int pos = 0, count = 0, nservice = sastr_nelement(sa) ; + resolve_service_t ares[nservice] ; - r = scan_mode(info->livetree.s,S_IFDIR) ; - if (r < 0) log_die(LOG_EXIT_SYS,info->livetree.s," conflicted format") ; - if (!r) - { - log_trace("create directory: ",info->livetree.s) ; - r = dir_create(info->livetree.s,0700) ; - if (!r) log_dieusys(LOG_EXIT_SYS,"create directory: ",info->livetree.s) ; - log_trace("chown directory: ",info->livetree.s) ; - if (chown(info->livetree.s,info->owner,gidowner) < 0) log_dieusys(LOG_EXIT_SYS,"chown directory: ",info->livetree.s) ; + FOREACH_SASTR(sa, pos) { + + char *service = sa->s + pos ; + + resolve_service_t res = RESOLVE_SERVICE_ZERO ; + resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; + + if (!resolve_read(wres, svdirs, service)) + log_dieusys(LOG_EXIT_SYS,"read resolve file of: ", service) ; + + /** + * boot time. We only pick the earlier service. + * The rest is initialized at stage2. + * */ + if (earlier) { + if (res.earlier) + ares[count++] = res ; + + } else + ares[count++] = res ; } - size_t dirlen ; - char svdir[info->tree.len + SS_SVDIRS_LEN + SS_SVC_LEN + 1] ; + nservice = count ; - auto_strings(svdir, info->tree.s, SS_SVDIRS, SS_SVC) ; + //0 don't remove down file -> 2 remove down file + if (!sanitize_init(ares, nservice, !earlier ? 0 : STATE_FLAGS_ISEARLIER)) + log_dieu(LOG_EXIT_SYS,"initiate services of tree: ", treename) ; - dirlen = info->tree.len + SS_SVDIRS_LEN + SS_SVC_LEN ; + service_resolve_array_free(ares, nservice) ; +} - if (!create_live(info)) log_dieusys(LOG_EXIT_SYS,"create live state") ; +int ssexec_init(int argc, char const *const *argv, ssexec_t *info) +{ + log_flow() ; - /** svc already initiated? */ - if (classic) { + int r, what = -1 ; + uint8_t nopts = 0, earlier = 0 ; + char const *treename = 0 ; + char opts[14] ; + gid_t gidowner ; + resolve_service_master_t mres = RESOLVE_SERVICE_MASTER_ZERO ; + resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE_MASTER, &mres) ; + stralloc sa = STRALLOC_ZERO ; - if (!sastr_dir_get(&sasvc,svdir,exclude,S_IFDIR)) - log_dieusys(LOG_EXIT_SYS,"get classic services from: ",svdir) ; + if (!yourgid(&gidowner,info->owner)) + log_dieusys(LOG_EXIT_SYS,"get gid") ; - if (!sasvc.len) { - log_info("Initialization report: no classic services into tree: ",info->treename.s) ; - goto follow ; - } + { + subgetopt l = SUBGETOPT_ZERO ; - if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) - log_dieu(LOG_EXIT_SYS,"set revolve pointer to source") ; - - for (i = 0;i < sasvc.len; i += strlen(sasvc.s + i) + 1) { - char *name = sasvc.s + i ; - resolve_service_t res = RESOLVE_SERVICE_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; - if (!resolve_check(sares.s,name)) log_diesys(LOG_EXIT_USER,"unknown service: ",name) ; - if (!resolve_read(wres,sares.s,name)) log_dieusys(LOG_EXIT_SYS,"read resolve file of: ",name) ; - if (!service_resolve_add_deps(&gares,&res,sares.s)) log_dieusys(LOG_EXIT_SYS,"resolve dependencies of: ",name) ; - resolve_free(wres) ; - } + for (;;) { - if (!earlier) { - /** reverse to start first the logger */ - genalloc_reverse(resolve_service_t,&gares) ; - if (!svc_init(info,svdir,&gares)) log_dieu(LOG_EXIT_SYS,"initiate service of tree: ",info->treename.s) ; + int opt = getopt_args(argc,argv, ">" OPTS_INIT, &l) ; + if (opt == -1) break ; + if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ; - } else { + switch (opt) { + + case 'o' : + auto_strings(opts, l.arg) ; + nopts++ ; - for (i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++) { - - logname = 0 ; - char *string = genalloc_s(resolve_service_t,&gares)[i].sa.s ; - char *name = string + genalloc_s(resolve_service_t,&gares)[i].name ; - size_t namelen = strlen(name) ; - logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ; - if (logname > 0) name = string + genalloc_s(resolve_service_t,&gares)[i].logassoc ; - char tocopy[dirlen + 1 + namelen + 1] ; - auto_strings(tocopy, svdir, "/", name) ; - if (!hiercopy(tocopy,string + genalloc_s(resolve_service_t,&gares)[i].runat)) log_dieusys(LOG_EXIT_SYS,"copy earlier service: ",tocopy," to: ",string + genalloc_s(resolve_service_t,&gares)[i].runat) ; - state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_FALSE) ; - state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ; - state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_UNKNOWN) ; - state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_UNKNOWN) ; - if (!state_write(&sta,string + genalloc_s(resolve_service_t,&gares)[i].state,name)) log_dieusys(LOG_EXIT_SYS,"write state file of: ",name) ; - log_info("Initialized successfully: ", logname < 0 ? name : string + genalloc_s(resolve_service_t,&gares)[i].logreal) ; + default: + + log_usage(usage_init) ; } } + argc -= l.ind ; argv += l.ind ; } - follow: + if (argc < 1) + log_usage(usage_init) ; - stralloc_free(&sares) ; - stralloc_free(&sasvc) ; - resolve_deep_free(DATA_SERVICE, &gares) ; + treename = argv[1] ; - /** db already initiated? */ - if (db) { - if (!earlier) { - if (db_ok(info->livetree.s,info->treename.s)) { - log_warn("db of tree: ",info->treename.s," already initialized") ; - goto end ; - } - }else log_die(LOG_EXIT_USER,"scandir: ",info->scandir.s," is not running") ; - }else goto end ; + if (nopts) + what = init_parse_options(opts) ; + + size_t treenamelen = strlen(treename) ; + size_t treelen = info->base.len + SS_SYSTEM_LEN + 1 + treenamelen + 1 + SS_SVDIRS_LEN ; + char tree[treelen + 1] ; + auto_strings(tree, info->base.s, SS_SYSTEM, "/", treename) ; + + if (!tree_isvalid(info->base.s, treename)) + log_diesys(LOG_EXIT_USER, "invalid tree directory: ", treename) ; + + if (!tree_get_permissions(tree, info->owner)) + log_die(LOG_EXIT_USER, "You're not allowed to use the tree: ", tree) ; + + r = scan_mode(info->scandir.s, S_IFDIR) ; + if (r < 0) log_die(LOG_EXIT_SYS,info->scandir.s, " conflicted format") ; + if (!r) log_die(LOG_EXIT_USER,"scandir: ", info->scandir.s, " doesn't exist") ; + + r = scandir_ok(info->scandir.s) ; + if (r != 1) earlier = 1 ; + + auto_strings(tree + info->base.len + SS_SYSTEM_LEN + 1 + treenamelen, SS_SVDIRS) ; + + if (!resolve_read_g(wres, tree, SS_MASTER + 1)) + log_dieu(LOG_EXIT_SYS, "read resolve service Master file of tree: ", treename) ; + + if (what < 0) { + + if (mres.ncontents) { + + if (!sastr_clean_string(&sa, mres.sa.s + mres.contents)) + log_dieu(LOG_EXIT_SYS, "clean string: ", mres.sa.s + mres.contents) ; + + } else { + + log_info("Initialization report: no enabled services to initiate at tree: ", treename) ; + goto end ; + } + + } else if (!what) { + + if (mres.ndisabled) { + + if (!sastr_clean_string(&sa, mres.sa.s + mres.disabled)) + log_dieu(LOG_EXIT_SYS, "clean string: ", mres.sa.s + mres.disabled) ; + + } else { + + log_info("Initialization report: no disabled services to initiate at tree: ", treename) ; + goto end ; + } + + } else if (what) { + + if (mres.nenabled) { + + if (!sastr_clean_string(&sa, mres.sa.s + mres.enabled)) + log_dieu(LOG_EXIT_SYS, "clean string: ", mres.sa.s + mres.enabled) ; + + } else { + + log_info("Initialization report: no enabled services to initiate at tree: ", treename) ; + goto end ; + } + } - if (!rc_init(info,envp)) log_dieusys(LOG_EXIT_SYS,"initiate db of tree: ",info->treename.s) ; + doit(&sa, tree, treename, earlier) ; end: - return 0 ; + resolve_free(wres) ; + stralloc_free(&sa) ; + return 0 ; } -- GitLab