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