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

revamp of svc_init and svc_unsupervise function

parent 4c9491c2
No related branches found
No related tags found
No related merge requests found
......@@ -38,176 +38,160 @@
#include <66/ssexec.h>
#include <66/state.h>
int svc_init(ssexec_t *info,char const *src, genalloc *ga)
#define FLAGS_INIT_EARLIER 1
#define FLAGS_INIT_DOWN (1 << 1)
/**
* @init: array of resolve files of services
* @len: length of the @init array
* @flags: FLAGS_INIT_DOWN -> remove down file, FLAGS_INIT_EARLIER -> earlier services
* */
int svc_init(ssexec_t *info, resolve_service_t *init, unsigned int len, uint8_t flags)
{
log_flow() ;
size_t namelen, srclen, svscanlen, tmplen, pos, i ;
ssize_t logname ;
uint8_t earlier = FLAGS_ISSET(flags, FLAGS_INIT_EARLIER) ;
uint8_t down = FLAGS_ISSET(flags, FLAGS_INIT_DOWN) ;
gid_t gid = getgid() ;
uint16_t id ;
ftrigr_t fifo = FTRIGR_ZERO ;
stralloc sadown = STRALLOC_ZERO ;
genalloc ids = GENALLOC_ZERO ; // uint16_t
int r, e = 0 ;
unsigned int pos = 0, nsv = 0 ;
unsigned int real[len] ;
unsigned int down[len] ;
ss_state_t sta = STATE_ZERO ;
tain deadline ;
tain_now_set_stopwatch_g() ;
tain_addsec(&deadline,&STAMP,2) ;
if (!ftrigr_startf(&fifo, &deadline, &STAMP))
goto err ;
if (!create_live(info)) { log_warnusys("create live state") ; goto err ; }
for (i = 0 ; i < genalloc_len(resolve_service_t,ga); i++)
{
logname = 0 ;
char *string = genalloc_s(resolve_service_t,ga)[i].sa.s ;
char *name = string + genalloc_s(resolve_service_t,ga)[i].name ;
char *state = string + genalloc_s(resolve_service_t,ga)[i].state ;
if (s6_svc_ok(string + genalloc_s(resolve_service_t,ga)[i].runat))
{
log_info("Initialization aborted -- ",name," already initialized") ;
log_trace("Write state file of: ",name) ;
if (!state_write(&sta,state,name))
{
log_warnusys("write state file of: ",name) ;
goto err ;
}
for (; pos < len ; pos++)
down[pos] = 0 ;
for (pos = 0 ; pos < len ; pos++) {
char *string = init[pos].sa.s ;
char *name = string + init[pos].name ;
size_t namelen = strlen(name) ;
size_t treenamelen = strlen(init[pos].treename) ;
if (!create_live_state(info, init[pos].treename))
log_warnusys_return(LOG_EXIT_ZERO, "create the live directory of states") ;
if (!earlier && s6_svc_ok(string + init[pos].runat)) {
log_info("Skipping: ", name," -- already initialized") ;
continue ;
}
logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ;
if (logname > 0) name = string + genalloc_s(resolve_service_t,ga)[i].logassoc ;
namelen = strlen(name) ;
srclen = strlen(src) ;
char svsrc[srclen + 1 + namelen + 1] ;
memcpy(svsrc,src,srclen) ;
svsrc[srclen] = '/' ;
memcpy(svsrc + srclen + 1,name,namelen) ;
svsrc[srclen + 1 + namelen] = 0 ;
if (logname > 0) svscanlen = strlen(string + genalloc_s(resolve_service_t,ga)[i].runat) - SS_LOG_SUFFIX_LEN ;
else svscanlen = strlen(string + genalloc_s(resolve_service_t,ga)[i].runat) ;
char svscan[svscanlen + 6 + 1] ;
memcpy(svscan,string + genalloc_s(resolve_service_t,ga)[i].runat,svscanlen) ;
svscan[svscanlen] = 0 ;
log_trace("init service: ", string + genalloc_s(resolve_service_t,ga)[i].name) ;
/** if logger was created do not pass here to avoid to erase
* the fifo of the logger*/
if (!scan_mode(svscan,S_IFDIR))
{
log_trace("copy: ",svsrc, " to ", svscan) ;
if (!hiercopy(svsrc,svscan))
{
log_warnusys("copy: ",svsrc," to: ",svscan) ;
goto err ;
}
char svsrc[info->base.len + SS_SYSTEM_LEN + 1 + treenamelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
auto_strings(svsrc, info->base.s, SS_SYSTEM_LEN, "/", treenamelen, SS_SVDIRS, SS_SVC, "/", name) ;
size_t runatlen = string + init[pos].runat ;
char scandir[runatlen + 6 + 1] ; // +6 event directory name
auto_strings(scandir, string + init[pos].runat) ;
r = scan_mode(scandir, S_IFDIR) ;
if (r < 0)
log_warnsys_return(LOG_EXIT_ZERO, "conflicting format for: ", scandir) ;
if (!r) {
log_trace("copy: ",svsrc, " to ", scandir) ;
if (!hiercopy(svsrc, scandir))
log_warnusys_return(LOG_EXIT_ZERO, "copy: ",svsrc," to: ",scandir) ;
}
auto_strings(scandir + runatlen, "/down") ;
fd = open_trunc(scandir) ;
if (fd < 0)
log_warnusys_return(LOG_EXIT_ZERO, "create down file: ", scandir) ;
fd_close(fd) ;
if (!init[pos].down)
down[nsv] = 1 ;
if (!earlier) {
auto_strings(scandir + runatlen, "/event") ;
log_trace("create fifo: ",scandir) ;
if (!ftrigw_fifodir_make(scandir, gid, 0))
log_warnusys_return(LOG_EXIT_ZERO, "create fifo: ",scandir) ;
}
/** if logger you need to copy again the real path */
svscanlen = strlen(string + genalloc_s(resolve_service_t,ga)[i].runat) ;
memcpy(svscan,string + genalloc_s(resolve_service_t,ga)[i].runat,svscanlen) ;
svscan[svscanlen] = 0 ;
/** if logger and the reload was asked the folder xxx/log doesn't exist
* check it and create again if doesn't exist */
if (!scan_mode(svscan,S_IFDIR))
{
tmplen = strlen(svsrc) ;
char tmp[tmplen + 4 + 1] ;
memcpy(tmp,svsrc,tmplen) ;
memcpy(tmp + tmplen,"/log",4) ;
tmp[tmplen + 4] = 0 ;
log_trace("copy: ",tmp, " to ", svscan) ;
if (!hiercopy(tmp,svscan))
{
log_warnusys("copy: ",tmp," to: ",svscan) ;
real[nsv++] = init[pos] ;
}
if (!earlier) {
ftrigr_t fifo = FTRIGR_ZERO ;
uint16_t ids[len] ;
unsigned int nids = 0 ;
tain deadline ;
tain_now_set_stopwatch_g() ;
tain_addsec(&deadline, &STAMP, 2) ;
if (!ftrigr_startf_g(&fifo, &deadline))
goto err ;
for (pos = 0 ; pos < nsv ; pos++) {
char *string = init[real[pos]].sa.s ;
size_t runatlen = string + init[real[pos]].runat ;
char scandir[runatlen + 6 + 1] ; // +6 event directory name
auto_strings(scandir, string + init[real[pos]].runat) ;
log_trace("subcribe to fifo: ", scandir) ;
/** unsubscribe automatically, options is 0 */
ids[nids] = ftrigr_subscribe_g(&fifo, scandir, "s", 0, &deadline) ;
if (!ids[nids++]) {
log_warnusys("subcribe to fifo: ", scandir) ;
goto err ;
}
}
memcpy(svscan + svscanlen, "/down", 5) ;
svscan[svscanlen + 5] = 0 ;
if (!genalloc_s(resolve_service_t,ga)[i].down)
{
if (!sastr_add_string(&sadown,svscan))
{
log_warnusys("add: ",svscan," to genalloc") ;
if (nids) {
log_trace("reload scandir: ", info->scandir.s) ;
if (scandir_send_signal(info->scandir.s, "h") <= 0) {
log_warnusys("reload scandir: ", info->scandir.s) ;
goto err ;
}
}
log_trace("create file: ",svscan) ;
if (!touch(svscan))
{
log_warnusys("create file: ",svscan) ;
goto err ;
}
memcpy(svscan + svscanlen, "/event", 6) ;
svscan[svscanlen + 6] = 0 ;
log_trace("create fifo: ",svscan) ;
if (!ftrigw_fifodir_make(svscan, gid, 0))
{
log_warnusys("create fifo: ",svscan) ;
goto err ;
}
log_trace("subcribe to fifo: ",svscan) ;
/** unsubscribe automatically, options is 0 */
id = ftrigr_subscribe_g(&fifo, svscan, "s", 0, &deadline) ;
if (!id)
{
log_warnusys("subcribe to fifo: ",svscan) ;
goto err ;
log_trace("waiting for events on fifo") ;
if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0)
goto err ;
}
if (!genalloc_append(uint16_t, &ids, &id)) goto err ;
}
if (genalloc_len(uint16_t,&ids))
{
log_trace("reload scandir: ",info->scandir.s) ;
if (scandir_send_signal(info->scandir.s,"h") <= 0)
{
log_warnusys("reload scandir: ",info->scandir.s) ;
goto err ;
}
log_trace("waiting for events on fifo") ;
if (ftrigr_wait_and_g(&fifo, genalloc_s(uint16_t, &ids), genalloc_len(uint16_t, &ids), &deadline) < 0)
goto err ;
for (pos = 0 ; pos < nsv ; pos++) {
char const *string = init[real[pos]].sa.s ;
char const *name = string + init[real[pos]].name ;
char const *state = string + init[real[pos]].state ;
log_trace("Write state file of: ", name) ;
state_setflag(&sta, SS_FLAGS_RELOAD, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_INIT, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_STATE, SS_FLAGS_UNKNOWN) ;
state_setflag(&sta, SS_FLAGS_PID, SS_FLAGS_UNKNOWN) ;
if (!state_write(&sta,state,name)) {
for (pos = 0 ; pos < sadown.len; pos += strlen(sadown.s + pos) + 1)
{
log_trace("delete down file at: ",sadown.s + pos) ;
if (unlink(sadown.s + pos) < 0 && errno != ENOENT) goto err ;
log_warnusys("write state file of: ",name) ;
goto err ;
}
for (pos = 0 ; pos < genalloc_len(resolve_service_t,ga) ; pos++)
{
char const *string = genalloc_s(resolve_service_t,ga)[pos].sa.s ;
char const *name = string + genalloc_s(resolve_service_t,ga)[pos].name ;
char const *state = string + genalloc_s(resolve_service_t,ga)[pos].state ;
if (down[pos] && down) {
log_trace("Write state file of: ",name) ;
if (!state_write(&sta,state,name))
{
log_warnusys("write state file of: ",name) ;
goto err ;
size_t runatlen = string + init[down[pos]].runat ;
char file[runatlen + 5 + 1] ;
auto_strings(file, string + init[down[pos]].runat, "/down") ;
log_trace("delete down file: ", file) ;
if (unlink(file) < 0 && errno != ENOENT) {
log_warnusys("delete down file: ", file)
}
log_info("Initialized successfully: ",name) ;
}
log_info("Initialized successfully: ",name) ;
}
ftrigr_end(&fifo) ;
stralloc_free(&sadown) ;
genalloc_free(uint16_t, &ids) ;
return 1 ;
e = 1 ;
err:
ftrigr_end(&fifo) ;
genalloc_free(uint16_t, &ids) ;
stralloc_free(&sadown) ;
ftrigr_end(&fifo) ;
return 0 ;
return e ;
}
......@@ -27,70 +27,76 @@
#include <66/ssexec.h>
#include <66/state.h>
int svc_unsupervise(ssexec_t *info,genalloc *ga,char const *sig,char const *const *envp)
int svc_unsupervise(ssexec_t *info, resolve_service_t *sv, unsigned int len)
{
log_flow() ;
size_t i = 0 ;
unsigned int pos = 0 ;
ss_state_t sta = STATE_ZERO ;
resolve_service_t_ref pres ;
stralloc sares = STRALLOC_ZERO ;
resolve_service_t_ref pres = 0 ;
if (!svc_send(info,ga,sig,envp))
{
log_warnu("stop services") ;
goto err ;
}
if (!svc_send(info, sv, len, "-d"))
log_warnu_return(LOG_EXIT_ZERO, "stop services") ;
for (; pos < len ; pos++) {
for (; i < genalloc_len(resolve_service_t,ga) ; i++)
{
char const *string = genalloc_s(resolve_service_t,ga)[i].sa.s ;
log_trace("delete directory service: ",string + genalloc_s(resolve_service_t,ga)[i].runat) ;
if (rm_rf(string + genalloc_s(resolve_service_t,ga)[i].runat) < 0)
{
log_warnusys("delete: ",string + genalloc_s(resolve_service_t,ga)[i].runat) ;
goto err ;
char const *string = sv[pos].sa.s ;
int r = access(string, F_OK) ;
if (!r) {
log_trace("delete service directory: ",string + sv[pos].runat) ;
if (rm_rf(string + sv[pos].runat) < 0)
log_warnu_return(LOG_EXIT_ZERO, "delete: ", string + sv[pos].runat) ;
}
}
if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC))
{
log_warnusys("set revolve pointer to source") ;
goto err ;
}
for (i = 0 ; i < genalloc_len(resolve_service_t,ga) ; i++)
{
pres = &genalloc_s(resolve_service_t,ga)[i] ;
for (pos = 0 ; pos < len ; pos++) {
pres = &sv[pos] ;
char const *string = pres->sa.s ;
char const *name = string + pres->name ;
char const *state = string + pres->state ;
size_t treenamelen = strlen(string + pres->treename) ;
char res_s[info->base.len + SS_SYSTEM + 1 + treenamelen + SS_SVDIRS_LEN + 1] ;
// remove the resolve/state file if the service is disabled
if (!pres->disen)
{
log_trace("Delete resolve file of: ",name) ;
resolve_rmfile(sares.s,name) ;
log_trace("Delete state file of: ",name) ;
state_rmfile(state,name) ;
}
else
{
state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_TRUE) ;
// state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
log_trace("Write state file of: ",name) ;
if (!state_write(&sta,state,name))
{
log_warnusys("write state file of: ",name) ;
goto err ;
if (!pres->disen) {
auto_strings(res_s, info->base.s, SS_SYSTEM, "/", string + pres->treename, SS_SVDIRS) ;
log_trace("Delete resolve file of: ", name) ;
resolve_rmfile(res_s, name) ;
int r = access(state, F_OK) ;
if (!r) {
log_trace("Delete state file of: ", name) ;
state_rmfile(state, name) ;
}
} else if (!access(state, F_OK)) {
/**
* The svc_unsupervise can be called with service which was
* never initialized. In this case the live state directory
* doesn't exist and we don't want to create a fresh one.
* So check first if the state directory exist before
* passing through here
* */
state_setflag(&sta, SS_FLAGS_RELOAD, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_INIT, SS_FLAGS_TRUE) ;
// state_setflag(&sta, SS_FLAGS_UNSUPERVISE, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_STATE, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_PID, SS_FLAGS_FALSE) ;
log_trace("Write state file of: ", name) ;
if (!state_write(&sta, state, name))
log_warnu_return(LOG_EXIT_ZERO, "write state file of: ", name) ;
}
log_info("Unsupervised successfully: ",name) ;
log_info("Unsupervised successfully: ", name) ;
}
stralloc_free(&sares) ;
return 1 ;
err:
stralloc_free(&sares) ;
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