storage: separate qemu-img command generation and execution

This allows us to create a test for the generated command line.
This commit is contained in:
Ján Tomko 2013-02-18 12:52:58 +01:00
parent 41c73f66bc
commit c6e87d1a4b
2 changed files with 67 additions and 39 deletions

View File

@ -636,17 +636,15 @@ cleanup:
return ret; return ret;
} }
virCommandPtr
static int virStorageBackendCreateQemuImgCmd(virConnectPtr conn,
virStorageBackendCreateQemuImg(virConnectPtr conn, virStoragePoolObjPtr pool,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol,
virStorageVolDefPtr vol, virStorageVolDefPtr inputvol,
virStorageVolDefPtr inputvol, unsigned int flags,
unsigned int flags) const char *create_tool,
int imgformat)
{ {
int ret = -1;
char *create_tool;
int imgformat = -1;
virCommandPtr cmd = NULL; virCommandPtr cmd = NULL;
bool do_encryption = (vol->target.encryption != NULL); bool do_encryption = (vol->target.encryption != NULL);
unsigned long long int size_arg; unsigned long long int size_arg;
@ -674,18 +672,18 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol type %d"), _("unknown storage vol type %d"),
vol->target.format); vol->target.format);
return -1; return NULL;
} }
if (inputvol && inputType == NULL) { if (inputvol && inputType == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol type %d"), _("unknown storage vol type %d"),
inputvol->target.format); inputvol->target.format);
return -1; return NULL;
} }
if (preallocate && vol->target.format != VIR_STORAGE_FILE_QCOW2) { if (preallocate && vol->target.format != VIR_STORAGE_FILE_QCOW2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("metadata preallocation only available with qcow2")); _("metadata preallocation only available with qcow2"));
return -1; return NULL;
} }
if (vol->backingStore.path) { if (vol->backingStore.path) {
@ -696,7 +694,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("metadata preallocation conflicts with backing" _("metadata preallocation conflicts with backing"
" store")); " store"));
return -1; return NULL;
} }
/* XXX: Not strictly required: qemu-img has an option a different /* XXX: Not strictly required: qemu-img has an option a different
@ -709,14 +707,14 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("a different backing store cannot " "%s", _("a different backing store cannot "
"be specified.")); "be specified."));
return -1; return NULL;
} }
if (backingType == NULL) { if (backingType == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol backing store type %d"), _("unknown storage vol backing store type %d"),
vol->backingStore.format); vol->backingStore.format);
return -1; return NULL;
} }
/* Convert relative backing store paths to absolute paths for access /* Convert relative backing store paths to absolute paths for access
@ -726,7 +724,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virAsprintf(&absolutePath, "%s/%s", pool->def->target.path, virAsprintf(&absolutePath, "%s/%s", pool->def->target.path,
vol->backingStore.path) < 0) { vol->backingStore.path) < 0) {
virReportOOMError(); virReportOOMError();
return -1; return NULL;
} }
accessRetCode = access(absolutePath ? absolutePath accessRetCode = access(absolutePath ? absolutePath
: vol->backingStore.path, R_OK); : vol->backingStore.path, R_OK);
@ -735,7 +733,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virReportSystemError(errno, virReportSystemError(errno,
_("inaccessible backing store volume %s"), _("inaccessible backing store volume %s"),
vol->backingStore.path); vol->backingStore.path);
return -1; return NULL;
} }
} }
@ -747,7 +745,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("qcow volume encryption unsupported with " _("qcow volume encryption unsupported with "
"volume format %s"), type); "volume format %s"), type);
return -1; return NULL;
} }
enc = vol->target.encryption; enc = vol->target.encryption;
if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW && if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW &&
@ -755,38 +753,23 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported volume encryption format %d"), _("unsupported volume encryption format %d"),
vol->target.encryption->format); vol->target.encryption->format);
return -1; return NULL;
} }
if (enc->nsecrets > 1) { if (enc->nsecrets > 1) {
virReportError(VIR_ERR_XML_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("too many secrets for qcow encryption")); _("too many secrets for qcow encryption"));
return -1; return NULL;
} }
if (enc->format == VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT || if (enc->format == VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT ||
enc->nsecrets == 0) { enc->nsecrets == 0) {
if (virStorageGenerateQcowEncryption(conn, vol) < 0) if (virStorageGenerateQcowEncryption(conn, vol) < 0)
return -1; return NULL;
} }
} }
/* Size in KB */ /* Size in KB */
size_arg = VIR_DIV_UP(vol->capacity, 1024); size_arg = VIR_DIV_UP(vol->capacity, 1024);
/* KVM is usually ahead of qemu on features, so try that first */
create_tool = virFindFileInPath("kvm-img");
if (!create_tool)
create_tool = virFindFileInPath("qemu-img");
if (!create_tool) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("unable to find kvm-img or qemu-img"));
return -1;
}
imgformat = virStorageBackendQEMUImgBackingFormat(create_tool);
if (imgformat < 0)
goto cleanup;
cmd = virCommandNew(create_tool); cmd = virCommandNew(create_tool);
if (inputvol) { if (inputvol) {
@ -849,11 +832,48 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
} }
} }
return cmd;
}
static int
virStorageBackendCreateQemuImg(virConnectPtr conn,
virStoragePoolObjPtr pool,
virStorageVolDefPtr vol,
virStorageVolDefPtr inputvol,
unsigned int flags)
{
int ret = -1;
const char *create_tool;
int imgformat;
virCommandPtr cmd;
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, -1);
/* KVM is usually ahead of qemu on features, so try that first */
create_tool = virFindFileInPath("kvm-img");
if (!create_tool)
create_tool = virFindFileInPath("qemu-img");
if (!create_tool) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("unable to find kvm-img or qemu-img"));
return -1;
}
imgformat = virStorageBackendQEMUImgBackingFormat(create_tool);
if (imgformat < 0)
goto cleanup;
cmd = virStorageBackendCreateQemuImgCmd(conn, pool, vol, inputvol, flags,
create_tool, imgformat);
if (!cmd)
goto cleanup;
ret = virStorageBackendCreateExecCommand(pool, vol, cmd); ret = virStorageBackendCreateExecCommand(pool, vol, cmd);
virCommandFree(cmd);
cleanup: cleanup:
VIR_FREE(create_tool); VIR_FREE(create_tool);
virCommandFree(cmd);
return ret; return ret;
} }

View File

@ -156,5 +156,13 @@ int virStorageBackendRunProgNul(virStoragePoolObjPtr pool,
virStorageBackendListVolNulFunc func, virStorageBackendListVolNulFunc func,
void *data); void *data);
virCommandPtr
virStorageBackendCreateQemuImgCmd(virConnectPtr conn,
virStoragePoolObjPtr pool,
virStorageVolDefPtr vol,
virStorageVolDefPtr inputvol,
unsigned int flags,
const char *create_tool,
int imgformat);
#endif /* __VIR_STORAGE_BACKEND_H__ */ #endif /* __VIR_STORAGE_BACKEND_H__ */