From 222fdbfd2b852bd47d976a6305cc5cf4849824e0 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Wed, 2 Apr 2014 18:50:12 +0200 Subject: [PATCH] virsh: Expose virDomain{Get,Set}Time These APIs are exposed under new virsh command 'domtime' which both gets and sets (not at the same time of course :)). Signed-off-by: Michal Privoznik --- tools/virsh-domain-monitor.c | 116 +++++++++++++++++++++++++++++++++++ tools/virsh.pod | 18 ++++++ 2 files changed, 134 insertions(+) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 18d551aa0a..a3b66edac1 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1355,6 +1355,116 @@ cmdDomstate(vshControl *ctl, const vshCmd *cmd) return ret; } +/* + * "domtime" command + */ +static const vshCmdInfo info_domtime[] = { + {.name = "help", + .data = N_("domain time") + }, + {.name = "desc", + .data = N_("Gets or sets the domain's system time") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_domtime[] = { + {.name = "domain", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("domain name, id or uuid") + }, + {.name = "now", + .type = VSH_OT_BOOL, + .help = N_("set to the time of the host running virsh") + }, + {.name = "pretty", + .type = VSH_OT_BOOL, + .help = N_("print domain's time in human readable form") + }, + {.name = "sync", + .type = VSH_OT_BOOL, + .help = N_("instead of setting given time, synchronize from domain's RTC"), + }, + {.name = "time", + .type = VSH_OT_INT, + .help = N_("time to set") + }, + {.name = NULL} +}; + +static bool +cmdDomTime(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret = false; + bool now = vshCommandOptBool(cmd, "now"); + bool pretty = vshCommandOptBool(cmd, "pretty"); + bool sync = vshCommandOptBool(cmd, "sync"); + long long seconds = 0; + unsigned int nseconds = 0; + unsigned int flags = 0; + bool doSet = false; + int rv; + + VSH_EXCLUSIVE_OPTIONS("time", "now"); + VSH_EXCLUSIVE_OPTIONS("time", "sync"); + VSH_EXCLUSIVE_OPTIONS("now", "sync"); + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + rv = vshCommandOptLongLong(cmd, "time", &seconds); + + if (rv < 0) { + /* invalid integer format */ + vshError(ctl, "%s", + _("Unable to parse integer parameter to --time.")); + goto cleanup; + } else if (rv > 0) { + /* valid integer to set */ + doSet = true; + } + + if (doSet || now || sync) { + if (now && ((seconds = time(NULL)) == (time_t) -1)) { + vshError(ctl, _("Unable to get current time")); + goto cleanup; + } + + if (sync) + flags |= VIR_DOMAIN_TIME_SYNC; + + if (virDomainSetTime(dom, seconds, nseconds, flags) < 0) + goto cleanup; + + } else { + if (virDomainGetTime(dom, &seconds, &nseconds, flags) < 0) + goto cleanup; + + if (pretty) { + char timestr[100]; + time_t cur_time = seconds; + struct tm time_info; + + if (!gmtime_r(&cur_time, &time_info)) { + vshError(ctl, _("Unable to format time")); + goto cleanup; + } + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &time_info); + + vshPrint(ctl, _("Time: %s"), timestr); + } else { + vshPrint(ctl, _("Time: %lld"), seconds); + } + } + + ret = true; + cleanup: + virDomainFree(dom); + return ret; +} + /* * "list" command */ @@ -1911,6 +2021,12 @@ const vshCmdDef domMonitoringCmds[] = { .info = info_domstate, .flags = 0 }, + {.name = "domtime", + .handler = cmdDomTime, + .opts = opts_domtime, + .info = info_domtime, + .flags = 0 + }, {.name = "list", .handler = cmdList, .opts = opts_list, diff --git a/tools/virsh.pod b/tools/virsh.pod index 22ca196249..de9a4f7981 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1017,6 +1017,24 @@ Returns state of an interface to VMM used to control a domain. For states other than "ok" or "error" the command also prints number of seconds elapsed since the control interface entered its current state. +=item B I { [I<--now>] [I<--pretty>] [I<--sync>] +[I<--time> B