xref: /titanic_52/usr/src/lib/librdc/common/rdcconfig.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 
27*fcf3ce44SJohn Forte #include <sys/types.h>
28*fcf3ce44SJohn Forte #include <stdio.h>
29*fcf3ce44SJohn Forte #include <errno.h>
30*fcf3ce44SJohn Forte #include <strings.h>
31*fcf3ce44SJohn Forte #include <stdlib.h>
32*fcf3ce44SJohn Forte #include <unistd.h>
33*fcf3ce44SJohn Forte #include <netdb.h>
34*fcf3ce44SJohn Forte #include <sys/stream.h>
35*fcf3ce44SJohn Forte #include <sys/socket.h>
36*fcf3ce44SJohn Forte #include <netinet/in.h>
37*fcf3ce44SJohn Forte #include <arpa/inet.h>
38*fcf3ce44SJohn Forte #include <ctype.h>
39*fcf3ce44SJohn Forte #include <thread.h>
40*fcf3ce44SJohn Forte #include <pthread.h>
41*fcf3ce44SJohn Forte 
42*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
43*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
44*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_impl.h>
45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
46*fcf3ce44SJohn Forte 
47*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_io.h>
48*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h>
49*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_prot.h>
50*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h>
51*fcf3ce44SJohn Forte #include <sys/nsctl/rdcrules.h>
52*fcf3ce44SJohn Forte #include <sys/nsctl/rdcerr.h>
53*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
54*fcf3ce44SJohn Forte 
55*fcf3ce44SJohn Forte #include <sys/unistat/spcs_dtrinkets.h>
56*fcf3ce44SJohn Forte #include <sys/unistat/spcs_etrinkets.h>
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte #include <sys/socket.h>
59*fcf3ce44SJohn Forte #include <netinet/in.h>
60*fcf3ce44SJohn Forte #include <arpa/inet.h>
61*fcf3ce44SJohn Forte #include <netinet/tcp.h>
62*fcf3ce44SJohn Forte #include <rpc/rpc_com.h>
63*fcf3ce44SJohn Forte #include <rpc/rpc.h>
64*fcf3ce44SJohn Forte 
65*fcf3ce44SJohn Forte struct netbuf svaddr, *svp;
66*fcf3ce44SJohn Forte struct netconfig nconf, *conf;
67*fcf3ce44SJohn Forte struct knetconfig knconf;
68*fcf3ce44SJohn Forte 
69*fcf3ce44SJohn Forte /*
70*fcf3ce44SJohn Forte  * libdscfg type stuff here
71*fcf3ce44SJohn Forte  */
72*fcf3ce44SJohn Forte extern int sv_enable(CFGFILE *cfg, rdcconfig_t *rdc);
73*fcf3ce44SJohn Forte extern int add_to_rdc_cfg(rdcconfig_t *rdcs);
74*fcf3ce44SJohn Forte extern int remove_from_rdc_cfg(rdcconfig_t *rdcs);
75*fcf3ce44SJohn Forte extern int replace_cfgfield(rdcconfig_t *rdcs, char *field, char *value);
76*fcf3ce44SJohn Forte extern int reverse_in_cfg(rdcconfig_t *rdcs);
77*fcf3ce44SJohn Forte 
78*fcf3ce44SJohn Forte rdcconfig_t *
79*fcf3ce44SJohn Forte rdc_dup_config(rdcconfig_t *orig)
80*fcf3ce44SJohn Forte {
81*fcf3ce44SJohn Forte 	rdcconfig_t *rc;
82*fcf3ce44SJohn Forte 
83*fcf3ce44SJohn Forte 	rc = (rdcconfig_t *)calloc(1, sizeof (*rc));
84*fcf3ce44SJohn Forte 	if (!rc) {
85*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
86*fcf3ce44SJohn Forte 		return (NULL);
87*fcf3ce44SJohn Forte 	}
88*fcf3ce44SJohn Forte 
89*fcf3ce44SJohn Forte 	*rc = *orig;
90*fcf3ce44SJohn Forte 	rc->next = NULL; /* don't want to hook into wrong chaing */
91*fcf3ce44SJohn Forte 	return (rc);
92*fcf3ce44SJohn Forte }
93*fcf3ce44SJohn Forte 
94*fcf3ce44SJohn Forte /*
95*fcf3ce44SJohn Forte  * takes in a chain of rdcconfig_t's and a chain
96*fcf3ce44SJohn Forte  * of rdc_rc_t's, checks for success in the rdc_rc_t,
97*fcf3ce44SJohn Forte  * then adds the corresponding rdcconfig_t to the return
98*fcf3ce44SJohn Forte  * chain.
99*fcf3ce44SJohn Forte  */
100*fcf3ce44SJohn Forte rdcconfig_t *
101*fcf3ce44SJohn Forte chain_successful(rdcconfig_t *rdcs, rdc_rc_t *rcs)
102*fcf3ce44SJohn Forte {
103*fcf3ce44SJohn Forte 	rdc_rc_t *rcp;
104*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
105*fcf3ce44SJohn Forte 	rdcconfig_t *ret = NULL;
106*fcf3ce44SJohn Forte 	rdcconfig_t *retp = NULL;
107*fcf3ce44SJohn Forte 
108*fcf3ce44SJohn Forte 	rcp = rcs;
109*fcf3ce44SJohn Forte 	rdcp = rdcs;
110*fcf3ce44SJohn Forte 
111*fcf3ce44SJohn Forte 	while (rcp) {
112*fcf3ce44SJohn Forte 		if (rcp->rc == 0) {
113*fcf3ce44SJohn Forte 			if ((ret == NULL) && (rdcp->persist)) {
114*fcf3ce44SJohn Forte 				retp = ret = rdc_dup_config(rdcp);
115*fcf3ce44SJohn Forte 
116*fcf3ce44SJohn Forte 			} else if ((ret) && (rdcp->persist)) {
117*fcf3ce44SJohn Forte 				retp->next = rdc_dup_config(rdcp);
118*fcf3ce44SJohn Forte 				retp = retp->next;
119*fcf3ce44SJohn Forte 			}
120*fcf3ce44SJohn Forte 		}
121*fcf3ce44SJohn Forte 		rcp = rcp->next;
122*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
123*fcf3ce44SJohn Forte 	}
124*fcf3ce44SJohn Forte 	return (ret);
125*fcf3ce44SJohn Forte 
126*fcf3ce44SJohn Forte }
127*fcf3ce44SJohn Forte 
128*fcf3ce44SJohn Forte rdc_set_t
129*fcf3ce44SJohn Forte config2set(rdcconfig_t *rdc)
130*fcf3ce44SJohn Forte {
131*fcf3ce44SJohn Forte 	rdc_set_t urdc;
132*fcf3ce44SJohn Forte 
133*fcf3ce44SJohn Forte 	bzero(&urdc, sizeof (rdc_set_t));
134*fcf3ce44SJohn Forte 	strncpy(urdc.primary.intf, rdc->phost, MAX_RDC_HOST_SIZE);
135*fcf3ce44SJohn Forte 	strncpy(urdc.primary.file, rdc->pfile, NSC_MAXPATH);
136*fcf3ce44SJohn Forte 	strncpy(urdc.primary.bitmap, rdc->pbmp, NSC_MAXPATH);
137*fcf3ce44SJohn Forte 	strncpy(urdc.secondary.intf, rdc->shost, MAX_RDC_HOST_SIZE);
138*fcf3ce44SJohn Forte 	strncpy(urdc.secondary.file, rdc->sfile, NSC_MAXPATH);
139*fcf3ce44SJohn Forte 	strncpy(urdc.secondary.bitmap, rdc->sbmp, NSC_MAXPATH);
140*fcf3ce44SJohn Forte 	strncpy(urdc.group_name, rdc->group, NSC_MAXPATH);
141*fcf3ce44SJohn Forte 
142*fcf3ce44SJohn Forte 	return (urdc);
143*fcf3ce44SJohn Forte }
144*fcf3ce44SJohn Forte 
145*fcf3ce44SJohn Forte rdc_rc_t *
146*fcf3ce44SJohn Forte new_rc()
147*fcf3ce44SJohn Forte {
148*fcf3ce44SJohn Forte 	rdc_rc_t *rc;
149*fcf3ce44SJohn Forte 
150*fcf3ce44SJohn Forte 	rc = (rdc_rc_t *)calloc(1, sizeof (*rc));
151*fcf3ce44SJohn Forte 	if (rc == NULL) {
152*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
153*fcf3ce44SJohn Forte 		return (NULL);
154*fcf3ce44SJohn Forte 	}
155*fcf3ce44SJohn Forte 	return (rc);
156*fcf3ce44SJohn Forte }
157*fcf3ce44SJohn Forte 
158*fcf3ce44SJohn Forte rdc_rc_t
159*fcf3ce44SJohn Forte rdc_config(rdc_config_t *rdccfg)
160*fcf3ce44SJohn Forte {
161*fcf3ce44SJohn Forte 	rdc_rc_t rc;
162*fcf3ce44SJohn Forte 	rdc_set_t *set;
163*fcf3ce44SJohn Forte 	spcs_s_info_t ustatus;
164*fcf3ce44SJohn Forte 
165*fcf3ce44SJohn Forte 	bzero(&rc, sizeof (rc));
166*fcf3ce44SJohn Forte 	ustatus = spcs_s_ucreate();
167*fcf3ce44SJohn Forte 
168*fcf3ce44SJohn Forte 	if (self_check(rdccfg->rdc_set->primary.intf)) {
169*fcf3ce44SJohn Forte 		rdccfg->options |= RDC_OPT_PRIMARY;
170*fcf3ce44SJohn Forte 		/* this needs changin if we do campus */
171*fcf3ce44SJohn Forte 		rdccfg->rdc_set->direct_file[0] = 0;
172*fcf3ce44SJohn Forte 	} else {
173*fcf3ce44SJohn Forte 		rdccfg->options |= RDC_OPT_SECONDARY;
174*fcf3ce44SJohn Forte 	}
175*fcf3ce44SJohn Forte 
176*fcf3ce44SJohn Forte 	/* set up return stuff.. */
177*fcf3ce44SJohn Forte 	set = &rdccfg->rdc_set[0];
178*fcf3ce44SJohn Forte 	strncpy(rc.set.phost, set->primary.intf, MAX_RDC_HOST_SIZE);
179*fcf3ce44SJohn Forte 	strncpy(rc.set.pfile, set->primary.file, NSC_MAXPATH);
180*fcf3ce44SJohn Forte 	strncpy(rc.set.shost, set->secondary.intf, MAX_RDC_HOST_SIZE);
181*fcf3ce44SJohn Forte 	strncpy(rc.set.sfile, set->secondary.file, NSC_MAXPATH);
182*fcf3ce44SJohn Forte 
183*fcf3ce44SJohn Forte 	rc.rc = RDC_IOCTL(RDC_CONFIG, rdccfg, NULL, 0, 0, 0, ustatus);
184*fcf3ce44SJohn Forte 
185*fcf3ce44SJohn Forte 	if (rc.rc < 0) {
186*fcf3ce44SJohn Forte 		rdc_set_error(&ustatus, RDC_SPCS, 0, 0);
187*fcf3ce44SJohn Forte 		strncpy(rc.msg, rdc_error(NULL), RDC_ERR_SIZE);
188*fcf3ce44SJohn Forte 	}
189*fcf3ce44SJohn Forte 
190*fcf3ce44SJohn Forte 	return (rc);
191*fcf3ce44SJohn Forte }
192*fcf3ce44SJohn Forte 
193*fcf3ce44SJohn Forte void *
194*fcf3ce44SJohn Forte rdc_mtconfig(void *rdc)
195*fcf3ce44SJohn Forte {
196*fcf3ce44SJohn Forte 	rdc_rc_t *rc[1];
197*fcf3ce44SJohn Forte 	rdc_set_t *set;
198*fcf3ce44SJohn Forte 	spcs_s_info_t ustatus;
199*fcf3ce44SJohn Forte 	rdc_config_t *rdccfg = (rdc_config_t *)rdc;
200*fcf3ce44SJohn Forte 
201*fcf3ce44SJohn Forte 	ustatus = spcs_s_ucreate();
202*fcf3ce44SJohn Forte 
203*fcf3ce44SJohn Forte 	if (self_check(rdccfg->rdc_set->primary.intf)) {
204*fcf3ce44SJohn Forte 		rdccfg->options |= RDC_OPT_PRIMARY;
205*fcf3ce44SJohn Forte 		/* this needs changin if we do campus */
206*fcf3ce44SJohn Forte 		rdccfg->rdc_set->direct_file[0] = 0;
207*fcf3ce44SJohn Forte 	} else {
208*fcf3ce44SJohn Forte 		rdccfg->options |= RDC_OPT_SECONDARY;
209*fcf3ce44SJohn Forte 	}
210*fcf3ce44SJohn Forte 
211*fcf3ce44SJohn Forte 	set = &rdccfg->rdc_set[0];
212*fcf3ce44SJohn Forte 	*rc = new_rc();
213*fcf3ce44SJohn Forte 
214*fcf3ce44SJohn Forte 	strncpy(rc[0]->set.phost, set->primary.intf, MAX_RDC_HOST_SIZE);
215*fcf3ce44SJohn Forte 	strncpy(rc[0]->set.pfile, set->primary.file, NSC_MAXPATH);
216*fcf3ce44SJohn Forte 	strncpy(rc[0]->set.pbmp, set->primary.bitmap, NSC_MAXPATH);
217*fcf3ce44SJohn Forte 	strncpy(rc[0]->set.shost, set->secondary.intf, MAX_RDC_HOST_SIZE);
218*fcf3ce44SJohn Forte 	strncpy(rc[0]->set.sfile, set->secondary.file, NSC_MAXPATH);
219*fcf3ce44SJohn Forte 	strncpy(rc[0]->set.sbmp, set->secondary.bitmap, NSC_MAXPATH);
220*fcf3ce44SJohn Forte 
221*fcf3ce44SJohn Forte 	rc[0]->rc = RDC_IOCTL(RDC_CONFIG, rdccfg, NULL, 0, 0, 0, ustatus);
222*fcf3ce44SJohn Forte 
223*fcf3ce44SJohn Forte 	if (rc[0]->rc < 0) {
224*fcf3ce44SJohn Forte 		rdc_set_error(&ustatus, RDC_SPCS, 0, 0);
225*fcf3ce44SJohn Forte 		strncpy(rc[0]->msg, rdc_error(NULL), RDC_ERR_SIZE);
226*fcf3ce44SJohn Forte 	}
227*fcf3ce44SJohn Forte 
228*fcf3ce44SJohn Forte 	sleep(1); /* give thr_join a chance to be called */
229*fcf3ce44SJohn Forte 	free(rdccfg);
230*fcf3ce44SJohn Forte 	thr_exit((void **) *rc);
231*fcf3ce44SJohn Forte 	return (NULL);
232*fcf3ce44SJohn Forte }
233*fcf3ce44SJohn Forte int
234*fcf3ce44SJohn Forte populate_addrs(rdc_set_t *urdc, int isenable)
235*fcf3ce44SJohn Forte {
236*fcf3ce44SJohn Forte 	struct t_info tinfo;
237*fcf3ce44SJohn Forte 	struct hostent *hp;
238*fcf3ce44SJohn Forte 	char toname[MAX_RDC_HOST_SIZE];
239*fcf3ce44SJohn Forte 	char fromname[MAX_RDC_HOST_SIZE];
240*fcf3ce44SJohn Forte 
241*fcf3ce44SJohn Forte 	strncpy(fromname, urdc->primary.intf, MAX_RDC_HOST_SIZE);
242*fcf3ce44SJohn Forte 	strncpy(toname, urdc->secondary.intf, MAX_RDC_HOST_SIZE);
243*fcf3ce44SJohn Forte 
244*fcf3ce44SJohn Forte 	if ((fromname[0] == '\0') || (fromname[0] == '\0')) {
245*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_FATAL,
246*fcf3ce44SJohn Forte 		    "NULL hostname recieved");
247*fcf3ce44SJohn Forte 		    return (-1);
248*fcf3ce44SJohn Forte 	}
249*fcf3ce44SJohn Forte 
250*fcf3ce44SJohn Forte 	hp = gethost_byname(fromname);
251*fcf3ce44SJohn Forte 	strncpy(fromname, hp->h_name, MAX_RDC_HOST_SIZE);
252*fcf3ce44SJohn Forte 	hp = gethost_byname(toname);
253*fcf3ce44SJohn Forte 	strncpy(toname, hp->h_name, MAX_RDC_HOST_SIZE);
254*fcf3ce44SJohn Forte 
255*fcf3ce44SJohn Forte 	if (self_check(fromname) && self_check(toname)) {
256*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_FATAL, "");
257*fcf3ce44SJohn Forte 	}
258*fcf3ce44SJohn Forte 
259*fcf3ce44SJohn Forte 	if (isenable) {
260*fcf3ce44SJohn Forte 		svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
261*fcf3ce44SJohn Forte 		    &conf, NULL, "rdc", &tinfo, 0);
262*fcf3ce44SJohn Forte 		if (svp == NULL)
263*fcf3ce44SJohn Forte 			return (-1);
264*fcf3ce44SJohn Forte 		svaddr = *svp;
265*fcf3ce44SJohn Forte 	} else {
266*fcf3ce44SJohn Forte 		bzero(&svaddr, sizeof (svaddr));
267*fcf3ce44SJohn Forte 	}
268*fcf3ce44SJohn Forte 
269*fcf3ce44SJohn Forte 	urdc->secondary.addr.len = svaddr.len;
270*fcf3ce44SJohn Forte 	urdc->secondary.addr.maxlen = svaddr.maxlen;
271*fcf3ce44SJohn Forte 	urdc->secondary.addr.buf = (void*)svaddr.buf;
272*fcf3ce44SJohn Forte 
273*fcf3ce44SJohn Forte 	if (isenable) {
274*fcf3ce44SJohn Forte 		svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
275*fcf3ce44SJohn Forte 		    &conf, NULL, "rdc", &tinfo, 0);
276*fcf3ce44SJohn Forte 		if (svp == NULL)
277*fcf3ce44SJohn Forte 			return (-1);
278*fcf3ce44SJohn Forte 		svaddr = *svp;
279*fcf3ce44SJohn Forte 	} else {
280*fcf3ce44SJohn Forte 		bzero(&svaddr, sizeof (svaddr));
281*fcf3ce44SJohn Forte 	}
282*fcf3ce44SJohn Forte 
283*fcf3ce44SJohn Forte 	urdc->primary.addr.len = svaddr.len;
284*fcf3ce44SJohn Forte 	urdc->primary.addr.maxlen = svaddr.maxlen;
285*fcf3ce44SJohn Forte 	urdc->primary.addr.buf = (void*)svaddr.buf;
286*fcf3ce44SJohn Forte 
287*fcf3ce44SJohn Forte 	if (isenable) {
288*fcf3ce44SJohn Forte 		convert_nconf_to_knconf(conf, &knconf);
289*fcf3ce44SJohn Forte 		urdc->netconfig = &knconf;
290*fcf3ce44SJohn Forte 	} else {
291*fcf3ce44SJohn Forte 		urdc->netconfig = NULL;
292*fcf3ce44SJohn Forte 	}
293*fcf3ce44SJohn Forte 	urdc->syshostid = (int32_t)gethostid();
294*fcf3ce44SJohn Forte 
295*fcf3ce44SJohn Forte 	return (1);
296*fcf3ce44SJohn Forte 
297*fcf3ce44SJohn Forte }
298*fcf3ce44SJohn Forte void
299*fcf3ce44SJohn Forte rdc_free_config(rdcconfig_t *rdc, int all)
300*fcf3ce44SJohn Forte {
301*fcf3ce44SJohn Forte 	rdcconfig_t *rdcp;
302*fcf3ce44SJohn Forte 	rdcconfig_t *rdcq;
303*fcf3ce44SJohn Forte 
304*fcf3ce44SJohn Forte 	rdcp = rdc;
305*fcf3ce44SJohn Forte 	if (all == RDC_FREEONE) {
306*fcf3ce44SJohn Forte 		free(rdcp);
307*fcf3ce44SJohn Forte 	} else while (rdcp) {
308*fcf3ce44SJohn Forte 		rdcq = rdcp->next;
309*fcf3ce44SJohn Forte 		free(rdcp);
310*fcf3ce44SJohn Forte 		rdcp = rdcq;
311*fcf3ce44SJohn Forte 	}
312*fcf3ce44SJohn Forte 	rdc = NULL;
313*fcf3ce44SJohn Forte }
314*fcf3ce44SJohn Forte 
315*fcf3ce44SJohn Forte void
316*fcf3ce44SJohn Forte rdc_free_rclist(rdc_rc_t *rc) {
317*fcf3ce44SJohn Forte 	rdc_rc_t *rcp, *rcq;
318*fcf3ce44SJohn Forte 
319*fcf3ce44SJohn Forte 	rcp = rc;
320*fcf3ce44SJohn Forte 	while (rcp) {
321*fcf3ce44SJohn Forte 		rcq = rcp->next;
322*fcf3ce44SJohn Forte 		free(rcp);
323*fcf3ce44SJohn Forte 		rcp = rcq;
324*fcf3ce44SJohn Forte 	}
325*fcf3ce44SJohn Forte 
326*fcf3ce44SJohn Forte }
327*fcf3ce44SJohn Forte /*ARGSUSED*/
328*fcf3ce44SJohn Forte rdcconfig_t *
329*fcf3ce44SJohn Forte rdc_alloc_config(const char *phost, const char *pfile,
330*fcf3ce44SJohn Forte     const char *pbmp, const char *shost, const char *sfile, const char *sbmp,
331*fcf3ce44SJohn Forte     const char *mode, const char *group, const char *ctag, const char *options,
332*fcf3ce44SJohn Forte     int persist)
333*fcf3ce44SJohn Forte {
334*fcf3ce44SJohn Forte 	rdcconfig_t *rc;
335*fcf3ce44SJohn Forte 
336*fcf3ce44SJohn Forte 	rc = (rdcconfig_t *)calloc(1, sizeof (*rc));
337*fcf3ce44SJohn Forte 	if (!rc) {
338*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
339*fcf3ce44SJohn Forte 		return (NULL);
340*fcf3ce44SJohn Forte 	}
341*fcf3ce44SJohn Forte 	if (phost)
342*fcf3ce44SJohn Forte 		strncpy(rc->phost, phost, NSC_MAXPATH);
343*fcf3ce44SJohn Forte 	if (pfile)
344*fcf3ce44SJohn Forte 		strncpy(rc->pfile, pfile, NSC_MAXPATH);
345*fcf3ce44SJohn Forte 	if (pbmp)
346*fcf3ce44SJohn Forte 		strncpy(rc->pbmp, pbmp, NSC_MAXPATH);
347*fcf3ce44SJohn Forte 	if (shost)
348*fcf3ce44SJohn Forte 		strncpy(rc->shost, shost, NSC_MAXPATH);
349*fcf3ce44SJohn Forte 	if (sfile)
350*fcf3ce44SJohn Forte 		strncpy(rc->sfile, sfile, NSC_MAXPATH);
351*fcf3ce44SJohn Forte 	if (sbmp)
352*fcf3ce44SJohn Forte 		strncpy(rc->sbmp, sbmp, NSC_MAXPATH);
353*fcf3ce44SJohn Forte 
354*fcf3ce44SJohn Forte 	strncpy(rc->direct, "ip", 2);
355*fcf3ce44SJohn Forte 
356*fcf3ce44SJohn Forte 	if (mode)
357*fcf3ce44SJohn Forte 		strncpy(rc->mode, mode, NSC_MAXPATH);
358*fcf3ce44SJohn Forte 	if (ctag)
359*fcf3ce44SJohn Forte 		strncpy(rc->ctag, ctag, NSC_MAXPATH);
360*fcf3ce44SJohn Forte 	if (options)
361*fcf3ce44SJohn Forte 		strncpy(rc->options, options, NSC_MAXPATH);
362*fcf3ce44SJohn Forte 
363*fcf3ce44SJohn Forte 	rc->persist = persist;
364*fcf3ce44SJohn Forte 	rc->next = NULL;
365*fcf3ce44SJohn Forte 
366*fcf3ce44SJohn Forte 	return (rc);
367*fcf3ce44SJohn Forte 
368*fcf3ce44SJohn Forte }
369*fcf3ce44SJohn Forte 
370*fcf3ce44SJohn Forte void
371*fcf3ce44SJohn Forte populate_rc(rdc_rc_t *rcp, rdcconfig_t *rdcp)
372*fcf3ce44SJohn Forte {
373*fcf3ce44SJohn Forte 	rcp->rc = -1;
374*fcf3ce44SJohn Forte 	strncpy(rcp->msg, rdc_error(NULL), RDC_ERR_SIZE);
375*fcf3ce44SJohn Forte 	strncpy(rcp->set.phost, rdcp->phost, NSC_MAXPATH);
376*fcf3ce44SJohn Forte 	strncpy(rcp->set.pfile, rdcp->pfile, NSC_MAXPATH);
377*fcf3ce44SJohn Forte 	strncpy(rcp->set.shost, rdcp->shost, NSC_MAXPATH);
378*fcf3ce44SJohn Forte 	strncpy(rcp->set.sfile, rdcp->sfile, NSC_MAXPATH);
379*fcf3ce44SJohn Forte }
380*fcf3ce44SJohn Forte 
381*fcf3ce44SJohn Forte /*
382*fcf3ce44SJohn Forte  * rdc_enable
383*fcf3ce44SJohn Forte  * return values
384*fcf3ce44SJohn Forte  * NULL on error
385*fcf3ce44SJohn Forte  * pointer to rdc_rc_t list of return values
386*fcf3ce44SJohn Forte  */
387*fcf3ce44SJohn Forte rdc_rc_t *
388*fcf3ce44SJohn Forte rdc_enable(rdcconfig_t *rdc)
389*fcf3ce44SJohn Forte {
390*fcf3ce44SJohn Forte 	rdc_config_t 	rdccfg;
391*fcf3ce44SJohn Forte 	rdcconfig_t 	*rdcp = NULL;
392*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
393*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
394*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
395*fcf3ce44SJohn Forte 
396*fcf3ce44SJohn Forte 	rdcp = rdc;
397*fcf3ce44SJohn Forte 	rc = new_rc();
398*fcf3ce44SJohn Forte 	if (!rc) { /* error already set */
399*fcf3ce44SJohn Forte 		return (NULL);
400*fcf3ce44SJohn Forte 	}
401*fcf3ce44SJohn Forte 	rcp = rc;
402*fcf3ce44SJohn Forte 	while (rdcp) {
403*fcf3ce44SJohn Forte 		if (!rdcp->mode) {
404*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
405*fcf3ce44SJohn Forte 			    RDC_EINVAL);
406*fcf3ce44SJohn Forte 			return (NULL);
407*fcf3ce44SJohn Forte 		}
408*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
409*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
410*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_ENABLE;
411*fcf3ce44SJohn Forte 		rdccfg.options = RDC_OPT_SETBMP;
412*fcf3ce44SJohn Forte 		if (strncmp(rdcp->mode, "sync", NSC_MAXPATH) == 0) {
413*fcf3ce44SJohn Forte 			rdccfg.options |= RDC_OPT_SYNC;
414*fcf3ce44SJohn Forte 		} else if (strncmp(rdc->mode, "async", NSC_MAXPATH) == 0) {
415*fcf3ce44SJohn Forte 			rdccfg.options |= RDC_OPT_ASYNC;
416*fcf3ce44SJohn Forte 		} else {
417*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
418*fcf3ce44SJohn Forte 			    RDC_EINVAL);
419*fcf3ce44SJohn Forte 			return (NULL);
420*fcf3ce44SJohn Forte 		}
421*fcf3ce44SJohn Forte 
422*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 1);
423*fcf3ce44SJohn Forte 
424*fcf3ce44SJohn Forte 		if (can_enable(rdcp)) {
425*fcf3ce44SJohn Forte 			/* do the operation */
426*fcf3ce44SJohn Forte 			*rcp = rdc_config(&rdccfg);
427*fcf3ce44SJohn Forte 
428*fcf3ce44SJohn Forte 		} else { /* set up what rdc_config would've set up */
429*fcf3ce44SJohn Forte 
430*fcf3ce44SJohn Forte 			populate_rc(rcp, rdcp);
431*fcf3ce44SJohn Forte 
432*fcf3ce44SJohn Forte 		}
433*fcf3ce44SJohn Forte 		if ((rcp->rc == 0) && (!rdcp->persist)) {
434*fcf3ce44SJohn Forte 			/*
435*fcf3ce44SJohn Forte 			 * if we are not persisting, do this now,
436*fcf3ce44SJohn Forte 			 * otherwise we will do it when
437*fcf3ce44SJohn Forte 			 * we have a lock on the cfg in add_to_rdc_cfg
438*fcf3ce44SJohn Forte 			 */
439*fcf3ce44SJohn Forte 			sv_enable(NULL, rdcp);
440*fcf3ce44SJohn Forte 		}
441*fcf3ce44SJohn Forte 
442*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
443*fcf3ce44SJohn Forte 		if (!rdcp)
444*fcf3ce44SJohn Forte 			break;
445*fcf3ce44SJohn Forte 
446*fcf3ce44SJohn Forte 		rcp->next = new_rc();
447*fcf3ce44SJohn Forte 		rcp = rcp->next;
448*fcf3ce44SJohn Forte 		if (!rcp) {
449*fcf3ce44SJohn Forte 			/* dont free here, return what you have */
450*fcf3ce44SJohn Forte 			break;
451*fcf3ce44SJohn Forte 		}
452*fcf3ce44SJohn Forte 	}
453*fcf3ce44SJohn Forte 
454*fcf3ce44SJohn Forte 	/*
455*fcf3ce44SJohn Forte 	 * travel the rc chain and rdc chain checking results,
456*fcf3ce44SJohn Forte 	 * building a new chain, and updating dscfg
457*fcf3ce44SJohn Forte 	 */
458*fcf3ce44SJohn Forte 	rcp = rc;
459*fcf3ce44SJohn Forte 	rdcp = rdc;
460*fcf3ce44SJohn Forte 
461*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
462*fcf3ce44SJohn Forte 
463*fcf3ce44SJohn Forte 	if (add_to_rdc_cfg(cfg_rdcs) < 0) {
464*fcf3ce44SJohn Forte 		/* XXX should disable or something here */
465*fcf3ce44SJohn Forte 		return (rc);
466*fcf3ce44SJohn Forte 	}
467*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
468*fcf3ce44SJohn Forte 	return (rc);
469*fcf3ce44SJohn Forte 
470*fcf3ce44SJohn Forte }
471*fcf3ce44SJohn Forte 
472*fcf3ce44SJohn Forte rdc_rc_t *
473*fcf3ce44SJohn Forte rdc_enable_clrbmp(rdcconfig_t *rdc)
474*fcf3ce44SJohn Forte {
475*fcf3ce44SJohn Forte 	rdc_config_t 	rdccfg;
476*fcf3ce44SJohn Forte 	rdcconfig_t 	*rdcp = NULL;
477*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
478*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
479*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
480*fcf3ce44SJohn Forte 
481*fcf3ce44SJohn Forte 	rdcp = rdc;
482*fcf3ce44SJohn Forte 	rc = (rdc_rc_t *)calloc(1, sizeof (rdc_rc_t));
483*fcf3ce44SJohn Forte 	if (!rc) {
484*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
485*fcf3ce44SJohn Forte 		return (NULL);
486*fcf3ce44SJohn Forte 	}
487*fcf3ce44SJohn Forte 	rcp = rc;
488*fcf3ce44SJohn Forte 	while (rdcp) {
489*fcf3ce44SJohn Forte 		if (!rdcp->mode) {
490*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
491*fcf3ce44SJohn Forte 			    RDC_EINVAL);
492*fcf3ce44SJohn Forte 			return (NULL);
493*fcf3ce44SJohn Forte 		}
494*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
495*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
496*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_ENABLE;
497*fcf3ce44SJohn Forte 		rdccfg.options = RDC_OPT_CLRBMP;
498*fcf3ce44SJohn Forte 		if (strncmp(rdcp->mode, "sync", NSC_MAXPATH) == 0) {
499*fcf3ce44SJohn Forte 			rdccfg.options |= RDC_OPT_SYNC;
500*fcf3ce44SJohn Forte 		} else if (strncmp(rdc->mode, "async", NSC_MAXPATH) == 0) {
501*fcf3ce44SJohn Forte 			rdccfg.options |= RDC_OPT_ASYNC;
502*fcf3ce44SJohn Forte 		} else {
503*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
504*fcf3ce44SJohn Forte 			    RDC_EINVAL);
505*fcf3ce44SJohn Forte 			return (NULL);
506*fcf3ce44SJohn Forte 		}
507*fcf3ce44SJohn Forte 
508*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 1);
509*fcf3ce44SJohn Forte 
510*fcf3ce44SJohn Forte 		if (can_enable(rdcp)) {
511*fcf3ce44SJohn Forte 			/* do the operation */
512*fcf3ce44SJohn Forte 			*rcp = rdc_config(&rdccfg);
513*fcf3ce44SJohn Forte 
514*fcf3ce44SJohn Forte 		} else { /* set up what rdc_config would've set up */
515*fcf3ce44SJohn Forte 
516*fcf3ce44SJohn Forte 			populate_rc(rcp, rdcp);
517*fcf3ce44SJohn Forte 
518*fcf3ce44SJohn Forte 		}
519*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
520*fcf3ce44SJohn Forte 		if (!rdcp)
521*fcf3ce44SJohn Forte 			break;
522*fcf3ce44SJohn Forte 
523*fcf3ce44SJohn Forte 		rcp->next = (rdc_rc_t *)calloc(1, sizeof (rdc_rc_t));
524*fcf3ce44SJohn Forte 		rcp = rcp->next;
525*fcf3ce44SJohn Forte 		if (!rcp)
526*fcf3ce44SJohn Forte 			break;
527*fcf3ce44SJohn Forte 	}
528*fcf3ce44SJohn Forte 
529*fcf3ce44SJohn Forte 	/*
530*fcf3ce44SJohn Forte 	 * travel the rc chain and rdc chain checking results,
531*fcf3ce44SJohn Forte 	 * building a new chain, and updating dscfg
532*fcf3ce44SJohn Forte 	 */
533*fcf3ce44SJohn Forte 	rcp = rc;
534*fcf3ce44SJohn Forte 	rdcp = rdc;
535*fcf3ce44SJohn Forte 
536*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
537*fcf3ce44SJohn Forte 
538*fcf3ce44SJohn Forte 	if (add_to_rdc_cfg(cfg_rdcs) < 0) {
539*fcf3ce44SJohn Forte 		/* XXX should disable or something here */
540*fcf3ce44SJohn Forte 		return (rc);
541*fcf3ce44SJohn Forte 	}
542*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
543*fcf3ce44SJohn Forte 
544*fcf3ce44SJohn Forte 	return (rc);
545*fcf3ce44SJohn Forte 
546*fcf3ce44SJohn Forte }
547*fcf3ce44SJohn Forte 
548*fcf3ce44SJohn Forte rdc_rc_t *
549*fcf3ce44SJohn Forte rdc_disable(rdcconfig_t *rdc)
550*fcf3ce44SJohn Forte {
551*fcf3ce44SJohn Forte 	rdc_config_t	rdccfg;
552*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
553*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
554*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
555*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
556*fcf3ce44SJohn Forte 
557*fcf3ce44SJohn Forte 	rdcp = rdc;
558*fcf3ce44SJohn Forte 	rc = new_rc();
559*fcf3ce44SJohn Forte 	if (!rc) {
560*fcf3ce44SJohn Forte 		return (NULL);
561*fcf3ce44SJohn Forte 	}
562*fcf3ce44SJohn Forte 	rcp = rc;
563*fcf3ce44SJohn Forte 
564*fcf3ce44SJohn Forte 	while (rdcp) {
565*fcf3ce44SJohn Forte 
566*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
567*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
568*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_DISABLE;
569*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
570*fcf3ce44SJohn Forte 
571*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
572*fcf3ce44SJohn Forte 
573*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
574*fcf3ce44SJohn Forte 		if (!rdcp)
575*fcf3ce44SJohn Forte 			break;
576*fcf3ce44SJohn Forte 
577*fcf3ce44SJohn Forte 		rcp->next = new_rc();
578*fcf3ce44SJohn Forte 		rcp = rcp->next;
579*fcf3ce44SJohn Forte 		if (!rcp)
580*fcf3ce44SJohn Forte 			return (rc);
581*fcf3ce44SJohn Forte 
582*fcf3ce44SJohn Forte 	}
583*fcf3ce44SJohn Forte 	rcp = rc;
584*fcf3ce44SJohn Forte 	rdcp = rdc;
585*fcf3ce44SJohn Forte 
586*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
587*fcf3ce44SJohn Forte 
588*fcf3ce44SJohn Forte 	remove_from_rdc_cfg(cfg_rdcs);
589*fcf3ce44SJohn Forte 
590*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
591*fcf3ce44SJohn Forte 
592*fcf3ce44SJohn Forte 	return (rc);
593*fcf3ce44SJohn Forte }
594*fcf3ce44SJohn Forte 
595*fcf3ce44SJohn Forte rdc_rc_t *
596*fcf3ce44SJohn Forte rdc_log(rdcconfig_t *rdc)
597*fcf3ce44SJohn Forte {
598*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
599*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
600*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
601*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
602*fcf3ce44SJohn Forte 
603*fcf3ce44SJohn Forte 	rdcp = rdc;
604*fcf3ce44SJohn Forte 	rc = new_rc();
605*fcf3ce44SJohn Forte 	if (!rc) {
606*fcf3ce44SJohn Forte 		return (NULL);
607*fcf3ce44SJohn Forte 	}
608*fcf3ce44SJohn Forte 	rcp = rc;
609*fcf3ce44SJohn Forte 
610*fcf3ce44SJohn Forte 	while (rdcp) {
611*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
612*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
613*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_LOG;
614*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
615*fcf3ce44SJohn Forte 
616*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
617*fcf3ce44SJohn Forte 
618*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
619*fcf3ce44SJohn Forte 		if (!rdcp)
620*fcf3ce44SJohn Forte 			break;
621*fcf3ce44SJohn Forte 
622*fcf3ce44SJohn Forte 		rcp->next = new_rc();
623*fcf3ce44SJohn Forte 		rcp = rcp->next;
624*fcf3ce44SJohn Forte 		if (!rcp)
625*fcf3ce44SJohn Forte 			break;
626*fcf3ce44SJohn Forte 	}
627*fcf3ce44SJohn Forte 	return (rc);
628*fcf3ce44SJohn Forte }
629*fcf3ce44SJohn Forte 
630*fcf3ce44SJohn Forte rdc_rc_t *
631*fcf3ce44SJohn Forte rdc_usync(rdcconfig_t *rdc)
632*fcf3ce44SJohn Forte {
633*fcf3ce44SJohn Forte 	rdc_config_t *rdccfg;
634*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
635*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
636*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
637*fcf3ce44SJohn Forte 	rdc_rc_t	*tmprc;
638*fcf3ce44SJohn Forte 	int trc;
639*fcf3ce44SJohn Forte 
640*fcf3ce44SJohn Forte 	rdcp = rdc;
641*fcf3ce44SJohn Forte 
642*fcf3ce44SJohn Forte 	while (rdcp) {
643*fcf3ce44SJohn Forte 		/* freed in rdc_mtconfig */
644*fcf3ce44SJohn Forte 		rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
645*fcf3ce44SJohn Forte 		rdccfg->rdc_set[0] = config2set(rdcp);
646*fcf3ce44SJohn Forte 		rdccfg->command = RDC_CMD_COPY;
647*fcf3ce44SJohn Forte 		rdccfg->options = RDC_OPT_UPDATE|RDC_OPT_FORWARD;
648*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg->rdc_set[0], 0);
649*fcf3ce44SJohn Forte 		trc = thr_create(NULL, 0, rdc_mtconfig,
650*fcf3ce44SJohn Forte 		    (void **) rdccfg, THR_BOUND, NULL);
651*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
652*fcf3ce44SJohn Forte 		if (!rdcp)
653*fcf3ce44SJohn Forte 			break;
654*fcf3ce44SJohn Forte 
655*fcf3ce44SJohn Forte 	}
656*fcf3ce44SJohn Forte 
657*fcf3ce44SJohn Forte 	/*
658*fcf3ce44SJohn Forte 	 * collect status here from thr_join-status,
659*fcf3ce44SJohn Forte 	 * and add to rdc_rc_t chain ?
660*fcf3ce44SJohn Forte 	 * this will block, but caller could always thread too
661*fcf3ce44SJohn Forte 	 */
662*fcf3ce44SJohn Forte 	while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
663*fcf3ce44SJohn Forte 		if (rc == NULL) {
664*fcf3ce44SJohn Forte 			rcp = rc = (rdc_rc_t *)tmprc;
665*fcf3ce44SJohn Forte 		} else {
666*fcf3ce44SJohn Forte 			rcp->next = (rdc_rc_t *)tmprc;
667*fcf3ce44SJohn Forte 			rcp = rcp->next;
668*fcf3ce44SJohn Forte 		}
669*fcf3ce44SJohn Forte 	}
670*fcf3ce44SJohn Forte 
671*fcf3ce44SJohn Forte 	return (rc);
672*fcf3ce44SJohn Forte }
673*fcf3ce44SJohn Forte 
674*fcf3ce44SJohn Forte rdc_rc_t *
675*fcf3ce44SJohn Forte rdc_fsync(rdcconfig_t *rdc)
676*fcf3ce44SJohn Forte {
677*fcf3ce44SJohn Forte 	rdc_config_t *rdccfg;
678*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
679*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
680*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
681*fcf3ce44SJohn Forte 	rdc_rc_t	*tmprc = NULL;
682*fcf3ce44SJohn Forte 	int trc;
683*fcf3ce44SJohn Forte 
684*fcf3ce44SJohn Forte 	rdcp = rdc;
685*fcf3ce44SJohn Forte 	rc = new_rc();
686*fcf3ce44SJohn Forte 	if (!rc) {
687*fcf3ce44SJohn Forte 		return (NULL);
688*fcf3ce44SJohn Forte 	}
689*fcf3ce44SJohn Forte 	rcp = rc;
690*fcf3ce44SJohn Forte 
691*fcf3ce44SJohn Forte 	while (rdcp) {
692*fcf3ce44SJohn Forte 		/* freed in rdc_mtconfig */
693*fcf3ce44SJohn Forte 		rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
694*fcf3ce44SJohn Forte 		rdccfg->rdc_set[0] = config2set(rdcp);
695*fcf3ce44SJohn Forte 		rdccfg->command = RDC_CMD_COPY;
696*fcf3ce44SJohn Forte 		rdccfg->options = RDC_OPT_FULL|RDC_OPT_FORWARD;
697*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg->rdc_set[0], 0);
698*fcf3ce44SJohn Forte 		trc = thr_create(NULL, 0, rdc_mtconfig,
699*fcf3ce44SJohn Forte 		    (void **) rdccfg, THR_BOUND, NULL);
700*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
701*fcf3ce44SJohn Forte 		if (!rdcp)
702*fcf3ce44SJohn Forte 			break;
703*fcf3ce44SJohn Forte 
704*fcf3ce44SJohn Forte 	}
705*fcf3ce44SJohn Forte 
706*fcf3ce44SJohn Forte 	/*
707*fcf3ce44SJohn Forte 	 * collect status here from thr_join-status,
708*fcf3ce44SJohn Forte 	 * and add to rdc_rc_t chain ?
709*fcf3ce44SJohn Forte 	 * this will block, but caller could always thread too
710*fcf3ce44SJohn Forte 	 */
711*fcf3ce44SJohn Forte 	while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
712*fcf3ce44SJohn Forte 		if (rc == NULL) {
713*fcf3ce44SJohn Forte 			rcp = rc = (rdc_rc_t *)tmprc;
714*fcf3ce44SJohn Forte 		} else {
715*fcf3ce44SJohn Forte 			rcp->next = (rdc_rc_t *)tmprc;
716*fcf3ce44SJohn Forte 			rcp = rcp->next;
717*fcf3ce44SJohn Forte 		}
718*fcf3ce44SJohn Forte 	}
719*fcf3ce44SJohn Forte 
720*fcf3ce44SJohn Forte 	return (rc);
721*fcf3ce44SJohn Forte }
722*fcf3ce44SJohn Forte 
723*fcf3ce44SJohn Forte rdc_rc_t *
724*fcf3ce44SJohn Forte rdc_rsync(rdcconfig_t *rdc)
725*fcf3ce44SJohn Forte {
726*fcf3ce44SJohn Forte 	rdc_config_t *rdccfg;
727*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
728*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
729*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
730*fcf3ce44SJohn Forte 	rdc_rc_t	*tmprc = NULL;
731*fcf3ce44SJohn Forte 	int trc;
732*fcf3ce44SJohn Forte 
733*fcf3ce44SJohn Forte 	rdcp = rdc;
734*fcf3ce44SJohn Forte 	rc = new_rc();
735*fcf3ce44SJohn Forte 	if (!rc) {
736*fcf3ce44SJohn Forte 		return (NULL);
737*fcf3ce44SJohn Forte 	}
738*fcf3ce44SJohn Forte 	rcp = rc;
739*fcf3ce44SJohn Forte 
740*fcf3ce44SJohn Forte 	while (rdcp) {
741*fcf3ce44SJohn Forte 		tmprc = cant_rsync(rdcp);
742*fcf3ce44SJohn Forte 		if (tmprc != NULL) {
743*fcf3ce44SJohn Forte 			if (rc == NULL) {
744*fcf3ce44SJohn Forte 				rcp = rc = tmprc;
745*fcf3ce44SJohn Forte 			} else {
746*fcf3ce44SJohn Forte 				rcp->next = tmprc;
747*fcf3ce44SJohn Forte 				rcp = rcp->next;
748*fcf3ce44SJohn Forte 			}
749*fcf3ce44SJohn Forte 			goto next;
750*fcf3ce44SJohn Forte 		}
751*fcf3ce44SJohn Forte 
752*fcf3ce44SJohn Forte 		/* freed in rdc_mtconfig */
753*fcf3ce44SJohn Forte 		rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
754*fcf3ce44SJohn Forte 		rdccfg->rdc_set[0] = config2set(rdcp);
755*fcf3ce44SJohn Forte 		rdccfg->command = RDC_CMD_COPY;
756*fcf3ce44SJohn Forte 		rdccfg->options = RDC_OPT_REVERSE|RDC_OPT_FULL;
757*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg->rdc_set[0], 0);
758*fcf3ce44SJohn Forte 		trc = thr_create(NULL, 0, rdc_mtconfig,
759*fcf3ce44SJohn Forte 		    (void **) rdccfg, THR_BOUND, NULL);
760*fcf3ce44SJohn Forte next:
761*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
762*fcf3ce44SJohn Forte 		if (!rdcp)
763*fcf3ce44SJohn Forte 			break;
764*fcf3ce44SJohn Forte 	}
765*fcf3ce44SJohn Forte 
766*fcf3ce44SJohn Forte 	/*
767*fcf3ce44SJohn Forte 	 * collect status here from thr_join-status,
768*fcf3ce44SJohn Forte 	 * and add to rdc_rc_t chain ?
769*fcf3ce44SJohn Forte 	 * this will block, but caller could always thread too
770*fcf3ce44SJohn Forte 	 */
771*fcf3ce44SJohn Forte 	while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
772*fcf3ce44SJohn Forte 		if (rc == NULL) {
773*fcf3ce44SJohn Forte 			rcp = rc = (rdc_rc_t *)tmprc;
774*fcf3ce44SJohn Forte 		} else {
775*fcf3ce44SJohn Forte 			rcp->next = (rdc_rc_t *)tmprc;
776*fcf3ce44SJohn Forte 			rcp = rcp->next;
777*fcf3ce44SJohn Forte 		}
778*fcf3ce44SJohn Forte 	}
779*fcf3ce44SJohn Forte 
780*fcf3ce44SJohn Forte 	return (rc);
781*fcf3ce44SJohn Forte }
782*fcf3ce44SJohn Forte 
783*fcf3ce44SJohn Forte rdc_rc_t *
784*fcf3ce44SJohn Forte rdc_ursync(rdcconfig_t *rdc)
785*fcf3ce44SJohn Forte {
786*fcf3ce44SJohn Forte 	rdc_config_t *rdccfg;
787*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
788*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
789*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
790*fcf3ce44SJohn Forte 	rdc_rc_t	*tmprc = NULL;
791*fcf3ce44SJohn Forte 	int trc;
792*fcf3ce44SJohn Forte 
793*fcf3ce44SJohn Forte 	rdcp = rdc;
794*fcf3ce44SJohn Forte 
795*fcf3ce44SJohn Forte 	while (rdcp) {
796*fcf3ce44SJohn Forte 		tmprc = cant_rsync(rdcp);
797*fcf3ce44SJohn Forte 		if (tmprc != NULL) {
798*fcf3ce44SJohn Forte 			if (rc == NULL) {
799*fcf3ce44SJohn Forte 				rcp = rc = tmprc;
800*fcf3ce44SJohn Forte 			} else {
801*fcf3ce44SJohn Forte 				rcp->next = tmprc;
802*fcf3ce44SJohn Forte 				rcp = rcp->next;
803*fcf3ce44SJohn Forte 			}
804*fcf3ce44SJohn Forte 			goto next;
805*fcf3ce44SJohn Forte 		}
806*fcf3ce44SJohn Forte 
807*fcf3ce44SJohn Forte 		/* freed in rdc_mtconfig */
808*fcf3ce44SJohn Forte 		rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
809*fcf3ce44SJohn Forte 		rdccfg->rdc_set[0] = config2set(rdcp);
810*fcf3ce44SJohn Forte 		rdccfg->command = RDC_CMD_COPY;
811*fcf3ce44SJohn Forte 		rdccfg->options = RDC_OPT_REVERSE | RDC_OPT_UPDATE;
812*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg->rdc_set[0], 0);
813*fcf3ce44SJohn Forte 		trc = thr_create(NULL, 0, rdc_mtconfig,
814*fcf3ce44SJohn Forte 		    (void **) rdccfg, THR_BOUND, NULL);
815*fcf3ce44SJohn Forte next:
816*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
817*fcf3ce44SJohn Forte 		if (!rdcp)
818*fcf3ce44SJohn Forte 			break;
819*fcf3ce44SJohn Forte 
820*fcf3ce44SJohn Forte 	}
821*fcf3ce44SJohn Forte 
822*fcf3ce44SJohn Forte 	/*
823*fcf3ce44SJohn Forte 	 * collect status here from thr_join-status,
824*fcf3ce44SJohn Forte 	 * and add to rdc_rc_t chain ?
825*fcf3ce44SJohn Forte 	 * this will block, but caller could always thread too
826*fcf3ce44SJohn Forte 	 */
827*fcf3ce44SJohn Forte 	while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
828*fcf3ce44SJohn Forte 		if (rc == NULL) {
829*fcf3ce44SJohn Forte 			rcp = rc = (rdc_rc_t *)tmprc;
830*fcf3ce44SJohn Forte 		} else {
831*fcf3ce44SJohn Forte 			rcp->next = (rdc_rc_t *)tmprc;
832*fcf3ce44SJohn Forte 			rcp = rcp->next;
833*fcf3ce44SJohn Forte 		}
834*fcf3ce44SJohn Forte 	}
835*fcf3ce44SJohn Forte 
836*fcf3ce44SJohn Forte 	return (rc);
837*fcf3ce44SJohn Forte }
838*fcf3ce44SJohn Forte 
839*fcf3ce44SJohn Forte rdc_rc_t *
840*fcf3ce44SJohn Forte rdc_wait(rdcconfig_t *rdc)
841*fcf3ce44SJohn Forte {
842*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
843*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
844*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
845*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
846*fcf3ce44SJohn Forte 
847*fcf3ce44SJohn Forte 	rdcp = rdc;
848*fcf3ce44SJohn Forte 	rc = new_rc();
849*fcf3ce44SJohn Forte 	if (!rc) {
850*fcf3ce44SJohn Forte 		return (NULL);
851*fcf3ce44SJohn Forte 	}
852*fcf3ce44SJohn Forte 	rcp = rc;
853*fcf3ce44SJohn Forte 
854*fcf3ce44SJohn Forte 	while (rdcp) {
855*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
856*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
857*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_WAIT;
858*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
859*fcf3ce44SJohn Forte 
860*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
861*fcf3ce44SJohn Forte 
862*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
863*fcf3ce44SJohn Forte 		if (!rdcp)
864*fcf3ce44SJohn Forte 			break;
865*fcf3ce44SJohn Forte 
866*fcf3ce44SJohn Forte 		rcp->next = new_rc();
867*fcf3ce44SJohn Forte 		rcp = rcp->next;
868*fcf3ce44SJohn Forte 		if (!rcp)
869*fcf3ce44SJohn Forte 			break;
870*fcf3ce44SJohn Forte 	}
871*fcf3ce44SJohn Forte 	return (rc);
872*fcf3ce44SJohn Forte }
873*fcf3ce44SJohn Forte 
874*fcf3ce44SJohn Forte rdc_rc_t *
875*fcf3ce44SJohn Forte rdc_set_autosync(rdcconfig_t *rdc, int autosync)
876*fcf3ce44SJohn Forte {
877*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
878*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
879*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
880*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
881*fcf3ce44SJohn Forte 
882*fcf3ce44SJohn Forte 	rdcp = rdc;
883*fcf3ce44SJohn Forte 	rc = new_rc();
884*fcf3ce44SJohn Forte 	if (!rc) {
885*fcf3ce44SJohn Forte 		return (NULL);
886*fcf3ce44SJohn Forte 	}
887*fcf3ce44SJohn Forte 	rcp = rc;
888*fcf3ce44SJohn Forte 
889*fcf3ce44SJohn Forte 	while (rdcp) {
890*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
891*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
892*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_TUNABLE;
893*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].autosync = autosync;
894*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].maxqitems = -1;
895*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].maxqfbas = -1;
896*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
897*fcf3ce44SJohn Forte 
898*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
899*fcf3ce44SJohn Forte 
900*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
901*fcf3ce44SJohn Forte 		if (!rdcp)
902*fcf3ce44SJohn Forte 			break;
903*fcf3ce44SJohn Forte 
904*fcf3ce44SJohn Forte 		rcp->next = new_rc();
905*fcf3ce44SJohn Forte 		rcp = rcp->next;
906*fcf3ce44SJohn Forte 		if (!rcp)
907*fcf3ce44SJohn Forte 			break;
908*fcf3ce44SJohn Forte 	}
909*fcf3ce44SJohn Forte 	return (rc);
910*fcf3ce44SJohn Forte }
911*fcf3ce44SJohn Forte 
912*fcf3ce44SJohn Forte rdc_rc_t *
913*fcf3ce44SJohn Forte rdc_set_maxqfbas(rdcconfig_t *rdc, int maxqfbas)
914*fcf3ce44SJohn Forte {
915*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
916*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
917*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
918*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
919*fcf3ce44SJohn Forte 
920*fcf3ce44SJohn Forte 	rdcp = rdc;
921*fcf3ce44SJohn Forte 	rc = new_rc();
922*fcf3ce44SJohn Forte 	if (!rc) {
923*fcf3ce44SJohn Forte 		return (NULL);
924*fcf3ce44SJohn Forte 	}
925*fcf3ce44SJohn Forte 	rcp = rc;
926*fcf3ce44SJohn Forte 
927*fcf3ce44SJohn Forte 	while (rdcp) {
928*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
929*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
930*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_TUNABLE;
931*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].autosync = -1;
932*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].maxqitems = -1;
933*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].maxqfbas = maxqfbas;
934*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
935*fcf3ce44SJohn Forte 
936*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
937*fcf3ce44SJohn Forte 
938*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
939*fcf3ce44SJohn Forte 		if (!rdcp)
940*fcf3ce44SJohn Forte 			break;
941*fcf3ce44SJohn Forte 
942*fcf3ce44SJohn Forte 		rcp->next = new_rc();
943*fcf3ce44SJohn Forte 		rcp = rcp->next;
944*fcf3ce44SJohn Forte 		if (!rcp)
945*fcf3ce44SJohn Forte 			break;
946*fcf3ce44SJohn Forte 	}
947*fcf3ce44SJohn Forte 	return (rc);
948*fcf3ce44SJohn Forte }
949*fcf3ce44SJohn Forte 
950*fcf3ce44SJohn Forte rdc_rc_t *
951*fcf3ce44SJohn Forte rdc_set_maxqitems(rdcconfig_t *rdc, int maxqitems)
952*fcf3ce44SJohn Forte {
953*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
954*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
955*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
956*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
957*fcf3ce44SJohn Forte 
958*fcf3ce44SJohn Forte 	rdcp = rdc;
959*fcf3ce44SJohn Forte 	rc = new_rc();
960*fcf3ce44SJohn Forte 
961*fcf3ce44SJohn Forte 	if (!rc) {
962*fcf3ce44SJohn Forte 		return (NULL);
963*fcf3ce44SJohn Forte 	}
964*fcf3ce44SJohn Forte 	rcp = rc;
965*fcf3ce44SJohn Forte 
966*fcf3ce44SJohn Forte 	while (rdcp) {
967*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
968*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdc);
969*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_TUNABLE;
970*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].autosync = -1;
971*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].maxqitems = maxqitems;
972*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0].maxqfbas = -1;
973*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
974*fcf3ce44SJohn Forte 
975*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
976*fcf3ce44SJohn Forte 
977*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
978*fcf3ce44SJohn Forte 		if (!rdcp)
979*fcf3ce44SJohn Forte 			break;
980*fcf3ce44SJohn Forte 
981*fcf3ce44SJohn Forte 		rcp->next = new_rc();
982*fcf3ce44SJohn Forte 		rcp = rcp->next;
983*fcf3ce44SJohn Forte 		if (!rcp)
984*fcf3ce44SJohn Forte 			break;
985*fcf3ce44SJohn Forte 	}
986*fcf3ce44SJohn Forte 	return (rc);
987*fcf3ce44SJohn Forte }
988*fcf3ce44SJohn Forte 
989*fcf3ce44SJohn Forte rdc_set_t
990*fcf3ce44SJohn Forte rdc_status(rdcconfig_t *rdc)
991*fcf3ce44SJohn Forte {
992*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
993*fcf3ce44SJohn Forte 
994*fcf3ce44SJohn Forte 	bzero(&rdccfg, sizeof (rdc_config_t));
995*fcf3ce44SJohn Forte 	rdccfg.rdc_set[0] = config2set(rdc);
996*fcf3ce44SJohn Forte 	rdccfg.command = RDC_CMD_STATUS;
997*fcf3ce44SJohn Forte 	populate_addrs(&rdccfg.rdc_set[0], 0);
998*fcf3ce44SJohn Forte 	rdc_config(&rdccfg);
999*fcf3ce44SJohn Forte 
1000*fcf3ce44SJohn Forte 	return (rdccfg.rdc_set[0]);
1001*fcf3ce44SJohn Forte }
1002*fcf3ce44SJohn Forte 
1003*fcf3ce44SJohn Forte int
1004*fcf3ce44SJohn Forte rdc_get_autosync(rdcconfig_t *rdc)
1005*fcf3ce44SJohn Forte {
1006*fcf3ce44SJohn Forte 	rdc_set_t rdcset;
1007*fcf3ce44SJohn Forte 
1008*fcf3ce44SJohn Forte 	rdcset = rdc_status(rdc);
1009*fcf3ce44SJohn Forte 	return (rdcset.autosync);
1010*fcf3ce44SJohn Forte }
1011*fcf3ce44SJohn Forte 
1012*fcf3ce44SJohn Forte int
1013*fcf3ce44SJohn Forte rdc_get_maxqfbas(rdcconfig_t *rdc)
1014*fcf3ce44SJohn Forte {
1015*fcf3ce44SJohn Forte 	rdc_set_t rdcset;
1016*fcf3ce44SJohn Forte 
1017*fcf3ce44SJohn Forte 	rdcset = rdc_status(rdc);
1018*fcf3ce44SJohn Forte 	return (rdcset.maxqfbas);
1019*fcf3ce44SJohn Forte 
1020*fcf3ce44SJohn Forte }
1021*fcf3ce44SJohn Forte 
1022*fcf3ce44SJohn Forte int
1023*fcf3ce44SJohn Forte rdc_get_maxqitems(rdcconfig_t *rdc)
1024*fcf3ce44SJohn Forte {
1025*fcf3ce44SJohn Forte 	rdc_set_t rdcset;
1026*fcf3ce44SJohn Forte 
1027*fcf3ce44SJohn Forte 	rdcset = rdc_status(rdc);
1028*fcf3ce44SJohn Forte 	return (rdcset.maxqitems);
1029*fcf3ce44SJohn Forte 
1030*fcf3ce44SJohn Forte }
1031*fcf3ce44SJohn Forte 
1032*fcf3ce44SJohn Forte int
1033*fcf3ce44SJohn Forte set_mode(rdcconfig_t *rdc)
1034*fcf3ce44SJohn Forte {
1035*fcf3ce44SJohn Forte 	if (strcmp(rdc->mode, "async") == 0)
1036*fcf3ce44SJohn Forte 		return (RDC_OPT_ASYNC);
1037*fcf3ce44SJohn Forte 	else
1038*fcf3ce44SJohn Forte 		return (RDC_OPT_SYNC);
1039*fcf3ce44SJohn Forte }
1040*fcf3ce44SJohn Forte 
1041*fcf3ce44SJohn Forte /*
1042*fcf3ce44SJohn Forte  * reconfig bitmaps are single set only ops
1043*fcf3ce44SJohn Forte  * for obvious reasons
1044*fcf3ce44SJohn Forte  */
1045*fcf3ce44SJohn Forte rdc_rc_t *
1046*fcf3ce44SJohn Forte rdc_reconfig_pbmp(rdcconfig_t *rdc, char *pbmp)
1047*fcf3ce44SJohn Forte {
1048*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1049*fcf3ce44SJohn Forte 	rdc_rc_t *rc;
1050*fcf3ce44SJohn Forte 
1051*fcf3ce44SJohn Forte 	rc = new_rc();
1052*fcf3ce44SJohn Forte 	if ((!rc) || (!pbmp))
1053*fcf3ce44SJohn Forte 		return (NULL);
1054*fcf3ce44SJohn Forte 
1055*fcf3ce44SJohn Forte 	bzero(&rdccfg, sizeof (rdc_config_t));
1056*fcf3ce44SJohn Forte 	rdccfg.rdc_set[0] = config2set(rdc);
1057*fcf3ce44SJohn Forte 	strncpy(rdccfg.rdc_set[0].primary.bitmap, pbmp, NSC_MAXPATH);
1058*fcf3ce44SJohn Forte 	rdccfg.command = RDC_CMD_RECONFIG;
1059*fcf3ce44SJohn Forte 	rdccfg.options |= set_mode(rdc);
1060*fcf3ce44SJohn Forte 	populate_addrs(&rdccfg.rdc_set[0], 0);
1061*fcf3ce44SJohn Forte 
1062*fcf3ce44SJohn Forte 	if (can_reconfig_pbmp(rdc, pbmp))
1063*fcf3ce44SJohn Forte 		*rc = rdc_config(&rdccfg);
1064*fcf3ce44SJohn Forte 	else
1065*fcf3ce44SJohn Forte 		populate_rc(rc, rdc);
1066*fcf3ce44SJohn Forte 
1067*fcf3ce44SJohn Forte 	if ((rc->rc == 0) && (rdc->persist))
1068*fcf3ce44SJohn Forte 		if (replace_cfgfield(rdc, "pbitmap", pbmp) < 0) {
1069*fcf3ce44SJohn Forte 			rc->rc = -1;
1070*fcf3ce44SJohn Forte 			strncpy(rc->msg, rdc_error(NULL), RDC_ERR_SIZE);
1071*fcf3ce44SJohn Forte 		}
1072*fcf3ce44SJohn Forte 	return (rc);
1073*fcf3ce44SJohn Forte }
1074*fcf3ce44SJohn Forte 
1075*fcf3ce44SJohn Forte rdc_rc_t *
1076*fcf3ce44SJohn Forte rdc_reconfig_sbmp(rdcconfig_t *rdc, char *sbmp)
1077*fcf3ce44SJohn Forte {
1078*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1079*fcf3ce44SJohn Forte 	rdc_rc_t *rc;
1080*fcf3ce44SJohn Forte 
1081*fcf3ce44SJohn Forte 	rc = new_rc();
1082*fcf3ce44SJohn Forte 	if (!rc)
1083*fcf3ce44SJohn Forte 		return (NULL);
1084*fcf3ce44SJohn Forte 
1085*fcf3ce44SJohn Forte 	bzero(&rdccfg, sizeof (rdc_config_t));
1086*fcf3ce44SJohn Forte 	rdccfg.rdc_set[0] = config2set(rdc);
1087*fcf3ce44SJohn Forte 	strncpy(rdccfg.rdc_set[0].secondary.bitmap, sbmp, NSC_MAXPATH);
1088*fcf3ce44SJohn Forte 	rdccfg.command = RDC_CMD_RECONFIG;
1089*fcf3ce44SJohn Forte 	rdccfg.options |= set_mode(rdc);
1090*fcf3ce44SJohn Forte 	populate_addrs(&rdccfg.rdc_set[0], 0);
1091*fcf3ce44SJohn Forte 
1092*fcf3ce44SJohn Forte 	if (can_reconfig_sbmp(rdc, sbmp))
1093*fcf3ce44SJohn Forte 		*rc = rdc_config(&rdccfg);
1094*fcf3ce44SJohn Forte 	else
1095*fcf3ce44SJohn Forte 		populate_rc(rc, rdc);
1096*fcf3ce44SJohn Forte 
1097*fcf3ce44SJohn Forte 	if ((rc->rc == 0) && (rdc->persist))
1098*fcf3ce44SJohn Forte 		replace_cfgfield(rdc, "sbitmap", sbmp);
1099*fcf3ce44SJohn Forte 
1100*fcf3ce44SJohn Forte 	return (rc);
1101*fcf3ce44SJohn Forte }
1102*fcf3ce44SJohn Forte 
1103*fcf3ce44SJohn Forte rdc_rc_t *
1104*fcf3ce44SJohn Forte rdc_reconfig_group(rdcconfig_t *rdc, char *group)
1105*fcf3ce44SJohn Forte {
1106*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1107*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
1108*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
1109*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
1110*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
1111*fcf3ce44SJohn Forte 
1112*fcf3ce44SJohn Forte 	rdcp = rdc;
1113*fcf3ce44SJohn Forte 	rc = new_rc();
1114*fcf3ce44SJohn Forte 	if (!rc) {
1115*fcf3ce44SJohn Forte 		return (NULL);
1116*fcf3ce44SJohn Forte 	}
1117*fcf3ce44SJohn Forte 	rcp = rc;
1118*fcf3ce44SJohn Forte 
1119*fcf3ce44SJohn Forte 	while (rdcp) {
1120*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
1121*fcf3ce44SJohn Forte 		/* just in case */
1122*fcf3ce44SJohn Forte 		strncpy(rdcp->group, group, NSC_MAXPATH);
1123*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
1124*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_RECONFIG;
1125*fcf3ce44SJohn Forte 		rdccfg.options |= set_mode(rdcp);
1126*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
1127*fcf3ce44SJohn Forte 
1128*fcf3ce44SJohn Forte 		/* reconfig group rules enforced in kernel */
1129*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
1130*fcf3ce44SJohn Forte 
1131*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
1132*fcf3ce44SJohn Forte 		if (!rdcp)
1133*fcf3ce44SJohn Forte 			break;
1134*fcf3ce44SJohn Forte 
1135*fcf3ce44SJohn Forte 		rcp->next = new_rc();
1136*fcf3ce44SJohn Forte 		rcp = rcp->next;
1137*fcf3ce44SJohn Forte 		if (!rcp)
1138*fcf3ce44SJohn Forte 			break;
1139*fcf3ce44SJohn Forte 	}
1140*fcf3ce44SJohn Forte 	rcp = rc;
1141*fcf3ce44SJohn Forte 	rdcp = rdc;
1142*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
1143*fcf3ce44SJohn Forte 	replace_cfgfield(cfg_rdcs, "group", group);
1144*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
1145*fcf3ce44SJohn Forte 
1146*fcf3ce44SJohn Forte 	return (rc);
1147*fcf3ce44SJohn Forte }
1148*fcf3ce44SJohn Forte /*ARGSUSED*/
1149*fcf3ce44SJohn Forte rdc_rc_t *
1150*fcf3ce44SJohn Forte rdc_reconfig_ctag(rdcconfig_t *rdc, char *ctag)
1151*fcf3ce44SJohn Forte {
1152*fcf3ce44SJohn Forte 	return (NULL);
1153*fcf3ce44SJohn Forte }
1154*fcf3ce44SJohn Forte 
1155*fcf3ce44SJohn Forte rdc_rc_t *
1156*fcf3ce44SJohn Forte rdc_set_sync(rdcconfig_t *rdc)
1157*fcf3ce44SJohn Forte {
1158*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1159*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
1160*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
1161*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
1162*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
1163*fcf3ce44SJohn Forte 
1164*fcf3ce44SJohn Forte 	rdcp = rdc;
1165*fcf3ce44SJohn Forte 	rc = new_rc();
1166*fcf3ce44SJohn Forte 	if (!rc) {
1167*fcf3ce44SJohn Forte 		return (NULL);
1168*fcf3ce44SJohn Forte 	}
1169*fcf3ce44SJohn Forte 	rcp = rc;
1170*fcf3ce44SJohn Forte 
1171*fcf3ce44SJohn Forte 	while (rdcp) {
1172*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
1173*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdc);
1174*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_RECONFIG;
1175*fcf3ce44SJohn Forte 		rdccfg.options |= RDC_OPT_SYNC;
1176*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
1177*fcf3ce44SJohn Forte 
1178*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
1179*fcf3ce44SJohn Forte 
1180*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
1181*fcf3ce44SJohn Forte 		if (!rdcp)
1182*fcf3ce44SJohn Forte 			break;
1183*fcf3ce44SJohn Forte 
1184*fcf3ce44SJohn Forte 		rcp->next = new_rc();
1185*fcf3ce44SJohn Forte 		rcp = rcp->next;
1186*fcf3ce44SJohn Forte 		if (!rcp)
1187*fcf3ce44SJohn Forte 			break;
1188*fcf3ce44SJohn Forte 	}
1189*fcf3ce44SJohn Forte 
1190*fcf3ce44SJohn Forte 	rcp = rc;
1191*fcf3ce44SJohn Forte 	rdcp = rdc;
1192*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
1193*fcf3ce44SJohn Forte 	replace_cfgfield(cfg_rdcs, "mode", "sync");
1194*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
1195*fcf3ce44SJohn Forte 
1196*fcf3ce44SJohn Forte 	return (rc);
1197*fcf3ce44SJohn Forte }
1198*fcf3ce44SJohn Forte 
1199*fcf3ce44SJohn Forte rdc_rc_t *
1200*fcf3ce44SJohn Forte rdc_set_async(rdcconfig_t *rdc)
1201*fcf3ce44SJohn Forte {
1202*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1203*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
1204*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
1205*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
1206*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
1207*fcf3ce44SJohn Forte 
1208*fcf3ce44SJohn Forte 	rdcp = rdc;
1209*fcf3ce44SJohn Forte 	rc = new_rc();
1210*fcf3ce44SJohn Forte 	if (!rc) {
1211*fcf3ce44SJohn Forte 		return (NULL);
1212*fcf3ce44SJohn Forte 	}
1213*fcf3ce44SJohn Forte 	rcp = rc;
1214*fcf3ce44SJohn Forte 
1215*fcf3ce44SJohn Forte 	while (rdcp) {
1216*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
1217*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
1218*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_RECONFIG;
1219*fcf3ce44SJohn Forte 		rdccfg.options |= RDC_OPT_ASYNC;
1220*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
1221*fcf3ce44SJohn Forte 
1222*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
1223*fcf3ce44SJohn Forte 
1224*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
1225*fcf3ce44SJohn Forte 		if (!rdcp)
1226*fcf3ce44SJohn Forte 			break;
1227*fcf3ce44SJohn Forte 
1228*fcf3ce44SJohn Forte 		rcp->next = new_rc();
1229*fcf3ce44SJohn Forte 		rcp = rcp->next;
1230*fcf3ce44SJohn Forte 		if (!rcp)
1231*fcf3ce44SJohn Forte 			break;
1232*fcf3ce44SJohn Forte 	}
1233*fcf3ce44SJohn Forte 	rcp = rc;
1234*fcf3ce44SJohn Forte 	rdcp = rdc;
1235*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
1236*fcf3ce44SJohn Forte 	replace_cfgfield(cfg_rdcs, "mode", "async");
1237*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
1238*fcf3ce44SJohn Forte 
1239*fcf3ce44SJohn Forte 	return (rc);
1240*fcf3ce44SJohn Forte }
1241*fcf3ce44SJohn Forte 
1242*fcf3ce44SJohn Forte rdc_rc_t *
1243*fcf3ce44SJohn Forte rdc_health(rdcconfig_t *rdc)
1244*fcf3ce44SJohn Forte {
1245*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1246*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
1247*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
1248*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
1249*fcf3ce44SJohn Forte 
1250*fcf3ce44SJohn Forte 	rdcp = rdc;
1251*fcf3ce44SJohn Forte 	rc = new_rc();
1252*fcf3ce44SJohn Forte 	if (!rc) {
1253*fcf3ce44SJohn Forte 		return (NULL);
1254*fcf3ce44SJohn Forte 	}
1255*fcf3ce44SJohn Forte 	rcp = rc;
1256*fcf3ce44SJohn Forte 
1257*fcf3ce44SJohn Forte 	while (rdcp) {
1258*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
1259*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
1260*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_HEALTH;
1261*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
1262*fcf3ce44SJohn Forte 
1263*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
1264*fcf3ce44SJohn Forte 
1265*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
1266*fcf3ce44SJohn Forte 		if (!rdcp)
1267*fcf3ce44SJohn Forte 			break;
1268*fcf3ce44SJohn Forte 
1269*fcf3ce44SJohn Forte 		rcp->next = new_rc();
1270*fcf3ce44SJohn Forte 		rcp = rcp->next;
1271*fcf3ce44SJohn Forte 
1272*fcf3ce44SJohn Forte 		if (!rcp)
1273*fcf3ce44SJohn Forte 			break;
1274*fcf3ce44SJohn Forte 
1275*fcf3ce44SJohn Forte 	}
1276*fcf3ce44SJohn Forte 	return (rc);
1277*fcf3ce44SJohn Forte }
1278*fcf3ce44SJohn Forte 
1279*fcf3ce44SJohn Forte rdc_rc_t *
1280*fcf3ce44SJohn Forte rdc_reverse_role(rdcconfig_t *rdc)
1281*fcf3ce44SJohn Forte {
1282*fcf3ce44SJohn Forte 	rdc_config_t rdccfg;
1283*fcf3ce44SJohn Forte 	rdcconfig_t	*rdcp = NULL;
1284*fcf3ce44SJohn Forte 	rdcconfig_t	*cfg_rdcs = NULL;
1285*fcf3ce44SJohn Forte 	rdc_rc_t	*rc = NULL;
1286*fcf3ce44SJohn Forte 	rdc_rc_t	*rcp = NULL;
1287*fcf3ce44SJohn Forte 
1288*fcf3ce44SJohn Forte 	rdcp = rdc;
1289*fcf3ce44SJohn Forte 	rc = new_rc();
1290*fcf3ce44SJohn Forte 	if (!rc) {
1291*fcf3ce44SJohn Forte 		return (NULL);
1292*fcf3ce44SJohn Forte 	}
1293*fcf3ce44SJohn Forte 	rcp = rc;
1294*fcf3ce44SJohn Forte 
1295*fcf3ce44SJohn Forte 	while (rdcp) {
1296*fcf3ce44SJohn Forte 		bzero(&rdccfg, sizeof (rdc_config_t));
1297*fcf3ce44SJohn Forte 		rdccfg.rdc_set[0] = config2set(rdcp);
1298*fcf3ce44SJohn Forte 		rdccfg.command = RDC_CMD_RECONFIG;
1299*fcf3ce44SJohn Forte 		rdccfg.options |= RDC_OPT_REVERSE_ROLE;
1300*fcf3ce44SJohn Forte 		rdccfg.options |= set_mode(rdcp);
1301*fcf3ce44SJohn Forte 		populate_addrs(&rdccfg.rdc_set[0], 0);
1302*fcf3ce44SJohn Forte 
1303*fcf3ce44SJohn Forte 		*rcp = rdc_config(&rdccfg);
1304*fcf3ce44SJohn Forte 
1305*fcf3ce44SJohn Forte 		rdcp = rdcp->next;
1306*fcf3ce44SJohn Forte 		if (!rdcp)
1307*fcf3ce44SJohn Forte 			break;
1308*fcf3ce44SJohn Forte 
1309*fcf3ce44SJohn Forte 		rcp->next = new_rc();
1310*fcf3ce44SJohn Forte 		rcp = rcp->next;
1311*fcf3ce44SJohn Forte 		if (!rcp)
1312*fcf3ce44SJohn Forte 			break;
1313*fcf3ce44SJohn Forte 	}
1314*fcf3ce44SJohn Forte 	rcp = rc;
1315*fcf3ce44SJohn Forte 	rdcp = rdc;
1316*fcf3ce44SJohn Forte 	cfg_rdcs = chain_successful(rdcp, rcp);
1317*fcf3ce44SJohn Forte 	reverse_in_cfg(cfg_rdcs);
1318*fcf3ce44SJohn Forte 	rdc_free_config(cfg_rdcs, RDC_FREEALL);
1319*fcf3ce44SJohn Forte 
1320*fcf3ce44SJohn Forte 	return (rc);
1321*fcf3ce44SJohn Forte }
1322