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