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