xref: /titanic_52/usr/src/lib/librdc/common/rdcrules.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/utsname.h>
28*fcf3ce44SJohn Forte #include <sys/mdb_modapi.h>
29*fcf3ce44SJohn Forte #include <stdio.h>
30*fcf3ce44SJohn Forte #include <errno.h>
31*fcf3ce44SJohn Forte #include <strings.h>
32*fcf3ce44SJohn Forte #include <stdlib.h>
33*fcf3ce44SJohn Forte #include <unistd.h>
34*fcf3ce44SJohn Forte #include <netdb.h>
35*fcf3ce44SJohn Forte #include <libintl.h>
36*fcf3ce44SJohn Forte #include <sys/stream.h>
37*fcf3ce44SJohn Forte #include <sys/socket.h>
38*fcf3ce44SJohn Forte #include <sys/stat.h>
39*fcf3ce44SJohn Forte #include <netinet/in.h>
40*fcf3ce44SJohn Forte #include <arpa/inet.h>
41*fcf3ce44SJohn Forte #include <ctype.h>
42*fcf3ce44SJohn Forte #include <thread.h>
43*fcf3ce44SJohn Forte #include <pthread.h>
44*fcf3ce44SJohn Forte 
45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
46*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
47*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_impl.h>
48*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
49*fcf3ce44SJohn Forte 
50*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_io.h>
51*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h>
52*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_prot.h>
53*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h>
54*fcf3ce44SJohn Forte #include <sys/nsctl/rdcerr.h>
55*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
56*fcf3ce44SJohn Forte 
57*fcf3ce44SJohn Forte #include <sys/unistat/spcs_dtrinkets.h>
58*fcf3ce44SJohn Forte #include <sys/unistat/spcs_etrinkets.h>
59*fcf3ce44SJohn Forte 
60*fcf3ce44SJohn Forte #include <sys/socket.h>
61*fcf3ce44SJohn Forte #include <sys/mnttab.h>
62*fcf3ce44SJohn Forte #include <netinet/in.h>
63*fcf3ce44SJohn Forte #include <arpa/inet.h>
64*fcf3ce44SJohn Forte #include <netinet/tcp.h>
65*fcf3ce44SJohn Forte #include <rpc/rpc_com.h>
66*fcf3ce44SJohn Forte #include <rpc/rpc.h>
67*fcf3ce44SJohn Forte 
68*fcf3ce44SJohn Forte #define	RDC_LOCAL_TAG	"local"
69*fcf3ce44SJohn Forte 
70*fcf3ce44SJohn Forte /*
71*fcf3ce44SJohn Forte  * bitmap_in_use
72*fcf3ce44SJohn Forte  * return 1 if in use
73*fcf3ce44SJohn Forte  * return 0 if not in use
74*fcf3ce44SJohn Forte  * return -1 on error
75*fcf3ce44SJohn Forte  */
76*fcf3ce44SJohn Forte 
77*fcf3ce44SJohn Forte int
78*fcf3ce44SJohn Forte bitmap_in_use(int cmd, char *hostp, char *bmp)
79*fcf3ce44SJohn Forte {
80*fcf3ce44SJohn Forte 	int i, setnumber;
81*fcf3ce44SJohn Forte 	CFGFILE *cfg;
82*fcf3ce44SJohn Forte 	char host[CFG_MAX_BUF];
83*fcf3ce44SJohn Forte 	char shost[CFG_MAX_BUF];
84*fcf3ce44SJohn Forte 	char pri[CFG_MAX_BUF]; /* rdc primary vol */
85*fcf3ce44SJohn Forte 	char sec[CFG_MAX_BUF]; /* rdc secondary vol */
86*fcf3ce44SJohn Forte 	char sbm[CFG_MAX_BUF]; /* rdc secondary bitmap */
87*fcf3ce44SJohn Forte 	char bit[CFG_MAX_BUF]; /* a bitmap */
88*fcf3ce44SJohn Forte 	char mas[CFG_MAX_BUF]; /* II master */
89*fcf3ce44SJohn Forte 	char sha[CFG_MAX_BUF]; /* II shadow */
90*fcf3ce44SJohn Forte 	char mod[CFG_MAX_BUF]; /* II mode */
91*fcf3ce44SJohn Forte 	char ovr[CFG_MAX_BUF]; /* II overflow */
92*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
93*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
94*fcf3ce44SJohn Forte 	int rc;
95*fcf3ce44SJohn Forte 	int ret = 0;
96*fcf3ce44SJohn Forte 
97*fcf3ce44SJohn Forte 
98*fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
99*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, NULL);
100*fcf3ce44SJohn Forte 		return (-1);
101*fcf3ce44SJohn Forte 	}
102*fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_RDLOCK)) {
103*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_DSCFG, 0, NULL);
104*fcf3ce44SJohn Forte 		cfg_close(cfg);
105*fcf3ce44SJohn Forte 		return (-1);
106*fcf3ce44SJohn Forte 	}
107*fcf3ce44SJohn Forte 
108*fcf3ce44SJohn Forte 	/*
109*fcf3ce44SJohn Forte 	 * look into II config to see if this is being used elsewhere
110*fcf3ce44SJohn Forte 	 */
111*fcf3ce44SJohn Forte 	/*CSTYLED*/
112*fcf3ce44SJohn Forte 	for (i = 0; ; i++) {
113*fcf3ce44SJohn Forte 		setnumber = i + 1;
114*fcf3ce44SJohn Forte 		snprintf(key, sizeof (key), "ii.set%d", setnumber);
115*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
116*fcf3ce44SJohn Forte 			break;
117*fcf3ce44SJohn Forte 
118*fcf3ce44SJohn Forte 		rc = sscanf(buf, "%s %s %s %s %s", mas, sha, bit, mod, ovr);
119*fcf3ce44SJohn Forte 		if (rc != 5) {
120*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_OS, 0, NULL);
121*fcf3ce44SJohn Forte 			    ret = -1;
122*fcf3ce44SJohn Forte 			    goto done;
123*fcf3ce44SJohn Forte 		}
124*fcf3ce44SJohn Forte 
125*fcf3ce44SJohn Forte 		/*
126*fcf3ce44SJohn Forte 		 * got master shadow bitmap, now compare
127*fcf3ce44SJohn Forte 		 */
128*fcf3ce44SJohn Forte 		if ((strcmp(bmp, mas) == 0) ||
129*fcf3ce44SJohn Forte 		    (strcmp(bmp, sha) == 0) ||
130*fcf3ce44SJohn Forte 		    (strcmp(bmp, bit) == 0) ||
131*fcf3ce44SJohn Forte 		    (strcmp(bmp, ovr) == 0)) {
132*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
133*fcf3ce44SJohn Forte 			    "bitmap %s is in use by"
134*fcf3ce44SJohn Forte 			    "Point-in-Time Copy", bmp);
135*fcf3ce44SJohn Forte 			ret = 1;
136*fcf3ce44SJohn Forte 			goto done;
137*fcf3ce44SJohn Forte 		}
138*fcf3ce44SJohn Forte 	}
139*fcf3ce44SJohn Forte 	/*
140*fcf3ce44SJohn Forte 	 * and last but not least, make sure sndr is not using vol for anything
141*fcf3ce44SJohn Forte 	 */
142*fcf3ce44SJohn Forte 	/*CSTYLED*/
143*fcf3ce44SJohn Forte 	for (i = 0; ; i++) {
144*fcf3ce44SJohn Forte 		setnumber = i + 1;
145*fcf3ce44SJohn Forte 		snprintf(key, sizeof (key), "sndr.set%d", setnumber);
146*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
147*fcf3ce44SJohn Forte 			break;
148*fcf3ce44SJohn Forte 		/*
149*fcf3ce44SJohn Forte 		 * I think this is quicker than
150*fcf3ce44SJohn Forte 		 * having to double dip into the config
151*fcf3ce44SJohn Forte 		 */
152*fcf3ce44SJohn Forte 		(void) sscanf(buf, "%s %s %s %s %s %s", host, pri, bit,
153*fcf3ce44SJohn Forte 		    shost, sec, sbm);
154*fcf3ce44SJohn Forte 		if (cmd == RDC_CMD_ENABLE) {
155*fcf3ce44SJohn Forte 			if (self_check(host)) {
156*fcf3ce44SJohn Forte 				if ((strcmp(bmp, pri) == 0) ||
157*fcf3ce44SJohn Forte 				    (strcmp(bmp, bit) == 0)) {
158*fcf3ce44SJohn Forte 					rdc_set_error(NULL, RDC_INTERNAL,
159*fcf3ce44SJohn Forte 					    RDC_NONFATAL, dgettext("librdc",
160*fcf3ce44SJohn Forte 					    "bitmap %s is in use by %s"),
161*fcf3ce44SJohn Forte 					    bmp, RDC_NAME_DU_JOUR);
162*fcf3ce44SJohn Forte 
163*fcf3ce44SJohn Forte 
164*fcf3ce44SJohn Forte 				    ret = 1;
165*fcf3ce44SJohn Forte 				    goto done;
166*fcf3ce44SJohn Forte 				}
167*fcf3ce44SJohn Forte 			} else {
168*fcf3ce44SJohn Forte 				if ((strcmp(bmp, sec) == 0) ||
169*fcf3ce44SJohn Forte 				    (strcmp(bmp, sbm) == 0)) {
170*fcf3ce44SJohn Forte 					rdc_set_error(NULL, RDC_INTERNAL,
171*fcf3ce44SJohn Forte 					    RDC_NONFATAL, dgettext("librdc",
172*fcf3ce44SJohn Forte 					    "bitmap %s is in use by %s"),
173*fcf3ce44SJohn Forte 					    bmp, RDC_NAME_DU_JOUR);
174*fcf3ce44SJohn Forte 				    ret = 1;
175*fcf3ce44SJohn Forte 				    goto done;
176*fcf3ce44SJohn Forte 				}
177*fcf3ce44SJohn Forte 			}
178*fcf3ce44SJohn Forte 		} else if (cmd == RDC_CMD_RECONFIG) {
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte 			/*
181*fcf3ce44SJohn Forte 			 * read this logic 1000 times and consider
182*fcf3ce44SJohn Forte 			 * multi homed, one to many, many to one (marketing)
183*fcf3ce44SJohn Forte 			 * etc, etc, before changing
184*fcf3ce44SJohn Forte 			 */
185*fcf3ce44SJohn Forte 			if (self_check(hostp)) {
186*fcf3ce44SJohn Forte 				if (self_check(host)) {
187*fcf3ce44SJohn Forte 					if ((strcmp(bmp, pri) == 0) ||
188*fcf3ce44SJohn Forte 					    (strcmp(bmp, bit) == 0)) {
189*fcf3ce44SJohn Forte 						rdc_set_error(NULL,
190*fcf3ce44SJohn Forte 						    RDC_INTERNAL, RDC_NONFATAL,
191*fcf3ce44SJohn Forte 						    dgettext("librdc", "bitmap"
192*fcf3ce44SJohn Forte 						    " %s is in use by %s"),
193*fcf3ce44SJohn Forte 						    bmp, RDC_NAME_DU_JOUR);
194*fcf3ce44SJohn Forte 						ret = 1;
195*fcf3ce44SJohn Forte 						goto done;
196*fcf3ce44SJohn Forte 					}
197*fcf3ce44SJohn Forte 				} else {
198*fcf3ce44SJohn Forte 					if ((strcmp(hostp, shost) == 0) &&
199*fcf3ce44SJohn Forte 					    (strcmp(bmp, sec) == 0) ||
200*fcf3ce44SJohn Forte 					    (strcmp(bmp, sbm) == 0)) {
201*fcf3ce44SJohn Forte 						rdc_set_error(NULL,
202*fcf3ce44SJohn Forte 						    RDC_INTERNAL, RDC_NONFATAL,
203*fcf3ce44SJohn Forte 						    dgettext("librdc", "bitmap"
204*fcf3ce44SJohn Forte 						    " %s is in use by %s"),
205*fcf3ce44SJohn Forte 						    bmp, RDC_NAME_DU_JOUR);
206*fcf3ce44SJohn Forte 						ret = 1;
207*fcf3ce44SJohn Forte 						goto done;
208*fcf3ce44SJohn Forte 					}
209*fcf3ce44SJohn Forte 				}
210*fcf3ce44SJohn Forte 			} else { /* self_check(hostp) failed */
211*fcf3ce44SJohn Forte 				if (self_check(host)) {
212*fcf3ce44SJohn Forte 					if ((strcmp(shost, hostp) == 0) &&
213*fcf3ce44SJohn Forte 					    (strcmp(bmp, sec) == 0) ||
214*fcf3ce44SJohn Forte 					    (strcmp(bmp, sbm) == 0)) {
215*fcf3ce44SJohn Forte 						rdc_set_error(NULL,
216*fcf3ce44SJohn Forte 						    RDC_INTERNAL, RDC_NONFATAL,
217*fcf3ce44SJohn Forte 						    dgettext("librdc", "bitmap"
218*fcf3ce44SJohn Forte 						    " %s is in use by %s"),
219*fcf3ce44SJohn Forte 						    bmp, RDC_NAME_DU_JOUR);
220*fcf3ce44SJohn Forte 						ret = 1;
221*fcf3ce44SJohn Forte 						goto done;
222*fcf3ce44SJohn Forte 					}
223*fcf3ce44SJohn Forte 				} else {
224*fcf3ce44SJohn Forte 					if ((strcmp(host, hostp) == 0) &&
225*fcf3ce44SJohn Forte 					    (strcmp(bmp, pri) == 0) ||
226*fcf3ce44SJohn Forte 					    (strcmp(bmp, bit) == 0)) {
227*fcf3ce44SJohn Forte 						rdc_set_error(NULL,
228*fcf3ce44SJohn Forte 						    RDC_INTERNAL, RDC_NONFATAL,
229*fcf3ce44SJohn Forte 						    dgettext("librdc", "bitmap"
230*fcf3ce44SJohn Forte 						    " %s is in use by %s"),
231*fcf3ce44SJohn Forte 						    bmp, RDC_NAME_DU_JOUR);
232*fcf3ce44SJohn Forte 						ret = 1;
233*fcf3ce44SJohn Forte 						goto done;
234*fcf3ce44SJohn Forte 					}
235*fcf3ce44SJohn Forte 				}
236*fcf3ce44SJohn Forte 			}
237*fcf3ce44SJohn Forte 
238*fcf3ce44SJohn Forte 		}
239*fcf3ce44SJohn Forte 
240*fcf3ce44SJohn Forte 	}
241*fcf3ce44SJohn Forte done:
242*fcf3ce44SJohn Forte 	cfg_close(cfg);
243*fcf3ce44SJohn Forte 	return (ret);
244*fcf3ce44SJohn Forte 
245*fcf3ce44SJohn Forte }
246*fcf3ce44SJohn Forte 
247*fcf3ce44SJohn Forte int
248*fcf3ce44SJohn Forte check_dgislocal(char *dgname)
249*fcf3ce44SJohn Forte {
250*fcf3ce44SJohn Forte 	char *othernode;
251*fcf3ce44SJohn Forte 	int rc;
252*fcf3ce44SJohn Forte 
253*fcf3ce44SJohn Forte 	/*
254*fcf3ce44SJohn Forte 	 * check where this disk service is mastered
255*fcf3ce44SJohn Forte 	 */
256*fcf3ce44SJohn Forte 
257*fcf3ce44SJohn Forte 	rc = cfg_dgname_islocal(dgname, &othernode);
258*fcf3ce44SJohn Forte 	if (rc < 0) {
259*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
260*fcf3ce44SJohn Forte 		    gettext("unable to find "
261*fcf3ce44SJohn Forte 		    "disk service, %s: %s"), dgname, strerror(errno));
262*fcf3ce44SJohn Forte 		    return (-1);
263*fcf3ce44SJohn Forte 	}
264*fcf3ce44SJohn Forte 
265*fcf3ce44SJohn Forte 	if (rc == 0) {
266*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
267*fcf3ce44SJohn Forte 		    gettext("disk service, %s, is "
268*fcf3ce44SJohn Forte 		    "active on node \"%s\"\nPlease re-issue "
269*fcf3ce44SJohn Forte 		    "the command on that node"), dgname, othernode);
270*fcf3ce44SJohn Forte 		    return (-1);
271*fcf3ce44SJohn Forte 	}
272*fcf3ce44SJohn Forte 	return (DCMD_OK);
273*fcf3ce44SJohn Forte }
274*fcf3ce44SJohn Forte 
275*fcf3ce44SJohn Forte int
276*fcf3ce44SJohn Forte ctag_check(rdcconfig_t *rdc)
277*fcf3ce44SJohn Forte {
278*fcf3ce44SJohn Forte 	char *file_dgname;
279*fcf3ce44SJohn Forte 	char *bmp_dgname;
280*fcf3ce44SJohn Forte 	char *fromhost, *tohost;
281*fcf3ce44SJohn Forte 	char *fromfile, *tofile;
282*fcf3ce44SJohn Forte 	char *frombitmap, *tobitmap;
283*fcf3ce44SJohn Forte 	char *localfile;
284*fcf3ce44SJohn Forte 	char *ctag;
285*fcf3ce44SJohn Forte 	char file_buf[MAX_RDC_HOST_SIZE];
286*fcf3ce44SJohn Forte 	char bmp_buf[MAX_RDC_HOST_SIZE];
287*fcf3ce44SJohn Forte 	int is_primary;
288*fcf3ce44SJohn Forte 	int islocal = 0;
289*fcf3ce44SJohn Forte 	struct hostent *hp;
290*fcf3ce44SJohn Forte 	char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
291*fcf3ce44SJohn Forte 
292*fcf3ce44SJohn Forte 	fromhost = rdc->phost;
293*fcf3ce44SJohn Forte 	fromfile = rdc->pfile;
294*fcf3ce44SJohn Forte 	frombitmap = rdc->pbmp;
295*fcf3ce44SJohn Forte 	tohost = rdc->shost;
296*fcf3ce44SJohn Forte 	tofile = rdc->sfile;
297*fcf3ce44SJohn Forte 	tobitmap = rdc->sbmp;
298*fcf3ce44SJohn Forte 	ctag = rdc->ctag;
299*fcf3ce44SJohn Forte 
300*fcf3ce44SJohn Forte 	/*
301*fcf3ce44SJohn Forte 	 * Check for the special (local) cluster tag
302*fcf3ce44SJohn Forte 	 */
303*fcf3ce44SJohn Forte 	if (!cfg_iscluster())
304*fcf3ce44SJohn Forte 		return (0);
305*fcf3ce44SJohn Forte 
306*fcf3ce44SJohn Forte 	if (ctag != NULL && strcmp(rdc->ctag, RDC_LOCAL_TAG) == 0) {
307*fcf3ce44SJohn Forte 		strcpy(rdc->ctag, "-");
308*fcf3ce44SJohn Forte 		islocal = TRUE;
309*fcf3ce44SJohn Forte 	} else {
310*fcf3ce44SJohn Forte 		islocal = FALSE;
311*fcf3ce44SJohn Forte 	}
312*fcf3ce44SJohn Forte 
313*fcf3ce44SJohn Forte 	hp = gethost_byname(fromhost);
314*fcf3ce44SJohn Forte 	strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
315*fcf3ce44SJohn Forte 	hp = gethost_byname(tohost);
316*fcf3ce44SJohn Forte 	strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
317*fcf3ce44SJohn Forte 	if (!self_check(fromname) && !self_check(toname)) {
318*fcf3ce44SJohn Forte 		/*
319*fcf3ce44SJohn Forte 		 * If we could get a list of logical hosts on this cluster
320*fcf3ce44SJohn Forte 		 * then we could print something intelligent about where
321*fcf3ce44SJohn Forte 		 * the volume is mastered. For now, just print some babble
322*fcf3ce44SJohn Forte 		 * about the fact that we have no idea.
323*fcf3ce44SJohn Forte 		 */
324*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
325*fcf3ce44SJohn Forte 				gettext("either %s:%s or %s:%s is not local"),
326*fcf3ce44SJohn Forte 					fromhost, fromfile, tohost, tofile);
327*fcf3ce44SJohn Forte 			return (-1);
328*fcf3ce44SJohn Forte 	}
329*fcf3ce44SJohn Forte 
330*fcf3ce44SJohn Forte 	is_primary = self_check(fromname);
331*fcf3ce44SJohn Forte 
332*fcf3ce44SJohn Forte 	/*
333*fcf3ce44SJohn Forte 	 * If implicit disk group name and no ctag specified by user,
334*fcf3ce44SJohn Forte 	 * we set the ctag to it.
335*fcf3ce44SJohn Forte 	 * If implicit disk group name, it must match any supplied ctag.
336*fcf3ce44SJohn Forte 	 */
337*fcf3ce44SJohn Forte 	if (is_primary)
338*fcf3ce44SJohn Forte 		localfile = fromfile;
339*fcf3ce44SJohn Forte 	else
340*fcf3ce44SJohn Forte 		localfile = tofile;
341*fcf3ce44SJohn Forte 	file_dgname = cfg_dgname(localfile, file_buf, sizeof (file_buf));
342*fcf3ce44SJohn Forte 	if (file_dgname != NULL && file_dgname[0] != '\0')
343*fcf3ce44SJohn Forte 		if (check_dgislocal(file_dgname) < 0) {
344*fcf3ce44SJohn Forte 			/* errors already set */
345*fcf3ce44SJohn Forte 			return (-1);
346*fcf3ce44SJohn Forte 		}
347*fcf3ce44SJohn Forte 
348*fcf3ce44SJohn Forte 	if (strlen(ctag) == 0 && file_dgname && strlen(file_dgname))
349*fcf3ce44SJohn Forte 		strncpy(ctag, file_dgname, MAX_RDC_HOST_SIZE);
350*fcf3ce44SJohn Forte 
351*fcf3ce44SJohn Forte 	/*
352*fcf3ce44SJohn Forte 	 * making an exception here for users giving the "local"tag
353*fcf3ce44SJohn Forte 	 * this overrides this error message. (rdc_islocal ! = 1)
354*fcf3ce44SJohn Forte 	 */
355*fcf3ce44SJohn Forte 	if (strlen(ctag) != 0 && file_dgname && islocal != 1 &&
356*fcf3ce44SJohn Forte 	    strlen(file_dgname) != 0 &&
357*fcf3ce44SJohn Forte 	    strncmp(ctag, file_dgname, MAX_RDC_HOST_SIZE) != 0) {
358*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
359*fcf3ce44SJohn Forte 		    gettext("ctag \"%s\" does not "
360*fcf3ce44SJohn Forte 		    "match disk group name \"%s\" of volume %s"), ctag,
361*fcf3ce44SJohn Forte 		    file_dgname, localfile);
362*fcf3ce44SJohn Forte 		return (-1);
363*fcf3ce44SJohn Forte 	}
364*fcf3ce44SJohn Forte 	if ((file_dgname == NULL) || ((strlen(ctag) == 0) &&
365*fcf3ce44SJohn Forte 	    (strlen(file_dgname) == 0))) {
366*fcf3ce44SJohn Forte 		/*
367*fcf3ce44SJohn Forte 		 * we must have a non-volume managed disk here
368*fcf3ce44SJohn Forte 		 * so ask for a tag and get out
369*fcf3ce44SJohn Forte 		 */
370*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
371*fcf3ce44SJohn Forte 		    gettext("volume \"%s\" is not part"
372*fcf3ce44SJohn Forte 		    " of a disk group,\nplease specify resource ctag\n"),
373*fcf3ce44SJohn Forte 		    localfile);
374*fcf3ce44SJohn Forte 
375*fcf3ce44SJohn Forte 	}
376*fcf3ce44SJohn Forte 
377*fcf3ce44SJohn Forte 	/*
378*fcf3ce44SJohn Forte 	 * Local bitmap must also have same ctag.
379*fcf3ce44SJohn Forte 	 */
380*fcf3ce44SJohn Forte 	if (is_primary)
381*fcf3ce44SJohn Forte 		localfile = frombitmap;
382*fcf3ce44SJohn Forte 	else
383*fcf3ce44SJohn Forte 		localfile = tobitmap;
384*fcf3ce44SJohn Forte 	bmp_dgname = cfg_dgname(localfile, bmp_buf, sizeof (bmp_buf));
385*fcf3ce44SJohn Forte 	if (bmp_dgname != NULL && bmp_dgname[0] != '\0')
386*fcf3ce44SJohn Forte 		if (check_dgislocal(bmp_dgname) < 0) {
387*fcf3ce44SJohn Forte 			/* error already set */
388*fcf3ce44SJohn Forte 			return (-1);
389*fcf3ce44SJohn Forte 		}
390*fcf3ce44SJohn Forte 
391*fcf3ce44SJohn Forte 	if (file_dgname && strlen(file_dgname) != 0) {
392*fcf3ce44SJohn Forte 		/* File is in a real disk group */
393*fcf3ce44SJohn Forte 		if ((bmp_dgname == NULL) || (strlen(bmp_dgname) == 0)) {
394*fcf3ce44SJohn Forte 			/* Bitmap is not in a real disk group */
395*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
396*fcf3ce44SJohn Forte 			    gettext("bitmap %s is not in disk group \"%s\""),
397*fcf3ce44SJohn Forte 			    localfile, islocal < 1?file_dgname:ctag);
398*fcf3ce44SJohn Forte 			return (-1);
399*fcf3ce44SJohn Forte 		}
400*fcf3ce44SJohn Forte 	}
401*fcf3ce44SJohn Forte 	if (strlen(ctag) != 0 && bmp_dgname && islocal != 1 &&
402*fcf3ce44SJohn Forte 	    strlen(bmp_dgname) != 0 &&
403*fcf3ce44SJohn Forte 	    strncmp(ctag, bmp_dgname, MAX_RDC_HOST_SIZE) != 0) {
404*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
405*fcf3ce44SJohn Forte 		    gettext("ctag \"%s\" does not "
406*fcf3ce44SJohn Forte 		    "match disk group name \"%s\" of bitmap %s"),
407*fcf3ce44SJohn Forte 		    ctag, bmp_dgname, localfile);
408*fcf3ce44SJohn Forte 		return (-1);
409*fcf3ce44SJohn Forte 	}
410*fcf3ce44SJohn Forte 
411*fcf3ce44SJohn Forte 	return (0);
412*fcf3ce44SJohn Forte }
413*fcf3ce44SJohn Forte int
414*fcf3ce44SJohn Forte mounted(char *device)
415*fcf3ce44SJohn Forte {
416*fcf3ce44SJohn Forte 	char target[NSC_MAXPATH];
417*fcf3ce44SJohn Forte 	struct mnttab mntref;
418*fcf3ce44SJohn Forte 	struct mnttab mntent;
419*fcf3ce44SJohn Forte 	FILE *mntfp;
420*fcf3ce44SJohn Forte 	int rdsk;
421*fcf3ce44SJohn Forte 	char *s;
422*fcf3ce44SJohn Forte 	int rc;
423*fcf3ce44SJohn Forte 	int i;
424*fcf3ce44SJohn Forte 
425*fcf3ce44SJohn Forte 	rdsk = i = 0;
426*fcf3ce44SJohn Forte 	for (s = target; i < NSC_MAXPATH && (*s = *device++); i++) {
427*fcf3ce44SJohn Forte 		if (*s == 'r' && rdsk == 0 && strncmp(device, "dsk/", 4) == 0)
428*fcf3ce44SJohn Forte 			rdsk = 1;
429*fcf3ce44SJohn Forte 		else
430*fcf3ce44SJohn Forte 			s++;
431*fcf3ce44SJohn Forte 	}
432*fcf3ce44SJohn Forte 	*s = '\0';
433*fcf3ce44SJohn Forte 
434*fcf3ce44SJohn Forte 	mntref.mnt_special = target;
435*fcf3ce44SJohn Forte 	mntref.mnt_mountp = NULL;
436*fcf3ce44SJohn Forte 	mntref.mnt_fstype = NULL;
437*fcf3ce44SJohn Forte 	mntref.mnt_mntopts = NULL;
438*fcf3ce44SJohn Forte 	mntref.mnt_time = NULL;
439*fcf3ce44SJohn Forte 
440*fcf3ce44SJohn Forte 	mntfp = fopen(MNTTAB, "r");
441*fcf3ce44SJohn Forte 
442*fcf3ce44SJohn Forte 	if (mntfp == NULL) {
443*fcf3ce44SJohn Forte 		/* Assume the worst, that it is mounted */
444*fcf3ce44SJohn Forte 		return (1);
445*fcf3ce44SJohn Forte 	}
446*fcf3ce44SJohn Forte 
447*fcf3ce44SJohn Forte 	if ((rc = getmntany(mntfp, &mntent, &mntref)) != -1) {
448*fcf3ce44SJohn Forte 		/* found something before EOF */
449*fcf3ce44SJohn Forte 		fclose(mntfp);
450*fcf3ce44SJohn Forte 		return (1);
451*fcf3ce44SJohn Forte 	}
452*fcf3ce44SJohn Forte 
453*fcf3ce44SJohn Forte 	fclose(mntfp);
454*fcf3ce44SJohn Forte 	return (0);
455*fcf3ce44SJohn Forte }
456*fcf3ce44SJohn Forte 
457*fcf3ce44SJohn Forte int
458*fcf3ce44SJohn Forte can_enable(rdcconfig_t *rdc)
459*fcf3ce44SJohn Forte {
460*fcf3ce44SJohn Forte 	struct stat stb;
461*fcf3ce44SJohn Forte 
462*fcf3ce44SJohn Forte 	if ((strcmp(rdc->pfile, rdc->pbmp) == 0) ||
463*fcf3ce44SJohn Forte 	    (strcmp(rdc->sfile, rdc->sbmp) == 0)) {
464*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
465*fcf3ce44SJohn Forte 		dgettext("librdc", "volumes and bitmaps must not match"));
466*fcf3ce44SJohn Forte 		return (0);
467*fcf3ce44SJohn Forte 	}
468*fcf3ce44SJohn Forte 	if (ctag_check(rdc) < 0) {
469*fcf3ce44SJohn Forte 		/* rdc_error should already be set */
470*fcf3ce44SJohn Forte 		return (0);
471*fcf3ce44SJohn Forte 	}
472*fcf3ce44SJohn Forte 
473*fcf3ce44SJohn Forte 	if (self_check(rdc->phost)) {
474*fcf3ce44SJohn Forte 		if (stat(rdc->pfile, &stb) != 0) {
475*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
476*fcf3ce44SJohn Forte 			return (0);
477*fcf3ce44SJohn Forte 		}
478*fcf3ce44SJohn Forte 		if (!S_ISCHR(stb.st_mode)) {
479*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
480*fcf3ce44SJohn Forte 			    dgettext("librdc", "%s is not a character device"),
481*fcf3ce44SJohn Forte 			    rdc->pfile);
482*fcf3ce44SJohn Forte 			return (0);
483*fcf3ce44SJohn Forte 		}
484*fcf3ce44SJohn Forte 		return (rdc->persist ?
485*fcf3ce44SJohn Forte 		    !bitmap_in_use(RDC_CMD_ENABLE, rdc->phost, rdc->pbmp) : 1);
486*fcf3ce44SJohn Forte 	} else { /* on the secondary */
487*fcf3ce44SJohn Forte 		if (stat(rdc->sfile, &stb) != 0) {
488*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_OS, 0,
489*fcf3ce44SJohn Forte 			    dgettext("librdc", "unable to access %s: %s"),
490*fcf3ce44SJohn Forte 			    rdc->sfile, strerror(errno));
491*fcf3ce44SJohn Forte 		}
492*fcf3ce44SJohn Forte 		if (!S_ISCHR(stb.st_mode)) {
493*fcf3ce44SJohn Forte 			rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
494*fcf3ce44SJohn Forte 			    dgettext("librdc",
495*fcf3ce44SJohn Forte 			    "%s is not a character device"), rdc->sfile);
496*fcf3ce44SJohn Forte 		}
497*fcf3ce44SJohn Forte 		return (rdc->persist ?
498*fcf3ce44SJohn Forte 		    !bitmap_in_use(RDC_CMD_ENABLE, rdc->shost, rdc->sbmp) : 1);
499*fcf3ce44SJohn Forte 	}
500*fcf3ce44SJohn Forte }
501*fcf3ce44SJohn Forte 
502*fcf3ce44SJohn Forte int
503*fcf3ce44SJohn Forte can_reconfig_pbmp(rdcconfig_t *rdc, char *bmp)
504*fcf3ce44SJohn Forte {
505*fcf3ce44SJohn Forte 	if (!rdc->persist)
506*fcf3ce44SJohn Forte 		return (0);
507*fcf3ce44SJohn Forte 
508*fcf3ce44SJohn Forte 	return (!bitmap_in_use(RDC_CMD_RECONFIG, rdc->phost, bmp));
509*fcf3ce44SJohn Forte }
510*fcf3ce44SJohn Forte 
511*fcf3ce44SJohn Forte int
512*fcf3ce44SJohn Forte can_reconfig_sbmp(rdcconfig_t *rdc, char *bmp)
513*fcf3ce44SJohn Forte {
514*fcf3ce44SJohn Forte 	if (!rdc->persist)
515*fcf3ce44SJohn Forte 		return (0);
516*fcf3ce44SJohn Forte 
517*fcf3ce44SJohn Forte 	return (!bitmap_in_use(RDC_CMD_RECONFIG, rdc->shost, bmp));
518*fcf3ce44SJohn Forte }
519*fcf3ce44SJohn Forte 
520*fcf3ce44SJohn Forte rdc_rc_t *
521*fcf3ce44SJohn Forte cant_rsync(rdcconfig_t *rdc)
522*fcf3ce44SJohn Forte {
523*fcf3ce44SJohn Forte 	rdc_rc_t *rc;
524*fcf3ce44SJohn Forte 
525*fcf3ce44SJohn Forte 	if (mounted(rdc->pfile)) {
526*fcf3ce44SJohn Forte 		rc = new_rc();
527*fcf3ce44SJohn Forte 		if (rc == NULL)
528*fcf3ce44SJohn Forte 			return (NULL);
529*fcf3ce44SJohn Forte 		strncpy(rc->set.phost, rdc->phost, MAX_RDC_HOST_SIZE);
530*fcf3ce44SJohn Forte 		strncpy(rc->set.pfile, rdc->pfile, NSC_MAXPATH);
531*fcf3ce44SJohn Forte 		strncpy(rc->set.pbmp, rdc->pbmp, NSC_MAXPATH);
532*fcf3ce44SJohn Forte 		strncpy(rc->set.shost, rdc->shost, MAX_RDC_HOST_SIZE);
533*fcf3ce44SJohn Forte 		strncpy(rc->set.sfile, rdc->sfile, NSC_MAXPATH);
534*fcf3ce44SJohn Forte 		strncpy(rc->set.sbmp, rdc->sbmp, NSC_MAXPATH);
535*fcf3ce44SJohn Forte 
536*fcf3ce44SJohn Forte 		rc->rc = -1;
537*fcf3ce44SJohn Forte 
538*fcf3ce44SJohn Forte 		rdc_set_error(NULL, RDC_INTERNAL, 0, "unable to sync %s volume"
539*fcf3ce44SJohn Forte 		    " is currently mounted", rdc->pfile);
540*fcf3ce44SJohn Forte 		strncpy(rc->msg, rdc_error(NULL), RDC_ERR_SIZE);
541*fcf3ce44SJohn Forte 
542*fcf3ce44SJohn Forte 		return (rc);
543*fcf3ce44SJohn Forte 	}
544*fcf3ce44SJohn Forte 	return (NULL);
545*fcf3ce44SJohn Forte }
546