diff --git a/src/include/66/66.h b/src/include/66/66.h index cfe9b8af33df66b12be9fba438af25ae9c153f6e..56c00d734b72a81ff248b7e33cdd15a7d951fa1f 100644 --- a/src/include/66/66.h +++ b/src/include/66/66.h @@ -33,5 +33,6 @@ #include <66/tree.h> #include <66/utils.h> #include <66/write.h> +#include <66/hash.h> #endif diff --git a/src/include/66/graph.h b/src/include/66/graph.h index ada7b76ca16e0b858973622764db7c1518cea067..393256c427673b9e8e2a49514b95a04489aab829 100644 --- a/src/include/66/graph.h +++ b/src/include/66/graph.h @@ -22,8 +22,9 @@ #include <66/service.h> #include <66/tree.h> #include <66/ssexec.h> +#include <66/hash.h> -extern void graph_build_tree(graph_t *g,char const *base, resolve_tree_master_enum_t field) ; +extern void graph_build_tree(graph_t *g, struct resolve_hash_tree_s **htres, char const *base, resolve_tree_master_enum_t field) ; extern void graph_build_service(graph_t *g, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag) ; extern int graph_compute_dependencies(graph_t *g, char const *vertex, char const *edge, uint8_t requiredby) ; extern 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) ; diff --git a/src/include/66/tree.h b/src/include/66/tree.h index 3e291ded04fc498e055324446ab0876ffc0747b3..91772143bc88690ca93737481deb6a7eb75f9088 100644 --- a/src/include/66/tree.h +++ b/src/include/66/tree.h @@ -24,6 +24,7 @@ #include <66/ssexec.h> #include <66/resolve.h> +#include <66/hash.h> #define TREE_GROUPS_BOOT "boot" #define TREE_GROUPS_BOOT_LEN (sizeof TREE_GROUPS_BOOT - 1) @@ -129,6 +130,15 @@ struct tree_seed_s } ; #define TREE_SEED_ZERO { STRALLOC_ZERO, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0 } +struct resolve_hash_tree_s { + char name[SS_MAX_SERVICE_NAME + 1] ; // name as key + uint8_t visit ; + resolve_tree_t tres ; + UT_hash_handle hh ; + +} ; +#define RESOLVE_HASH_TREE_ZERO { 0, 0, RESOLVE_TREE_ZERO, NULL } + /** @Return 1 on success * @Return 0 if not valid * @Return -1 on system error */ @@ -173,19 +183,13 @@ extern int tree_sethome(ssexec_t *info) ; extern int tree_switch_current(char const *base, char const *tree) ; -/** - * - * Resolve API - * - * */ - +/** Resolve API */ /** tree */ extern int tree_resolve_read_cdb(cdb *c, resolve_tree_t *tres) ; extern int tree_resolve_write_cdb(cdbmaker *c, resolve_tree_t *tres) ; extern int tree_resolve_copy(resolve_tree_t *dst, resolve_tree_t *tres) ; extern int tree_resolve_modify_field(resolve_tree_t *tres, uint8_t field, char const *data) ; extern int tree_resolve_get_field_tosa(stralloc *sa, resolve_tree_t *tres, resolve_tree_enum_t field) ; -extern int tree_resolve_array_search(resolve_tree_t *ares, unsigned int areslen, char const *name) ; extern void tree_service_add(char const *treename, char const *service, ssexec_t *info) ; extern void tree_service_remove(char const *base, char const *treename, char const *service) ; /** Master */ @@ -196,11 +200,7 @@ extern int tree_resolve_master_copy(resolve_tree_master_t *dst, resolve_tree_mas extern int tree_resolve_master_modify_field(resolve_tree_master_t *mres, uint8_t field, char const *data) ; extern int tree_resolve_master_get_field_tosa(stralloc *sa, resolve_tree_master_t *mres, resolve_tree_master_enum_t field) ; -/** - * - * Seed API - * - * */ +/** Seed API */ extern int tree_seed_file_isvalid(char const *seedpath, char const *treename) ; extern void tree_seed_free(tree_seed_t *seed) ; extern int tree_seed_get_group_permissions(tree_seed_t *seed) ; @@ -210,5 +210,10 @@ extern int tree_seed_parse_file(tree_seed_t *seed, char const *seedpath) ; extern int tree_seed_resolve_path(stralloc *sa, char const *seed) ; extern int tree_seed_setseed(tree_seed_t *seed, char const *treename) ; +/** HASH API*/ +extern int hash_add_tree(struct resolve_hash_tree_s **hash, char const *name, resolve_tree_t res) ; +extern struct resolve_hash_tree_s *hash_search_tree(struct resolve_hash_tree_s **hash, char const *name) ; +extern int hash_count_tree(struct resolve_hash_tree_s **hash) ; +extern void hash_free_tree(struct resolve_hash_tree_s **hash) ; #endif diff --git a/src/lib66/exec/ssexec_tree_admin.c b/src/lib66/exec/ssexec_tree_admin.c index c12c590a7c232c2810ae8245a9b88a8db347b022..18dcffe281fd25fc2583185b252cb76163efeda0 100644 --- a/src/lib66/exec/ssexec_tree_admin.c +++ b/src/lib66/exec/ssexec_tree_admin.c @@ -598,79 +598,6 @@ void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what) log_info("Created successfully tree: ", info->treename.s) ; } -/** - * WARNING: The order of the trees are not sorted by dependencies order - * - * !action -> disable - * action -> enable */ -void tree_master_enable_disable(char const *base, char const *treename, uint8_t action) -{ - log_flow() ; - - char *str = 0 ; - stralloc sa = STRALLOC_ZERO ; - resolve_tree_master_t mres = RESOLVE_TREE_MASTER_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE_MASTER, &mres) ; - - log_trace(!action ? "disable" : "enable"," tree: ", treename, " from: ", SS_MASTER + 1) ; - - if (resolve_read_g(wres, base, SS_MASTER + 1) <= 0) - log_dieusys(LOG_EXIT_SYS, "read resolve Master file of trees") ; - - if (!mres.nenabled && action) { - if (!resolve_modify_field(wres, E_RESOLVE_TREE_MASTER_ENABLED, treename)) - log_dieusys(LOG_EXIT_SYS, "modify resolve Master file of trees") ; - - mres.nenabled = 1 ; - goto write ; - } - - if (mres.nenabled) { - - if (!sastr_clean_string(&sa, mres.sa.s + mres.enabled)) - log_dieu(LOG_EXIT_SYS, "clean string") ; - - - if (!action) { - - if (!sastr_remove_element(&sa, treename)) - log_dieu(LOG_EXIT_SYS, "remove service: ", treename, " list") ; - - mres.nenabled-- ; - - } else if (action) { - // be paranoid and test the action var - if (!sastr_add_string(&sa, treename)) - log_dieu(LOG_EXIT_SYS, "clean string") ; - - if (!sastr_sortndrop_element(&sa)) - log_dieu(LOG_EXIT_SYS, "sort string") ; - - mres.nenabled++ ; - - } - - if (sa.len) { - - if (!sastr_rebuild_in_oneline(&sa)) - log_dieu(LOG_EXIT_SYS, "rebuild list") ; - str = sa.s ; - - } else str = "" ; - - if (!resolve_modify_field(wres, E_RESOLVE_TREE_MASTER_ENABLED, str)) - log_dieusys(LOG_EXIT_SYS, "modify resolve file of: ", SS_MASTER + 1) ; - - } - - write: - if (!resolve_write_g(wres, base, SS_MASTER + 1)) - log_dieusys(LOG_EXIT_SYS, "write resolve Master file of trees") ; - - resolve_free(wres) ; - stralloc_free(&sa) ; -} - void tree_enable_disable_deps(graph_t *g,char const *base, char const *treename, uint8_t action) { log_flow() ; @@ -715,9 +642,10 @@ void tree_enable_disable(graph_t *g, char const *base, char const *treename, uin resolve_tree_t tres = RESOLVE_TREE_ZERO ; resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ; - uint8_t disen = tree_isenabled(base, treename) ; - if (disen < 0) - log_dieu(LOG_EXIT_SYS, "read resolve file of: ", treename) ; + if (resolve_read_g(wres, base, treename) <= 0) + log_dieusys(LOG_EXIT_SYS, "read resolve file of: ", treename) ; + + uint8_t disen = tres.enabled ; if ((disen && !action) || (!disen && action)){ @@ -728,8 +656,11 @@ void tree_enable_disable(graph_t *g, char const *base, char const *treename, uin return ; } + tres.enabled = action ; + if (!resolve_write_g(wres, base, treename)) + log_dieusys(LOG_EXIT_SYS, "write resolve file of: ", treename) ; + tree_enable_disable_deps(g, base, treename, action) ; - tree_master_enable_disable(base, treename, action) ; log_info(!action ? "Disabled" : "Enabled"," successfully tree: ", treename) ; @@ -1098,6 +1029,7 @@ void tree_clone(char const *clone, ssexec_t *info) !resolve_modify_field(wres, E_RESOLVE_TREE_SUPERVISED, 0) || !resolve_modify_field(wres, E_RESOLVE_TREE_CONTENTS, "") || !resolve_modify_field(wres, E_RESOLVE_TREE_NCONTENTS, 0) || + !resolve_modify_field(wres, E_RESOLVE_TREE_ENABLED, 0) || !resolve_modify_field(wres, E_RESOLVE_TREE_NAME, clone)) log_dieusys(LOG_EXIT_SYS, "modify resolve file of tree: ", clone) ; @@ -1124,6 +1056,7 @@ int ssexec_tree_admin(int argc, char const *const *argv, ssexec_t *info) char oldtree[SS_MAX_TREENAME + 1] ; stralloc sa = STRALLOC_ZERO ; graph_t graph = GRAPH_ZERO ; + struct resolve_hash_tree_s *htres = NULL ; tree_what_t what = what_init() ; @@ -1243,7 +1176,7 @@ int ssexec_tree_admin(int argc, char const *const *argv, ssexec_t *info) if (!r && what.remove) log_dieusys(LOG_EXIT_SYS,"find tree: ", info->treename.s) ; - graph_build_tree(&graph, info->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; + graph_build_tree(&graph, &htres, info->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; if (what.remove) { tree_remove(&graph, info->base.s, info->treename.s, info) ; @@ -1313,6 +1246,7 @@ int ssexec_tree_admin(int argc, char const *const *argv, ssexec_t *info) stralloc_free(&sa) ; graph_free_all(&graph) ; + hash_free_tree(&htres) ; return 0 ; } diff --git a/src/lib66/exec/ssexec_tree_resolve.c b/src/lib66/exec/ssexec_tree_resolve.c index 28951a15c7f27a3af4be93ddb06f33a5ce92defc..0e59b2000f012e4cf74654580340d7e4a76b06e9 100644 --- a/src/lib66/exec/ssexec_tree_resolve.c +++ b/src/lib66/exec/ssexec_tree_resolve.c @@ -33,7 +33,7 @@ #include <66/config.h> #include <66/state.h> -#define MAXOPTS 16 +#define MAXOPTS 17 static wchar_t const field_suffix[] = L" :" ; static char fields[INFO_NKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ; @@ -94,6 +94,7 @@ int ssexec_tree_resolve(int argc, char const *const *argv, ssexec_t *info) char tree_buf[MAXOPTS][INFO_FIELD_MAXLEN] = { "name", + "enabled", "depends" , "requiredby", "allow", @@ -107,9 +108,7 @@ int ssexec_tree_resolve(int argc, char const *const *argv, ssexec_t *info) //"init" , //"supervised", // 13 // Master - "enabled", "current", - "nenabled", } ; if (!strcmp(argv[0], SS_MASTER + 1)) { @@ -140,6 +139,7 @@ int ssexec_tree_resolve(int argc, char const *const *argv, ssexec_t *info) unsigned int m = 0 ; info_display_string(fields[m++], tres.sa.s, tres.name, 0) ; + info_display_int(fields[m++], tres.enabled) ; info_display_string(fields[m++], tres.sa.s, tres.depends, 1) ; info_display_string(fields[m++], tres.sa.s, tres.requiredby, 1) ; info_display_string(fields[m++], tres.sa.s, tres.allow, 1) ; @@ -156,13 +156,11 @@ int ssexec_tree_resolve(int argc, char const *const *argv, ssexec_t *info) } else { info_display_string(fields[0], mres.sa.s, mres.name, 1) ; - info_display_string(fields[3], mres.sa.s, mres.allow, 1) ; - info_display_string(fields[11], mres.sa.s, mres.enabled, 1) ; + info_display_string(fields[4], mres.sa.s, mres.allow, 1) ; info_display_string(fields[12], mres.sa.s, mres.current, 1) ; - info_display_string(fields[5], mres.sa.s, mres.contents, 1) ; - info_display_int(fields[8], mres.nallow) ; - info_display_int(fields[13], mres.nenabled) ; - info_display_int(fields[10], mres.ncontents) ; + info_display_string(fields[6], mres.sa.s, mres.contents, 1) ; + info_display_int(fields[9], mres.nallow) ; + info_display_int(fields[11], mres.ncontents) ; } resolve_free(wres) ; diff --git a/src/lib66/exec/ssexec_tree_signal.c b/src/lib66/exec/ssexec_tree_signal.c index d5407bd450946622a8d979e8b9ccb7831526ed12..d982fe380d464b755f6fdf202424b41c2e1fa214 100644 --- a/src/lib66/exec/ssexec_tree_signal.c +++ b/src/lib66/exec/ssexec_tree_signal.c @@ -61,8 +61,6 @@ static unsigned int napid = 0 ; static unsigned int npid = 0 ; -static resolve_tree_t_ref pares = 0 ; -static unsigned int *pareslen = 0 ; static uint8_t reloadmsg = 0 ; typedef struct pidtree_s pidtree_t, *pidtree_t_ref ; @@ -70,7 +68,7 @@ struct pidtree_s { int pipe[2] ; pid_t pid ; - int aresid ; // id at array ares + resolve_tree_t *tres ; // id at array ares unsigned int vertex ; // id at graph_hash_t struct uint8_t state ; int nedge ; @@ -80,7 +78,17 @@ struct pidtree_s * to notify when a tree is started/stopped */ unsigned int notif[SS_MAX_SERVICE + 1] ; } ; -#define PIDTREE_ZERO { { -1, -1 }, -1, -1, 0, 0, 0, { 0 } } +#define PIDTREE_ZERO { \ + .pipe[0] = -1, \ + .pipe[1] = -1, \ + .tres = NULL, \ + .vertex = -1, \ + .state = 0, \ + .nedge = 0, \ + .edge = { 0 }, \ + .nnotif = 0, \ + .notif = { 0 } \ +} typedef enum fifo_e fifo_t, *fifo_t_ref ; enum fifo_e @@ -186,15 +194,6 @@ static void all_redir_fd(void) umask(022) ; } -void tree_resolve_array_free(resolve_tree_t *ares, unsigned int areslen) -{ - log_flow() ; - - unsigned int pos = 0 ; - for (; pos < areslen ; pos++) - stralloc_free(&ares[pos].sa) ; -} - static inline void kill_all(pidtree_t *apidt) { log_flow() ; @@ -217,21 +216,6 @@ static pidtree_t pidtree_init(unsigned int len) return pids ; } - -static int pidtree_get_id(pidtree_t *apidt, unsigned int id) -{ - log_flow() ; - - unsigned int pos = 0 ; - - for (; pos < napid ; pos++) { - if (apidt[pos].vertex == id) - return (unsigned int) pos ; - } - return -1 ; -} - - static void notify(pidtree_t *apidt, unsigned int pos, char const *sig, unsigned int what) { log_flow() ; @@ -246,16 +230,16 @@ static void notify(pidtree_t *apidt, unsigned int pos, char const *sig, unsigned if (apidt[pos].notif[i] == apidt[idx].vertex && !FLAGS_ISSET(apidt[idx].state, flag)) { - size_t nlen = uint_fmt(fmt, apidt[pos].aresid) ; + size_t nlen = uint_fmt(fmt, pos) ; fmt[nlen] = 0 ; size_t len = nlen + 1 + 2 ; char s[len + 1] ; auto_strings(s, fmt, ":", sig, "@") ; - log_trace("sends notification ", sig, " to: ", pares[apidt[idx].aresid].sa.s + pares[apidt[idx].aresid].name, " from: ", pares[apidt[pos].aresid].sa.s + pares[apidt[pos].aresid].name) ; + log_trace("sends notification ", sig, " to: ", apidt[idx].tres->sa.s + apidt[idx].tres->name, " from: ", apidt[pos].tres->sa.s + apidt[pos].tres->name) ; if (write(apidt[idx].pipe[1], s, strlen(s)) < 0) - log_dieusys(LOG_EXIT_SYS, "send notif to: ", pares[apidt[idx].aresid].sa.s + pares[apidt[idx].aresid].name) ; + log_dieusys(LOG_EXIT_SYS, "send notif to: ", apidt[idx].tres->sa.s + apidt[idx].tres->name) ; } } } @@ -270,37 +254,34 @@ static void announce(unsigned int pos, pidtree_t *apidt, char const *base, unsig log_flow() ; char fmt[UINT_FMT] ; - char const *treename = pares[apidt[pos].aresid].sa.s + pares[apidt[pos].aresid].name ; - - resolve_tree_t tres = RESOLVE_TREE_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ; + char const *treename = apidt[pos].tres->sa.s + apidt[pos].tres->name ; uint8_t flag = what ? FLAGS_DOWN : FLAGS_UP ; if (success) { - notify(apidt, pos, "F", what) ; - fmt[uint_fmt(fmt, exitcode)] = 0 ; log_1_warnu(reloadmsg == 0 ? "start" : reloadmsg > 1 ? "unsupervise" : what == 0 ? "start" : "stop", " tree: ", treename, " -- exited with signal: ", fmt) ; + notify(apidt, pos, "F", what) ; + FLAGS_SET(apidt[pos].state, FLAGS_BLOCK|FLAGS_FATAL) ; } else { + log_info("Successfully ", reloadmsg == 0 ? "started" : reloadmsg > 1 ? "unsupervised" : what == 0 ? "started" : "stopped", " tree: ", treename) ; + notify(apidt, pos, what ? "D" : "U", what) ; FLAGS_CLEAR(apidt[pos].state, FLAGS_BLOCK) ; FLAGS_SET(apidt[pos].state, flag|FLAGS_UNBLOCK) ; - log_info("Successfully ", reloadmsg == 0 ? "started" : reloadmsg > 1 ? "unsupervised" : what == 0 ? "started" : "stopped", " tree: ", treename) ; } - resolve_free(wres) ; } -static void pidtree_init_array(unsigned int *list, unsigned int listlen, pidtree_t *apidt, graph_t *g, resolve_tree_t *ares, unsigned int areslen, ssexec_t *info, uint8_t requiredby, uint8_t what) +static void pidtree_init_array(unsigned int *list, unsigned int listlen, pidtree_t *apidt, graph_t *g, struct resolve_hash_tree_s **htres, ssexec_t *info, uint8_t requiredby, uint8_t what) { log_flow() ; @@ -312,10 +293,11 @@ static void pidtree_init_array(unsigned int *list, unsigned int listlen, pidtree char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[list[pos]].vertex ; - pids.aresid = tree_resolve_array_search(ares, areslen, name) ; + struct resolve_hash_tree_s *hash = hash_search_tree(htres, name) ; + if (hash == NULL) + log_dieu(LOG_EXIT_SYS,"find hash id of: ", name, " -- please make a bug report") ; - if (pids.aresid < 0) - log_dieu(LOG_EXIT_SYS,"find ares id of: ", name, " -- please make a bug report") ; + pids.tres = &hash->tres ; pids.nedge = graph_matrix_get_edge_g_sorted_list(pids.edge, g, name, requiredby, 1) ; @@ -380,17 +362,16 @@ static int handle_signal(pidtree_t *apidt, unsigned int what, graph_t *graph, ss if (!WIFSIGNALED(wstat) && !WEXITSTATUS(wstat)) { announce(pos, apidt, info->base.s, what, 0, 0) ; + npid-- ; } else { ok = WIFSIGNALED(wstat) ? WTERMSIG(wstat) : WEXITSTATUS(wstat) ; announce(pos, apidt, info->base.s, what, 1, ok) ; - + npid-- ; kill_all(apidt) ; break ; } - - npid-- ; } } break ; @@ -399,7 +380,7 @@ static int handle_signal(pidtree_t *apidt, unsigned int what, graph_t *graph, ss case SIGINT : log_1_warn("aborting transaction") ; kill_all(apidt) ; - ok = 110 ; + ok = 111 ; break ; default : log_die(LOG_EXIT_SYS, "unexpected data in selfpipe") ; } @@ -424,6 +405,7 @@ static uint32_t compute_timeout (uint32_t timeout, tain *deadline) return t ; } */ + static int ssexec_callback(stralloc *sa, ssexec_t *info, unsigned int what) { log_flow() ; @@ -578,12 +560,12 @@ static int check_action(pidtree_t *apidt, unsigned int pos, unsigned int receive } -static int async_deps(pidtree_t *apidt, unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph, tain *deadline) +static int async_deps(struct resolve_hash_tree_s **htres, pidtree_t *apidt, unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph, tain *deadline) { log_flow() ; int r ; - unsigned int pos = 0, id = 0, ilog = 0, idx = 0 ; + unsigned int pos = 0, id = 0, idx = 0 ; char buf[(UINT_FMT*2)*SS_MAX_SERVICE + 1] ; tain dead ; @@ -606,7 +588,7 @@ static int async_deps(pidtree_t *apidt, unsigned int i, unsigned int what, ssexe if (!r) { errno = ETIMEDOUT ; - log_dieusys(LOG_EXIT_SYS,"time out", pares[apidt[i].aresid].sa.s + pares[apidt[i].aresid].name) ; + log_dieusys(LOG_EXIT_SYS,"time out", apidt[i].tres->sa.s + apidt[i].tres->name) ; } if (x.revents & IOPAUSE_READ) { @@ -638,7 +620,7 @@ static int async_deps(pidtree_t *apidt, unsigned int i, unsigned int what, ssexe /** * the received string have the format: - * index_of_the_ares_array_of_the_tree_dependency:signal_receive + * apids_array_id:signal_receive * * typically: * - 10:D @@ -657,9 +639,7 @@ static int async_deps(pidtree_t *apidt, unsigned int i, unsigned int what, ssexe if (!uint0_scan(line, &id)) log_dieusys(LOG_EXIT_SYS, "retrieve service number -- please make a bug report") ; - ilog = id ; - - log_trace(pares[apidt[i].aresid].sa.s + pares[apidt[i].aresid].name, " acknowledges: ", pc, " from: ", pares[ilog].sa.s + pares[ilog].name) ; + log_trace(apidt[i].tres->sa.s + apidt[i].tres->name, " acknowledges: ", pc, " from: ", apidt[id].tres->sa.s + apidt[id].tres->name) ; if (!visit[pos]) { @@ -669,7 +649,7 @@ static int async_deps(pidtree_t *apidt, unsigned int i, unsigned int what, ssexe id = check_action(apidt, id, c, what) ; if (id < 0) - log_die(LOG_EXIT_SYS, "tree dependency: ", pares[ilog].sa.s + pares[ilog].name, " of: ", pares[apidt[i].aresid].sa.s + pares[apidt[i].aresid].name," crashed") ; + log_die(LOG_EXIT_SYS, "tree dependency: ", apidt[id].tres->sa.s + apidt[id].tres->name, " of: ", apidt[id].tres->sa.s + apidt[id].tres->name," crashed") ; if (!id) continue ; @@ -685,7 +665,7 @@ static int async_deps(pidtree_t *apidt, unsigned int i, unsigned int what, ssexe return 1 ; } -static int async(pidtree_t *apidt, unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph, tain *deadline) +static int async(struct resolve_hash_tree_s **htres, pidtree_t *apidt, unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph, tain *deadline) { log_flow() ; @@ -705,7 +685,7 @@ static int async(pidtree_t *apidt, unsigned int i, unsigned int what, ssexec_t * FLAGS_SET(apidt[i].state, FLAGS_BLOCK) ; if (apidt[i].nedge) - if (!async_deps(apidt, i, what, info, graph, deadline)) + if (!async_deps(htres, apidt, i, what, info, graph, deadline)) log_warnu_return(LOG_EXIT_ZERO, !what ? "start" : "stop", " dependencies of tree: ", name) ; e = doit(name, info, what, deadline) ; @@ -728,7 +708,7 @@ static int async(pidtree_t *apidt, unsigned int i, unsigned int what, ssexec_t * return e ; } -static int waitit(pidtree_t *apidt, unsigned int what, graph_t *graph, tain *deadline, ssexec_t *info) +static int waitit(struct resolve_hash_tree_s **htres, pidtree_t *apidt, unsigned int what, graph_t *graph, tain *deadline, ssexec_t *info) { log_flow() ; @@ -753,7 +733,6 @@ static int waitit(pidtree_t *apidt, unsigned int what, graph_t *graph, tain *dea !sig_altignore(SIGPIPE)) log_dieusys(LOG_EXIT_SYS, "selfpipe_trap") ; - iopause_fd x = { .fd = spfd, .events = IOPAUSE_READ, .revents = 0 } ; for (; pos < napid ; pos++) { @@ -778,7 +757,7 @@ static int waitit(pidtree_t *apidt, unsigned int what, graph_t *graph, tain *dea close(apidtree[pos].pipe[1]) ; - e = async(apidtree, pos, what, info, graph, deadline) ; + e = async(htres, apidtree, pos, what, info, graph, deadline) ; goto end ; } @@ -810,31 +789,56 @@ static int waitit(pidtree_t *apidt, unsigned int what, graph_t *graph, tain *dea } } - selfpipe_finish() ; - end: - for (pos = 0 ; pos < napid ; pos++) { - close(apidtree[pos].pipe[1]) ; - close(apidtree[pos].pipe[0]) ; - } + for (pos = 0 ; pos < napid ; pos++) { + close(apidtree[pos].pipe[1]) ; + close(apidtree[pos].pipe[0]) ; + } + + + end: return e ; } +static void compute_visit_tree(char const *treename, unsigned int *visit, unsigned int *list, graph_t *graph, unsigned int *ntree, uint8_t requiredby) +{ + log_flow() ; + + unsigned int l[graph->mlen], c = 0, pos = 0, idx = 0 ; + + idx = graph_hash_vertex_get_id(graph, treename) ; + + if (!visit[idx]) { + /** avoid double entry */ + list[(*ntree)++] = idx ; + visit[idx] = 1 ; + + } + + /** find dependencies of the tree from the graph, do it recursively */ + c = graph_matrix_get_edge_g_sorted_list(l, graph, treename, requiredby, 1) ; + + /** append to the list to deal with */ + for (; pos < c ; pos++) { + if (!visit[l[pos]]) { + list[(*ntree)++] = l[pos] ; + visit[l[pos]] = 1 ; + } + } +} + int ssexec_tree_signal(int argc, char const *const *argv, ssexec_t *info) { log_flow() ; int r, shut = 0, fd ; tain deadline ; - uint8_t what = 0, requiredby = 0, found = 0 ; + uint8_t what = 0, requiredby = 0 ; stralloc sa = STRALLOC_ZERO ; size_t pos = 0 ; - - unsigned int areslen = 0, list[SS_MAX_SERVICE + 1], visit[SS_MAX_SERVICE + 1] ; - resolve_tree_t ares[SS_MAX_SERVICE + 1] ; - resolve_wrapper_t_ref wres = 0 ; - + struct resolve_hash_tree_s *htres = NULL ; + unsigned int list[SS_MAX_SERVICE + 1], visit[SS_MAX_SERVICE + 1] ; graph_t graph = GRAPH_ZERO ; memset(list, 0, (SS_MAX_SERVICE + 1) * sizeof(unsigned int)) ; @@ -881,7 +885,7 @@ int ssexec_tree_signal(int argc, char const *const *argv, ssexec_t *info) if ((svc_scandir_ok(info->scandir.s)) <= 0) log_die(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ; - graph_build_tree(&graph, info->base.s, !info->treename.len ? E_RESOLVE_TREE_MASTER_ENABLED : E_RESOLVE_TREE_MASTER_CONTENTS) ; + graph_build_tree(&graph, &htres, info->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; if (!graph.mlen) log_die(LOG_EXIT_USER, "trees selection is not created -- creates at least one tree") ; @@ -889,73 +893,39 @@ int ssexec_tree_signal(int argc, char const *const *argv, ssexec_t *info) if (!graph_matrix_sort_tosa(&sa, &graph)) log_dieu(LOG_EXIT_SYS, "get list of trees for graph -- please make a bug report") ; - FOREACH_SASTR(&sa, pos) { - - char *treename = sa.s + pos ; - - /** only one tree */ - if (info->treename.len) { - - if (!strcmp(info->treename.s, treename)) - found = 1 ; - else continue ; - } - - if (tree_resolve_array_search(ares, areslen, treename) < 0) { - - resolve_tree_t tres = RESOLVE_TREE_ZERO ; - /** need to make a copy of the resolve due of the freed - * of the wres struct at the end of the process */ - resolve_tree_t cp = RESOLVE_TREE_ZERO ; - wres = resolve_set_struct(DATA_TREE, &tres) ; + /** only one tree */ - if (resolve_read_g(wres, info->base.s, treename) <= 0) - log_dieu(LOG_EXIT_SYS, "read resolve file of: ", treename, " -- please make a bug report") ; + if (info->treename.len) { - tree_resolve_copy(&cp, &tres) ; + struct resolve_hash_tree_s *hash = hash_search_tree(&htres, info->treename.s) ; + if (hash == NULL) + log_dieu(LOG_EXIT_SYS,"find hash id of: ", info->treename.s, " -- please make a bug report") ; - ares[areslen++] = cp ; + compute_visit_tree(info->treename.s, visit, list, &graph, &napid, requiredby) ; - resolve_free(wres) ; - } - - unsigned int l[graph.mlen], c = 0, pos = 0, idx = 0 ; - - idx = graph_hash_vertex_get_id(&graph, treename) ; + } else { - if (!visit[idx]) { - /** avoid double entry */ - list[napid++] = idx ; - visit[idx] = 1 ; + FOREACH_SASTR(&sa, pos) { - } + char *treename = sa.s + pos ; + struct resolve_hash_tree_s *hash = hash_search_tree(&htres, treename) ; - /** find dependencies of the tree from the graph, do it recursively */ - c = graph_matrix_get_edge_g_sorted_list(l, &graph, treename, requiredby, 1) ; + if (hash == NULL) + log_dieu(LOG_EXIT_SYS,"find hash id of: ", treename, " -- please make a bug report") ; - /** append to the list to deal with */ - for (; pos < c ; pos++) { - if (!visit[l[pos]]) { - list[napid++] = l[pos] ; - visit[l[pos]] = 1 ; - } + if (hash->tres.enabled) + compute_visit_tree(treename, visit, list, &graph, &napid, requiredby) ; } - - if (found) - break ; } pidtree_t apidt[graph.mlen] ; - pares = ares ; - pareslen = &areslen ; - if (!napid) { r = 0 ; goto end ; } - pidtree_init_array(list, napid, apidt, &graph, ares, areslen, info, requiredby, what) ; + pidtree_init_array(list, napid, apidt, &graph, &htres, info, requiredby, what) ; if (shut) { @@ -985,7 +955,7 @@ int ssexec_tree_signal(int argc, char const *const *argv, ssexec_t *info) } } - r = waitit(apidt, what, &graph, &deadline, info) ; + r = waitit(&htres, apidt, what, &graph, &deadline, info) ; end: @@ -1003,7 +973,7 @@ int ssexec_tree_signal(int argc, char const *const *argv, ssexec_t *info) graph_free_all(&graph) ; stralloc_free(&sa) ; - tree_resolve_array_free(ares, areslen) ; + hash_free_tree(&htres) ; return r ; } diff --git a/src/lib66/exec/ssexec_tree_status.c b/src/lib66/exec/ssexec_tree_status.c index 8e646dd8036fcc2260fe511d61f601de6023cfc9..7689c9ccee6192cfd87f377286d92814eddd718c 100644 --- a/src/lib66/exec/ssexec_tree_status.c +++ b/src/lib66/exec/ssexec_tree_status.c @@ -42,6 +42,7 @@ #include <66/graph.h> #include <66/ssexec.h> #include <66/state.h> +#include <66/hash.h> static unsigned int REVERSE = 0 ; static unsigned int NOFIELD = 1 ; @@ -231,11 +232,12 @@ static void info_display_depends(char const *field, char const *treename) size_t padding = 1 ; graph_t graph = GRAPH_ZERO ; stralloc sa = STRALLOC_ZERO ; + struct resolve_hash_tree_s *htres = NULL ; if (NOFIELD) padding = info_display_field_name(field) ; else { field = 0 ; padding = 0 ; } - graph_build_tree(&graph, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; + graph_build_tree(&graph, &htres, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; r = graph_matrix_get_edge_g_sorted_sa(&sa, &graph, treename, 0, 0) ; if (r < 0) @@ -283,6 +285,7 @@ static void info_display_depends(char const *field, char const *treename) freed: graph_free_all(&graph) ; stralloc_free(&sa) ; + hash_free_tree(&htres) ; } static void info_display_requiredby(char const *field, char const *treename) @@ -291,11 +294,12 @@ static void info_display_requiredby(char const *field, char const *treename) size_t padding = 1 ; graph_t graph = GRAPH_ZERO ; stralloc sa = STRALLOC_ZERO ; + struct resolve_hash_tree_s *htres = NULL ; if (NOFIELD) padding = info_display_field_name(field) ; else { field = 0 ; padding = 0 ; } - graph_build_tree(&graph, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; + graph_build_tree(&graph, &htres, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; r = graph_matrix_get_edge_g_sorted_sa(&sa, &graph, treename, 1, 0) ; if (r < 0) @@ -345,6 +349,7 @@ static void info_display_requiredby(char const *field, char const *treename) freed: graph_free_all(&graph) ; stralloc_free(&sa) ; + hash_free_tree(&htres) ; } static void info_display_contents(char const *field, char const *treename) @@ -354,10 +359,7 @@ static void info_display_contents(char const *field, char const *treename) graph_t graph = GRAPH_ZERO ; stralloc sa = STRALLOC_ZERO ; - unsigned int areslen = 0 ; - resolve_service_t ares[SS_MAX_SERVICE + 1] ; - - memset(ares, 0, (SS_MAX_SERVICE + 1) * sizeof(resolve_service_t)) ; + struct resolve_hash_s *hres = NULL ; if (NOFIELD) padding = info_display_field_name(field) ; else { field = 0 ; padding = 0 ; } @@ -368,9 +370,9 @@ static void info_display_contents(char const *field, char const *treename) if (!sa.len) goto empty ; - service_graph_g(sa.s, sa.len, &graph, ares, &areslen, pinfo, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ; + service_graph_g_hash(sa.s, sa.len, &graph, &hres, pinfo, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ; - if (!areslen) + if (!HASH_COUNT(hres)) goto empty ; if (GRAPH) { @@ -414,6 +416,7 @@ static void info_display_contents(char const *field, char const *treename) freed: graph_free_all(&graph) ; + hash_free(&hres) ; stralloc_free(&sa) ; } @@ -464,6 +467,7 @@ int ssexec_tree_status(int argc, char const *const *argv, ssexec_t *info) size_t pos = 0 ; int what[MAXOPTS] = { 0 } ; stralloc sa = STRALLOC_ZERO ; + struct resolve_hash_tree_s *htres = NULL ; pinfo = info ; @@ -548,7 +552,7 @@ int ssexec_tree_status(int argc, char const *const *argv, ssexec_t *info) graph_t graph = GRAPH_ZERO ; - graph_build_tree(&graph, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; + graph_build_tree(&graph, &htres, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ; if (!graph_matrix_sort_tosa(&sa, &graph)) log_dieu(LOG_EXIT_SYS, "get the sorted list of trees") ; @@ -579,6 +583,7 @@ int ssexec_tree_status(int argc, char const *const *argv, ssexec_t *info) freed: stralloc_free(&sa) ; + hash_free_tree(&htres) ; return 0 ; } diff --git a/src/lib66/graph/graph_build_tree.c b/src/lib66/graph/graph_build_tree.c index 2352e5ac978ac03b27e6c0067eb12f414873f9cb..b1b5fd26cbc828bcaed7cfeda220efd693ced868 100644 --- a/src/lib66/graph/graph_build_tree.c +++ b/src/lib66/graph/graph_build_tree.c @@ -27,15 +27,12 @@ #include <66/tree.h> #include <66/graph.h> -void graph_build_tree(graph_t *g, char const *base, resolve_tree_master_enum_t field) +void graph_build_tree(graph_t *g, struct resolve_hash_tree_s **htres, char const *base, resolve_tree_master_enum_t field) { log_flow() ; size_t pos = 0 ; - stralloc sa = STRALLOC_ZERO ; - resolve_tree_t tres = RESOLVE_TREE_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ; if (!resolve_get_field_tosa_g(&sa, base, SS_MASTER + 1, DATA_TREE_MASTER, field)) log_dieu(LOG_EXIT_SYS, "get resolve Master file of trees") ; @@ -43,20 +40,33 @@ void graph_build_tree(graph_t *g, char const *base, resolve_tree_master_enum_t f FOREACH_SASTR(&sa, pos) { char *name = sa.s + pos ; + struct resolve_hash_tree_s *hash = hash_search_tree(htres, name) ; + + if (hash == NULL) { + + resolve_tree_t tres = RESOLVE_TREE_ZERO ; + resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ; + + if (resolve_read_g(wres, base, name) <= 0) + log_dieu(LOG_EXIT_SYS, "read resolve file of: ", name) ; + + if (!graph_vertex_add(g, name)) + log_dieu(LOG_EXIT_SYS, "add vertex of: ", name) ; - if (resolve_read_g(wres, base, name) <= 0) - log_dieu(LOG_EXIT_SYS, "read resolve file of: ", name) ; + if (tres.ndepends) + if (!graph_compute_dependencies(g, name, tres.sa.s + tres.depends, 0)) + log_dieu(LOG_EXIT_SYS, "compute dependencies of: ", name) ; - if (!graph_vertex_add(g, name)) - log_dieu(LOG_EXIT_SYS, "add vertex of: ", name) ; + if (tres.nrequiredby) + if (!graph_compute_dependencies(g, name, tres.sa.s + tres.requiredby, 1)) + log_dieu(LOG_EXIT_SYS, "compute requiredby of: ", name) ; - if (tres.ndepends) - if (!graph_compute_dependencies(g, name, tres.sa.s + tres.depends, 0)) - log_dieu(LOG_EXIT_SYS, "compute dependencies of: ", name) ; + log_trace("add tree: ", name, " to the graph selection") ; + if (!hash_add_tree(htres, name, tres)) + log_dieu(LOG_EXIT_SYS, "append graph selection with: ", name) ; - if (tres.nrequiredby) - if (!graph_compute_dependencies(g, name, tres.sa.s + tres.requiredby, 1)) - log_dieu(LOG_EXIT_SYS, "compute requiredby of: ", name) ; + free(wres) ; + } } if (!graph_matrix_build(g)) diff --git a/src/lib66/tree/deps-lib/deps b/src/lib66/tree/deps-lib/deps index 14b667336b552e905eac4fc1858254695aa0ce9f..773caac76e8d97c156fa19ee2416b985ff09a2db 100644 --- a/src/lib66/tree/deps-lib/deps +++ b/src/lib66/tree/deps-lib/deps @@ -1,12 +1,12 @@ tree_find_current.o tree_get_permissions.o +tree_hash.o tree_iscurrent.o tree_isenabled.o tree_isinitialized.o tree_issupervised.o tree_isvalid.o tree_ongroups.o -tree_resolve_array_search.o tree_resolve_copy.o tree_resolve_get_field_tosa.o tree_resolve_master_copy.o diff --git a/src/lib66/tree/tree_hash.c b/src/lib66/tree/tree_hash.c new file mode 100644 index 0000000000000000000000000000000000000000..63451e6faa42602e2c8f852635386439fba351d1 --- /dev/null +++ b/src/lib66/tree/tree_hash.c @@ -0,0 +1,70 @@ +/* + * tree_hash.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 <stddef.h> +#include <stdlib.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +#include <66/tree.h> +#include <66/hash.h> + +#include <66/resolve.h> + +int hash_add_tree(struct resolve_hash_tree_s **hash, char const *name, resolve_tree_t res) +{ + log_flow() ; + + struct resolve_hash_tree_s *s ; + s = (struct resolve_hash_tree_s *)malloc(sizeof(*s)); + if (s == NULL) + return 0 ; + + memset(s, 0, sizeof(*s)) ; + s->visit = 0 ; + auto_strings(s->name, name) ; + s->tres = res ; + HASH_ADD_STR(*hash, name, s) ; + + return 1 ; +} + +struct resolve_hash_tree_s *hash_search_tree(struct resolve_hash_tree_s **hash, char const *name) +{ + log_flow() ; + + struct resolve_hash_tree_s *s ; + HASH_FIND_STR(*hash, name, s) ; + return s ; + +} + +int hash_count_tree(struct resolve_hash_tree_s **hash) +{ + return HASH_COUNT(*hash) ; +} + +void hash_free_tree(struct resolve_hash_tree_s **hash) +{ + log_flow() ; + + struct resolve_hash_tree_s *c, *tmp ; + + HASH_ITER(hh, *hash, c, tmp) { + stralloc_free(&c->tres.sa) ; + HASH_DEL(*hash, c) ; + free(c) ; + } +} diff --git a/src/lib66/tree/tree_resolve_array_search.c b/src/lib66/tree/tree_resolve_array_search.c deleted file mode 100644 index 67177e780dc7c6a7e0732fd9015f7b01a15180af..0000000000000000000000000000000000000000 --- a/src/lib66/tree/tree_resolve_array_search.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * tree_resolve_array_search.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/log.h> -#include <66/tree.h> - -int tree_resolve_array_search(resolve_tree_t *ares, unsigned int areslen, char const *name) -{ - log_flow() ; - - unsigned int pos = 0 ; - - for (; pos < areslen ; pos++) { - - char const *n = ares[pos].sa.s + ares[pos].name ; - if (!strcmp(name, n)) - return pos ; - } - - return -1 ; -}