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

switch service graph construction to hash map, add parse_append_logger function

parent 9fbb254d
No related branches found
No related tags found
No related merge requests found
Showing
with 687 additions and 568 deletions
......@@ -370,7 +370,7 @@ static void info_display_contents(char const *field, char const *treename)
if (!sa.len)
goto empty ;
service_graph_g_hash(sa.s, sa.len, &graph, &hres, pinfo, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
service_graph_g(sa.s, sa.len, &graph, &hres, pinfo, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
if (!HASH_COUNT(hres))
goto empty ;
......
......@@ -27,8 +27,9 @@
#include <66/graph.h>
#include <66/state.h>
#include <66/config.h>
#include <66/hash.h>
void graph_build_service(graph_t *graph, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag)
void graph_build_service(graph_t *graph, struct resolve_hash_s **hres, ssexec_t *info, uint32_t flag)
{
log_flow() ;
......@@ -41,9 +42,7 @@ void graph_build_service(graph_t *graph, resolve_service_t *ares, unsigned int *
if (!sastr_dir_get_recursive(&sa, solve, exclude, S_IFLNK, 0))
log_dieu(LOG_EXIT_SYS, "get resolve files") ;
memset(ares, 0, (SS_MAX_SERVICE + 1) * sizeof(resolve_service_t)) ;
service_graph_g(sa.s, sa.len, graph, ares, areslen, info, flag) ;
service_graph_g(sa.s, sa.len, graph, hres, info, flag) ;
stralloc_free(&sa) ;
}
......@@ -78,6 +78,5 @@ void graph_build_tree(graph_t *g, struct resolve_hash_tree_s **htres, char const
if (!graph_matrix_sort(g))
log_dieu(LOG_EXIT_SYS, "sort the graph") ;
resolve_free(wres) ;
stralloc_free(&sa) ;
}
......@@ -21,13 +21,13 @@
#include <66/service.h>
#include <66/enum.h>
void graph_compute_visit(resolve_service_t *ares, unsigned int aresid, unsigned int *visit, unsigned int *list, graph_t *graph, unsigned int *nservice, uint8_t requiredby)
void graph_compute_visit(struct resolve_hash_s hash, unsigned int *visit, unsigned int *list, graph_t *graph, unsigned int *nservice, uint8_t requiredby)
{
log_flow() ;
unsigned int l[graph->mlen], c = 0, pos = 0, idx = 0 ;
idx = graph_hash_vertex_get_id(graph, ares[aresid].sa.s + ares[aresid].name) ;
idx = graph_hash_vertex_get_id(graph, hash.res.sa.s + hash.res.name) ;
if (!visit[idx]) {
list[(*nservice)++] = idx ;
......@@ -35,7 +35,7 @@ void graph_compute_visit(resolve_service_t *ares, unsigned int aresid, unsigned
}
/** find dependencies of the service from the graph, do it recursively */
c = graph_matrix_get_edge_g_list(l, graph, ares[aresid].sa.s + ares[aresid].name, requiredby, 1) ;
c = graph_matrix_get_edge_g_list(l, graph, hash.res.sa.s + hash.res.name, requiredby, 1) ;
/** append to the list to deal with */
for (pos = 0 ; pos < c ; pos++) {
......
......@@ -39,7 +39,7 @@
#include <66/sanitize.h>
#include <66/state.h>
static void parse_module_dependencies(stralloc *list, resolve_service_t *res, uint8_t requiredby, resolve_service_t *ares, unsigned int *areslen, uint8_t force, uint8_t conf, ssexec_t *info)
static void parse_module_dependencies(stralloc *list, resolve_service_t *res, uint8_t requiredby, struct resolve_hash_s **hres, uint8_t force, uint8_t conf, ssexec_t *info)
{
log_flow() ;
......@@ -79,7 +79,7 @@ static void parse_module_dependencies(stralloc *list, resolve_service_t *res, ui
(*nfield)++ ;
parse_frontend(sa.s, ares, areslen, info, force, conf, 0, fname, 0, 0) ;
parse_frontend(sa.s, hres, info, force, conf, 0, fname, 0, 0) ;
}
......@@ -142,7 +142,7 @@ static void parse_module_regex(resolve_service_t *res, char *copy, size_t copyle
regex_configure(res, info, copy, name) ;
}
void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint8_t force)
void parse_module(resolve_service_t *res, struct resolve_hash_s **hres, ssexec_t *info, uint8_t force)
{
log_flow() ;
......@@ -236,12 +236,12 @@ void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int
auto_strings(copy + copylen, SS_MODULE_ACTIVATED SS_MODULE_DEPENDS) ;
get_list(&list, copy, name, S_IFREG, exclude) ;
parse_module_dependencies(&list, res, 0, ares, areslen, force, conf, info) ;
parse_module_dependencies(&list, res, 0, hres, force, conf, info) ;
auto_strings(copy + copylen, SS_MODULE_ACTIVATED SS_MODULE_REQUIREDBY) ;
get_list(&list, copy, name, S_IFREG, exclude) ;
parse_module_dependencies(&list, res, 1, ares, areslen, force, conf, info) ;
parse_module_dependencies(&list, res, 1, hres, force, conf, info) ;
}
auto_strings(copy + copylen, SS_MODULE_ACTIVATED) ;
......@@ -307,7 +307,7 @@ void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int
if (!auto_stra(&info->treename, res->sa.s + res->treename))
log_die_nomem("stralloc") ;
parse_frontend(list.s, ares, areslen, info, force, conf, copy, fname, name, res->intree ? res->sa.s + res->intree : 0) ;
parse_frontend(list.s, hres, info, force, conf, copy, fname, name, res->intree ? res->sa.s + res->intree : 0) ;
info->opt_tree = opt_tree ;
}
......@@ -316,7 +316,7 @@ void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int
/** append the module name at each inner depends/requiredby dependencies service name
* and define contents field.*/
parse_rename_interdependences(res, name, ares, areslen) ;
parse_rename_interdependences(res, name, hres, info) ;
/** Remove the module name from requiredby field
* of the dependencies if the service disappears with the
......
parse_append_logger.o
parse_clean_line.o
parse_clean_list.o
parse_clean_quotes.o
......
/*
* parse_append_logger.c
*
* Copyright (c) 2018-2023 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 <oblibs/string.h>
#include <oblibs/log.h>
#include <66/resolve.h>
#include <66/service.h>
#include <66/enum.h>
#include <66/constants.h>
#include <66/config.h>
#include <66/utils.h>
#include <66/config.h>
#include <66/parse.h>
#include <s6/config.h>
#ifndef FAKELEN
#define FAKELEN strlen(run)
#endif
static uint32_t compute_log_dir(resolve_wrapper_t_ref wres, resolve_service_t *res)
{
log_flow() ;
size_t namelen = strlen(res->sa.s + res->name) ;
size_t syslen = res->owner ? strlen(res->sa.s + res->path.home) + strlen(SS_LOGGER_USERDIR) : strlen(SS_LOGGER_SYSDIR) ;
size_t dstlen = res->logger.destination ? strlen(res->sa.s + res->logger.destination) : strlen(SS_LOGGER_SYSDIR) ;
char dstlog[syslen + dstlen + namelen + 1] ;
if (!res->logger.destination) {
if (res->owner) {
char home[syslen + 1 + strlen(SS_LOGGER_USERDIR) + 1] ;
if (!set_ownerhome_stack(home))
log_dieusys(LOG_EXIT_SYS,"set home directory") ;
auto_strings(dstlog, home, SS_LOGGER_USERDIR, res->sa.s + res->name) ;
} else
auto_strings(dstlog, SS_LOGGER_SYSDIR, res->sa.s + res->name) ;
} else {
auto_strings(dstlog, res->sa.s + res->logger.destination) ;
}
return resolve_add_string(wres, dstlog) ;
}
static void compute_log_script(resolve_service_t *res, resolve_service_t *log)
{
log_flow() ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, log) ;
int build = !strcmp(res->sa.s + res->logger.execute.run.build, "custom") ? BUILD_CUSTOM : BUILD_AUTO ;
char *pmax = 0 ;
char *pback = 0 ;
char max[UINT32_FMT] ;
char back[UINT32_FMT] ;
char *timestamp = 0 ;
int itimestamp = SS_LOGGER_TIMESTAMP ;
char *logrunner = res->logger.execute.run.runas ? res->sa.s + res->logger.execute.run.runas : SS_LOGGER_RUNNER ;
log->execute.run.runas = resolve_add_string(wres, logrunner) ;
/** timestamp */
if (res->logger.timestamp != 3)
timestamp = res->logger.timestamp == TIME_NONE ? "" : res->logger.timestamp == TIME_ISO ? "T" : "t" ;
else
timestamp = itimestamp == TIME_NONE ? "" : itimestamp == TIME_ISO ? "T" : "t" ;
/** backup */
if (res->logger.backup) {
back[uint32_fmt(back,res->logger.backup)] = 0 ;
pback = back ;
}
/** file size */
if (res->logger.maxsize) {
max[uint32_fmt(max,res->logger.maxsize)] = 0 ;
pmax = max ;
}
char *shebang = "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ;
{
/** run scripts */
char run[SS_MAX_PATH_LEN + 1] ;
auto_strings(run, \
shebang, \
"s6-fdholder-retrieve ", \
res->sa.s + res->live.fdholderdir, "/s ", \
"\"" SS_FDHOLDER_PIPENAME "r-", \
res->sa.s + res->logger.name, "\"\n", \
"./run.user\n") ;
log->execute.run.run = resolve_add_string(wres, run) ;
}
{
if (!build) {
/** run.user script */
char run[SS_MAX_PATH_LEN + 1] ;
auto_strings(run, shebang) ;
auto_strings(run + FAKELEN, "fdmove -c 2 1\n") ;
/** runas */
if (!res->owner)
auto_strings(run + FAKELEN, S6_BINPREFIX "s6-setuidgid ", logrunner, "\n") ;
auto_strings(run + FAKELEN, "s6-log ") ;
if (SS_LOGGER_NOTIFY)
auto_strings(run + FAKELEN, "-d3 ") ;
auto_strings(run + FAKELEN, "n", pback, " ") ;
if (res->logger.timestamp < TIME_NONE)
auto_strings(run + FAKELEN, timestamp, " ") ;
auto_strings(run + FAKELEN, "s", pmax, " ", res->sa.s + res->logger.destination, "\n") ;
log->execute.run.run_user = resolve_add_string(wres, run) ;
} else {
if (res->logger.execute.run.shebang)
log_warn("@shebang field is deprecated -- please define it at start of your @execute field instead") ;
char *shebang = res->logger.execute.run.shebang ? res->sa.s + res->logger.execute.run.shebang : "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ;
size_t shebanglen = strlen(shebang) ;
char run[shebanglen + strlen(res->sa.s + res->logger.execute.run.run_user) + 2] ;
auto_strings(run, shebang, res->sa.s + res->logger.execute.run.run_user, "\n") ;
log->execute.run.run_user = resolve_add_string(wres, run) ;
}
}
free(wres) ;
}
static void compute_logger(resolve_service_t *res, resolve_service_t *log, ssexec_t *info)
{
log_flow() ;
if (!res->logger.name)
return ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, log) ;
resolve_init(wres) ;
char *str = res->sa.s ;
size_t namelen = strlen(str + res->logger.name) ;
char name[namelen + 1] ;
char description[namelen + 7 + 1] ;
auto_strings(name, str + res->logger.name) ;
auto_strings(description, str + res->name, " logger") ;
log->name = resolve_add_string(wres, name) ;
log->description = resolve_add_string(wres, description) ;
log->version = resolve_add_string(wres, str + res->version) ;
log->type = res->type ;
log->notify = 3 ;
log->maxdeath = res->maxdeath ;
log->earlier = res->earlier ;
if (res->intree)
log->intree = resolve_add_string(wres, str + res->intree) ;
log->ownerstr = resolve_add_string(wres, str + res->ownerstr) ;
log->owner = res->owner ;
log->treename = resolve_add_string(wres, str + res->treename) ;
log->user = resolve_add_string(wres, str + res->user) ;
if (res->inns)
log->inns = resolve_add_string(wres, str + res->inns) ;
log->path.home = resolve_add_string(wres, str + res->path.home) ;
log->path.frontend = resolve_add_string(wres, str + res->path.frontend) ;
log->path.servicedir = compute_src_servicedir(wres, info) ;
log->dependencies.requiredby = resolve_add_string(wres, str + res->name) ;
log->dependencies.nrequiredby = 1 ;
log->execute.run.build = resolve_add_string(wres, str + res->logger.execute.run.build) ;
log->execute.run.shebang = res->logger.execute.run.shebang ? resolve_add_string(wres, str + res->logger.execute.run.shebang) : 0 ;
log->execute.run.runas = resolve_add_string(wres, str + res->logger.execute.run.runas) ;
log->execute.timeout.kill = res->logger.execute.timeout.kill ;
log->execute.timeout.finish = res->logger.execute.timeout.finish ;
log->execute.down = res->logger.execute.down ;
log->execute.downsignal = res->logger.execute.downsignal ;
log->live.livedir = resolve_add_string(wres, info->live.s) ;
log->live.status = compute_status(wres, info) ;
log->live.servicedir = compute_live_servicedir(wres, info) ;
log->live.scandir = compute_scan_dir(wres, info) ;
log->live.statedir = compute_state_dir(wres, info, SS_STATE + 1) ;
log->live.eventdir = compute_state_dir(wres, info, SS_EVENTDIR + 1) ;
log->live.notifdir = compute_state_dir(wres, info, "notif") ;
log->live.supervisedir = compute_state_dir(wres, info, SS_SUPERVISEDIR + 1) ;
log->live.fdholderdir = compute_pipe_service(wres, info, SS_FDHOLDER) ;
log->live.oneshotddir = compute_pipe_service(wres, info, SS_ONESHOTD) ;
log->logger.destination = resolve_add_string(wres, str + res->logger.destination) ;
log->logger.backup = res->logger.backup ;
log->logger.maxsize = res->logger.maxsize ;
log->logger.timestamp = res->logger.timestamp ;
log->logger.want = 0 ;
// oneshot do not use fdholder daemon
if (res->type == TYPE_CLASSIC)
compute_log_script(res, log) ;
free(wres) ;
}
void parse_append_logger(struct resolve_hash_s **hres, resolve_service_t *res, ssexec_t *info)
{
log_flow() ;
char *name = res->sa.s + res->name ;
struct resolve_hash_s *hash ;
resolve_service_t lres = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
size_t namelen = strlen(name) ;
char logname[namelen + SS_LOG_SUFFIX_LEN + 1] ;
auto_strings(logname, name, SS_LOG_SUFFIX) ;
res->logger.name = resolve_add_string(wres, logname) ;
res->logger.destination = compute_log_dir(wres, res) ;
res->logger.execute.run.runas = res->logger.execute.run.runas ? resolve_add_string(wres, res->sa.s + res->logger.execute.run.runas) : resolve_add_string(wres, SS_LOGGER_RUNNER) ;
hash = hash_search(hres, logname) ;
if (hash == NULL && res->type == TYPE_CLASSIC) {
/** the logger is not a service with oneshot type */
if (res->dependencies.ndepends) {
char buf[strlen(res->sa.s + res->dependencies.depends) + 1 + strlen(res->sa.s + res->logger.name) + 1] ;
auto_strings(buf, res->sa.s + res->dependencies.depends, " ", res->sa.s + res->logger.name) ;
res->dependencies.depends = resolve_add_string(wres, buf) ;
} else {
res->dependencies.depends = resolve_add_string(wres, res->sa.s + res->logger.name) ;
}
res->dependencies.ndepends++ ;
compute_logger(res, &lres, info) ;
/** sanitize_init use this field */
res->logger.execute.run.run = resolve_add_string(wres, lres.sa.s + lres.execute.run.run) ;
res->logger.execute.run.run_user = resolve_add_string(wres, lres.sa.s + lres.execute.run.run_user) ;
if (hash_count(hres) > SS_MAX_SERVICE)
log_die(LOG_EXIT_SYS, "too many services to parse -- compile again 66 changing the --max-service options") ;
log_trace("add service: ", logname, " to the service selection") ;
if (!hash_add(hres, logname, lres))
log_dieu(LOG_EXIT_SYS, "append service selection with: ", logname) ;
}
free(wres) ;
}
\ No newline at end of file
......@@ -37,7 +37,7 @@
#define FAKELEN strlen(run)
#endif
static uint32_t compute_src_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
uint32_t compute_src_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
{
log_flow() ;
......@@ -52,7 +52,7 @@ static uint32_t compute_src_servicedir(resolve_wrapper_t_ref wres, ssexec_t *inf
return resolve_add_string(wres, dir) ;
}
static uint32_t compute_live_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
uint32_t compute_live_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
{
log_flow() ;
......@@ -68,7 +68,7 @@ static uint32_t compute_live_servicedir(resolve_wrapper_t_ref wres, ssexec_t *in
}
static uint32_t compute_status(resolve_wrapper_t_ref wres, ssexec_t *info)
uint32_t compute_status(resolve_wrapper_t_ref wres, ssexec_t *info)
{
log_flow() ;
......@@ -84,7 +84,7 @@ static uint32_t compute_status(resolve_wrapper_t_ref wres, ssexec_t *info)
}
static uint32_t compute_scan_dir(resolve_wrapper_t_ref wres, ssexec_t *info)
uint32_t compute_scan_dir(resolve_wrapper_t_ref wres, ssexec_t *info)
{
log_flow() ;
......@@ -99,7 +99,7 @@ static uint32_t compute_scan_dir(resolve_wrapper_t_ref wres, ssexec_t *info)
return resolve_add_string(wres, dir) ;
}
static uint32_t compute_state_dir(resolve_wrapper_t_ref wres, ssexec_t *info, char const *folder)
uint32_t compute_state_dir(resolve_wrapper_t_ref wres, ssexec_t *info, char const *folder)
{
log_flow() ;
......@@ -115,7 +115,7 @@ static uint32_t compute_state_dir(resolve_wrapper_t_ref wres, ssexec_t *info, ch
return resolve_add_string(wres, dir) ;
}
static uint32_t compute_pipe_service(resolve_wrapper_t_ref wres, ssexec_t *info, char const *service, char const *name)
uint32_t compute_pipe_service(resolve_wrapper_t_ref wres, ssexec_t *info, char const *name)
{
log_flow() ;
......@@ -128,39 +128,6 @@ static uint32_t compute_pipe_service(resolve_wrapper_t_ref wres, ssexec_t *info,
}
static uint32_t compute_log_dir(resolve_wrapper_t_ref wres, resolve_service_t *res)
{
log_flow() ;
size_t namelen = strlen(res->sa.s + res->name) ;
size_t syslen = res->owner ? strlen(res->sa.s + res->path.home) + strlen(SS_LOGGER_USERDIR) : strlen(SS_LOGGER_SYSDIR) ;
size_t dstlen = res->logger.destination ? strlen(res->sa.s + res->logger.destination) : strlen(SS_LOGGER_SYSDIR) ;
char dstlog[syslen + dstlen + namelen + 1] ;
if (!res->logger.destination) {
if (res->owner) {
char home[SS_MAX_PATH_LEN + 1 + strlen(SS_LOGGER_USERDIR) + 1] ;
if (!set_ownerhome_stack(home))
log_dieusys(LOG_EXIT_SYS,"set home directory") ;
auto_strings(dstlog, home, SS_LOGGER_USERDIR, res->sa.s + res->name) ;
} else
auto_strings(dstlog, SS_LOGGER_SYSDIR, res->sa.s + res->name) ;
} else {
auto_strings(dstlog, res->sa.s + res->logger.destination) ;
}
return resolve_add_string(wres, dstlog) ;
}
/**
* @!runorfinish -> finish, @runorfinish -> run
* */
......@@ -170,9 +137,8 @@ static void compute_wrapper_scripts(resolve_service_t *res, resolve_service_addo
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
char *shebang = "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -" ;
size_t shebanglen = strlen(shebang) ;
char run[shebanglen + strlen(res->sa.s + res->live.fdholderdir) + SS_FDHOLDER_PIPENAME_LEN + strlen(res->sa.s + res->name) + SS_LOG_SUFFIX_LEN + strlen(S6_BINPREFIX) + (SS_MAX_PATH*2) + SS_MAX_PATH + strlen(file) + 132 + 1] ;
char run[SS_MAX_PATH_LEN + 1] ;
auto_strings(run, shebang, !runorfinish ? (res->type != TYPE_ONESHOT ? "S0\n" : "P\n") : "P\n") ;
......@@ -196,7 +162,7 @@ static void compute_wrapper_scripts(resolve_service_t *res, resolve_service_addo
}
/**
* @!runorfinish -> finish, @runofinish -> run
* @!runorfinish -> finish.user, @runofinish -> run.user
* */
static void compute_wrapper_scripts_user(resolve_service_t *res, resolve_service_addon_scripts_t *scripts, uint8_t runorfinish)
{
......@@ -251,209 +217,10 @@ static void compute_wrapper_scripts_user(resolve_service_t *res, resolve_service
free(wres) ;
}
static void compute_log_script(resolve_service_t *res)
{
log_flow() ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
int build = !strcmp(res->sa.s + res->logger.execute.run.build, "custom") ? BUILD_CUSTOM : BUILD_AUTO ;
char *pmax = 0 ;
char *pback = 0 ;
char max[UINT32_FMT] ;
char back[UINT32_FMT] ;
char *timestamp = 0 ;
int itimestamp = SS_LOGGER_TIMESTAMP ;
char *logrunner = res->logger.execute.run.runas ? res->sa.s + res->logger.execute.run.runas : SS_LOGGER_RUNNER ;
res->logger.execute.run.runas = resolve_add_string(wres, logrunner) ;
/** timestamp */
if (res->logger.timestamp != 3)
timestamp = res->logger.timestamp == TIME_NONE ? "" : res->logger.timestamp == TIME_ISO ? "T" : "t" ;
else
timestamp = itimestamp == TIME_NONE ? "" : itimestamp == TIME_ISO ? "T" : "t" ;
/** backup */
if (res->logger.backup) {
back[uint32_fmt(back,res->logger.backup)] = 0 ;
pback = back ;
}
/** file size */
if (res->logger.maxsize) {
max[uint32_fmt(max,res->logger.maxsize)] = 0 ;
pmax = max ;
}
char *shebang = "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ;
size_t shebanglen = strlen(shebang) ;
{
/** run scripts */
char run[strlen(shebang) + strlen(res->sa.s + res->live.fdholderdir) + SS_FDHOLDER_PIPENAME_LEN + strlen(res->sa.s + res->logger.name) + strlen(logrunner) + strlen(S6_BINPREFIX) + strlen(res->sa.s + res->logger.execute.run.runas) + 67 + 1] ;
auto_strings(run, \
shebang, \
"s6-fdholder-retrieve ", \
res->sa.s + res->live.fdholderdir, "/s ", \
"\"" SS_FDHOLDER_PIPENAME "r-", \
res->sa.s + res->logger.name, "\"\n") ;
auto_strings(run + FAKELEN, "./run.user\n") ;
res->logger.execute.run.run = resolve_add_string(wres, run) ;
}
{
if (!build) {
/** run.user script */
char run[shebanglen + strlen(pback) + strlen(timestamp) + strlen(pmax) + strlen(res->sa.s + res->logger.destination) + 17 + 1] ;
auto_strings(run, shebang) ;
auto_strings(run + FAKELEN, "fdmove -c 2 1\n") ;
/** runas */
if (!res->owner)
auto_strings(run + FAKELEN, S6_BINPREFIX "s6-setuidgid ", logrunner, "\n") ;
auto_strings(run + FAKELEN, "s6-log ") ;
if (SS_LOGGER_NOTIFY)
auto_strings(run + FAKELEN, "-d3 ") ;
auto_strings(run + FAKELEN, "n", pback, " ") ;
if (res->logger.timestamp < TIME_NONE)
auto_strings(run + FAKELEN, timestamp, " ") ;
auto_strings(run + FAKELEN, "s", pmax, " ", res->sa.s + res->logger.destination, "\n") ;
res->logger.execute.run.run_user = resolve_add_string(wres, run) ;
} else {
if (res->logger.execute.run.shebang)
log_warn("@shebang field is deprecated -- please define it at start of your @execute field instead") ;
char *shebang = res->logger.execute.run.shebang ? res->sa.s + res->logger.execute.run.shebang : "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ;
size_t shebanglen = strlen(shebang) ;
char run[shebanglen + strlen(res->sa.s + res->logger.execute.run.run_user) + 2] ;
auto_strings(run, shebang, res->sa.s + res->logger.execute.run.run_user, "\n") ;
res->logger.execute.run.run_user = resolve_add_string(wres, run) ;
}
}
free(wres) ;
}
static void compute_log(resolve_service_t *res, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info)
void parse_compute_resolve(resolve_service_t *res, ssexec_t *info)
{
log_flow() ;
if (!res->logger.name)
return ;
resolve_service_t lres = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &lres) ;
resolve_init(wres) ;
char *str = res->sa.s ;
size_t namelen = strlen(str + res->logger.name) ;
char name[namelen + 1] ;
char description[namelen + 7 + 1] ;
auto_strings(name, str + res->logger.name) ;
auto_strings(description, str + res->name, " logger") ;
lres.name = resolve_add_string(wres, name) ;
lres.description = resolve_add_string(wres, description) ;
lres.version = resolve_add_string(wres, str + res->version) ;
lres.type = res->type ;
lres.notify = 3 ;
lres.maxdeath = res->maxdeath ;
lres.earlier = res->earlier ;
if (res->intree)
lres.intree = resolve_add_string(wres, str + res->intree) ;
lres.ownerstr = resolve_add_string(wres, str + res->ownerstr) ;
lres.owner = res->owner ;
lres.treename = resolve_add_string(wres, str + res->treename) ;
lres.user = resolve_add_string(wres, str + res->user) ;
if (res->inns)
lres.inns = resolve_add_string(wres, str + res->inns) ;
lres.path.home = resolve_add_string(wres, str + res->path.home) ;
lres.path.frontend = resolve_add_string(wres, str + res->path.frontend) ;
lres.path.servicedir = compute_src_servicedir(wres, info) ;
lres.dependencies.requiredby = resolve_add_string(wres, str + res->name) ;
lres.dependencies.nrequiredby = 1 ;
lres.execute.run.build = resolve_add_string(wres, str + res->logger.execute.run.build) ;
lres.execute.run.shebang = res->logger.execute.run.shebang ? resolve_add_string(wres, str + res->logger.execute.run.shebang) : 0 ;
lres.execute.run.runas = res->logger.execute.run.runas ? resolve_add_string(wres, str + res->logger.execute.run.runas) : resolve_add_string(wres, SS_LOGGER_RUNNER) ;
lres.execute.timeout.kill = res->logger.execute.timeout.kill ;
lres.execute.timeout.finish = res->logger.execute.timeout.finish ;
lres.execute.down = res->logger.execute.down ;
lres.execute.downsignal = res->logger.execute.downsignal ;
lres.live.livedir = resolve_add_string(wres, info->live.s) ;
lres.live.status = compute_status(wres, info) ;
lres.live.servicedir = compute_live_servicedir(wres, info) ;
lres.live.scandir = compute_scan_dir(wres, info) ;
lres.live.statedir = compute_state_dir(wres, info, SS_STATE + 1) ;
lres.live.eventdir = compute_state_dir(wres, info, SS_EVENTDIR + 1) ;
lres.live.notifdir = compute_state_dir(wres, info, "notif") ;
lres.live.supervisedir = compute_state_dir(wres, info, SS_SUPERVISEDIR + 1) ;
lres.live.fdholderdir = compute_pipe_service(wres, info, name, SS_FDHOLDER) ;
lres.live.oneshotddir = compute_pipe_service(wres, info, name, SS_ONESHOTD) ;
lres.logger.destination = resolve_add_string(wres, str + res->logger.destination) ;
lres.logger.backup = res->logger.backup ;
lres.logger.maxsize = res->logger.maxsize ;
lres.logger.timestamp = res->logger.timestamp ;
lres.logger.want = 0 ;
// oneshot do not use fdholder daemon
if (res->type == TYPE_CLASSIC) {
compute_log_script(res) ;
lres.execute.run.run = resolve_add_string(wres, res->sa.s + res->logger.execute.run.run) ;
lres.execute.run.run_user = resolve_add_string(wres, res->sa.s + res->logger.execute.run.run_user) ;
lres.execute.run.runas = resolve_add_string(wres, res->sa.s + res->logger.execute.run.runas) ;
}
if (service_resolve_array_search(ares, *areslen, name) < 0) {
log_trace("add service ", name, " to the selection") ;
if (*areslen > SS_MAX_SERVICE)
log_die(LOG_EXIT_SYS, "too many services to parse -- compile again 66 changing the --max-service options") ;
ares[(*areslen)++] = lres ;
}
free(wres) ;
}
void parse_compute_resolve(unsigned int idx, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info)
{
log_flow() ;
resolve_service_t_ref res = &ares[idx] ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
char name[strlen(res->sa.s + res->name) + 1] ;
......@@ -486,43 +253,10 @@ void parse_compute_resolve(unsigned int idx, resolve_service_t *ares, unsigned i
res->live.supervisedir = compute_state_dir(wres, info, SS_SUPERVISEDIR + 1) ;
/* fdholder */
res->live.fdholderdir = compute_pipe_service(wres, info, name, SS_FDHOLDER) ;
res->live.fdholderdir = compute_pipe_service(wres, info, SS_FDHOLDER) ;
/* oneshotd */
res->live.oneshotddir = compute_pipe_service(wres, info, name, SS_ONESHOTD) ;
if (res->logger.want && (res->type == TYPE_CLASSIC || res->type == TYPE_ONESHOT)) {
size_t namelen = strlen(name) ;
char logname[namelen + SS_LOG_SUFFIX_LEN + 1] ;
auto_strings(logname, name, SS_LOG_SUFFIX) ;
res->logger.name = resolve_add_string(wres, logname) ;
res->logger.destination = compute_log_dir(wres, res) ;
if (res->type == TYPE_CLASSIC) {
/** the logger is not a service with oneshot type */
if (res->dependencies.ndepends) {
char buf[strlen(res->sa.s + res->dependencies.depends) + 1 + strlen(res->sa.s + res->logger.name) + 1] ;
auto_strings(buf, res->sa.s + res->dependencies.depends, " ", res->sa.s + res->logger.name) ;
res->dependencies.depends = resolve_add_string(wres, buf) ;
} else {
res->dependencies.depends = resolve_add_string(wres, res->sa.s + res->logger.name) ;
}
res->dependencies.ndepends++ ;
compute_log(res, ares, areslen, info) ;
}
}
res->live.oneshotddir = compute_pipe_service(wres, info, SS_ONESHOTD) ;
if (res->type == TYPE_ONESHOT || res->type == TYPE_CLASSIC) {
......
......@@ -86,7 +86,7 @@ static void parse_service_instance(stralloc *frontend, char const *svsrc, char c
* @Die on fail
* @Return 1 on success
* @Return 2 -> already parsed */
int parse_frontend(char const *sv, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint8_t force, uint8_t conf, char const *forced_directory, char const *main, char const *inns, char const *intree)
int parse_frontend(char const *sv, struct resolve_hash_s **hres, ssexec_t *info, uint8_t force, uint8_t conf, char const *forced_directory, char const *main, char const *inns, char const *intree)
{
log_flow() ;
......@@ -95,6 +95,7 @@ int parse_frontend(char const *sv, resolve_service_t *ares, unsigned int *aresle
size_t svlen = strlen(sv) ;
char svname[svlen + 1], svsrc[svlen + 1] ;
stralloc sa = STRALLOC_ZERO ;
struct resolve_hash_s *hash ;
if (!ob_basename(svname, sv))
log_dieu(LOG_EXIT_SYS, "get basename of: ", sv) ;
......@@ -104,18 +105,21 @@ int parse_frontend(char const *sv, resolve_service_t *ares, unsigned int *aresle
if (inns) {
if (service_resolve_array_search(ares, *areslen, svname) >= 0)
hash = hash_search(hres, svname) ;
if (hash != NULL)
log_warn_return(2, "ignoring: ", svname, " service -- already appended to the selection") ;
char n[strlen(inns) + 1 + strlen(svname) + 1] ;
auto_strings(n, inns, ":", svname) ;
if (service_resolve_array_search(ares, *areslen, n) >= 0)
hash = hash_search(hres, n) ;
if (hash != NULL)
log_warn_return(2, "ignoring: ", n, " service -- already appended to the selection") ;
} else {
if (service_resolve_array_search(ares, *areslen, svname) >= 0)
hash = hash_search(hres, svname) ;
if (hash != NULL)
log_warn_return(2, "ignoring: ", svname, " service -- already appended to the selection") ;
}
......@@ -262,19 +266,28 @@ int parse_frontend(char const *sv, resolve_service_t *ares, unsigned int *aresle
/** parse interdependences if the service was never parsed */
if (isparsed == STATE_FLAGS_FALSE) {
if (!parse_interdependences(svname, res.sa.s + res.dependencies.depends, res.dependencies.ndepends, ares, areslen, info, force, conf, forced_directory, main, inns, intree))
if (!parse_interdependences(svname, res.sa.s + res.dependencies.depends, res.dependencies.ndepends, hres, info, force, conf, forced_directory, main, inns, intree))
log_dieu(LOG_EXIT_SYS, "parse dependencies of service: ", svname) ;
}
if (res.type == TYPE_MODULE)
parse_module(&res, ares, areslen, info, force) ;
parse_module(&res, hres, info, force) ;
if (service_resolve_array_search(ares, *areslen, res.sa.s + res.name) < 0) {
parse_compute_resolve(&res, info) ;
log_trace("add service ", res.sa.s + res.name, " to the selection") ;
if (*areslen > SS_MAX_SERVICE)
if (res.logger.want && res.type != TYPE_MODULE && !res.inns)
parse_append_logger(hres, &res, info) ;
hash = hash_search(hres, res.sa.s + res.name) ;
if (hash == NULL) {
if (hash_count(hres) > SS_MAX_SERVICE)
log_die(LOG_EXIT_SYS, "too many services to parse -- compile again 66 changing the --max-service options") ;
ares[(*areslen)++] = res ;
log_trace("add service: ", res.sa.s + res.name, " to the service selection") ;
char *name = res.sa.s + res.name ; // hash_add + log_dieu doesn't accept res.sa.s + res.name
if (!hash_add(hres, name, res))
log_dieu(LOG_EXIT_SYS, "append service selection with: ", name) ;
}
stralloc_free(&sa) ;
......
......@@ -30,7 +30,7 @@
#include <66/instance.h>
#include <66/module.h>
int parse_interdependences(char const *service, char const *list, unsigned int listlen, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint8_t force, uint8_t conf, char const *forced_directory, char const *main, char const *inns, char const *intree)
int parse_interdependences(char const *service, char const *list, unsigned int listlen, struct resolve_hash_s **hres, ssexec_t *info, uint8_t force, uint8_t conf, char const *forced_directory, char const *main, char const *inns, char const *intree)
{
log_flow() ;
......@@ -89,7 +89,7 @@ int parse_interdependences(char const *service, char const *list, unsigned int l
* forced_directory == 0 means that the service
* comes from an external directory of the module.
* In this case don't associated it at the module. */
parse_frontend(sa.s, ares, areslen, info, force, conf, forced_directory, main, !forced_directory ? 0 : inns, !forced_directory ? 0 : intree) ;
parse_frontend(sa.s, hres, info, force, conf, forced_directory, main, !forced_directory ? 0 : inns, !forced_directory ? 0 : intree) ;
}
} else
......
......@@ -27,124 +27,123 @@
#include <66/resolve.h>
#include <66/enum.h>
#include <66/constants.h>
#include <66/hash.h>
static void parse_prefix(char *result, stack *stk, resolve_service_t *ares, unsigned int areslen, char const *prefix)
static void parse_prefix(char *result, stack *stk, struct resolve_hash_s **hres, char const *prefix)
{
log_flow() ;
int aresid = -1 ;
size_t pos = 0, mlen = strlen(prefix) ;
struct resolve_hash_s *hash ;
FOREACH_STK(stk, pos) {
aresid = service_resolve_array_search(ares, areslen, stk->s + pos) ;
hash = hash_search(hres, stk->s + pos) ;
if (hash == NULL) {
if (aresid < 0) {
/** try with the name of the prefix as prefix */
char tmp[mlen + 1 + strlen(stk->s + pos) + 1] ;
auto_strings(tmp, prefix, ":", stk->s + pos) ;
aresid = service_resolve_array_search(ares, areslen, tmp) ;
if (aresid < 0)
hash = hash_search(hres, tmp) ;
if (hash == NULL)
log_die(LOG_EXIT_USER, "service: ", stk->s + pos, " not available -- please make a bug report") ;
}
/** check if the dependencies is a external one. In this
* case, the service is not considered as part of the prefix */
if (ares[aresid].inns && (!strcmp(ares[aresid].sa.s + ares[aresid].inns, prefix)))
* case, the service is not considered as part of the ns */
if (hash->res.inns && (!strcmp(hash->res.sa.s + hash->res.inns, prefix)) && str_start_with(hash->res.sa.s + hash->res.name, prefix))
auto_strings(result + strlen(result), prefix, ":", stk->s + pos, " ") ;
else
auto_strings(result + strlen(result), stk->s + pos, " ") ;
auto_strings(result + strlen(result), hash->res.sa.s + hash->res.name, " ") ;
}
result[strlen(result) - 1] = 0 ;
}
static void parse_prefix_name(unsigned int idx, resolve_service_t *ares, unsigned int areslen, char const *prefix)
static void parse_prefix_name(resolve_service_t *res, struct resolve_hash_s **hres, char const *prefix)
{
log_flow() ;
size_t mlen = strlen(prefix) ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &ares[idx]) ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
if (ares[idx].dependencies.ndepends) {
if (res->dependencies.ndepends) {
size_t depslen = strlen(ares[idx].sa.s + ares[idx].dependencies.depends) ;
size_t depslen = strlen(res->sa.s + res->dependencies.depends) ;
_init_stack_(stk, depslen + 1) ;
if (!stack_clean_string(&stk, res->sa.s + res->dependencies.depends, depslen))
log_dieusys(LOG_EXIT_SYS, "convert string to stack") ;
size_t len = (mlen + 1 + SS_MAX_TREENAME + 2) * ares[idx].dependencies.ndepends ;
size_t len = (mlen + 1 + SS_MAX_TREENAME + 2) * res->dependencies.ndepends ;
char n[len] ;
memset(n, 0, len * sizeof(char)); ;
parse_prefix(n, &stk, ares, areslen, prefix) ;
parse_prefix(n, &stk, hres, prefix) ;
ares[idx].dependencies.depends = resolve_add_string(wres, n) ;
res->dependencies.depends = resolve_add_string(wres, n) ;
}
if (ares[idx].dependencies.nrequiredby) {
if (res->dependencies.nrequiredby) {
size_t depslen = strlen(ares[idx].sa.s + ares[idx].dependencies.requiredby) ;
size_t depslen = strlen(res->sa.s + res->dependencies.requiredby) ;
_init_stack_(stk, depslen + 1) ;
if (!stack_clean_string(&stk, res->sa.s + res->dependencies.requiredby, depslen))
log_dieusys(LOG_EXIT_SYS, "convert string to stack") ;
size_t len = (mlen + 1 + SS_MAX_TREENAME + 2) * ares[idx].dependencies.nrequiredby ;
size_t len = (mlen + 1 + SS_MAX_TREENAME + 2) * res->dependencies.nrequiredby ;
char n[len] ;
memset(n, 0, len * sizeof(char)) ;
parse_prefix(n, &stk, ares, areslen, prefix) ;
parse_prefix(n, &stk, hres, prefix) ;
ares[idx].dependencies.requiredby = resolve_add_string(wres, n) ;
res->dependencies.requiredby = resolve_add_string(wres, n) ;
}
free(wres) ;
}
void parse_rename_interdependences(resolve_service_t *res, char const *prefix, resolve_service_t *ares, unsigned int *areslen)
void parse_rename_interdependences(resolve_service_t *res, char const *prefix, struct resolve_hash_s **hres, ssexec_t *info)
{
log_flow() ;
unsigned int aresid = 0 ;
size_t plen = strlen(prefix) ;
unsigned int visit[SS_MAX_SERVICE + 1] ;
resolve_wrapper_t_ref awres = 0 ;
struct resolve_hash_s *c, *tmp ;
stralloc sa = STRALLOC_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
memset(visit, 0, (SS_MAX_SERVICE + 1) * sizeof(unsigned int)) ;
for (; aresid < *areslen ; aresid++) {
HASH_ITER(hh, *hres, c, tmp) {
if (!strcmp(ares[aresid].sa.s + ares[aresid].inns, prefix)) {
if (!strcmp(c->res.sa.s + c->res.inns, prefix)) {
if (ares[aresid].dependencies.ndepends || ares[aresid].dependencies.nrequiredby)
parse_prefix_name(aresid, ares, *areslen, prefix) ;
if (c->res.dependencies.ndepends || c->res.dependencies.nrequiredby)
parse_prefix_name(&c->res, hres, prefix) ;
if (ares[aresid].logger.want && ares[aresid].type == TYPE_CLASSIC) {
if (c->res.logger.want && (c->res.type == TYPE_CLASSIC || c->res.type == TYPE_ONESHOT)) {
char n[strlen(ares[aresid].sa.s + ares[aresid].name) + SS_LOG_SUFFIX_LEN + 1] ;
size_t namelen = strlen(c->res.sa.s + c->res.name) ;
char logname[namelen + SS_LOG_SUFFIX_LEN + 1] ;
auto_strings(n, ares[aresid].sa.s + ares[aresid].name, SS_LOG_SUFFIX) ;
auto_strings(logname, c->res.sa.s + c->res.name, SS_LOG_SUFFIX) ;
if (!sastr_add_string(&sa, n))
log_die_nomem("stralloc") ;
}
parse_append_logger(hres, &c->res, info) ;
char tmp[plen + 1 + strlen(ares[aresid].sa.s + ares[aresid].name) + 1] ;
if (c->res.type == TYPE_CLASSIC) {
if (!sastr_add_string(&sa, logname))
log_die_nomem("stralloc") ;
}
auto_strings(tmp, prefix, ":", ares[aresid].sa.s + ares[aresid].name) ;
}
if (!sastr_add_string(&sa, ares[aresid].sa.s + ares[aresid].name))
log_die_nomem("stralloc") ;
if (sastr_cmp(&sa, c->res.sa.s + c->res.name) < 0 )
if (!sastr_add_string(&sa, c->res.sa.s + c->res.name))
log_die_nomem("stralloc") ;
}
}
......@@ -152,5 +151,4 @@ void parse_rename_interdependences(resolve_service_t *res, char const *prefix, r
stralloc_free(&sa) ;
free(wres) ;
free(awres) ;
}
......@@ -38,6 +38,7 @@
#include <66/graph.h>
#include <66/sanitize.h>
#include <66/symlink.h>
#include <66/hash.h>
parse_mill_t MILL_GET_SECTION_NAME = \
{ \
......@@ -163,77 +164,69 @@ static void parse_write_state(resolve_service_t *res, char const *dst, uint8_t f
}
}
void parse_service(char const *sv, ssexec_t *info, uint8_t force, uint8_t conf)
void parse_service(struct resolve_hash_s **hres, char const *sv, ssexec_t *info, uint8_t force, uint8_t conf)
{
log_flow();
int r ;
unsigned int areslen = 0, count = 0, pos = 0 ;
uint8_t rforce = 0 ;
resolve_service_t ares[SS_MAX_SERVICE + 1] ;
stralloc sa = STRALLOC_ZERO ;
struct resolve_hash_s *c, *tmp ;
char main[strlen(sv) + 1] ;
if (!ob_basename(main, sv))
log_dieu(LOG_EXIT_SYS, "get basename of: ", sv) ;
r = parse_frontend(sv, ares, &areslen, info, force, conf, 0, main, 0, 0) ;
r = parse_frontend(sv, hres, info, force, conf, 0, main, 0, 0) ;
if (r == 2)
/** already parsed */
return ;
/** parse_compute_resolve add the logger
* to the ares array */
count = areslen ;
for (; pos < count ; pos++)
parse_compute_resolve(pos, ares, &areslen, info) ;
for (pos = 0 ; pos < areslen ; pos++) {
HASH_ITER(hh, *hres, c, tmp) {
sa.len = 0 ;
/** be paranoid */
rforce = 0 ;
size_t namelen = strlen(ares[pos].sa.s + ares[pos].name), homelen = strlen(ares[pos].sa.s + ares[pos].path.home) ;
size_t namelen = strlen(c->res.sa.s + c->res.name), homelen = strlen(c->res.sa.s + c->res.path.home) ;
char servicedir[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
auto_strings(servicedir, ares[pos].sa.s + ares[pos].path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", ares[pos].sa.s + ares[pos].name) ;
auto_strings(servicedir, c->res.sa.s + c->res.path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", c->res.sa.s + c->res.name) ;
if (sanitize_write(&ares[pos], force))
if (sanitize_write(&c->res, force))
rforce = 1 ;
if (!auto_stra(&sa, "/tmp/", ares[pos].sa.s + ares[pos].name, ":XXXXXX"))
if (!auto_stra(&sa, "/tmp/", c->res.sa.s + c->res.name, ":XXXXXX"))
log_die_nomem("stralloc") ;
if (!mkdtemp(sa.s))
log_dieusys(LOG_EXIT_SYS, "create temporary directory") ;
write_services(&ares[pos], sa.s, rforce) ;
write_services(&c->res, sa.s, rforce) ;
parse_write_state(&ares[pos], sa.s, rforce) ;
parse_write_state(&c->res, sa.s, rforce) ;
service_resolve_write_remote(&ares[pos], sa.s, rforce) ;
service_resolve_write_remote(&c->res, sa.s, rforce) ;
parse_copy_to_source(servicedir, sa.s, &ares[pos], rforce) ;
parse_copy_to_source(servicedir, sa.s, &c->res, rforce) ;
/** do not die here, just warn the user */
log_trace("remove temporary directory: ", sa.s) ;
if (!dir_rm_rf(sa.s))
log_warnu("remove temporary directory: ", sa.s) ;
tree_service_add(ares[pos].sa.s + ares[pos].treename, ares[pos].sa.s + ares[pos].name, info) ;
tree_service_add(c->res.sa.s + c->res.treename, c->res.sa.s + c->res.name, info) ;
if (!symlink_make(&ares[pos]))
if (!symlink_make(&c->res))
log_dieusys(LOG_EXIT_SYS, "make service symlink") ;
/** symlink may exist already, be sure to point to the correct location */
if (!symlink_switch(&ares[pos], SYMLINK_SOURCE))
if (!symlink_switch(&c->res, SYMLINK_SOURCE))
log_dieusys(LOG_EXIT_SYS, "sanitize_symlink") ;
log_info("Parsed successfully: ", ares[pos].sa.s + ares[pos].name, " at tree: ", ares[pos].sa.s + ares[pos].treename) ;
log_info("Parsed successfully: ", c->res.sa.s + c->res.name, " at tree: ", c->res.sa.s + c->res.treename) ;
}
service_resolve_array_free(ares, areslen) ;
stralloc_free(&sa) ;
}
......@@ -30,6 +30,7 @@
#include <66/graph.h>
#include <66/constants.h>
#include <66/enum.h>
#include <66/hash.h>
/** rewrite depends/requiredby of each service
* found on the system */
......@@ -37,53 +38,53 @@ void sanitize_graph(ssexec_t *info)
{
log_flow() ;
int n = 0 ;
uint32_t flag = 0 ;
unsigned int areslen = 0 ;
stralloc sa = STRALLOC_ZERO ;
resolve_service_t ares[SS_MAX_SERVICE + 1] ;
struct resolve_hash_s *hres = NULL, *c, *tmp ;
graph_t graph = GRAPH_ZERO ;
resolve_wrapper_t_ref wres = 0 ;
FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_TOPARSE|STATE_FLAGS_WANTUP|STATE_FLAGS_WANTDOWN) ;
log_trace("sanitize system graph") ;
/** build the graph of the entire system */
graph_build_service(&graph, ares, &areslen, info, flag) ;
graph_build_service(&graph, &hres, info, flag) ;
for (; n < areslen ; n++) {
HASH_ITER(hh, hres, c, tmp) {
sa.len = 0 ;
resolve_service_t_ref res = &ares[n] ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
char *name = res->sa.s + res->name ;
wres = resolve_set_struct(DATA_SERVICE, &c->res) ;
char *name = c->res.sa.s + c->res.name ;
if (graph_matrix_get_edge_g_sa(&sa, &graph, name, 0, 0) < 0)
log_dieu(LOG_EXIT_SYS, "get dependencies of service: ", name) ;
res->dependencies.ndepends = 0 ;
res->dependencies.depends = 0 ;
c->res.dependencies.ndepends = 0 ;
c->res.dependencies.depends = 0 ;
if (sa.len)
res->dependencies.depends = parse_compute_list(wres, &sa, &res->dependencies.ndepends, 0) ;
c->res.dependencies.depends = parse_compute_list(wres, &sa, &c->res.dependencies.ndepends, 0) ;
sa.len = 0 ;
if (graph_matrix_get_edge_g_sa(&sa, &graph, name, 1, 0) < 0)
log_dieu(LOG_EXIT_SYS, "get requiredby of service: ", name) ;
res->dependencies.nrequiredby = 0 ;
res->dependencies.requiredby = 0 ;
c->res.dependencies.nrequiredby = 0 ;
c->res.dependencies.requiredby = 0 ;
if (sa.len)
res->dependencies.requiredby = parse_compute_list(wres, &sa, &res->dependencies.nrequiredby, 0) ;
c->res.dependencies.requiredby = parse_compute_list(wres, &sa, &c->res.dependencies.nrequiredby, 0) ;
if (!resolve_write_g(wres, info->base.s, name))
log_dieu(LOG_EXIT_SYS, "write resolve file of service: ", name) ;
free(wres) ;
resolve_free(wres) ;
}
service_resolve_array_free(ares, areslen) ;
graph_free_all(&graph) ;
stralloc_free(&sa) ;
hash_free(&hres) ;
graph_free_all(&graph) ;
}
......@@ -42,105 +42,109 @@
#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)
void cleanup(struct resolve_hash_s *hash, unsigned int alen)
{
unsigned int pos = 0 ;
int e = errno ;
ss_state_t sta = STATE_ZERO ;
resolve_service_t_ref pres = 0 ;
for (; pos < areslen ; pos++) {
for (; pos < alen ; pos++) {
if (toclean[pos]) {
pres = &hash[pos].res ;
if (!sanitize_fdholder(&ares[pos], &sta, STATE_FLAGS_FALSE, 0))
log_warnusys("sanitize fdholder directory: ", ares[pos].sa.s + ares[pos].live.fdholderdir);
if (!sanitize_fdholder(pres, &sta, STATE_FLAGS_FALSE, 0))
log_warnusys("sanitize fdholder directory: ", pres->sa.s + pres->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 directory: ", pres->sa.s + pres->live.servicedir) ;
if (!dir_rm_rf(pres->sa.s + pres->live.servicedir))
log_warnusys("remove live directory: ", pres->sa.s + pres->live.servicedir) ;
log_trace("remove symlink: ", pres->sa.s + pres->live.scandir) ;
unlink(pres->sa.s + pres->live.scandir) ;
log_trace("remove symlink: ", ares[pos].sa.s + ares[pos].live.scandir) ;
unlink(ares[pos].sa.s + ares[pos].live.scandir) ;
}
}
errno = e ;
}
void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen)
void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, struct resolve_hash_s **hres)
{
log_flow() ;
/* nothing to do */
if (!alen)
return ;
ftrigr_t fifo = FTRIGR_ZERO ;
uint32_t earlier ;
gid_t gid = getgid() ;
int is_supervised = 0 ;
unsigned int pos = 0, nsv = 0 ;
unsigned int real[alen], msg[areslen] ;
unsigned int pos = 0, nsv = 0, msg[alen] ;
ss_state_t sta = STATE_ZERO ;
resolve_service_t_ref pres = 0 ;
struct resolve_hash_s toclean[alen] ;
struct resolve_hash_s real[alen] ;
unsigned int ntoclean = 0 ;
memset(msg, 0, areslen * sizeof(unsigned int)) ;
memset(toclean, 0, (SS_MAX_SERVICE + 1) * sizeof(unsigned int)) ;
/* nothing to do */
if (!alen)
return ;
memset(msg, 0, alen * sizeof(unsigned int)) ;
memset(toclean, 0, alen * sizeof(struct resolve_hash_s)) ;
memset(real, 0, alen * sizeof(struct resolve_hash_s)) ;
for (; pos < alen ; pos++) {
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)
struct resolve_hash_s *hash = hash_search(hres,name) ;
if (hash == NULL)
log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ;
toclean[aresid] = 1 ;
earlier = ares[aresid].earlier ;
char *scandir = ares[aresid].sa.s + ares[aresid].live.scandir ;
pres = &hash->res ;
toclean[ntoclean++] = *hash ;
earlier = pres->earlier ;
char *scandir = pres->sa.s + pres->live.scandir ;
size_t scandirlen = strlen(scandir) ;
int r = state_read(&sta, &ares[aresid]) ;
int r = state_read(&sta, pres) ;
if (!r)
log_dieu(LOG_EXIT_SYS, "read state file of: ", name, " -- please make a bug reports") ;
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 (!sanitize_livestate(pres, &sta)) {
cleanup(toclean, ntoclean) ;
log_dieu(LOG_EXIT_SYS, "sanitize state directory: ", pres->sa.s + pres->name) ;
}
/**
* Module type are not a daemons. We don't need to supervise it.
* Special case for Oneshot, we only deal with the scandir symlink. */
if (ares[aresid].type == TYPE_MODULE)
if (pres->type == TYPE_MODULE)
continue ;
is_supervised = access(scandir, F_OK) ;
if (!earlier && !is_supervised) {
log_trace(name," already initialized -- ignore it") ;
msg[aresid] = 1 ;
msg[pos] = 1 ;
continue ;
}
if (is_supervised == -1) {
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 (!sanitize_scandir(pres, &sta)) {
cleanup(toclean, pos) ;
log_dieusys(LOG_EXIT_SYS, "sanitize_scandir directory: ", pres->sa.s + pres->live.scandir) ;
}
if (ares[aresid].type == TYPE_ONESHOT) {
if (pres->type == TYPE_ONESHOT) {
if (!state_write(&sta, &ares[aresid])) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "write status file of: ", ares[aresid].sa.s + ares[aresid].name) ;
if (!state_write(&sta, pres)) {
cleanup(toclean, pos) ;
log_dieusys(LOG_EXIT_SYS, "write status file of: ", pres->sa.s + pres->name) ;
}
continue ;
}
}
/* down file */
......@@ -151,7 +155,7 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
log_trace("create file: ", downfile) ;
int fd = open_trunc(downfile) ;
if (fd < 0) {
cleanup(ares, areslen) ;
cleanup(toclean, pos) ;
log_dieusys(LOG_EXIT_SYS, "create file: ", downfile) ;
}
fd_close(fd) ;
......@@ -159,24 +163,24 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
if (!earlier && is_supervised) {
if (!sanitize_fdholder(&ares[aresid], &sta, STATE_FLAGS_TRUE, 1)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "sanitize fdholder directory: ", ares[aresid].sa.s + ares[aresid].live.fdholderdir) ;
if (!sanitize_fdholder(pres, &sta, STATE_FLAGS_TRUE, 1)) {
cleanup(toclean, pos) ;
log_dieusys(LOG_EXIT_SYS, "sanitize fdholder directory: ", pres->sa.s + pres->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: ", pres->sa.s + pres->live.eventdir) ;
if (!ftrigw_fifodir_make(pres->sa.s + pres->live.eventdir, gid, 0)) {
cleanup(toclean, pos) ;
log_dieusys(LOG_EXIT_SYS, "create fifo: ", pres->sa.s + pres->live.eventdir) ;
}
}
if (!state_write(&sta, &ares[aresid])) {
cleanup(ares, areslen) ;
if (!state_write(&sta, pres)) {
cleanup(toclean, pos) ;
log_dieu(LOG_EXIT_SYS, "write state file of: ", name) ;
}
real[nsv++] = (unsigned int)aresid ;
real[nsv++] = *hash ;
}
/**
......@@ -198,24 +202,24 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
tain_addsec(&deadline, &STAMP, 3) ;
if (!ftrigr_startf_g(&fifo, &deadline)) {
cleanup(ares, areslen) ;
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "ftrigr") ;
}
for (pos = 0 ; pos < nsv ; pos++) {
if (ares[real[pos]].type == TYPE_CLASSIC && !ares[real[pos]].earlier) {
if (real[pos].res.type == TYPE_CLASSIC && !real[pos].res.earlier) {
fake = pos ;
char *sa = ares[real[pos]].sa.s ;
char *eventdir = sa + ares[real[pos]].live.eventdir ;
char *sa = real[pos].res.sa.s ;
char *eventdir = sa + real[pos].res.live.eventdir ;
log_trace("subcribe to fifo: ", eventdir) ;
/** unsubscribe automatically, options is 0 */
ids[nids] = ftrigr_subscribe_g(&fifo, eventdir, "s", 0, &deadline) ;
if (!ids[nids++]) {
cleanup(ares, areslen) ;
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "subcribe to fifo: ", eventdir) ;
}
}
......@@ -225,14 +229,14 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
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) ;
if (!sanitize_scandir(&real[fake].res, &sta)) {
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "sanitize scandir directory: ", real[fake].res.sa.s + real[fake].res.live.scandir) ;
}
log_trace("waiting for events on fifo...") ;
if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0) {
cleanup(ares, areslen) ;
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "wait for events") ;
}
}
......@@ -249,55 +253,56 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
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) {
cleanup(ares, areslen) ;
log_dieu(LOG_EXIT_SYS, "find ares id of: ", name, " -- please make a bug reports") ;
struct resolve_hash_s *hash = hash_search(hres, name) ;
if (hash == NULL) {
cleanup(toclean, ntoclean) ;
log_dieu(LOG_EXIT_SYS, "find hash id of: ", name, " -- please make a bug reports") ;
}
char *sa = ares[aresid].sa.s ;
pres = &hash->res ;
char *sa = pres->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 (!state_read(&sta, pres)) {
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "read status file of: ", sa + pres->name) ;
}
if (ares[aresid].type == TYPE_CLASSIC) {
if (pres->type == TYPE_CLASSIC) {
if (!earlier) {
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) ;
log_trace("clean event directory: ", sa + pres->live.eventdir) ;
if (!ftrigw_clean(sa + pres->live.eventdir))
log_warnu("clean event directory: ", sa + pres->live.eventdir) ;
}
}
if (ares[aresid].type == TYPE_CLASSIC || ares[aresid].type == TYPE_ONESHOT) {
if (ares[aresid].logger.want) {
/** Creation of the logger destination. This is made here to avoid
* issues on tmpfs logger directory destination */
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 ;
char *dst = ares[aresid].sa.s + ares[aresid].logger.destination ;
if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ;
}
log_trace("create directory: ", dst) ;
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 ((pres->type == TYPE_CLASSIC || pres->type == TYPE_ONESHOT) && pres->logger.want) {
/** Creation of the logger destination. This is made here to avoid
* issues on tmpfs logger directory destination */
uid_t log_uid ;
gid_t log_gid ;
char *logrunner = pres->sa.s + pres->logger.execute.run.runas ;
char *dst = pres->sa.s + pres->logger.destination ;
if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) {
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ;
}
log_trace("create directory: ", dst) ;
if (!dir_create_parent(dst, 0755)) {
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "create directory: ", dst) ;
}
if (!ares[aresid].owner && (strcmp(ares[aresid].sa.s + ares[aresid].logger.execute.run.build, "custom"))) {
if (!pres->owner && (strcmp(pres->sa.s + pres->logger.execute.run.build, "custom"))) {
if (chown(dst, log_uid, log_gid) == -1) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "chown: ", dst) ;
}
if (chown(dst, log_uid, log_gid) == -1) {
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "chown: ", dst) ;
}
}
}
......@@ -306,12 +311,12 @@ void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_s
state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE) ;
state_set_flag(&sta, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE) ;
if (!state_write(&sta, &ares[aresid])) {
cleanup(ares, areslen) ;
log_dieusys(LOG_EXIT_SYS, "write status file of: ", sa + ares[aresid].name) ;
if (!state_write(&sta, pres)) {
cleanup(toclean, ntoclean) ;
log_dieusys(LOG_EXIT_SYS, "write status file of: ", sa + pres->name) ;
}
if (!msg[aresid])
if (!msg[pos])
log_info("Initialized successfully: ", name) ;
}
}
......@@ -7,9 +7,8 @@ service_frontend_src.o
service_graph_build.o
service_graph_collect.o
service_graph_g.o
service_hash.o
service_is_g.o
service_resolve_array_free.o
service_resolve_array_search.o
service_resolve_copy.o
service_resolve_get_field_tosa.o
service_resolve_modify_field.o
......
......@@ -17,6 +17,7 @@
#include <oblibs/log.h>
#include <oblibs/graph.h>
#include <oblibs/stack.h>
#include <oblibs/sastr.h>
#include <skalibs/stralloc.h>
......@@ -27,13 +28,13 @@
#include <66/enum.h>
#include <66/ssexec.h>
static void service_enable_disable_deps(graph_t *g, unsigned int idx, resolve_service_t *ares, unsigned int areslen, uint8_t action, unsigned int *visit, uint8_t propagate, ssexec_t *info)
static void service_enable_disable_deps(graph_t *g, struct resolve_hash_s *hash, struct resolve_hash_s **hres, uint8_t action, uint8_t propagate, ssexec_t *info)
{
log_flow() ;
size_t pos = 0 ;
stralloc sa = STRALLOC_ZERO ;
resolve_service_t_ref res = &ares[idx] ;
resolve_service_t_ref res = &hash->res ;
if (graph_matrix_get_edge_g_sa(&sa, g, res->sa.s + res->name, action ? 0 : 1, 0) < 0)
log_dieu(LOG_EXIT_SYS, "get ", action ? "dependencies" : "required by" ," of: ", res->sa.s + res->name) ;
......@@ -43,12 +44,15 @@ static void service_enable_disable_deps(graph_t *g, unsigned int idx, resolve_se
FOREACH_SASTR(&sa, pos) {
char *name = sa.s + pos ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0)
struct resolve_hash_s *h = hash_search(hres, name) ;
if (h == NULL)
log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parse it?") ;
if (!visit[aresid])
service_enable_disable(g, aresid, ares, areslen, action, visit, propagate, info) ;
if (!h->visit) {
service_enable_disable(g, h, hres, action, propagate, info) ;
h->visit = 1 ;
}
}
}
......@@ -57,27 +61,29 @@ static void service_enable_disable_deps(graph_t *g, unsigned int idx, resolve_se
/** @action -> 0 disable
* @action -> 1 enable */
void service_enable_disable(graph_t *g, unsigned int idx, resolve_service_t *ares, unsigned int areslen, uint8_t action, unsigned int *visit, uint8_t propagate, ssexec_t *info)
void service_enable_disable(graph_t *g, struct resolve_hash_s *hash, struct resolve_hash_s **hres, uint8_t action, uint8_t propagate, ssexec_t *info)
{
log_flow() ;
if (!visit[idx]) {
if (!hash->visit) {
resolve_service_t_ref res = &ares[idx] ;
resolve_service_t_ref res = &hash->res ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
char const *treename = res->sa.s + (res->intree ? res->intree : res->treename) ;
/** resolve file may already exist. Be sure to add it to the contents field of the tree.*/
if (action)
tree_service_add(res->sa.s + (res->intree ? res->intree : res->treename), res->sa.s + res->name, info) ;
tree_service_add(treename, res->sa.s + res->name, info) ;
if (!service_resolve_modify_field(res, E_RESOLVE_SERVICE_ENABLED, !action ? "0" : "1"))
log_dieu(LOG_EXIT_SYS, "modify resolve file of: ", res->sa.s + res->name) ;
res->enabled = action ;
if (!resolve_write_g(wres, res->sa.s + res->path.home, res->sa.s + res->name))
log_dieu(LOG_EXIT_SYS, "write resolve file of: ", res->sa.s + res->name) ;
if (propagate)
service_enable_disable_deps(g, idx, ares, areslen, action, visit, propagate, info) ;
service_enable_disable_deps(g, hash, hres, action, propagate, info) ;
free(wres) ;
/** the logger must be disabled to avoid to start it
* with the 66 tree start <tree> command */
......@@ -85,26 +91,27 @@ void service_enable_disable(graph_t *g, unsigned int idx, resolve_service_t *are
char *name = res->sa.s + res->logger.name ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0)
struct resolve_hash_s *h = hash_search(hres, name) ;
if (h == NULL)
log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parse it?") ;
if (!visit[aresid]) {
if (!h->visit) {
wres = resolve_set_struct(DATA_SERVICE, &ares[aresid]) ;
wres = resolve_set_struct(DATA_SERVICE, &h->res) ;
if (action)
tree_service_add(ares[aresid].sa.s + (ares[aresid].intree ? ares[aresid].intree : ares[aresid].treename), ares[aresid].sa.s + ares[aresid].name, info) ;
tree_service_add(treename, h->res.sa.s + h->res.name, info) ;
if (!service_resolve_modify_field(&ares[aresid], E_RESOLVE_SERVICE_ENABLED, !action ? "0" : "1"))
log_dieu(LOG_EXIT_SYS, "modify resolve file of: ", ares[aresid].sa.s + ares[aresid].name) ;
h->res.enabled = action ;
if (!resolve_write_g(wres, ares[aresid].sa.s + ares[aresid].path.home, ares[aresid].sa.s + ares[aresid].name))
log_dieu(LOG_EXIT_SYS, "write resolve file of: ", ares[aresid].sa.s + ares[aresid].name) ;
if (!resolve_write_g(wres, h->res.sa.s + h->res.path.home, h->res.sa.s + h->res.name))
log_dieu(LOG_EXIT_SYS, "write resolve file of: ", h->res.sa.s + h->res.name) ;
log_info("Disabled successfully service: ", name) ;
log_info("Disabled successfully: ", name) ;
visit[aresid] = 1 ;
h->visit = 1 ;
resolve_free(wres) ;
}
}
......@@ -121,36 +128,37 @@ void service_enable_disable(graph_t *g, unsigned int idx, resolve_service_t *are
FOREACH_STK(&stk, pos) {
char *name = stk.s + pos ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0)
struct resolve_hash_s *h = hash_search(hres, name) ;
if (h == NULL)
log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parse it?") ;
if (!visit[aresid]) {
if (!h->visit) {
wres = resolve_set_struct(DATA_SERVICE, &ares[aresid]) ;
wres = resolve_set_struct(DATA_SERVICE, &h->res) ;
if (action)
tree_service_add(ares[aresid].sa.s + (ares[aresid].intree ? ares[aresid].intree : ares[aresid].treename), ares[aresid].sa.s + ares[aresid].name, info) ;
tree_service_add(treename, h->res.sa.s + h->res.name, info) ;
if (!service_resolve_modify_field(&ares[aresid], E_RESOLVE_SERVICE_ENABLED, !action ? "0" : "1"))
log_dieu(LOG_EXIT_SYS, "modify resolve file of: ", ares[aresid].sa.s + ares[aresid].name) ;
h->res.enabled = action ;
if (!resolve_write_g(wres, ares[aresid].sa.s + ares[aresid].path.home, ares[aresid].sa.s + ares[aresid].name))
log_dieu(LOG_EXIT_SYS, "write resolve file of: ", ares[aresid].sa.s + ares[aresid].name) ;
if (!resolve_write_g(wres, h->res.sa.s + h->res.path.home, h->res.sa.s + h->res.name))
log_dieu(LOG_EXIT_SYS, "write resolve file of: ", h->res.sa.s + h->res.name) ;
service_enable_disable_deps(g, aresid, ares, areslen, action, visit, propagate, info) ;
service_enable_disable_deps(g, h, hres, action, propagate, info) ;
visit[aresid] = 1 ;
h->visit = 1 ;
log_info(!action ? "Disabled" : "Enabled"," successfully service: ", ares[aresid].sa.s + ares[aresid].name) ;
log_info(!action ? "Disabled" : "Enabled"," successfully service: ", h->res.sa.s + h->res.name) ;
resolve_free(wres) ;
}
}
}
}
free(wres) ;
visit[idx] = 1 ;
hash->visit = 1 ;
log_info(!action ? "Disabled" : "Enabled"," successfully service: ", ares[idx].sa.s + ares[idx].name) ;
log_info(!action ? "Disabled" : "Enabled"," successfully: ", hash->res.sa.s + hash->res.name) ;
}
}
......@@ -23,8 +23,9 @@
#include <66/service.h>
#include <66/graph.h>
#include <66/state.h>
#include <66/hash.h>
static void issupervised(char *store, resolve_service_t *ares, unsigned int areslen, char const *str)
static void issupervised(char *store, struct resolve_hash_s **hres, char const *str)
{
size_t pos = 0, len = strlen(str) ;
ss_state_t ste = STATE_ZERO ;
......@@ -39,16 +40,16 @@ static void issupervised(char *store, resolve_service_t *ares, unsigned int ares
char *name = stk.s + pos ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0) {
struct resolve_hash_s *hash = hash_search(hres, name) ;
if (hash == NULL) {
log_warn("service: ", name, " not available -- ignore it") ;
continue ;
}
if (!state_check(&ares[aresid]))
if (!state_check(&hash->res))
continue ;
if (!state_read(&ste, &ares[aresid]))
if (!state_read(&ste, &hash->res))
continue ;
if (ste.issupervised == STATE_FLAGS_TRUE)
......@@ -60,23 +61,23 @@ static void issupervised(char *store, resolve_service_t *ares, unsigned int ares
store[strlen(store) - 1] = 0 ;
}
void service_graph_build(graph_t *g, resolve_service_t *ares, unsigned int areslen, uint32_t flag)
void service_graph_build(graph_t *g, struct resolve_hash_s **hres, uint32_t flag)
{
log_flow() ;
unsigned int pos = 0 ;
ss_state_t ste = STATE_ZERO ;
resolve_service_t_ref pres = 0 ;
struct resolve_hash_s *c, *tmp ;
for (; pos < areslen ; pos++) {
HASH_ITER(hh, *hres, c, tmp) {
pres = &ares[pos] ;
pres = &c->res ;
char *service = pres->sa.s + pres->name ;
if (!state_check(&ares[pos]))
if (!state_check(pres))
continue ;
if (!state_read(&ste, &ares[pos]))
if (!state_read(&ste, pres))
continue ;
if (ste.issupervised == STATE_FLAGS_FALSE && FLAGS_ISSET(flag, STATE_FLAGS_ISSUPERVISED)) {
......@@ -95,7 +96,7 @@ void service_graph_build(graph_t *g, resolve_service_t *ares, unsigned int aresl
if (FLAGS_ISSET(flag, STATE_FLAGS_ISSUPERVISED)) {
issupervised(store, ares, areslen, pres->sa.s + pres->dependencies.depends) ;
issupervised(store, hres, pres->sa.s + pres->dependencies.depends) ;
} else {
......@@ -114,7 +115,7 @@ void service_graph_build(graph_t *g, resolve_service_t *ares, unsigned int aresl
if (FLAGS_ISSET(flag, STATE_FLAGS_ISSUPERVISED)) {
issupervised(store, ares, areslen, pres->sa.s + pres->dependencies.requiredby) ;
issupervised(store, hres, pres->sa.s + pres->dependencies.requiredby) ;
} else {
......
......@@ -27,12 +27,13 @@
#include <66/state.h>
#include <66/graph.h>
#include <66/enum.h>
#include <66/hash.h>
/** list all services of the system dependending of the flag passed.
* STATE_FLAGS_TOPARSE -> call sanitize_source
* STATE_FLAGS_TOPROPAGATE -> it build with the dependencies/requiredby services.
* STATE_FLAGS_ISSUPERVISED -> only keep already supervised service*/
void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag)
void service_graph_collect(graph_t *g, char const *slist, size_t slen, struct resolve_hash_s **hres, ssexec_t *info, uint32_t flag)
{
log_flow () ;
......@@ -45,13 +46,11 @@ void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_s
for (; pos < slen ; pos += strlen(slist + pos) + 1) {
char const *name = slist + pos ;
struct resolve_hash_s *hash = hash_search(hres, name) ;
if (service_resolve_array_search(ares, (*areslen), name) < 0) {
if (hash == NULL) {
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
/** need to make a copy of the resolve due of the freed
* of the wres struct at the end of the process */
resolve_service_t cp = RESOLVE_SERVICE_ZERO ;
wres = resolve_set_struct(DATA_SERVICE, &res) ;
/** double pass with resolve_read.
......@@ -90,10 +89,9 @@ void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_s
if (res.earlier) {
if (!service_resolve_copy(&cp, &res))
log_dieu(LOG_EXIT_SYS, "copy resolve file of: ", name, " -- please make a bug report") ;
ares[(*areslen)++] = cp ;
log_trace("add service: ", name, " to the graph selection") ;
if (!hash_add(hres, name, res))
log_dieu(LOG_EXIT_SYS, "append graph selection with: ", name) ;
continue ;
}
resolve_free(wres) ;
......@@ -104,10 +102,9 @@ void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_s
if (ste.issupervised == STATE_FLAGS_TRUE) {
if (!service_resolve_copy(&cp, &res))
log_dieu(LOG_EXIT_SYS, "copy resolve file of: ", name, " -- please make a bug report") ;
ares[(*areslen)++] = cp ;
log_trace("add service: ", name, " to the graph selection") ;
if (!hash_add(hres, name, res))
log_dieu(LOG_EXIT_SYS, "append graph selection with: ", name) ;
} else {
resolve_free(wres) ;
......@@ -116,10 +113,9 @@ void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_s
} else {
if (!service_resolve_copy(&cp, &res))
log_dieu(LOG_EXIT_SYS, "copy resolve file of: ", name, " -- please make a bug report") ;
ares[(*areslen)++] = cp ;
log_trace("add service: ", name, " to the graph selection") ;
if (!hash_add(hres, name, res))
log_dieu(LOG_EXIT_SYS, "append graph selection with: ", name) ;
}
if (FLAGS_ISSET(flag, STATE_FLAGS_TOPROPAGATE)) {
......@@ -132,7 +128,7 @@ void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_s
if (!stack_clean_string(&stk, res.sa.s + res.dependencies.depends, len))
log_dieusys(LOG_EXIT_SYS, "clean string") ;
service_graph_collect(g, stk.s, stk.len, ares, areslen, info, flag) ;
service_graph_collect(g, stk.s, stk.len, hres, info, flag) ;
}
......@@ -144,11 +140,12 @@ void service_graph_collect(graph_t *g, char const *slist, size_t slen, resolve_s
if (!stack_clean_string(&stk, res.sa.s + res.dependencies.requiredby, len))
log_dieusys(LOG_EXIT_SYS, "clean string") ;
service_graph_collect(g, stk.s, stk.len, ares, areslen, info, flag) ;
service_graph_collect(g, stk.s, stk.len, hres, info, flag) ;
}
}
resolve_free(wres) ;
free(wres) ;
}
}
}
......@@ -25,6 +25,7 @@
#include <66/ssexec.h>
#include <66/state.h>
#include <66/enum.h>
#include <66/hash.h>
static void debug_flag(uint32_t flag)
{
......@@ -73,19 +74,19 @@ static void debug_flag(uint32_t flag)
log_trace("requested flags to build the graph: ", req) ;
}
void service_graph_g(char const *slist, size_t slen, graph_t *graph, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag)
void service_graph_g(char const *slist, size_t slen, graph_t *graph, struct resolve_hash_s **hres, ssexec_t *info, uint32_t flag)
{
log_flow() ;
debug_flag(flag) ;
service_graph_collect(graph, slist, slen, ares, areslen, info, flag) ;
service_graph_collect(graph, slist, slen, hres, info, flag) ;
if (!*areslen) {
if (!HASH_COUNT(*hres)) {
/* avoid empty string */
log_warn("no services matching the requirements at tree: ", info->treename.s) ;
return ;
}
service_graph_build(graph, ares, (*areslen), flag) ;
service_graph_build(graph, hres, flag) ;
}
/*
* service_resolve_array_search.c
* service_hash.c
*
* Copyright (c) 2018-2023 Eric Vidal <eric@obarun.org>
*
......@@ -12,23 +12,59 @@
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <66/service.h>
#include <66/hash.h>
int service_resolve_array_search(resolve_service_t *ares, unsigned int areslen, char const *name)
#include <66/resolve.h>
int hash_add(struct resolve_hash_s **hash, char const *name, resolve_service_t res)
{
log_flow() ;
unsigned int pos = 0 ;
struct resolve_hash_s *s ;
s = (struct resolve_hash_s *)malloc(sizeof(*s));
if (s == NULL)
return 0 ;
memset(s, 0, sizeof(*s)) ;
s->visit = 0 ;
auto_strings(s->name, name) ;
s->res = res ;
HASH_ADD_STR(*hash, name, s) ;
return 1 ;
}
struct resolve_hash_s *hash_search(struct resolve_hash_s **hash, char const *name)
{
log_flow() ;
for (; pos < areslen ; pos++) {
struct resolve_hash_s *s ;
HASH_FIND_STR(*hash, name, s) ;
return s ;
char const *n = ares[pos].sa.s + ares[pos].name ;
if (!strcmp(name, n))
return pos ;
}
}
return -1 ;
int hash_count(struct resolve_hash_s **hash)
{
return HASH_COUNT(*hash) ;
}
void hash_free(struct resolve_hash_s **hash)
{
log_flow() ;
struct resolve_hash_s *c, *tmp ;
HASH_ITER(hh, *hash, c, tmp) {
stralloc_free(&c->res.sa) ;
HASH_DEL(*hash, c) ;
free(c) ;
}
}
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