From 7762b10cbbebbb196a3b48e8975a9392c2ab31f0 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 11 Mar 2021 11:18:57 +0100 Subject: [PATCH] * Changed signal handling * Moved clixon-proc sigchild handling from handler to clixon_events --- CHANGELOG.md | 2 + apps/backend/backend_main.c | 9 +- apps/netconf/netconf_main.c | 2 +- apps/restconf/restconf_lib.c | 1 + apps/restconf/restconf_main_evhtp.c | 16 -- apps/restconf/restconf_main_fcgi.c | 5 +- apps/restconf/restconf_stream_fcgi.c | 2 +- lib/clixon/clixon_event.h | 6 +- lib/clixon/clixon_proc.h | 1 + lib/src/clixon_event.c | 40 ++++- lib/src/clixon_proc.c | 260 +++++++++++++++++++-------- lib/src/clixon_proto.c | 2 +- lib/src/clixon_stream.c | 2 +- test/test_restconf_rpc.sh | 42 +++-- util/clixon_util_grpc.c | 2 +- util/clixon_util_ssl.c | 2 +- 16 files changed, 268 insertions(+), 126 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b11f8c1f..2bbbac90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,8 @@ Developers may need to change their code ### Minor features +* Changed signal handling + * Moved clixon-proc sigchild handling from handler to clixon_events * The base capability has been changed to "urn:ietf:params:netconf:base:1.1" following RFC6241. * Made a separate Clixon datastore XML/JSON top-level symbol * Replaces the hardcoded "config" keyword. diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 571f71f2..83d205f4 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -166,13 +166,8 @@ backend_sig_term(int arg) static void backend_sig_child(int arg) { - int status; - int pid; - clicon_debug(1, "%s", __FUNCTION__); - if ((pid = waitpid(-1, &status, 0)) != -1 && WIFEXITED(status)){ - } - clicon_sig_ignore_set(1); + clicon_sig_child_set(1); } /*! Create backend server socket and register callback @@ -1038,7 +1033,7 @@ main(int argc, goto done; if (stream_timer_setup(0, h) < 0) goto done; - if (clixon_event_loop() < 0) + if (clixon_event_loop(h) < 0) goto done; ok: retval = 0; diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index da79f895..589b0cb3 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -873,7 +873,7 @@ main(int argc, if (clixon_event_reg_timeout(t, timeout_fn, NULL, "timeout") < 0) goto done; } - if (clixon_event_loop() < 0) + if (clixon_event_loop(h) < 0) goto done; retval = 0; done: diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c index b778f479..feca2264 100644 --- a/apps/restconf/restconf_lib.c +++ b/apps/restconf/restconf_lib.c @@ -256,6 +256,7 @@ restconf_terminate(clicon_handle h) xpath_optimize_exit(); restconf_handle_exit(h); clicon_log_exit(); + clicon_debug(1, "%s done", __FUNCTION__); return 0; } diff --git a/apps/restconf/restconf_main_evhtp.c b/apps/restconf/restconf_main_evhtp.c index d637dee7..a9e5db6c 100644 --- a/apps/restconf/restconf_main_evhtp.c +++ b/apps/restconf/restconf_main_evhtp.c @@ -160,17 +160,6 @@ restconf_sig_term(int arg) exit(-1); } -static void -restconf_sig_child(int arg) -{ - int status; - int pid; - - if ((pid = waitpid(-1, &status, 0)) != -1 && WIFEXITED(status)){ - } - clicon_sig_ignore_set(1); -} - static char* evhtp_method2str(enum htp_method m) { @@ -1286,11 +1275,6 @@ main(int argc, clicon_err(OE_DAEMON, errno, "Setting signal"); goto done; } - if (set_signal(SIGCHLD, restconf_sig_child, NULL) < 0){ - clicon_err(OE_DAEMON, errno, "Setting signal"); - goto done; - } - /* Find and read configfile */ if (clicon_options_main(h) < 0) goto done; diff --git a/apps/restconf/restconf_main_fcgi.c b/apps/restconf/restconf_main_fcgi.c index 630ef9ad..51b8f720 100644 --- a/apps/restconf/restconf_main_fcgi.c +++ b/apps/restconf/restconf_main_fcgi.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -146,9 +145,13 @@ restconf_sig_term(int arg) restconf_terminate(_CLICON_HANDLE); } clicon_exit_set(); /* checked in clixon_event_loop() */ + clicon_debug(1, "%s done", __FUNCTION__); exit(-1); } +/*! Reap stream child + * XXX The -1 should be changed to proper pid, see eg clixon_process_waitpid + */ static void restconf_sig_child(int arg) { diff --git a/apps/restconf/restconf_stream_fcgi.c b/apps/restconf/restconf_stream_fcgi.c index 2df4613f..96461f22 100644 --- a/apps/restconf/restconf_stream_fcgi.c +++ b/apps/restconf/restconf_stream_fcgi.c @@ -463,7 +463,7 @@ api_stream(clicon_handle h, /* Poll upstream errors */ stream_timeout(0, req); /* Start loop */ - clixon_event_loop(); + clixon_event_loop(h); close(s); clixon_event_unreg_fd(s, restconf_stream_cb); clixon_event_unreg_fd(rfcgi->listen_sock, diff --git a/lib/clixon/clixon_event.h b/lib/clixon/clixon_event.h index 4a741126..f4b3d7f7 100644 --- a/lib/clixon/clixon_event.h +++ b/lib/clixon/clixon_event.h @@ -49,6 +49,10 @@ int clicon_exit_reset(void); int clicon_exit_get(void); +int clicon_sig_child_set(int val); + +int clicon_sig_child_get(void); + int clicon_sig_ignore_set(int val); int clicon_sig_ignore_get(void); @@ -64,7 +68,7 @@ int clixon_event_unreg_timeout(int (*fn)(int, void*), void *arg); int clixon_event_poll(int fd); -int clixon_event_loop(void); +int clixon_event_loop(clicon_handle h); int clixon_event_exit(void); diff --git a/lib/clixon/clixon_proc.h b/lib/clixon/clixon_proc.h index 5eb7edd4..b2690442 100644 --- a/lib/clixon/clixon_proc.h +++ b/lib/clixon/clixon_proc.h @@ -67,5 +67,6 @@ int clixon_process_delete_all(clicon_handle h); int clixon_process_operation(clicon_handle h, const char *name, proc_operation op, const int wrapit, uint32_t *pid); int clixon_process_start_all(clicon_handle h); int clixon_process_sched_register(clicon_handle h); +int clixon_process_waitpid(clicon_handle h); #endif /* _CLIXON_PROC_H_ */ diff --git a/lib/src/clixon_event.c b/lib/src/clixon_event.c index c1f01741..1a0a2622 100644 --- a/lib/src/clixon_event.c +++ b/lib/src/clixon_event.c @@ -54,8 +54,11 @@ #include "clixon_queue.h" #include "clixon_log.h" +#include "clixon_hash.h" +#include "clixon_handle.h" #include "clixon_err.h" #include "clixon_sig.h" +#include "clixon_proc.h" #include "clixon_event.h" /* @@ -89,6 +92,9 @@ static int _ee_unreg = 0; /* If set (eg by signal handler) exit select loop on next run and return 0 */ static int _clicon_exit = 0; +/* If set (eg by signal handler) call waitpid on waiting processes, ignore EINTR, continue select loop */ +static int _clicon_sig_child = 0; + /* If set (eg by signal handler) ignore EINTR and continue select loop */ static int _clicon_sig_ignore = 0; @@ -121,6 +127,19 @@ clicon_exit_get(void) return _clicon_exit; } +int +clicon_sig_child_set(int val) +{ + _clicon_sig_child = val; + return 0; +} + +int +clicon_sig_child_get(void) +{ + return _clicon_sig_child; +} + int clicon_sig_ignore_set(int val) { @@ -308,7 +327,7 @@ clixon_event_poll(int fd) * @retval -1 Error: eg select, callback, timer, */ int -clixon_event_loop(void) +clixon_event_loop(clicon_handle h) { struct event_data *e; struct event_data *e_next; @@ -321,6 +340,12 @@ clixon_event_loop(void) while (!clicon_exit_get()){ FD_ZERO(&fdset); + if (clicon_sig_child_get()){ + /* Go through processes and wait for child processes */ + if (clixon_process_waitpid(h) < 0) + goto err; + clicon_sig_child_set(0); + } for (e=ee; e; e=e->e_next) if (e->e_type == EVENT_FD) FD_SET(e->e_fd, &fdset); @@ -333,7 +358,7 @@ clixon_event_loop(void) n = select(FD_SETSIZE, &fdset, NULL, NULL, &t); } else - n = select(FD_SETSIZE, &fdset, NULL, NULL, NULL); + n = select(FD_SETSIZE, &fdset, NULL, NULL, NULL); if (clicon_exit_get()) break; if (n == -1) { @@ -342,7 +367,9 @@ clixon_event_loop(void) * (1) Signals that exit gracefully, the function returns 0 * Must be registered such as by set_signal() of SIGTERM,SIGINT, etc with a handler that calls * clicon_exit_set(). - * (2) Signals that are ignored, and the select is rerun, eg SIGCHLD if handler calls clicon_sig_ignore() + * (2) SIGCHILD Childs that exit(), go through clixon_proc list and cal waitpid + * New select loop is called + * (2) Signals are ignored, and the select is rerun, ie handler calls clicon_sig_ignore_get * New select loop is called * (3) Other signals result in an error and return -1. */ @@ -351,6 +378,13 @@ clixon_event_loop(void) clicon_err(OE_EVENTS, errno, "select"); retval = 0; } + else if (clicon_sig_child_get()){ + /* Go through processes and wait for child processes */ + if (clixon_process_waitpid(h) < 0) + goto err; + clicon_sig_child_set(0); + continue; + } else if (clicon_sig_ignore_get()){ clicon_sig_ignore_set(0); continue; diff --git a/lib/src/clixon_proc.c b/lib/src/clixon_proc.c index 3cfe4807..96273f41 100644 --- a/lib/src/clixon_proc.c +++ b/lib/src/clixon_proc.c @@ -69,9 +69,9 @@ #include "clixon_err.h" #include "clixon_log.h" #include "clixon_queue.h" -#include "clixon_event.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_event.h" #include "clixon_sig.h" #include "clixon_string.h" #include "clixon_queue.h" @@ -83,13 +83,17 @@ /* Process entry list */ struct process_entry_t { - qelem_t pe_qelem; /* List header */ - char *pe_name; /* Name of process used for internal use */ - char *pe_netns; /* Network namespace */ - char **pe_argv; /* argv with command as element 0 and NULL-terminated */ - pid_t pe_pid; /* Running process id (state) or 0 if dead */ - proc_operation pe_op; /* Operation pending? */ - proc_cb_t *pe_callback; /* Wrapper function, may be called from process_operation */ + qelem_t pe_qelem; /* List header */ + char *pe_name; /* Name of process used for internal use. Unique with exiting=0 */ + char *pe_netns; /* Network namespace */ + char **pe_argv; /* argv with command as element 0 and NULL-terminated */ + int pe_argc; /* Length of argc */ + pid_t pe_pid; /* Running process id (state) or 0 if dead (pid is set if exiting=1) */ + int pe_exiting; /* If set process is in the process of dying needs reaping */ + int pe_clone; /* Duplicate when restarting, delete when reaped */ + pid_t pe_status; /* Status on exit as defined in waitpid */ + proc_operation pe_op; /* Operation pending? */ + proc_cb_t *pe_callback; /* Wrapper function, may be called from process_operation */ }; static void @@ -209,7 +213,7 @@ clixon_proc_background(char **argv, sigset_t oset; struct rlimit rlim = {0, }; - clicon_debug(1, "%s netns:%s", __FUNCTION__, netns); + clicon_debug(1, "%s", __FUNCTION__); if (argv == NULL){ clicon_err(OE_UNIX, EINVAL, "argv is NULL"); goto quit; @@ -303,6 +307,58 @@ clixon_process_op_str2int(char *opstr) return clicon_str2int(proc_operation_map, opstr); } +/*! Make a copy of process-entry struct */ +static int +clixon_process_register_dup(process_entry_t *pe0, + process_entry_t **pnew) +{ + int retval = -1; + process_entry_t *pe1 = NULL; + int i; + + if (pe0 == NULL){ + clicon_err(OE_DB, EINVAL, "pe0 is NULL"); + goto done; + } + if (pnew == NULL){ + clicon_err(OE_DB, EINVAL, "pnew is NULL"); + goto done; + } + if ((pe1 = malloc(sizeof(process_entry_t))) == NULL) { + clicon_err(OE_DB, errno, "malloc"); + goto done; + } + memset(pe1, 0, sizeof(*pe1)); + memcpy(pe1, pe0, sizeof(process_entry_t)); /* Note lots of malloced memory that needs to be handled after this copy*/ + pe1->pe_exiting = 0; + pe1->pe_clone = 0; + if ((pe1->pe_name = strdup(pe0->pe_name)) == NULL){ + clicon_err(OE_DB, errno, "strdup name"); + goto done; + } + if (pe0->pe_netns && (pe1->pe_netns = strdup(pe0->pe_netns)) == NULL){ + clicon_err(OE_DB, errno, "strdup netns"); + goto done; + } + if ((pe1->pe_argv = calloc(pe0->pe_argc, sizeof(char *))) == NULL){ + clicon_err(OE_UNIX, errno, "calloc"); + goto done; + } + for (i=0; ipe_argc; i++){ + if (pe0->pe_argv[i] != NULL && + (pe1->pe_argv[i] = strdup(pe0->pe_argv[i])) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + } + ADDQ(pe1, _proc_entry_list); + *pnew = pe1; + retval = 0; + done: + /* dealloc pe1 on error */ + return retval; +} + /*! Register an internal process * * @param[in] h Clixon handle @@ -348,6 +404,7 @@ clixon_process_register(clicon_handle h, clicon_err(OE_DB, errno, "strdup netns"); goto done; } + pe->pe_argc = argc; if ((pe->pe_argv = calloc(argc, sizeof(char *))) == NULL){ clicon_err(OE_UNIX, errno, "calloc"); goto done; @@ -356,6 +413,7 @@ clixon_process_register(clicon_handle h, if (argv[i] != NULL && (pe->pe_argv[i] = strdup(argv[i])) == NULL){ clicon_err(OE_UNIX, errno, "strdup"); + goto done; } } pe->pe_callback = callback; @@ -365,32 +423,42 @@ clixon_process_register(clicon_handle h, return retval; } +static int +clixon_process_delete_only(process_entry_t *pe) +{ + char **pa; + + if (pe->pe_name) + free(pe->pe_name); + if (pe->pe_netns) + free(pe->pe_netns); + if (pe->pe_argv){ + for (pa = pe->pe_argv; *pa != NULL; pa++){ + if (*pa) + free(*pa); + } + free(pe->pe_argv); + } + free(pe); + return 0; +} + /*! Delete all Upgrade callbacks */ int clixon_process_delete_all(clicon_handle h) { process_entry_t *pe; - char **pa; while((pe = _proc_entry_list) != NULL) { DELQ(pe, _proc_entry_list, process_entry_t *); - if (pe->pe_name) - free(pe->pe_name); - if (pe->pe_netns) - free(pe->pe_netns); - if (pe->pe_argv){ - for (pa = pe->pe_argv; *pa != NULL; pa++){ - if (*pa) - free(*pa); - } - free(pe->pe_argv); - } - free(pe); + clixon_process_delete_only(pe); } return 0; } +/*! + */ static int proc_op_run(pid_t pid0, int *runp) @@ -401,7 +469,7 @@ proc_op_run(pid_t pid0, run = 0; if ((pid = pid0) != 0){ /* if 0 stopped */ - /* Check if lives */ + /* Check if alive */ run = 1; if ((kill(pid, 0)) < 0){ if (errno == ESRCH){ @@ -420,49 +488,6 @@ proc_op_run(pid_t pid0, return retval; } -/*! Perform process operation - * - * @param[in] op One of: start, stop, restart, status - * @param[in] netns Network namespace - * @param[in] argv NULL-terminated Argument vector - * @param[out] pidp Process-id - */ -static int -clixon_process_operation_one(const proc_operation op, - const char *netns, - char **argv, - const char *name, - pid_t *pidp) -{ - int retval = -1; - int run = 0; - - /* Check if running */ - if (proc_op_run(*pidp, &run) < 0) - goto done; - if (op == PROC_OP_STOP || op == PROC_OP_RESTART){ - if (run){ - clicon_log(LOG_NOTICE, "Killing old daemon %s with pid: %d", name, *pidp); - kill(*pidp, SIGTERM); - } - *pidp = 0; /* mark as dead */ - run = 0; - } - if (op == PROC_OP_START || op == PROC_OP_RESTART){ - if (run == 1){ - ; /* Already runs */ - } - else{ - if (clixon_proc_background(argv, netns, pidp) < 0) - goto done; - clicon_debug(1, "%s started pid:%d", __FUNCTION__, *pidp); - } - } - retval = 0; - done: - return retval; -} - /*! Find process operation entry given name and op and perform operation if found * * @param[in] h clicon handle @@ -495,8 +520,11 @@ clixon_process_operation(clicon_handle h, if (wrapit && pe->pe_callback != NULL) if (pe->pe_callback(h, pe, &op) < 0) goto done; + clicon_debug(1, "%s name: %s pid:%d op: %s", __FUNCTION__, + name, pe->pe_pid, clicon_int2str(proc_operation_map, op)); if (op == PROC_OP_START || op == PROC_OP_STOP || op == PROC_OP_RESTART){ pe->pe_op = op; + clicon_debug(1, "%s scheduling %s pid:%d", __FUNCTION__, name, pe->pe_pid); sched++; } if (pid) @@ -510,7 +538,7 @@ clixon_process_operation(clicon_handle h, ok: retval = 0; done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); return retval; } @@ -558,6 +586,7 @@ clixon_process_start_all(clicon_handle h) * (1) at startup, if started before deamoninization, process will get as child of 1 * (2) edit changes or rpc restart especially of restconf where you may saw of your arm and terminate * return socket. + * A special complexity is restarting processes, where the old is killed, but state must be kept until it is reaped */ static int clixon_process_sched(int fd, @@ -565,25 +594,68 @@ clixon_process_sched(int fd, { int retval = -1; process_entry_t *pe; + process_entry_t *pe1; proc_operation op; + pid_t newpid; + int run; - clicon_debug(2, "%s",__FUNCTION__); + clicon_debug(1, "%s",__FUNCTION__); if (_proc_entry_list == NULL) goto ok; pe = _proc_entry_list; do { - if ((op = pe->pe_op) != PROC_OP_NONE){ - if (clixon_process_operation_one(op, pe->pe_netns, pe->pe_argv, pe->pe_name, &pe->pe_pid) < 0) + clicon_debug(1, "%s name: %s pid:%d op: %s", __FUNCTION__, + pe->pe_name, pe->pe_pid, clicon_int2str(proc_operation_map, pe->pe_op)); + /* Execute pending operations and not already exiting */ + if ((op = pe->pe_op) != PROC_OP_NONE && + pe->pe_exiting == 0){ + /* Check if running */ + run = 0; + clicon_debug(1, "%s run: %d", __FUNCTION__, run); + if (proc_op_run(pe->pe_pid, &run) < 0) goto done; - clicon_debug(1, "%s op:%s pid:%d", __FUNCTION__, clicon_int2str(proc_operation_map, op), pe->pe_pid); - pe->pe_op = PROC_OP_NONE; + switch (op){ + case PROC_OP_STOP: + clicon_debug(1, "%s stop pid:%d", __FUNCTION__, pe->pe_pid); + case PROC_OP_RESTART: + if (run){ + clicon_log(LOG_NOTICE, "Killing old process %s with pid: %d", pe->pe_name, pe->pe_pid); + kill(pe->pe_pid, SIGTERM); + /* Cant wait here because it would block the backend and terminating may involve + * some protocol handling, instead SIGCHLD is receoved and + * clixon_process_waitpid is called that for waits/reaps the dead process */ + pe->pe_exiting = 1; + } + if (op == PROC_OP_STOP) + break; + if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &newpid) < 0) + goto done; + clicon_debug(1, "%s restart pid:%d -> %d", __FUNCTION__, pe->pe_pid, newpid); + /* Create a new pe */ + if (clixon_process_register_dup(pe, &pe1) < 0) + goto done; + pe->pe_clone = 1; /* Delete when reaped */ + pe1->pe_op = PROC_OP_NONE; /* Dont restart again */ + pe1->pe_pid = newpid; + break; + case PROC_OP_START: + if (run) /* Already runs */ + break; + if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &pe->pe_pid) < 0) + goto done; + clicon_debug(1, "%s started pid:%d", __FUNCTION__, pe->pe_pid); + break; + default: + break; + } } + pe->pe_op = PROC_OP_NONE; pe = NEXTQ(process_entry_t *, pe); } while (pe != _proc_entry_list); ok: retval = 0; done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); return retval; } @@ -602,6 +674,7 @@ clixon_process_sched_register(clicon_handle h) struct timeval t; struct timeval t1 = {0, 1500}; /* See discussion ^*/ + clicon_debug(2, "%s", __FUNCTION__); gettimeofday(&t, NULL); timeradd(&t, &t1, &t); if (clixon_event_reg_timeout(t, clixon_process_sched, h, "process") < 0) @@ -611,3 +684,44 @@ clixon_process_sched_register(clicon_handle h) clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); return retval; } + +/*! Go through processes and wait for child processes + * Typically we know a child has been killed by SIGCHLD, but we do not know which process it is + * Traverse all known processes and reap them, eg call waitpid() to avoid zombies. + * @param[in] h Clixon handle + */ +int +clixon_process_waitpid(clicon_handle h) +{ + int retval = -1; + process_entry_t *pe; + int status = 0; + pid_t wpid; + + clicon_debug(1, "%s", __FUNCTION__); + pe = _proc_entry_list; + do { + if (pe->pe_pid != 0){ + clicon_debug(1, "%s waitpid(%d)", __FUNCTION__, pe->pe_pid); + if ((wpid = waitpid(pe->pe_pid, &status, WNOHANG)) == pe->pe_pid){ + clicon_debug(1, "%s waitpid(%d) waited", __FUNCTION__, pe->pe_pid); + pe->pe_exiting = 0; + pe->pe_pid = 0; /* mark as dead */ + pe->pe_status = status; + if (pe->pe_clone){ + /* Delete it */ + DELQ(pe, _proc_entry_list, process_entry_t *); + clixon_process_delete_only(pe); + } + break; /* pid is unique */ + } + else + clicon_debug(1, "%s waitpid(%d) nomatch:%d", __FUNCTION__, pe->pe_pid, wpid); + } + pe = NEXTQ(process_entry_t *, pe); + } while (pe != _proc_entry_list); + retval = 0; + // done: + clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); + return retval; +} diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 3c664a18..f4b7f453 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -67,9 +67,9 @@ /* clicon */ #include "clixon_err.h" #include "clixon_queue.h" -#include "clixon_event.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_event.h" #include "clixon_log.h" #include "clixon_yang.h" #include "clixon_sig.h" diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index 58b49f0e..3f49cf0d 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -73,10 +73,10 @@ #include "clixon_queue.h" #include "clixon_err.h" #include "clixon_log.h" -#include "clixon_event.h" #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_event.h" #include "clixon_yang.h" #include "clixon_xml.h" #include "clixon_xml_io.h" diff --git a/test/test_restconf_rpc.sh b/test/test_restconf_rpc.sh index eaf0d1d0..e3dcd849 100755 --- a/test/test_restconf_rpc.sh +++ b/test/test_restconf_rpc.sh @@ -7,6 +7,7 @@ # - on enable change, make the state as configured # - No restconf config means enable: false (extra rule) # See test_restconf_netns for network namespaces +# XXX Lots of sleeps to remove race conditions. I am sure there are others way to fix this # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi @@ -62,6 +63,7 @@ function testrpc() operation=$1 expectret=$2 + sleep $DEMSLEEP new "send rpc $operation" ret=$($clixon_netconf -qf $cfg<]]>]]>" "^]]>]]>$" -new "13. check status RPC on" +sleep $DEMSLEEP + +new "16. check status RPC on" pid=$(testrpc status 1) if [ $? -ne 0 ]; then echo "$pid";exit -1; fi @@ -343,9 +347,9 @@ if [ $pid -eq $pid1 ]; then err "A different pid" "Same pid: $pid" fi -new "Edit a non-restconf field via restconf" -echo "curl $CURLOPTS -X POST -H \"Content-Type: application/yang-data+json\" $RCPROTO://localhost/restconf/data -d '{\"example:val\":\"xyz\"}'" +sleep $DEMSLEEP +new "Edit a non-restconf field via restconf" expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"example:val":"xyz"}' )" 0 "HTTP/1.1 201 Created" new "check status RPC same pid" @@ -361,7 +365,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" -new "14. check status RPC off" +new "17. check status RPC off" pid=$(testrpc status 0) if [ $? -ne 0 ]; then echo "$pid";exit -1; fi diff --git a/util/clixon_util_grpc.c b/util/clixon_util_grpc.c index 53e4eca7..922926d9 100644 --- a/util/clixon_util_grpc.c +++ b/util/clixon_util_grpc.c @@ -541,7 +541,7 @@ main(int argc, } if (clixon_event_reg_fd(ss, ssl_input_cb, sd, "ssl socket") < 0) goto done; - if (clixon_event_loop() < 0) + if (clixon_event_loop(h) < 0) goto done; retval = 0; done: diff --git a/util/clixon_util_ssl.c b/util/clixon_util_ssl.c index 1d90045f..facc6ba0 100644 --- a/util/clixon_util_ssl.c +++ b/util/clixon_util_ssl.c @@ -539,7 +539,7 @@ main(int argc, } if (clixon_event_reg_fd(ss, ssl_input_cb, sd, "ssl socket") < 0) goto done; - if (clixon_event_loop() < 0) + if (clixon_event_loop(h) < 0) goto done; retval = 0; done: