17c478bd9Sstevel@tonic-gate /* 2*fe0e7ec4Smaheshvs * 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 #pragma ident "%Z%%M% %I% %E% SMI" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #define DKTYPENAMES 317c478bd9Sstevel@tonic-gate #include <stdio.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <fcntl.h> 357c478bd9Sstevel@tonic-gate #include <ustat.h> 367c478bd9Sstevel@tonic-gate #include <errno.h> 377c478bd9Sstevel@tonic-gate #include <sys/param.h> 387c478bd9Sstevel@tonic-gate #include <sys/types.h> 397c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 407c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 417c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 427c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 437c478bd9Sstevel@tonic-gate #include <sys/filio.h> 447c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> /* for ENDIAN defines */ 457c478bd9Sstevel@tonic-gate #include <sys/int_const.h> 467c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 477c478bd9Sstevel@tonic-gate #include <sys/stat.h> 487c478bd9Sstevel@tonic-gate #include <sys/file.h> 497c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 507c478bd9Sstevel@tonic-gate #include <string.h> 517c478bd9Sstevel@tonic-gate #include <sys/vfstab.h> 527c478bd9Sstevel@tonic-gate #include <sys/fs/udf_volume.h> 537c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 547c478bd9Sstevel@tonic-gate #include <locale.h> 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #include "fsck.h" 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate extern void errexit(char *, ...); 597c478bd9Sstevel@tonic-gate extern int32_t mounted(char *); 607c478bd9Sstevel@tonic-gate extern void pwarn(char *, ...); 617c478bd9Sstevel@tonic-gate extern void pfatal(char *, ...); 627c478bd9Sstevel@tonic-gate extern void printclean(); 637c478bd9Sstevel@tonic-gate extern void bufinit(); 647c478bd9Sstevel@tonic-gate extern void ckfini(); 657c478bd9Sstevel@tonic-gate extern int32_t bread(int32_t, char *, daddr_t, long); 667c478bd9Sstevel@tonic-gate extern int32_t reply(char *); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate static int32_t readvolseq(int32_t); 697c478bd9Sstevel@tonic-gate static uint32_t get_last_block(); 707c478bd9Sstevel@tonic-gate extern int32_t verifytag(struct tag *, uint32_t, struct tag *, int); 717c478bd9Sstevel@tonic-gate extern char *tagerrs[]; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate extern int mflag; 767c478bd9Sstevel@tonic-gate extern char hotroot; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate char avdbuf[MAXBSIZE]; /* buffer for anchor volume descriptor */ 797c478bd9Sstevel@tonic-gate char *main_vdbuf; /* buffer for entire main volume sequence */ 807c478bd9Sstevel@tonic-gate char *res_vdbuf; /* buffer for reserved volume sequence */ 817c478bd9Sstevel@tonic-gate int serialnum = -1; /* set from primary volume descriptor */ 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate char * 84*fe0e7ec4Smaheshvs setup(char *dev) 857c478bd9Sstevel@tonic-gate { 867c478bd9Sstevel@tonic-gate dev_t rootdev; 877c478bd9Sstevel@tonic-gate struct stat statb; 887c478bd9Sstevel@tonic-gate static char devstr[MAXPATHLEN]; 897c478bd9Sstevel@tonic-gate char *raw, *rawname(), *unrawname(); 907c478bd9Sstevel@tonic-gate struct ustat ustatb; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate havesb = 0; 937c478bd9Sstevel@tonic-gate if (stat("/", &statb) < 0) 947c478bd9Sstevel@tonic-gate errexit(gettext("Can't stat root\n")); 957c478bd9Sstevel@tonic-gate rootdev = statb.st_dev; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate devname = devstr; 987c478bd9Sstevel@tonic-gate (void) strncpy(devstr, dev, sizeof (devstr)); 997c478bd9Sstevel@tonic-gate restat: 1007c478bd9Sstevel@tonic-gate if (stat(devstr, &statb) < 0) { 1017c478bd9Sstevel@tonic-gate (void) printf(gettext("Can't stat %s\n"), devstr); 1027c478bd9Sstevel@tonic-gate exitstat = 34; 1037c478bd9Sstevel@tonic-gate return (0); 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate /* 1067c478bd9Sstevel@tonic-gate * A mount point is specified. But the mount point doesn't 1077c478bd9Sstevel@tonic-gate * match entries in the /etc/vfstab. 1087c478bd9Sstevel@tonic-gate * Search mnttab, because if the fs is error locked, it is 1097c478bd9Sstevel@tonic-gate * allowed to be fsck'd while mounted. 1107c478bd9Sstevel@tonic-gate */ 1117c478bd9Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == S_IFDIR) { 1127c478bd9Sstevel@tonic-gate (void) printf(gettext("%s is not a block or " 1137c478bd9Sstevel@tonic-gate "character device\n"), dev); 1147c478bd9Sstevel@tonic-gate return (0); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == S_IFBLK) { 1187c478bd9Sstevel@tonic-gate if (rootdev == statb.st_rdev) 1197c478bd9Sstevel@tonic-gate hotroot++; 1207c478bd9Sstevel@tonic-gate else if (ustat(statb.st_rdev, &ustatb) == 0) { 1217c478bd9Sstevel@tonic-gate (void) printf(gettext("%s is a mounted file system, " 1227c478bd9Sstevel@tonic-gate "ignored\n"), dev); 1237c478bd9Sstevel@tonic-gate exitstat = 33; 1247c478bd9Sstevel@tonic-gate return (0); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == S_IFDIR) { 1287c478bd9Sstevel@tonic-gate FILE *vfstab; 1297c478bd9Sstevel@tonic-gate struct vfstab vfsbuf; 1307c478bd9Sstevel@tonic-gate /* 1317c478bd9Sstevel@tonic-gate * Check vfstab for a mount point with this name 1327c478bd9Sstevel@tonic-gate */ 1337c478bd9Sstevel@tonic-gate if ((vfstab = fopen(VFSTAB, "r")) == NULL) { 1347c478bd9Sstevel@tonic-gate errexit(gettext("Can't open checklist file: %s\n"), 1357c478bd9Sstevel@tonic-gate VFSTAB); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate while (getvfsent(vfstab, &vfsbuf) == NULL) { 1387c478bd9Sstevel@tonic-gate if (strcmp(devstr, vfsbuf.vfs_mountp) == 0) { 1397c478bd9Sstevel@tonic-gate if (strcmp(vfsbuf.vfs_fstype, 1407c478bd9Sstevel@tonic-gate MNTTYPE_UDFS) != 0) { 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * found the entry but it is not a 1437c478bd9Sstevel@tonic-gate * udfs filesystem, don't check it 1447c478bd9Sstevel@tonic-gate */ 1457c478bd9Sstevel@tonic-gate (void) fclose(vfstab); 1467c478bd9Sstevel@tonic-gate return (0); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate (void) strcpy(devstr, vfsbuf.vfs_special); 1497c478bd9Sstevel@tonic-gate if (rflag) { 1507c478bd9Sstevel@tonic-gate raw = rawname( 1517c478bd9Sstevel@tonic-gate unrawname(vfsbuf.vfs_special)); 1527c478bd9Sstevel@tonic-gate (void) strcpy(devstr, raw); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate goto restat; 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate (void) fclose(vfstab); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate } else if (((statb.st_mode & S_IFMT) != S_IFBLK) && 1607c478bd9Sstevel@tonic-gate ((statb.st_mode & S_IFMT) != S_IFCHR)) { 1617c478bd9Sstevel@tonic-gate if (preen) 1627c478bd9Sstevel@tonic-gate pwarn(gettext("file is not a block or " 1637c478bd9Sstevel@tonic-gate "character device.\n")); 1647c478bd9Sstevel@tonic-gate else if (reply(gettext("file is not a block or " 1657c478bd9Sstevel@tonic-gate "character device; OK")) 1667c478bd9Sstevel@tonic-gate == 0) 1677c478bd9Sstevel@tonic-gate return (0); 1687c478bd9Sstevel@tonic-gate /* 1697c478bd9Sstevel@tonic-gate * To fsck regular files (fs images) 1707c478bd9Sstevel@tonic-gate * we need to clear the rflag since 1717c478bd9Sstevel@tonic-gate * regular files don't have raw names. --CW 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate rflag = 0; 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate if (mounted(devstr)) { 1777c478bd9Sstevel@tonic-gate if (rflag) 1787c478bd9Sstevel@tonic-gate mountedfs++; 1797c478bd9Sstevel@tonic-gate else { 1807c478bd9Sstevel@tonic-gate (void) printf(gettext("%s is mounted, fsck on BLOCK " 1817c478bd9Sstevel@tonic-gate "device ignored\n"), devstr); 1827c478bd9Sstevel@tonic-gate exit(33); 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate sync(); /* call sync, only when devstr's mounted */ 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate if (rflag) { 1877c478bd9Sstevel@tonic-gate char blockname[MAXPATHLEN]; 1887c478bd9Sstevel@tonic-gate /* 1897c478bd9Sstevel@tonic-gate * For root device check, must check 1907c478bd9Sstevel@tonic-gate * block devices. 1917c478bd9Sstevel@tonic-gate */ 1927c478bd9Sstevel@tonic-gate (void) strcpy(blockname, devstr); 1937c478bd9Sstevel@tonic-gate if (stat(unrawname(blockname), &statb) < 0) { 1947c478bd9Sstevel@tonic-gate (void) printf(gettext("Can't stat %s\n"), blockname); 1957c478bd9Sstevel@tonic-gate exitstat = 34; 1967c478bd9Sstevel@tonic-gate return (0); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate if (rootdev == statb.st_rdev) 2007c478bd9Sstevel@tonic-gate hotroot++; 2017c478bd9Sstevel@tonic-gate if ((fsreadfd = open(devstr, O_RDONLY)) < 0) { 2027c478bd9Sstevel@tonic-gate (void) printf(gettext("Can't open %s\n"), devstr); 2037c478bd9Sstevel@tonic-gate exitstat = 34; 2047c478bd9Sstevel@tonic-gate return (0); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate if (preen == 0 || debug != 0) 2077c478bd9Sstevel@tonic-gate (void) printf("** %s", devstr); 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (nflag || (fswritefd = open(devstr, O_WRONLY)) < 0) { 2107c478bd9Sstevel@tonic-gate fswritefd = -1; 2117c478bd9Sstevel@tonic-gate if (preen && !debug) 2127c478bd9Sstevel@tonic-gate pfatal(gettext("(NO WRITE ACCESS)\n")); 2137c478bd9Sstevel@tonic-gate (void) printf(gettext(" (NO WRITE)")); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate if (preen == 0) 2167c478bd9Sstevel@tonic-gate (void) printf("\n"); 2177c478bd9Sstevel@tonic-gate if (debug && (hotroot || mountedfs)) { 2187c478bd9Sstevel@tonic-gate (void) printf("** %s", devstr); 2197c478bd9Sstevel@tonic-gate if (hotroot) 2207c478bd9Sstevel@tonic-gate (void) printf(" is root fs%s", 2217c478bd9Sstevel@tonic-gate mountedfs? " and": ""); 2227c478bd9Sstevel@tonic-gate if (mountedfs) 2237c478bd9Sstevel@tonic-gate (void) printf(" is mounted"); 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate (void) printf(".\n"); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate fsmodified = 0; 2287c478bd9Sstevel@tonic-gate if (readvolseq(1) == 0) 2297c478bd9Sstevel@tonic-gate return (0); 2307c478bd9Sstevel@tonic-gate if (fflag == 0 && preen && 2317c478bd9Sstevel@tonic-gate lvintp->lvid_int_type == LVI_CLOSE) { 2327c478bd9Sstevel@tonic-gate iscorrupt = 0; 2337c478bd9Sstevel@tonic-gate printclean(); 2347c478bd9Sstevel@tonic-gate return (0); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate listmax = FEGROW; 2377c478bd9Sstevel@tonic-gate inphash = (struct fileinfo **)calloc(FEGROW, 2387c478bd9Sstevel@tonic-gate sizeof (struct fileinfo *)); 2397c478bd9Sstevel@tonic-gate inphead = (struct fileinfo *)calloc(FEGROW + 1, 2407c478bd9Sstevel@tonic-gate sizeof (struct fileinfo)); 2417c478bd9Sstevel@tonic-gate if (inphead == NULL || inphash == NULL) { 2427c478bd9Sstevel@tonic-gate (void) printf(gettext("cannot alloc %ld bytes for inphead\n"), 2437c478bd9Sstevel@tonic-gate listmax * sizeof (struct fileinfo)); 2447c478bd9Sstevel@tonic-gate goto badsb; 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate inpnext = inphead; 2477c478bd9Sstevel@tonic-gate inplast = &inphead[listmax]; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate bufinit(); 2507c478bd9Sstevel@tonic-gate return (devstr); 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate badsb: 2537c478bd9Sstevel@tonic-gate ckfini(); 2547c478bd9Sstevel@tonic-gate exitstat = 39; 2557c478bd9Sstevel@tonic-gate return (0); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 258*fe0e7ec4Smaheshvs static int 2597c478bd9Sstevel@tonic-gate check_pri_vol_desc(struct tag *tp) 2607c478bd9Sstevel@tonic-gate { 2617c478bd9Sstevel@tonic-gate pvolp = (struct pri_vol_desc *)tp; 2627c478bd9Sstevel@tonic-gate return (0); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate 265*fe0e7ec4Smaheshvs static int 2667c478bd9Sstevel@tonic-gate check_avdp(struct tag *tp) 2677c478bd9Sstevel@tonic-gate { 2687c478bd9Sstevel@tonic-gate avdp = (struct anch_vol_desc_ptr *)tp; 2697c478bd9Sstevel@tonic-gate return (0); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 272*fe0e7ec4Smaheshvs static int 2737c478bd9Sstevel@tonic-gate check_vdp(struct tag *tp) 2747c478bd9Sstevel@tonic-gate { 2757c478bd9Sstevel@tonic-gate volp = (struct vdp_desc *)tp; 2767c478bd9Sstevel@tonic-gate return (0); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 279*fe0e7ec4Smaheshvs static int 2807c478bd9Sstevel@tonic-gate check_iuvd(struct tag *tp) 2817c478bd9Sstevel@tonic-gate { 2827c478bd9Sstevel@tonic-gate iudp = (struct iuvd_desc *)tp; 2837c478bd9Sstevel@tonic-gate return (0); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 286*fe0e7ec4Smaheshvs static int 2877c478bd9Sstevel@tonic-gate check_part_desc(struct tag *tp) 2887c478bd9Sstevel@tonic-gate { 2897c478bd9Sstevel@tonic-gate partp = (struct part_desc *)tp; 2907c478bd9Sstevel@tonic-gate /* LINTED */ 2917c478bd9Sstevel@tonic-gate pheadp = (struct phdr_desc *)&partp->pd_pc_use; 2927c478bd9Sstevel@tonic-gate part_start = partp->pd_part_start; 2937c478bd9Sstevel@tonic-gate part_len = partp->pd_part_length; 2947c478bd9Sstevel@tonic-gate if (debug) 2957c478bd9Sstevel@tonic-gate (void) printf("partition start %x len %x\n", part_start, 2967c478bd9Sstevel@tonic-gate part_len); 2977c478bd9Sstevel@tonic-gate return (0); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 300*fe0e7ec4Smaheshvs static int 3017c478bd9Sstevel@tonic-gate check_log_desc(struct tag *tp) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate logvp = (struct log_vol_desc *)tp; 3047c478bd9Sstevel@tonic-gate return (0); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 307*fe0e7ec4Smaheshvs static int 3087c478bd9Sstevel@tonic-gate check_unall_desc(struct tag *tp) 3097c478bd9Sstevel@tonic-gate { 3107c478bd9Sstevel@tonic-gate unallp = (struct unall_desc *)tp; 3117c478bd9Sstevel@tonic-gate return (0); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* ARGSUSED */ 315*fe0e7ec4Smaheshvs static int 3167c478bd9Sstevel@tonic-gate check_term_desc(struct tag *tp) 3177c478bd9Sstevel@tonic-gate { 3187c478bd9Sstevel@tonic-gate return (0); 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 321*fe0e7ec4Smaheshvs static int 3227c478bd9Sstevel@tonic-gate check_lvint(struct tag *tp) 3237c478bd9Sstevel@tonic-gate { 3247c478bd9Sstevel@tonic-gate /* LINTED */ 3257c478bd9Sstevel@tonic-gate lvintp = (struct log_vol_int_desc *)tp; 3267c478bd9Sstevel@tonic-gate return (0); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate void 3307c478bd9Sstevel@tonic-gate dump16(char *cp, char *nl) 3317c478bd9Sstevel@tonic-gate { 3327c478bd9Sstevel@tonic-gate int i; 3337c478bd9Sstevel@tonic-gate long *ptr; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i += 4) { 3377c478bd9Sstevel@tonic-gate /* LINTED */ 3387c478bd9Sstevel@tonic-gate ptr = (long *)(cp + i); 3397c478bd9Sstevel@tonic-gate (void) printf("%08lx ", *ptr); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate (void) printf(nl); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate /* 3457c478bd9Sstevel@tonic-gate * Read in the super block and its summary info. 3467c478bd9Sstevel@tonic-gate */ 3477c478bd9Sstevel@tonic-gate /* ARGSUSED */ 348*fe0e7ec4Smaheshvs static int 3497c478bd9Sstevel@tonic-gate readvolseq(int32_t listerr) 3507c478bd9Sstevel@tonic-gate { 3517c478bd9Sstevel@tonic-gate struct tag *tp; 3527c478bd9Sstevel@tonic-gate long_ad_t *lap; 3537c478bd9Sstevel@tonic-gate struct anch_vol_desc_ptr *avp; 3547c478bd9Sstevel@tonic-gate uint8_t *cp, *end; 3557c478bd9Sstevel@tonic-gate daddr_t nextblock; 3567c478bd9Sstevel@tonic-gate int err; 3577c478bd9Sstevel@tonic-gate long freelen; 3587c478bd9Sstevel@tonic-gate daddr_t avdp; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate disk_size = get_last_block(); 3617c478bd9Sstevel@tonic-gate if (debug) 3627c478bd9Sstevel@tonic-gate (void) printf("Disk partition size: %x\n", disk_size); 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate /* LINTED */ 3657c478bd9Sstevel@tonic-gate avp = (struct anch_vol_desc_ptr *)avdbuf; 3667c478bd9Sstevel@tonic-gate tp = &avp->avd_tag; 3677c478bd9Sstevel@tonic-gate for (fsbsize = 512; fsbsize <= MAXBSIZE; fsbsize <<= 1) { 3687c478bd9Sstevel@tonic-gate avdp = FIRSTAVDP * fsbsize / DEV_BSIZE; 3697c478bd9Sstevel@tonic-gate if (bread(fsreadfd, avdbuf, avdp, fsbsize) != 0) 3707c478bd9Sstevel@tonic-gate return (0); 3717c478bd9Sstevel@tonic-gate err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC); 3727c478bd9Sstevel@tonic-gate if (debug) 3737c478bd9Sstevel@tonic-gate (void) printf("bsize %ld tp->tag %d, %s\n", fsbsize, 3747c478bd9Sstevel@tonic-gate tp->tag_id, tagerrs[err]); 3757c478bd9Sstevel@tonic-gate if (err == 0) 3767c478bd9Sstevel@tonic-gate break; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate if (fsbsize > MAXBSIZE) 3797c478bd9Sstevel@tonic-gate errexit(gettext("Can't find anchor volume descriptor\n")); 3807c478bd9Sstevel@tonic-gate secsize = fsbsize; 3817c478bd9Sstevel@tonic-gate if (debug) 3827c478bd9Sstevel@tonic-gate (void) printf("fsbsize = %ld\n", fsbsize); 3837c478bd9Sstevel@tonic-gate main_vdbuf = malloc(avp->avd_main_vdse.ext_len); 3847c478bd9Sstevel@tonic-gate res_vdbuf = malloc(avp->avd_res_vdse.ext_len); 3857c478bd9Sstevel@tonic-gate if (main_vdbuf == NULL || res_vdbuf == NULL) 3867c478bd9Sstevel@tonic-gate errexit("cannot allocate space for volume sequences\n"); 3877c478bd9Sstevel@tonic-gate if (debug) 3887c478bd9Sstevel@tonic-gate (void) printf("reading volume sequences " 3897c478bd9Sstevel@tonic-gate "(%d bytes at %x and %x)\n", 3907c478bd9Sstevel@tonic-gate avp->avd_main_vdse.ext_len, avp->avd_main_vdse.ext_loc, 3917c478bd9Sstevel@tonic-gate avp->avd_res_vdse.ext_loc); 3927c478bd9Sstevel@tonic-gate if (bread(fsreadfd, main_vdbuf, fsbtodb(avp->avd_main_vdse.ext_loc), 3937c478bd9Sstevel@tonic-gate avp->avd_main_vdse.ext_len) != 0) 3947c478bd9Sstevel@tonic-gate return (0); 3957c478bd9Sstevel@tonic-gate if (bread(fsreadfd, res_vdbuf, fsbtodb(avp->avd_res_vdse.ext_loc), 3967c478bd9Sstevel@tonic-gate avp->avd_res_vdse.ext_len) != 0) 3977c478bd9Sstevel@tonic-gate return (0); 3987c478bd9Sstevel@tonic-gate end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len; 3997c478bd9Sstevel@tonic-gate nextblock = avp->avd_main_vdse.ext_loc; 4007c478bd9Sstevel@tonic-gate for (cp = (uint8_t *)main_vdbuf; cp < end; cp += fsbsize, nextblock++) { 4017c478bd9Sstevel@tonic-gate /* LINTED */ 4027c478bd9Sstevel@tonic-gate tp = (struct tag *)cp; 4037c478bd9Sstevel@tonic-gate err = verifytag(tp, nextblock, tp, 0); 4047c478bd9Sstevel@tonic-gate if (debug) { 4057c478bd9Sstevel@tonic-gate dump16((char *)cp, ""); 4067c478bd9Sstevel@tonic-gate (void) printf("blk %lx err %s tag %d\n", nextblock, 4077c478bd9Sstevel@tonic-gate tagerrs[err], tp->tag_id); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate if (err == 0) { 4107c478bd9Sstevel@tonic-gate if (serialnum >= 0 && tp->tag_sno != serialnum) { 4117c478bd9Sstevel@tonic-gate (void) printf(gettext("serial number mismatch " 4127c478bd9Sstevel@tonic-gate "tag type %d, block %lx\n"), tp->tag_id, 4137c478bd9Sstevel@tonic-gate nextblock); 4147c478bd9Sstevel@tonic-gate continue; 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate switch (tp->tag_id) { 4177c478bd9Sstevel@tonic-gate case UD_PRI_VOL_DESC: 4187c478bd9Sstevel@tonic-gate serialnum = tp->tag_sno; 4197c478bd9Sstevel@tonic-gate if (debug) { 4207c478bd9Sstevel@tonic-gate (void) printf("serial number = %d\n", 4217c478bd9Sstevel@tonic-gate serialnum); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate err = check_pri_vol_desc(tp); 4247c478bd9Sstevel@tonic-gate break; 4257c478bd9Sstevel@tonic-gate case UD_ANCH_VOL_DESC: 4267c478bd9Sstevel@tonic-gate err = check_avdp(tp); 4277c478bd9Sstevel@tonic-gate break; 4287c478bd9Sstevel@tonic-gate case UD_VOL_DESC_PTR: 4297c478bd9Sstevel@tonic-gate err = check_vdp(tp); 4307c478bd9Sstevel@tonic-gate break; 4317c478bd9Sstevel@tonic-gate case UD_IMPL_USE_DESC: 4327c478bd9Sstevel@tonic-gate err = check_iuvd(tp); 4337c478bd9Sstevel@tonic-gate break; 4347c478bd9Sstevel@tonic-gate case UD_PART_DESC: 4357c478bd9Sstevel@tonic-gate err = check_part_desc(tp); 4367c478bd9Sstevel@tonic-gate break; 4377c478bd9Sstevel@tonic-gate case UD_LOG_VOL_DESC: 4387c478bd9Sstevel@tonic-gate err = check_log_desc(tp); 4397c478bd9Sstevel@tonic-gate break; 4407c478bd9Sstevel@tonic-gate case UD_UNALL_SPA_DESC: 4417c478bd9Sstevel@tonic-gate err = check_unall_desc(tp); 4427c478bd9Sstevel@tonic-gate break; 4437c478bd9Sstevel@tonic-gate case UD_TERM_DESC: 4447c478bd9Sstevel@tonic-gate err = check_term_desc(tp); 4457c478bd9Sstevel@tonic-gate goto done; 4467c478bd9Sstevel@tonic-gate break; 4477c478bd9Sstevel@tonic-gate case UD_LOG_VOL_INT: 4487c478bd9Sstevel@tonic-gate err = check_lvint(tp); 4497c478bd9Sstevel@tonic-gate break; 4507c478bd9Sstevel@tonic-gate default: 4517c478bd9Sstevel@tonic-gate (void) printf(gettext("Invalid volume " 4527c478bd9Sstevel@tonic-gate "sequence tag %d\n"), tp->tag_id); 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate } else { 4557c478bd9Sstevel@tonic-gate (void) printf(gettext("Volume sequence tag error %s\n"), 4567c478bd9Sstevel@tonic-gate tagerrs[err]); 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate done: 4607c478bd9Sstevel@tonic-gate if (!partp || !logvp) { 4617c478bd9Sstevel@tonic-gate (void) printf(gettext("Missing partition header or" 4627c478bd9Sstevel@tonic-gate " logical volume descriptor\n")); 4637c478bd9Sstevel@tonic-gate return (0); 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate /* Get the logical volume integrity descriptor */ 4677c478bd9Sstevel@tonic-gate lvintblock = logvp->lvd_int_seq_ext.ext_loc; 4687c478bd9Sstevel@tonic-gate lvintlen = logvp->lvd_int_seq_ext.ext_len; 4697c478bd9Sstevel@tonic-gate lvintp = (struct log_vol_int_desc *)malloc(lvintlen); 4707c478bd9Sstevel@tonic-gate if (debug) 4717c478bd9Sstevel@tonic-gate (void) printf("Logvolint at %x for %d bytes\n", lvintblock, 4727c478bd9Sstevel@tonic-gate lvintlen); 4737c478bd9Sstevel@tonic-gate if (lvintp == NULL) { 4747c478bd9Sstevel@tonic-gate (void) printf(gettext("Can't allocate space for logical" 4757c478bd9Sstevel@tonic-gate " volume integrity sequence\n")); 4767c478bd9Sstevel@tonic-gate return (0); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate if (bread(fsreadfd, (char *)lvintp, 4797c478bd9Sstevel@tonic-gate fsbtodb(lvintblock), lvintlen) != 0) { 4807c478bd9Sstevel@tonic-gate return (0); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate err = verifytag(&lvintp->lvid_tag, lvintblock, &lvintp->lvid_tag, 4837c478bd9Sstevel@tonic-gate UD_LOG_VOL_INT); 4847c478bd9Sstevel@tonic-gate if (debug) { 4857c478bd9Sstevel@tonic-gate dump16((char *)lvintp, "\n"); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate if (err) { 4887c478bd9Sstevel@tonic-gate (void) printf(gettext("Log_vol_int tag error: %s, tag = %d\n"), 4897c478bd9Sstevel@tonic-gate tagerrs[err], lvintp->lvid_tag.tag_id); 4907c478bd9Sstevel@tonic-gate return (0); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* Get pointer to implementation use area */ 4947c478bd9Sstevel@tonic-gate lviup = (struct lvid_iu *)&lvintp->lvid_fst[lvintp->lvid_npart*2]; 4957c478bd9Sstevel@tonic-gate if (debug) { 4967c478bd9Sstevel@tonic-gate (void) printf("free space %d total %d ", lvintp->lvid_fst[0], 4977c478bd9Sstevel@tonic-gate lvintp->lvid_fst[1]); 4987c478bd9Sstevel@tonic-gate (void) printf(gettext("nfiles %d ndirs %d\n"), lviup->lvidiu_nfiles, 4997c478bd9Sstevel@tonic-gate lviup->lvidiu_ndirs); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* Set up free block map and read in the existing free space map */ 5037c478bd9Sstevel@tonic-gate freelen = pheadp->phdr_usb.sad_ext_len; 5047c478bd9Sstevel@tonic-gate if (freelen == 0) { 5057c478bd9Sstevel@tonic-gate (void) printf(gettext("No partition free map\n")); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate part_bmp_bytes = (part_len + NBBY - 1) / NBBY; 5087c478bd9Sstevel@tonic-gate busymap = calloc((unsigned)part_bmp_bytes, sizeof (char)); 5097c478bd9Sstevel@tonic-gate if (busymap == NULL) { 5107c478bd9Sstevel@tonic-gate (void) printf(gettext("Can't allocate free block bitmap\n")); 5117c478bd9Sstevel@tonic-gate return (0); 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate if (freelen) { 5147c478bd9Sstevel@tonic-gate part_bmp_sectors = 5157c478bd9Sstevel@tonic-gate (part_bmp_bytes + SPACEMAP_OFF + secsize - 1) / 5167c478bd9Sstevel@tonic-gate secsize; 5177c478bd9Sstevel@tonic-gate part_bmp_loc = pheadp->phdr_usb.sad_ext_loc + part_start; 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate /* Mark the partition map blocks busy */ 5207c478bd9Sstevel@tonic-gate markbusy(pheadp->phdr_usb.sad_ext_loc, 5217c478bd9Sstevel@tonic-gate part_bmp_sectors * secsize); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate spacep = (struct space_bmap_desc *) 5247c478bd9Sstevel@tonic-gate malloc(secsize*part_bmp_sectors); 5257c478bd9Sstevel@tonic-gate if (spacep == NULL) { 5267c478bd9Sstevel@tonic-gate (void) printf(gettext("Can't allocate partition " 5277c478bd9Sstevel@tonic-gate "map\n")); 5287c478bd9Sstevel@tonic-gate return (0); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate if (bread(fsreadfd, (char *)spacep, fsbtodb(part_bmp_loc), 5317c478bd9Sstevel@tonic-gate part_bmp_sectors * secsize) != 0) 5327c478bd9Sstevel@tonic-gate return (0); 5337c478bd9Sstevel@tonic-gate cp = (uint8_t *)spacep; 5347c478bd9Sstevel@tonic-gate err = verifytag(&spacep->sbd_tag, pheadp->phdr_usb.sad_ext_loc, 5357c478bd9Sstevel@tonic-gate &spacep->sbd_tag, UD_SPA_BMAP_DESC); 5367c478bd9Sstevel@tonic-gate if (debug) { 5377c478bd9Sstevel@tonic-gate dump16((char *)cp, ""); 5387c478bd9Sstevel@tonic-gate (void) printf("blk %x err %s tag %d\n", part_bmp_loc, 5397c478bd9Sstevel@tonic-gate tagerrs[err], spacep->sbd_tag.tag_id); 5407c478bd9Sstevel@tonic-gate } 5417c478bd9Sstevel@tonic-gate freemap = (char *)cp + SPACEMAP_OFF; 5427c478bd9Sstevel@tonic-gate if (debug) 5437c478bd9Sstevel@tonic-gate (void) printf("err %s tag %x space bitmap at %x" 5447c478bd9Sstevel@tonic-gate " length %d nbits %d nbytes %d\n", 5457c478bd9Sstevel@tonic-gate tagerrs[err], spacep->sbd_tag.tag_id, 5467c478bd9Sstevel@tonic-gate part_bmp_loc, part_bmp_sectors, 5477c478bd9Sstevel@tonic-gate spacep->sbd_nbits, spacep->sbd_nbytes); 5487c478bd9Sstevel@tonic-gate if (err) { 5497c478bd9Sstevel@tonic-gate (void) printf(gettext("Space bitmap tag error, %s, " 5507c478bd9Sstevel@tonic-gate "tag = %d\n"), 5517c478bd9Sstevel@tonic-gate tagerrs[err], spacep->sbd_tag.tag_id); 5527c478bd9Sstevel@tonic-gate return (0); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate /* Get the fileset descriptor */ 5577c478bd9Sstevel@tonic-gate lap = (long_ad_t *)&logvp->lvd_lvcu; 5587c478bd9Sstevel@tonic-gate filesetblock = lap->lad_ext_loc; 5597c478bd9Sstevel@tonic-gate filesetlen = lap->lad_ext_len; 5607c478bd9Sstevel@tonic-gate markbusy(filesetblock, filesetlen); 5617c478bd9Sstevel@tonic-gate if (debug) 5627c478bd9Sstevel@tonic-gate (void) printf("Fileset descriptor at %x for %d bytes\n", 5637c478bd9Sstevel@tonic-gate filesetblock, filesetlen); 5647c478bd9Sstevel@tonic-gate if (!filesetlen) { 5657c478bd9Sstevel@tonic-gate (void) printf(gettext("No file set descriptor found\n")); 5667c478bd9Sstevel@tonic-gate return (0); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate fileset = (struct file_set_desc *)malloc(filesetlen); 5697c478bd9Sstevel@tonic-gate if (fileset == NULL) { 5707c478bd9Sstevel@tonic-gate (void) printf(gettext("Unable to allocate fileset\n")); 5717c478bd9Sstevel@tonic-gate return (0); 5727c478bd9Sstevel@tonic-gate } 5737c478bd9Sstevel@tonic-gate if (bread(fsreadfd, (char *)fileset, fsbtodb(filesetblock + part_start), 5747c478bd9Sstevel@tonic-gate filesetlen) != 0) { 5757c478bd9Sstevel@tonic-gate return (0); 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate err = verifytag(&fileset->fsd_tag, filesetblock, &fileset->fsd_tag, 5787c478bd9Sstevel@tonic-gate UD_FILE_SET_DESC); 5797c478bd9Sstevel@tonic-gate if (err) { 5807c478bd9Sstevel@tonic-gate (void) printf(gettext("Fileset tag error, tag = %d, %s\n"), 5817c478bd9Sstevel@tonic-gate fileset->fsd_tag.tag_id, tagerrs[err]); 5827c478bd9Sstevel@tonic-gate return (0); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate /* Get the address of the root file entry */ 5867c478bd9Sstevel@tonic-gate lap = (long_ad_t *)&fileset->fsd_root_icb; 5877c478bd9Sstevel@tonic-gate rootblock = lap->lad_ext_loc; 5887c478bd9Sstevel@tonic-gate rootlen = lap->lad_ext_len; 5897c478bd9Sstevel@tonic-gate if (debug) 5907c478bd9Sstevel@tonic-gate (void) printf("Root at %x for %d bytes\n", rootblock, rootlen); 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate havesb = 1; 5937c478bd9Sstevel@tonic-gate return (1); 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate uint32_t 5977c478bd9Sstevel@tonic-gate get_last_block() 5987c478bd9Sstevel@tonic-gate { 5997c478bd9Sstevel@tonic-gate struct vtoc vtoc; 6007c478bd9Sstevel@tonic-gate struct dk_cinfo dki_info; 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate if (ioctl(fsreadfd, DKIOCGVTOC, (intptr_t)&vtoc) != 0) { 6037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Unable to read VTOC\n")); 6047c478bd9Sstevel@tonic-gate return (0); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate if (vtoc.v_sanity != VTOC_SANE) { 6087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n")); 6097c478bd9Sstevel@tonic-gate return (0); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate if (ioctl(fsreadfd, DKIOCINFO, (intptr_t)&dki_info) != 0) { 6137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6147c478bd9Sstevel@tonic-gate gettext("Could not get the slice information\n")); 6157c478bd9Sstevel@tonic-gate return (0); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate if (dki_info.dki_partition > V_NUMPAR) { 6197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6207c478bd9Sstevel@tonic-gate gettext("dki_info.dki_partition > V_NUMPAR\n")); 6217c478bd9Sstevel@tonic-gate return (0); 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size); 6257c478bd9Sstevel@tonic-gate } 626