rcm_impl.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _RCM_IMPL_H
#define _RCM_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <locale.h>
#include <poll.h>
#include <signal.h>
#include <strings.h>
#include <syslog.h>
#include <thread.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <librcm.h>
#include <librcm_impl.h>
#include "rcm_module.h"
/*
* Daemon states for thread control
*/
#define RCMD_INIT 1
#define RCMD_NORMAL 2
#define RCMD_CLEANUP 3
#define RCMD_FINI 4
/*
* flags for node operation
*/
#define RSRC_NODE_CREATE 1
#define RSRC_NODE_REMOVE 2 /* not used */
/*
* Resource types
*/
#define RSRC_TYPE_NORMAL 0
#define RSRC_TYPE_DEVICE 1
#define RSRC_TYPE_FILESYS 2
#define RSRC_TYPE_ABSTRACT 3
/*
* lock conflict checking flags
*/
#define LOCK_FOR_DR 0
#define LOCK_FOR_USE 1
/*
* Sequence number encoding constants
*/
#define SEQ_NUM_SHIFT 8 /* lowest 8 bits indicate cascade operation */
#define SEQ_NUM_MASK ((1 << SEQ_NUM_SHIFT) - 1)
/*
* RCM queuing structure
*/
typedef struct rcm_queue {
struct rcm_queue *next;
struct rcm_queue *prev;
} rcm_queue_t;
#define RCM_STRUCT_BASE_ADDR(struct_type, x, y) \
((struct_type *) ((void *)(((char *)(x)) - \
(int)(&((struct_type *)0)->y))))
/*
* Struct for client loadable module
*/
typedef struct module {
struct module *next;
void *dlhandle;
struct rcm_mod_ops *(*init)();
const char *(*info)();
int (*fini)();
struct rcm_mod_ops *modops; /* ops vector */
char *name; /* module name */
rcm_handle_t *rcmhandle;
int ref_count;
rcm_queue_t client_q; /* list of module's clients */
struct script_info *rsi; /* scripting data */
} module_t;
/*
* Struct for describing a resource client
*/
typedef struct client {
rcm_queue_t queue; /* per module queue */
struct client *next; /* next client on rsrc node list */
module_t *module; /* per-client module */
char *alias; /* rsrc_name known to client */
pid_t pid; /* pid of regis process */
int state; /* rsrc state known to client */
uint_t flag; /* flag specified for registration */
uint_t prv_flags; /* currently used by rcm scripting */
} client_t;
/*
* defines for client_t:prv_flags (used by rcm scripting)
*/
#define RCM_NEED_TO_UNREGISTER 1
/*
* Struct for a list of outstanding rcm requests
*/
typedef struct {
int n_req;
int n_req_max; /* max entries in this block */
struct {
int seq_num; /* sequence number of request */
int state; /* current state */
id_t id; /* id of initiator */
uint_t flag; /* request flags */
int type; /* resource(device) type */
char device[MAXPATHLEN]; /* name of device or resource */
} req[1];
/* more entries may follow */
} rcm_req_t;
/*
* struct for describing resource tree node
*/
typedef struct rsrc_node {
struct rsrc_node *parent;
struct rsrc_node *sibling;
struct rsrc_node *child;
char *name; /* phys path for devices */
client_t *users; /* linked list of users */
int type; /* resource type */
} rsrc_node_t;
/*
* struct for tree action args
*/
typedef struct {
int cmd; /* command */
int seq_num; /* unique sequence number */
int retcode; /* return code */
uint_t flag; /* flag assoc. w command */
timespec_t *interval; /* for suspend command */
nvlist_t *nvl; /* for state changes */
rcm_info_t **info; /* info to be filled in */
} tree_walk_arg_t;
/*
* for synchrizing various threads
*/
typedef struct {
int thr_count;
short wanted;
short state;
time_t last_update;
cond_t cv;
mutex_t lock;
} barrier_t;
/*
* locks
*/
extern mutex_t rcm_req_lock;
/*
* global variables
*/
extern librcm_ops_t rcm_ops; /* ops for module callback */
extern int need_cleanup;
/*
* comparison macros
* EQUAL, AFTER, DESCENDENT
*/
#define EQUAL(x, y) (strcmp(x, y) == 0)
#define AFTER(x, y) (strcmp(x, y) > 0)
#define DESCENDENT(x, y) \
((strlen(x) > strlen(y)) && \
(strncmp(x, y, strlen(y)) == 0) && \
((x[strlen(y)] == '/') || \
(x[strlen(y)] == ':') || \
(x[strlen(y) - 1] == '/')))
/*
* function prototypes
*/
/* top level request handling routines */
void event_service(void **, size_t *);
int process_resource_suspend(char **, pid_t, uint_t, int, timespec_t *,
rcm_info_t **);
int notify_resource_resume(char **, pid_t, uint_t, int, rcm_info_t **);
int process_resource_offline(char **, pid_t, uint_t, int, rcm_info_t **);
int notify_resource_online(char **, pid_t, uint_t, int, rcm_info_t **);
int notify_resource_remove(char **, pid_t, uint_t, int, rcm_info_t **);
int add_resource_client(char *, char *, pid_t, uint_t, rcm_info_t **);
int remove_resource_client(char *, char *, pid_t, uint_t);
int get_resource_info(char **, uint_t, int, rcm_info_t **);
int notify_resource_event(char *, pid_t, uint_t, int, nvlist_t *,
rcm_info_t **);
int request_capacity_change(char *, pid_t, uint_t, int, nvlist_t *,
rcm_info_t **);
int notify_capacity_change(char *, pid_t, uint_t, int, nvlist_t *,
rcm_info_t **);
int get_resource_state(char *, pid_t, rcm_info_t **);
rcm_info_t *rsrc_mod_info();
/* dr request list routines */
rcm_info_t *rsrc_dr_info();
void clean_dr_list();
int dr_req_add(char *, pid_t, uint_t, int, int, timespec_t *, rcm_info_t **);
int dr_req_update(char *, pid_t, uint_t, int, int, rcm_info_t **);
int dr_req_lookup(int, char *);
void dr_req_remove(char *, uint_t);
int info_req_add(char *, uint_t, int);
void info_req_remove(int);
int rsrc_check_lock_conflicts(char *, uint_t, int, rcm_info_t **);
/* node related routines */
int rsrc_get_type(const char *);
int rsrc_node_find(char *, int, rsrc_node_t **);
int rsrc_node_add_user(rsrc_node_t *, char *, char *, pid_t, uint_t);
int rsrc_node_remove_user(rsrc_node_t *, char *, pid_t, uint_t);
client_t *rsrc_client_find(char *, pid_t, client_t **);
int rsrc_client_action_list(client_t *, int cmd, void *);
/* tree related routines */
int rsrc_usage_info(char **, uint_t, int, rcm_info_t **);
int rsrc_tree_action(rsrc_node_t *, int, tree_walk_arg_t *);
/* database helpers and misc */
void rcmd_set_state(int);
int rcmd_thr_incr(int);
void rcmd_thr_decr(void);
void rcmd_thr_signal(void);
void rcmd_lock_init(void);
void rcmd_db_init(void);
void rcmd_db_sync(void);
void rcmd_db_clean(void);
void rcmd_start_timer(int);
void rcmd_exit(int);
void rcm_log_message(int, char *, ...);
void rcm_log_msg(int, char *, ...);
void add_busy_rsrc_to_list(char *, pid_t, int, int, char *, const char *,
const char *, nvlist_t *, rcm_info_t **);
char *resolve_name(char *);
int proc_exist(pid_t);
void *s_malloc(size_t);
void *s_calloc(int, size_t);
void *s_realloc(void *, size_t);
char *s_strdup(const char *);
/*
* RCM queuing function prototypes
*/
void rcm_init_queue(rcm_queue_t *);
void rcm_enqueue_head(rcm_queue_t *, rcm_queue_t *);
void rcm_enqueue_tail(rcm_queue_t *, rcm_queue_t *);
void rcm_enqueue(rcm_queue_t *, rcm_queue_t *);
rcm_queue_t *rcm_dequeue_head(rcm_queue_t *);
rcm_queue_t *rcm_dequeue_tail(rcm_queue_t *);
void rcm_dequeue(rcm_queue_t *);
/*
* Function protoypes related to rcm scripting
*/
int script_main_init(void);
int script_main_fini(void);
struct rcm_mod_ops *script_init(module_t *);
char *script_info(module_t *);
int script_fini(module_t *);
#ifdef __cplusplus
}
#endif
#endif /* _RCM_IMPL_H */