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
initialize_client_tbl()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
insert_client(void * client_data,int client_type,int retry_limit)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
delete_client(int id)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