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