xref: /titanic_50/usr/src/cmd/avs/dsw/iicpshd.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
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