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 */