xref: /titanic_50/usr/src/cmd/avs/dsbitmap/dsbitmap.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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte #include <sys/types.h>
27*fcf3ce44SJohn Forte #include <sys/stat.h>
28*fcf3ce44SJohn Forte #include <sys/dkio.h>
29*fcf3ce44SJohn Forte #include <sys/vtoc.h>
30*fcf3ce44SJohn Forte #include <sys/mkdev.h>
31*fcf3ce44SJohn Forte #ifdef DKIOCPARTITION
32*fcf3ce44SJohn Forte #include <sys/efi_partition.h>
33*fcf3ce44SJohn Forte #endif
34*fcf3ce44SJohn Forte #include <strings.h>
35*fcf3ce44SJohn Forte #include <stdarg.h>
36*fcf3ce44SJohn Forte #include <stdlib.h>
37*fcf3ce44SJohn Forte #include <fcntl.h>
38*fcf3ce44SJohn Forte #include <errno.h>
39*fcf3ce44SJohn Forte #include <stdio.h>
40*fcf3ce44SJohn Forte #include <locale.h>
41*fcf3ce44SJohn Forte #include <unistd.h>
42*fcf3ce44SJohn Forte #include <libgen.h>
43*fcf3ce44SJohn Forte #include <kstat.h>
44*fcf3ce44SJohn Forte 
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 
49*fcf3ce44SJohn Forte #include <sys/nsctl/dsw.h>
50*fcf3ce44SJohn Forte #include <sys/nsctl/dsw_dev.h>
51*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_io.h>
52*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_bitmap.h>
53*fcf3ce44SJohn Forte 
54*fcf3ce44SJohn Forte enum { UNKNOWN = 0, SNDR, II };
55*fcf3ce44SJohn Forte 
56*fcf3ce44SJohn Forte static char *program;
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte void
usage(void)59*fcf3ce44SJohn Forte usage(void)
60*fcf3ce44SJohn Forte {
61*fcf3ce44SJohn Forte 	(void) printf(gettext("usage: %s -h\n"), program);
62*fcf3ce44SJohn Forte 	(void) printf(gettext("       %s { -p | -r } data_volume "
63*fcf3ce44SJohn Forte 	    "[bitmap_volume]\n"), program);
64*fcf3ce44SJohn Forte 	(void) printf(gettext("       -h : This usage message\n"));
65*fcf3ce44SJohn Forte 	(void) printf(gettext("       -p : Calculate size of Point in Time "
66*fcf3ce44SJohn Forte 	    "bitmap\n"));
67*fcf3ce44SJohn Forte 	(void) printf(gettext("       -r : Calculate size of Remote Mirror "
68*fcf3ce44SJohn Forte 	    "bitmap\n"));
69*fcf3ce44SJohn Forte }
70*fcf3ce44SJohn Forte 
71*fcf3ce44SJohn Forte 
72*fcf3ce44SJohn Forte static void
message(char * prefix,spcs_s_info_t * status,caddr_t string,va_list ap)73*fcf3ce44SJohn Forte message(char *prefix, spcs_s_info_t *status, caddr_t string, va_list ap)
74*fcf3ce44SJohn Forte {
75*fcf3ce44SJohn Forte 	(void) fprintf(stderr, "%s: %s: ", program, prefix);
76*fcf3ce44SJohn Forte 	(void) vfprintf(stderr, string, ap);
77*fcf3ce44SJohn Forte 	(void) fprintf(stderr, "\n");
78*fcf3ce44SJohn Forte 
79*fcf3ce44SJohn Forte 	if (status) {
80*fcf3ce44SJohn Forte 		spcs_s_report(*status, stderr);
81*fcf3ce44SJohn Forte 		spcs_s_ufree(status);
82*fcf3ce44SJohn Forte 	}
83*fcf3ce44SJohn Forte }
84*fcf3ce44SJohn Forte 
85*fcf3ce44SJohn Forte 
86*fcf3ce44SJohn Forte static void
error(spcs_s_info_t * status,char * string,...)87*fcf3ce44SJohn Forte error(spcs_s_info_t *status, char *string, ...)
88*fcf3ce44SJohn Forte {
89*fcf3ce44SJohn Forte 	va_list ap;
90*fcf3ce44SJohn Forte 	va_start(ap, string);
91*fcf3ce44SJohn Forte 
92*fcf3ce44SJohn Forte 	message(gettext("error"), status, string, ap);
93*fcf3ce44SJohn Forte 	va_end(ap);
94*fcf3ce44SJohn Forte 	exit(1);
95*fcf3ce44SJohn Forte }
96*fcf3ce44SJohn Forte 
97*fcf3ce44SJohn Forte 
98*fcf3ce44SJohn Forte static void
warn(spcs_s_info_t * status,char * string,...)99*fcf3ce44SJohn Forte warn(spcs_s_info_t *status, char *string, ...)
100*fcf3ce44SJohn Forte {
101*fcf3ce44SJohn Forte 	va_list ap;
102*fcf3ce44SJohn Forte 	va_start(ap, string);
103*fcf3ce44SJohn Forte 
104*fcf3ce44SJohn Forte 	message(gettext("warning"), status, string, ap);
105*fcf3ce44SJohn Forte 	va_end(ap);
106*fcf3ce44SJohn Forte }
107*fcf3ce44SJohn Forte 
108*fcf3ce44SJohn Forte #if defined(_LP64)
109*fcf3ce44SJohn Forte 					/* max value of a "long int" */
110*fcf3ce44SJohn Forte #define	ULONG_MAX	18446744073709551615UL
111*fcf3ce44SJohn Forte #else /* _ILP32 */
112*fcf3ce44SJohn Forte #define	ULONG_MAX	4294967295UL	/* max of "unsigned long int" */
113*fcf3ce44SJohn Forte #endif
114*fcf3ce44SJohn Forte 
115*fcf3ce44SJohn Forte static uint64_t
get_partsize(char * partition)116*fcf3ce44SJohn Forte get_partsize(char *partition)
117*fcf3ce44SJohn Forte {
118*fcf3ce44SJohn Forte #ifdef DKIOCPARTITION
119*fcf3ce44SJohn Forte 	struct dk_cinfo dki_info;
120*fcf3ce44SJohn Forte 	struct partition64 p64;
121*fcf3ce44SJohn Forte #endif
122*fcf3ce44SJohn Forte 	struct vtoc vtoc;
123*fcf3ce44SJohn Forte 	uint64_t size;
124*fcf3ce44SJohn Forte 	int fd;
125*fcf3ce44SJohn Forte 	int rc;
126*fcf3ce44SJohn Forte 
127*fcf3ce44SJohn Forte 	if ((fd = open(partition, O_RDONLY)) < 0) {
128*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to open partition, %s: %s"),
129*fcf3ce44SJohn Forte 		    partition, strerror(errno));
130*fcf3ce44SJohn Forte 		/* NOTREACHED */
131*fcf3ce44SJohn Forte 	}
132*fcf3ce44SJohn Forte 
133*fcf3ce44SJohn Forte 	rc = read_vtoc(fd, &vtoc);
134*fcf3ce44SJohn Forte 	if (rc >= 0) {
135*fcf3ce44SJohn Forte 		size = (uint64_t)(ULONG_MAX & vtoc.v_part[rc].p_size);
136*fcf3ce44SJohn Forte 		return (size);
137*fcf3ce44SJohn Forte 	}
138*fcf3ce44SJohn Forte #ifdef DKIOCPARTITION
139*fcf3ce44SJohn Forte 	else if (rc != VT_ENOTSUP) {
140*fcf3ce44SJohn Forte #endif
141*fcf3ce44SJohn Forte 		error(NULL,
142*fcf3ce44SJohn Forte 		    gettext("unable to read the vtoc from partition, %s: %s"),
143*fcf3ce44SJohn Forte 		    partition, strerror(errno));
144*fcf3ce44SJohn Forte 		/* NOTREACHED */
145*fcf3ce44SJohn Forte #ifdef DKIOCPARTITION
146*fcf3ce44SJohn Forte 	}
147*fcf3ce44SJohn Forte 
148*fcf3ce44SJohn Forte 	/* See if there is an EFI label */
149*fcf3ce44SJohn Forte 	rc = ioctl(fd, DKIOCINFO, &dki_info);
150*fcf3ce44SJohn Forte 	if (rc < 0) {
151*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to get controller info "
152*fcf3ce44SJohn Forte 		    "from partition, %s: %s"),
153*fcf3ce44SJohn Forte 		    partition, strerror(errno));
154*fcf3ce44SJohn Forte 		/* NOTREACHED */
155*fcf3ce44SJohn Forte 	}
156*fcf3ce44SJohn Forte 
157*fcf3ce44SJohn Forte 	bzero(&p64, sizeof (p64));
158*fcf3ce44SJohn Forte 	p64.p_partno = (uint_t)dki_info.dki_partition;
159*fcf3ce44SJohn Forte 	rc = ioctl(fd, DKIOCPARTITION, &p64);
160*fcf3ce44SJohn Forte 	if (rc >= 0) {
161*fcf3ce44SJohn Forte 		size = (uint64_t)p64.p_size;
162*fcf3ce44SJohn Forte 		return (size);
163*fcf3ce44SJohn Forte 	} else {
164*fcf3ce44SJohn Forte 		struct stat64 stb1, stb2;
165*fcf3ce44SJohn Forte 		struct dk_minfo dkm;
166*fcf3ce44SJohn Forte 
167*fcf3ce44SJohn Forte 		/*
168*fcf3ce44SJohn Forte 		 * See if the stat64 for ZFS's zvol matches
169*fcf3ce44SJohn Forte 		 * this file descriptor's fstat64 data.
170*fcf3ce44SJohn Forte 		 */
171*fcf3ce44SJohn Forte 		if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 ||
172*fcf3ce44SJohn Forte 		    fstat64(fd, &stb2) != 0 ||
173*fcf3ce44SJohn Forte 		    !S_ISCHR(stb1.st_mode) ||
174*fcf3ce44SJohn Forte 		    !S_ISCHR(stb2.st_mode) ||
175*fcf3ce44SJohn Forte 		    major(stb1.st_rdev) != major(stb2.st_rdev)) {
176*fcf3ce44SJohn Forte 			error(NULL,
177*fcf3ce44SJohn Forte 			    gettext("unable to read disk partition, %s: %s"),
178*fcf3ce44SJohn Forte 			    partition, strerror(errno));
179*fcf3ce44SJohn Forte 			/* NOTREACHED */
180*fcf3ce44SJohn Forte 		}
181*fcf3ce44SJohn Forte 
182*fcf3ce44SJohn Forte 		rc = ioctl(fd, DKIOCGMEDIAINFO, (void *)&dkm);
183*fcf3ce44SJohn Forte 		if (rc >= 0) {
184*fcf3ce44SJohn Forte 			size = LE_64(dkm.dki_capacity) *
185*fcf3ce44SJohn Forte 				dkm.dki_lbsize / 512;
186*fcf3ce44SJohn Forte 			return (size);
187*fcf3ce44SJohn Forte 		} else {
188*fcf3ce44SJohn Forte 			error(NULL, gettext("unable to read EFI label "
189*fcf3ce44SJohn Forte 			    "from partition, %s: %s"),
190*fcf3ce44SJohn Forte 			    partition, strerror(errno));
191*fcf3ce44SJohn Forte 			/* NOTREACHED */
192*fcf3ce44SJohn Forte 		}
193*fcf3ce44SJohn Forte 	}
194*fcf3ce44SJohn Forte 	return (size);
195*fcf3ce44SJohn Forte 
196*fcf3ce44SJohn Forte #endif	/* DKIOCPARTITION */
197*fcf3ce44SJohn Forte }
198*fcf3ce44SJohn Forte 
199*fcf3ce44SJohn Forte 
200*fcf3ce44SJohn Forte int
do_sndr(char * volume,char * bitmap)201*fcf3ce44SJohn Forte do_sndr(char *volume, char *bitmap)
202*fcf3ce44SJohn Forte {
203*fcf3ce44SJohn Forte 	uint64_t vblocks;
204*fcf3ce44SJohn Forte 	uint64_t bblocks;
205*fcf3ce44SJohn Forte 	uint64_t bsize_bits;	/* size of the bits alone */
206*fcf3ce44SJohn Forte 	uint64_t bsize_simple;	/* size of the simple bitmap */
207*fcf3ce44SJohn Forte 	uint64_t bsize_diskq;	/* size of the diskq bitmap, 8 bit refcnt */
208*fcf3ce44SJohn Forte 	uint64_t bsize_diskq32;	/* size of the diskq bitmap, 32 bit refcnt */
209*fcf3ce44SJohn Forte 	int rc = 0;
210*fcf3ce44SJohn Forte 
211*fcf3ce44SJohn Forte 	vblocks = get_partsize(volume);
212*fcf3ce44SJohn Forte 	if (bitmap) {
213*fcf3ce44SJohn Forte 		bblocks = get_partsize(bitmap);
214*fcf3ce44SJohn Forte 	}
215*fcf3ce44SJohn Forte 
216*fcf3ce44SJohn Forte 	bsize_bits = BMAP_LOG_BYTES(vblocks);
217*fcf3ce44SJohn Forte 	bsize_bits = (bsize_bits + 511) / 512;
218*fcf3ce44SJohn Forte 
219*fcf3ce44SJohn Forte 	bsize_simple = RDC_BITMAP_FBA + bsize_bits;
220*fcf3ce44SJohn Forte 	bsize_diskq = RDC_BITMAP_FBA + bsize_bits + (BITS_IN_BYTE * bsize_bits);
221*fcf3ce44SJohn Forte 	bsize_diskq32 = RDC_BITMAP_FBA + bsize_bits + (BITS_IN_BYTE *
222*fcf3ce44SJohn Forte 		bsize_bits * sizeof (unsigned int));
223*fcf3ce44SJohn Forte 
224*fcf3ce44SJohn Forte 	(void) printf(gettext("Remote Mirror bitmap sizing\n\n"));
225*fcf3ce44SJohn Forte 	(void) printf(gettext("Data volume (%s) size: %llu blocks\n"),
226*fcf3ce44SJohn Forte 	    volume, vblocks);
227*fcf3ce44SJohn Forte 
228*fcf3ce44SJohn Forte 	(void) printf(gettext("Required bitmap volume size:\n"));
229*fcf3ce44SJohn Forte 	(void) printf(gettext("  Sync replication: %llu blocks\n"),
230*fcf3ce44SJohn Forte 	    bsize_simple);
231*fcf3ce44SJohn Forte 	(void) printf(gettext("  Async replication with memory queue: "
232*fcf3ce44SJohn Forte 	    "%llu blocks\n"), bsize_simple);
233*fcf3ce44SJohn Forte 	(void) printf(gettext("  Async replication with disk queue: "
234*fcf3ce44SJohn Forte 	    "%llu blocks\n"), bsize_diskq);
235*fcf3ce44SJohn Forte 	(void) printf(gettext("  Async replication with disk queue and 32 bit "
236*fcf3ce44SJohn Forte 	    "refcount: %llu blocks\n"), bsize_diskq32);
237*fcf3ce44SJohn Forte 
238*fcf3ce44SJohn Forte 	if (bitmap) {
239*fcf3ce44SJohn Forte 		(void) printf("\n");
240*fcf3ce44SJohn Forte 		(void) printf(gettext("Supplied bitmap volume %s "
241*fcf3ce44SJohn Forte 		    "(%llu blocks)\n"),
242*fcf3ce44SJohn Forte 		    bitmap, bblocks);
243*fcf3ce44SJohn Forte 		if (bblocks >= bsize_diskq32) {
244*fcf3ce44SJohn Forte 			(void) printf(gettext("is large enough for all "
245*fcf3ce44SJohn Forte 			    "replication modes\n"));
246*fcf3ce44SJohn Forte 		} else if (bblocks >= bsize_diskq) {
247*fcf3ce44SJohn Forte 			(void) printf(gettext("is large enough for all "
248*fcf3ce44SJohn Forte 			    "replication modes, but with restricted diskq "
249*fcf3ce44SJohn Forte 			    "reference counts\n"));
250*fcf3ce44SJohn Forte 		} else if (bblocks >= bsize_simple) {
251*fcf3ce44SJohn Forte 			(void) printf(gettext(
252*fcf3ce44SJohn Forte 			    "is large enough for: Sync and Async(memory) "
253*fcf3ce44SJohn Forte 			    "replication modes only\n"));
254*fcf3ce44SJohn Forte 			rc = 3;
255*fcf3ce44SJohn Forte 		} else {
256*fcf3ce44SJohn Forte 			(void) printf(gettext(
257*fcf3ce44SJohn Forte 			    "is not large enough for any replication modes\n"));
258*fcf3ce44SJohn Forte 			rc = 4;
259*fcf3ce44SJohn Forte 		}
260*fcf3ce44SJohn Forte 	}
261*fcf3ce44SJohn Forte 
262*fcf3ce44SJohn Forte 	return (rc);
263*fcf3ce44SJohn Forte }
264*fcf3ce44SJohn Forte 
265*fcf3ce44SJohn Forte 
266*fcf3ce44SJohn Forte /* sizes in bytes */
267*fcf3ce44SJohn Forte #define	KILO	(1024)
268*fcf3ce44SJohn Forte #define	MEGA	(KILO * KILO)
269*fcf3ce44SJohn Forte #define	GIGA	(MEGA * KILO)
270*fcf3ce44SJohn Forte #define	TERA	((uint64_t)((uint64_t)GIGA * (uint64_t)KILO))
271*fcf3ce44SJohn Forte 
272*fcf3ce44SJohn Forte /* rounding function */
273*fcf3ce44SJohn Forte #define	roundup_2n(x, y)	(((x) + ((y) - 1)) & (~y))
274*fcf3ce44SJohn Forte 
275*fcf3ce44SJohn Forte int
do_ii(char * volume,char * bitmap)276*fcf3ce44SJohn Forte do_ii(char *volume, char *bitmap)
277*fcf3ce44SJohn Forte {
278*fcf3ce44SJohn Forte 	const uint64_t int64_bits = sizeof (uint64_t) * BITS_IN_BYTE;
279*fcf3ce44SJohn Forte 	const uint64_t int32_bits = sizeof (uint32_t) * BITS_IN_BYTE;
280*fcf3ce44SJohn Forte 	const uint64_t terablocks = TERA / ((uint64_t)FBA_SIZE(1));
281*fcf3ce44SJohn Forte 	uint64_t vblocks_phys, vblocks;
282*fcf3ce44SJohn Forte 	uint64_t bblocks;
283*fcf3ce44SJohn Forte 	uint64_t bsize_ind;	/* indep and dep not compact */
284*fcf3ce44SJohn Forte 	uint64_t bsize_cdep;	/* compact dep */
285*fcf3ce44SJohn Forte 	int rc = 0;
286*fcf3ce44SJohn Forte 
287*fcf3ce44SJohn Forte 	vblocks_phys = get_partsize(volume);
288*fcf3ce44SJohn Forte 	if (bitmap) {
289*fcf3ce44SJohn Forte 		bblocks = get_partsize(bitmap);
290*fcf3ce44SJohn Forte 	}
291*fcf3ce44SJohn Forte 
292*fcf3ce44SJohn Forte 	/* round up to multiple of DSW_SIZE blocks */
293*fcf3ce44SJohn Forte 	vblocks = roundup_2n(vblocks_phys, DSW_SIZE);
294*fcf3ce44SJohn Forte 	bsize_ind = DSW_SHD_BM_OFFSET + (2 * DSW_BM_FBA_LEN(vblocks));
295*fcf3ce44SJohn Forte 	bsize_cdep = bsize_ind;
296*fcf3ce44SJohn Forte 	bsize_cdep += DSW_BM_FBA_LEN(vblocks) *
297*fcf3ce44SJohn Forte 	    ((vblocks < (uint64_t)(terablocks * DSW_SIZE)) ?
298*fcf3ce44SJohn Forte 	    int32_bits : int64_bits);
299*fcf3ce44SJohn Forte 
300*fcf3ce44SJohn Forte 	(void) printf(gettext("Point in Time bitmap sizing\n\n"));
301*fcf3ce44SJohn Forte 	(void) printf(gettext("Data volume (%s) size: %llu blocks\n"),
302*fcf3ce44SJohn Forte 	    volume, vblocks_phys);
303*fcf3ce44SJohn Forte 
304*fcf3ce44SJohn Forte 	(void) printf(gettext("Required bitmap volume size:\n"));
305*fcf3ce44SJohn Forte 	(void) printf(gettext("  Independent shadow: %llu blocks\n"),
306*fcf3ce44SJohn Forte 	    bsize_ind);
307*fcf3ce44SJohn Forte 	(void) printf(gettext("  Full size dependent shadow: %llu blocks\n"),
308*fcf3ce44SJohn Forte 	    bsize_ind);
309*fcf3ce44SJohn Forte 	(void) printf(gettext("  Compact dependent shadow: %llu blocks\n"),
310*fcf3ce44SJohn Forte 	    bsize_cdep);
311*fcf3ce44SJohn Forte 
312*fcf3ce44SJohn Forte 	if (bitmap) {
313*fcf3ce44SJohn Forte 		(void) printf("\n");
314*fcf3ce44SJohn Forte 		(void) printf(gettext("Supplied bitmap volume %s "
315*fcf3ce44SJohn Forte 		    "(%llu blocks)\n"), bitmap, bblocks);
316*fcf3ce44SJohn Forte 
317*fcf3ce44SJohn Forte 		if (bblocks >= bsize_cdep) {
318*fcf3ce44SJohn Forte 			(void) printf(gettext("is large enough for all types "
319*fcf3ce44SJohn Forte 			    "of shadow volume\n"));
320*fcf3ce44SJohn Forte 		} else if (bblocks >= bsize_ind) {
321*fcf3ce44SJohn Forte 			(void) printf(gettext("is large enough for: "
322*fcf3ce44SJohn Forte 			    "Independent and full size dependent shadow "
323*fcf3ce44SJohn Forte 			    "volumes only\n"));
324*fcf3ce44SJohn Forte 			rc = 6;
325*fcf3ce44SJohn Forte 		} else {
326*fcf3ce44SJohn Forte 			(void) printf(gettext("is not large enough for"
327*fcf3ce44SJohn Forte 			    "any type of shadow volume\n"));
328*fcf3ce44SJohn Forte 			rc = 5;
329*fcf3ce44SJohn Forte 		}
330*fcf3ce44SJohn Forte 	}
331*fcf3ce44SJohn Forte 
332*fcf3ce44SJohn Forte 	return (rc);
333*fcf3ce44SJohn Forte }
334*fcf3ce44SJohn Forte 
335*fcf3ce44SJohn Forte 
336*fcf3ce44SJohn Forte /*
337*fcf3ce44SJohn Forte  * Return codes:
338*fcf3ce44SJohn Forte  *	0 success (if bitmap was supplied it is large enough for all uses)
339*fcf3ce44SJohn Forte  *	1 usage, programing, or access errors
340*fcf3ce44SJohn Forte  *	2 unknown option supplied on command line
341*fcf3ce44SJohn Forte  *	3 SNDR bitmap is not large enough for diskq usage
342*fcf3ce44SJohn Forte  *	4 SNDR bitmap is not large enough for any usage
343*fcf3ce44SJohn Forte  *	5 II bitmap is not large enough for any usage
344*fcf3ce44SJohn Forte  *	6 II bitmap is not large enough for compact dependent usage
345*fcf3ce44SJohn Forte  */
346*fcf3ce44SJohn Forte int
main(int argc,char * argv[])347*fcf3ce44SJohn Forte main(int argc, char *argv[])
348*fcf3ce44SJohn Forte {
349*fcf3ce44SJohn Forte 	extern int optind;
350*fcf3ce44SJohn Forte 	char *volume, *bitmap;
351*fcf3ce44SJohn Forte 	int type = UNKNOWN;
352*fcf3ce44SJohn Forte 	int opt;
353*fcf3ce44SJohn Forte 	int rc = 0;
354*fcf3ce44SJohn Forte 
355*fcf3ce44SJohn Forte 	(void) setlocale(LC_ALL, "");
356*fcf3ce44SJohn Forte 	(void) textdomain("dsbitmap");
357*fcf3ce44SJohn Forte 
358*fcf3ce44SJohn Forte 	program = strdup(basename(argv[0]));
359*fcf3ce44SJohn Forte 
360*fcf3ce44SJohn Forte 	while ((opt = getopt(argc, argv, "hpr")) != EOF) {
361*fcf3ce44SJohn Forte 		switch (opt) {
362*fcf3ce44SJohn Forte 		case 'p':
363*fcf3ce44SJohn Forte 			if (type != UNKNOWN) {
364*fcf3ce44SJohn Forte 				warn(NULL, gettext(
365*fcf3ce44SJohn Forte 				    "cannot specify -p with other options"));
366*fcf3ce44SJohn Forte 				usage();
367*fcf3ce44SJohn Forte 				return (1);
368*fcf3ce44SJohn Forte 			}
369*fcf3ce44SJohn Forte 			type = II;
370*fcf3ce44SJohn Forte 			break;
371*fcf3ce44SJohn Forte 
372*fcf3ce44SJohn Forte 		case 'r':
373*fcf3ce44SJohn Forte 			if (type != UNKNOWN) {
374*fcf3ce44SJohn Forte 				warn(NULL, gettext(
375*fcf3ce44SJohn Forte 				    "cannot specify -r with other options"));
376*fcf3ce44SJohn Forte 				usage();
377*fcf3ce44SJohn Forte 				return (1);
378*fcf3ce44SJohn Forte 			}
379*fcf3ce44SJohn Forte 			type = SNDR;
380*fcf3ce44SJohn Forte 			break;
381*fcf3ce44SJohn Forte 
382*fcf3ce44SJohn Forte 		case 'h':
383*fcf3ce44SJohn Forte 			if (argc != 2) {
384*fcf3ce44SJohn Forte 				warn(NULL, gettext(
385*fcf3ce44SJohn Forte 				    "cannot specify -h with other options"));
386*fcf3ce44SJohn Forte 				rc = 1;
387*fcf3ce44SJohn Forte 			}
388*fcf3ce44SJohn Forte 			usage();
389*fcf3ce44SJohn Forte 			return (rc);
390*fcf3ce44SJohn Forte 			/* NOTREACHED */
391*fcf3ce44SJohn Forte 
392*fcf3ce44SJohn Forte 		default:
393*fcf3ce44SJohn Forte 			usage();
394*fcf3ce44SJohn Forte 			return (2);
395*fcf3ce44SJohn Forte 			/* NOTREACHED */
396*fcf3ce44SJohn Forte 		}
397*fcf3ce44SJohn Forte 	}
398*fcf3ce44SJohn Forte 
399*fcf3ce44SJohn Forte 	if (type == UNKNOWN) {
400*fcf3ce44SJohn Forte 		warn(NULL, gettext("one of -p and -r must be specified"));
401*fcf3ce44SJohn Forte 		usage();
402*fcf3ce44SJohn Forte 		return (1);
403*fcf3ce44SJohn Forte 	}
404*fcf3ce44SJohn Forte 
405*fcf3ce44SJohn Forte 	if ((argc - optind) != 1 && (argc - optind) != 2) {
406*fcf3ce44SJohn Forte 		warn(NULL, gettext("incorrect number of arguments to %s"),
407*fcf3ce44SJohn Forte 		    (type == SNDR) ? "-r" : "-p");
408*fcf3ce44SJohn Forte 		usage();
409*fcf3ce44SJohn Forte 		return (1);
410*fcf3ce44SJohn Forte 	}
411*fcf3ce44SJohn Forte 
412*fcf3ce44SJohn Forte 	volume = argv[optind];
413*fcf3ce44SJohn Forte 	if ((argc - optind) == 2) {
414*fcf3ce44SJohn Forte 		bitmap = argv[optind+1];
415*fcf3ce44SJohn Forte 	} else {
416*fcf3ce44SJohn Forte 		bitmap = NULL;
417*fcf3ce44SJohn Forte 	}
418*fcf3ce44SJohn Forte 
419*fcf3ce44SJohn Forte 	switch (type) {
420*fcf3ce44SJohn Forte 	case SNDR:
421*fcf3ce44SJohn Forte 		rc = do_sndr(volume, bitmap);
422*fcf3ce44SJohn Forte 		break;
423*fcf3ce44SJohn Forte 
424*fcf3ce44SJohn Forte 	case II:
425*fcf3ce44SJohn Forte 		rc = do_ii(volume, bitmap);
426*fcf3ce44SJohn Forte 		break;
427*fcf3ce44SJohn Forte 
428*fcf3ce44SJohn Forte 	default:
429*fcf3ce44SJohn Forte 		/* cannot happen */
430*fcf3ce44SJohn Forte 		warn(NULL, gettext("one of -p and -r must be specified"));
431*fcf3ce44SJohn Forte 		rc = 1;
432*fcf3ce44SJohn Forte 		break;
433*fcf3ce44SJohn Forte 	}
434*fcf3ce44SJohn Forte 
435*fcf3ce44SJohn Forte 	return (rc);
436*fcf3ce44SJohn Forte }
437