Apply suggestion from Andrew for srcdir functionality.
[openais.git] / lib / confdb.c
blobca3fd5371b7547f2ae815840d592eeb5111cd782
1 /*
2 * Copyright (c) 2008 Red Hat, Inc.
4 * All rights reserved.
6 * Author: Christine Caulfield (ccaulfie@redhat.com)
8 * This software licensed under BSD license, the text of which follows:
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
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 MontaVista Software, 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.
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.
35 * Provides access to data in the openais object database
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <pthread.h>
42 #include <sys/types.h>
43 #include <errno.h>
45 #include <saAis.h>
46 #include <confdb.h>
47 #include <ipc_confdb.h>
48 #include <mar_gen.h>
49 #include <ais_util.h>
50 #include <list.h>
52 #include "sa-confdb.h"
54 /* Hold the information for iterators so that
55 callers can do recursive tree traversals.
56 each object_handle can have its own iterator */
57 struct iter_context {
58 struct list_head list;
59 uint32_t parent_object_handle;
60 uint32_t context;
63 struct confdb_inst {
64 int response_fd;
65 int dispatch_fd;
66 int finalize;
67 int standalone;
68 confdb_callbacks_t callbacks;
69 void *context;
70 pthread_mutex_t response_mutex;
71 pthread_mutex_t dispatch_mutex;
73 struct list_head object_find_head;
74 struct list_head object_iter_head;
75 struct list_head key_iter_head;
78 static void confdb_instance_destructor (void *instance);
80 static struct saHandleDatabase confdb_handle_t_db = {
81 .handleCount = 0,
82 .handles = 0,
83 .mutex = PTHREAD_MUTEX_INITIALIZER,
84 .handleInstanceDestructor = confdb_instance_destructor
87 /* Safely tidy one iterator context list */
88 static void free_context_list(struct list_head *list)
90 struct iter_context *context;
91 struct list_head *iter, *tmp;
93 for (iter = list->next, tmp = iter->next;
94 iter != list; iter = tmp, tmp = iter->next) {
96 context = list_entry (iter, struct iter_context, list);
97 free(context);
102 * Clean up function for a confdb instance (confdb_initialize) handle
104 static void confdb_instance_destructor (void *instance)
106 struct confdb_inst *confdb_inst = instance;
108 pthread_mutex_destroy (&confdb_inst->response_mutex);
109 pthread_mutex_destroy (&confdb_inst->dispatch_mutex);
112 static struct iter_context *find_iter_context(struct list_head *list, unsigned int object_handle)
114 struct iter_context *context;
115 struct list_head *iter;
117 for (iter = list->next;
118 iter != list; iter = iter->next) {
120 context = list_entry (iter, struct iter_context, list);
121 if (context->parent_object_handle == object_handle)
122 return context;
124 return NULL;
128 * @defgroup confdb_openais
129 * @ingroup openais
131 * @{
134 confdb_error_t confdb_initialize (
135 confdb_handle_t *handle,
136 confdb_callbacks_t *callbacks)
138 SaAisErrorT error;
139 struct confdb_inst *confdb_inst;
141 error = saHandleCreate (&confdb_handle_t_db, sizeof (struct confdb_inst), handle);
142 if (error != SA_AIS_OK) {
143 goto error_no_destroy;
146 error = saHandleInstanceGet (&confdb_handle_t_db, *handle, (void *)&confdb_inst);
147 if (error != SA_AIS_OK) {
148 goto error_destroy;
151 if (getenv("OPENAIS_DEFAULT_CONFIG_IFACE")) {
152 error = confdb_sa_init();
153 confdb_inst->standalone = 1;
155 else {
156 error = saServiceConnect (&confdb_inst->dispatch_fd,
157 &confdb_inst->response_fd,
158 CONFDB_SERVICE);
160 if (error != SA_AIS_OK)
161 goto error_put_destroy;
163 memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t));
165 pthread_mutex_init (&confdb_inst->response_mutex, NULL);
166 pthread_mutex_init (&confdb_inst->dispatch_mutex, NULL);
168 list_init (&confdb_inst->object_find_head);
169 list_init (&confdb_inst->object_iter_head);
170 list_init (&confdb_inst->key_iter_head);
172 saHandleInstancePut (&confdb_handle_t_db, *handle);
174 return (SA_AIS_OK);
176 error_put_destroy:
177 saHandleInstancePut (&confdb_handle_t_db, *handle);
178 error_destroy:
179 saHandleDestroy (&confdb_handle_t_db, *handle);
180 error_no_destroy:
181 return (error);
184 confdb_error_t confdb_finalize (
185 confdb_handle_t handle)
187 struct confdb_inst *confdb_inst;
188 SaAisErrorT error;
190 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
191 if (error != SA_AIS_OK) {
192 return (error);
195 pthread_mutex_lock (&confdb_inst->response_mutex);
198 * Another thread has already started finalizing
200 if (confdb_inst->finalize) {
201 pthread_mutex_unlock (&confdb_inst->response_mutex);
202 saHandleInstancePut (&confdb_handle_t_db, handle);
203 return (CONFDB_ERR_BAD_HANDLE);
206 confdb_inst->finalize = 1;
208 pthread_mutex_unlock (&confdb_inst->response_mutex);
210 saHandleDestroy (&confdb_handle_t_db, handle);
212 /* Free saved context handles */
213 free_context_list(&confdb_inst->object_find_head);
214 free_context_list(&confdb_inst->object_iter_head);
215 free_context_list(&confdb_inst->key_iter_head);
217 if (!confdb_inst->standalone) {
219 * Disconnect from the server
221 if (confdb_inst->response_fd != -1) {
222 shutdown(confdb_inst->response_fd, 0);
223 close(confdb_inst->response_fd);
225 if (confdb_inst->dispatch_fd != -1) {
226 shutdown(confdb_inst->dispatch_fd, 0);
227 close(confdb_inst->dispatch_fd);
230 saHandleInstancePut (&confdb_handle_t_db, handle);
232 return (CONFDB_OK);
235 confdb_error_t confdb_fd_get (
236 confdb_handle_t handle,
237 int *fd)
239 SaAisErrorT error;
240 struct confdb_inst *confdb_inst;
242 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
243 if (error != SA_AIS_OK) {
244 return (error);
247 *fd = confdb_inst->dispatch_fd;
249 saHandleInstancePut (&confdb_handle_t_db, handle);
251 return (SA_AIS_OK);
254 confdb_error_t confdb_context_get (
255 confdb_handle_t handle,
256 void **context)
258 SaAisErrorT error;
259 struct confdb_inst *confdb_inst;
261 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
262 if (error != SA_AIS_OK) {
263 return (error);
266 *context = confdb_inst->context;
268 saHandleInstancePut (&confdb_handle_t_db, handle);
270 return (SA_AIS_OK);
273 confdb_error_t confdb_context_set (
274 confdb_handle_t handle,
275 void *context)
277 SaAisErrorT error;
278 struct confdb_inst *confdb_inst;
280 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
281 if (error != SA_AIS_OK) {
282 return (error);
285 confdb_inst->context = context;
287 saHandleInstancePut (&confdb_handle_t_db, handle);
289 return (SA_AIS_OK);
292 struct res_overlay {
293 mar_res_header_t header __attribute__((aligned(8)));
294 char data[512000];
297 confdb_error_t confdb_dispatch (
298 confdb_handle_t handle,
299 confdb_dispatch_t dispatch_types)
301 struct pollfd ufds;
302 int timeout = -1;
303 SaAisErrorT error;
304 int cont = 1; /* always continue do loop except when set to 0 */
305 int dispatch_avail;
306 struct confdb_inst *confdb_inst;
307 struct res_lib_confdb_change_callback *res_confdb_change_callback;
308 confdb_callbacks_t callbacks;
309 struct res_overlay dispatch_data;
310 int ignore_dispatch = 0;
312 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
313 if (error != SA_AIS_OK) {
314 return (error);
317 if (confdb_inst->standalone) {
318 error = CONFDB_ERR_NOT_SUPPORTED;
319 goto error_unlock;
323 * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and
324 * wait indefinately for SA_DISPATCH_BLOCKING
326 if (dispatch_types == CONFDB_DISPATCH_ALL) {
327 timeout = 0;
330 do {
331 ufds.fd = confdb_inst->dispatch_fd;
332 ufds.events = POLLIN;
333 ufds.revents = 0;
335 error = saPollRetry (&ufds, 1, timeout);
336 if (error != SA_AIS_OK) {
337 goto error_nounlock;
340 pthread_mutex_lock (&confdb_inst->dispatch_mutex);
343 * Regather poll data in case ufds has changed since taking lock
345 error = saPollRetry (&ufds, 1, timeout);
346 if (error != SA_AIS_OK) {
347 goto error_nounlock;
351 * Handle has been finalized in another thread
353 if (confdb_inst->finalize == 1) {
354 error = CONFDB_OK;
355 pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
356 goto error_unlock;
359 dispatch_avail = ufds.revents & POLLIN;
360 if (dispatch_avail == 0 && dispatch_types == CONFDB_DISPATCH_ALL) {
361 pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
362 break; /* exit do while cont is 1 loop */
363 } else
364 if (dispatch_avail == 0) {
365 pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
366 continue; /* next poll */
369 if (ufds.revents & POLLIN) {
371 * Queue empty, read response from socket
373 error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.header,
374 sizeof (mar_res_header_t));
375 if (error != SA_AIS_OK) {
376 goto error_unlock;
378 if (dispatch_data.header.size > sizeof (mar_res_header_t)) {
379 error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.data,
380 dispatch_data.header.size - sizeof (mar_res_header_t));
382 if (error != SA_AIS_OK) {
383 goto error_unlock;
386 } else {
387 pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
388 continue;
392 * Make copy of callbacks, message data, unlock instance, and call callback
393 * A risk of this dispatch method is that the callback routines may
394 * operate at the same time that confdbFinalize has been called.
396 memcpy (&callbacks, &confdb_inst->callbacks, sizeof (confdb_callbacks_t));
398 pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
400 * Dispatch incoming message
402 switch (dispatch_data.header.id) {
403 case MESSAGE_RES_CONFDB_CHANGE_CALLBACK:
404 res_confdb_change_callback = (struct res_lib_confdb_change_callback *)&dispatch_data;
406 callbacks.confdb_change_notify_fn (handle,
407 res_confdb_change_callback->parent_object_handle,
408 res_confdb_change_callback->object_handle,
409 res_confdb_change_callback->object_name.value,
410 res_confdb_change_callback->object_name.length,
411 res_confdb_change_callback->key_name.value,
412 res_confdb_change_callback->key_name.length,
413 res_confdb_change_callback->key_value.value,
414 res_confdb_change_callback->key_value.length);
415 break;
417 default:
418 error = SA_AIS_ERR_LIBRARY;
419 goto error_nounlock;
420 break;
424 * Determine if more messages should be processed
425 * */
426 switch (dispatch_types) {
427 case CONFDB_DISPATCH_ONE:
428 if (ignore_dispatch) {
429 ignore_dispatch = 0;
430 } else {
431 cont = 0;
433 break;
434 case CONFDB_DISPATCH_ALL:
435 if (ignore_dispatch) {
436 ignore_dispatch = 0;
438 break;
439 case CONFDB_DISPATCH_BLOCKING:
440 break;
442 } while (cont);
444 error_unlock:
445 saHandleInstancePut (&confdb_handle_t_db, handle);
446 error_nounlock:
447 return (error);
450 confdb_error_t confdb_object_create (
451 confdb_handle_t handle,
452 unsigned int parent_object_handle,
453 void *object_name,
454 int object_name_len,
455 unsigned int *object_handle)
457 confdb_error_t error;
458 struct confdb_inst *confdb_inst;
459 struct iovec iov[2];
460 struct req_lib_confdb_object_create req_lib_confdb_object_create;
461 struct res_lib_confdb_object_create res_lib_confdb_object_create;
463 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
464 if (error != SA_AIS_OK) {
465 return (error);
468 if (confdb_inst->standalone) {
469 error = SA_AIS_OK;
471 if (confdb_sa_object_create(parent_object_handle,
472 object_name, object_name_len,
473 object_handle))
474 error = SA_AIS_ERR_ACCESS;
475 goto error_exit;
478 req_lib_confdb_object_create.header.size = sizeof (struct req_lib_confdb_object_create);
479 req_lib_confdb_object_create.header.id = MESSAGE_REQ_CONFDB_OBJECT_CREATE;
480 req_lib_confdb_object_create.parent_object_handle = parent_object_handle;
481 memcpy(req_lib_confdb_object_create.object_name.value, object_name, object_name_len);
482 req_lib_confdb_object_create.object_name.length = object_name_len;
484 iov[0].iov_base = (char *)&req_lib_confdb_object_create;
485 iov[0].iov_len = sizeof (struct req_lib_confdb_object_create);
487 pthread_mutex_lock (&confdb_inst->response_mutex);
489 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
490 &res_lib_confdb_object_create, sizeof (struct res_lib_confdb_object_create));
492 pthread_mutex_unlock (&confdb_inst->response_mutex);
493 if (error != SA_AIS_OK) {
494 goto error_exit;
497 error = res_lib_confdb_object_create.header.error;
498 *object_handle = res_lib_confdb_object_create.object_handle;
500 error_exit:
501 saHandleInstancePut (&confdb_handle_t_db, handle);
503 return (error);
506 confdb_error_t confdb_object_destroy (
507 confdb_handle_t handle,
508 unsigned int object_handle)
510 confdb_error_t error;
511 struct confdb_inst *confdb_inst;
512 struct iovec iov[2];
513 struct req_lib_confdb_object_destroy req_lib_confdb_object_destroy;
514 mar_res_header_t res;
516 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
517 if (error != SA_AIS_OK) {
518 return (error);
521 if (confdb_inst->standalone) {
522 error = SA_AIS_OK;
524 if (confdb_sa_object_destroy(object_handle))
525 error = SA_AIS_ERR_ACCESS;
526 goto error_exit;
529 req_lib_confdb_object_destroy.header.size = sizeof (struct req_lib_confdb_object_destroy);
530 req_lib_confdb_object_destroy.header.id = MESSAGE_REQ_CONFDB_OBJECT_DESTROY;
531 req_lib_confdb_object_destroy.object_handle = object_handle;
533 iov[0].iov_base = (char *)&req_lib_confdb_object_destroy;
534 iov[0].iov_len = sizeof (struct req_lib_confdb_object_destroy);
536 pthread_mutex_lock (&confdb_inst->response_mutex);
538 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
539 &res, sizeof ( mar_res_header_t));
541 pthread_mutex_unlock (&confdb_inst->response_mutex);
542 if (error != SA_AIS_OK) {
543 goto error_exit;
546 error = res.error;
548 error_exit:
549 saHandleInstancePut (&confdb_handle_t_db, handle);
551 return (error);
554 confdb_error_t confdb_object_parent_get (
555 confdb_handle_t handle,
556 unsigned int object_handle,
557 unsigned int *parent_object_handle)
559 confdb_error_t error;
560 struct confdb_inst *confdb_inst;
561 struct iovec iov[2];
562 struct req_lib_confdb_object_parent_get req_lib_confdb_object_parent_get;
563 struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get;
565 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
566 if (error != SA_AIS_OK) {
567 return (error);
570 if (confdb_inst->standalone) {
571 error = SA_AIS_OK;
573 if (confdb_sa_object_parent_get(object_handle, parent_object_handle))
574 error = SA_AIS_ERR_ACCESS;
575 goto error_exit;
578 req_lib_confdb_object_parent_get.header.size = sizeof (struct req_lib_confdb_object_parent_get);
579 req_lib_confdb_object_parent_get.header.id = MESSAGE_REQ_CONFDB_OBJECT_PARENT_GET;
580 req_lib_confdb_object_parent_get.object_handle = object_handle;
582 iov[0].iov_base = (char *)&req_lib_confdb_object_parent_get;
583 iov[0].iov_len = sizeof (struct req_lib_confdb_object_parent_get);
585 pthread_mutex_lock (&confdb_inst->response_mutex);
587 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
588 &res_lib_confdb_object_parent_get, sizeof (struct res_lib_confdb_object_parent_get));
590 pthread_mutex_unlock (&confdb_inst->response_mutex);
591 if (error != SA_AIS_OK) {
592 goto error_exit;
595 error = res_lib_confdb_object_parent_get.header.error;
596 *parent_object_handle = res_lib_confdb_object_parent_get.parent_object_handle;
598 error_exit:
599 saHandleInstancePut (&confdb_handle_t_db, handle);
601 return (error);
604 confdb_error_t confdb_key_create (
605 confdb_handle_t handle,
606 unsigned int parent_object_handle,
607 void *key_name,
608 int key_name_len,
609 void *value,
610 int value_len)
612 confdb_error_t error;
613 struct confdb_inst *confdb_inst;
614 struct iovec iov[2];
615 struct req_lib_confdb_key_create req_lib_confdb_key_create;
616 mar_res_header_t res;
618 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
619 if (error != SA_AIS_OK) {
620 return (error);
623 if (confdb_inst->standalone) {
624 error = SA_AIS_OK;
626 if (confdb_sa_key_create(parent_object_handle,
627 key_name, key_name_len,
628 value, value_len))
629 error = SA_AIS_ERR_ACCESS;
630 goto error_exit;
633 req_lib_confdb_key_create.header.size = sizeof (struct req_lib_confdb_key_create);
634 req_lib_confdb_key_create.header.id = MESSAGE_REQ_CONFDB_KEY_CREATE;
635 req_lib_confdb_key_create.object_handle = parent_object_handle;
636 memcpy(req_lib_confdb_key_create.key_name.value, key_name, key_name_len);
637 req_lib_confdb_key_create.key_name.length = key_name_len;
638 memcpy(req_lib_confdb_key_create.value.value, value, value_len);
639 req_lib_confdb_key_create.value.length = value_len;
641 iov[0].iov_base = (char *)&req_lib_confdb_key_create;
642 iov[0].iov_len = sizeof (struct req_lib_confdb_key_create);
644 pthread_mutex_lock (&confdb_inst->response_mutex);
646 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
647 &res, sizeof (res));
649 pthread_mutex_unlock (&confdb_inst->response_mutex);
650 if (error != SA_AIS_OK) {
651 goto error_exit;
654 error = res.error;
656 error_exit:
657 saHandleInstancePut (&confdb_handle_t_db, handle);
659 return (error);
662 confdb_error_t confdb_key_get (
663 confdb_handle_t handle,
664 unsigned int parent_object_handle,
665 void *key_name,
666 int key_name_len,
667 void *value,
668 int *value_len)
670 confdb_error_t error;
671 struct confdb_inst *confdb_inst;
672 struct iovec iov[2];
673 struct req_lib_confdb_key_get req_lib_confdb_key_get;
674 struct res_lib_confdb_key_get res_lib_confdb_key_get;
676 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
677 if (error != SA_AIS_OK) {
678 return (error);
681 if (confdb_inst->standalone) {
682 error = SA_AIS_OK;
684 if (confdb_sa_key_get(parent_object_handle,
685 key_name, key_name_len,
686 value, value_len))
687 error = SA_AIS_ERR_ACCESS;
688 goto error_exit;
691 req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
692 req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET;
693 req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
694 memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
695 req_lib_confdb_key_get.key_name.length = key_name_len;
697 iov[0].iov_base = (char *)&req_lib_confdb_key_get;
698 iov[0].iov_len = sizeof (struct req_lib_confdb_key_get);
700 pthread_mutex_lock (&confdb_inst->response_mutex);
702 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
703 &res_lib_confdb_key_get, sizeof (struct res_lib_confdb_key_get));
705 pthread_mutex_unlock (&confdb_inst->response_mutex);
706 if (error != SA_AIS_OK) {
707 goto error_exit;
710 error = res_lib_confdb_key_get.header.error;
711 if (error == SA_AIS_OK) {
712 *value_len = res_lib_confdb_key_get.value.length;
713 memcpy(value, res_lib_confdb_key_get.value.value, *value_len);
716 error_exit:
717 saHandleInstancePut (&confdb_handle_t_db, handle);
719 return (error);
723 confdb_error_t confdb_key_replace (
724 confdb_handle_t handle,
725 unsigned int parent_object_handle,
726 void *key_name,
727 int key_name_len,
728 void *old_value,
729 int old_value_len,
730 void *new_value,
731 int new_value_len)
733 confdb_error_t error;
734 struct confdb_inst *confdb_inst;
735 struct iovec iov[2];
736 struct req_lib_confdb_key_replace req_lib_confdb_key_replace;
737 mar_res_header_t res;
739 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
740 if (error != SA_AIS_OK) {
741 return (error);
744 if (confdb_inst->standalone) {
745 error = SA_AIS_OK;
747 if (confdb_sa_key_replace(parent_object_handle,
748 key_name, key_name_len,
749 old_value, old_value_len,
750 new_value, new_value_len))
751 error = SA_AIS_ERR_ACCESS;
752 goto error_exit;
754 req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace);
755 req_lib_confdb_key_replace.header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE;
756 req_lib_confdb_key_replace.object_handle = parent_object_handle;
757 memcpy(req_lib_confdb_key_replace.key_name.value, key_name, key_name_len);
758 req_lib_confdb_key_replace.key_name.length = key_name_len;
759 memcpy(req_lib_confdb_key_replace.old_value.value, old_value, old_value_len);
760 req_lib_confdb_key_replace.old_value.length = old_value_len;
761 memcpy(req_lib_confdb_key_replace.new_value.value, new_value, new_value_len);
762 req_lib_confdb_key_replace.new_value.length = new_value_len;
764 iov[0].iov_base = (char *)&req_lib_confdb_key_replace;
765 iov[0].iov_len = sizeof (struct req_lib_confdb_key_replace);
767 pthread_mutex_lock (&confdb_inst->response_mutex);
769 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
770 &res, sizeof (res));
772 pthread_mutex_unlock (&confdb_inst->response_mutex);
773 if (error != SA_AIS_OK) {
774 goto error_exit;
777 error = res.error;
779 error_exit:
780 saHandleInstancePut (&confdb_handle_t_db, handle);
782 return (error);
785 confdb_error_t confdb_object_iter_start (
786 confdb_handle_t handle,
787 unsigned int object_handle)
789 struct confdb_inst *confdb_inst;
790 confdb_error_t error = SA_AIS_OK;
791 struct iter_context *context;
793 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
794 if (error != SA_AIS_OK) {
795 return (error);
798 context = find_iter_context(&confdb_inst->object_iter_head, object_handle);
799 if (!context) {
800 context = malloc(sizeof(struct iter_context));
801 if (!context) {
802 error = CONFDB_ERR_NO_MEMORY;
803 goto ret;
805 context->parent_object_handle = object_handle;
806 list_add(&context->list, &confdb_inst->object_iter_head);
809 context->context = 0;
811 saHandleInstancePut (&confdb_handle_t_db, handle);
813 ret:
814 return error;
817 confdb_error_t confdb_key_iter_start (
818 confdb_handle_t handle,
819 unsigned int object_handle)
821 struct confdb_inst *confdb_inst;
822 confdb_error_t error = SA_AIS_OK;
823 struct iter_context *context;
825 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
826 if (error != SA_AIS_OK) {
827 return (error);
830 context = find_iter_context(&confdb_inst->key_iter_head, object_handle);
831 if (!context) {
832 context = malloc(sizeof(struct iter_context));
833 if (!context) {
834 error = CONFDB_ERR_NO_MEMORY;
835 goto ret;
837 context->parent_object_handle = object_handle;
838 list_add(&context->list, &confdb_inst->key_iter_head);
841 context->context = 0;
843 saHandleInstancePut (&confdb_handle_t_db, handle);
845 ret:
846 return error;
849 confdb_error_t confdb_object_find_start (
850 confdb_handle_t handle,
851 unsigned int parent_object_handle)
853 struct confdb_inst *confdb_inst;
854 confdb_error_t error = SA_AIS_OK;
855 struct iter_context *context;
857 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
858 if (error != SA_AIS_OK) {
859 return (error);
862 context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
863 if (!context) {
864 context = malloc(sizeof(struct iter_context));
865 if (!context) {
866 error = CONFDB_ERR_NO_MEMORY;
867 goto ret;
869 context->parent_object_handle = parent_object_handle;
870 list_add(&context->list, &confdb_inst->object_find_head);
873 context->context = 0;
875 saHandleInstancePut (&confdb_handle_t_db, handle);
877 ret:
878 return error;
881 confdb_error_t confdb_object_find (
882 confdb_handle_t handle,
883 unsigned int parent_object_handle,
884 void *object_name,
885 int object_name_len,
886 unsigned int *object_handle)
888 confdb_error_t error;
889 struct confdb_inst *confdb_inst;
890 struct iovec iov[2];
891 struct iter_context *context;
892 struct req_lib_confdb_object_find req_lib_confdb_object_find;
893 struct res_lib_confdb_object_find res_lib_confdb_object_find;
895 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
896 if (error != SA_AIS_OK) {
897 return (error);
900 /* You MUST call confdb_object_find_start first */
901 context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
902 if (!context) {
903 error = CONFDB_ERR_CONTEXT_NOT_FOUND;
904 goto error_exit;
907 if (confdb_inst->standalone) {
908 error = SA_AIS_OK;
910 if (confdb_sa_object_find(parent_object_handle,
911 context->context,
912 object_name, object_name_len,
913 object_handle,
914 &context->context))
915 error = SA_AIS_ERR_ACCESS;
916 goto error_exit;
919 req_lib_confdb_object_find.header.size = sizeof (struct req_lib_confdb_object_find);
920 req_lib_confdb_object_find.header.id = MESSAGE_REQ_CONFDB_OBJECT_FIND;
921 req_lib_confdb_object_find.parent_object_handle = parent_object_handle;
922 req_lib_confdb_object_find.next_entry = context->context;
923 memcpy(req_lib_confdb_object_find.object_name.value, object_name, object_name_len);
924 req_lib_confdb_object_find.object_name.length = object_name_len;
926 iov[0].iov_base = (char *)&req_lib_confdb_object_find;
927 iov[0].iov_len = sizeof (struct req_lib_confdb_object_find);
929 pthread_mutex_lock (&confdb_inst->response_mutex);
931 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
932 &res_lib_confdb_object_find, sizeof (struct res_lib_confdb_object_find));
934 pthread_mutex_unlock (&confdb_inst->response_mutex);
935 if (error != SA_AIS_OK) {
936 goto error_exit;
939 error = res_lib_confdb_object_find.header.error;
940 *object_handle = res_lib_confdb_object_find.object_handle;
941 context->context = res_lib_confdb_object_find.next_entry;
943 error_exit:
944 saHandleInstancePut (&confdb_handle_t_db, handle);
946 return (error);
950 confdb_error_t confdb_object_iter (
951 confdb_handle_t handle,
952 unsigned int parent_object_handle,
953 unsigned int *object_handle,
954 void *object_name,
955 int *object_name_len)
957 confdb_error_t error;
958 struct confdb_inst *confdb_inst;
959 struct iovec iov[2];
960 struct iter_context *context;
961 struct req_lib_confdb_object_iter req_lib_confdb_object_iter;
962 struct res_lib_confdb_object_iter res_lib_confdb_object_iter;
964 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
965 if (error != SA_AIS_OK) {
966 return (error);
969 /* You MUST call confdb_object_iter_start first */
970 context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle);
971 if (!context) {
972 error = CONFDB_ERR_CONTEXT_NOT_FOUND;
973 goto error_exit;
976 if (confdb_inst->standalone) {
977 error = SA_AIS_OK;
979 if (confdb_sa_object_iter(parent_object_handle,
980 context->context,
981 object_handle,
982 object_name, object_name_len))
983 error = SA_AIS_ERR_ACCESS;
984 goto sa_exit;
987 req_lib_confdb_object_iter.header.size = sizeof (struct req_lib_confdb_object_iter);
988 req_lib_confdb_object_iter.header.id = MESSAGE_REQ_CONFDB_OBJECT_ITER;
989 req_lib_confdb_object_iter.parent_object_handle = parent_object_handle;
990 req_lib_confdb_object_iter.next_entry = context->context;
992 iov[0].iov_base = (char *)&req_lib_confdb_object_iter;
993 iov[0].iov_len = sizeof (struct req_lib_confdb_object_iter);
995 pthread_mutex_lock (&confdb_inst->response_mutex);
997 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
998 &res_lib_confdb_object_iter, sizeof (struct res_lib_confdb_object_iter));
1000 pthread_mutex_unlock (&confdb_inst->response_mutex);
1001 if (error != SA_AIS_OK) {
1002 goto error_exit;
1005 error = res_lib_confdb_object_iter.header.error;
1006 if (error == SA_AIS_OK) {
1007 *object_name_len = res_lib_confdb_object_iter.object_name.length;
1008 memcpy(object_name, res_lib_confdb_object_iter.object_name.value, *object_name_len);
1009 *object_handle = res_lib_confdb_object_iter.object_handle;
1011 sa_exit:
1012 context->context++;
1014 error_exit:
1015 saHandleInstancePut (&confdb_handle_t_db, handle);
1017 return (error);
1020 confdb_error_t confdb_key_iter (
1021 confdb_handle_t handle,
1022 unsigned int parent_object_handle,
1023 void *key_name,
1024 int *key_name_len,
1025 void *value,
1026 int *value_len)
1028 confdb_error_t error;
1029 struct confdb_inst *confdb_inst;
1030 struct iovec iov[2];
1031 struct iter_context *context;
1032 struct req_lib_confdb_key_iter req_lib_confdb_key_iter;
1033 struct res_lib_confdb_key_iter res_lib_confdb_key_iter;
1035 error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
1036 if (error != SA_AIS_OK) {
1037 return (error);
1040 /* You MUST call confdb_key_iter_start first */
1041 context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle);
1042 if (!context) {
1043 error = CONFDB_ERR_CONTEXT_NOT_FOUND;
1044 goto error_exit;
1047 if (confdb_inst->standalone) {
1048 error = SA_AIS_OK;
1050 if (confdb_sa_key_iter(parent_object_handle,
1051 context->context,
1052 key_name, key_name_len,
1053 value, value_len))
1054 error = SA_AIS_ERR_ACCESS;
1055 goto sa_exit;
1058 req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
1059 req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER;
1060 req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
1061 req_lib_confdb_key_iter.next_entry = context->context;
1063 iov[0].iov_base = (char *)&req_lib_confdb_key_iter;
1064 iov[0].iov_len = sizeof (struct req_lib_confdb_key_iter);
1066 pthread_mutex_lock (&confdb_inst->response_mutex);
1068 error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
1069 &res_lib_confdb_key_iter, sizeof (struct res_lib_confdb_key_iter));
1071 pthread_mutex_unlock (&confdb_inst->response_mutex);
1072 if (error != SA_AIS_OK) {
1073 goto error_exit;
1076 error = res_lib_confdb_key_iter.header.error;
1077 if (error == SA_AIS_OK) {
1078 *key_name_len = res_lib_confdb_key_iter.key_name.length;
1079 memcpy(key_name, res_lib_confdb_key_iter.key_name.value, *key_name_len);
1080 *value_len = res_lib_confdb_key_iter.value.length;
1081 memcpy(value, res_lib_confdb_key_iter.value.value, *value_len);
1084 sa_exit:
1085 context->context++;
1087 error_exit:
1088 saHandleInstancePut (&confdb_handle_t_db, handle);
1090 return (error);