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.
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.
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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
29 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include <stdio_ext.h>
53 #include <sys/param.h>
55 #include <sys/types.h>
57 #include <librcm_impl.h>
59 #include "rcm_module.h"
63 * Daemon states for thread control
67 #define RCMD_CLEANUP 3
71 * flags for node operation
73 #define RSRC_NODE_CREATE 1
74 #define RSRC_NODE_REMOVE 2 /* not used */
79 #define RSRC_TYPE_NORMAL 0
80 #define RSRC_TYPE_DEVICE 1
81 #define RSRC_TYPE_FILESYS 2
82 #define RSRC_TYPE_ABSTRACT 3
85 * lock conflict checking flags
88 #define LOCK_FOR_USE 1
91 * Sequence number encoding constants
93 #define SEQ_NUM_SHIFT 8 /* lowest 8 bits indicate cascade operation */
94 #define SEQ_NUM_MASK ((1 << SEQ_NUM_SHIFT) - 1)
97 * RCM queuing structure
99 typedef struct rcm_queue
{
100 struct rcm_queue
*next
;
101 struct rcm_queue
*prev
;
104 #define RCM_STRUCT_BASE_ADDR(struct_type, x, y) \
105 ((struct_type *) ((void *)(((char *)(x)) - \
106 (int)(&((struct_type *)0)->y))))
109 * Struct for client loadable module
111 typedef struct module
{
114 struct rcm_mod_ops
*(*init
)();
115 const char *(*info
)();
117 struct rcm_mod_ops
*modops
; /* ops vector */
118 char *name
; /* module name */
119 rcm_handle_t
*rcmhandle
;
121 rcm_queue_t client_q
; /* list of module's clients */
122 struct script_info
*rsi
; /* scripting data */
126 * Struct for describing a resource client
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 */
140 * defines for client_t:prv_flags (used by rcm scripting)
142 #define RCM_NEED_TO_UNREGISTER 1
145 * Struct for a list of outstanding rcm requests
149 int n_req_max
; /* max entries in this block */
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 */
158 /* more entries may follow */
162 * struct for describing resource tree node
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 */
174 * struct for tree action args
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 */
187 * for synchrizing various threads
201 extern mutex_t rcm_req_lock
;
206 extern librcm_ops_t rcm_ops
; /* ops for module callback */
207 extern int need_cleanup
;
211 * EQUAL, AFTER, DESCENDENT
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] == '/')))
223 * function prototypes
226 /* top level request handling routines */
228 void event_service(void **, size_t *);
229 int process_resource_suspend(char **, pid_t
, uint_t
, int, timespec_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
*,
240 int request_capacity_change(char *, pid_t
, uint_t
, int, nvlist_t
*,
242 int notify_capacity_change(char *, pid_t
, uint_t
, int, nvlist_t
*,
244 int get_resource_state(char *, pid_t
, rcm_info_t
**);
245 rcm_info_t
*rsrc_mod_info();
247 /* dr request list routines */
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
**);
259 /* node related routines */
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 *);
268 /* tree related routines */
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
*);
273 /* database helpers and misc */
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);
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 *);
297 * RCM queuing function prototypes
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
*);
308 * Function protoypes related to rcm scripting
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
*);
321 #endif /* _RCM_IMPL_H */