summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2005-06-05 16:05:22 -0400
committerTheodore Ts'o <tytso@mit.edu>2005-06-05 16:05:22 -0400
commit2fa8f37ffff4687228d9f204062f2d27b0e5b919 (patch)
tree00cc7f21dd2f3c05b956990ea84322c02013dc8c
parent8198e7912663eb13680391979bfb6177f478e9e0 (diff)
downloade2fsprogs-2fa8f37ffff4687228d9f204062f2d27b0e5b919.tar.gz
On Linux 2.6 systems, mke2fs and badblocks will check to see whether
the filesystem appears to be busy; if so, the programs will print an error message and abort. (Addresses Debian Bug #308594).
-rw-r--r--lib/ext2fs/ChangeLog7
-rw-r--r--lib/ext2fs/ext2fs.h1
-rw-r--r--lib/ext2fs/ismounted.c47
-rw-r--r--misc/ChangeLog9
-rw-r--r--misc/badblocks.c28
-rw-r--r--misc/util.c25
6 files changed, 86 insertions, 31 deletions
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index 1b175758..4e83f4c1 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,10 @@
+2005-05-29 Theodore Ts'o <tytso@mit.edu>
+
+ * ismounted.c (ext2fs_check_mount_point): Add test to see if the
+ device appears to be busy; this only works on Linux 2.6+
+ systems, but provides some additional bullet-proofing in
+ those cases.
+
2005-05-08 Theodore Ts'o <tytso@mit.edu>
* test_io.c (safe_getenv): Fix bug so it would fetch the right
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 0832bc28..33ccf677 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -346,6 +346,7 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan;
#define EXT2_MF_ISROOT 2
#define EXT2_MF_READONLY 4
#define EXT2_MF_SWAP 8
+#define EXT2_MF_BUSY 16
/*
* Ext2/linux mode flags. We define them here so that we don't need
diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c
index 3f2241d2..5d32de0d 100644
--- a/lib/ext2fs/ismounted.c
+++ b/lib/ext2fs/ismounted.c
@@ -278,10 +278,12 @@ static int is_swap_device(const char *file)
/*
- * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
- * otherwise. If mtpt is non-NULL, the directory where the device is
- * mounted is copied to where mtpt is pointing, up to mtlen
- * characters.
+ * ext2fs_check_mount_point() fills determines if the device is
+ * mounted or otherwise busy, and fills in mount_flags with one or
+ * more of the following flags: EXT2_MF_MOUNTED, EXT2_MF_ISROOT,
+ * EXT2_MF_READONLY, EXT2_MF_SWAP, and EXT2_MF_BUSY. If mtpt is
+ * non-NULL, the directory where the device is mounted is copied to
+ * where mtpt is pointing, up to mtlen characters.
*/
#ifdef __TURBOC__
#pragma argsused
@@ -289,24 +291,43 @@ static int is_swap_device(const char *file)
errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
char *mtpt, int mtlen)
{
+ struct stat st_buf;
+ errcode_t retval = 0;
+ int fd;
+
if (is_swap_device(device)) {
*mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP;
strncpy(mtpt, "<swap>", mtlen);
- return 0;
- }
+ } else {
#ifdef HAVE_MNTENT_H
- return check_mntent(device, mount_flags, mtpt, mtlen);
+ retval = check_mntent(device, mount_flags, mtpt, mtlen);
#else
#ifdef HAVE_GETMNTINFO
- return check_getmntinfo(device, mount_flags, mtpt, mtlen);
+ retval = check_getmntinfo(device, mount_flags, mtpt, mtlen);
#else
#ifdef __GNUC__
#warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
#endif
- *mount_flags = 0;
- return 0;
+ *mount_flags = 0;
#endif /* HAVE_GETMNTINFO */
#endif /* HAVE_MNTENT_H */
+ }
+ if (retval)
+ return retval;
+
+#ifdef __linux__ /* This only works on Linux 2.6+ systems */
+ if ((stat(device, &st_buf) != 0) ||
+ !S_ISBLK(st_buf.st_mode))
+ return 0;
+ fd = open(device, O_RDONLY | O_EXCL);
+ if (fd < 0) {
+ if (errno == EBUSY)
+ *mount_flags |= EXT2_MF_BUSY;
+ } else
+ close(fd);
+
+ return 0;
+#endif
}
/*
@@ -339,20 +360,18 @@ int main(int argc, char **argv)
exit(1);
}
printf("Device %s reports flags %02x\n", argv[1], mount_flags);
+ if (mount_flags & EXT2_MF_BUSY)
+ printf("\t%s is apparently in use.\n", argv[1]);
if (mount_flags & EXT2_MF_MOUNTED)
printf("\t%s is mounted.\n", argv[1]);
-
if (mount_flags & EXT2_MF_SWAP)
printf("\t%s is a swap device.\n", argv[1]);
-
if (mount_flags & EXT2_MF_READONLY)
printf("\t%s is read-only.\n", argv[1]);
-
if (mount_flags & EXT2_MF_ISROOT)
printf("\t%s is the root filesystem.\n", argv[1]);
if (mntpt[0])
printf("\t%s is mounted on %s.\n", argv[1], mntpt);
-
exit(0);
}
#endif /* DEBUG */
diff --git a/misc/ChangeLog b/misc/ChangeLog
index 1b2826e5..b90715dd 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,3 +1,12 @@
+2005-05-29 Theodore Ts'o <tytso@mit.edu>
+
+ * util.c (check_mount): Check the new EXT2_MF_BUSY flag to
+ see if the device is in use by the system.
+
+ * badblocks.c (check_mount): Check the new EXT2_MF_BUSY flag to
+ see if the device is in use by the system. (Works only
+ for Linux 2.6 systems, addresses Debian Bug #308594).
+
2005-05-20 Theodore Ts'o <tytso@mit.edu>
* filefrag.c (frag_report, get_bmap): The FIBMAP and FIGETBSZ
diff --git a/misc/badblocks.c b/misc/badblocks.c
index 00016e5b..9a6acdfa 100644
--- a/misc/badblocks.c
+++ b/misc/badblocks.c
@@ -780,17 +780,27 @@ static void check_mount(char *device_name)
device_name);
return;
}
- if (!(mount_flags & EXT2_MF_MOUNTED))
- return;
+ if (mount_flags & EXT2_MF_MOUNTED) {
+ fprintf(stderr, _("%s is mounted; "), device_name);
+ if (force) {
+ fputs(_("badblocks forced anyway. "
+ "Hope /etc/mtab is incorrect.\n"), stderr);
+ return;
+ }
+ abort_badblocks:
+ fputs(_("it's not safe to run badblocks!\n"), stderr);
+ exit(1);
+ }
- fprintf(stderr, _("%s is mounted; "), device_name);
- if (force) {
- fputs(_("badblocks forced anyway. "
- "Hope /etc/mtab is incorrect.\n"), stderr);
- return;
+ if (mount_flags & EXT2_MF_BUSY) {
+ fprintf(stderr, _("%s is apparently in use by the system; "),
+ device_name);
+ if (force)
+ fputs(_("badblocks forced anyway.\n"), stderr);
+ else
+ goto abort_badblocks;
}
- fputs(_("it's not safe to run badblocks!\n"), stderr);
- exit(1);
+
}
diff --git a/misc/util.c b/misc/util.c
index 77359c84..a08a8dd6 100644
--- a/misc/util.c
+++ b/misc/util.c
@@ -152,17 +152,26 @@ void check_mount(const char *device, int force, const char *type)
device);
return;
}
- if (!(mount_flags & EXT2_MF_MOUNTED))
- return;
-
- fprintf(stderr, _("%s is mounted; "), device);
- if (force) {
- fputs(_("mke2fs forced anyway. Hope /etc/mtab is "
- "incorrect.\n"), stderr);
- } else {
+ if (mount_flags & EXT2_MF_MOUNTED) {
+ fprintf(stderr, _("%s is mounted; "), device);
+ if (force) {
+ fputs(_("mke2fs forced anyway. Hope /etc/mtab is "
+ "incorrect.\n"), stderr);
+ return;
+ }
+ abort_mke2fs:
fprintf(stderr, _("will not make a %s here!\n"), type);
exit(1);
}
+ if (mount_flags & EXT2_MF_BUSY) {
+ fprintf(stderr, _("%s is apparently in use by the system; "),
+ device);
+ if (force) {
+ fputs(_("mke2fs forced anyway.\n"), stderr);
+ return;
+ }
+ goto abort_mke2fs;
+ }
}
void parse_journal_opts(const char *opts)