mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
New APIs for guest inspection.
This commit converts (some of) the Perl inspection code to C and makes it available through core APIs. The new APIs are: inspect-os - Does the inspection, returns list of OSes inspect-get-* - Get results of the inspection where '*' is one of: type - 'windows' or 'linux' distro - Linux distro arch - architecture product-name - long product name string major-version minor-version - major.minor version of OS mountpoints - get a list of the mountpoints filesystems - get all filesystems associated with the OS This works for all existing supported Linux and Windows OSes.
This commit is contained in:
@@ -131,7 +131,7 @@ libguestfs_la_SOURCES = \
|
||||
proto.c \
|
||||
libguestfs.syms
|
||||
|
||||
libguestfs_la_LIBADD = $(LIBPCRE) $(LIBMAGIC) $(LTLIBTHREAD) ../gnulib/lib/libgnu.la
|
||||
libguestfs_la_LIBADD = $(HIVEX_LIBS) $(LIBPCRE) $(LIBMAGIC) $(LTLIBTHREAD) ../gnulib/lib/libgnu.la
|
||||
|
||||
# Make libguestfs include the convenience library.
|
||||
noinst_LTLIBRARIES = libprotocol.la
|
||||
@@ -139,6 +139,7 @@ libguestfs_la_LIBADD += libprotocol.la
|
||||
|
||||
libguestfs_la_CFLAGS = \
|
||||
-DGUESTFS_DEFAULT_PATH='"$(libdir)/guestfs"' \
|
||||
$(HIVEX_CFLAGS) \
|
||||
$(WARN_CFLAGS) $(WERROR_CFLAGS)
|
||||
|
||||
libguestfs_la_CPPFLAGS = -I$(top_srcdir)/gnulib/lib
|
||||
|
||||
221
src/generator.ml
221
src/generator.ml
@@ -1068,6 +1068,227 @@ initrd or kernel module(s) instead.
|
||||
|
||||
=back");
|
||||
|
||||
("inspect_os", (RStringList "roots", []), -1, [],
|
||||
[],
|
||||
"inspect disk and return list of operating systems found",
|
||||
"\
|
||||
This function uses other libguestfs functions and certain
|
||||
heuristics to inspect the disk(s) (usually disks belonging to
|
||||
a virtual machine), looking for operating systems.
|
||||
|
||||
The list returned is empty if no operating systems were found.
|
||||
|
||||
If one operating system was found, then this returns a list with
|
||||
a single element, which is the name of the root filesystem of
|
||||
this operating system. It is also possible for this function
|
||||
to return a list containing more than one element, indicating
|
||||
a dual-boot or multi-boot virtual machine, with each element being
|
||||
the root filesystem of one of the operating systems.
|
||||
|
||||
You can pass the root string(s) returned to other
|
||||
C<guestfs_inspect_get_*> functions in order to query further
|
||||
information about each operating system, such as the name
|
||||
and version.
|
||||
|
||||
This function uses other libguestfs features such as
|
||||
C<guestfs_mount_ro> and C<guestfs_umount_all> in order to mount
|
||||
and unmount filesystems and look at the contents. This should
|
||||
be called with no disks currently mounted. The function may also
|
||||
use Augeas, so any existing Augeas handle will be closed.
|
||||
|
||||
This function cannot decrypt encrypted disks. The caller
|
||||
must do that first (supplying the necessary keys) if the
|
||||
disk is encrypted.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
|
||||
("inspect_get_type", (RString "name", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get type of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns the type of the inspected operating system.
|
||||
Currently defined types are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item \"linux\"
|
||||
|
||||
Any Linux-based operating system.
|
||||
|
||||
=item \"windows\"
|
||||
|
||||
Any Microsoft Windows operating system.
|
||||
|
||||
=item \"unknown\"
|
||||
|
||||
The operating system type could not be determined.
|
||||
|
||||
=back
|
||||
|
||||
Future versions of libguestfs may return other strings here.
|
||||
The caller should be prepared to handle any string.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
|
||||
("inspect_get_arch", (RString "arch", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get architecture of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns the architecture of the inspected operating system.
|
||||
The possible return values are listed under
|
||||
C<guestfs_file_architecture>.
|
||||
|
||||
If the architecture could not be determined, then the
|
||||
string C<unknown> is returned.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
|
||||
("inspect_get_distro", (RString "distro", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get distro of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns the distro (distribution) of the inspected operating
|
||||
system.
|
||||
|
||||
Currently defined distros are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item \"debian\"
|
||||
|
||||
Debian or a Debian-derived distro such as Ubuntu.
|
||||
|
||||
=item \"fedora\"
|
||||
|
||||
Fedora.
|
||||
|
||||
=item \"redhat-based\"
|
||||
|
||||
Some Red Hat-derived distro.
|
||||
|
||||
=item \"rhel\"
|
||||
|
||||
Red Hat Enterprise Linux and some derivatives.
|
||||
|
||||
=item \"windows\"
|
||||
|
||||
Windows does not have distributions. This string is
|
||||
returned if the OS type is Windows.
|
||||
|
||||
=item \"unknown\"
|
||||
|
||||
The distro could not be determined.
|
||||
|
||||
=back
|
||||
|
||||
Future versions of libguestfs may return other strings here.
|
||||
The caller should be prepared to handle any string.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
|
||||
("inspect_get_major_version", (RInt "major", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get major version of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns the major version number of the inspected operating
|
||||
system.
|
||||
|
||||
Windows uses a consistent versioning scheme which is I<not>
|
||||
reflected in the popular public names used by the operating system.
|
||||
Notably the operating system known as \"Windows 7\" is really
|
||||
version 6.1 (ie. major = 6, minor = 1). You can find out the
|
||||
real versions corresponding to releases of Windows by consulting
|
||||
Wikipedia or MSDN.
|
||||
|
||||
If the version could not be determined, then C<0> is returned.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
|
||||
("inspect_get_minor_version", (RInt "minor", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get minor version of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns the minor version number of the inspected operating
|
||||
system.
|
||||
|
||||
If the version could not be determined, then C<0> is returned.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.
|
||||
See also C<guestfs_inspect_get_major_version>.");
|
||||
|
||||
("inspect_get_product_name", (RString "product", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get product name of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns the product name of the inspected operating
|
||||
system. The product name is generally some freeform string
|
||||
which can be displayed to the user, but should not be
|
||||
parsed by programs.
|
||||
|
||||
If the product name could not be determined, then the
|
||||
string C<unknown> is returned.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
|
||||
("inspect_get_mountpoints", (RHashtable "mountpoints", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get mountpoints of inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns a hash of where we think the filesystems
|
||||
associated with this operating system should be mounted.
|
||||
Callers should note that this is at best an educated guess
|
||||
made by reading configuration files such as C</etc/fstab>.
|
||||
|
||||
Each element in the returned hashtable has a key which
|
||||
is the path of the mountpoint (eg. C</boot>) and a value
|
||||
which is the filesystem that would be mounted there
|
||||
(eg. C</dev/sda1>).
|
||||
|
||||
Non-mounted devices such as swap devices are I<not>
|
||||
returned in this list.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.
|
||||
See also C<guestfs_inspect_get_filesystems>.");
|
||||
|
||||
("inspect_get_filesystems", (RStringList "filesystems", [Device "root"]), -1, [],
|
||||
[],
|
||||
"get filesystems associated with inspected operating system",
|
||||
"\
|
||||
This function should only be called with a root device string
|
||||
as returned by C<guestfs_inspect_os>.
|
||||
|
||||
This returns a list of all the filesystems that we think
|
||||
are associated with this operating system. This includes
|
||||
the root filesystem, other ordinary filesystems, and
|
||||
non-mounted devices like swap partitions.
|
||||
|
||||
In the case of a multi-boot virtual machine, it is possible
|
||||
for a filesystem to be shared between operating systems.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.
|
||||
See also C<guestfs_inspect_get_mountpoints>.");
|
||||
|
||||
]
|
||||
|
||||
(* daemon_functions are any functions which cause some action
|
||||
|
||||
@@ -131,6 +131,59 @@ struct guestfs_h
|
||||
void * close_cb_data;
|
||||
|
||||
int msg_next_serial;
|
||||
|
||||
/* Information gathered by inspect_os. Must be freed by calling
|
||||
* guestfs___free_inspect_info.
|
||||
*/
|
||||
struct inspect_fs *fses;
|
||||
size_t nr_fses;
|
||||
};
|
||||
|
||||
/* Per-filesystem data stored for inspect_os. */
|
||||
enum inspect_fs_content {
|
||||
FS_CONTENT_UNKNOWN = 0,
|
||||
FS_CONTENT_LINUX_ROOT,
|
||||
FS_CONTENT_WINDOWS_ROOT,
|
||||
FS_CONTENT_LINUX_BOOT,
|
||||
FS_CONTENT_LINUX_USR,
|
||||
FS_CONTENT_LINUX_USR_LOCAL,
|
||||
FS_CONTENT_LINUX_VAR,
|
||||
};
|
||||
|
||||
enum inspect_os_type {
|
||||
OS_TYPE_UNKNOWN = 0,
|
||||
OS_TYPE_LINUX,
|
||||
OS_TYPE_WINDOWS,
|
||||
};
|
||||
|
||||
enum inspect_os_distro {
|
||||
OS_DISTRO_UNKNOWN = 0,
|
||||
OS_DISTRO_DEBIAN,
|
||||
OS_DISTRO_FEDORA,
|
||||
OS_DISTRO_REDHAT_BASED,
|
||||
OS_DISTRO_RHEL,
|
||||
OS_DISTRO_WINDOWS,
|
||||
};
|
||||
|
||||
struct inspect_fs {
|
||||
int is_root;
|
||||
char *device;
|
||||
int is_mountable;
|
||||
int is_swap;
|
||||
enum inspect_fs_content content;
|
||||
enum inspect_os_type type;
|
||||
enum inspect_os_distro distro;
|
||||
char *product_name;
|
||||
int major_version;
|
||||
int minor_version;
|
||||
char *arch;
|
||||
struct inspect_fstab_entry *fstab;
|
||||
size_t nr_fstab;
|
||||
};
|
||||
|
||||
struct inspect_fstab_entry {
|
||||
char *device;
|
||||
char *mountpoint;
|
||||
};
|
||||
|
||||
struct guestfs_message_header;
|
||||
@@ -143,6 +196,7 @@ extern void *guestfs_safe_realloc (guestfs_h *g, void *ptr, int nbytes);
|
||||
extern char *guestfs_safe_strdup (guestfs_h *g, const char *str);
|
||||
extern char *guestfs_safe_strndup (guestfs_h *g, const char *str, size_t n);
|
||||
extern void *guestfs_safe_memdup (guestfs_h *g, void *ptr, size_t size);
|
||||
extern void guestfs___free_inspect_info (guestfs_h *g);
|
||||
extern int guestfs___set_busy (guestfs_h *g);
|
||||
extern int guestfs___end_busy (guestfs_h *g);
|
||||
extern int guestfs___send (guestfs_h *g, int proc_nr, xdrproc_t xdrp, char *args);
|
||||
|
||||
@@ -184,6 +184,8 @@ guestfs_close (guestfs_h *g)
|
||||
if (g->close_cb)
|
||||
g->close_cb (g, g->close_cb_data);
|
||||
|
||||
guestfs___free_inspect_info (g);
|
||||
|
||||
/* Try to sync if autosync flag is set. */
|
||||
if (g->autosync && g->state == READY) {
|
||||
guestfs_umount_all (g);
|
||||
|
||||
@@ -160,9 +160,10 @@ 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>. But you might find it easier to look at higher level
|
||||
programs built on top of libguestfs, in particular
|
||||
L<virt-inspector(1)>.
|
||||
L</guestfs_file>. Libguestfs also has a set of APIs for inspection of
|
||||
disk images (see L</INSPECTION> below). But you might find it easier
|
||||
to look at higher level programs built on top of libguestfs, in
|
||||
particular L<virt-inspector(1)>.
|
||||
|
||||
To mount a disk image read-only, use L</guestfs_mount_ro>. There are
|
||||
several other variations of the C<guestfs_mount_*> call.
|
||||
@@ -481,6 +482,65 @@ Then close the mapper device by calling
|
||||
L</guestfs_luks_close> on the C</dev/mapper/mapname>
|
||||
device (I<not> the underlying encrypted block device).
|
||||
|
||||
=head2 INSPECTION
|
||||
|
||||
Libguestfs has APIs for inspecting an unknown disk image to find out
|
||||
if it contains operating systems. (These APIs used to be in a
|
||||
separate Perl-only library called L<Sys::Guestfs::Lib(3)> but since
|
||||
version 1.5.3 the most frequently used part of this library has been
|
||||
rewritten in C and moved into the core code).
|
||||
|
||||
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 C</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_options> to
|
||||
mount the filesystems as suggested.
|
||||
|
||||
Be careful to mount filesystems in the right order (eg. C</> before
|
||||
C</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.
|
||||
|
||||
=head2 SPECIAL CONSIDERATIONS FOR WINDOWS GUESTS
|
||||
|
||||
Libguestfs can mount NTFS partitions. It does this using the
|
||||
@@ -495,7 +555,7 @@ that directory might be referred to as C</WINDOWS/System32>.
|
||||
Drive letter mappings are outside the scope of libguestfs. You have
|
||||
to use libguestfs to read the appropriate Windows Registry and
|
||||
configuration files, to determine yourself how drives are mapped (see
|
||||
also L<virt-inspector(1)>).
|
||||
also L<hivex(3)> and L<virt-inspector(1)>).
|
||||
|
||||
Replacing backslash characters with forward slash characters is also
|
||||
outside the scope of libguestfs, but something that you can easily do.
|
||||
|
||||
1017
src/inspect.c
1017
src/inspect.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user