diff options
Diffstat (limited to 'sbin/fsck/main.c')
-rw-r--r-- | sbin/fsck/main.c | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/sbin/fsck/main.c b/sbin/fsck/main.c deleted file mode 100644 index 6463990..0000000 --- a/sbin/fsck/main.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1980, 1986, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/mount.h> -#include <sys/resource.h> - -#include <ufs/ufs/dinode.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ffs/fs.h> - -#include <err.h> -#include <errno.h> -#include <fstab.h> -#include <paths.h> - -#include "fsck.h" - -static int argtoi __P((int flag, char *req, char *str, int base)); -static int docheck __P((struct fstab *fsp)); -static int checkfilesys __P((char *filesys, char *mntpt, long auxdata, - int child)); -static struct statfs *getmntpt __P((const char *)); -int main __P((int argc, char *argv[])); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int ch; - int ret, maxrun = 0; - struct rlimit rlimit; - - sync(); - while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) { - switch (ch) { - case 'p': - preen++; - break; - - case 'b': - bflag = argtoi('b', "number", optarg, 10); - printf("Alternate super block location: %d\n", bflag); - break; - - case 'c': - cvtlevel = argtoi('c', "conversion level", optarg, 10); - break; - - case 'd': - debug++; - break; - - case 'f': - fflag++; - break; - - case 'l': - maxrun = argtoi('l', "number", optarg, 10); - break; - - case 'm': - lfmode = argtoi('m', "mode", optarg, 8); - if (lfmode &~ 07777) - errx(EEXIT, "bad mode to -m: %o", lfmode); - printf("** lost+found creation mode %o\n", lfmode); - break; - - case 'n': - case 'N': - nflag++; - yflag = 0; - break; - - case 'y': - case 'Y': - yflag++; - nflag = 0; - break; - - default: - errx(EEXIT, "%c option?", ch); - } - } - argc -= optind; - argv += optind; - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - (void)signal(SIGINT, catch); - if (preen) - (void)signal(SIGQUIT, catchquit); - /* - * Push up our allowed memory limit so we can cope - * with huge filesystems. - */ - if (getrlimit(RLIMIT_DATA, &rlimit) == 0) { - rlimit.rlim_cur = rlimit.rlim_max; - (void)setrlimit(RLIMIT_DATA, &rlimit); - } - if (argc) { - while (argc-- > 0) { - char *path = blockcheck(*argv); - - if (path == NULL) - pfatal("Can't check %s\n", *argv); - else - (void)checkfilesys(path, 0, 0L, 0); - ++argv; - } - exit(0); - } - ret = checkfstab(preen, maxrun, docheck, checkfilesys); - if (returntosingle) - exit(2); - exit(ret); -} - -static int -argtoi(flag, req, str, base) - int flag; - char *req, *str; - int base; -{ - char *cp; - int ret; - - ret = (int)strtol(str, &cp, base); - if (cp == str || *cp) - errx(EEXIT, "-%c flag requires a %s", flag, req); - return (ret); -} - -/* - * Determine whether a filesystem should be checked. - */ -static int -docheck(fsp) - register struct fstab *fsp; -{ - - if (strcmp(fsp->fs_vfstype, "ufs") || - (strcmp(fsp->fs_type, FSTAB_RW) && - strcmp(fsp->fs_type, FSTAB_RO)) || - fsp->fs_passno == 0) - return (0); - return (1); -} - -/* - * Check the specified filesystem. - */ -/* ARGSUSED */ -static int -checkfilesys(filesys, mntpt, auxdata, child) - char *filesys, *mntpt; - long auxdata; - int child; -{ - ufs_daddr_t n_ffree, n_bfree; - struct dups *dp; - struct statfs *mntbuf; - struct zlncnt *zlnp; - int cylno; - - if (preen && child) - (void)signal(SIGQUIT, voidquit); - cdevname = filesys; - if (debug && preen) - pwarn("starting\n"); - switch (setup(filesys)) { - case 0: - if (preen) - pfatal("CAN'T CHECK FILE SYSTEM."); - return (0); - case -1: - pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree + - sblock.fs_frag * sblock.fs_cstotal.cs_nbfree); - printf("(%d frags, %d blocks, %.1f%% fragmentation)\n", - sblock.fs_cstotal.cs_nffree, sblock.fs_cstotal.cs_nbfree, - sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize); - return (0); - } - - /* - * Get the mount point information of the filesystem, if - * it is available. - */ - mntbuf = getmntpt(filesys); - - /* - * Cleared if any questions answered no. Used to decide if - * the superblock should be marked clean. - */ - resolved = 1; - /* - * 1: scan inodes tallying blocks used - */ - if (preen == 0) { - printf("** Last Mounted on %s\n", sblock.fs_fsmnt); - if (mntbuf != NULL && mntbuf->f_flags & MNT_ROOTFS) - printf("** Root file system\n"); - printf("** Phase 1 - Check Blocks and Sizes\n"); - } - pass1(); - - /* - * 1b: locate first references to duplicates, if any - */ - if (duplist) { - if (preen || usedsoftdep) - pfatal("INTERNAL ERROR: dups with -p"); - printf("** Phase 1b - Rescan For More DUPS\n"); - pass1b(); - } - - /* - * 2: traverse directories from root to mark all connected directories - */ - if (preen == 0) - printf("** Phase 2 - Check Pathnames\n"); - pass2(); - - /* - * 3: scan inodes looking for disconnected directories - */ - if (preen == 0) - printf("** Phase 3 - Check Connectivity\n"); - pass3(); - - /* - * 4: scan inodes looking for disconnected files; check reference counts - */ - if (preen == 0) - printf("** Phase 4 - Check Reference Counts\n"); - pass4(); - - /* - * 5: check and repair resource counts in cylinder groups - */ - if (preen == 0) - printf("** Phase 5 - Check Cyl groups\n"); - pass5(); - - /* - * print out summary statistics - */ - n_ffree = sblock.fs_cstotal.cs_nffree; - n_bfree = sblock.fs_cstotal.cs_nbfree; - pwarn("%ld files, %ld used, %ld free ", - n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree); - printf("(%d frags, %d blocks, %.1f%% fragmentation)\n", - n_ffree, n_bfree, n_ffree * 100.0 / sblock.fs_dsize); - if (debug && - (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree)) - printf("%d files missing\n", n_files); - if (debug) { - n_blks += sblock.fs_ncg * - (cgdmin(&sblock, 0) - cgsblock(&sblock, 0)); - n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0); - n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize); - if (n_blks -= maxfsblock - (n_ffree + sblock.fs_frag * n_bfree)) - printf("%d blocks missing\n", n_blks); - if (duplist != NULL) { - printf("The following duplicate blocks remain:"); - for (dp = duplist; dp; dp = dp->next) - printf(" %d,", dp->dup); - printf("\n"); - } - if (zlnhead != NULL) { - printf("The following zero link count inodes remain:"); - for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) - printf(" %u,", zlnp->zlncnt); - printf("\n"); - } - } - zlnhead = (struct zlncnt *)0; - duplist = (struct dups *)0; - muldup = (struct dups *)0; - inocleanup(); - if (fsmodified) { - sblock.fs_time = time(NULL); - sbdirty(); - } - if (cvtlevel && sblk.b_dirty) { - /* - * Write out the duplicate super blocks - */ - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) - bwrite(fswritefd, (char *)&sblock, - fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); - } - if (rerun) - resolved = 0; - - /* - * Check to see if the filesystem is mounted read-write. - */ - if (mntbuf != NULL && (mntbuf->f_flags & MNT_RDONLY) == 0) - resolved = 0; - ckfini(resolved); - - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) - if (inostathead[cylno].il_stat != NULL) - free((char *)inostathead[cylno].il_stat); - free((char *)inostathead); - inostathead = NULL; - if (fsmodified && !preen) - printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); - if (rerun) - printf("\n***** PLEASE RERUN FSCK *****\n"); - if (mntbuf != NULL) { - struct ufs_args args; - int ret; - /* - * We modified a mounted filesystem. Do a mount update on - * it unless it is read-write, so we can continue using it - * as safely as possible. - */ - if (mntbuf->f_flags & MNT_RDONLY) { - args.fspec = 0; - args.export.ex_flags = 0; - args.export.ex_root = 0; - ret = mount("ufs", mntbuf->f_mntonname, - mntbuf->f_flags | MNT_UPDATE | MNT_RELOAD, &args); - if (ret == 0) - return (0); - pwarn("mount reload of '%s' failed: %s\n\n", - mntbuf->f_mntonname, strerror(errno)); - } - if (!fsmodified) - return (0); - if (!preen) - printf("\n***** REBOOT NOW *****\n"); - sync(); - return (4); - } - return (0); -} - -/* - * Get the directory that the device is mounted on. - */ -static struct statfs * -getmntpt(name) - const char *name; -{ - struct stat devstat, mntdevstat; - char device[sizeof(_PATH_DEV) - 1 + MNAMELEN]; - char *devname; - struct statfs *mntbuf; - int i, mntsize; - - if (stat(name, &devstat) != 0 || - !(S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))) - return (NULL); - mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); - for (i = 0; i < mntsize; i++) { - if (strcmp(mntbuf[i].f_fstypename, "ufs") != 0) - continue; - devname = mntbuf[i].f_mntfromname; - if (*devname != '/') { - strcpy(device, _PATH_DEV); - strcat(device, devname); - devname = device; - } - if (stat(devname, &mntdevstat) == 0 && - mntdevstat.st_rdev == devstat.st_rdev) - return (&mntbuf[i]); - } - return (NULL); -} |