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