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

Merge branch 'async' into dev

parents b553427a 78da40a8
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,8 @@
#define SS_TREE_LEN (sizeof SS_TREE - 1)
#define SS_NOTIFICATION "notification-fd"
#define SS_NOTIFICATION_LEN (sizeof SS_NOTIFICATION - 1)
#define SS_MAXDEATHTALLY "max-death-tally"
#define SS_MAXDEATHTALLY_LEN (sizeof SS_MAXDEATHTALLY - 1)
/**tree dir*/
#define SS_RULES "/rules"
#define SS_RULES_LEN (sizeof SS_RULES - 1)
......
......@@ -23,7 +23,7 @@
#include <66/resolve.h>
#include <66/ssexec.h>
typedef struct ss_resolve_sig_s ss_resolve_sig_t, *ss_resovle_sig_t_ref ;
typedef struct ss_resolve_sig_s ss_resolve_sig_t, *ss_resolve_sig_t_ref ;
struct ss_resolve_sig_s
{
ss_resolve_t res ;
......@@ -77,7 +77,7 @@ enum sigactions_e
extern int svc_switch_to(ssexec_t *info,unsigned int where) ;
extern int svc_init(ssexec_t *info,char const *src, genalloc *ga) ;
extern int svc_init_pipe(ftrigr_t *fifo,genalloc *gasv) ;
extern int svc_init_pipe(ftrigr_t *fifo,genalloc *gasv,tain_t *deadline) ;
extern int svc_send(ssexec_t *info,genalloc *ga,char const *sig,char const *const *envp) ;
extern int svc_unsupervise(ssexec_t *info,genalloc *ga,char const *sig,char const *const *envp) ;
......
......@@ -100,7 +100,7 @@ char const *help_stop =
" -K: kill the service(s) and keep it down\n"
;
char const *usage_svctl = "66-svctl [ -h ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -n death ] [ -u | U | d | D | r | R | K | X ] service(s)" ;
char const *usage_svctl = "66-svctl [ -h ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -n death ] [ -u | d | r | K | X ] service(s)" ;
char const *help_svctl =
"66-svctl <options> tree\n"
......@@ -113,11 +113,8 @@ char const *help_svctl =
" -T: service timeout\n"
" -n: number of death\n"
" -u: bring up the service(s)\n"
" -U: really up\n"
" -d: bring down the service(s)\n"
" -D: really down\n"
" -r: reload\n"
" -R: reload and really up\n"
" -X: bring down the service(s) and the kill his supervisor\n"
" -K: kill the service(s) and keep it down\n"
;
......
......@@ -13,7 +13,7 @@
*/
#include <string.h>
//#include <stdio.h>
#include <stdio.h>
#include <oblibs/obgetopt.h>
#include <oblibs/error2.h>
......@@ -35,7 +35,7 @@
static int empty = 0 ;
static unsigned int RELOAD = 0 ;
static unsigned int DEADLINE = 0 ;
static char *SIG = "-U" ;
static char *SIG = "-u" ;
static genalloc nclassic = GENALLOC_ZERO ; //resolve_t type
static genalloc nrc = GENALLOC_ZERO ; //resolve_t type
......@@ -63,7 +63,7 @@ int svc_sanitize(ssexec_t *info, char const *const *envp)
VERBO1 strerr_warnwu1sys("publish service graph") ;
goto err ;
}
if (!svc_unsupervise(info,&graph_reload_cl.sorted,"-D",envp)) goto err ;
if (!svc_unsupervise(info,&graph_reload_cl.sorted,"-d",envp)) goto err ;
genalloc_reverse(ss_resolve_t,&graph_reload_cl.sorted) ;
if (!svc_init(info,sares.s,&graph_reload_cl.sorted))
{
......@@ -202,7 +202,7 @@ int ssexec_start(int argc, char const *const *argv,char const *const *envp,ssexe
// be sure that the global var are set correctly
RELOAD = 0 ;
DEADLINE = 0 ;
SIG = "-U" ;
SIG = "-u" ;
if (info->timeout) DEADLINE = info->timeout ;
......@@ -228,7 +228,7 @@ int ssexec_start(int argc, char const *const *argv,char const *const *envp,ssexe
switch (opt)
{
case 'r' : if (RELOAD) exitusage(usage_start) ; RELOAD = 1 ; SIG = "-r" ; break ;
case 'R' : if (RELOAD) exitusage(usage_start) ; RELOAD = 2 ; SIG = "-U" ; break ;
case 'R' : if (RELOAD) exitusage(usage_start) ; RELOAD = 2 ; SIG = "-u" ; break ;
default : exitusage(usage_start) ;
}
}
......
......@@ -32,7 +32,7 @@
static unsigned int DEADLINE = 0 ;
static unsigned int UNSUP = 0 ;
static char *SIG = "-D" ;
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 ;
......@@ -115,7 +115,7 @@ int ssexec_stop(int argc, char const *const *argv,char const *const *envp,ssexec
// be sure that the global var are set correctly
DEADLINE = 0 ;
UNSUP = 0 ;
SIG = "-D" ;
SIG = "-d" ;
if (info->timeout) DEADLINE = info->timeout ;
......
......@@ -18,6 +18,7 @@
#include <signal.h>
#include <unistd.h>//access
//#include <stdio.h>
//#include <stdlib.h>
#include <oblibs/obgetopt.h>
#include <oblibs/error2.h>
......@@ -35,6 +36,7 @@
#include <s6/s6-supervise.h>//s6_svstatus_t
#include <s6/ftrigr.h>
#include <66/utils.h>
#include <66/constants.h>
#include <66/svc.h>
......@@ -43,7 +45,18 @@
#include <66/state.h>
unsigned int SV_DEADLINE = 3000 ;
unsigned int DEATHSV = 10 ;
unsigned int DEATHSV = 5 ;
ftrigr_t fifo = FTRIGR_ZERO ;
typedef struct pidindex_s pidindex_t ;
struct pidindex_s
{
ss_resolve_sig_t_ref sv ;
pid_t pid ;
} ;
static pidindex_t *pidindex ;
static unsigned int npids = 0 ;
static int read_file (char const *file, char *buf, size_t n)
{
......@@ -134,153 +147,313 @@ static const uint8_t chtenum[128] =
* We let s6-supervise make what it need to do with this file but
* we take the same number to set the sv_signal.death value
* accepted for every daemon before exiting if the SIGNAL is not reached.
* If this file doesn't exist a number of 3 death (death -> number
* If this file doesn't exist a number of 5 death (death -> number
* of wrong signal received) is set by default.
* This ndeath value can be set on commandline by the -n options.
*
* In all case the loop is broken to avoids infinite iopause
*
* The notication-fd file is used as the original one. If the file
* doesn't exist and the SIGNAL is U , we change SIGNAL to u and warn
* the user about it.
*
* In the send_svc function a reached timeout is not an absolute error
* because we can have a notification-file in the servicedirs of the
* service with a deamon which doesn't support readiness notification.
* In this case, we send U and only receive u as event, the daemon is
* running but not notified by the daemon itself.
* We accept this case as an "half" success. We exit with success but
* the user is warned about the state. */
* exist and the SIGNAL is u , we change SIGNAL to U.
*/
/**@Return 0 on success
* @Return 1 on if signal is not complete (e.g. want U receive only u)
* @Return 2 on fail
* @Return 3 for PERMANENT failure */
int handle_case(stralloc *sa, ss_resolve_sig_t *sv_signal)
int handle_case(stralloc *sa, ss_resolve_sig_t *svc)
{
int p, h, err ;
unsigned int state, i = 0 ;
state = sv_signal->sig ;
state = svc->sig ;
err = 2 ;
for (;i < sa->len ; i++)
{
p = chtenum[(unsigned char)sa->s[i]] ;
unsigned char action = actions[state][p] ;
switch (action)
{
case GOTIT:
h = handle_signal_svc(sv_signal) ;
h = handle_signal_svc(svc) ;
if (!h)
{
err = 1 ;
err = 0 ;
break ;
}
err = 0 ;
return err ;
case WAIT:
err = 1 ;
return 1 ;
case WAIT: err = 0 ;
break ;
case DEAD:
err = 2 ;
return err ;
case DONE:
err = 0 ;
return err ;
case PERM:
err = 3 ;
return err ;
case DEAD: return 2 ;
case DONE: return 1 ;
case PERM: return 3 ;
default:
VERBO3 strerr_warnw1x("invalid state, make a bug report");
err = 2 ;
return err ;
return 2 ;
}
}
return err ;
}
static int handle_signal_pipe(ss_resolve_sig_t *svc)
static void write_state(ss_resolve_sig_t *svc)
{
char *sv = svc->res.sa.s + svc->res.runat ;
ss_state_t sta = STATE_ZERO ;
char const *state = svc->res.sa.s + svc->res.state ;
char const *sv = svc->res.sa.s + svc->res.name ;
if (svc->sig <= 3)
{
if (svc->state <= 1)
{
ss_state_setflag(&sta,SS_FLAGS_PID,svc->pid) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
}
else
{
ss_state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
}
else
{
if (svc->state <=1)
{
ss_state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
else
{
ss_state_setflag(&sta,SS_FLAGS_PID,svc->pid) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
}
}
ss_state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ;
VERBO2 strerr_warni2x("Write state file of: ",sv) ;
if (!ss_state_write(&sta,state,sv))
{
VERBO1 strerr_warnwu2sys("write state file of: ",sv) ;
}
}
static int announce(ss_resolve_sig_t *svc)
{
int r = svc->state ;
char *sv = svc->res.sa.s + svc->res.name ;
/** special case time out reached or number execeeded,
* last check with s6-svstat framboise*/
if (r == 0 || r == 4)
{
int e = handle_signal_svc(svc) ;
if (!e) r = r == 0 ? 2 : 4 ;
else r = r == 0 ? 0 : 1 ;
svc->state = r ;
}
switch(r)
{
case 0: VERBO1 strerr_warni4x(sv," is ",(svc->sig > 3) ? "down" : "up"," but not notified by the daemon itself") ;
break ;
case 1: VERBO1 strerr_warni4x(sv,": ",(svc->sig > 3) ? "stopped" : "started"," successfully") ;
break ;
case 2: VERBO1 strerr_warnwu2x((svc->sig > 3) ? "stop " : "start ", sv) ;
break ;
case 3: VERBO1 strerr_warnw3x(sv," report permanent failure -- unable to ",(svc->sig > 1) ? "stop" : "start") ;
break ;
case 4: VERBO1 strerr_warnwu3x((svc->sig > 3) ? "stop: " : "start: ",sv, ": number of try exceeded") ;
break ;
case-1: VERBO1 strerr_warnw3x("unexpected data in state file of: ",sv," -- please make a bug report") ;
break ;
}
return r ;
}
static inline void kill_all (void)
{
unsigned int j = npids ;
while (j--) kill(pidindex[j].pid, SIGTERM) ;
}
static int handle_signal_pipe(genalloc *gakeep)
{
int ok = 1 ;
for (;;)
{
switch (selfpipe_read())
{
case -1 : strerr_warnwu1sys("selfpipe_read") ; return 0 ;
case 0 : return 1 ;
case 0 : goto end ;
case SIGCHLD:
for (;;)
{
unsigned int j = 0 ;
int wstat ;
pid_t r = wait_nohang(&wstat) ;
if (r < 0)
if (errno = ECHILD) break ;
else strerr_diefu1sys(111,"wait for children") ;
else if (!r) break ;
for (; j < npids ; j++) if (pidindex[j].pid == r) break ;
if (j < npids)
{
ss_resolve_sig_t_ref sv = pidindex[j].sv ;
pidindex[j] = pidindex[--npids] ;
if (!WIFSIGNALED(wstat) && !WEXITSTATUS(wstat))
{
if (announce(sv) > 1) ok = 0 ;
write_state(sv) ;
}
else
{
ok = 0 ; announce(sv) ; write_state(sv) ;
}
}
}
break ;
case SIGTERM:
case SIGINT:
// TODO, little ugly for me
VERBO2 strerr_warnw1x("received SIGINT, aborting service transition") ;
if (svc->sig <= SIGRR)
s6_svc_writectl(sv, S6_SUPERVISE_CTLDIR, "d", 1) ;
return 0 ;
default : strerr_warn1x("unexpected data in selfpipe") ; return 0 ;
kill_all() ;
break ;
default : strerr_warn1x("unexpected data in selfpipe") ;
}
}
}
end:
return ok ;
static void announce(ss_resolve_sig_t *sv_signal)
}
static int compute_timeout(tain_t *start,tain_t *tsv)
{
int r = sv_signal->state ;
char *sv = sv_signal->res.sa.s + sv_signal->res.runat ;
if (r == 3) { VERBO2 strerr_warnw3x(sv," report permanent failure -- unable to ",(sv_signal->sig > 1) ? "stop" : "start") ; }
else if (r == 2) { VERBO2 strerr_warnwu2x((sv_signal->sig > 3) ? "stop " : "start ", sv) ; }
else if (r == 1) { VERBO2 strerr_warni4x(sv," is ",(sv_signal->sig > 3) ? "down" : "up"," but not notified by the daemon itself") ; }
else if (!r) { VERBO2 strerr_warni4x(sv,": ",(sv_signal->sig > 3) ? "stopped" : "started"," successfully") ; }
tain_t now ;
tain_t tpass ;
tain_now(&now) ;
tain_sub(&tpass,&now,start) ;
if (tain_less(tsv,&tpass)) return 0 ;
return 1 ;
}
int svc_listen(genalloc *gasv, ftrigr_t *fifo,int spfd,ss_resolve_sig_t *svc)
static void svc_listen_less(int state_val, int *state,unsigned int *did,unsigned int *loop,unsigned int pos)
{
(*state) = state_val ;
did[pos] = 1 ;
(*loop)--;
}
static void svc_listen(unsigned int nsv)
{
int r ;
stralloc sa = STRALLOC_ZERO ;
iopause_fd x[2] = { { .fd = ftrigr_fd(fifo), .events = IOPAUSE_READ } , { .fd = spfd, .events = IOPAUSE_READ, .revents = 0 } } ;
tain_t t ;
tain_now_g() ;
tain_add_g(&t,&svc->deadline) ;
VERBO3 strerr_warnt2x("start iopause for: ",svc->res.sa.s + svc->res.runat) ;
for(;;)
tain_t start ;
stralloc sa = STRALLOC_ZERO ;
iopause_fd x = { .fd = ftrigr_fd(&fifo), .events = IOPAUSE_READ } ;
ss_resolve_sig_t_ref svc ;
int *state = 0 ;
unsigned int *ndeath = 0, i, j ;
unsigned int did[nsv] ;
i = j = nsv ;
tain_now(&start) ;
tain_from_millisecs(&t,SV_DEADLINE) ;
tain_add_g(&t,&t) ;
while(i--)
did[i] = 0 ;
while(j)
{
r = ftrigr_checksa(fifo,svc->ids, &sa) ;
if (r < 0) { VERBO3 strerr_warnwu1sys("ftrigr_check") ; return 0 ; }
if (r)
{
svc->state = handle_case(&sa,svc) ;
if (!svc->state){ announce(svc) ; goto end ; }
else if (svc->state >= 2){ announce(svc) ; goto end ; }
}
if (!(svc->ndeath))
{
VERBO2 strerr_warnw2x("number of try exceeded for: ",svc->res.sa.s + svc->res.runat) ;
announce(svc) ;
goto end ;
}
r = iopause_g(x, 2, &t) ;
if (r < 0){ VERBO3 strerr_warnwu1sys("iopause") ; return 0 ; }
/** timeout is not a error , the iopause process did right */
else if (!r) { VERBO3 strerr_warnt2x("timed out reached for: ",svc->res.sa.s + svc->res.runat) ; announce(svc) ; break ; }
if (x[1].revents & IOPAUSE_READ) return handle_signal_pipe(svc) ? 1 : 0 ;
if (x[0].revents & IOPAUSE_READ)
r = iopause_g(&x, 1, &t) ;
if (r < 0) strerr_dief1sys(111,"listen iopause") ;
/** timeout is not a error , the iopause process did right*/
else if (!r) strerr_dief1sys(111,"listen time out") ;
if (x.revents & IOPAUSE_READ)
{
if (ftrigr_update(fifo) < 0){ VERBO3 strerr_warnwu1sys("ftrigr_update") ; return 0 ; }
svc->ndeath--;
i = 0 ;
if (ftrigr_update(&fifo) < 0) strerr_diefu1sys(111,"update fifo") ;
for (;i < nsv;i++)
{
if (did[i]) continue ;
svc = pidindex[i].sv ;
state = &svc->state ;
ndeath = &svc->ndeath ;
if (!compute_timeout(&start,&pidindex[i].sv->deadline))
svc_listen_less(0,state,did,&j,i) ;
sa.len = 0 ;
r = ftrigr_checksa(&fifo,svc->ids, &sa) ;
if (r < 0) { VERBO3 strerr_warnwu1sys("check fifo") ; goto end ; }
else if (r)
{
(*ndeath)-- ;
(*state) = handle_case(&sa,svc) ;
if (!(*ndeath)) svc_listen_less(4,state,did,&j,i) ;
if ((*state) >= 1) svc_listen_less(*state,state,did,&j,i) ;
}
}
}
}
end:
stralloc_free(&sa) ;
return svc->state ;
end:
stralloc_free(&sa) ;
}
/* @return 111 unable to control
* @return 100 "something is wrong with the S6_SUPERVISE_CTLDIR directory. errno reported
* @return 99 supervisor not listening */
static int svc_writectl(ss_resolve_sig_t *svc)
{
int r ;
char *sv = svc->res.sa.s + svc->res.runat ;
size_t siglen = strlen(svc->sigtosend) ;
VERBO2 strerr_warnt6x("send signal: ",svc->sigtosend," to: ", sv,"/",S6_SUPERVISE_CTLDIR) ;
r = s6_svc_writectl(sv, S6_SUPERVISE_CTLDIR, svc->sigtosend, siglen) ;
if (r == -1) return 111 ;
else if (r == -2) return 100 ;
else if (!r) return 99 ;
return 0 ;
}
static void svc_async(unsigned int i,unsigned int nsv)
{
int r ;
pid_t pid ;
pid = fork() ;
if (pid < 0) return ;
if (!pid)
{
r = svc_writectl(pidindex[i].sv) ;
_exit(r) ;
}
pidindex[npids].pid = pid ;
pidindex[npids++].sv = pidindex[i].sv ;
return ;
}
int doit (int spfd, genalloc *gakeep, tain_t *dead)
{
iopause_fd x = { .fd = spfd, .events = IOPAUSE_READ } ;
unsigned int nsv = genalloc_len(ss_resolve_sig_t,gakeep) ;
unsigned int i = 0 ;
int exitcode = 1 ;
pidindex_t pidindextable[nsv] ;
pidindex = pidindextable ;
/** keep the good order service declaration
* of the genalloc*/
while(i<nsv){
pidindex[i].sv = &genalloc_s(ss_resolve_sig_t,gakeep)[i] ;
pidindex[i].pid = 0 ;
i++ ;
}
i = 0 ;
while(i < nsv)
{
svc_async(i,nsv) ;
i++ ;
}
svc_listen(nsv) ;
while (npids)
{
int r = iopause_g(&x,1,dead) ;
if (r < 0) strerr_diefu1sys(111,"iopause") ;
if (!r) strerr_dief1x(111,"time out") ;
if (!handle_signal_pipe(gakeep)) exitcode = 0 ;
}
return exitcode ;
}
int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexec_t *info)
......@@ -288,12 +461,12 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
// be sure that the global var are set correctly
SV_DEADLINE = 3000 ;
DEATHSV = 10 ;
tain_t ttmain ;
DEATHSV = 5 ;
int e, isup, ret, r ;
int e, isup, r, ret = 1 ;
unsigned int death, tsv, reverse ;
int SIGNAL = -1 ;
tain_t ttmain ;
genalloc gakeep = GENALLOC_ZERO ; //type ss_resolve_sig
stralloc sares = STRALLOC_ZERO ;
......@@ -303,11 +476,9 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
char *sig = 0 ;
ftrigr_t fifo = FTRIGR_ZERO ;
s6_svstatus_t status = S6_SVSTATUS_ZERO ;
tsv = death = ret = reverse = 0 ;
tsv = death = reverse = 0 ;
//PROG = "66-svctl" ;
{
......@@ -315,20 +486,17 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
for (;;)
{
int opt = getopt_args(argc,argv, "n:udUDXrRK", &l) ;
int opt = getopt_args(argc,argv, "n:urdXK", &l) ;
if (opt == -1) break ;
if (opt == -2) strerr_dief1x(110,"options must be set first") ;
switch (opt)
{
case 'n' : if (!uint0_scan(l.arg, &death)) exitusage(usage_svctl) ; break ;
case 'u' : if (SIGNAL > 0) exitusage(usage_svctl) ; SIGNAL = SIGUP ; sig ="u" ; break ;
case 'U' : if (SIGNAL > 0) exitusage(usage_svctl) ; SIGNAL = SIGRUP ; sig = "uwU" ; break ;
case 'r' : if (SIGNAL > 0) ; SIGNAL = SIGR ; sig = "r" ; break ;
case 'R' : if (SIGNAL > 0) ; SIGNAL = SIGRR ; sig = "rwR" ; break ;
case 'd' : if (SIGNAL > 0) ; SIGNAL = SIGDOWN ; sig = "d" ; break ;
case 'D' : if (SIGNAL > 0) ; SIGNAL = SIGRDOWN ; sig = "dwD" ; break ;
case 'X' : if (SIGNAL > 0) ; SIGNAL = SIGX ; sig = "xd" ; break ;
case 'K' : if (SIGNAL > 0) ; SIGNAL = SIGRDOWN ; sig = "kd" ; break ;
case 'r' : if (SIGNAL > 0) exitusage(usage_svctl) ; SIGNAL = SIGR ; sig = "r" ; break ;
case 'd' : if (SIGNAL > 0) exitusage(usage_svctl) ; SIGNAL = SIGDOWN ; sig = "d" ; break ;
case 'X' : if (SIGNAL > 0) exitusage(usage_svctl) ; SIGNAL = SIGX ; sig = "xd" ; break ;
case 'K' : if (SIGNAL > 0) exitusage(usage_svctl) ; SIGNAL = SIGRDOWN ; sig = "kd" ; break ;
default : exitusage(usage_svctl) ;
}
......@@ -337,15 +505,10 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
}
if (argc < 1 || (SIGNAL < 0)) exitusage(usage_svctl) ;
if (info->timeout) tsv = info->timeout ;
if ((scandir_ok(info->scandir.s)) !=1 ) strerr_dief3sys(111,"scandir: ", info->scandir.s," is not running") ;
if (!ss_resolve_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) strerr_diefu1sys(111,"set revolve pointer to source") ;
if (SIGNAL > SIGRUP) reverse = 1 ;
for(;*argv;argv++)
{
char const *name = *argv ;
......@@ -355,7 +518,7 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
if (!ss_resolve_graph_build(&graph,&res,sares.s,reverse)) strerr_diefu1sys(111,"build services graph") ;
}
if (SIGNAL == SIGR || SIGNAL == SIGRR) reverse = 0 ;
if (SIGNAL == SIGR) reverse = 0 ;
r = ss_resolve_graph_publish(&graph,reverse) ;
if (r < 0) strerr_dief1x(111,"cyclic dependencies detected") ;
if (!r) strerr_diefu1sys(111,"publish service graph") ;
......@@ -368,7 +531,7 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
char *svok = string + sv_signal.res.runat ;
char *state = string + sv_signal.res.state ;
size_t svoklen = strlen(svok) ;
char file[svoklen + 16 + 1] ;
char file[svoklen + SS_NOTIFICATION_LEN + 1 + 1] ;
memcpy(file,svok,svoklen) ;
if (!ss_state_check(state,string + sv_signal.res.name)) strerr_dief2x(111,"unitialized service: ",string + sv_signal.res.name) ;
if (!ss_state_read(&sta,state,string + sv_signal.res.name)) strerr_diefu2sys(111,"read state of: ",string + sv_signal.res.name) ;
......@@ -376,7 +539,7 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
if (!s6_svstatus_read(svok,&status)) strerr_diefu2sys(111,"read status of: ",svok) ;
isup = status.pid && !status.flagfinishing ;
if (isup && (SIGNAL <= SIGRUP))
if (isup && (SIGNAL == SIGUP))
{
VERBO1 strerr_warni2x("Already up: ",string + sv_signal.res.name) ;
continue ;
......@@ -386,58 +549,38 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
VERBO1 strerr_warni2x("Already down: ",string + sv_signal.res.name) ;
continue ;
}
/*else if ((SIGNAL == SIGR) || (SIGNAL == SIGRR))
{
SIGNAL = SIGRUP ;
}*/
sv_signal.sigtosend = sig ;
sv_signal.sig = SIGNAL ;
sv_signal.sigtosend = sig ; sv_signal.sig = SIGNAL ;
/** notification-fd */
memcpy(file + svoklen,"/notification-fd",16) ;
file[svoklen + 16] = 0 ;
memcpy(file + svoklen,"/" SS_NOTIFICATION,SS_NOTIFICATION_LEN + 1) ;
file[svoklen + SS_NOTIFICATION_LEN + 1] = 0 ;
e = errno ;
errno = 0 ;
if (access(file, F_OK) < 0)
if (access(file, F_OK) < 0 && errno != ENOENT)
strerr_warnw1sys("conflicting format of file: " SS_NOTIFICATION) ;
else if (errno != ENOENT)
{
if (errno != ENOENT) strerr_diefu2sys(111, "access ", file) ;
if (SIGNAL == SIGRUP)
{
sv_signal.sig = SIGUP ;
sv_signal.sigtosend = "uwu" ;
VERBO1 strerr_warnw2x(file, " is not present - ignoring request for readiness notification") ;
}
if (SIGNAL == SIGRR)
{
sv_signal.sig = SIGR ;
sv_signal.sigtosend = "uwr" ;
VERBO1 strerr_warnw2x(file, " is not present - ignoring request for readiness notification") ;
}
if (SIGNAL == SIGRDOWN)
{
sv_signal.sig = SIGDOWN ;
sv_signal.sigtosend = "dwd" ;
VERBO1 strerr_warnw2x(file, " is not present - ignoring request for readiness notification") ;
}
if (!read_uint(file,&sv_signal.notify)) strerr_diefu2sys(111,"read: ",file) ;
if (SIGNAL == SIGUP)
{ sv_signal.sig = SIGRUP ; sv_signal.sigtosend = "uwU" ; }
else if (SIGNAL == SIGR)
{ sv_signal.sig = SIGRR ; sv_signal.sigtosend = "uwR" ; }
else if (SIGNAL == SIGDOWN)
{ sv_signal.sig = SIGRDOWN ; sv_signal.sigtosend = "dwD" ; }
}
else if (!read_uint(file,&sv_signal.notify)) strerr_diefu2sys(111,"read: ",file) ;
/** max-death-tally */
if (!death)
{
memcpy(file + svoklen,"/max-death-tally", 16) ;
file[svoklen + 16] = 0 ;
memcpy(file + svoklen,"/" SS_MAXDEATHTALLY, SS_MAXDEATHTALLY_LEN + 1) ;
file[svoklen + SS_MAXDEATHTALLY_LEN + 1] = 0 ;
errno = 0 ;
if (access(file, F_OK) < 0)
{
if (errno != ENOENT) strerr_diefu2sys(111, "access ", file) ;
}
if (errno == ENOENT)
{
sv_signal.ndeath = DEATHSV ;
}
else
{
if (!read_uint(file,&sv_signal.ndeath)) strerr_diefu2sys(111,"read: ",file) ;
......@@ -452,118 +595,55 @@ int ssexec_svctl(int argc, char const *const *argv,char const *const *envp,ssexe
else
{
/** timeout-{up/down} */
char *tm = NULL ;
unsigned int t ;
if (SIGNAL <= SIGR)
tm="/timeout-up" ;
else tm="/timeout-down" ;
errno = 0 ;
size_t tmlen = strlen(tm) ;
memcpy(file + svoklen,tm, tmlen) ;
file[svoklen + tmlen] = 0 ;
if (access(file, F_OK) < 0)
if (errno != ENOENT) strerr_diefu2sys(111, "access ", file) ;
if (errno == ENOENT)
tain_from_millisecs(&sv_signal.deadline, SV_DEADLINE) ;
else
{
char *tm = NULL ;
unsigned int t ;
if (SIGNAL <= SIGRR)
{
tm="/timeout-up" ;
}
else
{
tm="/timeout-down" ;
}
errno = 0 ;
size_t tmlen = strlen(tm) ;
memcpy(file + svoklen,tm, tmlen) ;
file[svoklen + tmlen] = 0 ;
if (access(file, F_OK) < 0)
{
if (errno != ENOENT) strerr_diefu2sys(111, "access ", file) ;
}
if (errno == ENOENT)
{
tain_from_millisecs(&sv_signal.deadline, SV_DEADLINE) ;
}
else
{
if (!read_uint(file,&t)) strerr_diefu2sys(111,"read: ",file) ;
if (!read_uint(file,&t)) strerr_diefu2sys(111,"read: ",file) ;
tain_from_millisecs(&sv_signal.deadline, t) ;
}
}
}
errno = e ;
if (!genalloc_append(ss_resolve_sig_t,&gakeep,&sv_signal)) strerr_diefu2sys(111,"append services selection with: ",string + sv_signal.res.name) ;
}
/** nothing to do */
if (!genalloc_len(ss_resolve_sig_t,&gakeep)) goto finish ;
ttmain = tain_infinite_relative ;
tain_now_g() ;
tain_add_g(&ttmain,&ttmain) ;
int spfd = selfpipe_init() ;
if (spfd < 0) strerr_diefu1sys(111, "selfpipe_trap") ;
if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ;
if (selfpipe_trap(SIGINT) < 0) strerr_diefu1sys(111, "selfpipe_trap") ;
if (selfpipe_trap(SIGTERM) < 0) strerr_diefu1sys(111, "selfpipe_trap") ;
if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111,"ignore SIGPIPE") ;
if (!svc_init_pipe(&fifo,&gakeep)) strerr_diefu1x(111,"init pipe") ;
for (unsigned int i = 0 ; i < genalloc_len(ss_resolve_sig_t,&gakeep) ; i++)
{
int nret = 0 ;
ss_resolve_sig_t *sv = &genalloc_s(ss_resolve_sig_t,&gakeep)[i] ;
char const *name = sv->res.sa.s + sv->res.name ;
char const *state = sv->res.sa.s + sv->res.state ;
nret = svc_listen(&gakeep,&fifo,spfd,sv) ;
if (nret > 1) ret = 111 ;
if (sv->sig <= 3)
{
if (nret <= 1)
{
ss_state_setflag(&sta,SS_FLAGS_PID,sv->pid) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
}
else
{
ss_state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
}
else
{
if (nret <=1)
{
ss_state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
else
{
ss_state_setflag(&sta,SS_FLAGS_PID,sv->pid) ;
ss_state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
}
}
ss_state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ;
ss_state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ;
VERBO2 strerr_warni2x("Write state file of: ",name) ;
if (!ss_state_write(&sta,state,name))
{
VERBO1 strerr_warnwu2sys("write state file of: ",name) ;
ret = 111 ;
}
if (!nret) VERBO1 strerr_warni3x((sv->sig > 3) ? "Stopped" : "Started"," successfully: ",name) ;
}
tain_now_g() ;
tain_addsec(&ttmain,&STAMP,2) ;
for (unsigned int i = 0 ; i < genalloc_len(ss_resolve_sig_t,&gakeep) ; i++)
{
ss_resolve_sig_t *sv = &genalloc_s(ss_resolve_sig_t,&gakeep)[i] ;
if (!ftrigr_unsubscribe_g(&fifo, sv->ids, &ttmain))
{
VERBO3 strerr_warnwu2sys("unsubscribe to fifo of: ",sv->res.sa.s + sv->res.name) ;
ret = 111 ;
}
}
if (!svc_init_pipe(&fifo,&gakeep,&ttmain)) strerr_diefu1x(111,"init pipe") ;
ret = doit(spfd,&gakeep,&ttmain) ;
finish:
ftrigr_end(&fifo) ;
selfpipe_finish() ;
stralloc_free(&sares) ;
ss_resolve_graph_free(&graph) ;
genalloc_free(ss_resolve_sig_t,&gakeep) ;
ss_resolve_free(&res) ;
return (ret > 1) ? 111 : 0 ;
ftrigr_end(&fifo) ;
selfpipe_finish() ;
stralloc_free(&sares) ;
ss_resolve_graph_free(&graph) ;
genalloc_free(ss_resolve_sig_t,&gakeep) ;
ss_resolve_free(&res) ;
return (!ret) ? 111 : 0 ;
}
......@@ -31,27 +31,18 @@
#include <66/resolve.h>
int svc_init_pipe(ftrigr_t *fifo,genalloc *gasv)
int svc_init_pipe(ftrigr_t *fifo,genalloc *gasv,tain_t *deadline)
{
tain_t ttmain ;
tain_now_g() ;
tain_addsec(&ttmain,&STAMP,2) ;
ss_resolve_sig_t *svc ;
//VERBO2 strerr_warni1x("initiate fifo: fifo") ;
if (!ftrigr_startf(fifo, &ttmain, &STAMP))
if (!ftrigr_startf_g(fifo, deadline))
VERBO3 { strerr_warnwu1sys("initiate fifo") ; return 0 ; }
for (unsigned int i = 0 ; i < genalloc_len(ss_resolve_sig_t,gasv) ; i++)
{
svc = &genalloc_s(ss_resolve_sig_t,gasv)[i] ;
int r ;
size_t siglen = strlen(svc->sigtosend) ;
char *svok = svc->res.sa.s + svc->res.runat ;
size_t scanlen = strlen(svok) ;
char svfifo[scanlen + 6 + 1] ;
memcpy(svfifo, svok,scanlen) ;
memcpy(svfifo + scanlen, "/event",6) ;
......@@ -65,31 +56,14 @@ int svc_init_pipe(ftrigr_t *fifo,genalloc *gasv)
}
VERBO3 strerr_warnt2x("subcribe to fifo: ",svfifo) ;
svc->ids = ftrigr_subscribe_g(fifo, svfifo, "[DuUdOxs]", FTRIGR_REPEAT, &ttmain) ;
svc->ids = ftrigr_subscribe_g(fifo, svfifo, "[DuUdOxs]", FTRIGR_REPEAT, deadline) ;
if (!svc->ids)
{
VERBO3 strerr_warnwu2sys("subcribe to fifo: ",svfifo) ;
goto end ;
}
VERBO3 strerr_warnt6x("send signal: ",svc->sigtosend," to: ", svok,"/",S6_SUPERVISE_CTLDIR) ;
r = s6_svc_writectl(svok, S6_SUPERVISE_CTLDIR, svc->sigtosend, siglen) ;
if (r < 0)
{
VERBO3 strerr_warnwu3sys("something is wrong with the ",svok, "/" S6_SUPERVISE_CTLDIR " directory. errno reported") ;
goto end ;
}
if (!r)
{
VERBO3 strerr_warnw3x("sv: ",svok, " is not supervised") ;
goto end ;
}
}
return 1 ;
end:
return 0 ;
}
......@@ -22,15 +22,13 @@
#include <66/resolve.h>
#include <66/ssexec.h>
int svc_send(ssexec_t *info,genalloc *ga,char const *sig,char const *const *envp)
{
unsigned int i = 0 ;
int nargc = 3 + genalloc_len(ss_resolve_t,ga) ;
char const *newargv[nargc] ;
unsigned int m = 0 ;
newargv[m++] = "fake_name" ;
newargv[m++] = sig ;
......
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