17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
543b3654dSrd117015 * Common Development and Distribution License (the "License").
643b3654dSrd117015 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*80148899SSurya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include "metad_local.h"
277c478bd9Sstevel@tonic-gate #include <metad.h>
287c478bd9Sstevel@tonic-gate #include <sys/lvm/md_mddb.h>
297c478bd9Sstevel@tonic-gate #include <sdssc.h>
307c478bd9Sstevel@tonic-gate #include <sys/lvm/md_mirror.h>
317c478bd9Sstevel@tonic-gate #include <syslog.h>
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h>
347c478bd9Sstevel@tonic-gate #include <sys/sysevent/svm.h>
357c478bd9Sstevel@tonic-gate #include <thread.h>
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate #define MDDOORS "/usr/lib/lvm/mddoors"
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate * rpc.metad daemon
417c478bd9Sstevel@tonic-gate *
427c478bd9Sstevel@tonic-gate * The rpc.metad deamon supports two versions of the svm rpc calls - version 1
437c478bd9Sstevel@tonic-gate * and version 2. The over-the-wire structures sent as part of these rpc calls
447c478bd9Sstevel@tonic-gate * are also versioned - version 1 and version 2 exist. It must be noted that
457c478bd9Sstevel@tonic-gate * the version 2 structures have sub-versions or revisions as well. The
467c478bd9Sstevel@tonic-gate * revisions in the version 2 structures allow for flexiblility in changing
477c478bd9Sstevel@tonic-gate * over the wire structures without creating a new version of the svm rpc
487c478bd9Sstevel@tonic-gate * calls. No changes may be made to the version 1 routines or structures used
497c478bd9Sstevel@tonic-gate * by these routines.
507c478bd9Sstevel@tonic-gate *
517c478bd9Sstevel@tonic-gate * If, for example, the version 2 mdrpc_devinfo_args over the wire structure
527c478bd9Sstevel@tonic-gate * (mdrpc_devinfo_2_args*) is changed then the structure change must be
537c478bd9Sstevel@tonic-gate * accompanied by the following:
547c478bd9Sstevel@tonic-gate *
557c478bd9Sstevel@tonic-gate * Header file changes:
567c478bd9Sstevel@tonic-gate * . May need to introduce a new structure revision MD_METAD_ARGS_REV_X, where
577c478bd9Sstevel@tonic-gate * X is the revision number.
587c478bd9Sstevel@tonic-gate * . Create mdrpc_devinfo_2_args_rX, where X is the new revision of the
597c478bd9Sstevel@tonic-gate * structure.
607c478bd9Sstevel@tonic-gate * . Add a switch statement in mdrpc_devinfo_2_args.
617c478bd9Sstevel@tonic-gate *
627c478bd9Sstevel@tonic-gate * rpc.metad changes:
637c478bd9Sstevel@tonic-gate * . Check for the structure revision in the appropriate mdrpc_devinfo_svc
647c478bd9Sstevel@tonic-gate * routine (mdrpc_devinfo_2_svc).
657c478bd9Sstevel@tonic-gate *
667c478bd9Sstevel@tonic-gate * libmeta changes:
677c478bd9Sstevel@tonic-gate * . In the libmeta code that makes the mdrpc_devinfo rpc call, the arguments
687c478bd9Sstevel@tonic-gate * being passed as part of this call (namely mdrpc_devinfo_Y_args) must have
697c478bd9Sstevel@tonic-gate * the revision field and associated structure populated correctly.
707c478bd9Sstevel@tonic-gate */
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate static md_setkey_t *my_svc_sk = NULL;
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate * Add namespace entry to local mddb for using given sideno, key
767c478bd9Sstevel@tonic-gate * and names.
777c478bd9Sstevel@tonic-gate */
787c478bd9Sstevel@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)797c478bd9Sstevel@tonic-gate add_sideno_sidenm(
807c478bd9Sstevel@tonic-gate mdsidenames_t *sidenms,
817c478bd9Sstevel@tonic-gate mdkey_t local_key,
827c478bd9Sstevel@tonic-gate side_t sideno,
837c478bd9Sstevel@tonic-gate md_set_desc *sd, /* Only used with Version 2 */
847c478bd9Sstevel@tonic-gate md_error_t *ep
857c478bd9Sstevel@tonic-gate )
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate mdsidenames_t *sn;
887c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
897c478bd9Sstevel@tonic-gate char *nm;
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
927c478bd9Sstevel@tonic-gate return (-1);
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate for (sn = sidenms; sn != NULL; sn = sn->next)
957c478bd9Sstevel@tonic-gate if (sn->sideno == sideno)
967c478bd9Sstevel@tonic-gate break;
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate assert(sn != NULL);
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate * SKEW will be used on the traditional diskset despite of the
1037c478bd9Sstevel@tonic-gate * rpc version. SKEW is not used on the multinode diskset
1047c478bd9Sstevel@tonic-gate */
1057c478bd9Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
1067c478bd9Sstevel@tonic-gate nm = meta_getnmbykey(MD_LOCAL_SET, sideno, local_key, ep);
1077c478bd9Sstevel@tonic-gate } else {
1087c478bd9Sstevel@tonic-gate nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW, local_key, ep);
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate if (nm == NULL) {
1127c478bd9Sstevel@tonic-gate if (! mdisok(ep)) {
1137c478bd9Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
1147c478bd9Sstevel@tonic-gate return (-1);
1157c478bd9Sstevel@tonic-gate mdclrerror(ep);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate * Ignore returned key from add_name, only care about errs
1207c478bd9Sstevel@tonic-gate *
1217c478bd9Sstevel@tonic-gate * SKEW is used for a regular diskset since sideno could
1227c478bd9Sstevel@tonic-gate * have a value of 0 in that diskset type. add_name is
1237c478bd9Sstevel@tonic-gate * writing to the local mddb and a sideno of 0 in the
1247c478bd9Sstevel@tonic-gate * local mddb is reserved for non-diskset names.
1257c478bd9Sstevel@tonic-gate * SKEW is added to the sideno in the local mddb so that
1267c478bd9Sstevel@tonic-gate * the sideno for the diskset will never be 0.
1277c478bd9Sstevel@tonic-gate *
1287c478bd9Sstevel@tonic-gate * In a MNdiskset, the sideno will never be 0 (by design).
1297c478bd9Sstevel@tonic-gate * So, no SKEW is needed when writing to the local mddb.
1307c478bd9Sstevel@tonic-gate */
1317c478bd9Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
1327c478bd9Sstevel@tonic-gate if (add_name(local_sp, sideno, local_key,
133da833524Sjeanm sn->dname, sn->mnum, sn->cname, NULL, NULL,
134da833524Sjeanm ep) == -1)
1357c478bd9Sstevel@tonic-gate return (-1);
1367c478bd9Sstevel@tonic-gate } else {
1377c478bd9Sstevel@tonic-gate if (add_name(local_sp, sideno+SKEW, local_key,
138da833524Sjeanm sn->dname, sn->mnum, sn->cname, NULL, NULL,
139da833524Sjeanm ep) == -1)
1407c478bd9Sstevel@tonic-gate return (-1);
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate } else
1437c478bd9Sstevel@tonic-gate Free(nm);
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate return (0);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate * Delete sidename entry from local set using key and sideno.
1507c478bd9Sstevel@tonic-gate */
1517c478bd9Sstevel@tonic-gate static int
del_sideno_sidenm(mdkey_t sidekey,side_t sideno,md_error_t * ep)1527c478bd9Sstevel@tonic-gate del_sideno_sidenm(
1537c478bd9Sstevel@tonic-gate mdkey_t sidekey,
1547c478bd9Sstevel@tonic-gate side_t sideno,
1557c478bd9Sstevel@tonic-gate md_error_t *ep
1567c478bd9Sstevel@tonic-gate )
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1617c478bd9Sstevel@tonic-gate return (-1);
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate if (del_name(local_sp, sideno, sidekey, ep) == -1)
1647c478bd9Sstevel@tonic-gate mdclrerror(ep); /* ignore errs */
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate return (0);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate * Add namespace entries to local mddb for drives in drive list in
1727c478bd9Sstevel@tonic-gate * set descriptor.
1737c478bd9Sstevel@tonic-gate *
1747c478bd9Sstevel@tonic-gate * If a MNset and if this host is being added to the set (this host
1757c478bd9Sstevel@tonic-gate * is in the node_v list), add a namespace entry for the name of
1767c478bd9Sstevel@tonic-gate * each drive using this host's sideno.
1777c478bd9Sstevel@tonic-gate *
1787c478bd9Sstevel@tonic-gate * If not a MNset, add namespace entries for all the new hosts being
1797c478bd9Sstevel@tonic-gate * added to this set (list in node_v).
1807c478bd9Sstevel@tonic-gate */
1817c478bd9Sstevel@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)1827c478bd9Sstevel@tonic-gate add_drv_sidenms(
1837c478bd9Sstevel@tonic-gate char *hostname,
1847c478bd9Sstevel@tonic-gate mdsetname_t *sp,
1857c478bd9Sstevel@tonic-gate md_set_desc *sd,
1867c478bd9Sstevel@tonic-gate int node_c,
1877c478bd9Sstevel@tonic-gate char **node_v,
1887c478bd9Sstevel@tonic-gate md_error_t *ep
1897c478bd9Sstevel@tonic-gate )
1907c478bd9Sstevel@tonic-gate {
1917c478bd9Sstevel@tonic-gate mdsetname_t *my_sp;
1927c478bd9Sstevel@tonic-gate md_drive_desc *dd, *my_dd, *p, *q;
1937c478bd9Sstevel@tonic-gate mddrivename_t *dn, *my_dn;
1947c478bd9Sstevel@tonic-gate int i;
1957c478bd9Sstevel@tonic-gate side_t sideno = 0, mysideno = 0;
1967c478bd9Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
1977c478bd9Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
1987c478bd9Sstevel@tonic-gate int devid_same = -1;
1997c478bd9Sstevel@tonic-gate int using_devid = 0;
2007c478bd9Sstevel@tonic-gate md_mnnode_desc *nd;
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate assert(sd->sd_drvs != NULL);
2037c478bd9Sstevel@tonic-gate dd = sd->sd_drvs;
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate if (dd->dd_dnp == NULL)
2067c478bd9Sstevel@tonic-gate return;
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate if ((my_sp = metasetname(sp->setname, ep)) == NULL)
2097c478bd9Sstevel@tonic-gate return;
2107c478bd9Sstevel@tonic-gate metaflushsetname(my_sp);
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate /* If a MN diskset */
2137c478bd9Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
2147c478bd9Sstevel@tonic-gate /* Find sideno associated with RPC client. */
2157c478bd9Sstevel@tonic-gate nd = sd->sd_nodelist;
2167c478bd9Sstevel@tonic-gate while (nd) {
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate if (strcmp(nd->nd_nodename, hostname) == 0) {
2197c478bd9Sstevel@tonic-gate sideno = nd->nd_nodeid;
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate /* While looping, find my side num as well */
2237c478bd9Sstevel@tonic-gate if (strcmp(nd->nd_nodename, mynode()) == 0) {
2247c478bd9Sstevel@tonic-gate mysideno = nd->nd_nodeid;
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate if ((sideno) && (mysideno)) {
2287c478bd9Sstevel@tonic-gate break;
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate nd = nd->nd_next;
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate if (!sideno) {
2347c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE,
2357c478bd9Sstevel@tonic-gate sp->setno, hostname, NULL, sp->setname);
2367c478bd9Sstevel@tonic-gate return;
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate } else {
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate * if not a MN diskset
2417c478bd9Sstevel@tonic-gate * do action for traditional diskset.
2427c478bd9Sstevel@tonic-gate * despite of the rpc version
2437c478bd9Sstevel@tonic-gate */
2447c478bd9Sstevel@tonic-gate for (sideno = 0; sideno < MD_MAXSIDES; sideno++) {
2457c478bd9Sstevel@tonic-gate /* Skip empty slots */
2467c478bd9Sstevel@tonic-gate if (sd->sd_nodes[sideno][0] == '\0')
2477c478bd9Sstevel@tonic-gate continue;
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate if (strcmp(hostname, sd->sd_nodes[sideno]) == 0)
2507c478bd9Sstevel@tonic-gate break;
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate if (sideno == MD_MAXSIDES) {
2547c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno,
2557c478bd9Sstevel@tonic-gate hostname, NULL, sp->setname);
2567c478bd9Sstevel@tonic-gate return;
2577c478bd9Sstevel@tonic-gate }
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate if ((my_dd = metaget_drivedesc_sideno(my_sp, sideno, MD_BASICNAME_OK,
2607c478bd9Sstevel@tonic-gate ep)) == NULL) {
2617c478bd9Sstevel@tonic-gate if (! mdisok(ep))
2627c478bd9Sstevel@tonic-gate return;
2637c478bd9Sstevel@tonic-gate /* we are supposed to have drives!!!! */
2647c478bd9Sstevel@tonic-gate assert(0);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate /*
2687c478bd9Sstevel@tonic-gate * The system is either all devid or all
2697c478bd9Sstevel@tonic-gate * non-devid so we look at the first item
2707c478bd9Sstevel@tonic-gate * in the list to determine if we're using devids or not.
2717c478bd9Sstevel@tonic-gate * We also check to make sure it's not a multi-node diskset.
2727c478bd9Sstevel@tonic-gate * If it is, we don't use devid's.
2737c478bd9Sstevel@tonic-gate *
2747c478bd9Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
2757c478bd9Sstevel@tonic-gate * points to a '' string of devid. We need to check this
2767c478bd9Sstevel@tonic-gate * before set the using_devid.
2777c478bd9Sstevel@tonic-gate */
2787c478bd9Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
2797c478bd9Sstevel@tonic-gate (!(MD_MNSET_DESC(sd))))
2807c478bd9Sstevel@tonic-gate using_devid = 1;
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate /*
2837c478bd9Sstevel@tonic-gate * We have to match-up the dd that were passed
2847c478bd9Sstevel@tonic-gate * across the wire to the dd we have in this daemon.
2857c478bd9Sstevel@tonic-gate * That way we can pick up the new sidenames that were
2867c478bd9Sstevel@tonic-gate * passed to us and match them up with the local namespace key.
2877c478bd9Sstevel@tonic-gate * Only we have the key, this cannot be passed in.
2887c478bd9Sstevel@tonic-gate */
2897c478bd9Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
2907c478bd9Sstevel@tonic-gate dn = p->dd_dnp;
2917c478bd9Sstevel@tonic-gate devid_remote = NULL;
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
2947c478bd9Sstevel@tonic-gate using_devid) {
2957c478bd9Sstevel@tonic-gate /*
2967c478bd9Sstevel@tonic-gate * We have a devid so use it
2977c478bd9Sstevel@tonic-gate */
2987c478bd9Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
3027c478bd9Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
3037c478bd9Sstevel@tonic-gate /* something went really wrong. Can't process */
3047c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
3057c478bd9Sstevel@tonic-gate hostname, dn->cname, sp->setname);
3067c478bd9Sstevel@tonic-gate return;
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate for (q = my_dd; q != NULL; q = q->dd_next) {
3107c478bd9Sstevel@tonic-gate my_dn = q->dd_dnp;
3117c478bd9Sstevel@tonic-gate devid_same = -1;
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate if (my_dn->devid != NULL && using_devid) {
3147c478bd9Sstevel@tonic-gate if (devid_str_decode(my_dn->devid,
3157c478bd9Sstevel@tonic-gate &devid_local, NULL) == 0) {
3167c478bd9Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
3177c478bd9Sstevel@tonic-gate devid_local);
3187c478bd9Sstevel@tonic-gate devid_free(devid_local);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate if (using_devid && devid_same == 0) {
3237c478bd9Sstevel@tonic-gate break;
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate if (!using_devid &&
3277c478bd9Sstevel@tonic-gate strcmp(my_dn->cname, dn->cname) == 0)
3287c478bd9Sstevel@tonic-gate break;
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate if (devid_remote) {
3327c478bd9Sstevel@tonic-gate devid_free(devid_remote);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate assert(q != NULL);
3357c478bd9Sstevel@tonic-gate assert(my_dn->side_names_key != MD_KEYWILD);
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) {
3387c478bd9Sstevel@tonic-gate /*
3397c478bd9Sstevel@tonic-gate * Add the side names to the local db
3407c478bd9Sstevel@tonic-gate * for this node only.
3417c478bd9Sstevel@tonic-gate */
3427c478bd9Sstevel@tonic-gate if (add_sideno_sidenm(dn->side_names,
3437c478bd9Sstevel@tonic-gate my_dn->side_names_key, mysideno, sd, ep))
3447c478bd9Sstevel@tonic-gate return;
3457c478bd9Sstevel@tonic-gate /*
3467c478bd9Sstevel@tonic-gate * Sidenames for this drive were added
3477c478bd9Sstevel@tonic-gate * to this host during the routine adddrvs.
3487c478bd9Sstevel@tonic-gate * The sidenames that were added are the
3497c478bd9Sstevel@tonic-gate * names associated with this drive on
3507c478bd9Sstevel@tonic-gate * each of the hosts that were previously
3517c478bd9Sstevel@tonic-gate * in the set.
3527c478bd9Sstevel@tonic-gate * When the sidename for this drive on
3537c478bd9Sstevel@tonic-gate * this host is added, the sidename
3547c478bd9Sstevel@tonic-gate * from the host executing the command
3557c478bd9Sstevel@tonic-gate * (not this host) is sent to this host.
3567c478bd9Sstevel@tonic-gate * This host finds the originating host's
3577c478bd9Sstevel@tonic-gate * sidename and can then determine this
3587c478bd9Sstevel@tonic-gate * host's sidename.
3597c478bd9Sstevel@tonic-gate * The sidenames from the other hosts serve
3607c478bd9Sstevel@tonic-gate * only as temporary sidenames until this
3617c478bd9Sstevel@tonic-gate * host's sidename can be added.
3627c478bd9Sstevel@tonic-gate * In order to conserve space in the
3637c478bd9Sstevel@tonic-gate * local mddb, the code now deletes the
3647c478bd9Sstevel@tonic-gate * temporary sidenames added during adddrvs.
3657c478bd9Sstevel@tonic-gate * When finished, only the sidename for this
3667c478bd9Sstevel@tonic-gate * node should be left.
3677c478bd9Sstevel@tonic-gate * Ignore any errors during this process since
3687c478bd9Sstevel@tonic-gate * a failure to delete the extraneous
3697c478bd9Sstevel@tonic-gate * sidenames shouldn't cause this routine
3707c478bd9Sstevel@tonic-gate * to fail (in case that sidename didn't exist).
3717c478bd9Sstevel@tonic-gate */
3727c478bd9Sstevel@tonic-gate nd = sd->sd_nodelist;
3737c478bd9Sstevel@tonic-gate while (nd) {
3747c478bd9Sstevel@tonic-gate if (nd->nd_nodeid != mysideno) {
3757c478bd9Sstevel@tonic-gate if (del_sideno_sidenm(
3767c478bd9Sstevel@tonic-gate dn->side_names_key,
3777c478bd9Sstevel@tonic-gate nd->nd_nodeid, ep) == -1)
3787c478bd9Sstevel@tonic-gate mdclrerror(ep);
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate nd = nd->nd_next;
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate } else {
3837c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
3847c478bd9Sstevel@tonic-gate /* Skip empty slots */
3857c478bd9Sstevel@tonic-gate if (sd->sd_nodes[i][0] == '\0')
3867c478bd9Sstevel@tonic-gate continue;
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate /* Skip nodes not being added */
3897c478bd9Sstevel@tonic-gate if (! strinlst(sd->sd_nodes[i],
3907c478bd9Sstevel@tonic-gate node_c, node_v))
3917c478bd9Sstevel@tonic-gate continue;
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate /* Add the per side names to local db */
3947c478bd9Sstevel@tonic-gate if (add_sideno_sidenm(dn->side_names,
3957c478bd9Sstevel@tonic-gate my_dn->side_names_key, i, sd, ep))
3967c478bd9Sstevel@tonic-gate return;
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate }
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate /* ARGSUSED */
4037c478bd9Sstevel@tonic-gate bool_t
mdrpc_flush_internal_common(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4047c478bd9Sstevel@tonic-gate mdrpc_flush_internal_common(mdrpc_null_args *args, mdrpc_generic_res *res,
4057c478bd9Sstevel@tonic-gate struct svc_req *rqstp)
4067c478bd9Sstevel@tonic-gate {
4077c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
408ee8af371Sachimm int err, op_mode = W_OK;
4097c478bd9Sstevel@tonic-gate
4102a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
4117c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4127c478bd9Sstevel@tonic-gate return (FALSE);
4137c478bd9Sstevel@tonic-gate else if (err != 0)
4147c478bd9Sstevel@tonic-gate return (TRUE);
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate metaflushnames(1);
4177c478bd9Sstevel@tonic-gate
4187c478bd9Sstevel@tonic-gate err = svc_fini(ep);
4197c478bd9Sstevel@tonic-gate
4207c478bd9Sstevel@tonic-gate return (TRUE);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate bool_t
mdrpc_flush_internal_1_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4247c478bd9Sstevel@tonic-gate mdrpc_flush_internal_1_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
4257c478bd9Sstevel@tonic-gate struct svc_req *rqstp)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate return (mdrpc_flush_internal_common(args, res, rqstp));
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate
4307c478bd9Sstevel@tonic-gate bool_t
mdrpc_flush_internal_2_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4317c478bd9Sstevel@tonic-gate mdrpc_flush_internal_2_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
4327c478bd9Sstevel@tonic-gate struct svc_req *rqstp)
4337c478bd9Sstevel@tonic-gate {
4347c478bd9Sstevel@tonic-gate return (mdrpc_flush_internal_common(args, res, rqstp));
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate * add 1 or more namespace entries per drive record.
4397c478bd9Sstevel@tonic-gate * (into the local namespace)
4407c478bd9Sstevel@tonic-gate */
4417c478bd9Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_common(mdrpc_drv_sidenm_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)4427c478bd9Sstevel@tonic-gate mdrpc_add_drv_sidenms_common(
4437c478bd9Sstevel@tonic-gate mdrpc_drv_sidenm_2_args_r1 *args,
4447c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
4457c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
4467c478bd9Sstevel@tonic-gate )
4477c478bd9Sstevel@tonic-gate {
4487c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
4497c478bd9Sstevel@tonic-gate int err;
4507c478bd9Sstevel@tonic-gate int op_mode = W_OK;
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate /* setup, check permissions */
4537c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4547c478bd9Sstevel@tonic-gate return (FALSE);
4557c478bd9Sstevel@tonic-gate else if (err != 0)
4567c478bd9Sstevel@tonic-gate return (TRUE);
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
4597c478bd9Sstevel@tonic-gate return (TRUE);
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate /* doit */
4627c478bd9Sstevel@tonic-gate add_drv_sidenms(args->hostname, args->sp, args->sd,
4637c478bd9Sstevel@tonic-gate args->node_v.node_v_len, args->node_v.node_v_val, ep);
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate err = svc_fini(ep);
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate return (TRUE);
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate /*
4717c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
4727c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
4737c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
4747c478bd9Sstevel@tonic-gate */
4757c478bd9Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_1_svc(mdrpc_drv_sidenm_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4767c478bd9Sstevel@tonic-gate mdrpc_add_drv_sidenms_1_svc(
4777c478bd9Sstevel@tonic-gate mdrpc_drv_sidenm_args *args,
4787c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
4797c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
4807c478bd9Sstevel@tonic-gate )
4817c478bd9Sstevel@tonic-gate {
4827c478bd9Sstevel@tonic-gate bool_t retval;
4837c478bd9Sstevel@tonic-gate mdrpc_drv_sidenm_2_args_r1 v2_args;
4847c478bd9Sstevel@tonic-gate int i, j;
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate /* allocate memory */
4877c478bd9Sstevel@tonic-gate v2_args.sd = Zalloc(sizeof (md_set_desc));
4887c478bd9Sstevel@tonic-gate alloc_newdrvdesc(args->sd->sd_drvs, &v2_args.sd->sd_drvs);
4892a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate /* build args */
4927c478bd9Sstevel@tonic-gate v2_args.hostname = args->hostname;
4937c478bd9Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
4947c478bd9Sstevel@tonic-gate v2_args.sp = args->sp;
4957c478bd9Sstevel@tonic-gate /* set descriptor */
4967c478bd9Sstevel@tonic-gate v2_args.sd->sd_ctime = args->sd->sd_ctime;
4977c478bd9Sstevel@tonic-gate v2_args.sd->sd_genid = args->sd->sd_genid;
4987c478bd9Sstevel@tonic-gate v2_args.sd->sd_setno = args->sd->sd_setno;
4997c478bd9Sstevel@tonic-gate v2_args.sd->sd_flags = args->sd->sd_flags;
5007c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
5017c478bd9Sstevel@tonic-gate v2_args.sd->sd_isown[i] = args->sd->sd_isown[i];
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j++)
5047c478bd9Sstevel@tonic-gate v2_args.sd->sd_nodes[i][j] =
5057c478bd9Sstevel@tonic-gate args->sd->sd_nodes[i][j];
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate v2_args.sd->sd_med = args->sd->sd_med;
5087c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
5097c478bd9Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->sd->sd_drvs, v2_args.sd->sd_drvs);
5107c478bd9Sstevel@tonic-gate v2_args.node_v.node_v_len = args->node_v.node_v_len;
5117c478bd9Sstevel@tonic-gate v2_args.node_v.node_v_val = args->node_v.node_v_val;
5127c478bd9Sstevel@tonic-gate
5137c478bd9Sstevel@tonic-gate retval = mdrpc_add_drv_sidenms_common(&v2_args, res, rqstp);
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate free(v2_args.sd);
5167c478bd9Sstevel@tonic-gate free_newdrvdesc(v2_args.sd->sd_drvs);
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate return (retval);
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_2_svc(mdrpc_drv_sidenm_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)5227c478bd9Sstevel@tonic-gate mdrpc_add_drv_sidenms_2_svc(
5237c478bd9Sstevel@tonic-gate mdrpc_drv_sidenm_2_args *args,
5247c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
5257c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
5267c478bd9Sstevel@tonic-gate )
5277c478bd9Sstevel@tonic-gate {
5282a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
5297c478bd9Sstevel@tonic-gate switch (args->rev) {
5307c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
5317c478bd9Sstevel@tonic-gate return (mdrpc_add_drv_sidenms_common(
5327c478bd9Sstevel@tonic-gate &args->mdrpc_drv_sidenm_2_args_u.rev1, res, rqstp));
5337c478bd9Sstevel@tonic-gate default:
5347c478bd9Sstevel@tonic-gate return (FALSE);
5357c478bd9Sstevel@tonic-gate }
5367c478bd9Sstevel@tonic-gate }
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate static int
add_sidenamelist(mddrivename_t * dn,side_t thisside,md_set_record * sr,md_error_t * ep)5397c478bd9Sstevel@tonic-gate add_sidenamelist(
5407c478bd9Sstevel@tonic-gate mddrivename_t *dn,
5417c478bd9Sstevel@tonic-gate side_t thisside,
5427c478bd9Sstevel@tonic-gate md_set_record *sr, /* used by RPC version 2 */
5437c478bd9Sstevel@tonic-gate md_error_t *ep
5447c478bd9Sstevel@tonic-gate )
5457c478bd9Sstevel@tonic-gate {
5467c478bd9Sstevel@tonic-gate mdsidenames_t *sn;
5477c478bd9Sstevel@tonic-gate mdkey_t key;
5487c478bd9Sstevel@tonic-gate int err;
5497c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
5507c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
5517c478bd9Sstevel@tonic-gate md_mnnode_record *nr;
5527c478bd9Sstevel@tonic-gate uint_t nodeid = 0;
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
5557c478bd9Sstevel@tonic-gate return (-1);
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate key = MD_KEYWILD;
5587c478bd9Sstevel@tonic-gate
5597c478bd9Sstevel@tonic-gate /*
5607c478bd9Sstevel@tonic-gate * If a multi-node diskset, find nodeid associated with this node.
5617c478bd9Sstevel@tonic-gate */
5627c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
5637c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
5647c478bd9Sstevel@tonic-gate nr = mnsr->sr_nodechain;
5657c478bd9Sstevel@tonic-gate while (nr) {
5667c478bd9Sstevel@tonic-gate if (strcmp(nr->nr_nodename, mynode()) == 0) {
5677c478bd9Sstevel@tonic-gate break;
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate nr = nr->nr_next;
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate /*
5727c478bd9Sstevel@tonic-gate * If node is found, then a new drive is being added to
5737c478bd9Sstevel@tonic-gate * a MN set of which this node is a member.
5747c478bd9Sstevel@tonic-gate * If node is not found, then this host is being added to
5757c478bd9Sstevel@tonic-gate * a MN set that has drives associated with it.
5767c478bd9Sstevel@tonic-gate */
5777c478bd9Sstevel@tonic-gate if (nr)
5787c478bd9Sstevel@tonic-gate nodeid = nr->nr_nodeid;
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) {
5817c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
5827c478bd9Sstevel@tonic-gate /*
5837c478bd9Sstevel@tonic-gate * In multi-node disksets, only add side information
5847c478bd9Sstevel@tonic-gate * to the local mddb about this node.
5857c478bd9Sstevel@tonic-gate * If the sideno for this node is found, then
5867c478bd9Sstevel@tonic-gate * a new drive is being added to a MN set of
5877c478bd9Sstevel@tonic-gate * which this node is a member.
5887c478bd9Sstevel@tonic-gate * If the sideno for this node is not found, then
5897c478bd9Sstevel@tonic-gate * this host is being added to a MNset that
5907c478bd9Sstevel@tonic-gate * has drives associated with it. In this case,
5917c478bd9Sstevel@tonic-gate * need to add the sidename associated with the
5927c478bd9Sstevel@tonic-gate * rpc client, but since we don't know which node
5937c478bd9Sstevel@tonic-gate * is the client, then add temp entries for all sides.
5947c478bd9Sstevel@tonic-gate * Later, the sidename for this node will be set
5957c478bd9Sstevel@tonic-gate * via add_drv_sidenms and then the temp
5967c478bd9Sstevel@tonic-gate * sidenames can be removed.
5977c478bd9Sstevel@tonic-gate */
5987c478bd9Sstevel@tonic-gate if (nodeid == sn->sideno) {
5997c478bd9Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno, key,
600da833524Sjeanm sn->dname, sn->mnum, sn->cname,
601da833524Sjeanm NULL, NULL, ep)) == -1)
6027c478bd9Sstevel@tonic-gate return (-1);
6037c478bd9Sstevel@tonic-gate key = (mdkey_t)err;
6047c478bd9Sstevel@tonic-gate break;
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate } else {
6077c478bd9Sstevel@tonic-gate /*
6087c478bd9Sstevel@tonic-gate * When a sidename is added into the namespace the local
6097c478bd9Sstevel@tonic-gate * side information for the name is added first of all.
6107c478bd9Sstevel@tonic-gate * When the first sidename is created this causes the
6117c478bd9Sstevel@tonic-gate * devid of the disk to be recorded in the namespace, if
6127c478bd9Sstevel@tonic-gate * the non-local side information is added first then
6137c478bd9Sstevel@tonic-gate * there is the possibility of getting the wrong devid
6147c478bd9Sstevel@tonic-gate * because there is no guarantee that the dev_t (mnum in
6157c478bd9Sstevel@tonic-gate * this instance) is the same across all the nodes in
6167c478bd9Sstevel@tonic-gate * the set. So the only way to make sure that the
6177c478bd9Sstevel@tonic-gate * correct dev_t is used is to force the adding in of
6187c478bd9Sstevel@tonic-gate * the local sidename record first of all. This same
6197c478bd9Sstevel@tonic-gate * issue affects add_key_name().
6207c478bd9Sstevel@tonic-gate */
6217c478bd9Sstevel@tonic-gate if (sn->sideno != thisside)
6227c478bd9Sstevel@tonic-gate continue;
6237c478bd9Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno+SKEW, key,
624da833524Sjeanm sn->dname, sn->mnum, sn->cname, NULL,
625da833524Sjeanm NULL, ep)) == -1)
6267c478bd9Sstevel@tonic-gate return (-1);
6277c478bd9Sstevel@tonic-gate key = (mdkey_t)err;
6287c478bd9Sstevel@tonic-gate break;
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate /*
6337c478bd9Sstevel@tonic-gate * Now the other sides for non-MN set
6347c478bd9Sstevel@tonic-gate */
6357c478bd9Sstevel@tonic-gate if (!MD_MNSET_REC(sr)) {
6367c478bd9Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) {
6377c478bd9Sstevel@tonic-gate if (sn->sideno == thisside)
6387c478bd9Sstevel@tonic-gate continue;
6397c478bd9Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno+SKEW, key,
640da833524Sjeanm sn->dname, sn->mnum, sn->cname, NULL, NULL,
641da833524Sjeanm ep)) == -1)
6427c478bd9Sstevel@tonic-gate return (-1);
6437c478bd9Sstevel@tonic-gate key = (mdkey_t)err;
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate /* Temporarily add all sides. */
6487c478bd9Sstevel@tonic-gate if ((key == MD_KEYWILD) && (MD_MNSET_REC(sr))) {
6497c478bd9Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next) {
6507c478bd9Sstevel@tonic-gate sn = dn->side_names;
6517c478bd9Sstevel@tonic-gate if (sn) {
6527c478bd9Sstevel@tonic-gate if ((err = add_name(local_sp, sn->sideno, key,
653da833524Sjeanm sn->dname, sn->mnum, sn->cname,
654da833524Sjeanm NULL, NULL, ep)) == -1)
6557c478bd9Sstevel@tonic-gate return (-1);
6567c478bd9Sstevel@tonic-gate key = (mdkey_t)err;
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate }
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate dn->side_names_key = key;
6627c478bd9Sstevel@tonic-gate return (0);
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate
665da833524Sjeanm /*
666da833524Sjeanm * imp_adddrvs
667da833524Sjeanm * This is a version of adddrvs that is specific to the
668da833524Sjeanm * metaimport command. Due to the unavailability of some disks,
669da833524Sjeanm * information needs to be obtained about the disk from the devid so
670da833524Sjeanm * it can eventually be passed down to add_sidenamelist.
671da833524Sjeanm * Go ahead and set drive state to MD_DR_OK here so that no
672da833524Sjeanm * later RPC is needed to set OK where UNRLSV_REPLICATED could
673da833524Sjeanm * be cleared. Set record is still set to MD_SR_ADD which will force
674da833524Sjeanm * a cleanup of the set in case of panic.
675da833524Sjeanm */
676da833524Sjeanm void
imp_adddrvs(char * setname,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)677da833524Sjeanm imp_adddrvs(
678da833524Sjeanm char *setname,
679da833524Sjeanm md_drive_desc *dd,
680da833524Sjeanm md_timeval32_t timestamp,
681da833524Sjeanm ulong_t genid,
682da833524Sjeanm md_error_t *ep
683da833524Sjeanm )
684da833524Sjeanm {
685da833524Sjeanm mddb_userreq_t req;
686da833524Sjeanm md_drive_record *dr, *tdr;
687da833524Sjeanm md_set_record *sr;
688da833524Sjeanm md_drive_desc *p;
689da833524Sjeanm mddrivename_t *dn;
690da833524Sjeanm mdname_t *np;
691da833524Sjeanm md_dev64_t dev;
692da833524Sjeanm md_error_t xep = mdnullerror;
693da833524Sjeanm char *minorname = NULL;
694da833524Sjeanm ddi_devid_t devidp = NULL;
695da833524Sjeanm mdsidenames_t *sn;
696da833524Sjeanm mdsetname_t *local_sp;
697da833524Sjeanm
698da833524Sjeanm
699da833524Sjeanm if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) {
700da833524Sjeanm return;
701da833524Sjeanm }
702da833524Sjeanm
703da833524Sjeanm if ((sr = getsetbyname(setname, ep)) == NULL)
704da833524Sjeanm return;
705da833524Sjeanm
706da833524Sjeanm for (p = dd; p != NULL; p = p->dd_next) {
707da833524Sjeanm uint_t rep_slice;
708da833524Sjeanm int ret = 0;
709da833524Sjeanm
710da833524Sjeanm dn = p->dd_dnp;
711da833524Sjeanm
712da833524Sjeanm /*
713da833524Sjeanm * We need the minorname and devid string decoded from the
714da833524Sjeanm * devid to add the sidename for this drive to the
715da833524Sjeanm * local set.
716da833524Sjeanm */
717da833524Sjeanm ret = devid_str_decode(dn->devid, &devidp, &minorname);
718da833524Sjeanm if (ret != 0) {
719da833524Sjeanm /* failed to decode the devid */
720da833524Sjeanm goto out;
721da833524Sjeanm }
722da833524Sjeanm
723da833524Sjeanm sn = dn->side_names;
724da833524Sjeanm if (sn == NULL) {
725da833524Sjeanm dn->side_names_key = MD_KEYWILD;
726da833524Sjeanm continue;
727da833524Sjeanm }
728da833524Sjeanm
729da833524Sjeanm if ((dn->side_names_key = add_name(local_sp, SKEW, MD_KEYWILD,
730da833524Sjeanm sn->dname, sn->mnum, sn->cname, minorname, devidp,
731da833524Sjeanm ep)) == -1) {
732da833524Sjeanm devid_free(devidp);
733da833524Sjeanm devid_str_free(minorname);
734da833524Sjeanm goto out;
735da833524Sjeanm }
736da833524Sjeanm
737da833524Sjeanm devid_free(devidp);
738da833524Sjeanm devid_str_free(minorname);
739da833524Sjeanm
740da833524Sjeanm /* Create the drive record */
741da833524Sjeanm (void) memset(&req, 0, sizeof (req));
742da833524Sjeanm METAD_SETUP_DR(MD_DB_CREATE, 0);
743da833524Sjeanm req.ur_size = sizeof (*dr);
744da833524Sjeanm if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
745da833524Sjeanm (void) mdstealerror(ep, &req.ur_mde);
746da833524Sjeanm goto out;
747da833524Sjeanm }
748da833524Sjeanm
749da833524Sjeanm /* Fill in the drive record values */
750da833524Sjeanm dr = Zalloc(sizeof (*dr));
751da833524Sjeanm dr->dr_selfid = req.ur_recid;
752da833524Sjeanm dr->dr_dbcnt = p->dd_dbcnt;
753da833524Sjeanm dr->dr_dbsize = p->dd_dbsize;
754da833524Sjeanm dr->dr_key = dn->side_names_key;
755da833524Sjeanm
756da833524Sjeanm dr->dr_ctime = timestamp;
757da833524Sjeanm dr->dr_genid = genid;
758da833524Sjeanm dr->dr_revision = MD_DRIVE_RECORD_REVISION;
759da833524Sjeanm dr->dr_flags = MD_DR_OK;
760da833524Sjeanm if (p->dd_flags & MD_DR_UNRSLV_REPLICATED) {
761da833524Sjeanm dr->dr_flags |= MD_DR_UNRSLV_REPLICATED;
762da833524Sjeanm sr->sr_flags |= MD_SR_UNRSLV_REPLICATED;
763da833524Sjeanm }
764da833524Sjeanm
765da833524Sjeanm /* Link the drive records and fill in in-core data */
766da833524Sjeanm dr_cache_add(sr, dr);
767da833524Sjeanm
768da833524Sjeanm dev = NODEV64;
769da833524Sjeanm if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
770da833524Sjeanm ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
771da833524Sjeanm dev = np->dev;
772da833524Sjeanm else
773da833524Sjeanm mdclrerror(&xep);
774da833524Sjeanm
775da833524Sjeanm SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
776da833524Sjeanm MD_LOCAL_SET, dev);
777da833524Sjeanm SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
778da833524Sjeanm sr->sr_setno, dev);
779da833524Sjeanm }
780da833524Sjeanm
781da833524Sjeanm /* Commit all the records atomically */
782da833524Sjeanm commitset(sr, TRUE, ep);
783da833524Sjeanm free_sr(sr);
784da833524Sjeanm return;
785da833524Sjeanm
786da833524Sjeanm out:
787da833524Sjeanm /* If failures, remove drive records. */
788da833524Sjeanm dr = tdr = sr->sr_drivechain;
789da833524Sjeanm while (dr != NULL) {
790da833524Sjeanm tdr = dr->dr_next;
791da833524Sjeanm if (del_name(local_sp, 0, dr->dr_key, &xep))
792da833524Sjeanm mdclrerror(&xep);
793da833524Sjeanm sr_del_drv(sr, dr->dr_selfid);
794da833524Sjeanm dr = tdr;
795da833524Sjeanm }
796da833524Sjeanm }
797da833524Sjeanm
7987c478bd9Sstevel@tonic-gate static void
adddrvs(char * setname,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)7997c478bd9Sstevel@tonic-gate adddrvs(
8007c478bd9Sstevel@tonic-gate char *setname,
8017c478bd9Sstevel@tonic-gate md_drive_desc *dd,
8027c478bd9Sstevel@tonic-gate md_timeval32_t timestamp,
8037c478bd9Sstevel@tonic-gate ulong_t genid,
8047c478bd9Sstevel@tonic-gate md_error_t *ep
8057c478bd9Sstevel@tonic-gate )
8067c478bd9Sstevel@tonic-gate {
8077c478bd9Sstevel@tonic-gate mddb_userreq_t req;
8087c478bd9Sstevel@tonic-gate md_drive_record *dr;
8097c478bd9Sstevel@tonic-gate md_set_record *sr;
8107c478bd9Sstevel@tonic-gate md_drive_desc *p;
8117c478bd9Sstevel@tonic-gate mddrivename_t *dn;
8127c478bd9Sstevel@tonic-gate mdname_t *np;
8137c478bd9Sstevel@tonic-gate md_dev64_t dev;
8147c478bd9Sstevel@tonic-gate md_error_t xep = mdnullerror;
8157c478bd9Sstevel@tonic-gate int i;
8167c478bd9Sstevel@tonic-gate
8177c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
8187c478bd9Sstevel@tonic-gate return;
8197c478bd9Sstevel@tonic-gate
8207c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr))
8217c478bd9Sstevel@tonic-gate i = 0;
8227c478bd9Sstevel@tonic-gate else {
8237c478bd9Sstevel@tonic-gate /* get thisside */
8247c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
8257c478bd9Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
8267c478bd9Sstevel@tonic-gate continue;
8277c478bd9Sstevel@tonic-gate if (strcmp(mynode(), sr->sr_nodes[i]) == 0)
8287c478bd9Sstevel@tonic-gate break;
8297c478bd9Sstevel@tonic-gate }
8307c478bd9Sstevel@tonic-gate
8317c478bd9Sstevel@tonic-gate if (i == MD_MAXSIDES) {
8327c478bd9Sstevel@tonic-gate /* so find the first free slot! */
8337c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
8347c478bd9Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
8357c478bd9Sstevel@tonic-gate break;
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate }
8397c478bd9Sstevel@tonic-gate
8407c478bd9Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
8417c478bd9Sstevel@tonic-gate uint_t rep_slice;
8427c478bd9Sstevel@tonic-gate
8437c478bd9Sstevel@tonic-gate dn = p->dd_dnp;
8447c478bd9Sstevel@tonic-gate
8457c478bd9Sstevel@tonic-gate /* Add the per side names to the local db */
8467c478bd9Sstevel@tonic-gate if (add_sidenamelist(dn, (side_t)i, sr, ep)) {
8477c478bd9Sstevel@tonic-gate free_sr(sr);
8487c478bd9Sstevel@tonic-gate return;
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gate /* Create the drive record */
8527c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
8537c478bd9Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_CREATE, 0);
8547c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*dr);
8557c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
8567c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
8577c478bd9Sstevel@tonic-gate free_sr(sr);
8587c478bd9Sstevel@tonic-gate return;
8597c478bd9Sstevel@tonic-gate }
8607c478bd9Sstevel@tonic-gate
8617c478bd9Sstevel@tonic-gate /* Fill in the drive record values */
8627c478bd9Sstevel@tonic-gate dr = Zalloc(sizeof (*dr));
8637c478bd9Sstevel@tonic-gate dr->dr_selfid = req.ur_recid;
8647c478bd9Sstevel@tonic-gate dr->dr_dbcnt = p->dd_dbcnt;
8657c478bd9Sstevel@tonic-gate dr->dr_dbsize = p->dd_dbsize;
8667c478bd9Sstevel@tonic-gate dr->dr_key = dn->side_names_key;
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate dr->dr_ctime = timestamp;
8697c478bd9Sstevel@tonic-gate dr->dr_genid = genid;
8707c478bd9Sstevel@tonic-gate dr->dr_revision = MD_DRIVE_RECORD_REVISION;
8717c478bd9Sstevel@tonic-gate dr->dr_flags = MD_DR_ADD;
8727c478bd9Sstevel@tonic-gate
8737c478bd9Sstevel@tonic-gate /* Link the drive records and fill in in-core data */
8747c478bd9Sstevel@tonic-gate dr_cache_add(sr, dr);
8757c478bd9Sstevel@tonic-gate
8767c478bd9Sstevel@tonic-gate dev = NODEV64;
8777c478bd9Sstevel@tonic-gate if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
8787c478bd9Sstevel@tonic-gate ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
8797c478bd9Sstevel@tonic-gate dev = np->dev;
8807c478bd9Sstevel@tonic-gate else
8817c478bd9Sstevel@tonic-gate mdclrerror(&xep);
8827c478bd9Sstevel@tonic-gate
8837c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
8847c478bd9Sstevel@tonic-gate MD_LOCAL_SET, dev);
8857c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
8867c478bd9Sstevel@tonic-gate sr->sr_setno, dev);
8877c478bd9Sstevel@tonic-gate }
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate /* Commit all the records atomically */
8907c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
8917c478bd9Sstevel@tonic-gate free_sr(sr);
8927c478bd9Sstevel@tonic-gate }
8937c478bd9Sstevel@tonic-gate
8947c478bd9Sstevel@tonic-gate /*
8957c478bd9Sstevel@tonic-gate * add 1 or more drive records to a set.
8967c478bd9Sstevel@tonic-gate */
8977c478bd9Sstevel@tonic-gate bool_t
mdrpc_adddrvs_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)8987c478bd9Sstevel@tonic-gate mdrpc_adddrvs_common(
8997c478bd9Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args,
9007c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
9017c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
9027c478bd9Sstevel@tonic-gate )
9037c478bd9Sstevel@tonic-gate {
9047c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
9057c478bd9Sstevel@tonic-gate int err;
9067c478bd9Sstevel@tonic-gate int op_mode = W_OK;
9077c478bd9Sstevel@tonic-gate
9087c478bd9Sstevel@tonic-gate /* setup, check permissions */
9097c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
9107c478bd9Sstevel@tonic-gate return (FALSE);
9117c478bd9Sstevel@tonic-gate else if (err != 0)
9127c478bd9Sstevel@tonic-gate return (TRUE);
9137c478bd9Sstevel@tonic-gate
9147c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
9157c478bd9Sstevel@tonic-gate return (TRUE);
9167c478bd9Sstevel@tonic-gate
9177c478bd9Sstevel@tonic-gate /* doit */
9187c478bd9Sstevel@tonic-gate adddrvs(args->sp->setname, args->drivedescs, args->timestamp,
9197c478bd9Sstevel@tonic-gate args->genid, ep);
9207c478bd9Sstevel@tonic-gate
9217c478bd9Sstevel@tonic-gate err = svc_fini(ep);
9227c478bd9Sstevel@tonic-gate
9237c478bd9Sstevel@tonic-gate return (TRUE);
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate
9267c478bd9Sstevel@tonic-gate /*
9277c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
9287c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
9297c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
9307c478bd9Sstevel@tonic-gate */
9317c478bd9Sstevel@tonic-gate bool_t
mdrpc_adddrvs_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9327c478bd9Sstevel@tonic-gate mdrpc_adddrvs_1_svc(
9337c478bd9Sstevel@tonic-gate mdrpc_drives_args *args,
9347c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
9357c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
9367c478bd9Sstevel@tonic-gate )
9377c478bd9Sstevel@tonic-gate {
9387c478bd9Sstevel@tonic-gate bool_t retval;
9397c478bd9Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args;
9407c478bd9Sstevel@tonic-gate
9417c478bd9Sstevel@tonic-gate /* allocate memory */
9427c478bd9Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
9432a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
9447c478bd9Sstevel@tonic-gate
9457c478bd9Sstevel@tonic-gate /* build args */
9467c478bd9Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
9477c478bd9Sstevel@tonic-gate v2_args.sp = args->sp;
9487c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
9497c478bd9Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
9507c478bd9Sstevel@tonic-gate v2_args.timestamp = args->timestamp;
9517c478bd9Sstevel@tonic-gate v2_args.genid = args->genid;
9527c478bd9Sstevel@tonic-gate
9537c478bd9Sstevel@tonic-gate retval = mdrpc_adddrvs_common(&v2_args, res, rqstp);
9547c478bd9Sstevel@tonic-gate
9557c478bd9Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
9567c478bd9Sstevel@tonic-gate
9577c478bd9Sstevel@tonic-gate return (retval);
9587c478bd9Sstevel@tonic-gate }
9597c478bd9Sstevel@tonic-gate
9607c478bd9Sstevel@tonic-gate bool_t
mdrpc_adddrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9617c478bd9Sstevel@tonic-gate mdrpc_adddrvs_2_svc(
9627c478bd9Sstevel@tonic-gate mdrpc_drives_2_args *args,
9637c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
9647c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
9657c478bd9Sstevel@tonic-gate )
9667c478bd9Sstevel@tonic-gate {
9672a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
9687c478bd9Sstevel@tonic-gate switch (args->rev) {
9697c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
9707c478bd9Sstevel@tonic-gate return (mdrpc_adddrvs_common(
9717c478bd9Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
9727c478bd9Sstevel@tonic-gate default:
9737c478bd9Sstevel@tonic-gate return (FALSE);
9747c478bd9Sstevel@tonic-gate }
9757c478bd9Sstevel@tonic-gate }
9767c478bd9Sstevel@tonic-gate
977da833524Sjeanm /*
978da833524Sjeanm * add 1 or more drive records to a set when importing.
979da833524Sjeanm */
980da833524Sjeanm bool_t
mdrpc_imp_adddrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)981da833524Sjeanm mdrpc_imp_adddrvs_2_svc(
982da833524Sjeanm mdrpc_drives_2_args *args,
983da833524Sjeanm mdrpc_generic_res *res,
984da833524Sjeanm struct svc_req *rqstp /* RPC stuff */
985da833524Sjeanm )
986da833524Sjeanm {
987da833524Sjeanm mdrpc_drives_2_args_r1 *v2_args;
988da833524Sjeanm md_error_t *ep = &res->status;
989da833524Sjeanm int err;
990da833524Sjeanm int op_mode = W_OK;
991da833524Sjeanm
9922a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
993da833524Sjeanm switch (args->rev) {
994da833524Sjeanm case MD_METAD_ARGS_REV_1:
995da833524Sjeanm v2_args = &args->mdrpc_drives_2_args_u.rev1;
996da833524Sjeanm if (v2_args == NULL) {
997da833524Sjeanm return (FALSE);
998da833524Sjeanm }
999da833524Sjeanm break;
1000da833524Sjeanm default:
1001da833524Sjeanm return (FALSE);
1002da833524Sjeanm }
1003da833524Sjeanm
1004da833524Sjeanm /* setup, check permissions */
1005da833524Sjeanm if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1006da833524Sjeanm return (FALSE);
1007da833524Sjeanm else if (err != 0)
1008da833524Sjeanm return (TRUE);
1009da833524Sjeanm
1010da833524Sjeanm if (check_set_lock(op_mode, v2_args->cl_sk, ep))
1011da833524Sjeanm return (TRUE);
1012da833524Sjeanm
1013da833524Sjeanm /* doit */
1014da833524Sjeanm imp_adddrvs(v2_args->sp->setname, v2_args->drivedescs,
1015da833524Sjeanm v2_args->timestamp, v2_args->genid, ep);
1016da833524Sjeanm
1017da833524Sjeanm err = svc_fini(ep);
1018da833524Sjeanm
1019da833524Sjeanm return (TRUE);
1020da833524Sjeanm }
1021da833524Sjeanm
10227c478bd9Sstevel@tonic-gate static void
addhosts(char * setname,int node_c,char ** node_v,int version,md_error_t * ep)10237c478bd9Sstevel@tonic-gate addhosts(
10247c478bd9Sstevel@tonic-gate char *setname,
10257c478bd9Sstevel@tonic-gate int node_c,
10267c478bd9Sstevel@tonic-gate char **node_v,
10277c478bd9Sstevel@tonic-gate int version, /* RPC version of calling routine */
10287c478bd9Sstevel@tonic-gate md_error_t *ep
10297c478bd9Sstevel@tonic-gate )
10307c478bd9Sstevel@tonic-gate {
10317c478bd9Sstevel@tonic-gate mddb_userreq_t req;
10327c478bd9Sstevel@tonic-gate md_set_record *sr;
10337c478bd9Sstevel@tonic-gate int i, j;
10347c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
10357c478bd9Sstevel@tonic-gate md_mnnode_record *nr;
10367c478bd9Sstevel@tonic-gate mddb_set_node_params_t snp;
10377c478bd9Sstevel@tonic-gate int nodecnt;
10387c478bd9Sstevel@tonic-gate mndiskset_membershiplist_t *nl, *nl2;
10397c478bd9Sstevel@tonic-gate
10407c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
10417c478bd9Sstevel@tonic-gate return;
10427c478bd9Sstevel@tonic-gate
10437c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
10447c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
10457c478bd9Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
10467c478bd9Sstevel@tonic-gate /*
10477c478bd9Sstevel@tonic-gate * Verify nodes are in membership list on THIS node.
10487c478bd9Sstevel@tonic-gate * Initiating node has verified that nodes are in membership
10497c478bd9Sstevel@tonic-gate * list on the initiating node.
10507c478bd9Sstevel@tonic-gate * Get membershiplist from API routine. If there's
10517c478bd9Sstevel@tonic-gate * an error, fail to add hosts and pass back error.
10527c478bd9Sstevel@tonic-gate */
10537c478bd9Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
10547c478bd9Sstevel@tonic-gate free_sr(sr);
10557c478bd9Sstevel@tonic-gate return;
10567c478bd9Sstevel@tonic-gate }
10577c478bd9Sstevel@tonic-gate /* Verify that all nodes are in member list */
10587c478bd9Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
10597c478bd9Sstevel@tonic-gate /*
10607c478bd9Sstevel@tonic-gate * If node in list isn't a member of the membership,
10617c478bd9Sstevel@tonic-gate * just return error.
10627c478bd9Sstevel@tonic-gate */
10637c478bd9Sstevel@tonic-gate if (meta_is_member(node_v[i], NULL, nl) == 0) {
10647c478bd9Sstevel@tonic-gate meta_free_nodelist(nl);
10657c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
10667c478bd9Sstevel@tonic-gate sr->sr_setno, node_v[i], NULL, setname);
10677c478bd9Sstevel@tonic-gate free_sr(sr);
10687c478bd9Sstevel@tonic-gate return;
10697c478bd9Sstevel@tonic-gate }
10707c478bd9Sstevel@tonic-gate }
10717c478bd9Sstevel@tonic-gate }
10727c478bd9Sstevel@tonic-gate
10737c478bd9Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
10747c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
10757c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
10767c478bd9Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
10777c478bd9Sstevel@tonic-gate /* Create the node record */
10787c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
10797c478bd9Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_CREATE, 0);
10807c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*nr);
10817c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
10827c478bd9Sstevel@tonic-gate != 0) {
10837c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
10847c478bd9Sstevel@tonic-gate meta_free_nodelist(nl);
10857c478bd9Sstevel@tonic-gate free_sr(sr);
10867c478bd9Sstevel@tonic-gate return;
10877c478bd9Sstevel@tonic-gate }
10887c478bd9Sstevel@tonic-gate
10897c478bd9Sstevel@tonic-gate nr = Zalloc(sizeof (*nr));
10907c478bd9Sstevel@tonic-gate nr->nr_revision = MD_MNNODE_RECORD_REVISION;
10917c478bd9Sstevel@tonic-gate nr->nr_selfid = req.ur_recid;
10927c478bd9Sstevel@tonic-gate nr->nr_ctime = sr->sr_ctime;
10937c478bd9Sstevel@tonic-gate nr->nr_genid = sr->sr_genid;
10947c478bd9Sstevel@tonic-gate nr->nr_flags = MD_MN_NODE_ADD;
10957c478bd9Sstevel@tonic-gate nl2 = nl;
10967c478bd9Sstevel@tonic-gate while (nl2) {
10977c478bd9Sstevel@tonic-gate if (strcmp(nl2->msl_node_name, node_v[i])
10987c478bd9Sstevel@tonic-gate == 0) {
10997c478bd9Sstevel@tonic-gate nr->nr_nodeid = nl2->msl_node_id;
11007c478bd9Sstevel@tonic-gate break;
11017c478bd9Sstevel@tonic-gate }
11027c478bd9Sstevel@tonic-gate nl2 = nl2->next;
11037c478bd9Sstevel@tonic-gate }
11047c478bd9Sstevel@tonic-gate
11057c478bd9Sstevel@tonic-gate (void) strcpy(nr->nr_nodename, node_v[i]);
11067c478bd9Sstevel@tonic-gate
11077c478bd9Sstevel@tonic-gate /*
11087c478bd9Sstevel@tonic-gate * When a node is added to a MN diskset, set the
11097c478bd9Sstevel@tonic-gate * nodeid of this node in the md_set structure
11107c478bd9Sstevel@tonic-gate * in the kernel.
11117c478bd9Sstevel@tonic-gate */
11127c478bd9Sstevel@tonic-gate if (strcmp(nr->nr_nodename, mynode()) == 0) {
11137c478bd9Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp));
11147c478bd9Sstevel@tonic-gate snp.sn_nodeid = nr->nr_nodeid;
11157c478bd9Sstevel@tonic-gate snp.sn_setno = mnsr->sr_setno;
11167c478bd9Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp,
11177c478bd9Sstevel@tonic-gate &snp.sn_mde, NULL) != 0) {
11187c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &snp.sn_mde);
11197c478bd9Sstevel@tonic-gate meta_free_nodelist(nl);
11207c478bd9Sstevel@tonic-gate free_sr(sr);
11217c478bd9Sstevel@tonic-gate return;
11227c478bd9Sstevel@tonic-gate }
11237c478bd9Sstevel@tonic-gate }
11247c478bd9Sstevel@tonic-gate
11257c478bd9Sstevel@tonic-gate /* Link the node records and fill in in-core data */
11267c478bd9Sstevel@tonic-gate mnnr_cache_add(mnsr, nr);
11277c478bd9Sstevel@tonic-gate
11287c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST,
11297c478bd9Sstevel@tonic-gate mnsr->sr_setno, nr->nr_nodeid);
11307c478bd9Sstevel@tonic-gate } else {
11317c478bd9Sstevel@tonic-gate for (j = 0; j < MD_MAXSIDES; j++) {
11327c478bd9Sstevel@tonic-gate if (sr->sr_nodes[j][0] != '\0')
11337c478bd9Sstevel@tonic-gate continue;
11347c478bd9Sstevel@tonic-gate (void) strcpy(sr->sr_nodes[j], node_v[i]);
11357c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD,
11367c478bd9Sstevel@tonic-gate SVM_TAG_HOST, sr->sr_setno, j);
11377c478bd9Sstevel@tonic-gate break;
11387c478bd9Sstevel@tonic-gate }
11397c478bd9Sstevel@tonic-gate }
11407c478bd9Sstevel@tonic-gate }
11417c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
11427c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
11437c478bd9Sstevel@tonic-gate meta_free_nodelist(nl);
11447c478bd9Sstevel@tonic-gate }
11457c478bd9Sstevel@tonic-gate
11467c478bd9Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
11477c478bd9Sstevel@tonic-gate
11487c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
11497c478bd9Sstevel@tonic-gate
11507c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
11517c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
11527c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
11537c478bd9Sstevel@tonic-gate } else {
11547c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*sr);
11557c478bd9Sstevel@tonic-gate }
11567c478bd9Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
11577c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
11587c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
11597c478bd9Sstevel@tonic-gate free_sr(sr);
11607c478bd9Sstevel@tonic-gate return;
11617c478bd9Sstevel@tonic-gate }
11627c478bd9Sstevel@tonic-gate
11637c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
11647c478bd9Sstevel@tonic-gate
11657c478bd9Sstevel@tonic-gate free_sr(sr);
11667c478bd9Sstevel@tonic-gate }
11677c478bd9Sstevel@tonic-gate
11687c478bd9Sstevel@tonic-gate /*
11697c478bd9Sstevel@tonic-gate * add 1 or more hosts to a set.
11707c478bd9Sstevel@tonic-gate */
11717c478bd9Sstevel@tonic-gate bool_t
mdrpc_addhosts_common(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)11727c478bd9Sstevel@tonic-gate mdrpc_addhosts_common(
11737c478bd9Sstevel@tonic-gate mdrpc_host_args *args,
11747c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
11757c478bd9Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
11767c478bd9Sstevel@tonic-gate int version /* RPC version */
11777c478bd9Sstevel@tonic-gate )
11787c478bd9Sstevel@tonic-gate {
11797c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
11807c478bd9Sstevel@tonic-gate int err;
11817c478bd9Sstevel@tonic-gate int op_mode = W_OK;
11827c478bd9Sstevel@tonic-gate
11837c478bd9Sstevel@tonic-gate /* setup, check permissions */
11847c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
11857c478bd9Sstevel@tonic-gate return (FALSE);
11867c478bd9Sstevel@tonic-gate else if (err != 0)
11877c478bd9Sstevel@tonic-gate return (TRUE);
11887c478bd9Sstevel@tonic-gate
11897c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
11907c478bd9Sstevel@tonic-gate return (TRUE);
11917c478bd9Sstevel@tonic-gate
11927c478bd9Sstevel@tonic-gate /* doit */
11937c478bd9Sstevel@tonic-gate addhosts(args->sp->setname, args->hosts.hosts_len,
11947c478bd9Sstevel@tonic-gate args->hosts.hosts_val, version, ep);
11957c478bd9Sstevel@tonic-gate
11967c478bd9Sstevel@tonic-gate err = svc_fini(ep);
11977c478bd9Sstevel@tonic-gate
11987c478bd9Sstevel@tonic-gate return (TRUE);
11997c478bd9Sstevel@tonic-gate }
12007c478bd9Sstevel@tonic-gate
12017c478bd9Sstevel@tonic-gate bool_t
mdrpc_addhosts_1_svc(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)12027c478bd9Sstevel@tonic-gate mdrpc_addhosts_1_svc(
12037c478bd9Sstevel@tonic-gate mdrpc_host_args *args,
12047c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
12057c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
12067c478bd9Sstevel@tonic-gate )
12077c478bd9Sstevel@tonic-gate {
12087c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
12092a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
12107c478bd9Sstevel@tonic-gate return (mdrpc_addhosts_common(args, res, rqstp, METAD_VERSION));
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate
12137c478bd9Sstevel@tonic-gate bool_t
mdrpc_addhosts_2_svc(mdrpc_host_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)12147c478bd9Sstevel@tonic-gate mdrpc_addhosts_2_svc(
12157c478bd9Sstevel@tonic-gate mdrpc_host_2_args *args,
12167c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
12177c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
12187c478bd9Sstevel@tonic-gate )
12197c478bd9Sstevel@tonic-gate {
12202a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
12217c478bd9Sstevel@tonic-gate switch (args->rev) {
12227c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
12237c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
12247c478bd9Sstevel@tonic-gate return (mdrpc_addhosts_common(
12257c478bd9Sstevel@tonic-gate &args->mdrpc_host_2_args_u.rev1, res,
12267c478bd9Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
12277c478bd9Sstevel@tonic-gate default:
12287c478bd9Sstevel@tonic-gate return (FALSE);
12297c478bd9Sstevel@tonic-gate }
12307c478bd9Sstevel@tonic-gate }
12317c478bd9Sstevel@tonic-gate
12327c478bd9Sstevel@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)12337c478bd9Sstevel@tonic-gate createset(
12347c478bd9Sstevel@tonic-gate mdsetname_t *sp,
12357c478bd9Sstevel@tonic-gate md_node_nm_arr_t nodes,
12367c478bd9Sstevel@tonic-gate md_timeval32_t timestamp,
12377c478bd9Sstevel@tonic-gate ulong_t genid,
12387c478bd9Sstevel@tonic-gate md_error_t *ep
12397c478bd9Sstevel@tonic-gate )
12407c478bd9Sstevel@tonic-gate {
12417c478bd9Sstevel@tonic-gate mddb_userreq_t req;
12427c478bd9Sstevel@tonic-gate md_set_record *sr;
12437c478bd9Sstevel@tonic-gate int i;
12447c478bd9Sstevel@tonic-gate
12457c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
12467c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0);
12477c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*sr);
12487c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
12497c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
12507c478bd9Sstevel@tonic-gate return;
12517c478bd9Sstevel@tonic-gate }
12527c478bd9Sstevel@tonic-gate
12537c478bd9Sstevel@tonic-gate sr = Zalloc(sizeof (*sr));
12547c478bd9Sstevel@tonic-gate
12557c478bd9Sstevel@tonic-gate sr->sr_selfid = req.ur_recid;
12567c478bd9Sstevel@tonic-gate sr->sr_setno = sp->setno;
12577c478bd9Sstevel@tonic-gate (void) strcpy(sr->sr_setname, sp->setname);
12587c478bd9Sstevel@tonic-gate
12597c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
12607c478bd9Sstevel@tonic-gate NODEV64);
12617c478bd9Sstevel@tonic-gate
12627c478bd9Sstevel@tonic-gate (void) meta_smf_enable(META_SMF_DISKSET, NULL);
12637c478bd9Sstevel@tonic-gate
12647c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
12657c478bd9Sstevel@tonic-gate (void) strcpy(sr->sr_nodes[i], nodes[i]);
12667c478bd9Sstevel@tonic-gate /* Skip empty slots */
12677c478bd9Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
12687c478bd9Sstevel@tonic-gate continue;
12697c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
12707c478bd9Sstevel@tonic-gate i);
12717c478bd9Sstevel@tonic-gate }
12727c478bd9Sstevel@tonic-gate
12737c478bd9Sstevel@tonic-gate sr->sr_ctime = timestamp;
12747c478bd9Sstevel@tonic-gate sr->sr_genid = genid;
12757c478bd9Sstevel@tonic-gate sr->sr_revision = MD_SET_RECORD_REVISION;
12767c478bd9Sstevel@tonic-gate sr->sr_flags |= MD_SR_ADD;
12777c478bd9Sstevel@tonic-gate
12787c478bd9Sstevel@tonic-gate sr->sr_mhiargs = defmhiargs;
12797c478bd9Sstevel@tonic-gate
12807c478bd9Sstevel@tonic-gate sr_cache_add(sr);
12817c478bd9Sstevel@tonic-gate
12827c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
12837c478bd9Sstevel@tonic-gate }
12847c478bd9Sstevel@tonic-gate
12857c478bd9Sstevel@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)12867c478bd9Sstevel@tonic-gate mncreateset(
12877c478bd9Sstevel@tonic-gate mdsetname_t *sp,
12887c478bd9Sstevel@tonic-gate md_mnnode_desc *nodelist,
12897c478bd9Sstevel@tonic-gate md_timeval32_t timestamp,
12907c478bd9Sstevel@tonic-gate ulong_t genid,
12917c478bd9Sstevel@tonic-gate md_node_nm_t master_nodenm,
12927c478bd9Sstevel@tonic-gate int master_nodeid,
12937c478bd9Sstevel@tonic-gate md_error_t *ep
12947c478bd9Sstevel@tonic-gate )
12957c478bd9Sstevel@tonic-gate {
12967c478bd9Sstevel@tonic-gate mddb_userreq_t req;
12977c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
12987c478bd9Sstevel@tonic-gate md_mnnode_record *nr;
12997c478bd9Sstevel@tonic-gate md_mnnode_desc *nd;
13007c478bd9Sstevel@tonic-gate mddb_set_node_params_t snp;
13017c478bd9Sstevel@tonic-gate int nodecnt;
13027c478bd9Sstevel@tonic-gate mndiskset_membershiplist_t *nl;
13037c478bd9Sstevel@tonic-gate
13047c478bd9Sstevel@tonic-gate /*
13057c478bd9Sstevel@tonic-gate * Validate that nodes in set being created are in the
13067c478bd9Sstevel@tonic-gate * membership list on THIS node.
13077c478bd9Sstevel@tonic-gate * Initiating node has verified that nodes are in membership
13087c478bd9Sstevel@tonic-gate * list on the initiating node.
13097c478bd9Sstevel@tonic-gate * Get membershiplist from API routine. If there's
13107c478bd9Sstevel@tonic-gate * an error, fail to add set and pass back error.
13117c478bd9Sstevel@tonic-gate */
13127c478bd9Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
13137c478bd9Sstevel@tonic-gate return;
13147c478bd9Sstevel@tonic-gate }
13157c478bd9Sstevel@tonic-gate /* Verify that all nodes are in member list */
13167c478bd9Sstevel@tonic-gate nd = nodelist;
13177c478bd9Sstevel@tonic-gate while (nd) {
13187c478bd9Sstevel@tonic-gate /*
13197c478bd9Sstevel@tonic-gate * If node in list isn't a member of the membership,
13207c478bd9Sstevel@tonic-gate * just return error.
13217c478bd9Sstevel@tonic-gate */
13227c478bd9Sstevel@tonic-gate if (meta_is_member(nd->nd_nodename, 0, nl) == 0) {
13237c478bd9Sstevel@tonic-gate meta_free_nodelist(nl);
13247c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
13257c478bd9Sstevel@tonic-gate sp->setno, nd->nd_nodename, NULL, sp->setname);
13267c478bd9Sstevel@tonic-gate return;
13277c478bd9Sstevel@tonic-gate }
13287c478bd9Sstevel@tonic-gate nd = nd->nd_next;
13297c478bd9Sstevel@tonic-gate }
13307c478bd9Sstevel@tonic-gate meta_free_nodelist(nl);
13317c478bd9Sstevel@tonic-gate
13327c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
13337c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0);
13347c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
13357c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
13367c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
13377c478bd9Sstevel@tonic-gate return;
13387c478bd9Sstevel@tonic-gate }
13397c478bd9Sstevel@tonic-gate
13407c478bd9Sstevel@tonic-gate mnsr = Zalloc(sizeof (*mnsr));
13417c478bd9Sstevel@tonic-gate mnsr->sr_selfid = req.ur_recid;
13427c478bd9Sstevel@tonic-gate mnsr->sr_setno = sp->setno;
13437c478bd9Sstevel@tonic-gate (void) strlcpy(mnsr->sr_setname, sp->setname, MD_MAX_SETNAME);
13447c478bd9Sstevel@tonic-gate
13457c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
13467c478bd9Sstevel@tonic-gate NODEV64);
13477c478bd9Sstevel@tonic-gate
13487c478bd9Sstevel@tonic-gate (void) meta_smf_enable(META_SMF_DISKSET | META_SMF_MN_DISKSET, NULL);
13497c478bd9Sstevel@tonic-gate
13507c478bd9Sstevel@tonic-gate nd = nodelist;
13517c478bd9Sstevel@tonic-gate while (nd) {
13527c478bd9Sstevel@tonic-gate /* Create the node record */
13537c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
13547c478bd9Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_CREATE, 0);
13557c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*nr);
13567c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
13577c478bd9Sstevel@tonic-gate /* Frees mnsr and any alloc'd node records */
13587c478bd9Sstevel@tonic-gate free_sr((struct md_set_record *)mnsr);
13597c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
13607c478bd9Sstevel@tonic-gate return;
13617c478bd9Sstevel@tonic-gate }
13627c478bd9Sstevel@tonic-gate
13637c478bd9Sstevel@tonic-gate nr = Zalloc(sizeof (*nr));
13647c478bd9Sstevel@tonic-gate nr->nr_revision = MD_MNNODE_RECORD_REVISION;
13657c478bd9Sstevel@tonic-gate nr->nr_selfid = req.ur_recid;
13667c478bd9Sstevel@tonic-gate nr->nr_ctime = timestamp;
13677c478bd9Sstevel@tonic-gate nr->nr_genid = genid;
13687c478bd9Sstevel@tonic-gate nr->nr_nodeid = nd->nd_nodeid;
13697c478bd9Sstevel@tonic-gate nr->nr_flags = nd->nd_flags;
13707c478bd9Sstevel@tonic-gate (void) strlcpy(nr->nr_nodename, nd->nd_nodename,
13717c478bd9Sstevel@tonic-gate MD_MAX_NODENAME);
13727c478bd9Sstevel@tonic-gate
13737c478bd9Sstevel@tonic-gate /* Link the node records and fill in in-core data */
13747c478bd9Sstevel@tonic-gate mnnr_cache_add(mnsr, nr);
13757c478bd9Sstevel@tonic-gate
13767c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
13777c478bd9Sstevel@tonic-gate nr->nr_nodeid);
13787c478bd9Sstevel@tonic-gate
13797c478bd9Sstevel@tonic-gate nd = nd->nd_next;
13807c478bd9Sstevel@tonic-gate }
13817c478bd9Sstevel@tonic-gate
13827c478bd9Sstevel@tonic-gate /*
13837c478bd9Sstevel@tonic-gate * For backward compatibility, fill in mynode name
13847c478bd9Sstevel@tonic-gate * as the only name in the sr_nodes array. This
13857c478bd9Sstevel@tonic-gate * allows the pre-MNdiskset code to see that there
13867c478bd9Sstevel@tonic-gate * is a node in this diskset. This will keep the
13877c478bd9Sstevel@tonic-gate * pre-MNdiskset code from removing this set.
13887c478bd9Sstevel@tonic-gate */
13897c478bd9Sstevel@tonic-gate (void) strlcpy(mnsr->sr_nodes_bw_compat[0], mynode(), MD_MAX_NODENAME);
13907c478bd9Sstevel@tonic-gate
13917c478bd9Sstevel@tonic-gate mnsr->sr_ctime = timestamp;
13927c478bd9Sstevel@tonic-gate mnsr->sr_genid = genid;
13937c478bd9Sstevel@tonic-gate mnsr->sr_revision = MD_SET_RECORD_REVISION;
13947c478bd9Sstevel@tonic-gate mnsr->sr_flags |= MD_SR_ADD;
13957c478bd9Sstevel@tonic-gate
13967c478bd9Sstevel@tonic-gate mnsr->sr_flags |= MD_SR_MN;
1397*80148899SSurya Prakki (void) strcpy(mnsr->sr_master_nodenm, master_nodenm);
13987c478bd9Sstevel@tonic-gate mnsr->sr_master_nodeid = master_nodeid;
13997c478bd9Sstevel@tonic-gate
14007c478bd9Sstevel@tonic-gate mnsr->sr_mhiargs = defmhiargs;
14017c478bd9Sstevel@tonic-gate
14027c478bd9Sstevel@tonic-gate sr_cache_add((struct md_set_record *)mnsr);
14037c478bd9Sstevel@tonic-gate
14047c478bd9Sstevel@tonic-gate commitset((struct md_set_record *)mnsr, TRUE, ep);
14057c478bd9Sstevel@tonic-gate
14067c478bd9Sstevel@tonic-gate /*
14077c478bd9Sstevel@tonic-gate * When a set is created for the first time, the nodelist
14087c478bd9Sstevel@tonic-gate * will contain this node.
14097c478bd9Sstevel@tonic-gate * When a node is just being added to a set, the nodelist
14107c478bd9Sstevel@tonic-gate * will not contain this node. This node is added to the
14117c478bd9Sstevel@tonic-gate * set structure with a later call to addhosts.
14127c478bd9Sstevel@tonic-gate *
14137c478bd9Sstevel@tonic-gate * So, if the nodelist contains an entry for this node
14147c478bd9Sstevel@tonic-gate * then set the nodeid of this node in the md_set kernel
14157c478bd9Sstevel@tonic-gate * data structure.
14167c478bd9Sstevel@tonic-gate */
14177c478bd9Sstevel@tonic-gate nd = nodelist;
14187c478bd9Sstevel@tonic-gate while (nd) {
14197c478bd9Sstevel@tonic-gate if (strcmp(nd->nd_nodename, mynode()) == 0) {
14207c478bd9Sstevel@tonic-gate break;
14217c478bd9Sstevel@tonic-gate }
14227c478bd9Sstevel@tonic-gate nd = nd->nd_next;
14237c478bd9Sstevel@tonic-gate }
14247c478bd9Sstevel@tonic-gate if (nd) {
14257c478bd9Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp));
14267c478bd9Sstevel@tonic-gate snp.sn_nodeid = nd->nd_nodeid;
14277c478bd9Sstevel@tonic-gate snp.sn_setno = sp->setno;
14287c478bd9Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp, &snp.sn_mde, NULL) != 0) {
14297c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &snp.sn_mde);
14307c478bd9Sstevel@tonic-gate return;
14317c478bd9Sstevel@tonic-gate }
14327c478bd9Sstevel@tonic-gate }
14337c478bd9Sstevel@tonic-gate }
14347c478bd9Sstevel@tonic-gate
14357c478bd9Sstevel@tonic-gate /*
14367c478bd9Sstevel@tonic-gate * create a set on a host
14377c478bd9Sstevel@tonic-gate */
14387c478bd9Sstevel@tonic-gate bool_t
mdrpc_createset_common(mdrpc_createset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)14397c478bd9Sstevel@tonic-gate mdrpc_createset_common(
14407c478bd9Sstevel@tonic-gate mdrpc_createset_args *args,
14417c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
14427c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
14437c478bd9Sstevel@tonic-gate )
14447c478bd9Sstevel@tonic-gate {
14457c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
14467c478bd9Sstevel@tonic-gate char stringbuf1[MAXPATHLEN];
14477c478bd9Sstevel@tonic-gate char stringbuf2[MAXPATHLEN];
14487c478bd9Sstevel@tonic-gate int err;
14497c478bd9Sstevel@tonic-gate int op_mode = W_OK;
14507c478bd9Sstevel@tonic-gate
14517c478bd9Sstevel@tonic-gate /* setup, check permissions */
14527c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
14537c478bd9Sstevel@tonic-gate return (FALSE);
14547c478bd9Sstevel@tonic-gate else if (err != 0)
14557c478bd9Sstevel@tonic-gate return (TRUE);
14567c478bd9Sstevel@tonic-gate
14577c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
14587c478bd9Sstevel@tonic-gate return (TRUE);
14597c478bd9Sstevel@tonic-gate
14607c478bd9Sstevel@tonic-gate /* create the arguments for the symlink() and unlink() calls */
14617c478bd9Sstevel@tonic-gate (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
14627c478bd9Sstevel@tonic-gate args->sp->setname);
14637c478bd9Sstevel@tonic-gate (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
14647c478bd9Sstevel@tonic-gate args->sp->setno);
14657c478bd9Sstevel@tonic-gate
14667c478bd9Sstevel@tonic-gate /*
14677c478bd9Sstevel@tonic-gate * Since we already verified that the setname was OK, make sure to
14687c478bd9Sstevel@tonic-gate * cleanup before proceeding.
14697c478bd9Sstevel@tonic-gate */
14707c478bd9Sstevel@tonic-gate if (unlink(stringbuf2) == -1) {
14717c478bd9Sstevel@tonic-gate if (errno != ENOENT) {
14727c478bd9Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2);
14737c478bd9Sstevel@tonic-gate return (TRUE);
14747c478bd9Sstevel@tonic-gate }
14757c478bd9Sstevel@tonic-gate }
14767c478bd9Sstevel@tonic-gate
14777c478bd9Sstevel@tonic-gate /* create the set */
14787c478bd9Sstevel@tonic-gate createset(args->sp, args->nodes, args->timestamp, args->genid, ep);
14797c478bd9Sstevel@tonic-gate
14807c478bd9Sstevel@tonic-gate if (! mdisok(ep))
14817c478bd9Sstevel@tonic-gate return (TRUE);
14827c478bd9Sstevel@tonic-gate
1483ee8af371Sachimm /* create the symlink */
1484ee8af371Sachimm if (symlink(stringbuf1, stringbuf2) == -1)
1485ee8af371Sachimm (void) mdsyserror(ep, errno, stringbuf2);
1486ee8af371Sachimm
14877c478bd9Sstevel@tonic-gate err = svc_fini(ep);
14887c478bd9Sstevel@tonic-gate
14897c478bd9Sstevel@tonic-gate return (TRUE);
14907c478bd9Sstevel@tonic-gate }
14917c478bd9Sstevel@tonic-gate
14927c478bd9Sstevel@tonic-gate bool_t
mdrpc_createset_1_svc(mdrpc_createset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)14937c478bd9Sstevel@tonic-gate mdrpc_createset_1_svc(
14947c478bd9Sstevel@tonic-gate mdrpc_createset_args *args,
14957c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
14967c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
14977c478bd9Sstevel@tonic-gate )
14987c478bd9Sstevel@tonic-gate {
14992a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
15007c478bd9Sstevel@tonic-gate return (mdrpc_createset_common(args, res, rqstp));
15017c478bd9Sstevel@tonic-gate }
15027c478bd9Sstevel@tonic-gate
15037c478bd9Sstevel@tonic-gate bool_t
mdrpc_createset_2_svc(mdrpc_createset_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15047c478bd9Sstevel@tonic-gate mdrpc_createset_2_svc(
15057c478bd9Sstevel@tonic-gate mdrpc_createset_2_args *args,
15067c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
15077c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
15087c478bd9Sstevel@tonic-gate )
15097c478bd9Sstevel@tonic-gate {
15102a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
15117c478bd9Sstevel@tonic-gate switch (args->rev) {
15127c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
15137c478bd9Sstevel@tonic-gate return (mdrpc_createset_common(
15147c478bd9Sstevel@tonic-gate &args->mdrpc_createset_2_args_u.rev1, res, rqstp));
15157c478bd9Sstevel@tonic-gate default:
15167c478bd9Sstevel@tonic-gate return (FALSE);
15177c478bd9Sstevel@tonic-gate }
15187c478bd9Sstevel@tonic-gate }
15197c478bd9Sstevel@tonic-gate
15207c478bd9Sstevel@tonic-gate bool_t
mdrpc_mncreateset_common(mdrpc_mncreateset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15217c478bd9Sstevel@tonic-gate mdrpc_mncreateset_common(
15227c478bd9Sstevel@tonic-gate mdrpc_mncreateset_args *args,
15237c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
15247c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
15257c478bd9Sstevel@tonic-gate )
15267c478bd9Sstevel@tonic-gate {
15277c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
15287c478bd9Sstevel@tonic-gate char stringbuf1[MAXPATHLEN];
15297c478bd9Sstevel@tonic-gate char stringbuf2[MAXPATHLEN];
15307c478bd9Sstevel@tonic-gate int err;
15317c478bd9Sstevel@tonic-gate int op_mode = W_OK;
15327c478bd9Sstevel@tonic-gate
15337c478bd9Sstevel@tonic-gate /* setup, check permissions */
15347c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
15357c478bd9Sstevel@tonic-gate return (FALSE);
15367c478bd9Sstevel@tonic-gate else if (err != 0)
15377c478bd9Sstevel@tonic-gate return (TRUE);
15387c478bd9Sstevel@tonic-gate
15397c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
15407c478bd9Sstevel@tonic-gate return (TRUE);
15417c478bd9Sstevel@tonic-gate
15427c478bd9Sstevel@tonic-gate /* create the arguments for the symlink() and unlink() calls */
15437c478bd9Sstevel@tonic-gate (void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
15447c478bd9Sstevel@tonic-gate args->sp->setname);
15457c478bd9Sstevel@tonic-gate (void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
15467c478bd9Sstevel@tonic-gate args->sp->setno);
15477c478bd9Sstevel@tonic-gate
15487c478bd9Sstevel@tonic-gate /*
15497c478bd9Sstevel@tonic-gate * Since we already verified that the setname was OK, make sure to
15507c478bd9Sstevel@tonic-gate * cleanup before proceeding.
15517c478bd9Sstevel@tonic-gate */
15527c478bd9Sstevel@tonic-gate if (unlink(stringbuf2) == -1) {
15537c478bd9Sstevel@tonic-gate if (errno != ENOENT) {
15547c478bd9Sstevel@tonic-gate (void) mdsyserror(ep, errno, stringbuf2);
15557c478bd9Sstevel@tonic-gate return (TRUE);
15567c478bd9Sstevel@tonic-gate }
15577c478bd9Sstevel@tonic-gate }
15587c478bd9Sstevel@tonic-gate
15597c478bd9Sstevel@tonic-gate /* create the set */
15607c478bd9Sstevel@tonic-gate mncreateset(args->sp, args->nodelist, args->timestamp, args->genid,
15617c478bd9Sstevel@tonic-gate args->master_nodenm, args->master_nodeid, ep);
15627c478bd9Sstevel@tonic-gate
15637c478bd9Sstevel@tonic-gate if (! mdisok(ep)) {
15647c478bd9Sstevel@tonic-gate return (TRUE);
15657c478bd9Sstevel@tonic-gate }
1566ee8af371Sachimm
1567ee8af371Sachimm /* create the symlink */
1568ee8af371Sachimm if (symlink(stringbuf1, stringbuf2) == -1)
1569ee8af371Sachimm (void) mdsyserror(ep, errno, stringbuf2);
1570ee8af371Sachimm
15717c478bd9Sstevel@tonic-gate err = svc_fini(ep);
15727c478bd9Sstevel@tonic-gate
15737c478bd9Sstevel@tonic-gate return (TRUE);
15747c478bd9Sstevel@tonic-gate }
15757c478bd9Sstevel@tonic-gate
15767c478bd9Sstevel@tonic-gate bool_t
mdrpc_mncreateset_2_svc(mdrpc_mncreateset_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15777c478bd9Sstevel@tonic-gate mdrpc_mncreateset_2_svc(
15787c478bd9Sstevel@tonic-gate mdrpc_mncreateset_2_args *args,
15797c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
15807c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
15817c478bd9Sstevel@tonic-gate )
15827c478bd9Sstevel@tonic-gate {
15832a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
15847c478bd9Sstevel@tonic-gate switch (args->rev) {
15857c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
15867c478bd9Sstevel@tonic-gate return (mdrpc_mncreateset_common(
15877c478bd9Sstevel@tonic-gate &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp));
15887c478bd9Sstevel@tonic-gate default:
15897c478bd9Sstevel@tonic-gate return (FALSE);
15907c478bd9Sstevel@tonic-gate }
15917c478bd9Sstevel@tonic-gate }
15927c478bd9Sstevel@tonic-gate
15937c478bd9Sstevel@tonic-gate static void
del_drv_sidenms(mdsetname_t * sp,int version,md_error_t * ep)15947c478bd9Sstevel@tonic-gate del_drv_sidenms(
15957c478bd9Sstevel@tonic-gate mdsetname_t *sp,
15967c478bd9Sstevel@tonic-gate int version, /* RPC version of calling routine */
15977c478bd9Sstevel@tonic-gate md_error_t *ep
15987c478bd9Sstevel@tonic-gate )
15997c478bd9Sstevel@tonic-gate {
16007c478bd9Sstevel@tonic-gate md_set_record *sr;
16017c478bd9Sstevel@tonic-gate md_drive_desc *dd, *p;
16027c478bd9Sstevel@tonic-gate mddrivename_t *dn;
16037c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
16047c478bd9Sstevel@tonic-gate int i;
16057c478bd9Sstevel@tonic-gate int rb_mode = 0;
16067c478bd9Sstevel@tonic-gate
16077c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
16087c478bd9Sstevel@tonic-gate return;
16097c478bd9Sstevel@tonic-gate
16107c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
16117c478bd9Sstevel@tonic-gate return;
16127c478bd9Sstevel@tonic-gate
16137c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
16147c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
16157c478bd9Sstevel@tonic-gate /*
16167c478bd9Sstevel@tonic-gate * In the multi-node diskset, there are no diskset
16177c478bd9Sstevel@tonic-gate * entries in the local set for other nodes, so there's
16187c478bd9Sstevel@tonic-gate * nothing to do.
16197c478bd9Sstevel@tonic-gate */
16207c478bd9Sstevel@tonic-gate free_sr(sr);
16217c478bd9Sstevel@tonic-gate return;
16227c478bd9Sstevel@tonic-gate }
16237c478bd9Sstevel@tonic-gate
16247c478bd9Sstevel@tonic-gate if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
16257c478bd9Sstevel@tonic-gate ep)) == NULL) {
16267c478bd9Sstevel@tonic-gate if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) {
16277c478bd9Sstevel@tonic-gate metaflushsetname(sp);
16287c478bd9Sstevel@tonic-gate if (! mdisok(ep)) {
16297c478bd9Sstevel@tonic-gate free_sr(sr);
16307c478bd9Sstevel@tonic-gate return;
16317c478bd9Sstevel@tonic-gate }
16327c478bd9Sstevel@tonic-gate /* we are supposed to have drives!!!! */
16337c478bd9Sstevel@tonic-gate assert(0);
16347c478bd9Sstevel@tonic-gate }
16357c478bd9Sstevel@tonic-gate rb_mode = 1;
16367c478bd9Sstevel@tonic-gate mdclrerror(ep);
16377c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
16387c478bd9Sstevel@tonic-gate /* Skip empty sides of the diskset */
16397c478bd9Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
16407c478bd9Sstevel@tonic-gate continue;
16417c478bd9Sstevel@tonic-gate dd = metaget_drivedesc_sideno(sp, i,
16427c478bd9Sstevel@tonic-gate (MD_BASICNAME_OK | PRINT_FAST), ep);
16437c478bd9Sstevel@tonic-gate /* Got dd, get out of loop */
16447c478bd9Sstevel@tonic-gate if (dd != NULL)
16457c478bd9Sstevel@tonic-gate break;
16467c478bd9Sstevel@tonic-gate
16477c478bd9Sstevel@tonic-gate /* some error occurred, get out of loop */
16487c478bd9Sstevel@tonic-gate if (! mdisok(ep))
16497c478bd9Sstevel@tonic-gate break;
16507c478bd9Sstevel@tonic-gate }
16517c478bd9Sstevel@tonic-gate /*
16527c478bd9Sstevel@tonic-gate * At this point, we have one of three possibilities:
16537c478bd9Sstevel@tonic-gate * 1) dd != NULL (we have found drives using an alternate
16547c478bd9Sstevel@tonic-gate * side.)
16557c478bd9Sstevel@tonic-gate * 2) dd == NULL (no drives) && mdisok(ep) : assert(0)
16567c478bd9Sstevel@tonic-gate * 3) dd == NULL (no drives) && ! mdisok(ep) : return
16577c478bd9Sstevel@tonic-gate * error information to caller.
16587c478bd9Sstevel@tonic-gate */
16597c478bd9Sstevel@tonic-gate if (dd == NULL) {
16607c478bd9Sstevel@tonic-gate metaflushsetname(sp);
16617c478bd9Sstevel@tonic-gate if (! mdisok(ep)) {
16627c478bd9Sstevel@tonic-gate free_sr(sr);
16637c478bd9Sstevel@tonic-gate return;
16647c478bd9Sstevel@tonic-gate }
16657c478bd9Sstevel@tonic-gate /* we are supposed to have drives!!!! */
16667c478bd9Sstevel@tonic-gate assert(0);
16677c478bd9Sstevel@tonic-gate }
16687c478bd9Sstevel@tonic-gate }
16697c478bd9Sstevel@tonic-gate
16707c478bd9Sstevel@tonic-gate /*
16717c478bd9Sstevel@tonic-gate * Let's run through each drive descriptor, and delete the
16727c478bd9Sstevel@tonic-gate * sidename for all sides that are not in the sr_nodes array.
16737c478bd9Sstevel@tonic-gate * We will ignore errors, cause the empty side may not
16747c478bd9Sstevel@tonic-gate * have had any names to begin with.
16757c478bd9Sstevel@tonic-gate */
16767c478bd9Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
16777c478bd9Sstevel@tonic-gate dn = p->dd_dnp;
16787c478bd9Sstevel@tonic-gate
16797c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
16807c478bd9Sstevel@tonic-gate /* Skip existing sides of the diskset */
16817c478bd9Sstevel@tonic-gate if (!rb_mode && sr->sr_nodes[i][0] != '\0')
16827c478bd9Sstevel@tonic-gate continue;
16837c478bd9Sstevel@tonic-gate /* An empty side, delete the sidename */
16847c478bd9Sstevel@tonic-gate if (del_name(local_sp, i+SKEW,
16857c478bd9Sstevel@tonic-gate dn->side_names_key, ep)) {
16867c478bd9Sstevel@tonic-gate if (!mdissyserror(ep, ENOENT)) {
16877c478bd9Sstevel@tonic-gate free_sr(sr);
16887c478bd9Sstevel@tonic-gate return;
16897c478bd9Sstevel@tonic-gate }
16907c478bd9Sstevel@tonic-gate mdclrerror(ep);
16917c478bd9Sstevel@tonic-gate }
16927c478bd9Sstevel@tonic-gate }
16937c478bd9Sstevel@tonic-gate }
16947c478bd9Sstevel@tonic-gate free_sr(sr);
16957c478bd9Sstevel@tonic-gate metaflushsetname(sp);
16967c478bd9Sstevel@tonic-gate }
16977c478bd9Sstevel@tonic-gate
16987c478bd9Sstevel@tonic-gate /*
16997c478bd9Sstevel@tonic-gate * delete 1 or more sidenames per drive desc, from the local namespace
17007c478bd9Sstevel@tonic-gate */
17017c478bd9Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)17027c478bd9Sstevel@tonic-gate mdrpc_del_drv_sidenms_common(
17037c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
17047c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
17057c478bd9Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
17067c478bd9Sstevel@tonic-gate int version /* RPC version */
17077c478bd9Sstevel@tonic-gate )
17087c478bd9Sstevel@tonic-gate {
17097c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
17107c478bd9Sstevel@tonic-gate int err;
17117c478bd9Sstevel@tonic-gate int op_mode = W_OK;
17127c478bd9Sstevel@tonic-gate
17137c478bd9Sstevel@tonic-gate /* setup, check permissions */
17147c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
17157c478bd9Sstevel@tonic-gate return (FALSE);
17167c478bd9Sstevel@tonic-gate else if (err != 0)
17177c478bd9Sstevel@tonic-gate return (TRUE);
17187c478bd9Sstevel@tonic-gate
17197c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
17207c478bd9Sstevel@tonic-gate return (TRUE);
17217c478bd9Sstevel@tonic-gate
17227c478bd9Sstevel@tonic-gate /* doit */
17237c478bd9Sstevel@tonic-gate del_drv_sidenms(args->sp, version, ep);
17247c478bd9Sstevel@tonic-gate
17257c478bd9Sstevel@tonic-gate err = svc_fini(ep);
17267c478bd9Sstevel@tonic-gate
17277c478bd9Sstevel@tonic-gate return (TRUE);
17287c478bd9Sstevel@tonic-gate }
17297c478bd9Sstevel@tonic-gate
17307c478bd9Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_1_svc(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)17317c478bd9Sstevel@tonic-gate mdrpc_del_drv_sidenms_1_svc(
17327c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
17337c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
17347c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
17357c478bd9Sstevel@tonic-gate )
17367c478bd9Sstevel@tonic-gate {
17372a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
17387c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
17397c478bd9Sstevel@tonic-gate return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION));
17407c478bd9Sstevel@tonic-gate }
17417c478bd9Sstevel@tonic-gate
17427c478bd9Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)17437c478bd9Sstevel@tonic-gate mdrpc_del_drv_sidenms_2_svc(
17447c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args,
17457c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
17467c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
17477c478bd9Sstevel@tonic-gate )
17487c478bd9Sstevel@tonic-gate {
17492a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
17507c478bd9Sstevel@tonic-gate switch (args->rev) {
17517c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
17527c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
17537c478bd9Sstevel@tonic-gate return (mdrpc_del_drv_sidenms_common(
17547c478bd9Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res,
17557c478bd9Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
17567c478bd9Sstevel@tonic-gate default:
17577c478bd9Sstevel@tonic-gate return (FALSE);
17587c478bd9Sstevel@tonic-gate }
17597c478bd9Sstevel@tonic-gate }
17607c478bd9Sstevel@tonic-gate
17617c478bd9Sstevel@tonic-gate static int
del_sidenamelist(md_set_record * sr,mddrivename_t * dn,md_error_t * ep)17627c478bd9Sstevel@tonic-gate del_sidenamelist(
17637c478bd9Sstevel@tonic-gate md_set_record *sr,
17647c478bd9Sstevel@tonic-gate mddrivename_t *dn,
17657c478bd9Sstevel@tonic-gate md_error_t *ep
17667c478bd9Sstevel@tonic-gate )
17677c478bd9Sstevel@tonic-gate {
17687c478bd9Sstevel@tonic-gate mdsidenames_t *sn;
17697c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
17707c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
17717c478bd9Sstevel@tonic-gate md_mnnode_record *nr;
17727c478bd9Sstevel@tonic-gate
17737c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
17747c478bd9Sstevel@tonic-gate return (-1);
17757c478bd9Sstevel@tonic-gate
17767c478bd9Sstevel@tonic-gate for (sn = dn->side_names; sn != NULL; sn = sn->next)
17777c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
17787c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
17797c478bd9Sstevel@tonic-gate /*
17807c478bd9Sstevel@tonic-gate * Only delete side name entries for this node
17817c478bd9Sstevel@tonic-gate * on a multi-node diskset.
17827c478bd9Sstevel@tonic-gate */
17837c478bd9Sstevel@tonic-gate nr = mnsr->sr_nodechain;
17847c478bd9Sstevel@tonic-gate while (nr) {
17857c478bd9Sstevel@tonic-gate if (nr->nr_nodeid == sn->sideno) {
17867c478bd9Sstevel@tonic-gate if (del_name(local_sp, sn->sideno,
17877c478bd9Sstevel@tonic-gate dn->side_names_key, ep) == -1)
17887c478bd9Sstevel@tonic-gate mdclrerror(ep); /* ignore err */
17897c478bd9Sstevel@tonic-gate break;
17907c478bd9Sstevel@tonic-gate }
17917c478bd9Sstevel@tonic-gate nr = nr->nr_next;
17927c478bd9Sstevel@tonic-gate }
17937c478bd9Sstevel@tonic-gate } else {
17947c478bd9Sstevel@tonic-gate if (del_name(local_sp, sn->sideno+SKEW,
17957c478bd9Sstevel@tonic-gate dn->side_names_key, ep) == -1)
17967c478bd9Sstevel@tonic-gate mdclrerror(ep); /* ignore errors */
17977c478bd9Sstevel@tonic-gate }
17987c478bd9Sstevel@tonic-gate
17997c478bd9Sstevel@tonic-gate dn->side_names_key = MD_KEYBAD;
18007c478bd9Sstevel@tonic-gate return (0);
18017c478bd9Sstevel@tonic-gate }
18027c478bd9Sstevel@tonic-gate
18037c478bd9Sstevel@tonic-gate static void
deldrvs(char * setname,md_drive_desc * dd,md_error_t * ep)18047c478bd9Sstevel@tonic-gate deldrvs(
18057c478bd9Sstevel@tonic-gate char *setname,
18067c478bd9Sstevel@tonic-gate md_drive_desc *dd,
18077c478bd9Sstevel@tonic-gate md_error_t *ep
18087c478bd9Sstevel@tonic-gate )
18097c478bd9Sstevel@tonic-gate {
18107c478bd9Sstevel@tonic-gate mdsetname_t *sp;
18117c478bd9Sstevel@tonic-gate md_set_record *sr;
18127c478bd9Sstevel@tonic-gate md_drive_record *dr;
18137c478bd9Sstevel@tonic-gate mddb_userreq_t req;
18147c478bd9Sstevel@tonic-gate md_drive_desc *p;
18157c478bd9Sstevel@tonic-gate mddrivename_t *dn, *dn1;
18167c478bd9Sstevel@tonic-gate side_t sideno;
18177c478bd9Sstevel@tonic-gate int i;
18187c478bd9Sstevel@tonic-gate int rb_mode = 0;
18197c478bd9Sstevel@tonic-gate mdname_t *np;
18207c478bd9Sstevel@tonic-gate md_dev64_t dev;
18217c478bd9Sstevel@tonic-gate md_error_t xep = mdnullerror;
18227c478bd9Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
18237c478bd9Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
18247c478bd9Sstevel@tonic-gate int devid_same = -1;
18257c478bd9Sstevel@tonic-gate int using_devid = 0;
18267c478bd9Sstevel@tonic-gate md_mnnode_record *nr;
18277c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
18287c478bd9Sstevel@tonic-gate
18297c478bd9Sstevel@tonic-gate if ((sp = metasetname(setname, ep)) == NULL)
18307c478bd9Sstevel@tonic-gate return;
18317c478bd9Sstevel@tonic-gate
18327c478bd9Sstevel@tonic-gate metaflushsetname(sp);
18337c478bd9Sstevel@tonic-gate
18347c478bd9Sstevel@tonic-gate if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) {
18357c478bd9Sstevel@tonic-gate if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE))
18367c478bd9Sstevel@tonic-gate return;
18377c478bd9Sstevel@tonic-gate mdclrerror(ep);
18387c478bd9Sstevel@tonic-gate /*
18397c478bd9Sstevel@tonic-gate * The set record is incomplete, so we need to make note
18407c478bd9Sstevel@tonic-gate * here so that we can do some special handling later.
18417c478bd9Sstevel@tonic-gate */
18427c478bd9Sstevel@tonic-gate rb_mode = 1;
18437c478bd9Sstevel@tonic-gate }
18447c478bd9Sstevel@tonic-gate
18457c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
18467c478bd9Sstevel@tonic-gate return;
18477c478bd9Sstevel@tonic-gate
18487c478bd9Sstevel@tonic-gate if (dd->dd_dnp == NULL)
18497c478bd9Sstevel@tonic-gate return;
18507c478bd9Sstevel@tonic-gate
18517c478bd9Sstevel@tonic-gate /*
18527c478bd9Sstevel@tonic-gate * The system is either all devid or all
18537c478bd9Sstevel@tonic-gate * non-devid so we determine this by looking
18547c478bd9Sstevel@tonic-gate * at the first item in the list.
18557c478bd9Sstevel@tonic-gate *
18567c478bd9Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
18577c478bd9Sstevel@tonic-gate * points to a '' string of devid. We need to check this
18587c478bd9Sstevel@tonic-gate * before set the using_devid.
18597c478bd9Sstevel@tonic-gate */
18607c478bd9Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
18617c478bd9Sstevel@tonic-gate (!(MD_MNSET_REC(sr))))
18627c478bd9Sstevel@tonic-gate using_devid = 1;
18637c478bd9Sstevel@tonic-gate
18647c478bd9Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
18657c478bd9Sstevel@tonic-gate dn = p->dd_dnp;
18667c478bd9Sstevel@tonic-gate devid_remote = NULL;
18677c478bd9Sstevel@tonic-gate
18687c478bd9Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
18697c478bd9Sstevel@tonic-gate using_devid) {
18707c478bd9Sstevel@tonic-gate /*
18717c478bd9Sstevel@tonic-gate * We have a devid so use it
18727c478bd9Sstevel@tonic-gate */
18737c478bd9Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
18747c478bd9Sstevel@tonic-gate }
18757c478bd9Sstevel@tonic-gate
18767c478bd9Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
18777c478bd9Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
18787c478bd9Sstevel@tonic-gate /* something went really wrong. Can't process */
18797c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
18807c478bd9Sstevel@tonic-gate mynode(), dn->cname, sp->setname);
18817c478bd9Sstevel@tonic-gate return;
18827c478bd9Sstevel@tonic-gate }
18837c478bd9Sstevel@tonic-gate
18847c478bd9Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
18857c478bd9Sstevel@tonic-gate devid_same = -1;
18867c478bd9Sstevel@tonic-gate
18877c478bd9Sstevel@tonic-gate if (! rb_mode) {
18887c478bd9Sstevel@tonic-gate dn1 = metadrivename_withdrkey(sp, sideno,
18897c478bd9Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep);
18907c478bd9Sstevel@tonic-gate if (dn1 == NULL) {
18917c478bd9Sstevel@tonic-gate free_sr(sr);
18927c478bd9Sstevel@tonic-gate if (devid_remote)
18937c478bd9Sstevel@tonic-gate devid_free(devid_remote);
18947c478bd9Sstevel@tonic-gate return;
18957c478bd9Sstevel@tonic-gate }
18967c478bd9Sstevel@tonic-gate } else {
18977c478bd9Sstevel@tonic-gate /*
18987c478bd9Sstevel@tonic-gate * Handle special case here where sidenames
18997c478bd9Sstevel@tonic-gate * from other hosts for this drive may be
19007c478bd9Sstevel@tonic-gate * in the local mddb, but there is no
19017c478bd9Sstevel@tonic-gate * sidename entry for this host for this drive.
19027c478bd9Sstevel@tonic-gate * This could have happened if the node
19037c478bd9Sstevel@tonic-gate * panic'd between the 2 operations when
19047c478bd9Sstevel@tonic-gate * adding this node to the set.
19057c478bd9Sstevel@tonic-gate * So, delete all sidename entries for this
19067c478bd9Sstevel@tonic-gate * drive.
19077c478bd9Sstevel@tonic-gate */
19087c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
19097c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
19107c478bd9Sstevel@tonic-gate nr = mnsr->sr_nodechain;
19117c478bd9Sstevel@tonic-gate while (nr) {
19127c478bd9Sstevel@tonic-gate /* We delete all dr sides */
19137c478bd9Sstevel@tonic-gate dn1 = metadrivename_withdrkey(
19147c478bd9Sstevel@tonic-gate sp, nr->nr_nodeid,
19157c478bd9Sstevel@tonic-gate dr->dr_key,
19167c478bd9Sstevel@tonic-gate MD_BASICNAME_OK, ep);
19177c478bd9Sstevel@tonic-gate
19187c478bd9Sstevel@tonic-gate /* if we do, get out of loop */
19197c478bd9Sstevel@tonic-gate if (dn1 != NULL)
19207c478bd9Sstevel@tonic-gate break;
19217c478bd9Sstevel@tonic-gate
19227c478bd9Sstevel@tonic-gate /* save error for later */
19237c478bd9Sstevel@tonic-gate (void) mdstealerror(&xep, ep);
19247c478bd9Sstevel@tonic-gate
19257c478bd9Sstevel@tonic-gate mdclrerror(ep);
19267c478bd9Sstevel@tonic-gate
19277c478bd9Sstevel@tonic-gate nr = nr->nr_next;
19287c478bd9Sstevel@tonic-gate }
19297c478bd9Sstevel@tonic-gate } else {
19307c478bd9Sstevel@tonic-gate /*
19317c478bd9Sstevel@tonic-gate * Handle special case here
19327c478bd9Sstevel@tonic-gate * for traditional diskset
19337c478bd9Sstevel@tonic-gate */
19347c478bd9Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
19357c478bd9Sstevel@tonic-gate /* We delete all dr sides */
19367c478bd9Sstevel@tonic-gate dn1 = metadrivename_withdrkey(
19377c478bd9Sstevel@tonic-gate sp, i, dr->dr_key,
19387c478bd9Sstevel@tonic-gate MD_BASICNAME_OK, ep);
19397c478bd9Sstevel@tonic-gate
19407c478bd9Sstevel@tonic-gate /* if we do, get out of loop */
19417c478bd9Sstevel@tonic-gate if (dn1 != NULL)
19427c478bd9Sstevel@tonic-gate break;
19437c478bd9Sstevel@tonic-gate
19447c478bd9Sstevel@tonic-gate /* save error for later */
19457c478bd9Sstevel@tonic-gate (void) mdstealerror(&xep, ep);
19467c478bd9Sstevel@tonic-gate
19477c478bd9Sstevel@tonic-gate mdclrerror(ep);
19487c478bd9Sstevel@tonic-gate }
19497c478bd9Sstevel@tonic-gate }
19507c478bd9Sstevel@tonic-gate
19517c478bd9Sstevel@tonic-gate if (dn1 == NULL) {
19527c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &xep);
19537c478bd9Sstevel@tonic-gate free_sr(sr);
19547c478bd9Sstevel@tonic-gate if (devid_remote)
19557c478bd9Sstevel@tonic-gate devid_free(devid_remote);
19567c478bd9Sstevel@tonic-gate return;
19577c478bd9Sstevel@tonic-gate }
19587c478bd9Sstevel@tonic-gate
19597c478bd9Sstevel@tonic-gate if (!using_devid)
19607c478bd9Sstevel@tonic-gate mdclrerror(ep);
19617c478bd9Sstevel@tonic-gate }
19627c478bd9Sstevel@tonic-gate
19637c478bd9Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) {
19647c478bd9Sstevel@tonic-gate if (devid_str_decode(dn1->devid, &devid_local,
19657c478bd9Sstevel@tonic-gate NULL) == 0) {
19667c478bd9Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
19677c478bd9Sstevel@tonic-gate devid_local);
19687c478bd9Sstevel@tonic-gate devid_free(devid_local);
19697c478bd9Sstevel@tonic-gate }
19707c478bd9Sstevel@tonic-gate }
19717c478bd9Sstevel@tonic-gate
19727c478bd9Sstevel@tonic-gate /*
19737c478bd9Sstevel@tonic-gate * Has the required disk been found - either the devids
19747c478bd9Sstevel@tonic-gate * match if devid are being used or the actual name of
19757c478bd9Sstevel@tonic-gate * the disk matches.
19767c478bd9Sstevel@tonic-gate */
19777c478bd9Sstevel@tonic-gate if ((using_devid && devid_same == 0) ||
19787c478bd9Sstevel@tonic-gate (!using_devid &&
19797c478bd9Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)) {
19807c478bd9Sstevel@tonic-gate uint_t rep_slice;
19817c478bd9Sstevel@tonic-gate
19827c478bd9Sstevel@tonic-gate dev = NODEV64;
19837c478bd9Sstevel@tonic-gate np = NULL;
19847c478bd9Sstevel@tonic-gate if (meta_replicaslice(dn1,
19857c478bd9Sstevel@tonic-gate &rep_slice, &xep) == 0) {
19867c478bd9Sstevel@tonic-gate np = metaslicename(dn1,
19877c478bd9Sstevel@tonic-gate rep_slice, &xep);
19887c478bd9Sstevel@tonic-gate }
19897c478bd9Sstevel@tonic-gate
19907c478bd9Sstevel@tonic-gate if (np != NULL)
19917c478bd9Sstevel@tonic-gate dev = np->dev;
19927c478bd9Sstevel@tonic-gate else
19937c478bd9Sstevel@tonic-gate mdclrerror(&xep);
19947c478bd9Sstevel@tonic-gate break;
19957c478bd9Sstevel@tonic-gate }
19967c478bd9Sstevel@tonic-gate }
19977c478bd9Sstevel@tonic-gate
19987c478bd9Sstevel@tonic-gate if (dr) {
19997c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
20007c478bd9Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid)
20017c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
20027c478bd9Sstevel@tonic-gate != 0) {
20037c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
20047c478bd9Sstevel@tonic-gate if (devid_remote)
20057c478bd9Sstevel@tonic-gate devid_free(devid_remote);
20067c478bd9Sstevel@tonic-gate free_sr(sr);
20077c478bd9Sstevel@tonic-gate return;
20087c478bd9Sstevel@tonic-gate }
20097c478bd9Sstevel@tonic-gate
20107c478bd9Sstevel@tonic-gate dr_cache_del(sr, dr->dr_selfid);
20117c478bd9Sstevel@tonic-gate
20127c478bd9Sstevel@tonic-gate if (del_sidenamelist(sr, dn1, ep) == -1) {
20137c478bd9Sstevel@tonic-gate goto out;
20147c478bd9Sstevel@tonic-gate }
20157c478bd9Sstevel@tonic-gate
20167c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
20177c478bd9Sstevel@tonic-gate sr->sr_setno, dev);
20187c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
20197c478bd9Sstevel@tonic-gate MD_LOCAL_SET, dev);
20207c478bd9Sstevel@tonic-gate
20217c478bd9Sstevel@tonic-gate continue;
20227c478bd9Sstevel@tonic-gate }
20237c478bd9Sstevel@tonic-gate
20247c478bd9Sstevel@tonic-gate if (devid_remote)
20257c478bd9Sstevel@tonic-gate devid_free(devid_remote);
20267c478bd9Sstevel@tonic-gate }
20277c478bd9Sstevel@tonic-gate
20287c478bd9Sstevel@tonic-gate out:
20297c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
20307c478bd9Sstevel@tonic-gate
20317c478bd9Sstevel@tonic-gate free_sr(sr);
20327c478bd9Sstevel@tonic-gate }
20337c478bd9Sstevel@tonic-gate
20347c478bd9Sstevel@tonic-gate /*
20357c478bd9Sstevel@tonic-gate * delete 1 or more drive records from a host.
20367c478bd9Sstevel@tonic-gate */
20377c478bd9Sstevel@tonic-gate bool_t
mdrpc_deldrvs_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)20387c478bd9Sstevel@tonic-gate mdrpc_deldrvs_common(
20397c478bd9Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args,
20407c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
20417c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
20427c478bd9Sstevel@tonic-gate )
20437c478bd9Sstevel@tonic-gate {
20447c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
20457c478bd9Sstevel@tonic-gate int err;
20467c478bd9Sstevel@tonic-gate int op_mode = W_OK;
20477c478bd9Sstevel@tonic-gate
20487c478bd9Sstevel@tonic-gate /* setup, check permissions */
20497c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
20507c478bd9Sstevel@tonic-gate return (FALSE);
20517c478bd9Sstevel@tonic-gate else if (err != 0)
20527c478bd9Sstevel@tonic-gate return (TRUE);
20537c478bd9Sstevel@tonic-gate
20547c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
20557c478bd9Sstevel@tonic-gate return (TRUE);
20567c478bd9Sstevel@tonic-gate
20577c478bd9Sstevel@tonic-gate /* doit */
20587c478bd9Sstevel@tonic-gate deldrvs(args->sp->setname, args->drivedescs, ep);
20597c478bd9Sstevel@tonic-gate
20607c478bd9Sstevel@tonic-gate err = svc_fini(ep);
20617c478bd9Sstevel@tonic-gate
20627c478bd9Sstevel@tonic-gate return (TRUE);
20637c478bd9Sstevel@tonic-gate }
20647c478bd9Sstevel@tonic-gate
20657c478bd9Sstevel@tonic-gate /*
20667c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
20677c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
20687c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
20697c478bd9Sstevel@tonic-gate */
20707c478bd9Sstevel@tonic-gate bool_t
mdrpc_deldrvs_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)20717c478bd9Sstevel@tonic-gate mdrpc_deldrvs_1_svc(
20727c478bd9Sstevel@tonic-gate mdrpc_drives_args *args,
20737c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
20747c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
20757c478bd9Sstevel@tonic-gate )
20767c478bd9Sstevel@tonic-gate {
20777c478bd9Sstevel@tonic-gate bool_t retval;
20787c478bd9Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args;
20797c478bd9Sstevel@tonic-gate
20807c478bd9Sstevel@tonic-gate /* allocate memory */
20817c478bd9Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
20822a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
20837c478bd9Sstevel@tonic-gate
20847c478bd9Sstevel@tonic-gate /* build args */
20857c478bd9Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
20867c478bd9Sstevel@tonic-gate v2_args.sp = args->sp;
20877c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
20887c478bd9Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
20897c478bd9Sstevel@tonic-gate v2_args.timestamp = args->timestamp;
20907c478bd9Sstevel@tonic-gate v2_args.genid = args->genid;
20917c478bd9Sstevel@tonic-gate
20927c478bd9Sstevel@tonic-gate retval = mdrpc_deldrvs_common(&v2_args, res, rqstp);
20937c478bd9Sstevel@tonic-gate
20947c478bd9Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
20957c478bd9Sstevel@tonic-gate
20967c478bd9Sstevel@tonic-gate return (retval);
20977c478bd9Sstevel@tonic-gate }
20987c478bd9Sstevel@tonic-gate
20997c478bd9Sstevel@tonic-gate bool_t
mdrpc_deldrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)21007c478bd9Sstevel@tonic-gate mdrpc_deldrvs_2_svc(
21017c478bd9Sstevel@tonic-gate mdrpc_drives_2_args *args,
21027c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
21037c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
21047c478bd9Sstevel@tonic-gate )
21057c478bd9Sstevel@tonic-gate {
21062a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
21077c478bd9Sstevel@tonic-gate switch (args->rev) {
21087c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
21097c478bd9Sstevel@tonic-gate return (mdrpc_deldrvs_common(
21107c478bd9Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
21117c478bd9Sstevel@tonic-gate default:
21127c478bd9Sstevel@tonic-gate return (FALSE);
21137c478bd9Sstevel@tonic-gate }
21147c478bd9Sstevel@tonic-gate }
21157c478bd9Sstevel@tonic-gate
21167c478bd9Sstevel@tonic-gate static void
delhosts(char * setname,int node_c,char ** node_v,int version,md_error_t * ep)21177c478bd9Sstevel@tonic-gate delhosts(
21187c478bd9Sstevel@tonic-gate char *setname,
21197c478bd9Sstevel@tonic-gate int node_c,
21207c478bd9Sstevel@tonic-gate char **node_v,
21217c478bd9Sstevel@tonic-gate int version, /* RPC version of calling routine */
21227c478bd9Sstevel@tonic-gate md_error_t *ep
21237c478bd9Sstevel@tonic-gate )
21247c478bd9Sstevel@tonic-gate {
21257c478bd9Sstevel@tonic-gate mddb_userreq_t req;
21267c478bd9Sstevel@tonic-gate md_set_record *sr;
21277c478bd9Sstevel@tonic-gate int i, j;
21287c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
21297c478bd9Sstevel@tonic-gate md_mnnode_record *nr;
21307c478bd9Sstevel@tonic-gate
21317c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
21327c478bd9Sstevel@tonic-gate return;
21337c478bd9Sstevel@tonic-gate
21347c478bd9Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
21357c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
21367c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
21377c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
21387c478bd9Sstevel@tonic-gate nr = mnsr->sr_nodechain;
21397c478bd9Sstevel@tonic-gate while (nr) {
21407c478bd9Sstevel@tonic-gate if (strcmp(nr->nr_nodename, node_v[i]) == 0) {
21417c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG,
21427c478bd9Sstevel@tonic-gate ESC_SVM_REMOVE, SVM_TAG_HOST,
21437c478bd9Sstevel@tonic-gate sr->sr_setno, nr->nr_nodeid);
21447c478bd9Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
21457c478bd9Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_DELETE,
21467c478bd9Sstevel@tonic-gate nr->nr_selfid);
21477c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req,
21487c478bd9Sstevel@tonic-gate &req.ur_mde, NULL) != 0) {
21497c478bd9Sstevel@tonic-gate (void) mdstealerror(ep,
21507c478bd9Sstevel@tonic-gate &req.ur_mde);
21517c478bd9Sstevel@tonic-gate free_sr(sr);
21527c478bd9Sstevel@tonic-gate return;
21537c478bd9Sstevel@tonic-gate }
21547c478bd9Sstevel@tonic-gate mnnr_cache_del(mnsr, nr->nr_selfid);
21557c478bd9Sstevel@tonic-gate break;
21567c478bd9Sstevel@tonic-gate }
21577c478bd9Sstevel@tonic-gate nr = nr->nr_next;
21587c478bd9Sstevel@tonic-gate }
21597c478bd9Sstevel@tonic-gate } else {
21607c478bd9Sstevel@tonic-gate for (j = 0; j < MD_MAXSIDES; j++) {
21617c478bd9Sstevel@tonic-gate if (sr->sr_nodes[j][0] == '\0')
21627c478bd9Sstevel@tonic-gate continue;
21637c478bd9Sstevel@tonic-gate if (strcmp(sr->sr_nodes[j], node_v[i]) != 0)
21647c478bd9Sstevel@tonic-gate continue;
21657c478bd9Sstevel@tonic-gate (void) memset(sr->sr_nodes[j], '\0',
21667c478bd9Sstevel@tonic-gate sizeof (sr->sr_nodes[j]));
21677c478bd9Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE,
21687c478bd9Sstevel@tonic-gate SVM_TAG_HOST, sr->sr_setno, j);
21697c478bd9Sstevel@tonic-gate break;
21707c478bd9Sstevel@tonic-gate }
21717c478bd9Sstevel@tonic-gate }
21727c478bd9Sstevel@tonic-gate }
21737c478bd9Sstevel@tonic-gate
21747c478bd9Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
21757c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
21767c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
21777c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
21787c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
21797c478bd9Sstevel@tonic-gate } else {
21807c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*sr);
21817c478bd9Sstevel@tonic-gate }
21827c478bd9Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
21837c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
21847c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
21857c478bd9Sstevel@tonic-gate free_sr(sr);
21867c478bd9Sstevel@tonic-gate return;
21877c478bd9Sstevel@tonic-gate }
21887c478bd9Sstevel@tonic-gate
21897c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
21907c478bd9Sstevel@tonic-gate free_sr(sr);
21917c478bd9Sstevel@tonic-gate }
21927c478bd9Sstevel@tonic-gate
21937c478bd9Sstevel@tonic-gate /*
21947c478bd9Sstevel@tonic-gate * delete 1 or more a hosts from a set.
21957c478bd9Sstevel@tonic-gate */
21967c478bd9Sstevel@tonic-gate bool_t
mdrpc_delhosts_common(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)21977c478bd9Sstevel@tonic-gate mdrpc_delhosts_common(
21987c478bd9Sstevel@tonic-gate mdrpc_host_args *args,
21997c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
22007c478bd9Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
22017c478bd9Sstevel@tonic-gate int version /* RPC version */
22027c478bd9Sstevel@tonic-gate )
22037c478bd9Sstevel@tonic-gate {
22047c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
22057c478bd9Sstevel@tonic-gate int err;
22067c478bd9Sstevel@tonic-gate int op_mode = W_OK;
22077c478bd9Sstevel@tonic-gate
22087c478bd9Sstevel@tonic-gate /* setup, check permissions */
22097c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
22107c478bd9Sstevel@tonic-gate return (FALSE);
22117c478bd9Sstevel@tonic-gate else if (err != 0)
22127c478bd9Sstevel@tonic-gate return (TRUE);
22137c478bd9Sstevel@tonic-gate
22147c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
22157c478bd9Sstevel@tonic-gate return (TRUE);
22167c478bd9Sstevel@tonic-gate
22177c478bd9Sstevel@tonic-gate /* doit */
22187c478bd9Sstevel@tonic-gate delhosts(args->sp->setname, args->hosts.hosts_len,
22197c478bd9Sstevel@tonic-gate args->hosts.hosts_val, version, ep);
22207c478bd9Sstevel@tonic-gate
22217c478bd9Sstevel@tonic-gate err = svc_fini(ep);
22227c478bd9Sstevel@tonic-gate
22237c478bd9Sstevel@tonic-gate return (TRUE);
22247c478bd9Sstevel@tonic-gate }
22257c478bd9Sstevel@tonic-gate
22267c478bd9Sstevel@tonic-gate bool_t
mdrpc_delhosts_1_svc(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22277c478bd9Sstevel@tonic-gate mdrpc_delhosts_1_svc(
22287c478bd9Sstevel@tonic-gate mdrpc_host_args *args,
22297c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
22307c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22317c478bd9Sstevel@tonic-gate )
22327c478bd9Sstevel@tonic-gate {
22332a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
22347c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
22357c478bd9Sstevel@tonic-gate return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION));
22367c478bd9Sstevel@tonic-gate }
22377c478bd9Sstevel@tonic-gate
22387c478bd9Sstevel@tonic-gate bool_t
mdrpc_delhosts_2_svc(mdrpc_host_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22397c478bd9Sstevel@tonic-gate mdrpc_delhosts_2_svc(
22407c478bd9Sstevel@tonic-gate mdrpc_host_2_args *args,
22417c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
22427c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22437c478bd9Sstevel@tonic-gate )
22447c478bd9Sstevel@tonic-gate {
22452a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
22467c478bd9Sstevel@tonic-gate switch (args->rev) {
22477c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
22487c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
22497c478bd9Sstevel@tonic-gate return (mdrpc_delhosts_common(
22507c478bd9Sstevel@tonic-gate &args->mdrpc_host_2_args_u.rev1, res,
22517c478bd9Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
22527c478bd9Sstevel@tonic-gate default:
22537c478bd9Sstevel@tonic-gate return (FALSE);
22547c478bd9Sstevel@tonic-gate }
22557c478bd9Sstevel@tonic-gate }
22567c478bd9Sstevel@tonic-gate
22577c478bd9Sstevel@tonic-gate /*
22587c478bd9Sstevel@tonic-gate * delete a set.
22597c478bd9Sstevel@tonic-gate */
22607c478bd9Sstevel@tonic-gate bool_t
mdrpc_delset_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22617c478bd9Sstevel@tonic-gate mdrpc_delset_common(
22627c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
22637c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
22647c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22657c478bd9Sstevel@tonic-gate )
22667c478bd9Sstevel@tonic-gate {
22677c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
22687c478bd9Sstevel@tonic-gate int err;
22697c478bd9Sstevel@tonic-gate int op_mode = W_OK;
22707c478bd9Sstevel@tonic-gate
22717c478bd9Sstevel@tonic-gate /* setup, check permissions */
22727c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
22737c478bd9Sstevel@tonic-gate return (FALSE);
22747c478bd9Sstevel@tonic-gate else if (err != 0)
22757c478bd9Sstevel@tonic-gate return (TRUE);
22767c478bd9Sstevel@tonic-gate
22777c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
22787c478bd9Sstevel@tonic-gate return (TRUE);
22797c478bd9Sstevel@tonic-gate
22807c478bd9Sstevel@tonic-gate /* doit */
22817c478bd9Sstevel@tonic-gate s_delset(args->sp->setname, ep);
22827c478bd9Sstevel@tonic-gate
22837c478bd9Sstevel@tonic-gate err = svc_fini(ep);
22847c478bd9Sstevel@tonic-gate
22857c478bd9Sstevel@tonic-gate return (TRUE);
22867c478bd9Sstevel@tonic-gate }
22877c478bd9Sstevel@tonic-gate
22887c478bd9Sstevel@tonic-gate bool_t
mdrpc_delset_1_svc(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22897c478bd9Sstevel@tonic-gate mdrpc_delset_1_svc(
22907c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
22917c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
22927c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
22937c478bd9Sstevel@tonic-gate )
22947c478bd9Sstevel@tonic-gate {
22952a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
22967c478bd9Sstevel@tonic-gate return (mdrpc_delset_common(args, res, rqstp));
22977c478bd9Sstevel@tonic-gate }
22987c478bd9Sstevel@tonic-gate
22997c478bd9Sstevel@tonic-gate bool_t
mdrpc_delset_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)23007c478bd9Sstevel@tonic-gate mdrpc_delset_2_svc(
23017c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args,
23027c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
23037c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
23047c478bd9Sstevel@tonic-gate )
23057c478bd9Sstevel@tonic-gate {
23062a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
23077c478bd9Sstevel@tonic-gate switch (args->rev) {
23087c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
23097c478bd9Sstevel@tonic-gate return (mdrpc_delset_common(
23107c478bd9Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
23117c478bd9Sstevel@tonic-gate default:
23127c478bd9Sstevel@tonic-gate return (FALSE);
23137c478bd9Sstevel@tonic-gate }
23147c478bd9Sstevel@tonic-gate }
23157c478bd9Sstevel@tonic-gate
23167c478bd9Sstevel@tonic-gate /*
23177c478bd9Sstevel@tonic-gate * return device info
23187c478bd9Sstevel@tonic-gate */
23197c478bd9Sstevel@tonic-gate static void
devinfo(mdsetname_t * sp,mddrivename_t * dp,mdrpc_devinfo_2_res * res,md_error_t * ep)23207c478bd9Sstevel@tonic-gate devinfo(
23217c478bd9Sstevel@tonic-gate mdsetname_t *sp,
23227c478bd9Sstevel@tonic-gate mddrivename_t *dp,
23237c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
23247c478bd9Sstevel@tonic-gate md_error_t *ep
23257c478bd9Sstevel@tonic-gate )
23267c478bd9Sstevel@tonic-gate {
23277c478bd9Sstevel@tonic-gate mdname_t *np, *real_np;
23287c478bd9Sstevel@tonic-gate
23297c478bd9Sstevel@tonic-gate if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
23307c478bd9Sstevel@tonic-gate return;
23317c478bd9Sstevel@tonic-gate
2332d7cd8252Stw21770 if ((real_np = metaname(&sp, np->bname, LOGICAL_DEVICE, ep)) == NULL)
23337c478bd9Sstevel@tonic-gate return;
23347c478bd9Sstevel@tonic-gate
23357c478bd9Sstevel@tonic-gate res->dev = real_np->dev;
23367c478bd9Sstevel@tonic-gate (void) getdevstamp(dp, (long *)&res->vtime, ep);
23377c478bd9Sstevel@tonic-gate res->enc_devid = meta_get_devid(np->rname);
23387c478bd9Sstevel@tonic-gate }
23397c478bd9Sstevel@tonic-gate
23407c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_common(mdrpc_devinfo_2_args_r1 * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)23417c478bd9Sstevel@tonic-gate mdrpc_devinfo_common(
23427c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_args_r1 *args,
23437c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
23447c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
23457c478bd9Sstevel@tonic-gate )
23467c478bd9Sstevel@tonic-gate {
23477c478bd9Sstevel@tonic-gate int slice;
23487c478bd9Sstevel@tonic-gate mdname_t *np;
23497c478bd9Sstevel@tonic-gate mddrivename_t *dnp = args->drivenamep;
23507c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
23517c478bd9Sstevel@tonic-gate int err;
23527c478bd9Sstevel@tonic-gate int op_mode = R_OK;
23537c478bd9Sstevel@tonic-gate
23547c478bd9Sstevel@tonic-gate /* setup, check permissions */
23557c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
23567c478bd9Sstevel@tonic-gate return (FALSE);
23577c478bd9Sstevel@tonic-gate else if (err != 0)
23587c478bd9Sstevel@tonic-gate return (TRUE);
23597c478bd9Sstevel@tonic-gate
23607c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
23617c478bd9Sstevel@tonic-gate return (TRUE);
23627c478bd9Sstevel@tonic-gate
23637c478bd9Sstevel@tonic-gate /*
23647c478bd9Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to
23657c478bd9Sstevel@tonic-gate * point to the right place.
23667c478bd9Sstevel@tonic-gate */
23677c478bd9Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
23687c478bd9Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL)
23697c478bd9Sstevel@tonic-gate return (TRUE);
23707c478bd9Sstevel@tonic-gate np->drivenamep = dnp;
23717c478bd9Sstevel@tonic-gate }
23727c478bd9Sstevel@tonic-gate
23737c478bd9Sstevel@tonic-gate /* doit */
23747c478bd9Sstevel@tonic-gate devinfo(args->sp, dnp, res, ep);
23757c478bd9Sstevel@tonic-gate
23767c478bd9Sstevel@tonic-gate err = svc_fini(ep);
23777c478bd9Sstevel@tonic-gate
23787c478bd9Sstevel@tonic-gate return (TRUE);
23797c478bd9Sstevel@tonic-gate }
23807c478bd9Sstevel@tonic-gate
23817c478bd9Sstevel@tonic-gate /*
23827c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
23837c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
23847c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
23857c478bd9Sstevel@tonic-gate */
23867c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_1_svc(mdrpc_devinfo_args * args,mdrpc_devinfo_res * res,struct svc_req * rqstp)23877c478bd9Sstevel@tonic-gate mdrpc_devinfo_1_svc(
23887c478bd9Sstevel@tonic-gate mdrpc_devinfo_args *args,
23897c478bd9Sstevel@tonic-gate mdrpc_devinfo_res *res,
23907c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
23917c478bd9Sstevel@tonic-gate )
23927c478bd9Sstevel@tonic-gate {
23937c478bd9Sstevel@tonic-gate bool_t retval;
23947c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_args_r1 v2_args;
23957c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_res v2_res;
23967c478bd9Sstevel@tonic-gate
23977c478bd9Sstevel@tonic-gate /* allocate memory */
23987c478bd9Sstevel@tonic-gate v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
23997c478bd9Sstevel@tonic-gate v2_args.drivenamep->parts.parts_val =
24007c478bd9Sstevel@tonic-gate Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
24012a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
24027c478bd9Sstevel@tonic-gate
24037c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
24047c478bd9Sstevel@tonic-gate meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
24057c478bd9Sstevel@tonic-gate retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp);
24067c478bd9Sstevel@tonic-gate
24077c478bd9Sstevel@tonic-gate /*
24087c478bd9Sstevel@tonic-gate * Fill in the result appropriately.
24097c478bd9Sstevel@tonic-gate * Since dev_t's for version 2 are 64-bit,
24107c478bd9Sstevel@tonic-gate * we need to convert them to 32-bit for version 1.
24117c478bd9Sstevel@tonic-gate */
24127c478bd9Sstevel@tonic-gate res->dev = meta_cmpldev(v2_res.dev);
24137c478bd9Sstevel@tonic-gate res->vtime = v2_res.vtime;
24147c478bd9Sstevel@tonic-gate res->status = v2_res.status;
24157c478bd9Sstevel@tonic-gate
24167c478bd9Sstevel@tonic-gate free(v2_args.drivenamep);
24177c478bd9Sstevel@tonic-gate free(v2_args.drivenamep->parts.parts_val);
24187c478bd9Sstevel@tonic-gate
24197c478bd9Sstevel@tonic-gate return (retval);
24207c478bd9Sstevel@tonic-gate }
24217c478bd9Sstevel@tonic-gate
24227c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_2_svc(mdrpc_devinfo_2_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)24237c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_svc(
24247c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_args *args,
24257c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
24267c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
24277c478bd9Sstevel@tonic-gate )
24287c478bd9Sstevel@tonic-gate {
24292a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
24307c478bd9Sstevel@tonic-gate switch (args->rev) {
24317c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
24327c478bd9Sstevel@tonic-gate return (mdrpc_devinfo_common(
24337c478bd9Sstevel@tonic-gate &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp));
24347c478bd9Sstevel@tonic-gate default:
24357c478bd9Sstevel@tonic-gate return (FALSE);
24367c478bd9Sstevel@tonic-gate }
24377c478bd9Sstevel@tonic-gate }
24387c478bd9Sstevel@tonic-gate
24397c478bd9Sstevel@tonic-gate /*
24407c478bd9Sstevel@tonic-gate * return device id
24417c478bd9Sstevel@tonic-gate */
24427c478bd9Sstevel@tonic-gate static void
mdrpc_get_devid(mdsetname_t * sp,mddrivename_t * dp,mdrpc_devid_res * res,md_error_t * ep)24437c478bd9Sstevel@tonic-gate mdrpc_get_devid(
24447c478bd9Sstevel@tonic-gate mdsetname_t *sp,
24457c478bd9Sstevel@tonic-gate mddrivename_t *dp,
24467c478bd9Sstevel@tonic-gate mdrpc_devid_res *res,
24477c478bd9Sstevel@tonic-gate md_error_t *ep
24487c478bd9Sstevel@tonic-gate )
24497c478bd9Sstevel@tonic-gate {
24507c478bd9Sstevel@tonic-gate mdname_t *np;
24517c478bd9Sstevel@tonic-gate
24527c478bd9Sstevel@tonic-gate if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
24537c478bd9Sstevel@tonic-gate return;
24547c478bd9Sstevel@tonic-gate
2455d7cd8252Stw21770 if (metaname(&sp, np->bname, LOGICAL_DEVICE, ep) == NULL)
24567c478bd9Sstevel@tonic-gate return;
24577c478bd9Sstevel@tonic-gate
24587c478bd9Sstevel@tonic-gate res->enc_devid = meta_get_devid(np->rname);
24597c478bd9Sstevel@tonic-gate }
24607c478bd9Sstevel@tonic-gate
24617c478bd9Sstevel@tonic-gate bool_t
mdrpc_devid_2_svc(mdrpc_devid_2_args * args,mdrpc_devid_res * res,struct svc_req * rqstp)24627c478bd9Sstevel@tonic-gate mdrpc_devid_2_svc(
24637c478bd9Sstevel@tonic-gate mdrpc_devid_2_args *args,
24647c478bd9Sstevel@tonic-gate mdrpc_devid_res *res,
24657c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
24667c478bd9Sstevel@tonic-gate )
24677c478bd9Sstevel@tonic-gate {
24687c478bd9Sstevel@tonic-gate int slice;
24697c478bd9Sstevel@tonic-gate mdname_t *np;
24707c478bd9Sstevel@tonic-gate mddrivename_t *dnp;
24717c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
24727c478bd9Sstevel@tonic-gate int err;
24737c478bd9Sstevel@tonic-gate int op_mode = R_OK;
24747c478bd9Sstevel@tonic-gate
24752a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
24767c478bd9Sstevel@tonic-gate switch (args->rev) {
24777c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
24787c478bd9Sstevel@tonic-gate dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep;
24797c478bd9Sstevel@tonic-gate break;
24807c478bd9Sstevel@tonic-gate default:
24817c478bd9Sstevel@tonic-gate return (FALSE);
24827c478bd9Sstevel@tonic-gate }
24837c478bd9Sstevel@tonic-gate
24847c478bd9Sstevel@tonic-gate /* setup, check permissions */
24857c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
24867c478bd9Sstevel@tonic-gate return (FALSE);
24877c478bd9Sstevel@tonic-gate else if (err != 0)
24887c478bd9Sstevel@tonic-gate return (TRUE);
24897c478bd9Sstevel@tonic-gate
24907c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
24917c478bd9Sstevel@tonic-gate return (TRUE);
24927c478bd9Sstevel@tonic-gate
24937c478bd9Sstevel@tonic-gate /*
24947c478bd9Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to
24957c478bd9Sstevel@tonic-gate * point to the right place.
24967c478bd9Sstevel@tonic-gate */
24977c478bd9Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
24987c478bd9Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL)
24997c478bd9Sstevel@tonic-gate return (TRUE);
25007c478bd9Sstevel@tonic-gate np->drivenamep = dnp;
25017c478bd9Sstevel@tonic-gate }
25027c478bd9Sstevel@tonic-gate
25037c478bd9Sstevel@tonic-gate /* doit */
25047c478bd9Sstevel@tonic-gate mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep);
25057c478bd9Sstevel@tonic-gate
25067c478bd9Sstevel@tonic-gate err = svc_fini(ep);
25077c478bd9Sstevel@tonic-gate
25087c478bd9Sstevel@tonic-gate return (TRUE);
25097c478bd9Sstevel@tonic-gate }
25107c478bd9Sstevel@tonic-gate
25117c478bd9Sstevel@tonic-gate /*
25127c478bd9Sstevel@tonic-gate * This routine should not be called for a multi-node diskset.
25137c478bd9Sstevel@tonic-gate *
25147c478bd9Sstevel@tonic-gate * The devid support is disabled for MN diskset so this routine
25157c478bd9Sstevel@tonic-gate * will not be called if the set is MN diskset. The check has
25167c478bd9Sstevel@tonic-gate * been done early in meta_getnextside_devinfo. However this
25177c478bd9Sstevel@tonic-gate * routine will be called when the devid support for MN set is
25187c478bd9Sstevel@tonic-gate * enabled and check is removed.
25197c478bd9Sstevel@tonic-gate */
25207c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_by_devid_2_svc(mdrpc_devidstr_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)25217c478bd9Sstevel@tonic-gate mdrpc_devinfo_by_devid_2_svc(
25227c478bd9Sstevel@tonic-gate mdrpc_devidstr_args *args,
25237c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
25247c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
25257c478bd9Sstevel@tonic-gate )
25267c478bd9Sstevel@tonic-gate {
25277c478bd9Sstevel@tonic-gate
25287c478bd9Sstevel@tonic-gate char *devidstr = args->enc_devid;
25297c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
25307c478bd9Sstevel@tonic-gate ddi_devid_t devid;
25317c478bd9Sstevel@tonic-gate char *minor_name = NULL;
25327c478bd9Sstevel@tonic-gate int ret = 0;
25337c478bd9Sstevel@tonic-gate int err;
25347c478bd9Sstevel@tonic-gate devid_nmlist_t *disklist = NULL;
25357c478bd9Sstevel@tonic-gate int op_mode = R_OK;
25367c478bd9Sstevel@tonic-gate mdname_t *np;
25377c478bd9Sstevel@tonic-gate mdsetname_t *sp = args->sp;
25387c478bd9Sstevel@tonic-gate
25397c478bd9Sstevel@tonic-gate /* setup, check permissions */
25407c478bd9Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
25417c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
25427c478bd9Sstevel@tonic-gate return (FALSE);
25437c478bd9Sstevel@tonic-gate else if (err != 0)
25447c478bd9Sstevel@tonic-gate return (TRUE);
25457c478bd9Sstevel@tonic-gate
25467c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
25477c478bd9Sstevel@tonic-gate return (TRUE);
25487c478bd9Sstevel@tonic-gate
25497c478bd9Sstevel@tonic-gate if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
25507c478bd9Sstevel@tonic-gate return (TRUE);
25517c478bd9Sstevel@tonic-gate
25527c478bd9Sstevel@tonic-gate /*
25537c478bd9Sstevel@tonic-gate * if we do not have a minor name then look for a character device.
25547c478bd9Sstevel@tonic-gate * This is because the caller (checkdrive_onnode) expects a character
25557c478bd9Sstevel@tonic-gate * device to be returned. The other client of this interface is
25567c478bd9Sstevel@tonic-gate * meta_getnextside_devinfo and this supplies a minor name.
25577c478bd9Sstevel@tonic-gate */
25587c478bd9Sstevel@tonic-gate if (minor_name == NULL) {
25597c478bd9Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid,
25607c478bd9Sstevel@tonic-gate DEVID_MINOR_NAME_ALL_CHR, &disklist);
25617c478bd9Sstevel@tonic-gate } else {
25627c478bd9Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
25637c478bd9Sstevel@tonic-gate &disklist);
25647c478bd9Sstevel@tonic-gate devid_str_free(minor_name);
25657c478bd9Sstevel@tonic-gate }
25667c478bd9Sstevel@tonic-gate
25677c478bd9Sstevel@tonic-gate devid_free(devid);
25687c478bd9Sstevel@tonic-gate if (ret != 0) {
25697c478bd9Sstevel@tonic-gate res->dev = NODEV64;
25707c478bd9Sstevel@tonic-gate devid_free_nmlist(disklist);
25717c478bd9Sstevel@tonic-gate return (TRUE);
25727c478bd9Sstevel@tonic-gate }
25737c478bd9Sstevel@tonic-gate
2574d7cd8252Stw21770 np = metaname(&sp, disklist[0].devname, LOGICAL_DEVICE, ep);
25757c478bd9Sstevel@tonic-gate if (np != NULL) {
25767c478bd9Sstevel@tonic-gate mdcinfo_t *cinfo;
25777c478bd9Sstevel@tonic-gate if ((cinfo = metagetcinfo(np, ep)) != NULL) {
25787c478bd9Sstevel@tonic-gate res->drivername = Strdup(cinfo->dname);
25797c478bd9Sstevel@tonic-gate }
25807c478bd9Sstevel@tonic-gate }
25817c478bd9Sstevel@tonic-gate
25827c478bd9Sstevel@tonic-gate res->dev = meta_expldev(disklist[0].dev);
25837c478bd9Sstevel@tonic-gate res->devname = strdup(disklist[0].devname);
25847c478bd9Sstevel@tonic-gate
25857c478bd9Sstevel@tonic-gate devid_free_nmlist(disklist);
25867c478bd9Sstevel@tonic-gate
25877c478bd9Sstevel@tonic-gate err = svc_fini(ep);
25887c478bd9Sstevel@tonic-gate
25897c478bd9Sstevel@tonic-gate return (TRUE);
25907c478bd9Sstevel@tonic-gate }
25917c478bd9Sstevel@tonic-gate
25927c478bd9Sstevel@tonic-gate /*
25937c478bd9Sstevel@tonic-gate * This routine should not be called for a multi-node diskset.
25947c478bd9Sstevel@tonic-gate *
25957c478bd9Sstevel@tonic-gate * The devid support is disabled for MN diskset so this routine
25967c478bd9Sstevel@tonic-gate * will not be called if the set is MN diskset. The check has
25977c478bd9Sstevel@tonic-gate * been done early in meta_getnextside_devinfo. However this
25987c478bd9Sstevel@tonic-gate * routine will be called when the devid support for MN set is
25997c478bd9Sstevel@tonic-gate * enabled and check is removed.
26007c478bd9Sstevel@tonic-gate *
26017c478bd9Sstevel@tonic-gate * This function will return the device info attempting to use
26027c478bd9Sstevel@tonic-gate * both the passed in devid and device name. This is to deal
26037c478bd9Sstevel@tonic-gate * with systems that use multi-path disks but not running mpxio.
26047c478bd9Sstevel@tonic-gate * In this situation meta_deviceid_to_nmlist will return multiple
26057c478bd9Sstevel@tonic-gate * devices. The orig_devname is used to disambiguate.
26067c478bd9Sstevel@tonic-gate *
26077c478bd9Sstevel@tonic-gate */
26087c478bd9Sstevel@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)26097c478bd9Sstevel@tonic-gate mdrpc_devinfo_by_devid_name_2_svc(
26107c478bd9Sstevel@tonic-gate mdrpc_devid_name_2_args *args,
26117c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_res *res,
26127c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
26137c478bd9Sstevel@tonic-gate )
26147c478bd9Sstevel@tonic-gate {
26157c478bd9Sstevel@tonic-gate
26167c478bd9Sstevel@tonic-gate char *devidstr;
26177c478bd9Sstevel@tonic-gate char *orig_devname;
26187c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
26197c478bd9Sstevel@tonic-gate ddi_devid_t devid;
26207c478bd9Sstevel@tonic-gate char *minor_name = NULL;
26217c478bd9Sstevel@tonic-gate int ret = 0;
26227c478bd9Sstevel@tonic-gate int err;
26237c478bd9Sstevel@tonic-gate int i;
26247c478bd9Sstevel@tonic-gate devid_nmlist_t *disklist = NULL;
26257c478bd9Sstevel@tonic-gate int op_mode = R_OK;
26267c478bd9Sstevel@tonic-gate mdname_t *np;
26277c478bd9Sstevel@tonic-gate mdsetname_t *sp;
26287c478bd9Sstevel@tonic-gate
26292a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
26307c478bd9Sstevel@tonic-gate switch (args->rev) {
26317c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
26327c478bd9Sstevel@tonic-gate sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp;
26337c478bd9Sstevel@tonic-gate devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid;
26347c478bd9Sstevel@tonic-gate orig_devname =
26357c478bd9Sstevel@tonic-gate (&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname;
26367c478bd9Sstevel@tonic-gate break;
26377c478bd9Sstevel@tonic-gate default:
26387c478bd9Sstevel@tonic-gate return (FALSE);
26397c478bd9Sstevel@tonic-gate }
26407c478bd9Sstevel@tonic-gate
26417c478bd9Sstevel@tonic-gate /* setup, check permissions */
26427c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
26437c478bd9Sstevel@tonic-gate return (FALSE);
26447c478bd9Sstevel@tonic-gate else if (err != 0)
26457c478bd9Sstevel@tonic-gate return (TRUE);
26467c478bd9Sstevel@tonic-gate
26477c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
26487c478bd9Sstevel@tonic-gate return (TRUE);
26497c478bd9Sstevel@tonic-gate
26507c478bd9Sstevel@tonic-gate if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
26517c478bd9Sstevel@tonic-gate return (TRUE);
26527c478bd9Sstevel@tonic-gate
26537c478bd9Sstevel@tonic-gate /*
26547c478bd9Sstevel@tonic-gate * if we do not have a minor name then look for a character device.
26557c478bd9Sstevel@tonic-gate * This is because the caller (checkdrive_onnode) expects a character
26567c478bd9Sstevel@tonic-gate * device to be returned. The other client of this interface is
26577c478bd9Sstevel@tonic-gate * meta_getnextside_devinfo and this supplies a minor name.
26587c478bd9Sstevel@tonic-gate */
26597c478bd9Sstevel@tonic-gate if (minor_name == NULL) {
26607c478bd9Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid,
26617c478bd9Sstevel@tonic-gate DEVID_MINOR_NAME_ALL_CHR, &disklist);
26627c478bd9Sstevel@tonic-gate } else {
26637c478bd9Sstevel@tonic-gate ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
26647c478bd9Sstevel@tonic-gate &disklist);
26657c478bd9Sstevel@tonic-gate devid_str_free(minor_name);
26667c478bd9Sstevel@tonic-gate }
26677c478bd9Sstevel@tonic-gate
26687c478bd9Sstevel@tonic-gate devid_free(devid);
26697c478bd9Sstevel@tonic-gate if (ret != 0) {
26707c478bd9Sstevel@tonic-gate res->dev = NODEV64;
26717c478bd9Sstevel@tonic-gate devid_free_nmlist(disklist);
26727c478bd9Sstevel@tonic-gate return (TRUE);
26737c478bd9Sstevel@tonic-gate }
26747c478bd9Sstevel@tonic-gate
26757c478bd9Sstevel@tonic-gate /* attempt to match to the device name on the originating node */
26767c478bd9Sstevel@tonic-gate for (i = 0; disklist[i].dev != NODEV; i++) {
26777c478bd9Sstevel@tonic-gate if (strncmp(orig_devname, disklist[i].devname,
26787c478bd9Sstevel@tonic-gate strlen(disklist[i].devname)) == 0)
26797c478bd9Sstevel@tonic-gate break;
26807c478bd9Sstevel@tonic-gate }
26817c478bd9Sstevel@tonic-gate
26827c478bd9Sstevel@tonic-gate /* if it's not found then use the first disk in the list */
26837c478bd9Sstevel@tonic-gate if (disklist[i].dev == NODEV)
26847c478bd9Sstevel@tonic-gate i = 0;
26857c478bd9Sstevel@tonic-gate
2686d7cd8252Stw21770 np = metaname(&sp, disklist[i].devname, LOGICAL_DEVICE, ep);
26877c478bd9Sstevel@tonic-gate if (np != NULL) {
26887c478bd9Sstevel@tonic-gate mdcinfo_t *cinfo;
26897c478bd9Sstevel@tonic-gate if ((cinfo = metagetcinfo(np, ep)) != NULL) {
26907c478bd9Sstevel@tonic-gate res->drivername = Strdup(cinfo->dname);
26917c478bd9Sstevel@tonic-gate }
26927c478bd9Sstevel@tonic-gate }
26937c478bd9Sstevel@tonic-gate
26947c478bd9Sstevel@tonic-gate res->dev = meta_expldev(disklist[i].dev);
26957c478bd9Sstevel@tonic-gate res->devname = strdup(disklist[i].devname);
26967c478bd9Sstevel@tonic-gate
26977c478bd9Sstevel@tonic-gate devid_free_nmlist(disklist);
26987c478bd9Sstevel@tonic-gate
26997c478bd9Sstevel@tonic-gate err = svc_fini(ep);
27007c478bd9Sstevel@tonic-gate
27017c478bd9Sstevel@tonic-gate return (TRUE);
27027c478bd9Sstevel@tonic-gate }
27037c478bd9Sstevel@tonic-gate
27047c478bd9Sstevel@tonic-gate static void
drvused(mdsetname_t * sp,mddrivename_t * dnp,md_error_t * ep)27057c478bd9Sstevel@tonic-gate drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep)
27067c478bd9Sstevel@tonic-gate {
27077c478bd9Sstevel@tonic-gate if (meta_check_drivemounted(sp, dnp, ep))
27087c478bd9Sstevel@tonic-gate return;
27097c478bd9Sstevel@tonic-gate
27107c478bd9Sstevel@tonic-gate if (meta_check_driveswapped(sp, dnp, ep))
27117c478bd9Sstevel@tonic-gate return;
27127c478bd9Sstevel@tonic-gate
27137c478bd9Sstevel@tonic-gate if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp,
27147c478bd9Sstevel@tonic-gate TRUE, ep))
27157c478bd9Sstevel@tonic-gate return;
27167c478bd9Sstevel@tonic-gate
27177c478bd9Sstevel@tonic-gate (void) meta_check_driveinset(sp, dnp, ep);
27187c478bd9Sstevel@tonic-gate }
27197c478bd9Sstevel@tonic-gate
27207c478bd9Sstevel@tonic-gate /*
27217c478bd9Sstevel@tonic-gate * determine if a device is in use.
27227c478bd9Sstevel@tonic-gate */
27237c478bd9Sstevel@tonic-gate bool_t
mdrpc_drvused_common(mdrpc_drvused_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)27247c478bd9Sstevel@tonic-gate mdrpc_drvused_common(
27257c478bd9Sstevel@tonic-gate mdrpc_drvused_2_args_r1 *args,
27267c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
27277c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
27287c478bd9Sstevel@tonic-gate )
27297c478bd9Sstevel@tonic-gate {
27307c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
27317c478bd9Sstevel@tonic-gate int slice;
27327c478bd9Sstevel@tonic-gate mdname_t *np;
27337c478bd9Sstevel@tonic-gate mddrivename_t *dnp = args->drivenamep;
27347c478bd9Sstevel@tonic-gate int err;
27357c478bd9Sstevel@tonic-gate int op_mode = R_OK;
27367c478bd9Sstevel@tonic-gate
27377c478bd9Sstevel@tonic-gate /* setup, check permissions */
27387c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
27397c478bd9Sstevel@tonic-gate return (FALSE);
27407c478bd9Sstevel@tonic-gate else if (err != 0)
27417c478bd9Sstevel@tonic-gate return (TRUE);
27427c478bd9Sstevel@tonic-gate
27437c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
27447c478bd9Sstevel@tonic-gate return (TRUE);
27457c478bd9Sstevel@tonic-gate
27467c478bd9Sstevel@tonic-gate if (dnp == NULL) {
27477c478bd9Sstevel@tonic-gate /* no drive pointer specified */
27487c478bd9Sstevel@tonic-gate return (TRUE);
27497c478bd9Sstevel@tonic-gate }
27507c478bd9Sstevel@tonic-gate /*
27517c478bd9Sstevel@tonic-gate * fix all the drivenamep's in the mdname_t's to
27527c478bd9Sstevel@tonic-gate * point to the right place.
27537c478bd9Sstevel@tonic-gate */
27547c478bd9Sstevel@tonic-gate for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
27557c478bd9Sstevel@tonic-gate if ((np = metaslicename(dnp, slice, ep)) == NULL)
27567c478bd9Sstevel@tonic-gate return (TRUE);
27577c478bd9Sstevel@tonic-gate np->drivenamep = dnp;
27587c478bd9Sstevel@tonic-gate }
27597c478bd9Sstevel@tonic-gate
27607c478bd9Sstevel@tonic-gate /* doit */
27617c478bd9Sstevel@tonic-gate drvused(args->sp, dnp, ep);
27627c478bd9Sstevel@tonic-gate
27637c478bd9Sstevel@tonic-gate err = svc_fini(ep);
27647c478bd9Sstevel@tonic-gate
27657c478bd9Sstevel@tonic-gate return (TRUE);
27667c478bd9Sstevel@tonic-gate }
27677c478bd9Sstevel@tonic-gate
27687c478bd9Sstevel@tonic-gate /*
27697c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
27707c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
27717c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
27727c478bd9Sstevel@tonic-gate */
27737c478bd9Sstevel@tonic-gate bool_t
mdrpc_drvused_1_svc(mdrpc_drvused_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)27747c478bd9Sstevel@tonic-gate mdrpc_drvused_1_svc(
27757c478bd9Sstevel@tonic-gate mdrpc_drvused_args *args,
27767c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
27777c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
27787c478bd9Sstevel@tonic-gate )
27797c478bd9Sstevel@tonic-gate {
27807c478bd9Sstevel@tonic-gate bool_t retval;
27817c478bd9Sstevel@tonic-gate mdrpc_drvused_2_args_r1 v2_args;
27827c478bd9Sstevel@tonic-gate
27837c478bd9Sstevel@tonic-gate /* allocate memory */
27847c478bd9Sstevel@tonic-gate v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
27857c478bd9Sstevel@tonic-gate v2_args.drivenamep->parts.parts_val =
27867c478bd9Sstevel@tonic-gate Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
27872a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
27887c478bd9Sstevel@tonic-gate
27897c478bd9Sstevel@tonic-gate /* build args */
27907c478bd9Sstevel@tonic-gate v2_args.sp = args->sp;
27917c478bd9Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
27927c478bd9Sstevel@tonic-gate
27937c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
27947c478bd9Sstevel@tonic-gate meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
27957c478bd9Sstevel@tonic-gate retval = mdrpc_drvused_common(&v2_args, res, rqstp);
27967c478bd9Sstevel@tonic-gate
27977c478bd9Sstevel@tonic-gate free(v2_args.drivenamep);
27987c478bd9Sstevel@tonic-gate free(v2_args.drivenamep->parts.parts_val);
27997c478bd9Sstevel@tonic-gate
28007c478bd9Sstevel@tonic-gate return (retval);
28017c478bd9Sstevel@tonic-gate }
28027c478bd9Sstevel@tonic-gate
28037c478bd9Sstevel@tonic-gate bool_t
mdrpc_drvused_2_svc(mdrpc_drvused_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)28047c478bd9Sstevel@tonic-gate mdrpc_drvused_2_svc(
28057c478bd9Sstevel@tonic-gate mdrpc_drvused_2_args *args,
28067c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
28077c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28087c478bd9Sstevel@tonic-gate )
28097c478bd9Sstevel@tonic-gate {
28102a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
28117c478bd9Sstevel@tonic-gate switch (args->rev) {
28127c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
28137c478bd9Sstevel@tonic-gate return (mdrpc_drvused_common(
28147c478bd9Sstevel@tonic-gate &args->mdrpc_drvused_2_args_u.rev1, res, rqstp));
28157c478bd9Sstevel@tonic-gate default:
28167c478bd9Sstevel@tonic-gate return (FALSE);
28177c478bd9Sstevel@tonic-gate }
28187c478bd9Sstevel@tonic-gate }
28197c478bd9Sstevel@tonic-gate
28207c478bd9Sstevel@tonic-gate /*
28217c478bd9Sstevel@tonic-gate * return a set records selected by name or number.
28227c478bd9Sstevel@tonic-gate */
28237c478bd9Sstevel@tonic-gate bool_t
mdrpc_getset_common(mdrpc_getset_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28247c478bd9Sstevel@tonic-gate mdrpc_getset_common(
28257c478bd9Sstevel@tonic-gate mdrpc_getset_args *args,
28267c478bd9Sstevel@tonic-gate mdrpc_getset_res *res,
28277c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28287c478bd9Sstevel@tonic-gate )
28297c478bd9Sstevel@tonic-gate {
28307c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
28317c478bd9Sstevel@tonic-gate int err;
28327c478bd9Sstevel@tonic-gate int op_mode = R_OK;
28337c478bd9Sstevel@tonic-gate
28347c478bd9Sstevel@tonic-gate /* setup, check permissions */
28357c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
28367c478bd9Sstevel@tonic-gate return (FALSE);
28377c478bd9Sstevel@tonic-gate else if (err != 0)
28387c478bd9Sstevel@tonic-gate return (TRUE);
28397c478bd9Sstevel@tonic-gate
28407c478bd9Sstevel@tonic-gate /* Don't have a setno, so we don't check the lock */
28417c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
28427c478bd9Sstevel@tonic-gate return (TRUE);
28437c478bd9Sstevel@tonic-gate
28447c478bd9Sstevel@tonic-gate /* doit */
28457c478bd9Sstevel@tonic-gate if (args->setname && *args->setname)
28467c478bd9Sstevel@tonic-gate res->sr = setdup(getsetbyname(args->setname, ep));
28477c478bd9Sstevel@tonic-gate else if (args->setno > 0)
28487c478bd9Sstevel@tonic-gate res->sr = setdup(getsetbynum(args->setno, ep));
28497c478bd9Sstevel@tonic-gate else
28507c478bd9Sstevel@tonic-gate res->sr = NULL;
28517c478bd9Sstevel@tonic-gate
28527c478bd9Sstevel@tonic-gate err = svc_fini(ep);
28537c478bd9Sstevel@tonic-gate
28547c478bd9Sstevel@tonic-gate return (TRUE);
28557c478bd9Sstevel@tonic-gate }
28567c478bd9Sstevel@tonic-gate
28577c478bd9Sstevel@tonic-gate bool_t
mdrpc_getset_1_svc(mdrpc_getset_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28587c478bd9Sstevel@tonic-gate mdrpc_getset_1_svc(
28597c478bd9Sstevel@tonic-gate mdrpc_getset_args *args,
28607c478bd9Sstevel@tonic-gate mdrpc_getset_res *res,
28617c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28627c478bd9Sstevel@tonic-gate )
28637c478bd9Sstevel@tonic-gate {
28642a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
28657c478bd9Sstevel@tonic-gate return (mdrpc_getset_common(args, res, rqstp));
28667c478bd9Sstevel@tonic-gate }
28677c478bd9Sstevel@tonic-gate
28687c478bd9Sstevel@tonic-gate bool_t
mdrpc_getset_2_svc(mdrpc_getset_2_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28697c478bd9Sstevel@tonic-gate mdrpc_getset_2_svc(
28707c478bd9Sstevel@tonic-gate mdrpc_getset_2_args *args,
28717c478bd9Sstevel@tonic-gate mdrpc_getset_res *res,
28727c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28737c478bd9Sstevel@tonic-gate )
28747c478bd9Sstevel@tonic-gate {
28752a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
28767c478bd9Sstevel@tonic-gate switch (args->rev) {
28777c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
28787c478bd9Sstevel@tonic-gate return (mdrpc_getset_common(
28797c478bd9Sstevel@tonic-gate &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
28807c478bd9Sstevel@tonic-gate default:
28817c478bd9Sstevel@tonic-gate return (FALSE);
28827c478bd9Sstevel@tonic-gate }
28837c478bd9Sstevel@tonic-gate }
28847c478bd9Sstevel@tonic-gate
28857c478bd9Sstevel@tonic-gate /*
28867c478bd9Sstevel@tonic-gate * return a MN set record selected by name or number.
28877c478bd9Sstevel@tonic-gate */
28887c478bd9Sstevel@tonic-gate bool_t
mdrpc_mngetset_common(mdrpc_getset_args * args,mdrpc_mngetset_res * res,struct svc_req * rqstp)28897c478bd9Sstevel@tonic-gate mdrpc_mngetset_common(
28907c478bd9Sstevel@tonic-gate mdrpc_getset_args *args,
28917c478bd9Sstevel@tonic-gate mdrpc_mngetset_res *res,
28927c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
28937c478bd9Sstevel@tonic-gate )
28947c478bd9Sstevel@tonic-gate {
28957c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
28967c478bd9Sstevel@tonic-gate int err;
28977c478bd9Sstevel@tonic-gate int op_mode = R_OK;
28987c478bd9Sstevel@tonic-gate md_set_record *sr = NULL;
28997c478bd9Sstevel@tonic-gate md_mnset_record *mnsr = NULL;
29007c478bd9Sstevel@tonic-gate
29017c478bd9Sstevel@tonic-gate /* setup, check permissions */
29027c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
29037c478bd9Sstevel@tonic-gate return (FALSE);
29047c478bd9Sstevel@tonic-gate else if (err != 0)
29057c478bd9Sstevel@tonic-gate return (TRUE);
29067c478bd9Sstevel@tonic-gate
29077c478bd9Sstevel@tonic-gate /* Don't have a setno, so we don't check the lock */
29087c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
29097c478bd9Sstevel@tonic-gate return (TRUE);
29107c478bd9Sstevel@tonic-gate
29117c478bd9Sstevel@tonic-gate /* doit */
29127c478bd9Sstevel@tonic-gate res->mnsr = NULL;
29137c478bd9Sstevel@tonic-gate if (args->setname && *args->setname)
29147c478bd9Sstevel@tonic-gate sr = getsetbyname(args->setname, ep);
29157c478bd9Sstevel@tonic-gate else if (args->setno > 0)
29167c478bd9Sstevel@tonic-gate sr = getsetbynum(args->setno, ep);
29177c478bd9Sstevel@tonic-gate
29187c478bd9Sstevel@tonic-gate if ((sr) && (MD_MNSET_REC(sr))) {
29197c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
29207c478bd9Sstevel@tonic-gate res->mnsr = mnsetdup(mnsr);
29217c478bd9Sstevel@tonic-gate }
29227c478bd9Sstevel@tonic-gate
29237c478bd9Sstevel@tonic-gate err = svc_fini(ep);
29247c478bd9Sstevel@tonic-gate
29257c478bd9Sstevel@tonic-gate return (TRUE);
29267c478bd9Sstevel@tonic-gate }
29277c478bd9Sstevel@tonic-gate
29287c478bd9Sstevel@tonic-gate bool_t
mdrpc_mngetset_2_svc(mdrpc_getset_2_args * args,mdrpc_mngetset_res * res,struct svc_req * rqstp)29297c478bd9Sstevel@tonic-gate mdrpc_mngetset_2_svc(
29307c478bd9Sstevel@tonic-gate mdrpc_getset_2_args *args,
29317c478bd9Sstevel@tonic-gate mdrpc_mngetset_res *res,
29327c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
29337c478bd9Sstevel@tonic-gate )
29347c478bd9Sstevel@tonic-gate {
29352a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
29367c478bd9Sstevel@tonic-gate switch (args->rev) {
29377c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
29387c478bd9Sstevel@tonic-gate return (mdrpc_mngetset_common(
29397c478bd9Sstevel@tonic-gate &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
29407c478bd9Sstevel@tonic-gate default:
29417c478bd9Sstevel@tonic-gate return (FALSE);
29427c478bd9Sstevel@tonic-gate }
29437c478bd9Sstevel@tonic-gate }
29447c478bd9Sstevel@tonic-gate
29457c478bd9Sstevel@tonic-gate static void
upd_setmaster(mdsetname_t * sp,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)29467c478bd9Sstevel@tonic-gate upd_setmaster(
29477c478bd9Sstevel@tonic-gate mdsetname_t *sp,
29487c478bd9Sstevel@tonic-gate md_node_nm_t master_nodenm,
29497c478bd9Sstevel@tonic-gate int master_nodeid,
29507c478bd9Sstevel@tonic-gate md_error_t *ep
29517c478bd9Sstevel@tonic-gate )
29527c478bd9Sstevel@tonic-gate {
29537c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
29547c478bd9Sstevel@tonic-gate md_set_record *sr;
29557c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
29567c478bd9Sstevel@tonic-gate mddb_setmaster_config_t sm;
29577c478bd9Sstevel@tonic-gate
29587c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
29597c478bd9Sstevel@tonic-gate return;
29607c478bd9Sstevel@tonic-gate
29617c478bd9Sstevel@tonic-gate metaflushsetname(local_sp);
29627c478bd9Sstevel@tonic-gate
29637c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
29647c478bd9Sstevel@tonic-gate return;
29657c478bd9Sstevel@tonic-gate
29667c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
29677c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
2968*80148899SSurya Prakki (void) strlcpy(mnsr->sr_master_nodenm, master_nodenm,
29697c478bd9Sstevel@tonic-gate MD_MAX_NODENAME);
29707c478bd9Sstevel@tonic-gate mnsr->sr_master_nodeid = master_nodeid;
29717c478bd9Sstevel@tonic-gate if (master_nodeid != 0) {
29727c478bd9Sstevel@tonic-gate (void) memset(&sm, 0, sizeof (sm));
29737c478bd9Sstevel@tonic-gate sm.c_setno = sp->setno;
29747c478bd9Sstevel@tonic-gate /* Use magic to help protect ioctl against attack. */
29757c478bd9Sstevel@tonic-gate sm.c_magic = MDDB_SETMASTER_MAGIC;
29767c478bd9Sstevel@tonic-gate if (strcmp(master_nodenm, mynode()) == 0) {
29777c478bd9Sstevel@tonic-gate sm.c_current_host_master = 1;
29787c478bd9Sstevel@tonic-gate } else {
29797c478bd9Sstevel@tonic-gate sm.c_current_host_master = 0;
29807c478bd9Sstevel@tonic-gate }
29817c478bd9Sstevel@tonic-gate (void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL);
29827c478bd9Sstevel@tonic-gate mdclrerror(&sm.c_mde);
29837c478bd9Sstevel@tonic-gate }
29847c478bd9Sstevel@tonic-gate }
29857c478bd9Sstevel@tonic-gate
29867c478bd9Sstevel@tonic-gate out:
29877c478bd9Sstevel@tonic-gate commitset(sr, FALSE, ep);
29887c478bd9Sstevel@tonic-gate free_sr(sr);
29897c478bd9Sstevel@tonic-gate }
29907c478bd9Sstevel@tonic-gate
29917c478bd9Sstevel@tonic-gate /*
29927c478bd9Sstevel@tonic-gate * set the master and nodeid in node record
29937c478bd9Sstevel@tonic-gate */
29947c478bd9Sstevel@tonic-gate bool_t
mdrpc_mnsetmaster_common(mdrpc_mnsetmaster_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)29957c478bd9Sstevel@tonic-gate mdrpc_mnsetmaster_common(
29967c478bd9Sstevel@tonic-gate mdrpc_mnsetmaster_args *args,
29977c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
29987c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
29997c478bd9Sstevel@tonic-gate )
30007c478bd9Sstevel@tonic-gate {
30017c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
30027c478bd9Sstevel@tonic-gate int err;
30037c478bd9Sstevel@tonic-gate int op_mode = W_OK;
30047c478bd9Sstevel@tonic-gate
30057c478bd9Sstevel@tonic-gate /* setup, check permissions */
30067c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
30077c478bd9Sstevel@tonic-gate return (FALSE);
30087c478bd9Sstevel@tonic-gate else if (err != 0)
30097c478bd9Sstevel@tonic-gate return (TRUE);
30107c478bd9Sstevel@tonic-gate
30117c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
30127c478bd9Sstevel@tonic-gate return (TRUE);
30137c478bd9Sstevel@tonic-gate
30147c478bd9Sstevel@tonic-gate /* doit */
30157c478bd9Sstevel@tonic-gate upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep);
30167c478bd9Sstevel@tonic-gate
30177c478bd9Sstevel@tonic-gate err = svc_fini(ep);
30187c478bd9Sstevel@tonic-gate
30197c478bd9Sstevel@tonic-gate return (TRUE);
30207c478bd9Sstevel@tonic-gate }
30217c478bd9Sstevel@tonic-gate
30227c478bd9Sstevel@tonic-gate bool_t
mdrpc_mnsetmaster_2_svc(mdrpc_mnsetmaster_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)30237c478bd9Sstevel@tonic-gate mdrpc_mnsetmaster_2_svc(
30247c478bd9Sstevel@tonic-gate mdrpc_mnsetmaster_2_args *args,
30257c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
30267c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
30277c478bd9Sstevel@tonic-gate )
30287c478bd9Sstevel@tonic-gate {
30292a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
30307c478bd9Sstevel@tonic-gate switch (args->rev) {
30317c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
30327c478bd9Sstevel@tonic-gate return (mdrpc_mnsetmaster_common(
30337c478bd9Sstevel@tonic-gate &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp));
30347c478bd9Sstevel@tonic-gate default:
30357c478bd9Sstevel@tonic-gate return (FALSE);
30367c478bd9Sstevel@tonic-gate }
30377c478bd9Sstevel@tonic-gate }
30387c478bd9Sstevel@tonic-gate
30397c478bd9Sstevel@tonic-gate /*
30407c478bd9Sstevel@tonic-gate * Join this node to the diskset.
30417c478bd9Sstevel@tonic-gate * Pass stale_flag information to snarf_set so that snarf code
30427c478bd9Sstevel@tonic-gate * can choose a STALE or non-STALE state when starting the set.
30437c478bd9Sstevel@tonic-gate * If master is STALE, any joining node will join a stale set regardless
30447c478bd9Sstevel@tonic-gate * of the number of accessible mddbs. Also, if master is at 50%
30457c478bd9Sstevel@tonic-gate * accessible replicas and is in the TOOFEW state, don't mark newly
30467c478bd9Sstevel@tonic-gate * joining node as STALE; mark it TOOFEW instead.
30477c478bd9Sstevel@tonic-gate */
30487c478bd9Sstevel@tonic-gate static void
joinset(mdsetname_t * sp,int flags,md_error_t * ep)30497c478bd9Sstevel@tonic-gate joinset(
30507c478bd9Sstevel@tonic-gate mdsetname_t *sp,
30517c478bd9Sstevel@tonic-gate int flags,
30527c478bd9Sstevel@tonic-gate md_error_t *ep
30537c478bd9Sstevel@tonic-gate )
30547c478bd9Sstevel@tonic-gate {
30557c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
30567c478bd9Sstevel@tonic-gate md_drive_desc *mydd;
30577c478bd9Sstevel@tonic-gate bool_t stale_bool;
30587c478bd9Sstevel@tonic-gate mddb_block_parm_t mbp;
30597c478bd9Sstevel@tonic-gate md_error_t xep = mdnullerror;
30607c478bd9Sstevel@tonic-gate
30617c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
30627c478bd9Sstevel@tonic-gate return;
30637c478bd9Sstevel@tonic-gate
30647c478bd9Sstevel@tonic-gate /*
30657c478bd9Sstevel@tonic-gate * Start mddoors daemon here.
30667c478bd9Sstevel@tonic-gate * mddoors itself takes care there will be
30677c478bd9Sstevel@tonic-gate * only one instance running, so starting it twice won't hurt
30687c478bd9Sstevel@tonic-gate */
3069*80148899SSurya Prakki (void) pclose(popen(MDDOORS, "w"));
30707c478bd9Sstevel@tonic-gate
30717c478bd9Sstevel@tonic-gate /*
30727c478bd9Sstevel@tonic-gate * Get latest copy of data. If a drive was just added causing
30737c478bd9Sstevel@tonic-gate * nodes to get joined - this drive won't be in the local
30747c478bd9Sstevel@tonic-gate * name caches drive list yet.
30757c478bd9Sstevel@tonic-gate */
30767c478bd9Sstevel@tonic-gate metaflushsetname(local_sp);
30777c478bd9Sstevel@tonic-gate
30787c478bd9Sstevel@tonic-gate mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
30797c478bd9Sstevel@tonic-gate if (mydd) {
3080b45175a7Sskamm /*
3081b45175a7Sskamm * Causes mddbs to be loaded into the kernel.
3082b45175a7Sskamm * Set the force flag so that replica locations can be loaded
3083b45175a7Sskamm * into the kernel even if a mediator node was unavailable.
3084b45175a7Sskamm * This allows a node to join an MO diskset when there are
3085b45175a7Sskamm * sufficient replicas available, but a mediator node
3086b45175a7Sskamm * in unavailable.
3087b45175a7Sskamm */
3088b45175a7Sskamm if (setup_db_bydd(local_sp, mydd, TRUE, ep) == -1) {
30897c478bd9Sstevel@tonic-gate /* If ep isn't set for some reason, set it */
3090b45175a7Sskamm if (mdisok(ep)) {
3091b6c8bd52Sjeanm (void) mdmddberror(ep, MDE_DB_NOTNOW,
3092b6c8bd52Sjeanm (minor_t)NODEV64, sp->setno, 0, NULL);
30937c478bd9Sstevel@tonic-gate }
30947c478bd9Sstevel@tonic-gate return;
30957c478bd9Sstevel@tonic-gate }
30967c478bd9Sstevel@tonic-gate
30977c478bd9Sstevel@tonic-gate if (flags & MNSET_IS_STALE)
30987c478bd9Sstevel@tonic-gate stale_bool = TRUE;
30997c478bd9Sstevel@tonic-gate else
31007c478bd9Sstevel@tonic-gate stale_bool = FALSE;
31017c478bd9Sstevel@tonic-gate
31027c478bd9Sstevel@tonic-gate /*
31037c478bd9Sstevel@tonic-gate * Snarf the set. No failure has occurred if STALE or
31047c478bd9Sstevel@tonic-gate * ACCOK error was set. Otherwise, fail the call setting
31057c478bd9Sstevel@tonic-gate * a generic error if no error was already set.
31067c478bd9Sstevel@tonic-gate *
31077c478bd9Sstevel@tonic-gate * STALE means that set has < 50% mddbs.
31087c478bd9Sstevel@tonic-gate * ACCOK means that the mediator provided an extra vote.
31097c478bd9Sstevel@tonic-gate */
31107c478bd9Sstevel@tonic-gate if (snarf_set(local_sp, stale_bool, ep) != 0) {
31117c478bd9Sstevel@tonic-gate if (!(mdismddberror(ep, MDE_DB_STALE)) &&
31127c478bd9Sstevel@tonic-gate !(mdismddberror(ep, MDE_DB_ACCOK))) {
31137c478bd9Sstevel@tonic-gate return;
31147c478bd9Sstevel@tonic-gate } else if (mdisok(ep)) {
31157c478bd9Sstevel@tonic-gate /* If snarf failed, but no error set - set it */
3116b6c8bd52Sjeanm (void) mdmddberror(ep, MDE_DB_NOTNOW,
3117b6c8bd52Sjeanm (minor_t)NODEV64, sp->setno, 0, NULL);
31187c478bd9Sstevel@tonic-gate return;
31197c478bd9Sstevel@tonic-gate }
31207c478bd9Sstevel@tonic-gate }
31217c478bd9Sstevel@tonic-gate
31227c478bd9Sstevel@tonic-gate /*
31237c478bd9Sstevel@tonic-gate * If node is joining during reconfig cycle, then
31247c478bd9Sstevel@tonic-gate * set mddb_parse to be in blocked state so that
31257c478bd9Sstevel@tonic-gate * mddb reparse messages are not generated until
31267c478bd9Sstevel@tonic-gate * the commd has been resumed later in the reconfig
31277c478bd9Sstevel@tonic-gate * cycle.
31287c478bd9Sstevel@tonic-gate */
31297c478bd9Sstevel@tonic-gate if (flags & MNSET_IN_RECONFIG) {
31307c478bd9Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp));
31317c478bd9Sstevel@tonic-gate if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) {
31327c478bd9Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp));
31337c478bd9Sstevel@tonic-gate mbp.c_setno = local_sp->setno;
31347c478bd9Sstevel@tonic-gate mbp.c_blk_flags = MDDB_BLOCK_PARSE;
31357c478bd9Sstevel@tonic-gate if (metaioctl(MD_MN_MDDB_BLOCK, &mbp,
31367c478bd9Sstevel@tonic-gate &mbp.c_mde, NULL)) {
3137*80148899SSurya Prakki (void) mdstealerror(&xep, &mbp.c_mde);
31387c478bd9Sstevel@tonic-gate mde_perror(ep, gettext(
31397c478bd9Sstevel@tonic-gate "Could not block set %s"),
31407c478bd9Sstevel@tonic-gate sp->setname);
31417c478bd9Sstevel@tonic-gate return;
31427c478bd9Sstevel@tonic-gate }
31437c478bd9Sstevel@tonic-gate }
31447c478bd9Sstevel@tonic-gate /*
31457c478bd9Sstevel@tonic-gate * If s_ownset fails and snarf_set succeeded,
31467c478bd9Sstevel@tonic-gate * then can steal the ownset failure information
31477c478bd9Sstevel@tonic-gate * and store it into ep. If snarf_set failed,
31487c478bd9Sstevel@tonic-gate * don't overwrite critical ep information even
31497c478bd9Sstevel@tonic-gate * if s_ownset failed.
31507c478bd9Sstevel@tonic-gate */
31517c478bd9Sstevel@tonic-gate if (!mdisok(&xep)) {
31527c478bd9Sstevel@tonic-gate /*
31537c478bd9Sstevel@tonic-gate * If snarf_set succeeded or snarf_set failed
31547c478bd9Sstevel@tonic-gate * with MDE_DB_ACCOK (which is set if the
31557c478bd9Sstevel@tonic-gate * mediator provided the extra vote) then
31567c478bd9Sstevel@tonic-gate * steal the xep failure information and put
31577c478bd9Sstevel@tonic-gate * into ep.
31587c478bd9Sstevel@tonic-gate */
31597c478bd9Sstevel@tonic-gate if (mdisok(ep) ||
31607c478bd9Sstevel@tonic-gate mdismddberror(ep, MDE_DB_ACCOK)) {
3161*80148899SSurya Prakki (void) mdstealerror(ep, &xep);
31627c478bd9Sstevel@tonic-gate }
31637c478bd9Sstevel@tonic-gate }
31647c478bd9Sstevel@tonic-gate }
31657c478bd9Sstevel@tonic-gate }
31667c478bd9Sstevel@tonic-gate }
31677c478bd9Sstevel@tonic-gate
31687c478bd9Sstevel@tonic-gate /*
31697c478bd9Sstevel@tonic-gate * Have this node join the set.
31707c478bd9Sstevel@tonic-gate * This is called when a node has been
31717c478bd9Sstevel@tonic-gate * added to a MN diskset that has drives.
31727c478bd9Sstevel@tonic-gate * Also, called when a node is an alive
31737c478bd9Sstevel@tonic-gate * member of a MN diskset and the first
31747c478bd9Sstevel@tonic-gate * drive has been added.
31757c478bd9Sstevel@tonic-gate */
31767c478bd9Sstevel@tonic-gate bool_t
mdrpc_joinset_common(mdrpc_sp_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)31777c478bd9Sstevel@tonic-gate mdrpc_joinset_common(
31787c478bd9Sstevel@tonic-gate mdrpc_sp_flags_args *args,
31797c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
31807c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
31817c478bd9Sstevel@tonic-gate )
31827c478bd9Sstevel@tonic-gate {
31837c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
31847c478bd9Sstevel@tonic-gate int err;
31857c478bd9Sstevel@tonic-gate int op_mode = W_OK;
31867c478bd9Sstevel@tonic-gate
31877c478bd9Sstevel@tonic-gate /* setup, check permissions */
31887c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
31897c478bd9Sstevel@tonic-gate return (FALSE);
31907c478bd9Sstevel@tonic-gate else if (err != 0)
31917c478bd9Sstevel@tonic-gate return (TRUE);
31927c478bd9Sstevel@tonic-gate
31937c478bd9Sstevel@tonic-gate /*
31947c478bd9Sstevel@tonic-gate * During reconfig, joinset can happen without
31957c478bd9Sstevel@tonic-gate * locking first. Turn off reconfig flag before calling
31967c478bd9Sstevel@tonic-gate * joinset.
31977c478bd9Sstevel@tonic-gate */
31987c478bd9Sstevel@tonic-gate if (!(args->flags & MNSET_IN_RECONFIG)) {
31997c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
32007c478bd9Sstevel@tonic-gate return (TRUE);
32017c478bd9Sstevel@tonic-gate }
32027c478bd9Sstevel@tonic-gate
32037c478bd9Sstevel@tonic-gate /* doit */
32047c478bd9Sstevel@tonic-gate joinset(args->sp, args->flags, ep);
32057c478bd9Sstevel@tonic-gate
32067c478bd9Sstevel@tonic-gate err = svc_fini(ep);
32077c478bd9Sstevel@tonic-gate
32087c478bd9Sstevel@tonic-gate return (TRUE);
32097c478bd9Sstevel@tonic-gate }
32107c478bd9Sstevel@tonic-gate
32117c478bd9Sstevel@tonic-gate bool_t
mdrpc_joinset_2_svc(mdrpc_sp_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32127c478bd9Sstevel@tonic-gate mdrpc_joinset_2_svc(
32137c478bd9Sstevel@tonic-gate mdrpc_sp_flags_2_args *args,
32147c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
32157c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
32167c478bd9Sstevel@tonic-gate )
32177c478bd9Sstevel@tonic-gate {
32182a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
32197c478bd9Sstevel@tonic-gate switch (args->rev) {
32207c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
32217c478bd9Sstevel@tonic-gate return (mdrpc_joinset_common(
32227c478bd9Sstevel@tonic-gate &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp));
32237c478bd9Sstevel@tonic-gate default:
32247c478bd9Sstevel@tonic-gate return (FALSE);
32257c478bd9Sstevel@tonic-gate }
32267c478bd9Sstevel@tonic-gate }
32277c478bd9Sstevel@tonic-gate
32287c478bd9Sstevel@tonic-gate static void
withdrawset(mdsetname_t * sp,md_error_t * ep)32297c478bd9Sstevel@tonic-gate withdrawset(
32307c478bd9Sstevel@tonic-gate mdsetname_t *sp,
32317c478bd9Sstevel@tonic-gate md_error_t *ep
32327c478bd9Sstevel@tonic-gate )
32337c478bd9Sstevel@tonic-gate {
32347c478bd9Sstevel@tonic-gate mdsetname_t *my_sp;
32357c478bd9Sstevel@tonic-gate
32367c478bd9Sstevel@tonic-gate if ((my_sp = metasetname(sp->setname, ep)) == NULL)
32377c478bd9Sstevel@tonic-gate return;
32387c478bd9Sstevel@tonic-gate
32397c478bd9Sstevel@tonic-gate (void) halt_set(my_sp, ep);
32407c478bd9Sstevel@tonic-gate }
32417c478bd9Sstevel@tonic-gate
32427c478bd9Sstevel@tonic-gate /*
32437c478bd9Sstevel@tonic-gate * Have this node withdraw from set.
32447c478bd9Sstevel@tonic-gate * In response to a failure that occurred
32457c478bd9Sstevel@tonic-gate * on the client after a joinset.
32467c478bd9Sstevel@tonic-gate */
32477c478bd9Sstevel@tonic-gate bool_t
mdrpc_withdrawset_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32487c478bd9Sstevel@tonic-gate mdrpc_withdrawset_common(
32497c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
32507c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
32517c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
32527c478bd9Sstevel@tonic-gate )
32537c478bd9Sstevel@tonic-gate {
32547c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
32557c478bd9Sstevel@tonic-gate int err;
32567c478bd9Sstevel@tonic-gate int op_mode = W_OK;
32577c478bd9Sstevel@tonic-gate
32587c478bd9Sstevel@tonic-gate /* setup, check permissions */
32597c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
32607c478bd9Sstevel@tonic-gate return (FALSE);
32617c478bd9Sstevel@tonic-gate else if (err != 0)
32627c478bd9Sstevel@tonic-gate return (TRUE);
32637c478bd9Sstevel@tonic-gate
32647c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
32657c478bd9Sstevel@tonic-gate return (TRUE);
32667c478bd9Sstevel@tonic-gate
32677c478bd9Sstevel@tonic-gate /* doit */
32687c478bd9Sstevel@tonic-gate withdrawset(args->sp, ep);
32697c478bd9Sstevel@tonic-gate
32707c478bd9Sstevel@tonic-gate err = svc_fini(ep);
32717c478bd9Sstevel@tonic-gate
32727c478bd9Sstevel@tonic-gate return (TRUE);
32737c478bd9Sstevel@tonic-gate }
32747c478bd9Sstevel@tonic-gate
32757c478bd9Sstevel@tonic-gate bool_t
mdrpc_withdrawset_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32767c478bd9Sstevel@tonic-gate mdrpc_withdrawset_2_svc(
32777c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args,
32787c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
32797c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
32807c478bd9Sstevel@tonic-gate )
32817c478bd9Sstevel@tonic-gate {
32822a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
32837c478bd9Sstevel@tonic-gate switch (args->rev) {
32847c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
32857c478bd9Sstevel@tonic-gate return (mdrpc_withdrawset_common(
32867c478bd9Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
32877c478bd9Sstevel@tonic-gate default:
32887c478bd9Sstevel@tonic-gate return (FALSE);
32897c478bd9Sstevel@tonic-gate }
32907c478bd9Sstevel@tonic-gate }
32917c478bd9Sstevel@tonic-gate
32927c478bd9Sstevel@tonic-gate static mhd_mhiargs_t *
gtimeout(mdsetname_t * sp,md_error_t * ep)32937c478bd9Sstevel@tonic-gate gtimeout(mdsetname_t *sp, md_error_t *ep)
32947c478bd9Sstevel@tonic-gate {
32957c478bd9Sstevel@tonic-gate md_set_record *sr;
32967c478bd9Sstevel@tonic-gate mhd_mhiargs_t *mhiargs;
32977c478bd9Sstevel@tonic-gate
32987c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
32997c478bd9Sstevel@tonic-gate return (NULL);
33007c478bd9Sstevel@tonic-gate
33017c478bd9Sstevel@tonic-gate mhiargs = Zalloc(sizeof (*mhiargs));
33027c478bd9Sstevel@tonic-gate *mhiargs = sr->sr_mhiargs;
33037c478bd9Sstevel@tonic-gate
33047c478bd9Sstevel@tonic-gate free_sr(sr);
33057c478bd9Sstevel@tonic-gate return (mhiargs);
33067c478bd9Sstevel@tonic-gate }
33077c478bd9Sstevel@tonic-gate
33087c478bd9Sstevel@tonic-gate /*
33097c478bd9Sstevel@tonic-gate * Get the MH timeout values for this set.
33107c478bd9Sstevel@tonic-gate */
33117c478bd9Sstevel@tonic-gate bool_t
mdrpc_gtimeout_common(mdrpc_sp_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33127c478bd9Sstevel@tonic-gate mdrpc_gtimeout_common(
33137c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
33147c478bd9Sstevel@tonic-gate mdrpc_gtimeout_res *res,
33157c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33167c478bd9Sstevel@tonic-gate )
33177c478bd9Sstevel@tonic-gate {
33187c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
33197c478bd9Sstevel@tonic-gate int err;
33207c478bd9Sstevel@tonic-gate int op_mode = R_OK;
33217c478bd9Sstevel@tonic-gate
33227c478bd9Sstevel@tonic-gate /* setup, check permissions */
33237c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
33247c478bd9Sstevel@tonic-gate return (FALSE);
33257c478bd9Sstevel@tonic-gate else if (err != 0)
33267c478bd9Sstevel@tonic-gate return (TRUE);
33277c478bd9Sstevel@tonic-gate
33287c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
33297c478bd9Sstevel@tonic-gate return (TRUE);
33307c478bd9Sstevel@tonic-gate
33317c478bd9Sstevel@tonic-gate /* doit */
33327c478bd9Sstevel@tonic-gate res->mhiargsp = gtimeout(args->sp, ep);
33337c478bd9Sstevel@tonic-gate
33347c478bd9Sstevel@tonic-gate err = svc_fini(ep);
33357c478bd9Sstevel@tonic-gate
33367c478bd9Sstevel@tonic-gate return (TRUE);
33377c478bd9Sstevel@tonic-gate }
33387c478bd9Sstevel@tonic-gate
33397c478bd9Sstevel@tonic-gate bool_t
mdrpc_gtimeout_1_svc(mdrpc_sp_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33407c478bd9Sstevel@tonic-gate mdrpc_gtimeout_1_svc(
33417c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
33427c478bd9Sstevel@tonic-gate mdrpc_gtimeout_res *res,
33437c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33447c478bd9Sstevel@tonic-gate )
33457c478bd9Sstevel@tonic-gate {
33462a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
33477c478bd9Sstevel@tonic-gate return (mdrpc_gtimeout_common(args, res, rqstp));
33487c478bd9Sstevel@tonic-gate }
33497c478bd9Sstevel@tonic-gate
33507c478bd9Sstevel@tonic-gate bool_t
mdrpc_gtimeout_2_svc(mdrpc_sp_2_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33517c478bd9Sstevel@tonic-gate mdrpc_gtimeout_2_svc(
33527c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args,
33537c478bd9Sstevel@tonic-gate mdrpc_gtimeout_res *res,
33547c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33557c478bd9Sstevel@tonic-gate )
33567c478bd9Sstevel@tonic-gate {
33572a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
33587c478bd9Sstevel@tonic-gate switch (args->rev) {
33597c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
33607c478bd9Sstevel@tonic-gate return (mdrpc_gtimeout_common(
33617c478bd9Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
33627c478bd9Sstevel@tonic-gate default:
33637c478bd9Sstevel@tonic-gate return (FALSE);
33647c478bd9Sstevel@tonic-gate }
33657c478bd9Sstevel@tonic-gate }
33667c478bd9Sstevel@tonic-gate
33677c478bd9Sstevel@tonic-gate /*
33687c478bd9Sstevel@tonic-gate * return the official host name for the callee
33697c478bd9Sstevel@tonic-gate */
33707c478bd9Sstevel@tonic-gate /*ARGSUSED*/
33717c478bd9Sstevel@tonic-gate bool_t
mdrpc_hostname_common(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)33727c478bd9Sstevel@tonic-gate mdrpc_hostname_common(
33737c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
33747c478bd9Sstevel@tonic-gate mdrpc_hostname_res *res,
33757c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
33767c478bd9Sstevel@tonic-gate )
33777c478bd9Sstevel@tonic-gate {
33787c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
33797c478bd9Sstevel@tonic-gate int err;
33807c478bd9Sstevel@tonic-gate int op_mode = R_OK;
33817c478bd9Sstevel@tonic-gate
33827c478bd9Sstevel@tonic-gate /* setup, check permissions */
33837c478bd9Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
33847c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
33857c478bd9Sstevel@tonic-gate return (FALSE);
33867c478bd9Sstevel@tonic-gate else if (err != 0)
33877c478bd9Sstevel@tonic-gate return (TRUE);
33887c478bd9Sstevel@tonic-gate
33897c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
33907c478bd9Sstevel@tonic-gate return (TRUE);
33917c478bd9Sstevel@tonic-gate
33927c478bd9Sstevel@tonic-gate /* doit */
33937c478bd9Sstevel@tonic-gate res->hostname = Strdup(mynode());
33947c478bd9Sstevel@tonic-gate
33957c478bd9Sstevel@tonic-gate err = svc_fini(ep);
33967c478bd9Sstevel@tonic-gate
33977c478bd9Sstevel@tonic-gate return (TRUE);
33987c478bd9Sstevel@tonic-gate }
33997c478bd9Sstevel@tonic-gate
34007c478bd9Sstevel@tonic-gate bool_t
mdrpc_hostname_1_svc(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)34017c478bd9Sstevel@tonic-gate mdrpc_hostname_1_svc(
34027c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
34037c478bd9Sstevel@tonic-gate mdrpc_hostname_res *res,
34047c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34057c478bd9Sstevel@tonic-gate )
34067c478bd9Sstevel@tonic-gate {
34077c478bd9Sstevel@tonic-gate return (mdrpc_hostname_common(args, res, rqstp));
34087c478bd9Sstevel@tonic-gate }
34097c478bd9Sstevel@tonic-gate
34107c478bd9Sstevel@tonic-gate bool_t
mdrpc_hostname_2_svc(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)34117c478bd9Sstevel@tonic-gate mdrpc_hostname_2_svc(
34127c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
34137c478bd9Sstevel@tonic-gate mdrpc_hostname_res *res,
34147c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34157c478bd9Sstevel@tonic-gate )
34167c478bd9Sstevel@tonic-gate {
34177c478bd9Sstevel@tonic-gate return (mdrpc_hostname_common(args, res, rqstp));
34187c478bd9Sstevel@tonic-gate }
34197c478bd9Sstevel@tonic-gate
34207c478bd9Sstevel@tonic-gate /*
34217c478bd9Sstevel@tonic-gate * return a response
34227c478bd9Sstevel@tonic-gate */
34237c478bd9Sstevel@tonic-gate /*ARGSUSED*/
34247c478bd9Sstevel@tonic-gate bool_t
mdrpc_nullproc_common(void * args,md_error_t * ep,struct svc_req * rqstp)34257c478bd9Sstevel@tonic-gate mdrpc_nullproc_common(
34267c478bd9Sstevel@tonic-gate void *args,
34277c478bd9Sstevel@tonic-gate md_error_t *ep,
34287c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34297c478bd9Sstevel@tonic-gate )
34307c478bd9Sstevel@tonic-gate {
34317c478bd9Sstevel@tonic-gate *ep = mdnullerror;
34327c478bd9Sstevel@tonic-gate /* do nothing */
34337c478bd9Sstevel@tonic-gate return (TRUE);
34347c478bd9Sstevel@tonic-gate }
34357c478bd9Sstevel@tonic-gate
34367c478bd9Sstevel@tonic-gate bool_t
mdrpc_nullproc_1_svc(void * args,md_error_t * ep,struct svc_req * rqstp)34377c478bd9Sstevel@tonic-gate mdrpc_nullproc_1_svc(
34387c478bd9Sstevel@tonic-gate void *args,
34397c478bd9Sstevel@tonic-gate md_error_t *ep,
34407c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34417c478bd9Sstevel@tonic-gate )
34427c478bd9Sstevel@tonic-gate {
34437c478bd9Sstevel@tonic-gate return (mdrpc_nullproc_common(args, ep, rqstp));
34447c478bd9Sstevel@tonic-gate }
34457c478bd9Sstevel@tonic-gate
34467c478bd9Sstevel@tonic-gate bool_t
mdrpc_nullproc_2_svc(void * args,md_error_t * ep,struct svc_req * rqstp)34477c478bd9Sstevel@tonic-gate mdrpc_nullproc_2_svc(
34487c478bd9Sstevel@tonic-gate void *args,
34497c478bd9Sstevel@tonic-gate md_error_t *ep,
34507c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34517c478bd9Sstevel@tonic-gate )
34527c478bd9Sstevel@tonic-gate {
34537c478bd9Sstevel@tonic-gate return (mdrpc_nullproc_common(args, ep, rqstp));
34547c478bd9Sstevel@tonic-gate }
34557c478bd9Sstevel@tonic-gate
34567c478bd9Sstevel@tonic-gate /*
34577c478bd9Sstevel@tonic-gate * determine if the caller owns the set.
34587c478bd9Sstevel@tonic-gate */
34597c478bd9Sstevel@tonic-gate bool_t
mdrpc_ownset_common(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)34607c478bd9Sstevel@tonic-gate mdrpc_ownset_common(
34617c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
34627c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
34637c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34647c478bd9Sstevel@tonic-gate )
34657c478bd9Sstevel@tonic-gate {
34667c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
34677c478bd9Sstevel@tonic-gate int err;
34687c478bd9Sstevel@tonic-gate int op_mode = R_OK;
34697c478bd9Sstevel@tonic-gate
34707c478bd9Sstevel@tonic-gate /* setup, check permissions */
34717c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
34727c478bd9Sstevel@tonic-gate return (FALSE);
34737c478bd9Sstevel@tonic-gate else if (err != 0)
34747c478bd9Sstevel@tonic-gate return (TRUE);
34757c478bd9Sstevel@tonic-gate
34767c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
34777c478bd9Sstevel@tonic-gate return (TRUE);
34787c478bd9Sstevel@tonic-gate
34797c478bd9Sstevel@tonic-gate /* doit */
34807c478bd9Sstevel@tonic-gate if (s_ownset(args->sp->setno, ep))
34817c478bd9Sstevel@tonic-gate res->value = TRUE;
34827c478bd9Sstevel@tonic-gate else
34837c478bd9Sstevel@tonic-gate res->value = FALSE;
34847c478bd9Sstevel@tonic-gate
34857c478bd9Sstevel@tonic-gate err = svc_fini(ep);
34867c478bd9Sstevel@tonic-gate
34877c478bd9Sstevel@tonic-gate return (TRUE);
34887c478bd9Sstevel@tonic-gate }
34897c478bd9Sstevel@tonic-gate
34907c478bd9Sstevel@tonic-gate bool_t
mdrpc_ownset_1_svc(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)34917c478bd9Sstevel@tonic-gate mdrpc_ownset_1_svc(
34927c478bd9Sstevel@tonic-gate mdrpc_sp_args *args,
34937c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
34947c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
34957c478bd9Sstevel@tonic-gate )
34967c478bd9Sstevel@tonic-gate {
34972a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
34987c478bd9Sstevel@tonic-gate return (mdrpc_ownset_common(args, res, rqstp));
34997c478bd9Sstevel@tonic-gate }
35007c478bd9Sstevel@tonic-gate
35017c478bd9Sstevel@tonic-gate bool_t
mdrpc_ownset_2_svc(mdrpc_sp_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)35027c478bd9Sstevel@tonic-gate mdrpc_ownset_2_svc(
35037c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args,
35047c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
35057c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
35067c478bd9Sstevel@tonic-gate )
35077c478bd9Sstevel@tonic-gate {
35082a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
35097c478bd9Sstevel@tonic-gate switch (args->rev) {
35107c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
35117c478bd9Sstevel@tonic-gate return (mdrpc_ownset_common(
35127c478bd9Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
35137c478bd9Sstevel@tonic-gate default:
35147c478bd9Sstevel@tonic-gate return (FALSE);
35157c478bd9Sstevel@tonic-gate }
35167c478bd9Sstevel@tonic-gate }
35177c478bd9Sstevel@tonic-gate
35187c478bd9Sstevel@tonic-gate static int
setnameok(char * setname,md_error_t * ep)35197c478bd9Sstevel@tonic-gate setnameok(char *setname, md_error_t *ep)
35207c478bd9Sstevel@tonic-gate {
35217c478bd9Sstevel@tonic-gate int rval = 0;
35227c478bd9Sstevel@tonic-gate struct stat statb;
35237c478bd9Sstevel@tonic-gate md_set_record *sr = NULL;
35247c478bd9Sstevel@tonic-gate char *setlink = NULL;
35257c478bd9Sstevel@tonic-gate
35267c478bd9Sstevel@tonic-gate setlink = Strdup("/dev/md/");
35277c478bd9Sstevel@tonic-gate setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1);
35287c478bd9Sstevel@tonic-gate (void) strcat(setlink, setname);
35297c478bd9Sstevel@tonic-gate
35307c478bd9Sstevel@tonic-gate if (lstat(setlink, &statb) == -1) {
35317c478bd9Sstevel@tonic-gate /*
35327c478bd9Sstevel@tonic-gate * If lstat() fails with ENOENT, setname is OK, if it
35337c478bd9Sstevel@tonic-gate * fails for other than that, we fail the RPC
35347c478bd9Sstevel@tonic-gate */
35357c478bd9Sstevel@tonic-gate if (errno == ENOENT) {
35367c478bd9Sstevel@tonic-gate rval = 1;
35377c478bd9Sstevel@tonic-gate goto out;
35387c478bd9Sstevel@tonic-gate }
35397c478bd9Sstevel@tonic-gate
35407c478bd9Sstevel@tonic-gate (void) mdsyserror(ep, errno, setlink);
35417c478bd9Sstevel@tonic-gate goto out;
35427c478bd9Sstevel@tonic-gate }
35437c478bd9Sstevel@tonic-gate
35447c478bd9Sstevel@tonic-gate /*
35457c478bd9Sstevel@tonic-gate * If the lstat() succeeded, then we see what type of object
35467c478bd9Sstevel@tonic-gate * we are dealing with, if it is a symlink, we do some further
35477c478bd9Sstevel@tonic-gate * checking, if it is not a symlink, then we return an
35487c478bd9Sstevel@tonic-gate * indication that the set name is NOT acceptable.
35497c478bd9Sstevel@tonic-gate */
35507c478bd9Sstevel@tonic-gate if (! S_ISLNK(statb.st_mode))
35517c478bd9Sstevel@tonic-gate goto out;
35527c478bd9Sstevel@tonic-gate
35537c478bd9Sstevel@tonic-gate /*
35547c478bd9Sstevel@tonic-gate * We look up the setname to see if there is a set
35557c478bd9Sstevel@tonic-gate * with that name, if there is, then we return
35567c478bd9Sstevel@tonic-gate * an indication that the set name is NOT acceptable.
35577c478bd9Sstevel@tonic-gate */
35587c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) != NULL)
35597c478bd9Sstevel@tonic-gate goto out;
35607c478bd9Sstevel@tonic-gate
35617c478bd9Sstevel@tonic-gate if (! mdiserror(ep, MDE_NO_SET))
35627c478bd9Sstevel@tonic-gate goto out;
35637c478bd9Sstevel@tonic-gate
35647c478bd9Sstevel@tonic-gate mdclrerror(ep);
35657c478bd9Sstevel@tonic-gate
35667c478bd9Sstevel@tonic-gate rval = 1;
35677c478bd9Sstevel@tonic-gate out:
35687c478bd9Sstevel@tonic-gate if (sr != NULL)
35697c478bd9Sstevel@tonic-gate free_sr(sr);
35707c478bd9Sstevel@tonic-gate Free(setlink);
35717c478bd9Sstevel@tonic-gate return (rval);
35727c478bd9Sstevel@tonic-gate }
35737c478bd9Sstevel@tonic-gate
35747c478bd9Sstevel@tonic-gate /*
35757c478bd9Sstevel@tonic-gate * Make sure the name of the set is OK.
35767c478bd9Sstevel@tonic-gate */
35777c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnameok_common(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)35787c478bd9Sstevel@tonic-gate mdrpc_setnameok_common(
35797c478bd9Sstevel@tonic-gate mdrpc_sp_args *args, /* device name */
35807c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
35817c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
35827c478bd9Sstevel@tonic-gate )
35837c478bd9Sstevel@tonic-gate {
35847c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
35857c478bd9Sstevel@tonic-gate int err;
35867c478bd9Sstevel@tonic-gate int op_mode = R_OK;
35877c478bd9Sstevel@tonic-gate
35887c478bd9Sstevel@tonic-gate /* setup, check permissions */
35897c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
35907c478bd9Sstevel@tonic-gate return (FALSE);
35917c478bd9Sstevel@tonic-gate else if (err != 0)
35927c478bd9Sstevel@tonic-gate return (TRUE);
35937c478bd9Sstevel@tonic-gate
35947c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
35957c478bd9Sstevel@tonic-gate return (TRUE);
35967c478bd9Sstevel@tonic-gate
35977c478bd9Sstevel@tonic-gate /* doit */
35987c478bd9Sstevel@tonic-gate res->value = setnameok(args->sp->setname, ep);
35997c478bd9Sstevel@tonic-gate
36007c478bd9Sstevel@tonic-gate err = svc_fini(ep);
36017c478bd9Sstevel@tonic-gate
36027c478bd9Sstevel@tonic-gate return (TRUE);
36037c478bd9Sstevel@tonic-gate }
36047c478bd9Sstevel@tonic-gate
36057c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnameok_1_svc(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36067c478bd9Sstevel@tonic-gate mdrpc_setnameok_1_svc(
36077c478bd9Sstevel@tonic-gate mdrpc_sp_args *args, /* device name */
36087c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
36097c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36107c478bd9Sstevel@tonic-gate )
36117c478bd9Sstevel@tonic-gate {
36122a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
36137c478bd9Sstevel@tonic-gate return (mdrpc_setnameok_common(args, res, rqstp));
36147c478bd9Sstevel@tonic-gate }
36157c478bd9Sstevel@tonic-gate
36167c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnameok_2_svc(mdrpc_sp_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36177c478bd9Sstevel@tonic-gate mdrpc_setnameok_2_svc(
36187c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args, /* device name */
36197c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
36207c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36217c478bd9Sstevel@tonic-gate )
36227c478bd9Sstevel@tonic-gate {
36232a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
36247c478bd9Sstevel@tonic-gate switch (args->rev) {
36257c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
36267c478bd9Sstevel@tonic-gate return (mdrpc_setnameok_common(
36277c478bd9Sstevel@tonic-gate &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
36287c478bd9Sstevel@tonic-gate default:
36297c478bd9Sstevel@tonic-gate return (FALSE);
36307c478bd9Sstevel@tonic-gate }
36317c478bd9Sstevel@tonic-gate }
36327c478bd9Sstevel@tonic-gate
36337c478bd9Sstevel@tonic-gate /*
36347c478bd9Sstevel@tonic-gate * determine if the setnumber we want to share is in use.
36357c478bd9Sstevel@tonic-gate */
36367c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_common(mdrpc_setno_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36377c478bd9Sstevel@tonic-gate mdrpc_setnumbusy_common(
36387c478bd9Sstevel@tonic-gate mdrpc_setno_args *args,
36397c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
36407c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36417c478bd9Sstevel@tonic-gate )
36427c478bd9Sstevel@tonic-gate {
36437c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
36447c478bd9Sstevel@tonic-gate md_set_record *sr = NULL;
36457c478bd9Sstevel@tonic-gate int err;
36467c478bd9Sstevel@tonic-gate int op_mode = R_OK;
36477c478bd9Sstevel@tonic-gate
36487c478bd9Sstevel@tonic-gate /* setup, check permissions */
36497c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
36507c478bd9Sstevel@tonic-gate return (FALSE);
36517c478bd9Sstevel@tonic-gate else if (err != 0)
36527c478bd9Sstevel@tonic-gate return (TRUE);
36537c478bd9Sstevel@tonic-gate
36547c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
36557c478bd9Sstevel@tonic-gate return (TRUE);
36567c478bd9Sstevel@tonic-gate
36577c478bd9Sstevel@tonic-gate /* doit */
36587c478bd9Sstevel@tonic-gate if ((sr = getsetbynum(args->setno, ep)) != NULL) {
36597c478bd9Sstevel@tonic-gate res->value = TRUE;
36607c478bd9Sstevel@tonic-gate free_sr(sr);
36617c478bd9Sstevel@tonic-gate return (TRUE);
36627c478bd9Sstevel@tonic-gate }
36637c478bd9Sstevel@tonic-gate res->value = FALSE;
36647c478bd9Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET))
36657c478bd9Sstevel@tonic-gate mdclrerror(ep);
36667c478bd9Sstevel@tonic-gate
36677c478bd9Sstevel@tonic-gate err = svc_fini(ep);
36687c478bd9Sstevel@tonic-gate
36697c478bd9Sstevel@tonic-gate return (TRUE);
36707c478bd9Sstevel@tonic-gate }
36717c478bd9Sstevel@tonic-gate
36727c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_1_svc(mdrpc_setno_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36737c478bd9Sstevel@tonic-gate mdrpc_setnumbusy_1_svc(
36747c478bd9Sstevel@tonic-gate mdrpc_setno_args *args,
36757c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
36767c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36777c478bd9Sstevel@tonic-gate )
36787c478bd9Sstevel@tonic-gate {
36792a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
36807c478bd9Sstevel@tonic-gate return (mdrpc_setnumbusy_common(args, res, rqstp));
36817c478bd9Sstevel@tonic-gate }
36827c478bd9Sstevel@tonic-gate
36837c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_2_svc(mdrpc_setno_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36847c478bd9Sstevel@tonic-gate mdrpc_setnumbusy_2_svc(
36857c478bd9Sstevel@tonic-gate mdrpc_setno_2_args *args,
36867c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
36877c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
36887c478bd9Sstevel@tonic-gate )
36897c478bd9Sstevel@tonic-gate {
36902a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
36917c478bd9Sstevel@tonic-gate switch (args->rev) {
36927c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
36937c478bd9Sstevel@tonic-gate return (mdrpc_setnumbusy_common(
36947c478bd9Sstevel@tonic-gate &args->mdrpc_setno_2_args_u.rev1, res, rqstp));
36957c478bd9Sstevel@tonic-gate default:
36967c478bd9Sstevel@tonic-gate return (FALSE);
36977c478bd9Sstevel@tonic-gate }
36987c478bd9Sstevel@tonic-gate }
36997c478bd9Sstevel@tonic-gate
37007c478bd9Sstevel@tonic-gate static void
stimeout(mdsetname_t * sp,mhd_mhiargs_t * mhiargsp,int version,md_error_t * ep)37017c478bd9Sstevel@tonic-gate stimeout(
37027c478bd9Sstevel@tonic-gate mdsetname_t *sp,
37037c478bd9Sstevel@tonic-gate mhd_mhiargs_t *mhiargsp,
37047c478bd9Sstevel@tonic-gate int version, /* RPC version of calling routine */
37057c478bd9Sstevel@tonic-gate md_error_t *ep
37067c478bd9Sstevel@tonic-gate )
37077c478bd9Sstevel@tonic-gate {
37087c478bd9Sstevel@tonic-gate mddb_userreq_t req;
37097c478bd9Sstevel@tonic-gate md_set_record *sr;
37107c478bd9Sstevel@tonic-gate
37117c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
37127c478bd9Sstevel@tonic-gate return;
37137c478bd9Sstevel@tonic-gate
37147c478bd9Sstevel@tonic-gate sr->sr_mhiargs = *mhiargsp;
37157c478bd9Sstevel@tonic-gate
37167c478bd9Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
37177c478bd9Sstevel@tonic-gate
37187c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
37197c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
37207c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
37217c478bd9Sstevel@tonic-gate req.ur_size = sizeof (struct md_mnset_record);
37227c478bd9Sstevel@tonic-gate } else {
37237c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*sr);
37247c478bd9Sstevel@tonic-gate }
37257c478bd9Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
37267c478bd9Sstevel@tonic-gate
37277c478bd9Sstevel@tonic-gate /*
37287c478bd9Sstevel@tonic-gate * Cluster nodename support
37297c478bd9Sstevel@tonic-gate * Convert nodename -> nodeid
37307c478bd9Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
37317c478bd9Sstevel@tonic-gate * both the nodeid and name.
37327c478bd9Sstevel@tonic-gate */
37337c478bd9Sstevel@tonic-gate if ((version == METAD_VERSION) ||
37347c478bd9Sstevel@tonic-gate ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
37357c478bd9Sstevel@tonic-gate sdssc_cm_sr_nm2nid(sr);
37367c478bd9Sstevel@tonic-gate
37377c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
37387c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
37397c478bd9Sstevel@tonic-gate return;
37407c478bd9Sstevel@tonic-gate }
37417c478bd9Sstevel@tonic-gate
37427c478bd9Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
37437c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid)
37447c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
37457c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
37467c478bd9Sstevel@tonic-gate
37477c478bd9Sstevel@tonic-gate /*
37487c478bd9Sstevel@tonic-gate * Cluster nodename support
37497c478bd9Sstevel@tonic-gate * Convert nodeid -> nodename
37507c478bd9Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
37517c478bd9Sstevel@tonic-gate * both the nodeid and name.
37527c478bd9Sstevel@tonic-gate */
37537c478bd9Sstevel@tonic-gate if ((version == METAD_VERSION) ||
37547c478bd9Sstevel@tonic-gate ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
37557c478bd9Sstevel@tonic-gate sdssc_cm_sr_nid2nm(sr);
37567c478bd9Sstevel@tonic-gate
37577c478bd9Sstevel@tonic-gate free_sr(sr);
37587c478bd9Sstevel@tonic-gate }
37597c478bd9Sstevel@tonic-gate
37607c478bd9Sstevel@tonic-gate /*
37617c478bd9Sstevel@tonic-gate * Set MH ioctl timeout values.
37627c478bd9Sstevel@tonic-gate */
37637c478bd9Sstevel@tonic-gate bool_t
mdrpc_stimeout_common(mdrpc_stimeout_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)37647c478bd9Sstevel@tonic-gate mdrpc_stimeout_common(
37657c478bd9Sstevel@tonic-gate mdrpc_stimeout_args *args,
37667c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
37677c478bd9Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
37687c478bd9Sstevel@tonic-gate int version /* RPC version */
37697c478bd9Sstevel@tonic-gate )
37707c478bd9Sstevel@tonic-gate {
37717c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
37727c478bd9Sstevel@tonic-gate int err;
37737c478bd9Sstevel@tonic-gate int op_mode = W_OK;
37747c478bd9Sstevel@tonic-gate
37757c478bd9Sstevel@tonic-gate /* setup, check permissions */
37767c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
37777c478bd9Sstevel@tonic-gate return (FALSE);
37787c478bd9Sstevel@tonic-gate else if (err != 0)
37797c478bd9Sstevel@tonic-gate return (TRUE);
37807c478bd9Sstevel@tonic-gate
37817c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, NULL, ep))
37827c478bd9Sstevel@tonic-gate return (TRUE);
37837c478bd9Sstevel@tonic-gate
37847c478bd9Sstevel@tonic-gate /* doit */
37857c478bd9Sstevel@tonic-gate stimeout(args->sp, args->mhiargsp, version, ep);
37867c478bd9Sstevel@tonic-gate
37877c478bd9Sstevel@tonic-gate err = svc_fini(ep);
37887c478bd9Sstevel@tonic-gate
37897c478bd9Sstevel@tonic-gate return (TRUE);
37907c478bd9Sstevel@tonic-gate }
37917c478bd9Sstevel@tonic-gate
37927c478bd9Sstevel@tonic-gate bool_t
mdrpc_stimeout_1_svc(mdrpc_stimeout_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)37937c478bd9Sstevel@tonic-gate mdrpc_stimeout_1_svc(
37947c478bd9Sstevel@tonic-gate mdrpc_stimeout_args *args,
37957c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
37967c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
37977c478bd9Sstevel@tonic-gate )
37987c478bd9Sstevel@tonic-gate {
37992a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
38007c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
38017c478bd9Sstevel@tonic-gate return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION));
38027c478bd9Sstevel@tonic-gate }
38037c478bd9Sstevel@tonic-gate
38047c478bd9Sstevel@tonic-gate bool_t
mdrpc_stimeout_2_svc(mdrpc_stimeout_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)38057c478bd9Sstevel@tonic-gate mdrpc_stimeout_2_svc(
38067c478bd9Sstevel@tonic-gate mdrpc_stimeout_2_args *args,
38077c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
38087c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
38097c478bd9Sstevel@tonic-gate )
38107c478bd9Sstevel@tonic-gate {
38112a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
38127c478bd9Sstevel@tonic-gate switch (args->rev) {
38137c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
38147c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
38157c478bd9Sstevel@tonic-gate return (mdrpc_stimeout_common(
38167c478bd9Sstevel@tonic-gate &args->mdrpc_stimeout_2_args_u.rev1, res,
38177c478bd9Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
38187c478bd9Sstevel@tonic-gate default:
38197c478bd9Sstevel@tonic-gate return (FALSE);
38207c478bd9Sstevel@tonic-gate }
38217c478bd9Sstevel@tonic-gate }
38227c478bd9Sstevel@tonic-gate
38237c478bd9Sstevel@tonic-gate static void
upd_dr_dbinfo(mdsetname_t * sp,md_drive_desc * dd,md_error_t * ep)38247c478bd9Sstevel@tonic-gate upd_dr_dbinfo(
38257c478bd9Sstevel@tonic-gate mdsetname_t *sp,
38267c478bd9Sstevel@tonic-gate md_drive_desc *dd,
38277c478bd9Sstevel@tonic-gate md_error_t *ep
38287c478bd9Sstevel@tonic-gate )
38297c478bd9Sstevel@tonic-gate {
38307c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
38317c478bd9Sstevel@tonic-gate md_set_record *sr;
38327c478bd9Sstevel@tonic-gate md_drive_record *dr;
38337c478bd9Sstevel@tonic-gate md_drive_desc *p;
38347c478bd9Sstevel@tonic-gate mddrivename_t *dn, *dn1;
38357c478bd9Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
38367c478bd9Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
38377c478bd9Sstevel@tonic-gate int devid_same = -1;
38387c478bd9Sstevel@tonic-gate side_t sideno;
38397c478bd9Sstevel@tonic-gate int using_devid = 0;
38407c478bd9Sstevel@tonic-gate
38417c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
38427c478bd9Sstevel@tonic-gate return;
38437c478bd9Sstevel@tonic-gate
38447c478bd9Sstevel@tonic-gate metaflushsetname(local_sp);
38457c478bd9Sstevel@tonic-gate
38467c478bd9Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
38477c478bd9Sstevel@tonic-gate return;
38487c478bd9Sstevel@tonic-gate
38497c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
38507c478bd9Sstevel@tonic-gate return;
38517c478bd9Sstevel@tonic-gate
38527c478bd9Sstevel@tonic-gate if (dd->dd_dnp == NULL)
38537c478bd9Sstevel@tonic-gate return;
38547c478bd9Sstevel@tonic-gate
38557c478bd9Sstevel@tonic-gate /*
38567c478bd9Sstevel@tonic-gate * The system is either all devid or all
38577c478bd9Sstevel@tonic-gate * non-devid so we determine this by looking
38587c478bd9Sstevel@tonic-gate * at the first item in the list.
38597c478bd9Sstevel@tonic-gate *
38607c478bd9Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
38617c478bd9Sstevel@tonic-gate * points to a '' string of devid. We need to check this
38627c478bd9Sstevel@tonic-gate * before set the using_devid.
38637c478bd9Sstevel@tonic-gate */
38647c478bd9Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
38657c478bd9Sstevel@tonic-gate (!(MD_MNSET_REC(sr))))
38667c478bd9Sstevel@tonic-gate using_devid = 1;
38677c478bd9Sstevel@tonic-gate
38687c478bd9Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
38697c478bd9Sstevel@tonic-gate dn = p->dd_dnp;
38707c478bd9Sstevel@tonic-gate devid_remote = NULL;
38717c478bd9Sstevel@tonic-gate
38727c478bd9Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
38737c478bd9Sstevel@tonic-gate using_devid) {
38747c478bd9Sstevel@tonic-gate /*
38757c478bd9Sstevel@tonic-gate * We have a devid so use it.
38767c478bd9Sstevel@tonic-gate */
38777c478bd9Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
38787c478bd9Sstevel@tonic-gate }
38797c478bd9Sstevel@tonic-gate
38807c478bd9Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
38817c478bd9Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
38827c478bd9Sstevel@tonic-gate /* something went really wrong. Can't process */
38837c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
38847c478bd9Sstevel@tonic-gate mynode(), dn->cname, sp->setname);
38857c478bd9Sstevel@tonic-gate return;
38867c478bd9Sstevel@tonic-gate }
38877c478bd9Sstevel@tonic-gate
38887c478bd9Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
38897c478bd9Sstevel@tonic-gate devid_same = -1;
38907c478bd9Sstevel@tonic-gate
38917c478bd9Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno,
38927c478bd9Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep);
38937c478bd9Sstevel@tonic-gate
38947c478bd9Sstevel@tonic-gate if (dn1 == NULL) {
38957c478bd9Sstevel@tonic-gate if (devid_remote)
38967c478bd9Sstevel@tonic-gate devid_free(devid_remote);
38977c478bd9Sstevel@tonic-gate goto out;
38987c478bd9Sstevel@tonic-gate }
38997c478bd9Sstevel@tonic-gate
39007c478bd9Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) {
39017c478bd9Sstevel@tonic-gate if (devid_str_decode(dn1->devid, &devid_local,
39027c478bd9Sstevel@tonic-gate NULL) == 0) {
39037c478bd9Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
39047c478bd9Sstevel@tonic-gate devid_local);
39057c478bd9Sstevel@tonic-gate devid_free(devid_local);
39067c478bd9Sstevel@tonic-gate }
39077c478bd9Sstevel@tonic-gate }
39087c478bd9Sstevel@tonic-gate
39097c478bd9Sstevel@tonic-gate if (using_devid && devid_same == 0)
39107c478bd9Sstevel@tonic-gate break;
39117c478bd9Sstevel@tonic-gate
39127c478bd9Sstevel@tonic-gate if (!using_devid &&
39137c478bd9Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)
39147c478bd9Sstevel@tonic-gate break;
39157c478bd9Sstevel@tonic-gate }
39167c478bd9Sstevel@tonic-gate
39177c478bd9Sstevel@tonic-gate if (dr) {
39187c478bd9Sstevel@tonic-gate /* Adjust the fields in the copy */
39197c478bd9Sstevel@tonic-gate dr->dr_dbcnt = p->dd_dbcnt;
39207c478bd9Sstevel@tonic-gate dr->dr_dbsize = p->dd_dbsize;
39217c478bd9Sstevel@tonic-gate }
39227c478bd9Sstevel@tonic-gate if (devid_remote)
39237c478bd9Sstevel@tonic-gate devid_free(devid_remote);
39247c478bd9Sstevel@tonic-gate }
39257c478bd9Sstevel@tonic-gate
39267c478bd9Sstevel@tonic-gate
39277c478bd9Sstevel@tonic-gate out:
39287c478bd9Sstevel@tonic-gate commitset(sr, FALSE, ep);
39297c478bd9Sstevel@tonic-gate free_sr(sr);
39307c478bd9Sstevel@tonic-gate }
39317c478bd9Sstevel@tonic-gate
39327c478bd9Sstevel@tonic-gate /*
39337c478bd9Sstevel@tonic-gate * update the database count and size field of drive records.
39347c478bd9Sstevel@tonic-gate */
39357c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)39367c478bd9Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_common(
39377c478bd9Sstevel@tonic-gate mdrpc_drives_2_args_r1 *args,
39387c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
39397c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
39407c478bd9Sstevel@tonic-gate )
39417c478bd9Sstevel@tonic-gate {
39427c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
39437c478bd9Sstevel@tonic-gate int err;
39447c478bd9Sstevel@tonic-gate int op_mode = W_OK;
39457c478bd9Sstevel@tonic-gate
39467c478bd9Sstevel@tonic-gate /* setup, check permissions */
39477c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
39487c478bd9Sstevel@tonic-gate return (FALSE);
39497c478bd9Sstevel@tonic-gate else if (err != 0)
39507c478bd9Sstevel@tonic-gate return (TRUE);
39517c478bd9Sstevel@tonic-gate
39527c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
39537c478bd9Sstevel@tonic-gate return (TRUE);
39547c478bd9Sstevel@tonic-gate
39557c478bd9Sstevel@tonic-gate /* doit */
39567c478bd9Sstevel@tonic-gate upd_dr_dbinfo(args->sp, args->drivedescs, ep);
39577c478bd9Sstevel@tonic-gate
39587c478bd9Sstevel@tonic-gate err = svc_fini(ep);
39597c478bd9Sstevel@tonic-gate
39607c478bd9Sstevel@tonic-gate return (TRUE);
39617c478bd9Sstevel@tonic-gate }
39627c478bd9Sstevel@tonic-gate
39637c478bd9Sstevel@tonic-gate /*
39647c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
39657c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
39667c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
39677c478bd9Sstevel@tonic-gate */
39687c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)39697c478bd9Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_1_svc(
39707c478bd9Sstevel@tonic-gate mdrpc_drives_args *args,
39717c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
39727c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
39737c478bd9Sstevel@tonic-gate )
39747c478bd9Sstevel@tonic-gate {
39757c478bd9Sstevel@tonic-gate bool_t retval;
39767c478bd9Sstevel@tonic-gate mdrpc_drives_2_args_r1 v2_args;
39777c478bd9Sstevel@tonic-gate
39787c478bd9Sstevel@tonic-gate /* allocate memory */
39797c478bd9Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
39802a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
39817c478bd9Sstevel@tonic-gate
39827c478bd9Sstevel@tonic-gate /* build args */
39837c478bd9Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
39847c478bd9Sstevel@tonic-gate v2_args.sp = args->sp;
39857c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
39867c478bd9Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
39877c478bd9Sstevel@tonic-gate v2_args.timestamp = args->timestamp;
39887c478bd9Sstevel@tonic-gate v2_args.genid = args->genid;
39897c478bd9Sstevel@tonic-gate
39907c478bd9Sstevel@tonic-gate retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp);
39917c478bd9Sstevel@tonic-gate
39927c478bd9Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
39937c478bd9Sstevel@tonic-gate
39947c478bd9Sstevel@tonic-gate return (retval);
39957c478bd9Sstevel@tonic-gate }
39967c478bd9Sstevel@tonic-gate
39977c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)39987c478bd9Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_2_svc(
39997c478bd9Sstevel@tonic-gate mdrpc_drives_2_args *args,
40007c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
40017c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
40027c478bd9Sstevel@tonic-gate )
40037c478bd9Sstevel@tonic-gate {
40042a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
40057c478bd9Sstevel@tonic-gate switch (args->rev) {
40067c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
40077c478bd9Sstevel@tonic-gate return (mdrpc_upd_dr_dbinfo_common(
40087c478bd9Sstevel@tonic-gate &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
40097c478bd9Sstevel@tonic-gate default:
40107c478bd9Sstevel@tonic-gate return (FALSE);
40117c478bd9Sstevel@tonic-gate }
40127c478bd9Sstevel@tonic-gate }
40137c478bd9Sstevel@tonic-gate
40147c478bd9Sstevel@tonic-gate static void
upd_dr_flags(mdsetname_t * sp,md_drive_desc * dd,uint_t new_flags,md_error_t * ep)40157c478bd9Sstevel@tonic-gate upd_dr_flags(
40167c478bd9Sstevel@tonic-gate mdsetname_t *sp,
40177c478bd9Sstevel@tonic-gate md_drive_desc *dd,
40187c478bd9Sstevel@tonic-gate uint_t new_flags,
40197c478bd9Sstevel@tonic-gate md_error_t *ep
40207c478bd9Sstevel@tonic-gate )
40217c478bd9Sstevel@tonic-gate {
40227c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
40237c478bd9Sstevel@tonic-gate md_set_record *sr;
40247c478bd9Sstevel@tonic-gate md_drive_record *dr;
40257c478bd9Sstevel@tonic-gate md_drive_desc *p;
40267c478bd9Sstevel@tonic-gate mddrivename_t *dn, *dn1;
40277c478bd9Sstevel@tonic-gate ddi_devid_t devid_remote = NULL;
40287c478bd9Sstevel@tonic-gate ddi_devid_t devid_local = NULL;
40297c478bd9Sstevel@tonic-gate int devid_same = -1;
40307c478bd9Sstevel@tonic-gate side_t sideno;
40317c478bd9Sstevel@tonic-gate int using_devid = 0;
40327c478bd9Sstevel@tonic-gate
40337c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
40347c478bd9Sstevel@tonic-gate return;
40357c478bd9Sstevel@tonic-gate
40367c478bd9Sstevel@tonic-gate metaflushsetname(local_sp);
40377c478bd9Sstevel@tonic-gate
40387c478bd9Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
40397c478bd9Sstevel@tonic-gate return;
40407c478bd9Sstevel@tonic-gate
40417c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
40427c478bd9Sstevel@tonic-gate return;
40437c478bd9Sstevel@tonic-gate
40447c478bd9Sstevel@tonic-gate if (dd->dd_dnp == NULL)
40457c478bd9Sstevel@tonic-gate return;
40467c478bd9Sstevel@tonic-gate
40477c478bd9Sstevel@tonic-gate /*
40487c478bd9Sstevel@tonic-gate * The system is either all devid or all
40497c478bd9Sstevel@tonic-gate * non-devid so we determine this by looking
40507c478bd9Sstevel@tonic-gate * at the first item in the list.
40517c478bd9Sstevel@tonic-gate *
40527c478bd9Sstevel@tonic-gate * For did disks, the dd_dnp->devid is a valid pointer which
40537c478bd9Sstevel@tonic-gate * points to a '' string of devid. We need to check this
40547c478bd9Sstevel@tonic-gate * before set the using_devid.
40557c478bd9Sstevel@tonic-gate */
40567c478bd9Sstevel@tonic-gate if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
40577c478bd9Sstevel@tonic-gate (!(MD_MNSET_REC(sr))))
40587c478bd9Sstevel@tonic-gate using_devid = 1;
40597c478bd9Sstevel@tonic-gate
40607c478bd9Sstevel@tonic-gate for (p = dd; p != NULL; p = p->dd_next) {
40617c478bd9Sstevel@tonic-gate dn = p->dd_dnp;
40627c478bd9Sstevel@tonic-gate devid_remote = NULL;
40637c478bd9Sstevel@tonic-gate
40647c478bd9Sstevel@tonic-gate if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
40657c478bd9Sstevel@tonic-gate using_devid) {
40667c478bd9Sstevel@tonic-gate /*
40677c478bd9Sstevel@tonic-gate * We have a devid so use it.
40687c478bd9Sstevel@tonic-gate */
40697c478bd9Sstevel@tonic-gate (void) devid_str_decode(dn->devid, &devid_remote, NULL);
40707c478bd9Sstevel@tonic-gate }
40717c478bd9Sstevel@tonic-gate
40727c478bd9Sstevel@tonic-gate /* check to make sure using_devid agrees with reality... */
40737c478bd9Sstevel@tonic-gate if ((using_devid == 1) && (devid_remote == NULL)) {
40747c478bd9Sstevel@tonic-gate /* something went really wrong. Can't process */
40757c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
40767c478bd9Sstevel@tonic-gate mynode(), dn->cname, sp->setname);
40777c478bd9Sstevel@tonic-gate return;
40787c478bd9Sstevel@tonic-gate }
40797c478bd9Sstevel@tonic-gate
40807c478bd9Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
40817c478bd9Sstevel@tonic-gate devid_same = -1;
40827c478bd9Sstevel@tonic-gate
40837c478bd9Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno,
40847c478bd9Sstevel@tonic-gate dr->dr_key, MD_BASICNAME_OK, ep);
40857c478bd9Sstevel@tonic-gate
40867c478bd9Sstevel@tonic-gate if (dn1 == NULL) {
40877c478bd9Sstevel@tonic-gate if (devid_remote)
40887c478bd9Sstevel@tonic-gate devid_free(devid_remote);
40897c478bd9Sstevel@tonic-gate goto out;
40907c478bd9Sstevel@tonic-gate }
40917c478bd9Sstevel@tonic-gate
40927c478bd9Sstevel@tonic-gate if (dn1->devid != NULL && using_devid) {
40937c478bd9Sstevel@tonic-gate if (devid_str_decode(dn1->devid,
40947c478bd9Sstevel@tonic-gate &devid_local, NULL) == 0) {
40957c478bd9Sstevel@tonic-gate devid_same = devid_compare(devid_remote,
40967c478bd9Sstevel@tonic-gate devid_local);
40977c478bd9Sstevel@tonic-gate devid_free(devid_local);
40987c478bd9Sstevel@tonic-gate }
40997c478bd9Sstevel@tonic-gate }
41007c478bd9Sstevel@tonic-gate
41017c478bd9Sstevel@tonic-gate if (using_devid && devid_same == 0)
41027c478bd9Sstevel@tonic-gate break;
41037c478bd9Sstevel@tonic-gate
41047c478bd9Sstevel@tonic-gate if (!using_devid &&
41057c478bd9Sstevel@tonic-gate strcmp(dn->cname, dn1->cname) == 0)
41067c478bd9Sstevel@tonic-gate break;
41077c478bd9Sstevel@tonic-gate }
41087c478bd9Sstevel@tonic-gate
41097c478bd9Sstevel@tonic-gate if (dr)
41107c478bd9Sstevel@tonic-gate dr->dr_flags = new_flags;
41117c478bd9Sstevel@tonic-gate if (devid_remote)
41127c478bd9Sstevel@tonic-gate devid_free(devid_remote);
41137c478bd9Sstevel@tonic-gate }
41147c478bd9Sstevel@tonic-gate out:
41157c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
41167c478bd9Sstevel@tonic-gate free_sr(sr);
41177c478bd9Sstevel@tonic-gate }
41187c478bd9Sstevel@tonic-gate
41197c478bd9Sstevel@tonic-gate /*
41207c478bd9Sstevel@tonic-gate * update the database count and size field of drive records.
41217c478bd9Sstevel@tonic-gate */
41227c478bd9Sstevel@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)41237c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_common(
41247c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 *args,
41257c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
41267c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
41277c478bd9Sstevel@tonic-gate )
41287c478bd9Sstevel@tonic-gate {
41297c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
41307c478bd9Sstevel@tonic-gate int err;
41317c478bd9Sstevel@tonic-gate int op_mode = W_OK;
41327c478bd9Sstevel@tonic-gate
41337c478bd9Sstevel@tonic-gate /* setup, check permissions */
41347c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
41357c478bd9Sstevel@tonic-gate return (FALSE);
41367c478bd9Sstevel@tonic-gate else if (err != 0)
41377c478bd9Sstevel@tonic-gate return (TRUE);
41387c478bd9Sstevel@tonic-gate
41397c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
41407c478bd9Sstevel@tonic-gate return (TRUE);
41417c478bd9Sstevel@tonic-gate
41427c478bd9Sstevel@tonic-gate /* doit */
41437c478bd9Sstevel@tonic-gate upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep);
41447c478bd9Sstevel@tonic-gate
41457c478bd9Sstevel@tonic-gate err = svc_fini(ep);
41467c478bd9Sstevel@tonic-gate
41477c478bd9Sstevel@tonic-gate return (TRUE);
41487c478bd9Sstevel@tonic-gate }
41497c478bd9Sstevel@tonic-gate
41507c478bd9Sstevel@tonic-gate /*
41517c478bd9Sstevel@tonic-gate * version 1 of the remote procedure. This procedure is called if the
41527c478bd9Sstevel@tonic-gate * client is running in version 1. We first convert version 1 arguments
41537c478bd9Sstevel@tonic-gate * into version 2 arguments and then call the common remote procedure.
41547c478bd9Sstevel@tonic-gate */
41557c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_1_svc(mdrpc_upd_dr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)41567c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_1_svc(
41577c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_args *args,
41587c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
41597c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
41607c478bd9Sstevel@tonic-gate )
41617c478bd9Sstevel@tonic-gate {
41627c478bd9Sstevel@tonic-gate bool_t retval;
41637c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 v2_args;
41647c478bd9Sstevel@tonic-gate
41657c478bd9Sstevel@tonic-gate /* allocate memory */
41667c478bd9Sstevel@tonic-gate alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
41672a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
41687c478bd9Sstevel@tonic-gate
41697c478bd9Sstevel@tonic-gate /* build args */
41707c478bd9Sstevel@tonic-gate v2_args.cl_sk = args->cl_sk;
41717c478bd9Sstevel@tonic-gate v2_args.sp = args->sp;
41727c478bd9Sstevel@tonic-gate /* convert v1 args to v2 (revision 1) args */
41737c478bd9Sstevel@tonic-gate meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
41747c478bd9Sstevel@tonic-gate v2_args.new_flags = args->new_flags;
41757c478bd9Sstevel@tonic-gate
41767c478bd9Sstevel@tonic-gate retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp);
41777c478bd9Sstevel@tonic-gate
41787c478bd9Sstevel@tonic-gate free_newdrvdesc(v2_args.drivedescs);
41797c478bd9Sstevel@tonic-gate
41807c478bd9Sstevel@tonic-gate return (retval);
41817c478bd9Sstevel@tonic-gate }
41827c478bd9Sstevel@tonic-gate
41837c478bd9Sstevel@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)41847c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_svc(
41857c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args *args,
41867c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
41877c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
41887c478bd9Sstevel@tonic-gate )
41897c478bd9Sstevel@tonic-gate {
41902a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
41917c478bd9Sstevel@tonic-gate switch (args->rev) {
41927c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
41937c478bd9Sstevel@tonic-gate return (mdrpc_upd_dr_flags_common(
41947c478bd9Sstevel@tonic-gate &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
41957c478bd9Sstevel@tonic-gate default:
41967c478bd9Sstevel@tonic-gate return (FALSE);
41977c478bd9Sstevel@tonic-gate }
41987c478bd9Sstevel@tonic-gate }
41997c478bd9Sstevel@tonic-gate
42007c478bd9Sstevel@tonic-gate static void
upd_sr_flags(mdsetname_t * sp,uint_t new_flags,md_error_t * ep)42017c478bd9Sstevel@tonic-gate upd_sr_flags(
42027c478bd9Sstevel@tonic-gate mdsetname_t *sp,
42037c478bd9Sstevel@tonic-gate uint_t new_flags,
42047c478bd9Sstevel@tonic-gate md_error_t *ep
42057c478bd9Sstevel@tonic-gate )
42067c478bd9Sstevel@tonic-gate {
42077c478bd9Sstevel@tonic-gate md_set_record *sr;
42087c478bd9Sstevel@tonic-gate
42097c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
42107c478bd9Sstevel@tonic-gate return;
42117c478bd9Sstevel@tonic-gate
42127c478bd9Sstevel@tonic-gate sr->sr_flags = new_flags;
42137c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
42147c478bd9Sstevel@tonic-gate free_sr(sr);
42157c478bd9Sstevel@tonic-gate }
42167c478bd9Sstevel@tonic-gate
42177c478bd9Sstevel@tonic-gate /*
42187c478bd9Sstevel@tonic-gate * update the set record flags
42197c478bd9Sstevel@tonic-gate */
42207c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_common(mdrpc_upd_sr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42217c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_common(
42227c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_args *args,
42237c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
42247c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
42257c478bd9Sstevel@tonic-gate )
42267c478bd9Sstevel@tonic-gate {
42277c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
42287c478bd9Sstevel@tonic-gate int err;
42297c478bd9Sstevel@tonic-gate int op_mode = W_OK;
42307c478bd9Sstevel@tonic-gate
42317c478bd9Sstevel@tonic-gate /* setup, check permissions */
42327c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
42337c478bd9Sstevel@tonic-gate return (FALSE);
42347c478bd9Sstevel@tonic-gate else if (err != 0)
42357c478bd9Sstevel@tonic-gate return (TRUE);
42367c478bd9Sstevel@tonic-gate
42377c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
42387c478bd9Sstevel@tonic-gate return (TRUE);
42397c478bd9Sstevel@tonic-gate
42407c478bd9Sstevel@tonic-gate /* doit */
42417c478bd9Sstevel@tonic-gate upd_sr_flags(args->sp, args->new_flags, ep);
42427c478bd9Sstevel@tonic-gate
42437c478bd9Sstevel@tonic-gate err = svc_fini(ep);
42447c478bd9Sstevel@tonic-gate
42457c478bd9Sstevel@tonic-gate return (TRUE);
42467c478bd9Sstevel@tonic-gate }
42477c478bd9Sstevel@tonic-gate
42487c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_1_svc(mdrpc_upd_sr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42497c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_1_svc(
42507c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_args *args,
42517c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
42527c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
42537c478bd9Sstevel@tonic-gate )
42547c478bd9Sstevel@tonic-gate {
42552a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
42567c478bd9Sstevel@tonic-gate return (mdrpc_upd_sr_flags_common(args, res, rqstp));
42577c478bd9Sstevel@tonic-gate }
42587c478bd9Sstevel@tonic-gate
42597c478bd9Sstevel@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)42607c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_2_svc(
42617c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_2_args *args,
42627c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
42637c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
42647c478bd9Sstevel@tonic-gate )
42657c478bd9Sstevel@tonic-gate {
42662a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
42677c478bd9Sstevel@tonic-gate switch (args->rev) {
42687c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
42697c478bd9Sstevel@tonic-gate return (mdrpc_upd_sr_flags_common(
42707c478bd9Sstevel@tonic-gate &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp));
42717c478bd9Sstevel@tonic-gate default:
42727c478bd9Sstevel@tonic-gate return (FALSE);
42737c478bd9Sstevel@tonic-gate }
42747c478bd9Sstevel@tonic-gate }
42757c478bd9Sstevel@tonic-gate
42767c478bd9Sstevel@tonic-gate /*
42777c478bd9Sstevel@tonic-gate * upd_nr_flags updates the node records stored in this node's local mddb
42787c478bd9Sstevel@tonic-gate * given a node desciptor list and an action. upd_nr_flags then commits
42797c478bd9Sstevel@tonic-gate * the node records to the local mddb.
42807c478bd9Sstevel@tonic-gate *
42817c478bd9Sstevel@tonic-gate * nd - A linked list of node descriptors that describes the node records
42827c478bd9Sstevel@tonic-gate * in this diskset on which the action applies.
42837c478bd9Sstevel@tonic-gate * flag_action: action to be taken on node records that match the nd list.
42847c478bd9Sstevel@tonic-gate * flag_action can be:
42857c478bd9Sstevel@tonic-gate * MD_NR_JOIN: set OWN flag in node records
42867c478bd9Sstevel@tonic-gate * MD_NR_WITHDRAW: reset OWN flag in node records
42877c478bd9Sstevel@tonic-gate * MD_NR_OK: reset ADD flags and set OK flag in node records
42887c478bd9Sstevel@tonic-gate * MD_NR_SET: set node record flags based on flags stored in nd
42897c478bd9Sstevel@tonic-gate *
42907c478bd9Sstevel@tonic-gate * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting
42917c478bd9Sstevel@tonic-gate * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW
42927c478bd9Sstevel@tonic-gate * (remove last disk from set) or OK (after addition of host to set).
42937c478bd9Sstevel@tonic-gate *
42947c478bd9Sstevel@tonic-gate * The SET flag_action is typically used when nodelist contains all nodes
42957c478bd9Sstevel@tonic-gate * in the diskset, but specific nodes have had flag changes. An example of
42967c478bd9Sstevel@tonic-gate * this would be the join/withdraw of a specific node to/from the set.
42977c478bd9Sstevel@tonic-gate *
42987c478bd9Sstevel@tonic-gate * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag. This
42997c478bd9Sstevel@tonic-gate * flag is used by the client to recover in case of failure and should not
43007c478bd9Sstevel@tonic-gate * be set in the node record flags.
43017c478bd9Sstevel@tonic-gate */
43027c478bd9Sstevel@tonic-gate static void
upd_nr_flags(mdsetname_t * sp,md_mnnode_desc * nd,uint_t flag_action,md_error_t * ep)43037c478bd9Sstevel@tonic-gate upd_nr_flags(
43047c478bd9Sstevel@tonic-gate mdsetname_t *sp,
43057c478bd9Sstevel@tonic-gate md_mnnode_desc *nd,
43067c478bd9Sstevel@tonic-gate uint_t flag_action,
43077c478bd9Sstevel@tonic-gate md_error_t *ep
43087c478bd9Sstevel@tonic-gate )
43097c478bd9Sstevel@tonic-gate {
43107c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
43117c478bd9Sstevel@tonic-gate md_set_record *sr;
43127c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
43137c478bd9Sstevel@tonic-gate md_mnnode_desc *ndp;
43147c478bd9Sstevel@tonic-gate md_mnnode_record *nrp;
43157c478bd9Sstevel@tonic-gate
43167c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(sp->setname, ep)) == NULL)
43177c478bd9Sstevel@tonic-gate return;
43187c478bd9Sstevel@tonic-gate
43197c478bd9Sstevel@tonic-gate metaflushsetname(local_sp);
43207c478bd9Sstevel@tonic-gate
43217c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(sp->setname, ep)) == NULL)
43227c478bd9Sstevel@tonic-gate return;
43237c478bd9Sstevel@tonic-gate
43247c478bd9Sstevel@tonic-gate if (!(MD_MNSET_REC(sr))) {
43257c478bd9Sstevel@tonic-gate return;
43267c478bd9Sstevel@tonic-gate }
43277c478bd9Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
43287c478bd9Sstevel@tonic-gate
43297c478bd9Sstevel@tonic-gate switch (flag_action) {
43307c478bd9Sstevel@tonic-gate case MD_NR_JOIN:
43317c478bd9Sstevel@tonic-gate case MD_NR_WITHDRAW:
43327c478bd9Sstevel@tonic-gate case MD_NR_SET:
43337c478bd9Sstevel@tonic-gate case MD_NR_OK:
43347c478bd9Sstevel@tonic-gate case MD_NR_DEL:
43357c478bd9Sstevel@tonic-gate break;
43367c478bd9Sstevel@tonic-gate default:
43377c478bd9Sstevel@tonic-gate return;
43387c478bd9Sstevel@tonic-gate }
43397c478bd9Sstevel@tonic-gate
43407c478bd9Sstevel@tonic-gate for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) {
43417c478bd9Sstevel@tonic-gate /* Find matching node record for given node descriptor */
43427c478bd9Sstevel@tonic-gate for (nrp = mnsr->sr_nodechain; nrp != NULL;
43437c478bd9Sstevel@tonic-gate nrp = nrp->nr_next) {
43447c478bd9Sstevel@tonic-gate if (ndp->nd_nodeid == nrp->nr_nodeid) {
43457c478bd9Sstevel@tonic-gate switch (flag_action) {
43467c478bd9Sstevel@tonic-gate case MD_NR_JOIN:
43477c478bd9Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_OWN;
43487c478bd9Sstevel@tonic-gate break;
43497c478bd9Sstevel@tonic-gate case MD_NR_WITHDRAW:
43507c478bd9Sstevel@tonic-gate nrp->nr_flags &= ~MD_MN_NODE_OWN;
43517c478bd9Sstevel@tonic-gate break;
43527c478bd9Sstevel@tonic-gate case MD_NR_OK:
43537c478bd9Sstevel@tonic-gate nrp->nr_flags &=
43547c478bd9Sstevel@tonic-gate ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL);
43557c478bd9Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_OK;
43567c478bd9Sstevel@tonic-gate break;
43577c478bd9Sstevel@tonic-gate case MD_NR_DEL:
43587c478bd9Sstevel@tonic-gate nrp->nr_flags &=
43597c478bd9Sstevel@tonic-gate ~(MD_MN_NODE_OK | MD_MN_NODE_ADD);
43607c478bd9Sstevel@tonic-gate nrp->nr_flags |= MD_MN_NODE_DEL;
43617c478bd9Sstevel@tonic-gate break;
43627c478bd9Sstevel@tonic-gate case MD_NR_SET:
43637c478bd9Sstevel@tonic-gate /* Do not set RB_JOIN flag */
43647c478bd9Sstevel@tonic-gate nrp->nr_flags =
43657c478bd9Sstevel@tonic-gate ndp->nd_flags & ~MD_MN_NODE_RB_JOIN;
43667c478bd9Sstevel@tonic-gate break;
43677c478bd9Sstevel@tonic-gate }
43687c478bd9Sstevel@tonic-gate break;
43697c478bd9Sstevel@tonic-gate }
43707c478bd9Sstevel@tonic-gate }
43717c478bd9Sstevel@tonic-gate }
43727c478bd9Sstevel@tonic-gate out:
43737c478bd9Sstevel@tonic-gate /* Don't increment set genid for node record flag update */
43747c478bd9Sstevel@tonic-gate commitset(sr, FALSE, ep);
43757c478bd9Sstevel@tonic-gate free_sr(sr);
43767c478bd9Sstevel@tonic-gate }
43777c478bd9Sstevel@tonic-gate
43787c478bd9Sstevel@tonic-gate /*
43797c478bd9Sstevel@tonic-gate * init/fini wrapper around upd_nr_flags
43807c478bd9Sstevel@tonic-gate */
43817c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_nr_flags_common(mdrpc_upd_nr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)43827c478bd9Sstevel@tonic-gate mdrpc_upd_nr_flags_common(
43837c478bd9Sstevel@tonic-gate mdrpc_upd_nr_flags_args *args,
43847c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
43857c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
43867c478bd9Sstevel@tonic-gate )
43877c478bd9Sstevel@tonic-gate {
43887c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
43897c478bd9Sstevel@tonic-gate int err;
43907c478bd9Sstevel@tonic-gate int op_mode = W_OK;
43917c478bd9Sstevel@tonic-gate
43927c478bd9Sstevel@tonic-gate /* setup, check permissions */
43937c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
43947c478bd9Sstevel@tonic-gate return (FALSE);
43957c478bd9Sstevel@tonic-gate else if (err != 0)
43967c478bd9Sstevel@tonic-gate return (TRUE);
43977c478bd9Sstevel@tonic-gate
43987c478bd9Sstevel@tonic-gate /*
43997c478bd9Sstevel@tonic-gate * During reconfig, node record flags can be updated without
44007c478bd9Sstevel@tonic-gate * locking first.
44017c478bd9Sstevel@tonic-gate */
44027c478bd9Sstevel@tonic-gate if (!(args->flags & MNSET_IN_RECONFIG)) {
44037c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
44047c478bd9Sstevel@tonic-gate return (TRUE);
44057c478bd9Sstevel@tonic-gate }
44067c478bd9Sstevel@tonic-gate
44077c478bd9Sstevel@tonic-gate /* doit */
44087c478bd9Sstevel@tonic-gate upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep);
44097c478bd9Sstevel@tonic-gate
44107c478bd9Sstevel@tonic-gate err = svc_fini(ep);
44117c478bd9Sstevel@tonic-gate
44127c478bd9Sstevel@tonic-gate return (TRUE);
44137c478bd9Sstevel@tonic-gate }
44147c478bd9Sstevel@tonic-gate
44157c478bd9Sstevel@tonic-gate /*
44167c478bd9Sstevel@tonic-gate * update the node records using given flag action.
44177c478bd9Sstevel@tonic-gate */
44187c478bd9Sstevel@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)44197c478bd9Sstevel@tonic-gate mdrpc_upd_nr_flags_2_svc(
44207c478bd9Sstevel@tonic-gate mdrpc_upd_nr_flags_2_args *args,
44217c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
44227c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
44237c478bd9Sstevel@tonic-gate )
44247c478bd9Sstevel@tonic-gate {
44252a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
44267c478bd9Sstevel@tonic-gate switch (args->rev) {
44277c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
44287c478bd9Sstevel@tonic-gate return (mdrpc_upd_nr_flags_common(
44297c478bd9Sstevel@tonic-gate &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp));
44307c478bd9Sstevel@tonic-gate default:
44317c478bd9Sstevel@tonic-gate return (FALSE);
44327c478bd9Sstevel@tonic-gate }
44337c478bd9Sstevel@tonic-gate }
44347c478bd9Sstevel@tonic-gate
44357c478bd9Sstevel@tonic-gate void
free_sk(md_setkey_t * skp)44367c478bd9Sstevel@tonic-gate free_sk(md_setkey_t *skp)
44377c478bd9Sstevel@tonic-gate {
44387c478bd9Sstevel@tonic-gate Free(skp->sk_setname);
44397c478bd9Sstevel@tonic-gate Free(skp->sk_host);
44407c478bd9Sstevel@tonic-gate Free(skp);
44417c478bd9Sstevel@tonic-gate }
44427c478bd9Sstevel@tonic-gate
44437c478bd9Sstevel@tonic-gate void
del_sk(set_t setno)44447c478bd9Sstevel@tonic-gate del_sk(set_t setno)
44457c478bd9Sstevel@tonic-gate {
44467c478bd9Sstevel@tonic-gate md_setkey_t *skp;
44477c478bd9Sstevel@tonic-gate md_setkey_t *tskp;
44487c478bd9Sstevel@tonic-gate
44497c478bd9Sstevel@tonic-gate for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) {
44507c478bd9Sstevel@tonic-gate if (setno == skp->sk_setno) {
44517c478bd9Sstevel@tonic-gate if (skp == my_svc_sk)
44527c478bd9Sstevel@tonic-gate my_svc_sk = skp->sk_next;
44537c478bd9Sstevel@tonic-gate else
44547c478bd9Sstevel@tonic-gate tskp->sk_next = skp->sk_next;
44557c478bd9Sstevel@tonic-gate
44567c478bd9Sstevel@tonic-gate Free(skp->sk_setname);
44577c478bd9Sstevel@tonic-gate Free(skp->sk_host);
44587c478bd9Sstevel@tonic-gate Free(skp);
44597c478bd9Sstevel@tonic-gate break;
44607c478bd9Sstevel@tonic-gate }
44617c478bd9Sstevel@tonic-gate }
44627c478bd9Sstevel@tonic-gate }
44637c478bd9Sstevel@tonic-gate
44647c478bd9Sstevel@tonic-gate md_setkey_t *
dupsk(md_setkey_t * skp)44657c478bd9Sstevel@tonic-gate dupsk(md_setkey_t *skp)
44667c478bd9Sstevel@tonic-gate {
44677c478bd9Sstevel@tonic-gate md_setkey_t *tskp;
44687c478bd9Sstevel@tonic-gate
44697c478bd9Sstevel@tonic-gate tskp = Zalloc(sizeof (md_setkey_t));
44707c478bd9Sstevel@tonic-gate
44717c478bd9Sstevel@tonic-gate *tskp = *skp;
44727c478bd9Sstevel@tonic-gate tskp->sk_host = Strdup(skp->sk_host);
44737c478bd9Sstevel@tonic-gate tskp->sk_setname = Strdup(skp->sk_setname);
44747c478bd9Sstevel@tonic-gate
44757c478bd9Sstevel@tonic-gate return (tskp);
44767c478bd9Sstevel@tonic-gate }
44777c478bd9Sstevel@tonic-gate
44787c478bd9Sstevel@tonic-gate md_setkey_t *
svc_get_setkey(set_t setno)44797c478bd9Sstevel@tonic-gate svc_get_setkey(set_t setno)
44807c478bd9Sstevel@tonic-gate {
44817c478bd9Sstevel@tonic-gate md_setkey_t *skp;
44827c478bd9Sstevel@tonic-gate
44837c478bd9Sstevel@tonic-gate for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next)
44847c478bd9Sstevel@tonic-gate if (setno == skp->sk_setno)
44857c478bd9Sstevel@tonic-gate return (dupsk(skp));
44867c478bd9Sstevel@tonic-gate return (NULL);
44877c478bd9Sstevel@tonic-gate }
44887c478bd9Sstevel@tonic-gate
44897c478bd9Sstevel@tonic-gate void
svc_set_setkey(md_setkey_t * svc_sk)44907c478bd9Sstevel@tonic-gate svc_set_setkey(md_setkey_t *svc_sk)
44917c478bd9Sstevel@tonic-gate {
44927c478bd9Sstevel@tonic-gate md_setkey_t *skp;
44937c478bd9Sstevel@tonic-gate
44947c478bd9Sstevel@tonic-gate if (my_svc_sk == NULL) {
44957c478bd9Sstevel@tonic-gate my_svc_sk = dupsk(svc_sk);
44967c478bd9Sstevel@tonic-gate return;
44977c478bd9Sstevel@tonic-gate }
44987c478bd9Sstevel@tonic-gate
44997c478bd9Sstevel@tonic-gate for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next)
45007c478bd9Sstevel@tonic-gate assert(svc_sk->sk_setno != skp->sk_setno);
45017c478bd9Sstevel@tonic-gate
45027c478bd9Sstevel@tonic-gate skp->sk_next = dupsk(svc_sk);
45037c478bd9Sstevel@tonic-gate }
45047c478bd9Sstevel@tonic-gate
45057c478bd9Sstevel@tonic-gate /*
45067c478bd9Sstevel@tonic-gate * Unlock the set
45077c478bd9Sstevel@tonic-gate *
45087c478bd9Sstevel@tonic-gate * To unlock the set, the user must have the correct key, once this is verified
45097c478bd9Sstevel@tonic-gate * the set is unlocked and the cached information for the set is flushed.
45107c478bd9Sstevel@tonic-gate */
45117c478bd9Sstevel@tonic-gate bool_t
mdrpc_unlock_set_common(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)45127c478bd9Sstevel@tonic-gate mdrpc_unlock_set_common(
45137c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
45147c478bd9Sstevel@tonic-gate mdrpc_setlock_res *res,
45157c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
45167c478bd9Sstevel@tonic-gate )
45177c478bd9Sstevel@tonic-gate {
45187c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
45197c478bd9Sstevel@tonic-gate int err;
45207c478bd9Sstevel@tonic-gate int op_mode = W_OK;
45217c478bd9Sstevel@tonic-gate md_setkey_t *svc_skp;
45227c478bd9Sstevel@tonic-gate md_set_desc *sd;
45237c478bd9Sstevel@tonic-gate mdsetname_t *sp;
45247c478bd9Sstevel@tonic-gate int multi_node = 0;
45257c478bd9Sstevel@tonic-gate md_error_t xep = mdnullerror;
45267c478bd9Sstevel@tonic-gate
45277c478bd9Sstevel@tonic-gate /* setup, check permissions */
45287c478bd9Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
45297c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
45307c478bd9Sstevel@tonic-gate return (FALSE);
45317c478bd9Sstevel@tonic-gate else if (err != 0)
45327c478bd9Sstevel@tonic-gate return (TRUE);
45337c478bd9Sstevel@tonic-gate
45347c478bd9Sstevel@tonic-gate /*
45357c478bd9Sstevel@tonic-gate * Is diskset a MN diskset?
45367c478bd9Sstevel@tonic-gate * Don't set error from this check since unlock set can be
45377c478bd9Sstevel@tonic-gate * called after a set has been deleted.
45387c478bd9Sstevel@tonic-gate */
45397c478bd9Sstevel@tonic-gate if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) &&
45407c478bd9Sstevel@tonic-gate ((sd = metaget_setdesc(sp, &xep)) != NULL)) {
45417c478bd9Sstevel@tonic-gate if ((MD_MNSET_DESC(sd))) {
45427c478bd9Sstevel@tonic-gate multi_node = 1;
45437c478bd9Sstevel@tonic-gate }
45447c478bd9Sstevel@tonic-gate }
45457c478bd9Sstevel@tonic-gate
45467c478bd9Sstevel@tonic-gate /* Get the set key, if any */
45477c478bd9Sstevel@tonic-gate svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
45487c478bd9Sstevel@tonic-gate
45497c478bd9Sstevel@tonic-gate /* The set is locked */
45507c478bd9Sstevel@tonic-gate if (svc_skp != NULL) {
45517c478bd9Sstevel@tonic-gate
45527c478bd9Sstevel@tonic-gate /* Make sure the opener has the right key. */
45537c478bd9Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec ||
45547c478bd9Sstevel@tonic-gate args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) {
45557c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_ULKSBADKEY,
45567c478bd9Sstevel@tonic-gate svc_skp->sk_setno, mynode(), svc_skp->sk_host,
45577c478bd9Sstevel@tonic-gate svc_skp->sk_setname);
45587c478bd9Sstevel@tonic-gate free_sk(svc_skp);
45597c478bd9Sstevel@tonic-gate return (TRUE);
45607c478bd9Sstevel@tonic-gate }
45617c478bd9Sstevel@tonic-gate
45627c478bd9Sstevel@tonic-gate /* Unlock the set */
45637c478bd9Sstevel@tonic-gate del_sk(args->cl_sk->sk_setno);
45647c478bd9Sstevel@tonic-gate
45657c478bd9Sstevel@tonic-gate /* Cleanup */
45667c478bd9Sstevel@tonic-gate free_sk(svc_skp);
45677c478bd9Sstevel@tonic-gate
45687c478bd9Sstevel@tonic-gate goto out;
45697c478bd9Sstevel@tonic-gate }
45707c478bd9Sstevel@tonic-gate
45717c478bd9Sstevel@tonic-gate
45727c478bd9Sstevel@tonic-gate /*
45737c478bd9Sstevel@tonic-gate * It is possible on a MN diskset to attempt to unlock a set that
45747c478bd9Sstevel@tonic-gate * is unlocked. This could occur when the metaset or metadb command
45757c478bd9Sstevel@tonic-gate * is failing due to another metaset or metadb command running.
45767c478bd9Sstevel@tonic-gate * So, print no warning for MN disksets.
45777c478bd9Sstevel@tonic-gate */
45787c478bd9Sstevel@tonic-gate if (multi_node == 0) {
45797c478bd9Sstevel@tonic-gate md_eprintf("Warning: set unlocked when unlock_set called!\n");
45807c478bd9Sstevel@tonic-gate }
45817c478bd9Sstevel@tonic-gate
45827c478bd9Sstevel@tonic-gate out:
45837c478bd9Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
45847c478bd9Sstevel@tonic-gate
45857c478bd9Sstevel@tonic-gate /* Flush the set cache */
45867c478bd9Sstevel@tonic-gate sr_cache_flush_setno(args->cl_sk->sk_setno);
45877c478bd9Sstevel@tonic-gate
45887c478bd9Sstevel@tonic-gate return (TRUE);
45897c478bd9Sstevel@tonic-gate }
45907c478bd9Sstevel@tonic-gate
45917c478bd9Sstevel@tonic-gate bool_t
mdrpc_unlock_set_1_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)45927c478bd9Sstevel@tonic-gate mdrpc_unlock_set_1_svc(
45937c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
45947c478bd9Sstevel@tonic-gate mdrpc_setlock_res *res,
45957c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
45967c478bd9Sstevel@tonic-gate )
45977c478bd9Sstevel@tonic-gate {
45987c478bd9Sstevel@tonic-gate return (mdrpc_unlock_set_common(args, res, rqstp));
45997c478bd9Sstevel@tonic-gate }
46007c478bd9Sstevel@tonic-gate
46017c478bd9Sstevel@tonic-gate bool_t
mdrpc_unlock_set_2_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)46027c478bd9Sstevel@tonic-gate mdrpc_unlock_set_2_svc(
46037c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
46047c478bd9Sstevel@tonic-gate mdrpc_setlock_res *res,
46057c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
46067c478bd9Sstevel@tonic-gate )
46077c478bd9Sstevel@tonic-gate {
46087c478bd9Sstevel@tonic-gate return (mdrpc_unlock_set_common(args, res, rqstp));
46097c478bd9Sstevel@tonic-gate }
46107c478bd9Sstevel@tonic-gate
46117c478bd9Sstevel@tonic-gate /*
46127c478bd9Sstevel@tonic-gate * Lock the set
46137c478bd9Sstevel@tonic-gate *
46147c478bd9Sstevel@tonic-gate * If the user does not hand us a key, then we generate a new key and lock the
46157c478bd9Sstevel@tonic-gate * set using this new key that was generated, if the user hands us a key then
46167c478bd9Sstevel@tonic-gate * we use the key to lock the set.
46177c478bd9Sstevel@tonic-gate */
46187c478bd9Sstevel@tonic-gate bool_t
mdrpc_lock_set_common(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)46197c478bd9Sstevel@tonic-gate mdrpc_lock_set_common(
46207c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
46217c478bd9Sstevel@tonic-gate mdrpc_setlock_res *res,
46227c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
46237c478bd9Sstevel@tonic-gate )
46247c478bd9Sstevel@tonic-gate {
46257c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
46267c478bd9Sstevel@tonic-gate int err;
46277c478bd9Sstevel@tonic-gate md_error_t xep = mdnullerror;
46287c478bd9Sstevel@tonic-gate int op_mode = W_OK;
46297c478bd9Sstevel@tonic-gate md_setkey_t *svc_skp;
46307c478bd9Sstevel@tonic-gate md_setkey_t new_sk;
463143b3654dSrd117015 md_set_desc *sd = NULL;
463243b3654dSrd117015 mdsetname_t *sp = NULL;
46337c478bd9Sstevel@tonic-gate
46347c478bd9Sstevel@tonic-gate /* setup, check permissions */
46357c478bd9Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
46367c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
46377c478bd9Sstevel@tonic-gate return (FALSE);
46387c478bd9Sstevel@tonic-gate else if (err != 0)
46397c478bd9Sstevel@tonic-gate return (TRUE);
46407c478bd9Sstevel@tonic-gate
46417c478bd9Sstevel@tonic-gate svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
46427c478bd9Sstevel@tonic-gate
464343b3654dSrd117015 /* The set is locked */
464443b3654dSrd117015 if (svc_skp != NULL) {
464543b3654dSrd117015
464643b3654dSrd117015 /*
464743b3654dSrd117015 * This lock request could be for a new diskset, as
464843b3654dSrd117015 * such metasetnosetname() may not return anything
464943b3654dSrd117015 * useful. Only call it if there is already a key.
465043b3654dSrd117015 */
465143b3654dSrd117015 if ((sp = metasetnosetname(args->cl_sk->sk_setno, ep))
465243b3654dSrd117015 != NULL) {
465343b3654dSrd117015 sd = metaget_setdesc(sp, ep);
465443b3654dSrd117015 }
465543b3654dSrd117015
465643b3654dSrd117015 /*
465743b3654dSrd117015 * meta_lock() provides local locking for non-MN
465843b3654dSrd117015 * disksets. The local lock is held before we call
465943b3654dSrd117015 * this RPC function. We should not receive a lock
466043b3654dSrd117015 * request from the host which owns the lock. If we
466143b3654dSrd117015 * do, release the lock.
466243b3654dSrd117015 */
466343b3654dSrd117015 if (!((sd != NULL) && (MD_MNSET_DESC(sd))) &&
466443b3654dSrd117015 (strcmp(svc_skp->sk_host, args->cl_sk->sk_host) == 0)) {
466543b3654dSrd117015 md_eprintf(
466643b3654dSrd117015 "Warning: set locked when lock_set called!\n");
466743b3654dSrd117015
466843b3654dSrd117015 md_eprintf("Held lock info:\n");
466943b3654dSrd117015
467043b3654dSrd117015 md_eprintf("\tLock:\n");
467143b3654dSrd117015 md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
467243b3654dSrd117015 md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno);
467343b3654dSrd117015 md_eprintf("\t\tHost: %s\n", svc_skp->sk_host);
467443b3654dSrd117015 md_eprintf("\t\tKey: %d/%d %s\n",
467543b3654dSrd117015 svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
467643b3654dSrd117015 ctime((const time_t *)&svc_skp->sk_key.tv_sec));
467743b3654dSrd117015
467843b3654dSrd117015 /* Unlock set */
467943b3654dSrd117015 del_sk(svc_skp->sk_setno);
468043b3654dSrd117015 free_sk(svc_skp);
468143b3654dSrd117015 svc_skp = NULL;
468243b3654dSrd117015
468343b3654dSrd117015 md_eprintf("Released lock held by requesting host\n");
468443b3654dSrd117015 }
468543b3654dSrd117015 }
468643b3654dSrd117015
46877c478bd9Sstevel@tonic-gate /* The set is unlocked */
46887c478bd9Sstevel@tonic-gate if (svc_skp == NULL) {
46897c478bd9Sstevel@tonic-gate /* If we have been given a key, use it. */
46907c478bd9Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) {
46917c478bd9Sstevel@tonic-gate svc_set_setkey(args->cl_sk);
46927c478bd9Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
46937c478bd9Sstevel@tonic-gate goto out;
46947c478bd9Sstevel@tonic-gate }
46957c478bd9Sstevel@tonic-gate
46967c478bd9Sstevel@tonic-gate /* We need to lock it, with a new key */
46977c478bd9Sstevel@tonic-gate new_sk = *args->cl_sk;
46987c478bd9Sstevel@tonic-gate if (meta_gettimeofday(&new_sk.sk_key) == -1) {
46997c478bd9Sstevel@tonic-gate (void) mdsyserror(ep, errno, "meta_gettimeofday()");
47007c478bd9Sstevel@tonic-gate mde_perror(&xep, "");
47017c478bd9Sstevel@tonic-gate md_exit(NULL, 1);
47027c478bd9Sstevel@tonic-gate }
47037c478bd9Sstevel@tonic-gate svc_set_setkey(&new_sk);
47047c478bd9Sstevel@tonic-gate
47057c478bd9Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
47067c478bd9Sstevel@tonic-gate goto out;
47077c478bd9Sstevel@tonic-gate }
47087c478bd9Sstevel@tonic-gate
47097c478bd9Sstevel@tonic-gate /*
47107c478bd9Sstevel@tonic-gate * If a MN diskset, the lock_set routine is used as a locking
47117c478bd9Sstevel@tonic-gate * mechanism to keep multiple metaset and/or metadb commads
47127c478bd9Sstevel@tonic-gate * from interfering with each other. If two metaset/metadb
47137c478bd9Sstevel@tonic-gate * commands are issued at the same time - one will complete
47147c478bd9Sstevel@tonic-gate * and the other command will fail with MDE_DS_NOTNOW_CMD.
47157c478bd9Sstevel@tonic-gate */
471643b3654dSrd117015 if ((sd != NULL) && MD_MNSET_DESC(sd)) {
47177c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_NOTNOW_CMD,
47187c478bd9Sstevel@tonic-gate svc_skp->sk_setno, mynode(),
47197c478bd9Sstevel@tonic-gate svc_skp->sk_host, svc_skp->sk_setname);
47207c478bd9Sstevel@tonic-gate goto out;
47217c478bd9Sstevel@tonic-gate }
47227c478bd9Sstevel@tonic-gate
47237c478bd9Sstevel@tonic-gate md_eprintf("Warning: set locked when lock_set called!\n");
47247c478bd9Sstevel@tonic-gate
47257c478bd9Sstevel@tonic-gate md_eprintf("Lock info:\n");
47267c478bd9Sstevel@tonic-gate
47277c478bd9Sstevel@tonic-gate md_eprintf("\tLock(svc):\n");
47287c478bd9Sstevel@tonic-gate md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
47297c478bd9Sstevel@tonic-gate md_eprintf("\t\tSetno: %d\n", svc_skp->sk_setno);
47307c478bd9Sstevel@tonic-gate md_eprintf("\t\tHost: %s\n", svc_skp->sk_host);
47317c478bd9Sstevel@tonic-gate md_eprintf("\t\tKey: %d/%d %s",
47327c478bd9Sstevel@tonic-gate svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
47337c478bd9Sstevel@tonic-gate ctime((const time_t *)&svc_skp->sk_key.tv_sec));
47347c478bd9Sstevel@tonic-gate
47357c478bd9Sstevel@tonic-gate md_eprintf("\tLock(cl):\n");
47367c478bd9Sstevel@tonic-gate md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname);
47377c478bd9Sstevel@tonic-gate md_eprintf("\t\tSetno: %d\n", args->cl_sk->sk_setno);
47387c478bd9Sstevel@tonic-gate md_eprintf("\t\tHost: %s\n", args->cl_sk->sk_host);
47397c478bd9Sstevel@tonic-gate md_eprintf("\t\tKey: %d/%d %s",
47407c478bd9Sstevel@tonic-gate args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec,
47417c478bd9Sstevel@tonic-gate ctime((const time_t *)&args->cl_sk->sk_key.tv_sec));
47427c478bd9Sstevel@tonic-gate
47437c478bd9Sstevel@tonic-gate /* The set is locked, do we have the key? */
47447c478bd9Sstevel@tonic-gate if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec &&
47457c478bd9Sstevel@tonic-gate args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) {
47467c478bd9Sstevel@tonic-gate res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
47477c478bd9Sstevel@tonic-gate goto out;
47487c478bd9Sstevel@tonic-gate }
47497c478bd9Sstevel@tonic-gate
47507c478bd9Sstevel@tonic-gate /*
47517c478bd9Sstevel@tonic-gate * The set is locked and we do not have the key, so we set up an error.
47527c478bd9Sstevel@tonic-gate */
47537c478bd9Sstevel@tonic-gate (void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(),
47547c478bd9Sstevel@tonic-gate svc_skp->sk_host, args->cl_sk->sk_setname);
47557c478bd9Sstevel@tonic-gate
47567c478bd9Sstevel@tonic-gate out:
47577c478bd9Sstevel@tonic-gate if (svc_skp != NULL)
47587c478bd9Sstevel@tonic-gate free_sk(svc_skp);
47597c478bd9Sstevel@tonic-gate
47607c478bd9Sstevel@tonic-gate /* Flush the set cache */
47617c478bd9Sstevel@tonic-gate sr_cache_flush_setno(args->cl_sk->sk_setno);
47627c478bd9Sstevel@tonic-gate
47637c478bd9Sstevel@tonic-gate return (TRUE);
47647c478bd9Sstevel@tonic-gate }
47657c478bd9Sstevel@tonic-gate
47667c478bd9Sstevel@tonic-gate bool_t
mdrpc_lock_set_1_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)47677c478bd9Sstevel@tonic-gate mdrpc_lock_set_1_svc(
47687c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
47697c478bd9Sstevel@tonic-gate mdrpc_setlock_res *res,
47707c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
47717c478bd9Sstevel@tonic-gate )
47727c478bd9Sstevel@tonic-gate {
47737c478bd9Sstevel@tonic-gate return (mdrpc_lock_set_common(args, res, rqstp));
47747c478bd9Sstevel@tonic-gate }
47757c478bd9Sstevel@tonic-gate
47767c478bd9Sstevel@tonic-gate bool_t
mdrpc_lock_set_2_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)47777c478bd9Sstevel@tonic-gate mdrpc_lock_set_2_svc(
47787c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
47797c478bd9Sstevel@tonic-gate mdrpc_setlock_res *res,
47807c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
47817c478bd9Sstevel@tonic-gate )
47827c478bd9Sstevel@tonic-gate {
47837c478bd9Sstevel@tonic-gate return (mdrpc_lock_set_common(args, res, rqstp));
47847c478bd9Sstevel@tonic-gate }
47857c478bd9Sstevel@tonic-gate
47867c478bd9Sstevel@tonic-gate static void
updmeds(char * setname,md_h_arr_t * medp,int version,md_error_t * ep)47877c478bd9Sstevel@tonic-gate updmeds(
47887c478bd9Sstevel@tonic-gate char *setname,
47897c478bd9Sstevel@tonic-gate md_h_arr_t *medp,
47907c478bd9Sstevel@tonic-gate int version, /* RPC version of calling routine */
47917c478bd9Sstevel@tonic-gate md_error_t *ep
47927c478bd9Sstevel@tonic-gate )
47937c478bd9Sstevel@tonic-gate {
47947c478bd9Sstevel@tonic-gate mddb_userreq_t req;
47957c478bd9Sstevel@tonic-gate md_set_record *sr;
47967c478bd9Sstevel@tonic-gate mddb_med_parm_t mp;
47977c478bd9Sstevel@tonic-gate
47987c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
47997c478bd9Sstevel@tonic-gate return;
48007c478bd9Sstevel@tonic-gate
48017c478bd9Sstevel@tonic-gate sr->sr_med = *medp; /* structure assignment */
48027c478bd9Sstevel@tonic-gate
48037c478bd9Sstevel@tonic-gate (void) memset(&req, '\0', sizeof (req));
48047c478bd9Sstevel@tonic-gate
48057c478bd9Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
48067c478bd9Sstevel@tonic-gate /* Do MN operation if rpc version supports it and if a MN set */
48077c478bd9Sstevel@tonic-gate if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
48087c478bd9Sstevel@tonic-gate req.ur_size = sizeof (struct md_mnset_record);
48097c478bd9Sstevel@tonic-gate } else {
48107c478bd9Sstevel@tonic-gate req.ur_size = sizeof (*sr);
48117c478bd9Sstevel@tonic-gate }
48127c478bd9Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
48137c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
48147c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
48157c478bd9Sstevel@tonic-gate free_sr(sr);
48167c478bd9Sstevel@tonic-gate return;
48177c478bd9Sstevel@tonic-gate }
48187c478bd9Sstevel@tonic-gate
48197c478bd9Sstevel@tonic-gate commitset(sr, TRUE, ep);
48207c478bd9Sstevel@tonic-gate
48217c478bd9Sstevel@tonic-gate /*
48227c478bd9Sstevel@tonic-gate * If a MN disket, send the mediator list to the kernel.
48237c478bd9Sstevel@tonic-gate */
48247c478bd9Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
48257c478bd9Sstevel@tonic-gate (void) memset(&mp, '\0', sizeof (mddb_med_parm_t));
48267c478bd9Sstevel@tonic-gate mp.med_setno = sr->sr_setno;
48277c478bd9Sstevel@tonic-gate if (meta_h2hi(medp, &mp.med, ep)) {
48287c478bd9Sstevel@tonic-gate free_sr(sr);
48297c478bd9Sstevel@tonic-gate return;
48307c478bd9Sstevel@tonic-gate }
48317c478bd9Sstevel@tonic-gate
48327c478bd9Sstevel@tonic-gate /* Resolve the IP addresses for the host list */
48337c478bd9Sstevel@tonic-gate if (meta_med_hnm2ip(&mp.med, ep)) {
48347c478bd9Sstevel@tonic-gate free_sr(sr);
48357c478bd9Sstevel@tonic-gate return;
48367c478bd9Sstevel@tonic-gate }
48377c478bd9Sstevel@tonic-gate
48387c478bd9Sstevel@tonic-gate /* If node not yet joined to set, failure is ok. */
48397c478bd9Sstevel@tonic-gate if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) {
48407c478bd9Sstevel@tonic-gate if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) {
48417c478bd9Sstevel@tonic-gate (void) mdstealerror(ep, &mp.med_mde);
48427c478bd9Sstevel@tonic-gate }
48437c478bd9Sstevel@tonic-gate }
48447c478bd9Sstevel@tonic-gate }
48457c478bd9Sstevel@tonic-gate free_sr(sr);
48467c478bd9Sstevel@tonic-gate }
48477c478bd9Sstevel@tonic-gate
48487c478bd9Sstevel@tonic-gate /*
48497c478bd9Sstevel@tonic-gate * Update the mediator data in the set record
48507c478bd9Sstevel@tonic-gate */
48517c478bd9Sstevel@tonic-gate bool_t
mdrpc_updmeds_common(mdrpc_updmeds_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)48527c478bd9Sstevel@tonic-gate mdrpc_updmeds_common(
48537c478bd9Sstevel@tonic-gate mdrpc_updmeds_args *args,
48547c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
48557c478bd9Sstevel@tonic-gate struct svc_req *rqstp, /* RPC stuff */
48567c478bd9Sstevel@tonic-gate int version /* RPC version */
48577c478bd9Sstevel@tonic-gate )
48587c478bd9Sstevel@tonic-gate {
48597c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
48607c478bd9Sstevel@tonic-gate int err;
48617c478bd9Sstevel@tonic-gate int op_mode = W_OK;
48627c478bd9Sstevel@tonic-gate
48637c478bd9Sstevel@tonic-gate /* setup, check permissions */
48647c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
48657c478bd9Sstevel@tonic-gate return (FALSE);
48667c478bd9Sstevel@tonic-gate else if (err != 0)
48677c478bd9Sstevel@tonic-gate return (TRUE);
48687c478bd9Sstevel@tonic-gate
48697c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
48707c478bd9Sstevel@tonic-gate return (TRUE);
48717c478bd9Sstevel@tonic-gate
48727c478bd9Sstevel@tonic-gate /* doit */
48737c478bd9Sstevel@tonic-gate updmeds(args->sp->setname, &args->meds, version, ep);
48747c478bd9Sstevel@tonic-gate
48757c478bd9Sstevel@tonic-gate err = svc_fini(ep);
48767c478bd9Sstevel@tonic-gate
48777c478bd9Sstevel@tonic-gate return (TRUE);
48787c478bd9Sstevel@tonic-gate }
48797c478bd9Sstevel@tonic-gate
48807c478bd9Sstevel@tonic-gate bool_t
mdrpc_updmeds_1_svc(mdrpc_updmeds_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)48817c478bd9Sstevel@tonic-gate mdrpc_updmeds_1_svc(
48827c478bd9Sstevel@tonic-gate mdrpc_updmeds_args *args,
48837c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
48847c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
48857c478bd9Sstevel@tonic-gate )
48867c478bd9Sstevel@tonic-gate {
48872a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
48887c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION) to common routine */
48897c478bd9Sstevel@tonic-gate return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION));
48907c478bd9Sstevel@tonic-gate }
48917c478bd9Sstevel@tonic-gate
48927c478bd9Sstevel@tonic-gate bool_t
mdrpc_updmeds_2_svc(mdrpc_updmeds_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)48937c478bd9Sstevel@tonic-gate mdrpc_updmeds_2_svc(
48947c478bd9Sstevel@tonic-gate mdrpc_updmeds_2_args *args,
48957c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
48967c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
48977c478bd9Sstevel@tonic-gate )
48987c478bd9Sstevel@tonic-gate {
48992a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
49007c478bd9Sstevel@tonic-gate switch (args->rev) {
49017c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
49027c478bd9Sstevel@tonic-gate /* Pass RPC version (METAD_VERSION_DEVID) to common routine */
49037c478bd9Sstevel@tonic-gate return (mdrpc_updmeds_common(
49047c478bd9Sstevel@tonic-gate &args->mdrpc_updmeds_2_args_u.rev1, res,
49057c478bd9Sstevel@tonic-gate rqstp, METAD_VERSION_DEVID));
49067c478bd9Sstevel@tonic-gate default:
49077c478bd9Sstevel@tonic-gate return (FALSE);
49087c478bd9Sstevel@tonic-gate }
49097c478bd9Sstevel@tonic-gate }
49107c478bd9Sstevel@tonic-gate
49117c478bd9Sstevel@tonic-gate /*
49127c478bd9Sstevel@tonic-gate * Call routines to suspend, reinit and resume mdcommd.
49137c478bd9Sstevel@tonic-gate * Called during metaset and metadb command.
49147c478bd9Sstevel@tonic-gate * NOT called during reconfig cycle.
49157c478bd9Sstevel@tonic-gate */
49167c478bd9Sstevel@tonic-gate bool_t
mdrpc_mdcommdctl_2_svc(mdrpc_mdcommdctl_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)49177c478bd9Sstevel@tonic-gate mdrpc_mdcommdctl_2_svc(
49187c478bd9Sstevel@tonic-gate mdrpc_mdcommdctl_2_args *args,
49197c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
49207c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
49217c478bd9Sstevel@tonic-gate )
49227c478bd9Sstevel@tonic-gate {
49237c478bd9Sstevel@tonic-gate mdrpc_mdcommdctl_args *args_cc;
49247c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
49257c478bd9Sstevel@tonic-gate int err;
49267c478bd9Sstevel@tonic-gate int op_mode = R_OK;
49277c478bd9Sstevel@tonic-gate int suspend_ret;
49287c478bd9Sstevel@tonic-gate
49292a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
49307c478bd9Sstevel@tonic-gate switch (args->rev) {
49317c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
49327c478bd9Sstevel@tonic-gate /* setup, check permissions */
49337c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
49347c478bd9Sstevel@tonic-gate return (FALSE);
49357c478bd9Sstevel@tonic-gate else if (err != 0)
49367c478bd9Sstevel@tonic-gate return (TRUE);
49377c478bd9Sstevel@tonic-gate
49387c478bd9Sstevel@tonic-gate args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1);
49397c478bd9Sstevel@tonic-gate switch (args_cc->flag_action) {
49407c478bd9Sstevel@tonic-gate case COMMDCTL_SUSPEND:
49417c478bd9Sstevel@tonic-gate suspend_ret = mdmn_suspend(args_cc->setno,
4942ab3487b0Sjkennedy args_cc->class, 0);
49437c478bd9Sstevel@tonic-gate if (suspend_ret != 0) {
49447c478bd9Sstevel@tonic-gate (void) mddserror(ep, suspend_ret,
49457c478bd9Sstevel@tonic-gate args_cc->setno, mynode(),
49467c478bd9Sstevel@tonic-gate NULL, mynode());
49477c478bd9Sstevel@tonic-gate }
49487c478bd9Sstevel@tonic-gate break;
49497c478bd9Sstevel@tonic-gate case COMMDCTL_RESUME:
49507c478bd9Sstevel@tonic-gate if (mdmn_resume(args_cc->setno,
4951ab3487b0Sjkennedy args_cc->class, args_cc->flags, 0)) {
49527c478bd9Sstevel@tonic-gate (void) mddserror(ep,
49537c478bd9Sstevel@tonic-gate MDE_DS_COMMDCTL_RESUME_FAIL,
49547c478bd9Sstevel@tonic-gate args_cc->setno, mynode(),
49557c478bd9Sstevel@tonic-gate NULL, mynode());
49567c478bd9Sstevel@tonic-gate }
49577c478bd9Sstevel@tonic-gate break;
49587c478bd9Sstevel@tonic-gate case COMMDCTL_REINIT:
4959ab3487b0Sjkennedy if (mdmn_reinit_set(args_cc->setno, 0)) {
49607c478bd9Sstevel@tonic-gate (void) mddserror(ep,
49617c478bd9Sstevel@tonic-gate MDE_DS_COMMDCTL_REINIT_FAIL,
49627c478bd9Sstevel@tonic-gate args_cc->setno, mynode(),
49637c478bd9Sstevel@tonic-gate NULL, mynode());
49647c478bd9Sstevel@tonic-gate }
49657c478bd9Sstevel@tonic-gate break;
49667c478bd9Sstevel@tonic-gate }
49677c478bd9Sstevel@tonic-gate err = svc_fini(ep);
49687c478bd9Sstevel@tonic-gate return (TRUE);
49697c478bd9Sstevel@tonic-gate
49707c478bd9Sstevel@tonic-gate default:
49717c478bd9Sstevel@tonic-gate return (FALSE);
49727c478bd9Sstevel@tonic-gate }
49737c478bd9Sstevel@tonic-gate }
49747c478bd9Sstevel@tonic-gate
49757c478bd9Sstevel@tonic-gate /*
49767c478bd9Sstevel@tonic-gate * Return TRUE if set is stale.
49777c478bd9Sstevel@tonic-gate */
49787c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_is_stale_2_svc(mdrpc_setno_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)49797c478bd9Sstevel@tonic-gate mdrpc_mn_is_stale_2_svc(
49807c478bd9Sstevel@tonic-gate mdrpc_setno_2_args *args,
49817c478bd9Sstevel@tonic-gate mdrpc_bool_res *res,
49827c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
49837c478bd9Sstevel@tonic-gate )
49847c478bd9Sstevel@tonic-gate {
49857c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
49867c478bd9Sstevel@tonic-gate mddb_config_t c;
49877c478bd9Sstevel@tonic-gate int err;
49887c478bd9Sstevel@tonic-gate int op_mode = R_OK;
49897c478bd9Sstevel@tonic-gate
49902a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
49917c478bd9Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c));
49927c478bd9Sstevel@tonic-gate switch (args->rev) {
49937c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
49947c478bd9Sstevel@tonic-gate c.c_id = 0;
49957c478bd9Sstevel@tonic-gate c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno;
49967c478bd9Sstevel@tonic-gate
49977c478bd9Sstevel@tonic-gate /* setup, check permissions */
49987c478bd9Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
49997c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
50007c478bd9Sstevel@tonic-gate return (FALSE);
50017c478bd9Sstevel@tonic-gate else if (err != 0)
50027c478bd9Sstevel@tonic-gate return (TRUE);
50037c478bd9Sstevel@tonic-gate
50047c478bd9Sstevel@tonic-gate if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
5005*80148899SSurya Prakki (void) mdstealerror(ep, &c.c_mde);
50067c478bd9Sstevel@tonic-gate return (TRUE);
50077c478bd9Sstevel@tonic-gate }
50087c478bd9Sstevel@tonic-gate
50097c478bd9Sstevel@tonic-gate if (c.c_flags & MDDB_C_STALE) {
50107c478bd9Sstevel@tonic-gate res->value = TRUE;
50117c478bd9Sstevel@tonic-gate } else {
50127c478bd9Sstevel@tonic-gate res->value = FALSE;
50137c478bd9Sstevel@tonic-gate }
50147c478bd9Sstevel@tonic-gate
50157c478bd9Sstevel@tonic-gate err = svc_fini(ep);
50167c478bd9Sstevel@tonic-gate return (TRUE);
50177c478bd9Sstevel@tonic-gate
50187c478bd9Sstevel@tonic-gate default:
50197c478bd9Sstevel@tonic-gate return (FALSE);
50207c478bd9Sstevel@tonic-gate }
50217c478bd9Sstevel@tonic-gate }
50227c478bd9Sstevel@tonic-gate
50237c478bd9Sstevel@tonic-gate /*
50247c478bd9Sstevel@tonic-gate * Clear out all clnt_locks held by all MN disksets.
50257c478bd9Sstevel@tonic-gate * This is only used during a reconfig cycle.
50267c478bd9Sstevel@tonic-gate */
50277c478bd9Sstevel@tonic-gate /* ARGSUSED */
5028b6c8bd52Sjeanm int
mdrpc_clr_mnsetlock_2_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)50297c478bd9Sstevel@tonic-gate mdrpc_clr_mnsetlock_2_svc(
50307c478bd9Sstevel@tonic-gate mdrpc_null_args *args,
50317c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
50327c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
50337c478bd9Sstevel@tonic-gate )
50347c478bd9Sstevel@tonic-gate {
50357c478bd9Sstevel@tonic-gate set_t max_sets, setno;
50367c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
50377c478bd9Sstevel@tonic-gate int err;
50387c478bd9Sstevel@tonic-gate int op_mode = W_OK;
50397c478bd9Sstevel@tonic-gate mdsetname_t *sp;
50407c478bd9Sstevel@tonic-gate
50417c478bd9Sstevel@tonic-gate /* setup, check permissions */
50427c478bd9Sstevel@tonic-gate (void) memset(res, 0, sizeof (*res));
50437c478bd9Sstevel@tonic-gate
50447c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
50457c478bd9Sstevel@tonic-gate return (FALSE);
50467c478bd9Sstevel@tonic-gate else if (err != 0)
50477c478bd9Sstevel@tonic-gate return (TRUE);
50487c478bd9Sstevel@tonic-gate
50497c478bd9Sstevel@tonic-gate /*
50507c478bd9Sstevel@tonic-gate * Walk through all possible disksets.
50517c478bd9Sstevel@tonic-gate * For each MN set, delete all keys associated with that set.
50527c478bd9Sstevel@tonic-gate */
50537c478bd9Sstevel@tonic-gate if ((max_sets = get_max_sets(ep)) == 0) {
50547c478bd9Sstevel@tonic-gate return (TRUE);
50557c478bd9Sstevel@tonic-gate }
50567c478bd9Sstevel@tonic-gate
50577c478bd9Sstevel@tonic-gate /* start walking through all possible disksets */
50587c478bd9Sstevel@tonic-gate for (setno = 1; setno < max_sets; setno++) {
50597c478bd9Sstevel@tonic-gate if ((sp = metasetnosetname(setno, ep)) == NULL) {
50607c478bd9Sstevel@tonic-gate if (mdiserror(ep, MDE_NO_SET)) {
50617c478bd9Sstevel@tonic-gate /* No set for this setno - continue */
50627c478bd9Sstevel@tonic-gate mdclrerror(ep);
50637c478bd9Sstevel@tonic-gate continue;
50647c478bd9Sstevel@tonic-gate } else {
50657c478bd9Sstevel@tonic-gate mde_perror(ep, gettext(
50667c478bd9Sstevel@tonic-gate "Unable to get set %s information"),
50677c478bd9Sstevel@tonic-gate sp->setname);
50687c478bd9Sstevel@tonic-gate mdclrerror(ep);
50697c478bd9Sstevel@tonic-gate continue;
50707c478bd9Sstevel@tonic-gate }
50717c478bd9Sstevel@tonic-gate }
50727c478bd9Sstevel@tonic-gate
50737c478bd9Sstevel@tonic-gate /* only check multi-node disksets */
50747c478bd9Sstevel@tonic-gate if (!meta_is_mn_set(sp, ep)) {
50757c478bd9Sstevel@tonic-gate mdclrerror(ep);
50767c478bd9Sstevel@tonic-gate continue;
50777c478bd9Sstevel@tonic-gate }
50787c478bd9Sstevel@tonic-gate
50797c478bd9Sstevel@tonic-gate /* Delete keys associated with rpc.metad clnt_lock */
50807c478bd9Sstevel@tonic-gate del_sk(setno);
50817c478bd9Sstevel@tonic-gate }
50827c478bd9Sstevel@tonic-gate
50837c478bd9Sstevel@tonic-gate *ep = mdnullerror;
50847c478bd9Sstevel@tonic-gate
50857c478bd9Sstevel@tonic-gate err = svc_fini(ep);
50867c478bd9Sstevel@tonic-gate
50877c478bd9Sstevel@tonic-gate return (TRUE);
50887c478bd9Sstevel@tonic-gate }
50897c478bd9Sstevel@tonic-gate
50907c478bd9Sstevel@tonic-gate /*
50917c478bd9Sstevel@tonic-gate * Get drive desc on this host for given setno.
50927c478bd9Sstevel@tonic-gate * This is only used during a reconfig cycle.
50937c478bd9Sstevel@tonic-gate * Returns a drive desc structure for the given mdsetname
50947c478bd9Sstevel@tonic-gate * from this host.
50957c478bd9Sstevel@tonic-gate *
50967c478bd9Sstevel@tonic-gate * Returned drive desc structure is partially filled in with
50977c478bd9Sstevel@tonic-gate * the drive name but is not filled in with any other strings
50987c478bd9Sstevel@tonic-gate * in the drivename structure.
50997c478bd9Sstevel@tonic-gate */
51007c478bd9Sstevel@tonic-gate bool_t
mdrpc_getdrivedesc_2_svc(mdrpc_sp_2_args * args,mdrpc_getdrivedesc_res * res,struct svc_req * rqstp)51017c478bd9Sstevel@tonic-gate mdrpc_getdrivedesc_2_svc(
51027c478bd9Sstevel@tonic-gate mdrpc_sp_2_args *args,
51037c478bd9Sstevel@tonic-gate mdrpc_getdrivedesc_res *res,
51047c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
51057c478bd9Sstevel@tonic-gate )
51067c478bd9Sstevel@tonic-gate {
51077c478bd9Sstevel@tonic-gate md_drive_desc *dd;
51087c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
51097c478bd9Sstevel@tonic-gate int err;
51107c478bd9Sstevel@tonic-gate int op_mode = R_OK;
51117c478bd9Sstevel@tonic-gate mdsetname_t *my_sp;
51127c478bd9Sstevel@tonic-gate mdrpc_sp_args *args_r1;
51137c478bd9Sstevel@tonic-gate
51142a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
51157c478bd9Sstevel@tonic-gate switch (args->rev) {
51167c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
51177c478bd9Sstevel@tonic-gate /* setup, check permissions */
51187c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
51197c478bd9Sstevel@tonic-gate return (FALSE);
51207c478bd9Sstevel@tonic-gate else if (err != 0)
51217c478bd9Sstevel@tonic-gate return (TRUE);
51227c478bd9Sstevel@tonic-gate
51237c478bd9Sstevel@tonic-gate /* doit */
51247c478bd9Sstevel@tonic-gate args_r1 = &args->mdrpc_sp_2_args_u.rev1;
51257c478bd9Sstevel@tonic-gate if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL)
51267c478bd9Sstevel@tonic-gate return (TRUE);
51277c478bd9Sstevel@tonic-gate
51287c478bd9Sstevel@tonic-gate dd = metaget_drivedesc(my_sp,
51297c478bd9Sstevel@tonic-gate (MD_BASICNAME_OK | PRINT_FAST), ep);
51307c478bd9Sstevel@tonic-gate
51317c478bd9Sstevel@tonic-gate res->dd = dd_list_dup(dd);
51327c478bd9Sstevel@tonic-gate
51337c478bd9Sstevel@tonic-gate err = svc_fini(ep);
51347c478bd9Sstevel@tonic-gate
51357c478bd9Sstevel@tonic-gate return (TRUE);
51367c478bd9Sstevel@tonic-gate default:
51377c478bd9Sstevel@tonic-gate return (FALSE);
51387c478bd9Sstevel@tonic-gate }
51397c478bd9Sstevel@tonic-gate }
51407c478bd9Sstevel@tonic-gate
51417c478bd9Sstevel@tonic-gate /*
51427c478bd9Sstevel@tonic-gate * Update drive records given list from master during reconfig.
51437c478bd9Sstevel@tonic-gate * Make this node's list match the master's list which may include
51447c478bd9Sstevel@tonic-gate * deleting a drive record that is known by this node and not known
51457c478bd9Sstevel@tonic-gate * by the master node.
51467c478bd9Sstevel@tonic-gate *
51477c478bd9Sstevel@tonic-gate * Sync up the set/node/drive record genids to match the genid
51487c478bd9Sstevel@tonic-gate * passed in the dd structure (all genids in this structure
51497c478bd9Sstevel@tonic-gate * are the same).
51507c478bd9Sstevel@tonic-gate */
51517c478bd9Sstevel@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)51527c478bd9Sstevel@tonic-gate mdrpc_upd_dr_reconfig_common(
51537c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args_r1 *args,
51547c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
51557c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
51567c478bd9Sstevel@tonic-gate )
51577c478bd9Sstevel@tonic-gate {
51587c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
51597c478bd9Sstevel@tonic-gate int err;
51607c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
51617c478bd9Sstevel@tonic-gate md_set_record *sr;
51627c478bd9Sstevel@tonic-gate md_mnset_record *mnsr;
51637c478bd9Sstevel@tonic-gate md_drive_record *dr, *dr_placeholder = NULL;
51647c478bd9Sstevel@tonic-gate md_drive_desc *dd;
51657c478bd9Sstevel@tonic-gate mddrivename_t *dn, *dn1;
51667c478bd9Sstevel@tonic-gate side_t sideno;
51677c478bd9Sstevel@tonic-gate md_mnnode_record *nrp;
51687c478bd9Sstevel@tonic-gate int op_mode = W_OK;
51697c478bd9Sstevel@tonic-gate int change = 0;
51707c478bd9Sstevel@tonic-gate
51717c478bd9Sstevel@tonic-gate /* setup, check permissions */
51727c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
51737c478bd9Sstevel@tonic-gate return (FALSE);
51747c478bd9Sstevel@tonic-gate else if (err != 0)
51757c478bd9Sstevel@tonic-gate return (TRUE);
51767c478bd9Sstevel@tonic-gate
51777c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(args->sp->setname, ep)) == NULL)
51787c478bd9Sstevel@tonic-gate return (TRUE);
51797c478bd9Sstevel@tonic-gate
51807c478bd9Sstevel@tonic-gate metaflushsetname(local_sp);
51817c478bd9Sstevel@tonic-gate
51827c478bd9Sstevel@tonic-gate if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
51837c478bd9Sstevel@tonic-gate return (TRUE);
51847c478bd9Sstevel@tonic-gate
51857c478bd9Sstevel@tonic-gate if ((sr = getsetbyname(args->sp->setname, ep)) == NULL)
51867c478bd9Sstevel@tonic-gate return (TRUE);
51877c478bd9Sstevel@tonic-gate
51887c478bd9Sstevel@tonic-gate if (!(MD_MNSET_REC(sr))) {
51897c478bd9Sstevel@tonic-gate free_sr(sr);
51907c478bd9Sstevel@tonic-gate return (TRUE);
51917c478bd9Sstevel@tonic-gate }
51927c478bd9Sstevel@tonic-gate
51937c478bd9Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
51947c478bd9Sstevel@tonic-gate /* Setup genid on set and node records */
51957c478bd9Sstevel@tonic-gate if (args->drivedescs) {
51967c478bd9Sstevel@tonic-gate if (mnsr->sr_genid != args->drivedescs->dd_genid) {
51977c478bd9Sstevel@tonic-gate change = 1;
51987c478bd9Sstevel@tonic-gate mnsr->sr_genid = args->drivedescs->dd_genid;
51997c478bd9Sstevel@tonic-gate }
52007c478bd9Sstevel@tonic-gate nrp = mnsr->sr_nodechain;
52017c478bd9Sstevel@tonic-gate while (nrp) {
52027c478bd9Sstevel@tonic-gate if (nrp->nr_genid != args->drivedescs->dd_genid) {
52037c478bd9Sstevel@tonic-gate change = 1;
52047c478bd9Sstevel@tonic-gate nrp->nr_genid = args->drivedescs->dd_genid;
52057c478bd9Sstevel@tonic-gate }
52067c478bd9Sstevel@tonic-gate nrp = nrp->nr_next;
52077c478bd9Sstevel@tonic-gate }
52087c478bd9Sstevel@tonic-gate }
52097c478bd9Sstevel@tonic-gate for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) {
52107c478bd9Sstevel@tonic-gate dn1 = metadrivename_withdrkey(local_sp, sideno,
52117c478bd9Sstevel@tonic-gate dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep);
52127c478bd9Sstevel@tonic-gate if (dn1 == NULL)
52137c478bd9Sstevel@tonic-gate goto out;
52147c478bd9Sstevel@tonic-gate for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) {
52157c478bd9Sstevel@tonic-gate dn = dd->dd_dnp;
52167c478bd9Sstevel@tonic-gate /* Found this node's drive rec to match dd */
52177c478bd9Sstevel@tonic-gate if (strcmp(dn->cname, dn1->cname) == 0)
52187c478bd9Sstevel@tonic-gate break;
52197c478bd9Sstevel@tonic-gate }
52207c478bd9Sstevel@tonic-gate
52217c478bd9Sstevel@tonic-gate /*
52227c478bd9Sstevel@tonic-gate * If drive found in master's list, make slave match master.
52237c478bd9Sstevel@tonic-gate * If drive not found in master's list, remove drive.
52247c478bd9Sstevel@tonic-gate */
52257c478bd9Sstevel@tonic-gate if (dd) {
52267c478bd9Sstevel@tonic-gate if ((dr->dr_flags != dd->dd_flags) ||
52277c478bd9Sstevel@tonic-gate (dr->dr_genid != dd->dd_genid)) {
52287c478bd9Sstevel@tonic-gate change = 1;
52297c478bd9Sstevel@tonic-gate dr->dr_flags = dd->dd_flags;
52307c478bd9Sstevel@tonic-gate dr->dr_genid = dd->dd_genid;
52317c478bd9Sstevel@tonic-gate }
52327c478bd9Sstevel@tonic-gate } else {
52337c478bd9Sstevel@tonic-gate /*
52347c478bd9Sstevel@tonic-gate * Delete entry from linked list. Need to use
52357c478bd9Sstevel@tonic-gate * dr_placeholder so that dr->dr_next points to
52367c478bd9Sstevel@tonic-gate * the next drive record in the list.
52377c478bd9Sstevel@tonic-gate */
52387c478bd9Sstevel@tonic-gate if (dr_placeholder == NULL) {
52397c478bd9Sstevel@tonic-gate dr_placeholder =
52407c478bd9Sstevel@tonic-gate Zalloc(sizeof (md_drive_record));
52417c478bd9Sstevel@tonic-gate }
52427c478bd9Sstevel@tonic-gate dr_placeholder->dr_next = dr->dr_next;
52437c478bd9Sstevel@tonic-gate dr_placeholder->dr_key = dr->dr_key;
52447c478bd9Sstevel@tonic-gate sr_del_drv(sr, dr->dr_selfid);
52457c478bd9Sstevel@tonic-gate (void) del_sideno_sidenm(dr_placeholder->dr_key,
52467c478bd9Sstevel@tonic-gate sideno, ep);
52477c478bd9Sstevel@tonic-gate change = 1;
52487c478bd9Sstevel@tonic-gate dr = dr_placeholder;
52497c478bd9Sstevel@tonic-gate }
52507c478bd9Sstevel@tonic-gate }
52517c478bd9Sstevel@tonic-gate out:
52527c478bd9Sstevel@tonic-gate /* If incore records are correct, don't need to write to disk */
52537c478bd9Sstevel@tonic-gate if (change) {
52547c478bd9Sstevel@tonic-gate /* Don't increment the genid in commitset */
52557c478bd9Sstevel@tonic-gate commitset(sr, FALSE, ep);
52567c478bd9Sstevel@tonic-gate }
52577c478bd9Sstevel@tonic-gate free_sr(sr);
52587c478bd9Sstevel@tonic-gate
52597c478bd9Sstevel@tonic-gate err = svc_fini(ep);
52607c478bd9Sstevel@tonic-gate
52617c478bd9Sstevel@tonic-gate if (dr_placeholder != NULL)
52627c478bd9Sstevel@tonic-gate Free(dr_placeholder);
52637c478bd9Sstevel@tonic-gate
52647c478bd9Sstevel@tonic-gate return (TRUE);
52657c478bd9Sstevel@tonic-gate }
52667c478bd9Sstevel@tonic-gate
52677c478bd9Sstevel@tonic-gate /*
52687c478bd9Sstevel@tonic-gate * Version 2 routine to update this node's drive records based on
52697c478bd9Sstevel@tonic-gate * list passed in from master node.
52707c478bd9Sstevel@tonic-gate */
52717c478bd9Sstevel@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)52727c478bd9Sstevel@tonic-gate mdrpc_upd_dr_reconfig_2_svc(
52737c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_args *args,
52747c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
52757c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
52767c478bd9Sstevel@tonic-gate )
52777c478bd9Sstevel@tonic-gate {
52782a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
52797c478bd9Sstevel@tonic-gate switch (args->rev) {
52807c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
52817c478bd9Sstevel@tonic-gate return (mdrpc_upd_dr_reconfig_common(
52827c478bd9Sstevel@tonic-gate &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
52837c478bd9Sstevel@tonic-gate default:
52847c478bd9Sstevel@tonic-gate return (FALSE);
52857c478bd9Sstevel@tonic-gate }
52867c478bd9Sstevel@tonic-gate }
52877c478bd9Sstevel@tonic-gate
52887c478bd9Sstevel@tonic-gate /*
52897c478bd9Sstevel@tonic-gate * reset mirror owner for mirrors owned by deleted
52907c478bd9Sstevel@tonic-gate * or withdrawn host(s). Hosts being deleted or
52917c478bd9Sstevel@tonic-gate * withdrawn are designated by nodeid since host is
52927c478bd9Sstevel@tonic-gate * already deleted or withdrawn from set and may not
52937c478bd9Sstevel@tonic-gate * be able to translate between a nodename and a nodeid.
52947c478bd9Sstevel@tonic-gate * If an error occurs, ep will be set to that error information.
52957c478bd9Sstevel@tonic-gate */
52967c478bd9Sstevel@tonic-gate static void
reset_mirror_owner(char * setname,int node_c,int * node_id,md_error_t * ep)52977c478bd9Sstevel@tonic-gate reset_mirror_owner(
52987c478bd9Sstevel@tonic-gate char *setname,
52997c478bd9Sstevel@tonic-gate int node_c,
53007c478bd9Sstevel@tonic-gate int *node_id, /* Array of node ids */
53017c478bd9Sstevel@tonic-gate md_error_t *ep
53027c478bd9Sstevel@tonic-gate )
53037c478bd9Sstevel@tonic-gate {
53047c478bd9Sstevel@tonic-gate mdsetname_t *local_sp;
53057c478bd9Sstevel@tonic-gate int i;
53067c478bd9Sstevel@tonic-gate mdnamelist_t *devnlp = NULL;
53077c478bd9Sstevel@tonic-gate mdnamelist_t *p;
53087c478bd9Sstevel@tonic-gate mdname_t *devnp = NULL;
53097c478bd9Sstevel@tonic-gate md_set_mmown_params_t ownpar_p;
53107c478bd9Sstevel@tonic-gate md_set_mmown_params_t *ownpar = &ownpar_p;
53117c478bd9Sstevel@tonic-gate char *miscname;
53127c478bd9Sstevel@tonic-gate
53137c478bd9Sstevel@tonic-gate if ((local_sp = metasetname(setname, ep)) == NULL)
53147c478bd9Sstevel@tonic-gate return;
53157c478bd9Sstevel@tonic-gate
53167c478bd9Sstevel@tonic-gate /* get a list of all the mirrors for current set */
53177c478bd9Sstevel@tonic-gate if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0)
53187c478bd9Sstevel@tonic-gate return;
53197c478bd9Sstevel@tonic-gate
53207c478bd9Sstevel@tonic-gate /* for each mirror */
53217c478bd9Sstevel@tonic-gate for (p = devnlp; (p != NULL); p = p->next) {
53227c478bd9Sstevel@tonic-gate devnp = p->namep;
53237c478bd9Sstevel@tonic-gate
53247c478bd9Sstevel@tonic-gate /*
53257c478bd9Sstevel@tonic-gate * we can only do these for mirrors so make sure we
53267c478bd9Sstevel@tonic-gate * really have a mirror device and not a softpartition
53277c478bd9Sstevel@tonic-gate * imitating one. meta_get_mirror_names seems to think
53287c478bd9Sstevel@tonic-gate * softparts on top of a mirror are mirrors!
53297c478bd9Sstevel@tonic-gate */
53307c478bd9Sstevel@tonic-gate if ((miscname = metagetmiscname(devnp, ep)) == NULL)
53317c478bd9Sstevel@tonic-gate goto out;
53327c478bd9Sstevel@tonic-gate if (strcmp(miscname, MD_MIRROR) != 0)
53337c478bd9Sstevel@tonic-gate continue;
53347c478bd9Sstevel@tonic-gate
53357c478bd9Sstevel@tonic-gate (void) memset(ownpar, 0, sizeof (*ownpar));
53367c478bd9Sstevel@tonic-gate ownpar->d.mnum = meta_getminor(devnp->dev);
53377c478bd9Sstevel@tonic-gate MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno);
53387c478bd9Sstevel@tonic-gate
53397c478bd9Sstevel@tonic-gate /* get the current owner id */
53407c478bd9Sstevel@tonic-gate if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep,
53417c478bd9Sstevel@tonic-gate "MD_MN_GET_MM_OWNER") != 0) {
53427c478bd9Sstevel@tonic-gate mde_perror(ep, gettext(
5343d7cd8252Stw21770 "Unable to get mirror owner for %s/%s"),
53447c478bd9Sstevel@tonic-gate local_sp->setname,
5345d7cd8252Stw21770 get_mdname(local_sp, ownpar->d.mnum));
53467c478bd9Sstevel@tonic-gate goto out;
53477c478bd9Sstevel@tonic-gate }
53487c478bd9Sstevel@tonic-gate
53497c478bd9Sstevel@tonic-gate if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) {
53507c478bd9Sstevel@tonic-gate mdclrerror(ep);
53517c478bd9Sstevel@tonic-gate continue;
53527c478bd9Sstevel@tonic-gate }
53537c478bd9Sstevel@tonic-gate /*
53547c478bd9Sstevel@tonic-gate * reset owner only if the current owner is
53557c478bd9Sstevel@tonic-gate * in the list of nodes being deleted.
53567c478bd9Sstevel@tonic-gate */
53577c478bd9Sstevel@tonic-gate for (i = 0; i < node_c; i++) {
53587c478bd9Sstevel@tonic-gate if (ownpar->d.owner == node_id[i]) {
53597c478bd9Sstevel@tonic-gate if (meta_mn_change_owner(&ownpar,
53607c478bd9Sstevel@tonic-gate local_sp->setno, ownpar->d.mnum,
53617c478bd9Sstevel@tonic-gate MD_MN_MIRROR_UNOWNED,
53627c478bd9Sstevel@tonic-gate MD_MN_MM_ALLOW_CHANGE) == -1) {
53637c478bd9Sstevel@tonic-gate mde_perror(ep, gettext(
53647c478bd9Sstevel@tonic-gate "Unable to reset mirror owner for"
5365d7cd8252Stw21770 " %s/%s"), local_sp->setname,
5366d7cd8252Stw21770 get_mdname(local_sp,
53677c478bd9Sstevel@tonic-gate ownpar->d.mnum));
53687c478bd9Sstevel@tonic-gate goto out;
53697c478bd9Sstevel@tonic-gate }
53707c478bd9Sstevel@tonic-gate break;
53717c478bd9Sstevel@tonic-gate }
53727c478bd9Sstevel@tonic-gate }
53737c478bd9Sstevel@tonic-gate }
53747c478bd9Sstevel@tonic-gate
53757c478bd9Sstevel@tonic-gate out:
53767c478bd9Sstevel@tonic-gate /* cleanup */
53777c478bd9Sstevel@tonic-gate metafreenamelist(devnlp);
53787c478bd9Sstevel@tonic-gate }
53797c478bd9Sstevel@tonic-gate
53807c478bd9Sstevel@tonic-gate /*
53817c478bd9Sstevel@tonic-gate * Wrapper routine for reset_mirror_owner.
53827c478bd9Sstevel@tonic-gate * Called when hosts are deleted or withdrawn
53837c478bd9Sstevel@tonic-gate * in order to reset any mirror owners that are needed.
53847c478bd9Sstevel@tonic-gate */
53857c478bd9Sstevel@tonic-gate bool_t
mdrpc_reset_mirror_owner_common(mdrpc_nodeid_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)53867c478bd9Sstevel@tonic-gate mdrpc_reset_mirror_owner_common(
53877c478bd9Sstevel@tonic-gate mdrpc_nodeid_args *args,
53887c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
53897c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
53907c478bd9Sstevel@tonic-gate )
53917c478bd9Sstevel@tonic-gate {
53927c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
53937c478bd9Sstevel@tonic-gate int err;
53947c478bd9Sstevel@tonic-gate int op_mode = W_OK;
53957c478bd9Sstevel@tonic-gate
53967c478bd9Sstevel@tonic-gate /* setup, check permissions */
53977c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
53987c478bd9Sstevel@tonic-gate return (FALSE);
53997c478bd9Sstevel@tonic-gate else if (err != 0)
54007c478bd9Sstevel@tonic-gate return (TRUE);
54017c478bd9Sstevel@tonic-gate
54027c478bd9Sstevel@tonic-gate if (check_set_lock(op_mode, args->cl_sk, ep))
54037c478bd9Sstevel@tonic-gate return (TRUE);
54047c478bd9Sstevel@tonic-gate
54057c478bd9Sstevel@tonic-gate /* doit */
54067c478bd9Sstevel@tonic-gate reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len,
54077c478bd9Sstevel@tonic-gate args->nodeid.nodeid_val, ep);
54087c478bd9Sstevel@tonic-gate
54097c478bd9Sstevel@tonic-gate err = svc_fini(ep);
54107c478bd9Sstevel@tonic-gate
54117c478bd9Sstevel@tonic-gate return (TRUE);
54127c478bd9Sstevel@tonic-gate }
54137c478bd9Sstevel@tonic-gate
54147c478bd9Sstevel@tonic-gate /*
54157c478bd9Sstevel@tonic-gate * RPC service routine to reset the mirror owner for mirrors owned
54167c478bd9Sstevel@tonic-gate * by the given hosts. Typically, the list of given hosts is a list
54177c478bd9Sstevel@tonic-gate * of nodes being deleted or withdrawn from a diskset.
54187c478bd9Sstevel@tonic-gate * The given hosts are designated by nodeid since host may
54197c478bd9Sstevel@tonic-gate * already be deleted or withdrawn from set and may not
54207c478bd9Sstevel@tonic-gate * be able to translate between a nodename and a nodeid.
54217c478bd9Sstevel@tonic-gate */
54227c478bd9Sstevel@tonic-gate bool_t
mdrpc_reset_mirror_owner_2_svc(mdrpc_nodeid_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54237c478bd9Sstevel@tonic-gate mdrpc_reset_mirror_owner_2_svc(
54247c478bd9Sstevel@tonic-gate mdrpc_nodeid_2_args *args,
54257c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
54267c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
54277c478bd9Sstevel@tonic-gate )
54287c478bd9Sstevel@tonic-gate {
54292a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
54307c478bd9Sstevel@tonic-gate switch (args->rev) {
54317c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
54327c478bd9Sstevel@tonic-gate return (mdrpc_reset_mirror_owner_common(
54337c478bd9Sstevel@tonic-gate &args->mdrpc_nodeid_2_args_u.rev1, res,
54347c478bd9Sstevel@tonic-gate rqstp));
54357c478bd9Sstevel@tonic-gate default:
54367c478bd9Sstevel@tonic-gate return (FALSE);
54377c478bd9Sstevel@tonic-gate }
54387c478bd9Sstevel@tonic-gate }
54397c478bd9Sstevel@tonic-gate
54407c478bd9Sstevel@tonic-gate /*
54417c478bd9Sstevel@tonic-gate * Call routines to suspend and resume I/O for the given diskset(s).
54427c478bd9Sstevel@tonic-gate * Called during reconfig cycle.
54437c478bd9Sstevel@tonic-gate * Diskset of 0 represents all MN disksets.
54447c478bd9Sstevel@tonic-gate */
54457c478bd9Sstevel@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)54467c478bd9Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_svc(
54477c478bd9Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_args *args,
54487c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
54497c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
54507c478bd9Sstevel@tonic-gate )
54517c478bd9Sstevel@tonic-gate {
54527c478bd9Sstevel@tonic-gate mdrpc_mn_susp_res_io_args *args_sr;
54537c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
54547c478bd9Sstevel@tonic-gate int err;
54557c478bd9Sstevel@tonic-gate int op_mode = R_OK;
54567c478bd9Sstevel@tonic-gate
54572a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
54587c478bd9Sstevel@tonic-gate switch (args->rev) {
54597c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
54607c478bd9Sstevel@tonic-gate /* setup, check permissions */
54617c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
54627c478bd9Sstevel@tonic-gate return (FALSE);
54637c478bd9Sstevel@tonic-gate else if (err != 0)
54647c478bd9Sstevel@tonic-gate return (TRUE);
54657c478bd9Sstevel@tonic-gate
54667c478bd9Sstevel@tonic-gate args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1);
54677c478bd9Sstevel@tonic-gate switch (args_sr->susp_res_cmd) {
54687c478bd9Sstevel@tonic-gate case MN_SUSP_IO:
54697c478bd9Sstevel@tonic-gate (void) (metaioctl(MD_MN_SUSPEND_SET,
54707c478bd9Sstevel@tonic-gate &args_sr->susp_res_setno, ep, NULL));
54717c478bd9Sstevel@tonic-gate break;
54727c478bd9Sstevel@tonic-gate case MN_RES_IO:
54737c478bd9Sstevel@tonic-gate (void) (metaioctl(MD_MN_RESUME_SET,
54747c478bd9Sstevel@tonic-gate &args_sr->susp_res_setno, ep, NULL));
54757c478bd9Sstevel@tonic-gate break;
54767c478bd9Sstevel@tonic-gate }
54777c478bd9Sstevel@tonic-gate err = svc_fini(ep);
54787c478bd9Sstevel@tonic-gate return (TRUE);
54797c478bd9Sstevel@tonic-gate
54807c478bd9Sstevel@tonic-gate default:
54817c478bd9Sstevel@tonic-gate return (FALSE);
54827c478bd9Sstevel@tonic-gate }
54837c478bd9Sstevel@tonic-gate }
54847c478bd9Sstevel@tonic-gate
54857c478bd9Sstevel@tonic-gate /*
54867c478bd9Sstevel@tonic-gate * Resnarf a set after it has been imported
54877c478bd9Sstevel@tonic-gate */
54887c478bd9Sstevel@tonic-gate bool_t
mdrpc_resnarf_set_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54897c478bd9Sstevel@tonic-gate mdrpc_resnarf_set_2_svc(
54907c478bd9Sstevel@tonic-gate mdrpc_setno_2_args *args,
54917c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
54927c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
54937c478bd9Sstevel@tonic-gate )
54947c478bd9Sstevel@tonic-gate {
54957c478bd9Sstevel@tonic-gate mdrpc_setno_args *setno_args;
54967c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
54977c478bd9Sstevel@tonic-gate int err;
54987c478bd9Sstevel@tonic-gate int op_mode = R_OK;
54997c478bd9Sstevel@tonic-gate
55002a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
55017c478bd9Sstevel@tonic-gate switch (args->rev) {
55027c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
55037c478bd9Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1;
55047c478bd9Sstevel@tonic-gate break;
55057c478bd9Sstevel@tonic-gate default:
55067c478bd9Sstevel@tonic-gate return (FALSE);
55077c478bd9Sstevel@tonic-gate }
55087c478bd9Sstevel@tonic-gate
55097c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55107c478bd9Sstevel@tonic-gate return (FALSE);
55117c478bd9Sstevel@tonic-gate else if (err != 0)
55127c478bd9Sstevel@tonic-gate return (TRUE);
55137c478bd9Sstevel@tonic-gate
55147c478bd9Sstevel@tonic-gate /* do it */
55157c478bd9Sstevel@tonic-gate if (resnarf_set(setno_args->setno, ep) < 0)
55167c478bd9Sstevel@tonic-gate return (FALSE);
55177c478bd9Sstevel@tonic-gate
55187c478bd9Sstevel@tonic-gate err = svc_fini(ep);
55197c478bd9Sstevel@tonic-gate return (TRUE);
55207c478bd9Sstevel@tonic-gate }
55217c478bd9Sstevel@tonic-gate
55227c478bd9Sstevel@tonic-gate /*
55237c478bd9Sstevel@tonic-gate * Creates a resync thread.
55247c478bd9Sstevel@tonic-gate * Always returns true.
55257c478bd9Sstevel@tonic-gate */
55267c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_mirror_resync_all_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)55277c478bd9Sstevel@tonic-gate mdrpc_mn_mirror_resync_all_2_svc(
55287c478bd9Sstevel@tonic-gate mdrpc_setno_2_args *args,
55297c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
55307c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
55317c478bd9Sstevel@tonic-gate )
55327c478bd9Sstevel@tonic-gate {
55337c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
55347c478bd9Sstevel@tonic-gate mdrpc_setno_args *setno_args;
55357c478bd9Sstevel@tonic-gate int err;
55367c478bd9Sstevel@tonic-gate int op_mode = R_OK;
55377c478bd9Sstevel@tonic-gate
55382a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
55397c478bd9Sstevel@tonic-gate switch (args->rev) {
55407c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
55417c478bd9Sstevel@tonic-gate /* setup, check permissions */
55427c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55437c478bd9Sstevel@tonic-gate return (FALSE);
55447c478bd9Sstevel@tonic-gate else if (err != 0)
55457c478bd9Sstevel@tonic-gate return (TRUE);
55467c478bd9Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1;
55477c478bd9Sstevel@tonic-gate
55487c478bd9Sstevel@tonic-gate /*
55497c478bd9Sstevel@tonic-gate * Need to invoke a metasync on a node newly added to a set.
55507c478bd9Sstevel@tonic-gate */
5551*80148899SSurya Prakki (void) meta_mn_mirror_resync_all(&(setno_args->setno));
55527c478bd9Sstevel@tonic-gate
55537c478bd9Sstevel@tonic-gate err = svc_fini(ep);
55547c478bd9Sstevel@tonic-gate return (TRUE);
55557c478bd9Sstevel@tonic-gate
55567c478bd9Sstevel@tonic-gate default:
55577c478bd9Sstevel@tonic-gate return (FALSE);
55587c478bd9Sstevel@tonic-gate }
55597c478bd9Sstevel@tonic-gate }
55607c478bd9Sstevel@tonic-gate
55617c478bd9Sstevel@tonic-gate /*
55627c478bd9Sstevel@tonic-gate * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(),
55637c478bd9Sstevel@tonic-gate * which forks a daemon process to perform this action.
55647c478bd9Sstevel@tonic-gate * Always returns true.
55657c478bd9Sstevel@tonic-gate */
55667c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_sp_update_abr_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)55677c478bd9Sstevel@tonic-gate mdrpc_mn_sp_update_abr_2_svc(
55687c478bd9Sstevel@tonic-gate mdrpc_setno_2_args *args,
55697c478bd9Sstevel@tonic-gate mdrpc_generic_res *res,
55707c478bd9Sstevel@tonic-gate struct svc_req *rqstp /* RPC stuff */
55717c478bd9Sstevel@tonic-gate )
55727c478bd9Sstevel@tonic-gate {
55737c478bd9Sstevel@tonic-gate md_error_t *ep = &res->status;
55747c478bd9Sstevel@tonic-gate mdrpc_setno_args *setno_args;
55757c478bd9Sstevel@tonic-gate int err;
55767c478bd9Sstevel@tonic-gate int op_mode = R_OK;
55777c478bd9Sstevel@tonic-gate
55782a1e69baSabalfour (void) memset(res, 0, sizeof (*res));
55797c478bd9Sstevel@tonic-gate switch (args->rev) {
55807c478bd9Sstevel@tonic-gate case MD_METAD_ARGS_REV_1:
55817c478bd9Sstevel@tonic-gate /* setup, check permissions */
55827c478bd9Sstevel@tonic-gate if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55837c478bd9Sstevel@tonic-gate return (FALSE);
55847c478bd9Sstevel@tonic-gate else if (err != 0)
55857c478bd9Sstevel@tonic-gate return (TRUE);
55867c478bd9Sstevel@tonic-gate setno_args = &args->mdrpc_setno_2_args_u.rev1;
55877c478bd9Sstevel@tonic-gate
5588*80148899SSurya Prakki (void) meta_mn_sp_update_abr(&(setno_args->setno));
55897c478bd9Sstevel@tonic-gate
55907c478bd9Sstevel@tonic-gate err = svc_fini(ep);
55917c478bd9Sstevel@tonic-gate return (TRUE);
55927c478bd9Sstevel@tonic-gate
55937c478bd9Sstevel@tonic-gate default:
55947c478bd9Sstevel@tonic-gate return (FALSE);
55957c478bd9Sstevel@tonic-gate }
55967c478bd9Sstevel@tonic-gate }
5597