10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51320Srd117015 * Common Development and Distribution License (the "License").
61320Srd117015 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*11053SSurya.Prakki@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include "metad_local.h"
270Sstevel@tonic-gate #include <metad.h>
280Sstevel@tonic-gate #include <sys/lvm/md_mddb.h>
290Sstevel@tonic-gate #include <sdssc.h>
300Sstevel@tonic-gate #include <sys/lvm/md_mirror.h>
310Sstevel@tonic-gate #include <syslog.h>
320Sstevel@tonic-gate
330Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h>
340Sstevel@tonic-gate #include <sys/sysevent/svm.h>
350Sstevel@tonic-gate #include <thread.h>
360Sstevel@tonic-gate
370Sstevel@tonic-gate #define MDDOORS "/usr/lib/lvm/mddoors"
380Sstevel@tonic-gate
390Sstevel@tonic-gate /*
400Sstevel@tonic-gate * rpc.metad daemon
410Sstevel@tonic-gate *
420Sstevel@tonic-gate * The rpc.metad deamon supports two versions of the svm rpc calls - version 1
430Sstevel@tonic-gate * and version 2. The over-the-wire structures sent as part of these rpc calls
440Sstevel@tonic-gate * are also versioned - version 1 and version 2 exist. It must be noted that
450Sstevel@tonic-gate * the version 2 structures have sub-versions or revisions as well. The
460Sstevel@tonic-gate * revisions in the version 2 structures allow for flexiblility in changing
470Sstevel@tonic-gate * over the wire structures without creating a new version of the svm rpc
480Sstevel@tonic-gate * calls. No changes may be made to the version 1 routines or structures used
490Sstevel@tonic-gate * by these routines.
500Sstevel@tonic-gate *
510Sstevel@tonic-gate * If, for example, the version 2 mdrpc_devinfo_args over the wire structure
520Sstevel@tonic-gate * (mdrpc_devinfo_2_args*) is changed then the structure change must be
530Sstevel@tonic-gate * accompanied by the following:
540Sstevel@tonic-gate *
550Sstevel@tonic-gate * Header file changes:
560Sstevel@tonic-gate * . May need to introduce a new structure revision MD_METAD_ARGS_REV_X, where
570Sstevel@tonic-gate * X is the revision number.
580Sstevel@tonic-gate * . Create mdrpc_devinfo_2_args_rX, where X is the new revision of the
590Sstevel@tonic-gate * structure.
600Sstevel@tonic-gate * . Add a switch statement in mdrpc_devinfo_2_args.
610Sstevel@tonic-gate *
620Sstevel@tonic-gate * rpc.metad changes:
630Sstevel@tonic-gate * . Check for the structure revision in the appropriate mdrpc_devinfo_svc
640Sstevel@tonic-gate * routine (mdrpc_devinfo_2_svc).
650Sstevel@tonic-gate *
660Sstevel@tonic-gate * libmeta changes:
670Sstevel@tonic-gate * . In the libmeta code that makes the mdrpc_devinfo rpc call, the arguments
680Sstevel@tonic-gate * being passed as part of this call (namely mdrpc_devinfo_Y_args) must have
690Sstevel@tonic-gate * the revision field and associated structure populated correctly.
700Sstevel@tonic-gate */
710Sstevel@tonic-gate
720Sstevel@tonic-gate static md_setkey_t *my_svc_sk = NULL;
730Sstevel@tonic-gate
740Sstevel@tonic-gate /*
750Sstevel@tonic-gate * Add namespace entry to local mddb for using given sideno, key
760Sstevel@tonic-gate * and names.
770Sstevel@tonic-gate */
780Sstevel@tonic-gate static int
add_sideno_sidenm(mdsidenames_t * sidenms,mdkey_t local_key,side_t sideno,md_set_desc * sd,md_error_t * ep)790Sstevel@tonic-gate add_sideno_sidenm(
800Sstevel@tonic-gate mdsidenames_t *sidenms,
810Sstevel@tonic-gate mdkey_t local_key,
820Sstevel@tonic-gate side_t sideno,
830Sstevel@tonic-gate md_set_desc *sd, /* Only used with Version 2 */
840Sstevel@tonic-gate md_error_t *ep
850Sstevel@tonic-gate )
860Sstevel@tonic-gate {
870Sstevel@tonic-gate mdsidenames_t *sn;
880Sstevel@tonic-gate mdsetname_t *local_sp;
890Sstevel@tonic-gate char *nm;
900Sstevel@tonic-gate
910Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
920Sstevel@tonic-gate return (-1);
930Sstevel@tonic-gate
940Sstevel@tonic-gate for (sn = sidenms; sn != NULL; sn = sn->next)
950Sstevel@tonic-gate if (sn->sideno == sideno)
960Sstevel@tonic-gate break;
970Sstevel@tonic-gate
980Sstevel@tonic-gate assert(sn != NULL);
990Sstevel@tonic-gate
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate * SKEW will be used on the traditional diskset despite of the
1030Sstevel@tonic-gate * rpc version. SKEW is not used on the multinode diskset
1040Sstevel@tonic-gate */
1050Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
1060Sstevel@tonic-gate nm = meta_getnmbykey(MD_LOCAL_SET, sideno, local_key, ep);
1070Sstevel@tonic-gate } else {
1080Sstevel@tonic-gate nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW, local_key, ep);
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate if (nm == NULL) {
1120Sstevel@tonic-gate if (! mdisok(ep)) {
1130Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
1140Sstevel@tonic-gate return (-1);
1150Sstevel@tonic-gate mdclrerror(ep);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate /*
1190Sstevel@tonic-gate * Ignore returned key from add_name, only care about errs
1200Sstevel@tonic-gate *
1210Sstevel@tonic-gate * SKEW is used for a regular diskset since sideno could
1220Sstevel@tonic-gate * have a value of 0 in that diskset type. add_name is
1230Sstevel@tonic-gate * writing to the local mddb and a sideno of 0 in the
1240Sstevel@tonic-gate * local mddb is reserved for non-diskset names.
1250Sstevel@tonic-gate * SKEW is added to the sideno in the local mddb so that
1260Sstevel@tonic-gate * the sideno for the diskset will never be 0.
1270Sstevel@tonic-gate *
1280Sstevel@tonic-gate * In a MNdiskset, the sideno will never be 0 (by design).
1290Sstevel@tonic-gate * So, no SKEW is needed when writing to the local mddb.
1300Sstevel@tonic-gate */
1310Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
1320Sstevel@tonic-gate if (add_name(local_sp, sideno, local_key,
1331945Sjeanm sn->dname, sn->mnum, sn->cname, NULL, NULL,
1341945Sjeanm ep) == -1)
1350Sstevel@tonic-gate return (-1);
1360Sstevel@tonic-gate } else {
1370Sstevel@tonic-gate if (add_name(local_sp, sideno+SKEW, local_key,
1381945Sjeanm sn->dname, sn->mnum, sn->cname, NULL, NULL,
1391945Sjeanm ep) == -1)
1400Sstevel@tonic-gate return (-1);
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate } else
1430Sstevel@tonic-gate Free(nm);
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate return (0);
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate /*
1490Sstevel@tonic-gate * Delete sidename entry from local set using key and sideno.
1500Sstevel@tonic-gate */
1510Sstevel@tonic-gate static int
del_sideno_sidenm(mdkey_t sidekey,side_t sideno,md_error_t * ep)1520Sstevel@tonic-gate del_sideno_sidenm(
1530Sstevel@tonic-gate mdkey_t sidekey,
1540Sstevel@tonic-gate side_t sideno,
1550Sstevel@tonic-gate md_error_t *ep
1560Sstevel@tonic-gate )
1570Sstevel@tonic-gate {
1580Sstevel@tonic-gate mdsetname_t *local_sp;
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1610Sstevel@tonic-gate return (-1);
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate if (del_name(local_sp, sideno, sidekey, ep) == -1)
1640Sstevel@tonic-gate mdclrerror(ep); /* ignore errs */
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate return (0);
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate /*
1710Sstevel@tonic-gate * Add namespace entries to local mddb for drives in drive list in
1720Sstevel@tonic-gate * set descriptor.
1730Sstevel@tonic-gate *
1740Sstevel@tonic-gate * If a MNset and if this host is being added to the set (this host
1750Sstevel@tonic-gate * is in the node_v list), add a namespace entry for the name of
1760Sstevel@tonic-gate * each drive using this host's sideno.
1770Sstevel@tonic-gate *
1780Sstevel@tonic-gate * If not a MNset, add namespace entries for all the new hosts being
1790Sstevel@tonic-gate * added to this set (list in node_v).
1800Sstevel@tonic-gate */
1810Sstevel@tonic-gate static void
add_drv_sidenms(char * hostname,mdsetname_t * sp,md_set_desc * sd,int node_c,char ** node_v,md_error_t * ep)1820Sstevel@tonic-gate add_drv_sidenms(
1830Sstevel@tonic-gate char *hostname,
1840Sstevel@tonic-gate mdsetname_t *sp,
1850Sstevel@tonic-gate md_set_desc *sd,
1860Sstevel@tonic-gate int node_c,
1870Sstevel@tonic-gate char **node_v,
1880Sstevel@tonic-gate md_error_t *ep
1890Sstevel@tonic-gate )
1900Sstevel@tonic-gate {
1910Sstevel@tonic-gate mdsetname_t *my_sp;
1920Sstevel@tonic-gate md_drive_desc *dd, *my_dd, *p, *q;
1930Sstevel@tonic-gate mddrivename_t *dn, *my_dn;
1940Sstevel@tonic-gate int i;
1950Sstevel@tonic-gate side_t sideno = 0, mysideno = 0;
1960Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
1970Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
1980Sstevel@tonic-gate int devid_same = -1;
1990Sstevel@tonic-gate int using_devid = 0;
2000Sstevel@tonic-gate md_mnnode_desc *nd;
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate assert(sd->sd_drvs != NULL);
2030Sstevel@tonic-gate dd = sd->sd_drvs;
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate if (dd->dd_dnp == NULL)
2060Sstevel@tonic-gate return;
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate if ((my_sp = metasetname(sp->setname, ep)) == NULL)
2090Sstevel@tonic-gate return;
2100Sstevel@tonic-gate metaflushsetname(my_sp);
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate /* If a MN diskset */
2130Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
2140Sstevel@tonic-gate /* Find sideno associated with RPC client. */
2150Sstevel@tonic-gate nd = sd->sd_nodelist;
2160Sstevel@tonic-gate while (nd) {
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate if (strcmp(nd->nd_nodename, hostname) == 0) {
2190Sstevel@tonic-gate sideno = nd->nd_nodeid;
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate /* While looping, find my side num as well */
2230Sstevel@tonic-gate if (strcmp(nd->nd_nodename, mynode()) == 0) {
2240Sstevel@tonic-gate mysideno = nd->nd_nodeid;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate if ((sideno) && (mysideno)) {
2280Sstevel@tonic-gate break;
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate nd = nd->nd_next;
2310Sstevel@tonic-gate }
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate if (!sideno) {
2340Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE,
2350Sstevel@tonic-gate sp->setno, hostname, NULL, sp->setname);
2360Sstevel@tonic-gate return;
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate } else {
2390Sstevel@tonic-gate /*
2400Sstevel@tonic-gate * if not a MN diskset
2410Sstevel@tonic-gate * do action for traditional diskset.
2420Sstevel@tonic-gate * despite of the rpc version
2430Sstevel@tonic-gate */
2440Sstevel@tonic-gate for (sideno = 0; sideno < MD_MAXSIDES; sideno++) {
2450Sstevel@tonic-gate /* Skip empty slots */
2460Sstevel@tonic-gate if (sd->sd_nodes[sideno][0] == '\0')
2470Sstevel@tonic-gate continue;
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate if (strcmp(hostname, sd->sd_nodes[sideno]) == 0)
2500Sstevel@tonic-gate break;
2510Sstevel@tonic-gate }
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate if (sideno == MD_MAXSIDES) {
2540Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno,
2550Sstevel@tonic-gate hostname, NULL, sp->setname);
2560Sstevel@tonic-gate return;
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate if ((my_dd = metaget_drivedesc_sideno(my_sp, sideno, MD_BASICNAME_OK,
2600Sstevel@tonic-gate ep)) == NULL) {
2610Sstevel@tonic-gate if (! mdisok(ep))
2620Sstevel@tonic-gate return;
2630Sstevel@tonic-gate /* we are supposed to have drives!!!! */
2640Sstevel@tonic-gate assert(0);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate /*
2680Sstevel@tonic-gate * The system is either all devid or all
2690Sstevel@tonic-gate * non-devid so we look at the first item
2700Sstevel@tonic-gate * in the list to determine if we're using devids or not.
2710Sstevel@tonic-gate * We also check to make sure it's not a multi-node diskset.
2720Sstevel@tonic-gate * If it is, we don't use devid's.
2730Sstevel@tonic-gate *
2740Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
2750Sstevel@tonic-gate * points to a '' string of devid. We need to check this
2760Sstevel@tonic-gate * before set the using_devid.
2770Sstevel@tonic-gate */
2780Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
2790Sstevel@tonic-gate (!(MD_MNSET_DESC(sd))))
2800Sstevel@tonic-gate using_devid = 1;
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /*
2830Sstevel@tonic-gate * We have to match-up the dd that were passed
2840Sstevel@tonic-gate * across the wire to the dd we have in this daemon.
2850Sstevel@tonic-gate * That way we can pick up the new sidenames that were
2860Sstevel@tonic-gate * passed to us and match them up with the local namespace key.
2870Sstevel@tonic-gate * Only we have the key, this cannot be passed in.
2880Sstevel@tonic-gate */
2890Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
2900Sstevel@tonic-gate dn = p->dd_dnp;
2910Sstevel@tonic-gate devid_remote = NULL;
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
2940Sstevel@tonic-gate using_devid) {
2950Sstevel@tonic-gate /*
2960Sstevel@tonic-gate * We have a devid so use it
2970Sstevel@tonic-gate */
2980Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
3020Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
3030Sstevel@tonic-gate /* something went really wrong. Can't process */
3040Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
3050Sstevel@tonic-gate hostname, dn->cname, sp->setname);
3060Sstevel@tonic-gate return;
3070Sstevel@tonic-gate }
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate for (q = my_dd; q != NULL; q = q->dd_next) {
3100Sstevel@tonic-gate my_dn = q->dd_dnp;
3110Sstevel@tonic-gate devid_same = -1;
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate if (my_dn->devid != NULL && using_devid) {
3140Sstevel@tonic-gate if (devid_str_decode(my_dn->devid,
3150Sstevel@tonic-gate &devid_local, NULL) == 0) {
3160Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
3170Sstevel@tonic-gate devid_local);
3180Sstevel@tonic-gate devid_free(devid_local);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate if (using_devid && devid_same == 0) {
3230Sstevel@tonic-gate break;
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate if (!using_devid &&
3270Sstevel@tonic-gate strcmp(my_dn->cname, dn->cname) == 0)
3280Sstevel@tonic-gate break;
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate if (devid_remote) {
3320Sstevel@tonic-gate devid_free(devid_remote);
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate assert(q != NULL);
3350Sstevel@tonic-gate assert(my_dn->side_names_key != MD_KEYWILD);
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
3380Sstevel@tonic-gate /*
3390Sstevel@tonic-gate * Add the side names to the local db
3400Sstevel@tonic-gate * for this node only.
3410Sstevel@tonic-gate */
3420Sstevel@tonic-gate if (add_sideno_sidenm(dn->side_names,
3430Sstevel@tonic-gate my_dn->side_names_key, mysideno, sd, ep))
3440Sstevel@tonic-gate return;
3450Sstevel@tonic-gate /*
3460Sstevel@tonic-gate * Sidenames for this drive were added
3470Sstevel@tonic-gate * to this host during the routine adddrvs.
3480Sstevel@tonic-gate * The sidenames that were added are the
3490Sstevel@tonic-gate * names associated with this drive on
3500Sstevel@tonic-gate * each of the hosts that were previously
3510Sstevel@tonic-gate * in the set.
3520Sstevel@tonic-gate * When the sidename for this drive on
3530Sstevel@tonic-gate * this host is added, the sidename
3540Sstevel@tonic-gate * from the host executing the command
3550Sstevel@tonic-gate * (not this host) is sent to this host.
3560Sstevel@tonic-gate * This host finds the originating host's
3570Sstevel@tonic-gate * sidename and can then determine this
3580Sstevel@tonic-gate * host's sidename.
3590Sstevel@tonic-gate * The sidenames from the other hosts serve
3600Sstevel@tonic-gate * only as temporary sidenames until this
3610Sstevel@tonic-gate * host's sidename can be added.
3620Sstevel@tonic-gate * In order to conserve space in the
3630Sstevel@tonic-gate * local mddb, the code now deletes the
3640Sstevel@tonic-gate * temporary sidenames added during adddrvs.
3650Sstevel@tonic-gate * When finished, only the sidename for this
3660Sstevel@tonic-gate * node should be left.
3670Sstevel@tonic-gate * Ignore any errors during this process since
3680Sstevel@tonic-gate * a failure to delete the extraneous
3690Sstevel@tonic-gate * sidenames shouldn't cause this routine
3700Sstevel@tonic-gate * to fail (in case that sidename didn't exist).
3710Sstevel@tonic-gate */
3720Sstevel@tonic-gate nd = sd->sd_nodelist;
3730Sstevel@tonic-gate while (nd) {
3740Sstevel@tonic-gate if (nd->nd_nodeid != mysideno) {
3750Sstevel@tonic-gate if (del_sideno_sidenm(
3760Sstevel@tonic-gate dn->side_names_key,
3770Sstevel@tonic-gate nd->nd_nodeid, ep) == -1)
3780Sstevel@tonic-gate mdclrerror(ep);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate nd = nd->nd_next;
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate } else {
3830Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
3840Sstevel@tonic-gate /* Skip empty slots */
3850Sstevel@tonic-gate if (sd->sd_nodes[i][0] == '\0')
3860Sstevel@tonic-gate continue;
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate /* Skip nodes not being added */
3890Sstevel@tonic-gate if (! strinlst(sd->sd_nodes[i],
3907084Sachimm node_c, node_v))
3910Sstevel@tonic-gate continue;
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate /* Add the per side names to local db */
3940Sstevel@tonic-gate if (add_sideno_sidenm(dn->side_names,
3950Sstevel@tonic-gate my_dn->side_names_key, i, sd, ep))
3960Sstevel@tonic-gate return;
3970Sstevel@tonic-gate }
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate /* ARGSUSED */
4030Sstevel@tonic-gate bool_t
mdrpc_flush_internal_common(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4040Sstevel@tonic-gate mdrpc_flush_internal_common(mdrpc_null_args *args, mdrpc_generic_res *res,
4050Sstevel@tonic-gate struct svc_req *rqstp)
4060Sstevel@tonic-gate {
4070Sstevel@tonic-gate md_error_t *ep = &res->status;
4087084Sachimm int err, op_mode = W_OK;
4090Sstevel@tonic-gate
4107159Sabalfour (void) memset(res, 0, sizeof (*res));
4110Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4120Sstevel@tonic-gate return (FALSE);
4130Sstevel@tonic-gate else if (err != 0)
4140Sstevel@tonic-gate return (TRUE);
4150Sstevel@tonic-gate
4160Sstevel@tonic-gate metaflushnames(1);
4170Sstevel@tonic-gate
4180Sstevel@tonic-gate err = svc_fini(ep);
4190Sstevel@tonic-gate
4200Sstevel@tonic-gate return (TRUE);
4210Sstevel@tonic-gate }
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate bool_t
mdrpc_flush_internal_1_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4240Sstevel@tonic-gate mdrpc_flush_internal_1_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
4250Sstevel@tonic-gate struct svc_req *rqstp)
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate return (mdrpc_flush_internal_common(args, res, rqstp));
4280Sstevel@tonic-gate }
4290Sstevel@tonic-gate
4300Sstevel@tonic-gate bool_t
mdrpc_flush_internal_2_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4310Sstevel@tonic-gate mdrpc_flush_internal_2_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
4320Sstevel@tonic-gate struct svc_req *rqstp)
4330Sstevel@tonic-gate {
4340Sstevel@tonic-gate return (mdrpc_flush_internal_common(args, res, rqstp));
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate /*
4380Sstevel@tonic-gate * add 1 or more namespace entries per drive record.
4390Sstevel@tonic-gate * (into the local namespace)
4400Sstevel@tonic-gate */
4410Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_common(mdrpc_drv_sidenm_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)4420Sstevel@tonic-gate mdrpc_add_drv_sidenms_common(
4430Sstevel@tonic-gate mdrpc_drv_sidenm_2_args_r1 *args,
4440Sstevel@tonic-gate mdrpc_generic_res *res,
4450Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
4460Sstevel@tonic-gate )
4470Sstevel@tonic-gate {
4480Sstevel@tonic-gate md_error_t *ep = &res->status;
4490Sstevel@tonic-gate int err;
4500Sstevel@tonic-gate int op_mode = W_OK;
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate /* setup, check permissions */
4530Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4540Sstevel@tonic-gate return (FALSE);
4550Sstevel@tonic-gate else if (err != 0)
4560Sstevel@tonic-gate return (TRUE);
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
4590Sstevel@tonic-gate return (TRUE);
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate /* doit */
4620Sstevel@tonic-gate add_drv_sidenms(args->hostname, args->sp, args->sd,
4630Sstevel@tonic-gate args->node_v.node_v_len, args->node_v.node_v_val, ep);
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate err = svc_fini(ep);
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate return (TRUE);
4680Sstevel@tonic-gate }
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate /*
4710Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
4720Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
4730Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
4740Sstevel@tonic-gate */
4750Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_1_svc(mdrpc_drv_sidenm_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4760Sstevel@tonic-gate mdrpc_add_drv_sidenms_1_svc(
4770Sstevel@tonic-gate mdrpc_drv_sidenm_args *args,
4780Sstevel@tonic-gate mdrpc_generic_res *res,
4790Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
4800Sstevel@tonic-gate )
4810Sstevel@tonic-gate {
4820Sstevel@tonic-gate bool_t retval;
4830Sstevel@tonic-gate mdrpc_drv_sidenm_2_args_r1 v2_args;
4840Sstevel@tonic-gate int i, j;
4850Sstevel@tonic-gate
4860Sstevel@tonic-gate /* allocate memory */
4870Sstevel@tonic-gate v2_args.sd = Zalloc(sizeof (md_set_desc));
4880Sstevel@tonic-gate alloc_newdrvdesc(args->sd->sd_drvs, &v2_args.sd->sd_drvs);
4897159Sabalfour (void) memset(res, 0, sizeof (*res));
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate /* build args */
4920Sstevel@tonic-gate v2_args.hostname = args->hostname;
4930Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
4940Sstevel@tonic-gate v2_args.sp = args->sp;
4950Sstevel@tonic-gate /* set descriptor */
4960Sstevel@tonic-gate v2_args.sd->sd_ctime = args->sd->sd_ctime;
4970Sstevel@tonic-gate v2_args.sd->sd_genid = args->sd->sd_genid;
4980Sstevel@tonic-gate v2_args.sd->sd_setno = args->sd->sd_setno;
4990Sstevel@tonic-gate v2_args.sd->sd_flags = args->sd->sd_flags;
5000Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
5010Sstevel@tonic-gate v2_args.sd->sd_isown[i] = args->sd->sd_isown[i];
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j++)
5040Sstevel@tonic-gate v2_args.sd->sd_nodes[i][j] =
5050Sstevel@tonic-gate args->sd->sd_nodes[i][j];
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate v2_args.sd->sd_med = args->sd->sd_med;
5080Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
5090Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->sd->sd_drvs, v2_args.sd->sd_drvs);
5100Sstevel@tonic-gate v2_args.node_v.node_v_len = args->node_v.node_v_len;
5110Sstevel@tonic-gate v2_args.node_v.node_v_val = args->node_v.node_v_val;
5120Sstevel@tonic-gate
5130Sstevel@tonic-gate retval = mdrpc_add_drv_sidenms_common(&v2_args, res, rqstp);
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate free(v2_args.sd);
5160Sstevel@tonic-gate free_newdrvdesc(v2_args.sd->sd_drvs);
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate return (retval);
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_2_svc(mdrpc_drv_sidenm_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)5220Sstevel@tonic-gate mdrpc_add_drv_sidenms_2_svc(
5230Sstevel@tonic-gate mdrpc_drv_sidenm_2_args *args,
5240Sstevel@tonic-gate mdrpc_generic_res *res,
5250Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
5260Sstevel@tonic-gate )
5270Sstevel@tonic-gate {
5287159Sabalfour (void) memset(res, 0, sizeof (*res));
5290Sstevel@tonic-gate switch (args->rev) {
5307084Sachimm case MD_METAD_ARGS_REV_1:
5310Sstevel@tonic-gate return (mdrpc_add_drv_sidenms_common(
5320Sstevel@tonic-gate &args->mdrpc_drv_sidenm_2_args_u.rev1, res, rqstp));
5337084Sachimm default:
5340Sstevel@tonic-gate return (FALSE);
5350Sstevel@tonic-gate }
5360Sstevel@tonic-gate }
5370Sstevel@tonic-gate
5380Sstevel@tonic-gate static int
add_sidenamelist(mddrivename_t * dn,side_t thisside,md_set_record * sr,md_error_t * ep)5390Sstevel@tonic-gate add_sidenamelist(
5400Sstevel@tonic-gate mddrivename_t *dn,
5410Sstevel@tonic-gate side_t thisside,
5420Sstevel@tonic-gate md_set_record *sr, /* used by RPC version 2 */
5430Sstevel@tonic-gate md_error_t *ep
5440Sstevel@tonic-gate )
5450Sstevel@tonic-gate {
5460Sstevel@tonic-gate mdsidenames_t *sn;
5470Sstevel@tonic-gate mdkey_t key;
5480Sstevel@tonic-gate int err;
5490Sstevel@tonic-gate mdsetname_t *local_sp;
5500Sstevel@tonic-gate md_mnset_record *mnsr;
5510Sstevel@tonic-gate md_mnnode_record *nr;
5520Sstevel@tonic-gate uint_t nodeid = 0;
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
5550Sstevel@tonic-gate return (-1);
5560Sstevel@tonic-gate
5570Sstevel@tonic-gate key = MD_KEYWILD;
5580Sstevel@tonic-gate
5590Sstevel@tonic-gate /*
5600Sstevel@tonic-gate * If a multi-node diskset, find nodeid associated with this node.
5610Sstevel@tonic-gate */
5620Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
5630Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
5640Sstevel@tonic-gate nr = mnsr->sr_nodechain;
5650Sstevel@tonic-gate while (nr) {
5660Sstevel@tonic-gate if (strcmp(nr->nr_nodename, mynode()) == 0) {
5670Sstevel@tonic-gate break;
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate nr = nr->nr_next;
5700Sstevel@tonic-gate }
5710Sstevel@tonic-gate /*
5720Sstevel@tonic-gate * If node is found, then a new drive is being added to
5730Sstevel@tonic-gate * a MN set of which this node is a member.
5740Sstevel@tonic-gate * If node is not found, then this host is being added to
5750Sstevel@tonic-gate * a MN set that has drives associated with it.
5760Sstevel@tonic-gate */
5770Sstevel@tonic-gate if (nr)
5780Sstevel@tonic-gate nodeid = nr->nr_nodeid;
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) {
5810Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
5820Sstevel@tonic-gate /*
5830Sstevel@tonic-gate * In multi-node disksets, only add side information
5840Sstevel@tonic-gate * to the local mddb about this node.
5850Sstevel@tonic-gate * If the sideno for this node is found, then
5860Sstevel@tonic-gate * a new drive is being added to a MN set of
5870Sstevel@tonic-gate * which this node is a member.
5880Sstevel@tonic-gate * If the sideno for this node is not found, then
5890Sstevel@tonic-gate * this host is being added to a MNset that
5900Sstevel@tonic-gate * has drives associated with it. In this case,
5910Sstevel@tonic-gate * need to add the sidename associated with the
5920Sstevel@tonic-gate * rpc client, but since we don't know which node
5930Sstevel@tonic-gate * is the client, then add temp entries for all sides.
5940Sstevel@tonic-gate * Later, the sidename for this node will be set
5950Sstevel@tonic-gate * via add_drv_sidenms and then the temp
5960Sstevel@tonic-gate * sidenames can be removed.
5970Sstevel@tonic-gate */
5980Sstevel@tonic-gate if (nodeid == sn->sideno) {
5990Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno, key,
6001945Sjeanm sn->dname, sn->mnum, sn->cname,
6011945Sjeanm NULL, NULL, ep)) == -1)
6020Sstevel@tonic-gate return (-1);
6030Sstevel@tonic-gate key = (mdkey_t)err;
6040Sstevel@tonic-gate break;
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate } else {
6070Sstevel@tonic-gate /*
6080Sstevel@tonic-gate * When a sidename is added into the namespace the local
6090Sstevel@tonic-gate * side information for the name is added first of all.
6100Sstevel@tonic-gate * When the first sidename is created this causes the
6110Sstevel@tonic-gate * devid of the disk to be recorded in the namespace, if
6120Sstevel@tonic-gate * the non-local side information is added first then
6130Sstevel@tonic-gate * there is the possibility of getting the wrong devid
6140Sstevel@tonic-gate * because there is no guarantee that the dev_t (mnum in
6150Sstevel@tonic-gate * this instance) is the same across all the nodes in
6160Sstevel@tonic-gate * the set. So the only way to make sure that the
6170Sstevel@tonic-gate * correct dev_t is used is to force the adding in of
6180Sstevel@tonic-gate * the local sidename record first of all. This same
6190Sstevel@tonic-gate * issue affects add_key_name().
6200Sstevel@tonic-gate */
6210Sstevel@tonic-gate if (sn->sideno != thisside)
6220Sstevel@tonic-gate continue;
6230Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno+SKEW, key,
6241945Sjeanm sn->dname, sn->mnum, sn->cname, NULL,
6251945Sjeanm NULL, ep)) == -1)
6260Sstevel@tonic-gate return (-1);
6270Sstevel@tonic-gate key = (mdkey_t)err;
6280Sstevel@tonic-gate break;
6290Sstevel@tonic-gate }
6300Sstevel@tonic-gate }
6310Sstevel@tonic-gate
6320Sstevel@tonic-gate /*
6330Sstevel@tonic-gate * Now the other sides for non-MN set
6340Sstevel@tonic-gate */
6350Sstevel@tonic-gate if (!MD_MNSET_REC(sr)) {
6360Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) {
6370Sstevel@tonic-gate if (sn->sideno == thisside)
6380Sstevel@tonic-gate continue;
6390Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno+SKEW, key,
6401945Sjeanm sn->dname, sn->mnum, sn->cname, NULL, NULL,
6411945Sjeanm ep)) == -1)
6420Sstevel@tonic-gate return (-1);
6430Sstevel@tonic-gate key = (mdkey_t)err;
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate
6470Sstevel@tonic-gate /* Temporarily add all sides. */
6480Sstevel@tonic-gate if ((key == MD_KEYWILD) && (MD_MNSET_REC(sr))) {
6490Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) {
6500Sstevel@tonic-gate sn = dn->side_names;
6510Sstevel@tonic-gate if (sn) {
6520Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno, key,
6531945Sjeanm sn->dname, sn->mnum, sn->cname,
6541945Sjeanm NULL, NULL, ep)) == -1)
6550Sstevel@tonic-gate return (-1);
6560Sstevel@tonic-gate key = (mdkey_t)err;
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate }
6590Sstevel@tonic-gate }
6600Sstevel@tonic-gate
6610Sstevel@tonic-gate dn->side_names_key = key;
6620Sstevel@tonic-gate return (0);
6630Sstevel@tonic-gate }
6640Sstevel@tonic-gate
6651945Sjeanm /*
6661945Sjeanm * imp_adddrvs
6671945Sjeanm * This is a version of adddrvs that is specific to the
6681945Sjeanm * metaimport command. Due to the unavailability of some disks,
6691945Sjeanm * information needs to be obtained about the disk from the devid so
6701945Sjeanm * it can eventually be passed down to add_sidenamelist.
6711945Sjeanm * Go ahead and set drive state to MD_DR_OK here so that no
6721945Sjeanm * later RPC is needed to set OK where UNRLSV_REPLICATED could
6731945Sjeanm * be cleared. Set record is still set to MD_SR_ADD which will force
6741945Sjeanm * a cleanup of the set in case of panic.
6751945Sjeanm */
6761945Sjeanm void
imp_adddrvs(char * setname,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)6771945Sjeanm imp_adddrvs(
6781945Sjeanm char *setname,
6791945Sjeanm md_drive_desc *dd,
6801945Sjeanm md_timeval32_t timestamp,
6811945Sjeanm ulong_t genid,
6821945Sjeanm md_error_t *ep
6831945Sjeanm )
6841945Sjeanm {
6851945Sjeanm mddb_userreq_t req;
6861945Sjeanm md_drive_record *dr, *tdr;
6871945Sjeanm md_set_record *sr;
6881945Sjeanm md_drive_desc *p;
6891945Sjeanm mddrivename_t *dn;
6901945Sjeanm mdname_t *np;
6911945Sjeanm md_dev64_t dev;
6921945Sjeanm md_error_t xep = mdnullerror;
6931945Sjeanm char *minorname = NULL;
6941945Sjeanm ddi_devid_t devidp = NULL;
6951945Sjeanm mdsidenames_t *sn;
6961945Sjeanm mdsetname_t *local_sp;
6971945Sjeanm
6981945Sjeanm
6991945Sjeanm if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) {
7001945Sjeanm return;
7011945Sjeanm }
7021945Sjeanm
7031945Sjeanm if ((sr = getsetbyname(setname, ep)) == NULL)
7041945Sjeanm return;
7051945Sjeanm
7061945Sjeanm for (p = dd; p != NULL; p = p->dd_next) {
7071945Sjeanm uint_t rep_slice;
7081945Sjeanm int ret = 0;
7091945Sjeanm
7101945Sjeanm dn = p->dd_dnp;
7111945Sjeanm
7121945Sjeanm /*
7131945Sjeanm * We need the minorname and devid string decoded from the
7141945Sjeanm * devid to add the sidename for this drive to the
7151945Sjeanm * local set.
7161945Sjeanm */
7171945Sjeanm ret = devid_str_decode(dn->devid, &devidp, &minorname);
7181945Sjeanm if (ret != 0) {
7191945Sjeanm /* failed to decode the devid */
7201945Sjeanm goto out;
7211945Sjeanm }
7221945Sjeanm
7231945Sjeanm sn = dn->side_names;
7241945Sjeanm if (sn == NULL) {
7251945Sjeanm dn->side_names_key = MD_KEYWILD;
7261945Sjeanm continue;
7271945Sjeanm }
7281945Sjeanm
7291945Sjeanm if ((dn->side_names_key = add_name(local_sp, SKEW, MD_KEYWILD,
7301945Sjeanm sn->dname, sn->mnum, sn->cname, minorname, devidp,
7311945Sjeanm ep)) == -1) {
7321945Sjeanm devid_free(devidp);
7331945Sjeanm devid_str_free(minorname);
7341945Sjeanm goto out;
7351945Sjeanm }
7361945Sjeanm
7371945Sjeanm devid_free(devidp);
7381945Sjeanm devid_str_free(minorname);
7391945Sjeanm
7401945Sjeanm /* Create the drive record */
7411945Sjeanm (void) memset(&req, 0, sizeof (req));
7421945Sjeanm METAD_SETUP_DR(MD_DB_CREATE, 0);
7431945Sjeanm req.ur_size = sizeof (*dr);
7441945Sjeanm if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
7451945Sjeanm (void) mdstealerror(ep, &req.ur_mde);
7461945Sjeanm goto out;
7471945Sjeanm }
7481945Sjeanm
7491945Sjeanm /* Fill in the drive record values */
7501945Sjeanm dr = Zalloc(sizeof (*dr));
7511945Sjeanm dr->dr_selfid = req.ur_recid;
7521945Sjeanm dr->dr_dbcnt = p->dd_dbcnt;
7531945Sjeanm dr->dr_dbsize = p->dd_dbsize;
7541945Sjeanm dr->dr_key = dn->side_names_key;
7551945Sjeanm
7561945Sjeanm dr->dr_ctime = timestamp;
7571945Sjeanm dr->dr_genid = genid;
7581945Sjeanm dr->dr_revision = MD_DRIVE_RECORD_REVISION;
7591945Sjeanm dr->dr_flags = MD_DR_OK;
7601945Sjeanm if (p->dd_flags & MD_DR_UNRSLV_REPLICATED) {
7611945Sjeanm dr->dr_flags |= MD_DR_UNRSLV_REPLICATED;
7621945Sjeanm sr->sr_flags |= MD_SR_UNRSLV_REPLICATED;
7631945Sjeanm }
7641945Sjeanm
7651945Sjeanm /* Link the drive records and fill in in-core data */
7661945Sjeanm dr_cache_add(sr, dr);
7671945Sjeanm
7681945Sjeanm dev = NODEV64;
7691945Sjeanm if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
7701945Sjeanm ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
7711945Sjeanm dev = np->dev;
7721945Sjeanm else
7731945Sjeanm mdclrerror(&xep);
7741945Sjeanm
7751945Sjeanm SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
7761945Sjeanm MD_LOCAL_SET, dev);
7771945Sjeanm SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
7781945Sjeanm sr->sr_setno, dev);
7791945Sjeanm }
7801945Sjeanm
7811945Sjeanm /* Commit all the records atomically */
7821945Sjeanm commitset(sr, TRUE, ep);
7831945Sjeanm free_sr(sr);
7841945Sjeanm return;
7851945Sjeanm
7861945Sjeanm out:
7871945Sjeanm /* If failures, remove drive records. */
7881945Sjeanm dr = tdr = sr->sr_drivechain;
7891945Sjeanm while (dr != NULL) {
7901945Sjeanm tdr = dr->dr_next;
7911945Sjeanm if (del_name(local_sp, 0, dr->dr_key, &xep))
7921945Sjeanm mdclrerror(&xep);
7931945Sjeanm sr_del_drv(sr, dr->dr_selfid);
7941945Sjeanm dr = tdr;
7951945Sjeanm }
7961945Sjeanm }
7971945Sjeanm
7980Sstevel@tonic-gate static void
adddrvs(char * setname,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)7990Sstevel@tonic-gate adddrvs(
8000Sstevel@tonic-gate char *setname,
8010Sstevel@tonic-gate md_drive_desc *dd,
8020Sstevel@tonic-gate md_timeval32_t timestamp,
8030Sstevel@tonic-gate ulong_t genid,
8040Sstevel@tonic-gate md_error_t *ep
8050Sstevel@tonic-gate )
8060Sstevel@tonic-gate {
8070Sstevel@tonic-gate mddb_userreq_t req;
8080Sstevel@tonic-gate md_drive_record *dr;
8090Sstevel@tonic-gate md_set_record *sr;
8100Sstevel@tonic-gate md_drive_desc *p;
8110Sstevel@tonic-gate mddrivename_t *dn;
8120Sstevel@tonic-gate mdname_t *np;
8130Sstevel@tonic-gate md_dev64_t dev;
8140Sstevel@tonic-gate md_error_t xep = mdnullerror;
8150Sstevel@tonic-gate int i;
8160Sstevel@tonic-gate
8170Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
8180Sstevel@tonic-gate return;
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate if (MD_MNSET_REC(sr))
8210Sstevel@tonic-gate i = 0;
8220Sstevel@tonic-gate else {
8230Sstevel@tonic-gate /* get thisside */
8240Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
8250Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
8260Sstevel@tonic-gate continue;
8270Sstevel@tonic-gate if (strcmp(mynode(), sr->sr_nodes[i]) == 0)
8280Sstevel@tonic-gate break;
8290Sstevel@tonic-gate }
8300Sstevel@tonic-gate
8310Sstevel@tonic-gate if (i == MD_MAXSIDES) {
8320Sstevel@tonic-gate /* so find the first free slot! */
8330Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
8340Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
8350Sstevel@tonic-gate break;
8360Sstevel@tonic-gate }
8370Sstevel@tonic-gate }
8380Sstevel@tonic-gate }
8390Sstevel@tonic-gate
8400Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
8410Sstevel@tonic-gate uint_t rep_slice;
8420Sstevel@tonic-gate
8430Sstevel@tonic-gate dn = p->dd_dnp;
8440Sstevel@tonic-gate
8450Sstevel@tonic-gate /* Add the per side names to the local db */
8460Sstevel@tonic-gate if (add_sidenamelist(dn, (side_t)i, sr, ep)) {
8470Sstevel@tonic-gate free_sr(sr);
8480Sstevel@tonic-gate return;
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate
8510Sstevel@tonic-gate /* Create the drive record */
8520Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
8530Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_CREATE, 0);
8540Sstevel@tonic-gate req.ur_size = sizeof (*dr);
8550Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
8560Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
8570Sstevel@tonic-gate free_sr(sr);
8580Sstevel@tonic-gate return;
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate /* Fill in the drive record values */
8620Sstevel@tonic-gate dr = Zalloc(sizeof (*dr));
8630Sstevel@tonic-gate dr->dr_selfid = req.ur_recid;
8640Sstevel@tonic-gate dr->dr_dbcnt = p->dd_dbcnt;
8650Sstevel@tonic-gate dr->dr_dbsize = p->dd_dbsize;
8660Sstevel@tonic-gate dr->dr_key = dn->side_names_key;
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate dr->dr_ctime = timestamp;
8690Sstevel@tonic-gate dr->dr_genid = genid;
8700Sstevel@tonic-gate dr->dr_revision = MD_DRIVE_RECORD_REVISION;
8710Sstevel@tonic-gate dr->dr_flags = MD_DR_ADD;
8720Sstevel@tonic-gate
8730Sstevel@tonic-gate /* Link the drive records and fill in in-core data */
8740Sstevel@tonic-gate dr_cache_add(sr, dr);
8750Sstevel@tonic-gate
8760Sstevel@tonic-gate dev = NODEV64;
8770Sstevel@tonic-gate if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
8780Sstevel@tonic-gate ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
8790Sstevel@tonic-gate dev = np->dev;
8800Sstevel@tonic-gate else
8810Sstevel@tonic-gate mdclrerror(&xep);
8820Sstevel@tonic-gate
8830Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
8840Sstevel@tonic-gate MD_LOCAL_SET, dev);
8850Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
8860Sstevel@tonic-gate sr->sr_setno, dev);
8870Sstevel@tonic-gate }
8880Sstevel@tonic-gate
8890Sstevel@tonic-gate /* Commit all the records atomically */
8900Sstevel@tonic-gate commitset(sr, TRUE, ep);
8910Sstevel@tonic-gate free_sr(sr);
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate
8940Sstevel@tonic-gate /*
8950Sstevel@tonic-gate * add 1 or more drive records to a set.
8960Sstevel@tonic-gate */
8970Sstevel@tonic-gate bool_t
mdrpc_adddrvs_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)8980Sstevel@tonic-gate mdrpc_adddrvs_common(
8990Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args,
9000Sstevel@tonic-gate mdrpc_generic_res *res,
9010Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
9020Sstevel@tonic-gate )
9030Sstevel@tonic-gate {
9040Sstevel@tonic-gate md_error_t *ep = &res->status;
9050Sstevel@tonic-gate int err;
9060Sstevel@tonic-gate int op_mode = W_OK;
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate /* setup, check permissions */
9090Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
9100Sstevel@tonic-gate return (FALSE);
9110Sstevel@tonic-gate else if (err != 0)
9120Sstevel@tonic-gate return (TRUE);
9130Sstevel@tonic-gate
9140Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
9150Sstevel@tonic-gate return (TRUE);
9160Sstevel@tonic-gate
9170Sstevel@tonic-gate /* doit */
9180Sstevel@tonic-gate adddrvs(args->sp->setname, args->drivedescs, args->timestamp,
9190Sstevel@tonic-gate args->genid, ep);
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate err = svc_fini(ep);
9220Sstevel@tonic-gate
9230Sstevel@tonic-gate return (TRUE);
9240Sstevel@tonic-gate }
9250Sstevel@tonic-gate
9260Sstevel@tonic-gate /*
9270Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
9280Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
9290Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
9300Sstevel@tonic-gate */
9310Sstevel@tonic-gate bool_t
mdrpc_adddrvs_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9320Sstevel@tonic-gate mdrpc_adddrvs_1_svc(
9330Sstevel@tonic-gate mdrpc_drives_args *args,
9340Sstevel@tonic-gate mdrpc_generic_res *res,
9350Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
9360Sstevel@tonic-gate )
9370Sstevel@tonic-gate {
9380Sstevel@tonic-gate bool_t retval;
9390Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args;
9400Sstevel@tonic-gate
9410Sstevel@tonic-gate /* allocate memory */
9420Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
9437159Sabalfour (void) memset(res, 0, sizeof (*res));
9440Sstevel@tonic-gate
9450Sstevel@tonic-gate /* build args */
9460Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
9470Sstevel@tonic-gate v2_args.sp = args->sp;
9480Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
9490Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
9500Sstevel@tonic-gate v2_args.timestamp = args->timestamp;
9510Sstevel@tonic-gate v2_args.genid = args->genid;
9520Sstevel@tonic-gate
9530Sstevel@tonic-gate retval = mdrpc_adddrvs_common(&v2_args, res, rqstp);
9540Sstevel@tonic-gate
9550Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
9560Sstevel@tonic-gate
9570Sstevel@tonic-gate return (retval);
9580Sstevel@tonic-gate }
9590Sstevel@tonic-gate
9600Sstevel@tonic-gate bool_t
mdrpc_adddrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9610Sstevel@tonic-gate mdrpc_adddrvs_2_svc(
9620Sstevel@tonic-gate mdrpc_drives_2_args *args,
9630Sstevel@tonic-gate mdrpc_generic_res *res,
9640Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
9650Sstevel@tonic-gate )
9660Sstevel@tonic-gate {
9677159Sabalfour (void) memset(res, 0, sizeof (*res));
9680Sstevel@tonic-gate switch (args->rev) {
9697084Sachimm case MD_METAD_ARGS_REV_1:
9700Sstevel@tonic-gate return (mdrpc_adddrvs_common(
9710Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
9727084Sachimm default:
9730Sstevel@tonic-gate return (FALSE);
9740Sstevel@tonic-gate }
9750Sstevel@tonic-gate }
9760Sstevel@tonic-gate
9771945Sjeanm /*
9781945Sjeanm * add 1 or more drive records to a set when importing.
9791945Sjeanm */
9801945Sjeanm bool_t
mdrpc_imp_adddrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9811945Sjeanm mdrpc_imp_adddrvs_2_svc(
9821945Sjeanm mdrpc_drives_2_args *args,
9831945Sjeanm mdrpc_generic_res *res,
9841945Sjeanm struct svc_req *rqstp /* RPC stuff */
9851945Sjeanm )
9861945Sjeanm {
9871945Sjeanm mdrpc_drives_2_args_r1 *v2_args;
9881945Sjeanm md_error_t *ep = &res->status;
9891945Sjeanm int err;
9901945Sjeanm int op_mode = W_OK;
9911945Sjeanm
9927159Sabalfour (void) memset(res, 0, sizeof (*res));
9931945Sjeanm switch (args->rev) {
9947084Sachimm case MD_METAD_ARGS_REV_1:
9951945Sjeanm v2_args = &args->mdrpc_drives_2_args_u.rev1;
9961945Sjeanm if (v2_args == NULL) {
9971945Sjeanm return (FALSE);
9981945Sjeanm }
9991945Sjeanm break;
10007084Sachimm default:
10011945Sjeanm return (FALSE);
10021945Sjeanm }
10031945Sjeanm
10041945Sjeanm /* setup, check permissions */
10051945Sjeanm if ((err = svc_init(rqstp, op_mode, ep)) < 0)
10061945Sjeanm return (FALSE);
10071945Sjeanm else if (err != 0)
10081945Sjeanm return (TRUE);
10091945Sjeanm
10101945Sjeanm if (check_set_lock(op_mode, v2_args->cl_sk, ep))
10111945Sjeanm return (TRUE);
10121945Sjeanm
10131945Sjeanm /* doit */
10141945Sjeanm imp_adddrvs(v2_args->sp->setname, v2_args->drivedescs,
10151945Sjeanm v2_args->timestamp, v2_args->genid, ep);
10161945Sjeanm
10171945Sjeanm err = svc_fini(ep);
10181945Sjeanm
10191945Sjeanm return (TRUE);
10201945Sjeanm }
10211945Sjeanm
10220Sstevel@tonic-gate static void
addhosts(char * setname,int node_c,char ** node_v,int version,md_error_t * ep)10230Sstevel@tonic-gate addhosts(
10240Sstevel@tonic-gate char *setname,
10250Sstevel@tonic-gate int node_c,
10260Sstevel@tonic-gate char **node_v,
10270Sstevel@tonic-gate int version, /* RPC version of calling routine */
10280Sstevel@tonic-gate md_error_t *ep
10290Sstevel@tonic-gate )
10300Sstevel@tonic-gate {
10310Sstevel@tonic-gate mddb_userreq_t req;
10320Sstevel@tonic-gate md_set_record *sr;
10330Sstevel@tonic-gate int i, j;
10340Sstevel@tonic-gate md_mnset_record *mnsr;
10350Sstevel@tonic-gate md_mnnode_record *nr;
10360Sstevel@tonic-gate mddb_set_node_params_t snp;
10370Sstevel@tonic-gate int nodecnt;
10380Sstevel@tonic-gate mndiskset_membershiplist_t *nl, *nl2;
10390Sstevel@tonic-gate
10400Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
10410Sstevel@tonic-gate return;
10420Sstevel@tonic-gate
10430Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
10440Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
10450Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
10460Sstevel@tonic-gate /*
10470Sstevel@tonic-gate * Verify nodes are in membership list on THIS node.
10480Sstevel@tonic-gate * Initiating node has verified that nodes are in membership
10490Sstevel@tonic-gate * list on the initiating node.
10500Sstevel@tonic-gate * Get membershiplist from API routine. If there's
10510Sstevel@tonic-gate * an error, fail to add hosts and pass back error.
10520Sstevel@tonic-gate */
10530Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
10540Sstevel@tonic-gate free_sr(sr);
10550Sstevel@tonic-gate return;
10560Sstevel@tonic-gate }
10570Sstevel@tonic-gate /* Verify that all nodes are in member list */
10580Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
10590Sstevel@tonic-gate /*
10600Sstevel@tonic-gate * If node in list isn't a member of the membership,
10610Sstevel@tonic-gate * just return error.
10620Sstevel@tonic-gate */
10630Sstevel@tonic-gate if (meta_is_member(node_v[i], NULL, nl) == 0) {
10640Sstevel@tonic-gate meta_free_nodelist(nl);
10650Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
10660Sstevel@tonic-gate sr->sr_setno, node_v[i], NULL, setname);
10670Sstevel@tonic-gate free_sr(sr);
10680Sstevel@tonic-gate return;
10690Sstevel@tonic-gate }
10700Sstevel@tonic-gate }
10710Sstevel@tonic-gate }
10720Sstevel@tonic-gate
10730Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
10740Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
10750Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
10760Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
10770Sstevel@tonic-gate /* Create the node record */
10780Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
10790Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_CREATE, 0);
10800Sstevel@tonic-gate req.ur_size = sizeof (*nr);
10810Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
10820Sstevel@tonic-gate != 0) {
10830Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
10840Sstevel@tonic-gate meta_free_nodelist(nl);
10850Sstevel@tonic-gate free_sr(sr);
10860Sstevel@tonic-gate return;
10870Sstevel@tonic-gate }
10880Sstevel@tonic-gate
10890Sstevel@tonic-gate nr = Zalloc(sizeof (*nr));
10900Sstevel@tonic-gate nr->nr_revision = MD_MNNODE_RECORD_REVISION;
10910Sstevel@tonic-gate nr->nr_selfid = req.ur_recid;
10920Sstevel@tonic-gate nr->nr_ctime = sr->sr_ctime;
10930Sstevel@tonic-gate nr->nr_genid = sr->sr_genid;
10940Sstevel@tonic-gate nr->nr_flags = MD_MN_NODE_ADD;
10950Sstevel@tonic-gate nl2 = nl;
10960Sstevel@tonic-gate while (nl2) {
10970Sstevel@tonic-gate if (strcmp(nl2->msl_node_name, node_v[i])
10980Sstevel@tonic-gate == 0) {
10990Sstevel@tonic-gate nr->nr_nodeid = nl2->msl_node_id;
11000Sstevel@tonic-gate break;
11010Sstevel@tonic-gate }
11020Sstevel@tonic-gate nl2 = nl2->next;
11030Sstevel@tonic-gate }
11040Sstevel@tonic-gate
11050Sstevel@tonic-gate (void) strcpy(nr->nr_nodename, node_v[i]);
11060Sstevel@tonic-gate
11070Sstevel@tonic-gate /*
11080Sstevel@tonic-gate * When a node is added to a MN diskset, set the
11090Sstevel@tonic-gate * nodeid of this node in the md_set structure
11100Sstevel@tonic-gate * in the kernel.
11110Sstevel@tonic-gate */
11120Sstevel@tonic-gate if (strcmp(nr->nr_nodename, mynode()) == 0) {
11130Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp));
11140Sstevel@tonic-gate snp.sn_nodeid = nr->nr_nodeid;
11150Sstevel@tonic-gate snp.sn_setno = mnsr->sr_setno;
11160Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp,
11170Sstevel@tonic-gate &snp.sn_mde, NULL) != 0) {
11180Sstevel@tonic-gate (void) mdstealerror(ep, &snp.sn_mde);
11190Sstevel@tonic-gate meta_free_nodelist(nl);
11200Sstevel@tonic-gate free_sr(sr);
11210Sstevel@tonic-gate return;
11220Sstevel@tonic-gate }
11230Sstevel@tonic-gate }
11240Sstevel@tonic-gate
11250Sstevel@tonic-gate /* Link the node records and fill in in-core data */
11260Sstevel@tonic-gate mnnr_cache_add(mnsr, nr);
11270Sstevel@tonic-gate
11280Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST,
11297084Sachimm mnsr->sr_setno, nr->nr_nodeid);
11300Sstevel@tonic-gate } else {
11310Sstevel@tonic-gate for (j = 0; j < MD_MAXSIDES; j++) {
11320Sstevel@tonic-gate if (sr->sr_nodes[j][0] != '\0')
11330Sstevel@tonic-gate continue;
11340Sstevel@tonic-gate (void) strcpy(sr->sr_nodes[j], node_v[i]);
11350Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD,
11360Sstevel@tonic-gate SVM_TAG_HOST, sr->sr_setno, j);
11370Sstevel@tonic-gate break;
11380Sstevel@tonic-gate }
11390Sstevel@tonic-gate }
11400Sstevel@tonic-gate }
11410Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
11420Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
11430Sstevel@tonic-gate meta_free_nodelist(nl);
11440Sstevel@tonic-gate }
11450Sstevel@tonic-gate
11460Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
11470Sstevel@tonic-gate
11480Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
11490Sstevel@tonic-gate
11500Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
11510Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
11520Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
11530Sstevel@tonic-gate } else {
11540Sstevel@tonic-gate req.ur_size = sizeof (*sr);
11550Sstevel@tonic-gate }
11560Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
11570Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
11580Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
11590Sstevel@tonic-gate free_sr(sr);
11600Sstevel@tonic-gate return;
11610Sstevel@tonic-gate }
11620Sstevel@tonic-gate
11630Sstevel@tonic-gate commitset(sr, TRUE, ep);
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate free_sr(sr);
11660Sstevel@tonic-gate }
11670Sstevel@tonic-gate
11680Sstevel@tonic-gate /*
11690Sstevel@tonic-gate * add 1 or more hosts to a set.
11700Sstevel@tonic-gate */
11710Sstevel@tonic-gate bool_t
mdrpc_addhosts_common(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)11720Sstevel@tonic-gate mdrpc_addhosts_common(
11730Sstevel@tonic-gate mdrpc_host_args *args,
11740Sstevel@tonic-gate mdrpc_generic_res *res,
11750Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
11760Sstevel@tonic-gate int version /* RPC version */
11770Sstevel@tonic-gate )
11780Sstevel@tonic-gate {
11790Sstevel@tonic-gate md_error_t *ep = &res->status;
11800Sstevel@tonic-gate int err;
11810Sstevel@tonic-gate int op_mode = W_OK;
11820Sstevel@tonic-gate
11830Sstevel@tonic-gate /* setup, check permissions */
11840Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
11850Sstevel@tonic-gate return (FALSE);
11860Sstevel@tonic-gate else if (err != 0)
11870Sstevel@tonic-gate return (TRUE);
11880Sstevel@tonic-gate
11890Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
11900Sstevel@tonic-gate return (TRUE);
11910Sstevel@tonic-gate
11920Sstevel@tonic-gate /* doit */
11930Sstevel@tonic-gate addhosts(args->sp->setname, args->hosts.hosts_len,
11940Sstevel@tonic-gate args->hosts.hosts_val, version, ep);
11950Sstevel@tonic-gate
11960Sstevel@tonic-gate err = svc_fini(ep);
11970Sstevel@tonic-gate
11980Sstevel@tonic-gate return (TRUE);
11990Sstevel@tonic-gate }
12000Sstevel@tonic-gate
12010Sstevel@tonic-gate bool_t
mdrpc_addhosts_1_svc(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)12020Sstevel@tonic-gate mdrpc_addhosts_1_svc(
12030Sstevel@tonic-gate mdrpc_host_args *args,
12040Sstevel@tonic-gate mdrpc_generic_res *res,
12050Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
12060Sstevel@tonic-gate )
12070Sstevel@tonic-gate {
12080Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
12097159Sabalfour (void) memset(res, 0, sizeof (*res));
12100Sstevel@tonic-gate return (mdrpc_addhosts_common(args, res, rqstp, METAD_VERSION));
12110Sstevel@tonic-gate }
12120Sstevel@tonic-gate
12130Sstevel@tonic-gate bool_t
mdrpc_addhosts_2_svc(mdrpc_host_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)12140Sstevel@tonic-gate mdrpc_addhosts_2_svc(
12150Sstevel@tonic-gate mdrpc_host_2_args *args,
12160Sstevel@tonic-gate mdrpc_generic_res *res,
12170Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
12180Sstevel@tonic-gate )
12190Sstevel@tonic-gate {
12207159Sabalfour (void) memset(res, 0, sizeof (*res));
12210Sstevel@tonic-gate switch (args->rev) {
12227084Sachimm case MD_METAD_ARGS_REV_1:
12230Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
12240Sstevel@tonic-gate return (mdrpc_addhosts_common(
12250Sstevel@tonic-gate &args->mdrpc_host_2_args_u.rev1, res,
12260Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
12277084Sachimm default:
12280Sstevel@tonic-gate return (FALSE);
12290Sstevel@tonic-gate }
12300Sstevel@tonic-gate }
12310Sstevel@tonic-gate
12320Sstevel@tonic-gate static void
createset(mdsetname_t * sp,md_node_nm_arr_t nodes,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)12330Sstevel@tonic-gate createset(
12340Sstevel@tonic-gate mdsetname_t *sp,
12350Sstevel@tonic-gate md_node_nm_arr_t nodes,
12360Sstevel@tonic-gate md_timeval32_t timestamp,
12370Sstevel@tonic-gate ulong_t genid,
12380Sstevel@tonic-gate md_error_t *ep
12390Sstevel@tonic-gate )
12400Sstevel@tonic-gate {
12410Sstevel@tonic-gate mddb_userreq_t req;
12420Sstevel@tonic-gate md_set_record *sr;
12430Sstevel@tonic-gate int i;
12440Sstevel@tonic-gate
12450Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
12460Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0);
12470Sstevel@tonic-gate req.ur_size = sizeof (*sr);
12480Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
12490Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
12500Sstevel@tonic-gate return;
12510Sstevel@tonic-gate }
12520Sstevel@tonic-gate
12530Sstevel@tonic-gate sr = Zalloc(sizeof (*sr));
12540Sstevel@tonic-gate
12550Sstevel@tonic-gate sr->sr_selfid = req.ur_recid;
12560Sstevel@tonic-gate sr->sr_setno = sp->setno;
12570Sstevel@tonic-gate (void) strcpy(sr->sr_setname, sp->setname);
12580Sstevel@tonic-gate
12590Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
12600Sstevel@tonic-gate NODEV64);
12610Sstevel@tonic-gate
12620Sstevel@tonic-gate (void) meta_smf_enable(META_SMF_DISKSET, NULL);
12630Sstevel@tonic-gate
12640Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
12650Sstevel@tonic-gate (void) strcpy(sr->sr_nodes[i], nodes[i]);
12660Sstevel@tonic-gate /* Skip empty slots */
12670Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
12680Sstevel@tonic-gate continue;
12690Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
12700Sstevel@tonic-gate i);
12710Sstevel@tonic-gate }
12720Sstevel@tonic-gate
12730Sstevel@tonic-gate sr->sr_ctime = timestamp;
12740Sstevel@tonic-gate sr->sr_genid = genid;
12750Sstevel@tonic-gate sr->sr_revision = MD_SET_RECORD_REVISION;
12760Sstevel@tonic-gate sr->sr_flags |= MD_SR_ADD;
12770Sstevel@tonic-gate
12780Sstevel@tonic-gate sr->sr_mhiargs = defmhiargs;
12790Sstevel@tonic-gate
12800Sstevel@tonic-gate sr_cache_add(sr);
12810Sstevel@tonic-gate
12820Sstevel@tonic-gate commitset(sr, TRUE, ep);
12830Sstevel@tonic-gate }
12840Sstevel@tonic-gate
12850Sstevel@tonic-gate static void
mncreateset(mdsetname_t * sp,md_mnnode_desc * nodelist,md_timeval32_t timestamp,ulong_t genid,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)12860Sstevel@tonic-gate mncreateset(
12870Sstevel@tonic-gate mdsetname_t *sp,
12880Sstevel@tonic-gate md_mnnode_desc *nodelist,
12890Sstevel@tonic-gate md_timeval32_t timestamp,
12900Sstevel@tonic-gate ulong_t genid,
12910Sstevel@tonic-gate md_node_nm_t master_nodenm,
12920Sstevel@tonic-gate int master_nodeid,
12930Sstevel@tonic-gate md_error_t *ep
12940Sstevel@tonic-gate )
12950Sstevel@tonic-gate {
12960Sstevel@tonic-gate mddb_userreq_t req;
12970Sstevel@tonic-gate md_mnset_record *mnsr;
12980Sstevel@tonic-gate md_mnnode_record *nr;
12990Sstevel@tonic-gate md_mnnode_desc *nd;
13000Sstevel@tonic-gate mddb_set_node_params_t snp;
13010Sstevel@tonic-gate int nodecnt;
13020Sstevel@tonic-gate mndiskset_membershiplist_t *nl;
13030Sstevel@tonic-gate
13040Sstevel@tonic-gate /*
13050Sstevel@tonic-gate * Validate that nodes in set being created are in the
13060Sstevel@tonic-gate * membership list on THIS node.
13070Sstevel@tonic-gate * Initiating node has verified that nodes are in membership
13080Sstevel@tonic-gate * list on the initiating node.
13090Sstevel@tonic-gate * Get membershiplist from API routine. If there's
13100Sstevel@tonic-gate * an error, fail to add set and pass back error.
13110Sstevel@tonic-gate */
13120Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
13130Sstevel@tonic-gate return;
13140Sstevel@tonic-gate }
13150Sstevel@tonic-gate /* Verify that all nodes are in member list */
13160Sstevel@tonic-gate nd = nodelist;
13170Sstevel@tonic-gate while (nd) {
13180Sstevel@tonic-gate /*
13190Sstevel@tonic-gate * If node in list isn't a member of the membership,
13200Sstevel@tonic-gate * just return error.
13210Sstevel@tonic-gate */
13220Sstevel@tonic-gate if (meta_is_member(nd->nd_nodename, 0, nl) == 0) {
13230Sstevel@tonic-gate meta_free_nodelist(nl);
13240Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
13250Sstevel@tonic-gate sp->setno, nd->nd_nodename, NULL, sp->setname);
13260Sstevel@tonic-gate return;
13270Sstevel@tonic-gate }
13280Sstevel@tonic-gate nd = nd->nd_next;
13290Sstevel@tonic-gate }
13300Sstevel@tonic-gate meta_free_nodelist(nl);
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
13330Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0);
13340Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
13350Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
13360Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
13370Sstevel@tonic-gate return;
13380Sstevel@tonic-gate }
13390Sstevel@tonic-gate
13400Sstevel@tonic-gate mnsr = Zalloc(sizeof (*mnsr));
13410Sstevel@tonic-gate mnsr->sr_selfid = req.ur_recid;
13420Sstevel@tonic-gate mnsr->sr_setno = sp->setno;
13430Sstevel@tonic-gate (void) strlcpy(mnsr->sr_setname, sp->setname, MD_MAX_SETNAME);
13440Sstevel@tonic-gate
13450Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
13460Sstevel@tonic-gate NODEV64);
13470Sstevel@tonic-gate
13480Sstevel@tonic-gate (void) meta_smf_enable(META_SMF_DISKSET | META_SMF_MN_DISKSET, NULL);
13490Sstevel@tonic-gate
13500Sstevel@tonic-gate nd = nodelist;
13510Sstevel@tonic-gate while (nd) {
13520Sstevel@tonic-gate /* Create the node record */
13530Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
13540Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_CREATE, 0);
13550Sstevel@tonic-gate req.ur_size = sizeof (*nr);
13560Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
13570Sstevel@tonic-gate /* Frees mnsr and any alloc'd node records */
13580Sstevel@tonic-gate free_sr((struct md_set_record *)mnsr);
13590Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
13600Sstevel@tonic-gate return;
13610Sstevel@tonic-gate }
13620Sstevel@tonic-gate
13630Sstevel@tonic-gate nr = Zalloc(sizeof (*nr));
13640Sstevel@tonic-gate nr->nr_revision = MD_MNNODE_RECORD_REVISION;
13650Sstevel@tonic-gate nr->nr_selfid = req.ur_recid;
13660Sstevel@tonic-gate nr->nr_ctime = timestamp;
13670Sstevel@tonic-gate nr->nr_genid = genid;
13680Sstevel@tonic-gate nr->nr_nodeid = nd->nd_nodeid;
13690Sstevel@tonic-gate nr->nr_flags = nd->nd_flags;
13700Sstevel@tonic-gate (void) strlcpy(nr->nr_nodename, nd->nd_nodename,
13717084Sachimm MD_MAX_NODENAME);
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate /* Link the node records and fill in in-core data */
13740Sstevel@tonic-gate mnnr_cache_add(mnsr, nr);
13750Sstevel@tonic-gate
13760Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
13770Sstevel@tonic-gate nr->nr_nodeid);
13780Sstevel@tonic-gate
13790Sstevel@tonic-gate nd = nd->nd_next;
13800Sstevel@tonic-gate }
13810Sstevel@tonic-gate
13820Sstevel@tonic-gate /*
13830Sstevel@tonic-gate * For backward compatibility, fill in mynode name
13840Sstevel@tonic-gate * as the only name in the sr_nodes array. This
13850Sstevel@tonic-gate * allows the pre-MNdiskset code to see that there
13860Sstevel@tonic-gate * is a node in this diskset. This will keep the
13870Sstevel@tonic-gate * pre-MNdiskset code from removing this set.
13880Sstevel@tonic-gate */
13890Sstevel@tonic-gate (void) strlcpy(mnsr->sr_nodes_bw_compat[0], mynode(), MD_MAX_NODENAME);
13900Sstevel@tonic-gate
13910Sstevel@tonic-gate mnsr->sr_ctime = timestamp;
13920Sstevel@tonic-gate mnsr->sr_genid = genid;
13930Sstevel@tonic-gate mnsr->sr_revision = MD_SET_RECORD_REVISION;
13940Sstevel@tonic-gate mnsr->sr_flags |= MD_SR_ADD;
13950Sstevel@tonic-gate
13960Sstevel@tonic-gate mnsr->sr_flags |= MD_SR_MN;
1397*11053SSurya.Prakki@Sun.COM (void) strcpy(mnsr->sr_master_nodenm, master_nodenm);
13980Sstevel@tonic-gate mnsr->sr_master_nodeid = master_nodeid;
13990Sstevel@tonic-gate
14000Sstevel@tonic-gate mnsr->sr_mhiargs = defmhiargs;
14010Sstevel@tonic-gate
14020Sstevel@tonic-gate sr_cache_add((struct md_set_record *)mnsr);
14030Sstevel@tonic-gate
14040Sstevel@tonic-gate commitset((struct md_set_record *)mnsr, TRUE, ep);
14050Sstevel@tonic-gate
14060Sstevel@tonic-gate /*
14070Sstevel@tonic-gate * When a set is created for the first time, the nodelist
14080Sstevel@tonic-gate * will contain this node.
14090Sstevel@tonic-gate * When a node is just being added to a set, the nodelist
14100Sstevel@tonic-gate * will not contain this node. This node is added to the
14110Sstevel@tonic-gate * set structure with a later call to addhosts.
14120Sstevel@tonic-gate *
14130Sstevel@tonic-gate * So, if the nodelist contains an entry for this node
14140Sstevel@tonic-gate * then set the nodeid of this node in the md_set kernel
14150Sstevel@tonic-gate * data structure.
14160Sstevel@tonic-gate */
14170Sstevel@tonic-gate nd = nodelist;
14180Sstevel@tonic-gate while (nd) {
14190Sstevel@tonic-gate if (strcmp(nd->nd_nodename, mynode()) == 0) {
14200Sstevel@tonic-gate break;
14210Sstevel@tonic-gate }
14220Sstevel@tonic-gate nd = nd->nd_next;
14230Sstevel@tonic-gate }
14240Sstevel@tonic-gate if (nd) {
14250Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp));
14260Sstevel@tonic-gate snp.sn_nodeid = nd->nd_nodeid;
14270Sstevel@tonic-gate snp.sn_setno = sp->setno;
14280Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp, &snp.sn_mde, NULL) != 0) {
14290Sstevel@tonic-gate (void) mdstealerror(ep, &snp.sn_mde);
14300Sstevel@tonic-gate return;
14310Sstevel@tonic-gate }
14320Sstevel@tonic-gate }
14330Sstevel@tonic-gate }
14340Sstevel@tonic-gate
14350Sstevel@tonic-gate /*
14360Sstevel@tonic-gate * create a set on a host
14370Sstevel@tonic-gate */
14380Sstevel@tonic-gate bool_t
mdrpc_createset_common(mdrpc_createset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)14390Sstevel@tonic-gate mdrpc_createset_common(
14400Sstevel@tonic-gate mdrpc_createset_args *args,
14410Sstevel@tonic-gate mdrpc_generic_res *res,
14420Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
14430Sstevel@tonic-gate )
14440Sstevel@tonic-gate {
14450Sstevel@tonic-gate md_error_t *ep = &res->status;
14460Sstevel@tonic-gate char stringbuf1[MAXPATHLEN];
14470Sstevel@tonic-gate char stringbuf2[MAXPATHLEN];
14480Sstevel@tonic-gate int err;
14490Sstevel@tonic-gate int op_mode = W_OK;
14500Sstevel@tonic-gate
14510Sstevel@tonic-gate /* setup, check permissions */
14520Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
14530Sstevel@tonic-gate return (FALSE);
14540Sstevel@tonic-gate else if (err != 0)
14550Sstevel@tonic-gate return (TRUE);
14560Sstevel@tonic-gate
14570Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
14580Sstevel@tonic-gate return (TRUE);
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate /* create the arguments for the symlink() and unlink() calls */
14610Sstevel@tonic-gate (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
14620Sstevel@tonic-gate args->sp->setname);
14630Sstevel@tonic-gate (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
14640Sstevel@tonic-gate args->sp->setno);
14650Sstevel@tonic-gate
14660Sstevel@tonic-gate /*
14670Sstevel@tonic-gate * Since we already verified that the setname was OK, make sure to
14680Sstevel@tonic-gate * cleanup before proceeding.
14690Sstevel@tonic-gate */
14700Sstevel@tonic-gate if (unlink(stringbuf2) == -1) {
14710Sstevel@tonic-gate if (errno != ENOENT) {
14720Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2);
14730Sstevel@tonic-gate return (TRUE);
14740Sstevel@tonic-gate }
14750Sstevel@tonic-gate }
14760Sstevel@tonic-gate
14770Sstevel@tonic-gate /* create the set */
14780Sstevel@tonic-gate createset(args->sp, args->nodes, args->timestamp, args->genid, ep);
14790Sstevel@tonic-gate
14800Sstevel@tonic-gate if (! mdisok(ep))
14810Sstevel@tonic-gate return (TRUE);
14820Sstevel@tonic-gate
14837084Sachimm /* create the symlink */
14847084Sachimm if (symlink(stringbuf1, stringbuf2) == -1)
14857084Sachimm (void) mdsyserror(ep, errno, stringbuf2);
14867084Sachimm
14870Sstevel@tonic-gate err = svc_fini(ep);
14880Sstevel@tonic-gate
14890Sstevel@tonic-gate return (TRUE);
14900Sstevel@tonic-gate }
14910Sstevel@tonic-gate
14920Sstevel@tonic-gate bool_t
mdrpc_createset_1_svc(mdrpc_createset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)14930Sstevel@tonic-gate mdrpc_createset_1_svc(
14940Sstevel@tonic-gate mdrpc_createset_args *args,
14950Sstevel@tonic-gate mdrpc_generic_res *res,
14960Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
14970Sstevel@tonic-gate )
14980Sstevel@tonic-gate {
14997159Sabalfour (void) memset(res, 0, sizeof (*res));
15000Sstevel@tonic-gate return (mdrpc_createset_common(args, res, rqstp));
15010Sstevel@tonic-gate }
15020Sstevel@tonic-gate
15030Sstevel@tonic-gate bool_t
mdrpc_createset_2_svc(mdrpc_createset_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15040Sstevel@tonic-gate mdrpc_createset_2_svc(
15050Sstevel@tonic-gate mdrpc_createset_2_args *args,
15060Sstevel@tonic-gate mdrpc_generic_res *res,
15070Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
15080Sstevel@tonic-gate )
15090Sstevel@tonic-gate {
15107159Sabalfour (void) memset(res, 0, sizeof (*res));
15110Sstevel@tonic-gate switch (args->rev) {
15127084Sachimm case MD_METAD_ARGS_REV_1:
15130Sstevel@tonic-gate return (mdrpc_createset_common(
15140Sstevel@tonic-gate &args->mdrpc_createset_2_args_u.rev1, res, rqstp));
15157084Sachimm default:
15160Sstevel@tonic-gate return (FALSE);
15170Sstevel@tonic-gate }
15180Sstevel@tonic-gate }
15190Sstevel@tonic-gate
15200Sstevel@tonic-gate bool_t
mdrpc_mncreateset_common(mdrpc_mncreateset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15210Sstevel@tonic-gate mdrpc_mncreateset_common(
15220Sstevel@tonic-gate mdrpc_mncreateset_args *args,
15230Sstevel@tonic-gate mdrpc_generic_res *res,
15240Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
15250Sstevel@tonic-gate )
15260Sstevel@tonic-gate {
15270Sstevel@tonic-gate md_error_t *ep = &res->status;
15280Sstevel@tonic-gate char stringbuf1[MAXPATHLEN];
15290Sstevel@tonic-gate char stringbuf2[MAXPATHLEN];
15300Sstevel@tonic-gate int err;
15310Sstevel@tonic-gate int op_mode = W_OK;
15320Sstevel@tonic-gate
15330Sstevel@tonic-gate /* setup, check permissions */
15340Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
15350Sstevel@tonic-gate return (FALSE);
15360Sstevel@tonic-gate else if (err != 0)
15370Sstevel@tonic-gate return (TRUE);
15380Sstevel@tonic-gate
15390Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
15400Sstevel@tonic-gate return (TRUE);
15410Sstevel@tonic-gate
15420Sstevel@tonic-gate /* create the arguments for the symlink() and unlink() calls */
15430Sstevel@tonic-gate (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
15440Sstevel@tonic-gate args->sp->setname);
15450Sstevel@tonic-gate (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
15460Sstevel@tonic-gate args->sp->setno);
15470Sstevel@tonic-gate
15480Sstevel@tonic-gate /*
15490Sstevel@tonic-gate * Since we already verified that the setname was OK, make sure to
15500Sstevel@tonic-gate * cleanup before proceeding.
15510Sstevel@tonic-gate */
15520Sstevel@tonic-gate if (unlink(stringbuf2) == -1) {
15530Sstevel@tonic-gate if (errno != ENOENT) {
15540Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2);
15550Sstevel@tonic-gate return (TRUE);
15560Sstevel@tonic-gate }
15570Sstevel@tonic-gate }
15580Sstevel@tonic-gate
15590Sstevel@tonic-gate /* create the set */
15600Sstevel@tonic-gate mncreateset(args->sp, args->nodelist, args->timestamp, args->genid,
15617084Sachimm args->master_nodenm, args->master_nodeid, ep);
15620Sstevel@tonic-gate
15630Sstevel@tonic-gate if (! mdisok(ep)) {
15640Sstevel@tonic-gate return (TRUE);
15650Sstevel@tonic-gate }
15667084Sachimm
15677084Sachimm /* create the symlink */
15687084Sachimm if (symlink(stringbuf1, stringbuf2) == -1)
15697084Sachimm (void) mdsyserror(ep, errno, stringbuf2);
15707084Sachimm
15710Sstevel@tonic-gate err = svc_fini(ep);
15720Sstevel@tonic-gate
15730Sstevel@tonic-gate return (TRUE);
15740Sstevel@tonic-gate }
15750Sstevel@tonic-gate
15760Sstevel@tonic-gate bool_t
mdrpc_mncreateset_2_svc(mdrpc_mncreateset_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15770Sstevel@tonic-gate mdrpc_mncreateset_2_svc(
15780Sstevel@tonic-gate mdrpc_mncreateset_2_args *args,
15790Sstevel@tonic-gate mdrpc_generic_res *res,
15800Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
15810Sstevel@tonic-gate )
15820Sstevel@tonic-gate {
15837159Sabalfour (void) memset(res, 0, sizeof (*res));
15840Sstevel@tonic-gate switch (args->rev) {
15857084Sachimm case MD_METAD_ARGS_REV_1:
15860Sstevel@tonic-gate return (mdrpc_mncreateset_common(
15870Sstevel@tonic-gate &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp));
15887084Sachimm default:
15890Sstevel@tonic-gate return (FALSE);
15900Sstevel@tonic-gate }
15910Sstevel@tonic-gate }
15920Sstevel@tonic-gate
15930Sstevel@tonic-gate static void
del_drv_sidenms(mdsetname_t * sp,int version,md_error_t * ep)15940Sstevel@tonic-gate del_drv_sidenms(
15950Sstevel@tonic-gate mdsetname_t *sp,
15960Sstevel@tonic-gate int version, /* RPC version of calling routine */
15970Sstevel@tonic-gate md_error_t *ep
15980Sstevel@tonic-gate )
15990Sstevel@tonic-gate {
16000Sstevel@tonic-gate md_set_record *sr;
16010Sstevel@tonic-gate md_drive_desc *dd, *p;
16020Sstevel@tonic-gate mddrivename_t *dn;
16030Sstevel@tonic-gate mdsetname_t *local_sp;
16040Sstevel@tonic-gate int i;
16050Sstevel@tonic-gate int rb_mode = 0;
16060Sstevel@tonic-gate
16070Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
16080Sstevel@tonic-gate return;
16090Sstevel@tonic-gate
16100Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
16110Sstevel@tonic-gate return;
16120Sstevel@tonic-gate
16130Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
16140Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
16150Sstevel@tonic-gate /*
16160Sstevel@tonic-gate * In the multi-node diskset, there are no diskset
16170Sstevel@tonic-gate * entries in the local set for other nodes, so there's
16180Sstevel@tonic-gate * nothing to do.
16190Sstevel@tonic-gate */
16200Sstevel@tonic-gate free_sr(sr);
16210Sstevel@tonic-gate return;
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate
16240Sstevel@tonic-gate if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
16250Sstevel@tonic-gate ep)) == NULL) {
16260Sstevel@tonic-gate if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) {
16270Sstevel@tonic-gate metaflushsetname(sp);
16280Sstevel@tonic-gate if (! mdisok(ep)) {
16290Sstevel@tonic-gate free_sr(sr);
16300Sstevel@tonic-gate return;
16310Sstevel@tonic-gate }
16320Sstevel@tonic-gate /* we are supposed to have drives!!!! */
16330Sstevel@tonic-gate assert(0);
16340Sstevel@tonic-gate }
16350Sstevel@tonic-gate rb_mode = 1;
16360Sstevel@tonic-gate mdclrerror(ep);
16370Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
16380Sstevel@tonic-gate /* Skip empty sides of the diskset */
16390Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
16400Sstevel@tonic-gate continue;
16410Sstevel@tonic-gate dd = metaget_drivedesc_sideno(sp, i,
16420Sstevel@tonic-gate (MD_BASICNAME_OK | PRINT_FAST), ep);
16430Sstevel@tonic-gate /* Got dd, get out of loop */
16440Sstevel@tonic-gate if (dd != NULL)
16450Sstevel@tonic-gate break;
16460Sstevel@tonic-gate
16470Sstevel@tonic-gate /* some error occurred, get out of loop */
16480Sstevel@tonic-gate if (! mdisok(ep))
16490Sstevel@tonic-gate break;
16500Sstevel@tonic-gate }
16510Sstevel@tonic-gate /*
16520Sstevel@tonic-gate * At this point, we have one of three possibilities:
16530Sstevel@tonic-gate * 1) dd != NULL (we have found drives using an alternate
16540Sstevel@tonic-gate * side.)
16550Sstevel@tonic-gate * 2) dd == NULL (no drives) && mdisok(ep) : assert(0)
16560Sstevel@tonic-gate * 3) dd == NULL (no drives) && ! mdisok(ep) : return
16570Sstevel@tonic-gate * error information to caller.
16580Sstevel@tonic-gate */
16590Sstevel@tonic-gate if (dd == NULL) {
16600Sstevel@tonic-gate metaflushsetname(sp);
16610Sstevel@tonic-gate if (! mdisok(ep)) {
16620Sstevel@tonic-gate free_sr(sr);
16630Sstevel@tonic-gate return;
16640Sstevel@tonic-gate }
16650Sstevel@tonic-gate /* we are supposed to have drives!!!! */
16660Sstevel@tonic-gate assert(0);
16670Sstevel@tonic-gate }
16680Sstevel@tonic-gate }
16690Sstevel@tonic-gate
16700Sstevel@tonic-gate /*
16710Sstevel@tonic-gate * Let's run through each drive descriptor, and delete the
16720Sstevel@tonic-gate * sidename for all sides that are not in the sr_nodes array.
16730Sstevel@tonic-gate * We will ignore errors, cause the empty side may not
16740Sstevel@tonic-gate * have had any names to begin with.
16750Sstevel@tonic-gate */
16760Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
16770Sstevel@tonic-gate dn = p->dd_dnp;
16780Sstevel@tonic-gate
16790Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
16800Sstevel@tonic-gate /* Skip existing sides of the diskset */
16810Sstevel@tonic-gate if (!rb_mode && sr->sr_nodes[i][0] != '\0')
16820Sstevel@tonic-gate continue;
16830Sstevel@tonic-gate /* An empty side, delete the sidename */
16840Sstevel@tonic-gate if (del_name(local_sp, i+SKEW,
16850Sstevel@tonic-gate dn->side_names_key, ep)) {
16860Sstevel@tonic-gate if (!mdissyserror(ep, ENOENT)) {
16870Sstevel@tonic-gate free_sr(sr);
16880Sstevel@tonic-gate return;
16890Sstevel@tonic-gate }
16900Sstevel@tonic-gate mdclrerror(ep);
16910Sstevel@tonic-gate }
16920Sstevel@tonic-gate }
16930Sstevel@tonic-gate }
16940Sstevel@tonic-gate free_sr(sr);
16950Sstevel@tonic-gate metaflushsetname(sp);
16960Sstevel@tonic-gate }
16970Sstevel@tonic-gate
16980Sstevel@tonic-gate /*
16990Sstevel@tonic-gate * delete 1 or more sidenames per drive desc, from the local namespace
17000Sstevel@tonic-gate */
17010Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)17020Sstevel@tonic-gate mdrpc_del_drv_sidenms_common(
17030Sstevel@tonic-gate mdrpc_sp_args *args,
17040Sstevel@tonic-gate mdrpc_generic_res *res,
17050Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
17060Sstevel@tonic-gate int version /* RPC version */
17070Sstevel@tonic-gate )
17080Sstevel@tonic-gate {
17090Sstevel@tonic-gate md_error_t *ep = &res->status;
17100Sstevel@tonic-gate int err;
17110Sstevel@tonic-gate int op_mode = W_OK;
17120Sstevel@tonic-gate
17130Sstevel@tonic-gate /* setup, check permissions */
17140Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
17150Sstevel@tonic-gate return (FALSE);
17160Sstevel@tonic-gate else if (err != 0)
17170Sstevel@tonic-gate return (TRUE);
17180Sstevel@tonic-gate
17190Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
17200Sstevel@tonic-gate return (TRUE);
17210Sstevel@tonic-gate
17220Sstevel@tonic-gate /* doit */
17230Sstevel@tonic-gate del_drv_sidenms(args->sp, version, ep);
17240Sstevel@tonic-gate
17250Sstevel@tonic-gate err = svc_fini(ep);
17260Sstevel@tonic-gate
17270Sstevel@tonic-gate return (TRUE);
17280Sstevel@tonic-gate }
17290Sstevel@tonic-gate
17300Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_1_svc(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)17310Sstevel@tonic-gate mdrpc_del_drv_sidenms_1_svc(
17320Sstevel@tonic-gate mdrpc_sp_args *args,
17330Sstevel@tonic-gate mdrpc_generic_res *res,
17340Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
17350Sstevel@tonic-gate )
17360Sstevel@tonic-gate {
17377159Sabalfour (void) memset(res, 0, sizeof (*res));
17380Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
17390Sstevel@tonic-gate return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION));
17400Sstevel@tonic-gate }
17410Sstevel@tonic-gate
17420Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)17430Sstevel@tonic-gate mdrpc_del_drv_sidenms_2_svc(
17440Sstevel@tonic-gate mdrpc_sp_2_args *args,
17450Sstevel@tonic-gate mdrpc_generic_res *res,
17460Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
17470Sstevel@tonic-gate )
17480Sstevel@tonic-gate {
17497159Sabalfour (void) memset(res, 0, sizeof (*res));
17500Sstevel@tonic-gate switch (args->rev) {
17517084Sachimm case MD_METAD_ARGS_REV_1:
17520Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
17530Sstevel@tonic-gate return (mdrpc_del_drv_sidenms_common(
17540Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res,
17550Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
17567084Sachimm default:
17570Sstevel@tonic-gate return (FALSE);
17580Sstevel@tonic-gate }
17590Sstevel@tonic-gate }
17600Sstevel@tonic-gate
17610Sstevel@tonic-gate static int
del_sidenamelist(md_set_record * sr,mddrivename_t * dn,md_error_t * ep)17620Sstevel@tonic-gate del_sidenamelist(
17630Sstevel@tonic-gate md_set_record *sr,
17640Sstevel@tonic-gate mddrivename_t *dn,
17650Sstevel@tonic-gate md_error_t *ep
17660Sstevel@tonic-gate )
17670Sstevel@tonic-gate {
17680Sstevel@tonic-gate mdsidenames_t *sn;
17690Sstevel@tonic-gate mdsetname_t *local_sp;
17700Sstevel@tonic-gate md_mnset_record *mnsr;
17710Sstevel@tonic-gate md_mnnode_record *nr;
17720Sstevel@tonic-gate
17730Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
17740Sstevel@tonic-gate return (-1);
17750Sstevel@tonic-gate
17760Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next)
17770Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
17780Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
17790Sstevel@tonic-gate /*
17800Sstevel@tonic-gate * Only delete side name entries for this node
17810Sstevel@tonic-gate * on a multi-node diskset.
17820Sstevel@tonic-gate */
17830Sstevel@tonic-gate nr = mnsr->sr_nodechain;
17840Sstevel@tonic-gate while (nr) {
17850Sstevel@tonic-gate if (nr->nr_nodeid == sn->sideno) {
17860Sstevel@tonic-gate if (del_name(local_sp, sn->sideno,
17870Sstevel@tonic-gate dn->side_names_key, ep) == -1)
17880Sstevel@tonic-gate mdclrerror(ep); /* ignore err */
17890Sstevel@tonic-gate break;
17900Sstevel@tonic-gate }
17910Sstevel@tonic-gate nr = nr->nr_next;
17920Sstevel@tonic-gate }
17930Sstevel@tonic-gate } else {
17940Sstevel@tonic-gate if (del_name(local_sp, sn->sideno+SKEW,
17950Sstevel@tonic-gate dn->side_names_key, ep) == -1)
17960Sstevel@tonic-gate mdclrerror(ep); /* ignore errors */
17970Sstevel@tonic-gate }
17980Sstevel@tonic-gate
17990Sstevel@tonic-gate dn->side_names_key = MD_KEYBAD;
18000Sstevel@tonic-gate return (0);
18010Sstevel@tonic-gate }
18020Sstevel@tonic-gate
18030Sstevel@tonic-gate static void
deldrvs(char * setname,md_drive_desc * dd,md_error_t * ep)18040Sstevel@tonic-gate deldrvs(
18050Sstevel@tonic-gate char *setname,
18060Sstevel@tonic-gate md_drive_desc *dd,
18070Sstevel@tonic-gate md_error_t *ep
18080Sstevel@tonic-gate )
18090Sstevel@tonic-gate {
18100Sstevel@tonic-gate mdsetname_t *sp;
18110Sstevel@tonic-gate md_set_record *sr;
18120Sstevel@tonic-gate md_drive_record *dr;
18130Sstevel@tonic-gate mddb_userreq_t req;
18140Sstevel@tonic-gate md_drive_desc *p;
18150Sstevel@tonic-gate mddrivename_t *dn, *dn1;
18160Sstevel@tonic-gate side_t sideno;
18170Sstevel@tonic-gate int i;
18180Sstevel@tonic-gate int rb_mode = 0;
18190Sstevel@tonic-gate mdname_t *np;
18200Sstevel@tonic-gate md_dev64_t dev;
18210Sstevel@tonic-gate md_error_t xep = mdnullerror;
18220Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
18230Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
18240Sstevel@tonic-gate int devid_same = -1;
18250Sstevel@tonic-gate int using_devid = 0;
18260Sstevel@tonic-gate md_mnnode_record *nr;
18270Sstevel@tonic-gate md_mnset_record *mnsr;
18280Sstevel@tonic-gate
18290Sstevel@tonic-gate if ((sp = metasetname(setname, ep)) == NULL)
18300Sstevel@tonic-gate return;
18310Sstevel@tonic-gate
18320Sstevel@tonic-gate metaflushsetname(sp);
18330Sstevel@tonic-gate
18340Sstevel@tonic-gate if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) {
18350Sstevel@tonic-gate if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE))
18360Sstevel@tonic-gate return;
18370Sstevel@tonic-gate mdclrerror(ep);
18380Sstevel@tonic-gate /*
18390Sstevel@tonic-gate * The set record is incomplete, so we need to make note
18400Sstevel@tonic-gate * here so that we can do some special handling later.
18410Sstevel@tonic-gate */
18420Sstevel@tonic-gate rb_mode = 1;
18430Sstevel@tonic-gate }
18440Sstevel@tonic-gate
18450Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
18460Sstevel@tonic-gate return;
18470Sstevel@tonic-gate
18480Sstevel@tonic-gate if (dd->dd_dnp == NULL)
18490Sstevel@tonic-gate return;
18500Sstevel@tonic-gate
18510Sstevel@tonic-gate /*
18520Sstevel@tonic-gate * The system is either all devid or all
18530Sstevel@tonic-gate * non-devid so we determine this by looking
18540Sstevel@tonic-gate * at the first item in the list.
18550Sstevel@tonic-gate *
18560Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
18570Sstevel@tonic-gate * points to a '' string of devid. We need to check this
18580Sstevel@tonic-gate * before set the using_devid.
18590Sstevel@tonic-gate */
18600Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
18610Sstevel@tonic-gate (!(MD_MNSET_REC(sr))))
18620Sstevel@tonic-gate using_devid = 1;
18630Sstevel@tonic-gate
18640Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
18650Sstevel@tonic-gate dn = p->dd_dnp;
18660Sstevel@tonic-gate devid_remote = NULL;
18670Sstevel@tonic-gate
18680Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
18690Sstevel@tonic-gate using_devid) {
18700Sstevel@tonic-gate /*
18710Sstevel@tonic-gate * We have a devid so use it
18720Sstevel@tonic-gate */
18730Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
18740Sstevel@tonic-gate }
18750Sstevel@tonic-gate
18760Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
18770Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
18780Sstevel@tonic-gate /* something went really wrong. Can't process */
18790Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
18800Sstevel@tonic-gate mynode(), dn->cname, sp->setname);
18810Sstevel@tonic-gate return;
18820Sstevel@tonic-gate }
18830Sstevel@tonic-gate
18840Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
18850Sstevel@tonic-gate devid_same = -1;
18860Sstevel@tonic-gate
18870Sstevel@tonic-gate if (! rb_mode) {
18880Sstevel@tonic-gate dn1 = metadrivename_withdrkey(sp, sideno,
18890Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep);
18900Sstevel@tonic-gate if (dn1 == NULL) {
18910Sstevel@tonic-gate free_sr(sr);
18920Sstevel@tonic-gate if (devid_remote)
18930Sstevel@tonic-gate devid_free(devid_remote);
18940Sstevel@tonic-gate return;
18950Sstevel@tonic-gate }
18960Sstevel@tonic-gate } else {
18970Sstevel@tonic-gate /*
18980Sstevel@tonic-gate * Handle special case here where sidenames
18990Sstevel@tonic-gate * from other hosts for this drive may be
19000Sstevel@tonic-gate * in the local mddb, but there is no
19010Sstevel@tonic-gate * sidename entry for this host for this drive.
19020Sstevel@tonic-gate * This could have happened if the node
19030Sstevel@tonic-gate * panic'd between the 2 operations when
19040Sstevel@tonic-gate * adding this node to the set.
19050Sstevel@tonic-gate * So, delete all sidename entries for this
19060Sstevel@tonic-gate * drive.
19070Sstevel@tonic-gate */
19080Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
19090Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
19100Sstevel@tonic-gate nr = mnsr->sr_nodechain;
19110Sstevel@tonic-gate while (nr) {
19120Sstevel@tonic-gate /* We delete all dr sides */
19130Sstevel@tonic-gate dn1 = metadrivename_withdrkey(
19140Sstevel@tonic-gate sp, nr->nr_nodeid,
19150Sstevel@tonic-gate dr->dr_key,
19160Sstevel@tonic-gate MD_BASICNAME_OK, ep);
19170Sstevel@tonic-gate
19180Sstevel@tonic-gate /* if we do, get out of loop */
19190Sstevel@tonic-gate if (dn1 != NULL)
19200Sstevel@tonic-gate break;
19210Sstevel@tonic-gate
19220Sstevel@tonic-gate /* save error for later */
19230Sstevel@tonic-gate (void) mdstealerror(&xep, ep);
19240Sstevel@tonic-gate
19250Sstevel@tonic-gate mdclrerror(ep);
19260Sstevel@tonic-gate
19270Sstevel@tonic-gate nr = nr->nr_next;
19280Sstevel@tonic-gate }
19290Sstevel@tonic-gate } else {
19300Sstevel@tonic-gate /*
19310Sstevel@tonic-gate * Handle special case here
19320Sstevel@tonic-gate * for traditional diskset
19330Sstevel@tonic-gate */
19340Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
19350Sstevel@tonic-gate /* We delete all dr sides */
19360Sstevel@tonic-gate dn1 = metadrivename_withdrkey(
19370Sstevel@tonic-gate sp, i, dr->dr_key,
19380Sstevel@tonic-gate MD_BASICNAME_OK, ep);
19390Sstevel@tonic-gate
19400Sstevel@tonic-gate /* if we do, get out of loop */
19410Sstevel@tonic-gate if (dn1 != NULL)
19420Sstevel@tonic-gate break;
19430Sstevel@tonic-gate
19440Sstevel@tonic-gate /* save error for later */
19450Sstevel@tonic-gate (void) mdstealerror(&xep, ep);
19460Sstevel@tonic-gate
19470Sstevel@tonic-gate mdclrerror(ep);
19480Sstevel@tonic-gate }
19490Sstevel@tonic-gate }
19500Sstevel@tonic-gate
19510Sstevel@tonic-gate if (dn1 == NULL) {
19520Sstevel@tonic-gate (void) mdstealerror(ep, &xep);
19530Sstevel@tonic-gate free_sr(sr);
19540Sstevel@tonic-gate if (devid_remote)
19550Sstevel@tonic-gate devid_free(devid_remote);
19560Sstevel@tonic-gate return;
19570Sstevel@tonic-gate }
19580Sstevel@tonic-gate
19590Sstevel@tonic-gate if (!using_devid)
19600Sstevel@tonic-gate mdclrerror(ep);
19610Sstevel@tonic-gate }
19620Sstevel@tonic-gate
19630Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) {
19640Sstevel@tonic-gate if (devid_str_decode(dn1->devid, &devid_local,
19650Sstevel@tonic-gate NULL) == 0) {
19660Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
19670Sstevel@tonic-gate devid_local);
19680Sstevel@tonic-gate devid_free(devid_local);
19690Sstevel@tonic-gate }
19700Sstevel@tonic-gate }
19710Sstevel@tonic-gate
19720Sstevel@tonic-gate /*
19730Sstevel@tonic-gate * Has the required disk been found - either the devids
19740Sstevel@tonic-gate * match if devid are being used or the actual name of
19750Sstevel@tonic-gate * the disk matches.
19760Sstevel@tonic-gate */
19770Sstevel@tonic-gate if ((using_devid && devid_same == 0) ||
19780Sstevel@tonic-gate (!using_devid &&
19790Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)) {
19800Sstevel@tonic-gate uint_t rep_slice;
19810Sstevel@tonic-gate
19820Sstevel@tonic-gate dev = NODEV64;
19830Sstevel@tonic-gate np = NULL;
19840Sstevel@tonic-gate if (meta_replicaslice(dn1,
19850Sstevel@tonic-gate &rep_slice, &xep) == 0) {
19860Sstevel@tonic-gate np = metaslicename(dn1,
19870Sstevel@tonic-gate rep_slice, &xep);
19880Sstevel@tonic-gate }
19890Sstevel@tonic-gate
19900Sstevel@tonic-gate if (np != NULL)
19910Sstevel@tonic-gate dev = np->dev;
19920Sstevel@tonic-gate else
19930Sstevel@tonic-gate mdclrerror(&xep);
19940Sstevel@tonic-gate break;
19950Sstevel@tonic-gate }
19960Sstevel@tonic-gate }
19970Sstevel@tonic-gate
19980Sstevel@tonic-gate if (dr) {
19990Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
20000Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid)
20010Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
20020Sstevel@tonic-gate != 0) {
20030Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
20040Sstevel@tonic-gate if (devid_remote)
20050Sstevel@tonic-gate devid_free(devid_remote);
20060Sstevel@tonic-gate free_sr(sr);
20070Sstevel@tonic-gate return;
20080Sstevel@tonic-gate }
20090Sstevel@tonic-gate
20100Sstevel@tonic-gate dr_cache_del(sr, dr->dr_selfid);
20110Sstevel@tonic-gate
20120Sstevel@tonic-gate if (del_sidenamelist(sr, dn1, ep) == -1) {
20130Sstevel@tonic-gate goto out;
20140Sstevel@tonic-gate }
20150Sstevel@tonic-gate
20160Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
20170Sstevel@tonic-gate sr->sr_setno, dev);
20180Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
20190Sstevel@tonic-gate MD_LOCAL_SET, dev);
20200Sstevel@tonic-gate
20210Sstevel@tonic-gate continue;
20220Sstevel@tonic-gate }
20230Sstevel@tonic-gate
20240Sstevel@tonic-gate if (devid_remote)
20250Sstevel@tonic-gate devid_free(devid_remote);
20260Sstevel@tonic-gate }
20270Sstevel@tonic-gate
20280Sstevel@tonic-gate out:
20290Sstevel@tonic-gate commitset(sr, TRUE, ep);
20300Sstevel@tonic-gate
20310Sstevel@tonic-gate free_sr(sr);
20320Sstevel@tonic-gate }
20330Sstevel@tonic-gate
20340Sstevel@tonic-gate /*
20350Sstevel@tonic-gate * delete 1 or more drive records from a host.
20360Sstevel@tonic-gate */
20370Sstevel@tonic-gate bool_t
mdrpc_deldrvs_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)20380Sstevel@tonic-gate mdrpc_deldrvs_common(
20390Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args,
20400Sstevel@tonic-gate mdrpc_generic_res *res,
20410Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
20420Sstevel@tonic-gate )
20430Sstevel@tonic-gate {
20440Sstevel@tonic-gate md_error_t *ep = &res->status;
20450Sstevel@tonic-gate int err;
20460Sstevel@tonic-gate int op_mode = W_OK;
20470Sstevel@tonic-gate
20480Sstevel@tonic-gate /* setup, check permissions */
20490Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
20500Sstevel@tonic-gate return (FALSE);
20510Sstevel@tonic-gate else if (err != 0)
20520Sstevel@tonic-gate return (TRUE);
20530Sstevel@tonic-gate
20540Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
20550Sstevel@tonic-gate return (TRUE);
20560Sstevel@tonic-gate
20570Sstevel@tonic-gate /* doit */
20580Sstevel@tonic-gate deldrvs(args->sp->setname, args->drivedescs, ep);
20590Sstevel@tonic-gate
20600Sstevel@tonic-gate err = svc_fini(ep);
20610Sstevel@tonic-gate
20620Sstevel@tonic-gate return (TRUE);
20630Sstevel@tonic-gate }
20640Sstevel@tonic-gate
20650Sstevel@tonic-gate /*
20660Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
20670Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
20680Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
20690Sstevel@tonic-gate */
20700Sstevel@tonic-gate bool_t
mdrpc_deldrvs_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)20710Sstevel@tonic-gate mdrpc_deldrvs_1_svc(
20720Sstevel@tonic-gate mdrpc_drives_args *args,
20730Sstevel@tonic-gate mdrpc_generic_res *res,
20740Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
20750Sstevel@tonic-gate )
20760Sstevel@tonic-gate {
20770Sstevel@tonic-gate bool_t retval;
20780Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args;
20790Sstevel@tonic-gate
20800Sstevel@tonic-gate /* allocate memory */
20810Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
20827159Sabalfour (void) memset(res, 0, sizeof (*res));
20830Sstevel@tonic-gate
20840Sstevel@tonic-gate /* build args */
20850Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
20860Sstevel@tonic-gate v2_args.sp = args->sp;
20870Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
20880Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
20890Sstevel@tonic-gate v2_args.timestamp = args->timestamp;
20900Sstevel@tonic-gate v2_args.genid = args->genid;
20910Sstevel@tonic-gate
20920Sstevel@tonic-gate retval = mdrpc_deldrvs_common(&v2_args, res, rqstp);
20930Sstevel@tonic-gate
20940Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
20950Sstevel@tonic-gate
20960Sstevel@tonic-gate return (retval);
20970Sstevel@tonic-gate }
20980Sstevel@tonic-gate
20990Sstevel@tonic-gate bool_t
mdrpc_deldrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)21000Sstevel@tonic-gate mdrpc_deldrvs_2_svc(
21010Sstevel@tonic-gate mdrpc_drives_2_args *args,
21020Sstevel@tonic-gate mdrpc_generic_res *res,
21030Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
21040Sstevel@tonic-gate )
21050Sstevel@tonic-gate {
21067159Sabalfour (void) memset(res, 0, sizeof (*res));
21070Sstevel@tonic-gate switch (args->rev) {
21087084Sachimm case MD_METAD_ARGS_REV_1:
21090Sstevel@tonic-gate return (mdrpc_deldrvs_common(
21100Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
21117084Sachimm default:
21120Sstevel@tonic-gate return (FALSE);
21130Sstevel@tonic-gate }
21140Sstevel@tonic-gate }
21150Sstevel@tonic-gate
21160Sstevel@tonic-gate static void
delhosts(char * setname,int node_c,char ** node_v,int version,md_error_t * ep)21170Sstevel@tonic-gate delhosts(
21180Sstevel@tonic-gate char *setname,
21190Sstevel@tonic-gate int node_c,
21200Sstevel@tonic-gate char **node_v,
21210Sstevel@tonic-gate int version, /* RPC version of calling routine */
21220Sstevel@tonic-gate md_error_t *ep
21230Sstevel@tonic-gate )
21240Sstevel@tonic-gate {
21250Sstevel@tonic-gate mddb_userreq_t req;
21260Sstevel@tonic-gate md_set_record *sr;
21270Sstevel@tonic-gate int i, j;
21280Sstevel@tonic-gate md_mnset_record *mnsr;
21290Sstevel@tonic-gate md_mnnode_record *nr;
21300Sstevel@tonic-gate
21310Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
21320Sstevel@tonic-gate return;
21330Sstevel@tonic-gate
21340Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
21350Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
21360Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
21370Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
21380Sstevel@tonic-gate nr = mnsr->sr_nodechain;
21390Sstevel@tonic-gate while (nr) {
21400Sstevel@tonic-gate if (strcmp(nr->nr_nodename, node_v[i]) == 0) {
21410Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG,
21427084Sachimm ESC_SVM_REMOVE, SVM_TAG_HOST,
21437084Sachimm sr->sr_setno, nr->nr_nodeid);
21440Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
21450Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_DELETE,
21460Sstevel@tonic-gate nr->nr_selfid);
21470Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req,
21480Sstevel@tonic-gate &req.ur_mde, NULL) != 0) {
21490Sstevel@tonic-gate (void) mdstealerror(ep,
21500Sstevel@tonic-gate &req.ur_mde);
21510Sstevel@tonic-gate free_sr(sr);
21520Sstevel@tonic-gate return;
21530Sstevel@tonic-gate }
21540Sstevel@tonic-gate mnnr_cache_del(mnsr, nr->nr_selfid);
21550Sstevel@tonic-gate break;
21560Sstevel@tonic-gate }
21570Sstevel@tonic-gate nr = nr->nr_next;
21580Sstevel@tonic-gate }
21590Sstevel@tonic-gate } else {
21600Sstevel@tonic-gate for (j = 0; j < MD_MAXSIDES; j++) {
21610Sstevel@tonic-gate if (sr->sr_nodes[j][0] == '\0')
21620Sstevel@tonic-gate continue;
21630Sstevel@tonic-gate if (strcmp(sr->sr_nodes[j], node_v[i]) != 0)
21640Sstevel@tonic-gate continue;
21650Sstevel@tonic-gate (void) memset(sr->sr_nodes[j], '\0',
21660Sstevel@tonic-gate sizeof (sr->sr_nodes[j]));
21670Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE,
21680Sstevel@tonic-gate SVM_TAG_HOST, sr->sr_setno, j);
21690Sstevel@tonic-gate break;
21700Sstevel@tonic-gate }
21710Sstevel@tonic-gate }
21720Sstevel@tonic-gate }
21730Sstevel@tonic-gate
21740Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
21750Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
21760Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
21770Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
21780Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
21790Sstevel@tonic-gate } else {
21800Sstevel@tonic-gate req.ur_size = sizeof (*sr);
21810Sstevel@tonic-gate }
21820Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
21830Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
21840Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
21850Sstevel@tonic-gate free_sr(sr);
21860Sstevel@tonic-gate return;
21870Sstevel@tonic-gate }
21880Sstevel@tonic-gate
21890Sstevel@tonic-gate commitset(sr, TRUE, ep);
21900Sstevel@tonic-gate free_sr(sr);
21910Sstevel@tonic-gate }
21920Sstevel@tonic-gate
21930Sstevel@tonic-gate /*
21940Sstevel@tonic-gate * delete 1 or more a hosts from a set.
21950Sstevel@tonic-gate */
21960Sstevel@tonic-gate bool_t
mdrpc_delhosts_common(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)21970Sstevel@tonic-gate mdrpc_delhosts_common(
21980Sstevel@tonic-gate mdrpc_host_args *args,
21990Sstevel@tonic-gate mdrpc_generic_res *res,
22000Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
22010Sstevel@tonic-gate int version /* RPC version */
22020Sstevel@tonic-gate )
22030Sstevel@tonic-gate {
22040Sstevel@tonic-gate md_error_t *ep = &res->status;
22050Sstevel@tonic-gate int err;
22060Sstevel@tonic-gate int op_mode = W_OK;
22070Sstevel@tonic-gate
22080Sstevel@tonic-gate /* setup, check permissions */
22090Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
22100Sstevel@tonic-gate return (FALSE);
22110Sstevel@tonic-gate else if (err != 0)
22120Sstevel@tonic-gate return (TRUE);
22130Sstevel@tonic-gate
22140Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
22150Sstevel@tonic-gate return (TRUE);
22160Sstevel@tonic-gate
22170Sstevel@tonic-gate /* doit */
22180Sstevel@tonic-gate delhosts(args->sp->setname, args->hosts.hosts_len,
22190Sstevel@tonic-gate args->hosts.hosts_val, version, ep);
22200Sstevel@tonic-gate
22210Sstevel@tonic-gate err = svc_fini(ep);
22220Sstevel@tonic-gate
22230Sstevel@tonic-gate return (TRUE);
22240Sstevel@tonic-gate }
22250Sstevel@tonic-gate
22260Sstevel@tonic-gate bool_t
mdrpc_delhosts_1_svc(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22270Sstevel@tonic-gate mdrpc_delhosts_1_svc(
22280Sstevel@tonic-gate mdrpc_host_args *args,
22290Sstevel@tonic-gate mdrpc_generic_res *res,
22300Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22310Sstevel@tonic-gate )
22320Sstevel@tonic-gate {
22337159Sabalfour (void) memset(res, 0, sizeof (*res));
22340Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
22350Sstevel@tonic-gate return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION));
22360Sstevel@tonic-gate }
22370Sstevel@tonic-gate
22380Sstevel@tonic-gate bool_t
mdrpc_delhosts_2_svc(mdrpc_host_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22390Sstevel@tonic-gate mdrpc_delhosts_2_svc(
22400Sstevel@tonic-gate mdrpc_host_2_args *args,
22410Sstevel@tonic-gate mdrpc_generic_res *res,
22420Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22430Sstevel@tonic-gate )
22440Sstevel@tonic-gate {
22457159Sabalfour (void) memset(res, 0, sizeof (*res));
22460Sstevel@tonic-gate switch (args->rev) {
22477084Sachimm case MD_METAD_ARGS_REV_1:
22480Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
22490Sstevel@tonic-gate return (mdrpc_delhosts_common(
22500Sstevel@tonic-gate &args->mdrpc_host_2_args_u.rev1, res,
22510Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
22527084Sachimm default:
22530Sstevel@tonic-gate return (FALSE);
22540Sstevel@tonic-gate }
22550Sstevel@tonic-gate }
22560Sstevel@tonic-gate
22570Sstevel@tonic-gate /*
22580Sstevel@tonic-gate * delete a set.
22590Sstevel@tonic-gate */
22600Sstevel@tonic-gate bool_t
mdrpc_delset_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22610Sstevel@tonic-gate mdrpc_delset_common(
22620Sstevel@tonic-gate mdrpc_sp_args *args,
22630Sstevel@tonic-gate mdrpc_generic_res *res,
22640Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22650Sstevel@tonic-gate )
22660Sstevel@tonic-gate {
22670Sstevel@tonic-gate md_error_t *ep = &res->status;
22680Sstevel@tonic-gate int err;
22690Sstevel@tonic-gate int op_mode = W_OK;
22700Sstevel@tonic-gate
22710Sstevel@tonic-gate /* setup, check permissions */
22720Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
22730Sstevel@tonic-gate return (FALSE);
22740Sstevel@tonic-gate else if (err != 0)
22750Sstevel@tonic-gate return (TRUE);
22760Sstevel@tonic-gate
22770Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
22780Sstevel@tonic-gate return (TRUE);
22790Sstevel@tonic-gate
22800Sstevel@tonic-gate /* doit */
22810Sstevel@tonic-gate s_delset(args->sp->setname, ep);
22820Sstevel@tonic-gate
22830Sstevel@tonic-gate err = svc_fini(ep);
22840Sstevel@tonic-gate
22850Sstevel@tonic-gate return (TRUE);
22860Sstevel@tonic-gate }
22870Sstevel@tonic-gate
22880Sstevel@tonic-gate bool_t
mdrpc_delset_1_svc(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22890Sstevel@tonic-gate mdrpc_delset_1_svc(
22900Sstevel@tonic-gate mdrpc_sp_args *args,
22910Sstevel@tonic-gate mdrpc_generic_res *res,
22920Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22930Sstevel@tonic-gate )
22940Sstevel@tonic-gate {
22957159Sabalfour (void) memset(res, 0, sizeof (*res));
22960Sstevel@tonic-gate return (mdrpc_delset_common(args, res, rqstp));
22970Sstevel@tonic-gate }
22980Sstevel@tonic-gate
22990Sstevel@tonic-gate bool_t
mdrpc_delset_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)23000Sstevel@tonic-gate mdrpc_delset_2_svc(
23010Sstevel@tonic-gate mdrpc_sp_2_args *args,
23020Sstevel@tonic-gate mdrpc_generic_res *res,
23030Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
23040Sstevel@tonic-gate )
23050Sstevel@tonic-gate {
23067159Sabalfour (void) memset(res, 0, sizeof (*res));
23070Sstevel@tonic-gate switch (args->rev) {
23087084Sachimm case MD_METAD_ARGS_REV_1:
23090Sstevel@tonic-gate return (mdrpc_delset_common(
23100Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
23117084Sachimm default:
23120Sstevel@tonic-gate return (FALSE);
23130Sstevel@tonic-gate }
23140Sstevel@tonic-gate }
23150Sstevel@tonic-gate
23160Sstevel@tonic-gate /*
23170Sstevel@tonic-gate * return device info
23180Sstevel@tonic-gate */
23190Sstevel@tonic-gate static void
devinfo(mdsetname_t * sp,mddrivename_t * dp,mdrpc_devinfo_2_res * res,md_error_t * ep)23200Sstevel@tonic-gate devinfo(
23210Sstevel@tonic-gate mdsetname_t *sp,
23220Sstevel@tonic-gate mddrivename_t *dp,
23230Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
23240Sstevel@tonic-gate md_error_t *ep
23250Sstevel@tonic-gate )
23260Sstevel@tonic-gate {
23270Sstevel@tonic-gate mdname_t *np, *real_np;
23280Sstevel@tonic-gate
23290Sstevel@tonic-gate if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
23300Sstevel@tonic-gate return;
23310Sstevel@tonic-gate
23321623Stw21770 if ((real_np = metaname(&sp, np->bname, LOGICAL_DEVICE, ep)) == NULL)
23330Sstevel@tonic-gate return;
23340Sstevel@tonic-gate
23350Sstevel@tonic-gate res->dev = real_np->dev;
23360Sstevel@tonic-gate (void) getdevstamp(dp, (long *)&res->vtime, ep);
23370Sstevel@tonic-gate res->enc_devid = meta_get_devid(np->rname);
23380Sstevel@tonic-gate }
23390Sstevel@tonic-gate
23400Sstevel@tonic-gate bool_t
mdrpc_devinfo_common(mdrpc_devinfo_2_args_r1 * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)23410Sstevel@tonic-gate mdrpc_devinfo_common(
23420Sstevel@tonic-gate mdrpc_devinfo_2_args_r1 *args,
23430Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
23440Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
23450Sstevel@tonic-gate )
23460Sstevel@tonic-gate {
23470Sstevel@tonic-gate int slice;
23480Sstevel@tonic-gate mdname_t *np;
23490Sstevel@tonic-gate mddrivename_t *dnp = args->drivenamep;
23500Sstevel@tonic-gate md_error_t *ep = &res->status;
23510Sstevel@tonic-gate int err;
23520Sstevel@tonic-gate int op_mode = R_OK;
23530Sstevel@tonic-gate
23540Sstevel@tonic-gate /* setup, check permissions */
23550Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
23560Sstevel@tonic-gate return (FALSE);
23570Sstevel@tonic-gate else if (err != 0)
23580Sstevel@tonic-gate return (TRUE);
23590Sstevel@tonic-gate
23600Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
23610Sstevel@tonic-gate return (TRUE);
23620Sstevel@tonic-gate
23630Sstevel@tonic-gate /*
23640Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to
23650Sstevel@tonic-gate * point to the right place.
23660Sstevel@tonic-gate */
23670Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
23680Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL)
23690Sstevel@tonic-gate return (TRUE);
23700Sstevel@tonic-gate np->drivenamep = dnp;
23710Sstevel@tonic-gate }
23720Sstevel@tonic-gate
23730Sstevel@tonic-gate /* doit */
23740Sstevel@tonic-gate devinfo(args->sp, dnp, res, ep);
23750Sstevel@tonic-gate
23760Sstevel@tonic-gate err = svc_fini(ep);
23770Sstevel@tonic-gate
23780Sstevel@tonic-gate return (TRUE);
23790Sstevel@tonic-gate }
23800Sstevel@tonic-gate
23810Sstevel@tonic-gate /*
23820Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
23830Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
23840Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
23850Sstevel@tonic-gate */
23860Sstevel@tonic-gate bool_t
mdrpc_devinfo_1_svc(mdrpc_devinfo_args * args,mdrpc_devinfo_res * res,struct svc_req * rqstp)23870Sstevel@tonic-gate mdrpc_devinfo_1_svc(
23880Sstevel@tonic-gate mdrpc_devinfo_args *args,
23890Sstevel@tonic-gate mdrpc_devinfo_res *res,
23900Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
23910Sstevel@tonic-gate )
23920Sstevel@tonic-gate {
23930Sstevel@tonic-gate bool_t retval;
23940Sstevel@tonic-gate mdrpc_devinfo_2_args_r1 v2_args;
23950Sstevel@tonic-gate mdrpc_devinfo_2_res v2_res;
23960Sstevel@tonic-gate
23970Sstevel@tonic-gate /* allocate memory */
23980Sstevel@tonic-gate v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
23990Sstevel@tonic-gate v2_args.drivenamep->parts.parts_val =
24000Sstevel@tonic-gate Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
24017159Sabalfour (void) memset(res, 0, sizeof (*res));
24020Sstevel@tonic-gate
24030Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
24040Sstevel@tonic-gate meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
24050Sstevel@tonic-gate retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp);
24060Sstevel@tonic-gate
24070Sstevel@tonic-gate /*
24080Sstevel@tonic-gate * Fill in the result appropriately.
24090Sstevel@tonic-gate * Since dev_t's for version 2 are 64-bit,
24100Sstevel@tonic-gate * we need to convert them to 32-bit for version 1.
24110Sstevel@tonic-gate */
24120Sstevel@tonic-gate res->dev = meta_cmpldev(v2_res.dev);
24130Sstevel@tonic-gate res->vtime = v2_res.vtime;
24140Sstevel@tonic-gate res->status = v2_res.status;
24150Sstevel@tonic-gate
24160Sstevel@tonic-gate free(v2_args.drivenamep);
24170Sstevel@tonic-gate free(v2_args.drivenamep->parts.parts_val);
24180Sstevel@tonic-gate
24190Sstevel@tonic-gate return (retval);
24200Sstevel@tonic-gate }
24210Sstevel@tonic-gate
24220Sstevel@tonic-gate bool_t
mdrpc_devinfo_2_svc(mdrpc_devinfo_2_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)24230Sstevel@tonic-gate mdrpc_devinfo_2_svc(
24240Sstevel@tonic-gate mdrpc_devinfo_2_args *args,
24250Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
24260Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
24270Sstevel@tonic-gate )
24280Sstevel@tonic-gate {
24297159Sabalfour (void) memset(res, 0, sizeof (*res));
24300Sstevel@tonic-gate switch (args->rev) {
24317084Sachimm case MD_METAD_ARGS_REV_1:
24320Sstevel@tonic-gate return (mdrpc_devinfo_common(
24330Sstevel@tonic-gate &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp));
24347084Sachimm default:
24350Sstevel@tonic-gate return (FALSE);
24360Sstevel@tonic-gate }
24370Sstevel@tonic-gate }
24380Sstevel@tonic-gate
24390Sstevel@tonic-gate /*
24400Sstevel@tonic-gate * return device id
24410Sstevel@tonic-gate */
24420Sstevel@tonic-gate static void
mdrpc_get_devid(mdsetname_t * sp,mddrivename_t * dp,mdrpc_devid_res * res,md_error_t * ep)24430Sstevel@tonic-gate mdrpc_get_devid(
24440Sstevel@tonic-gate mdsetname_t *sp,
24450Sstevel@tonic-gate mddrivename_t *dp,
24460Sstevel@tonic-gate mdrpc_devid_res *res,
24470Sstevel@tonic-gate md_error_t *ep
24480Sstevel@tonic-gate )
24490Sstevel@tonic-gate {
24500Sstevel@tonic-gate mdname_t *np;
24510Sstevel@tonic-gate
24520Sstevel@tonic-gate if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
24530Sstevel@tonic-gate return;
24540Sstevel@tonic-gate
24551623Stw21770 if (metaname(&sp, np->bname, LOGICAL_DEVICE, ep) == NULL)
24560Sstevel@tonic-gate return;
24570Sstevel@tonic-gate
24580Sstevel@tonic-gate res->enc_devid = meta_get_devid(np->rname);
24590Sstevel@tonic-gate }
24600Sstevel@tonic-gate
24610Sstevel@tonic-gate bool_t
mdrpc_devid_2_svc(mdrpc_devid_2_args * args,mdrpc_devid_res * res,struct svc_req * rqstp)24620Sstevel@tonic-gate mdrpc_devid_2_svc(
24630Sstevel@tonic-gate mdrpc_devid_2_args *args,
24640Sstevel@tonic-gate mdrpc_devid_res *res,
24650Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
24660Sstevel@tonic-gate )
24670Sstevel@tonic-gate {
24680Sstevel@tonic-gate int slice;
24690Sstevel@tonic-gate mdname_t *np;
24700Sstevel@tonic-gate mddrivename_t *dnp;
24710Sstevel@tonic-gate md_error_t *ep = &res->status;
24720Sstevel@tonic-gate int err;
24730Sstevel@tonic-gate int op_mode = R_OK;
24740Sstevel@tonic-gate
24757159Sabalfour (void) memset(res, 0, sizeof (*res));
24760Sstevel@tonic-gate switch (args->rev) {
24777084Sachimm case MD_METAD_ARGS_REV_1:
24780Sstevel@tonic-gate dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep;
24790Sstevel@tonic-gate break;
24807084Sachimm default:
24810Sstevel@tonic-gate return (FALSE);
24820Sstevel@tonic-gate }
24830Sstevel@tonic-gate
24840Sstevel@tonic-gate /* setup, check permissions */
24850Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
24860Sstevel@tonic-gate return (FALSE);
24870Sstevel@tonic-gate else if (err != 0)
24880Sstevel@tonic-gate return (TRUE);
24890Sstevel@tonic-gate
24900Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
24910Sstevel@tonic-gate return (TRUE);
24920Sstevel@tonic-gate
24930Sstevel@tonic-gate /*
24940Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to
24950Sstevel@tonic-gate * point to the right place.
24960Sstevel@tonic-gate */
24970Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
24980Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL)
24990Sstevel@tonic-gate return (TRUE);
25000Sstevel@tonic-gate np->drivenamep = dnp;
25010Sstevel@tonic-gate }
25020Sstevel@tonic-gate
25030Sstevel@tonic-gate /* doit */
25040Sstevel@tonic-gate mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep);
25050Sstevel@tonic-gate
25060Sstevel@tonic-gate err = svc_fini(ep);
25070Sstevel@tonic-gate
25080Sstevel@tonic-gate return (TRUE);
25090Sstevel@tonic-gate }
25100Sstevel@tonic-gate
25110Sstevel@tonic-gate /*
25120Sstevel@tonic-gate * This routine should not be called for a multi-node diskset.
25130Sstevel@tonic-gate *
25140Sstevel@tonic-gate * The devid support is disabled for MN diskset so this routine
25150Sstevel@tonic-gate * will not be called if the set is MN diskset. The check has
25160Sstevel@tonic-gate * been done early in meta_getnextside_devinfo. However this
25170Sstevel@tonic-gate * routine will be called when the devid support for MN set is
25180Sstevel@tonic-gate * enabled and check is removed.
25190Sstevel@tonic-gate */
25200Sstevel@tonic-gate bool_t
mdrpc_devinfo_by_devid_2_svc(mdrpc_devidstr_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)25210Sstevel@tonic-gate mdrpc_devinfo_by_devid_2_svc(
25220Sstevel@tonic-gate mdrpc_devidstr_args *args,
25230Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
25240Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
25250Sstevel@tonic-gate )
25260Sstevel@tonic-gate {
25270Sstevel@tonic-gate
25280Sstevel@tonic-gate char *devidstr = args->enc_devid;
25290Sstevel@tonic-gate md_error_t *ep = &res->status;
25300Sstevel@tonic-gate ddi_devid_t devid;
25310Sstevel@tonic-gate char *minor_name = NULL;
25320Sstevel@tonic-gate int ret = 0;
25330Sstevel@tonic-gate int err;
25340Sstevel@tonic-gate devid_nmlist_t *disklist = NULL;
25350Sstevel@tonic-gate int op_mode = R_OK;
25360Sstevel@tonic-gate mdname_t *np;
25370Sstevel@tonic-gate mdsetname_t *sp = args->sp;
25380Sstevel@tonic-gate
25390Sstevel@tonic-gate /* setup, check permissions */
25400Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
25410Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
25420Sstevel@tonic-gate return (FALSE);
25430Sstevel@tonic-gate else if (err != 0)
25440Sstevel@tonic-gate return (TRUE);
25450Sstevel@tonic-gate
25460Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
25470Sstevel@tonic-gate return (TRUE);
25480Sstevel@tonic-gate
25490Sstevel@tonic-gate if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
25500Sstevel@tonic-gate return (TRUE);
25510Sstevel@tonic-gate
25520Sstevel@tonic-gate /*
25530Sstevel@tonic-gate * if we do not have a minor name then look for a character device.
25540Sstevel@tonic-gate * This is because the caller (checkdrive_onnode) expects a character
25550Sstevel@tonic-gate * device to be returned. The other client of this interface is
25560Sstevel@tonic-gate * meta_getnextside_devinfo and this supplies a minor name.
25570Sstevel@tonic-gate */
25580Sstevel@tonic-gate if (minor_name == NULL) {
25590Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid,
25600Sstevel@tonic-gate DEVID_MINOR_NAME_ALL_CHR, &disklist);
25610Sstevel@tonic-gate } else {
25620Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
25630Sstevel@tonic-gate &disklist);
25640Sstevel@tonic-gate devid_str_free(minor_name);
25650Sstevel@tonic-gate }
25660Sstevel@tonic-gate
25670Sstevel@tonic-gate devid_free(devid);
25680Sstevel@tonic-gate if (ret != 0) {
25690Sstevel@tonic-gate res->dev = NODEV64;
25700Sstevel@tonic-gate devid_free_nmlist(disklist);
25710Sstevel@tonic-gate return (TRUE);
25720Sstevel@tonic-gate }
25730Sstevel@tonic-gate
25741623Stw21770 np = metaname(&sp, disklist[0].devname, LOGICAL_DEVICE, ep);
25750Sstevel@tonic-gate if (np != NULL) {
25760Sstevel@tonic-gate mdcinfo_t *cinfo;
25770Sstevel@tonic-gate if ((cinfo = metagetcinfo(np, ep)) != NULL) {
25780Sstevel@tonic-gate res->drivername = Strdup(cinfo->dname);
25790Sstevel@tonic-gate }
25800Sstevel@tonic-gate }
25810Sstevel@tonic-gate
25820Sstevel@tonic-gate res->dev = meta_expldev(disklist[0].dev);
25830Sstevel@tonic-gate res->devname = strdup(disklist[0].devname);
25840Sstevel@tonic-gate
25850Sstevel@tonic-gate devid_free_nmlist(disklist);
25860Sstevel@tonic-gate
25870Sstevel@tonic-gate err = svc_fini(ep);
25880Sstevel@tonic-gate
25890Sstevel@tonic-gate return (TRUE);
25900Sstevel@tonic-gate }
25910Sstevel@tonic-gate
25920Sstevel@tonic-gate /*
25930Sstevel@tonic-gate * This routine should not be called for a multi-node diskset.
25940Sstevel@tonic-gate *
25950Sstevel@tonic-gate * The devid support is disabled for MN diskset so this routine
25960Sstevel@tonic-gate * will not be called if the set is MN diskset. The check has
25970Sstevel@tonic-gate * been done early in meta_getnextside_devinfo. However this
25980Sstevel@tonic-gate * routine will be called when the devid support for MN set is
25990Sstevel@tonic-gate * enabled and check is removed.
26000Sstevel@tonic-gate *
26010Sstevel@tonic-gate * This function will return the device info attempting to use
26020Sstevel@tonic-gate * both the passed in devid and device name. This is to deal
26030Sstevel@tonic-gate * with systems that use multi-path disks but not running mpxio.
26040Sstevel@tonic-gate * In this situation meta_deviceid_to_nmlist will return multiple
26050Sstevel@tonic-gate * devices. The orig_devname is used to disambiguate.
26060Sstevel@tonic-gate *
26070Sstevel@tonic-gate */
26080Sstevel@tonic-gate bool_t
mdrpc_devinfo_by_devid_name_2_svc(mdrpc_devid_name_2_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)26090Sstevel@tonic-gate mdrpc_devinfo_by_devid_name_2_svc(
26100Sstevel@tonic-gate mdrpc_devid_name_2_args *args,
26110Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
26120Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
26130Sstevel@tonic-gate )
26140Sstevel@tonic-gate {
26150Sstevel@tonic-gate
26160Sstevel@tonic-gate char *devidstr;
26170Sstevel@tonic-gate char *orig_devname;
26180Sstevel@tonic-gate md_error_t *ep = &res->status;
26190Sstevel@tonic-gate ddi_devid_t devid;
26200Sstevel@tonic-gate char *minor_name = NULL;
26210Sstevel@tonic-gate int ret = 0;
26220Sstevel@tonic-gate int err;
26230Sstevel@tonic-gate int i;
26240Sstevel@tonic-gate devid_nmlist_t *disklist = NULL;
26250Sstevel@tonic-gate int op_mode = R_OK;
26260Sstevel@tonic-gate mdname_t *np;
26270Sstevel@tonic-gate mdsetname_t *sp;
26280Sstevel@tonic-gate
26297159Sabalfour (void) memset(res, 0, sizeof (*res));
26300Sstevel@tonic-gate switch (args->rev) {
26317084Sachimm case MD_METAD_ARGS_REV_1:
26320Sstevel@tonic-gate sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp;
26330Sstevel@tonic-gate devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid;
26340Sstevel@tonic-gate orig_devname =
26357084Sachimm (&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname;
26360Sstevel@tonic-gate break;
26377084Sachimm default:
26380Sstevel@tonic-gate return (FALSE);
26390Sstevel@tonic-gate }
26400Sstevel@tonic-gate
26410Sstevel@tonic-gate /* setup, check permissions */
26420Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
26430Sstevel@tonic-gate return (FALSE);
26440Sstevel@tonic-gate else if (err != 0)
26450Sstevel@tonic-gate return (TRUE);
26460Sstevel@tonic-gate
26470Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
26480Sstevel@tonic-gate return (TRUE);
26490Sstevel@tonic-gate
26500Sstevel@tonic-gate if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
26510Sstevel@tonic-gate return (TRUE);
26520Sstevel@tonic-gate
26530Sstevel@tonic-gate /*
26540Sstevel@tonic-gate * if we do not have a minor name then look for a character device.
26550Sstevel@tonic-gate * This is because the caller (checkdrive_onnode) expects a character
26560Sstevel@tonic-gate * device to be returned. The other client of this interface is
26570Sstevel@tonic-gate * meta_getnextside_devinfo and this supplies a minor name.
26580Sstevel@tonic-gate */
26590Sstevel@tonic-gate if (minor_name == NULL) {
26600Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid,
26610Sstevel@tonic-gate DEVID_MINOR_NAME_ALL_CHR, &disklist);
26620Sstevel@tonic-gate } else {
26630Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
26640Sstevel@tonic-gate &disklist);
26650Sstevel@tonic-gate devid_str_free(minor_name);
26660Sstevel@tonic-gate }
26670Sstevel@tonic-gate
26680Sstevel@tonic-gate devid_free(devid);
26690Sstevel@tonic-gate if (ret != 0) {
26700Sstevel@tonic-gate res->dev = NODEV64;
26710Sstevel@tonic-gate devid_free_nmlist(disklist);
26720Sstevel@tonic-gate return (TRUE);
26730Sstevel@tonic-gate }
26740Sstevel@tonic-gate
26750Sstevel@tonic-gate /* attempt to match to the device name on the originating node */
26760Sstevel@tonic-gate for (i = 0; disklist[i].dev != NODEV; i++) {
26770Sstevel@tonic-gate if (strncmp(orig_devname, disklist[i].devname,
26787084Sachimm strlen(disklist[i].devname)) == 0)
26790Sstevel@tonic-gate break;
26800Sstevel@tonic-gate }
26810Sstevel@tonic-gate
26820Sstevel@tonic-gate /* if it's not found then use the first disk in the list */
26830Sstevel@tonic-gate if (disklist[i].dev == NODEV)
26840Sstevel@tonic-gate i = 0;
26850Sstevel@tonic-gate
26861623Stw21770 np = metaname(&sp, disklist[i].devname, LOGICAL_DEVICE, ep);
26870Sstevel@tonic-gate if (np != NULL) {
26880Sstevel@tonic-gate mdcinfo_t *cinfo;
26890Sstevel@tonic-gate if ((cinfo = metagetcinfo(np, ep)) != NULL) {
26900Sstevel@tonic-gate res->drivername = Strdup(cinfo->dname);
26910Sstevel@tonic-gate }
26920Sstevel@tonic-gate }
26930Sstevel@tonic-gate
26940Sstevel@tonic-gate res->dev = meta_expldev(disklist[i].dev);
26950Sstevel@tonic-gate res->devname = strdup(disklist[i].devname);
26960Sstevel@tonic-gate
26970Sstevel@tonic-gate devid_free_nmlist(disklist);
26980Sstevel@tonic-gate
26990Sstevel@tonic-gate err = svc_fini(ep);
27000Sstevel@tonic-gate
27010Sstevel@tonic-gate return (TRUE);
27020Sstevel@tonic-gate }
27030Sstevel@tonic-gate
27040Sstevel@tonic-gate static void
drvused(mdsetname_t * sp,mddrivename_t * dnp,md_error_t * ep)27050Sstevel@tonic-gate drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep)
27060Sstevel@tonic-gate {
27070Sstevel@tonic-gate if (meta_check_drivemounted(sp, dnp, ep))
27080Sstevel@tonic-gate return;
27090Sstevel@tonic-gate
27100Sstevel@tonic-gate if (meta_check_driveswapped(sp, dnp, ep))
27110Sstevel@tonic-gate return;
27120Sstevel@tonic-gate
27130Sstevel@tonic-gate if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp,
27140Sstevel@tonic-gate TRUE, ep))
27150Sstevel@tonic-gate return;
27160Sstevel@tonic-gate
27170Sstevel@tonic-gate (void) meta_check_driveinset(sp, dnp, ep);
27180Sstevel@tonic-gate }
27190Sstevel@tonic-gate
27200Sstevel@tonic-gate /*
27210Sstevel@tonic-gate * determine if a device is in use.
27220Sstevel@tonic-gate */
27230Sstevel@tonic-gate bool_t
mdrpc_drvused_common(mdrpc_drvused_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)27240Sstevel@tonic-gate mdrpc_drvused_common(
27250Sstevel@tonic-gate mdrpc_drvused_2_args_r1 *args,
27260Sstevel@tonic-gate mdrpc_generic_res *res,
27270Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
27280Sstevel@tonic-gate )
27290Sstevel@tonic-gate {
27300Sstevel@tonic-gate md_error_t *ep = &res->status;
27310Sstevel@tonic-gate int slice;
27320Sstevel@tonic-gate mdname_t *np;
27330Sstevel@tonic-gate mddrivename_t *dnp = args->drivenamep;
27340Sstevel@tonic-gate int err;
27350Sstevel@tonic-gate int op_mode = R_OK;
27360Sstevel@tonic-gate
27370Sstevel@tonic-gate /* setup, check permissions */
27380Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
27390Sstevel@tonic-gate return (FALSE);
27400Sstevel@tonic-gate else if (err != 0)
27410Sstevel@tonic-gate return (TRUE);
27420Sstevel@tonic-gate
27430Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
27440Sstevel@tonic-gate return (TRUE);
27450Sstevel@tonic-gate
27460Sstevel@tonic-gate if (dnp == NULL) {
27470Sstevel@tonic-gate /* no drive pointer specified */
27480Sstevel@tonic-gate return (TRUE);
27490Sstevel@tonic-gate }
27500Sstevel@tonic-gate /*
27510Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to
27520Sstevel@tonic-gate * point to the right place.
27530Sstevel@tonic-gate */
27540Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
27550Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL)
27560Sstevel@tonic-gate return (TRUE);
27570Sstevel@tonic-gate np->drivenamep = dnp;
27580Sstevel@tonic-gate }
27590Sstevel@tonic-gate
27600Sstevel@tonic-gate /* doit */
27610Sstevel@tonic-gate drvused(args->sp, dnp, ep);
27620Sstevel@tonic-gate
27630Sstevel@tonic-gate err = svc_fini(ep);
27640Sstevel@tonic-gate
27650Sstevel@tonic-gate return (TRUE);
27660Sstevel@tonic-gate }
27670Sstevel@tonic-gate
27680Sstevel@tonic-gate /*
27690Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
27700Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
27710Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
27720Sstevel@tonic-gate */
27730Sstevel@tonic-gate bool_t
mdrpc_drvused_1_svc(mdrpc_drvused_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)27740Sstevel@tonic-gate mdrpc_drvused_1_svc(
27750Sstevel@tonic-gate mdrpc_drvused_args *args,
27760Sstevel@tonic-gate mdrpc_generic_res *res,
27770Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
27780Sstevel@tonic-gate )
27790Sstevel@tonic-gate {
27800Sstevel@tonic-gate bool_t retval;
27810Sstevel@tonic-gate mdrpc_drvused_2_args_r1 v2_args;
27820Sstevel@tonic-gate
27830Sstevel@tonic-gate /* allocate memory */
27840Sstevel@tonic-gate v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
27850Sstevel@tonic-gate v2_args.drivenamep->parts.parts_val =
27860Sstevel@tonic-gate Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
27877159Sabalfour (void) memset(res, 0, sizeof (*res));
27880Sstevel@tonic-gate
27890Sstevel@tonic-gate /* build args */
27900Sstevel@tonic-gate v2_args.sp = args->sp;
27910Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
27920Sstevel@tonic-gate
27930Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
27940Sstevel@tonic-gate meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
27950Sstevel@tonic-gate retval = mdrpc_drvused_common(&v2_args, res, rqstp);
27960Sstevel@tonic-gate
27970Sstevel@tonic-gate free(v2_args.drivenamep);
27980Sstevel@tonic-gate free(v2_args.drivenamep->parts.parts_val);
27990Sstevel@tonic-gate
28000Sstevel@tonic-gate return (retval);
28010Sstevel@tonic-gate }
28020Sstevel@tonic-gate
28030Sstevel@tonic-gate bool_t
mdrpc_drvused_2_svc(mdrpc_drvused_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)28040Sstevel@tonic-gate mdrpc_drvused_2_svc(
28050Sstevel@tonic-gate mdrpc_drvused_2_args *args,
28060Sstevel@tonic-gate mdrpc_generic_res *res,
28070Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28080Sstevel@tonic-gate )
28090Sstevel@tonic-gate {
28107159Sabalfour (void) memset(res, 0, sizeof (*res));
28110Sstevel@tonic-gate switch (args->rev) {
28127084Sachimm case MD_METAD_ARGS_REV_1:
28130Sstevel@tonic-gate return (mdrpc_drvused_common(
28140Sstevel@tonic-gate &args->mdrpc_drvused_2_args_u.rev1, res, rqstp));
28157084Sachimm default:
28160Sstevel@tonic-gate return (FALSE);
28170Sstevel@tonic-gate }
28180Sstevel@tonic-gate }
28190Sstevel@tonic-gate
28200Sstevel@tonic-gate /*
28210Sstevel@tonic-gate * return a set records selected by name or number.
28220Sstevel@tonic-gate */
28230Sstevel@tonic-gate bool_t
mdrpc_getset_common(mdrpc_getset_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28240Sstevel@tonic-gate mdrpc_getset_common(
28250Sstevel@tonic-gate mdrpc_getset_args *args,
28260Sstevel@tonic-gate mdrpc_getset_res *res,
28270Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28280Sstevel@tonic-gate )
28290Sstevel@tonic-gate {
28300Sstevel@tonic-gate md_error_t *ep = &res->status;
28310Sstevel@tonic-gate int err;
28320Sstevel@tonic-gate int op_mode = R_OK;
28330Sstevel@tonic-gate
28340Sstevel@tonic-gate /* setup, check permissions */
28350Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
28360Sstevel@tonic-gate return (FALSE);
28370Sstevel@tonic-gate else if (err != 0)
28380Sstevel@tonic-gate return (TRUE);
28390Sstevel@tonic-gate
28400Sstevel@tonic-gate /* Don't have a setno, so we don't check the lock */
28410Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
28420Sstevel@tonic-gate return (TRUE);
28430Sstevel@tonic-gate
28440Sstevel@tonic-gate /* doit */
28450Sstevel@tonic-gate if (args->setname && *args->setname)
28460Sstevel@tonic-gate res->sr = setdup(getsetbyname(args->setname, ep));
28470Sstevel@tonic-gate else if (args->setno > 0)
28480Sstevel@tonic-gate res->sr = setdup(getsetbynum(args->setno, ep));
28490Sstevel@tonic-gate else
28500Sstevel@tonic-gate res->sr = NULL;
28510Sstevel@tonic-gate
28520Sstevel@tonic-gate err = svc_fini(ep);
28530Sstevel@tonic-gate
28540Sstevel@tonic-gate return (TRUE);
28550Sstevel@tonic-gate }
28560Sstevel@tonic-gate
28570Sstevel@tonic-gate bool_t
mdrpc_getset_1_svc(mdrpc_getset_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28580Sstevel@tonic-gate mdrpc_getset_1_svc(
28590Sstevel@tonic-gate mdrpc_getset_args *args,
28600Sstevel@tonic-gate mdrpc_getset_res *res,
28610Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28620Sstevel@tonic-gate )
28630Sstevel@tonic-gate {
28647159Sabalfour (void) memset(res, 0, sizeof (*res));
28650Sstevel@tonic-gate return (mdrpc_getset_common(args, res, rqstp));
28660Sstevel@tonic-gate }
28670Sstevel@tonic-gate
28680Sstevel@tonic-gate bool_t
mdrpc_getset_2_svc(mdrpc_getset_2_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28690Sstevel@tonic-gate mdrpc_getset_2_svc(
28700Sstevel@tonic-gate mdrpc_getset_2_args *args,
28710Sstevel@tonic-gate mdrpc_getset_res *res,
28720Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28730Sstevel@tonic-gate )
28740Sstevel@tonic-gate {
28757159Sabalfour (void) memset(res, 0, sizeof (*res));
28760Sstevel@tonic-gate switch (args->rev) {
28777084Sachimm case MD_METAD_ARGS_REV_1:
28780Sstevel@tonic-gate return (mdrpc_getset_common(
28790Sstevel@tonic-gate &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
28807084Sachimm default:
28810Sstevel@tonic-gate return (FALSE);
28820Sstevel@tonic-gate }
28830Sstevel@tonic-gate }
28840Sstevel@tonic-gate
28850Sstevel@tonic-gate /*
28860Sstevel@tonic-gate * return a MN set record selected by name or number.
28870Sstevel@tonic-gate */
28880Sstevel@tonic-gate bool_t
mdrpc_mngetset_common(mdrpc_getset_args * args,mdrpc_mngetset_res * res,struct svc_req * rqstp)28890Sstevel@tonic-gate mdrpc_mngetset_common(
28900Sstevel@tonic-gate mdrpc_getset_args *args,
28910Sstevel@tonic-gate mdrpc_mngetset_res *res,
28920Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28930Sstevel@tonic-gate )
28940Sstevel@tonic-gate {
28950Sstevel@tonic-gate md_error_t *ep = &res->status;
28960Sstevel@tonic-gate int err;
28970Sstevel@tonic-gate int op_mode = R_OK;
28980Sstevel@tonic-gate md_set_record *sr = NULL;
28990Sstevel@tonic-gate md_mnset_record *mnsr = NULL;
29000Sstevel@tonic-gate
29010Sstevel@tonic-gate /* setup, check permissions */
29020Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
29030Sstevel@tonic-gate return (FALSE);
29040Sstevel@tonic-gate else if (err != 0)
29050Sstevel@tonic-gate return (TRUE);
29060Sstevel@tonic-gate
29070Sstevel@tonic-gate /* Don't have a setno, so we don't check the lock */
29080Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
29090Sstevel@tonic-gate return (TRUE);
29100Sstevel@tonic-gate
29110Sstevel@tonic-gate /* doit */
29120Sstevel@tonic-gate res->mnsr = NULL;
29130Sstevel@tonic-gate if (args->setname && *args->setname)
29140Sstevel@tonic-gate sr = getsetbyname(args->setname, ep);
29150Sstevel@tonic-gate else if (args->setno > 0)
29160Sstevel@tonic-gate sr = getsetbynum(args->setno, ep);
29170Sstevel@tonic-gate
29180Sstevel@tonic-gate if ((sr) && (MD_MNSET_REC(sr))) {
29190Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
29200Sstevel@tonic-gate res->mnsr = mnsetdup(mnsr);
29210Sstevel@tonic-gate }
29220Sstevel@tonic-gate
29230Sstevel@tonic-gate err = svc_fini(ep);
29240Sstevel@tonic-gate
29250Sstevel@tonic-gate return (TRUE);
29260Sstevel@tonic-gate }
29270Sstevel@tonic-gate
29280Sstevel@tonic-gate bool_t
mdrpc_mngetset_2_svc(mdrpc_getset_2_args * args,mdrpc_mngetset_res * res,struct svc_req * rqstp)29290Sstevel@tonic-gate mdrpc_mngetset_2_svc(
29300Sstevel@tonic-gate mdrpc_getset_2_args *args,
29310Sstevel@tonic-gate mdrpc_mngetset_res *res,
29320Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
29330Sstevel@tonic-gate )
29340Sstevel@tonic-gate {
29357159Sabalfour (void) memset(res, 0, sizeof (*res));
29360Sstevel@tonic-gate switch (args->rev) {
29377084Sachimm case MD_METAD_ARGS_REV_1:
29380Sstevel@tonic-gate return (mdrpc_mngetset_common(
29390Sstevel@tonic-gate &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
29407084Sachimm default:
29410Sstevel@tonic-gate return (FALSE);
29420Sstevel@tonic-gate }
29430Sstevel@tonic-gate }
29440Sstevel@tonic-gate
29450Sstevel@tonic-gate static void
upd_setmaster(mdsetname_t * sp,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)29460Sstevel@tonic-gate upd_setmaster(
29470Sstevel@tonic-gate mdsetname_t *sp,
29480Sstevel@tonic-gate md_node_nm_t master_nodenm,
29490Sstevel@tonic-gate int master_nodeid,
29500Sstevel@tonic-gate md_error_t *ep
29510Sstevel@tonic-gate )
29520Sstevel@tonic-gate {
29530Sstevel@tonic-gate mdsetname_t *local_sp;
29540Sstevel@tonic-gate md_set_record *sr;
29550Sstevel@tonic-gate md_mnset_record *mnsr;
29560Sstevel@tonic-gate mddb_setmaster_config_t sm;
29570Sstevel@tonic-gate
29580Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
29590Sstevel@tonic-gate return;
29600Sstevel@tonic-gate
29610Sstevel@tonic-gate metaflushsetname(local_sp);
29620Sstevel@tonic-gate
29630Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
29640Sstevel@tonic-gate return;
29650Sstevel@tonic-gate
29660Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
29670Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
2968*11053SSurya.Prakki@Sun.COM (void) strlcpy(mnsr->sr_master_nodenm, master_nodenm,
29697084Sachimm MD_MAX_NODENAME);
29700Sstevel@tonic-gate mnsr->sr_master_nodeid = master_nodeid;
29710Sstevel@tonic-gate if (master_nodeid != 0) {
29720Sstevel@tonic-gate (void) memset(&sm, 0, sizeof (sm));
29730Sstevel@tonic-gate sm.c_setno = sp->setno;
29740Sstevel@tonic-gate /* Use magic to help protect ioctl against attack. */
29750Sstevel@tonic-gate sm.c_magic = MDDB_SETMASTER_MAGIC;
29760Sstevel@tonic-gate if (strcmp(master_nodenm, mynode()) == 0) {
29770Sstevel@tonic-gate sm.c_current_host_master = 1;
29780Sstevel@tonic-gate } else {
29790Sstevel@tonic-gate sm.c_current_host_master = 0;
29800Sstevel@tonic-gate }
29810Sstevel@tonic-gate (void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL);
29820Sstevel@tonic-gate mdclrerror(&sm.c_mde);
29830Sstevel@tonic-gate }
29840Sstevel@tonic-gate }
29850Sstevel@tonic-gate
29860Sstevel@tonic-gate out:
29870Sstevel@tonic-gate commitset(sr, FALSE, ep);
29880Sstevel@tonic-gate free_sr(sr);
29890Sstevel@tonic-gate }
29900Sstevel@tonic-gate
29910Sstevel@tonic-gate /*
29920Sstevel@tonic-gate * set the master and nodeid in node record
29930Sstevel@tonic-gate */
29940Sstevel@tonic-gate bool_t
mdrpc_mnsetmaster_common(mdrpc_mnsetmaster_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)29950Sstevel@tonic-gate mdrpc_mnsetmaster_common(
29960Sstevel@tonic-gate mdrpc_mnsetmaster_args *args,
29970Sstevel@tonic-gate mdrpc_generic_res *res,
29980Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
29990Sstevel@tonic-gate )
30000Sstevel@tonic-gate {
30010Sstevel@tonic-gate md_error_t *ep = &res->status;
30020Sstevel@tonic-gate int err;
30030Sstevel@tonic-gate int op_mode = W_OK;
30040Sstevel@tonic-gate
30050Sstevel@tonic-gate /* setup, check permissions */
30060Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
30070Sstevel@tonic-gate return (FALSE);
30080Sstevel@tonic-gate else if (err != 0)
30090Sstevel@tonic-gate return (TRUE);
30100Sstevel@tonic-gate
30110Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
30120Sstevel@tonic-gate return (TRUE);
30130Sstevel@tonic-gate
30140Sstevel@tonic-gate /* doit */
30150Sstevel@tonic-gate upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep);
30160Sstevel@tonic-gate
30170Sstevel@tonic-gate err = svc_fini(ep);
30180Sstevel@tonic-gate
30190Sstevel@tonic-gate return (TRUE);
30200Sstevel@tonic-gate }
30210Sstevel@tonic-gate
30220Sstevel@tonic-gate bool_t
mdrpc_mnsetmaster_2_svc(mdrpc_mnsetmaster_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)30230Sstevel@tonic-gate mdrpc_mnsetmaster_2_svc(
30240Sstevel@tonic-gate mdrpc_mnsetmaster_2_args *args,
30250Sstevel@tonic-gate mdrpc_generic_res *res,
30260Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
30270Sstevel@tonic-gate )
30280Sstevel@tonic-gate {
30297159Sabalfour (void) memset(res, 0, sizeof (*res));
30300Sstevel@tonic-gate switch (args->rev) {
30317084Sachimm case MD_METAD_ARGS_REV_1:
30320Sstevel@tonic-gate return (mdrpc_mnsetmaster_common(
30330Sstevel@tonic-gate &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp));
30347084Sachimm default:
30350Sstevel@tonic-gate return (FALSE);
30360Sstevel@tonic-gate }
30370Sstevel@tonic-gate }
30380Sstevel@tonic-gate
30390Sstevel@tonic-gate /*
30400Sstevel@tonic-gate * Join this node to the diskset.
30410Sstevel@tonic-gate * Pass stale_flag information to snarf_set so that snarf code
30420Sstevel@tonic-gate * can choose a STALE or non-STALE state when starting the set.
30430Sstevel@tonic-gate * If master is STALE, any joining node will join a stale set regardless
30440Sstevel@tonic-gate * of the number of accessible mddbs. Also, if master is at 50%
30450Sstevel@tonic-gate * accessible replicas and is in the TOOFEW state, don't mark newly
30460Sstevel@tonic-gate * joining node as STALE; mark it TOOFEW instead.
30470Sstevel@tonic-gate */
30480Sstevel@tonic-gate static void
joinset(mdsetname_t * sp,int flags,md_error_t * ep)30490Sstevel@tonic-gate joinset(
30500Sstevel@tonic-gate mdsetname_t *sp,
30510Sstevel@tonic-gate int flags,
30520Sstevel@tonic-gate md_error_t *ep
30530Sstevel@tonic-gate )
30540Sstevel@tonic-gate {
30550Sstevel@tonic-gate mdsetname_t *local_sp;
30560Sstevel@tonic-gate md_drive_desc *mydd;
30570Sstevel@tonic-gate bool_t stale_bool;
30580Sstevel@tonic-gate mddb_block_parm_t mbp;
30590Sstevel@tonic-gate md_error_t xep = mdnullerror;
30600Sstevel@tonic-gate
30610Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
30620Sstevel@tonic-gate return;
30630Sstevel@tonic-gate
30640Sstevel@tonic-gate /*
30650Sstevel@tonic-gate * Start mddoors daemon here.
30660Sstevel@tonic-gate * mddoors itself takes care there will be
30670Sstevel@tonic-gate * only one instance running, so starting it twice won't hurt
30680Sstevel@tonic-gate */
3069*11053SSurya.Prakki@Sun.COM (void) pclose(popen(MDDOORS, "w"));
30700Sstevel@tonic-gate
30710Sstevel@tonic-gate /*
30720Sstevel@tonic-gate * Get latest copy of data. If a drive was just added causing
30730Sstevel@tonic-gate * nodes to get joined - this drive won't be in the local
30740Sstevel@tonic-gate * name caches drive list yet.
30750Sstevel@tonic-gate */
30760Sstevel@tonic-gate metaflushsetname(local_sp);
30770Sstevel@tonic-gate
30780Sstevel@tonic-gate mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
30790Sstevel@tonic-gate if (mydd) {
3080650Sskamm /*
3081650Sskamm * Causes mddbs to be loaded into the kernel.
3082650Sskamm * Set the force flag so that replica locations can be loaded
3083650Sskamm * into the kernel even if a mediator node was unavailable.
3084650Sskamm * This allows a node to join an MO diskset when there are
3085650Sskamm * sufficient replicas available, but a mediator node
3086650Sskamm * in unavailable.
3087650Sskamm */
3088650Sskamm if (setup_db_bydd(local_sp, mydd, TRUE, ep) == -1) {
30890Sstevel@tonic-gate /* If ep isn't set for some reason, set it */
3090650Sskamm if (mdisok(ep)) {
309162Sjeanm (void) mdmddberror(ep, MDE_DB_NOTNOW,
309262Sjeanm (minor_t)NODEV64, sp->setno, 0, NULL);
30930Sstevel@tonic-gate }
30940Sstevel@tonic-gate return;
30950Sstevel@tonic-gate }
30960Sstevel@tonic-gate
30970Sstevel@tonic-gate if (flags & MNSET_IS_STALE)
30980Sstevel@tonic-gate stale_bool = TRUE;
30990Sstevel@tonic-gate else
31000Sstevel@tonic-gate stale_bool = FALSE;
31010Sstevel@tonic-gate
31020Sstevel@tonic-gate /*
31030Sstevel@tonic-gate * Snarf the set. No failure has occurred if STALE or
31040Sstevel@tonic-gate * ACCOK error was set. Otherwise, fail the call setting
31050Sstevel@tonic-gate * a generic error if no error was already set.
31060Sstevel@tonic-gate *
31070Sstevel@tonic-gate * STALE means that set has < 50% mddbs.
31080Sstevel@tonic-gate * ACCOK means that the mediator provided an extra vote.
31090Sstevel@tonic-gate */
31100Sstevel@tonic-gate if (snarf_set(local_sp, stale_bool, ep) != 0) {
31110Sstevel@tonic-gate if (!(mdismddberror(ep, MDE_DB_STALE)) &&
31120Sstevel@tonic-gate !(mdismddberror(ep, MDE_DB_ACCOK))) {
31130Sstevel@tonic-gate return;
31140Sstevel@tonic-gate } else if (mdisok(ep)) {
31150Sstevel@tonic-gate /* If snarf failed, but no error set - set it */
311662Sjeanm (void) mdmddberror(ep, MDE_DB_NOTNOW,
311762Sjeanm (minor_t)NODEV64, sp->setno, 0, NULL);
31180Sstevel@tonic-gate return;
31190Sstevel@tonic-gate }
31200Sstevel@tonic-gate }
31210Sstevel@tonic-gate
31220Sstevel@tonic-gate /*
31230Sstevel@tonic-gate * If node is joining during reconfig cycle, then
31240Sstevel@tonic-gate * set mddb_parse to be in blocked state so that
31250Sstevel@tonic-gate * mddb reparse messages are not generated until
31260Sstevel@tonic-gate * the commd has been resumed later in the reconfig
31270Sstevel@tonic-gate * cycle.
31280Sstevel@tonic-gate */
31290Sstevel@tonic-gate if (flags & MNSET_IN_RECONFIG) {
31300Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp));
31310Sstevel@tonic-gate if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) {
31320Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp));
31330Sstevel@tonic-gate mbp.c_setno = local_sp->setno;
31340Sstevel@tonic-gate mbp.c_blk_flags = MDDB_BLOCK_PARSE;
31350Sstevel@tonic-gate if (metaioctl(MD_MN_MDDB_BLOCK, &mbp,
31360Sstevel@tonic-gate &mbp.c_mde, NULL)) {
3137*11053SSurya.Prakki@Sun.COM (void) mdstealerror(&xep, &mbp.c_mde);
31380Sstevel@tonic-gate mde_perror(ep, gettext(
31390Sstevel@tonic-gate "Could not block set %s"),
31400Sstevel@tonic-gate sp->setname);
31410Sstevel@tonic-gate return;
31420Sstevel@tonic-gate }
31430Sstevel@tonic-gate }
31440Sstevel@tonic-gate /*
31450Sstevel@tonic-gate * If s_ownset fails and snarf_set succeeded,
31460Sstevel@tonic-gate * then can steal the ownset failure information
31470Sstevel@tonic-gate * and store it into ep. If snarf_set failed,
31480Sstevel@tonic-gate * don't overwrite critical ep information even
31490Sstevel@tonic-gate * if s_ownset failed.
31500Sstevel@tonic-gate */
31510Sstevel@tonic-gate if (!mdisok(&xep)) {
31520Sstevel@tonic-gate /*
31530Sstevel@tonic-gate * If snarf_set succeeded or snarf_set failed
31540Sstevel@tonic-gate * with MDE_DB_ACCOK (which is set if the
31550Sstevel@tonic-gate * mediator provided the extra vote) then
31560Sstevel@tonic-gate * steal the xep failure information and put
31570Sstevel@tonic-gate * into ep.
31580Sstevel@tonic-gate */
31590Sstevel@tonic-gate if (mdisok(ep) ||
31600Sstevel@tonic-gate mdismddberror(ep, MDE_DB_ACCOK)) {
3161*11053SSurya.Prakki@Sun.COM (void) mdstealerror(ep, &xep);
31620Sstevel@tonic-gate }
31630Sstevel@tonic-gate }
31640Sstevel@tonic-gate }
31650Sstevel@tonic-gate }
31660Sstevel@tonic-gate }
31670Sstevel@tonic-gate
31680Sstevel@tonic-gate /*
31690Sstevel@tonic-gate * Have this node join the set.
31700Sstevel@tonic-gate * This is called when a node has been
31710Sstevel@tonic-gate * added to a MN diskset that has drives.
31720Sstevel@tonic-gate * Also, called when a node is an alive
31730Sstevel@tonic-gate * member of a MN diskset and the first
31740Sstevel@tonic-gate * drive has been added.
31750Sstevel@tonic-gate */
31760Sstevel@tonic-gate bool_t
mdrpc_joinset_common(mdrpc_sp_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)31770Sstevel@tonic-gate mdrpc_joinset_common(
31780Sstevel@tonic-gate mdrpc_sp_flags_args *args,
31790Sstevel@tonic-gate mdrpc_generic_res *res,
31800Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
31810Sstevel@tonic-gate )
31820Sstevel@tonic-gate {
31830Sstevel@tonic-gate md_error_t *ep = &res->status;
31840Sstevel@tonic-gate int err;
31850Sstevel@tonic-gate int op_mode = W_OK;
31860Sstevel@tonic-gate
31870Sstevel@tonic-gate /* setup, check permissions */
31880Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
31890Sstevel@tonic-gate return (FALSE);
31900Sstevel@tonic-gate else if (err != 0)
31910Sstevel@tonic-gate return (TRUE);
31920Sstevel@tonic-gate
31930Sstevel@tonic-gate /*
31940Sstevel@tonic-gate * During reconfig, joinset can happen without
31950Sstevel@tonic-gate * locking first. Turn off reconfig flag before calling
31960Sstevel@tonic-gate * joinset.
31970Sstevel@tonic-gate */
31980Sstevel@tonic-gate if (!(args->flags & MNSET_IN_RECONFIG)) {
31990Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
32000Sstevel@tonic-gate return (TRUE);
32010Sstevel@tonic-gate }
32020Sstevel@tonic-gate
32030Sstevel@tonic-gate /* doit */
32040Sstevel@tonic-gate joinset(args->sp, args->flags, ep);
32050Sstevel@tonic-gate
32060Sstevel@tonic-gate err = svc_fini(ep);
32070Sstevel@tonic-gate
32080Sstevel@tonic-gate return (TRUE);
32090Sstevel@tonic-gate }
32100Sstevel@tonic-gate
32110Sstevel@tonic-gate bool_t
mdrpc_joinset_2_svc(mdrpc_sp_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32120Sstevel@tonic-gate mdrpc_joinset_2_svc(
32130Sstevel@tonic-gate mdrpc_sp_flags_2_args *args,
32140Sstevel@tonic-gate mdrpc_generic_res *res,
32150Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
32160Sstevel@tonic-gate )
32170Sstevel@tonic-gate {
32187159Sabalfour (void) memset(res, 0, sizeof (*res));
32190Sstevel@tonic-gate switch (args->rev) {
32207084Sachimm case MD_METAD_ARGS_REV_1:
32210Sstevel@tonic-gate return (mdrpc_joinset_common(
32220Sstevel@tonic-gate &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp));
32237084Sachimm default:
32240Sstevel@tonic-gate return (FALSE);
32250Sstevel@tonic-gate }
32260Sstevel@tonic-gate }
32270Sstevel@tonic-gate
32280Sstevel@tonic-gate static void
withdrawset(mdsetname_t * sp,md_error_t * ep)32290Sstevel@tonic-gate withdrawset(
32300Sstevel@tonic-gate mdsetname_t *sp,
32310Sstevel@tonic-gate md_error_t *ep
32320Sstevel@tonic-gate )
32330Sstevel@tonic-gate {
32340Sstevel@tonic-gate mdsetname_t *my_sp;
32350Sstevel@tonic-gate
32360Sstevel@tonic-gate if ((my_sp = metasetname(sp->setname, ep)) == NULL)
32370Sstevel@tonic-gate return;
32380Sstevel@tonic-gate
32390Sstevel@tonic-gate (void) halt_set(my_sp, ep);
32400Sstevel@tonic-gate }
32410Sstevel@tonic-gate
32420Sstevel@tonic-gate /*
32430Sstevel@tonic-gate * Have this node withdraw from set.
32440Sstevel@tonic-gate * In response to a failure that occurred
32450Sstevel@tonic-gate * on the client after a joinset.
32460Sstevel@tonic-gate */
32470Sstevel@tonic-gate bool_t
mdrpc_withdrawset_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32480Sstevel@tonic-gate mdrpc_withdrawset_common(
32490Sstevel@tonic-gate mdrpc_sp_args *args,
32500Sstevel@tonic-gate mdrpc_generic_res *res,
32510Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
32520Sstevel@tonic-gate )
32530Sstevel@tonic-gate {
32540Sstevel@tonic-gate md_error_t *ep = &res->status;
32550Sstevel@tonic-gate int err;
32560Sstevel@tonic-gate int op_mode = W_OK;
32570Sstevel@tonic-gate
32580Sstevel@tonic-gate /* setup, check permissions */
32590Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
32600Sstevel@tonic-gate return (FALSE);
32610Sstevel@tonic-gate else if (err != 0)
32620Sstevel@tonic-gate return (TRUE);
32630Sstevel@tonic-gate
32640Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
32650Sstevel@tonic-gate return (TRUE);
32660Sstevel@tonic-gate
32670Sstevel@tonic-gate /* doit */
32680Sstevel@tonic-gate withdrawset(args->sp, ep);
32690Sstevel@tonic-gate
32700Sstevel@tonic-gate err = svc_fini(ep);
32710Sstevel@tonic-gate
32720Sstevel@tonic-gate return (TRUE);
32730Sstevel@tonic-gate }
32740Sstevel@tonic-gate
32750Sstevel@tonic-gate bool_t
mdrpc_withdrawset_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32760Sstevel@tonic-gate mdrpc_withdrawset_2_svc(
32770Sstevel@tonic-gate mdrpc_sp_2_args *args,
32780Sstevel@tonic-gate mdrpc_generic_res *res,
32790Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
32800Sstevel@tonic-gate )
32810Sstevel@tonic-gate {
32827159Sabalfour (void) memset(res, 0, sizeof (*res));
32830Sstevel@tonic-gate switch (args->rev) {
32847084Sachimm case MD_METAD_ARGS_REV_1:
32850Sstevel@tonic-gate return (mdrpc_withdrawset_common(
32860Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
32877084Sachimm default:
32880Sstevel@tonic-gate return (FALSE);
32890Sstevel@tonic-gate }
32900Sstevel@tonic-gate }
32910Sstevel@tonic-gate
32920Sstevel@tonic-gate static mhd_mhiargs_t *
gtimeout(mdsetname_t * sp,md_error_t * ep)32930Sstevel@tonic-gate gtimeout(mdsetname_t *sp, md_error_t *ep)
32940Sstevel@tonic-gate {
32950Sstevel@tonic-gate md_set_record *sr;
32960Sstevel@tonic-gate mhd_mhiargs_t *mhiargs;
32970Sstevel@tonic-gate
32980Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
32990Sstevel@tonic-gate return (NULL);
33000Sstevel@tonic-gate
33010Sstevel@tonic-gate mhiargs = Zalloc(sizeof (*mhiargs));
33020Sstevel@tonic-gate *mhiargs = sr->sr_mhiargs;
33030Sstevel@tonic-gate
33040Sstevel@tonic-gate free_sr(sr);
33050Sstevel@tonic-gate return (mhiargs);
33060Sstevel@tonic-gate }
33070Sstevel@tonic-gate
33080Sstevel@tonic-gate /*
33090Sstevel@tonic-gate * Get the MH timeout values for this set.
33100Sstevel@tonic-gate */
33110Sstevel@tonic-gate bool_t
mdrpc_gtimeout_common(mdrpc_sp_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33120Sstevel@tonic-gate mdrpc_gtimeout_common(
33130Sstevel@tonic-gate mdrpc_sp_args *args,
33140Sstevel@tonic-gate mdrpc_gtimeout_res *res,
33150Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33160Sstevel@tonic-gate )
33170Sstevel@tonic-gate {
33180Sstevel@tonic-gate md_error_t *ep = &res->status;
33190Sstevel@tonic-gate int err;
33200Sstevel@tonic-gate int op_mode = R_OK;
33210Sstevel@tonic-gate
33220Sstevel@tonic-gate /* setup, check permissions */
33230Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
33240Sstevel@tonic-gate return (FALSE);
33250Sstevel@tonic-gate else if (err != 0)
33260Sstevel@tonic-gate return (TRUE);
33270Sstevel@tonic-gate
33280Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
33290Sstevel@tonic-gate return (TRUE);
33300Sstevel@tonic-gate
33310Sstevel@tonic-gate /* doit */
33320Sstevel@tonic-gate res->mhiargsp = gtimeout(args->sp, ep);
33330Sstevel@tonic-gate
33340Sstevel@tonic-gate err = svc_fini(ep);
33350Sstevel@tonic-gate
33360Sstevel@tonic-gate return (TRUE);
33370Sstevel@tonic-gate }
33380Sstevel@tonic-gate
33390Sstevel@tonic-gate bool_t
mdrpc_gtimeout_1_svc(mdrpc_sp_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33400Sstevel@tonic-gate mdrpc_gtimeout_1_svc(
33410Sstevel@tonic-gate mdrpc_sp_args *args,
33420Sstevel@tonic-gate mdrpc_gtimeout_res *res,
33430Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33440Sstevel@tonic-gate )
33450Sstevel@tonic-gate {
33467159Sabalfour (void) memset(res, 0, sizeof (*res));
33470Sstevel@tonic-gate return (mdrpc_gtimeout_common(args, res, rqstp));
33480Sstevel@tonic-gate }
33490Sstevel@tonic-gate
33500Sstevel@tonic-gate bool_t
mdrpc_gtimeout_2_svc(mdrpc_sp_2_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33510Sstevel@tonic-gate mdrpc_gtimeout_2_svc(
33520Sstevel@tonic-gate mdrpc_sp_2_args *args,
33530Sstevel@tonic-gate mdrpc_gtimeout_res *res,
33540Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33550Sstevel@tonic-gate )
33560Sstevel@tonic-gate {
33577159Sabalfour (void) memset(res, 0, sizeof (*res));
33580Sstevel@tonic-gate switch (args->rev) {
33597084Sachimm case MD_METAD_ARGS_REV_1:
33600Sstevel@tonic-gate return (mdrpc_gtimeout_common(
33610Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
33627084Sachimm default:
33630Sstevel@tonic-gate return (FALSE);
33640Sstevel@tonic-gate }
33650Sstevel@tonic-gate }
33660Sstevel@tonic-gate
33670Sstevel@tonic-gate /*
33680Sstevel@tonic-gate * return the official host name for the callee
33690Sstevel@tonic-gate */
33700Sstevel@tonic-gate /*ARGSUSED*/
33710Sstevel@tonic-gate bool_t
mdrpc_hostname_common(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)33720Sstevel@tonic-gate mdrpc_hostname_common(
33730Sstevel@tonic-gate mdrpc_null_args *args,
33740Sstevel@tonic-gate mdrpc_hostname_res *res,
33750Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33760Sstevel@tonic-gate )
33770Sstevel@tonic-gate {
33780Sstevel@tonic-gate md_error_t *ep = &res->status;
33790Sstevel@tonic-gate int err;
33800Sstevel@tonic-gate int op_mode = R_OK;
33810Sstevel@tonic-gate
33820Sstevel@tonic-gate /* setup, check permissions */
33830Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
33840Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
33850Sstevel@tonic-gate return (FALSE);
33860Sstevel@tonic-gate else if (err != 0)
33870Sstevel@tonic-gate return (TRUE);
33880Sstevel@tonic-gate
33890Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
33900Sstevel@tonic-gate return (TRUE);
33910Sstevel@tonic-gate
33920Sstevel@tonic-gate /* doit */
33930Sstevel@tonic-gate res->hostname = Strdup(mynode());
33940Sstevel@tonic-gate
33950Sstevel@tonic-gate err = svc_fini(ep);
33960Sstevel@tonic-gate
33970Sstevel@tonic-gate return (TRUE);
33980Sstevel@tonic-gate }
33990Sstevel@tonic-gate
34000Sstevel@tonic-gate bool_t
mdrpc_hostname_1_svc(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)34010Sstevel@tonic-gate mdrpc_hostname_1_svc(
34020Sstevel@tonic-gate mdrpc_null_args *args,
34030Sstevel@tonic-gate mdrpc_hostname_res *res,
34040Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34050Sstevel@tonic-gate )
34060Sstevel@tonic-gate {
34070Sstevel@tonic-gate return (mdrpc_hostname_common(args, res, rqstp));
34080Sstevel@tonic-gate }
34090Sstevel@tonic-gate
34100Sstevel@tonic-gate bool_t
mdrpc_hostname_2_svc(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)34110Sstevel@tonic-gate mdrpc_hostname_2_svc(
34120Sstevel@tonic-gate mdrpc_null_args *args,
34130Sstevel@tonic-gate mdrpc_hostname_res *res,
34140Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34150Sstevel@tonic-gate )
34160Sstevel@tonic-gate {
34170Sstevel@tonic-gate return (mdrpc_hostname_common(args, res, rqstp));
34180Sstevel@tonic-gate }
34190Sstevel@tonic-gate
34200Sstevel@tonic-gate /*
34210Sstevel@tonic-gate * return a response
34220Sstevel@tonic-gate */
34230Sstevel@tonic-gate /*ARGSUSED*/
34240Sstevel@tonic-gate bool_t
mdrpc_nullproc_common(void * args,md_error_t * ep,struct svc_req * rqstp)34250Sstevel@tonic-gate mdrpc_nullproc_common(
34260Sstevel@tonic-gate void *args,
34270Sstevel@tonic-gate md_error_t *ep,
34280Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34290Sstevel@tonic-gate )
34300Sstevel@tonic-gate {
34310Sstevel@tonic-gate *ep = mdnullerror;
34320Sstevel@tonic-gate /* do nothing */
34330Sstevel@tonic-gate return (TRUE);
34340Sstevel@tonic-gate }
34350Sstevel@tonic-gate
34360Sstevel@tonic-gate bool_t
mdrpc_nullproc_1_svc(void * args,md_error_t * ep,struct svc_req * rqstp)34370Sstevel@tonic-gate mdrpc_nullproc_1_svc(
34380Sstevel@tonic-gate void *args,
34390Sstevel@tonic-gate md_error_t *ep,
34400Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34410Sstevel@tonic-gate )
34420Sstevel@tonic-gate {
34430Sstevel@tonic-gate return (mdrpc_nullproc_common(args, ep, rqstp));
34440Sstevel@tonic-gate }
34450Sstevel@tonic-gate
34460Sstevel@tonic-gate bool_t
mdrpc_nullproc_2_svc(void * args,md_error_t * ep,struct svc_req * rqstp)34470Sstevel@tonic-gate mdrpc_nullproc_2_svc(
34480Sstevel@tonic-gate void *args,
34490Sstevel@tonic-gate md_error_t *ep,
34500Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34510Sstevel@tonic-gate )
34520Sstevel@tonic-gate {
34530Sstevel@tonic-gate return (mdrpc_nullproc_common(args, ep, rqstp));
34540Sstevel@tonic-gate }
34550Sstevel@tonic-gate
34560Sstevel@tonic-gate /*
34570Sstevel@tonic-gate * determine if the caller owns the set.
34580Sstevel@tonic-gate */
34590Sstevel@tonic-gate bool_t
mdrpc_ownset_common(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)34600Sstevel@tonic-gate mdrpc_ownset_common(
34610Sstevel@tonic-gate mdrpc_sp_args *args,
34620Sstevel@tonic-gate mdrpc_bool_res *res,
34630Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34640Sstevel@tonic-gate )
34650Sstevel@tonic-gate {
34660Sstevel@tonic-gate md_error_t *ep = &res->status;
34670Sstevel@tonic-gate int err;
34680Sstevel@tonic-gate int op_mode = R_OK;
34690Sstevel@tonic-gate
34700Sstevel@tonic-gate /* setup, check permissions */
34710Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
34720Sstevel@tonic-gate return (FALSE);
34730Sstevel@tonic-gate else if (err != 0)
34740Sstevel@tonic-gate return (TRUE);
34750Sstevel@tonic-gate
34760Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
34770Sstevel@tonic-gate return (TRUE);
34780Sstevel@tonic-gate
34790Sstevel@tonic-gate /* doit */
34800Sstevel@tonic-gate if (s_ownset(args->sp->setno, ep))
34810Sstevel@tonic-gate res->value = TRUE;
34820Sstevel@tonic-gate else
34830Sstevel@tonic-gate res->value = FALSE;
34840Sstevel@tonic-gate
34850Sstevel@tonic-gate err = svc_fini(ep);
34860Sstevel@tonic-gate
34870Sstevel@tonic-gate return (TRUE);
34880Sstevel@tonic-gate }
34890Sstevel@tonic-gate
34900Sstevel@tonic-gate bool_t
mdrpc_ownset_1_svc(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)34910Sstevel@tonic-gate mdrpc_ownset_1_svc(
34920Sstevel@tonic-gate mdrpc_sp_args *args,
34930Sstevel@tonic-gate mdrpc_bool_res *res,
34940Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34950Sstevel@tonic-gate )
34960Sstevel@tonic-gate {
34977159Sabalfour (void) memset(res, 0, sizeof (*res));
34980Sstevel@tonic-gate return (mdrpc_ownset_common(args, res, rqstp));
34990Sstevel@tonic-gate }
35000Sstevel@tonic-gate
35010Sstevel@tonic-gate bool_t
mdrpc_ownset_2_svc(mdrpc_sp_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)35020Sstevel@tonic-gate mdrpc_ownset_2_svc(
35030Sstevel@tonic-gate mdrpc_sp_2_args *args,
35040Sstevel@tonic-gate mdrpc_bool_res *res,
35050Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
35060Sstevel@tonic-gate )
35070Sstevel@tonic-gate {
35087159Sabalfour (void) memset(res, 0, sizeof (*res));
35090Sstevel@tonic-gate switch (args->rev) {
35107084Sachimm case MD_METAD_ARGS_REV_1:
35110Sstevel@tonic-gate return (mdrpc_ownset_common(
35120Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
35137084Sachimm default:
35140Sstevel@tonic-gate return (FALSE);
35150Sstevel@tonic-gate }
35160Sstevel@tonic-gate }
35170Sstevel@tonic-gate
35180Sstevel@tonic-gate static int
setnameok(char * setname,md_error_t * ep)35190Sstevel@tonic-gate setnameok(char *setname, md_error_t *ep)
35200Sstevel@tonic-gate {
35210Sstevel@tonic-gate int rval = 0;
35220Sstevel@tonic-gate struct stat statb;
35230Sstevel@tonic-gate md_set_record *sr = NULL;
35240Sstevel@tonic-gate char *setlink = NULL;
35250Sstevel@tonic-gate
35260Sstevel@tonic-gate setlink = Strdup("/dev/md/");
35270Sstevel@tonic-gate setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1);
35280Sstevel@tonic-gate (void) strcat(setlink, setname);
35290Sstevel@tonic-gate
35300Sstevel@tonic-gate if (lstat(setlink, &statb) == -1) {
35310Sstevel@tonic-gate /*
35320Sstevel@tonic-gate * If lstat() fails with ENOENT, setname is OK, if it
35330Sstevel@tonic-gate * fails for other than that, we fail the RPC
35340Sstevel@tonic-gate */
35350Sstevel@tonic-gate if (errno == ENOENT) {
35360Sstevel@tonic-gate rval = 1;
35370Sstevel@tonic-gate goto out;
35380Sstevel@tonic-gate }
35390Sstevel@tonic-gate
35400Sstevel@tonic-gate (void) mdsyserror(ep, errno, setlink);
35410Sstevel@tonic-gate goto out;
35420Sstevel@tonic-gate }
35430Sstevel@tonic-gate
35440Sstevel@tonic-gate /*
35450Sstevel@tonic-gate * If the lstat() succeeded, then we see what type of object
35460Sstevel@tonic-gate * we are dealing with, if it is a symlink, we do some further
35470Sstevel@tonic-gate * checking, if it is not a symlink, then we return an
35480Sstevel@tonic-gate * indication that the set name is NOT acceptable.
35490Sstevel@tonic-gate */
35500Sstevel@tonic-gate if (! S_ISLNK(statb.st_mode))
35510Sstevel@tonic-gate goto out;
35520Sstevel@tonic-gate
35530Sstevel@tonic-gate /*
35540Sstevel@tonic-gate * We look up the setname to see if there is a set
35550Sstevel@tonic-gate * with that name, if there is, then we return
35560Sstevel@tonic-gate * an indication that the set name is NOT acceptable.
35570Sstevel@tonic-gate */
35580Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) != NULL)
35590Sstevel@tonic-gate goto out;
35600Sstevel@tonic-gate
35610Sstevel@tonic-gate if (! mdiserror(ep, MDE_NO_SET))
35620Sstevel@tonic-gate goto out;
35630Sstevel@tonic-gate
35640Sstevel@tonic-gate mdclrerror(ep);
35650Sstevel@tonic-gate
35660Sstevel@tonic-gate rval = 1;
35670Sstevel@tonic-gate out:
35680Sstevel@tonic-gate if (sr != NULL)
35690Sstevel@tonic-gate free_sr(sr);
35700Sstevel@tonic-gate Free(setlink);
35710Sstevel@tonic-gate return (rval);
35720Sstevel@tonic-gate }
35730Sstevel@tonic-gate
35740Sstevel@tonic-gate /*
35750Sstevel@tonic-gate * Make sure the name of the set is OK.
35760Sstevel@tonic-gate */
35770Sstevel@tonic-gate bool_t
mdrpc_setnameok_common(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)35780Sstevel@tonic-gate mdrpc_setnameok_common(
35790Sstevel@tonic-gate mdrpc_sp_args *args, /* device name */
35800Sstevel@tonic-gate mdrpc_bool_res *res,
35810Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
35820Sstevel@tonic-gate )
35830Sstevel@tonic-gate {
35840Sstevel@tonic-gate md_error_t *ep = &res->status;
35850Sstevel@tonic-gate int err;
35860Sstevel@tonic-gate int op_mode = R_OK;
35870Sstevel@tonic-gate
35880Sstevel@tonic-gate /* setup, check permissions */
35890Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
35900Sstevel@tonic-gate return (FALSE);
35910Sstevel@tonic-gate else if (err != 0)
35920Sstevel@tonic-gate return (TRUE);
35930Sstevel@tonic-gate
35940Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
35950Sstevel@tonic-gate return (TRUE);
35960Sstevel@tonic-gate
35970Sstevel@tonic-gate /* doit */
35980Sstevel@tonic-gate res->value = setnameok(args->sp->setname, ep);
35990Sstevel@tonic-gate
36000Sstevel@tonic-gate err = svc_fini(ep);
36010Sstevel@tonic-gate
36020Sstevel@tonic-gate return (TRUE);
36030Sstevel@tonic-gate }
36040Sstevel@tonic-gate
36050Sstevel@tonic-gate bool_t
mdrpc_setnameok_1_svc(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36060Sstevel@tonic-gate mdrpc_setnameok_1_svc(
36070Sstevel@tonic-gate mdrpc_sp_args *args, /* device name */
36080Sstevel@tonic-gate mdrpc_bool_res *res,
36090Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36100Sstevel@tonic-gate )
36110Sstevel@tonic-gate {
36127159Sabalfour (void) memset(res, 0, sizeof (*res));
36130Sstevel@tonic-gate return (mdrpc_setnameok_common(args, res, rqstp));
36140Sstevel@tonic-gate }
36150Sstevel@tonic-gate
36160Sstevel@tonic-gate bool_t
mdrpc_setnameok_2_svc(mdrpc_sp_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36170Sstevel@tonic-gate mdrpc_setnameok_2_svc(
36180Sstevel@tonic-gate mdrpc_sp_2_args *args, /* device name */
36190Sstevel@tonic-gate mdrpc_bool_res *res,
36200Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36210Sstevel@tonic-gate )
36220Sstevel@tonic-gate {
36237159Sabalfour (void) memset(res, 0, sizeof (*res));
36240Sstevel@tonic-gate switch (args->rev) {
36257084Sachimm case MD_METAD_ARGS_REV_1:
36260Sstevel@tonic-gate return (mdrpc_setnameok_common(
36270Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
36287084Sachimm default:
36290Sstevel@tonic-gate return (FALSE);
36300Sstevel@tonic-gate }
36310Sstevel@tonic-gate }
36320Sstevel@tonic-gate
36330Sstevel@tonic-gate /*
36340Sstevel@tonic-gate * determine if the setnumber we want to share is in use.
36350Sstevel@tonic-gate */
36360Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_common(mdrpc_setno_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36370Sstevel@tonic-gate mdrpc_setnumbusy_common(
36380Sstevel@tonic-gate mdrpc_setno_args *args,
36390Sstevel@tonic-gate mdrpc_bool_res *res,
36400Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36410Sstevel@tonic-gate )
36420Sstevel@tonic-gate {
36430Sstevel@tonic-gate md_error_t *ep = &res->status;
36440Sstevel@tonic-gate md_set_record *sr = NULL;
36450Sstevel@tonic-gate int err;
36460Sstevel@tonic-gate int op_mode = R_OK;
36470Sstevel@tonic-gate
36480Sstevel@tonic-gate /* setup, check permissions */
36490Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
36500Sstevel@tonic-gate return (FALSE);
36510Sstevel@tonic-gate else if (err != 0)
36520Sstevel@tonic-gate return (TRUE);
36530Sstevel@tonic-gate
36540Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
36550Sstevel@tonic-gate return (TRUE);
36560Sstevel@tonic-gate
36570Sstevel@tonic-gate /* doit */
36580Sstevel@tonic-gate if ((sr = getsetbynum(args->setno, ep)) != NULL) {
36590Sstevel@tonic-gate res->value = TRUE;
36600Sstevel@tonic-gate free_sr(sr);
36610Sstevel@tonic-gate return (TRUE);
36620Sstevel@tonic-gate }
36630Sstevel@tonic-gate res->value = FALSE;
36640Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET))
36650Sstevel@tonic-gate mdclrerror(ep);
36660Sstevel@tonic-gate
36670Sstevel@tonic-gate err = svc_fini(ep);
36680Sstevel@tonic-gate
36690Sstevel@tonic-gate return (TRUE);
36700Sstevel@tonic-gate }
36710Sstevel@tonic-gate
36720Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_1_svc(mdrpc_setno_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36730Sstevel@tonic-gate mdrpc_setnumbusy_1_svc(
36740Sstevel@tonic-gate mdrpc_setno_args *args,
36750Sstevel@tonic-gate mdrpc_bool_res *res,
36760Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36770Sstevel@tonic-gate )
36780Sstevel@tonic-gate {
36797159Sabalfour (void) memset(res, 0, sizeof (*res));
36800Sstevel@tonic-gate return (mdrpc_setnumbusy_common(args, res, rqstp));
36810Sstevel@tonic-gate }
36820Sstevel@tonic-gate
36830Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_2_svc(mdrpc_setno_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36840Sstevel@tonic-gate mdrpc_setnumbusy_2_svc(
36850Sstevel@tonic-gate mdrpc_setno_2_args *args,
36860Sstevel@tonic-gate mdrpc_bool_res *res,
36870Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36880Sstevel@tonic-gate )
36890Sstevel@tonic-gate {
36907159Sabalfour (void) memset(res, 0, sizeof (*res));
36910Sstevel@tonic-gate switch (args->rev) {
36927084Sachimm case MD_METAD_ARGS_REV_1:
36930Sstevel@tonic-gate return (mdrpc_setnumbusy_common(
36940Sstevel@tonic-gate &args->mdrpc_setno_2_args_u.rev1, res, rqstp));
36957084Sachimm default:
36960Sstevel@tonic-gate return (FALSE);
36970Sstevel@tonic-gate }
36980Sstevel@tonic-gate }
36990Sstevel@tonic-gate
37000Sstevel@tonic-gate static void
stimeout(mdsetname_t * sp,mhd_mhiargs_t * mhiargsp,int version,md_error_t * ep)37010Sstevel@tonic-gate stimeout(
37020Sstevel@tonic-gate mdsetname_t *sp,
37030Sstevel@tonic-gate mhd_mhiargs_t *mhiargsp,
37040Sstevel@tonic-gate int version, /* RPC version of calling routine */
37050Sstevel@tonic-gate md_error_t *ep
37060Sstevel@tonic-gate )
37070Sstevel@tonic-gate {
37080Sstevel@tonic-gate mddb_userreq_t req;
37090Sstevel@tonic-gate md_set_record *sr;
37100Sstevel@tonic-gate
37110Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
37120Sstevel@tonic-gate return;
37130Sstevel@tonic-gate
37140Sstevel@tonic-gate sr->sr_mhiargs = *mhiargsp;
37150Sstevel@tonic-gate
37160Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
37170Sstevel@tonic-gate
37180Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
37190Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
37200Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
37210Sstevel@tonic-gate req.ur_size = sizeof (struct md_mnset_record);
37220Sstevel@tonic-gate } else {
37230Sstevel@tonic-gate req.ur_size = sizeof (*sr);
37240Sstevel@tonic-gate }
37250Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
37260Sstevel@tonic-gate
37270Sstevel@tonic-gate /*
37280Sstevel@tonic-gate * Cluster nodename support
37290Sstevel@tonic-gate * Convert nodename -> nodeid
37300Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
37310Sstevel@tonic-gate * both the nodeid and name.
37320Sstevel@tonic-gate */
37330Sstevel@tonic-gate if ((version == METAD_VERSION) ||
37340Sstevel@tonic-gate ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
37350Sstevel@tonic-gate sdssc_cm_sr_nm2nid(sr);
37360Sstevel@tonic-gate
37370Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
37380Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
37390Sstevel@tonic-gate return;
37400Sstevel@tonic-gate }
37410Sstevel@tonic-gate
37420Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
37430Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid)
37440Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
37450Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
37460Sstevel@tonic-gate
37470Sstevel@tonic-gate /*
37480Sstevel@tonic-gate * Cluster nodename support
37490Sstevel@tonic-gate * Convert nodeid -> nodename
37500Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
37510Sstevel@tonic-gate * both the nodeid and name.
37520Sstevel@tonic-gate */
37530Sstevel@tonic-gate if ((version == METAD_VERSION) ||
37540Sstevel@tonic-gate ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
37550Sstevel@tonic-gate sdssc_cm_sr_nid2nm(sr);
37560Sstevel@tonic-gate
37570Sstevel@tonic-gate free_sr(sr);
37580Sstevel@tonic-gate }
37590Sstevel@tonic-gate
37600Sstevel@tonic-gate /*
37610Sstevel@tonic-gate * Set MH ioctl timeout values.
37620Sstevel@tonic-gate */
37630Sstevel@tonic-gate bool_t
mdrpc_stimeout_common(mdrpc_stimeout_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)37640Sstevel@tonic-gate mdrpc_stimeout_common(
37650Sstevel@tonic-gate mdrpc_stimeout_args *args,
37660Sstevel@tonic-gate mdrpc_generic_res *res,
37670Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
37680Sstevel@tonic-gate int version /* RPC version */
37690Sstevel@tonic-gate )
37700Sstevel@tonic-gate {
37710Sstevel@tonic-gate md_error_t *ep = &res->status;
37720Sstevel@tonic-gate int err;
37730Sstevel@tonic-gate int op_mode = W_OK;
37740Sstevel@tonic-gate
37750Sstevel@tonic-gate /* setup, check permissions */
37760Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
37770Sstevel@tonic-gate return (FALSE);
37780Sstevel@tonic-gate else if (err != 0)
37790Sstevel@tonic-gate return (TRUE);
37800Sstevel@tonic-gate
37810Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
37820Sstevel@tonic-gate return (TRUE);
37830Sstevel@tonic-gate
37840Sstevel@tonic-gate /* doit */
37850Sstevel@tonic-gate stimeout(args->sp, args->mhiargsp, version, ep);
37860Sstevel@tonic-gate
37870Sstevel@tonic-gate err = svc_fini(ep);
37880Sstevel@tonic-gate
37890Sstevel@tonic-gate return (TRUE);
37900Sstevel@tonic-gate }
37910Sstevel@tonic-gate
37920Sstevel@tonic-gate bool_t
mdrpc_stimeout_1_svc(mdrpc_stimeout_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)37930Sstevel@tonic-gate mdrpc_stimeout_1_svc(
37940Sstevel@tonic-gate mdrpc_stimeout_args *args,
37950Sstevel@tonic-gate mdrpc_generic_res *res,
37960Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
37970Sstevel@tonic-gate )
37980Sstevel@tonic-gate {
37997159Sabalfour (void) memset(res, 0, sizeof (*res));
38000Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
38010Sstevel@tonic-gate return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION));
38020Sstevel@tonic-gate }
38030Sstevel@tonic-gate
38040Sstevel@tonic-gate bool_t
mdrpc_stimeout_2_svc(mdrpc_stimeout_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)38050Sstevel@tonic-gate mdrpc_stimeout_2_svc(
38060Sstevel@tonic-gate mdrpc_stimeout_2_args *args,
38070Sstevel@tonic-gate mdrpc_generic_res *res,
38080Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
38090Sstevel@tonic-gate )
38100Sstevel@tonic-gate {
38117159Sabalfour (void) memset(res, 0, sizeof (*res));
38120Sstevel@tonic-gate switch (args->rev) {
38137084Sachimm case MD_METAD_ARGS_REV_1:
38140Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
38150Sstevel@tonic-gate return (mdrpc_stimeout_common(
38160Sstevel@tonic-gate &args->mdrpc_stimeout_2_args_u.rev1, res,
38170Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
38187084Sachimm default:
38190Sstevel@tonic-gate return (FALSE);
38200Sstevel@tonic-gate }
38210Sstevel@tonic-gate }
38220Sstevel@tonic-gate
38230Sstevel@tonic-gate static void
upd_dr_dbinfo(mdsetname_t * sp,md_drive_desc * dd,md_error_t * ep)38240Sstevel@tonic-gate upd_dr_dbinfo(
38250Sstevel@tonic-gate mdsetname_t *sp,
38260Sstevel@tonic-gate md_drive_desc *dd,
38270Sstevel@tonic-gate md_error_t *ep
38280Sstevel@tonic-gate )
38290Sstevel@tonic-gate {
38300Sstevel@tonic-gate mdsetname_t *local_sp;
38310Sstevel@tonic-gate md_set_record *sr;
38320Sstevel@tonic-gate md_drive_record *dr;
38330Sstevel@tonic-gate md_drive_desc *p;
38340Sstevel@tonic-gate mddrivename_t *dn, *dn1;
38350Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
38360Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
38370Sstevel@tonic-gate int devid_same = -1;
38380Sstevel@tonic-gate side_t sideno;
38390Sstevel@tonic-gate int using_devid = 0;
38400Sstevel@tonic-gate
38410Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
38420Sstevel@tonic-gate return;
38430Sstevel@tonic-gate
38440Sstevel@tonic-gate metaflushsetname(local_sp);
38450Sstevel@tonic-gate
38460Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
38470Sstevel@tonic-gate return;
38480Sstevel@tonic-gate
38490Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
38500Sstevel@tonic-gate return;
38510Sstevel@tonic-gate
38520Sstevel@tonic-gate if (dd->dd_dnp == NULL)
38530Sstevel@tonic-gate return;
38540Sstevel@tonic-gate
38550Sstevel@tonic-gate /*
38560Sstevel@tonic-gate * The system is either all devid or all
38570Sstevel@tonic-gate * non-devid so we determine this by looking
38580Sstevel@tonic-gate * at the first item in the list.
38590Sstevel@tonic-gate *
38600Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
38610Sstevel@tonic-gate * points to a '' string of devid. We need to check this
38620Sstevel@tonic-gate * before set the using_devid.
38630Sstevel@tonic-gate */
38640Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
38650Sstevel@tonic-gate (!(MD_MNSET_REC(sr))))
38660Sstevel@tonic-gate using_devid = 1;
38670Sstevel@tonic-gate
38680Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
38690Sstevel@tonic-gate dn = p->dd_dnp;
38700Sstevel@tonic-gate devid_remote = NULL;
38710Sstevel@tonic-gate
38720Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
38730Sstevel@tonic-gate using_devid) {
38740Sstevel@tonic-gate /*
38750Sstevel@tonic-gate * We have a devid so use it.
38760Sstevel@tonic-gate */
38770Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
38780Sstevel@tonic-gate }
38790Sstevel@tonic-gate
38800Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
38810Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
38820Sstevel@tonic-gate /* something went really wrong. Can't process */
38830Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
38840Sstevel@tonic-gate mynode(), dn->cname, sp->setname);
38850Sstevel@tonic-gate return;
38860Sstevel@tonic-gate }
38870Sstevel@tonic-gate
38880Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
38890Sstevel@tonic-gate devid_same = -1;
38900Sstevel@tonic-gate
38910Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno,
38920Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep);
38930Sstevel@tonic-gate
38940Sstevel@tonic-gate if (dn1 == NULL) {
38950Sstevel@tonic-gate if (devid_remote)
38960Sstevel@tonic-gate devid_free(devid_remote);
38970Sstevel@tonic-gate goto out;
38980Sstevel@tonic-gate }
38990Sstevel@tonic-gate
39000Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) {
39010Sstevel@tonic-gate if (devid_str_decode(dn1->devid, &devid_local,
39020Sstevel@tonic-gate NULL) == 0) {
39030Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
39040Sstevel@tonic-gate devid_local);
39050Sstevel@tonic-gate devid_free(devid_local);
39060Sstevel@tonic-gate }
39070Sstevel@tonic-gate }
39080Sstevel@tonic-gate
39090Sstevel@tonic-gate if (using_devid && devid_same == 0)
39100Sstevel@tonic-gate break;
39110Sstevel@tonic-gate
39120Sstevel@tonic-gate if (!using_devid &&
39130Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)
39140Sstevel@tonic-gate break;
39150Sstevel@tonic-gate }
39160Sstevel@tonic-gate
39170Sstevel@tonic-gate if (dr) {
39180Sstevel@tonic-gate /* Adjust the fields in the copy */
39190Sstevel@tonic-gate dr->dr_dbcnt = p->dd_dbcnt;
39200Sstevel@tonic-gate dr->dr_dbsize = p->dd_dbsize;
39210Sstevel@tonic-gate }
39220Sstevel@tonic-gate if (devid_remote)
39230Sstevel@tonic-gate devid_free(devid_remote);
39240Sstevel@tonic-gate }
39250Sstevel@tonic-gate
39260Sstevel@tonic-gate
39270Sstevel@tonic-gate out:
39280Sstevel@tonic-gate commitset(sr, FALSE, ep);
39290Sstevel@tonic-gate free_sr(sr);
39300Sstevel@tonic-gate }
39310Sstevel@tonic-gate
39320Sstevel@tonic-gate /*
39330Sstevel@tonic-gate * update the database count and size field of drive records.
39340Sstevel@tonic-gate */
39350Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)39360Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_common(
39370Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args,
39380Sstevel@tonic-gate mdrpc_generic_res *res,
39390Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
39400Sstevel@tonic-gate )
39410Sstevel@tonic-gate {
39420Sstevel@tonic-gate md_error_t *ep = &res->status;
39430Sstevel@tonic-gate int err;
39440Sstevel@tonic-gate int op_mode = W_OK;
39450Sstevel@tonic-gate
39460Sstevel@tonic-gate /* setup, check permissions */
39470Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
39480Sstevel@tonic-gate return (FALSE);
39490Sstevel@tonic-gate else if (err != 0)
39500Sstevel@tonic-gate return (TRUE);
39510Sstevel@tonic-gate
39520Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
39530Sstevel@tonic-gate return (TRUE);
39540Sstevel@tonic-gate
39550Sstevel@tonic-gate /* doit */
39560Sstevel@tonic-gate upd_dr_dbinfo(args->sp, args->drivedescs, ep);
39570Sstevel@tonic-gate
39580Sstevel@tonic-gate err = svc_fini(ep);
39590Sstevel@tonic-gate
39600Sstevel@tonic-gate return (TRUE);
39610Sstevel@tonic-gate }
39620Sstevel@tonic-gate
39630Sstevel@tonic-gate /*
39640Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
39650Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
39660Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
39670Sstevel@tonic-gate */
39680Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)39690Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_1_svc(
39700Sstevel@tonic-gate mdrpc_drives_args *args,
39710Sstevel@tonic-gate mdrpc_generic_res *res,
39720Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
39730Sstevel@tonic-gate )
39740Sstevel@tonic-gate {
39750Sstevel@tonic-gate bool_t retval;
39760Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args;
39770Sstevel@tonic-gate
39780Sstevel@tonic-gate /* allocate memory */
39790Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
39807159Sabalfour (void) memset(res, 0, sizeof (*res));
39810Sstevel@tonic-gate
39820Sstevel@tonic-gate /* build args */
39830Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
39840Sstevel@tonic-gate v2_args.sp = args->sp;
39850Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
39860Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
39870Sstevel@tonic-gate v2_args.timestamp = args->timestamp;
39880Sstevel@tonic-gate v2_args.genid = args->genid;
39890Sstevel@tonic-gate
39900Sstevel@tonic-gate retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp);
39910Sstevel@tonic-gate
39920Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
39930Sstevel@tonic-gate
39940Sstevel@tonic-gate return (retval);
39950Sstevel@tonic-gate }
39960Sstevel@tonic-gate
39970Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)39980Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_2_svc(
39990Sstevel@tonic-gate mdrpc_drives_2_args *args,
40000Sstevel@tonic-gate mdrpc_generic_res *res,
40010Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
40020Sstevel@tonic-gate )
40030Sstevel@tonic-gate {
40047159Sabalfour (void) memset(res, 0, sizeof (*res));
40050Sstevel@tonic-gate switch (args->rev) {
40067084Sachimm case MD_METAD_ARGS_REV_1:
40070Sstevel@tonic-gate return (mdrpc_upd_dr_dbinfo_common(
40080Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
40097084Sachimm default:
40100Sstevel@tonic-gate return (FALSE);
40110Sstevel@tonic-gate }
40120Sstevel@tonic-gate }
40130Sstevel@tonic-gate
40140Sstevel@tonic-gate static void
upd_dr_flags(mdsetname_t * sp,md_drive_desc * dd,uint_t new_flags,md_error_t * ep)40150Sstevel@tonic-gate upd_dr_flags(
40160Sstevel@tonic-gate mdsetname_t *sp,
40170Sstevel@tonic-gate md_drive_desc *dd,
40180Sstevel@tonic-gate uint_t new_flags,
40190Sstevel@tonic-gate md_error_t *ep
40200Sstevel@tonic-gate )
40210Sstevel@tonic-gate {
40220Sstevel@tonic-gate mdsetname_t *local_sp;
40230Sstevel@tonic-gate md_set_record *sr;
40240Sstevel@tonic-gate md_drive_record *dr;
40250Sstevel@tonic-gate md_drive_desc *p;
40260Sstevel@tonic-gate mddrivename_t *dn, *dn1;
40270Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
40280Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
40290Sstevel@tonic-gate int devid_same = -1;
40300Sstevel@tonic-gate side_t sideno;
40310Sstevel@tonic-gate int using_devid = 0;
40320Sstevel@tonic-gate
40330Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
40340Sstevel@tonic-gate return;
40350Sstevel@tonic-gate
40360Sstevel@tonic-gate metaflushsetname(local_sp);
40370Sstevel@tonic-gate
40380Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
40390Sstevel@tonic-gate return;
40400Sstevel@tonic-gate
40410Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
40420Sstevel@tonic-gate return;
40430Sstevel@tonic-gate
40440Sstevel@tonic-gate if (dd->dd_dnp == NULL)
40450Sstevel@tonic-gate return;
40460Sstevel@tonic-gate
40470Sstevel@tonic-gate /*
40480Sstevel@tonic-gate * The system is either all devid or all
40490Sstevel@tonic-gate * non-devid so we determine this by looking
40500Sstevel@tonic-gate * at the first item in the list.
40510Sstevel@tonic-gate *
40520Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
40530Sstevel@tonic-gate * points to a '' string of devid. We need to check this
40540Sstevel@tonic-gate * before set the using_devid.
40550Sstevel@tonic-gate */
40560Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
40570Sstevel@tonic-gate (!(MD_MNSET_REC(sr))))
40580Sstevel@tonic-gate using_devid = 1;
40590Sstevel@tonic-gate
40600Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
40610Sstevel@tonic-gate dn = p->dd_dnp;
40620Sstevel@tonic-gate devid_remote = NULL;
40630Sstevel@tonic-gate
40640Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
40650Sstevel@tonic-gate using_devid) {
40660Sstevel@tonic-gate /*
40670Sstevel@tonic-gate * We have a devid so use it.
40680Sstevel@tonic-gate */
40690Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
40700Sstevel@tonic-gate }
40710Sstevel@tonic-gate
40720Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
40730Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
40740Sstevel@tonic-gate /* something went really wrong. Can't process */
40750Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
40760Sstevel@tonic-gate mynode(), dn->cname, sp->setname);
40770Sstevel@tonic-gate return;
40780Sstevel@tonic-gate }
40790Sstevel@tonic-gate
40800Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
40810Sstevel@tonic-gate devid_same = -1;
40820Sstevel@tonic-gate
40830Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno,
40840Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep);
40850Sstevel@tonic-gate
40860Sstevel@tonic-gate if (dn1 == NULL) {
40870Sstevel@tonic-gate if (devid_remote)
40880Sstevel@tonic-gate devid_free(devid_remote);
40890Sstevel@tonic-gate goto out;
40900Sstevel@tonic-gate }
40910Sstevel@tonic-gate
40920Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) {
40930Sstevel@tonic-gate if (devid_str_decode(dn1->devid,
40940Sstevel@tonic-gate &devid_local, NULL) == 0) {
40950Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
40960Sstevel@tonic-gate devid_local);
40970Sstevel@tonic-gate devid_free(devid_local);
40980Sstevel@tonic-gate }
40990Sstevel@tonic-gate }
41000Sstevel@tonic-gate
41010Sstevel@tonic-gate if (using_devid && devid_same == 0)
41020Sstevel@tonic-gate break;
41030Sstevel@tonic-gate
41040Sstevel@tonic-gate if (!using_devid &&
41050Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)
41060Sstevel@tonic-gate break;
41070Sstevel@tonic-gate }
41080Sstevel@tonic-gate
41090Sstevel@tonic-gate if (dr)
41100Sstevel@tonic-gate dr->dr_flags = new_flags;
41110Sstevel@tonic-gate if (devid_remote)
41120Sstevel@tonic-gate devid_free(devid_remote);
41130Sstevel@tonic-gate }
41140Sstevel@tonic-gate out:
41150Sstevel@tonic-gate commitset(sr, TRUE, ep);
41160Sstevel@tonic-gate free_sr(sr);
41170Sstevel@tonic-gate }
41180Sstevel@tonic-gate
41190Sstevel@tonic-gate /*
41200Sstevel@tonic-gate * update the database count and size field of drive records.
41210Sstevel@tonic-gate */
41220Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_common(mdrpc_upd_dr_flags_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)41230Sstevel@tonic-gate mdrpc_upd_dr_flags_common(
41240Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 *args,
41250Sstevel@tonic-gate mdrpc_generic_res *res,
41260Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
41270Sstevel@tonic-gate )
41280Sstevel@tonic-gate {
41290Sstevel@tonic-gate md_error_t *ep = &res->status;
41300Sstevel@tonic-gate int err;
41310Sstevel@tonic-gate int op_mode = W_OK;
41320Sstevel@tonic-gate
41330Sstevel@tonic-gate /* setup, check permissions */
41340Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
41350Sstevel@tonic-gate return (FALSE);
41360Sstevel@tonic-gate else if (err != 0)
41370Sstevel@tonic-gate return (TRUE);
41380Sstevel@tonic-gate
41390Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
41400Sstevel@tonic-gate return (TRUE);
41410Sstevel@tonic-gate
41420Sstevel@tonic-gate /* doit */
41430Sstevel@tonic-gate upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep);
41440Sstevel@tonic-gate
41450Sstevel@tonic-gate err = svc_fini(ep);
41460Sstevel@tonic-gate
41470Sstevel@tonic-gate return (TRUE);
41480Sstevel@tonic-gate }
41490Sstevel@tonic-gate
41500Sstevel@tonic-gate /*
41510Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
41520Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
41530Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
41540Sstevel@tonic-gate */
41550Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_1_svc(mdrpc_upd_dr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)41560Sstevel@tonic-gate mdrpc_upd_dr_flags_1_svc(
41570Sstevel@tonic-gate mdrpc_upd_dr_flags_args *args,
41580Sstevel@tonic-gate mdrpc_generic_res *res,
41590Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
41600Sstevel@tonic-gate )
41610Sstevel@tonic-gate {
41620Sstevel@tonic-gate bool_t retval;
41630Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 v2_args;
41640Sstevel@tonic-gate
41650Sstevel@tonic-gate /* allocate memory */
41660Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
41677159Sabalfour (void) memset(res, 0, sizeof (*res));
41680Sstevel@tonic-gate
41690Sstevel@tonic-gate /* build args */
41700Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
41710Sstevel@tonic-gate v2_args.sp = args->sp;
41720Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
41730Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
41740Sstevel@tonic-gate v2_args.new_flags = args->new_flags;
41750Sstevel@tonic-gate
41760Sstevel@tonic-gate retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp);
41770Sstevel@tonic-gate
41780Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
41790Sstevel@tonic-gate
41800Sstevel@tonic-gate return (retval);
41810Sstevel@tonic-gate }
41820Sstevel@tonic-gate
41830Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_2_svc(mdrpc_upd_dr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)41840Sstevel@tonic-gate mdrpc_upd_dr_flags_2_svc(
41850Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args *args,
41860Sstevel@tonic-gate mdrpc_generic_res *res,
41870Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
41880Sstevel@tonic-gate )
41890Sstevel@tonic-gate {
41907159Sabalfour (void) memset(res, 0, sizeof (*res));
41910Sstevel@tonic-gate switch (args->rev) {
41927084Sachimm case MD_METAD_ARGS_REV_1:
41930Sstevel@tonic-gate return (mdrpc_upd_dr_flags_common(
41940Sstevel@tonic-gate &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
41957084Sachimm default:
41960Sstevel@tonic-gate return (FALSE);
41970Sstevel@tonic-gate }
41980Sstevel@tonic-gate }
41990Sstevel@tonic-gate
42000Sstevel@tonic-gate static void
upd_sr_flags(mdsetname_t * sp,uint_t new_flags,md_error_t * ep)42010Sstevel@tonic-gate upd_sr_flags(
42020Sstevel@tonic-gate mdsetname_t *sp,
42030Sstevel@tonic-gate uint_t new_flags,
42040Sstevel@tonic-gate md_error_t *ep
42050Sstevel@tonic-gate )
42060Sstevel@tonic-gate {
42070Sstevel@tonic-gate md_set_record *sr;
42080Sstevel@tonic-gate
42090Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
42100Sstevel@tonic-gate return;
42110Sstevel@tonic-gate
42120Sstevel@tonic-gate sr->sr_flags = new_flags;
42130Sstevel@tonic-gate commitset(sr, TRUE, ep);
42140Sstevel@tonic-gate free_sr(sr);
42150Sstevel@tonic-gate }
42160Sstevel@tonic-gate
42170Sstevel@tonic-gate /*
42180Sstevel@tonic-gate * update the set record flags
42190Sstevel@tonic-gate */
42200Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_common(mdrpc_upd_sr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42210Sstevel@tonic-gate mdrpc_upd_sr_flags_common(
42220Sstevel@tonic-gate mdrpc_upd_sr_flags_args *args,
42230Sstevel@tonic-gate mdrpc_generic_res *res,
42240Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
42250Sstevel@tonic-gate )
42260Sstevel@tonic-gate {
42270Sstevel@tonic-gate md_error_t *ep = &res->status;
42280Sstevel@tonic-gate int err;
42290Sstevel@tonic-gate int op_mode = W_OK;
42300Sstevel@tonic-gate
42310Sstevel@tonic-gate /* setup, check permissions */
42320Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
42330Sstevel@tonic-gate return (FALSE);
42340Sstevel@tonic-gate else if (err != 0)
42350Sstevel@tonic-gate return (TRUE);
42360Sstevel@tonic-gate
42370Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
42380Sstevel@tonic-gate return (TRUE);
42390Sstevel@tonic-gate
42400Sstevel@tonic-gate /* doit */
42410Sstevel@tonic-gate upd_sr_flags(args->sp, args->new_flags, ep);
42420Sstevel@tonic-gate
42430Sstevel@tonic-gate err = svc_fini(ep);
42440Sstevel@tonic-gate
42450Sstevel@tonic-gate return (TRUE);
42460Sstevel@tonic-gate }
42470Sstevel@tonic-gate
42480Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_1_svc(mdrpc_upd_sr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42490Sstevel@tonic-gate mdrpc_upd_sr_flags_1_svc(
42500Sstevel@tonic-gate mdrpc_upd_sr_flags_args *args,
42510Sstevel@tonic-gate mdrpc_generic_res *res,
42520Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
42530Sstevel@tonic-gate )
42540Sstevel@tonic-gate {
42557159Sabalfour (void) memset(res, 0, sizeof (*res));
42560Sstevel@tonic-gate return (mdrpc_upd_sr_flags_common(args, res, rqstp));
42570Sstevel@tonic-gate }
42580Sstevel@tonic-gate
42590Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_2_svc(mdrpc_upd_sr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42600Sstevel@tonic-gate mdrpc_upd_sr_flags_2_svc(
42610Sstevel@tonic-gate mdrpc_upd_sr_flags_2_args *args,
42620Sstevel@tonic-gate mdrpc_generic_res *res,
42630Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
42640Sstevel@tonic-gate )
42650Sstevel@tonic-gate {
42667159Sabalfour (void) memset(res, 0, sizeof (*res));
42670Sstevel@tonic-gate switch (args->rev) {
42687084Sachimm case MD_METAD_ARGS_REV_1:
42690Sstevel@tonic-gate return (mdrpc_upd_sr_flags_common(
42700Sstevel@tonic-gate &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp));
42717084Sachimm default:
42720Sstevel@tonic-gate return (FALSE);
42730Sstevel@tonic-gate }
42740Sstevel@tonic-gate }
42750Sstevel@tonic-gate
42760Sstevel@tonic-gate /*
42770Sstevel@tonic-gate * upd_nr_flags updates the node records stored in this node's local mddb
42780Sstevel@tonic-gate * given a node desciptor list and an action. upd_nr_flags then commits
42790Sstevel@tonic-gate * the node records to the local mddb.
42800Sstevel@tonic-gate *
42810Sstevel@tonic-gate * nd - A linked list of node descriptors that describes the node records
42820Sstevel@tonic-gate * in this diskset on which the action applies.
42830Sstevel@tonic-gate * flag_action: action to be taken on node records that match the nd list.
42840Sstevel@tonic-gate * flag_action can be:
42850Sstevel@tonic-gate * MD_NR_JOIN: set OWN flag in node records
42860Sstevel@tonic-gate * MD_NR_WITHDRAW: reset OWN flag in node records
42870Sstevel@tonic-gate * MD_NR_OK: reset ADD flags and set OK flag in node records
42880Sstevel@tonic-gate * MD_NR_SET: set node record flags based on flags stored in nd
42890Sstevel@tonic-gate *
42900Sstevel@tonic-gate * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting
42910Sstevel@tonic-gate * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW
42920Sstevel@tonic-gate * (remove last disk from set) or OK (after addition of host to set).
42930Sstevel@tonic-gate *
42940Sstevel@tonic-gate * The SET flag_action is typically used when nodelist contains all nodes
42950Sstevel@tonic-gate * in the diskset, but specific nodes have had flag changes. An example of
42960Sstevel@tonic-gate * this would be the join/withdraw of a specific node to/from the set.
42970Sstevel@tonic-gate *
42980Sstevel@tonic-gate * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag. This
42990Sstevel@tonic-gate * flag is used by the client to recover in case of failure and should not
43000Sstevel@tonic-gate * be set in the node record flags.
43010Sstevel@tonic-gate */
43020Sstevel@tonic-gate static void
upd_nr_flags(mdsetname_t * sp,md_mnnode_desc * nd,uint_t flag_action,md_error_t * ep)43030Sstevel@tonic-gate upd_nr_flags(
43040Sstevel@tonic-gate mdsetname_t *sp,
43050Sstevel@tonic-gate md_mnnode_desc *nd,
43060Sstevel@tonic-gate uint_t flag_action,
43070Sstevel@tonic-gate md_error_t *ep
43080Sstevel@tonic-gate )
43090Sstevel@tonic-gate {
43100Sstevel@tonic-gate mdsetname_t *local_sp;
43110Sstevel@tonic-gate md_set_record *sr;
43120Sstevel@tonic-gate md_mnset_record *mnsr;
43130Sstevel@tonic-gate md_mnnode_desc *ndp;
43140Sstevel@tonic-gate md_mnnode_record *nrp;
43150Sstevel@tonic-gate
43160Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
43170Sstevel@tonic-gate return;
43180Sstevel@tonic-gate
43190Sstevel@tonic-gate metaflushsetname(local_sp);
43200Sstevel@tonic-gate
43210Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
43220Sstevel@tonic-gate return;
43230Sstevel@tonic-gate
43240Sstevel@tonic-gate if (!(MD_MNSET_REC(sr))) {
43250Sstevel@tonic-gate return;
43260Sstevel@tonic-gate }
43270Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
43280Sstevel@tonic-gate
43290Sstevel@tonic-gate switch (flag_action) {
43300Sstevel@tonic-gate case MD_NR_JOIN:
43310Sstevel@tonic-gate case MD_NR_WITHDRAW:
43320Sstevel@tonic-gate case MD_NR_SET:
43330Sstevel@tonic-gate case MD_NR_OK:
43340Sstevel@tonic-gate case MD_NR_DEL:
43350Sstevel@tonic-gate break;
43360Sstevel@tonic-gate default:
43370Sstevel@tonic-gate return;
43380Sstevel@tonic-gate }
43390Sstevel@tonic-gate
43400Sstevel@tonic-gate for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) {
43410Sstevel@tonic-gate /* Find matching node record for given node descriptor */
43420Sstevel@tonic-gate for (nrp = mnsr->sr_nodechain; nrp != NULL;
43430Sstevel@tonic-gate nrp = nrp->nr_next) {
43440Sstevel@tonic-gate if (ndp->nd_nodeid == nrp->nr_nodeid) {
43450Sstevel@tonic-gate switch (flag_action) {
43460Sstevel@tonic-gate case MD_NR_JOIN:
43470Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_OWN;
43480Sstevel@tonic-gate break;
43490Sstevel@tonic-gate case MD_NR_WITHDRAW:
43500Sstevel@tonic-gate nrp->nr_flags &= ~MD_MN_NODE_OWN;
43510Sstevel@tonic-gate break;
43520Sstevel@tonic-gate case MD_NR_OK:
43530Sstevel@tonic-gate nrp->nr_flags &=
43540Sstevel@tonic-gate ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL);
43550Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_OK;
43560Sstevel@tonic-gate break;
43570Sstevel@tonic-gate case MD_NR_DEL:
43580Sstevel@tonic-gate nrp->nr_flags &=
43590Sstevel@tonic-gate ~(MD_MN_NODE_OK | MD_MN_NODE_ADD);
43600Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_DEL;
43610Sstevel@tonic-gate break;
43620Sstevel@tonic-gate case MD_NR_SET:
43630Sstevel@tonic-gate /* Do not set RB_JOIN flag */
43640Sstevel@tonic-gate nrp->nr_flags =
43650Sstevel@tonic-gate ndp->nd_flags & ~MD_MN_NODE_RB_JOIN;
43660Sstevel@tonic-gate break;
43670Sstevel@tonic-gate }
43680Sstevel@tonic-gate break;
43690Sstevel@tonic-gate }
43700Sstevel@tonic-gate }
43710Sstevel@tonic-gate }
43720Sstevel@tonic-gate out:
43730Sstevel@tonic-gate /* Don't increment set genid for node record flag update */
43740Sstevel@tonic-gate commitset(sr, FALSE, ep);
43750Sstevel@tonic-gate free_sr(sr);
43760Sstevel@tonic-gate }
43770Sstevel@tonic-gate
43780Sstevel@tonic-gate /*
43790Sstevel@tonic-gate * init/fini wrapper around upd_nr_flags
43800Sstevel@tonic-gate */
43810Sstevel@tonic-gate bool_t
mdrpc_upd_nr_flags_common(mdrpc_upd_nr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)43820Sstevel@tonic-gate mdrpc_upd_nr_flags_common(
43830Sstevel@tonic-gate mdrpc_upd_nr_flags_args *args,
43840Sstevel@tonic-gate mdrpc_generic_res *res,
43850Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
43860Sstevel@tonic-gate )
43870Sstevel@tonic-gate {
43880Sstevel@tonic-gate md_error_t *ep = &res->status;
43890Sstevel@tonic-gate int err;
43900Sstevel@tonic-gate int op_mode = W_OK;
43910Sstevel@tonic-gate
43920Sstevel@tonic-gate /* setup, check permissions */
43930Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
43940Sstevel@tonic-gate return (FALSE);
43950Sstevel@tonic-gate else if (err != 0)
43960Sstevel@tonic-gate return (TRUE);
43970Sstevel@tonic-gate
43980Sstevel@tonic-gate /*
43990Sstevel@tonic-gate * During reconfig, node record flags can be updated without
44000Sstevel@tonic-gate * locking first.
44010Sstevel@tonic-gate */
44020Sstevel@tonic-gate if (!(args->flags & MNSET_IN_RECONFIG)) {
44030Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
44040Sstevel@tonic-gate return (TRUE);
44050Sstevel@tonic-gate }
44060Sstevel@tonic-gate
44070Sstevel@tonic-gate /* doit */
44080Sstevel@tonic-gate upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep);
44090Sstevel@tonic-gate
44100Sstevel@tonic-gate err = svc_fini(ep);
44110Sstevel@tonic-gate
44120Sstevel@tonic-gate return (TRUE);
44130Sstevel@tonic-gate }
44140Sstevel@tonic-gate
44150Sstevel@tonic-gate /*
44160Sstevel@tonic-gate * update the node records using given flag action.
44170Sstevel@tonic-gate */
44180Sstevel@tonic-gate bool_t
mdrpc_upd_nr_flags_2_svc(mdrpc_upd_nr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)44190Sstevel@tonic-gate mdrpc_upd_nr_flags_2_svc(
44200Sstevel@tonic-gate mdrpc_upd_nr_flags_2_args *args,
44210Sstevel@tonic-gate mdrpc_generic_res *res,
44220Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
44230Sstevel@tonic-gate )
44240Sstevel@tonic-gate {
44257159Sabalfour (void) memset(res, 0, sizeof (*res));
44260Sstevel@tonic-gate switch (args->rev) {
44277084Sachimm case MD_METAD_ARGS_REV_1:
44280Sstevel@tonic-gate return (mdrpc_upd_nr_flags_common(
44290Sstevel@tonic-gate &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp));
44307084Sachimm default:
44310Sstevel@tonic-gate return (FALSE);
44320Sstevel@tonic-gate }
44330Sstevel@tonic-gate }
44340Sstevel@tonic-gate
44350Sstevel@tonic-gate void
free_sk(md_setkey_t * skp)44360Sstevel@tonic-gate free_sk(md_setkey_t *skp)
44370Sstevel@tonic-gate {
44380Sstevel@tonic-gate Free(skp->sk_setname);
44390Sstevel@tonic-gate Free(skp->sk_host);
44400Sstevel@tonic-gate Free(skp);
44410Sstevel@tonic-gate }
44420Sstevel@tonic-gate
44430Sstevel@tonic-gate void
del_sk(set_t setno)44440Sstevel@tonic-gate del_sk(set_t setno)
44450Sstevel@tonic-gate {
44460Sstevel@tonic-gate md_setkey_t *skp;
44470Sstevel@tonic-gate md_setkey_t *tskp;
44480Sstevel@tonic-gate
44490Sstevel@tonic-gate for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) {
44500Sstevel@tonic-gate if (setno == skp->sk_setno) {
44510Sstevel@tonic-gate if (skp == my_svc_sk)
44520Sstevel@tonic-gate my_svc_sk = skp->sk_next;
44530Sstevel@tonic-gate else
44540Sstevel@tonic-gate tskp->sk_next = skp->sk_next;
44550Sstevel@tonic-gate
44560Sstevel@tonic-gate Free(skp->sk_setname);
44570Sstevel@tonic-gate Free(skp->sk_host);
44580Sstevel@tonic-gate Free(skp);
44590Sstevel@tonic-gate break;
44600Sstevel@tonic-gate }
44610Sstevel@tonic-gate }
44620Sstevel@tonic-gate }
44630Sstevel@tonic-gate
44640Sstevel@tonic-gate md_setkey_t *
dupsk(md_setkey_t * skp)44650Sstevel@tonic-gate dupsk(md_setkey_t *skp)
44660Sstevel@tonic-gate {
44670Sstevel@tonic-gate md_setkey_t *tskp;
44680Sstevel@tonic-gate
44690Sstevel@tonic-gate tskp = Zalloc(sizeof (md_setkey_t));
44700Sstevel@tonic-gate
44710Sstevel@tonic-gate *tskp = *skp;
44720Sstevel@tonic-gate tskp->sk_host = Strdup(skp->sk_host);
44730Sstevel@tonic-gate tskp->sk_setname = Strdup(skp->sk_setname);
44740Sstevel@tonic-gate
44750Sstevel@tonic-gate return (tskp);
44760Sstevel@tonic-gate }
44770Sstevel@tonic-gate
44780Sstevel@tonic-gate md_setkey_t *
svc_get_setkey(set_t setno)44790Sstevel@tonic-gate svc_get_setkey(set_t setno)
44800Sstevel@tonic-gate {
44810Sstevel@tonic-gate md_setkey_t *skp;
44820Sstevel@tonic-gate
44830Sstevel@tonic-gate for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next)
44840Sstevel@tonic-gate if (setno == skp->sk_setno)
44850Sstevel@tonic-gate return (dupsk(skp));
44860Sstevel@tonic-gate return (NULL);
44870Sstevel@tonic-gate }
44880Sstevel@tonic-gate
44890Sstevel@tonic-gate void
svc_set_setkey(md_setkey_t * svc_sk)44900Sstevel@tonic-gate svc_set_setkey(md_setkey_t *svc_sk)
44910Sstevel@tonic-gate {
44920Sstevel@tonic-gate md_setkey_t *skp;
44930Sstevel@tonic-gate
44940Sstevel@tonic-gate if (my_svc_sk == NULL) {
44950Sstevel@tonic-gate my_svc_sk = dupsk(svc_sk);
44960Sstevel@tonic-gate return;
44970Sstevel@tonic-gate }
44980Sstevel@tonic-gate
44990Sstevel@tonic-gate for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next)
45000Sstevel@tonic-gate assert(svc_sk->sk_setno != skp->sk_setno);
45010Sstevel@tonic-gate
45020Sstevel@tonic-gate skp->sk_next = dupsk(svc_sk);
45030Sstevel@tonic-gate }
45040Sstevel@tonic-gate
45050Sstevel@tonic-gate /*
45060Sstevel@tonic-gate * Unlock the set
45070Sstevel@tonic-gate *
45080Sstevel@tonic-gate * To unlock the set, the user must have the correct key, once this is verified
45090Sstevel@tonic-gate * the set is unlocked and the cached information for the set is flushed.
45100Sstevel@tonic-gate */
45110Sstevel@tonic-gate bool_t
mdrpc_unlock_set_common(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)45120Sstevel@tonic-gate mdrpc_unlock_set_common(
45130Sstevel@tonic-gate mdrpc_null_args *args,
45140Sstevel@tonic-gate mdrpc_setlock_res *res,
45150Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
45160Sstevel@tonic-gate )
45170Sstevel@tonic-gate {
45180Sstevel@tonic-gate md_error_t *ep = &res->status;
45190Sstevel@tonic-gate int err;
45200Sstevel@tonic-gate int op_mode = W_OK;
45210Sstevel@tonic-gate md_setkey_t *svc_skp;
45220Sstevel@tonic-gate md_set_desc *sd;
45230Sstevel@tonic-gate mdsetname_t *sp;
45240Sstevel@tonic-gate int multi_node = 0;
45250Sstevel@tonic-gate md_error_t xep = mdnullerror;
45260Sstevel@tonic-gate
45270Sstevel@tonic-gate /* setup, check permissions */
45280Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
45290Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
45300Sstevel@tonic-gate return (FALSE);
45310Sstevel@tonic-gate else if (err != 0)
45320Sstevel@tonic-gate return (TRUE);
45330Sstevel@tonic-gate
45340Sstevel@tonic-gate /*
45350Sstevel@tonic-gate * Is diskset a MN diskset?
45360Sstevel@tonic-gate * Don't set error from this check since unlock set can be
45370Sstevel@tonic-gate * called after a set has been deleted.
45380Sstevel@tonic-gate */
45390Sstevel@tonic-gate if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) &&
45400Sstevel@tonic-gate ((sd = metaget_setdesc(sp, &xep)) != NULL)) {
45410Sstevel@tonic-gate if ((MD_MNSET_DESC(sd))) {
45420Sstevel@tonic-gate multi_node = 1;
45430Sstevel@tonic-gate }
45440Sstevel@tonic-gate }
45450Sstevel@tonic-gate
45460Sstevel@tonic-gate /* Get the set key, if any */
45470Sstevel@tonic-gate svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
45480Sstevel@tonic-gate
45490Sstevel@tonic-gate /* The set is locked */
45500Sstevel@tonic-gate if (svc_skp != NULL) {
45510Sstevel@tonic-gate
45520Sstevel@tonic-gate /* Make sure the opener has the right key. */
45530Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec ||
45540Sstevel@tonic-gate args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) {
45550Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_ULKSBADKEY,
45560Sstevel@tonic-gate svc_skp->sk_setno, mynode(), svc_skp->sk_host,
45570Sstevel@tonic-gate svc_skp->sk_setname);
45580Sstevel@tonic-gate free_sk(svc_skp);
45590Sstevel@tonic-gate return (TRUE);
45600Sstevel@tonic-gate }
45610Sstevel@tonic-gate
45620Sstevel@tonic-gate /* Unlock the set */
45630Sstevel@tonic-gate del_sk(args->cl_sk->sk_setno);
45640Sstevel@tonic-gate
45650Sstevel@tonic-gate /* Cleanup */
45660Sstevel@tonic-gate free_sk(svc_skp);
45670Sstevel@tonic-gate
45680Sstevel@tonic-gate goto out;
45690Sstevel@tonic-gate }
45700Sstevel@tonic-gate
45710Sstevel@tonic-gate
45720Sstevel@tonic-gate /*
45730Sstevel@tonic-gate * It is possible on a MN diskset to attempt to unlock a set that
45740Sstevel@tonic-gate * is unlocked. This could occur when the metaset or metadb command
45750Sstevel@tonic-gate * is failing due to another metaset or metadb command running.
45760Sstevel@tonic-gate * So, print no warning for MN disksets.
45770Sstevel@tonic-gate */
45780Sstevel@tonic-gate if (multi_node == 0) {
45790Sstevel@tonic-gate md_eprintf("Warning: set unlocked when unlock_set called!\n");
45800Sstevel@tonic-gate }
45810Sstevel@tonic-gate
45820Sstevel@tonic-gate out:
45830Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
45840Sstevel@tonic-gate
45850Sstevel@tonic-gate /* Flush the set cache */
45860Sstevel@tonic-gate sr_cache_flush_setno(args->cl_sk->sk_setno);
45870Sstevel@tonic-gate
45880Sstevel@tonic-gate return (TRUE);
45890Sstevel@tonic-gate }
45900Sstevel@tonic-gate
45910Sstevel@tonic-gate bool_t
mdrpc_unlock_set_1_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)45920Sstevel@tonic-gate mdrpc_unlock_set_1_svc(
45930Sstevel@tonic-gate mdrpc_null_args *args,
45940Sstevel@tonic-gate mdrpc_setlock_res *res,
45950Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
45960Sstevel@tonic-gate )
45970Sstevel@tonic-gate {
45980Sstevel@tonic-gate return (mdrpc_unlock_set_common(args, res, rqstp));
45990Sstevel@tonic-gate }
46000Sstevel@tonic-gate
46010Sstevel@tonic-gate bool_t
mdrpc_unlock_set_2_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)46020Sstevel@tonic-gate mdrpc_unlock_set_2_svc(
46030Sstevel@tonic-gate mdrpc_null_args *args,
46040Sstevel@tonic-gate mdrpc_setlock_res *res,
46050Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
46060Sstevel@tonic-gate )
46070Sstevel@tonic-gate {
46080Sstevel@tonic-gate return (mdrpc_unlock_set_common(args, res, rqstp));
46090Sstevel@tonic-gate }
46100Sstevel@tonic-gate
46110Sstevel@tonic-gate /*
46120Sstevel@tonic-gate * Lock the set
46130Sstevel@tonic-gate *
46140Sstevel@tonic-gate * If the user does not hand us a key, then we generate a new key and lock the
46150Sstevel@tonic-gate * set using this new key that was generated, if the user hands us a key then
46160Sstevel@tonic-gate * we use the key to lock the set.
46170Sstevel@tonic-gate */
46180Sstevel@tonic-gate bool_t
mdrpc_lock_set_common(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)46190Sstevel@tonic-gate mdrpc_lock_set_common(
46200Sstevel@tonic-gate mdrpc_null_args *args,
46210Sstevel@tonic-gate mdrpc_setlock_res *res,
46220Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
46230Sstevel@tonic-gate )
46240Sstevel@tonic-gate {
46250Sstevel@tonic-gate md_error_t *ep = &res->status;
46260Sstevel@tonic-gate int err;
46270Sstevel@tonic-gate md_error_t xep = mdnullerror;
46280Sstevel@tonic-gate int op_mode = W_OK;
46290Sstevel@tonic-gate md_setkey_t *svc_skp;
46300Sstevel@tonic-gate md_setkey_t new_sk;
46311320Srd117015 md_set_desc *sd = NULL;
46321320Srd117015 mdsetname_t *sp = NULL;
46330Sstevel@tonic-gate
46340Sstevel@tonic-gate /* setup, check permissions */
46350Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
46360Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
46370Sstevel@tonic-gate return (FALSE);
46380Sstevel@tonic-gate else if (err != 0)
46390Sstevel@tonic-gate return (TRUE);
46400Sstevel@tonic-gate
46410Sstevel@tonic-gate svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
46420Sstevel@tonic-gate
46431320Srd117015 /* The set is locked */
46441320Srd117015 if (svc_skp != NULL) {
46451320Srd117015
46461320Srd117015 /*
46471320Srd117015 * This lock request could be for a new diskset, as
46481320Srd117015 * such metasetnosetname() may not return anything
46491320Srd117015 * useful. Only call it if there is already a key.
46501320Srd117015 */
46511320Srd117015 if ((sp = metasetnosetname(args->cl_sk->sk_setno, ep))
46521320Srd117015 != NULL) {
46531320Srd117015 sd = metaget_setdesc(sp, ep);
46541320Srd117015 }
46551320Srd117015
46561320Srd117015 /*
46571320Srd117015 * meta_lock() provides local locking for non-MN
46581320Srd117015 * disksets. The local lock is held before we call
46591320Srd117015 * this RPC function. We should not receive a lock
46601320Srd117015 * request from the host which owns the lock. If we
46611320Srd117015 * do, release the lock.
46621320Srd117015 */
46631320Srd117015 if (!((sd != NULL) && (MD_MNSET_DESC(sd))) &&
46641320Srd117015 (strcmp(svc_skp->sk_host, args->cl_sk->sk_host) == 0)) {
46651320Srd117015 md_eprintf(
46661320Srd117015 "Warning: set locked when lock_set called!\n");
46671320Srd117015
46681320Srd117015 md_eprintf("Held lock info:\n");
46691320Srd117015
46701320Srd117015 md_eprintf("\tLock:\n");
46711320Srd117015 md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
46721320Srd117015 md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno);
46731320Srd117015 md_eprintf("\t\tHost: %s\n", svc_skp->sk_host);
46741320Srd117015 md_eprintf("\t\tKey: %d/%d %s\n",
46751320Srd117015 svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
46761320Srd117015 ctime((const time_t *)&svc_skp->sk_key.tv_sec));
46771320Srd117015
46781320Srd117015 /* Unlock set */
46791320Srd117015 del_sk(svc_skp->sk_setno);
46801320Srd117015 free_sk(svc_skp);
46811320Srd117015 svc_skp = NULL;
46821320Srd117015
46831320Srd117015 md_eprintf("Released lock held by requesting host\n");
46841320Srd117015 }
46851320Srd117015 }
46861320Srd117015
46870Sstevel@tonic-gate /* The set is unlocked */
46880Sstevel@tonic-gate if (svc_skp == NULL) {
46890Sstevel@tonic-gate /* If we have been given a key, use it. */
46900Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) {
46910Sstevel@tonic-gate svc_set_setkey(args->cl_sk);
46920Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
46930Sstevel@tonic-gate goto out;
46940Sstevel@tonic-gate }
46950Sstevel@tonic-gate
46960Sstevel@tonic-gate /* We need to lock it, with a new key */
46970Sstevel@tonic-gate new_sk = *args->cl_sk;
46980Sstevel@tonic-gate if (meta_gettimeofday(&new_sk.sk_key) == -1) {
46990Sstevel@tonic-gate (void) mdsyserror(ep, errno, "meta_gettimeofday()");
47000Sstevel@tonic-gate mde_perror(&xep, "");
47010Sstevel@tonic-gate md_exit(NULL, 1);
47020Sstevel@tonic-gate }
47030Sstevel@tonic-gate svc_set_setkey(&new_sk);
47040Sstevel@tonic-gate
47050Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
47060Sstevel@tonic-gate goto out;
47070Sstevel@tonic-gate }
47080Sstevel@tonic-gate
47090Sstevel@tonic-gate /*
47100Sstevel@tonic-gate * If a MN diskset, the lock_set routine is used as a locking
47110Sstevel@tonic-gate * mechanism to keep multiple metaset and/or metadb commads
47120Sstevel@tonic-gate * from interfering with each other. If two metaset/metadb
47130Sstevel@tonic-gate * commands are issued at the same time - one will complete
47140Sstevel@tonic-gate * and the other command will fail with MDE_DS_NOTNOW_CMD.
47150Sstevel@tonic-gate */
47161320Srd117015 if ((sd != NULL) && MD_MNSET_DESC(sd)) {
47170Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTNOW_CMD,
47180Sstevel@tonic-gate svc_skp->sk_setno, mynode(),
47190Sstevel@tonic-gate svc_skp->sk_host, svc_skp->sk_setname);
47200Sstevel@tonic-gate goto out;
47210Sstevel@tonic-gate }
47220Sstevel@tonic-gate
47230Sstevel@tonic-gate md_eprintf("Warning: set locked when lock_set called!\n");
47240Sstevel@tonic-gate
47250Sstevel@tonic-gate md_eprintf("Lock info:\n");
47260Sstevel@tonic-gate
47270Sstevel@tonic-gate md_eprintf("\tLock(svc):\n");
47280Sstevel@tonic-gate md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
47290Sstevel@tonic-gate md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno);
47300Sstevel@tonic-gate md_eprintf("\t\tHost: %s\n", svc_skp->sk_host);
47310Sstevel@tonic-gate md_eprintf("\t\tKey: %d/%d %s",
47320Sstevel@tonic-gate svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
47330Sstevel@tonic-gate ctime((const time_t *)&svc_skp->sk_key.tv_sec));
47340Sstevel@tonic-gate
47350Sstevel@tonic-gate md_eprintf("\tLock(cl):\n");
47360Sstevel@tonic-gate md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname);
47370Sstevel@tonic-gate md_eprintf("\t\tSetno: %d\n", args->cl_sk->sk_setno);
47380Sstevel@tonic-gate md_eprintf("\t\tHost: %s\n", args->cl_sk->sk_host);
47390Sstevel@tonic-gate md_eprintf("\t\tKey: %d/%d %s",
47400Sstevel@tonic-gate args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec,
47410Sstevel@tonic-gate ctime((const time_t *)&args->cl_sk->sk_key.tv_sec));
47420Sstevel@tonic-gate
47430Sstevel@tonic-gate /* The set is locked, do we have the key? */
47440Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec &&
47450Sstevel@tonic-gate args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) {
47460Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
47470Sstevel@tonic-gate goto out;
47480Sstevel@tonic-gate }
47490Sstevel@tonic-gate
47500Sstevel@tonic-gate /*
47510Sstevel@tonic-gate * The set is locked and we do not have the key, so we set up an error.
47520Sstevel@tonic-gate */
47530Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(),
47540Sstevel@tonic-gate svc_skp->sk_host, args->cl_sk->sk_setname);
47550Sstevel@tonic-gate
47560Sstevel@tonic-gate out:
47570Sstevel@tonic-gate if (svc_skp != NULL)
47580Sstevel@tonic-gate free_sk(svc_skp);
47590Sstevel@tonic-gate
47600Sstevel@tonic-gate /* Flush the set cache */
47610Sstevel@tonic-gate sr_cache_flush_setno(args->cl_sk->sk_setno);
47620Sstevel@tonic-gate
47630Sstevel@tonic-gate return (TRUE);
47640Sstevel@tonic-gate }
47650Sstevel@tonic-gate
47660Sstevel@tonic-gate bool_t
mdrpc_lock_set_1_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)47670Sstevel@tonic-gate mdrpc_lock_set_1_svc(
47680Sstevel@tonic-gate mdrpc_null_args *args,
47690Sstevel@tonic-gate mdrpc_setlock_res *res,
47700Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
47710Sstevel@tonic-gate )
47720Sstevel@tonic-gate {
47730Sstevel@tonic-gate return (mdrpc_lock_set_common(args, res, rqstp));
47740Sstevel@tonic-gate }
47750Sstevel@tonic-gate
47760Sstevel@tonic-gate bool_t
mdrpc_lock_set_2_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)47770Sstevel@tonic-gate mdrpc_lock_set_2_svc(
47780Sstevel@tonic-gate mdrpc_null_args *args,
47790Sstevel@tonic-gate mdrpc_setlock_res *res,
47800Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
47810Sstevel@tonic-gate )
47820Sstevel@tonic-gate {
47830Sstevel@tonic-gate return (mdrpc_lock_set_common(args, res, rqstp));
47840Sstevel@tonic-gate }
47850Sstevel@tonic-gate
47860Sstevel@tonic-gate static void
updmeds(char * setname,md_h_arr_t * medp,int version,md_error_t * ep)47870Sstevel@tonic-gate updmeds(
47880Sstevel@tonic-gate char *setname,
47890Sstevel@tonic-gate md_h_arr_t *medp,
47900Sstevel@tonic-gate int version, /* RPC version of calling routine */
47910Sstevel@tonic-gate md_error_t *ep
47920Sstevel@tonic-gate )
47930Sstevel@tonic-gate {
47940Sstevel@tonic-gate mddb_userreq_t req;
47950Sstevel@tonic-gate md_set_record *sr;
47960Sstevel@tonic-gate mddb_med_parm_t mp;
47970Sstevel@tonic-gate
47980Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
47990Sstevel@tonic-gate return;
48000Sstevel@tonic-gate
48010Sstevel@tonic-gate sr->sr_med = *medp; /* structure assignment */
48020Sstevel@tonic-gate
48030Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
48040Sstevel@tonic-gate
48050Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
48060Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
48070Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
48080Sstevel@tonic-gate req.ur_size = sizeof (struct md_mnset_record);
48090Sstevel@tonic-gate } else {
48100Sstevel@tonic-gate req.ur_size = sizeof (*sr);
48110Sstevel@tonic-gate }
48120Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
48130Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
48140Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
48150Sstevel@tonic-gate free_sr(sr);
48160Sstevel@tonic-gate return;
48170Sstevel@tonic-gate }
48180Sstevel@tonic-gate
48190Sstevel@tonic-gate commitset(sr, TRUE, ep);
48200Sstevel@tonic-gate
48210Sstevel@tonic-gate /*
48220Sstevel@tonic-gate * If a MN disket, send the mediator list to the kernel.
48230Sstevel@tonic-gate */
48240Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
48250Sstevel@tonic-gate (void) memset(&mp, '\0', sizeof (mddb_med_parm_t));
48260Sstevel@tonic-gate mp.med_setno = sr->sr_setno;
48270Sstevel@tonic-gate if (meta_h2hi(medp, &mp.med, ep)) {
48280Sstevel@tonic-gate free_sr(sr);
48290Sstevel@tonic-gate return;
48300Sstevel@tonic-gate }
48310Sstevel@tonic-gate
48320Sstevel@tonic-gate /* Resolve the IP addresses for the host list */
48330Sstevel@tonic-gate if (meta_med_hnm2ip(&mp.med, ep)) {
48340Sstevel@tonic-gate free_sr(sr);
48350Sstevel@tonic-gate return;
48360Sstevel@tonic-gate }
48370Sstevel@tonic-gate
48380Sstevel@tonic-gate /* If node not yet joined to set, failure is ok. */
48390Sstevel@tonic-gate if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) {
48400Sstevel@tonic-gate if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) {
48410Sstevel@tonic-gate (void) mdstealerror(ep, &mp.med_mde);
48420Sstevel@tonic-gate }
48430Sstevel@tonic-gate }
48440Sstevel@tonic-gate }
48450Sstevel@tonic-gate free_sr(sr);
48460Sstevel@tonic-gate }
48470Sstevel@tonic-gate
48480Sstevel@tonic-gate /*
48490Sstevel@tonic-gate * Update the mediator data in the set record
48500Sstevel@tonic-gate */
48510Sstevel@tonic-gate bool_t
mdrpc_updmeds_common(mdrpc_updmeds_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)48520Sstevel@tonic-gate mdrpc_updmeds_common(
48530Sstevel@tonic-gate mdrpc_updmeds_args *args,
48540Sstevel@tonic-gate mdrpc_generic_res *res,
48550Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
48560Sstevel@tonic-gate int version /* RPC version */
48570Sstevel@tonic-gate )
48580Sstevel@tonic-gate {
48590Sstevel@tonic-gate md_error_t *ep = &res->status;
48600Sstevel@tonic-gate int err;
48610Sstevel@tonic-gate int op_mode = W_OK;
48620Sstevel@tonic-gate
48630Sstevel@tonic-gate /* setup, check permissions */
48640Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
48650Sstevel@tonic-gate return (FALSE);
48660Sstevel@tonic-gate else if (err != 0)
48670Sstevel@tonic-gate return (TRUE);
48680Sstevel@tonic-gate
48690Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
48700Sstevel@tonic-gate return (TRUE);
48710Sstevel@tonic-gate
48720Sstevel@tonic-gate /* doit */
48730Sstevel@tonic-gate updmeds(args->sp->setname, &args->meds, version, ep);
48740Sstevel@tonic-gate
48750Sstevel@tonic-gate err = svc_fini(ep);
48760Sstevel@tonic-gate
48770Sstevel@tonic-gate return (TRUE);
48780Sstevel@tonic-gate }
48790Sstevel@tonic-gate
48800Sstevel@tonic-gate bool_t
mdrpc_updmeds_1_svc(mdrpc_updmeds_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)48810Sstevel@tonic-gate mdrpc_updmeds_1_svc(
48820Sstevel@tonic-gate mdrpc_updmeds_args *args,
48830Sstevel@tonic-gate mdrpc_generic_res *res,
48840Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
48850Sstevel@tonic-gate )
48860Sstevel@tonic-gate {
48877159Sabalfour (void) memset(res, 0, sizeof (*res));
48880Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
48890Sstevel@tonic-gate return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION));
48900Sstevel@tonic-gate }
48910Sstevel@tonic-gate
48920Sstevel@tonic-gate bool_t
mdrpc_updmeds_2_svc(mdrpc_updmeds_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)48930Sstevel@tonic-gate mdrpc_updmeds_2_svc(
48940Sstevel@tonic-gate mdrpc_updmeds_2_args *args,
48950Sstevel@tonic-gate mdrpc_generic_res *res,
48960Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
48970Sstevel@tonic-gate )
48980Sstevel@tonic-gate {
48997159Sabalfour (void) memset(res, 0, sizeof (*res));
49000Sstevel@tonic-gate switch (args->rev) {
49017084Sachimm case MD_METAD_ARGS_REV_1:
49020Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
49030Sstevel@tonic-gate return (mdrpc_updmeds_common(
49040Sstevel@tonic-gate &args->mdrpc_updmeds_2_args_u.rev1, res,
49050Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
49067084Sachimm default:
49070Sstevel@tonic-gate return (FALSE);
49080Sstevel@tonic-gate }
49090Sstevel@tonic-gate }
49100Sstevel@tonic-gate
49110Sstevel@tonic-gate /*
49120Sstevel@tonic-gate * Call routines to suspend, reinit and resume mdcommd.
49130Sstevel@tonic-gate * Called during metaset and metadb command.
49140Sstevel@tonic-gate * NOT called during reconfig cycle.
49150Sstevel@tonic-gate */
49160Sstevel@tonic-gate bool_t
mdrpc_mdcommdctl_2_svc(mdrpc_mdcommdctl_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)49170Sstevel@tonic-gate mdrpc_mdcommdctl_2_svc(
49180Sstevel@tonic-gate mdrpc_mdcommdctl_2_args *args,
49190Sstevel@tonic-gate mdrpc_generic_res *res,
49200Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
49210Sstevel@tonic-gate )
49220Sstevel@tonic-gate {
49230Sstevel@tonic-gate mdrpc_mdcommdctl_args *args_cc;
49240Sstevel@tonic-gate md_error_t *ep = &res->status;
49250Sstevel@tonic-gate int err;
49260Sstevel@tonic-gate int op_mode = R_OK;
49270Sstevel@tonic-gate int suspend_ret;
49280Sstevel@tonic-gate
49297159Sabalfour (void) memset(res, 0, sizeof (*res));
49300Sstevel@tonic-gate switch (args->rev) {
49317084Sachimm case MD_METAD_ARGS_REV_1:
49320Sstevel@tonic-gate /* setup, check permissions */
49330Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
49340Sstevel@tonic-gate return (FALSE);
49350Sstevel@tonic-gate else if (err != 0)
49360Sstevel@tonic-gate return (TRUE);
49370Sstevel@tonic-gate
49380Sstevel@tonic-gate args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1);
49390Sstevel@tonic-gate switch (args_cc->flag_action) {
49400Sstevel@tonic-gate case COMMDCTL_SUSPEND:
49410Sstevel@tonic-gate suspend_ret = mdmn_suspend(args_cc->setno,
49423073Sjkennedy args_cc->class, 0);
49430Sstevel@tonic-gate if (suspend_ret != 0) {
49440Sstevel@tonic-gate (void) mddserror(ep, suspend_ret,
49450Sstevel@tonic-gate args_cc->setno, mynode(),
49460Sstevel@tonic-gate NULL, mynode());
49470Sstevel@tonic-gate }
49480Sstevel@tonic-gate break;
49490Sstevel@tonic-gate case COMMDCTL_RESUME:
49500Sstevel@tonic-gate if (mdmn_resume(args_cc->setno,
49513073Sjkennedy args_cc->class, args_cc->flags, 0)) {
49520Sstevel@tonic-gate (void) mddserror(ep,
49530Sstevel@tonic-gate MDE_DS_COMMDCTL_RESUME_FAIL,
49540Sstevel@tonic-gate args_cc->setno, mynode(),
49550Sstevel@tonic-gate NULL, mynode());
49560Sstevel@tonic-gate }
49570Sstevel@tonic-gate break;
49580Sstevel@tonic-gate case COMMDCTL_REINIT:
49593073Sjkennedy if (mdmn_reinit_set(args_cc->setno, 0)) {
49600Sstevel@tonic-gate (void) mddserror(ep,
49610Sstevel@tonic-gate MDE_DS_COMMDCTL_REINIT_FAIL,
49620Sstevel@tonic-gate args_cc->setno, mynode(),
49630Sstevel@tonic-gate NULL, mynode());
49640Sstevel@tonic-gate }
49650Sstevel@tonic-gate break;
49660Sstevel@tonic-gate }
49670Sstevel@tonic-gate err = svc_fini(ep);
49680Sstevel@tonic-gate return (TRUE);
49690Sstevel@tonic-gate
49707084Sachimm default:
49710Sstevel@tonic-gate return (FALSE);
49720Sstevel@tonic-gate }
49730Sstevel@tonic-gate }
49740Sstevel@tonic-gate
49750Sstevel@tonic-gate /*
49760Sstevel@tonic-gate * Return TRUE if set is stale.
49770Sstevel@tonic-gate */
49780Sstevel@tonic-gate bool_t
mdrpc_mn_is_stale_2_svc(mdrpc_setno_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)49790Sstevel@tonic-gate mdrpc_mn_is_stale_2_svc(
49800Sstevel@tonic-gate mdrpc_setno_2_args *args,
49810Sstevel@tonic-gate mdrpc_bool_res *res,
49820Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
49830Sstevel@tonic-gate )
49840Sstevel@tonic-gate {
49850Sstevel@tonic-gate md_error_t *ep = &res->status;
49860Sstevel@tonic-gate mddb_config_t c;
49870Sstevel@tonic-gate int err;
49880Sstevel@tonic-gate int op_mode = R_OK;
49890Sstevel@tonic-gate
49907159Sabalfour (void) memset(res, 0, sizeof (*res));
49910Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c));
49920Sstevel@tonic-gate switch (args->rev) {
49937084Sachimm case MD_METAD_ARGS_REV_1:
49940Sstevel@tonic-gate c.c_id = 0;
49950Sstevel@tonic-gate c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno;
49960Sstevel@tonic-gate
49970Sstevel@tonic-gate /* setup, check permissions */
49980Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
49990Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
50000Sstevel@tonic-gate return (FALSE);
50010Sstevel@tonic-gate else if (err != 0)
50020Sstevel@tonic-gate return (TRUE);
50030Sstevel@tonic-gate
50040Sstevel@tonic-gate if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
5005*11053SSurya.Prakki@Sun.COM (void) mdstealerror(ep, &c.c_mde);
50060Sstevel@tonic-gate return (TRUE);
50070Sstevel@tonic-gate }
50080Sstevel@tonic-gate
50090Sstevel@tonic-gate if (c.c_flags & MDDB_C_STALE) {
50100Sstevel@tonic-gate res->value = TRUE;
50110Sstevel@tonic-gate } else {
50120Sstevel@tonic-gate res->value = FALSE;
50130Sstevel@tonic-gate }
50140Sstevel@tonic-gate
50150Sstevel@tonic-gate err = svc_fini(ep);
50160Sstevel@tonic-gate return (TRUE);
50170Sstevel@tonic-gate
50187084Sachimm default:
50190Sstevel@tonic-gate return (FALSE);
50200Sstevel@tonic-gate }
50210Sstevel@tonic-gate }
50220Sstevel@tonic-gate
50230Sstevel@tonic-gate /*
50240Sstevel@tonic-gate * Clear out all clnt_locks held by all MN disksets.
50250Sstevel@tonic-gate * This is only used during a reconfig cycle.
50260Sstevel@tonic-gate */
50270Sstevel@tonic-gate /* ARGSUSED */
502862Sjeanm int
mdrpc_clr_mnsetlock_2_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)50290Sstevel@tonic-gate mdrpc_clr_mnsetlock_2_svc(
50300Sstevel@tonic-gate mdrpc_null_args *args,
50310Sstevel@tonic-gate mdrpc_generic_res *res,
50320Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
50330Sstevel@tonic-gate )
50340Sstevel@tonic-gate {
50350Sstevel@tonic-gate set_t max_sets, setno;
50360Sstevel@tonic-gate md_error_t *ep = &res->status;
50370Sstevel@tonic-gate int err;
50380Sstevel@tonic-gate int op_mode = W_OK;
50390Sstevel@tonic-gate mdsetname_t *sp;
50400Sstevel@tonic-gate
50410Sstevel@tonic-gate /* setup, check permissions */
50420Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
50430Sstevel@tonic-gate
50440Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
50450Sstevel@tonic-gate return (FALSE);
50460Sstevel@tonic-gate else if (err != 0)
50470Sstevel@tonic-gate return (TRUE);
50480Sstevel@tonic-gate
50490Sstevel@tonic-gate /*
50500Sstevel@tonic-gate * Walk through all possible disksets.
50510Sstevel@tonic-gate * For each MN set, delete all keys associated with that set.
50520Sstevel@tonic-gate */
50530Sstevel@tonic-gate if ((max_sets = get_max_sets(ep)) == 0) {
50540Sstevel@tonic-gate return (TRUE);
50550Sstevel@tonic-gate }
50560Sstevel@tonic-gate
50570Sstevel@tonic-gate /* start walking through all possible disksets */
50580Sstevel@tonic-gate for (setno = 1; setno < max_sets; setno++) {
50590Sstevel@tonic-gate if ((sp = metasetnosetname(setno, ep)) == NULL) {
50600Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET)) {
50610Sstevel@tonic-gate /* No set for this setno - continue */
50620Sstevel@tonic-gate mdclrerror(ep);
50630Sstevel@tonic-gate continue;
50640Sstevel@tonic-gate } else {
50650Sstevel@tonic-gate mde_perror(ep, gettext(
50660Sstevel@tonic-gate "Unable to get set %s information"),
50670Sstevel@tonic-gate sp->setname);
50680Sstevel@tonic-gate mdclrerror(ep);
50690Sstevel@tonic-gate continue;
50700Sstevel@tonic-gate }
50710Sstevel@tonic-gate }
50720Sstevel@tonic-gate
50730Sstevel@tonic-gate /* only check multi-node disksets */
50740Sstevel@tonic-gate if (!meta_is_mn_set(sp, ep)) {
50750Sstevel@tonic-gate mdclrerror(ep);
50760Sstevel@tonic-gate continue;
50770Sstevel@tonic-gate }
50780Sstevel@tonic-gate
50790Sstevel@tonic-gate /* Delete keys associated with rpc.metad clnt_lock */
50800Sstevel@tonic-gate del_sk(setno);
50810Sstevel@tonic-gate }
50820Sstevel@tonic-gate
50830Sstevel@tonic-gate *ep = mdnullerror;
50840Sstevel@tonic-gate
50850Sstevel@tonic-gate err = svc_fini(ep);
50860Sstevel@tonic-gate
50870Sstevel@tonic-gate return (TRUE);
50880Sstevel@tonic-gate }
50890Sstevel@tonic-gate
50900Sstevel@tonic-gate /*
50910Sstevel@tonic-gate * Get drive desc on this host for given setno.
50920Sstevel@tonic-gate * This is only used during a reconfig cycle.
50930Sstevel@tonic-gate * Returns a drive desc structure for the given mdsetname
50940Sstevel@tonic-gate * from this host.
50950Sstevel@tonic-gate *
50960Sstevel@tonic-gate * Returned drive desc structure is partially filled in with
50970Sstevel@tonic-gate * the drive name but is not filled in with any other strings
50980Sstevel@tonic-gate * in the drivename structure.
50990Sstevel@tonic-gate */
51000Sstevel@tonic-gate bool_t
mdrpc_getdrivedesc_2_svc(mdrpc_sp_2_args * args,mdrpc_getdrivedesc_res * res,struct svc_req * rqstp)51010Sstevel@tonic-gate mdrpc_getdrivedesc_2_svc(
51020Sstevel@tonic-gate mdrpc_sp_2_args *args,
51030Sstevel@tonic-gate mdrpc_getdrivedesc_res *res,
51040Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
51050Sstevel@tonic-gate )
51060Sstevel@tonic-gate {
51070Sstevel@tonic-gate md_drive_desc *dd;
51080Sstevel@tonic-gate md_error_t *ep = &res->status;
51090Sstevel@tonic-gate int err;
51100Sstevel@tonic-gate int op_mode = R_OK;
51110Sstevel@tonic-gate mdsetname_t *my_sp;
51120Sstevel@tonic-gate mdrpc_sp_args *args_r1;
51130Sstevel@tonic-gate
51147159Sabalfour (void) memset(res, 0, sizeof (*res));
51150Sstevel@tonic-gate switch (args->rev) {
51167084Sachimm case MD_METAD_ARGS_REV_1:
51170Sstevel@tonic-gate /* setup, check permissions */
51180Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
51190Sstevel@tonic-gate return (FALSE);
51200Sstevel@tonic-gate else if (err != 0)
51210Sstevel@tonic-gate return (TRUE);
51220Sstevel@tonic-gate
51230Sstevel@tonic-gate /* doit */
51240Sstevel@tonic-gate args_r1 = &args->mdrpc_sp_2_args_u.rev1;
51250Sstevel@tonic-gate if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL)
51260Sstevel@tonic-gate return (TRUE);
51270Sstevel@tonic-gate
51280Sstevel@tonic-gate dd = metaget_drivedesc(my_sp,
51297084Sachimm (MD_BASICNAME_OK | PRINT_FAST), ep);
51300Sstevel@tonic-gate
51310Sstevel@tonic-gate res->dd = dd_list_dup(dd);
51320Sstevel@tonic-gate
51330Sstevel@tonic-gate err = svc_fini(ep);
51340Sstevel@tonic-gate
51350Sstevel@tonic-gate return (TRUE);
51367084Sachimm default:
51370Sstevel@tonic-gate return (FALSE);
51380Sstevel@tonic-gate }
51390Sstevel@tonic-gate }
51400Sstevel@tonic-gate
51410Sstevel@tonic-gate /*
51420Sstevel@tonic-gate * Update drive records given list from master during reconfig.
51430Sstevel@tonic-gate * Make this node's list match the master's list which may include
51440Sstevel@tonic-gate * deleting a drive record that is known by this node and not known
51450Sstevel@tonic-gate * by the master node.
51460Sstevel@tonic-gate *
51470Sstevel@tonic-gate * Sync up the set/node/drive record genids to match the genid
51480Sstevel@tonic-gate * passed in the dd structure (all genids in this structure
51490Sstevel@tonic-gate * are the same).
51500Sstevel@tonic-gate */
51510Sstevel@tonic-gate bool_t
mdrpc_upd_dr_reconfig_common(mdrpc_upd_dr_flags_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)51520Sstevel@tonic-gate mdrpc_upd_dr_reconfig_common(
51530Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 *args,
51540Sstevel@tonic-gate mdrpc_generic_res *res,
51550Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
51560Sstevel@tonic-gate )
51570Sstevel@tonic-gate {
51580Sstevel@tonic-gate md_error_t *ep = &res->status;
51590Sstevel@tonic-gate int err;
51600Sstevel@tonic-gate mdsetname_t *local_sp;
51610Sstevel@tonic-gate md_set_record *sr;
51620Sstevel@tonic-gate md_mnset_record *mnsr;
51630Sstevel@tonic-gate md_drive_record *dr, *dr_placeholder = NULL;
51640Sstevel@tonic-gate md_drive_desc *dd;
51650Sstevel@tonic-gate mddrivename_t *dn, *dn1;
51660Sstevel@tonic-gate side_t sideno;
51670Sstevel@tonic-gate md_mnnode_record *nrp;
51680Sstevel@tonic-gate int op_mode = W_OK;
51690Sstevel@tonic-gate int change = 0;
51700Sstevel@tonic-gate
51710Sstevel@tonic-gate /* setup, check permissions */
51720Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
51730Sstevel@tonic-gate return (FALSE);
51740Sstevel@tonic-gate else if (err != 0)
51750Sstevel@tonic-gate return (TRUE);
51760Sstevel@tonic-gate
51770Sstevel@tonic-gate if ((local_sp = metasetname(args->sp->setname, ep)) == NULL)
51780Sstevel@tonic-gate return (TRUE);
51790Sstevel@tonic-gate
51800Sstevel@tonic-gate metaflushsetname(local_sp);
51810Sstevel@tonic-gate
51820Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
51830Sstevel@tonic-gate return (TRUE);
51840Sstevel@tonic-gate
51850Sstevel@tonic-gate if ((sr = getsetbyname(args->sp->setname, ep)) == NULL)
51860Sstevel@tonic-gate return (TRUE);
51870Sstevel@tonic-gate
51880Sstevel@tonic-gate if (!(MD_MNSET_REC(sr))) {
51890Sstevel@tonic-gate free_sr(sr);
51900Sstevel@tonic-gate return (TRUE);
51910Sstevel@tonic-gate }
51920Sstevel@tonic-gate
51930Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
51940Sstevel@tonic-gate /* Setup genid on set and node records */
51950Sstevel@tonic-gate if (args->drivedescs) {
51960Sstevel@tonic-gate if (mnsr->sr_genid != args->drivedescs->dd_genid) {
51970Sstevel@tonic-gate change = 1;
51980Sstevel@tonic-gate mnsr->sr_genid = args->drivedescs->dd_genid;
51990Sstevel@tonic-gate }
52000Sstevel@tonic-gate nrp = mnsr->sr_nodechain;
52010Sstevel@tonic-gate while (nrp) {
52020Sstevel@tonic-gate if (nrp->nr_genid != args->drivedescs->dd_genid) {
52030Sstevel@tonic-gate change = 1;
52040Sstevel@tonic-gate nrp->nr_genid = args->drivedescs->dd_genid;
52050Sstevel@tonic-gate }
52060Sstevel@tonic-gate nrp = nrp->nr_next;
52070Sstevel@tonic-gate }
52080Sstevel@tonic-gate }
52090Sstevel@tonic-gate for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) {
52100Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno,
52110Sstevel@tonic-gate dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep);
52120Sstevel@tonic-gate if (dn1 == NULL)
52130Sstevel@tonic-gate goto out;
52140Sstevel@tonic-gate for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) {
52150Sstevel@tonic-gate dn = dd->dd_dnp;
52160Sstevel@tonic-gate /* Found this node's drive rec to match dd */
52170Sstevel@tonic-gate if (strcmp(dn->cname, dn1->cname) == 0)
52180Sstevel@tonic-gate break;
52190Sstevel@tonic-gate }
52200Sstevel@tonic-gate
52210Sstevel@tonic-gate /*
52220Sstevel@tonic-gate * If drive found in master's list, make slave match master.
52230Sstevel@tonic-gate * If drive not found in master's list, remove drive.
52240Sstevel@tonic-gate */
52250Sstevel@tonic-gate if (dd) {
52260Sstevel@tonic-gate if ((dr->dr_flags != dd->dd_flags) ||
52270Sstevel@tonic-gate (dr->dr_genid != dd->dd_genid)) {
52280Sstevel@tonic-gate change = 1;
52290Sstevel@tonic-gate dr->dr_flags = dd->dd_flags;
52300Sstevel@tonic-gate dr->dr_genid = dd->dd_genid;
52310Sstevel@tonic-gate }
52320Sstevel@tonic-gate } else {
52330Sstevel@tonic-gate /*
52340Sstevel@tonic-gate * Delete entry from linked list. Need to use
52350Sstevel@tonic-gate * dr_placeholder so that dr->dr_next points to
52360Sstevel@tonic-gate * the next drive record in the list.
52370Sstevel@tonic-gate */
52380Sstevel@tonic-gate if (dr_placeholder == NULL) {
52390Sstevel@tonic-gate dr_placeholder =
52407084Sachimm Zalloc(sizeof (md_drive_record));
52410Sstevel@tonic-gate }
52420Sstevel@tonic-gate dr_placeholder->dr_next = dr->dr_next;
52430Sstevel@tonic-gate dr_placeholder->dr_key = dr->dr_key;
52440Sstevel@tonic-gate sr_del_drv(sr, dr->dr_selfid);
52450Sstevel@tonic-gate (void) del_sideno_sidenm(dr_placeholder->dr_key,
52467084Sachimm sideno, ep);
52470Sstevel@tonic-gate change = 1;
52480Sstevel@tonic-gate dr = dr_placeholder;
52490Sstevel@tonic-gate }
52500Sstevel@tonic-gate }
52510Sstevel@tonic-gate out:
52520Sstevel@tonic-gate /* If incore records are correct, don't need to write to disk */
52530Sstevel@tonic-gate if (change) {
52540Sstevel@tonic-gate /* Don't increment the genid in commitset */
52550Sstevel@tonic-gate commitset(sr, FALSE, ep);
52560Sstevel@tonic-gate }
52570Sstevel@tonic-gate free_sr(sr);
52580Sstevel@tonic-gate
52590Sstevel@tonic-gate err = svc_fini(ep);
52600Sstevel@tonic-gate
52610Sstevel@tonic-gate if (dr_placeholder != NULL)
52620Sstevel@tonic-gate Free(dr_placeholder);
52630Sstevel@tonic-gate
52640Sstevel@tonic-gate return (TRUE);
52650Sstevel@tonic-gate }
52660Sstevel@tonic-gate
52670Sstevel@tonic-gate /*
52680Sstevel@tonic-gate * Version 2 routine to update this node's drive records based on
52690Sstevel@tonic-gate * list passed in from master node.
52700Sstevel@tonic-gate */
52710Sstevel@tonic-gate bool_t
mdrpc_upd_dr_reconfig_2_svc(mdrpc_upd_dr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)52720Sstevel@tonic-gate mdrpc_upd_dr_reconfig_2_svc(
52730Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args *args,
52740Sstevel@tonic-gate mdrpc_generic_res *res,
52750Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
52760Sstevel@tonic-gate )
52770Sstevel@tonic-gate {
52787159Sabalfour (void) memset(res, 0, sizeof (*res));
52790Sstevel@tonic-gate switch (args->rev) {
52807084Sachimm case MD_METAD_ARGS_REV_1:
52810Sstevel@tonic-gate return (mdrpc_upd_dr_reconfig_common(
52820Sstevel@tonic-gate &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
52837084Sachimm default:
52840Sstevel@tonic-gate return (FALSE);
52850Sstevel@tonic-gate }
52860Sstevel@tonic-gate }
52870Sstevel@tonic-gate
52880Sstevel@tonic-gate /*
52890Sstevel@tonic-gate * reset mirror owner for mirrors owned by deleted
52900Sstevel@tonic-gate * or withdrawn host(s). Hosts being deleted or
52910Sstevel@tonic-gate * withdrawn are designated by nodeid since host is
52920Sstevel@tonic-gate * already deleted or withdrawn from set and may not
52930Sstevel@tonic-gate * be able to translate between a nodename and a nodeid.
52940Sstevel@tonic-gate * If an error occurs, ep will be set to that error information.
52950Sstevel@tonic-gate */
52960Sstevel@tonic-gate static void
reset_mirror_owner(char * setname,int node_c,int * node_id,md_error_t * ep)52970Sstevel@tonic-gate reset_mirror_owner(
52980Sstevel@tonic-gate char *setname,
52990Sstevel@tonic-gate int node_c,
53000Sstevel@tonic-gate int *node_id, /* Array of node ids */
53010Sstevel@tonic-gate md_error_t *ep
53020Sstevel@tonic-gate )
53030Sstevel@tonic-gate {
53040Sstevel@tonic-gate mdsetname_t *local_sp;
53050Sstevel@tonic-gate int i;
53060Sstevel@tonic-gate mdnamelist_t *devnlp = NULL;
53070Sstevel@tonic-gate mdnamelist_t *p;
53080Sstevel@tonic-gate mdname_t *devnp = NULL;
53090Sstevel@tonic-gate md_set_mmown_params_t ownpar_p;
53100Sstevel@tonic-gate md_set_mmown_params_t *ownpar = &ownpar_p;
53110Sstevel@tonic-gate char *miscname;
53120Sstevel@tonic-gate
53130Sstevel@tonic-gate if ((local_sp = metasetname(setname, ep)) == NULL)
53140Sstevel@tonic-gate return;
53150Sstevel@tonic-gate
53160Sstevel@tonic-gate /* get a list of all the mirrors for current set */
53170Sstevel@tonic-gate if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0)
53180Sstevel@tonic-gate return;
53190Sstevel@tonic-gate
53200Sstevel@tonic-gate /* for each mirror */
53210Sstevel@tonic-gate for (p = devnlp; (p != NULL); p = p->next) {
53220Sstevel@tonic-gate devnp = p->namep;
53230Sstevel@tonic-gate
53240Sstevel@tonic-gate /*
53250Sstevel@tonic-gate * we can only do these for mirrors so make sure we
53260Sstevel@tonic-gate * really have a mirror device and not a softpartition
53270Sstevel@tonic-gate * imitating one. meta_get_mirror_names seems to think
53280Sstevel@tonic-gate * softparts on top of a mirror are mirrors!
53290Sstevel@tonic-gate */
53300Sstevel@tonic-gate if ((miscname = metagetmiscname(devnp, ep)) == NULL)
53310Sstevel@tonic-gate goto out;
53320Sstevel@tonic-gate if (strcmp(miscname, MD_MIRROR) != 0)
53330Sstevel@tonic-gate continue;
53340Sstevel@tonic-gate
53350Sstevel@tonic-gate (void) memset(ownpar, 0, sizeof (*ownpar));
53360Sstevel@tonic-gate ownpar->d.mnum = meta_getminor(devnp->dev);
53370Sstevel@tonic-gate MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno);
53380Sstevel@tonic-gate
53390Sstevel@tonic-gate /* get the current owner id */
53400Sstevel@tonic-gate if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep,
53410Sstevel@tonic-gate "MD_MN_GET_MM_OWNER") != 0) {
53420Sstevel@tonic-gate mde_perror(ep, gettext(
53431623Stw21770 "Unable to get mirror owner for %s/%s"),
53440Sstevel@tonic-gate local_sp->setname,
53451623Stw21770 get_mdname(local_sp, ownpar->d.mnum));
53460Sstevel@tonic-gate goto out;
53470Sstevel@tonic-gate }
53480Sstevel@tonic-gate
53490Sstevel@tonic-gate if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) {
53500Sstevel@tonic-gate mdclrerror(ep);
53510Sstevel@tonic-gate continue;
53520Sstevel@tonic-gate }
53530Sstevel@tonic-gate /*
53540Sstevel@tonic-gate * reset owner only if the current owner is
53550Sstevel@tonic-gate * in the list of nodes being deleted.
53560Sstevel@tonic-gate */
53570Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
53580Sstevel@tonic-gate if (ownpar->d.owner == node_id[i]) {
53590Sstevel@tonic-gate if (meta_mn_change_owner(&ownpar,
53600Sstevel@tonic-gate local_sp->setno, ownpar->d.mnum,
53610Sstevel@tonic-gate MD_MN_MIRROR_UNOWNED,
53620Sstevel@tonic-gate MD_MN_MM_ALLOW_CHANGE) == -1) {
53630Sstevel@tonic-gate mde_perror(ep, gettext(
53640Sstevel@tonic-gate "Unable to reset mirror owner for"
53651623Stw21770 " %s/%s"), local_sp->setname,
53661623Stw21770 get_mdname(local_sp,
53677084Sachimm ownpar->d.mnum));
53680Sstevel@tonic-gate goto out;
53690Sstevel@tonic-gate }
53700Sstevel@tonic-gate break;
53710Sstevel@tonic-gate }
53720Sstevel@tonic-gate }
53730Sstevel@tonic-gate }
53740Sstevel@tonic-gate
53750Sstevel@tonic-gate out:
53760Sstevel@tonic-gate /* cleanup */
53770Sstevel@tonic-gate metafreenamelist(devnlp);
53780Sstevel@tonic-gate }
53790Sstevel@tonic-gate
53800Sstevel@tonic-gate /*
53810Sstevel@tonic-gate * Wrapper routine for reset_mirror_owner.
53820Sstevel@tonic-gate * Called when hosts are deleted or withdrawn
53830Sstevel@tonic-gate * in order to reset any mirror owners that are needed.
53840Sstevel@tonic-gate */
53850Sstevel@tonic-gate bool_t
mdrpc_reset_mirror_owner_common(mdrpc_nodeid_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)53860Sstevel@tonic-gate mdrpc_reset_mirror_owner_common(
53870Sstevel@tonic-gate mdrpc_nodeid_args *args,
53880Sstevel@tonic-gate mdrpc_generic_res *res,
53890Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
53900Sstevel@tonic-gate )
53910Sstevel@tonic-gate {
53920Sstevel@tonic-gate md_error_t *ep = &res->status;
53930Sstevel@tonic-gate int err;
53940Sstevel@tonic-gate int op_mode = W_OK;
53950Sstevel@tonic-gate
53960Sstevel@tonic-gate /* setup, check permissions */
53970Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
53980Sstevel@tonic-gate return (FALSE);
53990Sstevel@tonic-gate else if (err != 0)
54000Sstevel@tonic-gate return (TRUE);
54010Sstevel@tonic-gate
54020Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
54030Sstevel@tonic-gate return (TRUE);
54040Sstevel@tonic-gate
54050Sstevel@tonic-gate /* doit */
54060Sstevel@tonic-gate reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len,
54070Sstevel@tonic-gate args->nodeid.nodeid_val, ep);
54080Sstevel@tonic-gate
54090Sstevel@tonic-gate err = svc_fini(ep);
54100Sstevel@tonic-gate
54110Sstevel@tonic-gate return (TRUE);
54120Sstevel@tonic-gate }
54130Sstevel@tonic-gate
54140Sstevel@tonic-gate /*
54150Sstevel@tonic-gate * RPC service routine to reset the mirror owner for mirrors owned
54160Sstevel@tonic-gate * by the given hosts. Typically, the list of given hosts is a list
54170Sstevel@tonic-gate * of nodes being deleted or withdrawn from a diskset.
54180Sstevel@tonic-gate * The given hosts are designated by nodeid since host may
54190Sstevel@tonic-gate * already be deleted or withdrawn from set and may not
54200Sstevel@tonic-gate * be able to translate between a nodename and a nodeid.
54210Sstevel@tonic-gate */
54220Sstevel@tonic-gate bool_t
mdrpc_reset_mirror_owner_2_svc(mdrpc_nodeid_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54230Sstevel@tonic-gate mdrpc_reset_mirror_owner_2_svc(
54240Sstevel@tonic-gate mdrpc_nodeid_2_args *args,
54250Sstevel@tonic-gate mdrpc_generic_res *res,
54260Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
54270Sstevel@tonic-gate )
54280Sstevel@tonic-gate {
54297159Sabalfour (void) memset(res, 0, sizeof (*res));
54300Sstevel@tonic-gate switch (args->rev) {
54317084Sachimm case MD_METAD_ARGS_REV_1:
54320Sstevel@tonic-gate return (mdrpc_reset_mirror_owner_common(
54330Sstevel@tonic-gate &args->mdrpc_nodeid_2_args_u.rev1, res,
54340Sstevel@tonic-gate rqstp));
54357084Sachimm default:
54360Sstevel@tonic-gate return (FALSE);
54370Sstevel@tonic-gate }
54380Sstevel@tonic-gate }
54390Sstevel@tonic-gate
54400Sstevel@tonic-gate /*
54410Sstevel@tonic-gate * Call routines to suspend and resume I/O for the given diskset(s).
54420Sstevel@tonic-gate * Called during reconfig cycle.
54430Sstevel@tonic-gate * Diskset of 0 represents all MN disksets.
54440Sstevel@tonic-gate */
54450Sstevel@tonic-gate bool_t
mdrpc_mn_susp_res_io_2_svc(mdrpc_mn_susp_res_io_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54460Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_svc(
54470Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_args *args,
54480Sstevel@tonic-gate mdrpc_generic_res *res,
54490Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
54500Sstevel@tonic-gate )
54510Sstevel@tonic-gate {
54520Sstevel@tonic-gate mdrpc_mn_susp_res_io_args *args_sr;
54530Sstevel@tonic-gate md_error_t *ep = &res->status;
54540Sstevel@tonic-gate int err;
54550Sstevel@tonic-gate int op_mode = R_OK;
54560Sstevel@tonic-gate
54577159Sabalfour (void) memset(res, 0, sizeof (*res));
54580Sstevel@tonic-gate switch (args->rev) {
54597084Sachimm case MD_METAD_ARGS_REV_1:
54600Sstevel@tonic-gate /* setup, check permissions */
54610Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
54620Sstevel@tonic-gate return (FALSE);
54630Sstevel@tonic-gate else if (err != 0)
54640Sstevel@tonic-gate return (TRUE);
54650Sstevel@tonic-gate
54660Sstevel@tonic-gate args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1);
54670Sstevel@tonic-gate switch (args_sr->susp_res_cmd) {
54680Sstevel@tonic-gate case MN_SUSP_IO:
54690Sstevel@tonic-gate (void) (metaioctl(MD_MN_SUSPEND_SET,
54707084Sachimm &args_sr->susp_res_setno, ep, NULL));
54710Sstevel@tonic-gate break;
54720Sstevel@tonic-gate case MN_RES_IO:
54730Sstevel@tonic-gate (void) (metaioctl(MD_MN_RESUME_SET,
54747084Sachimm &args_sr->susp_res_setno, ep, NULL));
54750Sstevel@tonic-gate break;
54760Sstevel@tonic-gate }
54770Sstevel@tonic-gate err = svc_fini(ep);
54780Sstevel@tonic-gate return (TRUE);
54790Sstevel@tonic-gate
54807084Sachimm default:
54810Sstevel@tonic-gate return (FALSE);
54820Sstevel@tonic-gate }
54830Sstevel@tonic-gate }
54840Sstevel@tonic-gate
54850Sstevel@tonic-gate /*
54860Sstevel@tonic-gate * Resnarf a set after it has been imported
54870Sstevel@tonic-gate */
54880Sstevel@tonic-gate bool_t
mdrpc_resnarf_set_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54890Sstevel@tonic-gate mdrpc_resnarf_set_2_svc(
54900Sstevel@tonic-gate mdrpc_setno_2_args *args,
54910Sstevel@tonic-gate mdrpc_generic_res *res,
54920Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
54930Sstevel@tonic-gate )
54940Sstevel@tonic-gate {
54950Sstevel@tonic-gate mdrpc_setno_args *setno_args;
54960Sstevel@tonic-gate md_error_t *ep = &res->status;
54970Sstevel@tonic-gate int err;
54980Sstevel@tonic-gate int op_mode = R_OK;
54990Sstevel@tonic-gate
55007159Sabalfour (void) memset(res, 0, sizeof (*res));
55010Sstevel@tonic-gate switch (args->rev) {
55027159Sabalfour case MD_METAD_ARGS_REV_1:
55030Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1;
55040Sstevel@tonic-gate break;
55057084Sachimm default:
55060Sstevel@tonic-gate return (FALSE);
55070Sstevel@tonic-gate }
55080Sstevel@tonic-gate
55090Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55100Sstevel@tonic-gate return (FALSE);
55110Sstevel@tonic-gate else if (err != 0)
55120Sstevel@tonic-gate return (TRUE);
55130Sstevel@tonic-gate
55140Sstevel@tonic-gate /* do it */
55150Sstevel@tonic-gate if (resnarf_set(setno_args->setno, ep) < 0)
55160Sstevel@tonic-gate return (FALSE);
55170Sstevel@tonic-gate
55180Sstevel@tonic-gate err = svc_fini(ep);
55190Sstevel@tonic-gate return (TRUE);
55200Sstevel@tonic-gate }
55210Sstevel@tonic-gate
55220Sstevel@tonic-gate /*
55230Sstevel@tonic-gate * Creates a resync thread.
55240Sstevel@tonic-gate * Always returns true.
55250Sstevel@tonic-gate */
55260Sstevel@tonic-gate bool_t
mdrpc_mn_mirror_resync_all_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)55270Sstevel@tonic-gate mdrpc_mn_mirror_resync_all_2_svc(
55280Sstevel@tonic-gate mdrpc_setno_2_args *args,
55290Sstevel@tonic-gate mdrpc_generic_res *res,
55300Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
55310Sstevel@tonic-gate )
55320Sstevel@tonic-gate {
55330Sstevel@tonic-gate md_error_t *ep = &res->status;
55340Sstevel@tonic-gate mdrpc_setno_args *setno_args;
55350Sstevel@tonic-gate int err;
55360Sstevel@tonic-gate int op_mode = R_OK;
55370Sstevel@tonic-gate
55387159Sabalfour (void) memset(res, 0, sizeof (*res));
55390Sstevel@tonic-gate switch (args->rev) {
55407084Sachimm case MD_METAD_ARGS_REV_1:
55410Sstevel@tonic-gate /* setup, check permissions */
55420Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55430Sstevel@tonic-gate return (FALSE);
55440Sstevel@tonic-gate else if (err != 0)
55450Sstevel@tonic-gate return (TRUE);
55460Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1;
55470Sstevel@tonic-gate
55480Sstevel@tonic-gate /*
55490Sstevel@tonic-gate * Need to invoke a metasync on a node newly added to a set.
55500Sstevel@tonic-gate */
5551*11053SSurya.Prakki@Sun.COM (void) meta_mn_mirror_resync_all(&(setno_args->setno));
55520Sstevel@tonic-gate
55530Sstevel@tonic-gate err = svc_fini(ep);
55540Sstevel@tonic-gate return (TRUE);
55550Sstevel@tonic-gate
55567084Sachimm default:
55570Sstevel@tonic-gate return (FALSE);
55580Sstevel@tonic-gate }
55590Sstevel@tonic-gate }
55600Sstevel@tonic-gate
55610Sstevel@tonic-gate /*
55620Sstevel@tonic-gate * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(),
55630Sstevel@tonic-gate * which forks a daemon process to perform this action.
55640Sstevel@tonic-gate * Always returns true.
55650Sstevel@tonic-gate */
55660Sstevel@tonic-gate bool_t
mdrpc_mn_sp_update_abr_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)55670Sstevel@tonic-gate mdrpc_mn_sp_update_abr_2_svc(
55680Sstevel@tonic-gate mdrpc_setno_2_args *args,
55690Sstevel@tonic-gate mdrpc_generic_res *res,
55700Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
55710Sstevel@tonic-gate )
55720Sstevel@tonic-gate {
55730Sstevel@tonic-gate md_error_t *ep = &res->status;
55740Sstevel@tonic-gate mdrpc_setno_args *setno_args;
55750Sstevel@tonic-gate int err;
55760Sstevel@tonic-gate int op_mode = R_OK;
55770Sstevel@tonic-gate
55787159Sabalfour (void) memset(res, 0, sizeof (*res));
55790Sstevel@tonic-gate switch (args->rev) {
55807084Sachimm case MD_METAD_ARGS_REV_1:
55810Sstevel@tonic-gate /* setup, check permissions */
55820Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55830Sstevel@tonic-gate return (FALSE);
55840Sstevel@tonic-gate else if (err != 0)
55850Sstevel@tonic-gate return (TRUE);
55860Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1;
55870Sstevel@tonic-gate
5588*11053SSurya.Prakki@Sun.COM (void) meta_mn_sp_update_abr(&(setno_args->setno));
55890Sstevel@tonic-gate
55900Sstevel@tonic-gate err = svc_fini(ep);
55910Sstevel@tonic-gate return (TRUE);
55920Sstevel@tonic-gate
55937084Sachimm default:
55940Sstevel@tonic-gate return (FALSE);
55950Sstevel@tonic-gate }
55960Sstevel@tonic-gate }
5597