On Fri, Sep 07, 2007 at 12:40:24PM +0200, Matthias Koenig wrote: > Karel Zak <kzak@xxxxxxxxxx> writes: > > >> # mount -oloop /tmp/volume /mnt/ > >> # mount -oloop /tmp/volume /mnt/ > >> # mount > >> /tmp/volume on /mnt type ext2 (rw,loop=/dev/loop0) > >> /tmp/volume on /mnt type ext2 (rw,loop=/dev/loop1) > > > > I know about this problem and it's "fixed" in Fedora util-linux > > package (almost for two years)... > > Ah thanks, I did not realize this patch. I'm not proud of this old patch. See below... There is not support for offsets (and lo_node of course). > > Doesn't have kernel all information? Why this is not disabled by > > kernel? Why this issues should be resolved by an userspace util when > > kernel supports it? Is it real problem for all filesystems? Doesn't > > exist same issue with multipath devices (SANs)? > > Good point. I am really not sure if setting up two loop devices with > identical parameters should be forbidden by the kernel. There might > be reasons these are valid use cases? People are crazy... :-) BTW, "duplicate" loops (by mount(8)) are disabled in Fedora 4,5,6,7,8 and RHEL5 and I've never seen any bug report. > Thats why I wanted to apply the check only for mount -oloop to > avoid two identical mounts as given in the example above. > The problem here is that the mount is a two step process: > 1. Setting up loop device, 2. mount, but appears transparently as > one step to the user. However, the behaviour is different for normal block > devices and loop devices. I think from a users POV mount should > behave consistently. Yes, I agree. > > Maybe we can add a warning message to losetup only. The losetup > > shouldn't be more "smart" than kernel or end-user -- I'd like to > > follow kernel in this case. > Yes, I agree. losetup as a low level tool shouldn't be smarter > than the user and only be restricted by the kernel itself. > I haven't been thinking about losetup itself, but the mount -oloop > case. OK. I look forward to your patches. Karel --- util-linux-ng-2.13-rc3/mount/fstab.c.kzak 2007-07-31 12:39:42.000000000 +0200 +++ util-linux-ng-2.13-rc3/mount/fstab.c 2007-08-13 12:24:40.000000000 +0200 @@ -264,6 +264,27 @@ return (ct == 1); } +/* + * Given the loop file LOOPFILE, and the mount point DIR, check that + * same file is already mounted on same directory + * + * Don't forget there's + * /path/loopfile /path/dir loop=/dev/loop0 + * in mtab for loop devices. + */ +int +is_mounted_same_loopfile(const char *loopfile, const char *dir) { + struct mntentchn *mc, *mc0; + int ct = 0; + + mc0 = mtab_head(); + for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev) + if (streq(mc->m.mnt_fsname, loopfile) && + streq(mc->m.mnt_dir, dir)) + ct++; + return (ct == 1); +} + /* Given the name FILE, try to find the option "loop=FILE" in mtab. */ struct mntentchn * getmntoptfile (const char *file) { --- util-linux-ng-2.13-rc3/mount/fstab.h.kzak 2007-05-30 10:18:12.000000000 +0200 +++ util-linux-ng-2.13-rc3/mount/fstab.h 2007-08-13 12:24:40.000000000 +0200 @@ -5,6 +5,7 @@ int mtab_is_writable(void); int mtab_does_not_exist(void); int is_mounted_once(const char *name); +int is_mounted_same_loopfile(const char *loopfile, const char *dir); struct mntentchn { struct mntentchn *nxt, *prev; --- util-linux-ng-2.13-rc3/mount/mount.c.kzak 2007-08-13 12:23:13.000000000 +0200 +++ util-linux-ng-2.13-rc3/mount/mount.c 2007-08-13 12:29:01.000000000 +0200 @@ -853,7 +853,7 @@ static int loop_check(const char **spec, const char **type, int *flags, - int *loop, const char **loopdev, const char **loopfile) { + int *loop, const char **loopdev, const char **loopfile, const char *dir) { int looptype; unsigned long long offset; @@ -894,6 +894,10 @@ offset = opt_offset ? strtoull(opt_offset, NULL, 0) : 0; + if (is_mounted_same_loopfile(*loopfile, dir)) { + error(_("mount: %s already mounted on %s"), *loopfile, dir); + return EX_FAIL; + } do { if (!*loopdev || !**loopdev) *loopdev = find_unused_loop_device(); @@ -1079,7 +1083,7 @@ * stale assignments of files to loop devices. Nasty when used for * encryption. */ - res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile); + res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile, node); if (res) goto out; } - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html