10Sstevel@tonic-gate /* 2*1053Smaheshvs * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 70Sstevel@tonic-gate /* All Rights Reserved */ 80Sstevel@tonic-gate 90Sstevel@tonic-gate /* 100Sstevel@tonic-gate * Copyright (c) 1980, 1986, 1990 The Regents of the University of California. 110Sstevel@tonic-gate * All rights reserved. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 140Sstevel@tonic-gate * provided that: (1) source distributions retain this entire copyright 150Sstevel@tonic-gate * notice and comment, and (2) distributions including binaries display 160Sstevel@tonic-gate * the following acknowledgement: ``This product includes software 170Sstevel@tonic-gate * developed by the University of California, Berkeley and its contributors'' 180Sstevel@tonic-gate * in the documentation or other materials provided with the distribution 190Sstevel@tonic-gate * and in all advertising materials mentioning features or use of this 200Sstevel@tonic-gate * software. Neither the name of the University nor the names of its 210Sstevel@tonic-gate * contributors may be used to endorse or promote products derived 220Sstevel@tonic-gate * from this software without specific prior written permission. 230Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 240Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 250Sstevel@tonic-gate * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 300Sstevel@tonic-gate #define DKTYPENAMES 310Sstevel@tonic-gate #include <stdio.h> 320Sstevel@tonic-gate #include <stdlib.h> 330Sstevel@tonic-gate #include <unistd.h> 340Sstevel@tonic-gate #include <fcntl.h> 350Sstevel@tonic-gate #include <ustat.h> 360Sstevel@tonic-gate #include <errno.h> 370Sstevel@tonic-gate #include <sys/param.h> 380Sstevel@tonic-gate #include <sys/types.h> 390Sstevel@tonic-gate #include <sys/sysmacros.h> 400Sstevel@tonic-gate #include <sys/mntent.h> 410Sstevel@tonic-gate #include <sys/mnttab.h> 420Sstevel@tonic-gate #include <sys/dkio.h> 430Sstevel@tonic-gate #include <sys/filio.h> 440Sstevel@tonic-gate #include <sys/isa_defs.h> /* for ENDIAN defines */ 450Sstevel@tonic-gate #include <sys/int_const.h> 460Sstevel@tonic-gate #include <sys/vnode.h> 470Sstevel@tonic-gate #include <sys/stat.h> 480Sstevel@tonic-gate #include <sys/file.h> 490Sstevel@tonic-gate #include <sys/fcntl.h> 500Sstevel@tonic-gate #include <string.h> 510Sstevel@tonic-gate #include <sys/vfstab.h> 520Sstevel@tonic-gate #include <sys/fs/udf_volume.h> 530Sstevel@tonic-gate #include <sys/vtoc.h> 540Sstevel@tonic-gate #include <locale.h> 550Sstevel@tonic-gate 560Sstevel@tonic-gate #include "fsck.h" 570Sstevel@tonic-gate 580Sstevel@tonic-gate extern void errexit(char *, ...); 590Sstevel@tonic-gate extern int32_t mounted(char *); 600Sstevel@tonic-gate extern void pwarn(char *, ...); 610Sstevel@tonic-gate extern void pfatal(char *, ...); 620Sstevel@tonic-gate extern void printclean(); 630Sstevel@tonic-gate extern void bufinit(); 640Sstevel@tonic-gate extern void ckfini(); 650Sstevel@tonic-gate extern int32_t bread(int32_t, char *, daddr_t, long); 660Sstevel@tonic-gate extern int32_t reply(char *); 670Sstevel@tonic-gate 680Sstevel@tonic-gate static int32_t readvolseq(int32_t); 690Sstevel@tonic-gate static uint32_t get_last_block(); 700Sstevel@tonic-gate extern int32_t verifytag(struct tag *, uint32_t, struct tag *, int); 710Sstevel@tonic-gate extern char *tagerrs[]; 720Sstevel@tonic-gate 730Sstevel@tonic-gate #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 740Sstevel@tonic-gate 750Sstevel@tonic-gate extern int mflag; 760Sstevel@tonic-gate extern char hotroot; 770Sstevel@tonic-gate 780Sstevel@tonic-gate char avdbuf[MAXBSIZE]; /* buffer for anchor volume descriptor */ 790Sstevel@tonic-gate char *main_vdbuf; /* buffer for entire main volume sequence */ 800Sstevel@tonic-gate char *res_vdbuf; /* buffer for reserved volume sequence */ 810Sstevel@tonic-gate int serialnum = -1; /* set from primary volume descriptor */ 820Sstevel@tonic-gate 830Sstevel@tonic-gate char * 84*1053Smaheshvs setup(char *dev) 850Sstevel@tonic-gate { 860Sstevel@tonic-gate dev_t rootdev; 870Sstevel@tonic-gate struct stat statb; 880Sstevel@tonic-gate static char devstr[MAXPATHLEN]; 890Sstevel@tonic-gate char *raw, *rawname(), *unrawname(); 900Sstevel@tonic-gate struct ustat ustatb; 910Sstevel@tonic-gate 920Sstevel@tonic-gate havesb = 0; 930Sstevel@tonic-gate if (stat("/", &statb) < 0) 940Sstevel@tonic-gate errexit(gettext("Can't stat root\n")); 950Sstevel@tonic-gate rootdev = statb.st_dev; 960Sstevel@tonic-gate 970Sstevel@tonic-gate devname = devstr; 980Sstevel@tonic-gate (void) strncpy(devstr, dev, sizeof (devstr)); 990Sstevel@tonic-gate restat: 1000Sstevel@tonic-gate if (stat(devstr, &statb) < 0) { 1010Sstevel@tonic-gate (void) printf(gettext("Can't stat %s\n"), devstr); 1020Sstevel@tonic-gate exitstat = 34; 1030Sstevel@tonic-gate return (0); 1040Sstevel@tonic-gate } 1050Sstevel@tonic-gate /* 1060Sstevel@tonic-gate * A mount point is specified. But the mount point doesn't 1070Sstevel@tonic-gate * match entries in the /etc/vfstab. 1080Sstevel@tonic-gate * Search mnttab, because if the fs is error locked, it is 1090Sstevel@tonic-gate * allowed to be fsck'd while mounted. 1100Sstevel@tonic-gate */ 1110Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == S_IFDIR) { 1120Sstevel@tonic-gate (void) printf(gettext("%s is not a block or " 1130Sstevel@tonic-gate "character device\n"), dev); 1140Sstevel@tonic-gate return (0); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == S_IFBLK) { 1180Sstevel@tonic-gate if (rootdev == statb.st_rdev) 1190Sstevel@tonic-gate hotroot++; 1200Sstevel@tonic-gate else if (ustat(statb.st_rdev, &ustatb) == 0) { 1210Sstevel@tonic-gate (void) printf(gettext("%s is a mounted file system, " 1220Sstevel@tonic-gate "ignored\n"), dev); 1230Sstevel@tonic-gate exitstat = 33; 1240Sstevel@tonic-gate return (0); 1250Sstevel@tonic-gate } 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == S_IFDIR) { 1280Sstevel@tonic-gate FILE *vfstab; 1290Sstevel@tonic-gate struct vfstab vfsbuf; 1300Sstevel@tonic-gate /* 1310Sstevel@tonic-gate * Check vfstab for a mount point with this name 1320Sstevel@tonic-gate */ 1330Sstevel@tonic-gate if ((vfstab = fopen(VFSTAB, "r")) == NULL) { 1340Sstevel@tonic-gate errexit(gettext("Can't open checklist file: %s\n"), 1350Sstevel@tonic-gate VFSTAB); 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate while (getvfsent(vfstab, &vfsbuf) == NULL) { 1380Sstevel@tonic-gate if (strcmp(devstr, vfsbuf.vfs_mountp) == 0) { 1390Sstevel@tonic-gate if (strcmp(vfsbuf.vfs_fstype, 1400Sstevel@tonic-gate MNTTYPE_UDFS) != 0) { 1410Sstevel@tonic-gate /* 1420Sstevel@tonic-gate * found the entry but it is not a 1430Sstevel@tonic-gate * udfs filesystem, don't check it 1440Sstevel@tonic-gate */ 1450Sstevel@tonic-gate (void) fclose(vfstab); 1460Sstevel@tonic-gate return (0); 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate (void) strcpy(devstr, vfsbuf.vfs_special); 1490Sstevel@tonic-gate if (rflag) { 1500Sstevel@tonic-gate raw = rawname( 1510Sstevel@tonic-gate unrawname(vfsbuf.vfs_special)); 1520Sstevel@tonic-gate (void) strcpy(devstr, raw); 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate goto restat; 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate (void) fclose(vfstab); 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate } else if (((statb.st_mode & S_IFMT) != S_IFBLK) && 1600Sstevel@tonic-gate ((statb.st_mode & S_IFMT) != S_IFCHR)) { 1610Sstevel@tonic-gate if (preen) 1620Sstevel@tonic-gate pwarn(gettext("file is not a block or " 1630Sstevel@tonic-gate "character device.\n")); 1640Sstevel@tonic-gate else if (reply(gettext("file is not a block or " 1650Sstevel@tonic-gate "character device; OK")) 1660Sstevel@tonic-gate == 0) 1670Sstevel@tonic-gate return (0); 1680Sstevel@tonic-gate /* 1690Sstevel@tonic-gate * To fsck regular files (fs images) 1700Sstevel@tonic-gate * we need to clear the rflag since 1710Sstevel@tonic-gate * regular files don't have raw names. --CW 1720Sstevel@tonic-gate */ 1730Sstevel@tonic-gate rflag = 0; 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate if (mounted(devstr)) { 1770Sstevel@tonic-gate if (rflag) 1780Sstevel@tonic-gate mountedfs++; 1790Sstevel@tonic-gate else { 1800Sstevel@tonic-gate (void) printf(gettext("%s is mounted, fsck on BLOCK " 1810Sstevel@tonic-gate "device ignored\n"), devstr); 1820Sstevel@tonic-gate exit(33); 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate sync(); /* call sync, only when devstr's mounted */ 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate if (rflag) { 1870Sstevel@tonic-gate char blockname[MAXPATHLEN]; 1880Sstevel@tonic-gate /* 1890Sstevel@tonic-gate * For root device check, must check 1900Sstevel@tonic-gate * block devices. 1910Sstevel@tonic-gate */ 1920Sstevel@tonic-gate (void) strcpy(blockname, devstr); 1930Sstevel@tonic-gate if (stat(unrawname(blockname), &statb) < 0) { 1940Sstevel@tonic-gate (void) printf(gettext("Can't stat %s\n"), blockname); 1950Sstevel@tonic-gate exitstat = 34; 1960Sstevel@tonic-gate return (0); 1970Sstevel@tonic-gate } 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate if (rootdev == statb.st_rdev) 2000Sstevel@tonic-gate hotroot++; 2010Sstevel@tonic-gate if ((fsreadfd = open(devstr, O_RDONLY)) < 0) { 2020Sstevel@tonic-gate (void) printf(gettext("Can't open %s\n"), devstr); 2030Sstevel@tonic-gate exitstat = 34; 2040Sstevel@tonic-gate return (0); 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate if (preen == 0 || debug != 0) 2070Sstevel@tonic-gate (void) printf("** %s", devstr); 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate if (nflag || (fswritefd = open(devstr, O_WRONLY)) < 0) { 2100Sstevel@tonic-gate fswritefd = -1; 2110Sstevel@tonic-gate if (preen && !debug) 2120Sstevel@tonic-gate pfatal(gettext("(NO WRITE ACCESS)\n")); 2130Sstevel@tonic-gate (void) printf(gettext(" (NO WRITE)")); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate if (preen == 0) 2160Sstevel@tonic-gate (void) printf("\n"); 2170Sstevel@tonic-gate if (debug && (hotroot || mountedfs)) { 2180Sstevel@tonic-gate (void) printf("** %s", devstr); 2190Sstevel@tonic-gate if (hotroot) 2200Sstevel@tonic-gate (void) printf(" is root fs%s", 2210Sstevel@tonic-gate mountedfs? " and": ""); 2220Sstevel@tonic-gate if (mountedfs) 2230Sstevel@tonic-gate (void) printf(" is mounted"); 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate (void) printf(".\n"); 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate fsmodified = 0; 2280Sstevel@tonic-gate if (readvolseq(1) == 0) 2290Sstevel@tonic-gate return (0); 2300Sstevel@tonic-gate if (fflag == 0 && preen && 2310Sstevel@tonic-gate lvintp->lvid_int_type == LVI_CLOSE) { 2320Sstevel@tonic-gate iscorrupt = 0; 2330Sstevel@tonic-gate printclean(); 2340Sstevel@tonic-gate return (0); 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate listmax = FEGROW; 2370Sstevel@tonic-gate inphash = (struct fileinfo **)calloc(FEGROW, 2380Sstevel@tonic-gate sizeof (struct fileinfo *)); 2390Sstevel@tonic-gate inphead = (struct fileinfo *)calloc(FEGROW + 1, 2400Sstevel@tonic-gate sizeof (struct fileinfo)); 2410Sstevel@tonic-gate if (inphead == NULL || inphash == NULL) { 2420Sstevel@tonic-gate (void) printf(gettext("cannot alloc %ld bytes for inphead\n"), 2430Sstevel@tonic-gate listmax * sizeof (struct fileinfo)); 2440Sstevel@tonic-gate goto badsb; 2450Sstevel@tonic-gate } 2460Sstevel@tonic-gate inpnext = inphead; 2470Sstevel@tonic-gate inplast = &inphead[listmax]; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate bufinit(); 2500Sstevel@tonic-gate return (devstr); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate badsb: 2530Sstevel@tonic-gate ckfini(); 2540Sstevel@tonic-gate exitstat = 39; 2550Sstevel@tonic-gate return (0); 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate 258*1053Smaheshvs static int 2590Sstevel@tonic-gate check_pri_vol_desc(struct tag *tp) 2600Sstevel@tonic-gate { 2610Sstevel@tonic-gate pvolp = (struct pri_vol_desc *)tp; 2620Sstevel@tonic-gate return (0); 2630Sstevel@tonic-gate } 2640Sstevel@tonic-gate 265*1053Smaheshvs static int 2660Sstevel@tonic-gate check_avdp(struct tag *tp) 2670Sstevel@tonic-gate { 2680Sstevel@tonic-gate avdp = (struct anch_vol_desc_ptr *)tp; 2690Sstevel@tonic-gate return (0); 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate 272*1053Smaheshvs static int 2730Sstevel@tonic-gate check_vdp(struct tag *tp) 2740Sstevel@tonic-gate { 2750Sstevel@tonic-gate volp = (struct vdp_desc *)tp; 2760Sstevel@tonic-gate return (0); 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate 279*1053Smaheshvs static int 2800Sstevel@tonic-gate check_iuvd(struct tag *tp) 2810Sstevel@tonic-gate { 2820Sstevel@tonic-gate iudp = (struct iuvd_desc *)tp; 2830Sstevel@tonic-gate return (0); 2840Sstevel@tonic-gate } 2850Sstevel@tonic-gate 286*1053Smaheshvs static int 2870Sstevel@tonic-gate check_part_desc(struct tag *tp) 2880Sstevel@tonic-gate { 2890Sstevel@tonic-gate partp = (struct part_desc *)tp; 2900Sstevel@tonic-gate /* LINTED */ 2910Sstevel@tonic-gate pheadp = (struct phdr_desc *)&partp->pd_pc_use; 2920Sstevel@tonic-gate part_start = partp->pd_part_start; 2930Sstevel@tonic-gate part_len = partp->pd_part_length; 2940Sstevel@tonic-gate if (debug) 2950Sstevel@tonic-gate (void) printf("partition start %x len %x\n", part_start, 2960Sstevel@tonic-gate part_len); 2970Sstevel@tonic-gate return (0); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 300*1053Smaheshvs static int 3010Sstevel@tonic-gate check_log_desc(struct tag *tp) 3020Sstevel@tonic-gate { 3030Sstevel@tonic-gate logvp = (struct log_vol_desc *)tp; 3040Sstevel@tonic-gate return (0); 3050Sstevel@tonic-gate } 3060Sstevel@tonic-gate 307*1053Smaheshvs static int 3080Sstevel@tonic-gate check_unall_desc(struct tag *tp) 3090Sstevel@tonic-gate { 3100Sstevel@tonic-gate unallp = (struct unall_desc *)tp; 3110Sstevel@tonic-gate return (0); 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate /* ARGSUSED */ 315*1053Smaheshvs static int 3160Sstevel@tonic-gate check_term_desc(struct tag *tp) 3170Sstevel@tonic-gate { 3180Sstevel@tonic-gate return (0); 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate 321*1053Smaheshvs static int 3220Sstevel@tonic-gate check_lvint(struct tag *tp) 3230Sstevel@tonic-gate { 3240Sstevel@tonic-gate /* LINTED */ 3250Sstevel@tonic-gate lvintp = (struct log_vol_int_desc *)tp; 3260Sstevel@tonic-gate return (0); 3270Sstevel@tonic-gate } 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate void 3300Sstevel@tonic-gate dump16(char *cp, char *nl) 3310Sstevel@tonic-gate { 3320Sstevel@tonic-gate int i; 3330Sstevel@tonic-gate long *ptr; 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate for (i = 0; i < 16; i += 4) { 3370Sstevel@tonic-gate /* LINTED */ 3380Sstevel@tonic-gate ptr = (long *)(cp + i); 3390Sstevel@tonic-gate (void) printf("%08lx ", *ptr); 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate (void) printf(nl); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate /* 3450Sstevel@tonic-gate * Read in the super block and its summary info. 3460Sstevel@tonic-gate */ 3470Sstevel@tonic-gate /* ARGSUSED */ 348*1053Smaheshvs static int 3490Sstevel@tonic-gate readvolseq(int32_t listerr) 3500Sstevel@tonic-gate { 3510Sstevel@tonic-gate struct tag *tp; 3520Sstevel@tonic-gate long_ad_t *lap; 3530Sstevel@tonic-gate struct anch_vol_desc_ptr *avp; 3540Sstevel@tonic-gate uint8_t *cp, *end; 3550Sstevel@tonic-gate daddr_t nextblock; 3560Sstevel@tonic-gate int err; 3570Sstevel@tonic-gate long freelen; 3580Sstevel@tonic-gate daddr_t avdp; 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate disk_size = get_last_block(); 3610Sstevel@tonic-gate if (debug) 3620Sstevel@tonic-gate (void) printf("Disk partition size: %x\n", disk_size); 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate /* LINTED */ 3650Sstevel@tonic-gate avp = (struct anch_vol_desc_ptr *)avdbuf; 3660Sstevel@tonic-gate tp = &avp->avd_tag; 3670Sstevel@tonic-gate for (fsbsize = 512; fsbsize <= MAXBSIZE; fsbsize <<= 1) { 3680Sstevel@tonic-gate avdp = FIRSTAVDP * fsbsize / DEV_BSIZE; 3690Sstevel@tonic-gate if (bread(fsreadfd, avdbuf, avdp, fsbsize) != 0) 3700Sstevel@tonic-gate return (0); 3710Sstevel@tonic-gate err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC); 3720Sstevel@tonic-gate if (debug) 3730Sstevel@tonic-gate (void) printf("bsize %ld tp->tag %d, %s\n", fsbsize, 3740Sstevel@tonic-gate tp->tag_id, tagerrs[err]); 3750Sstevel@tonic-gate if (err == 0) 3760Sstevel@tonic-gate break; 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate if (fsbsize > MAXBSIZE) 3790Sstevel@tonic-gate errexit(gettext("Can't find anchor volume descriptor\n")); 3800Sstevel@tonic-gate secsize = fsbsize; 3810Sstevel@tonic-gate if (debug) 3820Sstevel@tonic-gate (void) printf("fsbsize = %ld\n", fsbsize); 3830Sstevel@tonic-gate main_vdbuf = malloc(avp->avd_main_vdse.ext_len); 3840Sstevel@tonic-gate res_vdbuf = malloc(avp->avd_res_vdse.ext_len); 3850Sstevel@tonic-gate if (main_vdbuf == NULL || res_vdbuf == NULL) 3860Sstevel@tonic-gate errexit("cannot allocate space for volume sequences\n"); 3870Sstevel@tonic-gate if (debug) 3880Sstevel@tonic-gate (void) printf("reading volume sequences " 3890Sstevel@tonic-gate "(%d bytes at %x and %x)\n", 3900Sstevel@tonic-gate avp->avd_main_vdse.ext_len, avp->avd_main_vdse.ext_loc, 3910Sstevel@tonic-gate avp->avd_res_vdse.ext_loc); 3920Sstevel@tonic-gate if (bread(fsreadfd, main_vdbuf, fsbtodb(avp->avd_main_vdse.ext_loc), 3930Sstevel@tonic-gate avp->avd_main_vdse.ext_len) != 0) 3940Sstevel@tonic-gate return (0); 3950Sstevel@tonic-gate if (bread(fsreadfd, res_vdbuf, fsbtodb(avp->avd_res_vdse.ext_loc), 3960Sstevel@tonic-gate avp->avd_res_vdse.ext_len) != 0) 3970Sstevel@tonic-gate return (0); 3980Sstevel@tonic-gate end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len; 3990Sstevel@tonic-gate nextblock = avp->avd_main_vdse.ext_loc; 4000Sstevel@tonic-gate for (cp = (uint8_t *)main_vdbuf; cp < end; cp += fsbsize, nextblock++) { 4010Sstevel@tonic-gate /* LINTED */ 4020Sstevel@tonic-gate tp = (struct tag *)cp; 4030Sstevel@tonic-gate err = verifytag(tp, nextblock, tp, 0); 4040Sstevel@tonic-gate if (debug) { 4050Sstevel@tonic-gate dump16((char *)cp, ""); 4060Sstevel@tonic-gate (void) printf("blk %lx err %s tag %d\n", nextblock, 4070Sstevel@tonic-gate tagerrs[err], tp->tag_id); 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate if (err == 0) { 4100Sstevel@tonic-gate if (serialnum >= 0 && tp->tag_sno != serialnum) { 4110Sstevel@tonic-gate (void) printf(gettext("serial number mismatch " 4120Sstevel@tonic-gate "tag type %d, block %lx\n"), tp->tag_id, 4130Sstevel@tonic-gate nextblock); 4140Sstevel@tonic-gate continue; 4150Sstevel@tonic-gate } 4160Sstevel@tonic-gate switch (tp->tag_id) { 4170Sstevel@tonic-gate case UD_PRI_VOL_DESC: 4180Sstevel@tonic-gate serialnum = tp->tag_sno; 4190Sstevel@tonic-gate if (debug) { 4200Sstevel@tonic-gate (void) printf("serial number = %d\n", 4210Sstevel@tonic-gate serialnum); 4220Sstevel@tonic-gate } 4230Sstevel@tonic-gate err = check_pri_vol_desc(tp); 4240Sstevel@tonic-gate break; 4250Sstevel@tonic-gate case UD_ANCH_VOL_DESC: 4260Sstevel@tonic-gate err = check_avdp(tp); 4270Sstevel@tonic-gate break; 4280Sstevel@tonic-gate case UD_VOL_DESC_PTR: 4290Sstevel@tonic-gate err = check_vdp(tp); 4300Sstevel@tonic-gate break; 4310Sstevel@tonic-gate case UD_IMPL_USE_DESC: 4320Sstevel@tonic-gate err = check_iuvd(tp); 4330Sstevel@tonic-gate break; 4340Sstevel@tonic-gate case UD_PART_DESC: 4350Sstevel@tonic-gate err = check_part_desc(tp); 4360Sstevel@tonic-gate break; 4370Sstevel@tonic-gate case UD_LOG_VOL_DESC: 4380Sstevel@tonic-gate err = check_log_desc(tp); 4390Sstevel@tonic-gate break; 4400Sstevel@tonic-gate case UD_UNALL_SPA_DESC: 4410Sstevel@tonic-gate err = check_unall_desc(tp); 4420Sstevel@tonic-gate break; 4430Sstevel@tonic-gate case UD_TERM_DESC: 4440Sstevel@tonic-gate err = check_term_desc(tp); 4450Sstevel@tonic-gate goto done; 4460Sstevel@tonic-gate break; 4470Sstevel@tonic-gate case UD_LOG_VOL_INT: 4480Sstevel@tonic-gate err = check_lvint(tp); 4490Sstevel@tonic-gate break; 4500Sstevel@tonic-gate default: 4510Sstevel@tonic-gate (void) printf(gettext("Invalid volume " 4520Sstevel@tonic-gate "sequence tag %d\n"), tp->tag_id); 4530Sstevel@tonic-gate } 4540Sstevel@tonic-gate } else { 4550Sstevel@tonic-gate (void) printf(gettext("Volume sequence tag error %s\n"), 4560Sstevel@tonic-gate tagerrs[err]); 4570Sstevel@tonic-gate } 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate done: 4600Sstevel@tonic-gate if (!partp || !logvp) { 4610Sstevel@tonic-gate (void) printf(gettext("Missing partition header or" 4620Sstevel@tonic-gate " logical volume descriptor\n")); 4630Sstevel@tonic-gate return (0); 4640Sstevel@tonic-gate } 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate /* Get the logical volume integrity descriptor */ 4670Sstevel@tonic-gate lvintblock = logvp->lvd_int_seq_ext.ext_loc; 4680Sstevel@tonic-gate lvintlen = logvp->lvd_int_seq_ext.ext_len; 4690Sstevel@tonic-gate lvintp = (struct log_vol_int_desc *)malloc(lvintlen); 4700Sstevel@tonic-gate if (debug) 4710Sstevel@tonic-gate (void) printf("Logvolint at %x for %d bytes\n", lvintblock, 4720Sstevel@tonic-gate lvintlen); 4730Sstevel@tonic-gate if (lvintp == NULL) { 4740Sstevel@tonic-gate (void) printf(gettext("Can't allocate space for logical" 4750Sstevel@tonic-gate " volume integrity sequence\n")); 4760Sstevel@tonic-gate return (0); 4770Sstevel@tonic-gate } 4780Sstevel@tonic-gate if (bread(fsreadfd, (char *)lvintp, 4790Sstevel@tonic-gate fsbtodb(lvintblock), lvintlen) != 0) { 4800Sstevel@tonic-gate return (0); 4810Sstevel@tonic-gate } 4820Sstevel@tonic-gate err = verifytag(&lvintp->lvid_tag, lvintblock, &lvintp->lvid_tag, 4830Sstevel@tonic-gate UD_LOG_VOL_INT); 4840Sstevel@tonic-gate if (debug) { 4850Sstevel@tonic-gate dump16((char *)lvintp, "\n"); 4860Sstevel@tonic-gate } 4870Sstevel@tonic-gate if (err) { 4880Sstevel@tonic-gate (void) printf(gettext("Log_vol_int tag error: %s, tag = %d\n"), 4890Sstevel@tonic-gate tagerrs[err], lvintp->lvid_tag.tag_id); 4900Sstevel@tonic-gate return (0); 4910Sstevel@tonic-gate } 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate /* Get pointer to implementation use area */ 4940Sstevel@tonic-gate lviup = (struct lvid_iu *)&lvintp->lvid_fst[lvintp->lvid_npart*2]; 4950Sstevel@tonic-gate if (debug) { 4960Sstevel@tonic-gate (void) printf("free space %d total %d ", lvintp->lvid_fst[0], 4970Sstevel@tonic-gate lvintp->lvid_fst[1]); 4980Sstevel@tonic-gate (void) printf(gettext("nfiles %d ndirs %d\n"), lviup->lvidiu_nfiles, 4990Sstevel@tonic-gate lviup->lvidiu_ndirs); 5000Sstevel@tonic-gate } 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate /* Set up free block map and read in the existing free space map */ 5030Sstevel@tonic-gate freelen = pheadp->phdr_usb.sad_ext_len; 5040Sstevel@tonic-gate if (freelen == 0) { 5050Sstevel@tonic-gate (void) printf(gettext("No partition free map\n")); 5060Sstevel@tonic-gate } 5070Sstevel@tonic-gate part_bmp_bytes = (part_len + NBBY - 1) / NBBY; 5080Sstevel@tonic-gate busymap = calloc((unsigned)part_bmp_bytes, sizeof (char)); 5090Sstevel@tonic-gate if (busymap == NULL) { 5100Sstevel@tonic-gate (void) printf(gettext("Can't allocate free block bitmap\n")); 5110Sstevel@tonic-gate return (0); 5120Sstevel@tonic-gate } 5130Sstevel@tonic-gate if (freelen) { 5140Sstevel@tonic-gate part_bmp_sectors = 5150Sstevel@tonic-gate (part_bmp_bytes + SPACEMAP_OFF + secsize - 1) / 5160Sstevel@tonic-gate secsize; 5170Sstevel@tonic-gate part_bmp_loc = pheadp->phdr_usb.sad_ext_loc + part_start; 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate /* Mark the partition map blocks busy */ 5200Sstevel@tonic-gate markbusy(pheadp->phdr_usb.sad_ext_loc, 5210Sstevel@tonic-gate part_bmp_sectors * secsize); 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate spacep = (struct space_bmap_desc *) 5240Sstevel@tonic-gate malloc(secsize*part_bmp_sectors); 5250Sstevel@tonic-gate if (spacep == NULL) { 5260Sstevel@tonic-gate (void) printf(gettext("Can't allocate partition " 5270Sstevel@tonic-gate "map\n")); 5280Sstevel@tonic-gate return (0); 5290Sstevel@tonic-gate } 5300Sstevel@tonic-gate if (bread(fsreadfd, (char *)spacep, fsbtodb(part_bmp_loc), 5310Sstevel@tonic-gate part_bmp_sectors * secsize) != 0) 5320Sstevel@tonic-gate return (0); 5330Sstevel@tonic-gate cp = (uint8_t *)spacep; 5340Sstevel@tonic-gate err = verifytag(&spacep->sbd_tag, pheadp->phdr_usb.sad_ext_loc, 5350Sstevel@tonic-gate &spacep->sbd_tag, UD_SPA_BMAP_DESC); 5360Sstevel@tonic-gate if (debug) { 5370Sstevel@tonic-gate dump16((char *)cp, ""); 5380Sstevel@tonic-gate (void) printf("blk %x err %s tag %d\n", part_bmp_loc, 5390Sstevel@tonic-gate tagerrs[err], spacep->sbd_tag.tag_id); 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate freemap = (char *)cp + SPACEMAP_OFF; 5420Sstevel@tonic-gate if (debug) 5430Sstevel@tonic-gate (void) printf("err %s tag %x space bitmap at %x" 5440Sstevel@tonic-gate " length %d nbits %d nbytes %d\n", 5450Sstevel@tonic-gate tagerrs[err], spacep->sbd_tag.tag_id, 5460Sstevel@tonic-gate part_bmp_loc, part_bmp_sectors, 5470Sstevel@tonic-gate spacep->sbd_nbits, spacep->sbd_nbytes); 5480Sstevel@tonic-gate if (err) { 5490Sstevel@tonic-gate (void) printf(gettext("Space bitmap tag error, %s, " 5500Sstevel@tonic-gate "tag = %d\n"), 5510Sstevel@tonic-gate tagerrs[err], spacep->sbd_tag.tag_id); 5520Sstevel@tonic-gate return (0); 5530Sstevel@tonic-gate } 5540Sstevel@tonic-gate } 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate /* Get the fileset descriptor */ 5570Sstevel@tonic-gate lap = (long_ad_t *)&logvp->lvd_lvcu; 5580Sstevel@tonic-gate filesetblock = lap->lad_ext_loc; 5590Sstevel@tonic-gate filesetlen = lap->lad_ext_len; 5600Sstevel@tonic-gate markbusy(filesetblock, filesetlen); 5610Sstevel@tonic-gate if (debug) 5620Sstevel@tonic-gate (void) printf("Fileset descriptor at %x for %d bytes\n", 5630Sstevel@tonic-gate filesetblock, filesetlen); 5640Sstevel@tonic-gate if (!filesetlen) { 5650Sstevel@tonic-gate (void) printf(gettext("No file set descriptor found\n")); 5660Sstevel@tonic-gate return (0); 5670Sstevel@tonic-gate } 5680Sstevel@tonic-gate fileset = (struct file_set_desc *)malloc(filesetlen); 5690Sstevel@tonic-gate if (fileset == NULL) { 5700Sstevel@tonic-gate (void) printf(gettext("Unable to allocate fileset\n")); 5710Sstevel@tonic-gate return (0); 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate if (bread(fsreadfd, (char *)fileset, fsbtodb(filesetblock + part_start), 5740Sstevel@tonic-gate filesetlen) != 0) { 5750Sstevel@tonic-gate return (0); 5760Sstevel@tonic-gate } 5770Sstevel@tonic-gate err = verifytag(&fileset->fsd_tag, filesetblock, &fileset->fsd_tag, 5780Sstevel@tonic-gate UD_FILE_SET_DESC); 5790Sstevel@tonic-gate if (err) { 5800Sstevel@tonic-gate (void) printf(gettext("Fileset tag error, tag = %d, %s\n"), 5810Sstevel@tonic-gate fileset->fsd_tag.tag_id, tagerrs[err]); 5820Sstevel@tonic-gate return (0); 5830Sstevel@tonic-gate } 5840Sstevel@tonic-gate 5850Sstevel@tonic-gate /* Get the address of the root file entry */ 5860Sstevel@tonic-gate lap = (long_ad_t *)&fileset->fsd_root_icb; 5870Sstevel@tonic-gate rootblock = lap->lad_ext_loc; 5880Sstevel@tonic-gate rootlen = lap->lad_ext_len; 5890Sstevel@tonic-gate if (debug) 5900Sstevel@tonic-gate (void) printf("Root at %x for %d bytes\n", rootblock, rootlen); 5910Sstevel@tonic-gate 5920Sstevel@tonic-gate havesb = 1; 5930Sstevel@tonic-gate return (1); 5940Sstevel@tonic-gate } 5950Sstevel@tonic-gate 5960Sstevel@tonic-gate uint32_t 5970Sstevel@tonic-gate get_last_block() 5980Sstevel@tonic-gate { 5990Sstevel@tonic-gate struct vtoc vtoc; 6000Sstevel@tonic-gate struct dk_cinfo dki_info; 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate if (ioctl(fsreadfd, DKIOCGVTOC, (intptr_t)&vtoc) != 0) { 6030Sstevel@tonic-gate (void) fprintf(stderr, gettext("Unable to read VTOC\n")); 6040Sstevel@tonic-gate return (0); 6050Sstevel@tonic-gate } 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate if (vtoc.v_sanity != VTOC_SANE) { 6080Sstevel@tonic-gate (void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n")); 6090Sstevel@tonic-gate return (0); 6100Sstevel@tonic-gate } 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate if (ioctl(fsreadfd, DKIOCINFO, (intptr_t)&dki_info) != 0) { 6130Sstevel@tonic-gate (void) fprintf(stderr, 6140Sstevel@tonic-gate gettext("Could not get the slice information\n")); 6150Sstevel@tonic-gate return (0); 6160Sstevel@tonic-gate } 6170Sstevel@tonic-gate 6180Sstevel@tonic-gate if (dki_info.dki_partition > V_NUMPAR) { 6190Sstevel@tonic-gate (void) fprintf(stderr, 6200Sstevel@tonic-gate gettext("dki_info.dki_partition > V_NUMPAR\n")); 6210Sstevel@tonic-gate return (0); 6220Sstevel@tonic-gate } 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size); 6250Sstevel@tonic-gate } 626