xref: /titanic_52/usr/src/lib/librdc/common/rdcpersist.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte #include <sys/types.h>
27*fcf3ce44SJohn Forte #include <sys/stat.h>
28*fcf3ce44SJohn Forte #include <sys/mkdev.h>
29*fcf3ce44SJohn Forte #include <fcntl.h>
30*fcf3ce44SJohn Forte #include <unistd.h>
31*fcf3ce44SJohn Forte #include <stropts.h>
32*fcf3ce44SJohn Forte #include <stdio.h>
33*fcf3ce44SJohn Forte #include <errno.h>
34*fcf3ce44SJohn Forte #include <libintl.h>
35*fcf3ce44SJohn Forte #include <locale.h>
36*fcf3ce44SJohn Forte #include <stdlib.h>
37*fcf3ce44SJohn Forte 
38*fcf3ce44SJohn Forte #include <sys/nsctl/rdcerr.h>
39*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h>
40*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h>
41*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
42*fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.h>
43*fcf3ce44SJohn Forte #include <sys/nsctl/sv.h>
44*fcf3ce44SJohn Forte 
45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_dtrinkets.h>
46*fcf3ce44SJohn Forte #include <sys/unistat/spcs_etrinkets.h>
47*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
48*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
49*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_impl.h>
50*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
51*fcf3ce44SJohn Forte 
52*fcf3ce44SJohn Forte typedef struct volcount_s {
53*fcf3ce44SJohn Forte 	int count;
54*fcf3ce44SJohn Forte } volcount_t;
55*fcf3ce44SJohn Forte 
56*fcf3ce44SJohn Forte hash_node_t **volhash = NULL;
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte char *
59*fcf3ce44SJohn Forte config2buf(char *buf, rdcconfig_t *rdc)
60*fcf3ce44SJohn Forte {
61*fcf3ce44SJohn Forte 	snprintf(buf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s %s %s %s",
62*fcf3ce44SJohn Forte 	    rdc->phost, rdc->pfile, rdc->pbmp, rdc->shost, rdc->sfile,
63*fcf3ce44SJohn Forte 	    rdc->sbmp, rdc->direct, rdc->mode, rdc->group ? rdc->group : "",
64*fcf3ce44SJohn Forte 	    rdc->ctag ? rdc->ctag : "", rdc->options ? rdc->options : "");
65*fcf3ce44SJohn Forte 	return (buf);
66*fcf3ce44SJohn Forte 
67*fcf3ce44SJohn Forte }
68*fcf3ce44SJohn Forte 
69*fcf3ce44SJohn Forte /*
70*fcf3ce44SJohn Forte  * SV type functions.
71*fcf3ce44SJohn Forte  */
72*fcf3ce44SJohn Forte 
73*fcf3ce44SJohn Forte static void
74*fcf3ce44SJohn Forte load_rdc_vols(CFGFILE *cfg)
75*fcf3ce44SJohn Forte {
76*fcf3ce44SJohn Forte 	int set;
77*fcf3ce44SJohn Forte 	char key[ CFG_MAX_KEY ];
78*fcf3ce44SJohn Forte 	char buf[ CFG_MAX_BUF ];
79*fcf3ce44SJohn Forte 	char *vol, *bmp, *host1, *host2;
80*fcf3ce44SJohn Forte 	volcount_t *volcount;
81*fcf3ce44SJohn Forte 
82*fcf3ce44SJohn Forte 	if (volhash) {
83*fcf3ce44SJohn Forte 		return;
84*fcf3ce44SJohn Forte 	}
85*fcf3ce44SJohn Forte 
86*fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
87*fcf3ce44SJohn Forte 	volhash = nsc_create_hash();
88*fcf3ce44SJohn Forte 	for (set = 1; /*CSTYLED*/; set++) {
89*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d", set);
90*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) {
91*fcf3ce44SJohn Forte 			break;
92*fcf3ce44SJohn Forte 		}
93*fcf3ce44SJohn Forte 
94*fcf3ce44SJohn Forte 		host1 = strtok(buf, " ");
95*fcf3ce44SJohn Forte 		vol = strtok(NULL, " ");
96*fcf3ce44SJohn Forte 		bmp = strtok(NULL, " ");
97*fcf3ce44SJohn Forte 
98*fcf3ce44SJohn Forte 		if (!self_check(host1)) {
99*fcf3ce44SJohn Forte 			/* next one had better be ours */
100*fcf3ce44SJohn Forte 			host2 = strtok(NULL, " ");
101*fcf3ce44SJohn Forte 			vol = strtok(NULL, " ");
102*fcf3ce44SJohn Forte 			bmp = strtok(NULL, " ");
103*fcf3ce44SJohn Forte 
104*fcf3ce44SJohn Forte 			if (!self_check(host2)) {
105*fcf3ce44SJohn Forte 				continue;
106*fcf3ce44SJohn Forte 			}
107*fcf3ce44SJohn Forte 		}
108*fcf3ce44SJohn Forte 
109*fcf3ce44SJohn Forte 		/* primary vol may be used more than once */
110*fcf3ce44SJohn Forte 		volcount = (volcount_t *)nsc_lookup(volhash, vol);
111*fcf3ce44SJohn Forte 		if (volcount) {
112*fcf3ce44SJohn Forte 			volcount->count++;
113*fcf3ce44SJohn Forte 		} else {
114*fcf3ce44SJohn Forte 			volcount = (volcount_t *)malloc(sizeof (volcount_t));
115*fcf3ce44SJohn Forte 			volcount->count = 1;
116*fcf3ce44SJohn Forte 			nsc_insert_node(volhash, volcount, vol);
117*fcf3ce44SJohn Forte 		}
118*fcf3ce44SJohn Forte 
119*fcf3ce44SJohn Forte 		/* bitmap ought to be only used once */
120*fcf3ce44SJohn Forte 		volcount = (volcount_t *)nsc_lookup(volhash, bmp);
121*fcf3ce44SJohn Forte 		if (volcount) {
122*fcf3ce44SJohn Forte 			/* argh */
123*fcf3ce44SJohn Forte 			volcount->count++;
124*fcf3ce44SJohn Forte 		} else {
125*fcf3ce44SJohn Forte 			volcount = (volcount_t *)malloc(sizeof (volcount_t));
126*fcf3ce44SJohn Forte 			volcount->count = 1;
127*fcf3ce44SJohn Forte 			nsc_insert_node(volhash, volcount, bmp);
128*fcf3ce44SJohn Forte 		}
129*fcf3ce44SJohn Forte 	}
130*fcf3ce44SJohn Forte }
131*fcf3ce44SJohn Forte 
132*fcf3ce44SJohn Forte int
133*fcf3ce44SJohn Forte sv_enable_one_nocfg(char *vol)
134*fcf3ce44SJohn Forte {
135*fcf3ce44SJohn Forte 	struct stat sb;
136*fcf3ce44SJohn Forte 	sv_conf_t svc;
137*fcf3ce44SJohn Forte 	int fd;
138*fcf3ce44SJohn Forte 
139*fcf3ce44SJohn Forte 	bzero(&svc, sizeof (svc));
140*fcf3ce44SJohn Forte 	if (stat(vol, &sb) != 0) {
141*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, 0, "unable to stat %s", vol);
142*fcf3ce44SJohn Forte 		return (-1);
143*fcf3ce44SJohn Forte 	}
144*fcf3ce44SJohn Forte 	if (!S_ISCHR(sb.st_mode)) {
145*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, "%s is not"
146*fcf3ce44SJohn Forte 		    " a character device", vol);
147*fcf3ce44SJohn Forte 		return (-1);
148*fcf3ce44SJohn Forte 	}
149*fcf3ce44SJohn Forte 
150*fcf3ce44SJohn Forte 	svc.svc_major = major(sb.st_rdev);
151*fcf3ce44SJohn Forte 	svc.svc_minor = minor(sb.st_rdev);
152*fcf3ce44SJohn Forte 	strncpy(svc.svc_path, vol, sizeof (svc.svc_path));
153*fcf3ce44SJohn Forte 
154*fcf3ce44SJohn Forte 	fd = open(SV_DEVICE, O_RDONLY);
155*fcf3ce44SJohn Forte 	if (fd < 0) {
156*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, 0, 0);
157*fcf3ce44SJohn Forte 		return (-1);
158*fcf3ce44SJohn Forte 	}
159*fcf3ce44SJohn Forte 
160*fcf3ce44SJohn Forte 	svc.svc_flag = (NSC_DEVICE | NSC_CACHE);
161*fcf3ce44SJohn Forte 	svc.svc_error = spcs_s_ucreate();
162*fcf3ce44SJohn Forte 
163*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) {
164*fcf3ce44SJohn Forte 		if (errno != SV_EENABLED) {
165*fcf3ce44SJohn Forte 			rdc_set_error(&svc.svc_error, RDC_INTERNAL,
166*fcf3ce44SJohn Forte 			    RDC_NONFATAL, 0);
167*fcf3ce44SJohn Forte 			return (-1);
168*fcf3ce44SJohn Forte 		}
169*fcf3ce44SJohn Forte 	}
170*fcf3ce44SJohn Forte 
171*fcf3ce44SJohn Forte 	spcs_log("sv", NULL, gettext("enabled %s"), svc.svc_path);
172*fcf3ce44SJohn Forte 
173*fcf3ce44SJohn Forte 	close(fd);
174*fcf3ce44SJohn Forte 	return (1);
175*fcf3ce44SJohn Forte }
176*fcf3ce44SJohn Forte 
177*fcf3ce44SJohn Forte int
178*fcf3ce44SJohn Forte sv_enable_nocfg(rdcconfig_t *rdc)
179*fcf3ce44SJohn Forte {
180*fcf3ce44SJohn Forte 	struct stat stbv;
181*fcf3ce44SJohn Forte 	struct stat stbb;
182*fcf3ce44SJohn Forte 	sv_conf_t svcv;
183*fcf3ce44SJohn Forte 	sv_conf_t svcb;
184*fcf3ce44SJohn Forte 	char	vol[NSC_MAXPATH];
185*fcf3ce44SJohn Forte 	char	bmp[NSC_MAXPATH];
186*fcf3ce44SJohn Forte 	int fd = -1;
187*fcf3ce44SJohn Forte 
188*fcf3ce44SJohn Forte 
189*fcf3ce44SJohn Forte 	if (self_check(rdc->phost)) {
190*fcf3ce44SJohn Forte 		strncpy(vol, rdc->pfile, NSC_MAXPATH);
191*fcf3ce44SJohn Forte 		strncpy(bmp, rdc->pbmp, NSC_MAXPATH);
192*fcf3ce44SJohn Forte 	} else {
193*fcf3ce44SJohn Forte 		strncpy(vol, rdc->sfile, NSC_MAXPATH);
194*fcf3ce44SJohn Forte 		strncpy(bmp, rdc->sbmp, NSC_MAXPATH);
195*fcf3ce44SJohn Forte 	}
196*fcf3ce44SJohn Forte 
197*fcf3ce44SJohn Forte 	bzero(&svcv, sizeof (svcv));
198*fcf3ce44SJohn Forte 	bzero(&svcb, sizeof (svcb));
199*fcf3ce44SJohn Forte 
200*fcf3ce44SJohn Forte 	if ((stat(vol, &stbv) != 0) || (stat(bmp, &stbb) != 0))
201*fcf3ce44SJohn Forte 		return (-1);
202*fcf3ce44SJohn Forte 
203*fcf3ce44SJohn Forte 	if ((!S_ISCHR(stbv.st_mode)) || (!S_ISCHR(stbb.st_mode)))
204*fcf3ce44SJohn Forte 		return (-1);
205*fcf3ce44SJohn Forte 
206*fcf3ce44SJohn Forte 	svcv.svc_major = major(stbv.st_rdev);
207*fcf3ce44SJohn Forte 	svcb.svc_minor = minor(stbb.st_rdev);
208*fcf3ce44SJohn Forte 
209*fcf3ce44SJohn Forte 	strncpy(svcv.svc_path, vol, sizeof (svcv.svc_path));
210*fcf3ce44SJohn Forte 	strncpy(svcb.svc_path, bmp, sizeof (svcb.svc_path));
211*fcf3ce44SJohn Forte 
212*fcf3ce44SJohn Forte 	fd = open(SV_DEVICE, O_RDONLY);
213*fcf3ce44SJohn Forte 	if (fd < 0)
214*fcf3ce44SJohn Forte 		return (-1);
215*fcf3ce44SJohn Forte 
216*fcf3ce44SJohn Forte 	/* SV enable the volume */
217*fcf3ce44SJohn Forte 	svcv.svc_flag = (NSC_DEVICE | NSC_CACHE);
218*fcf3ce44SJohn Forte 	svcv.svc_error = spcs_s_ucreate();
219*fcf3ce44SJohn Forte 
220*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_ENABLE, &svcv) < 0) {
221*fcf3ce44SJohn Forte 		if (errno != SV_EENABLED) {
222*fcf3ce44SJohn Forte 			spcs_log("sv", &svcv.svc_error,
223*fcf3ce44SJohn Forte 			    gettext("unable to enable %s"),
224*fcf3ce44SJohn Forte 			    svcv.svc_path);
225*fcf3ce44SJohn Forte 			spcs_s_ufree(&svcv.svc_error);
226*fcf3ce44SJohn Forte 			return (-1);
227*fcf3ce44SJohn Forte 		}
228*fcf3ce44SJohn Forte 	}
229*fcf3ce44SJohn Forte 
230*fcf3ce44SJohn Forte 	/* SV enable the bitmap disable the vol on error */
231*fcf3ce44SJohn Forte 	svcb.svc_flag = (NSC_DEVICE | NSC_CACHE);
232*fcf3ce44SJohn Forte 	svcb.svc_error = spcs_s_ucreate();
233*fcf3ce44SJohn Forte 
234*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_ENABLE, &svcb) < 0) {
235*fcf3ce44SJohn Forte 		if (errno != SV_EENABLED) {
236*fcf3ce44SJohn Forte 			spcs_log("sv", &svcb.svc_error,
237*fcf3ce44SJohn Forte 			    gettext("unable to enable %s"),
238*fcf3ce44SJohn Forte 			    svcb.svc_path);
239*fcf3ce44SJohn Forte 			if (ioctl(fd, SVIOC_DISABLE, &svcv) < 0)
240*fcf3ce44SJohn Forte 				spcs_log("sv", &svcv.svc_error,
241*fcf3ce44SJohn Forte 				    gettext("unable to disable %s"),
242*fcf3ce44SJohn Forte 				    svcv.svc_path);
243*fcf3ce44SJohn Forte 
244*fcf3ce44SJohn Forte 			spcs_s_ufree(&svcv.svc_error);
245*fcf3ce44SJohn Forte 			spcs_s_ufree(&svcb.svc_error);
246*fcf3ce44SJohn Forte 			return (-1);
247*fcf3ce44SJohn Forte 		}
248*fcf3ce44SJohn Forte 	}
249*fcf3ce44SJohn Forte 
250*fcf3ce44SJohn Forte 
251*fcf3ce44SJohn Forte 	spcs_log("sv", NULL, gettext("enabled %s"), svcv.svc_path);
252*fcf3ce44SJohn Forte 	spcs_log("sv", NULL, gettext("enabled %s"), svcb.svc_path);
253*fcf3ce44SJohn Forte 	spcs_s_ufree(&svcv.svc_error);
254*fcf3ce44SJohn Forte 	spcs_s_ufree(&svcb.svc_error);
255*fcf3ce44SJohn Forte 
256*fcf3ce44SJohn Forte 
257*fcf3ce44SJohn Forte 	if (fd >= 0)
258*fcf3ce44SJohn Forte 		(void) close(fd);
259*fcf3ce44SJohn Forte 
260*fcf3ce44SJohn Forte 	return (1);
261*fcf3ce44SJohn Forte }
262*fcf3ce44SJohn Forte 
263*fcf3ce44SJohn Forte int
264*fcf3ce44SJohn Forte do_autosv_enable(CFGFILE *cfg, rdcconfig_t *rdc)
265*fcf3ce44SJohn Forte {
266*fcf3ce44SJohn Forte 	char vol[NSC_MAXPATH];
267*fcf3ce44SJohn Forte 	char bmp[NSC_MAXPATH];
268*fcf3ce44SJohn Forte 
269*fcf3ce44SJohn Forte 	cfg_load_svols(cfg);
270*fcf3ce44SJohn Forte 	cfg_load_dsvols(cfg);
271*fcf3ce44SJohn Forte 	cfg_load_shadows(cfg);
272*fcf3ce44SJohn Forte 	load_rdc_vols(cfg);
273*fcf3ce44SJohn Forte 
274*fcf3ce44SJohn Forte 	if (self_check(rdc->phost)) {
275*fcf3ce44SJohn Forte 		strncpy(vol, rdc->pfile, NSC_MAXPATH);
276*fcf3ce44SJohn Forte 		strncpy(bmp, rdc->pbmp, NSC_MAXPATH);
277*fcf3ce44SJohn Forte 	} else {
278*fcf3ce44SJohn Forte 		strncpy(vol, rdc->sfile, NSC_MAXPATH);
279*fcf3ce44SJohn Forte 		strncpy(bmp, rdc->sbmp, NSC_MAXPATH);
280*fcf3ce44SJohn Forte 	}
281*fcf3ce44SJohn Forte 	if (nsc_lookup(volhash, vol) == NULL) {
282*fcf3ce44SJohn Forte 		if (cfg_vol_enable(cfg, vol, rdc->ctag, "sndr") < 0) {
283*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
284*fcf3ce44SJohn Forte 			    "auto sv enable failed for %s", vol);
285*fcf3ce44SJohn Forte 			return (-1);
286*fcf3ce44SJohn Forte 		}
287*fcf3ce44SJohn Forte 	}
288*fcf3ce44SJohn Forte 	if (nsc_lookup(volhash, bmp) == NULL) {
289*fcf3ce44SJohn Forte 		if (cfg_vol_enable(cfg, bmp, rdc->ctag, "sndr") < 0) {
290*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
291*fcf3ce44SJohn Forte 			    "auto sv enable failed for %s", vol);
292*fcf3ce44SJohn Forte 			return (-1);
293*fcf3ce44SJohn Forte 		}
294*fcf3ce44SJohn Forte 	}
295*fcf3ce44SJohn Forte 
296*fcf3ce44SJohn Forte 	nsc_remove_all(volhash, free);
297*fcf3ce44SJohn Forte 	volhash = NULL;
298*fcf3ce44SJohn Forte 
299*fcf3ce44SJohn Forte 	cfg_unload_shadows();
300*fcf3ce44SJohn Forte 	cfg_unload_dsvols();
301*fcf3ce44SJohn Forte 	cfg_unload_svols();
302*fcf3ce44SJohn Forte 
303*fcf3ce44SJohn Forte 	return (1);
304*fcf3ce44SJohn Forte }
305*fcf3ce44SJohn Forte 
306*fcf3ce44SJohn Forte int
307*fcf3ce44SJohn Forte do_autosv_disable(CFGFILE *cfg, rdcconfig_t *rdc)
308*fcf3ce44SJohn Forte {
309*fcf3ce44SJohn Forte 	char vol[NSC_MAXPATH];
310*fcf3ce44SJohn Forte 	char bmp[NSC_MAXPATH];
311*fcf3ce44SJohn Forte 	volcount_t *vc;
312*fcf3ce44SJohn Forte 
313*fcf3ce44SJohn Forte 	cfg_load_svols(cfg);
314*fcf3ce44SJohn Forte 	cfg_load_dsvols(cfg);
315*fcf3ce44SJohn Forte 	cfg_load_shadows(cfg);
316*fcf3ce44SJohn Forte 	load_rdc_vols(cfg);
317*fcf3ce44SJohn Forte 
318*fcf3ce44SJohn Forte 	if (self_check(rdc->phost)) {
319*fcf3ce44SJohn Forte 		strncpy(vol, rdc->pfile, NSC_MAXPATH);
320*fcf3ce44SJohn Forte 		strncpy(bmp, rdc->pbmp, NSC_MAXPATH);
321*fcf3ce44SJohn Forte 	} else {
322*fcf3ce44SJohn Forte 		strncpy(vol, rdc->sfile, NSC_MAXPATH);
323*fcf3ce44SJohn Forte 		strncpy(bmp, rdc->sbmp, NSC_MAXPATH);
324*fcf3ce44SJohn Forte 	}
325*fcf3ce44SJohn Forte 
326*fcf3ce44SJohn Forte 	vc = nsc_lookup(volhash, vol);
327*fcf3ce44SJohn Forte 	if (vc && (vc->count == 1)) {
328*fcf3ce44SJohn Forte 		if (cfg_vol_disable(cfg, vol, rdc->ctag, "sndr") < 0)
329*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
330*fcf3ce44SJohn Forte 				"auto sv disable failed for %s", vol);
331*fcf3ce44SJohn Forte 	} else if (!vc) {
332*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
333*fcf3ce44SJohn Forte 		    "Unable to find %s in config", vol);
334*fcf3ce44SJohn Forte 	}
335*fcf3ce44SJohn Forte 	vc = nsc_lookup(volhash, bmp);
336*fcf3ce44SJohn Forte 	if (vc && (vc->count == 1)) {
337*fcf3ce44SJohn Forte 		if (cfg_vol_disable(cfg, bmp, rdc->ctag, "sndr") < 0)
338*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
339*fcf3ce44SJohn Forte 				"auto sv disable failed for %s", bmp);
340*fcf3ce44SJohn Forte 
341*fcf3ce44SJohn Forte 	} else if (!vc) {
342*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
343*fcf3ce44SJohn Forte 		    "Unable to find %s in config", bmp);
344*fcf3ce44SJohn Forte 	}
345*fcf3ce44SJohn Forte 
346*fcf3ce44SJohn Forte 	return (1);
347*fcf3ce44SJohn Forte 
348*fcf3ce44SJohn Forte }
349*fcf3ce44SJohn Forte 
350*fcf3ce44SJohn Forte /*
351*fcf3ce44SJohn Forte  * do sv enables for the appropriate vol
352*fcf3ce44SJohn Forte  * and bitmap. If called without persistance
353*fcf3ce44SJohn Forte  * it will follow a chain and sv enable all
354*fcf3ce44SJohn Forte  * otherwise, it will enable only the one
355*fcf3ce44SJohn Forte  * set.
356*fcf3ce44SJohn Forte  */
357*fcf3ce44SJohn Forte int
358*fcf3ce44SJohn Forte sv_enable(CFGFILE *cfg, rdcconfig_t *rdcs)
359*fcf3ce44SJohn Forte {
360*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp = NULL;
361*fcf3ce44SJohn Forte 
362*fcf3ce44SJohn Forte 	rdcp = rdcs;
363*fcf3ce44SJohn Forte 	if (!rdcp->persist) {
364*fcf3ce44SJohn Forte 
365*fcf3ce44SJohn Forte 		return (sv_enable_nocfg(rdcp));
366*fcf3ce44SJohn Forte 
367*fcf3ce44SJohn Forte 	} else if (cfg == NULL) {
368*fcf3ce44SJohn Forte 
369*fcf3ce44SJohn Forte 		return (-1);
370*fcf3ce44SJohn Forte 
371*fcf3ce44SJohn Forte 	}
372*fcf3ce44SJohn Forte 
373*fcf3ce44SJohn Forte 	do_autosv_enable(cfg, rdcp);
374*fcf3ce44SJohn Forte 
375*fcf3ce44SJohn Forte 	return (1);
376*fcf3ce44SJohn Forte }
377*fcf3ce44SJohn Forte 
378*fcf3ce44SJohn Forte int
379*fcf3ce44SJohn Forte sv_disable(CFGFILE *cfg, rdcconfig_t *rdcs)
380*fcf3ce44SJohn Forte {
381*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
382*fcf3ce44SJohn Forte 
383*fcf3ce44SJohn Forte 	rdcp = rdcs;
384*fcf3ce44SJohn Forte 	if (!rdcp->persist) { /* don't disable */
385*fcf3ce44SJohn Forte 
386*fcf3ce44SJohn Forte 		return (1);
387*fcf3ce44SJohn Forte 
388*fcf3ce44SJohn Forte 	} else if (cfg == NULL) {
389*fcf3ce44SJohn Forte 
390*fcf3ce44SJohn Forte 		return (-1);
391*fcf3ce44SJohn Forte 
392*fcf3ce44SJohn Forte 	}
393*fcf3ce44SJohn Forte 
394*fcf3ce44SJohn Forte 	do_autosv_disable(cfg, rdcp);
395*fcf3ce44SJohn Forte 
396*fcf3ce44SJohn Forte 	return (1);
397*fcf3ce44SJohn Forte 
398*fcf3ce44SJohn Forte }
399*fcf3ce44SJohn Forte 
400*fcf3ce44SJohn Forte /*
401*fcf3ce44SJohn Forte  * disable the appropriate bitmap in rdc
402*fcf3ce44SJohn Forte  * and replace it with bitmap
403*fcf3ce44SJohn Forte  */
404*fcf3ce44SJohn Forte int
405*fcf3ce44SJohn Forte sv_reconfig(CFGFILE *cfg, rdcconfig_t *rdc, char *oldbmp, char *newbmp)
406*fcf3ce44SJohn Forte {
407*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
408*fcf3ce44SJohn Forte 	int fail = 0;
409*fcf3ce44SJohn Forte 
410*fcf3ce44SJohn Forte 	rdcp = rdc;
411*fcf3ce44SJohn Forte 	if (!rdcp->persist) { /* just enable, don't disable */
412*fcf3ce44SJohn Forte 
413*fcf3ce44SJohn Forte 		sv_enable_one_nocfg(newbmp);
414*fcf3ce44SJohn Forte 
415*fcf3ce44SJohn Forte 	} else if (rdcp->persist) { /* do sv disable and enable */
416*fcf3ce44SJohn Forte 		volcount_t *vc;
417*fcf3ce44SJohn Forte 
418*fcf3ce44SJohn Forte 		cfg_load_svols(cfg);
419*fcf3ce44SJohn Forte 		cfg_load_dsvols(cfg);
420*fcf3ce44SJohn Forte 		cfg_load_shadows(cfg);
421*fcf3ce44SJohn Forte 		load_rdc_vols(cfg);
422*fcf3ce44SJohn Forte 
423*fcf3ce44SJohn Forte 		vc = (volcount_t *)nsc_lookup(volhash, oldbmp);
424*fcf3ce44SJohn Forte 		if (vc && (vc->count == 1)) {
425*fcf3ce44SJohn Forte 			if (cfg_vol_disable(cfg, oldbmp, rdc->ctag, "sndr") < 0)
426*fcf3ce44SJohn Forte 				rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
427*fcf3ce44SJohn Forte 				    "auto sv disable failed for %s", oldbmp);
428*fcf3ce44SJohn Forte 
429*fcf3ce44SJohn Forte 		}
430*fcf3ce44SJohn Forte 		if (nsc_lookup(volhash, newbmp) == NULL) {
431*fcf3ce44SJohn Forte 			if (cfg_vol_enable(cfg,
432*fcf3ce44SJohn Forte 			    newbmp, rdc->ctag, "sndr") < 0) {
433*fcf3ce44SJohn Forte 
434*fcf3ce44SJohn Forte 				rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
435*fcf3ce44SJohn Forte 				    "auto sv enable failed for %s", newbmp);
436*fcf3ce44SJohn Forte 				fail++;
437*fcf3ce44SJohn Forte 			}
438*fcf3ce44SJohn Forte 		}
439*fcf3ce44SJohn Forte 		nsc_remove_all(volhash, free);
440*fcf3ce44SJohn Forte 		volhash = NULL;
441*fcf3ce44SJohn Forte 
442*fcf3ce44SJohn Forte 		cfg_unload_shadows();
443*fcf3ce44SJohn Forte 		cfg_unload_dsvols();
444*fcf3ce44SJohn Forte 		cfg_unload_svols();
445*fcf3ce44SJohn Forte 		if (fail)
446*fcf3ce44SJohn Forte 			return (-1);
447*fcf3ce44SJohn Forte 
448*fcf3ce44SJohn Forte 	}
449*fcf3ce44SJohn Forte 	return (1);
450*fcf3ce44SJohn Forte 
451*fcf3ce44SJohn Forte }
452*fcf3ce44SJohn Forte 
453*fcf3ce44SJohn Forte /*
454*fcf3ce44SJohn Forte  * SNDR functions
455*fcf3ce44SJohn Forte  */
456*fcf3ce44SJohn Forte 
457*fcf3ce44SJohn Forte /*
458*fcf3ce44SJohn Forte  * add_to_rdc_cfg
459*fcf3ce44SJohn Forte  * this adds the successfully created rdc sets to libdscfg,
460*fcf3ce44SJohn Forte  * also, as auto_sv stuff is part of libdscfg, it does the
461*fcf3ce44SJohn Forte  * auto_sv stuff and enables the correct volumes
462*fcf3ce44SJohn Forte  */
463*fcf3ce44SJohn Forte int
464*fcf3ce44SJohn Forte add_to_rdc_cfg(rdcconfig_t *rdcs)
465*fcf3ce44SJohn Forte {
466*fcf3ce44SJohn Forte 	CFGFILE *cfg;
467*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
468*fcf3ce44SJohn Forte 	char *buf;
469*fcf3ce44SJohn Forte 
470*fcf3ce44SJohn Forte 
471*fcf3ce44SJohn Forte 	buf = calloc(CFG_MAX_BUF, sizeof (char));
472*fcf3ce44SJohn Forte 	if (!buf) {
473*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
474*fcf3ce44SJohn Forte 		return (NULL);
475*fcf3ce44SJohn Forte 	}
476*fcf3ce44SJohn Forte 
477*fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
478*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, 0);
479*fcf3ce44SJohn Forte 		return (-1);
480*fcf3ce44SJohn Forte 	}
481*fcf3ce44SJohn Forte 	if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) {
482*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, 0);
483*fcf3ce44SJohn Forte 		return (-1);
484*fcf3ce44SJohn Forte 	}
485*fcf3ce44SJohn Forte 
486*fcf3ce44SJohn Forte 	rdcp = rdcs;
487*fcf3ce44SJohn Forte 	while (rdcp)  {
488*fcf3ce44SJohn Forte 		buf = config2buf(buf, rdcp);
489*fcf3ce44SJohn Forte 		if ((sv_enable(cfg, rdcp) < 0) ||
490*fcf3ce44SJohn Forte 		    (cfg_put_cstring(cfg, "sndr", buf, CFG_MAX_BUF) < 0)) {
491*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
492*fcf3ce44SJohn Forte 			free(buf);
493*fcf3ce44SJohn Forte 			return (-1);
494*fcf3ce44SJohn Forte 		}
495*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
496*fcf3ce44SJohn Forte 	}
497*fcf3ce44SJohn Forte 	if (!cfg_commit(cfg)) {
498*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, NULL);
499*fcf3ce44SJohn Forte 		return (-1);
500*fcf3ce44SJohn Forte 	}
501*fcf3ce44SJohn Forte 
502*fcf3ce44SJohn Forte 	cfg_close(cfg);
503*fcf3ce44SJohn Forte 
504*fcf3ce44SJohn Forte 	return (0);
505*fcf3ce44SJohn Forte }
506*fcf3ce44SJohn Forte 
507*fcf3ce44SJohn Forte int
508*fcf3ce44SJohn Forte cfg_lookup(CFGFILE *cfg, char *shost, char *sfile)
509*fcf3ce44SJohn Forte {
510*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
511*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
512*fcf3ce44SJohn Forte 	int setnum;
513*fcf3ce44SJohn Forte 	int numsets = 0;
514*fcf3ce44SJohn Forte 
515*fcf3ce44SJohn Forte 	numsets = cfg_get_num_entries(cfg, "sndr");
516*fcf3ce44SJohn Forte 	for (setnum = 1; setnum <= numsets; setnum++) {
517*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
518*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.shost", setnum);
519*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
520*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
521*fcf3ce44SJohn Forte 			return (-1);
522*fcf3ce44SJohn Forte 		}
523*fcf3ce44SJohn Forte 		if (strncmp(buf, shost, strlen(shost)))
524*fcf3ce44SJohn Forte 			continue;
525*fcf3ce44SJohn Forte 
526*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
527*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.secondary", setnum);
528*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
529*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
530*fcf3ce44SJohn Forte 			return (-1);
531*fcf3ce44SJohn Forte 		}
532*fcf3ce44SJohn Forte 		if (strncmp(buf, sfile, strlen(sfile)))
533*fcf3ce44SJohn Forte 			continue;
534*fcf3ce44SJohn Forte 		break;
535*fcf3ce44SJohn Forte 	}
536*fcf3ce44SJohn Forte 	return (setnum);
537*fcf3ce44SJohn Forte }
538*fcf3ce44SJohn Forte 
539*fcf3ce44SJohn Forte void
540*fcf3ce44SJohn Forte remove_from_rdc_cfg(rdcconfig_t *rdcs)
541*fcf3ce44SJohn Forte {
542*fcf3ce44SJohn Forte 	CFGFILE *cfg;
543*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
544*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
545*fcf3ce44SJohn Forte 
546*fcf3ce44SJohn Forte 	rdcp = rdcs;
547*fcf3ce44SJohn Forte 	cfg = cfg_open(NULL);
548*fcf3ce44SJohn Forte 	cfg_lock(cfg, CFG_WRLOCK);
549*fcf3ce44SJohn Forte 
550*fcf3ce44SJohn Forte 	while (rdcp) {
551*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d",
552*fcf3ce44SJohn Forte 		    cfg_lookup(cfg, rdcp->shost, rdcp->sfile));
553*fcf3ce44SJohn Forte 		if ((sv_disable(cfg, rdcp) < 0) ||
554*fcf3ce44SJohn Forte 		    (cfg_put_cstring(cfg, key, NULL, 0)) < 0) {
555*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
556*fcf3ce44SJohn Forte 		}
557*fcf3ce44SJohn Forte 
558*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
559*fcf3ce44SJohn Forte 	}
560*fcf3ce44SJohn Forte 	cfg_commit(cfg);
561*fcf3ce44SJohn Forte 	cfg_close(cfg);
562*fcf3ce44SJohn Forte }
563*fcf3ce44SJohn Forte /*ARGSUSED*/
564*fcf3ce44SJohn Forte int
565*fcf3ce44SJohn Forte replace_entry(int offset, char *entry)
566*fcf3ce44SJohn Forte {
567*fcf3ce44SJohn Forte 	return (1);
568*fcf3ce44SJohn Forte }
569*fcf3ce44SJohn Forte 
570*fcf3ce44SJohn Forte /*
571*fcf3ce44SJohn Forte  * this will set the value at "field" in dscfg to the
572*fcf3ce44SJohn Forte  * value contained in entry.
573*fcf3ce44SJohn Forte  * for things like bitmap reconfigs, only pass one rdc
574*fcf3ce44SJohn Forte  * not a chain
575*fcf3ce44SJohn Forte  */
576*fcf3ce44SJohn Forte int
577*fcf3ce44SJohn Forte replace_cfgfield(rdcconfig_t *rdc, char *field, char *entry)
578*fcf3ce44SJohn Forte {
579*fcf3ce44SJohn Forte 	CFGFILE *cfg;
580*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
581*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
582*fcf3ce44SJohn Forte 	char newentry[CFG_MAX_BUF];
583*fcf3ce44SJohn Forte 	char oldbmp[CFG_MAX_BUF];
584*fcf3ce44SJohn Forte 	int setnum;
585*fcf3ce44SJohn Forte 	int ispbmp = 0;
586*fcf3ce44SJohn Forte 	int issbmp = 0;
587*fcf3ce44SJohn Forte 
588*fcf3ce44SJohn Forte 	if (strncmp(field, "pbitmap", NSC_MAXPATH) == 0)
589*fcf3ce44SJohn Forte 		ispbmp++;
590*fcf3ce44SJohn Forte 	if (strncmp(field, "sbitmap", NSC_MAXPATH) == 0)
591*fcf3ce44SJohn Forte 		issbmp++;
592*fcf3ce44SJohn Forte 
593*fcf3ce44SJohn Forte 	bzero(newentry, sizeof (newentry));
594*fcf3ce44SJohn Forte 	if (!entry || strlen(entry) == 0)
595*fcf3ce44SJohn Forte 		*newentry = '-';
596*fcf3ce44SJohn Forte 	else
597*fcf3ce44SJohn Forte 		strncpy(newentry, entry, CFG_MAX_BUF);
598*fcf3ce44SJohn Forte 
599*fcf3ce44SJohn Forte 
600*fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
601*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, 0);
602*fcf3ce44SJohn Forte 		return (-1);
603*fcf3ce44SJohn Forte 	}
604*fcf3ce44SJohn Forte 	if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) {
605*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, 0);
606*fcf3ce44SJohn Forte 		return (-1);
607*fcf3ce44SJohn Forte 	}
608*fcf3ce44SJohn Forte 
609*fcf3ce44SJohn Forte 	rdcp = rdc;
610*fcf3ce44SJohn Forte 	while (rdcp) {
611*fcf3ce44SJohn Forte 		if ((setnum = cfg_lookup(cfg, rdcp->shost, rdcp->sfile)) < 0) {
612*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
613*fcf3ce44SJohn Forte 			return (-1);
614*fcf3ce44SJohn Forte 		}
615*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.%s", setnum, field);
616*fcf3ce44SJohn Forte 		if (!((ispbmp || issbmp) &&
617*fcf3ce44SJohn Forte 		    (cfg_get_cstring(cfg, key, oldbmp, CFG_MAX_BUF)) == 0)) {
618*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, "unable to get %s",
619*fcf3ce44SJohn Forte 			    key);
620*fcf3ce44SJohn Forte 		}
621*fcf3ce44SJohn Forte 		if (((ispbmp && self_check(rdcp->phost)) ||
622*fcf3ce44SJohn Forte 		    (issbmp && self_check(rdcp->shost))) &&
623*fcf3ce44SJohn Forte 		    (sv_reconfig(cfg, rdcp, oldbmp, newentry) < 0)) {
624*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
625*fcf3ce44SJohn Forte 			    "unable to sv reconfig %s to %s", oldbmp, newentry);
626*fcf3ce44SJohn Forte 			return (-1);
627*fcf3ce44SJohn Forte 		}
628*fcf3ce44SJohn Forte 
629*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, newentry, CFG_MAX_BUF)) < 0) {
630*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
631*fcf3ce44SJohn Forte 			return (-1);
632*fcf3ce44SJohn Forte 		}
633*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
634*fcf3ce44SJohn Forte 	}
635*fcf3ce44SJohn Forte 	cfg_commit(cfg);
636*fcf3ce44SJohn Forte 	cfg_close(cfg);
637*fcf3ce44SJohn Forte 	return (1);
638*fcf3ce44SJohn Forte }
639*fcf3ce44SJohn Forte 
640*fcf3ce44SJohn Forte /*
641*fcf3ce44SJohn Forte  * reverse_in_cfg
642*fcf3ce44SJohn Forte  * used by RDC_OPT_REVERSE_ROLE
643*fcf3ce44SJohn Forte  * swaps primary info and secondary info
644*fcf3ce44SJohn Forte  */
645*fcf3ce44SJohn Forte int
646*fcf3ce44SJohn Forte reverse_in_cfg(rdcconfig_t *rdc)
647*fcf3ce44SJohn Forte {
648*fcf3ce44SJohn Forte 	CFGFILE *cfg;
649*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp = NULL;
650*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
651*fcf3ce44SJohn Forte 	int setnum;
652*fcf3ce44SJohn Forte 
653*fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
654*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, 0);
655*fcf3ce44SJohn Forte 		return (-1);
656*fcf3ce44SJohn Forte 	}
657*fcf3ce44SJohn Forte 	if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) {
658*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, 0);
659*fcf3ce44SJohn Forte 		return (-1);
660*fcf3ce44SJohn Forte 	}
661*fcf3ce44SJohn Forte 
662*fcf3ce44SJohn Forte 	rdcp = rdc;
663*fcf3ce44SJohn Forte 	while (rdcp) {
664*fcf3ce44SJohn Forte 		if ((setnum = cfg_lookup(cfg, rdcp->shost, rdcp->sfile)) < 0) {
665*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
666*fcf3ce44SJohn Forte 			goto badconfig;
667*fcf3ce44SJohn Forte 		}
668*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
669*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.phost", setnum);
670*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, rdcp->shost, CFG_MAX_BUF)) < 0) {
671*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
672*fcf3ce44SJohn Forte 			goto badconfig;
673*fcf3ce44SJohn Forte 		}
674*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
675*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.primary", setnum);
676*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, rdcp->sfile, CFG_MAX_BUF)) < 0) {
677*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
678*fcf3ce44SJohn Forte 			goto badconfig;
679*fcf3ce44SJohn Forte 		}
680*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
681*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.pbitmap", setnum);
682*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, rdcp->sbmp, CFG_MAX_BUF)) < 0) {
683*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
684*fcf3ce44SJohn Forte 			goto badconfig;
685*fcf3ce44SJohn Forte 		}
686*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
687*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.shost", setnum);
688*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, rdcp->phost, CFG_MAX_BUF)) < 0) {
689*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
690*fcf3ce44SJohn Forte 			goto badconfig;
691*fcf3ce44SJohn Forte 		}
692*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
693*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.secondary", setnum);
694*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, rdcp->pfile, CFG_MAX_BUF)) < 0) {
695*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
696*fcf3ce44SJohn Forte 			goto badconfig;
697*fcf3ce44SJohn Forte 		}
698*fcf3ce44SJohn Forte 		bzero(key, CFG_MAX_KEY);
699*fcf3ce44SJohn Forte 		snprintf(key, CFG_MAX_KEY, "sndr.set%d.sbitmap", setnum);
700*fcf3ce44SJohn Forte 		if ((cfg_put_cstring(cfg, key, rdcp->pbmp, CFG_MAX_BUF)) < 0) {
701*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_DSCFG, 0, 0);
702*fcf3ce44SJohn Forte 			goto badconfig;
703*fcf3ce44SJohn Forte 		}
704*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
705*fcf3ce44SJohn Forte 	}
706*fcf3ce44SJohn Forte 	if (!cfg_commit(cfg)) {
707*fcf3ce44SJohn Forte 		cfg_close(cfg);
708*fcf3ce44SJohn Forte 		return (-1);
709*fcf3ce44SJohn Forte 	}
710*fcf3ce44SJohn Forte 	cfg_close(cfg);
711*fcf3ce44SJohn Forte 	return (0);
712*fcf3ce44SJohn Forte 
713*fcf3ce44SJohn Forte badconfig:
714*fcf3ce44SJohn Forte 	cfg_close(cfg);
715*fcf3ce44SJohn Forte 	return (-1);
716*fcf3ce44SJohn Forte }
717