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