Instead of passing around a virConnectPtr object, just open a connection to the secret driver at time of use. Opening connections on demand will be beneficial when the secret driver is in a separate daemon. It also solves the problem that a number of callers just pass in a NULL connection today which prevents secret lookup working at all.
Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> --- src/storage/storage_backend_iscsi.c | 14 +++--- src/storage/storage_backend_logical.c | 2 +- src/storage/storage_backend_rbd.c | 41 +++++++-------- src/storage/storage_util.c | 95 ++++++++++++++++------------------- src/storage/storage_util.h | 6 +-- 5 files changed, 71 insertions(+), 87 deletions(-) diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index b0c5096adb..921215c9e9 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -273,13 +273,13 @@ virStorageBackendISCSICheckPool(virStoragePoolObjPtr pool, static int virStorageBackendISCSISetAuth(const char *portal, - virConnectPtr conn, virStoragePoolSourcePtr source) { unsigned char *secret_value = NULL; size_t secret_size; virStorageAuthDefPtr authdef = source->auth; int ret = -1; + virConnectPtr conn = NULL; if (!authdef || authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE) return 0; @@ -292,12 +292,9 @@ virStorageBackendISCSISetAuth(const char *portal, return -1; } - if (!conn) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("iscsi 'chap' authentication not supported " - "for autostarted pools")); + conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); + if (!conn) return -1; - } if (virSecretGetSecretString(conn, &authdef->seclookupdef, VIR_SECRET_USAGE_TYPE_ISCSI, @@ -322,11 +319,12 @@ virStorageBackendISCSISetAuth(const char *portal, cleanup: VIR_DISPOSE_N(secret_value, secret_size); + virObjectUnref(conn); return ret; } static int -virStorageBackendISCSIStartPool(virConnectPtr conn, +virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); @@ -362,7 +360,7 @@ virStorageBackendISCSIStartPool(virConnectPtr conn, if (virISCSINodeNew(portal, def->source.devices[0].path) < 0) goto cleanup; - if (virStorageBackendISCSISetAuth(portal, conn, &def->source) < 0) + if (virStorageBackendISCSISetAuth(portal, &def->source) < 0) goto cleanup; if (virISCSIConnectionLogin(portal, diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index 5df30de29d..64bfc8c976 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -997,7 +997,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, return -1; if (vol->target.encryption && - virStorageBackendCreateVolUsingQemuImg(conn, pool, vol, NULL, 0) < 0) + virStorageBackendCreateVolUsingQemuImg(pool, vol, NULL, 0) < 0) goto error; if ((fd = virStorageBackendVolOpen(vol->target.path, &sb, diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index 7f9597cabe..e901f370d5 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -71,7 +71,6 @@ virStorageBackendRBDRADOSConfSet(rados_t cluster, static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, - virConnectPtr conn, virStoragePoolSourcePtr source) { int ret = -1; @@ -87,6 +86,7 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, const char *mon_op_timeout = "30"; const char *osd_op_timeout = "30"; const char *rbd_default_format = "2"; + virConnectPtr conn = NULL; if (authdef) { VIR_DEBUG("Using cephx authorization, username: %s", authdef->username); @@ -96,12 +96,9 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, goto cleanup; } - if (!conn) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("'ceph' authentication not supported " - "for autostarted pools")); + conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); + if (!conn) return -1; - } if (virSecretGetSecretString(conn, &authdef->seclookupdef, VIR_SECRET_USAGE_TYPE_CEPH, @@ -201,6 +198,7 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, VIR_DISPOSE_N(secret_value, secret_value_size); VIR_DISPOSE_STRING(rados_key); + virObjectUnref(conn); virBufferFreeAndReset(&mon_host); VIR_FREE(mon_buff); return ret; @@ -252,8 +250,7 @@ virStorageBackendRBDFreeState(virStorageBackendRBDStatePtr *ptr) static virStorageBackendRBDStatePtr -virStorageBackendRBDNewState(virConnectPtr conn, - virStoragePoolObjPtr pool) +virStorageBackendRBDNewState(virStoragePoolObjPtr pool) { virStorageBackendRBDStatePtr ptr; virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); @@ -261,7 +258,7 @@ virStorageBackendRBDNewState(virConnectPtr conn, if (VIR_ALLOC(ptr) < 0) return NULL; - if (virStorageBackendRBDOpenRADOSConn(ptr, conn, &def->source) < 0) + if (virStorageBackendRBDOpenRADOSConn(ptr, &def->source) < 0) goto error; if (virStorageBackendRBDOpenIoCTX(ptr, pool) < 0) @@ -423,7 +420,7 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr vol, } static int -virStorageBackendRBDRefreshPool(virConnectPtr conn, +virStorageBackendRBDRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { size_t max_size = 1024; @@ -436,7 +433,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, struct rados_cluster_stat_t clusterstat; struct rados_pool_stat_t poolstat; - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if ((r = rados_cluster_stat(ptr->cluster, &clusterstat)) < 0) { @@ -605,7 +602,7 @@ virStorageBackendRBDCleanupSnapshots(rados_ioctx_t ioctx, } static int -virStorageBackendRBDDeleteVol(virConnectPtr conn, +virStorageBackendRBDDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags) @@ -623,7 +620,7 @@ virStorageBackendRBDDeleteVol(virConnectPtr conn, if (flags & VIR_STORAGE_VOL_DELETE_ZEROED) VIR_WARN("%s", "This storage backend does not support zeroed removal of volumes"); - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if (flags & VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS) { @@ -685,7 +682,7 @@ static int virStorageBackendRBDCreateImage(rados_ioctx_t io, } static int -virStorageBackendRBDBuildVol(virConnectPtr conn, +virStorageBackendRBDBuildVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags) @@ -718,7 +715,7 @@ virStorageBackendRBDBuildVol(virConnectPtr conn, goto cleanup; } - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if ((r = virStorageBackendRBDCreateImage(ptr->ioctx, vol->name, @@ -1041,7 +1038,7 @@ virStorageBackendRBDCloneImage(rados_ioctx_t io, } static int -virStorageBackendRBDBuildVolFrom(virConnectPtr conn, +virStorageBackendRBDBuildVolFrom(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr newvol, virStorageVolDefPtr origvol, @@ -1056,7 +1053,7 @@ virStorageBackendRBDBuildVolFrom(virConnectPtr conn, virCheckFlags(0, -1); - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if ((virStorageBackendRBDCloneImage(ptr->ioctx, origvol->name, @@ -1071,14 +1068,14 @@ virStorageBackendRBDBuildVolFrom(virConnectPtr conn, } static int -virStorageBackendRBDRefreshVol(virConnectPtr conn, +virStorageBackendRBDRefreshVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { virStorageBackendRBDStatePtr ptr = NULL; int ret = -1; - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0) @@ -1105,7 +1102,7 @@ virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, virCheckFlags(0, -1); - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if ((r = rbd_open(ptr->ioctx, vol->name, &image, NULL)) < 0) { @@ -1204,7 +1201,7 @@ virStorageBackendRBDVolWipeDiscard(rbd_image_t image, } static int -virStorageBackendRBDVolWipe(virConnectPtr conn, +virStorageBackendRBDVolWipe(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int algorithm, @@ -1222,7 +1219,7 @@ virStorageBackendRBDVolWipe(virConnectPtr conn, VIR_DEBUG("Wiping RBD image %s/%s", def->source.name, vol->name); - if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + if (!(ptr = virStorageBackendRBDNewState(pool))) goto cleanup; if ((r = rbd_open(ptr->ioctx, vol->name, &image, NULL)) < 0) { diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 9e1b63a436..5995921570 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -497,7 +497,7 @@ virStorageGenerateSecretUUID(virConnectPtr conn, _("unable to generate uuid")); return -1; } - tmp = conn->secretDriver->secretLookupByUUID(conn, uuid); + tmp = virSecretLookupByUUID(conn, uuid); if (tmp == NULL) return 0; @@ -511,8 +511,7 @@ virStorageGenerateSecretUUID(virConnectPtr conn, } static int -virStorageGenerateQcowEncryption(virConnectPtr conn, - virStorageVolDefPtr vol) +virStorageGenerateQcowEncryption(virStorageVolDefPtr vol) { virSecretDefPtr def = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -522,15 +521,11 @@ virStorageGenerateQcowEncryption(virConnectPtr conn, char *xml; unsigned char value[VIR_STORAGE_QCOW_PASSPHRASE_SIZE]; int ret = -1; + virConnectPtr conn = NULL; - if (conn->secretDriver == NULL || - conn->secretDriver->secretLookupByUUID == NULL || - conn->secretDriver->secretDefineXML == NULL || - conn->secretDriver->secretSetValue == NULL) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("secret storage not supported")); - goto cleanup; - } + conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); + if (!conn) + return -1; enc = vol->target.encryption; if (enc->nsecrets != 0) { @@ -557,7 +552,7 @@ virStorageGenerateQcowEncryption(virConnectPtr conn, if (xml == NULL) goto cleanup; - secret = conn->secretDriver->secretDefineXML(conn, xml, 0); + secret = virSecretDefineXML(conn, xml, 0); if (secret == NULL) { VIR_FREE(xml); goto cleanup; @@ -567,7 +562,7 @@ virStorageGenerateQcowEncryption(virConnectPtr conn, if (virStorageGenerateQcowPassphrase(value) < 0) goto cleanup; - if (conn->secretDriver->secretSetValue(secret, value, sizeof(value), 0) < 0) + if (virSecretSetValue(secret, value, sizeof(value), 0) < 0) goto cleanup; enc_secret->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE; @@ -582,11 +577,11 @@ virStorageGenerateQcowEncryption(virConnectPtr conn, cleanup: if (secret != NULL) { - if (ret != 0 && - conn->secretDriver->secretUndefine != NULL) - conn->secretDriver->secretUndefine(secret); + if (ret != 0) + virSecretUndefine(secret); virObjectUnref(secret); } + virObjectUnref(conn); virBufferFreeAndReset(&buf); virSecretDefFree(def); VIR_FREE(enc_secret); @@ -942,7 +937,6 @@ storageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc, static int storageBackendCreateQemuImgCheckEncryption(int format, const char *type, - virConnectPtr conn, virStorageVolDefPtr vol) { virStorageEncryptionPtr enc = vol->target.encryption; @@ -962,7 +956,7 @@ storageBackendCreateQemuImgCheckEncryption(int format, } if (enc->format == VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT || enc->nsecrets == 0) { - if (virStorageGenerateQcowEncryption(conn, vol) < 0) + if (virStorageGenerateQcowEncryption(vol) < 0) return -1; } } else if (format == VIR_STORAGE_FILE_RAW) { @@ -1178,8 +1172,7 @@ storageBackendResizeQemuImgImageOpts(virCommandPtr cmd, * volume definitions and imgformat */ virCommandPtr -virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, - virStoragePoolObjPtr pool, +virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags, @@ -1264,7 +1257,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, if (info.encryption && storageBackendCreateQemuImgCheckEncryption(info.format, type, - conn, vol) < 0) + vol) < 0) return NULL; @@ -1317,8 +1310,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, static char * -storageBackendCreateQemuImgSecretPath(virConnectPtr conn, - virStoragePoolObjPtr pool, +storageBackendCreateQemuImgSecretPath(virStoragePoolObjPtr pool, virStorageVolDefPtr vol) { virStorageEncryptionPtr enc = vol->target.encryption; @@ -1326,6 +1318,7 @@ storageBackendCreateQemuImgSecretPath(virConnectPtr conn, int fd = -1; uint8_t *secret = NULL; size_t secretlen = 0; + virConnectPtr conn = NULL; if (!enc) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1333,14 +1326,9 @@ storageBackendCreateQemuImgSecretPath(virConnectPtr conn, return NULL; } - if (!conn || !conn->secretDriver || - !conn->secretDriver->secretLookupByUUID || - !conn->secretDriver->secretLookupByUsage || - !conn->secretDriver->secretGetValue) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("unable to look up encryption secret")); + conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); + if (!conn) return NULL; - } if (!(secretPath = virStoragePoolObjBuildTempFilePath(pool, vol))) goto cleanup; @@ -1374,6 +1362,7 @@ storageBackendCreateQemuImgSecretPath(virConnectPtr conn, } cleanup: + virObjectUnref(conn); VIR_DISPOSE_N(secret, secretlen); VIR_FORCE_CLOSE(fd); @@ -1387,7 +1376,7 @@ storageBackendCreateQemuImgSecretPath(virConnectPtr conn, static int -storageBackendCreateQemuImg(virConnectPtr conn, +storageBackendCreateQemuImg(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, @@ -1417,11 +1406,11 @@ storageBackendCreateQemuImg(virConnectPtr conn, vol->target.encryption && vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) { if (!(secretPath = - storageBackendCreateQemuImgSecretPath(conn, pool, vol))) + storageBackendCreateQemuImgSecretPath(pool, vol))) goto cleanup; } - cmd = virStorageBackendCreateQemuImgCmdFromVol(conn, pool, vol, inputvol, + cmd = virStorageBackendCreateQemuImgCmdFromVol(pool, vol, inputvol, flags, create_tool, imgformat, secretPath); if (!cmd) @@ -1442,7 +1431,6 @@ storageBackendCreateQemuImg(virConnectPtr conn, /** * virStorageBackendCreateVolUsingQemuImg - * @conn: Connection pointer * @pool: Storage Pool Object * @vol: Volume definition * @inputvol: Volume to use for creation @@ -1458,8 +1446,7 @@ storageBackendCreateQemuImg(virConnectPtr conn, * Returns: 0 on success, -1 on failure. */ int -virStorageBackendCreateVolUsingQemuImg(virConnectPtr conn, - virStoragePoolObjPtr pool, +virStorageBackendCreateVolUsingQemuImg(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -1472,7 +1459,7 @@ virStorageBackendCreateVolUsingQemuImg(virConnectPtr conn, changeFormat = true; } - ret = storageBackendCreateQemuImg(conn, pool, vol, inputvol, flags); + ret = storageBackendCreateQemuImg(NULL, pool, vol, inputvol, flags); if (changeFormat) vol->target.format = VIR_STORAGE_FILE_NONE; @@ -2290,7 +2277,6 @@ virStorageBackendVolDeleteLocal(virConnectPtr conn ATTRIBUTE_UNUSED, /* storageBackendLoadDefaultSecrets: - * @conn: Connection pointer to fetch secret * @vol: volume being refreshed * * If the volume had a secret generated, we need to regenerate the @@ -2300,15 +2286,19 @@ virStorageBackendVolDeleteLocal(virConnectPtr conn ATTRIBUTE_UNUSED, * -1 on failures w/ error message set */ static int -storageBackendLoadDefaultSecrets(virConnectPtr conn, - virStorageVolDefPtr vol) +storageBackendLoadDefaultSecrets(virStorageVolDefPtr vol) { virSecretPtr sec; virStorageEncryptionSecretPtr encsec = NULL; + virConnectPtr conn = NULL; if (!vol->target.encryption || vol->target.encryption->nsecrets != 0) return 0; + conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); + if (!conn) + return -1; + /* The encryption secret for qcow2 and luks volumes use the path * to the volume, so look for a secret with the path. If not found, * then we cannot generate the secret after a refresh (or restart). @@ -2316,8 +2306,10 @@ storageBackendLoadDefaultSecrets(virConnectPtr conn, * a usage string that although matched with the secret usage string, * didn't contain the path to the volume. We won't error in that case, * but we also cannot find the secret. */ - if (!(sec = virSecretLookupByUsage(conn, VIR_SECRET_USAGE_TYPE_VOLUME, - vol->target.path))) + sec = virSecretLookupByUsage(conn, VIR_SECRET_USAGE_TYPE_VOLUME, + vol->target.path); + virObjectUnref(conn); + if (!sec) return 0; if (VIR_ALLOC_N(vol->target.encryption->secrets, 1) < 0 || @@ -2343,7 +2335,7 @@ storageBackendLoadDefaultSecrets(virConnectPtr conn, * Update info about a volume's capacity/allocation */ int -virStorageBackendVolRefreshLocal(virConnectPtr conn, +virStorageBackendVolRefreshLocal(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { @@ -2356,13 +2348,12 @@ virStorageBackendVolRefreshLocal(virConnectPtr conn, return ret; /* Load any secrets if possible */ - return storageBackendLoadDefaultSecrets(conn, vol); + return storageBackendLoadDefaultSecrets(vol); } static int -storageBackendResizeQemuImg(virConnectPtr conn, - virStoragePoolObjPtr pool, +storageBackendResizeQemuImg(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned long long capacity) { @@ -2386,14 +2377,14 @@ storageBackendResizeQemuImg(virConnectPtr conn, else type = virStorageFileFormatTypeToString(vol->target.format); - storageBackendLoadDefaultSecrets(conn, vol); + storageBackendLoadDefaultSecrets(vol); if (storageBackendCreateQemuImgCheckEncryption(vol->target.format, - type, NULL, vol) < 0) + type, vol) < 0) goto cleanup; if (!(secretPath = - storageBackendCreateQemuImgSecretPath(conn, pool, vol))) + storageBackendCreateQemuImgSecretPath(pool, vol))) goto cleanup; if (virAsprintf(&secretAlias, "%s_luks0", vol->name) < 0) @@ -2438,7 +2429,7 @@ storageBackendResizeQemuImg(virConnectPtr conn, * Resize a volume */ int -virStorageBackendVolResizeLocal(virConnectPtr conn, +virStorageBackendVolResizeLocal(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned long long capacity, @@ -2459,7 +2450,7 @@ virStorageBackendVolResizeLocal(virConnectPtr conn, return -1; } - return storageBackendResizeQemuImg(conn, pool, vol, capacity); + return storageBackendResizeQemuImg(pool, vol, capacity); } else if (vol->target.format == VIR_STORAGE_FILE_PLOOP) { return storagePloopResize(vol, capacity); } else { @@ -2470,7 +2461,7 @@ virStorageBackendVolResizeLocal(virConnectPtr conn, return -1; } - return storageBackendResizeQemuImg(conn, pool, vol, capacity); + return storageBackendResizeQemuImg(pool, vol, capacity); } } diff --git a/src/storage/storage_util.h b/src/storage/storage_util.h index dc7e62517b..ffc83c60ab 100644 --- a/src/storage/storage_util.h +++ b/src/storage/storage_util.h @@ -29,8 +29,7 @@ /* File creation/cloning functions used for cloning between backends */ int -virStorageBackendCreateVolUsingQemuImg(virConnectPtr conn, - virStoragePoolObjPtr pool, +virStorageBackendCreateVolUsingQemuImg(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags); @@ -166,8 +165,7 @@ char *virStorageBackendStablePath(virStoragePoolObjPtr pool, bool loop); virCommandPtr -virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, - virStoragePoolObjPtr pool, +virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags, -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list