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
iicpshd_lintmain(int argc,char * argv[])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
iicpshd_usage()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
copyshd(char * old_vol,char * new_vol)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
find_cfg_info(char * volume,char * token)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
copy_shadow_vol(char * old_shadow,char * new_shadow)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
update_dscfg(char * new_shadow)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
convert_to_blockdevice()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