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

remove use of s6-rc

parent 6715c89d
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 1301 deletions
/package/prog/skalibs
/package/admin/execline
/package/admin/s6
/package/admin/s6-rc
/package/prog/oblibs
......@@ -2,7 +2,6 @@
66-scanctl 0755
66-init 0755
66-tree 0755
66-dbctl 0755
66-enable 0755
66-disable 0755
66-parser 0755
......
......@@ -3,7 +3,6 @@ BIN_TARGETS := \
66-scanctl \
66-init \
66-tree \
66-dbctl \
66-enable \
66-disable \
66-parser \
......
/*
* 66-dbctl.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <oblibs/log.h>
#include <66/ssexec.h>
int main(int argc, char const *const *argv,char const *const *envp)
{
PROG = "66-dbctl" ;
ssexec_t info = SSEXEC_ZERO ;
info.prog = PROG ;
info.help = help_dbctl ;
info.usage = usage_dbctl ;
return ssexec_main(argc,argv,envp,&ssexec_dbctl,&info) ;
}
${LIB66}
-ls6rc
-ls6
-loblibs
-lskarnet
${SYSCLOCK_LIB}
${SPAWN_LIB}
/*
* db.h
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#ifndef SS_DB_H
#define SS_DB_H
#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
#include <66/ssexec.h>
extern int db_compile(char const *workdir, char const *tree, char const *treename,char const *const *envp) ;
extern int db_find_compiled_state(char const *livetree, char const *treename) ;
extern int db_update(char const *newdb, ssexec_t *info,char const *const *envp) ;
extern int db_ok(char const *livetree, char const *treename) ;
extern int db_switch_to(ssexec_t *info, char const *const *envp,unsigned int where) ;
#endif
/*
* rc.h
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#ifndef SS_RC_H
#define SS_RC_H
#include <66/ssexec.h>
#include <skalibs/genalloc.h>
extern int rc_init(ssexec_t *info, char const *const *envp) ;
extern int rc_send(ssexec_t *info,genalloc *ga,char const *sig,char const *const *envp) ;
extern int rc_unsupervise(ssexec_t *info, genalloc *ga,char const *sig,char const *const *envp) ;
extern int rc_manage(ssexec_t *info,genalloc *ga) ;
#endif
/*
* db_compile.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/db.h>
#include <s6-rc/config.h>//S6RC_BINPREFIX
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <oblibs/string.h>
#include <oblibs/log.h>
#include <oblibs/types.h>
#include <skalibs/types.h>
#include <skalibs/djbunix.h>
#include <66/utils.h>
#include <66/constants.h>
int db_compile(char const *workdir, char const *tree, char const *treename, char const *const *envp)
{
log_flow() ;
int wstat, r ;
pid_t pid ;
size_t wlen = strlen(workdir), treelen = strlen(treename) ;
char dest[wlen + SS_DB_LEN + 1 + treelen + 1] ;
auto_strings(dest, workdir, SS_DB, "/", treename) ;
char src[wlen + SS_DB_LEN + SS_SRC_LEN + 1] ;
auto_strings(src, workdir, SS_DB, SS_SRC) ;
r = scan_mode(dest,S_IFDIR) ;
if (r) {
if (rm_rf(dest) < 0)
log_warnusys_return(LOG_EXIT_ZERO,"remove: ", dest) ;
}
char const *newargv[7] ;
unsigned int m = 0 ;
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, VERBOSITY)] = 0 ;
newargv[m++] = S6RC_BINPREFIX "s6-rc-compile" ;
newargv[m++] = "-v" ;
newargv[m++] = fmt ;
newargv[m++] = "--" ;
newargv[m++] = dest ;
newargv[m++] = src ;
newargv[m++] = 0 ;
pid = child_spawn0(newargv[0],newargv,envp) ;
if (waitpid_nointr(pid,&wstat, 0) < 0)
log_warnusys_return(LOG_EXIT_ZERO,"wait for: ",newargv[0]) ;
if (wstat)
log_warnu_return(LOG_EXIT_ZERO,"compile: ",dest) ;
return 1 ;
}
/*
* db_find_compiled_state.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/utils.h>
#include <sys/stat.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <66/constants.h>
/** return 1-> backup
* return 0-> src
* -1->not initiated */
int db_find_compiled_state(char const *livetree, char const *treename)
{
log_flow() ;
int r ;
size_t treelen = strlen(livetree), namelen = strlen(treename) ;
struct stat st ;
char current[treelen + 1 + namelen + 9 + 1] ;
auto_strings(current, livetree, "/", treename, "/compiled") ;
if(lstat(current,&st) < 0) return -1 ;
if(!(S_ISLNK(st.st_mode)))
log_warnu_return(LOG_EXIT_LESSONE,"find symlink: ",current) ;
stralloc symreal = STRALLOC_ZERO ;
r = sarealpath(&symreal,current) ;
if (r < 0 ) {
stralloc_free(&symreal) ;
log_warnu_return(LOG_EXIT_LESSONE,"find real path: ",current) ;
}
char *b = NULL ;
b = memmem(symreal.s,symreal.len,SS_BACKUP,SS_BACKUP_LEN) ;
stralloc_free(&symreal) ;
if (!b) return 0 ;
return 1 ;
}
/*
* db_ok.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <66/constants.h>
int db_ok(char const *livetree, char const *treename)
{
log_flow() ;
size_t treelen = strlen(livetree), namelen = strlen(treename) ;
struct stat st ;
char sym[treelen + 1 + namelen + 1] ;
auto_strings(sym, livetree, "/", treename) ;
if(lstat(sym,&st) < 0)
return 0 ;
if(!(S_ISLNK(st.st_mode)))
return 0 ;
return 1 ;
}
/*
* db_switch_to.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/db.h>
#include <string.h>
#include <oblibs/log.h>
#include <skalibs/stralloc.h>
#include <skalibs/types.h>
#include <66/constants.h>
#include <66/backup.h>
#include <66/utils.h>
#include <66/enum.h>
#include <66/ssexec.h>
/** 1-> backup
* 0-> ori */
int db_switch_to(ssexec_t *info, unsigned int where)
{
log_flow() ;
int r, e = 0 ;
stralloc db = STRALLOC_ZERO ;
char type[UINT_FMT] ;
size_t typelen = uint_fmt(type, TYPE_BUNDLE) ;
type[typelen] = 0 ;
size_t cmdlen ;
char cmd[typelen + 6 + 1] ;
memcpy(cmd,"-t",2) ;
memcpy(cmd + 2,type,typelen) ;
cmdlen = 2 + typelen ;
memcpy(cmd + cmdlen," -b",3) ;
cmd[cmdlen + 3] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("find realpath of symlink for db of tree: ",info->treename.s) ;
goto err ;
}
// point to origin
if (!r && where)
{
log_trace("make a backup of db service for: ",info->treename.s) ;
if (!backup_make_new(info,TYPE_LONGRUN))
{
log_warnusys("make a backup of db service for: ",info->treename.s) ;
goto err ;
}
log_trace("switch db symlink of tree: ",info->treename.s," to backup") ;
memcpy(cmd + cmdlen," -s1",4) ;
cmd[cmdlen + 4] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("switch db symlink of tree: ",info->treename.s," to backup") ;
goto err ;
}
if (db_ok(info->livetree.s, info->treename.s))
{
if (!backup_realpath_sym(&db,info,TYPE_LONGRUN))
{
log_warnusys("find path of db: ",db.s) ;
goto err ;
}
log_trace("update ",info->livetree.s,"/",info->treename.s," to ",db.s,"/",info->treename.s) ;
if (!db_update(db.s, info))
{
log_trace("rollback db service: ", info->treename.s) ;
memcpy(cmd + cmdlen," -s0",4) ;
cmd[cmdlen + 4] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("switch db symlink of tree: ",info->treename.s," to source") ;
goto err ;
}
}
}
}
else if (r > 0 && !where)
{
log_trace("switch db symlink of tree: ",info->treename.s," to source") ;
memcpy(cmd + cmdlen," -s0",4) ;
cmd[cmdlen + 4] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("switch db symlink of tree: ",info->treename.s," to source") ;
goto err ;
}
if (db_ok(info->livetree.s,info->treename.s))
{
if (!backup_realpath_sym(&db,info,TYPE_LONGRUN))
{
log_warnusys("find path of db: ",db.s) ;
goto err ;
}
log_trace("update ",info->livetree.s,"/",info->treename.s," to ",db.s,"/",info->treename.s) ;
if (!db_update(db.s, info))
{
log_trace("rollback db: ", info->treename.s) ;
memcpy(cmd + cmdlen," -s1",4) ;
cmd[cmdlen + 4] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("switch db service for: ",info->treename.s," to backup") ;
goto err ;
}
}
}
log_trace("make a backup of db service for: ",info->treename.s) ;
if (!backup_make_new(info,TYPE_LONGRUN))
{
log_warnusys("make a backup of db service for: ",info->treename.s) ;
goto err ;
}
}
e = 1 ;
err:
stralloc_free(&db) ;
return e ;
}
/*
* db_update.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/db.h>
#include <s6-rc/config.h>//S6RC_BINPREFIX
#include <sys/types.h>
#include <string.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <skalibs/types.h>
#include <skalibs/djbunix.h>
#include <66/utils.h>
#include <66/ssexec.h>
int db_update(char const *newdb, ssexec_t *info)
{
log_flow() ;
pid_t pid ;
int wstat ;
size_t newdblen = strlen(newdb) ;
char db[newdblen + 1 + info->treename.len + 1] ;
auto_strings(db, newdb, "/", info->treename.s) ;
char newlive[info->livetree.len + 1 + info->treename.len + 1] ;
auto_strings(newlive, info->livetree.s, "/", info->treename.s) ;
char const *newargv[10] ;
unsigned int m = 0 ;
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, VERBOSITY)] = 0 ;
newargv[m++] = S6RC_BINPREFIX "s6-rc-update" ;
newargv[m++] = "-v" ;
newargv[m++] = fmt ;
newargv[m++] = "-l" ;
newargv[m++] = newlive ;
newargv[m++] = "--" ;
newargv[m++] = db ;
newargv[m++] = 0 ;
pid = child_spawn0(newargv[0],newargv, (char const *const *)environ) ;
if (waitpid_nointr(pid,&wstat, 0) < 0)
log_warnusys_return(LOG_EXIT_ZERO,"wait for ",newargv[0]) ;
if (wstat)
log_warnu_return(LOG_EXIT_ZERO,"update: ",newlive," to ",db) ;
return 1 ;
}
db_compile.o
db_find_compiled_state.o
db_ok.o
db_switch_to.o
db_update.o
-ls6rc
-loblibs
-lskarnet
/*
* ssexec_dbctl.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <sys/types.h>//pid_t
//#include <stdio.h>
#include <oblibs/obgetopt.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <skalibs/tai.h>
#include <skalibs/types.h>//UINT_FMT
#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
#include <skalibs/djbunix.h>
#include <s6/supervise.h>
#include <s6-rc/config.h>
#include <66/constants.h>
#include <66/utils.h>
#include <66/db.h>
#include <66/enum.h>
#include <66/resolve.h>
#include <66/ssexec.h>
#include <66/state.h>
#include <66/service.h>
static unsigned int DEADLINE = 0 ;
static void rebuild_list(ss_resolve_graph_t *graph,ssexec_t *info, int what)
{
log_flow() ;
int isup ;
s6_svstatus_t status = S6_SVSTATUS_ZERO ;
genalloc gatmp = GENALLOC_ZERO ;
ss_state_t sta = STATE_ZERO ;
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&graph->sorted) ; i++)
{
char *string = genalloc_s(resolve_service_t,&graph->sorted)[i].sa.s ;
char *name = string + genalloc_s(resolve_service_t,&graph->sorted)[i].name ;
char *runat = string + genalloc_s(resolve_service_t,&graph->sorted)[i].runat ;
char *state = string + genalloc_s(resolve_service_t,&graph->sorted)[i].state ;
if (!state_check(state,name)) log_die(LOG_EXIT_SYS,"unitialized service: ",name) ;
if (!state_read(&sta,state,name)) log_dieusys(LOG_EXIT_SYS,"read state of: ",name) ;
if (sta.init) log_die(LOG_EXIT_SYS,"unitialized service: ",name) ;
int type = genalloc_s(resolve_service_t,&graph->sorted)[i].type ;
if (type == TYPE_LONGRUN && genalloc_s(resolve_service_t,&graph->sorted)[i].disen)
{
if (!s6_svstatus_read(runat,&status)) log_dieusys(LOG_EXIT_SYS,"read status of: ",runat) ;
isup = status.pid && !status.flagfinishing ;
if (isup && !what)
{
log_info("Already up: ",name) ;
continue ;
}
else if (!isup && what)
{
log_info("Already down: ",name) ;
continue ;
}
}
else
{
if (!sta.state && what || !genalloc_s(resolve_service_t,&graph->sorted)[i].disen)
{
log_info("Already down: ",name) ;
continue ;
}
if (sta.state && !what)
{
log_info("Already up: ",name) ;
continue ;
}
}
genalloc_append(resolve_service_t,&gatmp,&genalloc_s(resolve_service_t,&graph->sorted)[i]) ;
}
genalloc_copy(resolve_service_t,&graph->sorted,&gatmp) ;
genalloc_free(resolve_service_t,&gatmp) ;
}
/* signal = 0 -> reload
* signal = 1 -> up
* signal > 1 -> down*/
static int check_status(genalloc *gares,ssexec_t *info,int signal)
{
log_flow() ;
int reload = 0 , up = 0 , ret = 0 ;
s6_svstatus_t status = S6_SVSTATUS_ZERO ;
ss_state_t sta = STATE_ZERO ;
if (!signal) reload = 1 ;
else if (signal == 1) up = 1 ;
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,gares) ; i++)
{
int nret = 0 ;
resolve_service_t_ref pres = &genalloc_s(resolve_service_t,gares)[i] ;
char const *name = pres->sa.s + pres->name ;
char const *state = pres->sa.s + pres->state ;
/** do not touch the Master resolve file*/
if (obstr_equal(name,SS_MASTER + 1)) continue ;
/** only check longrun service */
if (pres->type == TYPE_LONGRUN)
{
if (!s6_svstatus_read(pres->sa.s + pres->runat,&status)) log_dieusys(LOG_EXIT_SYS,"read status of: ",pres->sa.s + pres->runat) ;
else if (up)
{
if ((!WEXITSTATUS(status.wstat) && !WIFSIGNALED(status.wstat)) || (WIFSIGNALED(status.wstat) && !WEXITSTATUS(status.wstat) && (WTERMSIG(status.wstat) == 15 )))
{
state_setflag(&sta,SS_FLAGS_PID,status.pid) ;
state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
}
else
{
log_warnu("start: ",name) ;
nret = 1 ;
state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
}
else
{
if ((!WEXITSTATUS(status.wstat) && !WIFSIGNALED(status.wstat)) || (WIFSIGNALED(status.wstat) && !WEXITSTATUS(status.wstat) && (WTERMSIG(status.wstat) == 15 )))
{
state_setflag(&sta,SS_FLAGS_PID,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
else
{
log_warnu("stop: ",name) ;
state_setflag(&sta,SS_FLAGS_PID,status.pid) ;
state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
nret = 1 ;
}
}
}
if (nret) ret = 111 ;
state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ;
// state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ;
if (pres->type == TYPE_BUNDLE || pres->type == TYPE_ONESHOT)
{
if (up) state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_TRUE) ;
else state_setflag(&sta,SS_FLAGS_STATE,SS_FLAGS_FALSE) ;
}
log_trace("Write state file of: ",name) ;
if (!state_write(&sta,state,name))
{
log_warnusys("write state file of: ",name) ;
ret = 111 ;
}
if (!nret) log_info(reload ? "Reloaded" : up ? "Started" : "Stopped"," successfully: ",name) ;
}
return ret ;
}
static pid_t send(genalloc *gasv, char const *livetree, char const *signal,char const *const *envp)
{
log_flow() ;
tain deadline ;
tain_from_millisecs(&deadline, DEADLINE) ;
tain_now_g() ;
tain_add_g(&deadline, &deadline) ;
char const *newargv[10 + genalloc_len(resolve_service_t,gasv)] ;
unsigned int m = 0 ;
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, VERBOSITY)] = 0 ;
char tt[UINT32_FMT] ;
tt[uint32_fmt(tt,DEADLINE)] = 0 ;
newargv[m++] = S6RC_BINPREFIX "s6-rc" ;
newargv[m++] = "-v" ;
newargv[m++] = fmt ;
newargv[m++] = "-t" ;
newargv[m++] = tt ;
newargv[m++] = "-l" ;
newargv[m++] = livetree ;
newargv[m++] = signal ;
newargv[m++] = "change" ;
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,gasv); i++)
newargv[m++] = genalloc_s(resolve_service_t,gasv)[i].sa.s + genalloc_s(resolve_service_t,gasv)[i].name ;
newargv[m++] = 0 ;
return child_spawn0(newargv[0],newargv,envp) ;
}
int ssexec_dbctl(int argc, char const *const *argv,char const *const *envp,ssexec_t *info)
{
DEADLINE = 0 ;
if (info->timeout) DEADLINE = info->timeout ;
unsigned int up, down, reload, ret, reverse ;
int r, wstat ;
pid_t pid ;
char *signal = 0 ;
char *mainsv = SS_MASTER + 1 ;
genalloc gares = GENALLOC_ZERO ; //resolve_service_t
stralloc tmp = STRALLOC_ZERO ;
stralloc sares = STRALLOC_ZERO ;
ss_resolve_graph_t graph = RESOLVE_GRAPH_ZERO ;
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
up = down = reload = ret = reverse = 0 ;
//PROG = "66-dbctl" ;
{
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
{
int opt = getopt_args(argc,argv, OPTS_DBCTL, &l) ;
if (opt == -1) break ;
if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
switch (opt)
{
case 'u' : up = 1 ; if (down || reload) log_usage(usage_dbctl) ; break ;
case 'd' : down = 1 ; if (up || reload) log_usage(usage_dbctl) ; break ;
case 'r' : reload = 1 ; if (down || up) log_usage(usage_dbctl) ; break ;
default : log_usage(usage_dbctl) ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (!up && !down && !reload){ log_warn("signal must be set") ; log_usage(usage_dbctl) ; }
if (down)
{
signal = "-d" ;
}
else signal = "-u" ;
if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) log_dieusys(LOG_EXIT_SYS,"set revolve pointer to source") ;
if (argc < 1)
{
if (!resolve_check(sares.s,mainsv)) log_diesys(LOG_EXIT_SYS,"inner bundle doesn't exit -- please make a bug report") ;
if (!resolve_read(wres,sares.s,mainsv)) log_dieusys(LOG_EXIT_SYS,"read resolve file of inner bundle") ;
if (res.ndepends)
{
if (!resolve_append(&gares,wres)) log_dieusys(LOG_EXIT_SYS,"append services selection with inner bundle") ;
}
else
{
log_info("nothing to do") ;
resolve_free(wres) ;
goto freed ;
}
}
else
{
for(;*argv;argv++)
{
char const *name = *argv ;
if (!resolve_check(sares.s,name)) log_diesys(LOG_EXIT_SYS,"unknown service: ",name) ;
if (!resolve_read(wres,sares.s,name)) log_dieusys(LOG_EXIT_SYS,"read resolve file of: ",name) ;
if (res.type == TYPE_CLASSIC) log_die(LOG_EXIT_SYS,name," has type classic") ;
if (!resolve_append(&gares,wres)) log_dieusys(LOG_EXIT_SYS,"append services selection with: ", name) ;
}
}
if (!db_ok(info->livetree.s,info->treename.s))
log_diesys(LOG_EXIT_SYS,"db: ",info->livetree.s,"/",info->treename.s," is not running") ;
if (!stralloc_cats(&tmp,info->livetree.s)) log_die_nomem("stralloc") ;
if (!stralloc_cats(&tmp,"/")) log_die_nomem("stralloc") ;
if (!stralloc_cats(&tmp,info->treename.s)) log_die_nomem("stralloc") ;
if (!stralloc_0(&tmp)) log_die_nomem("stralloc") ;
if (reload)
{
reverse = 1 ;
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++)
{
if (!ss_resolve_graph_build(&graph,&genalloc_s(resolve_service_t,&gares)[i],sares.s,reverse)) log_dieusys(LOG_EXIT_SYS,"build services graph") ;
}
r = ss_resolve_graph_publish(&graph,reverse) ;
if (r < 0) log_die(LOG_EXIT_SYS,"cyclic dependencies detected") ;
if (!r) log_dieusys(LOG_EXIT_SYS,"publish service graph") ;
rebuild_list(&graph,info,reverse) ;
pid = send(&graph.sorted,tmp.s,"-d",envp) ;
if (waitpid_nointr(pid,&wstat, 0) < 0)
log_dieusys(LOG_EXIT_SYS,"wait for s6-rc") ;
if (wstat) log_dieu(LOG_EXIT_SYS," stop services selection") ;
ret = check_status(&graph.sorted,info,2) ;
if (ret) goto freed ;
ss_resolve_graph_free(&graph) ;
}
if (down) reverse = 1 ;
else reverse = 0 ;
for (unsigned int i = 0 ; i < genalloc_len(resolve_service_t,&gares) ; i++)
{
int ireverse = reverse ;
int logname = get_rstrlen_until(genalloc_s(resolve_service_t,&gares)[i].sa.s + genalloc_s(resolve_service_t,&gares)[i].name,SS_LOG_SUFFIX) ;
if (logname > 0 && (!resolve_cmp(&gares,genalloc_s(resolve_service_t,&gares)[i].sa.s + genalloc_s(resolve_service_t,&gares)[i].logassoc, DATA_SERVICE)) && down)
ireverse = 1 ;
if (reload) ireverse = 1 ;
if (!ss_resolve_graph_build(&graph,&genalloc_s(resolve_service_t,&gares)[i],sares.s,ireverse)) log_dieusys(LOG_EXIT_SYS,"build services graph") ;
}
r = ss_resolve_graph_publish(&graph,reverse) ;
if (r < 0) log_die(LOG_EXIT_SYS,"cyclic dependencies detected") ;
if (!r) log_dieusys(LOG_EXIT_SYS,"publish service graph") ;
rebuild_list(&graph,info,reverse) ;
pid = send(&graph.sorted,tmp.s,signal,envp) ;
if (waitpid_nointr(pid,&wstat, 0) < 0)
log_dieusys(LOG_EXIT_SYS,"wait for s6-rc") ;
if (wstat) log_dieu(LOG_EXIT_SYS,down ? "stop" : "start"," services selection") ;
ret = check_status(&graph.sorted,info,down ? 2 : 1) ;
freed:
stralloc_free(&tmp) ;
stralloc_free(&sares) ;
ss_resolve_graph_free(&graph) ;
resolve_free(wres) ;
resolve_deep_free(DATA_SERVICE, &gares) ;
return ret ;
}
rc_init.o
rc_manage.o
rc_send.o
rc_unsupervise.o
-ls6rc
-loblibs
-lskarnet
/*
* rc_init.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/rc.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/directory.h>
#include <oblibs/sastr.h>
#include <skalibs/genalloc.h>
#include <skalibs/djbunix.h>
#include <skalibs/types.h>
#include <66/resolve.h>
#include <66/ssexec.h>
#include <66/constants.h>
#include <66/utils.h>
#include <66/state.h>
#include <66/service.h>
#include <s6-rc/config.h>
/**@Return 1 on success
* @Return 2 on empty database
* @Return 0 on fail */
int rc_init(ssexec_t *info, char const *const *envp)
{
log_flow() ;
int r, wstat, empty = 0, e = 0 ;
pid_t pid ;
size_t pos = 0 ;
ss_state_t sta = STATE_ZERO ;
stralloc sares = STRALLOC_ZERO ;
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
stralloc sasvc = STRALLOC_ZERO ;
genalloc gares = GENALLOC_ZERO ; //resolve_service_t type
char svdir[info->tree.len + SS_SVDIRS_LEN + SS_DB_LEN + 1 + info->treename.len + 1] ;
char ltree[info->livetree.len + 1 + info->treename.len + 1] ;
char prefix[info->treename.len + 1 + 1] ;
char tt[UINT32_FMT] ;
char const *newargv[12] ;
unsigned int m = 0 ;
gid_t gidowner ;
if (!yourgid(&gidowner,info->owner)){ log_warnusys("set gid") ; goto err ; }
r = scan_mode(info->livetree.s,S_IFDIR) ;
if (r == -1) { errno = EEXIST ; log_warnsys("conflicting format of: ",info->livetree.s) ; goto err ; }
if (!r)
{
log_trace("create directory: ",info->livetree.s) ;
r = dir_create(info->livetree.s,0700) ;
if (!r){ log_warnusys("create directory: ",info->livetree.s) ; goto err ; }
log_trace("chown directory: ",info->livetree.s) ;
if (chown(info->livetree.s,info->owner,gidowner) < 0){ log_warnusys("chown directory: ",info->livetree.s) ; goto err ; }
}
if (!create_live(info)) { log_warnusys("create live state") ; goto err ; }
if (!sa_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC))
{ log_warnu("set revolve pointer to source") ; goto err ; }
if (!resolve_check(sares.s,SS_MASTER +1)) { log_warnu("find inner bundle -- please make a bug report") ; goto err ; }
if (!resolve_read(wres,sares.s,SS_MASTER + 1)) { log_warnusys("read resolve file of inner bundle") ; goto err ; }
if (!res.ndepends)
{
log_info("Initialization: no atomic services into tree: ",info->treename.s) ;
empty = 1 ;
goto end ;
}
memcpy(svdir,info->tree.s,info->tree.len) ;
memcpy(svdir + info->tree.len ,SS_SVDIRS ,SS_SVDIRS_LEN) ;
memcpy(svdir + info->tree.len + SS_SVDIRS_LEN,SS_DB,SS_DB_LEN) ;
memcpy(svdir + info->tree.len + SS_SVDIRS_LEN + SS_DB_LEN, "/", 1) ;
memcpy(svdir + info->tree.len + SS_SVDIRS_LEN + SS_DB_LEN + 1, info->treename.s,info->treename.len) ;
svdir[info->tree.len + SS_SVDIRS_LEN + SS_DB_LEN + 1 + info->treename.len] = 0 ;
memcpy(ltree,info->livetree.s,info->livetree.len) ;
ltree[info->livetree.len] = '/' ;
memcpy(ltree + info->livetree.len + 1, info->treename.s, info->treename.len) ;
ltree[info->livetree.len + 1 + info->treename.len] = 0 ;
memcpy(prefix,info->treename.s,info->treename.len) ;
memcpy(prefix + info->treename.len, "-",1) ;
prefix[info->treename.len + 1] = 0 ;
tt[uint32_fmt(tt,info->timeout)] = 0 ;
newargv[m++] = S6RC_BINPREFIX "s6-rc-init" ;
newargv[m++] = "-l" ;
newargv[m++] = ltree ;
newargv[m++] = "-c" ;
newargv[m++] = svdir ;
newargv[m++] = "-p" ;
newargv[m++] = prefix ;
newargv[m++] = "-t" ;
newargv[m++] = tt ;
newargv[m++] = "--" ;
newargv[m++] = info->scandir.s ;
newargv[m++] = 0 ;
log_trace("initiate db of tree: ",info->treename.s," ...") ;
pid = child_spawn0(newargv[0],newargv,envp) ;
if (waitpid_nointr(pid,&wstat, 0) < 0)
{ log_warnusys("wait for ",newargv[0]) ; goto err ; }
if (wstat) { log_warnu("init db of tree: ",info->treename.s) ; goto err ; }
if (!sastr_clean_string(&sasvc,res.sa.s + res.depends)) { log_warnusys("clean dependencies of inner bundle") ; goto err ; }
for (; pos < sasvc.len ; pos += strlen(sasvc.s + pos) +1)
{
char *name = sasvc.s + pos ;
resolve_service_t tmp = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &tmp) ;
if (!resolve_check(sares.s,name)){ log_warnsys("unknown service: ",name) ; goto err ; }
if (!resolve_read(wres,sares.s,name)) { log_warnusys("read resolve file of: ",name) ; goto err ; }
if (!service_resolve_add_deps(&gares,&tmp,sares.s)) { log_warnusys("resolve dependencies of: ",name) ; goto err ; }
resolve_free(wres) ;
}
for (pos = 0 ; pos < genalloc_len(resolve_service_t,&gares) ; pos++)
{
char const *string = genalloc_s(resolve_service_t,&gares)[pos].sa.s ;
char const *name = string + genalloc_s(resolve_service_t,&gares)[pos].name ;
char const *state = string + genalloc_s(resolve_service_t,&gares)[pos].state ;
log_trace("Write state file of: ",name) ;
if (!state_write(&sta,state,name))
{
log_warnusys("write state file of: ",name) ;
goto err ;
}
log_info("Initialized successfully: ",name) ;
}
end:
e = empty ? 2 : 1 ;
err:
resolve_deep_free(DATA_SERVICE, &gares) ;
stralloc_free(&sasvc) ;
resolve_free(wres) ;
stralloc_free(&sares) ;
return e ;
}
/*
* rc_manage.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/rc.h>
#include <string.h>
#include <oblibs/log.h>
#include <skalibs/tai.h>
#include <skalibs/genalloc.h>
#include <skalibs/djbunix.h>
#include <66/ssexec.h>
#include <66/utils.h>
#include <66/resolve.h>
#include <66/state.h>
#include <66/constants.h>
#include <66/db.h>
#include <s6-rc/s6rc-servicedir.h>
/**@Return 1 on success
* @Return 2 on empty database
* @Return 0 on fail */
int rc_manage(ssexec_t *info, resolve_service_t *sv, unsigned int len)
{
log_flow() ;
int r ;
unsigned int pos = 0 ;
ss_state_t sta = STATE_ZERO ;
size_t newlen ;
char prefix[info->treename.len + 2] ;
auto_strings(prefix, info->treename.s, "-") ;
char live[info->livetree.len + 1 + info->treename.len + 1 ];
auto_strings(live, info->livetree.s, "/", info->treename.s) ;
res_s[info->tree.len + SS_SVDIRS_LEN + SS_DB + 1 + info->treename.len + SS_SVDIRS_LEN + 1 + SS_MAX_SERVICE_NAME + 1] ;
auto_strings(res_s, info->tree.s, SS_SVDIRS, SS_DB, "/", info->treename.s, SS_SVDIRS, "/") ;
newlen = info->tree.len + SS_SVDIRS_LEN + SS_DB_LEN + 1 + info->treename.len + SS_SVDIRS_LEN + 1 ;
for (; pos < len ; pos++) {
char const *string = sv[pos].sa.s ;
char const *name = string + sv[pos].name ;
char const *runat = string + sv[pos].runat ;
int type = sv[pos].type ;
//do not try to copy a bundle or oneshot, this is already done.
if (type != TYPE_LONGRUN)
continue ;
auto_strings(res_s + newlen, name) ;
if (!hiercopy(res_s,runat))
log_warnusys_return(LOG_EXIT_ZERO, "copy: ", res_s, " to: ", runat) ;
}
/** do not really init the service if you come from backup,
* s6-rc-update will do the manage proccess for us. If we pass through
* here a double copy of the same service is made and s6-rc-update will fail. */
r = db_find_compiled_state(info->livetree.s, info->treename.s) ;
if (!r) {
tain deadline ;
if (info->timeout)
tain_from_millisecs(&deadline, info->timeout) ;
else deadline = tain_infinite_relative ;
tain_now_g() ;
tain_add_g(&deadline, &deadline) ;
r = s6rc_servicedir_manage_g(live, prefix, &deadline) ;
if (r == -1)
log_warnusys_return(LOG_EXIT_ZERO, "supervise service directories at: ", live, "/servicedirs") ;
}
for (pos = 0 ; i < len ; pos++) {
char const *string = sv[pos].sa.s ;
char const *name = string + sv[pos].name ;
char const *state = string + sv[pos].state ;
log_trace("Write state file of: ", name) ;
if (!state_write(&sta, state, name))
log_warnusys_return(LOG_EXIT_ZERO, "write state file of: ", name) ;
log_info("Initialized successfully: ",name) ;
}
return 1 ;
}
/*
* rc_send.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/rc.h>
#include <stddef.h>
#include <oblibs/log.h>
#include <skalibs/genalloc.h>
#include <66/resolve.h>
#include <66/service.h>
#include <66/ssexec.h>
int rc_send(ssexec_t *info, resolve_service_t *sv, unsigned int len, char const *sig)
{
log_flow() ;
unsigned int pos = 0 ;
int nargc = 3 + len ;
char const *newargv[nargc] ;
unsigned int m = 0 ;
newargv[m++] = "rc_send" ;
newargv[m++] = sig ;
for (; pos < len ; pos++)
newargv[m++] = sv[pos].sa.s + sv[pos].name ;
newargv[m++] = 0 ;
if (ssexec_dbctl(nargc, newargv, (char const *const *) environ, info))
return 0 ;
return 1 ;
}
/*
* rc_unsupervise.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/rc.h>
#include <string.h>
#include <oblibs/log.h>
#include <skalibs/genalloc.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <66/ssexec.h>
#include <66/state.h>
#include <66/resolve.h>
#include <66/db.h>
#include <66/utils.h>
#include <66/constants.h>
#include <s6-rc/s6rc-servicedir.h>
int rc_unsupervise(ssexec_t *info, resolve_service_t *sv, unsigned int len)
{
log_flow() ;
unsigned int pos = 0, e = 0 ;
resolve_service_t_ref pres ;
ss_state_t sta = STATE_ZERO ;
char prefix[info->treename.len + 2] ;
auto_strings(prefix, info->treename.s, "-") ;
char live[info->livetree.len + 1 + info->treename.len + 1 ];
auto_strings(live, info->livetree.s, "/", info->treename.s) ;
if (!db_switch_to(info, SS_SWSRC)) {
log_warnu("switch ", info->treename.s, " to source") ;
goto err ;
}
if (!rc_send(info, ga, sig, envp)) {
log_warnu("stop services") ;
goto err ;
}
for (; pos < len ; pos++) {
pres = &sv[pos] ;
char const *string = pres->sa.s ;
char const *name = string + pres->name ;
log_trace("delete directory service: ", string + pres->runat) ;
s6rc_servicedir_unsupervise(live, prefix, name, 0) ;
if (rm_rf(string + pres->runat) < 0)
goto err ;
}
char res_s[info->base.len + SS_SYSTEM + 1 + info->treename.len + SS_SVDIRS_LEN + 1] ;
auto_strings(res_s, info->base.s, SS_SYSTEM, "/", info->treename.s, SS_SVDIRS) ;
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 ;
// remove the resolve/state file if the service is disabled
if (!pres->disen)
{
log_trace("Delete resolve file of: ", name) ;
resolve_rmfile(res_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 ;
}
}
log_info("Unsupervised successfully: ", name) ;
}
e = 1 ;
err:
return e ;
}
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