From 7aa0e8c0cb8a6293d0c6f7e3d29c13b96dec2129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 25 Jan 2018 09:35:52 +0000 Subject: [PATCH] storage: export virStoragePoolLookupByTargetPath as a public API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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é --- 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 5ee9e5c32c..a14e27aac2 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 1b4bce4fc8..d5e38af5aa 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1694,6 +1694,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); } @@ -1710,6 +1713,7 @@ storagePoolLookupByTargetPath(virConnectPtr conn, } } + cleanup: VIR_FREE(cleanpath); return pool; } @@ -2808,6 +2812,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 */