Skip to content
Snippets Groups Projects
Commit cdc9615f authored by Eric Vidal's avatar Eric Vidal :speech_balloon:
Browse files

[WIP] revamp 66-start and 66-stop

parent 521b2009
No related branches found
No related tags found
No related merge requests found
...@@ -12,380 +12,156 @@ ...@@ -12,380 +12,156 @@
* except according to the terms contained in the LICENSE file./ * except according to the terms contained in the LICENSE file./
*/ */
#include <string.h> #include <stdint.h>
#include <stdlib.h>
#include <oblibs/obgetopt.h>
#include <oblibs/log.h> #include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.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 <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/ssexec.h>
#include <66/resolve.h> #include <66/config.h>
#include <66/rc.h> #include <66/graph.h>
#include <66/state.h> #include <66/state.h>
#include <66/svc.h>
#include <66/sanitize.h>
#include <66/service.h> #include <66/service.h>
static int empty = 0 ; int ssexec_start(int argc, char const *const *argv, ssexec_t *info)
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)
{ {
log_flow() ; log_flow() ;
unsigned int reverse = 0 ; uint32_t flag = 0 ;
int r ; graph_t graph = GRAPH_ZERO ;
stralloc sares = STRALLOC_ZERO ; unsigned int siglen = 2 ;
char *sig[siglen + 1] ;
if (!sa_pointo(&sares,info,TYPE_CLASSIC,SS_RESOLVE_SRC)) unsigned int areslen = 0, list[SS_MAX_SERVICE], nservice = 0 ;
{ resolve_service_t ares[SS_MAX_SERVICE] ;
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 ;
}
if (!svc_unsupervise(info,&graph_reload_cl.sorted,"-d",envp)) FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_TOINIT|STATE_FLAGS_WANTUP) ;
goto err ;
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) ; subgetopt l = SUBGETOPT_ZERO ;
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 ;
}
}
end: for (;;) {
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 ;
}
int rc_sanitize(ssexec_t *info, char const *const *envp) int opt = getopt_args(argc,argv, ">" OPTS_START, &l) ;
{ if (opt == -1) break ;
log_flow() ; if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
int r, reverse = 1, done = 0 ; switch (opt) {
stralloc sares = STRALLOC_ZERO ;
char db[info->livetree.len + 1 + info->treename.len + 1] ; case 'r' :
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 ;
if (!db_ok(info->livetree.s,info->treename.s)) if (FLAGS_ISSET(flag, STATE_FLAGS_TORESTART))
{ log_usage(usage_start) ;
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 (!db_switch_to(info,envp,SS_SWSRC)) FLAGS_SET(flag, STATE_FLAGS_TORELOAD) ;
{ break ;
log_warnu("switch ",info->treename.s," to source") ;
goto err ;
}
if (!rc_send(info,&graph_reload_rc.sorted,"-d",envp)) goto err ; case 'R' :
}
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 ;
}
int rc_start(ssexec_t *info,genalloc *ga,char const *signal,char const *const *envp) if (FLAGS_ISSET(flag, STATE_FLAGS_TORELOAD))
{ log_usage(usage_start) ;
log_flow() ;
char const *sig ; FLAGS_SET(flag, STATE_FLAGS_TORESTART) ;
if (RELOAD >= 1) sig = "-r" ; break ;
else sig = "-u" ;
int r = db_find_compiled_state(info->livetree.s,info->treename.s) ; default :
if (r >= 1)
{ log_usage(usage_start) ;
if (!db_switch_to(info,envp,SS_SWSRC)) }
log_warnu_return(LOG_EXIT_ZERO,"switch: ",info->treename.s," to source") ; }
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) if ((svc_scandir_ok(info->scandir.s)) != 1 )
{ log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s, " is not running") ;
// be sure that the global var are set correctly
RELOAD = 0 ;
DEADLINE = 0 ;
SIG = "-u" ;
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 ; /** build the graph of the entire system */
stralloc sares = STRALLOC_ZERO ; graph_build_service(&graph, ares, &areslen, info, flag) ;
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 ;
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") ;
{ for (n = 0 ; n < argc ; n++) {
subgetopt l = SUBGETOPT_ZERO ;
for (;;) int aresid = service_resolve_array_search(ares, areslen, argv[n]) ;
{ if (aresid < 0)
int opt = getopt_args(argc,argv, ">" OPTS_START, &l) ; log_die(LOG_EXIT_USER, "service: ", *argv, " not available -- did you parsed it?") ;
if (opt == -1) break ;
if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
switch (opt) list[nservice++] = aresid ;
{ unsigned int l[graph.mlen] ;
case 'r' : if (RELOAD) log_usage(usage_start) ; RELOAD = 1 ; SIG = "-r" ; break ; unsigned int c = 0 ;
case 'R' : if (RELOAD) log_usage(usage_start) ; RELOAD = 2 ; SIG = "-u" ; break ;
default : log_usage(usage_start) ; /** find dependencies of the service from the graph, do it recursively */
} c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 0, 1) ;
}
argc -= l.ind ; argv += l.ind ; /** 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") ; graph_free_all(&graph) ;
/** 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") ;
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++) sig[0] = "-wU" ;
{ sig[1] = "-ru" ;
char const *name = *argv ; sig[2] = 0 ;
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) ;
}
}
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++) if (!svc_send(argv, argc, sig, siglen, info))
{ log_dieu(LOG_EXIT_SYS, "send -wU -ru signal") ;
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 (obstr_equal(name,SS_MASTER + 1)) goto append ; } else if (FLAGS_ISSET(flag, STATE_FLAGS_TORESTART)) {
if (!pres->disen) sig[0] = "-wD" ;
log_die(LOG_EXIT_USER,"service: ",name," was disabled, you can only stop it") ; sig[1] = "-d" ;
sig[2] = 0 ;
logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ; if (!svc_send(argv, argc, sig, siglen, info))
if (logname > 0 && (!resolve_cmp(&gares, string + pres->logassoc, DATA_SERVICE))) log_dieu(LOG_EXIT_SYS, "send -wD -d signal") ;
{
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 (cl) sig[0] = "-wU" ;
{ sig[1] = "-ru" ;
log_trace("sanitize classic services list...") ; sig[2] = 0 ;
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") ;
resolve_deep_free(DATA_SERVICE, &nclassic) ; if (!svc_send(argv, argc, sig, siglen, info))
} log_dieu(LOG_EXIT_SYS, "send -wU -u signal") ;
if (rc)
{ } else {
log_trace("sanitize atomic services list...") ;
if (!rc_sanitize(info,envp)) sig[0] = "-wU" ;
log_dieu(LOG_EXIT_SYS,"sanitize atomic services list") ; sig[1] = "-u" ;
if (!empty) sig[2] = 0 ;
{
log_trace("start atomic services list ...") ; if (!svc_send(argv, argc, sig, siglen, info))
if (!rc_start(info,&nrc,SIG,envp)) log_dieu(LOG_EXIT_SYS, "send -wU -u signal") ;
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) ;
} }
stralloc_free(&sares) ;
stralloc_free(&sasta) ;
resolve_deep_free(DATA_SERVICE, &gares) ;
resolve_free(wres) ;
return 0 ; return 0 ;
} }
...@@ -12,258 +12,151 @@ ...@@ -12,258 +12,151 @@
* except according to the terms contained in the LICENSE file./ * 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/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 <skalibs/genalloc.h>
#include <66/utils.h> #include <66/graph.h>
#include <66/constants.h> #include <66/config.h>
#include <66/db.h>
#include <66/svc.h>
#include <66/rc.h>
#include <66/ssexec.h> #include <66/ssexec.h>
#include <66/resolve.h>
#include <66/service.h>
#include <66/state.h> #include <66/state.h>
#include <66/svc.h>
#include <66/service.h>
static unsigned int DEADLINE = 0 ; int ssexec_stop(int argc, char const *const *argv, ssexec_t *info)
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)
{ {
log_flow() ; log_flow() ;
unsigned int reverse = 1 ; uint32_t flag = 0 ;
int r ; graph_t graph = GRAPH_ZERO ;
if (genalloc_len(resolve_service_t,&graph_unsup_cl.name)) unsigned int areslen = 0, list[SS_MAX_SERVICE], nservice = 0 ;
{ resolve_service_t ares[SS_MAX_SERVICE] ;
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 ;
}
int rc_down(ssexec_t *info, char const *const *envp) FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_ISSUPERVISED|STATE_FLAGS_WANTDOWN) ;
{
log_flow() ;
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) ; subgetopt l = SUBGETOPT_ZERO ;
if (r < 0 || !r)
{
log_warnusys("publish service graph") ;
goto err ;
}
if (!rc_send(info,&graph_rc.sorted,"-d",envp)) goto err ;
}
ss_resolve_graph_free(&graph_unsup_rc) ; for (;;) {
ss_resolve_graph_free(&graph_rc) ;
return 1 ;
err:
ss_resolve_graph_free(&graph_unsup_rc) ;
ss_resolve_graph_free(&graph_rc) ;
return 0 ;
}
int ssexec_stop(int argc, char const *const *argv,char const *const *envp,ssexec_t *info) int opt = getopt_args(argc,argv, ">" OPTS_STOP, &l) ;
{ if (opt == -1) break ;
// be sure that the global var are set correctly if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
DEADLINE = 0 ;
UNSUP = 0 ;
SIG = "-d" ;
if (info->timeout) DEADLINE = info->timeout ; switch (opt) {
int cl, rc, sigopt ; case 'u' :
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 ;
cl = rc = sigopt = 0 ; FLAGS_SET(flag, STATE_FLAGS_TOUNSUPERVISE|STATE_FLAGS_WANTUP) ;
break ;
{ case 'X' :
subgetopt l = SUBGETOPT_ZERO ;
for (;;) log_1_warn("deprecated option -- use 66-svctl -xd instead") ;
{ return 0 ;
int opt = getopt_args(argc,argv, ">" OPTS_STOP, &l) ;
if (opt == -1) break ; case 'K' :
if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
switch (opt) log_1_warn("deprecated option -- use 66-svctl -kd instead") ;
{ return 0 ;
case 'u' : UNSUP = 1 ; break ;
case 'X' : if (sigopt) log_usage(usage_stop) ; sigopt = 1 ; SIG = "-X" ; break ; default :
case 'K' : if (sigopt) log_usage(usage_stop) ; sigopt = 1 ; SIG = "-K" ; break ; log_usage(usage_stop) ;
default : log_usage(usage_stop) ;
} }
} }
argc -= l.ind ; argv += l.ind ; 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++) if (!graph.mlen)
{ log_die(LOG_EXIT_USER, "services selection is not available -- try first to install the corresponding frontend file") ;
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) ;
}
}
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++) int n = 0 ;
{ for (; n < argc ; n++) {
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 ;
if (!state_check(state,name)) log_die(LOG_EXIT_USER,name," : is not initialized") ; int aresid = service_resolve_array_search(ares, areslen, argv[n]) ;
else if (!state_read(&sta,state,name)) log_dieusys(LOG_EXIT_SYS,"read state file of: ",name) ; 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)) /** find requiredby of the service from the graph, do it recursively */
{ c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 1, 1) ;
if (pres->ndepends) goto append ;
else continue ;
}
/** logger cannot be unsupervised alone */ /** append to the list to deal with */
if (logname > 0 && (!resolve_cmp(&gares,string + pres->logassoc, DATA_SERVICE))) for (unsigned int pos = 0 ; pos < c ; pos++)
{ list[nservice + pos] = l[pos] ;
if (UNSUP) log_die(LOG_EXIT_SYS,"logger detected - unsupervise request is not allowed") ;
} nservice += c ;
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++;
}
} }
/** rc work */ if (FLAGS_ISSET(flag, STATE_FLAGS_TOUNSUPERVISE)) {
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") ;
} /** 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 */ int nargc = 4 + nservice ;
if (cl) char const *newargv[nargc] ;
{ unsigned int m = 0, n = 0 ;
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") ;
}
if (UNSUP) newargv[m++] = "66-svctl" ;
{ newargv[m++] = "-wD" ;
log_trace("send signal -an to scandir: ",info->scandir.s) ; newargv[m++] = "-d" ;
if (scandir_send_signal(info->scandir.s,"h") <= 0)
log_dieu(LOG_EXIT_SYS,"send signal to scandir: ", info->scandir.s) ; 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) ; service_resolve_array_free(ares, areslen) ;
resolve_deep_free(DATA_SERVICE, &gares) ;
graph_free_all(&graph) ;
return 0 ; return 0 ;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment