Home | History | Annotate | Download | only in head
      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	_META_H
     28 #define	_META_H
     29 
     30 #include <limits.h>
     31 #include <stdio.h>
     32 #include <stdlib.h>
     33 #include <fcntl.h>
     34 #include <errno.h>
     35 #include <string.h>
     36 #include <unistd.h>
     37 #include <libgen.h>
     38 #include <locale.h>
     39 #include <time.h>
     40 #include <assert.h>
     41 #include <stdarg.h>
     42 #include <signal.h>
     43 #include <devid.h>
     44 #include <sys/types.h>
     45 #include <sys/stat.h>
     46 #include <sys/sysmacros.h>
     47 #include <sys/mkdev.h>
     48 #include <sys/time.h>
     49 #include <sys/dkio.h>
     50 #include <sys/vtoc.h>
     51 #include <sys/efi_partition.h>
     52 #include <meta_basic.h>
     53 #include <mdiox.h>
     54 #include <metamed.h>
     55 #include <sys/lvm/mdio.h>
     56 #include <sys/lvm/md_mddb.h>
     57 #include <sys/lvm/md_sp.h>
     58 #include <sys/lvm/mdmn_commd.h>
     59 
     60 #ifdef	__cplusplus
     61 extern "C" {
     62 #endif
     63 
     64 /* debug malloc include */
     65 #ifdef	DEBUG_MALLOC
     66 #ifdef	_REENTRANT
     67 die right now
     68 #endif
     69 #include <../lib/malloclib/malloc.h>
     70 #endif
     71 
     72 /*
     73  * useful macros
     74  */
     75 #ifndef	min
     76 #define	min(x, y)	(((x) < (y)) ? (x) : (y))
     77 #endif
     78 #ifndef	max
     79 #define	max(x, y)	(((x) > (y)) ? (x) : (y))
     80 #endif
     81 #ifndef	rounddown
     82 #define	rounddown(x, y)	(((x) / (y)) * (y))
     83 #endif
     84 
     85 /*
     86  * external names
     87  */
     88 
     89 #define	METATAB			"/etc/lvm/md.tab"
     90 #define	METACONF		"/etc/lvm/md.cf"
     91 #define	METACONFTMP		"/etc/lvm/md.cf.new"
     92 #define	META_DBCONF		"/etc/lvm/mddb.cf"
     93 #define	META_DBCONFTMP		"/etc/lvm/mddb.cf.new"
     94 #define	META_MNSET_NODELIST	"/var/run/nodelist"
     95 #define	METALOG			"/etc/lvm/md.log"
     96 #define	METALOCK		"/etc/lvm/lock"
     97 #define	METADEVPATH		"/etc/lvm/devpath"
     98 #define	METALOGENV		"MD_LOG"
     99 #define	METAPKGROOT		"/usr"
    100 #define	ADMSPECIAL		"/dev/md/admin"
    101 
    102 #define	MDB_STR			"metadevice state database"
    103 #define	META_LONGDISKNAME_STR	"<long disk name>"
    104 
    105 /* default database size (4MB) */
    106 #define	MD_DBSIZE	(8192)
    107 
    108 /* default Multinode database size (16MB) */
    109 #define	MD_MN_DBSIZE	(32768)
    110 
    111 /* disk label size */
    112 #define	VTOC_SIZE	(16)
    113 
    114 /* EFI geometry data */
    115 #define	MD_EFI_FG_HEADS		128
    116 #define	MD_EFI_FG_SECTORS	256
    117 #define	MD_EFI_FG_RPM		7200
    118 #define	MD_EFI_FG_WRI		1
    119 #define	MD_EFI_FG_RRI		1
    120 
    121 /* maximum ctd name size (in # of digits) for printing out */
    122 #define	CTD_FORMAT_LEN	6
    123 
    124 /* Recommend timeout in seconds for RPC client creation. */
    125 #define	MD_CLNT_CREATE_TOUT	(60)
    126 
    127 /*
    128  * If event needs to be checked during wait of MD_CLNT_CREATE_TOUT,
    129  * spin checking for event and then waiting for MD_CLNT_CREATE_SUBTIMEOUT
    130  * seconds until MD_CLNT_CREATE_TOUT seconds are used.
    131  */
    132 #define	MD_CLNT_CREATE_SUBTIMEOUT	(5)
    133 
    134 /*
    135  * metaclust verbosity levels and what they are for. Messages upto MC_LOG2
    136  * will also be logged in syslog.
    137  */
    138 #define	MC_LOG0		0	/* special class. log messages regardless of */
    139 				/* debug level */
    140 #define	MC_LOG1		1	/* log standard error messages */
    141 #define	MC_LOG2		2	/* log metaclust step level timing messages */
    142 #define	MC_LOG3		3	/* log per set level timing messages */
    143 				/* intended for use in loops walking mn sets */
    144 #define	MC_LOG4		4	/* log per device level timing messages */
    145 				/* intended for use in loops walking devices */
    146 #define	MC_LOG5		5	/* typically for use in deep nested loops */
    147 				/* or in libmeta routines */
    148 
    149 /*
    150  * for meta_print* options
    151  */
    152 typedef	uint_t	mdprtopts_t;
    153 #define	PRINT_SHORT		0x00000001
    154 #define	PRINT_SUBDEVS		0x00000002
    155 #define	PRINT_HEADER		0x00000004
    156 #define	PRINT_DEBUG		0x00000008
    157 #define	PRINT_TIMES		0x00000010
    158 #define	PRINT_SETSTAT		0x00000020
    159 #define	PRINT_SETSTAT_ONLY	0x00000040
    160 #define	PRINT_FAST		0x00000080
    161 #define	PRINT_DEVID		0x00000100
    162 #define	PRINT_LARGEDEVICES	0x00000200
    163 #define	PRINT_FN		0x00000400
    164 
    165 /*
    166  * for meta_devadm options
    167  */
    168 typedef	uint_t  mddevopts_t;
    169 #define	DEV_VERBOSE		0x00000001
    170 #define	DEV_NOACTION		0x00000002
    171 #define	DEV_LOG			0x00000004
    172 #define	DEV_RELOAD		0x00000008
    173 #define	DEV_UPDATE		0x00000010
    174 #define	DEV_LOCAL_SET		0x00000020	/* update only MD_LOCAL_SET */
    175 
    176 /*
    177  * return values for meta_devadm operations
    178  */
    179 #define	METADEVADM_SUCCESS	0
    180 #define	METADEVADM_ERR		1
    181 #define	METADEVADM_DEVIDINVALID	2
    182 #define	METADEVADM_DSKNAME_ERR	3
    183 #define	METADEVADM_DISKMOVE	4
    184 
    185 /*
    186  * return values for the splitname function
    187  */
    188 #define	METASPLIT_SUCCESS		0
    189 #define	METASPLIT_LONGPREFIX		1
    190 #define	METASPLIT_LONGDISKNAME		2
    191 
    192 /*
    193  * meta_check* options
    194  */
    195 typedef	uint_t	mdchkopts_t;
    196 #define	MDCHK_ALLOW_MDDB	0x01	/* allows repliica in md's (metainit) */
    197 #define	MDCHK_ALLOW_HS		0x02	/* allows hs in multiple hsp's (hs) */
    198 #define	MDCHK_ALLOW_LOG		0x04	/* allows sharing of logs (trans) */
    199 #define	MDCHK_ALLOW_REPSLICE	0x08	/* allow replica slice to be used */
    200 #define	MDCHK_ALLOW_NODBS	0x10	/* no db replicas allowed (metadb) */
    201 #define	MDCHK_DRVINSET		0x20	/* drive is in set (metaset) */
    202 #define	MDCHK_SET_LOCKED	0x40	/* The set is locked */
    203 #define	MDCHK_SET_FORCE		0x80	/* This is a forced operation */
    204 
    205 /*
    206  * meta_check_inuse options
    207  */
    208 typedef uint_t	mdinuseopts_t;
    209 #define	MDCHK_SWAP	0x01		/* check swap & overlap w/swap */
    210 #define	MDCHK_DUMP	0x02		/* check dump & overlap w/dump */
    211 #define	MDCHK_MOUNTED	0x04		/* check mounted & overlap w/mounted */
    212 #define	MDCHK_INUSE	0xff		/* check all */
    213 
    214 /*
    215  * meta* force options
    216  */
    217 typedef	uint_t	mdforceopts_t;
    218 #define	MDFORCE_NONE		0x01	/* no extra force used */
    219 #define	MDFORCE_LOCAL		0x02	/* force from metadb command line */
    220 #define	MDFORCE_DS		0x04	/* force from metaset library */
    221 #define	MDFORCE_SET_LOCKED	0x10	/* The set is locked */
    222 
    223 
    224 /*
    225  * meta* options
    226  */
    227 typedef	uint_t	mdcmdopts_t;
    228 #define	MDCMD_DOIT		0x0001	/* really do operation */
    229 #define	MDCMD_FORCE		0x0002	/* force operation */
    230 #define	MDCMD_PRINT		0x0004	/* print success messages to stdout */
    231 #define	MDCMD_RECURSE		0x0008	/* recursive operation */
    232 #define	MDCMD_INIT		0x0010	/* init operation */
    233 #define	MDCMD_UPDATE		0x0020	/* update sizes used w/o DOIT mostly */
    234 #define	MDCMD_NOLOCK		0x0040	/* lock already held, DONT acquire */
    235 #define	MDCMD_VERBOSE		0x0100	/* be verbose */
    236 #define	MDCMD_USE_WHOLE_DISK	0x0200	/* repartition disk */
    237 #define	MDCMD_DIRECT		0x0400	/* extents specified directly */
    238 #define	MDCMD_ALLOPTION		0x0800	/* the all option is being used */
    239 #define	MDCMD_MN_OPEN_CHECK	0x1000	/* Perform open check on all nodes */
    240 
    241 /*
    242  * meta_tab* definitions
    243  */
    244 #define	TAB_ARG_ALLOC	5
    245 #define	TAB_LINE_ALLOC	10
    246 
    247 typedef uint_t mdinittypes_t;
    248 #define	TAB_UNKNOWN		0x0000
    249 #define	TAB_MDDB		0x0001
    250 #define	TAB_HSP			0x0002
    251 #define	TAB_STRIPE		0x0004
    252 #define	TAB_MIRROR		0x0008
    253 #define	TAB_RAID		0x0010
    254 #define	TAB_TRANS		0x0020
    255 #define	TAB_SP			0x0040
    256 #define	TAB_MD			(TAB_STRIPE | TAB_MIRROR | TAB_RAID |\
    257 					TAB_TRANS | TAB_SP)
    258 #define	TAB_MD_HSP		(TAB_MD | TAB_HSP)
    259 
    260 typedef	struct {
    261 	mdinittypes_t	type;
    262 	char		*context;
    263 	char		*cname;
    264 	int		argc;
    265 	char		**argv;
    266 	size_t		alloc;
    267 	uint_t		flags;	/* for application use */
    268 } md_tab_line_t;
    269 
    270 typedef	struct {
    271 	char		*filename;
    272 	char		*data;
    273 	size_t		total;
    274 	size_t		nlines;
    275 	md_tab_line_t	*lines;
    276 	size_t		alloc;
    277 } md_tab_t;
    278 
    279 /*
    280  * disk status definitions
    281  */
    282 typedef struct md_disk_status_list {
    283 	struct md_disk_status_list	*next;
    284 	mddrivename_t			*drivenamep;
    285 	md_error_t			status;
    286 } md_disk_status_list_t;
    287 
    288 /*
    289  * module name list used by meta_patch_root & meta_systemfile
    290  */
    291 struct modname {
    292 	char		*name;
    293 	struct modname	*next;
    294 };
    295 
    296 /*
    297  * list to be used for printing Device Relocation Information
    298  */
    299 typedef struct mddevid_t {
    300 	struct mddevid_t *next;
    301 	char *ctdname;
    302 	mdkey_t key;
    303 } mddevid_t;
    304 
    305 /*
    306  * Multi-Node Diskset List
    307  *
    308  * we either store the IP address of the private interconnect or its name
    309  * in the msl_node_addr member
    310  */
    311 typedef struct mndiskset_membershiplist {
    312 	uint_t				msl_node_id;
    313 	md_mnnode_nm_t			msl_node_name;
    314 	md_mnnode_nm_t			msl_node_addr;
    315 	struct mndiskset_membershiplist	*next;
    316 } mndiskset_membershiplist_t;
    317 
    318 /*
    319  * client pool for rpc calls to mdcommd
    320  */
    321 typedef struct md_mn_client_list {
    322 	CLIENT *mcl_clnt;
    323 	struct md_mn_client_list *mcl_next;
    324 } md_mn_client_list_t;
    325 
    326 /*
    327  * Resync thread manipulation commands.
    328  *
    329  * The resync thread can now be started, blocked, unblocked or killed.
    330  * This typedef specifies the action to be taken by meta_resync.c
    331  * routines.
    332  */
    333 typedef enum {
    334 	MD_RESYNC_START = 1,
    335 	MD_RESYNC_BLOCK,
    336 	MD_RESYNC_UNBLOCK,
    337 	MD_RESYNC_KILL,
    338 	MD_RESYNC_KILL_NO_WAIT,
    339 	MD_RESYNC_FORCE_MNSTART
    340 } md_resync_cmd_t;
    341 
    342 
    343 /*
    344  * rpc.metad macro definitions.
    345  */
    346 #define	METAD_SETUP_DR(cmd, id)	\
    347 	{				\
    348 	req.ur_cmd = cmd;		\
    349 	req.ur_setno = MD_LOCAL_SET;	\
    350 	req.ur_type = MDDB_USER;	\
    351 	req.ur_type2 = MDDB_UR_DR;	\
    352 	req.ur_recid = id;		\
    353 	}
    354 
    355 #define	METAD_SETUP_NR(cmd, id)	\
    356 	{				\
    357 	req.ur_cmd = cmd;		\
    358 	req.ur_setno = MD_LOCAL_SET;	\
    359 	req.ur_type = MDDB_USER;	\
    360 	req.ur_type2 = MDDB_UR_NR;	\
    361 	req.ur_recid = id;		\
    362 	}
    363 
    364 #define	METAD_SETUP_SR(cmd, id)	\
    365 	{				\
    366 	req.ur_cmd = cmd;		\
    367 	req.ur_setno = MD_LOCAL_SET;	\
    368 	req.ur_type = MDDB_USER;	\
    369 	req.ur_type2 = MDDB_UR_SR;	\
    370 	req.ur_recid = id;		\
    371 	}
    372 
    373 #define	METAD_SETUP_UR(cmd, type2, id)	\
    374 	{				\
    375 	req.ur_cmd = cmd;		\
    376 	req.ur_setno = MD_LOCAL_SET;	\
    377 	req.ur_type = MDDB_USER;	\
    378 	req.ur_type2 = type2;		\
    379 	req.ur_recid = id;		\
    380 	}
    381 
    382 #define	METAD_SETUP_LR(cmd, setno, id)	\
    383 	{				\
    384 	req.ur_cmd = cmd;		\
    385 	req.ur_setno = setno;	\
    386 	req.ur_type = MDDB_USER;	\
    387 	req.ur_type2 = MDDB_UR_LR;	\
    388 	req.ur_recid = id;		\
    389 	}
    390 
    391 /*
    392  * This typedef specifies the signature of a function that
    393  * meta_client_create_retry can use to establish an rpc connection.
    394  * private is used to pass data from the caller of meta_client_create_retry
    395  * to clnt_create_func.
    396  */
    397 typedef CLIENT *(*clnt_create_func_t)(char *hostname,
    398 	void *private,
    399 	struct timeval *time_out);
    400 
    401 /* definition of the table for the different message types */
    402 typedef struct md_mn_msg_tbl_entry {
    403 	md_mn_msgclass_t	mte_class;
    404 	void (*mte_handler)
    405 	    (md_mn_msg_t *msg, uint_t flags, md_mn_result_t *res);
    406 	int (*mte_smgen)
    407 	    (md_mn_msg_t *msg, md_mn_msg_t **msglist);
    408 	time_t		mte_timeout; /* seconds before msg times out */
    409 	uint_t		mte_retry1; /* nretries in case of class busy */
    410 	uint_t		mte_ticks1; /* sleep nticks before retry */
    411 	uint_t		mte_retry2; /* nretries in case of comm fail */
    412 	uint_t		mte_ticks2; /* sleep nticks before retry */
    413 } md_mn_msg_tbl_entry_t;
    414 
    415 /*
    416  * Flags for the take command
    417  */
    418 #define	TAKE_FORCE	0x0001
    419 #define	TAKE_USETAG	0x0002
    420 #define	TAKE_USEIT	0x0004
    421 #define	TAKE_IMP	0x0008
    422 #define	TAKE_RETAKE	0x0010
    423 
    424 /*
    425  * ignore gettext for lint so we check printf args
    426  */
    427 #ifdef __lint
    428 #define	dgettext(d, s)	s
    429 #define	gettext(s)	s
    430 #endif
    431 
    432 /*
    433  * Defines for enabling/disabling SVM services in SMF.
    434  */
    435 #define	META_SMF_CORE		0x01
    436 #define	META_SMF_DISKSET	0x02
    437 #define	META_SMF_MN_DISKSET	0x04
    438 #define	META_SMF_ALL		0xFF
    439 
    440 /*
    441  * Defines to send/not_send addition of mddb sidenames to
    442  * rpc.mdcommd for MN disksets.
    443  */
    444 #define	DB_ADDSIDENMS_NO_BCAST	0
    445 #define	DB_ADDSIDENMS_BCAST	1
    446 
    447 /*
    448  * Defines and structures to support rpc.mdcommd.
    449  * RPC routines in rpc.metad will be used to suspend, resume
    450  * and reinitialize the rpc.mdcommd running on that node.
    451  * These actions are needed when the nodelist is changing.
    452  */
    453 #define	COMMDCTL_SUSPEND	1
    454 #define	COMMDCTL_RESUME		2
    455 #define	COMMDCTL_REINIT		3
    456 
    457 /*
    458  * Defines used when joining a node to a MN diskset.
    459  * A MN diskset is stale if < 50% mddbs are available when the first node
    460  * joins the set.  A MN diskset is stale when 50% mddbs are available when
    461  * the first node joins the set if the mediator is unable to provide an
    462  * extra vote.
    463  * Once a MN set is marked stale, it stays in the stale state (even if > 50%
    464  * mddbs are available) until all nodes are withdrawn from the diskset.
    465  * Any new nodes joining a stale MN diskset are marked stale regardless of
    466  * the availability of mddbs in order to keep the diskset consistent across
    467  * all nodes.
    468  *
    469  * If a reconfig cycle is underway, set the reconfig flag so that rpc.metad
    470  * clnt_locks are not enforced.  Since the reconfig cycle has locked out the
    471  * meta* commands, this is safe to do.
    472  */
    473 #define	MNSET_IS_STALE		1	/* Is MN set stale? */
    474 #define	MNSET_IN_RECONFIG	2	/* Is MN set in reconfig? */
    475 
    476 /*
    477  * Structure used during reconfig step2 to aid in sychronization
    478  * of the drives in a diskset.
    479  */
    480 typedef struct md_mnsr_node {
    481 	md_mnset_record		*mmn_mnsr;
    482 	md_mnnode_nm_t		mmn_nodename;
    483 	int			mmn_numdrives;
    484 	md_drive_desc		*mmn_dd;
    485 	struct md_mnsr_node	*mmn_next;
    486 } md_mnsr_node_t;
    487 
    488 
    489 /*
    490  * meta events definitions ("meta_notify.h")
    491  */
    492 
    493 /*
    494  * event flags
    495  * meta_notify_createq(),	(EXISTERR, PERMANENT)
    496  * meta_notify_getev(),		(WAIT)
    497  * meta_notify_getevlist()	(WAIT)
    498  */
    499 #define	EVFLG_WAIT	0x00000001	/* block until events are pending */
    500 #define	EVFLG_EXISTERR	0x00000002	/* if q exists, return an error */
    501 #define	EVFLG_PERMANENT	0x00000004	/* queue persists after process exit */
    502 
    503 /*
    504  * events are always associated with an underlying object
    505  * This object is of one of the following types.
    506  */
    507 typedef enum md_ev_objtype_t {
    508 	EVO_EMPTY	= 0,
    509 	EVO_METADEV,
    510 	EVO_MIRROR,
    511 	EVO_STRIPE,
    512 	EVO_RAID5,
    513 	EVO_TRANS,
    514 	EVO_REPLICA,
    515 	EVO_HSP,
    516 	EVO_HS,
    517 	EVO_SET,
    518 	EVO_DRIVE,
    519 	EVO_HOST,
    520 	EVO_MEDIATOR,
    521 	EVO_UNSPECIFIED,
    522 	EVO_LAST
    523 } ev_obj_t;
    524 
    525 /*
    526  * Specific events are sent upon state changes
    527  * in the underlying devices or when sent by
    528  * user applications. These events have a unique
    529  * type. These types map to kernel event types (sys/md_notify.h)
    530  *
    531  * When updating these UPDATE THE TABLE in lib/config/config.c
    532  */
    533 typedef enum md_ev_id_t {
    534 	EV_UNK = 0,
    535 	EV_EMPTY,
    536 	EV_CREATE,
    537 	EV_DELETE,
    538 	EV_ADD,
    539 	EV_REMOVE,
    540 	EV_REPLACE,
    541 	EV_GROW,
    542 	EV_RENAME_SRC,
    543 	EV_RENAME_DST,
    544 	EV_MEDIATOR_ADD,
    545 	EV_MEDIATOR_DELETE,
    546 	EV_HOST_ADD,
    547 	EV_HOST_DELETE,
    548 	EV_DRIVE_ADD,
    549 	EV_DRIVE_DELETE,
    550 	EV_INIT_START,
    551 	EV_INIT_FAILED,
    552 	EV_INIT_FATAL,
    553 	EV_INIT_SUCCESS,
    554 	EV_IOERR,
    555 	EV_ERRED,
    556 	EV_LASTERRED,
    557 	EV_OK,
    558 	EV_ENABLE,
    559 	EV_RESYNC_START,
    560 	EV_RESYNC_FAILED,
    561 	EV_RESYNC_SUCCESS,
    562 	EV_RESYNC_DONE,
    563 	EV_HOTSPARED,
    564 	EV_HS_FREED,
    565 	EV_HS_CHANGED,
    566 	EV_TAKEOVER,
    567 	EV_RELEASE,
    568 	EV_OPEN_FAIL,
    569 	EV_OFFLINE,
    570 	EV_ONLINE,
    571 	EV_GROW_PENDING,
    572 	EV_DETACH,
    573 	EV_DETACHING,
    574 	EV_ATTACH,
    575 	EV_ATTACHING,
    576 	EV_CHANGE,
    577 	EV_EXCHANGE,
    578 	EV_REGEN_START,
    579 	EV_REGEN_DONE,
    580 	EV_REGEN_FAILED,
    581 	EV_USER,
    582 	EV_NOTIFY_LOST,
    583 	EV_LAST
    584 } evid_t;
    585 
    586 #define	EV_ALLOBJS	(~0ULL)
    587 #define	EV_ALLSETS	((set_t)(~0))
    588 
    589 #if !defined(_KERNEL)
    590 
    591 #define	NOTIFY_MD(tag, set, dev, ev)					\
    592 	(void) meta_notify_sendev((tag), (set), (dev), (ev))
    593 
    594 #define	SE_NOTIFY(se_class, se_subclass, tag, set, dev)			\
    595 	meta_svm_sysevent((se_class), (se_subclass), (tag), (set), (dev))
    596 
    597 #endif /* _KERNEL */
    598 
    599 typedef struct md_ev {
    600 	ev_obj_t	obj_type;
    601 	set_t		setno;
    602 	evid_t		ev;
    603 	u_longlong_t	obj;	/* usually md_dev64_t or hsp id */
    604 	u_longlong_t	uev;	/* for (EV_USER) user-defined events */
    605 } md_ev_t;
    606 
    607 typedef struct md_evlist {
    608 	struct md_evlist	*next;
    609 	md_ev_t			*evp;
    610 } md_evlist_t;
    611 
    612 /* end of meta event definitions ("meta_notify.h") */
    613 
    614 typedef struct md_im_names {
    615 	int	min_count;
    616 	char	**min_names;
    617 } md_im_names_t;
    618 
    619 /* Values for replica info status */
    620 #define	MD_IM_REPLICA_SCANNED	(0x01)
    621 #define	MD_IM_REPLICA_VALID	(0x02)
    622 
    623 typedef struct md_im_replica_info {
    624 	struct md_im_replica_info	*mir_next;
    625 	int				mir_status;
    626 	int				mir_flags;
    627 	daddr32_t			mir_offset;
    628 	daddr32_t			mir_length;
    629 	md_timeval32_t			mir_timestamp;
    630 } md_im_replica_info_t;
    631 
    632 typedef struct md_im_drive_info {
    633 	struct md_im_drive_info		*mid_next; /* next drive in this set */
    634 	mddrivename_t			*mid_dnp;
    635 	void 				*mid_devid;
    636 	void				*mid_o_devid;
    637 	int				mid_devid_sz;
    638 	int				mid_o_devid_sz;
    639 	char				mid_minor_name[MDDB_MINOR_NAME_MAX];
    640 	minor_t				mid_mnum;
    641 	int				mid_available;
    642 	md_timeval32_t			mid_setcreatetimestamp;
    643 	char				*mid_driver_name;
    644 	char				*mid_devname;
    645 	md_im_replica_info_t		*mid_replicas;
    646 	int				overlapped_disk;
    647 	struct md_im_drive_info		*overlap; /* chain of overlap disks */
    648 } md_im_drive_info_t;
    649 
    650 /* Values for mid_available */
    651 #define	MD_IM_DISK_AVAILABLE		0x00
    652 #define	MD_IM_DISK_NOT_AVAILABLE	0x01
    653 
    654 /* Values for set descriptor flags */
    655 #define	MD_IM_SET_INVALID	0x10
    656 #define	MD_IM_SET_REPLICATED	0x20
    657 
    658 /* Values for mis_partial */
    659 #define	MD_IM_COMPLETE_DISKSET	0x04
    660 #define	MD_IM_PARTIAL_DISKSET	0x08
    661 
    662 typedef struct md_im_set_desc {
    663 	struct md_im_set_desc		*mis_next;
    664 	int				mis_flags;
    665 	int				mis_oldsetno;
    666 	md_im_drive_info_t		*mis_drives;
    667 	int				mis_active_replicas;
    668 	int				mis_partial;
    669 } md_im_set_desc_t;
    670 
    671 /* meta_admin.c */
    672 extern	int		open_admin(md_error_t *ep);
    673 extern	int		close_admin(md_error_t *ep);
    674 extern	int		meta_dev_ismeta(md_dev64_t dev);
    675 extern	int		meta_get_nunits(md_error_t *ep);
    676 extern	md_dev64_t	metamakedev(minor_t mnum);
    677 
    678 /* meta_attach.c */
    679 extern	int		meta_concat_generic(mdsetname_t *sp, mdname_t *namep,
    680 			    u_longlong_t big_or_little, md_error_t *ep);
    681 extern	int		meta_concat_parent(mdsetname_t *sp, mdname_t *childnp,
    682 			    md_error_t *ep);
    683 
    684 /* meta_check.c */
    685 extern	int		meta_check_inuse(mdsetname_t *sp, mdname_t *np,
    686 			    mdinuseopts_t inuse_flag, md_error_t *ep);
    687 extern	int		meta_check_driveinset(mdsetname_t *sp,
    688 			    mddrivename_t *dnp, md_error_t *ep);
    689 extern	int		meta_check_drivemounted(mdsetname_t *sp,
    690 			    mddrivename_t *dnp, md_error_t *ep);
    691 extern	int		meta_check_driveswapped(mdsetname_t *sp,
    692 			    mddrivename_t *dnp, md_error_t *ep);
    693 extern	int		meta_check_samedrive(mdname_t *np1, mdname_t *np2,
    694 			    md_error_t *ep);
    695 extern	int		meta_check_overlap(char *uname, mdname_t *np1,
    696 			    diskaddr_t slblk1, diskaddr_t nblks1, mdname_t *np2,
    697 			    diskaddr_t slblk2, diskaddr_t nblks2,
    698 			    md_error_t *ep);
    699 extern	int		meta_check_inmeta(mdsetname_t *sp, mdname_t *np,
    700 			    mdchkopts_t options, diskaddr_t slblk,
    701 			    diskaddr_t nblks,
    702 			    md_error_t *ep);
    703 extern	int		meta_check_inset(mdsetname_t *sp, mdname_t *np,
    704 			    md_error_t *ep);
    705 extern  int		meta_check_root(md_error_t *ep);
    706 
    707 
    708 /* meta_db.c */
    709 extern	char		*meta_devid_encode_str(ddi_devid_t devid,
    710 			    char *minor_name);
    711 extern	void		meta_devid_encode_str_free(char *devidstr);
    712 extern	int		meta_devid_decode_str(char *devidstr,
    713 			    ddi_devid_t *devidp, char **minor_namep);
    714 extern	int		meta_check_inreplica(mdsetname_t *sp, mdname_t *np,
    715 			    diskaddr_t slblk, diskaddr_t nblks, md_error_t *ep);
    716 extern	int		meta_check_replica(mdsetname_t *sp, mdname_t *np,
    717 			    mdchkopts_t options, diskaddr_t slblk,
    718 			    diskaddr_t nblks, md_error_t *ep);
    719 extern	int		meta_db_addsidenms(mdsetname_t *sp, mdname_t *np,
    720 			    daddr_t blkno, int bcast, md_error_t *ep);
    721 extern	int		meta_db_delsidenm(mdsetname_t *sp, side_t sideno,
    722 			    mdname_t *np, daddr_t blkno, md_error_t *ep);
    723 extern	int		meta_db_patch(char *sname, char *cname, int patch,
    724 			    md_error_t *ep);
    725 extern	int		meta_db_attach(mdsetname_t *sp, mdnamelist_t *db_nlp,
    726 			    mdchkopts_t options, md_timeval32_t *timeval,
    727 			    int dbcnt, int dbsize, char *sysfilename,
    728 			    md_error_t *ep);
    729 extern	int		meta_db_detach(mdsetname_t *sp, mdnamelist_t *db_nlp,
    730 			    mdforceopts_t force, char *sysfilename,
    731 			    md_error_t *ep);
    732 extern	void		metafreereplicalist(md_replicalist_t *rlp);
    733 extern	int		metareplicalist(mdsetname_t *sp, int flags,
    734 			    md_replicalist_t **rlpp, md_error_t *ep);
    735 extern	void		meta_sync_db_locations(mdsetname_t *sp,
    736 			    md_error_t *ep);
    737 extern	int		meta_setup_db_locations(md_error_t *ep);
    738 extern	daddr_t		meta_db_minreplica(mdsetname_t *sp, md_error_t *ep);
    739 extern	int		meta_get_replica_names(mdsetname_t *,
    740 			    mdnamelist_t **, int options, md_error_t *);
    741 extern	void		meta_mkdummymaster(mdsetname_t *sp, int fd,
    742 			    daddr_t firstblk);
    743 extern md_timeval32_t	meta_get_lb_inittime(mdsetname_t *sp, md_error_t *ep);
    744 
    745 /* meta_db_balance.c */
    746 extern	int		meta_db_balance(mdsetname_t *sp, md_drive_desc *opdd,
    747 			    md_drive_desc *curdd, daddr_t dbsize,
    748 			    md_error_t *ep);
    749 
    750 /* metadevstamp.c */
    751 extern 	int		getdevstamp(mddrivename_t *dnp, time_t *stamp,
    752 			    md_error_t *ep);
    753 extern 	int		setdevstamp(mddrivename_t *dnp, time_t *stamp,
    754 			    md_error_t *ep);
    755 
    756 /* meta_error.c */
    757 extern	int		metaioctl(int cmd, void *data, md_error_t *ep,
    758 			    char *name);
    759 extern	void		md_logpfx(FILE *fp);
    760 /* PRINTFLIKE2 */
    761 extern	char		*mde_sperror(md_error_t *mdep, const char *fmt, ...);
    762 /* PRINTFLIKE2 */
    763 extern	void		mde_perror(md_error_t *mdep, const char *fmt, ...);
    764 /* PRINTFLIKE1 */
    765 extern	void		md_perror(const char *fmt, ...);
    766 /* PRINTFLIKE1 */
    767 extern	void		md_eprintf(const char *fmt, ...);
    768 extern	void		meta_mc_log(int level, const char *fmt, ...);
    769 
    770 /* meta_getdevs.c */
    771 extern	minor_t		meta_getminor(md_dev64_t dev64);
    772 extern	major_t		meta_getmajor(md_dev64_t dev64);
    773 extern	md_dev64_t	meta_expldev(md_dev64_t dev);
    774 extern	dev32_t		meta_cmpldev(md_dev64_t dev64);
    775 
    776 extern	int		meta_fix_compnames(mdsetname_t *sp,
    777 			    mdname_t *namep, md_dev64_t dev, md_error_t *ep);
    778 extern	int		meta_getdevs(mdsetname_t *sp, mdname_t *namep,
    779 			    mdnamelist_t **nlpp, md_error_t *ep);
    780 extern	int		meta_getalldevs(mdsetname_t *sp, mdnamelist_t **nlpp,
    781 			    int check_db, md_error_t *ep);
    782 extern	int		meta_getvtoc(int fd, char *devname,
    783 			    struct extvtoc *vtocbufp, int *partno,
    784 			    md_error_t *ep);
    785 extern	int		meta_setvtoc(int fd, char *devname,
    786 			    struct extvtoc *vtocbufp, md_error_t *ep);
    787 extern	int		meta_setmdvtoc(int fd, char *devname,
    788 			    mdvtoc_t *mdvtocbufp, md_error_t *ep);
    789 extern	int		meta_get_names(char *drivername, mdsetname_t *sp,
    790 			    mdnamelist_t **nlpp, mdprtopts_t options,
    791 			    md_error_t *ep);
    792 extern	int		meta_deviceid_to_nmlist(char *search_path,
    793 			    ddi_devid_t devid, char *minor_name,
    794 			    devid_nmlist_t **retlist);
    795 
    796 /* meta_hotspares.c */
    797 extern	int		meta_get_hsp_names(mdsetname_t *sp,
    798 			    mdhspnamelist_t **hspnlpp, int options,
    799 			    md_error_t *ep);
    800 extern	void		meta_free_hsp(md_hsp_t *hspp);
    801 extern	void		meta_invalidate_hsp(mdhspname_t *hspnp);
    802 extern	md_hsp_t	*meta_get_hsp(mdsetname_t *sp, mdhspname_t *hspnp,
    803 			    md_error_t *ep);
    804 extern	md_hsp_t	*meta_get_hsp_common(mdsetname_t *sp,
    805 			    mdhspname_t *hspnp, int fast, md_error_t *ep);
    806 extern	int		meta_check_inhsp(mdsetname_t *sp, mdname_t *np,
    807 			    diskaddr_t slblk, diskaddr_t nblks, md_error_t *ep);
    808 extern	int		meta_check_hotspare(mdsetname_t *sp, mdname_t *np,
    809 			    md_error_t *ep);
    810 extern	char		*hs_state_to_name(md_hs_t *hsp,
    811 			    md_timeval32_t *tvp);
    812 extern	int		meta_hsp_print(mdsetname_t *sp, mdhspname_t *hspnp,
    813 			    mdnamelist_t **nlpp, char *fname, FILE *fp,
    814 			    mdprtopts_t options, md_error_t *ep);
    815 extern	int		metachkhsp(mdsetname_t *sp, mdhspname_t *hspnp,
    816 			    md_error_t *ep);
    817 extern	int		meta_hs_add(mdsetname_t *sp, mdhspname_t *hspnp,
    818 			    mdnamelist_t *nlp, mdcmdopts_t options,
    819 			    md_error_t *ep);
    820 extern	int		meta_hs_delete(mdsetname_t *sp, mdhspname_t *hspnp,
    821 			    mdnamelist_t *nlp, mdcmdopts_t options,
    822 			    md_error_t *ep);
    823 extern	int		meta_hs_replace(mdsetname_t *sp, mdhspname_t *hspnp,
    824 			    mdname_t *oldnp, mdname_t *newnp,
    825 			    mdcmdopts_t options, md_error_t *ep);
    826 extern	int		meta_hs_enable(mdsetname_t *sp, mdnamelist_t *nlp,
    827 			    mdcmdopts_t options, md_error_t *ep);
    828 extern	int		meta_check_hsp(mdsetname_t *sp, md_hsp_t *hspp,
    829 			    mdcmdopts_t options, md_error_t *ep);
    830 extern	int		meta_create_hsp(mdsetname_t *sp, md_hsp_t *hspp,
    831 			    mdcmdopts_t options, md_error_t *ep);
    832 extern	int		meta_init_hsp(mdsetname_t **spp,
    833 			    int argc, char *argv[], mdcmdopts_t options,
    834 			    md_error_t *ep);
    835 extern	int		meta_hsp_reset(mdsetname_t *sp, mdhspname_t *hspnp,
    836 			    mdcmdopts_t options, md_error_t *ep);
    837 
    838 /* meta_init.c */
    839 extern	int		parse_interlace(char *uname, char *name,
    840 			    diskaddr_t *interlacep, md_error_t *ep);
    841 extern	int		meta_cook_syntax(md_error_t *ep,
    842 			    md_void_errno_t errcode, char *uname,
    843 			    int argc, char *argv[]);
    844 extern	int		meta_setup_geom(md_unit_t *md, mdname_t *np,
    845 			    mdgeom_t *geomp, uint_t write_reinstruct,
    846 			    uint_t read_reinstruct, uint_t round_cyl,
    847 			    md_error_t *ep);
    848 extern	int		meta_adjust_geom(md_unit_t *md, mdname_t *np,
    849 			    uint_t write_reinstruct, uint_t read_reinstruct,
    850 			    uint_t round_cyl, md_error_t *ep);
    851 extern	int		meta_init_name(mdsetname_t **spp, int argc,
    852 			    char *argv[], char *cname, mdcmdopts_t options,
    853 			    md_error_t *ep);
    854 extern	int		meta_check_devicesize(diskaddr_t total_blocks);
    855 extern	int		meta_init_make_device(mdsetname_t **spp, char *uname,
    856 			    md_error_t *ep);
    857 extern mdinittypes_t	meta_get_init_type(int argc, char *argv[]);
    858 
    859 /* meta_mdcf.c */
    860 extern	int		meta_update_md_cf(mdsetname_t *sp, md_error_t *ep);
    861 
    862 /* meta_med.c */
    863 extern	int		meddstealerror(md_error_t *ep, med_err_t *medep);
    864 extern	int		clnt_med_null(char *hostname, md_error_t *ep);
    865 extern	int		clnt_med_upd_data(md_h_t *mdhp,