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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * University Copyright- Copyright (c) 1982, 1986, 1988 31 * The Regents of the University of California 32 * All Rights Reserved 33 * 34 * University Acknowledgment- Portions of this document are derived from 35 * software developed by the University of California, Berkeley, and its 36 * contributors. 37 */ 38 39 /* 40 * libfstyp module for ufs 41 */ 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <unistd.h> 45 #include <locale.h> 46 #include <fcntl.h> 47 #include <errno.h> 48 #include <strings.h> 49 50 #include <sys/param.h> 51 #include <sys/types.h> 52 #include <sys/mntent.h> 53 #include <sys/errno.h> 54 #include <sys/fs/ufs_fs.h> 55 #include <sys/stat.h> 56 #include <sys/vfs.h> 57 #include <sys/mnttab.h> 58 59 #include <sys/fs/ufs_log.h> 60 #include <sys/inttypes.h> 61 62 #include <libfstyp_module.h> 63 64 typedef struct fstyp_ufs { 65 int fd; 66 nvlist_t *attr; 67 68 union { 69 struct fs fs; 70 char pad[MAXBSIZE]; 71 } fsun; 72 73 union { 74 struct cg cg; 75 char pad[MAXBSIZE]; 76 } cgun; 77 78 char eg[MAXBSIZE]; 79 } fstyp_ufs_t; 80 81 #define afs fsun.fs 82 #define acg cgun.cg 83 84 #define MAXLABELS 20 85 #define LINEMAX 256 86 #define NRPOS 8 /* for pre FFFS compatibility */ 87 88 static int is_ufs(fstyp_ufs_t *h); 89 static int get_attr(fstyp_ufs_t *h); 90 static int dumpfs(fstyp_ufs_t *h, FILE *fout, FILE *ferr); 91 static void dumplog(fstyp_ufs_t *h, FILE *fout, FILE *ferr); 92 static void dumpcg(fstyp_ufs_t *h, FILE *fout, FILE *ferr, const int c); 93 static void pbits(FILE *out, const void *cp, const int max); 94 95 int fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle); 96 void fstyp_mod_fini(fstyp_mod_handle_t handle); 97 int fstyp_mod_ident(fstyp_mod_handle_t handle); 98 int fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp); 99 int fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr); 100 101 102 int 103 fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle) 104 { 105 struct fstyp_ufs *h; 106 107 if (offset != 0) { 108 return (FSTYP_ERR_OFFSET); 109 } 110 111 if ((h = calloc(1, sizeof (struct fstyp_ufs))) == NULL) { 112 return (FSTYP_ERR_NOMEM); 113 } 114 h->fd = fd; 115 116 *handle = (fstyp_mod_handle_t)h; 117 return (0); 118 } 119 120 void 121 fstyp_mod_fini(fstyp_mod_handle_t handle) 122 { 123 struct fstyp_ufs *h = (struct fstyp_ufs *)handle; 124 125 if (h->attr == NULL) { 126 nvlist_free(h->attr); 127 h->attr = NULL; 128 } 129 free(h); 130 } 131 132 int 133 fstyp_mod_ident(fstyp_mod_handle_t handle) 134 { 135 struct fstyp_ufs *h = (struct fstyp_ufs *)handle; 136 137 return (is_ufs(h)); 138 } 139 140 int 141 fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp) 142 { 143 struct fstyp_ufs *h = (struct fstyp_ufs *)handle; 144 int error; 145 146 if (h->attr == NULL) { 147 if (nvlist_alloc(&h->attr, NV_UNIQUE_NAME_TYPE, 0)) { 148 return (FSTYP_ERR_NOMEM); 149 } 150 if ((error = get_attr(h)) != 0) { 151 nvlist_free(h->attr); 152 h->attr = NULL; 153 return (error); 154 } 155 } 156 157 *attrp = h->attr; 158 return (0); 159 } 160 161 int 162 fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr) 163 { 164 struct fstyp_ufs *h = (struct fstyp_ufs *)handle; 165 166 return (dumpfs(h, fout, ferr)); 167 } 168 169 static int 170 is_ufs(fstyp_ufs_t *h) 171 { 172 (void) llseek(h->fd, (offset_t)SBLOCK * DEV_BSIZE, 0); 173 if (read(h->fd, &h->afs, SBSIZE) != SBSIZE) { 174 return (FSTYP_ERR_IO); 175 } 176 if ((h->afs.fs_magic != FS_MAGIC) && 177 (h->afs.fs_magic != MTB_UFS_MAGIC)) { 178 return (FSTYP_ERR_NO_MATCH); 179 } 180 if ((h->afs.fs_magic == FS_MAGIC) && 181 (h->afs.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && 182 h->afs.fs_version != UFS_VERSION_MIN)) { 183 return (FSTYP_ERR_NO_MATCH); 184 } 185 if ((h->afs.fs_magic == MTB_UFS_MAGIC) && 186 (h->afs.fs_version > MTB_UFS_VERSION_1 || 187 h->afs.fs_version < MTB_UFS_VERSION_MIN)) { 188 return (FSTYP_ERR_NO_MATCH); 189 } 190 return (0); 191 } 192 193 #define ADD_STRING(h, name, value) \ 194 if (nvlist_add_string(h->attr, name, value) != 0) { \ 195 return (FSTYP_ERR_NOMEM); \ 196 } 197 198 #define ADD_INT32(h, name, value) \ 199 if (nvlist_add_int32(h->attr, name, value) != 0) { \ 200 return (FSTYP_ERR_NOMEM); \ 201 } 202 203 #define ADD_BOOL(h, name, value) \ 204 if (nvlist_add_boolean_value(h->attr, name, value) != 0) { \ 205 return (FSTYP_ERR_NOMEM); \ 206 } 207 208 static int 209 get_attr(fstyp_ufs_t *h) 210 { 211 struct fs *fsp = &h->afs; 212 char s[128]; 213 time_t t; 214 215 ADD_INT32(h, "magic", fsp->fs_magic); 216 ADD_STRING(h, "format", 217 fsp->fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic"); 218 t = (time_t)fsp->fs_time; 219 (void) snprintf(s, sizeof (s), "%s", ctime(&t)); 220 s[strlen(s) - 1] = '\0'; 221 ADD_STRING(h, "time", s); 222 ADD_INT32(h, "sblkno", fsp->fs_sblkno); 223 ADD_INT32(h, "cblkno", fsp->fs_cblkno); 224 ADD_INT32(h, "iblkno", fsp->fs_iblkno); 225 ADD_INT32(h, "dblkno", fsp->fs_dblkno); 226 ADD_INT32(h, "sbsize", fsp->fs_sbsize); 227 ADD_INT32(h, "cgsize", fsp->fs_cgsize); 228 ADD_INT32(h, "cgoffset", fsp->fs_cgoffset); 229 ADD_INT32(h, "cgmask", fsp->fs_cgmask); 230 ADD_INT32(h, "ncg", fsp->fs_ncg); 231 ADD_INT32(h, "size", fsp->fs_size); 232 ADD_INT32(h, "blocks", fsp->fs_dsize); 233 ADD_INT32(h, "bsize", fsp->fs_bsize); 234 ADD_INT32(h, "bshift", fsp->fs_bshift); 235 ADD_INT32(h, "bmask", fsp->fs_bmask); 236 ADD_INT32(h, "fsize", fsp->fs_fsize); 237 ADD_INT32(h, "fshift", fsp->fs_fshift); 238 ADD_INT32(h, "fmask", fsp->fs_fmask); 239 ADD_INT32(h, "frag", fsp->fs_frag); 240 ADD_INT32(h, "fragshift", fsp->fs_fragshift); 241 ADD_INT32(h, "fsbtodb", fsp->fs_fsbtodb); 242 ADD_INT32(h, "minfree", fsp->fs_minfree); 243 ADD_INT32(h, "maxbpg", fsp->fs_maxbpg); 244 ADD_STRING(h, "optim", 245 fsp->fs_optim == FS_OPTSPACE ? "space" : "time"); 246 ADD_INT32(h, "maxcontig", fsp->fs_maxcontig); 247 ADD_INT32(h, "rotdelay", fsp->fs_rotdelay); 248 ADD_INT32(h, "rps", fsp->fs_rps); 249 ADD_INT32(h, "csaddr", fsp->fs_csaddr); 250 ADD_INT32(h, "cssize", fsp->fs_cssize); 251 ADD_INT32(h, "csshift", fsp->fs_csshift); 252 ADD_INT32(h, "csmask", fsp->fs_csmask); 253 ADD_INT32(h, "ntrak", fsp->fs_ntrak); 254 ADD_INT32(h, "nsect", fsp->fs_nsect); 255 ADD_INT32(h, "spc", fsp->fs_spc); 256 ADD_INT32(h, "ncyl", fsp->fs_ncyl); 257 ADD_INT32(h, "cpg", fsp->fs_cpg); 258 ADD_INT32(h, "bpg", fsp->fs_fpg / fsp->fs_frag); 259 ADD_INT32(h, "fpg", fsp->fs_fpg); 260 ADD_INT32(h, "ipg", fsp->fs_ipg); 261 ADD_INT32(h, "nindir", fsp->fs_nindir); 262 ADD_INT32(h, "inopb", fsp->fs_inopb); 263 ADD_INT32(h, "nspf", fsp->fs_nspf); 264 ADD_INT32(h, "nbfree", fsp->fs_cstotal.cs_nbfree); 265 ADD_INT32(h, "ndir", fsp->fs_cstotal.cs_ndir); 266 ADD_INT32(h, "nifree", fsp->fs_cstotal.cs_nifree); 267 ADD_INT32(h, "nffree", fsp->fs_cstotal.cs_nffree); 268 ADD_INT32(h, "cgrotor", fsp->fs_cgrotor); 269 ADD_INT32(h, "fmod", fsp->fs_fmod); 270 ADD_INT32(h, "ronly", fsp->fs_ronly); 271 ADD_INT32(h, "logbno", fsp->fs_logbno); 272 ADD_INT32(h, "rolled", fsp->fs_rolled); 273 ADD_INT32(h, "si", fsp->fs_si); 274 ADD_INT32(h, "flags", fsp->fs_flags); 275 ADD_INT32(h, "version", fsp->fs_version); 276 if (fsp->fs_reclaim & (FS_RECLAIM | FS_RECLAIMING)) { 277 (void) snprintf(s, sizeof (s), "%s%s", 278 (fsp->fs_reclaim & FS_RECLAIM) ? " FS_RECLAIM" : "", 279 (fsp->fs_reclaim & FS_RECLAIMING) ? " FS_RECLAIMING" : ""); 280 ADD_STRING(h, "fs_reclaim", s); 281 } 282 ADD_INT32(h, "clean", fsp->fs_clean); 283 284 if ((fsp->fs_state + (long)fsp->fs_time == FSOKAY) && 285 (fsp->fs_clean == FSCLEAN || fsp->fs_clean == FSSTABLE || 286 (fsp->fs_clean == FSLOG))) { 287 ADD_BOOL(h, "gen_clean", B_TRUE); 288 } else { 289 ADD_BOOL(h, "gen_clean", B_FALSE); 290 } 291 292 (void) snprintf(s, sizeof (s), "%d", fsp->fs_version); 293 ADD_STRING(h, "gen_version", s); 294 295 return (0); 296 } 297 298 299 static int 300 dumpfs(fstyp_ufs_t *h, FILE *fout, FILE *ferr) 301 { 302 int c, i, j, k, size, nrpos; 303 struct fs *fsp = &h->afs; 304 offset_t offset; 305 caddr_t sip; 306 time_t t; 307 308 t = (time_t)fsp->fs_time; 309 (void) fprintf(fout, "magic\t%x\tformat\t%s\ttime\t%s", fsp->fs_magic, 310 fsp->fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic", 311 ctime(&t)); 312 (void) fprintf(fout, "sblkno\t%d\tcblkno\t%d\tiblkno\t%d\tdblkno\t%d\n", 313 fsp->fs_sblkno, fsp->fs_cblkno, fsp->fs_iblkno, fsp->fs_dblkno); 314 (void) fprintf(fout, 315 "sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n", 316 fsp->fs_sbsize, fsp->fs_cgsize, fsp->fs_cgoffset, fsp->fs_cgmask); 317 (void) fprintf(fout, "ncg\t%d\tsize\t%d\tblocks\t%d\n", 318 fsp->fs_ncg, fsp->fs_size, fsp->fs_dsize); 319 (void) fprintf(fout, "bsize\t%d\tshift\t%d\tmask\t0x%08x\n", 320 fsp->fs_bsize, fsp->fs_bshift, fsp->fs_bmask); 321 (void) fprintf(fout, "fsize\t%d\tshift\t%d\tmask\t0x%08x\n", 322 fsp->fs_fsize, fsp->fs_fshift, fsp->fs_fmask); 323 (void) fprintf(fout, "frag\t%d\tshift\t%d\tfsbtodb\t%d\n", 324 fsp->fs_frag, fsp->fs_fragshift, fsp->fs_fsbtodb); 325 (void) fprintf(fout, "minfree\t%d%%\tmaxbpg\t%d\toptim\t%s\n", 326 fsp->fs_minfree, fsp->fs_maxbpg, 327 fsp->fs_optim == FS_OPTSPACE ? "space" : "time"); 328 (void) fprintf(fout, "maxcontig %d\trotdelay %dms\trps\t%d\n", 329 fsp->fs_maxcontig, fsp->fs_rotdelay, fsp->fs_rps); 330 (void) fprintf(fout, 331 "csaddr\t%d\tcssize\t%d\tshift\t%d\tmask\t0x%08x\n", 332 fsp->fs_csaddr, fsp->fs_cssize, fsp->fs_csshift, fsp->fs_csmask); 333 (void) fprintf(fout, "ntrak\t%d\tnsect\t%d\tspc\t%d\tncyl\t%d\n", 334 fsp->fs_ntrak, fsp->fs_nsect, fsp->fs_spc, fsp->fs_ncyl); 335 (void) fprintf(fout, "cpg\t%d\tbpg\t%d\tfpg\t%d\tipg\t%d\n", 336 fsp->fs_cpg, fsp->fs_fpg / fsp->fs_frag, fsp->fs_fpg, fsp->fs_ipg); 337 (void) fprintf(fout, "nindir\t%d\tinopb\t%d\tnspf\t%d\n", 338 fsp->fs_nindir, fsp->fs_inopb, fsp->fs_nspf); 339 (void) fprintf(fout, "nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", 340 fsp->fs_cstotal.cs_nbfree, fsp->fs_cstotal.cs_ndir, 341 fsp->fs_cstotal.cs_nifree, fsp->fs_cstotal.cs_nffree); 342 (void) fprintf(fout, "cgrotor\t%d\tfmod\t%d\tronly\t%d\tlogbno\t%d\n", 343 fsp->fs_cgrotor, fsp->fs_fmod, fsp->fs_ronly, fsp->fs_logbno); 344 (void) fprintf(fout, "rolled\t%d\tsi\t%d\tflags\t%x\n", 345 fsp->fs_rolled, fsp->fs_si, fsp->fs_flags); 346 (void) fprintf(fout, "version\t%d\n", fsp->fs_version); 347 if (fsp->fs_reclaim & (FS_RECLAIM | FS_RECLAIMING)) { 348 (void) fprintf(fout, "fs_reclaim%s%s\n", 349 (fsp->fs_reclaim & FS_RECLAIM) ? " FS_RECLAIM" : "", 350 (fsp->fs_reclaim & FS_RECLAIMING) ? " FS_RECLAIMING" : ""); 351 } else { 352 (void) fprintf(fout, "fs_reclaim is not set\n"); 353 } 354 if (fsp->fs_state + (long)fsp->fs_time == FSOKAY) { 355 (void) fprintf(fout, gettext( 356 "file system state is valid, fsclean is %d\n"), 357 fsp->fs_clean); 358 } else { 359 (void) fprintf(fout, 360 gettext("file system state is not valid\n")); 361 } 362 if (fsp->fs_cpc != 0) { 363 (void) fprintf(fout, gettext( 364 "blocks available in each rotational position")); 365 } else { 366 (void) fprintf(fout, gettext( 367 "insufficient space to maintain rotational tables\n")); 368 } 369 for (c = 0; c < fsp->fs_cpc; c++) { 370 (void) fprintf(fout, gettext("\ncylinder number %d:"), c); 371 nrpos = (((fsp)->fs_postblformat == FS_DYNAMICPOSTBLFMT) ? 372 (fsp)->fs_nrpos : NRPOS); 373 for (i = 0; i < nrpos; i++) { 374 if (fs_postbl(fsp, c)[i] == -1) 375 continue; 376 (void) fprintf(fout, gettext("\n position %d:\t"), i); 377 /*CSTYLED*/ 378 for (j = fs_postbl(fsp, c)[i], k = 1; ; 379 j += fs_rotbl(fsp)[j], k++) { 380 (void) fprintf(fout, "%5d", j); 381 if (k % 12 == 0) 382 (void) fprintf(fout, "\n\t\t"); 383 if ((fs_rotbl(fsp))[j] == 0) 384 break; 385 } 386 } 387 } 388 (void) fprintf(fout, "\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t"); 389 sip = calloc(1, fsp->fs_cssize); 390 /* void * cast is to convince lint that sip really is aligned */ 391 fsp->fs_u.fs_csp = (struct csum *)(void *)sip; 392 for (i = 0, j = 0; i < fsp->fs_cssize; i += fsp->fs_bsize, j++) { 393 size = fsp->fs_cssize - i < fsp->fs_bsize ? 394 fsp->fs_cssize - i : fsp->fs_bsize; 395 offset = (offset_t)fsbtodb( 396 fsp, (fsp->fs_csaddr + j * fsp->fs_frag)) * DEV_BSIZE; 397 (void) llseek(h->fd, offset, 0); 398 if (read(h->fd, sip, size) != size) { 399 return (FSTYP_ERR_IO); 400 } 401 sip += size; 402 } 403 for (i = 0; i < fsp->fs_ncg; i++) { 404 struct csum *cs = &fsp->fs_cs(fsp, i); 405 if (i && i % 4 == 0) 406 (void) fprintf(fout, "\n\t"); 407 (void) fprintf(fout, "(%d,%d,%d,%d) ", 408 cs->cs_nbfree, cs->cs_ndir, cs->cs_nifree, cs->cs_nffree); 409 } 410 (void) fprintf(fout, "\n"); 411 if (fsp->fs_ncyl % fsp->fs_cpg) { 412 (void) fprintf(fout, gettext("cylinders in last group %d\n"), 413 i = fsp->fs_ncyl % fsp->fs_cpg); 414 (void) fprintf(fout, gettext("blocks in last group %d\n"), 415 i * fsp->fs_spc / NSPB(fsp)); 416 } 417 (void) fprintf(fout, "\n"); 418 for (i = 0; i < fsp->fs_ncg; i++) 419 dumpcg(h, fout, ferr, i); 420 if (fsp->fs_logbno) 421 dumplog(h, fout, ferr); 422 return (0); 423 } 424 425 static void 426 setsum(int32_t *sp, int32_t *lp, int nb) 427 { 428 int32_t csum = 0; 429 430 *sp = 0; 431 nb /= sizeof (int32_t); 432 while (nb--) 433 csum += *lp++; 434 *sp = csum; 435 } 436 437 static int 438 checksum(int32_t *sp, int32_t *lp, int nb) 439 { 440 int32_t ssum = *sp; 441 442 setsum(sp, lp, nb); 443 if (ssum != *sp) { 444 *sp = ssum; 445 return (0); 446 } 447 return (1); 448 } 449 450 /* ARGSUSED */ 451 static void 452 dumplog(fstyp_ufs_t *h, FILE *fout, FILE *ferr) 453 { 454 int i; 455 long tb = 0; 456 extent_block_t *ebp; 457 extent_t *ep; 458 ml_odunit_t *ud; 459 struct fs *fsp = &h->afs; 460 461 (void) fprintf(fout, "\nlog\n"); 462 if (fsp->fs_magic == FS_MAGIC) 463 (void) fprintf(fout, 464 "log allocation block %d\n", fsp->fs_logbno); 465 else 466 (void) fprintf(fout, "log allocation block (in frags) %d\n", 467 fsp->fs_logbno); 468 (void) llseek(h->fd, (offset_t)logbtodb(fsp, 469 fsp->fs_logbno) * DEV_BSIZE, 0); 470 if (read(h->fd, (char *)&h->eg, fsp->fs_bsize) != fsp->fs_bsize) { 471 (void) fprintf(fout, gettext( 472 "dumplog: error reading log allocation\n")); 473 return; 474 } 475 ebp = (void *)h->eg; 476 if (ebp->type != LUFS_EXTENTS) 477 (void) fprintf(fout, 478 gettext("Invalid log allocation type %x\n"), ebp->type); 479 if (!checksum(&ebp->chksum, (int32_t *)ebp, fsp->fs_bsize)) 480 (void) fprintf(fout, gettext("Invalid log checksum\n")); 481 482 for (i = 0, ep = &ebp->extents[0]; i < ebp->nextents; ++i, ++ep) { 483 (void) fprintf(fout, "\tlogical block\t%" PRId32 484 "\tphysical block\t%" PRId32 485 "\tblocks\t%" PRId32 "\n", 486 ep->lbno, ep->pbno, ep->nbno); 487 tb += dbtob(ep->nbno); 488 } 489 (void) fprintf(fout, "log size %" PRIu32 " bytes (%ld calculated)\n", 490 ebp->nbytes, tb); 491 (void) fprintf(fout, "\n"); 492 ep = &ebp->extents[0]; 493 (void) llseek(h->fd, (offset_t)logbtodb(fsp, ep->pbno) * DEV_BSIZE, 0); 494 if (read(h->fd, &h->eg, dbtob(LS_SECTORS)) != dbtob(LS_SECTORS)) { 495 (void) fprintf(fout, gettext( 496 "dumplog: error reading log state\n")); 497 return; 498 } 499 ud = (void *)&h->eg; 500 (void) fprintf(fout, "version\t\t%" PRIu32 "\t\t", ud->od_version); 501 if (ud->od_badlog) 502 (void) fprintf(fout, "logstate\tError\n"); 503 else 504 (void) fprintf(fout, "logstate\tOkay\n"); 505 (void) fprintf(fout, "bol\t\t%" PRId32 "\t\teol\t\t%" PRId32 "\n", 506 ud->od_bol_lof, ud->od_eol_lof); 507 (void) fprintf(fout, "requestsize\t%" PRIu32 "\n", ud->od_requestsize); 508 (void) fprintf(fout, "statesize\t%" PRIu32 "\n", ud->od_statesize); 509 (void) fprintf(fout, "logsize\t\t%" PRIu32 "\n", ud->od_logsize); 510 (void) fprintf(fout, 511 "maxtransfer\t%" PRIu32 "\t\tdevbsize\t%" PRIu32 "\n", 512 ud->od_maxtransfer, ud->od_devbsize); 513 (void) fprintf(fout, 514 "head\t\t%" PRId32 "\t\thead ident\t%#" PRIx32 "\n", 515 ud->od_head_lof, ud->od_head_ident); 516 (void) fprintf(fout, 517 "tail\t\t%" PRId32 "\t\ttail ident\t%#" PRIx32 "\n", 518 ud->od_tail_lof, ud->od_tail_ident); 519 (void) fprintf(fout, "\t\t\t\tdebug\t\t%#" PRIx32 "\n", ud->od_debug); 520 if (ud->od_head_ident + ud->od_tail_ident != ud->od_chksum) 521 (void) fprintf(fout, 522 "Bad chksum\t%#" PRIx32 "\n", ud->od_chksum); 523 else 524 (void) fprintf(fout, 525 "Good chksum\t%#" PRIx32 "\n", ud->od_chksum); 526 } 527 528 /* ARGSUSED */ 529 static void 530 dumpcg(fstyp_ufs_t *h, FILE *fout, FILE *ferr, const int c) 531 { 532 int i, j; 533 offset_t off; 534 struct cg *cgp; 535 struct ocg *ocgp; 536 struct fs *fsp = &h->afs; 537 time_t t; 538 539 (void) fprintf(fout, "\ncg %d:\n", c); 540 off = llseek(h->fd, 541 (offset_t)fsbtodb(fsp, cgtod(fsp, c)) * DEV_BSIZE, 0); 542 if (read(h->fd, (char *)&h->acg, fsp->fs_bsize) != fsp->fs_bsize) { 543 (void) fprintf(fout, gettext("dumpfs: error reading cg\n")); 544 return; 545 } 546 cgp = (struct cg *)&h->acg; 547 ocgp = (struct ocg *)&h->acg; 548 if (!cg_chkmagic(cgp)) 549 (void) fprintf(fout, gettext( 550 "Invalid Cylinder grp magic fffs:%x 4.2 fs:%x\n"), 551 cgp->cg_magic, ocgp->cg_magic); 552 if (cgp->cg_magic == CG_MAGIC) { 553 /* print FFFS 4.3 cyl grp format. */ 554 t = (time_t)cgp->cg_time; 555 (void) fprintf(fout, "magic\t%x\ttell\t%llx\ttime\t%s", 556 cgp->cg_magic, off, ctime(&t)); /* *** */ 557 (void) fprintf(fout, 558 "cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n", 559 cgp->cg_cgx, cgp->cg_ncyl, cgp->cg_niblk, cgp->cg_ndblk); 560 (void) fprintf(fout, 561 "nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", 562 cgp->cg_cs.cs_nbfree, cgp->cg_cs.cs_ndir, 563 cgp->cg_cs.cs_nifree, cgp->cg_cs.cs_nffree); 564 (void) fprintf(fout, "rotor\t%d\tirotor\t%d\tfrotor\t%d\nfrsum", 565 cgp->cg_rotor, cgp->cg_irotor, cgp->cg_frotor); 566 for (i = 1, j = 0; i < fsp->fs_frag; i++) { 567 (void) fprintf(fout, "\t%d", cgp->cg_frsum[i]); 568 j += i * cgp->cg_frsum[i]; 569 } 570 (void) fprintf(fout, 571 gettext("\nsum of frsum: %d\niused:\t"), j); 572 pbits(fout, cg_inosused(cgp), fsp->fs_ipg); 573 (void) fprintf(fout, gettext("free:\t")); 574 pbits(fout, cg_blksfree(cgp), fsp->fs_fpg); 575 (void) fprintf(fout, "b:\n"); 576 for (i = 0; i < fsp->fs_cpg; i++) { 577 (void) fprintf(fout, 578 " c%d:\t(%d)\t", i, cg_blktot(cgp)[i]); 579 for (j = 0; j < fsp->fs_nrpos; j++) /* ****** */ 580 (void) fprintf(fout, 581 " %d", cg_blks(fsp, cgp, i)[j]); 582 (void) fprintf(fout, "\n"); 583 } 584 } else if (ocgp->cg_magic == CG_MAGIC) { 585 /* print Old cyl grp format. */ 586 t = (time_t)ocgp->cg_time; 587 (void) fprintf(fout, "magic\t%x\ttell\t%llx\ttime\t%s", 588 ocgp->cg_magic, off, ctime(&t)); 589 (void) fprintf(fout, 590 "cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n", 591 ocgp->cg_cgx, ocgp->cg_ncyl, ocgp->cg_niblk, 592 ocgp->cg_ndblk); 593 (void) fprintf(fout, 594 "nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", 595 ocgp->cg_cs.cs_nbfree, ocgp->cg_cs.cs_ndir, 596 ocgp->cg_cs.cs_nifree, ocgp->cg_cs.cs_nffree); 597 (void) fprintf(fout, 598 "rotor\t%d\tirotor\t%d\tfrotor\t%d\nfrsum", 599 ocgp->cg_rotor, ocgp->cg_irotor, ocgp->cg_frotor); 600 for (i = 1, j = 0; i < fsp->fs_frag; i++) { 601 (void) fprintf(fout, "\t%d", ocgp->cg_frsum[i]); 602 j += i * ocgp->cg_frsum[i]; 603 } 604 (void) fprintf(fout, 605 gettext("\nsum of frsum: %d\niused:\t"), j); 606 pbits(fout, ocgp->cg_iused, fsp->fs_ipg); 607 (void) fprintf(fout, gettext("free:\t")); 608 pbits(fout, ocgp->cg_free, fsp->fs_fpg); 609 (void) fprintf(fout, "b:\n"); 610 for (i = 0; i < fsp->fs_cpg; i++) { 611 (void) fprintf(fout, 612 " c%d:\t(%d)\t", i, ocgp->cg_btot[i]); 613 for (j = 0; j < NRPOS; j++) 614 (void) fprintf(fout, " %d", ocgp->cg_b[i][j]); 615 (void) fprintf(fout, "\n"); 616 } 617 } 618 } 619 620 621 static void 622 pbits(FILE *fout, const void *p, const int max) 623 { 624 int i; 625 int count = 0, j; 626 unsigned char *cp = (unsigned char *)p; 627 628 for (i = 0; i < max; i++) { 629 if (isset(cp, i)) { 630 if (count) 631 (void) fprintf(fout, ",%s", 632 (count % 9 == 8) ? "\n\t" : " "); 633 count++; 634 (void) fprintf(fout, "%d", i); 635 j = i; 636 while ((i + 1) < max && isset(cp, i+1)) 637 i++; 638 if (i != j) 639 (void) fprintf(fout, "-%d", i); 640 } 641 } 642 (void) fprintf(fout, "\n"); 643 } 644