Patch to add new api to logsys to get priority names from subsystem names.
[openais.git] / lib / cfg.c
blob3d8a97883ab2b7e34d6c7c38f9b315ecf1241758
2 /*
3 * Copyright (c) 2002-2005 MontaVista Software, Inc.
4 * Copyright (c) 2006 Red Hat, Inc.
6 * All rights reserved.
8 * Author: Steven Dake (sdake@mvista.com)
10 * This software licensed under BSD license, the text of which follows:
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * - Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * - Neither the name of the MontaVista Software, Inc. nor the names of its
21 * contributors may be used to endorse or promote products derived from this
22 * software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGE.
37 #include <stdio.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <errno.h>
42 #include <signal.h>
43 #include <pthread.h>
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <sys/select.h>
47 #include <sys/un.h>
49 #include <saAis.h>
50 #include <cfg.h>
51 #include <mar_gen.h>
52 #include <ipc_gen.h>
53 #include <ipc_cfg.h>
54 #include <ais_util.h>
56 struct res_overlay {
57 mar_res_header_t header;
58 char data[4096];
62 * Data structure for instance data
64 struct cfg_instance {
65 int response_fd;
66 int dispatch_fd;
67 OpenaisCfgCallbacksT callbacks;
68 SaNameT compName;
69 int compRegistered;
70 int finalize;
71 pthread_mutex_t response_mutex;
72 pthread_mutex_t dispatch_mutex;
75 static void cfg_handleInstanceDestructor (void *);
78 * All instances in one database
80 static struct saHandleDatabase cfg_hdb = {
81 .handleCount = 0,
82 .handles = 0,
83 .mutex = PTHREAD_MUTEX_INITIALIZER,
84 .handleInstanceDestructor = cfg_handleInstanceDestructor
88 * Implementation
90 void cfg_handleInstanceDestructor (void *instance)
92 struct cfg_instance *cfg_instance = instance;
94 pthread_mutex_destroy (&cfg_instance->response_mutex);
95 pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
98 SaAisErrorT
99 openais_cfg_initialize (
100 openais_cfg_handle_t *cfg_handle,
101 const OpenaisCfgCallbacksT *cfgCallbacks)
103 struct cfg_instance *cfg_instance;
104 SaAisErrorT error = SA_AIS_OK;
106 error = saHandleCreate (&cfg_hdb, sizeof (struct cfg_instance), cfg_handle);
107 if (error != SA_AIS_OK) {
108 goto error_no_destroy;
111 error = saHandleInstanceGet (&cfg_hdb, *cfg_handle, (void *)&cfg_instance);
112 if (error != SA_AIS_OK) {
113 goto error_destroy;
116 cfg_instance->response_fd = -1;
118 cfg_instance->dispatch_fd = -1;
120 error = saServiceConnect (&cfg_instance->response_fd,
121 &cfg_instance->dispatch_fd, CFG_SERVICE);
122 if (error != SA_AIS_OK) {
123 goto error_put_destroy;
126 if (cfgCallbacks) {
127 memcpy (&cfg_instance->callbacks, cfgCallbacks, sizeof (OpenaisCfgCallbacksT));
130 pthread_mutex_init (&cfg_instance->response_mutex, NULL);
132 pthread_mutex_init (&cfg_instance->dispatch_mutex, NULL);
134 saHandleInstancePut (&cfg_hdb, *cfg_handle);
136 return (SA_AIS_OK);
138 error_put_destroy:
139 saHandleInstancePut (&cfg_hdb, *cfg_handle);
140 error_destroy:
141 saHandleDestroy (&cfg_hdb, *cfg_handle);
142 error_no_destroy:
143 return (error);
146 SaAisErrorT
147 openais_cfg_fd_get (
148 openais_cfg_handle_t cfg_handle,
149 SaSelectionObjectT *selectionObject)
151 struct cfg_instance *cfg_instance;
152 SaAisErrorT error;
154 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
155 if (error != SA_AIS_OK) {
156 return (error);
159 *selectionObject = cfg_instance->dispatch_fd;
161 saHandleInstancePut (&cfg_hdb, cfg_handle);
162 return (SA_AIS_OK);
165 SaAisErrorT
166 openais_cfg_dispatch (
167 openais_cfg_handle_t cfg_handle,
168 SaDispatchFlagsT dispatchFlags)
170 struct pollfd ufds;
171 int timeout = -1;
172 SaAisErrorT error;
173 int cont = 1; /* always continue do loop except when set to 0 */
174 int dispatch_avail;
175 struct cfg_instance *cfg_instance;
176 #ifdef COMPILE_OUT
177 struct res_lib_openais_healthcheckcallback *res_lib_openais_healthcheckcallback;
178 struct res_lib_openais_readinessstatesetcallback *res_lib_openais_readinessstatesetcallback;
179 struct res_lib_openais_csisetcallback *res_lib_openais_csisetcallback;
180 struct res_lib_openais_csiremovecallback *res_lib_openais_csiremovecallback;
181 struct res_lib_cfg_statetrackcallback *res_lib_cfg_statetrackcallback;
182 #endif
183 OpenaisCfgCallbacksT callbacks;
184 struct res_overlay dispatch_data;
186 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
187 (void *)&cfg_instance);
188 if (error != SA_AIS_OK) {
189 return (error);
193 * Timeout instantly for SA_DISPATCH_ALL
195 if (dispatchFlags == SA_DISPATCH_ALL) {
196 timeout = 0;
199 do {
201 * Read data directly from socket
203 ufds.fd = cfg_instance->dispatch_fd;
204 ufds.events = POLLIN;
205 ufds.revents = 0;
207 error = saPollRetry (&ufds, 1, timeout);
208 if (error != SA_AIS_OK) {
209 goto error_nounlock;
212 pthread_mutex_lock (&cfg_instance->dispatch_mutex);
214 error = saPollRetry (&ufds, 1, 0);
215 if (error != SA_AIS_OK) {
216 goto error_nounlock;
220 * Handle has been finalized in another thread
222 if (cfg_instance->finalize == 1) {
223 error = SA_AIS_OK;
224 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
225 goto error_unlock;
228 dispatch_avail = ufds.revents & POLLIN;
229 if (dispatch_avail == 0 && dispatchFlags == SA_DISPATCH_ALL) {
230 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
231 break; /* exit do while cont is 1 loop */
232 } else
233 if (dispatch_avail == 0) {
234 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
235 continue; /* next poll */
238 if (ufds.revents & POLLIN) {
240 * Queue empty, read response from socket
242 error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.header,
243 sizeof (mar_res_header_t));
244 if (error != SA_AIS_OK) {
245 goto error_unlock;
247 if (dispatch_data.header.size > sizeof (mar_res_header_t)) {
248 error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.data,
249 dispatch_data.header.size - sizeof (mar_res_header_t));
250 if (error != SA_AIS_OK) {
251 goto error_unlock;
254 } else {
255 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
256 continue;
260 * Make copy of callbacks, message data, unlock instance, and call callback
261 * A risk of this dispatch method is that the callback routines may
262 * operate at the same time that cfgFinalize has been called in another thread.
264 memcpy (&callbacks, &cfg_instance->callbacks, sizeof (OpenaisCfgCallbacksT));
265 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
268 * Dispatch incoming response
270 switch (dispatch_data.header.id) {
272 default:
273 error = SA_AIS_ERR_LIBRARY;
274 goto error_nounlock;
275 break;
279 * Determine if more messages should be processed
281 switch (dispatchFlags) {
282 case SA_DISPATCH_ONE:
283 cont = 0;
284 break;
285 case SA_DISPATCH_ALL:
286 break;
287 case SA_DISPATCH_BLOCKING:
288 break;
290 } while (cont);
292 error_unlock:
293 saHandleInstancePut (&cfg_hdb, cfg_handle);
294 error_nounlock:
295 return (error);
298 SaAisErrorT
299 openais_cfg_finalize (
300 openais_cfg_handle_t cfg_handle)
302 struct cfg_instance *cfg_instance;
303 SaAisErrorT error;
305 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
306 if (error != SA_AIS_OK) {
307 return (error);
310 pthread_mutex_lock (&cfg_instance->dispatch_mutex);
312 pthread_mutex_lock (&cfg_instance->response_mutex);
315 * Another thread has already started finalizing
317 if (cfg_instance->finalize) {
318 pthread_mutex_unlock (&cfg_instance->response_mutex);
319 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
320 saHandleInstancePut (&cfg_hdb, cfg_handle);
321 return (SA_AIS_ERR_BAD_HANDLE);
324 cfg_instance->finalize = 1;
326 pthread_mutex_unlock (&cfg_instance->response_mutex);
328 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
330 pthread_mutex_destroy (&cfg_instance->response_mutex);
332 pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
334 saHandleDestroy (&cfg_hdb, cfg_handle);
336 if (cfg_instance->response_fd != -1) {
337 shutdown (cfg_instance->response_fd, 0);
338 close (cfg_instance->response_fd);
340 if (cfg_instance->dispatch_fd != -1) {
341 shutdown (cfg_instance->dispatch_fd, 0);
342 close (cfg_instance->dispatch_fd);
345 saHandleInstancePut (&cfg_hdb, cfg_handle);
347 return (error);
350 SaAisErrorT
351 openais_cfg_ring_status_get (
352 openais_cfg_handle_t cfg_handle,
353 char ***interface_names,
354 char ***status,
355 unsigned int *interface_count)
357 struct cfg_instance *cfg_instance;
358 struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget;
359 struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget;
360 unsigned int i;
361 SaAisErrorT error;
363 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
364 if (error != SA_AIS_OK) {
365 return (error);
368 req_lib_cfg_ringstatusget.header.size = sizeof (struct req_lib_cfg_ringstatusget);
369 req_lib_cfg_ringstatusget.header.id = MESSAGE_REQ_CFG_RINGSTATUSGET;
371 pthread_mutex_lock (&cfg_instance->response_mutex);
373 error = saSendReceiveReply (cfg_instance->response_fd,
374 &req_lib_cfg_ringstatusget,
375 sizeof (struct req_lib_cfg_ringstatusget),
376 &res_lib_cfg_ringstatusget,
377 sizeof (struct res_lib_cfg_ringstatusget));
379 pthread_mutex_unlock (&cfg_instance->response_mutex);
381 *interface_count = res_lib_cfg_ringstatusget.interface_count;
382 *interface_names = malloc (sizeof (char *) * *interface_count);
383 if (*interface_names == NULL) {
384 return (SA_AIS_ERR_NO_MEMORY);
386 memset (*interface_names, 0, sizeof (char *) * *interface_count);
388 *status = malloc (sizeof (char *) * *interface_count);
389 if (*status == NULL) {
390 error = SA_AIS_ERR_NO_MEMORY;
391 goto error_free_interface_names;
393 memset (*status, 0, sizeof (char *) * *interface_count);
395 for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
396 (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]);
397 if ((*(interface_names))[i] == NULL) {
398 error = SA_AIS_ERR_NO_MEMORY;
399 goto error_free_contents;
401 (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]);
402 if ((*(status))[i] == NULL) {
403 error = SA_AIS_ERR_NO_MEMORY;
404 goto error_free_contents;
407 goto no_error;
409 error_free_contents:
410 for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
411 if ((*(interface_names))[i]) {
412 free ((*(interface_names))[i]);
414 if ((*(status))[i]) {
415 free ((*(status))[i]);
419 free (*status);
421 error_free_interface_names:
422 free (*interface_names);
424 no_error:
425 saHandleInstancePut (&cfg_hdb, cfg_handle);
427 return (error);
430 SaAisErrorT
431 openais_cfg_ring_reenable (
432 openais_cfg_handle_t cfg_handle)
434 struct cfg_instance *cfg_instance;
435 struct req_lib_cfg_ringreenable req_lib_cfg_ringreenable;
436 struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable;
437 SaAisErrorT error;
439 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
440 if (error != SA_AIS_OK) {
441 return (error);
444 req_lib_cfg_ringreenable.header.size = sizeof (struct req_lib_cfg_ringreenable);
445 req_lib_cfg_ringreenable.header.id = MESSAGE_REQ_CFG_RINGREENABLE;
447 pthread_mutex_lock (&cfg_instance->response_mutex);
449 error = saSendReceiveReply (cfg_instance->response_fd,
450 &req_lib_cfg_ringreenable,
451 sizeof (struct req_lib_cfg_ringreenable),
452 &res_lib_cfg_ringreenable,
453 sizeof (struct res_lib_cfg_ringreenable));
455 pthread_mutex_unlock (&cfg_instance->response_mutex);
456 saHandleInstancePut (&cfg_hdb, cfg_handle);
458 return (error);
461 SaAisErrorT
462 openais_cfg_state_track (
463 openais_cfg_handle_t cfg_handle,
464 SaUint8T trackFlags,
465 const OpenaisCfgStateNotificationT *notificationBuffer)
467 struct cfg_instance *cfg_instance;
468 struct req_lib_cfg_statetrack req_lib_cfg_statetrack;
469 struct res_lib_cfg_statetrack res_lib_cfg_statetrack;
470 SaAisErrorT error;
472 req_lib_cfg_statetrack.header.size = sizeof (struct req_lib_cfg_statetrack);
473 req_lib_cfg_statetrack.header.id = MESSAGE_REQ_CFG_STATETRACKSTART;
474 req_lib_cfg_statetrack.trackFlags = trackFlags;
475 req_lib_cfg_statetrack.notificationBufferAddress = (OpenaisCfgStateNotificationT *)notificationBuffer;
477 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
478 (void *)&cfg_instance);
479 if (error != SA_AIS_OK) {
480 return (error);
483 pthread_mutex_lock (&cfg_instance->response_mutex);
485 error = saSendReceiveReply (cfg_instance->response_fd,
486 &req_lib_cfg_statetrack,
487 sizeof (struct req_lib_cfg_statetrack),
488 &res_lib_cfg_statetrack,
489 sizeof (struct res_lib_cfg_statetrack));
491 pthread_mutex_unlock (&cfg_instance->response_mutex);
493 saHandleInstancePut (&cfg_hdb, cfg_handle);
495 return (error == SA_AIS_OK ? res_lib_cfg_statetrack.header.error : error);
498 SaAisErrorT
499 openais_cfg_state_track_stop (
500 openais_cfg_handle_t cfg_handle)
502 struct cfg_instance *cfg_instance;
503 struct req_lib_cfg_statetrackstop req_lib_cfg_statetrackstop;
504 struct res_lib_cfg_statetrackstop res_lib_cfg_statetrackstop;
505 SaAisErrorT error;
507 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
508 (void *)&cfg_instance);
509 if (error != SA_AIS_OK) {
510 return (error);
513 req_lib_cfg_statetrackstop.header.size = sizeof (struct req_lib_cfg_statetrackstop);
514 req_lib_cfg_statetrackstop.header.id = MESSAGE_REQ_CFG_STATETRACKSTOP;
516 pthread_mutex_lock (&cfg_instance->response_mutex);
518 error = saSendReceiveReply (cfg_instance->response_fd,
519 &req_lib_cfg_statetrackstop,
520 sizeof (struct req_lib_cfg_statetrackstop),
521 &res_lib_cfg_statetrackstop,
522 sizeof (struct res_lib_cfg_statetrackstop));
524 pthread_mutex_unlock (&cfg_instance->response_mutex);
526 saHandleInstancePut (&cfg_hdb, cfg_handle);
528 return (error == SA_AIS_OK ? res_lib_cfg_statetrackstop.header.error : error);
531 SaAisErrorT
532 openais_cfg_admin_state_get (
533 openais_cfg_handle_t cfg_handle,
534 OpenaisCfgAdministrativeTargetT administrativeTarget,
535 OpenaisCfgAdministrativeStateT *administrativeState)
537 struct cfg_instance *cfg_instance;
538 struct req_lib_cfg_administrativestateget req_lib_cfg_administrativestateget;
539 struct res_lib_cfg_administrativestateget res_lib_cfg_administrativestateget;
540 SaAisErrorT error;
542 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
543 (void *)&cfg_instance);
544 if (error != SA_AIS_OK) {
545 return (error);
548 req_lib_cfg_administrativestateget.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET;
549 req_lib_cfg_administrativestateget.header.size = sizeof (struct req_lib_cfg_administrativestateget);
550 req_lib_cfg_administrativestateget.administrativeTarget = administrativeTarget;
552 error = saSendReceiveReply (cfg_instance->response_fd,
553 &req_lib_cfg_administrativestateget,
554 sizeof (struct req_lib_cfg_administrativestateget),
555 &res_lib_cfg_administrativestateget,
556 sizeof (struct res_lib_cfg_administrativestateget));
558 error = res_lib_cfg_administrativestateget.header.error;
560 pthread_mutex_unlock (&cfg_instance->response_mutex);
562 saHandleInstancePut (&cfg_hdb, cfg_handle);
564 return (error == SA_AIS_OK ? res_lib_cfg_administrativestateget.header.error : error);
567 SaAisErrorT
568 openais_cfg_admin_state_set (
569 openais_cfg_handle_t cfg_handle,
570 OpenaisCfgAdministrativeTargetT administrativeTarget,
571 OpenaisCfgAdministrativeStateT administrativeState)
573 struct cfg_instance *cfg_instance;
574 struct req_lib_cfg_administrativestateset req_lib_cfg_administrativestateset;
575 struct res_lib_cfg_administrativestateset res_lib_cfg_administrativestateset;
576 SaAisErrorT error;
578 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
579 (void *)&cfg_instance);
580 if (error != SA_AIS_OK) {
581 return (error);
584 req_lib_cfg_administrativestateset.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET;
585 req_lib_cfg_administrativestateset.header.size = sizeof (struct req_lib_cfg_administrativestateset);
586 req_lib_cfg_administrativestateset.administrativeTarget = administrativeTarget;
587 req_lib_cfg_administrativestateset.administrativeState = administrativeState;
589 error = saSendReceiveReply (cfg_instance->response_fd,
590 &req_lib_cfg_administrativestateset,
591 sizeof (struct req_lib_cfg_administrativestateset),
592 &res_lib_cfg_administrativestateset,
593 sizeof (struct res_lib_cfg_administrativestateset));
595 error = res_lib_cfg_administrativestateset.header.error;
597 pthread_mutex_unlock (&cfg_instance->response_mutex);
599 saHandleInstancePut (&cfg_hdb, cfg_handle);
601 return (error == SA_AIS_OK ? res_lib_cfg_administrativestateset.header.error : error);