=head2 RUNNING COMMANDS
-Although libguestfs is a primarily an API for manipulating files
+Although libguestfs is primarily an API for manipulating files
inside guest images, we also provide some limited facilities for
running commands inside guests.
Configuration commands for qemu such as L</guestfs_add_drive> can only
be issued when in the CONFIG state.
-The high-level API offers two calls that go from CONFIG through
-LAUNCHING to READY. L</guestfs_launch> blocks until the child process
-is READY to accept commands (or until some failure or timeout).
+The API offers one call that goes from CONFIG through LAUNCHING to
+READY. L</guestfs_launch> blocks until the child process is READY to
+accept commands (or until some failure or timeout).
L</guestfs_launch> internally moves the state from CONFIG to LAUNCHING
while it is running.
-High-level API actions such as L</guestfs_mount> can only be issued
-when in the READY state. These high-level API calls block waiting for
-the command to be carried out (ie. the state to transition to BUSY and
-then back to READY). But using the low-level event API, you get
-non-blocking versions. (But you can still only carry out one
-operation per handle at a time - that is a limitation of the
-communications protocol we use).
+API actions such as L</guestfs_mount> can only be issued when in the
+READY state. These API calls block waiting for the command to be
+carried out (ie. the state to transition to BUSY and then back to
+READY). 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. Mostly these are ignored
-by the high-level API, but using the low-level event API you can
-register to receive these messages.
+main program, such as kernel log messages. You can register a
+callback to receive these messages.
=head2 SETTING CALLBACKS TO HANDLE EVENTS
=head3 INITIAL MESSAGE
-Because the underlying channel (QEmu -net channel) doesn't have any
-sort of connection control, when the daemon launches it sends an
-initial word (C<GUESTFS_LAUNCH_FLAG>) which indicates that the guest
-and daemon is alive. This is what L</guestfs_launch> waits for.
+When the daemon launches it sends an initial word
+(C<GUESTFS_LAUNCH_FLAG>) which indicates that the guest and daemon is
+alive. This is what L</guestfs_launch> 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<GUESTFS_PROGRESS_FLAG>, followed by a fixed size progress message.
+
+The library turns them into progress callbacks (see
+C<guestfs_set_progress_callback>) if there is a callback registered,
+or discards them if not.
+
+The daemon self-limits the frequency of progress messages it sends
+(see C<daemon/proto.c:notify_progress>). Not all calls generate
+progress messages.
=head1 MULTIPLE HANDLES AND MULTIPLE THREADS
exclusively from one thread, or provide your own mutex so that two
threads cannot issue calls on the same handle at the same time.
+See the graphical program guestfs-browser for one possible
+architecture for multithreaded programs using libvirt and libguestfs.
+
=head1 QEMU WRAPPERS
If you want to compile your own qemu, run qemu from a non-standard