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 <mprivozn@xxxxxxxxxx> --- tools/virsh-domain-monitor.c | 126 +++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 16 ++++++ 2 files changed, 142 insertions(+) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index de4afbb..8e21e37 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1391,6 +1391,126 @@ cleanup: } /* + * "domtime" command + */ +static const vshCmdInfo info_domtime[] = { + {.name = "help", + .data = N_("domain time") + }, + {.name = "desc", + .data = N_("Gets or sets a domain 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 current host time") + }, + {.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"); + bool doSet = false; + long long guest_time; + const char *timezone = NULL; + int rv; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + rv = vshCommandOptLongLong(cmd, "time", &guest_time); + + if (rv < 0) { + /* invalid integer format */ + goto cleanup; + } else if (rv > 0) { + /* --time is used, so set time instead of get time. + * However, --time and --now are mutually exclusive. */ + if (now) { + vshError(ctl, _("--time and --now are mutually exclusive")); + goto cleanup; + } + + /* Neither is --time and --sync */ + if (sync) { + vshError(ctl, _("--time and --sync are mutually exclusive")); + goto cleanup; + + } + doSet = true; + } + + if (sync && now) { + vshError(ctl, _("--sync and --now are mutually exclusive")); + goto cleanup; + } + + /* --now or --sync means setting */ + doSet |= now | sync; + + if (doSet) { + if (now && ((guest_time = time(NULL)) == (time_t) -1)) { + vshError(ctl, _("unable to get current time")); + goto cleanup; + } + if (virDomainSetTime(dom, guest_time, timezone, + sync ? VIR_DOMAIN_TIME_SYNC : 0) < 0) + goto cleanup; + } else { + if (virDomainGetTime(dom, &guest_time, 0) < 0) + goto cleanup; + + if (pretty) { + char timestr[100]; + time_t cur_time = guest_time; + 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: %llu"), guest_time); + } + } + + ret = true; + +cleanup: + virDomainFree(dom); + return ret; +} + +/* * "list" command */ static const vshCmdInfo info_list[] = { @@ -1946,6 +2066,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 f221475..40cb5b5 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -969,6 +969,22 @@ Convert a domain Id (or UUID) to domain name Returns state about a domain. I<--reason> tells virsh to also print reason for the state. +=item B<domtime> I<domain> { [I<--now>] [I<--pretty>] [I<--sync>] +[I<--time> B<time>] } + +Gets or sets the domain's system time. When run without any arguments +(but I<domain>), the current domain's system time is printed out. The +I<--pretty> modifier can be used to print the time in more human +readable form. When I<--time> B<time> is specified, the domain's time is +not get but set instead. The I<--now> modifier acts like if it was an +alias for I<--time> B<$now>, which means it sets the time that is +currently on the host virsh is running at. In both cases (setting and +getting), time is in seconds relative to Epoch of 1970-01-01 in UTC. +The I<--sync> modifies the set behavior a bit: The time passed is +ignored, but the time to set is read from domain's RTC instead. Please +note, that some hypervisors may require a guest agent to be configured +in order to get or set the guest time. + =item B<domcontrol> I<domain> Returns state of an interface to VMM used to control a domain. For -- 1.8.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list