xref: /illumos-gate/usr/src/cmd/fs.d/udfs/fsck/setup.c (revision bfbf29e2d493eb4d7f76ee725d3229899602a088)
17c478bd9Sstevel@tonic-gate /*
2fe0e7ec4Smaheshvs  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
147c478bd9Sstevel@tonic-gate  * provided that: (1) source distributions retain this entire copyright
157c478bd9Sstevel@tonic-gate  * notice and comment, and (2) distributions including binaries display
167c478bd9Sstevel@tonic-gate  * the following acknowledgement:  ``This product includes software
177c478bd9Sstevel@tonic-gate  * developed by the University of California, Berkeley and its contributors''
187c478bd9Sstevel@tonic-gate  * in the documentation or other materials provided with the distribution
197c478bd9Sstevel@tonic-gate  * and in all advertising materials mentioning features or use of this
207c478bd9Sstevel@tonic-gate  * software. Neither the name of the University nor the names of its
217c478bd9Sstevel@tonic-gate  * contributors may be used to endorse or promote products derived
227c478bd9Sstevel@tonic-gate  * from this software without specific prior written permission.
237c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
247c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
257c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #define	DKTYPENAMES
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <unistd.h>
327c478bd9Sstevel@tonic-gate #include <fcntl.h>
337c478bd9Sstevel@tonic-gate #include <ustat.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate #include <sys/param.h>
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
387c478bd9Sstevel@tonic-gate #include <sys/mntent.h>
397c478bd9Sstevel@tonic-gate #include <sys/mnttab.h>
407c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
417c478bd9Sstevel@tonic-gate #include <sys/filio.h>
427c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>	/* for ENDIAN defines */
437c478bd9Sstevel@tonic-gate #include <sys/int_const.h>
447c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
457c478bd9Sstevel@tonic-gate #include <sys/stat.h>
467c478bd9Sstevel@tonic-gate #include <sys/file.h>
477c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
487c478bd9Sstevel@tonic-gate #include <string.h>
497c478bd9Sstevel@tonic-gate #include <sys/vfstab.h>
507c478bd9Sstevel@tonic-gate #include <sys/fs/udf_volume.h>
517c478bd9Sstevel@tonic-gate #include <sys/vtoc.h>
527c478bd9Sstevel@tonic-gate #include <locale.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #include "fsck.h"
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate extern void	errexit(char *, ...);
577c478bd9Sstevel@tonic-gate extern int32_t	mounted(char *);
587c478bd9Sstevel@tonic-gate extern void	pwarn(char *, ...);
597c478bd9Sstevel@tonic-gate extern void	pfatal(char *, ...);
607c478bd9Sstevel@tonic-gate extern void	printclean();
617c478bd9Sstevel@tonic-gate extern void	bufinit();
627c478bd9Sstevel@tonic-gate extern void	ckfini();
637c478bd9Sstevel@tonic-gate extern int32_t	bread(int32_t, char *, daddr_t, long);
647c478bd9Sstevel@tonic-gate extern int32_t	reply(char *);
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate static int32_t	readvolseq(int32_t);
677c478bd9Sstevel@tonic-gate static uint32_t	get_last_block();
687c478bd9Sstevel@tonic-gate extern int32_t	verifytag(struct tag *, uint32_t, struct tag *, int);
697c478bd9Sstevel@tonic-gate extern char	*tagerrs[];
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate #define	POWEROF2(num)	(((num) & ((num) - 1)) == 0)
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate extern int	mflag;
74*bfbf29e2SToomas Soome long fsbsize;
75*bfbf29e2SToomas Soome static char hotroot;	/* checking root device */
76*bfbf29e2SToomas Soome char *freemap;
77*bfbf29e2SToomas Soome char *busymap;
78*bfbf29e2SToomas Soome uint32_t part_start;
79*bfbf29e2SToomas Soome uint32_t lvintlen;
80*bfbf29e2SToomas Soome uint32_t lvintblock;
81*bfbf29e2SToomas Soome uint32_t rootblock;
82*bfbf29e2SToomas Soome uint32_t rootlen;
83*bfbf29e2SToomas Soome uint32_t part_bmp_bytes;
84*bfbf29e2SToomas Soome uint32_t part_bmp_sectors;
85*bfbf29e2SToomas Soome uint32_t part_bmp_loc;
86*bfbf29e2SToomas Soome int fsreadfd;
87*bfbf29e2SToomas Soome int fswritefd;
88*bfbf29e2SToomas Soome long secsize;
89*bfbf29e2SToomas Soome long numdirs, numfiles, listmax;
90*bfbf29e2SToomas Soome struct fileinfo *inphead, **inphash, *inpnext, *inplast;
91*bfbf29e2SToomas Soome struct space_bmap_desc *spacep;
92*bfbf29e2SToomas Soome static struct unall_desc *unallp;
93*bfbf29e2SToomas Soome static struct pri_vol_desc *pvolp;
94*bfbf29e2SToomas Soome static struct part_desc *partp;
95*bfbf29e2SToomas Soome static struct phdr_desc *pheadp;
96*bfbf29e2SToomas Soome static struct log_vol_desc *logvp;
97*bfbf29e2SToomas Soome struct lvid_iu *lviup;
98*bfbf29e2SToomas Soome static struct vdp_desc *volp;
99*bfbf29e2SToomas Soome static struct anch_vol_desc_ptr *avdp;
100*bfbf29e2SToomas Soome static struct iuvd_desc *iudp;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate char avdbuf[MAXBSIZE];		/* buffer for anchor volume descriptor */
1037c478bd9Sstevel@tonic-gate char *main_vdbuf;		/* buffer for entire main volume sequence */
1047c478bd9Sstevel@tonic-gate char *res_vdbuf;		/* buffer for reserved volume sequence */
1057c478bd9Sstevel@tonic-gate int serialnum = -1;		/* set from primary volume descriptor */
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate char *
setup(char * dev)108fe0e7ec4Smaheshvs setup(char *dev)
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	dev_t rootdev;
1117c478bd9Sstevel@tonic-gate 	struct stat statb;
1127c478bd9Sstevel@tonic-gate 	static char devstr[MAXPATHLEN];
1137c478bd9Sstevel@tonic-gate 	char *raw, *rawname(), *unrawname();
1147c478bd9Sstevel@tonic-gate 	struct ustat ustatb;
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	if (stat("/", &statb) < 0)
1177c478bd9Sstevel@tonic-gate 		errexit(gettext("Can't stat root\n"));
1187c478bd9Sstevel@tonic-gate 	rootdev = statb.st_dev;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	devname = devstr;
1217c478bd9Sstevel@tonic-gate 	(void) strncpy(devstr, dev, sizeof (devstr));
1227c478bd9Sstevel@tonic-gate restat:
1237c478bd9Sstevel@tonic-gate 	if (stat(devstr, &statb) < 0) {
1247c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Can't stat %s\n"), devstr);
1257c478bd9Sstevel@tonic-gate 		exitstat = 34;
1267c478bd9Sstevel@tonic-gate 		return (0);
1277c478bd9Sstevel@tonic-gate 	}
1287c478bd9Sstevel@tonic-gate 	/*
1297c478bd9Sstevel@tonic-gate 	 * A mount point is specified. But the mount point doesn't
1307c478bd9Sstevel@tonic-gate 	 * match entries in the /etc/vfstab.
1317c478bd9Sstevel@tonic-gate 	 * Search mnttab, because if the fs is error locked, it is
1327c478bd9Sstevel@tonic-gate 	 * allowed to be fsck'd while mounted.
1337c478bd9Sstevel@tonic-gate 	 */
1347c478bd9Sstevel@tonic-gate 	if ((statb.st_mode & S_IFMT) == S_IFDIR) {
1357c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s is not a block or "
1367c478bd9Sstevel@tonic-gate 			"character device\n"), dev);
1377c478bd9Sstevel@tonic-gate 		return (0);
1387c478bd9Sstevel@tonic-gate 	}
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	if ((statb.st_mode & S_IFMT) == S_IFBLK) {
1417c478bd9Sstevel@tonic-gate 		if (rootdev == statb.st_rdev)
1427c478bd9Sstevel@tonic-gate 			hotroot++;
1437c478bd9Sstevel@tonic-gate 		else if (ustat(statb.st_rdev, &ustatb) == 0) {
1447c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s is a mounted file system, "
1457c478bd9Sstevel@tonic-gate 				"ignored\n"), dev);
1467c478bd9Sstevel@tonic-gate 			exitstat = 33;
1477c478bd9Sstevel@tonic-gate 			return (0);
1487c478bd9Sstevel@tonic-gate 		}
1497c478bd9Sstevel@tonic-gate 	}
1507c478bd9Sstevel@tonic-gate 	if ((statb.st_mode & S_IFMT) == S_IFDIR) {
1517c478bd9Sstevel@tonic-gate 		FILE *vfstab;
1527c478bd9Sstevel@tonic-gate 		struct vfstab vfsbuf;
1537c478bd9Sstevel@tonic-gate 		/*
1547c478bd9Sstevel@tonic-gate 		 * Check vfstab for a mount point with this name
1557c478bd9Sstevel@tonic-gate 		 */
1567c478bd9Sstevel@tonic-gate 		if ((vfstab = fopen(VFSTAB, "r")) == NULL) {
1577c478bd9Sstevel@tonic-gate 			errexit(gettext("Can't open checklist file: %s\n"),
1587c478bd9Sstevel@tonic-gate 				VFSTAB);
1597c478bd9Sstevel@tonic-gate 		}
1608509e9caSToomas Soome 		while (getvfsent(vfstab, &vfsbuf) == 0) {
1617c478bd9Sstevel@tonic-gate 			if (strcmp(devstr, vfsbuf.vfs_mountp) == 0) {
1627c478bd9Sstevel@tonic-gate 				if (strcmp(vfsbuf.vfs_fstype,
1637c478bd9Sstevel@tonic-gate 				    MNTTYPE_UDFS) != 0) {
1647c478bd9Sstevel@tonic-gate 					/*
1657c478bd9Sstevel@tonic-gate 					 * found the entry but it is not a
1667c478bd9Sstevel@tonic-gate 					 * udfs filesystem, don't check it
1677c478bd9Sstevel@tonic-gate 					 */
1687c478bd9Sstevel@tonic-gate 					(void) fclose(vfstab);
1697c478bd9Sstevel@tonic-gate 					return (0);
1707c478bd9Sstevel@tonic-gate 				}
1717c478bd9Sstevel@tonic-gate 				(void) strcpy(devstr, vfsbuf.vfs_special);
1727c478bd9Sstevel@tonic-gate 				if (rflag) {
1737c478bd9Sstevel@tonic-gate 					raw = rawname(
1747c478bd9Sstevel@tonic-gate 					    unrawname(vfsbuf.vfs_special));
1757c478bd9Sstevel@tonic-gate 					(void) strcpy(devstr, raw);
1767c478bd9Sstevel@tonic-gate 				}
1777c478bd9Sstevel@tonic-gate 				goto restat;
1787c478bd9Sstevel@tonic-gate 			}
1797c478bd9Sstevel@tonic-gate 		}
1807c478bd9Sstevel@tonic-gate 		(void) fclose(vfstab);
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	} else if (((statb.st_mode & S_IFMT) != S_IFBLK) &&
1837c478bd9Sstevel@tonic-gate 	    ((statb.st_mode & S_IFMT) != S_IFCHR)) {
1847c478bd9Sstevel@tonic-gate 		if (preen)
1857c478bd9Sstevel@tonic-gate 			pwarn(gettext("file is not a block or "
1867c478bd9Sstevel@tonic-gate 				"character device.\n"));
1877c478bd9Sstevel@tonic-gate 		else if (reply(gettext("file is not a block or "
1887c478bd9Sstevel@tonic-gate 				"character device; OK"))
1897c478bd9Sstevel@tonic-gate 		    == 0)
1907c478bd9Sstevel@tonic-gate 			return (0);
1917c478bd9Sstevel@tonic-gate 		/*
1927c478bd9Sstevel@tonic-gate 		 * To fsck regular files (fs images)
1937c478bd9Sstevel@tonic-gate 		 * we need to clear the rflag since
1947c478bd9Sstevel@tonic-gate 		 * regular files don't have raw names.  --CW
1957c478bd9Sstevel@tonic-gate 		 */
1967c478bd9Sstevel@tonic-gate 		rflag = 0;
1977c478bd9Sstevel@tonic-gate 	}
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	if (mounted(devstr)) {
2007c478bd9Sstevel@tonic-gate 		if (rflag)
2017c478bd9Sstevel@tonic-gate 			mountedfs++;
2027c478bd9Sstevel@tonic-gate 		else {
2037c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s is mounted, fsck on BLOCK "
2047c478bd9Sstevel@tonic-gate 				"device ignored\n"), devstr);
2057c478bd9Sstevel@tonic-gate 			exit(33);
2067c478bd9Sstevel@tonic-gate 		}
2077c478bd9Sstevel@tonic-gate 		sync();	/* call sync, only when devstr's mounted */
2087c478bd9Sstevel@tonic-gate 	}
2097c478bd9Sstevel@tonic-gate 	if (rflag) {
2107c478bd9Sstevel@tonic-gate 		char blockname[MAXPATHLEN];
2117c478bd9Sstevel@tonic-gate 		/*
2127c478bd9Sstevel@tonic-gate 		 * For root device check, must check
2137c478bd9Sstevel@tonic-gate 		 * block devices.
2147c478bd9Sstevel@tonic-gate 		 */
2157c478bd9Sstevel@tonic-gate 		(void) strcpy(blockname, devstr);
2167c478bd9Sstevel@tonic-gate 		if (stat(unrawname(blockname), &statb) < 0) {
2177c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Can't stat %s\n"), blockname);
2187c478bd9Sstevel@tonic-gate 			exitstat = 34;
2197c478bd9Sstevel@tonic-gate 			return (0);
2207c478bd9Sstevel@tonic-gate 		}
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate 	if (rootdev == statb.st_rdev)
2237c478bd9Sstevel@tonic-gate 		hotroot++;
2247c478bd9Sstevel@tonic-gate 	if ((fsreadfd = open(devstr, O_RDONLY)) < 0) {
2257c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Can't open %s\n"), devstr);
2267c478bd9Sstevel@tonic-gate 		exitstat = 34;
2277c478bd9Sstevel@tonic-gate 		return (0);
2287c478bd9Sstevel@tonic-gate 	}
2297c478bd9Sstevel@tonic-gate 	if (preen == 0 || debug != 0)
2307c478bd9Sstevel@tonic-gate 		(void) printf("** %s", devstr);
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	if (nflag || (fswritefd = open(devstr, O_WRONLY)) < 0) {
2337c478bd9Sstevel@tonic-gate 		fswritefd = -1;
2347c478bd9Sstevel@tonic-gate 		if (preen && !debug)
2357c478bd9Sstevel@tonic-gate 			pfatal(gettext("(NO WRITE ACCESS)\n"));
2367c478bd9Sstevel@tonic-gate 		(void) printf(gettext(" (NO WRITE)"));
2377c478bd9Sstevel@tonic-gate 	}
2387c478bd9Sstevel@tonic-gate 	if (preen == 0)
2397c478bd9Sstevel@tonic-gate 		(void) printf("\n");
2407c478bd9Sstevel@tonic-gate 	if (debug && (hotroot || mountedfs)) {
2417c478bd9Sstevel@tonic-gate 		(void) printf("** %s", devstr);
2427c478bd9Sstevel@tonic-gate 		if (hotroot)
2437c478bd9Sstevel@tonic-gate 			(void) printf(" is root fs%s",
2447c478bd9Sstevel@tonic-gate 				mountedfs? " and": "");
2457c478bd9Sstevel@tonic-gate 		if (mountedfs)
2467c478bd9Sstevel@tonic-gate 			(void) printf(" is mounted");
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 		(void) printf(".\n");
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 	fsmodified = 0;
2517c478bd9Sstevel@tonic-gate 	if (readvolseq(1) == 0)
2527c478bd9Sstevel@tonic-gate 		return (0);
2537c478bd9Sstevel@tonic-gate 	if (fflag == 0 && preen &&
2547c478bd9Sstevel@tonic-gate 		lvintp->lvid_int_type == LVI_CLOSE) {
2557c478bd9Sstevel@tonic-gate 		iscorrupt = 0;
2567c478bd9Sstevel@tonic-gate 		printclean();
2577c478bd9Sstevel@tonic-gate 		return (0);
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 	listmax = FEGROW;
2607c478bd9Sstevel@tonic-gate 	inphash = (struct fileinfo **)calloc(FEGROW,
2617c478bd9Sstevel@tonic-gate 			sizeof (struct fileinfo *));
2627c478bd9Sstevel@tonic-gate 	inphead = (struct fileinfo *)calloc(FEGROW + 1,
2637c478bd9Sstevel@tonic-gate 			sizeof (struct fileinfo));
2647c478bd9Sstevel@tonic-gate 	if (inphead == NULL || inphash == NULL) {
2657c478bd9Sstevel@tonic-gate 		(void) printf(gettext("cannot alloc %ld bytes for inphead\n"),
2667c478bd9Sstevel@tonic-gate 			listmax * sizeof (struct fileinfo));
2677c478bd9Sstevel@tonic-gate 		goto badsb;
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate 	inpnext = inphead;
2707c478bd9Sstevel@tonic-gate 	inplast = &inphead[listmax];
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 	bufinit();
2737c478bd9Sstevel@tonic-gate 	return (devstr);
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate badsb:
2767c478bd9Sstevel@tonic-gate 	ckfini();
2777c478bd9Sstevel@tonic-gate 	exitstat = 39;
2787c478bd9Sstevel@tonic-gate 	return (0);
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate 
281fe0e7ec4Smaheshvs static int
check_pri_vol_desc(struct tag * tp)2827c478bd9Sstevel@tonic-gate check_pri_vol_desc(struct tag *tp)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate 	pvolp = (struct pri_vol_desc *)tp;
2857c478bd9Sstevel@tonic-gate 	return (0);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
288fe0e7ec4Smaheshvs static int
check_avdp(struct tag * tp)2897c478bd9Sstevel@tonic-gate check_avdp(struct tag *tp)
2907c478bd9Sstevel@tonic-gate {
2917c478bd9Sstevel@tonic-gate 	avdp = (struct anch_vol_desc_ptr *)tp;
2927c478bd9Sstevel@tonic-gate 	return (0);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
295fe0e7ec4Smaheshvs static int
check_vdp(struct tag * tp)2967c478bd9Sstevel@tonic-gate check_vdp(struct tag *tp)
2977c478bd9Sstevel@tonic-gate {
2987c478bd9Sstevel@tonic-gate 	volp = (struct vdp_desc *)tp;
2997c478bd9Sstevel@tonic-gate 	return (0);
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate 
302fe0e7ec4Smaheshvs static int
check_iuvd(struct tag * tp)3037c478bd9Sstevel@tonic-gate check_iuvd(struct tag *tp)
3047c478bd9Sstevel@tonic-gate {
3057c478bd9Sstevel@tonic-gate 	iudp = (struct iuvd_desc *)tp;
3067c478bd9Sstevel@tonic-gate 	return (0);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
309fe0e7ec4Smaheshvs static int
check_part_desc(struct tag * tp)3107c478bd9Sstevel@tonic-gate check_part_desc(struct tag *tp)
3117c478bd9Sstevel@tonic-gate {
3127c478bd9Sstevel@tonic-gate 	partp = (struct part_desc *)tp;
3137c478bd9Sstevel@tonic-gate 	/* LINTED */
3147c478bd9Sstevel@tonic-gate 	pheadp = (struct phdr_desc *)&partp->pd_pc_use;
3157c478bd9Sstevel@tonic-gate 	part_start = partp->pd_part_start;
3167c478bd9Sstevel@tonic-gate 	part_len = partp->pd_part_length;
3177c478bd9Sstevel@tonic-gate 	if (debug)
3187c478bd9Sstevel@tonic-gate 		(void) printf("partition start %x len %x\n", part_start,
3197c478bd9Sstevel@tonic-gate 			part_len);
3207c478bd9Sstevel@tonic-gate 	return (0);
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate 
323fe0e7ec4Smaheshvs static int
check_log_desc(struct tag * tp)3247c478bd9Sstevel@tonic-gate check_log_desc(struct tag *tp)
3257c478bd9Sstevel@tonic-gate {
3267c478bd9Sstevel@tonic-gate 	logvp = (struct log_vol_desc *)tp;
3277c478bd9Sstevel@tonic-gate 	return (0);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate 
330fe0e7ec4Smaheshvs static int
check_unall_desc(struct tag * tp)3317c478bd9Sstevel@tonic-gate check_unall_desc(struct tag *tp)
3327c478bd9Sstevel@tonic-gate {
3337c478bd9Sstevel@tonic-gate 	unallp = (struct unall_desc *)tp;
3347c478bd9Sstevel@tonic-gate 	return (0);
3357c478bd9Sstevel@tonic-gate }
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate /* ARGSUSED */
338fe0e7ec4Smaheshvs static int
check_term_desc(struct tag * tp)3397c478bd9Sstevel@tonic-gate check_term_desc(struct tag *tp)
3407c478bd9Sstevel@tonic-gate {
3417c478bd9Sstevel@tonic-gate 	return (0);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate 
344fe0e7ec4Smaheshvs static int
check_lvint(struct tag * tp)3457c478bd9Sstevel@tonic-gate check_lvint(struct tag *tp)
3467c478bd9Sstevel@tonic-gate {
3477c478bd9Sstevel@tonic-gate 	/* LINTED */
3487c478bd9Sstevel@tonic-gate 	lvintp = (struct log_vol_int_desc *)tp;
3497c478bd9Sstevel@tonic-gate 	return (0);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate void
dump16(char * cp,char * nl)3537c478bd9Sstevel@tonic-gate dump16(char *cp, char *nl)
3547c478bd9Sstevel@tonic-gate {
3557c478bd9Sstevel@tonic-gate 	int i;
3567c478bd9Sstevel@tonic-gate 	long *ptr;
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	for (i = 0; i < 16; i += 4) {
3607c478bd9Sstevel@tonic-gate 		/* LINTED */
3617c478bd9Sstevel@tonic-gate 		ptr = (long *)(cp + i);
3627c478bd9Sstevel@tonic-gate 		(void) printf("%08lx ", *ptr);
3637c478bd9Sstevel@tonic-gate 	}
3647c478bd9Sstevel@tonic-gate 	(void) printf(nl);
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate /*
3687c478bd9Sstevel@tonic-gate  * Read in the super block and its summary info.
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate /* ARGSUSED */
371fe0e7ec4Smaheshvs static int
readvolseq(int32_t listerr)3727c478bd9Sstevel@tonic-gate readvolseq(int32_t listerr)
3737c478bd9Sstevel@tonic-gate {
3747c478bd9Sstevel@tonic-gate 	struct tag *tp;
3757c478bd9Sstevel@tonic-gate 	long_ad_t *lap;
3767c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
3777c478bd9Sstevel@tonic-gate 	uint8_t *cp, *end;
3787c478bd9Sstevel@tonic-gate 	daddr_t nextblock;
3797c478bd9Sstevel@tonic-gate 	int err;
3807c478bd9Sstevel@tonic-gate 	long	freelen;
3817c478bd9Sstevel@tonic-gate 	daddr_t avdp;
382*bfbf29e2SToomas Soome 	struct file_set_desc *fileset;
383*bfbf29e2SToomas Soome 	uint32_t filesetblock;
384*bfbf29e2SToomas Soome 	uint32_t filesetlen;
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	if (debug)
387*bfbf29e2SToomas Soome 		(void) printf("Disk partition size: %x\n", get_last_block());
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	/* LINTED */
3907c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)avdbuf;
3917c478bd9Sstevel@tonic-gate 	tp = &avp->avd_tag;
3927c478bd9Sstevel@tonic-gate 	for (fsbsize = 512; fsbsize <= MAXBSIZE; fsbsize <<= 1) {
3937c478bd9Sstevel@tonic-gate 		avdp = FIRSTAVDP * fsbsize / DEV_BSIZE;
3947c478bd9Sstevel@tonic-gate 		if (bread(fsreadfd, avdbuf, avdp, fsbsize) != 0)
3957c478bd9Sstevel@tonic-gate 			return (0);
3967c478bd9Sstevel@tonic-gate 		err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC);
3977c478bd9Sstevel@tonic-gate 		if (debug)
3987c478bd9Sstevel@tonic-gate 			(void) printf("bsize %ld tp->tag %d, %s\n", fsbsize,
3997c478bd9Sstevel@tonic-gate 				tp->tag_id, tagerrs[err]);
4007c478bd9Sstevel@tonic-gate 		if (err == 0)
4017c478bd9Sstevel@tonic-gate 			break;
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 	if (fsbsize > MAXBSIZE)
4047c478bd9Sstevel@tonic-gate 		errexit(gettext("Can't find anchor volume descriptor\n"));
4057c478bd9Sstevel@tonic-gate 	secsize = fsbsize;
4067c478bd9Sstevel@tonic-gate 	if (debug)
4077c478bd9Sstevel@tonic-gate 		(void) printf("fsbsize = %ld\n", fsbsize);
4087c478bd9Sstevel@tonic-gate 	main_vdbuf = malloc(avp->avd_main_vdse.ext_len);
4097c478bd9Sstevel@tonic-gate 	res_vdbuf = malloc(avp->avd_res_vdse.ext_len);
4107c478bd9Sstevel@tonic-gate 	if (main_vdbuf == NULL || res_vdbuf == NULL)
4117c478bd9Sstevel@tonic-gate 		errexit("cannot allocate space for volume sequences\n");
4127c478bd9Sstevel@tonic-gate 	if (debug)
4137c478bd9Sstevel@tonic-gate 		(void) printf("reading volume sequences "
4147c478bd9Sstevel@tonic-gate 			"(%d bytes at %x and %x)\n",
4157c478bd9Sstevel@tonic-gate 			avp->avd_main_vdse.ext_len, avp->avd_main_vdse.ext_loc,
4167c478bd9Sstevel@tonic-gate 			avp->avd_res_vdse.ext_loc);
4177c478bd9Sstevel@tonic-gate 	if (bread(fsreadfd, main_vdbuf, fsbtodb(avp->avd_main_vdse.ext_loc),
4187c478bd9Sstevel@tonic-gate 		avp->avd_main_vdse.ext_len) != 0)
4197c478bd9Sstevel@tonic-gate 		return (0);
4207c478bd9Sstevel@tonic-gate 	if (bread(fsreadfd, res_vdbuf, fsbtodb(avp->avd_res_vdse.ext_loc),
4217c478bd9Sstevel@tonic-gate 		avp->avd_res_vdse.ext_len) != 0)
4227c478bd9Sstevel@tonic-gate 		return (0);
4237c478bd9Sstevel@tonic-gate 	end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len;
4247c478bd9Sstevel@tonic-gate 	nextblock = avp->avd_main_vdse.ext_loc;
4257c478bd9Sstevel@tonic-gate 	for (cp = (uint8_t *)main_vdbuf; cp < end; cp += fsbsize, nextblock++) {
4267c478bd9Sstevel@tonic-gate 		/* LINTED */
4277c478bd9Sstevel@tonic-gate 		tp = (struct tag *)cp;
4287c478bd9Sstevel@tonic-gate 		err = verifytag(tp, nextblock, tp, 0);
4297c478bd9Sstevel@tonic-gate 		if (debug) {
4307c478bd9Sstevel@tonic-gate 			dump16((char *)cp, "");
4317c478bd9Sstevel@tonic-gate 			(void) printf("blk %lx err %s tag %d\n", nextblock,
4327c478bd9Sstevel@tonic-gate 				tagerrs[err], tp->tag_id);
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 		if (err == 0) {
4357c478bd9Sstevel@tonic-gate 			if (serialnum >= 0 && tp->tag_sno != serialnum) {
4367c478bd9Sstevel@tonic-gate 				(void) printf(gettext("serial number mismatch "
4377c478bd9Sstevel@tonic-gate 					"tag type %d, block %lx\n"), tp->tag_id,
4387c478bd9Sstevel@tonic-gate 					nextblock);
4397c478bd9Sstevel@tonic-gate 				continue;
4407c478bd9Sstevel@tonic-gate 			}
4417c478bd9Sstevel@tonic-gate 			switch (tp->tag_id) {
4427c478bd9Sstevel@tonic-gate 			case UD_PRI_VOL_DESC:
4437c478bd9Sstevel@tonic-gate 				serialnum = tp->tag_sno;
4447c478bd9Sstevel@tonic-gate 				if (debug) {
4457c478bd9Sstevel@tonic-gate 					(void) printf("serial number = %d\n",
4467c478bd9Sstevel@tonic-gate 						serialnum);
4477c478bd9Sstevel@tonic-gate 				}
4487c478bd9Sstevel@tonic-gate 				err = check_pri_vol_desc(tp);
4497c478bd9Sstevel@tonic-gate 				break;
4507c478bd9Sstevel@tonic-gate 			case UD_ANCH_VOL_DESC:
4517c478bd9Sstevel@tonic-gate 				err = check_avdp(tp);
4527c478bd9Sstevel@tonic-gate 				break;
4537c478bd9Sstevel@tonic-gate 			case UD_VOL_DESC_PTR:
4547c478bd9Sstevel@tonic-gate 				err = check_vdp(tp);
4557c478bd9Sstevel@tonic-gate 				break;
4567c478bd9Sstevel@tonic-gate 			case UD_IMPL_USE_DESC:
4577c478bd9Sstevel@tonic-gate 				err = check_iuvd(tp);
4587c478bd9Sstevel@tonic-gate 				break;
4597c478bd9Sstevel@tonic-gate 			case UD_PART_DESC:
4607c478bd9Sstevel@tonic-gate 				err = check_part_desc(tp);
4617c478bd9Sstevel@tonic-gate 				break;
4627c478bd9Sstevel@tonic-gate 			case UD_LOG_VOL_DESC:
4637c478bd9Sstevel@tonic-gate 				err = check_log_desc(tp);
4647c478bd9Sstevel@tonic-gate 				break;
4657c478bd9Sstevel@tonic-gate 			case UD_UNALL_SPA_DESC:
4667c478bd9Sstevel@tonic-gate 				err = check_unall_desc(tp);
4677c478bd9Sstevel@tonic-gate 				break;
4687c478bd9Sstevel@tonic-gate 			case UD_TERM_DESC:
4697c478bd9Sstevel@tonic-gate 				err = check_term_desc(tp);
4707c478bd9Sstevel@tonic-gate 				goto done;
4717c478bd9Sstevel@tonic-gate 				break;
4727c478bd9Sstevel@tonic-gate 			case UD_LOG_VOL_INT:
4737c478bd9Sstevel@tonic-gate 				err = check_lvint(tp);
4747c478bd9Sstevel@tonic-gate 				break;
4757c478bd9Sstevel@tonic-gate 			default:
4767c478bd9Sstevel@tonic-gate 				(void) printf(gettext("Invalid volume "
4777c478bd9Sstevel@tonic-gate 					"sequence tag %d\n"), tp->tag_id);
4787c478bd9Sstevel@tonic-gate 			}
4797c478bd9Sstevel@tonic-gate 		} else {
4807c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Volume sequence tag error %s\n"),
4817c478bd9Sstevel@tonic-gate 				tagerrs[err]);
4827c478bd9Sstevel@tonic-gate 		}
4837c478bd9Sstevel@tonic-gate 	}
4847c478bd9Sstevel@tonic-gate done:
4857c478bd9Sstevel@tonic-gate 	if (!partp || !logvp) {
4867c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Missing partition header or"
4877c478bd9Sstevel@tonic-gate 			" logical volume descriptor\n"));
4887c478bd9Sstevel@tonic-gate 		return (0);
4897c478bd9Sstevel@tonic-gate 	}
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	/* Get the logical volume integrity descriptor */
4927c478bd9Sstevel@tonic-gate 	lvintblock = logvp->lvd_int_seq_ext.ext_loc;
4937c478bd9Sstevel@tonic-gate 	lvintlen = logvp->lvd_int_seq_ext.ext_len;
4947c478bd9Sstevel@tonic-gate 	lvintp = (struct log_vol_int_desc *)malloc(lvintlen);
4957c478bd9Sstevel@tonic-gate 	if (debug)
4967c478bd9Sstevel@tonic-gate 		(void) printf("Logvolint at %x for %d bytes\n", lvintblock,
4977c478bd9Sstevel@tonic-gate 			lvintlen);
4987c478bd9Sstevel@tonic-gate 	if (lvintp == NULL) {
4997c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Can't allocate space for logical"
5007c478bd9Sstevel@tonic-gate 			" volume integrity sequence\n"));
5017c478bd9Sstevel@tonic-gate 		return (0);
5027c478bd9Sstevel@tonic-gate 	}
5037c478bd9Sstevel@tonic-gate 	if (bread(fsreadfd, (char *)lvintp,
5047c478bd9Sstevel@tonic-gate 			fsbtodb(lvintblock), lvintlen) != 0) {
5057c478bd9Sstevel@tonic-gate 		return (0);
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 	err = verifytag(&lvintp->lvid_tag, lvintblock, &lvintp->lvid_tag,
5087c478bd9Sstevel@tonic-gate 		UD_LOG_VOL_INT);
5097c478bd9Sstevel@tonic-gate 	if (debug) {
5107c478bd9Sstevel@tonic-gate 		dump16((char *)lvintp, "\n");
5117c478bd9Sstevel@tonic-gate 	}
5127c478bd9Sstevel@tonic-gate 	if (err) {
5137c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Log_vol_int tag error: %s, tag = %d\n"),
5147c478bd9Sstevel@tonic-gate 			tagerrs[err], lvintp->lvid_tag.tag_id);
5157c478bd9Sstevel@tonic-gate 		return (0);
5167c478bd9Sstevel@tonic-gate 	}
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 	/* Get pointer to implementation use area */
5197c478bd9Sstevel@tonic-gate 	lviup = (struct lvid_iu *)&lvintp->lvid_fst[lvintp->lvid_npart*2];
5207c478bd9Sstevel@tonic-gate 	if (debug) {
5217c478bd9Sstevel@tonic-gate 		(void) printf("free space %d total %d ", lvintp->lvid_fst[0],
5227c478bd9Sstevel@tonic-gate 			lvintp->lvid_fst[1]);
5237c478bd9Sstevel@tonic-gate 	(void) printf(gettext("nfiles %d ndirs %d\n"), lviup->lvidiu_nfiles,
5247c478bd9Sstevel@tonic-gate 			lviup->lvidiu_ndirs);
5257c478bd9Sstevel@tonic-gate 	}
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	/* Set up free block map and read in the existing free space map */
5287c478bd9Sstevel@tonic-gate 	freelen = pheadp->phdr_usb.sad_ext_len;
5297c478bd9Sstevel@tonic-gate 	if (freelen == 0) {
5307c478bd9Sstevel@tonic-gate 		(void) printf(gettext("No partition free map\n"));
5317c478bd9Sstevel@tonic-gate 	}
5327c478bd9Sstevel@tonic-gate 	part_bmp_bytes = (part_len + NBBY - 1) / NBBY;
5337c478bd9Sstevel@tonic-gate 	busymap = calloc((unsigned)part_bmp_bytes, sizeof (char));
5347c478bd9Sstevel@tonic-gate 	if (busymap == NULL) {
5357c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Can't allocate free block bitmap\n"));
5367c478bd9Sstevel@tonic-gate 		return (0);
5377c478bd9Sstevel@tonic-gate 	}
5387c478bd9Sstevel@tonic-gate 	if (freelen) {
5397c478bd9Sstevel@tonic-gate 		part_bmp_sectors =
5407c478bd9Sstevel@tonic-gate 			(part_bmp_bytes + SPACEMAP_OFF + secsize - 1) /
5417c478bd9Sstevel@tonic-gate 			secsize;
5427c478bd9Sstevel@tonic-gate 		part_bmp_loc = pheadp->phdr_usb.sad_ext_loc + part_start;
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate 		/* Mark the partition map blocks busy */
5457c478bd9Sstevel@tonic-gate 		markbusy(pheadp->phdr_usb.sad_ext_loc,
5467c478bd9Sstevel@tonic-gate 			part_bmp_sectors * secsize);
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 		spacep = (struct space_bmap_desc *)
5497c478bd9Sstevel@tonic-gate 			malloc(secsize*part_bmp_sectors);
5507c478bd9Sstevel@tonic-gate 		if (spacep == NULL) {
5517c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Can't allocate partition "
5527c478bd9Sstevel@tonic-gate 				"map\n"));
5537c478bd9Sstevel@tonic-gate 			return (0);
5547c478bd9Sstevel@tonic-gate 		}
5557c478bd9Sstevel@tonic-gate 		if (bread(fsreadfd, (char *)spacep, fsbtodb(part_bmp_loc),
5567c478bd9Sstevel@tonic-gate 			part_bmp_sectors * secsize) != 0)
5577c478bd9Sstevel@tonic-gate 			return (0);
5587c478bd9Sstevel@tonic-gate 		cp = (uint8_t *)spacep;
5597c478bd9Sstevel@tonic-gate 		err = verifytag(&spacep->sbd_tag, pheadp->phdr_usb.sad_ext_loc,
5607c478bd9Sstevel@tonic-gate 			&spacep->sbd_tag, UD_SPA_BMAP_DESC);
5617c478bd9Sstevel@tonic-gate 		if (debug) {
5627c478bd9Sstevel@tonic-gate 			dump16((char *)cp, "");
5637c478bd9Sstevel@tonic-gate 			(void) printf("blk %x err %s tag %d\n", part_bmp_loc,
5647c478bd9Sstevel@tonic-gate 				tagerrs[err], spacep->sbd_tag.tag_id);
5657c478bd9Sstevel@tonic-gate 		}
5667c478bd9Sstevel@tonic-gate 		freemap = (char *)cp + SPACEMAP_OFF;
5677c478bd9Sstevel@tonic-gate 		if (debug)
5687c478bd9Sstevel@tonic-gate 			(void) printf("err %s tag %x space bitmap at %x"
5697c478bd9Sstevel@tonic-gate 				" length %d nbits %d nbytes %d\n",
5707c478bd9Sstevel@tonic-gate 				tagerrs[err], spacep->sbd_tag.tag_id,
5717c478bd9Sstevel@tonic-gate 				part_bmp_loc, part_bmp_sectors,
5727c478bd9Sstevel@tonic-gate 				spacep->sbd_nbits, spacep->sbd_nbytes);
5737c478bd9Sstevel@tonic-gate 		if (err) {
5747c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Space bitmap tag error, %s, "
5757c478bd9Sstevel@tonic-gate 				"tag = %d\n"),
5767c478bd9Sstevel@tonic-gate 				tagerrs[err], spacep->sbd_tag.tag_id);
5777c478bd9Sstevel@tonic-gate 			return (0);
5787c478bd9Sstevel@tonic-gate 		}
5797c478bd9Sstevel@tonic-gate 	}
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 	/* Get the fileset descriptor */
5827c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&logvp->lvd_lvcu;
5837c478bd9Sstevel@tonic-gate 	filesetblock = lap->lad_ext_loc;
5847c478bd9Sstevel@tonic-gate 	filesetlen = lap->lad_ext_len;
5857c478bd9Sstevel@tonic-gate 	markbusy(filesetblock, filesetlen);
5867c478bd9Sstevel@tonic-gate 	if (debug)
5877c478bd9Sstevel@tonic-gate 		(void) printf("Fileset descriptor at %x for %d bytes\n",
5887c478bd9Sstevel@tonic-gate 			filesetblock, filesetlen);
5897c478bd9Sstevel@tonic-gate 	if (!filesetlen) {
5907c478bd9Sstevel@tonic-gate 		(void) printf(gettext("No file set descriptor found\n"));
5917c478bd9Sstevel@tonic-gate 		return (0);
5927c478bd9Sstevel@tonic-gate 	}
5937c478bd9Sstevel@tonic-gate 	fileset = (struct file_set_desc *)malloc(filesetlen);
5947c478bd9Sstevel@tonic-gate 	if (fileset == NULL) {
5957c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Unable to allocate fileset\n"));
5967c478bd9Sstevel@tonic-gate 		return (0);
5977c478bd9Sstevel@tonic-gate 	}
5987c478bd9Sstevel@tonic-gate 	if (bread(fsreadfd, (char *)fileset, fsbtodb(filesetblock + part_start),
5997c478bd9Sstevel@tonic-gate 		filesetlen) != 0) {
6007c478bd9Sstevel@tonic-gate 		return (0);
6017c478bd9Sstevel@tonic-gate 	}
6027c478bd9Sstevel@tonic-gate 	err = verifytag(&fileset->fsd_tag, filesetblock, &fileset->fsd_tag,
6037c478bd9Sstevel@tonic-gate 		UD_FILE_SET_DESC);
6047c478bd9Sstevel@tonic-gate 	if (err) {
6057c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Fileset tag error, tag = %d, %s\n"),
6067c478bd9Sstevel@tonic-gate 			fileset->fsd_tag.tag_id, tagerrs[err]);
6077c478bd9Sstevel@tonic-gate 		return (0);
6087c478bd9Sstevel@tonic-gate 	}
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 	/* Get the address of the root file entry */
6117c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&fileset->fsd_root_icb;
6127c478bd9Sstevel@tonic-gate 	rootblock = lap->lad_ext_loc;
6137c478bd9Sstevel@tonic-gate 	rootlen = lap->lad_ext_len;
6147c478bd9Sstevel@tonic-gate 	if (debug)
6157c478bd9Sstevel@tonic-gate 		(void) printf("Root at %x for %d bytes\n", rootblock, rootlen);
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 	return (1);
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate uint32_t
get_last_block()6217c478bd9Sstevel@tonic-gate get_last_block()
6227c478bd9Sstevel@tonic-gate {
6237c478bd9Sstevel@tonic-gate 	struct vtoc vtoc;
6247c478bd9Sstevel@tonic-gate 	struct dk_cinfo dki_info;
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 	if (ioctl(fsreadfd, DKIOCGVTOC, (intptr_t)&vtoc) != 0) {
6277c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Unable to read VTOC\n"));
6287c478bd9Sstevel@tonic-gate 		return (0);
6297c478bd9Sstevel@tonic-gate 	}
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	if (vtoc.v_sanity != VTOC_SANE) {
6327c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n"));
6337c478bd9Sstevel@tonic-gate 		return (0);
6347c478bd9Sstevel@tonic-gate 	}
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	if (ioctl(fsreadfd, DKIOCINFO, (intptr_t)&dki_info) != 0) {
6377c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
6387c478bd9Sstevel@tonic-gate 		    gettext("Could not get the slice information\n"));
6397c478bd9Sstevel@tonic-gate 		return (0);
6407c478bd9Sstevel@tonic-gate 	}
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
6437c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
6447c478bd9Sstevel@tonic-gate 		    gettext("dki_info.dki_partition > V_NUMPAR\n"));
6457c478bd9Sstevel@tonic-gate 		return (0);
6467c478bd9Sstevel@tonic-gate 	}
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size);
6497c478bd9Sstevel@tonic-gate }
650