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

use tmpfs directory as service directory for the runtime. Deal with logger...

use tmpfs directory as service directory for the runtime. Deal with logger destination directory at init time
parent f44cea2e
No related branches found
No related tags found
No related merge requests found
......@@ -19,13 +19,14 @@
#include <66/service.h>
#include <66/ssexec.h>
#include <66/state.h>
extern int sanitize_system(ssexec_t *info) ;
extern void sanitize_source(char const *name, ssexec_t *info) ;
extern void sanitize_fdholder(resolve_service_t *res, uint32_t flag) ;
extern void sanitize_livestate(resolve_service_t *res) ;
extern void sanitize_scandir(resolve_service_t *res) ;
extern int sanitize_fdholder(resolve_service_t *res, ss_state_t *sta, uint32_t flag) ;
extern int sanitize_livestate(resolve_service_t *res, ss_state_t *sta) ;
extern int sanitize_scandir(resolve_service_t *res, ss_state_t *sta) ;
extern void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen) ;
extern void sanitize_graph(ssexec_t *info) ;
/** @Return 0 the service is already written
......
......@@ -33,14 +33,16 @@
#include <s6/fdholder.h>
void fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *limit)
static int fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *limit)
{
log_flow() ;
size_t namelen = strlen(name) ;
char fdname[SS_FDHOLDER_PIPENAME_LEN + 2 + namelen + 1] ;
int fd[2] ;
if (pipe(fd) < 0)
log_dieu(LOG_EXIT_SYS, "pipe") ;
log_warnu_return(LOG_EXIT_ZERO, "pipe") ;
auto_strings(fdname, SS_FDHOLDER_PIPENAME, "r-", name) ;
......@@ -48,7 +50,7 @@ void fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *li
if (!s6_fdholder_store_g(a, fd[0], fdname, limit, deadline)) {
close(fd[0]) ;
close(fd[1]) ;
log_dieusys(LOG_EXIT_SYS, "store fd: ", fdname) ;
log_warnusys_return(LOG_EXIT_ZERO, "store fd: ", fdname) ;
}
close(fd[0]) ;
......@@ -58,14 +60,18 @@ void fdholder_store(s6_fdholder_t *a, char const *name, tain *deadline, tain *li
log_trace("store identifier: ", fdname) ;
if (!s6_fdholder_store_g(a, fd[1], fdname, limit, deadline)) {
close(fd[1]) ;
log_dieusys(LOG_EXIT_SYS, "store fd: ", fdname) ;
log_warnusys_return(LOG_EXIT_ZERO, "store fd: ", fdname) ;
}
close(fd[1]) ;
return 1 ;
}
void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline)
static int fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline)
{
log_flow() ;
size_t namelen = strlen(name) ;
char fdname[SS_FDHOLDER_PIPENAME_LEN + 2 + namelen + 1] ;
......@@ -74,7 +80,7 @@ void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline)
if (s6_fdholder_retrieve_g(a, fdname, deadline) >= 0) {
log_trace("delete identifier: ", fdname) ;
if (!s6_fdholder_delete_g(a, fdname, deadline))
log_dieusys(LOG_EXIT_SYS, "delete fd: ", fdname) ;
log_warnusys_return(LOG_EXIT_ZERO, "delete fd: ", fdname) ;
}
fdname[strlen(SS_FDHOLDER_PIPENAME)] = 'w' ;
......@@ -83,8 +89,9 @@ void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline)
log_trace("delete identifier: ", fdname) ;
if (!s6_fdholder_delete_g(a, fdname, deadline))
log_dieusys(LOG_EXIT_SYS, "delete fd: ", fdname) ;
log_warnusys_return(LOG_EXIT_ZERO, "delete fd: ", fdname) ;
}
return 1 ;
}
/**
* Accepted flag are
......@@ -93,7 +100,7 @@ void fdholder_delete(s6_fdholder_t *a, char const *name, tain *deadline)
*
* */
void sanitize_fdholder(resolve_service_t *res, uint32_t flag)
int sanitize_fdholder(resolve_service_t *res, ss_state_t *sta, uint32_t flag)
{
log_flow() ;
......@@ -104,22 +111,18 @@ void sanitize_fdholder(resolve_service_t *res, uint32_t flag)
char *name = sa + res->logger.name ;
char *socket = sa + res->live.fdholderdir ;
size_t socketlen = strlen(socket) ;
ss_state_t sta = STATE_ZERO ;
s6_fdholder_t a = S6_FDHOLDER_ZERO ;
tain deadline = tain_infinite_relative, limit = tain_infinite_relative ;
char sock[socketlen + 3] ;
auto_strings(sock, socket, "/s") ;
if (!state_read(&sta, res))
log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ;
tain_now_set_stopwatch_g() ;
tain_add_g(&deadline, &deadline) ;
tain_add_g(&limit, &limit) ;
if (!s6_fdholder_start_g(&a, sock, &deadline))
log_dieusys(LOG_EXIT_SYS, "connect to socket: ", sock) ;
log_warnusys_return(LOG_EXIT_ZERO, "connect to socket: ", sock) ;
if (FLAGS_ISSET(flag, STATE_FLAGS_TRUE)) {
......@@ -128,21 +131,24 @@ void sanitize_fdholder(resolve_service_t *res, uint32_t flag)
sta->torestart == STATE_FLAGS_TRUE) {
log_trace("delete fdholder entry: ", name) ;
fdholder_delete(&a, name, &deadline) ;
if (!fdholder_delete(&a, name, &deadline))
return 0 ;
}
log_trace("store fdholder entry: ", name) ;
fdholder_store(&a, name, &deadline, &limit) ;
if (!fdholder_store(&a, name, &deadline, &limit))
return 0 ;
} else if (FLAGS_ISSET(flag, STATE_FLAGS_FALSE)) {
log_trace("delete fdholder entry: ", name) ;
fdholder_delete(&a, name, &deadline) ;
if (!fdholder_delete(&a, name, &deadline))
return 0 ;
}
if (s6_fdholder_list_g(&a, &list, &deadline) < 0)
log_dieusys(LOG_EXIT_SYS, "list identifier") ;
log_warnusys_return(LOG_EXIT_ZERO, "list identifier") ;
s6_fdholder_end(&a) ;
......@@ -168,10 +174,12 @@ void sanitize_fdholder(resolve_service_t *res, uint32_t flag)
auto_strings(file, socket, "/data/autofilled") ;
if (!openwritenclose_unsafe(file, list.s, list.len))
log_dieusys(LOG_EXIT_SYS, "write file: ", file) ;
log_warnusys_return(LOG_EXIT_ZERO, "write file: ", file) ;
svc_send_fdholder(socket, "twR") ;
stralloc_free(&list) ;
}
return 1 ;
}
......@@ -14,12 +14,15 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>// unlink
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/sastr.h>
#include <oblibs/environ.h>
#include <oblibs/directory.h>
#include <skalibs/types.h>
#include <skalibs/genalloc.h>
......@@ -38,6 +41,36 @@
#include <66/state.h>
#include <66/enum.h>
#include <66/sanitize.h>
#include <66/symlink.h>
static unsigned int toclean[SS_MAX_SERVICE + 1] ;
void cleanup(resolve_service_t *ares, unsigned int areslen)
{
unsigned int pos = 0 ;
int e = errno ;
ss_state_t sta = STATE_ZERO ;
for (; pos < areslen ; pos++) {
if (toclean[pos]) {
if (!sanitize_fdholder(&ares[pos], &sta, STATE_FLAGS_FALSE))
log_warnusys("sanitize fdholder directory: ", ares[pos].sa.s + ares[pos].live.fdholderdir);
log_trace("remove directory: ", ares[pos].sa.s + ares[pos].live.servicedir) ;
if (!dir_rm_rf(ares[pos].sa.s + ares[pos].live.servicedir))
log_warnusys("remove live directory: ", ares[pos].sa.s + ares[pos].live.servicedir) ;
log_trace("remove symlink: ", ares[pos].sa.s + ares[pos].live.scandir) ;
unlink(ares[pos].sa.s + ares[pos].live.scandir) ;
if (!symlink_switch(&ares[pos], SYMLINK_SOURCE))
log_warnusys("switch service symlink to source for: ", ares[pos].sa.s + ares[pos].name) ;
}
}
errno = e ;
}
void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen)
{
......@@ -46,13 +79,14 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
ftrigr_t fifo = FTRIGR_ZERO ;
uint32_t earlier ;
gid_t gid = getgid() ;
int is_supervised = 0, is_init = 0, gearlier = 0 ;
int is_supervised = 0 ;
unsigned int pos = 0, nsv = 0 ;
unsigned int real[alen] ;
unsigned int msg[areslen] ;
ss_state_t sta = STATE_ZERO ;
memset(msg, 0, areslen) ;
memset(msg, 0, areslen * sizeof(unsigned int)) ;
memset(toclean, 0, SS_MAX_SERVICE + 1 * sizeof(unsigned int)) ;
/* nothing to do */
if (!alen)
......@@ -66,20 +100,42 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
if (aresid < 0)
log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ;
if (!state_read(&sta, &ares[aresid]))
log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ;
earlier = sta.isearlier == STATE_FLAGS_TRUE ? 1 : 0 ;
char *sa = ares[aresid].sa.s ;
char *scandir = sa + ares[aresid].live.scandir ;
toclean[pos] = 1 ;
earlier = ares[aresid].earlier ;
char *scandir = ares[aresid].sa.s + ares[aresid].live.scandir ;
size_t scandirlen = strlen(scandir) ;
is_init = access(sa + ares[aresid].live.statedir, F_OK) ;
if (is_init < 0 || sta.toinit == STATE_FLAGS_TRUE)
sanitize_livestate(&ares[aresid]) ;
/** try to read the state following the symlink. It may not exist yet,
* for example at boot after a hard shutdown */
int r = state_read(&sta, &ares[aresid]) ;
if (!symlink_switch(&ares[aresid], SYMLINK_SOURCE))
log_dieu(LOG_EXIT_SYS, "switch service symlink to source for: ", name) ;
if (!r && !state_read(&sta, &ares[aresid]))
log_dieu(LOG_EXIT_SYS, "read state file of: ", name, " -- please make a bug reports") ;
//r = access(ares[aresid].sa.s + ares[aresid].live.servicedir, F_OK) ;
//if (!r) {
//if (sta.isup == STATE_FLAGS_TRUE)
// log_die(LOG_EXIT_USER, "service: ", name, " is running and the frontend file has changed. Please use 66 reconfigure ", name, " command instead.") ;
//log_trace("remove directory: ", ares[aresid].sa.s + ares[aresid].live.servicedir) ;
//if (!dir_rm_rf(ares[aresid].sa.s + ares[aresid].live.servicedir))
// log_dieusys(LOG_EXIT_SYS, "remove live directory: ", ares[aresid].sa.s + ares[aresid].live.servicedir) ;
//}
if (!sanitize_livestate(&ares[aresid], &sta)) {
cleanup(ares, areslen) ;
log_dieu(LOG_EXIT_SYS, "sanitize state directory: ", ares[aresid].sa.s + ares[aresid].name) ;
}
if (!symlink_switch(&ares[aresid], SYMLINK_LIVE)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "switch service symlink to live for: ", name) ;
}
if (earlier)
gearlier = aresid ;
/**
* Bundle and module type are not a daemons. We don't need to supervise it.
* Special case for Oneshot, we only deal with the scandir symlink. */
......@@ -96,7 +152,10 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
if (is_supervised == -1) {
sanitize_scandir(&ares[aresid]) ;
if (!sanitize_scandir(&ares[aresid], &sta)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "sanitize_scandir directory: ", ares[aresid].sa.s + ares[aresid].live.scandir) ;
}
if (ares[aresid].type == TYPE_ONESHOT)
continue ;
......@@ -109,18 +168,30 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
auto_strings(downfile, scandir, "/down") ;
log_trace("create file: ", downfile) ;
int fd = open_trunc(downfile) ;
if (fd < 0)
if (fd < 0) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "create file: ", downfile) ;
}
fd_close(fd) ;
}
if (!earlier && is_supervised) {
sanitize_fdholder(&ares[aresid], STATE_FLAGS_TRUE) ;
if (!sanitize_fdholder(&ares[aresid], &sta, STATE_FLAGS_TRUE)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "sanitize fdholder directory: ", ares[aresid].sa.s + ares[aresid].live.fdholderdir) ;
}
log_trace("create fifo: ", ares[aresid].sa.s + ares[aresid].live.eventdir) ;
if (!ftrigw_fifodir_make(ares[aresid].sa.s + ares[aresid].live.eventdir, gid, 0)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "create fifo: ", ares[aresid].sa.s + ares[aresid].live.eventdir) ;
}
}
log_trace("create fifo: ", sa + ares[aresid].live.eventdir) ;
if (!ftrigw_fifodir_make(sa + ares[aresid].live.eventdir, gid, 0))
log_dieusys(LOG_EXIT_SYS, "create fifo: ", sa + ares[aresid].live.eventdir) ;
if (!state_write(&sta, &ares[aresid])) {
cleanup(ares, areslen) ;
log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ;
}
real[nsv++] = (unsigned int)aresid ;
......@@ -132,19 +203,28 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
if (!earlier && nsv) {
uint16_t ids[nsv] ;
unsigned int nids = 0 ;
unsigned int nids = 0, fake = 0 ;
tain deadline ;
tain_now_set_stopwatch_g() ;
tain_addsec(&deadline, &STAMP, 2) ;
if (!ftrigr_startf_g(&fifo, &deadline))
memset(ids, 0, nsv * sizeof(uint16_t)) ;
tain_now_set_stopwatch_g() ;
/** TODO
* waiting for 3 seconds here,
* it should be the -T option if exist.
*/
tain_addsec(&deadline, &STAMP, 3) ;
if (!ftrigr_startf_g(&fifo, &deadline)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "ftrigr") ;
}
for (pos = 0 ; pos < nsv ; pos++) {
if (ares[real[pos]].type == TYPE_CLASSIC) {
fake = pos ;
char *sa = ares[real[pos]].sa.s ;
char *eventdir = sa + ares[real[pos]].live.eventdir ;
......@@ -152,26 +232,32 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
/** unsubscribe automatically, options is 0 */
ids[nids] = ftrigr_subscribe_g(&fifo, eventdir, "s", 0, &deadline) ;
if (!ids[nids++])
if (!ids[nids++]) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "subcribe to fifo: ", eventdir) ;
if (!state_messenger(&ares[real[pos]], STATE_FLAGS_TORELOAD, STATE_FLAGS_TRUE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", sa + ares[real[pos]].name) ;
}
}
}
if (nids) {
sanitize_scandir(&ares[real[0]]) ;
state_set_flag(&sta, STATE_FLAGS_TORELOAD, STATE_FLAGS_TRUE) ;
if (!sanitize_scandir(&ares[real[fake]], &sta)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "sanitize scandir directory: ", ares[real[fake]].sa.s + ares[real[fake]].live.scandir) ;
}
log_trace("waiting for events on fifo...") ;
if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0)
if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "wait for events") ;
}
}
}
ftrigr_end(&fifo) ;
/**
* We pass through here even for Bundle, Module and Oneshot.
* We need to write the state file anyway. Thus can always
......@@ -179,33 +265,67 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
* */
for (pos = 0 ; pos < alen ; pos++) {
ss_state_t sta = STATE_ZERO ;
char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[alist[pos]].vertex ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0)
log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ;
if (aresid < 0) {
cleanup(ares, areslen) ;
log_dieu(LOG_EXIT_SYS, "find ares id of: ", name, " -- please make a bug reports") ;
}
char *sa = ares[aresid].sa.s ;
if (!state_read(&sta, &ares[aresid])) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "read status file of: ", sa + ares[aresid].name) ;
}
if (ares[aresid].type == TYPE_CLASSIC || ares[aresid].type == TYPE_ONESHOT) {
log_trace("clean event directory: ", sa + ares[aresid].live.eventdir) ;
if (!ftrigw_clean(sa + ares[aresid].live.eventdir))
log_warnu("clean event directory: ", sa + ares[aresid].live.eventdir) ;
} else if (ares[aresid].type == TYPE_BUNDLE || ares[aresid].type == TYPE_MODULE) {
if (ares[aresid].type == TYPE_CLASSIC && ares[aresid].logger.want) {
/** Creation of the logger destination.
* This is made here to avoid issues if the logger destination
* is on tmpfs.
*/
uid_t log_uid ;
gid_t log_gid ;
char *logrunner = ares[aresid].logger.execute.run.runas ? ares[aresid].sa.s + ares[aresid].logger.execute.run.runas : SS_LOGGER_RUNNER ;
if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ;
}
char *dst = ares[aresid].sa.s + ares[aresid].logger.destination ;
if (!dir_create_parent(dst, 0755)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "create directory: ", ares[aresid].sa.s + ares[aresid].logger.destination) ;
}
if (!ares[aresid].owner && (strcmp(ares[aresid].sa.s + ares[aresid].logger.execute.run.build, "custom"))) {
if (chown(dst, log_uid, log_gid) == -1) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "chown: ", dst) ;
}
}
}
/** Consider Module and Bundle as supervised */
if (!state_messenger(&ares[aresid], STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
}
if (!state_messenger(&ares[aresid], STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
/** Consider Module and Bundle as supervised */
state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE) ;
if (!state_write(&sta, &ares[aresid])) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "write status file of: ", sa + ares[aresid].name) ;
}
if (!msg[aresid])
log_info("Initialized successfully: ", name) ;
}
ftrigr_end(&fifo) ;
}
......@@ -25,6 +25,7 @@
#include <skalibs/unix-transactional.h>
#include <skalibs/posixplz.h>
#include <skalibs/djbunix.h>
#include <66/constants.h>
#include <66/sanitize.h>
......@@ -33,8 +34,7 @@
#include <66/state.h>
/** creation of the /run/66/state/<uid> directory */
static void sanitize_livestate_directory(resolve_service_t *res)
static int sanitize_livestate_directory(resolve_service_t *res)
{
log_flow() ;
......@@ -48,78 +48,72 @@ static void sanitize_livestate_directory(resolve_service_t *res)
r = scan_mode(ste, S_IFDIR) ;
if (r < 0)
log_diesys(LOG_EXIT_SYS, "conflicting format for: ", ste) ;
log_warn_return(LOG_EXIT_ZERO, "conflicting format for: ", ste) ;
if (!r) {
log_trace("create directory: ", ste) ;
r = dir_create_parent(ste, 0700) ;
if (!r)
log_dieusys(LOG_EXIT_SYS, "create directory: ", ste) ;
log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", ste) ;
if (!yourgid(&gidowner, res->owner))
log_dieusys(LOG_EXIT_SYS, "get gid of: ", res->sa.s + res->ownerstr) ;
log_warnusys_return(LOG_EXIT_ZERO, "get gid of: ", res->sa.s + res->ownerstr) ;
if (chown(ste, res->owner, gidowner) < 0)
log_dieusys(LOG_EXIT_SYS, "chown: ", ste) ;
log_warnusys_return(LOG_EXIT_ZERO, "chown: ", ste) ;
}
}
/** creation of the /run/66/state/<uid>/<service> symlink */
return 1 ;
}
static void sanitize_livestate_service_symlink(resolve_service_t *res)
/** copy the source frontend directory to livestate */
static int sanitize_copy_source(resolve_service_t *res)
{
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
size_t homelen = strlen(res->sa.s + res->path.home) ;
char sym[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
char dst[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
log_flow() ;
char *home = res->sa.s + res->path.servicedir ;
char *live = res->sa.s + res->live.servicedir ;
char sym[strlen(live) + SS_RESOLVE_LEN + 1] ;
char dst[strlen(home) + SS_RESOLVE_LEN + 1] ;
if (!sanitize_livestate_directory(res))
return 0 ;
log_trace("copy: ", home, " to: ", live) ;
if (!hiercopy(home, live))
log_warnusys_return(LOG_EXIT_ZERO, "copy: ", home, " to: ", live) ;
auto_strings(sym, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
auto_strings(sym, live, SS_RESOLVE) ;
auto_strings(dst, home, SS_RESOLVE) ;
auto_strings(dst, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ;
log_trace("remove directory: ", sym) ;
if (!dir_rm_rf(sym))
log_warnusys_return(LOG_EXIT_ZERO, "remove live directory: ", sym) ;
log_trace("symlink: ", sym, " to: ", dst) ;
if (!atomic_symlink(dst, sym, "livestate"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
log_warnusys_return(LOG_EXIT_ZERO, "symlink: ", sym, " to: ", dst) ;
return 1 ;
}
void sanitize_livestate(resolve_service_t *res)
int sanitize_livestate(resolve_service_t *res, ss_state_t *sta)
{
log_flow() ;
int r ;
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->owner) ;
ss_state_t sta = STATE_ZERO ;
char ste[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
auto_strings(ste, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
if (!state_read(&sta, res))
log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ;
r = access(ste, F_OK) ;
r = access(res->sa.s + res->live.servicedir, F_OK) ;
if (r == -1) {
sanitize_livestate_directory(res) ;
sanitize_livestate_service_symlink(res) ;
} else {
if (sta.tounsupervise == STATE_FLAGS_TRUE) {
log_trace("unlink: ", ste) ;
unlink_void(ste) ;
if (!sanitize_copy_source(res))
return 0 ;
state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
} else if (sta->tounsupervise == STATE_FLAGS_TRUE) {
if (!state_write(&sta, res))
log_dieusys(LOG_EXIT_SYS, "write status file of: ", name) ;
}
log_trace("remove directory: ", res->sa.s + res->live.servicedir) ;
if (!dir_rm_rf(res->sa.s + res->live.servicedir))
log_warnusys_return(LOG_EXIT_ZERO, "remove live directory: ", res->sa.s + res->live.servicedir) ;
}
return 1 ;
}
......@@ -15,6 +15,7 @@
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h> // umask
#include <oblibs/log.h>
......@@ -34,46 +35,26 @@
static void scandir_scandir_to_livestate(resolve_service_t *res)
{
log_flow() ;
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
char sym[livelen + SS_SCANDIR_LEN + 1 + ownerlen + 1 + namelen + 1] ;
char dst[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
auto_strings(sym, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr, "/", name) ;
auto_strings(dst, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
log_trace("symlink: ", sym, " to: ", dst) ;
if (!atomic_symlink(dst, sym, "scandir"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
log_trace("symlink: ", sym, " to: ", res->sa.s + res->live.servicedir) ;
if (!atomic_symlink(res->sa.s + res->live.servicedir, sym, "scandir"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", res->sa.s + res->live.servicedir) ;
}
static void scandir_service_to_scandir(resolve_service_t *res)
int scandir_supervision_dir(resolve_service_t *res)
{
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t homelen = strlen(res->sa.s + res->path.home) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
char sym[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1 + SS_SCANDIR_LEN + 1] ;
char dst[livelen + SS_SCANDIR_LEN + 1 + ownerlen + 1] ;
auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE
, SS_SVC, "/", name, "/", SS_SCANDIR) ;
auto_strings(dst, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr) ;
log_trace("symlink: ", sym, " to: ", dst) ;
if (!atomic_symlink(dst, sym, "scandir"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
}
log_flow() ;
static void compute_supervision_dir(resolve_service_t *res)
{
mode_t hmod = umask(0) ;
char *event = res->sa.s + res->live.eventdir ;
char *supervise = res->sa.s + res->live.supervisedir ;
......@@ -82,102 +63,73 @@ static void compute_supervision_dir(resolve_service_t *res)
log_trace("create directory: ", event) ;
int r = dir_create_parent(event, 0700) ;
if (!r)
log_dieusys(LOG_EXIT_SYS, "create directory: ", event) ;
/**
*
* ISSUE: All the following means writting on a possible
* ro mountpoint, so crash occurs.
*
* */
log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", event) ;
if (chown(event, -1, getegid()) < 0)
log_dieusys(LOG_EXIT_SYS, "chown: ", event) ;
log_warnusys_return(LOG_EXIT_ZERO, "chown: ", event) ;
if (chmod(event, 03730) < 0)
log_dieusys(LOG_EXIT_SYS, "chmod: ", event) ;
log_warnusys_return(LOG_EXIT_ZERO, "chmod: ", event) ;
/* supervise dir*/
/* supervise dir */
log_trace("create directory: ", supervise) ;
r = dir_create_parent(supervise, 0700) ;
if (!r)
log_dieusys(LOG_EXIT_SYS, "create directory: ", event) ;
log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", event) ;
umask(hmod) ;
return 1 ;
}
void sanitize_scandir(resolve_service_t *res)
int sanitize_scandir(resolve_service_t *res, ss_state_t *sta)
{
log_flow() ;
int r ;
char *name = res->sa.s + res->name ;
uint8_t earlier = 0 ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t scandirlen = livelen + SS_SCANDIR_LEN + 1 + strlen(res->sa.s + res->ownerstr) ;
ss_state_t sta = STATE_ZERO ;
char svcandir[scandirlen + 1] ;
auto_strings(svcandir, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr) ;
if (!state_read(&sta, res))
log_dieu(LOG_EXIT_SYS, "read state file of: ", name) ;
r = access(res->sa.s + res->live.scandir, F_OK) ;
if (r == -1 && (sta.toinit == STATE_FLAGS_TRUE || sta.isearlier == STATE_FLAGS_TRUE)) {
if (r == -1 && (sta->toinit == STATE_FLAGS_TRUE || res->earlier)) {
if (res->type == TYPE_CLASSIC)
scandir_scandir_to_livestate(res) ;
scandir_service_to_scandir(res) ;
compute_supervision_dir(res) ;
earlier = service_is(&sta, STATE_FLAGS_ISEARLIER) == STATE_FLAGS_TRUE ? 1 : 0 ;
if (!earlier) {
if (res->earlier) {
if (svc_scandir_send(svcandir, "h") <= 0)
log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ;
log_warnu_return(LOG_EXIT_ZERO, "reload scandir: ", svcandir) ;
}
state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ;
state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE) ;
if (!state_write(&sta, res))
log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ;
state_set_flag(sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ;
state_set_flag(sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
} else {
if (service_is(&sta, STATE_FLAGS_TOUNSUPERVISE) == STATE_FLAGS_TRUE) {
if (sta->tounsupervise == STATE_FLAGS_TRUE) {
char s[livelen + SS_SCANDIR_LEN + 1 + strlen(res->sa.s + res->ownerstr) + 1 + namelen + 1] ;
auto_strings(s, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr, "/", name) ;
log_trace("remove symlink: ", res->sa.s + res->live.scandir) ;
unlink_void(res->sa.s + res->live.scandir) ;
log_trace("remove symlink: ", s) ;
unlink_void(s) ;
state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_FALSE) ;
state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_TRUE) ;
if (!state_write(&sta, res))
log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ;
state_set_flag(sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_FALSE) ;
state_set_flag(sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
if (svc_scandir_send(svcandir, "an") <= 0)
log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ;
log_warnu_return(LOG_EXIT_ZERO, "reload scandir: ", svcandir) ;
} else if (service_is(&sta, STATE_FLAGS_TORELOAD) == STATE_FLAGS_TRUE) {
} else if (sta->toreload == STATE_FLAGS_TRUE) {
if (svc_scandir_send(svcandir, "a") <= 0)
log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ;
state_set_flag(&sta, STATE_FLAGS_TORELOAD, STATE_FLAGS_FALSE) ;
state_set_flag(&sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ;
log_warnu_return(LOG_EXIT_ZERO, "reload scandir: ", svcandir) ;
if (!state_write(&sta, res))
log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ;
state_set_flag(sta, STATE_FLAGS_TORELOAD, STATE_FLAGS_FALSE) ;
state_set_flag(sta, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE) ;
state_set_flag(sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ;
}
}
return 1 ;
}
......@@ -51,6 +51,11 @@ void write_logger(resolve_service_t *res, char const *destination, uint8_t force
char *logrunner = res->execute.run.runas ? res->sa.s + res->execute.run.runas : SS_LOGGER_RUNNER ;
if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) {
parse_cleanup(res, destination, force) ;
log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ;
}
if (res->execute.timeout.kill) {
if (!write_uint(destination, "timeout-kill", res->execute.timeout.kill)) {
parse_cleanup(res, destination, force) ;
......@@ -71,30 +76,11 @@ void write_logger(resolve_service_t *res, char const *destination, uint8_t force
log_dieusys(LOG_EXIT_SYS, "write uint file ", SS_NOTIFICATION) ;
}
/** log destination */
log_trace("create directory: ", res->sa.s + res->logger.destination) ;
if (!dir_create_parent(res->sa.s + res->logger.destination, 0755)) {
parse_cleanup(res, destination, force) ;
log_dieusys(LOG_EXIT_SYS, "create directory: ", res->sa.s + res->logger.destination) ;
}
/**
* ISSUE: In case of e.g. earlier service the log
* may point to a tmpfs directory. At next reboot
* the log directory will not be present. We just
* react as oneshot service making it at .run file
* with execl-toc.
/** log destination
*
* The creation of the log destination directory is made at sanitize_init
* to avoid none existing directory if the destination is on tmpfs directory
*/
if (!owner && ((res->execute.run.build == BUILD_AUTO) || (!res->execute.run.build))) {
if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) {
parse_cleanup(res, destination, force) ;
log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ;
}
if (chown(res->sa.s + res->logger.destination, log_uid, log_gid) == -1) {
parse_cleanup(res, destination, force) ;
log_dieusys(LOG_EXIT_SYS, "chown: ", res->sa.s + res->logger.destination) ;
}
}
char write[strlen(destination) + 10] ;
......@@ -125,4 +111,12 @@ void write_logger(resolve_service_t *res, char const *destination, uint8_t force
parse_cleanup(res, destination, force) ;
log_dieusys(LOG_EXIT_SYS, "chmod", write) ;
}
if (!owner) {
if (chown(write, log_uid, log_gid) == -1) {
parse_cleanup(res, destination, force) ;
log_dieusys(LOG_EXIT_SYS, "chown: ", write) ;
}
}
}
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