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