mdio.h revision 1945:74cee1cd404b
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef	_SYS__MDIO_H
27#define	_SYS__MDIO_H
28
29#pragma ident	"%Z%%M%	%I%	%E% SMI"
30
31#include <sys/debug.h>
32#include <sys/ioctl.h>
33#include <sys/types.h>
34#include <sys/int_types.h>
35#include <sys/dditypes.h>
36#ifdef _KERNEL
37#include <sys/lvm/md_mdiox.h>
38#else /* !_KERNEL */
39#include <mdiox.h>
40#endif
41#include <sys/ddipropdefs.h>
42#include <sys/hwconf.h>
43
44#ifdef	__cplusplus
45extern "C" {
46#endif
47
48/*
49 * driver version number
50 */
51#define	MD_DVERSION	0x00040003	/* major.minor */
52#define	MD_SET_SHIFT	(NBITSMINOR32 - MD_BITSSET)
53#define	MD_MAXUNITS	(1 << MD_SET_SHIFT)
54#define	MD_UNIT_MASK	(MD_MAXUNITS - 1)
55
56#define	MD_MIN2UNIT(m)	((m) & MD_UNIT_MASK)
57#define	MD_MIN2SET(m)	((m) >> MD_SET_SHIFT)
58#define	MD_SID(u)	((u)->c.un_self_id)
59#define	MD_RECID(u)	((u)->c.un_record_id)
60#define	MD_STATUS(u)	((u)->c.un_status)
61#define	MD_PARENT(u)	((u)->c.un_parent)
62#define	MD_CAPAB(u)	((u)->c.un_capabilities)
63#define	MD_UN2SET(u)	MD_MIN2SET(MD_SID(u))
64#define	MD_UL2SET(l)	MD_MIN2SET(MAXMIN32 & ((l)->un_dev))
65
66#define	MD_MKMIN(s, u)	((((s) & MD_SETMASK) << MD_SET_SHIFT) | \
67			((u) & MD_UNIT_MASK))
68
69#define	HSP_BITSID	31
70#define	HSP_SET_SHIFT	(HSP_BITSID - MD_BITSSET)
71#define	HSP_SET_MASK	(MD_SETMASK << HSP_SET_SHIFT)
72#define	HSP_SET(hspid)	(((hspid) & HSP_SET_MASK) >> HSP_SET_SHIFT)
73#define	HSP_ID(hspid)	((hspid) & ~HSP_SET_MASK)
74#define	MAKE_HSP_ID(setno, id)  (((setno) << HSP_SET_SHIFT) | (id))
75
76/*
77 * The following macros were added to support friendly names for hot spare
78 * pools.  Before the addition of friendly names the hsp_self_id was merely
79 * the conbination of the set number and the hot spare pool number.  With
80 * friendly names a NM record is created to hold the hot spare pool name.
81 * The hsp_self_id now becomes the set number shifted left plus the NM
82 * record key plus 1000.  The number 1000 is used to collision between
83 * traditional hsp_self_ids and friendly name self ids.  In traditional hot
84 * spare pool the hot spare pool number could never be grater than 999.
85 *
86 * HSP_ID_IS_FN(hspid)	returns TRUE if the hot spare pool ID is the ID of
87 * 			a friendly named hsp.  Will return FALSE otherwise.
88 * 			hspid may contain the set bits, since HSP_ID_IS_FN
89 * 			will call HSP_ID as part of doing its work.
90 *
91 * KEY_TO_HSP_ID(setno, reckey)	constructs a hot spare pool ID (hsp_t) from
92 * 			a set number and a NM record key.  The result is
93 * 			suitable for storing in the hsp_self_id member of a
94 * 			hot_spare_pool struct.
95 *
96 * HSP_ID_TO_KEY(hspid)	returns the NM key that is encoded in the hot spare
97 * 			pool ID.  MD_KEYBAD will be returned if hspid does
98 * 			not represent a friendly named hsp.  hspid may
99 * 			contain the set bits, since HSP_ID_TO_KEY will call
100 * 			HSP_ID as part of doing its work.
101 *
102 * HSP_KEY_OK(reckey)	Insures that the NM record key is not so large as
103 * 			to interfere with the set number bits in a hot
104 * 			spare pool self id.  This macro will probably only
105 * 			be used in meta_hs_add.
106 */
107#define	HSP_FN_BASE	(1000)
108#define	HSP_ID_IS_FN(hspid) (HSP_ID(hspid) > HSP_FN_BASE)
109#define	KEY_TO_HSP_ID(setno, key) ((setno << HSP_SET_SHIFT) | \
110					(key + HSP_FN_BASE))
111#define	HSP_ID_TO_KEY(hspid) ((HSP_ID_IS_FN(hspid)) ? \
112				(HSP_ID(hspid) - HSP_FN_BASE) : MD_KEYBAD)
113#define	HSP_KEY_OK(key)	(((key + HSP_FN_BASE) & HSP_SET_MASK) == 0)
114
115/*
116 * for did stat ioctl
117 */
118#define	MD_FIND_INVDID	0x01
119#define	MD_GET_INVDID	0x02
120
121/*
122 * for setting the un_revision, hsp_revision and hs_revision
123 */
124#define	MD_64BIT_META_DEV	0x01
125#define	MD_FN_META_DEV		0x02	/* Friendly named metadevice */
126
127/*
128 * for trans EOF error messages
129 */
130#define	MD_EOF_TRANS_MSG	"Trans logging has been replaced by UFS" \
131	" Logging.\nSee mount_ufs(1M). Operation failed.\n"
132
133#define	MD_SHORT_EOF_TRANS_MSG	"#Trans logging has been replaced by UFS" \
134	" Logging.\n#See mount_ufs(1M). Operation failed.\n"
135
136#define	MD_EOF_TRANS_WARNING	"Existing Trans devices are not logging; they" \
137	"\npass data directly to the underlying device.\n"
138
139#define	MD_SHORT_EOF_TRANS_WARNING	"#Existing Trans devices are not " \
140	"logging; they\n#pass data directly to the underlying device.\n"
141
142/*
143 * for importing of disksets (IMP_LOAD)
144 */
145#define	MD_IMP_STALE_SET	1
146
147/*
148 * miscname stuff
149 */
150
151#define	MD_DRIVERNAMELEN	16
152#define	MD_SETDRIVERNAME(to, from, setno) \
153	if ((from) != NULL) \
154		(void) strcpy((to)->md_driver.md_drivername, (from)); \
155	(to)->md_driver.md_setno = (setno);
156
157
158#define	MD_GETDRIVERNAME(to, from) \
159	(void) strcpy((to), (from)->md_driver.md_drivername);
160
161#define	MD_PNTDRIVERNAME(from) \
162	((from)->md_driver.md_drivername)
163
164/*
165 * ioctl parameter structures
166 */
167
168#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
169#pragma pack(4)
170#endif
171typedef struct md_i_driverinfo {
172	MD_DRIVER
173	md_error_t	mde;
174	minor_t		mnum;
175} md_i_driverinfo_t;
176
177typedef struct md_i_getnext {
178	MD_DRIVER
179	md_error_t	mde;
180	minor_or_hsp_t	id;
181} md_i_getnext_t;
182
183typedef struct md_i_getnum {
184	MD_DRIVER
185	md_error_t	mde;
186	int		start;
187	int		size;
188	uint64_t	minors;	/* Pointer to minor #'s */
189} md_i_getnum_t;
190
191typedef struct md_i_get {
192	MD_DRIVER
193	md_error_t	mde;
194	minor_or_hsp_t	id;
195	int		size;
196	uint64_t	mdp;	/* Contains pointer */
197} md_i_get_t;
198
199typedef struct md_i_reset {
200	MD_DRIVER
201	md_error_t	mde;
202	minor_t		mnum;		/* Unit to clear */
203	int		force;
204} md_i_reset_t;
205
206/* soft partition reset parameters */
207typedef struct md_sp_reset {
208	MD_DRIVER
209	md_error_t	mde;		/* Error return */
210	minor_t		mnum;		/* Unit to clear */
211	int		force;		/* Force reset */
212	md_parent_t	new_parent;	/* New parent for child component */
213} md_sp_reset_t;
214
215/* soft partition status change parameters */
216typedef struct md_sp_statusset {
217	MD_DRIVER
218	md_error_t	mde;		/* Error return */
219	int		num_units;	/* Number of units */
220	int		new_status;	/* New status */
221	int		size;		/* Array size */
222	uint64_t	minors;		/* Pointer to array of minor numbers */
223} md_sp_statusset_t;
224
225typedef struct md_sp_update_wm {
226	MD_DRIVER
227	md_error_t	mde;		/* Error return */
228	minor_t		mnum;		/* Unit to update */
229	uint_t		count;		/* Number of watermarks */
230	uint64_t	wmp;		/* Pointer to array of watermarks */
231	uint64_t	osp;		/* Pointer to array of offsets */
232} md_sp_update_wm_t;
233
234typedef struct md_sp_read_wm {
235	MD_DRIVER
236	md_error_t	mde;		/* Error return */
237	md_dev64_t	rdev;		/* Device from which to read */
238	uint64_t	wmp;		/* Pointer to wm buffer */
239	xsp_offset_t	offset;		/* Offset of wm */
240} md_sp_read_wm_t;
241
242typedef struct md_set_userflags {
243	MD_DRIVER
244	md_error_t	mde;
245	minor_t		mnum;
246	uint_t		userflags;
247} md_set_userflags_t;
248
249typedef struct md_stripe_params {
250	MD_DRIVER
251	md_error_t	mde;		/* Error return */
252	minor_t		mnum;
253	ms_params_t	params;
254} md_stripe_params_t;
255
256typedef struct md_raid_params {
257	MD_DRIVER
258	md_error_t	mde;		/* Error return */
259	minor_t		mnum;
260	mr_params_t	params;
261} md_raid_params_t;
262
263typedef struct md_mirror_params {
264	MD_DRIVER
265	md_error_t	mde;		/* Error return */
266	minor_t		mnum;
267	mm_params_t	params;
268} md_mirror_params_t;
269
270typedef struct md_grow_params {
271	MD_DRIVER
272	md_error_t	mde;	/* Error return */
273	minor_t		mnum;	/* Unit to grow */
274	int		options; /* create a 64 or 32 bit device */
275	uint64_t	mdp;	/* Optional - pointer to new unit struct */
276	int		size;	/* Optional - size of new unit struct */
277	int		nrows;	/* Optional - original number of rows */
278	int		npar;	/* Optional - number of parents to lock */
279	uint64_t	par;	/* Optional - pointer to parent units */
280} md_grow_params_t;
281
282/* if the didstat struct changes you will need to change the following macro */
283typedef struct md_i_didstat {
284	md_error_t	mde;	/* Error return */
285	set_t		setno;	/* which set to use */
286	side_t		side;	/* which side to use */
287	int		mode;	/* find or get ? */
288	int		cnt;	/* return number of invalid devid's found */
289	int		maxsz;	/* return max size of invalid device id */
290	uint64_t	ctdp;	/* pointer to structure to fill with ctds */
291} md_i_didstat_t;
292
293typedef struct mdnm_params {
294	md_error_t	mde;		/* Error return */
295	char		drvnm[MD_MAXDRVNM];  /* drvnm for get/set/rem nm */
296	major_t		major;		/* major #, (alternative) for get nm */
297	minor_t		mnum;		/* minor #, for get/set/rem nm */
298	uint_t		devname_len;	/* Length of device name, for set nm */
299	uint64_t	devname;	/* Address of device name for set/get */
300	set_t		setno;		/* Which namespace set to use */
301	side_t		side;		/* -1 == current side, >0 specified */
302	mdkey_t		key;		/* 0 == alloc one, else use this key */
303	mdkey_t		retkey;		/* return key here! */
304	ushort_t	devid_size;	/* 0 == ret size, else use this one */
305	uint64_t	devid;		/* pointer to devid, supplied by user */
306	uint_t		pathname_len;	/* length of pathname */
307	uint64_t	pathname;	/* address of pathname for update */
308	md_dev64_t	devt;		/* devt for updating namespace */
309	ushort_t	minorname_len;	/* length of minor name */
310	uint64_t	minorname;	/* address of minor name */
311	uint_t		ref_count;	/* returned n_count */
312	int		imp_flag;	/* used by metaimport */
313} mdnm_params_t;
314
315typedef struct mdhspnm_params {
316	md_error_t	mde;		/* Error return */
317	char		drvnm[MD_MAXDRVNM];  /* drvnm for get/set/rem nm */
318	uint_t		hspname_len;	/* Length of device name, for set nm */
319	uint64_t	hspname;	/* Address of device name for set/get */
320	set_t		setno;		/* Which namespace set to use */
321	side_t		side;		/* -1 == current side, >0 specified */
322	hsp_t		hspid;		/* 0 == alloc one, else use this key */
323	hsp_t		ret_hspid;	/* return key here! */
324	uint_t		ref_count;	/* returned n_count */
325} mdhspnm_params_t;
326
327typedef struct md_getdevs_params {
328	MD_DRIVER
329	md_error_t	mde;
330	minor_t		mnum;
331	int		cnt;
332	uint64_t	devs;	/* Pointer to devs */
333} md_getdevs_params_t;
334
335
336typedef struct md_i_get_tstate {
337	minor_or_hsp_t	id;
338	uint_t		tstate;		/* Transient state */
339	md_error_t	mde;
340} md_i_get_tstate_t;
341
342typedef struct md_set_state_params {
343	MD_DRIVER
344	md_error_t	mde;
345	minor_t		mnum;
346	uint_t		sm;
347	uint_t		comp;
348	uint_t		state;
349	mddb_recid_t	hs_id;
350} md_set_state_params_t;
351
352typedef struct md_alloc_hotsp_params {
353	MD_DRIVER
354	md_error_t	mde;
355	minor_t		mnum;
356	uint_t		sm;
357	uint_t		comp;
358	mddb_recid_t	hs_id;
359} md_alloc_hotsp_params_t;
360
361typedef struct md_suspend_wr_params {
362	MD_DRIVER
363	md_error_t	mde;
364	minor_t		mnum;
365} md_suspend_wr_params_t;
366
367typedef struct md_mn_req_owner {
368	minor_t		mnum;		/* Mirror metadevice */
369	uint_t		flags;		/* Flags (see below) */
370	md_mn_nodeid_t	owner;		/* New owner of Mirror  */
371} md_mn_req_owner_t;
372
373#define	MD_MN_MM_PREVENT_CHANGE	0x0001	/* Disallow further ownership change */
374#define	MD_MN_MM_ALLOW_CHANGE	0x0002	/* Allow ownership change */
375#define	MD_MN_MM_SPAWN_THREAD	0x0004
376#define	MD_MN_MM_CHOOSE_OWNER	0x0008	/* Choose a resync owner */
377
378#define	MD_MN_MM_RESULT		0x80000000	/* Result contained in LSB */
379#define	MD_MN_MM_RESULT_MASK	0xFFFF		/* Mask for result code	   */
380#define	MD_MN_MM_RES_OK		0		/* Success */
381#define	MD_MN_MM_RES_FAIL	1		/* Failure */
382
383typedef struct md_set_mmown_params {
384	MD_DRIVER
385	md_error_t		mde;
386	md_mn_req_owner_t	d;	/* New owner */
387} md_set_mmown_params_t;
388
389typedef struct md_mn_own_status {
390	MD_DRIVER
391	md_error_t		mde;
392	minor_t			mnum;
393	uint_t			flags;	/* See above *_MM_RESULT flags */
394} md_mn_own_status_t;
395
396typedef struct md_mn_poke_hotspares {
397	MD_DRIVER
398	md_error_t		mde;
399} md_mn_poke_hotspares_t;
400
401typedef struct md_mn_rs_params {
402	MD_DRIVER
403	md_error_t	mde;
404	int		msg_type;	/* Type of message */
405	minor_t		mnum;		/* Mirror metadevice */
406	uint_t		rs_type;	/* Type of resync */
407	diskaddr_t	rs_start;	/* 1st block of resync range */
408	diskaddr_t	rs_size;	/* size of resync range */
409	diskaddr_t	rs_done;	/* amount of resync done so far */
410	diskaddr_t	rs_2_do;	/* amount still to be done */
411	md_mn_nodeid_t	rs_originator;	/* Originator of resync message */
412	char		rs_flags;	/* flags */
413	char		rs_first_time;	/* set if first resync-next message */
414	sm_state_t	rs_sm_state[NMIRROR];	/* Submirror state */
415	sm_flags_t	rs_sm_flags[NMIRROR];	/* Submirror flags */
416} md_mn_rs_params_t;
417
418/* flag values for rs_flags */
419#define	MD_MN_RS_ERR			0x01 /* Resync err */
420#define	MD_MN_RS_CLEAR_OPT_NOT_DONE	0x02 /* Optimized resync done */
421#define	MD_MN_RS_FIRST_RESYNC_NEXT	0x04 /* First RESYNC_NEXT message */
422
423typedef struct md_mn_setcap_params {
424	MD_DRIVER
425	md_error_t	mde;
426	minor_t		mnum;
427	uint_t		sc_set;		/* Capability settings */
428} md_mn_setcap_params_t;
429
430typedef struct md_mkdev_params {
431	MD_DRIVER
432	md_error_t	mde;		/* Error return */
433	unit_t		un;
434} md_mkdev_params_t;
435
436/*
437 * Flags to coordinate sending device id between kernel and user space.
438 * To get devid from kernel:
439 *   User calls ioctl with l_devid_flags set to GETSZ flag to get size of
440 *   devid which is returned in the l_devid_sz field if the SZ flag is set.
441 *   Then user allocs that size and sends same ioctl with SPACE flag set
442 *   and l_devid_sz set to alloc'd size.  Kernel either sets the NOSPACE
443 *   flag (if alloc'd space is not big enough) or sets the VALID flag and
444 *   fills in the devid.
445 *
446 * To send devid to kernel:
447 *   User alloc's space for devid, fills in devid, sets (SPACE|VALID|SZ) flags
448 *   and sets size of devid into l_devid_sz field.
449 *
450 * If MDDB_DEVID_SPACE is set, MDDB_DEVID_GETSZ is ignored.
451 * If no flags are set, devid information is ignored.
452 */
453#define	MDDB_DEVID_SPACE	0x0001	/* l_devid_sz bytes of space alloc'd */
454#define	MDDB_DEVID_VALID	0x0002	/* kernel has filled in devid */
455#define	MDDB_DEVID_NOSPACE	0x0004	/* not enough alloc'd space for devid */
456#define	MDDB_DEVID_GETSZ	0x0008	/* fill in l_devid_sz with devid size */
457#define	MDDB_DEVID_SZ		0x0010	/* l_devid_sz filled in with devid sz */
458
459
460
461/*
462 * Maximum number of replicas (or number of locator blocks) in set.
463 */
464#define	MDDB_NLB		50
465
466/*
467 * maximum size of allowable bootlist property string - only used to
468 * read in and write out boolist property strings to conf files.
469 */
470#define	MDDB_BOOTLIST_MAX_LEN	MAX_HWC_LINESIZE
471
472/*
473 * Percentage of free space left in replica during conversion of non-devid
474 * style replica to devid style replica.
475 */
476#define	MDDB_DEVID_CONV_PERC	5
477
478typedef struct mddb_cfg_loc {
479	dev32_t		l_dev;
480	daddr32_t	l_blkno;
481	int		l_flags;
482	char		l_driver[MD_MAXDRVNM];
483	minor_t		l_mnum;
484	int		l_devid_flags;
485	uint64_t	l_devid;	/* pointer to devid */
486	int		l_devid_sz;
487	uint64_t	l_old_devid;
488	int		l_old_devid_sz;
489	char		l_minor_name[MDDB_MINOR_NAME_MAX];
490	char		l_devname[MAXPATHLEN];	/* device name */
491} mddb_cfg_loc_t;
492
493typedef struct mddb_dtag {
494	md_timeval32_t	dt_tv;
495	int		dt_id;
496	set_t		dt_setno;
497	char		dt_sn[MDDB_SN_LEN];
498	char		dt_hn[MD_MAX_NODENAME_PLUS_1];
499} mddb_dtag_t;
500
501typedef struct mddb_dtag_lst {
502	struct mddb_dtag_lst	*dtl_nx;
503	mddb_dtag_t		dtl_dt;
504} mddb_dtag_lst_t;
505
506typedef struct mddb_dtag_get_parm {
507	set_t		dtgp_setno;
508	mddb_dtag_t	dtgp_dt;
509	md_error_t	dtgp_mde;
510} mddb_dtag_get_parm_t;
511
512typedef struct mddb_dtag_use_parm {
513	int		dtup_id;
514	set_t		dtup_setno;
515	md_error_t	dtup_mde;
516} mddb_dtag_use_parm_t;
517
518typedef struct mddb_accept_parm {
519	set_t		accp_setno;
520	md_error_t	accp_mde;
521} mddb_accept_parm_t;
522
523typedef struct mddb_med_parm {
524	set_t		med_setno;
525	md_hi_arr_t	med;
526	md_error_t	med_mde;		/* error return */
527} mddb_med_parm_t;
528
529typedef struct mddb_med_upd_parm {
530	set_t		med_setno;
531	md_error_t	med_mde;		/* error return */
532} mddb_med_upd_parm_t;
533
534#define	MED_TE_NM_LEN	64
535
536typedef struct mddb_med_t_ent {
537	char		med_te_nm[MED_TE_NM_LEN];
538	md_dev64_t	med_te_dev;		/* fixed size dev_t */
539} mddb_med_t_ent_t;
540
541typedef struct mddb_med_t_parm {
542	md_error_t		med_tp_mde;		/* error return */
543	int			med_tp_nents;		/* number of entries */
544	int			med_tp_setup;		/* setup flag */
545	mddb_med_t_ent_t	med_tp_ents[1];		/* Var. sized array */
546} mddb_med_t_parm_t;
547
548#define	MDDB_SETMASTER_MAGIC	0x53544d41	/* Ascii for STMA */
549typedef struct mddb_setmaster_config {
550	md_error_t	c_mde;
551	set_t		c_setno;
552	int		c_magic;		/* used to verify ioctl */
553	int		c_current_host_master;
554} mddb_setmaster_config_t;
555
556/*
557 * Structure used to set/reset/get flags in set structure.
558 */
559#define	MDDB_SETFLAGS_MAGIC	0x5354464c	/* ascii for STFL */
560typedef struct mddb_setflags_config {
561	md_error_t	sf_mde;
562	set_t		sf_setno;
563	int		sf_magic;	/* used to verify ioctl */
564	int		sf_flags;	/* Control flags set/reset/get */
565	int		sf_setflags;	/* Flag values */
566} mddb_setflags_config_t;
567
568typedef struct mddb_set_node_params {
569	md_error_t	sn_mde;
570	set_t		sn_setno;
571	md_mn_nodeid_t	sn_nodeid;
572} mddb_set_node_params_t;
573
574typedef struct mddb_block_parm {
575	md_error_t	c_mde;
576	set_t		c_setno;
577	int		c_blk_flags;
578} mddb_block_parm_t;
579
580typedef struct mddb_parse_parm {
581	md_error_t	c_mde;
582	set_t		c_setno;
583	int		c_parse_flags;
584	int		c_lb_flags[MDDB_NLB];
585} mddb_parse_parm_t;
586
587typedef struct mddb_optrec_parm {
588	md_error_t		c_mde;
589	set_t			c_setno;
590	md_replica_recerr_t	c_recerr[2];
591} mddb_optrec_parm_t;
592
593typedef struct mddb_config {
594	md_error_t	c_mde;			/* error return */
595	int		c_id;			/* used with getnext locator */
596	md_splitname	c_devname;		/* contains name or keys */
597	int		c_dbcnt;		/* number of dbs */
598	int		c_dbmax;		/* maximum number of dbs */
599	int		c_flags;
600	int		c_dbend;		/* size of database */
601	set_t		c_setno;		/* set number of replica */
602	int		c_multi_node;		/* set if multi_node set */
603	side_t		c_sideno;		/* side number of replica */
604	md_timeval32_t	c_timestamp;		/* creation of set */
605						/* setname */
606	char		c_setname[MD_MAX_SETNAME_PLUS_1];
607	md_hi_arr_t	c_med;			/* Mediator host information */
608	int		c_spare[14];		/* unused must be zero */
609	md_dev64_t	c_devt;			/* devt to get/set */
610	mddb_cfg_loc_t	c_locator;		/* device specific info */
611} mddb_config_t;
612
613#define	c_subcmd	c_spare[0]
614/*
615 * Subcommands.
616 */
617#define	MDDB_CONFIG_ABS	1		/* treat c_id as abs index */
618
619typedef	struct mddb_optloc {
620	int	recid;	/* really mddb_recid_t */
621	int	li[2];
622} mddb_optloc_t;
623
624typedef struct md_gs_stat_parm {
625	set_t		gs_setno;
626	uint_t		gs_status;
627	md_error_t	gs_mde;
628} md_gs_stat_parm_t;
629
630typedef struct {
631	int	setno;
632	int	owns_set;
633} mddb_ownset_t;
634
635typedef enum md_rename_operation_t {
636	MDRNOP_UNK = 0, MDRNOP_RENAME, MDRNOP_EXCHANGE
637} md_renop_t;
638
639typedef struct md_rename {
640	md_error_t	mde;
641	md_renop_t	op;
642	int		revision;
643	uint_t		flags;
644	struct {
645		minor_t	mnum;
646		key_t	key;
647	} from, to;
648} md_rename_t;
649
650typedef struct md_regen_param {
651	MD_DRIVER
652	md_error_t	mde;
653	minor_t		mnum;   /* Unit to regenerate parity for */
654} md_regen_param_t;
655
656/* Base ioctl's defined here */
657#define	MDIOC		('V' << 8)
658#define	ISMDIOC(c)	(((c) >> 8) == 'V')
659
660#define	MD_IOCSET	(MDIOC|0)	/* set config    (metainit) */
661#define	MD_IOCRESET	(MDIOC|1)	/* reset config  (metaclear) */
662#define	MD_IOCGET	(MDIOC|2)	/* get config    (metastat) */
663#define	MD_IOCGROW	(MDIOC|3)	/* grow config   (dyn concat) */
664#define	MD_IOCCHANGE	(MDIOC|4)	/* change config (metaparam) */
665#define	MD_IOCSET_NM	(MDIOC|5)	/* set device name */
666#define	MD_IOCGET_NM	(MDIOC|6)	/* get device name */
667#define	MD_IOCREM_NM	(MDIOC|7)	/* remove device name */
668#define	MD_IOCGET_DRVNM	(MDIOC|8)	/* get driver name */
669#define	MD_IOCGET_NEXT	(MDIOC|9)	/* get next unit id */
670#define	MD_IOCGET_DEVS	(MDIOC|10)	/* get device list */
671#define	MD_DB_NEWDEV	(MDIOC|11)	/* add a db replica */
672#define	MD_DB_USEDEV	(MDIOC|12)	/* patch in a db location */
673#define	MD_DB_GETDEV	(MDIOC|13)	/* get a db replica */
674#define	MD_DB_DELDEV	(MDIOC|14)	/* remove a db replica */
675#define	MD_DB_ENDDEV	(MDIOC|15)	/* get db replica and size */
676#define	MD_DB_GETDRVNM	(MDIOC|16)	/* get db replica driver name */
677#define	MD_HALT		(MDIOC|17)	/* halt driver   (metahalt) */
678#define	MD_GRAB_SET	(MDIOC|18)
679#define	MD_RELEASE_SET	(MDIOC|20)	/* release a set */
680#define	MD_IOCSETSYNC	(MDIOC|21)
681#define	MD_IOCGETSYNC	(MDIOC|22)
682#define	MD_IOCOFFLINE	(MDIOC|23)
683#define	MD_IOCONLINE	(MDIOC|24)
684#define	MD_IOCATTACH	(MDIOC|25)
685#define	MD_IOCDETACH	(MDIOC|26)
686#define	MD_IOCREPLACE	(MDIOC|27)
687#define	MD_DB_USERREQ	(MDIOC|28)
688#define	MD_DB_GETOPTLOC	(MDIOC|29)	/* get locators for opt resync rec. */
689#define	MD_DB_OWNSET	(MDIOC|30)	/* Does caller own the set */
690#define	MD_IOCGETNSET	(MDIOC|31)	/* Get the config'd number sets */
691#define	MD_IOCNXTKEY_NM	(MDIOC|32)	/* get next key from namespace */
692#define	MD_DB_NEWSIDE	(MDIOC|33)	/* add another side to the db replica */
693#define	MD_DB_DELSIDE	(MDIOC|34)	/* delete a side from the db replica */
694#define	MD_IOCGVERSION	(MDIOC|35)	/* get the driver version */
695#define	MD_IOCSET_FLAGS	(MDIOC|36)	/* set the userflags of a metadevice */
696#define	MD_IOCGETNUNITS	(MDIOC|37)	/* Get the config'd number units */
697#define	MD_IOCNOTIFY	(MDIOC|38)	/* notification */
698#define	MD_IOCRENAME	(MDIOC|39)	/* (Ex)Change/Rename unit identities */
699#define	MD_IOCISOPEN	(MDIOC|40)	/* Is metadevice open? */
700#define	MD_IOCSETREGEN	(MDIOC|41)	/* regen ioctl for raid */
701#define	MD_MED_GET_LST	(MDIOC|42)	/* Get the mediator list */
702#define	MD_MED_SET_LST	(MDIOC|43)	/* Set the mediator list */
703#define	MD_MED_UPD_MED	(MDIOC|44)	/* Have the kernel push mediator data */
704#define	MD_MED_GET_NMED	(MDIOC|45)	/* Get the max number of mediators */
705#define	MD_MED_GET_TLEN	(MDIOC|46)	/* Get the mediator transport tbl len */
706#define	MD_MED_GET_T	(MDIOC|47)	/* Get the mediator transport tbl */
707#define	MD_MED_SET_T	(MDIOC|48)	/* Set the mediator transport tbl */
708#define	MD_MED_GET_TAG	(MDIOC|49)	/* Get the list of data tags */
709#define	MD_MED_USE_TAG	(MDIOC|50)	/* Use one of the data tags */
710#define	MD_MED_ACCEPT	(MDIOC|51)	/* Accept 1/2 n 1/2 */
711#define	MD_GET_SETSTAT	(MDIOC|52)	/* Get the s_status for a set */
712#define	MD_SET_SETSTAT	(MDIOC|53)	/* Set the s_status for a set */
713#define	MD_IOCPROBE_DEV (MDIOC|54)	/* Force pseudo opens for metadevices */
714#define	MD_IOCGET_DID	(MDIOC|55)	/* Get device id */
715#define	MD_IOCUPD_NM	(MDIOC|56)	/* Update namespace */
716#define	MD_DB_SETDID	(MDIOC|57)	/* Set device id for a locator block */
717#define	MD_IOCUPD_LOCNM	(MDIOC|58)	/* update locator namespace */
718#define	MD_SETNMDID	(MDIOC|59)	/* update namespace devid */
719#define	MD_IOCDID_STAT	(MDIOC|60)	/* get invalid device id's */
720#define	MD_UPGRADE_STAT	(MDIOC|61)	/* get upgrade status information */
721#define	MD_IOCGET_NUM	(MDIOC|62)	/* get number of devs and devs */
722#define	MD_IOCGET_TSTATE (MDIOC|63)	/* get ui_tstate for metastat */
723#define	MD_SETMASTER	(MDIOC|64)
724#define	MD_MN_SET_DOORH		(MDIOC|65) /* MN: set the doorhandle */
725#define	MD_MN_OPEN_TEST		(MDIOC|66) /* MN: check / (un)lock a md */
726#define	MD_MN_SET_MM_OWNER	(MDIOC|67) /* Set mirror owner */
727#define	MD_MN_SET_NODEID	(MDIOC|68) /* Set this node's id */
728#define	MD_MN_SET_STATE		(MDIOC|69) /* Set mirror state */
729#define	MD_MN_SUSPEND_WRITES	(MDIOC|70) /* Blocks writes */
730#define	MD_MN_GET_MM_OWNER	(MDIOC|71) /* Get mirror owner */
731#define	MD_IOCGUNIQMSGID	(MDIOC|72) /* create a unique message ID */
732#define	MD_MN_MM_OWNER_STATUS 	(MDIOC|73) /* Return status of SET_MM_OWNER */
733#define	MD_MN_ALLOCATE_HOTSPARE (MDIOC|74) /* Allocate hotspare */
734#define	MD_MN_SUBMIRROR_STATE 	(MDIOC|75) /* Submirror state change */
735#define	MD_MN_RESYNC		(MDIOC|76) /* Resync ioctl */
736#define	MD_MN_SUSPEND_SET	(MDIOC|77) /* suspend IO's for a MN diskset */
737#define	MD_MN_RESUME_SET	(MDIOC|78) /* resume IO's for a MN diskset */
738#define	MD_MN_MDDB_PARSE	(MDIOC|79) /* Re-parse portion of MNset mddb */
739#define	MD_MN_MDDB_BLOCK	(MDIOC|80) /* Block parse or record changes */
740#define	MD_MN_MDDB_OPTRECFIX	(MDIOC|81) /* Fix optimized record failure */
741#define	MD_MN_SET_CAP		(MDIOC|82) /* set capability, eg ABR, DMR */
742#define	MD_MN_CHK_WRT_MDDB	(MDIOC|83) /* New master checks/writes mddb */
743#define	MD_MN_SET_SETFLAGS	(MDIOC|84) /* Set/reset set flags */
744#define	MD_MN_GET_SETFLAGS	(MDIOC|85) /* Gets set flags */
745#define	MD_IOCGET_DIDMIN	(MDIOC|94) /* get the minor name for a devid */
746#define	MD_IOCIMP_LOAD		(MDIOC|95) /* load the import replicas */
747#define	MD_IOCSET_DID		(MDIOC|96) /* set the devid of a disk */
748#define	MD_MN_GET_MIRROR_STATE	(MDIOC|97) /* Get the mirror state MN only */
749#define	MD_MN_DB_USERREQ	(MDIOC|98) /* MN MT-version of USERREQ */
750#define	MD_IOCMAKE_DEV		(MDIOC|99) /* create device node for unit */
751#define	MD_MN_SET_COMMD_RUNNING	(MDIOC|100) /* Commd running or exiting */
752#define	MD_MN_COMMD_ERR		(MDIOC|101) /* get a message out */
753#define	MD_MN_SETSYNC		(MDIOC|102) /* multi-threaded MD_IOCSETSYNC */
754#define	MD_MN_POKE_HOTSPARES	(MDIOC|103) /* poke hotspares */
755#define	MD_DB_LBINITTIME	(MDIOC|104) /* get the lb_inittime */
756#define	MD_IOCGET_HSP_NM	(MDIOC|105) /* get hsp entry from namespace */
757#define	MD_IOCREM_DEV		(MDIOC|106) /* remove device node for unit */
758#define	MD_IOCUPDATE_NM_RR_DID	(MDIOC|107) /* update remotely repl did in NM */
759
760
761#define	MDIOC_MISC	(MDIOC|128)	/* misc module base */
762/* Used in DEBUG_TEST code */
763#define	MD_MN_CHECK_DOOR1 (MDIOC|126)	/* MN: test door to master */
764#define	MD_MN_CHECK_DOOR2 (MDIOC|127)	/* MN: test door master-broadcast */
765
766#define	NODBNEEDED(c)	((c) == MD_IOCNOTIFY)
767
768typedef struct md_resync_ioctl {
769	MD_DRIVER
770	md_error_t	mde;
771	minor_t		ri_mnum;	    /* mirror to sync */
772	diskaddr_t	ri_copysize;	    /* The size of the copy buffer */
773	int		ri_zerofill;	    /* Zerofill on lec read error */
774	int		ri_percent_done;    /* percent done current phase */
775	int		ri_percent_dirty;
776	md_riflags_t	ri_flags;
777} md_resync_ioctl_t;
778
779typedef struct md_rrsize {
780	MD_DRIVER
781	md_error_t	mde;		/* error return */
782	minor_t		mnum;		/* unit # to get */
783	ulong_t		rr_num;		/* Number of resync regions */
784	ulong_t		rr_blksize;	/* Blocksize of regions */
785} md_rrsize_t;
786
787typedef	enum replace_cmd {
788	REPLACE_COMP, ENABLE_COMP, FORCE_REPLACE_COMP, FORCE_ENABLE_COMP
789} replace_cmd_t;
790
791typedef struct replace_params {
792	MD_DRIVER
793	md_error_t	mde;
794	replace_cmd_t	cmd;		/* what to do */
795	minor_t		mnum;		/* mirror to act upon */
796	md_dev64_t	old_dev;	/* enable/replace use this */
797	md_dev64_t	new_dev;	/* replace only uses this */
798	mdkey_t		new_key;	/* replace only uses this */
799	diskaddr_t	start_blk;	/* start block of new device */
800	int		has_label;	/* has label flag of new device */
801	diskaddr_t	number_blks;	/* # of blocks of new device */
802	uint_t		options;	/* misc options, see MDIOCTL_* below */
803} replace_params_t;
804
805typedef struct md_i_off_on {
806	MD_DRIVER
807	md_error_t	mde;
808	minor_t		mnum;
809	md_dev64_t	submirror;
810	int		force_offline;
811} md_i_off_on_t;
812
813typedef struct md_att_struct {
814	MD_DRIVER
815	md_error_t	mde;		/* Normal error */
816	minor_t		mnum;
817	mdkey_t		key;		/* namespace key of sm */
818	md_dev64_t	submirror;	/* The device  to attach */
819	uint_t		options;	/* passed in from the command */
820} md_att_struct_t;
821
822/* possible values for options above */
823#define	MDIOCTL_DRYRUN		0x0001	/* Only check if operation possible */
824#define	MDIOCTL_NO_RESYNC_RAID	0x0002	/* if cluster replace we don't */
825					/*    want to resync */
826
827typedef struct md_detach_params {
828	MD_DRIVER
829	md_error_t	mde;
830	minor_t		mnum;		/* mirror to act upon */
831	md_dev64_t	submirror;
832	int		force_detach;
833} md_detach_params_t;
834
835/*
836 * Structure for accessing the DB from user land.
837 */
838typedef struct mddb_userreq {
839	md_error_t		ur_mde;
840	mddb_usercmd_t		ur_cmd;
841	set_t			ur_setno;
842	mddb_type_t		ur_type;
843	uint_t			ur_type2;
844	mddb_recid_t		ur_recid;
845	mddb_recstatus_t	ur_recstat;
846	int			ur_size;
847	uint64_t		ur_data;	/* Pointer to user data */
848} mddb_userreq_t;
849
850/*
851 * Ioctl structure for MD_IOCISOPEN
852 */
853typedef struct md_isopen {
854	md_error_t	mde;
855	md_dev64_t	dev;
856	int		isopen;
857} md_isopen_t;
858
859/*
860 * Ioctl structure for MD_MN_OPEN_TEST
861 * md_clu_open stands for md check/lock/unlock
862 * Can't use MD_IOCISOPEN, because it's a contracted inteface.
863 */
864typedef struct md_clu_open {
865	md_error_t	clu_mde;
866	md_dev64_t	clu_dev;
867	enum {	MD_MN_LCU_CHECK = 0,
868		MD_MN_LCU_LOCK,
869		MD_MN_LCU_UNLOCK } clu_cmd;
870	int		clu_isopen;
871} md_clu_open_t;
872
873/*
874 * Structure to push the message out from commd
875 * MAXPATHLEN macro is being overloaded to represent
876 * the line size of 1024 characters. i.e. no path
877 * is being passed.
878 */
879typedef struct md_mn_commd_err {
880	int size;
881	uint64_t md_message; /* pointer to array of chars */
882} md_mn_commd_err_t;
883
884/*
885 * Ioctl structure for MD_IOCPROBE_DEV
886 */
887
888#define	TESTNAME_LEN 32
889
890#define	PROBE_SEMA(p)	p->probe_sema
891#define	PROBE_MX(p)	p->probe_mx
892
893/*
894 * To categorize user/kernel structures md_probedev is split into two,
895 * one used by user and the other by kernel, thereby hiding the semaphore
896 * /mutex pointer members from user, which should be the appropriate one.
897 */
898
899typedef struct md_probedev {
900	MD_DRIVER
901	md_error_t	mde;		/* return error status */
902	int		nmdevs;		/* number of metadevices */
903	char		test_name[TESTNAME_LEN];
904	uint64_t	mnum_list;	/* pointer to array of minor numbers */
905} md_probedev_t;
906
907typedef struct md_probedev_impl {
908	ksema_t		*probe_sema;
909	kmutex_t	*probe_mx;
910	md_probedev_t	probe;
911} md_probedev_impl_t;
912
913/*
914 * Ioctl structure for MD_MN_GET_MIRROR_STATE
915 */
916typedef struct md_mn_get_mir_state {
917	MD_DRIVER
918	minor_t		mnum;		/* Unit to obtain submirror info from */
919} md_mn_get_mir_state_t;
920
921#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
922#pragma pack()
923#endif
924/*
925 * Per set flags, stored in md_set[n].s_status
926 */
927#define	MD_SET_HALTED		0x00000001  /* Set is shut down */
928#define	MD_SET_SNARFED		0x00000002  /* incores built for set db recs */
929#define	MD_SET_SNARFING		0x00000004  /* incores being built for set */
930#define	MD_SET_STALE		0x00000008  /* set database not correct */
931#define	MD_SET_NM_LOADED	0x00000010  /* set namespace is loaded */
932#define	MD_SET_TAGDATA		0x00000020  /* tagged data detected */
933#define	MD_SET_ACCOK		0x00000040  /* Accept data is possible */
934#define	MD_SET_TOOFEW		0x00000080  /* not enough replicas */
935#define	MD_SET_USETAG		0x00000100  /* A tag is selected, use it */
936#define	MD_SET_ACCEPT		0x00000200  /* User chose accept 50/50 mode */
937#define	MD_SET_OWNERSHIP	0x00000400  /* Set is owned */
938#define	MD_SET_BADTAG		0x00000800  /* DT is not valid */
939#define	MD_SET_CLRTAG		0x00001000  /* Clear the tags */
940#define	MD_SET_KEEPTAG		0x00002000  /* Keep the tag */
941#define	MD_SET_PUSHLB		0x00004000  /* Indicate a LB push is needed */
942#define	MD_SET_MNSET		0x00008000  /* Set is a multinode diskset */
943#define	MD_SET_DIDCLUP		0x00010000  /* Set has cleaned up devids */
944#define	MD_SET_MNPARSE_BLK	0x00020000  /* Do not send parse msgs */
945#define	MD_SET_MN_NEWMAS_RC	0x00040000  /* Is new master during reconfig */
946#define	MD_SET_MN_START_RC	0x00080000  /* Start step executed for set */
947#define	MD_SET_IMPORT		0x00100000  /* Indicate set is importing */
948#define	MD_SET_MN_MIR_STATE_RC	0x00200000  /* Mirror state gotten for set */
949#define	MD_SET_HOLD		0x00400000  /* Hold set during release */
950#define	MD_SET_REPLICATED_IMPORT	0x00800000  /* Set importing RC disk */
951
952#define	MD_MNSET_SETNO(setno)	(md_set[setno].s_status & MD_SET_MNSET)
953
954/*
955 * See meta_prbits() in SUNWmd/lib/libmeta/meta_print.c for a description of
956 * the way this is used
957 */
958#define	MD_SET_STAT_BITS "\020\001HALTED\002SNARFED\003SNARFING\004STALE" \
959			    "\005NM_LOADED\006TAGDATA\007ACCOK\010TOOFEW" \
960			    "\011USETAG\012ACCEPT\013OWNERSHIP\014BADTAG" \
961			    "\015CLRTAG\016KEEPTAG\017PUSHLB\020MNSET" \
962			    "\021DIDCLUP\022MNPARSE_BLK\023MN_NEWMAS_RC" \
963			    "\024MN_START_RC\025IMPORT\026MIR_STATE_RC" \
964			    "\027HOLD\030REPLICATED_IMPORT"
965
966
967#ifdef	__cplusplus
968}
969#endif
970
971#endif	/* _SYS__MDIO_H */
972