[PATCH] p2v: Use lscpu instead of libvirt to get CPU information.
by Richard W.M. Jones
Don't get the CPU information from libvirt, because including libvirt
and all dependencies in the virt-p2v ISO bloats everything.
Instead get most of the information we need from the util-linux
program 'lscpu'.
Unfortunately the CPU model cannot be retrieved.
Example output:
$ ./run virt-p2v --cmdline="p2v.dump_config_and_exit"
[...]
cpu vendor . . . Intel
cpu sockets . . 2
cpu cores . . . 8
cpu threads . . 1
flags . . . . . acpi apic pae
This updates commit 963d6c3be7cd91c0373f67cfdd95c4f1dad1452f.
---
p2v/Makefile.am | 11 +-
p2v/cpuid.c | 331 ++++++++++++++++++++--------------------------------
p2v/dependencies.m4 | 5 -
3 files changed, 128 insertions(+), 219 deletions(-)
diff --git a/p2v/Makefile.am b/p2v/Makefile.am
index 726916027..94c649a8e 100644
--- a/p2v/Makefile.am
+++ b/p2v/Makefile.am
@@ -100,7 +100,6 @@ virt_p2v_CPPFLAGS = \
virt_p2v_CFLAGS = \
-pthread \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
- $(LIBVIRT_CFLAGS) \
$(PCRE_CFLAGS) \
$(LIBXML2_CFLAGS) \
$(GTK_CFLAGS) \
@@ -109,7 +108,6 @@ virt_p2v_CFLAGS = \
virt_p2v_LDADD = \
$(top_builddir)/common/utils/libutils.la \
$(top_builddir)/common/miniexpect/libminiexpect.la \
- $(LIBVIRT_LIBS) \
$(PCRE_LIBS) \
$(LIBXML2_LIBS) \
$(GTK_LIBS) \
@@ -126,16 +124,9 @@ dependencies_files = \
dependencies.redhat \
dependencies.suse
-if HAVE_LIBVIRT
-dependencies_have_libvirt = -DHAVE_LIBVIRT=1
-endif
-
$(dependencies_files): dependencies.m4
define=`echo $@ | $(SED) 's/dependencies.//;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`; \
- m4 -D$$define=1 \
- -DGTK_VERSION=$(GTK_VERSION) \
- $(dependencies_have_libvirt) \
- $< > $@-t
+ m4 -D$$define=1 -DGTK_VERSION=$(GTK_VERSION) $< > $@-t
mv $@-t $@
# Support files needed by the virt-p2v-make-* scripts.
diff --git a/p2v/cpuid.c b/p2v/cpuid.c
index 13b61b050..12720552d 100644
--- a/p2v/cpuid.c
+++ b/p2v/cpuid.c
@@ -17,20 +17,17 @@
*/
/**
- * Process CPU capabilities into libvirt-compatible C<E<lt>cpuE<gt>> data.
+ * Find CPU vendor, topology and some CPU flags.
*
- * If libvirt is available at compile time then this is quite
- * simple - libvirt API C<virConnectGetCapabilities> provides
- * a C<E<lt>hostE<ge>> element which has mostly what we need.
+ * lscpu (from util-linux) provides CPU vendor, topology and flags.
*
- * Flags C<acpi>, C<apic>, C<pae> still have to be parsed out of
- * F</proc/cpuinfo> because these will not necessarily be present in
- * the libvirt capabilities directly (they are implied by the
- * processor model, requiring a complex lookup in the CPU map).
+ * ACPI can be read by seeing if F</sys/firmware/acpi> exists.
*
- * Note that #vCPUs and amount of RAM is handled by F<main.c>.
+ * CPU model is essentially impossible to get without using libvirt,
+ * but we cannot use libvirt for the reasons outlined in this message:
+ * https://www.redhat.com/archives/libvirt-users/2017-March/msg00071.html
*
- * See: L<https://libvirt.org/formatdomain.html#elementsCPU>
+ * Note that #vCPUs and amount of RAM is handled by F<main.c>.
*/
#include <config.h>
@@ -40,15 +37,10 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
+#include <error.h>
#include <libintl.h>
-#ifdef HAVE_LIBVIRT
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-#endif
-
-#include <libxml/xpath.h>
-
+#include "c-ctype.h"
#include "getprogname.h"
#include "ignore-value.h"
@@ -65,235 +57,166 @@ free_cpu_config (struct cpu_config *cpu)
}
/**
- * Read flags from F</proc/cpuinfo>.
+ * Get the output of lscpu as a list of (key, value) pairs (as a
+ * flattened list of strings).
*/
-static void
-cpuinfo_flags (struct cpu_config *cpu)
+static char **
+get_lscpu (void)
{
const char *cmd;
CLEANUP_PCLOSE FILE *fp = NULL;
- CLEANUP_FREE char *flag = NULL;
+ CLEANUP_FREE char *line = NULL;
ssize_t len;
size_t buflen = 0;
+ char **ret = NULL;
+ size_t ret_size = 0;
- /* Get the flags, one per line. */
- cmd = "< /proc/cpuinfo "
-#if defined(__arm__)
- "grep ^Features"
-#else
- "grep ^flags"
-#endif
- " | awk '{ for (i = 3; i <= NF; ++i) { print $i }; exit }'";
+ cmd = "lscpu";
fp = popen (cmd, "re");
if (fp == NULL) {
- perror ("/proc/cpuinfo");
- return;
+ perror (cmd);
+ return NULL;
}
- while (errno = 0, (len = getline (&flag, &buflen, fp)) != -1) {
- if (len > 0 && flag[len-1] == '\n')
- flag[len-1] = '\0';
-
- if (STREQ (flag, "acpi"))
- cpu->acpi = 1;
- else if (STREQ (flag, "apic"))
- cpu->apic = 1;
- else if (STREQ (flag, "pae"))
- cpu->pae = 1;
+ ret = malloc (sizeof (char *));
+ if (ret == NULL) error (EXIT_FAILURE, errno, "malloc");
+ ret[0] = NULL;
+
+ while (errno = 0, (len = getline (&line, &buflen, fp)) != -1) {
+ char *p;
+ char *key, *value;
+
+ if (len > 0 && line[len-1] == '\n')
+ line[len-1] = '\0';
+
+ /* Split the line at the first ':' character. */
+ p = strchr (line, ':');
+ if (p == NULL)
+ continue;
+
+ *p = '\0';
+ key = strdup (line);
+ /* Skip leading whitespace in the value. */
+ for (++p; *p && c_isspace (*p); ++p)
+ ;
+ value = strdup (p);
+
+ /* Add key and value to the list, and trailing NULL pointer. */
+ ret_size += 2;
+ ret = realloc (ret, (ret_size + 1) * sizeof (char *));
+ if (ret == NULL) error (EXIT_FAILURE, errno, "realloc");
+ ret[ret_size-2] = key;
+ ret[ret_size-1] = value;
+ ret[ret_size] = NULL;
}
if (errno) {
- perror ("getline");
- return;
+ perror (cmd);
+ guestfs_int_free_string_list (ret);
+ return NULL;
}
+
+ return ret;
}
-#ifdef HAVE_LIBVIRT
+/**
+ * Read a single field from lscpu output.
+ *
+ * If the field does not exist, returns C<NULL>.
+ */
+static const char *
+get_field (char **lscpu, const char *key)
+{
+ size_t i;
+
+ for (i = 0; lscpu[i] != NULL; i += 2) {
+ if (STREQ (lscpu[i], key))
+ return lscpu[i+1];
+ }
+
+ return NULL;
+}
+/**
+ * Read the CPU vendor from lscpu output.
+ */
static void
-ignore_errors (void *ignore, virErrorPtr ignore2)
+get_vendor (char **lscpu, struct cpu_config *cpu)
{
- /* empty */
+ const char *vendor = get_field (lscpu, "Vendor ID");
+
+ if (vendor) {
+ /* Note this mapping comes from /usr/share/libvirt/cpu_map.xml */
+ if (STREQ (vendor, "GenuineIntel"))
+ cpu->vendor = strdup ("Intel");
+ else if (STREQ (vendor, "AuthenticAMD"))
+ cpu->vendor = strdup ("AMD");
+ /* Currently aarch64 lscpu has no Vendor ID XXX. */
+ }
}
-static void libvirt_error (const char *fs, ...) __attribute__((format (printf,1,2)));
-
+/**
+ * Read the CPU topology from lscpu output.
+ */
static void
-libvirt_error (const char *fs, ...)
+get_topology (char **lscpu, struct cpu_config *cpu)
{
- va_list args;
- CLEANUP_FREE char *msg = NULL;
- int len;
- virErrorPtr err;
-
- va_start (args, fs);
- len = vasprintf (&msg, fs, args);
- va_end (args);
-
- if (len < 0) goto fallback;
-
- /* In all recent libvirt, this retrieves the thread-local error. */
- err = virGetLastError ();
- if (err)
- fprintf (stderr,
- "%s: %s: %s [code=%d int1=%d]\n",
- getprogname (), msg, err->message, err->code, err->int1);
- else
- fallback:
- fprintf (stderr, "%s: %s\n", getprogname (), msg);
+ const char *v;
+
+ v = get_field (lscpu, "Socket(s)");
+ if (v)
+ ignore_value (sscanf (v, "%u", &cpu->sockets));
+ v = get_field (lscpu, "Core(s) per socket");
+ if (v)
+ ignore_value (sscanf (v, "%u", &cpu->cores));
+ v = get_field (lscpu, "Thread(s) per core");
+ if (v)
+ ignore_value (sscanf (v, "%u", &cpu->threads));
}
/**
- * Read the capabilities from libvirt and parse out the fields
- * we care about.
+ * Read some important flags from lscpu output.
*/
static void
-libvirt_capabilities (struct cpu_config *cpu)
+get_flags (char **lscpu, struct cpu_config *cpu)
{
- virConnectPtr conn;
- CLEANUP_FREE char *capabilities_xml = NULL;
- CLEANUP_XMLFREEDOC xmlDocPtr doc = NULL;
- CLEANUP_XMLXPATHFREECONTEXT xmlXPathContextPtr xpathCtx = NULL;
- CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xpathObj = NULL;
- const char *xpathexpr;
- xmlNodeSetPtr nodes;
- size_t nr_nodes, i;
- xmlNodePtr node;
-
- /* Connect to libvirt and get the capabilities XML. */
- conn = virConnectOpenReadOnly (NULL);
- if (!conn) {
- libvirt_error (_("could not connect to libvirt"));
- return;
- }
+ const char *flags;
- /* Suppress default behaviour of printing errors to stderr. Note
- * you can't set this to NULL to ignore errors; setting it to NULL
- * restores the default error handler ...
- */
- virConnSetErrorFunc (conn, NULL, ignore_errors);
-
- capabilities_xml = virConnectGetCapabilities (conn);
- if (!capabilities_xml) {
- libvirt_error (_("could not get libvirt capabilities"));
- virConnectClose (conn);
- return;
- }
-
- /* Parse the capabilities XML with libxml2. */
- doc = xmlReadMemory (capabilities_xml, strlen (capabilities_xml),
- NULL, NULL, XML_PARSE_NONET);
- if (doc == NULL) {
- fprintf (stderr,
- _("%s: unable to parse capabilities XML returned by libvirt\n"),
- getprogname ());
- virConnectClose (conn);
- return;
- }
-
- xpathCtx = xmlXPathNewContext (doc);
- if (xpathCtx == NULL) {
- fprintf (stderr, _("%s: unable to create new XPath context\n"),
- getprogname ());
- virConnectClose (conn);
- return;
- }
-
- /* Get the CPU vendor. */
- xpathexpr = "/capabilities/host/cpu/vendor/text()";
- xpathObj = xmlXPathEvalExpression (BAD_CAST xpathexpr, xpathCtx);
- if (xpathObj == NULL) {
- fprintf (stderr, _("%s: unable to evaluate xpath expression: %s\n"),
- getprogname (), xpathexpr);
- virConnectClose (conn);
- return;
- }
- nodes = xpathObj->nodesetval;
- nr_nodes = nodes->nodeNr;
- if (nr_nodes > 0) {
- node = nodes->nodeTab[0];
- cpu->vendor = (char *) xmlNodeGetContent (node);
- }
-
- /* Get the CPU model. */
- xmlXPathFreeObject (xpathObj);
- xpathexpr = "/capabilities/host/cpu/model/text()";
- xpathObj = xmlXPathEvalExpression (BAD_CAST xpathexpr, xpathCtx);
- if (xpathObj == NULL) {
- fprintf (stderr, _("%s: unable to evaluate xpath expression: %s\n"),
- getprogname (), xpathexpr);
- virConnectClose (conn);
- return;
- }
- nodes = xpathObj->nodesetval;
- nr_nodes = nodes->nodeNr;
- if (nr_nodes > 0) {
- node = nodes->nodeTab[0];
- cpu->model = (char *) xmlNodeGetContent (node);
- }
+ flags = get_field (lscpu, "Flags");
+ if (flags) {
+ cpu->apic = strstr (flags, " apic ") != NULL;
+ cpu->pae = strstr (flags, " pae ") != NULL;
- /* Get the topology. Note the XPath expression returns all
- * attributes of the <topology> node.
- */
- xmlXPathFreeObject (xpathObj);
- xpathexpr = "/capabilities/host/cpu/topology/@*";
- xpathObj = xmlXPathEvalExpression (BAD_CAST xpathexpr, xpathCtx);
- if (xpathObj == NULL) {
- fprintf (stderr, _("%s: unable to evaluate xpath expression: %s\n"),
- getprogname (), xpathexpr);
- virConnectClose (conn);
- return;
+ /* aarch64 /proc/cpuinfo has a "Features" field, but lscpu does
+ * not expose it. However aarch64 Features does not contain any
+ * of the interesting flags above.
+ */
}
- nodes = xpathObj->nodesetval;
- nr_nodes = nodes->nodeNr;
- /* Iterate over the attributes of the <topology> node. */
- for (i = 0; i < nr_nodes; ++i) {
- node = nodes->nodeTab[i];
-
- if (node->type == XML_ATTRIBUTE_NODE) {
- xmlAttrPtr attr = (xmlAttrPtr) node;
- CLEANUP_FREE char *content = NULL;
- unsigned *up;
-
- if (STREQ ((const char *) attr->name, "sockets")) {
- up = &cpu->sockets;
- parse_attr:
- *up = 0;
- content = (char *) xmlNodeListGetString (doc, attr->children, 1);
- if (content)
- ignore_value (sscanf (content, "%u", up));
- }
- else if (STREQ ((const char *) attr->name, "cores")) {
- up = &cpu->cores;
- goto parse_attr;
- }
- else if (STREQ ((const char *) attr->name, "threads")) {
- up = &cpu->threads;
- goto parse_attr;
- }
- }
- }
-
- virConnectClose (conn);
}
-#else /* !HAVE_LIBVIRT */
-
+/**
+ * Find out if the system uses ACPI.
+ */
static void
-libvirt_capabilities (struct cpu_config *cpu)
+get_acpi (struct cpu_config *cpu)
{
- fprintf (stderr,
- _("%s: program was compiled without libvirt support\n"),
- getprogname ());
+ cpu->acpi = access ("/sys/firmware/acpi", F_OK) == 0;
}
-#endif /* !HAVE_LIBVIRT */
-
void
get_cpu_config (struct cpu_config *cpu)
{
+ CLEANUP_FREE_STRING_LIST char **lscpu = NULL;
+
free_cpu_config (cpu);
- libvirt_capabilities (cpu);
- cpuinfo_flags (cpu);
+
+ lscpu = get_lscpu ();
+ if (lscpu != NULL) {
+ get_vendor (lscpu, cpu);
+ get_topology (lscpu, cpu);
+ get_flags (lscpu, cpu);
+ }
+
+ get_acpi (cpu);
}
diff --git a/p2v/dependencies.m4 b/p2v/dependencies.m4
index 0db2f85d4..02ca87c19 100644
--- a/p2v/dependencies.m4
+++ b/p2v/dependencies.m4
@@ -25,8 +25,6 @@ ifelse(REDHAT,1,
libxml2
gtk`'GTK_VERSION
dbus-libs
- dnl libvirt is optional, used just to parse the host CPU capabilities.
- ifdef(`HAVE_LIBVIRT', `libvirt-libs')
dnl Run as external programs by the p2v binary.
/usr/bin/ssh
@@ -66,7 +64,6 @@ ifelse(DEBIAN,1,
libxml2
ifelse(GTK_VERSION,2,libgtk`'GTK_VERSION`'.0-0,libgtk-`'GTK_VERSION`'-0)
libdbus-1-3
- ifdef(`HAVE_LIBVIRT', `libvirt0')
openssh-client
qemu-utils
debianutils
@@ -87,7 +84,6 @@ ifelse(ARCHLINUX,1,
libxml2
gtk`'GTK_VERSION
dbus
- ifdef(`HAVE_LIBVIRT', `libvirt')
openssh
qemu
which
@@ -110,7 +106,6 @@ ifelse(SUSE,1,
libxml2
gtk`'GTK_VERSION
libdbus-1-3
- ifdef(`HAVE_LIBVIRT', `libvirt-libs')
qemu-tools
openssh
dnl /usr/bin/which is in util-linux on SUSE
--
2.12.0
7 years, 9 months
[PATCH] bash: Implement tab completion for virt-win-reg (RHBZ#1367738).
by Richard W.M. Jones
This only implements long and short options.
Thanks: Ming Xie.
---
.gitignore | 1 +
bash/Makefile.am | 19 +++++++++++++------
bash/virt-v2v-copy-to-local | 21 ++++++++++++++++-----
tools/virt-win-reg | 22 ++++++++++++++++++++--
4 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/.gitignore b/.gitignore
index c82745e..5c7cd53 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,7 @@ Makefile.in
/bash/virt-tail
/bash/virt-tar-in
/bash/virt-tar-out
+/bash/virt-win-reg
/build-aux/.gitignore
/build-aux/ar-lib
/build-aux/compile
diff --git a/bash/Makefile.am b/bash/Makefile.am
index 86fd816..983e8da 100644
--- a/bash/Makefile.am
+++ b/bash/Makefile.am
@@ -51,7 +51,8 @@ symlinks = \
virt-sysprep \
virt-tail \
virt-tar-in \
- virt-tar-out
+ virt-tar-out \
+ virt-win-reg
# Note: Don't distribute the symbolic links, only the real files.
EXTRA_DIST = \
@@ -62,11 +63,17 @@ EXTRA_DIST = \
CLEANFILES += \
$(symlinks)
-# Any tool that has --short-options and --long-options is handled by
-# this common script. However this script cannot deal with commands
-# that use --ro/--rw (eg. virt-rescue), nor commands that have lots of
-# exceptions (eg. guestfish). Those tools have to be handled
-# individually.
+# Any tool that has --short-options and --long-options only is handled
+# by this common script.
+virt-win-reg:
+ rm -f $@
+ $(LN_S) virt-v2v-copy-to-local $@
+
+# Any tool that has --short-options and --long-options and a few
+# common options like -d is handled by this common script. However
+# this script cannot deal with commands that use --ro/--rw
+# (eg. virt-rescue), nor commands that have lots of exceptions
+# (eg. guestfish). Those tools have to be handled individually.
guestunmount \
virt-builder virt-cat virt-customize virt-df virt-dib virt-diff \
virt-edit virt-filesystems virt-format virt-get-kernel virt-inspector \
diff --git a/bash/virt-v2v-copy-to-local b/bash/virt-v2v-copy-to-local
index 4442da2..1296f26 100644
--- a/bash/virt-v2v-copy-to-local
+++ b/bash/virt-v2v-copy-to-local
@@ -15,28 +15,39 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-_virt_v2v_copy_to_local ()
+_guestfs_options_only ()
{
local cur prev words cword split
- local shortopts longopts items
+ local shortopts longopts tool="$1"
_init_completion -s || return
case "$cur" in
--*)
# --options
- longopts="$(virt-v2v-copy-to-local --long-options)"
+ longopts="$($tool --long-options)"
COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
return ;;
-*)
# -o and --options
- shortopts="$(virt-v2v-copy-to-local --short-options)"
- longopts="$(virt-v2v-copy-to-local --long-options)"
+ shortopts="$($tool --short-options)"
+ longopts="$($tool --long-options)"
COMPREPLY=( $(compgen -W "$shortopts $longopts" -- "$cur") )
return ;;
*)
COMPREPLY=( $(compgen "$cur") )
return ;;
esac
+}
+
+_virt_v2v_copy_to_local ()
+{
+ _guestfs_options_only "virt-v2v-copy-to-local"
} &&
complete -o default -F _virt_v2v_copy_to_local virt-v2v-copy-to-local
+
+_virt_win_reg ()
+{
+ _guestfs_options_only "virt-win-reg"
+} &&
+complete -o default -F _virt_win_reg virt-win-reg
diff --git a/tools/virt-win-reg b/tools/virt-win-reg
index 8ddc4f9..e173d71 100755
--- a/tools/virt-win-reg
+++ b/tools/virt-win-reg
@@ -221,7 +221,7 @@ passed into another program or stored in another Registry.
=cut
-GetOptions ("help|?" => \$help,
+my %opts = ("help|?" => \$help,
"version" => \$version,
"connect|c=s" => \$uri,
"debug|d" => \$debug,
@@ -229,7 +229,9 @@ GetOptions ("help|?" => \$help,
"merge" => \$merge,
"encoding=s" => \$encoding,
"unsafe-printable-strings" => \$unsafe_printable_strings,
- ) or pod2usage (2);
+ "long-options" => \&display_long_options,
+ "short-options" => \&display_short_options);
+GetOptions (%opts) or pod2usage (2);
pod2usage (1) if $help;
if ($version) {
my $g = Sys::Guestfs->new ();
@@ -238,6 +240,22 @@ if ($version) {
exit
}
+sub display_long_options
+{
+ foreach (sort keys %opts) {
+ if (m/^(.*?)([\|=].*)?$/ && !/-options$/) { print "--$1\n" }
+ }
+ exit
+}
+
+sub display_short_options
+{
+ foreach (sort keys %opts) {
+ if (m/\|(.)/) { print "-$1\n" }
+ }
+ exit
+}
+
# virt-win-reg only takes a single disk image ...
die __"no libvirt domain name or disk image given\n" if @ARGV == 0;
my $domname_or_image = shift @ARGV;
--
2.9.3
7 years, 9 months
[PATCH] v2v: xen: Require direct backend when doing Xen conversions over SSH.
by Richard W.M. Jones
From: "Richard W.M. Jones" <rjones(a)redhat.com>
Unfortunately libvirt has another bug related to the qemu
ssh driver, as described here:
https://bugzilla.redhat.com/show_bug.cgi?id=1434651#c3
Until this bug is fixed we have to require the direct backend to be
used for xen+ssh conversions.
This partially reverts commit ecbf09385033ba0acf14e914927ec81ad20a5308.
---
v2v/input_libvirt_xen_ssh.ml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/v2v/input_libvirt_xen_ssh.ml b/v2v/input_libvirt_xen_ssh.ml
index 4975eff..a68cdf8 100644
--- a/v2v/input_libvirt_xen_ssh.ml
+++ b/v2v/input_libvirt_xen_ssh.ml
@@ -38,6 +38,9 @@ object
debug "input_libvirt_xen_ssh: source: scheme %s server %s"
scheme server;
+ if backend_is_libvirt () then (
+ error (f_"because of libvirt bug https://bugzilla.redhat.com/1434651 you must set this environment variable:\n\nexport LIBGUESTFS_BACKEND=direct\n\nand then rerun the virt-v2v command.")
+ );
error_if_libvirt_does_not_support_json_backingfile ();
error_if_no_ssh_agent ();
--
1.8.3.1
7 years, 9 months
[PATCH v2] inspect: improve detection of Mageia install discs
by Pino Toscano
Check for a "product.id" file in an architecture-specific subdirectory
of the main partition, and use its data to improve the data on the
media.
Only Mageia as distribution name is recognized there, since most
probably this file will not be available on other distros.
---
Changes in v2:
- simplify file reading using guestfs_int_first_line_of_file
lib/inspect-fs-cd.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/lib/inspect-fs-cd.c b/lib/inspect-fs-cd.c
index 278386e..1cff560 100644
--- a/lib/inspect-fs-cd.c
+++ b/lib/inspect-fs-cd.c
@@ -21,6 +21,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <libintl.h>
+#include <inttypes.h>
#ifdef HAVE_ENDIAN_H
#include <endian.h>
@@ -432,10 +434,58 @@ check_w2k3_installer_root (guestfs_h *g, struct inspect_fs *fs,
return 0;
}
+/* Read the data from a product.id-like file.
+ *
+ * This is an old file, mostly used in Mandriva-based systems (still including
+ * Mageia). A very minimal documentation for it is:
+ * - https://wiki.mageia.org/en/Product_id
+ * - http://wiki.mandriva.com/en/Product_id (old URL, defunct)
+ */
+static int
+check_product_id_installer_root (guestfs_h *g, struct inspect_fs *fs,
+ const char *filename)
+{
+ CLEANUP_FREE char *line = NULL;
+ const char *elem;
+ char *saveptr;
+
+ fs->type = OS_TYPE_LINUX;
+
+ line = guestfs_int_first_line_of_file (g, filename);
+ if (line == NULL)
+ return -1;
+
+ elem = strtok_r (line, ",", &saveptr);
+ while (elem) {
+ const char *equal = strchr (elem, '=');
+ if (equal == NULL || equal == elem)
+ return -1;
+
+ const char *value = equal + 1;
+
+ if (STRPREFIX (elem, "distribution=")) {
+ if (STREQ (value, "Mageia"))
+ fs->distro = OS_DISTRO_MAGEIA;
+ } else if (STRPREFIX (elem, "version=")) {
+ if (guestfs_int_version_from_x_y_or_x (g, &fs->version, value) == -1)
+ return -1;
+ } else if (STRPREFIX (elem, "arch=")) {
+ fs->arch = safe_strdup (g, value);
+ }
+
+ elem = strtok_r (NULL, ",", &saveptr);
+ }
+
+ /* Not found. */
+ return 0;
+}
+
/* The currently mounted device is very likely to be an installer. */
int
guestfs_int_check_installer_root (guestfs_h *g, struct inspect_fs *fs)
{
+ CLEANUP_FREE_STRING_LIST char **paths = NULL;
+
/* The presence of certain files indicates a live CD.
*
* XXX Fedora netinst contains a ~120MB squashfs called
@@ -495,6 +545,18 @@ guestfs_int_check_installer_root (guestfs_h *g, struct inspect_fs *fs)
return -1;
}
+ /* Linux with /{i586,x86_64,etc}/product.id (typically found in Mandriva
+ * and Mageia). Usually there should be just one around, so we use the
+ * first one found.
+ */
+ paths = guestfs_glob_expand (g, "/*/product.id");
+ if (paths == NULL)
+ return -1;
+ if (paths[0] != NULL) {
+ if (check_product_id_installer_root (g, fs, paths[0]) == -1)
+ return -1;
+ }
+
return 0;
}
--
2.9.3
7 years, 9 months
[PATCH] inspect: improve detection of Mageia install discs
by Pino Toscano
Check for a "product.id" file in an architecture-specific subdirectory
of the main partition, and use its data to improve the data on the
media.
Only Mageia as distribution name is recognized there, since most
probably this file will not be available on other distros.
---
lib/inspect-fs-cd.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/lib/inspect-fs-cd.c b/lib/inspect-fs-cd.c
index 278386e..9c809b4 100644
--- a/lib/inspect-fs-cd.c
+++ b/lib/inspect-fs-cd.c
@@ -21,6 +21,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <libintl.h>
+#include <inttypes.h>
#ifdef HAVE_ENDIAN_H
#include <endian.h>
@@ -432,10 +434,72 @@ check_w2k3_installer_root (guestfs_h *g, struct inspect_fs *fs,
return 0;
}
+/* Read the data from a product.id-like file.
+ *
+ * This is an old file, mostly used in Mandriva-based systems (still including
+ * Mageia). A very minimal documentation for it is:
+ * - https://wiki.mageia.org/en/Product_id
+ * - http://wiki.mandriva.com/en/Product_id (old URL, defunct)
+ */
+static int
+check_product_id_installer_root (guestfs_h *g, struct inspect_fs *fs,
+ const char *filename)
+{
+ int64_t size;
+ CLEANUP_FREE_STRING_LIST char **lines = NULL;
+ const char *elem;
+ char *saveptr;
+
+ fs->type = OS_TYPE_LINUX;
+
+ /* Don't trust guestfs_head_n not to break with very large files.
+ * Check the file size is something reasonable first.
+ */
+ size = guestfs_filesize (g, filename);
+ if (size == -1)
+ /* guestfs_filesize failed and has already set error in handle */
+ return -1;
+ if (size > MAX_SMALL_FILE_SIZE) {
+ error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"),
+ filename, size);
+ return -1;
+ }
+
+ lines = guestfs_head_n (g, 1, filename);
+ if (lines == NULL)
+ return -1;
+
+ elem = strtok_r (lines[0], ",", &saveptr);
+ while (elem) {
+ const char *equal = strchr (elem, '=');
+ if (equal == NULL || equal == elem)
+ return -1;
+
+ const char *value = equal + 1;
+
+ if (STRPREFIX (elem, "distribution=")) {
+ if (STREQ (value, "Mageia"))
+ fs->distro = OS_DISTRO_MAGEIA;
+ } else if (STRPREFIX (elem, "version=")) {
+ if (guestfs_int_version_from_x_y_or_x (g, &fs->version, value) == -1)
+ return -1;
+ } else if (STRPREFIX (elem, "arch=")) {
+ fs->arch = safe_strdup (g, value);
+ }
+
+ elem = strtok_r (NULL, ",", &saveptr);
+ }
+
+ /* Not found. */
+ return 0;
+}
+
/* The currently mounted device is very likely to be an installer. */
int
guestfs_int_check_installer_root (guestfs_h *g, struct inspect_fs *fs)
{
+ CLEANUP_FREE_STRING_LIST char **paths = NULL;
+
/* The presence of certain files indicates a live CD.
*
* XXX Fedora netinst contains a ~120MB squashfs called
@@ -495,6 +559,18 @@ guestfs_int_check_installer_root (guestfs_h *g, struct inspect_fs *fs)
return -1;
}
+ /* Linux with /{i586,x86_64,etc}/product.id (typically found in Mandriva
+ * and Mageia). Usually there should be just one around, so we use the
+ * first one found.
+ */
+ paths = guestfs_glob_expand (g, "/*/product.id");
+ if (paths == NULL)
+ return -1;
+ if (paths[0] != NULL) {
+ if (check_product_id_installer_root (g, fs, paths[0]) == -1)
+ return -1;
+ }
+
return 0;
}
--
2.9.3
7 years, 9 months
[PATCH 0/5] dib: initial work to support d-i-b 2.0
by Pino Toscano
Hi,
this series start to implement some of the changes needed to support
d-i-b 2.0; normal VM distro builds seem to work correctly, ramdisk
builds are still broken and require more efforts.
Thanks,
Pino Toscano (5):
dib: implement get_image_element_array stuff
dib: export IMAGE_BLOCK_DEVICE_WITHOUT_PART
dib: extract get_required_tool out of require_tool
dib: require a Python interpreter
dib: implement IMAGE_ELEMENT_YAML
dib/cmdline.ml | 21 ++++++++++++++++++++-
dib/cmdline.mli | 1 +
dib/dib.ml | 44 ++++++++++++++++++++++++++++++++++++++++----
dib/utils.ml | 7 +++++--
dib/virt-dib.pod | 11 +++++++++++
5 files changed, 77 insertions(+), 7 deletions(-)
--
2.9.3
7 years, 9 months
[PATCH] bash: Add a bash completion script for virt-v2v-copy-to-local (RHBZ#1367738).
by Richard W.M. Jones
Thanks: Ming Xie
---
bash/Makefile.am | 3 ++-
bash/virt-v2v-copy-to-local | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 bash/virt-v2v-copy-to-local
diff --git a/bash/Makefile.am b/bash/Makefile.am
index 94a2d48..86fd816 100644
--- a/bash/Makefile.am
+++ b/bash/Makefile.am
@@ -22,7 +22,8 @@ scripts = \
guestmount \
virt-alignment-scan \
virt-rescue \
- virt-v2v
+ virt-v2v \
+ virt-v2v-copy-to-local
# Some of the scripts are simply symbolic links.
symlinks = \
diff --git a/bash/virt-v2v-copy-to-local b/bash/virt-v2v-copy-to-local
new file mode 100644
index 0000000..4442da2
--- /dev/null
+++ b/bash/virt-v2v-copy-to-local
@@ -0,0 +1,42 @@
+# virt-v2v-copy-to-local bash completion script -*- shell-script -*-
+# Copyright (C) 2014-2017 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+_virt_v2v_copy_to_local ()
+{
+ local cur prev words cword split
+ local shortopts longopts items
+
+ _init_completion -s || return
+
+ case "$cur" in
+ --*)
+ # --options
+ longopts="$(virt-v2v-copy-to-local --long-options)"
+ COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
+ return ;;
+ -*)
+ # -o and --options
+ shortopts="$(virt-v2v-copy-to-local --short-options)"
+ longopts="$(virt-v2v-copy-to-local --long-options)"
+ COMPREPLY=( $(compgen -W "$shortopts $longopts" -- "$cur") )
+ return ;;
+ *)
+ COMPREPLY=( $(compgen "$cur") )
+ return ;;
+ esac
+} &&
+complete -o default -F _virt_v2v_copy_to_local virt-v2v-copy-to-local
--
2.9.3
7 years, 9 months
Running virConnectGetCapabilities / virsh capabilities without a daemon or KVM
by Richard W.M. Jones
For virt-p2v we want to get the host CPU model, topology etc, and the
best way we found to do that was to pull it from libvirt
capabilities[1]. Since libvirt is already parsing the host CPU
information, and because /proc/cpuinfo is such a stupid format to
parse, this is very convenient.
Unfortunately it doesn't work unless libvirtd _and_ KVM are both
installed.
Without libvirtd installed:
# virsh capabilities
error: failed to connect to the hypervisor
error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory
With libvirt-daemon installed, but not QEMU:
# virsh capabilities
error: failed to connect to the hypervisor
error: no connection driver available for <null>
I feel I should be able to fiddle with the connection URI in some way
to make this possible, at least in the second case. However there's
not a concept of "no hypervisor", and I couldn't find any other way to
make it work. Using "test:///default" seems tempting, but it
substitutes some imaginary host (i686) so that's no good.
Installing KVM isn't really an option for us since we are trying to
build a minimal bootable ISO. Just installing qemu-system-x86_64
pulls in half the world. (Even installing libvirtd is difficult, and
we'd prefer to avoid it).
Any ideas?
Rich.
[1] https://github.com/libguestfs/libguestfs/commit/963d6c3be7cd91c0373f67cfd...
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
7 years, 9 months
[PATCH] p2v: gui: Change mnemonics so 's' is not used twice (RHBZ#1379289).
by Richard W.M. Jones
Change mnemonics so 's' is not used twice:
Start Conversion: 's' -> 'c'
Output Connection: 'c' -> 'o'
Output Storage: continues to use 's'
Thanks: Ming Xie.
---
p2v/gui.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/p2v/gui.c b/p2v/gui.c
index b850b2f10..464230645 100644
--- a/p2v/gui.c
+++ b/p2v/gui.c
@@ -785,7 +785,7 @@ create_conversion_dialog (struct config *config)
table_attach (output_tbl, o_combo,
1, 2, 0, 1, GTK_FILL, GTK_FILL, 1, 1);
- oc_label = gtk_label_new_with_mnemonic (_("Output _conn. (-oc):"));
+ oc_label = gtk_label_new_with_mnemonic (_("_Output conn. (-oc):"));
table_attach (output_tbl, oc_label,
0, 1, 1, 2, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (oc_label, 1., 0.5);
@@ -908,7 +908,7 @@ create_conversion_dialog (struct config *config)
/* Buttons. */
gtk_dialog_add_buttons (GTK_DIALOG (conv_dlg),
_("_Back"), 1,
- _("_Start conversion"), 2,
+ _("Start _conversion"), 2,
NULL);
back = gtk_dialog_get_widget_for_response (GTK_DIALOG (conv_dlg), 1);
start_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (conv_dlg), 2);
--
2.12.0
7 years, 9 months