Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
I forgot to include virsh changes in the series introducing
virDomainMigrateSetDowntime API call, so here it is...
tools/virsh.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index aa85ee6..f004ac0 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -125,6 +125,7 @@ typedef enum {
VSH_OT_BOOL, /* boolean option */
VSH_OT_STRING, /* string option */
VSH_OT_INT, /* int option */
+ VSH_OT_FLOAT, /* decimal option */
VSH_OT_DATA /* string data (as non-option) */
} vshCmdOptType;
@@ -227,6 +228,8 @@ static vshCmdOpt *vshCommandOpt(const vshCmd *cmd, const char *name);
static int vshCommandOptInt(const vshCmd *cmd, const char *name, int *found);
static char *vshCommandOptString(const vshCmd *cmd, const char *name,
int *found);
+static double vshCommandOptFloat(const vshCmd *cmd, const char *name,
+ int *found);
#if 0
static int vshCommandOptStringList(const vshCmd *cmd, const char *name, char ***data);
#endif
@@ -2747,6 +2750,7 @@ static const vshCmdOptDef opts_migrate[] = {
{"persistent", VSH_OT_BOOL, 0, N_("persist VM on destination")},
{"undefinesource", VSH_OT_BOOL, 0, N_("undefine VM on source")},
{"suspend", VSH_OT_BOOL, 0, N_("do not restart the domain on the
destination host")},
+ {"downtime", VSH_OT_FLOAT, 0, N_("maximum tolerable downtime (in
seconds) for migration")},
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the
destination host")},
{"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be
omitted")},
@@ -2762,6 +2766,7 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
const char *migrateuri;
const char *dname;
int flags = 0, found, ret = FALSE;
+ double downtime;
if (!vshConnectionUsability (ctl, ctl->conn, TRUE))
return FALSE;
@@ -2794,6 +2799,19 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool (cmd, "suspend"))
flags |= VIR_MIGRATE_PAUSED;
+ downtime = vshCommandOptFloat(cmd, "downtime", &found);
+ if (found) {
+ unsigned long long nanoseconds = downtime * 1e9;
+
+ if (nanoseconds <= 0) {
+ vshError(ctl, "%s", _("migrate: Invalid downtime"));
+ goto done;
+ }
+
+ if (virDomainMigrateSetDowntime(dom, nanoseconds))
+ goto done;
+ }
+
if ((flags & VIR_MIGRATE_PEER2PEER) ||
vshCommandOptBool (cmd, "direct")) {
/* For peer2peer migration or direct migration we only expect one URI
@@ -7938,6 +7956,9 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
else if (opt->type == VSH_OT_INT)
/* xgettext:c-format */
fmt = _("[--%s <number>]");
+ else if (opt->type == VSH_OT_FLOAT)
+ /* xgettext:c-format */
+ fmt = _("[--%s <decimal>]");
else if (opt->type == VSH_OT_STRING)
/* xgettext:c-format */
fmt = _("[--%s <string>]");
@@ -7965,6 +7986,8 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
snprintf(buf, sizeof(buf), "--%s", opt->name);
else if (opt->type == VSH_OT_INT)
snprintf(buf, sizeof(buf), _("--%s <number>"),
opt->name);
+ else if (opt->type == VSH_OT_FLOAT)
+ snprintf(buf, sizeof(buf), _("--%s <decimal>"),
opt->name);
else if (opt->type == VSH_OT_STRING)
snprintf(buf, sizeof(buf), _("--%s <string>"),
opt->name);
else if (opt->type == VSH_OT_DATA)
@@ -8065,6 +8088,30 @@ vshCommandOptString(const vshCmd *cmd, const char *name, int
*found)
return arg && arg->data && *arg->data ? arg->data : NULL;
}
+/*
+ * Returns option as DOUBLE
+ */
+static double
+vshCommandOptFloat(const vshCmd *cmd, const char *name, int *found)
+{
+ vshCmdOpt *arg = vshCommandOpt(cmd, name);
+ int num_found = FALSE;
+ double res = 0;
+ char *end_p = NULL;
+
+ if ((arg != NULL) && (arg->data != NULL)) {
+ errno = 0;
+ res = strtod(arg->data, &end_p);
+ if ((arg->data == end_p) || (*end_p != 0) || errno)
+ num_found = FALSE;
+ else
+ num_found = TRUE;
+ }
+ if (found)
+ *found = num_found;
+ return res;
+}
+
#if 0
static int
vshCommandOptStringList(const vshCmd *cmd, const char *name, char ***data)
@@ -8576,11 +8623,20 @@ vshCommandParse(vshControl *ctl, char *cmdstr)
if (tk == VSH_TK_ERROR)
goto syntaxError;
if (tk != VSH_TK_DATA) {
+ const char *type;
+ switch (opt->type) {
+ case VSH_OT_INT:
+ type = _("number");
+ break;
+ case VSH_OT_FLOAT:
+ type = _("decimal");
+ break;
+ default:
+ type = _("string");
+ }
vshError(ctl,
_("expected syntax: --%s <%s>"),
- opt->name,
- opt->type ==
- VSH_OT_INT ? _("number") :
_("string"));
+ opt->name, type);
goto syntaxError;
}
}
--
1.7.0.2