Add supoprt for D release use-case.
[sim/o1-interface.git] / ntsimulator / deploy / base / common.h.in
1 /**
2  * @file common.h
3  * @author Michal Vasko <mvasko@cesnet.cz>
4  * @brief common routines header
5  *
6  * @copyright
7  * Copyright 2018 Deutsche Telekom AG.
8  * Copyright 2018 - 2021 CESNET, z.s.p.o.
9  *
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
13  *
14  *    http://www.apache.org/licenses/LICENSE-2.0
15  *
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.
21  */
22
23 #ifndef _COMMON_H
24 #define _COMMON_H
25
26 #define _GNU_SOURCE
27 #define _POSIX_C_SOURCE 200809L
28
29 #include <errno.h>
30 #include <pthread.h>
31 #include <stdarg.h>
32 #include <stdint.h>
33 #include <string.h>
34 #include <time.h>
35
36 #include <libyang/libyang.h>
37
38 #include "compat.h"
39 #include "sysrepo.h"
40
41 /*
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
44  * the public API.
45  */
46 #define API __attribute__((visibility("default")))
47
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);
52 #endif
53
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
58 #endif
59
60 /** atomic variables */
61 #cmakedefine SR_HAVE_STDATOMIC
62 #ifdef SR_HAVE_STDATOMIC
63 # include <stdatomic.h>
64
65 # define ATOMIC_T atomic_uint_fast32_t
66 # define ATOMIC_T_MAX UINT_FAST32_MAX
67
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)
74 #else
75 # define ATOMIC_T uint32_t
76 # define ATOMIC_T_MAX UINT32_MAX
77
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)
84 #endif
85
86 /** macro for mutex align check */
87 #define SR_MUTEX_ALIGN_CHECK(mutex) ((uintptr_t)mutex % sizeof(void *))
88
89 /** macro for cond align check */
90 #define SR_COND_ALIGN_CHECK(cond) ((uintptr_t)cond % sizeof(void *))
91
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))
94
95 /** macro for all datastore types count */
96 #define SR_DS_COUNT 4
97
98 /** macro for checking session type */
99 #define SR_IS_EVENT_SESS(session) (session->ev != SR_SUB_EV_NONE)
100
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)))
103
104 /* macro for getting aligned SHM size */
105 #define SR_SHM_SIZE(size) ((size) + ((~(size) + 1) & (SR_SHM_MEM_ALIGN - 1)))
106
107 /* macro for getting main SHM from a connection */
108 #define SR_CONN_MAIN_SHM(conn) ((sr_main_shm_t *)(conn)->main_shm.addr)
109
110 /* macro for getting ext SHM from a connection */
111 #define SR_CONN_EXT_SHM(conn) ((sr_ext_shm_t *)(conn)->ext_shm.addr)
112
113 /** name of sysrepo YANG module */
114 #define SR_YANG_MOD "sysrepo"
115
116 /** UID of the superuser that can execute sensitive functions */
117 #define SR_SU_UID @SYSREPO_SUPERUSER_UID@
118
119 /** implemented ietf-yang-library revision */
120 #define SR_YANGLIB_REVISION @YANGLIB_REVISION@
121
122 /** main sysrepo repository path; prefix of all other paths by default */
123 #define SR_REPO_PATH "@REPO_PATH@"
124
125 /** environment variable overriding the compiled-in value */
126 #define SR_REPO_PATH_ENV "SYSREPO_REPOSITORY_PATH"
127
128 /** if not set, defaults to "SR_REPO_PATH/data" */
129 #define SR_STARTUP_PATH "@STARTUP_DATA_PATH@"
130
131 /** if not set, defaults to "SR_REPO_PATH/data/notif" */
132 #define SR_NOTIFICATION_PATH "@NOTIFICATION_PATH@"
133
134 /** if not set, defaults to "SR_REPO_PATH/yang" */
135 #define SR_YANG_PATH "@YANG_MODULE_PATH@"
136
137 /** where SHM files are stored */
138 #define SR_SHM_DIR "/dev/shm"
139
140 /** default prefix for SHM files in /dev/shm */
141 #define SR_SHM_PREFIX_DEFAULT "sr"
142
143 /** suffix of backed-up LYB files */
144 #define SR_FILE_BACKUP_SUFFIX ".bck"
145
146 /** environment variable for setting a custom prefix for SHM files */
147 #define SR_SHM_PREFIX_ENV "SYSREPO_SHM_PREFIX"
148
149 /** maximum number of possible system-wide concurrent owners of a read lock */
150 #define SR_RWLOCK_READ_LIMIT 10
151
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
154
155 /** notification file will never exceed this size (kB) */
156 #define SR_EV_NOTIF_FILE_MAX_SIZE 1024
157
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
160
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
163
164 /** timeout for locking notification buffer lock, used when adding/removing notifications (ms) */
165 #define SR_NOTIF_BUF_LOCK_TIMEOUT 100
166
167 /** timeout for locking subscription SHM; maximum time an event handling should take (ms) */
168 #define SR_SUBSHM_LOCK_TIMEOUT 10000
169
170 /** timeout for locking ext SHM lock; time that truncating and writing into SHM may take (ms) */
171 #define SR_EXT_LOCK_TIMEOUT 100
172
173 /** timeout for locking the local connection list; maximum time the list can be accessed (ms) */
174 #define SR_CONN_LIST_LOCK_TIMEOUT 100
175
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
178
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
181
182 /** timeout for locking SHM module/RPC subscriptions; maxmum time full event processing may take (ms) */
183 #define SR_SHMEXT_SUB_LOCK_TIMEOUT 15000
184
185 /** timeout for locking module cache (ms) */
186 #define SR_MOD_CACHE_LOCK_TIMEOUT 10000
187
188 /** default timeout for change subscription callback (ms) */
189 #define SR_CHANGE_CB_TIMEOUT 60000
190
191 /** default timeout for operational subscription callback (ms) */
192 #define SR_OPER_CB_TIMEOUT 60000
193
194 /** default timeout for RPC/action subscription callback (ms) */
195 #define SR_RPC_CB_TIMEOUT 60000
196
197 /** group to own all directories/files */
198 #define SR_GROUP "@SYSREPO_GROUP@"
199
200 /** umask modifying all the permissions below */
201 #define SR_UMASK @SYSREPO_UMASK@
202
203 /** permissions of main SHM lock file and main SHM itself */
204 #define SR_MAIN_SHM_PERM 00666
205
206 /** permissions of connection lock files */
207 #define SR_CONN_LOCKFILE_PERM 00666
208
209 /** permissions of all subscription SHMs */
210 #define SR_SUB_SHM_PERM 00666
211
212 /** permissions of all event pipes (only owner read, anyone else write */
213 #define SR_EVPIPE_PERM 00622
214
215 /** permissions of directories for sysrepo files */
216 #define SR_DIR_PERM 00777
217
218 /** permissions of used YANG modules */
219 #define SR_YANG_PERM 00644
220
221 /** permissions of stored notifications and data files */
222 #define SR_FILE_PERM 00600
223
224 /** permissions of data files of internal modules */
225 #define SR_INT_FILE_PERM 00664
226
227 /** permission of data files of sysrepo-monitoring internal module */
228 #define SR_MON_INT_FILE_PERM 00600
229
230 /** initial length of message buffer (B) */
231 #define SR_MSG_LEN_START 128
232
233 /** default operational origin for operational data (push/pull) */
234 #define SR_OPER_ORIGIN "unknown"
235
236 /** default operational origin for enabled running data */
237 #define SR_CONFIG_ORIGIN "intended"
238
239 /*
240  * Internal declarations + definitions
241  */
242
243 extern char sysrepo_yang[];
244
245 typedef struct sr_mod_s sr_mod_t;
246
247 typedef struct sr_dep_s sr_dep_t;
248
249 /** static initializer of the shared memory structure */
250 #define SR_SHM_INITIALIZER {.fd = -1, .size = 0, .addr = NULL}
251
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
255
256 /**
257  * @brief Generic shared memory information structure.
258  */
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. */
263 } sr_shm_t;
264
265 /**
266  * @brief Session information structure.
267  */
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. */
272 } sr_sid_t;
273
274 /**
275  * @brief Connection ID.
276  */
277 typedef uint32_t sr_cid_t;
278
279 /**
280  * @brief Lock mode.
281  */
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. */
287 } sr_lock_mode_t;
288
289 /**
290  * @brief Sysrepo read-write lock.
291  */
292 typedef struct sr_rwlock_s {
293     pthread_mutex_t mutex;          /**< Lock mutex. */
294     pthread_cond_t cond;            /**< Lock condition variable. */
295
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. */
300 } sr_rwlock_t;
301
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;
307 struct opsub_rpc_s;
308 struct modsub_notif_s;
309
310 #include "edit_diff.h"
311 #include "log.h"
312 #include "modinfo.h"
313 #include "shm.h"
314 #include "lyd_mods.h"
315 #include "replay.h"
316
317 /*
318  * Private definitions of public declarations
319  */
320
321 /**
322  * @brief Sysrepo connection.
323  */
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. */
328
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 */
333
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). */
338
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, */
342
343         struct {
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. */
349 };
350
351 /**
352  * @brief Sysrepo session.
353  */
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. */
361
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. */
365
366     struct {
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. */
370
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. */
384 };
385
386 /**
387  * @brief Sysrepo subscription.
388  */
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. */
396
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. */
407
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. */
412
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. */
416
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. */
424
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. */
431
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. */
446
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. */
451
452     struct opsub_rpc_s {
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. */
461
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. */
466
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. */
470 };
471
472 /**
473  * @brief Change iterator.
474  */
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. */
479 };
480
481 /*
482  * From sysrepo.c
483  */
484
485 /**
486  * @brief Start a new session.
487  *
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.
496  */
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);
499
500 /*
501  * Subscription functions
502  */
503
504 /**
505  * @brief Add a change subscription into a subscription structure.
506  *
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.
517  */
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);
521
522 /**
523  * @brief Delete a change subscription from a subscription structure.
524  *
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.
534  */
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);
538
539 /**
540  * @brief Add an operational subscription into a subscription structure.
541  *
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.
550  */
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);
553
554 /**
555  * @brief Delete an operational subscription from a subscription structure.
556  *
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.
561  */
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);
563
564 /**
565  * @brief Add a notification subscription into a subscription structure.
566  *
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.
579  */
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);
583
584 /**
585  * @brief Delete a notification subscription from a subscription structure.
586  *
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.
591  */
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);
593
594 /**
595  * @brief Add an RPC subscription into a subscription structure.
596  *
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.
607  */
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);
611
612 /**
613  * @brief Delete an RPC subscription from a subscription structure.
614  *
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.
623  */
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);
626
627 /**
628  * @brief Count subscriptions of session \p sess in subscriptions structure \p subs.
629  *
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.
634  */
635 int sr_subs_session_count(sr_session_ctx_t *sess, sr_lock_mode_t has_subs_lock, sr_subscription_ctx_t *subs);
636
637 /**
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!
640  *
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.
645  */
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);
647
648 /**
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!
651  *
652  * @param[in,out] subs Subscription structure.
653  * @return err_info, NULL on success.
654  */
655 sr_error_info_t *sr_subs_del_all(sr_subscription_ctx_t *subs);
656
657 /**
658  * @brief Find notifications subscribers for a module.
659  *
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.
665  */
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);
668
669 /**
670  * @brief Call notification callback for a notification.
671  *
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.
680  */
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);
683
684 /*
685  * Utility functions
686  */
687
688 /**
689  * @brief Add a generic pointer to a ptr array.
690  *
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.
696  */
697 sr_error_info_t *sr_ptr_add(pthread_mutex_t *ptr_lock, void ***ptrs, uint32_t *ptr_count, void *add_ptr);
698
699 /**
700  * @brief Delete a generic pointer from a ptr array.
701  *
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.
706  */
707 sr_error_info_t *sr_ptr_del(pthread_mutex_t *ptr_lock, void ***ptrs, uint32_t *ptr_count, void *del_ptr);
708
709 /**
710  * @brief Wrapper for libyang ly_ctx_new().
711  *
712  * @param[out] ly_ctx libyang context.
713  * @return err_info, NULL on success.
714  */
715 sr_error_info_t *sr_ly_ctx_new(struct ly_ctx **ly_ctx);
716
717 /**
718  * @brief Remove module YANG file.
719  *
720  * @param[in] name Module name.
721  * @param[in] revision Module revision, NULL if none.
722  * @return err_info, NULL on success.
723  */
724 sr_error_info_t *sr_remove_module_file(const char *name, const char *revision);
725
726 /**
727  * @brief Create (print) YANG module file and all of its submodules.
728  *
729  * @param[in] ly_mod Module to print.
730  * @return err_info, NULL on success.
731  */
732 sr_error_info_t *sr_store_module_files(const struct lys_module *ly_mod);
733
734 /**
735  * @brief Unlink startup, running, and candidate files of a module.
736  *
737  * @param[in] mod_name Module name.
738  * @return err_info, NULL on success.
739  */
740 sr_error_info_t *sr_remove_data_files(const char *mod_name);
741
742 /**
743  * @brief Check whether a module is internal libyang or sysrepo module.
744  *
745  * @param[in] ly_mod Module to check.
746  * @return 0 if not, non-zero if it is.
747  */
748 int sr_module_is_internal(const struct lys_module *ly_mod);
749
750 /**
751  * @brief Create startup file for a module.
752  *
753  * @param[in] ly_mod Module to create startup file for.
754  * @return err_info, NULL on success.
755  */
756 sr_error_info_t *sr_create_startup_file(const struct lys_module *ly_mod);
757
758 /**
759  * @brief Create all module import and include files, recursively.
760  *
761  * @param[in] ly_mod libyang module whose imports and includes to create.
762  * @return err_info, NULL on success.
763  */
764 sr_error_info_t *sr_create_module_imps_incs_r(const struct lys_module *ly_mod);
765
766 /**
767  * @brief Get the path the main SHM.
768  *
769  * @param[out] path Created path. Should be freed by the caller.
770  * @return err_info, NULL on success.
771  */
772 sr_error_info_t *sr_path_main_shm(char **path);
773
774 /**
775  * @brief Get the path the external SHM.
776  *
777  * @param[out] path Created path. Should be freed by the caller.
778  * @return err_info, NULL on success.
779  */
780 sr_error_info_t *sr_path_ext_shm(char **path);
781
782 /**
783  * @brief Get the path to a subscription SHM.
784  *
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.
790  */
791 sr_error_info_t *sr_path_sub_shm(const char *mod_name, const char *suffix1, int64_t suffix2, char **path);
792
793 /**
794  * @brief Get the path to a subscription data SHM.
795  *
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.
801  */
802 sr_error_info_t *sr_path_sub_data_shm(const char *mod_name, const char *suffix1, int64_t suffix2, char **path);
803
804 /**
805  * @brief Get the path to a volatile datastore SHM.
806  *
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.
811  */
812 sr_error_info_t *sr_path_ds_shm(const char *mod_name, sr_datastore_t ds, char **path);
813
814 /**
815  * @brief Get the path to an event pipe.
816  *
817  * @param[in] evpipe_num Event pipe number.
818  * @param[out] path Created path.
819  * @return err_info, NULL on success.
820  */
821 sr_error_info_t *sr_path_evpipe(uint32_t evpipe_num, char **path);
822
823 /**
824  * @brief Get the path to startup files directory.
825  *
826  * @param[out] path Created path.
827  * @return err_info, NULL on success.
828  */
829 sr_error_info_t *sr_path_startup_dir(char **path);
830
831 /**
832  * @brief Get the path to notification files directory.
833  *
834  * @param[out] path Created path.
835  * @return err_info, NULL on success.
836  */
837 sr_error_info_t *sr_path_notif_dir(char **path);
838
839 /**
840  * @brief Get the path to YANG module files directory.
841  *
842  * @param[out] path Created path.
843  * @return err_info, NULL on success.
844  */
845 sr_error_info_t *sr_path_yang_dir(char **path);
846
847 /**
848  * @brief Get the path to a module startup file.
849  *
850  * @param[in] mod_name Module name.
851  * @param[out] path Created path.
852  * @return err_info, NULL on success.
853  */
854 sr_error_info_t *sr_path_startup_file(const char *mod_name, char **path);
855
856 /**
857  * @brief Get the path to a module notification file.
858  *
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.
864  */
865 sr_error_info_t *sr_path_notif_file(const char *mod_name, time_t from_ts, time_t to_ts, char **path);
866
867 /**
868  * @brief Get the path to a YANG module file.
869  *
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.
874  */
875 sr_error_info_t *sr_path_yang_file(const char *mod_name, const char *mod_rev, char **path);
876
877 /**
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.
882  *
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.
886  */
887 sr_error_info_t *sr_path_conn_lockfile(sr_cid_t cid, char **path);
888
889 /**
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.
892  */
893 void sr_remove_evpipes(void);
894
895 /**
896  * @brief Get the UID of a user or vice versa.
897  *
898  * @param[in,out] uid UID.
899  * @param[in,out] user User name.
900  * @return err_info, NULL on success.
901  */
902 sr_error_info_t *sr_get_pwd(uid_t *uid, char **user);
903
904 /**
905  * @brief Change mode (permissions) and/or owner and group of a file.
906  *
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.
912  */
913 sr_error_info_t *sr_chmodown(const char *path, const char *owner, const char *group, mode_t perm);
914
915 /**
916  * @brief Check whether the effective user has permissions for a module.
917  *
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.
923  */
924 sr_error_info_t *sr_perm_check(const char *mod_name, int wr, int *has_access);
925
926 /**
927  * @brief Get mode (permissions) and/or owner and group of a module.
928  *
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.
935  */
936 sr_error_info_t *sr_perm_get(const char *mod_name, sr_datastore_t ds, char **owner, char **group, mode_t *perm);
937
938 /**
939  * @brief Check whether a file exists.
940  *
941  * @param[in] path Path to the file.
942  * @return 0 if file does not exist, non-zero if it exists.
943  */
944 int sr_file_exists(const char *path);
945
946 /**
947  * @brief Get current time with an offset.
948  *
949  * @param[out] ts Current time offset by \p add_ms.
950  * @param[in] add_ms Number os milliseconds added.
951  */
952 void sr_time_get(struct timespec *ts, uint32_t add_ms);
953
954 /**
955  * @brief Remap and possibly resize a SHM. Needs WRITE lock for resizing,
956  * otherwise READ lock is fine.
957  *
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.
961  */
962 sr_error_info_t *sr_shm_remap(sr_shm_t *shm, size_t new_shm_size);
963
964 /**
965  * @brief Clear a SHM structure.
966  *
967  * @param[in] shm SHM structure to clear.
968  */
969 void sr_shm_clear(sr_shm_t *shm);
970
971 /**
972  * @brief Get the next ext SHM memory hole.
973  *
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.
977  */
978 sr_ext_hole_t *sr_ext_hole_next(sr_ext_hole_t *last, sr_ext_shm_t *ext_shm);
979
980 /**
981  * @brief Find an existing hole.
982  *
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.
987  */
988 sr_ext_hole_t *sr_ext_hole_find(sr_ext_shm_t *ext_shm, uint32_t off, uint32_t min_size);
989
990 /**
991  * @brief Delete an existing hole.
992  *
993  * @param[in] ext_shm Ext SHM.
994  * @param[in] hole Hole to delete.
995  */
996 void sr_ext_hole_del(sr_ext_shm_t *ext_shm, sr_ext_hole_t *hole);
997
998 /**
999  * @brief Add a new hole.
1000  *
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.
1005  */
1006 void sr_ext_hole_add(sr_ext_shm_t *ext_shm, uint32_t off, uint32_t size);
1007
1008 /**
1009  * @brief Copy memory into SHM.
1010  *
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.
1016  */
1017 off_t sr_shmcpy(char *shm_addr, const void *src, size_t size, char **shm_end);
1018
1019 /**
1020  * @brief Copy string into SHM.
1021  *
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.
1026  */
1027 off_t sr_shmstrcpy(char *shm_addr, const char *str, char **shm_end);
1028
1029 /**
1030  * @brief Get required memory in ext SHM for a string.
1031  *
1032  * @param[in] str String to be examined.
1033  * @return Number of required bytes.
1034  */
1035 size_t sr_strshmlen(const char *str);
1036
1037 /**
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.
1040  *
1041  * May remap ext SHM!
1042  *
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.
1054  */
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);
1057
1058 /**
1059  * @brief Realloc for an array in SHM deleting one item.
1060  *
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.
1068  */
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);
1071
1072 /**
1073  * @brief Wrapper for pthread_mutex_init().
1074  *
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.
1078  */
1079 sr_error_info_t *sr_mutex_init(pthread_mutex_t *lock, int shared);
1080
1081 /**
1082  * @brief Callback called for each recovered owner of a lock.
1083  *
1084  * @param[in] mode Dead owner lock mode.
1085  * @param[in] cid Dead owner connection ID.
1086  * @param[in] data Arbitrary user data.
1087  */
1088 typedef void (*sr_lock_recover_cb)(sr_lock_mode_t mode, sr_cid_t cid, void *data);
1089
1090 /**
1091  * @brief Lock a mutex.
1092  *
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.
1100  */
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);
1102
1103 /**
1104  * @brief Unlock a mutex.
1105  *
1106  * @param[in] lock Mutex to unlock.
1107  */
1108 void sr_munlock(pthread_mutex_t *lock);
1109
1110 /**
1111  * @brief Initialize a sysrepo RW lock.
1112  *
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.
1116  */
1117 sr_error_info_t *sr_rwlock_init(sr_rwlock_t *rwlock, int shared);
1118
1119 /**
1120  * @brief Destroy a sysrepo RW lock.
1121  *
1122  * @param[in] rwlock RW lock to destroy.
1123  */
1124 void sr_rwlock_destroy(sr_rwlock_t *rwlock);
1125
1126 /**
1127  * @brief Lock a sysrepo RW lock. On failure, the lock is not changed in any way.
1128  *
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.
1137  */
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);
1140
1141 /**
1142  * @brief Relock a sysrepo RW lock (upgrade or downgrade). On failure, the lock is not changed in any way.
1143  *
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.
1146  *
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.
1155  */
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);
1158
1159 /**
1160  * @brief Unlock a sysrepo RW lock. On failure, whatever steps are possible are still performed.
1161  *
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.
1167  */
1168 void sr_rwunlock(sr_rwlock_t *rwlock, int timeout_ms, sr_lock_mode_t mode, sr_cid_t cid, const char *func);
1169
1170 /**
1171  * @brief Check whether a connection is alive.
1172  *
1173  * @param[in] cid Connection CID.
1174  * @return 0 if it is dead, non-zero if it alive.
1175  */
1176 int sr_conn_is_alive(sr_cid_t cid);
1177
1178 /**
1179  * @brief Wrapper to realloc() that frees memory on failure.
1180  *
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.
1184  */
1185 void *sr_realloc(void *ptr, size_t size);
1186
1187 /**
1188  * @brief Copy file contents to another file.
1189  *
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.
1194  */
1195 sr_error_info_t *sr_cp_path(const char *to, const char *from, mode_t file_mode);
1196
1197 /**
1198  * @brief Wrapper for open(2).
1199  *
1200  * Additionally sets umask.
1201  *
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.
1207  */
1208 int sr_open(const char *pathname, int flags, mode_t mode);
1209
1210 /**
1211  * @brief Create all directories in the path, wrapper for mkdir(2).
1212  *
1213  * Additionally sets umask.
1214  *
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.
1218  */
1219 sr_error_info_t *sr_mkpath(char *path, mode_t mode);
1220
1221 /**
1222  * @brief Get first namespace (module name) from an XPath expression.
1223  *
1224  * @param[in] expr Expression to inspect.
1225  * @return First module name, NULL on error.
1226  */
1227 char *sr_get_first_ns(const char *expr);
1228
1229 /**
1230  * @brief Get XPath expression without any predicates.
1231  *
1232  * @param[in] expr Expression to transform.
1233  * @param[out] expr2 Expression without predicates.
1234  * @return err_info, NULL on success.
1235  */
1236 sr_error_info_t *sr_get_trim_predicates(const char *expr, char **expr2);
1237
1238 /**
1239  * @brief Get datastore string name.
1240  *
1241  * @param[in] ds Datastore to transform.
1242  * @return Datastore string name.
1243  */
1244 const char *sr_ds2str(sr_datastore_t ds);
1245
1246 /**
1247  * @brief Get datastore identity name from ietf-datastores.
1248  *
1249  * @param[in] ds Datastore to transform.
1250  * @return Datastore identity name.
1251  */
1252 const char *sr_ds2ident(sr_datastore_t ds);
1253
1254 /**
1255  * @brief Sleep for specified milliseconds.
1256  *
1257  * @param[in] msec Number of ms to sleep for.
1258  * @return err_info, NULL on success.
1259  */
1260 sr_error_info_t *sr_msleep(uint32_t msec);
1261
1262 /**
1263  * @brief Print a message into a newly allocated buffer.
1264  *
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.
1271  */
1272 int sr_vsprintf(char **str, int *str_len, int offset, const char *format, va_list ap);
1273
1274 /**
1275  * @brief Print a message into a newly allocated buffer.
1276  *
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.
1283  */
1284 int sr_sprintf(char **str, int *str_len, int offset, const char *format, ...);
1285
1286 /**
1287  * @brief Get a file descriptor size.
1288  *
1289  * @param[in] fd File descriptor to inspect.
1290  * @param[out] size Size of \p fd.
1291  * @return err_info, NULL on success.
1292  */
1293 sr_error_info_t *sr_file_get_size(int fd, size_t *size);
1294
1295 /**
1296  * @brief Get string value of a libyang leaf(-list).
1297  *
1298  * @param[in] leaf Node to inspect.
1299  * @return String value of the node.
1300  */
1301 const char *sr_ly_leaf_value_str(const struct lyd_node *leaf);
1302
1303 /**
1304  * @brief Get event string name.
1305  *
1306  * @param[in] ev Event to transform.
1307  * @return Event string name.
1308  */
1309 const char *sr_ev2str(sr_sub_event_t ev);
1310
1311 /**
1312  * @brief Transform internal event type into a public API event type.
1313  *
1314  * @param[in] ev Internal event.
1315  * @return Public API event.
1316  */
1317 sr_event_t sr_ev2api(sr_sub_event_t ev);
1318
1319 /**
1320  * @brief Transform a libyang node into sysrepo value.
1321  *
1322  * @param[in] node libyang node to transform.
1323  * @param[out] sr_val sysrepo value.
1324  * @return err_info, NULL on success.
1325  */
1326 sr_error_info_t *sr_val_ly2sr(const struct lyd_node *node, sr_val_t *sr_val);
1327
1328 /**
1329  * @brief Transform a sysrepo value into libyang string value.
1330  *
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.
1337  */
1338 char *sr_val_sr2ly_str(struct ly_ctx *ctx, const sr_val_t *sr_val, const char *xpath, char *buf, int output);
1339
1340 /**
1341  * @brief Transform a sysrepo value into libyang node.
1342  *
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.
1350  */
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);
1353
1354 /**
1355  * @brief Split this sibling with following siblings and its preceding siblings.
1356  * Works only for top-level nodes!
1357  *
1358  * @param[in] sibling Specific sibling where to split the siblings.
1359  */
1360 void sr_ly_split(struct lyd_node *sibling);
1361
1362 /**
1363  * @brief Link together split siblings. Works only for top-level nodes!
1364  *
1365  * @param[in] first First sibling of the preceding siblings.
1366  * @param[in] sibling First sibling of the following siblings.
1367  */
1368 void sr_ly_link(struct lyd_node *first, struct lyd_node *sibling);
1369
1370 /**
1371  * @brief Duplicate nodes to the specified depth.
1372  *
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.
1377  */
1378 sr_error_info_t *sr_lyd_dup(const struct lyd_node *src_parent, uint32_t depth, struct lyd_node *trg_parent);
1379
1380 /**
1381  * @brief Get pointer to data node children.
1382  *
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.
1386  */
1387 struct lyd_node *sr_lyd_child(const struct lyd_node *node, int skip_keys);
1388
1389 /**
1390  * @brief Create any missing config/state NP containers in the siblings, recursively.
1391  *
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.
1398  */
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);
1401
1402 /**
1403  * @brief Duplicate only config NP containers of a module from a data tree. Also optionally create state NP containers.
1404  *
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.
1410  */
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);
1413
1414 /**
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.
1417  *
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.
1423  */
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);
1426
1427 /**
1428  * @brief Duplicate selected nodes from a data tree. Also properly handles config/state NP containers.
1429  * Works well even for XPaths with intersections.
1430  *
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.
1436  */
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);
1439
1440 /**
1441  * @brief Remove all nodes selected by XPath.
1442  *
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.
1446  */
1447 sr_error_info_t *sr_lyd_xpath_complement(struct lyd_node **data, const char *xpath);
1448
1449 /**
1450  * @brief Learn whether a node is user-ordered (leaf-)list.
1451  *
1452  * @param[in] node (Leaf-)list instance.
1453  * @return 0 if not, non-zero if it is.
1454  */
1455 int sr_ly_is_userord(const struct lyd_node *node);
1456
1457 /**
1458  * @brief Learn whether 2 anydata/anyxml nodes are equal or not.
1459  *
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.
1464  */
1465 sr_error_info_t *sr_lyd_anydata_equal(const struct lyd_node *any1, const struct lyd_node *any2, int *equal);
1466
1467 /**
1468  * @brief Free anydata/anyxml value.
1469  *
1470  * @param[in] any Node with value to free.
1471  */
1472 void sr_lyd_anydata_free(struct lyd_node *any);
1473
1474 /**
1475  * @brief Copy anydata/anyxml value from src to trg.
1476  *
1477  * @param[in] trg Target to copy to.
1478  * @param[in] src Source to copy from.
1479  * @return err_info, NULL on success.
1480  */
1481 sr_error_info_t *sr_lyd_anydata_copy(struct lyd_node *trg, const struct lyd_node *src);
1482
1483 /**
1484  * @brief Get string value of an anydata/anyxml node.
1485  *
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.
1489  */
1490 sr_error_info_t *sr_ly_anydata_value_str(const struct lyd_node *any, char **value_str);
1491
1492 /**
1493  * @brief Get a hash of a string value.
1494  *
1495  * @param[in] str String to hash.
1496  * @return String hash.
1497  */
1498 uint32_t sr_str_hash(const char *str);
1499
1500 /**
1501  * @brief Trim last node from an XPath.
1502  *
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.
1506  */
1507 sr_error_info_t *sr_xpath_trim_last_node(const char *xpath, char **trim_xpath);
1508
1509 /**
1510  * @brief Get the first node (with predicates if any) from an XPath.
1511  *
1512  * @param[in] xpath Full XPath.
1513  * @return First XPath node path.
1514  */
1515 char *sr_xpath_first_node_with_predicates(const char *xpath);
1516
1517 /**
1518  * @brief Get pointers to the next node name in an XPath.
1519  *
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).
1528  */
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);
1531
1532 /**
1533  * @brief Get pointers to the next predicate in an XPath.
1534  *
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).
1540  */
1541 const char *sr_xpath_next_predicate(const char *xpath, const char **pred, int *len, int *has_predicate);
1542
1543 /**
1544  * @brief Learn length of an XPath withtout any predicates.
1545  *
1546  * @param[in] xpath Full XPath.
1547  * @return XPath length.
1548  */
1549 size_t sr_xpath_len_no_predicates(const char *xpath);
1550
1551 /**
1552  * @brief Find last (most nested) parent (node with possible children) in a data tree.
1553  *
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.
1557  */
1558 sr_error_info_t *sr_ly_find_last_parent(struct lyd_node **parent, int nodetype);
1559
1560 /**
1561  * @brief Unlink data of a specific module from a data tree.
1562  *
1563  * @param[in,out] data Data tree.
1564  * @param[in] ly_mod libyang module of interest.
1565  * @return Unlinked data tree.
1566  */
1567 struct lyd_node *sr_module_data_unlink(struct lyd_node **data, const struct lys_module *ly_mod);
1568
1569 /**
1570  * @brief Append data loaded from a file/SHM for a specific module. Do not use for operational datastore.
1571  *
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.
1576  */
1577 sr_error_info_t *sr_module_file_data_append(const struct lys_module *ly_mod, sr_datastore_t ds, struct lyd_node **data);
1578
1579 /**
1580  * @brief Load operational data (diff) loaded from a SHM for a specific module.
1581  *
1582  * @param[in] mod Mod info mod.
1583  * @param[out] diff Loaded diff to return.
1584  * @return err_info, NULL on success.
1585  */
1586 sr_error_info_t *sr_module_file_oper_data_load(struct sr_mod_info_mod_s *mod, struct lyd_node **diff);
1587
1588 /**
1589  * @brief Set (replace) data in file/SHM for a specific module.
1590  *
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.
1598  */
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);
1601
1602 /**
1603  * @brief Update sysrepo stored operational diff of a module.
1604  *
1605  * @param[in] conn Connection to use.
1606  * @param[in] mod_name Module name.
1607  * @return err_info, NULL on success.
1608  */
1609 sr_error_info_t *sr_module_update_oper_diff(sr_conn_ctx_t *conn, const char *mod_name);
1610
1611 /**
1612  * @brief Get next feature of a module.
1613  *
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.
1618  */
1619 struct lys_feature *sr_lys_next_feature(struct lys_feature *last, const struct lys_module *ly_mod, uint32_t *idx);
1620
1621 /**
1622  * @brief Learn CIDs and PIDs of all the live connections.
1623  *
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.
1630  */
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);
1632
1633 /**
1634  * @brief Transform given time_t (seconds since the epoch) into the RFC 3339 format (YANG date-and-time).
1635  *
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.
1642  */
1643 sr_error_info_t *sr_time2datetime(time_t time, const char *tz, char *buf, char **buf2);
1644
1645 #endif