Whamcloud - gitweb
On Linux 2.6 systems, mke2fs and badblocks will check to see whether
authorTheodore Ts'o <tytso@mit.edu>
Sun, 5 Jun 2005 20:05:22 +0000 (16:05 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 5 Jun 2005 20:05:22 +0000 (16:05 -0400)
the filesystem appears to be busy; if so, the programs will print an
error message and abort.   (Addresses Debian Bug #308594).

lib/ext2fs/ChangeLog
lib/ext2fs/ext2fs.h
lib/ext2fs/ismounted.c
misc/ChangeLog
misc/badblocks.c
misc/util.c

index 1b17575..4e83f4c 100644 (file)
@@ -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
index 0832bc2..33ccf67 100644 (file)
@@ -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
index 3f2241d..5d32de0 100644 (file)
@@ -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 */
index 1b2826e..b90715d 100644 (file)
@@ -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
index 00016e5..9a6acdf 100644 (file)
@@ -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);
+
 }
 
 
index 77359c8..a08a8dd 100644 (file)
@@ -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)