Event priority. Backend socket has higher prio.

This commit is contained in:
Olof hagsand 2024-04-25 14:49:06 +02:00
parent f511cb0030
commit 7e1a00669c
7 changed files with 89 additions and 48 deletions

View file

@ -4,7 +4,7 @@ on:
push: push:
branches: branches:
- master - master
- datastore-split - test-actions
pull_request: pull_request:
branches: [ master ] branches: [ master ]

View file

@ -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

View file

@ -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;

View file

@ -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_ */

View file

@ -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 */
int e_prio; /* 1: high-prio FD:s only*/
struct timeval e_time; /* Timeout */ struct timeval e_time; /* Timeout */
void *e_arg; /* function argument */ void *e_arg; /* Function argument */
char e_string[EVENT_STRLEN]; /* string for debugging */ char e_string[EVENT_STRLEN]; /* String for debugging */
}; };
/* /*
@ -172,6 +174,7 @@ clicon_sig_ignore_get(void)
* @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
@ -218,8 +232,8 @@ 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 = &ee; e_prev = &ee;
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,13 @@ 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) {
if (clixon_exit_get() == 1)
break; 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){
clixon_debug(CLIXON_DBG_EVENT | CLIXON_DBG_DETAIL, "FD_ISSET: %s", e->e_string); 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){ 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;
@ -460,6 +475,28 @@ clixon_event_loop(clixon_handle h)
} }
} }
} }
}
/* 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;
if (e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset) && e->e_prio==0){
clixon_debug(CLIXON_DBG_EVENT, "FD_ISSET: %s", e->e_string);
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;
}
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) */
continue; continue;
err: err:
@ -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){

View file

@ -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