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 2008 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 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 /* should have same set */ 2N/A /* the old device binding is now established */ 2N/A /* In dryrun mode (DOIT not set) we must not alter the mddb */ 2N/A * There is no need to call meta_fixdevid() here as this function is 2N/A * only called by the metareplace -c command which actually does 2N/A * nothing (in terms of a resync) and thus does nothing with the devid. 2N/A /* Is this just a dryrun ? */ 2N/A "%s: device %s is replaced with %s\n"),
2N/A * FUNCTION: meta_get_stripe_names() 2N/A * INPUT: sp - the set name to get stripes from 2N/A * options - options from the command line 2N/A * OUTPUT: nlpp - list of all stripe names 2N/A * ep - return error pointer 2N/A * RETURNS: int - -1 if error, 0 success 2N/A * PURPOSE: returns a list of all stripes in the metadb 2N/A * for all devices in the specified set 2N/A * get stripe (common) 2N/A /* get miscname and unit */ 2N/A /* allocate stripe */ 2N/A /* get common info */ 2N/A /* allocate comps */ 2N/A /* get components */ 2N/A /* get the component name */ 2N/A /* get the hotspare name */ 2N/A /* override any start_blk */ 2N/A /* get the right component start_blk */ 2N/A /* override any start_blk */ 2N/A /* get time of last state change */ 2N/A /* get lasterr count */ 2N/A /* cleanup, return success */ 2N/A /* cleanup, return error */ 2N/A * check stripe for dev 2N/A /* should be in the same set */ 2N/A /* look in columns */ 2N/A /* check same drive since metagetstart() can fail */ 2N/A /* return success */ 2N/A * check to see if we're in a stripe 2N/A /* should have a set */ 2N/A /* for each stripe */ 2N/A /* cleanup, return success */ 2N/A * See if we are a soft partition: meta_sp_issp() returns 0 if 2N/A * np points to a soft partition, so the if and else clauses 2N/A * here represent "not a soft partition" and "soft partition," 2N/A /* make sure we have a disk */ 2N/A /* make sure soft partition can parent & doesn't have parent */ 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 /* return success */ 2N/A /* print name and num rows */ 2N/A /* print num components */ 2N/A * Print components. Always print the full path name. 2N/A /* print interlace */ 2N/A /* print continuation */ 2N/A /* print hotspare name */ 2N/A /* terminate last line */ 2N/A /* cleanup, return error */ 2N/A * convert component state to name 2N/A * print subdevice stripe row 2N/A * building a format string on the fly that will be used 2N/A * in fprintf. This is to allow really really long ctd names 2N/A "\t%-*.*s %-12.12s %5.5s %12.12s %5.5s %s\n",
2N/A "\t%-*s %5s %5s %-11s %-5s %-9s %s\n",
2N/A /* print components */ 2N/A * If the component is a metadevice, print out either 2N/A * unavailable or the state of the metadevice, if not 2N/A * a metadevice, print nothing if the state of the 2N/A * stripe is unavailable 2N/A * if top_tstate is set, that implies that you have 2N/A * a ctd type device with an unavailable metadevice 2N/A * on top of it. If so, print a - for it's state 2N/A /* populate the key in the name_p structure */ 2N/A /* determine if devid does NOT exist */ 2N/A * building a format string on the fly that will be used 2N/A * in fprintf. This is to allow really really long ctd names 2N/A "\t%-*s %8lld %-5.5s %12.12s %5.5s %s\n",
2N/A "\t%-*s %5lld %-5s %-11s %-5s %-9s %s\n",
2N/A /* cleanup, return error */ 2N/A * print toplevel stripe row 2N/A * building a format string on the fly that will be used 2N/A * in fprintf. This is to allow really really long ctd names 2N/A "\t%-*.*s %-12.12s %-5.5s\t%s\n",
2N/A /* print components */ 2N/A /* populate the key in the name_p structure */ 2N/A /* determine if devid does NOT exist */ 2N/A * building a format string on the fly that will be used 2N/A * in fprintf. This is to allow really really long ctd names 2N/A "\t%-*s %8lld %-5.5s\t%s\n",
len,
2N/A /* cleanup, return error */ 2N/A * print stripe options 2N/A /* cleanup, return error */ 2N/A * if the -B option has been specified check to see if the 2N/A * metadevice is s "big" one and print if so, also if a 2N/A * big device we need to store the ctd involved for use in 2N/A * printing out the relocation information. 2N/A * if the -D option has been specified check to see if the 2N/A * metadevice has a descriptive name and print if so, also if a 2N/A * descriptive device name we need to store the ctd involved 2N/A * for use in printing out the relocation information. 2N/A /* print hotspare pool */ 2N/A " State: Unavailable\n" 2N/A " Reconnect disk and invoke: metastat -i\n")) ==
EOF) {
2N/A /* print stripe and interlace */ 2N/A " Stripe %u: (interlace: %lld blocks)\n"),
2N/A /* print components appropriately */ 2N/A /* add extra line */ 2N/A /* cleanup, return error */ 2N/A /* should have same set */ 2N/A /* print all stripes */ 2N/A /* cleanup, return success */ 2N/A /* get unit structure */ 2N/A /* check for parented */ 2N/A /* print appropriate detail */ 2N/A /* Recurse on components that are metadevices */ 2N/A /* look for components that are metadevices */ 2N/A * find stripe component to replace 2N/A * Try to find the first erred component. 2N/A * If there is not one, then look for the 2N/A * first last_erred component. 2N/A /* return component */ 2N/A /* return success */ 2N/A * invalidate component names 2N/A * attach components to stripe 2N/A /* should have a set */ 2N/A /* check and count components */ 2N/A /* check against existing devices */ 2N/A /* check against ourselves */ 2N/A /* if zero, inherit the last rows interlace value */ 2N/A * calculate size of new unit structure 2N/A /* number of new components being added */ 2N/A /* count the # of components in the old unit */ 2N/A /* allocate new unit */ 2N/A /* compute new data */ 2N/A /* for each new device */ 2N/A /* figure out how big */ 2N/A /* adjust for smallest disk */ 2N/A /* get worst reinstructs */ 2N/A /* In dryrun mode (DOIT not set) we must not alter the mddb */ 2N/A /* store name in namespace */ 2N/A /* build new component */ 2N/A /* compute new size */ 2N/A "unit size overflow, limit is %lld blocks\n"),
2N/A /* adjust geometry */ 2N/A /* if in dryrun mode, we are done here. */ 2N/A "%s: attaching component would suceed\n"),
2N/A "%s: attaching components would suceed\n"),
2N/A /* grow any parents */ 2N/A /* cleanup, return error */ 2N/A * get stripe parameters 2N/A /* should have a set */ 2N/A /* return parameters */ 2N/A * set stripe parameters 2N/A /* should have a set */ 2N/A /* set parameters */ 2N/A /* return success */ 2N/A * check for dups in the stripe itself 2N/A for (r = 0; (r <=
row); ++r) {
2N/A for (c = 0; (c < e); ++c) {
2N/A * default stripe interlace 2N/A /* default to 512k, round up if necessary */ 2N/A * convert interlaces 2N/A /* compute default interlace */ 2N/A /* check interlace */ 2N/A /* check components */ 2N/A /* check component */ 2N/A /* check this stripe too */ 2N/A /* check hotspare pool name */ 2N/A /* return success */ 2N/A * setup stripe geometry 2N/A /* get worst reinstructs */ 2N/A * Figure out if the first component is a softpartition as the 2N/A * truncation check only occurs on them. 2N/A * If the stripe is to be multi-terabyte we should 2N/A * use EFI geometries, else we can get rounding errors 2N/A * in meta_setup_geom(). 2N/A /* setup geometry from first device */ 2N/A * Here we want to make sure that any truncation did not 2N/A * result in lost data (or, more appropriately, inaccessible 2N/A * This is mainly a danger for (1, 1) concats, but it is 2N/A * mathematically possible for other somewhat contrived 2N/A * arrangements where in the sum of the lengths of each row 2N/A * beyond the first is smaller than the cylinder size of the 2N/A * only component in the first row. 2N/A * It is tempting to simply test for truncation here, by 2N/A * (md->c.un_total_blocks < md->c.un_actual_tb). That does 2N/A * not tell us, however, if rounding resulted in data loss, 2N/A * rather only that it occurred. The somewhat less obvious 2N/A * test below covers both the obvious (1, 1) case and the 2N/A * aforementioned corner case. 2N/A * The only difference here is the text of the error 2N/A * message, since the remediation is slightly 2N/A * different in the one-component versus 2N/A * multiple-component cases. 2N/A * By the size comparison above and the initialization 2N/A * of buf[] in terms of ULLONG_MAX, we guarantee that 2N/A * the value arg is non-negative and that we won't 2N/A * overflow the container. 2N/A /* return success */ 2N/A /* validate stripe */ 2N/A /* allocate stripe unit */ 2N/A /* setup component count and offfset */ 2N/A * get start and size 2N/A * if first component is labelled, include label 2N/A /* make sure we still have something left */ 2N/A * round down by interlace: this only applies 2N/A * if this row is a stripe, as indicated by 2N/A * adjust for smallest disk: for a concat (any 2N/A * row with only one component), this will 2N/A * never hit the second conditional. 2N/A /* store name in namespace */ 2N/A /* setup component */ 2N/A "unit size overflow, limit is %lld blocks\n"),
2N/A /* fill in the size of the stripe */ 2N/A * If the device is being truncated then only allow this 2N/A * if the user is aware (using the -f option) or they 2N/A"%s: WARNING: This form of metainit is not recommended.\n" 2N/A"The stripe is truncating the size of the underlying device.\n" 2N/A"Please see ERRORS in metainit(1M) for additional information.\n"),
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 stripe name */ 2N/A /* see if it exists already */ 2N/A /* parse general options */ 2N/A /* allocate stripe */ 2N/A /* allocate and parse rows */ 2N/A /* allocate and parse components */ 2N/A /* parse component name */ 2N/A /* check for soft partition */ 2N/A /* parse row options */ 2N/A /* parse stripe options */ 2N/A * Get out if the specified hotspare pool really 2N/A /* we should be at the end */ 2N/A /* cleanup, return error */ 2N/A /* should have same set */ 2N/A /* reset all stripes */ 2N/A /* for each stripe */ 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 /* only recurse on metadevices */ 2N/A /* cleanup, return success */ 2N/A * reports TRUE if any stripe component is in error 2N/A /* get count of underlying devices */ 2N/A * Now get the data from the unit structure. 2N/A * The compnamep stuff contains the data from 2N/A * the namespace and we need the un_dev 2N/A * from the unit structure. 2N/A /* Get the devname from the name space. */ 2N/A * The minor numbers are different. 2N/A * Update the namespace with the 2N/A * information from the component. 2N/A }
/* End of if (mydevs == mydev[i]) */ 2N/A }
/* End of second for loop */ 2N/A }
/* End of first for loop */