1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * fsirand 39 */ 40 41 #include <fcntl.h> 42 #include <stdio.h> 43 #include <errno.h> 44 #include <sys/param.h> 45 #include <sys/types.h> 46 #include <sys/time.h> 47 #include <sys/fs/ufs_fs.h> 48 #include <sys/vnode.h> 49 #include <sys/fs/ufs_inode.h> 50 51 extern offset_t llseek(); 52 53 extern long lrand48(); 54 extern void srand48(); 55 56 char fsbuf[SBSIZE]; 57 struct dinode dibuf[8192/sizeof (struct dinode)]; 58 59 static char *strerror(/*int errnum*/); 60 61 void 62 main(argc, argv) 63 int argc; 64 char *argv[]; 65 { 66 struct fs *fs; 67 int fd; 68 char *dev; 69 int bno; 70 struct dinode *dip; 71 int inum, imax; 72 int i, n; 73 offset_t seekaddr; 74 int bsize; 75 int pflag = 0; 76 struct timeval timeval; 77 78 argv++; 79 argc--; 80 if (argc > 0 && strcmp(*argv, "-p") == 0) { 81 pflag++; 82 argv++; 83 argc--; 84 } 85 if (argc <= 0) { 86 (void) fprintf(stderr, "Usage: fsirand [-p] special\n"); 87 exit(1); 88 } 89 dev = *argv; 90 fd = open64(dev, pflag ? O_RDONLY : O_RDWR); 91 if (fd == -1) { 92 (void) fprintf(stderr, "fsirand: Cannot open %s: %s\n", dev, 93 strerror(errno)); 94 exit(1); 95 } 96 if (llseek(fd, (offset_t)SBLOCK * DEV_BSIZE, 0) == -1) { 97 (void) fprintf(stderr, 98 "fsirand: Seek to superblock failed: %s\n", 99 strerror(errno)); 100 exit(1); 101 } 102 fs = (struct fs *)fsbuf; 103 if ((n = read(fd, (char *)fs, SBSIZE)) != SBSIZE) { 104 (void) fprintf(stderr, 105 "fsirand: Read of superblock failed: %s\n", 106 n == -1 ? strerror(errno) : "Short read"); 107 exit(1); 108 } 109 if ((fs->fs_magic != FS_MAGIC) && 110 (fs->fs_magic != MTB_UFS_MAGIC)) { 111 (void) fprintf(stderr, 112 "fsirand: Not a file system (bad magic number in superblock)\n"); 113 exit(1); 114 } 115 if (fs->fs_magic == MTB_UFS_MAGIC && 116 (fs->fs_version > MTB_UFS_VERSION_1 || 117 fs->fs_version < MTB_UFS_VERSION_MIN)) { 118 (void) fprintf(stderr, 119 "fsirand: Unrecognized UFS format version number %d (in superblock)\n", 120 fs->fs_version); 121 exit(1); 122 } 123 if (pflag) { 124 (void) printf("fsid: %x %x\n", fs->fs_id[0], fs->fs_id[1]); 125 } else { 126 n = getpid(); 127 (void) gettimeofday(&timeval, (struct timezone *)NULL); 128 srand48((long)(timeval.tv_sec + timeval.tv_usec + n)); 129 } 130 bsize = INOPB(fs) * sizeof (struct dinode); 131 inum = 0; 132 imax = fs->fs_ipg * fs->fs_ncg; 133 while (inum < imax) { 134 bno = itod(fs, inum); 135 seekaddr = (offset_t)fsbtodb(fs, bno) * DEV_BSIZE; 136 if (llseek(fd, seekaddr, 0) == -1) { 137 (void) fprintf(stderr, 138 "fsirand: Seek to %ld %ld failed: %s\n", 139 ((off_t *)&seekaddr)[0], ((off_t *)&seekaddr)[1], 140 strerror(errno)); 141 exit(1); 142 } 143 n = read(fd, (char *)dibuf, bsize); 144 if (n != bsize) { 145 (void) fprintf(stderr, 146 "fsirand: Read of ilist block failed: %s\n", 147 n == -1 ? strerror(errno) : "Short read"); 148 exit(1); 149 } 150 for (dip = dibuf; dip < &dibuf[INOPB(fs)]; dip++) { 151 if (pflag) { 152 (void) printf("ino %d gen %x\n", inum, 153 dip->di_gen); 154 } else { 155 dip->di_gen = lrand48(); 156 } 157 inum++; 158 } 159 if (!pflag) { 160 if (llseek(fd, seekaddr, 0) == -1) { 161 (void) fprintf(stderr, 162 "fsirand: Seek to %ld %ld failed: %s\n", 163 ((off_t *)&seekaddr)[0], 164 ((off_t *)&seekaddr)[1], 165 seekaddr, strerror(errno)); 166 exit(1); 167 } 168 n = write(fd, (char *)dibuf, bsize); 169 if (n != bsize) { 170 (void) fprintf(stderr, 171 "fsirand: Write of ilist block failed: %s\n", 172 n == -1 ? strerror(errno) : "Short write"); 173 exit(1); 174 } 175 } 176 } 177 if (!pflag) { 178 (void) gettimeofday(&timeval, (struct timezone *)NULL); 179 fs->fs_id[0] = timeval.tv_sec; 180 fs->fs_id[1] = timeval.tv_usec + getpid(); 181 if (llseek(fd, (offset_t)SBLOCK * DEV_BSIZE, 0) == -1) { 182 (void) fprintf(stderr, 183 "fsirand: Seek to superblock failed: %s\n", 184 strerror(errno)); 185 exit(1); 186 } 187 if ((n = write(fd, (char *)fs, SBSIZE)) != SBSIZE) { 188 (void) fprintf(stderr, 189 "fsirand: Write of superblock failed: %s\n", 190 n == -1 ? strerror(errno) : "Short write"); 191 exit(1); 192 } 193 } 194 for (i = 0; i < fs->fs_ncg; i++) { 195 seekaddr = (offset_t)fsbtodb(fs, cgsblock(fs, i)) * DEV_BSIZE; 196 if (llseek(fd, seekaddr, 0) == -1) { 197 (void) fprintf(stderr, 198 "fsirand: Seek to alternate superblock failed: %s\n", 199 strerror(errno)); 200 exit(1); 201 } 202 if (pflag) { 203 if ((n = read(fd, (char *)fs, SBSIZE)) != SBSIZE) { 204 (void) fprintf(stderr, 205 "fsirand: Read of alternate superblock failed: %s\n", 206 n == -1 ? strerror(errno) : "Short read"); 207 exit(1); 208 } 209 if ((fs->fs_magic != FS_MAGIC) && 210 (fs->fs_magic != MTB_UFS_MAGIC)) { 211 (void) fprintf(stderr, 212 "fsirand: Not a valid file system (bad " 213 "magic number in alternate superblock)\n"); 214 exit(1); 215 } 216 } else { 217 if ((n = write(fd, (char *)fs, SBSIZE)) != SBSIZE) { 218 (void) fprintf(stderr, 219 "fsirand: Write of alternate superblock failed: %s\n", 220 n == -1 ? strerror(errno) : "Short write"); 221 exit(1); 222 } 223 } 224 } 225 exit(0); 226 /* NOTREACHED */ 227 } 228 229 static char * 230 strerror(errnum) 231 int errnum; 232 { 233 extern int sys_nerr; 234 extern char *sys_errlist[]; 235 static char unknown_error[16+1]; /* "Error NNNNNNNNNN" + '\0' */ 236 237 if (errnum < 0 || errnum > sys_nerr) { 238 (void) sprintf(unknown_error, "Error %d", errnum); 239 return (unknown_error); 240 } else 241 return (sys_errlist[errnum]); 242 } 243