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 2008 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 fprintf(stderr, gettext("Error opening config\n")); 94 exit(1); 95 } 96 97 if (!cfg_lock(cfg, CFG_WRLOCK)) { 98 spcs_log("ii", NULL, 99 "iicpbmp CFG_WRLOCK failed, errno %d", errno); 100 fprintf(stderr, gettext("Error locking config\n")); 101 exit(1); 102 } 103 } 104 105 for (argv++; *argv != NULL; argv += 2) 106 copybmp(argv[0], argv[1]); 107 if (update_cfg) 108 cfg_close(cfg); 109 exit(0); 110 return (0); 111 } 112 113 void 114 iicpbmp_usage() 115 { 116 fprintf(stderr, gettext("Usage:\n")); 117 fprintf(stderr, gettext("\tiicpbmp [-c] old_bitmap new_bitmap\n")); 118 exit(1); 119 } 120 121 void 122 copybmp(char *old_bitmap, char *new_bitmap) 123 { 124 int i; 125 int dsw_fd; 126 FILE *ifp, *ofp; 127 ii_header_t header; 128 char cp_buffer[256]; 129 dsw_stat_t args; 130 131 dsw_fd = open(DSWDEV, O_RDONLY); 132 if (dsw_fd < 0) { 133 perror(DSWDEV); 134 exit(1); 135 } 136 if (*old_bitmap != '/' || *new_bitmap != '/') { 137 fprintf(stderr, gettext( 138 "Both old and new bitmap file names must begin with a /.\n")); 139 exit(1); 140 } 141 142 if (strlen(new_bitmap) > DSW_NAMELEN) { 143 fprintf(stderr, gettext("New bitmap name is to long.\n")); 144 exit(1); 145 } 146 147 if (update_cfg && find_bitmap_cfg(old_bitmap) == 0) { 148 perror(old_bitmap); 149 fprintf(stderr, gettext("Old bitmap not in existing cfg\n")); 150 exit(1); 151 } 152 153 strncpy(args.shadow_vol, shadow, DSW_NAMELEN); 154 args.shadow_vol[DSW_NAMELEN-1] = '\0'; 155 156 args.status = spcs_s_ucreate(); 157 if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) { 158 fprintf(stderr, gettext("Suspend the Point-in-Time Copy " 159 "set first\n")); 160 close(dsw_fd); 161 exit(1); 162 } 163 164 if ((ifp = fopen(old_bitmap, "r")) == NULL) { 165 perror(old_bitmap); 166 fprintf(stderr, gettext("Can't open old bitmap file\n")); 167 exit(1); 168 } 169 170 /* Check old header looks like an Point-in-Time Copy bitmap header */ 171 172 if (fread(&header, sizeof (header), 1, ifp) != 1) { 173 fprintf(stderr, gettext("Can't read old bitmap file\n")); 174 exit(1); 175 } 176 177 if (header.ii_magic != DSW_CLEAN && header.ii_magic != DSW_DIRTY) { 178 fprintf(stderr, gettext("%s is not a Point-in-Time Copy " 179 "bitmap.\n"), old_bitmap); 180 exit(1); 181 } 182 183 if (strncmp(header.bitmap_vol, old_bitmap, DSW_NAMELEN) != 0) { 184 fprintf(stderr, gettext( 185 "%s has Point-in-Time Copy bitmap magic number,\n" 186 "but does not contain correct data.\n"), old_bitmap); 187 exit(1); 188 } 189 190 if ((ofp = fopen(new_bitmap, "w")) == NULL) { 191 perror(new_bitmap); 192 fprintf(stderr, gettext("Can't open new bitmap file\n")); 193 exit(1); 194 } 195 196 /* Set up new header */ 197 198 memset(header.bitmap_vol, 0, DSW_NAMELEN); 199 strncpy(header.bitmap_vol, new_bitmap, DSW_NAMELEN); 200 201 if (fwrite(&header, sizeof (header), 1, ofp) != 1) { 202 perror(new_bitmap); 203 fprintf(stderr, gettext("Can't write new bitmap header\n")); 204 exit(1); 205 } 206 207 /* Copy the bitmap itself */ 208 209 while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ifp)) 210 > 0) { 211 if (fwrite(cp_buffer, sizeof (char), i, ofp) != i) { 212 perror(gettext("Write new bitmap failed")); 213 break; 214 } 215 } 216 fclose(ofp); 217 fclose(ifp); 218 close(dsw_fd); 219 if (update_cfg) { 220 sprintf(key, "ii.set%d.bitmap", setnumber); 221 if (cfg_put_cstring(cfg, key, new_bitmap, strlen(new_bitmap)) 222 < 0) { 223 perror("cfg_put_cstring"); 224 } 225 cfg_commit(cfg); 226 spcs_log("ii", NULL, 227 "iicpbmp copy bit map for %s from %s to %s", 228 shadow, old_bitmap, new_bitmap); 229 } 230 } 231 232 /* 233 * find_bitmap_cfg() 234 * 235 */ 236 237 int 238 find_bitmap_cfg(char *bitmap) 239 { 240 for (setnumber = 1; ; setnumber++) { 241 bzero(buf, CFG_MAX_BUF); 242 snprintf(key, sizeof (key), "ii.set%d.bitmap", setnumber); 243 if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0) 244 return (0); 245 if (strcmp(buf, bitmap) == 0) { 246 snprintf(key, sizeof (key), "ii.set%d.shadow", 247 setnumber); 248 cfg_get_cstring(cfg, key, shadow, DSW_NAMELEN); 249 return (setnumber); 250 } 251 } 252 } 253