xref: /titanic_50/usr/src/cmd/rcm_daemon/common/rcm_impl.h (revision 0b5ce10aee80822ecc7df77df92a5e24078ba196)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _RCM_IMPL_H
27 #define	_RCM_IMPL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #ifdef	__cplusplus
32 extern "C" {
33 #endif
34 
35 #include <assert.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdio_ext.h>
39 #include <stdlib.h>
40 #include <dirent.h>
41 #include <dlfcn.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <limits.h>
45 #include <locale.h>
46 #include <poll.h>
47 #include <signal.h>
48 #include <strings.h>
49 #include <syslog.h>
50 #include <thread.h>
51 #include <unistd.h>
52 #include <sys/mman.h>
53 #include <sys/param.h>
54 #include <sys/stat.h>
55 #include <sys/types.h>
56 #include <librcm.h>
57 #include <librcm_impl.h>
58 
59 #include "rcm_module.h"
60 
61 
62 /*
63  * Daemon states for thread control
64  */
65 #define	RCMD_INIT	1
66 #define	RCMD_NORMAL	2
67 #define	RCMD_CLEANUP	3
68 #define	RCMD_FINI	4
69 
70 /*
71  * flags for node operation
72  */
73 #define	RSRC_NODE_CREATE	1
74 #define	RSRC_NODE_REMOVE	2	/* not used */
75 
76 /*
77  * Resource types
78  */
79 #define	RSRC_TYPE_NORMAL	0
80 #define	RSRC_TYPE_DEVICE	1
81 #define	RSRC_TYPE_FILESYS	2
82 #define	RSRC_TYPE_ABSTRACT	3
83 
84 /*
85  * lock conflict checking flags
86  */
87 #define	LOCK_FOR_DR		0
88 #define	LOCK_FOR_USE		1
89 
90 /*
91  * Sequence number encoding constants
92  */
93 #define	SEQ_NUM_SHIFT	8	/* lowest 8 bits indicate cascade operation */
94 #define	SEQ_NUM_MASK	((1 << SEQ_NUM_SHIFT) - 1)
95 
96 /*
97  * RCM queuing structure
98  */
99 typedef struct rcm_queue {
100 	struct rcm_queue	*next;
101 	struct rcm_queue	*prev;
102 } rcm_queue_t;
103 
104 #define	RCM_STRUCT_BASE_ADDR(struct_type, x, y)		\
105 	((struct_type *) ((void *)(((char *)(x)) -	\
106 			(int)(&((struct_type *)0)->y))))
107 
108 /*
109  * Struct for client loadable module
110  */
111 typedef struct module {
112 	struct module	*next;
113 	void		*dlhandle;
114 	struct rcm_mod_ops *(*init)();
115 	const char	*(*info)();
116 	int		(*fini)();
117 	struct rcm_mod_ops *modops;	/* ops vector */
118 	char		*name;		/* module name */
119 	rcm_handle_t	*rcmhandle;
120 	int		ref_count;
121 	rcm_queue_t	client_q;	/* list of module's clients */
122 	struct script_info *rsi;	/* scripting data */
123 } module_t;
124 
125 /*
126  * Struct for describing a resource client
127  */
128 typedef struct client {
129 	rcm_queue_t	queue;		/* per module queue */
130 	struct client	*next;		/* next client on rsrc node list */
131 	module_t	*module;	/* per-client module */
132 	char		*alias;		/* rsrc_name known to client */
133 	pid_t		pid;		/* pid of regis process */
134 	int		state;		/* rsrc state known to client */
135 	uint_t		flag;		/* flag specified for registration */
136 	uint_t		prv_flags;	/* currently used by rcm scripting */
137 } client_t;
138 
139 /*
140  * defines for client_t:prv_flags (used by rcm scripting)
141  */
142 #define	RCM_NEED_TO_UNREGISTER	1
143 
144 /*
145  * Struct for a list of outstanding rcm requests
146  */
147 typedef struct {
148 	int	n_req;
149 	int	n_req_max;	/* max entries in this block */
150 	struct {
151 		int	seq_num;		/* sequence number of request */
152 		int	state;			/* current state */
153 		id_t	id;			/* id of initiator */
154 		uint_t	flag;			/* request flags */
155 		int	type;			/* resource(device) type */
156 		char	device[MAXPATHLEN];	/* name of device or resource */
157 	} req[1];
158 	/* more entries may follow */
159 } rcm_req_t;
160 
161 /*
162  * struct for describing resource tree node
163  */
164 typedef struct rsrc_node {
165 	struct rsrc_node	*parent;
166 	struct rsrc_node	*sibling;
167 	struct rsrc_node	*child;
168 	char			*name;		/* phys path for devices */
169 	client_t		*users;		/* linked list of users */
170 	int			type;		/* resource type */
171 } rsrc_node_t;
172 
173 /*
174  * struct for tree action args
175  */
176 typedef struct {
177 	int cmd;		/* command */
178 	int seq_num;		/* unique sequence number */
179 	int retcode;		/* return code */
180 	uint_t flag;		/* flag assoc. w command */
181 	timespec_t *interval;	/* for suspend command */
182 	nvlist_t *nvl;		/* for state changes */
183 	rcm_info_t **info;	/* info to be filled in */
184 } tree_walk_arg_t;
185 
186 /*
187  * for synchrizing various threads
188  */
189 typedef struct {
190 	int thr_count;
191 	short wanted;
192 	short state;
193 	time_t last_update;
194 	cond_t cv;
195 	mutex_t lock;
196 } barrier_t;
197 
198 /*
199  * locks
200  */
201 extern mutex_t rcm_req_lock;
202 
203 /*
204  * global variables
205  */
206 extern librcm_ops_t rcm_ops;	/* ops for module callback */
207 extern int need_cleanup;
208 
209 /*
210  * comparison macros
211  *	EQUAL, AFTER, DESCENDENT
212  */
213 #define	EQUAL(x, y)	(strcmp(x, y) == 0)
214 #define	AFTER(x, y)	(strcmp(x, y) > 0)
215 #define	DESCENDENT(x, y)			\
216 	((strlen(x) > strlen(y)) &&		\
217 	(strncmp(x, y, strlen(y)) == 0) &&	\
218 	((x[strlen(y)] == '/') ||		\
219 	(x[strlen(y)] == ':') ||		\
220 	(x[strlen(y) - 1] == '/')))
221 
222 /*
223  * function prototypes
224  */
225 
226 /* top level request handling routines */
227 
228 void event_service(void **, size_t *);
229 int process_resource_suspend(char **, pid_t, uint_t, int, timespec_t *,
230     rcm_info_t **);
231 int notify_resource_resume(char **, pid_t, uint_t, int, rcm_info_t **);
232 int process_resource_offline(char **, pid_t, uint_t, int, rcm_info_t **);
233 int notify_resource_online(char **, pid_t, uint_t, int, rcm_info_t **);
234 int notify_resource_remove(char **, pid_t, uint_t, int, rcm_info_t **);
235 int add_resource_client(char *, char *, pid_t, uint_t, rcm_info_t **);
236 int remove_resource_client(char *, char *, pid_t, uint_t);
237 int get_resource_info(char **, uint_t, int, rcm_info_t **);
238 int notify_resource_event(char *, pid_t, uint_t, int, nvlist_t *,
239     rcm_info_t **);
240 int request_capacity_change(char *, pid_t, uint_t, int, nvlist_t *,
241     rcm_info_t **);
242 int notify_capacity_change(char *, pid_t, uint_t, int, nvlist_t *,
243     rcm_info_t **);
244 int get_resource_state(char *, pid_t, rcm_info_t **);
245 rcm_info_t *rsrc_mod_info();
246 
247 /* dr request list routines */
248 
249 rcm_info_t *rsrc_dr_info();
250 void clean_dr_list();
251 int dr_req_add(char *, pid_t, uint_t, int, int, timespec_t *, rcm_info_t **);
252 int dr_req_update(char *, pid_t, uint_t, int, int, rcm_info_t **);
253 int dr_req_lookup(int, char *);
254 void dr_req_remove(char *, uint_t);
255 int info_req_add(char *, uint_t, int);
256 void info_req_remove(int);
257 int rsrc_check_lock_conflicts(char *, uint_t, int, rcm_info_t **);
258 
259 /* node related routines */
260 
261 int rsrc_get_type(const char *);
262 int rsrc_node_find(char *, int, rsrc_node_t **);
263 int rsrc_node_add_user(rsrc_node_t *, char *, char *, pid_t, uint_t);
264 int rsrc_node_remove_user(rsrc_node_t *, char *, pid_t, uint_t);
265 client_t *rsrc_client_find(char *, pid_t, client_t **);
266 int rsrc_client_action_list(client_t *, int cmd, void *);
267 
268 /* tree related routines */
269 
270 int rsrc_usage_info(char **, uint_t, int, rcm_info_t **);
271 int rsrc_tree_action(rsrc_node_t *, int, tree_walk_arg_t *);
272 
273 /* database helpers and misc */
274 
275 void rcmd_set_state(int);
276 int rcmd_thr_incr(int);
277 void rcmd_thr_decr(void);
278 void rcmd_thr_signal(void);
279 void rcmd_lock_init(void);
280 void rcmd_db_init(void);
281 void rcmd_db_sync(void);
282 void rcmd_db_clean(void);
283 void rcmd_start_timer(int);
284 void rcmd_exit(int);
285 void rcm_log_message(int, char *, ...);
286 void rcm_log_msg(int, char *, ...);
287 void add_busy_rsrc_to_list(char *, pid_t, int, int, char *, const char *,
288 	const char *, nvlist_t *, rcm_info_t **);
289 char *resolve_name(char *);
290 int proc_exist(pid_t);
291 void *s_malloc(size_t);
292 void *s_calloc(int, size_t);
293 void *s_realloc(void *, size_t);
294 char *s_strdup(const char *);
295 
296 /*
297  * RCM queuing function prototypes
298  */
299 void rcm_init_queue(rcm_queue_t *);
300 void rcm_enqueue_head(rcm_queue_t *, rcm_queue_t *);
301 void rcm_enqueue_tail(rcm_queue_t *, rcm_queue_t *);
302 void rcm_enqueue(rcm_queue_t *, rcm_queue_t *);
303 rcm_queue_t *rcm_dequeue_head(rcm_queue_t *);
304 rcm_queue_t *rcm_dequeue_tail(rcm_queue_t *);
305 void rcm_dequeue(rcm_queue_t *);
306 
307 /*
308  * Function protoypes related to rcm scripting
309  */
310 int script_main_init(void);
311 int script_main_fini(void);
312 struct rcm_mod_ops *script_init(module_t *);
313 char *script_info(module_t *);
314 int script_fini(module_t *);
315 
316 
317 #ifdef	__cplusplus
318 }
319 #endif
320 
321 #endif /* _RCM_IMPL_H */
322