summary refs log tree commit diff stats
path: root/qga/commands-posix.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-25 12:30:01 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-25 12:30:01 +0000
commit0459650d94d18218808fcabc8c3227d2ee99af39 (patch)
tree89b1f02e7e4784c444faf91506ca7fcfd8bb7e7b /qga/commands-posix.c
parent05fd3bf2a1c9fc26414d3cf608732c40d0d9eb23 (diff)
parenta749f42da5129bbfadea6926964d9a213ed4bc5f (diff)
downloadfocaccia-qemu-0459650d94d18218808fcabc8c3227d2ee99af39.tar.gz
focaccia-qemu-0459650d94d18218808fcabc8c3227d2ee99af39.zip
Merge remote-tracking branch 'remotes/mdroth/qga-pull-2014-02-24' into staging
* remotes/mdroth/qga-pull-2014-02-24:
  qemu-ga: isa-serial support on Windows
  qga: Fix memory allocation pasto
  qga: Don't require 'time' argument in guest-set-time command
  qga: vss-win32: Fix interference with snapshot deletion by other VSS request
  qga: vss-win32: Fix interference with snapshot creation by other VSS requesters
  qga: vss-win32: Use NULL as an invalid pointer for OpenEvent and CreateEvent

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'qga/commands-posix.c')
-rw-r--r--qga/commands-posix.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index cae41716ca..6b5f11f83f 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -142,7 +142,7 @@ int64_t qmp_guest_get_time(Error **errp)
    return time_ns;
 }
 
-void qmp_guest_set_time(int64_t time_ns, Error **errp)
+void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
 {
     int ret;
     int status;
@@ -150,22 +150,28 @@ void qmp_guest_set_time(int64_t time_ns, Error **errp)
     Error *local_err = NULL;
     struct timeval tv;
 
-    /* year-2038 will overflow in case time_t is 32bit */
-    if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) {
-        error_setg(errp, "Time %" PRId64 " is too large", time_ns);
-        return;
-    }
+    /* If user has passed a time, validate and set it. */
+    if (has_time) {
+        /* year-2038 will overflow in case time_t is 32bit */
+        if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) {
+            error_setg(errp, "Time %" PRId64 " is too large", time_ns);
+            return;
+        }
 
-    tv.tv_sec = time_ns / 1000000000;
-    tv.tv_usec = (time_ns % 1000000000) / 1000;
+        tv.tv_sec = time_ns / 1000000000;
+        tv.tv_usec = (time_ns % 1000000000) / 1000;
 
-    ret = settimeofday(&tv, NULL);
-    if (ret < 0) {
-        error_setg_errno(errp, errno, "Failed to set time to guest");
-        return;
+        ret = settimeofday(&tv, NULL);
+        if (ret < 0) {
+            error_setg_errno(errp, errno, "Failed to set time to guest");
+            return;
+        }
     }
 
-    /* Set the Hardware Clock to the current System Time. */
+    /* Now, if user has passed a time to set and the system time is set, we
+     * just need to synchronize the hardware clock. However, if no time was
+     * passed, user is requesting the opposite: set the system time from the
+     * hardware clock. */
     pid = fork();
     if (pid == 0) {
         setsid();
@@ -173,7 +179,10 @@ void qmp_guest_set_time(int64_t time_ns, Error **errp)
         reopen_fd_to_null(1);
         reopen_fd_to_null(2);
 
-        execle("/sbin/hwclock", "hwclock", "-w", NULL, environ);
+        /* Use '/sbin/hwclock -w' to set RTC from the system time,
+         * or '/sbin/hwclock -s' to set the system time from RTC. */
+        execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
+               NULL, environ);
         _exit(EXIT_FAILURE);
     } else if (pid < 0) {
         error_setg_errno(errp, errno, "failed to create child process");
@@ -525,7 +534,7 @@ struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
     if (ret == -1) {
         error_setg_errno(err, errno, "failed to seek file");
     } else {
-        seek_data = g_malloc0(sizeof(GuestFileRead));
+        seek_data = g_new0(GuestFileSeek, 1);
         seek_data->position = ftell(fh);
         seek_data->eof = feof(fh);
     }