1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate /* 24*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*0Sstevel@tonic-gate * Use is subject to license terms. 26*0Sstevel@tonic-gate */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * initialize metadevices 32*0Sstevel@tonic-gate */ 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate #include <meta.h> 35*0Sstevel@tonic-gate #include <libdevinfo.h> 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate int 39*0Sstevel@tonic-gate parse_interlace( 40*0Sstevel@tonic-gate char *uname, /* Meta Device name (eg d0) */ 41*0Sstevel@tonic-gate char *str, /* String to Parse */ 42*0Sstevel@tonic-gate diskaddr_t *interlacep, 43*0Sstevel@tonic-gate md_error_t *ep 44*0Sstevel@tonic-gate ) 45*0Sstevel@tonic-gate { 46*0Sstevel@tonic-gate diskaddr_t num; 47*0Sstevel@tonic-gate char c; 48*0Sstevel@tonic-gate int cnt; 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate /* parse interlace */ 51*0Sstevel@tonic-gate if ((cnt = sscanf(str, "%llu%c", &num, &c)) < 1) { 52*0Sstevel@tonic-gate return (meta_cook_syntax(ep, MDE_BAD_INTERLACE, 53*0Sstevel@tonic-gate uname, 1, &str)); 54*0Sstevel@tonic-gate } else if (cnt == 1) { 55*0Sstevel@tonic-gate if (num & (DEV_BSIZE - 1)) { 56*0Sstevel@tonic-gate return (meta_cook_syntax(ep, MDE_BAD_INTERLACE, 57*0Sstevel@tonic-gate uname, 1, &str)); 58*0Sstevel@tonic-gate } 59*0Sstevel@tonic-gate num = lbtodb(num); 60*0Sstevel@tonic-gate } else switch (c) { 61*0Sstevel@tonic-gate case 'b': 62*0Sstevel@tonic-gate case 'B': 63*0Sstevel@tonic-gate num *= DEV_BSIZE / DEV_BSIZE; 64*0Sstevel@tonic-gate break; 65*0Sstevel@tonic-gate case 'k': 66*0Sstevel@tonic-gate case 'K': 67*0Sstevel@tonic-gate num *= 1024 / DEV_BSIZE; 68*0Sstevel@tonic-gate break; 69*0Sstevel@tonic-gate case 'm': 70*0Sstevel@tonic-gate case 'M': 71*0Sstevel@tonic-gate num *= 1024 * 1024 / DEV_BSIZE; 72*0Sstevel@tonic-gate break; 73*0Sstevel@tonic-gate default: 74*0Sstevel@tonic-gate return (meta_cook_syntax(ep, MDE_BAD_INTERLACE, 75*0Sstevel@tonic-gate NULL, 1, &str)); 76*0Sstevel@tonic-gate } 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate /* return success */ 79*0Sstevel@tonic-gate *interlacep = num; 80*0Sstevel@tonic-gate return (0); 81*0Sstevel@tonic-gate } 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate /* 84*0Sstevel@tonic-gate * cook up syntax error 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate int 87*0Sstevel@tonic-gate meta_cook_syntax( 88*0Sstevel@tonic-gate md_error_t *ep, 89*0Sstevel@tonic-gate md_void_errno_t errcode, 90*0Sstevel@tonic-gate char *uname, 91*0Sstevel@tonic-gate int argc, 92*0Sstevel@tonic-gate char *argv[] 93*0Sstevel@tonic-gate ) 94*0Sstevel@tonic-gate { 95*0Sstevel@tonic-gate int rval; 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate /* if we have a token, concat it to uname */ 98*0Sstevel@tonic-gate if ((argc > 0) && (argv[0] != NULL) && (argv[0][0] != '\0')) { 99*0Sstevel@tonic-gate char *p; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate if ((uname != NULL) && (uname[0] != '\0')) { 102*0Sstevel@tonic-gate p = Malloc(strlen(uname) + 2 103*0Sstevel@tonic-gate + 1 + strlen(argv[0]) + 1 + 1); 104*0Sstevel@tonic-gate (void) strcpy(p, uname); 105*0Sstevel@tonic-gate (void) strcat(p, ": "); 106*0Sstevel@tonic-gate } else { 107*0Sstevel@tonic-gate p = Malloc(1 + strlen(argv[0]) + 1 + 1); 108*0Sstevel@tonic-gate p[0] = '\0'; 109*0Sstevel@tonic-gate } 110*0Sstevel@tonic-gate (void) strcat(p, "\""); 111*0Sstevel@tonic-gate (void) strcat(p, argv[0]); 112*0Sstevel@tonic-gate (void) strcat(p, "\""); 113*0Sstevel@tonic-gate rval = mderror(ep, errcode, p); 114*0Sstevel@tonic-gate Free(p); 115*0Sstevel@tonic-gate } else { 116*0Sstevel@tonic-gate rval = mderror(ep, errcode, uname); 117*0Sstevel@tonic-gate } 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate return (rval); 120*0Sstevel@tonic-gate } 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate int 123*0Sstevel@tonic-gate meta_check_devicesize( 124*0Sstevel@tonic-gate diskaddr_t total_blocks 125*0Sstevel@tonic-gate ) 126*0Sstevel@tonic-gate { 127*0Sstevel@tonic-gate int rval = MD_CRO_32BIT; 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate if (total_blocks > MD_MAX_BLKS_FOR_SMALL_DEVS) { 131*0Sstevel@tonic-gate rval = MD_CRO_64BIT; 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate return (rval); 134*0Sstevel@tonic-gate } 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate /* 138*0Sstevel@tonic-gate * setup metadevice geometry 139*0Sstevel@tonic-gate */ 140*0Sstevel@tonic-gate /*ARGSUSED*/ 141*0Sstevel@tonic-gate int 142*0Sstevel@tonic-gate meta_setup_geom( 143*0Sstevel@tonic-gate md_unit_t *md, 144*0Sstevel@tonic-gate mdname_t *np, 145*0Sstevel@tonic-gate mdgeom_t *geomp, 146*0Sstevel@tonic-gate uint_t write_reinstruct, 147*0Sstevel@tonic-gate uint_t read_reinstruct, 148*0Sstevel@tonic-gate uint_t round_cyl, 149*0Sstevel@tonic-gate md_error_t *ep 150*0Sstevel@tonic-gate ) 151*0Sstevel@tonic-gate { 152*0Sstevel@tonic-gate diskaddr_t cylsize = geomp->nhead * geomp->nsect; 153*0Sstevel@tonic-gate diskaddr_t total_blocks; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate if (round_cyl) { 156*0Sstevel@tonic-gate total_blocks = rounddown(md->c.un_actual_tb, cylsize); 157*0Sstevel@tonic-gate } else { 158*0Sstevel@tonic-gate total_blocks = md->c.un_actual_tb; 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate md->c.un_total_blocks = total_blocks; 162*0Sstevel@tonic-gate md->c.un_nhead = geomp->nhead; 163*0Sstevel@tonic-gate md->c.un_nsect = geomp->nsect; 164*0Sstevel@tonic-gate md->c.un_rpm = geomp->rpm; 165*0Sstevel@tonic-gate md->c.un_wr_reinstruct = write_reinstruct; 166*0Sstevel@tonic-gate md->c.un_rd_reinstruct = read_reinstruct; 167*0Sstevel@tonic-gate return (0); 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate /* 171*0Sstevel@tonic-gate * adjust metadevice geometry 172*0Sstevel@tonic-gate */ 173*0Sstevel@tonic-gate /*ARGSUSED*/ 174*0Sstevel@tonic-gate int 175*0Sstevel@tonic-gate meta_adjust_geom( 176*0Sstevel@tonic-gate md_unit_t *md, 177*0Sstevel@tonic-gate mdname_t *np, 178*0Sstevel@tonic-gate uint_t write_reinstruct, 179*0Sstevel@tonic-gate uint_t read_reinstruct, 180*0Sstevel@tonic-gate uint_t round_cyl, 181*0Sstevel@tonic-gate md_error_t *ep 182*0Sstevel@tonic-gate ) 183*0Sstevel@tonic-gate { 184*0Sstevel@tonic-gate diskaddr_t cylsize = md->c.un_nhead * md->c.un_nsect; 185*0Sstevel@tonic-gate diskaddr_t total_blocks; 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate if (round_cyl) { 188*0Sstevel@tonic-gate total_blocks = rounddown(md->c.un_actual_tb, cylsize); 189*0Sstevel@tonic-gate } else { 190*0Sstevel@tonic-gate total_blocks = md->c.un_actual_tb; 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate md->c.un_total_blocks = total_blocks; 194*0Sstevel@tonic-gate if (write_reinstruct > md->c.un_wr_reinstruct) 195*0Sstevel@tonic-gate md->c.un_wr_reinstruct = write_reinstruct; 196*0Sstevel@tonic-gate if (read_reinstruct > md->c.un_rd_reinstruct) 197*0Sstevel@tonic-gate md->c.un_rd_reinstruct = read_reinstruct; 198*0Sstevel@tonic-gate return (0); 199*0Sstevel@tonic-gate } 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate /* 202*0Sstevel@tonic-gate * Function: meta_init_make_device 203*0Sstevel@tonic-gate * Purpose: 204*0Sstevel@tonic-gate * Create the device node <uname> by constructing the necessary 205*0Sstevel@tonic-gate * md_mkdev_params_t structure. We have to handle relative names 206*0Sstevel@tonic-gate * (e.g. "d80") and fully-qualified names (e.g. "/dev/md/red/dsk/d80"). 207*0Sstevel@tonic-gate * The field that we need is the unit number of the metadevice (80 in 208*0Sstevel@tonic-gate * the above examples). 209*0Sstevel@tonic-gate * Input: spp set structure 210*0Sstevel@tonic-gate * uname unit-name (fully qualified or relative) 211*0Sstevel@tonic-gate * Output: ep error return structure 212*0Sstevel@tonic-gate * Returns: 0 success 213*0Sstevel@tonic-gate * -1 Error. <ep> contains error reason 214*0Sstevel@tonic-gate */ 215*0Sstevel@tonic-gate int 216*0Sstevel@tonic-gate meta_init_make_device( 217*0Sstevel@tonic-gate mdsetname_t **spp, 218*0Sstevel@tonic-gate char *uname, 219*0Sstevel@tonic-gate md_error_t *ep 220*0Sstevel@tonic-gate ) 221*0Sstevel@tonic-gate { 222*0Sstevel@tonic-gate di_devlink_handle_t hdl; 223*0Sstevel@tonic-gate md_mkdev_params_t params; 224*0Sstevel@tonic-gate int rval = 0; 225*0Sstevel@tonic-gate char *p, *e = uname; 226*0Sstevel@tonic-gate size_t len = strlen(uname); 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate e += len; 229*0Sstevel@tonic-gate (void) memset(¶ms, 0, sizeof (params)); 230*0Sstevel@tonic-gate MD_SETDRIVERNAME(¶ms, "md", (*spp)->setno); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate /* 233*0Sstevel@tonic-gate * Find the start of the unit within <uname>. 234*0Sstevel@tonic-gate */ 235*0Sstevel@tonic-gate p = strrchr(uname, '/'); 236*0Sstevel@tonic-gate if (p == NULL) { 237*0Sstevel@tonic-gate /* Relative name (e.g. d80) */ 238*0Sstevel@tonic-gate p = &uname[1]; 239*0Sstevel@tonic-gate } else { 240*0Sstevel@tonic-gate /* qualified name (e.g. /dev/md/dsk/d80) */ 241*0Sstevel@tonic-gate p += 2; 242*0Sstevel@tonic-gate if (p >= e) { 243*0Sstevel@tonic-gate /* Invalid drive name */ 244*0Sstevel@tonic-gate p = Malloc(len + 3); 245*0Sstevel@tonic-gate (void) snprintf(p, len + 3, "\"%s\"", uname); 246*0Sstevel@tonic-gate rval = mderror(ep, MDE_NOT_DRIVENAME, p); 247*0Sstevel@tonic-gate Free(p); 248*0Sstevel@tonic-gate return (rval); 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate e = NULL; 252*0Sstevel@tonic-gate params.mnum = strtoul(p, &e, 10); 253*0Sstevel@tonic-gate if (e == p) { 254*0Sstevel@tonic-gate /* Invalid drive name */ 255*0Sstevel@tonic-gate p = Malloc(len + 3); 256*0Sstevel@tonic-gate (void) snprintf(p, len + 3, "\"%s\"", uname); 257*0Sstevel@tonic-gate rval = mderror(ep, MDE_NOT_DRIVENAME, p); 258*0Sstevel@tonic-gate Free(p); 259*0Sstevel@tonic-gate return (rval); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate if (metaioctl(MD_IOCMAKE_DEV, ¶ms, ¶ms.mde, NULL) != 0) { 263*0Sstevel@tonic-gate return (mdstealerror(ep, ¶ms.mde)); 264*0Sstevel@tonic-gate } 265*0Sstevel@tonic-gate /* 266*0Sstevel@tonic-gate * Wait until device appears in namespace. di_devlink_init() returns 267*0Sstevel@tonic-gate * once the /dev links have been created. If NULL is returned the 268*0Sstevel@tonic-gate * link operation failed and we haven't got a device to use. 269*0Sstevel@tonic-gate * NOTE: This will take a _long_ time for large numbers of metadevices. 270*0Sstevel@tonic-gate * Change to use the enhanced di_devlink_init() interface when 271*0Sstevel@tonic-gate * available. 272*0Sstevel@tonic-gate */ 273*0Sstevel@tonic-gate hdl = di_devlink_init("md", DI_MAKE_LINK); 274*0Sstevel@tonic-gate if (hdl != NULL) { 275*0Sstevel@tonic-gate (void) di_devlink_fini(&hdl); 276*0Sstevel@tonic-gate } else { 277*0Sstevel@tonic-gate p = Malloc(len + 3); 278*0Sstevel@tonic-gate (void) snprintf(p, len + 3, "\"%s\"", uname); 279*0Sstevel@tonic-gate rval = mderror(ep, MDE_UNIT_NOT_FOUND, p); 280*0Sstevel@tonic-gate Free(p); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate return (rval); 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate /* 286*0Sstevel@tonic-gate * FUNCTION: is_metadb_cmd() 287*0Sstevel@tonic-gate * INPUT: argc - number of command line arguments 288*0Sstevel@tonic-gate * argv - pointer to array of command line arguments 289*0Sstevel@tonic-gate * OUTPUT: none 290*0Sstevel@tonic-gate * RETURNS: TRUE if a metadb is to be created, FALSE otherwise 291*0Sstevel@tonic-gate * PURPOSE: parses enough of the command line to determine if a metadb 292*0Sstevel@tonic-gate * create is being attempted 293*0Sstevel@tonic-gate */ 294*0Sstevel@tonic-gate static boolean_t 295*0Sstevel@tonic-gate is_metadb_cmd( 296*0Sstevel@tonic-gate int argc, 297*0Sstevel@tonic-gate char *argv[] 298*0Sstevel@tonic-gate ) 299*0Sstevel@tonic-gate { 300*0Sstevel@tonic-gate ulong_t num; 301*0Sstevel@tonic-gate int len; 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate /* look for match */ 304*0Sstevel@tonic-gate if (argc > 0 && (sscanf(argv[0], "mddb%lu%n", &num, &len) == 1) && 305*0Sstevel@tonic-gate (strlen(argv[0]) == len) && ((long)num >= 0)) { 306*0Sstevel@tonic-gate return (B_TRUE); 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate return (B_FALSE); 310*0Sstevel@tonic-gate } 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate /* 313*0Sstevel@tonic-gate * FUNCTION: is_stripe_cmd() 314*0Sstevel@tonic-gate * INPUT: argc - number of command line arguments 315*0Sstevel@tonic-gate * argv - pointer to array of command line arguments 316*0Sstevel@tonic-gate * OUTPUT: none 317*0Sstevel@tonic-gate * RETURNS: TRUE if a stripe is to be created, FALSE otherwise 318*0Sstevel@tonic-gate * PURPOSE: parses enough of the command line to determine if a stripe 319*0Sstevel@tonic-gate * create is being attempted 320*0Sstevel@tonic-gate */ 321*0Sstevel@tonic-gate static boolean_t 322*0Sstevel@tonic-gate is_stripe_cmd( 323*0Sstevel@tonic-gate int argc, 324*0Sstevel@tonic-gate char *argv[] 325*0Sstevel@tonic-gate ) 326*0Sstevel@tonic-gate { 327*0Sstevel@tonic-gate uint_t nrow; 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate if (argc > 1 && (sscanf(argv[1], "%u", &nrow) != 1) || ((int)nrow < 0)) 330*0Sstevel@tonic-gate return (B_FALSE); 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate return (B_TRUE); 333*0Sstevel@tonic-gate } 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate /* 336*0Sstevel@tonic-gate * FUNCTION: meta_get_init_type() 337*0Sstevel@tonic-gate * INPUT: argc - number of command line arguments 338*0Sstevel@tonic-gate * argv - pointer to array of command line arguments 339*0Sstevel@tonic-gate * OUTPUT: none 340*0Sstevel@tonic-gate * RETURNS: type of metadevice or hot spare pools being initialized 341*0Sstevel@tonic-gate * PURPOSE: parses enough of the command line to determine what type 342*0Sstevel@tonic-gate * of metainit is being attempted 343*0Sstevel@tonic-gate */ 344*0Sstevel@tonic-gate mdinittypes_t 345*0Sstevel@tonic-gate meta_get_init_type( 346*0Sstevel@tonic-gate int argc, 347*0Sstevel@tonic-gate char *argv[] 348*0Sstevel@tonic-gate ) 349*0Sstevel@tonic-gate { 350*0Sstevel@tonic-gate char *arg = argv[1]; 351*0Sstevel@tonic-gate mdinittypes_t init_type; 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate if (argc == 1) /* must be a hot spare pool w/o devices */ 354*0Sstevel@tonic-gate return (TAB_HSP); 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate init_type = TAB_UNKNOWN; 357*0Sstevel@tonic-gate if (arg != NULL) { 358*0Sstevel@tonic-gate if (strcmp(arg, "-m") == 0) { 359*0Sstevel@tonic-gate init_type = TAB_MIRROR; 360*0Sstevel@tonic-gate } else if (strcmp(arg, "-r") == 0) { 361*0Sstevel@tonic-gate init_type = TAB_RAID; 362*0Sstevel@tonic-gate } else if (strcmp(arg, "-p") == 0) { 363*0Sstevel@tonic-gate init_type = TAB_SP; 364*0Sstevel@tonic-gate } else if (strcmp(arg, "-t") == 0) { 365*0Sstevel@tonic-gate init_type = TAB_TRANS; 366*0Sstevel@tonic-gate } else if (is_metadb_cmd(argc, argv)) { 367*0Sstevel@tonic-gate init_type = TAB_MDDB; 368*0Sstevel@tonic-gate } else if (is_stripe_cmd(argc, argv)) { 369*0Sstevel@tonic-gate init_type = TAB_STRIPE; 370*0Sstevel@tonic-gate } else { /* assume that it is a hsp */ 371*0Sstevel@tonic-gate init_type = TAB_HSP; 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate return (init_type); 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate /* 378*0Sstevel@tonic-gate * initialize named device or hotspare pool 379*0Sstevel@tonic-gate */ 380*0Sstevel@tonic-gate int 381*0Sstevel@tonic-gate meta_init_name( 382*0Sstevel@tonic-gate mdsetname_t **spp, 383*0Sstevel@tonic-gate int argc, 384*0Sstevel@tonic-gate char *argv[], 385*0Sstevel@tonic-gate mdcmdopts_t options, 386*0Sstevel@tonic-gate md_error_t *ep 387*0Sstevel@tonic-gate ) 388*0Sstevel@tonic-gate { 389*0Sstevel@tonic-gate mdinittypes_t init_type; 390*0Sstevel@tonic-gate char *p; 391*0Sstevel@tonic-gate int rval; 392*0Sstevel@tonic-gate char *uname = argv[0]; 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate assert(argc > 0); 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate /* determine type of metadevice or hot spare pool being created */ 397*0Sstevel@tonic-gate init_type = meta_get_init_type(argc, argv); 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate /* hotspare pool */ 400*0Sstevel@tonic-gate if (init_type == TAB_HSP) 401*0Sstevel@tonic-gate return (meta_init_hsp(spp, argc, argv, options, ep)); 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate /* metadevice */ 404*0Sstevel@tonic-gate if (argc >= 2 && init_type != TAB_UNKNOWN) { 405*0Sstevel@tonic-gate md_error_t t_e = mdnullerror; 406*0Sstevel@tonic-gate char *cname; 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate /* 409*0Sstevel@tonic-gate * We need to create the device node if the specified metadevice 410*0Sstevel@tonic-gate * does not already exist in the database. The actual creation 411*0Sstevel@tonic-gate * is undertaken by the md driver and the links propagated by 412*0Sstevel@tonic-gate * devfsadm. 413*0Sstevel@tonic-gate */ 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate /* initialize the spp properly */ 416*0Sstevel@tonic-gate if ((cname = meta_name_getname(spp, uname, &t_e)) != NULL) 417*0Sstevel@tonic-gate Free(cname); 418*0Sstevel@tonic-gate if (! mdisok(&t_e)) 419*0Sstevel@tonic-gate return (mdstealerror(ep, &t_e)); 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate /* Create device node */ 422*0Sstevel@tonic-gate if (meta_init_make_device(spp, uname, &t_e) != 0) { 423*0Sstevel@tonic-gate return (mdstealerror(ep, &t_e)); 424*0Sstevel@tonic-gate } 425*0Sstevel@tonic-gate 426*0Sstevel@tonic-gate switch (init_type) { 427*0Sstevel@tonic-gate case TAB_MIRROR: 428*0Sstevel@tonic-gate return (meta_init_mirror(spp, argc, argv, options, ep)); 429*0Sstevel@tonic-gate break; 430*0Sstevel@tonic-gate case TAB_RAID: 431*0Sstevel@tonic-gate return (meta_init_raid(spp, argc, argv, options, ep)); 432*0Sstevel@tonic-gate break; 433*0Sstevel@tonic-gate case TAB_SP: 434*0Sstevel@tonic-gate return (meta_init_sp(spp, argc, argv, options, ep)); 435*0Sstevel@tonic-gate break; 436*0Sstevel@tonic-gate case TAB_TRANS: 437*0Sstevel@tonic-gate return (mderror(ep, MDE_EOF_TRANS, NULL)); 438*0Sstevel@tonic-gate break; 439*0Sstevel@tonic-gate case TAB_STRIPE: 440*0Sstevel@tonic-gate return (meta_init_stripe(spp, argc, argv, options, ep)); 441*0Sstevel@tonic-gate break; 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate /* unknown type */ 446*0Sstevel@tonic-gate p = Malloc(1 + strlen(uname) + 1 + 1); 447*0Sstevel@tonic-gate (void) strcpy(p, "\""); 448*0Sstevel@tonic-gate (void) strcat(p, uname); 449*0Sstevel@tonic-gate (void) strcat(p, "\""); 450*0Sstevel@tonic-gate rval = mderror(ep, MDE_SYNTAX, p); 451*0Sstevel@tonic-gate Free(p); 452*0Sstevel@tonic-gate return (rval); 453*0Sstevel@tonic-gate } 454