diff options
-rw-r--r-- | lib/ext2fs/ChangeLog | 7 | ||||
-rw-r--r-- | lib/ext2fs/ext2fs.h | 1 | ||||
-rw-r--r-- | lib/ext2fs/ismounted.c | 47 | ||||
-rw-r--r-- | misc/ChangeLog | 9 | ||||
-rw-r--r-- | misc/badblocks.c | 28 | ||||
-rw-r--r-- | misc/util.c | 25 |
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) |