10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51094Sjkennedy * Common Development and Distribution License (the "License").
61094Sjkennedy * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
222063Shshaw * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * Just in case we're not in a build environment, make sure that
300Sstevel@tonic-gate * TEXT_DOMAIN gets set to something.
310Sstevel@tonic-gate */
320Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
330Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
340Sstevel@tonic-gate #endif
350Sstevel@tonic-gate
360Sstevel@tonic-gate /*
370Sstevel@tonic-gate * interface between user land and the set records
380Sstevel@tonic-gate */
390Sstevel@tonic-gate
400Sstevel@tonic-gate #include <meta.h>
410Sstevel@tonic-gate #include <metad.h>
420Sstevel@tonic-gate #include <sdssc.h>
430Sstevel@tonic-gate #include <syslog.h>
440Sstevel@tonic-gate #include <sys/cladm.h>
450Sstevel@tonic-gate #include "meta_set_prv.h"
460Sstevel@tonic-gate
470Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h>
480Sstevel@tonic-gate #include <sys/sysevent/svm.h>
490Sstevel@tonic-gate
500Sstevel@tonic-gate static md_set_record *setrecords = NULL; /* head of cache linked list */
510Sstevel@tonic-gate static int setsnarfdone = 0;
520Sstevel@tonic-gate
530Sstevel@tonic-gate typedef struct key_lst_t {
540Sstevel@tonic-gate side_t kl_side;
550Sstevel@tonic-gate mdkey_t kl_key;
560Sstevel@tonic-gate struct key_lst_t *kl_next;
570Sstevel@tonic-gate } key_lst_t;
580Sstevel@tonic-gate
590Sstevel@tonic-gate typedef struct ur_recid_lst {
600Sstevel@tonic-gate mddb_recid_t url_recid;
610Sstevel@tonic-gate struct ur_recid_lst *url_nx;
620Sstevel@tonic-gate } ur_recid_lst_t;
630Sstevel@tonic-gate
640Sstevel@tonic-gate static ur_recid_lst_t *url_used = NULL;
650Sstevel@tonic-gate static ur_recid_lst_t *url_tode = NULL;
660Sstevel@tonic-gate
670Sstevel@tonic-gate static void
url_addl(ur_recid_lst_t ** urlpp,mddb_recid_t recid)680Sstevel@tonic-gate url_addl(ur_recid_lst_t **urlpp, mddb_recid_t recid)
690Sstevel@tonic-gate {
700Sstevel@tonic-gate /* Run to the end of the list */
710Sstevel@tonic-gate for (/* void */; (*urlpp != NULL); urlpp = &(*urlpp)->url_nx)
720Sstevel@tonic-gate if ((*urlpp)->url_recid == recid)
730Sstevel@tonic-gate return;
740Sstevel@tonic-gate
750Sstevel@tonic-gate /* Add the new member */
760Sstevel@tonic-gate *urlpp = Zalloc(sizeof (**urlpp));
770Sstevel@tonic-gate if (*urlpp == NULL)
780Sstevel@tonic-gate return;
790Sstevel@tonic-gate
800Sstevel@tonic-gate (*urlpp)->url_recid = recid;
810Sstevel@tonic-gate }
820Sstevel@tonic-gate
830Sstevel@tonic-gate static int
url_findl(ur_recid_lst_t * urlp,mddb_recid_t recid)840Sstevel@tonic-gate url_findl(ur_recid_lst_t *urlp, mddb_recid_t recid)
850Sstevel@tonic-gate {
860Sstevel@tonic-gate while (urlp != NULL) {
870Sstevel@tonic-gate if (urlp->url_recid == recid)
880Sstevel@tonic-gate return (1);
890Sstevel@tonic-gate urlp = urlp->url_nx;
900Sstevel@tonic-gate }
910Sstevel@tonic-gate return (0);
920Sstevel@tonic-gate }
930Sstevel@tonic-gate
940Sstevel@tonic-gate static void
url_freel(ur_recid_lst_t ** urlpp)950Sstevel@tonic-gate url_freel(ur_recid_lst_t **urlpp)
960Sstevel@tonic-gate {
970Sstevel@tonic-gate ur_recid_lst_t *urlp;
980Sstevel@tonic-gate ur_recid_lst_t *turlp;
990Sstevel@tonic-gate
1000Sstevel@tonic-gate for (turlp = *urlpp; turlp != NULL; turlp = urlp) {
1010Sstevel@tonic-gate urlp = turlp->url_nx;
1020Sstevel@tonic-gate Free(turlp);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate *urlpp = (ur_recid_lst_t *)NULL;
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate static int
ckncvt_set_record(mddb_userreq_t * reqp,md_error_t * ep)1080Sstevel@tonic-gate ckncvt_set_record(mddb_userreq_t *reqp, md_error_t *ep)
1090Sstevel@tonic-gate {
1100Sstevel@tonic-gate mddb_userreq_t req;
1110Sstevel@tonic-gate md_set_record *sr;
1120Sstevel@tonic-gate int recs[3];
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate if (reqp->ur_size == sizeof (*sr))
1150Sstevel@tonic-gate return (0);
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate if (! md_in_daemon) {
1180Sstevel@tonic-gate if (reqp->ur_size >= sizeof (*sr))
1190Sstevel@tonic-gate return (0);
1200Sstevel@tonic-gate
12162Sjeanm reqp->ur_data = (uintptr_t)Realloc((void *)(uintptr_t)
12262Sjeanm reqp->ur_data, sizeof (*sr));
12362Sjeanm (void) memset(
12462Sjeanm ((char *)(uintptr_t)reqp->ur_data) + reqp->ur_size,
12562Sjeanm '\0', sizeof (*sr) - reqp->ur_size);
1260Sstevel@tonic-gate reqp->ur_size = sizeof (*sr);
1270Sstevel@tonic-gate return (0);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate /*
1310Sstevel@tonic-gate * If here, then the daemon is calling, and so the automatic
1320Sstevel@tonic-gate * conversion will be performed.
1330Sstevel@tonic-gate */
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate /* shorthand */
1360Sstevel@tonic-gate req = *reqp; /* structure assignment */
13762Sjeanm sr = (md_set_record *)(uintptr_t)req.ur_data;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate if (sr->sr_flags & MD_SR_CVT)
1400Sstevel@tonic-gate return (0);
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate /* Leave multi-node set records alone */
1430Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
1440Sstevel@tonic-gate return (0);
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate /* Mark the old record as converted */
1480Sstevel@tonic-gate sr->sr_flags |= MD_SR_CVT;
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
1530Sstevel@tonic-gate return (mdstealerror(ep, &req.ur_mde));
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate /* Create space for the new record */
1560Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_CREATE, 0);
1570Sstevel@tonic-gate req.ur_size = sizeof (*sr);
1580Sstevel@tonic-gate
1590Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
1600Sstevel@tonic-gate return (mdstealerror(ep, &req.ur_mde));
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate /* Allocate the new record */
1630Sstevel@tonic-gate sr = Zalloc(sizeof (*sr));
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate /* copy all the data from the record being converted */
16662Sjeanm (void) memmove(sr, (void *)(uintptr_t)reqp->ur_data, reqp->ur_size);
1670Sstevel@tonic-gate sr->sr_flags &= ~MD_SR_CVT;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate /* adjust the selfid to point to the new record */
1700Sstevel@tonic-gate sr->sr_selfid = req.ur_recid;
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
1730Sstevel@tonic-gate req.ur_size = sizeof (*sr);
1740Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
1770Sstevel@tonic-gate Free(sr);
1780Sstevel@tonic-gate return (mdstealerror(ep, &req.ur_mde));
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate /* Commit the old and the new */
18262Sjeanm recs[0] = ((md_set_record *)(uintptr_t)reqp->ur_data)->sr_selfid;
1830Sstevel@tonic-gate recs[1] = sr->sr_selfid;
1840Sstevel@tonic-gate recs[2] = 0;
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate METAD_SETUP_UR(MD_DB_COMMIT_MANY, 0, 0);
1870Sstevel@tonic-gate req.ur_size = sizeof (recs);
1880Sstevel@tonic-gate req.ur_data = (uintptr_t)recs;
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
1910Sstevel@tonic-gate Free(sr);
1920Sstevel@tonic-gate return (mdstealerror(ep, &req.ur_mde));
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate /* Add the the old record to the list of records to delete */
19662Sjeanm url_addl(&url_tode,
19762Sjeanm ((md_set_record *)(uintptr_t)reqp->ur_data)->sr_selfid);
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate /* Free the old records space */
20062Sjeanm Free((void *)(uintptr_t)reqp->ur_data);
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate /* Adjust the reqp structure to point to the new record and size */
2030Sstevel@tonic-gate reqp->ur_recid = sr->sr_selfid;
2040Sstevel@tonic-gate reqp->ur_size = sizeof (*sr);
2050Sstevel@tonic-gate reqp->ur_data = (uintptr_t)sr;
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate return (0);
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate mddb_userreq_t *
get_db_rec(md_ur_get_cmd_t cmd,set_t setno,mddb_type_t type,uint_t type2,mddb_recid_t * idp,md_error_t * ep)2110Sstevel@tonic-gate get_db_rec(
2120Sstevel@tonic-gate md_ur_get_cmd_t cmd,
2130Sstevel@tonic-gate set_t setno,
2140Sstevel@tonic-gate mddb_type_t type,
2150Sstevel@tonic-gate uint_t type2,
2160Sstevel@tonic-gate mddb_recid_t *idp,
2170Sstevel@tonic-gate md_error_t *ep
2180Sstevel@tonic-gate )
2190Sstevel@tonic-gate {
2200Sstevel@tonic-gate mddb_userreq_t *reqp = Zalloc(sizeof (*reqp));
2211094Sjkennedy mdsetname_t *sp;
2221094Sjkennedy md_set_desc *sd;
2231094Sjkennedy int ureq;
2241094Sjkennedy
2251094Sjkennedy if ((sp = metasetnosetname(setno, ep)) == NULL) {
2261094Sjkennedy Free(reqp);
2271094Sjkennedy return (NULL);
2281094Sjkennedy }
2291094Sjkennedy
2301094Sjkennedy if (metaislocalset(sp)) {
2311094Sjkennedy ureq = MD_DB_USERREQ;
2321094Sjkennedy } else {
2331094Sjkennedy if ((sd = metaget_setdesc(sp, ep)) == NULL) {
2341094Sjkennedy Free(reqp);
2351094Sjkennedy return (NULL);
2361094Sjkennedy }
2371094Sjkennedy ureq = MD_MNSET_DESC(sd) ? MD_MN_DB_USERREQ : MD_DB_USERREQ;
2381094Sjkennedy }
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate reqp->ur_setno = setno;
2410Sstevel@tonic-gate reqp->ur_type = type;
2420Sstevel@tonic-gate reqp->ur_type2 = type2;
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate switch (cmd) {
2450Sstevel@tonic-gate case MD_UR_GET_NEXT:
2460Sstevel@tonic-gate reqp->ur_cmd = MD_DB_GETNEXTREC;
2470Sstevel@tonic-gate reqp->ur_recid = *idp;
2481094Sjkennedy if (metaioctl(ureq, reqp, &reqp->ur_mde, NULL)
2490Sstevel@tonic-gate != 0) {
2500Sstevel@tonic-gate (void) mdstealerror(ep, &reqp->ur_mde);
2510Sstevel@tonic-gate Free(reqp);
2520Sstevel@tonic-gate return (NULL);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate *idp = reqp->ur_recid;
2550Sstevel@tonic-gate break;
2560Sstevel@tonic-gate case MD_UR_GET_WKEY:
2570Sstevel@tonic-gate reqp->ur_recid = *idp;
2580Sstevel@tonic-gate break;
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate
2610Sstevel@tonic-gate if (*idp <= 0) {
2620Sstevel@tonic-gate Free(reqp);
2630Sstevel@tonic-gate return (NULL);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate reqp->ur_cmd = MD_DB_GETSIZE;
2671094Sjkennedy if (metaioctl(ureq, reqp, &reqp->ur_mde, NULL) != 0) {
2680Sstevel@tonic-gate (void) mdstealerror(ep, &reqp->ur_mde);
2690Sstevel@tonic-gate Free(reqp);
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate *idp = 0;
2720Sstevel@tonic-gate return (NULL);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate reqp->ur_cmd = MD_DB_GETDATA;
2760Sstevel@tonic-gate reqp->ur_data = (uintptr_t)Zalloc(reqp->ur_size);
2771094Sjkennedy if (metaioctl(ureq, reqp, &reqp->ur_mde, NULL) != 0) {
2780Sstevel@tonic-gate (void) mdstealerror(ep, &reqp->ur_mde);
27962Sjeanm Free((void *)(uintptr_t)reqp->ur_data);
2800Sstevel@tonic-gate Free(reqp);
2810Sstevel@tonic-gate *idp = 0;
2820Sstevel@tonic-gate return (NULL);
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate switch (reqp->ur_type) {
2860Sstevel@tonic-gate case MDDB_USER:
2870Sstevel@tonic-gate switch (reqp->ur_type2) {
2880Sstevel@tonic-gate case MDDB_UR_SR:
2890Sstevel@tonic-gate if (ckncvt_set_record(reqp, ep)) {
29062Sjeanm Free((void *)(uintptr_t)reqp->ur_data);
2910Sstevel@tonic-gate Free(reqp);
2920Sstevel@tonic-gate return (NULL);
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate break;
2950Sstevel@tonic-gate }
2960Sstevel@tonic-gate break;
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate return (reqp);
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate void *
get_ur_rec(set_t setno,md_ur_get_cmd_t cmd,uint_t type2,mddb_recid_t * idp,md_error_t * ep)3030Sstevel@tonic-gate get_ur_rec(
3040Sstevel@tonic-gate set_t setno,
3050Sstevel@tonic-gate md_ur_get_cmd_t cmd,
3060Sstevel@tonic-gate uint_t type2,
3070Sstevel@tonic-gate mddb_recid_t *idp,
3080Sstevel@tonic-gate md_error_t *ep
3090Sstevel@tonic-gate )
3100Sstevel@tonic-gate {
3110Sstevel@tonic-gate mddb_userreq_t *reqp = NULL;
3120Sstevel@tonic-gate void *ret_val;
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate assert(idp != NULL);
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate reqp = get_db_rec(cmd, setno, MDDB_USER, type2, idp, ep);
3170Sstevel@tonic-gate if (reqp == NULL)
3180Sstevel@tonic-gate return (NULL);
3190Sstevel@tonic-gate
32062Sjeanm ret_val = (void *)(uintptr_t)reqp->ur_data;
3210Sstevel@tonic-gate Free(reqp);
3220Sstevel@tonic-gate return (ret_val);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate /*
3260Sstevel@tonic-gate * Called by rpc.metad on startup of disksets to cleanup
3270Sstevel@tonic-gate * the host entries associated with a diskset. This is needed if
3280Sstevel@tonic-gate * a node failed or the metaset command was killed during the addition
3290Sstevel@tonic-gate * of a node to a diskset.
3300Sstevel@tonic-gate *
3310Sstevel@tonic-gate * This is called for all traditional disksets.
3320Sstevel@tonic-gate * This is only called for MNdisksets when in there is only one node
3330Sstevel@tonic-gate * in all of the MN disksets and this node is not running SunCluster.
3340Sstevel@tonic-gate * (Otherwise, the cleanup of the host entries is handled by a
3350Sstevel@tonic-gate * reconfig cycle that the SunCluster software calls).
3360Sstevel@tonic-gate */
3370Sstevel@tonic-gate static int
sr_hosts(md_set_record * sr)3380Sstevel@tonic-gate sr_hosts(md_set_record *sr)
3390Sstevel@tonic-gate {
3400Sstevel@tonic-gate int i,
341*3165Spetede nid = 0,
3420Sstevel@tonic-gate self_in_set = FALSE;
3430Sstevel@tonic-gate md_error_t xep = mdnullerror;
3440Sstevel@tonic-gate md_mnnode_record *nr;
3450Sstevel@tonic-gate md_mnset_record *mnsr;
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
3480Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
3490Sstevel@tonic-gate nr = mnsr->sr_nodechain;
3500Sstevel@tonic-gate /*
3510Sstevel@tonic-gate * Already guaranteed to be only 1 node in set which
3520Sstevel@tonic-gate * is mynode (done in sr_validate).
3530Sstevel@tonic-gate * Now, check if node is in the OK state. If not in
3540Sstevel@tonic-gate * the OK state, leave self_in_set FALSE so that
3550Sstevel@tonic-gate * set will be removed.
3560Sstevel@tonic-gate */
3570Sstevel@tonic-gate if (nr->nr_flags & MD_MN_NODE_OK)
3580Sstevel@tonic-gate self_in_set = TRUE;
3590Sstevel@tonic-gate } else {
3600Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
3610Sstevel@tonic-gate /* Skip empty slots */
3620Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
3630Sstevel@tonic-gate continue;
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate /* Make sure we are in the set and skip this node */
3660Sstevel@tonic-gate if (strcmp(sr->sr_nodes[i], mynode()) == 0) {
3670Sstevel@tonic-gate self_in_set = TRUE;
3680Sstevel@tonic-gate break;
3690Sstevel@tonic-gate }
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate
3732063Shshaw if ((self_in_set == FALSE) && (!(MD_MNSET_REC(sr)))) {
3740Sstevel@tonic-gate /*
375*3165Spetede * Under some circumstances (/etc/cluster/nodeid file is
376*3165Spetede * missing) it is possible for the call to _cladm() to
377*3165Spetede * return 0 and a nid of 0. In this instance do not remove
378*3165Spetede * the set as it is Sun Cluster error that needs to be fixed.
3790Sstevel@tonic-gate */
380*3165Spetede if (_cladm(CL_CONFIG, CL_NODEID, &nid) == 0 && nid > 0) {
381*3165Spetede
382*3165Spetede /*
383*3165Spetede * See if we've got a node which has been booted in
384*3165Spetede * non-cluster mode. If true the nodeid will match
385*3165Spetede * one of the sr_nodes values because the conversion
386*3165Spetede * from nodeid to hostname failed to occur.
387*3165Spetede */
388*3165Spetede for (i = 0; i < MD_MAXSIDES; i++) {
389*3165Spetede if (sr->sr_nodes[i][0] == 0)
390*3165Spetede continue;
391*3165Spetede if (atoi(sr->sr_nodes[i]) == nid)
392*3165Spetede self_in_set = TRUE;
393*3165Spetede }
3940Sstevel@tonic-gate
395*3165Spetede /* If we aren't in the set, delete the set */
396*3165Spetede if (self_in_set == FALSE) {
397*3165Spetede syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
398*3165Spetede "Removing set %s from database\n"),
399*3165Spetede sr->sr_setname);
400*3165Spetede s_delset(sr->sr_setname, &xep);
401*3165Spetede if (! mdisok(&xep))
402*3165Spetede mdclrerror(&xep);
403*3165Spetede return (1);
404*3165Spetede }
405*3165Spetede } else {
406*3165Spetede /*
407*3165Spetede * Send a message to syslog and return without
408*3165Spetede * deleting any sets
409*3165Spetede */
4102063Shshaw syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
411*3165Spetede "Call to _cladm failed for set %s nodeid %d\n"),
412*3165Spetede sr->sr_setname, nid);
4132063Shshaw return (1);
4142063Shshaw }
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate return (0);
4170Sstevel@tonic-gate }
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate void
sr_del_drv(md_set_record * sr,mddb_recid_t recid)4200Sstevel@tonic-gate sr_del_drv(md_set_record *sr, mddb_recid_t recid)
4210Sstevel@tonic-gate {
4220Sstevel@tonic-gate mddb_userreq_t req;
4230Sstevel@tonic-gate md_error_t xep = mdnullerror;
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate if (!s_ownset(sr->sr_setno, &xep)) {
4260Sstevel@tonic-gate if (! mdisok(&xep))
4270Sstevel@tonic-gate mdclrerror(&xep);
4280Sstevel@tonic-gate goto skip;
4290Sstevel@tonic-gate }
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate /* delete the replicas? */
4320Sstevel@tonic-gate /* release ownership of the drive? */
4330Sstevel@tonic-gate /* NOTE: We may not have a name, so both of the above are ugly! */
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate skip:
4360Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
4370Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_DELETE, recid)
4380Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
4390Sstevel@tonic-gate mdclrerror(&req.ur_mde);
4400Sstevel@tonic-gate
4410Sstevel@tonic-gate dr_cache_del(sr, recid);
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate static void
sr_drvs(md_set_record * sr)4450Sstevel@tonic-gate sr_drvs(md_set_record *sr)
4460Sstevel@tonic-gate {
4470Sstevel@tonic-gate md_drive_record *dr;
4480Sstevel@tonic-gate int i;
4490Sstevel@tonic-gate int modified = 0;
4500Sstevel@tonic-gate int sidesok;
4510Sstevel@tonic-gate mdnm_params_t nm;
4520Sstevel@tonic-gate static char device_name[MAXPATHLEN];
4530Sstevel@tonic-gate md_error_t xep = mdnullerror;
4540Sstevel@tonic-gate md_mnnode_record *nr;
4550Sstevel@tonic-gate md_mnset_record *mnsr;
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr != NULL; dr = dr->dr_next) {
4580Sstevel@tonic-gate /* If we were mid-add, cleanup */
4590Sstevel@tonic-gate if ((dr->dr_flags & MD_DR_ADD)) {
4600Sstevel@tonic-gate sr_del_drv(sr, dr->dr_selfid);
4610Sstevel@tonic-gate modified++;
4620Sstevel@tonic-gate continue;
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate sidesok = TRUE;
4660Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
4670Sstevel@tonic-gate mnsr = (md_mnset_record *)sr;
4680Sstevel@tonic-gate nr = mnsr->sr_nodechain;
4690Sstevel@tonic-gate /*
4700Sstevel@tonic-gate * MultiNode disksets only have entries for
4710Sstevel@tonic-gate * their side in the local set. Verify
4720Sstevel@tonic-gate * that drive has a name associated with
4730Sstevel@tonic-gate * this node's side.
4740Sstevel@tonic-gate */
4750Sstevel@tonic-gate while (nr) {
4760Sstevel@tonic-gate /* Find my node */
4770Sstevel@tonic-gate if (strcmp(mynode(), nr->nr_nodename) != 0) {
4780Sstevel@tonic-gate nr = nr->nr_next;
4790Sstevel@tonic-gate continue;
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm));
4830Sstevel@tonic-gate nm.setno = MD_LOCAL_SET;
4840Sstevel@tonic-gate nm.side = nr->nr_nodeid;
4850Sstevel@tonic-gate nm.key = dr->dr_key;
4860Sstevel@tonic-gate nm.devname = (uint64_t)device_name;
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NM, &nm, &nm.mde,
4890Sstevel@tonic-gate NULL) != 0) {
4900Sstevel@tonic-gate if (! mdissyserror(&nm.mde, ENOENT)) {
4910Sstevel@tonic-gate mdclrerror(&nm.mde);
4920Sstevel@tonic-gate return;
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate /*
4970Sstevel@tonic-gate * If entry is found for this node, then
4980Sstevel@tonic-gate * break out of loop walking through
4990Sstevel@tonic-gate * node list. For a multi-node diskset,
5000Sstevel@tonic-gate * there should only be an entry for
5010Sstevel@tonic-gate * this node.
5020Sstevel@tonic-gate */
5030Sstevel@tonic-gate if (nm.key != MD_KEYWILD &&
5040Sstevel@tonic-gate ! mdissyserror(&nm.mde, ENOENT)) {
5050Sstevel@tonic-gate break;
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate /*
5090Sstevel@tonic-gate * If entry is not found for this node,
5100Sstevel@tonic-gate * then delete the drive. No need to
5110Sstevel@tonic-gate * continue through the node loop since
5120Sstevel@tonic-gate * our node has already been found.
5130Sstevel@tonic-gate */
5140Sstevel@tonic-gate sidesok = FALSE;
5150Sstevel@tonic-gate mdclrerror(&nm.mde);
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate /* If we are missing a sidename, cleanup */
5180Sstevel@tonic-gate sr_del_drv(sr, dr->dr_selfid);
5190Sstevel@tonic-gate modified++;
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate break;
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate } else {
5240Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
5250Sstevel@tonic-gate /* Skip empty slots */
5260Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
5270Sstevel@tonic-gate continue;
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm));
5300Sstevel@tonic-gate nm.setno = MD_LOCAL_SET;
5310Sstevel@tonic-gate nm.side = i + SKEW;
5320Sstevel@tonic-gate nm.key = dr->dr_key;
5330Sstevel@tonic-gate nm.devname = (uint64_t)device_name;
5340Sstevel@tonic-gate
5350Sstevel@tonic-gate if (metaioctl(MD_IOCGET_NM, &nm, &nm.mde,
5360Sstevel@tonic-gate NULL) != 0) {
5370Sstevel@tonic-gate if (! mdissyserror(&nm.mde, ENOENT)) {
5380Sstevel@tonic-gate mdclrerror(&nm.mde);
5390Sstevel@tonic-gate return;
5400Sstevel@tonic-gate }
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate if (nm.key != MD_KEYWILD &&
5440Sstevel@tonic-gate ! mdissyserror(&nm.mde, ENOENT))
5450Sstevel@tonic-gate continue;
5460Sstevel@tonic-gate
5470Sstevel@tonic-gate sidesok = FALSE;
5480Sstevel@tonic-gate mdclrerror(&nm.mde);
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate /* If we are missing a sidename, cleanup */
5510Sstevel@tonic-gate sr_del_drv(sr, dr->dr_selfid);
5520Sstevel@tonic-gate modified++;
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate break;
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate if (sidesok == FALSE)
5590Sstevel@tonic-gate continue;
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate /*
5620Sstevel@tonic-gate * If we got this far, the drive record is either in the OK
5630Sstevel@tonic-gate * or DEL state, if it is in the DEL state and the sidenames
5640Sstevel@tonic-gate * all checked out, then we will make it OK.
5650Sstevel@tonic-gate */
5660Sstevel@tonic-gate if ((dr->dr_flags & MD_DR_OK))
5670Sstevel@tonic-gate continue;
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate dr->dr_flags = MD_DR_OK;
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate modified++;
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate if (modified) {
5750Sstevel@tonic-gate commitset(sr, FALSE, &xep);
5760Sstevel@tonic-gate if (! mdisok(&xep))
5770Sstevel@tonic-gate mdclrerror(&xep);
5780Sstevel@tonic-gate }
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate static void
add_key_to_lst(key_lst_t ** klpp,side_t side,mdkey_t key)5820Sstevel@tonic-gate add_key_to_lst(key_lst_t **klpp, side_t side, mdkey_t key)
5830Sstevel@tonic-gate {
5840Sstevel@tonic-gate key_lst_t *klp;
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate assert(klpp != NULL);
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate for (/* void */; *klpp != NULL; klpp = &(*klpp)->kl_next)
5890Sstevel@tonic-gate /* void */;
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate /* allocate new list element */
5920Sstevel@tonic-gate klp = *klpp = Zalloc(sizeof (*klp));
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate klp->kl_side = side;
5950Sstevel@tonic-gate klp->kl_key = key;
5960Sstevel@tonic-gate }
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate #ifdef DUMPKEYLST
5990Sstevel@tonic-gate static void
pr_key_lst(char * tag,key_lst_t * klp)6000Sstevel@tonic-gate pr_key_lst(char *tag, key_lst_t *klp)
6010Sstevel@tonic-gate {
6020Sstevel@tonic-gate key_lst_t *tklp;
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate md_eprintf("Tag=%s\n", tag);
6050Sstevel@tonic-gate for (tklp = klp; tklp != NULL; tklp = tklp->kl_next)
6060Sstevel@tonic-gate md_eprintf("side=%d, key=%lu\n", tklp->kl_side, tklp->kl_key);
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate #endif /* DUMPKEYLST */
6090Sstevel@tonic-gate
6100Sstevel@tonic-gate static int
key_in_key_lst(key_lst_t * klp,side_t side,mdkey_t key)6110Sstevel@tonic-gate key_in_key_lst(key_lst_t *klp, side_t side, mdkey_t key)
6120Sstevel@tonic-gate {
6130Sstevel@tonic-gate key_lst_t *tklp;
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate for (tklp = klp; tklp != NULL; tklp = tklp->kl_next)
6160Sstevel@tonic-gate if (tklp->kl_side == side && tklp->kl_key == key)
6170Sstevel@tonic-gate return (1);
6180Sstevel@tonic-gate
6190Sstevel@tonic-gate return (0);
6200Sstevel@tonic-gate }
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate static void
destroy_key_lst(key_lst_t ** klpp)6230Sstevel@tonic-gate destroy_key_lst(key_lst_t **klpp)
6240Sstevel@tonic-gate {
6250Sstevel@tonic-gate key_lst_t *tklp, *klp;
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate assert(klpp != NULL);
6280Sstevel@tonic-gate
6290Sstevel@tonic-gate tklp = klp = *klpp;
6300Sstevel@tonic-gate while (klp != NULL) {
6310Sstevel@tonic-gate tklp = klp;
6320Sstevel@tonic-gate klp = klp->kl_next;
6330Sstevel@tonic-gate Free(tklp);
6340Sstevel@tonic-gate }
6350Sstevel@tonic-gate *klpp = NULL;
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate
6380Sstevel@tonic-gate static void
sr_sidenms(void)6390Sstevel@tonic-gate sr_sidenms(void)
6400Sstevel@tonic-gate {
6410Sstevel@tonic-gate md_drive_record *dr;
6420Sstevel@tonic-gate md_set_record *sr;
6430Sstevel@tonic-gate key_lst_t *use = NULL;
6440Sstevel@tonic-gate mdnm_params_t nm;
6450Sstevel@tonic-gate int i;
6460Sstevel@tonic-gate md_mnset_record *mnsr;
6470Sstevel@tonic-gate md_mnnode_record *nr;
6480Sstevel@tonic-gate side_t myside = 0;
6490Sstevel@tonic-gate
6500Sstevel@tonic-gate /*
6510Sstevel@tonic-gate * We now go through the list of set and drive records collecting
6520Sstevel@tonic-gate * the key/side pairs that are being used.
6530Sstevel@tonic-gate */
6540Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next) {
6550Sstevel@tonic-gate /*
6560Sstevel@tonic-gate * To handle the multi-node diskset case, get the sideno
6570Sstevel@tonic-gate * associated with this node. This sideno will be the
6580Sstevel@tonic-gate * same across all multi-node disksets.
6590Sstevel@tonic-gate */
6600Sstevel@tonic-gate if ((myside == 0) && (MD_MNSET_REC(sr))) {
6610Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
6620Sstevel@tonic-gate nr = mnsr->sr_nodechain;
6630Sstevel@tonic-gate while (nr) {
6640Sstevel@tonic-gate if (strcmp(mynode(), nr->nr_nodename) == 0) {
6650Sstevel@tonic-gate myside = nr->nr_nodeid;
6660Sstevel@tonic-gate break;
6670Sstevel@tonic-gate }
6680Sstevel@tonic-gate nr = nr->nr_next;
6690Sstevel@tonic-gate }
6700Sstevel@tonic-gate /*
6710Sstevel@tonic-gate * If this node is not in this MNset -
6720Sstevel@tonic-gate * then skip this set.
6730Sstevel@tonic-gate */
6740Sstevel@tonic-gate if (!nr) {
6750Sstevel@tonic-gate continue;
6760Sstevel@tonic-gate }
6770Sstevel@tonic-gate }
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate for (dr = sr->sr_drivechain; dr != NULL; dr = dr->dr_next) {
6800Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
6810Sstevel@tonic-gate /*
6820Sstevel@tonic-gate * There are no non-local sidenames in the
6830Sstevel@tonic-gate * local set for a multi-node diskset.
6840Sstevel@tonic-gate */
6850Sstevel@tonic-gate add_key_to_lst(&use, myside, dr->dr_key);
6860Sstevel@tonic-gate } else {
6870Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
6880Sstevel@tonic-gate /* Skip empty slots */
6890Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
6900Sstevel@tonic-gate continue;
6910Sstevel@tonic-gate
6920Sstevel@tonic-gate add_key_to_lst(&use, i + SKEW,
6930Sstevel@tonic-gate dr->dr_key);
6940Sstevel@tonic-gate }
6950Sstevel@tonic-gate }
6960Sstevel@tonic-gate }
6970Sstevel@tonic-gate }
6980Sstevel@tonic-gate
6990Sstevel@tonic-gate #ifdef DUMPKEYLST
7000Sstevel@tonic-gate pr_key_lst("use", use);
7010Sstevel@tonic-gate #endif /* DUMPKEYLST */
7020Sstevel@tonic-gate
7030Sstevel@tonic-gate /*
7040Sstevel@tonic-gate * We take the list above and get all non-local sidenames, checking
7050Sstevel@tonic-gate * each to see if they are in use, if they are not used, we delete them.
7060Sstevel@tonic-gate * Do the check for myside to cover multinode disksets.
7070Sstevel@tonic-gate * Then do the check for MD_MAXSIDES to cover non-multinode disksets.
7080Sstevel@tonic-gate * If any multi-node disksets were present, myside would be non-zero.
7090Sstevel@tonic-gate * myside is the same for all multi-node disksets for this node.
7100Sstevel@tonic-gate */
7110Sstevel@tonic-gate if (myside) {
7120Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm));
7130Sstevel@tonic-gate nm.setno = MD_LOCAL_SET;
7140Sstevel@tonic-gate nm.side = myside;
7150Sstevel@tonic-gate nm.key = MD_KEYWILD;
7160Sstevel@tonic-gate
7170Sstevel@tonic-gate /*CONSTCOND*/
7180Sstevel@tonic-gate while (1) {
7190Sstevel@tonic-gate if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde,
7200Sstevel@tonic-gate NULL) != 0) {
7210Sstevel@tonic-gate mdclrerror(&nm.mde);
7220Sstevel@tonic-gate break;
7230Sstevel@tonic-gate }
7240Sstevel@tonic-gate
7250Sstevel@tonic-gate if (nm.key == MD_KEYWILD)
7260Sstevel@tonic-gate break;
7270Sstevel@tonic-gate
7280Sstevel@tonic-gate if (! key_in_key_lst(use, nm.side, nm.key)) {
7290Sstevel@tonic-gate if (metaioctl(MD_IOCREM_NM, &nm, &nm.mde,
7300Sstevel@tonic-gate NULL) != 0) {
7310Sstevel@tonic-gate mdclrerror(&nm.mde);
7320Sstevel@tonic-gate continue;
7330Sstevel@tonic-gate }
7340Sstevel@tonic-gate }
7350Sstevel@tonic-gate }
7360Sstevel@tonic-gate }
7370Sstevel@tonic-gate /* Now handle the non-multinode disksets */
7380Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
7390Sstevel@tonic-gate (void) memset(&nm, '\0', sizeof (nm));
7400Sstevel@tonic-gate nm.setno = MD_LOCAL_SET;
7410Sstevel@tonic-gate nm.side = i + SKEW;
7420Sstevel@tonic-gate nm.key = MD_KEYWILD;
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate /*CONSTCOND*/
7450Sstevel@tonic-gate while (1) {
7460Sstevel@tonic-gate if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde,
7470Sstevel@tonic-gate NULL) != 0) {
7480Sstevel@tonic-gate mdclrerror(&nm.mde);
7490Sstevel@tonic-gate break;
7500Sstevel@tonic-gate }
7510Sstevel@tonic-gate
7520Sstevel@tonic-gate if (nm.key == MD_KEYWILD)
7530Sstevel@tonic-gate break;
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate if (! key_in_key_lst(use, nm.side, nm.key)) {
7560Sstevel@tonic-gate if (metaioctl(MD_IOCREM_NM, &nm, &nm.mde,
7570Sstevel@tonic-gate NULL) != 0) {
7580Sstevel@tonic-gate mdclrerror(&nm.mde);
7590Sstevel@tonic-gate continue;
7600Sstevel@tonic-gate }
7610Sstevel@tonic-gate }
7620Sstevel@tonic-gate }
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate
7650Sstevel@tonic-gate /* Cleanup */
7660Sstevel@tonic-gate destroy_key_lst(&use);
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate
7690Sstevel@tonic-gate void
sr_validate(void)7700Sstevel@tonic-gate sr_validate(void)
7710Sstevel@tonic-gate {
7720Sstevel@tonic-gate md_set_record *sr;
7730Sstevel@tonic-gate md_error_t xep = mdnullerror;
7740Sstevel@tonic-gate int mnset_single_node;
7750Sstevel@tonic-gate md_mnnode_record *nr;
7760Sstevel@tonic-gate md_mnset_record *mnsr;
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate assert(setsnarfdone != 0);
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate /* We have validated the records already */
7810Sstevel@tonic-gate if (setsnarfdone == 3)
7820Sstevel@tonic-gate return;
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate /*
7850Sstevel@tonic-gate * Check if we are in a single node non-SC3.x environmemnt
7860Sstevel@tonic-gate */
7870Sstevel@tonic-gate mnset_single_node = meta_mn_singlenode();
7880Sstevel@tonic-gate /*
7890Sstevel@tonic-gate * If a possible single_node situation, verify that all
7900Sstevel@tonic-gate * MN disksets have only one node (which is mynode()).
7910Sstevel@tonic-gate */
7920Sstevel@tonic-gate if (mnset_single_node) {
7930Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next) {
7940Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
7950Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
7960Sstevel@tonic-gate nr = mnsr->sr_nodechain;
7970Sstevel@tonic-gate /*
7980Sstevel@tonic-gate * If next pointer is non-null (more than
7990Sstevel@tonic-gate * one node in list) or if the single node
8000Sstevel@tonic-gate * isn't my node - reset single node flag.
8010Sstevel@tonic-gate */
8020Sstevel@tonic-gate if ((nr->nr_next) ||
8030Sstevel@tonic-gate (strcmp(nr->nr_nodename, mynode()) != 0)) {
8040Sstevel@tonic-gate mnset_single_node = 0;
8050Sstevel@tonic-gate break;
8060Sstevel@tonic-gate }
8070Sstevel@tonic-gate }
8080Sstevel@tonic-gate }
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next) {
8120Sstevel@tonic-gate /*
8130Sstevel@tonic-gate * If a MN diskset and not in the single node
8140Sstevel@tonic-gate * situation, then don't validate the MN set.
8150Sstevel@tonic-gate * This is done during a reconfig cycle since all
8160Sstevel@tonic-gate * nodes must take the same action.
8170Sstevel@tonic-gate */
8180Sstevel@tonic-gate if (MD_MNSET_REC(sr) && (mnset_single_node == 0))
8190Sstevel@tonic-gate continue;
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate /* Since we do "partial" snarf's, we only check new entries */
8220Sstevel@tonic-gate if (! (sr->sr_flags & MD_SR_CHECK))
8230Sstevel@tonic-gate continue;
8240Sstevel@tonic-gate
8250Sstevel@tonic-gate /* If we were mid-add, cleanup */
8260Sstevel@tonic-gate if ((sr->sr_flags & MD_SR_ADD)) {
8270Sstevel@tonic-gate s_delset(sr->sr_setname, &xep);
8280Sstevel@tonic-gate if (! mdisok(&xep))
8290Sstevel@tonic-gate mdclrerror(&xep);
8300Sstevel@tonic-gate continue;
8310Sstevel@tonic-gate }
8320Sstevel@tonic-gate
8330Sstevel@tonic-gate /* Make sure we are in the set. */
8340Sstevel@tonic-gate if (sr_hosts(sr))
8350Sstevel@tonic-gate continue;
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate /* Check has been done, clear the flag */
8380Sstevel@tonic-gate if ((sr->sr_flags & MD_SR_CHECK))
8390Sstevel@tonic-gate sr->sr_flags &= ~MD_SR_CHECK;
8400Sstevel@tonic-gate
8410Sstevel@tonic-gate /*
8420Sstevel@tonic-gate * If we got here, we are in the set, make sure the flags make
8430Sstevel@tonic-gate * sense.
8440Sstevel@tonic-gate */
8450Sstevel@tonic-gate if (! (sr->sr_flags & MD_SR_OK)) {
8460Sstevel@tonic-gate sr->sr_flags &= ~MD_SR_STATE_FLAGS;
8470Sstevel@tonic-gate sr->sr_flags |= MD_SR_OK;
8480Sstevel@tonic-gate commitset(sr, FALSE, &xep);
8490Sstevel@tonic-gate if (! mdisok(&xep))
8500Sstevel@tonic-gate mdclrerror(&xep);
8510Sstevel@tonic-gate }
8520Sstevel@tonic-gate
8530Sstevel@tonic-gate /* Make sure all the drives are in a stable state. */
8540Sstevel@tonic-gate sr_drvs(sr);
8550Sstevel@tonic-gate }
8560Sstevel@tonic-gate
8570Sstevel@tonic-gate /* Cleanup any stray sidenames */
8580Sstevel@tonic-gate sr_sidenms();
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate setsnarfdone = 3;
8610Sstevel@tonic-gate }
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate static md_set_record *
sr_in_cache(mddb_recid_t recid)8640Sstevel@tonic-gate sr_in_cache(mddb_recid_t recid)
8650Sstevel@tonic-gate {
8660Sstevel@tonic-gate md_set_record *tsr;
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate for (tsr = setrecords; tsr != NULL; tsr = tsr->sr_next)
8690Sstevel@tonic-gate if (tsr->sr_selfid == recid)
8700Sstevel@tonic-gate return (tsr);
8710Sstevel@tonic-gate return ((md_set_record *)NULL);
8720Sstevel@tonic-gate }
8730Sstevel@tonic-gate
8740Sstevel@tonic-gate int
set_snarf(md_error_t * ep)8750Sstevel@tonic-gate set_snarf(md_error_t *ep)
8760Sstevel@tonic-gate {
8770Sstevel@tonic-gate md_set_record *sr;
8780Sstevel@tonic-gate md_mnset_record *mnsr;
8790Sstevel@tonic-gate md_set_record *tsr;
8800Sstevel@tonic-gate md_drive_record *dr;
8810Sstevel@tonic-gate mddb_userreq_t *reqp;
8820Sstevel@tonic-gate ur_recid_lst_t *urlp;
8830Sstevel@tonic-gate mddb_recid_t id;
8840Sstevel@tonic-gate mddb_recid_t *p;
8850Sstevel@tonic-gate md_error_t xep = mdnullerror;
8860Sstevel@tonic-gate md_mnnode_record *nr;
8870Sstevel@tonic-gate mddb_set_node_params_t snp;
8880Sstevel@tonic-gate int nodecnt;
8890Sstevel@tonic-gate mndiskset_membershiplist_t *nl, *nl2;
8900Sstevel@tonic-gate
8910Sstevel@tonic-gate /* We have done the snarf call */
8920Sstevel@tonic-gate if (setsnarfdone != 0)
8930Sstevel@tonic-gate return (0);
8940Sstevel@tonic-gate
8950Sstevel@tonic-gate if (meta_setup_db_locations(ep) != 0) {
8960Sstevel@tonic-gate if (! mdismddberror(ep, MDE_DB_STALE))
8970Sstevel@tonic-gate return (-1);
8980Sstevel@tonic-gate mdclrerror(ep);
8990Sstevel@tonic-gate }
9000Sstevel@tonic-gate
9010Sstevel@tonic-gate /*
9020Sstevel@tonic-gate * Get membershiplist from API routine.
9030Sstevel@tonic-gate * If there's an error, just use a NULL
9040Sstevel@tonic-gate * nodelist.
9050Sstevel@tonic-gate */
9060Sstevel@tonic-gate if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
9070Sstevel@tonic-gate nodecnt = 0; /* no nodes are alive */
9080Sstevel@tonic-gate nl = NULL;
9090Sstevel@tonic-gate mdclrerror(ep);
9100Sstevel@tonic-gate }
9110Sstevel@tonic-gate
9120Sstevel@tonic-gate /* Let sr_cache_add and dr_cache_add know we are doing the snarf */
9130Sstevel@tonic-gate setsnarfdone = 1;
9140Sstevel@tonic-gate
9150Sstevel@tonic-gate /* Go get the set records */
9160Sstevel@tonic-gate id = 0;
9170Sstevel@tonic-gate while ((sr = get_ur_rec(MD_LOCAL_SET, MD_UR_GET_NEXT, MDDB_UR_SR,
9180Sstevel@tonic-gate &id, ep)) != NULL) {
9190Sstevel@tonic-gate sr->sr_next = NULL;
9200Sstevel@tonic-gate sr->sr_drivechain = NULL;
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate /*
9230Sstevel@tonic-gate * Cluster nodename support
9240Sstevel@tonic-gate * Convert nodeid -> nodename
9250Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
9260Sstevel@tonic-gate * both the nodeid and name.
9270Sstevel@tonic-gate */
9280Sstevel@tonic-gate if (!(MD_MNSET_REC(sr)))
9290Sstevel@tonic-gate sdssc_cm_sr_nid2nm(sr);
9300Sstevel@tonic-gate
9310Sstevel@tonic-gate /* If we were mid-cvt, cleanup */
9320Sstevel@tonic-gate if (sr->sr_flags & MD_SR_CVT) {
9330Sstevel@tonic-gate /* If the daemon is calling, cleanup */
9340Sstevel@tonic-gate if (md_in_daemon)
9350Sstevel@tonic-gate url_addl(&url_tode, sr->sr_selfid);
9360Sstevel@tonic-gate continue;
9370Sstevel@tonic-gate }
9380Sstevel@tonic-gate
9390Sstevel@tonic-gate if (md_in_daemon)
9400Sstevel@tonic-gate url_addl(&url_used, sr->sr_selfid);
9410Sstevel@tonic-gate
9420Sstevel@tonic-gate /* Skip cached records */
9430Sstevel@tonic-gate tsr = sr_in_cache(sr->sr_selfid);
9440Sstevel@tonic-gate if (tsr != (md_set_record *)NULL) {
9450Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
9460Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
9470Sstevel@tonic-gate Free(mnsr);
9480Sstevel@tonic-gate } else {
9490Sstevel@tonic-gate Free(sr);
9500Sstevel@tonic-gate }
9510Sstevel@tonic-gate if (md_in_daemon)
9520Sstevel@tonic-gate for (dr = tsr->sr_drivechain;
9530Sstevel@tonic-gate dr != (md_drive_record *)NULL;
9540Sstevel@tonic-gate dr = dr->dr_next)
9550Sstevel@tonic-gate url_addl(&url_used, dr->dr_selfid);
9560Sstevel@tonic-gate continue;
9570Sstevel@tonic-gate }
9580Sstevel@tonic-gate
9590Sstevel@tonic-gate /* Mark the record as one to be checked */
9600Sstevel@tonic-gate sr->sr_flags |= MD_SR_CHECK;
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate sr_cache_add(sr);
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate /* If MNdiskset, go get the node records */
9650Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
9660Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
9670Sstevel@tonic-gate mnsr->sr_nodechain = NULL;
9680Sstevel@tonic-gate p = &mnsr->sr_noderec;
9690Sstevel@tonic-gate while ((nr = get_ur_rec(MD_LOCAL_SET, MD_UR_GET_WKEY,
9700Sstevel@tonic-gate MDDB_UR_NR, p, ep)) != NULL) {
9710Sstevel@tonic-gate nr->nr_next = NULL;
9720Sstevel@tonic-gate
9730Sstevel@tonic-gate if (md_in_daemon)
9740Sstevel@tonic-gate url_addl(&url_used, nr->nr_selfid);
9750Sstevel@tonic-gate
9760Sstevel@tonic-gate /*
9770Sstevel@tonic-gate * Turn off ALIVE node flag based on member
9780Sstevel@tonic-gate * list.
9790Sstevel@tonic-gate * If ALIVE flag is not set, reset OWN flag.
9800Sstevel@tonic-gate * If this node is mynode, set the OWN flag
9810Sstevel@tonic-gate * to match the ownership of the diskset.
9820Sstevel@tonic-gate */
9830Sstevel@tonic-gate if (md_in_daemon) {
9840Sstevel@tonic-gate nr->nr_flags &= ~MD_MN_NODE_ALIVE;
9850Sstevel@tonic-gate nl2 = nl;
9860Sstevel@tonic-gate while (nl2) {
9870Sstevel@tonic-gate /*
9880Sstevel@tonic-gate * If in member list,
9890Sstevel@tonic-gate * set alive.
9900Sstevel@tonic-gate */
9910Sstevel@tonic-gate if (nl2->msl_node_id ==
9920Sstevel@tonic-gate nr->nr_nodeid) {
9930Sstevel@tonic-gate nr->nr_flags |=
9940Sstevel@tonic-gate MD_MN_NODE_ALIVE;
9950Sstevel@tonic-gate break;
9960Sstevel@tonic-gate }
9970Sstevel@tonic-gate nl2 = nl2->next;
9980Sstevel@tonic-gate }
9990Sstevel@tonic-gate /*
10000Sstevel@tonic-gate * If mynode is in member list, then
10010Sstevel@tonic-gate * check to see if set is snarfed.
10020Sstevel@tonic-gate * If set snarfed, set own flag;
10030Sstevel@tonic-gate * otherwise reset it.
10040Sstevel@tonic-gate * Don't change master even if
10050Sstevel@tonic-gate * node isn't an owner node, since
10060Sstevel@tonic-gate * node may be master, but hasn't
10070Sstevel@tonic-gate * joined the set yet.
10080Sstevel@tonic-gate */
10090Sstevel@tonic-gate if (nr->nr_flags & MD_MN_NODE_ALIVE) {
10100Sstevel@tonic-gate if (strcmp(nr->nr_nodename,
10110Sstevel@tonic-gate mynode()) == 0) {
10120Sstevel@tonic-gate if (s_ownset(
10130Sstevel@tonic-gate mnsr->sr_setno, ep)) {
10140Sstevel@tonic-gate nr->nr_flags |=
10150Sstevel@tonic-gate MD_MN_NODE_OWN;
10160Sstevel@tonic-gate } else {
10170Sstevel@tonic-gate nr->nr_flags &=
10180Sstevel@tonic-gate ~MD_MN_NODE_OWN;
10190Sstevel@tonic-gate }
10200Sstevel@tonic-gate }
10210Sstevel@tonic-gate } else {
10220Sstevel@tonic-gate if (strcmp(nr->nr_nodename,
10230Sstevel@tonic-gate mynode()) == 0) {
10240Sstevel@tonic-gate /*
10250Sstevel@tonic-gate * If my node isn't in member
10260Sstevel@tonic-gate * list then reset master.
10270Sstevel@tonic-gate */
10280Sstevel@tonic-gate mnsr = (struct
10290Sstevel@tonic-gate md_mnset_record *)sr;
10300Sstevel@tonic-gate mnsr->sr_master_nodeid =
10310Sstevel@tonic-gate MD_MN_INVALID_NID;
10320Sstevel@tonic-gate mnsr->sr_master_nodenm[0] =
10330Sstevel@tonic-gate '\0';
10340Sstevel@tonic-gate }
10350Sstevel@tonic-gate nr->nr_flags &= ~MD_MN_NODE_OWN;
10360Sstevel@tonic-gate }
10370Sstevel@tonic-gate }
10380Sstevel@tonic-gate
10390Sstevel@tonic-gate /*
10400Sstevel@tonic-gate * Must grab nr_nextrec now since
10410Sstevel@tonic-gate * mnnr_cache_add may change it
10420Sstevel@tonic-gate * (mnnr_cache_add is storing the nodes in
10430Sstevel@tonic-gate * an ascending nodeid order list in order
10440Sstevel@tonic-gate * to support reconfig).
10450Sstevel@tonic-gate */
10460Sstevel@tonic-gate if (nr->nr_nextrec != 0)
10470Sstevel@tonic-gate p = &nr->nr_nextrec;
10480Sstevel@tonic-gate else
10490Sstevel@tonic-gate p = NULL;
10500Sstevel@tonic-gate
10510Sstevel@tonic-gate mnnr_cache_add((struct md_mnset_record *)sr,
10520Sstevel@tonic-gate nr);
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate if ((md_in_daemon) &&
10550Sstevel@tonic-gate (strcmp(nr->nr_nodename, mynode()) == 0)) {
10560Sstevel@tonic-gate (void) memset(&snp, 0, sizeof (snp));
10570Sstevel@tonic-gate snp.sn_nodeid = nr->nr_nodeid;
10580Sstevel@tonic-gate snp.sn_setno = mnsr->sr_setno;
10590Sstevel@tonic-gate if (metaioctl(MD_MN_SET_NODEID, &snp,
10600Sstevel@tonic-gate &snp.sn_mde, NULL) != 0) {
10610Sstevel@tonic-gate (void) mdstealerror(ep,
10620Sstevel@tonic-gate &snp.sn_mde);
10630Sstevel@tonic-gate }
10640Sstevel@tonic-gate }
10650Sstevel@tonic-gate
10660Sstevel@tonic-gate if (p == NULL)
10670Sstevel@tonic-gate break;
10680Sstevel@tonic-gate }
10690Sstevel@tonic-gate if (! mdisok(ep)) {
10700Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
10710Sstevel@tonic-gate goto out;
10720Sstevel@tonic-gate mdclrerror(ep);
10730Sstevel@tonic-gate }
10740Sstevel@tonic-gate }
10750Sstevel@tonic-gate
10760Sstevel@tonic-gate if (sr->sr_driverec == 0)
10770Sstevel@tonic-gate continue;
10780Sstevel@tonic-gate
10790Sstevel@tonic-gate /* Go get the drive records */
10800Sstevel@tonic-gate p = &sr->sr_driverec;
10810Sstevel@tonic-gate while ((dr = get_ur_rec(MD_LOCAL_SET, MD_UR_GET_WKEY,
10820Sstevel@tonic-gate MDDB_UR_DR, p, ep)) != NULL) {
10830Sstevel@tonic-gate dr->dr_next = NULL;
10840Sstevel@tonic-gate
10850Sstevel@tonic-gate if (md_in_daemon)
10860Sstevel@tonic-gate url_addl(&url_used, dr->dr_selfid);
10870Sstevel@tonic-gate
10880Sstevel@tonic-gate dr_cache_add(sr, dr);
10890Sstevel@tonic-gate
10900Sstevel@tonic-gate if (dr->dr_nextrec == 0)
10910Sstevel@tonic-gate break;
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate p = &dr->dr_nextrec;
10940Sstevel@tonic-gate }
10950Sstevel@tonic-gate if (! mdisok(ep)) {
10960Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
10970Sstevel@tonic-gate goto out;
10980Sstevel@tonic-gate mdclrerror(ep);
10990Sstevel@tonic-gate /*
11000Sstevel@tonic-gate * If dr_nextrec was not valid, or we had some
11010Sstevel@tonic-gate * problem getting the record, we end up here.
11020Sstevel@tonic-gate * get_ur_rec() zeroes the recid we passed in,
11030Sstevel@tonic-gate * if we had a failure getting a record using a key,
11040Sstevel@tonic-gate * so we simply commit the set record and valid
11050Sstevel@tonic-gate * drive records, if this fails, we hand an error
11060Sstevel@tonic-gate * back to the caller.
11070Sstevel@tonic-gate */
11080Sstevel@tonic-gate commitset(sr, FALSE, ep);
11090Sstevel@tonic-gate if (! mdisok(ep))
11100Sstevel@tonic-gate goto out;
11110Sstevel@tonic-gate }
11120Sstevel@tonic-gate }
11130Sstevel@tonic-gate if (! mdisok(ep)) {
11140Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
11150Sstevel@tonic-gate goto out;
11160Sstevel@tonic-gate mdclrerror(ep);
11170Sstevel@tonic-gate }
11180Sstevel@tonic-gate
11190Sstevel@tonic-gate /*
11200Sstevel@tonic-gate * If the daemon called, go through the USER records and cleanup
11210Sstevel@tonic-gate * any that are not used by valid sets.
11220Sstevel@tonic-gate */
11230Sstevel@tonic-gate if (md_in_daemon) {
11240Sstevel@tonic-gate id = 0;
11250Sstevel@tonic-gate /* Make a list of records to delete */
11260Sstevel@tonic-gate while ((reqp = get_db_rec(MD_UR_GET_NEXT, MD_LOCAL_SET,
11270Sstevel@tonic-gate MDDB_USER, 0, &id, ep)) != NULL) {
11280Sstevel@tonic-gate if (reqp->ur_type2 != MDDB_UR_SR &&
11290Sstevel@tonic-gate reqp->ur_type2 != MDDB_UR_DR) {
113062Sjeanm Free((void *)(uintptr_t)reqp->ur_data);
11310Sstevel@tonic-gate Free(reqp);
11320Sstevel@tonic-gate continue;
11330Sstevel@tonic-gate }
11340Sstevel@tonic-gate if (! url_findl(url_used, reqp->ur_recid))
11350Sstevel@tonic-gate url_addl(&url_tode, reqp->ur_recid);
113662Sjeanm Free((void *)(uintptr_t)reqp->ur_data);
11370Sstevel@tonic-gate Free(reqp);
11380Sstevel@tonic-gate }
11390Sstevel@tonic-gate if (! mdisok(ep)) {
11400Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
11410Sstevel@tonic-gate goto out;
11420Sstevel@tonic-gate mdclrerror(ep);
11430Sstevel@tonic-gate }
11440Sstevel@tonic-gate
11450Sstevel@tonic-gate /* Delete all the delete listed records */
11460Sstevel@tonic-gate for (urlp = url_tode; urlp != NULL; urlp = urlp->url_nx) {
11470Sstevel@tonic-gate s_delrec(urlp->url_recid, &xep);
11480Sstevel@tonic-gate if (! mdisok(&xep))
11490Sstevel@tonic-gate mdclrerror(&xep);
11500Sstevel@tonic-gate }
11510Sstevel@tonic-gate }
11520Sstevel@tonic-gate
11530Sstevel@tonic-gate url_freel(&url_used);
11540Sstevel@tonic-gate url_freel(&url_tode);
11550Sstevel@tonic-gate
11560Sstevel@tonic-gate if (nodecnt)
11570Sstevel@tonic-gate meta_free_nodelist(nl);
11580Sstevel@tonic-gate
11590Sstevel@tonic-gate /* Mark the snarf complete */
11600Sstevel@tonic-gate setsnarfdone = 2;
11610Sstevel@tonic-gate return (0);
11620Sstevel@tonic-gate
11630Sstevel@tonic-gate out:
11640Sstevel@tonic-gate url_freel(&url_used);
11650Sstevel@tonic-gate url_freel(&url_tode);
11660Sstevel@tonic-gate
11670Sstevel@tonic-gate sr_cache_flush(1);
11680Sstevel@tonic-gate
11690Sstevel@tonic-gate if (nodecnt)
11700Sstevel@tonic-gate meta_free_nodelist(nl);
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate /* Snarf failed, reset state */
11730Sstevel@tonic-gate setsnarfdone = 0;
11740Sstevel@tonic-gate
11750Sstevel@tonic-gate return (-1);
11760Sstevel@tonic-gate }
11770Sstevel@tonic-gate
11780Sstevel@tonic-gate void
sr_cache_add(md_set_record * sr)11790Sstevel@tonic-gate sr_cache_add(md_set_record *sr)
11800Sstevel@tonic-gate {
11810Sstevel@tonic-gate md_set_record *tsr;
11820Sstevel@tonic-gate
11830Sstevel@tonic-gate assert(setsnarfdone != 0);
11840Sstevel@tonic-gate
11850Sstevel@tonic-gate if (setrecords == NULL) {
11860Sstevel@tonic-gate setrecords = sr;
11870Sstevel@tonic-gate return;
11880Sstevel@tonic-gate }
11890Sstevel@tonic-gate
11900Sstevel@tonic-gate for (tsr = setrecords; tsr->sr_next != NULL; tsr = tsr->sr_next)
11910Sstevel@tonic-gate /* void */;
11920Sstevel@tonic-gate tsr->sr_next = sr;
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate
11950Sstevel@tonic-gate void
sr_cache_del(mddb_recid_t recid)11960Sstevel@tonic-gate sr_cache_del(mddb_recid_t recid)
11970Sstevel@tonic-gate {
11980Sstevel@tonic-gate md_set_record *sr, *tsr;
11990Sstevel@tonic-gate md_mnset_record *mnsr;
12000Sstevel@tonic-gate
12010Sstevel@tonic-gate assert(setsnarfdone != 0);
12020Sstevel@tonic-gate
12030Sstevel@tonic-gate for (sr = tsr = setrecords; sr != NULL; tsr = sr, sr = sr->sr_next) {
12040Sstevel@tonic-gate if (sr->sr_selfid != recid)
12050Sstevel@tonic-gate continue;
12060Sstevel@tonic-gate if (sr == setrecords)
12070Sstevel@tonic-gate setrecords = sr->sr_next;
12080Sstevel@tonic-gate else
12090Sstevel@tonic-gate tsr->sr_next = sr->sr_next;
12100Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
12110Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
12120Sstevel@tonic-gate Free(mnsr);
12130Sstevel@tonic-gate } else {
12140Sstevel@tonic-gate Free(sr);
12150Sstevel@tonic-gate }
12160Sstevel@tonic-gate break;
12170Sstevel@tonic-gate }
12180Sstevel@tonic-gate if (setrecords == NULL)
12190Sstevel@tonic-gate setsnarfdone = 0;
12200Sstevel@tonic-gate }
12210Sstevel@tonic-gate
12220Sstevel@tonic-gate void
dr_cache_add(md_set_record * sr,md_drive_record * dr)12230Sstevel@tonic-gate dr_cache_add(md_set_record *sr, md_drive_record *dr)
12240Sstevel@tonic-gate {
12250Sstevel@tonic-gate md_drive_record *tdr;
12260Sstevel@tonic-gate
12270Sstevel@tonic-gate assert(setsnarfdone != 0);
12280Sstevel@tonic-gate
12290Sstevel@tonic-gate assert(sr != NULL);
12300Sstevel@tonic-gate
12310Sstevel@tonic-gate if (sr->sr_drivechain == NULL) {
12320Sstevel@tonic-gate sr->sr_drivechain = dr;
12330Sstevel@tonic-gate sr->sr_driverec = dr->dr_selfid;
12340Sstevel@tonic-gate return;
12350Sstevel@tonic-gate }
12360Sstevel@tonic-gate
12370Sstevel@tonic-gate for (tdr = sr->sr_drivechain; tdr->dr_next != NULL; tdr = tdr->dr_next)
12380Sstevel@tonic-gate /* void */;
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate tdr->dr_next = dr;
12410Sstevel@tonic-gate tdr->dr_nextrec = dr->dr_selfid;
12420Sstevel@tonic-gate }
12430Sstevel@tonic-gate
12440Sstevel@tonic-gate void
dr_cache_del(md_set_record * sr,mddb_recid_t recid)12450Sstevel@tonic-gate dr_cache_del(md_set_record *sr, mddb_recid_t recid)
12460Sstevel@tonic-gate {
12470Sstevel@tonic-gate md_drive_record *dr;
12480Sstevel@tonic-gate md_drive_record *tdr;
12490Sstevel@tonic-gate
12500Sstevel@tonic-gate assert(setsnarfdone != 0);
12510Sstevel@tonic-gate
12520Sstevel@tonic-gate assert(sr != NULL);
12530Sstevel@tonic-gate
12540Sstevel@tonic-gate for (dr = tdr = sr->sr_drivechain; dr != NULL;
12550Sstevel@tonic-gate tdr = dr, dr = dr->dr_next) {
12560Sstevel@tonic-gate if (dr->dr_selfid != recid)
12570Sstevel@tonic-gate continue;
12580Sstevel@tonic-gate
12590Sstevel@tonic-gate if (dr == sr->sr_drivechain) {
12600Sstevel@tonic-gate sr->sr_drivechain = dr->dr_next;
12610Sstevel@tonic-gate sr->sr_driverec = dr->dr_nextrec;
12620Sstevel@tonic-gate } else {
12630Sstevel@tonic-gate tdr->dr_next = dr->dr_next;
12640Sstevel@tonic-gate tdr->dr_nextrec = dr->dr_nextrec;
12650Sstevel@tonic-gate }
12660Sstevel@tonic-gate Free(dr);
12670Sstevel@tonic-gate break;
12680Sstevel@tonic-gate }
12690Sstevel@tonic-gate }
12700Sstevel@tonic-gate
12710Sstevel@tonic-gate /*
12720Sstevel@tonic-gate * Nodes must be kept in ascending node id order in order to
12730Sstevel@tonic-gate * support reconfig.
12740Sstevel@tonic-gate *
12750Sstevel@tonic-gate * This routine may change nr->nr_next and nr->nr_nextrec.
12760Sstevel@tonic-gate */
12770Sstevel@tonic-gate void
mnnr_cache_add(md_mnset_record * mnsr,md_mnnode_record * nr)12780Sstevel@tonic-gate mnnr_cache_add(md_mnset_record *mnsr, md_mnnode_record *nr)
12790Sstevel@tonic-gate {
12800Sstevel@tonic-gate md_mnnode_record *tnr, *tnr_prev;
12810Sstevel@tonic-gate
12820Sstevel@tonic-gate assert(mnsr != NULL);
12830Sstevel@tonic-gate
12840Sstevel@tonic-gate if (mnsr->sr_nodechain == NULL) {
12850Sstevel@tonic-gate mnsr->sr_nodechain = nr;
12860Sstevel@tonic-gate mnsr->sr_noderec = nr->nr_selfid;
12870Sstevel@tonic-gate return;
12880Sstevel@tonic-gate }
12890Sstevel@tonic-gate
12900Sstevel@tonic-gate /*
12910Sstevel@tonic-gate * If new_record->nodeid < first_record->nodeid,
12920Sstevel@tonic-gate * put new_record at beginning of list.
12930Sstevel@tonic-gate */
12940Sstevel@tonic-gate if (nr->nr_nodeid < mnsr->sr_nodechain->nr_nodeid) {
12950Sstevel@tonic-gate nr->nr_next = mnsr->sr_nodechain;
12960Sstevel@tonic-gate nr->nr_nextrec = mnsr->sr_noderec;
12970Sstevel@tonic-gate mnsr->sr_nodechain = nr;
12980Sstevel@tonic-gate mnsr->sr_noderec = nr->nr_selfid;
12990Sstevel@tonic-gate return;
13000Sstevel@tonic-gate }
13010Sstevel@tonic-gate
13020Sstevel@tonic-gate /*
13030Sstevel@tonic-gate * Walk list looking for place to insert record.
13040Sstevel@tonic-gate */
13050Sstevel@tonic-gate
13060Sstevel@tonic-gate tnr_prev = mnsr->sr_nodechain;
13070Sstevel@tonic-gate tnr = tnr_prev->nr_next;
13080Sstevel@tonic-gate while (tnr) {
13090Sstevel@tonic-gate /* Insert new record between tnr_prev and tnr */
13100Sstevel@tonic-gate if (nr->nr_nodeid < tnr->nr_nodeid) {
13110Sstevel@tonic-gate nr->nr_next = tnr;
13120Sstevel@tonic-gate nr->nr_nextrec = tnr->nr_selfid; /* tnr's recid */
13130Sstevel@tonic-gate tnr_prev->nr_next = nr;
13140Sstevel@tonic-gate tnr_prev->nr_nextrec = nr->nr_selfid;
13150Sstevel@tonic-gate return;
13160Sstevel@tonic-gate }
13170Sstevel@tonic-gate tnr_prev = tnr;
13180Sstevel@tonic-gate tnr = tnr->nr_next;
13190Sstevel@tonic-gate }
13200Sstevel@tonic-gate
13210Sstevel@tonic-gate /*
13220Sstevel@tonic-gate * Add record to end of list.
13230Sstevel@tonic-gate */
13240Sstevel@tonic-gate tnr_prev->nr_next = nr;
13250Sstevel@tonic-gate tnr_prev->nr_nextrec = nr->nr_selfid;
13260Sstevel@tonic-gate }
13270Sstevel@tonic-gate
13280Sstevel@tonic-gate void
mnnr_cache_del(md_mnset_record * mnsr,mddb_recid_t recid)13290Sstevel@tonic-gate mnnr_cache_del(md_mnset_record *mnsr, mddb_recid_t recid)
13300Sstevel@tonic-gate {
13310Sstevel@tonic-gate md_mnnode_record *nr;
13320Sstevel@tonic-gate md_mnnode_record *tnr;
13330Sstevel@tonic-gate
13340Sstevel@tonic-gate assert(mnsr != NULL);
13350Sstevel@tonic-gate
13360Sstevel@tonic-gate tnr = 0;
13370Sstevel@tonic-gate nr = mnsr->sr_nodechain;
13380Sstevel@tonic-gate while (nr) {
13390Sstevel@tonic-gate if (nr->nr_selfid != recid) {
13400Sstevel@tonic-gate tnr = nr;
13410Sstevel@tonic-gate nr = nr->nr_next;
13420Sstevel@tonic-gate continue;
13430Sstevel@tonic-gate }
13440Sstevel@tonic-gate
13450Sstevel@tonic-gate if (nr == mnsr->sr_nodechain) {
13460Sstevel@tonic-gate mnsr->sr_nodechain = nr->nr_next;
13470Sstevel@tonic-gate mnsr->sr_noderec = nr->nr_nextrec;
13480Sstevel@tonic-gate } else {
13490Sstevel@tonic-gate tnr->nr_next = nr->nr_next;
13500Sstevel@tonic-gate tnr->nr_nextrec = nr->nr_nextrec;
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate Free(nr);
13530Sstevel@tonic-gate break;
13540Sstevel@tonic-gate }
13550Sstevel@tonic-gate }
13560Sstevel@tonic-gate
13570Sstevel@tonic-gate int
metad_isautotakebyname(char * setname)13580Sstevel@tonic-gate metad_isautotakebyname(char *setname)
13590Sstevel@tonic-gate {
13600Sstevel@tonic-gate md_error_t error = mdnullerror;
13610Sstevel@tonic-gate md_set_record *sr;
13620Sstevel@tonic-gate
13630Sstevel@tonic-gate if (md_in_daemon)
13640Sstevel@tonic-gate assert(setsnarfdone != 0);
13650Sstevel@tonic-gate else if (set_snarf(&error)) {
13660Sstevel@tonic-gate mdclrerror(&error);
13670Sstevel@tonic-gate return (0);
13680Sstevel@tonic-gate }
13690Sstevel@tonic-gate
13700Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next) {
13710Sstevel@tonic-gate if (strcmp(setname, sr->sr_setname) == 0) {
13720Sstevel@tonic-gate if (sr->sr_flags & MD_SR_AUTO_TAKE)
13730Sstevel@tonic-gate return (1);
13740Sstevel@tonic-gate return (0);
13750Sstevel@tonic-gate }
13760Sstevel@tonic-gate }
13770Sstevel@tonic-gate
13780Sstevel@tonic-gate return (0);
13790Sstevel@tonic-gate }
13800Sstevel@tonic-gate
13810Sstevel@tonic-gate int
metad_isautotakebynum(set_t setno)13820Sstevel@tonic-gate metad_isautotakebynum(set_t setno)
13830Sstevel@tonic-gate {
13840Sstevel@tonic-gate md_error_t error = mdnullerror;
13850Sstevel@tonic-gate md_set_record *sr;
13860Sstevel@tonic-gate
13870Sstevel@tonic-gate if (md_in_daemon)
13880Sstevel@tonic-gate assert(setsnarfdone != 0);
13890Sstevel@tonic-gate else if (set_snarf(&error)) {
13900Sstevel@tonic-gate mdclrerror(&error);
13910Sstevel@tonic-gate return (0);
13920Sstevel@tonic-gate }
13930Sstevel@tonic-gate
13940Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next) {
13950Sstevel@tonic-gate if (setno == sr->sr_setno) {
13960Sstevel@tonic-gate if (sr->sr_flags & MD_SR_AUTO_TAKE)
13970Sstevel@tonic-gate return (1);
13980Sstevel@tonic-gate return (0);
13990Sstevel@tonic-gate }
14000Sstevel@tonic-gate }
14010Sstevel@tonic-gate
14020Sstevel@tonic-gate return (0);
14030Sstevel@tonic-gate }
14040Sstevel@tonic-gate
14050Sstevel@tonic-gate md_set_record *
metad_getsetbyname(char * setname,md_error_t * ep)14060Sstevel@tonic-gate metad_getsetbyname(char *setname, md_error_t *ep)
14070Sstevel@tonic-gate {
14080Sstevel@tonic-gate md_set_record *sr;
14090Sstevel@tonic-gate char buf[100];
14100Sstevel@tonic-gate
14110Sstevel@tonic-gate assert(setsnarfdone != 0);
14120Sstevel@tonic-gate
14130Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next)
14140Sstevel@tonic-gate if (strcmp(setname, sr->sr_setname) == 0)
14150Sstevel@tonic-gate return (sr);
14160Sstevel@tonic-gate
14170Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "setname \"%s\"", setname);
14180Sstevel@tonic-gate (void) mderror(ep, MDE_NO_SET, buf);
14190Sstevel@tonic-gate return (NULL);
14200Sstevel@tonic-gate }
14210Sstevel@tonic-gate
14220Sstevel@tonic-gate md_set_record *
metad_getsetbynum(set_t setno,md_error_t * ep)14230Sstevel@tonic-gate metad_getsetbynum(set_t setno, md_error_t *ep)
14240Sstevel@tonic-gate {
14250Sstevel@tonic-gate md_set_record *sr;
14260Sstevel@tonic-gate char buf[100];
14270Sstevel@tonic-gate
14280Sstevel@tonic-gate if (md_in_daemon)
14290Sstevel@tonic-gate assert(setsnarfdone != 0);
14300Sstevel@tonic-gate else if (set_snarf(ep)) /* BYPASS DAEMON mode */
14310Sstevel@tonic-gate return (NULL);
14320Sstevel@tonic-gate
14330Sstevel@tonic-gate for (sr = setrecords; sr != NULL; sr = sr->sr_next)
14340Sstevel@tonic-gate if (setno == sr->sr_setno)
14350Sstevel@tonic-gate return (sr);
14360Sstevel@tonic-gate
14370Sstevel@tonic-gate (void) sprintf(buf, "setno %u", setno);
14380Sstevel@tonic-gate (void) mderror(ep, MDE_NO_SET, buf);
14390Sstevel@tonic-gate return (NULL);
14400Sstevel@tonic-gate }
14410Sstevel@tonic-gate
14420Sstevel@tonic-gate
14430Sstevel@tonic-gate /*
14440Sstevel@tonic-gate * Commit the set record and all of its associated records
14450Sstevel@tonic-gate * (drive records, node records for a MNset) to the local mddb.
14460Sstevel@tonic-gate */
14470Sstevel@tonic-gate void
commitset(md_set_record * sr,int inc_genid,md_error_t * ep)14480Sstevel@tonic-gate commitset(md_set_record *sr, int inc_genid, md_error_t *ep)
14490Sstevel@tonic-gate {
14500Sstevel@tonic-gate int drc, nrc, rc;
14510Sstevel@tonic-gate int *recs;
14520Sstevel@tonic-gate uint_t size;
14530Sstevel@tonic-gate md_drive_record *dr;
14540Sstevel@tonic-gate mddb_userreq_t req;
14550Sstevel@tonic-gate md_mnset_record *mnsr;
14560Sstevel@tonic-gate md_mnnode_record *nr;
14570Sstevel@tonic-gate
14580Sstevel@tonic-gate assert(setsnarfdone != 0);
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate /*
14610Sstevel@tonic-gate * Cluster nodename support
14620Sstevel@tonic-gate * Convert nodename -> nodeid
14630Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
14640Sstevel@tonic-gate * both the nodeid and name.
14650Sstevel@tonic-gate */
14660Sstevel@tonic-gate if (!(MD_MNSET_REC(sr)))
14670Sstevel@tonic-gate sdssc_cm_sr_nm2nid(sr);
14680Sstevel@tonic-gate
14690Sstevel@tonic-gate /* Send down to kernel the data in mddb USER set record */
14700Sstevel@tonic-gate if (inc_genid)
14710Sstevel@tonic-gate sr->sr_genid++;
14720Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
14730Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
14740Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
14750Sstevel@tonic-gate req.ur_size = sizeof (*mnsr);
14760Sstevel@tonic-gate } else {
14770Sstevel@tonic-gate req.ur_size = sizeof (*sr);
14780Sstevel@tonic-gate }
14790Sstevel@tonic-gate req.ur_data = (uintptr_t)sr;
14800Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
14810Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
14820Sstevel@tonic-gate return;
14830Sstevel@tonic-gate }
14840Sstevel@tonic-gate
14850Sstevel@tonic-gate /*
14860Sstevel@tonic-gate * Walk through the drive records associated with this set record
14870Sstevel@tonic-gate * and send down to kernel the data in mddb USER drive record.
14880Sstevel@tonic-gate */
14890Sstevel@tonic-gate drc = 0;
14900Sstevel@tonic-gate dr = sr->sr_drivechain;
14910Sstevel@tonic-gate while (dr) {
14920Sstevel@tonic-gate if (inc_genid)
14930Sstevel@tonic-gate dr->dr_genid++;
14940Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_SETDATA, dr->dr_selfid)
14950Sstevel@tonic-gate req.ur_size = sizeof (*dr);
14960Sstevel@tonic-gate req.ur_data = (uintptr_t)dr;
14970Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
14980Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
14990Sstevel@tonic-gate return;
15000Sstevel@tonic-gate }
15010Sstevel@tonic-gate drc++;
15020Sstevel@tonic-gate dr = dr->dr_next;
15030Sstevel@tonic-gate }
15040Sstevel@tonic-gate
15050Sstevel@tonic-gate
15060Sstevel@tonic-gate /*
15070Sstevel@tonic-gate * If this set is a multi-node set -
15080Sstevel@tonic-gate * walk through the node records associated with this set record
15090Sstevel@tonic-gate * and send down to kernel the data in mddb USER node record.
15100Sstevel@tonic-gate */
15110Sstevel@tonic-gate nrc = 0;
15120Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
15130Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
15140Sstevel@tonic-gate nr = mnsr->sr_nodechain;
15150Sstevel@tonic-gate while (nr) {
15160Sstevel@tonic-gate if (inc_genid)
15170Sstevel@tonic-gate nr->nr_genid++;
15180Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_SETDATA, nr->nr_selfid)
15190Sstevel@tonic-gate req.ur_size = sizeof (*nr);
152062Sjeanm req.ur_data = (uint64_t)(uintptr_t)nr;
15210Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
15220Sstevel@tonic-gate != 0) {
15230Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
15240Sstevel@tonic-gate return;
15250Sstevel@tonic-gate }
15260Sstevel@tonic-gate nrc++;
15270Sstevel@tonic-gate nr = nr->nr_next;
15280Sstevel@tonic-gate }
15290Sstevel@tonic-gate }
15300Sstevel@tonic-gate
15310Sstevel@tonic-gate /*
15320Sstevel@tonic-gate * Set up list of mddb USER recids containing set and drive records
15330Sstevel@tonic-gate * and node records if a MNset.
15340Sstevel@tonic-gate */
15350Sstevel@tonic-gate rc = 0;
15360Sstevel@tonic-gate size = (nrc + drc + 2) * sizeof (int);
15370Sstevel@tonic-gate recs = Zalloc(size);
15380Sstevel@tonic-gate /* First recid in list is the set record's id */
15390Sstevel@tonic-gate recs[rc] = sr->sr_selfid;
15400Sstevel@tonic-gate rc++;
15410Sstevel@tonic-gate dr = sr->sr_drivechain;
15420Sstevel@tonic-gate while (dr) {
15430Sstevel@tonic-gate /* Now, fill in the drive record ids */
15440Sstevel@tonic-gate recs[rc] = dr->dr_selfid;
15450Sstevel@tonic-gate dr = dr->dr_next;
15460Sstevel@tonic-gate rc++;
15470Sstevel@tonic-gate }
15480Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
15490Sstevel@tonic-gate nr = mnsr->sr_nodechain;
15500Sstevel@tonic-gate while (nr) {
15510Sstevel@tonic-gate /* If a MNset, fill in the node record ids */
15520Sstevel@tonic-gate recs[rc] = nr->nr_selfid;
15530Sstevel@tonic-gate nr = nr->nr_next;
15540Sstevel@tonic-gate rc++;
15550Sstevel@tonic-gate }
15560Sstevel@tonic-gate }
15570Sstevel@tonic-gate /* Set last record to null recid */
15580Sstevel@tonic-gate recs[rc] = 0;
15590Sstevel@tonic-gate
15600Sstevel@tonic-gate /* Write out the set and drive and node records to the local mddb */
15610Sstevel@tonic-gate METAD_SETUP_UR(MD_DB_COMMIT_MANY, 0, 0);
15620Sstevel@tonic-gate req.ur_size = size;
15630Sstevel@tonic-gate req.ur_data = (uintptr_t)recs;
15640Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
15650Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
15660Sstevel@tonic-gate return;
15670Sstevel@tonic-gate }
15680Sstevel@tonic-gate
15690Sstevel@tonic-gate /*
15700Sstevel@tonic-gate * Cluster nodename support
15710Sstevel@tonic-gate * Convert nodeid -> nodename
15720Sstevel@tonic-gate * Don't do this for MN disksets since we've already stored
15730Sstevel@tonic-gate * both the nodeid and name.
15740Sstevel@tonic-gate */
15750Sstevel@tonic-gate if (!(MD_MNSET_REC(sr)))
15760Sstevel@tonic-gate sdssc_cm_sr_nid2nm(sr);
15770Sstevel@tonic-gate
15780Sstevel@tonic-gate Free(recs);
15790Sstevel@tonic-gate }
15800Sstevel@tonic-gate
15810Sstevel@tonic-gate /*
15820Sstevel@tonic-gate * This routine only handles returns a md_set_record structure even
15830Sstevel@tonic-gate * if the set record describes a MN set. This will allow pre-MN
15840Sstevel@tonic-gate * SVM RPC code to access a MN set record and to display it.
15850Sstevel@tonic-gate *
15860Sstevel@tonic-gate * The MN SVM RPC code detects if the set record returned describes
15870Sstevel@tonic-gate * a MN set and then will copy it using mnsetdup.
15880Sstevel@tonic-gate */
15890Sstevel@tonic-gate md_set_record *
setdup(md_set_record * sr)15900Sstevel@tonic-gate setdup(md_set_record *sr)
15910Sstevel@tonic-gate {
15920Sstevel@tonic-gate md_set_record *tsr = NULL;
15930Sstevel@tonic-gate md_drive_record **tdrpp = NULL;
15940Sstevel@tonic-gate
15950Sstevel@tonic-gate if (sr && (tsr = Malloc(sizeof (*sr))) != NULL) {
15960Sstevel@tonic-gate (void) memmove(tsr, sr, sizeof (*sr));
15970Sstevel@tonic-gate tsr->sr_next = NULL;
15980Sstevel@tonic-gate tdrpp = &tsr->sr_drivechain;
15990Sstevel@tonic-gate while (*tdrpp) {
16000Sstevel@tonic-gate *tdrpp = drdup(*tdrpp);
16010Sstevel@tonic-gate tdrpp = &(*tdrpp)->dr_next;
16020Sstevel@tonic-gate }
16030Sstevel@tonic-gate }
16040Sstevel@tonic-gate return (tsr);
16050Sstevel@tonic-gate }
16060Sstevel@tonic-gate
16070Sstevel@tonic-gate /*
16080Sstevel@tonic-gate * This routine only copies MN set records. If a non-MN set
16090Sstevel@tonic-gate * record was passed in NULL pointer will be returned.
16100Sstevel@tonic-gate */
16110Sstevel@tonic-gate md_mnset_record *
mnsetdup(md_mnset_record * mnsr)16120Sstevel@tonic-gate mnsetdup(md_mnset_record *mnsr)
16130Sstevel@tonic-gate {
16140Sstevel@tonic-gate md_mnset_record *tmnsr = NULL;
16150Sstevel@tonic-gate md_drive_record **tdrpp = NULL;
16160Sstevel@tonic-gate md_mnnode_record **tnrpp = NULL;
16170Sstevel@tonic-gate
16180Sstevel@tonic-gate if (!MD_MNSET_REC(mnsr)) {
16190Sstevel@tonic-gate return (NULL);
16200Sstevel@tonic-gate }
16210Sstevel@tonic-gate
16220Sstevel@tonic-gate if (mnsr && (tmnsr = Malloc(sizeof (*mnsr))) != NULL) {
16230Sstevel@tonic-gate (void) memmove(tmnsr, mnsr, sizeof (*mnsr));
16240Sstevel@tonic-gate tmnsr->sr_next = NULL;
16250Sstevel@tonic-gate tdrpp = &tmnsr->sr_drivechain;
16260Sstevel@tonic-gate while (*tdrpp) {
16270Sstevel@tonic-gate *tdrpp = drdup(*tdrpp);
16280Sstevel@tonic-gate tdrpp = &(*tdrpp)->dr_next;
16290Sstevel@tonic-gate }
16300Sstevel@tonic-gate tnrpp = &tmnsr->sr_nodechain;
16310Sstevel@tonic-gate while (*tnrpp) {
16320Sstevel@tonic-gate *tnrpp = nrdup(*tnrpp);
16330Sstevel@tonic-gate tnrpp = &(*tnrpp)->nr_next;
16340Sstevel@tonic-gate }
16350Sstevel@tonic-gate }
16360Sstevel@tonic-gate return (tmnsr);
16370Sstevel@tonic-gate }
16380Sstevel@tonic-gate
16390Sstevel@tonic-gate md_drive_record *
drdup(md_drive_record * dr)16400Sstevel@tonic-gate drdup(md_drive_record *dr)
16410Sstevel@tonic-gate {
16420Sstevel@tonic-gate md_drive_record *tdr = NULL;
16430Sstevel@tonic-gate
16440Sstevel@tonic-gate if (dr && (tdr = Malloc(sizeof (*dr))) != NULL)
16450Sstevel@tonic-gate (void) memmove(tdr, dr, sizeof (*dr));
16460Sstevel@tonic-gate return (tdr);
16470Sstevel@tonic-gate }
16480Sstevel@tonic-gate
16490Sstevel@tonic-gate md_mnnode_record *
nrdup(md_mnnode_record * nr)16500Sstevel@tonic-gate nrdup(md_mnnode_record *nr)
16510Sstevel@tonic-gate {
16520Sstevel@tonic-gate md_mnnode_record *tnr = NULL;
16530Sstevel@tonic-gate
16540Sstevel@tonic-gate if (nr && (tnr = Malloc(sizeof (*nr))) != NULL)
16550Sstevel@tonic-gate (void) memmove(tnr, nr, sizeof (*nr));
16560Sstevel@tonic-gate return (tnr);
16570Sstevel@tonic-gate }
16580Sstevel@tonic-gate
16590Sstevel@tonic-gate /*
16600Sstevel@tonic-gate * Duplicate parts of the drive decriptor list for this node.
16610Sstevel@tonic-gate * Only duplicate the drive name string in the mddrivename structure, don't
16620Sstevel@tonic-gate * need to copy any other pointers since only interested in the flags and
16630Sstevel@tonic-gate * the drive name (i.e. other pointers will be set to NULL).
16640Sstevel@tonic-gate * Returns NULL if failure due to Malloc failure.
16650Sstevel@tonic-gate * Returns pointer (non-NULL) to dup'd list if successful.
16660Sstevel@tonic-gate */
16670Sstevel@tonic-gate md_drive_desc *
dd_list_dup(md_drive_desc * dd)16680Sstevel@tonic-gate dd_list_dup(md_drive_desc *dd)
16690Sstevel@tonic-gate {
16700Sstevel@tonic-gate md_drive_desc *orig_dd;
16710Sstevel@tonic-gate md_drive_desc *copy_dd = NULL, *copy_dd_prev = NULL;
16720Sstevel@tonic-gate md_drive_desc *copy_dd_head = NULL;
16730Sstevel@tonic-gate mddrivename_t *copy_dnp;
16740Sstevel@tonic-gate char *copy_cname;
16750Sstevel@tonic-gate char *copy_devid;
16760Sstevel@tonic-gate
16770Sstevel@tonic-gate if (dd == NULL)
16780Sstevel@tonic-gate return (NULL);
16790Sstevel@tonic-gate
16800Sstevel@tonic-gate orig_dd = dd;
16810Sstevel@tonic-gate
16820Sstevel@tonic-gate while (orig_dd) {
16830Sstevel@tonic-gate copy_dd = Zalloc(sizeof (*copy_dd));
16840Sstevel@tonic-gate copy_dnp = Zalloc(sizeof (mddrivename_t));
16850Sstevel@tonic-gate copy_cname = Zalloc(sizeof (orig_dd->dd_dnp->cname));
16860Sstevel@tonic-gate if (orig_dd->dd_dnp->devid) {
16870Sstevel@tonic-gate copy_devid = Zalloc(sizeof (orig_dd->dd_dnp->devid));
16880Sstevel@tonic-gate } else {
16890Sstevel@tonic-gate copy_devid = NULL;
16900Sstevel@tonic-gate }
16910Sstevel@tonic-gate copy_dd->dd_next = NULL;
16920Sstevel@tonic-gate if ((copy_dd == NULL) || (copy_dnp == NULL) ||
16930Sstevel@tonic-gate (copy_cname == NULL)) {
16940Sstevel@tonic-gate while (copy_dd_head) {
16950Sstevel@tonic-gate copy_dd = copy_dd_head->dd_next;
16960Sstevel@tonic-gate Free(copy_dd_head);
16970Sstevel@tonic-gate copy_dd_head = copy_dd;
16980Sstevel@tonic-gate }
16990Sstevel@tonic-gate if (copy_dnp)
17000Sstevel@tonic-gate Free(copy_dnp);
17010Sstevel@tonic-gate if (copy_dd)
17020Sstevel@tonic-gate Free(copy_dd);
17030Sstevel@tonic-gate if (copy_cname)
17040Sstevel@tonic-gate Free(copy_cname);
17050Sstevel@tonic-gate if (copy_devid)
17060Sstevel@tonic-gate Free(copy_devid);
17070Sstevel@tonic-gate return (NULL);
17080Sstevel@tonic-gate }
17090Sstevel@tonic-gate (void) memmove(copy_dd, orig_dd, sizeof (*orig_dd));
17100Sstevel@tonic-gate (void) strlcpy(copy_cname, orig_dd->dd_dnp->cname,
17110Sstevel@tonic-gate sizeof (orig_dd->dd_dnp->cname));
17120Sstevel@tonic-gate copy_dd->dd_next = NULL;
17130Sstevel@tonic-gate copy_dd->dd_dnp = copy_dnp;
17140Sstevel@tonic-gate copy_dd->dd_dnp->cname = copy_cname;
17150Sstevel@tonic-gate if (copy_devid) {
17160Sstevel@tonic-gate (void) strlcpy(copy_devid, orig_dd->dd_dnp->devid,
17170Sstevel@tonic-gate sizeof (orig_dd->dd_dnp->devid));
17180Sstevel@tonic-gate }
17190Sstevel@tonic-gate
17200Sstevel@tonic-gate if (copy_dd_prev == NULL) {
17210Sstevel@tonic-gate copy_dd_head = copy_dd;
17220Sstevel@tonic-gate copy_dd_prev = copy_dd;
17230Sstevel@tonic-gate } else {
17240Sstevel@tonic-gate copy_dd_prev->dd_next = copy_dd;
17250Sstevel@tonic-gate copy_dd_prev = copy_dd;
17260Sstevel@tonic-gate }
17270Sstevel@tonic-gate orig_dd = orig_dd->dd_next;
17280Sstevel@tonic-gate }
17290Sstevel@tonic-gate copy_dd->dd_next = NULL;
17300Sstevel@tonic-gate return (copy_dd_head);
17310Sstevel@tonic-gate }
17320Sstevel@tonic-gate
17330Sstevel@tonic-gate void
sr_cache_flush(int flushnames)17340Sstevel@tonic-gate sr_cache_flush(int flushnames)
17350Sstevel@tonic-gate {
17360Sstevel@tonic-gate md_set_record *sr, *tsr;
17370Sstevel@tonic-gate md_mnset_record *mnsr;
17380Sstevel@tonic-gate md_drive_record *dr, *tdr;
17390Sstevel@tonic-gate md_mnnode_record *nr, *tnr;
17400Sstevel@tonic-gate
17410Sstevel@tonic-gate sr = tsr = setrecords;
17420Sstevel@tonic-gate while (sr != NULL) {
17430Sstevel@tonic-gate dr = tdr = sr->sr_drivechain;
17440Sstevel@tonic-gate while (dr != NULL) {
17450Sstevel@tonic-gate tdr = dr;
17460Sstevel@tonic-gate dr = dr->dr_next;
17470Sstevel@tonic-gate Free(tdr);
17480Sstevel@tonic-gate }
17490Sstevel@tonic-gate tsr = sr;
17500Sstevel@tonic-gate sr = sr->sr_next;
17510Sstevel@tonic-gate if (MD_MNSET_REC(tsr)) {
17520Sstevel@tonic-gate mnsr = (struct md_mnset_record *)tsr;
17530Sstevel@tonic-gate nr = tnr = mnsr->sr_nodechain;
17540Sstevel@tonic-gate while (nr != NULL) {
17550Sstevel@tonic-gate tnr = nr;
17560Sstevel@tonic-gate nr = nr->nr_next;
17570Sstevel@tonic-gate Free(tnr);
17580Sstevel@tonic-gate }
17590Sstevel@tonic-gate Free(mnsr);
17600Sstevel@tonic-gate } else {
17610Sstevel@tonic-gate Free(tsr);
17620Sstevel@tonic-gate }
17630Sstevel@tonic-gate }
17640Sstevel@tonic-gate
17650Sstevel@tonic-gate setrecords = NULL;
17660Sstevel@tonic-gate
17670Sstevel@tonic-gate setsnarfdone = 0;
17680Sstevel@tonic-gate
17690Sstevel@tonic-gate /* This will cause the other caches to be cleared */
17700Sstevel@tonic-gate if (flushnames)
17710Sstevel@tonic-gate metaflushnames(0);
17720Sstevel@tonic-gate }
17730Sstevel@tonic-gate
17740Sstevel@tonic-gate void
sr_cache_flush_setno(set_t setno)17750Sstevel@tonic-gate sr_cache_flush_setno(set_t setno)
17760Sstevel@tonic-gate {
17770Sstevel@tonic-gate md_set_record *sr, *tsr;
17780Sstevel@tonic-gate md_mnset_record *mnsr;
17790Sstevel@tonic-gate md_drive_record *dr, *tdr;
17800Sstevel@tonic-gate
17810Sstevel@tonic-gate assert(setsnarfdone != 0);
17820Sstevel@tonic-gate
17830Sstevel@tonic-gate for (sr = tsr = setrecords; sr; tsr = sr, sr = sr->sr_next) {
17840Sstevel@tonic-gate if (sr->sr_setno != setno)
17850Sstevel@tonic-gate continue;
17860Sstevel@tonic-gate
17870Sstevel@tonic-gate dr = tdr = sr->sr_drivechain;
17880Sstevel@tonic-gate while (dr != NULL) {
17890Sstevel@tonic-gate tdr = dr;
17900Sstevel@tonic-gate dr = dr->dr_next;
17910Sstevel@tonic-gate Free(tdr);
17920Sstevel@tonic-gate }
17930Sstevel@tonic-gate if (sr == setrecords)
17940Sstevel@tonic-gate setrecords = sr->sr_next;
17950Sstevel@tonic-gate else
17960Sstevel@tonic-gate tsr->sr_next = sr->sr_next;
17970Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
17980Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
17990Sstevel@tonic-gate Free(mnsr);
18000Sstevel@tonic-gate } else {
18010Sstevel@tonic-gate Free(sr);
18020Sstevel@tonic-gate }
18030Sstevel@tonic-gate break;
18040Sstevel@tonic-gate }
18050Sstevel@tonic-gate
18060Sstevel@tonic-gate setsnarfdone = 0;
18070Sstevel@tonic-gate
18080Sstevel@tonic-gate /* This will cause the other caches to be cleared */
18090Sstevel@tonic-gate metaflushnames(0);
18100Sstevel@tonic-gate }
18110Sstevel@tonic-gate
18120Sstevel@tonic-gate int
s_ownset(set_t setno,md_error_t * ep)18130Sstevel@tonic-gate s_ownset(set_t setno, md_error_t *ep)
18140Sstevel@tonic-gate {
18150Sstevel@tonic-gate mddb_ownset_t ownset_arg;
18160Sstevel@tonic-gate
18170Sstevel@tonic-gate ownset_arg.setno = setno;
18180Sstevel@tonic-gate ownset_arg.owns_set = MD_SETOWNER_NONE;
18190Sstevel@tonic-gate
18200Sstevel@tonic-gate if (metaioctl(MD_DB_OWNSET, &ownset_arg, ep, NULL) != 0)
18210Sstevel@tonic-gate return (0);
18220Sstevel@tonic-gate
18230Sstevel@tonic-gate return (ownset_arg.owns_set);
18240Sstevel@tonic-gate }
18250Sstevel@tonic-gate
18260Sstevel@tonic-gate void
s_delset(char * setname,md_error_t * ep)18270Sstevel@tonic-gate s_delset(char *setname, md_error_t *ep)
18280Sstevel@tonic-gate {
18290Sstevel@tonic-gate md_set_record *sr;
18300Sstevel@tonic-gate md_set_record *tsr;
18310Sstevel@tonic-gate md_drive_record *dr;
18320Sstevel@tonic-gate md_drive_record *tdr;
18330Sstevel@tonic-gate md_mnnode_record *nr, *tnr;
18340Sstevel@tonic-gate mddb_userreq_t req;
18350Sstevel@tonic-gate char stringbuf[100];
18360Sstevel@tonic-gate int i;
18370Sstevel@tonic-gate mdsetname_t *sp = NULL;
18380Sstevel@tonic-gate mddrivename_t *dn = NULL;
18390Sstevel@tonic-gate mdname_t *np = NULL;
18400Sstevel@tonic-gate md_dev64_t dev;
18410Sstevel@tonic-gate side_t myside = MD_SIDEWILD;
18420Sstevel@tonic-gate md_error_t xep = mdnullerror;
18430Sstevel@tonic-gate md_mnset_record *mnsr;
18440Sstevel@tonic-gate int num_sets = 0;
18450Sstevel@tonic-gate int num_mn_sets = 0;
18460Sstevel@tonic-gate
18470Sstevel@tonic-gate (void) memset(&req, 0, sizeof (mddb_userreq_t));
18480Sstevel@tonic-gate
18490Sstevel@tonic-gate if ((sr = getsetbyname(setname, ep)) == NULL)
18500Sstevel@tonic-gate return;
18510Sstevel@tonic-gate
18520Sstevel@tonic-gate sp = metasetnosetname(sr->sr_setno, &xep);
18530Sstevel@tonic-gate mdclrerror(&xep);
18540Sstevel@tonic-gate
18550Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
18560Sstevel@tonic-gate /*
18570Sstevel@tonic-gate * If this node is a set owner, halt the set before
18580Sstevel@tonic-gate * deleting the set records. Ignore any errors since
18590Sstevel@tonic-gate * s_ownset and halt_set could fail if panic had occurred
18600Sstevel@tonic-gate * during the add/delete of a node.
18610Sstevel@tonic-gate */
18620Sstevel@tonic-gate if (s_ownset(sr->sr_setno, &xep)) {
18630Sstevel@tonic-gate mdclrerror(&xep);
18640Sstevel@tonic-gate if (halt_set(sp, &xep))
18650Sstevel@tonic-gate mdclrerror(&xep);
18660Sstevel@tonic-gate }
18670Sstevel@tonic-gate }
18680Sstevel@tonic-gate
18690Sstevel@tonic-gate (void) snprintf(stringbuf, sizeof (stringbuf), "/dev/md/%s", setname);
18700Sstevel@tonic-gate (void) unlink(stringbuf);
18710Sstevel@tonic-gate (void) unlink(meta_lock_name(sr->sr_setno));
18720Sstevel@tonic-gate
18730Sstevel@tonic-gate if (MD_MNSET_REC(sr)) {
18740Sstevel@tonic-gate mnsr = (struct md_mnset_record *)sr;
18750Sstevel@tonic-gate nr = mnsr->sr_nodechain;
18760Sstevel@tonic-gate while (nr) {
18770Sstevel@tonic-gate /* Setting myside for later use */
18780Sstevel@tonic-gate if (strcmp(mynode(), nr->nr_nodename) == 0)
18790Sstevel@tonic-gate myside = nr->nr_nodeid;
18800Sstevel@tonic-gate
18810Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
18820Sstevel@tonic-gate METAD_SETUP_NR(MD_DB_DELETE, nr->nr_selfid)
18830Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde,
18840Sstevel@tonic-gate NULL) != 0) {
18850Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
18860Sstevel@tonic-gate free_sr(sr);
18870Sstevel@tonic-gate return;
18880Sstevel@tonic-gate }
18890Sstevel@tonic-gate tnr = nr;
18900Sstevel@tonic-gate nr = nr->nr_next;
18910Sstevel@tonic-gate
18920Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_HOST,
18930Sstevel@tonic-gate sr->sr_setno, tnr->nr_nodeid);
18940Sstevel@tonic-gate
18950Sstevel@tonic-gate mnnr_cache_del((struct md_mnset_record *)sr,
18960Sstevel@tonic-gate tnr->nr_selfid);
18970Sstevel@tonic-gate }
18980Sstevel@tonic-gate } else {
18990Sstevel@tonic-gate for (i = 0; i < MD_MAXSIDES; i++) {
19000Sstevel@tonic-gate /* Skip empty slots */
19010Sstevel@tonic-gate if (sr->sr_nodes[i][0] == '\0')
19020Sstevel@tonic-gate continue;
19030Sstevel@tonic-gate
19040Sstevel@tonic-gate if (strcmp(mynode(), sr->sr_nodes[i]) == 0)
19050Sstevel@tonic-gate myside = i;
19060Sstevel@tonic-gate
19070Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_HOST,
19080Sstevel@tonic-gate sr->sr_setno, i);
19090Sstevel@tonic-gate }
19100Sstevel@tonic-gate }
19110Sstevel@tonic-gate
19120Sstevel@tonic-gate dr = sr->sr_drivechain;
19130Sstevel@tonic-gate while (dr) {
19140Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
19150Sstevel@tonic-gate METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid)
19160Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
19170Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
19180Sstevel@tonic-gate free_sr(sr);
19190Sstevel@tonic-gate return;
19200Sstevel@tonic-gate }
19210Sstevel@tonic-gate tdr = dr;
19220Sstevel@tonic-gate dr = dr->dr_next;
19230Sstevel@tonic-gate
19240Sstevel@tonic-gate dev = NODEV64;
19250Sstevel@tonic-gate if (myside != MD_SIDEWILD && sp != NULL) {
19260Sstevel@tonic-gate dn = metadrivename_withdrkey(sp, myside,
19270Sstevel@tonic-gate tdr->dr_key, MD_BASICNAME_OK, &xep);
19280Sstevel@tonic-gate if (dn != NULL) {
19290Sstevel@tonic-gate uint_t rep_slice;
19300Sstevel@tonic-gate
19310Sstevel@tonic-gate np = NULL;
19320Sstevel@tonic-gate if (meta_replicaslice(dn, &rep_slice,
19330Sstevel@tonic-gate &xep) == 0) {
19340Sstevel@tonic-gate np = metaslicename(dn, rep_slice, &xep);
19350Sstevel@tonic-gate }
19360Sstevel@tonic-gate
19370Sstevel@tonic-gate if (np != NULL)
19380Sstevel@tonic-gate dev = np->dev;
19390Sstevel@tonic-gate else
19400Sstevel@tonic-gate mdclrerror(&xep);
19410Sstevel@tonic-gate } else
19420Sstevel@tonic-gate mdclrerror(&xep);
19430Sstevel@tonic-gate } else
19440Sstevel@tonic-gate mdclrerror(&xep);
19450Sstevel@tonic-gate
19460Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
19470Sstevel@tonic-gate sr->sr_setno, dev);
19480Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
19490Sstevel@tonic-gate MD_LOCAL_SET, dev);
19500Sstevel@tonic-gate
19510Sstevel@tonic-gate dr_cache_del(sr, tdr->dr_selfid);
19520Sstevel@tonic-gate
19530Sstevel@tonic-gate }
19540Sstevel@tonic-gate
19550Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
19560Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_DELETE, sr->sr_selfid)
19570Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
19580Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
19590Sstevel@tonic-gate free_sr(sr);
19600Sstevel@tonic-gate return;
19610Sstevel@tonic-gate }
19620Sstevel@tonic-gate
19630Sstevel@tonic-gate SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_DELETE, SVM_TAG_SET, sr->sr_setno,
19640Sstevel@tonic-gate NODEV64);
19650Sstevel@tonic-gate
19660Sstevel@tonic-gate for (tsr = setrecords; tsr; tsr = tsr->sr_next) {
19670Sstevel@tonic-gate if (tsr == sr)
19680Sstevel@tonic-gate continue;
19690Sstevel@tonic-gate
19700Sstevel@tonic-gate num_sets++;
19710Sstevel@tonic-gate if (MD_MNSET_REC(tsr))
19720Sstevel@tonic-gate num_mn_sets++;
19730Sstevel@tonic-gate }
19740Sstevel@tonic-gate
19750Sstevel@tonic-gate if (num_mn_sets == 0)
19762063Shshaw (void) meta_smf_disable(META_SMF_MN_DISKSET, NULL);
19770Sstevel@tonic-gate
19780Sstevel@tonic-gate /* The set we just deleted is the only one left */
19790Sstevel@tonic-gate if (num_sets == 0)
19802063Shshaw (void) meta_smf_disable(META_SMF_DISKSET, NULL);
19810Sstevel@tonic-gate
19820Sstevel@tonic-gate sr_cache_del(sr->sr_selfid);
19830Sstevel@tonic-gate free_sr(sr);
19840Sstevel@tonic-gate
19850Sstevel@tonic-gate }
19860Sstevel@tonic-gate
19870Sstevel@tonic-gate void
s_delrec(mddb_recid_t recid,md_error_t * ep)19880Sstevel@tonic-gate s_delrec(mddb_recid_t recid, md_error_t *ep)
19890Sstevel@tonic-gate {
19900Sstevel@tonic-gate mddb_userreq_t req;
19910Sstevel@tonic-gate
19920Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req));
19930Sstevel@tonic-gate
19940Sstevel@tonic-gate METAD_SETUP_SR(MD_DB_DELETE, recid)
19950Sstevel@tonic-gate
19960Sstevel@tonic-gate if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
19970Sstevel@tonic-gate (void) mdstealerror(ep, &req.ur_mde);
19980Sstevel@tonic-gate }
19990Sstevel@tonic-gate
20000Sstevel@tonic-gate /*
20010Sstevel@tonic-gate * resnarf the imported set
20020Sstevel@tonic-gate */
20030Sstevel@tonic-gate int
resnarf_set(set_t setno,md_error_t * ep)20040Sstevel@tonic-gate resnarf_set(
20050Sstevel@tonic-gate set_t setno,
20060Sstevel@tonic-gate md_error_t *ep
20070Sstevel@tonic-gate )
20080Sstevel@tonic-gate {
20090Sstevel@tonic-gate md_set_record *sr;
20100Sstevel@tonic-gate md_drive_record *dr;
20110Sstevel@tonic-gate mddb_recid_t id, *p;
20120Sstevel@tonic-gate
20130Sstevel@tonic-gate if (meta_setup_db_locations(ep) != 0) {
20140Sstevel@tonic-gate if (! mdismddberror(ep, MDE_DB_STALE))
20150Sstevel@tonic-gate return (-1);
20160Sstevel@tonic-gate mdclrerror(ep);
20170Sstevel@tonic-gate }
20180Sstevel@tonic-gate
20190Sstevel@tonic-gate setsnarfdone = 1;
20200Sstevel@tonic-gate
20210Sstevel@tonic-gate id = 0;
20220Sstevel@tonic-gate while ((sr = get_ur_rec(MD_LOCAL_SET, MD_UR_GET_NEXT, MDDB_UR_SR, &id,
20230Sstevel@tonic-gate ep)) != NULL) {
20240Sstevel@tonic-gate
20250Sstevel@tonic-gate if (sr->sr_setno != setno)
20260Sstevel@tonic-gate continue;
20270Sstevel@tonic-gate
20280Sstevel@tonic-gate /* Don't allow resnarf of a multi-node diskset */
20290Sstevel@tonic-gate if (MD_MNSET_REC(sr))
20300Sstevel@tonic-gate goto out;
20310Sstevel@tonic-gate
20320Sstevel@tonic-gate sr->sr_next = NULL;
20330Sstevel@tonic-gate sr->sr_drivechain = NULL;
20340Sstevel@tonic-gate
20350Sstevel@tonic-gate if (md_in_daemon)
20360Sstevel@tonic-gate url_addl(&url_used, sr->sr_selfid);
20370Sstevel@tonic-gate
20380Sstevel@tonic-gate sr->sr_flags |= MD_SR_CHECK;
20390Sstevel@tonic-gate
20400Sstevel@tonic-gate sr_cache_add(sr);
20410Sstevel@tonic-gate
20420Sstevel@tonic-gate if (sr->sr_driverec == 0)
20430Sstevel@tonic-gate break;
20440Sstevel@tonic-gate
20450Sstevel@tonic-gate p = &sr->sr_driverec;
20460Sstevel@tonic-gate while ((dr = get_ur_rec(MD_LOCAL_SET, MD_UR_GET_WKEY,
20470Sstevel@tonic-gate MDDB_UR_DR, p, ep)) != NULL) {
20480Sstevel@tonic-gate dr->dr_next = NULL;
20490Sstevel@tonic-gate
20500Sstevel@tonic-gate if (md_in_daemon)
20510Sstevel@tonic-gate url_addl(&url_used, dr->dr_selfid);
20520Sstevel@tonic-gate
20530Sstevel@tonic-gate dr_cache_add(sr, dr);
20540Sstevel@tonic-gate
20550Sstevel@tonic-gate if (dr->dr_nextrec == 0)
20560Sstevel@tonic-gate break;
20570Sstevel@tonic-gate
20580Sstevel@tonic-gate p = &dr->dr_nextrec;
20590Sstevel@tonic-gate }
20600Sstevel@tonic-gate if (! mdisok(ep)) {
20610Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
20620Sstevel@tonic-gate goto out;
20630Sstevel@tonic-gate mdclrerror(ep);
20640Sstevel@tonic-gate commitset(sr, FALSE, ep);
20650Sstevel@tonic-gate if (! mdisok(ep))
20660Sstevel@tonic-gate goto out;
20670Sstevel@tonic-gate }
20680Sstevel@tonic-gate }
20690Sstevel@tonic-gate if (! mdisok(ep)) {
20700Sstevel@tonic-gate if (! mdissyserror(ep, ENOENT))
20710Sstevel@tonic-gate goto out;
20720Sstevel@tonic-gate mdclrerror(ep);
20730Sstevel@tonic-gate }
20740Sstevel@tonic-gate
20750Sstevel@tonic-gate setsnarfdone = 2;
20760Sstevel@tonic-gate
20770Sstevel@tonic-gate url_freel(&url_used);
20780Sstevel@tonic-gate url_freel(&url_tode);
20790Sstevel@tonic-gate return (0);
20800Sstevel@tonic-gate
20810Sstevel@tonic-gate out:
20820Sstevel@tonic-gate url_freel(&url_used);
20830Sstevel@tonic-gate url_freel(&url_tode);
20840Sstevel@tonic-gate
20850Sstevel@tonic-gate sr_cache_flush(1);
20860Sstevel@tonic-gate
20870Sstevel@tonic-gate setsnarfdone = 0;
20880Sstevel@tonic-gate
20890Sstevel@tonic-gate return (-1);
20900Sstevel@tonic-gate }
2091