From ee9d9e38aba28e8fe1ac6cfc80c21befd97eeb57 Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Feb 12 2016 16:17:19 +0000 Subject: Fix failure when disk contains LV with activationskip=yes Upstream commit 2e16e3e99 (RHBZ#1306666). (cherry picked from commit 2dab3c2e8f05101f4147744a6bf0f29fe59920b2) --- diff --git a/0001-lvm-support-lvm2-older-than-2.02.107.patch b/0001-lvm-support-lvm2-older-than-2.02.107.patch new file mode 100644 index 0000000..1931280 --- /dev/null +++ b/0001-lvm-support-lvm2-older-than-2.02.107.patch @@ -0,0 +1,195 @@ +From d06da519b443796d83d1f7bd5424b5299b4cb9ad Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 28 Jan 2016 15:38:11 +0100 +Subject: [PATCH 1/2] lvm: support lvm2 older than 2.02.107 + +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. + +(cherry picked from commit f9e8f3b2d2cf1acdf9573faceb844b8d50bae69d) +--- + daemon/lvm.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 136 insertions(+), 11 deletions(-) + +diff --git a/daemon/lvm.c b/daemon/lvm.c +index cf8e0e5..501c967 100644 +--- a/daemon/lvm.c ++++ b/daemon/lvm.c +@@ -103,6 +103,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 +218,72 @@ 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/"); + } + + /* These were so complex to implement that I ended up auto-generating +-- +2.5.0 + diff --git a/0002-daemon-lvm-Ignore-LVs-with-the-activationskip-flag-s.patch b/0002-daemon-lvm-Ignore-LVs-with-the-activationskip-flag-s.patch new file mode 100644 index 0000000..8adf4e4 --- /dev/null +++ b/0002-daemon-lvm-Ignore-LVs-with-the-activationskip-flag-s.patch @@ -0,0 +1,44 @@ +From aa1ffc6d2bab0d3b0b9f71987e74dea6803f4bb7 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 12 Feb 2016 13:41:26 +0000 +Subject: [PATCH 2/2] daemon: lvm: Ignore LVs with the activationskip flag set + (RHBZ#1306666). + +When listing logical volumes, ignore the ones which don't get +activated automatically. No /dev/VG/LV device node is created for +these ones which confuses APIs that attempt to do 'guestfs_lvs' +followed by opening the device node. Note that 'guestfs_lvs_full' is +unaffected by this change. + +(cherry picked from commit 2e16e3e99324112845446c82b6a6e8b3e652e10d) +--- + daemon/lvm.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/daemon/lvm.c b/daemon/lvm.c +index 501c967..83cc6f8 100644 +--- a/daemon/lvm.c ++++ b/daemon/lvm.c +@@ -157,6 +157,10 @@ filter_convert_old_lvs_output (char *out) + if (lv_attr[0] == 't') + goto skip_line; + ++ /* Ignore activationskip (RHBZ#1306666). */ ++ if (strlen (lv_attr) >= 10 && lv_attr[9] == 'k') ++ goto skip_line; ++ + /* Ignore "unknown device" message (RHBZ#1054761). */ + if (STRNEQ (p, "unknown device")) { + char buf[256]; +@@ -260,7 +264,7 @@ do_lvs (void) + r = command (&out, &err, + str_lvm, "lvs", + "-o", "vg_name,lv_name", +- "-S", "lv_role=public", ++ "-S", "lv_role=public && lv_active=active", + "--noheadings", + "--separator", "/", NULL); + if (r == -1) { +-- +2.5.0 + diff --git a/libguestfs.spec b/libguestfs.spec index 51e9679..3a5ef39 100644 --- a/libguestfs.spec +++ b/libguestfs.spec @@ -25,7 +25,7 @@ Summary: Access and modify virtual machine disk images Name: libguestfs Epoch: 1 Version: 1.30.6 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv2+ # Source and patches. @@ -35,6 +35,10 @@ Source0: http://libguestfs.org/download/1.29-development/%{name}-%{version # RHBZ#1280029 Patch1: 0001-daemon-always-provide-stdin-when-running-chroot-comm.patch +# Upstream commit 2e16e3e99 for RHBZ#1306666. +Patch2: 0001-lvm-support-lvm2-older-than-2.02.107.patch +Patch3: 0002-daemon-lvm-Ignore-LVs-with-the-activationskip-flag-s.patch + # Basic build requirements: BuildRequires: perl(Pod::Simple) BuildRequires: perl(Pod::Man) @@ -1356,6 +1360,10 @@ popd %changelog +* Fri Feb 12 2016 Richard W.M. Jones - 1:1.30.6-2 +- Fix failure when disk contains LV with activationskip=yes + Upstream commit 2e16e3e99 (RHBZ#1306666). + * Wed Dec 16 2015 Richard W.M. Jones - 1:1.30.6-1 - New upstream version 1.30.6.