1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/time.h> 28 #include <errno.h> 29 #include <signal.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <fcntl.h> 33 #include <stdlib.h> 34 #include <unistd.h> 35 #include <values.h> 36 #include <locale.h> 37 #include <sys/stat.h> 38 #include <strings.h> 39 #include <stdarg.h> 40 #include <sys/param.h> 41 #include <nsctl.h> 42 43 #include <sys/nsctl/cfg.h> 44 #include <sys/unistat/spcs_s.h> 45 #include <sys/unistat/spcs_s_u.h> 46 #include <sys/unistat/spcs_errors.h> 47 #include <sys/nsctl/dsw.h> 48 #include <sys/nsctl/dsw_dev.h> 49 50 #define DSW_TEXT_DOMAIN "II" 51 52 void iicpbmp_usage(); 53 void copybmp(char *, char *); 54 int find_bitmap_cfg(char *); 55 56 extern int optind; 57 58 char *cmdnam; 59 60 extern char *optarg; 61 extern int optind, opterr, optopt; 62 int update_cfg = 1; 63 CFGFILE *cfg; 64 char shadow[DSW_NAMELEN]; 65 char buf[CFG_MAX_BUF]; 66 char key[CFG_MAX_KEY]; 67 int setnumber; 68 69 #ifdef lint 70 int 71 iicpbmp_lintmain(int argc, char *argv[]) 72 #else 73 int 74 main(int argc, char *argv[]) 75 #endif 76 { 77 cmdnam = argv[0]; 78 79 if (argc > 1) { 80 if (strcmp(argv[1], "-c") == 0) { 81 /* don't update cfg information */ 82 update_cfg = 0; 83 argc--; 84 argv++; 85 } 86 } 87 88 if (argc == 1 || (argc%2) == 0) /* must have pairs of filenames */ 89 iicpbmp_usage(); 90 91 if (update_cfg) { 92 if ((cfg = cfg_open(NULL)) == NULL) { 93 (void) fprintf(stderr, 94 gettext("Error opening config\n")); 95 exit(1); 96 } 97 98 if (!cfg_lock(cfg, CFG_WRLOCK)) { 99 spcs_log("ii", NULL, 100 "iicpbmp CFG_WRLOCK failed, errno %d", errno); 101 (void) fprintf(stderr, 102 gettext("Error locking config\n")); 103 exit(1); 104 } 105 } 106 107 for (argv++; *argv != NULL; argv += 2) 108 copybmp(argv[0], argv[1]); 109 if (update_cfg) 110 cfg_close(cfg); 111 exit(0); 112 return (0); 113 } 114 115 void 116 iicpbmp_usage() 117 { 118 (void) fprintf(stderr, gettext("Usage:\n")); 119 (void) fprintf(stderr, 120 gettext("\tiicpbmp [-c] old_bitmap new_bitmap\n")); 121 exit(1); 122 } 123 124 void 125 copybmp(char *old_bitmap, char *new_bitmap) 126 { 127 int i; 128 int dsw_fd; 129 FILE *ifp, *ofp; 130 ii_header_t header; 131 char cp_buffer[256]; 132 dsw_stat_t args; 133 134 dsw_fd = open(DSWDEV, O_RDONLY); 135 if (dsw_fd < 0) { 136 perror(DSWDEV); 137 exit(1); 138 } 139 if (*old_bitmap != '/' || *new_bitmap != '/') { 140 (void) fprintf(stderr, gettext("Both old and new bitmap " 141 "file names must begin with a /.\n")); 142 exit(1); 143 } 144 145 if (strlen(new_bitmap) > DSW_NAMELEN) { 146 (void) fprintf(stderr, 147 gettext("New bitmap name is too long.\n")); 148 exit(1); 149 } 150 151 if (update_cfg && find_bitmap_cfg(old_bitmap) == 0) { 152 perror(old_bitmap); 153 (void) fprintf(stderr, 154 gettext("Old bitmap not in existing cfg\n")); 155 exit(1); 156 } 157 158 (void) strncpy(args.shadow_vol, shadow, DSW_NAMELEN); 159 args.shadow_vol[DSW_NAMELEN-1] = '\0'; 160 161 args.status = spcs_s_ucreate(); 162 if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) { 163 (void) fprintf(stderr, gettext("Suspend the Point-in-Time Copy " 164 "set first\n")); 165 (void) close(dsw_fd); 166 exit(1); 167 } 168 169 if ((ifp = fopen(old_bitmap, "r")) == NULL) { 170 perror(old_bitmap); 171 (void) fprintf(stderr, gettext("Can't open old bitmap file\n")); 172 exit(1); 173 } 174 175 /* Check old header looks like an Point-in-Time Copy bitmap header */ 176 177 if (fread(&header, sizeof (header), 1, ifp) != 1) { 178 (void) fprintf(stderr, gettext("Can't read old bitmap file\n")); 179 exit(1); 180 } 181 182 if (header.ii_magic != DSW_CLEAN && header.ii_magic != DSW_DIRTY) { 183 (void) fprintf(stderr, gettext("%s is not a Point-in-Time Copy " 184 "bitmap.\n"), old_bitmap); 185 exit(1); 186 } 187 188 if (strncmp(header.bitmap_vol, old_bitmap, DSW_NAMELEN) != 0) { 189 (void) fprintf(stderr, gettext( 190 "%s has Point-in-Time Copy bitmap magic number,\n" 191 "but does not contain correct data.\n"), old_bitmap); 192 exit(1); 193 } 194 195 if ((ofp = fopen(new_bitmap, "w")) == NULL) { 196 perror(new_bitmap); 197 (void) fprintf(stderr, gettext("Can't open new bitmap file\n")); 198 exit(1); 199 } 200 201 /* Set up new header */ 202 203 (void) memset(header.bitmap_vol, 0, DSW_NAMELEN); 204 (void) strncpy(header.bitmap_vol, new_bitmap, DSW_NAMELEN); 205 206 if (fwrite(&header, sizeof (header), 1, ofp) != 1) { 207 perror(new_bitmap); 208 (void) fprintf(stderr, 209 gettext("Can't write new bitmap header\n")); 210 exit(1); 211 } 212 213 /* Copy the bitmap itself */ 214 215 while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ifp)) 216 > 0) { 217 if (fwrite(cp_buffer, sizeof (char), i, ofp) != i) { 218 perror(gettext("Write new bitmap failed")); 219 break; 220 } 221 } 222 (void) fclose(ofp); 223 (void) fclose(ifp); 224 (void) close(dsw_fd); 225 if (update_cfg) { 226 (void) sprintf(key, "ii.set%d.bitmap", setnumber); 227 if (cfg_put_cstring(cfg, key, new_bitmap, strlen(new_bitmap)) 228 < 0) { 229 perror("cfg_put_cstring"); 230 } 231 (void) cfg_commit(cfg); 232 spcs_log("ii", NULL, 233 "iicpbmp copy bit map for %s from %s to %s", 234 shadow, old_bitmap, new_bitmap); 235 } 236 } 237 238 /* 239 * find_bitmap_cfg() 240 * 241 */ 242 243 int 244 find_bitmap_cfg(char *bitmap) 245 { 246 for (setnumber = 1; ; setnumber++) { 247 bzero(buf, CFG_MAX_BUF); 248 (void) snprintf(key, sizeof (key), "ii.set%d.bitmap", 249 setnumber); 250 251 if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0) 252 return (0); 253 if (strcmp(buf, bitmap) == 0) { 254 (void) snprintf(key, sizeof (key), "ii.set%d.shadow", 255 setnumber); 256 (void) cfg_get_cstring(cfg, key, shadow, DSW_NAMELEN); 257 return (setnumber); 258 } 259 } 260 } 261