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 /*
28 * Copyright (c) 2018, Joyent, Inc.
29 */
30
31 /*
32 * syseventd client interfaces
33 */
34
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <stdarg.h>
38 #include <stddef.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <door.h>
42 #include <errno.h>
43 #include <strings.h>
44 #include <thread.h>
45 #include <pthread.h>
46 #include <synch.h>
47 #include <syslog.h>
48 #include <fcntl.h>
49 #include <stropts.h>
50 #include <locale.h>
51 #include <libsysevent.h>
52 #include <sys/stat.h>
53 #include <sys/sysevent.h>
54
55 #include "syseventd.h"
56 #include "message.h"
57
58 /*
59 * sysevent_client.c - contains routines particular to syseventd client
60 * management (addition and deletion).
61 */
62
63 /* Global client table and lock */
64 struct sysevent_client *sysevent_client_tbl[MAX_SLM];
65 mutex_t client_tbl_lock;
66
67 /*
68 * initialize_client_tbl - Initialize each client entry in the syseventd
69 * client table. Each entry in the client table
70 * entry represents one shared-object (SLM) client.
71 */
72 void
initialize_client_tbl()73 initialize_client_tbl()
74 {
75 struct sysevent_client *scp;
76 int i;
77
78 for (i = 0; i < MAX_SLM; ++i) {
79 if ((scp = (struct sysevent_client *)malloc(
80 sizeof (struct sysevent_client))) == NULL)
81 goto init_error;
82
83 if (mutex_init(&scp->client_lock, USYNC_THREAD, NULL) != 0)
84 goto init_error;
85
86 scp->client_data = NULL;
87 scp->client_num = i;
88 scp->eventq = NULL;
89
90 /* Clear all flags when setting UNLOADED */
91 scp->client_flags = SE_CLIENT_UNLOADED;
92
93 sysevent_client_tbl[i] = scp;
94 }
95
96 return;
97
98 init_error:
99 syseventd_err_print(INIT_CLIENT_TBL_ERR);
100 syseventd_exit(1);
101 }
102
103 /*
104 * insert_client - called when a new SLM is loaded with syseventd. The
105 * client specific data is updated to reflect this addition
106 */
107 int
insert_client(void * client_data,int client_type,int retry_limit)108 insert_client(void *client_data, int client_type, int retry_limit)
109 {
110 int i;
111 struct sysevent_client *scp;
112
113 (void) mutex_lock(&client_tbl_lock);
114 for (i = 0; i < MAX_SLM; ++i) {
115 scp = sysevent_client_tbl[i];
116 if (scp->client_data == NULL) {
117 (void) mutex_lock(&scp->client_lock);
118 scp->client_data = client_data;
119 scp->client_type = client_type;
120 scp->retry_limit = retry_limit;
121 scp->client_flags |= SE_CLIENT_LOADED;
122 (void) cond_init(&scp->client_cv, USYNC_THREAD,
123 NULL);
124 (void) mutex_unlock(&scp->client_lock);
125 (void) mutex_unlock(&client_tbl_lock);
126 return (i);
127 }
128 }
129
130 (void) mutex_unlock(&client_tbl_lock);
131 syseventd_print(1, "Unable to insert into syseventd client table\n");
132 return (-1);
133 }
134
135 /*
136 * delete_client - called to remove an SLM from the client table. Client
137 * removal may occur when syseventd terminates, receives
138 * a SIGHUP or the client must be force unloaded due
139 * it's unresponsive nature.
140 */
141 void
delete_client(int id)142 delete_client(int id)
143 {
144 struct sysevent_client *scp;
145
146 scp = sysevent_client_tbl[id];
147
148 free(scp->client_data);
149 scp->client_data = NULL;
150
151 /* Clear all flags when setting UNLOADED */
152 scp->client_flags = SE_CLIENT_UNLOADED;
153 (void) cond_destroy(&scp->client_cv);
154 bzero(&scp->client_cv, sizeof (cond_t));
155 }
156