[PATCH 1/6] launch: unix: check for length of sockets
by Pino Toscano
Error out early if the path to the socket will not fit into
sockaddr_un::sun_path, as we will not be able to connect to it.
---
src/launch-unix.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/launch-unix.c b/src/launch-unix.c
index 740c554..973e14b 100644
--- a/src/launch-unix.c
+++ b/src/launch-unix.c
@@ -47,6 +47,12 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath)
return -1;
}
+ if (strlen (sockpath) > UNIX_PATH_MAX-1) {
+ error (g, _("socket filename too long (more than %d characters): %s"),
+ UNIX_PATH_MAX-1, sockpath);
+ return -1;
+ }
+
if (g->verbose)
guestfs_int_print_timestamped_message (g, "connecting to %s", sockpath);
--
2.5.0
8 years, 10 months
[PATCH] inotify_add_watch: pass IN_ALL_EVENTS as mask for test
by Pino Toscano
Instead of pass 0x3fffffff as mask value, pass a simplier 0xfff, which
is the value of the IN_ALL_EVENTS define. This will still catch all
the inotify events, and avoid a EINVAL error with Linux 4.4.
---
generator/actions.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/generator/actions.ml b/generator/actions.ml
index 0d227cf..24c6eb7 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -7274,7 +7274,7 @@ per libguestfs instance." };
InitScratchFS, Always, TestResult (
[["mkdir"; "/inotify_add_watch"];
["inotify_init"; "0"];
- ["inotify_add_watch"; "/inotify_add_watch"; "1073741823"];
+ ["inotify_add_watch"; "/inotify_add_watch"; "4095"];
["touch"; "/inotify_add_watch/a"];
["touch"; "/inotify_add_watch/b"];
["inotify_files"]],
--
2.5.0
8 years, 11 months
[PATCH] lvm: support lvm2 older than 2.02.107
by Pino Toscano
lvm2 2.02.107 adds the -S/--select option used in lvs to filter out only
public LVs (see RHBZ#1278878). To make this work again with versions
of lvm2 older than that, only on old versions filter out thin layouts
and compose the resulting device strings ourselves.
The filtering done is much simplier than what "-S lv_role=public" will
do, but should be good enough for our need.
---
daemon/lvm.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 140 insertions(+), 10 deletions(-)
diff --git a/daemon/lvm.c b/daemon/lvm.c
index 979cf63..604e106 100644
--- a/daemon/lvm.c
+++ b/daemon/lvm.c
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <assert.h>
#include "daemon.h"
#include "c-ctype.h"
@@ -103,6 +104,85 @@ convert_lvm_output (char *out, const char *prefix)
return ret.argv;
}
+/* Filter a colon-separated output of
+ * lvs -o lv_attr,vg_name,lv_name
+ * removing thin layouts, and building the device path as we expect it.
+ *
+ * This is used only when lvm has no -S.
+ */
+static char **
+filter_convert_old_lvs_output (char *out)
+{
+ char *p, *pend;
+ DECLARE_STRINGSBUF (ret);
+
+ p = out;
+ while (p) {
+ size_t len;
+ char *saveptr;
+ char *lv_attr, *vg_name, *lv_name;
+
+ pend = strchr (p, '\n'); /* Get the next line of output. */
+ if (pend) {
+ *pend = '\0';
+ pend++;
+ }
+
+ while (*p && c_isspace (*p)) /* Skip any leading whitespace. */
+ p++;
+
+ /* Sigh, skip trailing whitespace too. "pvs", I'm looking at you. */
+ len = strlen (p)-1;
+ while (*p && c_isspace (p[len]))
+ p[len--] = '\0';
+
+ if (!*p) { /* Empty line? Skip it. */
+ skip_line:
+ p = pend;
+ continue;
+ }
+
+ lv_attr = strtok_r (p, ":", &saveptr);
+ if (!lv_attr)
+ goto skip_line;
+
+ vg_name = strtok_r (NULL, ":", &saveptr);
+ if (!vg_name)
+ goto skip_line;
+
+ lv_name = strtok_r (NULL, ":", &saveptr);
+ if (!lv_name)
+ goto skip_line;
+
+ /* Ignore thin layouts (RHBZ#1278878). */
+ if (lv_attr[0] == 't')
+ goto skip_line;
+
+ /* Ignore "unknown device" message (RHBZ#1054761). */
+ if (STRNEQ (p, "unknown device")) {
+ char buf[256];
+
+ snprintf (buf, sizeof buf, "/dev/%s/%s", vg_name, lv_name);
+ if (add_string (&ret, buf) == -1) {
+ free (out);
+ return NULL;
+ }
+ }
+
+ p = pend;
+ }
+
+ free (out);
+
+ if (ret.size > 0)
+ sort_strings (ret.argv, ret.size);
+
+ if (end_stringsbuf (&ret) == -1)
+ return NULL;
+
+ return ret.argv;
+}
+
char **
do_pvs (void)
{
@@ -139,26 +219,76 @@ do_vgs (void)
return convert_lvm_output (out, NULL);
}
+/* Check whether lvs has -S to filter its output.
+ * It is available only in lvm2 >= 2.02.107.
+ */
+static int
+test_lvs_has_S_opt (void)
+{
+ static int result = -1;
+ if (result != -1)
+ return result;
+
+ CLEANUP_FREE char *out = NULL;
+ CLEANUP_FREE char *err = NULL;
+
+ int r = command (&out, &err, str_lvm, "lvs", "--help", NULL);
+ if (r == -1) {
+ reply_with_error ("lvm lvs --help: %s", err);
+ return -1;
+ }
+
+ if (strstr (out, "-S") == NULL)
+ result = 0;
+ else
+ result = 1;
+
+ return result;
+}
+
char **
do_lvs (void)
{
char *out;
CLEANUP_FREE char *err = NULL;
int r;
+ int has_S = test_lvs_has_S_opt ();
- r = command (&out, &err,
- str_lvm, "lvs",
- "-o", "vg_name,lv_name",
- "-S", "lv_role=public",
- "--noheadings",
- "--separator", "/", NULL);
- if (r == -1) {
- reply_with_error ("%s", err);
- free (out);
+ if (has_S < 0)
return NULL;
+
+ if (has_S > 0) {
+ r = command (&out, &err,
+ str_lvm, "lvs",
+ "-o", "vg_name,lv_name",
+ "-S", "lv_role=public",
+ "--noheadings",
+ "--separator", "/", NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ free (out);
+ return NULL;
+ }
+
+ return convert_lvm_output (out, "/dev/");
+ } else {
+ r = command (&out, &err,
+ str_lvm, "lvs",
+ "-o", "lv_attr,vg_name,lv_name",
+ "--noheadings",
+ "--separator", ":", NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ free (out);
+ return NULL;
+ }
+
+ return filter_convert_old_lvs_output (out);
}
- return convert_lvm_output (out, "/dev/");
+ /*NOTREACHED*/
+ assert (false);
+ return NULL;
}
/* These were so complex to implement that I ended up auto-generating
--
2.5.0
8 years, 11 months
[PATCH] python: stop using parens-less print in tests
by Pino Toscano
print "" is no more available in Python 3, and print(...) is available
since Python 2.7; as one of the tests was using print(), use this form
everywhere so the tests can run fine with Python 3.
---
python/t/820-rhbz912499.py | 18 +++++++++---------
python/t/910-libvirt.py | 4 ++--
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/python/t/820-rhbz912499.py b/python/t/820-rhbz912499.py
index de6d1d3..1909a37 100644
--- a/python/t/820-rhbz912499.py
+++ b/python/t/820-rhbz912499.py
@@ -30,28 +30,28 @@ import guestfs
try:
import libvirt
except:
- print "skipping test: could not import python-libvirt"
+ print ("skipping test: could not import python-libvirt")
exit (77)
# If the backend is not libvirt, skip the test.
backend = guestfs.GuestFS().get_backend()
rex = re.compile ("^libvirt")
if not rex.match (backend):
- print "skipping test: backend is not libvirt"
+ print ("skipping test: backend is not libvirt")
exit (77)
# If the architecture doesn't support IDE, skip the test.
machine = platform.machine ()
rex = re.compile ("i.86")
if machine != "x86_64" and not rex.match (machine):
- print "skipping test: arch is not x86 and does not support IDE"
+ print ("skipping test: arch is not x86 and does not support IDE")
exit (77)
conn = libvirt.open (None)
# Check we're using the version of libvirt-python that has c_pointer() methods.
if not "c_pointer" in dir (conn):
- print "skipping test: libvirt-python doesn't support c_pointer()"
+ print ("skipping test: libvirt-python doesn't support c_pointer()")
exit (77)
# Create a test disk.
@@ -86,12 +86,12 @@ dom = conn.createXML (xml, libvirt.VIR_DOMAIN_START_AUTODESTROY)
if dom == None:
raise "could not create temporary domain (%s)" % domname
-print "temporary domain %s is running" % domname
+print ("temporary domain %s is running" % domname)
# Libvirt should have labelled the disk.
-print "before starting libguestfs"
+print ("before starting libguestfs")
before = check_output (["ls", "-Z", filename])
-print "disk label = %s" % before
+print ("disk label = %s" % before)
# Now see if we can open the domain with libguestfs without
# disturbing the label.
@@ -101,9 +101,9 @@ if r != 1:
raise "unexpected return value from add_libvirt_dom (%d)" % r
g.launch ()
-print "after starting libguestfs"
+print ("after starting libguestfs")
after = check_output (["ls", "-Z", filename])
-print "disk label = %s" % after
+print ("disk label = %s" % after)
if before != after:
raise "disk label was changed unexpectedly"
diff --git a/python/t/910-libvirt.py b/python/t/910-libvirt.py
index 1f70f36..f6c99c9 100644
--- a/python/t/910-libvirt.py
+++ b/python/t/910-libvirt.py
@@ -28,14 +28,14 @@ guestsdir = os.environ['guestsdir']
try:
import libvirt
except:
- print "could not import python-libvirt"
+ print ("could not import python-libvirt")
exit (77)
conn = libvirt.open ("test:///%s/guests.xml" % guestsdir)
# Check we're using the version of libvirt-python that has c_pointer() methods.
if not "c_pointer" in dir (conn):
- print "skipping test: libvirt-python doesn't support c_pointer()"
+ print ("skipping test: libvirt-python doesn't support c_pointer()")
exit (77)
dom = conn.lookupByName ("blank-disk")
--
2.5.0
8 years, 11 months
error during virt-sparsify
by Illia Svyrydov
Hello,
I'm using *virt-sparsify* for compressing image file
[ash2] jenkins@b-imagebuilder-worker-r13h17-prod:~/workspace/imagebuilder/packer/output$
virt-sparsify --compress
/data/home/jenkins/workspace/imagebuilder/packer/output/packer-vm.qcow2
/data/home/jenkins/workspace/imagebuilder/packer/output/packer-vm.qcow2.sparsified
Input disk virtual size = 41943040000 bytes (39.1G)
Create overlay file in /data/tmp/ to protect source disk ...
Examine source disk ...
Fatal error: exception Guestfs.Error("guestfs_launch failed.
This usually means the libguestfs appliance failed to start or crashed.
See http://libguestfs.org/guestfs-faq.1.html#debugging-libguestfs
or run 'libguestfs-test-tool' and post the *complete* output into a
bug report
Here is *libguestfs-test-tool* output
http://pastebin.com/raw/anuu6wkh
I would really appreciate any help or hint
Have a nice day,
Illia Svyrydov
8 years, 11 months
[PATCH 1/2] generator: add TestRunOrUnsupported test type
by Pino Toscano
Create a new TestRunOrUnsupported test type, which represents a test
sequence where a failure with ENOTSUP in the last command only marks the
test as skipped. To be used mainly when testing features available only
with some versions of helper tools used in the appliance, for example.
---
generator/tests_c_api.ml | 26 ++++++++++++++++++++++++--
generator/types.ml | 5 +++++
generator/utils.ml | 3 ++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 8116e9e..7cf3763 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -41,6 +41,7 @@ let rec generate_c_api_tests () =
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <errno.h>
#include \"guestfs.h\"
#include \"guestfs-internal-frontend.h\"
@@ -335,6 +336,23 @@ and generate_test_perform name i test_name test =
let seq, last = get_seq_last seq in
List.iter (generate_test_command_call test_name) seq;
generate_test_command_call test_name ~expect_error:true last
+
+ | TestRunOrUnsupported seq ->
+ pr " /* TestRunOrUnsupported for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call test_name ~expect_error:true ~do_return:false ~ret:"ret" last;
+ pr " if (ret == -1) {\n";
+ pr " if (guestfs_last_errno (g) == ENOTSUP) {\n";
+ pr " skipped (\"%s\", \"last command %%s returned ENOTSUP\", \"%s\");\n"
+ test_name (List.hd last);
+ pr " return 0;\n";
+ pr " }\n";
+ pr " fprintf (stderr, \"%%s: test failed: expected last command %%s to pass or fail with ENOTSUP, but it failed with %%d: %%s\\n\",\n";
+ pr " \"%s\", \"%s\", guestfs_last_errno (g), guestfs_last_error (g));\n"
+ test_name (List.hd last);
+ pr " return -1;\n";
+ pr " }\n"
);
pr " return 0;\n";
@@ -354,7 +372,7 @@ and generate_test_cleanup test_name cleanup =
* variable named 'ret'. If you expect to get an error then you should
* set expect_error:true.
*)
-and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
+and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test ?ret test_name cmd=
let ret = match ret with Some ret -> ret | None -> gensym "ret" in
let name, args =
@@ -561,7 +579,11 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
if expect_error then
pr " guestfs_pop_error_handler (g);\n";
- (match errcode_of_ret style_ret, expect_error with
+ let ret_errcode =
+ if do_return then errcode_of_ret style_ret
+ else `CannotReturnError in
+
+ (match ret_errcode, expect_error with
| `CannotReturnError, _ -> ()
| `ErrorIsMinusOne, false ->
pr " if (%s == -1)\n" ret;
diff --git a/generator/types.ml b/generator/types.ml
index 7fa65c9..b2f8724 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -245,6 +245,11 @@ and c_api_test =
*)
| TestLastFail of seq
+ (* Run the command sequence and expect either nothing to fail,
+ * or that the last command only can fail with ENOTSUP.
+ *)
+ | TestRunOrUnsupported of seq
+
(* Test prerequisites. *)
and c_api_test_prereq =
(* Test always runs. *)
diff --git a/generator/utils.ml b/generator/utils.ml
index 6eff6ad..34edf9d 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -266,7 +266,8 @@ let seq_of_test = function
| TestResultDevice (s, _)
| TestResultTrue s
| TestResultFalse s
- | TestLastFail s -> s
+ | TestLastFail s
+ | TestRunOrUnsupported s -> s
let c_quote str =
let str = replace_str str "\\" "\\\\" in
--
2.5.0
8 years, 11 months
[PATCH] inspect: Get architecture of Alpine Linux from /bin/busybox.
by Richard W.M. Jones
All the files in /bin are links to busybox. guestfs_file_architecture
doesn't follow symlinks so it fails. Therefore check /bin/busybox
(not a symlink) to find the architecture.
---
src/inspect-fs-unix.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index f915e86..6aaf5a1 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -1077,7 +1077,8 @@ static void
check_architecture (guestfs_h *g, struct inspect_fs *fs)
{
const char *binaries[] =
- { "/bin/bash", "/bin/ls", "/bin/echo", "/bin/rm", "/bin/sh" };
+ { "/bin/bash", "/bin/ls", "/bin/echo", "/bin/rm", "/bin/sh",
+ "/bin/busybox" };
size_t i;
char *arch;
--
2.5.0
8 years, 11 months