From 74fba6e6924cb25404921ca63345388aeaa659c5 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 29 Oct 2015 14:04:57 +0000 Subject: [PATCH] docs: Move architecture and internals documentation to guestfs-internals(1). --- .gitignore | 3 + docs/Makefile.am | 15 ++ docs/guestfs-faq.pod | 4 +- docs/guestfs-hacking.pod | 1 + docs/guestfs-internals.pod | 415 +++++++++++++++++++++++++++++++++++ docs/guestfs-performance.pod | 1 + po-docs/language.mk | 1 + po-docs/podfiles | 1 + src/guestfs.pod | 402 +-------------------------------- 9 files changed, 444 insertions(+), 399 deletions(-) create mode 100644 docs/guestfs-internals.pod diff --git a/.gitignore b/.gitignore index 3338d27bc..a33a2868c 100644 --- a/.gitignore +++ b/.gitignore @@ -132,12 +132,14 @@ Makefile.in /diff/virt-diff.1 /docs/guestfs-faq.1 /docs/guestfs-hacking.1 +/docs/guestfs-internals.1 /docs/guestfs-performance.1 /docs/guestfs-recipes.1 /docs/guestfs-release-notes.1 /docs/guestfs-testing.1 /docs/stamp-guestfs-faq.pod /docs/stamp-guestfs-hacking.pod +/docs/stamp-guestfs-internals.pod /docs/stamp-guestfs-performance.pod /docs/stamp-guestfs-recipes.pod /docs/stamp-guestfs-release-notes.pod @@ -234,6 +236,7 @@ Makefile.in /html/guestfs-examples.3.html /html/guestfs-faq.1.html /html/guestfs-hacking.1.html +/html/guestfs-internals.1.html /html/guestfs-golang.3.html /html/guestfs-java.3.html /html/guestfs-lua.3.html diff --git a/docs/Makefile.am b/docs/Makefile.am index 4e6a0b52b..9ead4c85e 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -20,6 +20,7 @@ include $(top_srcdir)/subdir-rules.mk EXTRA_DIST = \ guestfs-faq.pod \ guestfs-hacking.pod \ + guestfs-internals.pod \ guestfs-performance.pod \ guestfs-recipes.pod \ guestfs-release-notes.pod \ @@ -29,6 +30,7 @@ EXTRA_DIST = \ CLEANFILES = \ stamp-guestfs-faq.pod \ stamp-guestfs-hacking.pod \ + stamp-guestfs-internals.pod \ stamp-guestfs-performance.pod \ stamp-guestfs-recipes.pod \ stamp-guestfs-release-notes.pod \ @@ -37,6 +39,7 @@ CLEANFILES = \ man_MANS = \ guestfs-faq.1 \ guestfs-hacking.1 \ + guestfs-internals.1 \ guestfs-performance.1 \ guestfs-recipes.1 \ guestfs-release-notes.1 \ @@ -44,6 +47,7 @@ man_MANS = \ noinst_DATA = \ $(top_builddir)/html/guestfs-faq.1.html \ $(top_builddir)/html/guestfs-hacking.1.html \ + $(top_builddir)/html/guestfs-internals.1.html \ $(top_builddir)/html/guestfs-performance.1.html \ $(top_builddir)/html/guestfs-recipes.1.html \ $(top_builddir)/html/guestfs-release-notes.1.html \ @@ -71,6 +75,17 @@ stamp-guestfs-hacking.pod: guestfs-hacking.pod $< touch $@ +guestfs-internals.1 $(top_builddir)/html/guestfs-internals.1.html: stamp-guestfs-internals.pod + +stamp-guestfs-internals.pod: guestfs-internals.pod + $(PODWRAPPER) \ + --section 1 \ + --man guestfs-internals.1 \ + --html $(top_builddir)/html/guestfs-internals.1.html \ + --license LGPLv2+ \ + $< + touch $@ + guestfs-performance.1 $(top_builddir)/html/guestfs-performance.1.html: stamp-guestfs-performance.pod stamp-guestfs-performance.pod: guestfs-performance.pod diff --git a/docs/guestfs-faq.pod b/docs/guestfs-faq.pod index 55dfed272..5215e92e4 100644 --- a/docs/guestfs-faq.pod +++ b/docs/guestfs-faq.pod @@ -990,7 +990,7 @@ F program in the libguestfs sources. =head2 Digging deeper into the appliance boot process. Enable debugging and then read this documentation on the appliance -boot process: L. +boot process: L. =head2 libguestfs hangs or fails during run/launch. @@ -1015,6 +1015,8 @@ useful debugging information from libvirtd in F =head1 DESIGN/INTERNALS OF LIBGUESTFS +See also L. + =head2 Why don't you do everything through the FUSE / filesystem interface? diff --git a/docs/guestfs-hacking.pod b/docs/guestfs-hacking.pod index 7935b568d..76b1b8d5b 100644 --- a/docs/guestfs-hacking.pod +++ b/docs/guestfs-hacking.pod @@ -735,6 +735,7 @@ Create the branch in git: L, L, +L, L, L, L, diff --git a/docs/guestfs-internals.pod b/docs/guestfs-internals.pod new file mode 100644 index 000000000..a2cc17f31 --- /dev/null +++ b/docs/guestfs-internals.pod @@ -0,0 +1,415 @@ +=head1 NAME + +guestfs-internals - architecture and internals of libguestfs + +=head1 DESCRIPTION + +This manual page is for hackers who want to understand how libguestfs +works internally. This is just a description of how libguestfs works +now, and it may change at any time in the future. + +=head1 ARCHITECTURE + +Internally, libguestfs is implemented by running an appliance (a +special type of small virtual machine) using L. Qemu runs as +a child process of the main program. + + ┌───────────────────┐ + │ main program │ + │ │ + │ │ child process / appliance + │ │ ┌──────────────────────────┐ + │ │ │ qemu │ + ├───────────────────┤ RPC │ ┌─────────────────┐ │ + │ libguestfs ◀╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍▶ guestfsd │ │ + │ │ │ ├─────────────────┤ │ + └───────────────────┘ │ │ Linux kernel │ │ + │ └────────┬────────┘ │ + └───────────────│──────────┘ + │ + │ virtio-scsi + ┌──────┴──────┐ + │ Device or │ + │ disk image │ + └─────────────┘ + +The library, linked to the main program, creates the child process and +hence the appliance in the L function. + +Inside the appliance is a Linux kernel and a complete stack of +userspace tools (such as LVM and ext2 programs) and a small +controlling daemon called L. The library talks to +L using remote procedure calls (RPC). There is a mostly +one-to-one correspondence between libguestfs API calls and RPC calls +to the daemon. Lastly the disk image(s) are attached to the qemu +process which translates device access by the appliance's Linux kernel +into accesses to the image. + +A common misunderstanding is that the appliance "is" the virtual +machine. Although the disk image you are attached to might also be +used by some virtual machine, libguestfs doesn't know or care about +this. (But you will care if both libguestfs's qemu process and your +virtual machine are trying to update the disk image at the same time, +since these usually results in massive disk corruption). + +=head1 STATE MACHINE + +libguestfs uses a state machine to model the child process: + + | + guestfs_create / guestfs_create_flags + | + | + ____V_____ + / \ + | CONFIG | + \__________/ + ^ ^ \ + | \ \ guestfs_launch + | _\__V______ + | / \ + | | LAUNCHING | + | \___________/ + | / + | guestfs_launch + | / + __|____V + / \ + | READY | + \________/ + +The normal transitions are (1) CONFIG (when the handle is created, but +there is no child process), (2) LAUNCHING (when the child process is +booting up), (3) READY meaning the appliance is up, actions can be +issued to, and carried out by, the child process. + +The guest may be killed by L, or may die +asynchronously at any time (eg. due to some internal error), and that +causes the state to transition back to CONFIG. + +Configuration commands for qemu such as L can only +be issued when in the CONFIG state. + +The API offers one call that goes from CONFIG through LAUNCHING to +READY. L blocks until the child process is READY to +accept commands (or until some failure or timeout). +L internally moves the state from CONFIG to LAUNCHING +while it is running. + +API actions such as L can only be issued when in the +READY state. These API calls block waiting for the command to be +carried out. There are no non-blocking versions, and no way to issue +more than one command per handle at the same time. + +Finally, the child process sends asynchronous messages back to the +main program, such as kernel log messages. You can register a +callback to receive these messages. + +=head1 INTERNALS + +=head2 APPLIANCE BOOT PROCESS + +This process has evolved and continues to evolve. The description +here corresponds only to the current version of libguestfs and is +provided for information only. + +In order to follow the stages involved below, enable libguestfs +debugging (set the environment variable C). + +=over 4 + +=item Create the appliance + +C is invoked to create the kernel, a small initrd +and the appliance. + +The appliance is cached in FUIDE> (or in +another directory if C or C are set). + +For a complete description of how the appliance is created and cached, +read the L man page. + +=item Start qemu and boot the kernel + +qemu is invoked to boot the kernel. + +=item Run the initrd + +C builds a small initrd. The initrd is not the +appliance. The purpose of the initrd is to load enough kernel modules +in order that the appliance itself can be mounted and started. + +The initrd is a cpio archive called +FUIDE/appliance.d/initrd>. + +When the initrd has started you will see messages showing that kernel +modules are being loaded, similar to this: + + supermin: ext2 mini initrd starting up + supermin: mounting /sys + supermin: internal insmod libcrc32c.ko + supermin: internal insmod crc32c-intel.ko + +=item Find and mount the appliance device + +The appliance is a sparse file containing an ext2 filesystem which +contains a familiar (although reduced in size) Linux operating system. +It would normally be called +FUIDE/appliance.d/root>. + +The regular disks being inspected by libguestfs are the first +devices exposed by qemu (eg. as F). + +The last disk added to qemu is the appliance itself (eg. F +if there was only one regular disk). + +Thus the final job of the initrd is to locate the appliance disk, +mount it, and switch root into the appliance, and run F from +the appliance. + +If this works successfully you will see messages such as: + + supermin: picked /sys/block/vdb/dev as root device + supermin: creating /dev/root as block special 252:16 + supermin: mounting new root on /root + supermin: chroot + Starting /init script ... + +Note that C indicates that the appliance's +init script is now running. + +=item Initialize the appliance + +The appliance itself now initializes itself. This involves starting +certain processes like C, possibly printing some debug +information, and finally running the daemon (C). + +=item The daemon + +Finally the daemon (C) runs inside the appliance. If it +runs you should see: + + verbose daemon enabled + +The daemon expects to see a named virtio-serial port exposed by qemu +and connected on the other end to the library. + +The daemon connects to this port (and hence to the library) and sends +a four byte message C, which initiates the +communication protocol (see below). + +=back + +=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 F +(note: this file is automatically generated). + +There are two broad cases, ordinary functions that don't have any +C and C parameters, which are handled with very +simple request/reply messages. Then there are functions that have any +C or C 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 (encoded as XDR) + struct guestfs__args (encoded as XDR) + +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 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_args> is completely omitted. + +The header contains the procedure number (C) which is +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_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, + but not including the length word itself) + struct guestfs_message_header (encoded as XDR) + struct guestfs__ret (encoded as XDR) + +As above the C_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. + +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 (encoded as XDR) + struct guestfs_message_error (encoded as XDR) + +The C structure contains the error message as a +string. + +=head3 FUNCTIONS THAT HAVE FILEIN PARAMETERS + +A C parameter indicates that we transfer a file I 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 (encoded as XDR) + struct guestfs__args (encoded as XDR) + sequence of chunks for FileIn param #0 + sequence of chunks for FileIn param #1 etc. + +The "sequence of chunks" is: + + length of chunk (not including length word itself) + struct guestfs_chunk (encoded as XDR) + length of chunk + struct guestfs_chunk (encoded as XDR) + ... + length of chunk + struct guestfs_chunk (with data.data_len == 0) + +The final chunk has the C field set to zero. Additionally 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 sequence of chunks for each FileIn parameter one after +another (from left to right). + +Both the library (sender) I 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 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 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), 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 (encoded as XDR) + struct guestfs__ret (encoded as XDR) + sequence of chunks for FileOut param #0 + sequence of chunks for FileOut param #1 etc. + +=head3 INITIAL MESSAGE + +When the daemon launches it sends an initial word +(C) which indicates that the guest and daemon is +alive. This is what L waits for. + +=head3 PROGRESS NOTIFICATION MESSAGES + +The daemon may send progress notification messages at any time. These +are distinguished by the normal length word being replaced by +C, followed by a fixed size progress message. + +The library turns them into progress callbacks (see +L) if there is a callback registered, or +discards them if not. + +The daemon self-limits the frequency of progress messages it sends +(see C). Not all calls generate +progress messages. + +=head2 FIXED APPLIANCE + +When libguestfs (or libguestfs tools) are run, they search a path +looking for an appliance. The path is built into libguestfs, or can +be set using the C environment variable. + +Normally a supermin appliance is located on this path (see +L). libguestfs reconstructs this +into a full appliance by running C. + +However, a simpler "fixed appliance" can also be used. libguestfs +detects this by looking for a directory on the path containing all +the following files: + +=over 4 + +=item * F + +=item * F + +=item * F + +=item * F (note that it B be present as well) + +=back + +If the fixed appliance is found, libguestfs skips supermin entirely +and just runs the virtual machine (using qemu or the current backend, +see L) with the kernel, initrd and root disk from the fixed +appliance. + +Thus the fixed appliance can be used when a platform or a Linux +distribution does not support supermin. You build the fixed appliance +on a platform that does support supermin using +L, copy it over, and use that +to run libguestfs. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L. + +=head1 AUTHORS + +Richard W.M. Jones (C) + +=head1 COPYRIGHT + +Copyright (C) 2009-2015 Red Hat Inc. diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod index 27f24b41e..5a7c01b41 100644 --- a/docs/guestfs-performance.pod +++ b/docs/guestfs-performance.pod @@ -570,6 +570,7 @@ L, L, L, L, +L, L, L, L, diff --git a/po-docs/language.mk b/po-docs/language.mk index 8b70c55e3..73fcacded 100644 --- a/po-docs/language.mk +++ b/po-docs/language.mk @@ -33,6 +33,7 @@ MANPAGES = \ guestfs-examples.3 \ guestfs-faq.1 \ guestfs-hacking.1 \ + guestfs-internals.1 \ guestfs-golang.3 \ guestfs-java.3 \ guestfs-lua.3 \ diff --git a/po-docs/podfiles b/po-docs/podfiles index 2f932fe8c..611b549dd 100644 --- a/po-docs/podfiles +++ b/po-docs/podfiles @@ -15,6 +15,7 @@ ../diff/virt-diff.pod ../docs/guestfs-faq.pod ../docs/guestfs-hacking.pod +../docs/guestfs-internals.pod ../docs/guestfs-performance.pod ../docs/guestfs-recipes.pod ../docs/guestfs-release-notes.pod diff --git a/src/guestfs.pod b/src/guestfs.pod index b904ce40c..399396e34 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -41,7 +41,8 @@ For tips and recipes, see L. If you are having performance problems, read L. To help test libguestfs, read L and L. To contribute -code to libguestfs, see L. +code to libguestfs, see L. To find out how +libguestfs works, see L. =head1 API OVERVIEW @@ -3482,402 +3483,6 @@ In the first terminal, stap trace output similar to this is shown: 1318248061071167 (+4233108): launch_end 1318248061280324 (+209157): guestfs_mkfs g=0x1024ab0 fstype=0x46116f device=0x1024e60 -=begin html - - - - -=end html - -=head1 ARCHITECTURE - -Internally, libguestfs is implemented by running an appliance (a -special type of small virtual machine) using L. Qemu runs as -a child process of the main program. - - ┌───────────────────┐ - │ main program │ - │ │ - │ │ child process / appliance - │ │ ┌──────────────────────────┐ - │ │ │ qemu │ - ├───────────────────┤ RPC │ ┌─────────────────┐ │ - │ libguestfs ◀╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍▶ guestfsd │ │ - │ │ │ ├─────────────────┤ │ - └───────────────────┘ │ │ Linux kernel │ │ - │ └────────┬────────┘ │ - └───────────────│──────────┘ - │ - │ virtio-scsi - ┌──────┴──────┐ - │ Device or │ - │ disk image │ - └─────────────┘ - -The library, linked to the main program, creates the child process and -hence the appliance in the L function. - -Inside the appliance is a Linux kernel and a complete stack of -userspace tools (such as LVM and ext2 programs) and a small -controlling daemon called L. The library talks to -L using remote procedure calls (RPC). There is a mostly -one-to-one correspondence between libguestfs API calls and RPC calls -to the daemon. Lastly the disk image(s) are attached to the qemu -process which translates device access by the appliance's Linux kernel -into accesses to the image. - -A common misunderstanding is that the appliance "is" the virtual -machine. Although the disk image you are attached to might also be -used by some virtual machine, libguestfs doesn't know or care about -this. (But you will care if both libguestfs's qemu process and your -virtual machine are trying to update the disk image at the same time, -since these usually results in massive disk corruption). - -=head1 STATE MACHINE - -libguestfs uses a state machine to model the child process: - - | - guestfs_create / guestfs_create_flags - | - | - ____V_____ - / \ - | CONFIG | - \__________/ - ^ ^ \ - | \ \ guestfs_launch - | _\__V______ - | / \ - | | LAUNCHING | - | \___________/ - | / - | guestfs_launch - | / - __|____V - / \ - | READY | - \________/ - -The normal transitions are (1) CONFIG (when the handle is created, but -there is no child process), (2) LAUNCHING (when the child process is -booting up), (3) READY meaning the appliance is up, actions can be -issued to, and carried out by, the child process. - -The guest may be killed by L, or may die -asynchronously at any time (eg. due to some internal error), and that -causes the state to transition back to CONFIG. - -Configuration commands for qemu such as L can only -be issued when in the CONFIG state. - -The API offers one call that goes from CONFIG through LAUNCHING to -READY. L blocks until the child process is READY to -accept commands (or until some failure or timeout). -L internally moves the state from CONFIG to LAUNCHING -while it is running. - -API actions such as L can only be issued when in the -READY state. These API calls block waiting for the command to be -carried out. There are no non-blocking versions, and no way to issue -more than one command per handle at the same time. - -Finally, the child process sends asynchronous messages back to the -main program, such as kernel log messages. You can register a -callback to receive these messages. - -=head1 INTERNALS - -=head2 APPLIANCE BOOT PROCESS - -This process has evolved and continues to evolve. The description -here corresponds only to the current version of libguestfs and is -provided for information only. - -In order to follow the stages involved below, enable libguestfs -debugging (set the environment variable C). - -=over 4 - -=item Create the appliance - -C is invoked to create the kernel, a small initrd -and the appliance. - -The appliance is cached in FUIDE> (or in -another directory if C or C are set). - -For a complete description of how the appliance is created and cached, -read the L man page. - -=item Start qemu and boot the kernel - -qemu is invoked to boot the kernel. - -=item Run the initrd - -C builds a small initrd. The initrd is not the -appliance. The purpose of the initrd is to load enough kernel modules -in order that the appliance itself can be mounted and started. - -The initrd is a cpio archive called -FUIDE/appliance.d/initrd>. - -When the initrd has started you will see messages showing that kernel -modules are being loaded, similar to this: - - supermin: ext2 mini initrd starting up - supermin: mounting /sys - supermin: internal insmod libcrc32c.ko - supermin: internal insmod crc32c-intel.ko - -=item Find and mount the appliance device - -The appliance is a sparse file containing an ext2 filesystem which -contains a familiar (although reduced in size) Linux operating system. -It would normally be called -FUIDE/appliance.d/root>. - -The regular disks being inspected by libguestfs are the first -devices exposed by qemu (eg. as F). - -The last disk added to qemu is the appliance itself (eg. F -if there was only one regular disk). - -Thus the final job of the initrd is to locate the appliance disk, -mount it, and switch root into the appliance, and run F from -the appliance. - -If this works successfully you will see messages such as: - - supermin: picked /sys/block/vdb/dev as root device - supermin: creating /dev/root as block special 252:16 - supermin: mounting new root on /root - supermin: chroot - Starting /init script ... - -Note that C indicates that the appliance's -init script is now running. - -=item Initialize the appliance - -The appliance itself now initializes itself. This involves starting -certain processes like C, possibly printing some debug -information, and finally running the daemon (C). - -=item The daemon - -Finally the daemon (C) runs inside the appliance. If it -runs you should see: - - verbose daemon enabled - -The daemon expects to see a named virtio-serial port exposed by qemu -and connected on the other end to the library. - -The daemon connects to this port (and hence to the library) and sends -a four byte message C, which initiates the -communication protocol (see below). - -=back - -=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 F -(note: this file is automatically generated). - -There are two broad cases, ordinary functions that don't have any -C and C parameters, which are handled with very -simple request/reply messages. Then there are functions that have any -C or C 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 (encoded as XDR) - struct guestfs__args (encoded as XDR) - -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 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_args> is completely omitted. - -The header contains the procedure number (C) which is -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_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, - but not including the length word itself) - struct guestfs_message_header (encoded as XDR) - struct guestfs__ret (encoded as XDR) - -As above the C_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. - -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 (encoded as XDR) - struct guestfs_message_error (encoded as XDR) - -The C structure contains the error message as a -string. - -=head3 FUNCTIONS THAT HAVE FILEIN PARAMETERS - -A C parameter indicates that we transfer a file I 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 (encoded as XDR) - struct guestfs__args (encoded as XDR) - sequence of chunks for FileIn param #0 - sequence of chunks for FileIn param #1 etc. - -The "sequence of chunks" is: - - length of chunk (not including length word itself) - struct guestfs_chunk (encoded as XDR) - length of chunk - struct guestfs_chunk (encoded as XDR) - ... - length of chunk - struct guestfs_chunk (with data.data_len == 0) - -The final chunk has the C field set to zero. Additionally 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 sequence of chunks for each FileIn parameter one after -another (from left to right). - -Both the library (sender) I 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 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 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), 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 (encoded as XDR) - struct guestfs__ret (encoded as XDR) - sequence of chunks for FileOut param #0 - sequence of chunks for FileOut param #1 etc. - -=head3 INITIAL MESSAGE - -When the daemon launches it sends an initial word -(C) which indicates that the guest and daemon is -alive. This is what L waits for. - -=head3 PROGRESS NOTIFICATION MESSAGES - -The daemon may send progress notification messages at any time. These -are distinguished by the normal length word being replaced by -C, followed by a fixed size progress message. - -The library turns them into progress callbacks (see -L) if there is a callback registered, or -discards them if not. - -The daemon self-limits the frequency of progress messages it sends -(see C). Not all calls generate -progress messages. - -=head2 FIXED APPLIANCE - -When libguestfs (or libguestfs tools) are run, they search a path -looking for an appliance. The path is built into libguestfs, or can -be set using the C environment variable. - -Normally a supermin appliance is located on this path (see -L). libguestfs reconstructs this -into a full appliance by running C. - -However, a simpler "fixed appliance" can also be used. libguestfs -detects this by looking for a directory on the path containing all -the following files: - -=over 4 - -=item * F - -=item * F - -=item * F - -=item * F (note that it B be present as well) - -=back - -If the fixed appliance is found, libguestfs skips supermin entirely -and just runs the virtual machine (using qemu or the current backend, -see L) with the kernel, initrd and root disk from the fixed -appliance. - -Thus the fixed appliance can be used when a platform or a Linux -distribution does not support supermin. You build the fixed appliance -on a platform that does support supermin using -L, copy it over, and use that -to run libguestfs. - =head1 LIBGUESTFS VERSION NUMBERS Since April 2010, libguestfs has started to make separate development @@ -3946,7 +3551,7 @@ time. =head2 PROTOCOL LIMITS Internally libguestfs uses a message-based protocol to pass API calls -and their responses to and from a small "appliance" (see L +and their responses to and from a small "appliance" (see L for plenty more detail about this). The maximum message size used by the protocol is slightly less than 4 MB. For some API calls you may need to be aware of this limit. The API calls which may be affected @@ -4207,6 +3812,7 @@ L, L, L, L, +L, L, L, L,