2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * Just in case we're not in a build environment, make sure that 2N/A * TEXT_DOMAIN gets set to something. 2N/A * FUNCTION: meta_get_mirror_names() 2N/A * INPUT: sp - the set name to get mirrors from 2N/A * options - options from the command line 2N/A * OUTPUT: nlpp - list of all mirror names 2N/A * ep - return error pointer 2N/A * RETURNS: int - -1 if error, 0 success 2N/A * PURPOSE: returns a list of all mirrors in the metadb 2N/A * for all devices in the specified set 2N/A /* get miscname and unit */ 2N/A /* allocate mirror */ 2N/A /* get common info */ 2N/A /* get submirrors */ 2N/A /* get submirror state */ 2N/A /* get submirror time of last state change */ 2N/A /* get submirror flags */ 2N/A /* get submirror name */ 2N/A /* get resync info */ 2N/A /* cleanup, return success */ 2N/A /* cleanup, return error */ 2N/A * check mirror for dev 2N/A /* should be in the same set */ 2N/A /* look in submirrors */ 2N/A /* skip unused submirrors */ 2N/A /* return success */ 2N/A * check to see if we're in a mirror 2N/A /* should have a set */ 2N/A /* for each mirror */ 2N/A /* cleanup, return success */ 2N/A * Check to see if the primary mirror is built on top of a 2N/A * root slice which is mounted. This check is primarily to 2N/A * account for this case - 2N/A * # metainit -f d1 1 1 <root slice> 2N/A * # metainit d0 -m d1 2N/A * # metainit d2 1 1 ctds 2N/A * The metattach here needs to fail if the root slice is 2N/A * being mirrored; otherwise there is a potential for 2N/A * We need to take the canonical name here otherwise the call to 2N/A * metaname will add a bad entry to the drivelistp cache and 2N/A * things will get nasty later on. 2N/A * However we also need to trap the case where we have a logical 2N/A * device name and meta_canonicalize returns NULL. 2N/A * Get device name of current root metadevice. If root 2N/A * is net mounted as happens if we're part of the 2N/A * install process, rootnp will be set to NULL and we 2N/A * Since curroot should be a complete path, we only 2N/A * need to check whether the device is a logical device. 2N/A * The metaname below returns NULL if curroot is not a logical 2N/A * If we're here, the curroot is a mounted on a logical device. 2N/A * Make sure this mirror is not on the root logical device. 2N/A /* Check all submirrors */ 2N/A /* skip unused submirrors */ 2N/A /* check if submirror is a stripe or not */ 2N/A * Examine the first component of the first row and 2N/A * check to see if it has a mounted root slice 2N/A * we just care about the component built on 2N/A * top of a raw device 2N/A * If root device is the 1st component of 2N/A * the stripe, then fail. 2N/A /* return success */ 2N/A /* make sure we have a metadevice disk */ 2N/A * Check to see if the primary mirror consists of a root 2N/A /* check to ensure that it is not already in use */ 2N/A /* make sure it is in the set */ 2N/A /* make sure its not in a metadevice */ 2N/A }
else {
/* Metadevices only! */ 2N/A /* make sure it can be parented */ 2N/A /* return success */ 2N/A * convert read options 2N/A return (
"roundrobin");
2N/A return (
"geometric");
2N/A * convert write options 2N/A return (
"parallel");
2N/A * convert pass numbers 2N/A * convert resync option 2N/A /* print name and -m */ 2N/A /* print submirrors */ 2N/A /* skip unused submirrors */ 2N/A /* print submirror */ 2N/A /* cleanup, return error */ 2N/A * convert submirror state to name 2N/A * Only return Unavailable if there is no flagged error on the 2N/A * submirror. If the mirror has received any writes since the submirror 2N/A * went into Unavailable state a resync is required. To alert the 2N/A * administrator to this we return a 'Needs maintenance' message. 2N/A /* resyncing, needs repair */ 2N/A * convert submirror state to repair action 2N/A /* complete cancelled resync */ 2N/A /* replace stripe component */ 2N/A "metareplace %s %s <%s>",
2N/A "after replacing \"Maintenance\" " 2N/A "\t\tmetareplace %s %s <new device>"),
2N/A /* online submirror */ 2N/A /* unknown action */ 2N/A * print mirror options 2N/A /* Display resync option for mirror, if MultiNode set */ 2N/A " Resync option: %s\n"),
2N/A /* cleanup, return error */ 2N/A /* get the known membership list */ 2N/A /* find the matching node and return the name */ 2N/A /* match not found */ 2N/A * check for the -B option. If -B and the metadevice is 2N/A * a 64 bit device, get the dev for relocation information 2N/A * printout. If not a 64 bit device, just don't print this 2N/A * information out but you need to go down to the subdevice 2N/A * level and print there if appropriate. 2N/A * check for the -D option. If -D and the name is 2N/A * a descriptive name, get the dev for relocation information 2N/A * printout. If not a descriptive name, don't print this 2N/A * information out but you need to go down to the subdevice 2N/A * level and print there if appropriate. 2N/A /* print submirrors, adjust status */ 2N/A /* skip unused submirrors */ 2N/A /* print submirror */ 2N/A " State: %-12s %s\n"),
2N/A /* print resync status */ 2N/A /* Resync was cancelled but is restartable */ 2N/A " Resync cancelled: %2d.%1d %% done\n"),
2N/A " Resync cancelled: %d %% done\n"),
2N/A " Resync in progress: %2d.%1d %% done\n"),
2N/A " Resync in progress: %d %% done\n"),
2N/A /* print mirror owner for multi-node metadevice */ 2N/A "MD_MN_GET_MM_OWNER") != 0) {
2N/A /* MD_DEBUG stuff */ 2N/A /* get real mirror unit */ 2N/A /* print dirty regions */ 2N/A" Regions which are dirty: %d%% (blksize %d num %d)\n"),
2N/A /* print optimized resync record locations */ 2N/A "MD_DB_GETOPTLOC") != 0) {
2N/A /* Don't need device id information from this ioctl */ 2N/A "MD_DB_ENDDEV") != 0) {
2N/A " Resync record[%u]: %d (%s %d %d)\n"), i,
2N/A /* print submirror details */ 2N/A /* skip unused submirrors */ 2N/A /* get unit structure */ 2N/A /* add extra line */ 2N/A /* print submirror */ 2N/A "%s: Submirror of %s\n"),
2N/A " State: %-12s %s\n"),
2N/A /* print what to do */ 2N/A " Invoke: %s\n"), p) ==
EOF)) {
2N/A /* print underlying metadevice */ 2N/A /* add extra line */ 2N/A /* cleanup, return error */ 2N/A /* should have same set */ 2N/A /* print all mirrors */ 2N/A /* cleanup, return success */ 2N/A /* get unit structure */ 2N/A /* check for parented */ 2N/A /* print appropriate detail */ 2N/A /* print underlying metadevices */ 2N/A /* skip unused submirrors */ 2N/A /* print submirror */ 2N/A /* return success */ 2N/A /* should have same set */ 2N/A /* Only valid for mirror without ABR set */ 2N/A * In a MN set, the master always executes the online command first. 2N/A * Before the master executes the IOC_ONLINE ioctl, 2N/A * the master sends a message to all nodes to suspend writes to 2N/A * this mirror. Then the master executes the IOC_ONLINE ioctl 2N/A * which resumes writes to this mirror from the master node. 2N/A * As each slave executes the online command, each slave will 2N/A * call the IOC_ONLINE ioctl which will resume writes to this mirror 2N/A * from that slave node. 2N/A /* online submirror */ 2N/A "%s: submirror %s is onlined\n"),
2N/A /* return success */ 2N/A /* should have same set */ 2N/A /* Only valid for mirror without ABR set */ 2N/A * In a MN set, the master always executes the offline command first. 2N/A * Before the master executes the IOC_OFFLINE ioctl, 2N/A * the master sends a message to all nodes to suspend writes to 2N/A * this mirror. Then the master executes the IOC_OFFLINE ioctl 2N/A * which resumes writes to this mirror from the master node. 2N/A * As each slave executes the offline command, each slave will 2N/A * call the IOC_OFFLINE ioctl which will resume writes to this mirror 2N/A * from that slave node. 2N/A /* offline submirror */ 2N/A "%s: submirror %s is offlined\n"),
2N/A /* return success */ 2N/A * attach submirror to mirror 2N/A * we actually never have to worry about crossing a thresh hold here. 2N/A * 2 cases 1) attach and the only way the mirror can be 64 bit is if 2N/A * one of the submirrors already is. 2) grow and the only way the mirror 2N/A * is 64 bit is if one of the submirror's already is. 2N/A /* should have same set */ 2N/A /* check submirror */ 2N/A /* In dryrun mode (DOIT not set) we must not alter the mddb */ 2N/A /* store name in namespace */ 2N/A * In a MN set, the master always executes the attach command first. 2N/A * Before the master executes the IOC_ATTACH ioctl, in non-DRYRUN mode 2N/A * the master sends a message to all nodes to suspend writes to 2N/A * this mirror. Then the master executes the IOC_ATTACH ioctl 2N/A * which resumes writes to this mirror from the master node. 2N/A * As each slave executes the attach command, each slave will 2N/A * call the IOC_ATTACH ioctl which will resume writes to this mirror 2N/A * from that slave node. 2N/A /* attach submirror */ 2N/A /* if the comamnd was issued with -n option, use dryrun mode */ 2N/A /* In dryrun mode (DOIT not set) we must not alter the mddb */ 2N/A /* In dryrun mode (DOIT not set) we must not alter the mddb */ 2N/A /* return success */ 2N/A /* should have same set */ 2N/A * In a MN set, the master always executes the detach command first. 2N/A * Before the master executes the IOC_DETACH ioctl, 2N/A * the master sends a message to all nodes to suspend writes to 2N/A * this mirror. Then the master executes the IOC_DETACH ioctl 2N/A * which resumes writes to this mirror from the master node. 2N/A * As each slave executes the detach command, each slave will 2N/A * call the IOC_DETACH ioctl which will resume writes to this mirror 2N/A * from that slave node. 2N/A /* detach submirror */ 2N/A "%s: submirror %s is detached\n"),
2N/A /* return success */ 2N/A * get mirror parameters 2N/A /* should have a set */ 2N/A /* return parameters */ 2N/A * set mirror parameters 2N/A /* should have a set */ 2N/A /* set parameters */ 2N/A /* return success */ 2N/A * invalidate submirror names 2N/A * replace mirror component 2N/A /* should have same set */ 2N/A /* save new binding incase this is a rebind where oldnp==newnp */ 2N/A /* invalidate, then get the mirror (fill in oldnp from metadb) */ 2N/A /* the old device binding is now established */ 2N/A * check for the case where oldnp and newnp indicate the same 2N/A * device, but the dev_t of the device has changed between old 2N/A * and new. This is called a rebind. On entry the dev_t 2N/A * represents the new device binding determined from the 2N/A * filesystem (meta_getdev). After calling meta_get_unit 2N/A * oldnp (and maybe newnp if this is a rebind) is updated based 2N/A * to the old binding from the metadb (done by metakeyname). 2N/A * Save a copy of the devid associated with the new disk, the reason 2N/A * is that if we are rebinding then the call to meta_check_component() 2N/A * will cause the devid of the disk to be overwritten with what is in 2N/A * the replica namespace. The function that actually overwrites the 2N/A * devid is dr2drivedesc(). 2N/A /* if it's a multi-node diskset clear new_devidp */ 2N/A /* check it out (dup on rebind is ok) */ 2N/A * Copy back the saved devid. 2N/A /* store name in namespace, allocate new key */ 2N/A * In a MN set, the master always executes the replace command first. 2N/A * Before the master executes the IOC_REPLACE ioctl, in non-DRYRUN mode 2N/A * the master sends a message to all nodes to suspend writes to 2N/A * this mirror. Then the master executes the IOC_REPLACE ioctl 2N/A * which resumes writes to this mirror from the master node. 2N/A * As each slave executes the replace command, each slave will 2N/A * call the IOC_REPLACE ioctl which will resume writes to this mirror 2N/A * from that slave node. 2N/A * We are 'rebind'ing a disk that is in a diskset so as well 2N/A * as updating the diskset's namespace the local set needs 2N/A * to be updated because it also contains a reference to 2N/A * the disk in question. 2N/A /* replace component */ 2N/A /* Is this just a dryrun ? */ 2N/A "%s: device %s is replaced with %s\n"),
2N/A /* return success */ 2N/A * enable mirror component 2N/A /* should have same set */ 2N/A /* get the file_system dev binding */ 2N/A /* get the mirror unit (fill in compnp->dev with metadb version) */ 2N/A /* the metadb device binding is now established */ 2N/A * check for the case where the dev_t has changed between the 2N/A * filesystem and the metadb. This is called a rebind, and 2N/A * is handled by meta_mirror_replace. 2N/A /* establish file system binding with invalid start/end */ 2N/A /* setup mirror info */ 2N/A * In a MN set, the master always executes the replace command first. 2N/A * Before the master executes the IOC_REPLACE ioctl, in non-DRYRUN mode 2N/A * the master sends a message to all nodes to suspend writes to 2N/A * this mirror. Then the master executes the IOC_REPLACE ioctl 2N/A * which resumes writes to this mirror from the master node. 2N/A * As each slave executes the replace command, each slave will 2N/A * call the IOC_REPLACE ioctl which will resume writes to this mirror 2N/A * from that slave node. 2N/A /* enable component */ 2N/A /* Is this just a dryrun ? */ 2N/A * Are we dealing with a non-local set? If so need to update the 2N/A * local namespace so that the disk record has the correct devid. 2N/A * Failed to update the local set. Nothing to do here 2N/A * apart from report the error. The namespace is 2N/A * most likely broken and some form of remedial 2N/A * recovery is going to be required. 2N/A "%s: device %s is enabled\n"),
2N/A /* return success */ 2N/A * check for dups in the mirror itself 2N/A /* check submirrors */ 2N/A /* skip unused submirrors */ 2N/A /* check submirror */ 2N/A /* check this mirror too */ 2N/A /* check read option */ 2N/A /* check write option */ 2N/A /* check pass number */ 2N/A /* return success */ 2N/A * setup mirror geometry 2N/A /* get worst reinstructs */ 2N/A /* setup geometry from first submirror */ 2N/A /* return success */ 2N/A /* validate mirror */ 2N/A /* allocate mirror unit */ 2N/A /* skip unused submirrors */ 2N/A /* adjust for smallest submirror */ 2N/A /* store name in namespace */ 2N/A /* setup submirror */ 2N/A /* fill in the size of the mirror */ 2N/A /* if we're not doing anything, return success */ 2N/A /* did the user tell us to generate a large device? */ 2N/A /* cleanup, return success */ 2N/A * NOTE: this functions is metainit(1m)'s command line parser! 2N/A /* get mirror name */ 2N/A /* see if it exists already */ 2N/A /* parse general options */ 2N/A /* allocate mirror */ 2N/A /* parse submirrors */ 2N/A /* check for room */ 2N/A /* parse submirror name */ 2N/A /* dangerous n-way mirror creation */ 2N/A"%s: WARNING: This form of metainit is not recommended.\n" 2N/A"The submirrors may not have the same data.\n" 2N/A"Please see ERRORS in metainit(1M) for additional information.\n"),
2N/A /* parse mirror options */ 2N/A /* parse pass number */ 2N/A /* we should be at the end */ 2N/A "%s: Mirror is setup\n"),
2N/A /* cleanup, return error */ 2N/A /* should have same set */ 2N/A /* reset all mirrors */ 2N/A /* for each mirror */ 2N/A * If this is a multi-node set, we send a series 2N/A * of individual metaclear commands. 2N/A /* cleanup return success */ 2N/A /* get unit structure */ 2N/A /* make sure nobody owns us */ 2N/A /* clear subdevices cache */ 2N/A /* clear metadevice */ 2N/A /* clear subdevices */ 2N/A /* skip unused submirrors */ 2N/A /* make sure we have a metadevice */ 2N/A /* clear submirror */ 2N/A /* cleanup, return success */ 2N/A * reports TRUE if any mirror component is in error