mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
Commit55202a4d49("New API: get-sockdir", 2016-02-03) added identical language to "fish/guestfish.pod" and "src/guestfs.pod", including an internal link L</get-sockdir>. That's appropriate for "fish/guestfish.pod", but the same API description is generated with a different anchor for "src/guestfs.pod". Adapt the reference. Fixes:55202a4d49Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2184967 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Richard W.M. Jones <rjones@redhat.com> Message-Id: <20230714132213.96616-4-lersek@redhat.com> (cherry picked from commitb4a4b754c6)
3216 lines
102 KiB
Plaintext
3216 lines
102 KiB
Plaintext
=head1 NAME
|
||
|
||
guestfs - Library for accessing and modifying virtual machine images
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
#include <guestfs.h>
|
||
|
||
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_shutdown (g);
|
||
guestfs_close (g);
|
||
|
||
cc prog.c -o prog -lguestfs
|
||
or:
|
||
cc prog.c -o prog `pkg-config libguestfs --cflags --libs`
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
Libguestfs is a library for accessing and modifying disk images and
|
||
virtual machines.
|
||
|
||
This manual page documents the C API.
|
||
|
||
If you are looking for an introduction to libguestfs, see the web
|
||
site: L<http://libguestfs.org/>
|
||
|
||
Each virt tool has its own man page (for a full list, go to
|
||
L</SEE ALSO> at the end of this file).
|
||
|
||
Other libguestfs manual pages:
|
||
|
||
=over 4
|
||
|
||
=item L<guestfs-faq(1)>
|
||
|
||
Frequently Asked Questions (FAQ).
|
||
|
||
=item L<guestfs-examples(3)>
|
||
|
||
Examples of using the API from C. For examples in other languages,
|
||
see L</USING LIBGUESTFS WITH OTHER PROGRAMMING LANGUAGES> below.
|
||
|
||
=item L<guestfs-recipes(1)>
|
||
|
||
Tips and recipes.
|
||
|
||
=item L<guestfs-performance(1)>
|
||
|
||
Performance tips and solutions.
|
||
|
||
=item L<libguestfs-test-tool(1)>
|
||
|
||
=item L<guestfs-testing(1)>
|
||
|
||
Help testing libguestfs.
|
||
|
||
=item L<guestfs-building(1)>
|
||
|
||
How to build libguestfs from source.
|
||
|
||
=item L<guestfs-hacking(1)>
|
||
|
||
Contribute code to libguestfs.
|
||
|
||
=item L<guestfs-internals(1)>
|
||
|
||
How libguestfs works.
|
||
|
||
=item L<guestfs-security(1)>
|
||
|
||
Security information, including CVEs affecting libguestfs.
|
||
|
||
=back
|
||
|
||
=head1 API OVERVIEW
|
||
|
||
This section provides a gentler overview of the libguestfs API. We
|
||
also try to group API calls together, where that may not be obvious
|
||
from reading about the individual calls in the main section of this
|
||
manual.
|
||
|
||
=head2 HANDLES
|
||
|
||
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. 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.
|
||
|
||
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 (g, "guest.img");
|
||
|
||
/* Most manipulation calls won't work until you've launched
|
||
* the handle 'g'. You have to do this _after_ adding drives
|
||
* and _before_ other commands.
|
||
*/
|
||
guestfs_launch (g);
|
||
|
||
/* Either: examine what partitions, LVs etc are available: */
|
||
char **partitions = guestfs_list_partitions (g);
|
||
char **logvols = guestfs_lvs (g);
|
||
|
||
/* Or: ask libguestfs to find filesystems for you: */
|
||
char **filesystems = guestfs_list_filesystems (g);
|
||
|
||
/* Or: use inspection (see INSPECTION section below). */
|
||
|
||
/* To access a filesystem in the image, you must mount it. */
|
||
guestfs_mount (g, "/dev/sda1", "/");
|
||
|
||
/* Now you can perform filesystem actions on the guest
|
||
* disk image.
|
||
*/
|
||
guestfs_touch (g, "/hello");
|
||
|
||
/* Synchronize the disk. This is the opposite of guestfs_launch. */
|
||
guestfs_shutdown (g);
|
||
|
||
/* Close and free 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
|
||
functions that return integers return C<-1> on error, and all
|
||
functions that return pointers return C<NULL> on error. See section
|
||
L</ERROR HANDLING> below for how to handle errors, and consult the
|
||
documentation for each function call below to see precisely how they
|
||
return error indications.
|
||
|
||
The code above does not L<free(3)> the strings and arrays returned
|
||
from functions. Consult the documentation for each function to find
|
||
out how to free the return value.
|
||
|
||
See L<guestfs-examples(3)> for fully worked examples.
|
||
|
||
=head2 DISK IMAGES
|
||
|
||
The image filename (C<"guest.img"> in the example above) could be a
|
||
disk image from a virtual machine, a L<dd(1)> copy of a physical hard
|
||
disk, an actual block device, or simply an empty file of zeroes that
|
||
you have created through L<posix_fallocate(3)>. Libguestfs lets you
|
||
do useful things to all of these.
|
||
|
||
The call you should use in modern code for adding drives is
|
||
L</guestfs_add_drive_opts>. To add a disk image, allowing writes, and
|
||
specifying that the format is raw, do:
|
||
|
||
guestfs_add_drive_opts (g, filename,
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||
-1);
|
||
|
||
You can add a disk read-only using:
|
||
|
||
guestfs_add_drive_opts (g, filename,
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||
GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
|
||
-1);
|
||
|
||
or by calling the older function L</guestfs_add_drive_ro>. If you
|
||
use the readonly flag, libguestfs won't modify the file.
|
||
(See also L</DISK IMAGE FORMATS> below).
|
||
|
||
Be extremely cautious if the disk image is in use, eg. if it is being
|
||
used by a virtual machine. Adding it read-write will almost certainly
|
||
cause disk corruption, but adding it read-only is safe.
|
||
|
||
You should usually add at least one disk image, and you may add
|
||
multiple disk images. If adding multiple disk images, they usually
|
||
have to be "related", ie. from the same guest. In the API, the disk
|
||
images are usually referred to as F</dev/sda> (for the first one you
|
||
added), F</dev/sdb> (for the second one you added), etc.
|
||
|
||
Once L</guestfs_launch> has been called you cannot add any more images.
|
||
You can call L</guestfs_list_devices> to get a list of the device
|
||
names, in the order that you added them.
|
||
See also L</BLOCK DEVICE NAMING> below.
|
||
|
||
=head2 MOUNTING
|
||
|
||
Before you can read or write files, create directories and so on in a
|
||
disk image that contains filesystems, you have to mount those
|
||
filesystems using L</guestfs_mount> or L</guestfs_mount_ro>.
|
||
If you already know that a disk image contains (for example) one
|
||
partition with a filesystem on that partition, then you can mount it
|
||
directly:
|
||
|
||
guestfs_mount (g, "/dev/sda1", "/");
|
||
|
||
where F</dev/sda1> means literally the first partition (C<1>) of the
|
||
first disk image that we added (F</dev/sda>). If the disk contains
|
||
Linux LVM2 logical volumes you could refer to those instead
|
||
(eg. F</dev/VG/LV>). Note that these are libguestfs virtual devices,
|
||
and are nothing to do with host devices.
|
||
|
||
If you are given a disk image and you don’t know what it contains then
|
||
you have to find out. Libguestfs can do that too: use
|
||
L</guestfs_list_partitions> and L</guestfs_lvs> to list possible
|
||
partitions and LVs, and either try mounting each to see what is
|
||
mountable, or else examine them with L</guestfs_vfs_type> or
|
||
L</guestfs_file>. To list just filesystems, use
|
||
L</guestfs_list_filesystems>.
|
||
|
||
Libguestfs also has a set of APIs for inspection of unknown disk
|
||
images (see L</INSPECTION> below). You might also want to look at
|
||
higher level programs built on top of libguestfs, in particular
|
||
L<virt-inspector(1)>.
|
||
|
||
To mount a filesystem read-only, use L</guestfs_mount_ro>. There are
|
||
several other variations of the C<guestfs_mount_*> call.
|
||
|
||
=head2 FILESYSTEM ACCESS AND MODIFICATION
|
||
|
||
The majority of the libguestfs API consists of fairly low-level calls
|
||
for accessing and modifying the files, directories, symlinks etc on
|
||
mounted filesystems. There are over a hundred such calls which you
|
||
can find listed in detail below in this man page, and we don't even
|
||
pretend to cover them all in this overview.
|
||
|
||
Specify filenames as full paths, starting with C<"/"> and including
|
||
the mount point.
|
||
|
||
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 (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
|
||
L</DOWNLOADING> below), or C<NULL> if there was an error.
|
||
|
||
As another example, to create a top-level directory on that filesystem
|
||
called C<"var"> you would do:
|
||
|
||
guestfs_mkdir (g, "/var");
|
||
|
||
To create a symlink you could do:
|
||
|
||
guestfs_ln_s (g, "/etc/init.d/portmap",
|
||
"/etc/rc3.d/S30portmap");
|
||
|
||
Libguestfs will reject attempts to use relative paths and there is no
|
||
concept of a current working directory.
|
||
|
||
Libguestfs can return errors in many situations: for example if the
|
||
filesystem isn't writable, or if a file or directory that you
|
||
requested doesn't exist. If you are using the C API (documented here)
|
||
you have to check for those error conditions after each call. (Other
|
||
language bindings turn these errors into exceptions).
|
||
|
||
File writes are affected by the per-handle umask, set by calling
|
||
L</guestfs_umask> and defaulting to 022. See L</UMASK>.
|
||
|
||
Since libguestfs 1.18, it is possible to mount the libguestfs
|
||
filesystem on a local directory, subject to some restrictions. See
|
||
L</MOUNT LOCAL> below.
|
||
|
||
=head2 PARTITIONING
|
||
|
||
Libguestfs contains API calls to read, create and modify partition
|
||
tables on disk images.
|
||
|
||
In the common case where you want to create a single partition
|
||
covering the whole disk, you should use the L</guestfs_part_disk>
|
||
call:
|
||
|
||
const char *parttype = "mbr";
|
||
if (disk_is_larger_than_2TB)
|
||
parttype = "gpt";
|
||
guestfs_part_disk (g, "/dev/sda", parttype);
|
||
|
||
Obviously this effectively wipes anything that was on that disk image
|
||
before.
|
||
|
||
=head2 LVM2
|
||
|
||
Libguestfs provides access to a large part of the LVM2 API, such as
|
||
L</guestfs_lvcreate> and L</guestfs_vgremove>. It won't make much sense
|
||
unless you familiarize yourself with the concepts of physical volumes,
|
||
volume groups and logical volumes.
|
||
|
||
This author strongly recommends reading the LVM HOWTO, online at
|
||
L<http://tldp.org/HOWTO/LVM-HOWTO/>.
|
||
|
||
=head2 DOWNLOADING
|
||
|
||
Use L</guestfs_cat> to download small, text only files. This call
|
||
cannot handle files containing any ASCII NUL (C<\0>) characters.
|
||
However the API is very simple to use.
|
||
|
||
L</guestfs_read_file> can be used to read files which contain
|
||
arbitrary 8 bit data, since it returns a (pointer, size) pair.
|
||
|
||
L</guestfs_download> can be used to download any file, with no limits
|
||
on content or size.
|
||
|
||
To download multiple files, see L</guestfs_tar_out> and
|
||
L</guestfs_tgz_out>.
|
||
|
||
=head2 UPLOADING
|
||
|
||
To write a small file with fixed content, use L</guestfs_write>. To
|
||
create a file of all zeroes, use L</guestfs_truncate_size> (sparse) or
|
||
L</guestfs_fallocate64> (with all disk blocks allocated). There are a
|
||
variety of other functions for creating test files, for example
|
||
L</guestfs_fill> and L</guestfs_fill_pattern>.
|
||
|
||
To upload a single file, use L</guestfs_upload>. This call has no
|
||
limits on file content or size.
|
||
|
||
To upload multiple files, see L</guestfs_tar_in> and L</guestfs_tgz_in>.
|
||
|
||
However the fastest way to upload I<large numbers of arbitrary files>
|
||
is to turn them into a squashfs or CD ISO (see L<mksquashfs(8)> and
|
||
L<mkisofs(8)>), then attach this using L</guestfs_add_drive_ro>. If
|
||
you add the drive in a predictable way (eg. adding it last after all
|
||
other drives) then you can get the device name from
|
||
L</guestfs_list_devices> and mount it directly using
|
||
L</guestfs_mount_ro>. Note that squashfs images are sometimes
|
||
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.
|
||
|
||
To copy part of a file (offset and size) use
|
||
L</guestfs_copy_file_to_file>.
|
||
|
||
=item B<file> to B<device>
|
||
|
||
=item B<device> to B<file>
|
||
|
||
=item B<device> to B<device>
|
||
|
||
Use L</guestfs_copy_file_to_device>, L</guestfs_copy_device_to_file>,
|
||
or L</guestfs_copy_device_to_device>.
|
||
|
||
Example: duplicate the contents of an LV:
|
||
|
||
guestfs_copy_device_to_device (g,
|
||
"/dev/VG/Original", "/dev/VG/Copy",
|
||
/* -1 marks the end of the list of optional parameters */
|
||
-1);
|
||
|
||
The destination (F</dev/VG/Copy>) must be at least as large as the
|
||
source (F</dev/VG/Original>). To copy less than the whole source
|
||
device, use the optional C<size> parameter:
|
||
|
||
guestfs_copy_device_to_device (g,
|
||
"/dev/VG/Original", "/dev/VG/Copy",
|
||
GUESTFS_COPY_DEVICE_TO_DEVICE_SIZE, 10000,
|
||
-1);
|
||
|
||
=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 UPLOADING AND DOWNLOADING TO PIPES AND FILE DESCRIPTORS
|
||
|
||
Calls like L</guestfs_upload>, L</guestfs_download>,
|
||
L</guestfs_tar_in>, L</guestfs_tar_out> etc appear to only take
|
||
filenames as arguments, so it appears you can only upload and download
|
||
to files. However many Un*x-like hosts let you use the special device
|
||
files F</dev/stdin>, F</dev/stdout>, F</dev/stderr> and F</dev/fd/N>
|
||
to read and write from stdin, stdout, stderr, and arbitrary file
|
||
descriptor N.
|
||
|
||
For example, L<virt-cat(1)> writes its output to stdout by
|
||
doing:
|
||
|
||
guestfs_download (g, filename, "/dev/stdout");
|
||
|
||
and you can write tar output to a file descriptor C<fd> by doing:
|
||
|
||
char devfd[64];
|
||
snprintf (devfd, sizeof devfd, "/dev/fd/%d", fd);
|
||
guestfs_tar_out (g, "/", devfd);
|
||
|
||
=head2 LISTING FILES
|
||
|
||
L</guestfs_ll> is just designed for humans to read (mainly when using
|
||
the L<guestfish(1)>-equivalent command C<ll>).
|
||
|
||
L</guestfs_ls> is a quick way to get a list of files in a directory
|
||
from programs, as a flat list of strings.
|
||
|
||
L</guestfs_readdir> is a programmatic way to get a list of files in a
|
||
directory, plus additional information about each one. It is more
|
||
equivalent to using the L<readdir(3)> call on a local filesystem.
|
||
|
||
L</guestfs_find> and L</guestfs_find0> can be used to recursively list
|
||
files.
|
||
|
||
=head2 RUNNING COMMANDS
|
||
|
||
Although libguestfs is primarily an API for manipulating files
|
||
inside guest images, we also provide some limited facilities for
|
||
running commands inside guests.
|
||
|
||
There are many limitations to this:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
The kernel version that the command runs under will be different
|
||
from what it expects.
|
||
|
||
=item *
|
||
|
||
If the command needs to communicate with daemons, then most likely
|
||
they won't be running.
|
||
|
||
=item *
|
||
|
||
The command will be running in limited memory.
|
||
|
||
=item *
|
||
|
||
The network may not be available unless you enable it
|
||
(see L</guestfs_set_network>).
|
||
|
||
=item *
|
||
|
||
Only supports Linux guests (not Windows, BSD, etc).
|
||
|
||
=item *
|
||
|
||
Architecture limitations (eg. won’t work for a PPC guest on
|
||
an X86 host).
|
||
|
||
=item *
|
||
|
||
For SELinux guests, you may need to relabel the guest after
|
||
creating new files. See L</SELINUX> below.
|
||
|
||
=item *
|
||
|
||
I<Security:> It is not safe to run commands from untrusted, possibly
|
||
malicious guests. These commands may attempt to exploit your program
|
||
by sending unexpected output. They could also try to exploit the
|
||
Linux kernel or qemu provided by the libguestfs appliance. They could
|
||
use the network provided by the libguestfs appliance to bypass
|
||
ordinary network partitions and firewalls. They could use the
|
||
elevated privileges or different SELinux context of your program
|
||
to their advantage.
|
||
|
||
A secure alternative is to use libguestfs to install a "firstboot"
|
||
script (a script which runs when the guest next boots normally), and
|
||
to have this script run the commands you want in the normal context of
|
||
the running guest, network security and so on. For information about
|
||
other security issues, see L<guestfs-security(1)>.
|
||
|
||
=back
|
||
|
||
The two main API calls to run commands are L</guestfs_command> and
|
||
L</guestfs_sh> (there are also variations).
|
||
|
||
The difference is that L</guestfs_sh> runs commands using the shell, so
|
||
any shell globs, redirections, etc will work.
|
||
|
||
=head2 CONFIGURATION FILES
|
||
|
||
To read and write configuration files in Linux guest filesystems, we
|
||
strongly recommend using Augeas. For example, Augeas understands how
|
||
to read and write, say, a Linux shadow password file or X.org
|
||
configuration file, and so avoids you having to write that code.
|
||
|
||
The main Augeas calls are bound through the C<guestfs_aug_*> APIs. We
|
||
don't document Augeas itself here because there is excellent
|
||
documentation on the L<http://augeas.net/> website.
|
||
|
||
If you don’t want to use Augeas (you fool!) then try calling
|
||
L</guestfs_read_lines> to get the file as a list of lines which
|
||
you can iterate over.
|
||
|
||
=head2 SYSTEMD JOURNAL FILES
|
||
|
||
To read the systemd journal from a Linux guest, use the
|
||
C<guestfs_journal_*> APIs starting with L</guestfs_journal_open>.
|
||
|
||
Consult the journal documentation here:
|
||
L<sd-journal(3)>, L<sd_journal_open(3)>.
|
||
|
||
=head2 SELINUX
|
||
|
||
We support SELinux guests. However it is not possible to load the
|
||
SELinux policy of the guest into the appliance kernel. Therefore the
|
||
strategy for dealing with SELinux guests is to relabel them after
|
||
making changes.
|
||
|
||
In libguestfs E<ge> 1.34 there is a new API, L</guestfs_setfiles>,
|
||
which can be used for this. To properly use this API you have to
|
||
parse the guest SELinux configuration. See the L<virt-customize(1)>
|
||
module F<customize/SELinux_relabel.ml> for how to do this.
|
||
|
||
A simpler but slower alternative is to touch F</.autorelabel> in the
|
||
guest, which means that the guest will relabel itself at next boot.
|
||
|
||
Libguestfs E<le> 1.32 had APIs C<guestfs_set_selinux>,
|
||
C<guestfs_get_selinux>, C<guestfs_setcon> and C<guestfs_getcon>.
|
||
These did not work properly, are deprecated, and should not be used in
|
||
new code.
|
||
|
||
=head2 UMASK
|
||
|
||
Certain calls are affected by the current file mode creation mask (the
|
||
"umask"). In particular ones which create files or directories, such
|
||
as L</guestfs_touch>, L</guestfs_mknod> or L</guestfs_mkdir>. This
|
||
affects either the default mode that the file is created with or
|
||
modifies the mode that you supply.
|
||
|
||
The default umask is C<022>, so files are created with modes such as
|
||
C<0644> and directories with C<0755>.
|
||
|
||
There are two ways to avoid being affected by umask. Either set umask
|
||
to 0 (call C<guestfs_umask (g, 0)> early after launching). Or call
|
||
L</guestfs_chmod> after creating each file or directory.
|
||
|
||
For more information about umask, see L<umask(2)>.
|
||
|
||
=head2 LABELS AND UUIDS
|
||
|
||
Many filesystems, devices and logical volumes support either labels
|
||
(short strings like "BOOT" which might not be unique) and/or UUIDs
|
||
(globally unique IDs).
|
||
|
||
For filesystems, use L</guestfs_vfs_label> or L</guestfs_vfs_uuid> to
|
||
read the label or UUID. Some filesystems let you call
|
||
L</guestfs_set_label> or L</guestfs_set_uuid> to change the label or
|
||
UUID.
|
||
|
||
You can locate a filesystem by its label or UUID using
|
||
L</guestfs_findfs_label> or L</guestfs_findfs_uuid>.
|
||
|
||
For LVM2 (which supports only UUIDs), there is a rich set of APIs for
|
||
fetching UUIDs, fetching UUIDs of the contained objects, and changing
|
||
UUIDs. See:
|
||
L</guestfs_lvuuid>,
|
||
L</guestfs_vguuid>,
|
||
L</guestfs_pvuuid>,
|
||
L</guestfs_vglvuuids>,
|
||
L</guestfs_vgpvuuids>,
|
||
L</guestfs_vgchange_uuid>, L</guestfs_vgchange_uuid_all>,
|
||
L</guestfs_pvchange_uuid>, L</guestfs_pvchange_uuid_all>.
|
||
|
||
Note when cloning a filesystem, device or whole guest, it is a good
|
||
idea to set new randomly generated UUIDs on the copy.
|
||
|
||
=head2 ENCRYPTED DISKS
|
||
|
||
Libguestfs allows you to access Linux guests which have been
|
||
encrypted using whole disk encryption that conforms to the
|
||
Linux Unified Key Setup (LUKS) standard. This includes
|
||
nearly all whole disk encryption systems used by modern
|
||
Linux guests. Windows BitLocker is also supported.
|
||
|
||
Use L</guestfs_vfs_type> to identify encrypted block
|
||
devices. For LUKS it returns the string C<crypto_LUKS>.
|
||
For Windows BitLocker it returns C<BitLocker>.
|
||
|
||
Then open these devices by calling L</guestfs_cryptsetup_open>.
|
||
Obviously you will require the passphrase!
|
||
|
||
Passphrase-less unlocking is supported for LUKS (not BitLocker)
|
||
block devices that have been encrypted with network-bound disk
|
||
encryption (NBDE), using Clevis on the Linux guest side, and
|
||
Tang on a separate Linux server. Open such devices with
|
||
L</guestfs_clevis_luks_unlock>. The appliance will need
|
||
networking enabled (refer to L</guestfs_set_network>) and actual
|
||
connectivity to the Tang servers noted in the C<tang> Clevis
|
||
pins that are bound to the LUKS header. (This includes the
|
||
ability to resolve the names of the Tang servers.)
|
||
|
||
Opening an encrypted device creates a new device mapper device
|
||
called F</dev/mapper/mapname> (where C<mapname> is the string
|
||
you supply to L</guestfs_cryptsetup_open> or
|
||
L</guestfs_clevis_luks_unlock>). Reads and writes to this mapper
|
||
device are decrypted from and encrypted to the underlying block
|
||
device respectively.
|
||
|
||
LVM volume groups on the device can be made visible by calling
|
||
L</guestfs_vgscan> followed by L</guestfs_vg_activate_all>.
|
||
The logical volume(s) can now be mounted in the usual way.
|
||
|
||
Use the reverse process to close an encrypted device. Unmount
|
||
any logical volumes on it, deactivate the volume groups
|
||
by calling C<guestfs_vg_activate (g, 0, ["/dev/VG"])>.
|
||
Then close the mapper device by calling
|
||
L</guestfs_cryptsetup_close> on the F</dev/mapper/mapname>
|
||
device (I<not> the underlying encrypted block device).
|
||
|
||
=head2 MOUNT LOCAL
|
||
|
||
In libguestfs E<ge> 1.18, it is possible to mount the libguestfs
|
||
filesystem on a local directory and access it using ordinary POSIX
|
||
calls and programs.
|
||
|
||
Availability of this is subject to a number of restrictions: it
|
||
requires FUSE (the Filesystem in USErspace), and libfuse must also
|
||
have been available when libguestfs was compiled. FUSE may require
|
||
that a kernel module is loaded, and it may be necessary to add the
|
||
current user to a special C<fuse> group. See the documentation for
|
||
your distribution and L<http://fuse.sf.net> for further information.
|
||
|
||
The call to mount the libguestfs filesystem on a local directory is
|
||
L</guestfs_mount_local> (q.v.) followed by L</guestfs_mount_local_run>.
|
||
The latter does not return until you unmount the filesystem.
|
||
The reason is that the call enters the FUSE main loop and processes
|
||
kernel requests, turning them into libguestfs calls. An alternative
|
||
design would have been to create a background thread to do this, but
|
||
libguestfs doesn't require pthreads. This way is also more flexible:
|
||
for example the user can create another thread for
|
||
L</guestfs_mount_local_run>.
|
||
|
||
L</guestfs_mount_local> needs a certain amount of time to set up the
|
||
mountpoint. The mountpoint is not ready to use until the call
|
||
returns. At this point, accesses to the filesystem will block
|
||
until the main loop is entered (ie. L</guestfs_mount_local_run>).
|
||
So if you need to start another process to access the filesystem,
|
||
put the fork between L</guestfs_mount_local> and
|
||
L</guestfs_mount_local_run>.
|
||
|
||
=head3 MOUNT LOCAL COMPATIBILITY
|
||
|
||
Since local mounting was only added in libguestfs 1.18, and may not
|
||
be available even in these builds, you should consider writing code
|
||
so that it doesn't depend on this feature, and can fall back to
|
||
using libguestfs file system calls.
|
||
|
||
If libguestfs was compiled without support for L</guestfs_mount_local>
|
||
then calling it will return an error with errno set to C<ENOTSUP> (see
|
||
L</guestfs_last_errno>).
|
||
|
||
=head3 MOUNT LOCAL PERFORMANCE
|
||
|
||
Libguestfs on top of FUSE performs quite poorly. For best performance
|
||
do not use it. Use ordinary libguestfs filesystem calls, upload,
|
||
download etc. instead.
|
||
|
||
=head2 REMOTE STORAGE
|
||
|
||
=head3 CEPH
|
||
|
||
Libguestfs can access Ceph (librbd/RBD) disks.
|
||
|
||
To do this, set the optional C<protocol> and C<server> parameters of
|
||
L</guestfs_add_drive_opts> like this:
|
||
|
||
char **servers = { "ceph1.example.org:3000", /* ... */, NULL };
|
||
guestfs_add_drive_opts (g, "pool/image",
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||
GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "rbd",
|
||
GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
|
||
GUESTFS_ADD_DRIVE_OPTS_USERNAME, "rbduser",
|
||
GUESTFS_ADD_DRIVE_OPTS_SECRET, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||
-1);
|
||
|
||
C<servers> (the C<server> parameter) is a list of one or more Ceph
|
||
servers. The server string is documented in
|
||
L</guestfs_add_drive_opts>. The C<username> and C<secret> parameters are
|
||
also optional, and if not given, then no authentication will be used.
|
||
|
||
An encrypted RBD disk -- I<directly> opening which would require the
|
||
C<username> and C<secret> parameters -- cannot be accessed if the
|
||
following conditions all hold:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
the L<backend|/BACKEND> is libvirt,
|
||
|
||
=item *
|
||
|
||
the image specified by the C<filename> parameter is different from the
|
||
encrypted RBD disk,
|
||
|
||
=item *
|
||
|
||
the image specified by the C<filename> parameter has L<qcow2
|
||
format|/COMMON VIRTUAL DISK IMAGE FORMATS>,
|
||
|
||
=item *
|
||
|
||
the encrypted RBD disk is specified as a backing file at some level in
|
||
the qcow2 backing chain.
|
||
|
||
=back
|
||
|
||
This limitation is due to libvirt's (justified) separate handling of
|
||
disks vs. secrets. When the RBD username and secret are provided inside
|
||
a qcow2 backing file specification, libvirt does not construct an
|
||
ephemeral secret object from those, for Ceph authentication. Refer to
|
||
L<https://bugzilla.redhat.com/2033247>.
|
||
|
||
=head3 NETWORK BLOCK DEVICE
|
||
|
||
Libguestfs can access Network Block Device (NBD) disks remotely.
|
||
|
||
To do this, set the optional C<protocol> and C<server> parameters of
|
||
L</guestfs_add_drive_opts> like this:
|
||
|
||
char **server = { "nbd.example.org:3000", NULL };
|
||
guestfs_add_drive_opts (g, "" /* export name - see below */,
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||
GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd",
|
||
GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
|
||
-1);
|
||
|
||
Notes:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
C<server> is in fact a list of servers. For NBD you must always
|
||
supply a list with a single element. (Other remote protocols require
|
||
zero or more than one server, hence the requirement for this parameter
|
||
to be a list).
|
||
|
||
=item *
|
||
|
||
The C<server> string is documented in L</guestfs_add_drive_opts>. To
|
||
connect to a local qemu-nbd instance over a Unix domain socket, use
|
||
C<"unix:/path/to/socket">.
|
||
|
||
=item *
|
||
|
||
The C<filename> parameter is the NBD export name. Use an empty string
|
||
to mean the default export. Many NBD servers, including qemu-nbd, do
|
||
not support export names.
|
||
|
||
=item *
|
||
|
||
If using qemu-nbd as your server, you should always specify the C<-t>
|
||
option. The reason is that libguestfs may open several connections to
|
||
the server.
|
||
|
||
=item *
|
||
|
||
The libvirt backend requires that you set the C<format> parameter of
|
||
L</guestfs_add_drive_opts> accurately when you use writable NBD disks.
|
||
|
||
=item *
|
||
|
||
The libvirt backend has a bug that stops Unix domain socket
|
||
connections from working:
|
||
L<https://bugzilla.redhat.com/show_bug.cgi?id=922888>
|
||
|
||
=item *
|
||
|
||
The direct backend does not support readonly connections because
|
||
of a bug in qemu:
|
||
L<https://bugs.launchpad.net/qemu/+bug/1155677>
|
||
|
||
=back
|
||
|
||
=head2 INSPECTION
|
||
|
||
Libguestfs has APIs for inspecting an unknown disk image to find out
|
||
if it contains operating systems, an install CD or a live CD.
|
||
|
||
Add all disks belonging to the unknown virtual machine and call
|
||
L</guestfs_launch> in the usual way.
|
||
|
||
Then call L</guestfs_inspect_os>. This function uses other libguestfs
|
||
calls and certain heuristics, and returns a list of operating systems
|
||
that were found. An empty list means none were found. A single
|
||
element is the root filesystem of the operating system. For dual- or
|
||
multi-boot guests, multiple roots can be returned, each one
|
||
corresponding to a separate operating system. (Multi-boot virtual
|
||
machines are extremely rare in the world of virtualization, but since
|
||
this scenario can happen, we have built libguestfs to deal with it.)
|
||
|
||
For each root, you can then call various C<guestfs_inspect_get_*>
|
||
functions to get additional details about that operating system. For
|
||
example, call L</guestfs_inspect_get_type> to return the string
|
||
C<windows> or C<linux> for Windows and Linux-based operating systems
|
||
respectively.
|
||
|
||
Un*x-like and Linux-based operating systems usually consist of several
|
||
filesystems which are mounted at boot time (for example, a separate
|
||
boot partition mounted on F</boot>). The inspection rules are able to
|
||
detect how filesystems correspond to mount points. Call
|
||
C<guestfs_inspect_get_mountpoints> to get this mapping. It might
|
||
return a hash table like this example:
|
||
|
||
/boot => /dev/sda1
|
||
/ => /dev/vg_guest/lv_root
|
||
/usr => /dev/vg_guest/lv_usr
|
||
|
||
The caller can then make calls to L</guestfs_mount> to
|
||
mount the filesystems as suggested.
|
||
|
||
Be careful to mount filesystems in the right order (eg. F</> before
|
||
F</usr>). Sorting the keys of the hash by length, shortest first,
|
||
should work.
|
||
|
||
Inspection currently only works for some common operating systems.
|
||
Contributors are welcome to send patches for other operating systems
|
||
that we currently cannot detect.
|
||
|
||
Encrypted disks must be opened before inspection. See
|
||
L</ENCRYPTED DISKS> for more details. The L</guestfs_inspect_os>
|
||
function just ignores any encrypted devices.
|
||
|
||
A note on the implementation: The call L</guestfs_inspect_os> performs
|
||
inspection and caches the results in the guest handle. Subsequent
|
||
calls to C<guestfs_inspect_get_*> return this cached information, but
|
||
I<do not> re-read the disks. If you change the content of the guest
|
||
disks, you can redo inspection by calling L</guestfs_inspect_os>
|
||
again. (L</guestfs_inspect_list_applications2> works a little
|
||
differently from the other calls and does read the disks. See
|
||
documentation for that function for details).
|
||
|
||
=head3 INSPECTING INSTALL DISKS
|
||
|
||
Libguestfs (since 1.9.4) can detect some install disks, install
|
||
CDs, live CDs and more.
|
||
|
||
Further information is available about the operating system that can
|
||
be installed using the regular inspection APIs like
|
||
L</guestfs_inspect_get_product_name>,
|
||
L</guestfs_inspect_get_major_version> etc.
|
||
|
||
=head2 SPECIAL CONSIDERATIONS FOR WINDOWS GUESTS
|
||
|
||
Libguestfs can mount NTFS partitions. It does this using the
|
||
L<http://www.ntfs-3g.org/> driver.
|
||
|
||
=head3 DRIVE LETTERS AND PATHS
|
||
|
||
DOS and Windows still use drive letters, and the filesystems are
|
||
always treated as case insensitive by Windows itself, and therefore
|
||
you might find a Windows configuration file referring to a path like
|
||
C<c:\windows\system32>. When the filesystem is mounted in libguestfs,
|
||
that directory might be referred to as F</WINDOWS/System32>.
|
||
|
||
Drive letter mappings can be found using inspection
|
||
(see L</INSPECTION> and L</guestfs_inspect_get_drive_mappings>)
|
||
|
||
Dealing with separator characters (backslash vs forward slash) is
|
||
outside the scope of libguestfs, but usually a simple character
|
||
replacement will work.
|
||
|
||
To resolve the case insensitivity of paths, call
|
||
L</guestfs_case_sensitive_path>.
|
||
|
||
=head3 LONG FILENAMES ON NTFS
|
||
|
||
NTFS supports filenames up to 255 characters long. "Character" means
|
||
a 2 byte UTF-16 codepoint which can encode the most common Unicode
|
||
codepoints.
|
||
|
||
Most Linux filesystems support filenames up to 255 I<bytes>.
|
||
This means you may get an error:
|
||
|
||
File name too long
|
||
|
||
when you copy a file from NTFS to a Linux filesystem if the name, when
|
||
reencoded as UTF-8, would exceed 255 bytes in length.
|
||
|
||
This will most often happen when using non-ASCII names that are longer
|
||
than ~127 characters (eg. Greek, Cyrillic) or longer than ~85
|
||
characters (Asian languages).
|
||
|
||
A workaround is not to try to store such long filenames on Linux
|
||
native filesystems. Since the L<tar(1)> format can store unlimited
|
||
length filenames, keep the files in a tarball.
|
||
|
||
=head3 ACCESSING THE WINDOWS REGISTRY
|
||
|
||
Libguestfs also provides some help for decoding Windows Registry
|
||
"hive" files, through a separate C library called L<hivex(3)>.
|
||
|
||
Before libguestfs 1.19.35 you had to download the hive file, operate
|
||
on it locally using hivex, and upload it again. Since this version,
|
||
we have included the major hivex APIs directly in the libguestfs API
|
||
(see L</guestfs_hivex_open>). This means that if you have opened a
|
||
Windows guest, you can read and write the registry directly.
|
||
|
||
See also L<virt-win-reg(1)>.
|
||
|
||
=head3 SYMLINKS ON NTFS-3G FILESYSTEMS
|
||
|
||
Ntfs-3g tries to rewrite "Junction Points" and NTFS "symbolic links"
|
||
to provide something which looks like a Linux symlink. The way it
|
||
tries to do the rewriting is described here:
|
||
|
||
L<http://www.tuxera.com/community/ntfs-3g-advanced/junction-points-and-symbolic-links/>
|
||
|
||
The essential problem is that ntfs-3g simply does not have enough
|
||
information to do a correct job. NTFS links can contain drive letters
|
||
and references to external device GUIDs that ntfs-3g has no way of
|
||
resolving. It is almost certainly the case that libguestfs callers
|
||
should ignore what ntfs-3g does (ie. don't use L</guestfs_readlink> on
|
||
NTFS volumes).
|
||
|
||
Instead if you encounter a symbolic link on an ntfs-3g filesystem, use
|
||
L</guestfs_lgetxattr> to read the C<system.ntfs_reparse_data> extended
|
||
attribute, and read the raw reparse data from that (you can find the
|
||
format documented in various places around the web).
|
||
|
||
=head3 EXTENDED ATTRIBUTES ON NTFS-3G FILESYSTEMS
|
||
|
||
There are other useful extended attributes that can be read from
|
||
ntfs-3g filesystems (using L</guestfs_getxattr>). See:
|
||
|
||
L<http://www.tuxera.com/community/ntfs-3g-advanced/extended-attributes/>
|
||
|
||
=head3 WINDOWS HIBERNATION AND WINDOWS 8 FAST STARTUP
|
||
|
||
Windows guests which have been hibernated (instead of fully shut down)
|
||
cannot be mounted. This is a limitation of ntfs-3g. You will see an
|
||
error like this:
|
||
|
||
The disk contains an unclean file system (0, 0).
|
||
Metadata kept in Windows cache, refused to mount.
|
||
Failed to mount '/dev/sda2': Operation not permitted
|
||
The NTFS partition is in an unsafe state. Please resume
|
||
and shutdown Windows fully (no hibernation or fast
|
||
restarting), or mount the volume read-only with the
|
||
'ro' mount option.
|
||
|
||
In Windows 8, the shutdown button does not shut down the guest at all.
|
||
Instead it usually hibernates the guest. This is known as "fast
|
||
startup".
|
||
|
||
Some suggested workarounds are:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
Mount read-only (eg. L</guestfs_mount_ro>).
|
||
|
||
=item *
|
||
|
||
On Windows 8, turn off fast startup. It is in the Control Panel →
|
||
Power Options → Choose what the power buttons do → Change settings
|
||
that are currently unavailable → Turn on fast startup.
|
||
|
||
=item *
|
||
|
||
On Windows 7 and earlier, shut the guest off properly instead of
|
||
hibernating it.
|
||
|
||
=back
|
||
|
||
=head2 RESIZE2FS ERRORS
|
||
|
||
The L</guestfs_resize2fs>, L</guestfs_resize2fs_size> and
|
||
L</guestfs_resize2fs_M> calls are used to resize ext2/3/4 filesystems.
|
||
|
||
The underlying program (L<resize2fs(8)>) requires that the filesystem
|
||
is clean and recently fsck'd before you can resize it. Also, if the
|
||
resize operation fails for some reason, then you had to call fsck the
|
||
filesystem again to fix it.
|
||
|
||
In libguestfs C<lt> 1.17.14, you usually had to call
|
||
L</guestfs_e2fsck_f> before the resize. However, in C<ge> 1.17.14,
|
||
L<e2fsck(8)> is called automatically before the resize, so you no
|
||
longer need to do this.
|
||
|
||
The L<resize2fs(8)> program can still fail, in which case it prints an
|
||
error message similar to:
|
||
|
||
Please run 'e2fsck -fy <device>' to fix the filesystem
|
||
after the aborted resize operation.
|
||
|
||
You can do this by calling L</guestfs_e2fsck> with the C<forceall>
|
||
option. However in the context of disk images, it is usually better
|
||
to avoid this situation, eg. by rolling back to an earlier snapshot,
|
||
or by copying and resizing and on failure going back to the original.
|
||
|
||
=head2 USING LIBGUESTFS WITH OTHER PROGRAMMING LANGUAGES
|
||
|
||
Although we don’t want to discourage you from using the C API, we will
|
||
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_add_drive_ro(g,file)> is
|
||
C<$g-E<gt>add_drive_ro($file)> in Perl, C<g.add_drive_ro(file)> in Python,
|
||
and C<g#add_drive_ro file> in OCaml. In other words, a
|
||
straightforward, predictable isomorphism between each language.
|
||
|
||
Error messages are automatically transformed
|
||
into exceptions if the language supports it.
|
||
|
||
We don’t try to "object orientify" parts of the API in OO languages,
|
||
although contributors are welcome to write higher level APIs above
|
||
what we provide in their favourite languages if they wish.
|
||
|
||
=over 4
|
||
|
||
=item B<C++>
|
||
|
||
You can use the I<guestfs.h> header file from C++ programs. The C++
|
||
API is identical to the C API. C++ classes and exceptions are not
|
||
used.
|
||
|
||
=item B<C#>
|
||
|
||
The C# bindings are highly experimental. Please read the warnings
|
||
at the top of F<csharp/Libguestfs.cs>.
|
||
|
||
=item B<Erlang>
|
||
|
||
See L<guestfs-erlang(3)>.
|
||
|
||
=item B<GObject>
|
||
|
||
Experimental GObject bindings (with GObject Introspection support) are
|
||
available.
|
||
|
||
See L<guestfs-gobject(3)>.
|
||
|
||
=item B<Go>
|
||
|
||
See L<guestfs-golang(3)>.
|
||
|
||
=item B<Haskell>
|
||
|
||
This language binding is working but incomplete:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
Functions with optional arguments are not bound. Implementing
|
||
optional arguments in Haskell seems to be very complex.
|
||
|
||
=item *
|
||
|
||
Events are not bound.
|
||
|
||
=item *
|
||
|
||
Functions with the following return types are not bound:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
Any function returning a struct.
|
||
|
||
=item *
|
||
|
||
Any function returning a list of structs.
|
||
|
||
=item *
|
||
|
||
A few functions that return fixed length buffers (specifically ones
|
||
declared C<RBufferOut> in the generator).
|
||
|
||
=item *
|
||
|
||
A tiny number of obscure functions that return constant strings
|
||
(specifically ones declared C<RConstOptString> in the generator).
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=item B<Java>
|
||
|
||
Full documentation is contained in the Javadoc which is distributed
|
||
with libguestfs. For examples, see L<guestfs-java(3)>.
|
||
|
||
=item B<Lua>
|
||
|
||
See L<guestfs-lua(3)>.
|
||
|
||
=item B<OCaml>
|
||
|
||
See L<guestfs-ocaml(3)>.
|
||
|
||
=item B<Perl>
|
||
|
||
See L<guestfs-perl(3)> and L<Sys::Guestfs(3)>.
|
||
|
||
=item B<PHP>
|
||
|
||
For documentation see C<README-PHP> supplied with libguestfs
|
||
sources or in the php-libguestfs package for your distribution.
|
||
|
||
The PHP binding only works correctly on 64 bit machines.
|
||
|
||
=item B<Python>
|
||
|
||
See L<guestfs-python(3)>.
|
||
|
||
=item B<Ruby>
|
||
|
||
See L<guestfs-ruby(3)>.
|
||
|
||
For JRuby, use the Java bindings.
|
||
|
||
=item B<shell scripts>
|
||
|
||
See L<guestfish(1)>.
|
||
|
||
=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 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
|
||
L</guestfs_add_drive_ro> to guarantee that the disk is not changed.
|
||
|
||
=item guestfish command line is hard to use.
|
||
|
||
F<guestfish disk.img> doesn't do what people expect (open F<disk.img>
|
||
for examination). It tries to run a guestfish command F<disk.img>
|
||
which doesn't exist, so it fails. In earlier versions of guestfish
|
||
the error message was also unintuitive, but we have corrected this
|
||
since. Like the Bourne shell, we should have used C<guestfish -c
|
||
command> to run commands.
|
||
|
||
=item guestfish megabyte modifiers don’t work right on all commands
|
||
|
||
In recent guestfish you can use C<1M> to mean 1 megabyte (and
|
||
similarly for other modifiers). What guestfish actually does is to
|
||
multiply the number part by the modifier part and pass the result to
|
||
the C API. However this doesn't work for a few APIs which aren't
|
||
expecting bytes, but are already expecting some other unit
|
||
(eg. megabytes).
|
||
|
||
The most common is L</guestfs_lvcreate>. The guestfish command:
|
||
|
||
lvcreate LV VG 100M
|
||
|
||
does not do what you might expect. Instead because
|
||
L</guestfs_lvcreate> is already expecting megabytes, this tries to
|
||
create a 100 I<terabyte> (100 megabytes * megabytes) logical volume.
|
||
The error message you get from this is also a little obscure.
|
||
|
||
This could be fixed in the generator by specially marking parameters
|
||
and return values which take bytes or other units.
|
||
|
||
=item Ambiguity between devices and paths
|
||
|
||
There is a subtle ambiguity in the API between a device name
|
||
(eg. F</dev/sdb2>) and a similar pathname. A file might just happen
|
||
to be called C<sdb2> in the directory F</dev> (consider some non-Unix
|
||
VM image).
|
||
|
||
In the current API we usually resolve this ambiguity by having two
|
||
separate calls, for example L</guestfs_checksum> and
|
||
L</guestfs_checksum_device>. Some API calls are ambiguous and
|
||
(incorrectly) resolve the problem by detecting if the path supplied
|
||
begins with F</dev/>.
|
||
|
||
To avoid both the ambiguity and the need to duplicate some calls, we
|
||
could make paths/devices into structured names. One way to do this
|
||
would be to use a notation like grub (C<hd(0,0)>), although nobody
|
||
really likes this aspect of grub. Another way would be to use a
|
||
structured type, equivalent to this OCaml type:
|
||
|
||
type path = Path of string | Device of int | Partition of int * int
|
||
|
||
which would allow you to pass arguments like:
|
||
|
||
Path "/foo/bar"
|
||
Device 1 (* /dev/sdb, or perhaps /dev/sda *)
|
||
Partition (1, 2) (* /dev/sdb2 (or is it /dev/sda2 or /dev/sdb3?) *)
|
||
Path "/dev/sdb2" (* not a device *)
|
||
|
||
As you can see there are still problems to resolve even with this
|
||
representation. Also consider how it might work in guestfish.
|
||
|
||
=back
|
||
|
||
=head2 KEYS AND PASSPHRASES
|
||
|
||
Certain libguestfs calls take a parameter that contains sensitive key
|
||
material, passed in as a C string.
|
||
|
||
In the future we would hope to change the libguestfs implementation so
|
||
that keys are L<mlock(2)>-ed into physical RAM, and thus can never end
|
||
up in swap. However this is I<not> done at the moment, because of the
|
||
complexity of such an implementation.
|
||
|
||
Therefore you should be aware that any key parameter you pass to
|
||
libguestfs might end up being written out to the swap partition. If
|
||
this is a concern, scrub the swap partition or don't use libguestfs on
|
||
encrypted devices.
|
||
|
||
=head2 MULTIPLE HANDLES AND MULTIPLE THREADS
|
||
|
||
All high-level libguestfs actions are synchronous. If you want
|
||
to use libguestfs asynchronously then you must create a thread.
|
||
|
||
=head3 Threads in libguestfs E<ge> 1.38
|
||
|
||
In libguestfs E<ge> 1.38, each handle (C<guestfs_h>) contains a lock
|
||
which is acquired automatically when you call a libguestfs function.
|
||
The practical effect of this is you can call libguestfs functions with
|
||
the same handle from multiple threads without needing to do any
|
||
locking.
|
||
|
||
Also in libguestfs E<ge> 1.38, the last error on the handle
|
||
(L</guestfs_last_error>, L</guestfs_last_errno>) is stored in
|
||
thread-local storage, so it is safe to write code like:
|
||
|
||
if (guestfs_add_drive_ro (g, drive) == -1)
|
||
fprintf (stderr, "error was: %s\n", guestfs_last_error (g));
|
||
|
||
even when other threads may be concurrently using the same handle C<g>.
|
||
|
||
=head3 Threads in libguestfs E<lt> 1.38
|
||
|
||
In libguestfs E<lt> 1.38, you must use the handle only from a single
|
||
thread. Either use the handle exclusively from one thread, or provide
|
||
your own mutex so that two threads cannot issue calls on the same
|
||
handle at the same time. Even apparently innocent functions like
|
||
L</guestfs_get_trace> are I<not> safe to be called from multiple
|
||
threads without a mutex in libguestfs E<lt> 1.38.
|
||
|
||
Use L</guestfs_set_identifier> to make it simpler to identify threads
|
||
in trace output.
|
||
|
||
=head2 PATH
|
||
|
||
Libguestfs needs a supermin appliance, which it finds by looking along
|
||
an internal path.
|
||
|
||
By default it looks for these in the directory C<$libdir/guestfs>
|
||
(eg. F</usr/local/lib/guestfs> or F</usr/lib64/guestfs>).
|
||
|
||
Use L</guestfs_set_path> or set the environment variable
|
||
L</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 F</usr/lib/guestfs>.
|
||
|
||
=head2 QEMU WRAPPERS
|
||
|
||
If you want to compile your own qemu, run qemu from a non-standard
|
||
location, or pass extra arguments to qemu, then you can write a
|
||
shell-script wrapper around qemu.
|
||
|
||
There is one important rule to remember: you I<must C<exec qemu>> as
|
||
the last command in the shell script (so that qemu replaces the shell
|
||
and becomes the direct child of the libguestfs-using program). If you
|
||
don't do this, then the qemu process won't be cleaned up correctly.
|
||
|
||
Here is an example of a wrapper, where I have built my own copy of
|
||
qemu from source:
|
||
|
||
#!/bin/sh -
|
||
qemudir=/home/rjones/d/qemu
|
||
exec $qemudir/x86_64-softmmu/qemu-system-x86_64 -L $qemudir/pc-bios "$@"
|
||
|
||
Save this script as F</tmp/qemu.wrapper> (or wherever), C<chmod +x>,
|
||
and then use it by setting the LIBGUESTFS_HV environment variable.
|
||
For example:
|
||
|
||
LIBGUESTFS_HV=/tmp/qemu.wrapper guestfish
|
||
|
||
Note that libguestfs also calls qemu with the -help and -version
|
||
options in order to determine features.
|
||
|
||
Wrappers can also be used to edit the options passed to qemu. In the
|
||
following example, the C<-machine ...> option (C<-machine> and the
|
||
following argument) are removed from the command line and replaced
|
||
with C<-machine pc,accel=tcg>. The while loop iterates over the
|
||
options until it finds the right one to remove, putting the remaining
|
||
options into the C<args> array.
|
||
|
||
#!/bin/bash -
|
||
|
||
i=0
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
-machine)
|
||
shift 2;;
|
||
*)
|
||
args[i]="$1"
|
||
(( i++ ))
|
||
shift ;;
|
||
esac
|
||
done
|
||
|
||
exec qemu-kvm -machine pc,accel=tcg "${args[@]}"
|
||
|
||
=begin html
|
||
|
||
<!-- old anchor for the next section -->
|
||
<a name="attach-method"/>
|
||
|
||
=end html
|
||
|
||
=head2 BACKEND
|
||
|
||
The backend (previously known as the "attach method") controls how
|
||
libguestfs creates and/or connects to the backend daemon, eg. by
|
||
starting qemu directly, or using libvirt to manage an appliance,
|
||
running User-Mode Linux, or connecting to an already running daemon.
|
||
|
||
You can set the backend by calling L</guestfs_set_backend>, or by
|
||
setting the environment variable C<LIBGUESTFS_BACKEND>.
|
||
|
||
Possible backends are described below:
|
||
|
||
=over 4
|
||
|
||
=item C<direct>
|
||
|
||
=item C<appliance>
|
||
|
||
Run qemu directly to launch an appliance.
|
||
|
||
C<direct> and C<appliance> are synonyms.
|
||
|
||
This is the ordinary method and normally the default, but see the
|
||
note below.
|
||
|
||
=item C<libvirt>
|
||
|
||
=item C<libvirt:null>
|
||
|
||
=item C<libvirt:I<URI>>
|
||
|
||
Use libvirt to launch and manage the appliance.
|
||
|
||
C<libvirt> causes libguestfs to choose a suitable URI for creating
|
||
session guests. If using the libvirt backend, you almost always
|
||
should use this.
|
||
|
||
C<libvirt:null> causes libguestfs to use the C<NULL> connection URI,
|
||
which causes libvirt to try to guess what the user meant. You
|
||
probably don't want to use this.
|
||
|
||
C<libvirt:I<URI>> uses I<URI> as the libvirt connection URI (see
|
||
L<http://libvirt.org/uri.html>). The typical libvirt backend with a
|
||
URI would be C<libvirt:qemu:///session>
|
||
|
||
The libvirt backend supports more features, including sVirt.
|
||
|
||
=back
|
||
|
||
C<direct> is usually the default backend. However since libguestfs
|
||
E<ge> 1.19.24, libguestfs can be built with a different default by
|
||
doing:
|
||
|
||
./configure --with-default-backend=...
|
||
|
||
To find out if libguestfs was compiled with a different default
|
||
backend, do:
|
||
|
||
unset LIBGUESTFS_BACKEND
|
||
guestfish get-backend
|
||
|
||
=head2 BACKEND SETTINGS
|
||
|
||
Each backend can be configured by passing a list of strings. You can
|
||
either call L</guestfs_set_backend_settings> with a list of strings,
|
||
or set the C<LIBGUESTFS_BACKEND_SETTINGS> environment variable to a
|
||
colon-separated list of strings (before creating the handle).
|
||
|
||
=head3 force_tcg
|
||
|
||
Using:
|
||
|
||
export LIBGUESTFS_BACKEND_SETTINGS=force_tcg
|
||
|
||
will force the direct and libvirt backends to use TCG (software
|
||
emulation) instead of KVM (hardware accelerated virtualization).
|
||
|
||
=head3 force_kvm
|
||
|
||
Using:
|
||
|
||
export LIBGUESTFS_BACKEND_SETTINGS=force_kvm
|
||
|
||
will force the direct and libvirt backends to use KVM (hardware
|
||
accelerated virtualization) instead of TCG (software emulation).
|
||
|
||
=head3 gdb
|
||
|
||
The direct backend supports:
|
||
|
||
export LIBGUESTFS_BACKEND_SETTINGS=gdb
|
||
|
||
When this is set, qemu will not start running the appliance
|
||
immediately. It will wait for you to connect to it using gdb:
|
||
|
||
$ gdb
|
||
(gdb) symbol-file /path/to/vmlinux
|
||
(gdb) target remote tcp::1234
|
||
(gdb) cont
|
||
|
||
You can then debug the appliance kernel, which is useful to debug boot
|
||
failures (especially ones where there are no debug messages printed -
|
||
tip: look in the kernel C<log_buf>).
|
||
|
||
On Fedora, install C<kernel-debuginfo> for the C<vmlinux> file
|
||
(containing symbols). Make sure the symbols precisely match the
|
||
kernel being used.
|
||
|
||
=head2 ABI GUARANTEE
|
||
|
||
We guarantee the libguestfs ABI (binary interface), for public,
|
||
high-level actions as outlined in this section. Although we will
|
||
deprecate some actions, for example if they get replaced by newer
|
||
calls, we will keep the old actions forever. This allows you the
|
||
developer to program in confidence against the libguestfs API.
|
||
|
||
=head2 BLOCK DEVICE NAMING
|
||
|
||
Libguestfs defines F</dev/sd*> as the I<standard naming scheme> for
|
||
devices passed to API calls. So F</dev/sda> means "the first device
|
||
added by L</guestfs_add_drive_opts>", and F</dev/sdb3> means "the
|
||
third partition on the second device".
|
||
|
||
Internally device names are sometimes translated, but this should not
|
||
be visible at the API level.
|
||
|
||
=head3 DISK LABELS
|
||
|
||
In libguestfs E<ge> 1.20, you can give a label to a disk when you add
|
||
it, using the optional C<label> parameter to L</guestfs_add_drive_opts>.
|
||
(Note that disk labels are different from and not related to
|
||
filesystem labels).
|
||
|
||
Not all versions of libguestfs support setting a disk label, and when
|
||
it is supported, it is limited to 20 ASCII characters C<[a-zA-Z]>.
|
||
|
||
When you add a disk with a label, it can either be addressed
|
||
using F</dev/sd*>, or using F</dev/disk/guestfs/I<label>>.
|
||
Partitions on the disk can be addressed using
|
||
F</dev/disk/guestfs/I<label>I<partnum>>.
|
||
|
||
Listing devices (L</guestfs_list_devices>) and partitions
|
||
(L</guestfs_list_partitions>) returns the block device names. However
|
||
you can use L</guestfs_list_disk_labels> to map disk labels to block
|
||
device and partition names.
|
||
|
||
=head2 NULL DISKS
|
||
|
||
When adding a disk using, eg., L</guestfs_add_drive>, you can
|
||
set the filename to C<"/dev/null">. This string is treated
|
||
specially by libguestfs, causing it to add a "null disk".
|
||
|
||
A null disk has the following properties:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
A null disk will appear as a normal device, eg. in
|
||
calls to L</guestfs_list_devices>.
|
||
|
||
=item *
|
||
|
||
You may add C<"/dev/null"> multiple times.
|
||
|
||
=item *
|
||
|
||
You should not try to access a null disk in any way. For
|
||
example, you shouldn't try to read it or mount it.
|
||
|
||
=back
|
||
|
||
Null disks are used for three main purposes:
|
||
|
||
=over 4
|
||
|
||
=item 1.
|
||
|
||
Performance testing of libguestfs (see L<guestfs-performance(1)>).
|
||
|
||
=item 2.
|
||
|
||
The internal test suite.
|
||
|
||
=item 3.
|
||
|
||
If you want to use libguestfs APIs that don’t refer to disks, since
|
||
libguestfs requires that at least one disk is added, you should add a
|
||
null disk.
|
||
|
||
For example, to test if a feature is available, use code like this:
|
||
|
||
guestfs_h *g;
|
||
char **groups = [ "btrfs", NULL ];
|
||
|
||
g = guestfs_create ();
|
||
guestfs_add_drive (g, "/dev/null");
|
||
guestfs_launch (g);
|
||
if (guestfs_available (g, groups) == 0) {
|
||
// group(s) are available
|
||
} else {
|
||
// group(s) are not available
|
||
}
|
||
guestfs_close (g);
|
||
|
||
=back
|
||
|
||
=head2 DISK IMAGE FORMATS
|
||
|
||
Virtual disks come in a variety of formats. Some common formats
|
||
are listed below.
|
||
|
||
Note that libguestfs itself is not responsible for handling the disk
|
||
format: this is done using L<qemu(1)>. If support for a particular
|
||
format is missing or broken, this has to be fixed in qemu.
|
||
|
||
=head3 COMMON VIRTUAL DISK IMAGE FORMATS
|
||
|
||
=over 4
|
||
|
||
=item I<raw>
|
||
|
||
Raw format is simply a dump of the sequential bytes of the virtual
|
||
hard disk. There is no header, container, compression or processing
|
||
of any sort.
|
||
|
||
Since raw format requires no translation to read or write, it is both
|
||
fast and very well supported by qemu and all other hypervisors. You
|
||
can consider it to be a universal format that any hypervisor can
|
||
access.
|
||
|
||
Raw format files are not compressed and so take up the full space of
|
||
the original disk image even when they are empty. A variation (on
|
||
Linux/Unix at least) is to not store ranges of all-zero bytes by
|
||
storing the file as a sparse file. This "variant format" is sometimes
|
||
called I<raw sparse>. Many utilities, including L<virt-sparsify(1)>,
|
||
can make raw disk images sparse.
|
||
|
||
=item I<qcow2>
|
||
|
||
Qcow2 is the native disk image format used by qemu. Internally it
|
||
uses a two-level directory structure so that only blocks containing
|
||
data are stored in the file. It also has many other features such as
|
||
compression, snapshots and backing files.
|
||
|
||
There are at least two distinct variants of this format, although qemu
|
||
(and hence libguestfs) handles both transparently to the user.
|
||
|
||
=item I<vmdk>
|
||
|
||
VMDK is VMware’s native disk image format. There are many variations.
|
||
Modern qemu (hence libguestfs) supports most variations, but you
|
||
should be aware that older versions of qemu had some very bad
|
||
data-corrupting bugs in this area.
|
||
|
||
Note that VMware ESX exposes files with the name F<guest-flat.vmdk>.
|
||
These are not VMDK. They are raw format files which happen to have a
|
||
C<.vmdk> extension.
|
||
|
||
=item I<vdi>
|
||
|
||
VDI is VirtualBox’s native disk image format. Qemu (hence libguestfs)
|
||
has generally good support for this.
|
||
|
||
=item I<vpc>
|
||
|
||
=item I<vhd>
|
||
|
||
VPC (old) and VHD (modern) are the native disk image format of
|
||
Microsoft (and previously, Connectix) Virtual PC and Hyper-V.
|
||
|
||
=item Obsolete formats
|
||
|
||
The following formats are obsolete and should not be used:
|
||
I<qcow> (aka I<qcow1>), I<cow>, I<bochs>.
|
||
|
||
=back
|
||
|
||
=head3 DETECTING THE FORMAT OF A DISK IMAGE
|
||
|
||
Firstly note there is a security issue with auto-detecting the format
|
||
of a disk image. It may or may not apply in your use case. Read
|
||
L</CVE-2010-3851> below.
|
||
|
||
Libguestfs offers an API to get the format of a disk image
|
||
(L</guestfs_disk_format>), and it is safest to use this.
|
||
|
||
I<Don’t> be tempted to try parsing the text / human-readable output of
|
||
C<qemu-img> since it cannot be parsed reliably and securely. Also do
|
||
not use the C<file> command since the output of that changes over
|
||
time.
|
||
|
||
=head1 CONNECTION MANAGEMENT
|
||
|
||
=head2 guestfs_h *
|
||
|
||
C<guestfs_h> is the opaque type representing a connection handle.
|
||
Create a handle by calling L</guestfs_create> or
|
||
L</guestfs_create_flags>. Call L</guestfs_close> to free the handle
|
||
and release all resources used.
|
||
|
||
For information on using multiple handles and threads, see the section
|
||
L</MULTIPLE HANDLES AND MULTIPLE THREADS> above.
|
||
|
||
=head2 guestfs_create
|
||
|
||
guestfs_h *guestfs_create (void);
|
||
|
||
Create a connection handle.
|
||
|
||
On success this returns a non-NULL pointer to a handle. On error it
|
||
returns NULL.
|
||
|
||
You have to "configure" the handle after creating it. This includes
|
||
calling L</guestfs_add_drive_opts> (or one of the equivalent calls) on
|
||
the handle at least once.
|
||
|
||
After configuring the handle, you have to call L</guestfs_launch>.
|
||
|
||
You may also want to configure error handling for the handle. See the
|
||
L</ERROR HANDLING> section below.
|
||
|
||
=head2 guestfs_create_flags
|
||
|
||
guestfs_h *guestfs_create_flags (unsigned flags [, ...]);
|
||
|
||
Create a connection handle, supplying extra flags and
|
||
extra arguments to control how the handle is created.
|
||
|
||
On success this returns a non-NULL pointer to a handle. On error it
|
||
returns NULL.
|
||
|
||
L</guestfs_create> is equivalent to calling C<guestfs_create_flags(0)>.
|
||
|
||
The following flags may be logically ORed together. (Currently
|
||
no extra arguments are used).
|
||
|
||
=over 4
|
||
|
||
=item C<GUESTFS_CREATE_NO_ENVIRONMENT>
|
||
|
||
Don’t parse any environment variables (such as C<LIBGUESTFS_DEBUG> etc).
|
||
|
||
You can call L</guestfs_parse_environment> or
|
||
L</guestfs_parse_environment_list> afterwards to parse environment
|
||
variables. Alternately, I<don't> call these functions if you want the
|
||
handle to be unaffected by environment variables. See the example below.
|
||
|
||
The default (if this flag is not given) is to implicitly call
|
||
L</guestfs_parse_environment>.
|
||
|
||
=item C<GUESTFS_CREATE_NO_CLOSE_ON_EXIT>
|
||
|
||
Don’t try to close the handle in an L<atexit(3)> handler if the
|
||
program exits without explicitly closing the handle.
|
||
|
||
The default (if this flag is not given) is to install such an atexit
|
||
handler.
|
||
|
||
=back
|
||
|
||
=head3 USING C<GUESTFS_CREATE_NO_ENVIRONMENT>
|
||
|
||
You might use C<GUESTFS_CREATE_NO_ENVIRONMENT> and
|
||
an explicit call to L</guestfs_parse_environment> like this:
|
||
|
||
guestfs_h *g;
|
||
int r;
|
||
|
||
g = guestfs_create_flags (GUESTFS_CREATE_NO_ENVIRONMENT);
|
||
if (!g) {
|
||
perror ("guestfs_create_flags");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
r = guestfs_parse_environment (g);
|
||
if (r == -1)
|
||
exit (EXIT_FAILURE);
|
||
|
||
Or to create a handle which is unaffected by environment variables,
|
||
omit the call to C<guestfs_parse_environment> from the above code.
|
||
|
||
The above code has another advantage which is that any errors from
|
||
parsing the environment are passed through the error handler, whereas
|
||
C<guestfs_create> prints errors on stderr and ignores them.
|
||
|
||
=head2 guestfs_close
|
||
|
||
void guestfs_close (guestfs_h *g);
|
||
|
||
This closes the connection handle and frees up all resources used.
|
||
If a close callback was set on the handle, then it is called.
|
||
|
||
The correct way to close the handle is:
|
||
|
||
if (guestfs_shutdown (g) == -1) {
|
||
/* handle write errors here */
|
||
}
|
||
guestfs_close (g);
|
||
|
||
L</guestfs_shutdown> is only needed if B<all> of the following are true:
|
||
|
||
=over 4
|
||
|
||
=item 1
|
||
|
||
one or more disks were added in read-write mode, I<and>
|
||
|
||
=item 2
|
||
|
||
guestfs_launch was called, I<and>
|
||
|
||
=item 3
|
||
|
||
you made some changes, I<and>
|
||
|
||
=item 4
|
||
|
||
you have a way to handle write errors (eg. by exiting with an
|
||
error code or reporting something to the user).
|
||
|
||
=back
|
||
|
||
=head1 ERROR HANDLING
|
||
|
||
API functions can return errors. For example, almost all functions
|
||
that return C<int> will return C<-1> to indicate an error.
|
||
|
||
Additional information is available for errors: an error message
|
||
string and optionally an error number (errno) if the thing that failed
|
||
was a system call.
|
||
|
||
You can get at the additional information about the last error on the
|
||
handle by calling L</guestfs_last_error>, L</guestfs_last_errno>,
|
||
and/or by setting up an error handler with
|
||
L</guestfs_set_error_handler>.
|
||
|
||
When the handle is created, a default error handler is installed which
|
||
prints the error message string to C<stderr>. For small short-running
|
||
command line programs it is sufficient to do:
|
||
|
||
if (guestfs_launch (g) == -1)
|
||
exit (EXIT_FAILURE);
|
||
|
||
since the default error handler will ensure that an error message has
|
||
been printed to C<stderr> before the program exits.
|
||
|
||
For other programs the caller will almost certainly want to install an
|
||
alternate error handler or do error handling in-line as in the example
|
||
below. The non-C language bindings all install NULL error handlers
|
||
and turn errors into exceptions using code similar to this:
|
||
|
||
const char *msg;
|
||
int errnum;
|
||
|
||
/* This disables the default behaviour of printing errors
|
||
on stderr. */
|
||
guestfs_set_error_handler (g, NULL, NULL);
|
||
|
||
if (guestfs_launch (g) == -1) {
|
||
/* Examine the error message and print it, throw it,
|
||
etc. */
|
||
msg = guestfs_last_error (g);
|
||
errnum = guestfs_last_errno (g);
|
||
|
||
fprintf (stderr, "%s", msg);
|
||
if (errnum != 0)
|
||
fprintf (stderr, ": %s", strerror (errnum));
|
||
fprintf (stderr, "\n");
|
||
|
||
/* ... */
|
||
}
|
||
|
||
L</guestfs_create> returns C<NULL> if the handle cannot be created,
|
||
and because there is no handle if this happens there is no way to get
|
||
additional error information. Since libguestfs E<ge> 1.20, you can
|
||
use L</guestfs_create_flags> to properly deal with errors during
|
||
handle creation, although the vast majority of programs can continue
|
||
to use L</guestfs_create> and not worry about this situation.
|
||
|
||
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 L</guestfs_set_out_of_memory_handler>.
|
||
|
||
=head2 guestfs_last_error
|
||
|
||
const char *guestfs_last_error (guestfs_h *g);
|
||
|
||
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>.
|
||
|
||
Note the returned string does I<not> have a newline character at the
|
||
end. Most error messages are single lines. Some are split over
|
||
multiple lines and contain C<\n> characters within the string but not
|
||
at the end.
|
||
|
||
The lifetime of the returned string is until the next error occurs
|
||
on the same handle, or L</guestfs_close> is called. If you need
|
||
to keep it longer, copy it.
|
||
|
||
=head2 guestfs_last_errno
|
||
|
||
int guestfs_last_errno (guestfs_h *g);
|
||
|
||
This returns the last error number (errno) that happened on C<g>.
|
||
|
||
If successful, an errno integer not equal to zero is returned.
|
||
|
||
In many cases the special errno C<ENOTSUP> is returned if you tried to
|
||
call a function or use a feature which is not supported.
|
||
|
||
If no error number is available, this returns 0. This call can return
|
||
0 in three situations:
|
||
|
||
=over 4
|
||
|
||
=item 1.
|
||
|
||
There has not been any error on the handle.
|
||
|
||
=item 2.
|
||
|
||
There has been an error but the errno was meaningless. This
|
||
corresponds to the case where the error did not come from a
|
||
failed system call, but for some other reason.
|
||
|
||
=item 3.
|
||
|
||
There was an error from a failed system call, but for some
|
||
reason the errno was not captured and returned. This usually
|
||
indicates a bug in libguestfs.
|
||
|
||
=back
|
||
|
||
Libguestfs tries to convert the errno from inside the appliance into
|
||
a corresponding errno for the caller (not entirely trivial: the
|
||
appliance might be running a completely different operating system
|
||
from the library and error numbers are not standardized across
|
||
Un*xen). If this could not be done, then the error is translated to
|
||
C<EINVAL>. In practice this should only happen in very rare
|
||
circumstances.
|
||
|
||
=head2 guestfs_set_error_handler
|
||
|
||
typedef void (*guestfs_error_handler_cb) (guestfs_h *g,
|
||
void *opaque,
|
||
const char *msg);
|
||
void guestfs_set_error_handler (guestfs_h *g,
|
||
guestfs_error_handler_cb cb,
|
||
void *opaque);
|
||
|
||
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.
|
||
|
||
C<errno> is not passed to the callback. To get that the callback must
|
||
call L</guestfs_last_errno>.
|
||
|
||
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 *g,
|
||
void **opaque_rtn);
|
||
|
||
Returns the current error handler callback.
|
||
|
||
=head2 guestfs_push_error_handler
|
||
|
||
void guestfs_push_error_handler (guestfs_h *g,
|
||
guestfs_error_handler_cb cb,
|
||
void *opaque);
|
||
|
||
This is the same as L</guestfs_set_error_handler>, except that the old
|
||
error handler is stashed away in a stack inside the handle. You can
|
||
restore the previous error handler by calling
|
||
L</guestfs_pop_error_handler>.
|
||
|
||
Use the following code to temporarily disable errors around a function:
|
||
|
||
guestfs_push_error_handler (g, NULL, NULL);
|
||
guestfs_mkdir (g, "/foo"); /* We don't care if this fails. */
|
||
guestfs_pop_error_handler (g);
|
||
|
||
=head2 guestfs_pop_error_handler
|
||
|
||
void guestfs_pop_error_handler (guestfs_h *g);
|
||
|
||
Restore the previous error handler (see L</guestfs_push_error_handler>).
|
||
|
||
If you pop the stack too many times, then the default error handler is
|
||
restored.
|
||
|
||
=head2 guestfs_set_out_of_memory_handler
|
||
|
||
typedef void (*guestfs_abort_cb) (void);
|
||
void 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
|
||
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 *g);
|
||
|
||
This returns the current out of memory handler.
|
||
|
||
=head1 API CALLS
|
||
|
||
__ACTIONS__
|
||
|
||
=head1 STRUCTURES
|
||
|
||
__STRUCTS__
|
||
|
||
=head1 AVAILABILITY
|
||
|
||
=head2 GROUPS OF FUNCTIONALITY IN THE APPLIANCE
|
||
|
||
Using L</guestfs_available> you can test availability of
|
||
the following groups of functions. This test queries the
|
||
appliance to see if the appliance you are currently using
|
||
supports the functionality.
|
||
|
||
__AVAILABILITY__
|
||
|
||
=head2 FILESYSTEM AVAILABLE
|
||
|
||
The L</guestfs_filesystem_available> call tests whether a
|
||
filesystem type is supported by the appliance kernel.
|
||
|
||
This is mainly useful as a negative test. If this returns true,
|
||
it doesn't mean that a particular filesystem can be mounted,
|
||
since filesystems can fail for other reasons such as it being
|
||
a later version of the filesystem, or having incompatible features.
|
||
|
||
=head2 GUESTFISH supported COMMAND
|
||
|
||
In L<guestfish(3)> there is a handy interactive command
|
||
C<supported> which prints out the available groups and
|
||
whether they are supported by this build of libguestfs.
|
||
Note however that you have to do C<run> first.
|
||
|
||
=head2 SINGLE CALLS AT COMPILE TIME
|
||
|
||
Since version 1.5.8, C<E<lt>guestfs.hE<gt>> defines symbols
|
||
for each C API function, such as:
|
||
|
||
#define GUESTFS_HAVE_DD 1
|
||
|
||
if L</guestfs_dd> is available.
|
||
|
||
Before version 1.5.8, if you needed to test whether a single
|
||
libguestfs function is available at compile time, we recommended 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 <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <unistd.h>
|
||
#include <dlfcn.h>
|
||
#include <guestfs.h>
|
||
|
||
main ()
|
||
{
|
||
#ifdef GUESTFS_HAVE_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 (EXIT_FAILURE);
|
||
}
|
||
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
|
||
|
||
=head1 CALLS WITH OPTIONAL ARGUMENTS
|
||
|
||
A recent feature of the API is the introduction of calls which take
|
||
optional arguments. In C these are declared 3 ways. The main way is
|
||
as a call which takes variable arguments (ie. C<...>), as in this
|
||
example:
|
||
|
||
int guestfs_add_drive_opts (guestfs_h *g, const char *filename, ...);
|
||
|
||
Call this with a list of optional arguments, terminated by C<-1>.
|
||
So to call with no optional arguments specified:
|
||
|
||
guestfs_add_drive_opts (g, filename, -1);
|
||
|
||
With a single optional argument:
|
||
|
||
guestfs_add_drive_opts (g, filename,
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "qcow2",
|
||
-1);
|
||
|
||
With two:
|
||
|
||
guestfs_add_drive_opts (g, filename,
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "qcow2",
|
||
GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
|
||
-1);
|
||
|
||
and so forth. Don’t forget the terminating C<-1> otherwise
|
||
Bad Things will happen!
|
||
|
||
=head2 USING va_list FOR OPTIONAL ARGUMENTS
|
||
|
||
The second variant has the same name with the suffix C<_va>, which
|
||
works the same way but takes a C<va_list>. See the C manual for
|
||
details. For the example function, this is declared:
|
||
|
||
int guestfs_add_drive_opts_va (guestfs_h *g, const char *filename,
|
||
va_list args);
|
||
|
||
=head2 CONSTRUCTING OPTIONAL ARGUMENTS
|
||
|
||
The third variant is useful where you need to construct these
|
||
calls. You pass in a structure where you fill in the optional
|
||
fields. The structure has a bitmask as the first element which
|
||
you must set to indicate which fields you have filled in. For
|
||
our example function the structure and call are declared:
|
||
|
||
struct guestfs_add_drive_opts_argv {
|
||
uint64_t bitmask;
|
||
int readonly;
|
||
const char *format;
|
||
/* ... */
|
||
};
|
||
int guestfs_add_drive_opts_argv (guestfs_h *g, const char *filename,
|
||
const struct guestfs_add_drive_opts_argv *optargs);
|
||
|
||
You could call it like this:
|
||
|
||
struct guestfs_add_drive_opts_argv optargs = {
|
||
.bitmask = GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK |
|
||
GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK,
|
||
.readonly = 1,
|
||
.format = "qcow2"
|
||
};
|
||
|
||
guestfs_add_drive_opts_argv (g, filename, &optargs);
|
||
|
||
Notes:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
The C<_BITMASK> suffix on each option name when specifying the
|
||
bitmask.
|
||
|
||
=item *
|
||
|
||
You do not need to fill in all fields of the structure.
|
||
|
||
=item *
|
||
|
||
There must be a one-to-one correspondence between fields of the
|
||
structure that are filled in, and bits set in the bitmask.
|
||
|
||
=back
|
||
|
||
=head2 OPTIONAL ARGUMENTS IN OTHER LANGUAGES
|
||
|
||
In other languages, optional arguments are expressed in the
|
||
way that is natural for that language. We refer you to the
|
||
language-specific documentation for more details on that.
|
||
|
||
For guestfish, see L<guestfish(1)/OPTIONAL ARGUMENTS>.
|
||
|
||
=head1 EVENTS
|
||
|
||
=head2 SETTING CALLBACKS TO HANDLE EVENTS
|
||
|
||
B<Note:> This section documents the generic event mechanism introduced
|
||
in libguestfs 1.10, which you should use in new code if possible. The
|
||
old functions C<guestfs_set_log_message_callback>,
|
||
C<guestfs_set_subprocess_quit_callback>,
|
||
C<guestfs_set_launch_done_callback>, C<guestfs_set_close_callback> and
|
||
C<guestfs_set_progress_callback> are no longer documented in this
|
||
manual page. Because of the ABI guarantee, the old functions continue
|
||
to work.
|
||
|
||
Handles generate events when certain things happen, such as log
|
||
messages being generated, progress messages during long-running
|
||
operations, or the handle being closed. The API calls described below
|
||
let you register a callback to be called when events happen. You can
|
||
register multiple callbacks (for the same, different or overlapping
|
||
sets of events), and individually remove callbacks. If callbacks are
|
||
not removed, then they remain in force until the handle is closed.
|
||
|
||
In the current implementation, events are only generated
|
||
synchronously: that means that events (and hence callbacks) can only
|
||
happen while you are in the middle of making another libguestfs call.
|
||
The callback is called in the same thread.
|
||
|
||
Events may contain a payload, usually nothing (void), an array of 64
|
||
bit unsigned integers, or a message buffer. Payloads are discussed
|
||
later on.
|
||
|
||
=head2 CLASSES OF EVENTS
|
||
|
||
=over 4
|
||
|
||
=item GUESTFS_EVENT_CLOSE
|
||
(payload type: void)
|
||
|
||
The callback function will be called while the handle is being closed
|
||
(synchronously from L</guestfs_close>).
|
||
|
||
Note that libguestfs installs an L<atexit(3)> handler to try to clean
|
||
up handles that are open when the program exits. This means that this
|
||
callback might be called indirectly from L<exit(3)>, which can cause
|
||
unexpected problems in higher-level languages (eg. if your HLL
|
||
interpreter has already been cleaned up by the time this is called,
|
||
and if your callback then jumps into some HLL function).
|
||
|
||
If no callback is registered: the handle is closed without any
|
||
callback being invoked.
|
||
|
||
=item GUESTFS_EVENT_SUBPROCESS_QUIT
|
||
(payload type: void)
|
||
|
||
The callback function will be called when the child process quits,
|
||
either asynchronously or if killed by L</guestfs_kill_subprocess>.
|
||
(This corresponds to a transition from any state to the CONFIG state).
|
||
|
||
If no callback is registered: the event is ignored.
|
||
|
||
=item GUESTFS_EVENT_LAUNCH_DONE
|
||
(payload type: void)
|
||
|
||
The callback function 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).
|
||
|
||
If no callback is registered: the event is ignored.
|
||
|
||
=item GUESTFS_EVENT_PROGRESS
|
||
(payload type: array of 4 x uint64_t)
|
||
|
||
Some long-running operations can generate progress messages. If
|
||
this callback is registered, then it will be called each time a
|
||
progress message is generated (usually two seconds after the
|
||
operation started, and three times per second thereafter until
|
||
it completes, although the frequency may change in future versions).
|
||
|
||
The callback receives in the payload four unsigned 64 bit numbers
|
||
which are (in order): C<proc_nr>, C<serial>, C<position>, C<total>.
|
||
|
||
The units of C<total> are not defined, although for some
|
||
operations C<total> may relate in some way to the amount of
|
||
data to be transferred (eg. in bytes or megabytes), and
|
||
C<position> may be the portion which has been transferred.
|
||
|
||
The only defined and stable parts of the API are:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
The callback can display to the user some type of progress bar or
|
||
indicator which shows the ratio of C<position>:C<total>.
|
||
|
||
=item *
|
||
|
||
0 E<lt>= C<position> E<lt>= C<total>
|
||
|
||
=item *
|
||
|
||
If any progress notification is sent during a call, then a final
|
||
progress notification is always sent when C<position> = C<total>
|
||
(I<unless> the call fails with an error).
|
||
|
||
This is to simplify caller code, so callers can easily set the
|
||
progress indicator to "100%" at the end of the operation, without
|
||
requiring special code to detect this case.
|
||
|
||
=item *
|
||
|
||
For some calls we are unable to estimate the progress of the call, but
|
||
we can still generate progress messages to indicate activity. This is
|
||
known as "pulse mode", and is directly supported by certain progress
|
||
bar implementations (eg. GtkProgressBar).
|
||
|
||
For these calls, zero or more progress messages are generated with
|
||
C<position = 0> and C<total = 1>, followed by a final message with
|
||
C<position = total = 1>.
|
||
|
||
As noted above, if the call fails with an error then the final message
|
||
may not be generated.
|
||
|
||
=back
|
||
|
||
The callback also receives the procedure number (C<proc_nr>) and
|
||
serial number (C<serial>) of the call. These are only useful for
|
||
debugging protocol issues, and the callback can normally ignore them.
|
||
The callback may want to print these numbers in error messages or
|
||
debugging messages.
|
||
|
||
If no callback is registered: progress messages are discarded.
|
||
|
||
=item GUESTFS_EVENT_APPLIANCE
|
||
(payload type: message buffer)
|
||
|
||
The callback function is called whenever a log message is generated by
|
||
qemu, the appliance kernel, guestfsd (daemon), or utility programs.
|
||
|
||
If the verbose flag (L</guestfs_set_verbose>) is set before launch
|
||
(L</guestfs_launch>) then additional debug messages are generated.
|
||
|
||
If no callback is registered: the messages are discarded unless the
|
||
verbose flag is set in which case they are sent to stderr. You can
|
||
override the printing of verbose messages to stderr by setting up a
|
||
callback.
|
||
|
||
=item GUESTFS_EVENT_LIBRARY
|
||
(payload type: message buffer)
|
||
|
||
The callback function is called whenever a log message is generated by
|
||
the library part of libguestfs.
|
||
|
||
If the verbose flag (L</guestfs_set_verbose>) is set then additional
|
||
debug messages are generated.
|
||
|
||
If no callback is registered: the messages are discarded unless the
|
||
verbose flag is set in which case they are sent to stderr. You can
|
||
override the printing of verbose messages to stderr by setting up a
|
||
callback.
|
||
|
||
=item GUESTFS_EVENT_WARNING
|
||
(payload type: message buffer)
|
||
|
||
The callback function is called whenever a warning message is
|
||
generated by the library part of libguestfs.
|
||
|
||
If no callback is registered: the messages are printed to stderr. You
|
||
can override the printing of warning messages to stderr by setting up
|
||
a callback.
|
||
|
||
=item GUESTFS_EVENT_TRACE
|
||
(payload type: message buffer)
|
||
|
||
The callback function is called whenever a trace message is generated.
|
||
This only applies if the trace flag (L</guestfs_set_trace>) is set.
|
||
|
||
If no callback is registered: the messages are sent to stderr. You
|
||
can override the printing of trace messages to stderr by setting up a
|
||
callback.
|
||
|
||
=item GUESTFS_EVENT_ENTER
|
||
(payload type: function name)
|
||
|
||
The callback function is called whenever a libguestfs function
|
||
is entered.
|
||
|
||
The payload is a string which contains the name of the function
|
||
that we are entering (not including C<guestfs_> prefix).
|
||
|
||
Note that libguestfs functions can call themselves, so you may
|
||
see many events from a single call. A few libguestfs functions
|
||
do not generate this event.
|
||
|
||
If no callback is registered: the event is ignored.
|
||
|
||
=item GUESTFS_EVENT_LIBVIRT_AUTH
|
||
(payload type: libvirt URI)
|
||
|
||
For any API function that opens a libvirt connection, this
|
||
event may be generated to indicate that libvirt demands
|
||
authentication information. See L</LIBVIRT AUTHENTICATION> below.
|
||
|
||
If no callback is registered: C<virConnectAuthPtrDefault> is
|
||
used (suitable for command-line programs only).
|
||
|
||
=back
|
||
|
||
=head2 EVENT API
|
||
|
||
=head3 guestfs_set_event_callback
|
||
|
||
int guestfs_set_event_callback (guestfs_h *g,
|
||
guestfs_event_callback cb,
|
||
uint64_t event_bitmask,
|
||
int flags,
|
||
void *opaque);
|
||
|
||
This function registers a callback (C<cb>) for all event classes
|
||
in the C<event_bitmask>.
|
||
|
||
For example, to register for all log message events, you could call
|
||
this function with the bitmask
|
||
C<GUESTFS_EVENT_APPLIANCE|GUESTFS_EVENT_LIBRARY|GUESTFS_EVENT_WARNING>.
|
||
To register a single callback for all possible classes of events, use
|
||
C<GUESTFS_EVENT_ALL>.
|
||
|
||
C<flags> should always be passed as 0.
|
||
|
||
C<opaque> is an opaque pointer which is passed to the callback. You
|
||
can use it for any purpose.
|
||
|
||
The return value is the event handle (an integer) which you can use to
|
||
delete the callback (see below).
|
||
|
||
If there is an error, this function returns C<-1>, and sets the error
|
||
in the handle in the usual way (see L</guestfs_last_error> etc.)
|
||
|
||
Callbacks remain in effect until they are deleted, or until the handle
|
||
is closed.
|
||
|
||
In the case where multiple callbacks are registered for a particular
|
||
event class, all of the callbacks are called. The order in which
|
||
multiple callbacks are called is not defined.
|
||
|
||
=head3 guestfs_delete_event_callback
|
||
|
||
void guestfs_delete_event_callback (guestfs_h *g, int event_handle);
|
||
|
||
Delete a callback that was previously registered. C<event_handle>
|
||
should be the integer that was returned by a previous call to
|
||
C<guestfs_set_event_callback> on the same handle.
|
||
|
||
=head3 guestfs_event_to_string
|
||
|
||
char *guestfs_event_to_string (uint64_t event);
|
||
|
||
C<event> is either a single event or a bitmask of events. This
|
||
returns a string representation (useful for debugging or printing
|
||
events).
|
||
|
||
A single event is returned as the name in lower case, eg. C<"close">.
|
||
|
||
A bitmask of several events is returned as a comma-separated list,
|
||
eg. C<"close,progress">.
|
||
|
||
If zero is passed, then the empty string C<""> is returned.
|
||
|
||
On success this returns a string. On error it returns NULL and sets
|
||
C<errno>.
|
||
|
||
The returned string must be freed by the caller.
|
||
|
||
=head3 guestfs_event_callback
|
||
|
||
typedef void (*guestfs_event_callback) (
|
||
guestfs_h *g,
|
||
void *opaque,
|
||
uint64_t event,
|
||
int event_handle,
|
||
int flags,
|
||
const char *buf, size_t buf_len,
|
||
const uint64_t *array, size_t array_len);
|
||
|
||
This is the type of the event callback function that you have to
|
||
provide.
|
||
|
||
The basic parameters are: the handle (C<g>), the opaque user pointer
|
||
(C<opaque>), the event class (eg. C<GUESTFS_EVENT_PROGRESS>), the
|
||
event handle, and C<flags> which in the current API you should ignore.
|
||
|
||
The remaining parameters contain the event payload (if any). Each
|
||
event may contain a payload, which usually relates to the event class,
|
||
but for future proofing your code should be written to handle any
|
||
payload for any event class.
|
||
|
||
C<buf> and C<buf_len> contain a message buffer (if C<buf_len == 0>,
|
||
then there is no message buffer). Note that this message buffer can
|
||
contain arbitrary 8 bit data, including NUL bytes.
|
||
|
||
C<array> and C<array_len> is an array of 64 bit unsigned integers. At
|
||
the moment this is only used for progress messages.
|
||
|
||
=head2 EXAMPLE: CAPTURING LOG MESSAGES
|
||
|
||
A working program demonstrating this can be found in
|
||
F<examples/debug-logging.c> in the source of libguestfs.
|
||
|
||
One motivation for the generic event API was to allow GUI programs to
|
||
capture debug and other messages. In libguestfs E<le> 1.8 these were
|
||
sent unconditionally to C<stderr>.
|
||
|
||
Events associated with log messages are: C<GUESTFS_EVENT_LIBRARY>,
|
||
C<GUESTFS_EVENT_APPLIANCE>, C<GUESTFS_EVENT_WARNING> and
|
||
C<GUESTFS_EVENT_TRACE>. (Note that error messages are not events; you
|
||
must capture error messages separately).
|
||
|
||
Programs have to set up a callback to capture the classes of events of
|
||
interest:
|
||
|
||
int eh =
|
||
guestfs_set_event_callback
|
||
(g, message_callback,
|
||
GUESTFS_EVENT_LIBRARY | GUESTFS_EVENT_APPLIANCE |
|
||
GUESTFS_EVENT_WARNING | GUESTFS_EVENT_TRACE,
|
||
0, NULL) == -1)
|
||
if (eh == -1) {
|
||
// handle error in the usual way
|
||
}
|
||
|
||
The callback can then direct messages to the appropriate place. In
|
||
this example, messages are directed to syslog:
|
||
|
||
static void
|
||
message_callback (
|
||
guestfs_h *g,
|
||
void *opaque,
|
||
uint64_t event,
|
||
int event_handle,
|
||
int flags,
|
||
const char *buf, size_t buf_len,
|
||
const uint64_t *array, size_t array_len)
|
||
{
|
||
const int priority = LOG_USER|LOG_INFO;
|
||
if (buf_len > 0)
|
||
syslog (priority, "event 0x%lx: %s", event, buf);
|
||
}
|
||
|
||
=head2 LIBVIRT AUTHENTICATION
|
||
|
||
Some libguestfs API calls can open libvirt connections. Currently the
|
||
only ones are L</guestfs_add_domain>; and L</guestfs_launch> if the
|
||
libvirt backend has been selected. Libvirt connections may require
|
||
authentication, for example if they need to access a remote server or
|
||
to access root services from non-root. Libvirt authentication happens
|
||
via a callback mechanism, see
|
||
L<http://libvirt.org/guide/html/Application_Development_Guide-Connections.html>
|
||
|
||
You may provide libvirt authentication data by registering a callback
|
||
for events of type C<GUESTFS_EVENT_LIBVIRT_AUTH>.
|
||
|
||
If no such event is registered, then libguestfs uses a libvirt
|
||
function that provides command-line prompts
|
||
(C<virConnectAuthPtrDefault>). This is only suitable for command-line
|
||
libguestfs programs.
|
||
|
||
To provide authentication, first call
|
||
L</guestfs_set_libvirt_supported_credentials> with the list of
|
||
credentials your program knows how to provide. Second, register a
|
||
callback for the C<GUESTFS_EVENT_LIBVIRT_AUTH> event. The event
|
||
handler will be called when libvirt is requesting authentication
|
||
information.
|
||
|
||
In the event handler, call
|
||
L</guestfs_get_libvirt_requested_credentials> to get a list of the
|
||
credentials that libvirt is asking for. You then need to ask (eg. the
|
||
user) for each credential, and call
|
||
L</guestfs_set_libvirt_requested_credential> with the answer. Note
|
||
that for each credential, additional information may be available
|
||
via the calls
|
||
L</guestfs_get_libvirt_requested_credential_prompt>,
|
||
L</guestfs_get_libvirt_requested_credential_challenge> or
|
||
L</guestfs_get_libvirt_requested_credential_defresult>.
|
||
|
||
The example program below should make this clearer.
|
||
|
||
There is also a more substantial working example program supplied with
|
||
the libguestfs sources, called F<libvirt-auth.c>.
|
||
|
||
main ()
|
||
{
|
||
guestfs_h *g;
|
||
char *creds[] = { "authname", "passphrase", NULL };
|
||
int r, eh;
|
||
|
||
g = guestfs_create ();
|
||
if (!g) exit (EXIT_FAILURE);
|
||
|
||
/* Tell libvirt what credentials the program supports. */
|
||
r = guestfs_set_libvirt_supported_credentials (g, creds);
|
||
if (r == -1)
|
||
exit (EXIT_FAILURE);
|
||
|
||
/* Set up the event handler. */
|
||
eh = guestfs_set_event_callback (
|
||
g, do_auth,
|
||
GUESTFS_EVENT_LIBVIRT_AUTH, 0, NULL);
|
||
if (eh == -1)
|
||
exit (EXIT_FAILURE);
|
||
|
||
/* An example of a call that may ask for credentials. */
|
||
r = guestfs_add_domain (
|
||
g, "dom",
|
||
GUESTFS_ADD_DOMAIN_LIBVIRTURI, "qemu:///system",
|
||
-1);
|
||
if (r == -1)
|
||
exit (EXIT_FAILURE);
|
||
|
||
exit (EXIT_SUCCESS);
|
||
}
|
||
|
||
static void
|
||
do_auth (guestfs_h *g,
|
||
void *opaque,
|
||
uint64_t event,
|
||
int event_handle,
|
||
int flags,
|
||
const char *buf, size_t buf_len,
|
||
const uint64_t *array, size_t array_len)
|
||
{
|
||
char **creds;
|
||
size_t i;
|
||
char *prompt;
|
||
char *reply;
|
||
size_t replylen;
|
||
int r;
|
||
|
||
// buf will be the libvirt URI. buf_len may be ignored.
|
||
printf ("Authentication required for libvirt conn '%s'\n",
|
||
buf);
|
||
|
||
// Ask libguestfs what credentials libvirt is demanding.
|
||
creds = guestfs_get_libvirt_requested_credentials (g);
|
||
if (creds == NULL)
|
||
exit (EXIT_FAILURE);
|
||
|
||
// Now ask the user for answers.
|
||
for (i = 0; creds[i] != NULL; ++i)
|
||
{
|
||
if (strcmp (creds[i], "authname") == 0 ||
|
||
strcmp (creds[i], "passphrase") == 0)
|
||
{
|
||
prompt =
|
||
guestfs_get_libvirt_requested_credential_prompt (g, i);
|
||
if (prompt && strcmp (prompt, "") != 0)
|
||
printf ("%s: ", prompt);
|
||
free (prompt);
|
||
|
||
// Some code here to ask for the credential.
|
||
// ...
|
||
// Put the reply in 'reply', length 'replylen' (bytes).
|
||
|
||
r = guestfs_set_libvirt_requested_credential (g, i,
|
||
reply, replylen);
|
||
if (r == -1)
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
|
||
free (creds[i]);
|
||
}
|
||
|
||
free (creds);
|
||
}
|
||
|
||
=head1 CANCELLING LONG TRANSFERS
|
||
|
||
Some operations can be cancelled by the caller while they are in
|
||
progress. Currently only operations that involve uploading or
|
||
downloading data can be cancelled (technically: operations that have
|
||
C<FileIn> or C<FileOut> parameters in the generator).
|
||
|
||
To cancel the transfer, call L</guestfs_user_cancel>. For more
|
||
information, read the description of L</guestfs_user_cancel>.
|
||
|
||
=head1 PRIVATE DATA AREA
|
||
|
||
You can attach named pieces of private data to the libguestfs handle,
|
||
fetch them by name, and walk over them, for the lifetime of the
|
||
handle. This is called the private data area and is only available
|
||
from the C API.
|
||
|
||
To attach a named piece of data, use the following call:
|
||
|
||
void guestfs_set_private (guestfs_h *g, const char *key, void *data);
|
||
|
||
C<key> is the name to associate with this data, and C<data> is an
|
||
arbitrary pointer (which can be C<NULL>). Any previous item with the
|
||
same key is overwritten.
|
||
|
||
You can use any C<key> string you want, but avoid keys beginning with
|
||
an underscore character (libguestfs uses those for its own internal
|
||
purposes, such as implementing language bindings). It is recommended
|
||
that you prefix the key with some unique string to avoid collisions
|
||
with other users.
|
||
|
||
To retrieve the pointer, use:
|
||
|
||
void *guestfs_get_private (guestfs_h *g, const char *key);
|
||
|
||
This function returns C<NULL> if either no data is found associated
|
||
with C<key>, or if the user previously set the C<key>’s C<data>
|
||
pointer to C<NULL>.
|
||
|
||
Libguestfs does not try to look at or interpret the C<data> pointer in
|
||
any way. As far as libguestfs is concerned, it need not be a valid
|
||
pointer at all. In particular, libguestfs does I<not> try to free the
|
||
data when the handle is closed. If the data must be freed, then the
|
||
caller must either free it before calling L</guestfs_close> or must
|
||
set up a close callback to do it (see L</GUESTFS_EVENT_CLOSE>).
|
||
|
||
To walk over all entries, use these two functions:
|
||
|
||
void *guestfs_first_private (guestfs_h *g, const char **key_rtn);
|
||
|
||
void *guestfs_next_private (guestfs_h *g, const char **key_rtn);
|
||
|
||
C<guestfs_first_private> returns the first key, pointer pair ("first"
|
||
does not have any particular meaning -- keys are not returned in any
|
||
defined order). A pointer to the key is returned in C<*key_rtn> and
|
||
the corresponding data pointer is returned from the function. C<NULL>
|
||
is returned if there are no keys stored in the handle.
|
||
|
||
C<guestfs_next_private> returns the next key, pointer pair. The
|
||
return value of this function is C<NULL> if there are no further
|
||
entries to return.
|
||
|
||
Notes about walking over entries:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
You must not call C<guestfs_set_private> while walking over the
|
||
entries.
|
||
|
||
=item *
|
||
|
||
The handle maintains an internal iterator which is reset when you call
|
||
C<guestfs_first_private>. This internal iterator is invalidated when
|
||
you call C<guestfs_set_private>.
|
||
|
||
=item *
|
||
|
||
If you have set the data pointer associated with a key to C<NULL>, ie:
|
||
|
||
guestfs_set_private (g, key, NULL);
|
||
|
||
then that C<key> is not returned when walking.
|
||
|
||
=item *
|
||
|
||
C<*key_rtn> is only valid until the next call to
|
||
C<guestfs_first_private>, C<guestfs_next_private> or
|
||
C<guestfs_set_private>.
|
||
|
||
=back
|
||
|
||
The following example code shows how to print all keys and data
|
||
pointers that are associated with the handle C<g>:
|
||
|
||
const char *key;
|
||
void *data = guestfs_first_private (g, &key);
|
||
while (data != NULL)
|
||
{
|
||
printf ("key = %s, data = %p\n", key, data);
|
||
data = guestfs_next_private (g, &key);
|
||
}
|
||
|
||
More commonly you are only interested in keys that begin with an
|
||
application-specific prefix C<foo_>. Modify the loop like so:
|
||
|
||
const char *key;
|
||
void *data = guestfs_first_private (g, &key);
|
||
while (data != NULL)
|
||
{
|
||
if (strncmp (key, "foo_", strlen ("foo_")) == 0)
|
||
printf ("key = %s, data = %p\n", key, data);
|
||
data = guestfs_next_private (g, &key);
|
||
}
|
||
|
||
If you need to modify keys while walking, then you have to jump back
|
||
to the beginning of the loop. For example, to delete all keys
|
||
prefixed with C<foo_>:
|
||
|
||
const char *key;
|
||
void *data;
|
||
again:
|
||
data = guestfs_first_private (g, &key);
|
||
while (data != NULL)
|
||
{
|
||
if (strncmp (key, "foo_", strlen ("foo_")) == 0)
|
||
{
|
||
guestfs_set_private (g, key, NULL);
|
||
/* note that 'key' pointer is now invalid, and so is
|
||
the internal iterator */
|
||
goto again;
|
||
}
|
||
data = guestfs_next_private (g, &key);
|
||
}
|
||
|
||
Note that the above loop is guaranteed to terminate because the keys
|
||
are being deleted, but other manipulations of keys within the loop
|
||
might not terminate unless you also maintain an indication of which
|
||
keys have been visited.
|
||
|
||
=head1 LIBGUESTFS VERSION NUMBERS
|
||
|
||
Since April 2010, libguestfs has started to make separate development
|
||
and stable releases, along with corresponding branches in our git
|
||
repository. These separate releases can be identified by version
|
||
number:
|
||
|
||
even numbers for stable: 1.2.x, 1.4.x, ...
|
||
.-------- odd numbers for development: 1.3.x, 1.5.x, ...
|
||
|
|
||
v
|
||
1 . 3 . 5
|
||
^ ^
|
||
| |
|
||
| `-------- sub-version
|
||
|
|
||
`------ always '1' because we don't change the ABI
|
||
|
||
Thus "1.3.5" is the 5th update to the development branch "1.3".
|
||
|
||
As time passes we cherry pick fixes from the development branch and
|
||
backport those into the stable branch, the effect being that the
|
||
stable branch should get more stable and less buggy over time. So the
|
||
stable releases are ideal for people who don't need new features but
|
||
would just like the software to work.
|
||
|
||
Our criteria for backporting changes are:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
Documentation changes which don’t affect any code are
|
||
backported unless the documentation refers to a future feature
|
||
which is not in stable.
|
||
|
||
=item *
|
||
|
||
Bug fixes which are not controversial, fix obvious problems, and
|
||
have been well tested are backported.
|
||
|
||
=item *
|
||
|
||
Simple rearrangements of code which shouldn't affect how it works get
|
||
backported. This is so that the code in the two branches doesn't get
|
||
too far out of step, allowing us to backport future fixes more easily.
|
||
|
||
=item *
|
||
|
||
We I<don’t> backport new features, new APIs, new tools etc, except in
|
||
one exceptional case: the new feature is required in order to
|
||
implement an important bug fix.
|
||
|
||
=back
|
||
|
||
A new stable branch starts when we think the new features in
|
||
development are substantial and compelling enough over the current
|
||
stable branch to warrant it. When that happens we create new stable
|
||
and development versions 1.N.0 and 1.(N+1).0 [N is even]. The new
|
||
dot-oh release won't necessarily be so stable at this point, but by
|
||
backporting fixes from development, that branch will stabilize over
|
||
time.
|
||
|
||
=head1 LIMITS
|
||
|
||
=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<guestfs-internals(1)>
|
||
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.
|
||
|
||
In libguestfs E<lt> 1.19.32, several calls had to encode either their
|
||
entire argument list or their entire return value (or sometimes both)
|
||
in a single protocol message, and this gave them an arbitrary
|
||
limitation on how much data they could handle. For example,
|
||
L</guestfs_cat> could only download a file if it was less than around
|
||
4 MB in size. In later versions of libguestfs, some of these limits
|
||
have been removed. The APIs which were previously limited but are now
|
||
unlimited (except perhaps by available memory) are listed below. To
|
||
find out if a specific API is subject to protocol limits, check for
|
||
the warning in the API documentation which links to this section, and
|
||
remember to check the version of the documentation that matches the
|
||
version of libguestfs you are using.
|
||
|
||
L</guestfs_cat>, L</guestfs_find>, L</guestfs_read_file>,
|
||
L</guestfs_read_lines>, L</guestfs_write>, L</guestfs_write_append>,
|
||
L</guestfs_lstatlist>, L</guestfs_lxattrlist>,
|
||
L</guestfs_readlinklist>, L</guestfs_ls>.
|
||
|
||
See also L</UPLOADING> and L</DOWNLOADING> for further information
|
||
about copying large amounts of data into or out of a filesystem.
|
||
|
||
=head2 MAXIMUM NUMBER OF DISKS
|
||
|
||
In libguestfs E<ge> 1.19.7, you can query the maximum number of disks
|
||
that may be added by calling L</guestfs_max_disks>. In earlier
|
||
versions of libguestfs (ie. where this call is not available) you
|
||
should assume the maximum is 25.
|
||
|
||
The rest of this section covers implementation details, which could
|
||
change in future.
|
||
|
||
When using virtio-scsi disks (the default if available in qemu) the
|
||
current limit is B<255> disks. When using virtio-blk (the old
|
||
default) the limit is around B<27> disks, but may vary according to
|
||
implementation details and whether the network is enabled.
|
||
|
||
Virtio-scsi as used by libguestfs is configured to use one target per
|
||
disk, and 256 targets are available.
|
||
|
||
Virtio-blk consumes 1 virtual PCI slot per disk, and PCI is limited
|
||
to 31 slots, but some of these are used for other purposes.
|
||
|
||
One virtual disk is used by libguestfs internally.
|
||
|
||
Before libguestfs 1.19.7, disk names had to be a single character
|
||
(eg. F</dev/sda> through F</dev/sdz>), and since one disk is reserved,
|
||
that meant the limit was 25. This has been fixed in more recent
|
||
versions.
|
||
|
||
=head2 MAXIMUM NUMBER OF PARTITIONS PER DISK
|
||
|
||
Virtio limits the maximum number of partitions per disk to B<15>.
|
||
|
||
This is because it reserves 4 bits for the minor device number (thus
|
||
F</dev/vda>, and F</dev/vda1> through F</dev/vda15>).
|
||
|
||
If you attach a disk with more than 15 partitions, the extra
|
||
partitions are ignored by libguestfs.
|
||
|
||
=head2 MAXIMUM SIZE OF A DISK
|
||
|
||
Probably the limit is between 2**63-1 and 2**64-1 bytes.
|
||
|
||
We have tested block devices up to 1 exabyte (2**60 or
|
||
1,152,921,504,606,846,976 bytes) using sparse files backed by an XFS
|
||
host filesystem.
|
||
|
||
Although libguestfs probably does not impose any limit, the underlying
|
||
host storage will. If you store disk images on a host ext4
|
||
filesystem, then the maximum size will be limited by the maximum ext4
|
||
file size (currently 16 TB). If you store disk images as host logical
|
||
volumes then you are limited by the maximum size of an LV.
|
||
|
||
For the hugest disk image files, we recommend using XFS on the host
|
||
for storage.
|
||
|
||
=head2 MAXIMUM SIZE OF A PARTITION
|
||
|
||
The MBR (ie. classic MS-DOS) partitioning scheme uses 32 bit sector
|
||
numbers. Assuming a 512 byte sector size, this means that MBR cannot
|
||
address a partition located beyond 2 TB on the disk.
|
||
|
||
It is recommended that you use GPT partitions on disks which are
|
||
larger than this size. GPT uses 64 bit sector numbers and so can
|
||
address partitions which are theoretically larger than the largest
|
||
disk we could support.
|
||
|
||
=head2 MAXIMUM SIZE OF A FILESYSTEM, FILES, DIRECTORIES
|
||
|
||
This depends on the filesystem type. libguestfs itself does not
|
||
impose any known limit. Consult Wikipedia or the filesystem
|
||
documentation to find out what these limits are.
|
||
|
||
=head2 MAXIMUM UPLOAD AND DOWNLOAD
|
||
|
||
The API functions L</guestfs_upload>, L</guestfs_download>,
|
||
L</guestfs_tar_in>, L</guestfs_tar_out> and the like allow unlimited
|
||
sized uploads and downloads.
|
||
|
||
=head2 INSPECTION LIMITS
|
||
|
||
The inspection code has several arbitrary limits on things like the
|
||
size of Windows Registry hive it will read, and the length of product
|
||
name. These are intended to stop a malicious guest from consuming
|
||
arbitrary amounts of memory and disk space on the host, and should not
|
||
be reached in practice. See the source code for more information.
|
||
|
||
=head1 ADVANCED MACHINE READABLE OUTPUT
|
||
|
||
Some of the tools support a I<--machine-readable> option, which is
|
||
generally used to make the output more machine friendly, for easier
|
||
parsing for example. By default, this output goes to stdout.
|
||
|
||
When using the I<--machine-readable> option, the progress,
|
||
information, warning, and error messages are also printed in JSON
|
||
format for easier log tracking. Thus, it is highly recommended to
|
||
redirect the machine-readable output to a different stream. The
|
||
format of these JSON messages is like the following (actually printed
|
||
within a single line, below it is indented for readability):
|
||
|
||
{
|
||
"message": "Finishing off",
|
||
"timestamp": "2019-03-22T14:46:49.067294446+01:00",
|
||
"type": "message"
|
||
}
|
||
|
||
C<type> can be: C<message> for progress messages, C<info> for
|
||
information messages, C<warning> for warning messages, and C<error>
|
||
for error message.
|
||
C<timestamp> is the L<RFC 3339|https://www.ietf.org/rfc/rfc3339.txt>
|
||
timestamp of the message.
|
||
|
||
In addition to that, a subset of these tools support an extra string
|
||
passed to the I<--machine-readable> option: this string specifies
|
||
where the machine-readable output will go.
|
||
|
||
The possible values are:
|
||
|
||
=over 4
|
||
|
||
=item B<fd:>I<fd>
|
||
|
||
The output goes to the specified I<fd>, which is a file descriptor
|
||
already opened for writing.
|
||
|
||
=item B<file:>F<filename>
|
||
|
||
The output goes to the specified F<filename>.
|
||
|
||
=item B<stream:stdout>
|
||
|
||
The output goes to stdout. This is basically the same as the default
|
||
behaviour of I<--machine-readable> with no parameter, although stdout
|
||
as output is specified explicitly.
|
||
|
||
=item B<stream:stderr>
|
||
|
||
The output goes to stderr.
|
||
|
||
=back
|
||
|
||
=head1 ENVIRONMENT VARIABLES
|
||
|
||
=over 4
|
||
|
||
=item LIBGUESTFS_APPEND
|
||
|
||
Pass additional options to the guest kernel.
|
||
|
||
=item LIBGUESTFS_ATTACH_METHOD
|
||
|
||
This is the old way to set C<LIBGUESTFS_BACKEND>.
|
||
|
||
=item LIBGUESTFS_BACKEND
|
||
|
||
Choose the default way to create the appliance. See
|
||
L</guestfs_set_backend> and L</BACKEND>.
|
||
|
||
=item LIBGUESTFS_BACKEND_SETTINGS
|
||
|
||
A colon-separated list of backend-specific settings.
|
||
See L</BACKEND>, L</BACKEND SETTINGS>.
|
||
|
||
=item LIBGUESTFS_CACHEDIR
|
||
|
||
The location where libguestfs will cache its appliance, when
|
||
using a supermin appliance. The appliance is cached and shared
|
||
between all handles which have the same effective user ID.
|
||
|
||
If C<LIBGUESTFS_CACHEDIR> is not set, then C<TMPDIR> is used. If
|
||
C<TMPDIR> is not set, then F</var/tmp> is used.
|
||
|
||
See also L</LIBGUESTFS_TMPDIR>, L</guestfs_set_cachedir>.
|
||
|
||
=item LIBGUESTFS_DEBUG
|
||
|
||
Set C<LIBGUESTFS_DEBUG=1> to enable verbose messages. This
|
||
has the same effect as calling C<guestfs_set_verbose (g, 1)>.
|
||
|
||
=item LIBGUESTFS_HV
|
||
|
||
Set the default hypervisor (usually qemu) binary that libguestfs uses.
|
||
If not set, then the qemu which was found at compile time by the
|
||
configure script is used.
|
||
|
||
See also L</QEMU WRAPPERS> above.
|
||
|
||
=item LIBGUESTFS_MEMSIZE
|
||
|
||
Set the memory allocated to the qemu process, in megabytes. For
|
||
example:
|
||
|
||
LIBGUESTFS_MEMSIZE=700
|
||
|
||
=item LIBGUESTFS_PATH
|
||
|
||
Set the path that libguestfs uses to search for a supermin appliance.
|
||
See the discussion of paths in section L</PATH> above.
|
||
|
||
=item LIBGUESTFS_QEMU
|
||
|
||
This is the old way to set C<LIBGUESTFS_HV>.
|
||
|
||
=item LIBGUESTFS_TMPDIR
|
||
|
||
The location where libguestfs will store temporary files used
|
||
by each handle.
|
||
|
||
If C<LIBGUESTFS_TMPDIR> is not set, then C<TMPDIR> is used. If
|
||
C<TMPDIR> is not set, then F</tmp> is used.
|
||
|
||
See also L</LIBGUESTFS_CACHEDIR>, L</guestfs_set_tmpdir>.
|
||
|
||
=item LIBGUESTFS_TRACE
|
||
|
||
Set C<LIBGUESTFS_TRACE=1> to enable command traces. This
|
||
has the same effect as calling C<guestfs_set_trace (g, 1)>.
|
||
|
||
=item PATH
|
||
|
||
Libguestfs may run some external programs, and relies on C<$PATH>
|
||
being set to a reasonable value. If using the libvirt backend,
|
||
libvirt will not work at all unless C<$PATH> contains the path of
|
||
qemu/KVM. Note that PHP by default removes C<$PATH> from the
|
||
environment which tends to break everything.
|
||
|
||
=item SUPERMIN_KERNEL
|
||
|
||
=item SUPERMIN_KERNEL_VERSION
|
||
|
||
=item SUPERMIN_MODULES
|
||
|
||
These three environment variables allow the kernel that libguestfs
|
||
uses in the appliance to be selected. If C<$SUPERMIN_KERNEL> is not
|
||
set, then the most recent host kernel is chosen. For more information
|
||
about kernel selection, see L<supermin(1)>.
|
||
|
||
=item TMPDIR
|
||
|
||
See L</LIBGUESTFS_CACHEDIR>, L</LIBGUESTFS_TMPDIR>.
|
||
|
||
=item XDG_RUNTIME_DIR
|
||
|
||
This directory represents a user-specific directory for storing
|
||
non-essential runtime files.
|
||
|
||
If it is set, then is used to store temporary sockets. Otherwise,
|
||
F</tmp> is used.
|
||
|
||
See also L</guestfs_get_sockdir>,
|
||
L<http://www.freedesktop.org/wiki/Specifications/basedir-spec/>.
|
||
|
||
=back
|
||
|
||
=head1 SEE ALSO
|
||
|
||
Examples written in C:
|
||
L<guestfs-examples(3)>.
|
||
|
||
Language bindings:
|
||
L<guestfs-erlang(3)>,
|
||
L<guestfs-gobject(3)>,
|
||
L<guestfs-golang(3)>,
|
||
L<guestfs-java(3)>,
|
||
L<guestfs-lua(3)>,
|
||
L<guestfs-ocaml(3)>,
|
||
L<guestfs-perl(3)>,
|
||
L<guestfs-python(3)>,
|
||
L<guestfs-ruby(3)>.
|
||
|
||
Tools:
|
||
L<guestfish(1)>,
|
||
L<guestmount(1)>,
|
||
L<virt-alignment-scan(1)>,
|
||
L<virt-builder(1)>,
|
||
L<virt-builder-repository(1)>,
|
||
L<virt-cat(1)>,
|
||
L<virt-copy-in(1)>,
|
||
L<virt-copy-out(1)>,
|
||
L<virt-customize(1)>,
|
||
L<virt-df(1)>,
|
||
L<virt-diff(1)>,
|
||
L<virt-edit(1)>,
|
||
L<virt-filesystems(1)>,
|
||
L<virt-format(1)>,
|
||
L<virt-inspector(1)>,
|
||
L<virt-list-filesystems(1)>,
|
||
L<virt-list-partitions(1)>,
|
||
L<virt-log(1)>,
|
||
L<virt-ls(1)>,
|
||
L<virt-make-fs(1)>,
|
||
L<virt-p2v(1)>,
|
||
L<virt-rescue(1)>,
|
||
L<virt-resize(1)>,
|
||
L<virt-sparsify(1)>,
|
||
L<virt-sysprep(1)>,
|
||
L<virt-tail(1)>,
|
||
L<virt-tar(1)>,
|
||
L<virt-tar-in(1)>,
|
||
L<virt-tar-out(1)>,
|
||
L<virt-v2v(1)>,
|
||
L<virt-win-reg(1)>.
|
||
|
||
Other libguestfs topics:
|
||
L<guestfs-building(1)>,
|
||
L<guestfs-faq(1)>,
|
||
L<guestfs-hacking(1)>,
|
||
L<guestfs-internals(1)>,
|
||
L<guestfs-performance(1)>,
|
||
L<guestfs-release-notes(1)>,
|
||
L<guestfs-security(1)>,
|
||
L<guestfs-testing(1)>,
|
||
L<libguestfs-test-tool(1)>,
|
||
L<libguestfs-make-fixed-appliance(1)>.
|
||
|
||
Related manual pages:
|
||
L<supermin(1)>,
|
||
L<qemu(1)>,
|
||
L<hivex(3)>,
|
||
L<stap(1)>,
|
||
L<sd-journal(3)>.
|
||
|
||
Website:
|
||
L<http://libguestfs.org/>
|
||
|
||
Tools with a similar purpose:
|
||
L<fdisk(8)>,
|
||
L<parted(8)>,
|
||
L<kpartx(8)>,
|
||
L<lvm(8)>,
|
||
L<disktype(1)>.
|
||
|
||
=head1 AUTHORS
|
||
|
||
Richard W.M. Jones (C<rjones at redhat dot com>)
|
||
|
||
=head1 COPYRIGHT
|
||
|
||
Copyright (C) 2009-2023 Red Hat Inc.
|