1 /*
2  * Copyright (c) 2011 Red Hat, Inc.
3  *
4  * All rights reserved.
5  *
6  * Author: Jan Friesse (jfriesse@redhat.com)
7  *
8  * This software licensed under BSD license, the text of which follows:
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  *   this list of conditions and the following disclaimer.
15  * - Redistributions in binary form must reproduce the above copyright notice,
16  *   this list of conditions and the following disclaimer in the documentation
17  *   and/or other materials provided with the distribution.
18  * - Neither the name of the Red Hat, Inc. nor the names of its
19  *   contributors may be used to endorse or promote products derived from this
20  *   software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #ifndef COROSYNC_CMAP_H_DEFINED
36 #define COROSYNC_CMAP_H_DEFINED
37 
38 #include <corosync/corotypes.h>
39 #include <corosync/hdb.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /**
46  * @addtogroup cmap_corosync
47  *
48  * @{
49  */
50 
51 /*
52  * Handle for cmap service connection
53  */
54 typedef uint64_t cmap_handle_t;
55 
56 /*
57  * Handle for cmap iterator
58  */
59 typedef uint64_t cmap_iter_handle_t;
60 
61 /*
62  * Handle for cmap tracking function
63  */
64 typedef uint64_t cmap_track_handle_t;
65 
66 /*
67  * Maximum length of key in cmap
68  */
69 #define CMAP_KEYNAME_MAXLEN            255
70 /*
71  * Minumum length of key in cmap
72  */
73 #define CMAP_KEYNAME_MINLEN            3
74 
75 /*
76  * Tracking values.
77  */
78 #define CMAP_TRACK_ADD		4
79 #define CMAP_TRACK_DELETE	1
80 #define CMAP_TRACK_MODIFY	2
81 
82 /**
83  * Whole prefix is tracked, instead of key only (so "totem." tracking means that
84  * "totem.nodeid", "totem.version", ... applies). This value is also never returned
85  * inside of callback and is used only in adding track
86  */
87 #define CMAP_TRACK_PREFIX	8
88 
89 /**
90  * Possible types of value. Binary is raw data without trailing zero with given length
91  */
92 typedef enum {
93     CMAP_VALUETYPE_INT8 	=  1,
94     CMAP_VALUETYPE_UINT8	=  2,
95     CMAP_VALUETYPE_INT16	=  3,
96     CMAP_VALUETYPE_UINT16	=  4,
97     CMAP_VALUETYPE_INT32	=  5,
98     CMAP_VALUETYPE_UINT32	=  6,
99     CMAP_VALUETYPE_INT64	=  7,
100     CMAP_VALUETYPE_UINT64	=  8,
101     CMAP_VALUETYPE_FLOAT	=  9,
102     CMAP_VALUETYPE_DOUBLE	= 10,
103     CMAP_VALUETYPE_STRING	= 11,
104     CMAP_VALUETYPE_BINARY	= 12,
105 } cmap_value_types_t;
106 
107 /**
108  * Structure passed as new_value and old_value in change callback. It contains type of
109  * key, length of key and pointer to value of key
110  */
111 struct cmap_notify_value {
112 	cmap_value_types_t type;
113 	size_t len;
114 	const void *data;
115 };
116 
117 /**
118  * Prototype for notify callback function. Even is one of CMAP_TRACK_* event, key_name is
119  * changed key, new and old_value contains values or are zeroed (in other words, type is non
120  * existing 0 type) if there were no old (creating of key) or new (deleting of key) value.
121  * user_data are passed when adding tracking.
122  */
123 typedef void (*cmap_notify_fn_t) (
124 	cmap_handle_t cmap_handle,
125 	cmap_track_handle_t cmap_track_handle,
126 	int32_t event,
127 	const char *key_name,
128 	struct cmap_notify_value new_value,
129 	struct cmap_notify_value old_value,
130 	void *user_data);
131 
132 /**
133  * Create a new cmap connection
134  *
135  * @param handle will be filled with handle to be used for all following
136  * operations with cht.
137  */
138 extern cs_error_t cmap_initialize (
139 	cmap_handle_t *handle);
140 
141 /**
142  * Close the cmap handle
143  * @param handle cmap handle
144  */
145 extern cs_error_t cmap_finalize (
146 	cmap_handle_t handle);
147 
148 /**
149  * Get a file descriptor on which to poll.  cmap_handle_t is NOT a
150  * file descriptor and may not be used directly.
151  * @param handle cmap handle initialized by cmap_initialize
152  * @param fd file descriptor for poll
153  */
154 extern cs_error_t cmap_fd_get (
155 	cmap_handle_t handle,
156 	int *fd);
157 
158 /**
159  * Dispatch data from service.
160  * @param handle cmap handle initialized by cmap_initialize
161  * @param dispatch_types one of standard corosync dispatch values
162  */
163 extern cs_error_t cmap_dispatch (
164 	cmap_handle_t handle,
165 	cs_dispatch_flags_t dispatch_types);
166 /**
167  * @brief cmap_context_get
168  * @param handle
169  * @param context
170  * @return
171  */
172 extern cs_error_t cmap_context_get (
173 	cmap_handle_t handle,
174 	const void **context);
175 
176 /**
177  * @brief cmap_context_set
178  * @param handle
179  * @param context
180  * @return
181  */
182 extern cs_error_t cmap_context_set (
183 	cmap_handle_t handle,
184 	const void *context);
185 
186 /**
187  * Store value in cmap
188  * @param handle cmap handle
189  * @param key_name name of key where to store value
190  * @param value value to store
191  * @param value_len length of value to store
192  * @param type type to store
193  */
194 extern cs_error_t cmap_set(
195 	cmap_handle_t handle,
196 	const char *key_name,
197 	const void *value,
198 	size_t value_len,
199 	cmap_value_types_t type);
200 
201 /*
202  * Shortcuts for cmap_set with given type
203  */
204 extern cs_error_t cmap_set_int8(cmap_handle_t handle, const char *key_name, int8_t value);
205 extern cs_error_t cmap_set_uint8(cmap_handle_t handle, const char *key_name, uint8_t value);
206 extern cs_error_t cmap_set_int16(cmap_handle_t handle, const char *key_name, int16_t value);
207 extern cs_error_t cmap_set_uint16(cmap_handle_t handle, const char *key_name, uint16_t value);
208 extern cs_error_t cmap_set_int32(cmap_handle_t handle, const char *key_name, int32_t value);
209 extern cs_error_t cmap_set_uint32(cmap_handle_t handle, const char *key_name, uint32_t value);
210 extern cs_error_t cmap_set_int64(cmap_handle_t handle, const char *key_name, int64_t value);
211 extern cs_error_t cmap_set_uint64(cmap_handle_t handle, const char *key_name, uint64_t value);
212 extern cs_error_t cmap_set_float(cmap_handle_t handle, const char *key_name, float value);
213 extern cs_error_t cmap_set_double(cmap_handle_t handle, const char *key_name, double value);
214 extern cs_error_t cmap_set_string(cmap_handle_t handle, const char *key_name, const char *value);
215 
216 /**
217  * Deletes key from cmap database
218  * @param handle cmap handle
219  * @param key_name name of key to delete
220  */
221 extern cs_error_t cmap_delete(cmap_handle_t handle, const char *key_name);
222 
223 /**
224  * @brief Retrieve value of key key_name and store it in user preallocated value pointer.
225  *
226  * value can be NULL, and then only value_len and/or type is returned (both of them
227  * can also be NULL). If value is not NULL, actual length of value in map is checked
228  * against value_len. If *value_len is shorter then length of value in map, error
229  * CS_ERR_INVALID_PARAM is returned. After successful copy of value, value_len is
230  * set to actual length of value in map.
231  *
232  * @param handle cmap handle
233  * @param key_name name of key where to get value
234  * @param value pointer to store data (or NULL)
235  * @param value_len pointer with length of value (value != NULL), or pointer where value length
236  * will be returned (value == NULL) or NULL.
237  * @param type type of value in cmap
238  */
239 extern cs_error_t cmap_get(
240 	cmap_handle_t handle,
241 	const char *key_name,
242 	void *value,
243 	size_t *value_len,
244 	cmap_value_types_t *type);
245 
246 /*
247  * Shortcuts for cmap_get.
248  */
249 extern cs_error_t cmap_get_int8(cmap_handle_t handle, const char *key_name, int8_t *i8);
250 extern cs_error_t cmap_get_uint8(cmap_handle_t handle, const char *key_name, uint8_t *u8);
251 extern cs_error_t cmap_get_int16(cmap_handle_t handle, const char *key_name, int16_t *i16);
252 extern cs_error_t cmap_get_uint16(cmap_handle_t handle, const char *key_name, uint16_t *u16);
253 extern cs_error_t cmap_get_int32(cmap_handle_t handle, const char *key_name, int32_t *i32);
254 extern cs_error_t cmap_get_uint32(cmap_handle_t handle, const char *key_name, uint32_t *u32);
255 extern cs_error_t cmap_get_int64(cmap_handle_t handle, const char *key_name, int64_t *i64);
256 extern cs_error_t cmap_get_uint64(cmap_handle_t handle, const char *key_name, uint64_t *u64);
257 extern cs_error_t cmap_get_float(cmap_handle_t handle, const char *key_name, float *flt);
258 extern cs_error_t cmap_get_double(cmap_handle_t handle, const char *key_name, double *dbl);
259 
260 /**
261  * @brief Shortcut for cmap_get for string type.
262  *
263  * Returned string is newly allocated and caller is responsible for freeing memory
264  *
265  * @param handle cmap handle
266  * @param key_name name of key to get value from
267  * @param str pointer where char pointer will be stored
268  */
269 extern cs_error_t cmap_get_string(cmap_handle_t handle, const char *key_name, char **str);
270 
271 /**
272  * @brief Increment value of key_name if it is [u]int* type
273  *
274  * @param handle cmap handle
275  * @param key_name key name
276  */
277 extern cs_error_t cmap_inc(cmap_handle_t handle, const char *key_name);
278 
279 /**
280  * @brief Decrement value of key_name if it is [u]int* type
281  *
282  * @param handle cmap handle
283  * @param key_name key name
284  */
285 extern cs_error_t cmap_dec(cmap_handle_t handle, const char *key_name);
286 
287 /**
288  * @brief Initialize iterator with given prefix
289  *
290  * @param handle cmap handle
291  * @param prefix prefix to iterate on
292  * @param cmap_iter_handle value used for getting next value of iterator and/or deleting iteration
293  */
294 extern cs_error_t cmap_iter_init(cmap_handle_t handle, const char *prefix, cmap_iter_handle_t *cmap_iter_handle);
295 
296 /**
297  * @brief Return next item in iterator iter.
298  *
299  * value_len and type are optional (= can be NULL), but if set,
300  * length of returned value and/or type is returned.
301  *
302  * @param handle cmap handle
303  * @param iter_handle handle of iteration returned by cmap_iter_init
304  * @param key_name place to store name of key. Maximum length is CMAP_KEYNAME_MAXLEN and
305  *                 trailing zero is always added so size of the buffer has to be at least
306  *                 CMAP_KEYNAME_MAXLEN + 1.
307  * @param value_len length of value
308  * @param type type of value
309  * @return CS_NO_SECTION if there are no more sections to iterate
310  */
311 extern cs_error_t cmap_iter_next(
312 		cmap_handle_t handle,
313 		cmap_iter_handle_t iter_handle,
314 		char key_name[],
315 		size_t *value_len,
316 		cmap_value_types_t *type);
317 
318 /**
319  * @brief Finalize iterator
320  * @param handle
321  * @param iter_handle
322  * @return
323  */
324 extern cs_error_t cmap_iter_finalize(cmap_handle_t handle, cmap_iter_handle_t iter_handle);
325 
326 /**
327  * @brief Add tracking function for given key_name.
328  *
329  * Tracked changes (add|modify|delete) depend on track_type,
330  * which is bitwise or of CMAP_TRACK_* values. notify_fn is called on change, where user_data pointer
331  * is passed (unchanged). Value which can be used to delete tracking is passed as cmap_track.
332  *
333  * @param handle cmap handle
334  * @param key_name name of key to track changes on
335  * @param track_type bitwise-or of CMAP_TRACK_* values
336  * @param notify_fn function to be called on change of key
337  * @param user_data given pointer is unchanged passed to notify_fn
338  * @param cmap_track_handle handle used for removing of newly created track
339  */
340 extern cs_error_t cmap_track_add(
341 	cmap_handle_t handle,
342 	const char *key_name,
343         int32_t track_type,
344 	cmap_notify_fn_t notify_fn,
345         void *user_data,
346         cmap_track_handle_t *cmap_track_handle);
347 
348 /**
349  * Delete track created previously by cmap_track_add
350  * @param handle cmap handle
351  * @param track_handle Track handle
352  */
353 extern cs_error_t cmap_track_delete(cmap_handle_t handle, cmap_track_handle_t track_handle);
354 
355 /** @} */
356 
357 #ifdef __cplusplus
358 }
359 #endif
360 
361 #endif /* COROSYNC_CMAP_H_DEFINED */
362