summaryrefslogtreecommitdiffstats
path: root/lib/loopdev.c
diff options
context:
space:
mode:
authorKarel Zak2011-11-07 16:45:11 +0100
committerKarel Zak2011-11-07 16:45:11 +0100
commit0b14bf7af1f13b9bb0f3952af264c114bac83665 (patch)
tree5cdd9c72591d9e16a408f53d6d75a612391da3a3 /lib/loopdev.c
parentdocs: add note about config-gen purpose (diff)
downloadkernel-qcow2-util-linux-0b14bf7af1f13b9bb0f3952af264c114bac83665.tar.gz
kernel-qcow2-util-linux-0b14bf7af1f13b9bb0f3952af264c114bac83665.tar.xz
kernel-qcow2-util-linux-0b14bf7af1f13b9bb0f3952af264c114bac83665.zip
lib,loopdev: add LOOP_CTL_GET_FREE support
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/loopdev.c')
-rw-r--r--lib/loopdev.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/lib/loopdev.c b/lib/loopdev.c
index f83a443a0..3dfa78a40 100644
--- a/lib/loopdev.c
+++ b/lib/loopdev.c
@@ -139,6 +139,8 @@ int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
*/
int loopcxt_init(struct loopdev_cxt *lc, int flags)
{
+ struct stat st;
+
if (!lc)
return -EINVAL;
@@ -153,6 +155,9 @@ int loopcxt_init(struct loopdev_cxt *lc, int flags)
*/
lc->flags |= LOOPDEV_FL_NOIOCTL;
+ if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st))
+ lc->flags |= LOOPDEV_FL_CONTROL;
+
return 0;
}
@@ -917,18 +922,35 @@ int loopcxt_delete_device(struct loopdev_cxt *lc)
int loopcxt_find_unused(struct loopdev_cxt *lc)
{
- int rc;
+ int rc = -1;
DBG(lc, loopdev_debug("find_unused requested"));
- rc = loopcxt_init_iterator(lc, LOOPITER_FL_FREE);
- if (rc)
- return rc;
+ if (lc->flags & LOOPDEV_FL_CONTROL) {
+ int ctl = open(_PATH_DEV_LOOPCTL, O_RDWR);
- rc = loopcxt_next(lc);
- loopcxt_deinit_iterator(lc);
+ if (ctl >= 0)
+ rc = ioctl(ctl, LOOP_CTL_GET_FREE);
+ if (rc >= 0) {
+ char name[16];
+ snprintf(name, sizeof(name), "loop%d", rc);
+
+ rc = loopiter_set_device(lc, name);
+ }
+ if (ctl >= 0)
+ close(ctl);
+ DBG(lc, loopdev_debug("find_unused by loop-control [rc=%d]", rc));
+ }
- DBG(lc, loopdev_debug("find_unused done [rc=%d]", rc));
+ if (rc < 0) {
+ rc = loopcxt_init_iterator(lc, LOOPITER_FL_FREE);
+ if (rc)
+ return rc;
+
+ rc = loopcxt_next(lc);
+ loopcxt_deinit_iterator(lc);
+ DBG(lc, loopdev_debug("find_unused by scan [rc=%d]", rc));
+ }
return rc;
}