]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
losetup: use loop-control to explicitly ask for device
authorKarel Zak <kzak@redhat.com>
Tue, 6 Aug 2013 09:04:35 +0000 (11:04 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 6 Aug 2013 09:04:35 +0000 (11:04 +0200)
Now we use LOOP_CTL_GET_FREE ioctl to ask for free device, for example

  losetup -f foo.img

Unfortunately, losetup(8) allows to ask for specified device

  losetup /dev/loop100 foo.img

and in this case we assume that the device already exists in the
system. This is incorrect, we should be able to use loop-control
LOOP_CTL_ADD ioctl to ask for the specified device.

Signed-off-by: Karel Zak <kzak@redhat.com>
include/loopdev.h
lib/loopdev.c
sys-utils/losetup.c

index 9f199a086ebe4af5309d8c9aef851a4d92d35c61..eb328a080dd512825d6edb4bc7bdb45897389303 100644 (file)
@@ -149,6 +149,7 @@ extern void loopcxt_enable_debug(struct loopdev_cxt *lc, int enable);
 extern int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
                                __attribute__ ((warn_unused_result));
 extern int loopcxt_has_device(struct loopdev_cxt *lc);
+extern int loopcxt_add_device(struct loopdev_cxt *lc);
 extern char *loopcxt_strdup_device(struct loopdev_cxt *lc);
 extern const char *loopcxt_get_device(struct loopdev_cxt *lc);
 extern struct sysfs_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc);
index 9789feb88aa5a6d61a7a5bb3490973f56cfe3fa9..27276bfab5e81e480cd6512efe85cb47f962422c 100644 (file)
@@ -1297,6 +1297,36 @@ int loopcxt_delete_device(struct loopdev_cxt *lc)
        return 0;
 }
 
+int loopcxt_add_device(struct loopdev_cxt *lc)
+{
+       int rc = -EINVAL;
+       int ctl, nr = -1;
+       const char *p, *dev = loopcxt_get_device(lc);
+
+       if (!dev)
+               goto done;
+
+       if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
+               rc = -ENOSYS;
+               goto done;
+       }
+
+       p = strrchr(dev, '/');
+       if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
+              || nr < 0)
+               goto done;
+
+       ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
+       if (ctl >= 0) {
+               DBG(lc, loopdev_debug("add_device %d", nr));
+               rc = ioctl(ctl, LOOP_CTL_ADD, nr);
+               close(ctl);
+       }
+done:
+       DBG(lc, loopdev_debug("add_device done [rc=%d]", rc));
+       return rc;
+}
+
 /*
  * Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older
  * kernels we have to check all loop devices to found unused one.
index c1166b03933310dc914c4fa5c78c899c1a8d88be..234a15b0c28423f567719d848e939ce6222c4451 100644 (file)
@@ -641,6 +641,8 @@ int main(int argc, char **argv)
        {
                int hasdev = loopcxt_has_device(&lc);
 
+               if (hasdev && !is_loopdev(loopcxt_get_device(&lc)))
+                       loopcxt_add_device(&lc);
                do {
                        const char *errpre;