libguestfs preview for RHEL 7.4
by Richard W.M. Jones
With the release of RHEL 7.3 happening today, fixing 88 reported bugs
in libguestfs and virt-v2v, and countless other ones, it's time to
look ahead to RHEL 7.4.
Again we intend to rebase libguestfs, virt-v2v and virt-p2v:
https://bugzilla.redhat.com/show_bug.cgi?id=1359086
1359086 NEW Rebase libguestfs in RHEL 7.4
To help with testing I have set up a preview repository here:
http://people.redhat.com/~rjones/libguestfs-RHEL-7.4-preview/
As always:
(1) THE PACKAGES ARE NOT SUPPORTED! Do not contact Red Hat Support
about these packages. However you are welcome to file bugs or send
comments to <libguestfs(a)redhat.com>. The link for filing bugs is:
https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Enterprise%...
(2) These packages should work on top of RHEL 7.3 or CentOS 7.3.
(3) To install the packages you should create a yum repo file like the
one below, and then use yum commands as normal:
$ cat /etc/yum.repos.d/libguestfs-RHEL-7.4-preview.repo
[libguestfs-RHEL-7.4-preview]
name=libguestfs RHEL 7.4 preview
baseurl=http://people.redhat.com/~rjones/libguestfs-RHEL-7.4-preview/
enabled=1
gpgcheck=0
Notable changes in packaging:
- The 'virt-v2v' package now only includes virt-v2v, not virt-p2v.
- To build your own virt-p2v bootable USB key, install 'virt-p2v-maker'.
- virt-v2v installs Windows virtio drivers using a new technique
which tries to make the minimal possible changes to the Windows
registry. This may create exciting new bugs, so I'm particularly
interested in further testing in this area.
- There is currently a bogus dependency on 'kernel-rt' which
shouldn't be there ... under investigation.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html
7 years, 9 months
[PATCH v2 0/5] Import directly from OVA tar archive if possible
by Tomáš Golembiovský
This series is related to the problem of inefficient import of OVA
files. The needed enhancements of QEMU were merged into the codebase and
should be available in QEMU 2.8. From there we can use 'size' and
'offset' options in raw driver to tell QEMU to use only subset of a file
as an image.
The patch set is more or less complete. The only outstanding issue is
the missing detection of sparse files inside tar. But this can be done
in a separate patch. As pointed out before I didn't find a way how to
detect that by using the tar tool only and would probably require use of
some external library.
The first three patches are just preparation. The main work is in patch
four. Last patch fixes the tests.
v2:
- rewritten the tar invocations, the output processing is now done in
OcaML rather than with a shell code; it turned out to be easier and
more readable than I have feared.
- added QEMU version check
- addressed Pino's comments
- changed tests; the expected result is now based on the QEMU used
during testing
Tomáš Golembiovský (5):
mllib: compute checksum of file inside tar
v2v: ova: don't detect compressed disks, read the OVF instead
v2v: ova: move the untar function
v2v: ova: don't extract files from OVA if it's not needed
v2v: update tests to match changes in OVA import
mllib/checksums.ml | 11 +-
mllib/checksums.mli | 2 +-
test-data/utils.sh | 21 ++++
v2v/Makefile.am | 1 +
v2v/input_ova.ml | 184 +++++++++++++++++++++++++++-----
v2v/test-v2v-i-ova-formats.sh | 5 +-
v2v/test-v2v-i-ova-gz.ovf | 2 +-
v2v/test-v2v-i-ova-subfolders.expected2 | 18 ++++
v2v/test-v2v-i-ova-subfolders.sh | 12 ++-
v2v/test-v2v-i-ova-tar.expected | 18 ++++
v2v/test-v2v-i-ova-tar.expected2 | 18 ++++
v2v/test-v2v-i-ova-tar.ovf | 138 ++++++++++++++++++++++++
v2v/test-v2v-i-ova-tar.sh | 70 ++++++++++++
v2v/test-v2v-i-ova-two-disks.expected2 | 19 ++++
v2v/test-v2v-i-ova-two-disks.sh | 12 ++-
15 files changed, 493 insertions(+), 38 deletions(-)
create mode 100755 test-data/utils.sh
create mode 100644 v2v/test-v2v-i-ova-subfolders.expected2
create mode 100644 v2v/test-v2v-i-ova-tar.expected
create mode 100644 v2v/test-v2v-i-ova-tar.expected2
create mode 100644 v2v/test-v2v-i-ova-tar.ovf
create mode 100755 v2v/test-v2v-i-ova-tar.sh
create mode 100644 v2v/test-v2v-i-ova-two-disks.expected2
--
2.10.1
8 years
[PATCH 1/3] generator: c: move internal functions
by Pino Toscano
Move the generate_all_structs and generate_all_headers functions,
previously internal within the implementation of generate_guestfs_h, to
be usable by other functions in the same "C" module (but not public).
Only code motion.
---
generator/c.ml | 163 +++++++++++++++++++++++++++++----------------------------
1 file changed, 82 insertions(+), 81 deletions(-)
diff --git a/generator/c.ml b/generator/c.ml
index 6f5a517..f0df5ea 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -585,21 +585,85 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
/* Structures. */
";
- (* The structures are carefully written to have exactly the same
- * in-memory format as the XDR structures that we use on the wire to
- * the daemon. The reason for creating copies of these structures
- * here is just so we don't have to export the whole of
- * guestfs_protocol.h (which includes much unrelated and
- * XDR-dependent stuff that we don't want to be public, or required
- * by clients).
- *
- * To reiterate, we will pass these structures to and from the client
- * with a simple assignment or memcpy, so the format must be
- * identical to what rpcgen / the RFC defines.
- *)
-
(* Public structures. *)
- let generate_all_structs = List.iter (
+ generate_all_structs external_structs;
+
+ pr "\
+/* Actions. */
+";
+
+ generate_all_headers public_functions_sorted;
+
+ pr "\
+#if GUESTFS_PRIVATE
+/* Symbols protected by GUESTFS_PRIVATE are NOT part of the public,
+ * stable API, and can change at any time! We export them because
+ * they are used by some of the language bindings.
+ */
+
+/* Private functions. */
+
+";
+
+ generate_all_headers private_functions_sorted;
+
+ pr "\
+/* Private structures. */
+
+";
+
+ generate_all_structs internal_structs;
+
+pr "\
+
+#endif /* End of GUESTFS_PRIVATE. */
+
+/* Deprecated macros. Use GUESTFS_HAVE_* instead. */
+
+#define LIBGUESTFS_HAVE_CREATE_FLAGS 1
+#define LIBGUESTFS_HAVE_LAST_ERRNO 1
+#define LIBGUESTFS_HAVE_PUSH_ERROR_HANDLER 1
+#define LIBGUESTFS_HAVE_POP_ERROR_HANDLER 1
+#define LIBGUESTFS_HAVE_SET_EVENT_CALLBACK 1
+#define LIBGUESTFS_HAVE_DELETE_EVENT_CALLBACK 1
+#define LIBGUESTFS_HAVE_SET_CLOSE_CALLBACK 1
+#define LIBGUESTFS_HAVE_SET_PROGRESS_CALLBACK 1
+#define LIBGUESTFS_HAVE_SET_PRIVATE 1
+#define LIBGUESTFS_HAVE_GET_PRIVATE 1
+#define LIBGUESTFS_HAVE_FIRST_PRIVATE 1
+#define LIBGUESTFS_HAVE_NEXT_PRIVATE 1
+
+";
+
+ List.iter (
+ fun { name = shortname } ->
+ pr "#define LIBGUESTFS_HAVE_%s 1\n" (String.uppercase shortname);
+ ) public_functions_sorted;
+
+ pr "
+/* End of deprecated macros. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GUESTFS_H_ */
+"
+
+(* The structures are carefully written to have exactly the same
+ * in-memory format as the XDR structures that we use on the wire to
+ * the daemon. The reason for creating copies of these structures
+ * here is just so we don't have to export the whole of
+ * guestfs_protocol.h (which includes much unrelated and
+ * XDR-dependent stuff that we don't want to be public, or required
+ * by clients).
+ *
+ * To reiterate, we will pass these structures to and from the client
+ * with a simple assignment or memcpy, so the format must be
+ * identical to what rpcgen / the RFC defines.
+ *)
+and generate_all_structs structs =
+ List.iter (
fun { s_name = typ; s_cols = cols } ->
pr "#define GUESTFS_HAVE_STRUCT_%s 1\n" (String.uppercase typ);
pr "\n";
@@ -634,14 +698,9 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
pr "extern GUESTFS_DLL_PUBLIC void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
pr "extern GUESTFS_DLL_PUBLIC void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
pr "\n"
- ) in
-
- generate_all_structs external_structs;
-
- pr "\
-/* Actions. */
-";
+ ) structs
+and generate_all_headers actions =
let generate_action_header { name = shortname;
style = ret, args, optargs as style;
deprecated_by = deprecated_by } =
@@ -700,7 +759,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
pr "\n"
in
- let generate_all_headers = List.iter (
+ List.iter (
fun ({ name = name; style = ret, args, _ } as f) ->
(* If once_had_no_optargs is set, then we need to generate a
* <name>_opts variant, plus a backwards-compatible wrapper
@@ -712,65 +771,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
)
else
generate_action_header f
- ) in
-
- generate_all_headers public_functions_sorted;
-
- pr "\
-#if GUESTFS_PRIVATE
-/* Symbols protected by GUESTFS_PRIVATE are NOT part of the public,
- * stable API, and can change at any time! We export them because
- * they are used by some of the language bindings.
- */
-
-/* Private functions. */
-
-";
-
- generate_all_headers private_functions_sorted;
-
- pr "\
-/* Private structures. */
-
-";
-
- generate_all_structs internal_structs;
-
-pr "\
-
-#endif /* End of GUESTFS_PRIVATE. */
-
-/* Deprecated macros. Use GUESTFS_HAVE_* instead. */
-
-#define LIBGUESTFS_HAVE_CREATE_FLAGS 1
-#define LIBGUESTFS_HAVE_LAST_ERRNO 1
-#define LIBGUESTFS_HAVE_PUSH_ERROR_HANDLER 1
-#define LIBGUESTFS_HAVE_POP_ERROR_HANDLER 1
-#define LIBGUESTFS_HAVE_SET_EVENT_CALLBACK 1
-#define LIBGUESTFS_HAVE_DELETE_EVENT_CALLBACK 1
-#define LIBGUESTFS_HAVE_SET_CLOSE_CALLBACK 1
-#define LIBGUESTFS_HAVE_SET_PROGRESS_CALLBACK 1
-#define LIBGUESTFS_HAVE_SET_PRIVATE 1
-#define LIBGUESTFS_HAVE_GET_PRIVATE 1
-#define LIBGUESTFS_HAVE_FIRST_PRIVATE 1
-#define LIBGUESTFS_HAVE_NEXT_PRIVATE 1
-
-";
-
- List.iter (
- fun { name = shortname } ->
- pr "#define LIBGUESTFS_HAVE_%s 1\n" (String.uppercase shortname);
- ) public_functions_sorted;
-
- pr "
-/* End of deprecated macros. */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GUESTFS_H_ */
-"
+ ) actions
(* Generate the guestfs-internal-actions.h file. *)
and generate_internal_actions_h () =
--
2.7.4
8 years
[PATCH 1/2] libvirt: un-duplicate XPath code
by Pino Toscano
Move the checks for empty xmlXPathObjectPtr, and for extracting the
result string out of it, to a new helper functions.
This is just code motion, there should be no behaviour changes.
---
src/libvirt-domain.c | 122 +++++++++++++++++++++------------------------------
1 file changed, 50 insertions(+), 72 deletions(-)
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 4d4142d..baab307 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -43,6 +43,8 @@ static xmlDocPtr get_domain_xml (guestfs_h *g, virDomainPtr dom);
static ssize_t for_each_disk (guestfs_h *g, virConnectPtr conn, xmlDocPtr doc, int (*f) (guestfs_h *g, const char *filename, const char *format, int readonly, const char *protocol, char *const *server, const char *username, void *data), void *data);
static int libvirt_selinux_label (guestfs_h *g, xmlDocPtr doc, char **label_rtn, char **imagelabel_rtn);
static char *filename_from_pool (guestfs_h *g, virConnectPtr conn, const char *pool_nane, const char *volume_name);
+static bool xPathObjectIsEmpty (xmlXPathObjectPtr obj);
+static char *xPathObjectGetString (xmlDocPtr doc, xmlXPathObjectPtr obj);
static void
ignore_errors (void *ignore, virErrorPtr ignore2)
@@ -513,7 +515,6 @@ for_each_disk (guestfs_h *g,
CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xpusername = NULL;
CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xppool = NULL;
CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xpvolume = NULL;
- xmlAttrPtr attr;
int readonly;
int t;
@@ -527,31 +528,21 @@ for_each_disk (guestfs_h *g,
* Check the <disk type=..> attribute first to find out which one.
*/
xptype = xmlXPathEvalExpression (BAD_CAST "./@type", xpathCtx);
- if (xptype == NULL ||
- xptype->nodesetval == NULL ||
- xptype->nodesetval->nodeNr == 0) {
+ if (xPathObjectIsEmpty (xptype))
continue; /* no type attribute, skip it */
- }
- assert (xptype->nodesetval->nodeTab[0]);
- assert (xptype->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xptype->nodesetval->nodeTab[0];
- type = (char *) xmlNodeListGetString (doc, attr->children, 1);
+ type = xPathObjectGetString (doc, xptype);
if (STREQ (type, "file")) { /* type = "file" so look at source/@file */
xpathCtx->node = nodes->nodeTab[i];
xpfilename = xmlXPathEvalExpression (BAD_CAST "./source/@file",
xpathCtx);
- if (xpfilename == NULL ||
- xpfilename->nodesetval == NULL ||
- xpfilename->nodesetval->nodeNr == 0)
+ if (xPathObjectIsEmpty (xpfilename))
continue; /* disk filename not found, skip this */
} else if (STREQ (type, "block")) { /* type = "block", use source/@dev */
xpathCtx->node = nodes->nodeTab[i];
xpfilename = xmlXPathEvalExpression (BAD_CAST "./source/@dev",
xpathCtx);
- if (xpfilename == NULL ||
- xpfilename->nodesetval == NULL ||
- xpfilename->nodesetval->nodeNr == 0)
+ if (xPathObjectIsEmpty (xpfilename))
continue; /* disk filename not found, skip this */
} else if (STREQ (type, "network")) { /* type = "network", use source/@name */
int hi;
@@ -562,15 +553,9 @@ for_each_disk (guestfs_h *g,
/* Get the protocol (e.g. "rbd"). Required. */
xpprotocol = xmlXPathEvalExpression (BAD_CAST "./source/@protocol",
xpathCtx);
- if (xpprotocol == NULL ||
- xpprotocol->nodesetval == NULL ||
- xpprotocol->nodesetval->nodeNr == 0)
+ if (xPathObjectIsEmpty (xpprotocol))
continue;
- assert (xpprotocol->nodesetval->nodeTab[0]);
- assert (xpprotocol->nodesetval->nodeTab[0]->type ==
- XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xpprotocol->nodesetval->nodeTab[0];
- protocol = (char *) xmlNodeListGetString (doc, attr->children, 1);
+ protocol = xPathObjectGetString (doc, xpprotocol);
debug (g, "disk[%zu]: protocol: %s", i, protocol);
/* <source name="..."> is the path/exportname. Optional. */
@@ -583,13 +568,8 @@ for_each_disk (guestfs_h *g,
/* <auth username="...">. Optional. */
xpusername = xmlXPathEvalExpression (BAD_CAST "./auth/@username",
xpathCtx);
- if (xpusername != NULL &&
- xpusername->nodesetval != NULL &&
- xpusername->nodesetval->nodeNr != 0) {
- assert (xpusername->nodesetval->nodeTab[0]);
- assert (xpusername->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xpusername->nodesetval->nodeTab[0];
- username = (char *) xmlNodeListGetString (doc, attr->children, 1);
+ if (!xPathObjectIsEmpty (xpusername)) {
+ username = xPathObjectGetString (doc, xpusername);
debug (g, "disk[%zu]: username: %s", i, username);
}
@@ -641,28 +621,16 @@ for_each_disk (guestfs_h *g,
/* Get the source pool. Required. */
xppool = xmlXPathEvalExpression (BAD_CAST "./source/@pool",
xpathCtx);
- if (xppool == NULL ||
- xppool->nodesetval == NULL ||
- xppool->nodesetval->nodeNr == 0)
+ if (xPathObjectIsEmpty (xppool))
continue;
- assert (xppool->nodesetval->nodeTab[0]);
- assert (xppool->nodesetval->nodeTab[0]->type ==
- XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xppool->nodesetval->nodeTab[0];
- pool = (char *) xmlNodeListGetString (doc, attr->children, 1);
+ pool = xPathObjectGetString (doc, xppool);
/* Get the source volume. Required. */
xpvolume = xmlXPathEvalExpression (BAD_CAST "./source/@volume",
xpathCtx);
- if (xpvolume == NULL ||
- xpvolume->nodesetval == NULL ||
- xpvolume->nodesetval->nodeNr == 0)
+ if (xPathObjectIsEmpty (xpvolume))
continue;
- assert (xpvolume->nodesetval->nodeTab[0]);
- assert (xpvolume->nodesetval->nodeTab[0]->type ==
- XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xpvolume->nodesetval->nodeTab[0];
- volume = (char *) xmlNodeListGetString (doc, attr->children, 1);
+ volume = xPathObjectGetString (doc, xpvolume);
debug (g, "disk[%zu]: pool: %s; volume: %s", i, pool, volume);
@@ -679,13 +647,8 @@ for_each_disk (guestfs_h *g,
if (filename == NULL) {
assert (xpfilename);
assert (xpfilename->nodesetval);
- if (xpfilename->nodesetval->nodeNr > 0) {
- assert (xpfilename->nodesetval->nodeTab[0]);
- assert (xpfilename->nodesetval->nodeTab[0]->type ==
- XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xpfilename->nodesetval->nodeTab[0];
- filename = (char *) xmlNodeListGetString (doc, attr->children, 1);
- }
+ if (xpfilename->nodesetval->nodeNr > 0)
+ filename = xPathObjectGetString (doc, xpfilename);
else
/* For network protocols (eg. nbd), name may be omitted. */
filename = safe_strdup (g, "");
@@ -696,22 +659,14 @@ for_each_disk (guestfs_h *g,
/* Get the disk format (may not be set). */
xpathCtx->node = nodes->nodeTab[i];
xpformat = xmlXPathEvalExpression (BAD_CAST "./driver/@type", xpathCtx);
- if (xpformat != NULL &&
- xpformat->nodesetval &&
- xpformat->nodesetval->nodeNr > 0) {
- assert (xpformat->nodesetval->nodeTab[0]);
- assert (xpformat->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xpformat->nodesetval->nodeTab[0];
- format = (char *) xmlNodeListGetString (doc, attr->children, 1);
- }
+ if (!xPathObjectIsEmpty (xpformat))
+ format = xPathObjectGetString (doc, xpformat);
/* Get the <readonly/> flag. */
xpathCtx->node = nodes->nodeTab[i];
xpreadonly = xmlXPathEvalExpression (BAD_CAST "./readonly", xpathCtx);
readonly = 0;
- if (xpreadonly != NULL &&
- xpreadonly->nodesetval &&
- xpreadonly->nodesetval->nodeNr > 0)
+ if (!xPathObjectIsEmpty (xpreadonly))
readonly = 1;
if (f)
@@ -774,23 +729,17 @@ connect_live (guestfs_h *g, virDomainPtr dom)
if (nodes != NULL) {
for (i = 0; i < nodes->nodeNr; ++i) {
CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xppath = NULL;
- xmlAttrPtr attr;
/* See note in function above. */
xpathCtx->node = nodes->nodeTab[i];
/* The path is in <source path=..> attribute. */
xppath = xmlXPathEvalExpression (BAD_CAST "./source/@path", xpathCtx);
- if (xppath == NULL ||
- xppath->nodesetval == NULL ||
- xppath->nodesetval->nodeNr == 0) {
+ if (xPathObjectIsEmpty (xppath)) {
xmlXPathFreeObject (xppath);
continue; /* no type attribute, skip it */
}
- assert (xppath->nodesetval->nodeTab[0]);
- assert (xppath->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE);
- attr = (xmlAttrPtr) xppath->nodesetval->nodeTab[0];
- path = (char *) xmlNodeListGetString (doc, attr->children, 1);
+ path = xPathObjectGetString (doc, xppath);
break;
}
}
@@ -888,6 +837,35 @@ filename_from_pool (guestfs_h *g, virConnectPtr conn,
return filename;
}
+/* Check that C<obj> is not empty.
+ */
+static bool
+xPathObjectIsEmpty (xmlXPathObjectPtr obj)
+{
+ return obj == NULL ||
+ obj->nodesetval == NULL ||
+ obj->nodesetval->nodeNr == 0;
+}
+
+/* Get the string value from C<obj>.
+ *
+ * C<obj> is I<required> to not be empty, i.e. that C<xPathObjectIsEmpty>
+ * is C<false>.
+ */
+static char *
+xPathObjectGetString (xmlDocPtr doc, xmlXPathObjectPtr obj)
+{
+ xmlAttrPtr attr;
+ char *value;
+
+ assert (obj->nodesetval->nodeTab[0]);
+ assert (obj->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE);
+ attr = (xmlAttrPtr) obj->nodesetval->nodeTab[0];
+ value = (char *) xmlNodeListGetString (doc, attr->children, 1);
+
+ return value;
+}
+
#else /* no libvirt at compile time */
#define NOT_IMPL(r) \
--
2.7.4
8 years
[PATCH 1/2] daemon: allow to change the labels of swap partitions
by Pino Toscano
---
daemon/daemon.h | 1 +
daemon/labels.c | 3 +++
daemon/swap.c | 21 +++++++++++++++++++++
generator/actions.ml | 4 ++++
4 files changed, 29 insertions(+)
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 79a5288..2379e31 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -254,6 +254,7 @@ extern int64_t ntfs_minimum_size (const char *device);
/*-- in swap.c --*/
extern int swap_set_uuid (const char *device, const char *uuid);
+extern int swap_set_label (const char *device, const char *label);
/* ordinary daemon functions use these to indicate errors
* NB: you don't need to prefix the string with the current command,
diff --git a/daemon/labels.c b/daemon/labels.c
index 20f27cb..aaa3eaf 100644
--- a/daemon/labels.c
+++ b/daemon/labels.c
@@ -85,6 +85,9 @@ do_set_label (const mountable_t *mountable, const char *label)
else if (STREQ (vfs_type, "xfs"))
r = xfslabel (mountable->device, label);
+ else if (STREQ (vfs_type, "swap"))
+ r = swap_set_label (mountable->device, label);
+
else
NOT_SUPPORTED (-1, "don't know how to set the label for '%s' filesystems",
vfs_type);
diff --git a/daemon/swap.c b/daemon/swap.c
index 9d7839e..028bc1e 100644
--- a/daemon/swap.c
+++ b/daemon/swap.c
@@ -239,3 +239,24 @@ swap_set_uuid (const char *device, const char *uuid)
return 0;
}
+
+int
+swap_set_label (const char *device, const char *label)
+{
+ int r;
+ CLEANUP_FREE char *err = NULL;
+
+ if (strlen (label) > SWAP_LABEL_MAX) {
+ reply_with_error ("%s: Linux swap labels are limited to %d bytes",
+ label, SWAP_LABEL_MAX);
+ return -1;
+ }
+
+ r = command (NULL, &err, str_swaplabel, "-L", label, device, NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 43de38b..5e0356f 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -10304,6 +10304,10 @@ when trying to set the label.
The label is limited to 11 bytes.
+=item swap
+
+The label is limited to 16 bytes.
+
=back
If there is no support for changing the label
--
2.7.4
8 years
[PATCH 1/2] kernel: refactor build_kernel & find_kernel
by Pino Toscano
Move the handling of the SUPERMIN_* envvars, and the kernel copy/symlink
out of find_kernel to build_kernel: this way find_kernel does only the
search. Also, the modules path search is done in by find_kernel as
well.
This is mostly code motion, with no behaviour changes.
---
src/kernel.ml | 89 +++++++++++++++++++++++++++++------------------------------
1 file changed, 44 insertions(+), 45 deletions(-)
diff --git a/src/kernel.ml b/src/kernel.ml
index 9b0e8a2..2e061d8 100644
--- a/src/kernel.ml
+++ b/src/kernel.ml
@@ -40,28 +40,7 @@ let patt_of_cpu host_cpu =
let rec build_kernel debug host_cpu dtb_wildcard copy_kernel kernel dtb =
(* Locate the kernel. *)
- let kernel_name, kernel_version =
- find_kernel debug host_cpu copy_kernel kernel in
-
- (* If the user passed --dtb option, locate dtb. *)
- (match dtb_wildcard with
- | None -> ()
- | Some wildcard ->
- find_dtb debug copy_kernel kernel_name wildcard dtb
- );
-
- (* Get the kernel modules. *)
- let modpath = find_modpath debug kernel_version in
-
- if debug >= 1 then (
- printf "supermin: kernel: kernel_version %s\n" kernel_version;
- printf "supermin: kernel: modules %s\n%!" modpath;
- );
-
- (kernel_version, modpath)
-
-and find_kernel debug host_cpu copy_kernel kernel =
- let kernel_file, kernel_name, kernel_version =
+ let kernel_file, kernel_name, kernel_version, modpath =
try
let kernel_env = getenv "SUPERMIN_KERNEL" in
if debug >= 1 then
@@ -78,38 +57,58 @@ and find_kernel debug host_cpu copy_kernel kernel =
printf "supermin: kernel: SUPERMIN_KERNEL version %s\n%!"
kernel_version;
let kernel_name = Filename.basename kernel_env in
- kernel_env, kernel_name, kernel_version
+ let modpath = find_modpath debug kernel_version in
+ kernel_env, kernel_name, kernel_version, modpath
with Not_found ->
- let is_arm =
- String.length host_cpu >= 3 &&
- host_cpu.[0] = 'a' && host_cpu.[1] = 'r' && host_cpu.[2] = 'm' in
+ find_kernel debug host_cpu kernel in
- let all_files = Sys.readdir "/boot" in
- let all_files = Array.to_list all_files in
+ (* If the user passed --dtb option, locate dtb. *)
+ (match dtb_wildcard with
+ | None -> ()
+ | Some wildcard ->
+ find_dtb debug copy_kernel kernel_name wildcard dtb
+ );
- (* In original: ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen *)
- let patterns = patt_of_cpu host_cpu in
- let files = kernel_filter patterns is_arm all_files in
+ if debug >= 1 then (
+ printf "supermin: kernel: kernel_version %s\n" kernel_version;
+ printf "supermin: kernel: modules %s\n%!" modpath;
+ );
- let files =
- if files <> [] then files
- else
- (* In original: ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen *)
- kernel_filter ["vmlinu?-*"] is_arm all_files in
+ copy_or_symlink_file copy_kernel kernel_file kernel;
- if files = [] then no_kernels host_cpu;
+ (kernel_version, modpath)
- let files = List.sort (fun a b -> compare_version b a) files in
- let kernel_name = List.hd files in
- let kernel_version = get_kernel_version kernel_name in
+and find_kernel debug host_cpu kernel =
+ let is_arm =
+ String.length host_cpu >= 3 &&
+ host_cpu.[0] = 'a' && host_cpu.[1] = 'r' && host_cpu.[2] = 'm' in
- if debug >= 1 then
- printf "supermin: kernel: picked kernel %s\n%!" kernel_name;
+ let all_files = Sys.readdir "/boot" in
+ let all_files = Array.to_list all_files in
- ("/boot" // kernel_name), kernel_name, kernel_version in
+ (* In original: ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen *)
+ let patterns = patt_of_cpu host_cpu in
+ let files = kernel_filter patterns is_arm all_files in
- copy_or_symlink_file copy_kernel kernel_file kernel;
- kernel_name, kernel_version
+ let files =
+ if files <> [] then files
+ else
+ (* In original: ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen *)
+ kernel_filter ["vmlinu?-*"] is_arm all_files in
+
+ if files = [] then no_kernels host_cpu;
+
+ let files = List.sort (fun a b -> compare_version b a) files in
+ let kernel_name = List.hd files in
+ let kernel_version = get_kernel_version kernel_name in
+
+ if debug >= 1 then
+ printf "supermin: kernel: picked kernel %s\n%!" kernel_name;
+
+ (* Get the kernel modules. *)
+ let modpath = find_modpath debug kernel_version in
+
+ ("/boot" // kernel_name), kernel_name, kernel_version, modpath
and kernel_filter patterns is_arm all_files =
let files =
--
2.7.4
8 years
libguestfs and exporting to OVA/OVF
by Emmanuel Kasper
Hi
I've been looking for a standalone tool to create OVA/OVF VM files based
on a disk image and found none. So I was thinking to write my own.
Would you be interested in having such a tool in the libguestfs umbrella ?
My aim is too have a free toolchain to build VirtualBox images for
Debian (for Vagrant to be more exact, see
https://wiki.debian.org/Teams/Cloud/VagrantBaseBoxes)
Interface for such a tool would be something like
disk2ova --memory 2G --controller sata --network E1000
myDiskImage.{raw,qcow2}
based on the command line switches, a XML ovf would be created and
packed with the disk image in a OVA file.
There is some python code around which does that, for example the ganeti
export code and imagefactory
https://github.com/redhat-imaging/imagefactory/blob/master/imagefactory_p...
but nothing available as a standalone tool.
I am afraid I can only contribute Perl code.
Emmanuel
8 years
[PATCH] packagelist: add initviocons package on SUSE
by Cédric Bosdonnat
initviocons package provides tools to resize the terminal. Having it
in the appliance will allow SUSE users to have proper line wrapping
in their terminal when using virt-rescue.
---
appliance/packagelist.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index f278f66..bbbe4b2 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -139,6 +139,7 @@ ifelse(SUSE,1,
glibc-locale
gptfdisk
hivex
+ initviocons
iproute2
iputils
libcap2
--
2.10.2
8 years
[PATCH] v2v: -o vdsm, -o rhev: Don't create compat=0.10 images;
by Richard W.M. Jones
Support for RHEV with RHEL 6 nodes required us to output the old style
qcow2 compat=0.10 images. Since RHEV 3.6 GA, RHEL 6 has not been
supported as a RHEV node type.
There are significant downsides to using qcow2 compat=0.10 instead of
the modern default (compat=1.1), so stop forcing compat=0.10 for these
targets.
Thanks: Yaniv Kaul, Michal Skrivanek.
---
v2v/output_rhev.ml | 4 ----
v2v/output_vdsm.ml | 10 ----------
2 files changed, 14 deletions(-)
diff --git a/v2v/output_rhev.ml b/v2v/output_rhev.ml
index e45043b..3280150 100644
--- a/v2v/output_rhev.ml
+++ b/v2v/output_rhev.ml
@@ -248,10 +248,6 @@ object
Changeuid.func changeuid_t (
fun () ->
let g = open_guestfs ~identifier:"rhev_disk_create" () in
- (* For qcow2, override v2v-supplied compat option, because RHEL 6
- * nodes cannot handle qcow2 v3 (RHBZ#1145582).
- *)
- let compat = if format <> "qcow2" then compat else Some "0.10" in
g#disk_create ?backingfile ?backingformat ?preallocation ?compat
?clustersize path format size;
(* Make it sufficiently writable so that possibly root, or
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
index 7cd94c0..92ce5c0 100644
--- a/v2v/output_vdsm.ml
+++ b/v2v/output_vdsm.ml
@@ -145,16 +145,6 @@ object
(* Return the list of targets. *)
targets
- method disk_create ?backingfile ?backingformat ?preallocation ?compat
- ?clustersize path format size =
- let g = open_guestfs ~identifier:"vdsm_disk_create" () in
- (* For qcow2, override v2v-supplied compat option, because RHEL 6
- * nodes cannot handle qcow2 v3 (RHBZ#1145582).
- *)
- let compat = if format <> "qcow2" then compat else Some "0.10" in
- g#disk_create ?backingfile ?backingformat ?preallocation ?compat
- ?clustersize path format size
-
(* This is called after conversion to write the OVF metadata. *)
method create_metadata source targets _ guestcaps inspect target_firmware =
(* See #supported_firmware above. *)
--
2.10.2
8 years
[PATCH] appliance: move virt-rescue welcome to /etc/issue
by Cédric Bosdonnat
To allow easier downstream tweaks to the virt-rescue welcome message,
just output the content of the /etc/issue file in the appliance.
Thus, a new extras.tar.gz file appeared in supermin.d containing
the etc/issue file and future tweaks like this one.
---
appliance/Makefile.am | 11 +++++++++++
appliance/init | 11 ++---------
appliance/issue | 9 +++++++++
3 files changed, 22 insertions(+), 9 deletions(-)
create mode 100644 appliance/issue
diff --git a/appliance/Makefile.am b/appliance/Makefile.am
index e23778e..f26c4d4 100644
--- a/appliance/Makefile.am
+++ b/appliance/Makefile.am
@@ -36,6 +36,7 @@ EXTRA_DIST = \
guestfs_shadow.aug \
hostfiles.in \
init \
+ issue \
libguestfs-make-fixed-appliance.in \
libguestfs-make-fixed-appliance.pod \
make.sh.in \
@@ -49,6 +50,7 @@ superminfs_DATA = \
supermin.d/base.tar.gz \
supermin.d/daemon.tar.gz \
supermin.d/excludefiles \
+ supermin.d/extras.tar.gz \
supermin.d/hostfiles \
supermin.d/init.tar.gz \
supermin.d/packages \
@@ -107,6 +109,15 @@ supermin.d/excludefiles: excludefiles.in Makefile
cmp -s $@ excludefiles-t || mv excludefiles-t $@
rm -f excludefiles-t
+supermin.d/extras.tar.gz: issue
+ rm -f $@ $@-t
+ rm -rf tmp-d
+ mkdir -p tmp-d/etc
+ cp issue tmp-d/etc
+ ( cd tmp-d && tar zcf - * ) > $@-t
+ rm -r tmp-d
+ mv $@-t $@
+
supermin.d/hostfiles: hostfiles.in Makefile
m4 $(PACKAGELIST_CPP_FLAGS) $< | \
grep -v '^[[:space:]]*$$' | grep -v '^#' > hostfiles-t
diff --git a/appliance/init b/appliance/init
index 3816dfd..e549df0 100755
--- a/appliance/init
+++ b/appliance/init
@@ -184,15 +184,8 @@ else
echo "PS1='><rescue> '" >> $HOME/.bashrc
echo "export TERM PS1" >> $HOME/.bashrc
- echo
- echo "------------------------------------------------------------"
- echo
- echo "Welcome to virt-rescue, the libguestfs rescue shell."
- echo
- echo "Note: The contents of / are the rescue appliance."
- echo "You have to mount the guest's partitions under /sysroot"
- echo "before you can examine them."
- echo
+ cat /etc/issue
+
bash -i
echo
echo "virt-rescue: Syncing the disk now before exiting ..."
diff --git a/appliance/issue b/appliance/issue
new file mode 100644
index 0000000..40b8e17
--- /dev/null
+++ b/appliance/issue
@@ -0,0 +1,9 @@
+
+------------------------------------------------------------
+
+Welcome to virt-rescue, the libguestfs rescue shell.
+
+Note: The contents of / are the rescue appliance.
+You have to mount the guest's partitions under /sysroot
+before you can examine them.
+
--
2.6.6
8 years