protocol: Upload progress messages and optional arguments.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 1 Dec 2010 10:30:44 +0000 (10:30 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 1 Dec 2010 13:34:28 +0000 (13:34 +0000)
Two unrelated changes to the protocol to support progress
messages during uploads, and optional arguments.

Note that this makes an incompatible change to the protocol,
and this is reflected in the protocol version field (3 -> 4).

daemon/daemon.h
daemon/proto.c
generator/generator_xdr.ml
src/guestfs.pod
src/proto.c

index 6e9788a..1e58910 100644 (file)
@@ -103,6 +103,8 @@ extern const char *function_names[];
 /*-- in proto.c --*/
 extern int proc_nr;
 extern int serial;
 /*-- in proto.c --*/
 extern int proc_nr;
 extern int serial;
+extern uint64_t progress_hint;
+extern uint64_t optargs_bitmask;
 
 /*-- in mount.c --*/
 extern int root_mounted;
 
 /*-- in mount.c --*/
 extern int root_mounted;
index 63d1cc9..f3a3b26 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <inttypes.h>
 #include <unistd.h>
 #include <errno.h>
 #include <sys/param.h>         /* defines MIN */
 #include <unistd.h>
 #include <errno.h>
 #include <sys/param.h>         /* defines MIN */
 int proc_nr;
 int serial;
 
 int proc_nr;
 int serial;
 
+/* Hint for implementing progress messages for uploaded/incoming data.
+ * The caller sets this to a value > 0 if it knows or can estimate how
+ * much data will be sent (this is not always known, eg. for uploads
+ * coming from a pipe).  If this is known then we can emit progress
+ * messages as we write the data.
+ */
+uint64_t progress_hint;
+
+/* Optional arguments bitmask.  Caller sets this to indicate which
+ * optional arguments in the guestfs_<foo>_args structure are
+ * meaningful.  Optional arguments not covered by the bitmask are set
+ * to arbitrary values and the daemon should ignore them.  If the
+ * bitmask has bits set that the daemon doesn't understand, then the
+ * whole call is rejected early in processing.
+ */
+uint64_t optargs_bitmask;
+
 /* Time at which we received the current request. */
 static struct timeval start_t;
 
 /* Time at which we received the current request. */
 static struct timeval start_t;
 
@@ -149,9 +167,19 @@ main_loop (int _sock)
       reply_with_error ("unexpected message status (%d)", hdr.status);
       goto cont;
     }
       reply_with_error ("unexpected message status (%d)", hdr.status);
       goto cont;
     }
+    /* This version of the daemon does not understand optional arguments
+     * at all.  When we fix this, we will remove the next conditional.
+     */
+    if (hdr.optargs_bitmask != 0) {
+      reply_with_error ("optargs_bitmask != 0 (%" PRIu64 ")",
+                        hdr.optargs_bitmask);
+      goto cont;
+    }
 
     proc_nr = hdr.proc;
     serial = hdr.serial;
 
     proc_nr = hdr.proc;
     serial = hdr.serial;
+    progress_hint = hdr.progress_hint;
+    optargs_bitmask = hdr.optargs_bitmask;
 
     /* Clear errors before we call the stub functions.  This is just
      * to ensure that we can accurately report errors in cases where
 
     /* Clear errors before we call the stub functions.  This is just
      * to ensure that we can accurately report errors in cases where
index c6d8a4d..ca114c5 100644 (file)
@@ -158,7 +158,7 @@ let generate_xdr () =
  */
 
 const GUESTFS_PROGRAM = 0x2000F5F5;
  */
 
 const GUESTFS_PROGRAM = 0x2000F5F5;
-const GUESTFS_PROTOCOL_VERSION = 3;
+const GUESTFS_PROTOCOL_VERSION = 4;
 
 /* These constants must be larger than any possible message length. */
 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
 
 /* These constants must be larger than any possible message length. */
 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
@@ -193,6 +193,8 @@ struct guestfs_message_header {
   guestfs_procedure proc;            /* GUESTFS_PROC_x */
   guestfs_message_direction direction;
   unsigned serial;                   /* message serial number */
   guestfs_procedure proc;            /* GUESTFS_PROC_x */
   guestfs_message_direction direction;
   unsigned serial;                   /* message serial number */
+  unsigned hyper progress_hint;      /* upload hint for progress bar */
+  unsigned hyper optargs_bitmask;    /* bitmask for optional args */
   guestfs_message_status status;
 };
 
   guestfs_message_status status;
 };
 
index 677d944..7cb05a6 100644 (file)
@@ -1855,6 +1855,14 @@ The header contains the procedure number (C<guestfs_proc>) which is
 how the receiver knows what type of args structure to expect, or none
 at all.
 
 how the receiver knows what type of args structure to expect, or none
 at all.
 
+For functions that take optional arguments, the optional arguments are
+encoded in the C<guestfs_I<foo>_args> structure in the same way as
+ordinary arguments.  A bitmask in the header indicates which optional
+arguments are meaningful.  The bitmask is also checked to see if it
+contains bits set which the daemon does not know about (eg. if more
+optional arguments were added in a later version of the library), and
+this causes the call to be rejected.
+
 The reply message for ordinary functions is:
 
  total length (header + ret,
 The reply message for ordinary functions is:
 
  total length (header + ret,
index 5d924e8..5c22e3d 100644 (file)
@@ -658,6 +658,8 @@ guestfs___send (guestfs_h *g, int proc_nr, xdrproc_t xdrp, char *args)
   hdr.direction = GUESTFS_DIRECTION_CALL;
   hdr.serial = serial;
   hdr.status = GUESTFS_STATUS_OK;
   hdr.direction = GUESTFS_DIRECTION_CALL;
   hdr.serial = serial;
   hdr.status = GUESTFS_STATUS_OK;
+  hdr.progress_hint = 0;
+  hdr.optargs_bitmask = 0;
 
   if (!xdr_guestfs_message_header (&xdr, &hdr)) {
     error (g, _("xdr_guestfs_message_header failed"));
 
   if (!xdr_guestfs_message_header (&xdr, &hdr)) {
     error (g, _("xdr_guestfs_message_header failed"));