guestfs: Update architecture section of documentation.
[libguestfs.git] / guestfs.pod
index 4a47733..eb043f0 100644 (file)
@@ -274,6 +274,41 @@ non-portable between kernel versions, and they don't support labels or
 UUIDs.  If you want to pre-build an image or you need to mount it
 using a label or UUID, use an ISO image instead.
 
+=head2 COPYING
+
+There are various different commands for copying between files and
+devices and in and out of the guest filesystem.  These are summarised
+in the table below.
+
+=over 4
+
+=item B<file> to B<file>
+
+Use L</guestfs_cp> to copy a single file, or
+L</guestfs_cp_a> to copy directories recursively.
+
+=item B<file or device> to B<file or device>
+
+Use L</guestfs_dd> which efficiently uses L<dd(1)>
+to copy between files and devices in the guest.
+
+Example: duplicate the contents of an LV:
+
+ guestfs_dd (g, "/dev/VG/Original", "/dev/VG/Copy");
+
+The destination (C</dev/VG/Copy>) must be at least as large as the
+source (C</dev/VG/Original>).
+
+=item B<file on the host> to B<file or device>
+
+Use L</guestfs_upload>.  See L</UPLOADING> above.
+
+=item B<file or device> to B<file on the host>
+
+Use L</guestfs_download>.  See L</DOWNLOADING> above.
+
+=back
+
 =head2 LISTING FILES
 
 C<guestfs_ll> is just designed for humans to read (mainly when using
@@ -625,37 +660,137 @@ developer to program in confidence against libguestfs.
 
 =head1 AVAILABILITY
 
+=head2 GROUPS OF FUNCTIONALITY IN THE APPLIANCE
+
 Using L</guestfs_available> you can test availability of
-the following groups of functions:
+the following groups of functions.  This test queries the
+appliance to see if the appliance you are currently using
+supports the functionality.
 
 @AVAILABILITY@
 
-=head1 STATE MACHINE AND LOW-LEVEL EVENT API
-
-Internally, libguestfs is implemented by running a virtual machine
-using L<qemu(1)>.  QEmu runs as a child process of the main program,
-and most of this discussion won't make sense unless you understand
-that the complexity is dealing with the (asynchronous) actions of the
-child process.
-
-                            child process
-  ___________________       _________________________
- /                   \     /                         \
- | main program      |     | qemu +-----------------+|
- |                   |     |      | Linux kernel    ||
- +-------------------+     |      +-----------------+|
- | libguestfs     <-------------->| guestfsd        ||
- |                   |     |      +-----------------+|
- \___________________/     \_________________________/
-
-The diagram above shows libguestfs communicating with the guestfsd
-daemon running inside the qemu child process.  There are several
-points of failure here: qemu can fail to start, the virtual machine
-inside qemu can fail to boot, guestfsd can fail to start or not
-establish communication, any component can start successfully but fail
-asynchronously later, and so on.
-
-=head2 STATE MACHINE
+=head2 SINGLE CALLS AT COMPILE TIME
+
+If you need to test whether a single libguestfs function is
+available at compile time, we recommend using build tools
+such as autoconf or cmake.  For example in autotools you could
+use:
+
+ AC_CHECK_LIB([guestfs],[guestfs_create])
+ AC_CHECK_FUNCS([guestfs_dd])
+
+which would result in C<HAVE_GUESTFS_DD> being either defined
+or not defined in your program.
+
+=head2 SINGLE CALLS AT RUN TIME
+
+Testing at compile time doesn't guarantee that a function really
+exists in the library.  The reason is that you might be dynamically
+linked against a previous I<libguestfs.so> (dynamic library)
+which doesn't have the call.  This situation unfortunately results
+in a segmentation fault, which is a shortcoming of the C dynamic
+linking system itself.
+
+You can use L<dlopen(3)> to test if a function is available
+at run time, as in this example program (note that you still
+need the compile time check as well):
+
+ #include <config.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <dlfcn.h>
+ #include <guestfs.h>
+ main ()
+ {
+ #ifdef HAVE_GUESTFS_DD
+   void *dl;
+   int has_function;
+
+   /* Test if the function guestfs_dd is really available. */
+   dl = dlopen (NULL, RTLD_LAZY);
+   if (!dl) {
+     fprintf (stderr, "dlopen: %s\n", dlerror ());
+     exit (1);
+   }
+   has_function = dlsym (dl, "guestfs_dd") != NULL;
+   dlclose (dl);
+   if (!has_function)
+     printf ("this libguestfs.so does NOT have guestfs_dd function\n");
+   else {
+     printf ("this libguestfs.so has guestfs_dd function\n");
+     /* Now it's safe to call
+     guestfs_dd (g, "foo", "bar");
+     */
+   }
+ #else
+   printf ("guestfs_dd function was not found at compile time\n");
+ #endif
+  }
+
+You may think the above is an awful lot of hassle, and it is.
+There are other ways outside of the C linking system to ensure
+that this kind of incompatibility never arises, such as using
+package versioning:
+
+ Requires: libguestfs >= 1.0.80
+
+=begin html
+
+<!-- old anchor for the next section -->
+<a name="state_machine_and_low_level_event_api"/>
+
+=end html
+
+=head1 ARCHITECTURE
+
+Internally, libguestfs is implemented by running an appliance (a
+special type of small virtual machine) using L<qemu(1)>.  Qemu runs as
+a child process of the main program.
+
+  ___________________
+ /                   \
+ | main program      |
+ |                   |
+ |                   |           child process / appliance
+ |                   |           __________________________
+ |                   |          / qemu                     \
+ +-------------------+   RPC    |      +-----------------+ |
+ | libguestfs     <--------------------> guestfsd        | |
+ |                   |          |      +-----------------+ |
+ \___________________/          |      | Linux kernel    | |
+                                |      +--^--------------+ |
+                                \_________|________________/
+                                          |
+                                   _______v______
+                                  /              \
+                                  | Device or    |
+                                  | disk image   |
+                                  \______________/
+
+The library, linked to the main program, creates the child process and
+hence the appliance in the L</guestfs_launch> 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 C<guestfsd>.  The library talks to
+C<guestfsd> 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: