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
bitmap_in_use(int cmd,char * hostp,char * bmp)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
check_dgislocal(char * dgname)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
ctag_check(rdcconfig_t * rdc)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
mounted(char * device)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
can_enable(rdcconfig_t * rdc)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
can_reconfig_pbmp(rdcconfig_t * rdc,char * bmp)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
can_reconfig_sbmp(rdcconfig_t * rdc,char * bmp)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 *
cant_rsync(rdcconfig_t * rdc)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