summaryrefslogtreecommitdiff
path: root/mount/mount.c
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2010-07-29 14:18:46 +0200
committerKarel Zak <kzak@redhat.com>2010-07-29 16:08:12 +0200
commit4d9f9bdace6e18f1c5dcc242005bf2db9a13d5e6 (patch)
treea405163020d43050deca0df31f48e0cae997745c /mount/mount.c
parent9779651e2b6c06159a583d5852f1a54c000c6c8e (diff)
downloadutil-linux-old-4d9f9bdace6e18f1c5dcc242005bf2db9a13d5e6.tar.gz
mount: fix "mount -a" for auto-clear loopdevs and /proc/mounts
The "mount -a" uses /etc/mtab to detect already mounted file systems from /etc/fstab -- this check requires the same FS name (1st field) in fstab and mtab. On systems with enabled auto-clear loop devies or systems without regular mtab (symlink to /proc/mounts) there is /dev/loopN rather than image filename in mtab. For example: fstab: /mnt/store/foo.ISO /mnt/image auto defaults 0 0 mtab: /dev/loop0 /mnt/image iso9960 rw 0 0 We have to scan all available loop devices to check if some of the devices is not associated with the image file from fstab. Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=618957 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'mount/mount.c')
-rw-r--r--mount/mount.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/mount/mount.c b/mount/mount.c
index fef1a852..433941e1 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -1821,6 +1821,41 @@ mounted (const char *spec0, const char *node0) {
return ret;
}
+/* returns 0 if not mounted, 1 if mounted and -1 in case of error */
+static int
+is_fstab_entry_mounted(struct mntentchn *mc, int verbose)
+{
+ struct stat st;
+
+ if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
+ goto yes;
+
+ /* extra care for loop devices */
+ if ((strstr(mc->m.mnt_opts, "loop=") ||
+ (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode)))) {
+
+ char *p = strstr(mc->m.mnt_opts, "offset=");
+ uintmax_t offset = 0;
+
+ if (p && strtosize(p + 7, &offset) != 0) {
+ if (verbose)
+ printf(_("mount: ignore %s "
+ "(unparsable offset= option)\n"),
+ mc->m.mnt_fsname);
+ return -1;
+ }
+ if (is_mounted_same_loopfile(mc->m.mnt_dir, mc->m.mnt_fsname, offset))
+ goto yes;
+ }
+
+ return 0;
+yes:
+ if (verbose)
+ printf(_("mount: %s already mounted on %s\n"),
+ mc->m.mnt_fsname, mc->m.mnt_dir);
+ return 1;
+}
+
/* avoid using stat() on things we are not going to mount anyway.. */
static int
has_noauto (const char *opts) {
@@ -1866,16 +1901,8 @@ do_mount_all (char *types, char *options, char *test_opts) {
if (matching_type (mc->m.mnt_type, types)
&& matching_opts (mc->m.mnt_opts, test_opts)
&& !streq (mc->m.mnt_dir, "/")
- && !streq (mc->m.mnt_dir, "root")) {
-
- if (mounted (mc->m.mnt_fsname, mc->m.mnt_dir)) {
- if (verbose)
- printf(_("mount: %s already mounted "
- "on %s\n"),
- mc->m.mnt_fsname,
- mc->m.mnt_dir);
- continue;
- }
+ && !streq (mc->m.mnt_dir, "root")
+ && !is_fstab_entry_mounted(mc, verbose)) {
mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));
*mtmp = *mc;