%/* % * CDDL HEADER START % * % * The contents of this file are subject to the terms of the % * Common Development and Distribution License (the "License"). % * You may not use this file except in compliance with the License. % * % * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE % * or http://www.opensolaris.org/os/licensing. % * See the License for the specific language governing permissions % * and limitations under the License. % * % * When distributing Covered Code, include this CDDL HEADER in each % * file and include the License file at usr/src/OPENSOLARIS.LICENSE. % * If applicable, add the following below this CDDL HEADER, with the % * fields enclosed by brackets "[]" replaced with your own identifying % * information: Portions Copyright [yyyy] [name of copyright owner] % * % * CDDL HEADER END % */ % %/* % * Copyright 2006 Sun Microsystems, Inc. All rights reserved. % * Use is subject to license terms. % */ % %#pragma ident "%Z%%M% %I% %E% SMI" % %/* % * MDD interface definitions % */ %/* pick up multihost ioctl definitions */ %#include %/* get the basic XDR types */ %#include %/* pick up device id information */ %#include %#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 %/* % * NOTE: can't change these structures so make sure they are packed % * in the kernel. % */ %#pragma pack(4) %#endif % %/* % * fundamental types % */ % %/* % * % * NOTE: THESE ARE ON-DISK VALUES DO NOT CHANGE THE ORDER % */ enum mddb_type_t { MDDB_ALL, MDDB_NM_HDR, MDDB_NM, MDDB_SHR_NM, MDDB_VTOC, MDDB_USER, MDDB_DID_NM_HDR, MDDB_DID_NM, MDDB_DID_SHR_NM, MDDB_EFILABEL, MDDB_FIRST_MODID = 1000 }; % %/* % * Configuration commands. % */ enum mddb_cfgcmd_t { MDDB_USEDEV, MDDB_NEWDEV, MDDB_DELDEV, MDDB_GETDEV, MDDB_ENDDEV, MDDB_GETDRVRNAME, MDDB_RELEASESET, MDDB_NEWSIDE, MDDB_DELSIDE, MDDB_SETDID, MDDB_LBINITTIME }; % %/* % * Return codes from DB record operations. % */ enum mddb_recstatus_t { MDDB_NORECORD, MDDB_NODATA, MDDB_OK, MDDB_STALE }; % %/* % * Commands for DB accesses from user land. % */ enum mddb_usercmd_t { MD_DB_GETNEXTREC, MD_DB_COMMIT_ONE, MD_DB_COMMIT_MANY, MD_DB_GETDATA, MD_DB_DELETE, MD_DB_CREATE, MD_DB_GETSTATUS, MD_DB_GETSIZE, MD_DB_SETDATA, MD_DB_MAKEID }; % %/* % * MDDB_USER record subtypes, set records and drive records. % * Node records (NR) used for Multinode Disksets. % * The MDDB_UR_SR record subtype is associated with the structures % * md_set_record and md_mnset_record. % * The MDDB_UR_DR record subtype is associated with the structure % * md_drive_record. % * The MDDB_NR_DR record subtype is associated with the structure % * md_mnnode_record. % * The MDDB_UR_LR record subtype is associated with the structure % * md_mn_changelog_record_t % */ enum mddb_userrec_t { MDDB_UR_ALL, MDDB_UR_SR, MDDB_UR_DR, MDDB_UR_NR, MDDB_UR_LR }; % %/* % * MDDB_USER record get commands. % */ enum md_ur_get_cmd_t { MD_UR_GET_NEXT, MD_UR_GET_WKEY }; % %/* % * These are the options for mddb_createrec() % */ enum md_create_rec_option_t { MD_CRO_NOOPT = 0x000, MD_CRO_OPTIMIZE = 0x001, MD_CRO_32BIT = 0x002, MD_CRO_64BIT = 0x004, MD_CRO_STRIPE = 0x008, MD_CRO_MIRROR = 0x010, MD_CRO_RAID = 0x020, MD_CRO_SOFTPART = 0x040, MD_CRO_TRANS_MASTER = 0x080, MD_CRO_TRANS_LOG = 0x100, MD_CRO_HOTSPARE = 0x200, MD_CRO_HOTSPARE_POOL = 0x400, MD_CRO_CHANGELOG = 0x800, MD_CRO_FN = 0x1000 }; % %/* % * This SKEW value is used to skew the sideno of % * the share device names that are put into each % * local set's namespace. This will prevent the % * wrong name to be picked up via a devno, when % * we really wanted a local device name. % */ const SKEW = 1; #ifdef RPC_XDR % %/* Start - Avoid duplicate definitions, but get the xdr calls right */ %#if 0 #include "meta_arr.x" %#endif /* 0 */ %/* End - Avoid duplicate definitions, but get the xdr calls right */ % #endif /* RPC_XDR */ const MD_DRIVE_RECORD_REVISION = 0x00010000; #ifdef RPC_HDR % %#define MD_DR_ADD 0x00000001U %#define MD_DR_DEL 0x00000002U %#define MD_DR_FIX_MB_DID 0x10000000U /* Fix MB */ %#define MD_DR_FIX_LB_NM_DID 0x20000000U /* Fix LB and namespaces */ %#define MD_DR_UNRSLV_REPLICATED 0x40000000U %#define MD_DR_OK 0x80000000U #endif /* RPC_HDR */ #if !defined(_KERNEL) struct md_drive_record { u_int dr_revision; /* revision level */ u_int dr_flags; /* state flags */ mddb_recid_t dr_selfid; /* db record id */ md_timeval32_t dr_ctime; /* creation timestamp */ u_long dr_genid; /* generation id */ md_drive_record *dr_next; /* next ptr (Incore) */ mddb_recid_t dr_nextrec; /* next record id */ int dr_dbcnt; /* # of replica's */ int dr_dbsize; /* replica size */ mdkey_t dr_key; /* namespace key */ }; #else /* _KERNEL */ struct md_drive_record { u_int dr_revision; /* revision level */ u_int dr_flags; /* state flags */ mddb_recid_t dr_selfid; /* db record id */ md_timeval32_t dr_ctime; /* creation timestamp */ u_int dr_genid; /* generation id */ u_int dr_next; /* next ptr (Incore) */ mddb_recid_t dr_nextrec; /* next record id */ int dr_dbcnt; /* # of replica's */ int dr_dbsize; /* replica size */ mdkey_t dr_key; /* namespace key */ }; #endif /* !_KERNEL */ #ifdef RPC_HDR %/* % * Actions that can be taken on a node record. % * Used with routine upd_nr_flags. % */ % %#define MD_NR_JOIN 0x00000001U /* Turn on JOIN flag */ %#define MD_NR_WITHDRAW 0x00000002U /* Turn off JOIN flag */ %#define MD_NR_SET 0x00000004U /* Set node flags in nodelist */ %#define MD_NR_DEL 0x00000008U /* reset OK flag, set DEL */ %#define MD_NR_OK 0x80000000U /* set OK flag; reset ADD */ #endif /* RPC_HDR */ struct md_mnnode_record { u_int nr_revision; /* revision level */ u_int nr_flags; /* state flags */ mddb_recid_t nr_selfid; /* db record id */ md_timeval32_t nr_ctime; /* creation timestamp */ u_long nr_genid; /* generation id */ md_mnnode_record *nr_next; /* next ptr (Incore) */ mddb_recid_t nr_nextrec; /* next node rec id */ u_int nr_nodeid; /* node id */ md_node_nm_t nr_nodename; /* node name */ }; const MD_MNNODE_RECORD_REVISION = 0x00000100; const MD_SET_RECORD_REVISION = 0x00010000; #ifdef RPC_HDR % %#define MD_SR_ADD 0x00000001U %#define MD_SR_DEL 0x00000002U %#define MD_SR_CHECK 0x00000004U %#define MD_SR_CVT 0x00000008U %#define MD_SR_LOCAL 0x00000010U %#define MD_SR_UNRSLV_REPLICATED 0x08000000U %#define MD_SR_MB_DEVID 0x10000000U %#define MD_SR_AUTO_TAKE 0x20000000U %#define MD_SR_MN 0x40000000U %#define MD_SR_OK 0x80000000U %#define MD_SR_STATE_FLAGS (MD_SR_ADD | \ % MD_SR_DEL | \ % MD_SR_CHECK | \ % MD_SR_CVT | \ % MD_SR_UNRSLV_REPLICATED | \ % MD_SR_OK) #endif /* RPC_HDR */ #if !defined(_KERNEL) struct md_set_record { u_int sr_revision; /* revision level */ u_int sr_flags; /* state flags */ mddb_recid_t sr_selfid; /* db record id */ #ifdef RPC_HDR md_set_record *sr_next; /* next ptr (Incore) */ #endif /* RPC_HDR */ set_t sr_setno; /* set number */ md_set_nm_t sr_setname; /* setname */ md_timeval32_t sr_ctime; /* creation timestamp */ u_long sr_genid; /* generation id */ md_node_nm_arr_t sr_nodes; /* array of nodenames */ md_drive_record *sr_drivechain; /* dr list (Incore) */ mddb_recid_t sr_driverec; /* first dr record id */ mhd_mhiargs_t sr_mhiargs; /* MH ioctl timeouts */ md_h_arr_t sr_med; /* Mediator hosts */ }; #else /* _KERNEL */ struct md_set_record { u_int sr_revision; /* revision level */ u_int sr_flags; /* state flags */ mddb_recid_t sr_selfid; /* db record id */ #ifdef RPC_HDR u_int sr_next; /* next ptr (Incore) */ #endif /* RPC_HDR */ set_t sr_setno; /* set number */ md_set_nm_t sr_setname; /* setname */ md_timeval32_t sr_ctime; /* creation timestamp */ u_int sr_genid; /* generation id */ md_node_nm_arr_t sr_nodes; /* array of nodenames */ u_int sr_drivechain; /* dr list (Incore) */ mddb_recid_t sr_driverec; /* first dr record id */ mhd_mhiargs_t sr_mhiargs; /* MH ioctl timeouts */ md_h_arr_t sr_med; /* Mediator hosts */ }; #endif /* !_KERNEL */ struct md_mnset_record { u_int sr_revision; /* revision level */ u_int sr_flags; /* state flags */ mddb_recid_t sr_selfid; /* db record id */ #ifdef RPC_HDR md_set_record *sr_next; /* next ptr (Incore) */ #endif /* RPC_HDR */ set_t sr_setno; /* set number */ md_set_nm_t sr_setname; /* setname */ md_timeval32_t sr_ctime; /* creation timestamp */ u_long sr_genid; /* generation id */ md_node_nm_arr_t sr_nodes_bw_compat; /* for compat with */ /* md_set_record, */ /* first node always */ /* this node */ md_drive_record *sr_drivechain; /* dr list (Incore) */ mddb_recid_t sr_driverec; /* first dr record id */ mhd_mhiargs_t sr_mhiargs; /* MH ioctl timeouts */ md_h_arr_t sr_med; /* Mediator hosts */ md_mnnode_record *sr_nodechain; /* node list (incore) */ mddb_recid_t sr_noderec; /* first node rec id */ md_node_nm_t sr_master_nodenm; /* Master nm (incore) */ u_int sr_master_nodeid; /* Master id (incore) */ u_int sr_mddb_min_size; /* min size of mddb */ }; #ifdef RPC_HDR % %#define MD_SETOWNER_NO 0 %#define MD_SETOWNER_YES 1 %#define MD_SETOWNER_NONE 2 #endif /* RPC_HDR */ % %/* Gate key type */ struct md_setkey_t { string sk_host<>; set_t sk_setno; string sk_setname<>; md_timeval32_t sk_key; #ifdef RPC_HDR struct md_setkey_t *sk_next; #endif /* RPC_HDR */ }; % %/* metadevice ID */ typedef minor_t unit_t; % %/* component ID */ struct comp_t { minor_t mnum; /* associated metadevice */ md_dev64_t dev; }; % %/* hotspare pool ID */ typedef u_int hsp_t; #ifdef RPC_HDR % %#define MD_HSP_NONE ((hsp_t)~0U) #endif /* RPC_HDR */ % %/* hotspare ID */ struct hs_t { hsp_t hsp; /* associated hotspare pool */ md_dev64_t dev; /* device ID */ }; % %/* mnum or hsp */ typedef u_int minor_or_hsp_t; % %/* % * name service stuff % */ const MD_MAXPREFIX = 127; % %#define MD_MAX_CTDLEN 64 struct md_name_prefix { u_char pre_len; char pre_data[MD_MAXPREFIX]; }; const MD_MAXSUFFIX = 40; % struct md_name_suffix { u_char suf_prefix; u_char suf_len; char suf_data[MD_MAXSUFFIX]; }; struct md_splitname { md_name_prefix sn_prefix; md_name_suffix sn_suffix; }; #ifdef RPC_HDR % %#define SPN_PREFIX(spn) ((spn)->sn_prefix) %#define SPN_SUFFIX(spn) ((spn)->sn_suffix) #endif /* RPC_HDR */ % %/* % * Number of bits to represent a setno % * this gives us all info to define masks and shifts ... % * Also used for minor #, hsp id, recid mask and shifts. % */ const MD_BITSSET = 5; const MD_DEFAULTSETS = 4; % #ifdef RPC_HDR % %#define MD_MAXSETS (1 << MD_BITSSET) %#define MD_SETMASK (MD_MAXSETS - 1) #endif /* RPC_HDR */ % %/* % * Define a file descriptor for lockfd % * when the lock is not held. % */ const MD_NO_LOCK = -2; % %/* % * accumulated setname % */ struct mdsetname_t { string setname<>; /* logical name */ set_t setno; /* set number */ #ifdef RPC_HDR struct md_set_desc *setdesc; /* Cache set/drive desc */ int lockfd; /* used by meta_lock_* */ #endif /* RPC_HDR */ }; struct mdsetnamelist_t { mdsetnamelist_t *next; mdsetname_t *sp; }; % %/* % * device name % */ #ifdef RPC_HDR %#define MD_FULLNAME_ONLY 0x0 %#define MD_BASICNAME_OK 0x1 %#define MD_BYPASS_DAEMON 0x2 % %#define MD_SLICE0 0 %#define MD_SLICE6 6 %#define MD_SLICE7 7 % %#define MD_MAX_PARTS 17 #endif /* RPC_HDR */ struct mdname_t { #ifdef RPC_HDR struct mddrivename_t *drivenamep; /* back pointer to drive */ #endif /* RPC_HDR */ string cname<>; /* cannonical name */ string bname<>; /* block name */ string rname<>; /* raw name */ string devicesname<>; /* /devices name (or NULL) */ string minor_name<>; /* minor name with respect to devid */ md_dev64_t dev; /* major/minor (or NODEV64) */ #ifdef RPC_HDR mdkey_t key; /* namespace key (or MD_KEYBAD) */ #endif /* RPC_HDR */ diskaddr_t end_blk; /* end of database replicas (or -1) */ diskaddr_t start_blk; /* usable start block (or -1) */ }; %/* name structure (old style) */ struct o_mdname_t { #ifdef RPC_HDR struct o_mddrivename_t *drivenamep; /* back pointer to drive */ #endif /* RPC_HDR */ string cname<>; /* cannonical name */ string bname<>; /* block name */ string rname<>; /* raw name */ string devicesname<>; /* /devices name (or NULL) */ dev_t dev; /* major/minor (or NODEV64) */ #ifdef RPC_HDR mdkey_t key; /* namespace key (or MD_KEYBAD) */ #endif /* RPC_HDR */ daddr_t end_blk; /* end of database replicas (or -1) */ daddr_t start_blk; /* usable start block (or -1) */ }; struct mdnamelist_t { mdnamelist_t *next; mdname_t *namep; }; % %/* % * drive name % */ %/* name types */ enum mdnmtype_t { MDT_UNKNOWN = 0, /* unknown type */ MDT_ACCES, /* could not access device */ MDT_META, /* metadevice name */ MDT_COMP, /* regular device name */ MDT_FAST_META, /* metadevice name (partial) */ MDT_FAST_COMP /* regular device name (partial) */ }; %/* metadevice types */ enum md_types_t { MD_UNDEFINED = 0, MD_DEVICE, MD_METAMIRROR, MD_METATRANS, MD_METARAID, MD_METASP }; %/* SVM general device types % * % * META_DEVICE refers to any SVM metadevice % * LOGICAL_DEVICE refers to any underlying physical device % * HSP_DEVICE refers to a hotspare pool % * % * In the past, the device type can be determined via % * the device name (such as d10, c1t1d1s1). With % * the friendly name implementation, it is not possible % * to determine from the device name. In the code, % * whereever the device type is obvious that type will be % * used explicitly otherwise 'UNKNOWN' will be used and % * specific SVM lookup routines will be called to determine % * the device type associated with the name. % */ enum meta_device_type_t { UNKNOWN = 0, META_DEVICE, HSP_DEVICE, LOGICAL_DEVICE }; #ifdef RPC_HDR % %/* misc module names */ %/* When modifying this list also update meta_names in md_names.c */ %#define MD_STRIPE "md_stripe" %#define MD_MIRROR "md_mirror" %#define MD_TRANS "md_trans" %#define MD_HOTSPARES "md_hotspares" %#define MD_RAID "md_raid" %#define MD_VERIFY "md_verify" %#define MD_SP "md_sp" %#define MD_NOTIFY "md_notify" #endif /* RPC_HDR */ %/* generic device info */ struct mdgeom_t { u_int ncyl; u_int nhead; u_int nsect; u_int rpm; u_int write_reinstruct; u_int read_reinstruct; u_int blk_sz; }; %/* generic device info (old style) */ struct o_mdgeom_t { u_int ncyl; u_int nhead; u_int nsect; u_int rpm; u_int write_reinstruct; u_int read_reinstruct; }; struct mdcinfo_t { char cname[16]; /* controller driver name */ mhd_ctlrtype_t ctype; /* controller type */ u_int cnum; /* controller instance */ u_int tray; /* SSA100 tray */ u_int bus; /* SSA100 bus */ u_longlong_t wwn; /* SSA100 World Wide Name */ char dname[16]; /* disk driver name */ u_int unit; /* disk instance */ u_int maxtransfer; /* max I/O size (in blocks) */ }; struct mdpart_t { diskaddr_t start; /* start block */ diskaddr_t size; /* size of partition (in blocks) */ u_short tag; /* ID tag of partition */ u_short flag; /* permission flags */ diskaddr_t label; /* size of disk label (or 0) */ }; %/* partition information (old style) */ struct o_mdpart_t { daddr_t start; /* start block */ daddr_t size; /* size of partition (in blocks) */ u_short tag; /* ID tag of partition */ u_short flag; /* permission flags */ daddr_t label; /* size of disk label (or 0) */ }; struct mdvtoc_t { u_int nparts; diskaddr_t first_lba; /* for efi devices only */ diskaddr_t last_lba; /* for efi devices only */ diskaddr_t lbasize; /* for efi devices only */ mdpart_t parts[MD_MAX_PARTS]; /* room for i386 too */ char *typename; /* disk type (or NULL) */ }; %/* vtoc information (old style) */ struct o_mdvtoc_t { char *typename; /* disk type (or NULL) */ u_int nparts; o_mdpart_t parts[16]; /* room for i386 too */ }; % %/* % * List of drivename cnames per side, % * also the driver name, mnum (for slice 7). % */ struct mdsidenames_t { mdsidenames_t *next; side_t sideno; minor_t mnum; string dname<>; string cname<>; }; struct mddrivename_t { #ifdef RPC_HDR /* * the following string is not used but is left in place so that * it is not necessary to version the rpc interface that passes * this structure. */ string not_used<>; #endif /* RPC_HDR */ string cname<>; /* canonical drive name */ string rname<>; /* raw name */ mdnmtype_t type; /* type of drive */ string devid<>; /* Device Id of the drive */ int errnum; /* errno for type == MDT_ACCES */ mdgeom_t geom; /* disk geometry */ mdcinfo_t cinfo; /* controller info */ mdvtoc_t vtoc; /* volume table of contents info */ mdname_t parts<>; /* partitions in drive */ mdsidenames_t *side_names; /* list of names per side */ mdkey_t side_names_key; /* key used to store the side names*/ string miscname<>; /* metadevice misc name */ #ifdef RPC_HDR struct md_common_t *unitp; /* metadevice unit structure */ #endif /* RPC_HDR */ }; %/* % * old version of mddrivename_t that contains an old version of mdgeom_t, % * mdvtoc_t and mdname_t (prefixed _o). % */ struct o_mddrivename_t { #ifdef RPC_HDR string cachenm<>; /* name used for cache lookups */ #endif /* RPC_HDR */ string cname<>; /* canonical drive name */ string rname<>; /* raw name */ mdnmtype_t type; /* type of drive */ int errnum; /* errno for type == MDT_ACCES */ o_mdgeom_t geom; /* disk geometry (old style) */ mdcinfo_t cinfo; /* controller info */ o_mdvtoc_t vtoc; /* vtoc info (old style) */ o_mdname_t parts<>; /* partitions in drive (old style) */ mdsidenames_t *side_names; /* list of names per side */ mdkey_t side_names_key; /* key used to store the side names*/ string miscname<>; /* metadevice misc name */ #ifdef RPC_HDR struct md_common_t *unitp; /* metadevice unit structure */ #endif /* RPC_HDR */ }; struct mddrivenamelist_t { mddrivenamelist_t *next; mddrivename_t *drivenamep; }; % %/* % * replica struct % */ typedef u_int replica_flags_t; #ifdef RPC_HDR % %#define MDDB_F_EREAD 0x00001 /* a read error occurred */ %#define MDDB_F_TOOSMALL 0x00002 /* replica is too small to hold db */ %#define MDDB_F_EFMT 0x00004 /* something is wrong with the data */ %#define MDDB_F_EDATA 0x00008 /* error in data blocks */ %#define MDDB_F_EMASTER 0x00010 /* error in master block(s) */ %#define MDDB_F_ACTIVE 0x00020 /* this replica is currently in use */ %#define MDDB_F_EWRITE 0x00040 /* a write error occurred */ %#define MDDB_F_MASTER 0x00080 /* the copy which was used as input */ %#define MDDB_F_SUSPECT 0x00100 /* replica write ability is suspect */ %#define MDDB_F_PTCHED 0x00400 /* db location was patched in kernel */ %#define MDDB_F_IOCTL 0x00800 /* db location passed in from ioctl */ %#define MDDB_F_GOTTEN 0x01000 /* getdev has been done on this dev */ %#define MDDB_F_LOCACC 0x02000 /* the locator has been accessed */ %#define MDDB_F_UP2DATE 0x04000 /* this copy of db is up to date */ %#define MDDB_F_OLDACT 0x08000 /* this copy was active previously */ %#define MDDB_F_DELETED 0x10000 /* place holder in empty slot */ %#define MDDB_F_TAGDATA 0x20000 /* Data is tagged */ %#define MDDB_F_BADTAG 0x40000 /* Data tag was not valid */ %#define MDDB_F_NODEVID 0x80000 /* No devid associated with replica */ % %/* % * These are used in de_flags only % * Do not change these values, they are stored on-disk % */ %#define MDDB_F_STRIPE 0x00001 /* record is a stripe record */ %#define MDDB_F_MIRROR 0x00002 /* record is a mirror record */ %#define MDDB_F_RAID 0x00004 /* record is a raid record */ %#define MDDB_F_SOFTPART 0x00008 /* record is a sp record */ %#define MDDB_F_TRANS_MASTER 0x00010 /* trans master record */ %#define MDDB_F_TRANS_LOG 0x00020 /* trans log record */ %#define MDDB_F_HOTSPARE 0x00040 /* hotspare record */ %#define MDDB_F_HOTSPARE_POOL 0x00080 /* hotspare record */ %#define MDDB_F_OPT 0x00200 /* optimization record */ %#define MDDB_F_CHANGELOG 0x00400 /* change log record */ %/* used by metadb(1m) for printing */ %#define MDDB_FLAGS_STRING "RSFDMaWm pc luo tBr" %#define MDDB_FLAGS_LEN (strlen(MDDB_FLAGS_STRING)) % %/* % * See meta_prbits() in SUNWmd/lib/libmeta/meta_print.c for a description of % * the way this is used % */ %#define MDDB_F_BITNAMES "\020\001EREAD\002TOOSMALL\003EFMT\004EDATA" \ % "\005EMASTER\006ACTIVE\007EWRITE\010MASTER" \ % "\011SUSPECT\012OPT\013PTCHED\014IOCTL" \ % "\015GOTTEN\016LOCACC\017UP2DATE\020OLDACT" \ % "\021DELETED\022TAGDATA\023BADTAG\024NORELOC" % #endif /* RPC_HDR */ /* * Refering to r_blkno and r_nblk: * A replica will always be smaller than 1 Terabyte, so no need to * change the ondisk structure to 64 bits. */ struct md_replica_t { mdname_t *r_namep; replica_flags_t r_flags; daddr_t r_blkno; daddr_t r_nblk; ddi_devid_t r_devid; char r_driver_name[MD_MAXDRVNM]; char r_minor_name[MDDB_MINOR_NAME_MAX]; }; struct md_replica_recerr_t { int r_li; int r_flags; daddr32_t r_blkno; minor_t r_mnum; char r_driver_name[MD_MAXDRVNM]; }; struct md_replicalist_t { md_replicalist_t *rl_next; md_replica_t *rl_repp; }; % %/* % * set/drive structs exposed by the library routines % */ struct md_drive_desc { md_timeval32_t dd_ctime; /* creation time */ u_long dd_genid; /* generation id */ u_int dd_flags; /* state flags */ md_drive_desc *dd_next; /* next drive */ mddrivename_t *dd_dnp; /* drive name ptr */ int dd_dbcnt; /* # of replicas */ int dd_dbsize; /* size of replica */ }; % %/* % * set/drive structs exposed by the library routines (old style) % */ struct o_md_drive_desc { md_timeval32_t dd_ctime; /* creation time */ u_long dd_genid; /* generation id */ u_int dd_flags; /* state flags */ o_md_drive_desc *dd_next; /* next drive */ o_mddrivename_t *dd_dnp; /* drive name ptr */ int dd_dbcnt; /* # of replicas */ int dd_dbsize; /* size of replica */ }; struct md_mnnode_desc { md_timeval32_t nd_ctime; /* creation time */ u_long nd_genid; /* generation id */ u_int nd_flags; /* state flags */ md_mnnode_desc *nd_next; /* next node */ md_mnnode_nm_t nd_nodename; /* name of node */ u_int nd_nodeid; /* id of node */ md_mnnode_nm_t nd_priv_ic; /* priv interconnect */ /* nodename */ }; struct md_set_desc { md_timeval32_t sd_ctime; /* creation time */ u_long sd_genid; /* generation id */ set_t sd_setno; /* set number */ u_int sd_flags; /* state flags */ md_node_nm_arr_t sd_nodes; /* array of nodenames */ /* for !MN_disksets */ int sd_isown[MD_MAXSIDES]; /* bool for is owner? */ md_h_arr_t sd_med; /* Mediator hosts */ md_drive_desc *sd_drvs; /* drive list */ u_int sd_mn_am_i_master; u_int sd_mn_numnodes; /* # of nodes in list */ md_mnnode_desc *sd_nodelist; /* MN node list */ /* for MN_disksets */ md_node_nm_t sd_mn_master_nodenm; /* Master node name */ u_int sd_mn_master_nodeid; /* Master node id */ md_mnnode_desc *sd_mn_mynode; /* shortcut to me */ md_mnnode_desc *sd_mn_masternode; /* shortcut to master */ }; %/* % * Defines to determine if diskset is a Multinode diskset. % * The sd_flags field in the md_set_desc structure is never manipulated % * directly but is always a copy of the set record's sr_flags field, so % * the same define (MD_SR_MN) can be used for both sd_flags and sr_flags. % * The set record is of the structure type md_set_record if a regular diskset % * or type md_mnset_record for a Multinode diskset. %*/ %#define MD_MNSET_DESC(sd) (((sd)->sd_flags & MD_SR_MN) ? 1 : 0) %#define MD_MNSET_REC(sr) (((sr)->sr_flags & MD_SR_MN) ? 1 : 0) %#define MD_MNDR_REC(dr) (((dr)->dr_flags & MD_DR_MN) ? 1 : 0) %/* % * Define to determine if diskset is a Auto-Take diskset. %*/ %#define MD_ATSET_DESC(sd) (((sd)->sd_flags & MD_SR_AUTO_TAKE) ? 1 : 0) %/* % * Define to set the alive flag for a node. A node is alive if it % * is in the multi_node membership list. % */ %#define MD_MN_NODE_ALIVE 0x0001 %/* % * Define to set the own flag for a node. A node is an owner of the diskset % * if that node has snarf'd in the mddb. % */ %#define MD_MN_NODE_OWN 0x0002 %/* % * Defines to set the add, delete and ok states of a node. The add state is % * set at the beginning of the addition of a node to a diskset. The % * delete state is set at the beginning of a deletion of a node from a diskset. % * The OK state is set (and the add state reset) when that node is % * functional in the diskset. % * Rollback join flag is used on an error condition when deleting the last % * disk from a diskset. rpc.metad should never see this flag. % * NOSET flag is used on an error condition during a reconfig cycle when % * the set has been removed from this node. rpc.metad should just ignore % * this flag. % */ %#define MD_MN_NODE_ADD 0x0004 %#define MD_MN_NODE_DEL 0x0008 %#define MD_MN_NODE_OK 0x0010 %#define MD_MN_NODE_RB_JOIN 0x0020 %#define MD_MN_NODE_NOSET 0x0040 %/* % * Define for invalid node id. Used specifically to set mn set record % * master nodeid to invalid when no master can be determined. % */ %#define MD_MN_INVALID_NID 0xfffffffful /* invalid node id */ % %/* % * set description (old style) % */ struct o_md_set_desc { md_timeval32_t sd_ctime; /* creation time */ u_long sd_genid; /* generation id */ set_t sd_setno; /* set number */ u_int sd_flags; /* state flags */ md_node_nm_arr_t sd_nodes; /* array of nodenames */ int sd_isown[MD_MAXSIDES]; /* bool for is owner? */ md_h_arr_t sd_med; /* Mediator hosts */ o_md_drive_desc *sd_drvs; /* drive list */ }; % %/* % * hotspare pool name % */ struct mdhspname_t { string hspname<>; /* hotspare pool name */ hsp_t hsp; /* number */ #ifdef RPC_HDR struct md_hsp_t *unitp; /* hotspare pool unit structure */ #endif /* RPC_HDR */ }; struct mdhspnamelist_t { mdhspnamelist_t *next; mdhspname_t *hspnamep; }; % %/* % * generic metadevice descriptions for status and init % */ % %/* % * following used with un_status % * bottom 16 bits are global definitions % * top 16 bits are defined by sub device % */ typedef u_int md_status_t; #ifdef RPC_HDR % %#define MD_UN_GROW_PENDING 0x0008 /* grow mirror pending */ %#define MD_UN_BEING_RESET 0x0040 /* reset at snarf time */ #endif /* RPC_HDR */ % %/* % * following are used with un_parent % * MD_NO_PARENT - Not a sub-device. % * MD_MULTI_PARENT - A sub-device with one or more parents, like a log. % * other - A sub-device with only one parent, like a submirror. % * The number is the parent's unit number. % */ typedef unit_t md_parent_t; #ifdef RPC_HDR % %#define MD_NO_PARENT 0xffffffffu %#define MD_MULTI_PARENT 0xfffffffeu %#define MD_HAS_PARENT(p) ((p) != MD_NO_PARENT) #endif /* RPC_HDR */ typedef u_int md_stackcap_t; #ifdef RPC_HDR % %#define MD_CANT_PARENT 0x00 /* cannot have a parent */ %#define MD_CAN_PARENT 0x01 /* can have a parent */ %#define MD_CAN_SUB_MIRROR 0x02 /* can be a sub-mirror */ %#define MD_CAN_META_CHILD 0x04 /* can have metadev. children */ %#define MD_CAN_SP 0x08 /* can be soft partitioned */ #endif /* RPC_HDR */ /* common to all metadevices */ struct md_common_t { mdname_t *namep; md_types_t type; md_status_t state; md_stackcap_t capabilities; md_parent_t parent; diskaddr_t size; u_long user_flags; u_longlong_t revision; }; % %/* % * stripe % */ /* * ioctl stuff */ struct ms_params_t { int change_hsp_id; hsp_t hsp_id; }; /* * unit structure */ typedef u_int comp_state_t; #ifdef RPC_HDR % %#define CS_OKAY 0x0001 %#define CS_ERRED 0x0002 %#define CS_RESYNC 0x0004 %#define CS_LAST_ERRED 0x0008 % %/* interlace values (in bytes) */ %#define MININTERLACE (16 * 512) %#define MAXINTERLACE (100 * 1024 * 1024) #endif /* RPC_HDR */ struct md_comp_t { mdname_t *compnamep; mdname_t *hsnamep; comp_state_t state; u_int lasterrcnt; md_timeval32_t timestamp; }; struct md_row_t { diskaddr_t interlace; diskaddr_t row_size; md_comp_t comps<>; }; struct md_stripe_t { md_common_t common; mdhspname_t *hspnamep; md_row_t rows<>; }; % %/* % * soft partition % */ typedef uint64_t xsp_offset_t; typedef uint64_t xsp_length_t; typedef u_int xsp_status_t; % %#define SP_INIT 0x0001 %#define SP_OK 0x0002 %#define SP_LASTERR 0x0004 % /* * unit structure */ struct md_sp_ext_t { xsp_offset_t voff; xsp_offset_t poff; xsp_length_t len; }; struct md_sp_t { md_common_t common; mdname_t *compnamep; /* name of this component */ xsp_status_t status; /* state of this soft partition */ md_sp_ext_t ext<>; }; % %/* % * mirror % */ /* * ioctl stuff */ enum mm_wr_opt_t { WR_PARALLEL = 0, /* write submirrors in parallel */ WR_SERIAL /* write submirrors one at a time */ }; enum mm_rd_opt_t { RD_LOAD_BAL = 0, /* read submirrors roundrobin */ RD_GEOMETRY, /* read submirrors geometrically */ RD_FIRST /* read first submirror */ }; typedef short mm_pass_num_t; const MD_PASS_DEFAULT = 1; const MD_PASS_MAX = 9; struct mm_params_t { int change_read_option; mm_rd_opt_t read_option; int change_write_option; mm_wr_opt_t write_option; int change_pass_num; mm_pass_num_t pass_num; }; /* * unit structure */ typedef u_int sm_state_t; #ifdef RPC_HDR % %#define SMS_UNUSED 0x0000 %#define SMS_RUNNING 0x0001 %#define SMS_COMP_ERRED 0x0002 %#define SMS_COMP_RESYNC 0x0004 %#define SMS_ATTACHED 0x0008 %#define SMS_ATTACHED_RESYNC 0x0010 %#define SMS_OFFLINE 0x0020 %#define SMS_OFFLINE_RESYNC 0x0040 %#define SMS_ALL_ERRED 0x0080 %#define SMS_INUSE (0xffff) %#define SMS_LIMPING (SMS_COMP_ERRED | SMS_COMP_RESYNC) %#define SMS_IGNORE 0x4000 #endif /* RPC_HDR */ typedef u_int sm_flags_t; #ifdef RPC_HDR % %#define MD_SM_RESYNC_TARGET 0x0001 %#define MD_SM_FAILFAST 0x0002 #endif /* RPC_HDR */ struct md_submirror_t { mdname_t *submirnamep; sm_state_t state; sm_flags_t flags; md_timeval32_t timestamp; }; #ifdef RPC_HDR % %#define MD_UN_RESYNC_ACTIVE 0x00010000 %#define MD_UN_WAR 0x00020000 %#define MD_UN_OFFLINE_SM 0x00040000 %#define MD_UN_OPT_NOT_DONE 0x00080000 %#define MD_UN_KEEP_DIRTY (MD_UN_OFFLINE_SM | MD_UN_OPT_NOT_DONE) %#define MD_UN_RESYNC_CANCEL 0x00100000 %#define MD_UN_REPLAYED 0x00200000 %#define MD_UN_RENAMING 0x00400000 %#define MD_UN_MOD_INPROGRESS (MD_UN_RESYNC_ACTIVE | \ % MD_UN_OPT_NOT_DONE | \ % MD_UN_RENAMING) #endif /* RPC_HDR */ const NMIRROR = 4; struct md_mirror_t { md_common_t common; mm_rd_opt_t read_option; mm_wr_opt_t write_option; mm_pass_num_t pass_num; int percent_done; int percent_dirty; md_submirror_t submirrors[NMIRROR]; }; % %/* % * trans % */ %/* % * unit structure % */ typedef u_int mt_flags_t; #ifdef RPC_HDR % %#define TRANS_NEED_OPEN 0x0001 /* subdevs are unopened */ %#define TRANS_OPENED 0x0002 /* open at snarf succeeded */ %#define TRANS_DETACHING 0x0004 /* detaching the log */ %#define TRANS_DETACHED 0x0008 /* log successfully detached */ %#define TRANS_DETACH_SKIP 0x0010 /* already processed; skip */ %#define TRANS_ATTACHING 0x0020 /* attaching the log */ %#define TRANS_ROLL_ON_WRITE 0x0040 /* roll on physio write */ %#define TRANS_NEED_SCANROLL 0x0080 /* roll on physio write */ #endif /* RPC_HDR */ typedef u_int mt_l_error_t; #ifdef RPC_HDR % %#define LDL_ERROR 0x0001 /* error state */ %#define LDL_HERROR 0x0002 /* hard error state */ %#define LDL_ANYERROR 0x0003 /* any error state */ %#define LDL_NOERROR 0x0004 /* dont error transition during scan */ %#define LDL_SAVERROR 0x0008 /* transition to error after scan */ #endif /* RPC_HDR */ typedef u_int mt_debug_t; /* values in md_trans.h */ struct md_trans_t { md_common_t common; mdname_t *masternamep; mdname_t *lognamep; mt_flags_t flags; md_timeval32_t timestamp; mt_l_error_t log_error; md_timeval32_t log_timestamp; daddr_t log_size; mt_debug_t debug; }; % %/* % * RAID % */ /* * ioctl stuff */ struct mr_params_t { int change_hsp_id; hsp_t hsp_id; }; /* * unit structure */ enum rcs_state_t { RCS_UNUSED = 0x0, RCS_INIT = 0x1, RCS_OKAY = 0x2, RCS_ERRED = 0x4, RCS_LAST_ERRED = 0x8, RCS_RESYNC = 0x10, RCS_INIT_ERRED = 0x20, RCS_REGEN = 0x40 }; typedef u_int rcs_flags_t; #ifdef RPC_HDR % %#define MD_RAID_DEV_ISOPEN 0x00001 %#define MD_RAID_ALT_ISOPEN 0x00002 %#define MD_RAID_RESYNC 0x00004 %#define MD_RAID_RESYNC_ERRED 0x00008 %#define MD_RAID_FORCE_REPLACE 0x00010 %#define MD_RAID_WRITE_ALT 0x00020 %#define MD_RAID_DEV_ERRED 0x00040 %#define MD_RAID_COPY_RESYNC 0x00080 %#define MD_RAID_REGEN_RESYNC 0x00100 %#define MD_RAID_DEV_PROBEOPEN 0x00200 %#define MD_RAID_HAS_LABEL 0x40000 #endif /* RPC_HDR */ struct md_raidcol_t { mdname_t *colnamep; mdname_t *hsnamep; rcs_state_t state; rcs_flags_t flags; md_timeval32_t timestamp; }; enum rus_state_t { RUS_UNUSED = 0x0, RUS_INIT = 0x1, RUS_OKAY = 0x2, RUS_ERRED = 0x4, RUS_LAST_ERRED = 0x8, RUS_DOI = 0x10, RUS_REGEN = 0x20 }; typedef u_int md_riflags_t; #ifdef RPC_HDR % %#define MD_RI_INPROGRESS 0x0001 %#define MD_GROW_INPROGRESS 0x0002 %#define MD_RI_BLOCK 0x0004 %#define MD_RI_UNBLOCK 0x0008 %#define MD_RI_KILL 0x0010 %#define MD_RI_BLOCK_OWNER 0x0020 %#define MD_RI_SHUTDOWN 0x0040 %#define MD_RI_NO_WAIT 0x0080 %#define MD_RI_RESYNC_FORCE_MNSTART 0x0100 #endif /* RPC_HDR */ const MD_RAID_MIN = 3; struct md_raid_t { md_common_t common; rus_state_t state; md_timeval32_t timestamp; diskaddr_t interlace; diskaddr_t column_size; size_t orig_ncol; mdhspname_t *hspnamep; md_riflags_t resync_flags; int percent_dirty; int percent_done; int pw_count; md_raidcol_t cols<>; }; % %/* % * shared % */ /* * unit structure */ struct md_shared_t { md_common_t common; }; % %/* % * hotspare % */ /* * ioctl stuff */ enum hotspare_states_t { HSS_UNUSED, HSS_AVAILABLE, HSS_RESERVED, HSS_BROKEN }; /* * unit structure */ struct md_hs_t { mdname_t *hsnamep; hotspare_states_t state; diskaddr_t size; md_timeval32_t timestamp; u_longlong_t revision; }; struct md_hsp_t { mdhspname_t *hspnamep; u_int refcount; md_hs_t hotspares<>; }; % %/* % * specific error info % */ % %/* % * simple errors % */ enum md_void_errno_t { MDE_NONE = 0, MDE_UNIT_NOT_FOUND, MDE_DUPDRIVE, MDE_INVAL_HSOP, MDE_NO_SET, /* no such set */ MDE_SET_DIFF, /* setname changed on command line */ MDE_BAD_RD_OPT, /* bad mirror read option */ MDE_BAD_WR_OPT, /* bad mirror write option */ MDE_BAD_PASS_NUM, /* bad mirror pass number */ MDE_BAD_INTERLACE, /* bad stripe interlace */ MDE_NO_HSPS, /* couldn't find any hotspare pools */ MDE_NOTENOUGH_DB, /* Too few replicas */ MDE_DELDB_NOTALLOWED, /* last replica in ds cannot be del in metadb */ MDE_DEL_VALIDDB_NOTALLOWED, /* last valid replica cannot be del */ MDE_SYSTEM_FILE, /* /etc/system file error */ MDE_MDDB_FILE, /* /etc/lvm/mddb.cf file error */ MDE_MDDB_CKSUM, /* /etc/lvm/mddb.cf checksum error */ MDE_VFSTAB_FILE, /* /etc/vfstab file error */ MDE_NOSLICE, /* metaslicename() with sliceno to big */ MDE_SYNTAX, /* metainit syntax error */ MDE_OPTION, /* metainit options error */ MDE_TAKE_OWN, /* take ownership failed */ MDE_NOT_DRIVENAME, /* not in drivename syntax */ MDE_RESERVED, /* device is reserved by another host */ MDE_DVERSION, /* driver version out of sync */ MDE_MVERSION, /* MDDB version out of sync */ MDE_TESTERROR, /* Test Error Message */ MDE_BAD_ORIG_NCOL, /* bad RAID original column count */ MDE_RAID_INVALID, /* attempt to use -k on invalid device */ MDE_MED_ERROR, /* mediator error */ MDE_TOOMANYMED, /* Too many mediators specified */ MDE_NOMED, /* No mediators */ MDE_ONLYNODENAME, /* Only the nodename is needed */ MDE_RAID_BAD_PW_CNT, /* bad prewrite count specified */ MDE_DEVID_TOOBIG, /* Devid size is greater than allowed */ MDE_NOPERM, /* No permission - not root */ MDE_NODEVID, /* No device id for given devt */ MDE_NOROOT, /* No root in /etc/mnttab */ MDE_EOF_TRANS, /* trans logging eof'd */ MDE_BAD_RESYNC_OPT, /* bad mirror resync option */ MDE_NOT_MN, /* option only valid within a multi-node set */ MDE_ABR_SET, /* invalid operation for ABR mirror */ MDE_INVAL_MNOP, /* Invalid operation on MN diskset */ MDE_MNSET_NOTRANS, /* Trans metadevice not supported in MN set */ MDE_MNSET_NORAID, /* RAID metadevice not supported in MN set */ MDE_FORCE_DEL_ALL_DRV, /* Must use -f flag to delete all drives */ MDE_STRIPE_TRUNC_SINGLE, /* single component stripe truncation */ MDE_STRIPE_TRUNC_MULTIPLE, /* multiple component stripe trun */ MDE_SMF_FAIL, /* service management facility error */ MDE_SMF_NO_SERVICE, /* service not enabled in SMF */ MDE_AMBIGUOUS_DEV, /* Ambiguous device specified */ MDE_NAME_IN_USE, /* Friendly name already in use. For */ /* instance name desired for hot spare pool */ /* is being used for a metadevice. */ MDE_ZONE_ADMIN, /* in a zone & no admin device */ MDE_NAME_ILLEGAL /* illegal syntax for metadevice or hsp name */ }; struct md_void_error_t { md_void_errno_t errnum; }; % %/* % * system errors % */ struct md_sys_error_t { int errnum; }; % %/* % * RPC errors % */ struct md_rpc_error_t { enum clnt_stat errnum; }; % %/* % * device errors % */ enum md_dev_errno_t { MDE_INVAL_HS = 1, MDE_FIX_INVAL_STATE, MDE_FIX_INVAL_HS_STATE, MDE_NOT_META, MDE_IS_META, MDE_IS_SWAPPED, MDE_NAME_SPACE, MDE_IN_SHARED_SET, MDE_NOT_IN_SET, MDE_NOT_DISK, MDE_CANT_CONFIRM, MDE_INVALID_PART, MDE_HAS_MDDB, MDE_NO_DB, /* Replica not on device given */ MDE_CANTVERIFY_VTOC, MDE_NOT_LOCAL, MDE_DEVICES_NAME, MDE_REPCOMP_INVAL, /* replica slice not allowed in "set" metadevs */ MDE_REPCOMP_ONLY, /* only replica slice diskset replicas */ MDE_INV_ROOT, /* Invalid root device for this operation */ MDE_MULTNM, /* Multiple entries for device in namespace */ MDE_TOO_MANY_PARTS, /* dev has more than MD_MAX_PARTS partitions */ MDE_REPART_REPLICA, /* replica slice would move with repartitioning */ MDE_IS_DUMP /* device already in use as dump device */ }; struct md_dev_error_t { md_dev_errno_t errnum; md_dev64_t dev; /* 64 bit fixed size */ }; % %/* % * overlap errors % */ enum md_overlap_errno_t { MDE_OVERLAP_MOUNTED = 1, MDE_OVERLAP_SWAP, MDE_OVERLAP_DUMP }; % #if !defined(_KERNEL) struct md_overlap_error_t { md_overlap_errno_t errnum; string where<>; string overlap<>; }; #else struct md_overlap_error_t { md_overlap_errno_t errnum; u_int xwhere; u_int xoverlap; }; #endif /* !_KERNEL */ % %/* % * use errors % */ enum md_use_errno_t { MDE_IS_MOUNTED = 1, MDE_ALREADY, MDE_OVERLAP, MDE_SAME_DEVID }; % #if !defined(_KERNEL) struct md_use_error_t { md_use_errno_t errnum; md_dev64_t dev; string where<>; }; #else struct md_use_error_t { md_use_errno_t errnum; md_dev64_t dev; u_int xwhere; }; #endif % %/* % * metadevice errors % */ enum md_md_errno_t { MDE_INVAL_UNIT = 1, MDE_UNIT_NOT_SETUP, MDE_UNIT_ALREADY_SETUP, MDE_NOT_MM, MDE_NOT_ENOUGH_DBS, MDE_IS_SM, MDE_IS_OPEN, MDE_C_WITH_INVAL_SM, MDE_RESYNC_ACTIVE, MDE_LAST_SM_RE, MDE_MIRROR_FULL, MDE_IN_USE, MDE_SM_TOO_SMALL, MDE_NO_LABELED_SM, MDE_SM_OPEN_ERR, MDE_CANT_FIND_SM, MDE_LAST_SM, MDE_NO_READABLE_SM, MDE_SM_FAILED_COMPS, MDE_ILLEGAL_SM_STATE, MDE_RR_ALLOC_ERROR, MDE_MIRROR_OPEN_FAILURE, MDE_MIRROR_THREAD_FAILURE, MDE_GROW_DELAYED, MDE_NOT_MT, MDE_HS_IN_USE, MDE_HAS_LOG, MDE_UNKNOWN_TYPE, MDE_NOT_STRIPE, MDE_NOT_RAID, MDE_NROWS, MDE_NCOMPS, MDE_NSUBMIRS, MDE_BAD_STRIPE, MDE_BAD_MIRROR, MDE_BAD_TRANS, MDE_BAD_RAID, MDE_RAID_OPEN_FAILURE, MDE_RAID_THREAD_FAILURE, MDE_RAID_NEED_FORCE, MDE_NO_LOG, MDE_RAID_DOI, MDE_RAID_LAST_ERRED, MDE_RAID_NOT_OKAY, MDE_RENAME_BUSY, MDE_RENAME_SOURCE_BAD, MDE_RENAME_TARGET_BAD, MDE_RENAME_TARGET_UNRELATED, MDE_RENAME_CONFIG_ERROR, MDE_RENAME_ORDER, MDE_RECOVER_FAILED, MDE_NOT_SP, MDE_SP_NOSPACE, MDE_SP_BADWMREAD, MDE_SP_BADWMWRITE, MDE_SP_BADWMMAGIC, MDE_SP_BADWMCRC, MDE_SP_OVERLAP, MDE_SP_BAD_LENGTH, MDE_UNIT_TOO_LARGE, MDE_LOG_TOO_LARGE, MDE_SP_NOSP, MDE_IN_UNAVAIL_STATE }; struct md_md_error_t { md_md_errno_t errnum; minor_t mnum; }; % %/* % * component errors % */ enum md_comp_errno_t { MDE_CANT_FIND_COMP = 1, MDE_REPL_INVAL_STATE, MDE_COMP_TOO_SMALL, MDE_COMP_OPEN_ERR, MDE_RAID_COMP_ERRED, MDE_MAXIO, MDE_SP_COMP_OPEN_ERR }; struct md_comp_error_t { md_comp_errno_t errnum; comp_t comp; }; % %/* % * hotspare pool errors % */ enum md_hsp_errno_t { MDE_HSP_CREATE_FAILURE = 1, MDE_HSP_IN_USE, MDE_INVAL_HSP, MDE_HSP_BUSY, MDE_HSP_REF, MDE_HSP_ALREADY_SETUP, MDE_BAD_HSP, MDE_HSP_UNIT_TOO_LARGE }; struct md_hsp_error_t { md_hsp_errno_t errnum; hsp_t hsp; }; % %/* % * hotspare errors % */ enum md_hs_errno_t { MDE_HS_RESVD = 1, MDE_HS_CREATE_FAILURE, MDE_HS_INUSE, MDE_HS_UNIT_TOO_LARGE }; struct md_hs_error_t { md_hs_errno_t errnum; hs_t hs; }; % %/* % * MDDB errors % */ enum md_mddb_errno_t { MDE_TOOMANY_REPLICAS = 1, MDE_REPLICA_TOOSMALL, MDE_NOTVERIFIED, MDE_DB_INVALID, MDE_DB_EXISTS, MDE_DB_MASTER, MDE_DB_TOOSMALL, MDE_DB_NORECORD, MDE_DB_NOSPACE, MDE_DB_NOTNOW, MDE_DB_NODB, MDE_DB_NOTOWNER, MDE_DB_STALE, MDE_DB_TOOFEW, MDE_DB_TAGDATA, MDE_DB_ACCOK, MDE_DB_NTAGDATA, MDE_DB_ACCNOTOK, MDE_DB_NOLOCBLK, MDE_DB_NOLOCNMS, MDE_DB_NODIRBLK, MDE_DB_NOTAGREC, MDE_DB_NOTAG, MDE_DB_BLKRANGE }; % struct md_mddb_error_t { md_mddb_errno_t errnum; minor_t mnum; /* associated metadevice */ set_t setno; u_int size; }; % %/* % * diskset (ds) errors % */ enum md_ds_errno_t { MDE_DS_DUPHOST = 1, MDE_DS_NOTNODENAME, MDE_DS_SELFNOTIN, MDE_DS_NODEHASSET, MDE_DS_NODENOSET, MDE_DS_NOOWNER, MDE_DS_NOTOWNER, MDE_DS_NODEISNOTOWNER, MDE_DS_NODEINSET, MDE_DS_NODENOTINSET, MDE_DS_SETNUMBUSY, MDE_DS_SETNUMNOTAVAIL, MDE_DS_SETNAMEBUSY, MDE_DS_DRIVENOTCOMMON, MDE_DS_DRIVEINSET, MDE_DS_DRIVENOTINSET, MDE_DS_DRIVEINUSE, MDE_DS_DUPDRIVE, MDE_DS_INVALIDSETNAME, MDE_DS_HASDRIVES, MDE_DS_SIDENUMNOTAVAIL, MDE_DS_SETNAMETOOLONG, MDE_DS_NODENAMETOOLONG, MDE_DS_OHACANTDELSELF, MDE_DS_HOSTNOSIDE, MDE_DS_SETLOCKED, MDE_DS_ULKSBADKEY, MDE_DS_LKSBADKEY, MDE_DS_WRITEWITHSULK, MDE_DS_SETCLEANUP, MDE_DS_CANTDELSELF, MDE_DS_HASMED, MDE_DS_TOOMANYALIAS, MDE_DS_ISMED, MDE_DS_ISNOTMED, MDE_DS_INVALIDMEDNAME, MDE_DS_ALIASNOMATCH, MDE_DS_NOMEDONHOST, MDE_DS_CANTDELMASTER, MDE_DS_NOTINMEMBERLIST, MDE_DS_MNCANTDELSELF, MDE_DS_RPCVERSMISMATCH, MDE_DS_WITHDRAWMASTER, MDE_DS_COMMDCTL_SUSPEND_NYD, MDE_DS_COMMDCTL_SUSPEND_FAIL, MDE_DS_COMMDCTL_REINIT_FAIL, MDE_DS_COMMDCTL_RESUME_FAIL, MDE_DS_NOTNOW_RECONFIG, MDE_DS_NOTNOW_CMD, MDE_DS_COMMD_SEND_FAIL, MDE_DS_MASTER_ONLY, MDE_DS_DRIVENOTONHOST, MDE_DS_CANTRESNARF, MDE_DS_INSUFQUORUM, MDE_DS_EXTENDEDNM, MDE_DS_PARTIALSET, MDE_DS_SINGLEHOST, MDE_DS_AUTONOTSET, MDE_DS_INVALIDDEVID, MDE_DS_SETNOTIMP, MDE_DS_NOTSELFIDENTIFY }; % #if !defined(_KERNEL) struct md_ds_error_t { md_ds_errno_t errnum; set_t setno; string node<>; string drive<>; }; #else /* _KERNEL */ struct md_ds_error_t { md_ds_errno_t errnum; set_t setno; u_int xnode; u_int xdrive; }; #endif /* !_KERNEL */ % %/* % * fundamental error type % */ enum md_errclass_t { MDEC_VOID = 0, /* simple error */ MDEC_SYS, /* system errno */ MDEC_RPC, /* RPC errno */ MDEC_DEV, /* device error */ MDEC_USE, /* use error */ MDEC_MD, /* metadevice error */ MDEC_COMP, /* component error */ MDEC_HSP, /* hotspare pool error */ MDEC_HS, /* hotspare error */ MDEC_MDDB, /* metadevice database error */ MDEC_DS, /* diskset error */ MDEC_OVERLAP /* overlap error */ }; % %/* % * error info % */ union md_error_info_t switch (md_errclass_t errclass) { case MDEC_VOID: md_void_error_t void_error; case MDEC_SYS: md_sys_error_t sys_error; case MDEC_RPC: md_rpc_error_t rpc_error; case MDEC_DEV: md_dev_error_t dev_error; case MDEC_USE: md_use_error_t use_error; case MDEC_MD: md_md_error_t md_error; case MDEC_COMP: md_comp_error_t comp_error; case MDEC_HSP: md_hsp_error_t hsp_error; case MDEC_HS: md_hs_error_t hs_error; case MDEC_MDDB: md_mddb_error_t mddb_error; case MDEC_DS: md_ds_error_t ds_error; case MDEC_OVERLAP: md_overlap_error_t overlap_error; }; % #if !defined(_KERNEL) struct md_error_t { md_error_info_t info; /* specific info */ string host<>; /* hostname */ string extra<>; /* extra context info */ string name<>; /* file or device name */ }; #else /* _KERNEL */ struct md_error_t { md_error_info_t info; /* specific info */ u_int xhost; /* hostname */ u_int xextra; /* extra context info */ u_int xname; /* file or device name */ }; #endif /* !_KERNEL */ %#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 %#pragma pack() %#endif #ifdef RPC_HDR % %/* % * Null error constant % */ %#define MDNULLERROR {{MDEC_VOID}, NULL, NULL, NULL} #endif /* RPC_HDR */ #ifdef RPC_XDR %/* % * Constant null error struct. % */ %const md_error_t mdnullerror = MDNULLERROR; #endif /* RPC_XDR */ #ifdef RPC_HDR % %/* % * External reference to constant null error struct. (declared in mdiox_xdr.c) % */ %extern const md_error_t mdnullerror; % %/* % * External declarations % */ %extern void mdclrerror(md_error_t *ep); /* clear error */ %extern int mdstealerror(md_error_t *to, md_error_t *from); % %#define mdiserror(ep, num) (((ep)->info.errclass == MDEC_VOID) &&\ % ((ep)->info.md_error_info_t_u.void_error.errnum == (num))) %#define mdisok(ep) mdiserror(ep, MDE_NONE) % %#define mdissyserror(ep, num) (((ep)->info.errclass == MDEC_SYS) && \ % ((ep)->info.md_error_info_t_u.sys_error.errnum == (num))) %#define mdisrpcerror(ep, num) (((ep)->info.errclass == MDEC_RPC) && \ % ((ep)->info.md_error_info_t_u.rpc_error.errnum == (num))) %#define mdisdeverror(ep, num) (((ep)->info.errclass == MDEC_DEV) && \ % ((ep)->info.md_error_info_t_u.dev_error.errnum == (num))) %#define mdisuseerror(ep, num) (((ep)->info.errclass == MDEC_USE) && \ % ((ep)->info.md_error_info_t_u.use_error.errnum == (num))) %#define mdismderror(ep, num) (((ep)->info.errclass == MDEC_MD) && \ % ((ep)->info.md_error_info_t_u.md_error.errnum == (num))) %#define mdiscomperror(ep, num) (((ep)->info.errclass == MDEC_COMP) &&\ % ((ep)->info.md_error_info_t_u.comp_error.errnum == (num))) %#define mdishsperror(ep, num) (((ep)->info.errclass == MDEC_HSP) && \ % ((ep)->info.md_error_info_t_u.hsp_error.errnum == (num))) %#define mdishserror(ep, num) (((ep)->info.errclass == MDEC_HS) && \ % ((ep)->info.md_error_info_t_u.hs_error.errnum == (num))) %#define mdismddberror(ep, num) (((ep)->info.errclass == MDEC_MDDB) &&\ % ((ep)->info.md_error_info_t_u.mddb_error.errnum == (num))) %#define mdisdserror(ep, num) (((ep)->info.errclass == MDEC_DS) && \ % ((ep)->info.md_error_info_t_u.ds_error.errnum == (num))) %#define mdisoverlaperror(ep, num) \ % (((ep)->info.errclass == MDEC_OVERLAP) && \ % ((ep)->info.md_error_info_t_u.ds_error.errnum == (num))) % %#define mdanysyserror(ep) ((ep)->info.errclass == MDEC_SYS) %#define mdanyrpcerror(ep) ((ep)->info.errclass == MDEC_RPC) %#define mdanydeverror(ep) ((ep)->info.errclass == MDEC_DEV) %#define mdanyuseerror(ep) ((ep)->info.errclass == MDEC_USE) %#define mdanymderror(ep) ((ep)->info.errclass == MDEC_MD) %#define mdanycomperror(ep) ((ep)->info.errclass == MDEC_COMP) %#define mdanyhsperror(ep) ((ep)->info.errclass == MDEC_HSP) %#define mdanyhserror(ep) ((ep)->info.errclass == MDEC_HS) %#define mdanymddberror(ep) ((ep)->info.errclass == MDEC_MDDB) %#define mdanydserror(ep) ((ep)->info.errclass == MDEC_DS) %#define mdanyoverlaperror(ep) ((ep)->info.errclass == MDEC_OVERLAP) % #ifdef _KERNEL % %extern int mderror(md_error_t *ep, md_void_errno_t errnum); %extern int mdsyserror(md_error_t *ep, int errnum); %extern int mddeverror(md_error_t *ep, md_dev_errno_t errnum, % md_dev64_t dev); %extern int mdmderror(md_error_t *ep, md_md_errno_t errnum, minor_t mnum); %extern int mdcomperror(md_error_t *ep, md_comp_errno_t errnum, % minor_t mnum, md_dev64_t dev); %extern int mdhsperror(md_error_t *ep, md_hsp_errno_t errnum, hsp_t hsp); %extern int mdhserror(md_error_t *ep, md_hs_errno_t errnum, % hsp_t hsp, md_dev64_t dev); %extern int mdmddberror(md_error_t *ep, md_mddb_errno_t errnum, % minor_t mnum, set_t setno); %extern int mddbstatus2error(md_error_t *ep, int status, minor_t mnum, % set_t setno); % #else /* ! _KERNEL */ % %extern int mderror(md_error_t *ep, md_void_errno_t errnum, char *name); %extern int mdsyserror(md_error_t *ep, int errnum, char *name); %extern int mdrpcerror(md_error_t *ep, CLIENT *clntp, char *host, % char *extra); %extern int mdrpccreateerror(md_error_t *ep, char *host, char *extra); %extern int mddeverror(md_error_t *ep, md_dev_errno_t errnum, % md_dev64_t dev, char *name); %extern int mduseerror(md_error_t *ep, md_use_errno_t errnum, % md_dev64_t dev, char *where, char *name); %extern int mdmderror(md_error_t *ep, md_md_errno_t errnum, minor_t mnum, % char *name); %extern int mdcomperror(md_error_t *ep, md_comp_errno_t errnum, % minor_t mnum, md_dev64_t dev, char *name); %extern int mdhsperror(md_error_t *ep, md_hsp_errno_t errnum, hsp_t hsp, % char *name); %extern int mdhserror(md_error_t *ep, md_hs_errno_t errnum, % hsp_t hsp, md_dev64_t dev, char *name); %extern int mdmddberror(md_error_t *ep, md_mddb_errno_t errnum, % minor_t mnum, set_t setno, size_t size, char *name); %extern int mddserror(md_error_t *ep, md_ds_errno_t errnum, set_t setno, % char *node, char *drive, char *name); %extern int mdoverlaperror(md_error_t *ep, md_overlap_errno_t errnum, % char *overlap, char *where, char *name); % %extern void mderrorextra(md_error_t *ep, char *extra); % #endif /* ! _KERNEL */ #endif /* RPC_HDR */ /* * common unit structure */ struct mdc_unit { u_longlong_t un_revision; /* revision # (keep this a longlong) */ md_types_t un_type; /* type of record */ md_status_t un_status; /* status flags */ int un_parent_res; /* parent reserve index */ int un_child_res; /* child reserve index */ minor_t un_self_id; /* metadevice unit number */ mddb_recid_t un_record_id; /* db record id */ uint_t un_size; /* db record size for unit structure */ ushort_t un_flag; /* configuration info */ diskaddr_t un_total_blocks; /* external # blocks in metadevice */ diskaddr_t un_actual_tb; /* actual # blocks in metadevice */ uint_t un_nhead; /* saved value of # heads */ uint_t un_nsect; /* saved value of # sectors */ ushort_t un_rpm; /* saved value of rpm's */ ushort_t un_wr_reinstruct; /* worse case write reinstruct */ ushort_t un_rd_reinstruct; /* worse case read reinstruct */ mddb_recid_t un_vtoc_id; /* vtoc db record id */ md_stackcap_t un_capabilities; /* subdevice capabilities */ md_parent_t un_parent; /* -1 none, -2 many, positive unit # */ uint_t un_user_flags; /* provided for userland */ }; typedef struct mdc_unit mdc_unit_t; /* * For old 32 bit format use only */ %#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 %#pragma pack(4) %#endif struct mdc_unit32_od { u_longlong_t un_revision; md_types_t un_type; md_status_t un_status; int un_parent_res; int un_child_res; minor_t un_self_id; mddb_recid_t un_record_id; uint_t un_size; ushort_t un_flag; daddr32_t un_total_blocks; /* external # blocks in metadevice */ daddr32_t un_actual_tb; /* actual # blocks in metadevice */ ushort_t un_nhead; ushort_t un_nsect; ushort_t un_rpm; ushort_t un_wr_reinstruct; ushort_t un_rd_reinstruct; mddb_recid_t un_vtoc_id; md_stackcap_t un_capabilities; md_parent_t un_parent; uint_t un_user_flags; }; typedef struct mdc_unit32_od mdc_unit32_od_t; struct md_unit { mdc_unit_t c; /* common stuff */ }; typedef struct md_unit md_unit_t; enum sp_status_t { MD_SP_CREATEPEND, /* soft partition creation in progress */ MD_SP_GROWPEND, /* attach operation in progress */ MD_SP_DELPEND, /* delete operation in progress */ MD_SP_OK, /* soft partition is stable */ MD_SP_ERR, /* soft partition is errored */ MD_SP_RECOVER, /* recovery operation in progess */ MD_SP_LAST /* always the last entry */ }; /* soft partition offsets and lengths are specified in sectors */ typedef u_longlong_t sp_ext_offset_t; typedef u_longlong_t sp_ext_length_t; struct mp_ext { sp_ext_offset_t un_voff; /* virtual offset */ sp_ext_offset_t un_poff; /* physical offset */ sp_ext_length_t un_len; /* length of extent */ }; typedef struct mp_ext mp_ext_t; /* * mp_unit32_od is for old 32 bit format only */ struct mp_unit32_od { mdc_unit32_od_t c; /* common unit structure */ mdkey_t un_key; /* namespace key */ dev32_t un_dev; /* device number */ sp_ext_offset_t un_start_blk; /* start block, incl reserved space */ sp_status_t un_status; /* sp status */ uint_t un_numexts; /* number of extents */ sp_ext_length_t un_length; /* total length (in sectors) */ /* extent array. NOTE: sized dynamically! */ mp_ext_t un_ext[1]; }; typedef struct mp_unit32_od mp_unit32_od_t; /* * softpart unit structure */ struct mp_unit { mdc_unit_t c; /* common unit structure */ mdkey_t un_key; /* namespace key */ md_dev64_t un_dev; /* device number, 64 bit */ sp_ext_offset_t un_start_blk; /* start block, incl reserved space */ sp_status_t un_status; /* sp status */ uint_t un_numexts; /* number of extents */ sp_ext_length_t un_length; /* total length (in sectors) */ /* extent array. NOTE: sized dynamically! */ mp_ext_t un_ext[1]; }; typedef struct mp_unit mp_unit_t; /* * ioctl structures used when passing ioctls via rpc.mdcommd */ struct md_driver { char md_drivername[MD_MAXDRVNM]; set_t md_setno; }; typedef struct md_driver md_driver_t; %#define MD_DRIVER md_driver_t md_driver; #define MD_DRIVER md_driver_t md_driver; struct md_set_params { MD_DRIVER md_error_t mde; minor_t mnum; md_types_t type; uint_t size; int options; uint64_t mdp; /* Contains pointer */ }; typedef struct md_set_params md_set_params_t; %#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 %#pragma pack() %#endif