summaryrefslogtreecommitdiffstats
path: root/mount/lomount.c
diff options
context:
space:
mode:
authorPetr Uzel2011-02-17 12:52:43 +0100
committerKarel Zak2011-02-21 14:54:43 +0100
commitf4612577c942a3683b97632ad0b49671897c2070 (patch)
tree83f8e24026c681c30008890f56e4abfcd315e098 /mount/lomount.c
parentinclude: [xalloc.h]: mention strdup in the file description (diff)
downloadkernel-qcow2-util-linux-f4612577c942a3683b97632ad0b49671897c2070.tar.gz
kernel-qcow2-util-linux-f4612577c942a3683b97632ad0b49671897c2070.tar.xz
kernel-qcow2-util-linux-f4612577c942a3683b97632ad0b49671897c2070.zip
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 <petr.uzel@suse.cz> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'mount/lomount.c')
-rw-r--r--mount/lomount.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/mount/lomount.c b/mount/lomount.c
index ceb321751..0bbcbc19d 100644
--- a/mount/lomount.c
+++ b/mount/lomount.c
@@ -403,6 +403,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
@@ -565,6 +610,7 @@ show_associated_loop_devices(char *filename, unsigned long long offset, int isof
return 0;
}
+
#endif /* MAIN */
/* check if the loopfile is already associated with the same given
@@ -946,6 +992,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