1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2000-2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * syseventd client interfaces 31 */ 32 33 #include <stdio.h> 34 #include <sys/types.h> 35 #include <stdarg.h> 36 #include <stddef.h> 37 #include <stdlib.h> 38 #include <unistd.h> 39 #include <door.h> 40 #include <errno.h> 41 #include <strings.h> 42 #include <thread.h> 43 #include <pthread.h> 44 #include <synch.h> 45 #include <syslog.h> 46 #include <fcntl.h> 47 #include <stropts.h> 48 #include <locale.h> 49 #include <libsysevent.h> 50 #include <sys/stat.h> 51 #include <sys/sysevent.h> 52 53 #include "syseventd.h" 54 #include "message.h" 55 56 /* 57 * sysevent_client.c - contains routines particular to syseventd client 58 * management (addition and deletion). 59 */ 60 61 /* Global client table and lock */ 62 struct sysevent_client *sysevent_client_tbl[MAX_SLM]; 63 mutex_t client_tbl_lock; 64 65 /* 66 * initialize_client_tbl - Initialize each client entry in the syseventd 67 * client table. Each entry in the client table 68 * entry represents one shared-object (SLM) client. 69 */ 70 void 71 initialize_client_tbl() 72 { 73 struct sysevent_client *scp; 74 int i; 75 76 for (i = 0; i < MAX_SLM; ++i) { 77 if ((scp = (struct sysevent_client *)malloc( 78 sizeof (struct sysevent_client))) == NULL) 79 goto init_error; 80 81 if (mutex_init(&scp->client_lock, USYNC_THREAD, NULL) != 0) 82 goto init_error; 83 84 scp->client_data = NULL; 85 scp->client_num = i; 86 scp->eventq = NULL; 87 88 /* Clear all flags when setting UNLOADED */ 89 scp->client_flags = SE_CLIENT_UNLOADED; 90 91 sysevent_client_tbl[i] = scp; 92 } 93 94 return; 95 96 init_error: 97 syseventd_err_print(INIT_CLIENT_TBL_ERR); 98 syseventd_exit(1); 99 } 100 101 /* 102 * insert_client - called when a new SLM is loaded with syseventd. The 103 * client specific data is updated to reflect this addition 104 */ 105 int 106 insert_client(void *client_data, int client_type, int retry_limit) 107 { 108 int i; 109 struct sysevent_client *scp; 110 111 (void) mutex_lock(&client_tbl_lock); 112 for (i = 0; i < MAX_SLM; ++i) { 113 scp = sysevent_client_tbl[i]; 114 if (scp->client_data == NULL) { 115 (void) mutex_lock(&scp->client_lock); 116 scp->client_data = client_data; 117 scp->client_type = client_type; 118 scp->retry_limit = retry_limit; 119 scp->client_flags |= SE_CLIENT_LOADED; 120 (void) cond_init(&scp->client_cv, USYNC_THREAD, 121 NULL); 122 (void) mutex_unlock(&scp->client_lock); 123 (void) mutex_unlock(&client_tbl_lock); 124 return (i); 125 } 126 } 127 128 (void) mutex_unlock(&client_tbl_lock); 129 syseventd_print(1, "Unable to insert into syseventd client table\n"); 130 return (-1); 131 } 132 133 /* 134 * delete_client - called to remove an SLM from the client table. Client 135 * removal may occur when syseventd terminates, receives 136 * a SIGHUP or the client must be force unloaded due 137 * it's unresponsive nature. 138 */ 139 void 140 delete_client(int id) 141 { 142 struct sysevent_client *scp; 143 144 scp = sysevent_client_tbl[id]; 145 146 free(scp->client_data); 147 scp->client_data = NULL; 148 149 /* Clear all flags when setting UNLOADED */ 150 scp->client_flags = SE_CLIENT_UNLOADED; 151 (void) cond_destroy(&scp->client_cv); 152 bzero(&scp->client_cv, sizeof (cond_t)); 153 } 154