xref: /titanic_54/usr/src/cmd/avs/rdc/sndrboot.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte 
27*fcf3ce44SJohn Forte #include <sys/types.h>
28*fcf3ce44SJohn Forte #include <sys/wait.h>
29*fcf3ce44SJohn Forte #include <stdio.h>
30*fcf3ce44SJohn Forte #include <sys/mnttab.h>
31*fcf3ce44SJohn Forte #include <errno.h>
32*fcf3ce44SJohn Forte #include <limits.h>
33*fcf3ce44SJohn Forte #include <fcntl.h>
34*fcf3ce44SJohn Forte #include <strings.h>
35*fcf3ce44SJohn Forte #include <stdlib.h>
36*fcf3ce44SJohn Forte #include <unistd.h>
37*fcf3ce44SJohn Forte 
38*fcf3ce44SJohn Forte #include <locale.h>
39*fcf3ce44SJohn Forte #include <langinfo.h>
40*fcf3ce44SJohn Forte #include <libintl.h>
41*fcf3ce44SJohn Forte #include <stdarg.h>
42*fcf3ce44SJohn Forte #include <netdb.h>
43*fcf3ce44SJohn Forte #include <ctype.h>
44*fcf3ce44SJohn Forte #include <sys/utsname.h>
45*fcf3ce44SJohn Forte 
46*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_io.h>
47*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h>
48*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_prot.h>
49*fcf3ce44SJohn Forte 
50*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
51*fcf3ce44SJohn Forte #include <sys/nsctl/cfg_cluster.h>
52*fcf3ce44SJohn Forte 
53*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
54*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
55*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
56*fcf3ce44SJohn Forte 
57*fcf3ce44SJohn Forte #include "rdcadm.h"
58*fcf3ce44SJohn Forte 
59*fcf3ce44SJohn Forte /*
60*fcf3ce44SJohn Forte  * Special re-use of sndrboot to fix SNDR set IDs during post-patch processing
61*fcf3ce44SJohn Forte  */
62*fcf3ce44SJohn Forte #define	RDC_CMD_FIXSETIDS	0xFEEDFACE
63*fcf3ce44SJohn Forte 
64*fcf3ce44SJohn Forte /*
65*fcf3ce44SJohn Forte  * config file user level Dual copy pair structure
66*fcf3ce44SJohn Forte  */
67*fcf3ce44SJohn Forte typedef struct _sd_dual_pair {
68*fcf3ce44SJohn Forte 	char fhost[MAX_RDC_HOST_SIZE];	/* Hostname for primary device */
69*fcf3ce44SJohn Forte 	char fnetaddr[RDC_MAXADDR];	/* Host netaddr for primary device */
70*fcf3ce44SJohn Forte 	char ffile[NSC_MAXPATH];	/* Primary device */
71*fcf3ce44SJohn Forte 	char fbitmap[NSC_MAXPATH];	/* Primary bitmap device */
72*fcf3ce44SJohn Forte 	char thost[MAX_RDC_HOST_SIZE];	/* Hostname for secondary device */
73*fcf3ce44SJohn Forte 	char tnetaddr[RDC_MAXADDR];	/* Host netaddr for secondary device */
74*fcf3ce44SJohn Forte 	char tfile[NSC_MAXPATH];	/* Secondary device */
75*fcf3ce44SJohn Forte 	char tbitmap[NSC_MAXPATH];	/* Secondary bitmap device */
76*fcf3ce44SJohn Forte 	char directfile[NSC_MAXPATH];	/* Local FCAL direct IO volume */
77*fcf3ce44SJohn Forte 	char diskqueue[NSC_MAXPATH];	/* Disk Queue volume */
78*fcf3ce44SJohn Forte 	char group[NSC_MAXPATH];	/* Group name */
79*fcf3ce44SJohn Forte 	char lhost[MAX_RDC_HOST_SIZE];  /* Logical hostname for cluster */
80*fcf3ce44SJohn Forte 	int  doasync;			/* Device is in sync/async mode */
81*fcf3ce44SJohn Forte 	int  setid;			/* unique setid of this set */
82*fcf3ce44SJohn Forte } _sd_dual_pair_t;
83*fcf3ce44SJohn Forte 
84*fcf3ce44SJohn Forte #include <sys/socket.h>
85*fcf3ce44SJohn Forte #include <netinet/in.h>
86*fcf3ce44SJohn Forte #include <arpa/inet.h>
87*fcf3ce44SJohn Forte #include <netinet/tcp.h>
88*fcf3ce44SJohn Forte #include <rpc/rpc_com.h>
89*fcf3ce44SJohn Forte #include <rpc/rpc.h>
90*fcf3ce44SJohn Forte 
91*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h>
92*fcf3ce44SJohn Forte 
93*fcf3ce44SJohn Forte char *ctag = NULL;
94*fcf3ce44SJohn Forte 
95*fcf3ce44SJohn Forte int parseopts(int, char **, int *);
96*fcf3ce44SJohn Forte static int rdc_operation(char *, char *, char *, char *, char *, char *, int,
97*fcf3ce44SJohn Forte     char *, char *, char *, int, char *, int setid);
98*fcf3ce44SJohn Forte static int read_libcfg(int);
99*fcf3ce44SJohn Forte static void usage(void);
100*fcf3ce44SJohn Forte 
101*fcf3ce44SJohn Forte extern char *basename(char *);
102*fcf3ce44SJohn Forte 
103*fcf3ce44SJohn Forte int rdc_maxsets;
104*fcf3ce44SJohn Forte static _sd_dual_pair_t *pair_list;
105*fcf3ce44SJohn Forte char *program;
106*fcf3ce44SJohn Forte 
107*fcf3ce44SJohn Forte struct netbuf svaddr;
108*fcf3ce44SJohn Forte struct netbuf *svp;
109*fcf3ce44SJohn Forte struct netconfig nconf;
110*fcf3ce44SJohn Forte struct netconfig *conf;
111*fcf3ce44SJohn Forte struct knetconfig knconf;
112*fcf3ce44SJohn Forte static int clustered = 0;
113*fcf3ce44SJohn Forte static int proto_test = 0;
114*fcf3ce44SJohn Forte 
115*fcf3ce44SJohn Forte #ifdef lint
116*fcf3ce44SJohn Forte int
117*fcf3ce44SJohn Forte sndrboot_lintmain(int argc, char *argv[])
118*fcf3ce44SJohn Forte #else
119*fcf3ce44SJohn Forte int
120*fcf3ce44SJohn Forte main(int argc, char *argv[])
121*fcf3ce44SJohn Forte #endif
122*fcf3ce44SJohn Forte {
123*fcf3ce44SJohn Forte 	char fromhost[MAX_RDC_HOST_SIZE];
124*fcf3ce44SJohn Forte 	char tohost[MAX_RDC_HOST_SIZE];
125*fcf3ce44SJohn Forte 	char fromfile[NSC_MAXPATH];
126*fcf3ce44SJohn Forte 	char tofile[NSC_MAXPATH];
127*fcf3ce44SJohn Forte 	char frombitmap[NSC_MAXPATH];
128*fcf3ce44SJohn Forte 	char tobitmap[NSC_MAXPATH];
129*fcf3ce44SJohn Forte 	char directfile[NSC_MAXPATH];
130*fcf3ce44SJohn Forte 	char diskqueue[NSC_MAXPATH];
131*fcf3ce44SJohn Forte 	char group[NSC_MAXPATH];
132*fcf3ce44SJohn Forte 	char lhost[MAX_RDC_HOST_SIZE];
133*fcf3ce44SJohn Forte 	int pairs;
134*fcf3ce44SJohn Forte 	int pid;
135*fcf3ce44SJohn Forte 	int flag = 0;
136*fcf3ce44SJohn Forte 	int doasync;
137*fcf3ce44SJohn Forte 	int rc;
138*fcf3ce44SJohn Forte 	char *required;
139*fcf3ce44SJohn Forte 	int setid;
140*fcf3ce44SJohn Forte 
141*fcf3ce44SJohn Forte 	(void) setlocale(LC_ALL, "");
142*fcf3ce44SJohn Forte 	(void) textdomain("rdc");
143*fcf3ce44SJohn Forte 
144*fcf3ce44SJohn Forte 	program = basename(argv[0]);
145*fcf3ce44SJohn Forte 
146*fcf3ce44SJohn Forte 	rc = rdc_check_release(&required);
147*fcf3ce44SJohn Forte 	if (rc < 0) {
148*fcf3ce44SJohn Forte 		rdc_err(NULL,
149*fcf3ce44SJohn Forte 		    gettext("unable to determine the current "
150*fcf3ce44SJohn Forte 		    "Solaris release: %s\n"), strerror(errno));
151*fcf3ce44SJohn Forte 	} else if (rc == FALSE) {
152*fcf3ce44SJohn Forte 		rdc_err(NULL,
153*fcf3ce44SJohn Forte 		    gettext("incorrect Solaris release (requires %s)\n"),
154*fcf3ce44SJohn Forte 		    required);
155*fcf3ce44SJohn Forte 	}
156*fcf3ce44SJohn Forte 
157*fcf3ce44SJohn Forte 	rdc_maxsets = rdc_get_maxsets();
158*fcf3ce44SJohn Forte 	if (rdc_maxsets == -1) {
159*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
160*fcf3ce44SJohn Forte 		    gettext("%s unable to get maxsets value from kernel"),
161*fcf3ce44SJohn Forte 		    program);
162*fcf3ce44SJohn Forte 
163*fcf3ce44SJohn Forte 		rdc_err(NULL,
164*fcf3ce44SJohn Forte 		    gettext("unable to get maxsets value from kernel"));
165*fcf3ce44SJohn Forte 	}
166*fcf3ce44SJohn Forte 
167*fcf3ce44SJohn Forte 	pair_list = calloc(rdc_maxsets, sizeof (*pair_list));
168*fcf3ce44SJohn Forte 	if (pair_list == NULL) {
169*fcf3ce44SJohn Forte 		rdc_err(NULL,
170*fcf3ce44SJohn Forte 		    gettext(
171*fcf3ce44SJohn Forte 			"unable to allocate pair_list"
172*fcf3ce44SJohn Forte 			" array for %d sets"),
173*fcf3ce44SJohn Forte 			rdc_maxsets);
174*fcf3ce44SJohn Forte 	}
175*fcf3ce44SJohn Forte 
176*fcf3ce44SJohn Forte 	if (parseopts(argc, argv, &flag))
177*fcf3ce44SJohn Forte 		return (1);
178*fcf3ce44SJohn Forte 	pairs = read_libcfg(flag);
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte 	if (flag == RDC_CMD_FIXSETIDS) {
181*fcf3ce44SJohn Forte 		if (pairs) {
182*fcf3ce44SJohn Forte 			spcs_log("sndr", NULL, gettext("Fixed %d Remote Mirror"
183*fcf3ce44SJohn Forte 				    " set IDs"), pairs);
184*fcf3ce44SJohn Forte #ifdef DEBUG
185*fcf3ce44SJohn Forte 			rdc_warn(NULL, gettext("Fixed %d Remote Mirror set "
186*fcf3ce44SJohn Forte 				    "IDs"), pairs);
187*fcf3ce44SJohn Forte #endif
188*fcf3ce44SJohn Forte 		}
189*fcf3ce44SJohn Forte 		return (0);
190*fcf3ce44SJohn Forte 	}
191*fcf3ce44SJohn Forte 
192*fcf3ce44SJohn Forte 	if (pairs == 0) {
193*fcf3ce44SJohn Forte #ifdef DEBUG
194*fcf3ce44SJohn Forte 		rdc_err(NULL,
195*fcf3ce44SJohn Forte 		    gettext("Config contains no dual copy sets"));
196*fcf3ce44SJohn Forte #else
197*fcf3ce44SJohn Forte 		return (0);
198*fcf3ce44SJohn Forte #endif
199*fcf3ce44SJohn Forte 	}
200*fcf3ce44SJohn Forte 
201*fcf3ce44SJohn Forte 	while (pairs--) {
202*fcf3ce44SJohn Forte 		pid = fork();
203*fcf3ce44SJohn Forte 		if (pid == -1) {		/* error forking */
204*fcf3ce44SJohn Forte 			perror("fork");
205*fcf3ce44SJohn Forte 			continue;
206*fcf3ce44SJohn Forte 		}
207*fcf3ce44SJohn Forte 
208*fcf3ce44SJohn Forte 		if (pid > 0)		/* this is parent process */
209*fcf3ce44SJohn Forte 			continue;
210*fcf3ce44SJohn Forte 
211*fcf3ce44SJohn Forte /*
212*fcf3ce44SJohn Forte  * At this point, this is the child process.  Do the operation
213*fcf3ce44SJohn Forte  */
214*fcf3ce44SJohn Forte 
215*fcf3ce44SJohn Forte 		strncpy(fromfile,
216*fcf3ce44SJohn Forte 			pair_list[pairs].ffile, NSC_MAXPATH);
217*fcf3ce44SJohn Forte 		strncpy(tofile,
218*fcf3ce44SJohn Forte 			pair_list[pairs].tfile, NSC_MAXPATH);
219*fcf3ce44SJohn Forte 		strncpy(frombitmap,
220*fcf3ce44SJohn Forte 			pair_list[pairs].fbitmap, NSC_MAXPATH);
221*fcf3ce44SJohn Forte 		strncpy(fromhost,
222*fcf3ce44SJohn Forte 			pair_list[pairs].fhost, MAX_RDC_HOST_SIZE);
223*fcf3ce44SJohn Forte 		strncpy(tohost,
224*fcf3ce44SJohn Forte 			pair_list[pairs].thost, MAX_RDC_HOST_SIZE);
225*fcf3ce44SJohn Forte 		strncpy(tobitmap,
226*fcf3ce44SJohn Forte 			pair_list[pairs].tbitmap, NSC_MAXPATH);
227*fcf3ce44SJohn Forte 		strncpy(directfile,
228*fcf3ce44SJohn Forte 			pair_list[pairs].directfile, NSC_MAXPATH);
229*fcf3ce44SJohn Forte 		strncpy(diskqueue,
230*fcf3ce44SJohn Forte 			pair_list[pairs].diskqueue, NSC_MAXPATH);
231*fcf3ce44SJohn Forte 		strncpy(group,
232*fcf3ce44SJohn Forte 			pair_list[pairs].group, NSC_MAXPATH);
233*fcf3ce44SJohn Forte 		strncpy(lhost,
234*fcf3ce44SJohn Forte 			pair_list[pairs].lhost, MAX_RDC_HOST_SIZE);
235*fcf3ce44SJohn Forte 
236*fcf3ce44SJohn Forte 		doasync = pair_list[pairs].doasync;
237*fcf3ce44SJohn Forte 		setid = pair_list[pairs].setid;
238*fcf3ce44SJohn Forte 		if (rdc_operation(fromhost, fromfile, frombitmap,
239*fcf3ce44SJohn Forte 		    tohost, tofile, tobitmap, flag, directfile, group,
240*fcf3ce44SJohn Forte 		    diskqueue, doasync, lhost, setid)
241*fcf3ce44SJohn Forte 		    < 0) {
242*fcf3ce44SJohn Forte 			exit(255);
243*fcf3ce44SJohn Forte 		}
244*fcf3ce44SJohn Forte 
245*fcf3ce44SJohn Forte 		exit(0);
246*fcf3ce44SJohn Forte 	}
247*fcf3ce44SJohn Forte 
248*fcf3ce44SJohn Forte 	while ((wait((int *)0) > 0))
249*fcf3ce44SJohn Forte 		;
250*fcf3ce44SJohn Forte 	return (0);
251*fcf3ce44SJohn Forte }
252*fcf3ce44SJohn Forte 
253*fcf3ce44SJohn Forte static int
254*fcf3ce44SJohn Forte rdc_operation(fromhost, fromfile, frombitmap, tohost, tofile,
255*fcf3ce44SJohn Forte     tobitmap, flag, directfile, group, diskqueue, doasync,
256*fcf3ce44SJohn Forte     lhost, setid)
257*fcf3ce44SJohn Forte char *fromhost, *fromfile, *frombitmap;
258*fcf3ce44SJohn Forte char *tohost, *tofile, *tobitmap;
259*fcf3ce44SJohn Forte int flag, doasync;
260*fcf3ce44SJohn Forte char *directfile;
261*fcf3ce44SJohn Forte char *group, *diskqueue;
262*fcf3ce44SJohn Forte int setid;
263*fcf3ce44SJohn Forte char *lhost;
264*fcf3ce44SJohn Forte {
265*fcf3ce44SJohn Forte 	const int getaddr = (flag == RDC_CMD_RESUME);
266*fcf3ce44SJohn Forte 	const int rpcbind = !getaddr;
267*fcf3ce44SJohn Forte 	rdc_config_t parms;
268*fcf3ce44SJohn Forte 	int ret;
269*fcf3ce44SJohn Forte 	spcs_s_info_t ustatus;
270*fcf3ce44SJohn Forte 	struct hostent *hp;
271*fcf3ce44SJohn Forte 	char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
272*fcf3ce44SJohn Forte 	struct t_info tinfo;
273*fcf3ce44SJohn Forte 	int i;
274*fcf3ce44SJohn Forte 
275*fcf3ce44SJohn Forte 	conf = &nconf;
276*fcf3ce44SJohn Forte 	bzero(&fromname, MAXHOSTNAMELEN);
277*fcf3ce44SJohn Forte 	bzero(&toname, MAXHOSTNAMELEN);
278*fcf3ce44SJohn Forte 
279*fcf3ce44SJohn Forte 	hp = gethost_byname(fromhost);
280*fcf3ce44SJohn Forte 	if (hp == NULL) {
281*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
282*fcf3ce44SJohn Forte 		    gettext("%s gethost_byname failed for %s"),
283*fcf3ce44SJohn Forte 		    program, fromhost);
284*fcf3ce44SJohn Forte 	}
285*fcf3ce44SJohn Forte 	if (strcmp(hp->h_name, fromhost) == 0)
286*fcf3ce44SJohn Forte 		strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
287*fcf3ce44SJohn Forte 	else {
288*fcf3ce44SJohn Forte 	for (i = 0; hp->h_aliases[i] != NULL; i++) {
289*fcf3ce44SJohn Forte 		if (strcmp(hp->h_aliases[i], fromhost) == 0)
290*fcf3ce44SJohn Forte 			strncpy(fromname, hp->h_aliases[i], MAXHOSTNAMELEN);
291*fcf3ce44SJohn Forte 		}
292*fcf3ce44SJohn Forte 	}
293*fcf3ce44SJohn Forte 	if (fromname[0] == '\0') {
294*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
295*fcf3ce44SJohn Forte 		    gettext("%s host %s is not local"),
296*fcf3ce44SJohn Forte 		    program, fromhost);
297*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Host %s is not local"),
298*fcf3ce44SJohn Forte 		    fromhost);
299*fcf3ce44SJohn Forte 	}
300*fcf3ce44SJohn Forte 	hp = gethost_byname(tohost);
301*fcf3ce44SJohn Forte 	if (hp == NULL) {
302*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
303*fcf3ce44SJohn Forte 		    gettext("%s gethost_byname failed for %s"),
304*fcf3ce44SJohn Forte 		    program, tohost);
305*fcf3ce44SJohn Forte 	}
306*fcf3ce44SJohn Forte 	if (strcmp(hp->h_name, tohost) == 0)
307*fcf3ce44SJohn Forte 		strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
308*fcf3ce44SJohn Forte 	else {
309*fcf3ce44SJohn Forte 	for (i = 0; hp->h_aliases[i] != NULL; i++) {
310*fcf3ce44SJohn Forte 		if (strcmp(hp->h_aliases[i], tohost) == 0)
311*fcf3ce44SJohn Forte 			strncpy(toname, hp->h_aliases[i], MAXHOSTNAMELEN);
312*fcf3ce44SJohn Forte 		}
313*fcf3ce44SJohn Forte 	}
314*fcf3ce44SJohn Forte 	if (toname[0] == '\0') {
315*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
316*fcf3ce44SJohn Forte 		    gettext("%s host %s is not local"),
317*fcf3ce44SJohn Forte 		    program, tohost);
318*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Host %s is not local"),
319*fcf3ce44SJohn Forte 		    tohost);
320*fcf3ce44SJohn Forte 	}
321*fcf3ce44SJohn Forte 
322*fcf3ce44SJohn Forte 	if (self_check(fromname) && self_check(toname)) {
323*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
324*fcf3ce44SJohn Forte 		    gettext("%s Both %s and %s are local"),
325*fcf3ce44SJohn Forte 		    program, fromhost, tohost);
326*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Both %s and %s are local"),
327*fcf3ce44SJohn Forte 		    fromhost, tohost);
328*fcf3ce44SJohn Forte 	}
329*fcf3ce44SJohn Forte 
330*fcf3ce44SJohn Forte 	/*
331*fcf3ce44SJohn Forte 	 * Now build up the address for each host including port and transport
332*fcf3ce44SJohn Forte 	 */
333*fcf3ce44SJohn Forte 	if (getaddr) {
334*fcf3ce44SJohn Forte 		svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
335*fcf3ce44SJohn Forte 			&conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind);
336*fcf3ce44SJohn Forte 
337*fcf3ce44SJohn Forte 		if (svp == NULL) {
338*fcf3ce44SJohn Forte #ifdef DEBUG
339*fcf3ce44SJohn Forte 			(void) printf("get_addr failed for Ver 4 %s\n", toname);
340*fcf3ce44SJohn Forte #endif
341*fcf3ce44SJohn Forte 			spcs_log("sndr", NULL,
342*fcf3ce44SJohn Forte 			    gettext("%s get_addr failed for Ver 4"),
343*fcf3ce44SJohn Forte 			    program);
344*fcf3ce44SJohn Forte 			return (-1);
345*fcf3ce44SJohn Forte 		}
346*fcf3ce44SJohn Forte 		svaddr = *svp;
347*fcf3ce44SJohn Forte 	} else {
348*fcf3ce44SJohn Forte 		bzero(&svaddr, sizeof (svaddr));
349*fcf3ce44SJohn Forte 	}
350*fcf3ce44SJohn Forte 
351*fcf3ce44SJohn Forte 	parms.rdc_set->secondary.addr.len = svaddr.len;
352*fcf3ce44SJohn Forte 	parms.rdc_set->secondary.addr.maxlen = svaddr.maxlen;
353*fcf3ce44SJohn Forte 	parms.rdc_set->secondary.addr.buf = (void *)svaddr.buf;
354*fcf3ce44SJohn Forte 
355*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR
356*fcf3ce44SJohn Forte 	(void) fprintf(stderr,
357*fcf3ce44SJohn Forte 		"secondary buf %x len %d\n", svaddr.buf, svaddr.len);
358*fcf3ce44SJohn Forte 
359*fcf3ce44SJohn Forte 	for (i = 0; i < svaddr.len; i++)
360*fcf3ce44SJohn Forte 		(void) printf("%u ", svaddr.buf[i]);
361*fcf3ce44SJohn Forte 	(void) printf("\n");
362*fcf3ce44SJohn Forte #endif
363*fcf3ce44SJohn Forte 
364*fcf3ce44SJohn Forte 	if (getaddr) {
365*fcf3ce44SJohn Forte 		svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
366*fcf3ce44SJohn Forte 			&conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind);
367*fcf3ce44SJohn Forte 		if (svp == NULL) {
368*fcf3ce44SJohn Forte #ifdef DEBUG
369*fcf3ce44SJohn Forte 			(void) printf("get_addr failed for Ver 4 %s\n",
370*fcf3ce44SJohn Forte 			    fromname);
371*fcf3ce44SJohn Forte #endif
372*fcf3ce44SJohn Forte 			return (-1);
373*fcf3ce44SJohn Forte 		}
374*fcf3ce44SJohn Forte 		svaddr = *svp;
375*fcf3ce44SJohn Forte 	} else {
376*fcf3ce44SJohn Forte 		;
377*fcf3ce44SJohn Forte 		/*EMPTY*/
378*fcf3ce44SJohn Forte 	}
379*fcf3ce44SJohn Forte 	parms.rdc_set->primary.addr.len = svaddr.len;
380*fcf3ce44SJohn Forte 	parms.rdc_set->primary.addr.maxlen = svaddr.maxlen;
381*fcf3ce44SJohn Forte 	parms.rdc_set->primary.addr.buf =
382*fcf3ce44SJohn Forte 				(void *)svaddr.buf;
383*fcf3ce44SJohn Forte 
384*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR
385*fcf3ce44SJohn Forte 	(void) fprintf(stderr, "primary buf %x len %d\n",
386*fcf3ce44SJohn Forte 	    svaddr.buf, svaddr.len);
387*fcf3ce44SJohn Forte 	for (i = 0; i < svaddr.len; i++)
388*fcf3ce44SJohn Forte 		(void) printf("%u ", svaddr.buf[i]);
389*fcf3ce44SJohn Forte 	(void) printf("\n");
390*fcf3ce44SJohn Forte #endif
391*fcf3ce44SJohn Forte 
392*fcf3ce44SJohn Forte 	if (getaddr) {
393*fcf3ce44SJohn Forte 		(void) convert_nconf_to_knconf(conf, &knconf);
394*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR
395*fcf3ce44SJohn Forte 		(void) printf("knconf %x %s %s %x\n", knconf.knc_semantics,
396*fcf3ce44SJohn Forte 		    knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev);
397*fcf3ce44SJohn Forte #endif
398*fcf3ce44SJohn Forte 		parms.rdc_set->netconfig = &knconf;
399*fcf3ce44SJohn Forte 	} else {
400*fcf3ce44SJohn Forte 		parms.rdc_set->netconfig = NULL;
401*fcf3ce44SJohn Forte 	}
402*fcf3ce44SJohn Forte 	if (!clustered && !self_check(fromname) && !self_check(toname)) {
403*fcf3ce44SJohn Forte 		spcs_log("sndr", NULL,
404*fcf3ce44SJohn Forte 		    gettext("%s Neither %s nor %s is local"),
405*fcf3ce44SJohn Forte 		    program, fromhost, tohost);
406*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Neither %s nor %s is local"),
407*fcf3ce44SJohn Forte 		    fromhost, tohost);
408*fcf3ce44SJohn Forte 	}
409*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->primary.intf, fromhost, MAX_RDC_HOST_SIZE);
410*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH);
411*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH);
412*fcf3ce44SJohn Forte 
413*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->secondary.intf, tohost, MAX_RDC_HOST_SIZE);
414*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH);
415*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH);
416*fcf3ce44SJohn Forte 
417*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH);
418*fcf3ce44SJohn Forte 	strncpy(parms.rdc_set->disk_queue, diskqueue, NSC_MAXPATH);
419*fcf3ce44SJohn Forte 
420*fcf3ce44SJohn Forte 	parms.rdc_set->maxqfbas = maxqfbas;
421*fcf3ce44SJohn Forte 	parms.rdc_set->maxqitems = maxqitems;
422*fcf3ce44SJohn Forte 	parms.rdc_set->autosync = autosync;
423*fcf3ce44SJohn Forte 	parms.rdc_set->asyncthr = asyncthr;
424*fcf3ce44SJohn Forte 	parms.rdc_set->setid = setid;
425*fcf3ce44SJohn Forte 
426*fcf3ce44SJohn Forte 	/* gethostid(3c) is defined to return a 32bit value */
427*fcf3ce44SJohn Forte 	parms.rdc_set->syshostid = (int32_t)gethostid();
428*fcf3ce44SJohn Forte 
429*fcf3ce44SJohn Forte 	parms.command = 0;
430*fcf3ce44SJohn Forte 	parms.options = 0;
431*fcf3ce44SJohn Forte 	parms.command = flag;
432*fcf3ce44SJohn Forte 
433*fcf3ce44SJohn Forte 	if (flag == RDC_CMD_RESUME) {
434*fcf3ce44SJohn Forte 		if (doasync)
435*fcf3ce44SJohn Forte 			parms.options |= RDC_OPT_ASYNC;
436*fcf3ce44SJohn Forte 		else
437*fcf3ce44SJohn Forte 			parms.options |= RDC_OPT_SYNC;
438*fcf3ce44SJohn Forte 	}
439*fcf3ce44SJohn Forte 	if (clustered) {
440*fcf3ce44SJohn Forte 		if (!ctag)
441*fcf3ce44SJohn Forte 			goto noconfig;
442*fcf3ce44SJohn Forte 		if (strcmp(ctag, "-") == 0)
443*fcf3ce44SJohn Forte 			goto noconfig;
444*fcf3ce44SJohn Forte 
445*fcf3ce44SJohn Forte #ifdef DEBUG
446*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "logical hostname: %s\n", lhost);
447*fcf3ce44SJohn Forte #endif
448*fcf3ce44SJohn Forte 
449*fcf3ce44SJohn Forte 		if (strcmp(lhost, fromname) == 0) {
450*fcf3ce44SJohn Forte 			parms.options |= RDC_OPT_PRIMARY;
451*fcf3ce44SJohn Forte 			strncpy(parms.rdc_set->direct_file, directfile,
452*fcf3ce44SJohn Forte 				NSC_MAXPATH);
453*fcf3ce44SJohn Forte 
454*fcf3ce44SJohn Forte 		} else {
455*fcf3ce44SJohn Forte 			parms.options |= RDC_OPT_SECONDARY;
456*fcf3ce44SJohn Forte 			parms.rdc_set->direct_file[0] = 0; /* no fcal direct */
457*fcf3ce44SJohn Forte 		}
458*fcf3ce44SJohn Forte 	} else {
459*fcf3ce44SJohn Forte noconfig:
460*fcf3ce44SJohn Forte 		/*
461*fcf3ce44SJohn Forte 		 * If not clustered, don't resume sndr sets with lhost
462*fcf3ce44SJohn Forte 		 */
463*fcf3ce44SJohn Forte 		if ((flag == RDC_CMD_RESUME) && lhost && strlen(lhost))
464*fcf3ce44SJohn Forte 			return (0);
465*fcf3ce44SJohn Forte 
466*fcf3ce44SJohn Forte 		if (self_check(fromname)) {
467*fcf3ce44SJohn Forte 			parms.options |= RDC_OPT_PRIMARY;
468*fcf3ce44SJohn Forte 			strncpy(parms.rdc_set->direct_file, directfile,
469*fcf3ce44SJohn Forte 				NSC_MAXPATH);
470*fcf3ce44SJohn Forte 		} else {
471*fcf3ce44SJohn Forte 			parms.options |= RDC_OPT_SECONDARY;
472*fcf3ce44SJohn Forte 			parms.rdc_set->direct_file[0] = 0; /* no fcal direct */
473*fcf3ce44SJohn Forte 		}
474*fcf3ce44SJohn Forte 	}
475*fcf3ce44SJohn Forte 
476*fcf3ce44SJohn Forte 	ustatus = spcs_s_ucreate();
477*fcf3ce44SJohn Forte 
478*fcf3ce44SJohn Forte 	errno = 0;
479*fcf3ce44SJohn Forte 	ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
480*fcf3ce44SJohn Forte 	if (ret != SPCS_S_OK) {
481*fcf3ce44SJohn Forte 
482*fcf3ce44SJohn Forte 		/* Surpress error messages for suspend on cluster elements */
483*fcf3ce44SJohn Forte 		if ((flag == RDC_CMD_SUSPEND) && (errno == RDC_EALREADY) &&
484*fcf3ce44SJohn Forte 			!clustered && lhost && strlen(lhost)) {
485*fcf3ce44SJohn Forte 			spcs_s_ufree(&ustatus);
486*fcf3ce44SJohn Forte 			return (0);
487*fcf3ce44SJohn Forte 		}
488*fcf3ce44SJohn Forte 
489*fcf3ce44SJohn Forte 		(void) fprintf(stderr,
490*fcf3ce44SJohn Forte 			gettext("Remote Mirror: %s %s %s %s %s %s\n"),
491*fcf3ce44SJohn Forte 			fromhost, fromfile,
492*fcf3ce44SJohn Forte 			frombitmap, tohost, tofile, tobitmap);
493*fcf3ce44SJohn Forte 
494*fcf3ce44SJohn Forte 		if (errno == RDC_EEINVAL) {
495*fcf3ce44SJohn Forte 			spcs_log("sndr", NULL,
496*fcf3ce44SJohn Forte 			    gettext("%s %s %s %s %s %s %s %s\n%s"),
497*fcf3ce44SJohn Forte 			    program, rdc_decode_flag(flag, parms.options),
498*fcf3ce44SJohn Forte 			    fromhost, fromfile, frombitmap,
499*fcf3ce44SJohn Forte 			    tohost, tofile, tobitmap,
500*fcf3ce44SJohn Forte 			    gettext("invalid command option"));
501*fcf3ce44SJohn Forte 			rdc_err(&ustatus,
502*fcf3ce44SJohn Forte 			    gettext("Remote Mirror: invalid command option "
503*fcf3ce44SJohn Forte 				    "'%s'"), rdc_decode_flag(flag,
504*fcf3ce44SJohn Forte 				    parms.options));
505*fcf3ce44SJohn Forte 		} else {
506*fcf3ce44SJohn Forte 			spcs_log("sndr", &ustatus,
507*fcf3ce44SJohn Forte 			    gettext("%s %s %s %s %s %s %s %s"),
508*fcf3ce44SJohn Forte 			    program, rdc_decode_flag(flag, parms.options),
509*fcf3ce44SJohn Forte 			    fromhost, fromfile, frombitmap,
510*fcf3ce44SJohn Forte 			    tohost, tofile, tobitmap);
511*fcf3ce44SJohn Forte 			rdc_err(&ustatus, 0);
512*fcf3ce44SJohn Forte 		}
513*fcf3ce44SJohn Forte 	}
514*fcf3ce44SJohn Forte 
515*fcf3ce44SJohn Forte 	spcs_log("sndr", NULL,
516*fcf3ce44SJohn Forte 	    gettext("%s %s %s %s %s %s %s %s\nSuccessful"),
517*fcf3ce44SJohn Forte 	    program, rdc_decode_flag(flag, parms.options),
518*fcf3ce44SJohn Forte 	    fromhost, fromfile, frombitmap, tohost, tofile, tobitmap);
519*fcf3ce44SJohn Forte 
520*fcf3ce44SJohn Forte 	spcs_s_ufree(&ustatus);
521*fcf3ce44SJohn Forte 	return (0);
522*fcf3ce44SJohn Forte }
523*fcf3ce44SJohn Forte /*
524*fcf3ce44SJohn Forte  * assign setid's to any existing
525*fcf3ce44SJohn Forte  * sets without setids, making sure of course NOT to re-use a setid
526*fcf3ce44SJohn Forte  */
527*fcf3ce44SJohn Forte int
528*fcf3ce44SJohn Forte update_setids(CFGFILE *cfg, int *no_id, int highest)
529*fcf3ce44SJohn Forte {
530*fcf3ce44SJohn Forte 	int setid;
531*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
532*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
533*fcf3ce44SJohn Forte 	char *ctag;
534*fcf3ce44SJohn Forte 
535*fcf3ce44SJohn Forte 	/* If in a Sun Cluster, SetIDs need to have a ctag */
536*fcf3ce44SJohn Forte 	if ((ctag = cfg_get_resource(cfg)) != NULL) {
537*fcf3ce44SJohn Forte 		ctag = strdup(ctag);
538*fcf3ce44SJohn Forte 		cfg_resource(cfg, "setid-ctag");
539*fcf3ce44SJohn Forte 	}
540*fcf3ce44SJohn Forte 
541*fcf3ce44SJohn Forte 	/*
542*fcf3ce44SJohn Forte 	 * Paranoia. IF there are any sets with setids, we don't
543*fcf3ce44SJohn Forte 	 * want to re-use their number.
544*fcf3ce44SJohn Forte 	 */
545*fcf3ce44SJohn Forte 	if (highest > get_new_cfg_setid(cfg)) {
546*fcf3ce44SJohn Forte 		bzero(&buf, sizeof (buf));
547*fcf3ce44SJohn Forte 		(void) sprintf(buf, "%d", highest);
548*fcf3ce44SJohn Forte 		if (cfg_put_cstring(cfg, "setid.set1.value", buf,
549*fcf3ce44SJohn Forte 		    sizeof (buf)) < 0)
550*fcf3ce44SJohn Forte 			rdc_warn(NULL, gettext("sndrboot: Unable to store "
551*fcf3ce44SJohn Forte 			    "new setid"));
552*fcf3ce44SJohn Forte 	}
553*fcf3ce44SJohn Forte 
554*fcf3ce44SJohn Forte 	for (setid = 0; no_id[setid]; setid++) {
555*fcf3ce44SJohn Forte 		bzero(&buf, sizeof (buf));
556*fcf3ce44SJohn Forte 		bzero(&key, sizeof (key));
557*fcf3ce44SJohn Forte 		(void) sprintf(buf, "%d", get_new_cfg_setid(cfg));
558*fcf3ce44SJohn Forte 		(void) sprintf(key, "sndr.set%d.options", no_id[setid]);
559*fcf3ce44SJohn Forte 		if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid", buf) < 0)
560*fcf3ce44SJohn Forte 			rdc_warn(NULL, gettext("sndrboot: Unable to store "
561*fcf3ce44SJohn Forte 			    "unique setid"));
562*fcf3ce44SJohn Forte 
563*fcf3ce44SJohn Forte 		pair_list[no_id[setid] - 1].setid = atoi(buf);
564*fcf3ce44SJohn Forte 	}
565*fcf3ce44SJohn Forte 
566*fcf3ce44SJohn Forte 	/* Restore old ctag if in a Sun Cluster */
567*fcf3ce44SJohn Forte 	if (ctag) {
568*fcf3ce44SJohn Forte 		cfg_resource(cfg, ctag);
569*fcf3ce44SJohn Forte 		free(ctag);
570*fcf3ce44SJohn Forte 	}
571*fcf3ce44SJohn Forte 
572*fcf3ce44SJohn Forte 	if (cfg_commit(cfg) < 0)
573*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("sndrboot: Failed to commit setids"));
574*fcf3ce44SJohn Forte 
575*fcf3ce44SJohn Forte 	return (setid);
576*fcf3ce44SJohn Forte }
577*fcf3ce44SJohn Forte 
578*fcf3ce44SJohn Forte /*
579*fcf3ce44SJohn Forte  * this is called when the option lghn is no available in libdscfg
580*fcf3ce44SJohn Forte  * that should only happen on an upgrade.
581*fcf3ce44SJohn Forte  * cfg write lock must be held across this function
582*fcf3ce44SJohn Forte  */
583*fcf3ce44SJohn Forte char *
584*fcf3ce44SJohn Forte get_lghn(CFGFILE *cfg, char *ctag, int setnum, int flag)
585*fcf3ce44SJohn Forte {
586*fcf3ce44SJohn Forte 	FILE *pipe;
587*fcf3ce44SJohn Forte 	char rsgrp[SCCONF_MAXSTRINGLEN];
588*fcf3ce44SJohn Forte 	char cmd[SCCONF_MAXSTRINGLEN];
589*fcf3ce44SJohn Forte 	static char lhostname[MAX_RDC_HOST_SIZE];
590*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
591*fcf3ce44SJohn Forte 	int rc;
592*fcf3ce44SJohn Forte 
593*fcf3ce44SJohn Forte 	if (ctag == NULL)
594*fcf3ce44SJohn Forte 		goto fail;
595*fcf3ce44SJohn Forte 
596*fcf3ce44SJohn Forte 	bzero(&lhostname, sizeof (lhostname));
597*fcf3ce44SJohn Forte 
598*fcf3ce44SJohn Forte 	(void) sprintf(rsgrp, "%s-stor-rg", ctag);
599*fcf3ce44SJohn Forte /* BEGIN CSTYLED */
600*fcf3ce44SJohn Forte 	rc = snprintf(cmd, SCCONF_MAXSTRINGLEN,
601*fcf3ce44SJohn Forte 	    "/usr/cluster/bin/scrgadm -pvv | fgrep HostnameList \
602*fcf3ce44SJohn Forte | fgrep %s | fgrep value | awk -F: '{ print $4 }'", rsgrp);
603*fcf3ce44SJohn Forte /* END CSTYLED */
604*fcf3ce44SJohn Forte 
605*fcf3ce44SJohn Forte 	if (rc < 0) {
606*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Error getting scrgadm output"));
607*fcf3ce44SJohn Forte 	}
608*fcf3ce44SJohn Forte 
609*fcf3ce44SJohn Forte 	pipe = popen(cmd, "r");
610*fcf3ce44SJohn Forte 
611*fcf3ce44SJohn Forte 	if (pipe == NULL) {
612*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Error opening pipe"));
613*fcf3ce44SJohn Forte 	}
614*fcf3ce44SJohn Forte 	rc = fscanf(pipe, "%s", lhostname);
615*fcf3ce44SJohn Forte 	(void) pclose(pipe);
616*fcf3ce44SJohn Forte 
617*fcf3ce44SJohn Forte 	if (rc != 1) {
618*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Unable to get logical host"));
619*fcf3ce44SJohn Forte 	}
620*fcf3ce44SJohn Forte 
621*fcf3ce44SJohn Forte 	/* not really failing, but suspend does not have the config lock */
622*fcf3ce44SJohn Forte 	if (flag == RDC_CMD_SUSPEND)
623*fcf3ce44SJohn Forte 		goto fail;
624*fcf3ce44SJohn Forte 
625*fcf3ce44SJohn Forte 	bzero(&key, sizeof (key));
626*fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "sndr.set%d.options", setnum);
627*fcf3ce44SJohn Forte 	if (cfg_put_options(cfg, CFG_SEC_CONF, key, "lghn", lhostname) < 0)
628*fcf3ce44SJohn Forte 		rdc_warn(NULL, gettext("sndrboot: Unable to store logical "
629*fcf3ce44SJohn Forte 		    "host name in configuration database"));
630*fcf3ce44SJohn Forte 
631*fcf3ce44SJohn Forte 	if (cfg_commit(cfg) < 0)
632*fcf3ce44SJohn Forte 		rdc_err(NULL,
633*fcf3ce44SJohn Forte 		    gettext("sndrboot: Failed to commit logical host name"));
634*fcf3ce44SJohn Forte 
635*fcf3ce44SJohn Forte fail:
636*fcf3ce44SJohn Forte 	return (lhostname);
637*fcf3ce44SJohn Forte 
638*fcf3ce44SJohn Forte }
639*fcf3ce44SJohn Forte 
640*fcf3ce44SJohn Forte /*
641*fcf3ce44SJohn Forte  * read_libcfg()
642*fcf3ce44SJohn Forte  *
643*fcf3ce44SJohn Forte  * DESCRIPTION: Read the relevant config info via libcfg
644*fcf3ce44SJohn Forte  *
645*fcf3ce44SJohn Forte  * Outputs:
646*fcf3ce44SJohn Forte  *	int i			Number of pairs of devices
647*fcf3ce44SJohn Forte  *
648*fcf3ce44SJohn Forte  * Side Effects: The 0 to i-1 entries in the pair_list are filled.
649*fcf3ce44SJohn Forte  *
650*fcf3ce44SJohn Forte  */
651*fcf3ce44SJohn Forte static int
652*fcf3ce44SJohn Forte read_libcfg(int flag)
653*fcf3ce44SJohn Forte {
654*fcf3ce44SJohn Forte 	char fromhost[MAX_RDC_HOST_SIZE];
655*fcf3ce44SJohn Forte 	char fromfile[NSC_MAXPATH];
656*fcf3ce44SJohn Forte 	char frombitmap[NSC_MAXPATH];
657*fcf3ce44SJohn Forte 	char tohost[MAX_RDC_HOST_SIZE];
658*fcf3ce44SJohn Forte 	char tofile[NSC_MAXPATH];
659*fcf3ce44SJohn Forte 	char tobitmap[NSC_MAXPATH];
660*fcf3ce44SJohn Forte 	char directfile[NSC_MAXPATH];
661*fcf3ce44SJohn Forte 	char diskqueue[NSC_MAXPATH];
662*fcf3ce44SJohn Forte 	char group[NSC_MAXPATH];
663*fcf3ce44SJohn Forte 	char lhost[MAX_RDC_HOST_SIZE];
664*fcf3ce44SJohn Forte 	char sync[16];
665*fcf3ce44SJohn Forte 	char setid[64];
666*fcf3ce44SJohn Forte 	int doasync;
667*fcf3ce44SJohn Forte 	CFGFILE *cfg;
668*fcf3ce44SJohn Forte 	int i, j = 0;
669*fcf3ce44SJohn Forte 	int rc;
670*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
671*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
672*fcf3ce44SJohn Forte 	char dummy[NSC_MAXPATH];
673*fcf3ce44SJohn Forte 	int setnumber;
674*fcf3ce44SJohn Forte 	int numsets;
675*fcf3ce44SJohn Forte 	int highest = 0;
676*fcf3ce44SJohn Forte 	char lghn[5];
677*fcf3ce44SJohn Forte 	int *no_id;
678*fcf3ce44SJohn Forte 
679*fcf3ce44SJohn Forte 
680*fcf3ce44SJohn Forte 	if ((cfg = cfg_open("")) == NULL)
681*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Error opening config"));
682*fcf3ce44SJohn Forte 
683*fcf3ce44SJohn Forte 	/*
684*fcf3ce44SJohn Forte 	 * If RDC_CMD_FIXSETIDS, we were called during post-patch install
685*fcf3ce44SJohn Forte 	 * Acquire a write-lock on the cfg_lock(), so the code can attempt
686*fcf3ce44SJohn Forte 	 * to fix setIDs
687*fcf3ce44SJohn Forte 	 */
688*fcf3ce44SJohn Forte 	if (flag == RDC_CMD_FIXSETIDS) {
689*fcf3ce44SJohn Forte 		if (!cfg_lock(cfg, CFG_WRLOCK))
690*fcf3ce44SJohn Forte 			rdc_err(NULL, gettext("Error write locking config"));
691*fcf3ce44SJohn Forte 		cfg_resource(cfg, NULL);
692*fcf3ce44SJohn Forte 	} else {
693*fcf3ce44SJohn Forte 		if (!cfg_lock(cfg, CFG_RDLOCK))
694*fcf3ce44SJohn Forte 			rdc_err(NULL, gettext("Error locking config"));
695*fcf3ce44SJohn Forte 		cfg_resource(cfg, ctag);
696*fcf3ce44SJohn Forte 	}
697*fcf3ce44SJohn Forte 
698*fcf3ce44SJohn Forte 	if ((numsets = cfg_get_num_entries(cfg, "sndr")) < 0)
699*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("Unable to get set info from config"));
700*fcf3ce44SJohn Forte 
701*fcf3ce44SJohn Forte 	no_id = (int *)calloc(numsets + 1, sizeof (int));
702*fcf3ce44SJohn Forte 	if (!no_id)
703*fcf3ce44SJohn Forte 		rdc_err(NULL, gettext("No memory"));
704*fcf3ce44SJohn Forte 
705*fcf3ce44SJohn Forte 
706*fcf3ce44SJohn Forte 	(void) snprintf(lghn, sizeof (lghn), "lghn");
707*fcf3ce44SJohn Forte 
708*fcf3ce44SJohn Forte 	for (i = 0; i < rdc_maxsets; i++) {
709*fcf3ce44SJohn Forte 		setnumber = i + 1;
710*fcf3ce44SJohn Forte 
711*fcf3ce44SJohn Forte 		bzero(buf, CFG_MAX_BUF);
712*fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
713*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
714*fcf3ce44SJohn Forte 			break;
715*fcf3ce44SJohn Forte 
716*fcf3ce44SJohn Forte 		rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s",
717*fcf3ce44SJohn Forte 		    fromhost, fromfile, frombitmap, tohost, tofile, tobitmap,
718*fcf3ce44SJohn Forte 			directfile, sync, group, dummy, dummy, diskqueue);
719*fcf3ce44SJohn Forte 		if (rc != 12)
720*fcf3ce44SJohn Forte 			rdc_err(NULL, gettext("cfg input error (%d)"), rc);
721*fcf3ce44SJohn Forte 
722*fcf3ce44SJohn Forte 		if (strcmp(directfile, "ip") == 0)
723*fcf3ce44SJohn Forte 			strcpy(directfile, "");
724*fcf3ce44SJohn Forte 
725*fcf3ce44SJohn Forte 		if (strcmp(group, "-") == 0)
726*fcf3ce44SJohn Forte 			strcpy(group, "");
727*fcf3ce44SJohn Forte 
728*fcf3ce44SJohn Forte 		if (strcmp(diskqueue, "-") == 0)
729*fcf3ce44SJohn Forte 			strcpy(diskqueue, "");
730*fcf3ce44SJohn Forte 
731*fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key),
732*fcf3ce44SJohn Forte 			"sndr.set%d.options", setnumber);
733*fcf3ce44SJohn Forte 
734*fcf3ce44SJohn Forte 		if (cfg_get_single_option(cfg, CFG_SEC_CONF, key,
735*fcf3ce44SJohn Forte 			lghn, lhost, MAX_RDC_HOST_SIZE) < 0)
736*fcf3ce44SJohn Forte 			strcpy(lhost,
737*fcf3ce44SJohn Forte 			    get_lghn(cfg, ctag, setnumber, flag));
738*fcf3ce44SJohn Forte 
739*fcf3ce44SJohn Forte 		if (strcmp(sync, "sync") == 0)
740*fcf3ce44SJohn Forte 			doasync = 0;
741*fcf3ce44SJohn Forte 		else if (strcmp(sync, "async") == 0)
742*fcf3ce44SJohn Forte 			doasync = 1;
743*fcf3ce44SJohn Forte 		else {
744*fcf3ce44SJohn Forte 			cfg_close(cfg);
745*fcf3ce44SJohn Forte 			rdc_err(NULL,
746*fcf3ce44SJohn Forte 			    gettext("Set %s:%s neither sync nor async"),
747*fcf3ce44SJohn Forte 			    tohost, tofile);
748*fcf3ce44SJohn Forte 		}
749*fcf3ce44SJohn Forte 
750*fcf3ce44SJohn Forte 		strncpy(pair_list[i].fhost, fromhost,
751*fcf3ce44SJohn Forte 			MAX_RDC_HOST_SIZE);
752*fcf3ce44SJohn Forte 		strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH);
753*fcf3ce44SJohn Forte 		strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH);
754*fcf3ce44SJohn Forte 		strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE);
755*fcf3ce44SJohn Forte 		strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH);
756*fcf3ce44SJohn Forte 		strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH);
757*fcf3ce44SJohn Forte 		strncpy(pair_list[i].directfile, directfile,
758*fcf3ce44SJohn Forte 			NSC_MAXPATH);
759*fcf3ce44SJohn Forte 		strncpy(pair_list[i].diskqueue, diskqueue,
760*fcf3ce44SJohn Forte 			NSC_MAXPATH);
761*fcf3ce44SJohn Forte 		strncpy(pair_list[i].group, group, NSC_MAXPATH);
762*fcf3ce44SJohn Forte 		strncpy(pair_list[i].lhost, lhost, MAX_RDC_HOST_SIZE);
763*fcf3ce44SJohn Forte 		pair_list[i].doasync = doasync;
764*fcf3ce44SJohn Forte 
765*fcf3ce44SJohn Forte 		if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, "setid",
766*fcf3ce44SJohn Forte 		    setid, sizeof (setid)) < 0) {
767*fcf3ce44SJohn Forte 			no_id[j++] = setnumber;
768*fcf3ce44SJohn Forte 		}
769*fcf3ce44SJohn Forte 		pair_list[i].setid = atoi(setid);
770*fcf3ce44SJohn Forte 
771*fcf3ce44SJohn Forte 		if (pair_list[i].setid > highest)
772*fcf3ce44SJohn Forte 			highest = pair_list[i].setid;
773*fcf3ce44SJohn Forte 
774*fcf3ce44SJohn Forte 		if (gethost_netaddrs(fromhost, tohost,
775*fcf3ce44SJohn Forte 		    (char *)pair_list[i].fnetaddr,
776*fcf3ce44SJohn Forte 		    (char *)pair_list[i].tnetaddr) < 0) {
777*fcf3ce44SJohn Forte 			cfg_close(cfg);
778*fcf3ce44SJohn Forte 			spcs_log("sndr", NULL,
779*fcf3ce44SJohn Forte 			    gettext("%s unable to determine IP addresses "
780*fcf3ce44SJohn Forte 			    "for hosts %s %s"), program, fromhost, tohost);
781*fcf3ce44SJohn Forte 			rdc_err(NULL, gettext("unable to determine IP "
782*fcf3ce44SJohn Forte 			    "addresses for hosts %s, %s"), fromhost, tohost);
783*fcf3ce44SJohn Forte 		}
784*fcf3ce44SJohn Forte 	}
785*fcf3ce44SJohn Forte 	/*
786*fcf3ce44SJohn Forte 	 * fix any lost set ids if possible, also deal with upgrade
787*fcf3ce44SJohn Forte 	 */
788*fcf3ce44SJohn Forte 	if (j > 0 && flag == RDC_CMD_FIXSETIDS) {
789*fcf3ce44SJohn Forte 		(void) update_setids(cfg, no_id, highest);
790*fcf3ce44SJohn Forte 		i = j;	/* Set number of fixups */
791*fcf3ce44SJohn Forte 	}
792*fcf3ce44SJohn Forte 	free(no_id);
793*fcf3ce44SJohn Forte 	cfg_close(cfg);
794*fcf3ce44SJohn Forte 	return (i);
795*fcf3ce44SJohn Forte }
796*fcf3ce44SJohn Forte 
797*fcf3ce44SJohn Forte 
798*fcf3ce44SJohn Forte int
799*fcf3ce44SJohn Forte parseopts(argc, argv, flag)
800*fcf3ce44SJohn Forte int argc;
801*fcf3ce44SJohn Forte char **argv;
802*fcf3ce44SJohn Forte int *flag;
803*fcf3ce44SJohn Forte {
804*fcf3ce44SJohn Forte 	int  errflag = 0;
805*fcf3ce44SJohn Forte 	char c;
806*fcf3ce44SJohn Forte 	char inval = 0;
807*fcf3ce44SJohn Forte #ifdef DEBUG
808*fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, "C:Urs")) != -1) {
809*fcf3ce44SJohn Forte #else
810*fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, "C:rs")) != -1) {
811*fcf3ce44SJohn Forte #endif
812*fcf3ce44SJohn Forte 		switch (c) {
813*fcf3ce44SJohn Forte 		case 'C':
814*fcf3ce44SJohn Forte 			clustered = TRUE;
815*fcf3ce44SJohn Forte 			ctag = optarg;
816*fcf3ce44SJohn Forte 			break;
817*fcf3ce44SJohn Forte #ifdef DEBUG
818*fcf3ce44SJohn Forte 		case 'U':
819*fcf3ce44SJohn Forte 			proto_test = 1;
820*fcf3ce44SJohn Forte 			break;
821*fcf3ce44SJohn Forte #endif
822*fcf3ce44SJohn Forte 		case 'r':
823*fcf3ce44SJohn Forte 			if (*flag)
824*fcf3ce44SJohn Forte 				inval = 1;
825*fcf3ce44SJohn Forte 			*flag = RDC_CMD_RESUME;
826*fcf3ce44SJohn Forte 			break;
827*fcf3ce44SJohn Forte 		case 's':
828*fcf3ce44SJohn Forte 			if (*flag)
829*fcf3ce44SJohn Forte 				inval = 1;
830*fcf3ce44SJohn Forte 			*flag = RDC_CMD_SUSPEND;
831*fcf3ce44SJohn Forte 			break;
832*fcf3ce44SJohn Forte 		case '?':
833*fcf3ce44SJohn Forte 			errflag++;
834*fcf3ce44SJohn Forte 		}
835*fcf3ce44SJohn Forte 	}
836*fcf3ce44SJohn Forte 
837*fcf3ce44SJohn Forte 	/*
838*fcf3ce44SJohn Forte 	 * Special fix to address no SetIds in AVS 3.1 to 3.2 install + patch
839*fcf3ce44SJohn Forte 	 * Adjust set IDs, if someone invokes the following invalid command
840*fcf3ce44SJohn Forte 	 *
841*fcf3ce44SJohn Forte 	 *	/use/sbin/sndrboot -C post-patch-setids -r -s
842*fcf3ce44SJohn Forte 	 *
843*fcf3ce44SJohn Forte 	 * Command will be called in post-install of the patch containing fix
844*fcf3ce44SJohn Forte 	 *
845*fcf3ce44SJohn Forte 	 */
846*fcf3ce44SJohn Forte 	if (clustered && (strcmp(ctag, "post-patch-setids") == 0) &&
847*fcf3ce44SJohn Forte 	    *flag && inval) {
848*fcf3ce44SJohn Forte 		*flag = RDC_CMD_FIXSETIDS;
849*fcf3ce44SJohn Forte 		return (0);
850*fcf3ce44SJohn Forte 	}
851*fcf3ce44SJohn Forte 
852*fcf3ce44SJohn Forte 	if (inval) {
853*fcf3ce44SJohn Forte 		rdc_warn(NULL, gettext("Invalid argument combination"));
854*fcf3ce44SJohn Forte 		errflag = 1;
855*fcf3ce44SJohn Forte 	}
856*fcf3ce44SJohn Forte 
857*fcf3ce44SJohn Forte 	if (!*flag || errflag) {
858*fcf3ce44SJohn Forte 		usage();
859*fcf3ce44SJohn Forte 		return (-1);
860*fcf3ce44SJohn Forte 	}
861*fcf3ce44SJohn Forte 
862*fcf3ce44SJohn Forte 	return (0);
863*fcf3ce44SJohn Forte }
864*fcf3ce44SJohn Forte 
865*fcf3ce44SJohn Forte static void
866*fcf3ce44SJohn Forte usage()
867*fcf3ce44SJohn Forte {
868*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext("usage:\n"));
869*fcf3ce44SJohn Forte 	(void) fprintf(stderr,
870*fcf3ce44SJohn Forte 		gettext("\t%s -r [-C tag]\t\t"
871*fcf3ce44SJohn Forte 			"resume\n"), program);
872*fcf3ce44SJohn Forte 
873*fcf3ce44SJohn Forte 	(void) fprintf(stderr,
874*fcf3ce44SJohn Forte 		gettext("\t%s -s [-C tag]\t\t"
875*fcf3ce44SJohn Forte 			"suspend\n"), program);
876*fcf3ce44SJohn Forte }
877