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 2005 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 "metad_local.h" 30*0Sstevel@tonic-gate #include <metad.h> 31*0Sstevel@tonic-gate #include <sys/lvm/md_mddb.h> 32*0Sstevel@tonic-gate #include <sdssc.h> 33*0Sstevel@tonic-gate #include <sys/lvm/md_mirror.h> 34*0Sstevel@tonic-gate #include <syslog.h> 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h> 37*0Sstevel@tonic-gate #include <sys/sysevent/svm.h> 38*0Sstevel@tonic-gate #include <thread.h> 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #define MDDOORS "/usr/lib/lvm/mddoors" 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate /* 43*0Sstevel@tonic-gate * rpc.metad daemon 44*0Sstevel@tonic-gate * 45*0Sstevel@tonic-gate * The rpc.metad deamon supports two versions of the svm rpc calls - version 1 46*0Sstevel@tonic-gate * and version 2. The over-the-wire structures sent as part of these rpc calls 47*0Sstevel@tonic-gate * are also versioned - version 1 and version 2 exist. It must be noted that 48*0Sstevel@tonic-gate * the version 2 structures have sub-versions or revisions as well. The 49*0Sstevel@tonic-gate * revisions in the version 2 structures allow for flexiblility in changing 50*0Sstevel@tonic-gate * over the wire structures without creating a new version of the svm rpc 51*0Sstevel@tonic-gate * calls. No changes may be made to the version 1 routines or structures used 52*0Sstevel@tonic-gate * by these routines. 53*0Sstevel@tonic-gate * 54*0Sstevel@tonic-gate * If, for example, the version 2 mdrpc_devinfo_args over the wire structure 55*0Sstevel@tonic-gate * (mdrpc_devinfo_2_args*) is changed then the structure change must be 56*0Sstevel@tonic-gate * accompanied by the following: 57*0Sstevel@tonic-gate * 58*0Sstevel@tonic-gate * Header file changes: 59*0Sstevel@tonic-gate * . May need to introduce a new structure revision MD_METAD_ARGS_REV_X, where 60*0Sstevel@tonic-gate * X is the revision number. 61*0Sstevel@tonic-gate * . Create mdrpc_devinfo_2_args_rX, where X is the new revision of the 62*0Sstevel@tonic-gate * structure. 63*0Sstevel@tonic-gate * . Add a switch statement in mdrpc_devinfo_2_args. 64*0Sstevel@tonic-gate * 65*0Sstevel@tonic-gate * rpc.metad changes: 66*0Sstevel@tonic-gate * . Check for the structure revision in the appropriate mdrpc_devinfo_svc 67*0Sstevel@tonic-gate * routine (mdrpc_devinfo_2_svc). 68*0Sstevel@tonic-gate * 69*0Sstevel@tonic-gate * libmeta changes: 70*0Sstevel@tonic-gate * . In the libmeta code that makes the mdrpc_devinfo rpc call, the arguments 71*0Sstevel@tonic-gate * being passed as part of this call (namely mdrpc_devinfo_Y_args) must have 72*0Sstevel@tonic-gate * the revision field and associated structure populated correctly. 73*0Sstevel@tonic-gate */ 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate static md_setkey_t *my_svc_sk = NULL; 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate /* 78*0Sstevel@tonic-gate * Add namespace entry to local mddb for using given sideno, key 79*0Sstevel@tonic-gate * and names. 80*0Sstevel@tonic-gate */ 81*0Sstevel@tonic-gate static int 82*0Sstevel@tonic-gate add_sideno_sidenm( 83*0Sstevel@tonic-gate mdsidenames_t *sidenms, 84*0Sstevel@tonic-gate mdkey_t local_key, 85*0Sstevel@tonic-gate side_t sideno, 86*0Sstevel@tonic-gate md_set_desc *sd, /* Only used with Version 2 */ 87*0Sstevel@tonic-gate md_error_t *ep 88*0Sstevel@tonic-gate ) 89*0Sstevel@tonic-gate { 90*0Sstevel@tonic-gate mdsidenames_t *sn; 91*0Sstevel@tonic-gate mdsetname_t *local_sp; 92*0Sstevel@tonic-gate char *nm; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 95*0Sstevel@tonic-gate return (-1); 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate for (sn = sidenms; sn != NULL; sn = sn->next) 98*0Sstevel@tonic-gate if (sn->sideno == sideno) 99*0Sstevel@tonic-gate break; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate assert(sn != NULL); 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate /* 105*0Sstevel@tonic-gate * SKEW will be used on the traditional diskset despite of the 106*0Sstevel@tonic-gate * rpc version. SKEW is not used on the multinode diskset 107*0Sstevel@tonic-gate */ 108*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) { 109*0Sstevel@tonic-gate nm = meta_getnmbykey(MD_LOCAL_SET, sideno, local_key, ep); 110*0Sstevel@tonic-gate } else { 111*0Sstevel@tonic-gate nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW, local_key, ep); 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate if (nm == NULL) { 115*0Sstevel@tonic-gate if (! mdisok(ep)) { 116*0Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT)) 117*0Sstevel@tonic-gate return (-1); 118*0Sstevel@tonic-gate mdclrerror(ep); 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate /* 122*0Sstevel@tonic-gate * Ignore returned key from add_name, only care about errs 123*0Sstevel@tonic-gate * 124*0Sstevel@tonic-gate * SKEW is used for a regular diskset since sideno could 125*0Sstevel@tonic-gate * have a value of 0 in that diskset type. add_name is 126*0Sstevel@tonic-gate * writing to the local mddb and a sideno of 0 in the 127*0Sstevel@tonic-gate * local mddb is reserved for non-diskset names. 128*0Sstevel@tonic-gate * SKEW is added to the sideno in the local mddb so that 129*0Sstevel@tonic-gate * the sideno for the diskset will never be 0. 130*0Sstevel@tonic-gate * 131*0Sstevel@tonic-gate * In a MNdiskset, the sideno will never be 0 (by design). 132*0Sstevel@tonic-gate * So, no SKEW is needed when writing to the local mddb. 133*0Sstevel@tonic-gate */ 134*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) { 135*0Sstevel@tonic-gate if (add_name(local_sp, sideno, local_key, 136*0Sstevel@tonic-gate sn->dname, sn->mnum, sn->cname, ep) == -1) 137*0Sstevel@tonic-gate return (-1); 138*0Sstevel@tonic-gate } else { 139*0Sstevel@tonic-gate if (add_name(local_sp, sideno+SKEW, local_key, 140*0Sstevel@tonic-gate sn->dname, sn->mnum, sn->cname, ep) == -1) 141*0Sstevel@tonic-gate return (-1); 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate } else 144*0Sstevel@tonic-gate Free(nm); 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate return (0); 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate /* 150*0Sstevel@tonic-gate * Delete sidename entry from local set using key and sideno. 151*0Sstevel@tonic-gate */ 152*0Sstevel@tonic-gate static int 153*0Sstevel@tonic-gate del_sideno_sidenm( 154*0Sstevel@tonic-gate mdkey_t sidekey, 155*0Sstevel@tonic-gate side_t sideno, 156*0Sstevel@tonic-gate md_error_t *ep 157*0Sstevel@tonic-gate ) 158*0Sstevel@tonic-gate { 159*0Sstevel@tonic-gate mdsetname_t *local_sp; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 162*0Sstevel@tonic-gate return (-1); 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate if (del_name(local_sp, sideno, sidekey, ep) == -1) 165*0Sstevel@tonic-gate mdclrerror(ep); /* ignore errs */ 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate return (0); 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate /* 172*0Sstevel@tonic-gate * Add namespace entries to local mddb for drives in drive list in 173*0Sstevel@tonic-gate * set descriptor. 174*0Sstevel@tonic-gate * 175*0Sstevel@tonic-gate * If a MNset and if this host is being added to the set (this host 176*0Sstevel@tonic-gate * is in the node_v list), add a namespace entry for the name of 177*0Sstevel@tonic-gate * each drive using this host's sideno. 178*0Sstevel@tonic-gate * 179*0Sstevel@tonic-gate * If not a MNset, add namespace entries for all the new hosts being 180*0Sstevel@tonic-gate * added to this set (list in node_v). 181*0Sstevel@tonic-gate */ 182*0Sstevel@tonic-gate static void 183*0Sstevel@tonic-gate add_drv_sidenms( 184*0Sstevel@tonic-gate char *hostname, 185*0Sstevel@tonic-gate mdsetname_t *sp, 186*0Sstevel@tonic-gate md_set_desc *sd, 187*0Sstevel@tonic-gate int node_c, 188*0Sstevel@tonic-gate char **node_v, 189*0Sstevel@tonic-gate md_error_t *ep 190*0Sstevel@tonic-gate ) 191*0Sstevel@tonic-gate { 192*0Sstevel@tonic-gate mdsetname_t *my_sp; 193*0Sstevel@tonic-gate md_drive_desc *dd, *my_dd, *p, *q; 194*0Sstevel@tonic-gate mddrivename_t *dn, *my_dn; 195*0Sstevel@tonic-gate int i; 196*0Sstevel@tonic-gate side_t sideno = 0, mysideno = 0; 197*0Sstevel@tonic-gate ddi_devid_t devid_remote = NULL; 198*0Sstevel@tonic-gate ddi_devid_t devid_local = NULL; 199*0Sstevel@tonic-gate int devid_same = -1; 200*0Sstevel@tonic-gate int using_devid = 0; 201*0Sstevel@tonic-gate md_mnnode_desc *nd; 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate assert(sd->sd_drvs != NULL); 204*0Sstevel@tonic-gate dd = sd->sd_drvs; 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate if (dd->dd_dnp == NULL) 207*0Sstevel@tonic-gate return; 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate if ((my_sp = metasetname(sp->setname, ep)) == NULL) 210*0Sstevel@tonic-gate return; 211*0Sstevel@tonic-gate metaflushsetname(my_sp); 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate /* If a MN diskset */ 214*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) { 215*0Sstevel@tonic-gate /* Find sideno associated with RPC client. */ 216*0Sstevel@tonic-gate nd = sd->sd_nodelist; 217*0Sstevel@tonic-gate while (nd) { 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate if (strcmp(nd->nd_nodename, hostname) == 0) { 220*0Sstevel@tonic-gate sideno = nd->nd_nodeid; 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate /* While looping, find my side num as well */ 224*0Sstevel@tonic-gate if (strcmp(nd->nd_nodename, mynode()) == 0) { 225*0Sstevel@tonic-gate mysideno = nd->nd_nodeid; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate if ((sideno) && (mysideno)) { 229*0Sstevel@tonic-gate break; 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate nd = nd->nd_next; 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate if (!sideno) { 235*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE, 236*0Sstevel@tonic-gate sp->setno, hostname, NULL, sp->setname); 237*0Sstevel@tonic-gate return; 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate } else { 240*0Sstevel@tonic-gate /* 241*0Sstevel@tonic-gate * if not a MN diskset 242*0Sstevel@tonic-gate * do action for traditional diskset. 243*0Sstevel@tonic-gate * despite of the rpc version 244*0Sstevel@tonic-gate */ 245*0Sstevel@tonic-gate for (sideno = 0; sideno < MD_MAXSIDES; sideno++) { 246*0Sstevel@tonic-gate /* Skip empty slots */ 247*0Sstevel@tonic-gate if (sd->sd_nodes[sideno][0] == '\0') 248*0Sstevel@tonic-gate continue; 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate if (strcmp(hostname, sd->sd_nodes[sideno]) == 0) 251*0Sstevel@tonic-gate break; 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate if (sideno == MD_MAXSIDES) { 255*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno, 256*0Sstevel@tonic-gate hostname, NULL, sp->setname); 257*0Sstevel@tonic-gate return; 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate if ((my_dd = metaget_drivedesc_sideno(my_sp, sideno, MD_BASICNAME_OK, 261*0Sstevel@tonic-gate ep)) == NULL) { 262*0Sstevel@tonic-gate if (! mdisok(ep)) 263*0Sstevel@tonic-gate return; 264*0Sstevel@tonic-gate /* we are supposed to have drives!!!! */ 265*0Sstevel@tonic-gate assert(0); 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate /* 269*0Sstevel@tonic-gate * The system is either all devid or all 270*0Sstevel@tonic-gate * non-devid so we look at the first item 271*0Sstevel@tonic-gate * in the list to determine if we're using devids or not. 272*0Sstevel@tonic-gate * We also check to make sure it's not a multi-node diskset. 273*0Sstevel@tonic-gate * If it is, we don't use devid's. 274*0Sstevel@tonic-gate * 275*0Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which 276*0Sstevel@tonic-gate * points to a '' string of devid. We need to check this 277*0Sstevel@tonic-gate * before set the using_devid. 278*0Sstevel@tonic-gate */ 279*0Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 280*0Sstevel@tonic-gate (!(MD_MNSET_DESC(sd)))) 281*0Sstevel@tonic-gate using_devid = 1; 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* 284*0Sstevel@tonic-gate * We have to match-up the dd that were passed 285*0Sstevel@tonic-gate * across the wire to the dd we have in this daemon. 286*0Sstevel@tonic-gate * That way we can pick up the new sidenames that were 287*0Sstevel@tonic-gate * passed to us and match them up with the local namespace key. 288*0Sstevel@tonic-gate * Only we have the key, this cannot be passed in. 289*0Sstevel@tonic-gate */ 290*0Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) { 291*0Sstevel@tonic-gate dn = p->dd_dnp; 292*0Sstevel@tonic-gate devid_remote = NULL; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) && 295*0Sstevel@tonic-gate using_devid) { 296*0Sstevel@tonic-gate /* 297*0Sstevel@tonic-gate * We have a devid so use it 298*0Sstevel@tonic-gate */ 299*0Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL); 300*0Sstevel@tonic-gate } 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */ 303*0Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) { 304*0Sstevel@tonic-gate /* something went really wrong. Can't process */ 305*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 306*0Sstevel@tonic-gate hostname, dn->cname, sp->setname); 307*0Sstevel@tonic-gate return; 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate for (q = my_dd; q != NULL; q = q->dd_next) { 311*0Sstevel@tonic-gate my_dn = q->dd_dnp; 312*0Sstevel@tonic-gate devid_same = -1; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate if (my_dn->devid != NULL && using_devid) { 315*0Sstevel@tonic-gate if (devid_str_decode(my_dn->devid, 316*0Sstevel@tonic-gate &devid_local, NULL) == 0) { 317*0Sstevel@tonic-gate devid_same = devid_compare(devid_remote, 318*0Sstevel@tonic-gate devid_local); 319*0Sstevel@tonic-gate devid_free(devid_local); 320*0Sstevel@tonic-gate } 321*0Sstevel@tonic-gate } 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate if (using_devid && devid_same == 0) { 324*0Sstevel@tonic-gate break; 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate if (!using_devid && 328*0Sstevel@tonic-gate strcmp(my_dn->cname, dn->cname) == 0) 329*0Sstevel@tonic-gate break; 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate if (devid_remote) { 333*0Sstevel@tonic-gate devid_free(devid_remote); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate assert(q != NULL); 336*0Sstevel@tonic-gate assert(my_dn->side_names_key != MD_KEYWILD); 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) { 339*0Sstevel@tonic-gate /* 340*0Sstevel@tonic-gate * Add the side names to the local db 341*0Sstevel@tonic-gate * for this node only. 342*0Sstevel@tonic-gate */ 343*0Sstevel@tonic-gate if (add_sideno_sidenm(dn->side_names, 344*0Sstevel@tonic-gate my_dn->side_names_key, mysideno, sd, ep)) 345*0Sstevel@tonic-gate return; 346*0Sstevel@tonic-gate /* 347*0Sstevel@tonic-gate * Sidenames for this drive were added 348*0Sstevel@tonic-gate * to this host during the routine adddrvs. 349*0Sstevel@tonic-gate * The sidenames that were added are the 350*0Sstevel@tonic-gate * names associated with this drive on 351*0Sstevel@tonic-gate * each of the hosts that were previously 352*0Sstevel@tonic-gate * in the set. 353*0Sstevel@tonic-gate * When the sidename for this drive on 354*0Sstevel@tonic-gate * this host is added, the sidename 355*0Sstevel@tonic-gate * from the host executing the command 356*0Sstevel@tonic-gate * (not this host) is sent to this host. 357*0Sstevel@tonic-gate * This host finds the originating host's 358*0Sstevel@tonic-gate * sidename and can then determine this 359*0Sstevel@tonic-gate * host's sidename. 360*0Sstevel@tonic-gate * The sidenames from the other hosts serve 361*0Sstevel@tonic-gate * only as temporary sidenames until this 362*0Sstevel@tonic-gate * host's sidename can be added. 363*0Sstevel@tonic-gate * In order to conserve space in the 364*0Sstevel@tonic-gate * local mddb, the code now deletes the 365*0Sstevel@tonic-gate * temporary sidenames added during adddrvs. 366*0Sstevel@tonic-gate * When finished, only the sidename for this 367*0Sstevel@tonic-gate * node should be left. 368*0Sstevel@tonic-gate * Ignore any errors during this process since 369*0Sstevel@tonic-gate * a failure to delete the extraneous 370*0Sstevel@tonic-gate * sidenames shouldn't cause this routine 371*0Sstevel@tonic-gate * to fail (in case that sidename didn't exist). 372*0Sstevel@tonic-gate */ 373*0Sstevel@tonic-gate nd = sd->sd_nodelist; 374*0Sstevel@tonic-gate while (nd) { 375*0Sstevel@tonic-gate if (nd->nd_nodeid != mysideno) { 376*0Sstevel@tonic-gate if (del_sideno_sidenm( 377*0Sstevel@tonic-gate dn->side_names_key, 378*0Sstevel@tonic-gate nd->nd_nodeid, ep) == -1) 379*0Sstevel@tonic-gate mdclrerror(ep); 380*0Sstevel@tonic-gate } 381*0Sstevel@tonic-gate nd = nd->nd_next; 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate } else { 384*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 385*0Sstevel@tonic-gate /* Skip empty slots */ 386*0Sstevel@tonic-gate if (sd->sd_nodes[i][0] == '\0') 387*0Sstevel@tonic-gate continue; 388*0Sstevel@tonic-gate 389*0Sstevel@tonic-gate /* Skip nodes not being added */ 390*0Sstevel@tonic-gate if (! strinlst(sd->sd_nodes[i], 391*0Sstevel@tonic-gate node_c, node_v)) 392*0Sstevel@tonic-gate continue; 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate /* Add the per side names to local db */ 395*0Sstevel@tonic-gate if (add_sideno_sidenm(dn->side_names, 396*0Sstevel@tonic-gate my_dn->side_names_key, i, sd, ep)) 397*0Sstevel@tonic-gate return; 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate } 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate } 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate /* ARGSUSED */ 404*0Sstevel@tonic-gate bool_t 405*0Sstevel@tonic-gate mdrpc_flush_internal_common(mdrpc_null_args *args, mdrpc_generic_res *res, 406*0Sstevel@tonic-gate struct svc_req *rqstp) 407*0Sstevel@tonic-gate { 408*0Sstevel@tonic-gate md_error_t *ep = &res->status; 409*0Sstevel@tonic-gate int err, 410*0Sstevel@tonic-gate op_mode = W_OK; 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate memset(res, 0, sizeof (*res)); 413*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 414*0Sstevel@tonic-gate return (FALSE); 415*0Sstevel@tonic-gate else if (err != 0) 416*0Sstevel@tonic-gate return (TRUE); 417*0Sstevel@tonic-gate 418*0Sstevel@tonic-gate metaflushnames(1); 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate err = svc_fini(ep); 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate return (TRUE); 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate bool_t 426*0Sstevel@tonic-gate mdrpc_flush_internal_1_svc(mdrpc_null_args *args, mdrpc_generic_res *res, 427*0Sstevel@tonic-gate struct svc_req *rqstp) 428*0Sstevel@tonic-gate { 429*0Sstevel@tonic-gate return (mdrpc_flush_internal_common(args, res, rqstp)); 430*0Sstevel@tonic-gate } 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate bool_t 433*0Sstevel@tonic-gate mdrpc_flush_internal_2_svc(mdrpc_null_args *args, mdrpc_generic_res *res, 434*0Sstevel@tonic-gate struct svc_req *rqstp) 435*0Sstevel@tonic-gate { 436*0Sstevel@tonic-gate return (mdrpc_flush_internal_common(args, res, rqstp)); 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate /* 440*0Sstevel@tonic-gate * add 1 or more namespace entries per drive record. 441*0Sstevel@tonic-gate * (into the local namespace) 442*0Sstevel@tonic-gate */ 443*0Sstevel@tonic-gate bool_t 444*0Sstevel@tonic-gate mdrpc_add_drv_sidenms_common( 445*0Sstevel@tonic-gate mdrpc_drv_sidenm_2_args_r1 *args, 446*0Sstevel@tonic-gate mdrpc_generic_res *res, 447*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 448*0Sstevel@tonic-gate ) 449*0Sstevel@tonic-gate { 450*0Sstevel@tonic-gate md_error_t *ep = &res->status; 451*0Sstevel@tonic-gate int err; 452*0Sstevel@tonic-gate int op_mode = W_OK; 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate /* setup, check permissions */ 455*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 456*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 457*0Sstevel@tonic-gate return (FALSE); 458*0Sstevel@tonic-gate else if (err != 0) 459*0Sstevel@tonic-gate return (TRUE); 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 462*0Sstevel@tonic-gate return (TRUE); 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate /* doit */ 465*0Sstevel@tonic-gate add_drv_sidenms(args->hostname, args->sp, args->sd, 466*0Sstevel@tonic-gate args->node_v.node_v_len, args->node_v.node_v_val, ep); 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate err = svc_fini(ep); 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate return (TRUE); 471*0Sstevel@tonic-gate } 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate /* 474*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 475*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 476*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 477*0Sstevel@tonic-gate */ 478*0Sstevel@tonic-gate bool_t 479*0Sstevel@tonic-gate mdrpc_add_drv_sidenms_1_svc( 480*0Sstevel@tonic-gate mdrpc_drv_sidenm_args *args, 481*0Sstevel@tonic-gate mdrpc_generic_res *res, 482*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 483*0Sstevel@tonic-gate ) 484*0Sstevel@tonic-gate { 485*0Sstevel@tonic-gate bool_t retval; 486*0Sstevel@tonic-gate mdrpc_drv_sidenm_2_args_r1 v2_args; 487*0Sstevel@tonic-gate int i, j; 488*0Sstevel@tonic-gate 489*0Sstevel@tonic-gate /* allocate memory */ 490*0Sstevel@tonic-gate v2_args.sd = Zalloc(sizeof (md_set_desc)); 491*0Sstevel@tonic-gate alloc_newdrvdesc(args->sd->sd_drvs, &v2_args.sd->sd_drvs); 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate /* build args */ 494*0Sstevel@tonic-gate v2_args.hostname = args->hostname; 495*0Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk; 496*0Sstevel@tonic-gate v2_args.sp = args->sp; 497*0Sstevel@tonic-gate /* set descriptor */ 498*0Sstevel@tonic-gate v2_args.sd->sd_ctime = args->sd->sd_ctime; 499*0Sstevel@tonic-gate v2_args.sd->sd_genid = args->sd->sd_genid; 500*0Sstevel@tonic-gate v2_args.sd->sd_setno = args->sd->sd_setno; 501*0Sstevel@tonic-gate v2_args.sd->sd_flags = args->sd->sd_flags; 502*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 503*0Sstevel@tonic-gate v2_args.sd->sd_isown[i] = args->sd->sd_isown[i]; 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j++) 506*0Sstevel@tonic-gate v2_args.sd->sd_nodes[i][j] = 507*0Sstevel@tonic-gate args->sd->sd_nodes[i][j]; 508*0Sstevel@tonic-gate } 509*0Sstevel@tonic-gate v2_args.sd->sd_med = args->sd->sd_med; 510*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 511*0Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->sd->sd_drvs, v2_args.sd->sd_drvs); 512*0Sstevel@tonic-gate v2_args.node_v.node_v_len = args->node_v.node_v_len; 513*0Sstevel@tonic-gate v2_args.node_v.node_v_val = args->node_v.node_v_val; 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gate retval = mdrpc_add_drv_sidenms_common(&v2_args, res, rqstp); 516*0Sstevel@tonic-gate 517*0Sstevel@tonic-gate free(v2_args.sd); 518*0Sstevel@tonic-gate free_newdrvdesc(v2_args.sd->sd_drvs); 519*0Sstevel@tonic-gate 520*0Sstevel@tonic-gate return (retval); 521*0Sstevel@tonic-gate } 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate bool_t 524*0Sstevel@tonic-gate mdrpc_add_drv_sidenms_2_svc( 525*0Sstevel@tonic-gate mdrpc_drv_sidenm_2_args *args, 526*0Sstevel@tonic-gate mdrpc_generic_res *res, 527*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 528*0Sstevel@tonic-gate ) 529*0Sstevel@tonic-gate { 530*0Sstevel@tonic-gate switch (args->rev) { 531*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 532*0Sstevel@tonic-gate return (mdrpc_add_drv_sidenms_common( 533*0Sstevel@tonic-gate &args->mdrpc_drv_sidenm_2_args_u.rev1, res, rqstp)); 534*0Sstevel@tonic-gate default: 535*0Sstevel@tonic-gate return (FALSE); 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate } 538*0Sstevel@tonic-gate 539*0Sstevel@tonic-gate static int 540*0Sstevel@tonic-gate add_sidenamelist( 541*0Sstevel@tonic-gate mddrivename_t *dn, 542*0Sstevel@tonic-gate side_t thisside, 543*0Sstevel@tonic-gate md_set_record *sr, /* used by RPC version 2 */ 544*0Sstevel@tonic-gate md_error_t *ep 545*0Sstevel@tonic-gate ) 546*0Sstevel@tonic-gate { 547*0Sstevel@tonic-gate mdsidenames_t *sn; 548*0Sstevel@tonic-gate mdkey_t key; 549*0Sstevel@tonic-gate int err; 550*0Sstevel@tonic-gate mdsetname_t *local_sp; 551*0Sstevel@tonic-gate md_mnset_record *mnsr; 552*0Sstevel@tonic-gate md_mnnode_record *nr; 553*0Sstevel@tonic-gate uint_t nodeid = 0; 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 556*0Sstevel@tonic-gate return (-1); 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate key = MD_KEYWILD; 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate /* 561*0Sstevel@tonic-gate * If a multi-node diskset, find nodeid associated with this node. 562*0Sstevel@tonic-gate */ 563*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) { 564*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 565*0Sstevel@tonic-gate nr = mnsr->sr_nodechain; 566*0Sstevel@tonic-gate while (nr) { 567*0Sstevel@tonic-gate if (strcmp(nr->nr_nodename, mynode()) == 0) { 568*0Sstevel@tonic-gate break; 569*0Sstevel@tonic-gate } 570*0Sstevel@tonic-gate nr = nr->nr_next; 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate /* 573*0Sstevel@tonic-gate * If node is found, then a new drive is being added to 574*0Sstevel@tonic-gate * a MN set of which this node is a member. 575*0Sstevel@tonic-gate * If node is not found, then this host is being added to 576*0Sstevel@tonic-gate * a MN set that has drives associated with it. 577*0Sstevel@tonic-gate */ 578*0Sstevel@tonic-gate if (nr) 579*0Sstevel@tonic-gate nodeid = nr->nr_nodeid; 580*0Sstevel@tonic-gate } 581*0Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) { 582*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) { 583*0Sstevel@tonic-gate /* 584*0Sstevel@tonic-gate * In multi-node disksets, only add side information 585*0Sstevel@tonic-gate * to the local mddb about this node. 586*0Sstevel@tonic-gate * If the sideno for this node is found, then 587*0Sstevel@tonic-gate * a new drive is being added to a MN set of 588*0Sstevel@tonic-gate * which this node is a member. 589*0Sstevel@tonic-gate * If the sideno for this node is not found, then 590*0Sstevel@tonic-gate * this host is being added to a MNset that 591*0Sstevel@tonic-gate * has drives associated with it. In this case, 592*0Sstevel@tonic-gate * need to add the sidename associated with the 593*0Sstevel@tonic-gate * rpc client, but since we don't know which node 594*0Sstevel@tonic-gate * is the client, then add temp entries for all sides. 595*0Sstevel@tonic-gate * Later, the sidename for this node will be set 596*0Sstevel@tonic-gate * via add_drv_sidenms and then the temp 597*0Sstevel@tonic-gate * sidenames can be removed. 598*0Sstevel@tonic-gate */ 599*0Sstevel@tonic-gate if (nodeid == sn->sideno) { 600*0Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno, key, 601*0Sstevel@tonic-gate sn->dname, sn->mnum, sn->cname, ep)) == -1) 602*0Sstevel@tonic-gate return (-1); 603*0Sstevel@tonic-gate key = (mdkey_t)err; 604*0Sstevel@tonic-gate break; 605*0Sstevel@tonic-gate } 606*0Sstevel@tonic-gate } else { 607*0Sstevel@tonic-gate /* 608*0Sstevel@tonic-gate * When a sidename is added into the namespace the local 609*0Sstevel@tonic-gate * side information for the name is added first of all. 610*0Sstevel@tonic-gate * When the first sidename is created this causes the 611*0Sstevel@tonic-gate * devid of the disk to be recorded in the namespace, if 612*0Sstevel@tonic-gate * the non-local side information is added first then 613*0Sstevel@tonic-gate * there is the possibility of getting the wrong devid 614*0Sstevel@tonic-gate * because there is no guarantee that the dev_t (mnum in 615*0Sstevel@tonic-gate * this instance) is the same across all the nodes in 616*0Sstevel@tonic-gate * the set. So the only way to make sure that the 617*0Sstevel@tonic-gate * correct dev_t is used is to force the adding in of 618*0Sstevel@tonic-gate * the local sidename record first of all. This same 619*0Sstevel@tonic-gate * issue affects add_key_name(). 620*0Sstevel@tonic-gate */ 621*0Sstevel@tonic-gate if (sn->sideno != thisside) 622*0Sstevel@tonic-gate continue; 623*0Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno+SKEW, key, 624*0Sstevel@tonic-gate sn->dname, sn->mnum, sn->cname, ep)) == -1) 625*0Sstevel@tonic-gate return (-1); 626*0Sstevel@tonic-gate key = (mdkey_t)err; 627*0Sstevel@tonic-gate break; 628*0Sstevel@tonic-gate } 629*0Sstevel@tonic-gate } 630*0Sstevel@tonic-gate 631*0Sstevel@tonic-gate /* 632*0Sstevel@tonic-gate * Now the other sides for non-MN set 633*0Sstevel@tonic-gate */ 634*0Sstevel@tonic-gate if (!MD_MNSET_REC(sr)) { 635*0Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) { 636*0Sstevel@tonic-gate if (sn->sideno == thisside) 637*0Sstevel@tonic-gate continue; 638*0Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno+SKEW, key, 639*0Sstevel@tonic-gate sn->dname, sn->mnum, sn->cname, ep)) == -1) 640*0Sstevel@tonic-gate return (-1); 641*0Sstevel@tonic-gate key = (mdkey_t)err; 642*0Sstevel@tonic-gate } 643*0Sstevel@tonic-gate } 644*0Sstevel@tonic-gate 645*0Sstevel@tonic-gate /* Temporarily add all sides. */ 646*0Sstevel@tonic-gate if ((key == MD_KEYWILD) && (MD_MNSET_REC(sr))) { 647*0Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) { 648*0Sstevel@tonic-gate sn = dn->side_names; 649*0Sstevel@tonic-gate if (sn) { 650*0Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno, key, 651*0Sstevel@tonic-gate sn->dname, sn->mnum, sn->cname, ep)) == -1) 652*0Sstevel@tonic-gate return (-1); 653*0Sstevel@tonic-gate key = (mdkey_t)err; 654*0Sstevel@tonic-gate } 655*0Sstevel@tonic-gate } 656*0Sstevel@tonic-gate } 657*0Sstevel@tonic-gate 658*0Sstevel@tonic-gate dn->side_names_key = key; 659*0Sstevel@tonic-gate return (0); 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate 662*0Sstevel@tonic-gate static void 663*0Sstevel@tonic-gate adddrvs( 664*0Sstevel@tonic-gate char *setname, 665*0Sstevel@tonic-gate md_drive_desc *dd, 666*0Sstevel@tonic-gate md_timeval32_t timestamp, 667*0Sstevel@tonic-gate ulong_t genid, 668*0Sstevel@tonic-gate md_error_t *ep 669*0Sstevel@tonic-gate ) 670*0Sstevel@tonic-gate { 671*0Sstevel@tonic-gate mddb_userreq_t req; 672*0Sstevel@tonic-gate md_drive_record *dr; 673*0Sstevel@tonic-gate md_set_record *sr; 674*0Sstevel@tonic-gate md_drive_desc *p; 675*0Sstevel@tonic-gate mddrivename_t *dn; 676*0Sstevel@tonic-gate mdname_t *np; 677*0Sstevel@tonic-gate md_dev64_t dev; 678*0Sstevel@tonic-gate md_error_t xep = mdnullerror; 679*0Sstevel@tonic-gate int i; 680*0Sstevel@tonic-gate 681*0Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL) 682*0Sstevel@tonic-gate return; 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) 685*0Sstevel@tonic-gate i = 0; 686*0Sstevel@tonic-gate else { 687*0Sstevel@tonic-gate /* get thisside */ 688*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 689*0Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0') 690*0Sstevel@tonic-gate continue; 691*0Sstevel@tonic-gate if (strcmp(mynode(), sr->sr_nodes[i]) == 0) 692*0Sstevel@tonic-gate break; 693*0Sstevel@tonic-gate } 694*0Sstevel@tonic-gate 695*0Sstevel@tonic-gate if (i == MD_MAXSIDES) { 696*0Sstevel@tonic-gate /* so find the first free slot! */ 697*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 698*0Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0') 699*0Sstevel@tonic-gate break; 700*0Sstevel@tonic-gate } 701*0Sstevel@tonic-gate } 702*0Sstevel@tonic-gate } 703*0Sstevel@tonic-gate 704*0Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) { 705*0Sstevel@tonic-gate uint_t rep_slice; 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate dn = p->dd_dnp; 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate /* Add the per side names to the local db */ 710*0Sstevel@tonic-gate if (add_sidenamelist(dn, (side_t)i, sr, ep)) { 711*0Sstevel@tonic-gate free_sr(sr); 712*0Sstevel@tonic-gate return; 713*0Sstevel@tonic-gate } 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate /* Create the drive record */ 716*0Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 717*0Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_CREATE, 0); 718*0Sstevel@tonic-gate req.ur_size = sizeof (*dr); 719*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 720*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 721*0Sstevel@tonic-gate free_sr(sr); 722*0Sstevel@tonic-gate return; 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate /* Fill in the drive record values */ 726*0Sstevel@tonic-gate dr = Zalloc(sizeof (*dr)); 727*0Sstevel@tonic-gate dr->dr_selfid = req.ur_recid; 728*0Sstevel@tonic-gate dr->dr_dbcnt = p->dd_dbcnt; 729*0Sstevel@tonic-gate dr->dr_dbsize = p->dd_dbsize; 730*0Sstevel@tonic-gate dr->dr_key = dn->side_names_key; 731*0Sstevel@tonic-gate 732*0Sstevel@tonic-gate dr->dr_ctime = timestamp; 733*0Sstevel@tonic-gate dr->dr_genid = genid; 734*0Sstevel@tonic-gate dr->dr_revision = MD_DRIVE_RECORD_REVISION; 735*0Sstevel@tonic-gate dr->dr_flags = MD_DR_ADD; 736*0Sstevel@tonic-gate 737*0Sstevel@tonic-gate /* Link the drive records and fill in in-core data */ 738*0Sstevel@tonic-gate dr_cache_add(sr, dr); 739*0Sstevel@tonic-gate 740*0Sstevel@tonic-gate dev = NODEV64; 741*0Sstevel@tonic-gate if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) && 742*0Sstevel@tonic-gate ((np = metaslicename(dn, rep_slice, &xep)) != NULL)) 743*0Sstevel@tonic-gate dev = np->dev; 744*0Sstevel@tonic-gate else 745*0Sstevel@tonic-gate mdclrerror(&xep); 746*0Sstevel@tonic-gate 747*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE, 748*0Sstevel@tonic-gate MD_LOCAL_SET, dev); 749*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE, 750*0Sstevel@tonic-gate sr->sr_setno, dev); 751*0Sstevel@tonic-gate } 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate /* Commit all the records atomically */ 754*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 755*0Sstevel@tonic-gate free_sr(sr); 756*0Sstevel@tonic-gate } 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate /* 759*0Sstevel@tonic-gate * add 1 or more drive records to a set. 760*0Sstevel@tonic-gate */ 761*0Sstevel@tonic-gate bool_t 762*0Sstevel@tonic-gate mdrpc_adddrvs_common( 763*0Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args, 764*0Sstevel@tonic-gate mdrpc_generic_res *res, 765*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 766*0Sstevel@tonic-gate ) 767*0Sstevel@tonic-gate { 768*0Sstevel@tonic-gate md_error_t *ep = &res->status; 769*0Sstevel@tonic-gate int err; 770*0Sstevel@tonic-gate int op_mode = W_OK; 771*0Sstevel@tonic-gate 772*0Sstevel@tonic-gate /* setup, check permissions */ 773*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 774*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 775*0Sstevel@tonic-gate return (FALSE); 776*0Sstevel@tonic-gate else if (err != 0) 777*0Sstevel@tonic-gate return (TRUE); 778*0Sstevel@tonic-gate 779*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 780*0Sstevel@tonic-gate return (TRUE); 781*0Sstevel@tonic-gate 782*0Sstevel@tonic-gate /* doit */ 783*0Sstevel@tonic-gate adddrvs(args->sp->setname, args->drivedescs, args->timestamp, 784*0Sstevel@tonic-gate args->genid, ep); 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate err = svc_fini(ep); 787*0Sstevel@tonic-gate 788*0Sstevel@tonic-gate return (TRUE); 789*0Sstevel@tonic-gate } 790*0Sstevel@tonic-gate 791*0Sstevel@tonic-gate /* 792*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 793*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 794*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 795*0Sstevel@tonic-gate */ 796*0Sstevel@tonic-gate bool_t 797*0Sstevel@tonic-gate mdrpc_adddrvs_1_svc( 798*0Sstevel@tonic-gate mdrpc_drives_args *args, 799*0Sstevel@tonic-gate mdrpc_generic_res *res, 800*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 801*0Sstevel@tonic-gate ) 802*0Sstevel@tonic-gate { 803*0Sstevel@tonic-gate bool_t retval; 804*0Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args; 805*0Sstevel@tonic-gate 806*0Sstevel@tonic-gate /* allocate memory */ 807*0Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 808*0Sstevel@tonic-gate 809*0Sstevel@tonic-gate /* build args */ 810*0Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk; 811*0Sstevel@tonic-gate v2_args.sp = args->sp; 812*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 813*0Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 814*0Sstevel@tonic-gate v2_args.timestamp = args->timestamp; 815*0Sstevel@tonic-gate v2_args.genid = args->genid; 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate retval = mdrpc_adddrvs_common(&v2_args, res, rqstp); 818*0Sstevel@tonic-gate 819*0Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs); 820*0Sstevel@tonic-gate 821*0Sstevel@tonic-gate return (retval); 822*0Sstevel@tonic-gate } 823*0Sstevel@tonic-gate 824*0Sstevel@tonic-gate bool_t 825*0Sstevel@tonic-gate mdrpc_adddrvs_2_svc( 826*0Sstevel@tonic-gate mdrpc_drives_2_args *args, 827*0Sstevel@tonic-gate mdrpc_generic_res *res, 828*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 829*0Sstevel@tonic-gate ) 830*0Sstevel@tonic-gate { 831*0Sstevel@tonic-gate switch (args->rev) { 832*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 833*0Sstevel@tonic-gate return (mdrpc_adddrvs_common( 834*0Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 835*0Sstevel@tonic-gate default: 836*0Sstevel@tonic-gate return (FALSE); 837*0Sstevel@tonic-gate } 838*0Sstevel@tonic-gate } 839*0Sstevel@tonic-gate 840*0Sstevel@tonic-gate static void 841*0Sstevel@tonic-gate addhosts( 842*0Sstevel@tonic-gate char *setname, 843*0Sstevel@tonic-gate int node_c, 844*0Sstevel@tonic-gate char **node_v, 845*0Sstevel@tonic-gate int version, /* RPC version of calling routine */ 846*0Sstevel@tonic-gate md_error_t *ep 847*0Sstevel@tonic-gate ) 848*0Sstevel@tonic-gate { 849*0Sstevel@tonic-gate mddb_userreq_t req; 850*0Sstevel@tonic-gate md_set_record *sr; 851*0Sstevel@tonic-gate int i, j; 852*0Sstevel@tonic-gate md_mnset_record *mnsr; 853*0Sstevel@tonic-gate md_mnnode_record *nr; 854*0Sstevel@tonic-gate mddb_set_node_params_t snp; 855*0Sstevel@tonic-gate int nodecnt; 856*0Sstevel@tonic-gate mndiskset_membershiplist_t *nl, *nl2; 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL) 859*0Sstevel@tonic-gate return; 860*0Sstevel@tonic-gate 861*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 862*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 863*0Sstevel@tonic-gate mnsr = (md_mnset_record *)sr; 864*0Sstevel@tonic-gate /* 865*0Sstevel@tonic-gate * Verify nodes are in membership list on THIS node. 866*0Sstevel@tonic-gate * Initiating node has verified that nodes are in membership 867*0Sstevel@tonic-gate * list on the initiating node. 868*0Sstevel@tonic-gate * Get membershiplist from API routine. If there's 869*0Sstevel@tonic-gate * an error, fail to add hosts and pass back error. 870*0Sstevel@tonic-gate */ 871*0Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) { 872*0Sstevel@tonic-gate free_sr(sr); 873*0Sstevel@tonic-gate return; 874*0Sstevel@tonic-gate } 875*0Sstevel@tonic-gate /* Verify that all nodes are in member list */ 876*0Sstevel@tonic-gate for (i = 0; i < node_c; i++) { 877*0Sstevel@tonic-gate /* 878*0Sstevel@tonic-gate * If node in list isn't a member of the membership, 879*0Sstevel@tonic-gate * just return error. 880*0Sstevel@tonic-gate */ 881*0Sstevel@tonic-gate if (meta_is_member(node_v[i], NULL, nl) == 0) { 882*0Sstevel@tonic-gate meta_free_nodelist(nl); 883*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST, 884*0Sstevel@tonic-gate sr->sr_setno, node_v[i], NULL, setname); 885*0Sstevel@tonic-gate free_sr(sr); 886*0Sstevel@tonic-gate return; 887*0Sstevel@tonic-gate } 888*0Sstevel@tonic-gate } 889*0Sstevel@tonic-gate } 890*0Sstevel@tonic-gate 891*0Sstevel@tonic-gate for (i = 0; i < node_c; i++) { 892*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 893*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 894*0Sstevel@tonic-gate mnsr = (md_mnset_record *)sr; 895*0Sstevel@tonic-gate /* Create the node record */ 896*0Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 897*0Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_CREATE, 0); 898*0Sstevel@tonic-gate req.ur_size = sizeof (*nr); 899*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) 900*0Sstevel@tonic-gate != 0) { 901*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 902*0Sstevel@tonic-gate meta_free_nodelist(nl); 903*0Sstevel@tonic-gate free_sr(sr); 904*0Sstevel@tonic-gate return; 905*0Sstevel@tonic-gate } 906*0Sstevel@tonic-gate 907*0Sstevel@tonic-gate nr = Zalloc(sizeof (*nr)); 908*0Sstevel@tonic-gate nr->nr_revision = MD_MNNODE_RECORD_REVISION; 909*0Sstevel@tonic-gate nr->nr_selfid = req.ur_recid; 910*0Sstevel@tonic-gate nr->nr_ctime = sr->sr_ctime; 911*0Sstevel@tonic-gate nr->nr_genid = sr->sr_genid; 912*0Sstevel@tonic-gate nr->nr_flags = MD_MN_NODE_ADD; 913*0Sstevel@tonic-gate nl2 = nl; 914*0Sstevel@tonic-gate while (nl2) { 915*0Sstevel@tonic-gate if (strcmp(nl2->msl_node_name, node_v[i]) 916*0Sstevel@tonic-gate == 0) { 917*0Sstevel@tonic-gate nr->nr_nodeid = nl2->msl_node_id; 918*0Sstevel@tonic-gate break; 919*0Sstevel@tonic-gate } 920*0Sstevel@tonic-gate nl2 = nl2->next; 921*0Sstevel@tonic-gate } 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate (void) strcpy(nr->nr_nodename, node_v[i]); 924*0Sstevel@tonic-gate 925*0Sstevel@tonic-gate /* 926*0Sstevel@tonic-gate * When a node is added to a MN diskset, set the 927*0Sstevel@tonic-gate * nodeid of this node in the md_set structure 928*0Sstevel@tonic-gate * in the kernel. 929*0Sstevel@tonic-gate */ 930*0Sstevel@tonic-gate if (strcmp(nr->nr_nodename, mynode()) == 0) { 931*0Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp)); 932*0Sstevel@tonic-gate snp.sn_nodeid = nr->nr_nodeid; 933*0Sstevel@tonic-gate snp.sn_setno = mnsr->sr_setno; 934*0Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp, 935*0Sstevel@tonic-gate &snp.sn_mde, NULL) != 0) { 936*0Sstevel@tonic-gate (void) mdstealerror(ep, &snp.sn_mde); 937*0Sstevel@tonic-gate meta_free_nodelist(nl); 938*0Sstevel@tonic-gate free_sr(sr); 939*0Sstevel@tonic-gate return; 940*0Sstevel@tonic-gate } 941*0Sstevel@tonic-gate } 942*0Sstevel@tonic-gate 943*0Sstevel@tonic-gate /* Link the node records and fill in in-core data */ 944*0Sstevel@tonic-gate mnnr_cache_add(mnsr, nr); 945*0Sstevel@tonic-gate 946*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, 947*0Sstevel@tonic-gate mnsr->sr_setno, nr->nr_nodeid); 948*0Sstevel@tonic-gate } else { 949*0Sstevel@tonic-gate for (j = 0; j < MD_MAXSIDES; j++) { 950*0Sstevel@tonic-gate if (sr->sr_nodes[j][0] != '\0') 951*0Sstevel@tonic-gate continue; 952*0Sstevel@tonic-gate (void) strcpy(sr->sr_nodes[j], node_v[i]); 953*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, 954*0Sstevel@tonic-gate SVM_TAG_HOST, sr->sr_setno, j); 955*0Sstevel@tonic-gate break; 956*0Sstevel@tonic-gate } 957*0Sstevel@tonic-gate } 958*0Sstevel@tonic-gate } 959*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 960*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 961*0Sstevel@tonic-gate meta_free_nodelist(nl); 962*0Sstevel@tonic-gate } 963*0Sstevel@tonic-gate 964*0Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req)); 965*0Sstevel@tonic-gate 966*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 967*0Sstevel@tonic-gate 968*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 969*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 970*0Sstevel@tonic-gate req.ur_size = sizeof (*mnsr); 971*0Sstevel@tonic-gate } else { 972*0Sstevel@tonic-gate req.ur_size = sizeof (*sr); 973*0Sstevel@tonic-gate } 974*0Sstevel@tonic-gate req.ur_data = (uintptr_t)sr; 975*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 976*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 977*0Sstevel@tonic-gate free_sr(sr); 978*0Sstevel@tonic-gate return; 979*0Sstevel@tonic-gate } 980*0Sstevel@tonic-gate 981*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 982*0Sstevel@tonic-gate 983*0Sstevel@tonic-gate free_sr(sr); 984*0Sstevel@tonic-gate } 985*0Sstevel@tonic-gate 986*0Sstevel@tonic-gate /* 987*0Sstevel@tonic-gate * add 1 or more hosts to a set. 988*0Sstevel@tonic-gate */ 989*0Sstevel@tonic-gate bool_t 990*0Sstevel@tonic-gate mdrpc_addhosts_common( 991*0Sstevel@tonic-gate mdrpc_host_args *args, 992*0Sstevel@tonic-gate mdrpc_generic_res *res, 993*0Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */ 994*0Sstevel@tonic-gate int version /* RPC version */ 995*0Sstevel@tonic-gate ) 996*0Sstevel@tonic-gate { 997*0Sstevel@tonic-gate md_error_t *ep = &res->status; 998*0Sstevel@tonic-gate int err; 999*0Sstevel@tonic-gate int op_mode = W_OK; 1000*0Sstevel@tonic-gate 1001*0Sstevel@tonic-gate /* setup, check permissions */ 1002*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 1003*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1004*0Sstevel@tonic-gate return (FALSE); 1005*0Sstevel@tonic-gate else if (err != 0) 1006*0Sstevel@tonic-gate return (TRUE); 1007*0Sstevel@tonic-gate 1008*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 1009*0Sstevel@tonic-gate return (TRUE); 1010*0Sstevel@tonic-gate 1011*0Sstevel@tonic-gate /* doit */ 1012*0Sstevel@tonic-gate addhosts(args->sp->setname, args->hosts.hosts_len, 1013*0Sstevel@tonic-gate args->hosts.hosts_val, version, ep); 1014*0Sstevel@tonic-gate 1015*0Sstevel@tonic-gate err = svc_fini(ep); 1016*0Sstevel@tonic-gate 1017*0Sstevel@tonic-gate return (TRUE); 1018*0Sstevel@tonic-gate } 1019*0Sstevel@tonic-gate 1020*0Sstevel@tonic-gate bool_t 1021*0Sstevel@tonic-gate mdrpc_addhosts_1_svc( 1022*0Sstevel@tonic-gate mdrpc_host_args *args, 1023*0Sstevel@tonic-gate mdrpc_generic_res *res, 1024*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1025*0Sstevel@tonic-gate ) 1026*0Sstevel@tonic-gate { 1027*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */ 1028*0Sstevel@tonic-gate return (mdrpc_addhosts_common(args, res, rqstp, METAD_VERSION)); 1029*0Sstevel@tonic-gate } 1030*0Sstevel@tonic-gate 1031*0Sstevel@tonic-gate bool_t 1032*0Sstevel@tonic-gate mdrpc_addhosts_2_svc( 1033*0Sstevel@tonic-gate mdrpc_host_2_args *args, 1034*0Sstevel@tonic-gate mdrpc_generic_res *res, 1035*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1036*0Sstevel@tonic-gate ) 1037*0Sstevel@tonic-gate { 1038*0Sstevel@tonic-gate switch (args->rev) { 1039*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 1040*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 1041*0Sstevel@tonic-gate return (mdrpc_addhosts_common( 1042*0Sstevel@tonic-gate &args->mdrpc_host_2_args_u.rev1, res, 1043*0Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID)); 1044*0Sstevel@tonic-gate default: 1045*0Sstevel@tonic-gate return (FALSE); 1046*0Sstevel@tonic-gate } 1047*0Sstevel@tonic-gate } 1048*0Sstevel@tonic-gate 1049*0Sstevel@tonic-gate static void 1050*0Sstevel@tonic-gate createset( 1051*0Sstevel@tonic-gate mdsetname_t *sp, 1052*0Sstevel@tonic-gate md_node_nm_arr_t nodes, 1053*0Sstevel@tonic-gate md_timeval32_t timestamp, 1054*0Sstevel@tonic-gate ulong_t genid, 1055*0Sstevel@tonic-gate md_error_t *ep 1056*0Sstevel@tonic-gate ) 1057*0Sstevel@tonic-gate { 1058*0Sstevel@tonic-gate mddb_userreq_t req; 1059*0Sstevel@tonic-gate md_set_record *sr; 1060*0Sstevel@tonic-gate int i; 1061*0Sstevel@tonic-gate 1062*0Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 1063*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0); 1064*0Sstevel@tonic-gate req.ur_size = sizeof (*sr); 1065*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1066*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 1067*0Sstevel@tonic-gate return; 1068*0Sstevel@tonic-gate } 1069*0Sstevel@tonic-gate 1070*0Sstevel@tonic-gate sr = Zalloc(sizeof (*sr)); 1071*0Sstevel@tonic-gate 1072*0Sstevel@tonic-gate sr->sr_selfid = req.ur_recid; 1073*0Sstevel@tonic-gate sr->sr_setno = sp->setno; 1074*0Sstevel@tonic-gate (void) strcpy(sr->sr_setname, sp->setname); 1075*0Sstevel@tonic-gate 1076*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno, 1077*0Sstevel@tonic-gate NODEV64); 1078*0Sstevel@tonic-gate 1079*0Sstevel@tonic-gate (void) meta_smf_enable(META_SMF_DISKSET, NULL); 1080*0Sstevel@tonic-gate 1081*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 1082*0Sstevel@tonic-gate (void) strcpy(sr->sr_nodes[i], nodes[i]); 1083*0Sstevel@tonic-gate /* Skip empty slots */ 1084*0Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0') 1085*0Sstevel@tonic-gate continue; 1086*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno, 1087*0Sstevel@tonic-gate i); 1088*0Sstevel@tonic-gate } 1089*0Sstevel@tonic-gate 1090*0Sstevel@tonic-gate sr->sr_ctime = timestamp; 1091*0Sstevel@tonic-gate sr->sr_genid = genid; 1092*0Sstevel@tonic-gate sr->sr_revision = MD_SET_RECORD_REVISION; 1093*0Sstevel@tonic-gate sr->sr_flags |= MD_SR_ADD; 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gate sr->sr_mhiargs = defmhiargs; 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate sr_cache_add(sr); 1098*0Sstevel@tonic-gate 1099*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 1100*0Sstevel@tonic-gate } 1101*0Sstevel@tonic-gate 1102*0Sstevel@tonic-gate static void 1103*0Sstevel@tonic-gate mncreateset( 1104*0Sstevel@tonic-gate mdsetname_t *sp, 1105*0Sstevel@tonic-gate md_mnnode_desc *nodelist, 1106*0Sstevel@tonic-gate md_timeval32_t timestamp, 1107*0Sstevel@tonic-gate ulong_t genid, 1108*0Sstevel@tonic-gate md_node_nm_t master_nodenm, 1109*0Sstevel@tonic-gate int master_nodeid, 1110*0Sstevel@tonic-gate md_error_t *ep 1111*0Sstevel@tonic-gate ) 1112*0Sstevel@tonic-gate { 1113*0Sstevel@tonic-gate mddb_userreq_t req; 1114*0Sstevel@tonic-gate md_mnset_record *mnsr; 1115*0Sstevel@tonic-gate md_mnnode_record *nr; 1116*0Sstevel@tonic-gate md_mnnode_desc *nd; 1117*0Sstevel@tonic-gate mddb_set_node_params_t snp; 1118*0Sstevel@tonic-gate int nodecnt; 1119*0Sstevel@tonic-gate mndiskset_membershiplist_t *nl; 1120*0Sstevel@tonic-gate 1121*0Sstevel@tonic-gate /* 1122*0Sstevel@tonic-gate * Validate that nodes in set being created are in the 1123*0Sstevel@tonic-gate * membership list on THIS node. 1124*0Sstevel@tonic-gate * Initiating node has verified that nodes are in membership 1125*0Sstevel@tonic-gate * list on the initiating node. 1126*0Sstevel@tonic-gate * Get membershiplist from API routine. If there's 1127*0Sstevel@tonic-gate * an error, fail to add set and pass back error. 1128*0Sstevel@tonic-gate */ 1129*0Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) { 1130*0Sstevel@tonic-gate return; 1131*0Sstevel@tonic-gate } 1132*0Sstevel@tonic-gate /* Verify that all nodes are in member list */ 1133*0Sstevel@tonic-gate nd = nodelist; 1134*0Sstevel@tonic-gate while (nd) { 1135*0Sstevel@tonic-gate /* 1136*0Sstevel@tonic-gate * If node in list isn't a member of the membership, 1137*0Sstevel@tonic-gate * just return error. 1138*0Sstevel@tonic-gate */ 1139*0Sstevel@tonic-gate if (meta_is_member(nd->nd_nodename, 0, nl) == 0) { 1140*0Sstevel@tonic-gate meta_free_nodelist(nl); 1141*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST, 1142*0Sstevel@tonic-gate sp->setno, nd->nd_nodename, NULL, sp->setname); 1143*0Sstevel@tonic-gate return; 1144*0Sstevel@tonic-gate } 1145*0Sstevel@tonic-gate nd = nd->nd_next; 1146*0Sstevel@tonic-gate } 1147*0Sstevel@tonic-gate meta_free_nodelist(nl); 1148*0Sstevel@tonic-gate 1149*0Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 1150*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0); 1151*0Sstevel@tonic-gate req.ur_size = sizeof (*mnsr); 1152*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1153*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 1154*0Sstevel@tonic-gate return; 1155*0Sstevel@tonic-gate } 1156*0Sstevel@tonic-gate 1157*0Sstevel@tonic-gate mnsr = Zalloc(sizeof (*mnsr)); 1158*0Sstevel@tonic-gate mnsr->sr_selfid = req.ur_recid; 1159*0Sstevel@tonic-gate mnsr->sr_setno = sp->setno; 1160*0Sstevel@tonic-gate (void) strlcpy(mnsr->sr_setname, sp->setname, MD_MAX_SETNAME); 1161*0Sstevel@tonic-gate 1162*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno, 1163*0Sstevel@tonic-gate NODEV64); 1164*0Sstevel@tonic-gate 1165*0Sstevel@tonic-gate (void) meta_smf_enable(META_SMF_DISKSET | META_SMF_MN_DISKSET, NULL); 1166*0Sstevel@tonic-gate 1167*0Sstevel@tonic-gate nd = nodelist; 1168*0Sstevel@tonic-gate while (nd) { 1169*0Sstevel@tonic-gate /* Create the node record */ 1170*0Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 1171*0Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_CREATE, 0); 1172*0Sstevel@tonic-gate req.ur_size = sizeof (*nr); 1173*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1174*0Sstevel@tonic-gate /* Frees mnsr and any alloc'd node records */ 1175*0Sstevel@tonic-gate free_sr((struct md_set_record *)mnsr); 1176*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 1177*0Sstevel@tonic-gate return; 1178*0Sstevel@tonic-gate } 1179*0Sstevel@tonic-gate 1180*0Sstevel@tonic-gate nr = Zalloc(sizeof (*nr)); 1181*0Sstevel@tonic-gate nr->nr_revision = MD_MNNODE_RECORD_REVISION; 1182*0Sstevel@tonic-gate nr->nr_selfid = req.ur_recid; 1183*0Sstevel@tonic-gate nr->nr_ctime = timestamp; 1184*0Sstevel@tonic-gate nr->nr_genid = genid; 1185*0Sstevel@tonic-gate nr->nr_nodeid = nd->nd_nodeid; 1186*0Sstevel@tonic-gate nr->nr_flags = nd->nd_flags; 1187*0Sstevel@tonic-gate (void) strlcpy(nr->nr_nodename, nd->nd_nodename, 1188*0Sstevel@tonic-gate MD_MAX_NODENAME); 1189*0Sstevel@tonic-gate 1190*0Sstevel@tonic-gate /* Link the node records and fill in in-core data */ 1191*0Sstevel@tonic-gate mnnr_cache_add(mnsr, nr); 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno, 1194*0Sstevel@tonic-gate nr->nr_nodeid); 1195*0Sstevel@tonic-gate 1196*0Sstevel@tonic-gate nd = nd->nd_next; 1197*0Sstevel@tonic-gate } 1198*0Sstevel@tonic-gate 1199*0Sstevel@tonic-gate /* 1200*0Sstevel@tonic-gate * For backward compatibility, fill in mynode name 1201*0Sstevel@tonic-gate * as the only name in the sr_nodes array. This 1202*0Sstevel@tonic-gate * allows the pre-MNdiskset code to see that there 1203*0Sstevel@tonic-gate * is a node in this diskset. This will keep the 1204*0Sstevel@tonic-gate * pre-MNdiskset code from removing this set. 1205*0Sstevel@tonic-gate */ 1206*0Sstevel@tonic-gate (void) strlcpy(mnsr->sr_nodes_bw_compat[0], mynode(), MD_MAX_NODENAME); 1207*0Sstevel@tonic-gate 1208*0Sstevel@tonic-gate mnsr->sr_ctime = timestamp; 1209*0Sstevel@tonic-gate mnsr->sr_genid = genid; 1210*0Sstevel@tonic-gate mnsr->sr_revision = MD_SET_RECORD_REVISION; 1211*0Sstevel@tonic-gate mnsr->sr_flags |= MD_SR_ADD; 1212*0Sstevel@tonic-gate 1213*0Sstevel@tonic-gate mnsr->sr_flags |= MD_SR_MN; 1214*0Sstevel@tonic-gate strcpy(mnsr->sr_master_nodenm, master_nodenm); 1215*0Sstevel@tonic-gate mnsr->sr_master_nodeid = master_nodeid; 1216*0Sstevel@tonic-gate 1217*0Sstevel@tonic-gate mnsr->sr_mhiargs = defmhiargs; 1218*0Sstevel@tonic-gate 1219*0Sstevel@tonic-gate sr_cache_add((struct md_set_record *)mnsr); 1220*0Sstevel@tonic-gate 1221*0Sstevel@tonic-gate commitset((struct md_set_record *)mnsr, TRUE, ep); 1222*0Sstevel@tonic-gate 1223*0Sstevel@tonic-gate /* 1224*0Sstevel@tonic-gate * When a set is created for the first time, the nodelist 1225*0Sstevel@tonic-gate * will contain this node. 1226*0Sstevel@tonic-gate * When a node is just being added to a set, the nodelist 1227*0Sstevel@tonic-gate * will not contain this node. This node is added to the 1228*0Sstevel@tonic-gate * set structure with a later call to addhosts. 1229*0Sstevel@tonic-gate * 1230*0Sstevel@tonic-gate * So, if the nodelist contains an entry for this node 1231*0Sstevel@tonic-gate * then set the nodeid of this node in the md_set kernel 1232*0Sstevel@tonic-gate * data structure. 1233*0Sstevel@tonic-gate */ 1234*0Sstevel@tonic-gate nd = nodelist; 1235*0Sstevel@tonic-gate while (nd) { 1236*0Sstevel@tonic-gate if (strcmp(nd->nd_nodename, mynode()) == 0) { 1237*0Sstevel@tonic-gate break; 1238*0Sstevel@tonic-gate } 1239*0Sstevel@tonic-gate nd = nd->nd_next; 1240*0Sstevel@tonic-gate } 1241*0Sstevel@tonic-gate if (nd) { 1242*0Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp)); 1243*0Sstevel@tonic-gate snp.sn_nodeid = nd->nd_nodeid; 1244*0Sstevel@tonic-gate snp.sn_setno = sp->setno; 1245*0Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp, &snp.sn_mde, NULL) != 0) { 1246*0Sstevel@tonic-gate (void) mdstealerror(ep, &snp.sn_mde); 1247*0Sstevel@tonic-gate return; 1248*0Sstevel@tonic-gate } 1249*0Sstevel@tonic-gate } 1250*0Sstevel@tonic-gate } 1251*0Sstevel@tonic-gate 1252*0Sstevel@tonic-gate /* 1253*0Sstevel@tonic-gate * create a set on a host 1254*0Sstevel@tonic-gate */ 1255*0Sstevel@tonic-gate bool_t 1256*0Sstevel@tonic-gate mdrpc_createset_common( 1257*0Sstevel@tonic-gate mdrpc_createset_args *args, 1258*0Sstevel@tonic-gate mdrpc_generic_res *res, 1259*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1260*0Sstevel@tonic-gate ) 1261*0Sstevel@tonic-gate { 1262*0Sstevel@tonic-gate md_error_t *ep = &res->status; 1263*0Sstevel@tonic-gate char stringbuf1[MAXPATHLEN]; 1264*0Sstevel@tonic-gate char stringbuf2[MAXPATHLEN]; 1265*0Sstevel@tonic-gate int err; 1266*0Sstevel@tonic-gate int op_mode = W_OK; 1267*0Sstevel@tonic-gate 1268*0Sstevel@tonic-gate /* setup, check permissions */ 1269*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 1270*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1271*0Sstevel@tonic-gate return (FALSE); 1272*0Sstevel@tonic-gate else if (err != 0) 1273*0Sstevel@tonic-gate return (TRUE); 1274*0Sstevel@tonic-gate 1275*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 1276*0Sstevel@tonic-gate return (TRUE); 1277*0Sstevel@tonic-gate 1278*0Sstevel@tonic-gate /* create the arguments for the symlink() and unlink() calls */ 1279*0Sstevel@tonic-gate (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s", 1280*0Sstevel@tonic-gate args->sp->setname); 1281*0Sstevel@tonic-gate (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d", 1282*0Sstevel@tonic-gate args->sp->setno); 1283*0Sstevel@tonic-gate 1284*0Sstevel@tonic-gate /* 1285*0Sstevel@tonic-gate * Since we already verified that the setname was OK, make sure to 1286*0Sstevel@tonic-gate * cleanup before proceeding. 1287*0Sstevel@tonic-gate */ 1288*0Sstevel@tonic-gate if (unlink(stringbuf2) == -1) { 1289*0Sstevel@tonic-gate if (errno != ENOENT) { 1290*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2); 1291*0Sstevel@tonic-gate return (TRUE); 1292*0Sstevel@tonic-gate } 1293*0Sstevel@tonic-gate } 1294*0Sstevel@tonic-gate 1295*0Sstevel@tonic-gate /* create the set */ 1296*0Sstevel@tonic-gate createset(args->sp, args->nodes, args->timestamp, args->genid, ep); 1297*0Sstevel@tonic-gate 1298*0Sstevel@tonic-gate if (! mdisok(ep)) 1299*0Sstevel@tonic-gate return (TRUE); 1300*0Sstevel@tonic-gate 1301*0Sstevel@tonic-gate /* create the symlink */ 1302*0Sstevel@tonic-gate if (symlink(stringbuf1, stringbuf2) == -1) 1303*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2); 1304*0Sstevel@tonic-gate 1305*0Sstevel@tonic-gate err = svc_fini(ep); 1306*0Sstevel@tonic-gate 1307*0Sstevel@tonic-gate return (TRUE); 1308*0Sstevel@tonic-gate } 1309*0Sstevel@tonic-gate 1310*0Sstevel@tonic-gate bool_t 1311*0Sstevel@tonic-gate mdrpc_createset_1_svc( 1312*0Sstevel@tonic-gate mdrpc_createset_args *args, 1313*0Sstevel@tonic-gate mdrpc_generic_res *res, 1314*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1315*0Sstevel@tonic-gate ) 1316*0Sstevel@tonic-gate { 1317*0Sstevel@tonic-gate return (mdrpc_createset_common(args, res, rqstp)); 1318*0Sstevel@tonic-gate } 1319*0Sstevel@tonic-gate 1320*0Sstevel@tonic-gate bool_t 1321*0Sstevel@tonic-gate mdrpc_createset_2_svc( 1322*0Sstevel@tonic-gate mdrpc_createset_2_args *args, 1323*0Sstevel@tonic-gate mdrpc_generic_res *res, 1324*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1325*0Sstevel@tonic-gate ) 1326*0Sstevel@tonic-gate { 1327*0Sstevel@tonic-gate switch (args->rev) { 1328*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 1329*0Sstevel@tonic-gate return (mdrpc_createset_common( 1330*0Sstevel@tonic-gate &args->mdrpc_createset_2_args_u.rev1, res, rqstp)); 1331*0Sstevel@tonic-gate default: 1332*0Sstevel@tonic-gate return (FALSE); 1333*0Sstevel@tonic-gate } 1334*0Sstevel@tonic-gate } 1335*0Sstevel@tonic-gate 1336*0Sstevel@tonic-gate bool_t 1337*0Sstevel@tonic-gate mdrpc_mncreateset_common( 1338*0Sstevel@tonic-gate mdrpc_mncreateset_args *args, 1339*0Sstevel@tonic-gate mdrpc_generic_res *res, 1340*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1341*0Sstevel@tonic-gate ) 1342*0Sstevel@tonic-gate { 1343*0Sstevel@tonic-gate md_error_t *ep = &res->status; 1344*0Sstevel@tonic-gate char stringbuf1[MAXPATHLEN]; 1345*0Sstevel@tonic-gate char stringbuf2[MAXPATHLEN]; 1346*0Sstevel@tonic-gate int err; 1347*0Sstevel@tonic-gate int op_mode = W_OK; 1348*0Sstevel@tonic-gate 1349*0Sstevel@tonic-gate /* setup, check permissions */ 1350*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 1351*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1352*0Sstevel@tonic-gate return (FALSE); 1353*0Sstevel@tonic-gate else if (err != 0) 1354*0Sstevel@tonic-gate return (TRUE); 1355*0Sstevel@tonic-gate 1356*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 1357*0Sstevel@tonic-gate return (TRUE); 1358*0Sstevel@tonic-gate 1359*0Sstevel@tonic-gate /* create the arguments for the symlink() and unlink() calls */ 1360*0Sstevel@tonic-gate (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s", 1361*0Sstevel@tonic-gate args->sp->setname); 1362*0Sstevel@tonic-gate (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d", 1363*0Sstevel@tonic-gate args->sp->setno); 1364*0Sstevel@tonic-gate 1365*0Sstevel@tonic-gate /* 1366*0Sstevel@tonic-gate * Since we already verified that the setname was OK, make sure to 1367*0Sstevel@tonic-gate * cleanup before proceeding. 1368*0Sstevel@tonic-gate */ 1369*0Sstevel@tonic-gate if (unlink(stringbuf2) == -1) { 1370*0Sstevel@tonic-gate if (errno != ENOENT) { 1371*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2); 1372*0Sstevel@tonic-gate return (TRUE); 1373*0Sstevel@tonic-gate } 1374*0Sstevel@tonic-gate } 1375*0Sstevel@tonic-gate 1376*0Sstevel@tonic-gate /* create the set */ 1377*0Sstevel@tonic-gate mncreateset(args->sp, args->nodelist, args->timestamp, args->genid, 1378*0Sstevel@tonic-gate args->master_nodenm, args->master_nodeid, ep); 1379*0Sstevel@tonic-gate 1380*0Sstevel@tonic-gate if (! mdisok(ep)) { 1381*0Sstevel@tonic-gate return (TRUE); 1382*0Sstevel@tonic-gate } 1383*0Sstevel@tonic-gate 1384*0Sstevel@tonic-gate /* create the symlink */ 1385*0Sstevel@tonic-gate if (symlink(stringbuf1, stringbuf2) == -1) 1386*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2); 1387*0Sstevel@tonic-gate 1388*0Sstevel@tonic-gate err = svc_fini(ep); 1389*0Sstevel@tonic-gate 1390*0Sstevel@tonic-gate return (TRUE); 1391*0Sstevel@tonic-gate } 1392*0Sstevel@tonic-gate 1393*0Sstevel@tonic-gate bool_t 1394*0Sstevel@tonic-gate mdrpc_mncreateset_2_svc( 1395*0Sstevel@tonic-gate mdrpc_mncreateset_2_args *args, 1396*0Sstevel@tonic-gate mdrpc_generic_res *res, 1397*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1398*0Sstevel@tonic-gate ) 1399*0Sstevel@tonic-gate { 1400*0Sstevel@tonic-gate switch (args->rev) { 1401*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 1402*0Sstevel@tonic-gate return (mdrpc_mncreateset_common( 1403*0Sstevel@tonic-gate &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp)); 1404*0Sstevel@tonic-gate default: 1405*0Sstevel@tonic-gate return (FALSE); 1406*0Sstevel@tonic-gate } 1407*0Sstevel@tonic-gate } 1408*0Sstevel@tonic-gate 1409*0Sstevel@tonic-gate static void 1410*0Sstevel@tonic-gate del_drv_sidenms( 1411*0Sstevel@tonic-gate mdsetname_t *sp, 1412*0Sstevel@tonic-gate int version, /* RPC version of calling routine */ 1413*0Sstevel@tonic-gate md_error_t *ep 1414*0Sstevel@tonic-gate ) 1415*0Sstevel@tonic-gate { 1416*0Sstevel@tonic-gate md_set_record *sr; 1417*0Sstevel@tonic-gate md_drive_desc *dd, *p; 1418*0Sstevel@tonic-gate mddrivename_t *dn; 1419*0Sstevel@tonic-gate mdsetname_t *local_sp; 1420*0Sstevel@tonic-gate int i; 1421*0Sstevel@tonic-gate int rb_mode = 0; 1422*0Sstevel@tonic-gate 1423*0Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 1424*0Sstevel@tonic-gate return; 1425*0Sstevel@tonic-gate 1426*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 1427*0Sstevel@tonic-gate return; 1428*0Sstevel@tonic-gate 1429*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 1430*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 1431*0Sstevel@tonic-gate /* 1432*0Sstevel@tonic-gate * In the multi-node diskset, there are no diskset 1433*0Sstevel@tonic-gate * entries in the local set for other nodes, so there's 1434*0Sstevel@tonic-gate * nothing to do. 1435*0Sstevel@tonic-gate */ 1436*0Sstevel@tonic-gate free_sr(sr); 1437*0Sstevel@tonic-gate return; 1438*0Sstevel@tonic-gate } 1439*0Sstevel@tonic-gate 1440*0Sstevel@tonic-gate if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST), 1441*0Sstevel@tonic-gate ep)) == NULL) { 1442*0Sstevel@tonic-gate if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) { 1443*0Sstevel@tonic-gate metaflushsetname(sp); 1444*0Sstevel@tonic-gate if (! mdisok(ep)) { 1445*0Sstevel@tonic-gate free_sr(sr); 1446*0Sstevel@tonic-gate return; 1447*0Sstevel@tonic-gate } 1448*0Sstevel@tonic-gate /* we are supposed to have drives!!!! */ 1449*0Sstevel@tonic-gate assert(0); 1450*0Sstevel@tonic-gate } 1451*0Sstevel@tonic-gate rb_mode = 1; 1452*0Sstevel@tonic-gate mdclrerror(ep); 1453*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 1454*0Sstevel@tonic-gate /* Skip empty sides of the diskset */ 1455*0Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0') 1456*0Sstevel@tonic-gate continue; 1457*0Sstevel@tonic-gate dd = metaget_drivedesc_sideno(sp, i, 1458*0Sstevel@tonic-gate (MD_BASICNAME_OK | PRINT_FAST), ep); 1459*0Sstevel@tonic-gate /* Got dd, get out of loop */ 1460*0Sstevel@tonic-gate if (dd != NULL) 1461*0Sstevel@tonic-gate break; 1462*0Sstevel@tonic-gate 1463*0Sstevel@tonic-gate /* some error occurred, get out of loop */ 1464*0Sstevel@tonic-gate if (! mdisok(ep)) 1465*0Sstevel@tonic-gate break; 1466*0Sstevel@tonic-gate } 1467*0Sstevel@tonic-gate /* 1468*0Sstevel@tonic-gate * At this point, we have one of three possibilities: 1469*0Sstevel@tonic-gate * 1) dd != NULL (we have found drives using an alternate 1470*0Sstevel@tonic-gate * side.) 1471*0Sstevel@tonic-gate * 2) dd == NULL (no drives) && mdisok(ep) : assert(0) 1472*0Sstevel@tonic-gate * 3) dd == NULL (no drives) && ! mdisok(ep) : return 1473*0Sstevel@tonic-gate * error information to caller. 1474*0Sstevel@tonic-gate */ 1475*0Sstevel@tonic-gate if (dd == NULL) { 1476*0Sstevel@tonic-gate metaflushsetname(sp); 1477*0Sstevel@tonic-gate if (! mdisok(ep)) { 1478*0Sstevel@tonic-gate free_sr(sr); 1479*0Sstevel@tonic-gate return; 1480*0Sstevel@tonic-gate } 1481*0Sstevel@tonic-gate /* we are supposed to have drives!!!! */ 1482*0Sstevel@tonic-gate assert(0); 1483*0Sstevel@tonic-gate } 1484*0Sstevel@tonic-gate } 1485*0Sstevel@tonic-gate 1486*0Sstevel@tonic-gate /* 1487*0Sstevel@tonic-gate * Let's run through each drive descriptor, and delete the 1488*0Sstevel@tonic-gate * sidename for all sides that are not in the sr_nodes array. 1489*0Sstevel@tonic-gate * We will ignore errors, cause the empty side may not 1490*0Sstevel@tonic-gate * have had any names to begin with. 1491*0Sstevel@tonic-gate */ 1492*0Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) { 1493*0Sstevel@tonic-gate dn = p->dd_dnp; 1494*0Sstevel@tonic-gate 1495*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 1496*0Sstevel@tonic-gate /* Skip existing sides of the diskset */ 1497*0Sstevel@tonic-gate if (!rb_mode && sr->sr_nodes[i][0] != '\0') 1498*0Sstevel@tonic-gate continue; 1499*0Sstevel@tonic-gate /* An empty side, delete the sidename */ 1500*0Sstevel@tonic-gate if (del_name(local_sp, i+SKEW, 1501*0Sstevel@tonic-gate dn->side_names_key, ep)) { 1502*0Sstevel@tonic-gate if (!mdissyserror(ep, ENOENT)) { 1503*0Sstevel@tonic-gate free_sr(sr); 1504*0Sstevel@tonic-gate return; 1505*0Sstevel@tonic-gate } 1506*0Sstevel@tonic-gate mdclrerror(ep); 1507*0Sstevel@tonic-gate } 1508*0Sstevel@tonic-gate } 1509*0Sstevel@tonic-gate } 1510*0Sstevel@tonic-gate free_sr(sr); 1511*0Sstevel@tonic-gate metaflushsetname(sp); 1512*0Sstevel@tonic-gate } 1513*0Sstevel@tonic-gate 1514*0Sstevel@tonic-gate /* 1515*0Sstevel@tonic-gate * delete 1 or more sidenames per drive desc, from the local namespace 1516*0Sstevel@tonic-gate */ 1517*0Sstevel@tonic-gate bool_t 1518*0Sstevel@tonic-gate mdrpc_del_drv_sidenms_common( 1519*0Sstevel@tonic-gate mdrpc_sp_args *args, 1520*0Sstevel@tonic-gate mdrpc_generic_res *res, 1521*0Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */ 1522*0Sstevel@tonic-gate int version /* RPC version */ 1523*0Sstevel@tonic-gate ) 1524*0Sstevel@tonic-gate { 1525*0Sstevel@tonic-gate md_error_t *ep = &res->status; 1526*0Sstevel@tonic-gate int err; 1527*0Sstevel@tonic-gate int op_mode = W_OK; 1528*0Sstevel@tonic-gate 1529*0Sstevel@tonic-gate /* setup, check permissions */ 1530*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 1531*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1532*0Sstevel@tonic-gate return (FALSE); 1533*0Sstevel@tonic-gate else if (err != 0) 1534*0Sstevel@tonic-gate return (TRUE); 1535*0Sstevel@tonic-gate 1536*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 1537*0Sstevel@tonic-gate return (TRUE); 1538*0Sstevel@tonic-gate 1539*0Sstevel@tonic-gate /* doit */ 1540*0Sstevel@tonic-gate del_drv_sidenms(args->sp, version, ep); 1541*0Sstevel@tonic-gate 1542*0Sstevel@tonic-gate err = svc_fini(ep); 1543*0Sstevel@tonic-gate 1544*0Sstevel@tonic-gate return (TRUE); 1545*0Sstevel@tonic-gate } 1546*0Sstevel@tonic-gate 1547*0Sstevel@tonic-gate bool_t 1548*0Sstevel@tonic-gate mdrpc_del_drv_sidenms_1_svc( 1549*0Sstevel@tonic-gate mdrpc_sp_args *args, 1550*0Sstevel@tonic-gate mdrpc_generic_res *res, 1551*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1552*0Sstevel@tonic-gate ) 1553*0Sstevel@tonic-gate { 1554*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */ 1555*0Sstevel@tonic-gate return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION)); 1556*0Sstevel@tonic-gate } 1557*0Sstevel@tonic-gate 1558*0Sstevel@tonic-gate bool_t 1559*0Sstevel@tonic-gate mdrpc_del_drv_sidenms_2_svc( 1560*0Sstevel@tonic-gate mdrpc_sp_2_args *args, 1561*0Sstevel@tonic-gate mdrpc_generic_res *res, 1562*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1563*0Sstevel@tonic-gate ) 1564*0Sstevel@tonic-gate { 1565*0Sstevel@tonic-gate switch (args->rev) { 1566*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 1567*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 1568*0Sstevel@tonic-gate return (mdrpc_del_drv_sidenms_common( 1569*0Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, 1570*0Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID)); 1571*0Sstevel@tonic-gate default: 1572*0Sstevel@tonic-gate return (FALSE); 1573*0Sstevel@tonic-gate } 1574*0Sstevel@tonic-gate } 1575*0Sstevel@tonic-gate 1576*0Sstevel@tonic-gate static int 1577*0Sstevel@tonic-gate del_sidenamelist( 1578*0Sstevel@tonic-gate md_set_record *sr, 1579*0Sstevel@tonic-gate mddrivename_t *dn, 1580*0Sstevel@tonic-gate md_error_t *ep 1581*0Sstevel@tonic-gate ) 1582*0Sstevel@tonic-gate { 1583*0Sstevel@tonic-gate mdsidenames_t *sn; 1584*0Sstevel@tonic-gate mdsetname_t *local_sp; 1585*0Sstevel@tonic-gate md_mnset_record *mnsr; 1586*0Sstevel@tonic-gate md_mnnode_record *nr; 1587*0Sstevel@tonic-gate 1588*0Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) 1589*0Sstevel@tonic-gate return (-1); 1590*0Sstevel@tonic-gate 1591*0Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) 1592*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) { 1593*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 1594*0Sstevel@tonic-gate /* 1595*0Sstevel@tonic-gate * Only delete side name entries for this node 1596*0Sstevel@tonic-gate * on a multi-node diskset. 1597*0Sstevel@tonic-gate */ 1598*0Sstevel@tonic-gate nr = mnsr->sr_nodechain; 1599*0Sstevel@tonic-gate while (nr) { 1600*0Sstevel@tonic-gate if (nr->nr_nodeid == sn->sideno) { 1601*0Sstevel@tonic-gate if (del_name(local_sp, sn->sideno, 1602*0Sstevel@tonic-gate dn->side_names_key, ep) == -1) 1603*0Sstevel@tonic-gate mdclrerror(ep); /* ignore err */ 1604*0Sstevel@tonic-gate break; 1605*0Sstevel@tonic-gate } 1606*0Sstevel@tonic-gate nr = nr->nr_next; 1607*0Sstevel@tonic-gate } 1608*0Sstevel@tonic-gate } else { 1609*0Sstevel@tonic-gate if (del_name(local_sp, sn->sideno+SKEW, 1610*0Sstevel@tonic-gate dn->side_names_key, ep) == -1) 1611*0Sstevel@tonic-gate mdclrerror(ep); /* ignore errors */ 1612*0Sstevel@tonic-gate } 1613*0Sstevel@tonic-gate 1614*0Sstevel@tonic-gate dn->side_names_key = MD_KEYBAD; 1615*0Sstevel@tonic-gate return (0); 1616*0Sstevel@tonic-gate } 1617*0Sstevel@tonic-gate 1618*0Sstevel@tonic-gate static void 1619*0Sstevel@tonic-gate deldrvs( 1620*0Sstevel@tonic-gate char *setname, 1621*0Sstevel@tonic-gate md_drive_desc *dd, 1622*0Sstevel@tonic-gate md_error_t *ep 1623*0Sstevel@tonic-gate ) 1624*0Sstevel@tonic-gate { 1625*0Sstevel@tonic-gate mdsetname_t *sp; 1626*0Sstevel@tonic-gate md_set_record *sr; 1627*0Sstevel@tonic-gate md_drive_record *dr; 1628*0Sstevel@tonic-gate mddb_userreq_t req; 1629*0Sstevel@tonic-gate md_drive_desc *p; 1630*0Sstevel@tonic-gate mddrivename_t *dn, *dn1; 1631*0Sstevel@tonic-gate side_t sideno; 1632*0Sstevel@tonic-gate int i; 1633*0Sstevel@tonic-gate int rb_mode = 0; 1634*0Sstevel@tonic-gate mdname_t *np; 1635*0Sstevel@tonic-gate md_dev64_t dev; 1636*0Sstevel@tonic-gate md_error_t xep = mdnullerror; 1637*0Sstevel@tonic-gate ddi_devid_t devid_remote = NULL; 1638*0Sstevel@tonic-gate ddi_devid_t devid_local = NULL; 1639*0Sstevel@tonic-gate int devid_same = -1; 1640*0Sstevel@tonic-gate int using_devid = 0; 1641*0Sstevel@tonic-gate md_mnnode_record *nr; 1642*0Sstevel@tonic-gate md_mnset_record *mnsr; 1643*0Sstevel@tonic-gate 1644*0Sstevel@tonic-gate if ((sp = metasetname(setname, ep)) == NULL) 1645*0Sstevel@tonic-gate return; 1646*0Sstevel@tonic-gate 1647*0Sstevel@tonic-gate metaflushsetname(sp); 1648*0Sstevel@tonic-gate 1649*0Sstevel@tonic-gate if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) { 1650*0Sstevel@tonic-gate if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) 1651*0Sstevel@tonic-gate return; 1652*0Sstevel@tonic-gate mdclrerror(ep); 1653*0Sstevel@tonic-gate /* 1654*0Sstevel@tonic-gate * The set record is incomplete, so we need to make note 1655*0Sstevel@tonic-gate * here so that we can do some special handling later. 1656*0Sstevel@tonic-gate */ 1657*0Sstevel@tonic-gate rb_mode = 1; 1658*0Sstevel@tonic-gate } 1659*0Sstevel@tonic-gate 1660*0Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL) 1661*0Sstevel@tonic-gate return; 1662*0Sstevel@tonic-gate 1663*0Sstevel@tonic-gate if (dd->dd_dnp == NULL) 1664*0Sstevel@tonic-gate return; 1665*0Sstevel@tonic-gate 1666*0Sstevel@tonic-gate /* 1667*0Sstevel@tonic-gate * The system is either all devid or all 1668*0Sstevel@tonic-gate * non-devid so we determine this by looking 1669*0Sstevel@tonic-gate * at the first item in the list. 1670*0Sstevel@tonic-gate * 1671*0Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which 1672*0Sstevel@tonic-gate * points to a '' string of devid. We need to check this 1673*0Sstevel@tonic-gate * before set the using_devid. 1674*0Sstevel@tonic-gate */ 1675*0Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 1676*0Sstevel@tonic-gate (!(MD_MNSET_REC(sr)))) 1677*0Sstevel@tonic-gate using_devid = 1; 1678*0Sstevel@tonic-gate 1679*0Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) { 1680*0Sstevel@tonic-gate dn = p->dd_dnp; 1681*0Sstevel@tonic-gate devid_remote = NULL; 1682*0Sstevel@tonic-gate 1683*0Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) && 1684*0Sstevel@tonic-gate using_devid) { 1685*0Sstevel@tonic-gate /* 1686*0Sstevel@tonic-gate * We have a devid so use it 1687*0Sstevel@tonic-gate */ 1688*0Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL); 1689*0Sstevel@tonic-gate } 1690*0Sstevel@tonic-gate 1691*0Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */ 1692*0Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) { 1693*0Sstevel@tonic-gate /* something went really wrong. Can't process */ 1694*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 1695*0Sstevel@tonic-gate mynode(), dn->cname, sp->setname); 1696*0Sstevel@tonic-gate return; 1697*0Sstevel@tonic-gate } 1698*0Sstevel@tonic-gate 1699*0Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 1700*0Sstevel@tonic-gate devid_same = -1; 1701*0Sstevel@tonic-gate 1702*0Sstevel@tonic-gate if (! rb_mode) { 1703*0Sstevel@tonic-gate dn1 = metadrivename_withdrkey(sp, sideno, 1704*0Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep); 1705*0Sstevel@tonic-gate if (dn1 == NULL) { 1706*0Sstevel@tonic-gate free_sr(sr); 1707*0Sstevel@tonic-gate if (devid_remote) 1708*0Sstevel@tonic-gate devid_free(devid_remote); 1709*0Sstevel@tonic-gate return; 1710*0Sstevel@tonic-gate } 1711*0Sstevel@tonic-gate } else { 1712*0Sstevel@tonic-gate /* 1713*0Sstevel@tonic-gate * Handle special case here where sidenames 1714*0Sstevel@tonic-gate * from other hosts for this drive may be 1715*0Sstevel@tonic-gate * in the local mddb, but there is no 1716*0Sstevel@tonic-gate * sidename entry for this host for this drive. 1717*0Sstevel@tonic-gate * This could have happened if the node 1718*0Sstevel@tonic-gate * panic'd between the 2 operations when 1719*0Sstevel@tonic-gate * adding this node to the set. 1720*0Sstevel@tonic-gate * So, delete all sidename entries for this 1721*0Sstevel@tonic-gate * drive. 1722*0Sstevel@tonic-gate */ 1723*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) { 1724*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 1725*0Sstevel@tonic-gate nr = mnsr->sr_nodechain; 1726*0Sstevel@tonic-gate while (nr) { 1727*0Sstevel@tonic-gate /* We delete all dr sides */ 1728*0Sstevel@tonic-gate dn1 = metadrivename_withdrkey( 1729*0Sstevel@tonic-gate sp, nr->nr_nodeid, 1730*0Sstevel@tonic-gate dr->dr_key, 1731*0Sstevel@tonic-gate MD_BASICNAME_OK, ep); 1732*0Sstevel@tonic-gate 1733*0Sstevel@tonic-gate /* if we do, get out of loop */ 1734*0Sstevel@tonic-gate if (dn1 != NULL) 1735*0Sstevel@tonic-gate break; 1736*0Sstevel@tonic-gate 1737*0Sstevel@tonic-gate /* save error for later */ 1738*0Sstevel@tonic-gate (void) mdstealerror(&xep, ep); 1739*0Sstevel@tonic-gate 1740*0Sstevel@tonic-gate mdclrerror(ep); 1741*0Sstevel@tonic-gate 1742*0Sstevel@tonic-gate nr = nr->nr_next; 1743*0Sstevel@tonic-gate } 1744*0Sstevel@tonic-gate } else { 1745*0Sstevel@tonic-gate /* 1746*0Sstevel@tonic-gate * Handle special case here 1747*0Sstevel@tonic-gate * for traditional diskset 1748*0Sstevel@tonic-gate */ 1749*0Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) { 1750*0Sstevel@tonic-gate /* We delete all dr sides */ 1751*0Sstevel@tonic-gate dn1 = metadrivename_withdrkey( 1752*0Sstevel@tonic-gate sp, i, dr->dr_key, 1753*0Sstevel@tonic-gate MD_BASICNAME_OK, ep); 1754*0Sstevel@tonic-gate 1755*0Sstevel@tonic-gate /* if we do, get out of loop */ 1756*0Sstevel@tonic-gate if (dn1 != NULL) 1757*0Sstevel@tonic-gate break; 1758*0Sstevel@tonic-gate 1759*0Sstevel@tonic-gate /* save error for later */ 1760*0Sstevel@tonic-gate (void) mdstealerror(&xep, ep); 1761*0Sstevel@tonic-gate 1762*0Sstevel@tonic-gate mdclrerror(ep); 1763*0Sstevel@tonic-gate } 1764*0Sstevel@tonic-gate } 1765*0Sstevel@tonic-gate 1766*0Sstevel@tonic-gate if (dn1 == NULL) { 1767*0Sstevel@tonic-gate (void) mdstealerror(ep, &xep); 1768*0Sstevel@tonic-gate free_sr(sr); 1769*0Sstevel@tonic-gate if (devid_remote) 1770*0Sstevel@tonic-gate devid_free(devid_remote); 1771*0Sstevel@tonic-gate return; 1772*0Sstevel@tonic-gate } 1773*0Sstevel@tonic-gate 1774*0Sstevel@tonic-gate if (!using_devid) 1775*0Sstevel@tonic-gate mdclrerror(ep); 1776*0Sstevel@tonic-gate } 1777*0Sstevel@tonic-gate 1778*0Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) { 1779*0Sstevel@tonic-gate if (devid_str_decode(dn1->devid, &devid_local, 1780*0Sstevel@tonic-gate NULL) == 0) { 1781*0Sstevel@tonic-gate devid_same = devid_compare(devid_remote, 1782*0Sstevel@tonic-gate devid_local); 1783*0Sstevel@tonic-gate devid_free(devid_local); 1784*0Sstevel@tonic-gate } 1785*0Sstevel@tonic-gate } 1786*0Sstevel@tonic-gate 1787*0Sstevel@tonic-gate /* 1788*0Sstevel@tonic-gate * Has the required disk been found - either the devids 1789*0Sstevel@tonic-gate * match if devid are being used or the actual name of 1790*0Sstevel@tonic-gate * the disk matches. 1791*0Sstevel@tonic-gate */ 1792*0Sstevel@tonic-gate if ((using_devid && devid_same == 0) || 1793*0Sstevel@tonic-gate (!using_devid && 1794*0Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)) { 1795*0Sstevel@tonic-gate uint_t rep_slice; 1796*0Sstevel@tonic-gate 1797*0Sstevel@tonic-gate dev = NODEV64; 1798*0Sstevel@tonic-gate np = NULL; 1799*0Sstevel@tonic-gate if (meta_replicaslice(dn1, 1800*0Sstevel@tonic-gate &rep_slice, &xep) == 0) { 1801*0Sstevel@tonic-gate np = metaslicename(dn1, 1802*0Sstevel@tonic-gate rep_slice, &xep); 1803*0Sstevel@tonic-gate } 1804*0Sstevel@tonic-gate 1805*0Sstevel@tonic-gate if (np != NULL) 1806*0Sstevel@tonic-gate dev = np->dev; 1807*0Sstevel@tonic-gate else 1808*0Sstevel@tonic-gate mdclrerror(&xep); 1809*0Sstevel@tonic-gate break; 1810*0Sstevel@tonic-gate } 1811*0Sstevel@tonic-gate } 1812*0Sstevel@tonic-gate 1813*0Sstevel@tonic-gate if (dr) { 1814*0Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 1815*0Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid) 1816*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) 1817*0Sstevel@tonic-gate != 0) { 1818*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 1819*0Sstevel@tonic-gate if (devid_remote) 1820*0Sstevel@tonic-gate devid_free(devid_remote); 1821*0Sstevel@tonic-gate free_sr(sr); 1822*0Sstevel@tonic-gate return; 1823*0Sstevel@tonic-gate } 1824*0Sstevel@tonic-gate 1825*0Sstevel@tonic-gate dr_cache_del(sr, dr->dr_selfid); 1826*0Sstevel@tonic-gate 1827*0Sstevel@tonic-gate if (del_sidenamelist(sr, dn1, ep) == -1) { 1828*0Sstevel@tonic-gate goto out; 1829*0Sstevel@tonic-gate } 1830*0Sstevel@tonic-gate 1831*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE, 1832*0Sstevel@tonic-gate sr->sr_setno, dev); 1833*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE, 1834*0Sstevel@tonic-gate MD_LOCAL_SET, dev); 1835*0Sstevel@tonic-gate 1836*0Sstevel@tonic-gate continue; 1837*0Sstevel@tonic-gate } 1838*0Sstevel@tonic-gate 1839*0Sstevel@tonic-gate if (devid_remote) 1840*0Sstevel@tonic-gate devid_free(devid_remote); 1841*0Sstevel@tonic-gate } 1842*0Sstevel@tonic-gate 1843*0Sstevel@tonic-gate out: 1844*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 1845*0Sstevel@tonic-gate 1846*0Sstevel@tonic-gate free_sr(sr); 1847*0Sstevel@tonic-gate } 1848*0Sstevel@tonic-gate 1849*0Sstevel@tonic-gate /* 1850*0Sstevel@tonic-gate * delete 1 or more drive records from a host. 1851*0Sstevel@tonic-gate */ 1852*0Sstevel@tonic-gate bool_t 1853*0Sstevel@tonic-gate mdrpc_deldrvs_common( 1854*0Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args, 1855*0Sstevel@tonic-gate mdrpc_generic_res *res, 1856*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1857*0Sstevel@tonic-gate ) 1858*0Sstevel@tonic-gate { 1859*0Sstevel@tonic-gate md_error_t *ep = &res->status; 1860*0Sstevel@tonic-gate int err; 1861*0Sstevel@tonic-gate int op_mode = W_OK; 1862*0Sstevel@tonic-gate 1863*0Sstevel@tonic-gate /* setup, check permissions */ 1864*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 1865*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 1866*0Sstevel@tonic-gate return (FALSE); 1867*0Sstevel@tonic-gate else if (err != 0) 1868*0Sstevel@tonic-gate return (TRUE); 1869*0Sstevel@tonic-gate 1870*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 1871*0Sstevel@tonic-gate return (TRUE); 1872*0Sstevel@tonic-gate 1873*0Sstevel@tonic-gate /* doit */ 1874*0Sstevel@tonic-gate deldrvs(args->sp->setname, args->drivedescs, ep); 1875*0Sstevel@tonic-gate 1876*0Sstevel@tonic-gate err = svc_fini(ep); 1877*0Sstevel@tonic-gate 1878*0Sstevel@tonic-gate return (TRUE); 1879*0Sstevel@tonic-gate } 1880*0Sstevel@tonic-gate 1881*0Sstevel@tonic-gate /* 1882*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 1883*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 1884*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 1885*0Sstevel@tonic-gate */ 1886*0Sstevel@tonic-gate bool_t 1887*0Sstevel@tonic-gate mdrpc_deldrvs_1_svc( 1888*0Sstevel@tonic-gate mdrpc_drives_args *args, 1889*0Sstevel@tonic-gate mdrpc_generic_res *res, 1890*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1891*0Sstevel@tonic-gate ) 1892*0Sstevel@tonic-gate { 1893*0Sstevel@tonic-gate bool_t retval; 1894*0Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args; 1895*0Sstevel@tonic-gate 1896*0Sstevel@tonic-gate /* allocate memory */ 1897*0Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 1898*0Sstevel@tonic-gate 1899*0Sstevel@tonic-gate /* build args */ 1900*0Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk; 1901*0Sstevel@tonic-gate v2_args.sp = args->sp; 1902*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 1903*0Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 1904*0Sstevel@tonic-gate v2_args.timestamp = args->timestamp; 1905*0Sstevel@tonic-gate v2_args.genid = args->genid; 1906*0Sstevel@tonic-gate 1907*0Sstevel@tonic-gate retval = mdrpc_deldrvs_common(&v2_args, res, rqstp); 1908*0Sstevel@tonic-gate 1909*0Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs); 1910*0Sstevel@tonic-gate 1911*0Sstevel@tonic-gate return (retval); 1912*0Sstevel@tonic-gate } 1913*0Sstevel@tonic-gate 1914*0Sstevel@tonic-gate bool_t 1915*0Sstevel@tonic-gate mdrpc_deldrvs_2_svc( 1916*0Sstevel@tonic-gate mdrpc_drives_2_args *args, 1917*0Sstevel@tonic-gate mdrpc_generic_res *res, 1918*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 1919*0Sstevel@tonic-gate ) 1920*0Sstevel@tonic-gate { 1921*0Sstevel@tonic-gate switch (args->rev) { 1922*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 1923*0Sstevel@tonic-gate return (mdrpc_deldrvs_common( 1924*0Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 1925*0Sstevel@tonic-gate default: 1926*0Sstevel@tonic-gate return (FALSE); 1927*0Sstevel@tonic-gate } 1928*0Sstevel@tonic-gate } 1929*0Sstevel@tonic-gate 1930*0Sstevel@tonic-gate static void 1931*0Sstevel@tonic-gate delhosts( 1932*0Sstevel@tonic-gate char *setname, 1933*0Sstevel@tonic-gate int node_c, 1934*0Sstevel@tonic-gate char **node_v, 1935*0Sstevel@tonic-gate int version, /* RPC version of calling routine */ 1936*0Sstevel@tonic-gate md_error_t *ep 1937*0Sstevel@tonic-gate ) 1938*0Sstevel@tonic-gate { 1939*0Sstevel@tonic-gate mddb_userreq_t req; 1940*0Sstevel@tonic-gate md_set_record *sr; 1941*0Sstevel@tonic-gate int i, j; 1942*0Sstevel@tonic-gate md_mnset_record *mnsr; 1943*0Sstevel@tonic-gate md_mnnode_record *nr; 1944*0Sstevel@tonic-gate 1945*0Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL) 1946*0Sstevel@tonic-gate return; 1947*0Sstevel@tonic-gate 1948*0Sstevel@tonic-gate for (i = 0; i < node_c; i++) { 1949*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 1950*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 1951*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 1952*0Sstevel@tonic-gate nr = mnsr->sr_nodechain; 1953*0Sstevel@tonic-gate while (nr) { 1954*0Sstevel@tonic-gate if (strcmp(nr->nr_nodename, node_v[i]) == 0) { 1955*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, 1956*0Sstevel@tonic-gate ESC_SVM_REMOVE, SVM_TAG_HOST, 1957*0Sstevel@tonic-gate sr->sr_setno, nr->nr_nodeid); 1958*0Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req)); 1959*0Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_DELETE, 1960*0Sstevel@tonic-gate nr->nr_selfid); 1961*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, 1962*0Sstevel@tonic-gate &req.ur_mde, NULL) != 0) { 1963*0Sstevel@tonic-gate (void) mdstealerror(ep, 1964*0Sstevel@tonic-gate &req.ur_mde); 1965*0Sstevel@tonic-gate free_sr(sr); 1966*0Sstevel@tonic-gate return; 1967*0Sstevel@tonic-gate } 1968*0Sstevel@tonic-gate mnnr_cache_del(mnsr, nr->nr_selfid); 1969*0Sstevel@tonic-gate break; 1970*0Sstevel@tonic-gate } 1971*0Sstevel@tonic-gate nr = nr->nr_next; 1972*0Sstevel@tonic-gate } 1973*0Sstevel@tonic-gate } else { 1974*0Sstevel@tonic-gate for (j = 0; j < MD_MAXSIDES; j++) { 1975*0Sstevel@tonic-gate if (sr->sr_nodes[j][0] == '\0') 1976*0Sstevel@tonic-gate continue; 1977*0Sstevel@tonic-gate if (strcmp(sr->sr_nodes[j], node_v[i]) != 0) 1978*0Sstevel@tonic-gate continue; 1979*0Sstevel@tonic-gate (void) memset(sr->sr_nodes[j], '\0', 1980*0Sstevel@tonic-gate sizeof (sr->sr_nodes[j])); 1981*0Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, 1982*0Sstevel@tonic-gate SVM_TAG_HOST, sr->sr_setno, j); 1983*0Sstevel@tonic-gate break; 1984*0Sstevel@tonic-gate } 1985*0Sstevel@tonic-gate } 1986*0Sstevel@tonic-gate } 1987*0Sstevel@tonic-gate 1988*0Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req)); 1989*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 1990*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 1991*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 1992*0Sstevel@tonic-gate req.ur_size = sizeof (*mnsr); 1993*0Sstevel@tonic-gate } else { 1994*0Sstevel@tonic-gate req.ur_size = sizeof (*sr); 1995*0Sstevel@tonic-gate } 1996*0Sstevel@tonic-gate req.ur_data = (uintptr_t)sr; 1997*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 1998*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 1999*0Sstevel@tonic-gate free_sr(sr); 2000*0Sstevel@tonic-gate return; 2001*0Sstevel@tonic-gate } 2002*0Sstevel@tonic-gate 2003*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 2004*0Sstevel@tonic-gate free_sr(sr); 2005*0Sstevel@tonic-gate } 2006*0Sstevel@tonic-gate 2007*0Sstevel@tonic-gate /* 2008*0Sstevel@tonic-gate * delete 1 or more a hosts from a set. 2009*0Sstevel@tonic-gate */ 2010*0Sstevel@tonic-gate bool_t 2011*0Sstevel@tonic-gate mdrpc_delhosts_common( 2012*0Sstevel@tonic-gate mdrpc_host_args *args, 2013*0Sstevel@tonic-gate mdrpc_generic_res *res, 2014*0Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */ 2015*0Sstevel@tonic-gate int version /* RPC version */ 2016*0Sstevel@tonic-gate ) 2017*0Sstevel@tonic-gate { 2018*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2019*0Sstevel@tonic-gate int err; 2020*0Sstevel@tonic-gate int op_mode = W_OK; 2021*0Sstevel@tonic-gate 2022*0Sstevel@tonic-gate /* setup, check permissions */ 2023*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2024*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2025*0Sstevel@tonic-gate return (FALSE); 2026*0Sstevel@tonic-gate else if (err != 0) 2027*0Sstevel@tonic-gate return (TRUE); 2028*0Sstevel@tonic-gate 2029*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 2030*0Sstevel@tonic-gate return (TRUE); 2031*0Sstevel@tonic-gate 2032*0Sstevel@tonic-gate /* doit */ 2033*0Sstevel@tonic-gate delhosts(args->sp->setname, args->hosts.hosts_len, 2034*0Sstevel@tonic-gate args->hosts.hosts_val, version, ep); 2035*0Sstevel@tonic-gate 2036*0Sstevel@tonic-gate err = svc_fini(ep); 2037*0Sstevel@tonic-gate 2038*0Sstevel@tonic-gate return (TRUE); 2039*0Sstevel@tonic-gate } 2040*0Sstevel@tonic-gate 2041*0Sstevel@tonic-gate bool_t 2042*0Sstevel@tonic-gate mdrpc_delhosts_1_svc( 2043*0Sstevel@tonic-gate mdrpc_host_args *args, 2044*0Sstevel@tonic-gate mdrpc_generic_res *res, 2045*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2046*0Sstevel@tonic-gate ) 2047*0Sstevel@tonic-gate { 2048*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */ 2049*0Sstevel@tonic-gate return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION)); 2050*0Sstevel@tonic-gate } 2051*0Sstevel@tonic-gate 2052*0Sstevel@tonic-gate bool_t 2053*0Sstevel@tonic-gate mdrpc_delhosts_2_svc( 2054*0Sstevel@tonic-gate mdrpc_host_2_args *args, 2055*0Sstevel@tonic-gate mdrpc_generic_res *res, 2056*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2057*0Sstevel@tonic-gate ) 2058*0Sstevel@tonic-gate { 2059*0Sstevel@tonic-gate switch (args->rev) { 2060*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2061*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 2062*0Sstevel@tonic-gate return (mdrpc_delhosts_common( 2063*0Sstevel@tonic-gate &args->mdrpc_host_2_args_u.rev1, res, 2064*0Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID)); 2065*0Sstevel@tonic-gate default: 2066*0Sstevel@tonic-gate return (FALSE); 2067*0Sstevel@tonic-gate } 2068*0Sstevel@tonic-gate } 2069*0Sstevel@tonic-gate 2070*0Sstevel@tonic-gate /* 2071*0Sstevel@tonic-gate * delete a set. 2072*0Sstevel@tonic-gate */ 2073*0Sstevel@tonic-gate bool_t 2074*0Sstevel@tonic-gate mdrpc_delset_common( 2075*0Sstevel@tonic-gate mdrpc_sp_args *args, 2076*0Sstevel@tonic-gate mdrpc_generic_res *res, 2077*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2078*0Sstevel@tonic-gate ) 2079*0Sstevel@tonic-gate { 2080*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2081*0Sstevel@tonic-gate int err; 2082*0Sstevel@tonic-gate int op_mode = W_OK; 2083*0Sstevel@tonic-gate 2084*0Sstevel@tonic-gate /* setup, check permissions */ 2085*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2086*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2087*0Sstevel@tonic-gate return (FALSE); 2088*0Sstevel@tonic-gate else if (err != 0) 2089*0Sstevel@tonic-gate return (TRUE); 2090*0Sstevel@tonic-gate 2091*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 2092*0Sstevel@tonic-gate return (TRUE); 2093*0Sstevel@tonic-gate 2094*0Sstevel@tonic-gate /* doit */ 2095*0Sstevel@tonic-gate s_delset(args->sp->setname, ep); 2096*0Sstevel@tonic-gate 2097*0Sstevel@tonic-gate err = svc_fini(ep); 2098*0Sstevel@tonic-gate 2099*0Sstevel@tonic-gate return (TRUE); 2100*0Sstevel@tonic-gate } 2101*0Sstevel@tonic-gate 2102*0Sstevel@tonic-gate bool_t 2103*0Sstevel@tonic-gate mdrpc_delset_1_svc( 2104*0Sstevel@tonic-gate mdrpc_sp_args *args, 2105*0Sstevel@tonic-gate mdrpc_generic_res *res, 2106*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2107*0Sstevel@tonic-gate ) 2108*0Sstevel@tonic-gate { 2109*0Sstevel@tonic-gate return (mdrpc_delset_common(args, res, rqstp)); 2110*0Sstevel@tonic-gate } 2111*0Sstevel@tonic-gate 2112*0Sstevel@tonic-gate bool_t 2113*0Sstevel@tonic-gate mdrpc_delset_2_svc( 2114*0Sstevel@tonic-gate mdrpc_sp_2_args *args, 2115*0Sstevel@tonic-gate mdrpc_generic_res *res, 2116*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2117*0Sstevel@tonic-gate ) 2118*0Sstevel@tonic-gate { 2119*0Sstevel@tonic-gate switch (args->rev) { 2120*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2121*0Sstevel@tonic-gate return (mdrpc_delset_common( 2122*0Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 2123*0Sstevel@tonic-gate default: 2124*0Sstevel@tonic-gate return (FALSE); 2125*0Sstevel@tonic-gate } 2126*0Sstevel@tonic-gate } 2127*0Sstevel@tonic-gate 2128*0Sstevel@tonic-gate /* 2129*0Sstevel@tonic-gate * return device info 2130*0Sstevel@tonic-gate */ 2131*0Sstevel@tonic-gate static void 2132*0Sstevel@tonic-gate devinfo( 2133*0Sstevel@tonic-gate mdsetname_t *sp, 2134*0Sstevel@tonic-gate mddrivename_t *dp, 2135*0Sstevel@tonic-gate mdrpc_devinfo_2_res *res, 2136*0Sstevel@tonic-gate md_error_t *ep 2137*0Sstevel@tonic-gate ) 2138*0Sstevel@tonic-gate { 2139*0Sstevel@tonic-gate mdname_t *np, *real_np; 2140*0Sstevel@tonic-gate 2141*0Sstevel@tonic-gate if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL) 2142*0Sstevel@tonic-gate return; 2143*0Sstevel@tonic-gate 2144*0Sstevel@tonic-gate if ((real_np = metaname(&sp, np->bname, ep)) == NULL) 2145*0Sstevel@tonic-gate return; 2146*0Sstevel@tonic-gate 2147*0Sstevel@tonic-gate res->dev = real_np->dev; 2148*0Sstevel@tonic-gate (void) getdevstamp(dp, (long *)&res->vtime, ep); 2149*0Sstevel@tonic-gate res->enc_devid = meta_get_devid(np->rname); 2150*0Sstevel@tonic-gate } 2151*0Sstevel@tonic-gate 2152*0Sstevel@tonic-gate bool_t 2153*0Sstevel@tonic-gate mdrpc_devinfo_common( 2154*0Sstevel@tonic-gate mdrpc_devinfo_2_args_r1 *args, 2155*0Sstevel@tonic-gate mdrpc_devinfo_2_res *res, 2156*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2157*0Sstevel@tonic-gate ) 2158*0Sstevel@tonic-gate { 2159*0Sstevel@tonic-gate int slice; 2160*0Sstevel@tonic-gate mdname_t *np; 2161*0Sstevel@tonic-gate mddrivename_t *dnp = args->drivenamep; 2162*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2163*0Sstevel@tonic-gate int err; 2164*0Sstevel@tonic-gate int op_mode = R_OK; 2165*0Sstevel@tonic-gate 2166*0Sstevel@tonic-gate /* setup, check permissions */ 2167*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2168*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2169*0Sstevel@tonic-gate return (FALSE); 2170*0Sstevel@tonic-gate else if (err != 0) 2171*0Sstevel@tonic-gate return (TRUE); 2172*0Sstevel@tonic-gate 2173*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2174*0Sstevel@tonic-gate return (TRUE); 2175*0Sstevel@tonic-gate 2176*0Sstevel@tonic-gate /* 2177*0Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to 2178*0Sstevel@tonic-gate * point to the right place. 2179*0Sstevel@tonic-gate */ 2180*0Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) { 2181*0Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL) 2182*0Sstevel@tonic-gate return (TRUE); 2183*0Sstevel@tonic-gate np->drivenamep = dnp; 2184*0Sstevel@tonic-gate } 2185*0Sstevel@tonic-gate 2186*0Sstevel@tonic-gate /* doit */ 2187*0Sstevel@tonic-gate devinfo(args->sp, dnp, res, ep); 2188*0Sstevel@tonic-gate 2189*0Sstevel@tonic-gate err = svc_fini(ep); 2190*0Sstevel@tonic-gate 2191*0Sstevel@tonic-gate return (TRUE); 2192*0Sstevel@tonic-gate } 2193*0Sstevel@tonic-gate 2194*0Sstevel@tonic-gate /* 2195*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 2196*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 2197*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 2198*0Sstevel@tonic-gate */ 2199*0Sstevel@tonic-gate bool_t 2200*0Sstevel@tonic-gate mdrpc_devinfo_1_svc( 2201*0Sstevel@tonic-gate mdrpc_devinfo_args *args, 2202*0Sstevel@tonic-gate mdrpc_devinfo_res *res, 2203*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2204*0Sstevel@tonic-gate ) 2205*0Sstevel@tonic-gate { 2206*0Sstevel@tonic-gate bool_t retval; 2207*0Sstevel@tonic-gate mdrpc_devinfo_2_args_r1 v2_args; 2208*0Sstevel@tonic-gate mdrpc_devinfo_2_res v2_res; 2209*0Sstevel@tonic-gate 2210*0Sstevel@tonic-gate /* allocate memory */ 2211*0Sstevel@tonic-gate v2_args.drivenamep = Zalloc(sizeof (mddrivename_t)); 2212*0Sstevel@tonic-gate v2_args.drivenamep->parts.parts_val = 2213*0Sstevel@tonic-gate Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len); 2214*0Sstevel@tonic-gate 2215*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 2216*0Sstevel@tonic-gate meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep); 2217*0Sstevel@tonic-gate retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp); 2218*0Sstevel@tonic-gate 2219*0Sstevel@tonic-gate /* 2220*0Sstevel@tonic-gate * Fill in the result appropriately. 2221*0Sstevel@tonic-gate * Since dev_t's for version 2 are 64-bit, 2222*0Sstevel@tonic-gate * we need to convert them to 32-bit for version 1. 2223*0Sstevel@tonic-gate */ 2224*0Sstevel@tonic-gate res->dev = meta_cmpldev(v2_res.dev); 2225*0Sstevel@tonic-gate res->vtime = v2_res.vtime; 2226*0Sstevel@tonic-gate res->status = v2_res.status; 2227*0Sstevel@tonic-gate 2228*0Sstevel@tonic-gate free(v2_args.drivenamep); 2229*0Sstevel@tonic-gate free(v2_args.drivenamep->parts.parts_val); 2230*0Sstevel@tonic-gate 2231*0Sstevel@tonic-gate return (retval); 2232*0Sstevel@tonic-gate } 2233*0Sstevel@tonic-gate 2234*0Sstevel@tonic-gate bool_t 2235*0Sstevel@tonic-gate mdrpc_devinfo_2_svc( 2236*0Sstevel@tonic-gate mdrpc_devinfo_2_args *args, 2237*0Sstevel@tonic-gate mdrpc_devinfo_2_res *res, 2238*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2239*0Sstevel@tonic-gate ) 2240*0Sstevel@tonic-gate { 2241*0Sstevel@tonic-gate switch (args->rev) { 2242*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2243*0Sstevel@tonic-gate return (mdrpc_devinfo_common( 2244*0Sstevel@tonic-gate &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp)); 2245*0Sstevel@tonic-gate default: 2246*0Sstevel@tonic-gate return (FALSE); 2247*0Sstevel@tonic-gate } 2248*0Sstevel@tonic-gate } 2249*0Sstevel@tonic-gate 2250*0Sstevel@tonic-gate /* 2251*0Sstevel@tonic-gate * return device id 2252*0Sstevel@tonic-gate */ 2253*0Sstevel@tonic-gate static void 2254*0Sstevel@tonic-gate mdrpc_get_devid( 2255*0Sstevel@tonic-gate mdsetname_t *sp, 2256*0Sstevel@tonic-gate mddrivename_t *dp, 2257*0Sstevel@tonic-gate mdrpc_devid_res *res, 2258*0Sstevel@tonic-gate md_error_t *ep 2259*0Sstevel@tonic-gate ) 2260*0Sstevel@tonic-gate { 2261*0Sstevel@tonic-gate mdname_t *np; 2262*0Sstevel@tonic-gate 2263*0Sstevel@tonic-gate if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL) 2264*0Sstevel@tonic-gate return; 2265*0Sstevel@tonic-gate 2266*0Sstevel@tonic-gate if (metaname(&sp, np->bname, ep) == NULL) 2267*0Sstevel@tonic-gate return; 2268*0Sstevel@tonic-gate 2269*0Sstevel@tonic-gate res->enc_devid = meta_get_devid(np->rname); 2270*0Sstevel@tonic-gate } 2271*0Sstevel@tonic-gate 2272*0Sstevel@tonic-gate bool_t 2273*0Sstevel@tonic-gate mdrpc_devid_2_svc( 2274*0Sstevel@tonic-gate mdrpc_devid_2_args *args, 2275*0Sstevel@tonic-gate mdrpc_devid_res *res, 2276*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2277*0Sstevel@tonic-gate ) 2278*0Sstevel@tonic-gate { 2279*0Sstevel@tonic-gate int slice; 2280*0Sstevel@tonic-gate mdname_t *np; 2281*0Sstevel@tonic-gate mddrivename_t *dnp; 2282*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2283*0Sstevel@tonic-gate int err; 2284*0Sstevel@tonic-gate int op_mode = R_OK; 2285*0Sstevel@tonic-gate 2286*0Sstevel@tonic-gate switch (args->rev) { 2287*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2288*0Sstevel@tonic-gate dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep; 2289*0Sstevel@tonic-gate break; 2290*0Sstevel@tonic-gate default: 2291*0Sstevel@tonic-gate return (FALSE); 2292*0Sstevel@tonic-gate } 2293*0Sstevel@tonic-gate 2294*0Sstevel@tonic-gate /* setup, check permissions */ 2295*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2296*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2297*0Sstevel@tonic-gate return (FALSE); 2298*0Sstevel@tonic-gate else if (err != 0) 2299*0Sstevel@tonic-gate return (TRUE); 2300*0Sstevel@tonic-gate 2301*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2302*0Sstevel@tonic-gate return (TRUE); 2303*0Sstevel@tonic-gate 2304*0Sstevel@tonic-gate /* 2305*0Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to 2306*0Sstevel@tonic-gate * point to the right place. 2307*0Sstevel@tonic-gate */ 2308*0Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) { 2309*0Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL) 2310*0Sstevel@tonic-gate return (TRUE); 2311*0Sstevel@tonic-gate np->drivenamep = dnp; 2312*0Sstevel@tonic-gate } 2313*0Sstevel@tonic-gate 2314*0Sstevel@tonic-gate /* doit */ 2315*0Sstevel@tonic-gate mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep); 2316*0Sstevel@tonic-gate 2317*0Sstevel@tonic-gate err = svc_fini(ep); 2318*0Sstevel@tonic-gate 2319*0Sstevel@tonic-gate return (TRUE); 2320*0Sstevel@tonic-gate } 2321*0Sstevel@tonic-gate 2322*0Sstevel@tonic-gate /* 2323*0Sstevel@tonic-gate * This routine should not be called for a multi-node diskset. 2324*0Sstevel@tonic-gate * 2325*0Sstevel@tonic-gate * The devid support is disabled for MN diskset so this routine 2326*0Sstevel@tonic-gate * will not be called if the set is MN diskset. The check has 2327*0Sstevel@tonic-gate * been done early in meta_getnextside_devinfo. However this 2328*0Sstevel@tonic-gate * routine will be called when the devid support for MN set is 2329*0Sstevel@tonic-gate * enabled and check is removed. 2330*0Sstevel@tonic-gate */ 2331*0Sstevel@tonic-gate bool_t 2332*0Sstevel@tonic-gate mdrpc_devinfo_by_devid_2_svc( 2333*0Sstevel@tonic-gate mdrpc_devidstr_args *args, 2334*0Sstevel@tonic-gate mdrpc_devinfo_2_res *res, 2335*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2336*0Sstevel@tonic-gate ) 2337*0Sstevel@tonic-gate { 2338*0Sstevel@tonic-gate 2339*0Sstevel@tonic-gate char *devidstr = args->enc_devid; 2340*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2341*0Sstevel@tonic-gate ddi_devid_t devid; 2342*0Sstevel@tonic-gate char *minor_name = NULL; 2343*0Sstevel@tonic-gate int ret = 0; 2344*0Sstevel@tonic-gate int err; 2345*0Sstevel@tonic-gate devid_nmlist_t *disklist = NULL; 2346*0Sstevel@tonic-gate int op_mode = R_OK; 2347*0Sstevel@tonic-gate mdname_t *np; 2348*0Sstevel@tonic-gate mdsetname_t *sp = args->sp; 2349*0Sstevel@tonic-gate 2350*0Sstevel@tonic-gate /* setup, check permissions */ 2351*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2352*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2353*0Sstevel@tonic-gate return (FALSE); 2354*0Sstevel@tonic-gate else if (err != 0) 2355*0Sstevel@tonic-gate return (TRUE); 2356*0Sstevel@tonic-gate 2357*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2358*0Sstevel@tonic-gate return (TRUE); 2359*0Sstevel@tonic-gate 2360*0Sstevel@tonic-gate if (devid_str_decode(devidstr, &devid, &minor_name) != 0) 2361*0Sstevel@tonic-gate return (TRUE); 2362*0Sstevel@tonic-gate 2363*0Sstevel@tonic-gate /* 2364*0Sstevel@tonic-gate * if we do not have a minor name then look for a character device. 2365*0Sstevel@tonic-gate * This is because the caller (checkdrive_onnode) expects a character 2366*0Sstevel@tonic-gate * device to be returned. The other client of this interface is 2367*0Sstevel@tonic-gate * meta_getnextside_devinfo and this supplies a minor name. 2368*0Sstevel@tonic-gate */ 2369*0Sstevel@tonic-gate if (minor_name == NULL) { 2370*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, 2371*0Sstevel@tonic-gate DEVID_MINOR_NAME_ALL_CHR, &disklist); 2372*0Sstevel@tonic-gate } else { 2373*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, minor_name, 2374*0Sstevel@tonic-gate &disklist); 2375*0Sstevel@tonic-gate devid_str_free(minor_name); 2376*0Sstevel@tonic-gate } 2377*0Sstevel@tonic-gate 2378*0Sstevel@tonic-gate devid_free(devid); 2379*0Sstevel@tonic-gate if (ret != 0) { 2380*0Sstevel@tonic-gate res->dev = NODEV64; 2381*0Sstevel@tonic-gate devid_free_nmlist(disklist); 2382*0Sstevel@tonic-gate return (TRUE); 2383*0Sstevel@tonic-gate } 2384*0Sstevel@tonic-gate 2385*0Sstevel@tonic-gate np = metaname(&sp, disklist[0].devname, ep); 2386*0Sstevel@tonic-gate if (np != NULL) { 2387*0Sstevel@tonic-gate mdcinfo_t *cinfo; 2388*0Sstevel@tonic-gate if ((cinfo = metagetcinfo(np, ep)) != NULL) { 2389*0Sstevel@tonic-gate res->drivername = Strdup(cinfo->dname); 2390*0Sstevel@tonic-gate } 2391*0Sstevel@tonic-gate } 2392*0Sstevel@tonic-gate 2393*0Sstevel@tonic-gate res->dev = meta_expldev(disklist[0].dev); 2394*0Sstevel@tonic-gate res->devname = strdup(disklist[0].devname); 2395*0Sstevel@tonic-gate 2396*0Sstevel@tonic-gate devid_free_nmlist(disklist); 2397*0Sstevel@tonic-gate 2398*0Sstevel@tonic-gate err = svc_fini(ep); 2399*0Sstevel@tonic-gate 2400*0Sstevel@tonic-gate return (TRUE); 2401*0Sstevel@tonic-gate } 2402*0Sstevel@tonic-gate 2403*0Sstevel@tonic-gate /* 2404*0Sstevel@tonic-gate * This routine should not be called for a multi-node diskset. 2405*0Sstevel@tonic-gate * 2406*0Sstevel@tonic-gate * The devid support is disabled for MN diskset so this routine 2407*0Sstevel@tonic-gate * will not be called if the set is MN diskset. The check has 2408*0Sstevel@tonic-gate * been done early in meta_getnextside_devinfo. However this 2409*0Sstevel@tonic-gate * routine will be called when the devid support for MN set is 2410*0Sstevel@tonic-gate * enabled and check is removed. 2411*0Sstevel@tonic-gate * 2412*0Sstevel@tonic-gate * This function will return the device info attempting to use 2413*0Sstevel@tonic-gate * both the passed in devid and device name. This is to deal 2414*0Sstevel@tonic-gate * with systems that use multi-path disks but not running mpxio. 2415*0Sstevel@tonic-gate * In this situation meta_deviceid_to_nmlist will return multiple 2416*0Sstevel@tonic-gate * devices. The orig_devname is used to disambiguate. 2417*0Sstevel@tonic-gate * 2418*0Sstevel@tonic-gate */ 2419*0Sstevel@tonic-gate bool_t 2420*0Sstevel@tonic-gate mdrpc_devinfo_by_devid_name_2_svc( 2421*0Sstevel@tonic-gate mdrpc_devid_name_2_args *args, 2422*0Sstevel@tonic-gate mdrpc_devinfo_2_res *res, 2423*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2424*0Sstevel@tonic-gate ) 2425*0Sstevel@tonic-gate { 2426*0Sstevel@tonic-gate 2427*0Sstevel@tonic-gate char *devidstr; 2428*0Sstevel@tonic-gate char *orig_devname; 2429*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2430*0Sstevel@tonic-gate ddi_devid_t devid; 2431*0Sstevel@tonic-gate char *minor_name = NULL; 2432*0Sstevel@tonic-gate int ret = 0; 2433*0Sstevel@tonic-gate int err; 2434*0Sstevel@tonic-gate int i; 2435*0Sstevel@tonic-gate devid_nmlist_t *disklist = NULL; 2436*0Sstevel@tonic-gate int op_mode = R_OK; 2437*0Sstevel@tonic-gate mdname_t *np; 2438*0Sstevel@tonic-gate mdsetname_t *sp; 2439*0Sstevel@tonic-gate 2440*0Sstevel@tonic-gate switch (args->rev) { 2441*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2442*0Sstevel@tonic-gate sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp; 2443*0Sstevel@tonic-gate devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid; 2444*0Sstevel@tonic-gate orig_devname = 2445*0Sstevel@tonic-gate (&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname; 2446*0Sstevel@tonic-gate break; 2447*0Sstevel@tonic-gate default: 2448*0Sstevel@tonic-gate return (FALSE); 2449*0Sstevel@tonic-gate } 2450*0Sstevel@tonic-gate 2451*0Sstevel@tonic-gate /* setup, check permissions */ 2452*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2453*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2454*0Sstevel@tonic-gate return (FALSE); 2455*0Sstevel@tonic-gate else if (err != 0) 2456*0Sstevel@tonic-gate return (TRUE); 2457*0Sstevel@tonic-gate 2458*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2459*0Sstevel@tonic-gate return (TRUE); 2460*0Sstevel@tonic-gate 2461*0Sstevel@tonic-gate if (devid_str_decode(devidstr, &devid, &minor_name) != 0) 2462*0Sstevel@tonic-gate return (TRUE); 2463*0Sstevel@tonic-gate 2464*0Sstevel@tonic-gate /* 2465*0Sstevel@tonic-gate * if we do not have a minor name then look for a character device. 2466*0Sstevel@tonic-gate * This is because the caller (checkdrive_onnode) expects a character 2467*0Sstevel@tonic-gate * device to be returned. The other client of this interface is 2468*0Sstevel@tonic-gate * meta_getnextside_devinfo and this supplies a minor name. 2469*0Sstevel@tonic-gate */ 2470*0Sstevel@tonic-gate if (minor_name == NULL) { 2471*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, 2472*0Sstevel@tonic-gate DEVID_MINOR_NAME_ALL_CHR, &disklist); 2473*0Sstevel@tonic-gate } else { 2474*0Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, minor_name, 2475*0Sstevel@tonic-gate &disklist); 2476*0Sstevel@tonic-gate devid_str_free(minor_name); 2477*0Sstevel@tonic-gate } 2478*0Sstevel@tonic-gate 2479*0Sstevel@tonic-gate devid_free(devid); 2480*0Sstevel@tonic-gate if (ret != 0) { 2481*0Sstevel@tonic-gate res->dev = NODEV64; 2482*0Sstevel@tonic-gate devid_free_nmlist(disklist); 2483*0Sstevel@tonic-gate return (TRUE); 2484*0Sstevel@tonic-gate } 2485*0Sstevel@tonic-gate 2486*0Sstevel@tonic-gate /* attempt to match to the device name on the originating node */ 2487*0Sstevel@tonic-gate for (i = 0; disklist[i].dev != NODEV; i++) { 2488*0Sstevel@tonic-gate if (strncmp(orig_devname, disklist[i].devname, 2489*0Sstevel@tonic-gate strlen(disklist[i].devname)) == 0) 2490*0Sstevel@tonic-gate break; 2491*0Sstevel@tonic-gate } 2492*0Sstevel@tonic-gate 2493*0Sstevel@tonic-gate /* if it's not found then use the first disk in the list */ 2494*0Sstevel@tonic-gate if (disklist[i].dev == NODEV) 2495*0Sstevel@tonic-gate i = 0; 2496*0Sstevel@tonic-gate 2497*0Sstevel@tonic-gate np = metaname(&sp, disklist[i].devname, ep); 2498*0Sstevel@tonic-gate if (np != NULL) { 2499*0Sstevel@tonic-gate mdcinfo_t *cinfo; 2500*0Sstevel@tonic-gate if ((cinfo = metagetcinfo(np, ep)) != NULL) { 2501*0Sstevel@tonic-gate res->drivername = Strdup(cinfo->dname); 2502*0Sstevel@tonic-gate } 2503*0Sstevel@tonic-gate } 2504*0Sstevel@tonic-gate 2505*0Sstevel@tonic-gate res->dev = meta_expldev(disklist[i].dev); 2506*0Sstevel@tonic-gate res->devname = strdup(disklist[i].devname); 2507*0Sstevel@tonic-gate 2508*0Sstevel@tonic-gate devid_free_nmlist(disklist); 2509*0Sstevel@tonic-gate 2510*0Sstevel@tonic-gate err = svc_fini(ep); 2511*0Sstevel@tonic-gate 2512*0Sstevel@tonic-gate return (TRUE); 2513*0Sstevel@tonic-gate } 2514*0Sstevel@tonic-gate 2515*0Sstevel@tonic-gate static void 2516*0Sstevel@tonic-gate drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep) 2517*0Sstevel@tonic-gate { 2518*0Sstevel@tonic-gate if (meta_check_drivemounted(sp, dnp, ep)) 2519*0Sstevel@tonic-gate return; 2520*0Sstevel@tonic-gate 2521*0Sstevel@tonic-gate if (meta_check_driveswapped(sp, dnp, ep)) 2522*0Sstevel@tonic-gate return; 2523*0Sstevel@tonic-gate 2524*0Sstevel@tonic-gate if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp, 2525*0Sstevel@tonic-gate TRUE, ep)) 2526*0Sstevel@tonic-gate return; 2527*0Sstevel@tonic-gate 2528*0Sstevel@tonic-gate (void) meta_check_driveinset(sp, dnp, ep); 2529*0Sstevel@tonic-gate } 2530*0Sstevel@tonic-gate 2531*0Sstevel@tonic-gate /* 2532*0Sstevel@tonic-gate * determine if a device is in use. 2533*0Sstevel@tonic-gate */ 2534*0Sstevel@tonic-gate bool_t 2535*0Sstevel@tonic-gate mdrpc_drvused_common( 2536*0Sstevel@tonic-gate mdrpc_drvused_2_args_r1 *args, 2537*0Sstevel@tonic-gate mdrpc_generic_res *res, 2538*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2539*0Sstevel@tonic-gate ) 2540*0Sstevel@tonic-gate { 2541*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2542*0Sstevel@tonic-gate int slice; 2543*0Sstevel@tonic-gate mdname_t *np; 2544*0Sstevel@tonic-gate mddrivename_t *dnp = args->drivenamep; 2545*0Sstevel@tonic-gate int err; 2546*0Sstevel@tonic-gate int op_mode = R_OK; 2547*0Sstevel@tonic-gate 2548*0Sstevel@tonic-gate /* setup, check permissions */ 2549*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2550*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2551*0Sstevel@tonic-gate return (FALSE); 2552*0Sstevel@tonic-gate else if (err != 0) 2553*0Sstevel@tonic-gate return (TRUE); 2554*0Sstevel@tonic-gate 2555*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2556*0Sstevel@tonic-gate return (TRUE); 2557*0Sstevel@tonic-gate 2558*0Sstevel@tonic-gate if (dnp == NULL) { 2559*0Sstevel@tonic-gate /* no drive pointer specified */ 2560*0Sstevel@tonic-gate return (TRUE); 2561*0Sstevel@tonic-gate } 2562*0Sstevel@tonic-gate /* 2563*0Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to 2564*0Sstevel@tonic-gate * point to the right place. 2565*0Sstevel@tonic-gate */ 2566*0Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) { 2567*0Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL) 2568*0Sstevel@tonic-gate return (TRUE); 2569*0Sstevel@tonic-gate np->drivenamep = dnp; 2570*0Sstevel@tonic-gate } 2571*0Sstevel@tonic-gate 2572*0Sstevel@tonic-gate /* doit */ 2573*0Sstevel@tonic-gate drvused(args->sp, dnp, ep); 2574*0Sstevel@tonic-gate 2575*0Sstevel@tonic-gate err = svc_fini(ep); 2576*0Sstevel@tonic-gate 2577*0Sstevel@tonic-gate return (TRUE); 2578*0Sstevel@tonic-gate } 2579*0Sstevel@tonic-gate 2580*0Sstevel@tonic-gate /* 2581*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 2582*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 2583*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 2584*0Sstevel@tonic-gate */ 2585*0Sstevel@tonic-gate bool_t 2586*0Sstevel@tonic-gate mdrpc_drvused_1_svc( 2587*0Sstevel@tonic-gate mdrpc_drvused_args *args, 2588*0Sstevel@tonic-gate mdrpc_generic_res *res, 2589*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2590*0Sstevel@tonic-gate ) 2591*0Sstevel@tonic-gate { 2592*0Sstevel@tonic-gate bool_t retval; 2593*0Sstevel@tonic-gate mdrpc_drvused_2_args_r1 v2_args; 2594*0Sstevel@tonic-gate 2595*0Sstevel@tonic-gate /* allocate memory */ 2596*0Sstevel@tonic-gate v2_args.drivenamep = Zalloc(sizeof (mddrivename_t)); 2597*0Sstevel@tonic-gate v2_args.drivenamep->parts.parts_val = 2598*0Sstevel@tonic-gate Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len); 2599*0Sstevel@tonic-gate 2600*0Sstevel@tonic-gate /* build args */ 2601*0Sstevel@tonic-gate v2_args.sp = args->sp; 2602*0Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk; 2603*0Sstevel@tonic-gate 2604*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 2605*0Sstevel@tonic-gate meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep); 2606*0Sstevel@tonic-gate retval = mdrpc_drvused_common(&v2_args, res, rqstp); 2607*0Sstevel@tonic-gate 2608*0Sstevel@tonic-gate free(v2_args.drivenamep); 2609*0Sstevel@tonic-gate free(v2_args.drivenamep->parts.parts_val); 2610*0Sstevel@tonic-gate 2611*0Sstevel@tonic-gate return (retval); 2612*0Sstevel@tonic-gate } 2613*0Sstevel@tonic-gate 2614*0Sstevel@tonic-gate bool_t 2615*0Sstevel@tonic-gate mdrpc_drvused_2_svc( 2616*0Sstevel@tonic-gate mdrpc_drvused_2_args *args, 2617*0Sstevel@tonic-gate mdrpc_generic_res *res, 2618*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2619*0Sstevel@tonic-gate ) 2620*0Sstevel@tonic-gate { 2621*0Sstevel@tonic-gate switch (args->rev) { 2622*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2623*0Sstevel@tonic-gate return (mdrpc_drvused_common( 2624*0Sstevel@tonic-gate &args->mdrpc_drvused_2_args_u.rev1, res, rqstp)); 2625*0Sstevel@tonic-gate default: 2626*0Sstevel@tonic-gate return (FALSE); 2627*0Sstevel@tonic-gate } 2628*0Sstevel@tonic-gate } 2629*0Sstevel@tonic-gate 2630*0Sstevel@tonic-gate /* 2631*0Sstevel@tonic-gate * return a set records selected by name or number. 2632*0Sstevel@tonic-gate */ 2633*0Sstevel@tonic-gate bool_t 2634*0Sstevel@tonic-gate mdrpc_getset_common( 2635*0Sstevel@tonic-gate mdrpc_getset_args *args, 2636*0Sstevel@tonic-gate mdrpc_getset_res *res, 2637*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2638*0Sstevel@tonic-gate ) 2639*0Sstevel@tonic-gate { 2640*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2641*0Sstevel@tonic-gate int err; 2642*0Sstevel@tonic-gate int op_mode = R_OK; 2643*0Sstevel@tonic-gate 2644*0Sstevel@tonic-gate /* setup, check permissions */ 2645*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2646*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2647*0Sstevel@tonic-gate return (FALSE); 2648*0Sstevel@tonic-gate else if (err != 0) 2649*0Sstevel@tonic-gate return (TRUE); 2650*0Sstevel@tonic-gate 2651*0Sstevel@tonic-gate /* Don't have a setno, so we don't check the lock */ 2652*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2653*0Sstevel@tonic-gate return (TRUE); 2654*0Sstevel@tonic-gate 2655*0Sstevel@tonic-gate /* doit */ 2656*0Sstevel@tonic-gate if (args->setname && *args->setname) 2657*0Sstevel@tonic-gate res->sr = setdup(getsetbyname(args->setname, ep)); 2658*0Sstevel@tonic-gate else if (args->setno > 0) 2659*0Sstevel@tonic-gate res->sr = setdup(getsetbynum(args->setno, ep)); 2660*0Sstevel@tonic-gate else 2661*0Sstevel@tonic-gate res->sr = NULL; 2662*0Sstevel@tonic-gate 2663*0Sstevel@tonic-gate err = svc_fini(ep); 2664*0Sstevel@tonic-gate 2665*0Sstevel@tonic-gate return (TRUE); 2666*0Sstevel@tonic-gate } 2667*0Sstevel@tonic-gate 2668*0Sstevel@tonic-gate bool_t 2669*0Sstevel@tonic-gate mdrpc_getset_1_svc( 2670*0Sstevel@tonic-gate mdrpc_getset_args *args, 2671*0Sstevel@tonic-gate mdrpc_getset_res *res, 2672*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2673*0Sstevel@tonic-gate ) 2674*0Sstevel@tonic-gate { 2675*0Sstevel@tonic-gate return (mdrpc_getset_common(args, res, rqstp)); 2676*0Sstevel@tonic-gate } 2677*0Sstevel@tonic-gate 2678*0Sstevel@tonic-gate bool_t 2679*0Sstevel@tonic-gate mdrpc_getset_2_svc( 2680*0Sstevel@tonic-gate mdrpc_getset_2_args *args, 2681*0Sstevel@tonic-gate mdrpc_getset_res *res, 2682*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2683*0Sstevel@tonic-gate ) 2684*0Sstevel@tonic-gate { 2685*0Sstevel@tonic-gate switch (args->rev) { 2686*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2687*0Sstevel@tonic-gate return (mdrpc_getset_common( 2688*0Sstevel@tonic-gate &args->mdrpc_getset_2_args_u.rev1, res, rqstp)); 2689*0Sstevel@tonic-gate default: 2690*0Sstevel@tonic-gate return (FALSE); 2691*0Sstevel@tonic-gate } 2692*0Sstevel@tonic-gate } 2693*0Sstevel@tonic-gate 2694*0Sstevel@tonic-gate /* 2695*0Sstevel@tonic-gate * return a MN set record selected by name or number. 2696*0Sstevel@tonic-gate */ 2697*0Sstevel@tonic-gate bool_t 2698*0Sstevel@tonic-gate mdrpc_mngetset_common( 2699*0Sstevel@tonic-gate mdrpc_getset_args *args, 2700*0Sstevel@tonic-gate mdrpc_mngetset_res *res, 2701*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2702*0Sstevel@tonic-gate ) 2703*0Sstevel@tonic-gate { 2704*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2705*0Sstevel@tonic-gate int err; 2706*0Sstevel@tonic-gate int op_mode = R_OK; 2707*0Sstevel@tonic-gate md_set_record *sr = NULL; 2708*0Sstevel@tonic-gate md_mnset_record *mnsr = NULL; 2709*0Sstevel@tonic-gate 2710*0Sstevel@tonic-gate /* setup, check permissions */ 2711*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2712*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2713*0Sstevel@tonic-gate return (FALSE); 2714*0Sstevel@tonic-gate else if (err != 0) 2715*0Sstevel@tonic-gate return (TRUE); 2716*0Sstevel@tonic-gate 2717*0Sstevel@tonic-gate /* Don't have a setno, so we don't check the lock */ 2718*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 2719*0Sstevel@tonic-gate return (TRUE); 2720*0Sstevel@tonic-gate 2721*0Sstevel@tonic-gate /* doit */ 2722*0Sstevel@tonic-gate res->mnsr = NULL; 2723*0Sstevel@tonic-gate if (args->setname && *args->setname) 2724*0Sstevel@tonic-gate sr = getsetbyname(args->setname, ep); 2725*0Sstevel@tonic-gate else if (args->setno > 0) 2726*0Sstevel@tonic-gate sr = getsetbynum(args->setno, ep); 2727*0Sstevel@tonic-gate 2728*0Sstevel@tonic-gate if ((sr) && (MD_MNSET_REC(sr))) { 2729*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 2730*0Sstevel@tonic-gate res->mnsr = mnsetdup(mnsr); 2731*0Sstevel@tonic-gate } 2732*0Sstevel@tonic-gate 2733*0Sstevel@tonic-gate err = svc_fini(ep); 2734*0Sstevel@tonic-gate 2735*0Sstevel@tonic-gate return (TRUE); 2736*0Sstevel@tonic-gate } 2737*0Sstevel@tonic-gate 2738*0Sstevel@tonic-gate bool_t 2739*0Sstevel@tonic-gate mdrpc_mngetset_2_svc( 2740*0Sstevel@tonic-gate mdrpc_getset_2_args *args, 2741*0Sstevel@tonic-gate mdrpc_mngetset_res *res, 2742*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2743*0Sstevel@tonic-gate ) 2744*0Sstevel@tonic-gate { 2745*0Sstevel@tonic-gate switch (args->rev) { 2746*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2747*0Sstevel@tonic-gate return (mdrpc_mngetset_common( 2748*0Sstevel@tonic-gate &args->mdrpc_getset_2_args_u.rev1, res, rqstp)); 2749*0Sstevel@tonic-gate default: 2750*0Sstevel@tonic-gate return (FALSE); 2751*0Sstevel@tonic-gate } 2752*0Sstevel@tonic-gate } 2753*0Sstevel@tonic-gate 2754*0Sstevel@tonic-gate static void 2755*0Sstevel@tonic-gate upd_setmaster( 2756*0Sstevel@tonic-gate mdsetname_t *sp, 2757*0Sstevel@tonic-gate md_node_nm_t master_nodenm, 2758*0Sstevel@tonic-gate int master_nodeid, 2759*0Sstevel@tonic-gate md_error_t *ep 2760*0Sstevel@tonic-gate ) 2761*0Sstevel@tonic-gate { 2762*0Sstevel@tonic-gate mdsetname_t *local_sp; 2763*0Sstevel@tonic-gate md_set_record *sr; 2764*0Sstevel@tonic-gate md_mnset_record *mnsr; 2765*0Sstevel@tonic-gate mddb_setmaster_config_t sm; 2766*0Sstevel@tonic-gate 2767*0Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL) 2768*0Sstevel@tonic-gate return; 2769*0Sstevel@tonic-gate 2770*0Sstevel@tonic-gate metaflushsetname(local_sp); 2771*0Sstevel@tonic-gate 2772*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 2773*0Sstevel@tonic-gate return; 2774*0Sstevel@tonic-gate 2775*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) { 2776*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 2777*0Sstevel@tonic-gate strlcpy(mnsr->sr_master_nodenm, master_nodenm, 2778*0Sstevel@tonic-gate MD_MAX_NODENAME); 2779*0Sstevel@tonic-gate mnsr->sr_master_nodeid = master_nodeid; 2780*0Sstevel@tonic-gate if (master_nodeid != 0) { 2781*0Sstevel@tonic-gate (void) memset(&sm, 0, sizeof (sm)); 2782*0Sstevel@tonic-gate sm.c_setno = sp->setno; 2783*0Sstevel@tonic-gate /* Use magic to help protect ioctl against attack. */ 2784*0Sstevel@tonic-gate sm.c_magic = MDDB_SETMASTER_MAGIC; 2785*0Sstevel@tonic-gate if (strcmp(master_nodenm, mynode()) == 0) { 2786*0Sstevel@tonic-gate sm.c_current_host_master = 1; 2787*0Sstevel@tonic-gate } else { 2788*0Sstevel@tonic-gate sm.c_current_host_master = 0; 2789*0Sstevel@tonic-gate } 2790*0Sstevel@tonic-gate (void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL); 2791*0Sstevel@tonic-gate mdclrerror(&sm.c_mde); 2792*0Sstevel@tonic-gate } 2793*0Sstevel@tonic-gate } 2794*0Sstevel@tonic-gate 2795*0Sstevel@tonic-gate out: 2796*0Sstevel@tonic-gate commitset(sr, FALSE, ep); 2797*0Sstevel@tonic-gate free_sr(sr); 2798*0Sstevel@tonic-gate } 2799*0Sstevel@tonic-gate 2800*0Sstevel@tonic-gate /* 2801*0Sstevel@tonic-gate * set the master and nodeid in node record 2802*0Sstevel@tonic-gate */ 2803*0Sstevel@tonic-gate bool_t 2804*0Sstevel@tonic-gate mdrpc_mnsetmaster_common( 2805*0Sstevel@tonic-gate mdrpc_mnsetmaster_args *args, 2806*0Sstevel@tonic-gate mdrpc_generic_res *res, 2807*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2808*0Sstevel@tonic-gate ) 2809*0Sstevel@tonic-gate { 2810*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2811*0Sstevel@tonic-gate int err; 2812*0Sstevel@tonic-gate int op_mode = W_OK; 2813*0Sstevel@tonic-gate 2814*0Sstevel@tonic-gate /* setup, check permissions */ 2815*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2816*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2817*0Sstevel@tonic-gate return (FALSE); 2818*0Sstevel@tonic-gate else if (err != 0) 2819*0Sstevel@tonic-gate return (TRUE); 2820*0Sstevel@tonic-gate 2821*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 2822*0Sstevel@tonic-gate return (TRUE); 2823*0Sstevel@tonic-gate 2824*0Sstevel@tonic-gate /* doit */ 2825*0Sstevel@tonic-gate upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep); 2826*0Sstevel@tonic-gate 2827*0Sstevel@tonic-gate err = svc_fini(ep); 2828*0Sstevel@tonic-gate 2829*0Sstevel@tonic-gate return (TRUE); 2830*0Sstevel@tonic-gate } 2831*0Sstevel@tonic-gate 2832*0Sstevel@tonic-gate bool_t 2833*0Sstevel@tonic-gate mdrpc_mnsetmaster_2_svc( 2834*0Sstevel@tonic-gate mdrpc_mnsetmaster_2_args *args, 2835*0Sstevel@tonic-gate mdrpc_generic_res *res, 2836*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2837*0Sstevel@tonic-gate ) 2838*0Sstevel@tonic-gate { 2839*0Sstevel@tonic-gate switch (args->rev) { 2840*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 2841*0Sstevel@tonic-gate return (mdrpc_mnsetmaster_common( 2842*0Sstevel@tonic-gate &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp)); 2843*0Sstevel@tonic-gate default: 2844*0Sstevel@tonic-gate return (FALSE); 2845*0Sstevel@tonic-gate } 2846*0Sstevel@tonic-gate } 2847*0Sstevel@tonic-gate 2848*0Sstevel@tonic-gate /* 2849*0Sstevel@tonic-gate * Join this node to the diskset. 2850*0Sstevel@tonic-gate * Pass stale_flag information to snarf_set so that snarf code 2851*0Sstevel@tonic-gate * can choose a STALE or non-STALE state when starting the set. 2852*0Sstevel@tonic-gate * If master is STALE, any joining node will join a stale set regardless 2853*0Sstevel@tonic-gate * of the number of accessible mddbs. Also, if master is at 50% 2854*0Sstevel@tonic-gate * accessible replicas and is in the TOOFEW state, don't mark newly 2855*0Sstevel@tonic-gate * joining node as STALE; mark it TOOFEW instead. 2856*0Sstevel@tonic-gate */ 2857*0Sstevel@tonic-gate static void 2858*0Sstevel@tonic-gate joinset( 2859*0Sstevel@tonic-gate mdsetname_t *sp, 2860*0Sstevel@tonic-gate int flags, 2861*0Sstevel@tonic-gate md_error_t *ep 2862*0Sstevel@tonic-gate ) 2863*0Sstevel@tonic-gate { 2864*0Sstevel@tonic-gate mdsetname_t *local_sp; 2865*0Sstevel@tonic-gate md_drive_desc *mydd; 2866*0Sstevel@tonic-gate bool_t stale_bool; 2867*0Sstevel@tonic-gate mddb_block_parm_t mbp; 2868*0Sstevel@tonic-gate md_error_t xep = mdnullerror; 2869*0Sstevel@tonic-gate 2870*0Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL) 2871*0Sstevel@tonic-gate return; 2872*0Sstevel@tonic-gate 2873*0Sstevel@tonic-gate /* 2874*0Sstevel@tonic-gate * Start mddoors daemon here. 2875*0Sstevel@tonic-gate * mddoors itself takes care there will be 2876*0Sstevel@tonic-gate * only one instance running, so starting it twice won't hurt 2877*0Sstevel@tonic-gate */ 2878*0Sstevel@tonic-gate pclose(popen(MDDOORS, "w")); 2879*0Sstevel@tonic-gate 2880*0Sstevel@tonic-gate /* 2881*0Sstevel@tonic-gate * Get latest copy of data. If a drive was just added causing 2882*0Sstevel@tonic-gate * nodes to get joined - this drive won't be in the local 2883*0Sstevel@tonic-gate * name caches drive list yet. 2884*0Sstevel@tonic-gate */ 2885*0Sstevel@tonic-gate metaflushsetname(local_sp); 2886*0Sstevel@tonic-gate 2887*0Sstevel@tonic-gate mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep); 2888*0Sstevel@tonic-gate if (mydd) { 2889*0Sstevel@tonic-gate /* Causes mddbs to be loaded in kernel */ 2890*0Sstevel@tonic-gate if (setup_db_bydd(local_sp, mydd, 0, ep) == -1) { 2891*0Sstevel@tonic-gate /* If ep isn't set for some reason, set it */ 2892*0Sstevel@tonic-gate if (! mdisok(ep)) { 2893*0Sstevel@tonic-gate (void) mdmddberror(ep, MDE_DB_NOTNOW, NODEV64, 2894*0Sstevel@tonic-gate sp->setno, 0, NULL); 2895*0Sstevel@tonic-gate } 2896*0Sstevel@tonic-gate return; 2897*0Sstevel@tonic-gate } 2898*0Sstevel@tonic-gate 2899*0Sstevel@tonic-gate if (flags & MNSET_IS_STALE) 2900*0Sstevel@tonic-gate stale_bool = TRUE; 2901*0Sstevel@tonic-gate else 2902*0Sstevel@tonic-gate stale_bool = FALSE; 2903*0Sstevel@tonic-gate 2904*0Sstevel@tonic-gate /* 2905*0Sstevel@tonic-gate * Snarf the set. No failure has occurred if STALE or 2906*0Sstevel@tonic-gate * ACCOK error was set. Otherwise, fail the call setting 2907*0Sstevel@tonic-gate * a generic error if no error was already set. 2908*0Sstevel@tonic-gate * 2909*0Sstevel@tonic-gate * STALE means that set has < 50% mddbs. 2910*0Sstevel@tonic-gate * ACCOK means that the mediator provided an extra vote. 2911*0Sstevel@tonic-gate */ 2912*0Sstevel@tonic-gate if (snarf_set(local_sp, stale_bool, ep) != 0) { 2913*0Sstevel@tonic-gate if (!(mdismddberror(ep, MDE_DB_STALE)) && 2914*0Sstevel@tonic-gate !(mdismddberror(ep, MDE_DB_ACCOK))) { 2915*0Sstevel@tonic-gate return; 2916*0Sstevel@tonic-gate } else if (mdisok(ep)) { 2917*0Sstevel@tonic-gate /* If snarf failed, but no error set - set it */ 2918*0Sstevel@tonic-gate (void) mdmddberror(ep, MDE_DB_NOTNOW, NODEV64, 2919*0Sstevel@tonic-gate sp->setno, 0, NULL); 2920*0Sstevel@tonic-gate return; 2921*0Sstevel@tonic-gate } 2922*0Sstevel@tonic-gate } 2923*0Sstevel@tonic-gate 2924*0Sstevel@tonic-gate /* 2925*0Sstevel@tonic-gate * If node is joining during reconfig cycle, then 2926*0Sstevel@tonic-gate * set mddb_parse to be in blocked state so that 2927*0Sstevel@tonic-gate * mddb reparse messages are not generated until 2928*0Sstevel@tonic-gate * the commd has been resumed later in the reconfig 2929*0Sstevel@tonic-gate * cycle. 2930*0Sstevel@tonic-gate */ 2931*0Sstevel@tonic-gate if (flags & MNSET_IN_RECONFIG) { 2932*0Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp)); 2933*0Sstevel@tonic-gate if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) { 2934*0Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp)); 2935*0Sstevel@tonic-gate mbp.c_setno = local_sp->setno; 2936*0Sstevel@tonic-gate mbp.c_blk_flags = MDDB_BLOCK_PARSE; 2937*0Sstevel@tonic-gate if (metaioctl(MD_MN_MDDB_BLOCK, &mbp, 2938*0Sstevel@tonic-gate &mbp.c_mde, NULL)) { 2939*0Sstevel@tonic-gate mdstealerror(&xep, &mbp.c_mde); 2940*0Sstevel@tonic-gate mde_perror(ep, gettext( 2941*0Sstevel@tonic-gate "Could not block set %s"), 2942*0Sstevel@tonic-gate sp->setname); 2943*0Sstevel@tonic-gate return; 2944*0Sstevel@tonic-gate } 2945*0Sstevel@tonic-gate } 2946*0Sstevel@tonic-gate /* 2947*0Sstevel@tonic-gate * If s_ownset fails and snarf_set succeeded, 2948*0Sstevel@tonic-gate * then can steal the ownset failure information 2949*0Sstevel@tonic-gate * and store it into ep. If snarf_set failed, 2950*0Sstevel@tonic-gate * don't overwrite critical ep information even 2951*0Sstevel@tonic-gate * if s_ownset failed. 2952*0Sstevel@tonic-gate */ 2953*0Sstevel@tonic-gate if (!mdisok(&xep)) { 2954*0Sstevel@tonic-gate /* 2955*0Sstevel@tonic-gate * If snarf_set succeeded or snarf_set failed 2956*0Sstevel@tonic-gate * with MDE_DB_ACCOK (which is set if the 2957*0Sstevel@tonic-gate * mediator provided the extra vote) then 2958*0Sstevel@tonic-gate * steal the xep failure information and put 2959*0Sstevel@tonic-gate * into ep. 2960*0Sstevel@tonic-gate */ 2961*0Sstevel@tonic-gate if (mdisok(ep) || 2962*0Sstevel@tonic-gate mdismddberror(ep, MDE_DB_ACCOK)) { 2963*0Sstevel@tonic-gate mdstealerror(ep, &xep); 2964*0Sstevel@tonic-gate } 2965*0Sstevel@tonic-gate } 2966*0Sstevel@tonic-gate } 2967*0Sstevel@tonic-gate } 2968*0Sstevel@tonic-gate } 2969*0Sstevel@tonic-gate 2970*0Sstevel@tonic-gate /* 2971*0Sstevel@tonic-gate * Have this node join the set. 2972*0Sstevel@tonic-gate * This is called when a node has been 2973*0Sstevel@tonic-gate * added to a MN diskset that has drives. 2974*0Sstevel@tonic-gate * Also, called when a node is an alive 2975*0Sstevel@tonic-gate * member of a MN diskset and the first 2976*0Sstevel@tonic-gate * drive has been added. 2977*0Sstevel@tonic-gate */ 2978*0Sstevel@tonic-gate bool_t 2979*0Sstevel@tonic-gate mdrpc_joinset_common( 2980*0Sstevel@tonic-gate mdrpc_sp_flags_args *args, 2981*0Sstevel@tonic-gate mdrpc_generic_res *res, 2982*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 2983*0Sstevel@tonic-gate ) 2984*0Sstevel@tonic-gate { 2985*0Sstevel@tonic-gate md_error_t *ep = &res->status; 2986*0Sstevel@tonic-gate int err; 2987*0Sstevel@tonic-gate int op_mode = W_OK; 2988*0Sstevel@tonic-gate 2989*0Sstevel@tonic-gate /* setup, check permissions */ 2990*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 2991*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 2992*0Sstevel@tonic-gate return (FALSE); 2993*0Sstevel@tonic-gate else if (err != 0) 2994*0Sstevel@tonic-gate return (TRUE); 2995*0Sstevel@tonic-gate 2996*0Sstevel@tonic-gate /* 2997*0Sstevel@tonic-gate * During reconfig, joinset can happen without 2998*0Sstevel@tonic-gate * locking first. Turn off reconfig flag before calling 2999*0Sstevel@tonic-gate * joinset. 3000*0Sstevel@tonic-gate */ 3001*0Sstevel@tonic-gate if (!(args->flags & MNSET_IN_RECONFIG)) { 3002*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 3003*0Sstevel@tonic-gate return (TRUE); 3004*0Sstevel@tonic-gate } 3005*0Sstevel@tonic-gate 3006*0Sstevel@tonic-gate /* doit */ 3007*0Sstevel@tonic-gate joinset(args->sp, args->flags, ep); 3008*0Sstevel@tonic-gate 3009*0Sstevel@tonic-gate err = svc_fini(ep); 3010*0Sstevel@tonic-gate 3011*0Sstevel@tonic-gate return (TRUE); 3012*0Sstevel@tonic-gate } 3013*0Sstevel@tonic-gate 3014*0Sstevel@tonic-gate bool_t 3015*0Sstevel@tonic-gate mdrpc_joinset_2_svc( 3016*0Sstevel@tonic-gate mdrpc_sp_flags_2_args *args, 3017*0Sstevel@tonic-gate mdrpc_generic_res *res, 3018*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3019*0Sstevel@tonic-gate ) 3020*0Sstevel@tonic-gate { 3021*0Sstevel@tonic-gate switch (args->rev) { 3022*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3023*0Sstevel@tonic-gate return (mdrpc_joinset_common( 3024*0Sstevel@tonic-gate &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp)); 3025*0Sstevel@tonic-gate default: 3026*0Sstevel@tonic-gate return (FALSE); 3027*0Sstevel@tonic-gate } 3028*0Sstevel@tonic-gate } 3029*0Sstevel@tonic-gate 3030*0Sstevel@tonic-gate static void 3031*0Sstevel@tonic-gate withdrawset( 3032*0Sstevel@tonic-gate mdsetname_t *sp, 3033*0Sstevel@tonic-gate md_error_t *ep 3034*0Sstevel@tonic-gate ) 3035*0Sstevel@tonic-gate { 3036*0Sstevel@tonic-gate mdsetname_t *my_sp; 3037*0Sstevel@tonic-gate 3038*0Sstevel@tonic-gate if ((my_sp = metasetname(sp->setname, ep)) == NULL) 3039*0Sstevel@tonic-gate return; 3040*0Sstevel@tonic-gate 3041*0Sstevel@tonic-gate (void) halt_set(my_sp, ep); 3042*0Sstevel@tonic-gate } 3043*0Sstevel@tonic-gate 3044*0Sstevel@tonic-gate /* 3045*0Sstevel@tonic-gate * Have this node withdraw from set. 3046*0Sstevel@tonic-gate * In response to a failure that occurred 3047*0Sstevel@tonic-gate * on the client after a joinset. 3048*0Sstevel@tonic-gate */ 3049*0Sstevel@tonic-gate bool_t 3050*0Sstevel@tonic-gate mdrpc_withdrawset_common( 3051*0Sstevel@tonic-gate mdrpc_sp_args *args, 3052*0Sstevel@tonic-gate mdrpc_generic_res *res, 3053*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3054*0Sstevel@tonic-gate ) 3055*0Sstevel@tonic-gate { 3056*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3057*0Sstevel@tonic-gate int err; 3058*0Sstevel@tonic-gate int op_mode = W_OK; 3059*0Sstevel@tonic-gate 3060*0Sstevel@tonic-gate /* setup, check permissions */ 3061*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3062*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3063*0Sstevel@tonic-gate return (FALSE); 3064*0Sstevel@tonic-gate else if (err != 0) 3065*0Sstevel@tonic-gate return (TRUE); 3066*0Sstevel@tonic-gate 3067*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 3068*0Sstevel@tonic-gate return (TRUE); 3069*0Sstevel@tonic-gate 3070*0Sstevel@tonic-gate /* doit */ 3071*0Sstevel@tonic-gate withdrawset(args->sp, ep); 3072*0Sstevel@tonic-gate 3073*0Sstevel@tonic-gate err = svc_fini(ep); 3074*0Sstevel@tonic-gate 3075*0Sstevel@tonic-gate return (TRUE); 3076*0Sstevel@tonic-gate } 3077*0Sstevel@tonic-gate 3078*0Sstevel@tonic-gate bool_t 3079*0Sstevel@tonic-gate mdrpc_withdrawset_2_svc( 3080*0Sstevel@tonic-gate mdrpc_sp_2_args *args, 3081*0Sstevel@tonic-gate mdrpc_generic_res *res, 3082*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3083*0Sstevel@tonic-gate ) 3084*0Sstevel@tonic-gate { 3085*0Sstevel@tonic-gate switch (args->rev) { 3086*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3087*0Sstevel@tonic-gate return (mdrpc_withdrawset_common( 3088*0Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3089*0Sstevel@tonic-gate default: 3090*0Sstevel@tonic-gate return (FALSE); 3091*0Sstevel@tonic-gate } 3092*0Sstevel@tonic-gate } 3093*0Sstevel@tonic-gate 3094*0Sstevel@tonic-gate static mhd_mhiargs_t * 3095*0Sstevel@tonic-gate gtimeout(mdsetname_t *sp, md_error_t *ep) 3096*0Sstevel@tonic-gate { 3097*0Sstevel@tonic-gate md_set_record *sr; 3098*0Sstevel@tonic-gate mhd_mhiargs_t *mhiargs; 3099*0Sstevel@tonic-gate 3100*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3101*0Sstevel@tonic-gate return (NULL); 3102*0Sstevel@tonic-gate 3103*0Sstevel@tonic-gate mhiargs = Zalloc(sizeof (*mhiargs)); 3104*0Sstevel@tonic-gate *mhiargs = sr->sr_mhiargs; 3105*0Sstevel@tonic-gate 3106*0Sstevel@tonic-gate free_sr(sr); 3107*0Sstevel@tonic-gate return (mhiargs); 3108*0Sstevel@tonic-gate } 3109*0Sstevel@tonic-gate 3110*0Sstevel@tonic-gate /* 3111*0Sstevel@tonic-gate * Get the MH timeout values for this set. 3112*0Sstevel@tonic-gate */ 3113*0Sstevel@tonic-gate bool_t 3114*0Sstevel@tonic-gate mdrpc_gtimeout_common( 3115*0Sstevel@tonic-gate mdrpc_sp_args *args, 3116*0Sstevel@tonic-gate mdrpc_gtimeout_res *res, 3117*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3118*0Sstevel@tonic-gate ) 3119*0Sstevel@tonic-gate { 3120*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3121*0Sstevel@tonic-gate int err; 3122*0Sstevel@tonic-gate int op_mode = R_OK; 3123*0Sstevel@tonic-gate 3124*0Sstevel@tonic-gate /* setup, check permissions */ 3125*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3126*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3127*0Sstevel@tonic-gate return (FALSE); 3128*0Sstevel@tonic-gate else if (err != 0) 3129*0Sstevel@tonic-gate return (TRUE); 3130*0Sstevel@tonic-gate 3131*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 3132*0Sstevel@tonic-gate return (TRUE); 3133*0Sstevel@tonic-gate 3134*0Sstevel@tonic-gate /* doit */ 3135*0Sstevel@tonic-gate res->mhiargsp = gtimeout(args->sp, ep); 3136*0Sstevel@tonic-gate 3137*0Sstevel@tonic-gate err = svc_fini(ep); 3138*0Sstevel@tonic-gate 3139*0Sstevel@tonic-gate return (TRUE); 3140*0Sstevel@tonic-gate } 3141*0Sstevel@tonic-gate 3142*0Sstevel@tonic-gate bool_t 3143*0Sstevel@tonic-gate mdrpc_gtimeout_1_svc( 3144*0Sstevel@tonic-gate mdrpc_sp_args *args, 3145*0Sstevel@tonic-gate mdrpc_gtimeout_res *res, 3146*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3147*0Sstevel@tonic-gate ) 3148*0Sstevel@tonic-gate { 3149*0Sstevel@tonic-gate return (mdrpc_gtimeout_common(args, res, rqstp)); 3150*0Sstevel@tonic-gate } 3151*0Sstevel@tonic-gate 3152*0Sstevel@tonic-gate bool_t 3153*0Sstevel@tonic-gate mdrpc_gtimeout_2_svc( 3154*0Sstevel@tonic-gate mdrpc_sp_2_args *args, 3155*0Sstevel@tonic-gate mdrpc_gtimeout_res *res, 3156*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3157*0Sstevel@tonic-gate ) 3158*0Sstevel@tonic-gate { 3159*0Sstevel@tonic-gate switch (args->rev) { 3160*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3161*0Sstevel@tonic-gate return (mdrpc_gtimeout_common( 3162*0Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3163*0Sstevel@tonic-gate default: 3164*0Sstevel@tonic-gate return (FALSE); 3165*0Sstevel@tonic-gate } 3166*0Sstevel@tonic-gate } 3167*0Sstevel@tonic-gate 3168*0Sstevel@tonic-gate /* 3169*0Sstevel@tonic-gate * return the official host name for the callee 3170*0Sstevel@tonic-gate */ 3171*0Sstevel@tonic-gate /*ARGSUSED*/ 3172*0Sstevel@tonic-gate bool_t 3173*0Sstevel@tonic-gate mdrpc_hostname_common( 3174*0Sstevel@tonic-gate mdrpc_null_args *args, 3175*0Sstevel@tonic-gate mdrpc_hostname_res *res, 3176*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3177*0Sstevel@tonic-gate ) 3178*0Sstevel@tonic-gate { 3179*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3180*0Sstevel@tonic-gate int err; 3181*0Sstevel@tonic-gate int op_mode = R_OK; 3182*0Sstevel@tonic-gate 3183*0Sstevel@tonic-gate /* setup, check permissions */ 3184*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3185*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3186*0Sstevel@tonic-gate return (FALSE); 3187*0Sstevel@tonic-gate else if (err != 0) 3188*0Sstevel@tonic-gate return (TRUE); 3189*0Sstevel@tonic-gate 3190*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 3191*0Sstevel@tonic-gate return (TRUE); 3192*0Sstevel@tonic-gate 3193*0Sstevel@tonic-gate /* doit */ 3194*0Sstevel@tonic-gate res->hostname = Strdup(mynode()); 3195*0Sstevel@tonic-gate 3196*0Sstevel@tonic-gate err = svc_fini(ep); 3197*0Sstevel@tonic-gate 3198*0Sstevel@tonic-gate return (TRUE); 3199*0Sstevel@tonic-gate } 3200*0Sstevel@tonic-gate 3201*0Sstevel@tonic-gate bool_t 3202*0Sstevel@tonic-gate mdrpc_hostname_1_svc( 3203*0Sstevel@tonic-gate mdrpc_null_args *args, 3204*0Sstevel@tonic-gate mdrpc_hostname_res *res, 3205*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3206*0Sstevel@tonic-gate ) 3207*0Sstevel@tonic-gate { 3208*0Sstevel@tonic-gate return (mdrpc_hostname_common(args, res, rqstp)); 3209*0Sstevel@tonic-gate } 3210*0Sstevel@tonic-gate 3211*0Sstevel@tonic-gate bool_t 3212*0Sstevel@tonic-gate mdrpc_hostname_2_svc( 3213*0Sstevel@tonic-gate mdrpc_null_args *args, 3214*0Sstevel@tonic-gate mdrpc_hostname_res *res, 3215*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3216*0Sstevel@tonic-gate ) 3217*0Sstevel@tonic-gate { 3218*0Sstevel@tonic-gate return (mdrpc_hostname_common(args, res, rqstp)); 3219*0Sstevel@tonic-gate } 3220*0Sstevel@tonic-gate 3221*0Sstevel@tonic-gate /* 3222*0Sstevel@tonic-gate * return a response 3223*0Sstevel@tonic-gate */ 3224*0Sstevel@tonic-gate /*ARGSUSED*/ 3225*0Sstevel@tonic-gate bool_t 3226*0Sstevel@tonic-gate mdrpc_nullproc_common( 3227*0Sstevel@tonic-gate void *args, 3228*0Sstevel@tonic-gate md_error_t *ep, 3229*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3230*0Sstevel@tonic-gate ) 3231*0Sstevel@tonic-gate { 3232*0Sstevel@tonic-gate *ep = mdnullerror; 3233*0Sstevel@tonic-gate /* do nothing */ 3234*0Sstevel@tonic-gate return (TRUE); 3235*0Sstevel@tonic-gate } 3236*0Sstevel@tonic-gate 3237*0Sstevel@tonic-gate bool_t 3238*0Sstevel@tonic-gate mdrpc_nullproc_1_svc( 3239*0Sstevel@tonic-gate void *args, 3240*0Sstevel@tonic-gate md_error_t *ep, 3241*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3242*0Sstevel@tonic-gate ) 3243*0Sstevel@tonic-gate { 3244*0Sstevel@tonic-gate return (mdrpc_nullproc_common(args, ep, rqstp)); 3245*0Sstevel@tonic-gate } 3246*0Sstevel@tonic-gate 3247*0Sstevel@tonic-gate bool_t 3248*0Sstevel@tonic-gate mdrpc_nullproc_2_svc( 3249*0Sstevel@tonic-gate void *args, 3250*0Sstevel@tonic-gate md_error_t *ep, 3251*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3252*0Sstevel@tonic-gate ) 3253*0Sstevel@tonic-gate { 3254*0Sstevel@tonic-gate return (mdrpc_nullproc_common(args, ep, rqstp)); 3255*0Sstevel@tonic-gate } 3256*0Sstevel@tonic-gate 3257*0Sstevel@tonic-gate /* 3258*0Sstevel@tonic-gate * determine if the caller owns the set. 3259*0Sstevel@tonic-gate */ 3260*0Sstevel@tonic-gate bool_t 3261*0Sstevel@tonic-gate mdrpc_ownset_common( 3262*0Sstevel@tonic-gate mdrpc_sp_args *args, 3263*0Sstevel@tonic-gate mdrpc_bool_res *res, 3264*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3265*0Sstevel@tonic-gate ) 3266*0Sstevel@tonic-gate { 3267*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3268*0Sstevel@tonic-gate int err; 3269*0Sstevel@tonic-gate int op_mode = R_OK; 3270*0Sstevel@tonic-gate 3271*0Sstevel@tonic-gate /* setup, check permissions */ 3272*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3273*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3274*0Sstevel@tonic-gate return (FALSE); 3275*0Sstevel@tonic-gate else if (err != 0) 3276*0Sstevel@tonic-gate return (TRUE); 3277*0Sstevel@tonic-gate 3278*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 3279*0Sstevel@tonic-gate return (TRUE); 3280*0Sstevel@tonic-gate 3281*0Sstevel@tonic-gate /* doit */ 3282*0Sstevel@tonic-gate if (s_ownset(args->sp->setno, ep)) 3283*0Sstevel@tonic-gate res->value = TRUE; 3284*0Sstevel@tonic-gate else 3285*0Sstevel@tonic-gate res->value = FALSE; 3286*0Sstevel@tonic-gate 3287*0Sstevel@tonic-gate err = svc_fini(ep); 3288*0Sstevel@tonic-gate 3289*0Sstevel@tonic-gate return (TRUE); 3290*0Sstevel@tonic-gate } 3291*0Sstevel@tonic-gate 3292*0Sstevel@tonic-gate bool_t 3293*0Sstevel@tonic-gate mdrpc_ownset_1_svc( 3294*0Sstevel@tonic-gate mdrpc_sp_args *args, 3295*0Sstevel@tonic-gate mdrpc_bool_res *res, 3296*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3297*0Sstevel@tonic-gate ) 3298*0Sstevel@tonic-gate { 3299*0Sstevel@tonic-gate return (mdrpc_ownset_common(args, res, rqstp)); 3300*0Sstevel@tonic-gate } 3301*0Sstevel@tonic-gate 3302*0Sstevel@tonic-gate bool_t 3303*0Sstevel@tonic-gate mdrpc_ownset_2_svc( 3304*0Sstevel@tonic-gate mdrpc_sp_2_args *args, 3305*0Sstevel@tonic-gate mdrpc_bool_res *res, 3306*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3307*0Sstevel@tonic-gate ) 3308*0Sstevel@tonic-gate { 3309*0Sstevel@tonic-gate switch (args->rev) { 3310*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3311*0Sstevel@tonic-gate return (mdrpc_ownset_common( 3312*0Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3313*0Sstevel@tonic-gate default: 3314*0Sstevel@tonic-gate return (FALSE); 3315*0Sstevel@tonic-gate } 3316*0Sstevel@tonic-gate } 3317*0Sstevel@tonic-gate 3318*0Sstevel@tonic-gate static int 3319*0Sstevel@tonic-gate setnameok(char *setname, md_error_t *ep) 3320*0Sstevel@tonic-gate { 3321*0Sstevel@tonic-gate int rval = 0; 3322*0Sstevel@tonic-gate struct stat statb; 3323*0Sstevel@tonic-gate md_set_record *sr = NULL; 3324*0Sstevel@tonic-gate char *setlink = NULL; 3325*0Sstevel@tonic-gate 3326*0Sstevel@tonic-gate setlink = Strdup("/dev/md/"); 3327*0Sstevel@tonic-gate setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1); 3328*0Sstevel@tonic-gate (void) strcat(setlink, setname); 3329*0Sstevel@tonic-gate 3330*0Sstevel@tonic-gate if (lstat(setlink, &statb) == -1) { 3331*0Sstevel@tonic-gate /* 3332*0Sstevel@tonic-gate * If lstat() fails with ENOENT, setname is OK, if it 3333*0Sstevel@tonic-gate * fails for other than that, we fail the RPC 3334*0Sstevel@tonic-gate */ 3335*0Sstevel@tonic-gate if (errno == ENOENT) { 3336*0Sstevel@tonic-gate rval = 1; 3337*0Sstevel@tonic-gate goto out; 3338*0Sstevel@tonic-gate } 3339*0Sstevel@tonic-gate 3340*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, setlink); 3341*0Sstevel@tonic-gate goto out; 3342*0Sstevel@tonic-gate } 3343*0Sstevel@tonic-gate 3344*0Sstevel@tonic-gate /* 3345*0Sstevel@tonic-gate * If the lstat() succeeded, then we see what type of object 3346*0Sstevel@tonic-gate * we are dealing with, if it is a symlink, we do some further 3347*0Sstevel@tonic-gate * checking, if it is not a symlink, then we return an 3348*0Sstevel@tonic-gate * indication that the set name is NOT acceptable. 3349*0Sstevel@tonic-gate */ 3350*0Sstevel@tonic-gate if (! S_ISLNK(statb.st_mode)) 3351*0Sstevel@tonic-gate goto out; 3352*0Sstevel@tonic-gate 3353*0Sstevel@tonic-gate /* 3354*0Sstevel@tonic-gate * We look up the setname to see if there is a set 3355*0Sstevel@tonic-gate * with that name, if there is, then we return 3356*0Sstevel@tonic-gate * an indication that the set name is NOT acceptable. 3357*0Sstevel@tonic-gate */ 3358*0Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) != NULL) 3359*0Sstevel@tonic-gate goto out; 3360*0Sstevel@tonic-gate 3361*0Sstevel@tonic-gate if (! mdiserror(ep, MDE_NO_SET)) 3362*0Sstevel@tonic-gate goto out; 3363*0Sstevel@tonic-gate 3364*0Sstevel@tonic-gate mdclrerror(ep); 3365*0Sstevel@tonic-gate 3366*0Sstevel@tonic-gate rval = 1; 3367*0Sstevel@tonic-gate out: 3368*0Sstevel@tonic-gate if (sr != NULL) 3369*0Sstevel@tonic-gate free_sr(sr); 3370*0Sstevel@tonic-gate Free(setlink); 3371*0Sstevel@tonic-gate return (rval); 3372*0Sstevel@tonic-gate } 3373*0Sstevel@tonic-gate 3374*0Sstevel@tonic-gate /* 3375*0Sstevel@tonic-gate * Make sure the name of the set is OK. 3376*0Sstevel@tonic-gate */ 3377*0Sstevel@tonic-gate bool_t 3378*0Sstevel@tonic-gate mdrpc_setnameok_common( 3379*0Sstevel@tonic-gate mdrpc_sp_args *args, /* device name */ 3380*0Sstevel@tonic-gate mdrpc_bool_res *res, 3381*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3382*0Sstevel@tonic-gate ) 3383*0Sstevel@tonic-gate { 3384*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3385*0Sstevel@tonic-gate int err; 3386*0Sstevel@tonic-gate int op_mode = R_OK; 3387*0Sstevel@tonic-gate 3388*0Sstevel@tonic-gate /* setup, check permissions */ 3389*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3390*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3391*0Sstevel@tonic-gate return (FALSE); 3392*0Sstevel@tonic-gate else if (err != 0) 3393*0Sstevel@tonic-gate return (TRUE); 3394*0Sstevel@tonic-gate 3395*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 3396*0Sstevel@tonic-gate return (TRUE); 3397*0Sstevel@tonic-gate 3398*0Sstevel@tonic-gate /* doit */ 3399*0Sstevel@tonic-gate res->value = setnameok(args->sp->setname, ep); 3400*0Sstevel@tonic-gate 3401*0Sstevel@tonic-gate err = svc_fini(ep); 3402*0Sstevel@tonic-gate 3403*0Sstevel@tonic-gate return (TRUE); 3404*0Sstevel@tonic-gate } 3405*0Sstevel@tonic-gate 3406*0Sstevel@tonic-gate bool_t 3407*0Sstevel@tonic-gate mdrpc_setnameok_1_svc( 3408*0Sstevel@tonic-gate mdrpc_sp_args *args, /* device name */ 3409*0Sstevel@tonic-gate mdrpc_bool_res *res, 3410*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3411*0Sstevel@tonic-gate ) 3412*0Sstevel@tonic-gate { 3413*0Sstevel@tonic-gate return (mdrpc_setnameok_common(args, res, rqstp)); 3414*0Sstevel@tonic-gate } 3415*0Sstevel@tonic-gate 3416*0Sstevel@tonic-gate bool_t 3417*0Sstevel@tonic-gate mdrpc_setnameok_2_svc( 3418*0Sstevel@tonic-gate mdrpc_sp_2_args *args, /* device name */ 3419*0Sstevel@tonic-gate mdrpc_bool_res *res, 3420*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3421*0Sstevel@tonic-gate ) 3422*0Sstevel@tonic-gate { 3423*0Sstevel@tonic-gate switch (args->rev) { 3424*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3425*0Sstevel@tonic-gate return (mdrpc_setnameok_common( 3426*0Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp)); 3427*0Sstevel@tonic-gate default: 3428*0Sstevel@tonic-gate return (FALSE); 3429*0Sstevel@tonic-gate } 3430*0Sstevel@tonic-gate } 3431*0Sstevel@tonic-gate 3432*0Sstevel@tonic-gate /* 3433*0Sstevel@tonic-gate * determine if the setnumber we want to share is in use. 3434*0Sstevel@tonic-gate */ 3435*0Sstevel@tonic-gate bool_t 3436*0Sstevel@tonic-gate mdrpc_setnumbusy_common( 3437*0Sstevel@tonic-gate mdrpc_setno_args *args, 3438*0Sstevel@tonic-gate mdrpc_bool_res *res, 3439*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3440*0Sstevel@tonic-gate ) 3441*0Sstevel@tonic-gate { 3442*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3443*0Sstevel@tonic-gate md_set_record *sr = NULL; 3444*0Sstevel@tonic-gate int err; 3445*0Sstevel@tonic-gate int op_mode = R_OK; 3446*0Sstevel@tonic-gate 3447*0Sstevel@tonic-gate /* setup, check permissions */ 3448*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3449*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3450*0Sstevel@tonic-gate return (FALSE); 3451*0Sstevel@tonic-gate else if (err != 0) 3452*0Sstevel@tonic-gate return (TRUE); 3453*0Sstevel@tonic-gate 3454*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 3455*0Sstevel@tonic-gate return (TRUE); 3456*0Sstevel@tonic-gate 3457*0Sstevel@tonic-gate /* doit */ 3458*0Sstevel@tonic-gate if ((sr = getsetbynum(args->setno, ep)) != NULL) { 3459*0Sstevel@tonic-gate res->value = TRUE; 3460*0Sstevel@tonic-gate free_sr(sr); 3461*0Sstevel@tonic-gate return (TRUE); 3462*0Sstevel@tonic-gate } 3463*0Sstevel@tonic-gate res->value = FALSE; 3464*0Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET)) 3465*0Sstevel@tonic-gate mdclrerror(ep); 3466*0Sstevel@tonic-gate 3467*0Sstevel@tonic-gate err = svc_fini(ep); 3468*0Sstevel@tonic-gate 3469*0Sstevel@tonic-gate return (TRUE); 3470*0Sstevel@tonic-gate } 3471*0Sstevel@tonic-gate 3472*0Sstevel@tonic-gate bool_t 3473*0Sstevel@tonic-gate mdrpc_setnumbusy_1_svc( 3474*0Sstevel@tonic-gate mdrpc_setno_args *args, 3475*0Sstevel@tonic-gate mdrpc_bool_res *res, 3476*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3477*0Sstevel@tonic-gate ) 3478*0Sstevel@tonic-gate { 3479*0Sstevel@tonic-gate return (mdrpc_setnumbusy_common(args, res, rqstp)); 3480*0Sstevel@tonic-gate } 3481*0Sstevel@tonic-gate 3482*0Sstevel@tonic-gate bool_t 3483*0Sstevel@tonic-gate mdrpc_setnumbusy_2_svc( 3484*0Sstevel@tonic-gate mdrpc_setno_2_args *args, 3485*0Sstevel@tonic-gate mdrpc_bool_res *res, 3486*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3487*0Sstevel@tonic-gate ) 3488*0Sstevel@tonic-gate { 3489*0Sstevel@tonic-gate switch (args->rev) { 3490*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3491*0Sstevel@tonic-gate return (mdrpc_setnumbusy_common( 3492*0Sstevel@tonic-gate &args->mdrpc_setno_2_args_u.rev1, res, rqstp)); 3493*0Sstevel@tonic-gate default: 3494*0Sstevel@tonic-gate return (FALSE); 3495*0Sstevel@tonic-gate } 3496*0Sstevel@tonic-gate } 3497*0Sstevel@tonic-gate 3498*0Sstevel@tonic-gate static void 3499*0Sstevel@tonic-gate stimeout( 3500*0Sstevel@tonic-gate mdsetname_t *sp, 3501*0Sstevel@tonic-gate mhd_mhiargs_t *mhiargsp, 3502*0Sstevel@tonic-gate int version, /* RPC version of calling routine */ 3503*0Sstevel@tonic-gate md_error_t *ep 3504*0Sstevel@tonic-gate ) 3505*0Sstevel@tonic-gate { 3506*0Sstevel@tonic-gate mddb_userreq_t req; 3507*0Sstevel@tonic-gate md_set_record *sr; 3508*0Sstevel@tonic-gate 3509*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3510*0Sstevel@tonic-gate return; 3511*0Sstevel@tonic-gate 3512*0Sstevel@tonic-gate sr->sr_mhiargs = *mhiargsp; 3513*0Sstevel@tonic-gate 3514*0Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req)); 3515*0Sstevel@tonic-gate 3516*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 3517*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 3518*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 3519*0Sstevel@tonic-gate req.ur_size = sizeof (struct md_mnset_record); 3520*0Sstevel@tonic-gate } else { 3521*0Sstevel@tonic-gate req.ur_size = sizeof (*sr); 3522*0Sstevel@tonic-gate } 3523*0Sstevel@tonic-gate req.ur_data = (uintptr_t)sr; 3524*0Sstevel@tonic-gate 3525*0Sstevel@tonic-gate /* 3526*0Sstevel@tonic-gate * Cluster nodename support 3527*0Sstevel@tonic-gate * Convert nodename -> nodeid 3528*0Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored 3529*0Sstevel@tonic-gate * both the nodeid and name. 3530*0Sstevel@tonic-gate */ 3531*0Sstevel@tonic-gate if ((version == METAD_VERSION) || 3532*0Sstevel@tonic-gate ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr))))) 3533*0Sstevel@tonic-gate sdssc_cm_sr_nm2nid(sr); 3534*0Sstevel@tonic-gate 3535*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 3536*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 3537*0Sstevel@tonic-gate return; 3538*0Sstevel@tonic-gate } 3539*0Sstevel@tonic-gate 3540*0Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req)); 3541*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid) 3542*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) 3543*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 3544*0Sstevel@tonic-gate 3545*0Sstevel@tonic-gate /* 3546*0Sstevel@tonic-gate * Cluster nodename support 3547*0Sstevel@tonic-gate * Convert nodeid -> nodename 3548*0Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored 3549*0Sstevel@tonic-gate * both the nodeid and name. 3550*0Sstevel@tonic-gate */ 3551*0Sstevel@tonic-gate if ((version == METAD_VERSION) || 3552*0Sstevel@tonic-gate ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr))))) 3553*0Sstevel@tonic-gate sdssc_cm_sr_nid2nm(sr); 3554*0Sstevel@tonic-gate 3555*0Sstevel@tonic-gate free_sr(sr); 3556*0Sstevel@tonic-gate } 3557*0Sstevel@tonic-gate 3558*0Sstevel@tonic-gate /* 3559*0Sstevel@tonic-gate * Set MH ioctl timeout values. 3560*0Sstevel@tonic-gate */ 3561*0Sstevel@tonic-gate bool_t 3562*0Sstevel@tonic-gate mdrpc_stimeout_common( 3563*0Sstevel@tonic-gate mdrpc_stimeout_args *args, 3564*0Sstevel@tonic-gate mdrpc_generic_res *res, 3565*0Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */ 3566*0Sstevel@tonic-gate int version /* RPC version */ 3567*0Sstevel@tonic-gate ) 3568*0Sstevel@tonic-gate { 3569*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3570*0Sstevel@tonic-gate int err; 3571*0Sstevel@tonic-gate int op_mode = W_OK; 3572*0Sstevel@tonic-gate 3573*0Sstevel@tonic-gate /* setup, check permissions */ 3574*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3575*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3576*0Sstevel@tonic-gate return (FALSE); 3577*0Sstevel@tonic-gate else if (err != 0) 3578*0Sstevel@tonic-gate return (TRUE); 3579*0Sstevel@tonic-gate 3580*0Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep)) 3581*0Sstevel@tonic-gate return (TRUE); 3582*0Sstevel@tonic-gate 3583*0Sstevel@tonic-gate /* doit */ 3584*0Sstevel@tonic-gate stimeout(args->sp, args->mhiargsp, version, ep); 3585*0Sstevel@tonic-gate 3586*0Sstevel@tonic-gate err = svc_fini(ep); 3587*0Sstevel@tonic-gate 3588*0Sstevel@tonic-gate return (TRUE); 3589*0Sstevel@tonic-gate } 3590*0Sstevel@tonic-gate 3591*0Sstevel@tonic-gate bool_t 3592*0Sstevel@tonic-gate mdrpc_stimeout_1_svc( 3593*0Sstevel@tonic-gate mdrpc_stimeout_args *args, 3594*0Sstevel@tonic-gate mdrpc_generic_res *res, 3595*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3596*0Sstevel@tonic-gate ) 3597*0Sstevel@tonic-gate { 3598*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */ 3599*0Sstevel@tonic-gate return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION)); 3600*0Sstevel@tonic-gate } 3601*0Sstevel@tonic-gate 3602*0Sstevel@tonic-gate bool_t 3603*0Sstevel@tonic-gate mdrpc_stimeout_2_svc( 3604*0Sstevel@tonic-gate mdrpc_stimeout_2_args *args, 3605*0Sstevel@tonic-gate mdrpc_generic_res *res, 3606*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3607*0Sstevel@tonic-gate ) 3608*0Sstevel@tonic-gate { 3609*0Sstevel@tonic-gate switch (args->rev) { 3610*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3611*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 3612*0Sstevel@tonic-gate return (mdrpc_stimeout_common( 3613*0Sstevel@tonic-gate &args->mdrpc_stimeout_2_args_u.rev1, res, 3614*0Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID)); 3615*0Sstevel@tonic-gate default: 3616*0Sstevel@tonic-gate return (FALSE); 3617*0Sstevel@tonic-gate } 3618*0Sstevel@tonic-gate } 3619*0Sstevel@tonic-gate 3620*0Sstevel@tonic-gate static void 3621*0Sstevel@tonic-gate upd_dr_dbinfo( 3622*0Sstevel@tonic-gate mdsetname_t *sp, 3623*0Sstevel@tonic-gate md_drive_desc *dd, 3624*0Sstevel@tonic-gate md_error_t *ep 3625*0Sstevel@tonic-gate ) 3626*0Sstevel@tonic-gate { 3627*0Sstevel@tonic-gate mdsetname_t *local_sp; 3628*0Sstevel@tonic-gate md_set_record *sr; 3629*0Sstevel@tonic-gate md_drive_record *dr; 3630*0Sstevel@tonic-gate md_drive_desc *p; 3631*0Sstevel@tonic-gate mddrivename_t *dn, *dn1; 3632*0Sstevel@tonic-gate ddi_devid_t devid_remote = NULL; 3633*0Sstevel@tonic-gate ddi_devid_t devid_local = NULL; 3634*0Sstevel@tonic-gate int devid_same = -1; 3635*0Sstevel@tonic-gate side_t sideno; 3636*0Sstevel@tonic-gate int using_devid = 0; 3637*0Sstevel@tonic-gate 3638*0Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL) 3639*0Sstevel@tonic-gate return; 3640*0Sstevel@tonic-gate 3641*0Sstevel@tonic-gate metaflushsetname(local_sp); 3642*0Sstevel@tonic-gate 3643*0Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 3644*0Sstevel@tonic-gate return; 3645*0Sstevel@tonic-gate 3646*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3647*0Sstevel@tonic-gate return; 3648*0Sstevel@tonic-gate 3649*0Sstevel@tonic-gate if (dd->dd_dnp == NULL) 3650*0Sstevel@tonic-gate return; 3651*0Sstevel@tonic-gate 3652*0Sstevel@tonic-gate /* 3653*0Sstevel@tonic-gate * The system is either all devid or all 3654*0Sstevel@tonic-gate * non-devid so we determine this by looking 3655*0Sstevel@tonic-gate * at the first item in the list. 3656*0Sstevel@tonic-gate * 3657*0Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which 3658*0Sstevel@tonic-gate * points to a '' string of devid. We need to check this 3659*0Sstevel@tonic-gate * before set the using_devid. 3660*0Sstevel@tonic-gate */ 3661*0Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 3662*0Sstevel@tonic-gate (!(MD_MNSET_REC(sr)))) 3663*0Sstevel@tonic-gate using_devid = 1; 3664*0Sstevel@tonic-gate 3665*0Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) { 3666*0Sstevel@tonic-gate dn = p->dd_dnp; 3667*0Sstevel@tonic-gate devid_remote = NULL; 3668*0Sstevel@tonic-gate 3669*0Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) && 3670*0Sstevel@tonic-gate using_devid) { 3671*0Sstevel@tonic-gate /* 3672*0Sstevel@tonic-gate * We have a devid so use it. 3673*0Sstevel@tonic-gate */ 3674*0Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL); 3675*0Sstevel@tonic-gate } 3676*0Sstevel@tonic-gate 3677*0Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */ 3678*0Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) { 3679*0Sstevel@tonic-gate /* something went really wrong. Can't process */ 3680*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 3681*0Sstevel@tonic-gate mynode(), dn->cname, sp->setname); 3682*0Sstevel@tonic-gate return; 3683*0Sstevel@tonic-gate } 3684*0Sstevel@tonic-gate 3685*0Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 3686*0Sstevel@tonic-gate devid_same = -1; 3687*0Sstevel@tonic-gate 3688*0Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno, 3689*0Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep); 3690*0Sstevel@tonic-gate 3691*0Sstevel@tonic-gate if (dn1 == NULL) { 3692*0Sstevel@tonic-gate if (devid_remote) 3693*0Sstevel@tonic-gate devid_free(devid_remote); 3694*0Sstevel@tonic-gate goto out; 3695*0Sstevel@tonic-gate } 3696*0Sstevel@tonic-gate 3697*0Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) { 3698*0Sstevel@tonic-gate if (devid_str_decode(dn1->devid, &devid_local, 3699*0Sstevel@tonic-gate NULL) == 0) { 3700*0Sstevel@tonic-gate devid_same = devid_compare(devid_remote, 3701*0Sstevel@tonic-gate devid_local); 3702*0Sstevel@tonic-gate devid_free(devid_local); 3703*0Sstevel@tonic-gate } 3704*0Sstevel@tonic-gate } 3705*0Sstevel@tonic-gate 3706*0Sstevel@tonic-gate if (using_devid && devid_same == 0) 3707*0Sstevel@tonic-gate break; 3708*0Sstevel@tonic-gate 3709*0Sstevel@tonic-gate if (!using_devid && 3710*0Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0) 3711*0Sstevel@tonic-gate break; 3712*0Sstevel@tonic-gate } 3713*0Sstevel@tonic-gate 3714*0Sstevel@tonic-gate if (dr) { 3715*0Sstevel@tonic-gate /* Adjust the fields in the copy */ 3716*0Sstevel@tonic-gate dr->dr_dbcnt = p->dd_dbcnt; 3717*0Sstevel@tonic-gate dr->dr_dbsize = p->dd_dbsize; 3718*0Sstevel@tonic-gate } 3719*0Sstevel@tonic-gate if (devid_remote) 3720*0Sstevel@tonic-gate devid_free(devid_remote); 3721*0Sstevel@tonic-gate } 3722*0Sstevel@tonic-gate 3723*0Sstevel@tonic-gate 3724*0Sstevel@tonic-gate out: 3725*0Sstevel@tonic-gate commitset(sr, FALSE, ep); 3726*0Sstevel@tonic-gate free_sr(sr); 3727*0Sstevel@tonic-gate } 3728*0Sstevel@tonic-gate 3729*0Sstevel@tonic-gate /* 3730*0Sstevel@tonic-gate * update the database count and size field of drive records. 3731*0Sstevel@tonic-gate */ 3732*0Sstevel@tonic-gate bool_t 3733*0Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_common( 3734*0Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args, 3735*0Sstevel@tonic-gate mdrpc_generic_res *res, 3736*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3737*0Sstevel@tonic-gate ) 3738*0Sstevel@tonic-gate { 3739*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3740*0Sstevel@tonic-gate int err; 3741*0Sstevel@tonic-gate int op_mode = W_OK; 3742*0Sstevel@tonic-gate 3743*0Sstevel@tonic-gate /* setup, check permissions */ 3744*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3745*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3746*0Sstevel@tonic-gate return (FALSE); 3747*0Sstevel@tonic-gate else if (err != 0) 3748*0Sstevel@tonic-gate return (TRUE); 3749*0Sstevel@tonic-gate 3750*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 3751*0Sstevel@tonic-gate return (TRUE); 3752*0Sstevel@tonic-gate 3753*0Sstevel@tonic-gate /* doit */ 3754*0Sstevel@tonic-gate upd_dr_dbinfo(args->sp, args->drivedescs, ep); 3755*0Sstevel@tonic-gate 3756*0Sstevel@tonic-gate err = svc_fini(ep); 3757*0Sstevel@tonic-gate 3758*0Sstevel@tonic-gate return (TRUE); 3759*0Sstevel@tonic-gate } 3760*0Sstevel@tonic-gate 3761*0Sstevel@tonic-gate /* 3762*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 3763*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 3764*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 3765*0Sstevel@tonic-gate */ 3766*0Sstevel@tonic-gate bool_t 3767*0Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_1_svc( 3768*0Sstevel@tonic-gate mdrpc_drives_args *args, 3769*0Sstevel@tonic-gate mdrpc_generic_res *res, 3770*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3771*0Sstevel@tonic-gate ) 3772*0Sstevel@tonic-gate { 3773*0Sstevel@tonic-gate bool_t retval; 3774*0Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args; 3775*0Sstevel@tonic-gate 3776*0Sstevel@tonic-gate /* allocate memory */ 3777*0Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 3778*0Sstevel@tonic-gate 3779*0Sstevel@tonic-gate /* build args */ 3780*0Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk; 3781*0Sstevel@tonic-gate v2_args.sp = args->sp; 3782*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 3783*0Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 3784*0Sstevel@tonic-gate v2_args.timestamp = args->timestamp; 3785*0Sstevel@tonic-gate v2_args.genid = args->genid; 3786*0Sstevel@tonic-gate 3787*0Sstevel@tonic-gate retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp); 3788*0Sstevel@tonic-gate 3789*0Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs); 3790*0Sstevel@tonic-gate 3791*0Sstevel@tonic-gate return (retval); 3792*0Sstevel@tonic-gate } 3793*0Sstevel@tonic-gate 3794*0Sstevel@tonic-gate bool_t 3795*0Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_2_svc( 3796*0Sstevel@tonic-gate mdrpc_drives_2_args *args, 3797*0Sstevel@tonic-gate mdrpc_generic_res *res, 3798*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3799*0Sstevel@tonic-gate ) 3800*0Sstevel@tonic-gate { 3801*0Sstevel@tonic-gate switch (args->rev) { 3802*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3803*0Sstevel@tonic-gate return (mdrpc_upd_dr_dbinfo_common( 3804*0Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp)); 3805*0Sstevel@tonic-gate default: 3806*0Sstevel@tonic-gate return (FALSE); 3807*0Sstevel@tonic-gate } 3808*0Sstevel@tonic-gate } 3809*0Sstevel@tonic-gate 3810*0Sstevel@tonic-gate static void 3811*0Sstevel@tonic-gate upd_dr_flags( 3812*0Sstevel@tonic-gate mdsetname_t *sp, 3813*0Sstevel@tonic-gate md_drive_desc *dd, 3814*0Sstevel@tonic-gate uint_t new_flags, 3815*0Sstevel@tonic-gate md_error_t *ep 3816*0Sstevel@tonic-gate ) 3817*0Sstevel@tonic-gate { 3818*0Sstevel@tonic-gate mdsetname_t *local_sp; 3819*0Sstevel@tonic-gate md_set_record *sr; 3820*0Sstevel@tonic-gate md_drive_record *dr; 3821*0Sstevel@tonic-gate md_drive_desc *p; 3822*0Sstevel@tonic-gate mddrivename_t *dn, *dn1; 3823*0Sstevel@tonic-gate ddi_devid_t devid_remote = NULL; 3824*0Sstevel@tonic-gate ddi_devid_t devid_local = NULL; 3825*0Sstevel@tonic-gate int devid_same = -1; 3826*0Sstevel@tonic-gate side_t sideno; 3827*0Sstevel@tonic-gate int using_devid = 0; 3828*0Sstevel@tonic-gate 3829*0Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL) 3830*0Sstevel@tonic-gate return; 3831*0Sstevel@tonic-gate 3832*0Sstevel@tonic-gate metaflushsetname(local_sp); 3833*0Sstevel@tonic-gate 3834*0Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 3835*0Sstevel@tonic-gate return; 3836*0Sstevel@tonic-gate 3837*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 3838*0Sstevel@tonic-gate return; 3839*0Sstevel@tonic-gate 3840*0Sstevel@tonic-gate if (dd->dd_dnp == NULL) 3841*0Sstevel@tonic-gate return; 3842*0Sstevel@tonic-gate 3843*0Sstevel@tonic-gate /* 3844*0Sstevel@tonic-gate * The system is either all devid or all 3845*0Sstevel@tonic-gate * non-devid so we determine this by looking 3846*0Sstevel@tonic-gate * at the first item in the list. 3847*0Sstevel@tonic-gate * 3848*0Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which 3849*0Sstevel@tonic-gate * points to a '' string of devid. We need to check this 3850*0Sstevel@tonic-gate * before set the using_devid. 3851*0Sstevel@tonic-gate */ 3852*0Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') && 3853*0Sstevel@tonic-gate (!(MD_MNSET_REC(sr)))) 3854*0Sstevel@tonic-gate using_devid = 1; 3855*0Sstevel@tonic-gate 3856*0Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) { 3857*0Sstevel@tonic-gate dn = p->dd_dnp; 3858*0Sstevel@tonic-gate devid_remote = NULL; 3859*0Sstevel@tonic-gate 3860*0Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) && 3861*0Sstevel@tonic-gate using_devid) { 3862*0Sstevel@tonic-gate /* 3863*0Sstevel@tonic-gate * We have a devid so use it. 3864*0Sstevel@tonic-gate */ 3865*0Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL); 3866*0Sstevel@tonic-gate } 3867*0Sstevel@tonic-gate 3868*0Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */ 3869*0Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) { 3870*0Sstevel@tonic-gate /* something went really wrong. Can't process */ 3871*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno, 3872*0Sstevel@tonic-gate mynode(), dn->cname, sp->setname); 3873*0Sstevel@tonic-gate return; 3874*0Sstevel@tonic-gate } 3875*0Sstevel@tonic-gate 3876*0Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) { 3877*0Sstevel@tonic-gate devid_same = -1; 3878*0Sstevel@tonic-gate 3879*0Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno, 3880*0Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep); 3881*0Sstevel@tonic-gate 3882*0Sstevel@tonic-gate if (dn1 == NULL) { 3883*0Sstevel@tonic-gate if (devid_remote) 3884*0Sstevel@tonic-gate devid_free(devid_remote); 3885*0Sstevel@tonic-gate goto out; 3886*0Sstevel@tonic-gate } 3887*0Sstevel@tonic-gate 3888*0Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) { 3889*0Sstevel@tonic-gate if (devid_str_decode(dn1->devid, 3890*0Sstevel@tonic-gate &devid_local, NULL) == 0) { 3891*0Sstevel@tonic-gate devid_same = devid_compare(devid_remote, 3892*0Sstevel@tonic-gate devid_local); 3893*0Sstevel@tonic-gate devid_free(devid_local); 3894*0Sstevel@tonic-gate } 3895*0Sstevel@tonic-gate } 3896*0Sstevel@tonic-gate 3897*0Sstevel@tonic-gate if (using_devid && devid_same == 0) 3898*0Sstevel@tonic-gate break; 3899*0Sstevel@tonic-gate 3900*0Sstevel@tonic-gate if (!using_devid && 3901*0Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0) 3902*0Sstevel@tonic-gate break; 3903*0Sstevel@tonic-gate } 3904*0Sstevel@tonic-gate 3905*0Sstevel@tonic-gate if (dr) 3906*0Sstevel@tonic-gate dr->dr_flags = new_flags; 3907*0Sstevel@tonic-gate if (devid_remote) 3908*0Sstevel@tonic-gate devid_free(devid_remote); 3909*0Sstevel@tonic-gate } 3910*0Sstevel@tonic-gate out: 3911*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 3912*0Sstevel@tonic-gate free_sr(sr); 3913*0Sstevel@tonic-gate } 3914*0Sstevel@tonic-gate 3915*0Sstevel@tonic-gate /* 3916*0Sstevel@tonic-gate * update the database count and size field of drive records. 3917*0Sstevel@tonic-gate */ 3918*0Sstevel@tonic-gate bool_t 3919*0Sstevel@tonic-gate mdrpc_upd_dr_flags_common( 3920*0Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 *args, 3921*0Sstevel@tonic-gate mdrpc_generic_res *res, 3922*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3923*0Sstevel@tonic-gate ) 3924*0Sstevel@tonic-gate { 3925*0Sstevel@tonic-gate md_error_t *ep = &res->status; 3926*0Sstevel@tonic-gate int err; 3927*0Sstevel@tonic-gate int op_mode = W_OK; 3928*0Sstevel@tonic-gate 3929*0Sstevel@tonic-gate /* setup, check permissions */ 3930*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 3931*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 3932*0Sstevel@tonic-gate return (FALSE); 3933*0Sstevel@tonic-gate else if (err != 0) 3934*0Sstevel@tonic-gate return (TRUE); 3935*0Sstevel@tonic-gate 3936*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 3937*0Sstevel@tonic-gate return (TRUE); 3938*0Sstevel@tonic-gate 3939*0Sstevel@tonic-gate /* doit */ 3940*0Sstevel@tonic-gate upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep); 3941*0Sstevel@tonic-gate 3942*0Sstevel@tonic-gate err = svc_fini(ep); 3943*0Sstevel@tonic-gate 3944*0Sstevel@tonic-gate return (TRUE); 3945*0Sstevel@tonic-gate } 3946*0Sstevel@tonic-gate 3947*0Sstevel@tonic-gate /* 3948*0Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the 3949*0Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments 3950*0Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure. 3951*0Sstevel@tonic-gate */ 3952*0Sstevel@tonic-gate bool_t 3953*0Sstevel@tonic-gate mdrpc_upd_dr_flags_1_svc( 3954*0Sstevel@tonic-gate mdrpc_upd_dr_flags_args *args, 3955*0Sstevel@tonic-gate mdrpc_generic_res *res, 3956*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3957*0Sstevel@tonic-gate ) 3958*0Sstevel@tonic-gate { 3959*0Sstevel@tonic-gate bool_t retval; 3960*0Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 v2_args; 3961*0Sstevel@tonic-gate 3962*0Sstevel@tonic-gate /* allocate memory */ 3963*0Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs); 3964*0Sstevel@tonic-gate 3965*0Sstevel@tonic-gate /* build args */ 3966*0Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk; 3967*0Sstevel@tonic-gate v2_args.sp = args->sp; 3968*0Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */ 3969*0Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs); 3970*0Sstevel@tonic-gate v2_args.new_flags = args->new_flags; 3971*0Sstevel@tonic-gate 3972*0Sstevel@tonic-gate retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp); 3973*0Sstevel@tonic-gate 3974*0Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs); 3975*0Sstevel@tonic-gate 3976*0Sstevel@tonic-gate return (retval); 3977*0Sstevel@tonic-gate } 3978*0Sstevel@tonic-gate 3979*0Sstevel@tonic-gate bool_t 3980*0Sstevel@tonic-gate mdrpc_upd_dr_flags_2_svc( 3981*0Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args *args, 3982*0Sstevel@tonic-gate mdrpc_generic_res *res, 3983*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 3984*0Sstevel@tonic-gate ) 3985*0Sstevel@tonic-gate { 3986*0Sstevel@tonic-gate switch (args->rev) { 3987*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 3988*0Sstevel@tonic-gate return (mdrpc_upd_dr_flags_common( 3989*0Sstevel@tonic-gate &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp)); 3990*0Sstevel@tonic-gate default: 3991*0Sstevel@tonic-gate return (FALSE); 3992*0Sstevel@tonic-gate } 3993*0Sstevel@tonic-gate } 3994*0Sstevel@tonic-gate 3995*0Sstevel@tonic-gate static void 3996*0Sstevel@tonic-gate upd_sr_flags( 3997*0Sstevel@tonic-gate mdsetname_t *sp, 3998*0Sstevel@tonic-gate uint_t new_flags, 3999*0Sstevel@tonic-gate md_error_t *ep 4000*0Sstevel@tonic-gate ) 4001*0Sstevel@tonic-gate { 4002*0Sstevel@tonic-gate md_set_record *sr; 4003*0Sstevel@tonic-gate 4004*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 4005*0Sstevel@tonic-gate return; 4006*0Sstevel@tonic-gate 4007*0Sstevel@tonic-gate sr->sr_flags = new_flags; 4008*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 4009*0Sstevel@tonic-gate free_sr(sr); 4010*0Sstevel@tonic-gate } 4011*0Sstevel@tonic-gate 4012*0Sstevel@tonic-gate /* 4013*0Sstevel@tonic-gate * update the set record flags 4014*0Sstevel@tonic-gate */ 4015*0Sstevel@tonic-gate bool_t 4016*0Sstevel@tonic-gate mdrpc_upd_sr_flags_common( 4017*0Sstevel@tonic-gate mdrpc_upd_sr_flags_args *args, 4018*0Sstevel@tonic-gate mdrpc_generic_res *res, 4019*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4020*0Sstevel@tonic-gate ) 4021*0Sstevel@tonic-gate { 4022*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4023*0Sstevel@tonic-gate int err; 4024*0Sstevel@tonic-gate int op_mode = W_OK; 4025*0Sstevel@tonic-gate 4026*0Sstevel@tonic-gate /* setup, check permissions */ 4027*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4028*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4029*0Sstevel@tonic-gate return (FALSE); 4030*0Sstevel@tonic-gate else if (err != 0) 4031*0Sstevel@tonic-gate return (TRUE); 4032*0Sstevel@tonic-gate 4033*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 4034*0Sstevel@tonic-gate return (TRUE); 4035*0Sstevel@tonic-gate 4036*0Sstevel@tonic-gate /* doit */ 4037*0Sstevel@tonic-gate upd_sr_flags(args->sp, args->new_flags, ep); 4038*0Sstevel@tonic-gate 4039*0Sstevel@tonic-gate err = svc_fini(ep); 4040*0Sstevel@tonic-gate 4041*0Sstevel@tonic-gate return (TRUE); 4042*0Sstevel@tonic-gate } 4043*0Sstevel@tonic-gate 4044*0Sstevel@tonic-gate bool_t 4045*0Sstevel@tonic-gate mdrpc_upd_sr_flags_1_svc( 4046*0Sstevel@tonic-gate mdrpc_upd_sr_flags_args *args, 4047*0Sstevel@tonic-gate mdrpc_generic_res *res, 4048*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4049*0Sstevel@tonic-gate ) 4050*0Sstevel@tonic-gate { 4051*0Sstevel@tonic-gate return (mdrpc_upd_sr_flags_common(args, res, rqstp)); 4052*0Sstevel@tonic-gate } 4053*0Sstevel@tonic-gate 4054*0Sstevel@tonic-gate bool_t 4055*0Sstevel@tonic-gate mdrpc_upd_sr_flags_2_svc( 4056*0Sstevel@tonic-gate mdrpc_upd_sr_flags_2_args *args, 4057*0Sstevel@tonic-gate mdrpc_generic_res *res, 4058*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4059*0Sstevel@tonic-gate ) 4060*0Sstevel@tonic-gate { 4061*0Sstevel@tonic-gate switch (args->rev) { 4062*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 4063*0Sstevel@tonic-gate return (mdrpc_upd_sr_flags_common( 4064*0Sstevel@tonic-gate &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp)); 4065*0Sstevel@tonic-gate default: 4066*0Sstevel@tonic-gate return (FALSE); 4067*0Sstevel@tonic-gate } 4068*0Sstevel@tonic-gate } 4069*0Sstevel@tonic-gate 4070*0Sstevel@tonic-gate /* 4071*0Sstevel@tonic-gate * upd_nr_flags updates the node records stored in this node's local mddb 4072*0Sstevel@tonic-gate * given a node desciptor list and an action. upd_nr_flags then commits 4073*0Sstevel@tonic-gate * the node records to the local mddb. 4074*0Sstevel@tonic-gate * 4075*0Sstevel@tonic-gate * nd - A linked list of node descriptors that describes the node records 4076*0Sstevel@tonic-gate * in this diskset on which the action applies. 4077*0Sstevel@tonic-gate * flag_action: action to be taken on node records that match the nd list. 4078*0Sstevel@tonic-gate * flag_action can be: 4079*0Sstevel@tonic-gate * MD_NR_JOIN: set OWN flag in node records 4080*0Sstevel@tonic-gate * MD_NR_WITHDRAW: reset OWN flag in node records 4081*0Sstevel@tonic-gate * MD_NR_OK: reset ADD flags and set OK flag in node records 4082*0Sstevel@tonic-gate * MD_NR_SET: set node record flags based on flags stored in nd 4083*0Sstevel@tonic-gate * 4084*0Sstevel@tonic-gate * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting 4085*0Sstevel@tonic-gate * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW 4086*0Sstevel@tonic-gate * (remove last disk from set) or OK (after addition of host to set). 4087*0Sstevel@tonic-gate * 4088*0Sstevel@tonic-gate * The SET flag_action is typically used when nodelist contains all nodes 4089*0Sstevel@tonic-gate * in the diskset, but specific nodes have had flag changes. An example of 4090*0Sstevel@tonic-gate * this would be the join/withdraw of a specific node to/from the set. 4091*0Sstevel@tonic-gate * 4092*0Sstevel@tonic-gate * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag. This 4093*0Sstevel@tonic-gate * flag is used by the client to recover in case of failure and should not 4094*0Sstevel@tonic-gate * be set in the node record flags. 4095*0Sstevel@tonic-gate */ 4096*0Sstevel@tonic-gate static void 4097*0Sstevel@tonic-gate upd_nr_flags( 4098*0Sstevel@tonic-gate mdsetname_t *sp, 4099*0Sstevel@tonic-gate md_mnnode_desc *nd, 4100*0Sstevel@tonic-gate uint_t flag_action, 4101*0Sstevel@tonic-gate md_error_t *ep 4102*0Sstevel@tonic-gate ) 4103*0Sstevel@tonic-gate { 4104*0Sstevel@tonic-gate mdsetname_t *local_sp; 4105*0Sstevel@tonic-gate md_set_record *sr; 4106*0Sstevel@tonic-gate md_mnset_record *mnsr; 4107*0Sstevel@tonic-gate md_mnnode_desc *ndp; 4108*0Sstevel@tonic-gate md_mnnode_record *nrp; 4109*0Sstevel@tonic-gate 4110*0Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL) 4111*0Sstevel@tonic-gate return; 4112*0Sstevel@tonic-gate 4113*0Sstevel@tonic-gate metaflushsetname(local_sp); 4114*0Sstevel@tonic-gate 4115*0Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL) 4116*0Sstevel@tonic-gate return; 4117*0Sstevel@tonic-gate 4118*0Sstevel@tonic-gate if (!(MD_MNSET_REC(sr))) { 4119*0Sstevel@tonic-gate return; 4120*0Sstevel@tonic-gate } 4121*0Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr; 4122*0Sstevel@tonic-gate 4123*0Sstevel@tonic-gate switch (flag_action) { 4124*0Sstevel@tonic-gate case MD_NR_JOIN: 4125*0Sstevel@tonic-gate case MD_NR_WITHDRAW: 4126*0Sstevel@tonic-gate case MD_NR_SET: 4127*0Sstevel@tonic-gate case MD_NR_OK: 4128*0Sstevel@tonic-gate case MD_NR_DEL: 4129*0Sstevel@tonic-gate break; 4130*0Sstevel@tonic-gate default: 4131*0Sstevel@tonic-gate return; 4132*0Sstevel@tonic-gate } 4133*0Sstevel@tonic-gate 4134*0Sstevel@tonic-gate for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) { 4135*0Sstevel@tonic-gate /* Find matching node record for given node descriptor */ 4136*0Sstevel@tonic-gate for (nrp = mnsr->sr_nodechain; nrp != NULL; 4137*0Sstevel@tonic-gate nrp = nrp->nr_next) { 4138*0Sstevel@tonic-gate if (ndp->nd_nodeid == nrp->nr_nodeid) { 4139*0Sstevel@tonic-gate switch (flag_action) { 4140*0Sstevel@tonic-gate case MD_NR_JOIN: 4141*0Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_OWN; 4142*0Sstevel@tonic-gate break; 4143*0Sstevel@tonic-gate case MD_NR_WITHDRAW: 4144*0Sstevel@tonic-gate nrp->nr_flags &= ~MD_MN_NODE_OWN; 4145*0Sstevel@tonic-gate break; 4146*0Sstevel@tonic-gate case MD_NR_OK: 4147*0Sstevel@tonic-gate nrp->nr_flags &= 4148*0Sstevel@tonic-gate ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL); 4149*0Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_OK; 4150*0Sstevel@tonic-gate break; 4151*0Sstevel@tonic-gate case MD_NR_DEL: 4152*0Sstevel@tonic-gate nrp->nr_flags &= 4153*0Sstevel@tonic-gate ~(MD_MN_NODE_OK | MD_MN_NODE_ADD); 4154*0Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_DEL; 4155*0Sstevel@tonic-gate break; 4156*0Sstevel@tonic-gate case MD_NR_SET: 4157*0Sstevel@tonic-gate /* Do not set RB_JOIN flag */ 4158*0Sstevel@tonic-gate nrp->nr_flags = 4159*0Sstevel@tonic-gate ndp->nd_flags & ~MD_MN_NODE_RB_JOIN; 4160*0Sstevel@tonic-gate break; 4161*0Sstevel@tonic-gate } 4162*0Sstevel@tonic-gate break; 4163*0Sstevel@tonic-gate } 4164*0Sstevel@tonic-gate } 4165*0Sstevel@tonic-gate } 4166*0Sstevel@tonic-gate out: 4167*0Sstevel@tonic-gate /* Don't increment set genid for node record flag update */ 4168*0Sstevel@tonic-gate commitset(sr, FALSE, ep); 4169*0Sstevel@tonic-gate free_sr(sr); 4170*0Sstevel@tonic-gate } 4171*0Sstevel@tonic-gate 4172*0Sstevel@tonic-gate /* 4173*0Sstevel@tonic-gate * init/fini wrapper around upd_nr_flags 4174*0Sstevel@tonic-gate */ 4175*0Sstevel@tonic-gate bool_t 4176*0Sstevel@tonic-gate mdrpc_upd_nr_flags_common( 4177*0Sstevel@tonic-gate mdrpc_upd_nr_flags_args *args, 4178*0Sstevel@tonic-gate mdrpc_generic_res *res, 4179*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4180*0Sstevel@tonic-gate ) 4181*0Sstevel@tonic-gate { 4182*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4183*0Sstevel@tonic-gate int err; 4184*0Sstevel@tonic-gate int op_mode = W_OK; 4185*0Sstevel@tonic-gate 4186*0Sstevel@tonic-gate /* setup, check permissions */ 4187*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4188*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4189*0Sstevel@tonic-gate return (FALSE); 4190*0Sstevel@tonic-gate else if (err != 0) 4191*0Sstevel@tonic-gate return (TRUE); 4192*0Sstevel@tonic-gate 4193*0Sstevel@tonic-gate /* 4194*0Sstevel@tonic-gate * During reconfig, node record flags can be updated without 4195*0Sstevel@tonic-gate * locking first. 4196*0Sstevel@tonic-gate */ 4197*0Sstevel@tonic-gate if (!(args->flags & MNSET_IN_RECONFIG)) { 4198*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 4199*0Sstevel@tonic-gate return (TRUE); 4200*0Sstevel@tonic-gate } 4201*0Sstevel@tonic-gate 4202*0Sstevel@tonic-gate /* doit */ 4203*0Sstevel@tonic-gate upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep); 4204*0Sstevel@tonic-gate 4205*0Sstevel@tonic-gate err = svc_fini(ep); 4206*0Sstevel@tonic-gate 4207*0Sstevel@tonic-gate return (TRUE); 4208*0Sstevel@tonic-gate } 4209*0Sstevel@tonic-gate 4210*0Sstevel@tonic-gate /* 4211*0Sstevel@tonic-gate * update the node records using given flag action. 4212*0Sstevel@tonic-gate */ 4213*0Sstevel@tonic-gate bool_t 4214*0Sstevel@tonic-gate mdrpc_upd_nr_flags_2_svc( 4215*0Sstevel@tonic-gate mdrpc_upd_nr_flags_2_args *args, 4216*0Sstevel@tonic-gate mdrpc_generic_res *res, 4217*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4218*0Sstevel@tonic-gate ) 4219*0Sstevel@tonic-gate { 4220*0Sstevel@tonic-gate switch (args->rev) { 4221*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 4222*0Sstevel@tonic-gate return (mdrpc_upd_nr_flags_common( 4223*0Sstevel@tonic-gate &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp)); 4224*0Sstevel@tonic-gate default: 4225*0Sstevel@tonic-gate return (FALSE); 4226*0Sstevel@tonic-gate } 4227*0Sstevel@tonic-gate } 4228*0Sstevel@tonic-gate 4229*0Sstevel@tonic-gate void 4230*0Sstevel@tonic-gate free_sk(md_setkey_t *skp) 4231*0Sstevel@tonic-gate { 4232*0Sstevel@tonic-gate Free(skp->sk_setname); 4233*0Sstevel@tonic-gate Free(skp->sk_host); 4234*0Sstevel@tonic-gate Free(skp); 4235*0Sstevel@tonic-gate } 4236*0Sstevel@tonic-gate 4237*0Sstevel@tonic-gate void 4238*0Sstevel@tonic-gate del_sk(set_t setno) 4239*0Sstevel@tonic-gate { 4240*0Sstevel@tonic-gate md_setkey_t *skp; 4241*0Sstevel@tonic-gate md_setkey_t *tskp; 4242*0Sstevel@tonic-gate 4243*0Sstevel@tonic-gate for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) { 4244*0Sstevel@tonic-gate if (setno == skp->sk_setno) { 4245*0Sstevel@tonic-gate if (skp == my_svc_sk) 4246*0Sstevel@tonic-gate my_svc_sk = skp->sk_next; 4247*0Sstevel@tonic-gate else 4248*0Sstevel@tonic-gate tskp->sk_next = skp->sk_next; 4249*0Sstevel@tonic-gate 4250*0Sstevel@tonic-gate Free(skp->sk_setname); 4251*0Sstevel@tonic-gate Free(skp->sk_host); 4252*0Sstevel@tonic-gate Free(skp); 4253*0Sstevel@tonic-gate break; 4254*0Sstevel@tonic-gate } 4255*0Sstevel@tonic-gate } 4256*0Sstevel@tonic-gate } 4257*0Sstevel@tonic-gate 4258*0Sstevel@tonic-gate md_setkey_t * 4259*0Sstevel@tonic-gate dupsk(md_setkey_t *skp) 4260*0Sstevel@tonic-gate { 4261*0Sstevel@tonic-gate md_setkey_t *tskp; 4262*0Sstevel@tonic-gate 4263*0Sstevel@tonic-gate tskp = Zalloc(sizeof (md_setkey_t)); 4264*0Sstevel@tonic-gate 4265*0Sstevel@tonic-gate *tskp = *skp; 4266*0Sstevel@tonic-gate tskp->sk_host = Strdup(skp->sk_host); 4267*0Sstevel@tonic-gate tskp->sk_setname = Strdup(skp->sk_setname); 4268*0Sstevel@tonic-gate 4269*0Sstevel@tonic-gate return (tskp); 4270*0Sstevel@tonic-gate } 4271*0Sstevel@tonic-gate 4272*0Sstevel@tonic-gate md_setkey_t * 4273*0Sstevel@tonic-gate svc_get_setkey(set_t setno) 4274*0Sstevel@tonic-gate { 4275*0Sstevel@tonic-gate md_setkey_t *skp; 4276*0Sstevel@tonic-gate 4277*0Sstevel@tonic-gate for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next) 4278*0Sstevel@tonic-gate if (setno == skp->sk_setno) 4279*0Sstevel@tonic-gate return (dupsk(skp)); 4280*0Sstevel@tonic-gate return (NULL); 4281*0Sstevel@tonic-gate } 4282*0Sstevel@tonic-gate 4283*0Sstevel@tonic-gate void 4284*0Sstevel@tonic-gate svc_set_setkey(md_setkey_t *svc_sk) 4285*0Sstevel@tonic-gate { 4286*0Sstevel@tonic-gate md_setkey_t *skp; 4287*0Sstevel@tonic-gate 4288*0Sstevel@tonic-gate if (my_svc_sk == NULL) { 4289*0Sstevel@tonic-gate my_svc_sk = dupsk(svc_sk); 4290*0Sstevel@tonic-gate return; 4291*0Sstevel@tonic-gate } 4292*0Sstevel@tonic-gate 4293*0Sstevel@tonic-gate for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next) 4294*0Sstevel@tonic-gate assert(svc_sk->sk_setno != skp->sk_setno); 4295*0Sstevel@tonic-gate 4296*0Sstevel@tonic-gate skp->sk_next = dupsk(svc_sk); 4297*0Sstevel@tonic-gate } 4298*0Sstevel@tonic-gate 4299*0Sstevel@tonic-gate /* 4300*0Sstevel@tonic-gate * Unlock the set 4301*0Sstevel@tonic-gate * 4302*0Sstevel@tonic-gate * To unlock the set, the user must have the correct key, once this is verified 4303*0Sstevel@tonic-gate * the set is unlocked and the cached information for the set is flushed. 4304*0Sstevel@tonic-gate */ 4305*0Sstevel@tonic-gate bool_t 4306*0Sstevel@tonic-gate mdrpc_unlock_set_common( 4307*0Sstevel@tonic-gate mdrpc_null_args *args, 4308*0Sstevel@tonic-gate mdrpc_setlock_res *res, 4309*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4310*0Sstevel@tonic-gate ) 4311*0Sstevel@tonic-gate { 4312*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4313*0Sstevel@tonic-gate int err; 4314*0Sstevel@tonic-gate int op_mode = W_OK; 4315*0Sstevel@tonic-gate md_setkey_t *svc_skp; 4316*0Sstevel@tonic-gate md_set_desc *sd; 4317*0Sstevel@tonic-gate mdsetname_t *sp; 4318*0Sstevel@tonic-gate int multi_node = 0; 4319*0Sstevel@tonic-gate md_error_t xep = mdnullerror; 4320*0Sstevel@tonic-gate 4321*0Sstevel@tonic-gate /* setup, check permissions */ 4322*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4323*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4324*0Sstevel@tonic-gate return (FALSE); 4325*0Sstevel@tonic-gate else if (err != 0) 4326*0Sstevel@tonic-gate return (TRUE); 4327*0Sstevel@tonic-gate 4328*0Sstevel@tonic-gate /* 4329*0Sstevel@tonic-gate * Is diskset a MN diskset? 4330*0Sstevel@tonic-gate * Don't set error from this check since unlock set can be 4331*0Sstevel@tonic-gate * called after a set has been deleted. 4332*0Sstevel@tonic-gate */ 4333*0Sstevel@tonic-gate if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) && 4334*0Sstevel@tonic-gate ((sd = metaget_setdesc(sp, &xep)) != NULL)) { 4335*0Sstevel@tonic-gate if ((MD_MNSET_DESC(sd))) { 4336*0Sstevel@tonic-gate multi_node = 1; 4337*0Sstevel@tonic-gate } 4338*0Sstevel@tonic-gate } 4339*0Sstevel@tonic-gate 4340*0Sstevel@tonic-gate /* Get the set key, if any */ 4341*0Sstevel@tonic-gate svc_skp = svc_get_setkey(args->cl_sk->sk_setno); 4342*0Sstevel@tonic-gate 4343*0Sstevel@tonic-gate /* The set is locked */ 4344*0Sstevel@tonic-gate if (svc_skp != NULL) { 4345*0Sstevel@tonic-gate 4346*0Sstevel@tonic-gate /* Make sure the opener has the right key. */ 4347*0Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec || 4348*0Sstevel@tonic-gate args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) { 4349*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_ULKSBADKEY, 4350*0Sstevel@tonic-gate svc_skp->sk_setno, mynode(), svc_skp->sk_host, 4351*0Sstevel@tonic-gate svc_skp->sk_setname); 4352*0Sstevel@tonic-gate free_sk(svc_skp); 4353*0Sstevel@tonic-gate return (TRUE); 4354*0Sstevel@tonic-gate } 4355*0Sstevel@tonic-gate 4356*0Sstevel@tonic-gate /* Unlock the set */ 4357*0Sstevel@tonic-gate del_sk(args->cl_sk->sk_setno); 4358*0Sstevel@tonic-gate 4359*0Sstevel@tonic-gate /* Cleanup */ 4360*0Sstevel@tonic-gate free_sk(svc_skp); 4361*0Sstevel@tonic-gate 4362*0Sstevel@tonic-gate goto out; 4363*0Sstevel@tonic-gate } 4364*0Sstevel@tonic-gate 4365*0Sstevel@tonic-gate 4366*0Sstevel@tonic-gate /* 4367*0Sstevel@tonic-gate * It is possible on a MN diskset to attempt to unlock a set that 4368*0Sstevel@tonic-gate * is unlocked. This could occur when the metaset or metadb command 4369*0Sstevel@tonic-gate * is failing due to another metaset or metadb command running. 4370*0Sstevel@tonic-gate * So, print no warning for MN disksets. 4371*0Sstevel@tonic-gate */ 4372*0Sstevel@tonic-gate if (multi_node == 0) { 4373*0Sstevel@tonic-gate md_eprintf("Warning: set unlocked when unlock_set called!\n"); 4374*0Sstevel@tonic-gate } 4375*0Sstevel@tonic-gate 4376*0Sstevel@tonic-gate out: 4377*0Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4378*0Sstevel@tonic-gate 4379*0Sstevel@tonic-gate /* Flush the set cache */ 4380*0Sstevel@tonic-gate sr_cache_flush_setno(args->cl_sk->sk_setno); 4381*0Sstevel@tonic-gate 4382*0Sstevel@tonic-gate return (TRUE); 4383*0Sstevel@tonic-gate } 4384*0Sstevel@tonic-gate 4385*0Sstevel@tonic-gate bool_t 4386*0Sstevel@tonic-gate mdrpc_unlock_set_1_svc( 4387*0Sstevel@tonic-gate mdrpc_null_args *args, 4388*0Sstevel@tonic-gate mdrpc_setlock_res *res, 4389*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4390*0Sstevel@tonic-gate ) 4391*0Sstevel@tonic-gate { 4392*0Sstevel@tonic-gate return (mdrpc_unlock_set_common(args, res, rqstp)); 4393*0Sstevel@tonic-gate } 4394*0Sstevel@tonic-gate 4395*0Sstevel@tonic-gate bool_t 4396*0Sstevel@tonic-gate mdrpc_unlock_set_2_svc( 4397*0Sstevel@tonic-gate mdrpc_null_args *args, 4398*0Sstevel@tonic-gate mdrpc_setlock_res *res, 4399*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4400*0Sstevel@tonic-gate ) 4401*0Sstevel@tonic-gate { 4402*0Sstevel@tonic-gate return (mdrpc_unlock_set_common(args, res, rqstp)); 4403*0Sstevel@tonic-gate } 4404*0Sstevel@tonic-gate 4405*0Sstevel@tonic-gate /* 4406*0Sstevel@tonic-gate * Lock the set 4407*0Sstevel@tonic-gate * 4408*0Sstevel@tonic-gate * If the user does not hand us a key, then we generate a new key and lock the 4409*0Sstevel@tonic-gate * set using this new key that was generated, if the user hands us a key then 4410*0Sstevel@tonic-gate * we use the key to lock the set. 4411*0Sstevel@tonic-gate */ 4412*0Sstevel@tonic-gate bool_t 4413*0Sstevel@tonic-gate mdrpc_lock_set_common( 4414*0Sstevel@tonic-gate mdrpc_null_args *args, 4415*0Sstevel@tonic-gate mdrpc_setlock_res *res, 4416*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4417*0Sstevel@tonic-gate ) 4418*0Sstevel@tonic-gate { 4419*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4420*0Sstevel@tonic-gate int err; 4421*0Sstevel@tonic-gate md_error_t xep = mdnullerror; 4422*0Sstevel@tonic-gate int op_mode = W_OK; 4423*0Sstevel@tonic-gate md_setkey_t *svc_skp; 4424*0Sstevel@tonic-gate md_setkey_t new_sk; 4425*0Sstevel@tonic-gate md_set_desc *sd; 4426*0Sstevel@tonic-gate mdsetname_t *sp; 4427*0Sstevel@tonic-gate 4428*0Sstevel@tonic-gate /* setup, check permissions */ 4429*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4430*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4431*0Sstevel@tonic-gate return (FALSE); 4432*0Sstevel@tonic-gate else if (err != 0) 4433*0Sstevel@tonic-gate return (TRUE); 4434*0Sstevel@tonic-gate 4435*0Sstevel@tonic-gate svc_skp = svc_get_setkey(args->cl_sk->sk_setno); 4436*0Sstevel@tonic-gate 4437*0Sstevel@tonic-gate /* The set is unlocked */ 4438*0Sstevel@tonic-gate if (svc_skp == NULL) { 4439*0Sstevel@tonic-gate /* If we have been given a key, use it. */ 4440*0Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) { 4441*0Sstevel@tonic-gate svc_set_setkey(args->cl_sk); 4442*0Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4443*0Sstevel@tonic-gate goto out; 4444*0Sstevel@tonic-gate } 4445*0Sstevel@tonic-gate 4446*0Sstevel@tonic-gate /* We need to lock it, with a new key */ 4447*0Sstevel@tonic-gate new_sk = *args->cl_sk; 4448*0Sstevel@tonic-gate if (meta_gettimeofday(&new_sk.sk_key) == -1) { 4449*0Sstevel@tonic-gate (void) mdsyserror(ep, errno, "meta_gettimeofday()"); 4450*0Sstevel@tonic-gate mde_perror(&xep, ""); 4451*0Sstevel@tonic-gate md_exit(NULL, 1); 4452*0Sstevel@tonic-gate } 4453*0Sstevel@tonic-gate svc_set_setkey(&new_sk); 4454*0Sstevel@tonic-gate 4455*0Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4456*0Sstevel@tonic-gate goto out; 4457*0Sstevel@tonic-gate } 4458*0Sstevel@tonic-gate 4459*0Sstevel@tonic-gate /* 4460*0Sstevel@tonic-gate * If a MN diskset, the lock_set routine is used as a locking 4461*0Sstevel@tonic-gate * mechanism to keep multiple metaset and/or metadb commads 4462*0Sstevel@tonic-gate * from interfering with each other. If two metaset/metadb 4463*0Sstevel@tonic-gate * commands are issued at the same time - one will complete 4464*0Sstevel@tonic-gate * and the other command will fail with MDE_DS_NOTNOW_CMD. 4465*0Sstevel@tonic-gate */ 4466*0Sstevel@tonic-gate if (((sp = metasetnosetname(args->cl_sk->sk_setno, ep)) != NULL) && 4467*0Sstevel@tonic-gate ((sd = metaget_setdesc(sp, ep)) != NULL) && 4468*0Sstevel@tonic-gate (MD_MNSET_DESC(sd))) { 4469*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTNOW_CMD, 4470*0Sstevel@tonic-gate svc_skp->sk_setno, mynode(), 4471*0Sstevel@tonic-gate svc_skp->sk_host, svc_skp->sk_setname); 4472*0Sstevel@tonic-gate goto out; 4473*0Sstevel@tonic-gate } 4474*0Sstevel@tonic-gate 4475*0Sstevel@tonic-gate md_eprintf("Warning: set locked when lock_set called!\n"); 4476*0Sstevel@tonic-gate 4477*0Sstevel@tonic-gate md_eprintf("Lock info:\n"); 4478*0Sstevel@tonic-gate 4479*0Sstevel@tonic-gate md_eprintf("\tLock(svc):\n"); 4480*0Sstevel@tonic-gate md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname); 4481*0Sstevel@tonic-gate md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno); 4482*0Sstevel@tonic-gate md_eprintf("\t\tHost: %s\n", svc_skp->sk_host); 4483*0Sstevel@tonic-gate md_eprintf("\t\tKey: %d/%d %s", 4484*0Sstevel@tonic-gate svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec, 4485*0Sstevel@tonic-gate ctime((const time_t *)&svc_skp->sk_key.tv_sec)); 4486*0Sstevel@tonic-gate 4487*0Sstevel@tonic-gate md_eprintf("\tLock(cl):\n"); 4488*0Sstevel@tonic-gate md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname); 4489*0Sstevel@tonic-gate md_eprintf("\t\tSetno: %d\n", args->cl_sk->sk_setno); 4490*0Sstevel@tonic-gate md_eprintf("\t\tHost: %s\n", args->cl_sk->sk_host); 4491*0Sstevel@tonic-gate md_eprintf("\t\tKey: %d/%d %s", 4492*0Sstevel@tonic-gate args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec, 4493*0Sstevel@tonic-gate ctime((const time_t *)&args->cl_sk->sk_key.tv_sec)); 4494*0Sstevel@tonic-gate 4495*0Sstevel@tonic-gate /* The set is locked, do we have the key? */ 4496*0Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec && 4497*0Sstevel@tonic-gate args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) { 4498*0Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno); 4499*0Sstevel@tonic-gate goto out; 4500*0Sstevel@tonic-gate } 4501*0Sstevel@tonic-gate 4502*0Sstevel@tonic-gate /* 4503*0Sstevel@tonic-gate * The set is locked and we do not have the key, so we set up an error. 4504*0Sstevel@tonic-gate */ 4505*0Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(), 4506*0Sstevel@tonic-gate svc_skp->sk_host, args->cl_sk->sk_setname); 4507*0Sstevel@tonic-gate 4508*0Sstevel@tonic-gate out: 4509*0Sstevel@tonic-gate if (svc_skp != NULL) 4510*0Sstevel@tonic-gate free_sk(svc_skp); 4511*0Sstevel@tonic-gate 4512*0Sstevel@tonic-gate /* Flush the set cache */ 4513*0Sstevel@tonic-gate sr_cache_flush_setno(args->cl_sk->sk_setno); 4514*0Sstevel@tonic-gate 4515*0Sstevel@tonic-gate return (TRUE); 4516*0Sstevel@tonic-gate } 4517*0Sstevel@tonic-gate 4518*0Sstevel@tonic-gate bool_t 4519*0Sstevel@tonic-gate mdrpc_lock_set_1_svc( 4520*0Sstevel@tonic-gate mdrpc_null_args *args, 4521*0Sstevel@tonic-gate mdrpc_setlock_res *res, 4522*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4523*0Sstevel@tonic-gate ) 4524*0Sstevel@tonic-gate { 4525*0Sstevel@tonic-gate return (mdrpc_lock_set_common(args, res, rqstp)); 4526*0Sstevel@tonic-gate } 4527*0Sstevel@tonic-gate 4528*0Sstevel@tonic-gate bool_t 4529*0Sstevel@tonic-gate mdrpc_lock_set_2_svc( 4530*0Sstevel@tonic-gate mdrpc_null_args *args, 4531*0Sstevel@tonic-gate mdrpc_setlock_res *res, 4532*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4533*0Sstevel@tonic-gate ) 4534*0Sstevel@tonic-gate { 4535*0Sstevel@tonic-gate return (mdrpc_lock_set_common(args, res, rqstp)); 4536*0Sstevel@tonic-gate } 4537*0Sstevel@tonic-gate 4538*0Sstevel@tonic-gate static void 4539*0Sstevel@tonic-gate updmeds( 4540*0Sstevel@tonic-gate char *setname, 4541*0Sstevel@tonic-gate md_h_arr_t *medp, 4542*0Sstevel@tonic-gate int version, /* RPC version of calling routine */ 4543*0Sstevel@tonic-gate md_error_t *ep 4544*0Sstevel@tonic-gate ) 4545*0Sstevel@tonic-gate { 4546*0Sstevel@tonic-gate mddb_userreq_t req; 4547*0Sstevel@tonic-gate md_set_record *sr; 4548*0Sstevel@tonic-gate mddb_med_parm_t mp; 4549*0Sstevel@tonic-gate 4550*0Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL) 4551*0Sstevel@tonic-gate return; 4552*0Sstevel@tonic-gate 4553*0Sstevel@tonic-gate sr->sr_med = *medp; /* structure assignment */ 4554*0Sstevel@tonic-gate 4555*0Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req)); 4556*0Sstevel@tonic-gate 4557*0Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid) 4558*0Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */ 4559*0Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) { 4560*0Sstevel@tonic-gate req.ur_size = sizeof (struct md_mnset_record); 4561*0Sstevel@tonic-gate } else { 4562*0Sstevel@tonic-gate req.ur_size = sizeof (*sr); 4563*0Sstevel@tonic-gate } 4564*0Sstevel@tonic-gate req.ur_data = (uintptr_t)sr; 4565*0Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) { 4566*0Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde); 4567*0Sstevel@tonic-gate free_sr(sr); 4568*0Sstevel@tonic-gate return; 4569*0Sstevel@tonic-gate } 4570*0Sstevel@tonic-gate 4571*0Sstevel@tonic-gate commitset(sr, TRUE, ep); 4572*0Sstevel@tonic-gate 4573*0Sstevel@tonic-gate /* 4574*0Sstevel@tonic-gate * If a MN disket, send the mediator list to the kernel. 4575*0Sstevel@tonic-gate */ 4576*0Sstevel@tonic-gate if (MD_MNSET_REC(sr)) { 4577*0Sstevel@tonic-gate (void) memset(&mp, '\0', sizeof (mddb_med_parm_t)); 4578*0Sstevel@tonic-gate mp.med_setno = sr->sr_setno; 4579*0Sstevel@tonic-gate if (meta_h2hi(medp, &mp.med, ep)) { 4580*0Sstevel@tonic-gate free_sr(sr); 4581*0Sstevel@tonic-gate return; 4582*0Sstevel@tonic-gate } 4583*0Sstevel@tonic-gate 4584*0Sstevel@tonic-gate /* Resolve the IP addresses for the host list */ 4585*0Sstevel@tonic-gate if (meta_med_hnm2ip(&mp.med, ep)) { 4586*0Sstevel@tonic-gate free_sr(sr); 4587*0Sstevel@tonic-gate return; 4588*0Sstevel@tonic-gate } 4589*0Sstevel@tonic-gate 4590*0Sstevel@tonic-gate /* If node not yet joined to set, failure is ok. */ 4591*0Sstevel@tonic-gate if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) { 4592*0Sstevel@tonic-gate if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) { 4593*0Sstevel@tonic-gate (void) mdstealerror(ep, &mp.med_mde); 4594*0Sstevel@tonic-gate } 4595*0Sstevel@tonic-gate } 4596*0Sstevel@tonic-gate } 4597*0Sstevel@tonic-gate free_sr(sr); 4598*0Sstevel@tonic-gate } 4599*0Sstevel@tonic-gate 4600*0Sstevel@tonic-gate /* 4601*0Sstevel@tonic-gate * Update the mediator data in the set record 4602*0Sstevel@tonic-gate */ 4603*0Sstevel@tonic-gate bool_t 4604*0Sstevel@tonic-gate mdrpc_updmeds_common( 4605*0Sstevel@tonic-gate mdrpc_updmeds_args *args, 4606*0Sstevel@tonic-gate mdrpc_generic_res *res, 4607*0Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */ 4608*0Sstevel@tonic-gate int version /* RPC version */ 4609*0Sstevel@tonic-gate ) 4610*0Sstevel@tonic-gate { 4611*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4612*0Sstevel@tonic-gate int err; 4613*0Sstevel@tonic-gate int op_mode = W_OK; 4614*0Sstevel@tonic-gate 4615*0Sstevel@tonic-gate /* setup, check permissions */ 4616*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4617*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4618*0Sstevel@tonic-gate return (FALSE); 4619*0Sstevel@tonic-gate else if (err != 0) 4620*0Sstevel@tonic-gate return (TRUE); 4621*0Sstevel@tonic-gate 4622*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 4623*0Sstevel@tonic-gate return (TRUE); 4624*0Sstevel@tonic-gate 4625*0Sstevel@tonic-gate /* doit */ 4626*0Sstevel@tonic-gate updmeds(args->sp->setname, &args->meds, version, ep); 4627*0Sstevel@tonic-gate 4628*0Sstevel@tonic-gate err = svc_fini(ep); 4629*0Sstevel@tonic-gate 4630*0Sstevel@tonic-gate return (TRUE); 4631*0Sstevel@tonic-gate } 4632*0Sstevel@tonic-gate 4633*0Sstevel@tonic-gate bool_t 4634*0Sstevel@tonic-gate mdrpc_updmeds_1_svc( 4635*0Sstevel@tonic-gate mdrpc_updmeds_args *args, 4636*0Sstevel@tonic-gate mdrpc_generic_res *res, 4637*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4638*0Sstevel@tonic-gate ) 4639*0Sstevel@tonic-gate { 4640*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */ 4641*0Sstevel@tonic-gate return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION)); 4642*0Sstevel@tonic-gate } 4643*0Sstevel@tonic-gate 4644*0Sstevel@tonic-gate bool_t 4645*0Sstevel@tonic-gate mdrpc_updmeds_2_svc( 4646*0Sstevel@tonic-gate mdrpc_updmeds_2_args *args, 4647*0Sstevel@tonic-gate mdrpc_generic_res *res, 4648*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4649*0Sstevel@tonic-gate ) 4650*0Sstevel@tonic-gate { 4651*0Sstevel@tonic-gate switch (args->rev) { 4652*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 4653*0Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */ 4654*0Sstevel@tonic-gate return (mdrpc_updmeds_common( 4655*0Sstevel@tonic-gate &args->mdrpc_updmeds_2_args_u.rev1, res, 4656*0Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID)); 4657*0Sstevel@tonic-gate default: 4658*0Sstevel@tonic-gate return (FALSE); 4659*0Sstevel@tonic-gate } 4660*0Sstevel@tonic-gate } 4661*0Sstevel@tonic-gate 4662*0Sstevel@tonic-gate /* 4663*0Sstevel@tonic-gate * Call routines to suspend, reinit and resume mdcommd. 4664*0Sstevel@tonic-gate * Called during metaset and metadb command. 4665*0Sstevel@tonic-gate * NOT called during reconfig cycle. 4666*0Sstevel@tonic-gate */ 4667*0Sstevel@tonic-gate bool_t 4668*0Sstevel@tonic-gate mdrpc_mdcommdctl_2_svc( 4669*0Sstevel@tonic-gate mdrpc_mdcommdctl_2_args *args, 4670*0Sstevel@tonic-gate mdrpc_generic_res *res, 4671*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4672*0Sstevel@tonic-gate ) 4673*0Sstevel@tonic-gate { 4674*0Sstevel@tonic-gate mdrpc_mdcommdctl_args *args_cc; 4675*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4676*0Sstevel@tonic-gate int err; 4677*0Sstevel@tonic-gate int op_mode = R_OK; 4678*0Sstevel@tonic-gate int suspend_ret; 4679*0Sstevel@tonic-gate 4680*0Sstevel@tonic-gate switch (args->rev) { 4681*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 4682*0Sstevel@tonic-gate /* setup, check permissions */ 4683*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4684*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4685*0Sstevel@tonic-gate return (FALSE); 4686*0Sstevel@tonic-gate else if (err != 0) 4687*0Sstevel@tonic-gate return (TRUE); 4688*0Sstevel@tonic-gate 4689*0Sstevel@tonic-gate args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1); 4690*0Sstevel@tonic-gate switch (args_cc->flag_action) { 4691*0Sstevel@tonic-gate case COMMDCTL_SUSPEND: 4692*0Sstevel@tonic-gate suspend_ret = mdmn_suspend(args_cc->setno, 4693*0Sstevel@tonic-gate args_cc->class); 4694*0Sstevel@tonic-gate if (suspend_ret != 0) { 4695*0Sstevel@tonic-gate (void) mddserror(ep, suspend_ret, 4696*0Sstevel@tonic-gate args_cc->setno, mynode(), 4697*0Sstevel@tonic-gate NULL, mynode()); 4698*0Sstevel@tonic-gate } 4699*0Sstevel@tonic-gate break; 4700*0Sstevel@tonic-gate case COMMDCTL_RESUME: 4701*0Sstevel@tonic-gate if (mdmn_resume(args_cc->setno, 4702*0Sstevel@tonic-gate args_cc->class, args_cc->flags)) { 4703*0Sstevel@tonic-gate (void) mddserror(ep, 4704*0Sstevel@tonic-gate MDE_DS_COMMDCTL_RESUME_FAIL, 4705*0Sstevel@tonic-gate args_cc->setno, mynode(), 4706*0Sstevel@tonic-gate NULL, mynode()); 4707*0Sstevel@tonic-gate } 4708*0Sstevel@tonic-gate break; 4709*0Sstevel@tonic-gate case COMMDCTL_REINIT: 4710*0Sstevel@tonic-gate if (mdmn_reinit_set(args_cc->setno)) { 4711*0Sstevel@tonic-gate (void) mddserror(ep, 4712*0Sstevel@tonic-gate MDE_DS_COMMDCTL_REINIT_FAIL, 4713*0Sstevel@tonic-gate args_cc->setno, mynode(), 4714*0Sstevel@tonic-gate NULL, mynode()); 4715*0Sstevel@tonic-gate } 4716*0Sstevel@tonic-gate break; 4717*0Sstevel@tonic-gate } 4718*0Sstevel@tonic-gate err = svc_fini(ep); 4719*0Sstevel@tonic-gate return (TRUE); 4720*0Sstevel@tonic-gate 4721*0Sstevel@tonic-gate default: 4722*0Sstevel@tonic-gate return (FALSE); 4723*0Sstevel@tonic-gate } 4724*0Sstevel@tonic-gate } 4725*0Sstevel@tonic-gate 4726*0Sstevel@tonic-gate /* 4727*0Sstevel@tonic-gate * Return TRUE if set is stale. 4728*0Sstevel@tonic-gate */ 4729*0Sstevel@tonic-gate bool_t 4730*0Sstevel@tonic-gate mdrpc_mn_is_stale_2_svc( 4731*0Sstevel@tonic-gate mdrpc_setno_2_args *args, 4732*0Sstevel@tonic-gate mdrpc_bool_res *res, 4733*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4734*0Sstevel@tonic-gate ) 4735*0Sstevel@tonic-gate { 4736*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4737*0Sstevel@tonic-gate mddb_config_t c; 4738*0Sstevel@tonic-gate int err; 4739*0Sstevel@tonic-gate int op_mode = R_OK; 4740*0Sstevel@tonic-gate 4741*0Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c)); 4742*0Sstevel@tonic-gate switch (args->rev) { 4743*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 4744*0Sstevel@tonic-gate c.c_id = 0; 4745*0Sstevel@tonic-gate c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno; 4746*0Sstevel@tonic-gate 4747*0Sstevel@tonic-gate /* setup, check permissions */ 4748*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4749*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4750*0Sstevel@tonic-gate return (FALSE); 4751*0Sstevel@tonic-gate else if (err != 0) 4752*0Sstevel@tonic-gate return (TRUE); 4753*0Sstevel@tonic-gate 4754*0Sstevel@tonic-gate if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) { 4755*0Sstevel@tonic-gate mdstealerror(ep, &c.c_mde); 4756*0Sstevel@tonic-gate return (TRUE); 4757*0Sstevel@tonic-gate } 4758*0Sstevel@tonic-gate 4759*0Sstevel@tonic-gate if (c.c_flags & MDDB_C_STALE) { 4760*0Sstevel@tonic-gate res->value = TRUE; 4761*0Sstevel@tonic-gate } else { 4762*0Sstevel@tonic-gate res->value = FALSE; 4763*0Sstevel@tonic-gate } 4764*0Sstevel@tonic-gate 4765*0Sstevel@tonic-gate err = svc_fini(ep); 4766*0Sstevel@tonic-gate return (TRUE); 4767*0Sstevel@tonic-gate 4768*0Sstevel@tonic-gate default: 4769*0Sstevel@tonic-gate return (FALSE); 4770*0Sstevel@tonic-gate } 4771*0Sstevel@tonic-gate } 4772*0Sstevel@tonic-gate 4773*0Sstevel@tonic-gate /* 4774*0Sstevel@tonic-gate * Clear out all clnt_locks held by all MN disksets. 4775*0Sstevel@tonic-gate * This is only used during a reconfig cycle. 4776*0Sstevel@tonic-gate */ 4777*0Sstevel@tonic-gate /* ARGSUSED */ 4778*0Sstevel@tonic-gate mdrpc_clr_mnsetlock_2_svc( 4779*0Sstevel@tonic-gate mdrpc_null_args *args, 4780*0Sstevel@tonic-gate mdrpc_generic_res *res, 4781*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4782*0Sstevel@tonic-gate ) 4783*0Sstevel@tonic-gate { 4784*0Sstevel@tonic-gate set_t max_sets, setno; 4785*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4786*0Sstevel@tonic-gate int err; 4787*0Sstevel@tonic-gate int op_mode = W_OK; 4788*0Sstevel@tonic-gate mdsetname_t *sp; 4789*0Sstevel@tonic-gate 4790*0Sstevel@tonic-gate /* setup, check permissions */ 4791*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4792*0Sstevel@tonic-gate 4793*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4794*0Sstevel@tonic-gate return (FALSE); 4795*0Sstevel@tonic-gate else if (err != 0) 4796*0Sstevel@tonic-gate return (TRUE); 4797*0Sstevel@tonic-gate 4798*0Sstevel@tonic-gate /* 4799*0Sstevel@tonic-gate * Walk through all possible disksets. 4800*0Sstevel@tonic-gate * For each MN set, delete all keys associated with that set. 4801*0Sstevel@tonic-gate */ 4802*0Sstevel@tonic-gate if ((max_sets = get_max_sets(ep)) == 0) { 4803*0Sstevel@tonic-gate return (TRUE); 4804*0Sstevel@tonic-gate } 4805*0Sstevel@tonic-gate 4806*0Sstevel@tonic-gate /* start walking through all possible disksets */ 4807*0Sstevel@tonic-gate for (setno = 1; setno < max_sets; setno++) { 4808*0Sstevel@tonic-gate if ((sp = metasetnosetname(setno, ep)) == NULL) { 4809*0Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET)) { 4810*0Sstevel@tonic-gate /* No set for this setno - continue */ 4811*0Sstevel@tonic-gate mdclrerror(ep); 4812*0Sstevel@tonic-gate continue; 4813*0Sstevel@tonic-gate } else { 4814*0Sstevel@tonic-gate mde_perror(ep, gettext( 4815*0Sstevel@tonic-gate "Unable to get set %s information"), 4816*0Sstevel@tonic-gate sp->setname); 4817*0Sstevel@tonic-gate mdclrerror(ep); 4818*0Sstevel@tonic-gate continue; 4819*0Sstevel@tonic-gate } 4820*0Sstevel@tonic-gate } 4821*0Sstevel@tonic-gate 4822*0Sstevel@tonic-gate /* only check multi-node disksets */ 4823*0Sstevel@tonic-gate if (!meta_is_mn_set(sp, ep)) { 4824*0Sstevel@tonic-gate mdclrerror(ep); 4825*0Sstevel@tonic-gate continue; 4826*0Sstevel@tonic-gate } 4827*0Sstevel@tonic-gate 4828*0Sstevel@tonic-gate /* Delete keys associated with rpc.metad clnt_lock */ 4829*0Sstevel@tonic-gate del_sk(setno); 4830*0Sstevel@tonic-gate } 4831*0Sstevel@tonic-gate 4832*0Sstevel@tonic-gate *ep = mdnullerror; 4833*0Sstevel@tonic-gate 4834*0Sstevel@tonic-gate err = svc_fini(ep); 4835*0Sstevel@tonic-gate 4836*0Sstevel@tonic-gate return (TRUE); 4837*0Sstevel@tonic-gate } 4838*0Sstevel@tonic-gate 4839*0Sstevel@tonic-gate /* 4840*0Sstevel@tonic-gate * Get drive desc on this host for given setno. 4841*0Sstevel@tonic-gate * This is only used during a reconfig cycle. 4842*0Sstevel@tonic-gate * Returns a drive desc structure for the given mdsetname 4843*0Sstevel@tonic-gate * from this host. 4844*0Sstevel@tonic-gate * 4845*0Sstevel@tonic-gate * Returned drive desc structure is partially filled in with 4846*0Sstevel@tonic-gate * the drive name but is not filled in with any other strings 4847*0Sstevel@tonic-gate * in the drivename structure. 4848*0Sstevel@tonic-gate */ 4849*0Sstevel@tonic-gate bool_t 4850*0Sstevel@tonic-gate mdrpc_getdrivedesc_2_svc( 4851*0Sstevel@tonic-gate mdrpc_sp_2_args *args, 4852*0Sstevel@tonic-gate mdrpc_getdrivedesc_res *res, 4853*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4854*0Sstevel@tonic-gate ) 4855*0Sstevel@tonic-gate { 4856*0Sstevel@tonic-gate md_drive_desc *dd; 4857*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4858*0Sstevel@tonic-gate int err; 4859*0Sstevel@tonic-gate int op_mode = R_OK; 4860*0Sstevel@tonic-gate mdsetname_t *my_sp; 4861*0Sstevel@tonic-gate mdrpc_sp_args *args_r1; 4862*0Sstevel@tonic-gate 4863*0Sstevel@tonic-gate switch (args->rev) { 4864*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 4865*0Sstevel@tonic-gate /* setup, check permissions */ 4866*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4867*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4868*0Sstevel@tonic-gate return (FALSE); 4869*0Sstevel@tonic-gate else if (err != 0) 4870*0Sstevel@tonic-gate return (TRUE); 4871*0Sstevel@tonic-gate 4872*0Sstevel@tonic-gate /* doit */ 4873*0Sstevel@tonic-gate args_r1 = &args->mdrpc_sp_2_args_u.rev1; 4874*0Sstevel@tonic-gate if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL) 4875*0Sstevel@tonic-gate return (TRUE); 4876*0Sstevel@tonic-gate 4877*0Sstevel@tonic-gate dd = metaget_drivedesc(my_sp, 4878*0Sstevel@tonic-gate (MD_BASICNAME_OK | PRINT_FAST), ep); 4879*0Sstevel@tonic-gate 4880*0Sstevel@tonic-gate res->dd = dd_list_dup(dd); 4881*0Sstevel@tonic-gate 4882*0Sstevel@tonic-gate err = svc_fini(ep); 4883*0Sstevel@tonic-gate 4884*0Sstevel@tonic-gate return (TRUE); 4885*0Sstevel@tonic-gate default: 4886*0Sstevel@tonic-gate return (FALSE); 4887*0Sstevel@tonic-gate } 4888*0Sstevel@tonic-gate } 4889*0Sstevel@tonic-gate 4890*0Sstevel@tonic-gate /* 4891*0Sstevel@tonic-gate * Update drive records given list from master during reconfig. 4892*0Sstevel@tonic-gate * Make this node's list match the master's list which may include 4893*0Sstevel@tonic-gate * deleting a drive record that is known by this node and not known 4894*0Sstevel@tonic-gate * by the master node. 4895*0Sstevel@tonic-gate * 4896*0Sstevel@tonic-gate * Sync up the set/node/drive record genids to match the genid 4897*0Sstevel@tonic-gate * passed in the dd structure (all genids in this structure 4898*0Sstevel@tonic-gate * are the same). 4899*0Sstevel@tonic-gate */ 4900*0Sstevel@tonic-gate bool_t 4901*0Sstevel@tonic-gate mdrpc_upd_dr_reconfig_common( 4902*0Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 *args, 4903*0Sstevel@tonic-gate mdrpc_generic_res *res, 4904*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 4905*0Sstevel@tonic-gate ) 4906*0Sstevel@tonic-gate { 4907*0Sstevel@tonic-gate md_error_t *ep = &res->status; 4908*0Sstevel@tonic-gate int err; 4909*0Sstevel@tonic-gate mdsetname_t *local_sp; 4910*0Sstevel@tonic-gate md_set_record *sr; 4911*0Sstevel@tonic-gate md_mnset_record *mnsr; 4912*0Sstevel@tonic-gate md_drive_record *dr, *dr_placeholder = NULL; 4913*0Sstevel@tonic-gate md_drive_desc *dd; 4914*0Sstevel@tonic-gate mddrivename_t *dn, *dn1; 4915*0Sstevel@tonic-gate side_t sideno; 4916*0Sstevel@tonic-gate md_mnnode_record *nrp; 4917*0Sstevel@tonic-gate int op_mode = W_OK; 4918*0Sstevel@tonic-gate int change = 0; 4919*0Sstevel@tonic-gate 4920*0Sstevel@tonic-gate /* setup, check permissions */ 4921*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 4922*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 4923*0Sstevel@tonic-gate return (FALSE); 4924*0Sstevel@tonic-gate else if (err != 0) 4925*0Sstevel@tonic-gate return (TRUE); 4926*0Sstevel@tonic-gate 4927*0Sstevel@tonic-gate if ((local_sp = metasetname(args->sp->setname, ep)) == NULL) 4928*0Sstevel@tonic-gate return (TRUE); 4929*0Sstevel@tonic-gate 4930*0Sstevel@tonic-gate metaflushsetname(local_sp); 4931*0Sstevel@tonic-gate 4932*0Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD) 4933*0Sstevel@tonic-gate return (TRUE); 4934*0Sstevel@tonic-gate 4935*0Sstevel@tonic-gate if ((sr = getsetbyname(args->sp->setname, ep)) == NULL) 4936*0Sstevel@tonic-gate return (TRUE); 4937*0Sstevel@tonic-gate 4938*0Sstevel@tonic-gate if (!(MD_MNSET_REC(sr))) { 4939*0Sstevel@tonic-gate free_sr(sr); 4940*0Sstevel@tonic-gate return (TRUE); 4941*0Sstevel@tonic-gate } 4942*0Sstevel@tonic-gate 4943*0Sstevel@tonic-gate mnsr = (md_mnset_record *)sr; 4944*0Sstevel@tonic-gate /* Setup genid on set and node records */ 4945*0Sstevel@tonic-gate if (args->drivedescs) { 4946*0Sstevel@tonic-gate if (mnsr->sr_genid != args->drivedescs->dd_genid) { 4947*0Sstevel@tonic-gate change = 1; 4948*0Sstevel@tonic-gate mnsr->sr_genid = args->drivedescs->dd_genid; 4949*0Sstevel@tonic-gate } 4950*0Sstevel@tonic-gate nrp = mnsr->sr_nodechain; 4951*0Sstevel@tonic-gate while (nrp) { 4952*0Sstevel@tonic-gate if (nrp->nr_genid != args->drivedescs->dd_genid) { 4953*0Sstevel@tonic-gate change = 1; 4954*0Sstevel@tonic-gate nrp->nr_genid = args->drivedescs->dd_genid; 4955*0Sstevel@tonic-gate } 4956*0Sstevel@tonic-gate nrp = nrp->nr_next; 4957*0Sstevel@tonic-gate } 4958*0Sstevel@tonic-gate } 4959*0Sstevel@tonic-gate for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) { 4960*0Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno, 4961*0Sstevel@tonic-gate dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep); 4962*0Sstevel@tonic-gate if (dn1 == NULL) 4963*0Sstevel@tonic-gate goto out; 4964*0Sstevel@tonic-gate for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) { 4965*0Sstevel@tonic-gate dn = dd->dd_dnp; 4966*0Sstevel@tonic-gate /* Found this node's drive rec to match dd */ 4967*0Sstevel@tonic-gate if (strcmp(dn->cname, dn1->cname) == 0) 4968*0Sstevel@tonic-gate break; 4969*0Sstevel@tonic-gate } 4970*0Sstevel@tonic-gate 4971*0Sstevel@tonic-gate /* 4972*0Sstevel@tonic-gate * If drive found in master's list, make slave match master. 4973*0Sstevel@tonic-gate * If drive not found in master's list, remove drive. 4974*0Sstevel@tonic-gate */ 4975*0Sstevel@tonic-gate if (dd) { 4976*0Sstevel@tonic-gate if ((dr->dr_flags != dd->dd_flags) || 4977*0Sstevel@tonic-gate (dr->dr_genid != dd->dd_genid)) { 4978*0Sstevel@tonic-gate change = 1; 4979*0Sstevel@tonic-gate dr->dr_flags = dd->dd_flags; 4980*0Sstevel@tonic-gate dr->dr_genid = dd->dd_genid; 4981*0Sstevel@tonic-gate } 4982*0Sstevel@tonic-gate } else { 4983*0Sstevel@tonic-gate /* 4984*0Sstevel@tonic-gate * Delete entry from linked list. Need to use 4985*0Sstevel@tonic-gate * dr_placeholder so that dr->dr_next points to 4986*0Sstevel@tonic-gate * the next drive record in the list. 4987*0Sstevel@tonic-gate */ 4988*0Sstevel@tonic-gate if (dr_placeholder == NULL) { 4989*0Sstevel@tonic-gate dr_placeholder = 4990*0Sstevel@tonic-gate Zalloc(sizeof (md_drive_record)); 4991*0Sstevel@tonic-gate } 4992*0Sstevel@tonic-gate dr_placeholder->dr_next = dr->dr_next; 4993*0Sstevel@tonic-gate dr_placeholder->dr_key = dr->dr_key; 4994*0Sstevel@tonic-gate sr_del_drv(sr, dr->dr_selfid); 4995*0Sstevel@tonic-gate (void) del_sideno_sidenm(dr_placeholder->dr_key, 4996*0Sstevel@tonic-gate sideno, ep); 4997*0Sstevel@tonic-gate change = 1; 4998*0Sstevel@tonic-gate dr = dr_placeholder; 4999*0Sstevel@tonic-gate } 5000*0Sstevel@tonic-gate } 5001*0Sstevel@tonic-gate out: 5002*0Sstevel@tonic-gate /* If incore records are correct, don't need to write to disk */ 5003*0Sstevel@tonic-gate if (change) { 5004*0Sstevel@tonic-gate /* Don't increment the genid in commitset */ 5005*0Sstevel@tonic-gate commitset(sr, FALSE, ep); 5006*0Sstevel@tonic-gate } 5007*0Sstevel@tonic-gate free_sr(sr); 5008*0Sstevel@tonic-gate 5009*0Sstevel@tonic-gate err = svc_fini(ep); 5010*0Sstevel@tonic-gate 5011*0Sstevel@tonic-gate if (dr_placeholder != NULL) 5012*0Sstevel@tonic-gate Free(dr_placeholder); 5013*0Sstevel@tonic-gate 5014*0Sstevel@tonic-gate return (TRUE); 5015*0Sstevel@tonic-gate } 5016*0Sstevel@tonic-gate 5017*0Sstevel@tonic-gate /* 5018*0Sstevel@tonic-gate * Version 2 routine to update this node's drive records based on 5019*0Sstevel@tonic-gate * list passed in from master node. 5020*0Sstevel@tonic-gate */ 5021*0Sstevel@tonic-gate bool_t 5022*0Sstevel@tonic-gate mdrpc_upd_dr_reconfig_2_svc( 5023*0Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args *args, 5024*0Sstevel@tonic-gate mdrpc_generic_res *res, 5025*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5026*0Sstevel@tonic-gate ) 5027*0Sstevel@tonic-gate { 5028*0Sstevel@tonic-gate switch (args->rev) { 5029*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 5030*0Sstevel@tonic-gate return (mdrpc_upd_dr_reconfig_common( 5031*0Sstevel@tonic-gate &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp)); 5032*0Sstevel@tonic-gate default: 5033*0Sstevel@tonic-gate return (FALSE); 5034*0Sstevel@tonic-gate } 5035*0Sstevel@tonic-gate } 5036*0Sstevel@tonic-gate 5037*0Sstevel@tonic-gate /* 5038*0Sstevel@tonic-gate * reset mirror owner for mirrors owned by deleted 5039*0Sstevel@tonic-gate * or withdrawn host(s). Hosts being deleted or 5040*0Sstevel@tonic-gate * withdrawn are designated by nodeid since host is 5041*0Sstevel@tonic-gate * already deleted or withdrawn from set and may not 5042*0Sstevel@tonic-gate * be able to translate between a nodename and a nodeid. 5043*0Sstevel@tonic-gate * If an error occurs, ep will be set to that error information. 5044*0Sstevel@tonic-gate */ 5045*0Sstevel@tonic-gate static void 5046*0Sstevel@tonic-gate reset_mirror_owner( 5047*0Sstevel@tonic-gate char *setname, 5048*0Sstevel@tonic-gate int node_c, 5049*0Sstevel@tonic-gate int *node_id, /* Array of node ids */ 5050*0Sstevel@tonic-gate md_error_t *ep 5051*0Sstevel@tonic-gate ) 5052*0Sstevel@tonic-gate { 5053*0Sstevel@tonic-gate mdsetname_t *local_sp; 5054*0Sstevel@tonic-gate int i; 5055*0Sstevel@tonic-gate mdnamelist_t *devnlp = NULL; 5056*0Sstevel@tonic-gate mdnamelist_t *p; 5057*0Sstevel@tonic-gate mdname_t *devnp = NULL; 5058*0Sstevel@tonic-gate md_set_mmown_params_t ownpar_p; 5059*0Sstevel@tonic-gate md_set_mmown_params_t *ownpar = &ownpar_p; 5060*0Sstevel@tonic-gate char *miscname; 5061*0Sstevel@tonic-gate 5062*0Sstevel@tonic-gate if ((local_sp = metasetname(setname, ep)) == NULL) 5063*0Sstevel@tonic-gate return; 5064*0Sstevel@tonic-gate 5065*0Sstevel@tonic-gate /* get a list of all the mirrors for current set */ 5066*0Sstevel@tonic-gate if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0) 5067*0Sstevel@tonic-gate return; 5068*0Sstevel@tonic-gate 5069*0Sstevel@tonic-gate /* for each mirror */ 5070*0Sstevel@tonic-gate for (p = devnlp; (p != NULL); p = p->next) { 5071*0Sstevel@tonic-gate devnp = p->namep; 5072*0Sstevel@tonic-gate 5073*0Sstevel@tonic-gate /* 5074*0Sstevel@tonic-gate * we can only do these for mirrors so make sure we 5075*0Sstevel@tonic-gate * really have a mirror device and not a softpartition 5076*0Sstevel@tonic-gate * imitating one. meta_get_mirror_names seems to think 5077*0Sstevel@tonic-gate * softparts on top of a mirror are mirrors! 5078*0Sstevel@tonic-gate */ 5079*0Sstevel@tonic-gate if ((miscname = metagetmiscname(devnp, ep)) == NULL) 5080*0Sstevel@tonic-gate goto out; 5081*0Sstevel@tonic-gate if (strcmp(miscname, MD_MIRROR) != 0) 5082*0Sstevel@tonic-gate continue; 5083*0Sstevel@tonic-gate 5084*0Sstevel@tonic-gate (void) memset(ownpar, 0, sizeof (*ownpar)); 5085*0Sstevel@tonic-gate ownpar->d.mnum = meta_getminor(devnp->dev); 5086*0Sstevel@tonic-gate MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno); 5087*0Sstevel@tonic-gate 5088*0Sstevel@tonic-gate /* get the current owner id */ 5089*0Sstevel@tonic-gate if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep, 5090*0Sstevel@tonic-gate "MD_MN_GET_MM_OWNER") != 0) { 5091*0Sstevel@tonic-gate mde_perror(ep, gettext( 5092*0Sstevel@tonic-gate "Unable to get mirror owner for %s/d%u"), 5093*0Sstevel@tonic-gate local_sp->setname, 5094*0Sstevel@tonic-gate (unsigned)MD_MIN2UNIT(ownpar->d.mnum)); 5095*0Sstevel@tonic-gate goto out; 5096*0Sstevel@tonic-gate } 5097*0Sstevel@tonic-gate 5098*0Sstevel@tonic-gate if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) { 5099*0Sstevel@tonic-gate mdclrerror(ep); 5100*0Sstevel@tonic-gate continue; 5101*0Sstevel@tonic-gate } 5102*0Sstevel@tonic-gate /* 5103*0Sstevel@tonic-gate * reset owner only if the current owner is 5104*0Sstevel@tonic-gate * in the list of nodes being deleted. 5105*0Sstevel@tonic-gate */ 5106*0Sstevel@tonic-gate for (i = 0; i < node_c; i++) { 5107*0Sstevel@tonic-gate if (ownpar->d.owner == node_id[i]) { 5108*0Sstevel@tonic-gate if (meta_mn_change_owner(&ownpar, 5109*0Sstevel@tonic-gate local_sp->setno, ownpar->d.mnum, 5110*0Sstevel@tonic-gate MD_MN_MIRROR_UNOWNED, 5111*0Sstevel@tonic-gate MD_MN_MM_ALLOW_CHANGE) == -1) { 5112*0Sstevel@tonic-gate mde_perror(ep, gettext( 5113*0Sstevel@tonic-gate "Unable to reset mirror owner for" 5114*0Sstevel@tonic-gate " %s/d%u"), local_sp->setname, 5115*0Sstevel@tonic-gate (unsigned)MD_MIN2UNIT( 5116*0Sstevel@tonic-gate ownpar->d.mnum)); 5117*0Sstevel@tonic-gate goto out; 5118*0Sstevel@tonic-gate } 5119*0Sstevel@tonic-gate break; 5120*0Sstevel@tonic-gate } 5121*0Sstevel@tonic-gate } 5122*0Sstevel@tonic-gate } 5123*0Sstevel@tonic-gate 5124*0Sstevel@tonic-gate out: 5125*0Sstevel@tonic-gate /* cleanup */ 5126*0Sstevel@tonic-gate metafreenamelist(devnlp); 5127*0Sstevel@tonic-gate } 5128*0Sstevel@tonic-gate 5129*0Sstevel@tonic-gate /* 5130*0Sstevel@tonic-gate * Wrapper routine for reset_mirror_owner. 5131*0Sstevel@tonic-gate * Called when hosts are deleted or withdrawn 5132*0Sstevel@tonic-gate * in order to reset any mirror owners that are needed. 5133*0Sstevel@tonic-gate */ 5134*0Sstevel@tonic-gate bool_t 5135*0Sstevel@tonic-gate mdrpc_reset_mirror_owner_common( 5136*0Sstevel@tonic-gate mdrpc_nodeid_args *args, 5137*0Sstevel@tonic-gate mdrpc_generic_res *res, 5138*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5139*0Sstevel@tonic-gate ) 5140*0Sstevel@tonic-gate { 5141*0Sstevel@tonic-gate md_error_t *ep = &res->status; 5142*0Sstevel@tonic-gate int err; 5143*0Sstevel@tonic-gate int op_mode = W_OK; 5144*0Sstevel@tonic-gate 5145*0Sstevel@tonic-gate /* setup, check permissions */ 5146*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 5147*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5148*0Sstevel@tonic-gate return (FALSE); 5149*0Sstevel@tonic-gate else if (err != 0) 5150*0Sstevel@tonic-gate return (TRUE); 5151*0Sstevel@tonic-gate 5152*0Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep)) 5153*0Sstevel@tonic-gate return (TRUE); 5154*0Sstevel@tonic-gate 5155*0Sstevel@tonic-gate /* doit */ 5156*0Sstevel@tonic-gate reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len, 5157*0Sstevel@tonic-gate args->nodeid.nodeid_val, ep); 5158*0Sstevel@tonic-gate 5159*0Sstevel@tonic-gate err = svc_fini(ep); 5160*0Sstevel@tonic-gate 5161*0Sstevel@tonic-gate return (TRUE); 5162*0Sstevel@tonic-gate } 5163*0Sstevel@tonic-gate 5164*0Sstevel@tonic-gate /* 5165*0Sstevel@tonic-gate * RPC service routine to reset the mirror owner for mirrors owned 5166*0Sstevel@tonic-gate * by the given hosts. Typically, the list of given hosts is a list 5167*0Sstevel@tonic-gate * of nodes being deleted or withdrawn from a diskset. 5168*0Sstevel@tonic-gate * The given hosts are designated by nodeid since host may 5169*0Sstevel@tonic-gate * already be deleted or withdrawn from set and may not 5170*0Sstevel@tonic-gate * be able to translate between a nodename and a nodeid. 5171*0Sstevel@tonic-gate */ 5172*0Sstevel@tonic-gate bool_t 5173*0Sstevel@tonic-gate mdrpc_reset_mirror_owner_2_svc( 5174*0Sstevel@tonic-gate mdrpc_nodeid_2_args *args, 5175*0Sstevel@tonic-gate mdrpc_generic_res *res, 5176*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5177*0Sstevel@tonic-gate ) 5178*0Sstevel@tonic-gate { 5179*0Sstevel@tonic-gate switch (args->rev) { 5180*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 5181*0Sstevel@tonic-gate return (mdrpc_reset_mirror_owner_common( 5182*0Sstevel@tonic-gate &args->mdrpc_nodeid_2_args_u.rev1, res, 5183*0Sstevel@tonic-gate rqstp)); 5184*0Sstevel@tonic-gate default: 5185*0Sstevel@tonic-gate return (FALSE); 5186*0Sstevel@tonic-gate } 5187*0Sstevel@tonic-gate } 5188*0Sstevel@tonic-gate 5189*0Sstevel@tonic-gate /* 5190*0Sstevel@tonic-gate * Call routines to suspend and resume I/O for the given diskset(s). 5191*0Sstevel@tonic-gate * Called during reconfig cycle. 5192*0Sstevel@tonic-gate * Diskset of 0 represents all MN disksets. 5193*0Sstevel@tonic-gate */ 5194*0Sstevel@tonic-gate bool_t 5195*0Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_svc( 5196*0Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_args *args, 5197*0Sstevel@tonic-gate mdrpc_generic_res *res, 5198*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5199*0Sstevel@tonic-gate ) 5200*0Sstevel@tonic-gate { 5201*0Sstevel@tonic-gate mdrpc_mn_susp_res_io_args *args_sr; 5202*0Sstevel@tonic-gate md_error_t *ep = &res->status; 5203*0Sstevel@tonic-gate int err; 5204*0Sstevel@tonic-gate int op_mode = R_OK; 5205*0Sstevel@tonic-gate 5206*0Sstevel@tonic-gate switch (args->rev) { 5207*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 5208*0Sstevel@tonic-gate /* setup, check permissions */ 5209*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 5210*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5211*0Sstevel@tonic-gate return (FALSE); 5212*0Sstevel@tonic-gate else if (err != 0) 5213*0Sstevel@tonic-gate return (TRUE); 5214*0Sstevel@tonic-gate 5215*0Sstevel@tonic-gate args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1); 5216*0Sstevel@tonic-gate switch (args_sr->susp_res_cmd) { 5217*0Sstevel@tonic-gate case MN_SUSP_IO: 5218*0Sstevel@tonic-gate (void) (metaioctl(MD_MN_SUSPEND_SET, 5219*0Sstevel@tonic-gate &args_sr->susp_res_setno, ep, NULL)); 5220*0Sstevel@tonic-gate break; 5221*0Sstevel@tonic-gate case MN_RES_IO: 5222*0Sstevel@tonic-gate (void) (metaioctl(MD_MN_RESUME_SET, 5223*0Sstevel@tonic-gate &args_sr->susp_res_setno, ep, NULL)); 5224*0Sstevel@tonic-gate break; 5225*0Sstevel@tonic-gate } 5226*0Sstevel@tonic-gate err = svc_fini(ep); 5227*0Sstevel@tonic-gate return (TRUE); 5228*0Sstevel@tonic-gate 5229*0Sstevel@tonic-gate default: 5230*0Sstevel@tonic-gate return (FALSE); 5231*0Sstevel@tonic-gate } 5232*0Sstevel@tonic-gate } 5233*0Sstevel@tonic-gate 5234*0Sstevel@tonic-gate /* 5235*0Sstevel@tonic-gate * Resnarf a set after it has been imported 5236*0Sstevel@tonic-gate */ 5237*0Sstevel@tonic-gate bool_t 5238*0Sstevel@tonic-gate mdrpc_resnarf_set_2_svc( 5239*0Sstevel@tonic-gate mdrpc_setno_2_args *args, 5240*0Sstevel@tonic-gate mdrpc_generic_res *res, 5241*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5242*0Sstevel@tonic-gate ) 5243*0Sstevel@tonic-gate { 5244*0Sstevel@tonic-gate mdrpc_setno_args *setno_args; 5245*0Sstevel@tonic-gate md_error_t *ep = &res->status; 5246*0Sstevel@tonic-gate int err; 5247*0Sstevel@tonic-gate int op_mode = R_OK; 5248*0Sstevel@tonic-gate 5249*0Sstevel@tonic-gate switch (args->rev) { 5250*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 5251*0Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1; 5252*0Sstevel@tonic-gate break; 5253*0Sstevel@tonic-gate default: 5254*0Sstevel@tonic-gate return (FALSE); 5255*0Sstevel@tonic-gate } 5256*0Sstevel@tonic-gate 5257*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 5258*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5259*0Sstevel@tonic-gate return (FALSE); 5260*0Sstevel@tonic-gate else if (err != 0) 5261*0Sstevel@tonic-gate return (TRUE); 5262*0Sstevel@tonic-gate 5263*0Sstevel@tonic-gate /* do it */ 5264*0Sstevel@tonic-gate if (resnarf_set(setno_args->setno, ep) < 0) 5265*0Sstevel@tonic-gate return (FALSE); 5266*0Sstevel@tonic-gate 5267*0Sstevel@tonic-gate err = svc_fini(ep); 5268*0Sstevel@tonic-gate return (TRUE); 5269*0Sstevel@tonic-gate } 5270*0Sstevel@tonic-gate 5271*0Sstevel@tonic-gate /* 5272*0Sstevel@tonic-gate * Creates a resync thread. 5273*0Sstevel@tonic-gate * Always returns true. 5274*0Sstevel@tonic-gate */ 5275*0Sstevel@tonic-gate bool_t 5276*0Sstevel@tonic-gate mdrpc_mn_mirror_resync_all_2_svc( 5277*0Sstevel@tonic-gate mdrpc_setno_2_args *args, 5278*0Sstevel@tonic-gate mdrpc_generic_res *res, 5279*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5280*0Sstevel@tonic-gate ) 5281*0Sstevel@tonic-gate { 5282*0Sstevel@tonic-gate md_error_t *ep = &res->status; 5283*0Sstevel@tonic-gate mdrpc_setno_args *setno_args; 5284*0Sstevel@tonic-gate int err; 5285*0Sstevel@tonic-gate int op_mode = R_OK; 5286*0Sstevel@tonic-gate 5287*0Sstevel@tonic-gate switch (args->rev) { 5288*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 5289*0Sstevel@tonic-gate /* setup, check permissions */ 5290*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 5291*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5292*0Sstevel@tonic-gate return (FALSE); 5293*0Sstevel@tonic-gate else if (err != 0) 5294*0Sstevel@tonic-gate return (TRUE); 5295*0Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1; 5296*0Sstevel@tonic-gate 5297*0Sstevel@tonic-gate /* 5298*0Sstevel@tonic-gate * Need to invoke a metasync on a node newly added to a set. 5299*0Sstevel@tonic-gate */ 5300*0Sstevel@tonic-gate meta_mn_mirror_resync_all(&(setno_args->setno)); 5301*0Sstevel@tonic-gate 5302*0Sstevel@tonic-gate err = svc_fini(ep); 5303*0Sstevel@tonic-gate return (TRUE); 5304*0Sstevel@tonic-gate 5305*0Sstevel@tonic-gate default: 5306*0Sstevel@tonic-gate return (FALSE); 5307*0Sstevel@tonic-gate } 5308*0Sstevel@tonic-gate } 5309*0Sstevel@tonic-gate 5310*0Sstevel@tonic-gate /* 5311*0Sstevel@tonic-gate * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(), 5312*0Sstevel@tonic-gate * which forks a daemon process to perform this action. 5313*0Sstevel@tonic-gate * Always returns true. 5314*0Sstevel@tonic-gate */ 5315*0Sstevel@tonic-gate bool_t 5316*0Sstevel@tonic-gate mdrpc_mn_sp_update_abr_2_svc( 5317*0Sstevel@tonic-gate mdrpc_setno_2_args *args, 5318*0Sstevel@tonic-gate mdrpc_generic_res *res, 5319*0Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */ 5320*0Sstevel@tonic-gate ) 5321*0Sstevel@tonic-gate { 5322*0Sstevel@tonic-gate md_error_t *ep = &res->status; 5323*0Sstevel@tonic-gate mdrpc_setno_args *setno_args; 5324*0Sstevel@tonic-gate int err; 5325*0Sstevel@tonic-gate int op_mode = R_OK; 5326*0Sstevel@tonic-gate 5327*0Sstevel@tonic-gate switch (args->rev) { 5328*0Sstevel@tonic-gate case MD_METAD_ARGS_REV_1: 5329*0Sstevel@tonic-gate /* setup, check permissions */ 5330*0Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res)); 5331*0Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0) 5332*0Sstevel@tonic-gate return (FALSE); 5333*0Sstevel@tonic-gate else if (err != 0) 5334*0Sstevel@tonic-gate return (TRUE); 5335*0Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1; 5336*0Sstevel@tonic-gate 5337*0Sstevel@tonic-gate meta_mn_sp_update_abr(&(setno_args->setno)); 5338*0Sstevel@tonic-gate 5339*0Sstevel@tonic-gate err = svc_fini(ep); 5340*0Sstevel@tonic-gate return (TRUE); 5341*0Sstevel@tonic-gate 5342*0Sstevel@tonic-gate default: 5343*0Sstevel@tonic-gate return (FALSE); 5344*0Sstevel@tonic-gate } 5345*0Sstevel@tonic-gate } 5346