mirror of https://github.com/vitalif/e2fsprogs
Make fsck ignore mounted filesystems if given the -M option
Adapted from the SuSE patch, but fixes a number of very serious problems with the patch in SLES: 1) This changeset uses -M instead of -m; most lowercase options are reserved for use by the filesystem-specific fsck programs. All new fsck options must be upper case. 2) This changeset will skip the root filesystem in "fsck -AM", which the SLES patch will not do. 3) Loading /proc/mounts into the fs_info can cause -t opts matching to malfuction. So this changeset uses a simplified version of the ismounted.c function from the ext2fs library. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>bitmap-optimize
parent
e7cc6f7d0b
commit
fe263da923
|
@ -40,7 +40,7 @@ UUIDD_OBJS= uuidd.o
|
|||
DUMPE2FS_OBJS= dumpe2fs.o
|
||||
BADBLOCKS_OBJS= badblocks.o
|
||||
E2IMAGE_OBJS= e2image.o
|
||||
FSCK_OBJS= fsck.o base_device.o
|
||||
FSCK_OBJS= fsck.o base_device.o ismounted.o
|
||||
BLKID_OBJS= blkid.o
|
||||
FILEFRAG_OBJS= filefrag.o
|
||||
|
||||
|
@ -51,7 +51,7 @@ SRCS= $(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c \
|
|||
$(srcdir)/badblocks.c $(srcdir)/fsck.c $(srcdir)/util.c \
|
||||
$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
|
||||
$(srcdir)/filefrag.c $(srcdir)/base_device.c \
|
||||
$(srcdir)/../e2fsck/profile.c
|
||||
$(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c
|
||||
|
||||
LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
|
||||
DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
|
||||
|
@ -173,6 +173,10 @@ filefrag: $(FILEFRAG_OBJS)
|
|||
@echo " LD $@"
|
||||
@$(CC) $(ALL_LDFLAGS) -o filefrag $(FILEFRAG_OBJS)
|
||||
|
||||
tst_ismounted: $(srcdir)/ismounted.c $(STATIC_LIBEXT2FS)
|
||||
@echo " LD $@"
|
||||
$(CC) -o tst_ismounted $(srcdir)/ismounted.c -DDEBUG $(ALL_CFLAGS) $(LIBCOM_ERR)
|
||||
|
||||
tune2fs.8: $(DEP_SUBSTITUTE) $(srcdir)/tune2fs.8.in
|
||||
@echo " SUBST $@"
|
||||
@$(SUBSTITUTE_UPTIME) $(srcdir)/tune2fs.8.in tune2fs.8
|
||||
|
@ -368,7 +372,7 @@ clean:
|
|||
$(FMANPAGES) \
|
||||
base_device base_device.out mke2fs.static filefrag \
|
||||
e2initrd_helper partinfo prof_err.[ch] default_profile.c \
|
||||
uuidd e2image \#* *.s *.o *.a *~ core
|
||||
uuidd e2image tst_ismounted \#* *.s *.o *.a *~ core
|
||||
|
||||
mostlyclean: clean
|
||||
distclean: clean
|
||||
|
@ -444,5 +448,6 @@ blkid.o: $(srcdir)/blkid.c $(top_srcdir)/lib/blkid/blkid.h \
|
|||
logsave.o: $(srcdir)/logsave.c
|
||||
filefrag.o: $(srcdir)/filefrag.c
|
||||
base_device.o: $(srcdir)/base_device.c $(srcdir)/fsck.h
|
||||
ismounted.o: $(srcdir)/ismounted.c $(top_srcdir)/lib/et/com_err.h
|
||||
profile.o: $(srcdir)/../e2fsck/profile.c $(top_srcdir)/lib/et/com_err.h \
|
||||
$(srcdir)/../e2fsck/profile.h prof_err.h
|
||||
|
|
|
@ -8,7 +8,7 @@ fsck \- check and repair a Linux file system
|
|||
.SH SYNOPSIS
|
||||
.B fsck
|
||||
[
|
||||
.B \-sAVRTNP
|
||||
.B \-sAVRTMNP
|
||||
]
|
||||
[
|
||||
.B \-C
|
||||
|
@ -233,6 +233,10 @@ a progress bar at a time. GUI front-ends may specify a file descriptor
|
|||
.IR fd ,
|
||||
in which case the progress bar information will be sent to that file descriptor.
|
||||
.TP
|
||||
.B \-M
|
||||
Do not check mounted filesystems and return an exit code of 0
|
||||
for mounted filesystems.
|
||||
.TP
|
||||
.B \-N
|
||||
Don't execute, just show what would be done.
|
||||
.TP
|
||||
|
|
15
misc/fsck.c
15
misc/fsck.c
|
@ -102,7 +102,7 @@ int doall = 0;
|
|||
int noexecute = 0;
|
||||
int serialize = 0;
|
||||
int skip_root = 0;
|
||||
int like_mount = 0;
|
||||
int ignore_mounted = 0;
|
||||
int notitle = 0;
|
||||
int parallel_root = 0;
|
||||
int progress = 0;
|
||||
|
@ -973,7 +973,8 @@ static int check_all(NOARGS)
|
|||
break;
|
||||
}
|
||||
if (fs) {
|
||||
if (!skip_root && !ignore(fs)) {
|
||||
if (!skip_root && !ignore(fs) &&
|
||||
!(ignore_mounted && is_mounted(fs->device))) {
|
||||
fsck_device(fs, 1);
|
||||
status |= wait_many(FLAG_WAIT_ALL);
|
||||
if (status > EXIT_NONDESTRUCT)
|
||||
|
@ -1009,6 +1010,10 @@ static int check_all(NOARGS)
|
|||
not_done_yet++;
|
||||
continue;
|
||||
}
|
||||
if (ignore_mounted && is_mounted(fs->device)) {
|
||||
fs->flags |= FLAG_DONE;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If a filesystem on a particular device has
|
||||
* already been spawned, then we need to defer
|
||||
|
@ -1058,7 +1063,7 @@ static int check_all(NOARGS)
|
|||
|
||||
static void usage(NOARGS)
|
||||
{
|
||||
fputs(_("Usage: fsck [-ANPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr);
|
||||
fputs(_("Usage: fsck [-AMNPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr);
|
||||
exit(EXIT_USAGE);
|
||||
}
|
||||
|
||||
|
@ -1181,7 +1186,7 @@ static void PRS(int argc, char *argv[])
|
|||
notitle++;
|
||||
break;
|
||||
case 'M':
|
||||
like_mount++;
|
||||
ignore_mounted++;
|
||||
break;
|
||||
case 'P':
|
||||
parallel_root++;
|
||||
|
@ -1303,6 +1308,8 @@ int main(int argc, char *argv[])
|
|||
if (!fs)
|
||||
continue;
|
||||
}
|
||||
if (ignore_mounted && is_mounted(fs->device))
|
||||
continue;
|
||||
fsck_device(fs, interactive);
|
||||
if (serialize ||
|
||||
(max_running && (num_running >= max_running))) {
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* ismounted.c --- Check to see if the filesystem was mounted
|
||||
*
|
||||
* Copyright (C) 1995,1996,1997,1998,1999,2000,2008 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_LINUX_FD_H
|
||||
#include <linux/fd.h>
|
||||
#endif
|
||||
#ifdef HAVE_MNTENT_H
|
||||
#include <mntent.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*
|
||||
* ext2fs_check_if_mounted flags
|
||||
*/
|
||||
#define MF_MOUNTED 1
|
||||
|
||||
#include "et/com_err.h"
|
||||
|
||||
static char *skip_over_blank(char *cp)
|
||||
{
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static char *skip_over_word(char *cp)
|
||||
{
|
||||
while (*cp && !isspace(*cp))
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static char *parse_word(char **buf)
|
||||
{
|
||||
char *word, *next;
|
||||
|
||||
word = *buf;
|
||||
if (*word == 0)
|
||||
return 0;
|
||||
|
||||
word = skip_over_blank(word);
|
||||
next = skip_over_word(word);
|
||||
if (*next)
|
||||
*next++ = 0;
|
||||
*buf = next;
|
||||
return word;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function which checks a file in /etc/mtab format to see if a
|
||||
* filesystem is mounted. Returns an error if the file doesn't exist
|
||||
* or can't be opened.
|
||||
*/
|
||||
static errcode_t check_mntent_file(const char *mtab_file, const char *file,
|
||||
int *mount_flags)
|
||||
{
|
||||
struct stat st_buf;
|
||||
errcode_t retval = 0;
|
||||
dev_t file_dev=0, file_rdev=0;
|
||||
ino_t file_ino=0;
|
||||
FILE *f;
|
||||
char buf[1024], *device = 0, *mnt_dir = 0, *cp;
|
||||
int fd;
|
||||
|
||||
*mount_flags = 0;
|
||||
if ((f = fopen(mtab_file, "r")) == NULL)
|
||||
return errno;
|
||||
|
||||
if ((f = setmntent (mtab_file, "r")) == NULL)
|
||||
return errno;
|
||||
if (stat(file, &st_buf) == 0) {
|
||||
if (S_ISBLK(st_buf.st_mode)) {
|
||||
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
|
||||
file_rdev = st_buf.st_rdev;
|
||||
#endif /* __GNU__ */
|
||||
} else {
|
||||
file_dev = st_buf.st_dev;
|
||||
file_ino = st_buf.st_ino;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
if (!fgets(buf, sizeof(buf), f)) {
|
||||
device = mnt_dir = 0;
|
||||
break;
|
||||
}
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
|
||||
cp = buf;
|
||||
device = parse_word(&cp);
|
||||
if (!device || *device == '#')
|
||||
return 0; /* Ignore blank lines and comments */
|
||||
mnt_dir = parse_word(&cp);
|
||||
|
||||
if (device[0] != '/')
|
||||
continue;
|
||||
|
||||
if (strcmp(file, device) == 0)
|
||||
break;
|
||||
if (stat(device, &st_buf) == 0) {
|
||||
if (S_ISBLK(st_buf.st_mode)) {
|
||||
#ifndef __GNU__
|
||||
if (file_rdev && (file_rdev == st_buf.st_rdev))
|
||||
break;
|
||||
#endif /* __GNU__ */
|
||||
} else {
|
||||
if (file_dev && ((file_dev == st_buf.st_dev) &&
|
||||
(file_ino == st_buf.st_ino)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mnt_dir == 0) {
|
||||
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
|
||||
/*
|
||||
* Do an extra check to see if this is the root device. We
|
||||
* can't trust /etc/mtab, and /proc/mounts will only list
|
||||
* /dev/root for the root filesystem. Argh. Instead we
|
||||
* check if the given device has the same major/minor number
|
||||
* as the device that the root directory is on.
|
||||
*/
|
||||
if (file_rdev && (stat("/", &st_buf) == 0) &&
|
||||
(st_buf.st_dev == file_rdev))
|
||||
*mount_flags = MF_MOUNTED;
|
||||
#endif /* __GNU__ */
|
||||
goto errout;
|
||||
}
|
||||
#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
|
||||
/* Validate the entry in case /etc/mtab is out of date */
|
||||
/*
|
||||
* We need to be paranoid, because some broken distributions
|
||||
* (read: Slackware) don't initialize /etc/mtab before checking
|
||||
* all of the non-root filesystems on the disk.
|
||||
*/
|
||||
if (stat(mnt_dir, &st_buf) < 0) {
|
||||
retval = errno;
|
||||
if (retval == ENOENT) {
|
||||
#ifdef DEBUG
|
||||
printf("Bogus entry in %s! (%s does not exist)\n",
|
||||
mtab_file, mnt_dir);
|
||||
#endif /* DEBUG */
|
||||
retval = 0;
|
||||
}
|
||||
goto errout;
|
||||
}
|
||||
if (file_rdev && (st_buf.st_dev != file_rdev)) {
|
||||
#ifdef DEBUG
|
||||
printf("Bogus entry in %s! (%s not mounted on %s)\n",
|
||||
mtab_file, file, mnt_dir);
|
||||
#endif /* DEBUG */
|
||||
goto errout;
|
||||
}
|
||||
#endif /* __GNU__ */
|
||||
*mount_flags = MF_MOUNTED;
|
||||
|
||||
retval = 0;
|
||||
errout:
|
||||
endmntent (f);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int is_mounted(const char *file)
|
||||
{
|
||||
errcode_t retval;
|
||||
int mount_flags = 0;
|
||||
|
||||
#ifdef __linux__
|
||||
retval = check_mntent_file("/proc/mounts", file, &mount_flags);
|
||||
if (retval)
|
||||
return 0;
|
||||
if (mount_flags)
|
||||
return 1;
|
||||
#endif /* __linux__ */
|
||||
retval = check_mntent_file("/etc/mtab", file, &mount_flags);
|
||||
if (retval)
|
||||
return 0;
|
||||
return (mount_flags);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s device\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (is_mounted(argv[1]))
|
||||
printf("\t%s is mounted.\n", argv[1]);
|
||||
exit(0);
|
||||
}
|
||||
#endif /* DEBUG */
|
Loading…
Reference in New Issue