[libvirt] [PATCHv3 2/3] virsh: Expose virDomain{Get,Set}Time

Michal Privoznik mprivozn at redhat.com
Thu Apr 3 07:49:23 UTC 2014


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 at redhat.com>
---
 tools/virsh-domain-monitor.c | 132 +++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod              |  16 ++++++
 2 files changed, 148 insertions(+)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 18d551a..31fa8de 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -1356,6 +1356,132 @@ cmdDomstate(vshControl *ctl, const vshCmd *cmd)
 }
 
 /*
+ * "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");
+    long long seconds = 0;
+    unsigned int nseconds = 0;
+    unsigned int flags = 0;
+    bool doSet = false;
+    int rv;
+
+    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) {
+        /* --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 && ((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
  */
 static const vshCmdInfo info_list[] = {
@@ -1911,6 +2037,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 98d891a..d2de8a6 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -994,6 +994,22 @@ 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<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<domxml-from-native> I<format> I<config>
 
 Convert the file I<config> in the native guest configuration format
-- 
1.9.0




More information about the libvir-list mailing list