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/wait.h> 29*fcf3ce44SJohn Forte #include <stdio.h> 30*fcf3ce44SJohn Forte #include <errno.h> 31*fcf3ce44SJohn Forte #include <values.h> 32*fcf3ce44SJohn Forte #include <limits.h> 33*fcf3ce44SJohn Forte #include <fcntl.h> 34*fcf3ce44SJohn Forte #include <strings.h> 35*fcf3ce44SJohn Forte #include <stdlib.h> 36*fcf3ce44SJohn Forte #include <unistd.h> 37*fcf3ce44SJohn Forte #include <sys/stat.h> 38*fcf3ce44SJohn Forte 39*fcf3ce44SJohn Forte #include <locale.h> 40*fcf3ce44SJohn Forte #include <langinfo.h> 41*fcf3ce44SJohn Forte #include <libintl.h> 42*fcf3ce44SJohn Forte #include <stdarg.h> 43*fcf3ce44SJohn Forte #include <netdb.h> 44*fcf3ce44SJohn Forte #include <ctype.h> 45*fcf3ce44SJohn Forte 46*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_io.h> 47*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h> 48*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_prot.h> 49*fcf3ce44SJohn Forte 50*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h> 51*fcf3ce44SJohn Forte 52*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h> 53*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h> 54*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h> 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte #include <sys/socket.h> 57*fcf3ce44SJohn Forte #include <netinet/in.h> 58*fcf3ce44SJohn Forte #include <arpa/inet.h> 59*fcf3ce44SJohn Forte #include <netinet/tcp.h> 60*fcf3ce44SJohn Forte #include <rpc/rpc_com.h> 61*fcf3ce44SJohn Forte #include <rpc/rpc.h> 62*fcf3ce44SJohn Forte 63*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h> 64*fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.h> 65*fcf3ce44SJohn Forte 66*fcf3ce44SJohn Forte #include "rdcadm.h" 67*fcf3ce44SJohn Forte 68*fcf3ce44SJohn Forte /* 69*fcf3ce44SJohn Forte * support for the special cluster tag "local" to be used with -C in a 70*fcf3ce44SJohn Forte * cluster for local volumes. 71*fcf3ce44SJohn Forte */ 72*fcf3ce44SJohn Forte 73*fcf3ce44SJohn Forte #define RDC_LOCAL_TAG "local" 74*fcf3ce44SJohn Forte 75*fcf3ce44SJohn Forte typedef struct volcount_s { 76*fcf3ce44SJohn Forte int count; 77*fcf3ce44SJohn Forte } volcount_t; 78*fcf3ce44SJohn Forte hash_node_t **volhash = NULL; 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte /* 81*fcf3ce44SJohn Forte * rdc_islocal is only pertinent while creating the pairs array. 82*fcf3ce44SJohn Forte * after all the pairs are set, its value is useless, retaining 83*fcf3ce44SJohn Forte * the last value it was set to. 84*fcf3ce44SJohn Forte * its only reason in life is to suppress an error message in 2 85*fcf3ce44SJohn Forte * places where the inappropriate becomes appropriate (a supplied 86*fcf3ce44SJohn Forte * ctag which does not match an implied one cfg_dgame()). This 87*fcf3ce44SJohn Forte * happens when C "local" is supplied. It is then used to make an 88*fcf3ce44SJohn Forte * error message clearer. A 89*fcf3ce44SJohn Forte * gettext("set %s does not match", rdc_islocal < 1?dga:dgb) situation 90*fcf3ce44SJohn Forte */ 91*fcf3ce44SJohn Forte static int rdc_islocal = 0; 92*fcf3ce44SJohn Forte 93*fcf3ce44SJohn Forte char *program; 94*fcf3ce44SJohn Forte 95*fcf3ce44SJohn Forte #define min(a, b) ((a) > (b) ? (b) : (a)) 96*fcf3ce44SJohn Forte 97*fcf3ce44SJohn Forte static char place_holder[] = "-"; /* cfg place holder value */ 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte /* 100*fcf3ce44SJohn Forte * config file user level Dual copy pair structure 101*fcf3ce44SJohn Forte */ 102*fcf3ce44SJohn Forte typedef struct _sd_dual_pair { 103*fcf3ce44SJohn Forte char fhost[MAX_RDC_HOST_SIZE]; /* Hostname for primary device */ 104*fcf3ce44SJohn Forte char fnetaddr[RDC_MAXADDR]; /* Host netaddr for primary device */ 105*fcf3ce44SJohn Forte char ffile[NSC_MAXPATH]; /* Primary device */ 106*fcf3ce44SJohn Forte char fbitmap[NSC_MAXPATH]; /* Primary bitmap device */ 107*fcf3ce44SJohn Forte char thost[MAX_RDC_HOST_SIZE]; /* Hostname for secondary device */ 108*fcf3ce44SJohn Forte char tnetaddr[RDC_MAXADDR]; /* Host netaddr for secondary device */ 109*fcf3ce44SJohn Forte char tfile[NSC_MAXPATH]; /* Secondary device */ 110*fcf3ce44SJohn Forte char tbitmap[NSC_MAXPATH]; /* Secondary bitmap device */ 111*fcf3ce44SJohn Forte char directfile[NSC_MAXPATH]; /* Local FCAL direct IO volume */ 112*fcf3ce44SJohn Forte char group[NSC_MAXPATH]; /* Group name */ 113*fcf3ce44SJohn Forte char ctag[MAX_RDC_HOST_SIZE]; /* Cluster resource name tag */ 114*fcf3ce44SJohn Forte char diskqueue[NSC_MAXPATH]; /* Disk Queue volume */ 115*fcf3ce44SJohn Forte int doasync; /* Device is in sync/async mode */ 116*fcf3ce44SJohn Forte } _sd_dual_pair_t; 117*fcf3ce44SJohn Forte 118*fcf3ce44SJohn Forte #define EXTRA_ARGS 6 /* g grp C ctag q diskqueue */ 119*fcf3ce44SJohn Forte 120*fcf3ce44SJohn Forte static int rdc_operation( 121*fcf3ce44SJohn Forte CFGFILE *, char *, char *, char *, char *, char *, char *, 122*fcf3ce44SJohn Forte int, int, char *, char *, char *, char *, int *, int); 123*fcf3ce44SJohn Forte int read_config(int, char *, char *, char *); 124*fcf3ce44SJohn Forte static int read_libcfg(int, char *, char *); 125*fcf3ce44SJohn Forte int prompt_user(int, int); 126*fcf3ce44SJohn Forte static void rdc_check_dgislocal(char *); 127*fcf3ce44SJohn Forte void process_clocal(char *); 128*fcf3ce44SJohn Forte static void usage(void); 129*fcf3ce44SJohn Forte void q_usage(int); 130*fcf3ce44SJohn Forte static void load_rdc_vols(CFGFILE *); 131*fcf3ce44SJohn Forte static void unload_rdc_vols(); 132*fcf3ce44SJohn Forte static int perform_autosv(); 133*fcf3ce44SJohn Forte static void different_devs(char *, char *); 134*fcf3ce44SJohn Forte static void validate_name(CFGFILE *, char *); 135*fcf3ce44SJohn Forte static void set_autosync(int, char *, char *, char *); 136*fcf3ce44SJohn Forte static int autosync_is_on(char *tohost, char *tofile); 137*fcf3ce44SJohn Forte static void enable_autosync(char *fhost, char *ffile, char *thost, char *tfile); 138*fcf3ce44SJohn Forte static void checkgfields(CFGFILE *, int, char *, char *, char *, char *, 139*fcf3ce44SJohn Forte char *, char *, char *, char *, char *); 140*fcf3ce44SJohn Forte static void checkgfield(CFGFILE *, int, char *, char *, char *); 141*fcf3ce44SJohn Forte static int rdc_bitmapset(char *, char *, char *, int, nsc_off_t); 142*fcf3ce44SJohn Forte static int parse_cfg_buf(char *, _sd_dual_pair_t *, char *); 143*fcf3ce44SJohn Forte static void verify_groupname(char *grp); 144*fcf3ce44SJohn Forte extern char *basename(char *); 145*fcf3ce44SJohn Forte 146*fcf3ce44SJohn Forte int rdc_maxsets; 147*fcf3ce44SJohn Forte static _sd_dual_pair_t *pair_list; 148*fcf3ce44SJohn Forte 149*fcf3ce44SJohn Forte struct netbuf svaddr; 150*fcf3ce44SJohn Forte struct netbuf *svp; 151*fcf3ce44SJohn Forte struct netconfig nconf; 152*fcf3ce44SJohn Forte struct netconfig *conf; 153*fcf3ce44SJohn Forte struct knetconfig knconf; 154*fcf3ce44SJohn Forte 155*fcf3ce44SJohn Forte static char *reconfig_pbitmap = NULL; 156*fcf3ce44SJohn Forte static char *reconfig_sbitmap = NULL; 157*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 158*fcf3ce44SJohn Forte static char *reconfig_direct = NULL; 159*fcf3ce44SJohn Forte #endif 160*fcf3ce44SJohn Forte static char *reconfig_group = NULL; 161*fcf3ce44SJohn Forte static char reconfig_ctag[MAX_RDC_HOST_SIZE]; 162*fcf3ce44SJohn Forte static int reconfig_doasync = -1; 163*fcf3ce44SJohn Forte 164*fcf3ce44SJohn Forte static int clustered = 0; 165*fcf3ce44SJohn Forte static int proto_test = 0; 166*fcf3ce44SJohn Forte int allow_role = 0; 167*fcf3ce44SJohn Forte 168*fcf3ce44SJohn Forte 169*fcf3ce44SJohn Forte static char * 170*fcf3ce44SJohn Forte rdc_print_state(rdc_set_t *urdc) 171*fcf3ce44SJohn Forte { 172*fcf3ce44SJohn Forte if (!urdc) 173*fcf3ce44SJohn Forte return (""); 174*fcf3ce44SJohn Forte 175*fcf3ce44SJohn Forte if (urdc->sync_flags & RDC_VOL_FAILED) 176*fcf3ce44SJohn Forte return (gettext("volume failed")); 177*fcf3ce44SJohn Forte else if (urdc->sync_flags & RDC_FCAL_FAILED) 178*fcf3ce44SJohn Forte return (gettext("fcal failed")); 179*fcf3ce44SJohn Forte else if (urdc->bmap_flags & RDC_BMP_FAILED) 180*fcf3ce44SJohn Forte return (gettext("bitmap failed")); 181*fcf3ce44SJohn Forte else if (urdc->flags & RDC_DISKQ_FAILED) 182*fcf3ce44SJohn Forte return (gettext("disk queue failed")); 183*fcf3ce44SJohn Forte else if (urdc->flags & RDC_LOGGING) { 184*fcf3ce44SJohn Forte if (urdc->sync_flags & RDC_SYNC_NEEDED) 185*fcf3ce44SJohn Forte return (gettext("need sync")); 186*fcf3ce44SJohn Forte else if (urdc->sync_flags & RDC_RSYNC_NEEDED) 187*fcf3ce44SJohn Forte return (gettext("need reverse sync")); 188*fcf3ce44SJohn Forte else if (urdc->flags & RDC_QUEUING) 189*fcf3ce44SJohn Forte return (gettext("queuing")); 190*fcf3ce44SJohn Forte else 191*fcf3ce44SJohn Forte return (gettext("logging")); 192*fcf3ce44SJohn Forte } else if ((urdc->flags & RDC_SLAVE) && (urdc->flags & RDC_SYNCING)) { 193*fcf3ce44SJohn Forte if (urdc->flags & RDC_PRIMARY) 194*fcf3ce44SJohn Forte return (gettext("reverse syncing")); 195*fcf3ce44SJohn Forte else 196*fcf3ce44SJohn Forte return (gettext("syncing")); 197*fcf3ce44SJohn Forte } else if (urdc->flags & RDC_SYNCING) { 198*fcf3ce44SJohn Forte if (urdc->flags & RDC_PRIMARY) 199*fcf3ce44SJohn Forte return (gettext("syncing")); 200*fcf3ce44SJohn Forte else 201*fcf3ce44SJohn Forte return (gettext("reverse syncing")); 202*fcf3ce44SJohn Forte } 203*fcf3ce44SJohn Forte 204*fcf3ce44SJohn Forte return (gettext("replicating")); 205*fcf3ce44SJohn Forte } 206*fcf3ce44SJohn Forte 207*fcf3ce44SJohn Forte 208*fcf3ce44SJohn Forte static int 209*fcf3ce44SJohn Forte rdc_print(int file_format, int verbose, char *group_arg, char *ctag_arg, 210*fcf3ce44SJohn Forte char *user_shost, char *user_sdev, CFGFILE *cfgp) 211*fcf3ce44SJohn Forte { 212*fcf3ce44SJohn Forte rdc_status_t *rdc_status; 213*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 214*fcf3ce44SJohn Forte rdc_set_t *urdc; 215*fcf3ce44SJohn Forte size_t size; 216*fcf3ce44SJohn Forte int i, rc, max; 217*fcf3ce44SJohn Forte char *tohost, *tofile; 218*fcf3ce44SJohn Forte _sd_dual_pair_t pair; 219*fcf3ce44SJohn Forte char *tmptohost = pair.thost; 220*fcf3ce44SJohn Forte char *tmptofile = pair.tfile; 221*fcf3ce44SJohn Forte char *fromhost = pair.fhost; 222*fcf3ce44SJohn Forte char *fromfile = pair.ffile; 223*fcf3ce44SJohn Forte char *frombitmap = pair.fbitmap; 224*fcf3ce44SJohn Forte char *tobitmap = pair.tbitmap; 225*fcf3ce44SJohn Forte char *directfile = pair.directfile; 226*fcf3ce44SJohn Forte char *group = pair.group; 227*fcf3ce44SJohn Forte char *diskqueue = pair.diskqueue; 228*fcf3ce44SJohn Forte char *ctag = pair.ctag; 229*fcf3ce44SJohn Forte CFGFILE *cfg; 230*fcf3ce44SJohn Forte int j; 231*fcf3ce44SJohn Forte int setnumber; 232*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 233*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 234*fcf3ce44SJohn Forte char sync[16]; 235*fcf3ce44SJohn Forte int match, found; 236*fcf3ce44SJohn Forte 237*fcf3ce44SJohn Forte size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1)); 238*fcf3ce44SJohn Forte match = (user_shost != NULL || user_sdev != NULL); 239*fcf3ce44SJohn Forte found = 0; 240*fcf3ce44SJohn Forte 241*fcf3ce44SJohn Forte if (user_shost == NULL && user_sdev != NULL) 242*fcf3ce44SJohn Forte user_shost = ""; 243*fcf3ce44SJohn Forte else if (user_shost != NULL && user_sdev == NULL) 244*fcf3ce44SJohn Forte user_sdev = ""; 245*fcf3ce44SJohn Forte 246*fcf3ce44SJohn Forte rdc_status = malloc(size); 247*fcf3ce44SJohn Forte if (!rdc_status) { 248*fcf3ce44SJohn Forte rdc_err(NULL, 249*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 250*fcf3ce44SJohn Forte } 251*fcf3ce44SJohn Forte 252*fcf3ce44SJohn Forte rdc_status->nset = rdc_maxsets; 253*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 254*fcf3ce44SJohn Forte 255*fcf3ce44SJohn Forte rc = RDC_IOCTL(RDC_STATUS, rdc_status, 0, 0, 0, 0, ustatus); 256*fcf3ce44SJohn Forte if (rc == SPCS_S_ERROR) { 257*fcf3ce44SJohn Forte rdc_err(&ustatus, gettext("statistics error")); 258*fcf3ce44SJohn Forte } 259*fcf3ce44SJohn Forte 260*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 261*fcf3ce44SJohn Forte 262*fcf3ce44SJohn Forte max = min(rdc_status->nset, rdc_maxsets); 263*fcf3ce44SJohn Forte 264*fcf3ce44SJohn Forte if (cfgp != NULL) { 265*fcf3ce44SJohn Forte cfg = cfgp; 266*fcf3ce44SJohn Forte cfg_rewind(cfg, CFG_SEC_CONF); 267*fcf3ce44SJohn Forte } else { 268*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 269*fcf3ce44SJohn Forte rdc_err(NULL, 270*fcf3ce44SJohn Forte gettext("unable to access configuration")); 271*fcf3ce44SJohn Forte 272*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 273*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 274*fcf3ce44SJohn Forte } 275*fcf3ce44SJohn Forte 276*fcf3ce44SJohn Forte for (i = 0; i < max; i++) { 277*fcf3ce44SJohn Forte urdc = &rdc_status->rdc_set[i]; 278*fcf3ce44SJohn Forte 279*fcf3ce44SJohn Forte if (!(urdc->flags & RDC_ENABLED)) 280*fcf3ce44SJohn Forte continue; 281*fcf3ce44SJohn Forte 282*fcf3ce44SJohn Forte if (match && 283*fcf3ce44SJohn Forte (strcmp(user_shost, urdc->secondary.intf) != 0 || 284*fcf3ce44SJohn Forte strcmp(user_sdev, urdc->secondary.file) != 0)) 285*fcf3ce44SJohn Forte continue; 286*fcf3ce44SJohn Forte 287*fcf3ce44SJohn Forte tohost = urdc->secondary.intf; 288*fcf3ce44SJohn Forte tofile = urdc->secondary.file; 289*fcf3ce44SJohn Forte found = 1; 290*fcf3ce44SJohn Forte 291*fcf3ce44SJohn Forte /* get sndr entries until shost, sfile match */ 292*fcf3ce44SJohn Forte for (j = 0; j < rdc_maxsets; j++) { 293*fcf3ce44SJohn Forte setnumber = j + 1; 294*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 295*fcf3ce44SJohn Forte "sndr.set%d", setnumber); 296*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 297*fcf3ce44SJohn Forte break; 298*fcf3ce44SJohn Forte } 299*fcf3ce44SJohn Forte 300*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &pair, NULL)) 301*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cfg input error")); 302*fcf3ce44SJohn Forte 303*fcf3ce44SJohn Forte if (strcmp(tmptofile, tofile) != 0) 304*fcf3ce44SJohn Forte continue; 305*fcf3ce44SJohn Forte if (strcmp(tmptohost, tohost) != 0) 306*fcf3ce44SJohn Forte continue; 307*fcf3ce44SJohn Forte 308*fcf3ce44SJohn Forte if (pair.doasync == 0) 309*fcf3ce44SJohn Forte strcpy(sync, "sync"); 310*fcf3ce44SJohn Forte else 311*fcf3ce44SJohn Forte strcpy(sync, "async"); 312*fcf3ce44SJohn Forte 313*fcf3ce44SJohn Forte /* Got the matching entry */ 314*fcf3ce44SJohn Forte 315*fcf3ce44SJohn Forte break; 316*fcf3ce44SJohn Forte } 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte if (j == rdc_maxsets) 319*fcf3ce44SJohn Forte continue; /* not found in config */ 320*fcf3ce44SJohn Forte 321*fcf3ce44SJohn Forte if (strcmp(group_arg, "") != 0 && 322*fcf3ce44SJohn Forte strncmp(group_arg, group, NSC_MAXPATH) != 0) 323*fcf3ce44SJohn Forte continue; 324*fcf3ce44SJohn Forte 325*fcf3ce44SJohn Forte if (strcmp(ctag_arg, "") != 0 && 326*fcf3ce44SJohn Forte strncmp(ctag_arg, ctag, MAX_RDC_HOST_SIZE) != 0) 327*fcf3ce44SJohn Forte continue; 328*fcf3ce44SJohn Forte 329*fcf3ce44SJohn Forte if (file_format) { 330*fcf3ce44SJohn Forte (void) printf("%s %s %s %s %s %s %s %s", 331*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 332*fcf3ce44SJohn Forte tohost, tofile, tobitmap, 333*fcf3ce44SJohn Forte directfile, sync); 334*fcf3ce44SJohn Forte if (strlen(group) != 0) 335*fcf3ce44SJohn Forte (void) printf(" g %s", group); 336*fcf3ce44SJohn Forte if ((strlen(ctag) != 0) && (ctag[0] != '-')) 337*fcf3ce44SJohn Forte (void) printf(" C %s", ctag); 338*fcf3ce44SJohn Forte if (strlen(diskqueue) != 0) 339*fcf3ce44SJohn Forte (void) printf(" q %s", diskqueue); 340*fcf3ce44SJohn Forte (void) printf("\n"); 341*fcf3ce44SJohn Forte continue; 342*fcf3ce44SJohn Forte } 343*fcf3ce44SJohn Forte 344*fcf3ce44SJohn Forte if (strcmp(group_arg, "") != 0 && 345*fcf3ce44SJohn Forte strncmp(group_arg, urdc->group_name, NSC_MAXPATH) != 0) 346*fcf3ce44SJohn Forte continue; 347*fcf3ce44SJohn Forte 348*fcf3ce44SJohn Forte if (!(urdc->flags & RDC_PRIMARY)) { 349*fcf3ce44SJohn Forte (void) printf(gettext("%s\t<-\t%s:%s\n"), 350*fcf3ce44SJohn Forte urdc->secondary.file, urdc->primary.intf, 351*fcf3ce44SJohn Forte urdc->primary.file); 352*fcf3ce44SJohn Forte } else { 353*fcf3ce44SJohn Forte (void) printf(gettext("%s\t->\t%s:%s\n"), 354*fcf3ce44SJohn Forte urdc->primary.file, urdc->secondary.intf, 355*fcf3ce44SJohn Forte urdc->secondary.file); 356*fcf3ce44SJohn Forte } 357*fcf3ce44SJohn Forte if (!verbose) 358*fcf3ce44SJohn Forte continue; 359*fcf3ce44SJohn Forte 360*fcf3ce44SJohn Forte if (urdc->autosync) 361*fcf3ce44SJohn Forte (void) printf(gettext("autosync: on")); 362*fcf3ce44SJohn Forte else 363*fcf3ce44SJohn Forte (void) printf(gettext("autosync: off")); 364*fcf3ce44SJohn Forte 365*fcf3ce44SJohn Forte (void) printf(gettext(", max q writes: %lld"), urdc->maxqitems); 366*fcf3ce44SJohn Forte (void) printf(gettext(", max q fbas: %lld"), urdc->maxqfbas); 367*fcf3ce44SJohn Forte (void) printf(gettext(", async threads: %d"), 368*fcf3ce44SJohn Forte urdc->asyncthr); 369*fcf3ce44SJohn Forte (void) printf(gettext(", mode: %s"), 370*fcf3ce44SJohn Forte pair.doasync ? "async" : "sync"); 371*fcf3ce44SJohn Forte 372*fcf3ce44SJohn Forte if (strlen(urdc->group_name) != 0) 373*fcf3ce44SJohn Forte (void) printf(gettext(", group: %s"), urdc->group_name); 374*fcf3ce44SJohn Forte if ((strlen(ctag) != 0) && (ctag[0] != '-')) 375*fcf3ce44SJohn Forte (void) printf(gettext(", ctag: %s"), ctag); 376*fcf3ce44SJohn Forte if (strlen(urdc->disk_queue) != 0) { 377*fcf3ce44SJohn Forte (void) printf(gettext(", %s diskqueue: %s"), 378*fcf3ce44SJohn Forte (urdc->flags & RDC_QNOBLOCK) ? gettext("non blocking") : 379*fcf3ce44SJohn Forte gettext("blocking"), urdc->disk_queue); 380*fcf3ce44SJohn Forte } 381*fcf3ce44SJohn Forte 382*fcf3ce44SJohn Forte (void) printf(gettext(", state: %s"), rdc_print_state(urdc)); 383*fcf3ce44SJohn Forte (void) printf(gettext("\n")); 384*fcf3ce44SJohn Forte 385*fcf3ce44SJohn Forte } 386*fcf3ce44SJohn Forte 387*fcf3ce44SJohn Forte if (!cfgp) 388*fcf3ce44SJohn Forte cfg_close(cfg); 389*fcf3ce44SJohn Forte 390*fcf3ce44SJohn Forte free(rdc_status); 391*fcf3ce44SJohn Forte 392*fcf3ce44SJohn Forte if (match && !found) { 393*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("unable to find set %s:%s"), 394*fcf3ce44SJohn Forte user_shost, user_sdev); 395*fcf3ce44SJohn Forte } 396*fcf3ce44SJohn Forte 397*fcf3ce44SJohn Forte return (0); 398*fcf3ce44SJohn Forte } 399*fcf3ce44SJohn Forte 400*fcf3ce44SJohn Forte 401*fcf3ce44SJohn Forte int 402*fcf3ce44SJohn Forte parse_extras(int argc, char *args[], int i) 403*fcf3ce44SJohn Forte { 404*fcf3ce44SJohn Forte int gflag = 0; 405*fcf3ce44SJohn Forte int Cflag = 0; 406*fcf3ce44SJohn Forte int qflag = 0; 407*fcf3ce44SJohn Forte int j; 408*fcf3ce44SJohn Forte 409*fcf3ce44SJohn Forte strcpy(pair_list[i].ctag, ""); 410*fcf3ce44SJohn Forte strcpy(pair_list[i].group, ""); 411*fcf3ce44SJohn Forte strcpy(pair_list[i].diskqueue, ""); 412*fcf3ce44SJohn Forte 413*fcf3ce44SJohn Forte if (argc == 0) 414*fcf3ce44SJohn Forte return (0); 415*fcf3ce44SJohn Forte 416*fcf3ce44SJohn Forte if (argc != 2 && argc != 4 && argc != 6) 417*fcf3ce44SJohn Forte return (-1); 418*fcf3ce44SJohn Forte 419*fcf3ce44SJohn Forte for (j = 0; j < argc; j += 2) { 420*fcf3ce44SJohn Forte if (strcmp(args[j], "g") == 0) { 421*fcf3ce44SJohn Forte if (gflag) 422*fcf3ce44SJohn Forte return (-1); 423*fcf3ce44SJohn Forte strncpy(pair_list[i].group, args[j + 1], NSC_MAXPATH); 424*fcf3ce44SJohn Forte gflag = 1; 425*fcf3ce44SJohn Forte } 426*fcf3ce44SJohn Forte if (strcmp(args[j], "C") == 0) { 427*fcf3ce44SJohn Forte if (!clustered) 428*fcf3ce44SJohn Forte return (-1); 429*fcf3ce44SJohn Forte if (Cflag) 430*fcf3ce44SJohn Forte return (-1); 431*fcf3ce44SJohn Forte strncpy(pair_list[i].ctag, args[j + 1], 432*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 433*fcf3ce44SJohn Forte process_clocal(pair_list[i].ctag); 434*fcf3ce44SJohn Forte Cflag = 1; 435*fcf3ce44SJohn Forte } 436*fcf3ce44SJohn Forte if (strcmp(args[j], "q") == 0) { 437*fcf3ce44SJohn Forte if (qflag) 438*fcf3ce44SJohn Forte return (-1); 439*fcf3ce44SJohn Forte strncpy(pair_list[i].diskqueue, args[j + 1], 440*fcf3ce44SJohn Forte NSC_MAXPATH); 441*fcf3ce44SJohn Forte qflag = 1; 442*fcf3ce44SJohn Forte } 443*fcf3ce44SJohn Forte } 444*fcf3ce44SJohn Forte 445*fcf3ce44SJohn Forte return (0); 446*fcf3ce44SJohn Forte } 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte static int 449*fcf3ce44SJohn Forte parse_cfg_buf(char *buf, _sd_dual_pair_t *pair, char *lghn) 450*fcf3ce44SJohn Forte { 451*fcf3ce44SJohn Forte int rc = 0; 452*fcf3ce44SJohn Forte char sync[16]; 453*fcf3ce44SJohn Forte char options[64], *p, *q; 454*fcf3ce44SJohn Forte int len; 455*fcf3ce44SJohn Forte 456*fcf3ce44SJohn Forte rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s", pair->fhost, 457*fcf3ce44SJohn Forte pair->ffile, pair->fbitmap, pair->thost, pair->tfile, 458*fcf3ce44SJohn Forte pair->tbitmap, pair->directfile, sync, pair->group, 459*fcf3ce44SJohn Forte pair->ctag, options, pair->diskqueue); 460*fcf3ce44SJohn Forte 461*fcf3ce44SJohn Forte if (rc != 12) 462*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cfg input error")); 463*fcf3ce44SJohn Forte 464*fcf3ce44SJohn Forte if (strcmp(pair->diskqueue, place_holder) == 0) 465*fcf3ce44SJohn Forte strcpy(pair->diskqueue, ""); 466*fcf3ce44SJohn Forte 467*fcf3ce44SJohn Forte if (strcmp(pair->group, place_holder) == 0) 468*fcf3ce44SJohn Forte strcpy(pair->group, ""); 469*fcf3ce44SJohn Forte 470*fcf3ce44SJohn Forte if (strcmp(sync, "sync") == 0) 471*fcf3ce44SJohn Forte pair->doasync = 0; 472*fcf3ce44SJohn Forte else if (strcmp(sync, "async") == 0) 473*fcf3ce44SJohn Forte pair->doasync = 1; 474*fcf3ce44SJohn Forte else { 475*fcf3ce44SJohn Forte rdc_err(NULL, 476*fcf3ce44SJohn Forte gettext("set %s:%s neither sync nor async"), 477*fcf3ce44SJohn Forte pair->thost, pair->tfile); 478*fcf3ce44SJohn Forte } 479*fcf3ce44SJohn Forte 480*fcf3ce44SJohn Forte if (lghn && (p = strstr(options, "lghn="))) { 481*fcf3ce44SJohn Forte p += 5; 482*fcf3ce44SJohn Forte q = strchr(p, ';'); 483*fcf3ce44SJohn Forte if (q) { 484*fcf3ce44SJohn Forte /* LINTED p & q limited to options[64] */ 485*fcf3ce44SJohn Forte len = q - p; 486*fcf3ce44SJohn Forte } else { 487*fcf3ce44SJohn Forte len = strlen(p); 488*fcf3ce44SJohn Forte } 489*fcf3ce44SJohn Forte strncpy(lghn, p, len); 490*fcf3ce44SJohn Forte lghn[len] = '\0'; 491*fcf3ce44SJohn Forte } else if (lghn) { 492*fcf3ce44SJohn Forte *lghn = '\0'; 493*fcf3ce44SJohn Forte } 494*fcf3ce44SJohn Forte 495*fcf3ce44SJohn Forte return (0); 496*fcf3ce44SJohn Forte } 497*fcf3ce44SJohn Forte 498*fcf3ce44SJohn Forte static int 499*fcf3ce44SJohn Forte ctag_check(char *fromhost, char *fromfile, char *frombitmap, char *tohost, 500*fcf3ce44SJohn Forte char *tofile, char *tobitmap, char *ctag, char *diskq) 501*fcf3ce44SJohn Forte { 502*fcf3ce44SJohn Forte char *file_dgname; 503*fcf3ce44SJohn Forte char *bmp_dgname; 504*fcf3ce44SJohn Forte char *que_dgname; 505*fcf3ce44SJohn Forte char *localfile; 506*fcf3ce44SJohn Forte char file_buf[MAX_RDC_HOST_SIZE]; 507*fcf3ce44SJohn Forte char bmp_buf[MAX_RDC_HOST_SIZE]; 508*fcf3ce44SJohn Forte char que_buf[NSC_MAXPATH]; 509*fcf3ce44SJohn Forte int is_primary; 510*fcf3ce44SJohn Forte struct hostent *hp; 511*fcf3ce44SJohn Forte char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN]; 512*fcf3ce44SJohn Forte 513*fcf3ce44SJohn Forte if (!clustered) 514*fcf3ce44SJohn Forte return (0); 515*fcf3ce44SJohn Forte 516*fcf3ce44SJohn Forte hp = gethost_byname(fromhost); 517*fcf3ce44SJohn Forte strncpy(fromname, hp->h_name, MAXHOSTNAMELEN); 518*fcf3ce44SJohn Forte hp = gethost_byname(tohost); 519*fcf3ce44SJohn Forte strncpy(toname, hp->h_name, MAXHOSTNAMELEN); 520*fcf3ce44SJohn Forte if (!self_check(fromname) && !self_check(toname)) { 521*fcf3ce44SJohn Forte /* 522*fcf3ce44SJohn Forte * If we could get a list of logical hosts on this cluster 523*fcf3ce44SJohn Forte * then we could print something intelligent about where 524*fcf3ce44SJohn Forte * the volume is mastered. For now, just print some babble 525*fcf3ce44SJohn Forte * about the fact that we have no idea. 526*fcf3ce44SJohn Forte */ 527*fcf3ce44SJohn Forte rdc_err(NULL, 528*fcf3ce44SJohn Forte gettext("either %s:%s or %s:%s is not local"), 529*fcf3ce44SJohn Forte fromhost, fromfile, tohost, tofile); 530*fcf3ce44SJohn Forte } 531*fcf3ce44SJohn Forte 532*fcf3ce44SJohn Forte is_primary = self_check(fromname); 533*fcf3ce44SJohn Forte 534*fcf3ce44SJohn Forte /* 535*fcf3ce44SJohn Forte * If implicit disk group name and no ctag specified by user, 536*fcf3ce44SJohn Forte * we set the ctag to it. 537*fcf3ce44SJohn Forte * If implicit disk group name, it must match any supplied ctag. 538*fcf3ce44SJohn Forte */ 539*fcf3ce44SJohn Forte localfile = is_primary ? fromfile : tofile; 540*fcf3ce44SJohn Forte file_dgname = cfg_dgname(localfile, file_buf, sizeof (file_buf)); 541*fcf3ce44SJohn Forte if (file_dgname && strlen(file_dgname)) 542*fcf3ce44SJohn Forte rdc_check_dgislocal(file_dgname); 543*fcf3ce44SJohn Forte 544*fcf3ce44SJohn Forte /* 545*fcf3ce44SJohn Forte * Autogenerate a ctag, if not "-C local" or no "-C " specified 546*fcf3ce44SJohn Forte */ 547*fcf3ce44SJohn Forte if (!rdc_islocal && !strlen(ctag) && file_dgname && strlen(file_dgname)) 548*fcf3ce44SJohn Forte strncpy(ctag, file_dgname, MAX_RDC_HOST_SIZE); 549*fcf3ce44SJohn Forte 550*fcf3ce44SJohn Forte /* 551*fcf3ce44SJohn Forte * making an exception here for users giving the "local"tag 552*fcf3ce44SJohn Forte * this overrides this error message. (rdc_islocal ! = 1) 553*fcf3ce44SJohn Forte */ 554*fcf3ce44SJohn Forte if (!rdc_islocal && strlen(ctag) && 555*fcf3ce44SJohn Forte file_dgname && strlen(file_dgname) && 556*fcf3ce44SJohn Forte strncmp(ctag, file_dgname, MAX_RDC_HOST_SIZE)) { 557*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("ctag \"%s\" does not " 558*fcf3ce44SJohn Forte "match disk group name \"%s\" of volume %s"), ctag, 559*fcf3ce44SJohn Forte file_dgname, localfile); 560*fcf3ce44SJohn Forte return (-1); 561*fcf3ce44SJohn Forte } 562*fcf3ce44SJohn Forte 563*fcf3ce44SJohn Forte /* 564*fcf3ce44SJohn Forte * Do we have a non-volume managed disk without -C local specified? 565*fcf3ce44SJohn Forte */ 566*fcf3ce44SJohn Forte if (!rdc_islocal && (!file_dgname || !strlen(file_dgname))) { 567*fcf3ce44SJohn Forte rdc_err(NULL, gettext("volume \"%s\" is not part" 568*fcf3ce44SJohn Forte " of a disk group,\nplease specify resource ctag\n"), 569*fcf3ce44SJohn Forte localfile); 570*fcf3ce44SJohn Forte } 571*fcf3ce44SJohn Forte 572*fcf3ce44SJohn Forte /* 573*fcf3ce44SJohn Forte * Do we have a volume managed disk with -C local? 574*fcf3ce44SJohn Forte */ 575*fcf3ce44SJohn Forte if (rdc_islocal && file_dgname && (strlen(file_dgname) > 0)) { 576*fcf3ce44SJohn Forte rdc_err(NULL, gettext( 577*fcf3ce44SJohn Forte "volume \"%s\" is part of a disk group\n"), localfile); 578*fcf3ce44SJohn Forte } 579*fcf3ce44SJohn Forte 580*fcf3ce44SJohn Forte /* 581*fcf3ce44SJohn Forte * Local bitmap must also have same ctag. 582*fcf3ce44SJohn Forte */ 583*fcf3ce44SJohn Forte localfile = is_primary ? frombitmap : tobitmap; 584*fcf3ce44SJohn Forte bmp_dgname = cfg_dgname(localfile, bmp_buf, sizeof (bmp_buf)); 585*fcf3ce44SJohn Forte if (bmp_dgname && strlen(bmp_dgname)) 586*fcf3ce44SJohn Forte rdc_check_dgislocal(bmp_dgname); 587*fcf3ce44SJohn Forte 588*fcf3ce44SJohn Forte /* 589*fcf3ce44SJohn Forte * Assure that if the primary has a device group, so must the bitmap 590*fcf3ce44SJohn Forte */ 591*fcf3ce44SJohn Forte if ((file_dgname && strlen(file_dgname)) && 592*fcf3ce44SJohn Forte (!bmp_dgname || !strlen(bmp_dgname))) { 593*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("bitmap %s is not in disk group \"%s\""), 594*fcf3ce44SJohn Forte localfile, rdc_islocal < 1?file_dgname:ctag); 595*fcf3ce44SJohn Forte return (-1); 596*fcf3ce44SJohn Forte } 597*fcf3ce44SJohn Forte 598*fcf3ce44SJohn Forte /* 599*fcf3ce44SJohn Forte * Assure that if the if there is a ctag, it must match the bitmap 600*fcf3ce44SJohn Forte */ 601*fcf3ce44SJohn Forte if (!rdc_islocal && strlen(ctag) && 602*fcf3ce44SJohn Forte bmp_dgname && strlen(bmp_dgname) && 603*fcf3ce44SJohn Forte strncmp(ctag, bmp_dgname, MAX_RDC_HOST_SIZE)) { 604*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("ctag \"%s\" does not " 605*fcf3ce44SJohn Forte "match disk group name \"%s\" of bitmap %s"), ctag, 606*fcf3ce44SJohn Forte bmp_dgname, localfile); 607*fcf3ce44SJohn Forte return (-1); 608*fcf3ce44SJohn Forte } 609*fcf3ce44SJohn Forte 610*fcf3ce44SJohn Forte /* 611*fcf3ce44SJohn Forte * If this is the SNDR primary and there is a local disk queue 612*fcf3ce44SJohn Forte */ 613*fcf3ce44SJohn Forte if (is_primary && diskq[0]) { 614*fcf3ce44SJohn Forte 615*fcf3ce44SJohn Forte /* 616*fcf3ce44SJohn Forte * Local disk queue must also have same ctag. 617*fcf3ce44SJohn Forte */ 618*fcf3ce44SJohn Forte que_dgname = cfg_dgname(diskq, que_buf, sizeof (que_buf)); 619*fcf3ce44SJohn Forte if (que_dgname && strlen(que_dgname)) 620*fcf3ce44SJohn Forte rdc_check_dgislocal(que_dgname); 621*fcf3ce44SJohn Forte 622*fcf3ce44SJohn Forte /* 623*fcf3ce44SJohn Forte * Assure that if the primary has a device group, so must 624*fcf3ce44SJohn Forte * the disk queue 625*fcf3ce44SJohn Forte */ 626*fcf3ce44SJohn Forte if ((file_dgname && strlen(file_dgname)) && 627*fcf3ce44SJohn Forte (!que_dgname || !strlen(que_dgname))) { 628*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("disk queue %s is not in disk " 629*fcf3ce44SJohn Forte "group \"%s\""), diskq, 630*fcf3ce44SJohn Forte rdc_islocal < 1?file_dgname:ctag); 631*fcf3ce44SJohn Forte return (-1); 632*fcf3ce44SJohn Forte } 633*fcf3ce44SJohn Forte 634*fcf3ce44SJohn Forte /* 635*fcf3ce44SJohn Forte * Assure that if the if there is a ctag, it must match 636*fcf3ce44SJohn Forte * the disk queue 637*fcf3ce44SJohn Forte */ 638*fcf3ce44SJohn Forte if (!rdc_islocal && strlen(ctag) && 639*fcf3ce44SJohn Forte que_dgname && strlen(que_dgname) && 640*fcf3ce44SJohn Forte strncmp(ctag, que_dgname, MAX_RDC_HOST_SIZE)) { 641*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("ctag \"%s\" does not " 642*fcf3ce44SJohn Forte "match disk group name \"%s\" of disk queue %s"), 643*fcf3ce44SJohn Forte ctag, que_dgname, diskq); 644*fcf3ce44SJohn Forte return (-1); 645*fcf3ce44SJohn Forte } 646*fcf3ce44SJohn Forte } 647*fcf3ce44SJohn Forte 648*fcf3ce44SJohn Forte return (0); 649*fcf3ce44SJohn Forte } 650*fcf3ce44SJohn Forte 651*fcf3ce44SJohn Forte #define DISKQ_OKAY 0 652*fcf3ce44SJohn Forte #define DISKQ_FAIL 1 653*fcf3ce44SJohn Forte #define DISKQ_REWRITEG 2 654*fcf3ce44SJohn Forte /* 655*fcf3ce44SJohn Forte * check that newq is compatable with the groups current disk queue. 656*fcf3ce44SJohn Forte * Newq is incompatable if it is set and the groups queue is set and the queues 657*fcf3ce44SJohn Forte * are different. 658*fcf3ce44SJohn Forte * 659*fcf3ce44SJohn Forte * if newq is not set but should be, it will be set to the correct value. 660*fcf3ce44SJohn Forte * returns: 661*fcf3ce44SJohn Forte * DISK_REWRITEG entire group needs to take new value of disk_queue 662*fcf3ce44SJohn Forte * DISKQ_OKAY newq contains a value that matches the group. 663*fcf3ce44SJohn Forte * DISKQ_FAIL disk queues are incompatible. 664*fcf3ce44SJohn Forte */ 665*fcf3ce44SJohn Forte static int 666*fcf3ce44SJohn Forte check_diskqueue(CFGFILE *cfg, char *newq, char *newgroup) 667*fcf3ce44SJohn Forte { 668*fcf3ce44SJohn Forte int i, setnumber; 669*fcf3ce44SJohn Forte _sd_dual_pair_t pair; 670*fcf3ce44SJohn Forte char *group = pair.group; 671*fcf3ce44SJohn Forte char *diskqueue = pair.diskqueue; 672*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 673*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 674*fcf3ce44SJohn Forte int open_cfg = cfg == NULL ? 1 : 0; 675*fcf3ce44SJohn Forte 676*fcf3ce44SJohn Forte 677*fcf3ce44SJohn Forte if (newgroup == NULL || *newgroup == '\0') { 678*fcf3ce44SJohn Forte if (*newq == '\0') 679*fcf3ce44SJohn Forte return (DISKQ_OKAY); /* okay, */ 680*fcf3ce44SJohn Forte newgroup = "--nomatch--"; 681*fcf3ce44SJohn Forte } 682*fcf3ce44SJohn Forte 683*fcf3ce44SJohn Forte if (open_cfg) { 684*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 685*fcf3ce44SJohn Forte rdc_err(NULL, 686*fcf3ce44SJohn Forte gettext("unable to access configuration")); 687*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 688*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 689*fcf3ce44SJohn Forte } 690*fcf3ce44SJohn Forte 691*fcf3ce44SJohn Forte /*CSTYLED*/ 692*fcf3ce44SJohn Forte for (i = 0; ; i++) { 693*fcf3ce44SJohn Forte setnumber = i + 1; 694*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); 695*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 696*fcf3ce44SJohn Forte break; 697*fcf3ce44SJohn Forte /* 698*fcf3ce44SJohn Forte * I think this is quicker than 699*fcf3ce44SJohn Forte * having to double dip into the config 700*fcf3ce44SJohn Forte */ 701*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &pair, NULL)) 702*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cfg input error")); 703*fcf3ce44SJohn Forte 704*fcf3ce44SJohn Forte if (strncmp(group, newgroup, NSC_MAXPATH) != 0) { 705*fcf3ce44SJohn Forte if (((strncmp(diskqueue, newq, NSC_MAXPATH) == 0)) && 706*fcf3ce44SJohn Forte (diskqueue[0] != '\0')) { 707*fcf3ce44SJohn Forte if (open_cfg) 708*fcf3ce44SJohn Forte cfg_close(cfg); 709*fcf3ce44SJohn Forte return (DISKQ_FAIL); 710*fcf3ce44SJohn Forte } 711*fcf3ce44SJohn Forte continue; 712*fcf3ce44SJohn Forte } 713*fcf3ce44SJohn Forte if (*newq == '\0') { 714*fcf3ce44SJohn Forte if (diskqueue[0] != '\0') 715*fcf3ce44SJohn Forte strncpy(newq, diskqueue, NSC_MAXPATH); 716*fcf3ce44SJohn Forte if (open_cfg) 717*fcf3ce44SJohn Forte cfg_close(cfg); 718*fcf3ce44SJohn Forte return (DISKQ_OKAY); /* okay, */ 719*fcf3ce44SJohn Forte } 720*fcf3ce44SJohn Forte 721*fcf3ce44SJohn Forte if (open_cfg) 722*fcf3ce44SJohn Forte cfg_close(cfg); 723*fcf3ce44SJohn Forte if (diskqueue[0] == '\0') /* no queue here */ 724*fcf3ce44SJohn Forte return (DISKQ_REWRITEG); 725*fcf3ce44SJohn Forte return (strncmp(diskqueue, newq, NSC_MAXPATH) 726*fcf3ce44SJohn Forte == 0 ? DISKQ_OKAY : DISKQ_FAIL); 727*fcf3ce44SJohn Forte } 728*fcf3ce44SJohn Forte if (open_cfg) 729*fcf3ce44SJohn Forte cfg_close(cfg); 730*fcf3ce44SJohn Forte return (DISKQ_OKAY); 731*fcf3ce44SJohn Forte } 732*fcf3ce44SJohn Forte 733*fcf3ce44SJohn Forte 734*fcf3ce44SJohn Forte int 735*fcf3ce44SJohn Forte pair_diskqueue_check(int newpair) 736*fcf3ce44SJohn Forte { 737*fcf3ce44SJohn Forte int i, j; 738*fcf3ce44SJohn Forte int rc; 739*fcf3ce44SJohn Forte 740*fcf3ce44SJohn Forte for (i = 0; i < newpair; i++) { 741*fcf3ce44SJohn Forte if (strcmp(pair_list[i].group, pair_list[newpair].group) != 0) 742*fcf3ce44SJohn Forte continue; 743*fcf3ce44SJohn Forte if (strcmp(pair_list[i].diskqueue, pair_list[newpair].diskqueue) 744*fcf3ce44SJohn Forte == 0) 745*fcf3ce44SJohn Forte return (DISKQ_OKAY); /* matches existing group */ 746*fcf3ce44SJohn Forte if ((pair_list[newpair].group[0] != '\0') && 747*fcf3ce44SJohn Forte (pair_list[newpair].diskqueue[0] != '\0') && 748*fcf3ce44SJohn Forte (pair_list[i].diskqueue[0] != '\0')) { 749*fcf3ce44SJohn Forte rdc_warn(NULL, 750*fcf3ce44SJohn Forte gettext("disk queue %s does not match %s " 751*fcf3ce44SJohn Forte "skipping set"), pair_list[newpair].diskqueue, 752*fcf3ce44SJohn Forte pair_list[i].diskqueue); 753*fcf3ce44SJohn Forte return (DISKQ_FAIL); 754*fcf3ce44SJohn Forte } 755*fcf3ce44SJohn Forte 756*fcf3ce44SJohn Forte if ((strcmp(pair_list[newpair].diskqueue, "") == 0) && 757*fcf3ce44SJohn Forte pair_list[newpair].group[0] != '\0') { 758*fcf3ce44SJohn Forte strncpy(pair_list[newpair].diskqueue, 759*fcf3ce44SJohn Forte pair_list[i].diskqueue, NSC_MAXPATH); 760*fcf3ce44SJohn Forte return (DISKQ_OKAY); /* changed to existing group que */ 761*fcf3ce44SJohn Forte } 762*fcf3ce44SJohn Forte if (strcmp(pair_list[i].diskqueue, "") == 0) { 763*fcf3ce44SJohn Forte for (j = 0; j < newpair; j++) { 764*fcf3ce44SJohn Forte if ((pair_list[j].group[0] != '\0') && 765*fcf3ce44SJohn Forte (strncmp(pair_list[j].group, 766*fcf3ce44SJohn Forte pair_list[newpair].group, 767*fcf3ce44SJohn Forte NSC_MAXPATH) == 0)) { 768*fcf3ce44SJohn Forte strncpy(pair_list[j].diskqueue, 769*fcf3ce44SJohn Forte pair_list[newpair].diskqueue, 770*fcf3ce44SJohn Forte NSC_MAXPATH); 771*fcf3ce44SJohn Forte } 772*fcf3ce44SJohn Forte } 773*fcf3ce44SJohn Forte return (DISKQ_OKAY); 774*fcf3ce44SJohn Forte } 775*fcf3ce44SJohn Forte break; /* no problem with pair_list sets */ 776*fcf3ce44SJohn Forte 777*fcf3ce44SJohn Forte } 778*fcf3ce44SJohn Forte 779*fcf3ce44SJohn Forte /* now check with already configured sets */ 780*fcf3ce44SJohn Forte rc = check_diskqueue(NULL, pair_list[newpair].diskqueue, 781*fcf3ce44SJohn Forte pair_list[newpair].group); 782*fcf3ce44SJohn Forte if (rc == DISKQ_REWRITEG) { 783*fcf3ce44SJohn Forte for (i = 0; i < newpair; i++) { 784*fcf3ce44SJohn Forte if (strcmp(pair_list[i].group, 785*fcf3ce44SJohn Forte pair_list[newpair].group) != 0) 786*fcf3ce44SJohn Forte continue; 787*fcf3ce44SJohn Forte 788*fcf3ce44SJohn Forte strncpy(pair_list[i].diskqueue, 789*fcf3ce44SJohn Forte pair_list[newpair].diskqueue, NSC_MAXPATH); 790*fcf3ce44SJohn Forte } 791*fcf3ce44SJohn Forte } 792*fcf3ce44SJohn Forte return (rc); 793*fcf3ce44SJohn Forte } 794*fcf3ce44SJohn Forte 795*fcf3ce44SJohn Forte int 796*fcf3ce44SJohn Forte ii_set_exists(CFGFILE *cfg, char *ma, char *sh, char *bm) 797*fcf3ce44SJohn Forte { 798*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 799*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 800*fcf3ce44SJohn Forte char master[NSC_MAXPATH]; 801*fcf3ce44SJohn Forte char shadow[NSC_MAXPATH]; 802*fcf3ce44SJohn Forte char bitmap[NSC_MAXPATH]; 803*fcf3ce44SJohn Forte int i; 804*fcf3ce44SJohn Forte 805*fcf3ce44SJohn Forte for (i = 1; ; i++) { 806*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ii.set%d", i); 807*fcf3ce44SJohn Forte bzero(&master, sizeof (master)); 808*fcf3ce44SJohn Forte bzero(&shadow, sizeof (shadow)); 809*fcf3ce44SJohn Forte bzero(&bitmap, sizeof (bitmap)); 810*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 811*fcf3ce44SJohn Forte break; 812*fcf3ce44SJohn Forte (void) sscanf(buf, "%s %s %s", master, shadow, bitmap); 813*fcf3ce44SJohn Forte if (strcmp(master, ma) != 0) 814*fcf3ce44SJohn Forte continue; 815*fcf3ce44SJohn Forte if (strcmp(shadow, sh) != 0) 816*fcf3ce44SJohn Forte continue; 817*fcf3ce44SJohn Forte if (strcmp(bitmap, bm) != 0) 818*fcf3ce44SJohn Forte continue; 819*fcf3ce44SJohn Forte return (1); 820*fcf3ce44SJohn Forte } 821*fcf3ce44SJohn Forte return (0); 822*fcf3ce44SJohn Forte } 823*fcf3ce44SJohn Forte 824*fcf3ce44SJohn Forte void 825*fcf3ce44SJohn Forte rdc_ii_config(int argc, char **argv) 826*fcf3ce44SJohn Forte { 827*fcf3ce44SJohn Forte char *master; 828*fcf3ce44SJohn Forte char *shadow; 829*fcf3ce44SJohn Forte char *bitmap; 830*fcf3ce44SJohn Forte char c; 831*fcf3ce44SJohn Forte CFGFILE *cfg; 832*fcf3ce44SJohn Forte int i; 833*fcf3ce44SJohn Forte int setnumber; 834*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 835*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 836*fcf3ce44SJohn Forte int found; 837*fcf3ce44SJohn Forte int sev; 838*fcf3ce44SJohn Forte 839*fcf3ce44SJohn Forte /* Parse the rest of the arguments to see what to do */ 840*fcf3ce44SJohn Forte 841*fcf3ce44SJohn Forte if (argc - optind != 4) { 842*fcf3ce44SJohn Forte usage(); 843*fcf3ce44SJohn Forte exit(1); 844*fcf3ce44SJohn Forte } 845*fcf3ce44SJohn Forte 846*fcf3ce44SJohn Forte c = *argv[optind]; 847*fcf3ce44SJohn Forte switch (c) { 848*fcf3ce44SJohn Forte case 'd': 849*fcf3ce44SJohn Forte /* Delete an ndr_ii entry */ 850*fcf3ce44SJohn Forte 851*fcf3ce44SJohn Forte master = argv[++optind]; 852*fcf3ce44SJohn Forte shadow = argv[++optind]; 853*fcf3ce44SJohn Forte bitmap = argv[++optind]; 854*fcf3ce44SJohn Forte 855*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 856*fcf3ce44SJohn Forte rdc_err(NULL, 857*fcf3ce44SJohn Forte gettext("unable to access configuration")); 858*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) 859*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 860*fcf3ce44SJohn Forte 861*fcf3ce44SJohn Forte found = 0; 862*fcf3ce44SJohn Forte /* get ndr_ii entries until a match is found */ 863*fcf3ce44SJohn Forte /*CSTYLED*/ 864*fcf3ce44SJohn Forte for (i = 0; ; i++) { 865*fcf3ce44SJohn Forte setnumber = i + 1; 866*fcf3ce44SJohn Forte 867*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 868*fcf3ce44SJohn Forte "ndr_ii.set%d.secondary", 869*fcf3ce44SJohn Forte setnumber); 870*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 871*fcf3ce44SJohn Forte break; 872*fcf3ce44SJohn Forte if (strcmp(buf, master) != 0) 873*fcf3ce44SJohn Forte continue; 874*fcf3ce44SJohn Forte 875*fcf3ce44SJohn Forte /* Got a matching entry */ 876*fcf3ce44SJohn Forte 877*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 878*fcf3ce44SJohn Forte "ndr_ii.set%d.shadow", 879*fcf3ce44SJohn Forte setnumber); 880*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 881*fcf3ce44SJohn Forte break; 882*fcf3ce44SJohn Forte if (strcmp(buf, shadow) != 0) 883*fcf3ce44SJohn Forte continue; 884*fcf3ce44SJohn Forte 885*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 886*fcf3ce44SJohn Forte "ndr_ii.set%d.bitmap", 887*fcf3ce44SJohn Forte setnumber); 888*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 889*fcf3ce44SJohn Forte break; 890*fcf3ce44SJohn Forte if (strcmp(buf, bitmap) != 0) 891*fcf3ce44SJohn Forte continue; 892*fcf3ce44SJohn Forte 893*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 894*fcf3ce44SJohn Forte "ndr_ii.set%d", setnumber); 895*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, NULL, 0) < 0) { 896*fcf3ce44SJohn Forte rdc_warn(NULL, 897*fcf3ce44SJohn Forte gettext("unable to remove \"%s\" " 898*fcf3ce44SJohn Forte "from configuration storage: %s"), 899*fcf3ce44SJohn Forte key, cfg_error(&sev)); 900*fcf3ce44SJohn Forte } else { 901*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) 902*fcf3ce44SJohn Forte rdc_err(NULL, 903*fcf3ce44SJohn Forte gettext("ndr_ii set %s %s %s " 904*fcf3ce44SJohn Forte "not deconfigured."), 905*fcf3ce44SJohn Forte master, shadow, bitmap); 906*fcf3ce44SJohn Forte else 907*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 908*fcf3ce44SJohn Forte gettext("ndr_ii set %s %s %s " 909*fcf3ce44SJohn Forte "has been deconfigured."), 910*fcf3ce44SJohn Forte master, shadow, bitmap); 911*fcf3ce44SJohn Forte } 912*fcf3ce44SJohn Forte found = 1; 913*fcf3ce44SJohn Forte break; 914*fcf3ce44SJohn Forte } 915*fcf3ce44SJohn Forte 916*fcf3ce44SJohn Forte if (!found) { 917*fcf3ce44SJohn Forte rdc_err(NULL, 918*fcf3ce44SJohn Forte gettext("did not find matching ndr_ii " 919*fcf3ce44SJohn Forte "entry for %s %s %s"), master, shadow, bitmap); 920*fcf3ce44SJohn Forte } 921*fcf3ce44SJohn Forte 922*fcf3ce44SJohn Forte cfg_close(cfg); 923*fcf3ce44SJohn Forte 924*fcf3ce44SJohn Forte break; 925*fcf3ce44SJohn Forte 926*fcf3ce44SJohn Forte case 'a': 927*fcf3ce44SJohn Forte /* Add an ndr_ii entry */ 928*fcf3ce44SJohn Forte 929*fcf3ce44SJohn Forte master = argv[++optind]; 930*fcf3ce44SJohn Forte shadow = argv[++optind]; 931*fcf3ce44SJohn Forte bitmap = argv[++optind]; 932*fcf3ce44SJohn Forte 933*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 934*fcf3ce44SJohn Forte rdc_err(NULL, 935*fcf3ce44SJohn Forte gettext("unable to access configuration")); 936*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) 937*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 938*fcf3ce44SJohn Forte 939*fcf3ce44SJohn Forte found = 0; 940*fcf3ce44SJohn Forte /* get ndr_ii entries in case a match is found */ 941*fcf3ce44SJohn Forte /*CSTYLED*/ 942*fcf3ce44SJohn Forte for (i = 0; ; i++) { 943*fcf3ce44SJohn Forte setnumber = i + 1; 944*fcf3ce44SJohn Forte 945*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 946*fcf3ce44SJohn Forte "ndr_ii.set%d.secondary", 947*fcf3ce44SJohn Forte setnumber); 948*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 949*fcf3ce44SJohn Forte break; 950*fcf3ce44SJohn Forte if (strcmp(buf, master) == 0) { 951*fcf3ce44SJohn Forte rdc_err(NULL, 952*fcf3ce44SJohn Forte gettext("found matching ndr_ii " 953*fcf3ce44SJohn Forte "entry for %s"), master); 954*fcf3ce44SJohn Forte } 955*fcf3ce44SJohn Forte } 956*fcf3ce44SJohn Forte /* 957*fcf3ce44SJohn Forte * check to see if this is using a sndr bitmap. 958*fcf3ce44SJohn Forte * kind of a courtesy check, as the ii copy would fail anyway 959*fcf3ce44SJohn Forte * excepting the case where they had actually configured 960*fcf3ce44SJohn Forte * ii/sndr that way, in which case they are broken 961*fcf3ce44SJohn Forte * before we get here 962*fcf3ce44SJohn Forte */ 963*fcf3ce44SJohn Forte /*CSTYLED*/ 964*fcf3ce44SJohn Forte for (i = 0; ; i++) { 965*fcf3ce44SJohn Forte setnumber = i + 1; 966*fcf3ce44SJohn Forte 967*fcf3ce44SJohn Forte /* 968*fcf3ce44SJohn Forte * Checking local bitmaps 969*fcf3ce44SJohn Forte */ 970*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.phost", 971*fcf3ce44SJohn Forte setnumber); 972*fcf3ce44SJohn Forte 973*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 974*fcf3ce44SJohn Forte break; 975*fcf3ce44SJohn Forte if (self_check(buf)) { 976*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 977*fcf3ce44SJohn Forte "sndr.set%d.pbitmap", 978*fcf3ce44SJohn Forte setnumber); 979*fcf3ce44SJohn Forte } else { 980*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 981*fcf3ce44SJohn Forte "sndr.set%d.sbitmap", 982*fcf3ce44SJohn Forte setnumber); 983*fcf3ce44SJohn Forte } 984*fcf3ce44SJohn Forte 985*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 986*fcf3ce44SJohn Forte break; 987*fcf3ce44SJohn Forte 988*fcf3ce44SJohn Forte if ((strcmp(buf, bitmap) == 0) || 989*fcf3ce44SJohn Forte (strcmp(buf, master) == 0) || 990*fcf3ce44SJohn Forte (strcmp(buf, shadow) == 0)) { 991*fcf3ce44SJohn Forte rdc_err(NULL, 992*fcf3ce44SJohn Forte gettext("%s is already configured " 993*fcf3ce44SJohn Forte "as a Remote Mirror bitmap"), buf); 994*fcf3ce44SJohn Forte } 995*fcf3ce44SJohn Forte } 996*fcf3ce44SJohn Forte if (!ii_set_exists(cfg, master, shadow, bitmap)) { 997*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Point-in-Time Copy set " 998*fcf3ce44SJohn Forte "%s %s %s is not already configured. Remote " 999*fcf3ce44SJohn Forte "Mirror will attempt to configure this set when " 1000*fcf3ce44SJohn Forte "a sync is issued to it. The results of that " 1001*fcf3ce44SJohn Forte "operation will be in /var/adm/ds.log"), 1002*fcf3ce44SJohn Forte master, shadow, bitmap); 1003*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Point-in-Time Copy set " 1004*fcf3ce44SJohn Forte "%s %s %s is not already configured. Remote " 1005*fcf3ce44SJohn Forte "Mirror will attempt to configure this set when " 1006*fcf3ce44SJohn Forte "a sync is issued to it. The results of that " 1007*fcf3ce44SJohn Forte "operation will be in /var/adm/ds.log"), 1008*fcf3ce44SJohn Forte master, shadow, bitmap); 1009*fcf3ce44SJohn Forte } else { 1010*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("ndr_ii set " 1011*fcf3ce44SJohn Forte "%s %s %s has been configured."), 1012*fcf3ce44SJohn Forte master, shadow, bitmap); 1013*fcf3ce44SJohn Forte } 1014*fcf3ce44SJohn Forte 1015*fcf3ce44SJohn Forte /* 1016*fcf3ce44SJohn Forte * Prior to insertion in ndr_ii entry, if in a Sun Cluster 1017*fcf3ce44SJohn Forte * assure device groups are the same and cluster tag is set 1018*fcf3ce44SJohn Forte */ 1019*fcf3ce44SJohn Forte if (clustered && !rdc_islocal) { 1020*fcf3ce44SJohn Forte char mst_dg[NSC_MAXPATH] = {0}; 1021*fcf3ce44SJohn Forte char shd_dg[NSC_MAXPATH] = {0}; 1022*fcf3ce44SJohn Forte char bmp_dg[NSC_MAXPATH] = {0}; 1023*fcf3ce44SJohn Forte 1024*fcf3ce44SJohn Forte if (!(cfg_dgname(master, mst_dg, sizeof (mst_dg)) && 1025*fcf3ce44SJohn Forte cfg_dgname(shadow, shd_dg, sizeof (shd_dg)) && 1026*fcf3ce44SJohn Forte cfg_dgname(bitmap, bmp_dg, sizeof (bmp_dg)))) 1027*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("ndr_ii: %s %s %s are " 1028*fcf3ce44SJohn Forte "not in a device group"), 1029*fcf3ce44SJohn Forte master, shadow, bitmap); 1030*fcf3ce44SJohn Forte else if (strcmp(mst_dg, bmp_dg) || 1031*fcf3ce44SJohn Forte strcmp(mst_dg, shd_dg)) 1032*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("ndr_ii: %s %s %s are " 1033*fcf3ce44SJohn Forte "not in different device groups"), 1034*fcf3ce44SJohn Forte master, shadow, bitmap); 1035*fcf3ce44SJohn Forte else { 1036*fcf3ce44SJohn Forte cfg_resource(cfg, shd_dg); 1037*fcf3ce44SJohn Forte (void) snprintf(buf, sizeof (buf), 1038*fcf3ce44SJohn Forte "%s %s %s update %s", 1039*fcf3ce44SJohn Forte master, shadow, bitmap, shd_dg); 1040*fcf3ce44SJohn Forte } 1041*fcf3ce44SJohn Forte } else { 1042*fcf3ce44SJohn Forte (void) snprintf(buf, sizeof (buf), "%s %s %s update", 1043*fcf3ce44SJohn Forte master, shadow, bitmap); 1044*fcf3ce44SJohn Forte } 1045*fcf3ce44SJohn Forte 1046*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, "ndr_ii", buf, strlen(buf)) < 0) || 1047*fcf3ce44SJohn Forte (cfg_commit(cfg) < 0)) 1048*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("unable to add \"%s\" to " 1049*fcf3ce44SJohn Forte "configuration storage: %s"), 1050*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 1051*fcf3ce44SJohn Forte 1052*fcf3ce44SJohn Forte cfg_close(cfg); 1053*fcf3ce44SJohn Forte 1054*fcf3ce44SJohn Forte break; 1055*fcf3ce44SJohn Forte 1056*fcf3ce44SJohn Forte default: 1057*fcf3ce44SJohn Forte usage(); 1058*fcf3ce44SJohn Forte exit(1); 1059*fcf3ce44SJohn Forte } 1060*fcf3ce44SJohn Forte } 1061*fcf3ce44SJohn Forte 1062*fcf3ce44SJohn Forte void 1063*fcf3ce44SJohn Forte check_rdcbitmap(int cmd, char *hostp, char *bmp) 1064*fcf3ce44SJohn Forte { 1065*fcf3ce44SJohn Forte int i; 1066*fcf3ce44SJohn Forte CFGFILE *cfg; 1067*fcf3ce44SJohn Forte int entries; 1068*fcf3ce44SJohn Forte char **entry; 1069*fcf3ce44SJohn Forte char *host, *pri, *sec, *sbm, *bit, *mas, *sha, *ovr; 1070*fcf3ce44SJohn Forte char *shost, *buf, *que; 1071*fcf3ce44SJohn Forte 1072*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 1073*fcf3ce44SJohn Forte rdc_err(NULL, 1074*fcf3ce44SJohn Forte gettext("unable to access configuration")); 1075*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 1076*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 1077*fcf3ce44SJohn Forte 1078*fcf3ce44SJohn Forte /* 1079*fcf3ce44SJohn Forte * look into II config to see if this is being used elsewhere 1080*fcf3ce44SJohn Forte */ 1081*fcf3ce44SJohn Forte entry = NULL; 1082*fcf3ce44SJohn Forte entries = cfg_get_section(cfg, &entry, "ii"); 1083*fcf3ce44SJohn Forte for (i = 0; i < entries; i++) { 1084*fcf3ce44SJohn Forte buf = entry[i]; 1085*fcf3ce44SJohn Forte 1086*fcf3ce44SJohn Forte mas = strtok(buf, " "); /* master */ 1087*fcf3ce44SJohn Forte sha = strtok(NULL, " "); /* shadow */ 1088*fcf3ce44SJohn Forte bit = strtok(NULL, " "); /* bitmap */ 1089*fcf3ce44SJohn Forte (void) strtok(NULL, " "); /* mode */ 1090*fcf3ce44SJohn Forte ovr = strtok(NULL, " "); /* overflow */ 1091*fcf3ce44SJohn Forte 1092*fcf3ce44SJohn Forte /* 1093*fcf3ce44SJohn Forte * got master, shadow, overflow, and bitmap, now compare 1094*fcf3ce44SJohn Forte */ 1095*fcf3ce44SJohn Forte if ((strcmp(bmp, mas) == 0) || 1096*fcf3ce44SJohn Forte (strcmp(bmp, sha) == 0) || 1097*fcf3ce44SJohn Forte (strcmp(bmp, ovr) == 0) || 1098*fcf3ce44SJohn Forte (strcmp(bmp, bit) == 0)) { 1099*fcf3ce44SJohn Forte rdc_err(NULL, 1100*fcf3ce44SJohn Forte gettext("bitmap %s is in use by" 1101*fcf3ce44SJohn Forte " Point-in-Time Copy"), bmp); 1102*fcf3ce44SJohn Forte } 1103*fcf3ce44SJohn Forte free(buf); 1104*fcf3ce44SJohn Forte } 1105*fcf3ce44SJohn Forte if (entries) 1106*fcf3ce44SJohn Forte free(entry); 1107*fcf3ce44SJohn Forte 1108*fcf3ce44SJohn Forte 1109*fcf3ce44SJohn Forte /* 1110*fcf3ce44SJohn Forte * and last but not least, make sure sndr is not using vol for anything 1111*fcf3ce44SJohn Forte */ 1112*fcf3ce44SJohn Forte entry = NULL; 1113*fcf3ce44SJohn Forte entries = cfg_get_section(cfg, &entry, "sndr"); 1114*fcf3ce44SJohn Forte for (i = 0; i < entries; i++) { 1115*fcf3ce44SJohn Forte buf = entry[i]; 1116*fcf3ce44SJohn Forte 1117*fcf3ce44SJohn Forte /* 1118*fcf3ce44SJohn Forte * I think this is quicker than 1119*fcf3ce44SJohn Forte * having to double dip into the config 1120*fcf3ce44SJohn Forte */ 1121*fcf3ce44SJohn Forte host = strtok(buf, " "); /* phost */ 1122*fcf3ce44SJohn Forte pri = strtok(NULL, " "); /* primary */ 1123*fcf3ce44SJohn Forte bit = strtok(NULL, " "); /* pbitmap */ 1124*fcf3ce44SJohn Forte shost = strtok(NULL, " "); /* shost */ 1125*fcf3ce44SJohn Forte sec = strtok(NULL, " "); /* secondary */ 1126*fcf3ce44SJohn Forte sbm = strtok(NULL, " "); /* sbitmap */ 1127*fcf3ce44SJohn Forte (void) strtok(NULL, " "); /* type */ 1128*fcf3ce44SJohn Forte (void) strtok(NULL, " "); /* mode */ 1129*fcf3ce44SJohn Forte (void) strtok(NULL, " "); /* group */ 1130*fcf3ce44SJohn Forte (void) strtok(NULL, " "); /* cnode */ 1131*fcf3ce44SJohn Forte (void) strtok(NULL, " "); /* options */ 1132*fcf3ce44SJohn Forte que = strtok(NULL, " "); /* diskq */ 1133*fcf3ce44SJohn Forte 1134*fcf3ce44SJohn Forte if (cmd == RDC_CMD_ENABLE) { 1135*fcf3ce44SJohn Forte if (self_check(host)) { 1136*fcf3ce44SJohn Forte if ((strcmp(bmp, pri) == 0) || 1137*fcf3ce44SJohn Forte (strcmp(bmp, que) == 0) || 1138*fcf3ce44SJohn Forte (strcmp(bmp, bit) == 0)) { 1139*fcf3ce44SJohn Forte rdc_err(NULL, 1140*fcf3ce44SJohn Forte gettext("bitmap %s is already " 1141*fcf3ce44SJohn Forte "in use by StorEdge Network Data " 1142*fcf3ce44SJohn Forte "Replicator"), bmp); 1143*fcf3ce44SJohn Forte } 1144*fcf3ce44SJohn Forte } else { 1145*fcf3ce44SJohn Forte if ((strcmp(bmp, sec) == 0) || 1146*fcf3ce44SJohn Forte (strcmp(bmp, sbm) == 0)) { 1147*fcf3ce44SJohn Forte rdc_err(NULL, 1148*fcf3ce44SJohn Forte gettext("bitmap %s is already " 1149*fcf3ce44SJohn Forte "in use by StorEdge Network Data " 1150*fcf3ce44SJohn Forte "Replicator"), bmp); 1151*fcf3ce44SJohn Forte } 1152*fcf3ce44SJohn Forte } 1153*fcf3ce44SJohn Forte } else if (cmd == RDC_CMD_RECONFIG) { 1154*fcf3ce44SJohn Forte 1155*fcf3ce44SJohn Forte /* 1156*fcf3ce44SJohn Forte * read this logic 1000 times and consider 1157*fcf3ce44SJohn Forte * multi homed, one to many, many to one (marketing) 1158*fcf3ce44SJohn Forte * etc, etc, before changing 1159*fcf3ce44SJohn Forte */ 1160*fcf3ce44SJohn Forte if (self_check(hostp)) { 1161*fcf3ce44SJohn Forte if (self_check(host)) { 1162*fcf3ce44SJohn Forte if ((strcmp(bmp, pri) == 0) || 1163*fcf3ce44SJohn Forte (strcmp(bmp, que) == 0) || 1164*fcf3ce44SJohn Forte (strcmp(bmp, bit) == 0)) { 1165*fcf3ce44SJohn Forte rdc_err(NULL, 1166*fcf3ce44SJohn Forte gettext("bitmap %s is already " 1167*fcf3ce44SJohn Forte "in use by StorEdge Network " 1168*fcf3ce44SJohn Forte "Data Replicator"), bmp); 1169*fcf3ce44SJohn Forte } 1170*fcf3ce44SJohn Forte } else { 1171*fcf3ce44SJohn Forte if ((strcmp(hostp, shost) == 0) && 1172*fcf3ce44SJohn Forte (strcmp(bmp, sec) == 0) || 1173*fcf3ce44SJohn Forte (strcmp(bmp, sbm) == 0)) { 1174*fcf3ce44SJohn Forte rdc_err(NULL, 1175*fcf3ce44SJohn Forte gettext("bitmap %s is already " 1176*fcf3ce44SJohn Forte "in use by StorEdge Network " 1177*fcf3ce44SJohn Forte "Data Replicator"), bmp); 1178*fcf3ce44SJohn Forte 1179*fcf3ce44SJohn Forte } 1180*fcf3ce44SJohn Forte } 1181*fcf3ce44SJohn Forte } else { /* self_check(hostp) failed */ 1182*fcf3ce44SJohn Forte if (self_check(host)) { 1183*fcf3ce44SJohn Forte if ((strcmp(shost, hostp) == 0) && 1184*fcf3ce44SJohn Forte (strcmp(bmp, sec) == 0) || 1185*fcf3ce44SJohn Forte (strcmp(bmp, sbm) == 0)) { 1186*fcf3ce44SJohn Forte rdc_err(NULL, 1187*fcf3ce44SJohn Forte gettext("bitmap %s is already " 1188*fcf3ce44SJohn Forte "in use by StorEdge Network " 1189*fcf3ce44SJohn Forte "Data Replicator"), bmp); 1190*fcf3ce44SJohn Forte } 1191*fcf3ce44SJohn Forte } else { 1192*fcf3ce44SJohn Forte if ((strcmp(host, hostp) == 0) && 1193*fcf3ce44SJohn Forte (strcmp(bmp, pri) == 0) || 1194*fcf3ce44SJohn Forte (strcmp(bmp, que) == 0) || 1195*fcf3ce44SJohn Forte (strcmp(bmp, bit) == 0)) { 1196*fcf3ce44SJohn Forte rdc_err(NULL, 1197*fcf3ce44SJohn Forte gettext("bitmap %s is already " 1198*fcf3ce44SJohn Forte "in use by StorEdge Network " 1199*fcf3ce44SJohn Forte "Data Replicator"), bmp); 1200*fcf3ce44SJohn Forte } 1201*fcf3ce44SJohn Forte } 1202*fcf3ce44SJohn Forte } 1203*fcf3ce44SJohn Forte 1204*fcf3ce44SJohn Forte } 1205*fcf3ce44SJohn Forte 1206*fcf3ce44SJohn Forte free(buf); 1207*fcf3ce44SJohn Forte } 1208*fcf3ce44SJohn Forte cfg_close(cfg); 1209*fcf3ce44SJohn Forte 1210*fcf3ce44SJohn Forte if (entries) 1211*fcf3ce44SJohn Forte free(entry); 1212*fcf3ce44SJohn Forte } 1213*fcf3ce44SJohn Forte int 1214*fcf3ce44SJohn Forte check_intrange(char *arg) { 1215*fcf3ce44SJohn Forte int i; 1216*fcf3ce44SJohn Forte 1217*fcf3ce44SJohn Forte for (i = 0; i < strlen(arg); i++) { 1218*fcf3ce44SJohn Forte if (arg[i] < '0' || arg[i] > '9') { 1219*fcf3ce44SJohn Forte rdc_warn(NULL, "not a valid number, must be a " 1220*fcf3ce44SJohn Forte "decimal between 1 and %d", MAXINT); 1221*fcf3ce44SJohn Forte return (0); 1222*fcf3ce44SJohn Forte } 1223*fcf3ce44SJohn Forte } 1224*fcf3ce44SJohn Forte errno = 0; 1225*fcf3ce44SJohn Forte i = (int)strtol(arg, NULL, 10); 1226*fcf3ce44SJohn Forte if ((errno) || (i < 1) || (i > MAXINT)) { 1227*fcf3ce44SJohn Forte rdc_warn(NULL, "not a valid number, must be a decimal " 1228*fcf3ce44SJohn Forte "between 1 and %d", MAXINT); 1229*fcf3ce44SJohn Forte return (0); 1230*fcf3ce44SJohn Forte } 1231*fcf3ce44SJohn Forte return (1); 1232*fcf3ce44SJohn Forte } 1233*fcf3ce44SJohn Forte 1234*fcf3ce44SJohn Forte void 1235*fcf3ce44SJohn Forte rewrite_group_diskqueue(CFGFILE *cfg, _sd_dual_pair_t *pair, char *diskqueue) 1236*fcf3ce44SJohn Forte { 1237*fcf3ce44SJohn Forte int set; 1238*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1239*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1240*fcf3ce44SJohn Forte _sd_dual_pair_t tmpair; 1241*fcf3ce44SJohn Forte 1242*fcf3ce44SJohn Forte for (set = 1; /*CSTYLED*/; set++) { 1243*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 1244*fcf3ce44SJohn Forte bzero(&tmpair, sizeof (tmpair)); 1245*fcf3ce44SJohn Forte 1246*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", set); 1247*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 1248*fcf3ce44SJohn Forte break; 1249*fcf3ce44SJohn Forte } 1250*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &tmpair, NULL)) 1251*fcf3ce44SJohn Forte continue; 1252*fcf3ce44SJohn Forte if (pair->group && pair->group[0]) { 1253*fcf3ce44SJohn Forte if (strcmp(pair->group, tmpair.group) != 0) 1254*fcf3ce44SJohn Forte continue; /* not the group we want */ 1255*fcf3ce44SJohn Forte 1256*fcf3ce44SJohn Forte } else { /* no group specified */ 1257*fcf3ce44SJohn Forte if (strcmp(pair->thost, tmpair.thost) != 0) 1258*fcf3ce44SJohn Forte continue; 1259*fcf3ce44SJohn Forte if (strcmp(pair->tfile, tmpair.tfile) != 0) 1260*fcf3ce44SJohn Forte continue; 1261*fcf3ce44SJohn Forte } 1262*fcf3ce44SJohn Forte 1263*fcf3ce44SJohn Forte (void) sprintf(key, "sndr.set%d.diskq", set); 1264*fcf3ce44SJohn Forte 1265*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, diskqueue, 1266*fcf3ce44SJohn Forte strlen(diskqueue)) < 0) { 1267*fcf3ce44SJohn Forte perror(cfg_error(NULL)); 1268*fcf3ce44SJohn Forte } 1269*fcf3ce44SJohn Forte } 1270*fcf3ce44SJohn Forte } 1271*fcf3ce44SJohn Forte 1272*fcf3ce44SJohn Forte void 1273*fcf3ce44SJohn Forte diskq_subcmd(int subcmd, char *qvol, char *group_arg, char *ctag_arg, 1274*fcf3ce44SJohn Forte char *tohost_arg, char *tofile_arg) 1275*fcf3ce44SJohn Forte { 1276*fcf3ce44SJohn Forte int found = 0; 1277*fcf3ce44SJohn Forte int setnumber = 0; 1278*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1279*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1280*fcf3ce44SJohn Forte int i; 1281*fcf3ce44SJohn Forte int rc; 1282*fcf3ce44SJohn Forte int option = 0; 1283*fcf3ce44SJohn Forte _sd_dual_pair_t pair; 1284*fcf3ce44SJohn Forte CFGFILE *cfg; 1285*fcf3ce44SJohn Forte char *ctag = NULL; 1286*fcf3ce44SJohn Forte int resourced = 0; 1287*fcf3ce44SJohn Forte 1288*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 1289*fcf3ce44SJohn Forte rdc_err(NULL, 1290*fcf3ce44SJohn Forte gettext("unable to access configuration")); 1291*fcf3ce44SJohn Forte 1292*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) 1293*fcf3ce44SJohn Forte rdc_err(NULL, 1294*fcf3ce44SJohn Forte gettext("unable to lock configuration")); 1295*fcf3ce44SJohn Forte 1296*fcf3ce44SJohn Forte redo: 1297*fcf3ce44SJohn Forte if (cfg_load_svols(cfg) < 0 || 1298*fcf3ce44SJohn Forte cfg_load_dsvols(cfg) < 0 || 1299*fcf3ce44SJohn Forte cfg_load_shadows(cfg) < 0) 1300*fcf3ce44SJohn Forte rdc_err(NULL, 1301*fcf3ce44SJohn Forte gettext("Unable to parse config filer")); 1302*fcf3ce44SJohn Forte load_rdc_vols(cfg); 1303*fcf3ce44SJohn Forte 1304*fcf3ce44SJohn Forte /*CSTYLED*/ 1305*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets;) { 1306*fcf3ce44SJohn Forte setnumber++; 1307*fcf3ce44SJohn Forte 1308*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 1309*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1310*fcf3ce44SJohn Forte "sndr.set%d", setnumber); 1311*fcf3ce44SJohn Forte rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF); 1312*fcf3ce44SJohn Forte if (rc < 0) 1313*fcf3ce44SJohn Forte break; 1314*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &pair, NULL)) 1315*fcf3ce44SJohn Forte continue; 1316*fcf3ce44SJohn Forte 1317*fcf3ce44SJohn Forte if (strlen(group_arg) == 0) { 1318*fcf3ce44SJohn Forte if (strcmp(tohost_arg, pair.thost) == 0 && 1319*fcf3ce44SJohn Forte strcmp(tofile_arg, pair.tfile) == 0) { 1320*fcf3ce44SJohn Forte strcpy(group_arg, pair.group); 1321*fcf3ce44SJohn Forte found = 1; 1322*fcf3ce44SJohn Forte break; 1323*fcf3ce44SJohn Forte } 1324*fcf3ce44SJohn Forte 1325*fcf3ce44SJohn Forte } else { 1326*fcf3ce44SJohn Forte if (strcmp(group_arg, pair.group) == 0) { 1327*fcf3ce44SJohn Forte found = 1; 1328*fcf3ce44SJohn Forte break; 1329*fcf3ce44SJohn Forte } 1330*fcf3ce44SJohn Forte } 1331*fcf3ce44SJohn Forte } 1332*fcf3ce44SJohn Forte 1333*fcf3ce44SJohn Forte if (!found) { 1334*fcf3ce44SJohn Forte if (strlen(group_arg) == 0) { 1335*fcf3ce44SJohn Forte rdc_err(NULL, 1336*fcf3ce44SJohn Forte gettext("Unable to find %s:%s in " 1337*fcf3ce44SJohn Forte "configuration storage"), 1338*fcf3ce44SJohn Forte tohost_arg, tofile_arg); 1339*fcf3ce44SJohn Forte } else { 1340*fcf3ce44SJohn Forte rdc_err(NULL, 1341*fcf3ce44SJohn Forte gettext("Unable to find group %s in " 1342*fcf3ce44SJohn Forte "configuration storage"), group_arg); 1343*fcf3ce44SJohn Forte } 1344*fcf3ce44SJohn Forte } 1345*fcf3ce44SJohn Forte if (!resourced && strlen(pair.ctag)) { /* uh-oh... */ 1346*fcf3ce44SJohn Forte cfg_unload_svols(cfg); 1347*fcf3ce44SJohn Forte cfg_unload_dsvols(cfg); 1348*fcf3ce44SJohn Forte cfg_unload_shadows(cfg); 1349*fcf3ce44SJohn Forte unload_rdc_vols(); 1350*fcf3ce44SJohn Forte cfg_resource(cfg, pair.ctag); 1351*fcf3ce44SJohn Forte ctag = strdup(pair.ctag); 1352*fcf3ce44SJohn Forte resourced = 1; 1353*fcf3ce44SJohn Forte setnumber = 0; 1354*fcf3ce44SJohn Forte goto redo; 1355*fcf3ce44SJohn Forte } 1356*fcf3ce44SJohn Forte 1357*fcf3ce44SJohn Forte if (clustered && !rdc_islocal) { 1358*fcf3ce44SJohn Forte if (strcmp(ctag_arg, "") && 1359*fcf3ce44SJohn Forte strncmp(ctag_arg, pair.ctag, MAX_RDC_HOST_SIZE)) 1360*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("ctags %s and %s " 1361*fcf3ce44SJohn Forte "do not match, proceeding with operation based " 1362*fcf3ce44SJohn Forte "on existing set information"), ctag_arg, ctag); 1363*fcf3ce44SJohn Forte } 1364*fcf3ce44SJohn Forte switch (subcmd) { 1365*fcf3ce44SJohn Forte case RDC_CMD_ADDQ: 1366*fcf3ce44SJohn Forte if (clustered && (ctag_check(pair.fhost, pair.ffile, 1367*fcf3ce44SJohn Forte pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap, 1368*fcf3ce44SJohn Forte pair.ctag, qvol) < 0)) 1369*fcf3ce44SJohn Forte exit(1); 1370*fcf3ce44SJohn Forte 1371*fcf3ce44SJohn Forte if (strlen(pair.diskqueue) > 0) { 1372*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror set already " 1373*fcf3ce44SJohn Forte "has a disk queue")); 1374*fcf3ce44SJohn Forte } 1375*fcf3ce44SJohn Forte if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) { 1376*fcf3ce44SJohn Forte rdc_err(NULL, 1377*fcf3ce44SJohn Forte gettext("diskqueue %s is incompatible"), qvol); 1378*fcf3ce44SJohn Forte } 1379*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1380*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, 1381*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1382*fcf3ce44SJohn Forte 0) < 0) { 1383*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0) 1384*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove disk " 1385*fcf3ce44SJohn Forte "queue [%s] from configuration"), qvol); 1386*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Add disk queue operation " 1387*fcf3ce44SJohn Forte "failed")); 1388*fcf3ce44SJohn Forte } 1389*fcf3ce44SJohn Forte if (nsc_lookup(volhash, qvol) == NULL) { 1390*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) { 1391*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Add disk queue " 1392*fcf3ce44SJohn Forte "operation failed")); 1393*fcf3ce44SJohn Forte } 1394*fcf3ce44SJohn Forte } 1395*fcf3ce44SJohn Forte rewrite_group_diskqueue(cfg, &pair, qvol); 1396*fcf3ce44SJohn Forte 1397*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: added " 1398*fcf3ce44SJohn Forte "diskqueue %s to set %s:%s and its group"), qvol, 1399*fcf3ce44SJohn Forte pair.thost, pair.tfile); 1400*fcf3ce44SJohn Forte break; 1401*fcf3ce44SJohn Forte case RDC_OPT_FORCE_QINIT: 1402*fcf3ce44SJohn Forte if (strlen(pair.diskqueue) == 0) { 1403*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror set does not " 1404*fcf3ce44SJohn Forte "have a disk queue")); 1405*fcf3ce44SJohn Forte } 1406*fcf3ce44SJohn Forte subcmd = RDC_CMD_INITQ; 1407*fcf3ce44SJohn Forte option = RDC_OPT_FORCE_QINIT; 1408*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1409*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, subcmd, option, 1410*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1411*fcf3ce44SJohn Forte 0) < 0) { 1412*fcf3ce44SJohn Forte exit(1); 1413*fcf3ce44SJohn Forte } 1414*fcf3ce44SJohn Forte break; 1415*fcf3ce44SJohn Forte case RDC_CMD_INITQ: 1416*fcf3ce44SJohn Forte if (strlen(pair.diskqueue) == 0) { 1417*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror set does not " 1418*fcf3ce44SJohn Forte "have a disk queue")); 1419*fcf3ce44SJohn Forte } 1420*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1421*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, 1422*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1423*fcf3ce44SJohn Forte 0) < 0) { 1424*fcf3ce44SJohn Forte exit(1); 1425*fcf3ce44SJohn Forte } 1426*fcf3ce44SJohn Forte break; 1427*fcf3ce44SJohn Forte case RDC_CMD_REMQ: 1428*fcf3ce44SJohn Forte if (strlen(pair.diskqueue) == 0) { 1429*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror set does not " 1430*fcf3ce44SJohn Forte "have a disk queue")); 1431*fcf3ce44SJohn Forte } 1432*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1433*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, 1434*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1435*fcf3ce44SJohn Forte 0) < 0) { 1436*fcf3ce44SJohn Forte exit(1); 1437*fcf3ce44SJohn Forte } 1438*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0) 1439*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove disk queue " 1440*fcf3ce44SJohn Forte "[%s] from configuration"), pair.diskqueue); 1441*fcf3ce44SJohn Forte rewrite_group_diskqueue(cfg, &pair, place_holder); 1442*fcf3ce44SJohn Forte 1443*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: removed " 1444*fcf3ce44SJohn Forte "diskqueue from set %s:%s and its group"), pair.thost, 1445*fcf3ce44SJohn Forte pair.tfile); 1446*fcf3ce44SJohn Forte break; 1447*fcf3ce44SJohn Forte case RDC_CMD_KILLQ: 1448*fcf3ce44SJohn Forte if (strlen(pair.diskqueue) == 0) { 1449*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror set does not " 1450*fcf3ce44SJohn Forte "have a disk queue")); 1451*fcf3ce44SJohn Forte } 1452*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1453*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, 1454*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1455*fcf3ce44SJohn Forte 0) < 0) { 1456*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Failed to remove disk queue")); 1457*fcf3ce44SJohn Forte } 1458*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0) 1459*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove disk queue " 1460*fcf3ce44SJohn Forte "[%s] from configuration"), pair.diskqueue); 1461*fcf3ce44SJohn Forte 1462*fcf3ce44SJohn Forte rewrite_group_diskqueue(cfg, &pair, place_holder); 1463*fcf3ce44SJohn Forte 1464*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: forcibly " 1465*fcf3ce44SJohn Forte "removed diskqueue from set %s:%s and its group "), 1466*fcf3ce44SJohn Forte pair.thost, pair.tfile); 1467*fcf3ce44SJohn Forte break; 1468*fcf3ce44SJohn Forte case RDC_CMD_REPQ: 1469*fcf3ce44SJohn Forte if (clustered && (ctag_check(pair.fhost, pair.ffile, 1470*fcf3ce44SJohn Forte pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap, 1471*fcf3ce44SJohn Forte pair.ctag, qvol) < 0)) 1472*fcf3ce44SJohn Forte exit(1); 1473*fcf3ce44SJohn Forte 1474*fcf3ce44SJohn Forte if (strlen(pair.diskqueue) == 0) { 1475*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror set does not " 1476*fcf3ce44SJohn Forte "have a disk queue")); 1477*fcf3ce44SJohn Forte } 1478*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1479*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_REMQ, 0, 1480*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1481*fcf3ce44SJohn Forte 0) < 0) { 1482*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Failed to remove disk queue")); 1483*fcf3ce44SJohn Forte } 1484*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0) 1485*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove disk queue " 1486*fcf3ce44SJohn Forte "[%s] from configuration"), pair.diskqueue); 1487*fcf3ce44SJohn Forte 1488*fcf3ce44SJohn Forte rewrite_group_diskqueue(cfg, &pair, place_holder); 1489*fcf3ce44SJohn Forte 1490*fcf3ce44SJohn Forte /* commit here, enable may fail */ 1491*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) { 1492*fcf3ce44SJohn Forte rdc_err(NULL, gettext("commit replace disk queue %s " 1493*fcf3ce44SJohn Forte "with %s failed"), pair.diskqueue, qvol); 1494*fcf3ce44SJohn Forte } 1495*fcf3ce44SJohn Forte 1496*fcf3ce44SJohn Forte if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) { 1497*fcf3ce44SJohn Forte rdc_err(NULL, 1498*fcf3ce44SJohn Forte gettext("cannot replace disk queue %s with %s"), 1499*fcf3ce44SJohn Forte pair.diskqueue, qvol); 1500*fcf3ce44SJohn Forte } 1501*fcf3ce44SJohn Forte if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, 1502*fcf3ce44SJohn Forte pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_ADDQ, 0, 1503*fcf3ce44SJohn Forte pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, 1504*fcf3ce44SJohn Forte 0) < 0) { 1505*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0) 1506*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove disk " 1507*fcf3ce44SJohn Forte "queue [%s] from configuration"), qvol); 1508*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Failed to add new disk queue")); 1509*fcf3ce44SJohn Forte } 1510*fcf3ce44SJohn Forte if (nsc_lookup(volhash, qvol) == NULL) 1511*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) { 1512*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Replace disk queue " 1513*fcf3ce44SJohn Forte "operation failed")); 1514*fcf3ce44SJohn Forte } 1515*fcf3ce44SJohn Forte 1516*fcf3ce44SJohn Forte rewrite_group_diskqueue(cfg, &pair, qvol); 1517*fcf3ce44SJohn Forte 1518*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: replaced " 1519*fcf3ce44SJohn Forte "diskqueue for set %s:%s and its group with %s"), 1520*fcf3ce44SJohn Forte pair.thost, pair.tfile, qvol); 1521*fcf3ce44SJohn Forte break; 1522*fcf3ce44SJohn Forte } 1523*fcf3ce44SJohn Forte 1524*fcf3ce44SJohn Forte cfg_unload_svols(cfg); 1525*fcf3ce44SJohn Forte cfg_unload_dsvols(cfg); 1526*fcf3ce44SJohn Forte cfg_unload_shadows(cfg); 1527*fcf3ce44SJohn Forte unload_rdc_vols(); 1528*fcf3ce44SJohn Forte 1529*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) 1530*fcf3ce44SJohn Forte rdc_err(NULL, gettext("commit failed on disk queue operation")); 1531*fcf3ce44SJohn Forte 1532*fcf3ce44SJohn Forte cfg_close(cfg); 1533*fcf3ce44SJohn Forte if (ctag) 1534*fcf3ce44SJohn Forte free(ctag); 1535*fcf3ce44SJohn Forte } 1536*fcf3ce44SJohn Forte void 1537*fcf3ce44SJohn Forte spcslog_sync(rdcconfig_t *sets, int start, int type) 1538*fcf3ce44SJohn Forte { 1539*fcf3ce44SJohn Forte rdcconfig_t *setp = sets; 1540*fcf3ce44SJohn Forte 1541*fcf3ce44SJohn Forte while (setp) { 1542*fcf3ce44SJohn Forte if (start) { 1543*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1544*fcf3ce44SJohn Forte gettext("%s %s %s %s %s %s %s %s\nSync Started"), 1545*fcf3ce44SJohn Forte program, rdc_decode_flag(RDC_CMD_COPY, type), 1546*fcf3ce44SJohn Forte setp->phost, setp->pfile, setp->pbmp, 1547*fcf3ce44SJohn Forte setp->shost, setp->sfile, setp->sbmp); 1548*fcf3ce44SJohn Forte } else { 1549*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1550*fcf3ce44SJohn Forte gettext("%s %s %s %s %s %s %s %s\nSync Ended"), 1551*fcf3ce44SJohn Forte program, rdc_decode_flag(RDC_CMD_COPY, type), 1552*fcf3ce44SJohn Forte setp->phost, setp->pfile, setp->pbmp, 1553*fcf3ce44SJohn Forte setp->shost, setp->sfile, setp->sbmp); 1554*fcf3ce44SJohn Forte } 1555*fcf3ce44SJohn Forte setp = setp->next; 1556*fcf3ce44SJohn Forte } 1557*fcf3ce44SJohn Forte } 1558*fcf3ce44SJohn Forte 1559*fcf3ce44SJohn Forte void 1560*fcf3ce44SJohn Forte spcslog_tunable(char *shost, char *svol) 1561*fcf3ce44SJohn Forte { 1562*fcf3ce44SJohn Forte if (qblock == RDC_OPT_SET_QNOBLOCK) 1563*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("diskqueue " 1564*fcf3ce44SJohn Forte "set to non blocking for %s:%s and any members " 1565*fcf3ce44SJohn Forte "of it's group"), shost, svol); 1566*fcf3ce44SJohn Forte else if (qblock == RDC_OPT_CLR_QNOBLOCK) 1567*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("diskqueue " 1568*fcf3ce44SJohn Forte "set to blocking for %s:%s and any members " 1569*fcf3ce44SJohn Forte "of it's group"), shost, svol); 1570*fcf3ce44SJohn Forte 1571*fcf3ce44SJohn Forte if (maxqfbas) 1572*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("maxqfbas set to %d for %s:%s"), 1573*fcf3ce44SJohn Forte maxqfbas, shost, svol); 1574*fcf3ce44SJohn Forte if (maxqitems) 1575*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("maxwrites set to %d for %s:%s"), 1576*fcf3ce44SJohn Forte maxqitems, shost, svol); 1577*fcf3ce44SJohn Forte if (asyncthr) 1578*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("%d async threads configured " 1579*fcf3ce44SJohn Forte "for %s:%s"), asyncthr, shost, svol); 1580*fcf3ce44SJohn Forte } 1581*fcf3ce44SJohn Forte 1582*fcf3ce44SJohn Forte int 1583*fcf3ce44SJohn Forte set_qblock(char *blockarg) 1584*fcf3ce44SJohn Forte { 1585*fcf3ce44SJohn Forte if (strcmp(blockarg, "block") == 0) 1586*fcf3ce44SJohn Forte qblock = RDC_OPT_CLR_QNOBLOCK; 1587*fcf3ce44SJohn Forte else if (strcmp(blockarg, "noblock") == 0) 1588*fcf3ce44SJohn Forte qblock = RDC_OPT_SET_QNOBLOCK; 1589*fcf3ce44SJohn Forte else 1590*fcf3ce44SJohn Forte return (1); 1591*fcf3ce44SJohn Forte 1592*fcf3ce44SJohn Forte return (0); 1593*fcf3ce44SJohn Forte } 1594*fcf3ce44SJohn Forte 1595*fcf3ce44SJohn Forte static void 1596*fcf3ce44SJohn Forte rdc_force_disable(CFGFILE *cfg, char *phost, char *pvol, char *pbmp, 1597*fcf3ce44SJohn Forte char *shost, char *svol, char *sbmp, char *ctag, char *lhname) 1598*fcf3ce44SJohn Forte { 1599*fcf3ce44SJohn Forte rdc_config_t parms; 1600*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 1601*fcf3ce44SJohn Forte volcount_t *vc; 1602*fcf3ce44SJohn Forte char *datavol = NULL; 1603*fcf3ce44SJohn Forte char *bmpvol = NULL; 1604*fcf3ce44SJohn Forte int on_pri = 0; 1605*fcf3ce44SJohn Forte int on_sec = 0; 1606*fcf3ce44SJohn Forte 1607*fcf3ce44SJohn Forte /* are we on the primary or secondary host? */ 1608*fcf3ce44SJohn Forte if (ctag && *ctag && *lhname) { 1609*fcf3ce44SJohn Forte if (strcmp(phost, lhname) == 0) { 1610*fcf3ce44SJohn Forte on_pri = 1; 1611*fcf3ce44SJohn Forte } else if (strcmp(shost, lhname) == 0) { 1612*fcf3ce44SJohn Forte on_sec = 1; 1613*fcf3ce44SJohn Forte } 1614*fcf3ce44SJohn Forte } else if (self_check(phost)) { 1615*fcf3ce44SJohn Forte on_pri = 1; 1616*fcf3ce44SJohn Forte } else if (self_check(shost)) { 1617*fcf3ce44SJohn Forte on_sec = 1; 1618*fcf3ce44SJohn Forte } 1619*fcf3ce44SJohn Forte 1620*fcf3ce44SJohn Forte if (on_pri) { 1621*fcf3ce44SJohn Forte datavol = pvol; 1622*fcf3ce44SJohn Forte bmpvol = pbmp; 1623*fcf3ce44SJohn Forte } else if (on_sec) { 1624*fcf3ce44SJohn Forte datavol = svol; 1625*fcf3ce44SJohn Forte bmpvol = sbmp; 1626*fcf3ce44SJohn Forte } else { 1627*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Unable to determine whether current " 1628*fcf3ce44SJohn Forte "node is primary or secondary")); 1629*fcf3ce44SJohn Forte } 1630*fcf3ce44SJohn Forte 1631*fcf3ce44SJohn Forte /* set up parms structure */ 1632*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 1633*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.intf, phost, MAX_RDC_HOST_SIZE); 1634*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.file, pvol, NSC_MAXPATH); 1635*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.intf, shost, MAX_RDC_HOST_SIZE); 1636*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.file, svol, NSC_MAXPATH); 1637*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 1638*fcf3ce44SJohn Forte parms.options = RDC_OPT_FORCE_DISABLE; 1639*fcf3ce44SJohn Forte 1640*fcf3ce44SJohn Forte /* 1641*fcf3ce44SJohn Forte * We are now going to 'force' the kernel to disable the set. By 1642*fcf3ce44SJohn Forte * setting the RDC_OPT_FORCE_DISABLE flag, the kernel will bypass some 1643*fcf3ce44SJohn Forte * of the checks that are normally done when attempting to disable 1644*fcf3ce44SJohn Forte * a set. We need to do this force option in a cluster environment 1645*fcf3ce44SJohn Forte * when the logical hostname for the primary or secondary volume 1646*fcf3ce44SJohn Forte * is no longer available. 1647*fcf3ce44SJohn Forte */ 1648*fcf3ce44SJohn Forte spcs_log("sndr", NULL, "%s sndradm -d %s %s %s %s %s %s", 1649*fcf3ce44SJohn Forte gettext("FORCE DISABLE"), phost, pvol, pbmp, shost, svol, sbmp); 1650*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Forcing set disable")); 1651*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_CONFIG, &parms, 0, 0, 0, 0, ustatus) != SPCS_S_OK) 1652*fcf3ce44SJohn Forte rdc_warn(&ustatus, gettext("set %s:%s not enabled in kernel"), 1653*fcf3ce44SJohn Forte shost, svol); 1654*fcf3ce44SJohn Forte 1655*fcf3ce44SJohn Forte /* if we get to this point, then a set was disabled. try sv-disable */ 1656*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, datavol); 1657*fcf3ce44SJohn Forte if (vc && (1 == vc->count)) 1658*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, datavol, ctag, "sndr") < 0) 1659*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove data volume " 1660*fcf3ce44SJohn Forte "[%s] from configuration"), datavol); 1661*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, bmpvol); 1662*fcf3ce44SJohn Forte if (vc && (1 == vc->count)) 1663*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, bmpvol, ctag, "sndr") < 0) 1664*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to remove bitmap " 1665*fcf3ce44SJohn Forte "[%s] from configuration"), bmpvol); 1666*fcf3ce44SJohn Forte } 1667*fcf3ce44SJohn Forte 1668*fcf3ce44SJohn Forte void 1669*fcf3ce44SJohn Forte check_rdcsecondary(char *secondary) 1670*fcf3ce44SJohn Forte { 1671*fcf3ce44SJohn Forte int i; 1672*fcf3ce44SJohn Forte CFGFILE *cfg; 1673*fcf3ce44SJohn Forte int entries; 1674*fcf3ce44SJohn Forte char **entry; 1675*fcf3ce44SJohn Forte char *sha; 1676*fcf3ce44SJohn Forte char *buf; 1677*fcf3ce44SJohn Forte 1678*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 1679*fcf3ce44SJohn Forte rdc_err(NULL, 1680*fcf3ce44SJohn Forte gettext("error opening config")); 1681*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 1682*fcf3ce44SJohn Forte rdc_err(NULL, gettext("error locking config")); 1683*fcf3ce44SJohn Forte 1684*fcf3ce44SJohn Forte entry = NULL; 1685*fcf3ce44SJohn Forte entries = cfg_get_section(cfg, &entry, "ii"); 1686*fcf3ce44SJohn Forte for (i = 0; i < entries; i++) { 1687*fcf3ce44SJohn Forte buf = entry[i]; 1688*fcf3ce44SJohn Forte 1689*fcf3ce44SJohn Forte (void) strtok(buf, " "); /* master */ 1690*fcf3ce44SJohn Forte sha = strtok(NULL, " "); /* shadow */ 1691*fcf3ce44SJohn Forte if (strcmp(secondary, sha) == 0) { 1692*fcf3ce44SJohn Forte rdc_err(NULL, 1693*fcf3ce44SJohn Forte gettext("secondary %s is in use by" 1694*fcf3ce44SJohn Forte " Point-in-Time Copy"), secondary); 1695*fcf3ce44SJohn Forte } 1696*fcf3ce44SJohn Forte free(buf); 1697*fcf3ce44SJohn Forte } 1698*fcf3ce44SJohn Forte if (entries) 1699*fcf3ce44SJohn Forte free(entry); 1700*fcf3ce44SJohn Forte cfg_close(cfg); 1701*fcf3ce44SJohn Forte } 1702*fcf3ce44SJohn Forte 1703*fcf3ce44SJohn Forte int 1704*fcf3ce44SJohn Forte main(int argc, char *argv[]) 1705*fcf3ce44SJohn Forte { 1706*fcf3ce44SJohn Forte char config_file[FILENAME_MAX]; 1707*fcf3ce44SJohn Forte char fromhost[MAX_RDC_HOST_SIZE]; 1708*fcf3ce44SJohn Forte char tohost[MAX_RDC_HOST_SIZE]; 1709*fcf3ce44SJohn Forte char fromfile[NSC_MAXPATH]; 1710*fcf3ce44SJohn Forte char tofile[NSC_MAXPATH]; 1711*fcf3ce44SJohn Forte char frombitmap[NSC_MAXPATH]; 1712*fcf3ce44SJohn Forte char tobitmap[NSC_MAXPATH]; 1713*fcf3ce44SJohn Forte char directfile[NSC_MAXPATH]; 1714*fcf3ce44SJohn Forte char group[NSC_MAXPATH]; 1715*fcf3ce44SJohn Forte char ctag[MAX_RDC_HOST_SIZE]; 1716*fcf3ce44SJohn Forte char options_cfg[CFG_MAX_BUF]; 1717*fcf3ce44SJohn Forte char fromnetaddr[RDC_MAXADDR]; 1718*fcf3ce44SJohn Forte char tonetaddr[RDC_MAXADDR]; 1719*fcf3ce44SJohn Forte char tmphost[MAX_RDC_HOST_SIZE]; 1720*fcf3ce44SJohn Forte char tmpfile[NSC_MAXPATH]; 1721*fcf3ce44SJohn Forte char tmpbitmap[NSC_MAXPATH]; 1722*fcf3ce44SJohn Forte char diskqueue[NSC_MAXPATH]; 1723*fcf3ce44SJohn Forte char lhname[MAX_RDC_HOST_SIZE]; 1724*fcf3ce44SJohn Forte char mode[16]; 1725*fcf3ce44SJohn Forte rdc_version_t rdc_version; 1726*fcf3ce44SJohn Forte int pairs; 1727*fcf3ce44SJohn Forte int pid; 1728*fcf3ce44SJohn Forte int flag = 0; 1729*fcf3ce44SJohn Forte int fflag = 0; 1730*fcf3ce44SJohn Forte int reverse = 0; 1731*fcf3ce44SJohn Forte int nflag = 0; 1732*fcf3ce44SJohn Forte int iflag = 0; 1733*fcf3ce44SJohn Forte int doasync; 1734*fcf3ce44SJohn Forte int pflag = 0; 1735*fcf3ce44SJohn Forte int vflag = 0; 1736*fcf3ce44SJohn Forte int verbose = 0; 1737*fcf3ce44SJohn Forte int errflag = 0; 1738*fcf3ce44SJohn Forte int cfgflag = 0; 1739*fcf3ce44SJohn Forte int cfg_success; 1740*fcf3ce44SJohn Forte int Iflag = 0; 1741*fcf3ce44SJohn Forte char c; 1742*fcf3ce44SJohn Forte char inval = 0; 1743*fcf3ce44SJohn Forte int found; 1744*fcf3ce44SJohn Forte int rc; 1745*fcf3ce44SJohn Forte int geflag = 0; 1746*fcf3ce44SJohn Forte int qflag = 0; 1747*fcf3ce44SJohn Forte char *qarg; 1748*fcf3ce44SJohn Forte int Bflag = 0; 1749*fcf3ce44SJohn Forte char *bitfile; 1750*fcf3ce44SJohn Forte CFGFILE *cfg = NULL; 1751*fcf3ce44SJohn Forte int i; 1752*fcf3ce44SJohn Forte int setnumber; 1753*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1754*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1755*fcf3ce44SJohn Forte char ctag_arg[MAX_RDC_HOST_SIZE]; 1756*fcf3ce44SJohn Forte char group_arg[NSC_MAXPATH]; 1757*fcf3ce44SJohn Forte int file_format = 0; 1758*fcf3ce44SJohn Forte int sev; 1759*fcf3ce44SJohn Forte int diskq_group = DISKQ_OKAY; 1760*fcf3ce44SJohn Forte int extra_argc; 1761*fcf3ce44SJohn Forte char *ctag_p, *group_p, *diskqueue_p; 1762*fcf3ce44SJohn Forte char *required; 1763*fcf3ce44SJohn Forte char *role_env; 1764*fcf3ce44SJohn Forte int checksetfields = -1; 1765*fcf3ce44SJohn Forte nsc_off_t boffset = 0; 1766*fcf3ce44SJohn Forte int oflag = 0; 1767*fcf3ce44SJohn Forte rdcconfig_t *sets = NULL; 1768*fcf3ce44SJohn Forte rdcconfig_t *sets_p = NULL; 1769*fcf3ce44SJohn Forte rdc_rc_t *rclist = NULL; 1770*fcf3ce44SJohn Forte rdc_rc_t *rcp = NULL; 1771*fcf3ce44SJohn Forte int host_not_found = 0; 1772*fcf3ce44SJohn Forte 1773*fcf3ce44SJohn Forte (void) setlocale(LC_ALL, ""); 1774*fcf3ce44SJohn Forte (void) textdomain("rdc"); 1775*fcf3ce44SJohn Forte role_env = getenv("SNDR_ROLE_REVERSE"); 1776*fcf3ce44SJohn Forte if (role_env && strcmp(role_env, "sndr_allow_reverse") == 0) 1777*fcf3ce44SJohn Forte allow_role = 1; 1778*fcf3ce44SJohn Forte 1779*fcf3ce44SJohn Forte program = basename(argv[0]); 1780*fcf3ce44SJohn Forte 1781*fcf3ce44SJohn Forte rc = rdc_check_release(&required); 1782*fcf3ce44SJohn Forte if (rc < 0) { 1783*fcf3ce44SJohn Forte rdc_err(NULL, 1784*fcf3ce44SJohn Forte gettext("unable to determine the current " 1785*fcf3ce44SJohn Forte "Solaris release: %s\n"), strerror(errno)); 1786*fcf3ce44SJohn Forte } else if (rc == FALSE) { 1787*fcf3ce44SJohn Forte rdc_err(NULL, 1788*fcf3ce44SJohn Forte gettext("incorrect Solaris release (requires %s)\n"), 1789*fcf3ce44SJohn Forte required); 1790*fcf3ce44SJohn Forte } 1791*fcf3ce44SJohn Forte 1792*fcf3ce44SJohn Forte if ((clustered = cfg_iscluster()) < 0) { 1793*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to ascertain environment")); 1794*fcf3ce44SJohn Forte } 1795*fcf3ce44SJohn Forte 1796*fcf3ce44SJohn Forte strcpy(ctag_arg, ""); 1797*fcf3ce44SJohn Forte strcpy(group_arg, ""); 1798*fcf3ce44SJohn Forte bzero(ctag, MAX_RDC_HOST_SIZE); 1799*fcf3ce44SJohn Forte bzero(reconfig_ctag, MAX_RDC_HOST_SIZE); 1800*fcf3ce44SJohn Forte bzero(diskqueue, NSC_MAXPATH); 1801*fcf3ce44SJohn Forte 1802*fcf3ce44SJohn Forte rdc_maxsets = rdc_get_maxsets(); 1803*fcf3ce44SJohn Forte if (rdc_maxsets == -1) { 1804*fcf3ce44SJohn Forte rdc_err(NULL, 1805*fcf3ce44SJohn Forte gettext("unable to get maxsets value from kernel")); 1806*fcf3ce44SJohn Forte } 1807*fcf3ce44SJohn Forte 1808*fcf3ce44SJohn Forte pair_list = calloc(rdc_maxsets, sizeof (*pair_list)); 1809*fcf3ce44SJohn Forte if (pair_list == NULL) { 1810*fcf3ce44SJohn Forte rdc_err(NULL, 1811*fcf3ce44SJohn Forte gettext("unable to allocate pair_list array for %d sets"), 1812*fcf3ce44SJohn Forte rdc_maxsets); 1813*fcf3ce44SJohn Forte } 1814*fcf3ce44SJohn Forte 1815*fcf3ce44SJohn Forte bzero(group, sizeof (group)); 1816*fcf3ce44SJohn Forte bzero(diskqueue, sizeof (diskqueue)); 1817*fcf3ce44SJohn Forte qblock = 0; 1818*fcf3ce44SJohn Forte 1819*fcf3ce44SJohn Forte while ((c = 1820*fcf3ce44SJohn Forte #ifdef DEBUG 1821*fcf3ce44SJohn Forte getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw")) 1822*fcf3ce44SJohn Forte #else 1823*fcf3ce44SJohn Forte getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw")) 1824*fcf3ce44SJohn Forte #endif 1825*fcf3ce44SJohn Forte != -1) { 1826*fcf3ce44SJohn Forte switch (c) { 1827*fcf3ce44SJohn Forte case 'B': 1828*fcf3ce44SJohn Forte if (!allow_role || flag) { 1829*fcf3ce44SJohn Forte inval = 1; 1830*fcf3ce44SJohn Forte break; 1831*fcf3ce44SJohn Forte } 1832*fcf3ce44SJohn Forte bitfile = optarg; 1833*fcf3ce44SJohn Forte Bflag = 1; 1834*fcf3ce44SJohn Forte flag = RDC_BITMAPOP; 1835*fcf3ce44SJohn Forte break; 1836*fcf3ce44SJohn Forte case 'H': 1837*fcf3ce44SJohn Forte /* 'h' was already assigned */ 1838*fcf3ce44SJohn Forte if (flag) 1839*fcf3ce44SJohn Forte inval = 1; 1840*fcf3ce44SJohn Forte flag = RDC_CMD_HEALTH; 1841*fcf3ce44SJohn Forte break; 1842*fcf3ce44SJohn Forte case 'I': 1843*fcf3ce44SJohn Forte /* List or edit ndr_ii configuration entries */ 1844*fcf3ce44SJohn Forte Iflag = 1; 1845*fcf3ce44SJohn Forte break; 1846*fcf3ce44SJohn Forte case 'R': 1847*fcf3ce44SJohn Forte if (flag) 1848*fcf3ce44SJohn Forte inval = 1; 1849*fcf3ce44SJohn Forte flag = RDC_CMD_RECONFIG; 1850*fcf3ce44SJohn Forte break; 1851*fcf3ce44SJohn Forte #ifdef DEBUG 1852*fcf3ce44SJohn Forte case 'U': /* UDP support */ 1853*fcf3ce44SJohn Forte proto_test = 1; 1854*fcf3ce44SJohn Forte break; 1855*fcf3ce44SJohn Forte #endif 1856*fcf3ce44SJohn Forte case 'F': 1857*fcf3ce44SJohn Forte if (flag && flag != RDC_CMD_TUNABLE) 1858*fcf3ce44SJohn Forte inval = 1; 1859*fcf3ce44SJohn Forte flag = RDC_CMD_TUNABLE; 1860*fcf3ce44SJohn Forte 1861*fcf3ce44SJohn Forte if (check_intrange(optarg)) 1862*fcf3ce44SJohn Forte maxqfbas = atoi(optarg); 1863*fcf3ce44SJohn Forte else 1864*fcf3ce44SJohn Forte exit(1); 1865*fcf3ce44SJohn Forte 1866*fcf3ce44SJohn Forte break; 1867*fcf3ce44SJohn Forte case 'W': 1868*fcf3ce44SJohn Forte if (flag && flag != RDC_CMD_TUNABLE) 1869*fcf3ce44SJohn Forte inval = 1; 1870*fcf3ce44SJohn Forte flag = RDC_CMD_TUNABLE; 1871*fcf3ce44SJohn Forte 1872*fcf3ce44SJohn Forte if (check_intrange(optarg)) 1873*fcf3ce44SJohn Forte maxqitems = atoi(optarg); 1874*fcf3ce44SJohn Forte else 1875*fcf3ce44SJohn Forte exit(1); 1876*fcf3ce44SJohn Forte 1877*fcf3ce44SJohn Forte break; 1878*fcf3ce44SJohn Forte case 'A': 1879*fcf3ce44SJohn Forte if (flag && flag != RDC_CMD_TUNABLE) 1880*fcf3ce44SJohn Forte inval = 1; 1881*fcf3ce44SJohn Forte flag = RDC_CMD_TUNABLE; 1882*fcf3ce44SJohn Forte 1883*fcf3ce44SJohn Forte if (check_intrange(optarg)) 1884*fcf3ce44SJohn Forte asyncthr = atoi(optarg); 1885*fcf3ce44SJohn Forte else 1886*fcf3ce44SJohn Forte exit(1); 1887*fcf3ce44SJohn Forte 1888*fcf3ce44SJohn Forte break; 1889*fcf3ce44SJohn Forte case 'D': 1890*fcf3ce44SJohn Forte if (flag && flag != RDC_CMD_TUNABLE) 1891*fcf3ce44SJohn Forte inval = 1; 1892*fcf3ce44SJohn Forte flag = RDC_CMD_TUNABLE; 1893*fcf3ce44SJohn Forte 1894*fcf3ce44SJohn Forte if (set_qblock(optarg)) { 1895*fcf3ce44SJohn Forte usage(); 1896*fcf3ce44SJohn Forte exit(1); 1897*fcf3ce44SJohn Forte } 1898*fcf3ce44SJohn Forte iflag |= qblock; 1899*fcf3ce44SJohn Forte break; 1900*fcf3ce44SJohn Forte case 'a': 1901*fcf3ce44SJohn Forte if (flag && flag != RDC_CMD_TUNABLE) 1902*fcf3ce44SJohn Forte inval = 1; 1903*fcf3ce44SJohn Forte flag = RDC_CMD_TUNABLE; 1904*fcf3ce44SJohn Forte if (strcmp(optarg, "off") == 0) 1905*fcf3ce44SJohn Forte autosync = AUTOSYNC_OFF; 1906*fcf3ce44SJohn Forte else if (strcmp(optarg, "on") == 0) 1907*fcf3ce44SJohn Forte autosync = AUTOSYNC_ON; 1908*fcf3ce44SJohn Forte else 1909*fcf3ce44SJohn Forte inval = 1; 1910*fcf3ce44SJohn Forte break; 1911*fcf3ce44SJohn Forte case 'C': 1912*fcf3ce44SJohn Forte if (clustered) { 1913*fcf3ce44SJohn Forte strncpy(ctag_arg, optarg, MAX_RDC_HOST_SIZE); 1914*fcf3ce44SJohn Forte process_clocal(ctag_arg); 1915*fcf3ce44SJohn Forte } else 1916*fcf3ce44SJohn Forte inval = 1; 1917*fcf3ce44SJohn Forte break; 1918*fcf3ce44SJohn Forte case 'g': 1919*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE) 1920*fcf3ce44SJohn Forte inval = 1; 1921*fcf3ce44SJohn Forte geflag = 1; 1922*fcf3ce44SJohn Forte strncpy(group_arg, optarg, NSC_MAXPATH); 1923*fcf3ce44SJohn Forte verify_groupname(group_arg); 1924*fcf3ce44SJohn Forte break; 1925*fcf3ce44SJohn Forte case 'b': 1926*fcf3ce44SJohn Forte /* ignore */ 1927*fcf3ce44SJohn Forte break; 1928*fcf3ce44SJohn Forte case 'n': 1929*fcf3ce44SJohn Forte nflag = 1; 1930*fcf3ce44SJohn Forte break; 1931*fcf3ce44SJohn Forte case 'd': 1932*fcf3ce44SJohn Forte if (flag) 1933*fcf3ce44SJohn Forte inval = 1; 1934*fcf3ce44SJohn Forte flag = RDC_CMD_DISABLE; 1935*fcf3ce44SJohn Forte break; 1936*fcf3ce44SJohn Forte case 'e': 1937*fcf3ce44SJohn Forte if (flag || geflag) 1938*fcf3ce44SJohn Forte inval = 1; 1939*fcf3ce44SJohn Forte flag = RDC_CMD_ENABLE; 1940*fcf3ce44SJohn Forte iflag |= RDC_OPT_SETBMP; 1941*fcf3ce44SJohn Forte break; 1942*fcf3ce44SJohn Forte case 'E': 1943*fcf3ce44SJohn Forte if (flag) 1944*fcf3ce44SJohn Forte inval = 1; 1945*fcf3ce44SJohn Forte flag = RDC_CMD_ENABLE; 1946*fcf3ce44SJohn Forte iflag |= RDC_OPT_CLRBMP; 1947*fcf3ce44SJohn Forte break; 1948*fcf3ce44SJohn Forte case 'f': 1949*fcf3ce44SJohn Forte fflag = 1; 1950*fcf3ce44SJohn Forte strcpy(config_file, optarg); 1951*fcf3ce44SJohn Forte break; 1952*fcf3ce44SJohn Forte case 'h': 1953*fcf3ce44SJohn Forte usage(); 1954*fcf3ce44SJohn Forte exit(0); 1955*fcf3ce44SJohn Forte break; 1956*fcf3ce44SJohn Forte case 'l': 1957*fcf3ce44SJohn Forte if (flag) 1958*fcf3ce44SJohn Forte inval = 1; 1959*fcf3ce44SJohn Forte flag = RDC_CMD_LOG; 1960*fcf3ce44SJohn Forte break; 1961*fcf3ce44SJohn Forte case 'm': 1962*fcf3ce44SJohn Forte if (flag) 1963*fcf3ce44SJohn Forte inval = 1; 1964*fcf3ce44SJohn Forte flag = RDC_CMD_COPY; 1965*fcf3ce44SJohn Forte iflag |= RDC_OPT_FULL; 1966*fcf3ce44SJohn Forte break; 1967*fcf3ce44SJohn Forte case 'O': 1968*fcf3ce44SJohn Forte case 'o': 1969*fcf3ce44SJohn Forte 1970*fcf3ce44SJohn Forte if (!allow_role || oflag) { 1971*fcf3ce44SJohn Forte inval = 1; 1972*fcf3ce44SJohn Forte break; 1973*fcf3ce44SJohn Forte } 1974*fcf3ce44SJohn Forte if (c == 'o') { 1975*fcf3ce44SJohn Forte oflag = RDC_BITMAPOR; 1976*fcf3ce44SJohn Forte } else { 1977*fcf3ce44SJohn Forte oflag = RDC_BITMAPSET; 1978*fcf3ce44SJohn Forte } 1979*fcf3ce44SJohn Forte boffset = strtoull(optarg, NULL, 0); 1980*fcf3ce44SJohn Forte break; 1981*fcf3ce44SJohn Forte case 'P': 1982*fcf3ce44SJohn Forte if (flag) 1983*fcf3ce44SJohn Forte inval = 1; 1984*fcf3ce44SJohn Forte pflag = 1; 1985*fcf3ce44SJohn Forte verbose = 1; 1986*fcf3ce44SJohn Forte break; 1987*fcf3ce44SJohn Forte case 'p': 1988*fcf3ce44SJohn Forte if (flag) 1989*fcf3ce44SJohn Forte inval = 1; 1990*fcf3ce44SJohn Forte pflag = 1; 1991*fcf3ce44SJohn Forte break; 1992*fcf3ce44SJohn Forte case 'q': 1993*fcf3ce44SJohn Forte if (flag) 1994*fcf3ce44SJohn Forte inval = 1; 1995*fcf3ce44SJohn Forte flag = RDC_CMD_INITQ; 1996*fcf3ce44SJohn Forte qflag = optind; 1997*fcf3ce44SJohn Forte qarg = optarg; 1998*fcf3ce44SJohn Forte break; 1999*fcf3ce44SJohn Forte case 'i': 2000*fcf3ce44SJohn Forte if (flag) 2001*fcf3ce44SJohn Forte inval = 1; 2002*fcf3ce44SJohn Forte pflag = 1; 2003*fcf3ce44SJohn Forte file_format = 1; 2004*fcf3ce44SJohn Forte break; 2005*fcf3ce44SJohn Forte case 'r': 2006*fcf3ce44SJohn Forte reverse = 1; 2007*fcf3ce44SJohn Forte iflag |= RDC_OPT_REVERSE; 2008*fcf3ce44SJohn Forte break; 2009*fcf3ce44SJohn Forte case 's': 2010*fcf3ce44SJohn Forte if (flag) 2011*fcf3ce44SJohn Forte inval = 1; 2012*fcf3ce44SJohn Forte flag = RDC_CMD_STATUS; 2013*fcf3ce44SJohn Forte nflag = 1; /* No prompt for a status */ 2014*fcf3ce44SJohn Forte break; 2015*fcf3ce44SJohn Forte case 'u': 2016*fcf3ce44SJohn Forte if (flag) 2017*fcf3ce44SJohn Forte inval = 1; 2018*fcf3ce44SJohn Forte flag = RDC_CMD_COPY; 2019*fcf3ce44SJohn Forte iflag |= RDC_OPT_UPDATE; 2020*fcf3ce44SJohn Forte break; 2021*fcf3ce44SJohn Forte case 'v': 2022*fcf3ce44SJohn Forte if (flag) 2023*fcf3ce44SJohn Forte inval = 1; 2024*fcf3ce44SJohn Forte pflag = 1; 2025*fcf3ce44SJohn Forte vflag = 1; 2026*fcf3ce44SJohn Forte break; 2027*fcf3ce44SJohn Forte case 'w': 2028*fcf3ce44SJohn Forte if (flag) 2029*fcf3ce44SJohn Forte inval = 1; 2030*fcf3ce44SJohn Forte flag = RDC_CMD_WAIT; 2031*fcf3ce44SJohn Forte break; 2032*fcf3ce44SJohn Forte case '?': 2033*fcf3ce44SJohn Forte errflag++; 2034*fcf3ce44SJohn Forte } 2035*fcf3ce44SJohn Forte } 2036*fcf3ce44SJohn Forte 2037*fcf3ce44SJohn Forte if (inval || ((flag != RDC_BITMAPOP) && oflag)) { 2038*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("invalid argument combination")); 2039*fcf3ce44SJohn Forte errflag = 1; 2040*fcf3ce44SJohn Forte } 2041*fcf3ce44SJohn Forte 2042*fcf3ce44SJohn Forte if (flag && Iflag) { 2043*fcf3ce44SJohn Forte /* Mutually incompatible */ 2044*fcf3ce44SJohn Forte usage(); 2045*fcf3ce44SJohn Forte exit(1); 2046*fcf3ce44SJohn Forte } 2047*fcf3ce44SJohn Forte 2048*fcf3ce44SJohn Forte if (Iflag) { 2049*fcf3ce44SJohn Forte rdc_ii_config(argc, argv); 2050*fcf3ce44SJohn Forte exit(0); 2051*fcf3ce44SJohn Forte } 2052*fcf3ce44SJohn Forte 2053*fcf3ce44SJohn Forte if (vflag) { 2054*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 2055*fcf3ce44SJohn Forte 2056*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 2057*fcf3ce44SJohn Forte rc = RDC_IOCTL(RDC_VERSION, &rdc_version, 0, 0, 0, 0, ustatus); 2058*fcf3ce44SJohn Forte if (rc == SPCS_S_ERROR) { 2059*fcf3ce44SJohn Forte rdc_err(&ustatus, gettext("statistics error")); 2060*fcf3ce44SJohn Forte } 2061*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 2062*fcf3ce44SJohn Forte #ifdef DEBUG 2063*fcf3ce44SJohn Forte (void) printf(gettext("Remote Mirror version %d.%d.%d.%d\n"), 2064*fcf3ce44SJohn Forte rdc_version.major, rdc_version.minor, 2065*fcf3ce44SJohn Forte rdc_version.micro, rdc_version.baseline); 2066*fcf3ce44SJohn Forte #else 2067*fcf3ce44SJohn Forte if (rdc_version.micro) { 2068*fcf3ce44SJohn Forte (void) printf(gettext( 2069*fcf3ce44SJohn Forte "Remote Mirror version %d.%d.%d\n"), 2070*fcf3ce44SJohn Forte rdc_version.major, 2071*fcf3ce44SJohn Forte rdc_version.minor, 2072*fcf3ce44SJohn Forte rdc_version.micro); 2073*fcf3ce44SJohn Forte } else { 2074*fcf3ce44SJohn Forte (void) printf(gettext("Remote Mirror version %d.%d\n"), 2075*fcf3ce44SJohn Forte rdc_version.major, rdc_version.minor); 2076*fcf3ce44SJohn Forte } 2077*fcf3ce44SJohn Forte #endif 2078*fcf3ce44SJohn Forte exit(0); 2079*fcf3ce44SJohn Forte } 2080*fcf3ce44SJohn Forte 2081*fcf3ce44SJohn Forte if (!(flag || pflag) || errflag) { 2082*fcf3ce44SJohn Forte usage(); 2083*fcf3ce44SJohn Forte exit(1); 2084*fcf3ce44SJohn Forte } 2085*fcf3ce44SJohn Forte 2086*fcf3ce44SJohn Forte if (pflag && !fflag && (argc - optind) == 0) { 2087*fcf3ce44SJohn Forte /* print with no set specified */ 2088*fcf3ce44SJohn Forte exit(rdc_print(file_format, verbose, 2089*fcf3ce44SJohn Forte group_arg, ctag_arg, NULL, NULL, NULL)); 2090*fcf3ce44SJohn Forte } 2091*fcf3ce44SJohn Forte 2092*fcf3ce44SJohn Forte if (qflag) { /* change disk queue setting */ 2093*fcf3ce44SJohn Forte int subcmd = 0; 2094*fcf3ce44SJohn Forte int offset = 0; 2095*fcf3ce44SJohn Forte char *ptr; 2096*fcf3ce44SJohn Forte char *qvol; 2097*fcf3ce44SJohn Forte char tohost_arg[MAX_RDC_HOST_SIZE]; 2098*fcf3ce44SJohn Forte char tofile_arg[NSC_MAXPATH]; 2099*fcf3ce44SJohn Forte 2100*fcf3ce44SJohn Forte if (strcmp("a", qarg) == 0) { 2101*fcf3ce44SJohn Forte subcmd = RDC_CMD_ADDQ; 2102*fcf3ce44SJohn Forte offset = 1; 2103*fcf3ce44SJohn Forte } else if (strcmp("d", qarg) == 0) { 2104*fcf3ce44SJohn Forte subcmd = RDC_CMD_REMQ; 2105*fcf3ce44SJohn Forte offset = 0; 2106*fcf3ce44SJohn Forte } else if (strcmp("r", qarg) == 0) { 2107*fcf3ce44SJohn Forte subcmd = RDC_CMD_REPQ; 2108*fcf3ce44SJohn Forte offset = 1; 2109*fcf3ce44SJohn Forte } else { 2110*fcf3ce44SJohn Forte rdc_warn(NULL, " %s Invalid qopt", qarg); 2111*fcf3ce44SJohn Forte q_usage(1); 2112*fcf3ce44SJohn Forte exit(1); 2113*fcf3ce44SJohn Forte } 2114*fcf3ce44SJohn Forte if (strlen(group_arg) == 0) { 2115*fcf3ce44SJohn Forte /* pick out single set as shost:svol */ 2116*fcf3ce44SJohn Forte ptr = strtok(argv[qflag + offset], ":"); 2117*fcf3ce44SJohn Forte if (ptr) 2118*fcf3ce44SJohn Forte strncpy(tohost_arg, ptr, MAX_RDC_HOST_SIZE); 2119*fcf3ce44SJohn Forte else { 2120*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Bad host specified")); 2121*fcf3ce44SJohn Forte q_usage(1); 2122*fcf3ce44SJohn Forte exit(1); 2123*fcf3ce44SJohn Forte } 2124*fcf3ce44SJohn Forte ptr = strtok(NULL, ":"); 2125*fcf3ce44SJohn Forte if (ptr) 2126*fcf3ce44SJohn Forte strncpy(tofile_arg, ptr, NSC_MAXPATH); 2127*fcf3ce44SJohn Forte else { 2128*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Bad set specified")); 2129*fcf3ce44SJohn Forte q_usage(1); 2130*fcf3ce44SJohn Forte exit(1); 2131*fcf3ce44SJohn Forte } 2132*fcf3ce44SJohn Forte } 2133*fcf3ce44SJohn Forte 2134*fcf3ce44SJohn Forte qvol = argv[qflag]; 2135*fcf3ce44SJohn Forte if ((qvol == NULL) && (subcmd != RDC_CMD_REMQ)) { 2136*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("missing queue volume")); 2137*fcf3ce44SJohn Forte q_usage(1); 2138*fcf3ce44SJohn Forte exit(1); 2139*fcf3ce44SJohn Forte } 2140*fcf3ce44SJohn Forte diskq_subcmd(subcmd, qvol, group_arg, ctag_arg, 2141*fcf3ce44SJohn Forte tohost_arg, tofile_arg); 2142*fcf3ce44SJohn Forte exit(0); 2143*fcf3ce44SJohn Forte } 2144*fcf3ce44SJohn Forte 2145*fcf3ce44SJohn Forte if (flag == RDC_CMD_RECONFIG && !fflag) { 2146*fcf3ce44SJohn Forte /* See what is to be reconfigured */ 2147*fcf3ce44SJohn Forte if (argc - optind == 0) 2148*fcf3ce44SJohn Forte flag = RDC_CMD_RESET; 2149*fcf3ce44SJohn Forte else { 2150*fcf3ce44SJohn Forte if (argc - optind < 2) { 2151*fcf3ce44SJohn Forte usage(); 2152*fcf3ce44SJohn Forte exit(1); 2153*fcf3ce44SJohn Forte } 2154*fcf3ce44SJohn Forte c = *argv[optind++]; 2155*fcf3ce44SJohn Forte if (argv[optind -1][1] != '\0') { 2156*fcf3ce44SJohn Forte usage(); 2157*fcf3ce44SJohn Forte exit(2); 2158*fcf3ce44SJohn Forte } 2159*fcf3ce44SJohn Forte switch (c) { 2160*fcf3ce44SJohn Forte case 'b': 2161*fcf3ce44SJohn Forte if (argc - optind < 2) { 2162*fcf3ce44SJohn Forte usage(); 2163*fcf3ce44SJohn Forte exit(1); 2164*fcf3ce44SJohn Forte } 2165*fcf3ce44SJohn Forte if (*argv[optind] == 'p') 2166*fcf3ce44SJohn Forte reconfig_pbitmap = argv[++optind]; 2167*fcf3ce44SJohn Forte else if (*argv[optind] == 's') 2168*fcf3ce44SJohn Forte reconfig_sbitmap = argv[++optind]; 2169*fcf3ce44SJohn Forte else { 2170*fcf3ce44SJohn Forte usage(); 2171*fcf3ce44SJohn Forte exit(1); 2172*fcf3ce44SJohn Forte } 2173*fcf3ce44SJohn Forte optind++; 2174*fcf3ce44SJohn Forte break; 2175*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 2176*fcf3ce44SJohn Forte case 'd': 2177*fcf3ce44SJohn Forte reconfig_direct = argv[optind++]; 2178*fcf3ce44SJohn Forte break; 2179*fcf3ce44SJohn Forte #endif 2180*fcf3ce44SJohn Forte case 'g': 2181*fcf3ce44SJohn Forte reconfig_group = argv[optind++]; 2182*fcf3ce44SJohn Forte verify_groupname(reconfig_group); 2183*fcf3ce44SJohn Forte break; 2184*fcf3ce44SJohn Forte case 'C': 2185*fcf3ce44SJohn Forte if (clustered) { 2186*fcf3ce44SJohn Forte strncpy(reconfig_ctag, argv[optind++], 2187*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 2188*fcf3ce44SJohn Forte process_clocal(reconfig_ctag); 2189*fcf3ce44SJohn Forte } else { 2190*fcf3ce44SJohn Forte usage(); 2191*fcf3ce44SJohn Forte exit(1); 2192*fcf3ce44SJohn Forte } 2193*fcf3ce44SJohn Forte break; 2194*fcf3ce44SJohn Forte case 'm': 2195*fcf3ce44SJohn Forte if (strcmp(argv[optind], "sync") == 0) 2196*fcf3ce44SJohn Forte reconfig_doasync = 0; 2197*fcf3ce44SJohn Forte else if (strcmp(argv[optind], "async") == 0) 2198*fcf3ce44SJohn Forte reconfig_doasync = 1; 2199*fcf3ce44SJohn Forte else { 2200*fcf3ce44SJohn Forte usage(); 2201*fcf3ce44SJohn Forte exit(1); 2202*fcf3ce44SJohn Forte } 2203*fcf3ce44SJohn Forte optind++; 2204*fcf3ce44SJohn Forte break; 2205*fcf3ce44SJohn Forte case 'r': 2206*fcf3ce44SJohn Forte if (allow_role) { 2207*fcf3ce44SJohn Forte iflag |= RDC_OPT_REVERSE_ROLE; 2208*fcf3ce44SJohn Forte break; 2209*fcf3ce44SJohn Forte } 2210*fcf3ce44SJohn Forte default: 2211*fcf3ce44SJohn Forte usage(); 2212*fcf3ce44SJohn Forte exit(1); 2213*fcf3ce44SJohn Forte } 2214*fcf3ce44SJohn Forte } 2215*fcf3ce44SJohn Forte } 2216*fcf3ce44SJohn Forte if (fflag) { 2217*fcf3ce44SJohn Forte checksetfields = 1; 2218*fcf3ce44SJohn Forte if ((argc - optind) != 0) { 2219*fcf3ce44SJohn Forte usage(); 2220*fcf3ce44SJohn Forte exit(1); 2221*fcf3ce44SJohn Forte } 2222*fcf3ce44SJohn Forte } else { 2223*fcf3ce44SJohn Forte if ((argc - optind) == 0) { 2224*fcf3ce44SJohn Forte /* Use libcfg to figure out what to operate on */ 2225*fcf3ce44SJohn Forte cfgflag = 1; 2226*fcf3ce44SJohn Forte #ifdef DEBUG 2227*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("using current config")); 2228*fcf3ce44SJohn Forte #endif 2229*fcf3ce44SJohn Forte checksetfields = 0; 2230*fcf3ce44SJohn Forte } else { 2231*fcf3ce44SJohn Forte if ((argc - optind) < 8 && (argc - optind) != 1) { 2232*fcf3ce44SJohn Forte usage(); 2233*fcf3ce44SJohn Forte exit(1); 2234*fcf3ce44SJohn Forte } 2235*fcf3ce44SJohn Forte } 2236*fcf3ce44SJohn Forte } 2237*fcf3ce44SJohn Forte 2238*fcf3ce44SJohn Forte if (cfgflag) { 2239*fcf3ce44SJohn Forte if (flag == RDC_CMD_ADDQ || 2240*fcf3ce44SJohn Forte flag == RDC_CMD_REMQ || 2241*fcf3ce44SJohn Forte flag == RDC_CMD_KILLQ || 2242*fcf3ce44SJohn Forte flag == RDC_CMD_INITQ) { 2243*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not use current config " 2244*fcf3ce44SJohn Forte "for disk queue operations")); 2245*fcf3ce44SJohn Forte } 2246*fcf3ce44SJohn Forte } else if (fflag) { 2247*fcf3ce44SJohn Forte if (flag == RDC_CMD_ADDQ || 2248*fcf3ce44SJohn Forte flag == RDC_CMD_REMQ || 2249*fcf3ce44SJohn Forte flag == RDC_CMD_KILLQ || 2250*fcf3ce44SJohn Forte flag == RDC_CMD_INITQ) { 2251*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not use a config file " 2252*fcf3ce44SJohn Forte "for disk queue operations")); 2253*fcf3ce44SJohn Forte } 2254*fcf3ce44SJohn Forte } 2255*fcf3ce44SJohn Forte if (cfgflag) { 2256*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE) { 2257*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not use current config " 2258*fcf3ce44SJohn Forte "for enable command")); 2259*fcf3ce44SJohn Forte } 2260*fcf3ce44SJohn Forte if ((flag == RDC_CMD_RECONFIG) && (reconfig_pbitmap || 2261*fcf3ce44SJohn Forte reconfig_sbitmap)) { 2262*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not use current config " 2263*fcf3ce44SJohn Forte "for bitmap reconfiguration")); 2264*fcf3ce44SJohn Forte } 2265*fcf3ce44SJohn Forte if (flag == RDC_BITMAPOP) { 2266*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not use current config " 2267*fcf3ce44SJohn Forte "for bitmap set command")); 2268*fcf3ce44SJohn Forte } 2269*fcf3ce44SJohn Forte pairs = read_libcfg(flag, group_arg, ctag_arg); 2270*fcf3ce44SJohn Forte if (pairs == 0) { 2271*fcf3ce44SJohn Forte (void) fprintf(stderr, 2272*fcf3ce44SJohn Forte gettext("no matching Remote Mirror sets found " 2273*fcf3ce44SJohn Forte "in config\n")); 2274*fcf3ce44SJohn Forte exit(1); 2275*fcf3ce44SJohn Forte } 2276*fcf3ce44SJohn Forte } else if (!fflag) { 2277*fcf3ce44SJohn Forte /* 2278*fcf3ce44SJohn Forte * Format is either: 2279*fcf3ce44SJohn Forte * 2280*fcf3ce44SJohn Forte * tohost:tofile 2281*fcf3ce44SJohn Forte * 2282*fcf3ce44SJohn Forte * or something like this for example: 2283*fcf3ce44SJohn Forte * 2284*fcf3ce44SJohn Forte * fromhost fromfile frombitmap tohost tofile tobitmap ip sync 2285*fcf3ce44SJohn Forte * g group C ctag 2286*fcf3ce44SJohn Forte */ 2287*fcf3ce44SJohn Forte 2288*fcf3ce44SJohn Forte if (argc - optind == 1) { 2289*fcf3ce44SJohn Forte char tohost_arg[MAX_RDC_HOST_SIZE]; 2290*fcf3ce44SJohn Forte char tofile_arg[NSC_MAXPATH]; 2291*fcf3ce44SJohn Forte char *ptr; 2292*fcf3ce44SJohn Forte 2293*fcf3ce44SJohn Forte checksetfields = 0; 2294*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE) { 2295*fcf3ce44SJohn Forte rdc_err(NULL, 2296*fcf3ce44SJohn Forte gettext("must specify full set details for " 2297*fcf3ce44SJohn Forte "enable command")); 2298*fcf3ce44SJohn Forte } 2299*fcf3ce44SJohn Forte ptr = strtok(argv[optind], ":"); 2300*fcf3ce44SJohn Forte if (ptr) 2301*fcf3ce44SJohn Forte strncpy(tohost_arg, ptr, MAX_RDC_HOST_SIZE); 2302*fcf3ce44SJohn Forte else { 2303*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Bad host specified")); 2304*fcf3ce44SJohn Forte } 2305*fcf3ce44SJohn Forte ptr = strtok(NULL, ":"); 2306*fcf3ce44SJohn Forte if (ptr) 2307*fcf3ce44SJohn Forte strncpy(tofile_arg, ptr, NSC_MAXPATH); 2308*fcf3ce44SJohn Forte else { 2309*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Bad set specified")); 2310*fcf3ce44SJohn Forte } 2311*fcf3ce44SJohn Forte 2312*fcf3ce44SJohn Forte /* Now look up tohost:tofile via libcfg */ 2313*fcf3ce44SJohn Forte 2314*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 2315*fcf3ce44SJohn Forte rdc_err(NULL, 2316*fcf3ce44SJohn Forte gettext("unable to access configuration")); 2317*fcf3ce44SJohn Forte 2318*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 2319*fcf3ce44SJohn Forte rdc_err(NULL, 2320*fcf3ce44SJohn Forte gettext("unable to lock configuration")); 2321*fcf3ce44SJohn Forte 2322*fcf3ce44SJohn Forte setnumber = 0; 2323*fcf3ce44SJohn Forte found = 0; 2324*fcf3ce44SJohn Forte /*CSTYLED*/ 2325*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets;) { 2326*fcf3ce44SJohn Forte setnumber++; 2327*fcf3ce44SJohn Forte 2328*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 2329*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2330*fcf3ce44SJohn Forte "sndr.set%d", setnumber); 2331*fcf3ce44SJohn Forte rc = cfg_get_cstring(cfg, key, buf, 2332*fcf3ce44SJohn Forte CFG_MAX_BUF); 2333*fcf3ce44SJohn Forte if (rc < 0) 2334*fcf3ce44SJohn Forte break; 2335*fcf3ce44SJohn Forte 2336*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2337*fcf3ce44SJohn Forte "sndr.set%d.shost", setnumber); 2338*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, tohost, 2339*fcf3ce44SJohn Forte sizeof (tohost)); 2340*fcf3ce44SJohn Forte if (strncmp(tohost, tohost_arg, NSC_MAXPATH)) 2341*fcf3ce44SJohn Forte continue; 2342*fcf3ce44SJohn Forte 2343*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2344*fcf3ce44SJohn Forte "sndr.set%d.secondary", setnumber); 2345*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, tofile, 2346*fcf3ce44SJohn Forte sizeof (tofile)); 2347*fcf3ce44SJohn Forte if (strncmp(tofile, tofile_arg, NSC_MAXPATH)) 2348*fcf3ce44SJohn Forte continue; 2349*fcf3ce44SJohn Forte 2350*fcf3ce44SJohn Forte found = 1; 2351*fcf3ce44SJohn Forte 2352*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2353*fcf3ce44SJohn Forte "sndr.set%d.phost", setnumber); 2354*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, fromhost, 2355*fcf3ce44SJohn Forte sizeof (fromhost)); 2356*fcf3ce44SJohn Forte 2357*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2358*fcf3ce44SJohn Forte "sndr.set%d.primary", setnumber); 2359*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, fromfile, 2360*fcf3ce44SJohn Forte sizeof (fromfile)); 2361*fcf3ce44SJohn Forte 2362*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2363*fcf3ce44SJohn Forte "sndr.set%d.pbitmap", setnumber); 2364*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, frombitmap, 2365*fcf3ce44SJohn Forte sizeof (frombitmap)); 2366*fcf3ce44SJohn Forte 2367*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2368*fcf3ce44SJohn Forte "sndr.set%d.sbitmap", setnumber); 2369*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, tobitmap, 2370*fcf3ce44SJohn Forte sizeof (tobitmap)); 2371*fcf3ce44SJohn Forte 2372*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2373*fcf3ce44SJohn Forte "sndr.set%d.type", setnumber); 2374*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, directfile, 2375*fcf3ce44SJohn Forte sizeof (directfile)); 2376*fcf3ce44SJohn Forte if (strcmp(directfile, "ip") == 0) 2377*fcf3ce44SJohn Forte strcpy(directfile, ""); 2378*fcf3ce44SJohn Forte 2379*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2380*fcf3ce44SJohn Forte "sndr.set%d.mode", setnumber); 2381*fcf3ce44SJohn Forte (void) cfg_get_cstring( 2382*fcf3ce44SJohn Forte cfg, key, mode, sizeof (mode)); 2383*fcf3ce44SJohn Forte 2384*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2385*fcf3ce44SJohn Forte "sndr.set%d.group", setnumber); 2386*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, group, 2387*fcf3ce44SJohn Forte sizeof (group)); 2388*fcf3ce44SJohn Forte if (strcmp(group_arg, "") && 2389*fcf3ce44SJohn Forte strncmp(group_arg, group, NSC_MAXPATH)) 2390*fcf3ce44SJohn Forte continue; 2391*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2392*fcf3ce44SJohn Forte "sndr.set%d.cnode", setnumber); 2393*fcf3ce44SJohn Forte (void) cfg_get_cstring( 2394*fcf3ce44SJohn Forte cfg, key, ctag, sizeof (ctag)); 2395*fcf3ce44SJohn Forte if ((strlen(ctag_arg) > 0) && 2396*fcf3ce44SJohn Forte (strcmp(ctag_arg, ctag) != 0)) 2397*fcf3ce44SJohn Forte rdc_err(NULL, 2398*fcf3ce44SJohn Forte gettext("ctags %s and %s " 2399*fcf3ce44SJohn Forte "do not match"), ctag_arg, ctag); 2400*fcf3ce44SJohn Forte 2401*fcf3ce44SJohn Forte if (strcmp(mode, "sync") == 0) 2402*fcf3ce44SJohn Forte doasync = 0; 2403*fcf3ce44SJohn Forte else if (strcmp(mode, "async") == 0) 2404*fcf3ce44SJohn Forte doasync = 1; 2405*fcf3ce44SJohn Forte else { 2406*fcf3ce44SJohn Forte rdc_err(NULL, 2407*fcf3ce44SJohn Forte gettext("set %s:%s neither sync " 2408*fcf3ce44SJohn Forte "nor async"), tohost, tofile); 2409*fcf3ce44SJohn Forte } 2410*fcf3ce44SJohn Forte break; 2411*fcf3ce44SJohn Forte } 2412*fcf3ce44SJohn Forte cfg_close(cfg); 2413*fcf3ce44SJohn Forte if (!found) { 2414*fcf3ce44SJohn Forte rdc_err(NULL, 2415*fcf3ce44SJohn Forte gettext("set %s:%s not found in config"), 2416*fcf3ce44SJohn Forte tohost_arg, tofile_arg); 2417*fcf3ce44SJohn Forte } 2418*fcf3ce44SJohn Forte } else { 2419*fcf3ce44SJohn Forte checksetfields = 1; 2420*fcf3ce44SJohn Forte strncpy(fromhost, argv[optind], MAX_RDC_HOST_SIZE); 2421*fcf3ce44SJohn Forte strncpy(fromfile, argv[optind+1], NSC_MAXPATH); 2422*fcf3ce44SJohn Forte strncpy(frombitmap, argv[optind+2], NSC_MAXPATH); 2423*fcf3ce44SJohn Forte strncpy(tohost, argv[optind+3], MAX_RDC_HOST_SIZE); 2424*fcf3ce44SJohn Forte strncpy(tofile, argv[optind+4], NSC_MAXPATH); 2425*fcf3ce44SJohn Forte strncpy(tobitmap, argv[optind+5], NSC_MAXPATH); 2426*fcf3ce44SJohn Forte 2427*fcf3ce44SJohn Forte /* Check the length of entries from the command line */ 2428*fcf3ce44SJohn Forte if ((fromhost[MAX_RDC_HOST_SIZE - 1] != '\0') || 2429*fcf3ce44SJohn Forte (tohost[MAX_RDC_HOST_SIZE - 1] != '\0')) { 2430*fcf3ce44SJohn Forte rdc_err(NULL, 2431*fcf3ce44SJohn Forte gettext("hostname is longer than %d " 2432*fcf3ce44SJohn Forte "characters\n"), (MAX_RDC_HOST_SIZE - 1)); 2433*fcf3ce44SJohn Forte } 2434*fcf3ce44SJohn Forte 2435*fcf3ce44SJohn Forte /* Check if it's ip address -- not allowed */ 2436*fcf3ce44SJohn Forte if ((inet_addr(fromhost) != (in_addr_t)(-1)) || 2437*fcf3ce44SJohn Forte (inet_addr(tohost) != (in_addr_t)(-1))) { 2438*fcf3ce44SJohn Forte rdc_err(NULL, gettext( 2439*fcf3ce44SJohn Forte "The hostname specified is invalid.\n" 2440*fcf3ce44SJohn Forte "See 'man inet(3SOCKET)'")); 2441*fcf3ce44SJohn Forte } 2442*fcf3ce44SJohn Forte 2443*fcf3ce44SJohn Forte if ((fromfile[NSC_MAXPATH - 1] != '\0') || 2444*fcf3ce44SJohn Forte (tofile[NSC_MAXPATH - 1] != '\0') || 2445*fcf3ce44SJohn Forte (frombitmap[NSC_MAXPATH - 1] != '\0') || 2446*fcf3ce44SJohn Forte (tobitmap[NSC_MAXPATH - 1] != '\0')) { 2447*fcf3ce44SJohn Forte rdc_err(NULL, gettext("device name is longer " 2448*fcf3ce44SJohn Forte "than %d characters\n"), (NSC_MAXPATH - 1)); 2449*fcf3ce44SJohn Forte } 2450*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 2451*fcf3ce44SJohn Forte if (argv[optind+6][0] == '/') { 2452*fcf3ce44SJohn Forte /* FCAL directio */ 2453*fcf3ce44SJohn Forte strncpy(directfile, argv[optind+6], 2454*fcf3ce44SJohn Forte NSC_MAXPATH); 2455*fcf3ce44SJohn Forte } else if (strcmp(argv[optind+6], "ip") != 0) { 2456*fcf3ce44SJohn Forte #else 2457*fcf3ce44SJohn Forte if (strcmp(argv[optind+6], "ip") != 0) { 2458*fcf3ce44SJohn Forte #endif 2459*fcf3ce44SJohn Forte usage(); 2460*fcf3ce44SJohn Forte exit(1); 2461*fcf3ce44SJohn Forte } else 2462*fcf3ce44SJohn Forte strcpy(directfile, "ip"); 2463*fcf3ce44SJohn Forte 2464*fcf3ce44SJohn Forte if (strcmp(argv[optind+7], "sync") == 0) 2465*fcf3ce44SJohn Forte doasync = 0; 2466*fcf3ce44SJohn Forte else if (strcmp(argv[optind+7], "async") == 0) 2467*fcf3ce44SJohn Forte doasync = 1; 2468*fcf3ce44SJohn Forte else { 2469*fcf3ce44SJohn Forte usage(); 2470*fcf3ce44SJohn Forte exit(1); 2471*fcf3ce44SJohn Forte } 2472*fcf3ce44SJohn Forte 2473*fcf3ce44SJohn Forte /* 2474*fcf3ce44SJohn Forte * At this point, we could have a set which is 2475*fcf3ce44SJohn Forte * clustered, but neither a 'C ctag' or '-C ctag' has 2476*fcf3ce44SJohn Forte * been specified. To avoid clobbering the ctag if a 2477*fcf3ce44SJohn Forte * dscfg operation is done in the future, we should get 2478*fcf3ce44SJohn Forte * the ctag out of the config at this point. To do this, 2479*fcf3ce44SJohn Forte * set the cluster resource filter to NULL to look at 2480*fcf3ce44SJohn Forte * all sets in the config, pulling out the ctag for the 2481*fcf3ce44SJohn Forte * set matching shost:svol. If the set is not found, 2482*fcf3ce44SJohn Forte * fail here. Note, we skip this set on an enable as the 2483*fcf3ce44SJohn Forte * set is not yet in the config, so no need to waste 2484*fcf3ce44SJohn Forte * time. 2485*fcf3ce44SJohn Forte */ 2486*fcf3ce44SJohn Forte if ((argc - optind == 8) && clustered && 2487*fcf3ce44SJohn Forte (flag != RDC_CMD_ENABLE)) { 2488*fcf3ce44SJohn Forte int setnumber; 2489*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 2490*fcf3ce44SJohn Forte 2491*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 2492*fcf3ce44SJohn Forte rdc_err(NULL, 2493*fcf3ce44SJohn Forte gettext("unable to access configuration")); 2494*fcf3ce44SJohn Forte } 2495*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) { 2496*fcf3ce44SJohn Forte rdc_err(NULL, 2497*fcf3ce44SJohn Forte gettext("unable to lock configuration")); 2498*fcf3ce44SJohn Forte } 2499*fcf3ce44SJohn Forte 2500*fcf3ce44SJohn Forte cfg_resource(cfg, NULL); 2501*fcf3ce44SJohn Forte 2502*fcf3ce44SJohn Forte if ((setnumber = 2503*fcf3ce44SJohn Forte find_setnumber_in_libcfg(cfg, NULL, tohost, 2504*fcf3ce44SJohn Forte tofile)) < 0) { 2505*fcf3ce44SJohn Forte cfg_close(cfg); 2506*fcf3ce44SJohn Forte rdc_err(NULL, 2507*fcf3ce44SJohn Forte gettext("unable to find Remote " 2508*fcf3ce44SJohn Forte "Mirror set " 2509*fcf3ce44SJohn Forte "%s:%s in config"), 2510*fcf3ce44SJohn Forte tohost, tofile); 2511*fcf3ce44SJohn Forte } 2512*fcf3ce44SJohn Forte 2513*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2514*fcf3ce44SJohn Forte "sndr.set%d.cnode", setnumber); 2515*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, ctag_arg, 2516*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE) < 0) { 2517*fcf3ce44SJohn Forte cfg_close(cfg); 2518*fcf3ce44SJohn Forte rdc_err(NULL, 2519*fcf3ce44SJohn Forte gettext("unable to determine ctag " 2520*fcf3ce44SJohn Forte "for Remote Mirror set %s:%s"), 2521*fcf3ce44SJohn Forte tohost, tofile); 2522*fcf3ce44SJohn Forte } 2523*fcf3ce44SJohn Forte 2524*fcf3ce44SJohn Forte rdc_islocal = strcmp(ctag_arg, "-") ? 0 : 1; 2525*fcf3ce44SJohn Forte 2526*fcf3ce44SJohn Forte cfg_close(cfg); 2527*fcf3ce44SJohn Forte } 2528*fcf3ce44SJohn Forte 2529*fcf3ce44SJohn Forte extra_argc = argc - optind; 2530*fcf3ce44SJohn Forte if (extra_argc < 8 || extra_argc > 14 || 2531*fcf3ce44SJohn Forte extra_argc % 2 != 0) { 2532*fcf3ce44SJohn Forte usage(); 2533*fcf3ce44SJohn Forte exit(1); 2534*fcf3ce44SJohn Forte } 2535*fcf3ce44SJohn Forte 2536*fcf3ce44SJohn Forte /* 2537*fcf3ce44SJohn Forte * Loop through all of the extra arguments specified 2538*fcf3ce44SJohn Forte * on the command line, setting the appropriate values 2539*fcf3ce44SJohn Forte * for valid entries. If an unrecognized argument is 2540*fcf3ce44SJohn Forte * detected, abort with error. Note: This hack should be 2541*fcf3ce44SJohn Forte * removed and we should not accept these entries as 2542*fcf3ce44SJohn Forte * arguments, they should be passed in as switches. 2543*fcf3ce44SJohn Forte */ 2544*fcf3ce44SJohn Forte for (i = (8 + optind); i < argc; i += 2) { 2545*fcf3ce44SJohn Forte /* string case statement */ 2546*fcf3ce44SJohn Forte if (strcmp(argv[i], "g") == 0) { 2547*fcf3ce44SJohn Forte strncpy(group, argv[i + 1], NSC_MAXPATH); 2548*fcf3ce44SJohn Forte if (group[NSC_MAXPATH - 1] != '\0') { 2549*fcf3ce44SJohn Forte rdc_err(NULL, gettext("group name is " 2550*fcf3ce44SJohn Forte "longer than %d characters\n"), 2551*fcf3ce44SJohn Forte (NSC_MAXPATH - 1)); 2552*fcf3ce44SJohn Forte } 2553*fcf3ce44SJohn Forte } else if (strcmp(argv[i], "C") == 0) { 2554*fcf3ce44SJohn Forte if (!clustered) { 2555*fcf3ce44SJohn Forte usage(); 2556*fcf3ce44SJohn Forte exit(1); 2557*fcf3ce44SJohn Forte } 2558*fcf3ce44SJohn Forte strncpy(ctag, argv[i + 1], 2559*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 2560*fcf3ce44SJohn Forte 2561*fcf3ce44SJohn Forte if (ctag[MAX_RDC_HOST_SIZE - 1] != '\0') { 2562*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cluster name " 2563*fcf3ce44SJohn Forte "is longer than %d characters\n"), 2564*fcf3ce44SJohn Forte (MAX_RDC_HOST_SIZE - 1)); 2565*fcf3ce44SJohn Forte } 2566*fcf3ce44SJohn Forte process_clocal(ctag); 2567*fcf3ce44SJohn Forte 2568*fcf3ce44SJohn Forte /* 2569*fcf3ce44SJohn Forte * well here is something. 2570*fcf3ce44SJohn Forte * what if they went sndradm -C local 2571*fcf3ce44SJohn Forte * host a b host a b ip sync C foobar? 2572*fcf3ce44SJohn Forte * they might be confused 2573*fcf3ce44SJohn Forte * lets stop them if ctag_arg and ctag 2574*fcf3ce44SJohn Forte * don't match and forgive if they are 2575*fcf3ce44SJohn Forte * the same, below also. 2576*fcf3ce44SJohn Forte */ 2577*fcf3ce44SJohn Forte if ((strlen(ctag_arg) > 0) && 2578*fcf3ce44SJohn Forte (strcmp(ctag_arg, ctag) != 0)) { 2579*fcf3ce44SJohn Forte rdc_err(NULL, gettext("ctags " 2580*fcf3ce44SJohn Forte "%s and %s do not match "), 2581*fcf3ce44SJohn Forte ctag_arg, ctag); 2582*fcf3ce44SJohn Forte 2583*fcf3ce44SJohn Forte } 2584*fcf3ce44SJohn Forte } else if (strcmp(argv[i], "q") == 0) { 2585*fcf3ce44SJohn Forte strncpy(diskqueue, argv[i + 1], 2586*fcf3ce44SJohn Forte NSC_MAXPATH); 2587*fcf3ce44SJohn Forte if (diskqueue[NSC_MAXPATH - 1] != '\0') { 2588*fcf3ce44SJohn Forte rdc_err(NULL, gettext("diskq name is " 2589*fcf3ce44SJohn Forte "longer than %d characters\n"), 2590*fcf3ce44SJohn Forte (NSC_MAXPATH - 1)); 2591*fcf3ce44SJohn Forte } 2592*fcf3ce44SJohn Forte } else { 2593*fcf3ce44SJohn Forte /* Unrecognized argument */ 2594*fcf3ce44SJohn Forte usage(); 2595*fcf3ce44SJohn Forte exit(1); 2596*fcf3ce44SJohn Forte } 2597*fcf3ce44SJohn Forte } 2598*fcf3ce44SJohn Forte } 2599*fcf3ce44SJohn Forte 2600*fcf3ce44SJohn Forte /* 2601*fcf3ce44SJohn Forte * Are we able to determine the existance of either 2602*fcf3ce44SJohn Forte * of these host addresses? 2603*fcf3ce44SJohn Forte */ 2604*fcf3ce44SJohn Forte if (gethost_netaddrs(fromhost, tohost, 2605*fcf3ce44SJohn Forte (char *)&fromnetaddr, (char *)&tonetaddr) < 0) { 2606*fcf3ce44SJohn Forte (void) fprintf(stderr, "\n"); 2607*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("unable to determine IP " 2608*fcf3ce44SJohn Forte "addresses for either host %s or host %s"), 2609*fcf3ce44SJohn Forte fromhost, tohost); 2610*fcf3ce44SJohn Forte 2611*fcf3ce44SJohn Forte if (flag != RDC_CMD_DISABLE) 2612*fcf3ce44SJohn Forte exit(1); 2613*fcf3ce44SJohn Forte else 2614*fcf3ce44SJohn Forte host_not_found = 1; 2615*fcf3ce44SJohn Forte } 2616*fcf3ce44SJohn Forte 2617*fcf3ce44SJohn Forte /* 2618*fcf3ce44SJohn Forte * Are we running on neither host? 2619*fcf3ce44SJohn Forte */ 2620*fcf3ce44SJohn Forte if (!self_check(fromhost) && !self_check(tohost)) { 2621*fcf3ce44SJohn Forte if (flag == RDC_CMD_DISABLE) { 2622*fcf3ce44SJohn Forte (void) fprintf(stderr, "\n"); 2623*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Not running on either host " 2624*fcf3ce44SJohn Forte "%s or host %s"), fromhost, tohost); 2625*fcf3ce44SJohn Forte host_not_found = 1; 2626*fcf3ce44SJohn Forte } 2627*fcf3ce44SJohn Forte } 2628*fcf3ce44SJohn Forte 2629*fcf3ce44SJohn Forte /* 2630*fcf3ce44SJohn Forte * at this point, hopfully it is safe to say that 2631*fcf3ce44SJohn Forte * if a ctag was supplied via -C tag it is safe to 2632*fcf3ce44SJohn Forte * move it from ctag_arg to ctag. If it was passed in 2633*fcf3ce44SJohn Forte * at the end and the beginning of the cli, it must 2634*fcf3ce44SJohn Forte * match, as per checks above. if it was not passed 2635*fcf3ce44SJohn Forte * in at the end, but at the beginning, we can deal. 2636*fcf3ce44SJohn Forte * this should handle the case of shost:svol. 2637*fcf3ce44SJohn Forte * which is the main reason for this. 2638*fcf3ce44SJohn Forte * 2639*fcf3ce44SJohn Forte * there are 3 cases: passed in by cli, checked just above. 2640*fcf3ce44SJohn Forte * using libdscfg, you must pass in -C tag to have 2641*fcf3ce44SJohn Forte * ctag_check pass. 2642*fcf3ce44SJohn Forte * finally a file. same rules as libdscfg. 2643*fcf3ce44SJohn Forte */ 2644*fcf3ce44SJohn Forte if ((strlen(ctag) == 0) && (strlen(ctag_arg) > 0)) 2645*fcf3ce44SJohn Forte (void) strcpy(ctag, ctag_arg); 2646*fcf3ce44SJohn Forte 2647*fcf3ce44SJohn Forte if (flag == RDC_CMD_RECONFIG) { 2648*fcf3ce44SJohn Forte if (reconfig_pbitmap) { 2649*fcf3ce44SJohn Forte strncpy(frombitmap, reconfig_pbitmap, 2650*fcf3ce44SJohn Forte NSC_MAXPATH); 2651*fcf3ce44SJohn Forte check_rdcbitmap(flag, fromhost, frombitmap); 2652*fcf3ce44SJohn Forte } 2653*fcf3ce44SJohn Forte if (reconfig_sbitmap) { 2654*fcf3ce44SJohn Forte strncpy(tobitmap, reconfig_sbitmap, 2655*fcf3ce44SJohn Forte NSC_MAXPATH); 2656*fcf3ce44SJohn Forte check_rdcbitmap(flag, tohost, tobitmap); 2657*fcf3ce44SJohn Forte } 2658*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 2659*fcf3ce44SJohn Forte if (reconfig_direct) 2660*fcf3ce44SJohn Forte strncpy(directfile, reconfig_direct, 2661*fcf3ce44SJohn Forte NSC_MAXPATH); 2662*fcf3ce44SJohn Forte #endif 2663*fcf3ce44SJohn Forte if (reconfig_group) 2664*fcf3ce44SJohn Forte strncpy(group, reconfig_group, NSC_MAXPATH); 2665*fcf3ce44SJohn Forte 2666*fcf3ce44SJohn Forte if (strlen(reconfig_ctag) > 0) 2667*fcf3ce44SJohn Forte strncpy(ctag, reconfig_ctag, 2668*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 2669*fcf3ce44SJohn Forte if (reconfig_doasync != -1) 2670*fcf3ce44SJohn Forte doasync = reconfig_doasync; 2671*fcf3ce44SJohn Forte } 2672*fcf3ce44SJohn Forte 2673*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) { 2674*fcf3ce44SJohn Forte if (ctag_check(fromhost, fromfile, frombitmap, 2675*fcf3ce44SJohn Forte tohost, tofile, tobitmap, ctag, diskqueue) < 0) 2676*fcf3ce44SJohn Forte exit(1); 2677*fcf3ce44SJohn Forte if ((diskq_group = check_diskqueue(NULL, diskqueue, 2678*fcf3ce44SJohn Forte group)) == DISKQ_FAIL) { 2679*fcf3ce44SJohn Forte rdc_err(NULL, gettext("disk queue %s is " 2680*fcf3ce44SJohn Forte "incompatible with existing queue"), 2681*fcf3ce44SJohn Forte diskqueue); 2682*fcf3ce44SJohn Forte } 2683*fcf3ce44SJohn Forte 2684*fcf3ce44SJohn Forte } 2685*fcf3ce44SJohn Forte pairs = 1; 2686*fcf3ce44SJohn Forte } else { 2687*fcf3ce44SJohn Forte pairs = read_config(flag, config_file, group_arg, ctag_arg); 2688*fcf3ce44SJohn Forte if (pairs == 0) { 2689*fcf3ce44SJohn Forte rdc_err(NULL, gettext("%s contains no " 2690*fcf3ce44SJohn Forte "matching Remote Mirror sets"), config_file); 2691*fcf3ce44SJohn Forte } 2692*fcf3ce44SJohn Forte } 2693*fcf3ce44SJohn Forte 2694*fcf3ce44SJohn Forte if (!nflag && !pflag && prompt_user(flag, iflag) == -1) 2695*fcf3ce44SJohn Forte exit(1); 2696*fcf3ce44SJohn Forte 2697*fcf3ce44SJohn Forte while (pairs--) { 2698*fcf3ce44SJohn Forte 2699*fcf3ce44SJohn Forte if (cfgflag || fflag) { 2700*fcf3ce44SJohn Forte strncpy(fromfile, pair_list[pairs].ffile, NSC_MAXPATH); 2701*fcf3ce44SJohn Forte strncpy(tofile, pair_list[pairs].tfile, NSC_MAXPATH); 2702*fcf3ce44SJohn Forte strncpy(frombitmap, pair_list[pairs].fbitmap, 2703*fcf3ce44SJohn Forte NSC_MAXPATH); 2704*fcf3ce44SJohn Forte strncpy(fromhost, 2705*fcf3ce44SJohn Forte pair_list[pairs].fhost, MAX_RDC_HOST_SIZE); 2706*fcf3ce44SJohn Forte strncpy(tohost, pair_list[pairs].thost, 2707*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 2708*fcf3ce44SJohn Forte strncpy(tobitmap, pair_list[pairs].tbitmap, 2709*fcf3ce44SJohn Forte NSC_MAXPATH); 2710*fcf3ce44SJohn Forte strncpy(directfile, pair_list[pairs].directfile, 2711*fcf3ce44SJohn Forte NSC_MAXPATH); 2712*fcf3ce44SJohn Forte strncpy(group, pair_list[pairs].group, NSC_MAXPATH); 2713*fcf3ce44SJohn Forte strncpy(ctag, pair_list[pairs].ctag, MAX_RDC_HOST_SIZE); 2714*fcf3ce44SJohn Forte strncpy(diskqueue, pair_list[pairs].diskqueue, 2715*fcf3ce44SJohn Forte NSC_MAXPATH); 2716*fcf3ce44SJohn Forte 2717*fcf3ce44SJohn Forte bcopy(pair_list[pairs].fnetaddr, fromnetaddr, 2718*fcf3ce44SJohn Forte RDC_MAXADDR); 2719*fcf3ce44SJohn Forte bcopy(pair_list[pairs].tnetaddr, tonetaddr, 2720*fcf3ce44SJohn Forte RDC_MAXADDR); 2721*fcf3ce44SJohn Forte 2722*fcf3ce44SJohn Forte doasync = pair_list[pairs].doasync; 2723*fcf3ce44SJohn Forte } 2724*fcf3ce44SJohn Forte 2725*fcf3ce44SJohn Forte if (pflag) { 2726*fcf3ce44SJohn Forte static int first = 1; 2727*fcf3ce44SJohn Forte 2728*fcf3ce44SJohn Forte if (first) { 2729*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 2730*fcf3ce44SJohn Forte rdc_err(NULL, 2731*fcf3ce44SJohn Forte gettext("unable to access configuration")); 2732*fcf3ce44SJohn Forte 2733*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 2734*fcf3ce44SJohn Forte rdc_err(NULL, 2735*fcf3ce44SJohn Forte gettext("unable to lock configuration")); 2736*fcf3ce44SJohn Forte 2737*fcf3ce44SJohn Forte first = 0; 2738*fcf3ce44SJohn Forte } 2739*fcf3ce44SJohn Forte 2740*fcf3ce44SJohn Forte (void) rdc_print(file_format, verbose, 2741*fcf3ce44SJohn Forte group_arg, ctag_arg, tohost, tofile, cfg); 2742*fcf3ce44SJohn Forte 2743*fcf3ce44SJohn Forte if (pairs == 0) { 2744*fcf3ce44SJohn Forte cfg_close(cfg); 2745*fcf3ce44SJohn Forte exit(0); 2746*fcf3ce44SJohn Forte } 2747*fcf3ce44SJohn Forte 2748*fcf3ce44SJohn Forte /* short circuit the rest of the command loop */ 2749*fcf3ce44SJohn Forte continue; 2750*fcf3ce44SJohn Forte } 2751*fcf3ce44SJohn Forte if (Bflag) { 2752*fcf3ce44SJohn Forte int ret; 2753*fcf3ce44SJohn Forte ret = rdc_bitmapset(tohost, tofile, bitfile, oflag, 2754*fcf3ce44SJohn Forte boffset); 2755*fcf3ce44SJohn Forte exit(ret); 2756*fcf3ce44SJohn Forte } 2757*fcf3ce44SJohn Forte if ((fflag || cfgflag) && flag == RDC_CMD_RECONFIG) { 2758*fcf3ce44SJohn Forte char orig_fbmp[MAXHOSTNAMELEN]; 2759*fcf3ce44SJohn Forte char orig_tbmp[MAXHOSTNAMELEN]; 2760*fcf3ce44SJohn Forte int ret; 2761*fcf3ce44SJohn Forte rdc_config_t parms; 2762*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 2763*fcf3ce44SJohn Forte 2764*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 2765*fcf3ce44SJohn Forte parms.rdc_set->netconfig = NULL; 2766*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.intf, fromhost, 2767*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 2768*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.intf, tohost, 2769*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 2770*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.file, fromfile, 2771*fcf3ce44SJohn Forte NSC_MAXPATH); 2772*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.file, tofile, 2773*fcf3ce44SJohn Forte NSC_MAXPATH); 2774*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 2775*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 2776*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 2777*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 2778*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to get set status" 2779*fcf3ce44SJohn Forte " before reconfig operation")); 2780*fcf3ce44SJohn Forte } 2781*fcf3ce44SJohn Forte strncpy(orig_fbmp, parms.rdc_set->primary.bitmap, 2782*fcf3ce44SJohn Forte NSC_MAXPATH); 2783*fcf3ce44SJohn Forte strncpy(orig_tbmp, parms.rdc_set->secondary.bitmap, 2784*fcf3ce44SJohn Forte NSC_MAXPATH); 2785*fcf3ce44SJohn Forte 2786*fcf3ce44SJohn Forte if (strncmp(orig_fbmp, frombitmap, NSC_MAXPATH) != 0) 2787*fcf3ce44SJohn Forte check_rdcbitmap(flag, fromhost, frombitmap); 2788*fcf3ce44SJohn Forte if (strncmp(orig_tbmp, tobitmap, NSC_MAXPATH) != 0) 2789*fcf3ce44SJohn Forte check_rdcbitmap(flag, tohost, tobitmap); 2790*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 2791*fcf3ce44SJohn Forte 2792*fcf3ce44SJohn Forte } 2793*fcf3ce44SJohn Forte /* 2794*fcf3ce44SJohn Forte * take a peek in the config to see if 2795*fcf3ce44SJohn Forte * the bitmap is being used elsewhere 2796*fcf3ce44SJohn Forte */ 2797*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE) { 2798*fcf3ce44SJohn Forte struct stat stb; 2799*fcf3ce44SJohn Forte /* 2800*fcf3ce44SJohn Forte * just for fun, lets see if some silly person 2801*fcf3ce44SJohn Forte * specified the same vol and bitmap 2802*fcf3ce44SJohn Forte */ 2803*fcf3ce44SJohn Forte if ((strcmp(fromfile, frombitmap) == 0) || 2804*fcf3ce44SJohn Forte (strcmp(tofile, tobitmap) == 0)) 2805*fcf3ce44SJohn Forte rdc_err(NULL, gettext("volumes and bitmaps" 2806*fcf3ce44SJohn Forte " must not match")); 2807*fcf3ce44SJohn Forte if (self_check(fromhost)) { 2808*fcf3ce44SJohn Forte check_rdcbitmap(flag, fromhost, frombitmap); 2809*fcf3ce44SJohn Forte if (stat(fromfile, &stb) != 0) { 2810*fcf3ce44SJohn Forte rdc_err(NULL, 2811*fcf3ce44SJohn Forte gettext("unable to access %s: %s"), 2812*fcf3ce44SJohn Forte fromfile, strerror(errno)); 2813*fcf3ce44SJohn Forte } 2814*fcf3ce44SJohn Forte if (!S_ISCHR(stb.st_mode)) { 2815*fcf3ce44SJohn Forte rdc_err(NULL, 2816*fcf3ce44SJohn Forte gettext("%s is not a character device"), 2817*fcf3ce44SJohn Forte fromfile); 2818*fcf3ce44SJohn Forte } 2819*fcf3ce44SJohn Forte } else { /* on the secondary */ 2820*fcf3ce44SJohn Forte check_rdcbitmap(flag, tohost, tobitmap); 2821*fcf3ce44SJohn Forte /* extra check for secondary vol */ 2822*fcf3ce44SJohn Forte check_rdcsecondary(tofile); 2823*fcf3ce44SJohn Forte if (stat(tofile, &stb) != 0) { 2824*fcf3ce44SJohn Forte rdc_err(NULL, 2825*fcf3ce44SJohn Forte gettext("unable to access %s: %s"), 2826*fcf3ce44SJohn Forte tofile, strerror(errno)); 2827*fcf3ce44SJohn Forte } 2828*fcf3ce44SJohn Forte if (!S_ISCHR(stb.st_mode)) { 2829*fcf3ce44SJohn Forte rdc_err(NULL, 2830*fcf3ce44SJohn Forte gettext("%s is not a character device"), 2831*fcf3ce44SJohn Forte tofile); 2832*fcf3ce44SJohn Forte } 2833*fcf3ce44SJohn Forte } 2834*fcf3ce44SJohn Forte 2835*fcf3ce44SJohn Forte } 2836*fcf3ce44SJohn Forte 2837*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE || 2838*fcf3ce44SJohn Forte flag == RDC_CMD_RECONFIG) { 2839*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 2840*fcf3ce44SJohn Forte rdc_err(NULL, 2841*fcf3ce44SJohn Forte gettext("unable to access configuration")); 2842*fcf3ce44SJohn Forte 2843*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) 2844*fcf3ce44SJohn Forte rdc_err(NULL, 2845*fcf3ce44SJohn Forte gettext("unable to lock configuration")); 2846*fcf3ce44SJohn Forte 2847*fcf3ce44SJohn Forte cfg_resource(cfg, clustered ? ctag : NULL); 2848*fcf3ce44SJohn Forte } else 2849*fcf3ce44SJohn Forte cfg = NULL; 2850*fcf3ce44SJohn Forte 2851*fcf3ce44SJohn Forte if (cfg && perform_autosv() && 2852*fcf3ce44SJohn Forte (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE || 2853*fcf3ce44SJohn Forte flag == RDC_CMD_RECONFIG)) { 2854*fcf3ce44SJohn Forte if (cfg_load_svols(cfg) < 0 || 2855*fcf3ce44SJohn Forte cfg_load_dsvols(cfg) < 0 || 2856*fcf3ce44SJohn Forte cfg_load_shadows(cfg) < 0) 2857*fcf3ce44SJohn Forte rdc_err(NULL, 2858*fcf3ce44SJohn Forte gettext("Unable to parse config filer")); 2859*fcf3ce44SJohn Forte load_rdc_vols(cfg); 2860*fcf3ce44SJohn Forte } 2861*fcf3ce44SJohn Forte cfg_success = (cfg == NULL); 2862*fcf3ce44SJohn Forte if (cfg && flag == RDC_CMD_ENABLE) { 2863*fcf3ce44SJohn Forte /* Enabled, so add the set via libcfg */ 2864*fcf3ce44SJohn Forte 2865*fcf3ce44SJohn Forte /* Build a new sndr entry and put it */ 2866*fcf3ce44SJohn Forte group_p = *group? group : place_holder; 2867*fcf3ce44SJohn Forte diskqueue_p = *diskqueue? diskqueue : place_holder; 2868*fcf3ce44SJohn Forte 2869*fcf3ce44SJohn Forte if ((diskqueue_p == place_holder) && 2870*fcf3ce44SJohn Forte (group_p != place_holder)) { 2871*fcf3ce44SJohn Forte get_group_diskq(cfg, group_p, diskqueue); 2872*fcf3ce44SJohn Forte if (*diskqueue) 2873*fcf3ce44SJohn Forte diskqueue_p = diskqueue; 2874*fcf3ce44SJohn Forte } 2875*fcf3ce44SJohn Forte 2876*fcf3ce44SJohn Forte /* 2877*fcf3ce44SJohn Forte * format in pconfig is: 2878*fcf3ce44SJohn Forte * phost.primary.pbitmap.shost.secondary. 2879*fcf3ce44SJohn Forte * sbitmap.type.mode.group.cnode.options.diskq 2880*fcf3ce44SJohn Forte */ 2881*fcf3ce44SJohn Forte (void) snprintf(buf, sizeof (buf), 2882*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s %s %s - %s", 2883*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, tohost, tofile, 2884*fcf3ce44SJohn Forte tobitmap, directfile, 2885*fcf3ce44SJohn Forte doasync? "async" : "sync", group_p, 2886*fcf3ce44SJohn Forte clustered? ctag : "-", diskqueue_p); 2887*fcf3ce44SJohn Forte 2888*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, "sndr", buf, strlen(buf)) < 0) 2889*fcf3ce44SJohn Forte rdc_warn(NULL, 2890*fcf3ce44SJohn Forte gettext("unable to add \"%s\" to " 2891*fcf3ce44SJohn Forte "configuration storage: %s"), 2892*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 2893*fcf3ce44SJohn Forte setnumber = find_setnumber_in_libcfg(cfg, clustered? 2894*fcf3ce44SJohn Forte ctag : NULL, tohost, tofile); 2895*fcf3ce44SJohn Forte if (setnumber < 0) 2896*fcf3ce44SJohn Forte rdc_warn(NULL, 2897*fcf3ce44SJohn Forte gettext("unable to add \"%s\" to " 2898*fcf3ce44SJohn Forte "configuration storage: %s"), 2899*fcf3ce44SJohn Forte diskqueue_p, cfg_error(&sev)); 2900*fcf3ce44SJohn Forte 2901*fcf3ce44SJohn Forte else 2902*fcf3ce44SJohn Forte cfg_success = 1; 2903*fcf3ce44SJohn Forte 2904*fcf3ce44SJohn Forte /* Add cluster aware info */ 2905*fcf3ce44SJohn Forte if (clustered && !rdc_islocal) { 2906*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2907*fcf3ce44SJohn Forte "sndr.set%d.options", setnumber); 2908*fcf3ce44SJohn Forte if (self_check(fromhost)) { 2909*fcf3ce44SJohn Forte if (cfg_put_options(cfg, CFG_SEC_CONF, 2910*fcf3ce44SJohn Forte key, "lghn", fromhost) < 0) { 2911*fcf3ce44SJohn Forte rdc_err(NULL, 2912*fcf3ce44SJohn Forte gettext("unable to add " 2913*fcf3ce44SJohn Forte "\"%s\" to configuration " 2914*fcf3ce44SJohn Forte "storage: %s"), 2915*fcf3ce44SJohn Forte fromhost, cfg_error(&sev)); 2916*fcf3ce44SJohn Forte } 2917*fcf3ce44SJohn Forte } else if (self_check(tohost)) { 2918*fcf3ce44SJohn Forte if (cfg_put_options(cfg, CFG_SEC_CONF, 2919*fcf3ce44SJohn Forte key, "lghn", tohost) < 0) { 2920*fcf3ce44SJohn Forte rdc_err(NULL, 2921*fcf3ce44SJohn Forte gettext("unable to add " 2922*fcf3ce44SJohn Forte "\"%s\" to configuration " 2923*fcf3ce44SJohn Forte "storage: %s"), 2924*fcf3ce44SJohn Forte fromhost, cfg_error(&sev)); 2925*fcf3ce44SJohn Forte } 2926*fcf3ce44SJohn Forte } 2927*fcf3ce44SJohn Forte } 2928*fcf3ce44SJohn Forte } else if (cfg && flag == RDC_CMD_DISABLE) { 2929*fcf3ce44SJohn Forte found = 0; 2930*fcf3ce44SJohn Forte /* Disabled, so delete the set via libcfg */ 2931*fcf3ce44SJohn Forte 2932*fcf3ce44SJohn Forte /* get sndr entries until shost, sfile match */ 2933*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 2934*fcf3ce44SJohn Forte setnumber = i + 1; 2935*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", 2936*fcf3ce44SJohn Forte setnumber); 2937*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 2938*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) { 2939*fcf3ce44SJohn Forte break; 2940*fcf3ce44SJohn Forte } 2941*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2942*fcf3ce44SJohn Forte "sndr.set%d.secondary", setnumber); 2943*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 2944*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 2945*fcf3ce44SJohn Forte break; 2946*fcf3ce44SJohn Forte if (strcmp(buf, tofile) != 0) 2947*fcf3ce44SJohn Forte continue; 2948*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2949*fcf3ce44SJohn Forte "sndr.set%d.shost", 2950*fcf3ce44SJohn Forte setnumber); 2951*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 2952*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 2953*fcf3ce44SJohn Forte break; 2954*fcf3ce44SJohn Forte if (strcmp(buf, tohost) != 0) 2955*fcf3ce44SJohn Forte continue; 2956*fcf3ce44SJohn Forte found = 1; 2957*fcf3ce44SJohn Forte #ifdef DEBUG 2958*fcf3ce44SJohn Forte if (checksetfields == -1) { 2959*fcf3ce44SJohn Forte rdc_err(NULL, 2960*fcf3ce44SJohn Forte gettext("checksetfields not set")); 2961*fcf3ce44SJohn Forte } 2962*fcf3ce44SJohn Forte #endif 2963*fcf3ce44SJohn Forte if (checksetfields) { 2964*fcf3ce44SJohn Forte checkgfields(cfg, setnumber, fromhost, 2965*fcf3ce44SJohn Forte fromfile, frombitmap, tobitmap, 2966*fcf3ce44SJohn Forte directfile, (doasync == 1) 2967*fcf3ce44SJohn Forte ? "async" : "sync", group, ctag, 2968*fcf3ce44SJohn Forte diskqueue); 2969*fcf3ce44SJohn Forte } 2970*fcf3ce44SJohn Forte 2971*fcf3ce44SJohn Forte /* perform cluster specific options */ 2972*fcf3ce44SJohn Forte if (clustered) { 2973*fcf3ce44SJohn Forte /* get the logical host, if set */ 2974*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2975*fcf3ce44SJohn Forte "sndr.set%d.options", setnumber); 2976*fcf3ce44SJohn Forte (void) cfg_get_single_option(cfg, 2977*fcf3ce44SJohn Forte CFG_SEC_CONF, key, "lghn", 2978*fcf3ce44SJohn Forte lhname, MAX_RDC_HOST_SIZE); 2979*fcf3ce44SJohn Forte 2980*fcf3ce44SJohn Forte /* figure out the cluster tag, if any */ 2981*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2982*fcf3ce44SJohn Forte "sndr.set%d.cnode", setnumber); 2983*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 2984*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 2985*fcf3ce44SJohn Forte break; 2986*fcf3ce44SJohn Forte if (strcmp(buf, ctag)) 2987*fcf3ce44SJohn Forte rdc_err(NULL, gettext("ctags %s" 2988*fcf3ce44SJohn Forte " and %s do not match"), 2989*fcf3ce44SJohn Forte buf, ctag); 2990*fcf3ce44SJohn Forte } else { 2991*fcf3ce44SJohn Forte *lhname = '\0'; 2992*fcf3ce44SJohn Forte *ctag = '\0'; 2993*fcf3ce44SJohn Forte } 2994*fcf3ce44SJohn Forte 2995*fcf3ce44SJohn Forte /* figure out the disk queue, if any */ 2996*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 2997*fcf3ce44SJohn Forte "sndr.set%d.diskq", 2998*fcf3ce44SJohn Forte setnumber); 2999*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 3000*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 3001*fcf3ce44SJohn Forte break; 3002*fcf3ce44SJohn Forte if (strlen(buf) > 0) { 3003*fcf3ce44SJohn Forte strncpy(diskqueue, buf, NSC_MAXPATH); 3004*fcf3ce44SJohn Forte } else { 3005*fcf3ce44SJohn Forte *diskqueue = '\0'; 3006*fcf3ce44SJohn Forte } 3007*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", 3008*fcf3ce44SJohn Forte setnumber); 3009*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, NULL, 0) < 0) 3010*fcf3ce44SJohn Forte rdc_warn(NULL, 3011*fcf3ce44SJohn Forte gettext("unable to remove \"%s\" " 3012*fcf3ce44SJohn Forte "from configuration storage: %s"), 3013*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 3014*fcf3ce44SJohn Forte else 3015*fcf3ce44SJohn Forte cfg_success = 1; 3016*fcf3ce44SJohn Forte break; 3017*fcf3ce44SJohn Forte } 3018*fcf3ce44SJohn Forte if (found == 0) { 3019*fcf3ce44SJohn Forte rdc_err(NULL, 3020*fcf3ce44SJohn Forte gettext("Unable to find %s:%s in " 3021*fcf3ce44SJohn Forte "configuration storage"), 3022*fcf3ce44SJohn Forte tohost, tofile); 3023*fcf3ce44SJohn Forte } 3024*fcf3ce44SJohn Forte if (host_not_found) { 3025*fcf3ce44SJohn Forte rdc_force_disable(cfg, fromhost, fromfile, 3026*fcf3ce44SJohn Forte frombitmap, tohost, tofile, tobitmap, ctag, 3027*fcf3ce44SJohn Forte lhname); 3028*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) 3029*fcf3ce44SJohn Forte rdc_err(NULL, gettext("commit on " 3030*fcf3ce44SJohn Forte "force disable failed")); 3031*fcf3ce44SJohn Forte cfg_close(cfg); 3032*fcf3ce44SJohn Forte return (0); 3033*fcf3ce44SJohn Forte } 3034*fcf3ce44SJohn Forte } else if (cfg && flag == RDC_CMD_RECONFIG) { 3035*fcf3ce44SJohn Forte /* Update relevant cfg record */ 3036*fcf3ce44SJohn Forte 3037*fcf3ce44SJohn Forte cfg_resource(cfg, NULL); 3038*fcf3ce44SJohn Forte 3039*fcf3ce44SJohn Forte /* get sndr entries until shost, sfile match */ 3040*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 3041*fcf3ce44SJohn Forte setnumber = i + 1; 3042*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", 3043*fcf3ce44SJohn Forte setnumber); 3044*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 3045*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) { 3046*fcf3ce44SJohn Forte break; 3047*fcf3ce44SJohn Forte } 3048*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 3049*fcf3ce44SJohn Forte "sndr.set%d.secondary", setnumber); 3050*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 3051*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 3052*fcf3ce44SJohn Forte break; 3053*fcf3ce44SJohn Forte if (strcmp(buf, tofile) != 0) 3054*fcf3ce44SJohn Forte continue; 3055*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 3056*fcf3ce44SJohn Forte "sndr.set%d.shost", 3057*fcf3ce44SJohn Forte setnumber); 3058*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 3059*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 3060*fcf3ce44SJohn Forte break; 3061*fcf3ce44SJohn Forte if (strcmp(buf, tohost) != 0) 3062*fcf3ce44SJohn Forte continue; 3063*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 3064*fcf3ce44SJohn Forte "sndr.set%d.cnode", 3065*fcf3ce44SJohn Forte setnumber); 3066*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 3067*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 3068*fcf3ce44SJohn Forte break; 3069*fcf3ce44SJohn Forte if (reconfig_ctag[0] == '\0') 3070*fcf3ce44SJohn Forte strncpy(ctag, buf, sizeof (ctag)); 3071*fcf3ce44SJohn Forte if (doasync) 3072*fcf3ce44SJohn Forte strcpy(mode, "async"); 3073*fcf3ce44SJohn Forte else 3074*fcf3ce44SJohn Forte strcpy(mode, "sync"); 3075*fcf3ce44SJohn Forte if (strcmp(directfile, "") == 0) 3076*fcf3ce44SJohn Forte strcpy(directfile, "ip"); 3077*fcf3ce44SJohn Forte 3078*fcf3ce44SJohn Forte group_p = strlen(group) > 0 ? group : 3079*fcf3ce44SJohn Forte place_holder; 3080*fcf3ce44SJohn Forte 3081*fcf3ce44SJohn Forte /* 3082*fcf3ce44SJohn Forte * if we are reconfigging out altogether, 3083*fcf3ce44SJohn Forte * get rid of the diskqueue 3084*fcf3ce44SJohn Forte */ 3085*fcf3ce44SJohn Forte if (group_p == place_holder) 3086*fcf3ce44SJohn Forte diskqueue_p = place_holder; 3087*fcf3ce44SJohn Forte else 3088*fcf3ce44SJohn Forte diskqueue_p = strlen(diskqueue) > 0 ? 3089*fcf3ce44SJohn Forte diskqueue : place_holder; 3090*fcf3ce44SJohn Forte 3091*fcf3ce44SJohn Forte /* 3092*fcf3ce44SJohn Forte * do a little diskq dance here for reconfigs 3093*fcf3ce44SJohn Forte * that did not specify the diskqueue whilst 3094*fcf3ce44SJohn Forte * reconfigging ... 3095*fcf3ce44SJohn Forte */ 3096*fcf3ce44SJohn Forte if ((diskqueue_p == place_holder) && 3097*fcf3ce44SJohn Forte (group_p != place_holder)) { 3098*fcf3ce44SJohn Forte get_group_diskq(cfg, group_p, 3099*fcf3ce44SJohn Forte diskqueue); 3100*fcf3ce44SJohn Forte diskqueue_p = strlen(diskqueue) > 0 ? 3101*fcf3ce44SJohn Forte diskqueue : place_holder; 3102*fcf3ce44SJohn Forte } 3103*fcf3ce44SJohn Forte 3104*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 3105*fcf3ce44SJohn Forte "sndr.set%d.options", setnumber); 3106*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, options_cfg, 3107*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) { 3108*fcf3ce44SJohn Forte break; 3109*fcf3ce44SJohn Forte } 3110*fcf3ce44SJohn Forte 3111*fcf3ce44SJohn Forte ctag_p = strlen(ctag) > 0 ? 3112*fcf3ce44SJohn Forte ctag : place_holder; 3113*fcf3ce44SJohn Forte (void) snprintf(buf, sizeof (buf), 3114*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s %s %s %s %s", 3115*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 3116*fcf3ce44SJohn Forte tohost, tofile, tobitmap, 3117*fcf3ce44SJohn Forte directfile, mode, group_p, 3118*fcf3ce44SJohn Forte ctag_p, options_cfg, diskqueue_p); 3119*fcf3ce44SJohn Forte 3120*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", 3121*fcf3ce44SJohn Forte setnumber); 3122*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, buf, 3123*fcf3ce44SJohn Forte strlen(buf)) < 0) 3124*fcf3ce44SJohn Forte rdc_warn(NULL, 3125*fcf3ce44SJohn Forte gettext("unable to update \"%s\" " 3126*fcf3ce44SJohn Forte "in configuration storage: %s"), 3127*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 3128*fcf3ce44SJohn Forte else 3129*fcf3ce44SJohn Forte cfg_success = 1; 3130*fcf3ce44SJohn Forte break; 3131*fcf3ce44SJohn Forte } 3132*fcf3ce44SJohn Forte } 3133*fcf3ce44SJohn Forte 3134*fcf3ce44SJohn Forte if (cfg_success) { 3135*fcf3ce44SJohn Forte if (cfg && perform_autosv()) { 3136*fcf3ce44SJohn Forte if (self_check(fromhost)) { 3137*fcf3ce44SJohn Forte if (diskqueue[0] && 3138*fcf3ce44SJohn Forte (strcmp(diskqueue, fromfile) == 0) || 3139*fcf3ce44SJohn Forte (strcmp(diskqueue, frombitmap) == 0)) { 3140*fcf3ce44SJohn Forte rdc_err(NULL, gettext("disk " 3141*fcf3ce44SJohn Forte "queue volume %s must not " 3142*fcf3ce44SJohn Forte "match any primary Remote " 3143*fcf3ce44SJohn Forte "Mirror volume or bitmap"), 3144*fcf3ce44SJohn Forte diskqueue); 3145*fcf3ce44SJohn Forte } 3146*fcf3ce44SJohn Forte 3147*fcf3ce44SJohn Forte if (diskqueue[0]) { 3148*fcf3ce44SJohn Forte different_devs(fromfile, diskqueue); 3149*fcf3ce44SJohn Forte different_devs(frombitmap, diskqueue); 3150*fcf3ce44SJohn Forte validate_name(cfg, diskqueue); 3151*fcf3ce44SJohn Forte } 3152*fcf3ce44SJohn Forte different_devs(fromfile, frombitmap); 3153*fcf3ce44SJohn Forte validate_name(cfg, fromfile); 3154*fcf3ce44SJohn Forte validate_name(cfg, frombitmap); 3155*fcf3ce44SJohn Forte } else { 3156*fcf3ce44SJohn Forte different_devs(tofile, tobitmap); 3157*fcf3ce44SJohn Forte validate_name(cfg, tofile); 3158*fcf3ce44SJohn Forte validate_name(cfg, tobitmap); 3159*fcf3ce44SJohn Forte } 3160*fcf3ce44SJohn Forte } 3161*fcf3ce44SJohn Forte /* 3162*fcf3ce44SJohn Forte * okay, if the command is sync, just build 3163*fcf3ce44SJohn Forte * a list of rdcconfig_t's after the pairs-- 3164*fcf3ce44SJohn Forte * loop is done, we will pass this list to 3165*fcf3ce44SJohn Forte * librdc to multithread the syncs (after 3166*fcf3ce44SJohn Forte * forking off a daemonish type process 3167*fcf3ce44SJohn Forte * that waits for the libcall to complete 3168*fcf3ce44SJohn Forte * ints of interest: 3169*fcf3ce44SJohn Forte * flag ie RDC_CMD_COPY, iflag RDC_OPT_UPDATE, 3170*fcf3ce44SJohn Forte * reverse RDC_OPT_REVERSE, RDC_OPT_FORWARD 3171*fcf3ce44SJohn Forte * if necessary, turn autosync back on 3172*fcf3ce44SJohn Forte */ 3173*fcf3ce44SJohn Forte if (flag == RDC_CMD_COPY) { 3174*fcf3ce44SJohn Forte if (autosync_is_on(tohost, tofile) == 3175*fcf3ce44SJohn Forte AUTOSYNC_ON) 3176*fcf3ce44SJohn Forte enable_autosync(fromhost, fromfile, 3177*fcf3ce44SJohn Forte tohost, tofile); 3178*fcf3ce44SJohn Forte 3179*fcf3ce44SJohn Forte if (sets == NULL) { 3180*fcf3ce44SJohn Forte sets_p = sets = 3181*fcf3ce44SJohn Forte rdc_alloc_config(fromhost, fromfile, 3182*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 3183*fcf3ce44SJohn Forte tobitmap, "mode", "group", "ctag", 3184*fcf3ce44SJohn Forte "options", 0); 3185*fcf3ce44SJohn Forte 3186*fcf3ce44SJohn Forte if (sets_p == NULL) { 3187*fcf3ce44SJohn Forte rdc_err(NULL, 3188*fcf3ce44SJohn Forte gettext("rdc config alloc" 3189*fcf3ce44SJohn Forte "failed %s"), rdc_error(NULL)); 3190*fcf3ce44SJohn Forte } 3191*fcf3ce44SJohn Forte continue; 3192*fcf3ce44SJohn Forte } 3193*fcf3ce44SJohn Forte 3194*fcf3ce44SJohn Forte sets_p = sets_p->next = 3195*fcf3ce44SJohn Forte rdc_alloc_config(fromhost, fromfile, 3196*fcf3ce44SJohn Forte frombitmap, tohost, tofile, tobitmap, 3197*fcf3ce44SJohn Forte "mode", "group", "ctag", "options", 0); 3198*fcf3ce44SJohn Forte 3199*fcf3ce44SJohn Forte if (sets_p == NULL) { 3200*fcf3ce44SJohn Forte rdc_err(NULL, gettext("rdc config alloc" 3201*fcf3ce44SJohn Forte "failed %s"), rdc_error(NULL)); 3202*fcf3ce44SJohn Forte } 3203*fcf3ce44SJohn Forte continue; 3204*fcf3ce44SJohn Forte } 3205*fcf3ce44SJohn Forte 3206*fcf3ce44SJohn Forte /* 3207*fcf3ce44SJohn Forte * block incoming signals until after the possible 3208*fcf3ce44SJohn Forte * cfg_commit is done 3209*fcf3ce44SJohn Forte */ 3210*fcf3ce44SJohn Forte block_sigs(); 3211*fcf3ce44SJohn Forte if (rdc_operation(cfg, fromhost, fromfile, frombitmap, 3212*fcf3ce44SJohn Forte tohost, tofile, tobitmap, flag, iflag, directfile, 3213*fcf3ce44SJohn Forte group, ctag, diskqueue, &doasync, reverse) < 0) { 3214*fcf3ce44SJohn Forte ; 3215*fcf3ce44SJohn Forte /*EMPTY*/ 3216*fcf3ce44SJohn Forte } else if (cfg) { 3217*fcf3ce44SJohn Forte if (diskq_group == DISKQ_REWRITEG) { 3218*fcf3ce44SJohn Forte rewrite_group_diskqueue(cfg, 3219*fcf3ce44SJohn Forte &pair_list[pairs], diskqueue); 3220*fcf3ce44SJohn Forte } 3221*fcf3ce44SJohn Forte if (perform_autosv() && 3222*fcf3ce44SJohn Forte (flag == RDC_CMD_ENABLE || 3223*fcf3ce44SJohn Forte flag == RDC_CMD_DISABLE || 3224*fcf3ce44SJohn Forte flag == RDC_CMD_RECONFIG)) { 3225*fcf3ce44SJohn Forte unload_rdc_vols(); 3226*fcf3ce44SJohn Forte cfg_unload_shadows(); 3227*fcf3ce44SJohn Forte cfg_unload_dsvols(); 3228*fcf3ce44SJohn Forte cfg_unload_svols(); 3229*fcf3ce44SJohn Forte } 3230*fcf3ce44SJohn Forte if ((iflag & RDC_OPT_REVERSE_ROLE) != 0 && 3231*fcf3ce44SJohn Forte allow_role) { 3232*fcf3ce44SJohn Forte bzero(tmphost, MAX_RDC_HOST_SIZE); 3233*fcf3ce44SJohn Forte bzero(tmpfile, NSC_MAXPATH); 3234*fcf3ce44SJohn Forte bzero(tmpbitmap, NSC_MAXPATH); 3235*fcf3ce44SJohn Forte strncpy(tmphost, fromhost, 3236*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 3237*fcf3ce44SJohn Forte strncpy(tmpfile, fromfile, NSC_MAXPATH); 3238*fcf3ce44SJohn Forte strncpy(tmpbitmap, frombitmap, 3239*fcf3ce44SJohn Forte NSC_MAXPATH); 3240*fcf3ce44SJohn Forte 3241*fcf3ce44SJohn Forte strncpy(fromhost, tohost, 3242*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 3243*fcf3ce44SJohn Forte strncpy(fromfile, tofile, NSC_MAXPATH); 3244*fcf3ce44SJohn Forte strncpy(frombitmap, tobitmap, 3245*fcf3ce44SJohn Forte NSC_MAXPATH); 3246*fcf3ce44SJohn Forte 3247*fcf3ce44SJohn Forte strncpy(tohost, tmphost, 3248*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 3249*fcf3ce44SJohn Forte strncpy(tofile, tmpfile, NSC_MAXPATH); 3250*fcf3ce44SJohn Forte strncpy(tobitmap, tmpbitmap, 3251*fcf3ce44SJohn Forte NSC_MAXPATH); 3252*fcf3ce44SJohn Forte group_p = strlen(group) > 0 ? group : 3253*fcf3ce44SJohn Forte place_holder; 3254*fcf3ce44SJohn Forte diskqueue_p = strlen(diskqueue) > 0 ? 3255*fcf3ce44SJohn Forte diskqueue : place_holder; 3256*fcf3ce44SJohn Forte ctag_p = strlen(ctag) > 0 ? 3257*fcf3ce44SJohn Forte ctag : place_holder; 3258*fcf3ce44SJohn Forte (void) snprintf(buf, sizeof (buf), "%s " 3259*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s %s %s %s", 3260*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 3261*fcf3ce44SJohn Forte tohost, tofile, tobitmap, 3262*fcf3ce44SJohn Forte directfile, mode, group_p, 3263*fcf3ce44SJohn Forte ctag_p, options_cfg, diskqueue_p); 3264*fcf3ce44SJohn Forte 3265*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 3266*fcf3ce44SJohn Forte "sndr.set%d", setnumber); 3267*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, buf, 3268*fcf3ce44SJohn Forte strlen(buf)) < 0) 3269*fcf3ce44SJohn Forte rdc_err(NULL, 3270*fcf3ce44SJohn Forte gettext("unable to update \"%s\" " 3271*fcf3ce44SJohn Forte "in configuration storage: %s"), 3272*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 3273*fcf3ce44SJohn Forte } 3274*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) { 3275*fcf3ce44SJohn Forte rdc_err(NULL, gettext("commit on role " 3276*fcf3ce44SJohn Forte "reversal failed")); 3277*fcf3ce44SJohn Forte } 3278*fcf3ce44SJohn Forte } 3279*fcf3ce44SJohn Forte unblock_sigs(); 3280*fcf3ce44SJohn Forte } 3281*fcf3ce44SJohn Forte 3282*fcf3ce44SJohn Forte if (cfg) { 3283*fcf3ce44SJohn Forte cfg_close(cfg); 3284*fcf3ce44SJohn Forte } 3285*fcf3ce44SJohn Forte 3286*fcf3ce44SJohn Forte } 3287*fcf3ce44SJohn Forte if (flag == RDC_CMD_COPY) { 3288*fcf3ce44SJohn Forte pid = fork(); 3289*fcf3ce44SJohn Forte if (pid == -1) { /* error forking */ 3290*fcf3ce44SJohn Forte perror("fork"); 3291*fcf3ce44SJohn Forte exit(1); 3292*fcf3ce44SJohn Forte } 3293*fcf3ce44SJohn Forte } else { 3294*fcf3ce44SJohn Forte exit(0); 3295*fcf3ce44SJohn Forte } 3296*fcf3ce44SJohn Forte if (pid > 0) /* parent process */ 3297*fcf3ce44SJohn Forte exit(0); 3298*fcf3ce44SJohn Forte 3299*fcf3ce44SJohn Forte spcslog_sync(sets, 1, iflag); 3300*fcf3ce44SJohn Forte if (iflag & RDC_OPT_REVERSE) { 3301*fcf3ce44SJohn Forte if (iflag & RDC_OPT_UPDATE) 3302*fcf3ce44SJohn Forte rclist = rdc_ursync(sets); 3303*fcf3ce44SJohn Forte else 3304*fcf3ce44SJohn Forte rclist = rdc_rsync(sets); 3305*fcf3ce44SJohn Forte } else if (iflag & RDC_OPT_UPDATE) { 3306*fcf3ce44SJohn Forte rclist = rdc_usync(sets); 3307*fcf3ce44SJohn Forte } else 3308*fcf3ce44SJohn Forte rclist = rdc_fsync(sets); 3309*fcf3ce44SJohn Forte 3310*fcf3ce44SJohn Forte rcp = rclist; 3311*fcf3ce44SJohn Forte while (rcp) { 3312*fcf3ce44SJohn Forte if (rcp->rc < 0) { 3313*fcf3ce44SJohn Forte /* rclist->msg has already been gettext'd */ 3314*fcf3ce44SJohn Forte (void) fprintf(stderr, 3315*fcf3ce44SJohn Forte gettext("Remote Mirror: %s %s %s %s %s %s\n"), 3316*fcf3ce44SJohn Forte rcp->set.phost, rcp->set.pfile, rcp->set.pbmp, 3317*fcf3ce44SJohn Forte rcp->set.shost, rcp->set.sfile, rcp->set.sbmp); 3318*fcf3ce44SJohn Forte rdc_warn(NULL, "%s", rcp->msg); 3319*fcf3ce44SJohn Forte spcs_log("sndr", NULL, "%s", rcp->msg); 3320*fcf3ce44SJohn Forte } 3321*fcf3ce44SJohn Forte rcp = rcp->next; 3322*fcf3ce44SJohn Forte } 3323*fcf3ce44SJohn Forte 3324*fcf3ce44SJohn Forte spcslog_sync(sets, 0, iflag); 3325*fcf3ce44SJohn Forte 3326*fcf3ce44SJohn Forte if (sets) 3327*fcf3ce44SJohn Forte rdc_free_config(sets, RDC_FREEALL); 3328*fcf3ce44SJohn Forte if (rclist) 3329*fcf3ce44SJohn Forte rdc_free_rclist(rclist); 3330*fcf3ce44SJohn Forte 3331*fcf3ce44SJohn Forte return (0); 3332*fcf3ce44SJohn Forte } 3333*fcf3ce44SJohn Forte /* 3334*fcf3ce44SJohn Forte * process_clocal() 3335*fcf3ce44SJohn Forte * pre: a non null string 3336*fcf3ce44SJohn Forte * post: if the string is "local" 3337*fcf3ce44SJohn Forte * then it is converted to "-" 3338*fcf3ce44SJohn Forte * and rdc_islocal is set to 1 3339*fcf3ce44SJohn Forte * if not rdc_islocal set to 0 3340*fcf3ce44SJohn Forte */ 3341*fcf3ce44SJohn Forte void 3342*fcf3ce44SJohn Forte process_clocal(char *ctag) 3343*fcf3ce44SJohn Forte { 3344*fcf3ce44SJohn Forte /* 3345*fcf3ce44SJohn Forte * Check for the special cluster tag and convert into the 3346*fcf3ce44SJohn Forte * internal representation. 3347*fcf3ce44SJohn Forte */ 3348*fcf3ce44SJohn Forte 3349*fcf3ce44SJohn Forte if (ctag != NULL && strcmp(ctag, RDC_LOCAL_TAG) == 0) { 3350*fcf3ce44SJohn Forte strcpy(ctag, "-"); 3351*fcf3ce44SJohn Forte rdc_islocal = 1; 3352*fcf3ce44SJohn Forte } else { 3353*fcf3ce44SJohn Forte rdc_islocal = 0; 3354*fcf3ce44SJohn Forte } 3355*fcf3ce44SJohn Forte } 3356*fcf3ce44SJohn Forte 3357*fcf3ce44SJohn Forte static void 3358*fcf3ce44SJohn Forte rdc_check_dgislocal(char *dgname) 3359*fcf3ce44SJohn Forte { 3360*fcf3ce44SJohn Forte char *othernode; 3361*fcf3ce44SJohn Forte int rc; 3362*fcf3ce44SJohn Forte 3363*fcf3ce44SJohn Forte /* 3364*fcf3ce44SJohn Forte * check where this disk service is mastered 3365*fcf3ce44SJohn Forte */ 3366*fcf3ce44SJohn Forte 3367*fcf3ce44SJohn Forte rc = cfg_dgname_islocal(dgname, &othernode); 3368*fcf3ce44SJohn Forte if (rc < 0) { 3369*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to find " 3370*fcf3ce44SJohn Forte "disk service, %s: %s"), dgname, strerror(errno)); 3371*fcf3ce44SJohn Forte } 3372*fcf3ce44SJohn Forte 3373*fcf3ce44SJohn Forte if (rc == 0) { 3374*fcf3ce44SJohn Forte rdc_err(NULL, gettext("disk service, %s, is " 3375*fcf3ce44SJohn Forte "active on node \"%s\"\nPlease re-issue " 3376*fcf3ce44SJohn Forte "the command on that node"), dgname, othernode); 3377*fcf3ce44SJohn Forte } 3378*fcf3ce44SJohn Forte } 3379*fcf3ce44SJohn Forte 3380*fcf3ce44SJohn Forte static void 3381*fcf3ce44SJohn Forte different_devs(char *dev1, char *dev2) 3382*fcf3ce44SJohn Forte { 3383*fcf3ce44SJohn Forte struct stat buf1, buf2; 3384*fcf3ce44SJohn Forte 3385*fcf3ce44SJohn Forte if (stat(dev1, &buf1) < 0) { 3386*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"), 3387*fcf3ce44SJohn Forte dev1); 3388*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev1); 3389*fcf3ce44SJohn Forte } 3390*fcf3ce44SJohn Forte if (stat(dev2, &buf2) < 0) { 3391*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"), 3392*fcf3ce44SJohn Forte dev2); 3393*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev2); 3394*fcf3ce44SJohn Forte } 3395*fcf3ce44SJohn Forte if (buf1.st_rdev == buf2.st_rdev) { 3396*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: '%s' and '%s' " 3397*fcf3ce44SJohn Forte "refer to the same device"), dev1, dev2); 3398*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror: '%s' and '%s' refer to " 3399*fcf3ce44SJohn Forte "the same device"), dev1, dev2); 3400*fcf3ce44SJohn Forte } 3401*fcf3ce44SJohn Forte } 3402*fcf3ce44SJohn Forte 3403*fcf3ce44SJohn Forte static void 3404*fcf3ce44SJohn Forte validate_name(CFGFILE *cfg, char *vol) 3405*fcf3ce44SJohn Forte { 3406*fcf3ce44SJohn Forte char *altname; 3407*fcf3ce44SJohn Forte int rc; 3408*fcf3ce44SJohn Forte 3409*fcf3ce44SJohn Forte if (!cfg) { 3410*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror: null cfg ptr in " 3411*fcf3ce44SJohn Forte "validate_name")); 3412*fcf3ce44SJohn Forte } 3413*fcf3ce44SJohn Forte 3414*fcf3ce44SJohn Forte rc = cfg_get_canonical_name(cfg, vol, &altname); 3415*fcf3ce44SJohn Forte if (rc < 0) { 3416*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: unable to parse " 3417*fcf3ce44SJohn Forte "config file\n")); 3418*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror: unable to parse config " 3419*fcf3ce44SJohn Forte "file\n")); 3420*fcf3ce44SJohn Forte } 3421*fcf3ce44SJohn Forte if (rc) { 3422*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("Remote Mirror: '%s': already " 3423*fcf3ce44SJohn Forte "configured as '%s'"), vol, altname); 3424*fcf3ce44SJohn Forte rdc_err(NULL, gettext("Remote Mirror: The volume '%s' has been " 3425*fcf3ce44SJohn Forte "configured previously as '%s'. Re-enter command with " 3426*fcf3ce44SJohn Forte "the latter name."), vol, altname); 3427*fcf3ce44SJohn Forte } 3428*fcf3ce44SJohn Forte } 3429*fcf3ce44SJohn Forte 3430*fcf3ce44SJohn Forte /* 3431*fcf3ce44SJohn Forte * Add the autosync value to the option field for the sndr set specified by 3432*fcf3ce44SJohn Forte * tohost:tofile. 3433*fcf3ce44SJohn Forte * 3434*fcf3ce44SJohn Forte * ASSUMPTIONS: 3435*fcf3ce44SJohn Forte * - cfg file is available to take a write lock. 3436*fcf3ce44SJohn Forte * - set is already configured in dscfg 3437*fcf3ce44SJohn Forte * 3438*fcf3ce44SJohn Forte * INPUTS: 3439*fcf3ce44SJohn Forte * autosync_val - value to set autosync to 3440*fcf3ce44SJohn Forte * tohost - secondary host 3441*fcf3ce44SJohn Forte * tofile - secondary volume 3442*fcf3ce44SJohn Forte * 3443*fcf3ce44SJohn Forte * OUTPUTS: 3444*fcf3ce44SJohn Forte * none. 3445*fcf3ce44SJohn Forte * 3446*fcf3ce44SJohn Forte */ 3447*fcf3ce44SJohn Forte static void 3448*fcf3ce44SJohn Forte set_autosync(int autosync_val, char *tohost, char *tofile, char *ctag) 3449*fcf3ce44SJohn Forte { 3450*fcf3ce44SJohn Forte CFGFILE *cfg; 3451*fcf3ce44SJohn Forte char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; 3452*fcf3ce44SJohn Forte char tag[CFG_MAX_BUF], val[CFG_MAX_BUF]; 3453*fcf3ce44SJohn Forte char auto_tag[CFG_MAX_BUF]; 3454*fcf3ce44SJohn Forte _sd_dual_pair_t pair; 3455*fcf3ce44SJohn Forte _sd_dual_pair_t tmpair; 3456*fcf3ce44SJohn Forte int setnumber, options = 0, already_set = 0, cfg_success = 0; 3457*fcf3ce44SJohn Forte int set; 3458*fcf3ce44SJohn Forte 3459*fcf3ce44SJohn Forte /* verify valid autosync request */ 3460*fcf3ce44SJohn Forte if ((autosync_val != AUTOSYNC_ON) && (autosync_val != AUTOSYNC_OFF)) { 3461*fcf3ce44SJohn Forte #ifdef DEBUG 3462*fcf3ce44SJohn Forte rdc_warn(NULL, 3463*fcf3ce44SJohn Forte gettext("set_autosync called with improper value")); 3464*fcf3ce44SJohn Forte #endif 3465*fcf3ce44SJohn Forte return; 3466*fcf3ce44SJohn Forte } 3467*fcf3ce44SJohn Forte 3468*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 3469*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to access configuration")); 3470*fcf3ce44SJohn Forte } 3471*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 3472*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 3473*fcf3ce44SJohn Forte } 3474*fcf3ce44SJohn Forte 3475*fcf3ce44SJohn Forte if (clustered) { 3476*fcf3ce44SJohn Forte cfg_resource(cfg, ctag); 3477*fcf3ce44SJohn Forte } else { 3478*fcf3ce44SJohn Forte cfg_resource(cfg, NULL); 3479*fcf3ce44SJohn Forte } 3480*fcf3ce44SJohn Forte 3481*fcf3ce44SJohn Forte /* find set number in config */ 3482*fcf3ce44SJohn Forte if ((setnumber = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL, 3483*fcf3ce44SJohn Forte tohost, tofile)) < 0) { 3484*fcf3ce44SJohn Forte cfg_close(cfg); 3485*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to find Remote Mirror set %s:%s: " 3486*fcf3ce44SJohn Forte "in config"), tohost, tofile); 3487*fcf3ce44SJohn Forte } 3488*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.options", setnumber); 3489*fcf3ce44SJohn Forte (void) snprintf(auto_tag, sizeof (auto_tag), "auto"); 3490*fcf3ce44SJohn Forte 3491*fcf3ce44SJohn Forte /* Check if there are any options already set, including ours */ 3492*fcf3ce44SJohn Forte if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val, 3493*fcf3ce44SJohn Forte CFG_MAX_BUF) >= 0) { 3494*fcf3ce44SJohn Forte options = 1; 3495*fcf3ce44SJohn Forte 3496*fcf3ce44SJohn Forte do { 3497*fcf3ce44SJohn Forte if (strcmp(tag, auto_tag) == 0) { 3498*fcf3ce44SJohn Forte already_set = 1; 3499*fcf3ce44SJohn Forte } 3500*fcf3ce44SJohn Forte } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag, 3501*fcf3ce44SJohn Forte CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0); 3502*fcf3ce44SJohn Forte } 3503*fcf3ce44SJohn Forte 3504*fcf3ce44SJohn Forte /* options already exist, edit ours out */ 3505*fcf3ce44SJohn Forte if (options && already_set) { 3506*fcf3ce44SJohn Forte char *p, *q; 3507*fcf3ce44SJohn Forte int need_to_clear_buf = 1; 3508*fcf3ce44SJohn Forte 3509*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 3510*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to get options field " 3511*fcf3ce44SJohn Forte "for Remote Mirror set %s:%s"), tohost, tofile); 3512*fcf3ce44SJohn Forte } 3513*fcf3ce44SJohn Forte 3514*fcf3ce44SJohn Forte /* parse out our options, all of the form "auto=" */ 3515*fcf3ce44SJohn Forte p = strdup(buf); 3516*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 3517*fcf3ce44SJohn Forte 3518*fcf3ce44SJohn Forte q = strtok(p, ";"); 3519*fcf3ce44SJohn Forte do { 3520*fcf3ce44SJohn Forte /* if another tag/value exists, keep it */ 3521*fcf3ce44SJohn Forte if (strncmp(auto_tag, q, 4) != 0) { 3522*fcf3ce44SJohn Forte strcat(buf, q); 3523*fcf3ce44SJohn Forte strcat(buf, ";"); 3524*fcf3ce44SJohn Forte need_to_clear_buf = 0; 3525*fcf3ce44SJohn Forte } 3526*fcf3ce44SJohn Forte } while (q = strtok(NULL, ";")); 3527*fcf3ce44SJohn Forte free(p); 3528*fcf3ce44SJohn Forte 3529*fcf3ce44SJohn Forte /* if we were the only option, clear the field */ 3530*fcf3ce44SJohn Forte if (need_to_clear_buf) { 3531*fcf3ce44SJohn Forte strcat(buf, "-"); 3532*fcf3ce44SJohn Forte } 3533*fcf3ce44SJohn Forte 3534*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 3535*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to clear autosync value " 3536*fcf3ce44SJohn Forte "in config for Remote Mirror set %s:%s"), tohost, 3537*fcf3ce44SJohn Forte tofile); 3538*fcf3ce44SJohn Forte } else { 3539*fcf3ce44SJohn Forte cfg_success = 1; 3540*fcf3ce44SJohn Forte } 3541*fcf3ce44SJohn Forte } 3542*fcf3ce44SJohn Forte 3543*fcf3ce44SJohn Forte /* autosync is not present in options field, add if on is requested */ 3544*fcf3ce44SJohn Forte if (autosync_val == AUTOSYNC_ON) { 3545*fcf3ce44SJohn Forte if (cfg_put_options(cfg, CFG_SEC_CONF, key, auto_tag, "on") 3546*fcf3ce44SJohn Forte < 0) { 3547*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to update autosync value " 3548*fcf3ce44SJohn Forte "in config for Remote Mirror set %s:%s"), tohost, 3549*fcf3ce44SJohn Forte tofile); 3550*fcf3ce44SJohn Forte } else { 3551*fcf3ce44SJohn Forte cfg_success = 1; 3552*fcf3ce44SJohn Forte } 3553*fcf3ce44SJohn Forte } 3554*fcf3ce44SJohn Forte /* if we are in a group, update any other sets in the same group */ 3555*fcf3ce44SJohn Forte do { 3556*fcf3ce44SJohn Forte bzero(&pair, sizeof (pair)); 3557*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 3558*fcf3ce44SJohn Forte 3559*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); 3560*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 3561*fcf3ce44SJohn Forte break; 3562*fcf3ce44SJohn Forte } 3563*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &pair, NULL)) 3564*fcf3ce44SJohn Forte break; 3565*fcf3ce44SJohn Forte if (pair.group == NULL) /* not in a group */ 3566*fcf3ce44SJohn Forte break; 3567*fcf3ce44SJohn Forte if (!pair.group[0]) 3568*fcf3ce44SJohn Forte break; /* not in a group */ 3569*fcf3ce44SJohn Forte for (set = 1; /*CSTYLED*/; set++) { 3570*fcf3ce44SJohn Forte if (set == setnumber) 3571*fcf3ce44SJohn Forte continue; 3572*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 3573*fcf3ce44SJohn Forte options = 0; 3574*fcf3ce44SJohn Forte already_set = 0; 3575*fcf3ce44SJohn Forte 3576*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", set); 3577*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 3578*fcf3ce44SJohn Forte break; /* last set processed */ 3579*fcf3ce44SJohn Forte } 3580*fcf3ce44SJohn Forte bzero(&tmpair, sizeof (tmpair)); 3581*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &tmpair, NULL)) 3582*fcf3ce44SJohn Forte break; 3583*fcf3ce44SJohn Forte if (strcmp(pair.group, tmpair.group) != 0) 3584*fcf3ce44SJohn Forte continue; /* not the group we want */ 3585*fcf3ce44SJohn Forte 3586*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.options", 3587*fcf3ce44SJohn Forte set); 3588*fcf3ce44SJohn Forte /* 3589*fcf3ce44SJohn Forte * Check if there are any options already set, 3590*fcf3ce44SJohn Forte * including ours 3591*fcf3ce44SJohn Forte */ 3592*fcf3ce44SJohn Forte if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, 3593*fcf3ce44SJohn Forte CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0) { 3594*fcf3ce44SJohn Forte options = 1; 3595*fcf3ce44SJohn Forte 3596*fcf3ce44SJohn Forte do { 3597*fcf3ce44SJohn Forte if (strcmp(tag, auto_tag) == 0) { 3598*fcf3ce44SJohn Forte already_set = 1; 3599*fcf3ce44SJohn Forte } 3600*fcf3ce44SJohn Forte } while (cfg_get_options(cfg, CFG_SEC_CONF, 3601*fcf3ce44SJohn Forte NULL, tag, CFG_MAX_BUF, val, 3602*fcf3ce44SJohn Forte CFG_MAX_BUF) >= 0); 3603*fcf3ce44SJohn Forte } 3604*fcf3ce44SJohn Forte 3605*fcf3ce44SJohn Forte /* options already exist, edit ours out */ 3606*fcf3ce44SJohn Forte if (options && already_set) { 3607*fcf3ce44SJohn Forte char *p, *q; 3608*fcf3ce44SJohn Forte int need_to_clear_buf = 1; 3609*fcf3ce44SJohn Forte 3610*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) 3611*fcf3ce44SJohn Forte < 0) { 3612*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to get " 3613*fcf3ce44SJohn Forte "options field for Remote Mirror set " 3614*fcf3ce44SJohn Forte "%s:%s"), tmpair.thost, tmpair.tfile); 3615*fcf3ce44SJohn Forte } 3616*fcf3ce44SJohn Forte 3617*fcf3ce44SJohn Forte /* 3618*fcf3ce44SJohn Forte * parse out our options, all of the 3619*fcf3ce44SJohn Forte * form "auto=" 3620*fcf3ce44SJohn Forte */ 3621*fcf3ce44SJohn Forte p = strdup(buf); 3622*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 3623*fcf3ce44SJohn Forte 3624*fcf3ce44SJohn Forte q = strtok(p, ";"); 3625*fcf3ce44SJohn Forte do { 3626*fcf3ce44SJohn Forte /* 3627*fcf3ce44SJohn Forte * if another tag/value exists, 3628*fcf3ce44SJohn Forte * keep it 3629*fcf3ce44SJohn Forte */ 3630*fcf3ce44SJohn Forte if (strncmp(auto_tag, q, 4) != 0) { 3631*fcf3ce44SJohn Forte strcat(buf, q); 3632*fcf3ce44SJohn Forte strcat(buf, ";"); 3633*fcf3ce44SJohn Forte need_to_clear_buf = 0; 3634*fcf3ce44SJohn Forte } 3635*fcf3ce44SJohn Forte } while (q = strtok(NULL, ";")); 3636*fcf3ce44SJohn Forte free(p); 3637*fcf3ce44SJohn Forte 3638*fcf3ce44SJohn Forte /* 3639*fcf3ce44SJohn Forte * if we were the only option, 3640*fcf3ce44SJohn Forte * clear the field 3641*fcf3ce44SJohn Forte */ 3642*fcf3ce44SJohn Forte if (need_to_clear_buf) { 3643*fcf3ce44SJohn Forte strcat(buf, "-"); 3644*fcf3ce44SJohn Forte } 3645*fcf3ce44SJohn Forte 3646*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF) 3647*fcf3ce44SJohn Forte < 0) { 3648*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to clear " 3649*fcf3ce44SJohn Forte "autosync value in config for " 3650*fcf3ce44SJohn Forte "Remote Mirror set %s:%s"), 3651*fcf3ce44SJohn Forte tmpair.thost, tmpair.tfile); 3652*fcf3ce44SJohn Forte cfg_success = 0; 3653*fcf3ce44SJohn Forte } 3654*fcf3ce44SJohn Forte } 3655*fcf3ce44SJohn Forte 3656*fcf3ce44SJohn Forte /* 3657*fcf3ce44SJohn Forte * autosync is not present in options field, 3658*fcf3ce44SJohn Forte * add if on is requested 3659*fcf3ce44SJohn Forte */ 3660*fcf3ce44SJohn Forte if (autosync_val == AUTOSYNC_ON) { 3661*fcf3ce44SJohn Forte if (cfg_put_options(cfg, CFG_SEC_CONF, key, 3662*fcf3ce44SJohn Forte auto_tag, "on") < 0) { 3663*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to update" 3664*fcf3ce44SJohn Forte " autosync value in config for " 3665*fcf3ce44SJohn Forte "Remote Mirror set %s:%s"), 3666*fcf3ce44SJohn Forte tmpair.thost, 3667*fcf3ce44SJohn Forte tmpair.tfile); 3668*fcf3ce44SJohn Forte cfg_success = 0; 3669*fcf3ce44SJohn Forte } 3670*fcf3ce44SJohn Forte } 3671*fcf3ce44SJohn Forte } 3672*fcf3ce44SJohn Forte 3673*fcf3ce44SJohn Forte /* CONSTCOND */ 3674*fcf3ce44SJohn Forte } while (0); 3675*fcf3ce44SJohn Forte if (cfg_success) { 3676*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) { 3677*fcf3ce44SJohn Forte rdc_err(NULL, gettext("commit on role reversal failed")); 3678*fcf3ce44SJohn Forte } 3679*fcf3ce44SJohn Forte } 3680*fcf3ce44SJohn Forte 3681*fcf3ce44SJohn Forte cfg_close(cfg); 3682*fcf3ce44SJohn Forte } 3683*fcf3ce44SJohn Forte 3684*fcf3ce44SJohn Forte /* 3685*fcf3ce44SJohn Forte * Check to see if autosync is on for set specified by tohost:tofile. 3686*fcf3ce44SJohn Forte * 3687*fcf3ce44SJohn Forte * ASSUMPTIONS: 3688*fcf3ce44SJohn Forte * config is available to take a read lock against it. 3689*fcf3ce44SJohn Forte * 3690*fcf3ce44SJohn Forte * INPUTS: 3691*fcf3ce44SJohn Forte * tohost - secondary host 3692*fcf3ce44SJohn Forte * tofile - secondary volume 3693*fcf3ce44SJohn Forte * 3694*fcf3ce44SJohn Forte * OUTPUTS: 3695*fcf3ce44SJohn Forte * -1 error 3696*fcf3ce44SJohn Forte * AUTOSYNC_ON if autosync is on 3697*fcf3ce44SJohn Forte * AUTOSYNC_OFF if autosync is off 3698*fcf3ce44SJohn Forte */ 3699*fcf3ce44SJohn Forte static int 3700*fcf3ce44SJohn Forte autosync_is_on(char *tohost, char *tofile) 3701*fcf3ce44SJohn Forte { 3702*fcf3ce44SJohn Forte CFGFILE *cfg; 3703*fcf3ce44SJohn Forte int setnumber, autosync_val = AUTOSYNC_OFF; 3704*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 3705*fcf3ce44SJohn Forte char tag[CFG_MAX_BUF], val[CFG_MAX_BUF]; 3706*fcf3ce44SJohn Forte 3707*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 3708*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to access configuration")); 3709*fcf3ce44SJohn Forte } 3710*fcf3ce44SJohn Forte 3711*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) { 3712*fcf3ce44SJohn Forte cfg_close(cfg); 3713*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 3714*fcf3ce44SJohn Forte } 3715*fcf3ce44SJohn Forte 3716*fcf3ce44SJohn Forte if ((setnumber = find_setnumber_in_libcfg(cfg, NULL, tohost, tofile)) < 3717*fcf3ce44SJohn Forte 0) { 3718*fcf3ce44SJohn Forte cfg_close(cfg); 3719*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cannot find Remote Mirror set %s:%s in " 3720*fcf3ce44SJohn Forte "config"), tohost, tofile); 3721*fcf3ce44SJohn Forte } 3722*fcf3ce44SJohn Forte 3723*fcf3ce44SJohn Forte (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d.options", setnumber); 3724*fcf3ce44SJohn Forte if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val, 3725*fcf3ce44SJohn Forte CFG_MAX_BUF) >= 0) { 3726*fcf3ce44SJohn Forte do { 3727*fcf3ce44SJohn Forte if (strcmp(tag, "auto") == 0) { 3728*fcf3ce44SJohn Forte if (strcmp(val, "on") == 0) { 3729*fcf3ce44SJohn Forte autosync_val = AUTOSYNC_ON; 3730*fcf3ce44SJohn Forte } 3731*fcf3ce44SJohn Forte break; 3732*fcf3ce44SJohn Forte } 3733*fcf3ce44SJohn Forte } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag, 3734*fcf3ce44SJohn Forte CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0); 3735*fcf3ce44SJohn Forte } 3736*fcf3ce44SJohn Forte 3737*fcf3ce44SJohn Forte cfg_close(cfg); 3738*fcf3ce44SJohn Forte return (autosync_val); 3739*fcf3ce44SJohn Forte } 3740*fcf3ce44SJohn Forte 3741*fcf3ce44SJohn Forte void 3742*fcf3ce44SJohn Forte enable_autosync(char *fhost, char *ffile, char *thost, char *tfile) 3743*fcf3ce44SJohn Forte { 3744*fcf3ce44SJohn Forte rdc_config_t parms; 3745*fcf3ce44SJohn Forte spcs_s_info_t ustat; 3746*fcf3ce44SJohn Forte rdc_addr_t *p; 3747*fcf3ce44SJohn Forte 3748*fcf3ce44SJohn Forte ustat = spcs_s_ucreate(); 3749*fcf3ce44SJohn Forte parms.command = RDC_CMD_TUNABLE; 3750*fcf3ce44SJohn Forte 3751*fcf3ce44SJohn Forte p = &parms.rdc_set[0].primary; 3752*fcf3ce44SJohn Forte strncpy(p->intf, fhost, MAX_RDC_HOST_SIZE); 3753*fcf3ce44SJohn Forte strncpy(p->file, ffile, MAX_RDC_HOST_SIZE); 3754*fcf3ce44SJohn Forte 3755*fcf3ce44SJohn Forte p = &parms.rdc_set[0].secondary; 3756*fcf3ce44SJohn Forte strncpy(p->intf, thost, NSC_MAXPATH); 3757*fcf3ce44SJohn Forte strncpy(p->file, tfile, NSC_MAXPATH); 3758*fcf3ce44SJohn Forte 3759*fcf3ce44SJohn Forte parms.rdc_set[0].autosync = 1; 3760*fcf3ce44SJohn Forte parms.rdc_set[0].maxqfbas = -1; 3761*fcf3ce44SJohn Forte parms.rdc_set[0].maxqitems = -1; 3762*fcf3ce44SJohn Forte parms.rdc_set[0].asyncthr = -1; 3763*fcf3ce44SJohn Forte parms.rdc_set[0].netconfig = NULL; 3764*fcf3ce44SJohn Forte 3765*fcf3ce44SJohn Forte if ((RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustat)) != 3766*fcf3ce44SJohn Forte SPCS_S_OK) { 3767*fcf3ce44SJohn Forte rdc_warn(&ustat, gettext("failed to update autosync for" 3768*fcf3ce44SJohn Forte " Remote Mirror set %s:%s"), thost, tfile); 3769*fcf3ce44SJohn Forte spcs_log("sndr", &ustat, gettext("failed to update autosync for" 3770*fcf3ce44SJohn Forte " Remote Mirror set %s:%s"), thost, tfile); 3771*fcf3ce44SJohn Forte } 3772*fcf3ce44SJohn Forte spcs_s_ufree(&ustat); 3773*fcf3ce44SJohn Forte } 3774*fcf3ce44SJohn Forte 3775*fcf3ce44SJohn Forte static int 3776*fcf3ce44SJohn Forte rdc_operation(CFGFILE *cfg, char *fromhost, char *fromfile, char *frombitmap, 3777*fcf3ce44SJohn Forte char *tohost, char *tofile, char *tobitmap, 3778*fcf3ce44SJohn Forte int flag, int iflag, 3779*fcf3ce44SJohn Forte char *directfile, char *group, char *ctag, char *diskqueue, 3780*fcf3ce44SJohn Forte int *doasync, int reverse) 3781*fcf3ce44SJohn Forte { 3782*fcf3ce44SJohn Forte const int getaddr = (flag == RDC_CMD_ENABLE); 3783*fcf3ce44SJohn Forte const int rpcbind = !getaddr; 3784*fcf3ce44SJohn Forte rdc_config_t parms; 3785*fcf3ce44SJohn Forte int ret; 3786*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 3787*fcf3ce44SJohn Forte struct hostent *hp; 3788*fcf3ce44SJohn Forte char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN]; 3789*fcf3ce44SJohn Forte char orig_fbmp[MAXHOSTNAMELEN], orig_tbmp[MAXHOSTNAMELEN]; 3790*fcf3ce44SJohn Forte char orig_diskq[NSC_MAXPATH]; 3791*fcf3ce44SJohn Forte struct t_info tinfo; 3792*fcf3ce44SJohn Forte int success = 1; 3793*fcf3ce44SJohn Forte int autosync_toggle_needed = 0; 3794*fcf3ce44SJohn Forte char *vol1, *vol2, *vol3; 3795*fcf3ce44SJohn Forte 3796*fcf3ce44SJohn Forte conf = &nconf; 3797*fcf3ce44SJohn Forte 3798*fcf3ce44SJohn Forte hp = gethost_byname(fromhost); 3799*fcf3ce44SJohn Forte strncpy(fromname, hp->h_name, MAXHOSTNAMELEN); 3800*fcf3ce44SJohn Forte hp = gethost_byname(tohost); 3801*fcf3ce44SJohn Forte strncpy(toname, hp->h_name, MAXHOSTNAMELEN); 3802*fcf3ce44SJohn Forte 3803*fcf3ce44SJohn Forte if (self_check(fromname) && self_check(toname)) { 3804*fcf3ce44SJohn Forte rdc_err(NULL, gettext("both %s and %s are local"), 3805*fcf3ce44SJohn Forte fromhost, tohost); 3806*fcf3ce44SJohn Forte } 3807*fcf3ce44SJohn Forte 3808*fcf3ce44SJohn Forte /* we have to find out what to sv disable after reconfig */ 3809*fcf3ce44SJohn Forte if (flag == RDC_CMD_RECONFIG) { 3810*fcf3ce44SJohn Forte 3811*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 3812*fcf3ce44SJohn Forte parms.rdc_set->netconfig = NULL; 3813*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.intf, fromhost, 3814*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 3815*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.intf, tohost, 3816*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 3817*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.file, fromfile, 3818*fcf3ce44SJohn Forte NSC_MAXPATH); 3819*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.file, tofile, 3820*fcf3ce44SJohn Forte NSC_MAXPATH); 3821*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 3822*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 3823*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 3824*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 3825*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to get set status" 3826*fcf3ce44SJohn Forte " before reconfig operation")); 3827*fcf3ce44SJohn Forte } 3828*fcf3ce44SJohn Forte strncpy(orig_fbmp, parms.rdc_set->primary.bitmap, 3829*fcf3ce44SJohn Forte NSC_MAXPATH); 3830*fcf3ce44SJohn Forte strncpy(orig_tbmp, parms.rdc_set->secondary.bitmap, 3831*fcf3ce44SJohn Forte NSC_MAXPATH); 3832*fcf3ce44SJohn Forte strncpy(orig_diskq, parms.rdc_set->disk_queue, NSC_MAXPATH); 3833*fcf3ce44SJohn Forte } 3834*fcf3ce44SJohn Forte 3835*fcf3ce44SJohn Forte /* 3836*fcf3ce44SJohn Forte * another terrible addition, if we are reconfigging mode 3837*fcf3ce44SJohn Forte * and not logging, just give up. 3838*fcf3ce44SJohn Forte */ 3839*fcf3ce44SJohn Forte if ((reconfig_doasync != -1) && 3840*fcf3ce44SJohn Forte (!(parms.rdc_set->flags & RDC_LOGGING))) { 3841*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cannot reconfigure sync/async, " 3842*fcf3ce44SJohn Forte "Remote Mirror set not logging")); 3843*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("cannot reconfigure sync/async, " 3844*fcf3ce44SJohn Forte "Remote Mirror set not logging")); 3845*fcf3ce44SJohn Forte } 3846*fcf3ce44SJohn Forte 3847*fcf3ce44SJohn Forte /* 3848*fcf3ce44SJohn Forte * Now build up the address for each host including port and transport 3849*fcf3ce44SJohn Forte */ 3850*fcf3ce44SJohn Forte if (getaddr) { 3851*fcf3ce44SJohn Forte svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN, 3852*fcf3ce44SJohn Forte &conf, proto_test ? NC_UDP:NULL, "rdc", &tinfo, 3853*fcf3ce44SJohn Forte rpcbind); 3854*fcf3ce44SJohn Forte 3855*fcf3ce44SJohn Forte if (svp == NULL) { 3856*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("unable to determine network " 3857*fcf3ce44SJohn Forte "information for %s"), toname); 3858*fcf3ce44SJohn Forte #ifdef DEBUG 3859*fcf3ce44SJohn Forte (void) printf("get_addr failed for Ver 4 %s\n", toname); 3860*fcf3ce44SJohn Forte #endif 3861*fcf3ce44SJohn Forte return (-1); 3862*fcf3ce44SJohn Forte } 3863*fcf3ce44SJohn Forte svaddr = *svp; 3864*fcf3ce44SJohn Forte } else { 3865*fcf3ce44SJohn Forte bzero(&svaddr, sizeof (svaddr)); 3866*fcf3ce44SJohn Forte } 3867*fcf3ce44SJohn Forte 3868*fcf3ce44SJohn Forte parms.rdc_set->secondary.addr.len = svaddr.len; 3869*fcf3ce44SJohn Forte parms.rdc_set->secondary.addr.maxlen = 3870*fcf3ce44SJohn Forte svaddr.maxlen; 3871*fcf3ce44SJohn Forte parms.rdc_set->secondary.addr.buf = 3872*fcf3ce44SJohn Forte (void *)svaddr.buf; 3873*fcf3ce44SJohn Forte 3874*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR 3875*fcf3ce44SJohn Forte (void) fprintf(stderr, "secondary buf %x len %d\n", 3876*fcf3ce44SJohn Forte svaddr.buf, svaddr.len); 3877*fcf3ce44SJohn Forte 3878*fcf3ce44SJohn Forte for (i = 0; i < svaddr.len; i++) 3879*fcf3ce44SJohn Forte (void) printf("%u ", svaddr.buf[i]); 3880*fcf3ce44SJohn Forte (void) printf("\n"); 3881*fcf3ce44SJohn Forte #endif 3882*fcf3ce44SJohn Forte 3883*fcf3ce44SJohn Forte if (getaddr) { 3884*fcf3ce44SJohn Forte svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN, 3885*fcf3ce44SJohn Forte &conf, proto_test ? NC_UDP: NULL, "rdc", &tinfo, 3886*fcf3ce44SJohn Forte rpcbind); 3887*fcf3ce44SJohn Forte if (svp == NULL) { 3888*fcf3ce44SJohn Forte #ifdef DEBUG 3889*fcf3ce44SJohn Forte (void) printf("get_addr failed for Ver 4 %s\n", 3890*fcf3ce44SJohn Forte fromname); 3891*fcf3ce44SJohn Forte #endif 3892*fcf3ce44SJohn Forte return (-1); 3893*fcf3ce44SJohn Forte } 3894*fcf3ce44SJohn Forte svaddr = *svp; 3895*fcf3ce44SJohn Forte } 3896*fcf3ce44SJohn Forte 3897*fcf3ce44SJohn Forte parms.rdc_set->primary.addr.len = svaddr.len; 3898*fcf3ce44SJohn Forte parms.rdc_set->primary.addr.maxlen = svaddr.maxlen; 3899*fcf3ce44SJohn Forte parms.rdc_set->primary.addr.buf = (void *)svaddr.buf; 3900*fcf3ce44SJohn Forte 3901*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR 3902*fcf3ce44SJohn Forte (void) fprintf(stderr, "primary buf %x len %d\n", 3903*fcf3ce44SJohn Forte svaddr.buf, svaddr.len); 3904*fcf3ce44SJohn Forte for (i = 0; i < svaddr.len; i++) 3905*fcf3ce44SJohn Forte (void) printf("%u ", svaddr.buf[i]); 3906*fcf3ce44SJohn Forte (void) printf("\n"); 3907*fcf3ce44SJohn Forte #endif 3908*fcf3ce44SJohn Forte 3909*fcf3ce44SJohn Forte if (getaddr) { 3910*fcf3ce44SJohn Forte (void) convert_nconf_to_knconf(conf, &knconf); 3911*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR 3912*fcf3ce44SJohn Forte (void) printf("knconf %x %s %s %x\n", knconf.knc_semantics, 3913*fcf3ce44SJohn Forte knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev); 3914*fcf3ce44SJohn Forte #endif 3915*fcf3ce44SJohn Forte parms.rdc_set->netconfig = &knconf; 3916*fcf3ce44SJohn Forte } else { 3917*fcf3ce44SJohn Forte parms.rdc_set->netconfig = NULL; 3918*fcf3ce44SJohn Forte } 3919*fcf3ce44SJohn Forte 3920*fcf3ce44SJohn Forte if (!self_check(fromname) && !self_check(toname)) { 3921*fcf3ce44SJohn Forte if (!clustered) 3922*fcf3ce44SJohn Forte rdc_err(NULL, gettext("neither %s nor %s is local"), 3923*fcf3ce44SJohn Forte fromhost, tohost); 3924*fcf3ce44SJohn Forte else { 3925*fcf3ce44SJohn Forte /* 3926*fcf3ce44SJohn Forte * IF we could get a list of logical hosts on this cluster 3927*fcf3ce44SJohn Forte * Then we could print something intelligent about where 3928*fcf3ce44SJohn Forte * the volume is mastered. For now, just print some babble 3929*fcf3ce44SJohn Forte * about the fact that we have no idea. 3930*fcf3ce44SJohn Forte */ 3931*fcf3ce44SJohn Forte rdc_err(NULL, 3932*fcf3ce44SJohn Forte gettext("either %s:%s or %s:%s is not local"), 3933*fcf3ce44SJohn Forte fromhost, fromfile, tohost, tofile); 3934*fcf3ce44SJohn Forte } 3935*fcf3ce44SJohn Forte } 3936*fcf3ce44SJohn Forte 3937*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.intf, fromhost, MAX_RDC_HOST_SIZE); 3938*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH); 3939*fcf3ce44SJohn Forte strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH); 3940*fcf3ce44SJohn Forte 3941*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.intf, tohost, MAX_RDC_HOST_SIZE); 3942*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH); 3943*fcf3ce44SJohn Forte strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH); 3944*fcf3ce44SJohn Forte 3945*fcf3ce44SJohn Forte if ((group == NULL) || ((strcmp(group, "-")) == 0)) 3946*fcf3ce44SJohn Forte parms.rdc_set->group_name[0] = 0; 3947*fcf3ce44SJohn Forte else 3948*fcf3ce44SJohn Forte strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH); 3949*fcf3ce44SJohn Forte 3950*fcf3ce44SJohn Forte if (self_check(tohost) && 3951*fcf3ce44SJohn Forte (strlen(diskqueue) > 0) && (diskqueue[0] != '-')) 3952*fcf3ce44SJohn Forte if ((flag == RDC_CMD_ENABLE) || (flag == RDC_CMD_ADDQ)) 3953*fcf3ce44SJohn Forte rdc_err(NULL, gettext("enabling disk queue on a Remote" 3954*fcf3ce44SJohn Forte " Mirror secondary is not allowed (%s)"), 3955*fcf3ce44SJohn Forte diskqueue); 3956*fcf3ce44SJohn Forte 3957*fcf3ce44SJohn Forte if ((diskqueue == NULL) || ((strcmp(diskqueue, "-")) == 0)) 3958*fcf3ce44SJohn Forte parms.rdc_set->disk_queue[0] = 0; 3959*fcf3ce44SJohn Forte else 3960*fcf3ce44SJohn Forte strncpy(parms.rdc_set->disk_queue, diskqueue, NSC_MAXPATH); 3961*fcf3ce44SJohn Forte 3962*fcf3ce44SJohn Forte parms.rdc_set->maxqfbas = maxqfbas; 3963*fcf3ce44SJohn Forte parms.rdc_set->maxqitems = maxqitems; 3964*fcf3ce44SJohn Forte parms.rdc_set->asyncthr = asyncthr; 3965*fcf3ce44SJohn Forte /* set up the permanent set id for this set */ 3966*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE) { 3967*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 3968*fcf3ce44SJohn Forte char setid[64]; 3969*fcf3ce44SJohn Forte int set; 3970*fcf3ce44SJohn Forte parms.rdc_set->setid = get_new_cfg_setid(cfg); 3971*fcf3ce44SJohn Forte if (parms.rdc_set->setid <= 0) { 3972*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to obtain unique set id " 3973*fcf3ce44SJohn Forte "for %s:%s"), tohost, tofile); 3974*fcf3ce44SJohn Forte } 3975*fcf3ce44SJohn Forte if ((set = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL, 3976*fcf3ce44SJohn Forte tohost, tofile)) < 0) { 3977*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to store unique set id" 3978*fcf3ce44SJohn Forte " for %s:%s"), tohost, tofile); 3979*fcf3ce44SJohn Forte } 3980*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.options", set); 3981*fcf3ce44SJohn Forte (void) snprintf(setid, sizeof (setid), "%d", 3982*fcf3ce44SJohn Forte parms.rdc_set->setid); 3983*fcf3ce44SJohn Forte 3984*fcf3ce44SJohn Forte if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid", 3985*fcf3ce44SJohn Forte setid) < 0) { 3986*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to store unique set " 3987*fcf3ce44SJohn Forte "id for %s:%s: %s"), tohost, tofile, 3988*fcf3ce44SJohn Forte gettext(cfg_error(NULL))); 3989*fcf3ce44SJohn Forte } 3990*fcf3ce44SJohn Forte } else if (flag != RDC_CMD_DISABLE) { /* set already gone from cfg */ 3991*fcf3ce44SJohn Forte parms.rdc_set->setid = get_cfg_setid(cfg, ctag, tohost, tofile); 3992*fcf3ce44SJohn Forte if (parms.rdc_set->setid <= 0) { 3993*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to obtain unique set id " 3994*fcf3ce44SJohn Forte "for %s:%s"), tohost, tofile); 3995*fcf3ce44SJohn Forte } 3996*fcf3ce44SJohn Forte } 3997*fcf3ce44SJohn Forte 3998*fcf3ce44SJohn Forte /* 3999*fcf3ce44SJohn Forte * Always set autosync flag to default so nothing gets messed up. If 4000*fcf3ce44SJohn Forte * we are doing an autosync operation, it'll all get taken care of 4001*fcf3ce44SJohn Forte * then. 4002*fcf3ce44SJohn Forte */ 4003*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC; 4004*fcf3ce44SJohn Forte 4005*fcf3ce44SJohn Forte 4006*fcf3ce44SJohn Forte /* gethostid(3c) is defined to return a 32bit value */ 4007*fcf3ce44SJohn Forte parms.rdc_set->syshostid = (int32_t)gethostid(); 4008*fcf3ce44SJohn Forte 4009*fcf3ce44SJohn Forte parms.command = 0; 4010*fcf3ce44SJohn Forte parms.options = iflag; 4011*fcf3ce44SJohn Forte parms.command = flag; 4012*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) { 4013*fcf3ce44SJohn Forte if (*doasync) 4014*fcf3ce44SJohn Forte parms.options |= RDC_OPT_ASYNC; 4015*fcf3ce44SJohn Forte else 4016*fcf3ce44SJohn Forte parms.options |= RDC_OPT_SYNC; 4017*fcf3ce44SJohn Forte } else if (flag == RDC_CMD_COPY) { 4018*fcf3ce44SJohn Forte if (reverse) 4019*fcf3ce44SJohn Forte parms.options |= RDC_OPT_REVERSE; 4020*fcf3ce44SJohn Forte else 4021*fcf3ce44SJohn Forte parms.options |= RDC_OPT_FORWARD; 4022*fcf3ce44SJohn Forte } 4023*fcf3ce44SJohn Forte 4024*fcf3ce44SJohn Forte if (self_check(fromname)) { 4025*fcf3ce44SJohn Forte if (flag == RDC_CMD_COPY && reverse && mounted(fromfile)) 4026*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not start reverse sync" 4027*fcf3ce44SJohn Forte " as a file system is mounted on %s"), 4028*fcf3ce44SJohn Forte fromfile); 4029*fcf3ce44SJohn Forte parms.options |= RDC_OPT_PRIMARY; 4030*fcf3ce44SJohn Forte if (strcmp(directfile, "ip") == 0) 4031*fcf3ce44SJohn Forte parms.rdc_set->direct_file[0] = 0; /* no directfile */ 4032*fcf3ce44SJohn Forte else 4033*fcf3ce44SJohn Forte strncpy(parms.rdc_set->direct_file, directfile, 4034*fcf3ce44SJohn Forte NSC_MAXPATH); 4035*fcf3ce44SJohn Forte } else { 4036*fcf3ce44SJohn Forte parms.options |= RDC_OPT_SECONDARY; 4037*fcf3ce44SJohn Forte parms.rdc_set->direct_file[0] = 0; /* no fcal directio */ 4038*fcf3ce44SJohn Forte } 4039*fcf3ce44SJohn Forte 4040*fcf3ce44SJohn Forte if ((asyncthr || maxqitems || maxqfbas || qblock) && 4041*fcf3ce44SJohn Forte (parms.options & RDC_OPT_SECONDARY)) { 4042*fcf3ce44SJohn Forte rdc_err(NULL, gettext("changing queue parameters may " 4043*fcf3ce44SJohn Forte " only be done on a primary Remote Mirror host")); 4044*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("changing queue parameters may " 4045*fcf3ce44SJohn Forte " only be done on a primary Remote Mirror host")); 4046*fcf3ce44SJohn Forte 4047*fcf3ce44SJohn Forte } 4048*fcf3ce44SJohn Forte 4049*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 4050*fcf3ce44SJohn Forte 4051*fcf3ce44SJohn Forte if (flag == RDC_CMD_COPY) { 4052*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 4053*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); 4054*fcf3ce44SJohn Forte if ((ret != SPCS_S_OK) || 4055*fcf3ce44SJohn Forte !(parms.rdc_set->flags & RDC_LOGGING)) { 4056*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not start sync" 4057*fcf3ce44SJohn Forte " as Remote Mirror set %s:%s is not logging"), 4058*fcf3ce44SJohn Forte tohost, tofile); 4059*fcf3ce44SJohn Forte } 4060*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4061*fcf3ce44SJohn Forte gettext("%s %s %s %s %s %s %s %s\nStarting"), 4062*fcf3ce44SJohn Forte program, rdc_decode_flag(flag, parms.options), 4063*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4064*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4065*fcf3ce44SJohn Forte parms.command = RDC_CMD_COPY; 4066*fcf3ce44SJohn Forte } 4067*fcf3ce44SJohn Forte 4068*fcf3ce44SJohn Forte if ((flag == RDC_CMD_COPY) && 4069*fcf3ce44SJohn Forte (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) { 4070*fcf3ce44SJohn Forte /* check if autosync needs to be turned on when doing a copy/update */ 4071*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC_ON; 4072*fcf3ce44SJohn Forte autosync_toggle_needed = 1; 4073*fcf3ce44SJohn Forte } else if ((flag == RDC_CMD_LOG) && 4074*fcf3ce44SJohn Forte (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) { 4075*fcf3ce44SJohn Forte /* check if autosync needs to be turned off when going to logging */ 4076*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC_OFF; 4077*fcf3ce44SJohn Forte autosync_toggle_needed = 1; 4078*fcf3ce44SJohn Forte } else if (((autosync == AUTOSYNC_ON) || (autosync == AUTOSYNC_OFF)) && 4079*fcf3ce44SJohn Forte (flag == RDC_CMD_TUNABLE)) { 4080*fcf3ce44SJohn Forte /* 4081*fcf3ce44SJohn Forte * Request to change the autosync value. cfg file will be 4082*fcf3ce44SJohn Forte * available at this point. If autosync request is to turn off, 4083*fcf3ce44SJohn Forte * mark off in both the config and the kernel regardless of 4084*fcf3ce44SJohn Forte * the state of the set. If the request is to turn autosync on, 4085*fcf3ce44SJohn Forte * set in the kernel if the set is not in logging mode. 4086*fcf3ce44SJohn Forte * 4087*fcf3ce44SJohn Forte * XXX 4088*fcf3ce44SJohn Forte * If the set is in logging mode because of a network 4089*fcf3ce44SJohn Forte * failure, we will not know. Therefore, a manual update 4090*fcf3ce44SJohn Forte * will have to be issued to enable autosync in the 4091*fcf3ce44SJohn Forte * kernel. 4092*fcf3ce44SJohn Forte * XXX 4093*fcf3ce44SJohn Forte */ 4094*fcf3ce44SJohn Forte set_autosync(autosync, tohost, tofile, ctag); 4095*fcf3ce44SJohn Forte 4096*fcf3ce44SJohn Forte if (autosync == AUTOSYNC_OFF) { 4097*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC_OFF; 4098*fcf3ce44SJohn Forte } else if (autosync == AUTOSYNC_ON) { 4099*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 4100*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, 4101*fcf3ce44SJohn Forte ustatus); 4102*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4103*fcf3ce44SJohn Forte rdc_err(NULL, gettext("can not determine " 4104*fcf3ce44SJohn Forte "status of Remote Mirror set %s:%s"), 4105*fcf3ce44SJohn Forte tohost, tofile); 4106*fcf3ce44SJohn Forte } 4107*fcf3ce44SJohn Forte 4108*fcf3ce44SJohn Forte /* need to reset the tunables after a status ioctl */ 4109*fcf3ce44SJohn Forte parms.rdc_set->autosync = autosync; 4110*fcf3ce44SJohn Forte parms.rdc_set->maxqfbas = maxqfbas; 4111*fcf3ce44SJohn Forte parms.rdc_set->maxqitems = maxqitems; 4112*fcf3ce44SJohn Forte parms.rdc_set->asyncthr = asyncthr; 4113*fcf3ce44SJohn Forte 4114*fcf3ce44SJohn Forte /* 4115*fcf3ce44SJohn Forte * if in logging mode, just update config, kernel will 4116*fcf3ce44SJohn Forte * be updated with the next copy/update request. 4117*fcf3ce44SJohn Forte */ 4118*fcf3ce44SJohn Forte if (parms.rdc_set->flags & RDC_LOGGING) { 4119*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC; 4120*fcf3ce44SJohn Forte } else { 4121*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC_ON; 4122*fcf3ce44SJohn Forte } 4123*fcf3ce44SJohn Forte 4124*fcf3ce44SJohn Forte parms.command = flag; 4125*fcf3ce44SJohn Forte } 4126*fcf3ce44SJohn Forte } 4127*fcf3ce44SJohn Forte 4128*fcf3ce44SJohn Forte if (autosync_toggle_needed) { 4129*fcf3ce44SJohn Forte parms.command = RDC_CMD_TUNABLE; 4130*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); 4131*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4132*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("failed to update " 4133*fcf3ce44SJohn Forte "autosync for Remote Mirror set %s:%s"), tohost, 4134*fcf3ce44SJohn Forte tofile); 4135*fcf3ce44SJohn Forte rdc_err(NULL, gettext("failed to update autosync for " 4136*fcf3ce44SJohn Forte "Remote Mirror set %s:%s"), tohost, tofile); 4137*fcf3ce44SJohn Forte } 4138*fcf3ce44SJohn Forte /* reset command and default autosync flags */ 4139*fcf3ce44SJohn Forte parms.rdc_set->autosync = AUTOSYNC; 4140*fcf3ce44SJohn Forte parms.command = flag; 4141*fcf3ce44SJohn Forte } 4142*fcf3ce44SJohn Forte 4143*fcf3ce44SJohn Forte errno = 0; 4144*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); 4145*fcf3ce44SJohn Forte if ((ret != SPCS_S_OK) && (flag != RDC_CMD_HEALTH)) { 4146*fcf3ce44SJohn Forte (void) fprintf(stderr, 4147*fcf3ce44SJohn Forte gettext("Remote Mirror: %s %s %s %s %s %s\n"), 4148*fcf3ce44SJohn Forte fromhost, fromfile, 4149*fcf3ce44SJohn Forte frombitmap, tohost, tofile, tobitmap); 4150*fcf3ce44SJohn Forte 4151*fcf3ce44SJohn Forte if (errno == RDC_EEINVAL) { 4152*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4153*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s\n%s", 4154*fcf3ce44SJohn Forte program, rdc_decode_flag(flag, parms.options), 4155*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4156*fcf3ce44SJohn Forte tohost, tofile, tobitmap, 4157*fcf3ce44SJohn Forte gettext("invalid command option")); 4158*fcf3ce44SJohn Forte rdc_err(&ustatus, 4159*fcf3ce44SJohn Forte gettext("Remote Mirror: invalid command option " 4160*fcf3ce44SJohn Forte "'%s'"), rdc_decode_flag(flag, 4161*fcf3ce44SJohn Forte parms.options)); 4162*fcf3ce44SJohn Forte } else { 4163*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4164*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4165*fcf3ce44SJohn Forte program, rdc_decode_flag(flag, parms.options), 4166*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4167*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4168*fcf3ce44SJohn Forte if ((flag == RDC_CMD_RECONFIG) && 4169*fcf3ce44SJohn Forte (!(iflag & RDC_OPT_REVERSE_ROLE))) { 4170*fcf3ce44SJohn Forte success = 0; 4171*fcf3ce44SJohn Forte rdc_warn(&ustatus, 0); 4172*fcf3ce44SJohn Forte } else 4173*fcf3ce44SJohn Forte rdc_err(&ustatus, 0); 4174*fcf3ce44SJohn Forte } 4175*fcf3ce44SJohn Forte } 4176*fcf3ce44SJohn Forte if ((flag == RDC_CMD_RECONFIG) && (iflag & RDC_OPT_REVERSE_ROLE) == 0) { 4177*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 4178*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) == 4179*fcf3ce44SJohn Forte SPCS_S_OK) { 4180*fcf3ce44SJohn Forte char shostbuf[CFG_MAX_BUF]; 4181*fcf3ce44SJohn Forte char svolbuf[CFG_MAX_BUF]; 4182*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 4183*fcf3ce44SJohn Forte int i, numels; 4184*fcf3ce44SJohn Forte int cfgsuccess = 1; 4185*fcf3ce44SJohn Forte 4186*fcf3ce44SJohn Forte /* 4187*fcf3ce44SJohn Forte * okeydoke, at this point we could have a reconfig 4188*fcf3ce44SJohn Forte * gone bad. libdscfg does not know about this. 4189*fcf3ce44SJohn Forte * parms contains the kernel picture, and we know 4190*fcf3ce44SJohn Forte * what we tried to reconfig. find out where it went 4191*fcf3ce44SJohn Forte * wrong, find the set in libdscfg, update it. We'll 4192*fcf3ce44SJohn Forte * issue a warning, then return 0 (eventually). 4193*fcf3ce44SJohn Forte * this will allow libdscfg to be committed with the 4194*fcf3ce44SJohn Forte * good info. got it? 4195*fcf3ce44SJohn Forte * BTW: the only time we can run into this multiple 4196*fcf3ce44SJohn Forte * reconfig attempt failure is IF we reconfig from file 4197*fcf3ce44SJohn Forte * and some thing goes wrong with one of the reconfigs 4198*fcf3ce44SJohn Forte */ 4199*fcf3ce44SJohn Forte 4200*fcf3ce44SJohn Forte /* find the set in libdscfg */ 4201*fcf3ce44SJohn Forte 4202*fcf3ce44SJohn Forte numels = cfg_get_num_entries(cfg, "sndr"); 4203*fcf3ce44SJohn Forte /* yes, numels could be -1 */ 4204*fcf3ce44SJohn Forte for (i = 1; i < numels; i++) { 4205*fcf3ce44SJohn Forte bzero(shostbuf, sizeof (shostbuf)); 4206*fcf3ce44SJohn Forte bzero(svolbuf, sizeof (svolbuf)); 4207*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4208*fcf3ce44SJohn Forte 4209*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4210*fcf3ce44SJohn Forte "sndr.set%d.shost", i); 4211*fcf3ce44SJohn Forte 4212*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, &shostbuf, 4213*fcf3ce44SJohn Forte sizeof (shostbuf)); 4214*fcf3ce44SJohn Forte if (strncmp(shostbuf, tohost, sizeof (tohost))) 4215*fcf3ce44SJohn Forte continue; 4216*fcf3ce44SJohn Forte 4217*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4218*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4219*fcf3ce44SJohn Forte "sndr.set%d.secondary", i); 4220*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, &svolbuf, 4221*fcf3ce44SJohn Forte sizeof (svolbuf)); 4222*fcf3ce44SJohn Forte if (strncmp(svolbuf, tofile, NSC_MAXPATH)) 4223*fcf3ce44SJohn Forte continue; 4224*fcf3ce44SJohn Forte break; 4225*fcf3ce44SJohn Forte 4226*fcf3ce44SJohn Forte /* 4227*fcf3ce44SJohn Forte * found it, now i contains the set offset. 4228*fcf3ce44SJohn Forte * i, being the variable, not bad english. 4229*fcf3ce44SJohn Forte */ 4230*fcf3ce44SJohn Forte 4231*fcf3ce44SJohn Forte } 4232*fcf3ce44SJohn Forte /* shouldn't happen */ 4233*fcf3ce44SJohn Forte if ((numels < 1) || (i > numels)) { 4234*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("unable to retrieve " 4235*fcf3ce44SJohn Forte "set from configuration database")); 4236*fcf3ce44SJohn Forte /* 4237*fcf3ce44SJohn Forte * yuck. but indents are pushing the envelope 4238*fcf3ce44SJohn Forte * we should not be updating config 4239*fcf3ce44SJohn Forte * if we did not find the entry 4240*fcf3ce44SJohn Forte * the error will have to do 4241*fcf3ce44SJohn Forte */ 4242*fcf3ce44SJohn Forte cfgsuccess = 0; 4243*fcf3ce44SJohn Forte goto notfound; 4244*fcf3ce44SJohn Forte } 4245*fcf3ce44SJohn Forte 4246*fcf3ce44SJohn Forte /* 4247*fcf3ce44SJohn Forte * now, put all the correct names back for errors etc. 4248*fcf3ce44SJohn Forte * also, sock them into dscfg, if the the config was a 4249*fcf3ce44SJohn Forte * success for one, it will be a redundant but harmless 4250*fcf3ce44SJohn Forte */ 4251*fcf3ce44SJohn Forte 4252*fcf3ce44SJohn Forte /* 4253*fcf3ce44SJohn Forte * we could not have reconfigged mode if we 4254*fcf3ce44SJohn Forte * are not logging, AND the kernel CAN return 4255*fcf3ce44SJohn Forte * sync as the status of an async set if it is 4256*fcf3ce44SJohn Forte * currently syncing.. Hence the flags & RDC_LOGGING 4257*fcf3ce44SJohn Forte */ 4258*fcf3ce44SJohn Forte if (parms.rdc_set->flags & RDC_LOGGING) { 4259*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4260*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4261*fcf3ce44SJohn Forte "sndr.set%d.mode", i); 4262*fcf3ce44SJohn Forte if (parms.rdc_set->flags & RDC_ASYNC) { 4263*fcf3ce44SJohn Forte *doasync = 1; 4264*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, "async", 4265*fcf3ce44SJohn Forte strlen("async")) < 0) { 4266*fcf3ce44SJohn Forte cfgsuccess = 0; 4267*fcf3ce44SJohn Forte } 4268*fcf3ce44SJohn Forte 4269*fcf3ce44SJohn Forte } else { 4270*fcf3ce44SJohn Forte *doasync = 0; 4271*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, "sync", 4272*fcf3ce44SJohn Forte strlen("sync")) < 0) { 4273*fcf3ce44SJohn Forte cfgsuccess = 0; 4274*fcf3ce44SJohn Forte } 4275*fcf3ce44SJohn Forte } 4276*fcf3ce44SJohn Forte } 4277*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 4278*fcf3ce44SJohn Forte if (*parms.rdc_set->direct_file) { 4279*fcf3ce44SJohn Forte strncpy(directfile, parms.rdc_set->direct_file, 4280*fcf3ce44SJohn Forte NSC_MAXPATH); 4281*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4282*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4283*fcf3ce44SJohn Forte "sndr.set%d.type", i); 4284*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, directfile, 4285*fcf3ce44SJohn Forte strlen(directfile)) < 0) 4286*fcf3ce44SJohn Forte cfgsuccess = 0; 4287*fcf3ce44SJohn Forte } else { 4288*fcf3ce44SJohn Forte strncpy(directfile, "-", NSC_MAXPATH); 4289*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4290*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4291*fcf3ce44SJohn Forte "sndr.set%d.type", i); 4292*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, directfile, 4293*fcf3ce44SJohn Forte strlen(directfile)) < 0) 4294*fcf3ce44SJohn Forte cfgsuccess = 0; 4295*fcf3ce44SJohn Forte } 4296*fcf3ce44SJohn Forte #endif 4297*fcf3ce44SJohn Forte 4298*fcf3ce44SJohn Forte if (*parms.rdc_set->group_name) { 4299*fcf3ce44SJohn Forte strncpy(group, parms.rdc_set->group_name, 4300*fcf3ce44SJohn Forte NSC_MAXPATH); 4301*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4302*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4303*fcf3ce44SJohn Forte "sndr.set%d.group", i); 4304*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, group, 4305*fcf3ce44SJohn Forte strlen(group)) < 0) 4306*fcf3ce44SJohn Forte cfgsuccess = 0; 4307*fcf3ce44SJohn Forte 4308*fcf3ce44SJohn Forte } else { 4309*fcf3ce44SJohn Forte strncpy(group, "-", NSC_MAXPATH); 4310*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4311*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4312*fcf3ce44SJohn Forte "sndr.set%d.group", i); 4313*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, group, 4314*fcf3ce44SJohn Forte strlen(group)) < 0) 4315*fcf3ce44SJohn Forte cfgsuccess = 0; 4316*fcf3ce44SJohn Forte } 4317*fcf3ce44SJohn Forte 4318*fcf3ce44SJohn Forte if (*parms.rdc_set->disk_queue) { 4319*fcf3ce44SJohn Forte strncpy(diskqueue, parms.rdc_set->disk_queue, 4320*fcf3ce44SJohn Forte NSC_MAXPATH); 4321*fcf3ce44SJohn Forte } else { 4322*fcf3ce44SJohn Forte strncpy(diskqueue, "-", NSC_MAXPATH); 4323*fcf3ce44SJohn Forte } 4324*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4325*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4326*fcf3ce44SJohn Forte "sndr.set%d.diskq", i); 4327*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, diskqueue, 4328*fcf3ce44SJohn Forte strlen(diskqueue)) < 0) 4329*fcf3ce44SJohn Forte cfgsuccess = 0; 4330*fcf3ce44SJohn Forte 4331*fcf3ce44SJohn Forte strncpy(frombitmap, parms.rdc_set->primary.bitmap, 4332*fcf3ce44SJohn Forte NSC_MAXPATH); 4333*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4334*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4335*fcf3ce44SJohn Forte "sndr.set%d.pbitmap", i); 4336*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, frombitmap, 4337*fcf3ce44SJohn Forte strlen(frombitmap)) < 0) 4338*fcf3ce44SJohn Forte cfgsuccess = 0; 4339*fcf3ce44SJohn Forte 4340*fcf3ce44SJohn Forte strncpy(tobitmap, parms.rdc_set->secondary.bitmap, 4341*fcf3ce44SJohn Forte NSC_MAXPATH); 4342*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4343*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4344*fcf3ce44SJohn Forte "sndr.set%d.sbitmap", i); 4345*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, tobitmap, 4346*fcf3ce44SJohn Forte strlen(tobitmap)) < 0) 4347*fcf3ce44SJohn Forte cfgsuccess = 0; 4348*fcf3ce44SJohn Forte 4349*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 4350*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 4351*fcf3ce44SJohn Forte "sndr.set%d.cnode", i); 4352*fcf3ce44SJohn Forte if (clustered) 4353*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, ctag, 4354*fcf3ce44SJohn Forte strlen(ctag)) < 0) 4355*fcf3ce44SJohn Forte cfgsuccess = 0; 4356*fcf3ce44SJohn Forte notfound: 4357*fcf3ce44SJohn Forte if (cfgsuccess == 0) { 4358*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("unable to update " 4359*fcf3ce44SJohn Forte "configuration storage")); 4360*fcf3ce44SJohn Forte } 4361*fcf3ce44SJohn Forte } else { 4362*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4363*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s\n%s", 4364*fcf3ce44SJohn Forte program, rdc_decode_flag(flag, parms.options), 4365*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4366*fcf3ce44SJohn Forte tohost, tofile, tobitmap, 4367*fcf3ce44SJohn Forte gettext("unable to update config file")); 4368*fcf3ce44SJohn Forte rdc_err(&ustatus, 4369*fcf3ce44SJohn Forte gettext("Remote Mirror: unable to update " 4370*fcf3ce44SJohn Forte "config file")); 4371*fcf3ce44SJohn Forte 4372*fcf3ce44SJohn Forte } 4373*fcf3ce44SJohn Forte } 4374*fcf3ce44SJohn Forte 4375*fcf3ce44SJohn Forte if (flag == RDC_CMD_HEALTH && errno == 0) { 4376*fcf3ce44SJohn Forte (void) fprintf(stderr, 4377*fcf3ce44SJohn Forte gettext("Remote Mirror: %s %s %s %s %s %s\n"), 4378*fcf3ce44SJohn Forte fromhost, fromfile, 4379*fcf3ce44SJohn Forte frombitmap, tohost, tofile, tobitmap); 4380*fcf3ce44SJohn Forte 4381*fcf3ce44SJohn Forte if (ret == RDC_ACTIVE) 4382*fcf3ce44SJohn Forte (void) fprintf(stderr, "Active\n"); 4383*fcf3ce44SJohn Forte else if (ret == RDC_INACTIVE) 4384*fcf3ce44SJohn Forte (void) fprintf(stderr, "Inactive\n"); 4385*fcf3ce44SJohn Forte else 4386*fcf3ce44SJohn Forte (void) fprintf(stderr, "Unknown\n"); 4387*fcf3ce44SJohn Forte } else if (ret != SPCS_S_OK) { 4388*fcf3ce44SJohn Forte if (errno == RDC_EEINVAL) { 4389*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4390*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s\n%s", 4391*fcf3ce44SJohn Forte program, rdc_decode_flag(flag, parms.options), 4392*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4393*fcf3ce44SJohn Forte tohost, tofile, tobitmap, 4394*fcf3ce44SJohn Forte gettext("invalid command option")); 4395*fcf3ce44SJohn Forte rdc_err(&ustatus, 4396*fcf3ce44SJohn Forte gettext("Remote Mirror: invalid command option " 4397*fcf3ce44SJohn Forte "'%s'"), 4398*fcf3ce44SJohn Forte rdc_decode_flag(flag, parms.options)); 4399*fcf3ce44SJohn Forte } 4400*fcf3ce44SJohn Forte } 4401*fcf3ce44SJohn Forte if (flag == RDC_CMD_STATUS) { 4402*fcf3ce44SJohn Forte (void) fprintf(stderr, 4403*fcf3ce44SJohn Forte gettext("Remote Mirror: %s %s %s %s %s %s\n"), 4404*fcf3ce44SJohn Forte fromhost, fromfile, 4405*fcf3ce44SJohn Forte frombitmap, tohost, tofile, tobitmap); 4406*fcf3ce44SJohn Forte (void) fprintf(stderr, "flags 0x%x\n", parms.rdc_set->flags | 4407*fcf3ce44SJohn Forte parms.rdc_set->sync_flags | parms.rdc_set->bmap_flags); 4408*fcf3ce44SJohn Forte } else if (success) { 4409*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4410*fcf3ce44SJohn Forte gettext("%s %s %s %s %s %s %s %s\nSuccessful"), 4411*fcf3ce44SJohn Forte program, rdc_decode_flag(flag, parms.options), 4412*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4413*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4414*fcf3ce44SJohn Forte if (flag == RDC_CMD_TUNABLE) 4415*fcf3ce44SJohn Forte spcslog_tunable(tohost, tofile); 4416*fcf3ce44SJohn Forte } 4417*fcf3ce44SJohn Forte 4418*fcf3ce44SJohn Forte if (cfg && perform_autosv()) { 4419*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 4420*fcf3ce44SJohn Forte /* figure out which are the local volumes */ 4421*fcf3ce44SJohn Forte if (parms.options & RDC_OPT_PRIMARY) { 4422*fcf3ce44SJohn Forte vol1 = fromfile; 4423*fcf3ce44SJohn Forte vol2 = frombitmap; 4424*fcf3ce44SJohn Forte if ((diskqueue && diskqueue[0]) && 4425*fcf3ce44SJohn Forte (strncmp(diskqueue, "-", 1) != 0)) 4426*fcf3ce44SJohn Forte vol3 = diskqueue; 4427*fcf3ce44SJohn Forte else 4428*fcf3ce44SJohn Forte vol3 = NULL; 4429*fcf3ce44SJohn Forte } else { 4430*fcf3ce44SJohn Forte vol1 = tofile; 4431*fcf3ce44SJohn Forte vol2 = tobitmap; 4432*fcf3ce44SJohn Forte vol3 = NULL; 4433*fcf3ce44SJohn Forte if ((flag == RDC_CMD_ENABLE) && 4434*fcf3ce44SJohn Forte (strlen(diskqueue) > 0) && 4435*fcf3ce44SJohn Forte (strncmp(diskqueue, "-", 1)) != 0) { 4436*fcf3ce44SJohn Forte rdc_warn(NULL, 4437*fcf3ce44SJohn Forte gettext("enabling a disk queue on a " 4438*fcf3ce44SJohn Forte "Remote Mirror secondary is not allowed. " 4439*fcf3ce44SJohn Forte "(%s) ignored"), diskqueue); 4440*fcf3ce44SJohn Forte } 4441*fcf3ce44SJohn Forte } 4442*fcf3ce44SJohn Forte 4443*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE) { 4444*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 4445*fcf3ce44SJohn Forte /* 4446*fcf3ce44SJohn Forte * SV-enable all local volumes 4447*fcf3ce44SJohn Forte * if the sv_enables fail, disable the sndr vols 4448*fcf3ce44SJohn Forte * that we just enabled 4449*fcf3ce44SJohn Forte * and return -1 so the cfg_commit() won't happen 4450*fcf3ce44SJohn Forte */ 4451*fcf3ce44SJohn Forte 4452*fcf3ce44SJohn Forte if (nsc_lookup(volhash, vol1) == NULL) { 4453*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, vol1, ctag, "sndr") 4454*fcf3ce44SJohn Forte < 0) { 4455*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4456*fcf3ce44SJohn Forte "sv enable failed for %s, " 4457*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4458*fcf3ce44SJohn Forte vol1, tohost, tofile); 4459*fcf3ce44SJohn Forte /* 4460*fcf3ce44SJohn Forte * warn here, but we are going to exit 4461*fcf3ce44SJohn Forte * we want to catch any errors on the 4462*fcf3ce44SJohn Forte * way down, then exit 4463*fcf3ce44SJohn Forte */ 4464*fcf3ce44SJohn Forte 4465*fcf3ce44SJohn Forte rdc_warn(NULL, 4466*fcf3ce44SJohn Forte "unable to sv enable %s\n" 4467*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4468*fcf3ce44SJohn Forte vol1, tohost, tofile); 4469*fcf3ce44SJohn Forte 4470*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 4471*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 4472*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 4473*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4474*fcf3ce44SJohn Forte (void) fprintf(stderr, 4475*fcf3ce44SJohn Forte gettext("Remote Mirror:" 4476*fcf3ce44SJohn Forte " %s %s %s %s %s %s\n"), 4477*fcf3ce44SJohn Forte fromhost, fromfile, 4478*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 4479*fcf3ce44SJohn Forte tobitmap); 4480*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4481*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4482*fcf3ce44SJohn Forte program, 4483*fcf3ce44SJohn Forte rdc_decode_flag(parms.command, 4484*fcf3ce44SJohn Forte parms.options), 4485*fcf3ce44SJohn Forte fromhost, 4486*fcf3ce44SJohn Forte fromfile, frombitmap, 4487*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4488*fcf3ce44SJohn Forte rdc_err(&ustatus, 0); 4489*fcf3ce44SJohn Forte } 4490*fcf3ce44SJohn Forte /* 4491*fcf3ce44SJohn Forte * ok, we should've reported any errs 4492*fcf3ce44SJohn Forte * exit explictly 4493*fcf3ce44SJohn Forte */ 4494*fcf3ce44SJohn Forte exit(1); 4495*fcf3ce44SJohn Forte 4496*fcf3ce44SJohn Forte } 4497*fcf3ce44SJohn Forte } 4498*fcf3ce44SJohn Forte if (vol2 && nsc_lookup(volhash, vol2) == NULL) { 4499*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, vol2, ctag, "sndr") 4500*fcf3ce44SJohn Forte < 0) { 4501*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4502*fcf3ce44SJohn Forte "sv enable failed for %s, " 4503*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4504*fcf3ce44SJohn Forte vol1, tohost, tofile); 4505*fcf3ce44SJohn Forte /* 4506*fcf3ce44SJohn Forte * warn here, but we are going to exit 4507*fcf3ce44SJohn Forte * we want to catch any errors on the 4508*fcf3ce44SJohn Forte * way down, then exit 4509*fcf3ce44SJohn Forte */ 4510*fcf3ce44SJohn Forte 4511*fcf3ce44SJohn Forte rdc_warn(NULL, 4512*fcf3ce44SJohn Forte "unable to sv enable %s\n" 4513*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4514*fcf3ce44SJohn Forte vol2, tohost, tofile); 4515*fcf3ce44SJohn Forte 4516*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 4517*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 4518*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 4519*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4520*fcf3ce44SJohn Forte (void) fprintf(stderr, 4521*fcf3ce44SJohn Forte gettext("Remote Mirror:" 4522*fcf3ce44SJohn Forte " %s %s %s %s %s %s\n"), 4523*fcf3ce44SJohn Forte fromhost, fromfile, 4524*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 4525*fcf3ce44SJohn Forte tobitmap); 4526*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4527*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4528*fcf3ce44SJohn Forte program, 4529*fcf3ce44SJohn Forte rdc_decode_flag(parms.command, 4530*fcf3ce44SJohn Forte parms.options), 4531*fcf3ce44SJohn Forte fromhost, 4532*fcf3ce44SJohn Forte fromfile, frombitmap, 4533*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4534*fcf3ce44SJohn Forte rdc_err(&ustatus, 0); 4535*fcf3ce44SJohn Forte } 4536*fcf3ce44SJohn Forte /* 4537*fcf3ce44SJohn Forte * ok, we should've reported any errs 4538*fcf3ce44SJohn Forte * exit explictly 4539*fcf3ce44SJohn Forte */ 4540*fcf3ce44SJohn Forte exit(1); 4541*fcf3ce44SJohn Forte 4542*fcf3ce44SJohn Forte } 4543*fcf3ce44SJohn Forte } 4544*fcf3ce44SJohn Forte 4545*fcf3ce44SJohn Forte if (vol3 && nsc_lookup(volhash, diskqueue) == NULL) { 4546*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, diskqueue, ctag, "sndr") 4547*fcf3ce44SJohn Forte < 0) { 4548*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4549*fcf3ce44SJohn Forte "sv enable failed for %s, " 4550*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4551*fcf3ce44SJohn Forte diskqueue, tohost, tofile); 4552*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, vol1, ctag, 4553*fcf3ce44SJohn Forte "sndr") < 0) 4554*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4555*fcf3ce44SJohn Forte "remove volume [%s] from " 4556*fcf3ce44SJohn Forte "configuration"), vol1); 4557*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, vol2, ctag, 4558*fcf3ce44SJohn Forte "sndr") < 0) 4559*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4560*fcf3ce44SJohn Forte "remove volume [%s] from " 4561*fcf3ce44SJohn Forte "configuration"), vol2); 4562*fcf3ce44SJohn Forte 4563*fcf3ce44SJohn Forte /* 4564*fcf3ce44SJohn Forte * warn here, but we are going to exit 4565*fcf3ce44SJohn Forte * we want to catch any errors on the 4566*fcf3ce44SJohn Forte * way down, then exit 4567*fcf3ce44SJohn Forte */ 4568*fcf3ce44SJohn Forte 4569*fcf3ce44SJohn Forte rdc_warn(NULL, 4570*fcf3ce44SJohn Forte "unable to sv enable %s\n" 4571*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4572*fcf3ce44SJohn Forte diskqueue, tohost, tofile); 4573*fcf3ce44SJohn Forte 4574*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 4575*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 4576*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 4577*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4578*fcf3ce44SJohn Forte (void) fprintf(stderr, 4579*fcf3ce44SJohn Forte gettext("Remote Mirror:" 4580*fcf3ce44SJohn Forte " %s %s %s %s %s %s\n"), 4581*fcf3ce44SJohn Forte fromhost, fromfile, 4582*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 4583*fcf3ce44SJohn Forte tobitmap); 4584*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4585*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4586*fcf3ce44SJohn Forte program, 4587*fcf3ce44SJohn Forte rdc_decode_flag(parms.command, 4588*fcf3ce44SJohn Forte parms.options), 4589*fcf3ce44SJohn Forte fromhost, 4590*fcf3ce44SJohn Forte fromfile, frombitmap, 4591*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4592*fcf3ce44SJohn Forte rdc_err(&ustatus, 0); 4593*fcf3ce44SJohn Forte } 4594*fcf3ce44SJohn Forte /* 4595*fcf3ce44SJohn Forte * ok, we should've reported any errs 4596*fcf3ce44SJohn Forte * exit explictly 4597*fcf3ce44SJohn Forte */ 4598*fcf3ce44SJohn Forte exit(1); 4599*fcf3ce44SJohn Forte 4600*fcf3ce44SJohn Forte } 4601*fcf3ce44SJohn Forte } 4602*fcf3ce44SJohn Forte } else if (flag == RDC_CMD_DISABLE) { 4603*fcf3ce44SJohn Forte /* 4604*fcf3ce44SJohn Forte * If we're no longer using a volume, SV-disable it 4605*fcf3ce44SJohn Forte */ 4606*fcf3ce44SJohn Forte volcount_t *vc; 4607*fcf3ce44SJohn Forte 4608*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, vol1); 4609*fcf3ce44SJohn Forte if (vc && (1 == vc->count)) { 4610*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, vol1, ctag, "sndr") 4611*fcf3ce44SJohn Forte < 0) 4612*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4613*fcf3ce44SJohn Forte "remove volume [%s] from " 4614*fcf3ce44SJohn Forte "configuration"), vol1); 4615*fcf3ce44SJohn Forte 4616*fcf3ce44SJohn Forte } else if (!vc) { 4617*fcf3ce44SJohn Forte rdc_warn(NULL, 4618*fcf3ce44SJohn Forte gettext("Unable to find %s in config"), 4619*fcf3ce44SJohn Forte vol1); 4620*fcf3ce44SJohn Forte } 4621*fcf3ce44SJohn Forte 4622*fcf3ce44SJohn Forte if (vol2) { 4623*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, vol2); 4624*fcf3ce44SJohn Forte if (vc && (1 == vc->count)) { 4625*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, vol2, ctag, 4626*fcf3ce44SJohn Forte "sndr") < 0) 4627*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4628*fcf3ce44SJohn Forte "remove volume [%s] from " 4629*fcf3ce44SJohn Forte "configuration"), vol2); 4630*fcf3ce44SJohn Forte } else if (!vc) { 4631*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to find" 4632*fcf3ce44SJohn Forte " %s in config"), vol2); 4633*fcf3ce44SJohn Forte } 4634*fcf3ce44SJohn Forte } 4635*fcf3ce44SJohn Forte 4636*fcf3ce44SJohn Forte if (diskqueue != NULL && strlen(diskqueue) > 0) { 4637*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, diskqueue); 4638*fcf3ce44SJohn Forte if (vc && (1 == vc->count)) { 4639*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, diskqueue, ctag, 4640*fcf3ce44SJohn Forte "sndr") < 0) 4641*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4642*fcf3ce44SJohn Forte "remove disk queue [%s] from " 4643*fcf3ce44SJohn Forte "configuration"), diskqueue); 4644*fcf3ce44SJohn Forte } else if (!vc) { 4645*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to find" 4646*fcf3ce44SJohn Forte " %s in config"), diskqueue); 4647*fcf3ce44SJohn Forte } 4648*fcf3ce44SJohn Forte } 4649*fcf3ce44SJohn Forte /* WARNING about to go to 4 space indenting */ 4650*fcf3ce44SJohn Forte } else if (flag == RDC_CMD_RECONFIG) { 4651*fcf3ce44SJohn Forte volcount_t *vc; 4652*fcf3ce44SJohn Forte /* disable ex-bitmaps, enable new bitmaps */ 4653*fcf3ce44SJohn Forte if (parms.options & RDC_OPT_PRIMARY) { 4654*fcf3ce44SJohn Forte if (strcmp(orig_fbmp, frombitmap) != 0) { 4655*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, orig_fbmp); 4656*fcf3ce44SJohn Forte if (vc && (vc->count == 1)) { 4657*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, orig_fbmp, ctag, 4658*fcf3ce44SJohn Forte "sndr") < 0) 4659*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4660*fcf3ce44SJohn Forte "remove bitmap [%s] from " 4661*fcf3ce44SJohn Forte "configuration"), orig_fbmp); 4662*fcf3ce44SJohn Forte } else if (!vc) { 4663*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to find " 4664*fcf3ce44SJohn Forte "%s in config"), orig_fbmp); 4665*fcf3ce44SJohn Forte } 4666*fcf3ce44SJohn Forte if (nsc_lookup(volhash, frombitmap) == NULL) { 4667*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, frombitmap, ctag, 4668*fcf3ce44SJohn Forte "sndr") < 0) { 4669*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4670*fcf3ce44SJohn Forte "reconfig sv enable failed for %s, " 4671*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4672*fcf3ce44SJohn Forte frombitmap, tohost, tofile); 4673*fcf3ce44SJohn Forte rdc_warn(NULL, 4674*fcf3ce44SJohn Forte "unable to sv enable %s\n" 4675*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4676*fcf3ce44SJohn Forte frombitmap, tohost, tofile); 4677*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 4678*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 4679*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 4680*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4681*fcf3ce44SJohn Forte (void) fprintf(stderr, 4682*fcf3ce44SJohn Forte gettext("Remote Mirror:" 4683*fcf3ce44SJohn Forte " %s %s %s %s %s %s\n"), 4684*fcf3ce44SJohn Forte fromhost, fromfile, 4685*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 4686*fcf3ce44SJohn Forte tobitmap); 4687*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4688*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4689*fcf3ce44SJohn Forte program, 4690*fcf3ce44SJohn Forte rdc_decode_flag(parms.command, 4691*fcf3ce44SJohn Forte parms.options), 4692*fcf3ce44SJohn Forte fromhost, 4693*fcf3ce44SJohn Forte fromfile, frombitmap, 4694*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4695*fcf3ce44SJohn Forte rdc_warn(&ustatus, 0); 4696*fcf3ce44SJohn Forte } 4697*fcf3ce44SJohn Forte exit(1); 4698*fcf3ce44SJohn Forte } 4699*fcf3ce44SJohn Forte } 4700*fcf3ce44SJohn Forte } else if ((orig_diskq[0] != '\0') && 4701*fcf3ce44SJohn Forte (strcmp(orig_diskq, diskqueue) != 0)) { 4702*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, orig_diskq); 4703*fcf3ce44SJohn Forte if (vc && (vc->count == 1)) { 4704*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, orig_diskq, ctag, 4705*fcf3ce44SJohn Forte "sndr") < 0) 4706*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4707*fcf3ce44SJohn Forte "remove disk queue [%s] from " 4708*fcf3ce44SJohn Forte "configuration"), orig_diskq); 4709*fcf3ce44SJohn Forte } else if (!vc) { 4710*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to find " 4711*fcf3ce44SJohn Forte "%s in config"), orig_diskq); 4712*fcf3ce44SJohn Forte } 4713*fcf3ce44SJohn Forte if (vol3 && 4714*fcf3ce44SJohn Forte (nsc_lookup(volhash, diskqueue) == NULL)) { 4715*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, diskqueue, ctag, 4716*fcf3ce44SJohn Forte "sndr") < 0) { 4717*fcf3ce44SJohn Forte spcs_log("sndr", NULL, "reconfig sv " 4718*fcf3ce44SJohn Forte "enable of diskqueue %s failed, " 4719*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4720*fcf3ce44SJohn Forte diskqueue, tohost, tofile); 4721*fcf3ce44SJohn Forte rdc_warn(NULL, "reconfig sv " 4722*fcf3ce44SJohn Forte "enable of diskqueue %s failed." 4723*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4724*fcf3ce44SJohn Forte diskqueue, tohost, tofile); 4725*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 4726*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 4727*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 4728*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4729*fcf3ce44SJohn Forte (void) fprintf(stderr, 4730*fcf3ce44SJohn Forte gettext("Remote Mirror:" 4731*fcf3ce44SJohn Forte " %s %s %s %s %s %s\n"), 4732*fcf3ce44SJohn Forte fromhost, fromfile, 4733*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 4734*fcf3ce44SJohn Forte tobitmap); 4735*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4736*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4737*fcf3ce44SJohn Forte program, 4738*fcf3ce44SJohn Forte rdc_decode_flag(parms.command, 4739*fcf3ce44SJohn Forte parms.options), 4740*fcf3ce44SJohn Forte fromhost, 4741*fcf3ce44SJohn Forte fromfile, frombitmap, 4742*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4743*fcf3ce44SJohn Forte rdc_warn(&ustatus, 0); 4744*fcf3ce44SJohn Forte } 4745*fcf3ce44SJohn Forte exit(1); 4746*fcf3ce44SJohn Forte } 4747*fcf3ce44SJohn Forte } 4748*fcf3ce44SJohn Forte } 4749*fcf3ce44SJohn Forte } else if (flag != RDC_OPT_PRIMARY) { 4750*fcf3ce44SJohn Forte if (strcmp(orig_tbmp, tobitmap) != 0) { 4751*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, orig_tbmp); 4752*fcf3ce44SJohn Forte if (vc && (vc->count == 1)) { 4753*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, orig_tbmp, ctag, 4754*fcf3ce44SJohn Forte "sndr") < 0) 4755*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Failed to " 4756*fcf3ce44SJohn Forte "remove bitmap [%s] from " 4757*fcf3ce44SJohn Forte "configuration"), orig_tbmp); 4758*fcf3ce44SJohn Forte } else if (!vc) { 4759*fcf3ce44SJohn Forte rdc_warn(NULL, 4760*fcf3ce44SJohn Forte gettext("Unable to find %s in config"), 4761*fcf3ce44SJohn Forte orig_tbmp); 4762*fcf3ce44SJohn Forte } 4763*fcf3ce44SJohn Forte if (nsc_lookup(volhash, tobitmap) == NULL) { 4764*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, tobitmap, ctag, 4765*fcf3ce44SJohn Forte "sndr") < 0) { 4766*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 4767*fcf3ce44SJohn Forte "reconfig sv enable failed for %s, " 4768*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4769*fcf3ce44SJohn Forte tobitmap, tohost, tofile); 4770*fcf3ce44SJohn Forte rdc_warn(NULL, 4771*fcf3ce44SJohn Forte "unable to sv enable %s\n" 4772*fcf3ce44SJohn Forte "disabling Remote Mirror set %s:%s", 4773*fcf3ce44SJohn Forte tobitmap, tohost, tofile); 4774*fcf3ce44SJohn Forte parms.command = RDC_CMD_DISABLE; 4775*fcf3ce44SJohn Forte ret = RDC_IOCTL(RDC_CONFIG, &parms, 4776*fcf3ce44SJohn Forte NULL, 0, 0, 0, ustatus); 4777*fcf3ce44SJohn Forte if (ret != SPCS_S_OK) { 4778*fcf3ce44SJohn Forte (void) fprintf(stderr, 4779*fcf3ce44SJohn Forte gettext("Remote Mirror:" 4780*fcf3ce44SJohn Forte " %s %s %s %s %s %s\n"), 4781*fcf3ce44SJohn Forte fromhost, fromfile, 4782*fcf3ce44SJohn Forte frombitmap, tohost, tofile, 4783*fcf3ce44SJohn Forte tobitmap); 4784*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 4785*fcf3ce44SJohn Forte "%s %s %s %s %s %s %s %s", 4786*fcf3ce44SJohn Forte program, 4787*fcf3ce44SJohn Forte rdc_decode_flag(parms.command, 4788*fcf3ce44SJohn Forte parms.options), 4789*fcf3ce44SJohn Forte fromhost, fromfile, frombitmap, 4790*fcf3ce44SJohn Forte tohost, tofile, tobitmap); 4791*fcf3ce44SJohn Forte rdc_warn(&ustatus, 0); 4792*fcf3ce44SJohn Forte } 4793*fcf3ce44SJohn Forte exit(1); 4794*fcf3ce44SJohn Forte } 4795*fcf3ce44SJohn Forte } 4796*fcf3ce44SJohn Forte } 4797*fcf3ce44SJohn Forte } 4798*fcf3ce44SJohn Forte /* END 4 space indenting */ 4799*fcf3ce44SJohn Forte } 4800*fcf3ce44SJohn Forte } 4801*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 4802*fcf3ce44SJohn Forte 4803*fcf3ce44SJohn Forte return (0); 4804*fcf3ce44SJohn Forte } 4805*fcf3ce44SJohn Forte 4806*fcf3ce44SJohn Forte 4807*fcf3ce44SJohn Forte /* 4808*fcf3ce44SJohn Forte * read_config() 4809*fcf3ce44SJohn Forte * 4810*fcf3ce44SJohn Forte * DESCRIPTION: Read the lines in a configuration file and return the 4811*fcf3ce44SJohn Forte * pairs of devices to be mirrored/enabled/disabled/updated. 4812*fcf3ce44SJohn Forte * The format for the configuration file is as follows: 4813*fcf3ce44SJohn Forte * 4814*fcf3ce44SJohn Forte * fromhost fromfile frombitmap tohost tofile tobitmap 4815*fcf3ce44SJohn Forte * 4816*fcf3ce44SJohn Forte * where fromfile is the primary device which is local to the 4817*fcf3ce44SJohn Forte * fromhost subsystem, tofile is the secondary device which is 4818*fcf3ce44SJohn Forte * local to the tohost subsystem, and type is 1 if the device 4819*fcf3ce44SJohn Forte * a simckd device or 0 otherwise. Any line preceeded by a '#' 4820*fcf3ce44SJohn Forte * is considered to be a comment. 4821*fcf3ce44SJohn Forte * 4822*fcf3ce44SJohn Forte * Inputs: 4823*fcf3ce44SJohn Forte * char *config_file Name of configuration file for rdcadm 4824*fcf3ce44SJohn Forte * 4825*fcf3ce44SJohn Forte * Outputs: 4826*fcf3ce44SJohn Forte * int i Number of pairs of devices 4827*fcf3ce44SJohn Forte * 4828*fcf3ce44SJohn Forte * Side Effects: The 0 to i-1 entries in the pair_list are filled. 4829*fcf3ce44SJohn Forte * 4830*fcf3ce44SJohn Forte */ 4831*fcf3ce44SJohn Forte 4832*fcf3ce44SJohn Forte int 4833*fcf3ce44SJohn Forte read_config(int flag, char *config_file, char *group_arg, char *ctag_arg) 4834*fcf3ce44SJohn Forte { 4835*fcf3ce44SJohn Forte int ret; 4836*fcf3ce44SJohn Forte char dsk_flagstr[NSC_MAXPATH]; 4837*fcf3ce44SJohn Forte char line[1024], tmp_line[1024]; 4838*fcf3ce44SJohn Forte char fromhost[MAX_RDC_HOST_SIZE]; 4839*fcf3ce44SJohn Forte char fromfile[NSC_MAXPATH]; 4840*fcf3ce44SJohn Forte char frombitmap[NSC_MAXPATH]; 4841*fcf3ce44SJohn Forte char tohost[MAX_RDC_HOST_SIZE]; 4842*fcf3ce44SJohn Forte char tofile[NSC_MAXPATH]; 4843*fcf3ce44SJohn Forte char tobitmap[NSC_MAXPATH]; 4844*fcf3ce44SJohn Forte char directfile[NSC_MAXPATH]; 4845*fcf3ce44SJohn Forte char sync[16]; 4846*fcf3ce44SJohn Forte int doasync; 4847*fcf3ce44SJohn Forte FILE *fp; 4848*fcf3ce44SJohn Forte int i, j; 4849*fcf3ce44SJohn Forte char *extra_args[EXTRA_ARGS]; 4850*fcf3ce44SJohn Forte char *tmp, *split_str = " \t\n"; 4851*fcf3ce44SJohn Forte 4852*fcf3ce44SJohn Forte for (j = 0; j < EXTRA_ARGS; j++) 4853*fcf3ce44SJohn Forte extra_args[j] = malloc(NSC_MAXPATH); 4854*fcf3ce44SJohn Forte 4855*fcf3ce44SJohn Forte if (!(fp = fopen(config_file, "r"))) { 4856*fcf3ce44SJohn Forte rdc_err(NULL, gettext("error opening %s"), config_file); 4857*fcf3ce44SJohn Forte } 4858*fcf3ce44SJohn Forte 4859*fcf3ce44SJohn Forte i = 0; 4860*fcf3ce44SJohn Forte while (fgets(line, sizeof (line), fp)) { 4861*fcf3ce44SJohn Forte if (line[0] == '#') /* this is a comment */ 4862*fcf3ce44SJohn Forte continue; 4863*fcf3ce44SJohn Forte 4864*fcf3ce44SJohn Forte ret = 0; 4865*fcf3ce44SJohn Forte strcpy(tmp_line, line); 4866*fcf3ce44SJohn Forte 4867*fcf3ce44SJohn Forte if ((tmp = strtok(tmp_line, split_str)) != NULL) { 4868*fcf3ce44SJohn Forte if (strlen(tmp) >= MAX_RDC_HOST_SIZE) { 4869*fcf3ce44SJohn Forte (void) printf(gettext("hostname is longer than %d " 4870*fcf3ce44SJohn Forte "characters\n"), (MAX_RDC_HOST_SIZE - 1)); 4871*fcf3ce44SJohn Forte continue; 4872*fcf3ce44SJohn Forte } 4873*fcf3ce44SJohn Forte strncpy(fromhost, tmp, (MAX_RDC_HOST_SIZE - 1)); 4874*fcf3ce44SJohn Forte fromhost[(MAX_RDC_HOST_SIZE - 1)] = '\0'; 4875*fcf3ce44SJohn Forte ret++; 4876*fcf3ce44SJohn Forte } 4877*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4878*fcf3ce44SJohn Forte if (strlen(tmp) >= NSC_MAXPATH) { 4879*fcf3ce44SJohn Forte (void) printf(gettext( 4880*fcf3ce44SJohn Forte "device name is longer than %d " 4881*fcf3ce44SJohn Forte "characters\n"), (NSC_MAXPATH - 1)); 4882*fcf3ce44SJohn Forte continue; 4883*fcf3ce44SJohn Forte } 4884*fcf3ce44SJohn Forte strncpy(fromfile, tmp, (NSC_MAXPATH - 1)); 4885*fcf3ce44SJohn Forte fromfile[(NSC_MAXPATH - 1)] = '\0'; 4886*fcf3ce44SJohn Forte ret++; 4887*fcf3ce44SJohn Forte } 4888*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4889*fcf3ce44SJohn Forte if (strlen(tmp) >= NSC_MAXPATH) { 4890*fcf3ce44SJohn Forte (void) printf(gettext( 4891*fcf3ce44SJohn Forte "device name is longer than %d " 4892*fcf3ce44SJohn Forte "characters\n"), (NSC_MAXPATH - 1)); 4893*fcf3ce44SJohn Forte continue; 4894*fcf3ce44SJohn Forte } 4895*fcf3ce44SJohn Forte strncpy(frombitmap, tmp, (NSC_MAXPATH - 1)); 4896*fcf3ce44SJohn Forte frombitmap[(NSC_MAXPATH - 1)] = '\0'; 4897*fcf3ce44SJohn Forte ret++; 4898*fcf3ce44SJohn Forte } 4899*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4900*fcf3ce44SJohn Forte if (strlen(tmp) >= MAX_RDC_HOST_SIZE) { 4901*fcf3ce44SJohn Forte (void) printf(gettext( 4902*fcf3ce44SJohn Forte "hostname is longer than %d " 4903*fcf3ce44SJohn Forte "characters\n"), (MAX_RDC_HOST_SIZE - 1)); 4904*fcf3ce44SJohn Forte continue; 4905*fcf3ce44SJohn Forte } 4906*fcf3ce44SJohn Forte strncpy(tohost, tmp, (MAX_RDC_HOST_SIZE - 1)); 4907*fcf3ce44SJohn Forte tohost[(MAX_RDC_HOST_SIZE - 1)] = '\0'; 4908*fcf3ce44SJohn Forte ret++; 4909*fcf3ce44SJohn Forte } 4910*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4911*fcf3ce44SJohn Forte if (strlen(tmp) >= NSC_MAXPATH) { 4912*fcf3ce44SJohn Forte (void) printf(gettext( 4913*fcf3ce44SJohn Forte "device name is longer than %d " 4914*fcf3ce44SJohn Forte "characters\n"), (NSC_MAXPATH - 1)); 4915*fcf3ce44SJohn Forte continue; 4916*fcf3ce44SJohn Forte } 4917*fcf3ce44SJohn Forte strncpy(tofile, tmp, (NSC_MAXPATH - 1)); 4918*fcf3ce44SJohn Forte tofile[(NSC_MAXPATH - 1)] = '\0'; 4919*fcf3ce44SJohn Forte ret++; 4920*fcf3ce44SJohn Forte } 4921*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4922*fcf3ce44SJohn Forte if (strlen(tmp) >= NSC_MAXPATH) { 4923*fcf3ce44SJohn Forte (void) printf(gettext( 4924*fcf3ce44SJohn Forte "device name is longer than %d " 4925*fcf3ce44SJohn Forte "characters\n"), (NSC_MAXPATH - 1)); 4926*fcf3ce44SJohn Forte continue; 4927*fcf3ce44SJohn Forte } 4928*fcf3ce44SJohn Forte strncpy(tobitmap, tmp, (NSC_MAXPATH - 1)); 4929*fcf3ce44SJohn Forte tobitmap[(NSC_MAXPATH - 1)] = '\0'; 4930*fcf3ce44SJohn Forte ret++; 4931*fcf3ce44SJohn Forte } 4932*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4933*fcf3ce44SJohn Forte strncpy(dsk_flagstr, tmp, 15); 4934*fcf3ce44SJohn Forte dsk_flagstr[15] = '\0'; 4935*fcf3ce44SJohn Forte ret++; 4936*fcf3ce44SJohn Forte } 4937*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4938*fcf3ce44SJohn Forte strncpy(sync, tmp, 15); 4939*fcf3ce44SJohn Forte sync[15] = '\0'; 4940*fcf3ce44SJohn Forte ret++; 4941*fcf3ce44SJohn Forte } 4942*fcf3ce44SJohn Forte for (j = 0; j < EXTRA_ARGS; j++) { 4943*fcf3ce44SJohn Forte if ((tmp = strtok(NULL, split_str)) != NULL) { 4944*fcf3ce44SJohn Forte strncpy(extra_args[j], tmp, (NSC_MAXPATH - 1)); 4945*fcf3ce44SJohn Forte extra_args[j][(NSC_MAXPATH - 1)] = '\0'; 4946*fcf3ce44SJohn Forte ret++; 4947*fcf3ce44SJohn Forte } 4948*fcf3ce44SJohn Forte } 4949*fcf3ce44SJohn Forte 4950*fcf3ce44SJohn Forte if (ret == 0) /* this is a blank line */ 4951*fcf3ce44SJohn Forte continue; 4952*fcf3ce44SJohn Forte 4953*fcf3ce44SJohn Forte if (ret < 8) { 4954*fcf3ce44SJohn Forte (void) fclose(fp); 4955*fcf3ce44SJohn Forte rdc_warn(NULL, 4956*fcf3ce44SJohn Forte gettext("invalid format in %s"), config_file); 4957*fcf3ce44SJohn Forte rdc_err(NULL, "%s", line); 4958*fcf3ce44SJohn Forte } 4959*fcf3ce44SJohn Forte 4960*fcf3ce44SJohn Forte if (i >= rdc_maxsets) { 4961*fcf3ce44SJohn Forte (void) fclose(fp); 4962*fcf3ce44SJohn Forte rdc_err(NULL, 4963*fcf3ce44SJohn Forte gettext("number of Remote Mirror sets exceeds %d"), 4964*fcf3ce44SJohn Forte rdc_maxsets); 4965*fcf3ce44SJohn Forte } 4966*fcf3ce44SJohn Forte 4967*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 4968*fcf3ce44SJohn Forte if (dsk_flagstr[0] == '/') { 4969*fcf3ce44SJohn Forte /* fcal directio */ 4970*fcf3ce44SJohn Forte strncpy(directfile, dsk_flagstr, NSC_MAXPATH); 4971*fcf3ce44SJohn Forte } else if (strcmp(dsk_flagstr, "ip") != 0) { 4972*fcf3ce44SJohn Forte #else 4973*fcf3ce44SJohn Forte if (strcmp(dsk_flagstr, "ip") != 0) { 4974*fcf3ce44SJohn Forte #endif 4975*fcf3ce44SJohn Forte (void) fclose(fp); 4976*fcf3ce44SJohn Forte rdc_err(NULL, 4977*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 4978*fcf3ce44SJohn Forte gettext("ip/fcal specification missing")); 4979*fcf3ce44SJohn Forte #else 4980*fcf3ce44SJohn Forte gettext("ip specification missing")); 4981*fcf3ce44SJohn Forte #endif 4982*fcf3ce44SJohn Forte } else 4983*fcf3ce44SJohn Forte strcpy(directfile, "ip"); 4984*fcf3ce44SJohn Forte 4985*fcf3ce44SJohn Forte if (strcmp(sync, "sync") == 0) 4986*fcf3ce44SJohn Forte doasync = 0; 4987*fcf3ce44SJohn Forte else if (strcmp(sync, "async") == 0) 4988*fcf3ce44SJohn Forte doasync = 1; 4989*fcf3ce44SJohn Forte else { 4990*fcf3ce44SJohn Forte (void) fclose(fp); 4991*fcf3ce44SJohn Forte rdc_err(NULL, 4992*fcf3ce44SJohn Forte gettext("sync/async specification missing")); 4993*fcf3ce44SJohn Forte } 4994*fcf3ce44SJohn Forte strncpy(pair_list[i].fhost, fromhost, MAX_RDC_HOST_SIZE); 4995*fcf3ce44SJohn Forte strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH); 4996*fcf3ce44SJohn Forte strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH); 4997*fcf3ce44SJohn Forte strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE); 4998*fcf3ce44SJohn Forte strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH); 4999*fcf3ce44SJohn Forte strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH); 5000*fcf3ce44SJohn Forte strncpy(pair_list[i].directfile, directfile, NSC_MAXPATH); 5001*fcf3ce44SJohn Forte pair_list[i].doasync = doasync; 5002*fcf3ce44SJohn Forte 5003*fcf3ce44SJohn Forte if (gethost_netaddrs(fromhost, tohost, 5004*fcf3ce44SJohn Forte (char *)pair_list[i].fnetaddr, 5005*fcf3ce44SJohn Forte (char *)pair_list[i].tnetaddr) < 0) { 5006*fcf3ce44SJohn Forte (void) fclose(fp); 5007*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to determine IP " 5008*fcf3ce44SJohn Forte "addresses for hosts %s, %s"), fromhost, tohost); 5009*fcf3ce44SJohn Forte } 5010*fcf3ce44SJohn Forte 5011*fcf3ce44SJohn Forte if (parse_extras(ret - 8, extra_args, i) < 0) { 5012*fcf3ce44SJohn Forte (void) fclose(fp); 5013*fcf3ce44SJohn Forte rdc_err(NULL, gettext("illegal option in:\n%s"), 5014*fcf3ce44SJohn Forte line); 5015*fcf3ce44SJohn Forte } 5016*fcf3ce44SJohn Forte 5017*fcf3ce44SJohn Forte if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) { 5018*fcf3ce44SJohn Forte if (ctag_check(fromhost, fromfile, frombitmap, 5019*fcf3ce44SJohn Forte tohost, tofile, tobitmap, pair_list[i].ctag, 5020*fcf3ce44SJohn Forte pair_list[i].diskqueue) < 0) 5021*fcf3ce44SJohn Forte continue; /* Ignore illegal sets */ 5022*fcf3ce44SJohn Forte if (pair_diskqueue_check(i)) 5023*fcf3ce44SJohn Forte continue; /* ignore sets with incorrect diskq */ 5024*fcf3ce44SJohn Forte } 5025*fcf3ce44SJohn Forte 5026*fcf3ce44SJohn Forte /* Filter according to ctag and group arguments */ 5027*fcf3ce44SJohn Forte if (strcmp(ctag_arg, "") && 5028*fcf3ce44SJohn Forte strncmp(ctag_arg, pair_list[i].ctag, 5029*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE)) 5030*fcf3ce44SJohn Forte continue; 5031*fcf3ce44SJohn Forte if (strcmp(group_arg, "") && 5032*fcf3ce44SJohn Forte strncmp(group_arg, pair_list[i].group, NSC_MAXPATH)) 5033*fcf3ce44SJohn Forte continue; 5034*fcf3ce44SJohn Forte 5035*fcf3ce44SJohn Forte i++; 5036*fcf3ce44SJohn Forte } 5037*fcf3ce44SJohn Forte (void) fclose(fp); 5038*fcf3ce44SJohn Forte for (j = 0; j < EXTRA_ARGS; j++) 5039*fcf3ce44SJohn Forte free(extra_args[j]); 5040*fcf3ce44SJohn Forte return (i); 5041*fcf3ce44SJohn Forte } 5042*fcf3ce44SJohn Forte 5043*fcf3ce44SJohn Forte 5044*fcf3ce44SJohn Forte /* 5045*fcf3ce44SJohn Forte * read_libcfg() 5046*fcf3ce44SJohn Forte * 5047*fcf3ce44SJohn Forte * DESCRIPTION: Read the relevant config info via libcfg 5048*fcf3ce44SJohn Forte * 5049*fcf3ce44SJohn Forte * Outputs: 5050*fcf3ce44SJohn Forte * int i Number of pairs of devices 5051*fcf3ce44SJohn Forte * 5052*fcf3ce44SJohn Forte * Side Effects: The 0 to i-1 entries in the pair_list are filled. 5053*fcf3ce44SJohn Forte * 5054*fcf3ce44SJohn Forte */ 5055*fcf3ce44SJohn Forte static int 5056*fcf3ce44SJohn Forte read_libcfg(int flag, char *group_arg, char *ctag_arg) 5057*fcf3ce44SJohn Forte { 5058*fcf3ce44SJohn Forte int rc; 5059*fcf3ce44SJohn Forte CFGFILE *cfg; 5060*fcf3ce44SJohn Forte int i; 5061*fcf3ce44SJohn Forte _sd_dual_pair_t *pairp; 5062*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 5063*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 5064*fcf3ce44SJohn Forte int setnumber; 5065*fcf3ce44SJohn Forte 5066*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) 5067*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to access configuration")); 5068*fcf3ce44SJohn Forte 5069*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) 5070*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to lock configuration")); 5071*fcf3ce44SJohn Forte 5072*fcf3ce44SJohn Forte if (strcmp(ctag_arg, "")) 5073*fcf3ce44SJohn Forte cfg_resource(cfg, ctag_arg); 5074*fcf3ce44SJohn Forte else { 5075*fcf3ce44SJohn Forte cfg_resource(cfg, NULL); 5076*fcf3ce44SJohn Forte } 5077*fcf3ce44SJohn Forte 5078*fcf3ce44SJohn Forte setnumber = 0; 5079*fcf3ce44SJohn Forte /*CSTYLED*/ 5080*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets;) { 5081*fcf3ce44SJohn Forte setnumber++; 5082*fcf3ce44SJohn Forte 5083*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 5084*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); 5085*fcf3ce44SJohn Forte rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF); 5086*fcf3ce44SJohn Forte if (rc < 0) 5087*fcf3ce44SJohn Forte break; 5088*fcf3ce44SJohn Forte 5089*fcf3ce44SJohn Forte pairp = &pair_list[i]; 5090*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, pairp, NULL)) 5091*fcf3ce44SJohn Forte continue; 5092*fcf3ce44SJohn Forte 5093*fcf3ce44SJohn Forte if (strcmp(group_arg, "") && 5094*fcf3ce44SJohn Forte strncmp(group_arg, pairp->group, NSC_MAXPATH)) 5095*fcf3ce44SJohn Forte continue; 5096*fcf3ce44SJohn Forte 5097*fcf3ce44SJohn Forte if (flag == RDC_CMD_RECONFIG) { 5098*fcf3ce44SJohn Forte if (reconfig_pbitmap) 5099*fcf3ce44SJohn Forte strncpy(pairp->fbitmap, reconfig_pbitmap, 5100*fcf3ce44SJohn Forte NSC_MAXPATH); 5101*fcf3ce44SJohn Forte if (reconfig_sbitmap) 5102*fcf3ce44SJohn Forte strncpy(pairp->tbitmap, reconfig_sbitmap, 5103*fcf3ce44SJohn Forte NSC_MAXPATH); 5104*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 5105*fcf3ce44SJohn Forte if (reconfig_direct) 5106*fcf3ce44SJohn Forte strncpy(directfile, reconfig_direct, 5107*fcf3ce44SJohn Forte NSC_MAXPATH); 5108*fcf3ce44SJohn Forte #endif 5109*fcf3ce44SJohn Forte if (reconfig_group) 5110*fcf3ce44SJohn Forte strncpy(pairp->group, reconfig_group, 5111*fcf3ce44SJohn Forte NSC_MAXPATH); 5112*fcf3ce44SJohn Forte 5113*fcf3ce44SJohn Forte if (strlen(reconfig_ctag) > 0) 5114*fcf3ce44SJohn Forte strncpy(pairp->ctag, reconfig_ctag, 5115*fcf3ce44SJohn Forte MAX_RDC_HOST_SIZE); 5116*fcf3ce44SJohn Forte 5117*fcf3ce44SJohn Forte if (reconfig_doasync != -1) 5118*fcf3ce44SJohn Forte pairp->doasync = reconfig_doasync; 5119*fcf3ce44SJohn Forte } 5120*fcf3ce44SJohn Forte 5121*fcf3ce44SJohn Forte 5122*fcf3ce44SJohn Forte if (ctag_check(pairp->fhost, pairp->ffile, 5123*fcf3ce44SJohn Forte pairp->fbitmap, pairp->thost, pairp->tfile, 5124*fcf3ce44SJohn Forte pairp->tbitmap, pairp->ctag, pairp->diskqueue) < 0) 5125*fcf3ce44SJohn Forte continue; /* Ignore illegal sets */ 5126*fcf3ce44SJohn Forte 5127*fcf3ce44SJohn Forte if (gethost_netaddrs(pairp->fhost, pairp->thost, 5128*fcf3ce44SJohn Forte (char *)pairp->fnetaddr, 5129*fcf3ce44SJohn Forte (char *)pairp->tnetaddr) < 0) { 5130*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to determine IP " 5131*fcf3ce44SJohn Forte "addresses for hosts %s, %s"), pairp->fhost, 5132*fcf3ce44SJohn Forte pairp->thost); 5133*fcf3ce44SJohn Forte } 5134*fcf3ce44SJohn Forte 5135*fcf3ce44SJohn Forte i++; 5136*fcf3ce44SJohn Forte } 5137*fcf3ce44SJohn Forte 5138*fcf3ce44SJohn Forte cfg_close(cfg); 5139*fcf3ce44SJohn Forte return (i); 5140*fcf3ce44SJohn Forte } 5141*fcf3ce44SJohn Forte 5142*fcf3ce44SJohn Forte void 5143*fcf3ce44SJohn Forte q_usage(int prhdr) 5144*fcf3ce44SJohn Forte { 5145*fcf3ce44SJohn Forte if (prhdr) 5146*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext("disk queue usage:\n")); 5147*fcf3ce44SJohn Forte 5148*fcf3ce44SJohn Forte (void) fprintf(stderr, 5149*fcf3ce44SJohn Forte gettext("\t%s -g <group> -q a <vol>\t\tadd disk queue to " 5150*fcf3ce44SJohn Forte "group\n"), program); 5151*fcf3ce44SJohn Forte (void) fprintf(stderr, 5152*fcf3ce44SJohn Forte gettext("\t%s -g <group> -q d \t\tremove disk queue from" 5153*fcf3ce44SJohn Forte " group\n"), program); 5154*fcf3ce44SJohn Forte (void) fprintf(stderr, 5155*fcf3ce44SJohn Forte gettext("\t%s -g <group> -q r <newvol>\treplace disk queue for a" 5156*fcf3ce44SJohn Forte " group\n"), program); 5157*fcf3ce44SJohn Forte 5158*fcf3ce44SJohn Forte (void) fprintf(stderr, 5159*fcf3ce44SJohn Forte gettext("\t%s -q a <vol> <shost>:<sdev>\tadd disk queue to " 5160*fcf3ce44SJohn Forte "a set\n"), program); 5161*fcf3ce44SJohn Forte (void) fprintf(stderr, 5162*fcf3ce44SJohn Forte gettext("\t%s -q d <shost>:<sdev>\t\tremove disk queue from " 5163*fcf3ce44SJohn Forte "a set\n"), program); 5164*fcf3ce44SJohn Forte (void) fprintf(stderr, 5165*fcf3ce44SJohn Forte gettext("\t%s -q r <newvol> <shost>:<sdev>\treplace disk queue for " 5166*fcf3ce44SJohn Forte "a set\n"), program); 5167*fcf3ce44SJohn Forte 5168*fcf3ce44SJohn Forte } 5169*fcf3ce44SJohn Forte 5170*fcf3ce44SJohn Forte static void 5171*fcf3ce44SJohn Forte usage() 5172*fcf3ce44SJohn Forte { 5173*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext("usage:\n")); 5174*fcf3ce44SJohn Forte 5175*fcf3ce44SJohn Forte (void) fprintf(stderr, 5176*fcf3ce44SJohn Forte gettext("\t%s [opts] -a {on | off} [set]\t" 5177*fcf3ce44SJohn Forte "set autosync\n"), program); 5178*fcf3ce44SJohn Forte 5179*fcf3ce44SJohn Forte (void) fprintf(stderr, 5180*fcf3ce44SJohn Forte gettext("\t%s [opts] -A <asyncthr> [set]\t" 5181*fcf3ce44SJohn Forte "set the number of asynchronous\n\t\t\t\t\t\tthreads\n"), 5182*fcf3ce44SJohn Forte program); 5183*fcf3ce44SJohn Forte 5184*fcf3ce44SJohn Forte (void) fprintf(stderr, 5185*fcf3ce44SJohn Forte gettext("\t%s [opts] -d [set]\t\t\t" 5186*fcf3ce44SJohn Forte "disable\n"), program); 5187*fcf3ce44SJohn Forte 5188*fcf3ce44SJohn Forte (void) fprintf(stderr, 5189*fcf3ce44SJohn Forte gettext("\t%s [opts] -e [set]\t\t\t" 5190*fcf3ce44SJohn Forte "enable with bits in bitmap set\n"), program); 5191*fcf3ce44SJohn Forte 5192*fcf3ce44SJohn Forte (void) fprintf(stderr, 5193*fcf3ce44SJohn Forte gettext("\t%s [opts] -E [set]\t\t\t" 5194*fcf3ce44SJohn Forte "enable with bits in bitmap clear\n"), program); 5195*fcf3ce44SJohn Forte 5196*fcf3ce44SJohn Forte (void) fprintf(stderr, 5197*fcf3ce44SJohn Forte gettext("\t%s [opts] -F <maxqfbas> [set]\t" 5198*fcf3ce44SJohn Forte "set maximum fbas to queue\n"), program); 5199*fcf3ce44SJohn Forte 5200*fcf3ce44SJohn Forte (void) fprintf(stderr, 5201*fcf3ce44SJohn Forte gettext("\t%s [opts] -D {block | noblock} [set]\t" 5202*fcf3ce44SJohn Forte "set disk queue blocking mode\n"), program); 5203*fcf3ce44SJohn Forte 5204*fcf3ce44SJohn Forte (void) fprintf(stderr, 5205*fcf3ce44SJohn Forte gettext("\t%s [opts] -H [set]\t\t\t" 5206*fcf3ce44SJohn Forte "report link health\n"), program); 5207*fcf3ce44SJohn Forte 5208*fcf3ce44SJohn Forte (void) fprintf(stderr, 5209*fcf3ce44SJohn Forte gettext("\t%s -h\t\t\t\tusage message\n"), program); 5210*fcf3ce44SJohn Forte 5211*fcf3ce44SJohn Forte (void) fprintf(stderr, 5212*fcf3ce44SJohn Forte gettext("\t%s -I a <master> <shadow> <bitmap>\t" 5213*fcf3ce44SJohn Forte "add ndr_ii config entry\n"), program); 5214*fcf3ce44SJohn Forte 5215*fcf3ce44SJohn Forte (void) fprintf(stderr, 5216*fcf3ce44SJohn Forte gettext("\t%s -I d <master> <shadow> <bitmap>\t" 5217*fcf3ce44SJohn Forte "delete ndr_ii config entry\n"), program); 5218*fcf3ce44SJohn Forte 5219*fcf3ce44SJohn Forte (void) fprintf(stderr, 5220*fcf3ce44SJohn Forte gettext("\t%s [opts] -i [set]\t\t\t" 5221*fcf3ce44SJohn Forte "print sets in config file format\n"), program); 5222*fcf3ce44SJohn Forte 5223*fcf3ce44SJohn Forte (void) fprintf(stderr, 5224*fcf3ce44SJohn Forte gettext("\t%s [opts] -l [set]\t\t\t" 5225*fcf3ce44SJohn Forte "enter logging mode\n"), program); 5226*fcf3ce44SJohn Forte 5227*fcf3ce44SJohn Forte (void) fprintf(stderr, 5228*fcf3ce44SJohn Forte gettext("\t%s [opts] -m [set]\t\t\t" 5229*fcf3ce44SJohn Forte "full sync\n"), program); 5230*fcf3ce44SJohn Forte 5231*fcf3ce44SJohn Forte (void) fprintf(stderr, 5232*fcf3ce44SJohn Forte gettext("\t%s [opts] -m -r [set]\t\t" 5233*fcf3ce44SJohn Forte "full reverse sync\n"), program); 5234*fcf3ce44SJohn Forte 5235*fcf3ce44SJohn Forte (void) fprintf(stderr, 5236*fcf3ce44SJohn Forte gettext("\t%s [opts] -P [set]\t\t\t" 5237*fcf3ce44SJohn Forte "print sets verbose\n"), program); 5238*fcf3ce44SJohn Forte 5239*fcf3ce44SJohn Forte (void) fprintf(stderr, 5240*fcf3ce44SJohn Forte gettext("\t%s [opts] -p [set]\t\t\t" 5241*fcf3ce44SJohn Forte "print sets\n"), program); 5242*fcf3ce44SJohn Forte 5243*fcf3ce44SJohn Forte (void) fprintf(stderr, 5244*fcf3ce44SJohn Forte gettext("\t%s [opts] -R\t\t\t" 5245*fcf3ce44SJohn Forte "reset error conditions\n"), program); 5246*fcf3ce44SJohn Forte 5247*fcf3ce44SJohn Forte (void) fprintf(stderr, 5248*fcf3ce44SJohn Forte gettext("\t%s [opts] -R b p <bitmap> [set]\t" 5249*fcf3ce44SJohn Forte "reconfig primary bitmap\n"), program); 5250*fcf3ce44SJohn Forte 5251*fcf3ce44SJohn Forte (void) fprintf(stderr, 5252*fcf3ce44SJohn Forte gettext("\t%s [opts] -R b s <bitmap> [set]\t" 5253*fcf3ce44SJohn Forte "reconfig secondary bitmap\n"), program); 5254*fcf3ce44SJohn Forte 5255*fcf3ce44SJohn Forte if (clustered) 5256*fcf3ce44SJohn Forte (void) fprintf(stderr, 5257*fcf3ce44SJohn Forte gettext("\t%s [opts] -R C <ctag> [set]\t" 5258*fcf3ce44SJohn Forte "reconfig cluster tag\n"), program); 5259*fcf3ce44SJohn Forte 5260*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 5261*fcf3ce44SJohn Forte (void) fprintf(stderr, 5262*fcf3ce44SJohn Forte gettext("\t%s [opts] -R d <pathname> [set]\t" 5263*fcf3ce44SJohn Forte "reconfig campus direct file\n"), program); 5264*fcf3ce44SJohn Forte #endif 5265*fcf3ce44SJohn Forte 5266*fcf3ce44SJohn Forte (void) fprintf(stderr, 5267*fcf3ce44SJohn Forte gettext("\t%s [opts] -R -f <volset-file> \t" 5268*fcf3ce44SJohn Forte "reconfig from file\n"), program); 5269*fcf3ce44SJohn Forte 5270*fcf3ce44SJohn Forte (void) fprintf(stderr, 5271*fcf3ce44SJohn Forte gettext("\t%s [opts] -R g <group> [set]\t" 5272*fcf3ce44SJohn Forte "reconfig group\n"), program); 5273*fcf3ce44SJohn Forte 5274*fcf3ce44SJohn Forte (void) fprintf(stderr, 5275*fcf3ce44SJohn Forte gettext("\t%s [opts] -R m {sync|async} [set]\t" 5276*fcf3ce44SJohn Forte "reconfig mode\n"), program); 5277*fcf3ce44SJohn Forte 5278*fcf3ce44SJohn Forte if (allow_role) 5279*fcf3ce44SJohn Forte (void) fprintf(stderr, 5280*fcf3ce44SJohn Forte gettext("\t%s [opts] -R r [set]\t\t" 5281*fcf3ce44SJohn Forte "reverse roles\n"), program); 5282*fcf3ce44SJohn Forte 5283*fcf3ce44SJohn Forte (void) fprintf(stderr, 5284*fcf3ce44SJohn Forte gettext("\t%s [opts] -u [set]\t\t\t" 5285*fcf3ce44SJohn Forte "update sync\n"), program); 5286*fcf3ce44SJohn Forte 5287*fcf3ce44SJohn Forte (void) fprintf(stderr, 5288*fcf3ce44SJohn Forte gettext("\t%s [opts] -u -r [set]\t\t" 5289*fcf3ce44SJohn Forte "update reverse sync\n"), program); 5290*fcf3ce44SJohn Forte 5291*fcf3ce44SJohn Forte (void) fprintf(stderr, 5292*fcf3ce44SJohn Forte gettext("\t%s -v\t\t\t\tdisplay version\n"), program); 5293*fcf3ce44SJohn Forte 5294*fcf3ce44SJohn Forte (void) fprintf(stderr, 5295*fcf3ce44SJohn Forte gettext("\t%s [opts] -W <maxwrites> [set]\t" 5296*fcf3ce44SJohn Forte "set maximum writes to queue\n"), program); 5297*fcf3ce44SJohn Forte 5298*fcf3ce44SJohn Forte (void) fprintf(stderr, 5299*fcf3ce44SJohn Forte gettext("\t%s [opts] -w [set]\t\t\t" 5300*fcf3ce44SJohn Forte "wait\n"), program); 5301*fcf3ce44SJohn Forte q_usage(0); 5302*fcf3ce44SJohn Forte 5303*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext("\nopts:\n")); 5304*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext("\t-n\t\tnon-interactive mode " 5305*fcf3ce44SJohn Forte "(not valid for print operations)\n")); 5306*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 5307*fcf3ce44SJohn Forte "\t-g <group>\toperate on sets in group only " 5308*fcf3ce44SJohn Forte "(not valid for enable\n\t\t\toperations)\n")); 5309*fcf3ce44SJohn Forte if (clustered) 5310*fcf3ce44SJohn Forte (void) fprintf(stderr, 5311*fcf3ce44SJohn Forte gettext("\t-C <ctag>\tignore sets not in cluster ctag " 5312*fcf3ce44SJohn Forte "(not valid for enable\n\t\t\toperations)\n")); 5313*fcf3ce44SJohn Forte 5314*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext("\nset:\n")); 5315*fcf3ce44SJohn Forte if (clustered) 5316*fcf3ce44SJohn Forte (void) fprintf(stderr, 5317*fcf3ce44SJohn Forte gettext("\t<phost> <pdev> <pbmp> " 5318*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 5319*fcf3ce44SJohn Forte "<shost> <sdev> <sbmp> {ip | <directfile>} " 5320*fcf3ce44SJohn Forte #else 5321*fcf3ce44SJohn Forte "<shost> <sdev> <sbmp> ip " 5322*fcf3ce44SJohn Forte #endif 5323*fcf3ce44SJohn Forte "\\\n\t\t{sync | async} [g <group>] [q <qdev>] " 5324*fcf3ce44SJohn Forte "[C <ctag>]\n")); 5325*fcf3ce44SJohn Forte else 5326*fcf3ce44SJohn Forte (void) fprintf(stderr, 5327*fcf3ce44SJohn Forte gettext("\t<phost> <pdev> <pbmp> " 5328*fcf3ce44SJohn Forte #ifdef _RDC_CAMPUS 5329*fcf3ce44SJohn Forte "<shost> <sdev> <sbmp> {ip | <directfile>} " 5330*fcf3ce44SJohn Forte #else 5331*fcf3ce44SJohn Forte "<shost> <sdev> <sbmp> ip " 5332*fcf3ce44SJohn Forte #endif 5333*fcf3ce44SJohn Forte "\\\n\t\t{sync | async} [g <group>] [q <qdev>]\n")); 5334*fcf3ce44SJohn Forte (void) fprintf(stderr, 5335*fcf3ce44SJohn Forte gettext("\t<shost>:<sdev>\t\t" 5336*fcf3ce44SJohn Forte "operate on set matching shost and sdev\n")); 5337*fcf3ce44SJohn Forte (void) fprintf(stderr, 5338*fcf3ce44SJohn Forte gettext("\t-f volset-file\t\t" 5339*fcf3ce44SJohn Forte "operate on all sets specified in config file\n" 5340*fcf3ce44SJohn Forte "\t\t\t\tnote: not valid for single set operations. See\n" 5341*fcf3ce44SJohn Forte "\t\t\t\t%s(1RDC).\n"), program); 5342*fcf3ce44SJohn Forte (void) fprintf(stderr, 5343*fcf3ce44SJohn Forte gettext("\t<no arg>\t\toperate on all configured sets\n")); 5344*fcf3ce44SJohn Forte } 5345*fcf3ce44SJohn Forte 5346*fcf3ce44SJohn Forte int 5347*fcf3ce44SJohn Forte prompt_user(int flag, int options) 5348*fcf3ce44SJohn Forte { 5349*fcf3ce44SJohn Forte int c; 5350*fcf3ce44SJohn Forte 5351*fcf3ce44SJohn Forte switch (flag) { 5352*fcf3ce44SJohn Forte case RDC_CMD_DISABLE: 5353*fcf3ce44SJohn Forte (void) printf(gettext("Disable Remote Mirror? (Y/N) [N]: ")); 5354*fcf3ce44SJohn Forte break; 5355*fcf3ce44SJohn Forte case RDC_CMD_ENABLE: 5356*fcf3ce44SJohn Forte (void) printf(gettext("Enable Remote Mirror? (Y/N) [N]: ")); 5357*fcf3ce44SJohn Forte break; 5358*fcf3ce44SJohn Forte case RDC_CMD_HEALTH: 5359*fcf3ce44SJohn Forte (void) printf(gettext("Report Remote Mirror link health? (Y/N)" 5360*fcf3ce44SJohn Forte "[N]: ")); 5361*fcf3ce44SJohn Forte break; 5362*fcf3ce44SJohn Forte case RDC_CMD_COPY: 5363*fcf3ce44SJohn Forte if (options & RDC_OPT_FULL) { 5364*fcf3ce44SJohn Forte if (options & RDC_OPT_REVERSE) 5365*fcf3ce44SJohn Forte (void) printf(gettext("Overwrite primary with" 5366*fcf3ce44SJohn Forte " secondary? (Y/N) [N]: ")); 5367*fcf3ce44SJohn Forte else 5368*fcf3ce44SJohn Forte (void) printf(gettext("Overwrite secondary with" 5369*fcf3ce44SJohn Forte " primary? (Y/N) [N]: ")); 5370*fcf3ce44SJohn Forte } else { 5371*fcf3ce44SJohn Forte if (options & RDC_OPT_REVERSE) 5372*fcf3ce44SJohn Forte (void) printf(gettext("Refresh primary with" 5373*fcf3ce44SJohn Forte " secondary? (Y/N) [N]: ")); 5374*fcf3ce44SJohn Forte else 5375*fcf3ce44SJohn Forte (void) printf(gettext("Refresh secondary with" 5376*fcf3ce44SJohn Forte " primary? (Y/N) [N]: ")); 5377*fcf3ce44SJohn Forte } 5378*fcf3ce44SJohn Forte break; 5379*fcf3ce44SJohn Forte case RDC_CMD_RECONFIG: 5380*fcf3ce44SJohn Forte (void) printf(gettext( 5381*fcf3ce44SJohn Forte "Perform Remote Mirror reconfiguration? (Y/N) [N]: ")); 5382*fcf3ce44SJohn Forte break; 5383*fcf3ce44SJohn Forte case RDC_CMD_RESET: 5384*fcf3ce44SJohn Forte (void) printf(gettext("Perform Remote Mirror reset? (Y/N) " 5385*fcf3ce44SJohn Forte "[N]: ")); 5386*fcf3ce44SJohn Forte break; 5387*fcf3ce44SJohn Forte case RDC_CMD_TUNABLE: 5388*fcf3ce44SJohn Forte (void) printf(gettext("Change Remote Mirror tunable? (Y/N) " 5389*fcf3ce44SJohn Forte "[N]: ")); 5390*fcf3ce44SJohn Forte break; 5391*fcf3ce44SJohn Forte case RDC_CMD_LOG: 5392*fcf3ce44SJohn Forte (void) printf(gettext( 5393*fcf3ce44SJohn Forte "Put Remote Mirror into logging mode? (Y/N) [N]: ")); 5394*fcf3ce44SJohn Forte break; 5395*fcf3ce44SJohn Forte case RDC_CMD_WAIT: 5396*fcf3ce44SJohn Forte (void) printf(gettext( 5397*fcf3ce44SJohn Forte "Wait for Remote Mirror sync completion? (Y/N) [N]: ")); 5398*fcf3ce44SJohn Forte break; 5399*fcf3ce44SJohn Forte default: 5400*fcf3ce44SJohn Forte (void) printf(gettext("Perform Remote Mirror operation? (Y/N) " 5401*fcf3ce44SJohn Forte "[N]: ")); 5402*fcf3ce44SJohn Forte } 5403*fcf3ce44SJohn Forte 5404*fcf3ce44SJohn Forte c = getchar(); 5405*fcf3ce44SJohn Forte if ((c != 'y') && (c != 'Y')) { 5406*fcf3ce44SJohn Forte (void) printf("\n"); 5407*fcf3ce44SJohn Forte return (-1); 5408*fcf3ce44SJohn Forte } 5409*fcf3ce44SJohn Forte return (0); 5410*fcf3ce44SJohn Forte } 5411*fcf3ce44SJohn Forte 5412*fcf3ce44SJohn Forte static void 5413*fcf3ce44SJohn Forte load_rdc_vols(CFGFILE *cfg) 5414*fcf3ce44SJohn Forte { 5415*fcf3ce44SJohn Forte int set; 5416*fcf3ce44SJohn Forte char key[ CFG_MAX_KEY ]; 5417*fcf3ce44SJohn Forte char buf[ CFG_MAX_BUF ]; 5418*fcf3ce44SJohn Forte _sd_dual_pair_t pair; 5419*fcf3ce44SJohn Forte char *vol, *bmp; 5420*fcf3ce44SJohn Forte char *host1 = pair.fhost, *host2 = pair.thost; 5421*fcf3ce44SJohn Forte char *diskqueue = pair.diskqueue; 5422*fcf3ce44SJohn Forte volcount_t *volcount; 5423*fcf3ce44SJohn Forte char lghn[ MAX_RDC_HOST_SIZE ]; 5424*fcf3ce44SJohn Forte 5425*fcf3ce44SJohn Forte if (volhash) { 5426*fcf3ce44SJohn Forte return; 5427*fcf3ce44SJohn Forte } 5428*fcf3ce44SJohn Forte 5429*fcf3ce44SJohn Forte cfg_rewind(cfg, CFG_SEC_CONF); 5430*fcf3ce44SJohn Forte volhash = nsc_create_hash(); 5431*fcf3ce44SJohn Forte for (set = 1; /*CSTYLED*/; set++) { 5432*fcf3ce44SJohn Forte (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d", set); 5433*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) { 5434*fcf3ce44SJohn Forte break; 5435*fcf3ce44SJohn Forte } 5436*fcf3ce44SJohn Forte 5437*fcf3ce44SJohn Forte if (parse_cfg_buf(buf, &pair, lghn)) 5438*fcf3ce44SJohn Forte continue; 5439*fcf3ce44SJohn Forte vol = pair.ffile; 5440*fcf3ce44SJohn Forte bmp = pair.fbitmap; 5441*fcf3ce44SJohn Forte 5442*fcf3ce44SJohn Forte /* use lghn if possible */ 5443*fcf3ce44SJohn Forte if (*lghn) { 5444*fcf3ce44SJohn Forte if (strcmp(host2, lghn) == 0) { 5445*fcf3ce44SJohn Forte vol = pair.tfile; 5446*fcf3ce44SJohn Forte bmp = pair.tbitmap; 5447*fcf3ce44SJohn Forte } 5448*fcf3ce44SJohn Forte } else if (!self_check(host1)) { 5449*fcf3ce44SJohn Forte /* next one had better be ours */ 5450*fcf3ce44SJohn Forte vol = pair.tfile; 5451*fcf3ce44SJohn Forte bmp = pair.tbitmap; 5452*fcf3ce44SJohn Forte 5453*fcf3ce44SJohn Forte if (!self_check(host2)) { 5454*fcf3ce44SJohn Forte rdc_warn(NULL, 5455*fcf3ce44SJohn Forte gettext("config error: neither %s nor %s" 5456*fcf3ce44SJohn Forte " is localhost"), host1, host2); 5457*fcf3ce44SJohn Forte continue; 5458*fcf3ce44SJohn Forte } 5459*fcf3ce44SJohn Forte } 5460*fcf3ce44SJohn Forte 5461*fcf3ce44SJohn Forte /* primary vol may be used more than once */ 5462*fcf3ce44SJohn Forte volcount = (volcount_t *)nsc_lookup(volhash, vol); 5463*fcf3ce44SJohn Forte if (volcount) { 5464*fcf3ce44SJohn Forte volcount->count++; 5465*fcf3ce44SJohn Forte } else { 5466*fcf3ce44SJohn Forte volcount = (volcount_t *)malloc(sizeof (volcount_t)); 5467*fcf3ce44SJohn Forte volcount->count = 1; 5468*fcf3ce44SJohn Forte (void) nsc_insert_node(volhash, volcount, vol); 5469*fcf3ce44SJohn Forte } 5470*fcf3ce44SJohn Forte 5471*fcf3ce44SJohn Forte /* bitmap ought to be only used once */ 5472*fcf3ce44SJohn Forte volcount = (volcount_t *)nsc_lookup(volhash, bmp); 5473*fcf3ce44SJohn Forte if (volcount) { 5474*fcf3ce44SJohn Forte /* argh */ 5475*fcf3ce44SJohn Forte volcount->count++; 5476*fcf3ce44SJohn Forte } else { 5477*fcf3ce44SJohn Forte volcount = (volcount_t *)malloc(sizeof (volcount_t)); 5478*fcf3ce44SJohn Forte volcount->count = 1; 5479*fcf3ce44SJohn Forte (void) nsc_insert_node(volhash, volcount, bmp); 5480*fcf3ce44SJohn Forte } 5481*fcf3ce44SJohn Forte 5482*fcf3ce44SJohn Forte if (strcmp(diskqueue, place_holder) == 0) 5483*fcf3ce44SJohn Forte continue; 5484*fcf3ce44SJohn Forte /* diskqueue vol may be used more than once */ 5485*fcf3ce44SJohn Forte volcount = (volcount_t *)nsc_lookup(volhash, diskqueue); 5486*fcf3ce44SJohn Forte if (volcount) { 5487*fcf3ce44SJohn Forte volcount->count++; 5488*fcf3ce44SJohn Forte } else { 5489*fcf3ce44SJohn Forte volcount = (volcount_t *)malloc(sizeof (volcount_t)); 5490*fcf3ce44SJohn Forte volcount->count = 1; 5491*fcf3ce44SJohn Forte (void) nsc_insert_node(volhash, volcount, diskqueue); 5492*fcf3ce44SJohn Forte } 5493*fcf3ce44SJohn Forte } 5494*fcf3ce44SJohn Forte } 5495*fcf3ce44SJohn Forte 5496*fcf3ce44SJohn Forte static void 5497*fcf3ce44SJohn Forte unload_rdc_vols() 5498*fcf3ce44SJohn Forte { 5499*fcf3ce44SJohn Forte nsc_remove_all(volhash, free); 5500*fcf3ce44SJohn Forte volhash = 0; 5501*fcf3ce44SJohn Forte } 5502*fcf3ce44SJohn Forte 5503*fcf3ce44SJohn Forte static int 5504*fcf3ce44SJohn Forte perform_autosv() 5505*fcf3ce44SJohn Forte { 5506*fcf3ce44SJohn Forte if (!clustered) { 5507*fcf3ce44SJohn Forte return (1); 5508*fcf3ce44SJohn Forte } else { 5509*fcf3ce44SJohn Forte return (cfg_issuncluster()); 5510*fcf3ce44SJohn Forte } 5511*fcf3ce44SJohn Forte } 5512*fcf3ce44SJohn Forte 5513*fcf3ce44SJohn Forte /* 5514*fcf3ce44SJohn Forte * Check the user supplied fields against those in the dscfg for 5515*fcf3ce44SJohn Forte * this set. 5516*fcf3ce44SJohn Forte * Never returns on an error. 5517*fcf3ce44SJohn Forte */ 5518*fcf3ce44SJohn Forte static void 5519*fcf3ce44SJohn Forte checkgfields(CFGFILE *cfg, int setnumber, char *fromhost, char *fromfile, 5520*fcf3ce44SJohn Forte char *frombitmap, char *tobitmap, char *type, char *mode, char *group, 5521*fcf3ce44SJohn Forte char *ctag, char *diskq) 5522*fcf3ce44SJohn Forte { 5523*fcf3ce44SJohn Forte if (fromhost[0]) 5524*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "phost", 5525*fcf3ce44SJohn Forte gettext("primary host"), fromhost); 5526*fcf3ce44SJohn Forte if (fromfile[0]) 5527*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "primary", 5528*fcf3ce44SJohn Forte gettext("primary volume"), fromfile); 5529*fcf3ce44SJohn Forte if (frombitmap[0]) 5530*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "pbitmap", 5531*fcf3ce44SJohn Forte gettext("primary bitmap"), frombitmap); 5532*fcf3ce44SJohn Forte if (tobitmap[0]) 5533*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "sbitmap", 5534*fcf3ce44SJohn Forte gettext("secondary bitmap"), tobitmap); 5535*fcf3ce44SJohn Forte if (type[0]) 5536*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "type", 5537*fcf3ce44SJohn Forte gettext("type of connection"), type); 5538*fcf3ce44SJohn Forte if (mode[0]) 5539*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "mode", 5540*fcf3ce44SJohn Forte gettext("mode of connection"), mode); 5541*fcf3ce44SJohn Forte if (group[0]) 5542*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "group", 5543*fcf3ce44SJohn Forte gettext("group"), group); 5544*fcf3ce44SJohn Forte if (ctag[0]) 5545*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "cnode", 5546*fcf3ce44SJohn Forte gettext("cluster tag"), ctag); 5547*fcf3ce44SJohn Forte if (diskq[0]) 5548*fcf3ce44SJohn Forte checkgfield(cfg, setnumber, "diskq", 5549*fcf3ce44SJohn Forte gettext("disk queue volume"), diskq); 5550*fcf3ce44SJohn Forte } 5551*fcf3ce44SJohn Forte 5552*fcf3ce44SJohn Forte /* 5553*fcf3ce44SJohn Forte * Check the 'fname' field in the dscfg file for set number 'setnumber' 5554*fcf3ce44SJohn Forte * If it does not match the user's data, 'data', then print the error 5555*fcf3ce44SJohn Forte * message using the friendly field name 'ufield'. 5556*fcf3ce44SJohn Forte * Never returns on an error. 5557*fcf3ce44SJohn Forte */ 5558*fcf3ce44SJohn Forte static void 5559*fcf3ce44SJohn Forte checkgfield(CFGFILE *cfg, int setnumber, char *fname, char *ufield, char *data) 5560*fcf3ce44SJohn Forte { 5561*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 5562*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 5563*fcf3ce44SJohn Forte 5564*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.%s", setnumber, fname); 5565*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 5566*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to fetch data for key %s"), 5567*fcf3ce44SJohn Forte key); 5568*fcf3ce44SJohn Forte } 5569*fcf3ce44SJohn Forte if (strcmp(buf, data) != 0) { 5570*fcf3ce44SJohn Forte rdc_err(NULL, 5571*fcf3ce44SJohn Forte gettext("the value specified for the %s field is not\nthe " 5572*fcf3ce44SJohn Forte "same as that contained within the configuration storage " 5573*fcf3ce44SJohn Forte "file for this set.\nYou specified \"%s\" " 5574*fcf3ce44SJohn Forte "expected \"%s\"."), 5575*fcf3ce44SJohn Forte ufield, data, buf); 5576*fcf3ce44SJohn Forte } 5577*fcf3ce44SJohn Forte } 5578*fcf3ce44SJohn Forte 5579*fcf3ce44SJohn Forte /* 5580*fcf3ce44SJohn Forte * load and send the contents of the bitmap file to the kernel. 5581*fcf3ce44SJohn Forte */ 5582*fcf3ce44SJohn Forte static int 5583*fcf3ce44SJohn Forte rdc_bitmapset(char *tohost, char *tofile, char *bitmap, int op, 5584*fcf3ce44SJohn Forte nsc_off_t offset) 5585*fcf3ce44SJohn Forte { 5586*fcf3ce44SJohn Forte rdc_bitmap_op_t bmop; 5587*fcf3ce44SJohn Forte int fd; 5588*fcf3ce44SJohn Forte void *buffer; 5589*fcf3ce44SJohn Forte int buffersz; 5590*fcf3ce44SJohn Forte struct stat s; 5591*fcf3ce44SJohn Forte int n; 5592*fcf3ce44SJohn Forte int ret; 5593*fcf3ce44SJohn Forte /* 5594*fcf3ce44SJohn Forte * open bitmap file for reading. 5595*fcf3ce44SJohn Forte */ 5596*fcf3ce44SJohn Forte if ((fd = open(bitmap, O_RDONLY)) < 0) { 5597*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to open bitmap file %s"), 5598*fcf3ce44SJohn Forte bitmap); 5599*fcf3ce44SJohn Forte return (1); 5600*fcf3ce44SJohn Forte } 5601*fcf3ce44SJohn Forte fstat(fd, &s); 5602*fcf3ce44SJohn Forte 5603*fcf3ce44SJohn Forte if (S_ISREG(s.st_mode) == 0) { 5604*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Bitmap %s is not a regular file"), 5605*fcf3ce44SJohn Forte bitmap); 5606*fcf3ce44SJohn Forte (void) close(fd); 5607*fcf3ce44SJohn Forte return (1); 5608*fcf3ce44SJohn Forte } 5609*fcf3ce44SJohn Forte 5610*fcf3ce44SJohn Forte if (op == 0) { 5611*fcf3ce44SJohn Forte op = RDC_BITMAPOR; 5612*fcf3ce44SJohn Forte } 5613*fcf3ce44SJohn Forte /* 5614*fcf3ce44SJohn Forte * use the file size to allocate buffer. This 5615*fcf3ce44SJohn Forte * size should be a multiple of FBA, but don't check 5616*fcf3ce44SJohn Forte * it here. 5617*fcf3ce44SJohn Forte */ 5618*fcf3ce44SJohn Forte buffersz = s.st_size; 5619*fcf3ce44SJohn Forte buffer = malloc(buffersz); 5620*fcf3ce44SJohn Forte if (buffer == NULL) { 5621*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to allocate %d bytes " 5622*fcf3ce44SJohn Forte "for bitmap file %s"), buffersz, bitmap); 5623*fcf3ce44SJohn Forte (void) close(fd); 5624*fcf3ce44SJohn Forte return (1); 5625*fcf3ce44SJohn Forte } 5626*fcf3ce44SJohn Forte n = read(fd, buffer, buffersz); 5627*fcf3ce44SJohn Forte (void) close(fd); 5628*fcf3ce44SJohn Forte if (n != buffersz) { 5629*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Unable to read the bitmap file, " 5630*fcf3ce44SJohn Forte "read returned %d instead of %d"), 5631*fcf3ce44SJohn Forte n, buffersz); 5632*fcf3ce44SJohn Forte free(buffer); 5633*fcf3ce44SJohn Forte return (1); 5634*fcf3ce44SJohn Forte } 5635*fcf3ce44SJohn Forte bmop.offset = offset; 5636*fcf3ce44SJohn Forte bmop.op = op; 5637*fcf3ce44SJohn Forte strncpy(bmop.sechost, tohost, MAX_RDC_HOST_SIZE); 5638*fcf3ce44SJohn Forte strncpy(bmop.secfile, tofile, NSC_MAXPATH); 5639*fcf3ce44SJohn Forte bmop.len = buffersz; 5640*fcf3ce44SJohn Forte bmop.addr = (unsigned long)buffer; 5641*fcf3ce44SJohn Forte ret = rdc_ioctl_simple(RDC_BITMAPOP, &bmop); 5642*fcf3ce44SJohn Forte free(buffer); 5643*fcf3ce44SJohn Forte if (ret < 0) { 5644*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("Setting bitmap ioctl failed for set " 5645*fcf3ce44SJohn Forte "%s:%s"), tohost, tofile); 5646*fcf3ce44SJohn Forte 5647*fcf3ce44SJohn Forte switch (errno) { 5648*fcf3ce44SJohn Forte case EIO: 5649*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("One of the sets is not " 5650*fcf3ce44SJohn Forte "enabled")); 5651*fcf3ce44SJohn Forte break; 5652*fcf3ce44SJohn Forte case ENXIO: 5653*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("One of the sets is not " 5654*fcf3ce44SJohn Forte "logging")); 5655*fcf3ce44SJohn Forte break; 5656*fcf3ce44SJohn Forte default: 5657*fcf3ce44SJohn Forte break; 5658*fcf3ce44SJohn Forte } 5659*fcf3ce44SJohn Forte } else { 5660*fcf3ce44SJohn Forte ret = 0; 5661*fcf3ce44SJohn Forte } 5662*fcf3ce44SJohn Forte if (ret) 5663*fcf3ce44SJohn Forte ret = 1; 5664*fcf3ce44SJohn Forte return (ret); 5665*fcf3ce44SJohn Forte } 5666*fcf3ce44SJohn Forte 5667*fcf3ce44SJohn Forte /* 5668*fcf3ce44SJohn Forte * verify_groupname: Check the group name for the following rules: 5669*fcf3ce44SJohn Forte * 1. The name does not start with a '-' 5670*fcf3ce44SJohn Forte * 2. The name does not contain any space characters as defined by 5671*fcf3ce44SJohn Forte * isspace(3C). 5672*fcf3ce44SJohn Forte * 5673*fcf3ce44SJohn Forte * If either of these rules are broken, error immediately. 5674*fcf3ce44SJohn Forte */ 5675*fcf3ce44SJohn Forte static void 5676*fcf3ce44SJohn Forte verify_groupname(char *grp) 5677*fcf3ce44SJohn Forte { 5678*fcf3ce44SJohn Forte int i; 5679*fcf3ce44SJohn Forte 5680*fcf3ce44SJohn Forte if (grp[0] == '-') { 5681*fcf3ce44SJohn Forte rdc_err(NULL, gettext("group name cannot start with a '-'")); 5682*fcf3ce44SJohn Forte } 5683*fcf3ce44SJohn Forte 5684*fcf3ce44SJohn Forte for (i = 0; grp[i] != '\0'; i++) { 5685*fcf3ce44SJohn Forte if (isspace(grp[i])) { 5686*fcf3ce44SJohn Forte rdc_err(NULL, gettext("group name cannot contain a " 5687*fcf3ce44SJohn Forte "space")); 5688*fcf3ce44SJohn Forte } 5689*fcf3ce44SJohn Forte } 5690*fcf3ce44SJohn Forte } 5691