3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief common routines header
7 * Copyright 2018 Deutsche Telekom AG.
8 * Copyright 2018 - 2021 CESNET, z.s.p.o.
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
27 #define _POSIX_C_SOURCE 200809L
36 #include <libyang/libyang.h>
42 * If the compiler supports attribute to mark objects as hidden, mark all
43 * objects as hidden and export only objects explicitly marked to be part of
46 #define API __attribute__((visibility("default")))
48 /** support for pthread_mutex_timedlock */
49 #cmakedefine SR_HAVE_PTHREAD_MUTEX_TIMEDLOCK
50 #ifndef SR_HAVE_PTHREAD_MUTEX_TIMEDLOCK
51 int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime);
54 /** use access() if eaccess() is not available (it may adversely affect access control, however) */
55 #cmakedefine SR_HAVE_EACCESS
56 #ifndef SR_HAVE_EACCESS
57 # define eaccess access
60 /** atomic variables */
61 #cmakedefine SR_HAVE_STDATOMIC
62 #ifdef SR_HAVE_STDATOMIC
63 # include <stdatomic.h>
65 # define ATOMIC_T atomic_uint_fast32_t
66 # define ATOMIC_T_MAX UINT_FAST32_MAX
68 # define ATOMIC_STORE_RELAXED(var, x) atomic_store_explicit(&(var), x, memory_order_relaxed)
69 # define ATOMIC_LOAD_RELAXED(var) atomic_load_explicit(&(var), memory_order_relaxed)
70 # define ATOMIC_INC_RELAXED(var) atomic_fetch_add_explicit(&(var), 1, memory_order_relaxed)
71 # define ATOMIC_ADD_RELAXED(var, x) atomic_fetch_add_explicit(&(var), x, memory_order_relaxed)
72 # define ATOMIC_DEC_RELAXED(var) atomic_fetch_sub_explicit(&(var), 1, memory_order_relaxed)
73 # define ATOMIC_SUB_RELAXED(var, x) atomic_fetch_sub_explicit(&(var), x, memory_order_relaxed)
75 # define ATOMIC_T uint32_t
76 # define ATOMIC_T_MAX UINT32_MAX
78 # define ATOMIC_STORE_RELAXED(var, x) ((var) = (x))
79 # define ATOMIC_LOAD_RELAXED(var) (var)
80 # define ATOMIC_INC_RELAXED(var) __sync_fetch_and_add(&(var), 1)
81 # define ATOMIC_ADD_RELAXED(var, x) __sync_fetch_and_add(&(var), x)
82 # define ATOMIC_DEC_RELAXED(var) __sync_fetch_and_sub(&(var), 1)
83 # define ATOMIC_SUB_RELAXED(var, x) __sync_fetch_and_sub(&(var), x)
86 /** macro for mutex align check */
87 #define SR_MUTEX_ALIGN_CHECK(mutex) ((uintptr_t)mutex % sizeof(void *))
89 /** macro for cond align check */
90 #define SR_COND_ALIGN_CHECK(cond) ((uintptr_t)cond % sizeof(void *))
92 /** macro for checking datastore type */
93 #define SR_IS_CONVENTIONAL_DS(ds) ((ds == SR_DS_STARTUP) || (ds == SR_DS_RUNNING) || (ds == SR_DS_CANDIDATE))
95 /** macro for all datastore types count */
98 /** macro for checking session type */
99 #define SR_IS_EVENT_SESS(session) (session->ev != SR_SUB_EV_NONE)
101 /** macro for getting a SHM module on a specific index */
102 #define SR_SHM_MOD_IDX(main_shm_addr, idx) ((sr_mod_t *)(((char *)main_shm_addr) + sizeof(sr_main_shm_t) + idx * sizeof(sr_mod_t)))
104 /* macro for getting aligned SHM size */
105 #define SR_SHM_SIZE(size) ((size) + ((~(size) + 1) & (SR_SHM_MEM_ALIGN - 1)))
107 /* macro for getting main SHM from a connection */
108 #define SR_CONN_MAIN_SHM(conn) ((sr_main_shm_t *)(conn)->main_shm.addr)
110 /* macro for getting ext SHM from a connection */
111 #define SR_CONN_EXT_SHM(conn) ((sr_ext_shm_t *)(conn)->ext_shm.addr)
113 /** name of sysrepo YANG module */
114 #define SR_YANG_MOD "sysrepo"
116 /** UID of the superuser that can execute sensitive functions */
117 #define SR_SU_UID @SYSREPO_SUPERUSER_UID@
119 /** implemented ietf-yang-library revision */
120 #define SR_YANGLIB_REVISION @YANGLIB_REVISION@
122 /** main sysrepo repository path; prefix of all other paths by default */
123 #define SR_REPO_PATH "@REPO_PATH@"
125 /** environment variable overriding the compiled-in value */
126 #define SR_REPO_PATH_ENV "SYSREPO_REPOSITORY_PATH"
128 /** if not set, defaults to "SR_REPO_PATH/data" */
129 #define SR_STARTUP_PATH "@STARTUP_DATA_PATH@"
131 /** if not set, defaults to "SR_REPO_PATH/data/notif" */
132 #define SR_NOTIFICATION_PATH "@NOTIFICATION_PATH@"
134 /** if not set, defaults to "SR_REPO_PATH/yang" */
135 #define SR_YANG_PATH "@YANG_MODULE_PATH@"
137 /** where SHM files are stored */
138 #define SR_SHM_DIR "/dev/shm"
140 /** default prefix for SHM files in /dev/shm */
141 #define SR_SHM_PREFIX_DEFAULT "sr"
143 /** suffix of backed-up LYB files */
144 #define SR_FILE_BACKUP_SUFFIX ".bck"
146 /** environment variable for setting a custom prefix for SHM files */
147 #define SR_SHM_PREFIX_ENV "SYSREPO_SHM_PREFIX"
149 /** maximum number of possible system-wide concurrent owners of a read lock */
150 #define SR_RWLOCK_READ_LIMIT 10
152 /** all ext SHM item sizes will be aligned to this number; also represents the allocation unit (B) */
153 #define SR_SHM_MEM_ALIGN 8
155 /** notification file will never exceed this size (kB) */
156 #define SR_EV_NOTIF_FILE_MAX_SIZE 1024
158 /** timeout for locking subscription structure lock, should be enough for a single ::sr_process_events() call (ms) */
159 #define SR_SUBSCR_LOCK_TIMEOUT 30000
161 /** timeout for locking lydmods data for access; should be enough for parsing, applying any scheduled changes, and printing (ms) */
162 #define SR_LYDMODS_LOCK_TIMEOUT 5000
164 /** timeout for locking notification buffer lock, used when adding/removing notifications (ms) */
165 #define SR_NOTIF_BUF_LOCK_TIMEOUT 100
167 /** timeout for locking subscription SHM; maximum time an event handling should take (ms) */
168 #define SR_SUBSHM_LOCK_TIMEOUT 10000
170 /** timeout for locking ext SHM lock; time that truncating and writing into SHM may take (ms) */
171 #define SR_EXT_LOCK_TIMEOUT 100
173 /** timeout for locking the local connection list; maximum time the list can be accessed (ms) */
174 #define SR_CONN_LIST_LOCK_TIMEOUT 100
176 /** timeout for locking connection remap lock; maximum time it can be continuously read/written to it (ms) */
177 #define SR_CONN_REMAP_LOCK_TIMEOUT 10000
179 /** timeout for locking (data of) a module; maximum time a module write lock is expected to be held (ms) */
180 #define SR_MOD_LOCK_TIMEOUT 5000
182 /** timeout for locking SHM module/RPC subscriptions; maxmum time full event processing may take (ms) */
183 #define SR_SHMEXT_SUB_LOCK_TIMEOUT 15000
185 /** timeout for locking module cache (ms) */
186 #define SR_MOD_CACHE_LOCK_TIMEOUT 10000
188 /** default timeout for change subscription callback (ms) */
189 #define SR_CHANGE_CB_TIMEOUT 60000
191 /** default timeout for operational subscription callback (ms) */
192 #define SR_OPER_CB_TIMEOUT 60000
194 /** default timeout for RPC/action subscription callback (ms) */
195 #define SR_RPC_CB_TIMEOUT 60000
197 /** group to own all directories/files */
198 #define SR_GROUP "@SYSREPO_GROUP@"
200 /** umask modifying all the permissions below */
201 #define SR_UMASK @SYSREPO_UMASK@
203 /** permissions of main SHM lock file and main SHM itself */
204 #define SR_MAIN_SHM_PERM 00666
206 /** permissions of connection lock files */
207 #define SR_CONN_LOCKFILE_PERM 00666
209 /** permissions of all subscription SHMs */
210 #define SR_SUB_SHM_PERM 00666
212 /** permissions of all event pipes (only owner read, anyone else write */
213 #define SR_EVPIPE_PERM 00622
215 /** permissions of directories for sysrepo files */
216 #define SR_DIR_PERM 00777
218 /** permissions of used YANG modules */
219 #define SR_YANG_PERM 00644
221 /** permissions of stored notifications and data files */
222 #define SR_FILE_PERM 00600
224 /** permissions of data files of internal modules */
225 #define SR_INT_FILE_PERM 00664
227 /** permission of data files of sysrepo-monitoring internal module */
228 #define SR_MON_INT_FILE_PERM 00600
230 /** initial length of message buffer (B) */
231 #define SR_MSG_LEN_START 128
233 /** default operational origin for operational data (push/pull) */
234 #define SR_OPER_ORIGIN "unknown"
236 /** default operational origin for enabled running data */
237 #define SR_CONFIG_ORIGIN "intended"
240 * Internal declarations + definitions
243 extern char sysrepo_yang[];
245 typedef struct sr_mod_s sr_mod_t;
247 typedef struct sr_dep_s sr_dep_t;
249 /** static initializer of the shared memory structure */
250 #define SR_SHM_INITIALIZER {.fd = -1, .size = 0, .addr = NULL}
252 /** initializer of mod_info structure */
253 #define SR_MODINFO_INIT(mi, c, d, d2) mi.ds = (d); mi.ds2 = (d2); mi.diff = NULL; mi.data = NULL; \
254 mi.data_cached = 0; mi.conn = (c); mi.mods = NULL; mi.mod_count = 0
257 * @brief Generic shared memory information structure.
259 typedef struct sr_shm_s {
260 int fd; /**< Shared memory file desriptor. */
261 size_t size; /**< Shared memory mapping current size. */
262 char *addr; /**< Shared memory mapping address. */
266 * @brief Session information structure.
268 typedef struct sr_sid_s {
269 uint32_t sr; /**< Sysrepo session ID. */
270 uint32_t nc; /**< NETCONF session ID. */
271 char *user; /**< Sysrepo user. */
275 * @brief Connection ID.
277 typedef uint32_t sr_cid_t;
282 typedef enum sr_lock_mode_e {
283 SR_LOCK_NONE = 0, /**< Not locked. */
284 SR_LOCK_READ, /**< Read lock. */
285 SR_LOCK_READ_UPGR, /**< Read lock with the upgrade capability. */
286 SR_LOCK_WRITE /**< Write lock. */
290 * @brief Sysrepo read-write lock.
292 typedef struct sr_rwlock_s {
293 pthread_mutex_t mutex; /**< Lock mutex. */
294 pthread_cond_t cond; /**< Lock condition variable. */
296 pthread_mutex_t r_mutex; /**< Mutex for accessing readers, needed because of concurrent reading. */
297 sr_cid_t readers[SR_RWLOCK_READ_LIMIT]; /**< CIDs of all READ lock owners (including READ-UPGR), 0s otherwise. */
298 sr_cid_t upgr; /**< CID of the READ-UPGR lock owner if locked, 0 otherwise. */
299 sr_cid_t writer; /**< CID of the WRITE lock owner if locked, 0 otherwise. */
302 struct modsub_changesub_s;
303 struct modsub_change_s;
304 struct modsub_opersub_s;
305 struct modsub_oper_s;
306 struct opsub_rpcsub_s;
308 struct modsub_notif_s;
310 #include "edit_diff.h"
314 #include "lyd_mods.h"
318 * Private definitions of public declarations
322 * @brief Sysrepo connection.
324 struct sr_conn_ctx_s {
325 struct ly_ctx *ly_ctx; /**< Libyang context, also available to user. */
326 sr_conn_options_t opts; /**< Connection options. */
327 sr_diff_check_cb diff_check_cb; /**< Connection user diff check callback. */
329 pthread_mutex_t ptr_lock; /**< Session-shared lock for accessing pointers to sessions. */
330 sr_session_ctx_t **sessions; /**< Array of sessions for this connection. */
331 uint32_t session_count; /**< Session count. */
332 sr_cid_t cid; /**< Globally unique connection ID */
334 int main_create_lock; /**< Process-shared file lock for creating main/ext SHM. */
335 sr_rwlock_t ext_remap_lock; /**< Session-shared lock only for remapping ext SHM. */
336 sr_shm_t main_shm; /**< Main SHM structure. */
337 sr_shm_t ext_shm; /**< External SHM structure (all stored offsets point here). */
339 struct sr_mod_cache_s {
340 sr_rwlock_t lock; /**< Session-shared lock for accessing the module cache. */
341 struct lyd_node *data; /**< Data of all cached modules, */
344 const struct lys_module *ly_mod; /**< Libyang module in the cache. */
345 uint32_t ver; /**< Version of the module data in the cache, 0 is not valid */
346 } *mods; /**< Array of cached modules. */
347 uint32_t mod_count; /**< Cached modules count. */
348 } mod_cache; /**< Module running data cache. */
352 * @brief Sysrepo session.
354 struct sr_session_ctx_s {
355 sr_conn_ctx_t *conn; /**< Connection used for creating this session. */
356 sr_datastore_t ds; /**< Datastore of the session. */
357 sr_sub_event_t ev; /**< Event of a callback session. ::SR_SUB_EV_NONE for standard user sessions. */
358 sr_sid_t sid; /**< Session information. */
359 sr_sid_t ev_sid; /**< Event (originator) session information. Valid only if ev is not ::SR_SUB_EV_NONE. */
360 sr_error_info_t *err_info; /**< Session error information. */
362 pthread_mutex_t ptr_lock; /**< Lock for accessing pointers to subscriptions. */
363 sr_subscription_ctx_t **subscriptions; /**< Array of subscriptions of this session. */
364 uint32_t subscription_count; /**< Subscription count. */
367 struct lyd_node *edit; /**< Prepared edit data tree. */
368 struct lyd_node *diff; /**< Diff data tree, used for module change iterator. */
369 } dt[SR_DS_COUNT]; /**< Session-exclusive prepared changes. */
371 struct sr_sess_notif_buf {
372 ATOMIC_T thread_running; /**< Flag whether the notification buffering thread of this session is running. */
373 pthread_t tid; /**< Thread ID of the thread. */
374 sr_rwlock_t lock; /**< Lock for accessing thread_running and the notification buffer
375 (READ-lock is not used). */
376 struct sr_sess_notif_buf_node {
377 char *notif_lyb; /**< Buffered notification to be stored in LYB format. */
378 time_t notif_ts; /**< Buffered notification timestamp. */
379 const struct lys_module *notif_mod; /**< Buffered notification modules. */
380 struct sr_sess_notif_buf_node *next; /**< Next stored notification buffer node. */
381 } *first; /**< First stored notification buffer node. */
382 struct sr_sess_notif_buf_node *last; /**< Last stored notification buffer node. */
383 } notif_buf; /**< Notification buffering attributes. */
387 * @brief Sysrepo subscription.
389 struct sr_subscription_ctx_s {
390 sr_conn_ctx_t *conn; /**< Connection of the subscription. */
391 uint32_t evpipe_num; /**< Event pipe number of this subscription structure. */
392 int evpipe; /**< Event pipe opened for reading. */
393 ATOMIC_T thread_running; /**< Flag whether the thread handling this subscription is running. */
394 pthread_t tid; /**< Thread ID of the handler thread. */
395 sr_rwlock_t subs_lock; /**< Session-shared lock for accessing the subscriptions. */
397 struct modsub_change_s {
398 char *module_name; /**< Module of the subscriptions. */
399 sr_datastore_t ds; /**< Datastore of the subscriptions. */
400 struct modsub_changesub_s {
401 char *xpath; /**< Subscription XPath. */
402 uint32_t priority; /**< Subscription priority. */
403 sr_subscr_options_t opts; /**< Subscription options. */
404 sr_module_change_cb cb; /**< Subscription callback. */
405 void *private_data; /**< Subscription callback private data. */
406 sr_session_ctx_t *sess; /**< Subscription session. */
408 uint32_t request_id; /**< Request ID of the last processed request. */
409 sr_sub_event_t event; /**< Type of the last processed event. */
410 } *subs; /**< Configuration change subscriptions for each XPath. */
411 uint32_t sub_count; /**< Configuration change module XPath subscription count. */
413 sr_shm_t sub_shm; /**< Subscription SHM. */
414 } *change_subs; /**< Change subscriptions for each module. */
415 uint32_t change_sub_count; /**< Change module subscription count. */
417 struct modsub_oper_s {
418 char *module_name; /**< Module of the subscriptions. */
419 struct modsub_opersub_s {
420 char *xpath; /**< Subscription XPath. */
421 sr_oper_get_items_cb cb; /**< Subscription callback. */
422 void *private_data; /**< Subscription callback private data. */
423 sr_session_ctx_t *sess; /**< Subscription session. */
425 uint32_t request_id; /**< Request ID of the last processed request. */
426 sr_shm_t sub_shm; /**< Subscription SHM. */
427 } *subs; /**< Operational subscriptions for each XPath. */
428 uint32_t sub_count; /**< Operational module XPath subscription count. */
429 } *oper_subs; /**< Operational subscriptions for each module. */
430 uint32_t oper_sub_count; /**< Operational module subscription count. */
432 struct modsub_notif_s {
433 char *module_name; /**< Module of the subscriptions. */
434 struct modsub_notifsub_s {
435 uint32_t sub_id; /**< Unique (notification) subscription ID. */
436 char *xpath; /**< Subscription XPath. */
437 time_t start_time; /**< Subscription start time. */
438 int replayed; /**< Flag whether the subscription replay is finished. */
439 time_t stop_time; /**< Subscription stop time. */
440 sr_event_notif_cb cb; /**< Subscription value callback. */
441 sr_event_notif_tree_cb tree_cb; /**< Subscription tree callback. */
442 void *private_data; /**< Subscription callback private data. */
443 sr_session_ctx_t *sess; /**< Subscription session. */
444 } *subs; /**< Notification subscriptions for each XPath. */
445 uint32_t sub_count; /**< Notification module XPath subscription count. */
447 uint32_t request_id; /**< Request ID of the last processed request. */
448 sr_shm_t sub_shm; /**< Subscription SHM. */
449 } *notif_subs; /**< Notification subscriptions for each module. */
450 uint32_t notif_sub_count; /**< Notification module subscription count. */
453 char *path; /**< Subscription RPC/action path. */
454 struct opsub_rpcsub_s {
455 char *xpath; /**< Subscription XPath. */
456 uint32_t priority; /**< Subscription priority. */
457 sr_rpc_cb cb; /**< Subscription value callback. */
458 sr_rpc_tree_cb tree_cb; /**< Subscription tree callback. */
459 void *private_data; /**< Subscription callback private data. */
460 sr_session_ctx_t *sess; /**< Subscription session. */
462 uint32_t request_id; /**< Request ID of the last processed request. */
463 sr_sub_event_t event; /**< Type of the last processed event. */
464 } *subs; /**< RPC/action subscription for each XPath. */
465 uint32_t sub_count; /**< RPC/action XPath subscription count. */
467 sr_shm_t sub_shm; /**< Subscription SHM. */
468 } *rpc_subs; /**< RPC/action subscriptions for each operation. */
469 uint32_t rpc_sub_count; /**< RPC/action operation subscription count. */
473 * @brief Change iterator.
475 struct sr_change_iter_s {
476 struct lyd_node *diff; /**< Optional copied diff that set items point into. */
477 struct ly_set *set; /**< Set of all the selected diff nodes. */
478 uint32_t idx; /**< Index of the next change. */
486 * @brief Start a new session.
488 * @param[in] conn Connection of the session.
489 * @param[in] datastore Datastore of the session.
490 * @param[in] event Optional event the session is handling, SR_SUB_EV_NONE for a standard session.
491 * @param[in] ev_sid Event originator SID.
492 * @param[in] ev_ncid Event originator NCID.
493 * @param[in] ev_user Event originator user.
494 * @param[out] session Created session.
495 * @return err_info, NULL on success.
497 sr_error_info_t *_sr_session_start(sr_conn_ctx_t *conn, const sr_datastore_t datastore, sr_sub_event_t event,
498 uint32_t ev_sid, uint32_t ev_ncid, const char *ev_user, sr_session_ctx_t **session);
501 * Subscription functions
505 * @brief Add a change subscription into a subscription structure.
507 * @param[in] sess Subscription session.
508 * @param[in] mod_name Subscription module name.
509 * @param[in] xpath Subscription XPath.
510 * @param[in] change_cb Subscription callback.
511 * @param[in] private_data Subscription callback private data.
512 * @param[in] priority Subscription priority.
513 * @param[in] sub_opts Subscription options.
514 * @param[in] has_subs_lock What kind of SUBS lock is held.
515 * @param[in,out] subs Subscription structure.
516 * @return err_info, NULL on success.
518 sr_error_info_t *sr_sub_change_add(sr_session_ctx_t *sess, const char *mod_name, const char *xpath, sr_module_change_cb change_cb,
519 void *private_data, uint32_t priority, sr_subscr_options_t sub_opts, sr_lock_mode_t has_subs_lock,
520 sr_subscription_ctx_t *subs);
523 * @brief Delete a change subscription from a subscription structure.
525 * @param[in] mod_name Subscription module name.
526 * @param[in] xpath Subscription XPath.
527 * @param[in] ds Subscription datastore.
528 * @param[in] change_cb Subscription callback.
529 * @param[in] private_data Subscription callback private data.
530 * @param[in] priority Subscription priority.
531 * @param[in] sub_opts Subscription options.
532 * @param[in] has_subs_lock What kind of SUBS lock is held.
533 * @param[in,out] subs Subscription structure.
535 void sr_sub_change_del(const char *mod_name, const char *xpath, sr_datastore_t ds, sr_module_change_cb change_cb,
536 void *private_data, uint32_t priority, sr_subscr_options_t sub_opts, sr_lock_mode_t has_subs_lock,
537 sr_subscription_ctx_t *subs);
540 * @brief Add an operational subscription into a subscription structure.
542 * @param[in] sess Subscription session.
543 * @param[in] mod_name Subscription module name.
544 * @param[in] xpath Subscription XPath.
545 * @param[in] oper_cb Subscription callback.
546 * @param[in] private_data Subscription callback private data.
547 * @param[in] has_subs_lock What kind of SUBS lock is held.
548 * @param[in,out] subs Subscription structure.
549 * @return err_info, NULL on success.
551 sr_error_info_t *sr_sub_oper_add(sr_session_ctx_t *sess, const char *mod_name, const char *xpath,
552 sr_oper_get_items_cb oper_cb, void *private_data, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
555 * @brief Delete an operational subscription from a subscription structure.
557 * @param[in] mod_name Subscription module name.
558 * @param[in] xpath Subscription XPath.
559 * @param[in] has_subs_lock What kind of SUBS lock is held.
560 * @param[in,out] subs Subscription structure.
562 void sr_sub_oper_del(const char *mod_name, const char *xpath, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
565 * @brief Add a notification subscription into a subscription structure.
567 * @param[in] sess Subscription session.
568 * @param[in] mod_name Subscription module name.
569 * @param[in] sub_id Unique notif sub ID.
570 * @param[in] xpath Subscription XPath.
571 * @param[in] start_time Subscription start time.
572 * @param[in] stop_time Subscription stop time.
573 * @param[in] notif_cb Subscription value callback.
574 * @param[in] notif_tree_cb Subscription tree callback.
575 * @param[in] private_data Subscription callback private data.
576 * @param[in] has_subs_lock What kind of SUBS lock is held.
577 * @param[in,out] subs Subscription structure.
578 * @return err_info, NULL on success.
580 sr_error_info_t *sr_sub_notif_add(sr_session_ctx_t *sess, const char *mod_name, uint32_t sub_id, const char *xpath,
581 time_t start_time, time_t stop_time, sr_event_notif_cb notif_cb, sr_event_notif_tree_cb notif_tree_cb,
582 void *private_data, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
585 * @brief Delete a notification subscription from a subscription structure.
587 * @param[in] mod_name Subscription module name.
588 * @param[in] sub_id Unique notif sub ID.
589 * @param[in] has_subs_lock What kind of SUBS lock is held.
590 * @param[in,out] subs Subscription structure.
592 void sr_sub_notif_del(const char *mod_name, uint32_t sub_id, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
595 * @brief Add an RPC subscription into a subscription structure.
597 * @param[in] sess Subscription session.
598 * @param[in] path Subscription RPC path.
599 * @param[in] xpath Subscription XPath.
600 * @param[in] rpc_cb Subscription value callback.
601 * @param[in] rpc_tree_cb Subscription tree callback.
602 * @param[in] private_data Subscription callback private data.
603 * @param[in] priority Subscription priority.
604 * @param[in] has_subs_lock What kind of SUBS lock is held.
605 * @param[in,out] subs Subscription structure.
606 * @return err_info, NULL on success.
608 sr_error_info_t *sr_sub_rpc_add(sr_session_ctx_t *sess, const char *path, const char *xpath, sr_rpc_cb rpc_cb,
609 sr_rpc_tree_cb rpc_tree_cb, void *private_data, uint32_t priority, sr_lock_mode_t has_subs_lock,
610 sr_subscription_ctx_t *subs);
613 * @brief Delete an RPC subscription from a subscription structure.
615 * @param[in] path Subscription RPC path.
616 * @param[in] xpath Subscription XPath.
617 * @param[in] rpc_cb Subscription value callback.
618 * @param[in] rpc_tree_cb Subscription tree callback.
619 * @param[in] private_data Subscription callback private data.
620 * @param[in] priority Subscription priority.
621 * @param[in] has_subs_lock What kind of SUBS lock is held.
622 * @param[in,out] subs Subscription structure.
624 void sr_sub_rpc_del(const char *path, const char *xpath, sr_rpc_cb rpc_cb, sr_rpc_tree_cb rpc_tree_cb,
625 void *private_data, uint32_t priority, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
628 * @brief Count subscriptions of session \p sess in subscriptions structure \p subs.
630 * @param[in] sess Subscription session.
631 * @param[in] has_subs_lock What kind of SUBS lock is held.
632 * @param[in] subs Session subscription.
633 * @return Number of session subscriptions.
635 int sr_subs_session_count(sr_session_ctx_t *sess, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
638 * @brief Delete all subscriptions in \p subs of session \p sess.
639 * Main SHM read-upgr lock must be held and will be temporarily upgraded!
641 * @param[in] sess Subscription session.
642 * @param[in] has_subs_lock What kind of SUBS lock is held.
643 * @param[in] subs Session subscription.
644 * @return err_info, NULL on success.
646 sr_error_info_t *sr_subs_session_del(sr_session_ctx_t *sess, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
649 * @brief Delete all subscriptions in \p subs of all the sessions.
650 * Main SHM read-upgr lock must be held and will be temporarily upgraded!
652 * @param[in,out] subs Subscription structure.
653 * @return err_info, NULL on success.
655 sr_error_info_t *sr_subs_del_all(sr_subscription_ctx_t *subs);
658 * @brief Find notifications subscribers for a module.
660 * @param[in] conn Connection to use.
661 * @param[in] mod_name Module name.
662 * @param[out] notif_subs Notification subscriptions.
663 * @param[out] notif_sub_count Number of subscribers.
664 * @return err_info, NULL on success.
666 sr_error_info_t *sr_notif_find_subscriber(sr_conn_ctx_t *conn, const char *mod_name, sr_mod_notif_sub_t **notif_subs,
667 uint32_t *notif_sub_count);
670 * @brief Call notification callback for a notification.
672 * @param[in] ev_sess Event session to provide for the callback.
673 * @param[in] cb Value callback.
674 * @param[in] tree_cb Tree callback.
675 * @param[in] private_data Callback private data.
676 * @param[in] notif_type Notification type.
677 * @param[in] notif_op Notification node of the notification (relevant for nested notifications).
678 * @param[in] notif_ts Timestamp of when the notification was generated.
679 * @return err_info, NULL on success.
681 sr_error_info_t *sr_notif_call_callback(sr_session_ctx_t *ev_sess, sr_event_notif_cb cb, sr_event_notif_tree_cb tree_cb,
682 void *private_data, const sr_ev_notif_type_t notif_type, const struct lyd_node *notif_op, time_t notif_ts);
689 * @brief Add a generic pointer to a ptr array.
691 * @param[in] ptr_lock Pointers lock.
692 * @param[in,out] ptrs Pointer array to enlarge.
693 * @param[in,out] ptr_count Pointer array count.
694 * @param[in] add_ptr Pointer to add.
695 * @return err_info, NULL on success.
697 sr_error_info_t *sr_ptr_add(pthread_mutex_t *ptr_lock, void ***ptrs, uint32_t *ptr_count, void *add_ptr);
700 * @brief Delete a generic pointer from a ptr array.
702 * @param[in,out] ptrs Pointer array to delete from.
703 * @param[in,out] ptr_count Pointer array count.
704 * @param[in] del_ptr Pointer to delete.
705 * @return err_info, NULL on success.
707 sr_error_info_t *sr_ptr_del(pthread_mutex_t *ptr_lock, void ***ptrs, uint32_t *ptr_count, void *del_ptr);
710 * @brief Wrapper for libyang ly_ctx_new().
712 * @param[out] ly_ctx libyang context.
713 * @return err_info, NULL on success.
715 sr_error_info_t *sr_ly_ctx_new(struct ly_ctx **ly_ctx);
718 * @brief Remove module YANG file.
720 * @param[in] name Module name.
721 * @param[in] revision Module revision, NULL if none.
722 * @return err_info, NULL on success.
724 sr_error_info_t *sr_remove_module_file(const char *name, const char *revision);
727 * @brief Create (print) YANG module file and all of its submodules.
729 * @param[in] ly_mod Module to print.
730 * @return err_info, NULL on success.
732 sr_error_info_t *sr_store_module_files(const struct lys_module *ly_mod);
735 * @brief Unlink startup, running, and candidate files of a module.
737 * @param[in] mod_name Module name.
738 * @return err_info, NULL on success.
740 sr_error_info_t *sr_remove_data_files(const char *mod_name);
743 * @brief Check whether a module is internal libyang or sysrepo module.
745 * @param[in] ly_mod Module to check.
746 * @return 0 if not, non-zero if it is.
748 int sr_module_is_internal(const struct lys_module *ly_mod);
751 * @brief Create startup file for a module.
753 * @param[in] ly_mod Module to create startup file for.
754 * @return err_info, NULL on success.
756 sr_error_info_t *sr_create_startup_file(const struct lys_module *ly_mod);
759 * @brief Create all module import and include files, recursively.
761 * @param[in] ly_mod libyang module whose imports and includes to create.
762 * @return err_info, NULL on success.
764 sr_error_info_t *sr_create_module_imps_incs_r(const struct lys_module *ly_mod);
767 * @brief Get the path the main SHM.
769 * @param[out] path Created path. Should be freed by the caller.
770 * @return err_info, NULL on success.
772 sr_error_info_t *sr_path_main_shm(char **path);
775 * @brief Get the path the external SHM.
777 * @param[out] path Created path. Should be freed by the caller.
778 * @return err_info, NULL on success.
780 sr_error_info_t *sr_path_ext_shm(char **path);
783 * @brief Get the path to a subscription SHM.
785 * @param[in] mod_name Module name.
786 * @param[in] suffix1 First suffix.
787 * @param[in] suffix2 Second suffix, none if equals -1.
788 * @param[out] path Created path.
789 * @return err_info, NULL on success.
791 sr_error_info_t *sr_path_sub_shm(const char *mod_name, const char *suffix1, int64_t suffix2, char **path);
794 * @brief Get the path to a subscription data SHM.
796 * @param[in] mod_name Module name.
797 * @param[in] suffix1 First suffix.
798 * @param[in] suffix2 Second suffix, none if equals -1.
799 * @param[out] path Created path.
800 * @return err_info, NULL on success.
802 sr_error_info_t *sr_path_sub_data_shm(const char *mod_name, const char *suffix1, int64_t suffix2, char **path);
805 * @brief Get the path to a volatile datastore SHM.
807 * @param[in] mod_name Module name.
808 * @param[in] ds Target datastore.
809 * @param[out] path Created path.
810 * @return err_info, NULL on success.
812 sr_error_info_t *sr_path_ds_shm(const char *mod_name, sr_datastore_t ds, char **path);
815 * @brief Get the path to an event pipe.
817 * @param[in] evpipe_num Event pipe number.
818 * @param[out] path Created path.
819 * @return err_info, NULL on success.
821 sr_error_info_t *sr_path_evpipe(uint32_t evpipe_num, char **path);
824 * @brief Get the path to startup files directory.
826 * @param[out] path Created path.
827 * @return err_info, NULL on success.
829 sr_error_info_t *sr_path_startup_dir(char **path);
832 * @brief Get the path to notification files directory.
834 * @param[out] path Created path.
835 * @return err_info, NULL on success.
837 sr_error_info_t *sr_path_notif_dir(char **path);
840 * @brief Get the path to YANG module files directory.
842 * @param[out] path Created path.
843 * @return err_info, NULL on success.
845 sr_error_info_t *sr_path_yang_dir(char **path);
848 * @brief Get the path to a module startup file.
850 * @param[in] mod_name Module name.
851 * @param[out] path Created path.
852 * @return err_info, NULL on success.
854 sr_error_info_t *sr_path_startup_file(const char *mod_name, char **path);
857 * @brief Get the path to a module notification file.
859 * @param[in] mod_name Module name.
860 * @param[in] from_ts Timestamp of the first stored notification.
861 * @param[in] to_ts Timestamp of the last stored notification.
862 * @param[out] path Created path.
863 * @return err_info, NULL on success.
865 sr_error_info_t *sr_path_notif_file(const char *mod_name, time_t from_ts, time_t to_ts, char **path);
868 * @brief Get the path to a YANG module file.
870 * @param[in] mod_name Module name.
871 * @param[in] mod_rev Module revision.
872 * @param[out] path Created path.
873 * @return err_info, NULL on success.
875 sr_error_info_t *sr_path_yang_file(const char *mod_name, const char *mod_rev, char **path);
878 * @brief Populate the lockfile path for a given Connection ID.
879 * When called with cid of 0 the path will be set to the lock file directory
880 * path. The path parameter is set to newly allocated memory. Caller is
881 * responsible for freeing memory.
883 * @param[in] cid Connection ID for which the lockfile path is constructed.
884 * @param[out] path Lockfile directory if cid is 0, path of lockfile otherwise.
885 * @return err_info, NULL on success.
887 sr_error_info_t *sr_path_conn_lockfile(sr_cid_t cid, char **path);
890 * @brief Remove any leftover event pipes after crashed subscriptions.
891 * There should be none unless there was a subscription structure without subscriptions that crashed.
893 void sr_remove_evpipes(void);
896 * @brief Get the UID of a user or vice versa.
898 * @param[in,out] uid UID.
899 * @param[in,out] user User name.
900 * @return err_info, NULL on success.
902 sr_error_info_t *sr_get_pwd(uid_t *uid, char **user);
905 * @brief Change mode (permissions) and/or owner and group of a file.
907 * @param[in] path File path.
908 * @param[in] owner New owner if not NULL.
909 * @param[in] group New group if not NULL.
910 * @param[in] perm New permissions if not 0.
911 * @return err_info, NULL on success.
913 sr_error_info_t *sr_chmodown(const char *path, const char *owner, const char *group, mode_t perm);
916 * @brief Check whether the effective user has permissions for a module.
918 * @param[in] mod_name Module to check.
919 * @param[in] wr Check write access if set, otherwise read.
920 * @param[in,out] has_access If set, it will contain the result of the access check.
921 * If not set, denied access returns an error.
922 * @return err_info, NULL on success.
924 sr_error_info_t *sr_perm_check(const char *mod_name, int wr, int *has_access);
927 * @brief Get mode (permissions) and/or owner and group of a module.
929 * @param[in] mod_name Module name.
930 * @param[in] ds Datastore file to check, for general module access permissions, startup should always be used.
931 * @param[in,out] owner Module owner if not NULL.
932 * @param[in,out] group Module group if not NULL.
933 * @param[in,out] perm Module permissions if not NULL;
934 * @return err_info, NULL on success.
936 sr_error_info_t *sr_perm_get(const char *mod_name, sr_datastore_t ds, char **owner, char **group, mode_t *perm);
939 * @brief Check whether a file exists.
941 * @param[in] path Path to the file.
942 * @return 0 if file does not exist, non-zero if it exists.
944 int sr_file_exists(const char *path);
947 * @brief Get current time with an offset.
949 * @param[out] ts Current time offset by \p add_ms.
950 * @param[in] add_ms Number os milliseconds added.
952 void sr_time_get(struct timespec *ts, uint32_t add_ms);
955 * @brief Remap and possibly resize a SHM. Needs WRITE lock for resizing,
956 * otherwise READ lock is fine.
958 * @param[in] shm SHM structure to remap.
959 * @param[in] new_shm_size Resize SHM to this size, if 0 read the size of the SHM file.
960 * @return err_info, NULL on success.
962 sr_error_info_t *sr_shm_remap(sr_shm_t *shm, size_t new_shm_size);
965 * @brief Clear a SHM structure.
967 * @param[in] shm SHM structure to clear.
969 void sr_shm_clear(sr_shm_t *shm);
972 * @brief Get the next ext SHM memory hole.
974 * @param[in] last Last returned hole, NULL on first call.
975 * @param[in] ext_shm Ext SHM.
976 * @return Next ext SHM memor hole, NULL if the last was returned.
978 sr_ext_hole_t *sr_ext_hole_next(sr_ext_hole_t *last, sr_ext_shm_t *ext_shm);
981 * @brief Find an existing hole.
983 * @param[in] ext_shm Ext SHM.
984 * @param[in] off Optional offset of the hole.
985 * @param[in] min_size Minimum matching hole size.
986 * @return First suitable hole, NULL if none found.
988 sr_ext_hole_t *sr_ext_hole_find(sr_ext_shm_t *ext_shm, uint32_t off, uint32_t min_size);
991 * @brief Delete an existing hole.
993 * @param[in] ext_shm Ext SHM.
994 * @param[in] hole Hole to delete.
996 void sr_ext_hole_del(sr_ext_shm_t *ext_shm, sr_ext_hole_t *hole);
999 * @brief Add a new hole.
1001 * @param[in] ext_shm Ext SHM.
1002 * @param[in] off Offset of the new hole.
1003 * @param[in] size Size of the new hole.
1004 * @return First suitable hole, NULL if none found.
1006 void sr_ext_hole_add(sr_ext_shm_t *ext_shm, uint32_t off, uint32_t size);
1009 * @brief Copy memory into SHM.
1011 * @param[in] shm_addr Mapped SHM address.
1012 * @param[in] src Source memory.
1013 * @param[in] size Size of source memory.
1014 * @param[in,out] shm_end Current SHM end pointer, it is updated.
1015 * @return Offset of the copied memory in SHM.
1017 off_t sr_shmcpy(char *shm_addr, const void *src, size_t size, char **shm_end);
1020 * @brief Copy string into SHM.
1022 * @param[in] shm_addr Mapped SHM address.
1023 * @param[in] str Source string.
1024 * @param[in,out] shm_end Current SHM end pointer, it is updated.
1025 * @return Offset of the copied memory in SHM.
1027 off_t sr_shmstrcpy(char *shm_addr, const char *str, char **shm_end);
1030 * @brief Get required memory in ext SHM for a string.
1032 * @param[in] str String to be examined.
1033 * @return Number of required bytes.
1035 size_t sr_strshmlen(const char *str);
1038 * @brief Realloc for an array in ext SHM adding one new item. The array offset and item count is properly
1039 * updated in the ext SHM.
1041 * May remap ext SHM!
1043 * @param[in] shm_ext Ext SHM structure.
1044 * @param[in,out] shm_array_off Pointer to array offset in SHM, is updated.
1045 * @param[in,out] shm_count Pointer to array count in SHM, is updated.
1046 * @param[in] in_ext_shm Whether @p shm_array_off and @p shm_count themselves are stored in ext SHM or not (in main SHM).
1047 * In case they are in ext SHM, they should not be used directly after this function as they may have been remapped!
1048 * @param[in] item_size Array item size.
1049 * @param[in] add_idx Index of the new item, -1 for adding at the end.
1050 * @param[out] new_item Pointer to the new item.
1051 * @param[in] dyn_attr_size Optional dynamic attribute size to allocate as well.
1052 * @param[out] dyn_attr_off Optional allocated dynamic attribute offset.
1053 * @return err_info, NULL on success.
1055 sr_error_info_t *sr_shmrealloc_add(sr_shm_t *shm_ext, off_t *shm_array_off, uint32_t *shm_count_off, int in_ext_shm,
1056 size_t item_size, int64_t add_idx, void **new_item, size_t dyn_attr_size, off_t *dyn_attr_off);
1059 * @brief Realloc for an array in SHM deleting one item.
1061 * @param[in] shm_ext Ext SHM structure.
1062 * @param[in,out] shm_array_off Pointer to array in SHM, set to 0 if last item was removed.
1063 * @param[in,out] shm_count Pointer to array count in SHM, will be updated.
1064 * @param[in] item_size Array item size.
1065 * @param[in] del_idx Item index to delete.
1066 * @param[in] dyn_attr_size Aligned size of dynamic attributes of the deleted item, if any.
1067 * @param[in] dyn_attr_off Offset of the dynamic attribute, if any.
1069 void sr_shmrealloc_del(sr_shm_t *shm_ext, off_t *shm_array_off, uint32_t *shm_count, size_t item_size, uint32_t del_idx,
1070 size_t dyn_attr_size, off_t dyn_attr_off);
1073 * @brief Wrapper for pthread_mutex_init().
1075 * @param[in,out] lock pthread mutex to initialize.
1076 * @param[in] shared Whether the mutex will be shared between processes or not.
1077 * @return err_info, NULL on success.
1079 sr_error_info_t *sr_mutex_init(pthread_mutex_t *lock, int shared);
1082 * @brief Callback called for each recovered owner of a lock.
1084 * @param[in] mode Dead owner lock mode.
1085 * @param[in] cid Dead owner connection ID.
1086 * @param[in] data Arbitrary user data.
1088 typedef void (*sr_lock_recover_cb)(sr_lock_mode_t mode, sr_cid_t cid, void *data);
1091 * @brief Lock a mutex.
1093 * @param[in] lock Mutex to lock.
1094 * @param[in] timeout_ms Timeout in ms for locking.
1095 * @param[in] finc Name of the calling function for logging.
1096 * @param[in] cb Optional callback called when recovering locks. When calling it, the lock is always held.
1097 * Callback @p mode is set to ::SR_LOCK_WRITE and @p cid to 0.
1098 * @param[in] cb_data Arbitrary user data for @p cb.
1099 * @return err_info, NULL on success.
1101 sr_error_info_t *sr_mlock(pthread_mutex_t *lock, int timeout_ms, const char *func, sr_lock_recover_cb cb, void *cb_data);
1104 * @brief Unlock a mutex.
1106 * @param[in] lock Mutex to unlock.
1108 void sr_munlock(pthread_mutex_t *lock);
1111 * @brief Initialize a sysrepo RW lock.
1113 * @param[in,out] rwlock RW lock to initialize.
1114 * @param[in] shared Whether the RW lock will be shared between processes or not.
1115 * @return err_info, NULL on success.
1117 sr_error_info_t *sr_rwlock_init(sr_rwlock_t *rwlock, int shared);
1120 * @brief Destroy a sysrepo RW lock.
1122 * @param[in] rwlock RW lock to destroy.
1124 void sr_rwlock_destroy(sr_rwlock_t *rwlock);
1127 * @brief Lock a sysrepo RW lock. On failure, the lock is not changed in any way.
1129 * @param[in] rwlock RW lock to lock.
1130 * @param[in] timeout_ms Timeout in ms for locking.
1131 * @param[in] mode Lock mode to set.
1132 * @param[in] cid Lock owner connection ID.
1133 * @param[in] func Name of the calling function for logging.
1134 * @param[in] cb Optional callback called when recovering locks. When calling it, WRITE lock is always held.
1135 * @param[in] cb_data Arbitrary user data for @p cb.
1136 * @return err_info, NULL on success.
1138 sr_error_info_t *sr_rwlock(sr_rwlock_t *rwlock, int timeout_ms, sr_lock_mode_t mode, sr_cid_t cid, const char *func,
1139 sr_lock_recover_cb cb, void *cb_data);
1142 * @brief Relock a sysrepo RW lock (upgrade or downgrade). On failure, the lock is not changed in any way.
1144 * If @p mode is ::SR_LOCK_WRITE, the @p rwlock must be locked with ::SR_LOCK_READ_UPGR.
1145 * If @p mode is ::SR_LOCK_READ or ::SR_LOCK_READ_UPGR, the @p rwlock must be locked with ::SR_LOCK_WRITE.
1147 * @param[in] rwlock RW lock to lock.
1148 * @param[in] timeout_ms Timeout in ms for locking. Only needed for lock upgrade (if @p mode is ::SR_LOCK_WRITE).
1149 * @param[in] mode Lock mode to set.
1150 * @param[in] cid Lock owner connection ID.
1151 * @param[in] func Name of the calling function for logging.
1152 * @param[in] cb Optional callback called when recovering locks. When calling it, WRITE lock is always held.
1153 * @param[in] cb_data Arbitrary user data for @p cb.
1154 * @return err_info, NULL on success.
1156 sr_error_info_t *sr_rwrelock(sr_rwlock_t *rwlock, int timeout_ms, sr_lock_mode_t mode, sr_cid_t cid, const char *func,
1157 sr_lock_recover_cb cb, void *cb_data);
1160 * @brief Unlock a sysrepo RW lock. On failure, whatever steps are possible are still performed.
1162 * @param[in] rwlock RW lock to unlock.
1163 * @param[in] timeout_ms Timeout in ms for locking. Only needed for read or read-upgr unlock.
1164 * @param[in] mode Lock mode that was successfully set for the lock.
1165 * @param[in] cid Lock owner connection ID.
1166 * @param[in] func Name of the calling function for logging.
1168 void sr_rwunlock(sr_rwlock_t *rwlock, int timeout_ms, sr_lock_mode_t mode, sr_cid_t cid, const char *func);
1171 * @brief Check whether a connection is alive.
1173 * @param[in] cid Connection CID.
1174 * @return 0 if it is dead, non-zero if it alive.
1176 int sr_conn_is_alive(sr_cid_t cid);
1179 * @brief Wrapper to realloc() that frees memory on failure.
1181 * @param[in] ptr Pointer to the current memory.
1182 * @param[in] size New size of the memory.
1183 * @return Resized memory, NULL on error.
1185 void *sr_realloc(void *ptr, size_t size);
1188 * @brief Copy file contents to another file.
1190 * @param[in] to Destination file path.
1191 * @param[in] from Source file path.
1192 * @param[in] file_mode Permissions of \p to file, if being created.
1193 * @return err_info, NULL on success.
1195 sr_error_info_t *sr_cp_path(const char *to, const char *from, mode_t file_mode);
1198 * @brief Wrapper for open(2).
1200 * Additionally sets umask.
1202 * @param[in] pathname Path of the file to open.
1203 * @param[in] flags Flags to use.
1204 * @param[in] mode Permissions for the file in case it is created.
1205 * @return Opened file descriptor.
1206 * @return -1 on error, errno set.
1208 int sr_open(const char *pathname, int flags, mode_t mode);
1211 * @brief Create all directories in the path, wrapper for mkdir(2).
1213 * Additionally sets umask.
1215 * @param[in] path Full path, is temporarily modified.
1216 * @param[in] mode Mode (permissions) of the directories.
1217 * @return err_info, NULL on success.
1219 sr_error_info_t *sr_mkpath(char *path, mode_t mode);
1222 * @brief Get first namespace (module name) from an XPath expression.
1224 * @param[in] expr Expression to inspect.
1225 * @return First module name, NULL on error.
1227 char *sr_get_first_ns(const char *expr);
1230 * @brief Get XPath expression without any predicates.
1232 * @param[in] expr Expression to transform.
1233 * @param[out] expr2 Expression without predicates.
1234 * @return err_info, NULL on success.
1236 sr_error_info_t *sr_get_trim_predicates(const char *expr, char **expr2);
1239 * @brief Get datastore string name.
1241 * @param[in] ds Datastore to transform.
1242 * @return Datastore string name.
1244 const char *sr_ds2str(sr_datastore_t ds);
1247 * @brief Get datastore identity name from ietf-datastores.
1249 * @param[in] ds Datastore to transform.
1250 * @return Datastore identity name.
1252 const char *sr_ds2ident(sr_datastore_t ds);
1255 * @brief Sleep for specified milliseconds.
1257 * @param[in] msec Number of ms to sleep for.
1258 * @return err_info, NULL on success.
1260 sr_error_info_t *sr_msleep(uint32_t msec);
1263 * @brief Print a message into a newly allocated buffer.
1265 * @param[in,out] str Buffer for the message.
1266 * @param[in,out] str_len Current buffer length.
1267 * @param[in] offset Print into buffer with an offset.
1268 * @param[in] format Format of the message.
1269 * @param[in] ap Format argument list.
1270 * @return Number of printed characters, -1 on error.
1272 int sr_vsprintf(char **str, int *str_len, int offset, const char *format, va_list ap);
1275 * @brief Print a message into a newly allocated buffer.
1277 * @param[in,out] str Buffer for the message.
1278 * @param[in,out] str_len Current buffer length.
1279 * @param[in] offset Print into buffer with an offset.
1280 * @param[in] format Format of the message.
1281 * @param[in] ... Format arguments.
1282 * @return Number of printed characters, -1 on error.
1284 int sr_sprintf(char **str, int *str_len, int offset, const char *format, ...);
1287 * @brief Get a file descriptor size.
1289 * @param[in] fd File descriptor to inspect.
1290 * @param[out] size Size of \p fd.
1291 * @return err_info, NULL on success.
1293 sr_error_info_t *sr_file_get_size(int fd, size_t *size);
1296 * @brief Get string value of a libyang leaf(-list).
1298 * @param[in] leaf Node to inspect.
1299 * @return String value of the node.
1301 const char *sr_ly_leaf_value_str(const struct lyd_node *leaf);
1304 * @brief Get event string name.
1306 * @param[in] ev Event to transform.
1307 * @return Event string name.
1309 const char *sr_ev2str(sr_sub_event_t ev);
1312 * @brief Transform internal event type into a public API event type.
1314 * @param[in] ev Internal event.
1315 * @return Public API event.
1317 sr_event_t sr_ev2api(sr_sub_event_t ev);
1320 * @brief Transform a libyang node into sysrepo value.
1322 * @param[in] node libyang node to transform.
1323 * @param[out] sr_val sysrepo value.
1324 * @return err_info, NULL on success.
1326 sr_error_info_t *sr_val_ly2sr(const struct lyd_node *node, sr_val_t *sr_val);
1329 * @brief Transform a sysrepo value into libyang string value.
1331 * @param[in] ctx libyang context.
1332 * @param[in] sr_val sysrepo value to transform.
1333 * @param[in] xpath XPath of the sysrepo value.
1334 * @param[in] buf Function buffer, must be of size at least 22 bytes.
1335 * @param[in] output Whether to look for output nodes instead of input.
1336 * @return String value.
1338 char *sr_val_sr2ly_str(struct ly_ctx *ctx, const sr_val_t *sr_val, const char *xpath, char *buf, int output);
1341 * @brief Transform a sysrepo value into libyang node.
1343 * @param[in] ctx libyang context.
1344 * @param[in] xpath XPath of the sysrepo value.
1345 * @param[in] val_str String value of the sysrepo value.
1346 * @param[in] dflt Dflt flag if the sysrepo value.
1347 * @param[in] output Whether the sysrepo value is from an output.
1348 * @param[in,out] root Transformed sysrepo value, appended if set.
1349 * @return err_info, NULL on success.
1351 sr_error_info_t *sr_val_sr2ly(struct ly_ctx *ctx, const char *xpath, const char *val_str, int dflt, int output,
1352 struct lyd_node **root);
1355 * @brief Split this sibling with following siblings and its preceding siblings.
1356 * Works only for top-level nodes!
1358 * @param[in] sibling Specific sibling where to split the siblings.
1360 void sr_ly_split(struct lyd_node *sibling);
1363 * @brief Link together split siblings. Works only for top-level nodes!
1365 * @param[in] first First sibling of the preceding siblings.
1366 * @param[in] sibling First sibling of the following siblings.
1368 void sr_ly_link(struct lyd_node *first, struct lyd_node *sibling);
1371 * @brief Duplicate nodes to the specified depth.
1373 * @param[in] src_parent Source parent.
1374 * @param[in] depth Depth to duplicate.
1375 * @param[in,out] trg_parent Target parent to add children to.
1376 * @return err_info, NULL on success.
1378 sr_error_info_t *sr_lyd_dup(const struct lyd_node *src_parent, uint32_t depth, struct lyd_node *trg_parent);
1381 * @brief Get pointer to data node children.
1383 * @param[in] node Node to get children of.
1384 * @param[in] skip_keys Whether to return first non-key child in case of lists.
1385 * @return Node children, NULL if has none.
1387 struct lyd_node *sr_lyd_child(const struct lyd_node *node, int skip_keys);
1390 * @brief Create any missing config/state NP containers in the siblings, recursively.
1392 * @param[in,out] first First sibling to add NP containers into, set if @p parent is NULL.
1393 * Only @p ly_mod data are considered.
1394 * @param[in] parent Parent of any added NP containers, set if @p first is NULL.
1395 * @param[in] ly_mod Module to consider, set if @p parent is NULL.
1396 * @param[in,out] diff Optional diff to append any performed changes to.
1397 * @return err_info, NULL on success.
1399 sr_error_info_t *sr_lyd_create_sibling_np_cont_r(struct lyd_node **first, struct lyd_node *parent,
1400 const struct lys_module *ly_mod, struct lyd_node **diff);
1403 * @brief Duplicate only config NP containers of a module from a data tree. Also optionally create state NP containers.
1405 * @param[in] data Data tree to duplicate from.
1406 * @param[in] ly_mod Module whose data to duplicate.
1407 * @param[in] add_state_np_conts Whether to also add state NP containers.
1408 * @param[in,out] new_data Data with appended duplicated nodes.
1409 * @return err_info, NULL on success.
1411 sr_error_info_t *sr_lyd_dup_module_np_cont(const struct lyd_node *data, const struct lys_module *ly_mod,
1412 int add_state_np_conts, struct lyd_node **new_data);
1415 * @brief Duplicate all data of a module from a data tree. Also properly handles config NP containers
1416 * and optionally even state NP containers.
1418 * @param[in] data Data tree to duplicate from.
1419 * @param[in] ly_mod Module whose data to duplicate.
1420 * @param[in] add_state_np_conts Whether to also add state NP containers.
1421 * @param[in,out] new_data Data with appended duplicated nodes.
1422 * @return err_info, NULL on success.
1424 sr_error_info_t *sr_lyd_dup_module_data(const struct lyd_node *data, const struct lys_module *ly_mod,
1425 int add_state_np_conts, struct lyd_node **new_data);
1428 * @brief Duplicate selected nodes from a data tree. Also properly handles config/state NP containers.
1429 * Works well even for XPaths with intersections.
1431 * @param[in] data Data tree to duplicate from.
1432 * @param[in] xpaths Array of XPaths that will select the duplicated nodes.
1433 * @param[in] xp_count XPath count.
1434 * @param[in,out] new_data Data with appended duplicated selected nodes.
1435 * @return err_info, NULL on success.
1437 sr_error_info_t *sr_lyd_dup_enabled_xpath(const struct lyd_node *data, char **xpaths, uint16_t xp_count,
1438 struct lyd_node **new_data);
1441 * @brief Remove all nodes selected by XPath.
1443 * @param[in,out] data Data to filter.
1444 * @param[in] xpath XPath selecting the nodes that will be freed.
1445 * @return err_info, NULL on success.
1447 sr_error_info_t *sr_lyd_xpath_complement(struct lyd_node **data, const char *xpath);
1450 * @brief Learn whether a node is user-ordered (leaf-)list.
1452 * @param[in] node (Leaf-)list instance.
1453 * @return 0 if not, non-zero if it is.
1455 int sr_ly_is_userord(const struct lyd_node *node);
1458 * @brief Learn whether 2 anydata/anyxml nodes are equal or not.
1460 * @param[in] any1 First anydata/anyxml node.
1461 * @param[in] any2 Second anydata/anyxml node.
1462 * @param[out] equal 1 if equal, 0 otherwise.
1463 * @return err_info, NULL on success.
1465 sr_error_info_t *sr_lyd_anydata_equal(const struct lyd_node *any1, const struct lyd_node *any2, int *equal);
1468 * @brief Free anydata/anyxml value.
1470 * @param[in] any Node with value to free.
1472 void sr_lyd_anydata_free(struct lyd_node *any);
1475 * @brief Copy anydata/anyxml value from src to trg.
1477 * @param[in] trg Target to copy to.
1478 * @param[in] src Source to copy from.
1479 * @return err_info, NULL on success.
1481 sr_error_info_t *sr_lyd_anydata_copy(struct lyd_node *trg, const struct lyd_node *src);
1484 * @brief Get string value of an anydata/anyxml node.
1486 * @param[in] any Anydata/anyxml to get the value from.
1487 * @param[out] value_str String value.
1488 * @return err_info, NULL on success.
1490 sr_error_info_t *sr_ly_anydata_value_str(const struct lyd_node *any, char **value_str);
1493 * @brief Get a hash of a string value.
1495 * @param[in] str String to hash.
1496 * @return String hash.
1498 uint32_t sr_str_hash(const char *str);
1501 * @brief Trim last node from an XPath.
1503 * @param[in] xpath Full XPath.
1504 * @param[out] trim_xpath XPath without the last node (and its predicates, if any).
1505 * @return err_info, NULL on success.
1507 sr_error_info_t *sr_xpath_trim_last_node(const char *xpath, char **trim_xpath);
1510 * @brief Get the first node (with predicates if any) from an XPath.
1512 * @param[in] xpath Full XPath.
1513 * @return First XPath node path.
1515 char *sr_xpath_first_node_with_predicates(const char *xpath);
1518 * @brief Get pointers to the next node name in an XPath.
1520 * @param[in] xpath Current position in the XPath (`/` expected at the beginning).
1521 * @param[out] mod Module name, if any.
1522 * @param[out] mod_len Moduel name length.
1523 * @param[out] name Node name.
1524 * @param[out] len Node name length,
1525 * @param[out] double_slash Whether the node starts with '//'.
1526 * @param[out] has_predicate Whether a predicate follows.
1527 * @return Pointer to the next XPath part (node name or predicate).
1529 const char *sr_xpath_next_name(const char *xpath, const char **mod, int *mod_len, const char **name, int *len,
1530 int *double_slash, int *has_predicate);
1533 * @brief Get pointers to the next predicate in an XPath.
1535 * @param[in] xpath Current position in the XPath (`[` expected at the beginning).
1536 * @param[out] pred Predicate content.
1537 * @param[out] len Predicate content length,
1538 * @param[out] has_predicate Whether another predicate follows.
1539 * @return Pointer to the next XPath part (node name or predicate).
1541 const char *sr_xpath_next_predicate(const char *xpath, const char **pred, int *len, int *has_predicate);
1544 * @brief Learn length of an XPath withtout any predicates.
1546 * @param[in] xpath Full XPath.
1547 * @return XPath length.
1549 size_t sr_xpath_len_no_predicates(const char *xpath);
1552 * @brief Find last (most nested) parent (node with possible children) in a data tree.
1554 * @param[in,out] parent Any subtree node, will be moved to the last parent.
1555 * @param[in] nodetype Whether to stop when a specific node type is found or not.
1556 * @return err_info, NULL on success.
1558 sr_error_info_t *sr_ly_find_last_parent(struct lyd_node **parent, int nodetype);
1561 * @brief Unlink data of a specific module from a data tree.
1563 * @param[in,out] data Data tree.
1564 * @param[in] ly_mod libyang module of interest.
1565 * @return Unlinked data tree.
1567 struct lyd_node *sr_module_data_unlink(struct lyd_node **data, const struct lys_module *ly_mod);
1570 * @brief Append data loaded from a file/SHM for a specific module. Do not use for operational datastore.
1572 * @param[in] ly_mod Module to process.
1573 * @param[in] ds Datastore.
1574 * @param[in,out] data Data tree to append to.
1575 * @return err_info, NULL on success.
1577 sr_error_info_t *sr_module_file_data_append(const struct lys_module *ly_mod, sr_datastore_t ds, struct lyd_node **data);
1580 * @brief Load operational data (diff) loaded from a SHM for a specific module.
1582 * @param[in] mod Mod info mod.
1583 * @param[out] diff Loaded diff to return.
1584 * @return err_info, NULL on success.
1586 sr_error_info_t *sr_module_file_oper_data_load(struct sr_mod_info_mod_s *mod, struct lyd_node **diff);
1589 * @brief Set (replace) data in file/SHM for a specific module.
1591 * @param[in] mod_name Module name.
1592 * @param[in] ds Target datastore
1593 * @param[in] mod_data Module data.
1594 * @param[in] create_flags Additional flags that will be used for opening the file,
1595 * any of O_CREATE and O_EXCL are expected.
1596 * @param[in] file_mode Permissions (mode) of the file, must always be correctly set because of the backup.
1597 * @return err_info, NULL on success.
1599 sr_error_info_t *sr_module_file_data_set(const char *mod_name, sr_datastore_t ds, struct lyd_node *mod_data,
1600 int create_flags, mode_t file_mode);
1603 * @brief Update sysrepo stored operational diff of a module.
1605 * @param[in] conn Connection to use.
1606 * @param[in] mod_name Module name.
1607 * @return err_info, NULL on success.
1609 sr_error_info_t *sr_module_update_oper_diff(sr_conn_ctx_t *conn, const char *mod_name);
1612 * @brief Get next feature of a module.
1614 * @param[in] last Last returned feature, NULL on first call,
1615 * @param[in] ly_mod Module with the features.
1616 * @param[in,out] idx Internal index fo the feature, arbitrary value can be passed but must not be changed in between calls.
1617 * @return Next found feature, NULL if last was previously returned.
1619 struct lys_feature *sr_lys_next_feature(struct lys_feature *last, const struct lys_module *ly_mod, uint32_t *idx);
1622 * @brief Learn CIDs and PIDs of all the live connections.
1624 * @param[out] cids Optional array of CIDs.
1625 * @param[out] pids Optional array of PIDs.
1626 * @param[out] count Connection count, length of both @p cids and @p pids.
1627 * @param[out] dead_cids Optional array of dead CIDs.
1628 * @param[out] dead_count Length of @p dead_cids.
1629 * @return err_info, NULL on success.
1631 sr_error_info_t *sr_conn_info(sr_cid_t **cids, pid_t **pids, uint32_t *count, sr_cid_t **dead_cids, uint32_t *dead_count);
1634 * @brief Transform given time_t (seconds since the epoch) into the RFC 3339 format (YANG date-and-time).
1636 * @param[in] time Time to convert.
1637 * @param[in] tz Timezone name for the result. See tzselect(1) for list of
1638 * correct values. If not specified (NULL) or unknown/invalid, the result is provided in UTC (Zulu).
1639 * @param[in,out] buf Buffer to print the datetime into, must be at least 26 characters long. If not set, @p buf2 is used.
1640 * @param[in,out] buf2 Pointer to a buffer to allocate for the datetime.
1641 * @return err_info, NULL on success.
1643 sr_error_info_t *sr_time2datetime(time_t time, const char *tz, char *buf, char **buf2);