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