1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte 22*fcf3ce44SJohn Forte /* 23*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*fcf3ce44SJohn Forte * Use is subject to license terms. 25*fcf3ce44SJohn Forte */ 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte #include <sys/types.h> 28*fcf3ce44SJohn Forte #include <sys/time.h> 29*fcf3ce44SJohn Forte #include <errno.h> 30*fcf3ce44SJohn Forte #include <signal.h> 31*fcf3ce44SJohn Forte #include <stdio.h> 32*fcf3ce44SJohn Forte #include <string.h> 33*fcf3ce44SJohn Forte #include <fcntl.h> 34*fcf3ce44SJohn Forte #include <stdlib.h> 35*fcf3ce44SJohn Forte #include <unistd.h> 36*fcf3ce44SJohn Forte #include <values.h> 37*fcf3ce44SJohn Forte #include <locale.h> 38*fcf3ce44SJohn Forte #include <sys/stat.h> 39*fcf3ce44SJohn Forte #include <strings.h> 40*fcf3ce44SJohn Forte #include <stdarg.h> 41*fcf3ce44SJohn Forte #include <sys/param.h> 42*fcf3ce44SJohn Forte #include <nsctl.h> 43*fcf3ce44SJohn Forte 44*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h> 45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h> 46*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h> 47*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h> 48*fcf3ce44SJohn Forte #include <sys/nsctl/dsw.h> 49*fcf3ce44SJohn Forte #include <sys/nsctl/dsw_dev.h> /* for bitmap format */ 50*fcf3ce44SJohn Forte 51*fcf3ce44SJohn Forte #define DSW_TEXT_DOMAIN "II" 52*fcf3ce44SJohn Forte #define BITMAP_TOKEN "ii.set%d.bitmap" 53*fcf3ce44SJohn Forte #define SHADOW_TOKEN "ii.set%d.shadow" 54*fcf3ce44SJohn Forte #define SV_TOKEN "sv.set%d.vol" 55*fcf3ce44SJohn Forte #define DSVOL_TOKEN "dsvol.set%d.path" 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte void iicpshd_usage(); 58*fcf3ce44SJohn Forte void copyshd(char *, char *); 59*fcf3ce44SJohn Forte int find_cfg_info(char *, char *); 60*fcf3ce44SJohn Forte int copy_shadow_vol(char *, char *); 61*fcf3ce44SJohn Forte void convert_to_blockdevice(); 62*fcf3ce44SJohn Forte int update_dscfg(char *); 63*fcf3ce44SJohn Forte 64*fcf3ce44SJohn Forte extern int optind; 65*fcf3ce44SJohn Forte 66*fcf3ce44SJohn Forte extern char *optarg; 67*fcf3ce44SJohn Forte extern int optind, opterr, optopt; 68*fcf3ce44SJohn Forte int copy_shadow = 1; 69*fcf3ce44SJohn Forte CFGFILE *cfg; 70*fcf3ce44SJohn Forte char real_bitmap[DSW_NAMELEN]; 71*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 72*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 73*fcf3ce44SJohn Forte int set_number; 74*fcf3ce44SJohn Forte int sv_number; 75*fcf3ce44SJohn Forte int dsvol_number; 76*fcf3ce44SJohn Forte 77*fcf3ce44SJohn Forte #ifdef lint 78*fcf3ce44SJohn Forte int 79*fcf3ce44SJohn Forte iicpshd_lintmain(int argc, char *argv[]) 80*fcf3ce44SJohn Forte #else 81*fcf3ce44SJohn Forte int 82*fcf3ce44SJohn Forte main(int argc, char *argv[]) 83*fcf3ce44SJohn Forte #endif 84*fcf3ce44SJohn Forte { 85*fcf3ce44SJohn Forte if (argc > 1) { 86*fcf3ce44SJohn Forte if (strcmp(argv[1], "-s") == 0) { 87*fcf3ce44SJohn Forte /* don't copy shadow, only update dscfg and ii header */ 88*fcf3ce44SJohn Forte copy_shadow = 0; 89*fcf3ce44SJohn Forte argc--; 90*fcf3ce44SJohn Forte argv++; 91*fcf3ce44SJohn Forte } 92*fcf3ce44SJohn Forte } 93*fcf3ce44SJohn Forte 94*fcf3ce44SJohn Forte if (argc == 1 || (argc%2) == 0) /* must have pairs of filenames */ 95*fcf3ce44SJohn Forte iicpshd_usage(); 96*fcf3ce44SJohn Forte 97*fcf3ce44SJohn Forte /* open dscfg anyway */ 98*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 99*fcf3ce44SJohn Forte fprintf(stderr, gettext("Error opening config\n")); 100*fcf3ce44SJohn Forte exit(1); 101*fcf3ce44SJohn Forte } 102*fcf3ce44SJohn Forte 103*fcf3ce44SJohn Forte for (argv++; *argv != NULL; argv += 2) 104*fcf3ce44SJohn Forte copyshd(argv[0], argv[1]); 105*fcf3ce44SJohn Forte 106*fcf3ce44SJohn Forte /* close dscfg */ 107*fcf3ce44SJohn Forte cfg_close(cfg); 108*fcf3ce44SJohn Forte exit(0); 109*fcf3ce44SJohn Forte return (0); 110*fcf3ce44SJohn Forte } 111*fcf3ce44SJohn Forte 112*fcf3ce44SJohn Forte void 113*fcf3ce44SJohn Forte iicpshd_usage() 114*fcf3ce44SJohn Forte { 115*fcf3ce44SJohn Forte fprintf(stderr, gettext("Usage:\n")); 116*fcf3ce44SJohn Forte fprintf(stderr, gettext("\tiicpshd [-s] old_shadow new_shadow\n")); 117*fcf3ce44SJohn Forte exit(1); 118*fcf3ce44SJohn Forte } 119*fcf3ce44SJohn Forte 120*fcf3ce44SJohn Forte void 121*fcf3ce44SJohn Forte copyshd(char *old_vol, char *new_vol) 122*fcf3ce44SJohn Forte { 123*fcf3ce44SJohn Forte int dsw_fd; 124*fcf3ce44SJohn Forte FILE *ifp; 125*fcf3ce44SJohn Forte char header[FBA_SIZE(1) * DSW_CBLK_FBA]; 126*fcf3ce44SJohn Forte ii_header_t *hp; 127*fcf3ce44SJohn Forte dsw_stat_t args; 128*fcf3ce44SJohn Forte 129*fcf3ce44SJohn Forte /*LINTED pointer alignment*/ 130*fcf3ce44SJohn Forte hp = (ii_header_t *)&header; 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte dsw_fd = open(DSWDEV, O_RDONLY); 133*fcf3ce44SJohn Forte if (dsw_fd < 0) { 134*fcf3ce44SJohn Forte perror(DSWDEV); 135*fcf3ce44SJohn Forte exit(1); 136*fcf3ce44SJohn Forte } 137*fcf3ce44SJohn Forte if (*old_vol != '/' || *new_vol != '/') { 138*fcf3ce44SJohn Forte fprintf(stderr, gettext( 139*fcf3ce44SJohn Forte "Both old and new shadow file names must begin with a /.\n")); 140*fcf3ce44SJohn Forte exit(1); 141*fcf3ce44SJohn Forte } 142*fcf3ce44SJohn Forte 143*fcf3ce44SJohn Forte if (strlen(new_vol) > DSW_NAMELEN) { 144*fcf3ce44SJohn Forte fprintf(stderr, gettext("New shadow name is to long.\n")); 145*fcf3ce44SJohn Forte exit(1); 146*fcf3ce44SJohn Forte } 147*fcf3ce44SJohn Forte 148*fcf3ce44SJohn Forte /* check old shadow is in dscfg */ 149*fcf3ce44SJohn Forte if (find_cfg_info(old_vol, SHADOW_TOKEN) == 0) { 150*fcf3ce44SJohn Forte fprintf(stderr, gettext("Old shadow not in existing cfg\n")); 151*fcf3ce44SJohn Forte exit(1); 152*fcf3ce44SJohn Forte } 153*fcf3ce44SJohn Forte 154*fcf3ce44SJohn Forte /* check ii set status, suspend if need */ 155*fcf3ce44SJohn Forte strncpy(args.shadow_vol, old_vol, DSW_NAMELEN); 156*fcf3ce44SJohn Forte args.shadow_vol[DSW_NAMELEN-1] = '\0'; 157*fcf3ce44SJohn Forte args.status = spcs_s_ucreate(); 158*fcf3ce44SJohn Forte if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) { 159*fcf3ce44SJohn Forte fprintf(stderr, gettext("Suspend the Point-in-Time Copy " 160*fcf3ce44SJohn Forte "set first\n")); 161*fcf3ce44SJohn Forte close(dsw_fd); 162*fcf3ce44SJohn Forte exit(1); 163*fcf3ce44SJohn Forte } 164*fcf3ce44SJohn Forte 165*fcf3ce44SJohn Forte if (copy_shadow) { 166*fcf3ce44SJohn Forte if (copy_shadow_vol(old_vol, new_vol) == 0) { 167*fcf3ce44SJohn Forte perror(gettext("Write new shadow failed")); 168*fcf3ce44SJohn Forte close(dsw_fd); 169*fcf3ce44SJohn Forte exit(1); 170*fcf3ce44SJohn Forte } 171*fcf3ce44SJohn Forte } 172*fcf3ce44SJohn Forte if (find_cfg_info(old_vol, SV_TOKEN) == 0) { 173*fcf3ce44SJohn Forte fprintf(stderr, gettext("Old shadow not in existing cfg\n")); 174*fcf3ce44SJohn Forte exit(1); 175*fcf3ce44SJohn Forte } 176*fcf3ce44SJohn Forte if (find_cfg_info(old_vol, DSVOL_TOKEN) == 0) { 177*fcf3ce44SJohn Forte fprintf(stderr, gettext("Old shadow not in existing cfg\n")); 178*fcf3ce44SJohn Forte exit(1); 179*fcf3ce44SJohn Forte } 180*fcf3ce44SJohn Forte if (strstr(real_bitmap, "/rdsk/") == NULL) { 181*fcf3ce44SJohn Forte fprintf(stderr, 182*fcf3ce44SJohn Forte gettext("%s is not a character device\n"), real_bitmap); 183*fcf3ce44SJohn Forte exit(1); 184*fcf3ce44SJohn Forte } 185*fcf3ce44SJohn Forte 186*fcf3ce44SJohn Forte /* use block device /dsk/ to update bitmap header */ 187*fcf3ce44SJohn Forte convert_to_blockdevice(); 188*fcf3ce44SJohn Forte 189*fcf3ce44SJohn Forte /* open bitmap by using update mode */ 190*fcf3ce44SJohn Forte if ((ifp = fopen(real_bitmap, "r+")) == NULL) { 191*fcf3ce44SJohn Forte fprintf(stderr, gettext("Can't open bitmap file\n")); 192*fcf3ce44SJohn Forte exit(1); 193*fcf3ce44SJohn Forte } 194*fcf3ce44SJohn Forte 195*fcf3ce44SJohn Forte /* Check old header looks like an II bitmap header */ 196*fcf3ce44SJohn Forte if (fread(&header, DSW_CBLK_FBA, FBA_SIZE(1), ifp) != FBA_SIZE(1)) { 197*fcf3ce44SJohn Forte fprintf(stderr, gettext("Can't read bitmap file\n")); 198*fcf3ce44SJohn Forte exit(1); 199*fcf3ce44SJohn Forte } 200*fcf3ce44SJohn Forte 201*fcf3ce44SJohn Forte if (hp->ii_magic != DSW_CLEAN && hp->ii_magic != DSW_DIRTY) { 202*fcf3ce44SJohn Forte fprintf(stderr, gettext("%s is not an Point-in-Time Copy " 203*fcf3ce44SJohn Forte "shadow.\n"), old_vol); 204*fcf3ce44SJohn Forte exit(1); 205*fcf3ce44SJohn Forte } 206*fcf3ce44SJohn Forte 207*fcf3ce44SJohn Forte if (strncmp(hp->shadow_vol, old_vol, DSW_NAMELEN) != 0) { 208*fcf3ce44SJohn Forte fprintf(stderr, gettext( 209*fcf3ce44SJohn Forte "%s has Point-in-Time Copy shadow magic number,\n" 210*fcf3ce44SJohn Forte "but does not contain correct data.\n"), old_vol); 211*fcf3ce44SJohn Forte exit(1); 212*fcf3ce44SJohn Forte } 213*fcf3ce44SJohn Forte 214*fcf3ce44SJohn Forte memset(hp->shadow_vol, 0, DSW_NAMELEN); 215*fcf3ce44SJohn Forte strncpy(hp->shadow_vol, new_vol, DSW_NAMELEN); 216*fcf3ce44SJohn Forte 217*fcf3ce44SJohn Forte /* reset the pointer position */ 218*fcf3ce44SJohn Forte rewind(ifp); 219*fcf3ce44SJohn Forte if (fwrite(&header, DSW_CBLK_FBA, FBA_SIZE(1), ifp) != FBA_SIZE(1)) { 220*fcf3ce44SJohn Forte perror(new_vol); 221*fcf3ce44SJohn Forte fprintf(stderr, gettext("Can't write new bitmap header\n")); 222*fcf3ce44SJohn Forte exit(1); 223*fcf3ce44SJohn Forte } 224*fcf3ce44SJohn Forte fclose(ifp); 225*fcf3ce44SJohn Forte close(dsw_fd); 226*fcf3ce44SJohn Forte if (update_dscfg(new_vol) == 0) { 227*fcf3ce44SJohn Forte fprintf(stderr, gettext("Failed to update dscfg.\n")); 228*fcf3ce44SJohn Forte exit(1); 229*fcf3ce44SJohn Forte } else { 230*fcf3ce44SJohn Forte spcs_log("ii", NULL, 231*fcf3ce44SJohn Forte "iicpshd copy shadow from %s to %s", 232*fcf3ce44SJohn Forte old_vol, new_vol); 233*fcf3ce44SJohn Forte } 234*fcf3ce44SJohn Forte } 235*fcf3ce44SJohn Forte 236*fcf3ce44SJohn Forte /* 237*fcf3ce44SJohn Forte * find_cfg_info() 238*fcf3ce44SJohn Forte * 239*fcf3ce44SJohn Forte */ 240*fcf3ce44SJohn Forte 241*fcf3ce44SJohn Forte int 242*fcf3ce44SJohn Forte find_cfg_info(char *volume, char *token) 243*fcf3ce44SJohn Forte { 244*fcf3ce44SJohn Forte int i; 245*fcf3ce44SJohn Forte /* get read lock */ 246*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) { 247*fcf3ce44SJohn Forte spcs_log("ii", NULL, 248*fcf3ce44SJohn Forte "iicpbmp CFG_RDLOCK failed, errno %d", errno); 249*fcf3ce44SJohn Forte fprintf(stderr, gettext("Error locking config\n")); 250*fcf3ce44SJohn Forte exit(1); 251*fcf3ce44SJohn Forte } 252*fcf3ce44SJohn Forte for (i = 1; ; i++) { 253*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 254*fcf3ce44SJohn Forte snprintf(key, sizeof (key), token, i); 255*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0) { 256*fcf3ce44SJohn Forte cfg_unlock(cfg); 257*fcf3ce44SJohn Forte return (0); 258*fcf3ce44SJohn Forte } 259*fcf3ce44SJohn Forte if (strcmp(buf, volume) == 0) { 260*fcf3ce44SJohn Forte if (strcmp(token, SHADOW_TOKEN) == 0) { 261*fcf3ce44SJohn Forte snprintf(key, sizeof (key), BITMAP_TOKEN, i); 262*fcf3ce44SJohn Forte cfg_get_cstring 263*fcf3ce44SJohn Forte (cfg, key, real_bitmap, DSW_NAMELEN); 264*fcf3ce44SJohn Forte set_number = i; 265*fcf3ce44SJohn Forte } else if (strcmp(token, SV_TOKEN) == 0) { 266*fcf3ce44SJohn Forte sv_number = i; 267*fcf3ce44SJohn Forte } else if (strcmp(token, DSVOL_TOKEN) == 0) { 268*fcf3ce44SJohn Forte dsvol_number = i; 269*fcf3ce44SJohn Forte } 270*fcf3ce44SJohn Forte /* release read lock */ 271*fcf3ce44SJohn Forte cfg_unlock(cfg); 272*fcf3ce44SJohn Forte return (1); 273*fcf3ce44SJohn Forte } 274*fcf3ce44SJohn Forte } 275*fcf3ce44SJohn Forte } 276*fcf3ce44SJohn Forte 277*fcf3ce44SJohn Forte int 278*fcf3ce44SJohn Forte copy_shadow_vol(char *old_shadow, char *new_shadow) { 279*fcf3ce44SJohn Forte int i; 280*fcf3ce44SJohn Forte char cp_buffer[256]; 281*fcf3ce44SJohn Forte FILE *ishdfp, *oshdfp; 282*fcf3ce44SJohn Forte if ((ishdfp = fopen(old_shadow, "r")) == NULL) { 283*fcf3ce44SJohn Forte fprintf(stderr, gettext("Can't open old shadow file\n")); 284*fcf3ce44SJohn Forte return (0); 285*fcf3ce44SJohn Forte } 286*fcf3ce44SJohn Forte if ((oshdfp = fopen(new_shadow, "w")) == NULL) { 287*fcf3ce44SJohn Forte fprintf(stderr, gettext("Can't open new shadow file\n")); 288*fcf3ce44SJohn Forte return (0); 289*fcf3ce44SJohn Forte } 290*fcf3ce44SJohn Forte 291*fcf3ce44SJohn Forte /* Copy the shadow vol */ 292*fcf3ce44SJohn Forte while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ishdfp)) 293*fcf3ce44SJohn Forte > 0) { 294*fcf3ce44SJohn Forte if (fwrite(cp_buffer, sizeof (char), i, oshdfp) != i) { 295*fcf3ce44SJohn Forte fclose(ishdfp); 296*fcf3ce44SJohn Forte fclose(oshdfp); 297*fcf3ce44SJohn Forte return (0); 298*fcf3ce44SJohn Forte } 299*fcf3ce44SJohn Forte } 300*fcf3ce44SJohn Forte fclose(ishdfp); 301*fcf3ce44SJohn Forte fclose(oshdfp); 302*fcf3ce44SJohn Forte return (1); 303*fcf3ce44SJohn Forte } 304*fcf3ce44SJohn Forte 305*fcf3ce44SJohn Forte int 306*fcf3ce44SJohn Forte update_dscfg(char *new_shadow) { 307*fcf3ce44SJohn Forte 308*fcf3ce44SJohn Forte int len = strlen(new_shadow); 309*fcf3ce44SJohn Forte /* get write lock */ 310*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 311*fcf3ce44SJohn Forte spcs_log("ii", NULL, 312*fcf3ce44SJohn Forte "iicpbmp CFG_WRLOCK failed, errno %d", errno); 313*fcf3ce44SJohn Forte fprintf(stderr, gettext("Error locking config\n")); 314*fcf3ce44SJohn Forte return (0); 315*fcf3ce44SJohn Forte } 316*fcf3ce44SJohn Forte sprintf(key, SHADOW_TOKEN, set_number); 317*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) { 318*fcf3ce44SJohn Forte perror("cfg_put_cstring"); 319*fcf3ce44SJohn Forte return (0); 320*fcf3ce44SJohn Forte } 321*fcf3ce44SJohn Forte sprintf(key, SV_TOKEN, sv_number); 322*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) { 323*fcf3ce44SJohn Forte perror("cfg_put_cstring"); 324*fcf3ce44SJohn Forte return (0); 325*fcf3ce44SJohn Forte } 326*fcf3ce44SJohn Forte sprintf(key, DSVOL_TOKEN, dsvol_number); 327*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) { 328*fcf3ce44SJohn Forte perror("cfg_put_cstring"); 329*fcf3ce44SJohn Forte return (0); 330*fcf3ce44SJohn Forte } 331*fcf3ce44SJohn Forte cfg_commit(cfg); 332*fcf3ce44SJohn Forte cfg_unlock(cfg); 333*fcf3ce44SJohn Forte return (1); 334*fcf3ce44SJohn Forte } 335*fcf3ce44SJohn Forte 336*fcf3ce44SJohn Forte void 337*fcf3ce44SJohn Forte convert_to_blockdevice() { 338*fcf3ce44SJohn Forte int len = strlen(real_bitmap); 339*fcf3ce44SJohn Forte int i = 0, j = 0; 340*fcf3ce44SJohn Forte char *temp_string = malloc(len-1); 341*fcf3ce44SJohn Forte while (i < len + 1) { 342*fcf3ce44SJohn Forte if (real_bitmap[i] != 'r') { 343*fcf3ce44SJohn Forte temp_string[j] = real_bitmap[i]; 344*fcf3ce44SJohn Forte j++; 345*fcf3ce44SJohn Forte } 346*fcf3ce44SJohn Forte i++; 347*fcf3ce44SJohn Forte } 348*fcf3ce44SJohn Forte strcpy(real_bitmap, temp_string); 349*fcf3ce44SJohn Forte free(temp_string); 350*fcf3ce44SJohn Forte } 351