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

handle start/down of trees asynchronously except for dependency/requiredby. At least it build

parent 781c5663
No related branches found
No related tags found
No related merge requests found
...@@ -27,20 +27,61 @@ ...@@ -27,20 +27,61 @@
#include <oblibs/sastr.h> #include <oblibs/sastr.h>
#include <oblibs/obgetopt.h> #include <oblibs/obgetopt.h>
#include <oblibs/files.h> #include <oblibs/files.h>
#include <oblibs/graph.h>
#include <skalibs/types.h> #include <skalibs/types.h>
#include <skalibs/stralloc.h> #include <skalibs/stralloc.h>
#include <skalibs/djbunix.h> #include <skalibs/djbunix.h>
#include <skalibs/posixplz.h> #include <skalibs/posixplz.h>
#include <skalibs/tai.h>
#include <skalibs/selfpipe.h>
#include <skalibs/iopause.h>
#include <66/ssexec.h> #include <66/ssexec.h>
#include <66/constants.h> #include <66/constants.h>
#include <66/tree.h> #include <66/tree.h>
#include <66/utils.h>//scandir_ok #include <66/utils.h>//scandir_ok
#include <66/db.h> #include <66/db.h>
#include <66/graph.h>
#include <s6-rc/s6rc-servicedir.h> #include <s6-rc/s6rc-servicedir.h>
#define FLAGS_STARTING 1 // starting not really up
#define FLAGS_STOPPING 2 // stopping not really down
#define FLAGS_UP 3 // really up
#define FLAGS_DOWN 4 // really down
/*
#define FLAGS_BLOCK 5 // all deps are not up/down
#define FLAGS_UNBLOCK 6 // all deps up/down
#define FLAGS_FATAL 7 // process crashed
#define FLAGS_EXITED 8 // process exited
*/
/** return 1 if set, else 0*/
#define FLAGS_ISSET(has, want) \
((~(has) & (want)) == 0)
typedef struct pidvertex_s pidvertex_t, *pidvertex_t_ref ;
struct pidvertex_s
{
pid_t pid ;
unsigned int vertex ; // id at graph_hash_t struct
uint8_t state ;
int nedge ;
unsigned int *edge ; // array of id at graph_hash_t struct
} ;
#define PIDINDEX_ZERO { 0, 0, 0, 0, 0 }
static pidvertex_t *apidvertex ;
static unsigned int napid = 0 ;
static unsigned int npid = 0 ;
static int flag ;
static int flag_run ;
static void async(unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph) ;
static int unsupervise(ssexec_t *info, int what) ;
static inline unsigned int lookup (char const *const *table, char const *signal) static inline unsigned int lookup (char const *const *table, char const *signal)
{ {
log_flow() ; log_flow() ;
...@@ -54,113 +95,158 @@ static inline unsigned int parse_signal (char const *signal) ...@@ -54,113 +95,158 @@ static inline unsigned int parse_signal (char const *signal)
{ {
log_flow() ; log_flow() ;
static char const *const signal_table[] = static char const *const signal_table[] = {
{
"up", "up",
"down", "down",
"unsupervise", "unsupervise",
0 0
} ; } ;
unsigned int i = lookup(signal_table, signal) ; unsigned int i = lookup(signal_table, signal) ;
if (!signal_table[i]) log_usage(usage_all) ; if (!signal_table[i]) log_usage(usage_all) ;
return i ; return i ;
} }
int all_doit(ssexec_t *info, unsigned int what, char const *const *envp) static void redir_fd(void)
{ {
log_flow() ; log_flow() ;
int r ; int fd ;
while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0) {
stralloc salist = STRALLOC_ZERO ; if (fd >= 3)
char const *exclude[2] = { SS_LIVETREE_INIT, 0 } ; break ;
}
char ownerstr[UID_FMT] ; dup2 (fd,0) ;
size_t ownerlen = uid_fmt(ownerstr,info->owner) ; dup2 (fd,1) ;
ownerstr[ownerlen] = 0 ; dup2 (fd,2) ;
fd_close(fd) ;
char src[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1 + SS_LIVETREE_INIT_LEN + 1] ; if (setsid() < 0)
auto_strings(src,info->live.s,SS_STATE,"/",ownerstr,"/",info->treename.s,"/",SS_LIVETREE_INIT) ; log_dieusys(LOG_EXIT_SYS,"setsid") ;
r = scan_mode(src,S_IFREG) ; if ((chdir("/")) < 0)
if (r == -1) log_die(LOG_EXIT_SYS,src," conflicted format") ; log_dieusys(LOG_EXIT_SYS,"chdir") ;
if (!r) {
log_warn ("uninitialized tree: ", info->treename.s) ; ioctl(0,TIOCSCTTY,1) ;
goto freed ;
} umask(022) ;
}
src[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len] = 0 ;
if (!sastr_dir_get(&salist,src,exclude,S_IFREG)) static int doit(ssexec_t *info, char const *treename, unsigned int what)
log_dieusys(LOG_EXIT_SYS,"get contents of directory: ",src) ; {
log_flow() ;
int r, e = 1 ;
if (salist.len)
{ {
size_t pos = 0, len = sastr_len(&salist) ; info->treename.len = 0 ;
int n = what == 2 ? 3 : 2 ;
int nargc = n + len ;
char const *newargv[nargc] ;
unsigned int m = 0 ;
newargv[m++] = "fake_name" ; if (!auto_stra(&info->treename, treename))
if (what == 2) log_die_nomem("stralloc") ;
newargv[m++] = "-u" ;
FOREACH_SASTR(&salist,pos) { info->tree.len = 0 ;
newargv[m++] = salist.s + pos ; if (!auto_stra(&info->tree, treename))
} log_die_nomem("stralloc") ;
r = tree_sethome(info) ;
if (r <= 0)
log_warnu_return(LOG_EXIT_ONE, "find tree: ", info->treename.s) ;
if (!tree_get_permissions(info->tree.s, info->owner))
log_warn_return(LOG_EXIT_ONE, "You're not allowed to use the tree: ", info->tree.s) ;
}
newargv[m++] = 0 ; if (!tree_isinitialized(info->base.s, info->treename.s)) {
if (!what) { if (!what) {
if (ssexec_start(nargc,newargv,envp,info)) int nargc = 3 ;
goto err ; char const *newargv[nargc] ;
unsigned int m = 0 ;
newargv[m++] = "fake_name" ;
newargv[m++] = "b" ;
newargv[m++] = 0 ;
if (ssexec_init(nargc, newargv, (char const *const *)environ, info))
log_warnu_return(LOG_EXIT_ONE, "initiate services of tree: ", info->treename.s) ;
log_trace("reload scandir: ", info->scandir.s) ;
if (scandir_send_signal(info->scandir.s, "h") <= 0)
log_warnu_return(LOG_EXIT_ONE, "reload scandir: ", info->scandir.s) ;
} else { } else {
if (ssexec_stop(nargc,newargv,envp,info)) log_warn ("uninitialized tree: ", info->treename.s) ;
goto err ; goto freed ;
} }
} }
else
log_info("Empty tree: ",info->treename.s," -- nothing to do") ;
freed: if (what == 2) {
stralloc_free(&salist) ;
return 1 ;
err:
stralloc_free(&salist) ;
return 0 ;
}
static void all_redir_fd(void) if (unsupervise(info, what))
{ goto err ;
log_flow() ;
int fd ; } else {
while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0)
{
if (fd >= 3) break ;
}
dup2 (fd,0) ;
dup2 (fd,1) ;
dup2 (fd,2) ;
fd_close(fd) ;
if (setsid() < 0) char const *exclude[1] = { 0 } ;
log_dieusys(LOG_EXIT_SYS,"setsid") ; char ownerstr[UID_FMT] ;
size_t ownerlen = uid_fmt(ownerstr, info->owner) ;
ownerstr[ownerlen] = 0 ;
if ((chdir("/")) < 0) stralloc salist = STRALLOC_ZERO ;
log_dieusys(LOG_EXIT_SYS,"chdir") ;
ioctl(0,TIOCSCTTY,1) ; char src[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ;
umask(022) ; auto_strings(src, info->live.s, SS_STATE, "/", ownerstr, "/", info->treename.s) ;
if (!sastr_dir_get(&salist, src, exclude, S_IFREG))
log_warnusys_return(LOG_EXIT_ONE, "get contents of directory: ", src) ;
if (salist.len) {
size_t pos = 0, len = sastr_len(&salist) ;
int n = what == 2 ? 3 : 2 ;
int nargc = n + len ;
char const *newargv[nargc] ;
unsigned int m = 0 ;
newargv[m++] = "fake_name" ;
if (what == 2)
newargv[m++] = "-u" ;
FOREACH_SASTR(&salist, pos)
newargv[m++] = salist.s + pos ;
newargv[m++] = 0 ;
if (!what) {
if (ssexec_start(nargc, newargv, (char const *const *)environ, info))
goto err ;
} else {
if (ssexec_stop(nargc, newargv, (char const *const *)environ, info))
goto err ;
}
} else log_info("Empty tree: ", info->treename.s, " -- nothing to do") ;
stralloc_free(&salist) ;
}
freed:
e = 0 ;
err:
return e ;
} }
void all_unsupervise(ssexec_t *info, char const *const *envp,int what) static int unsupervise(ssexec_t *info, int what)
{ {
log_flow() ; log_flow() ;
...@@ -168,75 +254,305 @@ void all_unsupervise(ssexec_t *info, char const *const *envp,int what) ...@@ -168,75 +254,305 @@ void all_unsupervise(ssexec_t *info, char const *const *envp,int what)
char const *exclude[1] = { 0 } ; char const *exclude[1] = { 0 } ;
char ownerstr[UID_FMT] ; char ownerstr[UID_FMT] ;
size_t ownerlen = uid_fmt(ownerstr,info->owner) ; size_t ownerlen = uid_fmt(ownerstr, info->owner) ;
ownerstr[ownerlen] = 0 ; ownerstr[ownerlen] = 0 ;
stralloc salist = STRALLOC_ZERO ; stralloc salist = STRALLOC_ZERO ;
/** set what we need */ /** set what we need */
char prefix[info->treename.len + 2] ; char prefix[info->treename.len + 2] ;
auto_strings(prefix,info->treename.s,"-") ; auto_strings(prefix, info->treename.s, "-") ;
char livestate[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ; char livestate[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ;
auto_strings(livestate,info->live.s,SS_STATE + 1,"/",ownerstr,"/",info->treename.s) ; auto_strings(livestate, info->live.s, SS_STATE + 1, "/", ownerstr, "/", info->treename.s) ;
/** bring down service */ /** bring down service */
if (!all_doit(info,what,envp)) if (all_doit(info, info->treename.s, what))
log_warnusys("stop services") ; log_warnusys("stop services") ;
if (db_find_compiled_state(info->livetree.s,info->treename.s) >=0) if (db_find_compiled_state(info->livetree.s, info->treename.s) >=0) {
{
salist.len = 0 ; salist.len = 0 ;
char livetree[newlen + info->treename.len + SS_SVDIRS_LEN + 1] ; char livetree[newlen + info->treename.len + SS_SVDIRS_LEN + 1] ;
auto_strings(livetree,info->livetree.s,"/",info->treename.s,SS_SVDIRS) ; auto_strings(livetree, info->livetree.s, "/", info->treename.s, SS_SVDIRS) ;
if (!sastr_dir_get(&salist,livetree,exclude,S_IFDIR)) log_dieusys(LOG_EXIT_SYS,"get service list at: ",livetree) ; if (!sastr_dir_get(&salist,livetree,exclude,S_IFDIR))
log_warnusys_return(LOG_EXIT_ONE, "get service list at: ", livetree) ;
livetree[newlen + info->treename.len] = 0 ; livetree[newlen + info->treename.len] = 0 ;
pos = 0 ; pos = 0 ;
FOREACH_SASTR(&salist,pos) { FOREACH_SASTR(&salist,pos) {
s6rc_servicedir_unsupervise(livetree,prefix,salist.s + pos,0) ; s6rc_servicedir_unsupervise(livetree, prefix, salist.s + pos, 0) ;
} }
char *realsym = realpath(livetree, 0) ; char *realsym = realpath(livetree, 0) ;
if (!realsym) if (!realsym)
log_dieusys(LOG_EXIT_SYS,"find realpath of: ",livetree) ; log_warnusys_return(LOG_EXIT_ONE, "find realpath of: ", livetree) ;
if (rm_rf(realsym) == -1) if (rm_rf(realsym) == -1)
log_dieusys(LOG_EXIT_SYS,"remove: ", realsym) ; log_warnusys_return(LOG_EXIT_ONE, "remove: ", realsym) ;
free(realsym) ; free(realsym) ;
if (rm_rf(livetree) == -1) if (rm_rf(livetree) == -1)
log_dieusys(LOG_EXIT_SYS,"remove: ", livetree) ; log_warnusys_return(LOG_EXIT_ONE, "remove: ", livetree) ;
/** remove the symlink itself */ /** remove the symlink itself */
unlink_void(livetree) ; unlink_void(livetree) ;
} }
if (scandir_send_signal(info->scandir.s,"h") <= 0) if (scandir_send_signal(info->scandir.s,"h") <= 0)
log_dieusys(LOG_EXIT_SYS,"reload scandir: ",info->scandir.s) ; log_warnusys_return(LOG_EXIT_ONE, "reload scandir: ", info->scandir.s) ;
/** remove /run/66/state/uid/treename directory */ /** remove /run/66/state/uid/treename directory */
log_trace("delete: ",livestate,"..." ) ; log_trace("delete: ", livestate, "..." ) ;
if (rm_rf(livestate) < 0) if (rm_rf(livestate) < 0)
log_dieusys(LOG_EXIT_SYS,"delete ",livestate) ; log_warnusys_return(LOG_EXIT_ONE, "delete ", livestate) ;
log_info("Unsupervised successfully tree: ",info->treename.s) ; log_info("Unsupervised successfully tree: ", info->treename.s) ;
stralloc_free(&salist) ; stralloc_free(&salist) ;
return 0 ;
} }
int ssexec_all(int argc, char const *const *argv,char const *const *envp,ssexec_t *info) static pidvertex_t pidvertex_init(unsigned int len)
{ {
log_flow() ;
pidvertex_t pidv = PIDINDEX_ZERO ;
pidv.edge = (unsigned int *)malloc(len*sizeof(unsigned int)) ;
graph_array_init_single(pidv.edge, len) ;
return pidv ;
}
static void pidvertex_free(pidvertex_t *pidv)
{
free(pidv->edge) ;
}
static void pidvertex_init_array(pidvertex_t *apidvertex, graph_t *g, unsigned int *list, unsigned int count, ssexec_t *info, uint8_t requiredby)
{
log_flow() ;
int r = -1 ;
size_t pos = 0 ;
for (; pos < count ; pos++) {
char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[list[pos]].vertex ;
pidvertex_t pidv = pidvertex_init(g->mlen) ;
int r, what, shut = 0, fd ; pidv.nedge = graph_matrix_get_edge_g_sorted_list(pidv.edge, g, name, requiredby) ;
size_t statesize, pos = 0 ; if (pidv.nedge < 0)
log_dieu(LOG_EXIT_SYS,"get sorted ", requiredby ? "required by" : "dependency", " list of tree: ", name) ;
stralloc contents = STRALLOC_ZERO ; pidv.vertex = list[pos] ;
if (pidv.vertex < 0)
log_dieu(LOG_EXIT_SYS, "get vertex id -- please make a bug report") ;
r = tree_isinitialized(info->base.s, name) ;
if (r < 0)
log_dieu(LOG_EXIT_SYS, "read resolve file of tree: ", name) ;
if (r)
pidv.state |= FLAGS_UP ;
else
pidv.state |= FLAGS_DOWN ;
apidvertex[pos] = pidv ;
}
}
static void pidvertex_array_free(pidvertex_t *apidvertex, unsigned int len)
{
log_flow() ;
size_t pos = 0 ;
for(; pos < len ; pos++)
pidvertex_free(&apidvertex[pos]) ;
}
static int pidvertex_get_id(pidvertex_t *apidvertex, unsigned int id)
{
log_flow() ;
unsigned int pos = 0 ;
for (; pos < napid ; pos++) {
if (apidvertex[pos].vertex == id)
return (unsigned int) pos ;
}
return -1 ;
}
static void async_deps(unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph)
{
log_flow() ;
unsigned int pos = 0 ;
while (apidvertex[i].nedge) {
/** TODO: the pidvertex_get_id() function make a loop
* through the apidvertex array to find the corresponding
* index of the edge at the apidvertex array.
* This is clearly a waste of time and need to be optimized. */
unsigned int id = pidvertex_get_id(apidvertex, apidvertex[i].edge[pos]) ;
if (id < 0)
log_dieu(LOG_EXIT_SYS, "get apidvertex id -- please make a bug report") ;
async(id, what, info, graph) ;
apidvertex[i].nedge-- ;
pos++ ;
}
}
static void async(unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph)
{
/**
* @i: apidvertex array index
* */
log_flow() ;
int r ;
pid_t pid ;
char *treename = graph->data.s + genalloc_s(graph_hash_t,&graph->hash)[apidvertex[i].vertex].vertex ;
if (FLAGS_ISSET(apidvertex[i].state, flag) || FLAGS_ISSET(apidvertex[i].state, flag_run)) {
pid = fork() ;
if (pid < 0)
log_dieusys(LOG_EXIT_SYS, "fork") ;
if (!pid) {
if (!apidvertex[i].nedge) {
/** Mark as processing */
apidvertex[i].state |= flag_run ;
r = doit(info, treename, what) ;
_exit(r) ;
} else {
async_deps(i, what, info, graph) ;
}
}
apidvertex[i].pid = pid ;
} else {
log_trace("skipping: ", treename, " -- already ", FLAGS_ISSET(flag,FLAGS_DOWN) ? "down" : "up") ;
}
return ;
}
static int handle_signal(pidvertex_t *apidvertex)
{
log_flow() ;
int ok = 1 ;
for (;;) {
switch (selfpipe_read()) {
case -1 : log_warnusys_return(LOG_EXIT_ZERO,"selfpipe_read") ;
case 0 : return ok ;
case SIGCHLD :
for (;;) {
unsigned int j = 0 ;
int wstat ;
pid_t r = wait_nohang(&wstat) ;
if (r < 0) {
if (errno = ECHILD)
break ;
else
log_dieusys(LOG_EXIT_SYS,"wait for children") ;
} else if (!r) break ;
for (; j < npid ; j++)
if (apidvertex[j].pid == r)
break ;
if (j < npid) {
if (!WIFSIGNALED(wstat) && !WEXITSTATUS(wstat)) {
apidvertex[j].state &= ~flag & ~flag_run ;
} else {
ok = 0 ;
apidvertex[j].state &= ~flag & ~flag_run ;
}
apidvertex[j] = apidvertex[--npid] ;
}
}
break ;
case SIGTERM :
case SIGINT :
log_warn("received SIGINT, aborting service transition") ;
break ;
default : log_warn("unexpected data in selfpipe") ;
}
}
return ok ;
}
static int waitit(int spfd, pidvertex_t *apidvertex, graph_t *graph, unsigned int what, tain *deadline, ssexec_t *info)
{
iopause_fd x = { .fd = spfd, .events = IOPAUSE_READ } ;
unsigned int e = 1, pos = 0 ;
int r ;
npid = napid ;
for (; pos < npid ; pos++)
async(pos, what, info, graph) ;
while (npid) {
r = iopause_g(&x, 1, deadline) ;
if (r < 0)
log_dieusys(LOG_EXIT_SYS, "iopause") ;
if (!r)
log_die(LOG_EXIT_SYS,"time out") ;
if (!handle_signal(apidvertex))
e = 0 ;
}
return e ;
}
int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec_t *info)
{
int r, shut = 0, fd ;
tain deadline ;
unsigned int what ;
uint8_t requiredby = 0 ;
graph_t graph = GRAPH_ZERO ;
{ {
subgetopt l = SUBGETOPT_ZERO ; subgetopt l = SUBGETOPT_ZERO ;
...@@ -257,148 +573,125 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp,ssexec_ ...@@ -257,148 +573,125 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp,ssexec_
if (argc != 1) log_usage(usage_all) ; if (argc != 1) log_usage(usage_all) ;
if (info->timeout)
tain_from_millisecs(&deadline, info->timeout) ;
else
deadline = tain_infinite_relative ;
what = parse_signal(*argv) ; what = parse_signal(*argv) ;
if ((scandir_ok(info->scandir.s)) <= 0) if (what) {
log_die(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ;
char ste[info->base.len + SS_SYSTEM_LEN + SS_STATE_LEN + 1] ; requiredby = 1 ;
auto_strings(ste,info->base.s,SS_SYSTEM,SS_STATE) ; flag = FLAGS_UP ;
flag_run = FLAGS_STOPPING ;
r = scan_mode(ste,S_IFREG) ; } else {
if (r < 0) log_die(LOG_EXIT_SYS,"conflict format for: ",ste) ;
if (!r) log_dieusys(LOG_EXIT_SYS,"find: ",ste) ;
/** only one tree?*/ flag = FLAGS_DOWN ;
if (info->treename.len) flag_run = FLAGS_STARTING ;
{
if (!auto_stra(&contents,info->treename.s))
log_die_nomem("stralloc") ;
} }
else
{
statesize = file_get_size(ste) ;
r = openreadfileclose(ste,&contents,statesize) ; if ((scandir_ok(info->scandir.s)) <= 0)
if(!r) log_dieusys(LOG_EXIT_SYS,"open: ", ste) ; log_die(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ;
/** ensure that we have an empty line at the end of the string*/ if (!graph_build_g(&graph, info->base.s, info->treename.s, DATA_TREE))
if (!stralloc_cats(&contents,"\n") || log_dieu(LOG_EXIT_SYS,"build the graph") ;
!stralloc_0(&contents)) log_die_nomem("stralloc") ;
if (!sastr_clean_element(&contents)) { /** initialize and allocate apidvertex array */
log_info("nothing to do") ;
goto end ;
}
} pidvertex_t apidv[graph.mlen] ;
if (shut) apidvertex = apidv ;
{
pid_t dpid ;
int wstat = 0 ;
dpid = fork() ; /** only on tree */
if (info->treename.len) {
if (dpid < 0) log_dieusys(LOG_EXIT_SYS,"fork") ; unsigned int *alist ;
else if (dpid > 0)
{
if (waitpid_nointr(dpid,&wstat, 0) < 0)
log_dieusys(LOG_EXIT_SYS,"wait for child") ;
if (wstat) alist = (unsigned int *)malloc(graph.mlen*sizeof(unsigned int)) ;
log_die(LOG_EXIT_SYS,"child fail") ;
goto end ; graph_array_init_single(alist, graph.mlen) ;
}
else all_redir_fd() ;
}
/** Down/unsupervise process? reverse in that case to respect tree start order*/ napid = graph_matrix_get_edge_g_sorted_list(alist, &graph, info->treename.s, requiredby) ;
if (what)
if (!sastr_reverse(&contents)) log_dieu(LOG_EXIT_SYS,"reserve tree order") ;
FOREACH_SASTR(&contents,pos) { if (napid < 0)
log_dieu(LOG_EXIT_SYS, "get ", requiredby ? "required" : "dependencies", " sorted list of: ", info->treename.s) ;
info->treename.len = 0 ; alist[napid++] = (unsigned int)graph_hash_vertex_get_id(&graph, info->treename.s) ;
if (!auto_stra(&info->treename,contents.s + pos)) pidvertex_init_array(apidvertex, &graph, alist, napid, info, requiredby) ;
log_die_nomem("stralloc") ;
info->tree.len = 0 ; free(alist) ;
if (!auto_stra(&info->tree,contents.s + pos)) } else {
log_die_nomem("stralloc") ;
/**
*
*
*
*
*
*
*
* Attention ici avec le nouveau format de tree_sethome()
*
*
*
*
*
*
*
*
*
*
*
*
* */
r = tree_sethome(info) ;
if (r <= 0) log_dieusys(LOG_EXIT_SYS,"find tree: ", info->treename.s) ;
if (!tree_get_permissions(info->tree.s,info->owner)) napid = graph.sort_count ;
log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->tree.s) ;
if (!what) pidvertex_init_array(apidvertex, &graph, graph.sort, graph.sort_count, info, requiredby) ;
{ }
int nargc = 3 ;
char const *newargv[nargc] ;
unsigned int m = 0 ;
newargv[m++] = "fake_name" ; if (shut) {
newargv[m++] = "b" ;
newargv[m++] = 0 ; pid_t pid ;
int wstat = 0 ;
if (ssexec_init(nargc,newargv,envp,info)) pid = fork() ;
log_dieu(LOG_EXIT_SYS,"initiate services of tree: ",info->treename.s) ;
log_trace("reload scandir: ",info->scandir.s) ; if (pid < 0)
if (scandir_send_signal(info->scandir.s,"h") <= 0) log_dieusys(LOG_EXIT_SYS,"fork") ;
log_dieusys(LOG_EXIT_SYS,"reload scandir: ",info->scandir.s) ;
}
if (what < 2) { if (!pid) {
if (!all_doit(info,what,envp)) redir_fd() ;
log_dieu(LOG_EXIT_SYS,(what) ? "start" : "stop" , " services of tree: ",info->treename.s) ;
} else { } else {
all_unsupervise(info,envp,what) ; if (waitpid_nointr(pid,&wstat, 0) < 0)
log_dieusys(LOG_EXIT_SYS,"wait for child") ;
if (wstat)
log_die(LOG_EXIT_SYS,"child fail") ;
r = 1 ;
goto end ;
} }
} }
tain_now_set_stopwatch_g() ;
tain_add_g(&deadline, &deadline) ;
int spfd = selfpipe_init() ;
if (spfd < 0)
log_dieusys(LOG_EXIT_SYS, "selfpipe_init") ;
if (!selfpipe_trap(SIGCHLD) ||
!selfpipe_trap(SIGINT) ||
!selfpipe_trap(SIGTERM))
log_dieusys(LOG_EXIT_SYS, "selfpipe_trap") ;
r = waitit(spfd, apidvertex, &graph, what, &deadline, info) ;
end: end:
if (shut) selfpipe_finish() ;
{
if (shut) {
while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0) while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0)
{ if (fd >= 3)
if (fd >= 3) break ; break ;
}
dup2 (fd,0) ; dup2 (fd,0) ;
dup2 (fd,1) ; dup2 (fd,1) ;
dup2 (fd,2) ; dup2 (fd,2) ;
fd_close(fd) ; fd_close(fd) ;
} }
stralloc_free(&contents) ; graph_free_all(&graph) ;
pidvertex_array_free(apidvertex, napid) ;
return 0 ;
return (!r) ? 111 : 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