#include <guestfs.h>
- guestfs_h *handle = guestfs_create ();
- guestfs_add_drive (handle, "guest.img");
- guestfs_launch (handle);
- guestfs_mount (handle, "/dev/sda1", "/");
- guestfs_touch (handle, "/hello");
- guestfs_sync (handle);
- guestfs_close (handle);
+ guestfs_h *g = guestfs_create ();
+ guestfs_add_drive (g, "guest.img");
+ guestfs_launch (g);
+ guestfs_mount (g, "/dev/sda1", "/");
+ guestfs_touch (g, "/hello");
+ guestfs_umount (g, "/");
+ guestfs_sync (g);
+ guestfs_close (g);
+
+ cc prog.c -o prog -lguestfs
+or:
+ cc prog.c -o prog `pkg-config libguestfs --cflags --libs`
=head1 DESCRIPTION
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.
+in the context of the guest. Also you can access filesystems over
+FUSE.
Libguestfs is a library that can be linked with C and C++ management
-programs (or management programs written in OCaml, Perl, Python, Ruby, Java
-or Haskell). You can also use it from shell scripts or the command line.
+programs (or management programs written in OCaml, Perl, Python, Ruby,
+Java, Haskell or C#). 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.
Before you can use libguestfs calls, you have to create a handle.
Then you must add at least one disk image to the handle, followed by
launching the handle, then performing whatever operations you want,
-and finally closing the handle. So the general structure of all
-libguestfs-using programs looks like this:
+and finally closing the handle. By convention we use the single
+letter C<g> for the name of the handle variable, although of course
+you can use any name you want.
- guestfs_h *handle = guestfs_create ();
+The general structure of all libguestfs-using programs looks like
+this:
+
+ guestfs_h *g = guestfs_create ();
/* Call guestfs_add_drive additional times if there are
* multiple disk images.
*/
- guestfs_add_drive (handle, "guest.img");
+ guestfs_add_drive (g, "guest.img");
/* Most manipulation calls won't work until you've launched
- * the handle. You have to do this _after_ adding drives
+ * the handle 'g'. You have to do this _after_ adding drives
* and _before_ other commands.
*/
- guestfs_launch (handle);
+ guestfs_launch (g);
/* Now you can examine what partitions, LVs etc are available.
*/
- char **partitions = guestfs_list_partitions (handle);
- char **logvols = guestfs_lvs (handle);
+ char **partitions = guestfs_list_partitions (g);
+ char **logvols = guestfs_lvs (g);
/* To access a filesystem in the image, you must mount it.
*/
- guestfs_mount (handle, "/dev/sda1", "/");
+ guestfs_mount (g, "/dev/sda1", "/");
/* Now you can perform filesystem actions on the guest
* disk image.
*/
- guestfs_touch (handle, "/hello");
+ guestfs_touch (g, "/hello");
/* You only need to call guestfs_sync if you have made
- * changes to the guest image.
+ * changes to the guest image. (But if you've made changes
+ * then you *must* sync).
*/
- guestfs_sync (handle);
+ guestfs_sync (g);
- /* Close the handle. */
- guestfs_close (handle);
+ /* Close the handle 'g'. */
+ guestfs_close (g);
The code above doesn't include any error checking. In real code you
should check return values carefully for errors. In general all
image contains (for example) one partition with a filesystem on that
partition, then you can mount it directly:
- guestfs_mount (handle, "/dev/sda1", "/");
+ guestfs_mount (g, "/dev/sda1", "/");
where C</dev/sda1> means literally the first partition (C<1>) of the
first disk image that we added (C</dev/sda>). If the disk contains
For example, if you mounted a filesystem at C<"/"> and you want to
read the file called C<"etc/passwd"> then you could do:
- char *data = guestfs_cat (handle, "/etc/passwd");
+ char *data = guestfs_cat (g, "/etc/passwd");
This would return C<data> as a newly allocated buffer containing the
full content of that file (with some conditions: see also
As another example, to create a top-level directory on that filesystem
called C<"var"> you would do:
- guestfs_mkdir (handle, "/var");
+ guestfs_mkdir (g, "/var");
To create a symlink you could do:
- guestfs_ln_s (handle, "/etc/init.d/portmap",
+ guestfs_ln_s (g, "/etc/init.d/portmap",
"/etc/rc3.d/S30portmap");
Libguestfs will reject attempts to use relative paths. There is no
For this, call C<guestfs_case_sensitive_path>.
Libguestfs also provides some help for decoding Windows Registry
-"hive" files, through the library C<libhivex> which is part of
-libguestfs. You have to locate and download the hive file(s)
-yourself, and then pass them to C<libhivex> functions. See also the
-programs L<hivexml(1)>, L<hivexget(1)> and L<virt-win-reg(1)> for more
+"hive" files, through the library C<hivex> which is part of the
+libguestfs project. You have to locate and download the hive file(s)
+yourself, and then pass them to C<hivex> functions. See also the
+programs L<hivexml(1)>, L<hivexsh(1)> and L<virt-win-reg(1)> for more
help on this issue.
=head2 USING LIBGUESTFS WITH OTHER PROGRAMMING LANGUAGES
mention here that the same API is also available in other languages.
The API is broadly identical in all supported languages. This means
-that the C call C<guestfs_mount(handle,path)> is
-C<$handle-E<gt>mount($path)> in Perl, C<handle.mount(path)> in Python,
-and C<Guestfs.mount handle path> in OCaml. In other words, a
+that the C call C<guestfs_mount(g,path)> is
+C<$g-E<gt>mount($path)> in Perl, C<g.mount(path)> in Python,
+and C<Guestfs.mount g path> in OCaml. In other words, a
straightforward, predictable isomorphism between each language.
Error messages are automatically transformed
API is identical to the C API. C++ classes and exceptions are
not implemented.
+=item B<C#>
+
+The C# bindings are highly experimental. Please read the warnings
+at the top of C<csharp/Libguestfs.cs>.
+
=item B<Haskell>
-This is the only language binding that is incomplete. Only calls
-which return simple integers have been bound in Haskell, and we are
-looking for help to complete this binding.
+This is the only language binding that working but incomplete. Only
+calls which return simple integers have been bound in Haskell, and we
+are looking for help to complete this binding.
=item B<Java>
=back
+=head2 LIBGUESTFS GOTCHAS
+
+L<http://en.wikipedia.org/wiki/Gotcha_(programming)>: "A feature of a
+system [...] that works in the way it is documented but is
+counterintuitive and almost invites mistakes."
+
+Since we developed libguestfs and the associated tools, there are
+several things we would have designed differently, but are now stuck
+with for backwards compatibility or other reasons. If there is ever a
+libguestfs 2.0 release, you can expect these to change. Beware of
+them.
+
+=over 4
+
+=item Autosync / forgetting to sync.
+
+When modifying a filesystem from C or another language, you B<must>
+unmount all filesystems and call L</guestfs_sync> explicitly before
+you close the libguestfs handle. You can also call:
+
+ guestfs_set_autosync (g, 1);
+
+to have the unmount/sync done automatically for you when the handle 'g'
+is closed. (This feature is called "autosync", L</guestfs_set_autosync>
+q.v.)
+
+If you forget to do this, then it is entirely possible that your
+changes won't be written out, or will be partially written, or (very
+rarely) that you'll get disk corruption.
+
+Note that in L<guestfish(3)> I<autosync is the default>. So quick and
+dirty guestfish scripts that forget to sync will work just fine, which
+can make this extra-puzzling if you are trying to debug a problem.
+
+=item Mount option C<-o sync> should not be the default.
+
+If you use C<guestfs_mount>, then C<-o sync,noatime> are added
+implicitly. However C<-o sync> does not add any reliability benefit,
+but does have a very large performance impact.
+
+The work around is to use C<guestfs_mount_options> and set the mount
+options that you actually want to use.
+
+=item Read-only should be the default.
+
+In L<guestfish(3)>, I<--ro> should be the default, and you should
+have to specify I<--rw> if you want to make changes to the image.
+
+This would reduce the potential to corrupt live VM images.
+
+Note that many filesystems change the disk when you just mount and
+unmount, even if you didn't perform any writes. You need to use
+C<guestfs_add_drive_ro> to guarantee that the disk is not changed.
+
+=item guestfish command line is hard to use.
+
+C<guestfish disk.img> doesn't do what people expect (open C<disk.img>
+for examination). It tries to run a guestfish command C<disk.img>
+which doesn't exist, so it fails, and it fails with a strange and
+unintuitive error message. Like the Bourne shell, we should have used
+C<guestfish -c command> to run commands.
+
+=back
+
+=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</INTERNALS>
+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
+are individually documented, with a link back to this section of the
+documentation.
+
+A simple call such as C<guestfs_cat> returns its result (the file
+data) in a simple string. Because this string is at some point
+internally encoded as a message, the maximum size that it can return
+is slightly under 4 MB. If the requested file is larger than this
+then you will get an error.
+
+In order to transfer large files into and out of the guest filesystem,
+you need to use particular calls that support this. The sections
+L</UPLOADING> and L</DOWNLOADING> document how to do this.
+
+You might also consider mounting the disk image using our FUSE
+filesystem support (L<guestmount(1)>).
+
=head1 CONNECTION MANAGEMENT
=head2 guestfs_h *
=head2 guestfs_close
- void guestfs_close (guestfs_h *handle);
+ void guestfs_close (guestfs_h *g);
This closes the connection handle and frees up all resources used.
=head2 guestfs_last_error
- const char *guestfs_last_error (guestfs_h *handle);
+ const char *guestfs_last_error (guestfs_h *g);
-This returns the last error message that happened on C<handle>. If
+This returns the last error message that happened on C<g>. If
there has not been an error since the handle was created, then this
returns C<NULL>.
=head2 guestfs_set_error_handler
- typedef void (*guestfs_error_handler_cb) (guestfs_h *handle,
+ typedef void (*guestfs_error_handler_cb) (guestfs_h *g,
void *data,
const char *msg);
- void guestfs_set_error_handler (guestfs_h *handle,
+ void guestfs_set_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb,
void *data);
=head2 guestfs_get_error_handler
- guestfs_error_handler_cb guestfs_get_error_handler (guestfs_h *handle,
+ guestfs_error_handler_cb guestfs_get_error_handler (guestfs_h *g,
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,
+ int guestfs_set_out_of_memory_handler (guestfs_h *g,
guestfs_abort_cb);
The callback C<cb> will be called if there is an out of memory
=head2 guestfs_get_out_of_memory_handler
- guestfs_abort_fn guestfs_get_out_of_memory_handler (guestfs_h *handle);
+ guestfs_abort_fn guestfs_get_out_of_memory_handler (guestfs_h *g);
This returns the current out of memory handler.
dl = dlopen (NULL, RTLD_LAZY);
if (!dl) {
fprintf (stderr, "dlopen: %s\n", dlerror ());
- exit (1);
+ exit (EXIT_FAILURE);
}
has_function = dlsym (dl, "guestfs_dd") != NULL;
dlclose (dl);
typedef void (*guestfs_log_message_cb) (guestfs_h *g, void *opaque,
char *buf, int len);
- void guestfs_set_log_message_callback (guestfs_h *handle,
+ void guestfs_set_log_message_callback (guestfs_h *g,
guestfs_log_message_cb cb,
void *opaque);
=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,
+ void guestfs_set_subprocess_quit_callback (guestfs_h *g,
guestfs_subprocess_quit_cb cb,
void *opaque);
=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,
+ void guestfs_set_launch_done_callback (guestfs_h *g,
guestfs_ready_cb cb,
void *opaque);
=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)>.
+has the same effect as calling C<guestfs_set_verbose (g, 1)>.
=item LIBGUESTFS_MEMSIZE
=item LIBGUESTFS_TRACE
Set C<LIBGUESTFS_TRACE=1> to enable command traces. This
-has the same effect as calling C<guestfs_set_trace (handle, 1)>.
+has the same effect as calling C<guestfs_set_trace (g, 1)>.
=item TMPDIR
=head1 SEE ALSO
L<guestfish(1)>,
+L<guestmount(1)>,
+L<virt-cat(1)>,
+L<virt-df(1)>,
+L<virt-edit(1)>,
+L<virt-inspector(1)>,
+L<virt-list-filesystems(1)>,
+L<virt-list-partitions(1)>,
+L<virt-ls(1)>,
+L<virt-make-fs(1)>,
+L<virt-rescue(1)>,
+L<virt-tar(1)>,
+L<virt-win-reg(1)>,
L<qemu(1)>,
L<febootstrap(1)>,
+L<hivex(3)>,
L<http://libguestfs.org/>.
Tools with a similar purpose: