load and unload service engines at runtime.
[openais.git] / lib / cfg.c
blob119eeeb610ec7b680497ed9e904b4cbc348562d9
1 /*
2 * Copyright (c) 2002-2005 MontaVista Software, Inc.
3 * Copyright (c) 2006-2007 Red Hat, Inc.
5 * All rights reserved.
7 * Author: Steven Dake (sdake@mvista.com)
9 * This software licensed under BSD license, the text of which follows:
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
14 * - Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * - Neither the name of the MontaVista Software, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #include <signal.h>
42 #include <pthread.h>
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <sys/select.h>
46 #include <sys/un.h>
48 #include <saAis.h>
49 #include <cfg.h>
50 #include <mar_gen.h>
51 #include <ipc_gen.h>
52 #include <ipc_cfg.h>
53 #include <ais_util.h>
55 struct res_overlay {
56 mar_res_header_t header;
57 char data[4096];
61 * Data structure for instance data
63 struct cfg_instance {
64 int response_fd;
65 int dispatch_fd;
66 OpenaisCfgCallbacksT callbacks;
67 SaNameT compName;
68 int compRegistered;
69 int finalize;
70 pthread_mutex_t response_mutex;
71 pthread_mutex_t dispatch_mutex;
74 static void cfg_handleInstanceDestructor (void *);
77 * All instances in one database
79 static struct saHandleDatabase cfg_hdb = {
80 .handleCount = 0,
81 .handles = 0,
82 .mutex = PTHREAD_MUTEX_INITIALIZER,
83 .handleInstanceDestructor = cfg_handleInstanceDestructor
87 * Implementation
89 void cfg_handleInstanceDestructor (void *instance)
91 struct cfg_instance *cfg_instance = instance;
93 pthread_mutex_destroy (&cfg_instance->response_mutex);
94 pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
97 SaAisErrorT
98 openais_cfg_initialize (
99 openais_cfg_handle_t *cfg_handle,
100 const OpenaisCfgCallbacksT *cfgCallbacks)
102 struct cfg_instance *cfg_instance;
103 SaAisErrorT error = SA_AIS_OK;
105 error = saHandleCreate (&cfg_hdb, sizeof (struct cfg_instance), cfg_handle);
106 if (error != SA_AIS_OK) {
107 goto error_no_destroy;
110 error = saHandleInstanceGet (&cfg_hdb, *cfg_handle, (void *)&cfg_instance);
111 if (error != SA_AIS_OK) {
112 goto error_destroy;
115 cfg_instance->response_fd = -1;
117 cfg_instance->dispatch_fd = -1;
119 error = saServiceConnect (&cfg_instance->response_fd,
120 &cfg_instance->dispatch_fd, CFG_SERVICE);
121 if (error != SA_AIS_OK) {
122 goto error_put_destroy;
125 if (cfgCallbacks) {
126 memcpy (&cfg_instance->callbacks, cfgCallbacks, sizeof (OpenaisCfgCallbacksT));
129 pthread_mutex_init (&cfg_instance->response_mutex, NULL);
131 pthread_mutex_init (&cfg_instance->dispatch_mutex, NULL);
133 saHandleInstancePut (&cfg_hdb, *cfg_handle);
135 return (SA_AIS_OK);
137 error_put_destroy:
138 saHandleInstancePut (&cfg_hdb, *cfg_handle);
139 error_destroy:
140 saHandleDestroy (&cfg_hdb, *cfg_handle);
141 error_no_destroy:
142 return (error);
145 SaAisErrorT
146 openais_cfg_fd_get (
147 openais_cfg_handle_t cfg_handle,
148 SaSelectionObjectT *selectionObject)
150 struct cfg_instance *cfg_instance;
151 SaAisErrorT error;
153 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
154 if (error != SA_AIS_OK) {
155 return (error);
158 *selectionObject = cfg_instance->dispatch_fd;
160 saHandleInstancePut (&cfg_hdb, cfg_handle);
161 return (SA_AIS_OK);
164 SaAisErrorT
165 openais_cfg_dispatch (
166 openais_cfg_handle_t cfg_handle,
167 SaDispatchFlagsT dispatchFlags)
169 struct pollfd ufds;
170 int timeout = -1;
171 SaAisErrorT error;
172 int cont = 1; /* always continue do loop except when set to 0 */
173 int dispatch_avail;
174 struct cfg_instance *cfg_instance;
175 #ifdef COMPILE_OUT
176 struct res_lib_openais_healthcheckcallback *res_lib_openais_healthcheckcallback;
177 struct res_lib_openais_readinessstatesetcallback *res_lib_openais_readinessstatesetcallback;
178 struct res_lib_openais_csisetcallback *res_lib_openais_csisetcallback;
179 struct res_lib_openais_csiremovecallback *res_lib_openais_csiremovecallback;
180 struct res_lib_cfg_statetrackcallback *res_lib_cfg_statetrackcallback;
181 #endif
182 OpenaisCfgCallbacksT callbacks;
183 struct res_overlay dispatch_data;
185 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
186 (void *)&cfg_instance);
187 if (error != SA_AIS_OK) {
188 return (error);
192 * Timeout instantly for SA_DISPATCH_ALL
194 if (dispatchFlags == SA_DISPATCH_ALL) {
195 timeout = 0;
198 do {
200 * Read data directly from socket
202 ufds.fd = cfg_instance->dispatch_fd;
203 ufds.events = POLLIN;
204 ufds.revents = 0;
206 error = saPollRetry (&ufds, 1, timeout);
207 if (error != SA_AIS_OK) {
208 goto error_nounlock;
211 pthread_mutex_lock (&cfg_instance->dispatch_mutex);
213 error = saPollRetry (&ufds, 1, 0);
214 if (error != SA_AIS_OK) {
215 goto error_nounlock;
219 * Handle has been finalized in another thread
221 if (cfg_instance->finalize == 1) {
222 error = SA_AIS_OK;
223 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
224 goto error_unlock;
227 dispatch_avail = ufds.revents & POLLIN;
228 if (dispatch_avail == 0 && dispatchFlags == SA_DISPATCH_ALL) {
229 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
230 break; /* exit do while cont is 1 loop */
231 } else
232 if (dispatch_avail == 0) {
233 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
234 continue; /* next poll */
237 if (ufds.revents & POLLIN) {
239 * Queue empty, read response from socket
241 error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.header,
242 sizeof (mar_res_header_t));
243 if (error != SA_AIS_OK) {
244 goto error_unlock;
246 if (dispatch_data.header.size > sizeof (mar_res_header_t)) {
247 error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.data,
248 dispatch_data.header.size - sizeof (mar_res_header_t));
249 if (error != SA_AIS_OK) {
250 goto error_unlock;
253 } else {
254 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
255 continue;
259 * Make copy of callbacks, message data, unlock instance, and call callback
260 * A risk of this dispatch method is that the callback routines may
261 * operate at the same time that cfgFinalize has been called in another thread.
263 memcpy (&callbacks, &cfg_instance->callbacks, sizeof (OpenaisCfgCallbacksT));
264 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
267 * Dispatch incoming response
269 switch (dispatch_data.header.id) {
271 default:
272 error = SA_AIS_ERR_LIBRARY;
273 goto error_nounlock;
274 break;
278 * Determine if more messages should be processed
280 switch (dispatchFlags) {
281 case SA_DISPATCH_ONE:
282 cont = 0;
283 break;
284 case SA_DISPATCH_ALL:
285 break;
286 case SA_DISPATCH_BLOCKING:
287 break;
289 } while (cont);
291 error_unlock:
292 saHandleInstancePut (&cfg_hdb, cfg_handle);
293 error_nounlock:
294 return (error);
297 SaAisErrorT
298 openais_cfg_finalize (
299 openais_cfg_handle_t cfg_handle)
301 struct cfg_instance *cfg_instance;
302 SaAisErrorT error;
304 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
305 if (error != SA_AIS_OK) {
306 return (error);
309 pthread_mutex_lock (&cfg_instance->dispatch_mutex);
311 pthread_mutex_lock (&cfg_instance->response_mutex);
314 * Another thread has already started finalizing
316 if (cfg_instance->finalize) {
317 pthread_mutex_unlock (&cfg_instance->response_mutex);
318 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
319 saHandleInstancePut (&cfg_hdb, cfg_handle);
320 return (SA_AIS_ERR_BAD_HANDLE);
323 cfg_instance->finalize = 1;
325 pthread_mutex_unlock (&cfg_instance->response_mutex);
327 pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
329 pthread_mutex_destroy (&cfg_instance->response_mutex);
331 pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
333 saHandleDestroy (&cfg_hdb, cfg_handle);
335 if (cfg_instance->response_fd != -1) {
336 shutdown (cfg_instance->response_fd, 0);
337 close (cfg_instance->response_fd);
339 if (cfg_instance->dispatch_fd != -1) {
340 shutdown (cfg_instance->dispatch_fd, 0);
341 close (cfg_instance->dispatch_fd);
344 saHandleInstancePut (&cfg_hdb, cfg_handle);
346 return (error);
349 SaAisErrorT
350 openais_cfg_ring_status_get (
351 openais_cfg_handle_t cfg_handle,
352 char ***interface_names,
353 char ***status,
354 unsigned int *interface_count)
356 struct cfg_instance *cfg_instance;
357 struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget;
358 struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget;
359 unsigned int i;
360 SaAisErrorT error;
362 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
363 if (error != SA_AIS_OK) {
364 return (error);
367 req_lib_cfg_ringstatusget.header.size = sizeof (struct req_lib_cfg_ringstatusget);
368 req_lib_cfg_ringstatusget.header.id = MESSAGE_REQ_CFG_RINGSTATUSGET;
370 pthread_mutex_lock (&cfg_instance->response_mutex);
372 error = saSendReceiveReply (cfg_instance->response_fd,
373 &req_lib_cfg_ringstatusget,
374 sizeof (struct req_lib_cfg_ringstatusget),
375 &res_lib_cfg_ringstatusget,
376 sizeof (struct res_lib_cfg_ringstatusget));
378 pthread_mutex_unlock (&cfg_instance->response_mutex);
380 *interface_count = res_lib_cfg_ringstatusget.interface_count;
381 *interface_names = malloc (sizeof (char *) * *interface_count);
382 if (*interface_names == NULL) {
383 return (SA_AIS_ERR_NO_MEMORY);
385 memset (*interface_names, 0, sizeof (char *) * *interface_count);
387 *status = malloc (sizeof (char *) * *interface_count);
388 if (*status == NULL) {
389 error = SA_AIS_ERR_NO_MEMORY;
390 goto error_free_interface_names;
392 memset (*status, 0, sizeof (char *) * *interface_count);
394 for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
395 (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]);
396 if ((*(interface_names))[i] == NULL) {
397 error = SA_AIS_ERR_NO_MEMORY;
398 goto error_free_contents;
400 (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]);
401 if ((*(status))[i] == NULL) {
402 error = SA_AIS_ERR_NO_MEMORY;
403 goto error_free_contents;
406 goto no_error;
408 error_free_contents:
409 for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
410 if ((*(interface_names))[i]) {
411 free ((*(interface_names))[i]);
413 if ((*(status))[i]) {
414 free ((*(status))[i]);
418 free (*status);
420 error_free_interface_names:
421 free (*interface_names);
423 no_error:
424 saHandleInstancePut (&cfg_hdb, cfg_handle);
426 return (error);
429 SaAisErrorT
430 openais_cfg_ring_reenable (
431 openais_cfg_handle_t cfg_handle)
433 struct cfg_instance *cfg_instance;
434 struct req_lib_cfg_ringreenable req_lib_cfg_ringreenable;
435 struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable;
436 SaAisErrorT error;
438 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
439 if (error != SA_AIS_OK) {
440 return (error);
443 req_lib_cfg_ringreenable.header.size = sizeof (struct req_lib_cfg_ringreenable);
444 req_lib_cfg_ringreenable.header.id = MESSAGE_REQ_CFG_RINGREENABLE;
446 pthread_mutex_lock (&cfg_instance->response_mutex);
448 error = saSendReceiveReply (cfg_instance->response_fd,
449 &req_lib_cfg_ringreenable,
450 sizeof (struct req_lib_cfg_ringreenable),
451 &res_lib_cfg_ringreenable,
452 sizeof (struct res_lib_cfg_ringreenable));
454 pthread_mutex_unlock (&cfg_instance->response_mutex);
455 saHandleInstancePut (&cfg_hdb, cfg_handle);
457 return (error);
460 SaAisErrorT
461 openais_cfg_service_load (
462 openais_cfg_handle_t cfg_handle,
463 char *service_name,
464 unsigned int service_ver)
466 struct cfg_instance *cfg_instance;
467 struct req_lib_cfg_serviceload req_lib_cfg_serviceload;
468 struct res_lib_cfg_serviceload res_lib_cfg_serviceload;
469 SaAisErrorT error;
471 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
472 if (error != SA_AIS_OK) {
473 return (error);
476 req_lib_cfg_serviceload.header.size = sizeof (struct req_lib_cfg_serviceload);
477 req_lib_cfg_serviceload.header.id = MESSAGE_REQ_CFG_SERVICELOAD;
478 memset (&req_lib_cfg_serviceload.service_name, 0,
479 sizeof (req_lib_cfg_serviceload.service_name));
480 strncpy ((char *)req_lib_cfg_serviceload.service_name, service_name,
481 sizeof (req_lib_cfg_serviceload.service_name) - 1);
482 req_lib_cfg_serviceload.service_ver = service_ver;
484 pthread_mutex_lock (&cfg_instance->response_mutex);
486 error = saSendReceiveReply (cfg_instance->response_fd,
487 &req_lib_cfg_serviceload,
488 sizeof (struct req_lib_cfg_serviceload),
489 &res_lib_cfg_serviceload,
490 sizeof (struct res_lib_cfg_serviceload));
492 pthread_mutex_unlock (&cfg_instance->response_mutex);
493 saHandleInstancePut (&cfg_hdb, cfg_handle);
495 return (error);
498 SaAisErrorT
499 openais_cfg_service_unload (
500 openais_cfg_handle_t cfg_handle,
501 char *service_name,
502 unsigned int service_ver)
504 struct cfg_instance *cfg_instance;
505 struct req_lib_cfg_serviceunload req_lib_cfg_serviceunload;
506 struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload;
507 SaAisErrorT error;
509 error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
510 if (error != SA_AIS_OK) {
511 return (error);
514 req_lib_cfg_serviceunload.header.size = sizeof (struct req_lib_cfg_serviceunload);
515 req_lib_cfg_serviceunload.header.id = MESSAGE_REQ_CFG_SERVICEUNLOAD;
516 memset (&req_lib_cfg_serviceunload.service_name, 0,
517 sizeof (req_lib_cfg_serviceunload.service_name));
518 strncpy ((char *)req_lib_cfg_serviceunload.service_name, service_name,
519 sizeof (req_lib_cfg_serviceunload.service_name) - 1);
520 req_lib_cfg_serviceunload.service_ver = service_ver;
522 pthread_mutex_lock (&cfg_instance->response_mutex);
524 error = saSendReceiveReply (cfg_instance->response_fd,
525 &req_lib_cfg_serviceunload,
526 sizeof (struct req_lib_cfg_serviceunload),
527 &res_lib_cfg_serviceunload,
528 sizeof (struct res_lib_cfg_serviceunload));
530 pthread_mutex_unlock (&cfg_instance->response_mutex);
531 saHandleInstancePut (&cfg_hdb, cfg_handle);
533 return (error);
535 SaAisErrorT
536 openais_cfg_state_track (
537 openais_cfg_handle_t cfg_handle,
538 SaUint8T trackFlags,
539 const OpenaisCfgStateNotificationT *notificationBuffer)
541 struct cfg_instance *cfg_instance;
542 struct req_lib_cfg_statetrack req_lib_cfg_statetrack;
543 struct res_lib_cfg_statetrack res_lib_cfg_statetrack;
544 SaAisErrorT error;
546 req_lib_cfg_statetrack.header.size = sizeof (struct req_lib_cfg_statetrack);
547 req_lib_cfg_statetrack.header.id = MESSAGE_REQ_CFG_STATETRACKSTART;
548 req_lib_cfg_statetrack.trackFlags = trackFlags;
549 req_lib_cfg_statetrack.notificationBufferAddress = (OpenaisCfgStateNotificationT *)notificationBuffer;
551 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
552 (void *)&cfg_instance);
553 if (error != SA_AIS_OK) {
554 return (error);
557 pthread_mutex_lock (&cfg_instance->response_mutex);
559 error = saSendReceiveReply (cfg_instance->response_fd,
560 &req_lib_cfg_statetrack,
561 sizeof (struct req_lib_cfg_statetrack),
562 &res_lib_cfg_statetrack,
563 sizeof (struct res_lib_cfg_statetrack));
565 pthread_mutex_unlock (&cfg_instance->response_mutex);
567 saHandleInstancePut (&cfg_hdb, cfg_handle);
569 return (error == SA_AIS_OK ? res_lib_cfg_statetrack.header.error : error);
572 SaAisErrorT
573 openais_cfg_state_track_stop (
574 openais_cfg_handle_t cfg_handle)
576 struct cfg_instance *cfg_instance;
577 struct req_lib_cfg_statetrackstop req_lib_cfg_statetrackstop;
578 struct res_lib_cfg_statetrackstop res_lib_cfg_statetrackstop;
579 SaAisErrorT error;
581 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
582 (void *)&cfg_instance);
583 if (error != SA_AIS_OK) {
584 return (error);
587 req_lib_cfg_statetrackstop.header.size = sizeof (struct req_lib_cfg_statetrackstop);
588 req_lib_cfg_statetrackstop.header.id = MESSAGE_REQ_CFG_STATETRACKSTOP;
590 pthread_mutex_lock (&cfg_instance->response_mutex);
592 error = saSendReceiveReply (cfg_instance->response_fd,
593 &req_lib_cfg_statetrackstop,
594 sizeof (struct req_lib_cfg_statetrackstop),
595 &res_lib_cfg_statetrackstop,
596 sizeof (struct res_lib_cfg_statetrackstop));
598 pthread_mutex_unlock (&cfg_instance->response_mutex);
600 saHandleInstancePut (&cfg_hdb, cfg_handle);
602 return (error == SA_AIS_OK ? res_lib_cfg_statetrackstop.header.error : error);
605 SaAisErrorT
606 openais_cfg_admin_state_get (
607 openais_cfg_handle_t cfg_handle,
608 OpenaisCfgAdministrativeTargetT administrativeTarget,
609 OpenaisCfgAdministrativeStateT *administrativeState)
611 struct cfg_instance *cfg_instance;
612 struct req_lib_cfg_administrativestateget req_lib_cfg_administrativestateget;
613 struct res_lib_cfg_administrativestateget res_lib_cfg_administrativestateget;
614 SaAisErrorT error;
616 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
617 (void *)&cfg_instance);
618 if (error != SA_AIS_OK) {
619 return (error);
622 req_lib_cfg_administrativestateget.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET;
623 req_lib_cfg_administrativestateget.header.size = sizeof (struct req_lib_cfg_administrativestateget);
624 req_lib_cfg_administrativestateget.administrativeTarget = administrativeTarget;
626 error = saSendReceiveReply (cfg_instance->response_fd,
627 &req_lib_cfg_administrativestateget,
628 sizeof (struct req_lib_cfg_administrativestateget),
629 &res_lib_cfg_administrativestateget,
630 sizeof (struct res_lib_cfg_administrativestateget));
632 error = res_lib_cfg_administrativestateget.header.error;
634 pthread_mutex_unlock (&cfg_instance->response_mutex);
636 saHandleInstancePut (&cfg_hdb, cfg_handle);
638 return (error == SA_AIS_OK ? res_lib_cfg_administrativestateget.header.error : error);
641 SaAisErrorT
642 openais_cfg_admin_state_set (
643 openais_cfg_handle_t cfg_handle,
644 OpenaisCfgAdministrativeTargetT administrativeTarget,
645 OpenaisCfgAdministrativeStateT administrativeState)
647 struct cfg_instance *cfg_instance;
648 struct req_lib_cfg_administrativestateset req_lib_cfg_administrativestateset;
649 struct res_lib_cfg_administrativestateset res_lib_cfg_administrativestateset;
650 SaAisErrorT error;
652 error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
653 (void *)&cfg_instance);
654 if (error != SA_AIS_OK) {
655 return (error);
658 req_lib_cfg_administrativestateset.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET;
659 req_lib_cfg_administrativestateset.header.size = sizeof (struct req_lib_cfg_administrativestateset);
660 req_lib_cfg_administrativestateset.administrativeTarget = administrativeTarget;
661 req_lib_cfg_administrativestateset.administrativeState = administrativeState;
663 error = saSendReceiveReply (cfg_instance->response_fd,
664 &req_lib_cfg_administrativestateset,
665 sizeof (struct req_lib_cfg_administrativestateset),
666 &res_lib_cfg_administrativestateset,
667 sizeof (struct res_lib_cfg_administrativestateset));
669 error = res_lib_cfg_administrativestateset.header.error;
671 pthread_mutex_unlock (&cfg_instance->response_mutex);
673 saHandleInstancePut (&cfg_hdb, cfg_handle);
675 return (error == SA_AIS_OK ? res_lib_cfg_administrativestateset.header.error : error);