diff --git a/umount-by-imgname.patch b/umount-by-imgname.patch new file mode 100644 index 0000000..c19c014 --- /dev/null +++ b/umount-by-imgname.patch @@ -0,0 +1,166 @@ +From f4612577c942a3683b97632ad0b49671897c2070 Mon Sep 17 00:00:00 2001 +From: Petr Uzel +Date: Thu, 17 Feb 2011 12:52:43 +0100 +Subject: [PATCH] umount: allow unmounting loopdev specified by associated file + +Make it possible to unmount a filesystem on a loop device if it is +specified by associated backing file. It does not attempt to unmount +anything if there are more than one loop device associated with the +given file. + +Umount looks for associated loopdevice(s) only if umount is called +with the regular file as an argument. + +Before: + mount -o loop -t ext2 img mnt + umount -v img + > Could not find /home/puzel/upstream/util-linux/img in mtab + > umount: img: not mounted + +After: + mount -o loop -t ext2 img mnt + umount -v img + > img is associated with /dev/loop0, trying to unmount it + > /dev/loop0 has been unmounted + +[kzak@redhat.com: - fix memory leak in lomount.c] + +Addresses: https://bugzilla.novell.com/show_bug.cgi?id=666161 +Signed-off-by: Petr Uzel +Signed-off-by: Karel Zak +--- + mount/lomount.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + mount/lomount.h | 1 + + mount/umount.c | 22 ++++++++++++++++++++++ + 3 files changed, 76 insertions(+), 0 deletions(-) + +Index: util-linux-2.19/mount/lomount.c +=================================================================== +--- util-linux-2.19.orig/mount/lomount.c ++++ util-linux-2.19/mount/lomount.c +@@ -409,6 +409,51 @@ done: + return -1; + } + ++/* Find loop device associated with given @filename. Used for unmounting loop ++ * device specified by associated backing file. ++ * ++ * returns: 1 no such device/error ++ * 2 more than one loop device associated with @filename ++ * 0 exactly one loop device associated with @filename ++ * (@loopdev points to string containing full device name) ++ */ ++int ++find_loopdev_by_backing_file(const char *filename, char **loopdev) ++{ ++ struct looplist ll; ++ struct stat filestat; ++ int fd; ++ int devs_n = 0; /* number of loop devices found */ ++ char* devname = NULL; ++ ++ if (stat(filename, &filestat) == -1) { ++ perror(filename); ++ return 1; ++ } ++ ++ if (looplist_open(&ll, LLFLG_USEDONLY) == -1) { ++ error(_("%s: /dev directory does not exist."), progname); ++ return 1; ++ } ++ ++ while((devs_n < 2) && (fd = looplist_next(&ll)) != -1) { ++ if (is_associated(fd, &filestat, 0, 0) == 1) { ++ if (!devname) ++ devname = xstrdup(ll.name); ++ devs_n++; ++ } ++ close(fd); ++ } ++ looplist_close(&ll); ++ ++ if (devs_n == 1) { ++ *loopdev = devname; ++ return 0; /* exactly one loopdev */ ++ } ++ free(devname); ++ return devs_n ? 2 : 1; /* more loopdevs or error */ ++} ++ + #ifdef MAIN + + static int +@@ -581,6 +626,7 @@ show_associated_loop_devices(char *filen + return 0; + } + ++ + #endif /* MAIN */ + + /* check if the loopfile is already associated with the same given +@@ -1054,6 +1100,13 @@ find_unused_loop_device (void) { + return 0; + } + ++int ++find_loopdev_by_backing_file(const char *filename, char **loopdev) ++{ ++ mutter(); ++ return 1; ++} ++ + #endif /* !LOOP_SET_FD */ + + #ifdef MAIN +Index: util-linux-2.19/mount/lomount.h +=================================================================== +--- util-linux-2.19.orig/mount/lomount.h ++++ util-linux-2.19/mount/lomount.h +@@ -11,6 +11,7 @@ extern char * find_unused_loop_device(vo + extern int loopfile_used_with(char *devname, const char *filename, unsigned long long offset); + extern char *loopfile_used (const char *filename, unsigned long long offset); + extern char *loopdev_get_loopfile(const char *device); ++extern int find_loopdev_by_backing_file(const char *filename, char **loopdev); + + + #define SETLOOP_RDONLY (1<<0) /* Open loop read-only */ +Index: util-linux-2.19/mount/umount.c +=================================================================== +--- util-linux-2.19.orig/mount/umount.c ++++ util-linux-2.19/mount/umount.c +@@ -502,6 +502,7 @@ umount_file (char *arg) { + const char *file, *options; + int fstab_has_user, fstab_has_users, fstab_has_owner, fstab_has_group; + int ok; ++ struct stat statbuf; + + if (!*arg) { /* "" would be expanded to `pwd` */ + die(2, _("Cannot unmount \"\"\n")); +@@ -509,6 +510,27 @@ umount_file (char *arg) { + } + + file = canonicalize(arg); /* mtab paths are canonicalized */ ++ ++ /* if file is a regular file, check if it is associated ++ * with some loop device ++ */ ++ if (!stat(file, &statbuf) && S_ISREG(statbuf.st_mode)) { ++ char *loopdev = NULL; ++ switch (find_loopdev_by_backing_file(file, &loopdev)) { ++ case 0: ++ if (verbose) ++ printf(_("%s is associated with %s, trying to unmount it\n"), ++ arg, loopdev); ++ file = loopdev; ++ break; ++ case 2: ++ if (verbose) ++ printf(_("%s is associated with more than one loop device: not unmounting\n"), ++ arg); ++ break; ++ } ++ } ++ + if (verbose > 1) + printf(_("Trying to unmount %s\n"), file); + diff --git a/util-linux.changes b/util-linux.changes index 70582b6..88e4ac1 100644 --- a/util-linux.changes +++ b/util-linux.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Feb 21 16:28:38 UTC 2011 - puzel@novell.com + +- add umount-by-imgname.patch (bnc#666161) + ------------------------------------------------------------------- Thu Feb 10 11:01:40 UTC 2011 - puzel@novell.com diff --git a/util-linux.spec b/util-linux.spec index 3b356f9..e3bc88c 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -81,6 +81,7 @@ Patch1: util-linux-2.12r-fdisk_remove_bogus_warnings.patch # crypto patch Patch3: util-linux-2.17.1-mount_losetup_crypto.patch Patch4: util-linux-2.17.1-losetup-honor-documented-c-option +Patch5: umount-by-imgname.patch ## ## adjtimex ## @@ -182,6 +183,7 @@ Files to develop applications using the libmount library. %patch1 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 # cd adjtimex-*