17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
21*11576SSurya.Prakki@Sun.COM
227836SJohn.Forte@Sun.COM /*
23*11576SSurya.Prakki@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
247836SJohn.Forte@Sun.COM * Use is subject to license terms.
257836SJohn.Forte@Sun.COM */
267836SJohn.Forte@Sun.COM
277836SJohn.Forte@Sun.COM #include <sys/types.h>
287836SJohn.Forte@Sun.COM #include <sys/utsname.h>
297836SJohn.Forte@Sun.COM #include <sys/wait.h>
307836SJohn.Forte@Sun.COM #include <stdio.h>
317836SJohn.Forte@Sun.COM #include <errno.h>
327836SJohn.Forte@Sun.COM #include <values.h>
337836SJohn.Forte@Sun.COM #include <limits.h>
347836SJohn.Forte@Sun.COM #include <fcntl.h>
357836SJohn.Forte@Sun.COM #include <strings.h>
367836SJohn.Forte@Sun.COM #include <stdlib.h>
377836SJohn.Forte@Sun.COM #include <unistd.h>
387836SJohn.Forte@Sun.COM #include <sys/stat.h>
397836SJohn.Forte@Sun.COM
407836SJohn.Forte@Sun.COM #include <locale.h>
417836SJohn.Forte@Sun.COM #include <langinfo.h>
427836SJohn.Forte@Sun.COM #include <libintl.h>
437836SJohn.Forte@Sun.COM #include <stdarg.h>
447836SJohn.Forte@Sun.COM #include <netdb.h>
457836SJohn.Forte@Sun.COM #include <ctype.h>
467836SJohn.Forte@Sun.COM
477836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_io.h>
487836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_ioctl.h>
497836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_prot.h>
507836SJohn.Forte@Sun.COM
517836SJohn.Forte@Sun.COM #include <sys/nsctl/cfg.h>
527836SJohn.Forte@Sun.COM
537836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
547836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_u.h>
557836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
567836SJohn.Forte@Sun.COM
577836SJohn.Forte@Sun.COM #include <sys/socket.h>
587836SJohn.Forte@Sun.COM #include <netinet/in.h>
597836SJohn.Forte@Sun.COM #include <arpa/inet.h>
607836SJohn.Forte@Sun.COM #include <netinet/tcp.h>
617836SJohn.Forte@Sun.COM #include <rpc/rpc_com.h>
627836SJohn.Forte@Sun.COM #include <rpc/rpc.h>
637836SJohn.Forte@Sun.COM
647836SJohn.Forte@Sun.COM #include <sys/nsctl/librdc.h>
657836SJohn.Forte@Sun.COM #include <sys/nsctl/nsc_hash.h>
667836SJohn.Forte@Sun.COM
677836SJohn.Forte@Sun.COM #include "rdcadm.h"
687836SJohn.Forte@Sun.COM
697836SJohn.Forte@Sun.COM /*
707836SJohn.Forte@Sun.COM * support for the special cluster tag "local" to be used with -C in a
717836SJohn.Forte@Sun.COM * cluster for local volumes.
727836SJohn.Forte@Sun.COM */
737836SJohn.Forte@Sun.COM
747836SJohn.Forte@Sun.COM #define RDC_LOCAL_TAG "local"
757836SJohn.Forte@Sun.COM
767836SJohn.Forte@Sun.COM typedef struct volcount_s {
777836SJohn.Forte@Sun.COM int count;
787836SJohn.Forte@Sun.COM } volcount_t;
797836SJohn.Forte@Sun.COM hash_node_t **volhash = NULL;
807836SJohn.Forte@Sun.COM
817836SJohn.Forte@Sun.COM /*
827836SJohn.Forte@Sun.COM * rdc_islocal is only pertinent while creating the pairs array.
837836SJohn.Forte@Sun.COM * after all the pairs are set, its value is useless, retaining
847836SJohn.Forte@Sun.COM * the last value it was set to.
857836SJohn.Forte@Sun.COM * its only reason in life is to suppress an error message in 2
867836SJohn.Forte@Sun.COM * places where the inappropriate becomes appropriate (a supplied
877836SJohn.Forte@Sun.COM * ctag which does not match an implied one cfg_dgame()). This
887836SJohn.Forte@Sun.COM * happens when C "local" is supplied. It is then used to make an
897836SJohn.Forte@Sun.COM * error message clearer. A
907836SJohn.Forte@Sun.COM * gettext("set %s does not match", rdc_islocal < 1?dga:dgb) situation
917836SJohn.Forte@Sun.COM */
927836SJohn.Forte@Sun.COM static int rdc_islocal = 0;
937836SJohn.Forte@Sun.COM
947836SJohn.Forte@Sun.COM char *program;
957836SJohn.Forte@Sun.COM
967836SJohn.Forte@Sun.COM #define min(a, b) ((a) > (b) ? (b) : (a))
977836SJohn.Forte@Sun.COM
987836SJohn.Forte@Sun.COM static char place_holder[] = "-"; /* cfg place holder value */
997836SJohn.Forte@Sun.COM
1007836SJohn.Forte@Sun.COM /*
1017836SJohn.Forte@Sun.COM * config file user level Dual copy pair structure
1027836SJohn.Forte@Sun.COM */
1037836SJohn.Forte@Sun.COM typedef struct _sd_dual_pair {
1047836SJohn.Forte@Sun.COM char fhost[MAX_RDC_HOST_SIZE]; /* Hostname for primary device */
1057836SJohn.Forte@Sun.COM char fnetaddr[RDC_MAXADDR]; /* Host netaddr for primary device */
1067836SJohn.Forte@Sun.COM char ffile[NSC_MAXPATH]; /* Primary device */
1077836SJohn.Forte@Sun.COM char fbitmap[NSC_MAXPATH]; /* Primary bitmap device */
1087836SJohn.Forte@Sun.COM char thost[MAX_RDC_HOST_SIZE]; /* Hostname for secondary device */
1097836SJohn.Forte@Sun.COM char tnetaddr[RDC_MAXADDR]; /* Host netaddr for secondary device */
1107836SJohn.Forte@Sun.COM char tfile[NSC_MAXPATH]; /* Secondary device */
1117836SJohn.Forte@Sun.COM char tbitmap[NSC_MAXPATH]; /* Secondary bitmap device */
1127836SJohn.Forte@Sun.COM char directfile[NSC_MAXPATH]; /* Local FCAL direct IO volume */
1137836SJohn.Forte@Sun.COM char group[NSC_MAXPATH]; /* Group name */
1147836SJohn.Forte@Sun.COM char ctag[MAX_RDC_HOST_SIZE]; /* Cluster resource name tag */
1157836SJohn.Forte@Sun.COM char diskqueue[NSC_MAXPATH]; /* Disk Queue volume */
1167836SJohn.Forte@Sun.COM int doasync; /* Device is in sync/async mode */
1177836SJohn.Forte@Sun.COM } _sd_dual_pair_t;
1187836SJohn.Forte@Sun.COM
1197836SJohn.Forte@Sun.COM #define EXTRA_ARGS 6 /* g grp C ctag q diskqueue */
1207836SJohn.Forte@Sun.COM
1217836SJohn.Forte@Sun.COM static int rdc_operation(
1227836SJohn.Forte@Sun.COM CFGFILE *, char *, char *, char *, char *, char *, char *,
1237836SJohn.Forte@Sun.COM int, int, char *, char *, char *, char *, int *, int);
1247836SJohn.Forte@Sun.COM int read_config(int, char *, char *, char *);
1257836SJohn.Forte@Sun.COM static int read_libcfg(int, char *, char *);
1267836SJohn.Forte@Sun.COM int prompt_user(int, int);
1277836SJohn.Forte@Sun.COM static void rdc_check_dgislocal(char *);
1287836SJohn.Forte@Sun.COM void process_clocal(char *);
1297836SJohn.Forte@Sun.COM static void usage(void);
1307836SJohn.Forte@Sun.COM void q_usage(int);
1317836SJohn.Forte@Sun.COM static void load_rdc_vols(CFGFILE *);
1327836SJohn.Forte@Sun.COM static void unload_rdc_vols();
1337836SJohn.Forte@Sun.COM static int perform_autosv();
1347836SJohn.Forte@Sun.COM static void different_devs(char *, char *);
1357836SJohn.Forte@Sun.COM static void validate_name(CFGFILE *, char *);
1367836SJohn.Forte@Sun.COM static void set_autosync(int, char *, char *, char *);
1377836SJohn.Forte@Sun.COM static int autosync_is_on(char *tohost, char *tofile);
1387836SJohn.Forte@Sun.COM static void enable_autosync(char *fhost, char *ffile, char *thost, char *tfile);
1397836SJohn.Forte@Sun.COM static void checkgfields(CFGFILE *, int, char *, char *, char *, char *,
1407836SJohn.Forte@Sun.COM char *, char *, char *, char *, char *);
1417836SJohn.Forte@Sun.COM static void checkgfield(CFGFILE *, int, char *, char *, char *);
1427836SJohn.Forte@Sun.COM static int rdc_bitmapset(char *, char *, char *, int, nsc_off_t);
1437836SJohn.Forte@Sun.COM static int parse_cfg_buf(char *, _sd_dual_pair_t *, char *);
1447836SJohn.Forte@Sun.COM static void verify_groupname(char *grp);
1457836SJohn.Forte@Sun.COM extern char *basename(char *);
1467836SJohn.Forte@Sun.COM
1477836SJohn.Forte@Sun.COM int rdc_maxsets;
1487836SJohn.Forte@Sun.COM static _sd_dual_pair_t *pair_list;
1497836SJohn.Forte@Sun.COM
1507836SJohn.Forte@Sun.COM struct netbuf svaddr;
1517836SJohn.Forte@Sun.COM struct netbuf *svp;
1527836SJohn.Forte@Sun.COM struct netconfig nconf;
1537836SJohn.Forte@Sun.COM struct netconfig *conf;
1547836SJohn.Forte@Sun.COM struct knetconfig knconf;
1557836SJohn.Forte@Sun.COM
1567836SJohn.Forte@Sun.COM static char *reconfig_pbitmap = NULL;
1577836SJohn.Forte@Sun.COM static char *reconfig_sbitmap = NULL;
1587836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
1597836SJohn.Forte@Sun.COM static char *reconfig_direct = NULL;
1607836SJohn.Forte@Sun.COM #endif
1617836SJohn.Forte@Sun.COM static char *reconfig_group = NULL;
1627836SJohn.Forte@Sun.COM static char reconfig_ctag[MAX_RDC_HOST_SIZE];
1637836SJohn.Forte@Sun.COM static int reconfig_doasync = -1;
1647836SJohn.Forte@Sun.COM
1657836SJohn.Forte@Sun.COM static int clustered = 0;
1667836SJohn.Forte@Sun.COM static int proto_test = 0;
1677836SJohn.Forte@Sun.COM int allow_role = 0;
1687836SJohn.Forte@Sun.COM
1697836SJohn.Forte@Sun.COM
1707836SJohn.Forte@Sun.COM static char *
rdc_print_state(rdc_set_t * urdc)1717836SJohn.Forte@Sun.COM rdc_print_state(rdc_set_t *urdc)
1727836SJohn.Forte@Sun.COM {
1737836SJohn.Forte@Sun.COM if (!urdc)
1747836SJohn.Forte@Sun.COM return ("");
1757836SJohn.Forte@Sun.COM
1767836SJohn.Forte@Sun.COM if (urdc->sync_flags & RDC_VOL_FAILED)
1777836SJohn.Forte@Sun.COM return (gettext("volume failed"));
1787836SJohn.Forte@Sun.COM else if (urdc->sync_flags & RDC_FCAL_FAILED)
1797836SJohn.Forte@Sun.COM return (gettext("fcal failed"));
1807836SJohn.Forte@Sun.COM else if (urdc->bmap_flags & RDC_BMP_FAILED)
1817836SJohn.Forte@Sun.COM return (gettext("bitmap failed"));
1827836SJohn.Forte@Sun.COM else if (urdc->flags & RDC_DISKQ_FAILED)
1837836SJohn.Forte@Sun.COM return (gettext("disk queue failed"));
1847836SJohn.Forte@Sun.COM else if (urdc->flags & RDC_LOGGING) {
1857836SJohn.Forte@Sun.COM if (urdc->sync_flags & RDC_SYNC_NEEDED)
1867836SJohn.Forte@Sun.COM return (gettext("need sync"));
1877836SJohn.Forte@Sun.COM else if (urdc->sync_flags & RDC_RSYNC_NEEDED)
1887836SJohn.Forte@Sun.COM return (gettext("need reverse sync"));
1897836SJohn.Forte@Sun.COM else if (urdc->flags & RDC_QUEUING)
1907836SJohn.Forte@Sun.COM return (gettext("queuing"));
1917836SJohn.Forte@Sun.COM else
1927836SJohn.Forte@Sun.COM return (gettext("logging"));
1937836SJohn.Forte@Sun.COM } else if ((urdc->flags & RDC_SLAVE) && (urdc->flags & RDC_SYNCING)) {
1947836SJohn.Forte@Sun.COM if (urdc->flags & RDC_PRIMARY)
1957836SJohn.Forte@Sun.COM return (gettext("reverse syncing"));
1967836SJohn.Forte@Sun.COM else
1977836SJohn.Forte@Sun.COM return (gettext("syncing"));
1987836SJohn.Forte@Sun.COM } else if (urdc->flags & RDC_SYNCING) {
1997836SJohn.Forte@Sun.COM if (urdc->flags & RDC_PRIMARY)
2007836SJohn.Forte@Sun.COM return (gettext("syncing"));
2017836SJohn.Forte@Sun.COM else
2027836SJohn.Forte@Sun.COM return (gettext("reverse syncing"));
2037836SJohn.Forte@Sun.COM }
2047836SJohn.Forte@Sun.COM
2057836SJohn.Forte@Sun.COM return (gettext("replicating"));
2067836SJohn.Forte@Sun.COM }
2077836SJohn.Forte@Sun.COM
2087836SJohn.Forte@Sun.COM
2097836SJohn.Forte@Sun.COM static int
rdc_print(int file_format,int verbose,char * group_arg,char * ctag_arg,char * user_shost,char * user_sdev,CFGFILE * cfgp)2107836SJohn.Forte@Sun.COM rdc_print(int file_format, int verbose, char *group_arg, char *ctag_arg,
2117836SJohn.Forte@Sun.COM char *user_shost, char *user_sdev, CFGFILE *cfgp)
2127836SJohn.Forte@Sun.COM {
2137836SJohn.Forte@Sun.COM rdc_status_t *rdc_status;
2147836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
2157836SJohn.Forte@Sun.COM rdc_set_t *urdc;
2167836SJohn.Forte@Sun.COM size_t size;
2177836SJohn.Forte@Sun.COM int i, rc, max;
2187836SJohn.Forte@Sun.COM char *tohost, *tofile;
2197836SJohn.Forte@Sun.COM _sd_dual_pair_t pair;
2207836SJohn.Forte@Sun.COM char *tmptohost = pair.thost;
2217836SJohn.Forte@Sun.COM char *tmptofile = pair.tfile;
2227836SJohn.Forte@Sun.COM char *fromhost = pair.fhost;
2237836SJohn.Forte@Sun.COM char *fromfile = pair.ffile;
2247836SJohn.Forte@Sun.COM char *frombitmap = pair.fbitmap;
2257836SJohn.Forte@Sun.COM char *tobitmap = pair.tbitmap;
2267836SJohn.Forte@Sun.COM char *directfile = pair.directfile;
2277836SJohn.Forte@Sun.COM char *group = pair.group;
2287836SJohn.Forte@Sun.COM char *diskqueue = pair.diskqueue;
2297836SJohn.Forte@Sun.COM char *ctag = pair.ctag;
2307836SJohn.Forte@Sun.COM CFGFILE *cfg;
2317836SJohn.Forte@Sun.COM int j;
2327836SJohn.Forte@Sun.COM int setnumber;
2337836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
2347836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
2357836SJohn.Forte@Sun.COM char sync[16];
2367836SJohn.Forte@Sun.COM int match, found;
2377836SJohn.Forte@Sun.COM
2387836SJohn.Forte@Sun.COM size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1));
2397836SJohn.Forte@Sun.COM match = (user_shost != NULL || user_sdev != NULL);
2407836SJohn.Forte@Sun.COM found = 0;
2417836SJohn.Forte@Sun.COM
2427836SJohn.Forte@Sun.COM if (user_shost == NULL && user_sdev != NULL)
2437836SJohn.Forte@Sun.COM user_shost = "";
2447836SJohn.Forte@Sun.COM else if (user_shost != NULL && user_sdev == NULL)
2457836SJohn.Forte@Sun.COM user_sdev = "";
2467836SJohn.Forte@Sun.COM
2477836SJohn.Forte@Sun.COM rdc_status = malloc(size);
2487836SJohn.Forte@Sun.COM if (!rdc_status) {
2497836SJohn.Forte@Sun.COM rdc_err(NULL,
2507836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
2517836SJohn.Forte@Sun.COM }
2527836SJohn.Forte@Sun.COM
2537836SJohn.Forte@Sun.COM rdc_status->nset = rdc_maxsets;
2547836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
2557836SJohn.Forte@Sun.COM
2567836SJohn.Forte@Sun.COM rc = RDC_IOCTL(RDC_STATUS, rdc_status, 0, 0, 0, 0, ustatus);
2577836SJohn.Forte@Sun.COM if (rc == SPCS_S_ERROR) {
2587836SJohn.Forte@Sun.COM rdc_err(&ustatus, gettext("statistics error"));
2597836SJohn.Forte@Sun.COM }
2607836SJohn.Forte@Sun.COM
2617836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
2627836SJohn.Forte@Sun.COM
2637836SJohn.Forte@Sun.COM max = min(rdc_status->nset, rdc_maxsets);
2647836SJohn.Forte@Sun.COM
2657836SJohn.Forte@Sun.COM if (cfgp != NULL) {
2667836SJohn.Forte@Sun.COM cfg = cfgp;
2677836SJohn.Forte@Sun.COM cfg_rewind(cfg, CFG_SEC_CONF);
2687836SJohn.Forte@Sun.COM } else {
2697836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
2707836SJohn.Forte@Sun.COM rdc_err(NULL,
2717836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
2727836SJohn.Forte@Sun.COM
2737836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
2747836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
2757836SJohn.Forte@Sun.COM }
2767836SJohn.Forte@Sun.COM
2777836SJohn.Forte@Sun.COM for (i = 0; i < max; i++) {
2787836SJohn.Forte@Sun.COM urdc = &rdc_status->rdc_set[i];
2797836SJohn.Forte@Sun.COM
2807836SJohn.Forte@Sun.COM if (!(urdc->flags & RDC_ENABLED))
2817836SJohn.Forte@Sun.COM continue;
2827836SJohn.Forte@Sun.COM
2837836SJohn.Forte@Sun.COM if (match &&
2847836SJohn.Forte@Sun.COM (strcmp(user_shost, urdc->secondary.intf) != 0 ||
2857836SJohn.Forte@Sun.COM strcmp(user_sdev, urdc->secondary.file) != 0))
2867836SJohn.Forte@Sun.COM continue;
2877836SJohn.Forte@Sun.COM
2887836SJohn.Forte@Sun.COM tohost = urdc->secondary.intf;
2897836SJohn.Forte@Sun.COM tofile = urdc->secondary.file;
2907836SJohn.Forte@Sun.COM found = 1;
2917836SJohn.Forte@Sun.COM
2927836SJohn.Forte@Sun.COM /* get sndr entries until shost, sfile match */
2937836SJohn.Forte@Sun.COM for (j = 0; j < rdc_maxsets; j++) {
2947836SJohn.Forte@Sun.COM setnumber = j + 1;
2957836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
2967836SJohn.Forte@Sun.COM "sndr.set%d", setnumber);
2977836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
2987836SJohn.Forte@Sun.COM break;
2997836SJohn.Forte@Sun.COM }
3007836SJohn.Forte@Sun.COM
3017836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &pair, NULL))
3027836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cfg input error"));
3037836SJohn.Forte@Sun.COM
3047836SJohn.Forte@Sun.COM if (strcmp(tmptofile, tofile) != 0)
3057836SJohn.Forte@Sun.COM continue;
3067836SJohn.Forte@Sun.COM if (strcmp(tmptohost, tohost) != 0)
3077836SJohn.Forte@Sun.COM continue;
3087836SJohn.Forte@Sun.COM
3097836SJohn.Forte@Sun.COM if (pair.doasync == 0)
310*11576SSurya.Prakki@Sun.COM (void) strcpy(sync, "sync");
3117836SJohn.Forte@Sun.COM else
312*11576SSurya.Prakki@Sun.COM (void) strcpy(sync, "async");
3137836SJohn.Forte@Sun.COM
3147836SJohn.Forte@Sun.COM /* Got the matching entry */
3157836SJohn.Forte@Sun.COM
3167836SJohn.Forte@Sun.COM break;
3177836SJohn.Forte@Sun.COM }
3187836SJohn.Forte@Sun.COM
3197836SJohn.Forte@Sun.COM if (j == rdc_maxsets)
3207836SJohn.Forte@Sun.COM continue; /* not found in config */
3217836SJohn.Forte@Sun.COM
3227836SJohn.Forte@Sun.COM if (strcmp(group_arg, "") != 0 &&
3237836SJohn.Forte@Sun.COM strncmp(group_arg, group, NSC_MAXPATH) != 0)
3247836SJohn.Forte@Sun.COM continue;
3257836SJohn.Forte@Sun.COM
3267836SJohn.Forte@Sun.COM if (strcmp(ctag_arg, "") != 0 &&
3277836SJohn.Forte@Sun.COM strncmp(ctag_arg, ctag, MAX_RDC_HOST_SIZE) != 0)
3287836SJohn.Forte@Sun.COM continue;
3297836SJohn.Forte@Sun.COM
3307836SJohn.Forte@Sun.COM if (file_format) {
3317836SJohn.Forte@Sun.COM (void) printf("%s %s %s %s %s %s %s %s",
3327836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
3337836SJohn.Forte@Sun.COM tohost, tofile, tobitmap,
3347836SJohn.Forte@Sun.COM directfile, sync);
3357836SJohn.Forte@Sun.COM if (strlen(group) != 0)
3367836SJohn.Forte@Sun.COM (void) printf(" g %s", group);
3377836SJohn.Forte@Sun.COM if ((strlen(ctag) != 0) && (ctag[0] != '-'))
3387836SJohn.Forte@Sun.COM (void) printf(" C %s", ctag);
3397836SJohn.Forte@Sun.COM if (strlen(diskqueue) != 0)
3407836SJohn.Forte@Sun.COM (void) printf(" q %s", diskqueue);
3417836SJohn.Forte@Sun.COM (void) printf("\n");
3427836SJohn.Forte@Sun.COM continue;
3437836SJohn.Forte@Sun.COM }
3447836SJohn.Forte@Sun.COM
3457836SJohn.Forte@Sun.COM if (strcmp(group_arg, "") != 0 &&
3467836SJohn.Forte@Sun.COM strncmp(group_arg, urdc->group_name, NSC_MAXPATH) != 0)
3477836SJohn.Forte@Sun.COM continue;
3487836SJohn.Forte@Sun.COM
3497836SJohn.Forte@Sun.COM if (!(urdc->flags & RDC_PRIMARY)) {
3507836SJohn.Forte@Sun.COM (void) printf(gettext("%s\t<-\t%s:%s\n"),
3517836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->primary.intf,
3527836SJohn.Forte@Sun.COM urdc->primary.file);
3537836SJohn.Forte@Sun.COM } else {
3547836SJohn.Forte@Sun.COM (void) printf(gettext("%s\t->\t%s:%s\n"),
3557836SJohn.Forte@Sun.COM urdc->primary.file, urdc->secondary.intf,
3567836SJohn.Forte@Sun.COM urdc->secondary.file);
3577836SJohn.Forte@Sun.COM }
3587836SJohn.Forte@Sun.COM if (!verbose)
3597836SJohn.Forte@Sun.COM continue;
3607836SJohn.Forte@Sun.COM
3617836SJohn.Forte@Sun.COM if (urdc->autosync)
3627836SJohn.Forte@Sun.COM (void) printf(gettext("autosync: on"));
3637836SJohn.Forte@Sun.COM else
3647836SJohn.Forte@Sun.COM (void) printf(gettext("autosync: off"));
3657836SJohn.Forte@Sun.COM
3667836SJohn.Forte@Sun.COM (void) printf(gettext(", max q writes: %lld"), urdc->maxqitems);
3677836SJohn.Forte@Sun.COM (void) printf(gettext(", max q fbas: %lld"), urdc->maxqfbas);
3687836SJohn.Forte@Sun.COM (void) printf(gettext(", async threads: %d"),
3697836SJohn.Forte@Sun.COM urdc->asyncthr);
3707836SJohn.Forte@Sun.COM (void) printf(gettext(", mode: %s"),
3717836SJohn.Forte@Sun.COM pair.doasync ? "async" : "sync");
3727836SJohn.Forte@Sun.COM
3737836SJohn.Forte@Sun.COM if (strlen(urdc->group_name) != 0)
3747836SJohn.Forte@Sun.COM (void) printf(gettext(", group: %s"), urdc->group_name);
3757836SJohn.Forte@Sun.COM if ((strlen(ctag) != 0) && (ctag[0] != '-'))
3767836SJohn.Forte@Sun.COM (void) printf(gettext(", ctag: %s"), ctag);
3777836SJohn.Forte@Sun.COM if (strlen(urdc->disk_queue) != 0) {
3787836SJohn.Forte@Sun.COM (void) printf(gettext(", %s diskqueue: %s"),
3797836SJohn.Forte@Sun.COM (urdc->flags & RDC_QNOBLOCK) ? gettext("non blocking") :
3807836SJohn.Forte@Sun.COM gettext("blocking"), urdc->disk_queue);
3817836SJohn.Forte@Sun.COM }
3827836SJohn.Forte@Sun.COM
3837836SJohn.Forte@Sun.COM (void) printf(gettext(", state: %s"), rdc_print_state(urdc));
3847836SJohn.Forte@Sun.COM (void) printf(gettext("\n"));
3857836SJohn.Forte@Sun.COM
3867836SJohn.Forte@Sun.COM }
3877836SJohn.Forte@Sun.COM
3887836SJohn.Forte@Sun.COM if (!cfgp)
3897836SJohn.Forte@Sun.COM cfg_close(cfg);
3907836SJohn.Forte@Sun.COM
3917836SJohn.Forte@Sun.COM free(rdc_status);
3927836SJohn.Forte@Sun.COM
3937836SJohn.Forte@Sun.COM if (match && !found) {
3947836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("unable to find set %s:%s"),
3957836SJohn.Forte@Sun.COM user_shost, user_sdev);
3967836SJohn.Forte@Sun.COM }
3977836SJohn.Forte@Sun.COM
3987836SJohn.Forte@Sun.COM return (0);
3997836SJohn.Forte@Sun.COM }
4007836SJohn.Forte@Sun.COM
4017836SJohn.Forte@Sun.COM
4027836SJohn.Forte@Sun.COM int
parse_extras(int argc,char * args[],int i)4037836SJohn.Forte@Sun.COM parse_extras(int argc, char *args[], int i)
4047836SJohn.Forte@Sun.COM {
4057836SJohn.Forte@Sun.COM int gflag = 0;
4067836SJohn.Forte@Sun.COM int Cflag = 0;
4077836SJohn.Forte@Sun.COM int qflag = 0;
4087836SJohn.Forte@Sun.COM int j;
4097836SJohn.Forte@Sun.COM
410*11576SSurya.Prakki@Sun.COM (void) strcpy(pair_list[i].ctag, "");
411*11576SSurya.Prakki@Sun.COM (void) strcpy(pair_list[i].group, "");
412*11576SSurya.Prakki@Sun.COM (void) strcpy(pair_list[i].diskqueue, "");
4137836SJohn.Forte@Sun.COM
4147836SJohn.Forte@Sun.COM if (argc == 0)
4157836SJohn.Forte@Sun.COM return (0);
4167836SJohn.Forte@Sun.COM
4177836SJohn.Forte@Sun.COM if (argc != 2 && argc != 4 && argc != 6)
4187836SJohn.Forte@Sun.COM return (-1);
4197836SJohn.Forte@Sun.COM
4207836SJohn.Forte@Sun.COM for (j = 0; j < argc; j += 2) {
4217836SJohn.Forte@Sun.COM if (strcmp(args[j], "g") == 0) {
4227836SJohn.Forte@Sun.COM if (gflag)
4237836SJohn.Forte@Sun.COM return (-1);
424*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].group, args[j + 1],
425*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
4267836SJohn.Forte@Sun.COM gflag = 1;
4277836SJohn.Forte@Sun.COM }
4287836SJohn.Forte@Sun.COM if (strcmp(args[j], "C") == 0) {
4297836SJohn.Forte@Sun.COM if (!clustered)
4307836SJohn.Forte@Sun.COM return (-1);
4317836SJohn.Forte@Sun.COM if (Cflag)
4327836SJohn.Forte@Sun.COM return (-1);
433*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].ctag, args[j + 1],
4347836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
4357836SJohn.Forte@Sun.COM process_clocal(pair_list[i].ctag);
4367836SJohn.Forte@Sun.COM Cflag = 1;
4377836SJohn.Forte@Sun.COM }
4387836SJohn.Forte@Sun.COM if (strcmp(args[j], "q") == 0) {
4397836SJohn.Forte@Sun.COM if (qflag)
4407836SJohn.Forte@Sun.COM return (-1);
441*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].diskqueue, args[j + 1],
4427836SJohn.Forte@Sun.COM NSC_MAXPATH);
4437836SJohn.Forte@Sun.COM qflag = 1;
4447836SJohn.Forte@Sun.COM }
4457836SJohn.Forte@Sun.COM }
4467836SJohn.Forte@Sun.COM
4477836SJohn.Forte@Sun.COM return (0);
4487836SJohn.Forte@Sun.COM }
4497836SJohn.Forte@Sun.COM
4507836SJohn.Forte@Sun.COM static int
parse_cfg_buf(char * buf,_sd_dual_pair_t * pair,char * lghn)4517836SJohn.Forte@Sun.COM parse_cfg_buf(char *buf, _sd_dual_pair_t *pair, char *lghn)
4527836SJohn.Forte@Sun.COM {
4537836SJohn.Forte@Sun.COM int rc = 0;
4547836SJohn.Forte@Sun.COM char sync[16];
4557836SJohn.Forte@Sun.COM char options[64], *p, *q;
4567836SJohn.Forte@Sun.COM int len;
4577836SJohn.Forte@Sun.COM
4587836SJohn.Forte@Sun.COM rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s", pair->fhost,
4597836SJohn.Forte@Sun.COM pair->ffile, pair->fbitmap, pair->thost, pair->tfile,
4607836SJohn.Forte@Sun.COM pair->tbitmap, pair->directfile, sync, pair->group,
4617836SJohn.Forte@Sun.COM pair->ctag, options, pair->diskqueue);
4627836SJohn.Forte@Sun.COM
4637836SJohn.Forte@Sun.COM if (rc != 12)
4647836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cfg input error"));
4657836SJohn.Forte@Sun.COM
4667836SJohn.Forte@Sun.COM if (strcmp(pair->diskqueue, place_holder) == 0)
467*11576SSurya.Prakki@Sun.COM (void) strcpy(pair->diskqueue, "");
4687836SJohn.Forte@Sun.COM
4697836SJohn.Forte@Sun.COM if (strcmp(pair->group, place_holder) == 0)
470*11576SSurya.Prakki@Sun.COM (void) strcpy(pair->group, "");
4717836SJohn.Forte@Sun.COM
4727836SJohn.Forte@Sun.COM if (strcmp(sync, "sync") == 0)
4737836SJohn.Forte@Sun.COM pair->doasync = 0;
4747836SJohn.Forte@Sun.COM else if (strcmp(sync, "async") == 0)
4757836SJohn.Forte@Sun.COM pair->doasync = 1;
4767836SJohn.Forte@Sun.COM else {
4777836SJohn.Forte@Sun.COM rdc_err(NULL,
4787836SJohn.Forte@Sun.COM gettext("set %s:%s neither sync nor async"),
4797836SJohn.Forte@Sun.COM pair->thost, pair->tfile);
4807836SJohn.Forte@Sun.COM }
4817836SJohn.Forte@Sun.COM
4827836SJohn.Forte@Sun.COM if (lghn && (p = strstr(options, "lghn="))) {
4837836SJohn.Forte@Sun.COM p += 5;
4847836SJohn.Forte@Sun.COM q = strchr(p, ';');
4857836SJohn.Forte@Sun.COM if (q) {
4867836SJohn.Forte@Sun.COM /* LINTED p & q limited to options[64] */
4877836SJohn.Forte@Sun.COM len = q - p;
4887836SJohn.Forte@Sun.COM } else {
4897836SJohn.Forte@Sun.COM len = strlen(p);
4907836SJohn.Forte@Sun.COM }
491*11576SSurya.Prakki@Sun.COM (void) strncpy(lghn, p, len);
4927836SJohn.Forte@Sun.COM lghn[len] = '\0';
4937836SJohn.Forte@Sun.COM } else if (lghn) {
4947836SJohn.Forte@Sun.COM *lghn = '\0';
4957836SJohn.Forte@Sun.COM }
4967836SJohn.Forte@Sun.COM
4977836SJohn.Forte@Sun.COM return (0);
4987836SJohn.Forte@Sun.COM }
4997836SJohn.Forte@Sun.COM
5007836SJohn.Forte@Sun.COM static int
ctag_check(char * fromhost,char * fromfile,char * frombitmap,char * tohost,char * tofile,char * tobitmap,char * ctag,char * diskq)5017836SJohn.Forte@Sun.COM ctag_check(char *fromhost, char *fromfile, char *frombitmap, char *tohost,
5027836SJohn.Forte@Sun.COM char *tofile, char *tobitmap, char *ctag, char *diskq)
5037836SJohn.Forte@Sun.COM {
5047836SJohn.Forte@Sun.COM char *file_dgname;
5057836SJohn.Forte@Sun.COM char *bmp_dgname;
5067836SJohn.Forte@Sun.COM char *que_dgname;
5077836SJohn.Forte@Sun.COM char *localfile;
5087836SJohn.Forte@Sun.COM char file_buf[MAX_RDC_HOST_SIZE];
5097836SJohn.Forte@Sun.COM char bmp_buf[MAX_RDC_HOST_SIZE];
5107836SJohn.Forte@Sun.COM char que_buf[NSC_MAXPATH];
5117836SJohn.Forte@Sun.COM int is_primary;
5127836SJohn.Forte@Sun.COM struct hostent *hp;
5137836SJohn.Forte@Sun.COM char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
5147836SJohn.Forte@Sun.COM
5157836SJohn.Forte@Sun.COM if (!clustered)
5167836SJohn.Forte@Sun.COM return (0);
5177836SJohn.Forte@Sun.COM
5187836SJohn.Forte@Sun.COM hp = gethost_byname(fromhost);
519*11576SSurya.Prakki@Sun.COM (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
5207836SJohn.Forte@Sun.COM hp = gethost_byname(tohost);
521*11576SSurya.Prakki@Sun.COM (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
5227836SJohn.Forte@Sun.COM if (!self_check(fromname) && !self_check(toname)) {
5237836SJohn.Forte@Sun.COM /*
5247836SJohn.Forte@Sun.COM * If we could get a list of logical hosts on this cluster
5257836SJohn.Forte@Sun.COM * then we could print something intelligent about where
5267836SJohn.Forte@Sun.COM * the volume is mastered. For now, just print some babble
5277836SJohn.Forte@Sun.COM * about the fact that we have no idea.
5287836SJohn.Forte@Sun.COM */
5297836SJohn.Forte@Sun.COM rdc_err(NULL,
5307836SJohn.Forte@Sun.COM gettext("either %s:%s or %s:%s is not local"),
5317836SJohn.Forte@Sun.COM fromhost, fromfile, tohost, tofile);
5327836SJohn.Forte@Sun.COM }
5337836SJohn.Forte@Sun.COM
5347836SJohn.Forte@Sun.COM is_primary = self_check(fromname);
5357836SJohn.Forte@Sun.COM
5367836SJohn.Forte@Sun.COM /*
5377836SJohn.Forte@Sun.COM * If implicit disk group name and no ctag specified by user,
5387836SJohn.Forte@Sun.COM * we set the ctag to it.
5397836SJohn.Forte@Sun.COM * If implicit disk group name, it must match any supplied ctag.
5407836SJohn.Forte@Sun.COM */
5417836SJohn.Forte@Sun.COM localfile = is_primary ? fromfile : tofile;
5427836SJohn.Forte@Sun.COM file_dgname = cfg_dgname(localfile, file_buf, sizeof (file_buf));
5437836SJohn.Forte@Sun.COM if (file_dgname && strlen(file_dgname))
5447836SJohn.Forte@Sun.COM rdc_check_dgislocal(file_dgname);
5457836SJohn.Forte@Sun.COM
5467836SJohn.Forte@Sun.COM /*
5477836SJohn.Forte@Sun.COM * Autogenerate a ctag, if not "-C local" or no "-C " specified
5487836SJohn.Forte@Sun.COM */
5497836SJohn.Forte@Sun.COM if (!rdc_islocal && !strlen(ctag) && file_dgname && strlen(file_dgname))
550*11576SSurya.Prakki@Sun.COM (void) strncpy(ctag, file_dgname, MAX_RDC_HOST_SIZE);
5517836SJohn.Forte@Sun.COM
5527836SJohn.Forte@Sun.COM /*
5537836SJohn.Forte@Sun.COM * making an exception here for users giving the "local"tag
5547836SJohn.Forte@Sun.COM * this overrides this error message. (rdc_islocal ! = 1)
5557836SJohn.Forte@Sun.COM */
5567836SJohn.Forte@Sun.COM if (!rdc_islocal && strlen(ctag) &&
5577836SJohn.Forte@Sun.COM file_dgname && strlen(file_dgname) &&
5587836SJohn.Forte@Sun.COM strncmp(ctag, file_dgname, MAX_RDC_HOST_SIZE)) {
5597836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("ctag \"%s\" does not "
5607836SJohn.Forte@Sun.COM "match disk group name \"%s\" of volume %s"), ctag,
5617836SJohn.Forte@Sun.COM file_dgname, localfile);
5627836SJohn.Forte@Sun.COM return (-1);
5637836SJohn.Forte@Sun.COM }
5647836SJohn.Forte@Sun.COM
5657836SJohn.Forte@Sun.COM /*
5667836SJohn.Forte@Sun.COM * Do we have a non-volume managed disk without -C local specified?
5677836SJohn.Forte@Sun.COM */
5687836SJohn.Forte@Sun.COM if (!rdc_islocal && (!file_dgname || !strlen(file_dgname))) {
5697836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("volume \"%s\" is not part"
5707836SJohn.Forte@Sun.COM " of a disk group,\nplease specify resource ctag\n"),
5717836SJohn.Forte@Sun.COM localfile);
5727836SJohn.Forte@Sun.COM }
5737836SJohn.Forte@Sun.COM
5747836SJohn.Forte@Sun.COM /*
5757836SJohn.Forte@Sun.COM * Do we have a volume managed disk with -C local?
5767836SJohn.Forte@Sun.COM */
5777836SJohn.Forte@Sun.COM if (rdc_islocal && file_dgname && (strlen(file_dgname) > 0)) {
5787836SJohn.Forte@Sun.COM rdc_err(NULL, gettext(
5797836SJohn.Forte@Sun.COM "volume \"%s\" is part of a disk group\n"), localfile);
5807836SJohn.Forte@Sun.COM }
5817836SJohn.Forte@Sun.COM
5827836SJohn.Forte@Sun.COM /*
5837836SJohn.Forte@Sun.COM * Local bitmap must also have same ctag.
5847836SJohn.Forte@Sun.COM */
5857836SJohn.Forte@Sun.COM localfile = is_primary ? frombitmap : tobitmap;
5867836SJohn.Forte@Sun.COM bmp_dgname = cfg_dgname(localfile, bmp_buf, sizeof (bmp_buf));
5877836SJohn.Forte@Sun.COM if (bmp_dgname && strlen(bmp_dgname))
5887836SJohn.Forte@Sun.COM rdc_check_dgislocal(bmp_dgname);
5897836SJohn.Forte@Sun.COM
5907836SJohn.Forte@Sun.COM /*
5917836SJohn.Forte@Sun.COM * Assure that if the primary has a device group, so must the bitmap
5927836SJohn.Forte@Sun.COM */
5937836SJohn.Forte@Sun.COM if ((file_dgname && strlen(file_dgname)) &&
5947836SJohn.Forte@Sun.COM (!bmp_dgname || !strlen(bmp_dgname))) {
5957836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("bitmap %s is not in disk group \"%s\""),
5967836SJohn.Forte@Sun.COM localfile, rdc_islocal < 1?file_dgname:ctag);
5977836SJohn.Forte@Sun.COM return (-1);
5987836SJohn.Forte@Sun.COM }
5997836SJohn.Forte@Sun.COM
6007836SJohn.Forte@Sun.COM /*
6017836SJohn.Forte@Sun.COM * Assure that if the if there is a ctag, it must match the bitmap
6027836SJohn.Forte@Sun.COM */
6037836SJohn.Forte@Sun.COM if (!rdc_islocal && strlen(ctag) &&
6047836SJohn.Forte@Sun.COM bmp_dgname && strlen(bmp_dgname) &&
6057836SJohn.Forte@Sun.COM strncmp(ctag, bmp_dgname, MAX_RDC_HOST_SIZE)) {
6067836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("ctag \"%s\" does not "
6077836SJohn.Forte@Sun.COM "match disk group name \"%s\" of bitmap %s"), ctag,
6087836SJohn.Forte@Sun.COM bmp_dgname, localfile);
6097836SJohn.Forte@Sun.COM return (-1);
6107836SJohn.Forte@Sun.COM }
6117836SJohn.Forte@Sun.COM
6127836SJohn.Forte@Sun.COM /*
6137836SJohn.Forte@Sun.COM * If this is the SNDR primary and there is a local disk queue
6147836SJohn.Forte@Sun.COM */
6157836SJohn.Forte@Sun.COM if (is_primary && diskq[0]) {
6167836SJohn.Forte@Sun.COM
6177836SJohn.Forte@Sun.COM /*
6187836SJohn.Forte@Sun.COM * Local disk queue must also have same ctag.
6197836SJohn.Forte@Sun.COM */
6207836SJohn.Forte@Sun.COM que_dgname = cfg_dgname(diskq, que_buf, sizeof (que_buf));
6217836SJohn.Forte@Sun.COM if (que_dgname && strlen(que_dgname))
6227836SJohn.Forte@Sun.COM rdc_check_dgislocal(que_dgname);
6237836SJohn.Forte@Sun.COM
6247836SJohn.Forte@Sun.COM /*
6257836SJohn.Forte@Sun.COM * Assure that if the primary has a device group, so must
6267836SJohn.Forte@Sun.COM * the disk queue
6277836SJohn.Forte@Sun.COM */
6287836SJohn.Forte@Sun.COM if ((file_dgname && strlen(file_dgname)) &&
6297836SJohn.Forte@Sun.COM (!que_dgname || !strlen(que_dgname))) {
6307836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("disk queue %s is not in disk "
6317836SJohn.Forte@Sun.COM "group \"%s\""), diskq,
6327836SJohn.Forte@Sun.COM rdc_islocal < 1?file_dgname:ctag);
6337836SJohn.Forte@Sun.COM return (-1);
6347836SJohn.Forte@Sun.COM }
6357836SJohn.Forte@Sun.COM
6367836SJohn.Forte@Sun.COM /*
6377836SJohn.Forte@Sun.COM * Assure that if the if there is a ctag, it must match
6387836SJohn.Forte@Sun.COM * the disk queue
6397836SJohn.Forte@Sun.COM */
6407836SJohn.Forte@Sun.COM if (!rdc_islocal && strlen(ctag) &&
6417836SJohn.Forte@Sun.COM que_dgname && strlen(que_dgname) &&
6427836SJohn.Forte@Sun.COM strncmp(ctag, que_dgname, MAX_RDC_HOST_SIZE)) {
6437836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("ctag \"%s\" does not "
6447836SJohn.Forte@Sun.COM "match disk group name \"%s\" of disk queue %s"),
6457836SJohn.Forte@Sun.COM ctag, que_dgname, diskq);
6467836SJohn.Forte@Sun.COM return (-1);
6477836SJohn.Forte@Sun.COM }
6487836SJohn.Forte@Sun.COM }
6497836SJohn.Forte@Sun.COM
6507836SJohn.Forte@Sun.COM return (0);
6517836SJohn.Forte@Sun.COM }
6527836SJohn.Forte@Sun.COM
6537836SJohn.Forte@Sun.COM #define DISKQ_OKAY 0
6547836SJohn.Forte@Sun.COM #define DISKQ_FAIL 1
6557836SJohn.Forte@Sun.COM #define DISKQ_REWRITEG 2
6567836SJohn.Forte@Sun.COM /*
6577836SJohn.Forte@Sun.COM * check that newq is compatable with the groups current disk queue.
6587836SJohn.Forte@Sun.COM * Newq is incompatable if it is set and the groups queue is set and the queues
6597836SJohn.Forte@Sun.COM * are different.
6607836SJohn.Forte@Sun.COM *
6617836SJohn.Forte@Sun.COM * if newq is not set but should be, it will be set to the correct value.
6627836SJohn.Forte@Sun.COM * returns:
6637836SJohn.Forte@Sun.COM * DISK_REWRITEG entire group needs to take new value of disk_queue
6647836SJohn.Forte@Sun.COM * DISKQ_OKAY newq contains a value that matches the group.
6657836SJohn.Forte@Sun.COM * DISKQ_FAIL disk queues are incompatible.
6667836SJohn.Forte@Sun.COM */
6677836SJohn.Forte@Sun.COM static int
check_diskqueue(CFGFILE * cfg,char * newq,char * newgroup)6687836SJohn.Forte@Sun.COM check_diskqueue(CFGFILE *cfg, char *newq, char *newgroup)
6697836SJohn.Forte@Sun.COM {
6707836SJohn.Forte@Sun.COM int i, setnumber;
6717836SJohn.Forte@Sun.COM _sd_dual_pair_t pair;
6727836SJohn.Forte@Sun.COM char *group = pair.group;
6737836SJohn.Forte@Sun.COM char *diskqueue = pair.diskqueue;
6747836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
6757836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
6767836SJohn.Forte@Sun.COM int open_cfg = cfg == NULL ? 1 : 0;
6777836SJohn.Forte@Sun.COM
6787836SJohn.Forte@Sun.COM
6797836SJohn.Forte@Sun.COM if (newgroup == NULL || *newgroup == '\0') {
6807836SJohn.Forte@Sun.COM if (*newq == '\0')
6817836SJohn.Forte@Sun.COM return (DISKQ_OKAY); /* okay, */
6827836SJohn.Forte@Sun.COM newgroup = "--nomatch--";
6837836SJohn.Forte@Sun.COM }
6847836SJohn.Forte@Sun.COM
6857836SJohn.Forte@Sun.COM if (open_cfg) {
6867836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
6877836SJohn.Forte@Sun.COM rdc_err(NULL,
6887836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
6897836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
6907836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
6917836SJohn.Forte@Sun.COM }
6927836SJohn.Forte@Sun.COM
6937836SJohn.Forte@Sun.COM /*CSTYLED*/
6947836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
6957836SJohn.Forte@Sun.COM setnumber = i + 1;
6967836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
6977836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
6987836SJohn.Forte@Sun.COM break;
6997836SJohn.Forte@Sun.COM /*
7007836SJohn.Forte@Sun.COM * I think this is quicker than
7017836SJohn.Forte@Sun.COM * having to double dip into the config
7027836SJohn.Forte@Sun.COM */
7037836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &pair, NULL))
7047836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cfg input error"));
7057836SJohn.Forte@Sun.COM
7067836SJohn.Forte@Sun.COM if (strncmp(group, newgroup, NSC_MAXPATH) != 0) {
7077836SJohn.Forte@Sun.COM if (((strncmp(diskqueue, newq, NSC_MAXPATH) == 0)) &&
7087836SJohn.Forte@Sun.COM (diskqueue[0] != '\0')) {
7097836SJohn.Forte@Sun.COM if (open_cfg)
7107836SJohn.Forte@Sun.COM cfg_close(cfg);
7117836SJohn.Forte@Sun.COM return (DISKQ_FAIL);
7127836SJohn.Forte@Sun.COM }
7137836SJohn.Forte@Sun.COM continue;
7147836SJohn.Forte@Sun.COM }
7157836SJohn.Forte@Sun.COM if (*newq == '\0') {
7167836SJohn.Forte@Sun.COM if (diskqueue[0] != '\0')
717*11576SSurya.Prakki@Sun.COM (void) strncpy(newq, diskqueue, NSC_MAXPATH);
7187836SJohn.Forte@Sun.COM if (open_cfg)
7197836SJohn.Forte@Sun.COM cfg_close(cfg);
7207836SJohn.Forte@Sun.COM return (DISKQ_OKAY); /* okay, */
7217836SJohn.Forte@Sun.COM }
7227836SJohn.Forte@Sun.COM
7237836SJohn.Forte@Sun.COM if (open_cfg)
7247836SJohn.Forte@Sun.COM cfg_close(cfg);
7257836SJohn.Forte@Sun.COM if (diskqueue[0] == '\0') /* no queue here */
7267836SJohn.Forte@Sun.COM return (DISKQ_REWRITEG);
7277836SJohn.Forte@Sun.COM return (strncmp(diskqueue, newq, NSC_MAXPATH)
7287836SJohn.Forte@Sun.COM == 0 ? DISKQ_OKAY : DISKQ_FAIL);
7297836SJohn.Forte@Sun.COM }
7307836SJohn.Forte@Sun.COM if (open_cfg)
7317836SJohn.Forte@Sun.COM cfg_close(cfg);
7327836SJohn.Forte@Sun.COM return (DISKQ_OKAY);
7337836SJohn.Forte@Sun.COM }
7347836SJohn.Forte@Sun.COM
7357836SJohn.Forte@Sun.COM
7367836SJohn.Forte@Sun.COM int
pair_diskqueue_check(int newpair)7377836SJohn.Forte@Sun.COM pair_diskqueue_check(int newpair)
7387836SJohn.Forte@Sun.COM {
7397836SJohn.Forte@Sun.COM int i, j;
7407836SJohn.Forte@Sun.COM int rc;
7417836SJohn.Forte@Sun.COM
7427836SJohn.Forte@Sun.COM for (i = 0; i < newpair; i++) {
7437836SJohn.Forte@Sun.COM if (strcmp(pair_list[i].group, pair_list[newpair].group) != 0)
7447836SJohn.Forte@Sun.COM continue;
7457836SJohn.Forte@Sun.COM if (strcmp(pair_list[i].diskqueue, pair_list[newpair].diskqueue)
7467836SJohn.Forte@Sun.COM == 0)
7477836SJohn.Forte@Sun.COM return (DISKQ_OKAY); /* matches existing group */
7487836SJohn.Forte@Sun.COM if ((pair_list[newpair].group[0] != '\0') &&
7497836SJohn.Forte@Sun.COM (pair_list[newpair].diskqueue[0] != '\0') &&
7507836SJohn.Forte@Sun.COM (pair_list[i].diskqueue[0] != '\0')) {
7517836SJohn.Forte@Sun.COM rdc_warn(NULL,
7527836SJohn.Forte@Sun.COM gettext("disk queue %s does not match %s "
7537836SJohn.Forte@Sun.COM "skipping set"), pair_list[newpair].diskqueue,
7547836SJohn.Forte@Sun.COM pair_list[i].diskqueue);
7557836SJohn.Forte@Sun.COM return (DISKQ_FAIL);
7567836SJohn.Forte@Sun.COM }
7577836SJohn.Forte@Sun.COM
7587836SJohn.Forte@Sun.COM if ((strcmp(pair_list[newpair].diskqueue, "") == 0) &&
7597836SJohn.Forte@Sun.COM pair_list[newpair].group[0] != '\0') {
760*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[newpair].diskqueue,
7617836SJohn.Forte@Sun.COM pair_list[i].diskqueue, NSC_MAXPATH);
7627836SJohn.Forte@Sun.COM return (DISKQ_OKAY); /* changed to existing group que */
7637836SJohn.Forte@Sun.COM }
7647836SJohn.Forte@Sun.COM if (strcmp(pair_list[i].diskqueue, "") == 0) {
7657836SJohn.Forte@Sun.COM for (j = 0; j < newpair; j++) {
7667836SJohn.Forte@Sun.COM if ((pair_list[j].group[0] != '\0') &&
7677836SJohn.Forte@Sun.COM (strncmp(pair_list[j].group,
7687836SJohn.Forte@Sun.COM pair_list[newpair].group,
7697836SJohn.Forte@Sun.COM NSC_MAXPATH) == 0)) {
770*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[j].diskqueue,
7717836SJohn.Forte@Sun.COM pair_list[newpair].diskqueue,
7727836SJohn.Forte@Sun.COM NSC_MAXPATH);
7737836SJohn.Forte@Sun.COM }
7747836SJohn.Forte@Sun.COM }
7757836SJohn.Forte@Sun.COM return (DISKQ_OKAY);
7767836SJohn.Forte@Sun.COM }
7777836SJohn.Forte@Sun.COM break; /* no problem with pair_list sets */
7787836SJohn.Forte@Sun.COM
7797836SJohn.Forte@Sun.COM }
7807836SJohn.Forte@Sun.COM
7817836SJohn.Forte@Sun.COM /* now check with already configured sets */
7827836SJohn.Forte@Sun.COM rc = check_diskqueue(NULL, pair_list[newpair].diskqueue,
7837836SJohn.Forte@Sun.COM pair_list[newpair].group);
7847836SJohn.Forte@Sun.COM if (rc == DISKQ_REWRITEG) {
7857836SJohn.Forte@Sun.COM for (i = 0; i < newpair; i++) {
7867836SJohn.Forte@Sun.COM if (strcmp(pair_list[i].group,
7877836SJohn.Forte@Sun.COM pair_list[newpair].group) != 0)
7887836SJohn.Forte@Sun.COM continue;
7897836SJohn.Forte@Sun.COM
790*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].diskqueue,
7917836SJohn.Forte@Sun.COM pair_list[newpair].diskqueue, NSC_MAXPATH);
7927836SJohn.Forte@Sun.COM }
7937836SJohn.Forte@Sun.COM }
7947836SJohn.Forte@Sun.COM return (rc);
7957836SJohn.Forte@Sun.COM }
7967836SJohn.Forte@Sun.COM
7977836SJohn.Forte@Sun.COM int
ii_set_exists(CFGFILE * cfg,char * ma,char * sh,char * bm)7987836SJohn.Forte@Sun.COM ii_set_exists(CFGFILE *cfg, char *ma, char *sh, char *bm)
7997836SJohn.Forte@Sun.COM {
8007836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
8017836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
8027836SJohn.Forte@Sun.COM char master[NSC_MAXPATH];
8037836SJohn.Forte@Sun.COM char shadow[NSC_MAXPATH];
8047836SJohn.Forte@Sun.COM char bitmap[NSC_MAXPATH];
8057836SJohn.Forte@Sun.COM int i;
8067836SJohn.Forte@Sun.COM
8077836SJohn.Forte@Sun.COM for (i = 1; ; i++) {
8087836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ii.set%d", i);
8097836SJohn.Forte@Sun.COM bzero(&master, sizeof (master));
8107836SJohn.Forte@Sun.COM bzero(&shadow, sizeof (shadow));
8117836SJohn.Forte@Sun.COM bzero(&bitmap, sizeof (bitmap));
8127836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8137836SJohn.Forte@Sun.COM break;
8147836SJohn.Forte@Sun.COM (void) sscanf(buf, "%s %s %s", master, shadow, bitmap);
8157836SJohn.Forte@Sun.COM if (strcmp(master, ma) != 0)
8167836SJohn.Forte@Sun.COM continue;
8177836SJohn.Forte@Sun.COM if (strcmp(shadow, sh) != 0)
8187836SJohn.Forte@Sun.COM continue;
8197836SJohn.Forte@Sun.COM if (strcmp(bitmap, bm) != 0)
8207836SJohn.Forte@Sun.COM continue;
8217836SJohn.Forte@Sun.COM return (1);
8227836SJohn.Forte@Sun.COM }
8237836SJohn.Forte@Sun.COM return (0);
8247836SJohn.Forte@Sun.COM }
8257836SJohn.Forte@Sun.COM
8267836SJohn.Forte@Sun.COM void
rdc_ii_config(int argc,char ** argv)8277836SJohn.Forte@Sun.COM rdc_ii_config(int argc, char **argv)
8287836SJohn.Forte@Sun.COM {
8297836SJohn.Forte@Sun.COM char *master;
8307836SJohn.Forte@Sun.COM char *shadow;
8317836SJohn.Forte@Sun.COM char *bitmap;
8327836SJohn.Forte@Sun.COM char c;
8337836SJohn.Forte@Sun.COM CFGFILE *cfg;
8347836SJohn.Forte@Sun.COM int i;
8357836SJohn.Forte@Sun.COM int setnumber;
8367836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
8377836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
8387836SJohn.Forte@Sun.COM int found;
8397836SJohn.Forte@Sun.COM int sev;
8407836SJohn.Forte@Sun.COM
8417836SJohn.Forte@Sun.COM /* Parse the rest of the arguments to see what to do */
8427836SJohn.Forte@Sun.COM
8437836SJohn.Forte@Sun.COM if (argc - optind != 4) {
8447836SJohn.Forte@Sun.COM usage();
8457836SJohn.Forte@Sun.COM exit(1);
8467836SJohn.Forte@Sun.COM }
8477836SJohn.Forte@Sun.COM
8487836SJohn.Forte@Sun.COM c = *argv[optind];
8497836SJohn.Forte@Sun.COM switch (c) {
8507836SJohn.Forte@Sun.COM case 'd':
8517836SJohn.Forte@Sun.COM /* Delete an ndr_ii entry */
8527836SJohn.Forte@Sun.COM
8537836SJohn.Forte@Sun.COM master = argv[++optind];
8547836SJohn.Forte@Sun.COM shadow = argv[++optind];
8557836SJohn.Forte@Sun.COM bitmap = argv[++optind];
8567836SJohn.Forte@Sun.COM
8577836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
8587836SJohn.Forte@Sun.COM rdc_err(NULL,
8597836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
8607836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK))
8617836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
8627836SJohn.Forte@Sun.COM
8637836SJohn.Forte@Sun.COM found = 0;
8647836SJohn.Forte@Sun.COM /* get ndr_ii entries until a match is found */
8657836SJohn.Forte@Sun.COM /*CSTYLED*/
8667836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
8677836SJohn.Forte@Sun.COM setnumber = i + 1;
8687836SJohn.Forte@Sun.COM
8697836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
8707836SJohn.Forte@Sun.COM "ndr_ii.set%d.secondary",
8717836SJohn.Forte@Sun.COM setnumber);
8727836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8737836SJohn.Forte@Sun.COM break;
8747836SJohn.Forte@Sun.COM if (strcmp(buf, master) != 0)
8757836SJohn.Forte@Sun.COM continue;
8767836SJohn.Forte@Sun.COM
8777836SJohn.Forte@Sun.COM /* Got a matching entry */
8787836SJohn.Forte@Sun.COM
8797836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
8807836SJohn.Forte@Sun.COM "ndr_ii.set%d.shadow",
8817836SJohn.Forte@Sun.COM setnumber);
8827836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8837836SJohn.Forte@Sun.COM break;
8847836SJohn.Forte@Sun.COM if (strcmp(buf, shadow) != 0)
8857836SJohn.Forte@Sun.COM continue;
8867836SJohn.Forte@Sun.COM
8877836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
8887836SJohn.Forte@Sun.COM "ndr_ii.set%d.bitmap",
8897836SJohn.Forte@Sun.COM setnumber);
8907836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8917836SJohn.Forte@Sun.COM break;
8927836SJohn.Forte@Sun.COM if (strcmp(buf, bitmap) != 0)
8937836SJohn.Forte@Sun.COM continue;
8947836SJohn.Forte@Sun.COM
8957836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
8967836SJohn.Forte@Sun.COM "ndr_ii.set%d", setnumber);
8977836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
8987836SJohn.Forte@Sun.COM rdc_warn(NULL,
8997836SJohn.Forte@Sun.COM gettext("unable to remove \"%s\" "
9007836SJohn.Forte@Sun.COM "from configuration storage: %s"),
9017836SJohn.Forte@Sun.COM key, cfg_error(&sev));
9027836SJohn.Forte@Sun.COM } else {
9037836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0)
9047836SJohn.Forte@Sun.COM rdc_err(NULL,
9057836SJohn.Forte@Sun.COM gettext("ndr_ii set %s %s %s "
9067836SJohn.Forte@Sun.COM "not deconfigured."),
9077836SJohn.Forte@Sun.COM master, shadow, bitmap);
9087836SJohn.Forte@Sun.COM else
9097836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
9107836SJohn.Forte@Sun.COM gettext("ndr_ii set %s %s %s "
9117836SJohn.Forte@Sun.COM "has been deconfigured."),
9127836SJohn.Forte@Sun.COM master, shadow, bitmap);
9137836SJohn.Forte@Sun.COM }
9147836SJohn.Forte@Sun.COM found = 1;
9157836SJohn.Forte@Sun.COM break;
9167836SJohn.Forte@Sun.COM }
9177836SJohn.Forte@Sun.COM
9187836SJohn.Forte@Sun.COM if (!found) {
9197836SJohn.Forte@Sun.COM rdc_err(NULL,
9207836SJohn.Forte@Sun.COM gettext("did not find matching ndr_ii "
9217836SJohn.Forte@Sun.COM "entry for %s %s %s"), master, shadow, bitmap);
9227836SJohn.Forte@Sun.COM }
9237836SJohn.Forte@Sun.COM
9247836SJohn.Forte@Sun.COM cfg_close(cfg);
9257836SJohn.Forte@Sun.COM
9267836SJohn.Forte@Sun.COM break;
9277836SJohn.Forte@Sun.COM
9287836SJohn.Forte@Sun.COM case 'a':
9297836SJohn.Forte@Sun.COM /* Add an ndr_ii entry */
9307836SJohn.Forte@Sun.COM
9317836SJohn.Forte@Sun.COM master = argv[++optind];
9327836SJohn.Forte@Sun.COM shadow = argv[++optind];
9337836SJohn.Forte@Sun.COM bitmap = argv[++optind];
9347836SJohn.Forte@Sun.COM
9357836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
9367836SJohn.Forte@Sun.COM rdc_err(NULL,
9377836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
9387836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK))
9397836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
9407836SJohn.Forte@Sun.COM
9417836SJohn.Forte@Sun.COM found = 0;
9427836SJohn.Forte@Sun.COM /* get ndr_ii entries in case a match is found */
9437836SJohn.Forte@Sun.COM /*CSTYLED*/
9447836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
9457836SJohn.Forte@Sun.COM setnumber = i + 1;
9467836SJohn.Forte@Sun.COM
9477836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
9487836SJohn.Forte@Sun.COM "ndr_ii.set%d.secondary",
9497836SJohn.Forte@Sun.COM setnumber);
9507836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
9517836SJohn.Forte@Sun.COM break;
9527836SJohn.Forte@Sun.COM if (strcmp(buf, master) == 0) {
9537836SJohn.Forte@Sun.COM rdc_err(NULL,
9547836SJohn.Forte@Sun.COM gettext("found matching ndr_ii "
9557836SJohn.Forte@Sun.COM "entry for %s"), master);
9567836SJohn.Forte@Sun.COM }
9577836SJohn.Forte@Sun.COM }
9587836SJohn.Forte@Sun.COM /*
9597836SJohn.Forte@Sun.COM * check to see if this is using a sndr bitmap.
9607836SJohn.Forte@Sun.COM * kind of a courtesy check, as the ii copy would fail anyway
9617836SJohn.Forte@Sun.COM * excepting the case where they had actually configured
9627836SJohn.Forte@Sun.COM * ii/sndr that way, in which case they are broken
9637836SJohn.Forte@Sun.COM * before we get here
9647836SJohn.Forte@Sun.COM */
9657836SJohn.Forte@Sun.COM /*CSTYLED*/
9667836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
9677836SJohn.Forte@Sun.COM setnumber = i + 1;
9687836SJohn.Forte@Sun.COM
9697836SJohn.Forte@Sun.COM /*
9707836SJohn.Forte@Sun.COM * Checking local bitmaps
9717836SJohn.Forte@Sun.COM */
9727836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.phost",
9737836SJohn.Forte@Sun.COM setnumber);
9747836SJohn.Forte@Sun.COM
9757836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
9767836SJohn.Forte@Sun.COM break;
9777836SJohn.Forte@Sun.COM if (self_check(buf)) {
9787836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
9797836SJohn.Forte@Sun.COM "sndr.set%d.pbitmap",
9807836SJohn.Forte@Sun.COM setnumber);
9817836SJohn.Forte@Sun.COM } else {
9827836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
9837836SJohn.Forte@Sun.COM "sndr.set%d.sbitmap",
9847836SJohn.Forte@Sun.COM setnumber);
9857836SJohn.Forte@Sun.COM }
9867836SJohn.Forte@Sun.COM
9877836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
9887836SJohn.Forte@Sun.COM break;
9897836SJohn.Forte@Sun.COM
9907836SJohn.Forte@Sun.COM if ((strcmp(buf, bitmap) == 0) ||
9917836SJohn.Forte@Sun.COM (strcmp(buf, master) == 0) ||
9927836SJohn.Forte@Sun.COM (strcmp(buf, shadow) == 0)) {
9937836SJohn.Forte@Sun.COM rdc_err(NULL,
9947836SJohn.Forte@Sun.COM gettext("%s is already configured "
9957836SJohn.Forte@Sun.COM "as a Remote Mirror bitmap"), buf);
9967836SJohn.Forte@Sun.COM }
9977836SJohn.Forte@Sun.COM }
9987836SJohn.Forte@Sun.COM if (!ii_set_exists(cfg, master, shadow, bitmap)) {
9997836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Point-in-Time Copy set "
10007836SJohn.Forte@Sun.COM "%s %s %s is not already configured. Remote "
10017836SJohn.Forte@Sun.COM "Mirror will attempt to configure this set when "
10027836SJohn.Forte@Sun.COM "a sync is issued to it. The results of that "
10037836SJohn.Forte@Sun.COM "operation will be in /var/adm/ds.log"),
10047836SJohn.Forte@Sun.COM master, shadow, bitmap);
10057836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Point-in-Time Copy set "
10067836SJohn.Forte@Sun.COM "%s %s %s is not already configured. Remote "
10077836SJohn.Forte@Sun.COM "Mirror will attempt to configure this set when "
10087836SJohn.Forte@Sun.COM "a sync is issued to it. The results of that "
10097836SJohn.Forte@Sun.COM "operation will be in /var/adm/ds.log"),
10107836SJohn.Forte@Sun.COM master, shadow, bitmap);
10117836SJohn.Forte@Sun.COM } else {
10127836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("ndr_ii set "
10137836SJohn.Forte@Sun.COM "%s %s %s has been configured."),
10147836SJohn.Forte@Sun.COM master, shadow, bitmap);
10157836SJohn.Forte@Sun.COM }
10167836SJohn.Forte@Sun.COM
10177836SJohn.Forte@Sun.COM /*
10187836SJohn.Forte@Sun.COM * Prior to insertion in ndr_ii entry, if in a Sun Cluster
10197836SJohn.Forte@Sun.COM * assure device groups are the same and cluster tag is set
10207836SJohn.Forte@Sun.COM */
10217836SJohn.Forte@Sun.COM if (clustered && !rdc_islocal) {
10227836SJohn.Forte@Sun.COM char mst_dg[NSC_MAXPATH] = {0};
10237836SJohn.Forte@Sun.COM char shd_dg[NSC_MAXPATH] = {0};
10247836SJohn.Forte@Sun.COM char bmp_dg[NSC_MAXPATH] = {0};
10257836SJohn.Forte@Sun.COM
10267836SJohn.Forte@Sun.COM if (!(cfg_dgname(master, mst_dg, sizeof (mst_dg)) &&
10277836SJohn.Forte@Sun.COM cfg_dgname(shadow, shd_dg, sizeof (shd_dg)) &&
10287836SJohn.Forte@Sun.COM cfg_dgname(bitmap, bmp_dg, sizeof (bmp_dg))))
10297836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("ndr_ii: %s %s %s are "
10307836SJohn.Forte@Sun.COM "not in a device group"),
10317836SJohn.Forte@Sun.COM master, shadow, bitmap);
10327836SJohn.Forte@Sun.COM else if (strcmp(mst_dg, bmp_dg) ||
10337836SJohn.Forte@Sun.COM strcmp(mst_dg, shd_dg))
10347836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("ndr_ii: %s %s %s are "
10357836SJohn.Forte@Sun.COM "not in different device groups"),
10367836SJohn.Forte@Sun.COM master, shadow, bitmap);
10377836SJohn.Forte@Sun.COM else {
10387836SJohn.Forte@Sun.COM cfg_resource(cfg, shd_dg);
10397836SJohn.Forte@Sun.COM (void) snprintf(buf, sizeof (buf),
10407836SJohn.Forte@Sun.COM "%s %s %s update %s",
10417836SJohn.Forte@Sun.COM master, shadow, bitmap, shd_dg);
10427836SJohn.Forte@Sun.COM }
10437836SJohn.Forte@Sun.COM } else {
10447836SJohn.Forte@Sun.COM (void) snprintf(buf, sizeof (buf), "%s %s %s update",
10457836SJohn.Forte@Sun.COM master, shadow, bitmap);
10467836SJohn.Forte@Sun.COM }
10477836SJohn.Forte@Sun.COM
10487836SJohn.Forte@Sun.COM if ((cfg_put_cstring(cfg, "ndr_ii", buf, strlen(buf)) < 0) ||
10497836SJohn.Forte@Sun.COM (cfg_commit(cfg) < 0))
10507836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("unable to add \"%s\" to "
10517836SJohn.Forte@Sun.COM "configuration storage: %s"),
10527836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
10537836SJohn.Forte@Sun.COM
10547836SJohn.Forte@Sun.COM cfg_close(cfg);
10557836SJohn.Forte@Sun.COM
10567836SJohn.Forte@Sun.COM break;
10577836SJohn.Forte@Sun.COM
10587836SJohn.Forte@Sun.COM default:
10597836SJohn.Forte@Sun.COM usage();
10607836SJohn.Forte@Sun.COM exit(1);
10617836SJohn.Forte@Sun.COM }
10627836SJohn.Forte@Sun.COM }
10637836SJohn.Forte@Sun.COM
10647836SJohn.Forte@Sun.COM void
check_rdcbitmap(int cmd,char * hostp,char * bmp)10657836SJohn.Forte@Sun.COM check_rdcbitmap(int cmd, char *hostp, char *bmp)
10667836SJohn.Forte@Sun.COM {
10677836SJohn.Forte@Sun.COM int i;
10687836SJohn.Forte@Sun.COM CFGFILE *cfg;
10697836SJohn.Forte@Sun.COM int entries;
10707836SJohn.Forte@Sun.COM char **entry;
10717836SJohn.Forte@Sun.COM char *host, *pri, *sec, *sbm, *bit, *mas, *sha, *ovr;
10727836SJohn.Forte@Sun.COM char *shost, *buf, *que;
10737836SJohn.Forte@Sun.COM
10747836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
10757836SJohn.Forte@Sun.COM rdc_err(NULL,
10767836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
10777836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
10787836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
10797836SJohn.Forte@Sun.COM
10807836SJohn.Forte@Sun.COM /*
10817836SJohn.Forte@Sun.COM * look into II config to see if this is being used elsewhere
10827836SJohn.Forte@Sun.COM */
10837836SJohn.Forte@Sun.COM entry = NULL;
10847836SJohn.Forte@Sun.COM entries = cfg_get_section(cfg, &entry, "ii");
10857836SJohn.Forte@Sun.COM for (i = 0; i < entries; i++) {
10867836SJohn.Forte@Sun.COM buf = entry[i];
10877836SJohn.Forte@Sun.COM
10887836SJohn.Forte@Sun.COM mas = strtok(buf, " "); /* master */
10897836SJohn.Forte@Sun.COM sha = strtok(NULL, " "); /* shadow */
10907836SJohn.Forte@Sun.COM bit = strtok(NULL, " "); /* bitmap */
10917836SJohn.Forte@Sun.COM (void) strtok(NULL, " "); /* mode */
10927836SJohn.Forte@Sun.COM ovr = strtok(NULL, " "); /* overflow */
10937836SJohn.Forte@Sun.COM
10947836SJohn.Forte@Sun.COM /*
10957836SJohn.Forte@Sun.COM * got master, shadow, overflow, and bitmap, now compare
10967836SJohn.Forte@Sun.COM */
10977836SJohn.Forte@Sun.COM if ((strcmp(bmp, mas) == 0) ||
10987836SJohn.Forte@Sun.COM (strcmp(bmp, sha) == 0) ||
10997836SJohn.Forte@Sun.COM (strcmp(bmp, ovr) == 0) ||
11007836SJohn.Forte@Sun.COM (strcmp(bmp, bit) == 0)) {
11017836SJohn.Forte@Sun.COM rdc_err(NULL,
11027836SJohn.Forte@Sun.COM gettext("bitmap %s is in use by"
11037836SJohn.Forte@Sun.COM " Point-in-Time Copy"), bmp);
11047836SJohn.Forte@Sun.COM }
11057836SJohn.Forte@Sun.COM free(buf);
11067836SJohn.Forte@Sun.COM }
11077836SJohn.Forte@Sun.COM if (entries)
11087836SJohn.Forte@Sun.COM free(entry);
11097836SJohn.Forte@Sun.COM
11107836SJohn.Forte@Sun.COM
11117836SJohn.Forte@Sun.COM /*
11127836SJohn.Forte@Sun.COM * and last but not least, make sure sndr is not using vol for anything
11137836SJohn.Forte@Sun.COM */
11147836SJohn.Forte@Sun.COM entry = NULL;
11157836SJohn.Forte@Sun.COM entries = cfg_get_section(cfg, &entry, "sndr");
11167836SJohn.Forte@Sun.COM for (i = 0; i < entries; i++) {
11177836SJohn.Forte@Sun.COM buf = entry[i];
11187836SJohn.Forte@Sun.COM
11197836SJohn.Forte@Sun.COM /*
11207836SJohn.Forte@Sun.COM * I think this is quicker than
11217836SJohn.Forte@Sun.COM * having to double dip into the config
11227836SJohn.Forte@Sun.COM */
11237836SJohn.Forte@Sun.COM host = strtok(buf, " "); /* phost */
11247836SJohn.Forte@Sun.COM pri = strtok(NULL, " "); /* primary */
11257836SJohn.Forte@Sun.COM bit = strtok(NULL, " "); /* pbitmap */
11267836SJohn.Forte@Sun.COM shost = strtok(NULL, " "); /* shost */
11277836SJohn.Forte@Sun.COM sec = strtok(NULL, " "); /* secondary */
11287836SJohn.Forte@Sun.COM sbm = strtok(NULL, " "); /* sbitmap */
11297836SJohn.Forte@Sun.COM (void) strtok(NULL, " "); /* type */
11307836SJohn.Forte@Sun.COM (void) strtok(NULL, " "); /* mode */
11317836SJohn.Forte@Sun.COM (void) strtok(NULL, " "); /* group */
11327836SJohn.Forte@Sun.COM (void) strtok(NULL, " "); /* cnode */
11337836SJohn.Forte@Sun.COM (void) strtok(NULL, " "); /* options */
11347836SJohn.Forte@Sun.COM que = strtok(NULL, " "); /* diskq */
11357836SJohn.Forte@Sun.COM
11367836SJohn.Forte@Sun.COM if (cmd == RDC_CMD_ENABLE) {
11377836SJohn.Forte@Sun.COM if (self_check(host)) {
11387836SJohn.Forte@Sun.COM if ((strcmp(bmp, pri) == 0) ||
11397836SJohn.Forte@Sun.COM (strcmp(bmp, que) == 0) ||
11407836SJohn.Forte@Sun.COM (strcmp(bmp, bit) == 0)) {
11417836SJohn.Forte@Sun.COM rdc_err(NULL,
11427836SJohn.Forte@Sun.COM gettext("bitmap %s is already "
11437836SJohn.Forte@Sun.COM "in use by StorEdge Network Data "
11447836SJohn.Forte@Sun.COM "Replicator"), bmp);
11457836SJohn.Forte@Sun.COM }
11467836SJohn.Forte@Sun.COM } else {
11477836SJohn.Forte@Sun.COM if ((strcmp(bmp, sec) == 0) ||
11487836SJohn.Forte@Sun.COM (strcmp(bmp, sbm) == 0)) {
11497836SJohn.Forte@Sun.COM rdc_err(NULL,
11507836SJohn.Forte@Sun.COM gettext("bitmap %s is already "
11517836SJohn.Forte@Sun.COM "in use by StorEdge Network Data "
11527836SJohn.Forte@Sun.COM "Replicator"), bmp);
11537836SJohn.Forte@Sun.COM }
11547836SJohn.Forte@Sun.COM }
11557836SJohn.Forte@Sun.COM } else if (cmd == RDC_CMD_RECONFIG) {
11567836SJohn.Forte@Sun.COM
11577836SJohn.Forte@Sun.COM /*
11587836SJohn.Forte@Sun.COM * read this logic 1000 times and consider
11597836SJohn.Forte@Sun.COM * multi homed, one to many, many to one (marketing)
11607836SJohn.Forte@Sun.COM * etc, etc, before changing
11617836SJohn.Forte@Sun.COM */
11627836SJohn.Forte@Sun.COM if (self_check(hostp)) {
11637836SJohn.Forte@Sun.COM if (self_check(host)) {
11647836SJohn.Forte@Sun.COM if ((strcmp(bmp, pri) == 0) ||
11657836SJohn.Forte@Sun.COM (strcmp(bmp, que) == 0) ||
11667836SJohn.Forte@Sun.COM (strcmp(bmp, bit) == 0)) {
11677836SJohn.Forte@Sun.COM rdc_err(NULL,
11687836SJohn.Forte@Sun.COM gettext("bitmap %s is already "
11697836SJohn.Forte@Sun.COM "in use by StorEdge Network "
11707836SJohn.Forte@Sun.COM "Data Replicator"), bmp);
11717836SJohn.Forte@Sun.COM }
11727836SJohn.Forte@Sun.COM } else {
11737836SJohn.Forte@Sun.COM if ((strcmp(hostp, shost) == 0) &&
11747836SJohn.Forte@Sun.COM (strcmp(bmp, sec) == 0) ||
11757836SJohn.Forte@Sun.COM (strcmp(bmp, sbm) == 0)) {
11767836SJohn.Forte@Sun.COM rdc_err(NULL,
11777836SJohn.Forte@Sun.COM gettext("bitmap %s is already "
11787836SJohn.Forte@Sun.COM "in use by StorEdge Network "
11797836SJohn.Forte@Sun.COM "Data Replicator"), bmp);
11807836SJohn.Forte@Sun.COM
11817836SJohn.Forte@Sun.COM }
11827836SJohn.Forte@Sun.COM }
11837836SJohn.Forte@Sun.COM } else { /* self_check(hostp) failed */
11847836SJohn.Forte@Sun.COM if (self_check(host)) {
11857836SJohn.Forte@Sun.COM if ((strcmp(shost, hostp) == 0) &&
11867836SJohn.Forte@Sun.COM (strcmp(bmp, sec) == 0) ||
11877836SJohn.Forte@Sun.COM (strcmp(bmp, sbm) == 0)) {
11887836SJohn.Forte@Sun.COM rdc_err(NULL,
11897836SJohn.Forte@Sun.COM gettext("bitmap %s is already "
11907836SJohn.Forte@Sun.COM "in use by StorEdge Network "
11917836SJohn.Forte@Sun.COM "Data Replicator"), bmp);
11927836SJohn.Forte@Sun.COM }
11937836SJohn.Forte@Sun.COM } else {
11947836SJohn.Forte@Sun.COM if ((strcmp(host, hostp) == 0) &&
11957836SJohn.Forte@Sun.COM (strcmp(bmp, pri) == 0) ||
11967836SJohn.Forte@Sun.COM (strcmp(bmp, que) == 0) ||
11977836SJohn.Forte@Sun.COM (strcmp(bmp, bit) == 0)) {
11987836SJohn.Forte@Sun.COM rdc_err(NULL,
11997836SJohn.Forte@Sun.COM gettext("bitmap %s is already "
12007836SJohn.Forte@Sun.COM "in use by StorEdge Network "
12017836SJohn.Forte@Sun.COM "Data Replicator"), bmp);
12027836SJohn.Forte@Sun.COM }
12037836SJohn.Forte@Sun.COM }
12047836SJohn.Forte@Sun.COM }
12057836SJohn.Forte@Sun.COM
12067836SJohn.Forte@Sun.COM }
12077836SJohn.Forte@Sun.COM
12087836SJohn.Forte@Sun.COM free(buf);
12097836SJohn.Forte@Sun.COM }
12107836SJohn.Forte@Sun.COM cfg_close(cfg);
12117836SJohn.Forte@Sun.COM
12127836SJohn.Forte@Sun.COM if (entries)
12137836SJohn.Forte@Sun.COM free(entry);
12147836SJohn.Forte@Sun.COM }
12157836SJohn.Forte@Sun.COM int
check_intrange(char * arg)12167836SJohn.Forte@Sun.COM check_intrange(char *arg) {
12177836SJohn.Forte@Sun.COM int i;
12187836SJohn.Forte@Sun.COM
12197836SJohn.Forte@Sun.COM for (i = 0; i < strlen(arg); i++) {
12207836SJohn.Forte@Sun.COM if (arg[i] < '0' || arg[i] > '9') {
12217836SJohn.Forte@Sun.COM rdc_warn(NULL, "not a valid number, must be a "
12227836SJohn.Forte@Sun.COM "decimal between 1 and %d", MAXINT);
12237836SJohn.Forte@Sun.COM return (0);
12247836SJohn.Forte@Sun.COM }
12257836SJohn.Forte@Sun.COM }
12267836SJohn.Forte@Sun.COM errno = 0;
12277836SJohn.Forte@Sun.COM i = (int)strtol(arg, NULL, 10);
12287836SJohn.Forte@Sun.COM if ((errno) || (i < 1) || (i > MAXINT)) {
12297836SJohn.Forte@Sun.COM rdc_warn(NULL, "not a valid number, must be a decimal "
12307836SJohn.Forte@Sun.COM "between 1 and %d", MAXINT);
12317836SJohn.Forte@Sun.COM return (0);
12327836SJohn.Forte@Sun.COM }
12337836SJohn.Forte@Sun.COM return (1);
12347836SJohn.Forte@Sun.COM }
12357836SJohn.Forte@Sun.COM
12367836SJohn.Forte@Sun.COM void
rewrite_group_diskqueue(CFGFILE * cfg,_sd_dual_pair_t * pair,char * diskqueue)12377836SJohn.Forte@Sun.COM rewrite_group_diskqueue(CFGFILE *cfg, _sd_dual_pair_t *pair, char *diskqueue)
12387836SJohn.Forte@Sun.COM {
12397836SJohn.Forte@Sun.COM int set;
12407836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
12417836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
12427836SJohn.Forte@Sun.COM _sd_dual_pair_t tmpair;
12437836SJohn.Forte@Sun.COM
12447836SJohn.Forte@Sun.COM for (set = 1; /*CSTYLED*/; set++) {
12457836SJohn.Forte@Sun.COM bzero(buf, CFG_MAX_BUF);
12467836SJohn.Forte@Sun.COM bzero(&tmpair, sizeof (tmpair));
12477836SJohn.Forte@Sun.COM
12487836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d", set);
12497836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
12507836SJohn.Forte@Sun.COM break;
12517836SJohn.Forte@Sun.COM }
12527836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &tmpair, NULL))
12537836SJohn.Forte@Sun.COM continue;
12547836SJohn.Forte@Sun.COM if (pair->group && pair->group[0]) {
12557836SJohn.Forte@Sun.COM if (strcmp(pair->group, tmpair.group) != 0)
12567836SJohn.Forte@Sun.COM continue; /* not the group we want */
12577836SJohn.Forte@Sun.COM
12587836SJohn.Forte@Sun.COM } else { /* no group specified */
12597836SJohn.Forte@Sun.COM if (strcmp(pair->thost, tmpair.thost) != 0)
12607836SJohn.Forte@Sun.COM continue;
12617836SJohn.Forte@Sun.COM if (strcmp(pair->tfile, tmpair.tfile) != 0)
12627836SJohn.Forte@Sun.COM continue;
12637836SJohn.Forte@Sun.COM }
12647836SJohn.Forte@Sun.COM
12657836SJohn.Forte@Sun.COM (void) sprintf(key, "sndr.set%d.diskq", set);
12667836SJohn.Forte@Sun.COM
12677836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, diskqueue,
12687836SJohn.Forte@Sun.COM strlen(diskqueue)) < 0) {
12697836SJohn.Forte@Sun.COM perror(cfg_error(NULL));
12707836SJohn.Forte@Sun.COM }
12717836SJohn.Forte@Sun.COM }
12727836SJohn.Forte@Sun.COM }
12737836SJohn.Forte@Sun.COM
12747836SJohn.Forte@Sun.COM void
diskq_subcmd(int subcmd,char * qvol,char * group_arg,char * ctag_arg,char * tohost_arg,char * tofile_arg)12757836SJohn.Forte@Sun.COM diskq_subcmd(int subcmd, char *qvol, char *group_arg, char *ctag_arg,
12767836SJohn.Forte@Sun.COM char *tohost_arg, char *tofile_arg)
12777836SJohn.Forte@Sun.COM {
12787836SJohn.Forte@Sun.COM int found = 0;
12797836SJohn.Forte@Sun.COM int setnumber = 0;
12807836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
12817836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
12827836SJohn.Forte@Sun.COM int i;
12837836SJohn.Forte@Sun.COM int rc;
12847836SJohn.Forte@Sun.COM int option = 0;
12857836SJohn.Forte@Sun.COM _sd_dual_pair_t pair;
12867836SJohn.Forte@Sun.COM CFGFILE *cfg;
12877836SJohn.Forte@Sun.COM char *ctag = NULL;
12887836SJohn.Forte@Sun.COM int resourced = 0;
12897836SJohn.Forte@Sun.COM
12907836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
12917836SJohn.Forte@Sun.COM rdc_err(NULL,
12927836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
12937836SJohn.Forte@Sun.COM
12947836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK))
12957836SJohn.Forte@Sun.COM rdc_err(NULL,
12967836SJohn.Forte@Sun.COM gettext("unable to lock configuration"));
12977836SJohn.Forte@Sun.COM
12987836SJohn.Forte@Sun.COM redo:
12997836SJohn.Forte@Sun.COM if (cfg_load_svols(cfg) < 0 ||
13007836SJohn.Forte@Sun.COM cfg_load_dsvols(cfg) < 0 ||
13017836SJohn.Forte@Sun.COM cfg_load_shadows(cfg) < 0)
13027836SJohn.Forte@Sun.COM rdc_err(NULL,
13037836SJohn.Forte@Sun.COM gettext("Unable to parse config filer"));
13047836SJohn.Forte@Sun.COM load_rdc_vols(cfg);
13057836SJohn.Forte@Sun.COM
13067836SJohn.Forte@Sun.COM /*CSTYLED*/
13077836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets;) {
13087836SJohn.Forte@Sun.COM setnumber++;
13097836SJohn.Forte@Sun.COM
13107836SJohn.Forte@Sun.COM bzero(buf, CFG_MAX_BUF);
13117836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
13127836SJohn.Forte@Sun.COM "sndr.set%d", setnumber);
13137836SJohn.Forte@Sun.COM rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF);
13147836SJohn.Forte@Sun.COM if (rc < 0)
13157836SJohn.Forte@Sun.COM break;
13167836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &pair, NULL))
13177836SJohn.Forte@Sun.COM continue;
13187836SJohn.Forte@Sun.COM
13197836SJohn.Forte@Sun.COM if (strlen(group_arg) == 0) {
13207836SJohn.Forte@Sun.COM if (strcmp(tohost_arg, pair.thost) == 0 &&
13217836SJohn.Forte@Sun.COM strcmp(tofile_arg, pair.tfile) == 0) {
1322*11576SSurya.Prakki@Sun.COM (void) strcpy(group_arg, pair.group);
13237836SJohn.Forte@Sun.COM found = 1;
13247836SJohn.Forte@Sun.COM break;
13257836SJohn.Forte@Sun.COM }
13267836SJohn.Forte@Sun.COM
13277836SJohn.Forte@Sun.COM } else {
13287836SJohn.Forte@Sun.COM if (strcmp(group_arg, pair.group) == 0) {
13297836SJohn.Forte@Sun.COM found = 1;
13307836SJohn.Forte@Sun.COM break;
13317836SJohn.Forte@Sun.COM }
13327836SJohn.Forte@Sun.COM }
13337836SJohn.Forte@Sun.COM }
13347836SJohn.Forte@Sun.COM
13357836SJohn.Forte@Sun.COM if (!found) {
13367836SJohn.Forte@Sun.COM if (strlen(group_arg) == 0) {
13377836SJohn.Forte@Sun.COM rdc_err(NULL,
13387836SJohn.Forte@Sun.COM gettext("Unable to find %s:%s in "
13397836SJohn.Forte@Sun.COM "configuration storage"),
13407836SJohn.Forte@Sun.COM tohost_arg, tofile_arg);
13417836SJohn.Forte@Sun.COM } else {
13427836SJohn.Forte@Sun.COM rdc_err(NULL,
13437836SJohn.Forte@Sun.COM gettext("Unable to find group %s in "
13447836SJohn.Forte@Sun.COM "configuration storage"), group_arg);
13457836SJohn.Forte@Sun.COM }
13467836SJohn.Forte@Sun.COM }
13477836SJohn.Forte@Sun.COM if (!resourced && strlen(pair.ctag)) { /* uh-oh... */
13487836SJohn.Forte@Sun.COM cfg_unload_svols(cfg);
13497836SJohn.Forte@Sun.COM cfg_unload_dsvols(cfg);
13507836SJohn.Forte@Sun.COM cfg_unload_shadows(cfg);
13517836SJohn.Forte@Sun.COM unload_rdc_vols();
13527836SJohn.Forte@Sun.COM cfg_resource(cfg, pair.ctag);
13537836SJohn.Forte@Sun.COM ctag = strdup(pair.ctag);
13547836SJohn.Forte@Sun.COM resourced = 1;
13557836SJohn.Forte@Sun.COM setnumber = 0;
13567836SJohn.Forte@Sun.COM goto redo;
13577836SJohn.Forte@Sun.COM }
13587836SJohn.Forte@Sun.COM
13597836SJohn.Forte@Sun.COM if (clustered && !rdc_islocal) {
13607836SJohn.Forte@Sun.COM if (strcmp(ctag_arg, "") &&
13617836SJohn.Forte@Sun.COM strncmp(ctag_arg, pair.ctag, MAX_RDC_HOST_SIZE))
13627836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("ctags %s and %s "
13637836SJohn.Forte@Sun.COM "do not match, proceeding with operation based "
13647836SJohn.Forte@Sun.COM "on existing set information"), ctag_arg, ctag);
13657836SJohn.Forte@Sun.COM }
13667836SJohn.Forte@Sun.COM switch (subcmd) {
13677836SJohn.Forte@Sun.COM case RDC_CMD_ADDQ:
13687836SJohn.Forte@Sun.COM if (clustered && (ctag_check(pair.fhost, pair.ffile,
13697836SJohn.Forte@Sun.COM pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap,
13707836SJohn.Forte@Sun.COM pair.ctag, qvol) < 0))
13717836SJohn.Forte@Sun.COM exit(1);
13727836SJohn.Forte@Sun.COM
13737836SJohn.Forte@Sun.COM if (strlen(pair.diskqueue) > 0) {
13747836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror set already "
13757836SJohn.Forte@Sun.COM "has a disk queue"));
13767836SJohn.Forte@Sun.COM }
13777836SJohn.Forte@Sun.COM if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) {
13787836SJohn.Forte@Sun.COM rdc_err(NULL,
13797836SJohn.Forte@Sun.COM gettext("diskqueue %s is incompatible"), qvol);
13807836SJohn.Forte@Sun.COM }
13817836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
13827836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
13837836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
13847836SJohn.Forte@Sun.COM 0) < 0) {
13857836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0)
13867836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove disk "
13877836SJohn.Forte@Sun.COM "queue [%s] from configuration"), qvol);
13887836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Add disk queue operation "
13897836SJohn.Forte@Sun.COM "failed"));
13907836SJohn.Forte@Sun.COM }
13917836SJohn.Forte@Sun.COM if (nsc_lookup(volhash, qvol) == NULL) {
13927836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) {
13937836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Add disk queue "
13947836SJohn.Forte@Sun.COM "operation failed"));
13957836SJohn.Forte@Sun.COM }
13967836SJohn.Forte@Sun.COM }
13977836SJohn.Forte@Sun.COM rewrite_group_diskqueue(cfg, &pair, qvol);
13987836SJohn.Forte@Sun.COM
13997836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: added "
14007836SJohn.Forte@Sun.COM "diskqueue %s to set %s:%s and its group"), qvol,
14017836SJohn.Forte@Sun.COM pair.thost, pair.tfile);
14027836SJohn.Forte@Sun.COM break;
14037836SJohn.Forte@Sun.COM case RDC_OPT_FORCE_QINIT:
14047836SJohn.Forte@Sun.COM if (strlen(pair.diskqueue) == 0) {
14057836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror set does not "
14067836SJohn.Forte@Sun.COM "have a disk queue"));
14077836SJohn.Forte@Sun.COM }
14087836SJohn.Forte@Sun.COM subcmd = RDC_CMD_INITQ;
14097836SJohn.Forte@Sun.COM option = RDC_OPT_FORCE_QINIT;
14107836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
14117836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, subcmd, option,
14127836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
14137836SJohn.Forte@Sun.COM 0) < 0) {
14147836SJohn.Forte@Sun.COM exit(1);
14157836SJohn.Forte@Sun.COM }
14167836SJohn.Forte@Sun.COM break;
14177836SJohn.Forte@Sun.COM case RDC_CMD_INITQ:
14187836SJohn.Forte@Sun.COM if (strlen(pair.diskqueue) == 0) {
14197836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror set does not "
14207836SJohn.Forte@Sun.COM "have a disk queue"));
14217836SJohn.Forte@Sun.COM }
14227836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
14237836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
14247836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
14257836SJohn.Forte@Sun.COM 0) < 0) {
14267836SJohn.Forte@Sun.COM exit(1);
14277836SJohn.Forte@Sun.COM }
14287836SJohn.Forte@Sun.COM break;
14297836SJohn.Forte@Sun.COM case RDC_CMD_REMQ:
14307836SJohn.Forte@Sun.COM if (strlen(pair.diskqueue) == 0) {
14317836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror set does not "
14327836SJohn.Forte@Sun.COM "have a disk queue"));
14337836SJohn.Forte@Sun.COM }
14347836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
14357836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
14367836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
14377836SJohn.Forte@Sun.COM 0) < 0) {
14387836SJohn.Forte@Sun.COM exit(1);
14397836SJohn.Forte@Sun.COM }
14407836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0)
14417836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove disk queue "
14427836SJohn.Forte@Sun.COM "[%s] from configuration"), pair.diskqueue);
14437836SJohn.Forte@Sun.COM rewrite_group_diskqueue(cfg, &pair, place_holder);
14447836SJohn.Forte@Sun.COM
14457836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: removed "
14467836SJohn.Forte@Sun.COM "diskqueue from set %s:%s and its group"), pair.thost,
14477836SJohn.Forte@Sun.COM pair.tfile);
14487836SJohn.Forte@Sun.COM break;
14497836SJohn.Forte@Sun.COM case RDC_CMD_KILLQ:
14507836SJohn.Forte@Sun.COM if (strlen(pair.diskqueue) == 0) {
14517836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror set does not "
14527836SJohn.Forte@Sun.COM "have a disk queue"));
14537836SJohn.Forte@Sun.COM }
14547836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
14557836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
14567836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
14577836SJohn.Forte@Sun.COM 0) < 0) {
14587836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Failed to remove disk queue"));
14597836SJohn.Forte@Sun.COM }
14607836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0)
14617836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove disk queue "
14627836SJohn.Forte@Sun.COM "[%s] from configuration"), pair.diskqueue);
14637836SJohn.Forte@Sun.COM
14647836SJohn.Forte@Sun.COM rewrite_group_diskqueue(cfg, &pair, place_holder);
14657836SJohn.Forte@Sun.COM
14667836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: forcibly "
14677836SJohn.Forte@Sun.COM "removed diskqueue from set %s:%s and its group "),
14687836SJohn.Forte@Sun.COM pair.thost, pair.tfile);
14697836SJohn.Forte@Sun.COM break;
14707836SJohn.Forte@Sun.COM case RDC_CMD_REPQ:
14717836SJohn.Forte@Sun.COM if (clustered && (ctag_check(pair.fhost, pair.ffile,
14727836SJohn.Forte@Sun.COM pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap,
14737836SJohn.Forte@Sun.COM pair.ctag, qvol) < 0))
14747836SJohn.Forte@Sun.COM exit(1);
14757836SJohn.Forte@Sun.COM
14767836SJohn.Forte@Sun.COM if (strlen(pair.diskqueue) == 0) {
14777836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror set does not "
14787836SJohn.Forte@Sun.COM "have a disk queue"));
14797836SJohn.Forte@Sun.COM }
14807836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
14817836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_REMQ, 0,
14827836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
14837836SJohn.Forte@Sun.COM 0) < 0) {
14847836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Failed to remove disk queue"));
14857836SJohn.Forte@Sun.COM }
14867836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0)
14877836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove disk queue "
14887836SJohn.Forte@Sun.COM "[%s] from configuration"), pair.diskqueue);
14897836SJohn.Forte@Sun.COM
14907836SJohn.Forte@Sun.COM rewrite_group_diskqueue(cfg, &pair, place_holder);
14917836SJohn.Forte@Sun.COM
14927836SJohn.Forte@Sun.COM /* commit here, enable may fail */
14937836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0) {
14947836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("commit replace disk queue %s "
14957836SJohn.Forte@Sun.COM "with %s failed"), pair.diskqueue, qvol);
14967836SJohn.Forte@Sun.COM }
14977836SJohn.Forte@Sun.COM
14987836SJohn.Forte@Sun.COM if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) {
14997836SJohn.Forte@Sun.COM rdc_err(NULL,
15007836SJohn.Forte@Sun.COM gettext("cannot replace disk queue %s with %s"),
15017836SJohn.Forte@Sun.COM pair.diskqueue, qvol);
15027836SJohn.Forte@Sun.COM }
15037836SJohn.Forte@Sun.COM if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
15047836SJohn.Forte@Sun.COM pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_ADDQ, 0,
15057836SJohn.Forte@Sun.COM pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
15067836SJohn.Forte@Sun.COM 0) < 0) {
15077836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0)
15087836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove disk "
15097836SJohn.Forte@Sun.COM "queue [%s] from configuration"), qvol);
15107836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Failed to add new disk queue"));
15117836SJohn.Forte@Sun.COM }
15127836SJohn.Forte@Sun.COM if (nsc_lookup(volhash, qvol) == NULL)
15137836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) {
15147836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Replace disk queue "
15157836SJohn.Forte@Sun.COM "operation failed"));
15167836SJohn.Forte@Sun.COM }
15177836SJohn.Forte@Sun.COM
15187836SJohn.Forte@Sun.COM rewrite_group_diskqueue(cfg, &pair, qvol);
15197836SJohn.Forte@Sun.COM
15207836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: replaced "
15217836SJohn.Forte@Sun.COM "diskqueue for set %s:%s and its group with %s"),
15227836SJohn.Forte@Sun.COM pair.thost, pair.tfile, qvol);
15237836SJohn.Forte@Sun.COM break;
15247836SJohn.Forte@Sun.COM }
15257836SJohn.Forte@Sun.COM
15267836SJohn.Forte@Sun.COM cfg_unload_svols(cfg);
15277836SJohn.Forte@Sun.COM cfg_unload_dsvols(cfg);
15287836SJohn.Forte@Sun.COM cfg_unload_shadows(cfg);
15297836SJohn.Forte@Sun.COM unload_rdc_vols();
15307836SJohn.Forte@Sun.COM
15317836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0)
15327836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("commit failed on disk queue operation"));
15337836SJohn.Forte@Sun.COM
15347836SJohn.Forte@Sun.COM cfg_close(cfg);
15357836SJohn.Forte@Sun.COM if (ctag)
15367836SJohn.Forte@Sun.COM free(ctag);
15377836SJohn.Forte@Sun.COM }
15387836SJohn.Forte@Sun.COM void
spcslog_sync(rdcconfig_t * sets,int start,int type)15397836SJohn.Forte@Sun.COM spcslog_sync(rdcconfig_t *sets, int start, int type)
15407836SJohn.Forte@Sun.COM {
15417836SJohn.Forte@Sun.COM rdcconfig_t *setp = sets;
15427836SJohn.Forte@Sun.COM
15437836SJohn.Forte@Sun.COM while (setp) {
15447836SJohn.Forte@Sun.COM if (start) {
15457836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
15467836SJohn.Forte@Sun.COM gettext("%s %s %s %s %s %s %s %s\nSync Started"),
15477836SJohn.Forte@Sun.COM program, rdc_decode_flag(RDC_CMD_COPY, type),
15487836SJohn.Forte@Sun.COM setp->phost, setp->pfile, setp->pbmp,
15497836SJohn.Forte@Sun.COM setp->shost, setp->sfile, setp->sbmp);
15507836SJohn.Forte@Sun.COM } else {
15517836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
15527836SJohn.Forte@Sun.COM gettext("%s %s %s %s %s %s %s %s\nSync Ended"),
15537836SJohn.Forte@Sun.COM program, rdc_decode_flag(RDC_CMD_COPY, type),
15547836SJohn.Forte@Sun.COM setp->phost, setp->pfile, setp->pbmp,
15557836SJohn.Forte@Sun.COM setp->shost, setp->sfile, setp->sbmp);
15567836SJohn.Forte@Sun.COM }
15577836SJohn.Forte@Sun.COM setp = setp->next;
15587836SJohn.Forte@Sun.COM }
15597836SJohn.Forte@Sun.COM }
15607836SJohn.Forte@Sun.COM
15617836SJohn.Forte@Sun.COM void
spcslog_tunable(char * shost,char * svol)15627836SJohn.Forte@Sun.COM spcslog_tunable(char *shost, char *svol)
15637836SJohn.Forte@Sun.COM {
15647836SJohn.Forte@Sun.COM if (qblock == RDC_OPT_SET_QNOBLOCK)
15657836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("diskqueue "
15667836SJohn.Forte@Sun.COM "set to non blocking for %s:%s and any members "
15677836SJohn.Forte@Sun.COM "of it's group"), shost, svol);
15687836SJohn.Forte@Sun.COM else if (qblock == RDC_OPT_CLR_QNOBLOCK)
15697836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("diskqueue "
15707836SJohn.Forte@Sun.COM "set to blocking for %s:%s and any members "
15717836SJohn.Forte@Sun.COM "of it's group"), shost, svol);
15727836SJohn.Forte@Sun.COM
15737836SJohn.Forte@Sun.COM if (maxqfbas)
15747836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("maxqfbas set to %d for %s:%s"),
15757836SJohn.Forte@Sun.COM maxqfbas, shost, svol);
15767836SJohn.Forte@Sun.COM if (maxqitems)
15777836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("maxwrites set to %d for %s:%s"),
15787836SJohn.Forte@Sun.COM maxqitems, shost, svol);
15797836SJohn.Forte@Sun.COM if (asyncthr)
15807836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("%d async threads configured "
15817836SJohn.Forte@Sun.COM "for %s:%s"), asyncthr, shost, svol);
15827836SJohn.Forte@Sun.COM }
15837836SJohn.Forte@Sun.COM
15847836SJohn.Forte@Sun.COM int
set_qblock(char * blockarg)15857836SJohn.Forte@Sun.COM set_qblock(char *blockarg)
15867836SJohn.Forte@Sun.COM {
15877836SJohn.Forte@Sun.COM if (strcmp(blockarg, "block") == 0)
15887836SJohn.Forte@Sun.COM qblock = RDC_OPT_CLR_QNOBLOCK;
15897836SJohn.Forte@Sun.COM else if (strcmp(blockarg, "noblock") == 0)
15907836SJohn.Forte@Sun.COM qblock = RDC_OPT_SET_QNOBLOCK;
15917836SJohn.Forte@Sun.COM else
15927836SJohn.Forte@Sun.COM return (1);
15937836SJohn.Forte@Sun.COM
15947836SJohn.Forte@Sun.COM return (0);
15957836SJohn.Forte@Sun.COM }
15967836SJohn.Forte@Sun.COM
15977836SJohn.Forte@Sun.COM static void
rdc_force_disable(CFGFILE * cfg,char * phost,char * pvol,char * pbmp,char * shost,char * svol,char * sbmp,char * ctag,char * lhname)15987836SJohn.Forte@Sun.COM rdc_force_disable(CFGFILE *cfg, char *phost, char *pvol, char *pbmp,
15997836SJohn.Forte@Sun.COM char *shost, char *svol, char *sbmp, char *ctag, char *lhname)
16007836SJohn.Forte@Sun.COM {
16017836SJohn.Forte@Sun.COM rdc_config_t parms;
16027836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
16037836SJohn.Forte@Sun.COM volcount_t *vc;
16047836SJohn.Forte@Sun.COM char *datavol = NULL;
16057836SJohn.Forte@Sun.COM char *bmpvol = NULL;
16067836SJohn.Forte@Sun.COM int on_pri = 0;
16077836SJohn.Forte@Sun.COM int on_sec = 0;
16087836SJohn.Forte@Sun.COM
16097836SJohn.Forte@Sun.COM /* are we on the primary or secondary host? */
16107836SJohn.Forte@Sun.COM if (ctag && *ctag && *lhname) {
16117836SJohn.Forte@Sun.COM if (strcmp(phost, lhname) == 0) {
16127836SJohn.Forte@Sun.COM on_pri = 1;
16137836SJohn.Forte@Sun.COM } else if (strcmp(shost, lhname) == 0) {
16147836SJohn.Forte@Sun.COM on_sec = 1;
16157836SJohn.Forte@Sun.COM }
16167836SJohn.Forte@Sun.COM } else if (self_check(phost)) {
16177836SJohn.Forte@Sun.COM on_pri = 1;
16187836SJohn.Forte@Sun.COM } else if (self_check(shost)) {
16197836SJohn.Forte@Sun.COM on_sec = 1;
16207836SJohn.Forte@Sun.COM }
16217836SJohn.Forte@Sun.COM
16227836SJohn.Forte@Sun.COM if (on_pri) {
16237836SJohn.Forte@Sun.COM datavol = pvol;
16247836SJohn.Forte@Sun.COM bmpvol = pbmp;
16257836SJohn.Forte@Sun.COM } else if (on_sec) {
16267836SJohn.Forte@Sun.COM datavol = svol;
16277836SJohn.Forte@Sun.COM bmpvol = sbmp;
16287836SJohn.Forte@Sun.COM } else {
16297836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Unable to determine whether current "
16307836SJohn.Forte@Sun.COM "node is primary or secondary"));
16317836SJohn.Forte@Sun.COM }
16327836SJohn.Forte@Sun.COM
16337836SJohn.Forte@Sun.COM /* set up parms structure */
16347836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
1635*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.intf, phost, MAX_RDC_HOST_SIZE);
1636*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.file, pvol, NSC_MAXPATH);
1637*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.intf, shost, MAX_RDC_HOST_SIZE);
1638*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.file, svol, NSC_MAXPATH);
16397836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
16407836SJohn.Forte@Sun.COM parms.options = RDC_OPT_FORCE_DISABLE;
16417836SJohn.Forte@Sun.COM
16427836SJohn.Forte@Sun.COM /*
16437836SJohn.Forte@Sun.COM * We are now going to 'force' the kernel to disable the set. By
16447836SJohn.Forte@Sun.COM * setting the RDC_OPT_FORCE_DISABLE flag, the kernel will bypass some
16457836SJohn.Forte@Sun.COM * of the checks that are normally done when attempting to disable
16467836SJohn.Forte@Sun.COM * a set. We need to do this force option in a cluster environment
16477836SJohn.Forte@Sun.COM * when the logical hostname for the primary or secondary volume
16487836SJohn.Forte@Sun.COM * is no longer available.
16497836SJohn.Forte@Sun.COM */
16507836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, "%s sndradm -d %s %s %s %s %s %s",
16517836SJohn.Forte@Sun.COM gettext("FORCE DISABLE"), phost, pvol, pbmp, shost, svol, sbmp);
16527836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Forcing set disable"));
16537836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_CONFIG, &parms, 0, 0, 0, 0, ustatus) != SPCS_S_OK)
16547836SJohn.Forte@Sun.COM rdc_warn(&ustatus, gettext("set %s:%s not enabled in kernel"),
16557836SJohn.Forte@Sun.COM shost, svol);
16567836SJohn.Forte@Sun.COM
16577836SJohn.Forte@Sun.COM /* if we get to this point, then a set was disabled. try sv-disable */
16587836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, datavol);
16597836SJohn.Forte@Sun.COM if (vc && (1 == vc->count))
16607836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, datavol, ctag, "sndr") < 0)
16617836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove data volume "
16627836SJohn.Forte@Sun.COM "[%s] from configuration"), datavol);
16637836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, bmpvol);
16647836SJohn.Forte@Sun.COM if (vc && (1 == vc->count))
16657836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, bmpvol, ctag, "sndr") < 0)
16667836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to remove bitmap "
16677836SJohn.Forte@Sun.COM "[%s] from configuration"), bmpvol);
16687836SJohn.Forte@Sun.COM }
16697836SJohn.Forte@Sun.COM
16707836SJohn.Forte@Sun.COM void
check_rdcsecondary(char * secondary)16717836SJohn.Forte@Sun.COM check_rdcsecondary(char *secondary)
16727836SJohn.Forte@Sun.COM {
16737836SJohn.Forte@Sun.COM int i;
16747836SJohn.Forte@Sun.COM CFGFILE *cfg;
16757836SJohn.Forte@Sun.COM int entries;
16767836SJohn.Forte@Sun.COM char **entry;
16777836SJohn.Forte@Sun.COM char *sha;
16787836SJohn.Forte@Sun.COM char *buf;
16797836SJohn.Forte@Sun.COM
16807836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
16817836SJohn.Forte@Sun.COM rdc_err(NULL,
16827836SJohn.Forte@Sun.COM gettext("error opening config"));
16837836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
16847836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("error locking config"));
16857836SJohn.Forte@Sun.COM
16867836SJohn.Forte@Sun.COM entry = NULL;
16877836SJohn.Forte@Sun.COM entries = cfg_get_section(cfg, &entry, "ii");
16887836SJohn.Forte@Sun.COM for (i = 0; i < entries; i++) {
16897836SJohn.Forte@Sun.COM buf = entry[i];
16907836SJohn.Forte@Sun.COM
16917836SJohn.Forte@Sun.COM (void) strtok(buf, " "); /* master */
16927836SJohn.Forte@Sun.COM sha = strtok(NULL, " "); /* shadow */
16937836SJohn.Forte@Sun.COM if (strcmp(secondary, sha) == 0) {
16947836SJohn.Forte@Sun.COM rdc_err(NULL,
16957836SJohn.Forte@Sun.COM gettext("secondary %s is in use by"
16967836SJohn.Forte@Sun.COM " Point-in-Time Copy"), secondary);
16977836SJohn.Forte@Sun.COM }
16987836SJohn.Forte@Sun.COM free(buf);
16997836SJohn.Forte@Sun.COM }
17007836SJohn.Forte@Sun.COM if (entries)
17017836SJohn.Forte@Sun.COM free(entry);
17027836SJohn.Forte@Sun.COM cfg_close(cfg);
17037836SJohn.Forte@Sun.COM }
17047836SJohn.Forte@Sun.COM
17057836SJohn.Forte@Sun.COM int
main(int argc,char * argv[])17067836SJohn.Forte@Sun.COM main(int argc, char *argv[])
17077836SJohn.Forte@Sun.COM {
17087836SJohn.Forte@Sun.COM char config_file[FILENAME_MAX];
17097836SJohn.Forte@Sun.COM char fromhost[MAX_RDC_HOST_SIZE];
17107836SJohn.Forte@Sun.COM char tohost[MAX_RDC_HOST_SIZE];
17117836SJohn.Forte@Sun.COM char fromfile[NSC_MAXPATH];
17127836SJohn.Forte@Sun.COM char tofile[NSC_MAXPATH];
17137836SJohn.Forte@Sun.COM char frombitmap[NSC_MAXPATH];
17147836SJohn.Forte@Sun.COM char tobitmap[NSC_MAXPATH];
17157836SJohn.Forte@Sun.COM char directfile[NSC_MAXPATH];
17167836SJohn.Forte@Sun.COM char group[NSC_MAXPATH];
17177836SJohn.Forte@Sun.COM char ctag[MAX_RDC_HOST_SIZE];
17187836SJohn.Forte@Sun.COM char options_cfg[CFG_MAX_BUF];
17197836SJohn.Forte@Sun.COM char fromnetaddr[RDC_MAXADDR];
17207836SJohn.Forte@Sun.COM char tonetaddr[RDC_MAXADDR];
17217836SJohn.Forte@Sun.COM char tmphost[MAX_RDC_HOST_SIZE];
17227836SJohn.Forte@Sun.COM char tmpfile[NSC_MAXPATH];
17237836SJohn.Forte@Sun.COM char tmpbitmap[NSC_MAXPATH];
17247836SJohn.Forte@Sun.COM char diskqueue[NSC_MAXPATH];
17257836SJohn.Forte@Sun.COM char lhname[MAX_RDC_HOST_SIZE];
17267836SJohn.Forte@Sun.COM char mode[16];
17277836SJohn.Forte@Sun.COM rdc_version_t rdc_version;
17287836SJohn.Forte@Sun.COM int pairs;
17297836SJohn.Forte@Sun.COM int pid;
17307836SJohn.Forte@Sun.COM int flag = 0;
17317836SJohn.Forte@Sun.COM int fflag = 0;
17327836SJohn.Forte@Sun.COM int reverse = 0;
17337836SJohn.Forte@Sun.COM int nflag = 0;
17347836SJohn.Forte@Sun.COM int iflag = 0;
17357836SJohn.Forte@Sun.COM int doasync;
17367836SJohn.Forte@Sun.COM int pflag = 0;
17377836SJohn.Forte@Sun.COM int vflag = 0;
17387836SJohn.Forte@Sun.COM int verbose = 0;
17397836SJohn.Forte@Sun.COM int errflag = 0;
17407836SJohn.Forte@Sun.COM int cfgflag = 0;
17417836SJohn.Forte@Sun.COM int cfg_success;
17427836SJohn.Forte@Sun.COM int Iflag = 0;
17437836SJohn.Forte@Sun.COM char c;
17447836SJohn.Forte@Sun.COM char inval = 0;
17457836SJohn.Forte@Sun.COM int found;
17467836SJohn.Forte@Sun.COM int rc;
17477836SJohn.Forte@Sun.COM int geflag = 0;
17487836SJohn.Forte@Sun.COM int qflag = 0;
17497836SJohn.Forte@Sun.COM char *qarg;
17507836SJohn.Forte@Sun.COM int Bflag = 0;
17517836SJohn.Forte@Sun.COM char *bitfile;
17527836SJohn.Forte@Sun.COM CFGFILE *cfg = NULL;
17537836SJohn.Forte@Sun.COM int i;
17547836SJohn.Forte@Sun.COM int setnumber;
17557836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
17567836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
17577836SJohn.Forte@Sun.COM char ctag_arg[MAX_RDC_HOST_SIZE];
17587836SJohn.Forte@Sun.COM char group_arg[NSC_MAXPATH];
17597836SJohn.Forte@Sun.COM int file_format = 0;
17607836SJohn.Forte@Sun.COM int sev;
17617836SJohn.Forte@Sun.COM int diskq_group = DISKQ_OKAY;
17627836SJohn.Forte@Sun.COM int extra_argc;
17637836SJohn.Forte@Sun.COM char *ctag_p, *group_p, *diskqueue_p;
17647836SJohn.Forte@Sun.COM char *required;
17657836SJohn.Forte@Sun.COM char *role_env;
17667836SJohn.Forte@Sun.COM int checksetfields = -1;
17677836SJohn.Forte@Sun.COM nsc_off_t boffset = 0;
17687836SJohn.Forte@Sun.COM int oflag = 0;
17697836SJohn.Forte@Sun.COM rdcconfig_t *sets = NULL;
17707836SJohn.Forte@Sun.COM rdcconfig_t *sets_p = NULL;
17717836SJohn.Forte@Sun.COM rdc_rc_t *rclist = NULL;
17727836SJohn.Forte@Sun.COM rdc_rc_t *rcp = NULL;
17737836SJohn.Forte@Sun.COM int host_not_found = 0;
17747836SJohn.Forte@Sun.COM
17757836SJohn.Forte@Sun.COM (void) setlocale(LC_ALL, "");
17767836SJohn.Forte@Sun.COM (void) textdomain("rdc");
17777836SJohn.Forte@Sun.COM role_env = getenv("SNDR_ROLE_REVERSE");
17787836SJohn.Forte@Sun.COM if (role_env && strcmp(role_env, "sndr_allow_reverse") == 0)
17797836SJohn.Forte@Sun.COM allow_role = 1;
17807836SJohn.Forte@Sun.COM
17817836SJohn.Forte@Sun.COM program = basename(argv[0]);
17827836SJohn.Forte@Sun.COM
17837836SJohn.Forte@Sun.COM rc = rdc_check_release(&required);
17847836SJohn.Forte@Sun.COM if (rc < 0) {
17857836SJohn.Forte@Sun.COM rdc_err(NULL,
17867836SJohn.Forte@Sun.COM gettext("unable to determine the current "
17877836SJohn.Forte@Sun.COM "Solaris release: %s\n"), strerror(errno));
17887836SJohn.Forte@Sun.COM } else if (rc == FALSE) {
17897836SJohn.Forte@Sun.COM rdc_err(NULL,
17907836SJohn.Forte@Sun.COM gettext("incorrect Solaris release (requires %s)\n"),
17917836SJohn.Forte@Sun.COM required);
17927836SJohn.Forte@Sun.COM }
17937836SJohn.Forte@Sun.COM
17947836SJohn.Forte@Sun.COM if ((clustered = cfg_iscluster()) < 0) {
17957836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to ascertain environment"));
17967836SJohn.Forte@Sun.COM }
17977836SJohn.Forte@Sun.COM
1798*11576SSurya.Prakki@Sun.COM (void) strcpy(ctag_arg, "");
1799*11576SSurya.Prakki@Sun.COM (void) strcpy(group_arg, "");
18007836SJohn.Forte@Sun.COM bzero(ctag, MAX_RDC_HOST_SIZE);
18017836SJohn.Forte@Sun.COM bzero(reconfig_ctag, MAX_RDC_HOST_SIZE);
18027836SJohn.Forte@Sun.COM bzero(diskqueue, NSC_MAXPATH);
18037836SJohn.Forte@Sun.COM
18047836SJohn.Forte@Sun.COM rdc_maxsets = rdc_get_maxsets();
18057836SJohn.Forte@Sun.COM if (rdc_maxsets == -1) {
18067836SJohn.Forte@Sun.COM rdc_err(NULL,
18077836SJohn.Forte@Sun.COM gettext("unable to get maxsets value from kernel"));
18087836SJohn.Forte@Sun.COM }
18097836SJohn.Forte@Sun.COM
18107836SJohn.Forte@Sun.COM pair_list = calloc(rdc_maxsets, sizeof (*pair_list));
18117836SJohn.Forte@Sun.COM if (pair_list == NULL) {
18127836SJohn.Forte@Sun.COM rdc_err(NULL,
18137836SJohn.Forte@Sun.COM gettext("unable to allocate pair_list array for %d sets"),
18147836SJohn.Forte@Sun.COM rdc_maxsets);
18157836SJohn.Forte@Sun.COM }
18167836SJohn.Forte@Sun.COM
18177836SJohn.Forte@Sun.COM bzero(group, sizeof (group));
18187836SJohn.Forte@Sun.COM bzero(diskqueue, sizeof (diskqueue));
18197836SJohn.Forte@Sun.COM qblock = 0;
18207836SJohn.Forte@Sun.COM
18217836SJohn.Forte@Sun.COM while ((c =
18227836SJohn.Forte@Sun.COM #ifdef DEBUG
18237836SJohn.Forte@Sun.COM getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw"))
18247836SJohn.Forte@Sun.COM #else
18257836SJohn.Forte@Sun.COM getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw"))
18267836SJohn.Forte@Sun.COM #endif
18277836SJohn.Forte@Sun.COM != -1) {
18287836SJohn.Forte@Sun.COM switch (c) {
18297836SJohn.Forte@Sun.COM case 'B':
18307836SJohn.Forte@Sun.COM if (!allow_role || flag) {
18317836SJohn.Forte@Sun.COM inval = 1;
18327836SJohn.Forte@Sun.COM break;
18337836SJohn.Forte@Sun.COM }
18347836SJohn.Forte@Sun.COM bitfile = optarg;
18357836SJohn.Forte@Sun.COM Bflag = 1;
18367836SJohn.Forte@Sun.COM flag = RDC_BITMAPOP;
18377836SJohn.Forte@Sun.COM break;
18387836SJohn.Forte@Sun.COM case 'H':
18397836SJohn.Forte@Sun.COM /* 'h' was already assigned */
18407836SJohn.Forte@Sun.COM if (flag)
18417836SJohn.Forte@Sun.COM inval = 1;
18427836SJohn.Forte@Sun.COM flag = RDC_CMD_HEALTH;
18437836SJohn.Forte@Sun.COM break;
18447836SJohn.Forte@Sun.COM case 'I':
18457836SJohn.Forte@Sun.COM /* List or edit ndr_ii configuration entries */
18467836SJohn.Forte@Sun.COM Iflag = 1;
18477836SJohn.Forte@Sun.COM break;
18487836SJohn.Forte@Sun.COM case 'R':
18497836SJohn.Forte@Sun.COM if (flag)
18507836SJohn.Forte@Sun.COM inval = 1;
18517836SJohn.Forte@Sun.COM flag = RDC_CMD_RECONFIG;
18527836SJohn.Forte@Sun.COM break;
18537836SJohn.Forte@Sun.COM #ifdef DEBUG
18547836SJohn.Forte@Sun.COM case 'U': /* UDP support */
18557836SJohn.Forte@Sun.COM proto_test = 1;
18567836SJohn.Forte@Sun.COM break;
18577836SJohn.Forte@Sun.COM #endif
18587836SJohn.Forte@Sun.COM case 'F':
18597836SJohn.Forte@Sun.COM if (flag && flag != RDC_CMD_TUNABLE)
18607836SJohn.Forte@Sun.COM inval = 1;
18617836SJohn.Forte@Sun.COM flag = RDC_CMD_TUNABLE;
18627836SJohn.Forte@Sun.COM
18637836SJohn.Forte@Sun.COM if (check_intrange(optarg))
18647836SJohn.Forte@Sun.COM maxqfbas = atoi(optarg);
18657836SJohn.Forte@Sun.COM else
18667836SJohn.Forte@Sun.COM exit(1);
18677836SJohn.Forte@Sun.COM
18687836SJohn.Forte@Sun.COM break;
18697836SJohn.Forte@Sun.COM case 'W':
18707836SJohn.Forte@Sun.COM if (flag && flag != RDC_CMD_TUNABLE)
18717836SJohn.Forte@Sun.COM inval = 1;
18727836SJohn.Forte@Sun.COM flag = RDC_CMD_TUNABLE;
18737836SJohn.Forte@Sun.COM
18747836SJohn.Forte@Sun.COM if (check_intrange(optarg))
18757836SJohn.Forte@Sun.COM maxqitems = atoi(optarg);
18767836SJohn.Forte@Sun.COM else
18777836SJohn.Forte@Sun.COM exit(1);
18787836SJohn.Forte@Sun.COM
18797836SJohn.Forte@Sun.COM break;
18807836SJohn.Forte@Sun.COM case 'A':
18817836SJohn.Forte@Sun.COM if (flag && flag != RDC_CMD_TUNABLE)
18827836SJohn.Forte@Sun.COM inval = 1;
18837836SJohn.Forte@Sun.COM flag = RDC_CMD_TUNABLE;
18847836SJohn.Forte@Sun.COM
18857836SJohn.Forte@Sun.COM if (check_intrange(optarg))
18867836SJohn.Forte@Sun.COM asyncthr = atoi(optarg);
18877836SJohn.Forte@Sun.COM else
18887836SJohn.Forte@Sun.COM exit(1);
18897836SJohn.Forte@Sun.COM
18907836SJohn.Forte@Sun.COM break;
18917836SJohn.Forte@Sun.COM case 'D':
18927836SJohn.Forte@Sun.COM if (flag && flag != RDC_CMD_TUNABLE)
18937836SJohn.Forte@Sun.COM inval = 1;
18947836SJohn.Forte@Sun.COM flag = RDC_CMD_TUNABLE;
18957836SJohn.Forte@Sun.COM
18967836SJohn.Forte@Sun.COM if (set_qblock(optarg)) {
18977836SJohn.Forte@Sun.COM usage();
18987836SJohn.Forte@Sun.COM exit(1);
18997836SJohn.Forte@Sun.COM }
19007836SJohn.Forte@Sun.COM iflag |= qblock;
19017836SJohn.Forte@Sun.COM break;
19027836SJohn.Forte@Sun.COM case 'a':
19037836SJohn.Forte@Sun.COM if (flag && flag != RDC_CMD_TUNABLE)
19047836SJohn.Forte@Sun.COM inval = 1;
19057836SJohn.Forte@Sun.COM flag = RDC_CMD_TUNABLE;
19067836SJohn.Forte@Sun.COM if (strcmp(optarg, "off") == 0)
19077836SJohn.Forte@Sun.COM autosync = AUTOSYNC_OFF;
19087836SJohn.Forte@Sun.COM else if (strcmp(optarg, "on") == 0)
19097836SJohn.Forte@Sun.COM autosync = AUTOSYNC_ON;
19107836SJohn.Forte@Sun.COM else
19117836SJohn.Forte@Sun.COM inval = 1;
19127836SJohn.Forte@Sun.COM break;
19137836SJohn.Forte@Sun.COM case 'C':
19147836SJohn.Forte@Sun.COM if (clustered) {
1915*11576SSurya.Prakki@Sun.COM (void) strncpy(ctag_arg, optarg,
1916*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
19177836SJohn.Forte@Sun.COM process_clocal(ctag_arg);
19187836SJohn.Forte@Sun.COM } else
19197836SJohn.Forte@Sun.COM inval = 1;
19207836SJohn.Forte@Sun.COM break;
19217836SJohn.Forte@Sun.COM case 'g':
19227836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE)
19237836SJohn.Forte@Sun.COM inval = 1;
19247836SJohn.Forte@Sun.COM geflag = 1;
1925*11576SSurya.Prakki@Sun.COM (void) strncpy(group_arg, optarg, NSC_MAXPATH);
19267836SJohn.Forte@Sun.COM verify_groupname(group_arg);
19277836SJohn.Forte@Sun.COM break;
19287836SJohn.Forte@Sun.COM case 'b':
19297836SJohn.Forte@Sun.COM /* ignore */
19307836SJohn.Forte@Sun.COM break;
19317836SJohn.Forte@Sun.COM case 'n':
19327836SJohn.Forte@Sun.COM nflag = 1;
19337836SJohn.Forte@Sun.COM break;
19347836SJohn.Forte@Sun.COM case 'd':
19357836SJohn.Forte@Sun.COM if (flag)
19367836SJohn.Forte@Sun.COM inval = 1;
19377836SJohn.Forte@Sun.COM flag = RDC_CMD_DISABLE;
19387836SJohn.Forte@Sun.COM break;
19397836SJohn.Forte@Sun.COM case 'e':
19407836SJohn.Forte@Sun.COM if (flag || geflag)
19417836SJohn.Forte@Sun.COM inval = 1;
19427836SJohn.Forte@Sun.COM flag = RDC_CMD_ENABLE;
19437836SJohn.Forte@Sun.COM iflag |= RDC_OPT_SETBMP;
19447836SJohn.Forte@Sun.COM break;
19457836SJohn.Forte@Sun.COM case 'E':
19467836SJohn.Forte@Sun.COM if (flag)
19477836SJohn.Forte@Sun.COM inval = 1;
19487836SJohn.Forte@Sun.COM flag = RDC_CMD_ENABLE;
19497836SJohn.Forte@Sun.COM iflag |= RDC_OPT_CLRBMP;
19507836SJohn.Forte@Sun.COM break;
19517836SJohn.Forte@Sun.COM case 'f':
19527836SJohn.Forte@Sun.COM fflag = 1;
1953*11576SSurya.Prakki@Sun.COM (void) strcpy(config_file, optarg);
19547836SJohn.Forte@Sun.COM break;
19557836SJohn.Forte@Sun.COM case 'h':
19567836SJohn.Forte@Sun.COM usage();
19577836SJohn.Forte@Sun.COM exit(0);
19587836SJohn.Forte@Sun.COM break;
19597836SJohn.Forte@Sun.COM case 'l':
19607836SJohn.Forte@Sun.COM if (flag)
19617836SJohn.Forte@Sun.COM inval = 1;
19627836SJohn.Forte@Sun.COM flag = RDC_CMD_LOG;
19637836SJohn.Forte@Sun.COM break;
19647836SJohn.Forte@Sun.COM case 'm':
19657836SJohn.Forte@Sun.COM if (flag)
19667836SJohn.Forte@Sun.COM inval = 1;
19677836SJohn.Forte@Sun.COM flag = RDC_CMD_COPY;
19687836SJohn.Forte@Sun.COM iflag |= RDC_OPT_FULL;
19697836SJohn.Forte@Sun.COM break;
19707836SJohn.Forte@Sun.COM case 'O':
19717836SJohn.Forte@Sun.COM case 'o':
19727836SJohn.Forte@Sun.COM
19737836SJohn.Forte@Sun.COM if (!allow_role || oflag) {
19747836SJohn.Forte@Sun.COM inval = 1;
19757836SJohn.Forte@Sun.COM break;
19767836SJohn.Forte@Sun.COM }
19777836SJohn.Forte@Sun.COM if (c == 'o') {
19787836SJohn.Forte@Sun.COM oflag = RDC_BITMAPOR;
19797836SJohn.Forte@Sun.COM } else {
19807836SJohn.Forte@Sun.COM oflag = RDC_BITMAPSET;
19817836SJohn.Forte@Sun.COM }
19827836SJohn.Forte@Sun.COM boffset = strtoull(optarg, NULL, 0);
19837836SJohn.Forte@Sun.COM break;
19847836SJohn.Forte@Sun.COM case 'P':
19857836SJohn.Forte@Sun.COM if (flag)
19867836SJohn.Forte@Sun.COM inval = 1;
19877836SJohn.Forte@Sun.COM pflag = 1;
19887836SJohn.Forte@Sun.COM verbose = 1;
19897836SJohn.Forte@Sun.COM break;
19907836SJohn.Forte@Sun.COM case 'p':
19917836SJohn.Forte@Sun.COM if (flag)
19927836SJohn.Forte@Sun.COM inval = 1;
19937836SJohn.Forte@Sun.COM pflag = 1;
19947836SJohn.Forte@Sun.COM break;
19957836SJohn.Forte@Sun.COM case 'q':
19967836SJohn.Forte@Sun.COM if (flag)
19977836SJohn.Forte@Sun.COM inval = 1;
19987836SJohn.Forte@Sun.COM flag = RDC_CMD_INITQ;
19997836SJohn.Forte@Sun.COM qflag = optind;
20007836SJohn.Forte@Sun.COM qarg = optarg;
20017836SJohn.Forte@Sun.COM break;
20027836SJohn.Forte@Sun.COM case 'i':
20037836SJohn.Forte@Sun.COM if (flag)
20047836SJohn.Forte@Sun.COM inval = 1;
20057836SJohn.Forte@Sun.COM pflag = 1;
20067836SJohn.Forte@Sun.COM file_format = 1;
20077836SJohn.Forte@Sun.COM break;
20087836SJohn.Forte@Sun.COM case 'r':
20097836SJohn.Forte@Sun.COM reverse = 1;
20107836SJohn.Forte@Sun.COM iflag |= RDC_OPT_REVERSE;
20117836SJohn.Forte@Sun.COM break;
20127836SJohn.Forte@Sun.COM case 's':
20137836SJohn.Forte@Sun.COM if (flag)
20147836SJohn.Forte@Sun.COM inval = 1;
20157836SJohn.Forte@Sun.COM flag = RDC_CMD_STATUS;
20167836SJohn.Forte@Sun.COM nflag = 1; /* No prompt for a status */
20177836SJohn.Forte@Sun.COM break;
20187836SJohn.Forte@Sun.COM case 'u':
20197836SJohn.Forte@Sun.COM if (flag)
20207836SJohn.Forte@Sun.COM inval = 1;
20217836SJohn.Forte@Sun.COM flag = RDC_CMD_COPY;
20227836SJohn.Forte@Sun.COM iflag |= RDC_OPT_UPDATE;
20237836SJohn.Forte@Sun.COM break;
20247836SJohn.Forte@Sun.COM case 'v':
20257836SJohn.Forte@Sun.COM if (flag)
20267836SJohn.Forte@Sun.COM inval = 1;
20277836SJohn.Forte@Sun.COM pflag = 1;
20287836SJohn.Forte@Sun.COM vflag = 1;
20297836SJohn.Forte@Sun.COM break;
20307836SJohn.Forte@Sun.COM case 'w':
20317836SJohn.Forte@Sun.COM if (flag)
20327836SJohn.Forte@Sun.COM inval = 1;
20337836SJohn.Forte@Sun.COM flag = RDC_CMD_WAIT;
20347836SJohn.Forte@Sun.COM break;
20357836SJohn.Forte@Sun.COM case '?':
20367836SJohn.Forte@Sun.COM errflag++;
20377836SJohn.Forte@Sun.COM }
20387836SJohn.Forte@Sun.COM }
20397836SJohn.Forte@Sun.COM
20407836SJohn.Forte@Sun.COM if (inval || ((flag != RDC_BITMAPOP) && oflag)) {
20417836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("invalid argument combination"));
20427836SJohn.Forte@Sun.COM errflag = 1;
20437836SJohn.Forte@Sun.COM }
20447836SJohn.Forte@Sun.COM
20457836SJohn.Forte@Sun.COM if (flag && Iflag) {
20467836SJohn.Forte@Sun.COM /* Mutually incompatible */
20477836SJohn.Forte@Sun.COM usage();
20487836SJohn.Forte@Sun.COM exit(1);
20497836SJohn.Forte@Sun.COM }
20507836SJohn.Forte@Sun.COM
20517836SJohn.Forte@Sun.COM if (Iflag) {
20527836SJohn.Forte@Sun.COM rdc_ii_config(argc, argv);
20537836SJohn.Forte@Sun.COM exit(0);
20547836SJohn.Forte@Sun.COM }
20557836SJohn.Forte@Sun.COM
20567836SJohn.Forte@Sun.COM if (vflag) {
20577836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
20587836SJohn.Forte@Sun.COM
20597836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
20607836SJohn.Forte@Sun.COM rc = RDC_IOCTL(RDC_VERSION, &rdc_version, 0, 0, 0, 0, ustatus);
20617836SJohn.Forte@Sun.COM if (rc == SPCS_S_ERROR) {
20627836SJohn.Forte@Sun.COM rdc_err(&ustatus, gettext("statistics error"));
20637836SJohn.Forte@Sun.COM }
20647836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
20657836SJohn.Forte@Sun.COM #ifdef DEBUG
20667836SJohn.Forte@Sun.COM (void) printf(gettext("Remote Mirror version %d.%d.%d.%d\n"),
20677836SJohn.Forte@Sun.COM rdc_version.major, rdc_version.minor,
20687836SJohn.Forte@Sun.COM rdc_version.micro, rdc_version.baseline);
20697836SJohn.Forte@Sun.COM #else
20707836SJohn.Forte@Sun.COM if (rdc_version.micro) {
20717836SJohn.Forte@Sun.COM (void) printf(gettext(
20727836SJohn.Forte@Sun.COM "Remote Mirror version %d.%d.%d\n"),
20737836SJohn.Forte@Sun.COM rdc_version.major,
20747836SJohn.Forte@Sun.COM rdc_version.minor,
20757836SJohn.Forte@Sun.COM rdc_version.micro);
20767836SJohn.Forte@Sun.COM } else {
20777836SJohn.Forte@Sun.COM (void) printf(gettext("Remote Mirror version %d.%d\n"),
20787836SJohn.Forte@Sun.COM rdc_version.major, rdc_version.minor);
20797836SJohn.Forte@Sun.COM }
20807836SJohn.Forte@Sun.COM #endif
20817836SJohn.Forte@Sun.COM exit(0);
20827836SJohn.Forte@Sun.COM }
20837836SJohn.Forte@Sun.COM
20847836SJohn.Forte@Sun.COM if (!(flag || pflag) || errflag) {
20857836SJohn.Forte@Sun.COM usage();
20867836SJohn.Forte@Sun.COM exit(1);
20877836SJohn.Forte@Sun.COM }
20887836SJohn.Forte@Sun.COM
20897836SJohn.Forte@Sun.COM if (pflag && !fflag && (argc - optind) == 0) {
20907836SJohn.Forte@Sun.COM /* print with no set specified */
20917836SJohn.Forte@Sun.COM exit(rdc_print(file_format, verbose,
20927836SJohn.Forte@Sun.COM group_arg, ctag_arg, NULL, NULL, NULL));
20937836SJohn.Forte@Sun.COM }
20947836SJohn.Forte@Sun.COM
20957836SJohn.Forte@Sun.COM if (qflag) { /* change disk queue setting */
20967836SJohn.Forte@Sun.COM int subcmd = 0;
20977836SJohn.Forte@Sun.COM int offset = 0;
20987836SJohn.Forte@Sun.COM char *ptr;
20997836SJohn.Forte@Sun.COM char *qvol;
21007836SJohn.Forte@Sun.COM char tohost_arg[MAX_RDC_HOST_SIZE];
21017836SJohn.Forte@Sun.COM char tofile_arg[NSC_MAXPATH];
21027836SJohn.Forte@Sun.COM
21037836SJohn.Forte@Sun.COM if (strcmp("a", qarg) == 0) {
21047836SJohn.Forte@Sun.COM subcmd = RDC_CMD_ADDQ;
21057836SJohn.Forte@Sun.COM offset = 1;
21067836SJohn.Forte@Sun.COM } else if (strcmp("d", qarg) == 0) {
21077836SJohn.Forte@Sun.COM subcmd = RDC_CMD_REMQ;
21087836SJohn.Forte@Sun.COM offset = 0;
21097836SJohn.Forte@Sun.COM } else if (strcmp("r", qarg) == 0) {
21107836SJohn.Forte@Sun.COM subcmd = RDC_CMD_REPQ;
21117836SJohn.Forte@Sun.COM offset = 1;
21127836SJohn.Forte@Sun.COM } else {
21137836SJohn.Forte@Sun.COM rdc_warn(NULL, " %s Invalid qopt", qarg);
21147836SJohn.Forte@Sun.COM q_usage(1);
21157836SJohn.Forte@Sun.COM exit(1);
21167836SJohn.Forte@Sun.COM }
21177836SJohn.Forte@Sun.COM if (strlen(group_arg) == 0) {
21187836SJohn.Forte@Sun.COM /* pick out single set as shost:svol */
21197836SJohn.Forte@Sun.COM ptr = strtok(argv[qflag + offset], ":");
21207836SJohn.Forte@Sun.COM if (ptr)
2121*11576SSurya.Prakki@Sun.COM (void) strncpy(tohost_arg, ptr,
2122*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
21237836SJohn.Forte@Sun.COM else {
21247836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Bad host specified"));
21257836SJohn.Forte@Sun.COM q_usage(1);
21267836SJohn.Forte@Sun.COM exit(1);
21277836SJohn.Forte@Sun.COM }
21287836SJohn.Forte@Sun.COM ptr = strtok(NULL, ":");
21297836SJohn.Forte@Sun.COM if (ptr)
2130*11576SSurya.Prakki@Sun.COM (void) strncpy(tofile_arg, ptr, NSC_MAXPATH);
21317836SJohn.Forte@Sun.COM else {
21327836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Bad set specified"));
21337836SJohn.Forte@Sun.COM q_usage(1);
21347836SJohn.Forte@Sun.COM exit(1);
21357836SJohn.Forte@Sun.COM }
21367836SJohn.Forte@Sun.COM }
21377836SJohn.Forte@Sun.COM
21387836SJohn.Forte@Sun.COM qvol = argv[qflag];
21397836SJohn.Forte@Sun.COM if ((qvol == NULL) && (subcmd != RDC_CMD_REMQ)) {
21407836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("missing queue volume"));
21417836SJohn.Forte@Sun.COM q_usage(1);
21427836SJohn.Forte@Sun.COM exit(1);
21437836SJohn.Forte@Sun.COM }
21447836SJohn.Forte@Sun.COM diskq_subcmd(subcmd, qvol, group_arg, ctag_arg,
21457836SJohn.Forte@Sun.COM tohost_arg, tofile_arg);
21467836SJohn.Forte@Sun.COM exit(0);
21477836SJohn.Forte@Sun.COM }
21487836SJohn.Forte@Sun.COM
21497836SJohn.Forte@Sun.COM if (flag == RDC_CMD_RECONFIG && !fflag) {
21507836SJohn.Forte@Sun.COM /* See what is to be reconfigured */
21517836SJohn.Forte@Sun.COM if (argc - optind == 0)
21527836SJohn.Forte@Sun.COM flag = RDC_CMD_RESET;
21537836SJohn.Forte@Sun.COM else {
21547836SJohn.Forte@Sun.COM if (argc - optind < 2) {
21557836SJohn.Forte@Sun.COM usage();
21567836SJohn.Forte@Sun.COM exit(1);
21577836SJohn.Forte@Sun.COM }
21587836SJohn.Forte@Sun.COM c = *argv[optind++];
21597836SJohn.Forte@Sun.COM if (argv[optind -1][1] != '\0') {
21607836SJohn.Forte@Sun.COM usage();
21617836SJohn.Forte@Sun.COM exit(2);
21627836SJohn.Forte@Sun.COM }
21637836SJohn.Forte@Sun.COM switch (c) {
21647836SJohn.Forte@Sun.COM case 'b':
21657836SJohn.Forte@Sun.COM if (argc - optind < 2) {
21667836SJohn.Forte@Sun.COM usage();
21677836SJohn.Forte@Sun.COM exit(1);
21687836SJohn.Forte@Sun.COM }
21697836SJohn.Forte@Sun.COM if (*argv[optind] == 'p')
21707836SJohn.Forte@Sun.COM reconfig_pbitmap = argv[++optind];
21717836SJohn.Forte@Sun.COM else if (*argv[optind] == 's')
21727836SJohn.Forte@Sun.COM reconfig_sbitmap = argv[++optind];
21737836SJohn.Forte@Sun.COM else {
21747836SJohn.Forte@Sun.COM usage();
21757836SJohn.Forte@Sun.COM exit(1);
21767836SJohn.Forte@Sun.COM }
21777836SJohn.Forte@Sun.COM optind++;
21787836SJohn.Forte@Sun.COM break;
21797836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
21807836SJohn.Forte@Sun.COM case 'd':
21817836SJohn.Forte@Sun.COM reconfig_direct = argv[optind++];
21827836SJohn.Forte@Sun.COM break;
21837836SJohn.Forte@Sun.COM #endif
21847836SJohn.Forte@Sun.COM case 'g':
21857836SJohn.Forte@Sun.COM reconfig_group = argv[optind++];
21867836SJohn.Forte@Sun.COM verify_groupname(reconfig_group);
21877836SJohn.Forte@Sun.COM break;
21887836SJohn.Forte@Sun.COM case 'C':
21897836SJohn.Forte@Sun.COM if (clustered) {
2190*11576SSurya.Prakki@Sun.COM (void) strncpy(reconfig_ctag,
2191*11576SSurya.Prakki@Sun.COM argv[optind++], MAX_RDC_HOST_SIZE);
21927836SJohn.Forte@Sun.COM process_clocal(reconfig_ctag);
21937836SJohn.Forte@Sun.COM } else {
21947836SJohn.Forte@Sun.COM usage();
21957836SJohn.Forte@Sun.COM exit(1);
21967836SJohn.Forte@Sun.COM }
21977836SJohn.Forte@Sun.COM break;
21987836SJohn.Forte@Sun.COM case 'm':
21997836SJohn.Forte@Sun.COM if (strcmp(argv[optind], "sync") == 0)
22007836SJohn.Forte@Sun.COM reconfig_doasync = 0;
22017836SJohn.Forte@Sun.COM else if (strcmp(argv[optind], "async") == 0)
22027836SJohn.Forte@Sun.COM reconfig_doasync = 1;
22037836SJohn.Forte@Sun.COM else {
22047836SJohn.Forte@Sun.COM usage();
22057836SJohn.Forte@Sun.COM exit(1);
22067836SJohn.Forte@Sun.COM }
22077836SJohn.Forte@Sun.COM optind++;
22087836SJohn.Forte@Sun.COM break;
22097836SJohn.Forte@Sun.COM case 'r':
22107836SJohn.Forte@Sun.COM if (allow_role) {
22117836SJohn.Forte@Sun.COM iflag |= RDC_OPT_REVERSE_ROLE;
22127836SJohn.Forte@Sun.COM break;
22137836SJohn.Forte@Sun.COM }
22147836SJohn.Forte@Sun.COM default:
22157836SJohn.Forte@Sun.COM usage();
22167836SJohn.Forte@Sun.COM exit(1);
22177836SJohn.Forte@Sun.COM }
22187836SJohn.Forte@Sun.COM }
22197836SJohn.Forte@Sun.COM }
22207836SJohn.Forte@Sun.COM if (fflag) {
22217836SJohn.Forte@Sun.COM checksetfields = 1;
22227836SJohn.Forte@Sun.COM if ((argc - optind) != 0) {
22237836SJohn.Forte@Sun.COM usage();
22247836SJohn.Forte@Sun.COM exit(1);
22257836SJohn.Forte@Sun.COM }
22267836SJohn.Forte@Sun.COM } else {
22277836SJohn.Forte@Sun.COM if ((argc - optind) == 0) {
22287836SJohn.Forte@Sun.COM /* Use libcfg to figure out what to operate on */
22297836SJohn.Forte@Sun.COM cfgflag = 1;
22307836SJohn.Forte@Sun.COM #ifdef DEBUG
22317836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("using current config"));
22327836SJohn.Forte@Sun.COM #endif
22337836SJohn.Forte@Sun.COM checksetfields = 0;
22347836SJohn.Forte@Sun.COM } else {
22357836SJohn.Forte@Sun.COM if ((argc - optind) < 8 && (argc - optind) != 1) {
22367836SJohn.Forte@Sun.COM usage();
22377836SJohn.Forte@Sun.COM exit(1);
22387836SJohn.Forte@Sun.COM }
22397836SJohn.Forte@Sun.COM }
22407836SJohn.Forte@Sun.COM }
22417836SJohn.Forte@Sun.COM
22427836SJohn.Forte@Sun.COM if (cfgflag) {
22437836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ADDQ ||
22447836SJohn.Forte@Sun.COM flag == RDC_CMD_REMQ ||
22457836SJohn.Forte@Sun.COM flag == RDC_CMD_KILLQ ||
22467836SJohn.Forte@Sun.COM flag == RDC_CMD_INITQ) {
22477836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not use current config "
22487836SJohn.Forte@Sun.COM "for disk queue operations"));
22497836SJohn.Forte@Sun.COM }
22507836SJohn.Forte@Sun.COM } else if (fflag) {
22517836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ADDQ ||
22527836SJohn.Forte@Sun.COM flag == RDC_CMD_REMQ ||
22537836SJohn.Forte@Sun.COM flag == RDC_CMD_KILLQ ||
22547836SJohn.Forte@Sun.COM flag == RDC_CMD_INITQ) {
22557836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not use a config file "
22567836SJohn.Forte@Sun.COM "for disk queue operations"));
22577836SJohn.Forte@Sun.COM }
22587836SJohn.Forte@Sun.COM }
22597836SJohn.Forte@Sun.COM if (cfgflag) {
22607836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE) {
22617836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not use current config "
22627836SJohn.Forte@Sun.COM "for enable command"));
22637836SJohn.Forte@Sun.COM }
22647836SJohn.Forte@Sun.COM if ((flag == RDC_CMD_RECONFIG) && (reconfig_pbitmap ||
22657836SJohn.Forte@Sun.COM reconfig_sbitmap)) {
22667836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not use current config "
22677836SJohn.Forte@Sun.COM "for bitmap reconfiguration"));
22687836SJohn.Forte@Sun.COM }
22697836SJohn.Forte@Sun.COM if (flag == RDC_BITMAPOP) {
22707836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not use current config "
22717836SJohn.Forte@Sun.COM "for bitmap set command"));
22727836SJohn.Forte@Sun.COM }
22737836SJohn.Forte@Sun.COM pairs = read_libcfg(flag, group_arg, ctag_arg);
22747836SJohn.Forte@Sun.COM if (pairs == 0) {
22757836SJohn.Forte@Sun.COM (void) fprintf(stderr,
22767836SJohn.Forte@Sun.COM gettext("no matching Remote Mirror sets found "
22777836SJohn.Forte@Sun.COM "in config\n"));
22787836SJohn.Forte@Sun.COM exit(1);
22797836SJohn.Forte@Sun.COM }
22807836SJohn.Forte@Sun.COM } else if (!fflag) {
22817836SJohn.Forte@Sun.COM /*
22827836SJohn.Forte@Sun.COM * Format is either:
22837836SJohn.Forte@Sun.COM *
22847836SJohn.Forte@Sun.COM * tohost:tofile
22857836SJohn.Forte@Sun.COM *
22867836SJohn.Forte@Sun.COM * or something like this for example:
22877836SJohn.Forte@Sun.COM *
22887836SJohn.Forte@Sun.COM * fromhost fromfile frombitmap tohost tofile tobitmap ip sync
22897836SJohn.Forte@Sun.COM * g group C ctag
22907836SJohn.Forte@Sun.COM */
22917836SJohn.Forte@Sun.COM
22927836SJohn.Forte@Sun.COM if (argc - optind == 1) {
22937836SJohn.Forte@Sun.COM char tohost_arg[MAX_RDC_HOST_SIZE];
22947836SJohn.Forte@Sun.COM char tofile_arg[NSC_MAXPATH];
22957836SJohn.Forte@Sun.COM char *ptr;
22967836SJohn.Forte@Sun.COM
22977836SJohn.Forte@Sun.COM checksetfields = 0;
22987836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE) {
22997836SJohn.Forte@Sun.COM rdc_err(NULL,
23007836SJohn.Forte@Sun.COM gettext("must specify full set details for "
23017836SJohn.Forte@Sun.COM "enable command"));
23027836SJohn.Forte@Sun.COM }
23037836SJohn.Forte@Sun.COM ptr = strtok(argv[optind], ":");
23047836SJohn.Forte@Sun.COM if (ptr)
2305*11576SSurya.Prakki@Sun.COM (void) strncpy(tohost_arg, ptr,
2306*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
23077836SJohn.Forte@Sun.COM else {
23087836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Bad host specified"));
23097836SJohn.Forte@Sun.COM }
23107836SJohn.Forte@Sun.COM ptr = strtok(NULL, ":");
23117836SJohn.Forte@Sun.COM if (ptr)
2312*11576SSurya.Prakki@Sun.COM (void) strncpy(tofile_arg, ptr, NSC_MAXPATH);
23137836SJohn.Forte@Sun.COM else {
23147836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Bad set specified"));
23157836SJohn.Forte@Sun.COM }
23167836SJohn.Forte@Sun.COM
23177836SJohn.Forte@Sun.COM /* Now look up tohost:tofile via libcfg */
23187836SJohn.Forte@Sun.COM
23197836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
23207836SJohn.Forte@Sun.COM rdc_err(NULL,
23217836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
23227836SJohn.Forte@Sun.COM
23237836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
23247836SJohn.Forte@Sun.COM rdc_err(NULL,
23257836SJohn.Forte@Sun.COM gettext("unable to lock configuration"));
23267836SJohn.Forte@Sun.COM
23277836SJohn.Forte@Sun.COM setnumber = 0;
23287836SJohn.Forte@Sun.COM found = 0;
23297836SJohn.Forte@Sun.COM /*CSTYLED*/
23307836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets;) {
23317836SJohn.Forte@Sun.COM setnumber++;
23327836SJohn.Forte@Sun.COM
23337836SJohn.Forte@Sun.COM bzero(buf, CFG_MAX_BUF);
23347836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23357836SJohn.Forte@Sun.COM "sndr.set%d", setnumber);
23367836SJohn.Forte@Sun.COM rc = cfg_get_cstring(cfg, key, buf,
23377836SJohn.Forte@Sun.COM CFG_MAX_BUF);
23387836SJohn.Forte@Sun.COM if (rc < 0)
23397836SJohn.Forte@Sun.COM break;
23407836SJohn.Forte@Sun.COM
23417836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23427836SJohn.Forte@Sun.COM "sndr.set%d.shost", setnumber);
23437836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, tohost,
23447836SJohn.Forte@Sun.COM sizeof (tohost));
23457836SJohn.Forte@Sun.COM if (strncmp(tohost, tohost_arg, NSC_MAXPATH))
23467836SJohn.Forte@Sun.COM continue;
23477836SJohn.Forte@Sun.COM
23487836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23497836SJohn.Forte@Sun.COM "sndr.set%d.secondary", setnumber);
23507836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, tofile,
23517836SJohn.Forte@Sun.COM sizeof (tofile));
23527836SJohn.Forte@Sun.COM if (strncmp(tofile, tofile_arg, NSC_MAXPATH))
23537836SJohn.Forte@Sun.COM continue;
23547836SJohn.Forte@Sun.COM
23557836SJohn.Forte@Sun.COM found = 1;
23567836SJohn.Forte@Sun.COM
23577836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23587836SJohn.Forte@Sun.COM "sndr.set%d.phost", setnumber);
23597836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, fromhost,
23607836SJohn.Forte@Sun.COM sizeof (fromhost));
23617836SJohn.Forte@Sun.COM
23627836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23637836SJohn.Forte@Sun.COM "sndr.set%d.primary", setnumber);
23647836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, fromfile,
23657836SJohn.Forte@Sun.COM sizeof (fromfile));
23667836SJohn.Forte@Sun.COM
23677836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23687836SJohn.Forte@Sun.COM "sndr.set%d.pbitmap", setnumber);
23697836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, frombitmap,
23707836SJohn.Forte@Sun.COM sizeof (frombitmap));
23717836SJohn.Forte@Sun.COM
23727836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23737836SJohn.Forte@Sun.COM "sndr.set%d.sbitmap", setnumber);
23747836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, tobitmap,
23757836SJohn.Forte@Sun.COM sizeof (tobitmap));
23767836SJohn.Forte@Sun.COM
23777836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23787836SJohn.Forte@Sun.COM "sndr.set%d.type", setnumber);
23797836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, directfile,
23807836SJohn.Forte@Sun.COM sizeof (directfile));
23817836SJohn.Forte@Sun.COM if (strcmp(directfile, "ip") == 0)
2382*11576SSurya.Prakki@Sun.COM (void) strcpy(directfile, "");
23837836SJohn.Forte@Sun.COM
23847836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23857836SJohn.Forte@Sun.COM "sndr.set%d.mode", setnumber);
23867836SJohn.Forte@Sun.COM (void) cfg_get_cstring(
23877836SJohn.Forte@Sun.COM cfg, key, mode, sizeof (mode));
23887836SJohn.Forte@Sun.COM
23897836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23907836SJohn.Forte@Sun.COM "sndr.set%d.group", setnumber);
23917836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, group,
23927836SJohn.Forte@Sun.COM sizeof (group));
23937836SJohn.Forte@Sun.COM if (strcmp(group_arg, "") &&
23947836SJohn.Forte@Sun.COM strncmp(group_arg, group, NSC_MAXPATH))
23957836SJohn.Forte@Sun.COM continue;
23967836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
23977836SJohn.Forte@Sun.COM "sndr.set%d.cnode", setnumber);
23987836SJohn.Forte@Sun.COM (void) cfg_get_cstring(
23997836SJohn.Forte@Sun.COM cfg, key, ctag, sizeof (ctag));
24007836SJohn.Forte@Sun.COM if ((strlen(ctag_arg) > 0) &&
24017836SJohn.Forte@Sun.COM (strcmp(ctag_arg, ctag) != 0))
24027836SJohn.Forte@Sun.COM rdc_err(NULL,
24037836SJohn.Forte@Sun.COM gettext("ctags %s and %s "
24047836SJohn.Forte@Sun.COM "do not match"), ctag_arg, ctag);
24057836SJohn.Forte@Sun.COM
24067836SJohn.Forte@Sun.COM if (strcmp(mode, "sync") == 0)
24077836SJohn.Forte@Sun.COM doasync = 0;
24087836SJohn.Forte@Sun.COM else if (strcmp(mode, "async") == 0)
24097836SJohn.Forte@Sun.COM doasync = 1;
24107836SJohn.Forte@Sun.COM else {
24117836SJohn.Forte@Sun.COM rdc_err(NULL,
24127836SJohn.Forte@Sun.COM gettext("set %s:%s neither sync "
24137836SJohn.Forte@Sun.COM "nor async"), tohost, tofile);
24147836SJohn.Forte@Sun.COM }
24157836SJohn.Forte@Sun.COM break;
24167836SJohn.Forte@Sun.COM }
24177836SJohn.Forte@Sun.COM cfg_close(cfg);
24187836SJohn.Forte@Sun.COM if (!found) {
24197836SJohn.Forte@Sun.COM rdc_err(NULL,
24207836SJohn.Forte@Sun.COM gettext("set %s:%s not found in config"),
24217836SJohn.Forte@Sun.COM tohost_arg, tofile_arg);
24227836SJohn.Forte@Sun.COM }
24237836SJohn.Forte@Sun.COM } else {
24247836SJohn.Forte@Sun.COM checksetfields = 1;
2425*11576SSurya.Prakki@Sun.COM (void) strncpy(fromhost, argv[optind],
2426*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
2427*11576SSurya.Prakki@Sun.COM (void) strncpy(fromfile, argv[optind+1], NSC_MAXPATH);
2428*11576SSurya.Prakki@Sun.COM (void) strncpy(frombitmap, argv[optind+2], NSC_MAXPATH);
2429*11576SSurya.Prakki@Sun.COM (void) strncpy(tohost, argv[optind+3],
2430*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
2431*11576SSurya.Prakki@Sun.COM (void) strncpy(tofile, argv[optind+4], NSC_MAXPATH);
2432*11576SSurya.Prakki@Sun.COM (void) strncpy(tobitmap, argv[optind+5], NSC_MAXPATH);
24337836SJohn.Forte@Sun.COM
24347836SJohn.Forte@Sun.COM /* Check the length of entries from the command line */
24357836SJohn.Forte@Sun.COM if ((fromhost[MAX_RDC_HOST_SIZE - 1] != '\0') ||
24367836SJohn.Forte@Sun.COM (tohost[MAX_RDC_HOST_SIZE - 1] != '\0')) {
24377836SJohn.Forte@Sun.COM rdc_err(NULL,
24387836SJohn.Forte@Sun.COM gettext("hostname is longer than %d "
24397836SJohn.Forte@Sun.COM "characters\n"), (MAX_RDC_HOST_SIZE - 1));
24407836SJohn.Forte@Sun.COM }
24417836SJohn.Forte@Sun.COM
24427836SJohn.Forte@Sun.COM /* Check if it's ip address -- not allowed */
24437836SJohn.Forte@Sun.COM if ((inet_addr(fromhost) != (in_addr_t)(-1)) ||
24447836SJohn.Forte@Sun.COM (inet_addr(tohost) != (in_addr_t)(-1))) {
24457836SJohn.Forte@Sun.COM rdc_err(NULL, gettext(
24467836SJohn.Forte@Sun.COM "The hostname specified is invalid.\n"
24477836SJohn.Forte@Sun.COM "See 'man inet(3SOCKET)'"));
24487836SJohn.Forte@Sun.COM }
24497836SJohn.Forte@Sun.COM
24507836SJohn.Forte@Sun.COM if ((fromfile[NSC_MAXPATH - 1] != '\0') ||
24517836SJohn.Forte@Sun.COM (tofile[NSC_MAXPATH - 1] != '\0') ||
24527836SJohn.Forte@Sun.COM (frombitmap[NSC_MAXPATH - 1] != '\0') ||
24537836SJohn.Forte@Sun.COM (tobitmap[NSC_MAXPATH - 1] != '\0')) {
24547836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("device name is longer "
24557836SJohn.Forte@Sun.COM "than %d characters\n"), (NSC_MAXPATH - 1));
24567836SJohn.Forte@Sun.COM }
24577836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
24587836SJohn.Forte@Sun.COM if (argv[optind+6][0] == '/') {
24597836SJohn.Forte@Sun.COM /* FCAL directio */
2460*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile, argv[optind+6],
24617836SJohn.Forte@Sun.COM NSC_MAXPATH);
24627836SJohn.Forte@Sun.COM } else if (strcmp(argv[optind+6], "ip") != 0) {
24637836SJohn.Forte@Sun.COM #else
24647836SJohn.Forte@Sun.COM if (strcmp(argv[optind+6], "ip") != 0) {
24657836SJohn.Forte@Sun.COM #endif
24667836SJohn.Forte@Sun.COM usage();
24677836SJohn.Forte@Sun.COM exit(1);
24687836SJohn.Forte@Sun.COM } else
2469*11576SSurya.Prakki@Sun.COM (void) strcpy(directfile, "ip");
24707836SJohn.Forte@Sun.COM
24717836SJohn.Forte@Sun.COM if (strcmp(argv[optind+7], "sync") == 0)
24727836SJohn.Forte@Sun.COM doasync = 0;
24737836SJohn.Forte@Sun.COM else if (strcmp(argv[optind+7], "async") == 0)
24747836SJohn.Forte@Sun.COM doasync = 1;
24757836SJohn.Forte@Sun.COM else {
24767836SJohn.Forte@Sun.COM usage();
24777836SJohn.Forte@Sun.COM exit(1);
24787836SJohn.Forte@Sun.COM }
24797836SJohn.Forte@Sun.COM
24807836SJohn.Forte@Sun.COM /*
24817836SJohn.Forte@Sun.COM * At this point, we could have a set which is
24827836SJohn.Forte@Sun.COM * clustered, but neither a 'C ctag' or '-C ctag' has
24837836SJohn.Forte@Sun.COM * been specified. To avoid clobbering the ctag if a
24847836SJohn.Forte@Sun.COM * dscfg operation is done in the future, we should get
24857836SJohn.Forte@Sun.COM * the ctag out of the config at this point. To do this,
24867836SJohn.Forte@Sun.COM * set the cluster resource filter to NULL to look at
24877836SJohn.Forte@Sun.COM * all sets in the config, pulling out the ctag for the
24887836SJohn.Forte@Sun.COM * set matching shost:svol. If the set is not found,
24897836SJohn.Forte@Sun.COM * fail here. Note, we skip this set on an enable as the
24907836SJohn.Forte@Sun.COM * set is not yet in the config, so no need to waste
24917836SJohn.Forte@Sun.COM * time.
24927836SJohn.Forte@Sun.COM */
24937836SJohn.Forte@Sun.COM if ((argc - optind == 8) && clustered &&
24947836SJohn.Forte@Sun.COM (flag != RDC_CMD_ENABLE)) {
24957836SJohn.Forte@Sun.COM int setnumber;
24967836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
24977836SJohn.Forte@Sun.COM
24987836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
24997836SJohn.Forte@Sun.COM rdc_err(NULL,
25007836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
25017836SJohn.Forte@Sun.COM }
25027836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK)) {
25037836SJohn.Forte@Sun.COM rdc_err(NULL,
25047836SJohn.Forte@Sun.COM gettext("unable to lock configuration"));
25057836SJohn.Forte@Sun.COM }
25067836SJohn.Forte@Sun.COM
25077836SJohn.Forte@Sun.COM cfg_resource(cfg, NULL);
25087836SJohn.Forte@Sun.COM
25097836SJohn.Forte@Sun.COM if ((setnumber =
25107836SJohn.Forte@Sun.COM find_setnumber_in_libcfg(cfg, NULL, tohost,
25117836SJohn.Forte@Sun.COM tofile)) < 0) {
25127836SJohn.Forte@Sun.COM cfg_close(cfg);
25137836SJohn.Forte@Sun.COM rdc_err(NULL,
25147836SJohn.Forte@Sun.COM gettext("unable to find Remote "
25157836SJohn.Forte@Sun.COM "Mirror set "
25167836SJohn.Forte@Sun.COM "%s:%s in config"),
25177836SJohn.Forte@Sun.COM tohost, tofile);
25187836SJohn.Forte@Sun.COM }
25197836SJohn.Forte@Sun.COM
25207836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
25217836SJohn.Forte@Sun.COM "sndr.set%d.cnode", setnumber);
25227836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, ctag_arg,
25237836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE) < 0) {
25247836SJohn.Forte@Sun.COM cfg_close(cfg);
25257836SJohn.Forte@Sun.COM rdc_err(NULL,
25267836SJohn.Forte@Sun.COM gettext("unable to determine ctag "
25277836SJohn.Forte@Sun.COM "for Remote Mirror set %s:%s"),
25287836SJohn.Forte@Sun.COM tohost, tofile);
25297836SJohn.Forte@Sun.COM }
25307836SJohn.Forte@Sun.COM
25317836SJohn.Forte@Sun.COM rdc_islocal = strcmp(ctag_arg, "-") ? 0 : 1;
25327836SJohn.Forte@Sun.COM
25337836SJohn.Forte@Sun.COM cfg_close(cfg);
25347836SJohn.Forte@Sun.COM }
25357836SJohn.Forte@Sun.COM
25367836SJohn.Forte@Sun.COM extra_argc = argc - optind;
25377836SJohn.Forte@Sun.COM if (extra_argc < 8 || extra_argc > 14 ||
25387836SJohn.Forte@Sun.COM extra_argc % 2 != 0) {
25397836SJohn.Forte@Sun.COM usage();
25407836SJohn.Forte@Sun.COM exit(1);
25417836SJohn.Forte@Sun.COM }
25427836SJohn.Forte@Sun.COM
25437836SJohn.Forte@Sun.COM /*
25447836SJohn.Forte@Sun.COM * Loop through all of the extra arguments specified
25457836SJohn.Forte@Sun.COM * on the command line, setting the appropriate values
25467836SJohn.Forte@Sun.COM * for valid entries. If an unrecognized argument is
25477836SJohn.Forte@Sun.COM * detected, abort with error. Note: This hack should be
25487836SJohn.Forte@Sun.COM * removed and we should not accept these entries as
25497836SJohn.Forte@Sun.COM * arguments, they should be passed in as switches.
25507836SJohn.Forte@Sun.COM */
25517836SJohn.Forte@Sun.COM for (i = (8 + optind); i < argc; i += 2) {
25527836SJohn.Forte@Sun.COM /* string case statement */
25537836SJohn.Forte@Sun.COM if (strcmp(argv[i], "g") == 0) {
2554*11576SSurya.Prakki@Sun.COM (void) strncpy(group, argv[i + 1],
2555*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
25567836SJohn.Forte@Sun.COM if (group[NSC_MAXPATH - 1] != '\0') {
25577836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("group name is "
25587836SJohn.Forte@Sun.COM "longer than %d characters\n"),
25597836SJohn.Forte@Sun.COM (NSC_MAXPATH - 1));
25607836SJohn.Forte@Sun.COM }
25617836SJohn.Forte@Sun.COM } else if (strcmp(argv[i], "C") == 0) {
25627836SJohn.Forte@Sun.COM if (!clustered) {
25637836SJohn.Forte@Sun.COM usage();
25647836SJohn.Forte@Sun.COM exit(1);
25657836SJohn.Forte@Sun.COM }
2566*11576SSurya.Prakki@Sun.COM (void) strncpy(ctag, argv[i + 1],
25677836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
25687836SJohn.Forte@Sun.COM
25697836SJohn.Forte@Sun.COM if (ctag[MAX_RDC_HOST_SIZE - 1] != '\0') {
25707836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cluster name "
25717836SJohn.Forte@Sun.COM "is longer than %d characters\n"),
25727836SJohn.Forte@Sun.COM (MAX_RDC_HOST_SIZE - 1));
25737836SJohn.Forte@Sun.COM }
25747836SJohn.Forte@Sun.COM process_clocal(ctag);
25757836SJohn.Forte@Sun.COM
25767836SJohn.Forte@Sun.COM /*
25777836SJohn.Forte@Sun.COM * well here is something.
25787836SJohn.Forte@Sun.COM * what if they went sndradm -C local
25797836SJohn.Forte@Sun.COM * host a b host a b ip sync C foobar?
25807836SJohn.Forte@Sun.COM * they might be confused
25817836SJohn.Forte@Sun.COM * lets stop them if ctag_arg and ctag
25827836SJohn.Forte@Sun.COM * don't match and forgive if they are
25837836SJohn.Forte@Sun.COM * the same, below also.
25847836SJohn.Forte@Sun.COM */
25857836SJohn.Forte@Sun.COM if ((strlen(ctag_arg) > 0) &&
25867836SJohn.Forte@Sun.COM (strcmp(ctag_arg, ctag) != 0)) {
25877836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("ctags "
25887836SJohn.Forte@Sun.COM "%s and %s do not match "),
25897836SJohn.Forte@Sun.COM ctag_arg, ctag);
25907836SJohn.Forte@Sun.COM
25917836SJohn.Forte@Sun.COM }
25927836SJohn.Forte@Sun.COM } else if (strcmp(argv[i], "q") == 0) {
2593*11576SSurya.Prakki@Sun.COM (void) strncpy(diskqueue, argv[i + 1],
25947836SJohn.Forte@Sun.COM NSC_MAXPATH);
25957836SJohn.Forte@Sun.COM if (diskqueue[NSC_MAXPATH - 1] != '\0') {
25967836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("diskq name is "
25977836SJohn.Forte@Sun.COM "longer than %d characters\n"),
25987836SJohn.Forte@Sun.COM (NSC_MAXPATH - 1));
25997836SJohn.Forte@Sun.COM }
26007836SJohn.Forte@Sun.COM } else {
26017836SJohn.Forte@Sun.COM /* Unrecognized argument */
26027836SJohn.Forte@Sun.COM usage();
26037836SJohn.Forte@Sun.COM exit(1);
26047836SJohn.Forte@Sun.COM }
26057836SJohn.Forte@Sun.COM }
26067836SJohn.Forte@Sun.COM }
26077836SJohn.Forte@Sun.COM
26087836SJohn.Forte@Sun.COM /*
26097836SJohn.Forte@Sun.COM * Are we able to determine the existance of either
26107836SJohn.Forte@Sun.COM * of these host addresses?
26117836SJohn.Forte@Sun.COM */
26127836SJohn.Forte@Sun.COM if (gethost_netaddrs(fromhost, tohost,
26137836SJohn.Forte@Sun.COM (char *)&fromnetaddr, (char *)&tonetaddr) < 0) {
26147836SJohn.Forte@Sun.COM (void) fprintf(stderr, "\n");
26157836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("unable to determine IP "
26167836SJohn.Forte@Sun.COM "addresses for either host %s or host %s"),
26177836SJohn.Forte@Sun.COM fromhost, tohost);
26187836SJohn.Forte@Sun.COM
26197836SJohn.Forte@Sun.COM if (flag != RDC_CMD_DISABLE)
26207836SJohn.Forte@Sun.COM exit(1);
26217836SJohn.Forte@Sun.COM else
26227836SJohn.Forte@Sun.COM host_not_found = 1;
26237836SJohn.Forte@Sun.COM }
26247836SJohn.Forte@Sun.COM
26257836SJohn.Forte@Sun.COM /*
26267836SJohn.Forte@Sun.COM * Are we running on neither host?
26277836SJohn.Forte@Sun.COM */
26287836SJohn.Forte@Sun.COM if (!self_check(fromhost) && !self_check(tohost)) {
26297836SJohn.Forte@Sun.COM if (flag == RDC_CMD_DISABLE) {
26307836SJohn.Forte@Sun.COM (void) fprintf(stderr, "\n");
26317836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Not running on either host "
26327836SJohn.Forte@Sun.COM "%s or host %s"), fromhost, tohost);
26337836SJohn.Forte@Sun.COM host_not_found = 1;
26347836SJohn.Forte@Sun.COM }
26357836SJohn.Forte@Sun.COM }
26367836SJohn.Forte@Sun.COM
26377836SJohn.Forte@Sun.COM /*
26387836SJohn.Forte@Sun.COM * at this point, hopfully it is safe to say that
26397836SJohn.Forte@Sun.COM * if a ctag was supplied via -C tag it is safe to
26407836SJohn.Forte@Sun.COM * move it from ctag_arg to ctag. If it was passed in
26417836SJohn.Forte@Sun.COM * at the end and the beginning of the cli, it must
26427836SJohn.Forte@Sun.COM * match, as per checks above. if it was not passed
26437836SJohn.Forte@Sun.COM * in at the end, but at the beginning, we can deal.
26447836SJohn.Forte@Sun.COM * this should handle the case of shost:svol.
26457836SJohn.Forte@Sun.COM * which is the main reason for this.
26467836SJohn.Forte@Sun.COM *
26477836SJohn.Forte@Sun.COM * there are 3 cases: passed in by cli, checked just above.
26487836SJohn.Forte@Sun.COM * using libdscfg, you must pass in -C tag to have
26497836SJohn.Forte@Sun.COM * ctag_check pass.
26507836SJohn.Forte@Sun.COM * finally a file. same rules as libdscfg.
26517836SJohn.Forte@Sun.COM */
26527836SJohn.Forte@Sun.COM if ((strlen(ctag) == 0) && (strlen(ctag_arg) > 0))
26537836SJohn.Forte@Sun.COM (void) strcpy(ctag, ctag_arg);
26547836SJohn.Forte@Sun.COM
26557836SJohn.Forte@Sun.COM if (flag == RDC_CMD_RECONFIG) {
26567836SJohn.Forte@Sun.COM if (reconfig_pbitmap) {
2657*11576SSurya.Prakki@Sun.COM (void) strncpy(frombitmap, reconfig_pbitmap,
26587836SJohn.Forte@Sun.COM NSC_MAXPATH);
26597836SJohn.Forte@Sun.COM check_rdcbitmap(flag, fromhost, frombitmap);
26607836SJohn.Forte@Sun.COM }
26617836SJohn.Forte@Sun.COM if (reconfig_sbitmap) {
2662*11576SSurya.Prakki@Sun.COM (void) strncpy(tobitmap, reconfig_sbitmap,
26637836SJohn.Forte@Sun.COM NSC_MAXPATH);
26647836SJohn.Forte@Sun.COM check_rdcbitmap(flag, tohost, tobitmap);
26657836SJohn.Forte@Sun.COM }
26667836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
26677836SJohn.Forte@Sun.COM if (reconfig_direct)
2668*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile, reconfig_direct,
26697836SJohn.Forte@Sun.COM NSC_MAXPATH);
26707836SJohn.Forte@Sun.COM #endif
26717836SJohn.Forte@Sun.COM if (reconfig_group)
2672*11576SSurya.Prakki@Sun.COM (void) strncpy(group, reconfig_group,
2673*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
26747836SJohn.Forte@Sun.COM
26757836SJohn.Forte@Sun.COM if (strlen(reconfig_ctag) > 0)
2676*11576SSurya.Prakki@Sun.COM (void) strncpy(ctag, reconfig_ctag,
26777836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
26787836SJohn.Forte@Sun.COM if (reconfig_doasync != -1)
26797836SJohn.Forte@Sun.COM doasync = reconfig_doasync;
26807836SJohn.Forte@Sun.COM }
26817836SJohn.Forte@Sun.COM
26827836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) {
26837836SJohn.Forte@Sun.COM if (ctag_check(fromhost, fromfile, frombitmap,
26847836SJohn.Forte@Sun.COM tohost, tofile, tobitmap, ctag, diskqueue) < 0)
26857836SJohn.Forte@Sun.COM exit(1);
26867836SJohn.Forte@Sun.COM if ((diskq_group = check_diskqueue(NULL, diskqueue,
26877836SJohn.Forte@Sun.COM group)) == DISKQ_FAIL) {
26887836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("disk queue %s is "
26897836SJohn.Forte@Sun.COM "incompatible with existing queue"),
26907836SJohn.Forte@Sun.COM diskqueue);
26917836SJohn.Forte@Sun.COM }
26927836SJohn.Forte@Sun.COM
26937836SJohn.Forte@Sun.COM }
26947836SJohn.Forte@Sun.COM pairs = 1;
26957836SJohn.Forte@Sun.COM } else {
26967836SJohn.Forte@Sun.COM pairs = read_config(flag, config_file, group_arg, ctag_arg);
26977836SJohn.Forte@Sun.COM if (pairs == 0) {
26987836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("%s contains no "
26997836SJohn.Forte@Sun.COM "matching Remote Mirror sets"), config_file);
27007836SJohn.Forte@Sun.COM }
27017836SJohn.Forte@Sun.COM }
27027836SJohn.Forte@Sun.COM
27037836SJohn.Forte@Sun.COM if (!nflag && !pflag && prompt_user(flag, iflag) == -1)
27047836SJohn.Forte@Sun.COM exit(1);
27057836SJohn.Forte@Sun.COM
27067836SJohn.Forte@Sun.COM while (pairs--) {
27077836SJohn.Forte@Sun.COM
27087836SJohn.Forte@Sun.COM if (cfgflag || fflag) {
2709*11576SSurya.Prakki@Sun.COM (void) strncpy(fromfile, pair_list[pairs].ffile,
2710*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
2711*11576SSurya.Prakki@Sun.COM (void) strncpy(tofile, pair_list[pairs].tfile,
2712*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
2713*11576SSurya.Prakki@Sun.COM (void) strncpy(frombitmap, pair_list[pairs].fbitmap,
2714*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
2715*11576SSurya.Prakki@Sun.COM (void) strncpy(fromhost,
2716*11576SSurya.Prakki@Sun.COM pair_list[pairs].fhost, MAX_RDC_HOST_SIZE);
2717*11576SSurya.Prakki@Sun.COM (void) strncpy(tohost, pair_list[pairs].thost,
2718*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
2719*11576SSurya.Prakki@Sun.COM (void) strncpy(tobitmap, pair_list[pairs].tbitmap,
2720*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
2721*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile, pair_list[pairs].directfile,
2722*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
2723*11576SSurya.Prakki@Sun.COM (void) strncpy(group, pair_list[pairs].group,
2724*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
2725*11576SSurya.Prakki@Sun.COM (void) strncpy(ctag, pair_list[pairs].ctag,
2726*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
2727*11576SSurya.Prakki@Sun.COM (void) strncpy(diskqueue, pair_list[pairs].diskqueue,
27287836SJohn.Forte@Sun.COM NSC_MAXPATH);
27297836SJohn.Forte@Sun.COM
27307836SJohn.Forte@Sun.COM bcopy(pair_list[pairs].fnetaddr, fromnetaddr,
2731*11576SSurya.Prakki@Sun.COM RDC_MAXADDR);
27327836SJohn.Forte@Sun.COM bcopy(pair_list[pairs].tnetaddr, tonetaddr,
2733*11576SSurya.Prakki@Sun.COM RDC_MAXADDR);
27347836SJohn.Forte@Sun.COM
27357836SJohn.Forte@Sun.COM doasync = pair_list[pairs].doasync;
27367836SJohn.Forte@Sun.COM }
27377836SJohn.Forte@Sun.COM
27387836SJohn.Forte@Sun.COM if (pflag) {
27397836SJohn.Forte@Sun.COM static int first = 1;
27407836SJohn.Forte@Sun.COM
27417836SJohn.Forte@Sun.COM if (first) {
27427836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
27437836SJohn.Forte@Sun.COM rdc_err(NULL,
27447836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
27457836SJohn.Forte@Sun.COM
27467836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
27477836SJohn.Forte@Sun.COM rdc_err(NULL,
27487836SJohn.Forte@Sun.COM gettext("unable to lock configuration"));
27497836SJohn.Forte@Sun.COM
27507836SJohn.Forte@Sun.COM first = 0;
27517836SJohn.Forte@Sun.COM }
27527836SJohn.Forte@Sun.COM
27537836SJohn.Forte@Sun.COM (void) rdc_print(file_format, verbose,
27547836SJohn.Forte@Sun.COM group_arg, ctag_arg, tohost, tofile, cfg);
27557836SJohn.Forte@Sun.COM
27567836SJohn.Forte@Sun.COM if (pairs == 0) {
27577836SJohn.Forte@Sun.COM cfg_close(cfg);
27587836SJohn.Forte@Sun.COM exit(0);
27597836SJohn.Forte@Sun.COM }
27607836SJohn.Forte@Sun.COM
27617836SJohn.Forte@Sun.COM /* short circuit the rest of the command loop */
27627836SJohn.Forte@Sun.COM continue;
27637836SJohn.Forte@Sun.COM }
27647836SJohn.Forte@Sun.COM if (Bflag) {
27657836SJohn.Forte@Sun.COM int ret;
27667836SJohn.Forte@Sun.COM ret = rdc_bitmapset(tohost, tofile, bitfile, oflag,
27677836SJohn.Forte@Sun.COM boffset);
27687836SJohn.Forte@Sun.COM exit(ret);
27697836SJohn.Forte@Sun.COM }
27707836SJohn.Forte@Sun.COM if ((fflag || cfgflag) && flag == RDC_CMD_RECONFIG) {
27717836SJohn.Forte@Sun.COM char orig_fbmp[MAXHOSTNAMELEN];
27727836SJohn.Forte@Sun.COM char orig_tbmp[MAXHOSTNAMELEN];
27737836SJohn.Forte@Sun.COM int ret;
27747836SJohn.Forte@Sun.COM rdc_config_t parms;
27757836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
27767836SJohn.Forte@Sun.COM
27777836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
27787836SJohn.Forte@Sun.COM parms.rdc_set->netconfig = NULL;
2779*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.intf, fromhost,
27807836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
2781*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.intf, tohost,
27827836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
2783*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.file, fromfile,
27847836SJohn.Forte@Sun.COM NSC_MAXPATH);
2785*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.file, tofile,
27867836SJohn.Forte@Sun.COM NSC_MAXPATH);
27877836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
27887836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
27897836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
27907836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
27917836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to get set status"
27927836SJohn.Forte@Sun.COM " before reconfig operation"));
27937836SJohn.Forte@Sun.COM }
2794*11576SSurya.Prakki@Sun.COM (void) strncpy(orig_fbmp, parms.rdc_set->primary.bitmap,
27957836SJohn.Forte@Sun.COM NSC_MAXPATH);
2796*11576SSurya.Prakki@Sun.COM (void) strncpy(orig_tbmp,
2797*11576SSurya.Prakki@Sun.COM parms.rdc_set->secondary.bitmap, NSC_MAXPATH);
27987836SJohn.Forte@Sun.COM
27997836SJohn.Forte@Sun.COM if (strncmp(orig_fbmp, frombitmap, NSC_MAXPATH) != 0)
28007836SJohn.Forte@Sun.COM check_rdcbitmap(flag, fromhost, frombitmap);
28017836SJohn.Forte@Sun.COM if (strncmp(orig_tbmp, tobitmap, NSC_MAXPATH) != 0)
28027836SJohn.Forte@Sun.COM check_rdcbitmap(flag, tohost, tobitmap);
28037836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
28047836SJohn.Forte@Sun.COM
28057836SJohn.Forte@Sun.COM }
28067836SJohn.Forte@Sun.COM /*
28077836SJohn.Forte@Sun.COM * take a peek in the config to see if
28087836SJohn.Forte@Sun.COM * the bitmap is being used elsewhere
28097836SJohn.Forte@Sun.COM */
28107836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE) {
28117836SJohn.Forte@Sun.COM struct stat stb;
28127836SJohn.Forte@Sun.COM /*
28137836SJohn.Forte@Sun.COM * just for fun, lets see if some silly person
28147836SJohn.Forte@Sun.COM * specified the same vol and bitmap
28157836SJohn.Forte@Sun.COM */
28167836SJohn.Forte@Sun.COM if ((strcmp(fromfile, frombitmap) == 0) ||
28177836SJohn.Forte@Sun.COM (strcmp(tofile, tobitmap) == 0))
28187836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("volumes and bitmaps"
28197836SJohn.Forte@Sun.COM " must not match"));
28207836SJohn.Forte@Sun.COM if (self_check(fromhost)) {
28217836SJohn.Forte@Sun.COM check_rdcbitmap(flag, fromhost, frombitmap);
28227836SJohn.Forte@Sun.COM if (stat(fromfile, &stb) != 0) {
28237836SJohn.Forte@Sun.COM rdc_err(NULL,
28247836SJohn.Forte@Sun.COM gettext("unable to access %s: %s"),
28257836SJohn.Forte@Sun.COM fromfile, strerror(errno));
28267836SJohn.Forte@Sun.COM }
28277836SJohn.Forte@Sun.COM if (!S_ISCHR(stb.st_mode)) {
28287836SJohn.Forte@Sun.COM rdc_err(NULL,
28297836SJohn.Forte@Sun.COM gettext("%s is not a character device"),
28307836SJohn.Forte@Sun.COM fromfile);
28317836SJohn.Forte@Sun.COM }
28327836SJohn.Forte@Sun.COM } else { /* on the secondary */
28337836SJohn.Forte@Sun.COM check_rdcbitmap(flag, tohost, tobitmap);
28347836SJohn.Forte@Sun.COM /* extra check for secondary vol */
28357836SJohn.Forte@Sun.COM check_rdcsecondary(tofile);
28367836SJohn.Forte@Sun.COM if (stat(tofile, &stb) != 0) {
28377836SJohn.Forte@Sun.COM rdc_err(NULL,
28387836SJohn.Forte@Sun.COM gettext("unable to access %s: %s"),
28397836SJohn.Forte@Sun.COM tofile, strerror(errno));
28407836SJohn.Forte@Sun.COM }
28417836SJohn.Forte@Sun.COM if (!S_ISCHR(stb.st_mode)) {
28427836SJohn.Forte@Sun.COM rdc_err(NULL,
28437836SJohn.Forte@Sun.COM gettext("%s is not a character device"),
28447836SJohn.Forte@Sun.COM tofile);
28457836SJohn.Forte@Sun.COM }
28467836SJohn.Forte@Sun.COM }
28477836SJohn.Forte@Sun.COM
28487836SJohn.Forte@Sun.COM }
28497836SJohn.Forte@Sun.COM
28507836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE ||
28517836SJohn.Forte@Sun.COM flag == RDC_CMD_RECONFIG) {
28527836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
28537836SJohn.Forte@Sun.COM rdc_err(NULL,
28547836SJohn.Forte@Sun.COM gettext("unable to access configuration"));
28557836SJohn.Forte@Sun.COM
28567836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK))
28577836SJohn.Forte@Sun.COM rdc_err(NULL,
28587836SJohn.Forte@Sun.COM gettext("unable to lock configuration"));
28597836SJohn.Forte@Sun.COM
28607836SJohn.Forte@Sun.COM cfg_resource(cfg, clustered ? ctag : NULL);
28617836SJohn.Forte@Sun.COM } else
28627836SJohn.Forte@Sun.COM cfg = NULL;
28637836SJohn.Forte@Sun.COM
28647836SJohn.Forte@Sun.COM if (cfg && perform_autosv() &&
28657836SJohn.Forte@Sun.COM (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE ||
28667836SJohn.Forte@Sun.COM flag == RDC_CMD_RECONFIG)) {
28677836SJohn.Forte@Sun.COM if (cfg_load_svols(cfg) < 0 ||
28687836SJohn.Forte@Sun.COM cfg_load_dsvols(cfg) < 0 ||
28697836SJohn.Forte@Sun.COM cfg_load_shadows(cfg) < 0)
28707836SJohn.Forte@Sun.COM rdc_err(NULL,
28717836SJohn.Forte@Sun.COM gettext("Unable to parse config filer"));
28727836SJohn.Forte@Sun.COM load_rdc_vols(cfg);
28737836SJohn.Forte@Sun.COM }
28747836SJohn.Forte@Sun.COM cfg_success = (cfg == NULL);
28757836SJohn.Forte@Sun.COM if (cfg && flag == RDC_CMD_ENABLE) {
28767836SJohn.Forte@Sun.COM /* Enabled, so add the set via libcfg */
28777836SJohn.Forte@Sun.COM
28787836SJohn.Forte@Sun.COM /* Build a new sndr entry and put it */
28797836SJohn.Forte@Sun.COM group_p = *group? group : place_holder;
28807836SJohn.Forte@Sun.COM diskqueue_p = *diskqueue? diskqueue : place_holder;
28817836SJohn.Forte@Sun.COM
28827836SJohn.Forte@Sun.COM if ((diskqueue_p == place_holder) &&
28837836SJohn.Forte@Sun.COM (group_p != place_holder)) {
28847836SJohn.Forte@Sun.COM get_group_diskq(cfg, group_p, diskqueue);
28857836SJohn.Forte@Sun.COM if (*diskqueue)
28867836SJohn.Forte@Sun.COM diskqueue_p = diskqueue;
28877836SJohn.Forte@Sun.COM }
28887836SJohn.Forte@Sun.COM
28897836SJohn.Forte@Sun.COM /*
28907836SJohn.Forte@Sun.COM * format in pconfig is:
28917836SJohn.Forte@Sun.COM * phost.primary.pbitmap.shost.secondary.
28927836SJohn.Forte@Sun.COM * sbitmap.type.mode.group.cnode.options.diskq
28937836SJohn.Forte@Sun.COM */
28947836SJohn.Forte@Sun.COM (void) snprintf(buf, sizeof (buf),
28957836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s %s %s - %s",
28967836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap, tohost, tofile,
28977836SJohn.Forte@Sun.COM tobitmap, directfile,
28987836SJohn.Forte@Sun.COM doasync? "async" : "sync", group_p,
28997836SJohn.Forte@Sun.COM clustered? ctag : "-", diskqueue_p);
29007836SJohn.Forte@Sun.COM
29017836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, "sndr", buf, strlen(buf)) < 0)
29027836SJohn.Forte@Sun.COM rdc_warn(NULL,
29037836SJohn.Forte@Sun.COM gettext("unable to add \"%s\" to "
29047836SJohn.Forte@Sun.COM "configuration storage: %s"),
29057836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
29067836SJohn.Forte@Sun.COM setnumber = find_setnumber_in_libcfg(cfg, clustered?
29077836SJohn.Forte@Sun.COM ctag : NULL, tohost, tofile);
29087836SJohn.Forte@Sun.COM if (setnumber < 0)
29097836SJohn.Forte@Sun.COM rdc_warn(NULL,
29107836SJohn.Forte@Sun.COM gettext("unable to add \"%s\" to "
29117836SJohn.Forte@Sun.COM "configuration storage: %s"),
29127836SJohn.Forte@Sun.COM diskqueue_p, cfg_error(&sev));
29137836SJohn.Forte@Sun.COM
29147836SJohn.Forte@Sun.COM else
29157836SJohn.Forte@Sun.COM cfg_success = 1;
29167836SJohn.Forte@Sun.COM
29177836SJohn.Forte@Sun.COM /* Add cluster aware info */
29187836SJohn.Forte@Sun.COM if (clustered && !rdc_islocal) {
29197836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
29207836SJohn.Forte@Sun.COM "sndr.set%d.options", setnumber);
29217836SJohn.Forte@Sun.COM if (self_check(fromhost)) {
29227836SJohn.Forte@Sun.COM if (cfg_put_options(cfg, CFG_SEC_CONF,
29237836SJohn.Forte@Sun.COM key, "lghn", fromhost) < 0) {
29247836SJohn.Forte@Sun.COM rdc_err(NULL,
29257836SJohn.Forte@Sun.COM gettext("unable to add "
29267836SJohn.Forte@Sun.COM "\"%s\" to configuration "
29277836SJohn.Forte@Sun.COM "storage: %s"),
29287836SJohn.Forte@Sun.COM fromhost, cfg_error(&sev));
29297836SJohn.Forte@Sun.COM }
29307836SJohn.Forte@Sun.COM } else if (self_check(tohost)) {
29317836SJohn.Forte@Sun.COM if (cfg_put_options(cfg, CFG_SEC_CONF,
29327836SJohn.Forte@Sun.COM key, "lghn", tohost) < 0) {
29337836SJohn.Forte@Sun.COM rdc_err(NULL,
29347836SJohn.Forte@Sun.COM gettext("unable to add "
29357836SJohn.Forte@Sun.COM "\"%s\" to configuration "
29367836SJohn.Forte@Sun.COM "storage: %s"),
29377836SJohn.Forte@Sun.COM fromhost, cfg_error(&sev));
29387836SJohn.Forte@Sun.COM }
29397836SJohn.Forte@Sun.COM }
29407836SJohn.Forte@Sun.COM }
29417836SJohn.Forte@Sun.COM } else if (cfg && flag == RDC_CMD_DISABLE) {
29427836SJohn.Forte@Sun.COM found = 0;
29437836SJohn.Forte@Sun.COM /* Disabled, so delete the set via libcfg */
29447836SJohn.Forte@Sun.COM
29457836SJohn.Forte@Sun.COM /* get sndr entries until shost, sfile match */
29467836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
29477836SJohn.Forte@Sun.COM setnumber = i + 1;
29487836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d",
29497836SJohn.Forte@Sun.COM setnumber);
29507836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
29517836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0) {
29527836SJohn.Forte@Sun.COM break;
29537836SJohn.Forte@Sun.COM }
29547836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
29557836SJohn.Forte@Sun.COM "sndr.set%d.secondary", setnumber);
29567836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
29577836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
29587836SJohn.Forte@Sun.COM break;
29597836SJohn.Forte@Sun.COM if (strcmp(buf, tofile) != 0)
29607836SJohn.Forte@Sun.COM continue;
29617836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
29627836SJohn.Forte@Sun.COM "sndr.set%d.shost",
29637836SJohn.Forte@Sun.COM setnumber);
29647836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
29657836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
29667836SJohn.Forte@Sun.COM break;
29677836SJohn.Forte@Sun.COM if (strcmp(buf, tohost) != 0)
29687836SJohn.Forte@Sun.COM continue;
29697836SJohn.Forte@Sun.COM found = 1;
29707836SJohn.Forte@Sun.COM #ifdef DEBUG
29717836SJohn.Forte@Sun.COM if (checksetfields == -1) {
29727836SJohn.Forte@Sun.COM rdc_err(NULL,
29737836SJohn.Forte@Sun.COM gettext("checksetfields not set"));
29747836SJohn.Forte@Sun.COM }
29757836SJohn.Forte@Sun.COM #endif
29767836SJohn.Forte@Sun.COM if (checksetfields) {
29777836SJohn.Forte@Sun.COM checkgfields(cfg, setnumber, fromhost,
29787836SJohn.Forte@Sun.COM fromfile, frombitmap, tobitmap,
29797836SJohn.Forte@Sun.COM directfile, (doasync == 1)
29807836SJohn.Forte@Sun.COM ? "async" : "sync", group, ctag,
29817836SJohn.Forte@Sun.COM diskqueue);
29827836SJohn.Forte@Sun.COM }
29837836SJohn.Forte@Sun.COM
29847836SJohn.Forte@Sun.COM /* perform cluster specific options */
29857836SJohn.Forte@Sun.COM if (clustered) {
29867836SJohn.Forte@Sun.COM /* get the logical host, if set */
29877836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
29887836SJohn.Forte@Sun.COM "sndr.set%d.options", setnumber);
29897836SJohn.Forte@Sun.COM (void) cfg_get_single_option(cfg,
29907836SJohn.Forte@Sun.COM CFG_SEC_CONF, key, "lghn",
29917836SJohn.Forte@Sun.COM lhname, MAX_RDC_HOST_SIZE);
29927836SJohn.Forte@Sun.COM
29937836SJohn.Forte@Sun.COM /* figure out the cluster tag, if any */
29947836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
29957836SJohn.Forte@Sun.COM "sndr.set%d.cnode", setnumber);
29967836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
29977836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
29987836SJohn.Forte@Sun.COM break;
29997836SJohn.Forte@Sun.COM if (strcmp(buf, ctag))
30007836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("ctags %s"
30017836SJohn.Forte@Sun.COM " and %s do not match"),
30027836SJohn.Forte@Sun.COM buf, ctag);
30037836SJohn.Forte@Sun.COM } else {
30047836SJohn.Forte@Sun.COM *lhname = '\0';
30057836SJohn.Forte@Sun.COM *ctag = '\0';
30067836SJohn.Forte@Sun.COM }
30077836SJohn.Forte@Sun.COM
30087836SJohn.Forte@Sun.COM /* figure out the disk queue, if any */
30097836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
30107836SJohn.Forte@Sun.COM "sndr.set%d.diskq",
30117836SJohn.Forte@Sun.COM setnumber);
30127836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
30137836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
30147836SJohn.Forte@Sun.COM break;
30157836SJohn.Forte@Sun.COM if (strlen(buf) > 0) {
3016*11576SSurya.Prakki@Sun.COM (void) strncpy(diskqueue, buf,
3017*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
30187836SJohn.Forte@Sun.COM } else {
30197836SJohn.Forte@Sun.COM *diskqueue = '\0';
30207836SJohn.Forte@Sun.COM }
30217836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d",
30227836SJohn.Forte@Sun.COM setnumber);
30237836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, NULL, 0) < 0)
30247836SJohn.Forte@Sun.COM rdc_warn(NULL,
30257836SJohn.Forte@Sun.COM gettext("unable to remove \"%s\" "
30267836SJohn.Forte@Sun.COM "from configuration storage: %s"),
30277836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
30287836SJohn.Forte@Sun.COM else
30297836SJohn.Forte@Sun.COM cfg_success = 1;
30307836SJohn.Forte@Sun.COM break;
30317836SJohn.Forte@Sun.COM }
30327836SJohn.Forte@Sun.COM if (found == 0) {
30337836SJohn.Forte@Sun.COM rdc_err(NULL,
30347836SJohn.Forte@Sun.COM gettext("Unable to find %s:%s in "
30357836SJohn.Forte@Sun.COM "configuration storage"),
30367836SJohn.Forte@Sun.COM tohost, tofile);
30377836SJohn.Forte@Sun.COM }
30387836SJohn.Forte@Sun.COM if (host_not_found) {
30397836SJohn.Forte@Sun.COM rdc_force_disable(cfg, fromhost, fromfile,
30407836SJohn.Forte@Sun.COM frombitmap, tohost, tofile, tobitmap, ctag,
30417836SJohn.Forte@Sun.COM lhname);
30427836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0)
30437836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("commit on "
30447836SJohn.Forte@Sun.COM "force disable failed"));
30457836SJohn.Forte@Sun.COM cfg_close(cfg);
30467836SJohn.Forte@Sun.COM return (0);
30477836SJohn.Forte@Sun.COM }
30487836SJohn.Forte@Sun.COM } else if (cfg && flag == RDC_CMD_RECONFIG) {
30497836SJohn.Forte@Sun.COM /* Update relevant cfg record */
30507836SJohn.Forte@Sun.COM
30517836SJohn.Forte@Sun.COM cfg_resource(cfg, NULL);
30527836SJohn.Forte@Sun.COM
30537836SJohn.Forte@Sun.COM /* get sndr entries until shost, sfile match */
30547836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
30557836SJohn.Forte@Sun.COM setnumber = i + 1;
30567836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d",
30577836SJohn.Forte@Sun.COM setnumber);
30587836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
30597836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0) {
30607836SJohn.Forte@Sun.COM break;
30617836SJohn.Forte@Sun.COM }
30627836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
30637836SJohn.Forte@Sun.COM "sndr.set%d.secondary", setnumber);
30647836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
30657836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
30667836SJohn.Forte@Sun.COM break;
30677836SJohn.Forte@Sun.COM if (strcmp(buf, tofile) != 0)
30687836SJohn.Forte@Sun.COM continue;
30697836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
30707836SJohn.Forte@Sun.COM "sndr.set%d.shost",
30717836SJohn.Forte@Sun.COM setnumber);
30727836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
30737836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
30747836SJohn.Forte@Sun.COM break;
30757836SJohn.Forte@Sun.COM if (strcmp(buf, tohost) != 0)
30767836SJohn.Forte@Sun.COM continue;
30777836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
30787836SJohn.Forte@Sun.COM "sndr.set%d.cnode",
30797836SJohn.Forte@Sun.COM setnumber);
30807836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
30817836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
30827836SJohn.Forte@Sun.COM break;
30837836SJohn.Forte@Sun.COM if (reconfig_ctag[0] == '\0')
3084*11576SSurya.Prakki@Sun.COM (void) strncpy(ctag, buf,
3085*11576SSurya.Prakki@Sun.COM sizeof (ctag));
30867836SJohn.Forte@Sun.COM if (doasync)
3087*11576SSurya.Prakki@Sun.COM (void) strcpy(mode, "async");
30887836SJohn.Forte@Sun.COM else
3089*11576SSurya.Prakki@Sun.COM (void) strcpy(mode, "sync");
30907836SJohn.Forte@Sun.COM if (strcmp(directfile, "") == 0)
3091*11576SSurya.Prakki@Sun.COM (void) strcpy(directfile, "ip");
30927836SJohn.Forte@Sun.COM
30937836SJohn.Forte@Sun.COM group_p = strlen(group) > 0 ? group :
30947836SJohn.Forte@Sun.COM place_holder;
30957836SJohn.Forte@Sun.COM
30967836SJohn.Forte@Sun.COM /*
30977836SJohn.Forte@Sun.COM * if we are reconfigging out altogether,
30987836SJohn.Forte@Sun.COM * get rid of the diskqueue
30997836SJohn.Forte@Sun.COM */
31007836SJohn.Forte@Sun.COM if (group_p == place_holder)
31017836SJohn.Forte@Sun.COM diskqueue_p = place_holder;
31027836SJohn.Forte@Sun.COM else
31037836SJohn.Forte@Sun.COM diskqueue_p = strlen(diskqueue) > 0 ?
31047836SJohn.Forte@Sun.COM diskqueue : place_holder;
31057836SJohn.Forte@Sun.COM
31067836SJohn.Forte@Sun.COM /*
31077836SJohn.Forte@Sun.COM * do a little diskq dance here for reconfigs
31087836SJohn.Forte@Sun.COM * that did not specify the diskqueue whilst
31097836SJohn.Forte@Sun.COM * reconfigging ...
31107836SJohn.Forte@Sun.COM */
31117836SJohn.Forte@Sun.COM if ((diskqueue_p == place_holder) &&
31127836SJohn.Forte@Sun.COM (group_p != place_holder)) {
31137836SJohn.Forte@Sun.COM get_group_diskq(cfg, group_p,
31147836SJohn.Forte@Sun.COM diskqueue);
31157836SJohn.Forte@Sun.COM diskqueue_p = strlen(diskqueue) > 0 ?
31167836SJohn.Forte@Sun.COM diskqueue : place_holder;
31177836SJohn.Forte@Sun.COM }
31187836SJohn.Forte@Sun.COM
31197836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
31207836SJohn.Forte@Sun.COM "sndr.set%d.options", setnumber);
31217836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, options_cfg,
31227836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0) {
31237836SJohn.Forte@Sun.COM break;
31247836SJohn.Forte@Sun.COM }
31257836SJohn.Forte@Sun.COM
31267836SJohn.Forte@Sun.COM ctag_p = strlen(ctag) > 0 ?
31277836SJohn.Forte@Sun.COM ctag : place_holder;
31287836SJohn.Forte@Sun.COM (void) snprintf(buf, sizeof (buf),
31297836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s %s %s %s %s",
31307836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
31317836SJohn.Forte@Sun.COM tohost, tofile, tobitmap,
31327836SJohn.Forte@Sun.COM directfile, mode, group_p,
31337836SJohn.Forte@Sun.COM ctag_p, options_cfg, diskqueue_p);
31347836SJohn.Forte@Sun.COM
31357836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d",
31367836SJohn.Forte@Sun.COM setnumber);
31377836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, buf,
31387836SJohn.Forte@Sun.COM strlen(buf)) < 0)
31397836SJohn.Forte@Sun.COM rdc_warn(NULL,
31407836SJohn.Forte@Sun.COM gettext("unable to update \"%s\" "
31417836SJohn.Forte@Sun.COM "in configuration storage: %s"),
31427836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
31437836SJohn.Forte@Sun.COM else
31447836SJohn.Forte@Sun.COM cfg_success = 1;
31457836SJohn.Forte@Sun.COM break;
31467836SJohn.Forte@Sun.COM }
31477836SJohn.Forte@Sun.COM }
31487836SJohn.Forte@Sun.COM
31497836SJohn.Forte@Sun.COM if (cfg_success) {
31507836SJohn.Forte@Sun.COM if (cfg && perform_autosv()) {
31517836SJohn.Forte@Sun.COM if (self_check(fromhost)) {
31527836SJohn.Forte@Sun.COM if (diskqueue[0] &&
31537836SJohn.Forte@Sun.COM (strcmp(diskqueue, fromfile) == 0) ||
31547836SJohn.Forte@Sun.COM (strcmp(diskqueue, frombitmap) == 0)) {
31557836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("disk "
31567836SJohn.Forte@Sun.COM "queue volume %s must not "
31577836SJohn.Forte@Sun.COM "match any primary Remote "
31587836SJohn.Forte@Sun.COM "Mirror volume or bitmap"),
31597836SJohn.Forte@Sun.COM diskqueue);
31607836SJohn.Forte@Sun.COM }
31617836SJohn.Forte@Sun.COM
31627836SJohn.Forte@Sun.COM if (diskqueue[0]) {
31637836SJohn.Forte@Sun.COM different_devs(fromfile, diskqueue);
31647836SJohn.Forte@Sun.COM different_devs(frombitmap, diskqueue);
31657836SJohn.Forte@Sun.COM validate_name(cfg, diskqueue);
31667836SJohn.Forte@Sun.COM }
31677836SJohn.Forte@Sun.COM different_devs(fromfile, frombitmap);
31687836SJohn.Forte@Sun.COM validate_name(cfg, fromfile);
31697836SJohn.Forte@Sun.COM validate_name(cfg, frombitmap);
31707836SJohn.Forte@Sun.COM } else {
31717836SJohn.Forte@Sun.COM different_devs(tofile, tobitmap);
31727836SJohn.Forte@Sun.COM validate_name(cfg, tofile);
31737836SJohn.Forte@Sun.COM validate_name(cfg, tobitmap);
31747836SJohn.Forte@Sun.COM }
31757836SJohn.Forte@Sun.COM }
31767836SJohn.Forte@Sun.COM /*
31777836SJohn.Forte@Sun.COM * okay, if the command is sync, just build
31787836SJohn.Forte@Sun.COM * a list of rdcconfig_t's after the pairs--
31797836SJohn.Forte@Sun.COM * loop is done, we will pass this list to
31807836SJohn.Forte@Sun.COM * librdc to multithread the syncs (after
31817836SJohn.Forte@Sun.COM * forking off a daemonish type process
31827836SJohn.Forte@Sun.COM * that waits for the libcall to complete
31837836SJohn.Forte@Sun.COM * ints of interest:
31847836SJohn.Forte@Sun.COM * flag ie RDC_CMD_COPY, iflag RDC_OPT_UPDATE,
31857836SJohn.Forte@Sun.COM * reverse RDC_OPT_REVERSE, RDC_OPT_FORWARD
31867836SJohn.Forte@Sun.COM * if necessary, turn autosync back on
31877836SJohn.Forte@Sun.COM */
31887836SJohn.Forte@Sun.COM if (flag == RDC_CMD_COPY) {
31897836SJohn.Forte@Sun.COM if (autosync_is_on(tohost, tofile) ==
31907836SJohn.Forte@Sun.COM AUTOSYNC_ON)
31917836SJohn.Forte@Sun.COM enable_autosync(fromhost, fromfile,
31927836SJohn.Forte@Sun.COM tohost, tofile);
31937836SJohn.Forte@Sun.COM
31947836SJohn.Forte@Sun.COM if (sets == NULL) {
31957836SJohn.Forte@Sun.COM sets_p = sets =
31967836SJohn.Forte@Sun.COM rdc_alloc_config(fromhost, fromfile,
31977836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
31987836SJohn.Forte@Sun.COM tobitmap, "mode", "group", "ctag",
31997836SJohn.Forte@Sun.COM "options", 0);
32007836SJohn.Forte@Sun.COM
32017836SJohn.Forte@Sun.COM if (sets_p == NULL) {
32027836SJohn.Forte@Sun.COM rdc_err(NULL,
32037836SJohn.Forte@Sun.COM gettext("rdc config alloc"
32047836SJohn.Forte@Sun.COM "failed %s"), rdc_error(NULL));
32057836SJohn.Forte@Sun.COM }
32067836SJohn.Forte@Sun.COM continue;
32077836SJohn.Forte@Sun.COM }
32087836SJohn.Forte@Sun.COM
32097836SJohn.Forte@Sun.COM sets_p = sets_p->next =
32107836SJohn.Forte@Sun.COM rdc_alloc_config(fromhost, fromfile,
32117836SJohn.Forte@Sun.COM frombitmap, tohost, tofile, tobitmap,
32127836SJohn.Forte@Sun.COM "mode", "group", "ctag", "options", 0);
32137836SJohn.Forte@Sun.COM
32147836SJohn.Forte@Sun.COM if (sets_p == NULL) {
32157836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("rdc config alloc"
32167836SJohn.Forte@Sun.COM "failed %s"), rdc_error(NULL));
32177836SJohn.Forte@Sun.COM }
32187836SJohn.Forte@Sun.COM continue;
32197836SJohn.Forte@Sun.COM }
32207836SJohn.Forte@Sun.COM
32217836SJohn.Forte@Sun.COM /*
32227836SJohn.Forte@Sun.COM * block incoming signals until after the possible
32237836SJohn.Forte@Sun.COM * cfg_commit is done
32247836SJohn.Forte@Sun.COM */
32257836SJohn.Forte@Sun.COM block_sigs();
32267836SJohn.Forte@Sun.COM if (rdc_operation(cfg, fromhost, fromfile, frombitmap,
32277836SJohn.Forte@Sun.COM tohost, tofile, tobitmap, flag, iflag, directfile,
32287836SJohn.Forte@Sun.COM group, ctag, diskqueue, &doasync, reverse) < 0) {
32297836SJohn.Forte@Sun.COM ;
32307836SJohn.Forte@Sun.COM /*EMPTY*/
32317836SJohn.Forte@Sun.COM } else if (cfg) {
32327836SJohn.Forte@Sun.COM if (diskq_group == DISKQ_REWRITEG) {
32337836SJohn.Forte@Sun.COM rewrite_group_diskqueue(cfg,
32347836SJohn.Forte@Sun.COM &pair_list[pairs], diskqueue);
32357836SJohn.Forte@Sun.COM }
32367836SJohn.Forte@Sun.COM if (perform_autosv() &&
32377836SJohn.Forte@Sun.COM (flag == RDC_CMD_ENABLE ||
32387836SJohn.Forte@Sun.COM flag == RDC_CMD_DISABLE ||
32397836SJohn.Forte@Sun.COM flag == RDC_CMD_RECONFIG)) {
32407836SJohn.Forte@Sun.COM unload_rdc_vols();
32417836SJohn.Forte@Sun.COM cfg_unload_shadows();
32427836SJohn.Forte@Sun.COM cfg_unload_dsvols();
32437836SJohn.Forte@Sun.COM cfg_unload_svols();
32447836SJohn.Forte@Sun.COM }
32457836SJohn.Forte@Sun.COM if ((iflag & RDC_OPT_REVERSE_ROLE) != 0 &&
32467836SJohn.Forte@Sun.COM allow_role) {
32477836SJohn.Forte@Sun.COM bzero(tmphost, MAX_RDC_HOST_SIZE);
32487836SJohn.Forte@Sun.COM bzero(tmpfile, NSC_MAXPATH);
32497836SJohn.Forte@Sun.COM bzero(tmpbitmap, NSC_MAXPATH);
3250*11576SSurya.Prakki@Sun.COM (void) strncpy(tmphost, fromhost,
32517836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
3252*11576SSurya.Prakki@Sun.COM (void) strncpy(tmpfile, fromfile,
3253*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
3254*11576SSurya.Prakki@Sun.COM (void) strncpy(tmpbitmap, frombitmap,
3255*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
3256*11576SSurya.Prakki@Sun.COM
3257*11576SSurya.Prakki@Sun.COM (void) strncpy(fromhost, tohost,
3258*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
3259*11576SSurya.Prakki@Sun.COM (void) strncpy(fromfile, tofile,
3260*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
3261*11576SSurya.Prakki@Sun.COM (void) strncpy(frombitmap, tobitmap,
3262*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
3263*11576SSurya.Prakki@Sun.COM
3264*11576SSurya.Prakki@Sun.COM (void) strncpy(tohost, tmphost,
3265*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
3266*11576SSurya.Prakki@Sun.COM (void) strncpy(tofile, tmpfile,
3267*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
3268*11576SSurya.Prakki@Sun.COM (void) strncpy(tobitmap, tmpbitmap,
3269*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
32707836SJohn.Forte@Sun.COM group_p = strlen(group) > 0 ? group :
32717836SJohn.Forte@Sun.COM place_holder;
32727836SJohn.Forte@Sun.COM diskqueue_p = strlen(diskqueue) > 0 ?
32737836SJohn.Forte@Sun.COM diskqueue : place_holder;
32747836SJohn.Forte@Sun.COM ctag_p = strlen(ctag) > 0 ?
32757836SJohn.Forte@Sun.COM ctag : place_holder;
32767836SJohn.Forte@Sun.COM (void) snprintf(buf, sizeof (buf), "%s "
32777836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s %s %s %s",
32787836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
32797836SJohn.Forte@Sun.COM tohost, tofile, tobitmap,
32807836SJohn.Forte@Sun.COM directfile, mode, group_p,
32817836SJohn.Forte@Sun.COM ctag_p, options_cfg, diskqueue_p);
32827836SJohn.Forte@Sun.COM
32837836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
32847836SJohn.Forte@Sun.COM "sndr.set%d", setnumber);
32857836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, buf,
32867836SJohn.Forte@Sun.COM strlen(buf)) < 0)
32877836SJohn.Forte@Sun.COM rdc_err(NULL,
32887836SJohn.Forte@Sun.COM gettext("unable to update \"%s\" "
32897836SJohn.Forte@Sun.COM "in configuration storage: %s"),
32907836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
32917836SJohn.Forte@Sun.COM }
32927836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0) {
32937836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("commit on role "
32947836SJohn.Forte@Sun.COM "reversal failed"));
32957836SJohn.Forte@Sun.COM }
32967836SJohn.Forte@Sun.COM }
32977836SJohn.Forte@Sun.COM unblock_sigs();
32987836SJohn.Forte@Sun.COM }
32997836SJohn.Forte@Sun.COM
33007836SJohn.Forte@Sun.COM if (cfg) {
33017836SJohn.Forte@Sun.COM cfg_close(cfg);
33027836SJohn.Forte@Sun.COM }
33037836SJohn.Forte@Sun.COM
33047836SJohn.Forte@Sun.COM }
33057836SJohn.Forte@Sun.COM if (flag == RDC_CMD_COPY) {
33067836SJohn.Forte@Sun.COM pid = fork();
33077836SJohn.Forte@Sun.COM if (pid == -1) { /* error forking */
33087836SJohn.Forte@Sun.COM perror("fork");
33097836SJohn.Forte@Sun.COM exit(1);
33107836SJohn.Forte@Sun.COM }
33117836SJohn.Forte@Sun.COM } else {
33127836SJohn.Forte@Sun.COM exit(0);
33137836SJohn.Forte@Sun.COM }
33147836SJohn.Forte@Sun.COM if (pid > 0) /* parent process */
33157836SJohn.Forte@Sun.COM exit(0);
33167836SJohn.Forte@Sun.COM
33177836SJohn.Forte@Sun.COM spcslog_sync(sets, 1, iflag);
33187836SJohn.Forte@Sun.COM if (iflag & RDC_OPT_REVERSE) {
33197836SJohn.Forte@Sun.COM if (iflag & RDC_OPT_UPDATE)
33207836SJohn.Forte@Sun.COM rclist = rdc_ursync(sets);
33217836SJohn.Forte@Sun.COM else
33227836SJohn.Forte@Sun.COM rclist = rdc_rsync(sets);
33237836SJohn.Forte@Sun.COM } else if (iflag & RDC_OPT_UPDATE) {
33247836SJohn.Forte@Sun.COM rclist = rdc_usync(sets);
33257836SJohn.Forte@Sun.COM } else
33267836SJohn.Forte@Sun.COM rclist = rdc_fsync(sets);
33277836SJohn.Forte@Sun.COM
33287836SJohn.Forte@Sun.COM rcp = rclist;
33297836SJohn.Forte@Sun.COM while (rcp) {
33307836SJohn.Forte@Sun.COM if (rcp->rc < 0) {
33317836SJohn.Forte@Sun.COM /* rclist->msg has already been gettext'd */
33327836SJohn.Forte@Sun.COM (void) fprintf(stderr,
33337836SJohn.Forte@Sun.COM gettext("Remote Mirror: %s %s %s %s %s %s\n"),
33347836SJohn.Forte@Sun.COM rcp->set.phost, rcp->set.pfile, rcp->set.pbmp,
33357836SJohn.Forte@Sun.COM rcp->set.shost, rcp->set.sfile, rcp->set.sbmp);
33367836SJohn.Forte@Sun.COM rdc_warn(NULL, "%s", rcp->msg);
33377836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, "%s", rcp->msg);
33387836SJohn.Forte@Sun.COM }
33397836SJohn.Forte@Sun.COM rcp = rcp->next;
33407836SJohn.Forte@Sun.COM }
33417836SJohn.Forte@Sun.COM
33427836SJohn.Forte@Sun.COM spcslog_sync(sets, 0, iflag);
33437836SJohn.Forte@Sun.COM
33447836SJohn.Forte@Sun.COM if (sets)
33457836SJohn.Forte@Sun.COM rdc_free_config(sets, RDC_FREEALL);
33467836SJohn.Forte@Sun.COM if (rclist)
33477836SJohn.Forte@Sun.COM rdc_free_rclist(rclist);
33487836SJohn.Forte@Sun.COM
33497836SJohn.Forte@Sun.COM return (0);
33507836SJohn.Forte@Sun.COM }
33517836SJohn.Forte@Sun.COM /*
33527836SJohn.Forte@Sun.COM * process_clocal()
33537836SJohn.Forte@Sun.COM * pre: a non null string
33547836SJohn.Forte@Sun.COM * post: if the string is "local"
33557836SJohn.Forte@Sun.COM * then it is converted to "-"
33567836SJohn.Forte@Sun.COM * and rdc_islocal is set to 1
33577836SJohn.Forte@Sun.COM * if not rdc_islocal set to 0
33587836SJohn.Forte@Sun.COM */
33597836SJohn.Forte@Sun.COM void
33607836SJohn.Forte@Sun.COM process_clocal(char *ctag)
33617836SJohn.Forte@Sun.COM {
33627836SJohn.Forte@Sun.COM /*
33637836SJohn.Forte@Sun.COM * Check for the special cluster tag and convert into the
33647836SJohn.Forte@Sun.COM * internal representation.
33657836SJohn.Forte@Sun.COM */
33667836SJohn.Forte@Sun.COM
33677836SJohn.Forte@Sun.COM if (ctag != NULL && strcmp(ctag, RDC_LOCAL_TAG) == 0) {
3368*11576SSurya.Prakki@Sun.COM (void) strcpy(ctag, "-");
33697836SJohn.Forte@Sun.COM rdc_islocal = 1;
33707836SJohn.Forte@Sun.COM } else {
33717836SJohn.Forte@Sun.COM rdc_islocal = 0;
33727836SJohn.Forte@Sun.COM }
33737836SJohn.Forte@Sun.COM }
33747836SJohn.Forte@Sun.COM
33757836SJohn.Forte@Sun.COM static void
33767836SJohn.Forte@Sun.COM rdc_check_dgislocal(char *dgname)
33777836SJohn.Forte@Sun.COM {
33787836SJohn.Forte@Sun.COM char *othernode;
33797836SJohn.Forte@Sun.COM int rc;
33807836SJohn.Forte@Sun.COM
33817836SJohn.Forte@Sun.COM /*
33827836SJohn.Forte@Sun.COM * check where this disk service is mastered
33837836SJohn.Forte@Sun.COM */
33847836SJohn.Forte@Sun.COM
33857836SJohn.Forte@Sun.COM rc = cfg_dgname_islocal(dgname, &othernode);
33867836SJohn.Forte@Sun.COM if (rc < 0) {
33877836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to find "
33887836SJohn.Forte@Sun.COM "disk service, %s: %s"), dgname, strerror(errno));
33897836SJohn.Forte@Sun.COM }
33907836SJohn.Forte@Sun.COM
33917836SJohn.Forte@Sun.COM if (rc == 0) {
33927836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("disk service, %s, is "
33937836SJohn.Forte@Sun.COM "active on node \"%s\"\nPlease re-issue "
33947836SJohn.Forte@Sun.COM "the command on that node"), dgname, othernode);
33957836SJohn.Forte@Sun.COM }
33967836SJohn.Forte@Sun.COM }
33977836SJohn.Forte@Sun.COM
33987836SJohn.Forte@Sun.COM static void
33997836SJohn.Forte@Sun.COM different_devs(char *dev1, char *dev2)
34007836SJohn.Forte@Sun.COM {
34017836SJohn.Forte@Sun.COM struct stat buf1, buf2;
34027836SJohn.Forte@Sun.COM
34037836SJohn.Forte@Sun.COM if (stat(dev1, &buf1) < 0) {
34047836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"),
34057836SJohn.Forte@Sun.COM dev1);
34067836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev1);
34077836SJohn.Forte@Sun.COM }
34087836SJohn.Forte@Sun.COM if (stat(dev2, &buf2) < 0) {
34097836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"),
34107836SJohn.Forte@Sun.COM dev2);
34117836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev2);
34127836SJohn.Forte@Sun.COM }
34137836SJohn.Forte@Sun.COM if (buf1.st_rdev == buf2.st_rdev) {
34147836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: '%s' and '%s' "
34157836SJohn.Forte@Sun.COM "refer to the same device"), dev1, dev2);
34167836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror: '%s' and '%s' refer to "
34177836SJohn.Forte@Sun.COM "the same device"), dev1, dev2);
34187836SJohn.Forte@Sun.COM }
34197836SJohn.Forte@Sun.COM }
34207836SJohn.Forte@Sun.COM
34217836SJohn.Forte@Sun.COM static void
34227836SJohn.Forte@Sun.COM validate_name(CFGFILE *cfg, char *vol)
34237836SJohn.Forte@Sun.COM {
34247836SJohn.Forte@Sun.COM char *altname;
34257836SJohn.Forte@Sun.COM int rc;
34267836SJohn.Forte@Sun.COM
34277836SJohn.Forte@Sun.COM if (!cfg) {
34287836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror: null cfg ptr in "
34297836SJohn.Forte@Sun.COM "validate_name"));
34307836SJohn.Forte@Sun.COM }
34317836SJohn.Forte@Sun.COM
34327836SJohn.Forte@Sun.COM rc = cfg_get_canonical_name(cfg, vol, &altname);
34337836SJohn.Forte@Sun.COM if (rc < 0) {
34347836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: unable to parse "
34357836SJohn.Forte@Sun.COM "config file\n"));
34367836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror: unable to parse config "
34377836SJohn.Forte@Sun.COM "file\n"));
34387836SJohn.Forte@Sun.COM }
34397836SJohn.Forte@Sun.COM if (rc) {
34407836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("Remote Mirror: '%s': already "
34417836SJohn.Forte@Sun.COM "configured as '%s'"), vol, altname);
34427836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("Remote Mirror: The volume '%s' has been "
34437836SJohn.Forte@Sun.COM "configured previously as '%s'. Re-enter command with "
34447836SJohn.Forte@Sun.COM "the latter name."), vol, altname);
34457836SJohn.Forte@Sun.COM }
34467836SJohn.Forte@Sun.COM }
34477836SJohn.Forte@Sun.COM
34487836SJohn.Forte@Sun.COM /*
34497836SJohn.Forte@Sun.COM * Add the autosync value to the option field for the sndr set specified by
34507836SJohn.Forte@Sun.COM * tohost:tofile.
34517836SJohn.Forte@Sun.COM *
34527836SJohn.Forte@Sun.COM * ASSUMPTIONS:
34537836SJohn.Forte@Sun.COM * - cfg file is available to take a write lock.
34547836SJohn.Forte@Sun.COM * - set is already configured in dscfg
34557836SJohn.Forte@Sun.COM *
34567836SJohn.Forte@Sun.COM * INPUTS:
34577836SJohn.Forte@Sun.COM * autosync_val - value to set autosync to
34587836SJohn.Forte@Sun.COM * tohost - secondary host
34597836SJohn.Forte@Sun.COM * tofile - secondary volume
34607836SJohn.Forte@Sun.COM *
34617836SJohn.Forte@Sun.COM * OUTPUTS:
34627836SJohn.Forte@Sun.COM * none.
34637836SJohn.Forte@Sun.COM *
34647836SJohn.Forte@Sun.COM */
34657836SJohn.Forte@Sun.COM static void
34667836SJohn.Forte@Sun.COM set_autosync(int autosync_val, char *tohost, char *tofile, char *ctag)
34677836SJohn.Forte@Sun.COM {
34687836SJohn.Forte@Sun.COM CFGFILE *cfg;
34697836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
34707836SJohn.Forte@Sun.COM char tag[CFG_MAX_BUF], val[CFG_MAX_BUF];
34717836SJohn.Forte@Sun.COM char auto_tag[CFG_MAX_BUF];
34727836SJohn.Forte@Sun.COM _sd_dual_pair_t pair;
34737836SJohn.Forte@Sun.COM _sd_dual_pair_t tmpair;
34747836SJohn.Forte@Sun.COM int setnumber, options = 0, already_set = 0, cfg_success = 0;
34757836SJohn.Forte@Sun.COM int set;
34767836SJohn.Forte@Sun.COM
34777836SJohn.Forte@Sun.COM /* verify valid autosync request */
34787836SJohn.Forte@Sun.COM if ((autosync_val != AUTOSYNC_ON) && (autosync_val != AUTOSYNC_OFF)) {
34797836SJohn.Forte@Sun.COM #ifdef DEBUG
34807836SJohn.Forte@Sun.COM rdc_warn(NULL,
34817836SJohn.Forte@Sun.COM gettext("set_autosync called with improper value"));
34827836SJohn.Forte@Sun.COM #endif
34837836SJohn.Forte@Sun.COM return;
34847836SJohn.Forte@Sun.COM }
34857836SJohn.Forte@Sun.COM
34867836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
34877836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to access configuration"));
34887836SJohn.Forte@Sun.COM }
34897836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK)) {
34907836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
34917836SJohn.Forte@Sun.COM }
34927836SJohn.Forte@Sun.COM
34937836SJohn.Forte@Sun.COM if (clustered) {
34947836SJohn.Forte@Sun.COM cfg_resource(cfg, ctag);
34957836SJohn.Forte@Sun.COM } else {
34967836SJohn.Forte@Sun.COM cfg_resource(cfg, NULL);
34977836SJohn.Forte@Sun.COM }
34987836SJohn.Forte@Sun.COM
34997836SJohn.Forte@Sun.COM /* find set number in config */
35007836SJohn.Forte@Sun.COM if ((setnumber = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL,
35017836SJohn.Forte@Sun.COM tohost, tofile)) < 0) {
35027836SJohn.Forte@Sun.COM cfg_close(cfg);
35037836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to find Remote Mirror set %s:%s: "
35047836SJohn.Forte@Sun.COM "in config"), tohost, tofile);
35057836SJohn.Forte@Sun.COM }
35067836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.options", setnumber);
35077836SJohn.Forte@Sun.COM (void) snprintf(auto_tag, sizeof (auto_tag), "auto");
35087836SJohn.Forte@Sun.COM
35097836SJohn.Forte@Sun.COM /* Check if there are any options already set, including ours */
35107836SJohn.Forte@Sun.COM if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val,
35117836SJohn.Forte@Sun.COM CFG_MAX_BUF) >= 0) {
35127836SJohn.Forte@Sun.COM options = 1;
35137836SJohn.Forte@Sun.COM
35147836SJohn.Forte@Sun.COM do {
35157836SJohn.Forte@Sun.COM if (strcmp(tag, auto_tag) == 0) {
35167836SJohn.Forte@Sun.COM already_set = 1;
35177836SJohn.Forte@Sun.COM }
35187836SJohn.Forte@Sun.COM } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag,
35197836SJohn.Forte@Sun.COM CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0);
35207836SJohn.Forte@Sun.COM }
35217836SJohn.Forte@Sun.COM
35227836SJohn.Forte@Sun.COM /* options already exist, edit ours out */
35237836SJohn.Forte@Sun.COM if (options && already_set) {
35247836SJohn.Forte@Sun.COM char *p, *q;
35257836SJohn.Forte@Sun.COM int need_to_clear_buf = 1;
35267836SJohn.Forte@Sun.COM
35277836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
35287836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to get options field "
35297836SJohn.Forte@Sun.COM "for Remote Mirror set %s:%s"), tohost, tofile);
35307836SJohn.Forte@Sun.COM }
35317836SJohn.Forte@Sun.COM
35327836SJohn.Forte@Sun.COM /* parse out our options, all of the form "auto=" */
35337836SJohn.Forte@Sun.COM p = strdup(buf);
35347836SJohn.Forte@Sun.COM bzero(buf, sizeof (buf));
35357836SJohn.Forte@Sun.COM
35367836SJohn.Forte@Sun.COM q = strtok(p, ";");
35377836SJohn.Forte@Sun.COM do {
35387836SJohn.Forte@Sun.COM /* if another tag/value exists, keep it */
35397836SJohn.Forte@Sun.COM if (strncmp(auto_tag, q, 4) != 0) {
3540*11576SSurya.Prakki@Sun.COM (void) strcat(buf, q);
3541*11576SSurya.Prakki@Sun.COM (void) strcat(buf, ";");
35427836SJohn.Forte@Sun.COM need_to_clear_buf = 0;
35437836SJohn.Forte@Sun.COM }
35447836SJohn.Forte@Sun.COM } while (q = strtok(NULL, ";"));
35457836SJohn.Forte@Sun.COM free(p);
35467836SJohn.Forte@Sun.COM
35477836SJohn.Forte@Sun.COM /* if we were the only option, clear the field */
35487836SJohn.Forte@Sun.COM if (need_to_clear_buf) {
3549*11576SSurya.Prakki@Sun.COM (void) strcat(buf, "-");
35507836SJohn.Forte@Sun.COM }
35517836SJohn.Forte@Sun.COM
35527836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
35537836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to clear autosync value "
35547836SJohn.Forte@Sun.COM "in config for Remote Mirror set %s:%s"), tohost,
35557836SJohn.Forte@Sun.COM tofile);
35567836SJohn.Forte@Sun.COM } else {
35577836SJohn.Forte@Sun.COM cfg_success = 1;
35587836SJohn.Forte@Sun.COM }
35597836SJohn.Forte@Sun.COM }
35607836SJohn.Forte@Sun.COM
35617836SJohn.Forte@Sun.COM /* autosync is not present in options field, add if on is requested */
35627836SJohn.Forte@Sun.COM if (autosync_val == AUTOSYNC_ON) {
35637836SJohn.Forte@Sun.COM if (cfg_put_options(cfg, CFG_SEC_CONF, key, auto_tag, "on")
35647836SJohn.Forte@Sun.COM < 0) {
35657836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to update autosync value "
35667836SJohn.Forte@Sun.COM "in config for Remote Mirror set %s:%s"), tohost,
35677836SJohn.Forte@Sun.COM tofile);
35687836SJohn.Forte@Sun.COM } else {
35697836SJohn.Forte@Sun.COM cfg_success = 1;
35707836SJohn.Forte@Sun.COM }
35717836SJohn.Forte@Sun.COM }
35727836SJohn.Forte@Sun.COM /* if we are in a group, update any other sets in the same group */
35737836SJohn.Forte@Sun.COM do {
35747836SJohn.Forte@Sun.COM bzero(&pair, sizeof (pair));
35757836SJohn.Forte@Sun.COM bzero(buf, CFG_MAX_BUF);
35767836SJohn.Forte@Sun.COM
35777836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
35787836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
35797836SJohn.Forte@Sun.COM break;
35807836SJohn.Forte@Sun.COM }
35817836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &pair, NULL))
35827836SJohn.Forte@Sun.COM break;
35837836SJohn.Forte@Sun.COM if (pair.group == NULL) /* not in a group */
35847836SJohn.Forte@Sun.COM break;
35857836SJohn.Forte@Sun.COM if (!pair.group[0])
35867836SJohn.Forte@Sun.COM break; /* not in a group */
35877836SJohn.Forte@Sun.COM for (set = 1; /*CSTYLED*/; set++) {
35887836SJohn.Forte@Sun.COM if (set == setnumber)
35897836SJohn.Forte@Sun.COM continue;
35907836SJohn.Forte@Sun.COM bzero(buf, CFG_MAX_BUF);
35917836SJohn.Forte@Sun.COM options = 0;
35927836SJohn.Forte@Sun.COM already_set = 0;
35937836SJohn.Forte@Sun.COM
35947836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d", set);
35957836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
35967836SJohn.Forte@Sun.COM break; /* last set processed */
35977836SJohn.Forte@Sun.COM }
35987836SJohn.Forte@Sun.COM bzero(&tmpair, sizeof (tmpair));
35997836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &tmpair, NULL))
36007836SJohn.Forte@Sun.COM break;
36017836SJohn.Forte@Sun.COM if (strcmp(pair.group, tmpair.group) != 0)
36027836SJohn.Forte@Sun.COM continue; /* not the group we want */
36037836SJohn.Forte@Sun.COM
36047836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.options",
36057836SJohn.Forte@Sun.COM set);
36067836SJohn.Forte@Sun.COM /*
36077836SJohn.Forte@Sun.COM * Check if there are any options already set,
36087836SJohn.Forte@Sun.COM * including ours
36097836SJohn.Forte@Sun.COM */
36107836SJohn.Forte@Sun.COM if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag,
36117836SJohn.Forte@Sun.COM CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0) {
36127836SJohn.Forte@Sun.COM options = 1;
36137836SJohn.Forte@Sun.COM
36147836SJohn.Forte@Sun.COM do {
36157836SJohn.Forte@Sun.COM if (strcmp(tag, auto_tag) == 0) {
36167836SJohn.Forte@Sun.COM already_set = 1;
36177836SJohn.Forte@Sun.COM }
36187836SJohn.Forte@Sun.COM } while (cfg_get_options(cfg, CFG_SEC_CONF,
36197836SJohn.Forte@Sun.COM NULL, tag, CFG_MAX_BUF, val,
36207836SJohn.Forte@Sun.COM CFG_MAX_BUF) >= 0);
36217836SJohn.Forte@Sun.COM }
36227836SJohn.Forte@Sun.COM
36237836SJohn.Forte@Sun.COM /* options already exist, edit ours out */
36247836SJohn.Forte@Sun.COM if (options && already_set) {
36257836SJohn.Forte@Sun.COM char *p, *q;
36267836SJohn.Forte@Sun.COM int need_to_clear_buf = 1;
36277836SJohn.Forte@Sun.COM
36287836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)
36297836SJohn.Forte@Sun.COM < 0) {
36307836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to get "
36317836SJohn.Forte@Sun.COM "options field for Remote Mirror set "
36327836SJohn.Forte@Sun.COM "%s:%s"), tmpair.thost, tmpair.tfile);
36337836SJohn.Forte@Sun.COM }
36347836SJohn.Forte@Sun.COM
36357836SJohn.Forte@Sun.COM /*
36367836SJohn.Forte@Sun.COM * parse out our options, all of the
36377836SJohn.Forte@Sun.COM * form "auto="
36387836SJohn.Forte@Sun.COM */
36397836SJohn.Forte@Sun.COM p = strdup(buf);
36407836SJohn.Forte@Sun.COM bzero(buf, sizeof (buf));
36417836SJohn.Forte@Sun.COM
36427836SJohn.Forte@Sun.COM q = strtok(p, ";");
36437836SJohn.Forte@Sun.COM do {
36447836SJohn.Forte@Sun.COM /*
36457836SJohn.Forte@Sun.COM * if another tag/value exists,
36467836SJohn.Forte@Sun.COM * keep it
36477836SJohn.Forte@Sun.COM */
36487836SJohn.Forte@Sun.COM if (strncmp(auto_tag, q, 4) != 0) {
3649*11576SSurya.Prakki@Sun.COM (void) strcat(buf, q);
3650*11576SSurya.Prakki@Sun.COM (void) strcat(buf, ";");
36517836SJohn.Forte@Sun.COM need_to_clear_buf = 0;
36527836SJohn.Forte@Sun.COM }
36537836SJohn.Forte@Sun.COM } while (q = strtok(NULL, ";"));
36547836SJohn.Forte@Sun.COM free(p);
36557836SJohn.Forte@Sun.COM
36567836SJohn.Forte@Sun.COM /*
36577836SJohn.Forte@Sun.COM * if we were the only option,
36587836SJohn.Forte@Sun.COM * clear the field
36597836SJohn.Forte@Sun.COM */
36607836SJohn.Forte@Sun.COM if (need_to_clear_buf) {
3661*11576SSurya.Prakki@Sun.COM (void) strcat(buf, "-");
36627836SJohn.Forte@Sun.COM }
36637836SJohn.Forte@Sun.COM
36647836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF)
36657836SJohn.Forte@Sun.COM < 0) {
36667836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to clear "
36677836SJohn.Forte@Sun.COM "autosync value in config for "
36687836SJohn.Forte@Sun.COM "Remote Mirror set %s:%s"),
36697836SJohn.Forte@Sun.COM tmpair.thost, tmpair.tfile);
36707836SJohn.Forte@Sun.COM cfg_success = 0;
36717836SJohn.Forte@Sun.COM }
36727836SJohn.Forte@Sun.COM }
36737836SJohn.Forte@Sun.COM
36747836SJohn.Forte@Sun.COM /*
36757836SJohn.Forte@Sun.COM * autosync is not present in options field,
36767836SJohn.Forte@Sun.COM * add if on is requested
36777836SJohn.Forte@Sun.COM */
36787836SJohn.Forte@Sun.COM if (autosync_val == AUTOSYNC_ON) {
36797836SJohn.Forte@Sun.COM if (cfg_put_options(cfg, CFG_SEC_CONF, key,
36807836SJohn.Forte@Sun.COM auto_tag, "on") < 0) {
36817836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to update"
36827836SJohn.Forte@Sun.COM " autosync value in config for "
36837836SJohn.Forte@Sun.COM "Remote Mirror set %s:%s"),
36847836SJohn.Forte@Sun.COM tmpair.thost,
36857836SJohn.Forte@Sun.COM tmpair.tfile);
36867836SJohn.Forte@Sun.COM cfg_success = 0;
36877836SJohn.Forte@Sun.COM }
36887836SJohn.Forte@Sun.COM }
36897836SJohn.Forte@Sun.COM }
36907836SJohn.Forte@Sun.COM
36917836SJohn.Forte@Sun.COM /* CONSTCOND */
36927836SJohn.Forte@Sun.COM } while (0);
36937836SJohn.Forte@Sun.COM if (cfg_success) {
36947836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0) {
36957836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("commit on role reversal failed"));
36967836SJohn.Forte@Sun.COM }
36977836SJohn.Forte@Sun.COM }
36987836SJohn.Forte@Sun.COM
36997836SJohn.Forte@Sun.COM cfg_close(cfg);
37007836SJohn.Forte@Sun.COM }
37017836SJohn.Forte@Sun.COM
37027836SJohn.Forte@Sun.COM /*
37037836SJohn.Forte@Sun.COM * Check to see if autosync is on for set specified by tohost:tofile.
37047836SJohn.Forte@Sun.COM *
37057836SJohn.Forte@Sun.COM * ASSUMPTIONS:
37067836SJohn.Forte@Sun.COM * config is available to take a read lock against it.
37077836SJohn.Forte@Sun.COM *
37087836SJohn.Forte@Sun.COM * INPUTS:
37097836SJohn.Forte@Sun.COM * tohost - secondary host
37107836SJohn.Forte@Sun.COM * tofile - secondary volume
37117836SJohn.Forte@Sun.COM *
37127836SJohn.Forte@Sun.COM * OUTPUTS:
37137836SJohn.Forte@Sun.COM * -1 error
37147836SJohn.Forte@Sun.COM * AUTOSYNC_ON if autosync is on
37157836SJohn.Forte@Sun.COM * AUTOSYNC_OFF if autosync is off
37167836SJohn.Forte@Sun.COM */
37177836SJohn.Forte@Sun.COM static int
37187836SJohn.Forte@Sun.COM autosync_is_on(char *tohost, char *tofile)
37197836SJohn.Forte@Sun.COM {
37207836SJohn.Forte@Sun.COM CFGFILE *cfg;
37217836SJohn.Forte@Sun.COM int setnumber, autosync_val = AUTOSYNC_OFF;
37227836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
37237836SJohn.Forte@Sun.COM char tag[CFG_MAX_BUF], val[CFG_MAX_BUF];
37247836SJohn.Forte@Sun.COM
37257836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
37267836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to access configuration"));
37277836SJohn.Forte@Sun.COM }
37287836SJohn.Forte@Sun.COM
37297836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK)) {
37307836SJohn.Forte@Sun.COM cfg_close(cfg);
37317836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
37327836SJohn.Forte@Sun.COM }
37337836SJohn.Forte@Sun.COM
37347836SJohn.Forte@Sun.COM if ((setnumber = find_setnumber_in_libcfg(cfg, NULL, tohost, tofile)) <
37357836SJohn.Forte@Sun.COM 0) {
37367836SJohn.Forte@Sun.COM cfg_close(cfg);
37377836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cannot find Remote Mirror set %s:%s in "
37387836SJohn.Forte@Sun.COM "config"), tohost, tofile);
37397836SJohn.Forte@Sun.COM }
37407836SJohn.Forte@Sun.COM
37417836SJohn.Forte@Sun.COM (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d.options", setnumber);
37427836SJohn.Forte@Sun.COM if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val,
37437836SJohn.Forte@Sun.COM CFG_MAX_BUF) >= 0) {
37447836SJohn.Forte@Sun.COM do {
37457836SJohn.Forte@Sun.COM if (strcmp(tag, "auto") == 0) {
37467836SJohn.Forte@Sun.COM if (strcmp(val, "on") == 0) {
37477836SJohn.Forte@Sun.COM autosync_val = AUTOSYNC_ON;
37487836SJohn.Forte@Sun.COM }
37497836SJohn.Forte@Sun.COM break;
37507836SJohn.Forte@Sun.COM }
37517836SJohn.Forte@Sun.COM } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag,
37527836SJohn.Forte@Sun.COM CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0);
37537836SJohn.Forte@Sun.COM }
37547836SJohn.Forte@Sun.COM
37557836SJohn.Forte@Sun.COM cfg_close(cfg);
37567836SJohn.Forte@Sun.COM return (autosync_val);
37577836SJohn.Forte@Sun.COM }
37587836SJohn.Forte@Sun.COM
37597836SJohn.Forte@Sun.COM void
37607836SJohn.Forte@Sun.COM enable_autosync(char *fhost, char *ffile, char *thost, char *tfile)
37617836SJohn.Forte@Sun.COM {
37627836SJohn.Forte@Sun.COM rdc_config_t parms;
37637836SJohn.Forte@Sun.COM spcs_s_info_t ustat;
37647836SJohn.Forte@Sun.COM rdc_addr_t *p;
37657836SJohn.Forte@Sun.COM
37667836SJohn.Forte@Sun.COM ustat = spcs_s_ucreate();
37677836SJohn.Forte@Sun.COM parms.command = RDC_CMD_TUNABLE;
37687836SJohn.Forte@Sun.COM
37697836SJohn.Forte@Sun.COM p = &parms.rdc_set[0].primary;
3770*11576SSurya.Prakki@Sun.COM (void) strncpy(p->intf, fhost, MAX_RDC_HOST_SIZE);
3771*11576SSurya.Prakki@Sun.COM (void) strncpy(p->file, ffile, MAX_RDC_HOST_SIZE);
37727836SJohn.Forte@Sun.COM
37737836SJohn.Forte@Sun.COM p = &parms.rdc_set[0].secondary;
3774*11576SSurya.Prakki@Sun.COM (void) strncpy(p->intf, thost, NSC_MAXPATH);
3775*11576SSurya.Prakki@Sun.COM (void) strncpy(p->file, tfile, NSC_MAXPATH);
37767836SJohn.Forte@Sun.COM
37777836SJohn.Forte@Sun.COM parms.rdc_set[0].autosync = 1;
37787836SJohn.Forte@Sun.COM parms.rdc_set[0].maxqfbas = -1;
37797836SJohn.Forte@Sun.COM parms.rdc_set[0].maxqitems = -1;
37807836SJohn.Forte@Sun.COM parms.rdc_set[0].asyncthr = -1;
37817836SJohn.Forte@Sun.COM parms.rdc_set[0].netconfig = NULL;
37827836SJohn.Forte@Sun.COM
37837836SJohn.Forte@Sun.COM if ((RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustat)) !=
37847836SJohn.Forte@Sun.COM SPCS_S_OK) {
37857836SJohn.Forte@Sun.COM rdc_warn(&ustat, gettext("failed to update autosync for"
37867836SJohn.Forte@Sun.COM " Remote Mirror set %s:%s"), thost, tfile);
37877836SJohn.Forte@Sun.COM spcs_log("sndr", &ustat, gettext("failed to update autosync for"
37887836SJohn.Forte@Sun.COM " Remote Mirror set %s:%s"), thost, tfile);
37897836SJohn.Forte@Sun.COM }
37907836SJohn.Forte@Sun.COM spcs_s_ufree(&ustat);
37917836SJohn.Forte@Sun.COM }
37927836SJohn.Forte@Sun.COM
37937836SJohn.Forte@Sun.COM static int
37947836SJohn.Forte@Sun.COM rdc_operation(CFGFILE *cfg, char *fromhost, char *fromfile, char *frombitmap,
37957836SJohn.Forte@Sun.COM char *tohost, char *tofile, char *tobitmap,
37967836SJohn.Forte@Sun.COM int flag, int iflag,
37977836SJohn.Forte@Sun.COM char *directfile, char *group, char *ctag, char *diskqueue,
37987836SJohn.Forte@Sun.COM int *doasync, int reverse)
37997836SJohn.Forte@Sun.COM {
38007836SJohn.Forte@Sun.COM const int getaddr = (flag == RDC_CMD_ENABLE);
38017836SJohn.Forte@Sun.COM const int rpcbind = !getaddr;
38027836SJohn.Forte@Sun.COM rdc_config_t parms;
38037836SJohn.Forte@Sun.COM int ret;
38047836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
38057836SJohn.Forte@Sun.COM struct hostent *hp;
38067836SJohn.Forte@Sun.COM char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
38077836SJohn.Forte@Sun.COM char orig_fbmp[MAXHOSTNAMELEN], orig_tbmp[MAXHOSTNAMELEN];
38087836SJohn.Forte@Sun.COM char orig_diskq[NSC_MAXPATH];
38097836SJohn.Forte@Sun.COM struct t_info tinfo;
38107836SJohn.Forte@Sun.COM int success = 1;
38117836SJohn.Forte@Sun.COM int autosync_toggle_needed = 0;
38127836SJohn.Forte@Sun.COM char *vol1, *vol2, *vol3;
38137836SJohn.Forte@Sun.COM
38147836SJohn.Forte@Sun.COM conf = &nconf;
38157836SJohn.Forte@Sun.COM
38167836SJohn.Forte@Sun.COM hp = gethost_byname(fromhost);
3817*11576SSurya.Prakki@Sun.COM (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
38187836SJohn.Forte@Sun.COM hp = gethost_byname(tohost);
3819*11576SSurya.Prakki@Sun.COM (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
38207836SJohn.Forte@Sun.COM
38217836SJohn.Forte@Sun.COM if (self_check(fromname) && self_check(toname)) {
38227836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("both %s and %s are local"),
38237836SJohn.Forte@Sun.COM fromhost, tohost);
38247836SJohn.Forte@Sun.COM }
38257836SJohn.Forte@Sun.COM
38267836SJohn.Forte@Sun.COM /* we have to find out what to sv disable after reconfig */
38277836SJohn.Forte@Sun.COM if (flag == RDC_CMD_RECONFIG) {
38287836SJohn.Forte@Sun.COM
38297836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
38307836SJohn.Forte@Sun.COM parms.rdc_set->netconfig = NULL;
3831*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.intf, fromhost,
38327836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
3833*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.intf, tohost,
38347836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
3835*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.file, fromfile,
38367836SJohn.Forte@Sun.COM NSC_MAXPATH);
3837*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.file, tofile,
38387836SJohn.Forte@Sun.COM NSC_MAXPATH);
38397836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
38407836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
38417836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
38427836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
38437836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to get set status"
38447836SJohn.Forte@Sun.COM " before reconfig operation"));
38457836SJohn.Forte@Sun.COM }
3846*11576SSurya.Prakki@Sun.COM (void) strncpy(orig_fbmp, parms.rdc_set->primary.bitmap,
38477836SJohn.Forte@Sun.COM NSC_MAXPATH);
3848*11576SSurya.Prakki@Sun.COM (void) strncpy(orig_tbmp, parms.rdc_set->secondary.bitmap,
38497836SJohn.Forte@Sun.COM NSC_MAXPATH);
3850*11576SSurya.Prakki@Sun.COM (void) strncpy(orig_diskq, parms.rdc_set->disk_queue,
3851*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
38527836SJohn.Forte@Sun.COM }
38537836SJohn.Forte@Sun.COM
38547836SJohn.Forte@Sun.COM /*
38557836SJohn.Forte@Sun.COM * another terrible addition, if we are reconfigging mode
38567836SJohn.Forte@Sun.COM * and not logging, just give up.
38577836SJohn.Forte@Sun.COM */
38587836SJohn.Forte@Sun.COM if ((reconfig_doasync != -1) &&
38597836SJohn.Forte@Sun.COM (!(parms.rdc_set->flags & RDC_LOGGING))) {
38607836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cannot reconfigure sync/async, "
38617836SJohn.Forte@Sun.COM "Remote Mirror set not logging"));
38627836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("cannot reconfigure sync/async, "
38637836SJohn.Forte@Sun.COM "Remote Mirror set not logging"));
38647836SJohn.Forte@Sun.COM }
38657836SJohn.Forte@Sun.COM
38667836SJohn.Forte@Sun.COM /*
38677836SJohn.Forte@Sun.COM * Now build up the address for each host including port and transport
38687836SJohn.Forte@Sun.COM */
38697836SJohn.Forte@Sun.COM if (getaddr) {
38707836SJohn.Forte@Sun.COM svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
38717836SJohn.Forte@Sun.COM &conf, proto_test ? NC_UDP:NULL, "rdc", &tinfo,
38727836SJohn.Forte@Sun.COM rpcbind);
38737836SJohn.Forte@Sun.COM
38747836SJohn.Forte@Sun.COM if (svp == NULL) {
38757836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("unable to determine network "
38767836SJohn.Forte@Sun.COM "information for %s"), toname);
38777836SJohn.Forte@Sun.COM #ifdef DEBUG
38787836SJohn.Forte@Sun.COM (void) printf("get_addr failed for Ver 4 %s\n", toname);
38797836SJohn.Forte@Sun.COM #endif
38807836SJohn.Forte@Sun.COM return (-1);
38817836SJohn.Forte@Sun.COM }
38827836SJohn.Forte@Sun.COM svaddr = *svp;
38837836SJohn.Forte@Sun.COM } else {
38847836SJohn.Forte@Sun.COM bzero(&svaddr, sizeof (svaddr));
38857836SJohn.Forte@Sun.COM }
38867836SJohn.Forte@Sun.COM
38877836SJohn.Forte@Sun.COM parms.rdc_set->secondary.addr.len = svaddr.len;
38887836SJohn.Forte@Sun.COM parms.rdc_set->secondary.addr.maxlen =
38897836SJohn.Forte@Sun.COM svaddr.maxlen;
38907836SJohn.Forte@Sun.COM parms.rdc_set->secondary.addr.buf =
38917836SJohn.Forte@Sun.COM (void *)svaddr.buf;
38927836SJohn.Forte@Sun.COM
38937836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
38947836SJohn.Forte@Sun.COM (void) fprintf(stderr, "secondary buf %x len %d\n",
38957836SJohn.Forte@Sun.COM svaddr.buf, svaddr.len);
38967836SJohn.Forte@Sun.COM
38977836SJohn.Forte@Sun.COM for (i = 0; i < svaddr.len; i++)
38987836SJohn.Forte@Sun.COM (void) printf("%u ", svaddr.buf[i]);
38997836SJohn.Forte@Sun.COM (void) printf("\n");
39007836SJohn.Forte@Sun.COM #endif
39017836SJohn.Forte@Sun.COM
39027836SJohn.Forte@Sun.COM if (getaddr) {
39037836SJohn.Forte@Sun.COM svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
39047836SJohn.Forte@Sun.COM &conf, proto_test ? NC_UDP: NULL, "rdc", &tinfo,
39057836SJohn.Forte@Sun.COM rpcbind);
39067836SJohn.Forte@Sun.COM if (svp == NULL) {
39077836SJohn.Forte@Sun.COM #ifdef DEBUG
39087836SJohn.Forte@Sun.COM (void) printf("get_addr failed for Ver 4 %s\n",
39097836SJohn.Forte@Sun.COM fromname);
39107836SJohn.Forte@Sun.COM #endif
39117836SJohn.Forte@Sun.COM return (-1);
39127836SJohn.Forte@Sun.COM }
39137836SJohn.Forte@Sun.COM svaddr = *svp;
39147836SJohn.Forte@Sun.COM }
39157836SJohn.Forte@Sun.COM
39167836SJohn.Forte@Sun.COM parms.rdc_set->primary.addr.len = svaddr.len;
39177836SJohn.Forte@Sun.COM parms.rdc_set->primary.addr.maxlen = svaddr.maxlen;
39187836SJohn.Forte@Sun.COM parms.rdc_set->primary.addr.buf = (void *)svaddr.buf;
39197836SJohn.Forte@Sun.COM
39207836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
39217836SJohn.Forte@Sun.COM (void) fprintf(stderr, "primary buf %x len %d\n",
39227836SJohn.Forte@Sun.COM svaddr.buf, svaddr.len);
39237836SJohn.Forte@Sun.COM for (i = 0; i < svaddr.len; i++)
39247836SJohn.Forte@Sun.COM (void) printf("%u ", svaddr.buf[i]);
39257836SJohn.Forte@Sun.COM (void) printf("\n");
39267836SJohn.Forte@Sun.COM #endif
39277836SJohn.Forte@Sun.COM
39287836SJohn.Forte@Sun.COM if (getaddr) {
39297836SJohn.Forte@Sun.COM (void) convert_nconf_to_knconf(conf, &knconf);
39307836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
39317836SJohn.Forte@Sun.COM (void) printf("knconf %x %s %s %x\n", knconf.knc_semantics,
39327836SJohn.Forte@Sun.COM knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev);
39337836SJohn.Forte@Sun.COM #endif
39347836SJohn.Forte@Sun.COM parms.rdc_set->netconfig = &knconf;
39357836SJohn.Forte@Sun.COM } else {
39367836SJohn.Forte@Sun.COM parms.rdc_set->netconfig = NULL;
39377836SJohn.Forte@Sun.COM }
39387836SJohn.Forte@Sun.COM
39397836SJohn.Forte@Sun.COM if (!self_check(fromname) && !self_check(toname)) {
39407836SJohn.Forte@Sun.COM if (!clustered)
39417836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("neither %s nor %s is local"),
39427836SJohn.Forte@Sun.COM fromhost, tohost);
39437836SJohn.Forte@Sun.COM else {
39447836SJohn.Forte@Sun.COM /*
39457836SJohn.Forte@Sun.COM * IF we could get a list of logical hosts on this cluster
39467836SJohn.Forte@Sun.COM * Then we could print something intelligent about where
39477836SJohn.Forte@Sun.COM * the volume is mastered. For now, just print some babble
39487836SJohn.Forte@Sun.COM * about the fact that we have no idea.
39497836SJohn.Forte@Sun.COM */
39507836SJohn.Forte@Sun.COM rdc_err(NULL,
39517836SJohn.Forte@Sun.COM gettext("either %s:%s or %s:%s is not local"),
39527836SJohn.Forte@Sun.COM fromhost, fromfile, tohost, tofile);
39537836SJohn.Forte@Sun.COM }
39547836SJohn.Forte@Sun.COM }
39557836SJohn.Forte@Sun.COM
3956*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.intf, fromhost,
3957*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
3958*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH);
3959*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH);
3960*11576SSurya.Prakki@Sun.COM
3961*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.intf, tohost,
3962*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
3963*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH);
3964*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH);
39657836SJohn.Forte@Sun.COM
39667836SJohn.Forte@Sun.COM if ((group == NULL) || ((strcmp(group, "-")) == 0))
39677836SJohn.Forte@Sun.COM parms.rdc_set->group_name[0] = 0;
39687836SJohn.Forte@Sun.COM else
3969*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH);
39707836SJohn.Forte@Sun.COM
39717836SJohn.Forte@Sun.COM if (self_check(tohost) &&
39727836SJohn.Forte@Sun.COM (strlen(diskqueue) > 0) && (diskqueue[0] != '-'))
39737836SJohn.Forte@Sun.COM if ((flag == RDC_CMD_ENABLE) || (flag == RDC_CMD_ADDQ))
39747836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("enabling disk queue on a Remote"
39757836SJohn.Forte@Sun.COM " Mirror secondary is not allowed (%s)"),
39767836SJohn.Forte@Sun.COM diskqueue);
39777836SJohn.Forte@Sun.COM
39787836SJohn.Forte@Sun.COM if ((diskqueue == NULL) || ((strcmp(diskqueue, "-")) == 0))
39797836SJohn.Forte@Sun.COM parms.rdc_set->disk_queue[0] = 0;
39807836SJohn.Forte@Sun.COM else
3981*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->disk_queue, diskqueue,
3982*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
39837836SJohn.Forte@Sun.COM
39847836SJohn.Forte@Sun.COM parms.rdc_set->maxqfbas = maxqfbas;
39857836SJohn.Forte@Sun.COM parms.rdc_set->maxqitems = maxqitems;
39867836SJohn.Forte@Sun.COM parms.rdc_set->asyncthr = asyncthr;
39877836SJohn.Forte@Sun.COM /* set up the permanent set id for this set */
39887836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE) {
39897836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
39907836SJohn.Forte@Sun.COM char setid[64];
39917836SJohn.Forte@Sun.COM int set;
39927836SJohn.Forte@Sun.COM parms.rdc_set->setid = get_new_cfg_setid(cfg);
39937836SJohn.Forte@Sun.COM if (parms.rdc_set->setid <= 0) {
39947836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to obtain unique set id "
39957836SJohn.Forte@Sun.COM "for %s:%s"), tohost, tofile);
39967836SJohn.Forte@Sun.COM }
39977836SJohn.Forte@Sun.COM if ((set = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL,
39987836SJohn.Forte@Sun.COM tohost, tofile)) < 0) {
39997836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to store unique set id"
40007836SJohn.Forte@Sun.COM " for %s:%s"), tohost, tofile);
40017836SJohn.Forte@Sun.COM }
40027836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.options", set);
40037836SJohn.Forte@Sun.COM (void) snprintf(setid, sizeof (setid), "%d",
40047836SJohn.Forte@Sun.COM parms.rdc_set->setid);
40057836SJohn.Forte@Sun.COM
40067836SJohn.Forte@Sun.COM if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid",
40077836SJohn.Forte@Sun.COM setid) < 0) {
40087836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to store unique set "
40097836SJohn.Forte@Sun.COM "id for %s:%s: %s"), tohost, tofile,
40107836SJohn.Forte@Sun.COM gettext(cfg_error(NULL)));
40117836SJohn.Forte@Sun.COM }
40127836SJohn.Forte@Sun.COM } else if (flag != RDC_CMD_DISABLE) { /* set already gone from cfg */
40137836SJohn.Forte@Sun.COM parms.rdc_set->setid = get_cfg_setid(cfg, ctag, tohost, tofile);
40147836SJohn.Forte@Sun.COM if (parms.rdc_set->setid <= 0) {
40157836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to obtain unique set id "
40167836SJohn.Forte@Sun.COM "for %s:%s"), tohost, tofile);
40177836SJohn.Forte@Sun.COM }
40187836SJohn.Forte@Sun.COM }
40197836SJohn.Forte@Sun.COM
40207836SJohn.Forte@Sun.COM /*
40217836SJohn.Forte@Sun.COM * Always set autosync flag to default so nothing gets messed up. If
40227836SJohn.Forte@Sun.COM * we are doing an autosync operation, it'll all get taken care of
40237836SJohn.Forte@Sun.COM * then.
40247836SJohn.Forte@Sun.COM */
40257836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC;
40267836SJohn.Forte@Sun.COM
40277836SJohn.Forte@Sun.COM
40287836SJohn.Forte@Sun.COM /* gethostid(3c) is defined to return a 32bit value */
40297836SJohn.Forte@Sun.COM parms.rdc_set->syshostid = (int32_t)gethostid();
40307836SJohn.Forte@Sun.COM
40317836SJohn.Forte@Sun.COM parms.command = 0;
40327836SJohn.Forte@Sun.COM parms.options = iflag;
40337836SJohn.Forte@Sun.COM parms.command = flag;
40347836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) {
40357836SJohn.Forte@Sun.COM if (*doasync)
40367836SJohn.Forte@Sun.COM parms.options |= RDC_OPT_ASYNC;
40377836SJohn.Forte@Sun.COM else
40387836SJohn.Forte@Sun.COM parms.options |= RDC_OPT_SYNC;
40397836SJohn.Forte@Sun.COM } else if (flag == RDC_CMD_COPY) {
40407836SJohn.Forte@Sun.COM if (reverse)
40417836SJohn.Forte@Sun.COM parms.options |= RDC_OPT_REVERSE;
40427836SJohn.Forte@Sun.COM else
40437836SJohn.Forte@Sun.COM parms.options |= RDC_OPT_FORWARD;
40447836SJohn.Forte@Sun.COM }
40457836SJohn.Forte@Sun.COM
40467836SJohn.Forte@Sun.COM if (self_check(fromname)) {
40477836SJohn.Forte@Sun.COM if (flag == RDC_CMD_COPY && reverse && mounted(fromfile))
40487836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not start reverse sync"
40497836SJohn.Forte@Sun.COM " as a file system is mounted on %s"),
40507836SJohn.Forte@Sun.COM fromfile);
40517836SJohn.Forte@Sun.COM parms.options |= RDC_OPT_PRIMARY;
40527836SJohn.Forte@Sun.COM if (strcmp(directfile, "ip") == 0)
40537836SJohn.Forte@Sun.COM parms.rdc_set->direct_file[0] = 0; /* no directfile */
40547836SJohn.Forte@Sun.COM else
4055*11576SSurya.Prakki@Sun.COM (void) strncpy(parms.rdc_set->direct_file, directfile,
40567836SJohn.Forte@Sun.COM NSC_MAXPATH);
40577836SJohn.Forte@Sun.COM } else {
40587836SJohn.Forte@Sun.COM parms.options |= RDC_OPT_SECONDARY;
40597836SJohn.Forte@Sun.COM parms.rdc_set->direct_file[0] = 0; /* no fcal directio */
40607836SJohn.Forte@Sun.COM }
40617836SJohn.Forte@Sun.COM
40627836SJohn.Forte@Sun.COM if ((asyncthr || maxqitems || maxqfbas || qblock) &&
40637836SJohn.Forte@Sun.COM (parms.options & RDC_OPT_SECONDARY)) {
40647836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("changing queue parameters may "
40657836SJohn.Forte@Sun.COM " only be done on a primary Remote Mirror host"));
40667836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("changing queue parameters may "
40677836SJohn.Forte@Sun.COM " only be done on a primary Remote Mirror host"));
40687836SJohn.Forte@Sun.COM
40697836SJohn.Forte@Sun.COM }
40707836SJohn.Forte@Sun.COM
40717836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
40727836SJohn.Forte@Sun.COM
40737836SJohn.Forte@Sun.COM if (flag == RDC_CMD_COPY) {
40747836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
40757836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
40767836SJohn.Forte@Sun.COM if ((ret != SPCS_S_OK) ||
40777836SJohn.Forte@Sun.COM !(parms.rdc_set->flags & RDC_LOGGING)) {
40787836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not start sync"
40797836SJohn.Forte@Sun.COM " as Remote Mirror set %s:%s is not logging"),
40807836SJohn.Forte@Sun.COM tohost, tofile);
40817836SJohn.Forte@Sun.COM }
40827836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
40837836SJohn.Forte@Sun.COM gettext("%s %s %s %s %s %s %s %s\nStarting"),
40847836SJohn.Forte@Sun.COM program, rdc_decode_flag(flag, parms.options),
40857836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
40867836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
40877836SJohn.Forte@Sun.COM parms.command = RDC_CMD_COPY;
40887836SJohn.Forte@Sun.COM }
40897836SJohn.Forte@Sun.COM
40907836SJohn.Forte@Sun.COM if ((flag == RDC_CMD_COPY) &&
40917836SJohn.Forte@Sun.COM (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) {
40927836SJohn.Forte@Sun.COM /* check if autosync needs to be turned on when doing a copy/update */
40937836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC_ON;
40947836SJohn.Forte@Sun.COM autosync_toggle_needed = 1;
40957836SJohn.Forte@Sun.COM } else if ((flag == RDC_CMD_LOG) &&
40967836SJohn.Forte@Sun.COM (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) {
40977836SJohn.Forte@Sun.COM /* check if autosync needs to be turned off when going to logging */
40987836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC_OFF;
40997836SJohn.Forte@Sun.COM autosync_toggle_needed = 1;
41007836SJohn.Forte@Sun.COM } else if (((autosync == AUTOSYNC_ON) || (autosync == AUTOSYNC_OFF)) &&
41017836SJohn.Forte@Sun.COM (flag == RDC_CMD_TUNABLE)) {
41027836SJohn.Forte@Sun.COM /*
41037836SJohn.Forte@Sun.COM * Request to change the autosync value. cfg file will be
41047836SJohn.Forte@Sun.COM * available at this point. If autosync request is to turn off,
41057836SJohn.Forte@Sun.COM * mark off in both the config and the kernel regardless of
41067836SJohn.Forte@Sun.COM * the state of the set. If the request is to turn autosync on,
41077836SJohn.Forte@Sun.COM * set in the kernel if the set is not in logging mode.
41087836SJohn.Forte@Sun.COM *
41097836SJohn.Forte@Sun.COM * XXX
41107836SJohn.Forte@Sun.COM * If the set is in logging mode because of a network
41117836SJohn.Forte@Sun.COM * failure, we will not know. Therefore, a manual update
41127836SJohn.Forte@Sun.COM * will have to be issued to enable autosync in the
41137836SJohn.Forte@Sun.COM * kernel.
41147836SJohn.Forte@Sun.COM * XXX
41157836SJohn.Forte@Sun.COM */
41167836SJohn.Forte@Sun.COM set_autosync(autosync, tohost, tofile, ctag);
41177836SJohn.Forte@Sun.COM
41187836SJohn.Forte@Sun.COM if (autosync == AUTOSYNC_OFF) {
41197836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC_OFF;
41207836SJohn.Forte@Sun.COM } else if (autosync == AUTOSYNC_ON) {
41217836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
41227836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0,
41237836SJohn.Forte@Sun.COM ustatus);
41247836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
41257836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("can not determine "
41267836SJohn.Forte@Sun.COM "status of Remote Mirror set %s:%s"),
41277836SJohn.Forte@Sun.COM tohost, tofile);
41287836SJohn.Forte@Sun.COM }
41297836SJohn.Forte@Sun.COM
41307836SJohn.Forte@Sun.COM /* need to reset the tunables after a status ioctl */
41317836SJohn.Forte@Sun.COM parms.rdc_set->autosync = autosync;
41327836SJohn.Forte@Sun.COM parms.rdc_set->maxqfbas = maxqfbas;
41337836SJohn.Forte@Sun.COM parms.rdc_set->maxqitems = maxqitems;
41347836SJohn.Forte@Sun.COM parms.rdc_set->asyncthr = asyncthr;
41357836SJohn.Forte@Sun.COM
41367836SJohn.Forte@Sun.COM /*
41377836SJohn.Forte@Sun.COM * if in logging mode, just update config, kernel will
41387836SJohn.Forte@Sun.COM * be updated with the next copy/update request.
41397836SJohn.Forte@Sun.COM */
41407836SJohn.Forte@Sun.COM if (parms.rdc_set->flags & RDC_LOGGING) {
41417836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC;
41427836SJohn.Forte@Sun.COM } else {
41437836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC_ON;
41447836SJohn.Forte@Sun.COM }
41457836SJohn.Forte@Sun.COM
41467836SJohn.Forte@Sun.COM parms.command = flag;
41477836SJohn.Forte@Sun.COM }
41487836SJohn.Forte@Sun.COM }
41497836SJohn.Forte@Sun.COM
41507836SJohn.Forte@Sun.COM if (autosync_toggle_needed) {
41517836SJohn.Forte@Sun.COM parms.command = RDC_CMD_TUNABLE;
41527836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
41537836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
41547836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("failed to update "
41557836SJohn.Forte@Sun.COM "autosync for Remote Mirror set %s:%s"), tohost,
41567836SJohn.Forte@Sun.COM tofile);
41577836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("failed to update autosync for "
41587836SJohn.Forte@Sun.COM "Remote Mirror set %s:%s"), tohost, tofile);
41597836SJohn.Forte@Sun.COM }
41607836SJohn.Forte@Sun.COM /* reset command and default autosync flags */
41617836SJohn.Forte@Sun.COM parms.rdc_set->autosync = AUTOSYNC;
41627836SJohn.Forte@Sun.COM parms.command = flag;
41637836SJohn.Forte@Sun.COM }
41647836SJohn.Forte@Sun.COM
41657836SJohn.Forte@Sun.COM errno = 0;
41667836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
41677836SJohn.Forte@Sun.COM if ((ret != SPCS_S_OK) && (flag != RDC_CMD_HEALTH)) {
41687836SJohn.Forte@Sun.COM (void) fprintf(stderr,
41697836SJohn.Forte@Sun.COM gettext("Remote Mirror: %s %s %s %s %s %s\n"),
41707836SJohn.Forte@Sun.COM fromhost, fromfile,
41717836SJohn.Forte@Sun.COM frombitmap, tohost, tofile, tobitmap);
41727836SJohn.Forte@Sun.COM
41737836SJohn.Forte@Sun.COM if (errno == RDC_EEINVAL) {
41747836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
41757836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s\n%s",
41767836SJohn.Forte@Sun.COM program, rdc_decode_flag(flag, parms.options),
41777836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
41787836SJohn.Forte@Sun.COM tohost, tofile, tobitmap,
41797836SJohn.Forte@Sun.COM gettext("invalid command option"));
41807836SJohn.Forte@Sun.COM rdc_err(&ustatus,
41817836SJohn.Forte@Sun.COM gettext("Remote Mirror: invalid command option "
41827836SJohn.Forte@Sun.COM "'%s'"), rdc_decode_flag(flag,
41837836SJohn.Forte@Sun.COM parms.options));
41847836SJohn.Forte@Sun.COM } else {
41857836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
41867836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
41877836SJohn.Forte@Sun.COM program, rdc_decode_flag(flag, parms.options),
41887836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
41897836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
41907836SJohn.Forte@Sun.COM if ((flag == RDC_CMD_RECONFIG) &&
41917836SJohn.Forte@Sun.COM (!(iflag & RDC_OPT_REVERSE_ROLE))) {
41927836SJohn.Forte@Sun.COM success = 0;
41937836SJohn.Forte@Sun.COM rdc_warn(&ustatus, 0);
41947836SJohn.Forte@Sun.COM } else
41957836SJohn.Forte@Sun.COM rdc_err(&ustatus, 0);
41967836SJohn.Forte@Sun.COM }
41977836SJohn.Forte@Sun.COM }
41987836SJohn.Forte@Sun.COM if ((flag == RDC_CMD_RECONFIG) && (iflag & RDC_OPT_REVERSE_ROLE) == 0) {
41997836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
42007836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) ==
42017836SJohn.Forte@Sun.COM SPCS_S_OK) {
42027836SJohn.Forte@Sun.COM char shostbuf[CFG_MAX_BUF];
42037836SJohn.Forte@Sun.COM char svolbuf[CFG_MAX_BUF];
42047836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
42057836SJohn.Forte@Sun.COM int i, numels;
42067836SJohn.Forte@Sun.COM int cfgsuccess = 1;
42077836SJohn.Forte@Sun.COM
42087836SJohn.Forte@Sun.COM /*
42097836SJohn.Forte@Sun.COM * okeydoke, at this point we could have a reconfig
42107836SJohn.Forte@Sun.COM * gone bad. libdscfg does not know about this.
42117836SJohn.Forte@Sun.COM * parms contains the kernel picture, and we know
42127836SJohn.Forte@Sun.COM * what we tried to reconfig. find out where it went
42137836SJohn.Forte@Sun.COM * wrong, find the set in libdscfg, update it. We'll
42147836SJohn.Forte@Sun.COM * issue a warning, then return 0 (eventually).
42157836SJohn.Forte@Sun.COM * this will allow libdscfg to be committed with the
42167836SJohn.Forte@Sun.COM * good info. got it?
42177836SJohn.Forte@Sun.COM * BTW: the only time we can run into this multiple
42187836SJohn.Forte@Sun.COM * reconfig attempt failure is IF we reconfig from file
42197836SJohn.Forte@Sun.COM * and some thing goes wrong with one of the reconfigs
42207836SJohn.Forte@Sun.COM */
42217836SJohn.Forte@Sun.COM
42227836SJohn.Forte@Sun.COM /* find the set in libdscfg */
42237836SJohn.Forte@Sun.COM
42247836SJohn.Forte@Sun.COM numels = cfg_get_num_entries(cfg, "sndr");
42257836SJohn.Forte@Sun.COM /* yes, numels could be -1 */
42267836SJohn.Forte@Sun.COM for (i = 1; i < numels; i++) {
42277836SJohn.Forte@Sun.COM bzero(shostbuf, sizeof (shostbuf));
42287836SJohn.Forte@Sun.COM bzero(svolbuf, sizeof (svolbuf));
42297836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
42307836SJohn.Forte@Sun.COM
42317836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
42327836SJohn.Forte@Sun.COM "sndr.set%d.shost", i);
42337836SJohn.Forte@Sun.COM
42347836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, &shostbuf,
42357836SJohn.Forte@Sun.COM sizeof (shostbuf));
42367836SJohn.Forte@Sun.COM if (strncmp(shostbuf, tohost, sizeof (tohost)))
42377836SJohn.Forte@Sun.COM continue;
42387836SJohn.Forte@Sun.COM
42397836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
42407836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
42417836SJohn.Forte@Sun.COM "sndr.set%d.secondary", i);
42427836SJohn.Forte@Sun.COM (void) cfg_get_cstring(cfg, key, &svolbuf,
42437836SJohn.Forte@Sun.COM sizeof (svolbuf));
42447836SJohn.Forte@Sun.COM if (strncmp(svolbuf, tofile, NSC_MAXPATH))
42457836SJohn.Forte@Sun.COM continue;
42467836SJohn.Forte@Sun.COM break;
42477836SJohn.Forte@Sun.COM
42487836SJohn.Forte@Sun.COM /*
42497836SJohn.Forte@Sun.COM * found it, now i contains the set offset.
42507836SJohn.Forte@Sun.COM * i, being the variable, not bad english.
42517836SJohn.Forte@Sun.COM */
42527836SJohn.Forte@Sun.COM
42537836SJohn.Forte@Sun.COM }
42547836SJohn.Forte@Sun.COM /* shouldn't happen */
42557836SJohn.Forte@Sun.COM if ((numels < 1) || (i > numels)) {
42567836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("unable to retrieve "
42577836SJohn.Forte@Sun.COM "set from configuration database"));
42587836SJohn.Forte@Sun.COM /*
42597836SJohn.Forte@Sun.COM * yuck. but indents are pushing the envelope
42607836SJohn.Forte@Sun.COM * we should not be updating config
42617836SJohn.Forte@Sun.COM * if we did not find the entry
42627836SJohn.Forte@Sun.COM * the error will have to do
42637836SJohn.Forte@Sun.COM */
42647836SJohn.Forte@Sun.COM cfgsuccess = 0;
42657836SJohn.Forte@Sun.COM goto notfound;
42667836SJohn.Forte@Sun.COM }
42677836SJohn.Forte@Sun.COM
42687836SJohn.Forte@Sun.COM /*
42697836SJohn.Forte@Sun.COM * now, put all the correct names back for errors etc.
42707836SJohn.Forte@Sun.COM * also, sock them into dscfg, if the the config was a
42717836SJohn.Forte@Sun.COM * success for one, it will be a redundant but harmless
42727836SJohn.Forte@Sun.COM */
42737836SJohn.Forte@Sun.COM
42747836SJohn.Forte@Sun.COM /*
42757836SJohn.Forte@Sun.COM * we could not have reconfigged mode if we
42767836SJohn.Forte@Sun.COM * are not logging, AND the kernel CAN return
42777836SJohn.Forte@Sun.COM * sync as the status of an async set if it is
42787836SJohn.Forte@Sun.COM * currently syncing.. Hence the flags & RDC_LOGGING
42797836SJohn.Forte@Sun.COM */
42807836SJohn.Forte@Sun.COM if (parms.rdc_set->flags & RDC_LOGGING) {
42817836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
42827836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
42837836SJohn.Forte@Sun.COM "sndr.set%d.mode", i);
42847836SJohn.Forte@Sun.COM if (parms.rdc_set->flags & RDC_ASYNC) {
42857836SJohn.Forte@Sun.COM *doasync = 1;
42867836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, "async",
42877836SJohn.Forte@Sun.COM strlen("async")) < 0) {
42887836SJohn.Forte@Sun.COM cfgsuccess = 0;
42897836SJohn.Forte@Sun.COM }
42907836SJohn.Forte@Sun.COM
42917836SJohn.Forte@Sun.COM } else {
42927836SJohn.Forte@Sun.COM *doasync = 0;
42937836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, "sync",
42947836SJohn.Forte@Sun.COM strlen("sync")) < 0) {
42957836SJohn.Forte@Sun.COM cfgsuccess = 0;
42967836SJohn.Forte@Sun.COM }
42977836SJohn.Forte@Sun.COM }
42987836SJohn.Forte@Sun.COM }
42997836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
43007836SJohn.Forte@Sun.COM if (*parms.rdc_set->direct_file) {
4301*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile,
4302*11576SSurya.Prakki@Sun.COM parms.rdc_set->direct_file, NSC_MAXPATH);
43037836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43047836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43057836SJohn.Forte@Sun.COM "sndr.set%d.type", i);
43067836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, directfile,
43077836SJohn.Forte@Sun.COM strlen(directfile)) < 0)
43087836SJohn.Forte@Sun.COM cfgsuccess = 0;
43097836SJohn.Forte@Sun.COM } else {
4310*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile, "-", NSC_MAXPATH);
43117836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43127836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43137836SJohn.Forte@Sun.COM "sndr.set%d.type", i);
43147836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, directfile,
43157836SJohn.Forte@Sun.COM strlen(directfile)) < 0)
43167836SJohn.Forte@Sun.COM cfgsuccess = 0;
43177836SJohn.Forte@Sun.COM }
43187836SJohn.Forte@Sun.COM #endif
43197836SJohn.Forte@Sun.COM
43207836SJohn.Forte@Sun.COM if (*parms.rdc_set->group_name) {
4321*11576SSurya.Prakki@Sun.COM (void) strncpy(group, parms.rdc_set->group_name,
43227836SJohn.Forte@Sun.COM NSC_MAXPATH);
43237836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43247836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43257836SJohn.Forte@Sun.COM "sndr.set%d.group", i);
43267836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, group,
43277836SJohn.Forte@Sun.COM strlen(group)) < 0)
43287836SJohn.Forte@Sun.COM cfgsuccess = 0;
43297836SJohn.Forte@Sun.COM
43307836SJohn.Forte@Sun.COM } else {
4331*11576SSurya.Prakki@Sun.COM (void) strncpy(group, "-", NSC_MAXPATH);
43327836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43337836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43347836SJohn.Forte@Sun.COM "sndr.set%d.group", i);
43357836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, group,
43367836SJohn.Forte@Sun.COM strlen(group)) < 0)
43377836SJohn.Forte@Sun.COM cfgsuccess = 0;
43387836SJohn.Forte@Sun.COM }
43397836SJohn.Forte@Sun.COM
43407836SJohn.Forte@Sun.COM if (*parms.rdc_set->disk_queue) {
4341*11576SSurya.Prakki@Sun.COM (void) strncpy(diskqueue,
4342*11576SSurya.Prakki@Sun.COM parms.rdc_set->disk_queue, NSC_MAXPATH);
43437836SJohn.Forte@Sun.COM } else {
4344*11576SSurya.Prakki@Sun.COM (void) strncpy(diskqueue, "-", NSC_MAXPATH);
43457836SJohn.Forte@Sun.COM }
43467836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43477836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43487836SJohn.Forte@Sun.COM "sndr.set%d.diskq", i);
43497836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, diskqueue,
43507836SJohn.Forte@Sun.COM strlen(diskqueue)) < 0)
43517836SJohn.Forte@Sun.COM cfgsuccess = 0;
43527836SJohn.Forte@Sun.COM
4353*11576SSurya.Prakki@Sun.COM (void) strncpy(frombitmap,
4354*11576SSurya.Prakki@Sun.COM parms.rdc_set->primary.bitmap, NSC_MAXPATH);
43557836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43567836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43577836SJohn.Forte@Sun.COM "sndr.set%d.pbitmap", i);
43587836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, frombitmap,
43597836SJohn.Forte@Sun.COM strlen(frombitmap)) < 0)
43607836SJohn.Forte@Sun.COM cfgsuccess = 0;
43617836SJohn.Forte@Sun.COM
4362*11576SSurya.Prakki@Sun.COM (void) strncpy(tobitmap,
4363*11576SSurya.Prakki@Sun.COM parms.rdc_set->secondary.bitmap, NSC_MAXPATH);
43647836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43657836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43667836SJohn.Forte@Sun.COM "sndr.set%d.sbitmap", i);
43677836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, tobitmap,
43687836SJohn.Forte@Sun.COM strlen(tobitmap)) < 0)
43697836SJohn.Forte@Sun.COM cfgsuccess = 0;
43707836SJohn.Forte@Sun.COM
43717836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
43727836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
43737836SJohn.Forte@Sun.COM "sndr.set%d.cnode", i);
43747836SJohn.Forte@Sun.COM if (clustered)
43757836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, ctag,
43767836SJohn.Forte@Sun.COM strlen(ctag)) < 0)
43777836SJohn.Forte@Sun.COM cfgsuccess = 0;
43787836SJohn.Forte@Sun.COM notfound:
43797836SJohn.Forte@Sun.COM if (cfgsuccess == 0) {
43807836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("unable to update "
43817836SJohn.Forte@Sun.COM "configuration storage"));
43827836SJohn.Forte@Sun.COM }
43837836SJohn.Forte@Sun.COM } else {
43847836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
43857836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s\n%s",
43867836SJohn.Forte@Sun.COM program, rdc_decode_flag(flag, parms.options),
43877836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
43887836SJohn.Forte@Sun.COM tohost, tofile, tobitmap,
43897836SJohn.Forte@Sun.COM gettext("unable to update config file"));
43907836SJohn.Forte@Sun.COM rdc_err(&ustatus,
43917836SJohn.Forte@Sun.COM gettext("Remote Mirror: unable to update "
43927836SJohn.Forte@Sun.COM "config file"));
43937836SJohn.Forte@Sun.COM
43947836SJohn.Forte@Sun.COM }
43957836SJohn.Forte@Sun.COM }
43967836SJohn.Forte@Sun.COM
43977836SJohn.Forte@Sun.COM if (flag == RDC_CMD_HEALTH && errno == 0) {
43987836SJohn.Forte@Sun.COM (void) fprintf(stderr,
43997836SJohn.Forte@Sun.COM gettext("Remote Mirror: %s %s %s %s %s %s\n"),
44007836SJohn.Forte@Sun.COM fromhost, fromfile,
44017836SJohn.Forte@Sun.COM frombitmap, tohost, tofile, tobitmap);
44027836SJohn.Forte@Sun.COM
44037836SJohn.Forte@Sun.COM if (ret == RDC_ACTIVE)
44047836SJohn.Forte@Sun.COM (void) fprintf(stderr, "Active\n");
44057836SJohn.Forte@Sun.COM else if (ret == RDC_INACTIVE)
44067836SJohn.Forte@Sun.COM (void) fprintf(stderr, "Inactive\n");
44077836SJohn.Forte@Sun.COM else
44087836SJohn.Forte@Sun.COM (void) fprintf(stderr, "Unknown\n");
44097836SJohn.Forte@Sun.COM } else if (ret != SPCS_S_OK) {
44107836SJohn.Forte@Sun.COM if (errno == RDC_EEINVAL) {
44117836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
44127836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s\n%s",
44137836SJohn.Forte@Sun.COM program, rdc_decode_flag(flag, parms.options),
44147836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
44157836SJohn.Forte@Sun.COM tohost, tofile, tobitmap,
44167836SJohn.Forte@Sun.COM gettext("invalid command option"));
44177836SJohn.Forte@Sun.COM rdc_err(&ustatus,
44187836SJohn.Forte@Sun.COM gettext("Remote Mirror: invalid command option "
44197836SJohn.Forte@Sun.COM "'%s'"),
44207836SJohn.Forte@Sun.COM rdc_decode_flag(flag, parms.options));
44217836SJohn.Forte@Sun.COM }
44227836SJohn.Forte@Sun.COM }
44237836SJohn.Forte@Sun.COM if (flag == RDC_CMD_STATUS) {
44247836SJohn.Forte@Sun.COM (void) fprintf(stderr,
44257836SJohn.Forte@Sun.COM gettext("Remote Mirror: %s %s %s %s %s %s\n"),
44267836SJohn.Forte@Sun.COM fromhost, fromfile,
44277836SJohn.Forte@Sun.COM frombitmap, tohost, tofile, tobitmap);
44287836SJohn.Forte@Sun.COM (void) fprintf(stderr, "flags 0x%x\n", parms.rdc_set->flags |
44297836SJohn.Forte@Sun.COM parms.rdc_set->sync_flags | parms.rdc_set->bmap_flags);
44307836SJohn.Forte@Sun.COM } else if (success) {
44317836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
44327836SJohn.Forte@Sun.COM gettext("%s %s %s %s %s %s %s %s\nSuccessful"),
44337836SJohn.Forte@Sun.COM program, rdc_decode_flag(flag, parms.options),
44347836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
44357836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
44367836SJohn.Forte@Sun.COM if (flag == RDC_CMD_TUNABLE)
44377836SJohn.Forte@Sun.COM spcslog_tunable(tohost, tofile);
44387836SJohn.Forte@Sun.COM }
44397836SJohn.Forte@Sun.COM
44407836SJohn.Forte@Sun.COM if (cfg && perform_autosv()) {
44417836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
44427836SJohn.Forte@Sun.COM /* figure out which are the local volumes */
44437836SJohn.Forte@Sun.COM if (parms.options & RDC_OPT_PRIMARY) {
44447836SJohn.Forte@Sun.COM vol1 = fromfile;
44457836SJohn.Forte@Sun.COM vol2 = frombitmap;
44467836SJohn.Forte@Sun.COM if ((diskqueue && diskqueue[0]) &&
44477836SJohn.Forte@Sun.COM (strncmp(diskqueue, "-", 1) != 0))
44487836SJohn.Forte@Sun.COM vol3 = diskqueue;
44497836SJohn.Forte@Sun.COM else
44507836SJohn.Forte@Sun.COM vol3 = NULL;
44517836SJohn.Forte@Sun.COM } else {
44527836SJohn.Forte@Sun.COM vol1 = tofile;
44537836SJohn.Forte@Sun.COM vol2 = tobitmap;
44547836SJohn.Forte@Sun.COM vol3 = NULL;
44557836SJohn.Forte@Sun.COM if ((flag == RDC_CMD_ENABLE) &&
44567836SJohn.Forte@Sun.COM (strlen(diskqueue) > 0) &&
44577836SJohn.Forte@Sun.COM (strncmp(diskqueue, "-", 1)) != 0) {
44587836SJohn.Forte@Sun.COM rdc_warn(NULL,
44597836SJohn.Forte@Sun.COM gettext("enabling a disk queue on a "
44607836SJohn.Forte@Sun.COM "Remote Mirror secondary is not allowed. "
44617836SJohn.Forte@Sun.COM "(%s) ignored"), diskqueue);
44627836SJohn.Forte@Sun.COM }
44637836SJohn.Forte@Sun.COM }
44647836SJohn.Forte@Sun.COM
44657836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE) {
44667836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
44677836SJohn.Forte@Sun.COM /*
44687836SJohn.Forte@Sun.COM * SV-enable all local volumes
44697836SJohn.Forte@Sun.COM * if the sv_enables fail, disable the sndr vols
44707836SJohn.Forte@Sun.COM * that we just enabled
44717836SJohn.Forte@Sun.COM * and return -1 so the cfg_commit() won't happen
44727836SJohn.Forte@Sun.COM */
44737836SJohn.Forte@Sun.COM
44747836SJohn.Forte@Sun.COM if (nsc_lookup(volhash, vol1) == NULL) {
44757836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, vol1, ctag, "sndr")
44767836SJohn.Forte@Sun.COM < 0) {
44777836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
44787836SJohn.Forte@Sun.COM "sv enable failed for %s, "
44797836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
44807836SJohn.Forte@Sun.COM vol1, tohost, tofile);
44817836SJohn.Forte@Sun.COM /*
44827836SJohn.Forte@Sun.COM * warn here, but we are going to exit
44837836SJohn.Forte@Sun.COM * we want to catch any errors on the
44847836SJohn.Forte@Sun.COM * way down, then exit
44857836SJohn.Forte@Sun.COM */
44867836SJohn.Forte@Sun.COM
44877836SJohn.Forte@Sun.COM rdc_warn(NULL,
44887836SJohn.Forte@Sun.COM "unable to sv enable %s\n"
44897836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
44907836SJohn.Forte@Sun.COM vol1, tohost, tofile);
44917836SJohn.Forte@Sun.COM
44927836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
44937836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
44947836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
44957836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
44967836SJohn.Forte@Sun.COM (void) fprintf(stderr,
44977836SJohn.Forte@Sun.COM gettext("Remote Mirror:"
44987836SJohn.Forte@Sun.COM " %s %s %s %s %s %s\n"),
44997836SJohn.Forte@Sun.COM fromhost, fromfile,
45007836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
45017836SJohn.Forte@Sun.COM tobitmap);
45027836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
45037836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
45047836SJohn.Forte@Sun.COM program,
45057836SJohn.Forte@Sun.COM rdc_decode_flag(parms.command,
45067836SJohn.Forte@Sun.COM parms.options),
45077836SJohn.Forte@Sun.COM fromhost,
45087836SJohn.Forte@Sun.COM fromfile, frombitmap,
45097836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
45107836SJohn.Forte@Sun.COM rdc_err(&ustatus, 0);
45117836SJohn.Forte@Sun.COM }
45127836SJohn.Forte@Sun.COM /*
45137836SJohn.Forte@Sun.COM * ok, we should've reported any errs
45147836SJohn.Forte@Sun.COM * exit explictly
45157836SJohn.Forte@Sun.COM */
45167836SJohn.Forte@Sun.COM exit(1);
45177836SJohn.Forte@Sun.COM
45187836SJohn.Forte@Sun.COM }
45197836SJohn.Forte@Sun.COM }
45207836SJohn.Forte@Sun.COM if (vol2 && nsc_lookup(volhash, vol2) == NULL) {
45217836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, vol2, ctag, "sndr")
45227836SJohn.Forte@Sun.COM < 0) {
45237836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
45247836SJohn.Forte@Sun.COM "sv enable failed for %s, "
45257836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
45267836SJohn.Forte@Sun.COM vol1, tohost, tofile);
45277836SJohn.Forte@Sun.COM /*
45287836SJohn.Forte@Sun.COM * warn here, but we are going to exit
45297836SJohn.Forte@Sun.COM * we want to catch any errors on the
45307836SJohn.Forte@Sun.COM * way down, then exit
45317836SJohn.Forte@Sun.COM */
45327836SJohn.Forte@Sun.COM
45337836SJohn.Forte@Sun.COM rdc_warn(NULL,
45347836SJohn.Forte@Sun.COM "unable to sv enable %s\n"
45357836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
45367836SJohn.Forte@Sun.COM vol2, tohost, tofile);
45377836SJohn.Forte@Sun.COM
45387836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
45397836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
45407836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
45417836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
45427836SJohn.Forte@Sun.COM (void) fprintf(stderr,
45437836SJohn.Forte@Sun.COM gettext("Remote Mirror:"
45447836SJohn.Forte@Sun.COM " %s %s %s %s %s %s\n"),
45457836SJohn.Forte@Sun.COM fromhost, fromfile,
45467836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
45477836SJohn.Forte@Sun.COM tobitmap);
45487836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
45497836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
45507836SJohn.Forte@Sun.COM program,
45517836SJohn.Forte@Sun.COM rdc_decode_flag(parms.command,
45527836SJohn.Forte@Sun.COM parms.options),
45537836SJohn.Forte@Sun.COM fromhost,
45547836SJohn.Forte@Sun.COM fromfile, frombitmap,
45557836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
45567836SJohn.Forte@Sun.COM rdc_err(&ustatus, 0);
45577836SJohn.Forte@Sun.COM }
45587836SJohn.Forte@Sun.COM /*
45597836SJohn.Forte@Sun.COM * ok, we should've reported any errs
45607836SJohn.Forte@Sun.COM * exit explictly
45617836SJohn.Forte@Sun.COM */
45627836SJohn.Forte@Sun.COM exit(1);
45637836SJohn.Forte@Sun.COM
45647836SJohn.Forte@Sun.COM }
45657836SJohn.Forte@Sun.COM }
45667836SJohn.Forte@Sun.COM
45677836SJohn.Forte@Sun.COM if (vol3 && nsc_lookup(volhash, diskqueue) == NULL) {
45687836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, diskqueue, ctag, "sndr")
45697836SJohn.Forte@Sun.COM < 0) {
45707836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
45717836SJohn.Forte@Sun.COM "sv enable failed for %s, "
45727836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
45737836SJohn.Forte@Sun.COM diskqueue, tohost, tofile);
45747836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, vol1, ctag,
45757836SJohn.Forte@Sun.COM "sndr") < 0)
45767836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
45777836SJohn.Forte@Sun.COM "remove volume [%s] from "
45787836SJohn.Forte@Sun.COM "configuration"), vol1);
45797836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, vol2, ctag,
45807836SJohn.Forte@Sun.COM "sndr") < 0)
45817836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
45827836SJohn.Forte@Sun.COM "remove volume [%s] from "
45837836SJohn.Forte@Sun.COM "configuration"), vol2);
45847836SJohn.Forte@Sun.COM
45857836SJohn.Forte@Sun.COM /*
45867836SJohn.Forte@Sun.COM * warn here, but we are going to exit
45877836SJohn.Forte@Sun.COM * we want to catch any errors on the
45887836SJohn.Forte@Sun.COM * way down, then exit
45897836SJohn.Forte@Sun.COM */
45907836SJohn.Forte@Sun.COM
45917836SJohn.Forte@Sun.COM rdc_warn(NULL,
45927836SJohn.Forte@Sun.COM "unable to sv enable %s\n"
45937836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
45947836SJohn.Forte@Sun.COM diskqueue, tohost, tofile);
45957836SJohn.Forte@Sun.COM
45967836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
45977836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
45987836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
45997836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
46007836SJohn.Forte@Sun.COM (void) fprintf(stderr,
46017836SJohn.Forte@Sun.COM gettext("Remote Mirror:"
46027836SJohn.Forte@Sun.COM " %s %s %s %s %s %s\n"),
46037836SJohn.Forte@Sun.COM fromhost, fromfile,
46047836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
46057836SJohn.Forte@Sun.COM tobitmap);
46067836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
46077836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
46087836SJohn.Forte@Sun.COM program,
46097836SJohn.Forte@Sun.COM rdc_decode_flag(parms.command,
46107836SJohn.Forte@Sun.COM parms.options),
46117836SJohn.Forte@Sun.COM fromhost,
46127836SJohn.Forte@Sun.COM fromfile, frombitmap,
46137836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
46147836SJohn.Forte@Sun.COM rdc_err(&ustatus, 0);
46157836SJohn.Forte@Sun.COM }
46167836SJohn.Forte@Sun.COM /*
46177836SJohn.Forte@Sun.COM * ok, we should've reported any errs
46187836SJohn.Forte@Sun.COM * exit explictly
46197836SJohn.Forte@Sun.COM */
46207836SJohn.Forte@Sun.COM exit(1);
46217836SJohn.Forte@Sun.COM
46227836SJohn.Forte@Sun.COM }
46237836SJohn.Forte@Sun.COM }
46247836SJohn.Forte@Sun.COM } else if (flag == RDC_CMD_DISABLE) {
46257836SJohn.Forte@Sun.COM /*
46267836SJohn.Forte@Sun.COM * If we're no longer using a volume, SV-disable it
46277836SJohn.Forte@Sun.COM */
46287836SJohn.Forte@Sun.COM volcount_t *vc;
46297836SJohn.Forte@Sun.COM
46307836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, vol1);
46317836SJohn.Forte@Sun.COM if (vc && (1 == vc->count)) {
46327836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, vol1, ctag, "sndr")
46337836SJohn.Forte@Sun.COM < 0)
46347836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
46357836SJohn.Forte@Sun.COM "remove volume [%s] from "
46367836SJohn.Forte@Sun.COM "configuration"), vol1);
46377836SJohn.Forte@Sun.COM
46387836SJohn.Forte@Sun.COM } else if (!vc) {
46397836SJohn.Forte@Sun.COM rdc_warn(NULL,
46407836SJohn.Forte@Sun.COM gettext("Unable to find %s in config"),
46417836SJohn.Forte@Sun.COM vol1);
46427836SJohn.Forte@Sun.COM }
46437836SJohn.Forte@Sun.COM
46447836SJohn.Forte@Sun.COM if (vol2) {
46457836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, vol2);
46467836SJohn.Forte@Sun.COM if (vc && (1 == vc->count)) {
46477836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, vol2, ctag,
46487836SJohn.Forte@Sun.COM "sndr") < 0)
46497836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
46507836SJohn.Forte@Sun.COM "remove volume [%s] from "
46517836SJohn.Forte@Sun.COM "configuration"), vol2);
46527836SJohn.Forte@Sun.COM } else if (!vc) {
46537836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to find"
46547836SJohn.Forte@Sun.COM " %s in config"), vol2);
46557836SJohn.Forte@Sun.COM }
46567836SJohn.Forte@Sun.COM }
46577836SJohn.Forte@Sun.COM
46587836SJohn.Forte@Sun.COM if (diskqueue != NULL && strlen(diskqueue) > 0) {
46597836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, diskqueue);
46607836SJohn.Forte@Sun.COM if (vc && (1 == vc->count)) {
46617836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, diskqueue, ctag,
46627836SJohn.Forte@Sun.COM "sndr") < 0)
46637836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
46647836SJohn.Forte@Sun.COM "remove disk queue [%s] from "
46657836SJohn.Forte@Sun.COM "configuration"), diskqueue);
46667836SJohn.Forte@Sun.COM } else if (!vc) {
46677836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to find"
46687836SJohn.Forte@Sun.COM " %s in config"), diskqueue);
46697836SJohn.Forte@Sun.COM }
46707836SJohn.Forte@Sun.COM }
46717836SJohn.Forte@Sun.COM /* WARNING about to go to 4 space indenting */
46727836SJohn.Forte@Sun.COM } else if (flag == RDC_CMD_RECONFIG) {
46737836SJohn.Forte@Sun.COM volcount_t *vc;
46747836SJohn.Forte@Sun.COM /* disable ex-bitmaps, enable new bitmaps */
46757836SJohn.Forte@Sun.COM if (parms.options & RDC_OPT_PRIMARY) {
46767836SJohn.Forte@Sun.COM if (strcmp(orig_fbmp, frombitmap) != 0) {
46777836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, orig_fbmp);
46787836SJohn.Forte@Sun.COM if (vc && (vc->count == 1)) {
46797836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, orig_fbmp, ctag,
46807836SJohn.Forte@Sun.COM "sndr") < 0)
46817836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
46827836SJohn.Forte@Sun.COM "remove bitmap [%s] from "
46837836SJohn.Forte@Sun.COM "configuration"), orig_fbmp);
46847836SJohn.Forte@Sun.COM } else if (!vc) {
46857836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to find "
46867836SJohn.Forte@Sun.COM "%s in config"), orig_fbmp);
46877836SJohn.Forte@Sun.COM }
46887836SJohn.Forte@Sun.COM if (nsc_lookup(volhash, frombitmap) == NULL) {
46897836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, frombitmap, ctag,
46907836SJohn.Forte@Sun.COM "sndr") < 0) {
46917836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
46927836SJohn.Forte@Sun.COM "reconfig sv enable failed for %s, "
46937836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
46947836SJohn.Forte@Sun.COM frombitmap, tohost, tofile);
46957836SJohn.Forte@Sun.COM rdc_warn(NULL,
46967836SJohn.Forte@Sun.COM "unable to sv enable %s\n"
46977836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
46987836SJohn.Forte@Sun.COM frombitmap, tohost, tofile);
46997836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
47007836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
47017836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
47027836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
47037836SJohn.Forte@Sun.COM (void) fprintf(stderr,
47047836SJohn.Forte@Sun.COM gettext("Remote Mirror:"
47057836SJohn.Forte@Sun.COM " %s %s %s %s %s %s\n"),
47067836SJohn.Forte@Sun.COM fromhost, fromfile,
47077836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
47087836SJohn.Forte@Sun.COM tobitmap);
47097836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
47107836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
47117836SJohn.Forte@Sun.COM program,
47127836SJohn.Forte@Sun.COM rdc_decode_flag(parms.command,
47137836SJohn.Forte@Sun.COM parms.options),
47147836SJohn.Forte@Sun.COM fromhost,
47157836SJohn.Forte@Sun.COM fromfile, frombitmap,
47167836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
47177836SJohn.Forte@Sun.COM rdc_warn(&ustatus, 0);
47187836SJohn.Forte@Sun.COM }
47197836SJohn.Forte@Sun.COM exit(1);
47207836SJohn.Forte@Sun.COM }
47217836SJohn.Forte@Sun.COM }
47227836SJohn.Forte@Sun.COM } else if ((orig_diskq[0] != '\0') &&
47237836SJohn.Forte@Sun.COM (strcmp(orig_diskq, diskqueue) != 0)) {
47247836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, orig_diskq);
47257836SJohn.Forte@Sun.COM if (vc && (vc->count == 1)) {
47267836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, orig_diskq, ctag,
47277836SJohn.Forte@Sun.COM "sndr") < 0)
47287836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
47297836SJohn.Forte@Sun.COM "remove disk queue [%s] from "
47307836SJohn.Forte@Sun.COM "configuration"), orig_diskq);
47317836SJohn.Forte@Sun.COM } else if (!vc) {
47327836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to find "
47337836SJohn.Forte@Sun.COM "%s in config"), orig_diskq);
47347836SJohn.Forte@Sun.COM }
47357836SJohn.Forte@Sun.COM if (vol3 &&
47367836SJohn.Forte@Sun.COM (nsc_lookup(volhash, diskqueue) == NULL)) {
47377836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, diskqueue, ctag,
47387836SJohn.Forte@Sun.COM "sndr") < 0) {
47397836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, "reconfig sv "
47407836SJohn.Forte@Sun.COM "enable of diskqueue %s failed, "
47417836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
47427836SJohn.Forte@Sun.COM diskqueue, tohost, tofile);
47437836SJohn.Forte@Sun.COM rdc_warn(NULL, "reconfig sv "
47447836SJohn.Forte@Sun.COM "enable of diskqueue %s failed."
47457836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
47467836SJohn.Forte@Sun.COM diskqueue, tohost, tofile);
47477836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
47487836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
47497836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
47507836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
47517836SJohn.Forte@Sun.COM (void) fprintf(stderr,
47527836SJohn.Forte@Sun.COM gettext("Remote Mirror:"
47537836SJohn.Forte@Sun.COM " %s %s %s %s %s %s\n"),
47547836SJohn.Forte@Sun.COM fromhost, fromfile,
47557836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
47567836SJohn.Forte@Sun.COM tobitmap);
47577836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
47587836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
47597836SJohn.Forte@Sun.COM program,
47607836SJohn.Forte@Sun.COM rdc_decode_flag(parms.command,
47617836SJohn.Forte@Sun.COM parms.options),
47627836SJohn.Forte@Sun.COM fromhost,
47637836SJohn.Forte@Sun.COM fromfile, frombitmap,
47647836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
47657836SJohn.Forte@Sun.COM rdc_warn(&ustatus, 0);
47667836SJohn.Forte@Sun.COM }
47677836SJohn.Forte@Sun.COM exit(1);
47687836SJohn.Forte@Sun.COM }
47697836SJohn.Forte@Sun.COM }
47707836SJohn.Forte@Sun.COM }
47717836SJohn.Forte@Sun.COM } else if (flag != RDC_OPT_PRIMARY) {
47727836SJohn.Forte@Sun.COM if (strcmp(orig_tbmp, tobitmap) != 0) {
47737836SJohn.Forte@Sun.COM vc = nsc_lookup(volhash, orig_tbmp);
47747836SJohn.Forte@Sun.COM if (vc && (vc->count == 1)) {
47757836SJohn.Forte@Sun.COM if (cfg_vol_disable(cfg, orig_tbmp, ctag,
47767836SJohn.Forte@Sun.COM "sndr") < 0)
47777836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Failed to "
47787836SJohn.Forte@Sun.COM "remove bitmap [%s] from "
47797836SJohn.Forte@Sun.COM "configuration"), orig_tbmp);
47807836SJohn.Forte@Sun.COM } else if (!vc) {
47817836SJohn.Forte@Sun.COM rdc_warn(NULL,
47827836SJohn.Forte@Sun.COM gettext("Unable to find %s in config"),
47837836SJohn.Forte@Sun.COM orig_tbmp);
47847836SJohn.Forte@Sun.COM }
47857836SJohn.Forte@Sun.COM if (nsc_lookup(volhash, tobitmap) == NULL) {
47867836SJohn.Forte@Sun.COM if (cfg_vol_enable(cfg, tobitmap, ctag,
47877836SJohn.Forte@Sun.COM "sndr") < 0) {
47887836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
47897836SJohn.Forte@Sun.COM "reconfig sv enable failed for %s, "
47907836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
47917836SJohn.Forte@Sun.COM tobitmap, tohost, tofile);
47927836SJohn.Forte@Sun.COM rdc_warn(NULL,
47937836SJohn.Forte@Sun.COM "unable to sv enable %s\n"
47947836SJohn.Forte@Sun.COM "disabling Remote Mirror set %s:%s",
47957836SJohn.Forte@Sun.COM tobitmap, tohost, tofile);
47967836SJohn.Forte@Sun.COM parms.command = RDC_CMD_DISABLE;
47977836SJohn.Forte@Sun.COM ret = RDC_IOCTL(RDC_CONFIG, &parms,
47987836SJohn.Forte@Sun.COM NULL, 0, 0, 0, ustatus);
47997836SJohn.Forte@Sun.COM if (ret != SPCS_S_OK) {
48007836SJohn.Forte@Sun.COM (void) fprintf(stderr,
48017836SJohn.Forte@Sun.COM gettext("Remote Mirror:"
48027836SJohn.Forte@Sun.COM " %s %s %s %s %s %s\n"),
48037836SJohn.Forte@Sun.COM fromhost, fromfile,
48047836SJohn.Forte@Sun.COM frombitmap, tohost, tofile,
48057836SJohn.Forte@Sun.COM tobitmap);
48067836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
48077836SJohn.Forte@Sun.COM "%s %s %s %s %s %s %s %s",
48087836SJohn.Forte@Sun.COM program,
48097836SJohn.Forte@Sun.COM rdc_decode_flag(parms.command,
48107836SJohn.Forte@Sun.COM parms.options),
48117836SJohn.Forte@Sun.COM fromhost, fromfile, frombitmap,
48127836SJohn.Forte@Sun.COM tohost, tofile, tobitmap);
48137836SJohn.Forte@Sun.COM rdc_warn(&ustatus, 0);
48147836SJohn.Forte@Sun.COM }
48157836SJohn.Forte@Sun.COM exit(1);
48167836SJohn.Forte@Sun.COM }
48177836SJohn.Forte@Sun.COM }
48187836SJohn.Forte@Sun.COM }
48197836SJohn.Forte@Sun.COM }
48207836SJohn.Forte@Sun.COM /* END 4 space indenting */
48217836SJohn.Forte@Sun.COM }
48227836SJohn.Forte@Sun.COM }
48237836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
48247836SJohn.Forte@Sun.COM
48257836SJohn.Forte@Sun.COM return (0);
48267836SJohn.Forte@Sun.COM }
48277836SJohn.Forte@Sun.COM
48287836SJohn.Forte@Sun.COM
48297836SJohn.Forte@Sun.COM /*
48307836SJohn.Forte@Sun.COM * read_config()
48317836SJohn.Forte@Sun.COM *
48327836SJohn.Forte@Sun.COM * DESCRIPTION: Read the lines in a configuration file and return the
48337836SJohn.Forte@Sun.COM * pairs of devices to be mirrored/enabled/disabled/updated.
48347836SJohn.Forte@Sun.COM * The format for the configuration file is as follows:
48357836SJohn.Forte@Sun.COM *
48367836SJohn.Forte@Sun.COM * fromhost fromfile frombitmap tohost tofile tobitmap
48377836SJohn.Forte@Sun.COM *
48387836SJohn.Forte@Sun.COM * where fromfile is the primary device which is local to the
48397836SJohn.Forte@Sun.COM * fromhost subsystem, tofile is the secondary device which is
48407836SJohn.Forte@Sun.COM * local to the tohost subsystem, and type is 1 if the device
48417836SJohn.Forte@Sun.COM * a simckd device or 0 otherwise. Any line preceeded by a '#'
48427836SJohn.Forte@Sun.COM * is considered to be a comment.
48437836SJohn.Forte@Sun.COM *
48447836SJohn.Forte@Sun.COM * Inputs:
48457836SJohn.Forte@Sun.COM * char *config_file Name of configuration file for rdcadm
48467836SJohn.Forte@Sun.COM *
48477836SJohn.Forte@Sun.COM * Outputs:
48487836SJohn.Forte@Sun.COM * int i Number of pairs of devices
48497836SJohn.Forte@Sun.COM *
48507836SJohn.Forte@Sun.COM * Side Effects: The 0 to i-1 entries in the pair_list are filled.
48517836SJohn.Forte@Sun.COM *
48527836SJohn.Forte@Sun.COM */
48537836SJohn.Forte@Sun.COM
48547836SJohn.Forte@Sun.COM int
48557836SJohn.Forte@Sun.COM read_config(int flag, char *config_file, char *group_arg, char *ctag_arg)
48567836SJohn.Forte@Sun.COM {
48577836SJohn.Forte@Sun.COM int ret;
48587836SJohn.Forte@Sun.COM char dsk_flagstr[NSC_MAXPATH];
48597836SJohn.Forte@Sun.COM char line[1024], tmp_line[1024];
48607836SJohn.Forte@Sun.COM char fromhost[MAX_RDC_HOST_SIZE];
48617836SJohn.Forte@Sun.COM char fromfile[NSC_MAXPATH];
48627836SJohn.Forte@Sun.COM char frombitmap[NSC_MAXPATH];
48637836SJohn.Forte@Sun.COM char tohost[MAX_RDC_HOST_SIZE];
48647836SJohn.Forte@Sun.COM char tofile[NSC_MAXPATH];
48657836SJohn.Forte@Sun.COM char tobitmap[NSC_MAXPATH];
48667836SJohn.Forte@Sun.COM char directfile[NSC_MAXPATH];
48677836SJohn.Forte@Sun.COM char sync[16];
48687836SJohn.Forte@Sun.COM int doasync;
48697836SJohn.Forte@Sun.COM FILE *fp;
48707836SJohn.Forte@Sun.COM int i, j;
48717836SJohn.Forte@Sun.COM char *extra_args[EXTRA_ARGS];
48727836SJohn.Forte@Sun.COM char *tmp, *split_str = " \t\n";
48737836SJohn.Forte@Sun.COM
48747836SJohn.Forte@Sun.COM for (j = 0; j < EXTRA_ARGS; j++)
48757836SJohn.Forte@Sun.COM extra_args[j] = malloc(NSC_MAXPATH);
48767836SJohn.Forte@Sun.COM
48777836SJohn.Forte@Sun.COM if (!(fp = fopen(config_file, "r"))) {
48787836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("error opening %s"), config_file);
48797836SJohn.Forte@Sun.COM }
48807836SJohn.Forte@Sun.COM
48817836SJohn.Forte@Sun.COM i = 0;
48827836SJohn.Forte@Sun.COM while (fgets(line, sizeof (line), fp)) {
48837836SJohn.Forte@Sun.COM if (line[0] == '#') /* this is a comment */
48847836SJohn.Forte@Sun.COM continue;
48857836SJohn.Forte@Sun.COM
48867836SJohn.Forte@Sun.COM ret = 0;
4887*11576SSurya.Prakki@Sun.COM (void) strcpy(tmp_line, line);
48887836SJohn.Forte@Sun.COM
48897836SJohn.Forte@Sun.COM if ((tmp = strtok(tmp_line, split_str)) != NULL) {
48907836SJohn.Forte@Sun.COM if (strlen(tmp) >= MAX_RDC_HOST_SIZE) {
48917836SJohn.Forte@Sun.COM (void) printf(gettext("hostname is longer than %d "
48927836SJohn.Forte@Sun.COM "characters\n"), (MAX_RDC_HOST_SIZE - 1));
48937836SJohn.Forte@Sun.COM continue;
48947836SJohn.Forte@Sun.COM }
4895*11576SSurya.Prakki@Sun.COM (void) strncpy(fromhost, tmp, (MAX_RDC_HOST_SIZE - 1));
48967836SJohn.Forte@Sun.COM fromhost[(MAX_RDC_HOST_SIZE - 1)] = '\0';
48977836SJohn.Forte@Sun.COM ret++;
48987836SJohn.Forte@Sun.COM }
48997836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
49007836SJohn.Forte@Sun.COM if (strlen(tmp) >= NSC_MAXPATH) {
49017836SJohn.Forte@Sun.COM (void) printf(gettext(
49027836SJohn.Forte@Sun.COM "device name is longer than %d "
49037836SJohn.Forte@Sun.COM "characters\n"), (NSC_MAXPATH - 1));
49047836SJohn.Forte@Sun.COM continue;
49057836SJohn.Forte@Sun.COM }
4906*11576SSurya.Prakki@Sun.COM (void) strncpy(fromfile, tmp, (NSC_MAXPATH - 1));
49077836SJohn.Forte@Sun.COM fromfile[(NSC_MAXPATH - 1)] = '\0';
49087836SJohn.Forte@Sun.COM ret++;
49097836SJohn.Forte@Sun.COM }
49107836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
49117836SJohn.Forte@Sun.COM if (strlen(tmp) >= NSC_MAXPATH) {
49127836SJohn.Forte@Sun.COM (void) printf(gettext(
49137836SJohn.Forte@Sun.COM "device name is longer than %d "
49147836SJohn.Forte@Sun.COM "characters\n"), (NSC_MAXPATH - 1));
49157836SJohn.Forte@Sun.COM continue;
49167836SJohn.Forte@Sun.COM }
4917*11576SSurya.Prakki@Sun.COM (void) strncpy(frombitmap, tmp, (NSC_MAXPATH - 1));
49187836SJohn.Forte@Sun.COM frombitmap[(NSC_MAXPATH - 1)] = '\0';
49197836SJohn.Forte@Sun.COM ret++;
49207836SJohn.Forte@Sun.COM }
49217836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
49227836SJohn.Forte@Sun.COM if (strlen(tmp) >= MAX_RDC_HOST_SIZE) {
49237836SJohn.Forte@Sun.COM (void) printf(gettext(
49247836SJohn.Forte@Sun.COM "hostname is longer than %d "
49257836SJohn.Forte@Sun.COM "characters\n"), (MAX_RDC_HOST_SIZE - 1));
49267836SJohn.Forte@Sun.COM continue;
49277836SJohn.Forte@Sun.COM }
4928*11576SSurya.Prakki@Sun.COM (void) strncpy(tohost, tmp, (MAX_RDC_HOST_SIZE - 1));
49297836SJohn.Forte@Sun.COM tohost[(MAX_RDC_HOST_SIZE - 1)] = '\0';
49307836SJohn.Forte@Sun.COM ret++;
49317836SJohn.Forte@Sun.COM }
49327836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
49337836SJohn.Forte@Sun.COM if (strlen(tmp) >= NSC_MAXPATH) {
49347836SJohn.Forte@Sun.COM (void) printf(gettext(
49357836SJohn.Forte@Sun.COM "device name is longer than %d "
49367836SJohn.Forte@Sun.COM "characters\n"), (NSC_MAXPATH - 1));
49377836SJohn.Forte@Sun.COM continue;
49387836SJohn.Forte@Sun.COM }
4939*11576SSurya.Prakki@Sun.COM (void) strncpy(tofile, tmp, (NSC_MAXPATH - 1));
49407836SJohn.Forte@Sun.COM tofile[(NSC_MAXPATH - 1)] = '\0';
49417836SJohn.Forte@Sun.COM ret++;
49427836SJohn.Forte@Sun.COM }
49437836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
49447836SJohn.Forte@Sun.COM if (strlen(tmp) >= NSC_MAXPATH) {
49457836SJohn.Forte@Sun.COM (void) printf(gettext(
49467836SJohn.Forte@Sun.COM "device name is longer than %d "
49477836SJohn.Forte@Sun.COM "characters\n"), (NSC_MAXPATH - 1));
49487836SJohn.Forte@Sun.COM continue;
49497836SJohn.Forte@Sun.COM }
4950*11576SSurya.Prakki@Sun.COM (void) strncpy(tobitmap, tmp, (NSC_MAXPATH - 1));
49517836SJohn.Forte@Sun.COM tobitmap[(NSC_MAXPATH - 1)] = '\0';
49527836SJohn.Forte@Sun.COM ret++;
49537836SJohn.Forte@Sun.COM }
49547836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
4955*11576SSurya.Prakki@Sun.COM (void) strncpy(dsk_flagstr, tmp, 15);
49567836SJohn.Forte@Sun.COM dsk_flagstr[15] = '\0';
49577836SJohn.Forte@Sun.COM ret++;
49587836SJohn.Forte@Sun.COM }
49597836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
4960*11576SSurya.Prakki@Sun.COM (void) strncpy(sync, tmp, 15);
49617836SJohn.Forte@Sun.COM sync[15] = '\0';
49627836SJohn.Forte@Sun.COM ret++;
49637836SJohn.Forte@Sun.COM }
49647836SJohn.Forte@Sun.COM for (j = 0; j < EXTRA_ARGS; j++) {
49657836SJohn.Forte@Sun.COM if ((tmp = strtok(NULL, split_str)) != NULL) {
4966*11576SSurya.Prakki@Sun.COM (void) strncpy(extra_args[j], tmp,
4967*11576SSurya.Prakki@Sun.COM (NSC_MAXPATH - 1));
49687836SJohn.Forte@Sun.COM extra_args[j][(NSC_MAXPATH - 1)] = '\0';
49697836SJohn.Forte@Sun.COM ret++;
49707836SJohn.Forte@Sun.COM }
49717836SJohn.Forte@Sun.COM }
49727836SJohn.Forte@Sun.COM
49737836SJohn.Forte@Sun.COM if (ret == 0) /* this is a blank line */
49747836SJohn.Forte@Sun.COM continue;
49757836SJohn.Forte@Sun.COM
49767836SJohn.Forte@Sun.COM if (ret < 8) {
49777836SJohn.Forte@Sun.COM (void) fclose(fp);
49787836SJohn.Forte@Sun.COM rdc_warn(NULL,
49797836SJohn.Forte@Sun.COM gettext("invalid format in %s"), config_file);
49807836SJohn.Forte@Sun.COM rdc_err(NULL, "%s", line);
49817836SJohn.Forte@Sun.COM }
49827836SJohn.Forte@Sun.COM
49837836SJohn.Forte@Sun.COM if (i >= rdc_maxsets) {
49847836SJohn.Forte@Sun.COM (void) fclose(fp);
49857836SJohn.Forte@Sun.COM rdc_err(NULL,
49867836SJohn.Forte@Sun.COM gettext("number of Remote Mirror sets exceeds %d"),
49877836SJohn.Forte@Sun.COM rdc_maxsets);
49887836SJohn.Forte@Sun.COM }
49897836SJohn.Forte@Sun.COM
49907836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
49917836SJohn.Forte@Sun.COM if (dsk_flagstr[0] == '/') {
49927836SJohn.Forte@Sun.COM /* fcal directio */
4993*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile, dsk_flagstr, NSC_MAXPATH);
49947836SJohn.Forte@Sun.COM } else if (strcmp(dsk_flagstr, "ip") != 0) {
49957836SJohn.Forte@Sun.COM #else
49967836SJohn.Forte@Sun.COM if (strcmp(dsk_flagstr, "ip") != 0) {
49977836SJohn.Forte@Sun.COM #endif
49987836SJohn.Forte@Sun.COM (void) fclose(fp);
49997836SJohn.Forte@Sun.COM rdc_err(NULL,
50007836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
50017836SJohn.Forte@Sun.COM gettext("ip/fcal specification missing"));
50027836SJohn.Forte@Sun.COM #else
50037836SJohn.Forte@Sun.COM gettext("ip specification missing"));
50047836SJohn.Forte@Sun.COM #endif
50057836SJohn.Forte@Sun.COM } else
5006*11576SSurya.Prakki@Sun.COM (void) strcpy(directfile, "ip");
50077836SJohn.Forte@Sun.COM
50087836SJohn.Forte@Sun.COM if (strcmp(sync, "sync") == 0)
50097836SJohn.Forte@Sun.COM doasync = 0;
50107836SJohn.Forte@Sun.COM else if (strcmp(sync, "async") == 0)
50117836SJohn.Forte@Sun.COM doasync = 1;
50127836SJohn.Forte@Sun.COM else {
50137836SJohn.Forte@Sun.COM (void) fclose(fp);
50147836SJohn.Forte@Sun.COM rdc_err(NULL,
50157836SJohn.Forte@Sun.COM gettext("sync/async specification missing"));
50167836SJohn.Forte@Sun.COM }
5017*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].fhost, fromhost, MAX_RDC_HOST_SIZE);
5018*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH);
5019*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH);
5020*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE);
5021*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH);
5022*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH);
5023*11576SSurya.Prakki@Sun.COM (void) strncpy(pair_list[i].directfile, directfile,
5024*11576SSurya.Prakki@Sun.COM NSC_MAXPATH);
50257836SJohn.Forte@Sun.COM pair_list[i].doasync = doasync;
50267836SJohn.Forte@Sun.COM
50277836SJohn.Forte@Sun.COM if (gethost_netaddrs(fromhost, tohost,
50287836SJohn.Forte@Sun.COM (char *)pair_list[i].fnetaddr,
50297836SJohn.Forte@Sun.COM (char *)pair_list[i].tnetaddr) < 0) {
50307836SJohn.Forte@Sun.COM (void) fclose(fp);
50317836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to determine IP "
50327836SJohn.Forte@Sun.COM "addresses for hosts %s, %s"), fromhost, tohost);
50337836SJohn.Forte@Sun.COM }
50347836SJohn.Forte@Sun.COM
50357836SJohn.Forte@Sun.COM if (parse_extras(ret - 8, extra_args, i) < 0) {
50367836SJohn.Forte@Sun.COM (void) fclose(fp);
50377836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("illegal option in:\n%s"),
50387836SJohn.Forte@Sun.COM line);
50397836SJohn.Forte@Sun.COM }
50407836SJohn.Forte@Sun.COM
50417836SJohn.Forte@Sun.COM if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) {
50427836SJohn.Forte@Sun.COM if (ctag_check(fromhost, fromfile, frombitmap,
50437836SJohn.Forte@Sun.COM tohost, tofile, tobitmap, pair_list[i].ctag,
50447836SJohn.Forte@Sun.COM pair_list[i].diskqueue) < 0)
50457836SJohn.Forte@Sun.COM continue; /* Ignore illegal sets */
50467836SJohn.Forte@Sun.COM if (pair_diskqueue_check(i))
50477836SJohn.Forte@Sun.COM continue; /* ignore sets with incorrect diskq */
50487836SJohn.Forte@Sun.COM }
50497836SJohn.Forte@Sun.COM
50507836SJohn.Forte@Sun.COM /* Filter according to ctag and group arguments */
50517836SJohn.Forte@Sun.COM if (strcmp(ctag_arg, "") &&
50527836SJohn.Forte@Sun.COM strncmp(ctag_arg, pair_list[i].ctag,
50537836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE))
50547836SJohn.Forte@Sun.COM continue;
50557836SJohn.Forte@Sun.COM if (strcmp(group_arg, "") &&
50567836SJohn.Forte@Sun.COM strncmp(group_arg, pair_list[i].group, NSC_MAXPATH))
50577836SJohn.Forte@Sun.COM continue;
50587836SJohn.Forte@Sun.COM
50597836SJohn.Forte@Sun.COM i++;
50607836SJohn.Forte@Sun.COM }
50617836SJohn.Forte@Sun.COM (void) fclose(fp);
50627836SJohn.Forte@Sun.COM for (j = 0; j < EXTRA_ARGS; j++)
50637836SJohn.Forte@Sun.COM free(extra_args[j]);
50647836SJohn.Forte@Sun.COM return (i);
50657836SJohn.Forte@Sun.COM }
50667836SJohn.Forte@Sun.COM
50677836SJohn.Forte@Sun.COM
50687836SJohn.Forte@Sun.COM /*
50697836SJohn.Forte@Sun.COM * read_libcfg()
50707836SJohn.Forte@Sun.COM *
50717836SJohn.Forte@Sun.COM * DESCRIPTION: Read the relevant config info via libcfg
50727836SJohn.Forte@Sun.COM *
50737836SJohn.Forte@Sun.COM * Outputs:
50747836SJohn.Forte@Sun.COM * int i Number of pairs of devices
50757836SJohn.Forte@Sun.COM *
50767836SJohn.Forte@Sun.COM * Side Effects: The 0 to i-1 entries in the pair_list are filled.
50777836SJohn.Forte@Sun.COM *
50787836SJohn.Forte@Sun.COM */
50797836SJohn.Forte@Sun.COM static int
50807836SJohn.Forte@Sun.COM read_libcfg(int flag, char *group_arg, char *ctag_arg)
50817836SJohn.Forte@Sun.COM {
50827836SJohn.Forte@Sun.COM int rc;
50837836SJohn.Forte@Sun.COM CFGFILE *cfg;
50847836SJohn.Forte@Sun.COM int i;
50857836SJohn.Forte@Sun.COM _sd_dual_pair_t *pairp;
50867836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
50877836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
50887836SJohn.Forte@Sun.COM int setnumber;
50897836SJohn.Forte@Sun.COM
50907836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL)
50917836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to access configuration"));
50927836SJohn.Forte@Sun.COM
50937836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK))
50947836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to lock configuration"));
50957836SJohn.Forte@Sun.COM
50967836SJohn.Forte@Sun.COM if (strcmp(ctag_arg, ""))
50977836SJohn.Forte@Sun.COM cfg_resource(cfg, ctag_arg);
50987836SJohn.Forte@Sun.COM else {
50997836SJohn.Forte@Sun.COM cfg_resource(cfg, NULL);
51007836SJohn.Forte@Sun.COM }
51017836SJohn.Forte@Sun.COM
51027836SJohn.Forte@Sun.COM setnumber = 0;
51037836SJohn.Forte@Sun.COM /*CSTYLED*/
51047836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets;) {
51057836SJohn.Forte@Sun.COM setnumber++;
51067836SJohn.Forte@Sun.COM
51077836SJohn.Forte@Sun.COM bzero(buf, CFG_MAX_BUF);
51087836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
51097836SJohn.Forte@Sun.COM rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF);
51107836SJohn.Forte@Sun.COM if (rc < 0)
51117836SJohn.Forte@Sun.COM break;
51127836SJohn.Forte@Sun.COM
51137836SJohn.Forte@Sun.COM pairp = &pair_list[i];
51147836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, pairp, NULL))
51157836SJohn.Forte@Sun.COM continue;
51167836SJohn.Forte@Sun.COM
51177836SJohn.Forte@Sun.COM if (strcmp(group_arg, "") &&
51187836SJohn.Forte@Sun.COM strncmp(group_arg, pairp->group, NSC_MAXPATH))
51197836SJohn.Forte@Sun.COM continue;
51207836SJohn.Forte@Sun.COM
51217836SJohn.Forte@Sun.COM if (flag == RDC_CMD_RECONFIG) {
51227836SJohn.Forte@Sun.COM if (reconfig_pbitmap)
5123*11576SSurya.Prakki@Sun.COM (void) strncpy(pairp->fbitmap, reconfig_pbitmap,
51247836SJohn.Forte@Sun.COM NSC_MAXPATH);
51257836SJohn.Forte@Sun.COM if (reconfig_sbitmap)
5126*11576SSurya.Prakki@Sun.COM (void) strncpy(pairp->tbitmap, reconfig_sbitmap,
51277836SJohn.Forte@Sun.COM NSC_MAXPATH);
51287836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
51297836SJohn.Forte@Sun.COM if (reconfig_direct)
5130*11576SSurya.Prakki@Sun.COM (void) strncpy(directfile, reconfig_direct,
51317836SJohn.Forte@Sun.COM NSC_MAXPATH);
51327836SJohn.Forte@Sun.COM #endif
51337836SJohn.Forte@Sun.COM if (reconfig_group)
5134*11576SSurya.Prakki@Sun.COM (void) strncpy(pairp->group, reconfig_group,
51357836SJohn.Forte@Sun.COM NSC_MAXPATH);
51367836SJohn.Forte@Sun.COM
51377836SJohn.Forte@Sun.COM if (strlen(reconfig_ctag) > 0)
5138*11576SSurya.Prakki@Sun.COM (void) strncpy(pairp->ctag, reconfig_ctag,
51397836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
51407836SJohn.Forte@Sun.COM
51417836SJohn.Forte@Sun.COM if (reconfig_doasync != -1)
51427836SJohn.Forte@Sun.COM pairp->doasync = reconfig_doasync;
51437836SJohn.Forte@Sun.COM }
51447836SJohn.Forte@Sun.COM
51457836SJohn.Forte@Sun.COM
51467836SJohn.Forte@Sun.COM if (ctag_check(pairp->fhost, pairp->ffile,
51477836SJohn.Forte@Sun.COM pairp->fbitmap, pairp->thost, pairp->tfile,
51487836SJohn.Forte@Sun.COM pairp->tbitmap, pairp->ctag, pairp->diskqueue) < 0)
51497836SJohn.Forte@Sun.COM continue; /* Ignore illegal sets */
51507836SJohn.Forte@Sun.COM
51517836SJohn.Forte@Sun.COM if (gethost_netaddrs(pairp->fhost, pairp->thost,
51527836SJohn.Forte@Sun.COM (char *)pairp->fnetaddr,
51537836SJohn.Forte@Sun.COM (char *)pairp->tnetaddr) < 0) {
51547836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to determine IP "
51557836SJohn.Forte@Sun.COM "addresses for hosts %s, %s"), pairp->fhost,
51567836SJohn.Forte@Sun.COM pairp->thost);
51577836SJohn.Forte@Sun.COM }
51587836SJohn.Forte@Sun.COM
51597836SJohn.Forte@Sun.COM i++;
51607836SJohn.Forte@Sun.COM }
51617836SJohn.Forte@Sun.COM
51627836SJohn.Forte@Sun.COM cfg_close(cfg);
51637836SJohn.Forte@Sun.COM return (i);
51647836SJohn.Forte@Sun.COM }
51657836SJohn.Forte@Sun.COM
51667836SJohn.Forte@Sun.COM void
51677836SJohn.Forte@Sun.COM q_usage(int prhdr)
51687836SJohn.Forte@Sun.COM {
51697836SJohn.Forte@Sun.COM if (prhdr)
51707836SJohn.Forte@Sun.COM (void) fprintf(stderr, gettext("disk queue usage:\n"));
51717836SJohn.Forte@Sun.COM
51727836SJohn.Forte@Sun.COM (void) fprintf(stderr,
51737836SJohn.Forte@Sun.COM gettext("\t%s -g <group> -q a <vol>\t\tadd disk queue to "
51747836SJohn.Forte@Sun.COM "group\n"), program);
51757836SJohn.Forte@Sun.COM (void) fprintf(stderr,
51767836SJohn.Forte@Sun.COM gettext("\t%s -g <group> -q d \t\tremove disk queue from"
51777836SJohn.Forte@Sun.COM " group\n"), program);
51787836SJohn.Forte@Sun.COM (void) fprintf(stderr,
51797836SJohn.Forte@Sun.COM gettext("\t%s -g <group> -q r <newvol>\treplace disk queue for a"
51807836SJohn.Forte@Sun.COM " group\n"), program);
51817836SJohn.Forte@Sun.COM
51827836SJohn.Forte@Sun.COM (void) fprintf(stderr,
51837836SJohn.Forte@Sun.COM gettext("\t%s -q a <vol> <shost>:<sdev>\tadd disk queue to "
51847836SJohn.Forte@Sun.COM "a set\n"), program);
51857836SJohn.Forte@Sun.COM (void) fprintf(stderr,
51867836SJohn.Forte@Sun.COM gettext("\t%s -q d <shost>:<sdev>\t\tremove disk queue from "
51877836SJohn.Forte@Sun.COM "a set\n"), program);
51887836SJohn.Forte@Sun.COM (void) fprintf(stderr,
51897836SJohn.Forte@Sun.COM gettext("\t%s -q r <newvol> <shost>:<sdev>\treplace disk queue for "
51907836SJohn.Forte@Sun.COM "a set\n"), program);
51917836SJohn.Forte@Sun.COM
51927836SJohn.Forte@Sun.COM }
51937836SJohn.Forte@Sun.COM
51947836SJohn.Forte@Sun.COM static void
51957836SJohn.Forte@Sun.COM usage()
51967836SJohn.Forte@Sun.COM {
51977836SJohn.Forte@Sun.COM (void) fprintf(stderr, gettext("usage:\n"));
51987836SJohn.Forte@Sun.COM
51997836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52007836SJohn.Forte@Sun.COM gettext("\t%s [opts] -a {on | off} [set]\t"
52017836SJohn.Forte@Sun.COM "set autosync\n"), program);
52027836SJohn.Forte@Sun.COM
52037836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52047836SJohn.Forte@Sun.COM gettext("\t%s [opts] -A <asyncthr> [set]\t"
52057836SJohn.Forte@Sun.COM "set the number of asynchronous\n\t\t\t\t\t\tthreads\n"),
52067836SJohn.Forte@Sun.COM program);
52077836SJohn.Forte@Sun.COM
52087836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52097836SJohn.Forte@Sun.COM gettext("\t%s [opts] -d [set]\t\t\t"
52107836SJohn.Forte@Sun.COM "disable\n"), program);
52117836SJohn.Forte@Sun.COM
52127836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52137836SJohn.Forte@Sun.COM gettext("\t%s [opts] -e [set]\t\t\t"
52147836SJohn.Forte@Sun.COM "enable with bits in bitmap set\n"), program);
52157836SJohn.Forte@Sun.COM
52167836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52177836SJohn.Forte@Sun.COM gettext("\t%s [opts] -E [set]\t\t\t"
52187836SJohn.Forte@Sun.COM "enable with bits in bitmap clear\n"), program);
52197836SJohn.Forte@Sun.COM
52207836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52217836SJohn.Forte@Sun.COM gettext("\t%s [opts] -F <maxqfbas> [set]\t"
52227836SJohn.Forte@Sun.COM "set maximum fbas to queue\n"), program);
52237836SJohn.Forte@Sun.COM
52247836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52257836SJohn.Forte@Sun.COM gettext("\t%s [opts] -D {block | noblock} [set]\t"
52267836SJohn.Forte@Sun.COM "set disk queue blocking mode\n"), program);
52277836SJohn.Forte@Sun.COM
52287836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52297836SJohn.Forte@Sun.COM gettext("\t%s [opts] -H [set]\t\t\t"
52307836SJohn.Forte@Sun.COM "report link health\n"), program);
52317836SJohn.Forte@Sun.COM
52327836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52337836SJohn.Forte@Sun.COM gettext("\t%s -h\t\t\t\tusage message\n"), program);
52347836SJohn.Forte@Sun.COM
52357836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52367836SJohn.Forte@Sun.COM gettext("\t%s -I a <master> <shadow> <bitmap>\t"
52377836SJohn.Forte@Sun.COM "add ndr_ii config entry\n"), program);
52387836SJohn.Forte@Sun.COM
52397836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52407836SJohn.Forte@Sun.COM gettext("\t%s -I d <master> <shadow> <bitmap>\t"
52417836SJohn.Forte@Sun.COM "delete ndr_ii config entry\n"), program);
52427836SJohn.Forte@Sun.COM
52437836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52447836SJohn.Forte@Sun.COM gettext("\t%s [opts] -i [set]\t\t\t"
52457836SJohn.Forte@Sun.COM "print sets in config file format\n"), program);
52467836SJohn.Forte@Sun.COM
52477836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52487836SJohn.Forte@Sun.COM gettext("\t%s [opts] -l [set]\t\t\t"
52497836SJohn.Forte@Sun.COM "enter logging mode\n"), program);
52507836SJohn.Forte@Sun.COM
52517836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52527836SJohn.Forte@Sun.COM gettext("\t%s [opts] -m [set]\t\t\t"
52537836SJohn.Forte@Sun.COM "full sync\n"), program);
52547836SJohn.Forte@Sun.COM
52557836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52567836SJohn.Forte@Sun.COM gettext("\t%s [opts] -m -r [set]\t\t"
52577836SJohn.Forte@Sun.COM "full reverse sync\n"), program);
52587836SJohn.Forte@Sun.COM
52597836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52607836SJohn.Forte@Sun.COM gettext("\t%s [opts] -P [set]\t\t\t"
52617836SJohn.Forte@Sun.COM "print sets verbose\n"), program);
52627836SJohn.Forte@Sun.COM
52637836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52647836SJohn.Forte@Sun.COM gettext("\t%s [opts] -p [set]\t\t\t"
52657836SJohn.Forte@Sun.COM "print sets\n"), program);
52667836SJohn.Forte@Sun.COM
52677836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52687836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R\t\t\t"
52697836SJohn.Forte@Sun.COM "reset error conditions\n"), program);
52707836SJohn.Forte@Sun.COM
52717836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52727836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R b p <bitmap> [set]\t"
52737836SJohn.Forte@Sun.COM "reconfig primary bitmap\n"), program);
52747836SJohn.Forte@Sun.COM
52757836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52767836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R b s <bitmap> [set]\t"
52777836SJohn.Forte@Sun.COM "reconfig secondary bitmap\n"), program);
52787836SJohn.Forte@Sun.COM
52797836SJohn.Forte@Sun.COM if (clustered)
52807836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52817836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R C <ctag> [set]\t"
52827836SJohn.Forte@Sun.COM "reconfig cluster tag\n"), program);
52837836SJohn.Forte@Sun.COM
52847836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
52857836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52867836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R d <pathname> [set]\t"
52877836SJohn.Forte@Sun.COM "reconfig campus direct file\n"), program);
52887836SJohn.Forte@Sun.COM #endif
52897836SJohn.Forte@Sun.COM
52907836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52917836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R -f <volset-file> \t"
52927836SJohn.Forte@Sun.COM "reconfig from file\n"), program);
52937836SJohn.Forte@Sun.COM
52947836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52957836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R g <group> [set]\t"
52967836SJohn.Forte@Sun.COM "reconfig group\n"), program);
52977836SJohn.Forte@Sun.COM
52987836SJohn.Forte@Sun.COM (void) fprintf(stderr,
52997836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R m {sync|async} [set]\t"
53007836SJohn.Forte@Sun.COM "reconfig mode\n"), program);
53017836SJohn.Forte@Sun.COM
53027836SJohn.Forte@Sun.COM if (allow_role)
53037836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53047836SJohn.Forte@Sun.COM gettext("\t%s [opts] -R r [set]\t\t"
53057836SJohn.Forte@Sun.COM "reverse roles\n"), program);
53067836SJohn.Forte@Sun.COM
53077836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53087836SJohn.Forte@Sun.COM gettext("\t%s [opts] -u [set]\t\t\t"
53097836SJohn.Forte@Sun.COM "update sync\n"), program);
53107836SJohn.Forte@Sun.COM
53117836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53127836SJohn.Forte@Sun.COM gettext("\t%s [opts] -u -r [set]\t\t"
53137836SJohn.Forte@Sun.COM "update reverse sync\n"), program);
53147836SJohn.Forte@Sun.COM
53157836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53167836SJohn.Forte@Sun.COM gettext("\t%s -v\t\t\t\tdisplay version\n"), program);
53177836SJohn.Forte@Sun.COM
53187836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53197836SJohn.Forte@Sun.COM gettext("\t%s [opts] -W <maxwrites> [set]\t"
53207836SJohn.Forte@Sun.COM "set maximum writes to queue\n"), program);
53217836SJohn.Forte@Sun.COM
53227836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53237836SJohn.Forte@Sun.COM gettext("\t%s [opts] -w [set]\t\t\t"
53247836SJohn.Forte@Sun.COM "wait\n"), program);
53257836SJohn.Forte@Sun.COM q_usage(0);
53267836SJohn.Forte@Sun.COM
53277836SJohn.Forte@Sun.COM (void) fprintf(stderr, gettext("\nopts:\n"));
53287836SJohn.Forte@Sun.COM (void) fprintf(stderr, gettext("\t-n\t\tnon-interactive mode "
53297836SJohn.Forte@Sun.COM "(not valid for print operations)\n"));
53307836SJohn.Forte@Sun.COM (void) fprintf(stderr, gettext(
53317836SJohn.Forte@Sun.COM "\t-g <group>\toperate on sets in group only "
53327836SJohn.Forte@Sun.COM "(not valid for enable\n\t\t\toperations)\n"));
53337836SJohn.Forte@Sun.COM if (clustered)
53347836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53357836SJohn.Forte@Sun.COM gettext("\t-C <ctag>\tignore sets not in cluster ctag "
53367836SJohn.Forte@Sun.COM "(not valid for enable\n\t\t\toperations)\n"));
53377836SJohn.Forte@Sun.COM
53387836SJohn.Forte@Sun.COM (void) fprintf(stderr, gettext("\nset:\n"));
53397836SJohn.Forte@Sun.COM if (clustered)
53407836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53417836SJohn.Forte@Sun.COM gettext("\t<phost> <pdev> <pbmp> "
53427836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
53437836SJohn.Forte@Sun.COM "<shost> <sdev> <sbmp> {ip | <directfile>} "
53447836SJohn.Forte@Sun.COM #else
53457836SJohn.Forte@Sun.COM "<shost> <sdev> <sbmp> ip "
53467836SJohn.Forte@Sun.COM #endif
53477836SJohn.Forte@Sun.COM "\\\n\t\t{sync | async} [g <group>] [q <qdev>] "
53487836SJohn.Forte@Sun.COM "[C <ctag>]\n"));
53497836SJohn.Forte@Sun.COM else
53507836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53517836SJohn.Forte@Sun.COM gettext("\t<phost> <pdev> <pbmp> "
53527836SJohn.Forte@Sun.COM #ifdef _RDC_CAMPUS
53537836SJohn.Forte@Sun.COM "<shost> <sdev> <sbmp> {ip | <directfile>} "
53547836SJohn.Forte@Sun.COM #else
53557836SJohn.Forte@Sun.COM "<shost> <sdev> <sbmp> ip "
53567836SJohn.Forte@Sun.COM #endif
53577836SJohn.Forte@Sun.COM "\\\n\t\t{sync | async} [g <group>] [q <qdev>]\n"));
53587836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53597836SJohn.Forte@Sun.COM gettext("\t<shost>:<sdev>\t\t"
53607836SJohn.Forte@Sun.COM "operate on set matching shost and sdev\n"));
53617836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53627836SJohn.Forte@Sun.COM gettext("\t-f volset-file\t\t"
53637836SJohn.Forte@Sun.COM "operate on all sets specified in config file\n"
53647836SJohn.Forte@Sun.COM "\t\t\t\tnote: not valid for single set operations. See\n"
53657836SJohn.Forte@Sun.COM "\t\t\t\t%s(1RDC).\n"), program);
53667836SJohn.Forte@Sun.COM (void) fprintf(stderr,
53677836SJohn.Forte@Sun.COM gettext("\t<no arg>\t\toperate on all configured sets\n"));
53687836SJohn.Forte@Sun.COM }
53697836SJohn.Forte@Sun.COM
53707836SJohn.Forte@Sun.COM int
53717836SJohn.Forte@Sun.COM prompt_user(int flag, int options)
53727836SJohn.Forte@Sun.COM {
53737836SJohn.Forte@Sun.COM int c;
53747836SJohn.Forte@Sun.COM
53757836SJohn.Forte@Sun.COM switch (flag) {
53767836SJohn.Forte@Sun.COM case RDC_CMD_DISABLE:
53777836SJohn.Forte@Sun.COM (void) printf(gettext("Disable Remote Mirror? (Y/N) [N]: "));
53787836SJohn.Forte@Sun.COM break;
53797836SJohn.Forte@Sun.COM case RDC_CMD_ENABLE:
53807836SJohn.Forte@Sun.COM (void) printf(gettext("Enable Remote Mirror? (Y/N) [N]: "));
53817836SJohn.Forte@Sun.COM break;
53827836SJohn.Forte@Sun.COM case RDC_CMD_HEALTH:
53837836SJohn.Forte@Sun.COM (void) printf(gettext("Report Remote Mirror link health? (Y/N)"
53847836SJohn.Forte@Sun.COM "[N]: "));
53857836SJohn.Forte@Sun.COM break;
53867836SJohn.Forte@Sun.COM case RDC_CMD_COPY:
53877836SJohn.Forte@Sun.COM if (options & RDC_OPT_FULL) {
53887836SJohn.Forte@Sun.COM if (options & RDC_OPT_REVERSE)
53897836SJohn.Forte@Sun.COM (void) printf(gettext("Overwrite primary with"
53907836SJohn.Forte@Sun.COM " secondary? (Y/N) [N]: "));
53917836SJohn.Forte@Sun.COM else
53927836SJohn.Forte@Sun.COM (void) printf(gettext("Overwrite secondary with"
53937836SJohn.Forte@Sun.COM " primary? (Y/N) [N]: "));
53947836SJohn.Forte@Sun.COM } else {
53957836SJohn.Forte@Sun.COM if (options & RDC_OPT_REVERSE)
53967836SJohn.Forte@Sun.COM (void) printf(gettext("Refresh primary with"
53977836SJohn.Forte@Sun.COM " secondary? (Y/N) [N]: "));
53987836SJohn.Forte@Sun.COM else
53997836SJohn.Forte@Sun.COM (void) printf(gettext("Refresh secondary with"
54007836SJohn.Forte@Sun.COM " primary? (Y/N) [N]: "));
54017836SJohn.Forte@Sun.COM }
54027836SJohn.Forte@Sun.COM break;
54037836SJohn.Forte@Sun.COM case RDC_CMD_RECONFIG:
54047836SJohn.Forte@Sun.COM (void) printf(gettext(
54057836SJohn.Forte@Sun.COM "Perform Remote Mirror reconfiguration? (Y/N) [N]: "));
54067836SJohn.Forte@Sun.COM break;
54077836SJohn.Forte@Sun.COM case RDC_CMD_RESET:
54087836SJohn.Forte@Sun.COM (void) printf(gettext("Perform Remote Mirror reset? (Y/N) "
54097836SJohn.Forte@Sun.COM "[N]: "));
54107836SJohn.Forte@Sun.COM break;
54117836SJohn.Forte@Sun.COM case RDC_CMD_TUNABLE:
54127836SJohn.Forte@Sun.COM (void) printf(gettext("Change Remote Mirror tunable? (Y/N) "
54137836SJohn.Forte@Sun.COM "[N]: "));
54147836SJohn.Forte@Sun.COM break;
54157836SJohn.Forte@Sun.COM case RDC_CMD_LOG:
54167836SJohn.Forte@Sun.COM (void) printf(gettext(
54177836SJohn.Forte@Sun.COM "Put Remote Mirror into logging mode? (Y/N) [N]: "));
54187836SJohn.Forte@Sun.COM break;
54197836SJohn.Forte@Sun.COM case RDC_CMD_WAIT:
54207836SJohn.Forte@Sun.COM (void) printf(gettext(
54217836SJohn.Forte@Sun.COM "Wait for Remote Mirror sync completion? (Y/N) [N]: "));
54227836SJohn.Forte@Sun.COM break;
54237836SJohn.Forte@Sun.COM default:
54247836SJohn.Forte@Sun.COM (void) printf(gettext("Perform Remote Mirror operation? (Y/N) "
54257836SJohn.Forte@Sun.COM "[N]: "));
54267836SJohn.Forte@Sun.COM }
54277836SJohn.Forte@Sun.COM
54287836SJohn.Forte@Sun.COM c = getchar();
54297836SJohn.Forte@Sun.COM if ((c != 'y') && (c != 'Y')) {
54307836SJohn.Forte@Sun.COM (void) printf("\n");
54317836SJohn.Forte@Sun.COM return (-1);
54327836SJohn.Forte@Sun.COM }
54337836SJohn.Forte@Sun.COM return (0);
54347836SJohn.Forte@Sun.COM }
54357836SJohn.Forte@Sun.COM
54367836SJohn.Forte@Sun.COM static void
54377836SJohn.Forte@Sun.COM load_rdc_vols(CFGFILE *cfg)
54387836SJohn.Forte@Sun.COM {
54397836SJohn.Forte@Sun.COM int set;
54407836SJohn.Forte@Sun.COM char key[ CFG_MAX_KEY ];
54417836SJohn.Forte@Sun.COM char buf[ CFG_MAX_BUF ];
54427836SJohn.Forte@Sun.COM _sd_dual_pair_t pair;
54437836SJohn.Forte@Sun.COM char *vol, *bmp;
54447836SJohn.Forte@Sun.COM char *host1 = pair.fhost, *host2 = pair.thost;
54457836SJohn.Forte@Sun.COM char *diskqueue = pair.diskqueue;
54467836SJohn.Forte@Sun.COM volcount_t *volcount;
54477836SJohn.Forte@Sun.COM char lghn[ MAX_RDC_HOST_SIZE ];
54487836SJohn.Forte@Sun.COM
54497836SJohn.Forte@Sun.COM if (volhash) {
54507836SJohn.Forte@Sun.COM return;
54517836SJohn.Forte@Sun.COM }
54527836SJohn.Forte@Sun.COM
54537836SJohn.Forte@Sun.COM cfg_rewind(cfg, CFG_SEC_CONF);
54547836SJohn.Forte@Sun.COM volhash = nsc_create_hash();
54557836SJohn.Forte@Sun.COM for (set = 1; /*CSTYLED*/; set++) {
54567836SJohn.Forte@Sun.COM (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d", set);
54577836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) {
54587836SJohn.Forte@Sun.COM break;
54597836SJohn.Forte@Sun.COM }
54607836SJohn.Forte@Sun.COM
54617836SJohn.Forte@Sun.COM if (parse_cfg_buf(buf, &pair, lghn))
54627836SJohn.Forte@Sun.COM continue;
54637836SJohn.Forte@Sun.COM vol = pair.ffile;
54647836SJohn.Forte@Sun.COM bmp = pair.fbitmap;
54657836SJohn.Forte@Sun.COM
54667836SJohn.Forte@Sun.COM /* use lghn if possible */
54677836SJohn.Forte@Sun.COM if (*lghn) {
54687836SJohn.Forte@Sun.COM if (strcmp(host2, lghn) == 0) {
54697836SJohn.Forte@Sun.COM vol = pair.tfile;
54707836SJohn.Forte@Sun.COM bmp = pair.tbitmap;
54717836SJohn.Forte@Sun.COM }
54727836SJohn.Forte@Sun.COM } else if (!self_check(host1)) {
54737836SJohn.Forte@Sun.COM /* next one had better be ours */
54747836SJohn.Forte@Sun.COM vol = pair.tfile;
54757836SJohn.Forte@Sun.COM bmp = pair.tbitmap;
54767836SJohn.Forte@Sun.COM
54777836SJohn.Forte@Sun.COM if (!self_check(host2)) {
54787836SJohn.Forte@Sun.COM rdc_warn(NULL,
54797836SJohn.Forte@Sun.COM gettext("config error: neither %s nor %s"
54807836SJohn.Forte@Sun.COM " is localhost"), host1, host2);
54817836SJohn.Forte@Sun.COM continue;
54827836SJohn.Forte@Sun.COM }
54837836SJohn.Forte@Sun.COM }
54847836SJohn.Forte@Sun.COM
54857836SJohn.Forte@Sun.COM /* primary vol may be used more than once */
54867836SJohn.Forte@Sun.COM volcount = (volcount_t *)nsc_lookup(volhash, vol);
54877836SJohn.Forte@Sun.COM if (volcount) {
54887836SJohn.Forte@Sun.COM volcount->count++;
54897836SJohn.Forte@Sun.COM } else {
54907836SJohn.Forte@Sun.COM volcount = (volcount_t *)malloc(sizeof (volcount_t));
54917836SJohn.Forte@Sun.COM volcount->count = 1;
54927836SJohn.Forte@Sun.COM (void) nsc_insert_node(volhash, volcount, vol);
54937836SJohn.Forte@Sun.COM }
54947836SJohn.Forte@Sun.COM
54957836SJohn.Forte@Sun.COM /* bitmap ought to be only used once */
54967836SJohn.Forte@Sun.COM volcount = (volcount_t *)nsc_lookup(volhash, bmp);
54977836SJohn.Forte@Sun.COM if (volcount) {
54987836SJohn.Forte@Sun.COM /* argh */
54997836SJohn.Forte@Sun.COM volcount->count++;
55007836SJohn.Forte@Sun.COM } else {
55017836SJohn.Forte@Sun.COM volcount = (volcount_t *)malloc(sizeof (volcount_t));
55027836SJohn.Forte@Sun.COM volcount->count = 1;
55037836SJohn.Forte@Sun.COM (void) nsc_insert_node(volhash, volcount, bmp);
55047836SJohn.Forte@Sun.COM }
55057836SJohn.Forte@Sun.COM
55067836SJohn.Forte@Sun.COM if (strcmp(diskqueue, place_holder) == 0)
55077836SJohn.Forte@Sun.COM continue;
55087836SJohn.Forte@Sun.COM /* diskqueue vol may be used more than once */
55097836SJohn.Forte@Sun.COM volcount = (volcount_t *)nsc_lookup(volhash, diskqueue);
55107836SJohn.Forte@Sun.COM if (volcount) {
55117836SJohn.Forte@Sun.COM volcount->count++;
55127836SJohn.Forte@Sun.COM } else {
55137836SJohn.Forte@Sun.COM volcount = (volcount_t *)malloc(sizeof (volcount_t));
55147836SJohn.Forte@Sun.COM volcount->count = 1;
55157836SJohn.Forte@Sun.COM (void) nsc_insert_node(volhash, volcount, diskqueue);
55167836SJohn.Forte@Sun.COM }
55177836SJohn.Forte@Sun.COM }
55187836SJohn.Forte@Sun.COM }
55197836SJohn.Forte@Sun.COM
55207836SJohn.Forte@Sun.COM static void
55217836SJohn.Forte@Sun.COM unload_rdc_vols()
55227836SJohn.Forte@Sun.COM {
55237836SJohn.Forte@Sun.COM nsc_remove_all(volhash, free);
55247836SJohn.Forte@Sun.COM volhash = 0;
55257836SJohn.Forte@Sun.COM }
55267836SJohn.Forte@Sun.COM
55277836SJohn.Forte@Sun.COM static int
55287836SJohn.Forte@Sun.COM perform_autosv()
55297836SJohn.Forte@Sun.COM {
55307836SJohn.Forte@Sun.COM if (!clustered) {
55317836SJohn.Forte@Sun.COM return (1);
55327836SJohn.Forte@Sun.COM } else {
55337836SJohn.Forte@Sun.COM return (cfg_issuncluster());
55347836SJohn.Forte@Sun.COM }
55357836SJohn.Forte@Sun.COM }
55367836SJohn.Forte@Sun.COM
55377836SJohn.Forte@Sun.COM /*
55387836SJohn.Forte@Sun.COM * Check the user supplied fields against those in the dscfg for
55397836SJohn.Forte@Sun.COM * this set.
55407836SJohn.Forte@Sun.COM * Never returns on an error.
55417836SJohn.Forte@Sun.COM */
55427836SJohn.Forte@Sun.COM static void
55437836SJohn.Forte@Sun.COM checkgfields(CFGFILE *cfg, int setnumber, char *fromhost, char *fromfile,
55447836SJohn.Forte@Sun.COM char *frombitmap, char *tobitmap, char *type, char *mode, char *group,
55457836SJohn.Forte@Sun.COM char *ctag, char *diskq)
55467836SJohn.Forte@Sun.COM {
55477836SJohn.Forte@Sun.COM if (fromhost[0])
55487836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "phost",
55497836SJohn.Forte@Sun.COM gettext("primary host"), fromhost);
55507836SJohn.Forte@Sun.COM if (fromfile[0])
55517836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "primary",
55527836SJohn.Forte@Sun.COM gettext("primary volume"), fromfile);
55537836SJohn.Forte@Sun.COM if (frombitmap[0])
55547836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "pbitmap",
55557836SJohn.Forte@Sun.COM gettext("primary bitmap"), frombitmap);
55567836SJohn.Forte@Sun.COM if (tobitmap[0])
55577836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "sbitmap",
55587836SJohn.Forte@Sun.COM gettext("secondary bitmap"), tobitmap);
55597836SJohn.Forte@Sun.COM if (type[0])
55607836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "type",
55617836SJohn.Forte@Sun.COM gettext("type of connection"), type);
55627836SJohn.Forte@Sun.COM if (mode[0])
55637836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "mode",
55647836SJohn.Forte@Sun.COM gettext("mode of connection"), mode);
55657836SJohn.Forte@Sun.COM if (group[0])
55667836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "group",
55677836SJohn.Forte@Sun.COM gettext("group"), group);
55687836SJohn.Forte@Sun.COM if (ctag[0])
55697836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "cnode",
55707836SJohn.Forte@Sun.COM gettext("cluster tag"), ctag);
55717836SJohn.Forte@Sun.COM if (diskq[0])
55727836SJohn.Forte@Sun.COM checkgfield(cfg, setnumber, "diskq",
55737836SJohn.Forte@Sun.COM gettext("disk queue volume"), diskq);
55747836SJohn.Forte@Sun.COM }
55757836SJohn.Forte@Sun.COM
55767836SJohn.Forte@Sun.COM /*
55777836SJohn.Forte@Sun.COM * Check the 'fname' field in the dscfg file for set number 'setnumber'
55787836SJohn.Forte@Sun.COM * If it does not match the user's data, 'data', then print the error
55797836SJohn.Forte@Sun.COM * message using the friendly field name 'ufield'.
55807836SJohn.Forte@Sun.COM * Never returns on an error.
55817836SJohn.Forte@Sun.COM */
55827836SJohn.Forte@Sun.COM static void
55837836SJohn.Forte@Sun.COM checkgfield(CFGFILE *cfg, int setnumber, char *fname, char *ufield, char *data)
55847836SJohn.Forte@Sun.COM {
55857836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
55867836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
55877836SJohn.Forte@Sun.COM
55887836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.%s", setnumber, fname);
55897836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
55907836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to fetch data for key %s"),
55917836SJohn.Forte@Sun.COM key);
55927836SJohn.Forte@Sun.COM }
55937836SJohn.Forte@Sun.COM if (strcmp(buf, data) != 0) {
55947836SJohn.Forte@Sun.COM rdc_err(NULL,
55957836SJohn.Forte@Sun.COM gettext("the value specified for the %s field is not\nthe "
55967836SJohn.Forte@Sun.COM "same as that contained within the configuration storage "
55977836SJohn.Forte@Sun.COM "file for this set.\nYou specified \"%s\" "
55987836SJohn.Forte@Sun.COM "expected \"%s\"."),
55997836SJohn.Forte@Sun.COM ufield, data, buf);
56007836SJohn.Forte@Sun.COM }
56017836SJohn.Forte@Sun.COM }
56027836SJohn.Forte@Sun.COM
56037836SJohn.Forte@Sun.COM /*
56047836SJohn.Forte@Sun.COM * load and send the contents of the bitmap file to the kernel.
56057836SJohn.Forte@Sun.COM */
56067836SJohn.Forte@Sun.COM static int
56077836SJohn.Forte@Sun.COM rdc_bitmapset(char *tohost, char *tofile, char *bitmap, int op,
56087836SJohn.Forte@Sun.COM nsc_off_t offset)
56097836SJohn.Forte@Sun.COM {
56107836SJohn.Forte@Sun.COM rdc_bitmap_op_t bmop;
56117836SJohn.Forte@Sun.COM int fd;
56127836SJohn.Forte@Sun.COM void *buffer;
56137836SJohn.Forte@Sun.COM int buffersz;
56147836SJohn.Forte@Sun.COM struct stat s;
56157836SJohn.Forte@Sun.COM int n;
56167836SJohn.Forte@Sun.COM int ret;
56177836SJohn.Forte@Sun.COM /*
56187836SJohn.Forte@Sun.COM * open bitmap file for reading.
56197836SJohn.Forte@Sun.COM */
56207836SJohn.Forte@Sun.COM if ((fd = open(bitmap, O_RDONLY)) < 0) {
56217836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to open bitmap file %s"),
56227836SJohn.Forte@Sun.COM bitmap);
56237836SJohn.Forte@Sun.COM return (1);
56247836SJohn.Forte@Sun.COM }
5625*11576SSurya.Prakki@Sun.COM (void) fstat(fd, &s);
56267836SJohn.Forte@Sun.COM
56277836SJohn.Forte@Sun.COM if (S_ISREG(s.st_mode) == 0) {
56287836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Bitmap %s is not a regular file"),
56297836SJohn.Forte@Sun.COM bitmap);
56307836SJohn.Forte@Sun.COM (void) close(fd);
56317836SJohn.Forte@Sun.COM return (1);
56327836SJohn.Forte@Sun.COM }
56337836SJohn.Forte@Sun.COM
56347836SJohn.Forte@Sun.COM if (op == 0) {
56357836SJohn.Forte@Sun.COM op = RDC_BITMAPOR;
56367836SJohn.Forte@Sun.COM }
56377836SJohn.Forte@Sun.COM /*
56387836SJohn.Forte@Sun.COM * use the file size to allocate buffer. This
56397836SJohn.Forte@Sun.COM * size should be a multiple of FBA, but don't check
56407836SJohn.Forte@Sun.COM * it here.
56417836SJohn.Forte@Sun.COM */
56427836SJohn.Forte@Sun.COM buffersz = s.st_size;
56437836SJohn.Forte@Sun.COM buffer = malloc(buffersz);
56447836SJohn.Forte@Sun.COM if (buffer == NULL) {
56457836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to allocate %d bytes "
56467836SJohn.Forte@Sun.COM "for bitmap file %s"), buffersz, bitmap);
56477836SJohn.Forte@Sun.COM (void) close(fd);
56487836SJohn.Forte@Sun.COM return (1);
56497836SJohn.Forte@Sun.COM }
56507836SJohn.Forte@Sun.COM n = read(fd, buffer, buffersz);
56517836SJohn.Forte@Sun.COM (void) close(fd);
56527836SJohn.Forte@Sun.COM if (n != buffersz) {
56537836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Unable to read the bitmap file, "
56547836SJohn.Forte@Sun.COM "read returned %d instead of %d"),
56557836SJohn.Forte@Sun.COM n, buffersz);
56567836SJohn.Forte@Sun.COM free(buffer);
56577836SJohn.Forte@Sun.COM return (1);
56587836SJohn.Forte@Sun.COM }
56597836SJohn.Forte@Sun.COM bmop.offset = offset;
56607836SJohn.Forte@Sun.COM bmop.op = op;
5661*11576SSurya.Prakki@Sun.COM (void) strncpy(bmop.sechost, tohost, MAX_RDC_HOST_SIZE);
5662*11576SSurya.Prakki@Sun.COM (void) strncpy(bmop.secfile, tofile, NSC_MAXPATH);
56637836SJohn.Forte@Sun.COM bmop.len = buffersz;
56647836SJohn.Forte@Sun.COM bmop.addr = (unsigned long)buffer;
56657836SJohn.Forte@Sun.COM ret = rdc_ioctl_simple(RDC_BITMAPOP, &bmop);
56667836SJohn.Forte@Sun.COM free(buffer);
56677836SJohn.Forte@Sun.COM if (ret < 0) {
56687836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("Setting bitmap ioctl failed for set "
56697836SJohn.Forte@Sun.COM "%s:%s"), tohost, tofile);
56707836SJohn.Forte@Sun.COM
56717836SJohn.Forte@Sun.COM switch (errno) {
56727836SJohn.Forte@Sun.COM case EIO:
56737836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("One of the sets is not "
56747836SJohn.Forte@Sun.COM "enabled"));
56757836SJohn.Forte@Sun.COM break;
56767836SJohn.Forte@Sun.COM case ENXIO:
56777836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("One of the sets is not "
56787836SJohn.Forte@Sun.COM "logging"));
56797836SJohn.Forte@Sun.COM break;
56807836SJohn.Forte@Sun.COM default:
56817836SJohn.Forte@Sun.COM break;
56827836SJohn.Forte@Sun.COM }
56837836SJohn.Forte@Sun.COM } else {
56847836SJohn.Forte@Sun.COM ret = 0;
56857836SJohn.Forte@Sun.COM }
56867836SJohn.Forte@Sun.COM if (ret)
56877836SJohn.Forte@Sun.COM ret = 1;
56887836SJohn.Forte@Sun.COM return (ret);
56897836SJohn.Forte@Sun.COM }
56907836SJohn.Forte@Sun.COM
56917836SJohn.Forte@Sun.COM /*
56927836SJohn.Forte@Sun.COM * verify_groupname: Check the group name for the following rules:
56937836SJohn.Forte@Sun.COM * 1. The name does not start with a '-'
56947836SJohn.Forte@Sun.COM * 2. The name does not contain any space characters as defined by
56957836SJohn.Forte@Sun.COM * isspace(3C).
56967836SJohn.Forte@Sun.COM *
56977836SJohn.Forte@Sun.COM * If either of these rules are broken, error immediately.
56987836SJohn.Forte@Sun.COM */
56997836SJohn.Forte@Sun.COM static void
57007836SJohn.Forte@Sun.COM verify_groupname(char *grp)
57017836SJohn.Forte@Sun.COM {
57027836SJohn.Forte@Sun.COM int i;
57037836SJohn.Forte@Sun.COM
57047836SJohn.Forte@Sun.COM if (grp[0] == '-') {
57057836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("group name cannot start with a '-'"));
57067836SJohn.Forte@Sun.COM }
57077836SJohn.Forte@Sun.COM
57087836SJohn.Forte@Sun.COM for (i = 0; grp[i] != '\0'; i++) {
57097836SJohn.Forte@Sun.COM if (isspace(grp[i])) {
57107836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("group name cannot contain a "
57117836SJohn.Forte@Sun.COM "space"));
57127836SJohn.Forte@Sun.COM }
57137836SJohn.Forte@Sun.COM }
57147836SJohn.Forte@Sun.COM }
5715