protocol: Handle progress notification messages during FileIn.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 1 Dec 2010 13:31:25 +0000 (13:31 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 1 Dec 2010 13:35:32 +0000 (13:35 +0000)
If the daemon sends progress notification messages while we
are uploading FileIn parameters, these are received in
check_for_daemon_cancellation_or_eof.  Modify this library
function so that it turns these messages into callbacks.

daemon/proto.c
src/proto.c

index f3a3b26..1fdb26c 100644 (file)
@@ -425,6 +425,7 @@ receive_file (receive_cb cb, void *opaque)
       return 0;                        /* end of file */
     }
 
       return 0;                        /* end of file */
     }
 
+    /* Note that the callback can generate progress messages. */
     if (cb)
       r = cb (opaque, chunk.data.data_val, chunk.data.data_len);
     else
     if (cb)
       r = cb (opaque, chunk.data.data_val, chunk.data.data_len);
     else
index dd81f48..a5d9d2b 100644 (file)
@@ -70,6 +70,9 @@
 #include "guestfs-internal-actions.h"
 #include "guestfs_protocol.h"
 
 #include "guestfs-internal-actions.h"
 #include "guestfs_protocol.h"
 
+/* Size of guestfs_progress message on the wire. */
+#define PROGRESS_MESSAGE_SIZE 24
+
 /* This is the code used to send and receive RPC messages and (for
  * certain types of message) to perform file transfers.  This code is
  * driven from the generated actions (src/actions.c).  There
 /* This is the code used to send and receive RPC messages and (for
  * certain types of message) to perform file transfers.  This code is
  * driven from the generated actions (src/actions.c).  There
@@ -316,6 +319,33 @@ check_for_daemon_cancellation_or_eof (guestfs_h *g, int fd)
   xdr_uint32_t (&xdr, &flag);
   xdr_destroy (&xdr);
 
   xdr_uint32_t (&xdr, &flag);
   xdr_destroy (&xdr);
 
+  /* Read and process progress messages that happen during FileIn. */
+  if (flag == GUESTFS_PROGRESS_FLAG) {
+    char buf[PROGRESS_MESSAGE_SIZE];
+
+    n = really_read_from_socket (g, fd, buf, PROGRESS_MESSAGE_SIZE);
+    if (n == -1)
+      return -1;
+    if (n == 0) {
+      child_cleanup (g);
+      return -1;
+    }
+
+    if (g->state == BUSY && g->progress_cb) {
+      guestfs_progress message;
+
+      xdrmem_create (&xdr, buf, PROGRESS_MESSAGE_SIZE, XDR_DECODE);
+      xdr_guestfs_progress (&xdr, &message);
+      xdr_destroy (&xdr);
+
+      g->progress_cb (g, g->progress_cb_data,
+                      message.proc, message.serial,
+                      message.position, message.total);
+    }
+
+    return 0;
+  }
+
   if (flag != GUESTFS_CANCEL_FLAG) {
     error (g, _("check_for_daemon_cancellation_or_eof: read 0x%x from daemon, expected 0x%x\n"),
            flag, GUESTFS_CANCEL_FLAG);
   if (flag != GUESTFS_CANCEL_FLAG) {
     error (g, _("check_for_daemon_cancellation_or_eof: read 0x%x from daemon, expected 0x%x\n"),
            flag, GUESTFS_CANCEL_FLAG);
@@ -418,9 +448,6 @@ guestfs___send_to_daemon (guestfs_h *g, const void *v_buf, size_t n)
  * will not see GUESTFS_PROGRESS_FLAG.
  */
 
  * will not see GUESTFS_PROGRESS_FLAG.
  */
 
-/* Size of guestfs_progress message on the wire. */
-#define PROGRESS_MESSAGE_SIZE 24
-
 int
 guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn)
 {
 int
 guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn)
 {