diff options
author | Richard Jones <rjones@redhat.com> | 2009-04-19 14:33:46 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2009-04-19 14:33:46 +0100 |
commit | 08c333a73893a0fc413e7619c8e64bebaebc741a (patch) | |
tree | add3fe0958ad5d45f0bd898426f672ea42a6dd5b | |
parent | d73a4f097f96e7246718671b0a85cb94f0d3a88f (diff) | |
download | libguestfs-08c333a73893a0fc413e7619c8e64bebaebc741a.tar.gz libguestfs-08c333a73893a0fc413e7619c8e64bebaebc741a.tar.xz libguestfs-08c333a73893a0fc413e7619c8e64bebaebc741a.zip |
Document the internal protocol.
-rw-r--r-- | guestfs.pod | 124 | ||||
-rwxr-xr-x | src/generator.ml | 38 |
2 files changed, 132 insertions, 30 deletions
diff --git a/guestfs.pod b/guestfs.pod index cce7b90d..a4624312 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -491,6 +491,130 @@ C<guestfs_create_main_loop>. This isn't documented. Please see the libguestfs-select and libguestfs-glib implementations. +=head1 INTERNALS + +=head2 COMMUNICATION PROTOCOL + +Don't rely on using this protocol directly. This section documents +how it currently works, but it may change at any time. + +The protocol used to talk between the library and the daemon running +inside the qemu virtual machine is a simple RPC mechanism built on top +of XDR (RFC 1014, RFC 1832, RFC 4506). + +The detailed format of structures is in C<src/guestfs_protocol.x> +(note: this file is automatically generated). + +There are two broad cases, ordinary functions that don't have any +C<FileIn> and C<FileOut> parameters, which are handled with very +simple request/reply messages. Then there are functions that have any +C<FileIn> or C<FileOut> parameters, which use the same request and +reply messages, but they may also be followed by files sent using a +chunked encoding. + +=head3 ORDINARY FUNCTIONS (NO FILEIN/FILEOUT PARAMS) + +For ordinary functions, the request message is: + + total length (header + arguments, + but not including the length word itself) + struct guestfs_message_header + struct guestfs_<foo>_args + +The total length field allows the daemon to allocate a fixed size +buffer into which it slurps the rest of the message. As a result, the +total length is limited to C<GUESTFS_MESSAGE_MAX> bytes (currently +4MB), which means the effective size of any request is limited to +somewhere under this size. + +Note also that many functions don't take any arguments, in which case +the C<guestfs_I<foo>_args> is completely omitted. + +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. + +The reply message for ordinary functions is: + + total length (header + ret, + but not including the length word itself) + struct guestfs_message_header + struct guestfs_<foo>_ret + +As above the C<guestfs_I<foo>_ret> structure may be completely omitted +for functions that return no formal return values. + +As above the total length of the reply is limited to +C<GUESTFS_MESSAGE_MAX>. + +In the case of an error, a flag is set in the header, and the reply +message is slightly changed: + + total length (header + error, + but not including the length word itself) + struct guestfs_message_header + struct guestfs_message_error + +The C<guestfs_message_error> structure contains the error message as a +string. + +=head3 FUNCTIONS THAT HAVE FILEIN PARAMETERS + +A C<FileIn> parameter indicates that we transfer a file I<into> the +guest. The normal request message is sent (see above). However this +is followed by a sequence of file chunks. + + total length (header + arguments, + but not including the length word itself, + and not including the chunks) + struct guestfs_message_header + struct guestfs_<foo>_args + sequence of chunks for FileIn param #0 + sequence of chunks for FileIn param #1 etc. + +The sequence of chunks is a sequence of C<struct guestfs_chunk>. A +flag is set in the final chunk to indicate either successful +completion or early cancellation. + +At time of writing there are no functions that have more than one +FileIn parameter. However this is (theoretically) supported, by +sending the chunks for each FileIn parameter one after another (from +left to right). + +Both the library (sender) I<and> the daemon (receiver) may cancel the +transfer. The library does this by sending a chunk with a special +flag set to indicate cancellation. When the daemon sees this, it +cancels the whole RPC, does I<not> send any reply, and goes back to +reading the next request. + +The daemon may also cancel. It does this by writing a special word +C<GUESTFS_CANCEL_FLAG> to the socket. The library listens for this +during the transfer, and if it gets it, it will cancel the transfer +(it sends a cancel chunk). The special word is chosen so that even if +cancellation happens right at the end of the transfer (after the +library has finished writing and has started listening for the reply), +the "spurious" cancel flag will not be confused with the reply +message. + +This protocol allows the transfer of arbitrary sized files (no 32 bit +limit), and also files where the size is not known in advance +(eg. from pipes or sockets). However the chunks are rather small +(C<GUESTFS_MAX_CHUNK_SIZE>), so that neither the library nor the +daemon need to keep much in memory. + +=head3 FUNCTIONS THAT HAVE FILEOUT PARAMETERS + +The protocol for FileOut parameters is exactly the same as for FileIn +parameters, but with the roles of daemon and library reversed. + + total length (header + ret, + but not including the length word itself, + and not including the chunks) + struct guestfs_message_header + struct guestfs_<foo>_ret + sequence of chunks for FileOut param #0 + sequence of chunks for FileOut param #1 etc. + =head1 ENVIRONMENT VARIABLES =over 4 diff --git a/src/generator.ml b/src/generator.ml index cf5db876..8c75b933 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -1924,9 +1924,17 @@ and generate_xdr () = (* Message header, etc. *) pr "\ +/* The communication protocol is now documented in the guestfs(3) + * manpage. + */ + const GUESTFS_PROGRAM = 0x2000F5F5; const GUESTFS_PROTOCOL_VERSION = 1; +/* These constants must be larger than any possible message length. */ +const GUESTFS_LAUNCH_FLAG = 0xf5f55f5f; +const GUESTFS_CANCEL_FLAG = 0xffffeeee; + enum guestfs_message_direction { GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */ GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */ @@ -1943,19 +1951,6 @@ struct guestfs_message_error { string error_message<GUESTFS_ERROR_LEN>; }; -/* For normal requests and replies (not involving any FileIn or - * FileOut parameters), the protocol is: - * - * For requests: - * total length (header + args, but not including length word itself) - * header - * guestfs_foo_args struct - * For replies: - * total length (as above) - * header - * guestfs_foo_ret struct - */ - struct guestfs_message_header { unsigned prog; /* GUESTFS_PROGRAM */ unsigned vers; /* GUESTFS_PROTOCOL_VERSION */ @@ -1965,23 +1960,6 @@ struct guestfs_message_header { guestfs_message_status status; }; -/* Chunked encoding used to transfer files, for FileIn and FileOut - * parameters. - * - * For requests which have >= 1 FileIn parameter: - * length of header + args (but not length word itself, and not chunks) - * header - * guestfs_foo_args struct - * sequence of chunks for FileIn param #0 - * sequence of chunks for FileIn param #1 etc - * - * For replies which have >= 1 FileOut parameter: - * length of header + ret (but not length word itself, and not chunks) - * header - * guestfs_foo_ret struct - * sequence of chunks for FileOut param #0 - * sequence of chunks for FileOut param #1 etc - */ const GUESTFS_MAX_CHUNK_SIZE = 8192; struct guestfs_chunk { |