xref: /illumos-gate/usr/src/cmd/syseventd/daemons/syseventd/sysevent_client.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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