X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=guestfs.pod;h=cce7b90db7bc964686339626f35869e20e8db01f;hp=63bd14c43a0d74a6ac85e7e1a9db8de37bfe8500;hb=7bf3e1a43512293b1a3f78f880b57e7bbd372eae;hpb=5de49dc0d82a86032eb51e2cb9e43813e2480594 diff --git a/guestfs.pod b/guestfs.pod index 63bd14c..cce7b90 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -6,12 +6,14 @@ guestfs - Library for accessing and modifying virtual machine images =head1 SYNOPSIS - guestfs_h handle = guestfs_create (); + #include + + guestfs_h *handle = guestfs_create (); guestfs_add_drive (handle, "guest.img"); guestfs_launch (handle); guestfs_wait_ready (handle); guestfs_mount (handle, "/dev/sda1", "/"); - guestfs_touch_file (handle, "/hello"); + guestfs_touch (handle, "/hello"); guestfs_sync (handle); guestfs_close (handle); @@ -32,44 +34,182 @@ schemes, qcow, qcow2, vmdk. Libguestfs provides ways to enumerate guest storage (eg. partitions, LVs, what filesystem is in each LV, etc.). It can also run commands -in the context of the guest. Also you can mount guest filesystems on -the host (requires root privs and NFS). +in the context of the guest. Also you can access filesystems over FTP. Libguestfs is a library that can be linked with C and C++ management -programs (or management programs written in other languages, if people -contribute the language bindings). You can also use it from shell -scripts or the command line. +programs (or management programs written in OCaml, Perl or Python). +You can also use it from shell scripts or the command line. -=head1 CONNECTION MANAGEMENT +You don't need to be root to use libguestfs, although obviously you do +need enough permissions to access the disk images. +=head1 CONNECTION MANAGEMENT +If you are using the high-level API, then you should call the +functions in the following order: + guestfs_h *handle = guestfs_create (); + + guestfs_add_drive (handle, "guest.img"); + /* call guestfs_add_drive additional times if the guest has + * multiple disks + */ + + guestfs_launch (handle); + guestfs_wait_ready (handle); + /* now you can examine what partitions, LVs etc are available + * you have to mount / at least + */ + guestfs_mount (handle, "/dev/sda1", "/"); + /* now you can perform actions on the guest disk image */ + guestfs_touch (handle, "/hello"); + + /* you only need to call guestfs_sync if you have made + * changes to the guest image + */ + guestfs_sync (handle); + + guestfs_close (handle); -=head1 CONFIGURATION MANAGEMENT +C and all of the actions including C +are blocking calls. You can use the low-level event API to do +non-blocking operations instead. +All functions that return integers, return C<-1> on error. See +section ERROR HANDLING below for how to handle errors. +=head2 guestfs_h * +C is the opaque type representing a connection handle. +Create a handle by calling C. Call C +to free the handle and release all resources used. +For information on using multiple handles and threads, see the section +MULTIPLE HANDLES AND MULTIPLE THREADS below. +=head2 guestfs_create -=head1 HIGH-LEVEL API + guestfs_h *guestfs_create (void); +Create a connection handle. +You have to call C on the handle at least once. +This function returns a non-NULL pointer to a handle on success or +NULL on error. +After configuring the handle, you have to call C and +C. +You may also want to configure error handling for the handle. See +ERROR HANDLING section below. +=head2 guestfs_close + void guestfs_close (guestfs_h *handle); +This closes the connection handle and frees up all resources used. =head1 ERROR HANDLING +The convention in all functions that return C is that they return +C<-1> to indicate an error. You can get additional information on +errors by calling C and/or by setting up an error +handler with C. + +The default error handler prints the information string to C. + +Out of memory errors are handled differently. The default action is +to call L. If this is undesirable, then you can set a +handler using C. + +=head2 guestfs_last_error + + const char *guestfs_last_error (guestfs_h *handle); + +This returns the last error message that happened on C. If +there has not been an error since the handle was created, then this +returns C. + +The lifetime of the returned string is until the next error occurs, or +C is called. + +The error string is not localized (ie. is always in English), because +this makes searching for error messages in search engines give the +largest number of results. + +=head2 guestfs_set_error_handler + + typedef void (*guestfs_error_handler_cb) (guestfs_h *handle, + void *data, + const char *msg); + void guestfs_set_error_handler (guestfs_h *handle, + guestfs_error_handler_cb cb, + void *data); + +The callback C will be called if there is an error. The +parameters passed to the callback are an opaque data pointer and the +error message string. + +Note that the message string C is freed as soon as the callback +function returns, so if you want to stash it somewhere you must make +your own copy. + +The default handler prints messages on C. + +If you set C to C then I handler is called. + +=head2 guestfs_get_error_handler + + guestfs_error_handler_cb guestfs_get_error_handler (guestfs_h *handle, + void **data_rtn); + +Returns the current error handler callback. + +=head2 guestfs_set_out_of_memory_handler + + typedef void (*guestfs_abort_cb) (void); + int guestfs_set_out_of_memory_handler (guestfs_h *handle, + guestfs_abort_cb); + +The callback C will be called if there is an out of memory +situation. I. +The default is to call L. +You cannot set C to C. You can't ignore out of memory +situations. +=head2 guestfs_get_out_of_memory_handler + guestfs_abort_fn guestfs_get_out_of_memory_handler (guestfs_h *handle); + +This returns the current out of memory handler. + +=head1 PATH + +Libguestfs needs a kernel and initrd.img, which it finds by looking +along an internal path. + +By default it looks for these in the directory C<$libdir/guestfs> +(eg. C or C). + +Use C or set the environment variable +C to change the directories that libguestfs will +search in. The value is a colon-separated list of paths. The current +directory is I searched unless the path contains an empty element +or C<.>. For example C would +search the current directory and then C. + +=head1 HIGH-LEVEL API ACTIONS + +@ACTIONS@ + +=head1 STRUCTURES + +@STRUCTS@ =head1 STATE MACHINE AND LOW-LEVEL EVENT API @@ -79,6 +219,23 @@ 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 libguestfs uses a state machine to model the child process: @@ -154,37 +311,26 @@ this function with C set to C. =head2 NON-BLOCKING ACTIONS -C is the most interesting callback to -play with, since it allows you to perform actions without blocking. +XXX This section was documented in previous versions but never +implemented in a way which matched the documentation. For now I have +removed the documentation, pending a working implementation. See also +C in the source. -For example: - do_it () - { - start_call (); - guestfs_main_loop_run (); /* --> blocks, then calls my_cb */ - } +=head2 guestfs_set_send_callback - start_call () - { - guestfs_set_reply_callback (handle, my_cb, data); - guestfs_nb_[action] (handle, [other parameters ...]); - /* returns immediately */ - } - - my_cb (guestfs_h handle, void *data) - { - retval = guestfs_nb_[action]_r (handle); - /* ... */ - } + typedef void (*guestfs_send_cb) (guestfs_h *g, void *opaque); + void guestfs_set_send_callback (guestfs_h *handle, + guestfs_send_cb cb, + void *opaque); -There are C and C functions -corresponding to (very nearly) every C action in the -high-level API. +The callback function C will be called whenever a message +which is queued for sending, has been sent. =head2 guestfs_set_reply_callback - void guestfs_set_reply_callback (guestfs_handle h, + typedef void (*guestfs_reply_cb) (guestfs_h *g, void *opaque, XDR *xdr); + void guestfs_set_reply_callback (guestfs_h *handle, guestfs_reply_cb cb, void *opaque); @@ -192,12 +338,15 @@ The callback function C will be called whenever a reply is received from the child process. (This corresponds to a transition from the BUSY state to the READY state). -Note (I) that high-level API calls overwrite this -callback. +Note that the C that you get in the callback is in C +mode, and you need to consume it before you return from the callback +function (since it gets destroyed after). =head2 guestfs_set_log_message_callback - void guestfs_set_log_message_callback (guestfs_handle h, + typedef void (*guestfs_log_message_cb) (guestfs_h *g, void *opaque, + char *buf, int len); + void guestfs_set_log_message_callback (guestfs_h *handle, guestfs_log_message_cb cb, void *opaque); @@ -211,7 +360,8 @@ discarded. =head2 guestfs_set_subprocess_quit_callback - void guestfs_set_subprocess_quit_callback (guestfs_handle h, + typedef void (*guestfs_subprocess_quit_cb) (guestfs_h *g, void *opaque); + void guestfs_set_subprocess_quit_callback (guestfs_h *handle, guestfs_subprocess_quit_cb cb, void *opaque); @@ -220,33 +370,35 @@ quits, either asynchronously or if killed by C. (This corresponds to a transition from any state to the CONFIG state). -=head2 guestfs_set_ready_callback +=head2 guestfs_set_launch_done_callback - void guestfs_set_ready_callback (guestfs_handle h, - guestfs_ready_cb cb, - void *opaque); + typedef void (*guestfs_launch_done_cb) (guestfs_h *g, void *opaque); + void guestfs_set_launch_done_callback (guestfs_h *handle, + guestfs_ready_cb cb, + void *opaque); The callback function C will be called when the child process -becomes ready. (This corresponds to a transition from I -LAUNCHING I BUSY to the READY state). +becomes ready first time after it has been launched. (This +corresponds to a transition from LAUNCHING to the READY state). You can use this instead of C to implement a non-blocking wait for the child process to finish booting up. =head2 EVENT MAIN LOOP -To use the low-level event API, you have to provide an event "main -loop". You can write your own, but if you don't want to write one, -two are provided for you: +To use the low-level event API and/or to use handles from multiple +threads, you have to provide an event "main loop". You can write your +own, but if you don't want to write one, two types are provided for +you: =over 4 -=item libguestfs-poll +=item libguestfs-select -A simple main loop that is implemented using L. +A simple main loop that is implemented using L. -This is the default main loop unless you call C -or C. +This is the default main loop for new guestfs handles, unless you +call C after a handle is created. =item libguestfs-glib @@ -256,80 +408,111 @@ without hanging during long or slow operations. =back -=head2 guestfs_set_main_loop +=head2 MULTIPLE HANDLES AND MULTIPLE THREADS - void guestfs_set_main_loop (guestfs_main_loop *); +The support for multiple handles and multiple threads is modelled +after glib (although doesn't require glib, if you use the select-based +main loop). -This call sets the current main loop to the list of callbacks -contained in the C structure. +L -Only one main loop implementation can be used by libguestfs, so -calling this replaces the previous one. (So this is something that -has to be done by the main program, but only the main program "knows" -that it is a GTK+ program or whatever). +You will need to create one main loop for each thread that wants to +use libguestfs. Each guestfs handle should be confined to one thread. +If you try to pass guestfs handles between threads, you will get +undefined results. -You should call this early in the main program, certainly before -calling C. +If you only want to use guestfs handles from one thread in your +program, but your program has other threads doing other things, then +you don't need to do anything special. -=head2 guestfs_glib_set_main_loop +=head2 SINGLE THREAD CASE - void guestfs_glib_set_main_loop (GMainLoop *); +In the single thread case, there is a single select-based main loop +created for you. All guestfs handles will use this main loop to +execute high level API actions. -This helper calls C with the correct callbacks -for integrating with the GLib main loop. +=head2 MULTIPLE THREADS CASE -The libguestfs-glib main loop is contained in a separate library, so -that libguestfs doesn't depend on the whole of GLib: +In the multiple threads case, you will need to create a main loop for +each thread that wants to use libguestfs. - #include - #include +To create main loops for other threads, use +C or C. - main () - { - GMainLoop *loop = - g_main_loop_new (g_main_context_default (), 1); - ... - guestfs_glib_set_main_loop (loop); - ... - g_main_loop_run (loop); - } +Then you will need to attach each handle to the thread-specific main +loop by calling: -To use this main loop you must link with C<-lguestfs-glib>. (See also -the GLib and GTK+ documentation). + handle = guestfs_create (); + guestfs_set_main_loop (handle, main_loop_of_current_thread); + +=head2 guestfs_set_main_loop -=head2 guestfs_main_loop_run + void guestfs_set_main_loop (guestfs_h *handle, + guestfs_main_loop *main_loop); - void guestfs_main_loop_run (void); +Sets the main loop used by high level API actions for this handle. By +default, the select-based main loop is used (see +C). -This calls the main loop. +You only need to use this in multi-threaded programs, where multiple +threads want to use libguestfs. Create a main loop for each thread, +then call this function. -For some types of main loop you may want or prefer to call another -function, eg. C, or the main loop may already be -invoked by another part of your program. In those cases, ignore this -call. +You cannot pass guestfs handles between threads. -=head2 guestfs_main_loop_quit +=head2 guestfs_get_main_loop - void guestfs_main_loop_quit (void); + guestfs_main_loop *guestfs_get_main_loop (guestfs_h *handle); -This instructs the main loop to quit. In other words, -C will return. +Return the main loop used by C. -For some types of main loop you may want or prefer to call another -function, eg. C. In those cases, ignore this call. +=head2 guestfs_get_default_main_loop + + guestfs_main_loop *guestfs_get_default_main_loop (void); + +Return the default select-based main loop. + +=head2 guestfs_create_main_loop + + guestfs_main_loop *guestfs_create_main_loop (void); + +This creates a select-based main loop. You should create one main +loop for each additional thread that needs to use libguestfs. + +=head2 guestfs_free_main_loop + + void guestfs_free_main_loop (guestfs_main_loop *); + +Free the select-based main loop which was previously allocated with +C. =head2 WRITING A CUSTOM MAIN LOOP -This isn't documented. Please see the libguestfs-poll and libguestfs-glib -implementations. +This isn't documented. Please see the libguestfs-select and +libguestfs-glib implementations. -=head1 SEE ALSO +=head1 ENVIRONMENT VARIABLES + +=over 4 + +=item LIBGUESTFS_DEBUG -L +Set C to enable verbose messages. This +has the same effect as calling C. +=item LIBGUESTFS_PATH +Set the path that libguestfs uses to search for kernel and initrd.img. +See the discussion of paths in section PATH above. +=back + +=head1 SEE ALSO +L, +L, +L, +L. =head1 AUTHORS