mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 03:42:19 +00:00
qemu: blockPull: Refactor the rest of qemuDomainBlockJobImpl
Since it now handles only block pull code paths we can refactor it and remove tons of cruft.
This commit is contained in:
parent
cfc0a3d4ce
commit
065a81082d
@ -16238,17 +16238,16 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
|
|||||||
/* bandwidth in MiB/s per public API. Caller must lock vm beforehand,
|
/* bandwidth in MiB/s per public API. Caller must lock vm beforehand,
|
||||||
* and not access it afterwards. */
|
* and not access it afterwards. */
|
||||||
static int
|
static int
|
||||||
qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
qemuDomainBlockPullCommon(virQEMUDriverPtr driver,
|
||||||
virConnectPtr conn,
|
virDomainObjPtr vm,
|
||||||
const char *path, const char *base,
|
const char *path,
|
||||||
|
const char *base,
|
||||||
unsigned long bandwidth,
|
unsigned long bandwidth,
|
||||||
int mode, unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virQEMUDriverPtr driver = conn->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
qemuDomainObjPrivatePtr priv;
|
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
int ret = -1;
|
bool modern;
|
||||||
bool async = false;
|
|
||||||
int idx;
|
int idx;
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
virStorageSourcePtr baseSource = NULL;
|
virStorageSourcePtr baseSource = NULL;
|
||||||
@ -16256,12 +16255,7 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
char *basePath = NULL;
|
char *basePath = NULL;
|
||||||
char *backingPath = NULL;
|
char *backingPath = NULL;
|
||||||
unsigned long long speed = bandwidth;
|
unsigned long long speed = bandwidth;
|
||||||
|
int ret = -1;
|
||||||
if (!virDomainObjIsActive(vm)) {
|
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
||||||
_("domain is not running"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE && !base) {
|
if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE && !base) {
|
||||||
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
@ -16270,24 +16264,24 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = vm->privateData;
|
if (qemuDomainSupportsBlockJobs(vm, &modern) < 0)
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC)) {
|
|
||||||
async = true;
|
|
||||||
} else if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_SYNC)) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
||||||
_("block jobs not supported with this QEMU binary"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else if (base) {
|
|
||||||
|
if (!modern) {
|
||||||
|
if (base) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("partial block pull not supported with this "
|
_("partial block pull not supported with this "
|
||||||
"QEMU binary"));
|
"QEMU binary"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else if (mode == BLOCK_JOB_PULL && bandwidth) {
|
}
|
||||||
|
|
||||||
|
if (bandwidth) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("setting bandwidth at start of block pull not "
|
_("setting bandwidth at start of block pull not "
|
||||||
"supported with this QEMU binary"));
|
"supported with this QEMU binary"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -16298,12 +16292,11 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = qemuDiskPathToAlias(vm, path, &idx);
|
if (!(device = qemuDiskPathToAlias(vm, path, &idx)))
|
||||||
if (!device)
|
|
||||||
goto endjob;
|
goto endjob;
|
||||||
disk = vm->def->disks[idx];
|
disk = vm->def->disks[idx];
|
||||||
|
|
||||||
if (mode == BLOCK_JOB_PULL && qemuDomainDiskBlockJobIsActive(disk))
|
if (qemuDomainDiskBlockJobIsActive(disk))
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
if (base &&
|
if (base &&
|
||||||
@ -16326,7 +16319,6 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
&backingPath) < 0)
|
&backingPath) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
|
|
||||||
if (!backingPath) {
|
if (!backingPath) {
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
_("can't keep relative backing relationship"));
|
_("can't keep relative backing relationship"));
|
||||||
@ -16336,8 +16328,7 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert bandwidth MiB to bytes, if needed */
|
/* Convert bandwidth MiB to bytes, if needed */
|
||||||
if (mode == BLOCK_JOB_PULL &&
|
if (!(flags & VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES)) {
|
||||||
!(flags & VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES)) {
|
|
||||||
if (speed > LLONG_MAX >> 20) {
|
if (speed > LLONG_MAX >> 20) {
|
||||||
virReportError(VIR_ERR_OVERFLOW,
|
virReportError(VIR_ERR_OVERFLOW,
|
||||||
_("bandwidth must be less than %llu"),
|
_("bandwidth must be less than %llu"),
|
||||||
@ -16352,15 +16343,15 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
|
basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
|
||||||
baseSource);
|
baseSource);
|
||||||
if (!baseSource || basePath)
|
if (!baseSource || basePath)
|
||||||
ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
|
ret = qemuMonitorBlockStream(priv->mon, device, basePath, backingPath,
|
||||||
speed, mode, async);
|
speed, modern);
|
||||||
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
if (ret < 0) {
|
|
||||||
|
if (ret < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
} else if (mode == BLOCK_JOB_PULL) {
|
|
||||||
disk->blockjob = true;
|
disk->blockjob = true;
|
||||||
}
|
|
||||||
|
|
||||||
endjob:
|
endjob:
|
||||||
qemuDomainObjEndJob(driver, vm);
|
qemuDomainObjEndJob(driver, vm);
|
||||||
@ -16373,6 +16364,7 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemuDomainBlockJobAbort(virDomainPtr dom,
|
qemuDomainBlockJobAbort(virDomainPtr dom,
|
||||||
const char *path,
|
const char *path,
|
||||||
@ -16855,6 +16847,7 @@ static int
|
|||||||
qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
|
qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
|
||||||
unsigned long bandwidth, unsigned int flags)
|
unsigned long bandwidth, unsigned int flags)
|
||||||
{
|
{
|
||||||
|
virQEMUDriverPtr driver = dom->conn->privateData;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
unsigned long long speed = bandwidth;
|
unsigned long long speed = bandwidth;
|
||||||
@ -16877,8 +16870,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
|
|||||||
/* For normal rebase (enhanced blockpull), the common code handles
|
/* For normal rebase (enhanced blockpull), the common code handles
|
||||||
* everything, including vm cleanup. */
|
* everything, including vm cleanup. */
|
||||||
if (!(flags & VIR_DOMAIN_BLOCK_REBASE_COPY))
|
if (!(flags & VIR_DOMAIN_BLOCK_REBASE_COPY))
|
||||||
return qemuDomainBlockJobImpl(vm, dom->conn, path, base, bandwidth,
|
return qemuDomainBlockPullCommon(driver, vm, path, base, bandwidth, flags);
|
||||||
BLOCK_JOB_PULL, flags);
|
|
||||||
|
|
||||||
/* If we got here, we are doing a block copy rebase. */
|
/* If we got here, we are doing a block copy rebase. */
|
||||||
if (VIR_ALLOC(dest) < 0)
|
if (VIR_ALLOC(dest) < 0)
|
||||||
@ -17016,8 +17008,8 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qemuDomainBlockJobImpl(vm, dom->conn, path, NULL, bandwidth,
|
return qemuDomainBlockPullCommon(dom->conn->privateData,
|
||||||
BLOCK_JOB_PULL, flags);
|
vm, path, NULL, bandwidth, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3577,28 +3577,26 @@ int qemuMonitorScreendump(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
/* bandwidth is in bytes/sec */
|
/* bandwidth is in bytes/sec */
|
||||||
int
|
int
|
||||||
qemuMonitorBlockJob(qemuMonitorPtr mon,
|
qemuMonitorBlockStream(qemuMonitorPtr mon,
|
||||||
const char *device,
|
const char *device,
|
||||||
const char *base,
|
const char *base,
|
||||||
const char *backingName,
|
const char *backingName,
|
||||||
unsigned long long bandwidth,
|
unsigned long long bandwidth,
|
||||||
qemuMonitorBlockJobCmd mode,
|
|
||||||
bool modern)
|
bool modern)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
VIR_DEBUG("mon=%p, device=%s, base=%s, backingName=%s, bandwidth=%lluB, "
|
VIR_DEBUG("mon=%p, device=%s, base=%s, backingName=%s, bandwidth=%lluB, "
|
||||||
"mode=%o, modern=%d",
|
"modern=%d",
|
||||||
mon, device, NULLSTR(base), NULLSTR(backingName),
|
mon, device, NULLSTR(base), NULLSTR(backingName),
|
||||||
bandwidth, mode, modern);
|
bandwidth, modern);
|
||||||
|
|
||||||
if (mon->json)
|
if (!mon->json) {
|
||||||
ret = qemuMonitorJSONBlockJob(mon, device, base, backingName,
|
|
||||||
bandwidth, mode, modern);
|
|
||||||
else
|
|
||||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
||||||
_("block jobs require JSON monitor"));
|
_("block jobs require JSON monitor"));
|
||||||
return ret;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return qemuMonitorJSONBlockStream(mon, device, base, backingName,
|
||||||
|
bandwidth, modern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -755,16 +755,11 @@ int qemuMonitorSendKey(qemuMonitorPtr mon,
|
|||||||
unsigned int *keycodes,
|
unsigned int *keycodes,
|
||||||
unsigned int nkeycodes);
|
unsigned int nkeycodes);
|
||||||
|
|
||||||
typedef enum {
|
int qemuMonitorBlockStream(qemuMonitorPtr mon,
|
||||||
BLOCK_JOB_PULL,
|
|
||||||
} qemuMonitorBlockJobCmd;
|
|
||||||
|
|
||||||
int qemuMonitorBlockJob(qemuMonitorPtr mon,
|
|
||||||
const char *device,
|
const char *device,
|
||||||
const char *base,
|
const char *base,
|
||||||
const char *backingName,
|
const char *backingName,
|
||||||
unsigned long long bandwidth,
|
unsigned long long bandwidth,
|
||||||
qemuMonitorBlockJobCmd mode,
|
|
||||||
bool modern)
|
bool modern)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
@ -4282,57 +4282,24 @@ qemuMonitorJSONBlockJobError(virJSONValuePtr reply,
|
|||||||
|
|
||||||
/* speed is in bytes/sec */
|
/* speed is in bytes/sec */
|
||||||
int
|
int
|
||||||
qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
|
qemuMonitorJSONBlockStream(qemuMonitorPtr mon,
|
||||||
const char *device,
|
const char *device,
|
||||||
const char *base,
|
const char *base,
|
||||||
const char *backingName,
|
const char *backingName,
|
||||||
unsigned long long speed,
|
unsigned long long speed,
|
||||||
qemuMonitorBlockJobCmd mode,
|
|
||||||
bool modern)
|
bool modern)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virJSONValuePtr cmd = NULL;
|
virJSONValuePtr cmd = NULL;
|
||||||
virJSONValuePtr reply = NULL;
|
virJSONValuePtr reply = NULL;
|
||||||
const char *cmd_name = NULL;
|
const char *cmd_name = modern ? "block-stream" : "block_stream";
|
||||||
|
|
||||||
if (base && (mode != BLOCK_JOB_PULL || !modern)) {
|
if (!(cmd = qemuMonitorJSONMakeCommand(cmd_name,
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("only modern block pull supports base: %s"), base);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backingName && mode != BLOCK_JOB_PULL) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("backing name is supported only for block pull"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backingName && !base) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("backing name requires a base image"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (speed && mode == BLOCK_JOB_PULL && !modern) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("only modern block pull supports speed: %llu"),
|
|
||||||
speed);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case BLOCK_JOB_PULL:
|
|
||||||
cmd_name = modern ? "block-stream" : "block_stream";
|
|
||||||
cmd = qemuMonitorJSONMakeCommand(cmd_name,
|
|
||||||
"s:device", device,
|
"s:device", device,
|
||||||
"Y:speed", speed,
|
"Y:speed", speed,
|
||||||
"S:base", base,
|
"S:base", base,
|
||||||
"S:backing-file", backingName,
|
"S:backing-file", backingName,
|
||||||
NULL);
|
NULL)))
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmd)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
@ -297,12 +297,11 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
|
|||||||
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
|
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
|
||||||
const char *file);
|
const char *file);
|
||||||
|
|
||||||
int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
|
int qemuMonitorJSONBlockStream(qemuMonitorPtr mon,
|
||||||
const char *device,
|
const char *device,
|
||||||
const char *base,
|
const char *base,
|
||||||
const char *backingName,
|
const char *backingName,
|
||||||
unsigned long long speed,
|
unsigned long long speed,
|
||||||
qemuMonitorBlockJobCmd mode,
|
|
||||||
bool modern)
|
bool modern)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user