summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs/main.c
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2001-04-24 22:38:08 +0000
committermckusick <mckusick@FreeBSD.org>2001-04-24 22:38:08 +0000
commitecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f (patch)
tree261472238f24e110d11cd5bf7fc8de94dc83e882 /sbin/fsck_ffs/main.c
parentb92d41b0e964c6163071505bd9fdc9f02b6410fe (diff)
downloadFreeBSD-src-ecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f.zip
FreeBSD-src-ecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f.tar.gz
Add support for the -F flag which determines whether a specified
filesystem needs foreground checking (usually at boot time) or can defer to background checking (after the system is up and running). See the manual page, fsck_ffs(8), for details on the -F and -B options. These options are primarily intended for use by the fsck front end. All output is directed to stdout so that the output is coherent when redirected to a file or a pipe. Unify the code with the fsck front end that allows either a device or a mount point to be specified as the argument to be checked.
Diffstat (limited to 'sbin/fsck_ffs/main.c')
-rw-r--r--sbin/fsck_ffs/main.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index 83bb312..930a4c4 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -63,8 +63,6 @@ static const char rcsid[] =
#include "fsck.h"
-int returntosingle;
-
static void usage __P((void));
static int argtoi __P((int flag, char *req, char *str, int base));
static int docheck __P((struct fstab *fsp));
@@ -84,7 +82,7 @@ main(argc, argv)
sync();
skipclean = 1;
- while ((ch = getopt(argc, argv, "b:Bc:dfm:npy")) != -1) {
+ while ((ch = getopt(argc, argv, "b:Bc:dfFm:npy")) != -1) {
switch (ch) {
case 'b':
skipclean = 0;
@@ -109,6 +107,10 @@ main(argc, argv)
skipclean = 0;
break;
+ case 'F':
+ bkgrdcheck = 1;
+ break;
+
case 'm':
lfmode = argtoi('m', "mode", optarg, 8);
if (lfmode &~ 07777)
@@ -154,7 +156,7 @@ main(argc, argv)
(void)setrlimit(RLIMIT_DATA, &rlimit);
}
while (argc-- > 0)
- (void)checkfilesys(blockcheck(*argv++), 0, 0L, 0);
+ (void)checkfilesys(*argv++, 0, 0L, 0);
if (returntosingle)
ret = 2;
@@ -193,15 +195,46 @@ checkfilesys(filesys, mntpt, auxdata, child)
struct zlncnt *zlnp;
ufs_daddr_t blks;
ufs_daddr_t files;
- int cylno;
+ int cylno, size;
if (preen && child)
(void)signal(SIGQUIT, voidquit);
cdevname = filesys;
if (debug && preen)
pwarn("starting\n");
+ /*
+ * Make best effort to get the disk name. Check first to see
+ * if it is listed among the mounted filesystems. Failing that
+ * check to see if it is listed in /etc/fstab.
+ */
+ mntp = getmntpt(filesys);
+ if (mntp != NULL)
+ filesys = mntp->f_mntfromname;
+ else
+ filesys = blockcheck(filesys);
+ /*
+ * If -F flag specified, check to see whether a background check
+ * is possible and needed. If possible and needed, exit with
+ * status zero. Otherwise exit with status non-zero. A non-zero
+ * exit status will cause a foreground check to be run.
+ */
sblock_init();
-
+ if (bkgrdcheck) {
+ if ((fsreadfd = open(filesys, O_RDONLY)) < 0 || readsb(0) == 0)
+ exit(3); /* Cannot read superblock */
+ close(fsreadfd);
+ if (sblock.fs_flags & FS_NEEDSFSCK)
+ exit(4); /* Earlier background failed */
+ if ((sblock.fs_flags & FS_DOSOFTDEP) == 0)
+ exit(5); /* Not running soft updates */
+ size = MIBSIZE;
+ if (sysctlnametomib("vfs.ffs.adjrefcnt", adjrefcnt, &size) < 0)
+ exit(6); /* Lacks kernel support */
+ if ((mntp == NULL && sblock.fs_clean == 1) ||
+ (mntp != NULL && (sblock.fs_flags & FS_UNCLEAN) == 0))
+ exit(7); /* Filesystem clean, report it now */
+ exit(0);
+ }
/*
* If we are to do a background check:
* Get the mount point information of the filesystem
@@ -209,7 +242,6 @@ checkfilesys(filesys, mntpt, auxdata, child)
* return created snapshot file
* if not found, clear bkgrdflag and proceed with normal fsck
*/
- mntp = getmntpt(filesys);
if (bkgrdflag) {
if (mntp == NULL) {
bkgrdflag = 0;
@@ -432,7 +464,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
}
/*
- * Get the directory that the device is mounted on.
+ * Get the mount point information for name.
*/
static struct statfs *
getmntpt(name)
@@ -441,27 +473,35 @@ getmntpt(name)
struct stat devstat, mntdevstat;
char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
char *devname;
- struct statfs *mntbuf;
- int i, mntsize;
+ struct statfs *mntbuf, *statfsp;
+ int i, mntsize, isdev;
- if (stat(name, &devstat) != 0 ||
- !(S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode)))
+ if (stat(name, &devstat) != 0)
return (NULL);
+ if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
+ isdev = 1;
+ else
+ isdev = 0;
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;
+ statfsp = &mntbuf[i];
+ devname = statfsp->f_mntfromname;
if (*devname != '/') {
strcpy(device, _PATH_DEV);
strcat(device, devname);
- devname = device;
+ strcpy(statfsp->f_mntfromname, device);
+ }
+ if (isdev == 0) {
+ if (strcmp(name, statfsp->f_mntonname))
+ continue;
+ return (statfsp);
}
if (stat(devname, &mntdevstat) == 0 &&
mntdevstat.st_rdev == devstat.st_rdev)
- return (&mntbuf[i]);
+ return (statfsp);
}
- return (NULL);
+ statfsp = NULL;
+ return (statfsp);
}
static void
OpenPOWER on IntegriCloud