Annotation of 43BSDTahoe/etc/fsck/main.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)main.c     5.8 (Berkeley) 5/3/88";
                     15: #endif not lint
                     16: 
                     17: #include <sys/param.h>
                     18: #include <sys/inode.h>
                     19: #include <sys/fs.h>
                     20: #include <sys/stat.h>
                     21: #include <sys/wait.h>
                     22: #include <fstab.h>
                     23: #include <strings.h>
                     24: #include "fsck.h"
                     25: 
                     26: char   *rawname(), *unrawname(), *blockcheck();
                     27: int    catch(), catchquit(), voidquit();
                     28: int    returntosingle;
                     29: int    (*signal())();
                     30: 
                     31: main(argc, argv)
                     32:        int     argc;
                     33:        char    *argv[];
                     34: {
                     35:        struct fstab *fsp;
                     36:        int pid, passno, anygtr, sumstatus;
                     37:        char *name;
                     38:        struct worklist {
                     39:                int     pid;            /* pid of child doing the check */
                     40:                struct  worklist *next; /* next in list */
                     41:                char    name[MAXMNTLEN];/* name of file system */
                     42:        } *listhead = 0, *freelist = 0, *badlist = 0;
                     43:        register struct worklist *wp, *pwp;
                     44: 
                     45:        sync();
                     46:        while (--argc > 0 && **++argv == '-') {
                     47:                switch (*++*argv) {
                     48: 
                     49:                case 'p':
                     50:                        preen++;
                     51:                        break;
                     52: 
                     53:                case 'b':
                     54:                        if (argv[0][1] != '\0') {
                     55:                                bflag = atoi(argv[0]+1);
                     56:                        } else {
                     57:                                bflag = atoi(*++argv);
                     58:                                argc--;
                     59:                        }
                     60:                        printf("Alternate super block location: %d\n", bflag);
                     61:                        break;
                     62: 
                     63:                case 'c':
                     64:                        cvtflag++;
                     65:                        break;
                     66: 
                     67:                case 'd':
                     68:                        debug++;
                     69:                        break;
                     70: 
                     71:                case 'n':       /* default no answer flag */
                     72:                case 'N':
                     73:                        nflag++;
                     74:                        yflag = 0;
                     75:                        break;
                     76: 
                     77:                case 'y':       /* default yes answer flag */
                     78:                case 'Y':
                     79:                        yflag++;
                     80:                        nflag = 0;
                     81:                        break;
                     82: 
                     83:                default:
                     84:                        errexit("%c option?\n", **argv);
                     85:                }
                     86:        }
                     87:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                     88:                (void)signal(SIGINT, catch);
                     89:        if (preen)
                     90:                (void)signal(SIGQUIT, catchquit);
                     91:        if (argc) {
                     92:                while (argc-- > 0) {
                     93:                        hotroot = 0;
                     94:                        checkfilesys(*argv++);
                     95:                }
                     96:                exit(0);
                     97:        }
                     98:        sumstatus = 0;
                     99:        passno = 1;
                    100:        do {
                    101:                anygtr = 0;
                    102:                if (setfsent() == 0)
                    103:                        errexit("Can't open checklist file: %s\n", FSTAB);
                    104:                while ((fsp = getfsent()) != 0) {
                    105:                        if (strcmp(fsp->fs_type, FSTAB_RW) &&
                    106:                            strcmp(fsp->fs_type, FSTAB_RO) &&
                    107:                            strcmp(fsp->fs_type, FSTAB_RQ))
                    108:                                continue;
                    109:                        if (preen == 0 ||
                    110:                            passno == 1 && fsp->fs_passno == passno) {
                    111:                                name = blockcheck(fsp->fs_spec);
                    112:                                if (name != NULL)
                    113:                                        checkfilesys(name);
                    114:                                else if (preen)
                    115:                                        exit(8);
                    116:                        } else if (fsp->fs_passno > passno) {
                    117:                                anygtr = 1;
                    118:                        } else if (fsp->fs_passno == passno) {
                    119:                                name = blockcheck(fsp->fs_spec);
                    120:                                if (name == NULL) {
                    121:                                        pwarn("BAD DISK NAME %s\n",
                    122:                                                fsp->fs_spec);
                    123:                                        sumstatus |= 8;
                    124:                                        continue;
                    125:                                }
                    126:                                pid = fork();
                    127:                                if (pid < 0) {
                    128:                                        perror("fork");
                    129:                                        exit(8);
                    130:                                }
                    131:                                if (pid == 0) {
                    132:                                        (void)signal(SIGQUIT, voidquit);
                    133:                                        checkfilesys(name);
                    134:                                        exit(0);
                    135:                                } else {
                    136:                                        if (freelist == 0) {
                    137:                                                wp = (struct worklist *) malloc
                    138:                                                    (sizeof(struct worklist));
                    139:                                        } else {
                    140:                                                wp = freelist;
                    141:                                                freelist = wp->next;
                    142:                                        }
                    143:                                        wp->next = listhead;
                    144:                                        listhead = wp;
                    145:                                        wp->pid = pid;
                    146:                                        sprintf(wp->name, "%s (%s)", name,
                    147:                                            fsp->fs_file);
                    148:                                }
                    149:                        }
                    150:                }
                    151:                if (preen) {
                    152:                        union wait status;
                    153:                        while ((pid = wait(&status)) != -1) {
                    154:                                sumstatus |= status.w_retcode;
                    155:                                pwp = 0;
                    156:                                for (wp = listhead; wp; pwp = wp, wp = wp->next)
                    157:                                        if (wp->pid == pid)
                    158:                                                break;
                    159:                                if (wp == 0) {
                    160:                                        printf("Unknown pid %d\n", pid);
                    161:                                        continue;
                    162:                                }
                    163:                                if (pwp == 0)
                    164:                                        listhead = wp->next;
                    165:                                else
                    166:                                        pwp->next = wp->next;
                    167:                                if (status.w_retcode != 0) {
                    168:                                        wp->next = badlist;
                    169:                                        badlist = wp;
                    170:                                } else {
                    171:                                        wp->next = freelist;
                    172:                                        freelist = wp;
                    173:                                }
                    174:                        }
                    175:                }
                    176:                passno++;
                    177:        } while (anygtr);
                    178:        if (sumstatus) {
                    179:                if (badlist == 0)
                    180:                        exit(8);
                    181:                printf("THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
                    182:                        badlist->next ? "S" : "", "UNEXPECTED INCONSISTENCY:");
                    183:                for (wp = badlist; wp; wp = wp->next)
                    184:                        printf("%s%s", wp->name, wp->next ? ", " : "\n");
                    185:                exit(8);
                    186:        }
                    187:        (void)endfsent();
                    188:        if (returntosingle)
                    189:                exit(2);
                    190:        exit(0);
                    191: }
                    192: 
                    193: checkfilesys(filesys)
                    194:        char *filesys;
                    195: {
                    196:        daddr_t n_ffree, n_bfree;
                    197:        struct dups *dp;
                    198:        struct zlncnt *zlnp;
                    199: 
                    200:        devname = filesys;
                    201:        if (setup(filesys) == 0) {
                    202:                if (preen)
                    203:                        pfatal("CAN'T CHECK FILE SYSTEM.");
                    204:                return;
                    205:        }
                    206:        /*
                    207:         * 1: scan inodes tallying blocks used
                    208:         */
                    209:        if (preen == 0) {
                    210:                printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
                    211:                if (hotroot)
                    212:                        printf("** Root file system\n");
                    213:                printf("** Phase 1 - Check Blocks and Sizes\n");
                    214:        }
                    215:        pass1();
                    216: 
                    217:        /*
                    218:         * 1b: locate first references to duplicates, if any
                    219:         */
                    220:        if (duplist) {
                    221:                if (preen)
                    222:                        pfatal("INTERNAL ERROR: dups with -p");
                    223:                printf("** Phase 1b - Rescan For More DUPS\n");
                    224:                pass1b();
                    225:        }
                    226: 
                    227:        /*
                    228:         * 2: traverse directories from root to mark all connected directories
                    229:         */
                    230:        if (preen == 0)
                    231:                printf("** Phase 2 - Check Pathnames\n");
                    232:        pass2();
                    233: 
                    234:        /*
                    235:         * 3: scan inodes looking for disconnected directories
                    236:         */
                    237:        if (preen == 0)
                    238:                printf("** Phase 3 - Check Connectivity\n");
                    239:        pass3();
                    240: 
                    241:        /*
                    242:         * 4: scan inodes looking for disconnected files; check reference counts
                    243:         */
                    244:        if (preen == 0)
                    245:                printf("** Phase 4 - Check Reference Counts\n");
                    246:        pass4();
                    247: 
                    248:        /*
                    249:         * 5: check and repair resource counts in cylinder groups
                    250:         */
                    251:        if (preen == 0)
                    252:                printf("** Phase 5 - Check Cyl groups\n");
                    253:        pass5();
                    254: 
                    255:        /*
                    256:         * print out summary statistics
                    257:         */
                    258:        n_ffree = sblock.fs_cstotal.cs_nffree;
                    259:        n_bfree = sblock.fs_cstotal.cs_nbfree;
                    260:        pwarn("%d files, %d used, %d free ",
                    261:            n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
                    262:        printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
                    263:            n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize);
                    264:        if (debug && (n_files -= imax - ROOTINO - sblock.fs_cstotal.cs_nifree))
                    265:                printf("%d files missing\n", n_files);
                    266:        if (debug) {
                    267:                n_blks += sblock.fs_ncg *
                    268:                        (cgdmin(&sblock, 0) - cgsblock(&sblock, 0));
                    269:                n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0);
                    270:                n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize);
                    271:                if (n_blks -= fmax - (n_ffree + sblock.fs_frag * n_bfree))
                    272:                        printf("%d blocks missing\n", n_blks);
                    273:                if (duplist != NULL) {
                    274:                        printf("The following duplicate blocks remain:");
                    275:                        for (dp = duplist; dp; dp = dp->next)
                    276:                                printf(" %d,", dp->dup);
                    277:                        printf("\n");
                    278:                }
                    279:                if (zlnhead != NULL) {
                    280:                        printf("The following zero link count inodes remain:");
                    281:                        for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
                    282:                                printf(" %d,", zlnp->zlncnt);
                    283:                        printf("\n");
                    284:                }
                    285:        }
                    286:        zlnhead = (struct zlncnt *)0;
                    287:        duplist = (struct dups *)0;
                    288:        if (dfile.mod) {
                    289:                (void)time(&sblock.fs_time);
                    290:                sbdirty();
                    291:        }
                    292:        ckfini();
                    293:        free(blockmap);
                    294:        free(statemap);
                    295:        free((char *)lncntp);
                    296:        if (!dfile.mod)
                    297:                return;
                    298:        if (!preen) {
                    299:                printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
                    300:                if (hotroot)
                    301:                        printf("\n***** REBOOT UNIX *****\n");
                    302:        }
                    303:        if (hotroot) {
                    304:                sync();
                    305:                exit(4);
                    306:        }
                    307: }
                    308: 
                    309: char *
                    310: blockcheck(name)
                    311:        char *name;
                    312: {
                    313:        struct stat stslash, stblock, stchar;
                    314:        char *raw;
                    315:        int looped = 0;
                    316: 
                    317:        hotroot = 0;
                    318:        if (stat("/", &stslash) < 0){
                    319:                perror("/");
                    320:                printf("Can't stat root\n");
                    321:                return (0);
                    322:        }
                    323: retry:
                    324:        if (stat(name, &stblock) < 0){
                    325:                perror(name);
                    326:                printf("Can't stat %s\n", name);
                    327:                return (0);
                    328:        }
                    329:        if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
                    330:                if (stslash.st_dev == stblock.st_rdev) {
                    331:                        hotroot++;
                    332:                        return (name);
                    333:                }
                    334:                raw = rawname(name);
                    335:                if (stat(raw, &stchar) < 0){
                    336:                        perror(raw);
                    337:                        printf("Can't stat %s\n", raw);
                    338:                        return (name);
                    339:                }
                    340:                if ((stchar.st_mode & S_IFMT) == S_IFCHR)
                    341:                        return (raw);
                    342:                else {
                    343:                        printf("%s is not a character device\n", raw);
                    344:                        return (name);
                    345:                }
                    346:        } else if ((stblock.st_mode & S_IFMT) == S_IFCHR) {
                    347:                if (looped) {
                    348:                        printf("Can't make sense out of name %s\n", name);
                    349:                        return (0);
                    350:                }
                    351:                name = unrawname(name);
                    352:                looped++;
                    353:                goto retry;
                    354:        }
                    355:        printf("Can't make sense out of name %s\n", name);
                    356:        return (0);
                    357: }
                    358: 
                    359: char *
                    360: unrawname(cp)
                    361:        char *cp;
                    362: {
                    363:        char *dp = rindex(cp, '/');
                    364:        struct stat stb;
                    365: 
                    366:        if (dp == 0)
                    367:                return (cp);
                    368:        if (stat(cp, &stb) < 0)
                    369:                return (cp);
                    370:        if ((stb.st_mode&S_IFMT) != S_IFCHR)
                    371:                return (cp);
                    372:        if (*(dp+1) != 'r')
                    373:                return (cp);
                    374:        (void)strcpy(dp+1, dp+2);
                    375:        return (cp);
                    376: }
                    377: 
                    378: char *
                    379: rawname(cp)
                    380:        char *cp;
                    381: {
                    382:        static char rawbuf[32];
                    383:        char *dp = rindex(cp, '/');
                    384: 
                    385:        if (dp == 0)
                    386:                return (0);
                    387:        *dp = 0;
                    388:        (void)strcpy(rawbuf, cp);
                    389:        *dp = '/';
                    390:        (void)strcat(rawbuf, "/r");
                    391:        (void)strcat(rawbuf, dp+1);
                    392:        return (rawbuf);
                    393: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.