1724365f7Ssethg /*
2724365f7Ssethg  * CDDL HEADER START
3724365f7Ssethg  *
4724365f7Ssethg  * The contents of this file are subject to the terms of the
5724365f7Ssethg  * Common Development and Distribution License (the "License").
6724365f7Ssethg  * You may not use this file except in compliance with the License.
7724365f7Ssethg  *
8724365f7Ssethg  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9724365f7Ssethg  * or http://www.opensolaris.org/os/licensing.
10724365f7Ssethg  * See the License for the specific language governing permissions
11724365f7Ssethg  * and limitations under the License.
12724365f7Ssethg  *
13724365f7Ssethg  * When distributing Covered Code, include this CDDL HEADER in each
14724365f7Ssethg  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15724365f7Ssethg  * If applicable, add the following below this CDDL HEADER, with the
16724365f7Ssethg  * fields enclosed by brackets "[]" replaced with your own identifying
17724365f7Ssethg  * information: Portions Copyright [yyyy] [name of copyright owner]
18724365f7Ssethg  *
19724365f7Ssethg  * CDDL HEADER END
20724365f7Ssethg  */
21724365f7Ssethg 
22724365f7Ssethg /*
2324db4641Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24724365f7Ssethg  * Use is subject to license terms.
25*0244979bSAlek Pinchuk  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
26724365f7Ssethg  */
27724365f7Ssethg 
28724365f7Ssethg #ifndef _DISKMOND_CONF_H
29724365f7Ssethg #define	_DISKMOND_CONF_H
30724365f7Ssethg 
31724365f7Ssethg /*
32724365f7Ssethg  * Configuration File data
33724365f7Ssethg  */
34724365f7Ssethg 
35724365f7Ssethg #ifdef __cplusplus
36724365f7Ssethg extern "C" {
37724365f7Ssethg #endif
38724365f7Ssethg 
39724365f7Ssethg #include <sys/types.h>
40724365f7Ssethg #include <pthread.h>
41724365f7Ssethg #include <libnvpair.h>
42724365f7Ssethg #include <fm/fmd_api.h>
43724365f7Ssethg #include "dm_types.h"
44724365f7Ssethg #include "util.h"
45724365f7Ssethg 
46724365f7Ssethg #ifndef MIN
47724365f7Ssethg #define	MIN(x, y) ((x) < (y) ? (x) : (y))
48724365f7Ssethg #endif
49724365f7Ssethg 
50724365f7Ssethg #ifndef MAX
51724365f7Ssethg #define	MAX(x, y) ((x) > (y) ? (x) : (y))
52724365f7Ssethg #endif
53724365f7Ssethg 
54724365f7Ssethg #define	DEVICES_PREFIX "/devices"
55724365f7Ssethg 
56724365f7Ssethg #define	GLOBAL_PROP_LOG_LEVEL		"log-level"
57724365f7Ssethg 
58724365f7Ssethg /* Property names (and values) for the disk configuration file entity */
59724365f7Ssethg #define	DISK_PROP_DEVPATH		"dev-path"
60724365f7Ssethg #define	DISK_PROP_LOGNAME		"logical-path"
61724365f7Ssethg #define	DISK_PROP_FRUACTION		"fru-update-action"
62724365f7Ssethg #define	DISK_PROP_OTEMPACTION		"overtemp-action"
63724365f7Ssethg #define	DISK_PROP_STFAILACTION		"selftest-fail-action"
64*0244979bSAlek Pinchuk #define	DISK_PROP_SSMWEAROUTACTION	"ssm-wearout-action"
65724365f7Ssethg 
66724365f7Ssethg /* Properties for the "ap" subentity */
67724365f7Ssethg #define	DISK_AP_PROP_APID "path"
68724365f7Ssethg 
69724365f7Ssethg #define	DEVPATH_MINOR_SEPARATOR ':'
70724365f7Ssethg 
71724365f7Ssethg #define	DEFAULT_FAULT_POLLING_INTERVAL 3600	/* seconds */
72724365f7Ssethg 
73724365f7Ssethg #define	INDICATOR_FAULT_IDENTIFIER "FAULT"
74724365f7Ssethg 
75724365f7Ssethg typedef enum conf_err_e {
76724365f7Ssethg 	E_NO_ERROR = 0,
77724365f7Ssethg 	E_MULTIPLE_IND_LISTS_DEFINED,
78724365f7Ssethg 	E_MULTIPLE_INDRULE_LISTS_DEFINED,
79724365f7Ssethg 	E_INVALID_STATE_CHANGE,
80724365f7Ssethg 	E_IND_MULTIPLY_DEFINED,
81724365f7Ssethg 	E_IND_ACTION_REDUNDANT,
82724365f7Ssethg 	E_IND_ACTION_CONFLICT,
83724365f7Ssethg 	E_IND_MISSING_FAULT_ON,
84724365f7Ssethg 	E_IND_MISSING_FAULT_OFF,
85724365f7Ssethg 	E_INDRULE_REFERENCES_NONEXISTENT_IND_ACTION,
86724365f7Ssethg 	E_DUPLICATE_STATE_TRANSITION
87724365f7Ssethg } conf_err_t;
88724365f7Ssethg 
89724365f7Ssethg typedef enum {
90724365f7Ssethg 	INDICATOR_UNKNOWN,
91724365f7Ssethg 	INDICATOR_ON,
92724365f7Ssethg 	INDICATOR_OFF
93724365f7Ssethg } ind_state_t;
94724365f7Ssethg 
95724365f7Ssethg typedef enum {
96724365f7Ssethg 	TS_NOT_RUNNING,
97724365f7Ssethg 	TS_RUNNING,
98724365f7Ssethg 	TS_EXIT_REQUESTED,
99724365f7Ssethg 	TS_EXITED
100724365f7Ssethg } thread_state_t;
101724365f7Ssethg 
102724365f7Ssethg typedef struct ind_action {
103724365f7Ssethg 	ind_state_t		ind_state;
104724365f7Ssethg 	char			*ind_name;
105724365f7Ssethg 	struct ind_action	*next;
106724365f7Ssethg } ind_action_t;
107724365f7Ssethg 
108724365f7Ssethg typedef struct state_transition {
109724365f7Ssethg 	hotplug_state_t		begin;
110724365f7Ssethg 	hotplug_state_t		end;
111724365f7Ssethg } state_transition_t;
112724365f7Ssethg 
113724365f7Ssethg typedef struct indrule {
114724365f7Ssethg 	state_transition_t	strans;
115724365f7Ssethg 	ind_action_t 		*action_list;
116724365f7Ssethg 	struct indrule 		*next;
117724365f7Ssethg } indrule_t;
118724365f7Ssethg 
119724365f7Ssethg typedef struct indicator {
120724365f7Ssethg 	ind_state_t		ind_state;
121724365f7Ssethg 	char			*ind_name;
122724365f7Ssethg 	char			*ind_instr_spec;
123724365f7Ssethg 	struct indicator	*next;
124724365f7Ssethg } indicator_t;
125724365f7Ssethg 
126724365f7Ssethg typedef struct diskmon {
127724365f7Ssethg 	/*
128724365f7Ssethg 	 * Static configuration data
129724365f7Ssethg 	 */
130724365f7Ssethg 	nvlist_t		*props;
131724365f7Ssethg 	char			*location;	/* descriptive location */
132724365f7Ssethg 	nvlist_t		*app_props;
133724365f7Ssethg 	indicator_t		*ind_list;
134724365f7Ssethg 	indrule_t		*indrule_list;
135724365f7Ssethg 	/*
136724365f7Ssethg 	 * Dynamic data
137724365f7Ssethg 	 */
138724365f7Ssethg 	hotplug_state_t		state;
139724365f7Ssethg 
140724365f7Ssethg 	/*
141724365f7Ssethg 	 * Only one manager can be manipulating the
142724365f7Ssethg 	 * state in the diskmon at one time (either the
143724365f7Ssethg 	 * state-change manager or the fault-polling manager)
144724365f7Ssethg 	 */
145724365f7Ssethg 	pthread_mutex_t		manager_mutex;
146724365f7Ssethg 
147724365f7Ssethg 	/*
148724365f7Ssethg 	 * Set to true only during initialization, and
149724365f7Ssethg 	 * cleared the next time a fru update needs to
150724365f7Ssethg 	 * occur, this flag enabled an optimization of
151724365f7Ssethg 	 * NOT calling libtopo for a configuration update
152724365f7Ssethg 	 * when the DE starts up.  This allows a HUGE
153724365f7Ssethg 	 * savings (since only a single snapshot-- the
154724365f7Ssethg 	 * initial snapshot) is used as the source of
155724365f7Ssethg 	 * the FRU information.
156724365f7Ssethg 	 */
157724365f7Ssethg 	boolean_t		initial_configuration;
158724365f7Ssethg 
15924db4641Seschrock 	/* For the state-change manager: */
160724365f7Ssethg 
161724365f7Ssethg 	/*
16224db4641Seschrock 	 * Current state of the fault indicator.
163724365f7Ssethg 	 */
164724365f7Ssethg 	pthread_mutex_t		fault_indicator_mutex;
165724365f7Ssethg 	ind_state_t		fault_indicator_state;
166724365f7Ssethg 
167724365f7Ssethg 	/*
168724365f7Ssethg 	 * Set to TRUE when a disk transitions to the CONFIGURED state
16924db4641Seschrock 	 * and remains TRUE until the disk is physically removed.
170724365f7Ssethg 	 */
171724365f7Ssethg 	boolean_t		configured_yet;
172724365f7Ssethg 
173724365f7Ssethg 	/*
174724365f7Ssethg 	 * The number of disk hotplug state transitions since the disk
175724365f7Ssethg 	 * was inserted.
176724365f7Ssethg 	 */
177724365f7Ssethg 	uint_t			state_change_count;
178724365f7Ssethg 
179724365f7Ssethg 	/* Disk FRU (model, manufacturer, etc) information */
180724365f7Ssethg 	pthread_mutex_t		fru_mutex;
181724365f7Ssethg 	dm_fru_t		*frup;
182724365f7Ssethg 
183724365f7Ssethg 	struct diskmon		*next;
184724365f7Ssethg } diskmon_t;
185724365f7Ssethg 
186724365f7Ssethg typedef struct cfgdata {
187724365f7Ssethg 	nvlist_t 		*props;
188724365f7Ssethg 	diskmon_t		*disk_list;
189724365f7Ssethg } cfgdata_t;
190724365f7Ssethg 
191724365f7Ssethg typedef struct namevalpr {
192724365f7Ssethg 	char 			*name;
193724365f7Ssethg 	char 			*value;
194724365f7Ssethg } namevalpr_t;
195724365f7Ssethg 
196724365f7Ssethg 
197724365f7Ssethg extern indicator_t 	*new_indicator(ind_state_t lstate, char *namep,
198724365f7Ssethg     char *actionp);
199724365f7Ssethg extern void		link_indicator(indicator_t **first,
200724365f7Ssethg     indicator_t *to_add);
201724365f7Ssethg extern void		ind_free(indicator_t *indp);
202724365f7Ssethg 
203724365f7Ssethg extern ind_action_t 	*new_indaction(ind_state_t state, char *namep);
204724365f7Ssethg extern void		link_indaction(ind_action_t **first,
205724365f7Ssethg     ind_action_t *to_add);
206724365f7Ssethg extern void		indaction_free(ind_action_t *lap);
207724365f7Ssethg 
208724365f7Ssethg extern indrule_t 	*new_indrule(state_transition_t *st,
209724365f7Ssethg     ind_action_t *actionp);
210724365f7Ssethg extern void		link_indrule(indrule_t **first, indrule_t *to_add);
211724365f7Ssethg extern void		indrule_free(indrule_t *lrp);
212724365f7Ssethg 
213724365f7Ssethg extern diskmon_t	*new_diskmon(nvlist_t *app_props, indicator_t *indp,
214724365f7Ssethg     indrule_t *indrp, nvlist_t *nvlp);
215724365f7Ssethg extern void		diskmon_free(diskmon_t *dmp);
216724365f7Ssethg 
217724365f7Ssethg extern dm_fru_t 	*new_dmfru(char *manu, char *modl, char *firmrev,
218724365f7Ssethg     char *serno, uint64_t capa);
219724365f7Ssethg extern void		dmfru_free(dm_fru_t *frup);
220724365f7Ssethg 
221724365f7Ssethg extern nvlist_t 	*namevalpr_to_nvlist(namevalpr_t *nvprp);
222724365f7Ssethg 
223724365f7Ssethg extern conf_err_t	check_state_transition(hotplug_state_t s1,
224724365f7Ssethg     hotplug_state_t s2);
225724365f7Ssethg extern conf_err_t	check_inds(indicator_t *indp);
226724365f7Ssethg extern conf_err_t	check_indactions(ind_action_t *indap);
227724365f7Ssethg extern conf_err_t	check_indrules(indrule_t *indrp,
228724365f7Ssethg     state_transition_t **offender);
229724365f7Ssethg extern conf_err_t	check_consistent_ind_indrules(indicator_t *indp,
230724365f7Ssethg     indrule_t *indrp, ind_action_t **offender);
231724365f7Ssethg 
232724365f7Ssethg extern void		cfgdata_add_diskmon(cfgdata_t *cfgp, diskmon_t *dmp);
233724365f7Ssethg 
234724365f7Ssethg extern void		conf_error_msg(conf_err_t err, char *buf, int buflen,
235724365f7Ssethg     void *arg);
236724365f7Ssethg 
237724365f7Ssethg extern const char	*dm_prop_lookup(nvlist_t *props, const char *prop_name);
238724365f7Ssethg extern int		dm_prop_lookup_int(nvlist_t *props,
239724365f7Ssethg     const char *prop_name, int *value);
240724365f7Ssethg 
241724365f7Ssethg extern int		config_init(void);
242724365f7Ssethg extern int		config_get(fmd_hdl_t *hdl, const fmd_prop_t *fmd_props);
243724365f7Ssethg extern void		config_fini(void);
244724365f7Ssethg 
245724365f7Ssethg extern const char *hotplug_state_string(hotplug_state_t state);
246724365f7Ssethg 
247724365f7Ssethg extern nvlist_t	*dm_global_proplist(void);
248724365f7Ssethg 
249724365f7Ssethg #ifdef __cplusplus
250724365f7Ssethg }
251724365f7Ssethg #endif
252724365f7Ssethg 
253724365f7Ssethg #endif /* _DISKMOND_CONF_H */
254