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 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <stdio.h> 30*0Sstevel@tonic-gate #include <stdarg.h> 31*0Sstevel@tonic-gate #include <ctype.h> 32*0Sstevel@tonic-gate #include <sys/fcntl.h> 33*0Sstevel@tonic-gate #include <sys/types.h> 34*0Sstevel@tonic-gate #include <devid.h> 35*0Sstevel@tonic-gate #include <ftw.h> 36*0Sstevel@tonic-gate #include <string.h> 37*0Sstevel@tonic-gate #include <mdiox.h> 38*0Sstevel@tonic-gate #include <sys/lvm/mdio.h> 39*0Sstevel@tonic-gate #include <meta.h> 40*0Sstevel@tonic-gate #include <syslog.h> 41*0Sstevel@tonic-gate #include <sdssc.h> 42*0Sstevel@tonic-gate #include "meta_set_prv.h" 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate /* 45*0Sstevel@tonic-gate * Just in case we're not in a build environment, make sure that 46*0Sstevel@tonic-gate * TEXT_DOMAIN gets set to something. 47*0Sstevel@tonic-gate */ 48*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 49*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 50*0Sstevel@tonic-gate #endif 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate #define RAW_PATH 0x001 /* rdsk */ 53*0Sstevel@tonic-gate #define BLOCK_PATH 0x002 /* dsk */ 54*0Sstevel@tonic-gate #define DSK_TYPE 0x004 /* normal /dev/[r]dsk */ 55*0Sstevel@tonic-gate #define TEST_TYPE 0x008 /* test driver path */ 56*0Sstevel@tonic-gate #define DID_TYPE 0x010 /* cluster did path */ 57*0Sstevel@tonic-gate #define AP_TYPE 0x020 /* should be obsolete */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate typedef struct path_list { 60*0Sstevel@tonic-gate char *search_path; 61*0Sstevel@tonic-gate char *search_type; 62*0Sstevel@tonic-gate int path_type; 63*0Sstevel@tonic-gate } path_list_t; 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate /* 66*0Sstevel@tonic-gate * A table of the supported path types - this should ideally be generated 67*0Sstevel@tonic-gate * by reading the /etc/lvm/devpath file 68*0Sstevel@tonic-gate */ 69*0Sstevel@tonic-gate static path_list_t plist[] = { 70*0Sstevel@tonic-gate {"/dev/rdsk", DEVID_MINOR_NAME_ALL_CHR, RAW_PATH|DSK_TYPE}, 71*0Sstevel@tonic-gate {"/dev/dsk", DEVID_MINOR_NAME_ALL_BLK, BLOCK_PATH|DSK_TYPE}, 72*0Sstevel@tonic-gate {"/dev/did/rdsk", DEVID_MINOR_NAME_ALL_CHR, RAW_PATH|DID_TYPE}, 73*0Sstevel@tonic-gate {"/dev/did/dsk", DEVID_MINOR_NAME_ALL_BLK, BLOCK_PATH|DID_TYPE}, 74*0Sstevel@tonic-gate {"/dev/td/dsk", DEVID_MINOR_NAME_ALL_BLK, BLOCK_PATH|TEST_TYPE}, 75*0Sstevel@tonic-gate {"/dev/td/rdsk", DEVID_MINOR_NAME_ALL_CHR, RAW_PATH|TEST_TYPE}, 76*0Sstevel@tonic-gate }; 77*0Sstevel@tonic-gate static int num = sizeof (plist)/sizeof (path_list_t); 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate static mddevopts_t dev_options = 0; 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate /* indicate whether to print an error message or not */ 82*0Sstevel@tonic-gate static int firsttime = 1; 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate #define DEV_MATCH 0x1 85*0Sstevel@tonic-gate #define NAME_MATCH 0x2 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate #define DEBUGON 1 88*0Sstevel@tonic-gate #define DEBUGOFF 2 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate /* 91*0Sstevel@tonic-gate * Debug function: to turn on devadm function debugging include DEVADM 92*0Sstevel@tonic-gate * in the MD_DEBUG enviroment variable: MD_DEBUG=...,DEVADM... 93*0Sstevel@tonic-gate */ 94*0Sstevel@tonic-gate /*PRINTFLIKE1*/ 95*0Sstevel@tonic-gate static void 96*0Sstevel@tonic-gate mda_debug(char *format, ...) 97*0Sstevel@tonic-gate { 98*0Sstevel@tonic-gate char *p; 99*0Sstevel@tonic-gate static int debug_set = 0; 100*0Sstevel@tonic-gate va_list ap; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate if (debug_set == 0) { 103*0Sstevel@tonic-gate if (((p = getenv("MD_DEBUG")) != NULL) && 104*0Sstevel@tonic-gate (strstr(p, "DEVADM") != NULL)) 105*0Sstevel@tonic-gate debug_set = DEBUGON; 106*0Sstevel@tonic-gate else 107*0Sstevel@tonic-gate debug_set = DEBUGOFF; 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate if (debug_set == DEBUGON) { 110*0Sstevel@tonic-gate va_start(ap, format); 111*0Sstevel@tonic-gate (void) vfprintf(stderr, format, ap); 112*0Sstevel@tonic-gate va_end(ap); 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* print error messages to the terminal or syslog */ 117*0Sstevel@tonic-gate /*PRINTFLIKE1*/ 118*0Sstevel@tonic-gate static void 119*0Sstevel@tonic-gate mda_print(char *message, ...) 120*0Sstevel@tonic-gate { 121*0Sstevel@tonic-gate va_list ap; 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate va_start(ap, message); 124*0Sstevel@tonic-gate if (dev_options & DEV_LOG) { 125*0Sstevel@tonic-gate /* 126*0Sstevel@tonic-gate * The program is a daemon in the sense that it 127*0Sstevel@tonic-gate * is a system utility. 128*0Sstevel@tonic-gate */ 129*0Sstevel@tonic-gate (void) vsyslog((LOG_ERR | LOG_DAEMON), message, ap); 130*0Sstevel@tonic-gate } else { 131*0Sstevel@tonic-gate (void) vfprintf(stderr, message, ap); 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate va_end(ap); 134*0Sstevel@tonic-gate } 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate /* 137*0Sstevel@tonic-gate * Utility to find the correct options to use for the devid search 138*0Sstevel@tonic-gate * based upon the path of the device. 139*0Sstevel@tonic-gate * 140*0Sstevel@tonic-gate * RETURN: 141*0Sstevel@tonic-gate * -1 Error, the path passed in is not in the table 142*0Sstevel@tonic-gate * >= 0 The element number for the options within the table 143*0Sstevel@tonic-gate */ 144*0Sstevel@tonic-gate static int 145*0Sstevel@tonic-gate mda_findpath(char *path) 146*0Sstevel@tonic-gate { 147*0Sstevel@tonic-gate int i = 0; 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate for (i = 0; i < num; i++) { 150*0Sstevel@tonic-gate if (strncmp(plist[i].search_path, path, 151*0Sstevel@tonic-gate strlen(plist[i].search_path)) == 0) 152*0Sstevel@tonic-gate return (i); 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate return (-1); 155*0Sstevel@tonic-gate } 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate /* 158*0Sstevel@tonic-gate * Utility to get the path of a device 159*0Sstevel@tonic-gate */ 160*0Sstevel@tonic-gate static char * 161*0Sstevel@tonic-gate mda_getpath(char *devname) 162*0Sstevel@tonic-gate { 163*0Sstevel@tonic-gate char *ptr; 164*0Sstevel@tonic-gate char *pathname; 165*0Sstevel@tonic-gate size_t len; 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate if ((ptr = strrchr(devname, '/')) == NULL) { 168*0Sstevel@tonic-gate mda_debug("Invalid format: %s\n", devname); 169*0Sstevel@tonic-gate return (NULL); 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate ptr++; 172*0Sstevel@tonic-gate len = strlen(devname) - strlen(ptr); 173*0Sstevel@tonic-gate pathname = Malloc(len + 1); 174*0Sstevel@tonic-gate (void) strncpy(pathname, devname, len); 175*0Sstevel@tonic-gate pathname[len] = '\0'; 176*0Sstevel@tonic-gate return (pathname); 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate /* 180*0Sstevel@tonic-gate * update_locator_namespace -- Contains the ioctl call that will update 181*0Sstevel@tonic-gate * the ctds and pathname (ie. /dev/dsk etc) within the 182*0Sstevel@tonic-gate * locator block namespace. 183*0Sstevel@tonic-gate * 184*0Sstevel@tonic-gate * RETURN 185*0Sstevel@tonic-gate * METADEVADM_ERR ioctl failed and ep is updated with the error 186*0Sstevel@tonic-gate * METADEVADM_SUCCESS success 187*0Sstevel@tonic-gate */ 188*0Sstevel@tonic-gate static int 189*0Sstevel@tonic-gate update_locator_namespace( 190*0Sstevel@tonic-gate set_t setno, 191*0Sstevel@tonic-gate side_t sideno, 192*0Sstevel@tonic-gate char *devname, 193*0Sstevel@tonic-gate md_dev64_t dev, 194*0Sstevel@tonic-gate char *pname, 195*0Sstevel@tonic-gate md_error_t *ep 196*0Sstevel@tonic-gate ) 197*0Sstevel@tonic-gate { 198*0Sstevel@tonic-gate mdnm_params_t nm; 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm)); 201*0Sstevel@tonic-gate nm.mde = mdnullerror; 202*0Sstevel@tonic-gate nm.setno = setno; 203*0Sstevel@tonic-gate nm.side = sideno; 204*0Sstevel@tonic-gate nm.devname = (uintptr_t)devname; 205*0Sstevel@tonic-gate nm.devname_len = strlen(devname); 206*0Sstevel@tonic-gate nm.devt = dev; 207*0Sstevel@tonic-gate nm.pathname = (uintptr_t)pname; 208*0Sstevel@tonic-gate nm.pathname_len = strlen(pname); 209*0Sstevel@tonic-gate if (metaioctl(MD_IOCUPD_LOCNM, &nm, &nm.mde, NULL) != 0) { 210*0Sstevel@tonic-gate (void) mdstealerror(ep, &nm.mde); 211*0Sstevel@tonic-gate return (METADEVADM_ERR); 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate /* 217*0Sstevel@tonic-gate * update_namespace -- Contains the ioctl call that will update the 218*0Sstevel@tonic-gate * device name and pathname in the namespace area. 219*0Sstevel@tonic-gate * 220*0Sstevel@tonic-gate * RETURN 221*0Sstevel@tonic-gate * METADEVADM_ERR ioctl failed and ep is updated with the error 222*0Sstevel@tonic-gate * METADEVADM_SUCCESS success 223*0Sstevel@tonic-gate */ 224*0Sstevel@tonic-gate static int 225*0Sstevel@tonic-gate update_namespace( 226*0Sstevel@tonic-gate set_t setno, 227*0Sstevel@tonic-gate side_t sideno, 228*0Sstevel@tonic-gate char *devname, 229*0Sstevel@tonic-gate md_dev64_t dev, 230*0Sstevel@tonic-gate mdkey_t key, 231*0Sstevel@tonic-gate char *pname, 232*0Sstevel@tonic-gate md_error_t *ep 233*0Sstevel@tonic-gate ) 234*0Sstevel@tonic-gate { 235*0Sstevel@tonic-gate mdnm_params_t nm; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm)); 238*0Sstevel@tonic-gate nm.mde = mdnullerror; 239*0Sstevel@tonic-gate nm.setno = setno; 240*0Sstevel@tonic-gate nm.side = sideno; 241*0Sstevel@tonic-gate nm.devname = (uintptr_t)devname; 242*0Sstevel@tonic-gate nm.devname_len = strlen(devname); 243*0Sstevel@tonic-gate nm.mnum = meta_getminor(dev); 244*0Sstevel@tonic-gate nm.key = key; 245*0Sstevel@tonic-gate nm.pathname = (uintptr_t)pname; 246*0Sstevel@tonic-gate nm.pathname_len = strlen(pname); 247*0Sstevel@tonic-gate if (metaioctl(MD_IOCUPD_NM, &nm, &nm.mde, NULL) != 0) { 248*0Sstevel@tonic-gate (void) mdstealerror(ep, &nm.mde); 249*0Sstevel@tonic-gate return (METADEVADM_ERR); 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate /* 255*0Sstevel@tonic-gate * stripS - Strip s<digits> off the end of the ctds name if it exists 256*0Sstevel@tonic-gate */ 257*0Sstevel@tonic-gate static void 258*0Sstevel@tonic-gate stripS(char *name) 259*0Sstevel@tonic-gate { 260*0Sstevel@tonic-gate char *p; 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate /* gobble number and 's' */ 263*0Sstevel@tonic-gate p = name + strlen(name) - 1; 264*0Sstevel@tonic-gate for (; (p > name); --p) { 265*0Sstevel@tonic-gate if (!isdigit(*p)) 266*0Sstevel@tonic-gate break; 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate if (*p == 's') { 270*0Sstevel@tonic-gate *p = '\0'; 271*0Sstevel@tonic-gate } 272*0Sstevel@tonic-gate } 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate /* 275*0Sstevel@tonic-gate * getdiskname -- to be used when scanning the input from the -u arg. 276*0Sstevel@tonic-gate * This routine will strip off input that is anything but cxtxdx. 277*0Sstevel@tonic-gate * ie. it will call stripS to get rid of slice info. Will also 278*0Sstevel@tonic-gate * strip off /dev/dsk, /dev/rdsk, /dev/ap/dsk, /dev/ap/rdsk, 279*0Sstevel@tonic-gate * /dev/did/dsk, or /dev/did/rdsk. The caller will need to free 280*0Sstevel@tonic-gate * the return value. 281*0Sstevel@tonic-gate * 282*0Sstevel@tonic-gate * RETURN 283*0Sstevel@tonic-gate * string that has the disk name in it ie. c0t0d0 284*0Sstevel@tonic-gate */ 285*0Sstevel@tonic-gate static char * 286*0Sstevel@tonic-gate getdiskname( 287*0Sstevel@tonic-gate char *name 288*0Sstevel@tonic-gate ) 289*0Sstevel@tonic-gate { 290*0Sstevel@tonic-gate char *p; 291*0Sstevel@tonic-gate char *diskname; 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate /* regular device */ 294*0Sstevel@tonic-gate if ((strncmp(name, "/dev/dsk/", strlen("/dev/dsk/")) == 0) && 295*0Sstevel@tonic-gate (strchr((p = name + strlen("/dev/dsk/")), '/') == NULL)) { 296*0Sstevel@tonic-gate diskname = Strdup(p); 297*0Sstevel@tonic-gate stripS(diskname); 298*0Sstevel@tonic-gate return (diskname); 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate if ((strncmp(name, "/dev/rdsk/", strlen("/dev/rdsk/")) == 0) && 302*0Sstevel@tonic-gate (strchr((p = name + strlen("/dev/rdsk/")), '/') == NULL)) { 303*0Sstevel@tonic-gate diskname = Strdup(p); 304*0Sstevel@tonic-gate stripS(diskname); 305*0Sstevel@tonic-gate return (diskname); 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate if ((strncmp(name, "/dev/ap/dsk/", strlen("/dev/ap/dsk/")) == 0) && 309*0Sstevel@tonic-gate (strchr((p = name + strlen("/dev/ap/dsk/")), '/') == NULL)) { 310*0Sstevel@tonic-gate diskname = Strdup(p); 311*0Sstevel@tonic-gate stripS(diskname); 312*0Sstevel@tonic-gate return (diskname); 313*0Sstevel@tonic-gate } 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate if ((strncmp(name, "/dev/ap/rdsk/", strlen("/dev/ap/rdsk/")) == 0) && 316*0Sstevel@tonic-gate (strchr((p = name + strlen("/dev/ap/rdsk/")), '/') == NULL)) { 317*0Sstevel@tonic-gate diskname = Strdup(p); 318*0Sstevel@tonic-gate stripS(diskname); 319*0Sstevel@tonic-gate return (diskname); 320*0Sstevel@tonic-gate } 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate if ((strncmp(name, "/dev/did/dsk/", strlen("/dev/did/dsk/")) == 0) && 323*0Sstevel@tonic-gate (strchr((p = name + strlen("/dev/did/dsk/")), '/') == NULL)) { 324*0Sstevel@tonic-gate diskname = Strdup(p); 325*0Sstevel@tonic-gate stripS(diskname); 326*0Sstevel@tonic-gate return (diskname); 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate if ((strncmp(name, "/dev/did/rdsk/", strlen("/dev/did/rdsk/")) == 0) && 330*0Sstevel@tonic-gate (strchr((p = name + strlen("/dev/did/rdsk/")), '/') == NULL)) { 331*0Sstevel@tonic-gate diskname = Strdup(p); 332*0Sstevel@tonic-gate stripS(diskname); 333*0Sstevel@tonic-gate return (diskname); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate diskname = Strdup(name); 337*0Sstevel@tonic-gate stripS(diskname); 338*0Sstevel@tonic-gate return (diskname); 339*0Sstevel@tonic-gate } 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate /* 342*0Sstevel@tonic-gate * has_devid -- return the device ID for a given key 343*0Sstevel@tonic-gate * 344*0Sstevel@tonic-gate * RETURN 345*0Sstevel@tonic-gate * NULL error 346*0Sstevel@tonic-gate * devid devid found that corresponds to the given key. 347*0Sstevel@tonic-gate */ 348*0Sstevel@tonic-gate static ddi_devid_t 349*0Sstevel@tonic-gate has_devid(set_t setno, side_t sideno, mdkey_t key, md_error_t *ep) 350*0Sstevel@tonic-gate { 351*0Sstevel@tonic-gate return (meta_getdidbykey(setno, sideno, key, ep)); 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate /* 355*0Sstevel@tonic-gate * Go through the existing list of replicas and check to see 356*0Sstevel@tonic-gate * if their disk has moved, if so update the replica list 357*0Sstevel@tonic-gate * 358*0Sstevel@tonic-gate * RETURN 359*0Sstevel@tonic-gate * -1 error 360*0Sstevel@tonic-gate * 0 success 361*0Sstevel@tonic-gate */ 362*0Sstevel@tonic-gate static int 363*0Sstevel@tonic-gate fix_replicanames( 364*0Sstevel@tonic-gate mdsetname_t *sp, 365*0Sstevel@tonic-gate md_error_t *ep 366*0Sstevel@tonic-gate ) 367*0Sstevel@tonic-gate { 368*0Sstevel@tonic-gate md_replicalist_t *rlp = NULL; 369*0Sstevel@tonic-gate md_replicalist_t *rl; 370*0Sstevel@tonic-gate int ret = -1; 371*0Sstevel@tonic-gate int match_type = 0; 372*0Sstevel@tonic-gate devid_nmlist_t *disklist = NULL; 373*0Sstevel@tonic-gate dev_t small_dev = (dev_t)NODEV; 374*0Sstevel@tonic-gate side_t sideno; 375*0Sstevel@tonic-gate set_t setno = sp->setno; 376*0Sstevel@tonic-gate char *search_path; 377*0Sstevel@tonic-gate int search_number; 378*0Sstevel@tonic-gate char *ctds_name; 379*0Sstevel@tonic-gate char *path_name; 380*0Sstevel@tonic-gate int i; 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate sideno = getmyside(sp, ep); 383*0Sstevel@tonic-gate if (sideno == MD_SIDEWILD) { 384*0Sstevel@tonic-gate mda_debug("Failed to find the side number\n"); 385*0Sstevel@tonic-gate return (-1); 386*0Sstevel@tonic-gate } 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate if (metareplicalist(sp, MD_BASICNAME_OK | PRINT_FAST, &rlp, ep) < 0) { 389*0Sstevel@tonic-gate mda_debug("Unable to get a list of replicas\n"); 390*0Sstevel@tonic-gate return (METADEVADM_ERR); 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate for (rl = rlp; (rl != NULL); rl = rl->rl_next) { 394*0Sstevel@tonic-gate md_replica_t *r = rl->rl_repp; 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate small_dev = meta_cmpldev(r->r_namep->dev); 397*0Sstevel@tonic-gate search_number = mda_findpath(r->r_namep->bname); 398*0Sstevel@tonic-gate if (search_number == -1) { 399*0Sstevel@tonic-gate mda_debug("replica update: invalid path: %s", 400*0Sstevel@tonic-gate r->r_namep->bname); 401*0Sstevel@tonic-gate continue; 402*0Sstevel@tonic-gate } else { 403*0Sstevel@tonic-gate search_path = plist[search_number].search_path; 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate if (r->r_devid == NULL) 407*0Sstevel@tonic-gate continue; 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist(search_path, r->r_devid, 410*0Sstevel@tonic-gate r->r_minor_name, &disklist); 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate mda_debug("replica update: search_path %s\n", search_path); 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate if (ret != 0) { 415*0Sstevel@tonic-gate /* 416*0Sstevel@tonic-gate * Failed to find the disk, nothing can be done. 417*0Sstevel@tonic-gate * The replica will be marked as bad later. 418*0Sstevel@tonic-gate */ 419*0Sstevel@tonic-gate mda_debug("replica update: failed to find disk %s\n", 420*0Sstevel@tonic-gate r->r_namep->cname); 421*0Sstevel@tonic-gate continue; 422*0Sstevel@tonic-gate } 423*0Sstevel@tonic-gate mda_debug("replica update: current %s (%p)\n", 424*0Sstevel@tonic-gate r->r_namep->bname, (void *) small_dev); 425*0Sstevel@tonic-gate 426*0Sstevel@tonic-gate /* 427*0Sstevel@tonic-gate * Check to see if the returned disk matches the stored one 428*0Sstevel@tonic-gate */ 429*0Sstevel@tonic-gate for (i = 0; disklist[i].dev != NODEV; i++) { 430*0Sstevel@tonic-gate match_type = 0; 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate mda_debug("replica update: devid list: %s (%p)\n", 433*0Sstevel@tonic-gate disklist[i].devname, (void *) disklist[i].dev); 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate if (disklist[i].dev == small_dev) { 436*0Sstevel@tonic-gate match_type |= DEV_MATCH; 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate if (strncmp(r->r_namep->bname, disklist[i].devname, 440*0Sstevel@tonic-gate strlen(r->r_namep->bname)) == 0) { 441*0Sstevel@tonic-gate match_type |= NAME_MATCH; 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate 444*0Sstevel@tonic-gate /* 445*0Sstevel@tonic-gate * break out if some sort of match is found because 446*0Sstevel@tonic-gate * we already match on the devid. 447*0Sstevel@tonic-gate */ 448*0Sstevel@tonic-gate if (match_type != 0) 449*0Sstevel@tonic-gate break; 450*0Sstevel@tonic-gate } 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate mda_debug("fix_replicanames: match: %x i: %d\n", match_type, i); 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate if (match_type == (DEV_MATCH|NAME_MATCH)) { 455*0Sstevel@tonic-gate /* no change */ 456*0Sstevel@tonic-gate mda_debug("replica update: no change %s\n", 457*0Sstevel@tonic-gate disklist[i].devname); 458*0Sstevel@tonic-gate devid_free_nmlist(disklist); 459*0Sstevel@tonic-gate continue; 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate /* No match found - use the first entry in disklist */ 463*0Sstevel@tonic-gate if (disklist[i].dev == NODEV) 464*0Sstevel@tonic-gate i = 0; 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gate mda_debug("replica update: reloading %s %p\n", 467*0Sstevel@tonic-gate disklist[i].devname, 468*0Sstevel@tonic-gate (void *) meta_expldev(disklist[i].dev)); 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate if (firsttime) { 471*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 472*0Sstevel@tonic-gate "Disk movement detected\n")); 473*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 474*0Sstevel@tonic-gate "Updating device names in Solaris Volume " 475*0Sstevel@tonic-gate "Manager\n")); 476*0Sstevel@tonic-gate firsttime = 0; 477*0Sstevel@tonic-gate } 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 480*0Sstevel@tonic-gate char *devidstr; 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gate devidstr = 483*0Sstevel@tonic-gate devid_str_encode(r->r_devid, r->r_minor_name); 484*0Sstevel@tonic-gate if (devidstr == NULL) { 485*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 486*0Sstevel@tonic-gate "Failed to encode the devid\n")); 487*0Sstevel@tonic-gate continue; 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 490*0Sstevel@tonic-gate "%s changed to %s from device relocation " 491*0Sstevel@tonic-gate "information %s\n"), 492*0Sstevel@tonic-gate (char *)r->r_namep->cname, disklist[i].devname, 493*0Sstevel@tonic-gate devidstr); 494*0Sstevel@tonic-gate } 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate if (!(dev_options & DEV_NOACTION)) { 497*0Sstevel@tonic-gate mda_debug("Updating locator name\n"); 498*0Sstevel@tonic-gate ctds_name = strrchr(disklist[i].devname, '/'); 499*0Sstevel@tonic-gate ctds_name++; 500*0Sstevel@tonic-gate if ((path_name = mda_getpath(disklist[i].devname)) 501*0Sstevel@tonic-gate == NULL) { 502*0Sstevel@tonic-gate continue; 503*0Sstevel@tonic-gate } 504*0Sstevel@tonic-gate if (update_locator_namespace(setno, sideno, 505*0Sstevel@tonic-gate ctds_name, meta_expldev(disklist[i].dev), 506*0Sstevel@tonic-gate path_name, ep) != 0) { 507*0Sstevel@tonic-gate mda_debug("replica update: ioctl failed\n"); 508*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 509*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 510*0Sstevel@tonic-gate "Failed to update locator " 511*0Sstevel@tonic-gate "namespace on change from %s " 512*0Sstevel@tonic-gate "to %s\n"), ctds_name, 513*0Sstevel@tonic-gate disklist[i].devname); 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate } 516*0Sstevel@tonic-gate } 517*0Sstevel@tonic-gate Free(path_name); 518*0Sstevel@tonic-gate devid_free_nmlist(disklist); 519*0Sstevel@tonic-gate } 520*0Sstevel@tonic-gate metafreereplicalist(rlp); 521*0Sstevel@tonic-gate return (0); 522*0Sstevel@tonic-gate } 523*0Sstevel@tonic-gate 524*0Sstevel@tonic-gate /* 525*0Sstevel@tonic-gate * pathname_reload - main function for the -r option. Will reload the 526*0Sstevel@tonic-gate * pathname in both the main namespace and the locator namespace. 527*0Sstevel@tonic-gate * Also, checks both areas for invalid device ID's and prints them 528*0Sstevel@tonic-gate * out. 529*0Sstevel@tonic-gate * 530*0Sstevel@tonic-gate * If the set is a multi-node diskset that means there are no devid's 531*0Sstevel@tonic-gate * so just return. 532*0Sstevel@tonic-gate * 533*0Sstevel@tonic-gate * RETURN 534*0Sstevel@tonic-gate * METADEVADM_ERR error 535*0Sstevel@tonic-gate * METADEVADM_SUCCESS success 536*0Sstevel@tonic-gate * METADEVADM_DEVIDINVALID success, but invalid devids detected 537*0Sstevel@tonic-gate */ 538*0Sstevel@tonic-gate int 539*0Sstevel@tonic-gate pathname_reload( 540*0Sstevel@tonic-gate mdsetname_t **spp, 541*0Sstevel@tonic-gate set_t setno, 542*0Sstevel@tonic-gate md_error_t *ep) 543*0Sstevel@tonic-gate { 544*0Sstevel@tonic-gate char *drvnmp; 545*0Sstevel@tonic-gate minor_t mnum = 0; 546*0Sstevel@tonic-gate md_dev64_t dev = 0; 547*0Sstevel@tonic-gate mdnm_params_t nm; 548*0Sstevel@tonic-gate char *ctds_name; 549*0Sstevel@tonic-gate ddi_devid_t devidp; 550*0Sstevel@tonic-gate md_i_didstat_t ds; 551*0Sstevel@tonic-gate side_t sideno; 552*0Sstevel@tonic-gate char *search_path = NULL; 553*0Sstevel@tonic-gate int search_number; 554*0Sstevel@tonic-gate devid_nmlist_t *disklist = NULL; 555*0Sstevel@tonic-gate char *minor_name = NULL; 556*0Sstevel@tonic-gate char *devidstr = NULL; 557*0Sstevel@tonic-gate char *path = NULL; 558*0Sstevel@tonic-gate int ret; 559*0Sstevel@tonic-gate dev_t small_dev = (dev_t)NODEV; 560*0Sstevel@tonic-gate int match_type; 561*0Sstevel@tonic-gate char *tmp = NULL; 562*0Sstevel@tonic-gate mdsetname_t *sp = *spp; 563*0Sstevel@tonic-gate md_set_desc *sd; 564*0Sstevel@tonic-gate int i; 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate /* 567*0Sstevel@tonic-gate * Check for multi-node diskset and return if it is one. 568*0Sstevel@tonic-gate */ 569*0Sstevel@tonic-gate if (!metaislocalset(sp)) { 570*0Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 571*0Sstevel@tonic-gate return (METADEVADM_ERR); 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 574*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 575*0Sstevel@tonic-gate } 576*0Sstevel@tonic-gate 577*0Sstevel@tonic-gate /* 578*0Sstevel@tonic-gate * Get the entry of the namespace via the key. To do this 579*0Sstevel@tonic-gate * call MD_IOCNXTKEY until no more. 580*0Sstevel@tonic-gate * For each entry in the namespace we want to check 581*0Sstevel@tonic-gate * for devid and update 582*0Sstevel@tonic-gate */ 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm)); 585*0Sstevel@tonic-gate nm.key = MD_KEYWILD; 586*0Sstevel@tonic-gate 587*0Sstevel@tonic-gate sideno = getmyside(*spp, ep); 588*0Sstevel@tonic-gate if (sideno == MD_SIDEWILD) { 589*0Sstevel@tonic-gate /* failed to find this node in the set */ 590*0Sstevel@tonic-gate mda_debug("Failed to find the side number\n"); 591*0Sstevel@tonic-gate return (METADEVADM_ERR); 592*0Sstevel@tonic-gate } 593*0Sstevel@tonic-gate 594*0Sstevel@tonic-gate /* LINTED */ 595*0Sstevel@tonic-gate while (1) { 596*0Sstevel@tonic-gate nm.mde = mdnullerror; 597*0Sstevel@tonic-gate nm.setno = setno; 598*0Sstevel@tonic-gate nm.side = sideno; 599*0Sstevel@tonic-gate /* look at each key in the namespace */ 600*0Sstevel@tonic-gate if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde, NULL) != 0) { 601*0Sstevel@tonic-gate (void) mdstealerror(ep, &nm.mde); 602*0Sstevel@tonic-gate return (METADEVADM_ERR); 603*0Sstevel@tonic-gate } 604*0Sstevel@tonic-gate 605*0Sstevel@tonic-gate if (nm.key == MD_KEYWILD) { 606*0Sstevel@tonic-gate /* no more entries */ 607*0Sstevel@tonic-gate break; 608*0Sstevel@tonic-gate } 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate /* 611*0Sstevel@tonic-gate * get the nm entry using the key. Then check to see if 612*0Sstevel@tonic-gate * there's a devid associated with this entry 613*0Sstevel@tonic-gate * If not, go onto next key. 614*0Sstevel@tonic-gate */ 615*0Sstevel@tonic-gate if ((nm.devname = (uintptr_t)meta_getnmentbykey(setno, sideno, 616*0Sstevel@tonic-gate nm.key, &drvnmp, &mnum, &dev, ep)) == NULL) { 617*0Sstevel@tonic-gate mda_debug("pathname_reload: no name for key: %d\n", 618*0Sstevel@tonic-gate nm.key); 619*0Sstevel@tonic-gate continue; 620*0Sstevel@tonic-gate } 621*0Sstevel@tonic-gate 622*0Sstevel@tonic-gate mda_debug("pathname_reload: examining %s\n", 623*0Sstevel@tonic-gate (char *)nm.devname); 624*0Sstevel@tonic-gate 625*0Sstevel@tonic-gate if ((devidp = has_devid(setno, sideno, nm.key, ep)) == NULL) { 626*0Sstevel@tonic-gate /* metadevices do not have devid's in them */ 627*0Sstevel@tonic-gate mda_debug("pathname_reload: no devid for %s\n", 628*0Sstevel@tonic-gate (char *)nm.devname); 629*0Sstevel@tonic-gate continue; 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate if ((minor_name = meta_getdidminorbykey(setno, sideno, 633*0Sstevel@tonic-gate nm.key, ep)) == NULL) { 634*0Sstevel@tonic-gate /* 635*0Sstevel@tonic-gate * In theory this is impossible because if the 636*0Sstevel@tonic-gate * devidp is non-null then the minor_name has 637*0Sstevel@tonic-gate * already been looked up. 638*0Sstevel@tonic-gate */ 639*0Sstevel@tonic-gate mda_debug("No minor name for %s\n", (char *)nm.devname); 640*0Sstevel@tonic-gate free(devidp); 641*0Sstevel@tonic-gate continue; 642*0Sstevel@tonic-gate } 643*0Sstevel@tonic-gate /* 644*0Sstevel@tonic-gate * If there is a devid then we have a real device that 645*0Sstevel@tonic-gate * could have moved. 646*0Sstevel@tonic-gate */ 647*0Sstevel@tonic-gate devidstr = devid_str_encode(devidp, minor_name); 648*0Sstevel@tonic-gate if (devidstr == NULL) { 649*0Sstevel@tonic-gate mda_debug("Failed to encode the devid\n"); 650*0Sstevel@tonic-gate free(devidp); 651*0Sstevel@tonic-gate continue; 652*0Sstevel@tonic-gate } 653*0Sstevel@tonic-gate mda_debug("devid: %s\n", devidstr); 654*0Sstevel@tonic-gate 655*0Sstevel@tonic-gate /* 656*0Sstevel@tonic-gate * Find the search path that should be used. This is an 657*0Sstevel@tonic-gate * optimization to try and prevent a search for the complete 658*0Sstevel@tonic-gate * /dev namespace. 659*0Sstevel@tonic-gate */ 660*0Sstevel@tonic-gate search_number = mda_findpath((char *)nm.devname); 661*0Sstevel@tonic-gate if (search_number == -1) { 662*0Sstevel@tonic-gate search_path = "/dev"; 663*0Sstevel@tonic-gate } else { 664*0Sstevel@tonic-gate search_path = plist[search_number].search_path; 665*0Sstevel@tonic-gate } 666*0Sstevel@tonic-gate 667*0Sstevel@tonic-gate /* now look for the disk name using the devid */ 668*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist(search_path, devidp, 669*0Sstevel@tonic-gate minor_name, &disklist); 670*0Sstevel@tonic-gate free(devidp); 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gate if (ret != 0) { 673*0Sstevel@tonic-gate /* 674*0Sstevel@tonic-gate * Failed to find the disk 675*0Sstevel@tonic-gate */ 676*0Sstevel@tonic-gate devid_str_free(devidstr); 677*0Sstevel@tonic-gate continue; 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gate small_dev = meta_cmpldev(dev); 681*0Sstevel@tonic-gate mda_debug("Old device lookup: %s (%p)\n", 682*0Sstevel@tonic-gate (char *)nm.devname, (void *)small_dev); 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate /* 685*0Sstevel@tonic-gate * Check to see if the returned disk matches the stored one 686*0Sstevel@tonic-gate */ 687*0Sstevel@tonic-gate for (i = 0; disklist[i].dev != NODEV; i++) { 688*0Sstevel@tonic-gate match_type = 0; 689*0Sstevel@tonic-gate mda_debug("From devid lookup: %s (%p)\n", 690*0Sstevel@tonic-gate (char *)disklist[i].devname, 691*0Sstevel@tonic-gate (void *)disklist[i].dev); 692*0Sstevel@tonic-gate 693*0Sstevel@tonic-gate if (disklist[i].dev == small_dev) { 694*0Sstevel@tonic-gate match_type |= DEV_MATCH; 695*0Sstevel@tonic-gate } 696*0Sstevel@tonic-gate 697*0Sstevel@tonic-gate if (strncmp((char *)nm.devname, disklist[i].devname, 698*0Sstevel@tonic-gate strlen((char *)nm.devname)) == 0) { 699*0Sstevel@tonic-gate mda_debug("Name match: %s and %s (%d)\n", 700*0Sstevel@tonic-gate disklist[i].devname, (char *)nm.devname, 701*0Sstevel@tonic-gate strlen((char *)nm.devname)); 702*0Sstevel@tonic-gate match_type |= NAME_MATCH; 703*0Sstevel@tonic-gate } 704*0Sstevel@tonic-gate 705*0Sstevel@tonic-gate if (match_type == (DEV_MATCH|NAME_MATCH)) 706*0Sstevel@tonic-gate break; 707*0Sstevel@tonic-gate } 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate if (match_type == (DEV_MATCH|NAME_MATCH)) { 710*0Sstevel@tonic-gate /* no change */ 711*0Sstevel@tonic-gate devid_str_free(devidstr); 712*0Sstevel@tonic-gate mda_debug("All matched %s\n", disklist[i].devname); 713*0Sstevel@tonic-gate devid_free_nmlist(disklist); 714*0Sstevel@tonic-gate continue; 715*0Sstevel@tonic-gate } 716*0Sstevel@tonic-gate 717*0Sstevel@tonic-gate /* No match found - use the first entry in disklist */ 718*0Sstevel@tonic-gate i = 0; 719*0Sstevel@tonic-gate 720*0Sstevel@tonic-gate if (firsttime) { 721*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 722*0Sstevel@tonic-gate "Disk movement detected\n")); 723*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 724*0Sstevel@tonic-gate "Updating device names in " 725*0Sstevel@tonic-gate "Solaris Volume Manager\n")); 726*0Sstevel@tonic-gate firsttime = 0; 727*0Sstevel@tonic-gate } 728*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 729*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 730*0Sstevel@tonic-gate "%s changed to %s from device relocation " 731*0Sstevel@tonic-gate "information %s\n"), 732*0Sstevel@tonic-gate (char *)nm.devname, disklist[i].devname, 733*0Sstevel@tonic-gate devidstr); 734*0Sstevel@tonic-gate } 735*0Sstevel@tonic-gate devid_str_free(devidstr); 736*0Sstevel@tonic-gate 737*0Sstevel@tonic-gate /* need to build up the path of the disk */ 738*0Sstevel@tonic-gate if ((path = Strdup(disklist[i].devname)) == NULL) { 739*0Sstevel@tonic-gate mda_debug("Failed to duplicate path: %s\n", 740*0Sstevel@tonic-gate disklist[i].devname); 741*0Sstevel@tonic-gate devid_free_nmlist(disklist); 742*0Sstevel@tonic-gate continue; 743*0Sstevel@tonic-gate } 744*0Sstevel@tonic-gate if ((tmp = strrchr(path, '/')) == NULL) { 745*0Sstevel@tonic-gate mda_debug("Failed to parse %s\n", path); 746*0Sstevel@tonic-gate devid_free_nmlist(disklist); 747*0Sstevel@tonic-gate Free(path); 748*0Sstevel@tonic-gate continue; 749*0Sstevel@tonic-gate } 750*0Sstevel@tonic-gate tmp += sizeof (char); 751*0Sstevel@tonic-gate *tmp = '\0'; 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate if ((ctds_name = strrchr(disklist[i].devname, '/')) == NULL) { 754*0Sstevel@tonic-gate mda_debug("Failed to parse ctds name: %s\n", 755*0Sstevel@tonic-gate disklist[i].devname); 756*0Sstevel@tonic-gate devid_free_nmlist(disklist); 757*0Sstevel@tonic-gate Free(path); 758*0Sstevel@tonic-gate continue; 759*0Sstevel@tonic-gate } 760*0Sstevel@tonic-gate ctds_name += sizeof (char); 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate mda_debug("Reloading disk %s %s %p\n", 763*0Sstevel@tonic-gate ctds_name, path, (void *) meta_expldev(disklist[i].dev)); 764*0Sstevel@tonic-gate 765*0Sstevel@tonic-gate if (!(dev_options & DEV_NOACTION)) { 766*0Sstevel@tonic-gate /* Something has changed so update the namespace */ 767*0Sstevel@tonic-gate if (update_namespace(setno, sideno, ctds_name, 768*0Sstevel@tonic-gate meta_expldev(disklist[i].dev), nm.key, path, 769*0Sstevel@tonic-gate ep) != 0) { 770*0Sstevel@tonic-gate mda_debug("Failed to update namespace\n"); 771*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 772*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 773*0Sstevel@tonic-gate "Failed to update namespace on " 774*0Sstevel@tonic-gate "change from %s to %s\n"), 775*0Sstevel@tonic-gate ctds_name, disklist[i].devname); 776*0Sstevel@tonic-gate } 777*0Sstevel@tonic-gate } 778*0Sstevel@tonic-gate } 779*0Sstevel@tonic-gate devid_free_nmlist(disklist); 780*0Sstevel@tonic-gate Free(path); 781*0Sstevel@tonic-gate } 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate if (fix_replicanames(*spp, ep) == -1) 784*0Sstevel@tonic-gate mda_debug("Failed to update replicas\n"); 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate /* 787*0Sstevel@tonic-gate * check for invalid device id's 788*0Sstevel@tonic-gate */ 789*0Sstevel@tonic-gate (void) memset(&ds, '\0', sizeof (ds)); 790*0Sstevel@tonic-gate ds.setno = setno; 791*0Sstevel@tonic-gate ds.side = sideno; 792*0Sstevel@tonic-gate ds.mode = MD_FIND_INVDID; 793*0Sstevel@tonic-gate /* get count of number of invalid device id's */ 794*0Sstevel@tonic-gate if (metaioctl(MD_IOCDID_STAT, &ds, &ds.mde, NULL) != 0) { 795*0Sstevel@tonic-gate (void) mdstealerror(ep, &ds.mde); 796*0Sstevel@tonic-gate return (METADEVADM_ERR); 797*0Sstevel@tonic-gate } 798*0Sstevel@tonic-gate if (ds.cnt != 0) { 799*0Sstevel@tonic-gate char *ctdptr, *ctdp; 800*0Sstevel@tonic-gate /* 801*0Sstevel@tonic-gate * we have some invalid device id's so we need to 802*0Sstevel@tonic-gate * print them out 803*0Sstevel@tonic-gate */ 804*0Sstevel@tonic-gate ds.mode = MD_GET_INVDID; 805*0Sstevel@tonic-gate /* malloc buffer for kernel to place devid list into */ 806*0Sstevel@tonic-gate if ((ctdptr = (char *)Malloc((ds.cnt * ds.maxsz) + 1)) == 0) { 807*0Sstevel@tonic-gate return (METADEVADM_ERR); 808*0Sstevel@tonic-gate } 809*0Sstevel@tonic-gate ds.ctdp = (uintptr_t)ctdptr; 810*0Sstevel@tonic-gate /* get actual list of invalid device id's */ 811*0Sstevel@tonic-gate if (metaioctl(MD_IOCDID_STAT, &ds, &ds.mde, NULL) != 0) { 812*0Sstevel@tonic-gate Free(ctdptr); 813*0Sstevel@tonic-gate (void) mdstealerror(ep, &ds.mde); 814*0Sstevel@tonic-gate return (METADEVADM_ERR); 815*0Sstevel@tonic-gate } 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate /* print out the invalid devid's */ 818*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 819*0Sstevel@tonic-gate "Invalid device relocation information " 820*0Sstevel@tonic-gate "detected in Solaris Volume Manager\n")); 821*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 822*0Sstevel@tonic-gate "Please check the status of the following disk(s):\n")); 823*0Sstevel@tonic-gate ctdp = (char *)ds.ctdp; 824*0Sstevel@tonic-gate while (*ctdp != NULL) { 825*0Sstevel@tonic-gate mda_print("\t%s\n", ctdp); 826*0Sstevel@tonic-gate ctdp += ds.maxsz; 827*0Sstevel@tonic-gate } 828*0Sstevel@tonic-gate Free(ctdptr); 829*0Sstevel@tonic-gate return (METADEVADM_DEVIDINVALID); 830*0Sstevel@tonic-gate } 831*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 832*0Sstevel@tonic-gate } 833*0Sstevel@tonic-gate 834*0Sstevel@tonic-gate /* 835*0Sstevel@tonic-gate * replica_update_devid - cycle through the replica list, rlp, and 836*0Sstevel@tonic-gate * update the device ids on all of the replicas that are on the 837*0Sstevel@tonic-gate * device specified by lp. A side effect is to update the value of 838*0Sstevel@tonic-gate * cdevidpp to contain the character representation of the device 839*0Sstevel@tonic-gate * id before updating if it is not already set. 840*0Sstevel@tonic-gate * 841*0Sstevel@tonic-gate * RETURN 842*0Sstevel@tonic-gate * METADEVADM_ERR error 843*0Sstevel@tonic-gate * METADEVADM_SUCCESS success 844*0Sstevel@tonic-gate */ 845*0Sstevel@tonic-gate static int 846*0Sstevel@tonic-gate replica_update_devid( 847*0Sstevel@tonic-gate md_replicalist_t *rlp, 848*0Sstevel@tonic-gate mddrivename_t *dnp, 849*0Sstevel@tonic-gate set_t setno, 850*0Sstevel@tonic-gate char **cdevidpp, 851*0Sstevel@tonic-gate md_error_t *ep 852*0Sstevel@tonic-gate ) 853*0Sstevel@tonic-gate { 854*0Sstevel@tonic-gate mddb_config_t db_c; 855*0Sstevel@tonic-gate md_replicalist_t *rl; 856*0Sstevel@tonic-gate ddi_devid_t devidp; 857*0Sstevel@tonic-gate int ret; 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate if (cdevidpp == NULL) 860*0Sstevel@tonic-gate return (METADEVADM_ERR); 861*0Sstevel@tonic-gate 862*0Sstevel@tonic-gate ret = devid_str_decode(dnp->devid, &devidp, NULL); 863*0Sstevel@tonic-gate if (ret != 0) { 864*0Sstevel@tonic-gate /* failed to encode the devid */ 865*0Sstevel@tonic-gate mda_debug("Failed to decode %s into a valid devid\n", 866*0Sstevel@tonic-gate dnp->devid); 867*0Sstevel@tonic-gate return (METADEVADM_ERR); 868*0Sstevel@tonic-gate } 869*0Sstevel@tonic-gate 870*0Sstevel@tonic-gate /* search replica list for give ctd name */ 871*0Sstevel@tonic-gate for (rl = rlp; (rl != NULL); rl = rl->rl_next) { 872*0Sstevel@tonic-gate md_replica_t *r = rl->rl_repp; 873*0Sstevel@tonic-gate mdname_t *rnp = r->r_namep; 874*0Sstevel@tonic-gate 875*0Sstevel@tonic-gate if (strncmp(rnp->cname, dnp->cname, strlen(dnp->cname)) == 0) { 876*0Sstevel@tonic-gate 877*0Sstevel@tonic-gate /* found the replica, now grab the devid */ 878*0Sstevel@tonic-gate if (*cdevidpp == NULL) { 879*0Sstevel@tonic-gate *cdevidpp = devid_str_encode(r->r_devid, NULL); 880*0Sstevel@tonic-gate } 881*0Sstevel@tonic-gate 882*0Sstevel@tonic-gate if (*cdevidpp == NULL) { 883*0Sstevel@tonic-gate devid_free(devidp); 884*0Sstevel@tonic-gate return (METADEVADM_ERR); 885*0Sstevel@tonic-gate } 886*0Sstevel@tonic-gate 887*0Sstevel@tonic-gate mda_debug("Updating replica %s, set %d, old devid %s\n", 888*0Sstevel@tonic-gate rnp->cname, setno, *cdevidpp); 889*0Sstevel@tonic-gate 890*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 891*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 892*0Sstevel@tonic-gate "Updating replica %s of set number %d from " 893*0Sstevel@tonic-gate "device id %s to device id %s\n"), 894*0Sstevel@tonic-gate rnp->cname, setno, *cdevidpp, dnp->devid); 895*0Sstevel@tonic-gate } 896*0Sstevel@tonic-gate 897*0Sstevel@tonic-gate (void) memset(&db_c, '\0', sizeof (db_c)); 898*0Sstevel@tonic-gate 899*0Sstevel@tonic-gate db_c.c_setno = setno; 900*0Sstevel@tonic-gate db_c.c_devt = rnp->dev; 901*0Sstevel@tonic-gate 902*0Sstevel@tonic-gate if (!(dev_options & DEV_NOACTION)) { 903*0Sstevel@tonic-gate 904*0Sstevel@tonic-gate mda_debug("Updating replica\n"); 905*0Sstevel@tonic-gate 906*0Sstevel@tonic-gate /* 907*0Sstevel@tonic-gate * call into kernel to update lb 908*0Sstevel@tonic-gate * namespace device id 909*0Sstevel@tonic-gate * of given devt 910*0Sstevel@tonic-gate */ 911*0Sstevel@tonic-gate if (metaioctl(MD_DB_SETDID, &db_c, 912*0Sstevel@tonic-gate &db_c.c_mde, NULL) != 0) { 913*0Sstevel@tonic-gate devid_free(devidp); 914*0Sstevel@tonic-gate (void) mdstealerror(ep, &db_c.c_mde); 915*0Sstevel@tonic-gate return (METADEVADM_ERR); 916*0Sstevel@tonic-gate } 917*0Sstevel@tonic-gate } 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate } 920*0Sstevel@tonic-gate } 921*0Sstevel@tonic-gate devid_free(devidp); 922*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 923*0Sstevel@tonic-gate } 924*0Sstevel@tonic-gate 925*0Sstevel@tonic-gate /* 926*0Sstevel@tonic-gate * devid_update -- main routine for the -u option. Will update both the 927*0Sstevel@tonic-gate * namespace and the locator block with the correct devid for the 928*0Sstevel@tonic-gate * disk specified. 929*0Sstevel@tonic-gate * 930*0Sstevel@tonic-gate * RETURN 931*0Sstevel@tonic-gate * METADEVADM_ERR error 932*0Sstevel@tonic-gate * METADEVADM_SUCCESS success 933*0Sstevel@tonic-gate */ 934*0Sstevel@tonic-gate static int 935*0Sstevel@tonic-gate devid_update( 936*0Sstevel@tonic-gate mdsetname_t **spp, 937*0Sstevel@tonic-gate set_t setno, 938*0Sstevel@tonic-gate char *ctd, 939*0Sstevel@tonic-gate md_error_t *ep 940*0Sstevel@tonic-gate ) 941*0Sstevel@tonic-gate { 942*0Sstevel@tonic-gate md_drive_desc *dd, *ddp; 943*0Sstevel@tonic-gate mddrivename_t *dnp; 944*0Sstevel@tonic-gate mdnm_params_t nm; 945*0Sstevel@tonic-gate ddi_devid_t devidp; 946*0Sstevel@tonic-gate side_t side; 947*0Sstevel@tonic-gate char *old_cdevidp = NULL; 948*0Sstevel@tonic-gate md_replicalist_t *rlp = NULL; 949*0Sstevel@tonic-gate int rval = METADEVADM_ERR; 950*0Sstevel@tonic-gate mdname_t *np = NULL; 951*0Sstevel@tonic-gate uint_t rep_slice; 952*0Sstevel@tonic-gate char *pathname = NULL; 953*0Sstevel@tonic-gate char *diskname = NULL; 954*0Sstevel@tonic-gate int fd = -1; 955*0Sstevel@tonic-gate int len; 956*0Sstevel@tonic-gate char *fp; 957*0Sstevel@tonic-gate 958*0Sstevel@tonic-gate side = getmyside(*spp, ep); 959*0Sstevel@tonic-gate if (side == MD_SIDEWILD) { 960*0Sstevel@tonic-gate /* failed to find this node in the set */ 961*0Sstevel@tonic-gate mda_debug("Failed to find the side number\n"); 962*0Sstevel@tonic-gate return (METADEVADM_ERR); 963*0Sstevel@tonic-gate } 964*0Sstevel@tonic-gate 965*0Sstevel@tonic-gate if ((dnp = metadrivename(spp, ctd, ep)) == NULL) { 966*0Sstevel@tonic-gate mda_debug("Failed to create a dnp for %s\n", ctd); 967*0Sstevel@tonic-gate return (METADEVADM_ERR); 968*0Sstevel@tonic-gate } 969*0Sstevel@tonic-gate if (dnp->devid == NULL) { 970*0Sstevel@tonic-gate /* 971*0Sstevel@tonic-gate * Disk does not have a devid! So cannot update the 972*0Sstevel@tonic-gate * devid within the replica. 973*0Sstevel@tonic-gate */ 974*0Sstevel@tonic-gate mda_debug("%s does not have a devid\n", dnp->cname); 975*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 976*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 977*0Sstevel@tonic-gate "%s does not have a device id. Cannot update " 978*0Sstevel@tonic-gate "device id if none exists\n"), ctd); 979*0Sstevel@tonic-gate } 980*0Sstevel@tonic-gate return (METADEVADM_ERR); 981*0Sstevel@tonic-gate } 982*0Sstevel@tonic-gate 983*0Sstevel@tonic-gate mda_debug("Devid update to: %s\n", dnp->devid); 984*0Sstevel@tonic-gate 985*0Sstevel@tonic-gate /* 986*0Sstevel@tonic-gate * Check if we own the set, if we do then do some processing 987*0Sstevel@tonic-gate * on the replicas. 988*0Sstevel@tonic-gate */ 989*0Sstevel@tonic-gate if (meta_check_ownership(*spp, ep) == 0) { 990*0Sstevel@tonic-gate 991*0Sstevel@tonic-gate /* get the replicas */ 992*0Sstevel@tonic-gate if (metareplicalist(*spp, MD_BASICNAME_OK | PRINT_FAST, &rlp, 993*0Sstevel@tonic-gate ep) < 0) 994*0Sstevel@tonic-gate return (METADEVADM_ERR); 995*0Sstevel@tonic-gate 996*0Sstevel@tonic-gate /* update the devids in the replicas if necessary */ 997*0Sstevel@tonic-gate if (replica_update_devid(rlp, dnp, setno, &old_cdevidp, 998*0Sstevel@tonic-gate ep) != METADEVADM_SUCCESS) { 999*0Sstevel@tonic-gate metafreereplicalist(rlp); 1000*0Sstevel@tonic-gate return (METADEVADM_ERR); 1001*0Sstevel@tonic-gate } 1002*0Sstevel@tonic-gate 1003*0Sstevel@tonic-gate metafreereplicalist(rlp); 1004*0Sstevel@tonic-gate } 1005*0Sstevel@tonic-gate 1006*0Sstevel@tonic-gate /* 1007*0Sstevel@tonic-gate * If this is not the LOCAL set then need to update the LOCAL 1008*0Sstevel@tonic-gate * replica with the new disk record. 1009*0Sstevel@tonic-gate */ 1010*0Sstevel@tonic-gate 1011*0Sstevel@tonic-gate if (setno != MD_LOCAL_SET) { 1012*0Sstevel@tonic-gate mda_debug("Non-local set: %d side %d\n", setno, side); 1013*0Sstevel@tonic-gate 1014*0Sstevel@tonic-gate /* 1015*0Sstevel@tonic-gate * Need to find the disk record within the set and then 1016*0Sstevel@tonic-gate * update it. 1017*0Sstevel@tonic-gate */ 1018*0Sstevel@tonic-gate if ((dd = 1019*0Sstevel@tonic-gate metaget_drivedesc(*spp, MD_FULLNAME_ONLY, ep)) == NULL) { 1020*0Sstevel@tonic-gate if (! mdisok(ep)) 1021*0Sstevel@tonic-gate goto out; 1022*0Sstevel@tonic-gate /* no disks in the set - no point continuing */ 1023*0Sstevel@tonic-gate mda_debug("No disks in diskset\n"); 1024*0Sstevel@tonic-gate rval = METADEVADM_SUCCESS; 1025*0Sstevel@tonic-gate goto out; 1026*0Sstevel@tonic-gate } 1027*0Sstevel@tonic-gate 1028*0Sstevel@tonic-gate for (ddp = dd; ddp != NULL; ddp = ddp->dd_next) { 1029*0Sstevel@tonic-gate if (strncmp(ddp->dd_dnp->cname, dnp->cname, 1030*0Sstevel@tonic-gate strlen(dnp->cname)) == 0) 1031*0Sstevel@tonic-gate break; 1032*0Sstevel@tonic-gate } 1033*0Sstevel@tonic-gate 1034*0Sstevel@tonic-gate if (ddp == NULL) { 1035*0Sstevel@tonic-gate /* failed to finddisk in the set */ 1036*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1037*0Sstevel@tonic-gate "%s not found in set %s. Check your syntax\n"), 1038*0Sstevel@tonic-gate ctd, (*spp)->setname); 1039*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_DRIVENOTINSET, setno, NULL, 1040*0Sstevel@tonic-gate ctd, (*spp)->setname); 1041*0Sstevel@tonic-gate goto out; 1042*0Sstevel@tonic-gate } 1043*0Sstevel@tonic-gate 1044*0Sstevel@tonic-gate /* 1045*0Sstevel@tonic-gate * Now figure out the correct slice, for a diskset the slice 1046*0Sstevel@tonic-gate * we care about is always the 'replica' slice. 1047*0Sstevel@tonic-gate */ 1048*0Sstevel@tonic-gate if (meta_replicaslice(dnp, &rep_slice, ep) != 0) { 1049*0Sstevel@tonic-gate mda_debug("Unable to find replica slice for %s\n", 1050*0Sstevel@tonic-gate dnp->cname); 1051*0Sstevel@tonic-gate goto out; 1052*0Sstevel@tonic-gate } 1053*0Sstevel@tonic-gate 1054*0Sstevel@tonic-gate mda_debug("slice no: %d disk %s\n", rep_slice, dnp->cname); 1055*0Sstevel@tonic-gate 1056*0Sstevel@tonic-gate if ((np = metaslicename(dnp, rep_slice, ep)) == NULL) { 1057*0Sstevel@tonic-gate mda_debug("Unable to build namespace\n"); 1058*0Sstevel@tonic-gate goto out; 1059*0Sstevel@tonic-gate } 1060*0Sstevel@tonic-gate 1061*0Sstevel@tonic-gate mda_debug("check: ctdname: %s\n", np->cname); 1062*0Sstevel@tonic-gate mda_debug("check: ctdname: %s\n", np->rname); 1063*0Sstevel@tonic-gate mda_debug("check: ctdname: %s\n", np->bname); 1064*0Sstevel@tonic-gate 1065*0Sstevel@tonic-gate if (!(dev_options & DEV_NOACTION)) { 1066*0Sstevel@tonic-gate 1067*0Sstevel@tonic-gate mda_debug("Updating record: key %d name %s\n", 1068*0Sstevel@tonic-gate ddp->dd_dnp->side_names_key, np->cname); 1069*0Sstevel@tonic-gate 1070*0Sstevel@tonic-gate pathname = mda_getpath(np->bname); 1071*0Sstevel@tonic-gate 1072*0Sstevel@tonic-gate if (update_namespace(MD_LOCAL_SET, side + SKEW, 1073*0Sstevel@tonic-gate np->cname, np->dev, ddp->dd_dnp->side_names_key, 1074*0Sstevel@tonic-gate pathname, ep) != 0) { 1075*0Sstevel@tonic-gate goto out; 1076*0Sstevel@tonic-gate } 1077*0Sstevel@tonic-gate 1078*0Sstevel@tonic-gate /* 1079*0Sstevel@tonic-gate * Now update the devid entry as well, this works 1080*0Sstevel@tonic-gate * correctly because the prior call to 1081*0Sstevel@tonic-gate * update_namespace() above puts the correct dev_t 1082*0Sstevel@tonic-gate * in the namespace which will then be resolved 1083*0Sstevel@tonic-gate * to the new devid by the ioctl now called. 1084*0Sstevel@tonic-gate */ 1085*0Sstevel@tonic-gate nm.mde = mdnullerror; 1086*0Sstevel@tonic-gate nm.setno = MD_LOCAL_SET; 1087*0Sstevel@tonic-gate nm.side = side + SKEW; 1088*0Sstevel@tonic-gate nm.key = ddp->dd_dnp->side_names_key; 1089*0Sstevel@tonic-gate if (metaioctl(MD_SETNMDID, &nm, &nm.mde, NULL) != 0) { 1090*0Sstevel@tonic-gate (void) mdstealerror(ep, &nm.mde); 1091*0Sstevel@tonic-gate goto out; 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate } 1094*0Sstevel@tonic-gate } 1095*0Sstevel@tonic-gate 1096*0Sstevel@tonic-gate if ((dev_options & DEV_LOCAL_SET) && (setno != MD_LOCAL_SET)) { 1097*0Sstevel@tonic-gate /* 1098*0Sstevel@tonic-gate * Only want to update the local set so do not continue. 1099*0Sstevel@tonic-gate */ 1100*0Sstevel@tonic-gate rval = METADEVADM_SUCCESS; 1101*0Sstevel@tonic-gate goto out; 1102*0Sstevel@tonic-gate } 1103*0Sstevel@tonic-gate 1104*0Sstevel@tonic-gate /* 1105*0Sstevel@tonic-gate * Iterate through all of the metadevices looking for the 1106*0Sstevel@tonic-gate * passed in ctd. If found then update the devid 1107*0Sstevel@tonic-gate */ 1108*0Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm)); 1109*0Sstevel@tonic-gate nm.key = MD_KEYWILD; 1110*0Sstevel@tonic-gate /* LINTED */ 1111*0Sstevel@tonic-gate while (1) { 1112*0Sstevel@tonic-gate nm.mde = mdnullerror; 1113*0Sstevel@tonic-gate nm.setno = setno; 1114*0Sstevel@tonic-gate nm.side = side; 1115*0Sstevel@tonic-gate 1116*0Sstevel@tonic-gate /* search each namespace entry */ 1117*0Sstevel@tonic-gate if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde, NULL) != 0) { 1118*0Sstevel@tonic-gate (void) mdstealerror(ep, &nm.mde); 1119*0Sstevel@tonic-gate rval = METADEVADM_ERR; 1120*0Sstevel@tonic-gate goto out; 1121*0Sstevel@tonic-gate } 1122*0Sstevel@tonic-gate if (nm.key == MD_KEYWILD) { 1123*0Sstevel@tonic-gate if (setno != MD_LOCAL_SET) { 1124*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1125*0Sstevel@tonic-gate "%s not found in set %s. Check your " 1126*0Sstevel@tonic-gate "syntax\n"), ctd, (*spp)->setname); 1127*0Sstevel@tonic-gate goto out; 1128*0Sstevel@tonic-gate } else { 1129*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1130*0Sstevel@tonic-gate "%s not found in local set. " 1131*0Sstevel@tonic-gate "Check your syntax\n"), ctd); 1132*0Sstevel@tonic-gate goto out; 1133*0Sstevel@tonic-gate } 1134*0Sstevel@tonic-gate } 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate nm.devname = (uintptr_t)meta_getnmentbykey(setno, side, nm.key, 1137*0Sstevel@tonic-gate NULL, NULL, NULL, ep); 1138*0Sstevel@tonic-gate if (nm.devname == NULL) { 1139*0Sstevel@tonic-gate rval = METADEVADM_ERR; 1140*0Sstevel@tonic-gate goto out; 1141*0Sstevel@tonic-gate } 1142*0Sstevel@tonic-gate 1143*0Sstevel@tonic-gate diskname = getdiskname((char *)nm.devname); 1144*0Sstevel@tonic-gate 1145*0Sstevel@tonic-gate mda_debug("Checking %s with %s\n", diskname, dnp->cname); 1146*0Sstevel@tonic-gate if (strcmp(diskname, dnp->cname) != 0) 1147*0Sstevel@tonic-gate continue; 1148*0Sstevel@tonic-gate 1149*0Sstevel@tonic-gate mda_debug("Updating device %s in namespace\n", 1150*0Sstevel@tonic-gate (char *)nm.devname); 1151*0Sstevel@tonic-gate 1152*0Sstevel@tonic-gate /* 1153*0Sstevel@tonic-gate * found disk, does it have a devid within the namespace ? 1154*0Sstevel@tonic-gate * It might not because it does not support devid's or was 1155*0Sstevel@tonic-gate * put into the namespace when there was no devid support 1156*0Sstevel@tonic-gate */ 1157*0Sstevel@tonic-gate if ((devidp = has_devid(setno, side, nm.key, ep)) == NULL) { 1158*0Sstevel@tonic-gate mda_debug("%s has no devid in the namespace", 1159*0Sstevel@tonic-gate (char *)nm.devname); 1160*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 1161*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1162*0Sstevel@tonic-gate "SVM has no device id for " 1163*0Sstevel@tonic-gate "%s, cannot update.\n"), (char *)nm.devname); 1164*0Sstevel@tonic-gate } 1165*0Sstevel@tonic-gate continue; /* no devid. go on to next */ 1166*0Sstevel@tonic-gate } 1167*0Sstevel@tonic-gate if (old_cdevidp == NULL) { 1168*0Sstevel@tonic-gate old_cdevidp = devid_str_encode(devidp, NULL); 1169*0Sstevel@tonic-gate } 1170*0Sstevel@tonic-gate free(devidp); 1171*0Sstevel@tonic-gate 1172*0Sstevel@tonic-gate /* 1173*0Sstevel@tonic-gate * has devid so update namespace, note the key has been set 1174*0Sstevel@tonic-gate * by the prior MD_IOCNXTKEY_NM ioctl. 1175*0Sstevel@tonic-gate */ 1176*0Sstevel@tonic-gate nm.mde = mdnullerror; 1177*0Sstevel@tonic-gate nm.setno = setno; 1178*0Sstevel@tonic-gate nm.side = side; 1179*0Sstevel@tonic-gate if (!(dev_options & DEV_NOACTION)) { 1180*0Sstevel@tonic-gate /* 1181*0Sstevel@tonic-gate * The call below may fail if the -u option is being 1182*0Sstevel@tonic-gate * used to update a disk that has been replaced. 1183*0Sstevel@tonic-gate * The -u option to metadevadm should not be used 1184*0Sstevel@tonic-gate * for this purpose because we trust the dev_t of 1185*0Sstevel@tonic-gate * the device in the replica and if we have replaced 1186*0Sstevel@tonic-gate * the device and it is a fibre one then the dev_t 1187*0Sstevel@tonic-gate * will have changed. This means we end up looking for 1188*0Sstevel@tonic-gate * the devid of a non-existant disk and we subsequently 1189*0Sstevel@tonic-gate * fail with NODEVID. 1190*0Sstevel@tonic-gate */ 1191*0Sstevel@tonic-gate if (metaioctl(MD_SETNMDID, &nm, 1192*0Sstevel@tonic-gate &nm.mde, NULL) != 0) { 1193*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 1194*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1195*0Sstevel@tonic-gate "SVM failed to update the device " 1196*0Sstevel@tonic-gate "id for %s probably due to both " 1197*0Sstevel@tonic-gate "devt and device id changing.\n"), 1198*0Sstevel@tonic-gate (char *)nm.devname); 1199*0Sstevel@tonic-gate } 1200*0Sstevel@tonic-gate (void) mdstealerror(ep, &nm.mde); 1201*0Sstevel@tonic-gate mde_perror(ep, ""); 1202*0Sstevel@tonic-gate rval = METADEVADM_ERR; 1203*0Sstevel@tonic-gate goto out; 1204*0Sstevel@tonic-gate } 1205*0Sstevel@tonic-gate } 1206*0Sstevel@tonic-gate if (old_cdevidp == NULL) { 1207*0Sstevel@tonic-gate rval = METADEVADM_ERR; 1208*0Sstevel@tonic-gate goto out; 1209*0Sstevel@tonic-gate } 1210*0Sstevel@tonic-gate break; 1211*0Sstevel@tonic-gate } /* end while */ 1212*0Sstevel@tonic-gate 1213*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1214*0Sstevel@tonic-gate "Updating Solaris Volume Manager device relocation " 1215*0Sstevel@tonic-gate "information for %s\n"), ctd); 1216*0Sstevel@tonic-gate 1217*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1218*0Sstevel@tonic-gate "Old device reloc information:\n\t%s\n"), old_cdevidp); 1219*0Sstevel@tonic-gate 1220*0Sstevel@tonic-gate len = strlen(dnp->rname) + strlen("s0"); 1221*0Sstevel@tonic-gate if ((fp = (char *)Malloc(len + 1)) == NULL) { 1222*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1223*0Sstevel@tonic-gate "insufficient memory, device Reloc info not " 1224*0Sstevel@tonic-gate "available\n")); 1225*0Sstevel@tonic-gate } else { 1226*0Sstevel@tonic-gate (void) snprintf(fp, len + 1, "%ss0", dnp->rname); 1227*0Sstevel@tonic-gate if ((fd = open(fp, O_RDONLY|O_NDELAY)) < 0) { 1228*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1229*0Sstevel@tonic-gate "Open of %s failed\n"), fp); 1230*0Sstevel@tonic-gate } else { 1231*0Sstevel@tonic-gate int rc = -1; 1232*0Sstevel@tonic-gate ddi_devid_t devid1 = NULL; 1233*0Sstevel@tonic-gate char *cdevidp; 1234*0Sstevel@tonic-gate 1235*0Sstevel@tonic-gate rc = devid_get(fd, &devid1); 1236*0Sstevel@tonic-gate if (close(fd) < 0) { 1237*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1238*0Sstevel@tonic-gate "Close of %s failed\n"), fp); 1239*0Sstevel@tonic-gate } 1240*0Sstevel@tonic-gate if (rc != 0) { 1241*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1242*0Sstevel@tonic-gate "Unable to obtain device " 1243*0Sstevel@tonic-gate "Reloc info for %s\n"), fp); 1244*0Sstevel@tonic-gate } else { 1245*0Sstevel@tonic-gate cdevidp = devid_str_encode(devid1, NULL); 1246*0Sstevel@tonic-gate if (cdevidp == NULL) { 1247*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1248*0Sstevel@tonic-gate "Unable to print " 1249*0Sstevel@tonic-gate "device Reloc info for %s\n"), fp); 1250*0Sstevel@tonic-gate } else { 1251*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1252*0Sstevel@tonic-gate "New device reloc " 1253*0Sstevel@tonic-gate "information:\n\t%s\n"), cdevidp); 1254*0Sstevel@tonic-gate devid_str_free(cdevidp); 1255*0Sstevel@tonic-gate } 1256*0Sstevel@tonic-gate devid_free(devid1); 1257*0Sstevel@tonic-gate } 1258*0Sstevel@tonic-gate } 1259*0Sstevel@tonic-gate Free(fp); 1260*0Sstevel@tonic-gate } 1261*0Sstevel@tonic-gate 1262*0Sstevel@tonic-gate rval = METADEVADM_SUCCESS; 1263*0Sstevel@tonic-gate 1264*0Sstevel@tonic-gate out: 1265*0Sstevel@tonic-gate if (diskname) 1266*0Sstevel@tonic-gate Free(diskname); 1267*0Sstevel@tonic-gate if (pathname) 1268*0Sstevel@tonic-gate Free(pathname); 1269*0Sstevel@tonic-gate if (old_cdevidp) { 1270*0Sstevel@tonic-gate devid_str_free(old_cdevidp); 1271*0Sstevel@tonic-gate } 1272*0Sstevel@tonic-gate return (rval); 1273*0Sstevel@tonic-gate 1274*0Sstevel@tonic-gate } 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate /* 1277*0Sstevel@tonic-gate * Check the ctd name of the disk to see if the disk has moved. If it 1278*0Sstevel@tonic-gate * has moved then the newname is returned in 'newname', it is up to 1279*0Sstevel@tonic-gate * the caller to free the memory associated with it. 1280*0Sstevel@tonic-gate * 1281*0Sstevel@tonic-gate * RETURN 1282*0Sstevel@tonic-gate * METADEVADM_ERR error 1283*0Sstevel@tonic-gate * METADEVADM_SUCCESS success 1284*0Sstevel@tonic-gate * METADEVADM_DISKMOVE success, and the disk has moved 1285*0Sstevel@tonic-gate * METADEVADM_DSKNAME_ERR error creating the disk name structures. 1286*0Sstevel@tonic-gate */ 1287*0Sstevel@tonic-gate int 1288*0Sstevel@tonic-gate meta_upd_ctdnames( 1289*0Sstevel@tonic-gate mdsetname_t **spp, 1290*0Sstevel@tonic-gate set_t setno, 1291*0Sstevel@tonic-gate side_t sideno, 1292*0Sstevel@tonic-gate mddrivename_t *dnp, 1293*0Sstevel@tonic-gate char **newname, 1294*0Sstevel@tonic-gate md_error_t *ep 1295*0Sstevel@tonic-gate ) 1296*0Sstevel@tonic-gate { 1297*0Sstevel@tonic-gate char *drvnmp; 1298*0Sstevel@tonic-gate int i; 1299*0Sstevel@tonic-gate minor_t mnum = 0; 1300*0Sstevel@tonic-gate md_dev64_t dev = 0; 1301*0Sstevel@tonic-gate dev_t small_dev = (dev_t)NODEV; 1302*0Sstevel@tonic-gate mdnm_params_t nm; 1303*0Sstevel@tonic-gate char *pathname; 1304*0Sstevel@tonic-gate char *minor_name = NULL; 1305*0Sstevel@tonic-gate ddi_devid_t devidp; 1306*0Sstevel@tonic-gate devid_nmlist_t *disklist = NULL; 1307*0Sstevel@tonic-gate int ret = 0; 1308*0Sstevel@tonic-gate mdsidenames_t *snp; 1309*0Sstevel@tonic-gate int match_type; 1310*0Sstevel@tonic-gate int search_number = -1; 1311*0Sstevel@tonic-gate char *search_type = NULL; 1312*0Sstevel@tonic-gate char *search_path = NULL; 1313*0Sstevel@tonic-gate uint_t rep_slice; 1314*0Sstevel@tonic-gate mddrivename_t *newdnp; 1315*0Sstevel@tonic-gate mdname_t *np; 1316*0Sstevel@tonic-gate mdsetname_t *sp = *spp; 1317*0Sstevel@tonic-gate md_set_desc *sd; 1318*0Sstevel@tonic-gate 1319*0Sstevel@tonic-gate /* 1320*0Sstevel@tonic-gate * setno should always be 0 but we're going to 1321*0Sstevel@tonic-gate * check for multi-node diskset and return if it is one. 1322*0Sstevel@tonic-gate */ 1323*0Sstevel@tonic-gate if (!metaislocalset(sp)) { 1324*0Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) 1325*0Sstevel@tonic-gate return (METADEVADM_ERR); 1326*0Sstevel@tonic-gate 1327*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 1328*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 1329*0Sstevel@tonic-gate } 1330*0Sstevel@tonic-gate 1331*0Sstevel@tonic-gate if (dnp->devid == NULL) { 1332*0Sstevel@tonic-gate /* no devid, nothing can be done */ 1333*0Sstevel@tonic-gate mda_debug("meta_upd_ctdnames: %s has no devid\n", dnp->cname); 1334*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 1335*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1336*0Sstevel@tonic-gate "%s has no devid, cannot detect " 1337*0Sstevel@tonic-gate "disk movement for this disk.\n"), dnp->cname); 1338*0Sstevel@tonic-gate } 1339*0Sstevel@tonic-gate return (ret); 1340*0Sstevel@tonic-gate } 1341*0Sstevel@tonic-gate 1342*0Sstevel@tonic-gate /* 1343*0Sstevel@tonic-gate * Find the correct side name for the disk. There is a sidename 1344*0Sstevel@tonic-gate * for each host associated with the diskset. 1345*0Sstevel@tonic-gate */ 1346*0Sstevel@tonic-gate for (snp = dnp->side_names; snp != NULL; snp = snp->next) { 1347*0Sstevel@tonic-gate mda_debug("meta_upd_ctdnames: %s %d args: setno %d sideno %d\n", 1348*0Sstevel@tonic-gate snp->cname, snp->sideno, setno, sideno); 1349*0Sstevel@tonic-gate /* only use SKEW for the local replica */ 1350*0Sstevel@tonic-gate if (setno == 0) { 1351*0Sstevel@tonic-gate if (snp->sideno + SKEW == sideno) 1352*0Sstevel@tonic-gate break; 1353*0Sstevel@tonic-gate } else { 1354*0Sstevel@tonic-gate if (snp->sideno == sideno) 1355*0Sstevel@tonic-gate break; 1356*0Sstevel@tonic-gate } 1357*0Sstevel@tonic-gate } 1358*0Sstevel@tonic-gate 1359*0Sstevel@tonic-gate if (snp == NULL) { 1360*0Sstevel@tonic-gate /* 1361*0Sstevel@tonic-gate * Failed to find the side name, this should not 1362*0Sstevel@tonic-gate * be possible. However if it does happen this is an 1363*0Sstevel@tonic-gate * indication of an inconsistant replica - something 1364*0Sstevel@tonic-gate * might have gone wrong during an add or a delete of 1365*0Sstevel@tonic-gate * a host. 1366*0Sstevel@tonic-gate */ 1367*0Sstevel@tonic-gate mda_debug("Unable to find the side information for disk %s", 1368*0Sstevel@tonic-gate dnp->cname); 1369*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE, (*spp)->setno, mynode(), 1370*0Sstevel@tonic-gate NULL, dnp->cname); 1371*0Sstevel@tonic-gate return (METADEVADM_ERR); 1372*0Sstevel@tonic-gate } 1373*0Sstevel@tonic-gate /* 1374*0Sstevel@tonic-gate * Find the type of device we are to be searching on 1375*0Sstevel@tonic-gate */ 1376*0Sstevel@tonic-gate search_number = mda_findpath(snp->cname); 1377*0Sstevel@tonic-gate if (search_number == -1) { 1378*0Sstevel@tonic-gate search_path = "/dev"; 1379*0Sstevel@tonic-gate search_type = DEVID_MINOR_NAME_ALL; 1380*0Sstevel@tonic-gate } else { 1381*0Sstevel@tonic-gate search_path = plist[search_number].search_path; 1382*0Sstevel@tonic-gate search_type = plist[search_number].search_type; 1383*0Sstevel@tonic-gate } 1384*0Sstevel@tonic-gate 1385*0Sstevel@tonic-gate mda_debug("Search path :%s searth_type: %x\n", 1386*0Sstevel@tonic-gate search_path, (int)search_type); 1387*0Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm)); 1388*0Sstevel@tonic-gate 1389*0Sstevel@tonic-gate nm.mde = mdnullerror; 1390*0Sstevel@tonic-gate nm.setno = setno; 1391*0Sstevel@tonic-gate nm.side = sideno; 1392*0Sstevel@tonic-gate 1393*0Sstevel@tonic-gate /* 1394*0Sstevel@tonic-gate * Get the devname from the name space. 1395*0Sstevel@tonic-gate */ 1396*0Sstevel@tonic-gate if ((nm.devname = (uintptr_t)meta_getnmentbykey(setno, sideno, 1397*0Sstevel@tonic-gate dnp->side_names_key, &drvnmp, &mnum, &dev, ep)) == NULL) { 1398*0Sstevel@tonic-gate return (METADEVADM_ERR); 1399*0Sstevel@tonic-gate } 1400*0Sstevel@tonic-gate 1401*0Sstevel@tonic-gate ret = devid_str_decode(dnp->devid, &devidp, &minor_name); 1402*0Sstevel@tonic-gate devid_str_free(minor_name); 1403*0Sstevel@tonic-gate 1404*0Sstevel@tonic-gate if (ret != 0) { 1405*0Sstevel@tonic-gate /* 1406*0Sstevel@tonic-gate * Failed to encode the devid. 1407*0Sstevel@tonic-gate */ 1408*0Sstevel@tonic-gate devid_free(devidp); 1409*0Sstevel@tonic-gate return (METADEVADM_ERR); 1410*0Sstevel@tonic-gate } 1411*0Sstevel@tonic-gate 1412*0Sstevel@tonic-gate /* 1413*0Sstevel@tonic-gate * Use the stored devid to find the existing device node and check 1414*0Sstevel@tonic-gate * to see if the disk has moved. Use the raw devices as the name 1415*0Sstevel@tonic-gate * of the disk is stored as the raw device, if this is not done 1416*0Sstevel@tonic-gate * then the disk will not be found. 1417*0Sstevel@tonic-gate */ 1418*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist(search_path, devidp, 1419*0Sstevel@tonic-gate search_type, &disklist); 1420*0Sstevel@tonic-gate 1421*0Sstevel@tonic-gate if (ret != 0) { 1422*0Sstevel@tonic-gate if (dev_options & DEV_VERBOSE) { 1423*0Sstevel@tonic-gate mda_print(dgettext(TEXT_DOMAIN, 1424*0Sstevel@tonic-gate "Device ID %s last associated with " 1425*0Sstevel@tonic-gate "disk %s no longer found in system\n"), 1426*0Sstevel@tonic-gate dnp->devid, dnp->cname); 1427*0Sstevel@tonic-gate } 1428*0Sstevel@tonic-gate devid_free(devidp); 1429*0Sstevel@tonic-gate devid_free_nmlist(disklist); 1430*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 1431*0Sstevel@tonic-gate } 1432*0Sstevel@tonic-gate 1433*0Sstevel@tonic-gate small_dev = meta_cmpldev(dev); 1434*0Sstevel@tonic-gate mda_debug("Old device lookup: %s (%p)\n", 1435*0Sstevel@tonic-gate (char *)nm.devname, (void *)small_dev); 1436*0Sstevel@tonic-gate /* 1437*0Sstevel@tonic-gate * Check to see if the returned disk matches the stored one 1438*0Sstevel@tonic-gate */ 1439*0Sstevel@tonic-gate for (i = 0; disklist[i].dev != NODEV; i++) { 1440*0Sstevel@tonic-gate match_type = 0; 1441*0Sstevel@tonic-gate mda_debug("From devid lookup: %s (%p)\n", 1442*0Sstevel@tonic-gate disklist[i].devname, (void *)disklist[i].dev); 1443*0Sstevel@tonic-gate 1444*0Sstevel@tonic-gate if (disklist[i].dev == small_dev) { 1445*0Sstevel@tonic-gate match_type |= DEV_MATCH; 1446*0Sstevel@tonic-gate } 1447*0Sstevel@tonic-gate 1448*0Sstevel@tonic-gate if (strncmp((char *)nm.devname, disklist[i].devname, 1449*0Sstevel@tonic-gate strlen((char *)nm.devname)) == 0) { 1450*0Sstevel@tonic-gate match_type |= NAME_MATCH; 1451*0Sstevel@tonic-gate } 1452*0Sstevel@tonic-gate 1453*0Sstevel@tonic-gate if (match_type != 0) 1454*0Sstevel@tonic-gate break; 1455*0Sstevel@tonic-gate } 1456*0Sstevel@tonic-gate devid_free(devidp); 1457*0Sstevel@tonic-gate 1458*0Sstevel@tonic-gate mda_debug("meta_upd_ctdnames: match: %x i: %d\n", match_type, i); 1459*0Sstevel@tonic-gate 1460*0Sstevel@tonic-gate if (match_type == (DEV_MATCH|NAME_MATCH)) { 1461*0Sstevel@tonic-gate /* no change */ 1462*0Sstevel@tonic-gate devid_free_nmlist(disklist); 1463*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 1464*0Sstevel@tonic-gate } 1465*0Sstevel@tonic-gate 1466*0Sstevel@tonic-gate /* No match found - use the first entry in disklist */ 1467*0Sstevel@tonic-gate if (disklist[i].dev == NODEV) 1468*0Sstevel@tonic-gate i = 0; 1469*0Sstevel@tonic-gate 1470*0Sstevel@tonic-gate if (!(match_type & DEV_MATCH)) { 1471*0Sstevel@tonic-gate /* did not match on the dev, so dev_t has changed */ 1472*0Sstevel@tonic-gate mda_debug("Did not match on dev: %p %p\n", 1473*0Sstevel@tonic-gate (void *) small_dev, (void *) disklist[i].dev); 1474*0Sstevel@tonic-gate dev = meta_expldev(disklist[i].dev); 1475*0Sstevel@tonic-gate } 1476*0Sstevel@tonic-gate 1477*0Sstevel@tonic-gate if (!(match_type & NAME_MATCH)) { 1478*0Sstevel@tonic-gate mda_debug("Did not match on name: %s (%p)\n", 1479*0Sstevel@tonic-gate (char *)nm.devname, (void *) disklist[i].dev); 1480*0Sstevel@tonic-gate } 1481*0Sstevel@tonic-gate 1482*0Sstevel@tonic-gate /* 1483*0Sstevel@tonic-gate * If here, then the name in the disklist is the one we 1484*0Sstevel@tonic-gate * want in any case so use it. 1485*0Sstevel@tonic-gate */ 1486*0Sstevel@tonic-gate mda_debug("devname: %s\n", disklist[i].devname); 1487*0Sstevel@tonic-gate /* 1488*0Sstevel@tonic-gate * Need to remove the slice as metadrivename() expects a diskname 1489*0Sstevel@tonic-gate */ 1490*0Sstevel@tonic-gate stripS(disklist[i].devname); 1491*0Sstevel@tonic-gate /* 1492*0Sstevel@tonic-gate * Build an mddrivename_t to use 1493*0Sstevel@tonic-gate */ 1494*0Sstevel@tonic-gate if ((newdnp = metadrivename(spp, disklist[i].devname, ep)) == NULL) { 1495*0Sstevel@tonic-gate mda_debug("Unable to make a dnp out of %s\n", 1496*0Sstevel@tonic-gate disklist[i].devname); 1497*0Sstevel@tonic-gate return (METADEVADM_DSKNAME_ERR); 1498*0Sstevel@tonic-gate } 1499*0Sstevel@tonic-gate /* 1500*0Sstevel@tonic-gate * Need to find the correct slice used for the replica 1501*0Sstevel@tonic-gate */ 1502*0Sstevel@tonic-gate if (meta_replicaslice(newdnp, &rep_slice, ep) != 0) { 1503*0Sstevel@tonic-gate return (METADEVADM_DSKNAME_ERR); 1504*0Sstevel@tonic-gate } 1505*0Sstevel@tonic-gate 1506*0Sstevel@tonic-gate if ((np = metaslicename(newdnp, rep_slice, ep)) == NULL) { 1507*0Sstevel@tonic-gate mda_debug("Failed to build an np for %s\n", dnp->rname); 1508*0Sstevel@tonic-gate return (METADEVADM_DSKNAME_ERR); 1509*0Sstevel@tonic-gate } 1510*0Sstevel@tonic-gate mda_debug("check: cname: %s\n", np->cname); 1511*0Sstevel@tonic-gate mda_debug("check: rname: %s\n", np->rname); 1512*0Sstevel@tonic-gate mda_debug("check: bname: %s\n", np->bname); 1513*0Sstevel@tonic-gate 1514*0Sstevel@tonic-gate if (newname != NULL) 1515*0Sstevel@tonic-gate *newname = Strdup(np->bname); 1516*0Sstevel@tonic-gate 1517*0Sstevel@tonic-gate if (!(dev_options & DEV_NOACTION)) { 1518*0Sstevel@tonic-gate 1519*0Sstevel@tonic-gate mda_debug("update namespace\n"); 1520*0Sstevel@tonic-gate 1521*0Sstevel@tonic-gate /* get the block path */ 1522*0Sstevel@tonic-gate pathname = mda_getpath(np->bname); 1523*0Sstevel@tonic-gate 1524*0Sstevel@tonic-gate if (update_namespace(setno, sideno, np->cname, 1525*0Sstevel@tonic-gate dev, dnp->side_names_key, pathname, ep) != 0) { 1526*0Sstevel@tonic-gate /* finished with the list so return the memory */ 1527*0Sstevel@tonic-gate Free(pathname); 1528*0Sstevel@tonic-gate devid_free_nmlist(disklist); 1529*0Sstevel@tonic-gate return (METADEVADM_ERR); 1530*0Sstevel@tonic-gate } 1531*0Sstevel@tonic-gate } 1532*0Sstevel@tonic-gate /* finished with the list so return the memory */ 1533*0Sstevel@tonic-gate Free(pathname); 1534*0Sstevel@tonic-gate devid_free_nmlist(disklist); 1535*0Sstevel@tonic-gate ret = METADEVADM_DISKMOVE; 1536*0Sstevel@tonic-gate return (ret); 1537*0Sstevel@tonic-gate } 1538*0Sstevel@tonic-gate 1539*0Sstevel@tonic-gate int 1540*0Sstevel@tonic-gate meta_fixdevid( 1541*0Sstevel@tonic-gate mdsetname_t *sp, 1542*0Sstevel@tonic-gate mddevopts_t options, 1543*0Sstevel@tonic-gate char *diskname, 1544*0Sstevel@tonic-gate md_error_t *ep 1545*0Sstevel@tonic-gate ) 1546*0Sstevel@tonic-gate { 1547*0Sstevel@tonic-gate set_t setno = sp->setno; 1548*0Sstevel@tonic-gate int ret = 0; 1549*0Sstevel@tonic-gate char *pathname = NULL; 1550*0Sstevel@tonic-gate mdsetname_t *local_sp = NULL; 1551*0Sstevel@tonic-gate md_drive_desc *d = NULL; 1552*0Sstevel@tonic-gate char *newname = NULL; 1553*0Sstevel@tonic-gate md_drive_desc *dd; 1554*0Sstevel@tonic-gate side_t sideno; 1555*0Sstevel@tonic-gate md_set_desc *sd; 1556*0Sstevel@tonic-gate 1557*0Sstevel@tonic-gate /* if MN diskset just return */ 1558*0Sstevel@tonic-gate if (!metaislocalset(sp)) { 1559*0Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) == NULL) { 1560*0Sstevel@tonic-gate return (METADEVADM_ERR); 1561*0Sstevel@tonic-gate } 1562*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) 1563*0Sstevel@tonic-gate return (METADEVADM_SUCCESS); 1564*0Sstevel@tonic-gate } 1565*0Sstevel@tonic-gate 1566*0Sstevel@tonic-gate dev_options |= options; 1567*0Sstevel@tonic-gate mda_debug("dev_options: %x\n", dev_options); 1568*0Sstevel@tonic-gate if (dev_options & DEV_RELOAD) { 1569*0Sstevel@tonic-gate /* 1570*0Sstevel@tonic-gate * If it's not the local set we need to check the local 1571*0Sstevel@tonic-gate * namespace to see if disks have moved as it contains 1572*0Sstevel@tonic-gate * entries for the disks in the set. 1573*0Sstevel@tonic-gate */ 1574*0Sstevel@tonic-gate if (setno != MD_LOCAL_SET) { 1575*0Sstevel@tonic-gate if ((dd = metaget_drivedesc(sp, MD_BASICNAME_OK | 1576*0Sstevel@tonic-gate PRINT_FAST, ep)) == NULL) { 1577*0Sstevel@tonic-gate mde_perror(ep, ""); 1578*0Sstevel@tonic-gate mdclrerror(ep); 1579*0Sstevel@tonic-gate return (METADEVADM_ERR); 1580*0Sstevel@tonic-gate } 1581*0Sstevel@tonic-gate local_sp = metasetname(MD_LOCAL_NAME, ep); 1582*0Sstevel@tonic-gate sideno = getmyside(sp, ep) + SKEW; 1583*0Sstevel@tonic-gate for (d = dd; d != NULL; d = d->dd_next) { 1584*0Sstevel@tonic-gate /* 1585*0Sstevel@tonic-gate * Actually do the check of the disks. 1586*0Sstevel@tonic-gate */ 1587*0Sstevel@tonic-gate ret = meta_upd_ctdnames(&local_sp, 0, sideno, 1588*0Sstevel@tonic-gate d->dd_dnp, &newname, ep); 1589*0Sstevel@tonic-gate 1590*0Sstevel@tonic-gate if ((ret == METADEVADM_ERR) || 1591*0Sstevel@tonic-gate (ret == METADEVADM_DSKNAME_ERR)) { 1592*0Sstevel@tonic-gate /* check failed in unknown manner */ 1593*0Sstevel@tonic-gate mda_debug("meta_upd_ctdnames failed\n"); 1594*0Sstevel@tonic-gate return (METADEVADM_ERR); 1595*0Sstevel@tonic-gate } 1596*0Sstevel@tonic-gate } 1597*0Sstevel@tonic-gate } 1598*0Sstevel@tonic-gate 1599*0Sstevel@tonic-gate /* do a reload of the devid namespace */ 1600*0Sstevel@tonic-gate ret = pathname_reload(&sp, setno, ep); 1601*0Sstevel@tonic-gate } else if (dev_options & DEV_UPDATE) { 1602*0Sstevel@tonic-gate pathname = getdiskname(diskname); 1603*0Sstevel@tonic-gate ret = devid_update(&sp, setno, pathname, ep); 1604*0Sstevel@tonic-gate free(pathname); 1605*0Sstevel@tonic-gate } 1606*0Sstevel@tonic-gate return (ret); 1607*0Sstevel@tonic-gate } 1608