xref: /titanic_51/usr/src/cmd/avs/dsw/iiadm.c (revision ea3068a71489464a7cde899773f9ae3541209461)
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  */
21fcf3ce44SJohn Forte /*
22570de38fSSurya Prakki  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte 
26fcf3ce44SJohn Forte #include <sys/types.h>
27fcf3ce44SJohn Forte #include <sys/time.h>
28fcf3ce44SJohn Forte #include <errno.h>
29fcf3ce44SJohn Forte #include <signal.h>
30fcf3ce44SJohn Forte #include <stdio.h>
31fcf3ce44SJohn Forte #include <string.h>
32fcf3ce44SJohn Forte #include <fcntl.h>
33fcf3ce44SJohn Forte #include <stdlib.h>
34fcf3ce44SJohn Forte #include <unistd.h>
35fcf3ce44SJohn Forte #include <values.h>
36fcf3ce44SJohn Forte #include <locale.h>
37fcf3ce44SJohn Forte #include <langinfo.h>
38fcf3ce44SJohn Forte #include <sys/mman.h>
39fcf3ce44SJohn Forte #include <sys/stat.h>
40fcf3ce44SJohn Forte #include <sys/wait.h>
41fcf3ce44SJohn Forte #include <strings.h>
42fcf3ce44SJohn Forte #include <stdarg.h>
43fcf3ce44SJohn Forte #include <ctype.h>
44fcf3ce44SJohn Forte #include <math.h>
45fcf3ce44SJohn Forte #include <sys/param.h>
46fcf3ce44SJohn Forte #include <sys/mnttab.h>
47fcf3ce44SJohn Forte #include <nsctl.h>
48fcf3ce44SJohn Forte #include <netdb.h>
49fcf3ce44SJohn Forte #include <search.h>
50fcf3ce44SJohn Forte 
51fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
52fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.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 #include <sys/nsctl/dsw.h>
58fcf3ce44SJohn Forte #include <sys/nsctl/dsw_dev.h>		/* for bit map header format */
59fcf3ce44SJohn Forte 
60fcf3ce44SJohn Forte #include <sys/nskernd.h>
61fcf3ce44SJohn Forte 
62fcf3ce44SJohn Forte typedef struct mstcount_s {
63fcf3ce44SJohn Forte 	int count;
64fcf3ce44SJohn Forte } mstcount_t;
65fcf3ce44SJohn Forte typedef struct shdvol_s {
66fcf3ce44SJohn Forte 	char master[ DSW_NAMELEN ];
67fcf3ce44SJohn Forte } shdvol_t;
68fcf3ce44SJohn Forte typedef struct grptag_s {
69fcf3ce44SJohn Forte 	char ctag[ DSW_NAMELEN ];
70fcf3ce44SJohn Forte } grptag_t;
71fcf3ce44SJohn Forte hash_node_t **volhash = NULL;
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte #define	DSW_TEXT_DOMAIN	"II"
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte #include <dlfcn.h>
76fcf3ce44SJohn Forte #define	RDC_LIB "/usr/lib/librdc.so.1"
77fcf3ce44SJohn Forte static int (*self_check)(char *);
78fcf3ce44SJohn Forte 
79fcf3ce44SJohn Forte /*
80fcf3ce44SJohn Forte  * Support for the special cluster tag "local" to be used with -C in a
81fcf3ce44SJohn Forte  * cluster for local volumes.
82fcf3ce44SJohn Forte  */
83fcf3ce44SJohn Forte #define	II_LOCAL_TAG	"local"
84fcf3ce44SJohn Forte 
85fcf3ce44SJohn Forte #define	II_NOT_CLUSTER	1
86fcf3ce44SJohn Forte #define	II_CLUSTER	2
87fcf3ce44SJohn Forte #define	II_CLUSTER_LCL	3
88fcf3ce44SJohn Forte 
89fcf3ce44SJohn Forte static char *cfg_cluster_tag = NULL;
90fcf3ce44SJohn Forte static CFGFILE *cfg = NULL;
91fcf3ce44SJohn Forte 
92fcf3ce44SJohn Forte void sigterm(int sig);
93fcf3ce44SJohn Forte 
94fcf3ce44SJohn Forte #define	SD_BIT_CLR(bmap, bit)		(bmap &= ~(1 << bit))
95fcf3ce44SJohn Forte #define	SD_BIT_ISSET(bmap, bit)		((bmap & (1 << bit)) != 0)
96fcf3ce44SJohn Forte 
97fcf3ce44SJohn Forte #define	MAX_LINE_SIZE 256	/* maximum characters per line in config file */
98fcf3ce44SJohn Forte #define	MAX_GROUPS 1024		/* maximum number of groups to support */
99fcf3ce44SJohn Forte #define	MAX_CLUSTERS 1024	/* maximum number of resource groups */
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte unsigned long	bm_size;		/* size in bytes of bitmap */
102fcf3ce44SJohn Forte unsigned long	bm_actual;		/* original number of bits in bitmap */
103fcf3ce44SJohn Forte int	debug = 0;
104fcf3ce44SJohn Forte 
105fcf3ce44SJohn Forte int	dsw_fd;
106fcf3ce44SJohn Forte 
107fcf3ce44SJohn Forte #define	LD_II		0x00000001
108fcf3ce44SJohn Forte #define	LD_DSVOLS	0x00000002
109fcf3ce44SJohn Forte #define	LD_SVOLS	0x00000004
110fcf3ce44SJohn Forte #define	LD_SHADOWS	0x00000008
111fcf3ce44SJohn Forte 
112fcf3ce44SJohn Forte static int reload_vols = 0;
113fcf3ce44SJohn Forte static int config_locked = 0;
114fcf3ce44SJohn Forte static int last_lock;
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte /*
117fcf3ce44SJohn Forte  * names for do_copy() flags.
118fcf3ce44SJohn Forte  */
119fcf3ce44SJohn Forte 
120fcf3ce44SJohn Forte enum	copy_update {Copy = 0, Update};
121fcf3ce44SJohn Forte enum	copy_direction {ToShadow = 0, ToMaster};
122fcf3ce44SJohn Forte enum	copy_wait {WaitForStart = 0, WaitForEnd};
123fcf3ce44SJohn Forte 
124fcf3ce44SJohn Forte char	*cmdnam;
125fcf3ce44SJohn Forte 
126fcf3ce44SJohn Forte unsigned char	*allocate_bitmap(char *);
127fcf3ce44SJohn Forte void		usage(char *);
128fcf3ce44SJohn Forte void		enable(char *, char *, char *, char *);
129fcf3ce44SJohn Forte int		disable(char *);
130fcf3ce44SJohn Forte void		bitmap_op(char *, int, int, int, int);
131fcf3ce44SJohn Forte void		print_status(dsw_config_t *, int);
132fcf3ce44SJohn Forte int		abort_copy(char *);
133fcf3ce44SJohn Forte int		reset(char *);
134fcf3ce44SJohn Forte int		overflow(char *);
135fcf3ce44SJohn Forte void		iiversion(void);
136fcf3ce44SJohn Forte int		wait_for_copy(char *);
137fcf3ce44SJohn Forte int		export(char *);
138fcf3ce44SJohn Forte void		list_volumes(void);
139fcf3ce44SJohn Forte void		dsw_error(char *, spcs_s_info_t *);
140fcf3ce44SJohn Forte void		InitEnv();
141fcf3ce44SJohn Forte static void	check_dg_is_local(char *dgname);
142fcf3ce44SJohn Forte static int	check_resource_group(char *volume);
143fcf3ce44SJohn Forte static int	check_diskgroup(char *path, char *result);
144fcf3ce44SJohn Forte static int	check_cluster();
145fcf3ce44SJohn Forte static void	unload_ii_vols();
146fcf3ce44SJohn Forte static void	load_ii_vols(CFGFILE *);
147fcf3ce44SJohn Forte static int	perform_autosv();
148fcf3ce44SJohn Forte static int	is_exported(char *);
149fcf3ce44SJohn Forte static void	conform_name(char **);
150fcf3ce44SJohn Forte static void	do_attach(dsw_config_t *);
151fcf3ce44SJohn Forte static int	ii_lock(CFGFILE *, int);
152fcf3ce44SJohn Forte static void	verify_groupname(char *grp, int testDash);
153fcf3ce44SJohn Forte 
154fcf3ce44SJohn Forte void	dsw_list_clusters(char *);
155fcf3ce44SJohn Forte void	dsw_enable(int, char **);
156fcf3ce44SJohn Forte void	dsw_disable(int, char **);
157fcf3ce44SJohn Forte void	dsw_copy_to_shadow(int, char **);
158fcf3ce44SJohn Forte void	dsw_update_shadow(int, char **);
159fcf3ce44SJohn Forte void	dsw_copy_to_master(int, char **);
160fcf3ce44SJohn Forte void	dsw_update_master(int, char **);
161fcf3ce44SJohn Forte void	dsw_abort_copy(int, char **);
162fcf3ce44SJohn Forte void	dsw_display_status(int, char **);
163fcf3ce44SJohn Forte void	dsw_display_bitmap(int, char **);
164fcf3ce44SJohn Forte void	dsw_reset(int, char **);
165fcf3ce44SJohn Forte void	dsw_overflow(int, char **);
166fcf3ce44SJohn Forte void	dsw_version(int, char **);
167fcf3ce44SJohn Forte void	dsw_wait(int, char **);
168fcf3ce44SJohn Forte void	dsw_list_volumes(int, char **);
169fcf3ce44SJohn Forte void	dsw_list_group_volumes();
170fcf3ce44SJohn Forte void	dsw_export(int, char **);
171fcf3ce44SJohn Forte void	dsw_import(int, char **);
172fcf3ce44SJohn Forte void	dsw_join(int, char **);
173fcf3ce44SJohn Forte void	dsw_attach(int, char **);
174fcf3ce44SJohn Forte void	dsw_detach(int, char **);
175fcf3ce44SJohn Forte void	dsw_params(int, char **);
176fcf3ce44SJohn Forte void	dsw_olist(int, char **);
177fcf3ce44SJohn Forte void	dsw_ostat(int, char **);
178fcf3ce44SJohn Forte void	dsw_move_2_group(int, char **);
179fcf3ce44SJohn Forte void	dsw_list_groups();
180fcf3ce44SJohn Forte void	check_iishadow(char *);
181fcf3ce44SJohn Forte 
182fcf3ce44SJohn Forte extern char *optarg;
183fcf3ce44SJohn Forte extern int optind, opterr, optopt;
184fcf3ce44SJohn Forte 
185fcf3ce44SJohn Forte int	Aflg;
186fcf3ce44SJohn Forte int	Cflg;
187fcf3ce44SJohn Forte int	CLflg;
188fcf3ce44SJohn Forte int	Dflg;
189fcf3ce44SJohn Forte int	Eflg;
190fcf3ce44SJohn Forte int	Iflg;
191fcf3ce44SJohn Forte int	Jflg;
192fcf3ce44SJohn Forte int	Lflg;
193fcf3ce44SJohn Forte int	Oflg;
194fcf3ce44SJohn Forte int	Pflg;
195fcf3ce44SJohn Forte int	Qflg;
196fcf3ce44SJohn Forte int	Rflg;
197fcf3ce44SJohn Forte int	aflg;
198fcf3ce44SJohn Forte int	bflg;
199fcf3ce44SJohn Forte int	cflg;
200fcf3ce44SJohn Forte int	dflg;
201fcf3ce44SJohn Forte int	eflg;
202fcf3ce44SJohn Forte int	fflg;
203fcf3ce44SJohn Forte int	gflg;
204fcf3ce44SJohn Forte int	gLflg;
205fcf3ce44SJohn Forte int	hflg;
206fcf3ce44SJohn Forte int	iflg;
207fcf3ce44SJohn Forte int	lflg;
208fcf3ce44SJohn Forte int	mflg;
209fcf3ce44SJohn Forte int	nflg;
210fcf3ce44SJohn Forte int	pflg;
211fcf3ce44SJohn Forte int	uflg;
212fcf3ce44SJohn Forte int	vflg;
213fcf3ce44SJohn Forte int	wflg;
214fcf3ce44SJohn Forte 
215fcf3ce44SJohn Forte int	errflg;
216fcf3ce44SJohn Forte #ifdef DEBUG
217fcf3ce44SJohn Forte const char single_opts[] =
218fcf3ce44SJohn Forte 	"a:b:c:d:e:f:g:hilmnpu:vw:A:C:D:E:I:J:LO:PQ:R:";
219fcf3ce44SJohn Forte #else
220fcf3ce44SJohn Forte /* no b or f flags */
221fcf3ce44SJohn Forte const char single_opts[] = "a:c:d:e:g:hilmnpu:vw:A:C:D:E:I:J:LO:PQ:R:";
222fcf3ce44SJohn Forte #endif
223fcf3ce44SJohn Forte const char group_opts[] = "ac:de:ilmnpu:wA:C:DELPR";
224fcf3ce44SJohn Forte const char *opt_list = single_opts;
225fcf3ce44SJohn Forte 
226fcf3ce44SJohn Forte char	buf[CFG_MAX_BUF];
227fcf3ce44SJohn Forte char	key[CFG_MAX_KEY];
228fcf3ce44SJohn Forte char	last_overflow[DSW_NAMELEN];
229fcf3ce44SJohn Forte int	setnumber;
230fcf3ce44SJohn Forte char	*group_name;
231fcf3ce44SJohn Forte char	**group_volumes;
232fcf3ce44SJohn Forte enum copy_direction direction;
233fcf3ce44SJohn Forte char	*param_delay, *param_unit;
234fcf3ce44SJohn Forte char	*overflow_file;
235fcf3ce44SJohn Forte 
236fcf3ce44SJohn Forte #ifdef lint
237fcf3ce44SJohn Forte int
238fcf3ce44SJohn Forte iiadm_lintmain(int argc, char *argv[])
239fcf3ce44SJohn Forte #else
240fcf3ce44SJohn Forte int
241fcf3ce44SJohn Forte main(int argc, char *argv[])
242fcf3ce44SJohn Forte #endif
243fcf3ce44SJohn Forte {
244fcf3ce44SJohn Forte 	int c;
245fcf3ce44SJohn Forte 	int actions = 0;
246fcf3ce44SJohn Forte 	int ac;
247fcf3ce44SJohn Forte 	char *av[1024];
248fcf3ce44SJohn Forte 
249fcf3ce44SJohn Forte 	InitEnv();
250fcf3ce44SJohn Forte 
251570de38fSSurya Prakki 	(void) memset(av, 0, sizeof (av));
252fcf3ce44SJohn Forte 	cmdnam = argv[0];
253fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, opt_list)) != EOF)
254fcf3ce44SJohn Forte 		switch (c) {
255fcf3ce44SJohn Forte 		case 'c':
256fcf3ce44SJohn Forte 			cflg++;
257fcf3ce44SJohn Forte 			actions++;
258fcf3ce44SJohn Forte 			if (strcmp(optarg, "m") == 0) {
259fcf3ce44SJohn Forte 				av[0] = "copy_to_master";
260fcf3ce44SJohn Forte 				direction = ToMaster;
261fcf3ce44SJohn Forte 			} else if (strcmp(optarg, "s") == 0) {
262fcf3ce44SJohn Forte 				av[0] = "copy_to_shadow";
263fcf3ce44SJohn Forte 				direction = ToShadow;
264fcf3ce44SJohn Forte 			} else {
265fcf3ce44SJohn Forte 				errflg ++;
266fcf3ce44SJohn Forte 				usage(gettext(
267fcf3ce44SJohn Forte 					"must specify m or s with -c"));
268fcf3ce44SJohn Forte 			}
269fcf3ce44SJohn Forte 			ac = 2;
270fcf3ce44SJohn Forte 			break;
271fcf3ce44SJohn Forte 		case 'd':
272fcf3ce44SJohn Forte 			dflg++;
273fcf3ce44SJohn Forte 			actions++;
274fcf3ce44SJohn Forte 			av[0] = "disable";
275fcf3ce44SJohn Forte 			av[1] = optarg;
276fcf3ce44SJohn Forte 			ac = 2;
277fcf3ce44SJohn Forte 			break;
278fcf3ce44SJohn Forte 		case 'e':
279fcf3ce44SJohn Forte 			eflg++;
280fcf3ce44SJohn Forte 			actions++;
281fcf3ce44SJohn Forte 			av[0] = "enable";
282fcf3ce44SJohn Forte 			if (strcmp(optarg, "ind") == 0)
283fcf3ce44SJohn Forte 				av[4] = "independent";
284fcf3ce44SJohn Forte 			else if (strcmp(optarg, "dep") == 0)
285fcf3ce44SJohn Forte 				av[4] = "dependent";
286fcf3ce44SJohn Forte 			else {
287fcf3ce44SJohn Forte 				errflg ++;
288fcf3ce44SJohn Forte 				usage(gettext(
289fcf3ce44SJohn Forte 					"must specify ind or dep with -e"));
290fcf3ce44SJohn Forte 			}
291fcf3ce44SJohn Forte 			ac = 1;
292fcf3ce44SJohn Forte 			break;
293fcf3ce44SJohn Forte 		case 'g':
294fcf3ce44SJohn Forte 			gflg++;
295fcf3ce44SJohn Forte 			opt_list = group_opts;
296fcf3ce44SJohn Forte 			group_name = optarg;
297fcf3ce44SJohn Forte 			if (group_name && *group_name == '-') {
298fcf3ce44SJohn Forte 				gLflg = (strcmp("-L", group_name) == 0);
299fcf3ce44SJohn Forte 				if (gLflg)
300fcf3ce44SJohn Forte 					actions++;
301fcf3ce44SJohn Forte 			}
302fcf3ce44SJohn Forte 			verify_groupname(group_name, !gLflg);
303fcf3ce44SJohn Forte 			break;
304fcf3ce44SJohn Forte 		case 'h':
305fcf3ce44SJohn Forte 			hflg++;
306fcf3ce44SJohn Forte 			actions++;
307fcf3ce44SJohn Forte 			break;
308fcf3ce44SJohn Forte 		case 'u':
309fcf3ce44SJohn Forte 			uflg++;
310fcf3ce44SJohn Forte 			actions++;
311fcf3ce44SJohn Forte 			if (strcmp(optarg, "m") == 0) {
312fcf3ce44SJohn Forte 				av[0] = "update_master";
313fcf3ce44SJohn Forte 				direction = ToMaster;
314fcf3ce44SJohn Forte 			} else if (strcmp(optarg, "s") == 0) {
315fcf3ce44SJohn Forte 				av[0] = "update_shadow";
316fcf3ce44SJohn Forte 				direction = ToShadow;
317fcf3ce44SJohn Forte 			} else {
318fcf3ce44SJohn Forte 				errflg ++;
319fcf3ce44SJohn Forte 				usage(gettext(
320fcf3ce44SJohn Forte 					"must specify m or s with -u"));
321fcf3ce44SJohn Forte 			}
322fcf3ce44SJohn Forte 			ac = 2;
323fcf3ce44SJohn Forte 			break;
324fcf3ce44SJohn Forte 		case 'i':
325fcf3ce44SJohn Forte 			iflg++;
326fcf3ce44SJohn Forte 			actions++;
327fcf3ce44SJohn Forte 			av[0] = "display_status";
328fcf3ce44SJohn Forte 			break;
329fcf3ce44SJohn Forte 		case 'l':
330fcf3ce44SJohn Forte 			lflg++;
331fcf3ce44SJohn Forte 			actions++;
332fcf3ce44SJohn Forte 			av[0] = "list_config";
333fcf3ce44SJohn Forte 			ac = 1;
334fcf3ce44SJohn Forte 			break;
335fcf3ce44SJohn Forte 		case 'm':
336fcf3ce44SJohn Forte 			mflg++;
337fcf3ce44SJohn Forte 			actions++;
338fcf3ce44SJohn Forte 			av[0] = "move_to_group";
339fcf3ce44SJohn Forte 			ac = 1;
340fcf3ce44SJohn Forte 			break;
341fcf3ce44SJohn Forte 		case 'n':
342fcf3ce44SJohn Forte 			nflg++;
343fcf3ce44SJohn Forte 			break;
344fcf3ce44SJohn Forte 		case 'p':
345fcf3ce44SJohn Forte 			pflg++;
346fcf3ce44SJohn Forte 			break;
347fcf3ce44SJohn Forte 		case 'b':
348fcf3ce44SJohn Forte 			bflg++;
349fcf3ce44SJohn Forte 			actions++;
350fcf3ce44SJohn Forte 			av[0] = "display_bitmap";
351fcf3ce44SJohn Forte 			av[1] = optarg;
352fcf3ce44SJohn Forte 			ac = 2;
353fcf3ce44SJohn Forte 			break;
354fcf3ce44SJohn Forte 		case 'a':
355fcf3ce44SJohn Forte 			aflg++;
356fcf3ce44SJohn Forte 			actions++;
357fcf3ce44SJohn Forte 			av[0] = "abort_copy";
358fcf3ce44SJohn Forte 			av[1] = optarg;
359fcf3ce44SJohn Forte 			ac = 2;
360fcf3ce44SJohn Forte 			break;
361fcf3ce44SJohn Forte 		case 'v':
362fcf3ce44SJohn Forte 			vflg++;
363fcf3ce44SJohn Forte 			actions++;
364fcf3ce44SJohn Forte 			av[1] = "version";
365fcf3ce44SJohn Forte 			ac = 1;
366fcf3ce44SJohn Forte 			break;
367fcf3ce44SJohn Forte 		case 'w':
368fcf3ce44SJohn Forte 			wflg++;
369fcf3ce44SJohn Forte 			actions++;
370fcf3ce44SJohn Forte 			av[0] = "wait";
371fcf3ce44SJohn Forte 			av[1] = optarg;
372fcf3ce44SJohn Forte 			ac = 2;
373fcf3ce44SJohn Forte 			break;
374fcf3ce44SJohn Forte 		case 'A':
375fcf3ce44SJohn Forte 			Aflg++;
376fcf3ce44SJohn Forte 			actions++;
377fcf3ce44SJohn Forte 			av[0] = "attach";
378fcf3ce44SJohn Forte 			av[1] = optarg;
379fcf3ce44SJohn Forte 			ac = 2;
380fcf3ce44SJohn Forte 			break;
381fcf3ce44SJohn Forte 		case 'C':
382fcf3ce44SJohn Forte 			Cflg++;
383fcf3ce44SJohn Forte 			cfg_cluster_tag = optarg;
384fcf3ce44SJohn Forte 			if (cfg_cluster_tag && *cfg_cluster_tag == '-') {
385fcf3ce44SJohn Forte 				CLflg = (strcmp("-L", cfg_cluster_tag) == 0);
386fcf3ce44SJohn Forte 				if (CLflg)
387fcf3ce44SJohn Forte 					actions++;
388fcf3ce44SJohn Forte 			}
389fcf3ce44SJohn Forte 			break;
390fcf3ce44SJohn Forte 		case 'D':
391fcf3ce44SJohn Forte 			Dflg++;
392fcf3ce44SJohn Forte 			actions++;
393fcf3ce44SJohn Forte 			av[0] = "detach";
394fcf3ce44SJohn Forte 			av[1] = optarg;
395fcf3ce44SJohn Forte 			ac = 2;
396fcf3ce44SJohn Forte 			break;
397fcf3ce44SJohn Forte 		case 'O':
398fcf3ce44SJohn Forte 			Oflg++;
399fcf3ce44SJohn Forte 			actions++;
400fcf3ce44SJohn Forte 			av[0] = "overflow";
401fcf3ce44SJohn Forte 			av[1] = optarg;
402fcf3ce44SJohn Forte 			ac = 2;
403fcf3ce44SJohn Forte 			break;
404fcf3ce44SJohn Forte 		case 'R':
405fcf3ce44SJohn Forte 			Rflg++;
406fcf3ce44SJohn Forte 			actions++;
407fcf3ce44SJohn Forte 			av[0] = "reset";
408fcf3ce44SJohn Forte 			av[1] = optarg;
409fcf3ce44SJohn Forte 			ac = 2;
410fcf3ce44SJohn Forte 			break;
411fcf3ce44SJohn Forte 		case 'E':
412fcf3ce44SJohn Forte 			Eflg++;
413fcf3ce44SJohn Forte 			actions++;
414fcf3ce44SJohn Forte 			av[0] = "export";
415fcf3ce44SJohn Forte 			av[1] = optarg;
416fcf3ce44SJohn Forte 			ac = 2;
417fcf3ce44SJohn Forte 			break;
418fcf3ce44SJohn Forte 		case 'I':
419fcf3ce44SJohn Forte 			Iflg++;
420fcf3ce44SJohn Forte 			actions++;
421fcf3ce44SJohn Forte 			av[0] = "import";
422fcf3ce44SJohn Forte 			av[1] = optarg;
423fcf3ce44SJohn Forte 			ac = 2;
424fcf3ce44SJohn Forte 			break;
425fcf3ce44SJohn Forte 		case 'J':
426fcf3ce44SJohn Forte 			Jflg++;
427fcf3ce44SJohn Forte 			actions++;
428fcf3ce44SJohn Forte 			av[0] = "join";
429fcf3ce44SJohn Forte 			av[1] = optarg;
430fcf3ce44SJohn Forte 			ac = 2;
431fcf3ce44SJohn Forte 			break;
432fcf3ce44SJohn Forte 		case 'P':
433fcf3ce44SJohn Forte 			Pflg++;
434fcf3ce44SJohn Forte 			actions++;
435fcf3ce44SJohn Forte 			av[0] = "parameter";
436fcf3ce44SJohn Forte 			ac = 1;
437fcf3ce44SJohn Forte 			break;
438fcf3ce44SJohn Forte 		case 'L':
439fcf3ce44SJohn Forte 			Lflg++;
440fcf3ce44SJohn Forte 			actions++;
441fcf3ce44SJohn Forte 			/* If -g group -L, force error */
442fcf3ce44SJohn Forte 			if (group_name) actions++;
443fcf3ce44SJohn Forte 			av[0] = "LIST";
444fcf3ce44SJohn Forte 			ac = 1;
445fcf3ce44SJohn Forte 			break;
446fcf3ce44SJohn Forte 		case 'Q':
447fcf3ce44SJohn Forte 			Qflg++;
448fcf3ce44SJohn Forte 			actions++;
449fcf3ce44SJohn Forte 			av[0] = "query";
450fcf3ce44SJohn Forte 			av[1] = optarg;
451fcf3ce44SJohn Forte 			ac = 2;
452fcf3ce44SJohn Forte 			break;
453fcf3ce44SJohn Forte 		case '?':
454fcf3ce44SJohn Forte 			errflg++;
455fcf3ce44SJohn Forte 			break;
456fcf3ce44SJohn Forte 		}
457fcf3ce44SJohn Forte 	if (hflg) {
458fcf3ce44SJohn Forte 		usage(NULL);
459fcf3ce44SJohn Forte 		exit(0);
460fcf3ce44SJohn Forte 		}
461fcf3ce44SJohn Forte 
462fcf3ce44SJohn Forte 	if (errflg)
463fcf3ce44SJohn Forte 		usage(gettext("unrecognized argument"));
464fcf3ce44SJohn Forte 	switch (actions) {
465fcf3ce44SJohn Forte 		case 0:
466fcf3ce44SJohn Forte 			if (argc > 1)
467fcf3ce44SJohn Forte 				usage(gettext("must specify an action flag"));
468fcf3ce44SJohn Forte 
469fcf3ce44SJohn Forte 			/* default behavior is to list configuration */
470fcf3ce44SJohn Forte 			lflg++; av[0] = "list_config"; ac = 1;
471fcf3ce44SJohn Forte 			break;
472fcf3ce44SJohn Forte 		case 1:
473fcf3ce44SJohn Forte 			break;
474fcf3ce44SJohn Forte 		default:
475fcf3ce44SJohn Forte 			usage(gettext("too many action flags"));
476fcf3ce44SJohn Forte 			break;
477fcf3ce44SJohn Forte 	}
478fcf3ce44SJohn Forte 
479fcf3ce44SJohn Forte 	if (gflg && (Iflg || Jflg || Oflg || Qflg))
480fcf3ce44SJohn Forte 		usage(gettext("can't use a group with this option"));
481fcf3ce44SJohn Forte 	if (!gflg && (mflg))
482fcf3ce44SJohn Forte 		usage(gettext("must use a group with this option"));
483fcf3ce44SJohn Forte 
484fcf3ce44SJohn Forte 	/*
485fcf3ce44SJohn Forte 	 * Open configuration file.
486fcf3ce44SJohn Forte 	 */
487fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
488fcf3ce44SJohn Forte 		perror("unable to access configuration");
489fcf3ce44SJohn Forte 		exit(2);
490fcf3ce44SJohn Forte 	}
491fcf3ce44SJohn Forte 
492fcf3ce44SJohn Forte 	/*
493fcf3ce44SJohn Forte 	 * Set write locking (CFG_WRLOCK) for:
494fcf3ce44SJohn Forte 	 *	iiadm -e (enable)
495fcf3ce44SJohn Forte 	 * 	iiadm -d (disable)
496fcf3ce44SJohn Forte 	 *	iiadm -A (attach overflow)
497fcf3ce44SJohn Forte 	 *	iiadm -D (detach overflow)
498fcf3ce44SJohn Forte 	 *	iiadm -g grp -m volume (move volume into group)
499fcf3ce44SJohn Forte 	 *	iiadm -E (export shadow [needs to update dsvol section])
500fcf3ce44SJohn Forte 	 *	iiadm -I (import shadow [ditto])
501fcf3ce44SJohn Forte 	 *	iiadm -J (join shadow [ditto])
502fcf3ce44SJohn Forte 	 * read locking (CFG_RDLOCK) for all other commands
503fcf3ce44SJohn Forte 	 */
504fcf3ce44SJohn Forte 	last_lock = (eflg || dflg || mflg || Aflg || Dflg || Eflg || Iflg ||
505fcf3ce44SJohn Forte 	    Jflg)? CFG_WRLOCK : CFG_RDLOCK;
506fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, last_lock)) {
507fcf3ce44SJohn Forte 		perror("unable to lock configuration");
508fcf3ce44SJohn Forte 		exit(2);
509fcf3ce44SJohn Forte 	}
510fcf3ce44SJohn Forte 	config_locked = 1;
511fcf3ce44SJohn Forte 
512fcf3ce44SJohn Forte 	/*
513fcf3ce44SJohn Forte 	 * If we are in a cluster, set or derive a valid disk group
514fcf3ce44SJohn Forte 	 */
515fcf3ce44SJohn Forte 	switch (check_cluster()) {
516fcf3ce44SJohn Forte 	case II_CLUSTER:
517fcf3ce44SJohn Forte 		/*
518fcf3ce44SJohn Forte 		 * If in a Sun Cluster, can't Import an II shadow
519fcf3ce44SJohn Forte 		 * Must be done as -C local
520fcf3ce44SJohn Forte 		 */
521fcf3ce44SJohn Forte 		if (Iflg)
522fcf3ce44SJohn Forte 			dsw_error(gettext(
523fcf3ce44SJohn Forte 				"-I (import) only allowed as -C local"), NULL);
524fcf3ce44SJohn Forte 		/*FALLTHRU*/
525fcf3ce44SJohn Forte 	case II_CLUSTER_LCL:
526fcf3ce44SJohn Forte 		/*
527fcf3ce44SJohn Forte 		 * If a cluster tag was specified or derived, set it
528fcf3ce44SJohn Forte 		 */
529fcf3ce44SJohn Forte 		if (CLflg) {
530fcf3ce44SJohn Forte 			dsw_list_clusters(argv[optind]);
531fcf3ce44SJohn Forte 			cfg_close(cfg);
532fcf3ce44SJohn Forte 			exit(0);
533fcf3ce44SJohn Forte 		} else {
534fcf3ce44SJohn Forte 			cfg_resource(cfg, cfg_cluster_tag);
535fcf3ce44SJohn Forte 		}
536fcf3ce44SJohn Forte 		break;
537fcf3ce44SJohn Forte 	case II_NOT_CLUSTER:
538fcf3ce44SJohn Forte 		if (cfg_cluster_tag != NULL)
539fcf3ce44SJohn Forte 			dsw_error(gettext(
540fcf3ce44SJohn Forte 			    "-C is valid only in a Sun Cluster"), NULL);
541fcf3ce44SJohn Forte 		break;
542fcf3ce44SJohn Forte 	default:
543fcf3ce44SJohn Forte 		dsw_error(gettext(
544fcf3ce44SJohn Forte 		    "Unexpected return from check_cluster()"), NULL);
545fcf3ce44SJohn Forte 	}
546fcf3ce44SJohn Forte 
547fcf3ce44SJohn Forte 	/* preload the ii config */
548fcf3ce44SJohn Forte 	load_ii_vols(cfg);
549fcf3ce44SJohn Forte 	reload_vols |= LD_II;
550fcf3ce44SJohn Forte 
551fcf3ce44SJohn Forte 	if (eflg) {
552fcf3ce44SJohn Forte 		if (argc - optind != 3)
553fcf3ce44SJohn Forte 			usage(gettext("must specify 3 volumes with -e"));
554fcf3ce44SJohn Forte 		av[1] = argv[optind++];
555fcf3ce44SJohn Forte 		av[2] = argv[optind++];
556fcf3ce44SJohn Forte 		av[3] = argv[optind++];
557fcf3ce44SJohn Forte 		ac = 5;
558fcf3ce44SJohn Forte 		dsw_enable(ac, av);
559fcf3ce44SJohn Forte 	} else if (dflg) {
560fcf3ce44SJohn Forte 		dsw_disable(ac, av);
561fcf3ce44SJohn Forte 	} else if (uflg) {
562fcf3ce44SJohn Forte 		if (argv[optind] == NULL && group_name == NULL)
563fcf3ce44SJohn Forte 			usage(gettext("must specify volume with -u"));
564fcf3ce44SJohn Forte 		for (c = 1; argv[optind] != NULL; optind++)
565fcf3ce44SJohn Forte 			av[c++] = argv[optind];
566fcf3ce44SJohn Forte 		av[c] = NULL;
567fcf3ce44SJohn Forte 
568fcf3ce44SJohn Forte 		if (direction == ToMaster)
569fcf3ce44SJohn Forte 			dsw_update_master(ac, av);
570fcf3ce44SJohn Forte 		else
571fcf3ce44SJohn Forte 			dsw_update_shadow(ac, av);
572fcf3ce44SJohn Forte 	} else if (iflg) {
573fcf3ce44SJohn Forte 		if (argv[optind]) {
574fcf3ce44SJohn Forte 			av[1] = argv[optind];
575fcf3ce44SJohn Forte 			ac = 2;
576fcf3ce44SJohn Forte 		} else
577fcf3ce44SJohn Forte 			ac = 1;
578fcf3ce44SJohn Forte 		dsw_display_status(ac, av);
579fcf3ce44SJohn Forte 	} else if (bflg) {
580fcf3ce44SJohn Forte 		dsw_display_bitmap(ac, av);
581fcf3ce44SJohn Forte 	} else if (cflg) {
582fcf3ce44SJohn Forte 		if (argv[optind] == NULL && group_name == NULL)
583fcf3ce44SJohn Forte 			usage(gettext("must specify volume with -c"));
584fcf3ce44SJohn Forte 		for (c = 1; argv[optind] != NULL; optind++)
585fcf3ce44SJohn Forte 			av[c++] = argv[optind];
586fcf3ce44SJohn Forte 		av[c] = NULL;
587fcf3ce44SJohn Forte 
588fcf3ce44SJohn Forte 		if (direction == ToMaster)
589fcf3ce44SJohn Forte 			dsw_copy_to_master(ac, av);
590fcf3ce44SJohn Forte 		else
591fcf3ce44SJohn Forte 			dsw_copy_to_shadow(ac, av);
592fcf3ce44SJohn Forte 	} else if (aflg) {
593fcf3ce44SJohn Forte 		dsw_abort_copy(ac, av);
594fcf3ce44SJohn Forte 	} else if (Eflg) {
595fcf3ce44SJohn Forte 		dsw_export(ac, av);
596fcf3ce44SJohn Forte 	} else if (Iflg) {
597fcf3ce44SJohn Forte 		if (argc - optind != 1)
598fcf3ce44SJohn Forte 			usage(gettext("must specify 2 volumes with -I"));
599fcf3ce44SJohn Forte 		av[2] = argv[optind++];
600fcf3ce44SJohn Forte 		ac = 3;
601fcf3ce44SJohn Forte 		dsw_import(ac, av);
602fcf3ce44SJohn Forte 	} else if (Aflg) {
603fcf3ce44SJohn Forte 		if (group_name) {
604fcf3ce44SJohn Forte 			if (argc - optind != 0)
605fcf3ce44SJohn Forte 				usage(gettext("must specify overflow volume " \
606fcf3ce44SJohn Forte 				"when using groups with -A"));
607fcf3ce44SJohn Forte 			ac = 2;
608fcf3ce44SJohn Forte 		} else {
609fcf3ce44SJohn Forte 			if (argc - optind != 1)
610fcf3ce44SJohn Forte 				usage(gettext("specify 2 volumes with -A"));
611fcf3ce44SJohn Forte 			ac = 3;
612fcf3ce44SJohn Forte 			av[2] = argv[optind++];
613fcf3ce44SJohn Forte 		}
614fcf3ce44SJohn Forte 		dsw_attach(ac, av);
615fcf3ce44SJohn Forte 	} else if (Dflg) {
616fcf3ce44SJohn Forte 		dsw_detach(ac, av);
617fcf3ce44SJohn Forte 	} else if (Jflg) {
618fcf3ce44SJohn Forte 		if (argc - optind != 1)
619fcf3ce44SJohn Forte 			usage(gettext("must specify 2 volumes with -J"));
620fcf3ce44SJohn Forte 		av[2] = argv[optind++];
621fcf3ce44SJohn Forte 		ac = 3;
622fcf3ce44SJohn Forte 		dsw_join(ac, av);
623fcf3ce44SJohn Forte 	} else if (Pflg) {
624fcf3ce44SJohn Forte 		if (argc - optind == ((group_name) ? 0 : 1)) {
625fcf3ce44SJohn Forte 			av[1] = argv[optind++];
626fcf3ce44SJohn Forte 			ac = (group_name) ? 0 : 2;
627fcf3ce44SJohn Forte 		} else if (argc - optind == ((group_name) ? 2 : 3)) {
628fcf3ce44SJohn Forte 			av[1] = argv[optind++];
629fcf3ce44SJohn Forte 			av[2] = argv[optind++];
630fcf3ce44SJohn Forte 			av[3] = argv[optind++];
631fcf3ce44SJohn Forte 			ac = (group_name) ? 2 : 4;
632fcf3ce44SJohn Forte 		} else
633fcf3ce44SJohn Forte 			usage(gettext(
634fcf3ce44SJohn Forte 				"must specify delay, unit and shadow with -P"));
635fcf3ce44SJohn Forte 		dsw_params(ac, av);
636fcf3ce44SJohn Forte 	} else if (Oflg) {
637fcf3ce44SJohn Forte 		dsw_overflow(ac, av);
638fcf3ce44SJohn Forte 	} else if (Rflg) {
639fcf3ce44SJohn Forte 		dsw_reset(ac, av);
640fcf3ce44SJohn Forte 	} else if (vflg) {
641fcf3ce44SJohn Forte 		dsw_version(ac, av);
642fcf3ce44SJohn Forte 	} else if (wflg) {
643fcf3ce44SJohn Forte 		dsw_wait(ac, av);
644fcf3ce44SJohn Forte 	} else if (lflg) {
645fcf3ce44SJohn Forte 		if ((gflg) && (!group_name))
646fcf3ce44SJohn Forte 			dsw_list_group_volumes();
647fcf3ce44SJohn Forte 		else
648fcf3ce44SJohn Forte 			dsw_list_volumes(ac, av);
649fcf3ce44SJohn Forte 	} else if (Lflg) {
650fcf3ce44SJohn Forte 		dsw_olist(ac, av);
651fcf3ce44SJohn Forte 	} else if (gLflg) {
652fcf3ce44SJohn Forte 		dsw_list_groups();
653fcf3ce44SJohn Forte 	} else if (Qflg) {
654fcf3ce44SJohn Forte 		dsw_ostat(ac, av);
655fcf3ce44SJohn Forte 	} else if (mflg) {
656fcf3ce44SJohn Forte 		if (argc - optind < 1)
657fcf3ce44SJohn Forte 			usage(gettext("must specify one or more volumes"));
658fcf3ce44SJohn Forte 		for (c = 1; argv[optind] != NULL; optind++)
659fcf3ce44SJohn Forte 			av[c++] = argv[optind];
660fcf3ce44SJohn Forte 		av[c] = NULL;
661fcf3ce44SJohn Forte 		dsw_move_2_group(ac, av);
662fcf3ce44SJohn Forte 	}
663fcf3ce44SJohn Forte 	if (cfg)
664fcf3ce44SJohn Forte 		cfg_close(cfg);
665fcf3ce44SJohn Forte 
666fcf3ce44SJohn Forte 	exit(0);
667fcf3ce44SJohn Forte 	return (0);
668fcf3ce44SJohn Forte }
669fcf3ce44SJohn Forte 
670fcf3ce44SJohn Forte static int
671fcf3ce44SJohn Forte ii_lock(CFGFILE *cfg, int locktype)
672fcf3ce44SJohn Forte {
673fcf3ce44SJohn Forte 	last_lock = locktype;
674fcf3ce44SJohn Forte 	return (cfg_lock(cfg, locktype));
675fcf3ce44SJohn Forte }
676fcf3ce44SJohn Forte 
677fcf3ce44SJohn Forte static int
678fcf3ce44SJohn Forte do_ioctl(int fd, int cmd, void *arg)
679fcf3ce44SJohn Forte {
680fcf3ce44SJohn Forte 	int unlocked = 0;
681fcf3ce44SJohn Forte 	int rc;
682fcf3ce44SJohn Forte 	int save_errno;
683fcf3ce44SJohn Forte 
684fcf3ce44SJohn Forte 	if (config_locked) {
685fcf3ce44SJohn Forte 		switch (cmd) {
686fcf3ce44SJohn Forte 		case DSWIOC_ENABLE:
687fcf3ce44SJohn Forte 		case DSWIOC_RESUME:
688fcf3ce44SJohn Forte 		case DSWIOC_SUSPEND:
689fcf3ce44SJohn Forte 		case DSWIOC_COPY:
690fcf3ce44SJohn Forte 		case DSWIOC_BITMAP:
691fcf3ce44SJohn Forte 		case DSWIOC_DISABLE:
692fcf3ce44SJohn Forte 		case DSWIOC_SHUTDOWN:
693fcf3ce44SJohn Forte 		case DSWIOC_ABORT:
694fcf3ce44SJohn Forte 		case DSWIOC_RESET:
695fcf3ce44SJohn Forte 		case DSWIOC_OFFLINE:
696fcf3ce44SJohn Forte 		case DSWIOC_WAIT:
697fcf3ce44SJohn Forte 		case DSWIOC_ACOPY:
698fcf3ce44SJohn Forte 		case DSWIOC_EXPORT:
699fcf3ce44SJohn Forte 		case DSWIOC_IMPORT:
700fcf3ce44SJohn Forte 		case DSWIOC_JOIN:
701fcf3ce44SJohn Forte 		case DSWIOC_COPYP:
702fcf3ce44SJohn Forte 		case DSWIOC_OATTACH:
703fcf3ce44SJohn Forte 		case DSWIOC_ODETACH:
704fcf3ce44SJohn Forte 		case DSWIOC_SBITSSET:
705fcf3ce44SJohn Forte 		case DSWIOC_CBITSSET:
706fcf3ce44SJohn Forte 		case DSWIOC_SEGMENT:
707fcf3ce44SJohn Forte 		case DSWIOC_MOVEGRP:
708fcf3ce44SJohn Forte 		case DSWIOC_CHANGETAG:
709fcf3ce44SJohn Forte 			cfg_unlock(cfg);
710fcf3ce44SJohn Forte 			unlocked = 1;
711fcf3ce44SJohn Forte 			break;
712fcf3ce44SJohn Forte 
713fcf3ce44SJohn Forte 		case DSWIOC_STAT:
714fcf3ce44SJohn Forte 		case DSWIOC_VERSION:
715fcf3ce44SJohn Forte 		case DSWIOC_LIST:
716fcf3ce44SJohn Forte 		case DSWIOC_OCREAT:
717fcf3ce44SJohn Forte 		case DSWIOC_OLIST:
718fcf3ce44SJohn Forte 		case DSWIOC_OSTAT:
719fcf3ce44SJohn Forte 		case DSWIOC_OSTAT2:
720fcf3ce44SJohn Forte 		case DSWIOC_LISTLEN:
721fcf3ce44SJohn Forte 		case DSWIOC_OLISTLEN:
722fcf3ce44SJohn Forte 		case DSWIOC_CLIST:
723fcf3ce44SJohn Forte 		case DSWIOC_GLIST:
724fcf3ce44SJohn Forte 			break;
725fcf3ce44SJohn Forte 
726fcf3ce44SJohn Forte 		default:
727570de38fSSurya Prakki 			(void) fprintf(stderr,
728fcf3ce44SJohn Forte 			    "cfg locking needs to be set for %08x\n", cmd);
729fcf3ce44SJohn Forte 			exit(1);
730fcf3ce44SJohn Forte 			break;
731fcf3ce44SJohn Forte 		}
732fcf3ce44SJohn Forte 	}
733fcf3ce44SJohn Forte 	if (unlocked) {
734fcf3ce44SJohn Forte 		/* unload vol hashes */
735fcf3ce44SJohn Forte 		if (reload_vols & LD_II)
736fcf3ce44SJohn Forte 			unload_ii_vols();
737fcf3ce44SJohn Forte 		if (reload_vols & LD_SHADOWS)
738fcf3ce44SJohn Forte 			cfg_unload_shadows();
739fcf3ce44SJohn Forte 		if (reload_vols & LD_DSVOLS)
740fcf3ce44SJohn Forte 			cfg_unload_dsvols();
741fcf3ce44SJohn Forte 		if (reload_vols & LD_SVOLS)
742fcf3ce44SJohn Forte 			cfg_unload_svols();
743fcf3ce44SJohn Forte 	}
744fcf3ce44SJohn Forte 	rc = ioctl(fd, cmd, arg);
745fcf3ce44SJohn Forte 	save_errno = errno;
746fcf3ce44SJohn Forte 	if (config_locked && unlocked) {
747570de38fSSurya Prakki 		(void) cfg_lock(cfg, last_lock);
748fcf3ce44SJohn Forte 	}
749fcf3ce44SJohn Forte 	if (unlocked) {
750fcf3ce44SJohn Forte 		/* reload vol hashes */
751fcf3ce44SJohn Forte 		if (reload_vols & LD_SVOLS)
752570de38fSSurya Prakki 			(void) cfg_load_svols(cfg);
753fcf3ce44SJohn Forte 		if (reload_vols & LD_DSVOLS)
754570de38fSSurya Prakki 			(void) cfg_load_dsvols(cfg);
755fcf3ce44SJohn Forte 		if (reload_vols & LD_SHADOWS)
756570de38fSSurya Prakki 			(void) cfg_load_shadows(cfg);
757fcf3ce44SJohn Forte 		if (reload_vols & LD_II)
758fcf3ce44SJohn Forte 			load_ii_vols(cfg);
759fcf3ce44SJohn Forte 	}
760fcf3ce44SJohn Forte 
761fcf3ce44SJohn Forte 	errno = save_errno;
762fcf3ce44SJohn Forte 	return (rc);
763fcf3ce44SJohn Forte }
764fcf3ce44SJohn Forte 
765fcf3ce44SJohn Forte static int
766fcf3ce44SJohn Forte get_dsw_config(int setno, dsw_config_t *parms)
767fcf3ce44SJohn Forte {
768fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
769fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
770fcf3ce44SJohn Forte 
771fcf3ce44SJohn Forte 	bzero(parms, sizeof (dsw_config_t));
772fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.master", setno);
773fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, parms->master_vol, DSW_NAMELEN) < 0)
774fcf3ce44SJohn Forte 		return (-1);
775fcf3ce44SJohn Forte 
776fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.shadow", setno);
777fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, parms->shadow_vol, DSW_NAMELEN);
778fcf3ce44SJohn Forte 
779fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.bitmap", setno);
780fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, parms->bitmap_vol, DSW_NAMELEN);
781fcf3ce44SJohn Forte 
782fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.mode", setno);
783fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, buf, sizeof (buf));
784fcf3ce44SJohn Forte 	if (strcmp(buf, "I") == 0)
785fcf3ce44SJohn Forte 		parms->flag |= DSW_GOLDEN;
786fcf3ce44SJohn Forte 
787fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.overflow", setno);
788fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, last_overflow, DSW_NAMELEN);
789fcf3ce44SJohn Forte 
790fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.group", setno);
791fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, parms->group_name, DSW_NAMELEN);
792fcf3ce44SJohn Forte 
793fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "ii.set%d.cnode", setno);
794fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, parms->cluster_tag, DSW_NAMELEN);
795fcf3ce44SJohn Forte 	return (0);
796fcf3ce44SJohn Forte }
797fcf3ce44SJohn Forte 
798fcf3ce44SJohn Forte static int
799fcf3ce44SJohn Forte find_next_cf_line(char *volume, int next)
800fcf3ce44SJohn Forte {
801fcf3ce44SJohn Forte 	dsw_config_t cf_line;
802fcf3ce44SJohn Forte 
803fcf3ce44SJohn Forte 	for (setnumber = next; get_dsw_config(setnumber, &cf_line) == 0;
804fcf3ce44SJohn Forte 	    setnumber++) {
805fcf3ce44SJohn Forte 		if (strncmp(volume, cf_line.master_vol, DSW_NAMELEN) == 0 ||
806fcf3ce44SJohn Forte 		    strncmp(volume, cf_line.shadow_vol, DSW_NAMELEN) == 0 ||
807fcf3ce44SJohn Forte 		    strncmp(volume, cf_line.bitmap_vol, DSW_NAMELEN) == 0)
808fcf3ce44SJohn Forte 			return (1);
809fcf3ce44SJohn Forte 	}
810fcf3ce44SJohn Forte 	return (0);
811fcf3ce44SJohn Forte }
812fcf3ce44SJohn Forte int
813fcf3ce44SJohn Forte find_any_cf_line(char *volume)
814fcf3ce44SJohn Forte {
815fcf3ce44SJohn Forte 	return (find_next_cf_line(volume, 1));
816fcf3ce44SJohn Forte }
817fcf3ce44SJohn Forte 
818fcf3ce44SJohn Forte static int
819fcf3ce44SJohn Forte find_next_shadow_line(char *volume, int next)
820fcf3ce44SJohn Forte {
821fcf3ce44SJohn Forte 	dsw_config_t cf_line;
822fcf3ce44SJohn Forte 
823fcf3ce44SJohn Forte 	for (setnumber = next; get_dsw_config(setnumber, &cf_line) == 0;
824fcf3ce44SJohn Forte 	    setnumber++) {
825fcf3ce44SJohn Forte 		if (strncmp(volume, cf_line.shadow_vol, DSW_NAMELEN) == 0)
826fcf3ce44SJohn Forte 			return (1);
827fcf3ce44SJohn Forte 	}
828fcf3ce44SJohn Forte 	return (0);
829fcf3ce44SJohn Forte }
830fcf3ce44SJohn Forte int
831fcf3ce44SJohn Forte find_shadow_line(char *volume)
832fcf3ce44SJohn Forte {
833fcf3ce44SJohn Forte 	return (find_next_shadow_line(volume, 1));
834fcf3ce44SJohn Forte }
835fcf3ce44SJohn Forte 
836fcf3ce44SJohn Forte /*
837fcf3ce44SJohn Forte  * this function is designed to be called once, subsequent calls won't
838fcf3ce44SJohn Forte  * free memory allocated by earlier invocations.
839fcf3ce44SJohn Forte  */
840fcf3ce44SJohn Forte char *
841fcf3ce44SJohn Forte get_overflow_list()
842fcf3ce44SJohn Forte {
843fcf3ce44SJohn Forte 	dsw_aioctl_t *acopy_args;
844fcf3ce44SJohn Forte 	int rc, num;
845fcf3ce44SJohn Forte 
846fcf3ce44SJohn Forte 	num = do_ioctl(dsw_fd, DSWIOC_OLISTLEN, NULL);
847fcf3ce44SJohn Forte 	if (num < 0)
848fcf3ce44SJohn Forte 		dsw_error(gettext("Can't get overflow list length"), NULL);
849fcf3ce44SJohn Forte 
850fcf3ce44SJohn Forte 	acopy_args = malloc(sizeof (dsw_aioctl_t) + num * DSW_NAMELEN);
851fcf3ce44SJohn Forte 	if (acopy_args == NULL)
852fcf3ce44SJohn Forte 		dsw_error(gettext("Can't get memory for list enquiry"), NULL);
853fcf3ce44SJohn Forte 
854fcf3ce44SJohn Forte 	acopy_args->count = num;
855fcf3ce44SJohn Forte 	acopy_args->flags = 0;
856fcf3ce44SJohn Forte 	acopy_args->status = spcs_s_ucreate();
857fcf3ce44SJohn Forte 
858fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_OLIST, acopy_args);
859fcf3ce44SJohn Forte 	if (rc == -1)
860fcf3ce44SJohn Forte 		dsw_error(gettext("Overflow list access failure"),
861fcf3ce44SJohn Forte 		    &acopy_args->status);
862fcf3ce44SJohn Forte 	else
863fcf3ce44SJohn Forte 		acopy_args->shadow_vol[DSW_NAMELEN*acopy_args->count] = NULL;
864fcf3ce44SJohn Forte 
865fcf3ce44SJohn Forte 	return (acopy_args->shadow_vol);
866fcf3ce44SJohn Forte }
867fcf3ce44SJohn Forte 
868fcf3ce44SJohn Forte /*
869fcf3ce44SJohn Forte  * this function is designed to be called once, subsequent calls won't
870fcf3ce44SJohn Forte  * free memory allocated by earlier invocations.
871fcf3ce44SJohn Forte  */
872fcf3ce44SJohn Forte 
873fcf3ce44SJohn Forte int
874fcf3ce44SJohn Forte find_group_members(char *group)
875fcf3ce44SJohn Forte {
876fcf3ce44SJohn Forte 	int nmembers = 0;
877fcf3ce44SJohn Forte 	int vector_len = 0;
878fcf3ce44SJohn Forte 
879fcf3ce44SJohn Forte 	group_volumes = NULL;
880fcf3ce44SJohn Forte 	for (setnumber = 1; /*CSTYLED*/; setnumber++) {
881fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "ii.set%d.group", setnumber);
882*ea3068a7SRichard Lowe 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
883fcf3ce44SJohn Forte 			break;
884fcf3ce44SJohn Forte 
885fcf3ce44SJohn Forte 		if (strcmp(group, buf))
886fcf3ce44SJohn Forte 			continue;
887fcf3ce44SJohn Forte 
888fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "ii.set%d.shadow",
889fcf3ce44SJohn Forte 		    setnumber);
890*ea3068a7SRichard Lowe 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
891fcf3ce44SJohn Forte 			break;
892fcf3ce44SJohn Forte 
893fcf3ce44SJohn Forte 		if (nmembers >= vector_len) {
894fcf3ce44SJohn Forte 			vector_len += 10;
895fcf3ce44SJohn Forte 			group_volumes = realloc(group_volumes, (1+vector_len) *
896fcf3ce44SJohn Forte 			    sizeof (char *));
897fcf3ce44SJohn Forte 		}
898fcf3ce44SJohn Forte 		group_volumes[nmembers] = strdup(buf);
899fcf3ce44SJohn Forte 		nmembers++;
900fcf3ce44SJohn Forte 	}
901fcf3ce44SJohn Forte 	if (group_volumes)
902fcf3ce44SJohn Forte 		group_volumes[nmembers] = NULL;	/* terminate list */
903fcf3ce44SJohn Forte 	return (nmembers);
904fcf3ce44SJohn Forte }
905fcf3ce44SJohn Forte 
906fcf3ce44SJohn Forte static int
907fcf3ce44SJohn Forte find_next_matching_cf_line(
908fcf3ce44SJohn Forte 	char *volume, dsw_config_t *conf, dsw_ioctl_t *io, int next)
909fcf3ce44SJohn Forte {
910fcf3ce44SJohn Forte 	dsw_config_t config;
911fcf3ce44SJohn Forte 
912fcf3ce44SJohn Forte 	if (!find_next_cf_line(volume, next)) {
913fcf3ce44SJohn Forte 		return (0);
914fcf3ce44SJohn Forte 	}
915fcf3ce44SJohn Forte 
916fcf3ce44SJohn Forte 	if (conf == NULL)
917fcf3ce44SJohn Forte 		conf = &config;
918fcf3ce44SJohn Forte 	(void) get_dsw_config(setnumber, conf);
919fcf3ce44SJohn Forte 	if (io) {
920*ea3068a7SRichard Lowe 		(void) strlcpy(io->shadow_vol, conf->shadow_vol, DSW_NAMELEN);
921fcf3ce44SJohn Forte 	}
922fcf3ce44SJohn Forte 	return (1);
923fcf3ce44SJohn Forte }
924fcf3ce44SJohn Forte 
925fcf3ce44SJohn Forte int
926fcf3ce44SJohn Forte find_matching_cf_line(char *volume, dsw_config_t *conf, dsw_ioctl_t *io)
927fcf3ce44SJohn Forte {
928fcf3ce44SJohn Forte 	return (find_next_matching_cf_line(volume, conf, io, 1));
929fcf3ce44SJohn Forte }
930fcf3ce44SJohn Forte 
931fcf3ce44SJohn Forte int
932fcf3ce44SJohn Forte find_shadow_config(char *volume, dsw_config_t *conf, dsw_ioctl_t *io)
933fcf3ce44SJohn Forte {
934fcf3ce44SJohn Forte 	dsw_config_t *c, cf;
935fcf3ce44SJohn Forte 
936fcf3ce44SJohn Forte 	if (io) {
937fcf3ce44SJohn Forte 		bzero(io, sizeof (dsw_ioctl_t));
938fcf3ce44SJohn Forte 	}
939fcf3ce44SJohn Forte 	c = conf ? conf : &cf;
940fcf3ce44SJohn Forte 	setnumber = 1;
941fcf3ce44SJohn Forte 	/* perform action for each line of the stored config file */
942fcf3ce44SJohn Forte 	for ((void) snprintf(key, sizeof (key), "ii.set%d.shadow", setnumber);
943fcf3ce44SJohn Forte 	    cfg_get_cstring(cfg, key, c->shadow_vol, DSW_NAMELEN) >= 0;
944fcf3ce44SJohn Forte 	    (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
945fcf3ce44SJohn Forte 	    ++setnumber)) {
946fcf3ce44SJohn Forte 		if (strncmp(volume, c->shadow_vol, DSW_NAMELEN) == 0) {
947fcf3ce44SJohn Forte 			(void) get_dsw_config(setnumber, c);
948fcf3ce44SJohn Forte 
949fcf3ce44SJohn Forte 			if (check_resource_group(c->bitmap_vol)) {
950fcf3ce44SJohn Forte 				setnumber = 0;
951fcf3ce44SJohn Forte 				continue;
952fcf3ce44SJohn Forte 			}
953fcf3ce44SJohn Forte 
954fcf3ce44SJohn Forte 			switch (check_cluster()) {
955fcf3ce44SJohn Forte 			case II_CLUSTER:
956fcf3ce44SJohn Forte 				if ((cfg_cluster_tag) &&
957fcf3ce44SJohn Forte 				    (strcmp(cfg_cluster_tag, c->cluster_tag)))
958fcf3ce44SJohn Forte 					continue;
959fcf3ce44SJohn Forte 				break;
960fcf3ce44SJohn Forte 			case II_CLUSTER_LCL:
961fcf3ce44SJohn Forte 				if (strlen(c->cluster_tag))
962fcf3ce44SJohn Forte 					continue;
963fcf3ce44SJohn Forte 				break;
964fcf3ce44SJohn Forte 			}
965fcf3ce44SJohn Forte 
966fcf3ce44SJohn Forte 			if (io) {
967*ea3068a7SRichard Lowe 				(void) strlcpy(io->shadow_vol, c->shadow_vol,
968fcf3ce44SJohn Forte 				    DSW_NAMELEN);
969fcf3ce44SJohn Forte 			}
970fcf3ce44SJohn Forte 			return (1);
971fcf3ce44SJohn Forte 		}
972fcf3ce44SJohn Forte 	}
973fcf3ce44SJohn Forte 	return (0);
974fcf3ce44SJohn Forte }
975fcf3ce44SJohn Forte 
976fcf3ce44SJohn Forte void
977fcf3ce44SJohn Forte add_cfg_entry(dsw_config_t *parms)
978fcf3ce44SJohn Forte {
979fcf3ce44SJohn Forte 	/* insert the well-known fields first */
980fcf3ce44SJohn Forte 	(void) snprintf(buf, sizeof (buf), "%s %s %s %s",
981fcf3ce44SJohn Forte 	    parms->master_vol, parms->shadow_vol, parms->bitmap_vol,
982fcf3ce44SJohn Forte 	    (parms->flag & DSW_GOLDEN) ? "I" : "D");
983fcf3ce44SJohn Forte 
984fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, "ii", buf, strlen(buf)) >=  0) {
985fcf3ce44SJohn Forte 		/* if we have a group name, add it */
986fcf3ce44SJohn Forte 		if (group_name) {
987fcf3ce44SJohn Forte 			if (find_any_cf_line(parms->shadow_vol)) {
988fcf3ce44SJohn Forte 				(void) sprintf(buf, "ii.set%d.group",
989fcf3ce44SJohn Forte 				    setnumber);
990fcf3ce44SJohn Forte 				if (cfg_put_cstring(cfg, buf,
991fcf3ce44SJohn Forte 				    group_name, strlen(group_name)) < 0)
992fcf3ce44SJohn Forte 					perror("cfg_put_cstring");
993fcf3ce44SJohn Forte 			}
994fcf3ce44SJohn Forte 			else
995fcf3ce44SJohn Forte 				perror("cfg_location");
996fcf3ce44SJohn Forte 		}
997fcf3ce44SJohn Forte 
998fcf3ce44SJohn Forte 		/* commit the record */
999fcf3ce44SJohn Forte 		(void) cfg_commit(cfg);
1000fcf3ce44SJohn Forte 	}
1001fcf3ce44SJohn Forte 	else
1002fcf3ce44SJohn Forte 		perror("cfg_put_string");
1003fcf3ce44SJohn Forte }
1004fcf3ce44SJohn Forte 
1005fcf3ce44SJohn Forte void
1006fcf3ce44SJohn Forte remove_iiset(int setno, char *shadow, int shd_exp)
1007fcf3ce44SJohn Forte {
1008fcf3ce44SJohn Forte 	mstcount_t *mdata;
1009fcf3ce44SJohn Forte 	shdvol_t *sdata;
1010fcf3ce44SJohn Forte 	char sn[CFG_MAX_BUF];
1011fcf3ce44SJohn Forte 
1012fcf3ce44SJohn Forte 	if (perform_autosv()) {
1013fcf3ce44SJohn Forte 		if (volhash) {
1014fcf3ce44SJohn Forte 			unload_ii_vols();
1015fcf3ce44SJohn Forte 		}
1016fcf3ce44SJohn Forte 		load_ii_vols(cfg);
1017fcf3ce44SJohn Forte 		if (cfg_load_dsvols(cfg) < 0 || cfg_load_svols(cfg) < 0) {
1018fcf3ce44SJohn Forte 			dsw_error(gettext("Unable to parse config file"), NULL);
1019fcf3ce44SJohn Forte 		}
1020fcf3ce44SJohn Forte 
1021fcf3ce44SJohn Forte 		sdata = (shdvol_t *)nsc_lookup(volhash, shadow);
1022fcf3ce44SJohn Forte 		if (sdata) {
1023fcf3ce44SJohn Forte 			/*
1024fcf3ce44SJohn Forte 			 * Handle the normal cases of disabling a set that is
1025fcf3ce44SJohn Forte 			 * not an imported shadow volume
1026fcf3ce44SJohn Forte 			 */
1027fcf3ce44SJohn Forte 			if (strcmp(sdata->master, II_IMPORTED_SHADOW)) {
1028fcf3ce44SJohn Forte 				/*
1029fcf3ce44SJohn Forte 				 * Handle multiple-shadows of single master
1030fcf3ce44SJohn Forte 				 */
1031fcf3ce44SJohn Forte 				mdata = (mstcount_t *)
1032fcf3ce44SJohn Forte 				    nsc_lookup(volhash, sdata->master);
1033fcf3ce44SJohn Forte 				if ((mdata) && (mdata->count == 1)) {
1034fcf3ce44SJohn Forte 					if (cfg_vol_disable(cfg, sdata->master,
1035fcf3ce44SJohn Forte 					    cfg_cluster_tag, "ii") < 0)
1036fcf3ce44SJohn Forte 						dsw_error(gettext(
1037*ea3068a7SRichard Lowe 						    "SV disable of master "
1038*ea3068a7SRichard Lowe 						    "failed"),
1039fcf3ce44SJohn Forte 						    NULL);
1040fcf3ce44SJohn Forte 				}
1041fcf3ce44SJohn Forte 			}
1042fcf3ce44SJohn Forte 
1043fcf3ce44SJohn Forte 			/*
1044fcf3ce44SJohn Forte 			 * Handle disk group name of different shadow
1045fcf3ce44SJohn Forte 			 */
1046fcf3ce44SJohn Forte 			if (shd_exp) {
1047fcf3ce44SJohn Forte 				/*
1048fcf3ce44SJohn Forte 				 * If shadow is exported, then do nothing
1049fcf3ce44SJohn Forte 				 */
1050fcf3ce44SJohn Forte 				/*EMPTY*/;
1051fcf3ce44SJohn Forte 			} else if (cfg_cluster_tag &&
1052fcf3ce44SJohn Forte 			    strcmp(cfg_cluster_tag, "") &&
1053fcf3ce44SJohn Forte 			    cfg_dgname(shadow, sn, sizeof (sn)) &&
1054fcf3ce44SJohn Forte 			    strlen(sn) &&
1055fcf3ce44SJohn Forte 			    strcmp(sn, cfg_cluster_tag)) {
1056fcf3ce44SJohn Forte 					/* reload disk group volumes */
1057fcf3ce44SJohn Forte 					cfg_resource(cfg, sn);
1058fcf3ce44SJohn Forte 					cfg_unload_dsvols();
1059fcf3ce44SJohn Forte 					cfg_unload_svols();
1060fcf3ce44SJohn Forte 					(void) cfg_load_dsvols(cfg);
1061fcf3ce44SJohn Forte 					(void) cfg_load_svols(cfg);
1062fcf3ce44SJohn Forte 					if (cfg_vol_disable(cfg, shadow, sn,
1063*ea3068a7SRichard Lowe 					    "ii") < 0) {
1064fcf3ce44SJohn Forte 						dsw_error(gettext(
1065*ea3068a7SRichard Lowe 						    "SV disable of shadow "
1066*ea3068a7SRichard Lowe 						    "failed"),
1067fcf3ce44SJohn Forte 						    NULL);
1068*ea3068a7SRichard Lowe 					}
1069fcf3ce44SJohn Forte 					cfg_resource(cfg, cfg_cluster_tag);
1070fcf3ce44SJohn Forte 			} else {
1071fcf3ce44SJohn Forte 				if (cfg_vol_disable(cfg, shadow,
1072fcf3ce44SJohn Forte 				    cfg_cluster_tag, "ii") < 0)
1073fcf3ce44SJohn Forte 					dsw_error(gettext(
1074fcf3ce44SJohn Forte 					    "SV disable of shadow failed"),
1075fcf3ce44SJohn Forte 					    NULL);
1076fcf3ce44SJohn Forte 			}
1077fcf3ce44SJohn Forte 		}
1078fcf3ce44SJohn Forte 		cfg_unload_svols();
1079fcf3ce44SJohn Forte 		cfg_unload_dsvols();
1080fcf3ce44SJohn Forte 		unload_ii_vols();
1081fcf3ce44SJohn Forte 		reload_vols &= ~(LD_SVOLS | LD_DSVOLS | LD_II);
1082fcf3ce44SJohn Forte 	}
1083fcf3ce44SJohn Forte 
1084fcf3ce44SJohn Forte 	(void) sprintf(key, "ii.set%d", setno);
1085fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
1086fcf3ce44SJohn Forte 		perror("cfg_put_cstring");
1087fcf3ce44SJohn Forte 	}
1088fcf3ce44SJohn Forte 	(void) cfg_commit(cfg);
1089fcf3ce44SJohn Forte }
1090fcf3ce44SJohn Forte 
1091fcf3ce44SJohn Forte /*
1092fcf3ce44SJohn Forte  * determine if we are running in a Sun Cluster Environment
1093fcf3ce44SJohn Forte  */
1094fcf3ce44SJohn Forte int
1095fcf3ce44SJohn Forte check_cluster()
1096fcf3ce44SJohn Forte {
1097fcf3ce44SJohn Forte 	static int is_cluster = -1;
1098fcf3ce44SJohn Forte 	int rc;
1099fcf3ce44SJohn Forte #ifdef DEBUG
1100fcf3ce44SJohn Forte 	char *cdebug = getenv("II_SET_CLUSTER");
1101fcf3ce44SJohn Forte #endif
1102fcf3ce44SJohn Forte 
1103fcf3ce44SJohn Forte 	/*
1104fcf3ce44SJohn Forte 	 * If this routine was previously called, just return results
1105fcf3ce44SJohn Forte 	 */
1106fcf3ce44SJohn Forte 	if (is_cluster != -1)
1107fcf3ce44SJohn Forte 		return (is_cluster);
1108fcf3ce44SJohn Forte 
1109fcf3ce44SJohn Forte 	/*
1110fcf3ce44SJohn Forte 	 * See if Sun Cluster was installed on this node
1111fcf3ce44SJohn Forte 	 */
1112fcf3ce44SJohn Forte #ifdef DEBUG
1113fcf3ce44SJohn Forte 	if (cdebug) rc = atoi(cdebug);
1114fcf3ce44SJohn Forte 	else
1115fcf3ce44SJohn Forte #endif
1116fcf3ce44SJohn Forte 	rc = cfg_iscluster();
1117fcf3ce44SJohn Forte 	if (rc > 0) {
1118fcf3ce44SJohn Forte 		/*
1119fcf3ce44SJohn Forte 		 * Determine if user specified -C local
1120fcf3ce44SJohn Forte 		 */
1121fcf3ce44SJohn Forte 		if ((cfg_cluster_tag == NULL) ||
1122fcf3ce44SJohn Forte 		    (strcmp(cfg_cluster_tag, II_LOCAL_TAG))) {
1123fcf3ce44SJohn Forte 			/*
1124fcf3ce44SJohn Forte 			 * We're in a Sun Cluster, and no "-C local"
1125fcf3ce44SJohn Forte 			 */
1126fcf3ce44SJohn Forte 			is_cluster = II_CLUSTER;
1127fcf3ce44SJohn Forte 		} else {
1128fcf3ce44SJohn Forte 			/*
1129fcf3ce44SJohn Forte 			 * We're in a Sun Cluster, but "-C local" was specified
1130fcf3ce44SJohn Forte 			 */
1131fcf3ce44SJohn Forte 			is_cluster = II_CLUSTER_LCL;
1132fcf3ce44SJohn Forte 			cfg_cluster_tag = "";
1133fcf3ce44SJohn Forte 		}
1134fcf3ce44SJohn Forte 		return (is_cluster);
1135fcf3ce44SJohn Forte 	} else if (rc == 0) {
1136fcf3ce44SJohn Forte 		/*
1137fcf3ce44SJohn Forte 		 * Not in a Sun Cluster
1138fcf3ce44SJohn Forte 		 */
1139fcf3ce44SJohn Forte 		is_cluster = II_NOT_CLUSTER;
1140fcf3ce44SJohn Forte 		return (is_cluster);
1141fcf3ce44SJohn Forte 	} else {
1142fcf3ce44SJohn Forte 		dsw_error(gettext("unable to ascertain environment"), NULL);
1143fcf3ce44SJohn Forte 		/*NOTREACHED*/
1144fcf3ce44SJohn Forte 	}
1145fcf3ce44SJohn Forte 
1146fcf3ce44SJohn Forte 	/* gcc */
1147fcf3ce44SJohn Forte 	return (is_cluster);
1148fcf3ce44SJohn Forte }
1149fcf3ce44SJohn Forte 
1150fcf3ce44SJohn Forte /*
1151fcf3ce44SJohn Forte  * Determine if we need to set a cfg_resource based on this volume
1152fcf3ce44SJohn Forte  */
1153fcf3ce44SJohn Forte static int
1154fcf3ce44SJohn Forte check_resource_group(char *volume)
1155fcf3ce44SJohn Forte {
1156fcf3ce44SJohn Forte 	char diskgroup[CFG_MAX_BUF];
1157fcf3ce44SJohn Forte 
1158fcf3ce44SJohn Forte 	/*
1159fcf3ce44SJohn Forte 	 * If we are in a cluster, attempt to derive a new resource group
1160fcf3ce44SJohn Forte 	 */
1161fcf3ce44SJohn Forte 
1162fcf3ce44SJohn Forte #ifdef DEBUG
1163fcf3ce44SJohn Forte 	if (getenv("II_SET_CLUSTER") || (check_cluster() == II_CLUSTER)) {
1164fcf3ce44SJohn Forte #else
1165fcf3ce44SJohn Forte 	if (check_cluster() == II_CLUSTER) {
1166fcf3ce44SJohn Forte #endif
1167fcf3ce44SJohn Forte 		if (check_diskgroup(volume, diskgroup)) {
1168fcf3ce44SJohn Forte 			if (cfg_cluster_tag == NULL) {
1169fcf3ce44SJohn Forte 				cfg_cluster_tag = strdup(diskgroup);
1170fcf3ce44SJohn Forte 				if (cfg_cluster_tag == NULL)
1171fcf3ce44SJohn Forte 					dsw_error(gettext(
1172fcf3ce44SJohn Forte 					"Memory allocation failure"), NULL);
1173fcf3ce44SJohn Forte 				cfg_resource(cfg, cfg_cluster_tag);
1174fcf3ce44SJohn Forte 				return (1);
1175fcf3ce44SJohn Forte 			} else {
1176fcf3ce44SJohn Forte 				/*
1177*ea3068a7SRichard Lowe 				 * Check dgname and cluster tag from -C are
1178*ea3068a7SRichard Lowe 				 * the same.
1179fcf3ce44SJohn Forte 				 */
1180fcf3ce44SJohn Forte 				if (strcmp(diskgroup, cfg_cluster_tag) != 0) {
1181fcf3ce44SJohn Forte 					char error_buffer[128];
1182*ea3068a7SRichard Lowe 					(void) snprintf(error_buffer,
1183*ea3068a7SRichard Lowe 					    sizeof (error_buffer),
1184*ea3068a7SRichard Lowe 					    gettext("-C (%s) does not match "
1185*ea3068a7SRichard Lowe 					    "disk group name (%s) for %s"),
1186*ea3068a7SRichard Lowe 					    cfg_cluster_tag, diskgroup, volume);
1187fcf3ce44SJohn Forte 					spcs_log("ii", NULL, error_buffer);
1188fcf3ce44SJohn Forte 					dsw_error(error_buffer, NULL);
1189fcf3ce44SJohn Forte 				}
1190fcf3ce44SJohn Forte 			}
1191fcf3ce44SJohn Forte 		} else if (cfg_cluster_tag == NULL)
1192fcf3ce44SJohn Forte 			dsw_error(gettext(
1193fcf3ce44SJohn Forte 			    "Point-in-Time Copy volumes, that are not "
1194fcf3ce44SJohn Forte 			    "in a device group which has been "
1195fcf3ce44SJohn Forte 			    "registered with SunCluster, "
1196fcf3ce44SJohn Forte 			    "require usage of \"-C\""), NULL);
1197fcf3ce44SJohn Forte 	}
1198fcf3ce44SJohn Forte 	return (0);
1199fcf3ce44SJohn Forte }
1200fcf3ce44SJohn Forte 
1201fcf3ce44SJohn Forte static void
1202fcf3ce44SJohn Forte check_dg_is_local(char *dgname)
1203fcf3ce44SJohn Forte {
1204fcf3ce44SJohn Forte 	char error_buffer[128];
1205fcf3ce44SJohn Forte 	char *othernode;
1206fcf3ce44SJohn Forte 	int rc;
1207fcf3ce44SJohn Forte 
1208fcf3ce44SJohn Forte 	/*
1209fcf3ce44SJohn Forte 	 * check where this disk service is mastered
1210fcf3ce44SJohn Forte 	 */
1211fcf3ce44SJohn Forte 	rc = cfg_dgname_islocal(dgname, &othernode);
1212fcf3ce44SJohn Forte 	if (rc < 0) {
1213fcf3ce44SJohn Forte 		(void) snprintf(error_buffer, sizeof (error_buffer),
1214fcf3ce44SJohn Forte 		    gettext("Unable to find disk service:%s"), dgname);
1215fcf3ce44SJohn Forte 		dsw_error(error_buffer, NULL);
1216fcf3ce44SJohn Forte 	} else if (rc == 0) {
1217fcf3ce44SJohn Forte 		(void) snprintf(error_buffer, sizeof (error_buffer),
1218fcf3ce44SJohn Forte 		    gettext("disk service, %s, is active on node \"%s\"\n"
1219fcf3ce44SJohn Forte 		    "Please re-issue the command on that node"), dgname,
1220fcf3ce44SJohn Forte 		    othernode);
1221fcf3ce44SJohn Forte 		dsw_error(error_buffer, NULL);
1222fcf3ce44SJohn Forte 	}
1223fcf3ce44SJohn Forte }
1224fcf3ce44SJohn Forte 
1225fcf3ce44SJohn Forte /*
1226fcf3ce44SJohn Forte  * Carry out cluster based checks for a specified volume, or just
1227fcf3ce44SJohn Forte  * global options.
1228fcf3ce44SJohn Forte  */
1229fcf3ce44SJohn Forte static int
1230fcf3ce44SJohn Forte check_diskgroup(char *path, char *result)
1231fcf3ce44SJohn Forte {
1232fcf3ce44SJohn Forte 	char dgname[CFG_MAX_BUF];
1233fcf3ce44SJohn Forte 	char error_buffer[128];
1234fcf3ce44SJohn Forte 
1235fcf3ce44SJohn Forte #ifdef DEBUG
1236fcf3ce44SJohn Forte 	char *override = getenv("II_CLUSTER_TAG");
1237fcf3ce44SJohn Forte 	if (override) {
1238570de38fSSurya Prakki 		(void) strcpy(result, override);
1239fcf3ce44SJohn Forte 		return (1);
1240fcf3ce44SJohn Forte 	}
1241fcf3ce44SJohn Forte #endif
1242fcf3ce44SJohn Forte 	/*
1243fcf3ce44SJohn Forte 	 * Check on path name, a returned NULL dgname is valid
1244fcf3ce44SJohn Forte 	 */
1245fcf3ce44SJohn Forte 	if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) {
1246fcf3ce44SJohn Forte 		(void) snprintf(error_buffer, sizeof (error_buffer), gettext(
1247fcf3ce44SJohn Forte 		    "unable to determine disk group name for %s"), path);
1248fcf3ce44SJohn Forte 		dsw_error(error_buffer, NULL);
1249fcf3ce44SJohn Forte 	}
1250fcf3ce44SJohn Forte 	if (strcmp(dgname, "") == 0)
1251fcf3ce44SJohn Forte 		return (0);
1252fcf3ce44SJohn Forte 
1253fcf3ce44SJohn Forte 	/*
1254fcf3ce44SJohn Forte 	 * See if disk group is local to this node
1255fcf3ce44SJohn Forte 	 */
1256fcf3ce44SJohn Forte 	check_dg_is_local(dgname);
1257fcf3ce44SJohn Forte 
1258fcf3ce44SJohn Forte 	/*
1259fcf3ce44SJohn Forte 	 * Copy dgname into result
1260fcf3ce44SJohn Forte 	 */
1261570de38fSSurya Prakki 	(void) strcpy(result, dgname);
1262fcf3ce44SJohn Forte 	return (1);
1263fcf3ce44SJohn Forte }
1264fcf3ce44SJohn Forte 
1265fcf3ce44SJohn Forte /*
1266fcf3ce44SJohn Forte  * sigterm (): traps specified signal , usually termination one
1267fcf3ce44SJohn Forte  */
1268fcf3ce44SJohn Forte void
1269fcf3ce44SJohn Forte sigterm(int sig)
1270fcf3ce44SJohn Forte {
1271fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("%s received signal %d"), cmdnam, sig);
1272fcf3ce44SJohn Forte 	exit(1);
1273fcf3ce44SJohn Forte }
1274fcf3ce44SJohn Forte 
1275fcf3ce44SJohn Forte /*
1276fcf3ce44SJohn Forte  * sigchild; reap child and collect status.
1277fcf3ce44SJohn Forte  */
1278fcf3ce44SJohn Forte 
1279fcf3ce44SJohn Forte volatile pid_t	dead_child;
1280fcf3ce44SJohn Forte int	dead_stat;
1281fcf3ce44SJohn Forte 
1282fcf3ce44SJohn Forte /*ARGSUSED*/
1283fcf3ce44SJohn Forte void
1284fcf3ce44SJohn Forte sigchild(int sig)
1285fcf3ce44SJohn Forte {
1286fcf3ce44SJohn Forte 	dead_child = wait(&dead_stat);
1287fcf3ce44SJohn Forte }
1288fcf3ce44SJohn Forte 
1289fcf3ce44SJohn Forte /*
1290fcf3ce44SJohn Forte  * InitEnv(): initializes environment
1291fcf3ce44SJohn Forte  */
1292fcf3ce44SJohn Forte void
1293fcf3ce44SJohn Forte InitEnv()
1294fcf3ce44SJohn Forte {
1295fcf3ce44SJohn Forte 	(void) setlocale(LC_ALL, "");
1296fcf3ce44SJohn Forte 	(void) textdomain(DSW_TEXT_DOMAIN);
1297fcf3ce44SJohn Forte 
1298fcf3ce44SJohn Forte #ifndef DEBUG
1299570de38fSSurya Prakki 	(void) sigset(SIGHUP, sigterm);
1300570de38fSSurya Prakki 	(void) sigset(SIGINT, sigterm);
1301570de38fSSurya Prakki 	(void) sigset(SIGQUIT, sigterm);
1302570de38fSSurya Prakki 	(void) sigset(SIGILL, sigterm);
1303570de38fSSurya Prakki 	(void) sigset(SIGEMT, sigterm);
1304570de38fSSurya Prakki 	(void) sigset(SIGABRT, sigterm);
1305570de38fSSurya Prakki 	(void) sigset(SIGFPE, sigterm);
1306570de38fSSurya Prakki 	(void) sigset(SIGBUS, sigterm);
1307570de38fSSurya Prakki 	(void) sigset(SIGSEGV, sigterm);
1308570de38fSSurya Prakki 	(void) sigset(SIGTERM, sigterm);
1309570de38fSSurya Prakki 	(void) sigset(SIGPWR, sigterm);
1310570de38fSSurya Prakki 	(void) sigset(SIGSTOP, sigterm);
1311570de38fSSurya Prakki 	(void) sigset(SIGTSTP, sigterm);
1312fcf3ce44SJohn Forte #endif
1313fcf3ce44SJohn Forte 
1314fcf3ce44SJohn Forte 	dsw_fd = open(DSWDEV, O_RDONLY);
1315fcf3ce44SJohn Forte 	if (dsw_fd < 0) {
1316fcf3ce44SJohn Forte 		perror(DSWDEV);
1317fcf3ce44SJohn Forte 		exit(1);
1318fcf3ce44SJohn Forte 	}
1319fcf3ce44SJohn Forte 
1320570de38fSSurya Prakki 	(void) setsid();
1321fcf3ce44SJohn Forte }
1322fcf3ce44SJohn Forte 
1323fcf3ce44SJohn Forte /*
1324fcf3ce44SJohn Forte  * print an error message, followed by decoded errno then exit.
1325fcf3ce44SJohn Forte  */
1326fcf3ce44SJohn Forte void
1327fcf3ce44SJohn Forte dsw_error(char *str, spcs_s_info_t *status)
1328fcf3ce44SJohn Forte {
1329fcf3ce44SJohn Forte 	char *sp;
1330fcf3ce44SJohn Forte 
1331fcf3ce44SJohn Forte 	(void) fprintf(stderr, "%s: %s:\n", cmdnam, str);
1332fcf3ce44SJohn Forte 	if (status == NULL) {
1333fcf3ce44SJohn Forte 		/* deflect ESRCH */
1334fcf3ce44SJohn Forte 		if (ESRCH == errno) {
1335fcf3ce44SJohn Forte 			sp = "Set/volume not found";
1336fcf3ce44SJohn Forte 		} else {
1337fcf3ce44SJohn Forte 			sp = strerror(errno);
1338fcf3ce44SJohn Forte 		}
1339fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n", sp ? sp : "");
1340fcf3ce44SJohn Forte 	} else {
1341fcf3ce44SJohn Forte 		spcs_s_report(*status, stderr);
1342fcf3ce44SJohn Forte 		spcs_s_ufree(status);
1343fcf3ce44SJohn Forte 	}
1344fcf3ce44SJohn Forte 	if (cfg)
1345fcf3ce44SJohn Forte 		cfg_close(cfg);
1346fcf3ce44SJohn Forte 	exit(2);
1347fcf3ce44SJohn Forte }
1348fcf3ce44SJohn Forte 
1349fcf3ce44SJohn Forte 
1350fcf3ce44SJohn Forte #undef size
1351fcf3ce44SJohn Forte 
1352fcf3ce44SJohn Forte void
1353fcf3ce44SJohn Forte free_bitmap(unsigned char *bitmap)
1354fcf3ce44SJohn Forte {
1355fcf3ce44SJohn Forte 	free(bitmap);
1356fcf3ce44SJohn Forte }
1357fcf3ce44SJohn Forte 
1358fcf3ce44SJohn Forte 
1359fcf3ce44SJohn Forte int
1360fcf3ce44SJohn Forte get_bitmap(master_volume, shd_bitmap, copy_bitmap, size)
1361fcf3ce44SJohn Forte 	char		*master_volume;
1362fcf3ce44SJohn Forte 	unsigned char	*shd_bitmap;
1363fcf3ce44SJohn Forte 	unsigned char	*copy_bitmap;
1364fcf3ce44SJohn Forte 	unsigned long	size;
1365fcf3ce44SJohn Forte {
1366fcf3ce44SJohn Forte 	dsw_bitmap_t parms;
1367fcf3ce44SJohn Forte 
1368*ea3068a7SRichard Lowe 	(void) strlcpy(parms.shadow_vol, master_volume, DSW_NAMELEN);
1369fcf3ce44SJohn Forte 	parms.shd_bitmap = shd_bitmap;
1370fcf3ce44SJohn Forte 	parms.shd_size = size;
1371fcf3ce44SJohn Forte 	parms.copy_bitmap = copy_bitmap;
1372fcf3ce44SJohn Forte 	parms.copy_size = size;
1373fcf3ce44SJohn Forte 
1374fcf3ce44SJohn Forte 	return (do_ioctl(dsw_fd, DSWIOC_BITMAP, &parms));
1375fcf3ce44SJohn Forte }
1376fcf3ce44SJohn Forte 
1377fcf3ce44SJohn Forte unsigned char *
1378fcf3ce44SJohn Forte allocate_bitmap(char *shadow_volume)
1379fcf3ce44SJohn Forte {
1380fcf3ce44SJohn Forte 	unsigned char	*shd_bitmap;
1381fcf3ce44SJohn Forte 	unsigned char	*copy_bitmap;
1382fcf3ce44SJohn Forte 	unsigned char	*p;
1383fcf3ce44SJohn Forte 	unsigned char	*q;
1384fcf3ce44SJohn Forte 	int		i;
1385fcf3ce44SJohn Forte 	dsw_stat_t	args;
1386fcf3ce44SJohn Forte 	int		stat_flags;
1387fcf3ce44SJohn Forte 
1388*ea3068a7SRichard Lowe 	(void) strlcpy(args.shadow_vol, shadow_volume, DSW_NAMELEN);
1389fcf3ce44SJohn Forte 
1390fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
1391fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1)
1392fcf3ce44SJohn Forte 		dsw_error(gettext("Stat failed"), &args.status);
1393fcf3ce44SJohn Forte 
1394fcf3ce44SJohn Forte 	stat_flags = args.stat;
1395fcf3ce44SJohn Forte 	if (stat_flags & DSW_BMPOFFLINE)
1396fcf3ce44SJohn Forte 		return (NULL);
1397fcf3ce44SJohn Forte 
1398fcf3ce44SJohn Forte 	bm_size = args.size;
1399fcf3ce44SJohn Forte 	bm_size = (bm_size + DSW_SIZE-1) / DSW_SIZE;
1400fcf3ce44SJohn Forte 	bm_actual = bm_size;
1401fcf3ce44SJohn Forte 	bm_size = (bm_size + DSW_BITS-1) / DSW_BITS;
1402fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
1403fcf3ce44SJohn Forte 
1404fcf3ce44SJohn Forte 	p = shd_bitmap = (unsigned char *) malloc(bm_size);
1405fcf3ce44SJohn Forte 	if (!shd_bitmap) {
1406fcf3ce44SJohn Forte 		perror(gettext("malloc bitmap"));
1407fcf3ce44SJohn Forte 		return (NULL);
1408fcf3ce44SJohn Forte 	}
1409fcf3ce44SJohn Forte 
1410fcf3ce44SJohn Forte 	q = copy_bitmap = (unsigned char *) malloc(bm_size);
1411fcf3ce44SJohn Forte 	if (!copy_bitmap) {
1412fcf3ce44SJohn Forte 		perror(gettext("malloc bitmap"));
1413fcf3ce44SJohn Forte 		free(shd_bitmap);
1414fcf3ce44SJohn Forte 		return (NULL);
1415fcf3ce44SJohn Forte 	}
1416fcf3ce44SJohn Forte 
1417570de38fSSurya Prakki 	(void) memset(shd_bitmap, 0, bm_size);
1418570de38fSSurya Prakki 	(void) memset(copy_bitmap, 0, bm_size);
1419fcf3ce44SJohn Forte 
1420fcf3ce44SJohn Forte 	if (get_bitmap(shadow_volume, shd_bitmap, copy_bitmap, bm_size) < 0) {
1421fcf3ce44SJohn Forte 		free(copy_bitmap);
1422fcf3ce44SJohn Forte 		free(shd_bitmap);
1423fcf3ce44SJohn Forte 		return (NULL);
1424fcf3ce44SJohn Forte 	}
1425fcf3ce44SJohn Forte 
1426fcf3ce44SJohn Forte 	/*
1427fcf3ce44SJohn Forte 	 * "or" the copy and shadow bitmaps together to return a composite
1428fcf3ce44SJohn Forte 	 * bitmap that contains the total set of differences between the
1429fcf3ce44SJohn Forte 	 * volumes.
1430fcf3ce44SJohn Forte 	 */
1431fcf3ce44SJohn Forte 	for (i = bm_size; i-- > 0; /*CSTYLED*/)
1432fcf3ce44SJohn Forte 		*p++ |= *q++;
1433fcf3ce44SJohn Forte 
1434fcf3ce44SJohn Forte 	free(copy_bitmap);
1435fcf3ce44SJohn Forte 
1436fcf3ce44SJohn Forte 	return (shd_bitmap);
1437fcf3ce44SJohn Forte }
1438fcf3ce44SJohn Forte 
1439fcf3ce44SJohn Forte /*
1440fcf3ce44SJohn Forte  * print usage message and exit.
1441fcf3ce44SJohn Forte  */
1442fcf3ce44SJohn Forte void
1443fcf3ce44SJohn Forte usage(char *why)
1444fcf3ce44SJohn Forte {
1445fcf3ce44SJohn Forte 	if (why) {
1446fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s: %s\n", cmdnam, why);
1447fcf3ce44SJohn Forte 
1448fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1449fcf3ce44SJohn Forte 		    gettext("\nBrief summary:"));
1450fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1451fcf3ce44SJohn Forte 		    gettext("\t-e {ind|dep} master_vol shadow_vol "
1452fcf3ce44SJohn Forte 		    "bitmap_vol"));
1453fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1454fcf3ce44SJohn Forte 		    gettext("\t-[cu {s|m}] volume_set"));
1455fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1456fcf3ce44SJohn Forte 		    gettext("\t-i all"));
1457fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1458fcf3ce44SJohn Forte 		    gettext("\t-[adDEilPRw] volume_set"));
1459fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1460fcf3ce44SJohn Forte 		    gettext("\t-g group_name [options]"));
1461fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1462fcf3ce44SJohn Forte 		    gettext("\t-C cluster_tag [options]"));
1463fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1464fcf3ce44SJohn Forte 		    gettext("\t-[hilLv]"));
1465fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1466fcf3ce44SJohn Forte 		    gettext("\t-[IJ] volume_set bitmap"));
1467fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1468fcf3ce44SJohn Forte 		    gettext("\t-A overflow_vol volume_set"));
1469fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1470fcf3ce44SJohn Forte 		    gettext("\t-[OQ] overflow_vol"));
1471fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n",
1472fcf3ce44SJohn Forte 		    gettext("\t-P {delay} {units} volume_set"));
1473fcf3ce44SJohn Forte 
1474fcf3ce44SJohn Forte 		/* assume we came here due to a user mistake */
1475fcf3ce44SJohn Forte 		exit(1);
1476fcf3ce44SJohn Forte 		/* NOTREACHED */
1477fcf3ce44SJohn Forte 	} else {
1478fcf3ce44SJohn Forte 
1479fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1480fcf3ce44SJohn Forte 		    gettext("Point-in-Time Copy Administrator CLI options"));
1481fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1482fcf3ce44SJohn Forte 		    gettext("Usage summary:"));
1483fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1484fcf3ce44SJohn Forte 		    gettext("\t-e ind m s b\tenable independent master shadow "
1485fcf3ce44SJohn Forte 		    "bitmap"));
1486fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1487fcf3ce44SJohn Forte 		    gettext("\t-e dep m s b\tenable dependent master shadow "
1488fcf3ce44SJohn Forte 		    "bitmap"));
1489fcf3ce44SJohn Forte 		if (check_cluster() == II_CLUSTER)
1490fcf3ce44SJohn Forte 			(void) fprintf(stdout, "%s\n",
1491fcf3ce44SJohn Forte 			    gettext("\t-ne ind m s b\tenable exportable master "
1492fcf3ce44SJohn Forte 			    "shadow bitmap"));
1493fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1494fcf3ce44SJohn Forte 		    gettext("\t-d v\t\tdisable volume"));
1495fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1496fcf3ce44SJohn Forte 		    gettext("\t-u s v\t\tupdate shadow volume"));
1497fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1498fcf3ce44SJohn Forte 		    gettext("\t-u m v\t\tupdate master volume"));
1499fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1500fcf3ce44SJohn Forte 		    gettext("\t-c s v\t\tcopy to shadow volume"));
1501fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1502fcf3ce44SJohn Forte 		    gettext("\t-c m v\t\tcopy to master volume"));
1503fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1504fcf3ce44SJohn Forte 		    gettext("\t-a v\t\tabort copy volume"));
1505fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1506fcf3ce44SJohn Forte 		    gettext("\t-w v\t\twait volume"));
1507fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1508fcf3ce44SJohn Forte 		    gettext("\t-i v\t\tdisplay volume status"));
1509fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1510fcf3ce44SJohn Forte 		    gettext("\t-i all\t\tdisplay all volume status"));
1511fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1512fcf3ce44SJohn Forte 		    gettext("\t-l\t\tlist all volumes"));
1513fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1514fcf3ce44SJohn Forte 		    gettext("\t-R v\t\treset volume"));
1515fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1516fcf3ce44SJohn Forte 		    gettext("\t-A o v\t\tattach overflow to volume"));
1517fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1518fcf3ce44SJohn Forte 		    gettext("\t-D v\t\tdetach overflow from volume"));
1519fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1520fcf3ce44SJohn Forte 		    gettext("\t-L\t\tlist all overflow volumes"));
1521fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1522fcf3ce44SJohn Forte 		    gettext("\t-O o\t\tinitialize overflow"));
1523fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1524fcf3ce44SJohn Forte 		    gettext("\t-Q o\t\tquery status of overflow"));
1525fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1526fcf3ce44SJohn Forte 		    gettext("\t-E v\t\texport shadow volume"));
1527fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1528fcf3ce44SJohn Forte 		    gettext("\t-I v b\t\timport volume bitmap"));
1529fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1530fcf3ce44SJohn Forte 		    gettext("\t-J v b\t\tjoin volume bitmap"));
1531fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1532fcf3ce44SJohn Forte 		    gettext("\t-P d u v\tset copy delay/units for volume"));
1533fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1534fcf3ce44SJohn Forte 		    gettext("\t-P v\t\tget copy delay/units for volume"));
1535fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1536fcf3ce44SJohn Forte 		    gettext("\t-C tag\t\tcluster resource tag"));
1537fcf3ce44SJohn Forte #ifdef DEBUG
1538fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1539fcf3ce44SJohn Forte 		    gettext("\t-b v\t\tdisplay bitmap volume"));
1540fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1541fcf3ce44SJohn Forte 		    gettext("\t-f f\t\tuse private configuration file"));
1542fcf3ce44SJohn Forte #endif
1543fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1544fcf3ce44SJohn Forte 		    gettext("\t-v\t\tprint software versions"));
1545fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1546fcf3ce44SJohn Forte 		    gettext("\t-n\t\tperform action without question"));
1547fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1548fcf3ce44SJohn Forte 		    gettext("\t-p [-c|-u] {m|s}"
1549fcf3ce44SJohn Forte 		    "enable PID locking on copy or update"));
1550fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1551fcf3ce44SJohn Forte 		    gettext("\t-p -w v\t\tdisable PID locking"));
1552fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1553fcf3ce44SJohn Forte 		    gettext("\t-h\t\tiiadm usage summary"));
1554fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1555fcf3ce44SJohn Forte 		    gettext("\nUsage summary for options that support "
1556fcf3ce44SJohn Forte 		    "grouping (-g g):"));
1557fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1558fcf3ce44SJohn Forte 		    gettext("\t-g g -e ind m s b group enable independent "
1559fcf3ce44SJohn Forte 		    "master shadow bitmap"));
1560fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1561fcf3ce44SJohn Forte 		    gettext("\t-g g -e dep m s b group enable dependent "
1562fcf3ce44SJohn Forte 		    "master shadow bitmap"));
1563fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1564fcf3ce44SJohn Forte 		    gettext("\t-g g -d\t\tdisable group"));
1565fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1566fcf3ce44SJohn Forte 		    gettext("\t-g g -u s\tupdate shadow for all volumes in "
1567fcf3ce44SJohn Forte 		    "group"));
1568fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1569fcf3ce44SJohn Forte 		    gettext("\t-g g -u m\tupdate master for all volumes in "
1570fcf3ce44SJohn Forte 		    "group"));
1571fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1572fcf3ce44SJohn Forte 		    gettext("\t-g g -c s\tcopy to shadow for all volumes in "
1573fcf3ce44SJohn Forte 		    "group"));
1574fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1575fcf3ce44SJohn Forte 		    gettext("\t-g g -c m\tcopy to master for all volumes in "
1576fcf3ce44SJohn Forte 		    "group"));
1577fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1578fcf3ce44SJohn Forte 		    gettext("\t-g g -a\t\tabort copy for all volumes in "
1579fcf3ce44SJohn Forte 		    "group"));
1580fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1581fcf3ce44SJohn Forte 		    gettext("\t-g g -w\t\twait for all volumes in group"));
1582fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1583fcf3ce44SJohn Forte 		    gettext("\t-g g -i\t\tdisplay status of all volumes in "
1584fcf3ce44SJohn Forte 		    "group"));
1585fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1586fcf3ce44SJohn Forte 		    gettext("\t-g g -l\t\tlist all volumes in group"));
1587fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1588fcf3ce44SJohn Forte 		    gettext("\t-g -L\t\tlist all groups"));
1589fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1590fcf3ce44SJohn Forte 		    gettext("\t-g g -m v v\tmove one or more volumes into "
1591fcf3ce44SJohn Forte 		    "group"));
1592fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1593fcf3ce44SJohn Forte 		    gettext("\t-g \"\" -m v\tremove volume from group"));
1594fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1595fcf3ce44SJohn Forte 		    gettext("\t-g g -R\t\treset all volumes in group"));
1596fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1597fcf3ce44SJohn Forte 		    gettext("\t-g g -A o\tattach overflow to all volumes in "
1598fcf3ce44SJohn Forte 		    "group"));
1599fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1600fcf3ce44SJohn Forte 		    gettext("\t-g g -D\t\tdetach overflow from all volumes in "
1601fcf3ce44SJohn Forte 		    "group"));
1602fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1603fcf3ce44SJohn Forte 		    gettext("\t-g g -E\t\texport shadow volume for all "
1604fcf3ce44SJohn Forte 		    "volumes in group"));
1605fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1606fcf3ce44SJohn Forte 		    gettext("\t-g g -P d u\tset copy delay/units for all "
1607fcf3ce44SJohn Forte 		    "volumes in group"));
1608fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1609fcf3ce44SJohn Forte 		    gettext("\t-g g -P\t\tget copy delay/units for all "
1610fcf3ce44SJohn Forte 		    "volumes in group"));
1611fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1612fcf3ce44SJohn Forte 		    gettext("\nLegend summary:"));
1613fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1614fcf3ce44SJohn Forte 		    gettext("\tind\t\tindependent volume set"));
1615fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1616fcf3ce44SJohn Forte 		    gettext("\tdep\t\tdependent volume set"));
1617fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1618fcf3ce44SJohn Forte 		    gettext("\tall\t\tall configured volumes"));
1619fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1620fcf3ce44SJohn Forte 		    gettext("\tm\t\tmaster volume"));
1621fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1622fcf3ce44SJohn Forte 		    gettext("\ts\t\tshadow volume"));
1623fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1624fcf3ce44SJohn Forte 		    gettext("\tv\t\tshadow volume (reference name)"));
1625fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1626fcf3ce44SJohn Forte 		    gettext("\to\t\toverflow volume"));
1627fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1628fcf3ce44SJohn Forte 		    gettext("\tb\t\tbitmap volume"));
1629fcf3ce44SJohn Forte #ifdef DEBUG
1630fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1631fcf3ce44SJohn Forte 		    gettext("\tf\t\tconfiguration file name"));
1632fcf3ce44SJohn Forte #endif
1633fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1634fcf3ce44SJohn Forte 		    gettext("\td\t\tdelay tick interval"));
1635fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1636fcf3ce44SJohn Forte 		    gettext("\tu\t\tunit size"));
1637fcf3ce44SJohn Forte 		(void) fprintf(stdout, "%s\n",
1638fcf3ce44SJohn Forte 		    gettext("\tg\t\tgroup name"));
1639fcf3ce44SJohn Forte 
1640fcf3ce44SJohn Forte 		/* assume we came here because user request help text */
1641fcf3ce44SJohn Forte 		exit(0);
1642fcf3ce44SJohn Forte 		/* NOTREACHED */
1643fcf3ce44SJohn Forte 	}
1644fcf3ce44SJohn Forte 
1645fcf3ce44SJohn Forte }
1646fcf3ce44SJohn Forte 
1647fcf3ce44SJohn Forte static  char    yeschr[MAX_LINE_SIZE + 2];
1648fcf3ce44SJohn Forte static  char    nochr[MAX_LINE_SIZE + 2];
1649fcf3ce44SJohn Forte 
1650fcf3ce44SJohn Forte static int
1651fcf3ce44SJohn Forte yes(void)
1652fcf3ce44SJohn Forte {
1653fcf3ce44SJohn Forte 	int	i, b;
1654fcf3ce44SJohn Forte 	char	ans[MAX_LINE_SIZE + 1];
1655fcf3ce44SJohn Forte 
1656fcf3ce44SJohn Forte 	for (i = 0; /*CSTYLED*/; i++) {
1657fcf3ce44SJohn Forte 		b = getchar();
1658fcf3ce44SJohn Forte 		if (b == '\n' || b == '\0' || b == EOF) {
1659fcf3ce44SJohn Forte 			if (i < MAX_LINE_SIZE)
1660fcf3ce44SJohn Forte 				ans[i] = 0;
1661fcf3ce44SJohn Forte 			break;
1662fcf3ce44SJohn Forte 		}
1663fcf3ce44SJohn Forte 		if (i < MAX_LINE_SIZE)
1664fcf3ce44SJohn Forte 			ans[i] = b;
1665fcf3ce44SJohn Forte 	}
1666fcf3ce44SJohn Forte 	if (i >= MAX_LINE_SIZE) {
1667fcf3ce44SJohn Forte 		i = MAX_LINE_SIZE;
1668fcf3ce44SJohn Forte 		ans[MAX_LINE_SIZE] = 0;
1669fcf3ce44SJohn Forte 	}
1670fcf3ce44SJohn Forte 	if ((i == 0) || (strncmp(yeschr, ans, i))) {
1671fcf3ce44SJohn Forte 		if (strncmp(nochr, ans, i) == 0)
1672fcf3ce44SJohn Forte 			return (0);
1673fcf3ce44SJohn Forte 		else if (strncmp(yeschr, ans, i) == 0)
1674fcf3ce44SJohn Forte 			return (1);
1675fcf3ce44SJohn Forte 		else {
1676fcf3ce44SJohn Forte 			(void) fprintf(stderr, "%s %s/%s\n",
1677fcf3ce44SJohn Forte 			    gettext("You have to respond with"),
1678fcf3ce44SJohn Forte 			    yeschr, nochr);
1679fcf3ce44SJohn Forte 			return (2);
1680fcf3ce44SJohn Forte 		}
1681fcf3ce44SJohn Forte 	}
1682fcf3ce44SJohn Forte 	return (1);
1683fcf3ce44SJohn Forte }
1684fcf3ce44SJohn Forte 
1685fcf3ce44SJohn Forte static int
1686fcf3ce44SJohn Forte convert_int(char *str)
1687fcf3ce44SJohn Forte {
1688fcf3ce44SJohn Forte 	int result, rc;
1689fcf3ce44SJohn Forte 	char *buf;
1690fcf3ce44SJohn Forte 
1691fcf3ce44SJohn Forte 	buf = (char *)calloc(strlen(str) + 256, sizeof (char));
1692fcf3ce44SJohn Forte 	rc = sscanf(str, "%d%s", &result, buf);
1693fcf3ce44SJohn Forte 
1694fcf3ce44SJohn Forte 	if (rc != 1) {
1695fcf3ce44SJohn Forte 		(void) sprintf(buf, gettext("'%s' is not a valid number"), str);
1696fcf3ce44SJohn Forte 		/* dsw_error calls exit which frees 'buf' */
1697fcf3ce44SJohn Forte 		errno = EINVAL;
1698fcf3ce44SJohn Forte 		dsw_error(buf, NULL);
1699fcf3ce44SJohn Forte 	}
1700fcf3ce44SJohn Forte 	free(buf);
1701fcf3ce44SJohn Forte 
1702fcf3ce44SJohn Forte 	return (result);
1703fcf3ce44SJohn Forte }
1704fcf3ce44SJohn Forte 
1705fcf3ce44SJohn Forte void
1706fcf3ce44SJohn Forte check_action(char *will_happen)
1707fcf3ce44SJohn Forte {
1708fcf3ce44SJohn Forte 	int answer;
1709fcf3ce44SJohn Forte 
1710fcf3ce44SJohn Forte 	if (nflg || !isatty(fileno(stdin)))
1711fcf3ce44SJohn Forte 		return;
1712570de38fSSurya Prakki 	(void) strncpy(yeschr, nl_langinfo(YESSTR), MAX_LINE_SIZE + 1);
1713570de38fSSurya Prakki 	(void) strncpy(nochr, nl_langinfo(NOSTR), MAX_LINE_SIZE + 1);
1714fcf3ce44SJohn Forte 
1715fcf3ce44SJohn Forte 	/*CONSTCOND*/
1716fcf3ce44SJohn Forte 	while (1) {
1717fcf3ce44SJohn Forte 		(void) printf("%s %s/%s ", will_happen, yeschr, nochr);
1718fcf3ce44SJohn Forte 		answer = yes();
1719fcf3ce44SJohn Forte 		if (answer == 1 || answer == 0)
1720fcf3ce44SJohn Forte 			break;
1721fcf3ce44SJohn Forte 	}
1722fcf3ce44SJohn Forte 	if (answer == 1)
1723fcf3ce44SJohn Forte 		return;
1724fcf3ce44SJohn Forte 	exit(1);
1725fcf3ce44SJohn Forte }
1726fcf3ce44SJohn Forte 
1727fcf3ce44SJohn Forte enum	child_event {Status, CopyStart};
1728fcf3ce44SJohn Forte 
1729fcf3ce44SJohn Forte /*
1730fcf3ce44SJohn Forte  * Wait for child process to get to some state, where some state may be:
1731fcf3ce44SJohn Forte  *
1732fcf3ce44SJohn Forte  *	Status		Set up the shadow enough so that it responds
1733fcf3ce44SJohn Forte  *			to status requests.
1734fcf3ce44SJohn Forte  *	CopyStart	Start copy/update operations.
1735fcf3ce44SJohn Forte  */
1736fcf3ce44SJohn Forte 
1737fcf3ce44SJohn Forte int
1738fcf3ce44SJohn Forte child_wait(pid_t child, enum child_event event, char *volume)
1739fcf3ce44SJohn Forte {
1740fcf3ce44SJohn Forte 	dsw_stat_t	args;
1741fcf3ce44SJohn Forte 	int rc;
1742fcf3ce44SJohn Forte 
1743*ea3068a7SRichard Lowe 	(void) strlcpy(args.shadow_vol, volume, DSW_NAMELEN);
1744fcf3ce44SJohn Forte 
1745570de38fSSurya Prakki 	for (; dead_child != child; (void) sleep(1)) {
1746fcf3ce44SJohn Forte 
1747fcf3ce44SJohn Forte 		/* poll shadow group with a status ioctl() */
1748fcf3ce44SJohn Forte 		args.status = spcs_s_ucreate();
1749fcf3ce44SJohn Forte 		errno = 0;
1750fcf3ce44SJohn Forte 		rc = do_ioctl(dsw_fd, DSWIOC_STAT, &args);
1751fcf3ce44SJohn Forte 
1752fcf3ce44SJohn Forte 		spcs_s_ufree(&args.status);
1753fcf3ce44SJohn Forte 
1754fcf3ce44SJohn Forte 		if (event == Status) {
1755fcf3ce44SJohn Forte 			/* keep polling while we fail with DSW_ENOTFOUND */
1756fcf3ce44SJohn Forte 			if (rc != -1 || errno != DSW_ENOTFOUND)
1757fcf3ce44SJohn Forte 				return (0);
1758fcf3ce44SJohn Forte 		} else {
1759fcf3ce44SJohn Forte 			/* event == CopyStart */
1760fcf3ce44SJohn Forte 			if (rc == -1) {
1761fcf3ce44SJohn Forte 				return (1);	/* something wrong */
1762fcf3ce44SJohn Forte 			}
1763fcf3ce44SJohn Forte 			if (args.stat & DSW_COPYINGP)
1764fcf3ce44SJohn Forte 				return (0);	/* copying underway */
1765fcf3ce44SJohn Forte 		}
1766fcf3ce44SJohn Forte 	}
1767fcf3ce44SJohn Forte 	/* child died */
1768fcf3ce44SJohn Forte 	if (WIFEXITED(dead_stat))
1769fcf3ce44SJohn Forte 		return (WEXITSTATUS(dead_stat));
1770fcf3ce44SJohn Forte 	else
1771fcf3ce44SJohn Forte 		return (1);
1772fcf3ce44SJohn Forte }
1773fcf3ce44SJohn Forte 
1774fcf3ce44SJohn Forte int
1775fcf3ce44SJohn Forte mounted(char *t)
1776fcf3ce44SJohn Forte {
1777fcf3ce44SJohn Forte 	int	rdsk;
1778fcf3ce44SJohn Forte 	int	i;
1779fcf3ce44SJohn Forte 	FILE	*mntfp;
1780fcf3ce44SJohn Forte 	struct mnttab mntref;
1781fcf3ce44SJohn Forte 	struct mnttab mntent;
1782fcf3ce44SJohn Forte 	char	target[DSW_NAMELEN];
1783fcf3ce44SJohn Forte 	char	*s;
1784fcf3ce44SJohn Forte 
1785fcf3ce44SJohn Forte 	rdsk = i = 0;
1786fcf3ce44SJohn Forte 	for (s = target; i < DSW_NAMELEN && (*s = *t++); i++) {
1787fcf3ce44SJohn Forte 		if (*s == 'r' && rdsk == 0)
1788fcf3ce44SJohn Forte 			rdsk = 1;
1789fcf3ce44SJohn Forte 		else
1790fcf3ce44SJohn Forte 			s++;
1791fcf3ce44SJohn Forte 	}
1792fcf3ce44SJohn Forte 	*s = '\0';
1793fcf3ce44SJohn Forte 
1794fcf3ce44SJohn Forte 	mntref.mnt_special = target;
1795fcf3ce44SJohn Forte 	mntref.mnt_mountp = NULL;
1796fcf3ce44SJohn Forte 	mntref.mnt_fstype = NULL;
1797fcf3ce44SJohn Forte 	mntref.mnt_mntopts = NULL;
1798fcf3ce44SJohn Forte 	mntref.mnt_time = NULL;
1799fcf3ce44SJohn Forte 
1800fcf3ce44SJohn Forte 	if ((mntfp = fopen("/etc/mnttab", "r")) == NULL) {
1801fcf3ce44SJohn Forte 		dsw_error(gettext("Can not check volume against mount table"),
1802fcf3ce44SJohn Forte 		    NULL);
1803fcf3ce44SJohn Forte 	}
1804fcf3ce44SJohn Forte 	if (getmntany(mntfp, &mntent, &mntref) != -1) {
1805fcf3ce44SJohn Forte 		/* found something before EOF */
1806fcf3ce44SJohn Forte 		(void) fclose(mntfp);
1807fcf3ce44SJohn Forte 		return (1);
1808fcf3ce44SJohn Forte 	}
1809fcf3ce44SJohn Forte 	(void) fclose(mntfp);
1810fcf3ce44SJohn Forte 	return (0);
1811fcf3ce44SJohn Forte }
1812fcf3ce44SJohn Forte 
1813fcf3ce44SJohn Forte void
1814fcf3ce44SJohn Forte enable(char *master_volume, char *shadow_volume,
1815fcf3ce44SJohn Forte 	char *bitmap_volume, char *copy_type)
1816fcf3ce44SJohn Forte {
1817fcf3ce44SJohn Forte 	dsw_config_t parms;
1818fcf3ce44SJohn Forte 	dsw_ioctl_t temp;
1819fcf3ce44SJohn Forte 	char	*p;
1820fcf3ce44SJohn Forte 	int	rc;
1821fcf3ce44SJohn Forte 	pid_t	child;
1822fcf3ce44SJohn Forte 	spcs_s_info_t *sp_info;
1823fcf3ce44SJohn Forte 	struct stat mstat, sstat, bstat;
1824fcf3ce44SJohn Forte 	char	mst_dg[DSW_NAMELEN] = {0};
1825fcf3ce44SJohn Forte 	char	shd_dg[DSW_NAMELEN] = {0};
1826fcf3ce44SJohn Forte 	char	bmp_dg[DSW_NAMELEN] = {0};
1827fcf3ce44SJohn Forte 	int	mvol_enabled;
1828fcf3ce44SJohn Forte 	char	*altname;
1829fcf3ce44SJohn Forte 	grptag_t *gdata;
1830fcf3ce44SJohn Forte 
1831fcf3ce44SJohn Forte 	bzero(&parms, sizeof (dsw_config_t));
1832fcf3ce44SJohn Forte 
1833fcf3ce44SJohn Forte 	if (strcmp(copy_type, "independent") == 0 ||
1834fcf3ce44SJohn Forte 	    strcmp(copy_type, gettext("independent")) == 0)
1835fcf3ce44SJohn Forte 		parms.flag = DSW_GOLDEN;
1836fcf3ce44SJohn Forte 	else if (strcmp(copy_type, "dependent") == 0 ||
1837fcf3ce44SJohn Forte 	    strcmp(copy_type, gettext("dependent")) == 0)
1838fcf3ce44SJohn Forte 		parms.flag = 0;
1839fcf3ce44SJohn Forte 	else
1840fcf3ce44SJohn Forte 		dsw_error(gettext("don't understand shadow type"), NULL);
1841fcf3ce44SJohn Forte 
1842fcf3ce44SJohn Forte 	/* validate volume names */
1843fcf3ce44SJohn Forte 	if (perform_autosv()) {
1844fcf3ce44SJohn Forte 		if (cfg_load_svols(cfg) < 0 || cfg_load_dsvols(cfg) < 0 ||
1845fcf3ce44SJohn Forte 		    cfg_load_shadows(cfg) < 0) {
1846fcf3ce44SJohn Forte 			dsw_error(gettext("Unable to parse config file"), NULL);
1847fcf3ce44SJohn Forte 		}
1848fcf3ce44SJohn Forte 		load_ii_vols(cfg);
1849fcf3ce44SJohn Forte 		reload_vols = LD_SVOLS | LD_DSVOLS | LD_SHADOWS | LD_II;
1850fcf3ce44SJohn Forte 
1851fcf3ce44SJohn Forte 		/* see if it's been used before under a different name */
1852fcf3ce44SJohn Forte 		conform_name(&master_volume);
1853fcf3ce44SJohn Forte 		conform_name(&shadow_volume);
1854fcf3ce44SJohn Forte 		rc = cfg_get_canonical_name(cfg, bitmap_volume, &altname);
1855fcf3ce44SJohn Forte 		if (rc < 0) {
1856fcf3ce44SJohn Forte 			dsw_error(gettext("Unable to parse config file"), NULL);
1857fcf3ce44SJohn Forte 		}
1858fcf3ce44SJohn Forte 		if (rc) {
1859fcf3ce44SJohn Forte 			errno = EBUSY;
1860fcf3ce44SJohn Forte 			dsw_error(gettext("Bitmap in use"), NULL);
1861fcf3ce44SJohn Forte 		}
1862fcf3ce44SJohn Forte 	}
1863fcf3ce44SJohn Forte 
1864fcf3ce44SJohn Forte 	/*
1865fcf3ce44SJohn Forte 	 * If not local, determine disk group names for volumes in II set
1866fcf3ce44SJohn Forte 	 */
1867fcf3ce44SJohn Forte 	switch (check_cluster()) {
1868fcf3ce44SJohn Forte 	case II_CLUSTER:
1869fcf3ce44SJohn Forte 		/*
1870fcf3ce44SJohn Forte 		 * Check if none or all volumes are in a disk group
1871fcf3ce44SJohn Forte 		 */
1872fcf3ce44SJohn Forte 		rc = 0;
1873fcf3ce44SJohn Forte 		if (check_diskgroup(master_volume, mst_dg)) rc++;
1874fcf3ce44SJohn Forte 		if (check_diskgroup(shadow_volume, shd_dg)) rc++;
1875fcf3ce44SJohn Forte 		if (check_diskgroup(bitmap_volume, bmp_dg)) rc++;
1876fcf3ce44SJohn Forte 		if ((rc != 0) && (rc != 3))
1877fcf3ce44SJohn Forte 			dsw_error(gettext(
1878fcf3ce44SJohn Forte 			    "Not all Point-in-Time Copy volumes are "
1879fcf3ce44SJohn Forte 			    "in a disk group"), NULL);
1880fcf3ce44SJohn Forte 
1881fcf3ce44SJohn Forte 		/*
1882fcf3ce44SJohn Forte 		 * If volumes are not in a disk group, but are in a
1883fcf3ce44SJohn Forte 		 * cluster, then "-C <tag>", must be set
1884fcf3ce44SJohn Forte 		 */
1885fcf3ce44SJohn Forte 		if (rc == 0 && cfg_cluster_tag == NULL)
1886fcf3ce44SJohn Forte 			dsw_error(gettext(
1887fcf3ce44SJohn Forte 			    "Point-in-Time Copy volumes, that are not "
1888fcf3ce44SJohn Forte 			    "in a device group which has been "
1889fcf3ce44SJohn Forte 			    "registered with SunCluster, "
1890fcf3ce44SJohn Forte 			    "require usage of \"-C\""), NULL);
1891fcf3ce44SJohn Forte 
1892fcf3ce44SJohn Forte 		/*
1893fcf3ce44SJohn Forte 		 * the same disk group
1894fcf3ce44SJohn Forte 		 * If -n, plus mst_dg==bmp_dg, then allow E/I/J in SunCluster
1895fcf3ce44SJohn Forte 		 */
1896fcf3ce44SJohn Forte 		if ((strcmp(mst_dg, bmp_dg)) ||
1897fcf3ce44SJohn Forte 		    (strcmp(mst_dg, shd_dg) && (!nflg)))
1898fcf3ce44SJohn Forte 			dsw_error(gettext(
1899fcf3ce44SJohn Forte 			    "Volumes are not in same disk group"), NULL);
1900fcf3ce44SJohn Forte 
1901fcf3ce44SJohn Forte 		/*
1902fcf3ce44SJohn Forte 		 * Can never enable the same shadow twice, regardless of
1903fcf3ce44SJohn Forte 		 * exportable shadow device group movement
1904fcf3ce44SJohn Forte 		 */
1905fcf3ce44SJohn Forte 		if (find_shadow_line(shadow_volume))
1906fcf3ce44SJohn Forte 			dsw_error(gettext(
1907fcf3ce44SJohn Forte 			    "Shadow volume is already configured"), NULL);
1908fcf3ce44SJohn Forte 
1909fcf3ce44SJohn Forte 		/*
1910fcf3ce44SJohn Forte 		 * Groups cannot span multiple clusters
1911fcf3ce44SJohn Forte 		 */
1912fcf3ce44SJohn Forte 		if (group_name && perform_autosv()) {
1913fcf3ce44SJohn Forte 			gdata = (grptag_t *)nsc_lookup(volhash, group_name);
1914fcf3ce44SJohn Forte 			if (gdata &&
1915fcf3ce44SJohn Forte 			    strncmp(gdata->ctag, mst_dg, DSW_NAMELEN) != 0) {
1916fcf3ce44SJohn Forte 				errno = EINVAL;
1917fcf3ce44SJohn Forte 				dsw_error(gettext("Group contains sets not "
1918fcf3ce44SJohn Forte 				    "in the same cluster resource"), NULL);
1919fcf3ce44SJohn Forte 			}
1920fcf3ce44SJohn Forte 		}
1921fcf3ce44SJohn Forte 
1922fcf3ce44SJohn Forte 		/*
1923fcf3ce44SJohn Forte 		 * Check cluster tag and bitmap disk group
1924fcf3ce44SJohn Forte 		 * set latter if different
1925fcf3ce44SJohn Forte 		 */
1926fcf3ce44SJohn Forte 		if (check_resource_group(bitmap_volume)) {
1927fcf3ce44SJohn Forte 			/*
1928fcf3ce44SJohn Forte 			 * Unload and reload in the event cluster tag has
1929fcf3ce44SJohn Forte 			 * changed
1930fcf3ce44SJohn Forte 			 */
1931fcf3ce44SJohn Forte 			if (perform_autosv()) {
1932fcf3ce44SJohn Forte 				unload_ii_vols();
1933fcf3ce44SJohn Forte 				cfg_unload_shadows();
1934fcf3ce44SJohn Forte 				cfg_unload_dsvols();
1935fcf3ce44SJohn Forte 				cfg_unload_svols();
1936fcf3ce44SJohn Forte 				if (cfg_load_svols(cfg) < 0 ||
1937fcf3ce44SJohn Forte 				    cfg_load_dsvols(cfg) < 0 ||
1938fcf3ce44SJohn Forte 				    cfg_load_shadows(cfg) < 0) {
1939fcf3ce44SJohn Forte 					dsw_error(gettext(
1940fcf3ce44SJohn Forte 					    "Unable to parse config "
1941fcf3ce44SJohn Forte 					    "file"), NULL);
1942fcf3ce44SJohn Forte 				}
1943fcf3ce44SJohn Forte 				load_ii_vols(cfg);
1944fcf3ce44SJohn Forte 			}
1945fcf3ce44SJohn Forte 		}
1946fcf3ce44SJohn Forte 		/*
1947fcf3ce44SJohn Forte 		 * Copy cluster name into config
1948fcf3ce44SJohn Forte 		 */
1949570de38fSSurya Prakki 		(void) strncpy(parms.cluster_tag, cfg_cluster_tag, DSW_NAMELEN);
1950fcf3ce44SJohn Forte 		break;
1951fcf3ce44SJohn Forte 
1952fcf3ce44SJohn Forte 	case II_CLUSTER_LCL:
1953fcf3ce44SJohn Forte 		/* ensure that the -C local won't interfere with the set */
1954fcf3ce44SJohn Forte 		if (group_name && perform_autosv()) {
1955fcf3ce44SJohn Forte 			gdata = (grptag_t *)nsc_lookup(volhash, group_name);
1956fcf3ce44SJohn Forte 			if (gdata) {
1957fcf3ce44SJohn Forte 				if (strlen(gdata->ctag) != 0) {
1958fcf3ce44SJohn Forte 					errno = EINVAL;
1959fcf3ce44SJohn Forte 					dsw_error(gettext("Unable to put set "
1960fcf3ce44SJohn Forte 					    "into -C local and specified "
1961fcf3ce44SJohn Forte 					    "group"), NULL);
1962fcf3ce44SJohn Forte 				}
1963fcf3ce44SJohn Forte 			}
1964fcf3ce44SJohn Forte 		}
1965fcf3ce44SJohn Forte 		break;
1966fcf3ce44SJohn Forte 	}
1967fcf3ce44SJohn Forte 
1968fcf3ce44SJohn Forte 	/*
1969fcf3ce44SJohn Forte 	 * If we've got a group name, add it into the config
1970fcf3ce44SJohn Forte 	 */
1971fcf3ce44SJohn Forte 	if (group_name) {
1972570de38fSSurya Prakki 		(void) strncpy(parms.group_name, group_name, DSW_NAMELEN);
1973fcf3ce44SJohn Forte 	}
1974fcf3ce44SJohn Forte 
1975fcf3ce44SJohn Forte 	/*
1976fcf3ce44SJohn Forte 	 * Determine accessability of volumes
1977fcf3ce44SJohn Forte 	 */
1978fcf3ce44SJohn Forte 	if (stat(master_volume, &mstat) != 0)
1979fcf3ce44SJohn Forte 		dsw_error(gettext(
1980fcf3ce44SJohn Forte 		    "Unable to access master volume"), NULL);
1981fcf3ce44SJohn Forte 	if (!S_ISCHR(mstat.st_mode))
1982fcf3ce44SJohn Forte 		dsw_error(gettext(
1983fcf3ce44SJohn Forte 		    "Master volume is not a character device"), NULL);
1984fcf3ce44SJohn Forte 	/* check the shadow_vol hasn't be used as SNDR secondary vol */
1985fcf3ce44SJohn Forte 	check_iishadow(shadow_volume);
1986fcf3ce44SJohn Forte 	if (stat(shadow_volume, &sstat) != 0)
1987fcf3ce44SJohn Forte 		dsw_error(gettext(
1988fcf3ce44SJohn Forte 		    "Unable to access shadow volume"), NULL);
1989fcf3ce44SJohn Forte 	if (!S_ISCHR(sstat.st_mode))
1990fcf3ce44SJohn Forte 		dsw_error(gettext(
1991fcf3ce44SJohn Forte 		    "Shadow volume is not a character device"), NULL);
1992fcf3ce44SJohn Forte 	if (mounted(shadow_volume)) {
1993fcf3ce44SJohn Forte 		errno = EBUSY;
1994fcf3ce44SJohn Forte 		dsw_error(gettext(
1995fcf3ce44SJohn Forte 		    "Shadow volume is mounted, unmount it first"), NULL);
1996fcf3ce44SJohn Forte 	}
1997fcf3ce44SJohn Forte 	if (mstat.st_rdev == sstat.st_rdev) {
1998fcf3ce44SJohn Forte 		errno = EINVAL;
1999fcf3ce44SJohn Forte 		dsw_error(gettext(
2000fcf3ce44SJohn Forte 		    "Master and shadow are the same device"), NULL);
2001fcf3ce44SJohn Forte 	}
2002fcf3ce44SJohn Forte 	if (stat(bitmap_volume, &bstat) != 0) {
2003fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to access bitmap"), NULL);
2004fcf3ce44SJohn Forte 	}
2005fcf3ce44SJohn Forte 	if (!S_ISCHR(bstat.st_mode))
2006fcf3ce44SJohn Forte 		dsw_error(gettext(
2007fcf3ce44SJohn Forte 		    "Bitmap volume is not a character device"), NULL);
2008fcf3ce44SJohn Forte 	if (S_ISCHR(bstat.st_mode)) {
2009fcf3ce44SJohn Forte 		if (mstat.st_rdev == bstat.st_rdev) {
2010fcf3ce44SJohn Forte 			errno = EINVAL;
2011fcf3ce44SJohn Forte 			dsw_error(gettext(
2012fcf3ce44SJohn Forte 			    "Master and bitmap are the same device"), NULL);
2013fcf3ce44SJohn Forte 		} else if (sstat.st_rdev == bstat.st_rdev) {
2014fcf3ce44SJohn Forte 			errno = EINVAL;
2015fcf3ce44SJohn Forte 			dsw_error(gettext(
2016fcf3ce44SJohn Forte 			    "Shadow and bitmap are the same device"), NULL);
2017fcf3ce44SJohn Forte 		}
2018fcf3ce44SJohn Forte 	}
2019fcf3ce44SJohn Forte 
2020570de38fSSurya Prakki 	(void) strncpy(parms.master_vol, master_volume, DSW_NAMELEN);
2021570de38fSSurya Prakki 	(void) strncpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
2022570de38fSSurya Prakki 	(void) strncpy(parms.bitmap_vol, bitmap_volume, DSW_NAMELEN);
2023fcf3ce44SJohn Forte 	errno = 0;
2024fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
2025fcf3ce44SJohn Forte 
2026fcf3ce44SJohn Forte 	/*
2027fcf3ce44SJohn Forte 	 * Check that none of the member volumes forms part of another
2028fcf3ce44SJohn Forte 	 * InstantImage group.
2029fcf3ce44SJohn Forte 	 *
2030fcf3ce44SJohn Forte 	 * -- this check has been removed; it is done in the kernel instead
2031fcf3ce44SJohn Forte 	 * -- PJW
2032fcf3ce44SJohn Forte 	 */
2033fcf3ce44SJohn Forte 
2034fcf3ce44SJohn Forte 	/*
2035fcf3ce44SJohn Forte 	 * Check against overflow volumes
2036fcf3ce44SJohn Forte 	 */
2037fcf3ce44SJohn Forte 	for (p = get_overflow_list(); *p != NULL; p += DSW_NAMELEN) {
2038fcf3ce44SJohn Forte 		if (strncmp(master_volume, p, DSW_NAMELEN) == 0)
2039fcf3ce44SJohn Forte 			dsw_error(gettext(
2040fcf3ce44SJohn Forte 			    "Master volume is already an overflow volume"),
2041fcf3ce44SJohn Forte 			    NULL);
2042fcf3ce44SJohn Forte 		else if (strncmp(shadow_volume, p, DSW_NAMELEN) == 0)
2043fcf3ce44SJohn Forte 			dsw_error(gettext(
2044fcf3ce44SJohn Forte 			    "Shadow volume is already an overflow volume"),
2045fcf3ce44SJohn Forte 			    NULL);
2046fcf3ce44SJohn Forte 		else if (strncmp(bitmap_volume, p, DSW_NAMELEN) == 0)
2047fcf3ce44SJohn Forte 			dsw_error(gettext(
2048fcf3ce44SJohn Forte 			    "Bitmap volume is already an overflow volume"),
2049fcf3ce44SJohn Forte 			    NULL);
2050fcf3ce44SJohn Forte 	}
2051fcf3ce44SJohn Forte 
2052fcf3ce44SJohn Forte 	/*
2053fcf3ce44SJohn Forte 	 * Make sure that the shadow volume is not already configured
2054fcf3ce44SJohn Forte 	 */
2055fcf3ce44SJohn Forte 	if (find_shadow_config(shadow_volume, NULL, &temp))
2056fcf3ce44SJohn Forte 		dsw_error(gettext(
2057fcf3ce44SJohn Forte 		    "Shadow volume is already configured"), NULL);
2058fcf3ce44SJohn Forte 	if (perform_autosv()) {
2059fcf3ce44SJohn Forte 		/*
2060fcf3ce44SJohn Forte 		 * parse the dsvol entries to see if we need to place
2061fcf3ce44SJohn Forte 		 * the master or shadow under SV control
2062fcf3ce44SJohn Forte 		 */
2063fcf3ce44SJohn Forte 		if (nsc_lookup(volhash, master_volume) == NULL) {
2064fcf3ce44SJohn Forte 			if (cfg_vol_enable(cfg, master_volume, cfg_cluster_tag,
2065fcf3ce44SJohn Forte 			    "ii") < 0) {
2066fcf3ce44SJohn Forte 				dsw_error(
2067fcf3ce44SJohn Forte 				    gettext("Cannot enable master volume"),
2068fcf3ce44SJohn Forte 				    NULL);
2069fcf3ce44SJohn Forte 			}
2070fcf3ce44SJohn Forte 			mvol_enabled = 1;
2071fcf3ce44SJohn Forte 		} else {
2072fcf3ce44SJohn Forte 			mvol_enabled = 0;
2073fcf3ce44SJohn Forte 		}
2074fcf3ce44SJohn Forte 		if (nsc_lookup(volhash, shadow_volume) == NULL) {
2075fcf3ce44SJohn Forte 			if (nflg) {
2076fcf3ce44SJohn Forte 				cfg_resource(cfg, shd_dg);
2077fcf3ce44SJohn Forte 				rc = cfg_vol_enable(cfg, shadow_volume,
2078fcf3ce44SJohn Forte 				    shd_dg, "ii");
2079fcf3ce44SJohn Forte 				cfg_resource(cfg, cfg_cluster_tag);
2080fcf3ce44SJohn Forte 			} else {
2081fcf3ce44SJohn Forte 				rc = cfg_vol_enable(cfg, shadow_volume,
2082fcf3ce44SJohn Forte 				    cfg_cluster_tag, "ii");
2083fcf3ce44SJohn Forte 			}
2084fcf3ce44SJohn Forte 			if (rc < 0) {
2085fcf3ce44SJohn Forte 				if (mvol_enabled) {
2086fcf3ce44SJohn Forte 					if (cfg_vol_disable(cfg,
2087fcf3ce44SJohn Forte 					    master_volume, cfg_cluster_tag,
2088fcf3ce44SJohn Forte 					    "ii") < 0)
2089fcf3ce44SJohn Forte 						dsw_error(gettext(
2090*ea3068a7SRichard Lowe 						    "SV disable of master "
2091*ea3068a7SRichard Lowe 						    "failed"),
2092fcf3ce44SJohn Forte 						    NULL);
2093fcf3ce44SJohn Forte 				}
2094fcf3ce44SJohn Forte 				dsw_error(
2095fcf3ce44SJohn Forte 				    gettext("Cannot enable shadow volume"),
2096fcf3ce44SJohn Forte 				    NULL);
2097fcf3ce44SJohn Forte 			}
2098fcf3ce44SJohn Forte 		}
2099fcf3ce44SJohn Forte 		unload_ii_vols();
2100fcf3ce44SJohn Forte 		cfg_unload_shadows();
2101fcf3ce44SJohn Forte 		cfg_unload_dsvols();
2102fcf3ce44SJohn Forte 		cfg_unload_svols();
2103fcf3ce44SJohn Forte 		reload_vols = 0;
2104fcf3ce44SJohn Forte 	}
2105fcf3ce44SJohn Forte 
2106fcf3ce44SJohn Forte 	add_cfg_entry(&parms);
2107fcf3ce44SJohn Forte 	cfg_unlock(cfg);
2108fcf3ce44SJohn Forte 	config_locked = 0;
2109fcf3ce44SJohn Forte 
2110570de38fSSurya Prakki 	(void) sigset(SIGCHLD, sigchild);
2111fcf3ce44SJohn Forte 	switch (child = fork()) {
2112fcf3ce44SJohn Forte 
2113fcf3ce44SJohn Forte 	case (pid_t)-1:
2114fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to fork"), NULL);
2115fcf3ce44SJohn Forte 		break;
2116fcf3ce44SJohn Forte 
2117fcf3ce44SJohn Forte 	case 0:
2118fcf3ce44SJohn Forte 		rc = do_ioctl(dsw_fd, DSWIOC_ENABLE, &parms);
2119fcf3ce44SJohn Forte 		if (rc == -1 && errno != DSW_EABORTED && errno != DSW_EIO) {
2120fcf3ce44SJohn Forte 			/*
2121fcf3ce44SJohn Forte 			 * Failed to enable shadow group, log problem and remove
2122fcf3ce44SJohn Forte 			 * the shadow group from the config file.
2123fcf3ce44SJohn Forte 			 */
2124fcf3ce44SJohn Forte 			spcs_log("ii", &parms.status,
2125fcf3ce44SJohn Forte 			    gettext("Enable failed %s %s %s (%s)"),
2126fcf3ce44SJohn Forte 			    master_volume, shadow_volume, bitmap_volume,
2127fcf3ce44SJohn Forte 			    parms.flag & DSW_GOLDEN ?
2128fcf3ce44SJohn Forte 			    "independent" : "dependent");
2129fcf3ce44SJohn Forte 
2130fcf3ce44SJohn Forte 			if (!ii_lock(cfg, CFG_WRLOCK) ||
2131fcf3ce44SJohn Forte 			    !find_shadow_config(shadow_volume, NULL, &temp)) {
2132fcf3ce44SJohn Forte 				dsw_error(gettext(
2133fcf3ce44SJohn Forte 				    "Enable failed, can't tidy up cfg"),
2134fcf3ce44SJohn Forte 				    &parms.status);
2135fcf3ce44SJohn Forte 			}
2136fcf3ce44SJohn Forte 			config_locked = 1;
2137fcf3ce44SJohn Forte 			remove_iiset(setnumber, shadow_volume, 0);
2138fcf3ce44SJohn Forte 			dsw_error(gettext("Enable failed"), &parms.status);
2139fcf3ce44SJohn Forte 		}
2140fcf3ce44SJohn Forte 
2141fcf3ce44SJohn Forte 		if (rc == -1)
2142fcf3ce44SJohn Forte 			sp_info = &parms.status;
2143fcf3ce44SJohn Forte 		else
2144fcf3ce44SJohn Forte 			sp_info = NULL;
2145fcf3ce44SJohn Forte 		spcs_log("ii", sp_info, gettext("Enabled %s %s %s (%s)"),
2146fcf3ce44SJohn Forte 		    master_volume, shadow_volume, bitmap_volume,
2147fcf3ce44SJohn Forte 		    parms.flag & DSW_GOLDEN ? "independent" : "dependent");
2148fcf3ce44SJohn Forte 		spcs_s_ufree(&parms.status);
2149fcf3ce44SJohn Forte 		break;
2150fcf3ce44SJohn Forte 
2151fcf3ce44SJohn Forte 	default:
2152fcf3ce44SJohn Forte 		exit(child_wait(child, Status, shadow_volume));
2153fcf3ce44SJohn Forte 		break;
2154fcf3ce44SJohn Forte 	}
2155fcf3ce44SJohn Forte }
2156fcf3ce44SJohn Forte 
2157fcf3ce44SJohn Forte int
2158fcf3ce44SJohn Forte reset(char *volume)
2159fcf3ce44SJohn Forte {
2160fcf3ce44SJohn Forte 	dsw_ioctl_t args;
2161fcf3ce44SJohn Forte 	dsw_config_t parms;
2162fcf3ce44SJohn Forte 	int	rc;
2163fcf3ce44SJohn Forte 	int	wait_loc;
2164fcf3ce44SJohn Forte 	pid_t	child = (pid_t)0;
2165fcf3ce44SJohn Forte 	enum copy_wait wait_action;
2166fcf3ce44SJohn Forte 	spcs_s_info_t *stat;
2167fcf3ce44SJohn Forte 	dsw_stat_t prev_stat;
2168fcf3ce44SJohn Forte 	int stat_flags;
2169fcf3ce44SJohn Forte 	static int unlocked = 0;
2170fcf3ce44SJohn Forte 	int	do_enable = 0;
2171fcf3ce44SJohn Forte 	char	key[CFG_MAX_KEY];
2172fcf3ce44SJohn Forte 	char	optval[CFG_MAX_BUF];
2173fcf3ce44SJohn Forte 	unsigned int flags;
2174fcf3ce44SJohn Forte 
2175fcf3ce44SJohn Forte 	wait_action = WaitForStart;
2176fcf3ce44SJohn Forte 
2177fcf3ce44SJohn Forte 	if (unlocked && !ii_lock(cfg, CFG_RDLOCK)) {
2178fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to set locking on the configuration"),
2179fcf3ce44SJohn Forte 		    NULL);
2180fcf3ce44SJohn Forte 	}
2181fcf3ce44SJohn Forte 	config_locked = 1;
2182fcf3ce44SJohn Forte 	if (!find_shadow_config(volume, &parms, &args))
2183fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
2184fcf3ce44SJohn Forte 		    "group"), NULL);
2185fcf3ce44SJohn Forte 
2186fcf3ce44SJohn Forte 	cfg_unlock(cfg);
2187fcf3ce44SJohn Forte 	config_locked = 0;
2188fcf3ce44SJohn Forte 	unlocked = 1;
2189fcf3ce44SJohn Forte 
2190fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Start reset %s"), volume);
2191*ea3068a7SRichard Lowe 	(void) strlcpy(prev_stat.shadow_vol, volume, DSW_NAMELEN);
2192fcf3ce44SJohn Forte 	prev_stat.status = spcs_s_ucreate();
2193fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_STAT, &prev_stat) == -1) {
2194fcf3ce44SJohn Forte 		/* set is suspended, so we do the enable processing instead */
2195fcf3ce44SJohn Forte 		do_enable = 1;
2196fcf3ce44SJohn Forte 
2197fcf3ce44SJohn Forte 		/* first check to see whether the set was offline */
2198570de38fSSurya Prakki 		(void) snprintf(key, CFG_MAX_KEY, "ii.set%d.options",
2199570de38fSSurya Prakki 		    setnumber);
2200fcf3ce44SJohn Forte 		if (!ii_lock(cfg, CFG_RDLOCK)) {
2201fcf3ce44SJohn Forte 			dsw_error(gettext("Unable to set locking on the "
2202fcf3ce44SJohn Forte 			    "configuration"), NULL);
2203fcf3ce44SJohn Forte 		}
2204fcf3ce44SJohn Forte 		config_locked = 1;
2205fcf3ce44SJohn Forte 		unlocked = 0;
2206fcf3ce44SJohn Forte 		if (cfg_get_single_option(cfg, CFG_SEC_CONF, key,
2207fcf3ce44SJohn Forte 		    NSKERN_II_BMP_OPTION, optval, CFG_MAX_BUF) < 0) {
2208fcf3ce44SJohn Forte 			dsw_error(gettext("unable to read config file"), NULL);
2209fcf3ce44SJohn Forte 		}
2210fcf3ce44SJohn Forte 		cfg_unlock(cfg);
2211fcf3ce44SJohn Forte 		config_locked = 0;
2212fcf3ce44SJohn Forte 		unlocked = 1;
2213570de38fSSurya Prakki 		(void) sscanf(optval, "%x", &flags);
2214fcf3ce44SJohn Forte 		if ((flags & DSW_OFFLINE) == 0) {
2215fcf3ce44SJohn Forte 			/* set wasn't offline - don't reset */
2216fcf3ce44SJohn Forte 			dsw_error(gettext("Set not offline, will not reset"),
2217fcf3ce44SJohn Forte 			    NULL);
2218fcf3ce44SJohn Forte 		}
2219fcf3ce44SJohn Forte 		parms.status = spcs_s_ucreate();
2220fcf3ce44SJohn Forte 		stat = &parms.status;
2221fcf3ce44SJohn Forte 		stat_flags = DSW_BMPOFFLINE;
2222fcf3ce44SJohn Forte 	} else {
2223fcf3ce44SJohn Forte 		args.status = spcs_s_ucreate();
2224fcf3ce44SJohn Forte 		stat = &args.status;
2225fcf3ce44SJohn Forte 		stat_flags = prev_stat.stat;
2226fcf3ce44SJohn Forte 	}
2227fcf3ce44SJohn Forte 	spcs_s_ufree(&prev_stat.status);
2228fcf3ce44SJohn Forte 
2229fcf3ce44SJohn Forte 	if (wait_action == WaitForStart)
2230570de38fSSurya Prakki 		(void) sigset(SIGCHLD, sigchild);
2231fcf3ce44SJohn Forte 
2232fcf3ce44SJohn Forte 	switch (child = fork()) {
2233fcf3ce44SJohn Forte 
2234fcf3ce44SJohn Forte 	case (pid_t)-1:
2235fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to fork"), NULL);
2236fcf3ce44SJohn Forte 		break;
2237fcf3ce44SJohn Forte 
2238fcf3ce44SJohn Forte 	case 0:
2239fcf3ce44SJohn Forte 		if (do_enable) {
2240fcf3ce44SJohn Forte 			rc = do_ioctl(dsw_fd, DSWIOC_ENABLE, &parms);
2241fcf3ce44SJohn Forte 		} else {
2242fcf3ce44SJohn Forte 			rc = do_ioctl(dsw_fd, DSWIOC_RESET, &args);
2243fcf3ce44SJohn Forte 		}
2244fcf3ce44SJohn Forte 		if (rc == -1 && errno != DSW_EABORTED && errno != DSW_EIO) {
2245fcf3ce44SJohn Forte 			spcs_log("ii", stat, gettext("Fail reset %s"), volume);
2246fcf3ce44SJohn Forte 			dsw_error(gettext("Reset shadow failed"), stat);
2247fcf3ce44SJohn Forte 		}
2248fcf3ce44SJohn Forte 		/* last_overflow is set during find_shadow_config */
2249fcf3ce44SJohn Forte 		if (strlen(last_overflow) > 0 &&
2250fcf3ce44SJohn Forte 		    (stat_flags & (DSW_SHDOFFLINE | DSW_BMPOFFLINE)) != 0) {
2251fcf3ce44SJohn Forte 			/* reattach it */
2252570de38fSSurya Prakki 			(void) strncpy(parms.bitmap_vol, last_overflow,
2253570de38fSSurya Prakki 			    DSW_NAMELEN);
2254fcf3ce44SJohn Forte 			do_attach(&parms);
2255fcf3ce44SJohn Forte 		}
2256fcf3ce44SJohn Forte 		spcs_log("ii", stat, gettext("Finish reset %s"), volume);
2257fcf3ce44SJohn Forte 		spcs_s_ufree(stat);
2258fcf3ce44SJohn Forte 
2259fcf3ce44SJohn Forte 		exit(0);
2260fcf3ce44SJohn Forte 		break;
2261fcf3ce44SJohn Forte 	default:
2262fcf3ce44SJohn Forte 		if (wait_action == WaitForStart) {
2263fcf3ce44SJohn Forte 			rc = child_wait(child, CopyStart, args.shadow_vol);
2264fcf3ce44SJohn Forte 		} else { /* wait_action == WaitForEnd */
2265fcf3ce44SJohn Forte 			wait_loc = 0;
2266570de38fSSurya Prakki 			(void) wait(&wait_loc);
2267fcf3ce44SJohn Forte 			if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0))
2268fcf3ce44SJohn Forte 				rc = 0;
2269fcf3ce44SJohn Forte 			else
2270fcf3ce44SJohn Forte 				rc = -1;
2271fcf3ce44SJohn Forte 		}
2272fcf3ce44SJohn Forte 		break;
2273fcf3ce44SJohn Forte 	}
2274fcf3ce44SJohn Forte 	/* if successful, remove flags entry from options field */
2275fcf3ce44SJohn Forte 	if (rc >= 0) {
2276fcf3ce44SJohn Forte 		if (!ii_lock(cfg, CFG_WRLOCK)) {
2277fcf3ce44SJohn Forte 			dsw_error(gettext("Unable to set locking on the "
2278fcf3ce44SJohn Forte 			    "configuration"), NULL);
2279fcf3ce44SJohn Forte 		}
2280fcf3ce44SJohn Forte 		config_locked = 1;
2281fcf3ce44SJohn Forte 		if (!find_shadow_config(volume, &parms, &args)) {
2282fcf3ce44SJohn Forte 			dsw_error(gettext("Volume is not in a Point-in-Time "
2283fcf3ce44SJohn Forte 			    "Copy group"), NULL);
2284fcf3ce44SJohn Forte 		}
2285570de38fSSurya Prakki 		(void) snprintf(key, CFG_MAX_KEY, "ii.set%d.options",
2286570de38fSSurya Prakki 		    setnumber);
2287fcf3ce44SJohn Forte 		if (cfg_del_option(cfg, CFG_SEC_CONF, key, NSKERN_II_BMP_OPTION)
2288fcf3ce44SJohn Forte 		    < 0) {
2289fcf3ce44SJohn Forte 			dsw_error(gettext("Update of config failed"), NULL);
2290fcf3ce44SJohn Forte 		}
2291570de38fSSurya Prakki 		(void) cfg_commit(cfg);
2292fcf3ce44SJohn Forte 		cfg_unlock(cfg);
2293fcf3ce44SJohn Forte 		config_locked = 0;
2294fcf3ce44SJohn Forte 	}
2295fcf3ce44SJohn Forte 
2296fcf3ce44SJohn Forte 	return (rc);
2297fcf3ce44SJohn Forte }
2298fcf3ce44SJohn Forte 
2299fcf3ce44SJohn Forte int
2300fcf3ce44SJohn Forte overflow(char *volume)
2301fcf3ce44SJohn Forte {
2302fcf3ce44SJohn Forte 	dsw_ioctl_t args;
2303fcf3ce44SJohn Forte 	int	rc;
2304fcf3ce44SJohn Forte 	spcs_s_info_t *stat;
2305fcf3ce44SJohn Forte 
2306fcf3ce44SJohn Forte 	check_action(gettext("Initialize this overflow volume?"));
2307fcf3ce44SJohn Forte 	if (find_matching_cf_line(volume, NULL, &args))
2308fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is part of a Point-in-Time Copy "
2309fcf3ce44SJohn Forte 		    "group"), NULL);
2310fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
2311570de38fSSurya Prakki 	(void) strncpy(args.shadow_vol, volume, DSW_NAMELEN);
2312fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_OCREAT, &args);
2313fcf3ce44SJohn Forte 	if (rc == -1) {
2314fcf3ce44SJohn Forte 		spcs_log("ii", &args.status,
2315fcf3ce44SJohn Forte 		    gettext("Create overflow failed %s"), volume);
2316fcf3ce44SJohn Forte 		dsw_error(gettext("Create overflow failed"), &args.status);
2317fcf3ce44SJohn Forte 	}
2318fcf3ce44SJohn Forte 	if (rc == -1)
2319fcf3ce44SJohn Forte 		stat = &args.status;
2320fcf3ce44SJohn Forte 	else
2321fcf3ce44SJohn Forte 		stat = NULL;
2322fcf3ce44SJohn Forte 	spcs_log("ii", stat, gettext("Create overflow succeeded %s"), volume);
2323fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
2324fcf3ce44SJohn Forte 
2325fcf3ce44SJohn Forte 	return (0);
2326fcf3ce44SJohn Forte }
2327fcf3ce44SJohn Forte 
2328fcf3ce44SJohn Forte void
2329fcf3ce44SJohn Forte bitmap_op(char *master_volume, int print_bitmap, int bitmap_percent, int used,
2330fcf3ce44SJohn Forte     int is_compact)
2331fcf3ce44SJohn Forte {
2332fcf3ce44SJohn Forte 	unsigned char *bitmap;
2333fcf3ce44SJohn Forte 	char *name;
2334fcf3ce44SJohn Forte 	int i, x, y;
2335fcf3ce44SJohn Forte 	unsigned j;
2336fcf3ce44SJohn Forte 	unsigned long n;
2337fcf3ce44SJohn Forte 	unsigned long percent;
2338fcf3ce44SJohn Forte 
2339fcf3ce44SJohn Forte 	bitmap = allocate_bitmap(master_volume);
2340fcf3ce44SJohn Forte 	if (bitmap == NULL)
2341fcf3ce44SJohn Forte 		return;
2342fcf3ce44SJohn Forte 
2343fcf3ce44SJohn Forte 	if (bitmap_percent) {
2344fcf3ce44SJohn Forte 		/* count the number of bits set in bitmap */
2345fcf3ce44SJohn Forte 		for (i = n = 0; i < bm_size; i++)
2346fcf3ce44SJohn Forte 			for (j = (unsigned)bitmap[i]; j; j &= j -1)
2347fcf3ce44SJohn Forte 				n++;
2348fcf3ce44SJohn Forte 		if (is_compact)
2349fcf3ce44SJohn Forte 			(void) printf(gettext("Chunks in map: %d used: %d\n"),
2350fcf3ce44SJohn Forte 			    used, n);
2351fcf3ce44SJohn Forte 		if (bm_actual < 100) {
2352fcf3ce44SJohn Forte 			percent = 0;
2353fcf3ce44SJohn Forte 		} else {
2354fcf3ce44SJohn Forte 			percent = (n * 100) / bm_actual;
2355fcf3ce44SJohn Forte 		}
2356fcf3ce44SJohn Forte 		(void) printf(gettext("Percent of bitmap set: %u\n"), percent);
2357fcf3ce44SJohn Forte 		percent = percent/100;
2358fcf3ce44SJohn Forte 		/* distinguish between 0.0000% and 0.n% of bitmap set */
2359fcf3ce44SJohn Forte 		if (percent < 1)
2360fcf3ce44SJohn Forte 			(void) printf("\t(%s)\n", n > 0 ?
2361fcf3ce44SJohn Forte 			    gettext("bitmap dirty") : gettext("bitmap clean"));
2362fcf3ce44SJohn Forte 	}
2363fcf3ce44SJohn Forte 
2364fcf3ce44SJohn Forte 	if (print_bitmap) {
2365fcf3ce44SJohn Forte 		name = strrchr(master_volume, '/');
2366fcf3ce44SJohn Forte 		if (name++ == NULL)
2367fcf3ce44SJohn Forte 		name = master_volume;
2368fcf3ce44SJohn Forte 		i = bm_size * 8;
2369fcf3ce44SJohn Forte 		x = (int)ceil(sqrt((double)i));
2370fcf3ce44SJohn Forte 		x += (8 - (x % 8));	/* round up to nearest multiple of 8 */
2371fcf3ce44SJohn Forte 		y = i / x;
2372fcf3ce44SJohn Forte 		if (y * x < i)
2373fcf3ce44SJohn Forte 			y++;
2374fcf3ce44SJohn Forte 		(void) printf("#define bm%s_width %d\n#define bm%s_height %d\n",
2375fcf3ce44SJohn Forte 		    name, x, name, y);
2376fcf3ce44SJohn Forte 		(void) printf("#define bm%s_x_hot 0\n#define bm%s_y_hot 0\n",
2377fcf3ce44SJohn Forte 		    name, name);
2378fcf3ce44SJohn Forte 		(void) printf("static char bm%s_bits[] = {\n", name);
2379fcf3ce44SJohn Forte 		for (i = 0; i < bm_size; i++) {
2380fcf3ce44SJohn Forte 			if (i % 12 == 0)
2381fcf3ce44SJohn Forte 				(void) printf("\n");
2382fcf3ce44SJohn Forte 			(void) printf("0x%02x, ", bitmap[i]);
2383fcf3ce44SJohn Forte 		}
2384fcf3ce44SJohn Forte 		y = x * y;
2385fcf3ce44SJohn Forte 		for (; i < y; i++) {
2386fcf3ce44SJohn Forte 			if (i % 12 == 0)
2387fcf3ce44SJohn Forte 				(void) printf("\n");
2388fcf3ce44SJohn Forte 			(void) printf("0x00, ");
2389fcf3ce44SJohn Forte 		}
2390fcf3ce44SJohn Forte 		(void) printf("\n};\n");
2391fcf3ce44SJohn Forte 	}
2392fcf3ce44SJohn Forte 
2393fcf3ce44SJohn Forte 	free_bitmap(bitmap);
2394fcf3ce44SJohn Forte }
2395fcf3ce44SJohn Forte 
2396fcf3ce44SJohn Forte static int
2397fcf3ce44SJohn Forte validate_group_names(char **vol_list, char *group)
2398fcf3ce44SJohn Forte {
2399fcf3ce44SJohn Forte 	ENTRY item, *found;
2400fcf3ce44SJohn Forte 	int i, rc, count;
2401fcf3ce44SJohn Forte 	dsw_aioctl_t *group_list;
2402fcf3ce44SJohn Forte 	char *ptr;
2403fcf3ce44SJohn Forte 
2404fcf3ce44SJohn Forte 	if (group == NULL || *group == NULL) {
2405fcf3ce44SJohn Forte 		/* no group set, just count volume list */
2406fcf3ce44SJohn Forte 		for (i = 0; *vol_list++ != NULL; i++)
2407fcf3ce44SJohn Forte 			;
2408fcf3ce44SJohn Forte 		return (i);
2409fcf3ce44SJohn Forte 	}
2410fcf3ce44SJohn Forte 
2411fcf3ce44SJohn Forte 	if ((count = do_ioctl(dsw_fd, DSWIOC_LISTLEN, NULL)) < 0)
2412fcf3ce44SJohn Forte 		dsw_error("DSWIOC_LISTLEN", NULL);
2413fcf3ce44SJohn Forte 
2414fcf3ce44SJohn Forte 	group_list = malloc(sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
2415fcf3ce44SJohn Forte 	if (group_list == NULL)
2416fcf3ce44SJohn Forte 		dsw_error(gettext("Failed to allocate memory"), NULL);
2417fcf3ce44SJohn Forte 
2418fcf3ce44SJohn Forte 	bzero(group_list, sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
2419fcf3ce44SJohn Forte 	group_list->count = count;
2420fcf3ce44SJohn Forte 	group_list->flags = 0;
2421fcf3ce44SJohn Forte 	group_list->status = spcs_s_ucreate();
2422570de38fSSurya Prakki 	(void) strncpy(group_list->shadow_vol, group, DSW_NAMELEN);
2423fcf3ce44SJohn Forte 
2424fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_GLIST, group_list);
2425fcf3ce44SJohn Forte 	if (rc < 0)
2426fcf3ce44SJohn Forte 		dsw_error(gettext("Group list access failure"),
2427fcf3ce44SJohn Forte 		    &group_list->status);
2428fcf3ce44SJohn Forte 
2429fcf3ce44SJohn Forte 	group_list->shadow_vol[DSW_NAMELEN * group_list->count] = '\0';
2430fcf3ce44SJohn Forte 
2431fcf3ce44SJohn Forte 	/* create hash and enter all volumes into it */
2432fcf3ce44SJohn Forte 	if (hcreate(group_list->count) == 0)
2433fcf3ce44SJohn Forte 		dsw_error(gettext("Failed to allocate memory"), NULL);
2434fcf3ce44SJohn Forte 	ptr = group_list->shadow_vol;
2435fcf3ce44SJohn Forte 	count = group_list->count;
2436fcf3ce44SJohn Forte 	i = 0;
2437fcf3ce44SJohn Forte 	while (i < count) {
2438fcf3ce44SJohn Forte 		ptr[ DSW_NAMELEN - 1 ] = '\0';
2439fcf3ce44SJohn Forte 		item.key = ptr;
2440fcf3ce44SJohn Forte 		item.data = (void *) 0;
2441fcf3ce44SJohn Forte 		(void) hsearch(item, ENTER);
2442fcf3ce44SJohn Forte 		++i;
2443fcf3ce44SJohn Forte 		ptr += DSW_NAMELEN;
2444fcf3ce44SJohn Forte 	}
2445fcf3ce44SJohn Forte 
2446fcf3ce44SJohn Forte 	/* now compare the volume list with the hash */
2447fcf3ce44SJohn Forte 	for (i = 0; vol_list[ i ]; i++) {
2448fcf3ce44SJohn Forte 		item.key = vol_list[ i ];
2449fcf3ce44SJohn Forte 		found = hsearch(item, FIND);
2450fcf3ce44SJohn Forte 		if (!found)
2451fcf3ce44SJohn Forte 			dsw_error(gettext("Group config does not match kernel"),
2452fcf3ce44SJohn Forte 			    NULL);
2453fcf3ce44SJohn Forte 		if (found->data != (void *) 0)
2454fcf3ce44SJohn Forte 			dsw_error(gettext("Duplicate volume specified"), NULL);
2455fcf3ce44SJohn Forte 		found->data = (void *) 1;
2456fcf3ce44SJohn Forte 	}
2457fcf3ce44SJohn Forte 	if (i != count)
2458fcf3ce44SJohn Forte 		dsw_error(gettext("Group config does not match kernel"), NULL);
2459fcf3ce44SJohn Forte 
2460fcf3ce44SJohn Forte 	/* everything checks out */
2461fcf3ce44SJohn Forte 	free(group_list);
2462fcf3ce44SJohn Forte 	hdestroy();
2463fcf3ce44SJohn Forte 
2464fcf3ce44SJohn Forte 	return (count);
2465fcf3ce44SJohn Forte }
2466fcf3ce44SJohn Forte 
2467fcf3ce44SJohn Forte int
2468fcf3ce44SJohn Forte do_acopy(char **vol_list, enum copy_update update_mode,
2469fcf3ce44SJohn Forte 		enum copy_direction direction)
2470fcf3ce44SJohn Forte {
2471fcf3ce44SJohn Forte 	dsw_aioctl_t *acopy_args;
2472fcf3ce44SJohn Forte 	dsw_ioctl_t copy_args;
2473fcf3ce44SJohn Forte 	dsw_config_t parms;
2474fcf3ce44SJohn Forte 	dsw_stat_t	stat_s;
2475fcf3ce44SJohn Forte 	int	i;
2476fcf3ce44SJohn Forte 	int	rc;
2477fcf3ce44SJohn Forte 	int	n_vols;
2478fcf3ce44SJohn Forte 	char	*t;
2479fcf3ce44SJohn Forte 	char	buf[1024];
2480fcf3ce44SJohn Forte 	char	*sp;
2481fcf3ce44SJohn Forte 	char	*ppid;
2482fcf3ce44SJohn Forte 
2483fcf3ce44SJohn Forte 	n_vols = validate_group_names(vol_list, group_name);
2484fcf3ce44SJohn Forte 
2485fcf3ce44SJohn Forte 	acopy_args = calloc(sizeof (dsw_aioctl_t) + n_vols * DSW_NAMELEN, 1);
2486fcf3ce44SJohn Forte 	if (acopy_args == NULL)
2487fcf3ce44SJohn Forte 		dsw_error(gettext("Too many volumes given for update"), NULL);
2488fcf3ce44SJohn Forte 
2489fcf3ce44SJohn Forte 	acopy_args->count = n_vols;
2490fcf3ce44SJohn Forte 
2491fcf3ce44SJohn Forte 	acopy_args->flags = 0;
2492fcf3ce44SJohn Forte 
2493fcf3ce44SJohn Forte 	if (update_mode == Update)
2494fcf3ce44SJohn Forte 		acopy_args->flags |= CV_BMP_ONLY;
2495fcf3ce44SJohn Forte 	if (direction == ToMaster)
2496fcf3ce44SJohn Forte 		acopy_args->flags |= CV_SHD2MST;
2497fcf3ce44SJohn Forte 	if (pflg) {
2498fcf3ce44SJohn Forte 		acopy_args->flags |= CV_LOCK_PID;
2499fcf3ce44SJohn Forte #ifdef DEBUG
2500fcf3ce44SJohn Forte 		ppid = getenv("IIADM_PPID");
2501fcf3ce44SJohn Forte 		if (ppid) {
2502fcf3ce44SJohn Forte 			acopy_args->pid = atoi(ppid);
2503570de38fSSurya Prakki 			(void) fprintf(stderr, "(using %s for ppid)\n", ppid);
2504fcf3ce44SJohn Forte 		} else {
2505fcf3ce44SJohn Forte 			acopy_args->pid = getppid();
2506fcf3ce44SJohn Forte 		}
2507fcf3ce44SJohn Forte #else
2508fcf3ce44SJohn Forte 		acopy_args->pid = getppid();
2509fcf3ce44SJohn Forte #endif
2510fcf3ce44SJohn Forte 	}
2511fcf3ce44SJohn Forte 
2512fcf3ce44SJohn Forte 	for (i = 0; i < n_vols; i++) {
2513fcf3ce44SJohn Forte 		if (!find_shadow_config(vol_list[i], &parms, &copy_args))
2514fcf3ce44SJohn Forte 			dsw_error(gettext("Volume is not in a Point-in-Time "
2515fcf3ce44SJohn Forte 			    "group"), NULL);
2516fcf3ce44SJohn Forte 		if (direction == ToMaster) {
2517fcf3ce44SJohn Forte 			t = parms.master_vol;
2518fcf3ce44SJohn Forte 		} else {
2519fcf3ce44SJohn Forte 			t = parms.shadow_vol;
2520fcf3ce44SJohn Forte 		}
2521fcf3ce44SJohn Forte 
2522fcf3ce44SJohn Forte 		if (mounted(t)) {
2523fcf3ce44SJohn Forte 			errno = EBUSY;
2524fcf3ce44SJohn Forte 			dsw_error(gettext("Target of copy/update is mounted, "
2525fcf3ce44SJohn Forte 			    "unmount it first"), NULL);
2526fcf3ce44SJohn Forte 		}
2527fcf3ce44SJohn Forte 
2528*ea3068a7SRichard Lowe 		(void) strlcpy(stat_s.shadow_vol, parms.shadow_vol,
2529570de38fSSurya Prakki 		    DSW_NAMELEN);
2530fcf3ce44SJohn Forte 		stat_s.status = spcs_s_ucreate();
2531fcf3ce44SJohn Forte 		rc = do_ioctl(dsw_fd, DSWIOC_STAT, &stat_s);
2532fcf3ce44SJohn Forte 		spcs_s_ufree(&stat_s.status);
2533fcf3ce44SJohn Forte 		if (rc == -1) {
2534fcf3ce44SJohn Forte 			(void) sprintf(buf,
2535fcf3ce44SJohn Forte 			    gettext("Shadow group %s is suspended"),
2536fcf3ce44SJohn Forte 			    vol_list[i]);
2537fcf3ce44SJohn Forte 			dsw_error(buf, NULL);
2538fcf3ce44SJohn Forte 		}
2539fcf3ce44SJohn Forte 
2540fcf3ce44SJohn Forte 		if (stat_s.stat & DSW_COPYINGP) {
2541fcf3ce44SJohn Forte 			(void) fprintf(stderr, "%s: %s\n", cmdnam,
2542fcf3ce44SJohn Forte 			    gettext("Copy already in progress"));
2543fcf3ce44SJohn Forte 			exit(1);
2544fcf3ce44SJohn Forte 		}
2545fcf3ce44SJohn Forte 	}
2546fcf3ce44SJohn Forte 	acopy_args->status = spcs_s_ucreate();
2547fcf3ce44SJohn Forte 	for (i = 0; i < n_vols; i++) {
2548fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Atomic %s %s %s"),
2549*ea3068a7SRichard Lowe 		    update_mode == Update ? gettext("update") : gettext("copy"),
2550fcf3ce44SJohn Forte 		    vol_list[i],
2551fcf3ce44SJohn Forte 		    direction == ToMaster ?  gettext("from shadow") :
2552fcf3ce44SJohn Forte 		    gettext("to shadow"));
2553fcf3ce44SJohn Forte 	}
2554fcf3ce44SJohn Forte 	if (group_name == NULL || *group_name == NULL) {
2555fcf3ce44SJohn Forte 		sp = acopy_args->shadow_vol;
2556fcf3ce44SJohn Forte 		for (i = 0; i < n_vols; i++, sp += DSW_NAMELEN)
2557570de38fSSurya Prakki 			(void) strncpy(sp, vol_list[i], DSW_NAMELEN);
2558fcf3ce44SJohn Forte 	} else {
2559570de38fSSurya Prakki 		(void) strncpy(acopy_args->shadow_vol, group_name, DSW_NAMELEN);
2560fcf3ce44SJohn Forte 		acopy_args->flags |= CV_IS_GROUP;
2561fcf3ce44SJohn Forte 	}
2562fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_ACOPY, acopy_args);
2563fcf3ce44SJohn Forte 	if (rc == -1) {
2564fcf3ce44SJohn Forte 		i = acopy_args->count;
2565fcf3ce44SJohn Forte 		if (i < 0 || i >= n_vols) {
2566fcf3ce44SJohn Forte 			spcs_log("ii", NULL, gettext("Atomic update failed"));
2567fcf3ce44SJohn Forte 			(void) sprintf(buf, gettext("Update failed"));
2568fcf3ce44SJohn Forte 		} else {
2569fcf3ce44SJohn Forte 			spcs_log("ii", NULL,
2570fcf3ce44SJohn Forte 			    gettext("Atomic update of %s failed"),
2571fcf3ce44SJohn Forte 			    vol_list[acopy_args->count]);
2572fcf3ce44SJohn Forte 			(void) sprintf(buf, gettext("Update of %s failed"),
2573fcf3ce44SJohn Forte 			    vol_list[acopy_args->count]);
2574fcf3ce44SJohn Forte 		}
2575fcf3ce44SJohn Forte 		dsw_error(buf, &(acopy_args->status));
2576fcf3ce44SJohn Forte 	}
2577fcf3ce44SJohn Forte 	return (rc);
2578fcf3ce44SJohn Forte }
2579fcf3ce44SJohn Forte 
2580fcf3ce44SJohn Forte int
2581fcf3ce44SJohn Forte do_copy(char **vol_list, enum copy_update update_mode,
2582fcf3ce44SJohn Forte 		enum copy_direction direction, enum copy_wait wait_action)
2583fcf3ce44SJohn Forte {
2584fcf3ce44SJohn Forte 	dsw_ioctl_t copy_args;
2585fcf3ce44SJohn Forte 	dsw_config_t parms;
2586fcf3ce44SJohn Forte 	dsw_stat_t	stat_s;
2587fcf3ce44SJohn Forte 	int	rc;
2588fcf3ce44SJohn Forte 	int	wait_loc;
2589fcf3ce44SJohn Forte 	char	*t;
2590fcf3ce44SJohn Forte 	char	*volume;
2591fcf3ce44SJohn Forte 	pid_t	child = (pid_t)0;
2592fcf3ce44SJohn Forte 	char	*ppid;
2593fcf3ce44SJohn Forte 
2594fcf3ce44SJohn Forte 	if (vol_list[0] && vol_list[1])
2595fcf3ce44SJohn Forte 		return (do_acopy(vol_list, update_mode, direction));
2596fcf3ce44SJohn Forte 
2597fcf3ce44SJohn Forte 	volume = vol_list[0];
2598fcf3ce44SJohn Forte 	if (!find_shadow_config(volume, &parms, &copy_args))
2599fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
2600fcf3ce44SJohn Forte 		    "group"), NULL);
2601fcf3ce44SJohn Forte 
2602fcf3ce44SJohn Forte 	cfg_unlock(cfg);
2603fcf3ce44SJohn Forte 	config_locked = 0;
2604fcf3ce44SJohn Forte 	copy_args.flags = 0;
2605fcf3ce44SJohn Forte 
2606fcf3ce44SJohn Forte 	if (update_mode == Update)
2607fcf3ce44SJohn Forte 		copy_args.flags |= CV_BMP_ONLY;
2608fcf3ce44SJohn Forte 	if (direction == ToMaster) {
2609fcf3ce44SJohn Forte 		copy_args.flags |= CV_SHD2MST;
2610fcf3ce44SJohn Forte 		t = parms.master_vol;
2611fcf3ce44SJohn Forte 	} else {
2612fcf3ce44SJohn Forte 		t = parms.shadow_vol;
2613fcf3ce44SJohn Forte 	}
2614fcf3ce44SJohn Forte 	if (pflg) {
2615fcf3ce44SJohn Forte 		copy_args.flags |= CV_LOCK_PID;
2616fcf3ce44SJohn Forte #ifdef DEBUG
2617fcf3ce44SJohn Forte 		ppid = getenv("IIADM_PPID");
2618fcf3ce44SJohn Forte 		if (ppid) {
2619fcf3ce44SJohn Forte 			copy_args.pid = atoi(ppid);
2620570de38fSSurya Prakki 			(void) fprintf(stderr, "(using %s for ppid)\n", ppid);
2621fcf3ce44SJohn Forte 		} else {
2622fcf3ce44SJohn Forte 			copy_args.pid = getppid();
2623fcf3ce44SJohn Forte 		}
2624fcf3ce44SJohn Forte #else
2625fcf3ce44SJohn Forte 		copy_args.pid = getppid();
2626fcf3ce44SJohn Forte #endif
2627fcf3ce44SJohn Forte 	}
2628fcf3ce44SJohn Forte 
2629fcf3ce44SJohn Forte 	if (mounted(t)) {
2630fcf3ce44SJohn Forte 		errno = EBUSY;
2631fcf3ce44SJohn Forte 		dsw_error(gettext("Target of copy/update is mounted, "
2632fcf3ce44SJohn Forte 		    "unmount it first"), NULL);
2633fcf3ce44SJohn Forte 	}
2634fcf3ce44SJohn Forte 
2635*ea3068a7SRichard Lowe 	(void) strlcpy(stat_s.shadow_vol, copy_args.shadow_vol, DSW_NAMELEN);
2636fcf3ce44SJohn Forte 	stat_s.status = spcs_s_ucreate();
2637fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_STAT, &stat_s);
2638fcf3ce44SJohn Forte 	spcs_s_ufree(&stat_s.status);
2639fcf3ce44SJohn Forte 	if (rc == -1)
2640fcf3ce44SJohn Forte 		dsw_error(gettext("Shadow group suspended"), NULL);
2641fcf3ce44SJohn Forte 
2642fcf3ce44SJohn Forte 	if (stat_s.stat & DSW_COPYINGP) {
2643fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s: %s\n", cmdnam,
2644fcf3ce44SJohn Forte 		    gettext("Copy already in progress"));
2645fcf3ce44SJohn Forte 		exit(1);
2646fcf3ce44SJohn Forte 	}
2647fcf3ce44SJohn Forte 
2648fcf3ce44SJohn Forte 	copy_args.status = spcs_s_ucreate();
2649fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Start %s %s %s"),
2650*ea3068a7SRichard Lowe 	    update_mode == Update ? gettext("update") : gettext("copy"),
2651fcf3ce44SJohn Forte 	    volume,
2652fcf3ce44SJohn Forte 	    direction == ToMaster ?  gettext("from shadow") :
2653fcf3ce44SJohn Forte 	    gettext("to shadow"));
2654fcf3ce44SJohn Forte 
2655fcf3ce44SJohn Forte 	if (wait_action == WaitForStart)
2656570de38fSSurya Prakki 		(void) sigset(SIGCHLD, sigchild);
2657fcf3ce44SJohn Forte 	switch (child = fork()) {
2658fcf3ce44SJohn Forte 
2659fcf3ce44SJohn Forte 	case (pid_t)-1:
2660fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to fork"),
2661fcf3ce44SJohn Forte 		    NULL);
2662fcf3ce44SJohn Forte 		break;
2663fcf3ce44SJohn Forte 
2664fcf3ce44SJohn Forte 	case 0:
2665fcf3ce44SJohn Forte 		rc = do_ioctl(dsw_fd, DSWIOC_COPY, &copy_args);
2666fcf3ce44SJohn Forte 		if (rc == -1) {
2667fcf3ce44SJohn Forte 			spcs_log("ii", &copy_args.status,
2668fcf3ce44SJohn Forte 			    gettext("Fail %s %s %s"),
2669fcf3ce44SJohn Forte 			    update_mode == Update ?
2670fcf3ce44SJohn Forte 			    gettext("update") : gettext("copy"),
2671fcf3ce44SJohn Forte 			    volume,
2672*ea3068a7SRichard Lowe 			    direction == ToMaster ?
2673*ea3068a7SRichard Lowe 			    gettext("from shadow") : gettext("to shadow"));
2674fcf3ce44SJohn Forte 			dsw_error(gettext("Copy failed"), &copy_args.status);
2675fcf3ce44SJohn Forte 		}
2676fcf3ce44SJohn Forte 		spcs_s_ufree(&copy_args.status);
2677fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Finish %s %s %s"),
2678*ea3068a7SRichard Lowe 		    update_mode == Update ? gettext("update") : gettext("copy"),
2679fcf3ce44SJohn Forte 		    volume,
2680fcf3ce44SJohn Forte 		    direction == ToMaster ?  gettext("from shadow") :
2681fcf3ce44SJohn Forte 		    gettext("to shadow"));
2682fcf3ce44SJohn Forte 
2683fcf3ce44SJohn Forte 		exit(0);
2684fcf3ce44SJohn Forte 		break;
2685fcf3ce44SJohn Forte 	default:
2686fcf3ce44SJohn Forte 		if (wait_action == WaitForStart) {
2687fcf3ce44SJohn Forte 			rc = child_wait(child, CopyStart, copy_args.shadow_vol);
2688fcf3ce44SJohn Forte 		} else { /* wait_action == WaitForEnd */
2689fcf3ce44SJohn Forte 			wait_loc = 0;
2690570de38fSSurya Prakki 			(void) wait(&wait_loc);
2691fcf3ce44SJohn Forte 			if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0))
2692fcf3ce44SJohn Forte 				rc = 0;
2693fcf3ce44SJohn Forte 			else
2694fcf3ce44SJohn Forte 				rc = 1;
2695fcf3ce44SJohn Forte 		}
2696fcf3ce44SJohn Forte 		break;
2697fcf3ce44SJohn Forte 	}
2698fcf3ce44SJohn Forte 	return (rc);
2699fcf3ce44SJohn Forte }
2700fcf3ce44SJohn Forte 
2701fcf3ce44SJohn Forte void
2702fcf3ce44SJohn Forte print_status(dsw_config_t *conf, int in_config)
2703fcf3ce44SJohn Forte {
2704fcf3ce44SJohn Forte 	dsw_stat_t args;
2705fcf3ce44SJohn Forte 	int	stat_flags;
2706fcf3ce44SJohn Forte 	static int need_sep = 0;
2707fcf3ce44SJohn Forte 	time_t tmp_time;
2708fcf3ce44SJohn Forte 
2709fcf3ce44SJohn Forte 	if (need_sep++ > 0)
2710fcf3ce44SJohn Forte 		(void) printf("--------------------------------------"
2711fcf3ce44SJohn Forte 		    "----------------------------------------\n");
2712*ea3068a7SRichard Lowe 	(void) strlcpy(args.shadow_vol, conf->shadow_vol, DSW_NAMELEN);
2713fcf3ce44SJohn Forte 	if (in_config) {
2714fcf3ce44SJohn Forte 		(void) printf("%s: %s\n",
2715fcf3ce44SJohn Forte 		    conf->master_vol, gettext("(master volume)"));
2716fcf3ce44SJohn Forte 		(void) printf("%s: %s\n",
2717fcf3ce44SJohn Forte 		    conf->shadow_vol, gettext("(shadow volume)"));
2718fcf3ce44SJohn Forte 		(void) printf("%s: %s\n",
2719fcf3ce44SJohn Forte 		    conf->bitmap_vol, gettext("(bitmap volume)"));
2720fcf3ce44SJohn Forte 	}
2721fcf3ce44SJohn Forte 
2722fcf3ce44SJohn Forte 	/*
2723fcf3ce44SJohn Forte 	 * Do special checking on the status of this volume in a Sun Cluster
2724fcf3ce44SJohn Forte 	 */
2725fcf3ce44SJohn Forte 	if (check_cluster() == II_CLUSTER) {
2726fcf3ce44SJohn Forte 		char dgname[CFG_MAX_BUF], *other_node;
2727fcf3ce44SJohn Forte 
2728fcf3ce44SJohn Forte 		if (cfg_dgname(conf->bitmap_vol, dgname, sizeof (dgname))) {
2729fcf3ce44SJohn Forte 			if (strlen(dgname)) {
2730*ea3068a7SRichard Lowe 				int rc = cfg_dgname_islocal(dgname,
2731*ea3068a7SRichard Lowe 				    &other_node);
2732*ea3068a7SRichard Lowe 
2733fcf3ce44SJohn Forte 				if (rc < 0) {
2734fcf3ce44SJohn Forte 					(void) printf(gettext(
2735*ea3068a7SRichard Lowe 					    "Suspended on this node, "
2736*ea3068a7SRichard Lowe 					    "not active elsewhere\n"));
2737fcf3ce44SJohn Forte 					return;
2738fcf3ce44SJohn Forte 				} else if (rc == 0) {
2739fcf3ce44SJohn Forte 					(void) printf(gettext(
2740*ea3068a7SRichard Lowe 					    "Suspended on this node, "
2741*ea3068a7SRichard Lowe 					    "active on %s\n"), other_node);
2742fcf3ce44SJohn Forte 					return;
2743fcf3ce44SJohn Forte 				}
2744fcf3ce44SJohn Forte 			}
2745fcf3ce44SJohn Forte 		}
2746fcf3ce44SJohn Forte 	}
2747fcf3ce44SJohn Forte 
2748fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
2749fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) {
2750fcf3ce44SJohn Forte 
2751fcf3ce44SJohn Forte 		/* Handle Not found or not in config */
2752fcf3ce44SJohn Forte 		if (errno != DSW_ENOTFOUND || !in_config)
2753fcf3ce44SJohn Forte 			dsw_error(gettext("Stat failed"), &args.status);
2754fcf3ce44SJohn Forte 
2755fcf3ce44SJohn Forte 		/* Just suspend */
2756fcf3ce44SJohn Forte 		(void) printf(gettext("Suspended.\n"));
2757fcf3ce44SJohn Forte 		return;
2758fcf3ce44SJohn Forte 	}
2759fcf3ce44SJohn Forte 
2760fcf3ce44SJohn Forte 	if (args.overflow_vol[0] != '\0')
2761fcf3ce44SJohn Forte 		(void) printf("%s: %s\n", args.overflow_vol,
2762fcf3ce44SJohn Forte 		    gettext("(overflow volume)"));
2763fcf3ce44SJohn Forte 
2764fcf3ce44SJohn Forte 	if (conf->group_name[0] != '\0')
2765fcf3ce44SJohn Forte 		(void) printf(gettext("Group name: %s\n"),
2766fcf3ce44SJohn Forte 		    conf->group_name);
2767fcf3ce44SJohn Forte 
2768fcf3ce44SJohn Forte 	if (conf->cluster_tag[0] != '\0')
2769fcf3ce44SJohn Forte 		(void) printf(gettext("Cluster tag: %s\n"),
2770fcf3ce44SJohn Forte 		    conf->cluster_tag);
2771fcf3ce44SJohn Forte 
2772fcf3ce44SJohn Forte 	stat_flags = args.stat;
2773fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
2774fcf3ce44SJohn Forte 	if (stat_flags & DSW_GOLDEN)
2775fcf3ce44SJohn Forte 		(void) printf(gettext("Independent copy"));
2776fcf3ce44SJohn Forte 	else
2777fcf3ce44SJohn Forte 		(void) printf(gettext("Dependent copy"));
2778fcf3ce44SJohn Forte 
2779fcf3ce44SJohn Forte 	if (stat_flags & DSW_TREEMAP)
2780fcf3ce44SJohn Forte 		(void) printf(gettext(", compacted shadow space"));
2781fcf3ce44SJohn Forte 
2782fcf3ce44SJohn Forte 	if (stat_flags & DSW_COPYINGP)
2783fcf3ce44SJohn Forte 		(void) printf(gettext(", copy in progress"));
2784fcf3ce44SJohn Forte 	else if (stat_flags & DSW_COPYING)
2785fcf3ce44SJohn Forte 		(void) printf(gettext(", copy not active"));
2786fcf3ce44SJohn Forte 
2787fcf3ce44SJohn Forte 	if (stat_flags & DSW_COPYINGM)
2788fcf3ce44SJohn Forte 		(void) printf(gettext(", copying master to shadow"));
2789fcf3ce44SJohn Forte 
2790fcf3ce44SJohn Forte 	if (stat_flags & DSW_COPYINGS)
2791fcf3ce44SJohn Forte 		(void) printf(gettext(", copying shadow to master"));
2792fcf3ce44SJohn Forte 
2793fcf3ce44SJohn Forte 	if (stat_flags & DSW_COPYINGX)
2794fcf3ce44SJohn Forte 		(void) printf(gettext(", abort of copy requested"));
2795fcf3ce44SJohn Forte 
2796fcf3ce44SJohn Forte 	if (stat_flags & DSW_MSTOFFLINE)
2797fcf3ce44SJohn Forte 		(void) printf(gettext(", master volume offline"));
2798fcf3ce44SJohn Forte 
2799fcf3ce44SJohn Forte 	if (stat_flags & DSW_SHDOFFLINE)
2800fcf3ce44SJohn Forte 		(void) printf(gettext(", shadow volume offline"));
2801fcf3ce44SJohn Forte 
2802fcf3ce44SJohn Forte 	if (stat_flags & DSW_BMPOFFLINE)
2803fcf3ce44SJohn Forte 		(void) printf(gettext(", bitmap volume offline"));
2804fcf3ce44SJohn Forte 
2805fcf3ce44SJohn Forte 	if (stat_flags & DSW_OVROFFLINE)
2806fcf3ce44SJohn Forte 		(void) printf(gettext(", overflow volume offline"));
2807fcf3ce44SJohn Forte 
2808fcf3ce44SJohn Forte 	if (stat_flags & DSW_SHDEXPORT)
2809fcf3ce44SJohn Forte 		(void) printf(gettext(", shadow volume exported"));
2810fcf3ce44SJohn Forte 
2811fcf3ce44SJohn Forte 	if (stat_flags & DSW_SHDIMPORT)
2812fcf3ce44SJohn Forte 		(void) printf(gettext(", shadow volume imported"));
2813fcf3ce44SJohn Forte 
2814fcf3ce44SJohn Forte 	if (stat_flags & DSW_OVERFLOW)
2815fcf3ce44SJohn Forte 		(void) printf(gettext(", out of space"));
2816fcf3ce44SJohn Forte 
2817fcf3ce44SJohn Forte 	if (stat_flags & DSW_VOVERFLOW)
2818fcf3ce44SJohn Forte 		(void) printf(gettext(", spilled into overflow volume"));
2819fcf3ce44SJohn Forte 	(void) printf("\n");
2820fcf3ce44SJohn Forte 
2821fcf3ce44SJohn Forte 	tmp_time = args.mtime;
2822fcf3ce44SJohn Forte 	if (tmp_time != 0)
2823fcf3ce44SJohn Forte 		(void) printf("%s %s", gettext("Latest modified time:"),
2824fcf3ce44SJohn Forte 		    ctime(&tmp_time));
2825fcf3ce44SJohn Forte 	else
2826fcf3ce44SJohn Forte 		(void) printf("%s\n", gettext("Latest modified time: unknown"));
2827fcf3ce44SJohn Forte 
2828fcf3ce44SJohn Forte 	(void) printf("%s %8llu\n", gettext("Volume size:"), args.size);
2829fcf3ce44SJohn Forte 	if (args.shdsize != 0) {
2830fcf3ce44SJohn Forte 		(void) printf("%s %lld %s %lld\n",
2831fcf3ce44SJohn Forte 		    gettext("Shadow chunks total:"), args.shdsize,
2832fcf3ce44SJohn Forte 		    gettext("Shadow chunks used:"), args.shdused);
2833fcf3ce44SJohn Forte 	}
2834fcf3ce44SJohn Forte 	bitmap_op(args.shadow_vol, 0, 1, 0, 0);
2835fcf3ce44SJohn Forte }
2836fcf3ce44SJohn Forte 
2837fcf3ce44SJohn Forte int
2838fcf3ce44SJohn Forte abort_copy(char *volume)
2839fcf3ce44SJohn Forte {
2840fcf3ce44SJohn Forte 	dsw_ioctl_t args;
2841fcf3ce44SJohn Forte 
2842fcf3ce44SJohn Forte 	if (!find_shadow_config(volume, NULL, &args))
2843fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
2844fcf3ce44SJohn Forte 		    "group"), NULL);
2845fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
2846fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_ABORT, &args)  == -1)
2847fcf3ce44SJohn Forte 		dsw_error(gettext("Abort failed"), &args.status);
2848fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Abort %s"), args.shadow_vol);
2849fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
2850fcf3ce44SJohn Forte 	return (0);
2851fcf3ce44SJohn Forte }
2852fcf3ce44SJohn Forte 
2853fcf3ce44SJohn Forte void
2854fcf3ce44SJohn Forte iiversion()
2855fcf3ce44SJohn Forte {
2856fcf3ce44SJohn Forte 	dsw_version_t args;
2857fcf3ce44SJohn Forte 
2858fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
2859fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_VERSION, &args)  == -1)
2860fcf3ce44SJohn Forte 		dsw_error(gettext("Version failed"), &args.status);
2861fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
2862fcf3ce44SJohn Forte #ifdef DEBUG
2863fcf3ce44SJohn Forte 	(void) printf(gettext("Point in Time Copy version %d.%d.%d.%d\n"),
2864fcf3ce44SJohn Forte 	    args.major, args.minor, args.micro, args.baseline);
2865fcf3ce44SJohn Forte #else
2866fcf3ce44SJohn Forte 	if (args.micro) {
2867fcf3ce44SJohn Forte 		(void) printf(gettext("Point in Time Copy version %d.%d.%d\n"),
2868fcf3ce44SJohn Forte 		    args.major, args.minor, args.micro);
2869fcf3ce44SJohn Forte 	} else {
2870fcf3ce44SJohn Forte 		(void) printf(gettext("Point in Time Copy version %d.%d\n"),
2871fcf3ce44SJohn Forte 		    args.major, args.minor);
2872fcf3ce44SJohn Forte 	}
2873fcf3ce44SJohn Forte #endif
2874fcf3ce44SJohn Forte }
2875fcf3ce44SJohn Forte 
2876fcf3ce44SJohn Forte void
2877fcf3ce44SJohn Forte list_volumes()
2878fcf3ce44SJohn Forte {
2879fcf3ce44SJohn Forte 	dsw_list_t args;
2880fcf3ce44SJohn Forte 	int i, set, found;
2881fcf3ce44SJohn Forte 	dsw_config_t *lp;
2882fcf3ce44SJohn Forte 	ENTRY item, *ip;
2883fcf3ce44SJohn Forte 	dsw_config_t parms;
2884fcf3ce44SJohn Forte 
2885fcf3ce44SJohn Forte 	if ((i = do_ioctl(dsw_fd, DSWIOC_LISTLEN, &args)) == -1)
2886fcf3ce44SJohn Forte 		dsw_error("DSWIOC_LISTLEN", NULL);
2887fcf3ce44SJohn Forte 
2888fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
2889fcf3ce44SJohn Forte 	args.list_used = 0;
2890fcf3ce44SJohn Forte 	args.list_size = i + 4;
2891fcf3ce44SJohn Forte 	lp = args.list = (dsw_config_t *)
2892fcf3ce44SJohn Forte 	    malloc(args.list_size * sizeof (dsw_config_t));
2893fcf3ce44SJohn Forte 
2894fcf3ce44SJohn Forte 	if (args.list == NULL)
2895fcf3ce44SJohn Forte 		dsw_error(gettext("Failed to allocate memory"), NULL);
2896fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_LIST, &args)  == -1)
2897fcf3ce44SJohn Forte 		dsw_error(gettext("List failed"), &args.status);
2898fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
2899fcf3ce44SJohn Forte 
2900fcf3ce44SJohn Forte 	/* make a hashtable */
2901fcf3ce44SJohn Forte 	if (args.list_used > 0) {
2902fcf3ce44SJohn Forte 		if (hcreate(args.list_used) == 0) {
2903fcf3ce44SJohn Forte 			dsw_error(gettext("Failed to allocate memory"), NULL);
2904fcf3ce44SJohn Forte 			/*NOTREACHED*/
2905fcf3ce44SJohn Forte 		}
2906fcf3ce44SJohn Forte 	}
2907fcf3ce44SJohn Forte 
2908fcf3ce44SJohn Forte 	/* populate the hashtable */
2909fcf3ce44SJohn Forte 	for (i = 0; i < args.list_used; i++, lp++) {
2910fcf3ce44SJohn Forte 		item.key = lp->shadow_vol;
2911fcf3ce44SJohn Forte 		item.data = (char *)lp;
2912fcf3ce44SJohn Forte 		if (hsearch(item, ENTER) == NULL) {
2913fcf3ce44SJohn Forte 			dsw_error(gettext("Failed to allocate memory"), NULL);
2914fcf3ce44SJohn Forte 			/*NOTREACHED*/
2915fcf3ce44SJohn Forte 		}
2916fcf3ce44SJohn Forte 	}
2917fcf3ce44SJohn Forte 
2918fcf3ce44SJohn Forte 	/* perform action for each line of the stored config file */
2919fcf3ce44SJohn Forte 	for (set = 1; get_dsw_config(set, &parms) == 0; set++) {
2920fcf3ce44SJohn Forte 
2921fcf3ce44SJohn Forte 		/* Are there any II sets configured on this node? */
2922fcf3ce44SJohn Forte 		if (args.list_used > 0) {
2923fcf3ce44SJohn Forte 			item.key = parms.shadow_vol;
2924fcf3ce44SJohn Forte 
2925fcf3ce44SJohn Forte 			/* Is this volume configured on this node? */
2926fcf3ce44SJohn Forte 			if (ip = hsearch(item, FIND)) {
2927fcf3ce44SJohn Forte 
2928fcf3ce44SJohn Forte 				/* Handle Imported Shadows */
2929fcf3ce44SJohn Forte 				/* LINTED alignment of cast ok */
2930fcf3ce44SJohn Forte 				lp = (dsw_config_t *)ip->data;
2931fcf3ce44SJohn Forte 				if (strcmp(parms.master_vol,
2932fcf3ce44SJohn Forte 				    II_IMPORTED_SHADOW))
2933fcf3ce44SJohn Forte 					found = !(lp->flag & DSW_SHDIMPORT);
2934fcf3ce44SJohn Forte 				else
2935fcf3ce44SJohn Forte 					found = (lp->flag & DSW_SHDIMPORT);
2936fcf3ce44SJohn Forte 			}
2937fcf3ce44SJohn Forte 			else
2938fcf3ce44SJohn Forte 				found = FALSE;
2939fcf3ce44SJohn Forte 		}
2940fcf3ce44SJohn Forte 		else
2941fcf3ce44SJohn Forte 			found = FALSE;
2942fcf3ce44SJohn Forte 
2943fcf3ce44SJohn Forte 		if ((cfg_cluster_tag) &&
2944fcf3ce44SJohn Forte 		    strcmp(cfg_cluster_tag, parms.cluster_tag))
2945fcf3ce44SJohn Forte 			continue;
2946fcf3ce44SJohn Forte 
2947fcf3ce44SJohn Forte 		if ((group_name) && strcmp(group_name, parms.group_name))
2948fcf3ce44SJohn Forte 			continue;
2949fcf3ce44SJohn Forte 
2950fcf3ce44SJohn Forte 		(void) printf("%s %.*s %.*s %.*s%s\n",
2951fcf3ce44SJohn Forte 		    (parms.flag & DSW_GOLDEN) ? "ind" : "dep",
2952fcf3ce44SJohn Forte 		    DSW_NAMELEN, parms.master_vol,
2953fcf3ce44SJohn Forte 		    DSW_NAMELEN, parms.shadow_vol,
2954fcf3ce44SJohn Forte 		    DSW_NAMELEN, parms.bitmap_vol,
2955fcf3ce44SJohn Forte 		    found ? "" : gettext(" (suspended)"));
2956fcf3ce44SJohn Forte 	}
2957fcf3ce44SJohn Forte 	hdestroy();
2958fcf3ce44SJohn Forte 	free(args.list);
2959fcf3ce44SJohn Forte }
2960fcf3ce44SJohn Forte 
2961fcf3ce44SJohn Forte int
2962fcf3ce44SJohn Forte wait_for_copy(char *volume)
2963fcf3ce44SJohn Forte {
2964fcf3ce44SJohn Forte 	dsw_ioctl_t parms;
2965fcf3ce44SJohn Forte 	int rc;
2966fcf3ce44SJohn Forte 	static int unlocked = 0;
2967fcf3ce44SJohn Forte 	char *ppid;
2968fcf3ce44SJohn Forte 
2969fcf3ce44SJohn Forte 	if (unlocked && !ii_lock(cfg, CFG_RDLOCK)) {
2970fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to set locking on the configuration"),
2971fcf3ce44SJohn Forte 		    NULL);
2972fcf3ce44SJohn Forte 	}
2973fcf3ce44SJohn Forte 	config_locked = 1;
2974fcf3ce44SJohn Forte 	if (!find_shadow_config(volume, NULL, &parms))
2975fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
2976fcf3ce44SJohn Forte 		    "group"), NULL);
2977fcf3ce44SJohn Forte 	cfg_unlock(cfg);
2978fcf3ce44SJohn Forte 	config_locked = 0;
2979fcf3ce44SJohn Forte 	unlocked = 1;
2980fcf3ce44SJohn Forte 
2981fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
2982fcf3ce44SJohn Forte 	if (pflg) {
2983fcf3ce44SJohn Forte #ifdef DEBUG
2984fcf3ce44SJohn Forte 		ppid = getenv("IIADM_PPID");
2985fcf3ce44SJohn Forte 		if (ppid) {
2986fcf3ce44SJohn Forte 			parms.pid = atoi(ppid);
2987570de38fSSurya Prakki 			(void) fprintf(stderr, "(using %s for ppid)\n", ppid);
2988fcf3ce44SJohn Forte 		} else {
2989fcf3ce44SJohn Forte 			parms.pid = (nflg) ? -1 : getppid();
2990fcf3ce44SJohn Forte 		}
2991fcf3ce44SJohn Forte #else
2992fcf3ce44SJohn Forte 		parms.pid = (nflg) ? -1 : getppid();
2993fcf3ce44SJohn Forte #endif
2994fcf3ce44SJohn Forte 		parms.flags |= CV_LOCK_PID;
2995fcf3ce44SJohn Forte 	}
2996fcf3ce44SJohn Forte 
2997fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_WAIT, &parms);
2998fcf3ce44SJohn Forte 	if (rc == -1)
2999fcf3ce44SJohn Forte 		dsw_error(gettext("Wait failed"), &parms.status);
3000fcf3ce44SJohn Forte 	spcs_s_ufree(&parms.status);
3001fcf3ce44SJohn Forte 	return (0);
3002fcf3ce44SJohn Forte }
3003fcf3ce44SJohn Forte 
3004fcf3ce44SJohn Forte int
3005fcf3ce44SJohn Forte export(char *volume)
3006fcf3ce44SJohn Forte {
3007fcf3ce44SJohn Forte 	dsw_ioctl_t parms;
3008fcf3ce44SJohn Forte 	dsw_config_t conf;
3009fcf3ce44SJohn Forte 	char *old_ctag, dgname[DSW_NAMELEN];
3010fcf3ce44SJohn Forte 	int rc;
3011fcf3ce44SJohn Forte 
3012fcf3ce44SJohn Forte 	if (!find_shadow_config(volume, &conf, &parms))
3013fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
3014fcf3ce44SJohn Forte 		    "group"), NULL);
3015fcf3ce44SJohn Forte 	if (mounted(volume))
3016fcf3ce44SJohn Forte 		dsw_error(gettext("Can't export a mounted volume"), NULL);
3017fcf3ce44SJohn Forte 
3018fcf3ce44SJohn Forte 	/* If this is an exportable shadow in the cluster, change ctag */
3019fcf3ce44SJohn Forte 	if (strlen(conf.cluster_tag) &&
3020fcf3ce44SJohn Forte 	    (cfg_dgname(volume, dgname, sizeof (dgname)))) {
3021fcf3ce44SJohn Forte 		old_ctag = cfg_cluster_tag;
3022fcf3ce44SJohn Forte 		cfg_resource(cfg, cfg_cluster_tag = strdup(dgname));
3023fcf3ce44SJohn Forte 	} else	old_ctag = NULL;
3024fcf3ce44SJohn Forte 
3025fcf3ce44SJohn Forte 	if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) {
3026fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to parse config file"), NULL);
3027fcf3ce44SJohn Forte 	}
3028fcf3ce44SJohn Forte 	reload_vols = LD_DSVOLS | LD_SHADOWS;
3029fcf3ce44SJohn Forte 	conform_name(&volume);
3030fcf3ce44SJohn Forte 
3031fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Export %s"), volume);
3032fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
3033fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_EXPORT, &parms);
3034fcf3ce44SJohn Forte 	if (rc == -1)
3035fcf3ce44SJohn Forte 		dsw_error(gettext("Export failed"), &parms.status);
3036fcf3ce44SJohn Forte 	if (perform_autosv()) {
3037fcf3ce44SJohn Forte 		if (cfg_vol_disable(cfg, volume, cfg_cluster_tag, "ii") < 0) {
3038fcf3ce44SJohn Forte 			dsw_error(gettext("SV-disable failed"), NULL);
3039fcf3ce44SJohn Forte 		}
3040570de38fSSurya Prakki 		(void) cfg_commit(cfg);
3041fcf3ce44SJohn Forte 	}
3042fcf3ce44SJohn Forte 
3043fcf3ce44SJohn Forte 	/* restore old cluster tag, if changed */
3044fcf3ce44SJohn Forte 	if (old_ctag != NULL)
3045fcf3ce44SJohn Forte 		cfg_resource(cfg, cfg_cluster_tag = old_ctag);
3046fcf3ce44SJohn Forte 
3047fcf3ce44SJohn Forte 	spcs_s_ufree(&parms.status);
3048fcf3ce44SJohn Forte 	return (0);
3049fcf3ce44SJohn Forte }
3050fcf3ce44SJohn Forte 
3051fcf3ce44SJohn Forte int
3052fcf3ce44SJohn Forte detach(char *volume)
3053fcf3ce44SJohn Forte {
3054fcf3ce44SJohn Forte 	dsw_ioctl_t parms;
3055fcf3ce44SJohn Forte 	int rc;
3056fcf3ce44SJohn Forte 
3057fcf3ce44SJohn Forte 	if (!find_shadow_config(volume, NULL, &parms))
3058fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
3059fcf3ce44SJohn Forte 		    "group"), NULL);
3060fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
3061fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_ODETACH, &parms);
3062fcf3ce44SJohn Forte 	if (rc == 0) {
3063fcf3ce44SJohn Forte 		/* remove overflow from cfg line */
3064fcf3ce44SJohn Forte 		(void) sprintf(key, "ii.set%d.overflow", setnumber);
3065fcf3ce44SJohn Forte 		if (cfg_put_cstring(cfg, key, "-", 1) < 0) {
3066fcf3ce44SJohn Forte 				perror("cfg_put_cstring");
3067fcf3ce44SJohn Forte 		}
3068fcf3ce44SJohn Forte 		(void) cfg_commit(cfg);
3069fcf3ce44SJohn Forte 	} else {
3070fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Detach of overflow %s failed"),
3071fcf3ce44SJohn Forte 		    parms.shadow_vol);
3072fcf3ce44SJohn Forte 		dsw_error(gettext("Failed to detach overflow volume"),
3073fcf3ce44SJohn Forte 		    &parms.status);
3074fcf3ce44SJohn Forte 	}
3075fcf3ce44SJohn Forte 	return (rc);
3076fcf3ce44SJohn Forte }
3077fcf3ce44SJohn Forte 
3078fcf3ce44SJohn Forte static void
3079fcf3ce44SJohn Forte can_disable(char *vol)
3080fcf3ce44SJohn Forte {
3081fcf3ce44SJohn Forte 	dsw_stat_t args;
3082fcf3ce44SJohn Forte 
3083fcf3ce44SJohn Forte 	if (mounted(vol)) {
3084*ea3068a7SRichard Lowe 		(void) strlcpy(args.shadow_vol, vol, DSW_NAMELEN);
3085fcf3ce44SJohn Forte 		args.status = spcs_s_ucreate();
3086fcf3ce44SJohn Forte 		if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) != -1 &&
3087fcf3ce44SJohn Forte 		    (args.stat & DSW_GOLDEN) == 0) {
3088fcf3ce44SJohn Forte 			errno = EBUSY;
3089fcf3ce44SJohn Forte 			dsw_error(gettext("Shadow Volume is currently mounted "
3090fcf3ce44SJohn Forte 			    "and dependent on the master volume"), NULL);
3091fcf3ce44SJohn Forte 		}
3092fcf3ce44SJohn Forte 		spcs_s_ufree(&args.status);
3093fcf3ce44SJohn Forte 	}
3094fcf3ce44SJohn Forte }
3095fcf3ce44SJohn Forte 
3096fcf3ce44SJohn Forte static void
3097fcf3ce44SJohn Forte clean_up_after_failed_disable(dsw_ioctl_t *parms)
3098fcf3ce44SJohn Forte {
3099fcf3ce44SJohn Forte 	char **p;
3100fcf3ce44SJohn Forte 	dsw_stat_t args;
3101fcf3ce44SJohn Forte 
3102fcf3ce44SJohn Forte 	for (p = group_volumes; *p; p++) {
3103*ea3068a7SRichard Lowe 		(void) strlcpy(args.shadow_vol, *p, DSW_NAMELEN);
3104fcf3ce44SJohn Forte 		args.status = spcs_s_ucreate();
3105fcf3ce44SJohn Forte 		if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) {
3106fcf3ce44SJohn Forte 			/* set was successfully disabled */
3107fcf3ce44SJohn Forte 			if (find_shadow_config(*p, NULL, NULL))
3108fcf3ce44SJohn Forte 				remove_iiset(setnumber, *p, 0);
3109fcf3ce44SJohn Forte 		}
3110fcf3ce44SJohn Forte 		spcs_s_ufree(&args.status);
3111fcf3ce44SJohn Forte 	}
3112fcf3ce44SJohn Forte 
3113fcf3ce44SJohn Forte 	dsw_error(gettext("Some sets in the group failed to disable"),
3114fcf3ce44SJohn Forte 	    &parms->status);
3115fcf3ce44SJohn Forte }
3116fcf3ce44SJohn Forte 
3117fcf3ce44SJohn Forte int
3118fcf3ce44SJohn Forte dsw_group_or_single_disable(int argc, char *argv[])
3119fcf3ce44SJohn Forte {
3120fcf3ce44SJohn Forte 	int rc = 0;
3121fcf3ce44SJohn Forte 	char **p;
3122fcf3ce44SJohn Forte 	dsw_ioctl_t parms;
3123fcf3ce44SJohn Forte 	int flags = 0;
3124fcf3ce44SJohn Forte 	dsw_config_t conf;
3125fcf3ce44SJohn Forte 	int shd_exported = 0;
3126fcf3ce44SJohn Forte 
3127fcf3ce44SJohn Forte 	if (argc != 2)
3128fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3129fcf3ce44SJohn Forte 
3130fcf3ce44SJohn Forte 	if (group_name) {
3131fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3132fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3133fcf3ce44SJohn Forte 			    "has no members"), NULL);
3134fcf3ce44SJohn Forte 		for (p = group_volumes; *p; p++) {
3135fcf3ce44SJohn Forte 			can_disable(*p);
3136fcf3ce44SJohn Forte 		}
3137fcf3ce44SJohn Forte 
3138570de38fSSurya Prakki 		(void) strncpy(parms.shadow_vol, group_name, DSW_NAMELEN);
3139fcf3ce44SJohn Forte 		if (*group_name)
3140fcf3ce44SJohn Forte 			flags = CV_IS_GROUP;
3141fcf3ce44SJohn Forte 	} else {
3142fcf3ce44SJohn Forte 		if (!find_shadow_config(argv[1], &conf, &parms)) {
3143fcf3ce44SJohn Forte 			dsw_error(gettext("Volume is not in a Point-in-Time "
3144fcf3ce44SJohn Forte 			    "Copy group"), NULL);
3145fcf3ce44SJohn Forte 		}
3146fcf3ce44SJohn Forte 
3147fcf3ce44SJohn Forte 		can_disable(argv[1]);
3148fcf3ce44SJohn Forte 		flags = 0;
3149fcf3ce44SJohn Forte 	}
3150fcf3ce44SJohn Forte 
3151fcf3ce44SJohn Forte 	if (group_name && !*group_name) {
3152fcf3ce44SJohn Forte 		/* user typed iiadm -g "" -d */
3153fcf3ce44SJohn Forte 		for (p = group_volumes; *p; p++) {
3154fcf3ce44SJohn Forte 			parms.status = spcs_s_ucreate();
3155fcf3ce44SJohn Forte 			parms.flags = flags;
3156570de38fSSurya Prakki 			(void) strncpy(parms.shadow_vol, *p, DSW_NAMELEN);
3157fcf3ce44SJohn Forte 			rc = do_ioctl(dsw_fd, DSWIOC_DISABLE, &parms);
3158fcf3ce44SJohn Forte 			if (rc == -1 && errno != DSW_ENOTFOUND)
3159fcf3ce44SJohn Forte 				dsw_error(gettext("Disable failed"),
3160fcf3ce44SJohn Forte 				    &parms.status);
3161fcf3ce44SJohn Forte 			if (!find_shadow_config(*p, NULL, NULL))
3162fcf3ce44SJohn Forte 				dsw_error(gettext("Volume is not in a Point-in"
3163fcf3ce44SJohn Forte 				    "-Time Copy group"), &parms.status);
3164fcf3ce44SJohn Forte 			remove_iiset(setnumber, *p, 0);
3165fcf3ce44SJohn Forte 			spcs_s_ufree(&parms.status);
3166fcf3ce44SJohn Forte 			spcs_log("ii", NULL, gettext("Disabled %s"),
3167fcf3ce44SJohn Forte 			    parms.shadow_vol);
3168fcf3ce44SJohn Forte 		}
3169fcf3ce44SJohn Forte 	} else {
3170fcf3ce44SJohn Forte 		if (is_exported(conf.shadow_vol)) {
3171fcf3ce44SJohn Forte 			shd_exported = 1;
3172fcf3ce44SJohn Forte 		}
3173fcf3ce44SJohn Forte 		if ((strcmp(conf.master_vol, II_IMPORTED_SHADOW) == 0) &&
3174fcf3ce44SJohn Forte 		    is_exported(conf.shadow_vol)) {
3175fcf3ce44SJohn Forte 			dsw_error(gettext(
3176fcf3ce44SJohn Forte 			"Imported shadow not disabled"), NULL);
3177fcf3ce44SJohn Forte 		}
3178fcf3ce44SJohn Forte 
3179fcf3ce44SJohn Forte 		parms.status = spcs_s_ucreate();
3180fcf3ce44SJohn Forte 		parms.flags = flags;
3181fcf3ce44SJohn Forte 		rc = do_ioctl(dsw_fd, DSWIOC_DISABLE, &parms);
3182fcf3ce44SJohn Forte 		if (rc == -1 && errno != DSW_ENOTFOUND) {
3183fcf3ce44SJohn Forte 			if (errno == DSW_EDISABLE) {
3184fcf3ce44SJohn Forte 				/*
3185fcf3ce44SJohn Forte 				 * one or more sets within the group
3186fcf3ce44SJohn Forte 				 * couldn't disable
3187fcf3ce44SJohn Forte 				 */
3188fcf3ce44SJohn Forte 				clean_up_after_failed_disable(&parms);
3189fcf3ce44SJohn Forte 			} else {
3190fcf3ce44SJohn Forte 				dsw_error(gettext("Disable failed"),
3191fcf3ce44SJohn Forte 				    &parms.status);
3192fcf3ce44SJohn Forte 			}
3193fcf3ce44SJohn Forte 		}
3194fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Disabled %s"), parms.shadow_vol);
3195fcf3ce44SJohn Forte 	}
3196fcf3ce44SJohn Forte 
3197fcf3ce44SJohn Forte 
3198fcf3ce44SJohn Forte 	if (group_name && *group_name) {
3199fcf3ce44SJohn Forte 		for (p = group_volumes; *p; p++) {
3200fcf3ce44SJohn Forte 			if (!find_shadow_config(*p, NULL, NULL)) {
3201fcf3ce44SJohn Forte 				/* argh! */
3202570de38fSSurya Prakki 				(void) fprintf(stderr,
3203570de38fSSurya Prakki 				    gettext("Volume '%s' is not "
3204fcf3ce44SJohn Forte 				    "in a Point-in-Time Copy group"), *p);
3205fcf3ce44SJohn Forte 			} else {
3206fcf3ce44SJohn Forte 				remove_iiset(setnumber, *p, 0);
3207fcf3ce44SJohn Forte 			}
3208fcf3ce44SJohn Forte 		}
3209fcf3ce44SJohn Forte 	} else if (!group_name) {
3210fcf3ce44SJohn Forte 		if (!find_shadow_config(argv[1], NULL, NULL)) {
3211fcf3ce44SJohn Forte 			/* argh! */
3212fcf3ce44SJohn Forte 			dsw_error(gettext("Volume is not in a Point-in-Time "
3213fcf3ce44SJohn Forte 			    "Copy group"), NULL);
3214fcf3ce44SJohn Forte 		}
3215fcf3ce44SJohn Forte 
3216fcf3ce44SJohn Forte 		remove_iiset(setnumber, argv[1], shd_exported);
3217fcf3ce44SJohn Forte 	}
3218fcf3ce44SJohn Forte 
3219fcf3ce44SJohn Forte 	return (0);
3220fcf3ce44SJohn Forte }
3221fcf3ce44SJohn Forte 
3222fcf3ce44SJohn Forte int
3223fcf3ce44SJohn Forte dsw_group_or_single_op(int argc, char *argv[], int (*op)(char *))
3224fcf3ce44SJohn Forte {
3225fcf3ce44SJohn Forte 	int rc = 0;
3226fcf3ce44SJohn Forte 
3227fcf3ce44SJohn Forte 	if (argc != 2)
3228fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3229fcf3ce44SJohn Forte 
3230fcf3ce44SJohn Forte 	if (group_name) {
3231fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3232fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3233*ea3068a7SRichard Lowe 			    "has no members"), NULL);
3234fcf3ce44SJohn Forte 		for (; *group_volumes; group_volumes++)
3235fcf3ce44SJohn Forte 			rc |= (*op)(*group_volumes);
3236fcf3ce44SJohn Forte 	} else {
3237fcf3ce44SJohn Forte 		rc = (*op)(argv[1]);
3238fcf3ce44SJohn Forte 	}
3239fcf3ce44SJohn Forte 	return (rc);
3240fcf3ce44SJohn Forte }
3241fcf3ce44SJohn Forte 
3242fcf3ce44SJohn Forte void
3243fcf3ce44SJohn Forte dsw_list_clusters(char *cluster)
3244fcf3ce44SJohn Forte {
3245fcf3ce44SJohn Forte 	dsw_aioctl_t *acopy_args;
3246fcf3ce44SJohn Forte 	int rc, i, count;
3247fcf3ce44SJohn Forte 	char *ptr;
3248fcf3ce44SJohn Forte 
3249fcf3ce44SJohn Forte 	if ((count = do_ioctl(dsw_fd, DSWIOC_LISTLEN, NULL)) < 0)
3250fcf3ce44SJohn Forte 		dsw_error("DSWIOC_LISTLEN", NULL);
3251fcf3ce44SJohn Forte 
3252fcf3ce44SJohn Forte 	acopy_args = malloc(sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
3253fcf3ce44SJohn Forte 	if (acopy_args == NULL)
3254fcf3ce44SJohn Forte 		dsw_error(gettext("Can't get memory for list enquiry"), NULL);
3255fcf3ce44SJohn Forte 
3256fcf3ce44SJohn Forte 	bzero(acopy_args, sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
3257fcf3ce44SJohn Forte 	acopy_args->count = count;
3258fcf3ce44SJohn Forte 	acopy_args->flags = 0;
3259fcf3ce44SJohn Forte 	acopy_args->status = spcs_s_ucreate();
3260fcf3ce44SJohn Forte 	if (cluster)
3261570de38fSSurya Prakki 		(void) strncpy(acopy_args->shadow_vol, cluster, DSW_NAMELEN);
3262fcf3ce44SJohn Forte 
3263fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_CLIST, acopy_args);
3264fcf3ce44SJohn Forte 	if (rc == -1)
3265fcf3ce44SJohn Forte 		dsw_error(gettext("Cluster list access failure"),
3266fcf3ce44SJohn Forte 		    &acopy_args->status);
3267fcf3ce44SJohn Forte 
3268fcf3ce44SJohn Forte 	acopy_args->shadow_vol[DSW_NAMELEN*acopy_args->count] = NULL;
3269fcf3ce44SJohn Forte 
3270fcf3ce44SJohn Forte 	if (cluster) {
3271570de38fSSurya Prakki 		(void) printf(gettext("Sets in cluster resource group %s:\n"),
3272fcf3ce44SJohn Forte 		    cluster);
3273fcf3ce44SJohn Forte 	} else {
3274570de38fSSurya Prakki 		(void) printf(
3275570de38fSSurya Prakki 		    gettext("Currently configured resource groups\n"));
3276fcf3ce44SJohn Forte 	}
3277fcf3ce44SJohn Forte 	for (i = 0, ptr = acopy_args->shadow_vol; *ptr &&
3278fcf3ce44SJohn Forte 	    i < acopy_args->count; i++, ptr += DSW_NAMELEN) {
3279570de38fSSurya Prakki 		(void) printf("  %-64.64s\n", ptr);
3280fcf3ce44SJohn Forte 	}
3281fcf3ce44SJohn Forte }
3282fcf3ce44SJohn Forte 
3283fcf3ce44SJohn Forte void
3284fcf3ce44SJohn Forte dsw_enable(int argc, char *argv[])
3285fcf3ce44SJohn Forte {
3286fcf3ce44SJohn Forte 	if (argc != 5)
3287fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3288fcf3ce44SJohn Forte 
3289fcf3ce44SJohn Forte 	enable(argv[1], argv[2], argv[3], argv[4]);
3290fcf3ce44SJohn Forte 	exit(0);
3291fcf3ce44SJohn Forte }
3292fcf3ce44SJohn Forte 
3293fcf3ce44SJohn Forte 
3294fcf3ce44SJohn Forte void
3295fcf3ce44SJohn Forte dsw_disable(int argc, char *argv[])
3296fcf3ce44SJohn Forte {
3297fcf3ce44SJohn Forte 	(void) dsw_group_or_single_disable(argc, argv);
3298fcf3ce44SJohn Forte 	exit(0);
3299fcf3ce44SJohn Forte }
3300fcf3ce44SJohn Forte 
3301fcf3ce44SJohn Forte 
3302fcf3ce44SJohn Forte void
3303fcf3ce44SJohn Forte dsw_copy_to_shadow(int argc, char *argv[])
3304fcf3ce44SJohn Forte {
3305fcf3ce44SJohn Forte 	char	**volume_list;
3306fcf3ce44SJohn Forte 
3307fcf3ce44SJohn Forte 	if (argc != 2)
3308fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3309fcf3ce44SJohn Forte 	if (group_name == NULL)
3310fcf3ce44SJohn Forte 		volume_list = ++argv;
3311fcf3ce44SJohn Forte 	else {
3312fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3313fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3314*ea3068a7SRichard Lowe 			    "has no members"), NULL);
3315fcf3ce44SJohn Forte 		volume_list = group_volumes;
3316fcf3ce44SJohn Forte 	}
3317fcf3ce44SJohn Forte 
3318fcf3ce44SJohn Forte 	exit(do_copy(volume_list, Copy, ToShadow, WaitForStart));
3319fcf3ce44SJohn Forte }
3320fcf3ce44SJohn Forte 
3321fcf3ce44SJohn Forte 
3322fcf3ce44SJohn Forte void
3323fcf3ce44SJohn Forte dsw_update_shadow(int argc, char *argv[])
3324fcf3ce44SJohn Forte {
3325fcf3ce44SJohn Forte 	char	**volume_list;
3326fcf3ce44SJohn Forte 
3327fcf3ce44SJohn Forte 	if (argc != 2)
3328fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3329fcf3ce44SJohn Forte 	if (group_name == NULL)
3330fcf3ce44SJohn Forte 		volume_list = ++argv;
3331fcf3ce44SJohn Forte 	else {
3332fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3333fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3334*ea3068a7SRichard Lowe 			    "has no members"), NULL);
3335fcf3ce44SJohn Forte 		volume_list = group_volumes;
3336fcf3ce44SJohn Forte 	}
3337fcf3ce44SJohn Forte 
3338fcf3ce44SJohn Forte 	exit(do_copy(volume_list, Update, ToShadow, WaitForStart));
3339fcf3ce44SJohn Forte }
3340fcf3ce44SJohn Forte 
3341fcf3ce44SJohn Forte 
3342fcf3ce44SJohn Forte void
3343fcf3ce44SJohn Forte dsw_copy_to_master(int argc, char *argv[])
3344fcf3ce44SJohn Forte {
3345fcf3ce44SJohn Forte 	char	**volume_list;
3346fcf3ce44SJohn Forte 
3347fcf3ce44SJohn Forte 	if (argc != 2)
3348fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3349fcf3ce44SJohn Forte 	if (group_name == NULL) {
3350fcf3ce44SJohn Forte 		volume_list = ++argv;
3351fcf3ce44SJohn Forte 		check_action(gettext("Overwrite master with shadow volume?"));
3352fcf3ce44SJohn Forte 	} else {
3353fcf3ce44SJohn Forte 		check_action(gettext("Overwrite every"
3354fcf3ce44SJohn Forte 		    " master in this group with its shadow volume?"));
3355fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3356fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3357*ea3068a7SRichard Lowe 			    "has no members"), NULL);
3358fcf3ce44SJohn Forte 		volume_list = group_volumes;
3359fcf3ce44SJohn Forte 	}
3360fcf3ce44SJohn Forte 
3361fcf3ce44SJohn Forte 	exit(do_copy(volume_list, Copy, ToMaster, WaitForStart));
3362fcf3ce44SJohn Forte }
3363fcf3ce44SJohn Forte 
3364fcf3ce44SJohn Forte 
3365fcf3ce44SJohn Forte void
3366fcf3ce44SJohn Forte dsw_update_master(int argc, char *argv[])
3367fcf3ce44SJohn Forte {
3368fcf3ce44SJohn Forte 	char	**volume_list;
3369fcf3ce44SJohn Forte 
3370fcf3ce44SJohn Forte 	if (argc != 2)
3371fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3372fcf3ce44SJohn Forte 	if (group_name == NULL) {
3373fcf3ce44SJohn Forte 		volume_list = ++argv;
3374fcf3ce44SJohn Forte 		check_action(gettext("Overwrite master with shadow volume?"));
3375fcf3ce44SJohn Forte 	} else {
3376fcf3ce44SJohn Forte 		check_action(gettext("Overwrite every"
3377fcf3ce44SJohn Forte 		    " master in this group with its shadow volume?"));
3378fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3379fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3380*ea3068a7SRichard Lowe 			    "has no members"), NULL);
3381fcf3ce44SJohn Forte 		volume_list = group_volumes;
3382fcf3ce44SJohn Forte 	}
3383fcf3ce44SJohn Forte 
3384fcf3ce44SJohn Forte 	exit(do_copy(volume_list, Update, ToMaster, WaitForStart));
3385fcf3ce44SJohn Forte }
3386fcf3ce44SJohn Forte 
3387fcf3ce44SJohn Forte 
3388fcf3ce44SJohn Forte void
3389fcf3ce44SJohn Forte dsw_abort_copy(int argc, char *argv[])
3390fcf3ce44SJohn Forte {
3391fcf3ce44SJohn Forte 	exit(dsw_group_or_single_op(argc, argv, abort_copy));
3392fcf3ce44SJohn Forte }
3393fcf3ce44SJohn Forte 
3394fcf3ce44SJohn Forte 
3395fcf3ce44SJohn Forte void
3396fcf3ce44SJohn Forte dsw_display_status(int argc, char *argv[])
3397fcf3ce44SJohn Forte {
3398fcf3ce44SJohn Forte 	dsw_config_t parms;
3399fcf3ce44SJohn Forte 	int	in_config;
3400fcf3ce44SJohn Forte 
3401fcf3ce44SJohn Forte 	if (argc != 2 && argc != 1)
3402fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3403fcf3ce44SJohn Forte 
3404fcf3ce44SJohn Forte 	/* "iiadm -i" and "iiadm -i all" are equivalent */
3405fcf3ce44SJohn Forte 	if (argc == 2 && strcmp("all", argv[1]) != 0) {
3406fcf3ce44SJohn Forte 		in_config = find_shadow_config(argv[1], &parms, NULL);
3407fcf3ce44SJohn Forte 		if (!in_config) {
3408fcf3ce44SJohn Forte 			(void) printf(gettext(
3409fcf3ce44SJohn Forte 			    "Volume is not in configuration file\n"), NULL);
3410fcf3ce44SJohn Forte 			(void) fflush(stdout);
3411*ea3068a7SRichard Lowe 			(void) strlcpy(parms.shadow_vol, argv[1], DSW_NAMELEN);
3412fcf3ce44SJohn Forte 		}
3413fcf3ce44SJohn Forte 		print_status(&parms, in_config);
3414fcf3ce44SJohn Forte 	} else if (group_name) {
3415fcf3ce44SJohn Forte 		if (find_group_members(group_name) < 1)
3416fcf3ce44SJohn Forte 			dsw_error(gettext("Group does not exist or "
3417*ea3068a7SRichard Lowe 			    "has no members"), NULL);
3418fcf3ce44SJohn Forte 		for (; *group_volumes; group_volumes++) {
3419fcf3ce44SJohn Forte 			in_config = find_shadow_config(*group_volumes,
3420fcf3ce44SJohn Forte 			    &parms, NULL);
3421fcf3ce44SJohn Forte 			if (in_config)
3422fcf3ce44SJohn Forte 				print_status(&parms, in_config);
3423fcf3ce44SJohn Forte 		}
3424fcf3ce44SJohn Forte 	} else {
3425fcf3ce44SJohn Forte 		/* perform action for each line of the stored config file */
3426fcf3ce44SJohn Forte 		for (setnumber = 1;
3427fcf3ce44SJohn Forte 		    !get_dsw_config(setnumber, &parms); setnumber++) {
3428fcf3ce44SJohn Forte 			switch (check_cluster()) {
3429fcf3ce44SJohn Forte 			case II_CLUSTER:
3430fcf3ce44SJohn Forte 				if ((cfg_cluster_tag) &&
3431*ea3068a7SRichard Lowe 				    (strcmp(cfg_cluster_tag,
3432*ea3068a7SRichard Lowe 				    parms.cluster_tag)))
3433fcf3ce44SJohn Forte 					continue;
3434fcf3ce44SJohn Forte 				break;
3435fcf3ce44SJohn Forte 			case II_CLUSTER_LCL:
3436fcf3ce44SJohn Forte 				if (strlen(parms.cluster_tag))
3437fcf3ce44SJohn Forte 					continue;
3438fcf3ce44SJohn Forte 				break;
3439fcf3ce44SJohn Forte 			}
3440fcf3ce44SJohn Forte 			print_status(&parms, 1);
3441fcf3ce44SJohn Forte 		}
3442fcf3ce44SJohn Forte 	}
3443fcf3ce44SJohn Forte 	exit(0);
3444fcf3ce44SJohn Forte }
3445fcf3ce44SJohn Forte 
3446fcf3ce44SJohn Forte void
3447fcf3ce44SJohn Forte dsw_display_bitmap(int argc, char *argv[])
3448fcf3ce44SJohn Forte {
3449fcf3ce44SJohn Forte 	dsw_config_t parms;
3450fcf3ce44SJohn Forte 	int	in_config;
3451fcf3ce44SJohn Forte 
3452fcf3ce44SJohn Forte 	if (argc != 2)
3453fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3454fcf3ce44SJohn Forte 
3455fcf3ce44SJohn Forte 	in_config = find_shadow_config(argv[1], &parms, NULL);
3456fcf3ce44SJohn Forte 	if (!in_config) {
3457fcf3ce44SJohn Forte 		(void) printf(gettext(
3458fcf3ce44SJohn Forte 		    "Volume is not in configuration file\n"), NULL);
3459fcf3ce44SJohn Forte 		(void) fflush(stdout);
3460*ea3068a7SRichard Lowe 		(void) strlcpy(parms.master_vol, argv[1], DSW_NAMELEN);
3461fcf3ce44SJohn Forte 	}
3462fcf3ce44SJohn Forte 
3463fcf3ce44SJohn Forte 	bitmap_op(parms.shadow_vol, 1, 0, 0, 0);
3464fcf3ce44SJohn Forte 	exit(0);
3465fcf3ce44SJohn Forte }
3466fcf3ce44SJohn Forte 
3467fcf3ce44SJohn Forte 
3468fcf3ce44SJohn Forte /*ARGSUSED*/
3469fcf3ce44SJohn Forte void
3470fcf3ce44SJohn Forte dsw_version(int argc, char *argv[])
3471fcf3ce44SJohn Forte {
3472fcf3ce44SJohn Forte 	iiversion();
3473fcf3ce44SJohn Forte 	exit(0);
3474fcf3ce44SJohn Forte }
3475fcf3ce44SJohn Forte 
3476fcf3ce44SJohn Forte void
3477fcf3ce44SJohn Forte dsw_reset(int argc, char *argv[])
3478fcf3ce44SJohn Forte {
3479fcf3ce44SJohn Forte 	exit(dsw_group_or_single_op(argc, argv, reset));
3480fcf3ce44SJohn Forte }
3481fcf3ce44SJohn Forte 
3482fcf3ce44SJohn Forte void
3483fcf3ce44SJohn Forte dsw_overflow(int argc, char *argv[])
3484fcf3ce44SJohn Forte {
3485fcf3ce44SJohn Forte 	if (argc != 2)
3486fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3487fcf3ce44SJohn Forte 
3488fcf3ce44SJohn Forte 	exit(overflow(argv[1]));
3489fcf3ce44SJohn Forte }
3490fcf3ce44SJohn Forte 
3491fcf3ce44SJohn Forte void
3492fcf3ce44SJohn Forte dsw_wait(int argc, char *argv[])
3493fcf3ce44SJohn Forte {
3494fcf3ce44SJohn Forte 	exit(dsw_group_or_single_op(argc, argv, wait_for_copy));
3495fcf3ce44SJohn Forte }
3496fcf3ce44SJohn Forte 
3497fcf3ce44SJohn Forte /*ARGSUSED*/
3498fcf3ce44SJohn Forte void
3499fcf3ce44SJohn Forte dsw_list_volumes(int argc, char *argv[])
3500fcf3ce44SJohn Forte {
3501fcf3ce44SJohn Forte 	if (argc != 1)
3502fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3503fcf3ce44SJohn Forte 
3504fcf3ce44SJohn Forte 	list_volumes();
3505fcf3ce44SJohn Forte 	exit(0);
3506fcf3ce44SJohn Forte }
3507fcf3ce44SJohn Forte 
3508fcf3ce44SJohn Forte void
3509fcf3ce44SJohn Forte dsw_export(int argc, char *argv[])
3510fcf3ce44SJohn Forte {
3511fcf3ce44SJohn Forte 	if (argc != 2)
3512fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3513fcf3ce44SJohn Forte 
3514fcf3ce44SJohn Forte 	exit(dsw_group_or_single_op(argc, argv, export));
3515fcf3ce44SJohn Forte }
3516fcf3ce44SJohn Forte 
3517fcf3ce44SJohn Forte void
3518fcf3ce44SJohn Forte dsw_detach(int argc, char *argv[])
3519fcf3ce44SJohn Forte {
3520fcf3ce44SJohn Forte 	(void) dsw_group_or_single_op(argc, argv, detach);
3521fcf3ce44SJohn Forte 	exit(0);
3522fcf3ce44SJohn Forte }
3523fcf3ce44SJohn Forte 
3524fcf3ce44SJohn Forte void
3525fcf3ce44SJohn Forte import(char *shadow_volume, char *bitmap_volume)
3526fcf3ce44SJohn Forte {
3527fcf3ce44SJohn Forte 	dsw_config_t parms = {0};
3528fcf3ce44SJohn Forte 	int rc = 0;
3529fcf3ce44SJohn Forte 	char	shd_dg[DSW_NAMELEN];
3530fcf3ce44SJohn Forte 	char	bmp_dg[DSW_NAMELEN];
3531fcf3ce44SJohn Forte 
3532fcf3ce44SJohn Forte 	/*
3533fcf3ce44SJohn Forte 	 * If importing a shadow volume and the shadow volume is already
3534fcf3ce44SJohn Forte 	 * configured, we only support this if we are in a Sun Cluster
3535fcf3ce44SJohn Forte 	 * and the current user specified a cluster tag of -C local
3536fcf3ce44SJohn Forte 	 */
3537fcf3ce44SJohn Forte 	if (find_shadow_config(shadow_volume, &parms, NULL)) {
3538fcf3ce44SJohn Forte 		dsw_error(gettext("Can't import volume on same node"), NULL);
3539fcf3ce44SJohn Forte 	}
3540fcf3ce44SJohn Forte 
3541fcf3ce44SJohn Forte 	switch (check_cluster()) {
3542fcf3ce44SJohn Forte 	case II_CLUSTER:
3543fcf3ce44SJohn Forte 	case II_CLUSTER_LCL:
3544fcf3ce44SJohn Forte 		(void) check_resource_group(shadow_volume);
3545fcf3ce44SJohn Forte 		if (cfg_cluster_tag) { /* check all volumes are in same dg */
3546fcf3ce44SJohn Forte 			if (cfg_dgname(shadow_volume, shd_dg, DSW_NAMELEN)
3547fcf3ce44SJohn Forte 			    == NULL)
3548fcf3ce44SJohn Forte 				dsw_error(gettext("Shadow volume not in a"
3549fcf3ce44SJohn Forte 				    " disk group"), NULL);
3550fcf3ce44SJohn Forte 			if (cfg_dgname(bitmap_volume, bmp_dg, DSW_NAMELEN)
3551fcf3ce44SJohn Forte 			    == NULL)
3552fcf3ce44SJohn Forte 				dsw_error(gettext("Bitmap volume not in a"
3553fcf3ce44SJohn Forte 				    " disk group"), NULL);
3554fcf3ce44SJohn Forte 			if (strcmp(bmp_dg, shd_dg) != 0)
3555fcf3ce44SJohn Forte 				dsw_error(gettext("Bitmap volume not in"
3556fcf3ce44SJohn Forte 				    " same disk group as shadow set members"),
3557fcf3ce44SJohn Forte 				    NULL);
3558fcf3ce44SJohn Forte 		}
3559fcf3ce44SJohn Forte 		break;
3560fcf3ce44SJohn Forte 	case II_NOT_CLUSTER:
3561fcf3ce44SJohn Forte 		/* do nothing */
3562fcf3ce44SJohn Forte 		break;
3563fcf3ce44SJohn Forte 	default:
3564fcf3ce44SJohn Forte 		dsw_error(gettext(
3565fcf3ce44SJohn Forte 		    "Unexpected return from check_cluster()"), NULL);
3566fcf3ce44SJohn Forte 	}
3567fcf3ce44SJohn Forte 
3568fcf3ce44SJohn Forte 	/* Local configuration volumes */
3569fcf3ce44SJohn Forte 	if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) {
3570fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to parse config file"), NULL);
3571fcf3ce44SJohn Forte 	}
3572fcf3ce44SJohn Forte 
3573fcf3ce44SJohn Forte 	reload_vols = LD_DSVOLS | LD_SHADOWS;
3574fcf3ce44SJohn Forte 	conform_name(&shadow_volume);
3575570de38fSSurya Prakki 	(void) strcpy(parms.master_vol, II_IMPORTED_SHADOW);
3576*ea3068a7SRichard Lowe 	(void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
3577*ea3068a7SRichard Lowe 	(void) strlcpy(parms.bitmap_vol, bitmap_volume, DSW_NAMELEN);
3578fcf3ce44SJohn Forte 	parms.flag = DSW_GOLDEN;
3579fcf3ce44SJohn Forte 
3580fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Import %s %s"),
3581fcf3ce44SJohn Forte 	    parms.shadow_vol, parms.bitmap_vol);
3582fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
3583fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_IMPORT, &parms);
3584fcf3ce44SJohn Forte 	if (rc == -1) {
3585fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Import failed %s %s"),
3586fcf3ce44SJohn Forte 		    parms.shadow_vol, parms.bitmap_vol);
3587fcf3ce44SJohn Forte 		dsw_error(gettext("Import failed"), &parms.status);
3588fcf3ce44SJohn Forte 	}
3589fcf3ce44SJohn Forte 	if (perform_autosv()) {
3590fcf3ce44SJohn Forte 		if (cfg_vol_enable(cfg, shadow_volume, cfg_cluster_tag, "ii")
3591fcf3ce44SJohn Forte 		    < 0) {
3592fcf3ce44SJohn Forte 			dsw_error(gettext("SV-enable failed"), NULL);
3593fcf3ce44SJohn Forte 		}
3594fcf3ce44SJohn Forte 		/* cfg_commit is called by add_cfg_entry below */
3595fcf3ce44SJohn Forte 	}
3596fcf3ce44SJohn Forte 	spcs_s_ufree(&parms.status);
3597fcf3ce44SJohn Forte 	add_cfg_entry(&parms);
3598fcf3ce44SJohn Forte }
3599fcf3ce44SJohn Forte 
3600fcf3ce44SJohn Forte void
3601fcf3ce44SJohn Forte dsw_import(int argc, char *argv[])
3602fcf3ce44SJohn Forte {
3603fcf3ce44SJohn Forte 	if (argc != 3)
3604fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3605fcf3ce44SJohn Forte 	import(argv[1], argv[2]);
3606fcf3ce44SJohn Forte 
3607fcf3ce44SJohn Forte 	exit(0);
3608fcf3ce44SJohn Forte }
3609fcf3ce44SJohn Forte 
3610fcf3ce44SJohn Forte void
3611fcf3ce44SJohn Forte join(char *shadow_volume, char *bitmap_file)
3612fcf3ce44SJohn Forte {
3613fcf3ce44SJohn Forte 	dsw_ioctl_t shd;
3614fcf3ce44SJohn Forte 	dsw_config_t conf;
3615fcf3ce44SJohn Forte 	dsw_bitmap_t parms;
3616fcf3ce44SJohn Forte 	int rc = 0;
3617fcf3ce44SJohn Forte 	int size;
3618fcf3ce44SJohn Forte 	FILE *bmpfp;
3619fcf3ce44SJohn Forte 	uchar_t *shd_bitmap = 0;
3620fcf3ce44SJohn Forte 	ii_header_t header;
3621fcf3ce44SJohn Forte 	char dgname[DSW_NAMELEN];
3622fcf3ce44SJohn Forte 
3623fcf3ce44SJohn Forte 	if (!find_shadow_config(shadow_volume, &conf, &shd))
3624fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
3625fcf3ce44SJohn Forte 		    "group"), NULL);
3626fcf3ce44SJohn Forte 
3627fcf3ce44SJohn Forte 	/* If this is an exportable shadow in the cluster, change ctag */
3628fcf3ce44SJohn Forte 	if (strlen(conf.cluster_tag) &&
3629fcf3ce44SJohn Forte 	    (cfg_dgname(shadow_volume, dgname, sizeof (dgname))))
3630fcf3ce44SJohn Forte 		cfg_resource(cfg, cfg_cluster_tag = strdup(dgname));
3631fcf3ce44SJohn Forte 
3632fcf3ce44SJohn Forte 	if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) {
3633fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to parse config file"), NULL);
3634fcf3ce44SJohn Forte 	}
3635fcf3ce44SJohn Forte 	reload_vols = LD_DSVOLS | LD_SHADOWS;
3636fcf3ce44SJohn Forte 	conform_name(&shadow_volume);
3637fcf3ce44SJohn Forte 
3638fcf3ce44SJohn Forte 	if ((bmpfp = fopen(bitmap_file, "r")) == NULL) {
3639fcf3ce44SJohn Forte 		perror(bitmap_file);
3640fcf3ce44SJohn Forte 		(void) fprintf(stderr,
3641fcf3ce44SJohn Forte 		    gettext("Can't open imported bitmap volume\n"));
3642fcf3ce44SJohn Forte 		exit(1);
3643fcf3ce44SJohn Forte 	}
3644fcf3ce44SJohn Forte 
3645fcf3ce44SJohn Forte 	if (fread(&header, sizeof (header), 1, bmpfp) != 1) {
3646fcf3ce44SJohn Forte 		(void) fprintf(stderr,
3647fcf3ce44SJohn Forte 		    gettext("Can't read imported bitmap volume\n"));
3648fcf3ce44SJohn Forte 		exit(1);
3649fcf3ce44SJohn Forte 	}
3650fcf3ce44SJohn Forte 
3651fcf3ce44SJohn Forte 	/* See if this is a bitmap header */
3652fcf3ce44SJohn Forte 	switch (header.ii_magic) {
3653fcf3ce44SJohn Forte 	case DSW_DIRTY:		/* A copy of a enable bitmap volume */
3654fcf3ce44SJohn Forte 	case DSW_CLEAN:
3655fcf3ce44SJohn Forte 		check_action(gettext("Use the never imported bitmap?"));
3656fcf3ce44SJohn Forte 		break;
3657fcf3ce44SJohn Forte 	case DSW_INVALID:	/* A valid diskable secondary bitmap */
3658fcf3ce44SJohn Forte 		break;
3659fcf3ce44SJohn Forte 	default:
3660fcf3ce44SJohn Forte 		(void) fprintf(stderr,
3661fcf3ce44SJohn Forte 		    gettext("Secondary bitmap is not a valid bitmap volume\n"));
3662fcf3ce44SJohn Forte 		exit(1);
3663fcf3ce44SJohn Forte 	}
3664fcf3ce44SJohn Forte 
3665fcf3ce44SJohn Forte 	size = FBA_SIZE(header.ii_copyfba - header.ii_shdfba);
3666fcf3ce44SJohn Forte 	if ((shd_bitmap = malloc(size)) == NULL) {
3667fcf3ce44SJohn Forte 		perror("malloc");
3668fcf3ce44SJohn Forte 		exit(1);
3669fcf3ce44SJohn Forte 	}
3670fcf3ce44SJohn Forte 
3671fcf3ce44SJohn Forte 	if (fseek(bmpfp, FBA_SIZE(header.ii_shdfba), SEEK_SET)) {
3672fcf3ce44SJohn Forte 		perror("fseek");
3673fcf3ce44SJohn Forte 		exit(1);
3674fcf3ce44SJohn Forte 	}
3675fcf3ce44SJohn Forte 
3676fcf3ce44SJohn Forte 	if (fread(shd_bitmap, 1, size, bmpfp) != size) {
3677fcf3ce44SJohn Forte 		(void) fprintf(stderr,
3678fcf3ce44SJohn Forte 		    gettext("Can't read imported bitmap volume\n"));
3679fcf3ce44SJohn Forte 		exit(1);
3680fcf3ce44SJohn Forte 	}
3681fcf3ce44SJohn Forte 
3682fcf3ce44SJohn Forte 	(void) fclose(bmpfp);
3683fcf3ce44SJohn Forte 
3684*ea3068a7SRichard Lowe 	(void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
3685fcf3ce44SJohn Forte 	parms.shd_bitmap = shd_bitmap;
3686fcf3ce44SJohn Forte 	parms.shd_size = size;
3687fcf3ce44SJohn Forte 	parms.copy_bitmap = NULL;
3688fcf3ce44SJohn Forte 	parms.copy_size = 0;
3689fcf3ce44SJohn Forte 
3690fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Join %s %s"),
3691fcf3ce44SJohn Forte 	    parms.shadow_vol, bitmap_file);
3692fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
3693fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_JOIN, &parms);
3694fcf3ce44SJohn Forte 	if (rc == -1) {
3695fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Join failed %s %s"),
3696fcf3ce44SJohn Forte 		    parms.shadow_vol, bitmap_file);
3697fcf3ce44SJohn Forte 		dsw_error(gettext("Join failed"), &parms.status);
3698fcf3ce44SJohn Forte 	}
3699fcf3ce44SJohn Forte 	if (perform_autosv()) {
3700fcf3ce44SJohn Forte 		rc = cfg_vol_enable(cfg, shadow_volume, cfg_cluster_tag, "ii");
3701fcf3ce44SJohn Forte 		if (rc < 0) {
3702fcf3ce44SJohn Forte 			dsw_error(gettext("SV-enable failed"), NULL);
3703fcf3ce44SJohn Forte 		}
3704570de38fSSurya Prakki 		(void) cfg_commit(cfg);
3705fcf3ce44SJohn Forte 	}
3706fcf3ce44SJohn Forte 	spcs_s_ufree(&parms.status);
3707fcf3ce44SJohn Forte }
3708fcf3ce44SJohn Forte 
3709fcf3ce44SJohn Forte int
3710fcf3ce44SJohn Forte params(char *shadow_volume)
3711fcf3ce44SJohn Forte {
3712fcf3ce44SJohn Forte 	char *delay = param_delay;
3713fcf3ce44SJohn Forte 	char *unit = param_unit;
3714fcf3ce44SJohn Forte 	dsw_copyp_t parms;
3715fcf3ce44SJohn Forte 	int rc = 0;
3716fcf3ce44SJohn Forte 	int get = 0;
3717fcf3ce44SJohn Forte 	int new_delay;
3718fcf3ce44SJohn Forte 	int new_unit;
3719fcf3ce44SJohn Forte 
3720*ea3068a7SRichard Lowe 	(void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
3721fcf3ce44SJohn Forte 	if (delay == NULL || unit == NULL) {
3722fcf3ce44SJohn Forte 		get = 1;
3723fcf3ce44SJohn Forte 		parms.copy_delay = -1;
3724fcf3ce44SJohn Forte 		parms.copy_unit = -1;
3725fcf3ce44SJohn Forte 	} else {
3726fcf3ce44SJohn Forte 		new_delay = parms.copy_delay = convert_int(delay);
3727fcf3ce44SJohn Forte 		new_unit = parms.copy_unit = convert_int(unit);
3728fcf3ce44SJohn Forte 	}
3729fcf3ce44SJohn Forte 
3730fcf3ce44SJohn Forte 	parms.status = spcs_s_ucreate();
3731fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_COPYP, &parms);
3732fcf3ce44SJohn Forte 	if (rc == -1) {
3733fcf3ce44SJohn Forte 		(void) fprintf(stderr,
3734fcf3ce44SJohn Forte 		    gettext("Parameter ranges are delay(%d - %d), "
3735fcf3ce44SJohn Forte 		    "units(%d - %d)\n"), MIN_THROTTLE_DELAY, MAX_THROTTLE_DELAY,
3736fcf3ce44SJohn Forte 		    MIN_THROTTLE_UNIT, MAX_THROTTLE_UNIT);
3737fcf3ce44SJohn Forte 		dsw_error(gettext("Set Copy Parameters failed"), &parms.status);
3738fcf3ce44SJohn Forte 	}
3739fcf3ce44SJohn Forte 	if (!get)
3740fcf3ce44SJohn Forte 		spcs_log("ii", NULL, gettext("Changed copy parameters %s from "
3741fcf3ce44SJohn Forte 		    "%d %d to %d %d"), parms.shadow_vol, parms.copy_delay,
3742fcf3ce44SJohn Forte 		    parms.copy_unit, new_delay, new_unit);
3743fcf3ce44SJohn Forte 	else
3744fcf3ce44SJohn Forte 		(void) printf(gettext("volume: %s\ncopy delay: %d\ncopy unit:"
3745fcf3ce44SJohn Forte 		    " %d\n"), parms.shadow_vol, parms.copy_delay,
3746fcf3ce44SJohn Forte 		    parms.copy_unit);
3747fcf3ce44SJohn Forte 	spcs_s_ufree(&parms.status);
3748fcf3ce44SJohn Forte 	return (0);
3749fcf3ce44SJohn Forte }
3750fcf3ce44SJohn Forte 
3751fcf3ce44SJohn Forte static void
3752fcf3ce44SJohn Forte do_attach(dsw_config_t *parms)
3753fcf3ce44SJohn Forte {
3754fcf3ce44SJohn Forte 	dsw_config_t io;
3755fcf3ce44SJohn Forte 	int rc;
3756fcf3ce44SJohn Forte 	int check = 0;
3757fcf3ce44SJohn Forte 
3758fcf3ce44SJohn Forte 	spcs_log("ii", NULL, gettext("Attach %s %s"),
3759fcf3ce44SJohn Forte 	    parms->shadow_vol, parms->bitmap_vol);
3760fcf3ce44SJohn Forte 	parms->status = spcs_s_ucreate();
3761fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_OATTACH, parms);
3762fcf3ce44SJohn Forte 	if (rc == -1) {
3763fcf3ce44SJohn Forte 		check = 1;
3764fcf3ce44SJohn Forte 		/* if overflow() fails, it calls dsw_error to exit */
3765fcf3ce44SJohn Forte 		(void) overflow(parms->bitmap_vol);
3766fcf3ce44SJohn Forte 	}
3767fcf3ce44SJohn Forte 	spcs_s_ufree(&parms->status);
3768fcf3ce44SJohn Forte 	if (check == 1) {
3769fcf3ce44SJohn Forte 		if (!find_shadow_config(parms->shadow_vol, &io, NULL))
3770fcf3ce44SJohn Forte 			dsw_error(
3771fcf3ce44SJohn Forte 			    gettext("Volume is not in a Point-in-Time Copy "
3772fcf3ce44SJohn Forte 			    "group"), NULL);
3773*ea3068a7SRichard Lowe 		(void) strlcpy(io.bitmap_vol, parms->bitmap_vol, DSW_NAMELEN);
3774fcf3ce44SJohn Forte 		io.status = spcs_s_ucreate();
3775fcf3ce44SJohn Forte 		if (do_ioctl(dsw_fd, DSWIOC_OATTACH, &io) == -1) {
3776fcf3ce44SJohn Forte 			spcs_log("ii", NULL, gettext("Attach failed %s %s"),
3777fcf3ce44SJohn Forte 			    io.shadow_vol, parms->bitmap_vol);
3778fcf3ce44SJohn Forte 			dsw_error(gettext("Attach failed"), &io.status);
3779fcf3ce44SJohn Forte 		}
3780fcf3ce44SJohn Forte 		spcs_s_ufree(&io.status);
3781fcf3ce44SJohn Forte 	}
3782fcf3ce44SJohn Forte }
3783fcf3ce44SJohn Forte 
3784fcf3ce44SJohn Forte int
3785fcf3ce44SJohn Forte attach(char *shadow_volume)
3786fcf3ce44SJohn Forte {
3787fcf3ce44SJohn Forte 	dsw_config_t parms;
3788fcf3ce44SJohn Forte 	dsw_stat_t args;
3789fcf3ce44SJohn Forte 	char	shd_dg[DSW_NAMELEN];
3790fcf3ce44SJohn Forte 	char	ovr_dg[DSW_NAMELEN];
3791fcf3ce44SJohn Forte 
3792fcf3ce44SJohn Forte 	switch (check_cluster()) {
3793fcf3ce44SJohn Forte 	case II_CLUSTER:
3794fcf3ce44SJohn Forte 	case II_CLUSTER_LCL:
3795fcf3ce44SJohn Forte 		(void) check_resource_group(shadow_volume);
3796fcf3ce44SJohn Forte 		if (cfg_cluster_tag) { /* check all volumes are in same dg */
3797fcf3ce44SJohn Forte 			if (cfg_dgname(shadow_volume, shd_dg, DSW_NAMELEN)
3798fcf3ce44SJohn Forte 			    == NULL)
3799fcf3ce44SJohn Forte 				dsw_error(gettext("Shadow volume not in a"
3800fcf3ce44SJohn Forte 				    " disk group"), NULL);
3801fcf3ce44SJohn Forte 			if (cfg_dgname(overflow_file, ovr_dg, DSW_NAMELEN)
3802fcf3ce44SJohn Forte 			    == NULL)
3803fcf3ce44SJohn Forte 				dsw_error(gettext("Overflow volume not in a"
3804fcf3ce44SJohn Forte 				    " disk group"), NULL);
3805fcf3ce44SJohn Forte 			if (strcmp(ovr_dg, shd_dg) != 0)
3806fcf3ce44SJohn Forte 				dsw_error(gettext("Overflow volume not in"
3807fcf3ce44SJohn Forte 				    " same disk group as shadow set members"),
3808fcf3ce44SJohn Forte 				    NULL);
3809fcf3ce44SJohn Forte 		}
3810fcf3ce44SJohn Forte 		break;
3811fcf3ce44SJohn Forte 	case II_NOT_CLUSTER:
3812fcf3ce44SJohn Forte 		/* do nothing */
3813fcf3ce44SJohn Forte 		break;
3814fcf3ce44SJohn Forte 	default:
3815fcf3ce44SJohn Forte 		dsw_error(gettext(
3816fcf3ce44SJohn Forte 		    "Unexpected return from check_cluster()"), NULL);
3817fcf3ce44SJohn Forte 	}
3818fcf3ce44SJohn Forte 
3819fcf3ce44SJohn Forte 	/* assure that the overflow_file is not an II volume */
3820fcf3ce44SJohn Forte 	if (find_any_cf_line(overflow_file))
3821fcf3ce44SJohn Forte 		dsw_error(gettext(
3822fcf3ce44SJohn Forte 		    "Overflow volume is already in a Point-in-Time Copy "
3823fcf3ce44SJohn Forte 		    "group"), NULL);
3824fcf3ce44SJohn Forte 
3825fcf3ce44SJohn Forte 	/* use find_shadow_config() to find setnumber */
3826fcf3ce44SJohn Forte 	if (!find_shadow_config(shadow_volume, &parms, NULL))
3827fcf3ce44SJohn Forte 		dsw_error(gettext("Volume is not in a Point-in-Time Copy "
3828fcf3ce44SJohn Forte 		    "group"), NULL);
3829fcf3ce44SJohn Forte 
3830fcf3ce44SJohn Forte 	/* can only attach an overflow volume to dependent, compact shadow */
3831*ea3068a7SRichard Lowe 	(void) strlcpy(args.shadow_vol, shadow_volume, DSW_NAMELEN);
3832fcf3ce44SJohn Forte 
3833fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
3834fcf3ce44SJohn Forte 	if ((do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) ||
3835fcf3ce44SJohn Forte 	    !(args.stat & DSW_TREEMAP))
3836fcf3ce44SJohn Forte 		dsw_error(gettext("Not a compact dependent shadow"), NULL);
3837fcf3ce44SJohn Forte 
3838fcf3ce44SJohn Forte 	/* bitmap_vol is overloaded */
3839*ea3068a7SRichard Lowe 	(void) strlcpy(parms.bitmap_vol, overflow_file, DSW_NAMELEN);
3840fcf3ce44SJohn Forte 
3841fcf3ce44SJohn Forte 	do_attach(&parms);
3842fcf3ce44SJohn Forte 
3843fcf3ce44SJohn Forte 	/* add overflow to cfg line */
3844fcf3ce44SJohn Forte 	(void) sprintf(key, "ii.set%d.overflow", setnumber);
3845fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, key, overflow_file,
3846fcf3ce44SJohn Forte 	    strlen(overflow_file)) < 0) {
3847fcf3ce44SJohn Forte 		perror("cfg_put_cstring");
3848fcf3ce44SJohn Forte 	}
3849fcf3ce44SJohn Forte 	(void) cfg_commit(cfg);
3850fcf3ce44SJohn Forte 	return (0);
3851fcf3ce44SJohn Forte }
3852fcf3ce44SJohn Forte 
3853fcf3ce44SJohn Forte void
3854fcf3ce44SJohn Forte dsw_join(int argc, char *argv[])
3855fcf3ce44SJohn Forte {
3856fcf3ce44SJohn Forte 	if (argc != 3)
3857fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3858fcf3ce44SJohn Forte 
3859fcf3ce44SJohn Forte 	join(argv[1], argv[2]);
3860fcf3ce44SJohn Forte 	exit(0);
3861fcf3ce44SJohn Forte }
3862fcf3ce44SJohn Forte 
3863fcf3ce44SJohn Forte void
3864fcf3ce44SJohn Forte dsw_params(int argc, char *argv[])
3865fcf3ce44SJohn Forte {
3866fcf3ce44SJohn Forte 	if (argc != 4 && argc != 2 && argc != 0)
3867fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3868fcf3ce44SJohn Forte 
3869fcf3ce44SJohn Forte 	if ((argc == 4) || (argc == 2)) {
3870fcf3ce44SJohn Forte 		param_delay = argv[1];
3871fcf3ce44SJohn Forte 		param_unit = argv[2];
3872fcf3ce44SJohn Forte 		if (argc == 4) {
3873fcf3ce44SJohn Forte 			argv[1] = argv[3];
3874fcf3ce44SJohn Forte 			argv[2] = NULL;
3875fcf3ce44SJohn Forte 		}
3876fcf3ce44SJohn Forte 	}
3877fcf3ce44SJohn Forte 	exit(dsw_group_or_single_op(2, argv, params));
3878fcf3ce44SJohn Forte }
3879fcf3ce44SJohn Forte 
3880fcf3ce44SJohn Forte /*ARGSUSED*/
3881fcf3ce44SJohn Forte void
3882fcf3ce44SJohn Forte dsw_attach(int argc, char *argv[])
3883fcf3ce44SJohn Forte {
3884fcf3ce44SJohn Forte 	overflow_file = argv[1];
3885fcf3ce44SJohn Forte 	argv[1] = argv[2];
3886fcf3ce44SJohn Forte 	(void) dsw_group_or_single_op(2, argv, attach);
3887fcf3ce44SJohn Forte 	exit(0);
3888fcf3ce44SJohn Forte }
3889fcf3ce44SJohn Forte 
3890fcf3ce44SJohn Forte /*ARGSUSED*/
3891fcf3ce44SJohn Forte void
3892fcf3ce44SJohn Forte dsw_olist(int argc, char *argv[])
3893fcf3ce44SJohn Forte {
3894fcf3ce44SJohn Forte 	char	*sp, *overflow_list, **vol;
3895fcf3ce44SJohn Forte 	int	count, i;
3896fcf3ce44SJohn Forte 	ENTRY	item, *found;
3897fcf3ce44SJohn Forte 	char	key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ];
3898fcf3ce44SJohn Forte 
3899fcf3ce44SJohn Forte 	overflow_list = get_overflow_list();
3900fcf3ce44SJohn Forte 
3901fcf3ce44SJohn Forte 	/* count entries */
3902fcf3ce44SJohn Forte 	count = 0;
3903fcf3ce44SJohn Forte 	for (sp = overflow_list; *sp; sp += DSW_NAMELEN) {
3904fcf3ce44SJohn Forte 		++count;
3905fcf3ce44SJohn Forte 	}
3906fcf3ce44SJohn Forte 
3907fcf3ce44SJohn Forte 	/* create hash (adding room for suspended overflow volumes) */
3908fcf3ce44SJohn Forte 	if (hcreate(count + 1024) == 0) {
3909fcf3ce44SJohn Forte 		dsw_error(gettext("Out of memory creating lookup table"), NULL);
3910fcf3ce44SJohn Forte 		/*NOTREACHED*/
3911fcf3ce44SJohn Forte 	}
3912fcf3ce44SJohn Forte 
3913fcf3ce44SJohn Forte 	if (count > 0) {
3914fcf3ce44SJohn Forte 		/* create memory to store copy of list */
3915fcf3ce44SJohn Forte 		vol = (char **)calloc(count, sizeof (char *));
3916fcf3ce44SJohn Forte 		if (!vol) {
3917fcf3ce44SJohn Forte 			dsw_error(
3918fcf3ce44SJohn Forte 			    gettext("Out of memory creating lookup table"),
3919fcf3ce44SJohn Forte 			    NULL);
3920fcf3ce44SJohn Forte 			/*NOTREACHED*/
3921fcf3ce44SJohn Forte 		}
3922fcf3ce44SJohn Forte 
3923fcf3ce44SJohn Forte 		/* fill hash */
3924fcf3ce44SJohn Forte 		for (i = 0, sp = overflow_list; *sp; sp += DSW_NAMELEN, i++) {
3925fcf3ce44SJohn Forte 
3926fcf3ce44SJohn Forte 			/* make copy of string */
3927fcf3ce44SJohn Forte 			vol[ i ] = (char *)malloc(DSW_NAMELEN + 1);
3928*ea3068a7SRichard Lowe 			(void) strlcpy(vol[ i ], sp, DSW_NAMELEN);
3929fcf3ce44SJohn Forte 
3930fcf3ce44SJohn Forte 			item.key = vol[ i ];
3931fcf3ce44SJohn Forte 			item.data = (char *)0;
3932fcf3ce44SJohn Forte 			(void) hsearch(item, ENTER);
3933fcf3ce44SJohn Forte 		}
3934fcf3ce44SJohn Forte 	}
3935fcf3ce44SJohn Forte 
3936fcf3ce44SJohn Forte 	/* loop through config file entries */
3937fcf3ce44SJohn Forte 	i = 0;
3938fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
3939fcf3ce44SJohn Forte 
3940fcf3ce44SJohn Forte 	/*CONSTCOND*/
3941fcf3ce44SJohn Forte 	while (1) {
3942fcf3ce44SJohn Forte 		++i;
3943fcf3ce44SJohn Forte 		(void) snprintf(key, CFG_MAX_KEY, "ii.set%d.overflow", i);
3944fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
3945fcf3ce44SJohn Forte 			break;
3946fcf3ce44SJohn Forte 		}
3947fcf3ce44SJohn Forte 
3948fcf3ce44SJohn Forte 		/* has this set got an overflow volume? */
3949fcf3ce44SJohn Forte 		if (!*buf) {
3950fcf3ce44SJohn Forte 			continue;
3951fcf3ce44SJohn Forte 		}
3952fcf3ce44SJohn Forte 
3953fcf3ce44SJohn Forte 		/* look up overflow in hash */
3954fcf3ce44SJohn Forte 		item.key = buf;
3955fcf3ce44SJohn Forte 		if (count > 0 && (found = hsearch(item, FIND)) != NULL) {
3956fcf3ce44SJohn Forte 			if (0 == (int)found->data) {
3957fcf3ce44SJohn Forte 				(void) printf("%s\n", buf);
3958fcf3ce44SJohn Forte 				found->data = (char *)1;
3959fcf3ce44SJohn Forte 				(void) hsearch(*found, ENTER);
3960fcf3ce44SJohn Forte 			}
3961fcf3ce44SJohn Forte 		} else {
3962fcf3ce44SJohn Forte 			/* must be part of a suspended set */
3963fcf3ce44SJohn Forte 			(void) printf("%s (attached to suspended set)\n", buf);
3964fcf3ce44SJohn Forte 			item.key = buf;
3965fcf3ce44SJohn Forte 			item.data = (char *)1;
3966fcf3ce44SJohn Forte 			(void) hsearch(item, ENTER);
3967fcf3ce44SJohn Forte 		}
3968fcf3ce44SJohn Forte 	}
3969fcf3ce44SJohn Forte 
3970fcf3ce44SJohn Forte 	exit(0);
3971fcf3ce44SJohn Forte }
3972fcf3ce44SJohn Forte 
3973fcf3ce44SJohn Forte void
3974fcf3ce44SJohn Forte dsw_ostat(int argc, char *argv[])
3975fcf3ce44SJohn Forte {
3976fcf3ce44SJohn Forte 	dsw_ostat_t	args;
3977fcf3ce44SJohn Forte 	int	stat_flags;
3978fcf3ce44SJohn Forte 
3979fcf3ce44SJohn Forte 	if (argc != 2)
3980fcf3ce44SJohn Forte 		usage(gettext("Incorrect number of arguments"));
3981fcf3ce44SJohn Forte 
3982*ea3068a7SRichard Lowe 	(void) strlcpy(args.overflow_vol, argv[1], DSW_NAMELEN);
3983fcf3ce44SJohn Forte 
3984fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
3985fcf3ce44SJohn Forte 	if (do_ioctl(dsw_fd, DSWIOC_OSTAT2, &args) == -1)
3986fcf3ce44SJohn Forte 		dsw_error(gettext("Stat failed"), &args.status);
3987fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
3988fcf3ce44SJohn Forte 
3989fcf3ce44SJohn Forte 	if ((args.hversion >= 1) && (args.hmagic == II_OMAGIC)) {
3990fcf3ce44SJohn Forte 		stat_flags = args.flags;
3991fcf3ce44SJohn Forte 		if (stat_flags & IIO_CNTR_INVLD)
3992fcf3ce44SJohn Forte 			(void) printf(gettext("Clean shutdown of volume "
3993fcf3ce44SJohn Forte 			"sets associated with overflow volume "
3994fcf3ce44SJohn Forte 			"did not occur.\n"
3995fcf3ce44SJohn Forte 			"Overflow counters will be inconsistent "
3996fcf3ce44SJohn Forte 			"until new point-in-time(s) are taken.\n"));
3997fcf3ce44SJohn Forte 	}
3998fcf3ce44SJohn Forte 	(void) printf(gettext("Total number of attached shadows: %d\n"),
3999fcf3ce44SJohn Forte 	    args.drefcnt);
4000fcf3ce44SJohn Forte 	(void) printf(gettext("Number of currently attached shadows: %d\n"),
4001fcf3ce44SJohn Forte 	    args.crefcnt);
4002fcf3ce44SJohn Forte 	(void) printf(gettext("Total number of chunks: %lld\n"), args.nchunks);
4003fcf3ce44SJohn Forte 	(void) printf(gettext("Number of chunks ever allocated: %lld\n"),
4004fcf3ce44SJohn Forte 	    args.used);
4005fcf3ce44SJohn Forte 	(void) printf(gettext("Number of used chunks: %lld\n"),
4006fcf3ce44SJohn Forte 	    (args.nchunks - args.unused));
4007fcf3ce44SJohn Forte 	(void) printf(gettext("Number of unused chunks: %lld\n"), args.unused);
4008fcf3ce44SJohn Forte 	exit(0);
4009fcf3ce44SJohn Forte }
4010fcf3ce44SJohn Forte 
4011fcf3ce44SJohn Forte /*ARGSUSED*/
4012fcf3ce44SJohn Forte void
4013fcf3ce44SJohn Forte dsw_move_2_group(int argc, char *argv[])
4014fcf3ce44SJohn Forte {
4015fcf3ce44SJohn Forte 	dsw_config_t parms;
4016fcf3ce44SJohn Forte 	dsw_movegrp_t movegrp;
4017fcf3ce44SJohn Forte 	grptag_t *gdata;
4018fcf3ce44SJohn Forte 	int waserr = 0;
4019fcf3ce44SJohn Forte 
4020fcf3ce44SJohn Forte 	/* handle move to NULL group, or group of all spaces or tabs */
4021570de38fSSurya Prakki 	(void) strncpy(movegrp.new_group, group_name, DSW_NAMELEN);
4022fcf3ce44SJohn Forte 	if ((strlen(group_name) == 0) || (strcspn(group_name, " \t") == 0)) {
4023fcf3ce44SJohn Forte 		group_name = "-";
4024fcf3ce44SJohn Forte 		bzero(movegrp.new_group, DSW_NAMELEN);
4025fcf3ce44SJohn Forte 		gdata = NULL;
4026fcf3ce44SJohn Forte 	} else {
4027fcf3ce44SJohn Forte 		/* get the ctag for this group (if any) */
4028fcf3ce44SJohn Forte 		gdata = (grptag_t *)nsc_lookup(volhash, group_name);
4029fcf3ce44SJohn Forte 	}
4030fcf3ce44SJohn Forte 
4031fcf3ce44SJohn Forte 	movegrp.status = spcs_s_ucreate();
4032fcf3ce44SJohn Forte 
4033fcf3ce44SJohn Forte 	for (++argv; *argv; argv++) {
4034fcf3ce44SJohn Forte 		if (!find_shadow_config(*argv, &parms, NULL))
4035fcf3ce44SJohn Forte 			dsw_error(gettext("Volume is not in a Point-in-Time "
4036fcf3ce44SJohn Forte 			    "Copy group"), NULL);
4037fcf3ce44SJohn Forte 
4038fcf3ce44SJohn Forte 		/* ensure the ctag matches the group */
4039fcf3ce44SJohn Forte 		if (gdata && *gdata->ctag) {
4040fcf3ce44SJohn Forte 			if (strncmp(parms.cluster_tag, gdata->ctag,
4041fcf3ce44SJohn Forte 			    DSW_NAMELEN) != 0) {
4042fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s %s %s\n", cmdnam,
4043fcf3ce44SJohn Forte 				    gettext("unable to move set"), *argv,
4044fcf3ce44SJohn Forte 				    gettext("into new group - cluster "
4045fcf3ce44SJohn Forte 				    "resource mismatch"));
4046fcf3ce44SJohn Forte 				waserr = 1;
4047fcf3ce44SJohn Forte 				continue;
4048fcf3ce44SJohn Forte 			}
4049fcf3ce44SJohn Forte 		}
4050fcf3ce44SJohn Forte 
4051fcf3ce44SJohn Forte 		/* move the set in the kernel */
4052570de38fSSurya Prakki 		(void) strncpy(movegrp.shadow_vol, parms.shadow_vol,
4053570de38fSSurya Prakki 		    DSW_NAMELEN);
4054fcf3ce44SJohn Forte 		if (do_ioctl(dsw_fd, DSWIOC_MOVEGRP, &movegrp) < 0)
4055fcf3ce44SJohn Forte 			dsw_error(gettext("Failed to move group in kernel"),
4056fcf3ce44SJohn Forte 			    NULL);
4057fcf3ce44SJohn Forte 
4058fcf3ce44SJohn Forte 		/* now update the config */
4059fcf3ce44SJohn Forte 		(void) sprintf(key, "ii.set%d.group", setnumber);
4060fcf3ce44SJohn Forte 		if (cfg_put_cstring(cfg, key, group_name,
4061fcf3ce44SJohn Forte 		    strlen(group_name)) < 0) {
4062fcf3ce44SJohn Forte 			perror("cfg_put_cstring");
4063fcf3ce44SJohn Forte 		}
4064fcf3ce44SJohn Forte 		(void) cfg_commit(cfg);
4065fcf3ce44SJohn Forte 	}
4066fcf3ce44SJohn Forte 	spcs_s_ufree(&movegrp.status);
4067fcf3ce44SJohn Forte 	cfg_close(cfg);
4068fcf3ce44SJohn Forte 	exit(waserr);
4069fcf3ce44SJohn Forte }
4070fcf3ce44SJohn Forte 
4071fcf3ce44SJohn Forte void
4072fcf3ce44SJohn Forte dsw_list_groups()
4073fcf3ce44SJohn Forte {
4074fcf3ce44SJohn Forte 	FILE *pfp;
4075fcf3ce44SJohn Forte 
4076fcf3ce44SJohn Forte 	if ((pfp = popen("/usr/bin/sort -u", "w")) == NULL) {
4077fcf3ce44SJohn Forte 		dsw_error(gettext("Can't open sort program"), NULL);
4078fcf3ce44SJohn Forte 	}
4079fcf3ce44SJohn Forte 
4080fcf3ce44SJohn Forte 	(void) fflush(stdout);
4081fcf3ce44SJohn Forte 	for (setnumber = 1; /*CSTYLED*/; setnumber++) {
4082fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "ii.set%d.group", setnumber);
4083fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
4084fcf3ce44SJohn Forte 			break;
4085fcf3ce44SJohn Forte 
4086fcf3ce44SJohn Forte 		/* skip if shadow set is not in any group */
4087fcf3ce44SJohn Forte 		if (strcmp(buf, "") == 0)
4088fcf3ce44SJohn Forte 			continue;
4089fcf3ce44SJohn Forte 		(void) fprintf(pfp, "%s\n", buf);
4090fcf3ce44SJohn Forte 	}
4091fcf3ce44SJohn Forte 	(void) pclose(pfp);
4092fcf3ce44SJohn Forte }
4093fcf3ce44SJohn Forte 
4094fcf3ce44SJohn Forte void
4095fcf3ce44SJohn Forte dsw_list_group_volumes()
4096fcf3ce44SJohn Forte {
4097fcf3ce44SJohn Forte 	FILE *pfp;
4098fcf3ce44SJohn Forte 
4099fcf3ce44SJohn Forte 	if (find_group_members(group_name) < 1)
4100fcf3ce44SJohn Forte 		dsw_error(gettext("Group does not exist or has no members"),
4101fcf3ce44SJohn Forte 		    NULL);
4102fcf3ce44SJohn Forte 
4103fcf3ce44SJohn Forte 	if ((pfp = popen("/usr/bin/sort -u", "w")) == NULL) {
4104fcf3ce44SJohn Forte 		dsw_error(gettext("Can't open sort program"), NULL);
4105fcf3ce44SJohn Forte 	}
4106fcf3ce44SJohn Forte 
4107fcf3ce44SJohn Forte 	(void) fflush(stdout);
4108fcf3ce44SJohn Forte 	for (; *group_volumes; group_volumes++)
4109fcf3ce44SJohn Forte 		(void) fprintf(pfp, "%s\n", *group_volumes);
4110fcf3ce44SJohn Forte 	(void) pclose(pfp);
4111fcf3ce44SJohn Forte }
4112fcf3ce44SJohn Forte 
4113fcf3ce44SJohn Forte static void
4114fcf3ce44SJohn Forte load_ii_vols(CFGFILE *cfg)
4115fcf3ce44SJohn Forte {
4116fcf3ce44SJohn Forte 	int set, entries;
4117fcf3ce44SJohn Forte 	char *mst, *shd, *buf, **entry;
4118fcf3ce44SJohn Forte 	char *ctag, *group;
4119fcf3ce44SJohn Forte 	mstcount_t *mdata;
4120fcf3ce44SJohn Forte 	shdvol_t *sdata;
4121fcf3ce44SJohn Forte 	grptag_t *gdata;
4122fcf3ce44SJohn Forte 	static int whinged = 0;
4123fcf3ce44SJohn Forte 
4124fcf3ce44SJohn Forte 	if (volhash) {
4125fcf3ce44SJohn Forte 		return;
4126fcf3ce44SJohn Forte 	}
4127fcf3ce44SJohn Forte 
4128fcf3ce44SJohn Forte 	volhash = nsc_create_hash();
4129fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
4130fcf3ce44SJohn Forte 	entries = cfg_get_section(cfg, &entry, "ii");
4131fcf3ce44SJohn Forte 	for (set = 1; set <= entries; set++) {
4132fcf3ce44SJohn Forte 		buf = entry[set - 1];
4133fcf3ce44SJohn Forte 
4134fcf3ce44SJohn Forte 		/* grab master volume name */
4135fcf3ce44SJohn Forte 		mst = strtok(buf, " ");
4136fcf3ce44SJohn Forte 		if (!mst) {
4137fcf3ce44SJohn Forte 			free(buf);
4138fcf3ce44SJohn Forte 			break;
4139fcf3ce44SJohn Forte 		}
4140fcf3ce44SJohn Forte 
4141fcf3ce44SJohn Forte 		/* grab shadow, group & cnode fields */
4142fcf3ce44SJohn Forte 		shd = strtok(NULL, " ");
4143fcf3ce44SJohn Forte 		(void) strtok(NULL, " ");	/* bitmap */
4144fcf3ce44SJohn Forte 		(void) strtok(NULL, " ");	/* mode */
4145fcf3ce44SJohn Forte 		(void) strtok(NULL, " ");	/* overflow */
4146fcf3ce44SJohn Forte 		ctag = strtok(NULL, " ");	/* cnode */
4147fcf3ce44SJohn Forte 		(void) strtok(NULL, " ");	/* options */
4148fcf3ce44SJohn Forte 		group = strtok(NULL, " ");	/* group */
4149fcf3ce44SJohn Forte 
4150fcf3ce44SJohn Forte 		/* Fix optional tags */
4151fcf3ce44SJohn Forte 		if (ctag)
4152fcf3ce44SJohn Forte 			ctag += strspn(ctag, "-");
4153fcf3ce44SJohn Forte 		if (group)
4154fcf3ce44SJohn Forte 			group += strspn(group, "-");
4155fcf3ce44SJohn Forte 
4156fcf3ce44SJohn Forte 		/* If cluster tags don't match, skip record */
4157fcf3ce44SJohn Forte 		if ((cfg_cluster_tag && strcmp(ctag, cfg_cluster_tag)) ||
4158fcf3ce44SJohn Forte 		    (!cfg_cluster_tag && strlen(ctag))) {
4159fcf3ce44SJohn Forte 			free(buf);
4160fcf3ce44SJohn Forte 			continue;
4161fcf3ce44SJohn Forte 		}
4162fcf3ce44SJohn Forte 
4163fcf3ce44SJohn Forte 		/* master volume, may be duplicates */
4164fcf3ce44SJohn Forte 		mdata = (mstcount_t *)nsc_lookup(volhash, mst);
4165fcf3ce44SJohn Forte 		if (mdata) {
4166fcf3ce44SJohn Forte 			++mdata->count;
4167fcf3ce44SJohn Forte 		} else {
4168fcf3ce44SJohn Forte 			mdata = (mstcount_t *)malloc(sizeof (mstcount_t));
4169fcf3ce44SJohn Forte 			mdata->count = 1;
4170fcf3ce44SJohn Forte 			(void) nsc_insert_node(volhash, mdata, mst);
4171fcf3ce44SJohn Forte 		}
4172fcf3ce44SJohn Forte 
4173fcf3ce44SJohn Forte 		/* grab shadow volume name */
4174fcf3ce44SJohn Forte 		sdata = (shdvol_t *)malloc(sizeof (shdvol_t));
4175570de38fSSurya Prakki 		(void) strncpy(sdata->master, mst, DSW_NAMELEN);
4176fcf3ce44SJohn Forte 		(void) nsc_insert_node(volhash, sdata, shd);
4177fcf3ce44SJohn Forte 
4178fcf3ce44SJohn Forte 		/* No need to continue if no groups or ctags */
4179fcf3ce44SJohn Forte 		if (!group || !*group || !ctag || !*ctag) {
4180fcf3ce44SJohn Forte 			free(buf);
4181fcf3ce44SJohn Forte 			continue;
4182fcf3ce44SJohn Forte 		}
4183fcf3ce44SJohn Forte 
4184fcf3ce44SJohn Forte 		gdata = (grptag_t *)nsc_lookup(volhash, group);
4185fcf3ce44SJohn Forte 		if (gdata) {
4186fcf3ce44SJohn Forte 			/* group already exists - check ctag */
4187fcf3ce44SJohn Forte 			if (*ctag &&
4188fcf3ce44SJohn Forte 			    (strncmp(ctag, gdata->ctag, DSW_NAMELEN) != 0)) {
4189fcf3ce44SJohn Forte 				if (!whinged) {
4190570de38fSSurya Prakki 					(void) printf(gettext(
4191570de38fSSurya Prakki 					    "Warning: multiple "
4192fcf3ce44SJohn Forte 					    "cluster resource groups "
4193fcf3ce44SJohn Forte 					    "defined within a single "
4194fcf3ce44SJohn Forte 					    "I/O group\n"));
4195fcf3ce44SJohn Forte 					whinged = 1;
4196fcf3ce44SJohn Forte 				}
4197fcf3ce44SJohn Forte 			}
4198fcf3ce44SJohn Forte 		} else {
4199fcf3ce44SJohn Forte 			gdata = (grptag_t *)malloc(sizeof (grptag_t));
4200570de38fSSurya Prakki 			(void) strncpy(gdata->ctag, ctag, DSW_NAMELEN);
4201fcf3ce44SJohn Forte 			(void) nsc_insert_node(volhash, gdata, group);
4202fcf3ce44SJohn Forte 		}
4203fcf3ce44SJohn Forte 
4204fcf3ce44SJohn Forte 		free(buf);
4205fcf3ce44SJohn Forte 	}
4206fcf3ce44SJohn Forte 
4207fcf3ce44SJohn Forte 	/* free up any leftovers */
4208fcf3ce44SJohn Forte 	while (set < entries)
4209fcf3ce44SJohn Forte 		free(entry[set++]);
4210fcf3ce44SJohn Forte 	if (entries)
4211fcf3ce44SJohn Forte 		free(entry);
4212fcf3ce44SJohn Forte }
4213fcf3ce44SJohn Forte 
4214fcf3ce44SJohn Forte static void
4215fcf3ce44SJohn Forte unload_ii_vols()
4216fcf3ce44SJohn Forte {
4217fcf3ce44SJohn Forte 	nsc_remove_all(volhash, free);
4218fcf3ce44SJohn Forte 	volhash = 0;
4219fcf3ce44SJohn Forte }
4220fcf3ce44SJohn Forte 
4221fcf3ce44SJohn Forte static int
4222fcf3ce44SJohn Forte perform_autosv()
4223fcf3ce44SJohn Forte {
4224fcf3ce44SJohn Forte 	static int result;
4225fcf3ce44SJohn Forte 	static int calculated = 0;
4226fcf3ce44SJohn Forte 	int rc;
4227fcf3ce44SJohn Forte 
4228fcf3ce44SJohn Forte #ifdef DEBUG
4229fcf3ce44SJohn Forte 	if (getenv("II_SET_CLUSTER"))
4230fcf3ce44SJohn Forte 		return (1);
4231fcf3ce44SJohn Forte #endif
4232fcf3ce44SJohn Forte 
4233fcf3ce44SJohn Forte 	if (calculated) {
4234fcf3ce44SJohn Forte 		return (result);
4235fcf3ce44SJohn Forte 	}
4236fcf3ce44SJohn Forte 
4237fcf3ce44SJohn Forte 	/*
4238fcf3ce44SJohn Forte 	 * we only perform auto-sv if we're in a sun cluster or if
4239fcf3ce44SJohn Forte 	 * we're on a standalone system.  I.e. we don't do auto-sv on Harry
4240fcf3ce44SJohn Forte 	 */
4241fcf3ce44SJohn Forte 	rc = check_cluster();
4242fcf3ce44SJohn Forte 
4243fcf3ce44SJohn Forte 	if (II_NOT_CLUSTER == rc) {
4244fcf3ce44SJohn Forte 		result = 1;
4245fcf3ce44SJohn Forte 	} else {
4246fcf3ce44SJohn Forte 		result = cfg_issuncluster();
4247fcf3ce44SJohn Forte 	}
4248fcf3ce44SJohn Forte 
4249fcf3ce44SJohn Forte 	calculated = 1;
4250fcf3ce44SJohn Forte 	return (result);
4251fcf3ce44SJohn Forte }
4252fcf3ce44SJohn Forte 
4253fcf3ce44SJohn Forte /*
4254fcf3ce44SJohn Forte  * Returns true if set has had the shadow volume exported.
4255fcf3ce44SJohn Forte  * Returns false if shadow volume is not exported, or set is suspended.
4256fcf3ce44SJohn Forte  */
4257fcf3ce44SJohn Forte static int
4258fcf3ce44SJohn Forte is_exported(char *set)
4259fcf3ce44SJohn Forte {
4260fcf3ce44SJohn Forte 	dsw_stat_t args;
4261fcf3ce44SJohn Forte 	int rc;
4262fcf3ce44SJohn Forte 
4263*ea3068a7SRichard Lowe 	(void) strlcpy(args.shadow_vol, set, DSW_NAMELEN);
4264fcf3ce44SJohn Forte 	args.status = spcs_s_ucreate();
4265fcf3ce44SJohn Forte 
4266fcf3ce44SJohn Forte 	rc = do_ioctl(dsw_fd, DSWIOC_STAT, &args);
4267fcf3ce44SJohn Forte 	spcs_s_ufree(&args.status);
4268fcf3ce44SJohn Forte 
4269fcf3ce44SJohn Forte 	if (-1 == rc) {
4270fcf3ce44SJohn Forte 		/* set must be suspended, or being disabled */
4271fcf3ce44SJohn Forte 		return (0);
4272fcf3ce44SJohn Forte 	}
4273fcf3ce44SJohn Forte 
4274fcf3ce44SJohn Forte 	return ((args.stat & DSW_SHDEXPORT) == DSW_SHDEXPORT);
4275fcf3ce44SJohn Forte }
4276fcf3ce44SJohn Forte 
4277fcf3ce44SJohn Forte static void
4278fcf3ce44SJohn Forte conform_name(char **path)
4279fcf3ce44SJohn Forte {
4280fcf3ce44SJohn Forte 	char *cfgname;
4281fcf3ce44SJohn Forte 	int rc = cfg_get_canonical_name(cfg, *path, &cfgname);
4282fcf3ce44SJohn Forte 
4283fcf3ce44SJohn Forte 	if (rc < 0) {
4284fcf3ce44SJohn Forte 		dsw_error(gettext("Unable to parse config file"), NULL);
4285fcf3ce44SJohn Forte 	}
4286fcf3ce44SJohn Forte 	if (rc) {
4287570de38fSSurya Prakki 		(void) printf("  '%s'\n%s\n  '%s'\n", *path,
4288fcf3ce44SJohn Forte 		    gettext("is currently configured as"), cfgname);
4289fcf3ce44SJohn Forte 		check_action(gettext("Perform operation with indicated volume"
4290fcf3ce44SJohn Forte 		    " name?"));
4291fcf3ce44SJohn Forte 		*path = cfgname;
4292fcf3ce44SJohn Forte 		/*
4293fcf3ce44SJohn Forte 		 * NOTE: *path ought to be deallocated ('free(*path)') after
4294fcf3ce44SJohn Forte 		 * we're done with it, but since this routine is called just
4295fcf3ce44SJohn Forte 		 * before we exit, it doesn't really matter
4296fcf3ce44SJohn Forte 		 */
4297fcf3ce44SJohn Forte 	}
4298fcf3ce44SJohn Forte }
4299fcf3ce44SJohn Forte 
4300fcf3ce44SJohn Forte /*
4301fcf3ce44SJohn Forte  * verify_groupname(char *, int);
4302fcf3ce44SJohn Forte  *
4303fcf3ce44SJohn Forte  * Check the group name for the following rules:
4304fcf3ce44SJohn Forte  *	1. The name does not start with a '-'
4305fcf3ce44SJohn Forte  *	2. The name does not contain any space characters as defined by
4306fcf3ce44SJohn Forte  *	   isspace(3C).
4307fcf3ce44SJohn Forte  * If either of these rules are broken, error immediately. The check for a
4308fcf3ce44SJohn Forte  * leading dash can be skipped if the 'testDash' argument is false. This is to
4309fcf3ce44SJohn Forte  * allow for the '-g -L' functionality.
4310fcf3ce44SJohn Forte  *
4311fcf3ce44SJohn Forte  */
4312fcf3ce44SJohn Forte static void
4313fcf3ce44SJohn Forte verify_groupname(char *grp, int testDash)
4314fcf3ce44SJohn Forte {
4315fcf3ce44SJohn Forte 	int i;
4316fcf3ce44SJohn Forte 
4317fcf3ce44SJohn Forte 	if (testDash && grp[0] == '-') {
4318fcf3ce44SJohn Forte 		errno = EINVAL;
4319fcf3ce44SJohn Forte 		dsw_error(gettext("group name cannot start with a '-'"), NULL);
4320fcf3ce44SJohn Forte 	}
4321fcf3ce44SJohn Forte 
4322fcf3ce44SJohn Forte 	for (i = 0; grp[i] != '\0'; i++) {
4323fcf3ce44SJohn Forte 		if (isspace(grp[i])) {
4324fcf3ce44SJohn Forte 			errno = EINVAL;
4325fcf3ce44SJohn Forte 			dsw_error(gettext("group name cannot contain a space"),
4326fcf3ce44SJohn Forte 			    NULL);
4327fcf3ce44SJohn Forte 		}
4328fcf3ce44SJohn Forte 	}
4329fcf3ce44SJohn Forte }
4330fcf3ce44SJohn Forte 
4331fcf3ce44SJohn Forte void
4332fcf3ce44SJohn Forte check_iishadow(char *shadow_vol) {
4333fcf3ce44SJohn Forte 	int i;
4334fcf3ce44SJohn Forte 	int entries;
4335fcf3ce44SJohn Forte 	char **entry;
4336fcf3ce44SJohn Forte 	char *shost;
4337fcf3ce44SJohn Forte 	char *svol;
4338fcf3ce44SJohn Forte 	char *buf;
4339fcf3ce44SJohn Forte 	void *librdc;
4340fcf3ce44SJohn Forte 
4341fcf3ce44SJohn Forte 	/*
4342fcf3ce44SJohn Forte 	 * See if librdc is around
4343fcf3ce44SJohn Forte 	 * If not, we can just return
4344fcf3ce44SJohn Forte 	 */
4345fcf3ce44SJohn Forte 	if (librdc = dlopen(RDC_LIB, RTLD_LAZY | RTLD_GLOBAL))
4346fcf3ce44SJohn Forte 		self_check = (int (*)(char *)) dlsym(librdc, "self_check");
4347fcf3ce44SJohn Forte 	else {
4348fcf3ce44SJohn Forte 		return;
4349fcf3ce44SJohn Forte 	}
4350fcf3ce44SJohn Forte 
4351fcf3ce44SJohn Forte 	entry = NULL;
4352fcf3ce44SJohn Forte 	entries = cfg_get_section(cfg, &entry, "sndr");
4353fcf3ce44SJohn Forte 	for (i = 0; i < entries; i++) {
4354fcf3ce44SJohn Forte 		buf = entry[i];
4355fcf3ce44SJohn Forte 
4356fcf3ce44SJohn Forte 		(void) strtok(buf, " ");	/* phost */
4357fcf3ce44SJohn Forte 		(void) strtok(NULL, " ");	/* primary */
4358fcf3ce44SJohn Forte 		(void) strtok(NULL, " ");	/* pbitmap */
4359fcf3ce44SJohn Forte 		shost = strtok(NULL, " ");	/* shost */
4360fcf3ce44SJohn Forte 		svol = strtok(NULL, " ");	/* secondary */
4361fcf3ce44SJohn Forte 
4362fcf3ce44SJohn Forte 		if (self_check(shost) && (strcmp(shadow_vol, svol) == 0)) {
4363fcf3ce44SJohn Forte 			free(buf);
4364fcf3ce44SJohn Forte 			if (entries)
4365fcf3ce44SJohn Forte 				free(entry);
4366fcf3ce44SJohn Forte 			errno = EINVAL;
4367fcf3ce44SJohn Forte 			dsw_error(gettext(
4368fcf3ce44SJohn Forte 			    "shadow volume is in use as SNDR secondary volume"),
4369fcf3ce44SJohn Forte 			    NULL);
4370fcf3ce44SJohn Forte 		}
4371fcf3ce44SJohn Forte 		free(buf);
4372fcf3ce44SJohn Forte 	}
4373fcf3ce44SJohn Forte 
4374fcf3ce44SJohn Forte 	(void) dlclose(librdc);
4375fcf3ce44SJohn Forte 	if (entries)
4376fcf3ce44SJohn Forte 		free(entry);
4377fcf3ce44SJohn Forte }
4378