diff options
author | Karel Zak <kzak@redhat.com> | 2010-07-29 14:18:46 +0200 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2010-07-29 16:08:12 +0200 |
commit | 4d9f9bdace6e18f1c5dcc242005bf2db9a13d5e6 (patch) | |
tree | a405163020d43050deca0df31f48e0cae997745c /mount/mount.c | |
parent | 9779651e2b6c06159a583d5852f1a54c000c6c8e (diff) | |
download | util-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.c | 47 |
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; |