From 27dedba28cd971389baf9dc55dc34475e9ddcf57 Mon Sep 17 00:00:00 2001 From: adrian Date: Mon, 9 Oct 2000 10:26:15 +0000 Subject: .. fsck wrappers aftercommit #1: I don't know how these files got lost, but they did. Oops. --- sbin/fsck/fsck.8 | 123 +++++++++++++++++++ sbin/fsck/preen.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 467 insertions(+) create mode 100644 sbin/fsck/fsck.8 create mode 100644 sbin/fsck/preen.c (limited to 'sbin/fsck') diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8 new file mode 100644 index 0000000..a4ec5f5 --- /dev/null +++ b/sbin/fsck/fsck.8 @@ -0,0 +1,123 @@ +.\" $NetBSD: fsck.8,v 1.19 1999/03/10 00:08:33 erh Exp $ +.\" $FreeBSD$ +.\" +.\" Copyright (c) 1996 Christos Zoulas. 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 Christos Zoulas. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.Dd September 23, 1996 +.Dt FSCK 8 +.Os NetBSD 1 +.Sh NAME +.Nm fsck +.Nd file system consistency check and interactive repair +.Sh SYNOPSIS +.Nm "" +.Op Fl dvplfyn +.Op Fl l Ar maxparallel +.Op Fl t Ar fstype +.Op Fl T Ar fstype:fsoptions +.Op special | node ... +.Sh DESCRIPTION +The +.Nm +command invokes filesystem-specific programs to check +the special devices listed in the +.Xr fstab 5 +file or in the command line for consistency. +.Pp +It is normally used in the script +.Pa /etc/rc +during automatic reboot. +If no filesystems are specified, and ``preen'' mode is enabled ( +.Fl p +option) +.Nm +reads the table +.Pa /etc/fstab +to determine which filesystems to check. +Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro'' +and that have non-zero pass number are checked. +Filesystems with pass number 1 (normally just the root filesystem) +are checked one at a time. +When pass 1 completes, all remaining filesystems are checked, +running one process per disk drive. +The disk drive containing each filesystem is inferred from the longest prefix +of the device name that ends in a digit; the remaining characters are assumed +to be the partition designator. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl d +Debugging mode. Just print the commands without executing them. Available +only if +.Nm +is compiled to support it. +.It Fl f +Force checking of filesystems, even when they are marked clean (for filesystems +that support this). +.It Fl l Ar maxparallel +Limit the number of parallel checks to the number specified in +the following argument. By default, the limit is the number of +disks, running one process per disk. If a smaller limit is giv- +en, the disks are checked round-robin, one filesystem at a time. +.It Fl n +Causes +.Nm +to assume no as the answer to all operator questions, except "CONTINUE?". +.It Fl p +Enter preen mode. +.It Fl t Ar fstype +Invoke +.Nm +only for the comma separated list of filesystem types. If the +list starts with +.Dq no +then invoke +.Nm +for the filesystem types that are not specified in the list. +.It Fl v +Print the commands before executing them. +.It Fl y +Causes +.Nm +to assume yes +as the answer to all operator questions. +.It Fl T Ar fstype:fsoptions +List of comma separated file system specific options for the specified +file system type, in the same format as +.Xr mount 8 . +.El +.Sh FILES +.Bl -tag -width /etc/fstab -compact +.It Pa /etc/fstab +file system table +.El +.Sh SEE ALSO +.Xr mount 8 , +.Xr fstab 5 , +.Xr fsck_msdos 8 , +.Xr fsck_ffs 8 diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c new file mode 100644 index 0000000..1275ab7 --- /dev/null +++ b/sbin/fsck/preen.c @@ -0,0 +1,344 @@ +/* $NetBSD: preen.c,v 1.18 1998/07/26 20:02:36 mycroft Exp $ */ + +/* + * Copyright (c) 1990, 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. + * + * $FreeBSD$ + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: preen.c,v 1.18 1998/07/26 20:02:36 mycroft Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "fsutil.h" + +struct partentry { + TAILQ_ENTRY(partentry) p_entries; + char *p_devname; /* device name */ + char *p_mntpt; /* mount point */ + char *p_type; /* filesystem type */ + void *p_auxarg; /* auxiliary argument */ +}; + +TAILQ_HEAD(part, partentry) badh; + +struct diskentry { + TAILQ_ENTRY(diskentry) d_entries; + char *d_name; /* disk base name */ + TAILQ_HEAD(prt, partentry) d_part; /* list of partitions on disk */ + int d_pid; /* 0 or pid of fsck proc */ +}; + +TAILQ_HEAD(disk, diskentry) diskh; + +static int nrun = 0, ndisks = 0; + +static struct diskentry *finddisk __P((const char *)); +static void addpart __P((const char *, const char *, const char *, void *)); +static int startdisk __P((struct diskentry *, + int (*)(const char *, const char *, const char *, void *, pid_t *))); +static void printpart __P((void)); + +int +checkfstab(flags, maxrun, docheck, checkit) + int flags, maxrun; + void *(*docheck) __P((struct fstab *)); + int (*checkit) __P((const char *, const char *, const char *, void *, + pid_t *)); +{ + struct fstab *fs; + struct diskentry *d, *nextdisk; + struct partentry *p; + int ret, pid, retcode, passno, sumstatus, status; + void *auxarg; + const char *name; + + TAILQ_INIT(&badh); + TAILQ_INIT(&diskh); + + sumstatus = 0; + + for (passno = 1; passno <= 2; passno++) { + if (setfsent() == 0) { + warnx("Can't open checklist file: %s\n", _PATH_FSTAB); + return (8); + } + while ((fs = getfsent()) != 0) { + if ((auxarg = (*docheck)(fs)) == NULL) + continue; + + /* XXX We don't need to search for blockdevs .. */ + /* name = blockcheck(fs->fs_spec); */ + name = fs->fs_spec; + if (flags & CHECK_DEBUG) + printf("pass %d, name %s\n", passno, name); + + if ((flags & CHECK_PREEN) == 0 || + (passno == 1 && fs->fs_passno == 1)) { + if (name == NULL) { + if (flags & CHECK_PREEN) + return 8; + else + continue; + } + sumstatus = (*checkit)(fs->fs_vfstype, + name, fs->fs_file, auxarg, NULL); + + if (sumstatus) + return (sumstatus); + } else if (passno == 2 && fs->fs_passno > 1) { + if (name == NULL) { + (void) fprintf(stderr, + "BAD DISK NAME %s\n", fs->fs_spec); + sumstatus |= 8; + continue; + } + addpart(fs->fs_vfstype, name, fs->fs_file, + auxarg); + } + } + if ((flags & CHECK_PREEN) == 0) + return 0; + } + + if (flags & CHECK_DEBUG) + printpart(); + + if (flags & CHECK_PREEN) { + if (maxrun == 0) + maxrun = ndisks; + if (maxrun > ndisks) + maxrun = ndisks; + nextdisk = diskh.tqh_first; + for (passno = 0; passno < maxrun; ++passno) { + if ((ret = startdisk(nextdisk, checkit)) != 0) + return ret; + nextdisk = nextdisk->d_entries.tqe_next; + } + + while ((pid = wait(&status)) != -1) { + for (d = diskh.tqh_first; d; d = d->d_entries.tqe_next) + if (d->d_pid == pid) + break; + + if (d == NULL) { + warnx("Unknown pid %d\n", pid); + continue; + } + + + if (WIFEXITED(status)) + retcode = WEXITSTATUS(status); + else + retcode = 0; + + p = d->d_part.tqh_first; + + if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) + (void) printf("done %s: %s (%s) = 0x%x\n", + p->p_type, p->p_devname, p->p_mntpt, + status); + + if (WIFSIGNALED(status)) { + (void) fprintf(stderr, + "%s: %s (%s): EXITED WITH SIGNAL %d\n", + p->p_type, p->p_devname, p->p_mntpt, + WTERMSIG(status)); + retcode = 8; + } + + TAILQ_REMOVE(&d->d_part, p, p_entries); + + if (retcode != 0) { + TAILQ_INSERT_TAIL(&badh, p, p_entries); + sumstatus |= retcode; + } else { + free(p->p_type); + free(p->p_devname); + free(p); + } + d->d_pid = 0; + nrun--; + + if (d->d_part.tqh_first == NULL) + ndisks--; + + if (nextdisk == NULL) { + if (d->d_part.tqh_first) { + if ((ret = startdisk(d, checkit)) != 0) + return ret; + } + } else if (nrun < maxrun && nrun < ndisks) { + for ( ;; ) { + nextdisk = nextdisk->d_entries.tqe_next; + if (nextdisk == NULL) + nextdisk = diskh.tqh_first; + if (nextdisk->d_part.tqh_first != NULL + && nextdisk->d_pid == 0) + break; + } + if ((ret = startdisk(nextdisk, checkit)) != 0) + return ret; + } + } + } + if (sumstatus) { + p = badh.tqh_first; + if (p == NULL) + return (sumstatus); + + (void) fprintf(stderr, + "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t", + p->p_entries.tqe_next ? "S" : "", + "UNEXPECTED INCONSISTENCY:"); + + for (; p; p = p->p_entries.tqe_next) + (void) fprintf(stderr, + "%s: %s (%s)%s", p->p_type, p->p_devname, + p->p_mntpt, p->p_entries.tqe_next ? ", " : "\n"); + + return sumstatus; + } + (void) endfsent(); + return (0); +} + + +static struct diskentry * +finddisk(name) + const char *name; +{ + const char *p; + size_t len = 0; + struct diskentry *d; + + for (len = strlen(name), p = name + len - 1; p >= name; --p) + if (isdigit(*p)) { + len = p - name + 1; + break; + } + if (p < name) + len = strlen(name); + + for (d = diskh.tqh_first; d != NULL; d = d->d_entries.tqe_next) + if (strncmp(d->d_name, name, len) == 0 && d->d_name[len] == 0) + return d; + + d = emalloc(sizeof(*d)); + d->d_name = estrdup(name); + d->d_name[len] = '\0'; + TAILQ_INIT(&d->d_part); + d->d_pid = 0; + + TAILQ_INSERT_TAIL(&diskh, d, d_entries); + ndisks++; + + return d; +} + + +static void +printpart() +{ + struct diskentry *d; + struct partentry *p; + + for (d = diskh.tqh_first; d != NULL; d = d->d_entries.tqe_next) { + (void) printf("disk %s: ", d->d_name); + for (p = d->d_part.tqh_first; p != NULL; + p = p->p_entries.tqe_next) + (void) printf("%s ", p->p_devname); + (void) printf("\n"); + } +} + + +static void +addpart(type, devname, mntpt, auxarg) + const char *type, *devname, *mntpt; + void *auxarg; +{ + struct diskentry *d = finddisk(devname); + struct partentry *p; + + for (p = d->d_part.tqh_first; p != NULL; p = p->p_entries.tqe_next) + if (strcmp(p->p_devname, devname) == 0) { + warnx("%s in fstab more than once!\n", devname); + return; + } + + p = emalloc(sizeof(*p)); + p->p_devname = estrdup(devname); + p->p_mntpt = estrdup(mntpt); + p->p_type = estrdup(type); + p->p_auxarg = auxarg; + + TAILQ_INSERT_TAIL(&d->d_part, p, p_entries); +} + + +static int +startdisk(d, checkit) + struct diskentry *d; + int (*checkit) __P((const char *, const char *, const char *, void *, + pid_t *)); +{ + struct partentry *p = d->d_part.tqh_first; + int rv; + + while ((rv = (*checkit)(p->p_type, p->p_devname, p->p_mntpt, + p->p_auxarg, &d->d_pid)) != 0 && nrun > 0) + sleep(10); + + if (rv == 0) + nrun++; + + return rv; +} -- cgit v1.1