提交 8312d44d 编写于 作者: E Erik Skultety 提交者: Peter Krempa

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
上级 52691f99
...@@ -1709,6 +1709,17 @@ static void vshCatchInt(int sig ATTRIBUTE_UNUSED, ...@@ -1709,6 +1709,17 @@ static void vshCatchInt(int sig ATTRIBUTE_UNUSED,
intCaught = 1; 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 * "blockcommit" command
*/ */
...@@ -1808,6 +1819,8 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd) ...@@ -1808,6 +1819,8 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
const char *path = NULL; const char *path = NULL;
bool quit = false; bool quit = false;
int abort_flags = 0; int abort_flags = 0;
int status = -1;
int cb_id = -1;
blocking |= vshCommandOptBool(cmd, "timeout") || pivot || finish; blocking |= vshCommandOptBool(cmd, "timeout") || pivot || finish;
if (blocking) { if (blocking) {
...@@ -1837,6 +1850,17 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd) ...@@ -1837,6 +1850,17 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
return false; 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)) if (!blockJobImpl(ctl, cmd, VSH_CMD_BLOCK_JOB_COMMIT, &dom))
goto cleanup; goto cleanup;
...@@ -1878,7 +1902,7 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd) ...@@ -1878,7 +1902,7 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
intCaught ? "interrupted" : "timeout"); intCaught ? "interrupted" : "timeout");
intCaught = 0; intCaught = 0;
timeout = 0; timeout = 0;
quit = true; status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) { if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
vshError(ctl, _("failed to abort job for disk %s"), path); vshError(ctl, _("failed to abort job for disk %s"), path);
goto cleanup; goto cleanup;
...@@ -1890,6 +1914,9 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd) ...@@ -1890,6 +1914,9 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
} }
} }
if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
quit = true;
if (verbose && !quit) { if (verbose && !quit) {
/* printf [100 %] */ /* printf [100 %] */
vshPrintJobProgress(_("Block Commit"), 0, 1); vshPrintJobProgress(_("Block Commit"), 0, 1);
...@@ -1920,6 +1947,8 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd) ...@@ -1920,6 +1947,8 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
virDomainFree(dom); virDomainFree(dom);
if (blocking) if (blocking)
sigaction(SIGINT, &old_sig_action, NULL); sigaction(SIGINT, &old_sig_action, NULL);
if (cb_id >= 0)
virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
return ret; return ret;
} }
...@@ -2043,6 +2072,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) ...@@ -2043,6 +2072,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
char *xmlstr = NULL; char *xmlstr = NULL;
virTypedParameterPtr params = NULL; virTypedParameterPtr params = NULL;
int nparams = 0; int nparams = 0;
int status = -1;
int cb_id = -1;
if (vshCommandOptStringReq(ctl, cmd, "path", &path) < 0) if (vshCommandOptStringReq(ctl, cmd, "path", &path) < 0)
return false; return false;
...@@ -2083,6 +2114,17 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) ...@@ -2083,6 +2114,17 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
return false; 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))) if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
goto cleanup; goto cleanup;
...@@ -2216,7 +2258,7 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) ...@@ -2216,7 +2258,7 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
intCaught ? "interrupted" : "timeout"); intCaught ? "interrupted" : "timeout");
intCaught = 0; intCaught = 0;
timeout = 0; timeout = 0;
quit = true; status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) { if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
vshError(ctl, _("failed to abort job for disk %s"), path); vshError(ctl, _("failed to abort job for disk %s"), path);
goto cleanup; goto cleanup;
...@@ -2228,6 +2270,9 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) ...@@ -2228,6 +2270,9 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
} }
} }
if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
quit = true;
if (!quit && pivot) { if (!quit && pivot) {
abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT; abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT;
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) { if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
...@@ -2256,6 +2301,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) ...@@ -2256,6 +2301,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
virDomainFree(dom); virDomainFree(dom);
if (blocking) if (blocking)
sigaction(SIGINT, &old_sig_action, NULL); sigaction(SIGINT, &old_sig_action, NULL);
if (cb_id >= 0)
virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
return ret; return ret;
} }
...@@ -2513,6 +2560,8 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd) ...@@ -2513,6 +2560,8 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
const char *path = NULL; const char *path = NULL;
bool quit = false; bool quit = false;
int abort_flags = 0; int abort_flags = 0;
int status = -1;
int cb_id = -1;
if (blocking) { if (blocking) {
if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0) if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
...@@ -2538,6 +2587,17 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd) ...@@ -2538,6 +2587,17 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
return false; 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)) if (!blockJobImpl(ctl, cmd, VSH_CMD_BLOCK_JOB_PULL, &dom))
goto cleanup; goto cleanup;
...@@ -2574,7 +2634,7 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd) ...@@ -2574,7 +2634,7 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
intCaught ? "interrupted" : "timeout"); intCaught ? "interrupted" : "timeout");
intCaught = 0; intCaught = 0;
timeout = 0; timeout = 0;
quit = true; status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) { if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
vshError(ctl, _("failed to abort job for disk %s"), path); vshError(ctl, _("failed to abort job for disk %s"), path);
goto cleanup; goto cleanup;
...@@ -2586,6 +2646,9 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd) ...@@ -2586,6 +2646,9 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
} }
} }
if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
quit = true;
if (verbose && !quit) { if (verbose && !quit) {
/* printf [100 %] */ /* printf [100 %] */
vshPrintJobProgress(_("Block Pull"), 0, 1); vshPrintJobProgress(_("Block Pull"), 0, 1);
...@@ -2598,6 +2661,8 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd) ...@@ -2598,6 +2661,8 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
virDomainFree(dom); virDomainFree(dom);
if (blocking) if (blocking)
sigaction(SIGINT, &old_sig_action, NULL); sigaction(SIGINT, &old_sig_action, NULL);
if (cb_id >= 0)
virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册