xref: /titanic_41/usr/src/uts/common/sys/lvm/md_notify.h (revision e4d060fb4c00d44cd578713eb9a921f594b733b8)
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 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_MD_NOTIFY_H
28 #define	_SYS_MD_NOTIFY_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/lvm/mdvar.h>
33 #include <sys/proc.h>
34 #include <sys/lvm/md_mirror_shared.h>
35 #include <sys/time.h>
36 
37 #ifdef	__cplusplus
38 extern "C" {
39 #endif
40 
41 #define	MD_EVENT_ID		(0xda1eab1e)
42 #define	MD_ALLSETS		((ulong_t)0xffffffff)
43 #define	MD_ALLDEVS		((ulong_t)0xffffffff)
44 #define	MD_NOTIFY_HALT_TRIES	(4)
45 #define	MD_NOTIFY_NAME_SIZE	(64)
46 #define	MD_NOTIFY_REVISION	1
47 
48 /* mdn_flags bits in struct md_event_queue */
49 
50 #define	MD_EVENT_QUEUE_DESTROY	(0x00000001)
51 #define	MD_EVENT_QUEUE_INVALID	(0x00000002)
52 #define	MD_EVENT_QUEUE_PERM	(0x00000004) /* do not delete when proc dies */
53 #define	MD_EVENT_QUEUE_FULL	(0x00000008)
54 
55 typedef enum md_event_type {
56 
57 	EQ_EMPTY = 0,
58 
59 	/* Configuration Changes */
60 	EQ_CREATE = 1,
61 	EQ_DELETE,
62 	EQ_ADD,
63 	EQ_REMOVE,
64 	EQ_REPLACE,
65 	EQ_GROW,
66 	EQ_RENAME_SRC,
67 	EQ_RENAME_DST,
68 
69 	EQ_MEDIATOR_ADD,
70 	EQ_MEDIATOR_DELETE,
71 	EQ_HOST_ADD,
72 	EQ_HOST_DELETE,
73 	EQ_DRIVE_ADD,
74 	EQ_DRIVE_DELETE,
75 
76 	/* State Changes */
77 	EQ_INIT_START = 0x00000400,
78 	EQ_INIT_FAILED,
79 	EQ_INIT_FATAL,
80 	EQ_INIT_SUCCESS,
81 	EQ_IOERR,
82 	EQ_ERRED,
83 	EQ_LASTERRED,
84 	EQ_OK,
85 	EQ_ENABLE,
86 	EQ_RESYNC_START,
87 	EQ_RESYNC_FAILED,
88 	EQ_RESYNC_SUCCESS,	/* resync has succeeded */
89 	EQ_RESYNC_DONE,		/* resync completed */
90 	EQ_HOTSPARED,		/* hot spare aquired for use */
91 	EQ_HS_FREED,		/* hotspare no longer in use */
92 	EQ_HS_CHANGED,		/* change of metadevice hotspare pool */
93 	EQ_TAKEOVER,
94 	EQ_RELEASE,
95 	EQ_OPEN_FAIL,
96 	EQ_OFFLINE,
97 	EQ_ONLINE,
98 	EQ_DETACH,
99 	EQ_DETACHING,
100 	EQ_ATTACH,
101 	EQ_ATTACHING,
102 	EQ_CHANGE,
103 	EQ_EXCHANGE,
104 	EQ_REGEN_START,
105 	EQ_REGEN_DONE,
106 	EQ_REGEN_FAILED,
107 
108 	/* User defined event */
109 	EQ_USER = 0x00100000,
110 
111 	/* Notify Specfic */
112 	EQ_NOTIFY_LOST,
113 	EQ_LAST }
114 	md_event_type_t;
115 
116 typedef enum md_event_cmds {
117 	EQ_NONE =	0x00000000,
118 	EQ_ON =		0x00000001,
119 	EQ_OFF =	0x00000002,
120 	EQ_GET_NOWAIT =	0x00000010,
121 	EQ_GET_WAIT =	0x00000040,
122 	EQ_PUT =	0x00000020,
123 
124 	EQ_ALLVALID =	0x00000073
125 	}md_event_cmds_t;
126 
127 typedef enum md_tags {
128 	TAG_EMPTY,
129 	TAG_METADEVICE,
130 	TAG_REPLICA,
131 	TAG_HSP,
132 	TAG_HS,
133 	TAG_SET,
134 	TAG_DRIVE,
135 	TAG_HOST,
136 	TAG_MEDIATOR,
137 	TAG_UNK,
138 	TAG_LAST
139 } md_tags_t;
140 
141 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
142 #pragma pack(4)
143 #endif
144 typedef struct md_event_ioctl {
145 	MD_DRIVER
146 	md_error_t	mde;		/* error return */
147 	uint_t		mdn_magic;	/* magic number for structure */
148 	int		mdn_rev;	/* revision number */
149 	char		mdn_name[MD_NOTIFY_NAME_SIZE];
150 					/* queue name */
151 	int		mdn_flags;	/* ioctl flags */
152 	md_event_cmds_t	mdn_cmd;	/* command value */
153 	md_tags_t	mdn_tag;	/* object tag */
154 	set_t		mdn_set;	/* set number */
155 	md_dev64_t	mdn_dev;	/* device event occurred on */
156 	md_event_type_t	mdn_event;	/* event */
157 	u_longlong_t	mdn_user;	/* user defined event */
158 	md_timeval32_t	mdn_time;	/* time stamp of event */
159 } md_event_ioctl_t;
160 
161 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
162 #pragma pack()
163 #endif
164 
165 /* ioctl flags */
166 #define	EQ_Q_PERM	(0x00000001)	/* do not delete when proc dies */
167 
168 #define	EQ_Q_ALLVALID	(0x00000001)	/* all valid notify ioctl flags */
169 
170 typedef enum notify_cmds_t
171 	{ EQ_LIST_ADD = 1, EQ_LIST_DELETE }
172 	notify_cmds_t;
173 
174 typedef struct notify {
175 	notify_cmds_t	mdn_cmd;	/* list function (add/delete) */
176 	md_tags_t	mdn_tag;	/* type of object */
177 	set_t		mdn_set;	/* set where event occurred */
178 	md_dev64_t	mdn_dev;	/* device that event occurred on */
179 	md_event_type_t	mdn_event;	/* event */
180 }notify_t;
181 
182 
183 #ifdef _KERNEL
184 
185 #define	NOTIFY_MD(tag, set, dev, event) 				\
186 	(void) md_notify_interface(EQ_PUT, (tag), (set), (dev), (event))
187 
188 #define	SE_NOTIFY(se_class, se_subclass, tag, set, dev)		\
189 	svm_gen_sysevent((se_class), (se_subclass), (tag), (set), (dev))
190 
191 typedef struct md_event {
192 	struct md_event *mdn_next;	/* pointer to next element */
193 	md_tags_t	mdn_tag;	/* object type */
194 	set_t		mdn_set;	/* set where event occurred */
195 	md_dev64_t	mdn_dev;	/* device that event occurred on */
196 	md_event_type_t	mdn_event;	/* event */
197 	u_longlong_t	mdn_user;	/* user defined event */
198 	struct timeval	mdn_time;	/* time stamp of event */
199 }md_event_t;
200 
201 typedef struct md_event_queue {
202 	struct md_event_queue	*mdn_nextq;	/* next event queue */
203 	char		mdn_name[MD_NOTIFY_NAME_SIZE];
204 					/* queue name */
205 	int		mdn_flags;	/* queue flags */
206 	pid_t		mdn_pid;	/* pid that created the queue */
207 	proc_t		*mdn_proc;	/* process that created the queue */
208 	uid_t		mdn_uid;	/* uid of queue creator */
209 	size_t		mdn_size;	/* size of the queue in elements */
210 	md_event_t	*mdn_front;	/* front element in queue */
211 	md_event_t	*mdn_tail;	/* last element of queue */
212 	int		mdn_waiting;	/* number of process waiting */
213 	kcondvar_t	mdn_cv;		/* waiting condition varaible */
214 } md_event_queue_t;
215 
216 /*
217  * The remainder of this file defines items that are used for testing
218  * md_notify.
219  */
220 
221 /*
222  * Named services for testing
223  */
224 
225 #define	MD_NOTIFY_REAP_OFF	"notify turn reap off"
226 #define	MD_NOTIFY_REAP_ON	"notify turn reap on"
227 #define	MD_NOTIFY_TEST_STATS	"notify test statistics"
228 
229 /*
230  * The MD_NOTIFY_TEST_STATS named service can be invoked to get md_notify
231  * to set the values of this structure.  The md_tnotify module uses this
232  * structure.
233  */
234 
235 typedef struct md_notify_stats {
236 	kmutex_t	*mds_eventq_mx;	/* Address of mutex protecting */
237 					/*   event queue. */
238 	int		mds_max_queue;	/* Max. # events in notify queue. */
239 	int		mds_reap;	/* events since last reap. */
240 	int		mds_reap_count;	/* # events between reaps. */
241 	int		mds_reap_off;	/* non-zero -> reaping is off. */
242 } md_notify_stats_t;
243 
244 #endif	/* _KERNEL */
245 
246 #ifdef	__cplusplus
247 }
248 #endif
249 
250 #endif	/* _SYS_MD_NOTIFY_H */
251