mdvar.h revision da83352438a4a62b87fcb6fd1583e3a70aa31bb8
/*
* 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
* 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.
*/
#ifndef _SYS_MDVAR_H
#define _SYS_MDVAR_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef DEBUG
#endif
#include <sys/efi_partition.h>
#include <sys/byteorder.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* defaults
*/
#define MAXBOOTLIST 64
/*
* Needed for backwards-compatibility with metadevices created under
* 2.6 or earlier. Back then, a krwlock_t was twelve bytes. More
* recently, it's four bytes. Since these get included in structures
* written out to disk, we have to make sure we're using the largest
* size. Things will get interesting if krwlock_t ever gets bigger
* than twelve bytes.
*/
typedef union _md_krwlock {
struct {
void *_opaque[3];
} xx;
} md_krwlock_t;
typedef struct {
long io_state; /* !0 if waiting on zero */
} md_set_io_t;
typedef enum set_iostate {
MD_SET_ACTIVE = 1,
MD_SET_RELEASE = 2
/*
* for md_dev64_t translation
*/
struct md_xlate_table {
};
extern struct md_xlate_table *md_tuple_table;
/*
* for major number translation
*/
struct md_xlate_major_table {
char *drv_name;
};
extern struct md_xlate_major_table *md_major_tuple_table;
extern int md_tuple_length;
extern uint_t md_majortab_len;
extern int md_in_upgrade;
extern md_mn_nodeid_t md_mn_mynode_id;
/*
* Flags used during upgrade:
*
* md_keep_repl_state flag means that mddb should be kept in the format
* that was found on disk (non-device id format vs. device id format).
* This is used during the upgrade process when install is probing
* for root disks so that the user can choose the one to be upgraded.
*
* md_devid_destroy flag is used to destroy device ids stored in the
* metadevice state database (mddb).
*
* The md_devid_destroy flag is to be used only in a catastrophic failure
* case. An example of this would be if a user upgrades firmware on all
* disks where this causes the disks to now have different device id's.
* The user would not be able to boot a mirror'd root filesystem since the
* system would recognize none of the device id's stored in the mddb.
* This flag would destroy all device id information stored in the mddb and
* if the md_keep_repl_state flag was not set, the mddb would be reconverted
* to device id format on SLVM startup and all of the device id
* information would be regenerated.
*
* If the md_devid_destroy flag is set and the md_keep_repl_state flag is
* set, the mddb's would have their device id information destroyed and
* would be left in non-devid format since the device id information would
* not be regenerated.
*
* This flag is not documented anywhere and is only to be used as a last
* resort as in the described case or if a device driver has a bug where
* device id's are found to not be unique. If device id's aren't unique,
* the user could run without device id's until a patch is released for
* that driver.
*/
extern int md_keep_repl_state;
extern int md_devid_destroy;
extern int mdmn_door_did;
#ifdef _KERNEL
extern door_handle_t mdmn_door_handle;
#endif /* _KERNEL */
/*
* An io_lock mechanism for raid, the MD_UL_XXXX bits are used for
* convenience.
*/
typedef struct md_io_lock {
void *io_list_front;
void *io_list_back;
} md_io_lock_t;
/*
* The following flags are in un_flag field of mdc_unit struct.
*/
/*
* This is the number of bytes a DKIOCGETEFI ioctl returns
* For now it's one time the header and once the size for a partition info
*/
/* This is the number of bytes consumed by efi_gpe_PartitionName */
typedef enum hs_cmds {
} hs_cmds_t;
typedef struct md_link {
} md_link_t;
typedef struct mdi_unit {
int ui_opsindex;
} mdi_unit_t;
/*
* Following are used with ui_lock
* which is in the unit incore structure.
*/
#define MD_UL_WANABEWRITER 0x0002
#define MD_UL_OPENORCLOSE 0x0004
/*
* The softpart open code may do an I/O to validate the watermarks
* and should hold no open locks during this I/O. So, mark the unit
* as OPENINPROGRESS and drop the locks. This will keep any other
* softpart open's waiting until the validate has completed.
*/
/*
* Following are used with ui_tstate to specify any transient states which
* occur during metadevice operation. These are not written to the metadb as
* they do not represent a failure of the underlying metadevice.
* Transient errors are stored in the lower 16 bits and other transient
* state is stored in the upper 16 bits.
* MD_NOTOPENABLE should contain all the states that are set prior to an
* open (by snarf) and that indicate that a metadevice cannot be opened.
*/
/* A metadevice cannot be opened when these states are set */
typedef struct md_ioctl_lock {
int l_flags; /* locks held */
#define MD_MASTER_DROPPED 0x0001
#define MD_READER_HELD 0x0002
#define MD_WRITER_HELD 0x0004
#define MD_IO_HELD 0x0008
#define MD_ARRAY_READER 0x0010
#define MD_ARRAY_WRITER 0x0020
#define STALE_OK 0x0100
#define NO_OLD 0x0200
#define NO_LOCK 0x0400
#define IOLOCK md_ioctl_lock_t
#define WR_LOCK MD_WRITER_HELD
#define ARRAY_WRITER MD_ARRAY_WRITER
#define ARRAY_READER MD_ARRAY_READER
#define IOLOCK_RETURN_REACQUIRE(lock) \
/*
* checks to be sure locks are held
*/
#define UNIT_WRITER_HELD(un) \
#define UNIT_READER_HELD(un) \
#define IO_WRITER_HELD(un) \
#define IO_READER_HELD(un) \
#ifdef DEBUG
statvar++
statvar--
statvar = 0;
{ \
statvar++; \
}
{ \
if (value) \
statvar++; \
}
#else
#endif
/*
* bit map related macros
*/
typedef struct daemon_queue {
int maxq_len;
int qlen;
int treqs; /* total number of requests */
struct daemon_queue *dq_next;
struct daemon_queue *dq_prev;
void (*dq_call)();
#ifdef _KERNEL
#define MDI_UNIT(m) ((mdi_unit_t *) \
/*
* This is the current maximum number of real disks per Virtual Disk.
*/
/*
* daemon threads are used in multiple places in md. The following set of
* structures and routines allow a common way to create and initialize them.
*
* md_requestq_entry_t - entry of creating request queues.
* struct mdq_anchor - request queue header
*
* Functions associated with request queues:
*
* int init_requestq_entry -
* void daemon_request - put a request on the queue.
*/
typedef struct md_requestq_entry {
struct mdq_anchor *dispq_headp;
int *num_threadsp; /* threads servicing the queue */
#define NULL_REQUESTQ_ENTRY(rqp)\
/* this typedef is used to differentiate between the two call styles */
typedef enum callstyle {
} callstyle_t;
#define daemon_request_new daemon_request
typedef struct mdq_anchor {
} mdq_anchor_t;
typedef struct daemon_request {
int dr_pending;
typedef struct sv_dev {
} sv_dev_t;
/*
* Types of device probes
*/
typedef struct probe_req {
void *private_handle; /* private handle */
} probe_req_t;
/* Global flags */
#define MD_GBL_DAEMONS_DIE 0x0002
/* Available bit was GBL_STALE 0x0008 */
typedef struct md_named_services {
intptr_t (*md_service)();
char *md_name;
typedef struct md_ops {
int (*md_open)(
int flag,
int otyp,
int md_oflags);
int (*md_close)(
int flag,
int otyp,
int md_oflags);
void (*md_strategy)(
int flag,
void *private);
int (*md_print)(); /* unused now */
int (*md_dump)(
int nblk);
int (*md_read)(
int (*md_write)(
int (*md_ioctl)(
int cmd,
void *data,
int mode,
int (*md_snarf)(
int (*md_halt)();
int (*md_aread)(
int (*md_awrite)(
int (*md_imp_set)(
/*
* o md_modid and md_locked should be deleted.
* o md_mod should be added
* ddi_modhandle_t md_mod;
* and used instead of the md_mods array (md_mods should
* be deleted).
*/
int md_modid;
int md_locked;
int md_selfindex;
/* NOTE: TSlvm depends on offsets in and sizeof this structure */
} md_ops_t;
/* macro to generate linkage for a md misc plugin module */
#define md_noop
}; \
static struct modlinkage modlinkage = { \
}; \
int \
_init(void) \
{ \
int i; \
init_init; \
if ((i = mod_install(&modlinkage)) != 0) { \
fini_uninit; \
} \
return (i); \
} \
int \
_fini() \
{ \
int i; \
if ((i = mod_remove(&modlinkage)) == 0) { \
fini_uninit; \
} \
return (i); \
} \
int \
{ \
}
} md_haltcmd_t;
/*
* To support cpr (Energy Star) we need to know when the resync threads are
* running to not allow suspention.
*/
typedef struct md_resync_thds_cnt {
int md_raid_resync; /* count of active raid resync threads */
int md_mirror_resync; /* count of active mirror resync threads */
} md_resync_t;
/*
* flags used with call to individual strategy routines
*/
#define MD_STR_PASSEDON 0x0000ffff
#define MD_STR_NOTTOP 0x00000001
/*
* Bits for return value of md_getdevnum
*/
#define MD_TRUST_DEVT 1
#define MD_NOTRUST_DEVT 0
/* Flag for drivers to pass to kmem_cache_alloc() */
/* Named services */
#define MD_CHECK_OFFLINE "check_offline"
#define MD_INC_ABR_COUNT "inc abr count"
#define MD_DEC_ABR_COUNT "dec abr count"
/* Externals from md.c */
extern int mdstrategy(buf_t *);
/* External from md_subr.c */
extern int md_inc_iocount(set_t);
extern void md_inc_iocount_noblock(set_t);
extern void md_dec_iocount(set_t);
extern int md_isblock_setio(set_t);
extern int md_block_setio(set_t);
extern void md_clearblock_setio(set_t);
extern void md_unblock_setio(set_t);
extern int md_tas_block_setio(set_t);
extern void md_biodone(struct buf *);
extern void md_bioreset(struct buf *);
extern void md_xlate_free(int);
extern major_t md_targ_name_to_major(char *);
extern char *md_targ_major_to_name(major_t);
extern void md_majortab_free();
extern void md_set_status(int);
extern void md_clr_status(int);
extern int md_get_status(void);
extern void md_set_setstatus(set_t, int);
extern void md_clr_setstatus(set_t, int);
extern void *md_unit_readerlock(mdi_unit_t *);
extern void *md_unit_writerlock(mdi_unit_t *);
extern void md_unit_readerexit(mdi_unit_t *);
extern void md_unit_writerexit(mdi_unit_t *);
extern void md_ioctl_releaselocks(int, int, mdi_unit_t *);
extern void md_ioctl_reacquirelocks(int, mdi_unit_t *);
extern int md_ioctl_lock_exit(int, int, mdi_unit_t *, int);
extern int md_ioctl_lock_enter(void);
extern void md_ioctl_readerexit(IOLOCK *);
extern void md_ioctl_writerexit(IOLOCK *);
extern void md_ioctl_io_exit(IOLOCK *);
extern void md_ioctl_droplocks(IOLOCK *);
extern void md_array_writer(IOLOCK *);
extern void md_array_reader(IOLOCK *);
extern void md_ioctl_openclose_exit(IOLOCK *);
extern void md_ioctl_openclose_exit_lh(IOLOCK *);
extern void *md_unit_openclose_enter(mdi_unit_t *);
extern void md_unit_openclose_exit(mdi_unit_t *);
extern void md_unit_openclose_exit_lh(mdi_unit_t *);
extern void *md_io_readerlock(mdi_unit_t *);
extern void *md_io_writerlock(mdi_unit_t *);
extern void md_io_readerexit(mdi_unit_t *);
extern void md_io_writerexit(mdi_unit_t *);
extern intptr_t (*md_get_named_service())();
extern int init_requestq(md_requestq_entry_t *, void (*)(),
caddr_t, int, int);
extern void daemon_request(mdq_anchor_t *, void(*)(),
extern void md_daemon(int, mdq_anchor_t *);
extern void mddb_commitrec_wrapper(mddb_recid_t);
extern void mddb_commitrecs_wrapper(mddb_recid_t *);
extern void mddb_deleterec_wrapper(mddb_recid_t);
extern int md_halt(int global_lock_flag);
extern void md_layered_close(md_dev64_t, int);
extern char *md_get_device_name(md_dev64_t);
extern int md_start_daemons(int init_queues);
extern int md_loadsubmod(set_t, char *, int);
extern int md_getmodindex(md_driver_t *, int, int);
extern void md_call_strategy(buf_t *, int, void *);
extern int md_dev_exists(md_dev64_t);
extern void md_reset_parent(md_dev64_t);
extern void md_rem_names(sv_dev_t *, int);
struct uio;
extern int md_chk_uio(struct uio *);
extern void md_minphys(buf_t *);
extern proc_t *md_getproc(void);
extern int md_check_ioctl_against_efi(int, ushort_t);
md_mn_kresult_t *);
extern void mdmn_ksend_show_error(int, md_mn_kresult_t *, const char *);
extern void mdmn_clear_all_capabilities(minor_t);
extern int md_init_probereq(struct md_probedev_impl *p,
daemon_queue_t **hdrpp);
extern boolean_t callb_md_mrs_cpr(void *, int);
extern int md_rem_selfname(minor_t);
/* Externals from md_ioctl.c */
extern int md_mn_is_commd_present(void);
extern void md_mn_clear_commd_present(void);
extern void md_get_efi(md_unit_t *, char *);
extern int md_set_efi(md_unit_t *, char *);
extern int md_dkiocgetefi(minor_t, void *, int);
extern int md_dkiocsetefi(minor_t, void *, int);
extern int md_dkiocpartition(minor_t, void *, int);
extern void md_remove_minor_node(minor_t);
/* Externals from md_names.c */
set_t, md_error_t *);
size_t);
char *);
extern void md_unload_namespace(set_t, int);
extern int md_nm_did_chkspace(set_t);
extern void md_bioinit();
md_error_t *ep);
void *didptr);
extern void md_timeval(md_timeval32_t *);
extern int md_imp_snarf_set(mddb_config_t *);
/* externals from md_mddb.c */
extern void *lookup_shared_entry(struct nm_next_hdr *,
char *, int);
mddb_recid_t *);
#endif /* _KERNEL */
/* externals from md_revchk.c */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_MDVAR_H */