mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
536 lines
18 KiB
Plaintext
536 lines
18 KiB
Plaintext
=encoding utf8
|
|
|
|
=head1 NAME
|
|
|
|
guestfs - Library for accessing and modifying virtual machine images
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
#include <guestfs.h>
|
|
|
|
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 (handle, "/hello");
|
|
guestfs_sync (handle);
|
|
guestfs_close (handle);
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Libguestfs is a library for accessing and modifying guest disk images.
|
|
Amongst the things this is good for: making batch configuration
|
|
changes to guests, getting disk used/free statistics (see also:
|
|
virt-df), migrating between virtualization systems (see also:
|
|
virt-p2v), performing partial backups, performing partial guest
|
|
clones, cloning guests and changing registry/UUID/hostname info, and
|
|
much else besides.
|
|
|
|
Libguestfs uses Linux kernel and qemu code, and can access any type of
|
|
guest filesystem that Linux and qemu can, including but not limited
|
|
to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
|
|
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 access filesystems over FTP.
|
|
|
|
Libguestfs is a library that can be linked with C and C++ management
|
|
programs (or management programs written in OCaml or Perl).
|
|
You can also use it from shell scripts or the command line.
|
|
|
|
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);
|
|
|
|
C<guestfs_wait_ready> and all of the actions including C<guestfs_sync>
|
|
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<guestfs_h> is the opaque type representing a connection handle.
|
|
Create a handle by calling C<guestfs_create>. Call C<guestfs_close>
|
|
to free the handle and release all resources used.
|
|
|
|
Handles and operations on handles are not thread safe. However you
|
|
can use a separate handle for each thread (but not on the same disk
|
|
image).
|
|
|
|
=head2 guestfs_create
|
|
|
|
guestfs_h *guestfs_create (void);
|
|
|
|
Create a connection handle.
|
|
|
|
You have to call C<guestfs_add_drive> 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<guestfs_launch> and
|
|
C<guestfs_wait_ready>.
|
|
|
|
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<int> is that they return
|
|
C<-1> to indicate an error. You can get additional information on
|
|
errors by calling C<guestfs_last_error> and/or by setting up an error
|
|
handler with C<guestfs_set_error_handler>.
|
|
|
|
The default error handler prints the information string to C<stderr>.
|
|
|
|
Out of memory errors are handled differently. The default action is
|
|
to call L<abort(3)>. If this is undesirable, then you can set a
|
|
handler using C<guestfs_set_out_of_memory_handler>.
|
|
|
|
=head2 guestfs_last_error
|
|
|
|
const char *guestfs_last_error (guestfs_h *handle);
|
|
|
|
This returns the last error message that happened on C<handle>. If
|
|
there has not been an error since the handle was created, then this
|
|
returns C<NULL>.
|
|
|
|
The lifetime of the returned string is until the next error occurs, or
|
|
C<guestfs_close> 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<cb> 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<msg> 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<stderr>.
|
|
|
|
If you set C<cb> to C<NULL> then I<no> 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<cb> will be called if there is an out of memory
|
|
situation. I<Note this callback must not return>.
|
|
|
|
The default is to call L<abort(3)>.
|
|
|
|
You cannot set C<cb> to C<NULL>. 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</usr/local/lib/guestfs> or C</usr/lib64/guestfs>).
|
|
|
|
Use C<guestfs_set_path> or set the environment variable
|
|
C<LIBGUESTFS_PATH> to change the directories that libguestfs will
|
|
search in. The value is a colon-separated list of paths. The current
|
|
directory is I<not> searched unless the path contains an empty element
|
|
or C<.>. For example C<LIBGUESTFS_PATH=:/usr/lib/guestfs> would
|
|
search the current directory and then C</usr/lib/guestfs>.
|
|
|
|
=head1 HIGH-LEVEL API ACTIONS
|
|
|
|
@ACTIONS@
|
|
|
|
=head1 STRUCTURES
|
|
|
|
@STRUCTS@
|
|
|
|
=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
|
|
|
|
libguestfs uses a state machine to model the child process:
|
|
|
|
|
|
|
guestfs_create
|
|
|
|
|
|
|
|
____V_____
|
|
/ \
|
|
| CONFIG |
|
|
\__________/
|
|
^ ^ ^ \
|
|
/ | \ \ guestfs_launch
|
|
/ | _\__V______
|
|
/ | / \
|
|
/ | | LAUNCHING |
|
|
/ | \___________/
|
|
/ | /
|
|
/ | guestfs_wait_ready
|
|
/ | /
|
|
______ / __|____V
|
|
/ \ ------> / \
|
|
| BUSY | | 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) alternating between READY and BUSY as commands are
|
|
issued to, and carried out by, the child process.
|
|
|
|
The guest may be killed by C<guestfs_kill_subprocess>, 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 C<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. C<guestfs_launch> is a non-blocking call that
|
|
starts up the child process, immediately moving from CONFIG to
|
|
LAUNCHING. C<guestfs_wait_ready> blocks until the child process is
|
|
READY to accept commands (or until some failure or timeout). The
|
|
low-level event API described below provides a non-blocking way to
|
|
replace C<guestfs_wait_ready>.
|
|
|
|
High-level API actions such as C<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).
|
|
|
|
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.
|
|
|
|
=head2 SETTING CALLBACKS TO HANDLE EVENTS
|
|
|
|
The child process generates events in some situations. Current events
|
|
include: receiving a reply message after some action, receiving a log
|
|
message, the child process exits, &c.
|
|
|
|
Use the C<guestfs_set_*_callback> functions to set a callback for
|
|
different types of events.
|
|
|
|
Only I<one callback of each type> can be registered for each handle.
|
|
Calling C<guestfs_set_*_callback> again overwrites the previous
|
|
callback of that type. Cancel all callbacks of this type by calling
|
|
this function with C<cb> set to C<NULL>.
|
|
|
|
=head2 NON-BLOCKING ACTIONS
|
|
|
|
XXX NOT IMPLEMENTED YET XXX
|
|
|
|
C<guestfs_set_reply_callback> is the most interesting callback to
|
|
play with, since it allows you to perform actions without blocking.
|
|
|
|
For example:
|
|
|
|
do_it ()
|
|
{
|
|
start_call ();
|
|
guestfs_main_loop_run (); /* --> blocks, then calls my_cb */
|
|
}
|
|
|
|
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, XDR *xdr)
|
|
{
|
|
retval = guestfs_nb_[action]_r (handle, xdr);
|
|
/* ... */
|
|
}
|
|
|
|
There are C<guestfs_nb_*> and C<guestfs_nb_*_r> functions
|
|
corresponding to every C<guestfs_*> action in the high-level API.
|
|
|
|
=head2 guestfs_set_reply_callback
|
|
|
|
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);
|
|
|
|
The callback function C<cb> 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 that the C<xdr> that you get in the callback is in C<XDR_DECODE>
|
|
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
|
|
|
|
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);
|
|
|
|
The callback function C<cb> will be called whenever qemu or the guest
|
|
writes anything to the console.
|
|
|
|
Use this function to capture kernel messages and similar.
|
|
|
|
Normally there is no log message handler, and log messages are just
|
|
discarded.
|
|
|
|
=head2 guestfs_set_subprocess_quit_callback
|
|
|
|
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);
|
|
|
|
The callback function C<cb> will be called when the child process
|
|
quits, either asynchronously or if killed by
|
|
C<guestfs_kill_subprocess>. (This corresponds to a transition from
|
|
any state to the CONFIG state).
|
|
|
|
=head2 guestfs_set_launch_done_callback
|
|
|
|
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<cb> will be called when the child process
|
|
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<guestfs_wait_ready> 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:
|
|
|
|
=over 4
|
|
|
|
=item libguestfs-select
|
|
|
|
A simple main loop that is implemented using L<select(2)>.
|
|
|
|
This is the default main loop unless you call C<guestfs_set_main_loop>
|
|
or C<guestfs_glib_set_main_loop>.
|
|
|
|
=item libguestfs-glib
|
|
|
|
An implementation which can be used with GLib and GTK+ programs. You
|
|
can use this to write graphical (GTK+) programs which use libguestfs
|
|
without hanging during long or slow operations.
|
|
|
|
=back
|
|
|
|
=head2 guestfs_set_main_loop
|
|
|
|
void guestfs_set_main_loop (guestfs_main_loop *);
|
|
|
|
This call sets the current main loop to the list of callbacks
|
|
contained in the C<guestfs_main_loop> structure.
|
|
|
|
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 should call this early in the main program, certainly before
|
|
calling C<guestfs_create>.
|
|
|
|
=head2 guestfs_glib_set_main_loop
|
|
|
|
void guestfs_glib_set_main_loop (GMainLoop *);
|
|
|
|
This helper calls C<guestfs_set_main_loop> with the correct callbacks
|
|
for integrating with the GLib main loop.
|
|
|
|
The libguestfs-glib main loop is contained in a separate library, so
|
|
that libguestfs doesn't depend on the whole of GLib:
|
|
|
|
#include <glib.h>
|
|
#include <guestfs-glib.h>
|
|
|
|
main ()
|
|
{
|
|
GMainLoop *loop =
|
|
g_main_loop_new (g_main_context_default (), 1);
|
|
...
|
|
guestfs_glib_set_main_loop (loop);
|
|
...
|
|
g_main_loop_run (loop);
|
|
}
|
|
|
|
To use this main loop you must link with C<-lguestfs-glib>. (See also
|
|
the GLib and GTK+ documentation).
|
|
|
|
=head2 guestfs_main_loop_run
|
|
|
|
void guestfs_main_loop_run (void);
|
|
|
|
This calls the main loop.
|
|
|
|
For some types of main loop you may want or prefer to call another
|
|
function, eg. C<g_main_loop_run>, or the main loop may already be
|
|
invoked by another part of your program. In those cases, ignore this
|
|
call.
|
|
|
|
=head2 guestfs_main_loop_quit
|
|
|
|
void guestfs_main_loop_quit (void);
|
|
|
|
This instructs the main loop to quit. In other words,
|
|
C<guestfs_main_loop_run> will return.
|
|
|
|
For some types of main loop you may want or prefer to call another
|
|
function, eg. C<g_main_loop_quit>. In those cases, ignore this call.
|
|
|
|
=head2 WRITING A CUSTOM MAIN LOOP
|
|
|
|
This isn't documented. Please see the libguestfs-select and
|
|
libguestfs-glib implementations.
|
|
|
|
=head1 ENVIRONMENT VARIABLES
|
|
|
|
=over 4
|
|
|
|
=item LIBGUESTFS_DEBUG
|
|
|
|
Set C<LIBGUESTFS_DEBUG=1> to enable verbose messages. This
|
|
has the same effect as calling C<guestfs_set_verbose (handle, 1)>.
|
|
|
|
=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<guestfish(1)>,
|
|
L<qemu(1)>,
|
|
L<febootstrap(1)>,
|
|
L<http://et.redhat.com/~rjones/libguestfs>.
|
|
|
|
=head1 AUTHORS
|
|
|
|
Richard W.M. Jones (C<rjones at redhat dot com>)
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (C) 2009 Red Hat Inc.
|
|
L<http://et.redhat.com/~rjones/libguestfs>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|