]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/ismounted: basic support for loop devices
authorKarel Zak <kzak@redhat.com>
Wed, 19 Dec 2012 11:40:32 +0000 (12:40 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 19 Dec 2012 11:40:32 +0000 (12:40 +0100)
 # losetup -a /dev/loop0
 /dev/loop0: [2053]:1048578 (/home/fs-images/filesystems/ext2.img)

 # findmnt /dev/loop0
 TARGET    SOURCE     FSTYPE OPTIONS
 /mnt/test /dev/loop0 ext3   rw,relatime,data=ordered

old version:

 ./test_ismounted /home/fs-images/filesystems/ext2.img
 not mounted

new version:

 ./test_ismounted /home/fs-images/filesystems/ext2.img
 mounted on /mnt/test

Reported-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/Makemodule.am
lib/Makemodule.am
lib/ismounted.c

index b329a99a8037830acd94f4a0807ad0814e88cc88..fb5dabac3cab5d027476795f701f944fd05f93a2 100644 (file)
@@ -3,8 +3,7 @@ sbin_PROGRAMS += fsck.minix
 dist_man_MANS += disk-utils/fsck.minix.8
 fsck_minix_SOURCES = \
        disk-utils/fsck.minix.c \
-       disk-utils/minix_programs.h \
-       lib/ismounted.c
+       disk-utils/minix_programs.h
 fsck_minix_LDADD = $(LDADD) libcommon.la
 
 sbin_PROGRAMS += mkfs.minix
index 806f9e5b087fa4ecab0a23a996e57d8014c5268c..d3cf8928d0bd7d7a05f58777b03a7319831fc1fc 100644 (file)
@@ -76,6 +76,7 @@ test_blkdev_LDADD = libcommon.la
 
 test_ismounted_SOURCES = lib/ismounted.c
 test_ismounted_CFLAGS = -DTEST_PROGRAM
+test_ismounted_LDADD = libcommon.la
 
 test_wholedisk_SOURCES = lib/wholedisk.c
 test_wholedisk_CFLAGS = -DTEST_PROGRAM
index 273a7d9518630a8e54d52615b42bad31bcf1b392..c2ad2434b43fea32c4ebc2b98e0f080ad92e6099 100644 (file)
 #include "pathnames.h"
 #include "ismounted.h"
 #include "c.h"
+#ifdef __linux__
+# include "loopdev.h"
+#endif
+
+
 
 #ifdef HAVE_MNTENT_H
 /*
@@ -39,7 +44,7 @@ static int check_mntent_file(const char *mtab_file, const char *file,
        struct mntent   *mnt;
        struct stat     st_buf;
        int             retval = 0;
-       dev_t           file_dev=0, file_rdev=0;
+       dev_t           file_dev=0, file_rdev=0, lodev_dev=0;
        ino_t           file_ino=0;
        FILE            *f;
        int             fd;
@@ -47,32 +52,51 @@ static int check_mntent_file(const char *mtab_file, const char *file,
        *mount_flags = 0;
        if ((f = setmntent (mtab_file, "r")) == NULL)
                return errno;
+
        if (stat(file, &st_buf) == 0) {
                if (S_ISBLK(st_buf.st_mode)) {
 #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
                        file_rdev = st_buf.st_rdev;
 #endif /* __GNU__ */
                } else {
+#ifdef __linux__
+                       /*
+                        * Maybe the file is backing file for a loop device.
+                        *
+                        * For is_mounted() we complete ignore the fact that
+                        * the same backing file maybe mapped into more loop
+                        * devices by sizelimit and offset loop options. If you
+                        * want really robust code than use libmount...
+                        */
+                       char *name = loopdev_find_by_backing_file(file, 0, 0);
+                       if (name && stat(name, &st_buf) == 0)
+                               lodev_dev = st_buf.st_rdev;
+                       free(name);
+#endif
                        file_dev = st_buf.st_dev;
                        file_ino = st_buf.st_ino;
                }
        }
+
        while ((mnt = getmntent (f)) != NULL) {
                if (mnt->mnt_fsname[0] != '/')
                        continue;
                if (strcmp(file, mnt->mnt_fsname) == 0)
                        break;
-               if (stat(mnt->mnt_fsname, &st_buf) == 0) {
-                       if (S_ISBLK(st_buf.st_mode)) {
+               if (stat(mnt->mnt_fsname, &st_buf) != 0)
+                       continue;
+
+               if (S_ISBLK(st_buf.st_mode)) {
 #ifndef __GNU__
-                               if (file_rdev && (file_rdev == st_buf.st_rdev))
-                                       break;
-#endif /* __GNU__ */
-                       } else {
-                               if (file_dev && ((file_dev == st_buf.st_dev) &&
-                                                (file_ino == st_buf.st_ino)))
-                                       break;
+                       if ((file_rdev && file_rdev == st_buf.st_rdev) ||
+                           (lodev_dev && lodev_dev == st_buf.st_rdev)) {
+                               break;
                        }
+#endif /* __GNU__ */
+               } else {
+                       if (file_dev && ((file_dev == st_buf.st_dev) &&
+                                        (file_ino == st_buf.st_ino)))
+                               break;
                }
        }