|
|
7a3408 |
From 8dff17fed328807c986ee100045ff6464e0b70cf Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <8dff17fed328807c986ee100045ff6464e0b70cf@dist-git>
|
|
|
7a3408 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
7a3408 |
Date: Tue, 21 Jul 2015 16:18:34 +0200
|
|
|
7a3408 |
Subject: [PATCH] virsh: Refactor block job waiting in cmdBlockCommit
|
|
|
7a3408 |
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1227551
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1197592
|
|
|
7a3408 |
|
|
|
7a3408 |
Reuse the vshBlockJobWait infrastructure to refactor cmdBlockCommit to
|
|
|
7a3408 |
use the common code. This additionally fixes a bug when working with
|
|
|
7a3408 |
new qemus, where when doing an active commit with --pivot the pivoting
|
|
|
7a3408 |
would fail, since qemu reaches 100% completion but the job doesn't
|
|
|
7a3408 |
switch to synchronized phase right away.
|
|
|
7a3408 |
|
|
|
7a3408 |
(cherry picked from commit 7408403560f7d054da75acaab855a95c51a92e2b)
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
tools/virsh-domain.c | 133 ++++++++++++++++-----------------------------------
|
|
|
7a3408 |
1 file changed, 40 insertions(+), 93 deletions(-)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
|
|
|
7a3408 |
index 385eba2..8c5ef34 100644
|
|
|
7a3408 |
--- a/tools/virsh-domain.c
|
|
|
7a3408 |
+++ b/tools/virsh-domain.c
|
|
|
7a3408 |
@@ -2026,20 +2026,13 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
|
|
7a3408 |
bool blocking = vshCommandOptBool(cmd, "wait") || pivot || finish;
|
|
|
7a3408 |
bool async = vshCommandOptBool(cmd, "async");
|
|
|
7a3408 |
int timeout = 0;
|
|
|
7a3408 |
- struct sigaction sig_action;
|
|
|
7a3408 |
- struct sigaction old_sig_action;
|
|
|
7a3408 |
- sigset_t sigmask, oldsigmask;
|
|
|
7a3408 |
- struct timeval start;
|
|
|
7a3408 |
- struct timeval curr;
|
|
|
7a3408 |
const char *path = NULL;
|
|
|
7a3408 |
const char *base = NULL;
|
|
|
7a3408 |
const char *top = NULL;
|
|
|
7a3408 |
- bool quit = false;
|
|
|
7a3408 |
int abort_flags = 0;
|
|
|
7a3408 |
- int status = -1;
|
|
|
7a3408 |
- int cb_id = -1;
|
|
|
7a3408 |
unsigned int flags = 0;
|
|
|
7a3408 |
unsigned long bandwidth = 0;
|
|
|
7a3408 |
+ vshBlockJobWaitDataPtr bjWait = NULL;
|
|
|
7a3408 |
|
|
|
7a3408 |
VSH_EXCLUSIVE_OPTIONS("pivot", "keep-overlay");
|
|
|
7a3408 |
|
|
|
7a3408 |
@@ -2090,120 +2083,74 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
|
|
|
7a3408 |
if (async)
|
|
|
7a3408 |
abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (blocking) {
|
|
|
7a3408 |
- sigemptyset(&sigmask);
|
|
|
7a3408 |
- sigaddset(&sigmask, SIGINT);
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- intCaught = 0;
|
|
|
7a3408 |
- sig_action.sa_sigaction = vshCatchInt;
|
|
|
7a3408 |
- sig_action.sa_flags = SA_SIGINFO;
|
|
|
7a3408 |
- sigemptyset(&sig_action.sa_mask);
|
|
|
7a3408 |
- sigaction(SIGINT, &sig_action, &old_sig_action);
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- GETTIMEOFDAY(&start;;
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
-
|
|
|
7a3408 |
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
|
|
7a3408 |
return false;
|
|
|
7a3408 |
|
|
|
7a3408 |
- virConnectDomainEventGenericCallback cb =
|
|
|
7a3408 |
- VIR_DOMAIN_EVENT_CALLBACK(vshBlockJobStatusHandler);
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- if ((cb_id = virConnectDomainEventRegisterAny(ctl->conn,
|
|
|
7a3408 |
- dom,
|
|
|
7a3408 |
- VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
|
|
|
7a3408 |
- cb,
|
|
|
7a3408 |
- &status,
|
|
|
7a3408 |
- NULL)) < 0)
|
|
|
7a3408 |
- vshResetLibvirtError();
|
|
|
7a3408 |
+ if (blocking &&
|
|
|
7a3408 |
+ !(bjWait = vshBlockJobWaitInit(ctl, dom, path, _("Block commit"),
|
|
|
7a3408 |
+ verbose, timeout, async)))
|
|
|
7a3408 |
+ goto cleanup;
|
|
|
7a3408 |
|
|
|
7a3408 |
if (virDomainBlockCommit(dom, path, base, top, bandwidth, flags) < 0)
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
|
|
|
7a3408 |
if (!blocking) {
|
|
|
7a3408 |
- vshPrint(ctl, "%s", active ?
|
|
|
7a3408 |
- _("Active Block Commit started") :
|
|
|
7a3408 |
- _("Block Commit started"));
|
|
|
7a3408 |
+ if (active)
|
|
|
7a3408 |
+ vshPrint(ctl, "%s", _("Active Block Commit started"));
|
|
|
7a3408 |
+ else
|
|
|
7a3408 |
+ vshPrint(ctl, "%s", _("Block Commit started"));
|
|
|
7a3408 |
+
|
|
|
7a3408 |
ret = true;
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
- while (blocking) {
|
|
|
7a3408 |
- virDomainBlockJobInfo info;
|
|
|
7a3408 |
- int result;
|
|
|
7a3408 |
+ /* Execution continues here only if --wait or friends were specified */
|
|
|
7a3408 |
+ switch (vshBlockJobWait(bjWait)) {
|
|
|
7a3408 |
+ case -1:
|
|
|
7a3408 |
+ goto cleanup;
|
|
|
7a3408 |
|
|
|
7a3408 |
- pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
|
|
|
7a3408 |
- result = virDomainGetBlockJobInfo(dom, path, &info, 0);
|
|
|
7a3408 |
- pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
|
|
|
7a3408 |
+ case VIR_DOMAIN_BLOCK_JOB_CANCELED:
|
|
|
7a3408 |
+ vshPrint(ctl, "\n%s", _("Commit aborted"));
|
|
|
7a3408 |
+ goto cleanup;
|
|
|
7a3408 |
+ break;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (result < 0) {
|
|
|
7a3408 |
- vshError(ctl, _("failed to query job for disk %s"), path);
|
|
|
7a3408 |
+ case VIR_DOMAIN_BLOCK_JOB_FAILED:
|
|
|
7a3408 |
+ vshPrint(ctl, "\n%s", _("Commit failed"));
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
- if (result == 0)
|
|
|
7a3408 |
break;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (verbose)
|
|
|
7a3408 |
- vshPrintJobProgress(_("Block Commit"),
|
|
|
7a3408 |
- info.end - info.cur, info.end);
|
|
|
7a3408 |
- if (active && info.cur == info.end)
|
|
|
7a3408 |
+ case VIR_DOMAIN_BLOCK_JOB_READY:
|
|
|
7a3408 |
+ case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
|
|
|
7a3408 |
break;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (active) {
|
|
|
7a3408 |
+ if (pivot) {
|
|
|
7a3408 |
+ abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT;
|
|
|
7a3408 |
+ if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
|
|
7a3408 |
+ vshError(ctl, _("failed to pivot job for disk %s"), path);
|
|
|
7a3408 |
+ goto cleanup;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
|
|
|
7a3408 |
- GETTIMEOFDAY(&curr);
|
|
|
7a3408 |
- if (intCaught || (timeout &&
|
|
|
7a3408 |
- (((int)(curr.tv_sec - start.tv_sec) * 1000 +
|
|
|
7a3408 |
- (int)(curr.tv_usec - start.tv_usec) / 1000) >
|
|
|
7a3408 |
- timeout))) {
|
|
|
7a3408 |
- vshDebug(ctl, VSH_ERR_DEBUG,
|
|
|
7a3408 |
- intCaught ? "interrupted" : "timeout");
|
|
|
7a3408 |
- intCaught = 0;
|
|
|
7a3408 |
- timeout = 0;
|
|
|
7a3408 |
- status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
|
|
|
7a3408 |
+ vshPrint(ctl, "\n%s", _("Successfully pivoted"));
|
|
|
7a3408 |
+ } else if (finish) {
|
|
|
7a3408 |
if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
|
|
7a3408 |
- vshError(ctl, _("failed to abort job for disk %s"), path);
|
|
|
7a3408 |
+ vshError(ctl, _("failed to finish job for disk %s"), path);
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
- if (abort_flags & VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC)
|
|
|
7a3408 |
- break;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ vshPrint(ctl, "\n%s", _("Commit complete, overlay image kept"));
|
|
|
7a3408 |
} else {
|
|
|
7a3408 |
- usleep(500 * 1000);
|
|
|
7a3408 |
+ vshPrint(ctl, "\n%s", _("Now in synchronized phase"));
|
|
|
7a3408 |
}
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
|
|
|
7a3408 |
- quit = true;
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- if (verbose && !quit) {
|
|
|
7a3408 |
- /* printf [100 %] */
|
|
|
7a3408 |
- vshPrintJobProgress(_("Block Commit"), 0, 1);
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
- if (!quit && pivot) {
|
|
|
7a3408 |
- abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT;
|
|
|
7a3408 |
- if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
|
|
7a3408 |
- vshError(ctl, _("failed to pivot job for disk %s"), path);
|
|
|
7a3408 |
- goto cleanup;
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
- } else if (finish && !quit &&
|
|
|
7a3408 |
- virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
|
|
|
7a3408 |
- vshError(ctl, _("failed to finish job for disk %s"), path);
|
|
|
7a3408 |
- goto cleanup;
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
- if (quit)
|
|
|
7a3408 |
- vshPrint(ctl, "\n%s", _("Commit aborted"));
|
|
|
7a3408 |
- else if (pivot)
|
|
|
7a3408 |
- vshPrint(ctl, "\n%s", _("Successfully pivoted"));
|
|
|
7a3408 |
- else if (!finish && active)
|
|
|
7a3408 |
- vshPrint(ctl, "\n%s", _("Now in synchronized phase"));
|
|
|
7a3408 |
- else
|
|
|
7a3408 |
+ } else {
|
|
|
7a3408 |
vshPrint(ctl, "\n%s", _("Commit complete"));
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
|
|
|
7a3408 |
ret = true;
|
|
|
7a3408 |
cleanup:
|
|
|
7a3408 |
virDomainFree(dom);
|
|
|
7a3408 |
- if (blocking)
|
|
|
7a3408 |
- sigaction(SIGINT, &old_sig_action, NULL);
|
|
|
7a3408 |
- if (cb_id >= 0)
|
|
|
7a3408 |
- virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
|
|
|
7a3408 |
+ vshBlockJobWaitFree(bjWait);
|
|
|
7a3408 |
return ret;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.5.0
|
|
|
7a3408 |
|