The storagePoolLookupByTargetPath() method in the storage driver is used
by the QEMU driver during block migration. If there's a valid use case
for this in the QEMU driver, then external apps likely have similar
needs. Exposing it in the public API removes the direct dependancy from
the QEMU driver to the storage driver.

Signed-off-by: Daniel P. Berrangé <berra...@redhat.com>
---
 include/libvirt/libvirt-storage.h |  2 ++
 src/driver-storage.h              |  5 +++++
 src/libvirt-storage.c             | 40 +++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms           |  6 ++++++
 src/qemu/qemu_migration.c         |  2 +-
 src/remote/remote_driver.c        |  1 +
 src/remote/remote_protocol.x      | 17 ++++++++++++++++-
 src/remote_protocol-structs       |  7 +++++++
 src/storage/storage_driver.c      |  5 +++++
 9 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt-storage.h 
b/include/libvirt/libvirt-storage.h
index 736e2e3b80..413d9f6c4c 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -264,6 +264,8 @@ virStoragePoolPtr       virStoragePoolLookupByUUID      
(virConnectPtr conn,
 virStoragePoolPtr       virStoragePoolLookupByUUIDString(virConnectPtr conn,
                                                          const char *uuid);
 virStoragePoolPtr       virStoragePoolLookupByVolume    (virStorageVolPtr vol);
+virStoragePoolPtr       virStoragePoolLookupByTargetPath(virConnectPtr conn,
+                                                         const char *path);
 
 /*
  * Creating/destroying pools
diff --git a/src/driver-storage.h b/src/driver-storage.h
index 48e588a546..146eb88b2c 100644
--- a/src/driver-storage.h
+++ b/src/driver-storage.h
@@ -63,6 +63,10 @@ typedef virStoragePoolPtr
 typedef virStoragePoolPtr
 (*virDrvStoragePoolLookupByVolume)(virStorageVolPtr vol);
 
+typedef virStoragePoolPtr
+(*virDrvStoragePoolLookupByTargetPath)(virConnectPtr conn,
+                                       const char *path);
+
 typedef virStoragePoolPtr
 (*virDrvStoragePoolCreateXML)(virConnectPtr conn,
                               const char *xmlDesc,
@@ -236,6 +240,7 @@ struct _virStorageDriver {
     virDrvStoragePoolLookupByName storagePoolLookupByName;
     virDrvStoragePoolLookupByUUID storagePoolLookupByUUID;
     virDrvStoragePoolLookupByVolume storagePoolLookupByVolume;
+    virDrvStoragePoolLookupByTargetPath storagePoolLookupByTargetPath;
     virDrvStoragePoolCreateXML storagePoolCreateXML;
     virDrvStoragePoolDefineXML storagePoolDefineXML;
     virDrvStoragePoolBuild storagePoolBuild;
diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c
index e4646cb80f..3845a5d55e 100644
--- a/src/libvirt-storage.c
+++ b/src/libvirt-storage.c
@@ -497,6 +497,46 @@ virStoragePoolLookupByVolume(virStorageVolPtr vol)
 }
 
 
+/**
+ * virStoragePoolLookupByTargetPath:
+ * @conn: pointer to hypervisor connection
+ * @path: path at which the pool is exposed
+ *
+ * Fetch a storage pool which maps to a particular target directory.
+ * If more than one pool maps to the path, it is undefined which
+ * will be returned first.
+ *
+ * virStoragePoolFree should be used to free the resources after the
+ * storage pool object is no longer needed.
+ *
+ * Returns a virStoragePoolPtr object, or NULL if no matching pool is found
+ */
+virStoragePoolPtr
+virStoragePoolLookupByTargetPath(virConnectPtr conn,
+                                 const char *path)
+{
+    VIR_DEBUG("conn=%p, path=%s", conn, NULLSTR(path));
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, NULL);
+    virCheckNonNullArgGoto(path, error);
+
+    if (conn->storageDriver && 
conn->storageDriver->storagePoolLookupByTargetPath) {
+        virStoragePoolPtr ret;
+        ret = conn->storageDriver->storagePoolLookupByTargetPath(conn, path);
+        if (!ret)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(conn);
+    return NULL;
+}
+
 /**
  * virStoragePoolCreateXML:
  * @conn: pointer to hypervisor connection
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 0efde25a7f..95df3a0dbc 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -779,4 +779,10 @@ LIBVIRT_3.9.0 {
     global:
         virDomainSetLifecycleAction;
 } LIBVIRT_3.7.0;
+
+LIBVIRT_4.1.0 {
+    global:
+        virStoragePoolLookupByTargetPath;
+} LIBVIRT_3.9.0;
+
 # .... define new API here using predicted next version number ....
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 1854900c9a..8301c76a19 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -329,7 +329,7 @@ qemuMigrationPrecreateDisk(virConnectPtr conn,
         *volName = '\0';
         volName++;
 
-        if (!(pool = storagePoolLookupByTargetPath(conn, basePath)))
+        if (!(pool = virStoragePoolLookupByTargetPath(conn, basePath)))
             goto cleanup;
         format = virStorageFileFormatTypeToString(disk->src->format);
         if (disk->src->format == VIR_STORAGE_FILE_QCOW2)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f8fa64af99..9ea726dc45 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8556,6 +8556,7 @@ static virStorageDriver storage_driver = {
     .storagePoolLookupByName = remoteStoragePoolLookupByName, /* 0.4.1 */
     .storagePoolLookupByUUID = remoteStoragePoolLookupByUUID, /* 0.4.1 */
     .storagePoolLookupByVolume = remoteStoragePoolLookupByVolume, /* 0.4.1 */
+    .storagePoolLookupByTargetPath = remoteStoragePoolLookupByTargetPath, /* 
4.1.0 */
     .storagePoolCreateXML = remoteStoragePoolCreateXML, /* 0.4.1 */
     .storagePoolDefineXML = remoteStoragePoolDefineXML, /* 0.4.1 */
     .storagePoolBuild = remoteStoragePoolBuild, /* 0.4.1 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 0aed25220d..9dbd497b2f 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1761,6 +1761,14 @@ struct remote_storage_pool_lookup_by_volume_ret {
     remote_nonnull_storage_pool pool;
 };
 
+struct remote_storage_pool_lookup_by_target_path_args {
+    remote_nonnull_string path;
+};
+
+struct remote_storage_pool_lookup_by_target_path_ret {
+    remote_nonnull_storage_pool pool;
+};
+
 struct remote_storage_pool_create_xml_args {
     remote_nonnull_string xml;
     unsigned int flags;
@@ -6120,5 +6128,12 @@ enum remote_procedure {
      * @generate: both
      * @acl: domain:write
      */
-    REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION = 390
+    REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION = 390,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: storage_pool:getattr
+     */
+    REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_TARGET_PATH = 391
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 59b0acec69..f45aba27a2 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1330,6 +1330,12 @@ struct remote_storage_pool_lookup_by_volume_args {
 struct remote_storage_pool_lookup_by_volume_ret {
         remote_nonnull_storage_pool pool;
 };
+struct remote_storage_pool_lookup_by_target_path_args {
+        remote_nonnull_string      path;
+};
+struct remote_storage_pool_lookup_by_target_path_ret {
+        remote_nonnull_storage_pool pool;
+};
 struct remote_storage_pool_create_xml_args {
         remote_nonnull_string      xml;
         u_int                      flags;
@@ -3262,4 +3268,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC = 388,
         REMOTE_PROC_DOMAIN_MANAGED_SAVE_DEFINE_XML = 389,
         REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION = 390,
+        REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_TARGET_PATH = 391,
 };
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 25e563e8d6..d43ad1826c 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1628,6 +1628,9 @@ storagePoolLookupByTargetPath(virConnectPtr conn,
                                            
storagePoolLookupByTargetPathCallback,
                                            cleanpath))) {
         def = virStoragePoolObjGetDef(obj);
+        if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0)
+            goto cleanup;
+
         pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
         virStoragePoolObjEndAPI(&obj);
     }
@@ -1644,6 +1647,7 @@ storagePoolLookupByTargetPath(virConnectPtr conn,
         }
     }
 
+ cleanup:
     VIR_FREE(cleanpath);
     return pool;
 }
@@ -2701,6 +2705,7 @@ static virStorageDriver storageDriver = {
     .storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */
     .storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */
     .storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */
+    .storagePoolLookupByTargetPath = storagePoolLookupByTargetPath, /* 4.1.0 */
     .storagePoolCreateXML = storagePoolCreateXML, /* 0.4.0 */
     .storagePoolDefineXML = storagePoolDefineXML, /* 0.4.0 */
     .storagePoolBuild = storagePoolBuild, /* 0.4.0 */
-- 
2.14.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to