Event priority. Backend socket has higher prio.
This commit is contained in:
parent
f511cb0030
commit
7e1a00669c
7 changed files with 89 additions and 48 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -4,7 +4,7 @@ on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- datastore-split
|
- test-actions
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,17 @@ Expected: June 2024
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
* New: Event priority. Backend socket has higher prio
|
||||||
* New: Split configure datastore multiple sub-files on mount-point boundaries
|
* New: Split configure datastore multiple sub-files on mount-point boundaries
|
||||||
* Avoid writung sub-files without new data (dirty cache)
|
* Avoid writing sub-files without new data (dirty cache)
|
||||||
* Added: Code for SHA digests.
|
* Added: Code for SHA digests.
|
||||||
* New: [Autolock](https://github.com/clicon/clixon/issues/508)
|
* New: [Autolock](https://github.com/clicon/clixon/issues/508)
|
||||||
* CLI configurable format: [Default format should be configurable](https://github.com/clicon/clixon-controller/issues/87)
|
* CLI configurable format: [Default format should be configurable](https://github.com/clicon/clixon-controller/issues/87)
|
||||||
* CLI support for multiple inline commands separated by semi-colon
|
* CLI support for multiple inline commands separated by semi-colon
|
||||||
* New `clixon-config@2024-04-01.yang` revision
|
* New `clixon-config@2024-04-01.yang` revision
|
||||||
* Added options:
|
* Added options:
|
||||||
- `CLICON_XMLDB_MULTIPLE`: Split datastore into multiple sub files
|
- `CLICON_SOCK_PRIO`: Enable socket event priority
|
||||||
|
- `CLICON_XMLDB_MULTI`: Split datastore into multiple sub files
|
||||||
- `CLICON_NETCONF_DUPLICATE_ALLOW`: Disable duplicate check in NETCONF messages
|
- `CLICON_NETCONF_DUPLICATE_ALLOW`: Disable duplicate check in NETCONF messages
|
||||||
- `CLICON_CLI_OUTPUT_FORMAT`: Default CLI output format
|
- `CLICON_CLI_OUTPUT_FORMAT`: Default CLI output format
|
||||||
- `CLICON_AUTOLOCK`: Implicit locks
|
- `CLICON_AUTOLOCK`: Implicit locks
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,6 @@ backend_accept_client(int fd,
|
||||||
}
|
}
|
||||||
if ((ce = backend_client_add(h, &from)) == NULL)
|
if ((ce = backend_client_add(h, &from)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get credentials of connected peer - only for unix socket
|
* Get credentials of connected peer - only for unix socket
|
||||||
*/
|
*/
|
||||||
|
|
@ -291,11 +290,11 @@ backend_accept_client(int fd,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ce->ce_s = s;
|
ce->ce_s = s;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we register callbacks for actual data socket
|
* Register callback for actual data socket
|
||||||
*/
|
*/
|
||||||
if (clixon_event_reg_fd(s, from_client, (void*)ce, "local netconf client socket") < 0)
|
if (clixon_event_reg_fd_prio(s, from_client, (void*)ce, "local netconf client socket",
|
||||||
|
clicon_option_bool(h, "CLICON_SOCK_PRIO")) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
s = -1;
|
s = -1;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ stream_child_free(clixon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
sc = NEXTQ(struct stream_child *, sc);
|
sc = NEXTQ(struct stream_child *, sc);
|
||||||
} while (sc && sc != STREAM_CHILD);
|
} while (sc && sc != STREAM_CHILD);
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -44,30 +44,19 @@
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int clixon_exit_set(int nr);
|
int clixon_exit_set(int nr);
|
||||||
|
|
||||||
int clixon_exit_get(void);
|
int clixon_exit_get(void);
|
||||||
|
|
||||||
int clicon_sig_child_set(int val);
|
int clicon_sig_child_set(int val);
|
||||||
|
|
||||||
int clicon_sig_child_get(void);
|
int clicon_sig_child_get(void);
|
||||||
|
|
||||||
int clicon_sig_ignore_set(int val);
|
int clicon_sig_ignore_set(int val);
|
||||||
|
|
||||||
int clicon_sig_ignore_get(void);
|
int clicon_sig_ignore_get(void);
|
||||||
|
|
||||||
int clixon_event_reg_fd(int fd, int (*fn)(int, void*), void *arg, char *str);
|
int clixon_event_reg_fd(int fd, int (*fn)(int, void*), void *arg, char *str);
|
||||||
|
int clixon_event_reg_fd_prio(int fd, int (*fn)(int, void*), void *arg, char *str, int prio);
|
||||||
int clixon_event_unreg_fd(int s, int (*fn)(int, void*));
|
int clixon_event_unreg_fd(int s, int (*fn)(int, void*));
|
||||||
|
|
||||||
int clixon_event_reg_timeout(struct timeval t, int (*fn)(int, void*),
|
int clixon_event_reg_timeout(struct timeval t, int (*fn)(int, void*),
|
||||||
void *arg, char *str);
|
void *arg, char *str);
|
||||||
|
|
||||||
int clixon_event_unreg_timeout(int (*fn)(int, void*), void *arg);
|
int clixon_event_unreg_timeout(int (*fn)(int, void*), void *arg);
|
||||||
|
|
||||||
int clixon_event_poll(int fd);
|
int clixon_event_poll(int fd);
|
||||||
|
|
||||||
int clixon_event_loop(clixon_handle h);
|
int clixon_event_loop(clixon_handle h);
|
||||||
|
|
||||||
int clixon_event_exit(void);
|
int clixon_event_exit(void);
|
||||||
|
|
||||||
#endif /* _CLIXON_EVENT_H_ */
|
#endif /* _CLIXON_EVENT_H_ */
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
#include "clixon_sig.h"
|
#include "clixon_sig.h"
|
||||||
#include "clixon_proc.h"
|
#include "clixon_proc.h"
|
||||||
|
#include "clixon_options.h"
|
||||||
#include "clixon_event.h"
|
#include "clixon_event.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -77,13 +78,14 @@
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
struct event_data{
|
struct event_data{
|
||||||
struct event_data *e_next; /* next in list */
|
struct event_data *e_next; /* Next in list */
|
||||||
int (*e_fn)(int, void*); /* function */
|
int (*e_fn)(int, void*); /* Callback function */
|
||||||
enum {EVENT_FD, EVENT_TIME} e_type; /* type of event */
|
enum {EVENT_FD, EVENT_TIME} e_type; /* Type of event */
|
||||||
int e_fd; /* File descriptor */
|
int e_fd; /* File descriptor */
|
||||||
struct timeval e_time; /* Timeout */
|
int e_prio; /* 1: high-prio FD:s only*/
|
||||||
void *e_arg; /* function argument */
|
struct timeval e_time; /* Timeout */
|
||||||
char e_string[EVENT_STRLEN]; /* string for debugging */
|
void *e_arg; /* Function argument */
|
||||||
|
char e_string[EVENT_STRLEN]; /* String for debugging */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -168,10 +170,11 @@ clicon_sig_ignore_get(void)
|
||||||
|
|
||||||
/*! Register a callback function to be called on input on a file descriptor.
|
/*! Register a callback function to be called on input on a file descriptor.
|
||||||
*
|
*
|
||||||
* @param[in] fd File descriptor
|
* @param[in] fd File descriptor
|
||||||
* @param[in] fn Function to call when input available on fd
|
* @param[in] fn Function to call when input available on fd
|
||||||
* @param[in] arg Argument to function fn
|
* @param[in] arg Argument to function fn
|
||||||
* @param[in] str Describing string for logging
|
* @param[in] str Describing string for logging
|
||||||
|
* @param[in] prio Priority (0 or 1)
|
||||||
* @code
|
* @code
|
||||||
* int fn(int fd, void *arg){
|
* int fn(int fd, void *arg){
|
||||||
* }
|
* }
|
||||||
|
|
@ -180,10 +183,11 @@ clicon_sig_ignore_get(void)
|
||||||
* @see clixon_event_unreg_fd
|
* @see clixon_event_unreg_fd
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clixon_event_reg_fd(int fd,
|
clixon_event_reg_fd_prio(int fd,
|
||||||
int (*fn)(int, void*),
|
int (*fn)(int, void*),
|
||||||
void *arg,
|
void *arg,
|
||||||
char *str)
|
char *str,
|
||||||
|
int prio)
|
||||||
{
|
{
|
||||||
struct event_data *e;
|
struct event_data *e;
|
||||||
|
|
||||||
|
|
@ -197,12 +201,22 @@ clixon_event_reg_fd(int fd,
|
||||||
e->e_fn = fn;
|
e->e_fn = fn;
|
||||||
e->e_arg = arg;
|
e->e_arg = arg;
|
||||||
e->e_type = EVENT_FD;
|
e->e_type = EVENT_FD;
|
||||||
|
e->e_prio = prio;
|
||||||
e->e_next = ee;
|
e->e_next = ee;
|
||||||
ee = e;
|
ee = e;
|
||||||
clixon_debug(CLIXON_DBG_EVENT | CLIXON_DBG_DETAIL, "registering %s", e->e_string);
|
clixon_debug(CLIXON_DBG_EVENT, "registering %s", e->e_string);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
clixon_event_reg_fd(int fd,
|
||||||
|
int (*fn)(int, void*),
|
||||||
|
void *arg,
|
||||||
|
char *str)
|
||||||
|
{
|
||||||
|
return clixon_event_reg_fd_prio(fd, fn, arg, str, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Deregister a file descriptor callback
|
/*! Deregister a file descriptor callback
|
||||||
*
|
*
|
||||||
* @param[in] s File descriptor
|
* @param[in] s File descriptor
|
||||||
|
|
@ -217,9 +231,9 @@ int
|
||||||
clixon_event_unreg_fd(int s,
|
clixon_event_unreg_fd(int s,
|
||||||
int (*fn)(int, void*))
|
int (*fn)(int, void*))
|
||||||
{
|
{
|
||||||
struct event_data *e;
|
struct event_data *e;
|
||||||
struct event_data **e_prev;
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
struct event_data **e_prev;
|
||||||
|
|
||||||
e_prev = ⅇ
|
e_prev = ⅇ
|
||||||
for (e = ee; e; e = e->e_next){
|
for (e = ee; e; e = e->e_next){
|
||||||
|
|
@ -315,8 +329,9 @@ int
|
||||||
clixon_event_unreg_timeout(int (*fn)(int, void*),
|
clixon_event_unreg_timeout(int (*fn)(int, void*),
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct event_data *e, **e_prev;
|
struct event_data *e;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
struct event_data **e_prev;
|
||||||
|
|
||||||
e_prev = &ee_timers;
|
e_prev = &ee_timers;
|
||||||
for (e = ee_timers; e; e = e->e_next){
|
for (e = ee_timers; e; e = e->e_next){
|
||||||
|
|
@ -365,13 +380,13 @@ int
|
||||||
clixon_event_loop(clixon_handle h)
|
clixon_event_loop(clixon_handle h)
|
||||||
{
|
{
|
||||||
struct event_data *e;
|
struct event_data *e;
|
||||||
struct event_data *e_next;
|
|
||||||
int n;
|
int n;
|
||||||
struct timeval t;
|
struct timeval t;
|
||||||
struct timeval t0;
|
struct timeval t0;
|
||||||
struct timeval tnull = {0,};
|
struct timeval tnull = {0,};
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
struct event_data *e_next;
|
||||||
|
|
||||||
while (clixon_exit_get() != 1){
|
while (clixon_exit_get() != 1){
|
||||||
FD_ZERO(&fdset);
|
FD_ZERO(&fdset);
|
||||||
|
|
@ -409,7 +424,7 @@ clixon_event_loop(clixon_handle h)
|
||||||
* New select loop is called
|
* New select loop is called
|
||||||
* (3) Other signals result in an error and return -1.
|
* (3) Other signals result in an error and return -1.
|
||||||
*/
|
*/
|
||||||
clixon_debug(CLIXON_DBG_EVENT | CLIXON_DBG_DETAIL, "select: %s", strerror(errno));
|
clixon_debug(CLIXON_DBG_EVENT, "select: %s", strerror(errno));
|
||||||
if (clixon_exit_get() == 1){
|
if (clixon_exit_get() == 1){
|
||||||
clixon_err(OE_EVENTS, errno, "select");
|
clixon_err(OE_EVENTS, errno, "select");
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -443,13 +458,33 @@ clixon_event_loop(clixon_handle h)
|
||||||
free(e);
|
free(e);
|
||||||
}
|
}
|
||||||
_ee_unreg = 0;
|
_ee_unreg = 0;
|
||||||
for (e=ee; e; e=e_next){
|
if (clicon_option_bool(h, "CLICON_SOCK_PRIO")){
|
||||||
if (clixon_exit_get() == 1){
|
for (e=ee; e; e=e_next) {
|
||||||
break;
|
if (clixon_exit_get() == 1)
|
||||||
|
break;
|
||||||
|
e_next = e->e_next;
|
||||||
|
if (e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset) && e->e_prio){
|
||||||
|
clixon_debug(CLIXON_DBG_EVENT, "FD_ISSET: %s prio:%d", e->e_string, e->e_prio);
|
||||||
|
if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){
|
||||||
|
clixon_debug(CLIXON_DBG_EVENT, "Error in: %s", e->e_string);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (_ee_unreg){
|
||||||
|
_ee_unreg = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unprio
|
||||||
|
* Note that without prio, round-robin fairness is ensured, not with prio */
|
||||||
|
for (e=ee; e; e=e_next){
|
||||||
|
if (clixon_exit_get() == 1)
|
||||||
|
break;
|
||||||
e_next = e->e_next;
|
e_next = e->e_next;
|
||||||
if(e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset)){
|
if (e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset) && e->e_prio==0){
|
||||||
clixon_debug(CLIXON_DBG_EVENT | CLIXON_DBG_DETAIL, "FD_ISSET: %s", e->e_string);
|
clixon_debug(CLIXON_DBG_EVENT, "FD_ISSET: %s", e->e_string);
|
||||||
if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){
|
if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){
|
||||||
clixon_debug(CLIXON_DBG_EVENT, "Error in: %s", e->e_string);
|
clixon_debug(CLIXON_DBG_EVENT, "Error in: %s", e->e_string);
|
||||||
goto err;
|
goto err;
|
||||||
|
|
@ -458,6 +493,8 @@ clixon_event_loop(clixon_handle h)
|
||||||
_ee_unreg = 0;
|
_ee_unreg = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (clicon_option_bool(h, "CLICON_SOCK_PRIO"))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clixon_exit_decr(); /* If exit is set and > 1, decrement it (and exit when 1) */
|
clixon_exit_decr(); /* If exit is set and > 1, decrement it (and exit when 1) */
|
||||||
|
|
@ -475,7 +512,8 @@ clixon_event_loop(clixon_handle h)
|
||||||
int
|
int
|
||||||
clixon_event_exit(void)
|
clixon_event_exit(void)
|
||||||
{
|
{
|
||||||
struct event_data *e, *e_next;
|
struct event_data *e;
|
||||||
|
struct event_data *e_next;
|
||||||
|
|
||||||
e_next = ee;
|
e_next = ee;
|
||||||
while ((e = e_next) != NULL){
|
while ((e = e_next) != NULL){
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ module clixon-config {
|
||||||
revision 2024-04-01 {
|
revision 2024-04-01 {
|
||||||
description
|
description
|
||||||
"Added options:
|
"Added options:
|
||||||
|
CLICON_SOCK_PRIO: Enable socket event priority
|
||||||
CLICON_XMLDB_MULTI: Split datastore into multiple sub files
|
CLICON_XMLDB_MULTI: Split datastore into multiple sub files
|
||||||
CLICON_NETCONF_DUPLICATE_ALLOW: Disable duplicate check in NETCONF messages.
|
CLICON_NETCONF_DUPLICATE_ALLOW: Disable duplicate check in NETCONF messages.
|
||||||
CLICON_CLI_OUTPUT_FORMAT: Default CLI output format
|
CLICON_CLI_OUTPUT_FORMAT: Default CLI output format
|
||||||
|
|
@ -927,6 +928,18 @@ module clixon-config {
|
||||||
"Group membership to access clixon_backend unix socket and gid for
|
"Group membership to access clixon_backend unix socket and gid for
|
||||||
deamon";
|
deamon";
|
||||||
}
|
}
|
||||||
|
leaf CLICON_SOCK_PRIO {
|
||||||
|
type boolean;
|
||||||
|
default false;
|
||||||
|
description
|
||||||
|
"Enable socket event priority.
|
||||||
|
If enabled, a file-descriptor can be registered as high prio.
|
||||||
|
Presently, the backend socket has higher prio than others.
|
||||||
|
(should be made more generic)
|
||||||
|
Note that a side-effect of enabling this option is that fairness of
|
||||||
|
non-prio events is disabled
|
||||||
|
This is useful if the backend opens other sockets, such as the controller";
|
||||||
|
}
|
||||||
leaf CLICON_BACKEND_USER {
|
leaf CLICON_BACKEND_USER {
|
||||||
type string;
|
type string;
|
||||||
description
|
description
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue