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
iiadm_lintmain(int argc,char * argv[])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
ii_lock(CFGFILE * cfg,int locktype)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
do_ioctl(int fd,int cmd,void * arg)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
get_dsw_config(int setno,dsw_config_t * parms)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
find_next_cf_line(char * volume,int next)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
find_any_cf_line(char * volume)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
find_next_shadow_line(char * volume,int next)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
find_shadow_line(char * volume)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 *
get_overflow_list()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
find_group_members(char * group)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
find_next_matching_cf_line(char * volume,dsw_config_t * conf,dsw_ioctl_t * io,int next)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
find_matching_cf_line(char * volume,dsw_config_t * conf,dsw_ioctl_t * io)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
find_shadow_config(char * volume,dsw_config_t * conf,dsw_ioctl_t * io)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
add_cfg_entry(dsw_config_t * parms)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
remove_iiset(int setno,char * shadow,int shd_exp)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
check_cluster()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
check_resource_group(char * volume)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, ©_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, ©_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, ©_args);
2666fcf3ce44SJohn Forte if (rc == -1) {
2667fcf3ce44SJohn Forte spcs_log("ii", ©_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"), ©_args.status);
2675fcf3ce44SJohn Forte }
2676fcf3ce44SJohn Forte spcs_s_ufree(©_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