xref: /onnv-gate/usr/src/cmd/avs/rdc/sndrboot.c (revision 11576:b23c42c0c9d6)
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 
287836SJohn.Forte@Sun.COM #include <sys/types.h>
297836SJohn.Forte@Sun.COM #include <sys/wait.h>
307836SJohn.Forte@Sun.COM #include <stdio.h>
317836SJohn.Forte@Sun.COM #include <sys/mnttab.h>
327836SJohn.Forte@Sun.COM #include <errno.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 
397836SJohn.Forte@Sun.COM #include <locale.h>
407836SJohn.Forte@Sun.COM #include <langinfo.h>
417836SJohn.Forte@Sun.COM #include <libintl.h>
427836SJohn.Forte@Sun.COM #include <stdarg.h>
437836SJohn.Forte@Sun.COM #include <netdb.h>
447836SJohn.Forte@Sun.COM #include <ctype.h>
457836SJohn.Forte@Sun.COM #include <sys/utsname.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 #include <sys/nsctl/cfg_cluster.h>
537836SJohn.Forte@Sun.COM 
547836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
557836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_u.h>
567836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
577836SJohn.Forte@Sun.COM 
587836SJohn.Forte@Sun.COM #include "rdcadm.h"
597836SJohn.Forte@Sun.COM 
607836SJohn.Forte@Sun.COM /*
617836SJohn.Forte@Sun.COM  * Special re-use of sndrboot to fix SNDR set IDs during post-patch processing
627836SJohn.Forte@Sun.COM  */
637836SJohn.Forte@Sun.COM #define	RDC_CMD_FIXSETIDS	0xFEEDFACE
647836SJohn.Forte@Sun.COM 
657836SJohn.Forte@Sun.COM /*
667836SJohn.Forte@Sun.COM  * config file user level Dual copy pair structure
677836SJohn.Forte@Sun.COM  */
687836SJohn.Forte@Sun.COM typedef struct _sd_dual_pair {
697836SJohn.Forte@Sun.COM 	char fhost[MAX_RDC_HOST_SIZE];	/* Hostname for primary device */
707836SJohn.Forte@Sun.COM 	char fnetaddr[RDC_MAXADDR];	/* Host netaddr for primary device */
717836SJohn.Forte@Sun.COM 	char ffile[NSC_MAXPATH];	/* Primary device */
727836SJohn.Forte@Sun.COM 	char fbitmap[NSC_MAXPATH];	/* Primary bitmap device */
737836SJohn.Forte@Sun.COM 	char thost[MAX_RDC_HOST_SIZE];	/* Hostname for secondary device */
747836SJohn.Forte@Sun.COM 	char tnetaddr[RDC_MAXADDR];	/* Host netaddr for secondary device */
757836SJohn.Forte@Sun.COM 	char tfile[NSC_MAXPATH];	/* Secondary device */
767836SJohn.Forte@Sun.COM 	char tbitmap[NSC_MAXPATH];	/* Secondary bitmap device */
777836SJohn.Forte@Sun.COM 	char directfile[NSC_MAXPATH];	/* Local FCAL direct IO volume */
787836SJohn.Forte@Sun.COM 	char diskqueue[NSC_MAXPATH];	/* Disk Queue volume */
797836SJohn.Forte@Sun.COM 	char group[NSC_MAXPATH];	/* Group name */
807836SJohn.Forte@Sun.COM 	char lhost[MAX_RDC_HOST_SIZE];  /* Logical hostname for cluster */
817836SJohn.Forte@Sun.COM 	int  doasync;			/* Device is in sync/async mode */
827836SJohn.Forte@Sun.COM 	int  setid;			/* unique setid of this set */
837836SJohn.Forte@Sun.COM } _sd_dual_pair_t;
847836SJohn.Forte@Sun.COM 
857836SJohn.Forte@Sun.COM #include <sys/socket.h>
867836SJohn.Forte@Sun.COM #include <netinet/in.h>
877836SJohn.Forte@Sun.COM #include <arpa/inet.h>
887836SJohn.Forte@Sun.COM #include <netinet/tcp.h>
897836SJohn.Forte@Sun.COM #include <rpc/rpc_com.h>
907836SJohn.Forte@Sun.COM #include <rpc/rpc.h>
917836SJohn.Forte@Sun.COM 
927836SJohn.Forte@Sun.COM #include <sys/nsctl/librdc.h>
937836SJohn.Forte@Sun.COM 
947836SJohn.Forte@Sun.COM char *ctag = NULL;
957836SJohn.Forte@Sun.COM 
967836SJohn.Forte@Sun.COM int parseopts(int, char **, int *);
977836SJohn.Forte@Sun.COM static int rdc_operation(char *, char *, char *, char *, char *, char *, int,
987836SJohn.Forte@Sun.COM     char *, char *, char *, int, char *, int setid);
997836SJohn.Forte@Sun.COM static int read_libcfg(int);
1007836SJohn.Forte@Sun.COM static void usage(void);
1017836SJohn.Forte@Sun.COM 
1027836SJohn.Forte@Sun.COM extern char *basename(char *);
1037836SJohn.Forte@Sun.COM 
1047836SJohn.Forte@Sun.COM int rdc_maxsets;
1057836SJohn.Forte@Sun.COM static _sd_dual_pair_t *pair_list;
1067836SJohn.Forte@Sun.COM char *program;
1077836SJohn.Forte@Sun.COM 
1087836SJohn.Forte@Sun.COM struct netbuf svaddr;
1097836SJohn.Forte@Sun.COM struct netbuf *svp;
1107836SJohn.Forte@Sun.COM struct netconfig nconf;
1117836SJohn.Forte@Sun.COM struct netconfig *conf;
1127836SJohn.Forte@Sun.COM struct knetconfig knconf;
1137836SJohn.Forte@Sun.COM static int clustered = 0;
1147836SJohn.Forte@Sun.COM static int proto_test = 0;
1157836SJohn.Forte@Sun.COM 
1167836SJohn.Forte@Sun.COM #ifdef lint
1177836SJohn.Forte@Sun.COM int
sndrboot_lintmain(int argc,char * argv[])1187836SJohn.Forte@Sun.COM sndrboot_lintmain(int argc, char *argv[])
1197836SJohn.Forte@Sun.COM #else
1207836SJohn.Forte@Sun.COM int
1217836SJohn.Forte@Sun.COM main(int argc, char *argv[])
1227836SJohn.Forte@Sun.COM #endif
1237836SJohn.Forte@Sun.COM {
1247836SJohn.Forte@Sun.COM 	char fromhost[MAX_RDC_HOST_SIZE];
1257836SJohn.Forte@Sun.COM 	char tohost[MAX_RDC_HOST_SIZE];
1267836SJohn.Forte@Sun.COM 	char fromfile[NSC_MAXPATH];
1277836SJohn.Forte@Sun.COM 	char tofile[NSC_MAXPATH];
1287836SJohn.Forte@Sun.COM 	char frombitmap[NSC_MAXPATH];
1297836SJohn.Forte@Sun.COM 	char tobitmap[NSC_MAXPATH];
1307836SJohn.Forte@Sun.COM 	char directfile[NSC_MAXPATH];
1317836SJohn.Forte@Sun.COM 	char diskqueue[NSC_MAXPATH];
1327836SJohn.Forte@Sun.COM 	char group[NSC_MAXPATH];
1337836SJohn.Forte@Sun.COM 	char lhost[MAX_RDC_HOST_SIZE];
1347836SJohn.Forte@Sun.COM 	int pairs;
1357836SJohn.Forte@Sun.COM 	int pid;
1367836SJohn.Forte@Sun.COM 	int flag = 0;
1377836SJohn.Forte@Sun.COM 	int doasync;
1387836SJohn.Forte@Sun.COM 	int rc;
1397836SJohn.Forte@Sun.COM 	char *required;
1407836SJohn.Forte@Sun.COM 	int setid;
1417836SJohn.Forte@Sun.COM 
1427836SJohn.Forte@Sun.COM 	(void) setlocale(LC_ALL, "");
1437836SJohn.Forte@Sun.COM 	(void) textdomain("rdc");
1447836SJohn.Forte@Sun.COM 
1457836SJohn.Forte@Sun.COM 	program = basename(argv[0]);
1467836SJohn.Forte@Sun.COM 
1477836SJohn.Forte@Sun.COM 	rc = rdc_check_release(&required);
1487836SJohn.Forte@Sun.COM 	if (rc < 0) {
1497836SJohn.Forte@Sun.COM 		rdc_err(NULL,
1507836SJohn.Forte@Sun.COM 		    gettext("unable to determine the current "
1517836SJohn.Forte@Sun.COM 		    "Solaris release: %s\n"), strerror(errno));
1527836SJohn.Forte@Sun.COM 	} else if (rc == FALSE) {
1537836SJohn.Forte@Sun.COM 		rdc_err(NULL,
1547836SJohn.Forte@Sun.COM 		    gettext("incorrect Solaris release (requires %s)\n"),
1557836SJohn.Forte@Sun.COM 		    required);
1567836SJohn.Forte@Sun.COM 	}
1577836SJohn.Forte@Sun.COM 
1587836SJohn.Forte@Sun.COM 	rdc_maxsets = rdc_get_maxsets();
1597836SJohn.Forte@Sun.COM 	if (rdc_maxsets == -1) {
1607836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
1617836SJohn.Forte@Sun.COM 		    gettext("%s unable to get maxsets value from kernel"),
1627836SJohn.Forte@Sun.COM 		    program);
1637836SJohn.Forte@Sun.COM 
1647836SJohn.Forte@Sun.COM 		rdc_err(NULL,
1657836SJohn.Forte@Sun.COM 		    gettext("unable to get maxsets value from kernel"));
1667836SJohn.Forte@Sun.COM 	}
1677836SJohn.Forte@Sun.COM 
1687836SJohn.Forte@Sun.COM 	pair_list = calloc(rdc_maxsets, sizeof (*pair_list));
1697836SJohn.Forte@Sun.COM 	if (pair_list == NULL) {
1707836SJohn.Forte@Sun.COM 		rdc_err(NULL,
1717836SJohn.Forte@Sun.COM 		    gettext(
1727836SJohn.Forte@Sun.COM 			"unable to allocate pair_list"
1737836SJohn.Forte@Sun.COM 			" array for %d sets"),
1747836SJohn.Forte@Sun.COM 			rdc_maxsets);
1757836SJohn.Forte@Sun.COM 	}
1767836SJohn.Forte@Sun.COM 
1777836SJohn.Forte@Sun.COM 	if (parseopts(argc, argv, &flag))
1787836SJohn.Forte@Sun.COM 		return (1);
1797836SJohn.Forte@Sun.COM 	pairs = read_libcfg(flag);
1807836SJohn.Forte@Sun.COM 
1817836SJohn.Forte@Sun.COM 	if (flag == RDC_CMD_FIXSETIDS) {
1827836SJohn.Forte@Sun.COM 		if (pairs) {
1837836SJohn.Forte@Sun.COM 			spcs_log("sndr", NULL, gettext("Fixed %d Remote Mirror"
1847836SJohn.Forte@Sun.COM 				    " set IDs"), pairs);
1857836SJohn.Forte@Sun.COM #ifdef DEBUG
1867836SJohn.Forte@Sun.COM 			rdc_warn(NULL, gettext("Fixed %d Remote Mirror set "
1877836SJohn.Forte@Sun.COM 				    "IDs"), pairs);
1887836SJohn.Forte@Sun.COM #endif
1897836SJohn.Forte@Sun.COM 		}
1907836SJohn.Forte@Sun.COM 		return (0);
1917836SJohn.Forte@Sun.COM 	}
1927836SJohn.Forte@Sun.COM 
1937836SJohn.Forte@Sun.COM 	if (pairs == 0) {
1947836SJohn.Forte@Sun.COM #ifdef DEBUG
1957836SJohn.Forte@Sun.COM 		rdc_err(NULL,
1967836SJohn.Forte@Sun.COM 		    gettext("Config contains no dual copy sets"));
1977836SJohn.Forte@Sun.COM #else
1987836SJohn.Forte@Sun.COM 		return (0);
1997836SJohn.Forte@Sun.COM #endif
2007836SJohn.Forte@Sun.COM 	}
2017836SJohn.Forte@Sun.COM 
2027836SJohn.Forte@Sun.COM 	while (pairs--) {
2037836SJohn.Forte@Sun.COM 		pid = fork();
2047836SJohn.Forte@Sun.COM 		if (pid == -1) {		/* error forking */
2057836SJohn.Forte@Sun.COM 			perror("fork");
2067836SJohn.Forte@Sun.COM 			continue;
2077836SJohn.Forte@Sun.COM 		}
2087836SJohn.Forte@Sun.COM 
2097836SJohn.Forte@Sun.COM 		if (pid > 0)		/* this is parent process */
2107836SJohn.Forte@Sun.COM 			continue;
2117836SJohn.Forte@Sun.COM 
2127836SJohn.Forte@Sun.COM /*
2137836SJohn.Forte@Sun.COM  * At this point, this is the child process.  Do the operation
2147836SJohn.Forte@Sun.COM  */
2157836SJohn.Forte@Sun.COM 
216*11576SSurya.Prakki@Sun.COM 		(void) strncpy(fromfile,
217*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].ffile, NSC_MAXPATH);
218*11576SSurya.Prakki@Sun.COM 		(void) strncpy(tofile,
219*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].tfile, NSC_MAXPATH);
220*11576SSurya.Prakki@Sun.COM 		(void) strncpy(frombitmap,
221*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].fbitmap, NSC_MAXPATH);
222*11576SSurya.Prakki@Sun.COM 		(void) strncpy(fromhost,
223*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].fhost, MAX_RDC_HOST_SIZE);
224*11576SSurya.Prakki@Sun.COM 		(void) strncpy(tohost,
225*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].thost, MAX_RDC_HOST_SIZE);
226*11576SSurya.Prakki@Sun.COM 		(void) strncpy(tobitmap,
227*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].tbitmap, NSC_MAXPATH);
228*11576SSurya.Prakki@Sun.COM 		(void) strncpy(directfile,
229*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].directfile, NSC_MAXPATH);
230*11576SSurya.Prakki@Sun.COM 		(void) strncpy(diskqueue,
231*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].diskqueue, NSC_MAXPATH);
232*11576SSurya.Prakki@Sun.COM 		(void) strncpy(group,
233*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].group, NSC_MAXPATH);
234*11576SSurya.Prakki@Sun.COM 		(void) strncpy(lhost,
235*11576SSurya.Prakki@Sun.COM 		    pair_list[pairs].lhost, MAX_RDC_HOST_SIZE);
2367836SJohn.Forte@Sun.COM 
2377836SJohn.Forte@Sun.COM 		doasync = pair_list[pairs].doasync;
2387836SJohn.Forte@Sun.COM 		setid = pair_list[pairs].setid;
2397836SJohn.Forte@Sun.COM 		if (rdc_operation(fromhost, fromfile, frombitmap,
2407836SJohn.Forte@Sun.COM 		    tohost, tofile, tobitmap, flag, directfile, group,
2417836SJohn.Forte@Sun.COM 		    diskqueue, doasync, lhost, setid)
2427836SJohn.Forte@Sun.COM 		    < 0) {
2437836SJohn.Forte@Sun.COM 			exit(255);
2447836SJohn.Forte@Sun.COM 		}
2457836SJohn.Forte@Sun.COM 
2467836SJohn.Forte@Sun.COM 		exit(0);
2477836SJohn.Forte@Sun.COM 	}
2487836SJohn.Forte@Sun.COM 
2497836SJohn.Forte@Sun.COM 	while ((wait((int *)0) > 0))
2507836SJohn.Forte@Sun.COM 		;
2517836SJohn.Forte@Sun.COM 	return (0);
2527836SJohn.Forte@Sun.COM }
2537836SJohn.Forte@Sun.COM 
2547836SJohn.Forte@Sun.COM static int
rdc_operation(fromhost,fromfile,frombitmap,tohost,tofile,tobitmap,flag,directfile,group,diskqueue,doasync,lhost,setid)2557836SJohn.Forte@Sun.COM rdc_operation(fromhost, fromfile, frombitmap, tohost, tofile,
2567836SJohn.Forte@Sun.COM     tobitmap, flag, directfile, group, diskqueue, doasync,
2577836SJohn.Forte@Sun.COM     lhost, setid)
2587836SJohn.Forte@Sun.COM char *fromhost, *fromfile, *frombitmap;
2597836SJohn.Forte@Sun.COM char *tohost, *tofile, *tobitmap;
2607836SJohn.Forte@Sun.COM int flag, doasync;
2617836SJohn.Forte@Sun.COM char *directfile;
2627836SJohn.Forte@Sun.COM char *group, *diskqueue;
2637836SJohn.Forte@Sun.COM int setid;
2647836SJohn.Forte@Sun.COM char *lhost;
2657836SJohn.Forte@Sun.COM {
2667836SJohn.Forte@Sun.COM 	const int getaddr = (flag == RDC_CMD_RESUME);
2677836SJohn.Forte@Sun.COM 	const int rpcbind = !getaddr;
2687836SJohn.Forte@Sun.COM 	rdc_config_t parms;
2697836SJohn.Forte@Sun.COM 	int ret;
2707836SJohn.Forte@Sun.COM 	spcs_s_info_t ustatus;
2717836SJohn.Forte@Sun.COM 	struct hostent *hp;
2727836SJohn.Forte@Sun.COM 	char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
2737836SJohn.Forte@Sun.COM 	struct t_info tinfo;
2747836SJohn.Forte@Sun.COM 	int i;
2757836SJohn.Forte@Sun.COM 
2767836SJohn.Forte@Sun.COM 	conf = &nconf;
2777836SJohn.Forte@Sun.COM 	bzero(&fromname, MAXHOSTNAMELEN);
2787836SJohn.Forte@Sun.COM 	bzero(&toname, MAXHOSTNAMELEN);
2797836SJohn.Forte@Sun.COM 
2807836SJohn.Forte@Sun.COM 	hp = gethost_byname(fromhost);
2817836SJohn.Forte@Sun.COM 	if (hp == NULL) {
2827836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
2837836SJohn.Forte@Sun.COM 		    gettext("%s gethost_byname failed for %s"),
2847836SJohn.Forte@Sun.COM 		    program, fromhost);
2857836SJohn.Forte@Sun.COM 	}
2867836SJohn.Forte@Sun.COM 	if (strcmp(hp->h_name, fromhost) == 0)
287*11576SSurya.Prakki@Sun.COM 		(void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
2887836SJohn.Forte@Sun.COM 	else {
2897836SJohn.Forte@Sun.COM 	for (i = 0; hp->h_aliases[i] != NULL; i++) {
2907836SJohn.Forte@Sun.COM 		if (strcmp(hp->h_aliases[i], fromhost) == 0)
291*11576SSurya.Prakki@Sun.COM 			(void) strncpy(fromname, hp->h_aliases[i],
292*11576SSurya.Prakki@Sun.COM 			    MAXHOSTNAMELEN);
2937836SJohn.Forte@Sun.COM 		}
2947836SJohn.Forte@Sun.COM 	}
2957836SJohn.Forte@Sun.COM 	if (fromname[0] == '\0') {
2967836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
2977836SJohn.Forte@Sun.COM 		    gettext("%s host %s is not local"),
2987836SJohn.Forte@Sun.COM 		    program, fromhost);
2997836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Host %s is not local"),
3007836SJohn.Forte@Sun.COM 		    fromhost);
3017836SJohn.Forte@Sun.COM 	}
3027836SJohn.Forte@Sun.COM 	hp = gethost_byname(tohost);
3037836SJohn.Forte@Sun.COM 	if (hp == NULL) {
3047836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
3057836SJohn.Forte@Sun.COM 		    gettext("%s gethost_byname failed for %s"),
3067836SJohn.Forte@Sun.COM 		    program, tohost);
3077836SJohn.Forte@Sun.COM 	}
3087836SJohn.Forte@Sun.COM 	if (strcmp(hp->h_name, tohost) == 0)
309*11576SSurya.Prakki@Sun.COM 		(void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
3107836SJohn.Forte@Sun.COM 	else {
3117836SJohn.Forte@Sun.COM 	for (i = 0; hp->h_aliases[i] != NULL; i++) {
3127836SJohn.Forte@Sun.COM 		if (strcmp(hp->h_aliases[i], tohost) == 0)
313*11576SSurya.Prakki@Sun.COM 			(void) strncpy(toname, hp->h_aliases[i],
314*11576SSurya.Prakki@Sun.COM 			    MAXHOSTNAMELEN);
3157836SJohn.Forte@Sun.COM 		}
3167836SJohn.Forte@Sun.COM 	}
3177836SJohn.Forte@Sun.COM 	if (toname[0] == '\0') {
3187836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
3197836SJohn.Forte@Sun.COM 		    gettext("%s host %s is not local"),
3207836SJohn.Forte@Sun.COM 		    program, tohost);
3217836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Host %s is not local"),
3227836SJohn.Forte@Sun.COM 		    tohost);
3237836SJohn.Forte@Sun.COM 	}
3247836SJohn.Forte@Sun.COM 
3257836SJohn.Forte@Sun.COM 	if (self_check(fromname) && self_check(toname)) {
3267836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
3277836SJohn.Forte@Sun.COM 		    gettext("%s Both %s and %s are local"),
3287836SJohn.Forte@Sun.COM 		    program, fromhost, tohost);
3297836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Both %s and %s are local"),
3307836SJohn.Forte@Sun.COM 		    fromhost, tohost);
3317836SJohn.Forte@Sun.COM 	}
3327836SJohn.Forte@Sun.COM 
3337836SJohn.Forte@Sun.COM 	/*
3347836SJohn.Forte@Sun.COM 	 * Now build up the address for each host including port and transport
3357836SJohn.Forte@Sun.COM 	 */
3367836SJohn.Forte@Sun.COM 	if (getaddr) {
3377836SJohn.Forte@Sun.COM 		svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
3387836SJohn.Forte@Sun.COM 			&conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind);
3397836SJohn.Forte@Sun.COM 
3407836SJohn.Forte@Sun.COM 		if (svp == NULL) {
3417836SJohn.Forte@Sun.COM #ifdef DEBUG
3427836SJohn.Forte@Sun.COM 			(void) printf("get_addr failed for Ver 4 %s\n", toname);
3437836SJohn.Forte@Sun.COM #endif
3447836SJohn.Forte@Sun.COM 			spcs_log("sndr", NULL,
3457836SJohn.Forte@Sun.COM 			    gettext("%s get_addr failed for Ver 4"),
3467836SJohn.Forte@Sun.COM 			    program);
3477836SJohn.Forte@Sun.COM 			return (-1);
3487836SJohn.Forte@Sun.COM 		}
3497836SJohn.Forte@Sun.COM 		svaddr = *svp;
3507836SJohn.Forte@Sun.COM 	} else {
3517836SJohn.Forte@Sun.COM 		bzero(&svaddr, sizeof (svaddr));
3527836SJohn.Forte@Sun.COM 	}
3537836SJohn.Forte@Sun.COM 
3547836SJohn.Forte@Sun.COM 	parms.rdc_set->secondary.addr.len = svaddr.len;
3557836SJohn.Forte@Sun.COM 	parms.rdc_set->secondary.addr.maxlen = svaddr.maxlen;
3567836SJohn.Forte@Sun.COM 	parms.rdc_set->secondary.addr.buf = (void *)svaddr.buf;
3577836SJohn.Forte@Sun.COM 
3587836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
3597836SJohn.Forte@Sun.COM 	(void) fprintf(stderr,
3607836SJohn.Forte@Sun.COM 		"secondary buf %x len %d\n", svaddr.buf, svaddr.len);
3617836SJohn.Forte@Sun.COM 
3627836SJohn.Forte@Sun.COM 	for (i = 0; i < svaddr.len; i++)
3637836SJohn.Forte@Sun.COM 		(void) printf("%u ", svaddr.buf[i]);
3647836SJohn.Forte@Sun.COM 	(void) printf("\n");
3657836SJohn.Forte@Sun.COM #endif
3667836SJohn.Forte@Sun.COM 
3677836SJohn.Forte@Sun.COM 	if (getaddr) {
3687836SJohn.Forte@Sun.COM 		svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
3697836SJohn.Forte@Sun.COM 			&conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind);
3707836SJohn.Forte@Sun.COM 		if (svp == NULL) {
3717836SJohn.Forte@Sun.COM #ifdef DEBUG
3727836SJohn.Forte@Sun.COM 			(void) printf("get_addr failed for Ver 4 %s\n",
3737836SJohn.Forte@Sun.COM 			    fromname);
3747836SJohn.Forte@Sun.COM #endif
3757836SJohn.Forte@Sun.COM 			return (-1);
3767836SJohn.Forte@Sun.COM 		}
3777836SJohn.Forte@Sun.COM 		svaddr = *svp;
3787836SJohn.Forte@Sun.COM 	} else {
3797836SJohn.Forte@Sun.COM 		;
3807836SJohn.Forte@Sun.COM 		/*EMPTY*/
3817836SJohn.Forte@Sun.COM 	}
3827836SJohn.Forte@Sun.COM 	parms.rdc_set->primary.addr.len = svaddr.len;
3837836SJohn.Forte@Sun.COM 	parms.rdc_set->primary.addr.maxlen = svaddr.maxlen;
3847836SJohn.Forte@Sun.COM 	parms.rdc_set->primary.addr.buf =
3857836SJohn.Forte@Sun.COM 				(void *)svaddr.buf;
3867836SJohn.Forte@Sun.COM 
3877836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
3887836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, "primary buf %x len %d\n",
3897836SJohn.Forte@Sun.COM 	    svaddr.buf, svaddr.len);
3907836SJohn.Forte@Sun.COM 	for (i = 0; i < svaddr.len; i++)
3917836SJohn.Forte@Sun.COM 		(void) printf("%u ", svaddr.buf[i]);
3927836SJohn.Forte@Sun.COM 	(void) printf("\n");
3937836SJohn.Forte@Sun.COM #endif
3947836SJohn.Forte@Sun.COM 
3957836SJohn.Forte@Sun.COM 	if (getaddr) {
3967836SJohn.Forte@Sun.COM 		(void) convert_nconf_to_knconf(conf, &knconf);
3977836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
3987836SJohn.Forte@Sun.COM 		(void) printf("knconf %x %s %s %x\n", knconf.knc_semantics,
3997836SJohn.Forte@Sun.COM 		    knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev);
4007836SJohn.Forte@Sun.COM #endif
4017836SJohn.Forte@Sun.COM 		parms.rdc_set->netconfig = &knconf;
4027836SJohn.Forte@Sun.COM 	} else {
4037836SJohn.Forte@Sun.COM 		parms.rdc_set->netconfig = NULL;
4047836SJohn.Forte@Sun.COM 	}
4057836SJohn.Forte@Sun.COM 	if (!clustered && !self_check(fromname) && !self_check(toname)) {
4067836SJohn.Forte@Sun.COM 		spcs_log("sndr", NULL,
4077836SJohn.Forte@Sun.COM 		    gettext("%s Neither %s nor %s is local"),
4087836SJohn.Forte@Sun.COM 		    program, fromhost, tohost);
4097836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Neither %s nor %s is local"),
4107836SJohn.Forte@Sun.COM 		    fromhost, tohost);
4117836SJohn.Forte@Sun.COM 	}
412*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->primary.intf, fromhost,
413*11576SSurya.Prakki@Sun.COM 	    MAX_RDC_HOST_SIZE);
414*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH);
415*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH);
4167836SJohn.Forte@Sun.COM 
417*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->secondary.intf, tohost,
418*11576SSurya.Prakki@Sun.COM 	    MAX_RDC_HOST_SIZE);
419*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH);
420*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH);
4217836SJohn.Forte@Sun.COM 
422*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH);
423*11576SSurya.Prakki@Sun.COM 	(void) strncpy(parms.rdc_set->disk_queue, diskqueue, NSC_MAXPATH);
4247836SJohn.Forte@Sun.COM 
4257836SJohn.Forte@Sun.COM 	parms.rdc_set->maxqfbas = maxqfbas;
4267836SJohn.Forte@Sun.COM 	parms.rdc_set->maxqitems = maxqitems;
4277836SJohn.Forte@Sun.COM 	parms.rdc_set->autosync = autosync;
4287836SJohn.Forte@Sun.COM 	parms.rdc_set->asyncthr = asyncthr;
4297836SJohn.Forte@Sun.COM 	parms.rdc_set->setid = setid;
4307836SJohn.Forte@Sun.COM 
4317836SJohn.Forte@Sun.COM 	/* gethostid(3c) is defined to return a 32bit value */
4327836SJohn.Forte@Sun.COM 	parms.rdc_set->syshostid = (int32_t)gethostid();
4337836SJohn.Forte@Sun.COM 
4347836SJohn.Forte@Sun.COM 	parms.command = 0;
4357836SJohn.Forte@Sun.COM 	parms.options = 0;
4367836SJohn.Forte@Sun.COM 	parms.command = flag;
4377836SJohn.Forte@Sun.COM 
4387836SJohn.Forte@Sun.COM 	if (flag == RDC_CMD_RESUME) {
4397836SJohn.Forte@Sun.COM 		if (doasync)
4407836SJohn.Forte@Sun.COM 			parms.options |= RDC_OPT_ASYNC;
4417836SJohn.Forte@Sun.COM 		else
4427836SJohn.Forte@Sun.COM 			parms.options |= RDC_OPT_SYNC;
4437836SJohn.Forte@Sun.COM 	}
4447836SJohn.Forte@Sun.COM 	if (clustered) {
4457836SJohn.Forte@Sun.COM 		if (!ctag)
4467836SJohn.Forte@Sun.COM 			goto noconfig;
4477836SJohn.Forte@Sun.COM 		if (strcmp(ctag, "-") == 0)
4487836SJohn.Forte@Sun.COM 			goto noconfig;
4497836SJohn.Forte@Sun.COM 
4507836SJohn.Forte@Sun.COM #ifdef DEBUG
4517836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "logical hostname: %s\n", lhost);
4527836SJohn.Forte@Sun.COM #endif
4537836SJohn.Forte@Sun.COM 
4547836SJohn.Forte@Sun.COM 		if (strcmp(lhost, fromname) == 0) {
4557836SJohn.Forte@Sun.COM 			parms.options |= RDC_OPT_PRIMARY;
456*11576SSurya.Prakki@Sun.COM 			(void) strncpy(parms.rdc_set->direct_file, directfile,
457*11576SSurya.Prakki@Sun.COM 			    NSC_MAXPATH);
4587836SJohn.Forte@Sun.COM 
4597836SJohn.Forte@Sun.COM 		} else {
4607836SJohn.Forte@Sun.COM 			parms.options |= RDC_OPT_SECONDARY;
4617836SJohn.Forte@Sun.COM 			parms.rdc_set->direct_file[0] = 0; /* no fcal direct */
4627836SJohn.Forte@Sun.COM 		}
4637836SJohn.Forte@Sun.COM 	} else {
4647836SJohn.Forte@Sun.COM noconfig:
4657836SJohn.Forte@Sun.COM 		/*
4667836SJohn.Forte@Sun.COM 		 * If not clustered, don't resume sndr sets with lhost
4677836SJohn.Forte@Sun.COM 		 */
4687836SJohn.Forte@Sun.COM 		if ((flag == RDC_CMD_RESUME) && lhost && strlen(lhost))
4697836SJohn.Forte@Sun.COM 			return (0);
4707836SJohn.Forte@Sun.COM 
4717836SJohn.Forte@Sun.COM 		if (self_check(fromname)) {
4727836SJohn.Forte@Sun.COM 			parms.options |= RDC_OPT_PRIMARY;
473*11576SSurya.Prakki@Sun.COM 			(void) strncpy(parms.rdc_set->direct_file, directfile,
474*11576SSurya.Prakki@Sun.COM 			    NSC_MAXPATH);
4757836SJohn.Forte@Sun.COM 		} else {
4767836SJohn.Forte@Sun.COM 			parms.options |= RDC_OPT_SECONDARY;
4777836SJohn.Forte@Sun.COM 			parms.rdc_set->direct_file[0] = 0; /* no fcal direct */
4787836SJohn.Forte@Sun.COM 		}
4797836SJohn.Forte@Sun.COM 	}
4807836SJohn.Forte@Sun.COM 
4817836SJohn.Forte@Sun.COM 	ustatus = spcs_s_ucreate();
4827836SJohn.Forte@Sun.COM 
4837836SJohn.Forte@Sun.COM 	errno = 0;
4847836SJohn.Forte@Sun.COM 	ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
4857836SJohn.Forte@Sun.COM 	if (ret != SPCS_S_OK) {
4867836SJohn.Forte@Sun.COM 
4877836SJohn.Forte@Sun.COM 		/* Surpress error messages for suspend on cluster elements */
4887836SJohn.Forte@Sun.COM 		if ((flag == RDC_CMD_SUSPEND) && (errno == RDC_EALREADY) &&
4897836SJohn.Forte@Sun.COM 			!clustered && lhost && strlen(lhost)) {
4907836SJohn.Forte@Sun.COM 			spcs_s_ufree(&ustatus);
4917836SJohn.Forte@Sun.COM 			return (0);
4927836SJohn.Forte@Sun.COM 		}
4937836SJohn.Forte@Sun.COM 
4947836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
4957836SJohn.Forte@Sun.COM 			gettext("Remote Mirror: %s %s %s %s %s %s\n"),
4967836SJohn.Forte@Sun.COM 			fromhost, fromfile,
4977836SJohn.Forte@Sun.COM 			frombitmap, tohost, tofile, tobitmap);
4987836SJohn.Forte@Sun.COM 
4997836SJohn.Forte@Sun.COM 		if (errno == RDC_EEINVAL) {
5007836SJohn.Forte@Sun.COM 			spcs_log("sndr", NULL,
5017836SJohn.Forte@Sun.COM 			    gettext("%s %s %s %s %s %s %s %s\n%s"),
5027836SJohn.Forte@Sun.COM 			    program, rdc_decode_flag(flag, parms.options),
5037836SJohn.Forte@Sun.COM 			    fromhost, fromfile, frombitmap,
5047836SJohn.Forte@Sun.COM 			    tohost, tofile, tobitmap,
5057836SJohn.Forte@Sun.COM 			    gettext("invalid command option"));
5067836SJohn.Forte@Sun.COM 			rdc_err(&ustatus,
5077836SJohn.Forte@Sun.COM 			    gettext("Remote Mirror: invalid command option "
5087836SJohn.Forte@Sun.COM 				    "'%s'"), rdc_decode_flag(flag,
5097836SJohn.Forte@Sun.COM 				    parms.options));
5107836SJohn.Forte@Sun.COM 		} else {
5117836SJohn.Forte@Sun.COM 			spcs_log("sndr", &ustatus,
5127836SJohn.Forte@Sun.COM 			    gettext("%s %s %s %s %s %s %s %s"),
5137836SJohn.Forte@Sun.COM 			    program, rdc_decode_flag(flag, parms.options),
5147836SJohn.Forte@Sun.COM 			    fromhost, fromfile, frombitmap,
5157836SJohn.Forte@Sun.COM 			    tohost, tofile, tobitmap);
5167836SJohn.Forte@Sun.COM 			rdc_err(&ustatus, 0);
5177836SJohn.Forte@Sun.COM 		}
5187836SJohn.Forte@Sun.COM 	}
5197836SJohn.Forte@Sun.COM 
5207836SJohn.Forte@Sun.COM 	spcs_log("sndr", NULL,
5217836SJohn.Forte@Sun.COM 	    gettext("%s %s %s %s %s %s %s %s\nSuccessful"),
5227836SJohn.Forte@Sun.COM 	    program, rdc_decode_flag(flag, parms.options),
5237836SJohn.Forte@Sun.COM 	    fromhost, fromfile, frombitmap, tohost, tofile, tobitmap);
5247836SJohn.Forte@Sun.COM 
5257836SJohn.Forte@Sun.COM 	spcs_s_ufree(&ustatus);
5267836SJohn.Forte@Sun.COM 	return (0);
5277836SJohn.Forte@Sun.COM }
5287836SJohn.Forte@Sun.COM /*
5297836SJohn.Forte@Sun.COM  * assign setid's to any existing
5307836SJohn.Forte@Sun.COM  * sets without setids, making sure of course NOT to re-use a setid
5317836SJohn.Forte@Sun.COM  */
5327836SJohn.Forte@Sun.COM int
update_setids(CFGFILE * cfg,int * no_id,int highest)5337836SJohn.Forte@Sun.COM update_setids(CFGFILE *cfg, int *no_id, int highest)
5347836SJohn.Forte@Sun.COM {
5357836SJohn.Forte@Sun.COM 	int setid;
5367836SJohn.Forte@Sun.COM 	char buf[CFG_MAX_BUF];
5377836SJohn.Forte@Sun.COM 	char key[CFG_MAX_KEY];
5387836SJohn.Forte@Sun.COM 	char *ctag;
5397836SJohn.Forte@Sun.COM 
5407836SJohn.Forte@Sun.COM 	/* If in a Sun Cluster, SetIDs need to have a ctag */
5417836SJohn.Forte@Sun.COM 	if ((ctag = cfg_get_resource(cfg)) != NULL) {
5427836SJohn.Forte@Sun.COM 		ctag = strdup(ctag);
5437836SJohn.Forte@Sun.COM 		cfg_resource(cfg, "setid-ctag");
5447836SJohn.Forte@Sun.COM 	}
5457836SJohn.Forte@Sun.COM 
5467836SJohn.Forte@Sun.COM 	/*
5477836SJohn.Forte@Sun.COM 	 * Paranoia. IF there are any sets with setids, we don't
5487836SJohn.Forte@Sun.COM 	 * want to re-use their number.
5497836SJohn.Forte@Sun.COM 	 */
5507836SJohn.Forte@Sun.COM 	if (highest > get_new_cfg_setid(cfg)) {
5517836SJohn.Forte@Sun.COM 		bzero(&buf, sizeof (buf));
5527836SJohn.Forte@Sun.COM 		(void) sprintf(buf, "%d", highest);
5537836SJohn.Forte@Sun.COM 		if (cfg_put_cstring(cfg, "setid.set1.value", buf,
5547836SJohn.Forte@Sun.COM 		    sizeof (buf)) < 0)
5557836SJohn.Forte@Sun.COM 			rdc_warn(NULL, gettext("sndrboot: Unable to store "
5567836SJohn.Forte@Sun.COM 			    "new setid"));
5577836SJohn.Forte@Sun.COM 	}
5587836SJohn.Forte@Sun.COM 
5597836SJohn.Forte@Sun.COM 	for (setid = 0; no_id[setid]; setid++) {
5607836SJohn.Forte@Sun.COM 		bzero(&buf, sizeof (buf));
5617836SJohn.Forte@Sun.COM 		bzero(&key, sizeof (key));
5627836SJohn.Forte@Sun.COM 		(void) sprintf(buf, "%d", get_new_cfg_setid(cfg));
5637836SJohn.Forte@Sun.COM 		(void) sprintf(key, "sndr.set%d.options", no_id[setid]);
5647836SJohn.Forte@Sun.COM 		if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid", buf) < 0)
5657836SJohn.Forte@Sun.COM 			rdc_warn(NULL, gettext("sndrboot: Unable to store "
5667836SJohn.Forte@Sun.COM 			    "unique setid"));
5677836SJohn.Forte@Sun.COM 
5687836SJohn.Forte@Sun.COM 		pair_list[no_id[setid] - 1].setid = atoi(buf);
5697836SJohn.Forte@Sun.COM 	}
5707836SJohn.Forte@Sun.COM 
5717836SJohn.Forte@Sun.COM 	/* Restore old ctag if in a Sun Cluster */
5727836SJohn.Forte@Sun.COM 	if (ctag) {
5737836SJohn.Forte@Sun.COM 		cfg_resource(cfg, ctag);
5747836SJohn.Forte@Sun.COM 		free(ctag);
5757836SJohn.Forte@Sun.COM 	}
5767836SJohn.Forte@Sun.COM 
5777836SJohn.Forte@Sun.COM 	if (cfg_commit(cfg) < 0)
5787836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("sndrboot: Failed to commit setids"));
5797836SJohn.Forte@Sun.COM 
5807836SJohn.Forte@Sun.COM 	return (setid);
5817836SJohn.Forte@Sun.COM }
5827836SJohn.Forte@Sun.COM 
5837836SJohn.Forte@Sun.COM /*
5847836SJohn.Forte@Sun.COM  * this is called when the option lghn is no available in libdscfg
5857836SJohn.Forte@Sun.COM  * that should only happen on an upgrade.
5867836SJohn.Forte@Sun.COM  * cfg write lock must be held across this function
5877836SJohn.Forte@Sun.COM  */
5887836SJohn.Forte@Sun.COM char *
get_lghn(CFGFILE * cfg,char * ctag,int setnum,int flag)5897836SJohn.Forte@Sun.COM get_lghn(CFGFILE *cfg, char *ctag, int setnum, int flag)
5907836SJohn.Forte@Sun.COM {
5917836SJohn.Forte@Sun.COM 	FILE *pipe;
5927836SJohn.Forte@Sun.COM 	char rsgrp[SCCONF_MAXSTRINGLEN];
5937836SJohn.Forte@Sun.COM 	char cmd[SCCONF_MAXSTRINGLEN];
5947836SJohn.Forte@Sun.COM 	static char lhostname[MAX_RDC_HOST_SIZE];
5957836SJohn.Forte@Sun.COM 	char key[CFG_MAX_KEY];
5967836SJohn.Forte@Sun.COM 	int rc;
5977836SJohn.Forte@Sun.COM 
5987836SJohn.Forte@Sun.COM 	if (ctag == NULL)
5997836SJohn.Forte@Sun.COM 		goto fail;
6007836SJohn.Forte@Sun.COM 
6017836SJohn.Forte@Sun.COM 	bzero(&lhostname, sizeof (lhostname));
6027836SJohn.Forte@Sun.COM 
6037836SJohn.Forte@Sun.COM 	(void) sprintf(rsgrp, "%s-stor-rg", ctag);
6047836SJohn.Forte@Sun.COM /* BEGIN CSTYLED */
6057836SJohn.Forte@Sun.COM 	rc = snprintf(cmd, SCCONF_MAXSTRINGLEN,
6067836SJohn.Forte@Sun.COM 	    "/usr/cluster/bin/scrgadm -pvv | fgrep HostnameList \
6077836SJohn.Forte@Sun.COM | fgrep %s | fgrep value | awk -F: '{ print $4 }'", rsgrp);
6087836SJohn.Forte@Sun.COM /* END CSTYLED */
6097836SJohn.Forte@Sun.COM 
6107836SJohn.Forte@Sun.COM 	if (rc < 0) {
6117836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Error getting scrgadm output"));
6127836SJohn.Forte@Sun.COM 	}
6137836SJohn.Forte@Sun.COM 
6147836SJohn.Forte@Sun.COM 	pipe = popen(cmd, "r");
6157836SJohn.Forte@Sun.COM 
6167836SJohn.Forte@Sun.COM 	if (pipe == NULL) {
6177836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Error opening pipe"));
6187836SJohn.Forte@Sun.COM 	}
6197836SJohn.Forte@Sun.COM 	rc = fscanf(pipe, "%s", lhostname);
6207836SJohn.Forte@Sun.COM 	(void) pclose(pipe);
6217836SJohn.Forte@Sun.COM 
6227836SJohn.Forte@Sun.COM 	if (rc != 1) {
6237836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Unable to get logical host"));
6247836SJohn.Forte@Sun.COM 	}
6257836SJohn.Forte@Sun.COM 
6267836SJohn.Forte@Sun.COM 	/* not really failing, but suspend does not have the config lock */
6277836SJohn.Forte@Sun.COM 	if (flag == RDC_CMD_SUSPEND)
6287836SJohn.Forte@Sun.COM 		goto fail;
6297836SJohn.Forte@Sun.COM 
6307836SJohn.Forte@Sun.COM 	bzero(&key, sizeof (key));
6317836SJohn.Forte@Sun.COM 	(void) snprintf(key, sizeof (key), "sndr.set%d.options", setnum);
6327836SJohn.Forte@Sun.COM 	if (cfg_put_options(cfg, CFG_SEC_CONF, key, "lghn", lhostname) < 0)
6337836SJohn.Forte@Sun.COM 		rdc_warn(NULL, gettext("sndrboot: Unable to store logical "
6347836SJohn.Forte@Sun.COM 		    "host name in configuration database"));
6357836SJohn.Forte@Sun.COM 
6367836SJohn.Forte@Sun.COM 	if (cfg_commit(cfg) < 0)
6377836SJohn.Forte@Sun.COM 		rdc_err(NULL,
6387836SJohn.Forte@Sun.COM 		    gettext("sndrboot: Failed to commit logical host name"));
6397836SJohn.Forte@Sun.COM 
6407836SJohn.Forte@Sun.COM fail:
6417836SJohn.Forte@Sun.COM 	return (lhostname);
6427836SJohn.Forte@Sun.COM 
6437836SJohn.Forte@Sun.COM }
6447836SJohn.Forte@Sun.COM 
6457836SJohn.Forte@Sun.COM /*
6467836SJohn.Forte@Sun.COM  * read_libcfg()
6477836SJohn.Forte@Sun.COM  *
6487836SJohn.Forte@Sun.COM  * DESCRIPTION: Read the relevant config info via libcfg
6497836SJohn.Forte@Sun.COM  *
6507836SJohn.Forte@Sun.COM  * Outputs:
6517836SJohn.Forte@Sun.COM  *	int i			Number of pairs of devices
6527836SJohn.Forte@Sun.COM  *
6537836SJohn.Forte@Sun.COM  * Side Effects: The 0 to i-1 entries in the pair_list are filled.
6547836SJohn.Forte@Sun.COM  *
6557836SJohn.Forte@Sun.COM  */
6567836SJohn.Forte@Sun.COM static int
read_libcfg(int flag)6577836SJohn.Forte@Sun.COM read_libcfg(int flag)
6587836SJohn.Forte@Sun.COM {
6597836SJohn.Forte@Sun.COM 	char fromhost[MAX_RDC_HOST_SIZE];
6607836SJohn.Forte@Sun.COM 	char fromfile[NSC_MAXPATH];
6617836SJohn.Forte@Sun.COM 	char frombitmap[NSC_MAXPATH];
6627836SJohn.Forte@Sun.COM 	char tohost[MAX_RDC_HOST_SIZE];
6637836SJohn.Forte@Sun.COM 	char tofile[NSC_MAXPATH];
6647836SJohn.Forte@Sun.COM 	char tobitmap[NSC_MAXPATH];
6657836SJohn.Forte@Sun.COM 	char directfile[NSC_MAXPATH];
6667836SJohn.Forte@Sun.COM 	char diskqueue[NSC_MAXPATH];
6677836SJohn.Forte@Sun.COM 	char group[NSC_MAXPATH];
6687836SJohn.Forte@Sun.COM 	char lhost[MAX_RDC_HOST_SIZE];
6697836SJohn.Forte@Sun.COM 	char sync[16];
6707836SJohn.Forte@Sun.COM 	char setid[64];
6717836SJohn.Forte@Sun.COM 	int doasync;
6727836SJohn.Forte@Sun.COM 	CFGFILE *cfg;
6737836SJohn.Forte@Sun.COM 	int i, j = 0;
6747836SJohn.Forte@Sun.COM 	int rc;
6757836SJohn.Forte@Sun.COM 	char buf[CFG_MAX_BUF];
6767836SJohn.Forte@Sun.COM 	char key[CFG_MAX_KEY];
6777836SJohn.Forte@Sun.COM 	char dummy[NSC_MAXPATH];
6787836SJohn.Forte@Sun.COM 	int setnumber;
6797836SJohn.Forte@Sun.COM 	int numsets;
6807836SJohn.Forte@Sun.COM 	int highest = 0;
6817836SJohn.Forte@Sun.COM 	char lghn[5];
6827836SJohn.Forte@Sun.COM 	int *no_id;
6837836SJohn.Forte@Sun.COM 
6847836SJohn.Forte@Sun.COM 
6857836SJohn.Forte@Sun.COM 	if ((cfg = cfg_open("")) == NULL)
6867836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Error opening config"));
6877836SJohn.Forte@Sun.COM 
6887836SJohn.Forte@Sun.COM 	/*
6897836SJohn.Forte@Sun.COM 	 * If RDC_CMD_FIXSETIDS, we were called during post-patch install
6907836SJohn.Forte@Sun.COM 	 * Acquire a write-lock on the cfg_lock(), so the code can attempt
6917836SJohn.Forte@Sun.COM 	 * to fix setIDs
6927836SJohn.Forte@Sun.COM 	 */
6937836SJohn.Forte@Sun.COM 	if (flag == RDC_CMD_FIXSETIDS) {
6947836SJohn.Forte@Sun.COM 		if (!cfg_lock(cfg, CFG_WRLOCK))
6957836SJohn.Forte@Sun.COM 			rdc_err(NULL, gettext("Error write locking config"));
6967836SJohn.Forte@Sun.COM 		cfg_resource(cfg, NULL);
6977836SJohn.Forte@Sun.COM 	} else {
6987836SJohn.Forte@Sun.COM 		if (!cfg_lock(cfg, CFG_RDLOCK))
6997836SJohn.Forte@Sun.COM 			rdc_err(NULL, gettext("Error locking config"));
7007836SJohn.Forte@Sun.COM 		cfg_resource(cfg, ctag);
7017836SJohn.Forte@Sun.COM 	}
7027836SJohn.Forte@Sun.COM 
7037836SJohn.Forte@Sun.COM 	if ((numsets = cfg_get_num_entries(cfg, "sndr")) < 0)
7047836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("Unable to get set info from config"));
7057836SJohn.Forte@Sun.COM 
7067836SJohn.Forte@Sun.COM 	no_id = (int *)calloc(numsets + 1, sizeof (int));
7077836SJohn.Forte@Sun.COM 	if (!no_id)
7087836SJohn.Forte@Sun.COM 		rdc_err(NULL, gettext("No memory"));
7097836SJohn.Forte@Sun.COM 
7107836SJohn.Forte@Sun.COM 
7117836SJohn.Forte@Sun.COM 	(void) snprintf(lghn, sizeof (lghn), "lghn");
7127836SJohn.Forte@Sun.COM 
7137836SJohn.Forte@Sun.COM 	for (i = 0; i < rdc_maxsets; i++) {
7147836SJohn.Forte@Sun.COM 		setnumber = i + 1;
7157836SJohn.Forte@Sun.COM 
7167836SJohn.Forte@Sun.COM 		bzero(buf, CFG_MAX_BUF);
7177836SJohn.Forte@Sun.COM 		(void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
7187836SJohn.Forte@Sun.COM 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
7197836SJohn.Forte@Sun.COM 			break;
7207836SJohn.Forte@Sun.COM 
7217836SJohn.Forte@Sun.COM 		rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s",
7227836SJohn.Forte@Sun.COM 		    fromhost, fromfile, frombitmap, tohost, tofile, tobitmap,
7237836SJohn.Forte@Sun.COM 			directfile, sync, group, dummy, dummy, diskqueue);
7247836SJohn.Forte@Sun.COM 		if (rc != 12)
7257836SJohn.Forte@Sun.COM 			rdc_err(NULL, gettext("cfg input error (%d)"), rc);
7267836SJohn.Forte@Sun.COM 
7277836SJohn.Forte@Sun.COM 		if (strcmp(directfile, "ip") == 0)
728*11576SSurya.Prakki@Sun.COM 			(void) strcpy(directfile, "");
7297836SJohn.Forte@Sun.COM 
7307836SJohn.Forte@Sun.COM 		if (strcmp(group, "-") == 0)
731*11576SSurya.Prakki@Sun.COM 			(void) strcpy(group, "");
7327836SJohn.Forte@Sun.COM 
7337836SJohn.Forte@Sun.COM 		if (strcmp(diskqueue, "-") == 0)
734*11576SSurya.Prakki@Sun.COM 			(void) strcpy(diskqueue, "");
7357836SJohn.Forte@Sun.COM 
7367836SJohn.Forte@Sun.COM 		(void) snprintf(key, sizeof (key),
7377836SJohn.Forte@Sun.COM 			"sndr.set%d.options", setnumber);
7387836SJohn.Forte@Sun.COM 
7397836SJohn.Forte@Sun.COM 		if (cfg_get_single_option(cfg, CFG_SEC_CONF, key,
7407836SJohn.Forte@Sun.COM 			lghn, lhost, MAX_RDC_HOST_SIZE) < 0)
741*11576SSurya.Prakki@Sun.COM 			(void) strcpy(lhost,
7427836SJohn.Forte@Sun.COM 			    get_lghn(cfg, ctag, setnumber, flag));
7437836SJohn.Forte@Sun.COM 
7447836SJohn.Forte@Sun.COM 		if (strcmp(sync, "sync") == 0)
7457836SJohn.Forte@Sun.COM 			doasync = 0;
7467836SJohn.Forte@Sun.COM 		else if (strcmp(sync, "async") == 0)
7477836SJohn.Forte@Sun.COM 			doasync = 1;
7487836SJohn.Forte@Sun.COM 		else {
7497836SJohn.Forte@Sun.COM 			cfg_close(cfg);
7507836SJohn.Forte@Sun.COM 			rdc_err(NULL,
7517836SJohn.Forte@Sun.COM 			    gettext("Set %s:%s neither sync nor async"),
7527836SJohn.Forte@Sun.COM 			    tohost, tofile);
7537836SJohn.Forte@Sun.COM 		}
7547836SJohn.Forte@Sun.COM 
755*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].fhost, fromhost,
756*11576SSurya.Prakki@Sun.COM 		    MAX_RDC_HOST_SIZE);
757*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH);
758*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH);
759*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE);
760*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH);
761*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH);
762*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].directfile, directfile,
763*11576SSurya.Prakki@Sun.COM 		    NSC_MAXPATH);
764*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].diskqueue, diskqueue,
765*11576SSurya.Prakki@Sun.COM 		    NSC_MAXPATH);
766*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].group, group, NSC_MAXPATH);
767*11576SSurya.Prakki@Sun.COM 		(void) strncpy(pair_list[i].lhost, lhost, MAX_RDC_HOST_SIZE);
7687836SJohn.Forte@Sun.COM 		pair_list[i].doasync = doasync;
7697836SJohn.Forte@Sun.COM 
7707836SJohn.Forte@Sun.COM 		if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, "setid",
7717836SJohn.Forte@Sun.COM 		    setid, sizeof (setid)) < 0) {
7727836SJohn.Forte@Sun.COM 			no_id[j++] = setnumber;
7737836SJohn.Forte@Sun.COM 		}
7747836SJohn.Forte@Sun.COM 		pair_list[i].setid = atoi(setid);
7757836SJohn.Forte@Sun.COM 
7767836SJohn.Forte@Sun.COM 		if (pair_list[i].setid > highest)
7777836SJohn.Forte@Sun.COM 			highest = pair_list[i].setid;
7787836SJohn.Forte@Sun.COM 
7797836SJohn.Forte@Sun.COM 		if (gethost_netaddrs(fromhost, tohost,
7807836SJohn.Forte@Sun.COM 		    (char *)pair_list[i].fnetaddr,
7817836SJohn.Forte@Sun.COM 		    (char *)pair_list[i].tnetaddr) < 0) {
7827836SJohn.Forte@Sun.COM 			cfg_close(cfg);
7837836SJohn.Forte@Sun.COM 			spcs_log("sndr", NULL,
7847836SJohn.Forte@Sun.COM 			    gettext("%s unable to determine IP addresses "
7857836SJohn.Forte@Sun.COM 			    "for hosts %s %s"), program, fromhost, tohost);
7867836SJohn.Forte@Sun.COM 			rdc_err(NULL, gettext("unable to determine IP "
7877836SJohn.Forte@Sun.COM 			    "addresses for hosts %s, %s"), fromhost, tohost);
7887836SJohn.Forte@Sun.COM 		}
7897836SJohn.Forte@Sun.COM 	}
7907836SJohn.Forte@Sun.COM 	/*
7917836SJohn.Forte@Sun.COM 	 * fix any lost set ids if possible, also deal with upgrade
7927836SJohn.Forte@Sun.COM 	 */
7937836SJohn.Forte@Sun.COM 	if (j > 0 && flag == RDC_CMD_FIXSETIDS) {
7947836SJohn.Forte@Sun.COM 		(void) update_setids(cfg, no_id, highest);
7957836SJohn.Forte@Sun.COM 		i = j;	/* Set number of fixups */
7967836SJohn.Forte@Sun.COM 	}
7977836SJohn.Forte@Sun.COM 	free(no_id);
7987836SJohn.Forte@Sun.COM 	cfg_close(cfg);
7997836SJohn.Forte@Sun.COM 	return (i);
8007836SJohn.Forte@Sun.COM }
8017836SJohn.Forte@Sun.COM 
8027836SJohn.Forte@Sun.COM 
8037836SJohn.Forte@Sun.COM int
parseopts(argc,argv,flag)8047836SJohn.Forte@Sun.COM parseopts(argc, argv, flag)
8057836SJohn.Forte@Sun.COM int argc;
8067836SJohn.Forte@Sun.COM char **argv;
8077836SJohn.Forte@Sun.COM int *flag;
8087836SJohn.Forte@Sun.COM {
8097836SJohn.Forte@Sun.COM 	int  errflag = 0;
8107836SJohn.Forte@Sun.COM 	char c;
8117836SJohn.Forte@Sun.COM 	char inval = 0;
8127836SJohn.Forte@Sun.COM #ifdef DEBUG
8137836SJohn.Forte@Sun.COM 	while ((c = getopt(argc, argv, "C:Urs")) != -1) {
8147836SJohn.Forte@Sun.COM #else
8157836SJohn.Forte@Sun.COM 	while ((c = getopt(argc, argv, "C:rs")) != -1) {
8167836SJohn.Forte@Sun.COM #endif
8177836SJohn.Forte@Sun.COM 		switch (c) {
8187836SJohn.Forte@Sun.COM 		case 'C':
8197836SJohn.Forte@Sun.COM 			clustered = TRUE;
8207836SJohn.Forte@Sun.COM 			ctag = optarg;
8217836SJohn.Forte@Sun.COM 			break;
8227836SJohn.Forte@Sun.COM #ifdef DEBUG
8237836SJohn.Forte@Sun.COM 		case 'U':
8247836SJohn.Forte@Sun.COM 			proto_test = 1;
8257836SJohn.Forte@Sun.COM 			break;
8267836SJohn.Forte@Sun.COM #endif
8277836SJohn.Forte@Sun.COM 		case 'r':
8287836SJohn.Forte@Sun.COM 			if (*flag)
8297836SJohn.Forte@Sun.COM 				inval = 1;
8307836SJohn.Forte@Sun.COM 			*flag = RDC_CMD_RESUME;
8317836SJohn.Forte@Sun.COM 			break;
8327836SJohn.Forte@Sun.COM 		case 's':
8337836SJohn.Forte@Sun.COM 			if (*flag)
8347836SJohn.Forte@Sun.COM 				inval = 1;
8357836SJohn.Forte@Sun.COM 			*flag = RDC_CMD_SUSPEND;
8367836SJohn.Forte@Sun.COM 			break;
8377836SJohn.Forte@Sun.COM 		case '?':
8387836SJohn.Forte@Sun.COM 			errflag++;
8397836SJohn.Forte@Sun.COM 		}
8407836SJohn.Forte@Sun.COM 	}
8417836SJohn.Forte@Sun.COM 
8427836SJohn.Forte@Sun.COM 	/*
8437836SJohn.Forte@Sun.COM 	 * Special fix to address no SetIds in AVS 3.1 to 3.2 install + patch
8447836SJohn.Forte@Sun.COM 	 * Adjust set IDs, if someone invokes the following invalid command
8457836SJohn.Forte@Sun.COM 	 *
8467836SJohn.Forte@Sun.COM 	 *	/use/sbin/sndrboot -C post-patch-setids -r -s
8477836SJohn.Forte@Sun.COM 	 *
8487836SJohn.Forte@Sun.COM 	 * Command will be called in post-install of the patch containing fix
8497836SJohn.Forte@Sun.COM 	 *
8507836SJohn.Forte@Sun.COM 	 */
8517836SJohn.Forte@Sun.COM 	if (clustered && (strcmp(ctag, "post-patch-setids") == 0) &&
8527836SJohn.Forte@Sun.COM 	    *flag && inval) {
8537836SJohn.Forte@Sun.COM 		*flag = RDC_CMD_FIXSETIDS;
8547836SJohn.Forte@Sun.COM 		return (0);
8557836SJohn.Forte@Sun.COM 	}
8567836SJohn.Forte@Sun.COM 
8577836SJohn.Forte@Sun.COM 	if (inval) {
8587836SJohn.Forte@Sun.COM 		rdc_warn(NULL, gettext("Invalid argument combination"));
8597836SJohn.Forte@Sun.COM 		errflag = 1;
8607836SJohn.Forte@Sun.COM 	}
8617836SJohn.Forte@Sun.COM 
8627836SJohn.Forte@Sun.COM 	if (!*flag || errflag) {
8637836SJohn.Forte@Sun.COM 		usage();
8647836SJohn.Forte@Sun.COM 		return (-1);
8657836SJohn.Forte@Sun.COM 	}
8667836SJohn.Forte@Sun.COM 
8677836SJohn.Forte@Sun.COM 	return (0);
8687836SJohn.Forte@Sun.COM }
8697836SJohn.Forte@Sun.COM 
8707836SJohn.Forte@Sun.COM static void
usage()8717836SJohn.Forte@Sun.COM usage()
8727836SJohn.Forte@Sun.COM {
8737836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("usage:\n"));
8747836SJohn.Forte@Sun.COM 	(void) fprintf(stderr,
8757836SJohn.Forte@Sun.COM 		gettext("\t%s -r [-C tag]\t\t"
8767836SJohn.Forte@Sun.COM 			"resume\n"), program);
8777836SJohn.Forte@Sun.COM 
8787836SJohn.Forte@Sun.COM 	(void) fprintf(stderr,
8797836SJohn.Forte@Sun.COM 		gettext("\t%s -s [-C tag]\t\t"
8807836SJohn.Forte@Sun.COM 			"suspend\n"), program);
8817836SJohn.Forte@Sun.COM }
882