From cdc9615fcc287592b935524d0e244d6a2bb23f6b Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Sat, 15 Oct 2022 23:38:38 +1100 Subject: [PATCH] [WIP] revamp 66-start and 66-stop --- src/lib66/exec/ssexec_start.c | 426 ++++++++-------------------------- src/lib66/exec/ssexec_stop.c | 313 ++++++++----------------- 2 files changed, 204 insertions(+), 535 deletions(-) diff --git a/src/lib66/exec/ssexec_start.c b/src/lib66/exec/ssexec_start.c index 61497fa6..a7fded35 100644 --- a/src/lib66/exec/ssexec_start.c +++ b/src/lib66/exec/ssexec_start.c @@ -12,380 +12,156 @@ * except according to the terms contained in the LICENSE file./ */ -#include <string.h> -#include <stdlib.h> +#include <stdint.h> -#include <oblibs/obgetopt.h> #include <oblibs/log.h> -#include <oblibs/string.h> #include <oblibs/types.h> +#include <oblibs/obgetopt.h> +#include <oblibs/graph.h> -#include <skalibs/stralloc.h> +#include <skalibs/sgetopt.h> #include <skalibs/genalloc.h> -#include <66/db.h> -#include <66/utils.h> -#include <66/constants.h> -#include <66/svc.h> #include <66/ssexec.h> -#include <66/resolve.h> -#include <66/rc.h> +#include <66/config.h> +#include <66/graph.h> #include <66/state.h> +#include <66/svc.h> +#include <66/sanitize.h> #include <66/service.h> -static int empty = 0 ; -static unsigned int RELOAD = 0 ; -static unsigned int DEADLINE = 0 ; -static char *SIG = "-u" ; - -static genalloc nclassic = GENALLOC_ZERO ; //resolve_t type -static genalloc nrc = GENALLOC_ZERO ; //resolve_t type -static ss_resolve_graph_t graph_init_cl = RESOLVE_GRAPH_ZERO ; -static ss_resolve_graph_t graph_reload_cl = RESOLVE_GRAPH_ZERO ; -static ss_resolve_graph_t graph_init_rc = RESOLVE_GRAPH_ZERO ; -static ss_resolve_graph_t graph_reload_rc = RESOLVE_GRAPH_ZERO ; - -int svc_sanitize(ssexec_t *info, char const *const *envp) +int ssexec_start(int argc, char const *const *argv, ssexec_t *info) { log_flow() ; - unsigned int reverse = 0 ; - int r ; - stralloc sares = STRALLOC_ZERO ; + uint32_t flag = 0 ; + graph_t graph = GRAPH_ZERO ; + unsigned int siglen = 2 ; + char *sig[siglen + 1] ; - if (!sa_pointo(&sares,info,TYPE_CLASSIC,SS_RESOLVE_SRC)) - { - log_warnu("set revolve pointer to source") ; - goto err; - } - if (genalloc_len(resolve_service_t,&graph_reload_cl.name)) - { - //reverse = 1 ; - r = ss_resolve_graph_publish(&graph_reload_cl,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } + unsigned int areslen = 0, list[SS_MAX_SERVICE], nservice = 0 ; + resolve_service_t ares[SS_MAX_SERVICE] ; - if (!svc_unsupervise(info,&graph_reload_cl.sorted,"-d",envp)) - goto err ; + FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_TOINIT|STATE_FLAGS_WANTUP) ; - genalloc_reverse(resolve_service_t,&graph_reload_cl.sorted) ; - if (!svc_init(info,sares.s,&graph_reload_cl.sorted)) - { - log_warnu("iniatiate service list") ; - goto err ; - } - goto end ; - } - if (genalloc_len(resolve_service_t,&graph_init_cl.name)) { - r = ss_resolve_graph_publish(&graph_init_cl,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!svc_init(info,sares.s,&graph_init_cl.sorted)) - { - log_warnu("iniatiate service list") ; - goto err ; - } - } + subgetopt l = SUBGETOPT_ZERO ; - end: - stralloc_free(&sares) ; - ss_resolve_graph_free(&graph_reload_cl) ; - ss_resolve_graph_free(&graph_init_cl) ; - return 1 ; - err: - stralloc_free(&sares) ; - ss_resolve_graph_free(&graph_reload_cl) ; - ss_resolve_graph_free(&graph_init_cl) ; - return 0 ; -} + for (;;) { -int rc_sanitize(ssexec_t *info, char const *const *envp) -{ - log_flow() ; + int opt = getopt_args(argc,argv, ">" OPTS_START, &l) ; + if (opt == -1) break ; + if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ; - int r, reverse = 1, done = 0 ; - stralloc sares = STRALLOC_ZERO ; + switch (opt) { - char db[info->livetree.len + 1 + info->treename.len + 1] ; - memcpy(db,info->livetree.s,info->livetree.len) ; - db[info->livetree.len] = '/' ; - memcpy(db + info->livetree.len + 1, info->treename.s, info->treename.len) ; - db[info->livetree.len + 1 + info->treename.len] = 0 ; + case 'r' : - if (!db_ok(info->livetree.s,info->treename.s)) - { - r = rc_init(info,envp) ; - if (!r) goto err ; - else if (r > 1) { empty = 1 ; goto end ; } - done = 1 ; - } - if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) - { - log_warnu("set revolve pointer to source") ; - goto err; - } - if (genalloc_len(resolve_service_t,&graph_init_rc.name) && !done) - { - int ireverse = 0 ; - r = ss_resolve_graph_publish(&graph_init_rc,ireverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!rc_manage(info,&graph_init_rc.sorted)) - { - log_warnu("iniatiate service list") ; - goto err ; - } - } - if (genalloc_len(resolve_service_t,&graph_reload_rc.name)) - { - r = ss_resolve_graph_publish(&graph_reload_rc,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!db_switch_to(info,envp,SS_SWBACK)) - { - log_warnu("switch ",info->treename.s," to backup") ; - goto err ; - } - if (!db_compile(sares.s,info->tree.s, info->treename.s,envp)) - { - log_warnu("compile ",sares.s,"/",info->treename.s) ; - goto err ; - } + if (FLAGS_ISSET(flag, STATE_FLAGS_TORESTART)) + log_usage(usage_start) ; - if (!db_switch_to(info,envp,SS_SWSRC)) - { - log_warnu("switch ",info->treename.s," to source") ; - goto err ; - } + FLAGS_SET(flag, STATE_FLAGS_TORELOAD) ; + break ; - if (!rc_send(info,&graph_reload_rc.sorted,"-d",envp)) goto err ; - } - end: - ss_resolve_graph_free(&graph_reload_rc) ; - ss_resolve_graph_free(&graph_init_rc) ; - stralloc_free(&sares) ; - return 1 ; - - err: - ss_resolve_graph_free(&graph_reload_rc) ; - ss_resolve_graph_free(&graph_init_rc) ; - stralloc_free(&sares) ; - return 0 ; -} + case 'R' : -int rc_start(ssexec_t *info,genalloc *ga,char const *signal,char const *const *envp) -{ - log_flow() ; + if (FLAGS_ISSET(flag, STATE_FLAGS_TORELOAD)) + log_usage(usage_start) ; - char const *sig ; - if (RELOAD >= 1) sig = "-r" ; - else sig = "-u" ; + FLAGS_SET(flag, STATE_FLAGS_TORESTART) ; + break ; - int r = db_find_compiled_state(info->livetree.s,info->treename.s) ; - if (r >= 1) - { - if (!db_switch_to(info,envp,SS_SWSRC)) - log_warnu_return(LOG_EXIT_ZERO,"switch: ",info->treename.s," to source") ; + default : + + log_usage(usage_start) ; + } + } + argc -= l.ind ; argv += l.ind ; } - if (!rc_send(info,ga,sig,envp)) return 0 ; - return 1 ; -} + if (argc < 1) + log_usage(usage_start) ; -int ssexec_start(int argc, char const *const *argv,char const *const *envp,ssexec_t *info) -{ - // be sure that the global var are set correctly - RELOAD = 0 ; - DEADLINE = 0 ; - SIG = "-u" ; + if ((svc_scandir_ok(info->scandir.s)) != 1 ) + log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s, " is not running") ; - if (info->timeout) DEADLINE = info->timeout ; + int n = 0 ; + for (; n < argc ; n++) + /** If it's the first use of 66, we don't have + * any resolve files available or the service was + * never parsed, the graph is empty in the first case or + * the later call of service_array_search do not found the corresponding + * resolve file for the second case. + * Try at least to parse the corresponding frontend file. */ + sanitize_source(argv[n], info, STATE_FLAGS_UNKNOWN) ; - int cl, rc, logname ; - stralloc sares = STRALLOC_ZERO ; - stralloc sasta = STRALLOC_ZERO ; - genalloc gares = GENALLOC_ZERO ; //resolve_service_t - resolve_service_t_ref pres ; - resolve_service_t res = RESOLVE_SERVICE_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; - ss_state_t sta = STATE_ZERO ; + /** build the graph of the entire system */ + graph_build_service(&graph, ares, &areslen, info, flag) ; - cl = rc = logname = 0 ; + if (!graph.mlen) + log_die(LOG_EXIT_USER, "services selection is not available -- try first to install the corresponding frontend file") ; - { - subgetopt l = SUBGETOPT_ZERO ; + for (n = 0 ; n < argc ; n++) { - for (;;) - { - int opt = getopt_args(argc,argv, ">" OPTS_START, &l) ; - if (opt == -1) break ; - if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ; + int aresid = service_resolve_array_search(ares, areslen, argv[n]) ; + if (aresid < 0) + log_die(LOG_EXIT_USER, "service: ", *argv, " not available -- did you parsed it?") ; - switch (opt) - { - case 'r' : if (RELOAD) log_usage(usage_start) ; RELOAD = 1 ; SIG = "-r" ; break ; - case 'R' : if (RELOAD) log_usage(usage_start) ; RELOAD = 2 ; SIG = "-u" ; break ; - default : log_usage(usage_start) ; - } - } - argc -= l.ind ; argv += l.ind ; + list[nservice++] = aresid ; + unsigned int l[graph.mlen] ; + unsigned int c = 0 ; + + /** find dependencies of the service from the graph, do it recursively */ + c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 0, 1) ; + + /** append to the list to deal with */ + for (unsigned int pos = 0 ; pos < c ; pos++) + list[nservice + pos] = l[pos] ; + + nservice += c ; } - if (argc < 1) log_usage(usage_start) ; + /** initiate services at the corresponding scandir */ + sanitize_init(list, nservice, &graph, ares, areslen, FLAGS_ISSET(flag, STATE_FLAGS_TORESTART) ? STATE_FLAGS_TOINIT : STATE_FLAGS_UNKNOWN) ; - if ((scandir_ok(info->scandir.s)) !=1 ) log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ; + service_resolve_array_free(ares, areslen) ; - if (!sa_pointo(&sasta,info,SS_NOTYPE,SS_RESOLVE_STATE)) log_dieusys(LOG_EXIT_SYS,"set revolve pointer to state") ; - /** the tree may not initialized already, check it and create - * the live directory if it's the case */ - if (!scan_mode(sasta.s,S_IFDIR)) - if (!create_live(info)) log_dieusys(LOG_EXIT_SYS,"create live state") ; + graph_free_all(&graph) ; - if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) log_dieusys(LOG_EXIT_SYS,"set revolve pointer to source") ; + if (FLAGS_ISSET(flag, STATE_FLAGS_TORELOAD)) { - for (;*argv;argv++) - { - char const *name = *argv ; - if (!resolve_check(sares.s,name)) log_info_return(LOG_EXIT_ZERO,name," is not enabled") ; - if (!resolve_read(wres,sares.s,name)) log_dieusys(LOG_EXIT_SYS,"read resolve file of: ",name) ; - if (res.type == TYPE_MODULE) - { - if (!module_in_cmdline(&gares,&res,sares.s)) - log_dieu(LOG_EXIT_SYS,"add dependencies of module: ",name) ; - } - else - { - if (!resolve_append(&gares,wres)) - log_dieusys(LOG_EXIT_SYS,"append services selection with: ",name) ; - } - } + sig[0] = "-wU" ; + sig[1] = "-ru" ; + sig[2] = 0 ; - for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++) - { - int init = 0 ; - int reload = 0 ; - int reverse = 0 ; - pres = &genalloc_s(resolve_service_t,&gares)[i] ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, pres) ; - char *string = pres->sa.s ; - char *name = string + pres->name ; - logname = 0 ; - if (!state_check(sasta.s,name)) - { - init = 1 ; - goto append ; - } - else if (!state_read(&sta,sasta.s,name)) log_dieusys(LOG_EXIT_SYS,"read state file of: ",name) ; + if (!svc_send(argv, argc, sig, siglen, info)) + log_dieu(LOG_EXIT_SYS, "send -wU -ru signal") ; - if (obstr_equal(name,SS_MASTER + 1)) goto append ; + } else if (FLAGS_ISSET(flag, STATE_FLAGS_TORESTART)) { - if (!pres->disen) - log_die(LOG_EXIT_USER,"service: ",name," was disabled, you can only stop it") ; + sig[0] = "-wD" ; + sig[1] = "-d" ; + sig[2] = 0 ; - logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ; - if (logname > 0 && (!resolve_cmp(&gares, string + pres->logassoc, DATA_SERVICE))) - { - if (RELOAD > 1) log_die(LOG_EXIT_SYS,"-R signal is not allowed to a logger") ; - if (sta.init) reverse = 1 ; - } - if (RELOAD > 1 || sta.reload) reload = 1 ; - - if (sta.init){ reload = 0 ; init = 1 ; } - - append: - if (pres->type == TYPE_CLASSIC) - { - if (reload) - { - reverse = 1 ; - if (!ss_resolve_graph_build(&graph_reload_cl,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - } - else if (init) - { - reverse = 0 ; - if (!ss_resolve_graph_build(&graph_init_cl,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - } - if (!resolve_append(&nclassic,wres)) log_dieusys(LOG_EXIT_SYS,"append services selection with: ",name) ; - cl++ ; - } - else - { - if (reload) - { - reverse = 1 ; - if (!ss_resolve_graph_build(&graph_reload_rc,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - } - else if (init) - { - reverse = 0 ; - if (!ss_resolve_graph_build(&graph_init_rc,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - } - if (!resolve_append(&nrc,wres)) log_dieusys(LOG_EXIT_SYS,"append services selection with: ",name) ; - rc++; - } - free(wres) ; - } + if (!svc_send(argv, argc, sig, siglen, info)) + log_dieu(LOG_EXIT_SYS, "send -wD -d signal") ; - if (cl) - { - log_trace("sanitize classic services list...") ; - if (!svc_sanitize(info,envp)) - log_dieu(LOG_EXIT_SYS,"sanitize classic services list") ; - log_trace("start classic services list ...") ; - { - /** In case of -R asked by user, svc service will be unsupervised. - * In this case the log will be started directly by the service (log is - * a part of the service directory A.K.A. service/log). - * So we need to make a distinction for 66-svctl between -r and -R to avoid - * to start the logger before the service itself because the resolution of - * the graph will append the service log. */ - if (RELOAD == 2) SIG = "-R" ; - if (!svc_send(info,&nclassic,SIG,envp)) - log_dieu(LOG_EXIT_SYS,"start classic services list") ; - } - log_trace("switch classic service list of: ",info->treename.s," to source") ; - if (!svc_switch_to(info,SS_SWSRC)) - log_dieu(LOG_EXIT_SYS,"switch classic service list of: ",info->treename.s," to source") ; + sig[0] = "-wU" ; + sig[1] = "-ru" ; + sig[2] = 0 ; - resolve_deep_free(DATA_SERVICE, &nclassic) ; - } - if (rc) - { - log_trace("sanitize atomic services list...") ; - if (!rc_sanitize(info,envp)) - log_dieu(LOG_EXIT_SYS,"sanitize atomic services list") ; - if (!empty) - { - log_trace("start atomic services list ...") ; - if (!rc_start(info,&nrc,SIG,envp)) - log_dieu(LOG_EXIT_SYS,"start atomic services list ") ; - log_trace("switch atomic services list of: ",info->treename.s," to source") ; - if (!db_switch_to(info,envp,SS_SWSRC)) - log_dieu(LOG_EXIT_SYS,"switch atomic services list of: ",info->treename.s," to source") ; - } - resolve_deep_free(DATA_SERVICE, &nrc) ; + if (!svc_send(argv, argc, sig, siglen, info)) + log_dieu(LOG_EXIT_SYS, "send -wU -u signal") ; + + } else { + + sig[0] = "-wU" ; + sig[1] = "-u" ; + sig[2] = 0 ; + + if (!svc_send(argv, argc, sig, siglen, info)) + log_dieu(LOG_EXIT_SYS, "send -wU -u signal") ; } - stralloc_free(&sares) ; - stralloc_free(&sasta) ; - resolve_deep_free(DATA_SERVICE, &gares) ; - resolve_free(wres) ; return 0 ; } diff --git a/src/lib66/exec/ssexec_stop.c b/src/lib66/exec/ssexec_stop.c index 27743fe8..2451a22c 100644 --- a/src/lib66/exec/ssexec_stop.c +++ b/src/lib66/exec/ssexec_stop.c @@ -12,258 +12,151 @@ * except according to the terms contained in the LICENSE file./ */ -#include <string.h> +#include <stdint.h> -#include <oblibs/obgetopt.h> #include <oblibs/log.h> -#include <oblibs/string.h> +#include <oblibs/types.h> +#include <oblibs/obgetopt.h> +#include <oblibs/graph.h> -#include <skalibs/stralloc.h> +#include <skalibs/sgetopt.h> +#include <skalibs/djbunix.h> #include <skalibs/genalloc.h> -#include <66/utils.h> -#include <66/constants.h> -#include <66/db.h> -#include <66/svc.h> -#include <66/rc.h> +#include <66/graph.h> +#include <66/config.h> #include <66/ssexec.h> -#include <66/resolve.h> -#include <66/service.h> #include <66/state.h> +#include <66/svc.h> +#include <66/service.h> -static unsigned int DEADLINE = 0 ; -static unsigned int UNSUP = 0 ; -static char *SIG = "-d" ; - -static ss_resolve_graph_t graph_unsup_cl = RESOLVE_GRAPH_ZERO ; -static ss_resolve_graph_t graph_cl = RESOLVE_GRAPH_ZERO ; -static ss_resolve_graph_t graph_unsup_rc = RESOLVE_GRAPH_ZERO ; -static ss_resolve_graph_t graph_rc = RESOLVE_GRAPH_ZERO ; - -int svc_down(ssexec_t *info, char const *const *envp) +int ssexec_stop(int argc, char const *const *argv, ssexec_t *info) { log_flow() ; - unsigned int reverse = 1 ; - int r ; + uint32_t flag = 0 ; + graph_t graph = GRAPH_ZERO ; - if (genalloc_len(resolve_service_t,&graph_unsup_cl.name)) - { - UNSUP = 1 ; - r = ss_resolve_graph_publish(&graph_unsup_cl,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!svc_unsupervise(info,&graph_unsup_cl.sorted,SIG,envp)) goto err ; - } - else - { - r = ss_resolve_graph_publish(&graph_cl,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!svc_send(info,&graph_cl.sorted,SIG,envp)) goto err ; - } - ss_resolve_graph_free(&graph_unsup_cl) ; - ss_resolve_graph_free(&graph_cl) ; - return 1 ; - err: - ss_resolve_graph_free(&graph_unsup_cl) ; - ss_resolve_graph_free(&graph_cl) ; - return 0 ; -} + unsigned int areslen = 0, list[SS_MAX_SERVICE], nservice = 0 ; + resolve_service_t ares[SS_MAX_SERVICE] ; -int rc_down(ssexec_t *info, char const *const *envp) -{ - log_flow() ; + FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_ISSUPERVISED|STATE_FLAGS_WANTDOWN) ; - unsigned int reverse = 1 ; - int r ; - - if (genalloc_len(resolve_service_t,&graph_unsup_rc.name)) - { - UNSUP = 1 ; - r = ss_resolve_graph_publish(&graph_unsup_rc,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!rc_unsupervise(info,&graph_unsup_rc.sorted,"-d",envp)) goto err ; - } - else { - r = ss_resolve_graph_publish(&graph_rc,reverse) ; - if (r < 0 || !r) - { - log_warnusys("publish service graph") ; - goto err ; - } - if (!rc_send(info,&graph_rc.sorted,"-d",envp)) goto err ; - } + subgetopt l = SUBGETOPT_ZERO ; - ss_resolve_graph_free(&graph_unsup_rc) ; - ss_resolve_graph_free(&graph_rc) ; - return 1 ; - err: - ss_resolve_graph_free(&graph_unsup_rc) ; - ss_resolve_graph_free(&graph_rc) ; - return 0 ; -} + for (;;) { -int ssexec_stop(int argc, char const *const *argv,char const *const *envp,ssexec_t *info) -{ - // be sure that the global var are set correctly - DEADLINE = 0 ; - UNSUP = 0 ; - SIG = "-d" ; + int opt = getopt_args(argc,argv, ">" OPTS_STOP, &l) ; + if (opt == -1) break ; + if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ; - if (info->timeout) DEADLINE = info->timeout ; + switch (opt) { - int cl, rc, sigopt ; - stralloc sares = STRALLOC_ZERO ; - genalloc gares = GENALLOC_ZERO ; //resolve_service_t - resolve_service_t_ref pres ; - resolve_service_t res = RESOLVE_SERVICE_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; - ss_state_t sta = STATE_ZERO ; + case 'u' : - cl = rc = sigopt = 0 ; + FLAGS_SET(flag, STATE_FLAGS_TOUNSUPERVISE|STATE_FLAGS_WANTUP) ; + break ; - { - subgetopt l = SUBGETOPT_ZERO ; + case 'X' : - for (;;) - { - int opt = getopt_args(argc,argv, ">" OPTS_STOP, &l) ; - if (opt == -1) break ; - if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ; + log_1_warn("deprecated option -- use 66-svctl -xd instead") ; + return 0 ; + + case 'K' : - switch (opt) - { - case 'u' : UNSUP = 1 ; break ; - case 'X' : if (sigopt) log_usage(usage_stop) ; sigopt = 1 ; SIG = "-X" ; break ; - case 'K' : if (sigopt) log_usage(usage_stop) ; sigopt = 1 ; SIG = "-K" ; break ; - default : log_usage(usage_stop) ; + log_1_warn("deprecated option -- use 66-svctl -kd instead") ; + return 0 ; + + default : + log_usage(usage_stop) ; } } argc -= l.ind ; argv += l.ind ; } - if (argc < 1) log_usage(usage_stop) ; + if (argc < 1) + log_usage(usage_stop) ; - if ((scandir_ok(info->scandir.s)) !=1 ) log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ; + if ((svc_scandir_ok(info->scandir.s)) != 1) + log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ; - if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) log_dieusys(LOG_EXIT_SYS,"set revolve pointer to source") ; + /** build the graph of the entire system */ + graph_build_service(&graph, ares, &areslen, info, flag) ; - for (;*argv;argv++) - { - char const *name = *argv ; - if (!resolve_check(sares.s,name)) log_info_return(LOG_EXIT_ZERO,name," is not enabled") ; - if (!resolve_read(wres,sares.s,name)) log_dieusys(LOG_EXIT_SYS,"read resolve file of: ",name) ; - if (res.type == TYPE_MODULE) - { - if (!module_in_cmdline(&gares,&res,sares.s)) - log_dieu(LOG_EXIT_SYS,"add dependencies of module: ",name) ; - } - else - { - if (!resolve_append(&gares,wres)) - log_dieusys(LOG_EXIT_SYS,"append resolve file of: ",name) ; - } - } + if (!graph.mlen) + log_die(LOG_EXIT_USER, "services selection is not available -- try first to install the corresponding frontend file") ; - for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++) - { - int unsup = 0 , reverse = 1 ; - pres = &genalloc_s(resolve_service_t,&gares)[i] ; - char const *string = pres->sa.s ; - char const *name = string + pres->name ; - char const *state = string + pres->state ; + int n = 0 ; + for (; n < argc ; n++) { - if (!state_check(state,name)) log_die(LOG_EXIT_USER,name," : is not initialized") ; - else if (!state_read(&sta,state,name)) log_dieusys(LOG_EXIT_SYS,"read state file of: ",name) ; + int aresid = service_resolve_array_search(ares, areslen, argv[n]) ; + if (aresid < 0) + log_die(LOG_EXIT_USER, "service: ", *argv, " not available -- did you started it?") ; - int logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ; + list[nservice++] = aresid ; + unsigned int l[graph.mlen] ; + unsigned int c = 0 ; - if (obstr_equal(name,SS_MASTER + 1)) - { - if (pres->ndepends) goto append ; - else continue ; - } + /** find requiredby of the service from the graph, do it recursively */ + c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 1, 1) ; - /** logger cannot be unsupervised alone */ - if (logname > 0 && (!resolve_cmp(&gares,string + pres->logassoc, DATA_SERVICE))) - { - if (UNSUP) log_die(LOG_EXIT_SYS,"logger detected - unsupervise request is not allowed") ; - } - if (UNSUP) unsup = 1 ; - if (sta.unsupervise) unsup = 1 ; - append: - if (pres->type == TYPE_CLASSIC) - { - if (unsup) - { - if (!ss_resolve_graph_build(&graph_unsup_cl,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - if (!service_resolve_add_logger(&graph_unsup_cl.name,sares.s)) - log_dieusys(LOG_EXIT_SYS,"append service selection with logger") ; - } - if (!ss_resolve_graph_build(&graph_cl,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - cl++ ; - } - else - { - if (unsup) - { - if (!ss_resolve_graph_build(&graph_unsup_rc,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - if (!service_resolve_add_logger(&graph_unsup_rc.name,sares.s)) - log_dieusys(LOG_EXIT_SYS,"append service selection with logger") ; - } - if (!ss_resolve_graph_build(&graph_rc,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) - log_dieusys(LOG_EXIT_SYS,"build services graph") ; - rc++; - } + /** append to the list to deal with */ + for (unsigned int pos = 0 ; pos < c ; pos++) + list[nservice + pos] = l[pos] ; + + nservice += c ; } - /** rc work */ - if (rc) - { - log_trace("stop atomic services ...") ; - if (!rc_down(info,envp)) - log_dieu(LOG_EXIT_SYS,"stop atomic services") ; - log_trace("switch atomic services of: ",info->treename.s," to source") ; - if (!db_switch_to(info,envp,SS_SWSRC)) - log_dieu(LOG_EXIT_SYS,"switch",info->livetree.s,"/",info->treename.s," to source") ; + if (FLAGS_ISSET(flag, STATE_FLAGS_TOUNSUPERVISE)) { - } + /** we cannot pass through the svc_send() function which + * call ssexec_svctl(). The ssexec_svctl function is asynchronous. + * So, when child exist, the svc_send is "unblocked" and the program + * continue to execute. We need to wait for all services to be brought + * down before executing the unsupervise.*/ + pid_t pid ; + int wstat ; - /** svc work */ - if (cl) - { - log_trace("stop classic services ...") ; - if (!svc_down(info,envp)) - log_dieu(LOG_EXIT_SYS,"stop classic services") ; - log_trace("switch classic services of: ",info->treename.s," to source") ; - if (!svc_switch_to(info,SS_SWSRC)) - log_dieu(LOG_EXIT_SYS,"switch classic service of: ",info->treename.s," to source") ; - } + int nargc = 4 + nservice ; + char const *newargv[nargc] ; + unsigned int m = 0, n = 0 ; - if (UNSUP) - { - log_trace("send signal -an to scandir: ",info->scandir.s) ; - if (scandir_send_signal(info->scandir.s,"h") <= 0) - log_dieu(LOG_EXIT_SYS,"send signal to scandir: ", info->scandir.s) ; + newargv[m++] = "66-svctl" ; + newargv[m++] = "-wD" ; + newargv[m++] = "-d" ; + + for (; n < nservice ; n++) + newargv[m++] = graph.data.s + genalloc_s(graph_hash_t,&graph.hash)[list[n]].vertex ; + + newargv[m++] = 0 ; + + pid = child_spawn0(newargv[0], newargv, (char const *const *) environ) ; + + if (waitpid_nointr(pid, &wstat, 0) < 0) + log_dieusys(LOG_EXIT_SYS, "wait for 66-svctl") ; + + if (wstat) + log_dieu(LOG_EXIT_SYS, "stop services selection") ; + + svc_unsupervise(list, nservice, &graph, ares, areslen) ; + + } else { + + unsigned int siglen = 2 ; + char *sig[siglen + 1] ; + + sig[0] = "-wD" ; + sig[1] = "-d" ; + sig[2] = 0 ; + + if (!svc_send(argv, argc, sig, siglen, info)) + log_dieu(LOG_EXIT_SYS, "send -wD -d signal") ; } - stralloc_free(&sares) ; - resolve_free(wres) ; - resolve_deep_free(DATA_SERVICE, &gares) ; + + service_resolve_array_free(ares, areslen) ; + + graph_free_all(&graph) ; return 0 ; } -- GitLab