C-API: Added cli_process_control(), added uid to cli_process_control()
This commit is contained in:
parent
bd6a67f1d9
commit
080eef0278
12 changed files with 103 additions and 20 deletions
|
|
@ -54,6 +54,7 @@ Expected: July 2023
|
||||||
### C/CLI-API changes on existing features
|
### C/CLI-API changes on existing features
|
||||||
Developers may need to change their code
|
Developers may need to change their code
|
||||||
|
|
||||||
|
* Added `uid` parameter to `clixon_process_register()`
|
||||||
* Added output function to JSON output:
|
* Added output function to JSON output:
|
||||||
* `xml2json_vec(...,skiptop)` --> `xml2json_vec(..., cligen_output, skiptop)`
|
* `xml2json_vec(...,skiptop)` --> `xml2json_vec(..., cligen_output, skiptop)`
|
||||||
* `yang2cli_yspec` removed last argument `printgen`.
|
* `yang2cli_yspec` removed last argument `printgen`.
|
||||||
|
|
|
||||||
|
|
@ -314,13 +314,14 @@ restconf_pseudo_process_control(clicon_handle h)
|
||||||
if (clixon_process_register(h, RESTCONF_PROCESS,
|
if (clixon_process_register(h, RESTCONF_PROCESS,
|
||||||
"Clixon RESTCONF process",
|
"Clixon RESTCONF process",
|
||||||
NULL /* XXX network namespace */,
|
NULL /* XXX network namespace */,
|
||||||
|
-1,
|
||||||
restconf_rpc_wrapper,
|
restconf_rpc_wrapper,
|
||||||
argv, nr) < 0)
|
argv, nr) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (argv != NULL)
|
|
||||||
free(argv);
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (argv != NULL)
|
||||||
|
free(argv);
|
||||||
if (cb)
|
if (cb)
|
||||||
cbuf_free(cb);
|
cbuf_free(cb);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -1626,3 +1626,64 @@ cvec_append(cvec *cvv0,
|
||||||
}
|
}
|
||||||
return cvv2;
|
return cvv2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Process control as defined by clixon-lib API
|
||||||
|
*
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] cvv Not used
|
||||||
|
* @param[in] arg Two strings: <process name> <process operation>
|
||||||
|
* @code
|
||||||
|
* actions-daemon("Actions daemon operations") start,
|
||||||
|
* cli_process_control("Action process", "start");
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cli_process_control(clicon_handle h,
|
||||||
|
cvec *cvv,
|
||||||
|
cvec *argv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *name;
|
||||||
|
char *opstr;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
cxobj *xerr;
|
||||||
|
|
||||||
|
if (cvec_len(argv) != 2){
|
||||||
|
clicon_err(OE_PLUGIN, EINVAL, "Requires two element: process name and operation");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
name = cv_string_get(cvec_i(argv, 0));
|
||||||
|
opstr = cv_string_get(cvec_i(argv, 1));
|
||||||
|
if (clixon_process_op_str2int(opstr) == -1){
|
||||||
|
clicon_err(OE_UNIX, 0, "No such process op: %s", opstr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb, "<rpc xmlns=\"%s\"", NETCONF_BASE_NAMESPACE);
|
||||||
|
cprintf(cb, " %s", NETCONF_MESSAGE_ID_ATTR);
|
||||||
|
cprintf(cb, ">");
|
||||||
|
cprintf(cb, "<process-control xmlns=\"%s\">", CLIXON_LIB_NS);
|
||||||
|
cprintf(cb, "<name>%s</name>", name);
|
||||||
|
cprintf(cb, "<operation>%s</operation>", opstr);
|
||||||
|
cprintf(cb, "</process-control>");
|
||||||
|
cprintf(cb, "</rpc>");
|
||||||
|
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, NULL) < 0)
|
||||||
|
goto done;
|
||||||
|
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||||
|
clixon_netconf_error(xerr, "Get configuration", NULL);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (clixon_xml2file(stdout, xml_child_i(xret, 0), 0, 1, NULL, cligen_output, 0, 1) < 0)
|
||||||
|
goto done;
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1515,7 +1515,6 @@ cli_show_statistics(clicon_handle h,
|
||||||
if (clixon_xml2file(stdout, xml_child_i(xret, 0), 0, 1, NULL, cligen_output, 0, 1) < 0)
|
if (clixon_xml2file(stdout, xml_child_i(xret, 0), 0, 1, NULL, cligen_output, 0, 1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
fprintf(stdout, "CLI:\n");
|
fprintf(stdout, "CLI:\n");
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (xret)
|
if (xret)
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,6 @@ int cli_notification_register(clicon_handle h, char *stream, enum format_enum fo
|
||||||
char *filter, int status,
|
char *filter, int status,
|
||||||
int (*fn)(int, void*), void *arg);
|
int (*fn)(int, void*), void *arg);
|
||||||
|
|
||||||
/* cli_common.c: CLIgen new vector callbacks */
|
|
||||||
|
|
||||||
int mtpoint_paths(yang_stmt *yspec0, char *mtpoint, char *api_path_fmt1, char **api_path_fmt01);
|
int mtpoint_paths(yang_stmt *yspec0, char *mtpoint, char *api_path_fmt1, char **api_path_fmt01);
|
||||||
int dbxml_body(cxobj *xbot, cvec *cvv);
|
int dbxml_body(cxobj *xbot, cvec *cvv);
|
||||||
int identityref_add_ns(cxobj *x, void *arg);
|
int identityref_add_ns(cxobj *x, void *arg);
|
||||||
|
|
@ -113,6 +111,7 @@ int cli_unlock(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_copy_config(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_copy_config(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_help(clicon_handle h, cvec *vars, cvec *argv);
|
int cli_help(clicon_handle h, cvec *vars, cvec *argv);
|
||||||
cvec *cvec_append(cvec *cvv0, cvec *cvv1);
|
cvec *cvec_append(cvec *cvv0, cvec *cvv1);
|
||||||
|
int cli_process_control(clicon_handle h, cvec *vars, cvec *argv);
|
||||||
|
|
||||||
/* In cli_show.c */
|
/* In cli_show.c */
|
||||||
int expand_dbvar(void *h, char *name, cvec *cvv, cvec *argv,
|
int expand_dbvar(void *h, char *name, cvec *cvv, cvec *argv,
|
||||||
|
|
|
||||||
|
|
@ -52,19 +52,25 @@ typedef enum proc_operation {
|
||||||
PROC_OP_STATUS
|
PROC_OP_STATUS
|
||||||
} proc_operation;
|
} proc_operation;
|
||||||
|
|
||||||
/* Process RPC callback function */
|
/*! Process RPC callback function
|
||||||
typedef int (proc_cb_t)(clicon_handle h, process_entry_t *pe, proc_operation *operation);
|
*
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] pe Process entry
|
||||||
|
* @param[in,out] op Process operation
|
||||||
|
*/
|
||||||
|
typedef int (proc_cb_t)(clicon_handle h,
|
||||||
|
process_entry_t *pe,
|
||||||
|
proc_operation *operation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int clixon_proc_socket(char **argv, int sock_flags, pid_t *pid, int *sock);
|
int clixon_proc_socket(char **argv, int sock_flags, pid_t *pid, int *sock);
|
||||||
int clixon_proc_socket_close(pid_t pid, int sock);
|
int clixon_proc_socket_close(pid_t pid, int sock);
|
||||||
int clixon_proc_background(char **argv, const char *netns, pid_t *pid);
|
|
||||||
int clixon_process_pid(clicon_handle h, const char *name, pid_t *pid);
|
int clixon_process_pid(clicon_handle h, const char *name, pid_t *pid);
|
||||||
proc_operation clixon_process_op_str2int(char *opstr);
|
proc_operation clixon_process_op_str2int(char *opstr);
|
||||||
int clixon_process_argv_get(clicon_handle h, const char *name, char ***argv, int *argc);
|
int clixon_process_argv_get(clicon_handle h, const char *name, char ***argv, int *argc);
|
||||||
int clixon_process_register(clicon_handle h, const char *name, const char *descr, const char *netns, proc_cb_t *callback, char **argv, int argc);
|
int clixon_process_register(clicon_handle h, const char *name, const char *descr, const char *netns, uid_t uid, proc_cb_t *callback, char **argv, int argc);
|
||||||
int clixon_process_delete_all(clicon_handle h);
|
int clixon_process_delete_all(clicon_handle h);
|
||||||
int clixon_process_operation(clicon_handle h, const char *name, proc_operation op, const int wrapit);
|
int clixon_process_operation(clicon_handle h, const char *name, proc_operation op, const int wrapit);
|
||||||
int clixon_process_status(clicon_handle h, const char *name, cbuf *cbret);
|
int clixon_process_status(clicon_handle h, const char *name, cbuf *cbret);
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ clicon_log_str(int level,
|
||||||
char *msg)
|
char *msg)
|
||||||
{
|
{
|
||||||
if (_logflags & CLICON_LOG_SYSLOG)
|
if (_logflags & CLICON_LOG_SYSLOG)
|
||||||
syslog(LOG_MAKEPRI(LOG_USER, level), "%s", msg);
|
syslog(LOG_MAKEPRI(LOG_USER, level), "%s", msg); // XXX this may block
|
||||||
/* syslog makes own filtering, we do it here:
|
/* syslog makes own filtering, we do it here:
|
||||||
* if normal (not debug) then filter loglevels >= debug
|
* if normal (not debug) then filter loglevels >= debug
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
* @param[in] buf Packet buffer
|
* @param[in] buf Packet buffer
|
||||||
* @param[in] buflen Length of packet buffer
|
* @param[in] buflen Length of packet buffer
|
||||||
* @param[out] eof Socket closed / eof?
|
* @param[out] eof Socket closed / eof?
|
||||||
* @retval 0 OK
|
* @retval n length
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
ssize_t
|
ssize_t
|
||||||
|
|
|
||||||
|
|
@ -1688,6 +1688,7 @@ netconf_db_find(cxobj *xn,
|
||||||
* cbuf_free(cb);
|
* cbuf_free(cb);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @see clixon_netconf_error_fn
|
* @see clixon_netconf_error_fn
|
||||||
|
* XXX does not support prefixes properly
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
netconf_err2cb(cxobj *xerr,
|
netconf_err2cb(cxobj *xerr,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@
|
||||||
description, namespace, start arguments, etc. Starts in STOPPED state:
|
description, namespace, start arguments, etc. Starts in STOPPED state:
|
||||||
--> STOPPED
|
--> STOPPED
|
||||||
|
|
||||||
On operation "start" or "restart" it gets a pid and goes into RUNNING state:
|
On operation using clixon_process_operation():
|
||||||
|
"start" or "restart" it gets a pid and goes into RUNNING state:
|
||||||
STOPPED -- (re)start --> RUNNING(pid)
|
STOPPED -- (re)start --> RUNNING(pid)
|
||||||
|
|
||||||
When running, several things may happen:
|
When running, several things may happen:
|
||||||
|
|
@ -116,6 +117,7 @@
|
||||||
#include "clixon_hash.h"
|
#include "clixon_hash.h"
|
||||||
#include "clixon_handle.h"
|
#include "clixon_handle.h"
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
|
#include "clixon_uid.h"
|
||||||
#include "clixon_event.h"
|
#include "clixon_event.h"
|
||||||
#include "clixon_sig.h"
|
#include "clixon_sig.h"
|
||||||
#include "clixon_string.h"
|
#include "clixon_string.h"
|
||||||
|
|
@ -143,6 +145,7 @@ struct process_entry_t {
|
||||||
char *pe_name; /* Name of process used for internal use. Unique with exiting=0 */
|
char *pe_name; /* Name of process used for internal use. Unique with exiting=0 */
|
||||||
char *pe_description; /* Description of service */
|
char *pe_description; /* Description of service */
|
||||||
char *pe_netns; /* Network namespace */
|
char *pe_netns; /* Network namespace */
|
||||||
|
uid_t pe_uid; /* UID of process or -1 to keep same as backend */
|
||||||
char **pe_argv; /* argv with command as element 0 and NULL-terminated */
|
char **pe_argv; /* argv with command as element 0 and NULL-terminated */
|
||||||
int pe_argc; /* Length of argc */
|
int pe_argc; /* Length of argc */
|
||||||
pid_t pe_pid; /* Running process id (state) or 0 if dead (pid is set if exiting=1) */
|
pid_t pe_pid; /* Running process id (state) or 0 if dead (pid is set if exiting=1) */
|
||||||
|
|
@ -261,13 +264,15 @@ clixon_proc_socket_close(pid_t pid,
|
||||||
*
|
*
|
||||||
* @param[in] argv NULL-terminated Argument vector
|
* @param[in] argv NULL-terminated Argument vector
|
||||||
* @param[in] netns Network namespace (or NULL)
|
* @param[in] netns Network namespace (or NULL)
|
||||||
|
* @param[in] uid User-id or -1 to keep existing
|
||||||
* @param[out] pid Process id
|
* @param[out] pid Process id
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error.
|
* @retval -1 Error.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
clixon_proc_background(char **argv,
|
clixon_proc_background(char **argv,
|
||||||
const char *netns,
|
const char *netns,
|
||||||
|
uid_t uid,
|
||||||
pid_t *pid0)
|
pid_t *pid0)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -308,10 +313,14 @@ clixon_proc_background(char **argv,
|
||||||
char nsfile[PATH_MAX];
|
char nsfile[PATH_MAX];
|
||||||
int nsfd;
|
int nsfd;
|
||||||
#endif
|
#endif
|
||||||
|
if (uid != -1){
|
||||||
|
if (drop_priv_perm(uid) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
clicon_debug(1, "%s child", __FUNCTION__);
|
clicon_debug(1, "%s child", __FUNCTION__);
|
||||||
clicon_signal_unblock(0);
|
clicon_signal_unblock(0);
|
||||||
signal(SIGTSTP, SIG_IGN);
|
signal(SIGTSTP, SIG_IGN);
|
||||||
|
|
||||||
if (chdir("/") < 0){
|
if (chdir("/") < 0){
|
||||||
clicon_err(OE_UNIX, errno, "chdirq");
|
clicon_err(OE_UNIX, errno, "chdirq");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -425,6 +434,7 @@ clixon_process_argv_get(clicon_handle h,
|
||||||
* @param[in] name Process name
|
* @param[in] name Process name
|
||||||
* @param[in] description Description of process
|
* @param[in] description Description of process
|
||||||
* @param[in] netns Namespace netspace (or NULL)
|
* @param[in] netns Namespace netspace (or NULL)
|
||||||
|
* @param[in] uid UID of process (or -1 to keep same)
|
||||||
* @param[in] callback Wrapper function
|
* @param[in] callback Wrapper function
|
||||||
* @param[in] argv NULL-terminated vector of vectors
|
* @param[in] argv NULL-terminated vector of vectors
|
||||||
* @param[in] argc Length of argv
|
* @param[in] argc Length of argv
|
||||||
|
|
@ -437,6 +447,7 @@ clixon_process_register(clicon_handle h,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *description,
|
const char *description,
|
||||||
const char *netns,
|
const char *netns,
|
||||||
|
const uid_t uid,
|
||||||
proc_cb_t *callback,
|
proc_cb_t *callback,
|
||||||
char **argv,
|
char **argv,
|
||||||
int argc)
|
int argc)
|
||||||
|
|
@ -470,6 +481,7 @@ clixon_process_register(clicon_handle h,
|
||||||
clicon_err(OE_DB, errno, "strdup netns");
|
clicon_err(OE_DB, errno, "strdup netns");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
pe->pe_uid = uid;
|
||||||
pe->pe_argc = argc;
|
pe->pe_argc = argc;
|
||||||
if ((pe->pe_argv = calloc(argc, sizeof(char *))) == NULL){
|
if ((pe->pe_argv = calloc(argc, sizeof(char *))) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "calloc");
|
clicon_err(OE_UNIX, errno, "calloc");
|
||||||
|
|
@ -839,7 +851,8 @@ clixon_process_sched(int fd,
|
||||||
if (proc_op_run(pe->pe_pid, &isrunning) < 0)
|
if (proc_op_run(pe->pe_pid, &isrunning) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (!isrunning)
|
if (!isrunning)
|
||||||
if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &pe->pe_pid) < 0)
|
if (clixon_proc_background(pe->pe_argv, pe->pe_netns,
|
||||||
|
pe->pe_uid, &pe->pe_pid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_debug(1, "%s %s(%d) %s --%s--> %s", __FUNCTION__,
|
clicon_debug(1, "%s %s(%d) %s --%s--> %s", __FUNCTION__,
|
||||||
pe->pe_name, pe->pe_pid,
|
pe->pe_name, pe->pe_pid,
|
||||||
|
|
@ -864,7 +877,8 @@ clixon_process_sched(int fd,
|
||||||
case PROC_OP_START:
|
case PROC_OP_START:
|
||||||
if (isrunning) /* Already runs */
|
if (isrunning) /* Already runs */
|
||||||
break;
|
break;
|
||||||
if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &pe->pe_pid) < 0)
|
if (clixon_proc_background(pe->pe_argv, pe->pe_netns,
|
||||||
|
pe->pe_uid, &pe->pe_pid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_debug(1, "%s %s(%d) %s --%s--> %s", __FUNCTION__,
|
clicon_debug(1, "%s %s(%d) %s --%s--> %s", __FUNCTION__,
|
||||||
pe->pe_name, pe->pe_pid,
|
pe->pe_name, pe->pe_pid,
|
||||||
|
|
@ -967,7 +981,8 @@ clixon_process_waitpid(clicon_handle h)
|
||||||
case PROC_OP_RESTART:
|
case PROC_OP_RESTART:
|
||||||
/* This is the case where there is an existing process running.
|
/* This is the case where there is an existing process running.
|
||||||
* it was killed above but still runs and needs to be reaped */
|
* it was killed above but still runs and needs to be reaped */
|
||||||
if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &pe->pe_pid) < 0)
|
if (clixon_proc_background(pe->pe_argv, pe->pe_netns,
|
||||||
|
pe->pe_uid, &pe->pe_pid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
gettimeofday(&pe->pe_starttime, NULL);
|
gettimeofday(&pe->pe_starttime, NULL);
|
||||||
clicon_debug(1, "%s %s(%d) %s --%s--> %s", __FUNCTION__,
|
clicon_debug(1, "%s %s(%d) %s --%s--> %s", __FUNCTION__,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue