mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
virsh: Fix msg: blockjob is aborted from another client
When a block{pull, copy, commit} is aborted via keyboard interrupt, the job is properly canceled followed by proper error message. However, when the job receives an abort from another client connected to the same domain, the error message incorrectly indicates that a blockjob has been finished successfully, though the abort request took effect. This patch introduces a new blockjob abort handler, which is registered when the client calls block{copy,commit,pull} routine, providing its caller the status of the finished blockjob. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1135442
This commit is contained in:
parent
52691f99fa
commit
8312d44d72
@ -1709,6 +1709,17 @@ static void vshCatchInt(int sig ATTRIBUTE_UNUSED,
|
||||
intCaught = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
vshBlockJobStatusHandler(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom ATTRIBUTE_UNUSED,
|
||||
const char *disk ATTRIBUTE_UNUSED,
|
||||
int type ATTRIBUTE_UNUSED,
|
||||
int status,
|
||||
void *opaque)
|
||||
{
|
||||
*(int *) opaque = status;
|
||||
}
|
||||
|
||||
/*
|
||||
* "blockcommit" command
|
||||
*/
|
||||
@ -1808,6 +1819,8 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
||||
const char *path = NULL;
|
||||
bool quit = false;
|
||||
int abort_flags = 0;
|
||||
int status = -1;
|
||||
int cb_id = -1;
|
||||
|
||||
blocking |= vshCommandOptBool(cmd, "timeout") || pivot || finish;
|
||||
if (blocking) {
|
||||
@ -1837,6 +1850,17 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
||||
return false;
|
||||
}
|
||||
|
||||
virConnectDomainEventGenericCallback cb =
|
||||
VIR_DOMAIN_EVENT_CALLBACK(vshBlockJobStatusHandler);
|
||||
|
||||
if ((cb_id = virConnectDomainEventRegisterAny(ctl->conn,
|
||||
dom,
|
||||
VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
|
||||
cb,
|
||||
&status,
|
||||
NULL)) < 0)
|
||||
vshResetLibvirtError();
|
||||
|
||||
if (!blockJobImpl(ctl, cmd, VSH_CMD_BLOCK_JOB_COMMIT, &dom))
|
||||
goto cleanup;
|
||||
|
||||
@ -1878,7 +1902,7 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
||||
intCaught ? "interrupted" : "timeout");
|
||||
intCaught = 0;
|
||||
timeout = 0;
|
||||
quit = true;
|
||||
status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
|
||||
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
||||
vshError(ctl, _("failed to abort job for disk %s"), path);
|
||||
goto cleanup;
|
||||
@ -1890,6 +1914,9 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
|
||||
quit = true;
|
||||
|
||||
if (verbose && !quit) {
|
||||
/* printf [100 %] */
|
||||
vshPrintJobProgress(_("Block Commit"), 0, 1);
|
||||
@ -1920,6 +1947,8 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
||||
virDomainFree(dom);
|
||||
if (blocking)
|
||||
sigaction(SIGINT, &old_sig_action, NULL);
|
||||
if (cb_id >= 0)
|
||||
virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2043,6 +2072,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
|
||||
char *xmlstr = NULL;
|
||||
virTypedParameterPtr params = NULL;
|
||||
int nparams = 0;
|
||||
int status = -1;
|
||||
int cb_id = -1;
|
||||
|
||||
if (vshCommandOptStringReq(ctl, cmd, "path", &path) < 0)
|
||||
return false;
|
||||
@ -2083,6 +2114,17 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
|
||||
return false;
|
||||
}
|
||||
|
||||
virConnectDomainEventGenericCallback cb =
|
||||
VIR_DOMAIN_EVENT_CALLBACK(vshBlockJobStatusHandler);
|
||||
|
||||
if ((cb_id = virConnectDomainEventRegisterAny(ctl->conn,
|
||||
dom,
|
||||
VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
|
||||
cb,
|
||||
&status,
|
||||
NULL)) < 0)
|
||||
vshResetLibvirtError();
|
||||
|
||||
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
@ -2216,7 +2258,7 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
|
||||
intCaught ? "interrupted" : "timeout");
|
||||
intCaught = 0;
|
||||
timeout = 0;
|
||||
quit = true;
|
||||
status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
|
||||
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
||||
vshError(ctl, _("failed to abort job for disk %s"), path);
|
||||
goto cleanup;
|
||||
@ -2228,6 +2270,9 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
|
||||
quit = true;
|
||||
|
||||
if (!quit && pivot) {
|
||||
abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT;
|
||||
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
||||
@ -2256,6 +2301,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
|
||||
virDomainFree(dom);
|
||||
if (blocking)
|
||||
sigaction(SIGINT, &old_sig_action, NULL);
|
||||
if (cb_id >= 0)
|
||||
virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2513,6 +2560,8 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
|
||||
const char *path = NULL;
|
||||
bool quit = false;
|
||||
int abort_flags = 0;
|
||||
int status = -1;
|
||||
int cb_id = -1;
|
||||
|
||||
if (blocking) {
|
||||
if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
|
||||
@ -2538,6 +2587,17 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
|
||||
return false;
|
||||
}
|
||||
|
||||
virConnectDomainEventGenericCallback cb =
|
||||
VIR_DOMAIN_EVENT_CALLBACK(vshBlockJobStatusHandler);
|
||||
|
||||
if ((cb_id = virConnectDomainEventRegisterAny(ctl->conn,
|
||||
dom,
|
||||
VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
|
||||
cb,
|
||||
&status,
|
||||
NULL)) < 0)
|
||||
vshResetLibvirtError();
|
||||
|
||||
if (!blockJobImpl(ctl, cmd, VSH_CMD_BLOCK_JOB_PULL, &dom))
|
||||
goto cleanup;
|
||||
|
||||
@ -2574,7 +2634,7 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
|
||||
intCaught ? "interrupted" : "timeout");
|
||||
intCaught = 0;
|
||||
timeout = 0;
|
||||
quit = true;
|
||||
status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
|
||||
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
||||
vshError(ctl, _("failed to abort job for disk %s"), path);
|
||||
goto cleanup;
|
||||
@ -2586,6 +2646,9 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
|
||||
quit = true;
|
||||
|
||||
if (verbose && !quit) {
|
||||
/* printf [100 %] */
|
||||
vshPrintJobProgress(_("Block Pull"), 0, 1);
|
||||
@ -2598,6 +2661,8 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
|
||||
virDomainFree(dom);
|
||||
if (blocking)
|
||||
sigaction(SIGINT, &old_sig_action, NULL);
|
||||
if (cb_id >= 0)
|
||||
virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user