Home | History | Annotate | Download | only in lvm
      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 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef	_SYS_MDVAR_H
     28 #define	_SYS_MDVAR_H
     29 
     30 #include <sys/types.h>
     31 #include <sys/kmem.h>
     32 #include <sys/mkdev.h>
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/t_lock.h>
     36 #include <sys/open.h>
     37 #include <sys/devops.h>
     38 #include <sys/modctl.h>
     39 #ifdef	DEBUG
     40 #include <sys/thread.h>
     41 #endif
     42 #include <sys/kstat.h>
     43 #include <sys/efi_partition.h>
     44 #include <sys/byteorder.h>
     45 #include <sys/door.h>
     46 
     47 #include <sys/lvm/mdmn_commd.h>
     48 #include <sys/lvm/mdio.h>
     49 #include <sys/lvm/md_mdiox.h>
     50 #include <sys/lvm/md_mddb.h>
     51 #include <sys/lvm/md_notify.h>
     52 
     53 #ifdef	__cplusplus
     54 extern "C" {
     55 #endif
     56 
     57 /*
     58  * defaults
     59  */
     60 #define	NMD_DEFAULT		128	/* number of metadevices */
     61 #define	MD_NOPS			25	/* number of misc modules */
     62 #define	MAXBOOTLIST		64
     63 
     64 /*
     65  * Needed for backwards-compatibility with metadevices created under
     66  * 2.6 or earlier.  Back then, a krwlock_t was twelve bytes.  More
     67  * recently, it's four bytes.  Since these get included in structures
     68  * written out to disk, we have to make sure we're using the largest
     69  * size.  Things will get interesting if krwlock_t ever gets bigger
     70  * than twelve bytes.
     71  */
     72 
     73 typedef union _md_krwlock {
     74 	krwlock_t	lock;
     75 	struct {
     76 		void	*_opaque[3];
     77 	} xx;
     78 } md_krwlock_t;
     79 
     80 typedef struct {
     81 	kmutex_t	md_io_mx;		/* counter mutex */
     82 	kcondvar_t	md_io_cv;		/* ioctl wait on if draining */
     83 	long		io_cnt;			/* number of I/Os */
     84 	long		io_state;		/* !0 if waiting on zero */
     85 } md_set_io_t;
     86 
     87 typedef enum set_iostate {
     88 	MD_SET_ACTIVE = 1,
     89 	MD_SET_RELEASE = 2
     90 }set_iostate_t;
     91 
     92 /*
     93  * for md_dev64_t translation
     94  */
     95 struct md_xlate_table {
     96 	dev32_t		mini_devt;
     97 	dev32_t		targ_devt;
     98 };
     99 
    100 extern struct md_xlate_table	*md_tuple_table;
    101 
    102 /*
    103  * for major number translation
    104  */
    105 
    106 struct md_xlate_major_table {
    107 	char		*drv_name;
    108 	major_t		targ_maj;
    109 };
    110 
    111 extern struct md_xlate_major_table *md_major_tuple_table;
    112 
    113 extern int	md_tuple_length;
    114 extern uint_t	md_majortab_len;
    115 extern int	md_in_upgrade;
    116 
    117 extern md_mn_nodeid_t	md_mn_mynode_id;
    118 
    119 #define	MD_UPGRADE (md_in_upgrade == 1)
    120 
    121 /*
    122  * Flags used during upgrade:
    123  *
    124  * md_keep_repl_state flag means that mddb should be kept in the format
    125  *   that was found on disk (non-device id format vs. device id format).
    126  *   This is used during the upgrade process when install is probing
    127  *   for root disks so that the user can choose the one to be upgraded.
    128  *
    129  * md_devid_destroy flag is used to destroy device ids stored in the
    130  *   metadevice state database (mddb).
    131  *
    132  *   The md_devid_destroy flag is to be used only in a catastrophic failure
    133  *   case. An example of this would be if a user upgrades firmware on all
    134  *   disks where this causes the disks to now have different device id's.
    135  *   The user would not be able to boot a mirror'd root filesystem since the
    136  *   system would recognize none of the device id's stored in the mddb.
    137  *   This flag would destroy all device id information stored in the mddb and
    138  *   if the md_keep_repl_state flag was not set, the mddb would be reconverted
    139  *   to device id format on SLVM startup and all of the device id
    140  *   information would be regenerated.
    141  *
    142  *   If the md_devid_destroy flag is set and the md_keep_repl_state flag is
    143  *   set, the mddb's would have their device id information destroyed and
    144  *   would be left in non-devid format since the device id information would
    145  *   not be regenerated.
    146  *
    147  *   This flag is not documented anywhere and is only to be used as a last
    148  *   resort as in the described case or if a device driver has a bug where
    149  *   device id's are found to not be unique.  If device id's aren't unique,
    150  *   the user could run without device id's until a patch is released for
    151  *   that driver.
    152  */
    153 extern int	md_keep_repl_state;
    154 extern int	md_devid_destroy;
    155 extern int	mdmn_door_did;
    156 #ifdef _KERNEL
    157 extern door_handle_t	mdmn_door_handle;
    158 #endif /* _KERNEL */
    159 
    160 /*
    161  * An io_lock mechanism for raid, the MD_UL_XXXX bits are used for
    162  * convenience.
    163  */
    164 typedef struct md_io_lock {
    165 	ulong_t		io_readercnt;	/* number of unit readers */
    166 	ulong_t		io_wanabecnt;	/* # pending on becoming unit writer */
    167 	ulong_t		io_lock;
    168 	void		*io_list_front;
    169 	void		*io_list_back;
    170 	kmutex_t	io_mx;
    171 	kcondvar_t	io_cv;
    172 	kmutex_t	io_list_mutex;	/* list of waiting io */
    173 	kthread_id_t	io_owner;	/* writer thread */
    174 } md_io_lock_t;
    175 
    176 /*
    177  * The following flags are in un_flag field of mdc_unit struct.
    178  */
    179 #define	MD_LABELED	0x1	/* First sector of the metadevice is a label */
    180 #define	MD_EFILABEL	0x2	/* This md has an EFI label and no vtoc */
    181 
    182 /*
    183  * This is the number of bytes a DKIOCGETEFI ioctl returns
    184  * For now it's one time the header and once the size for a partition info
    185  */
    186 #define	MD_EFI_LABEL_SIZE (sizeof (efi_gpt_t) + sizeof (efi_gpe_t))
    187 
    188 /* This is the number of bytes consumed by efi_gpe_PartitionName */
    189 #define	MD_EFI_PARTNAME_BYTES (EFI_PART_NAME_LEN * sizeof (ushort_t))
    190 
    191 typedef enum hs_cmds {
    192 	HS_GET, HS_FREE, HS_BAD, HSP_INCREF, HSP_DECREF, HS_MKDEV
    193 } hs_cmds_t;
    194 
    195 typedef struct md_link {
    196 	struct md_link	*ln_next;
    197 	set_t		ln_setno;
    198 	uint_t		ln_id;
    199 } md_link_t;
    200 
    201 typedef struct mdi_unit {
    202 	md_link_t	ui_link;
    203 	ulong_t		ui_readercnt;	/* number of unit readers */
    204 	ulong_t		ui_wanabecnt;	/* # pending on becoming unit writer */
    205 	ulong_t		ui_lock;
    206 	kmutex_t	ui_mx;
    207 	kcondvar_t	ui_cv;
    208 	int		ui_opsindex;
    209 	uint_t		ui_ocnt[OTYPCNT]; /* open counts */
    210 	md_io_lock_t	*ui_io_lock;	/* pointer to io lock */
    211 	kstat_t		*ui_kstat;	/* kernel statistics */
    212 	kthread_id_t	ui_owner;	/* writer thread */
    213 	uint_t		ui_tstate;	/* transient state bits */
    214 	uint_t		ui_capab;	/* Capability bits supported */
    215 } mdi_unit_t;
    216 
    217 /*
    218  * Following are used with ui_lock
    219  * which is in the unit incore structure.
    220  */
    221 #define	MD_UL_WRITER		0x0001 /* Stall all new strategy calls */
    222 #define	MD_UL_WANABEWRITER	0x0002
    223 #define	MD_UL_OPENORCLOSE	0x0004
    224 
    225 #define	MD_UL_OPEN		0x0008	/* unit is open */
    226 #define	MD_UL_EXCL		0x0010	/* unit is open exclusively */
    227 
    228 /*
    229  * The softpart open code may do an I/O to validate the watermarks
    230  * and should hold no open locks during this I/O.  So, mark the unit
    231  * as OPENINPROGRESS and drop the locks.  This will keep any other
    232  * softpart open's waiting until the validate has completed.
    233  */
    234 #define	MD_UL_OPENINPROGRESS	0x0020	/* Open in Progress */
    235 
    236 /*
    237  * Following are used with ui_tstate to specify any transient states which
    238  * occur during metadevice operation. These are not written to the metadb as
    239  * they do not represent a failure of the underlying metadevice.
    240  * Transient errors are stored in the lower 16 bits and other transient
    241  * state is stored in the upper 16 bits.
    242  * MD_NOTOPENABLE should contain all the states that are set prior to an
    243  * open (by snarf) and that indicate that a metadevice cannot be opened.
    244  */
    245 #define	MD_DEV_ERRORED		0x0000ffff /* ui_tstate error bits */
    246 #define	MD_EOF_METADEVICE	0x00000001 /* EOF'd metadevice */
    247 #define	MD_64MD_ON_32KERNEL	0x00000002 /* 64bit metadev on 32bit kernel */
    248 #define	MD_INACCESSIBLE		0x00000004 /* metadevice unavailable */
    249 #define	MD_RETRYING		0x00010000 /* retrying errored failfast I/O */
    250 #define	MD_OPENLOCKED		0x00020000 /* MN: open locked before removing */
    251 #define	MD_ERR_PENDING		0x00040000 /* MN: error pending */
    252 #define	MD_ABR_CAP		0x00080000 /* MN: Application Based Recovery */
    253 #define	MD_DMR_CAP		0x00100000 /* MN: Directed Mirror Read */
    254 #define	MD_RELEASE_IOERR_DONE	0x00200000 /* ioerr console message done */
    255 #define	MD_RESYNC_NOT_DONE	0x00400000 /* resync not done yet */
    256 
    257 /* A metadevice cannot be opened when these states are set */
    258 #define	MD_NOTOPENABLE		(MD_EOF_METADEVICE|MD_64MD_ON_32KERNEL)
    259 
    260 typedef struct md_ioctl_lock {
    261 	int		l_flags;	/* locks held */
    262 	mdi_unit_t	*l_ui;		/* unit for which lock is held */
    263 } md_ioctl_lock_t;
    264 
    265 #define	MD_MASTER_DROPPED	0x0001
    266 #define	MD_READER_HELD		0x0002
    267 #define	MD_WRITER_HELD		0x0004
    268 #define	MD_IO_HELD		0x0008
    269 #define	MD_ARRAY_READER		0x0010
    270 #define	MD_ARRAY_WRITER		0x0020
    271 #define	STALE_OK		0x0100
    272 #define	NO_OLD			0x0200
    273 #define	NO_LOCK			0x0400
    274 #define	MD_MT_IOCTL		0x80000 /* MD_GBL_IOCTL_LOCK not set */
    275 #define	IOLOCK	md_ioctl_lock_t
    276 
    277 #define	WR_LOCK			MD_WRITER_HELD
    278 #define	RD_LOCK			MD_READER_HELD | STALE_OK
    279 #define	ARRAY_WRITER		MD_ARRAY_WRITER
    280 #define	ARRAY_READER		MD_ARRAY_READER
    281 #define	WRITERS			MD_WRITER_HELD | MD_IO_HELD | MD_ARRAY_WRITER
    282 #define	READERS			RD_LOCK | MD_ARRAY_READER
    283 
    284 #define	IOLOCK_RETURN_IOCTLEND(code, lock) \
    285 	md_ioctl_lock_exit((code), (lock)->l_flags, (lock)->l_ui, TRUE)
    286 
    287 #define	IOLOCK_RETURN(code, lock) \
    288 	md_ioctl_lock_exit((code), (lock)->l_flags, (lock)->l_ui, FALSE)
    289 
    290 #define	IOLOCK_RETURN_RELEASE(code, lock) \
    291 	md_ioctl_releaselocks((code), (lock)->l_flags, (lock)->l_ui)
    292 
    293 #define	IOLOCK_RETURN_REACQUIRE(lock) \
    294 	md_ioctl_reacquirelocks((lock)->l_flags, (lock)->l_ui)
    295 
    296 #define	IOLOCK_INIT(lock)	bzero((caddr_t)(lock), sizeof (*(lock)))
    297 /*
    298  * checks to be sure locks are held
    299  */
    300 #define	UNIT_WRITER_HELD(un) \
    301 	(MDI_UNIT(MD_SID(un))->ui_lock & MD_UL_WRITER)
    302 #define	UNIT_READER_HELD(un) \
    303 	(MDI_UNIT(MD_SID(un))->ui_readercnt != 0)
    304 #define	IO_WRITER_HELD(un) \
    305 	(MDI_UNIT(MD_SID(un))->ui_io_lock->io_lock & MD_UL_WRITER)
    306 #define	IO_READER_HELD(un) \
    307 	(MDI_UNIT(MD_SID(un))->ui_io_lock->io_readercnt != 0)
    308 
    309 #ifdef  DEBUG
    310 #define	STAT_INC(statvar)		\
    311 	statvar++
    312 #define	STAT_DEC(statvar)		\
    313 	statvar--
    314 #define	STAT_ZERO(statvar)		\
    315 	statvar = 0;
    316 #define	STAT_MAX(statmax, statvar)	\
    317 	{				\
    318 	statvar++;			\
    319 	if (statvar > statmax)		\
    320 		statmax = statvar;	\
    321 	}
    322 #define	STAT_CHECK(statvar, value)	\
    323 	{				\
    324 	if (value)			\
    325 		statvar++;		\
    326 	}
    327 #else
    328 #define	STAT_INC(statvar)
    329 #define	STAT_DEC(statvar)
    330 #define	STAT_ZERO(statvar)
    331 #define	STAT_MAX(statmax, statvar)
    332 #define	STAT_CHECK(statvar, value)
    333 #endif
    334 /*
    335  * bit map related macros
    336  */
    337 #define	setbit(a, i)	((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    338 #define	clrbit(a, i)	((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    339 #define	isset(a, i)	((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    340 #define	isclr(a, i)	(((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
    341 
    342 typedef struct daemon_queue {
    343 	int	maxq_len;
    344 	int	qlen;
    345 	int	treqs;		/* total number of requests */
    346 	struct daemon_queue	*dq_next;
    347 	struct daemon_queue	*dq_prev;
    348 	void			(*dq_call)();
    349 } daemon_queue_t;
    350 
    351 #define	DAEMON_QUEUE daemon_queue_t	dq;
    352 
    353 #ifdef _KERNEL
    354 #include	<sys/buf.h>
    355 #include	<sys/dkio.h>
    356 #include	<sys/vtoc.h>
    357 
    358 #define	MD_DEV2SET(d)	(MD_MIN2SET(md_getminor(d)))
    359 
    360 #define	MD_UNIT(m)	(md_set[MD_MIN2SET(m)].s_un[MD_MIN2UNIT(m)])
    361 #define	MDI_UNIT(m)	((mdi_unit_t *) \
    362 			    md_set[MD_MIN2SET(m)].s_ui[MD_MIN2UNIT(m)])
    363 #define	MD_VOIDUNIT(m)	(md_set[MD_MIN2SET(m)].s_un[MD_MIN2UNIT(m)])
    364 #define	MDI_VOIDUNIT(m)	(md_set[MD_MIN2SET(m)].s_ui[MD_MIN2UNIT(m)])
    365 
    366 /*
    367  * This is the current maximum number of real disks per Virtual Disk.
    368  */
    369 extern	uint_t	md_mdelay;	/* md_mirror timeout delay */
    370 
    371 #define	MD_ADM_MINOR		L_MAXMIN32 /* the minor number for md_admin */
    372 #define	MD_MDELAY		(md_mdelay)
    373 #define	NUM_USEC_IN_SEC		1000000 /* 1 million usec in a second */
    374 
    375 #define	ANY_SERVICE		-1	/* md_get_named_service() wild card */
    376 
    377 /*
    378  * daemon threads are used in multiple places in md. The following set of
    379  * structures and routines allow a common way to create and initialize them.
    380  *
    381  * md_requestq_entry_t - entry of creating request queues.
    382  * struct mdq_anchor - request queue header
    383  *
    384  * Functions associated with request queues:
    385  *
    386  * int init_requestq_entry -
    387  * void daemon_request - put a request on the queue.
    388  */
    389 
    390 typedef struct md_requestq_entry {
    391 	struct mdq_anchor	*dispq_headp;
    392 	int		*num_threadsp; /* threads servicing the queue */
    393 } md_requestq_entry_t;
    394 
    395 #define	NULL_REQUESTQ_ENTRY(rqp)\
    396 		((rqp)->dispq_headp == NULL || (rqp)->num_threadsp == NULL)
    397 
    398 /* this typedef is used to differentiate between the two call styles */
    399 typedef enum callstyle {
    400 	REQ_OLD,
    401 	REQ_NEW
    402 } callstyle_t;
    403 
    404 
    405 #define	daemon_request_new daemon_request
    406 
    407 typedef struct mdq_anchor {
    408 	DAEMON_QUEUE
    409 	kcondvar_t	 a_cv;		/* Request has been put on queue */
    410 	kmutex_t	 a_mx;
    411 } mdq_anchor_t;
    412 
    413 typedef struct daemon_request {
    414 	DAEMON_QUEUE
    415 	kmutex_t	dr_mx;
    416 	int		dr_pending;
    417 	timeout_id_t	dr_timeout_id;
    418 } daemon_request_t;
    419 
    420 typedef struct sv_dev {
    421 	set_t	setno;
    422 	side_t	side;
    423 	mdkey_t	key;
    424 } sv_dev_t;
    425 
    426 /*
    427  * Types of device probes
    428  */
    429 
    430 
    431 typedef struct probe_req {
    432 	DAEMON_QUEUE
    433 	minor_t mnum;			/* mnum of the metadevice to probe */
    434 	void   *private_handle;		/* private handle */
    435 	intptr_t (*probe_fcn)();	/* type of probeing to be done */
    436 } probe_req_t;
    437 
    438 /* Global flags */
    439 #define	MD_NO_GBL_LOCKS_HELD	0x0000	/* currently holding no global locks */
    440 #define	MD_GBL_DAEMONS_LIVE	0x0001	/* master daemon has been started. */
    441 #define	MD_GBL_DAEMONS_DIE	0x0002
    442 #define	MD_GBL_HALTED		0x0004	/* driver is shut down */
    443 
    444 /* Available bit was GBL_STALE	0x0008	*/
    445 
    446 #define	MD_GBL_IOCTL_LOCK	0x0010	/* single-threads ioctls */
    447 #define	MD_GBL_HS_LOCK		0x0020	/* single-threads hotspares */
    448 #define	MD_GBL_OPEN		0x0040	/* admin is open */
    449 #define	MD_GBL_EXCL		0x0080	/* admin is open exclusively */
    450 
    451 #define	MD_OFLG_NULL		0x0000	/* Null flag */
    452 #define	MD_OFLG_CONT_ERRS	0x0001	/* Continue on open errors */
    453 #define	MD_OFLG_PROBEDEV	0x0002  /* force a simulated open */
    454 #define	MD_OFLG_ISINIT		0x0004  /* raid initialization */
    455 #define	MD_OFLG_FROMIOCTL	0x0008  /* Called from an ioctl handler */
    456 
    457 
    458 typedef struct md_named_services {
    459 
    460 	intptr_t	(*md_service)();
    461 	char		*md_name;
    462 } md_named_services_t;
    463 
    464 typedef enum md_snarfcmd {MD_SNARF_CLEANUP, MD_SNARF_DOIT} md_snarfcmd_t;
    465 
    466 typedef struct md_ops {
    467 	int	(*md_open)(
    468 		    dev_t		*devp,
    469 		    int			flag,
    470 		    int			otyp,
    471 		    cred_t		*credp,
    472 		    int			md_oflags);
    473 	int	(*md_close)(
    474 		    dev_t		dev,
    475 		    int			flag,
    476 		    int			otyp,
    477 		    cred_t		*credp,
    478 		    int			md_oflags);
    479 	void	(*md_strategy)(
    480 		    buf_t		*bufp,
    481 		    int			flag,
    482 		    void		*private);
    483 	int	(*md_print)();		/* unused now */
    484 	int	(*md_dump)(
    485 		    dev_t		dev,
    486 		    caddr_t		addr,
    487 		    daddr_t		blkno,
    488 		    int			nblk);
    489 	int	(*md_read)(
    490 		    dev_t		dev,
    491 		    struct uio		*uiop,
    492 		    cred_t		*credp);
    493 	int	(*md_write)(
    494 		    dev_t		dev,
    495 		    struct uio		*uiop,
    496 		    cred_t		*credp);
    497 	int	(*md_ioctl)(
    498 		    dev_t		dev,
    499 		    int			cmd,
    500 		    void		*data,
    501 		    int			mode,
    502 		    IOLOCK		*lockp);
    503 	int	(*md_snarf)(
    504 		    md_snarfcmd_t	cmd,
    505 		    set_t		setno);
    506 	int	(*md_halt)();
    507 	int	(*md_aread)(
    508 		    dev_t		dev,
    509 		    struct aio_req	*aiop,
    510 		    cred_t		*credp);
    511 	int	(*md_awrite)(
    512 		    dev_t		dev,
    513 		    struct aio_req	*aiop,
    514 		    cred_t		*credp);
    515 	int	(*md_imp_set)(
    516 		    set_t		setno);
    517 	md_named_services_t	*md_services;
    518 	md_krwlock_t		md_link_rw;
    519 	md_link_t		*md_head;
    520 	/*
    521 	 * NOTE: when TSlvm s10/onnv compatibility is not an issue:
    522 	 *	o md_modid and md_locked should be deleted.
    523 	 *	o md_mod should be added
    524 	 *		ddi_modhandle_t		md_mod;
    525 	 *	  and used instead of the md_mods array (md_mods should
    526 	 *	  be deleted).
    527 	 */
    528 	int			md_modid;
    529 	int			md_locked;
    530 	int			md_selfindex;
    531 	struct md_ops		*md_next;
    532 	md_driver_t		md_driver;
    533 	/* NOTE: TSlvm depends on offsets in and sizeof this structure */
    534 } md_ops_t;
    535 
    536 /* macro to generate linkage for a md misc plugin module */
    537 #define	md_noop
    538 #define	MD_PLUGIN_MISC_MODULE(desc, init_init, fini_uninit)		\
    539 	static struct modlmisc		modlmisc = {			\
    540 		&mod_miscops, "Solaris Volume Manager " desc		\
    541 	};								\
    542 	static struct modlinkage	modlinkage = {			\
    543 		MODREV_1, (void *)&modlmisc, NULL			\
    544 	};								\
    545 	int								\
    546 	_init(void)							\
    547 	{								\
    548 		int	i;						\
    549 		init_init;						\
    550 		if ((i = mod_install(&modlinkage)) != 0) {		\
    551 			fini_uninit;					\
    552 		}							\
    553 		return (i);						\
    554 	}								\
    555 	int								\
    556 	_fini()								\
    557 	{								\
    558 		int	i;                                              \
    559 		if ((i = mod_remove(&modlinkage)) == 0) {		\
    560 			fini_uninit;					\
    561 		}							\
    562 		return (i);						\
    563 	}								\
    564 	int								\
    565 	_info(struct modinfo *modinfop)					\
    566 	{								\
    567 		return (mod_info(&modlinkage, modinfop));		\
    568 	}
    569 
    570 typedef enum md_haltcmd {MD_HALT_ALL, MD_HALT_CHECK, MD_HALT_DOIT,
    571 			MD_HALT_CLOSE, MD_HALT_OPEN, MD_HALT_UNLOAD
    572 } md_haltcmd_t;
    573 
    574 /*
    575  * To support cpr (Energy Star) we need to know when the resync threads are
    576  * running to not allow suspention.
    577  */
    578 typedef struct md_resync_thds_cnt {
    579 	int md_raid_resync;	/* count of active raid resync threads */
    580 	int md_mirror_resync;	/* count of active mirror resync threads */
    581 	kmutex_t md_resync_mutex;	/* protects both resync counts */
    582 } md_resync_t;
    583 
    584 /*
    585  * flags used with call to individual strategy routines
    586  */
    587 #define	MD_STR_PASSEDON 0x0000ffff
    588 #define	MD_STR_NOTTOP	0x00000001
    589 #define	MD_STR_MAPPED	0x00000002	/* set when buf_t is mapped in	*/
    590 #define	MD_STR_ABR	0x00000004	/* use ABR to handle any recovery */
    591 #define	MD_STR_WMUPDATE	0x00000008	/* set if updating watermarks for sp */
    592 #define	MD_IO_COUNTED	0x00000400	/* io has been counted */
    593 #define	MD_NOBLOCK	0x00000800	/* do not block io durring release */
    594 
    595 #define	MD_STR_WAR	0x00010000	/* this write is write after read */
    596 #define	MD_STR_WOW	0x00020000	/* handling a write-on-write */
    597 #define	MD_STR_DMR	0x00040000	/* Directed Read request */
    598 #define	MD_STR_DIRTY_RD	0x00080000	/* Read of a dirty block */
    599 #define	MD_STR_FLAG_ERR	0x00100000	/* Flag any write error on this i/o */
    600 #define	MD_STR_BLOCK_OK	0x00200000	/* Flag if caller i/o can be blocked */
    601 
    602 /*
    603  * Bits for return value of md_getdevnum
    604  */
    605 #define	MD_TRUST_DEVT	1
    606 #define	MD_NOTRUST_DEVT	0
    607 
    608 /* Flag for drivers to pass to kmem_cache_alloc() */
    609 #define	MD_ALLOCFLAGS   (KM_PUSHPAGE | KM_SLEEP)
    610 
    611 /* Named services */
    612 #define	MD_CHECK_OFFLINE	"check_offline"
    613 #define	MD_INC_ABR_COUNT	"inc abr count"
    614 #define	MD_DEC_ABR_COUNT	"dec abr count"
    615 
    616 /* md_getdevname_common flags for namespace lock */
    617 #define	MD_WAIT_LOCK	0
    618 #define	MD_NOWAIT_LOCK	1
    619 
    620 /* Externals from md.c */
    621 extern int	md_snarf_db_set(set_t setno, md_error_t *ep);
    622 extern void	get_info(struct dk_cinfo *, minor_t);
    623 extern void	get_minfo(struct dk_minfo *, minor_t);
    624 extern int	mdstrategy(buf_t *);
    625 extern int	md_create_minor_node(set_t, minor_t);
    626 extern void	md_nblocks_set(minor_t mnum, uint64_t nblocks);
    627 
    628 /* External from md_subr.c */
    629 extern int	md_inc_iocount(set_t);
    630 extern void	md_inc_iocount_noblock(set_t);
    631 extern void	md_dec_iocount(set_t);
    632 extern int	md_isblock_setio(set_t);
    633 extern int	md_block_setio(set_t);
    634 extern void	md_clearblock_setio(set_t);
    635 extern void	md_unblock_setio(set_t);
    636 extern int	md_tas_block_setio(set_t);
    637 extern void	md_biodone(struct buf *);
    638 extern void	md_bioreset(struct buf *);
    639 extern md_dev64_t md_xlate_targ_2_mini(md_dev64_t);
    640 extern md_dev64_t md_xlate_mini_2_targ(md_dev64_t);
    641 extern void	md_xlate_free(int);
    642 extern major_t	md_targ_name_to_major(char *);
    643 extern char	*md_targ_major_to_name(major_t);
    644 extern void	md_majortab_free();
    645 extern void	md_set_status(int);
    646 extern void	md_clr_status(int);
    647 extern int	md_get_status(void);
    648 extern void	md_set_setstatus(set_t, int);
    649 extern void	md_clr_setstatus(set_t, int);
    650 extern uint_t	md_get_setstatus(set_t);
    651 extern void	*md_unit_readerlock(mdi_unit_t *);
    652 extern void	*md_unit_writerlock(mdi_unit_t *);
    653 extern void	md_unit_readerexit(mdi_unit_t *);
    654 extern void	md_unit_writerexit(mdi_unit_t *);
    655 extern void	md_ioctl_releaselocks(int, int, mdi_unit_t *);
    656 extern void	md_ioctl_reacquirelocks(int, mdi_unit_t *);
    657 extern int	md_ioctl_lock_exit(int, int, mdi_unit_t *, int);
    658 extern int	md_ioctl_lock_enter(void);
    659 extern void	*md_ioctl_readerlock(IOLOCK *, mdi_unit_t *);
    660 extern void	md_ioctl_readerexit(IOLOCK *);
    661 extern void	*md_ioctl_writerlock(IOLOCK *, mdi_unit_t *);
    662 extern void	md_ioctl_writerexit(IOLOCK *);
    663 extern void	md_ioctl_io_exit(IOLOCK *);
    664 extern void	*md_ioctl_io_lock(IOLOCK *, mdi_unit_t *);
    665 extern void	md_ioctl_droplocks(IOLOCK *);
    666 extern void	md_array_writer(IOLOCK *);
    667 extern void	md_array_reader(IOLOCK *);
    668 extern void	*md_ioctl_openclose_enter(IOLOCK *, mdi_unit_t *);
    669 extern void	md_ioctl_openclose_exit(IOLOCK *);
    670 extern void	md_ioctl_openclose_exit_lh(IOLOCK *);
    671 extern void	*md_unit_openclose_enter(mdi_unit_t *);
    672 extern void	md_unit_openclose_exit(mdi_unit_t *);
    673 extern void	md_unit_openclose_exit_lh(mdi_unit_t *);
    674 extern int	md_unit_isopen(mdi_unit_t *ui);
    675 extern int	md_unit_incopen(minor_t mnum, int flag, int otyp);
    676 extern int	md_unit_decopen(minor_t mnum, int otyp);
    677 extern void	*md_io_readerlock(mdi_unit_t *);
    678 extern void	*md_io_writerlock(mdi_unit_t *);
    679 extern void	md_io_readerexit(mdi_unit_t *);
    680 extern void	md_io_writerexit(mdi_unit_t *);
    681 extern intptr_t	(*md_get_named_service())();
    682 extern int	init_requestq(md_requestq_entry_t *, void (*)(),
    683 						caddr_t, int, int);
    684 extern void	daemon_request(mdq_anchor_t *, void(*)(),
    685 				daemon_queue_t *, callstyle_t);
    686 extern void	md_daemon(int, mdq_anchor_t *);
    687 extern void	mddb_commitrec_wrapper(mddb_recid_t);
    688 extern void	mddb_commitrecs_wrapper(mddb_recid_t *);
    689 extern void	mddb_deleterec_wrapper(mddb_recid_t);
    690 extern void	md_holdset_enter(set_t setno);
    691 extern void	md_holdset_exit(set_t setno);
    692 extern int	md_holdset_testandenter(set_t setno);
    693 extern void	md_haltsnarf_enter(set_t setno);
    694 extern void	md_haltsnarf_exit(set_t setno);
    695 extern void	md_haltsnarf_wait(set_t setno);
    696 extern int	md_halt_set(set_t setno, enum md_haltcmd cmd);
    697 extern int	md_halt(int global_lock_flag);
    698 extern int	md_layered_open(minor_t, md_dev64_t *, int);
    699 extern void	md_layered_close(md_dev64_t, int);
    700 extern char	*md_get_device_name(md_dev64_t);
    701 extern int	errdone(mdi_unit_t *, struct buf *, int);
    702 extern int	md_checkbuf(mdi_unit_t *, md_unit_t *, buf_t *);
    703 extern int	md_start_daemons(int init_queues);
    704 extern int	md_loadsubmod(set_t, char *, int);
    705 extern int	md_getmodindex(md_driver_t *, int, int);
    706 extern void	md_call_strategy(buf_t *, int, void *);
    707 extern int	md_call_ioctl(md_dev64_t, int, void *, int, IOLOCK *);
    708 extern void	md_rem_link(set_t, int, krwlock_t *, md_link_t **);
    709 extern int	md_dev_exists(md_dev64_t);
    710 extern md_parent_t md_get_parent(md_dev64_t);
    711 extern void	md_set_parent(md_dev64_t, md_parent_t);
    712 extern void	md_reset_parent(md_dev64_t);
    713 extern struct hot_spare_pool *find_hot_spare_pool(set_t, int);
    714 extern int	md_hot_spare_ifc(hs_cmds_t, mddb_recid_t, u_longlong_t, int,
    715 		    mddb_recid_t *, mdkey_t *, md_dev64_t *, diskaddr_t *);
    716 extern int	md_notify_interface(md_event_cmds_t cmd, md_tags_t type,
    717 		set_t set, md_dev64_t dev, md_event_type_t event);
    718 extern void	svm_gen_sysevent(char *se_class, char *se_subclass,
    719 		    uint32_t tag, set_t setno, md_dev64_t devid);
    720 extern void	md_create_unit_incore(minor_t, md_ops_t *, int);
    721 extern void	md_destroy_unit_incore(minor_t, md_ops_t *);
    722 extern void	md_rem_names(sv_dev_t *, int);
    723 struct uio;
    724 extern int	md_chk_uio(struct uio *);
    725 extern char	*md_shortname(minor_t mnum);
    726 extern char	*md_devname(set_t setno, md_dev64_t dev, char *buf,
    727 		size_t size);
    728 extern void	md_minphys(buf_t *);
    729 extern void	md_kstat_init(minor_t mnum);
    730 extern void	md_kstat_init_ui(minor_t mnum, mdi_unit_t *ui);
    731 extern void	md_kstat_destroy(minor_t mnum);
    732 extern void	md_kstat_destroy_ui(mdi_unit_t *ui);
    733 extern void	md_kstat_waitq_enter(mdi_unit_t *ui);
    734 extern void	md_kstat_waitq_to_runq(mdi_unit_t *ui);
    735 extern void	md_kstat_waitq_exit(mdi_unit_t *ui);
    736 extern void	md_kstat_runq_enter(mdi_unit_t *ui);
    737 extern void	md_kstat_runq_exit(mdi_unit_t *ui);
    738 extern void	md_kstat_done(mdi_unit_t *ui, buf_t *bp, int war);
    739 extern pid_t	md_getpid(void);
    740 extern proc_t	*md_getproc(void);
    741 extern int	md_checkpid(pid_t pid, proc_t *proc);
    742 extern char	*md_strdup(char *cp);
    743 extern void	freestr(char *cp);
    744 extern int	md_check_ioctl_against_unit(int, mdc_unit_t);
    745 extern mddb_recid_t md_vtoc_to_efi_record(mddb_recid_t, set_t);
    746 
    747 extern int	mdmn_ksend_message(set_t, md_mn_msgtype_t, uint_t,
    748 		    md_mn_nodeid_t, char *, int, md_mn_kresult_t *);
    749 extern void	mdmn_ksend_show_error(int, md_mn_kresult_t *, const char *);
    750 extern int	mdmn_send_capability_message(minor_t, volcap_t, IOLOCK *);
    751 extern void	mdmn_clear_all_capabilities(minor_t);
    752 extern int	md_init_probereq(struct md_probedev_impl *p,
    753 		    daemon_queue_t **hdrpp);
    754 extern boolean_t callb_md_mrs_cpr(void *, int);
    755 extern void	md_upd_set_unnext(set_t, unit_t);
    756 extern int	md_rem_selfname(minor_t);
    757 extern void	md_rem_hspname(set_t, mdkey_t);
    758 extern void	*md_create_taskq(set_t, minor_t);
    759 
    760 /* Externals from md_ioctl.c */
    761 extern int	md_mn_is_commd_present(void);
    762 extern int	md_mn_is_commd_present_lite(void);
    763 extern void	md_mn_clear_commd_present(void);
    764 extern int	md_admin_ioctl(md_dev64_t, int, caddr_t, int, IOLOCK *lockp);
    765 extern void	md_get_geom(md_unit_t *, struct dk_geom *);
    766 extern int	md_set_vtoc(md_unit_t *, struct vtoc *);
    767 extern void	md_get_vtoc(md_unit_t *, struct vtoc *);
    768 extern int	md_set_extvtoc(md_unit_t *, struct extvtoc *);
    769 extern void	md_get_extvtoc(md_unit_t *, struct extvtoc *);
    770 extern void	md_get_cgapart(md_unit_t *, struct dk_map *);
    771 extern void	md_get_efi(md_unit_t *, char *);
    772 extern int	md_set_efi(md_unit_t *, char *);
    773 extern int	md_dkiocgetefi(minor_t, void *, int);
    774 extern int	md_dkiocsetefi(minor_t, void *, int);
    775 extern int	md_dkiocpartition(minor_t, void *, int);
    776 extern void	md_remove_minor_node(minor_t);
    777 
    778 
    779 /* Externals from md_names.c */
    780 extern mdkey_t	md_setdevname(set_t, side_t, mdkey_t, char *, minor_t, char *,
    781 		    int imp_flag, ddi_devid_t devid, char *minorname,
    782 			set_t, md_error_t *);
    783 extern int	md_getdevname(set_t, side_t, mdkey_t, md_dev64_t, char *,
    784 		    size_t);
    785 extern int	md_getdevname_common(set_t, side_t, mdkey_t, md_dev64_t, char *,
    786 		    size_t, int);
    787 extern int	md_gethspinfo(set_t, side_t, mdkey_t, char *, hsp_t *,
    788 		    char *);
    789 extern int	md_getkeyfromdev(set_t, side_t, md_dev64_t, mdkey_t *, int *);
    790 extern int	md_devid_found(set_t, side_t, mdkey_t);
    791 extern int	md_getnment(set_t, side_t, mdkey_t, md_dev64_t,
    792 		    char *, uint_t, major_t *, minor_t *, mdkey_t *);
    793 extern md_dev64_t md_getdevnum(set_t, side_t, mdkey_t, int);
    794 extern mdkey_t	md_getnextkey(set_t, side_t, mdkey_t, uint_t *);
    795 extern int	md_remdevname(set_t, side_t, mdkey_t);
    796 extern mdkey_t	md_setshared_name(set_t, char *, int);
    797 extern char	*md_getshared_name(set_t, mdkey_t);
    798 extern int	md_remshared_name(set_t, mdkey_t);
    799 extern mdkey_t	md_getshared_key(set_t, char *);
    800 extern int	md_setshared_data(set_t, uint_t, caddr_t);
    801 extern caddr_t	md_getshared_data(set_t, uint_t);
    802 extern int	md_load_namespace(set_t, md_error_t *ep, int);
    803 extern void	md_unload_namespace(set_t, int);
    804 extern int	md_nm_did_chkspace(set_t);
    805 extern void	md_bioinit();
    806 extern buf_t	*md_bioclone(buf_t *, off_t, size_t, dev_t, diskaddr_t,
    807 		    int (*)(buf_t *), buf_t *, int);
    808 extern int	md_getdevid(set_t setno, side_t side, mdkey_t key,
    809 		    ddi_devid_t devid, ushort_t *did_size);
    810 extern int	md_getdevidminor(set_t setno, side_t side, mdkey_t key,
    811 		    char *minorname, size_t minorname_len);
    812 extern int	md_update_namespace(set_t setno, side_t side, mdkey_t key,
    813 		    caddr_t devname, caddr_t pathname, minor_t mnum);
    814 extern int	md_update_locator_namespace(set_t setno, side_t side,
    815 		    caddr_t devname, caddr_t pathname, md_dev64_t devt);
    816 extern int	md_update_namespace_did(set_t setno, side_t side, mdkey_t key,
    817 		    md_error_t *ep);
    818 extern int	md_validate_devid(set_t setno, side_t side, int *maxsz);
    819 extern int	md_get_invdid(set_t setno, side_t side, int cnt, int maxsz,
    820 		    void *didptr);
    821 extern md_dev64_t md_resolve_bydevid(minor_t, md_dev64_t, mdkey_t key);
    822 extern md_dev64_t md_expldev(md_dev64_t);
    823 extern dev32_t	md_cmpldev(md_dev64_t);
    824 extern dev_t	md_dev64_to_dev(md_dev64_t);
    825 extern md_dev64_t md_makedevice(major_t, minor_t);
    826 extern major_t	md_getmajor(md_dev64_t);
    827 extern minor_t	md_getminor(md_dev64_t);
    828 extern void	md_timeval(md_timeval32_t *);
    829 extern int	md_imp_snarf_set(mddb_config_t *);
    830 
    831 /* externals from md_mddb.c */
    832 extern int	mddb_reread_rr(set_t, mddb_recid_t);
    833 extern int	mddb_setowner(mddb_recid_t id, md_mn_nodeid_t owner);
    834 extern int	mddb_parse(mddb_parse_parm_t *mpp);
    835 extern int	mddb_block(mddb_block_parm_t *mpp);
    836 extern int	mddb_optrecfix(mddb_optrec_parm_t *mop);
    837 extern int	mddb_check_write_ioctl(mddb_config_t *info);
    838 extern int	mddb_setflags_ioctl(mddb_setflags_config_t *info);
    839 extern struct nm_next_hdr	*get_first_record(set_t, int, int);
    840 extern void	*lookup_entry(struct nm_next_hdr *, set_t,
    841 			side_t, mdkey_t, md_dev64_t, int);
    842 extern void	*lookup_shared_entry(struct nm_next_hdr *,
    843 		    mdkey_t key, char *, mddb_recid_t *, int);
    844 extern int	remove_shared_entry(struct nm_next_hdr *, mdkey_t key,
    845 		    char *, int);
    846 extern void	*alloc_entry(struct nm_next_hdr *, mddb_recid_t, size_t, int,
    847 		    mddb_recid_t *);
    848 extern void	*getshared_name(set_t, mdkey_t, int);
    849 
    850 #endif	/* _KERNEL */
    851 
    852 
    853 /* externals from md_revchk.c */
    854 extern int	revchk(uint_t my_rev, uint_t data);
    855 
    856 
    857 #ifdef	__cplusplus
    858 }
    859 #endif
    860 
    861 #endif	/* _SYS_MDVAR_H */
    862