stable-2.02 - devices: drop open error message
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=559cf0cd1e226baf63a...
Commit: 559cf0cd1e226baf63a98c39572264fbf5c3f6b4
Parent: 228e331e270451e16126659655905a583a03a0d3
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Apr 23 09:39:42 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Apr 23 09:42:25 2019 -0500
devices: drop open error message
This open error is being printed in more common,
non-error circumstances than expected. After a
number of complaints make it only a debug message.
---
lib/device/dev-io.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index 2a83a96..6996a44 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -572,10 +572,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
}
}
#endif
- if (quiet)
- log_sys_debug("open", name);
- else
- log_sys_error("open", name);
+ log_sys_debug("open", name);
dev->flags |= DEV_OPEN_FAILURE;
return 0;
5 years
master - cleanup: missed string specifier
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8fbaa6d9a5dd738a566...
Commit: 8fbaa6d9a5dd738a566906a23f5bbe901d80a9d2
Parent: 44cfa558437634c15ec6da38507e73b4c86837c1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Apr 17 11:29:35 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Apr 17 11:35:44 2019 +0200
cleanup: missed string specifier
---
libdaemon/server/daemon-server.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index e4ff8a1..9dd0017 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -656,7 +656,7 @@ void daemon_start(daemon_state s)
sigprocmask(SIG_SETMASK, &new_set, NULL);
if (_shutdown_requested && !s.threads->next) {
sigprocmask(SIG_SETMASK, &old_set, NULL);
- INFO(&s, "shutdown requested", s.name);
+ INFO(&s, "%s shutdown requested", s.name);
break;
}
ret = pselect(s.socket_fd + 1, &in, NULL, NULL, _get_timeout(s), &old_set);
5 years
stable-2.02 - cleanup: missed string specifier
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=228e331e270451e1612...
Commit: 228e331e270451e16126659655905a583a03a0d3
Parent: 3ead62e24b6b616c4bde093db37dc770a38669ae
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Apr 17 11:29:35 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Apr 17 11:29:35 2019 +0200
cleanup: missed string specifier
---
libdaemon/server/daemon-server.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index c61683a..8534b79 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -658,7 +658,7 @@ void daemon_start(daemon_state s)
sigprocmask(SIG_SETMASK, &new_set, NULL);
if (_shutdown_requested && !s.threads->next) {
sigprocmask(SIG_SETMASK, &old_set, NULL);
- INFO(&s, "shutdown requested", s.name);
+ INFO(&s, "%s shutdown requested", s.name);
break;
}
ret = pselect(s.socket_fd + 1, &in, NULL, NULL, _get_timeout(s), &old_set);
5 years
master - configure: check for pselect
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=116bd314cb8bb169336...
Commit: 116bd314cb8bb169336b2a14ff5ced78d9de9047
Parent: aa75b31db54782fb24b6b7e3c681a61b3579117c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Apr 10 13:22:43 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Apr 16 12:14:31 2019 +0200
configure: check for pselect
---
configure | 2 +-
configure.ac | 2 +-
include/configure.h.in | 6 ++++++
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 53f5023..cced7bd 100755
--- a/configure
+++ b/configure
@@ -6634,7 +6634,7 @@ $as_echo "#define _REENTRANT 1" >>confdefs.h
################################################################################
for ac_func in ftruncate gethostname getpagesize gettimeofday localtime_r \
- memchr memset mkdir mkfifo munmap nl_langinfo realpath rmdir setenv \
+ memchr memset mkdir mkfifo munmap nl_langinfo pselect realpath rmdir setenv \
setlocale strcasecmp strchr strcspn strdup strerror strncasecmp strndup \
strrchr strspn strstr strtol strtoul uname
do :
diff --git a/configure.ac b/configure.ac
index 98a39f6..1e45c0e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,7 +153,7 @@ AC_DEFINE([_REENTRANT], 1, [Define to use re-entrant thread safe versions])
################################################################################
dnl -- Check for functions
AC_CHECK_FUNCS([ftruncate gethostname getpagesize gettimeofday localtime_r \
- memchr memset mkdir mkfifo munmap nl_langinfo realpath rmdir setenv \
+ memchr memset mkdir mkfifo munmap nl_langinfo pselect realpath rmdir setenv \
setlocale strcasecmp strchr strcspn strdup strerror strncasecmp strndup \
strrchr strspn strstr strtol strtoul uname], , [AC_MSG_ERROR(bailing out)])
AC_FUNC_ALLOCA
diff --git a/include/configure.h.in b/include/configure.h.in
index dde55fe..ce4c326 100644
--- a/include/configure.h.in
+++ b/include/configure.h.in
@@ -292,6 +292,12 @@
/* Define to 1 if you have the <paths.h> header file. */
#undef HAVE_PATHS_H
+/* Define to 1 if you have the `pselect' function. */
+#undef HAVE_PSELECT
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
/* Define to 1 if the system has the type `ptrdiff_t'. */
#undef HAVE_PTRDIFF_T
5 years
master - libdaemon: use pselect to avoid condition checking race
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=44cfa558437634c15ec...
Commit: 44cfa558437634c15ec6da38507e73b4c86837c1
Parent: 116bd314cb8bb169336b2a14ff5ced78d9de9047
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Apr 10 12:50:53 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Apr 16 12:18:34 2019 +0200
libdaemon: use pselect to avoid condition checking race
To avoid tiny race on checking arrival of signal and entering select
(that can latter remain stuck as signal was already delivered) switch
to use pselect().
If it would needed, we can eventually add extra code for older systems
without pselect(), but there are probably no such ancient systems in
use.
---
WHATS_NEW | 1 +
daemons/lvmpolld/lvmpolld-core.c | 2 +-
libdaemon/server/daemon-server.c | 38 ++++++++++++++++++++++++++++----------
libdaemon/server/daemon-server.h | 2 +-
4 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 0f0c6ae..6ab973d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.03.02 -
===================================
+ Fix signal delivery checking race in libdaemon (lvmetad).
Add missing Before=shutdown.target to LVM2 services to fix shutdown ordering.
Skip autoactivation for a PV when PV size does not match device size.
Remove first-pvscan-initialization which should no longer be needed.
diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c
index 3aac65f..af98843 100644
--- a/daemons/lvmpolld/lvmpolld-core.c
+++ b/daemons/lvmpolld/lvmpolld-core.c
@@ -915,7 +915,7 @@ int main(int argc, char *argv[])
int option_index = 0;
int client = 0, server = 0;
unsigned action = ACTION_MAX;
- struct timeval timeout;
+ struct timespec timeout;
daemon_idle di = { .ptimeout = &timeout };
struct lvmpolld_state ls = { .log_config = "" };
daemon_state s = {
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index a2216ac..e4ff8a1 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -85,7 +85,7 @@ static int _is_idle(daemon_state s)
return s.idle && s.idle->is_idle && !s.threads->next;
}
-static struct timeval *_get_timeout(daemon_state s)
+static struct timespec *_get_timeout(daemon_state s)
{
return s.idle ? s.idle->ptimeout : NULL;
}
@@ -94,7 +94,7 @@ static void _reset_timeout(daemon_state s)
{
if (s.idle) {
s.idle->ptimeout->tv_sec = 1;
- s.idle->ptimeout->tv_usec = 0;
+ s.idle->ptimeout->tv_nsec = 0;
}
}
@@ -559,6 +559,8 @@ void daemon_start(daemon_state s)
thread_state _threads = { .next = NULL };
unsigned timeout_count = 0;
fd_set in;
+ sigset_t new_set, old_set;
+ int ret;
/*
* Switch to C locale to avoid reading large locale-archive file used by
@@ -626,8 +628,7 @@ void daemon_start(daemon_state s)
if (!s.foreground)
kill(getppid(), SIGTERM);
- /*
- * Use daemon_main for daemon-specific init and polling, or
+ /* * Use daemon_main for daemon-specific init and polling, or
* use daemon_init for daemon-specific init and generic lib polling.
*/
@@ -641,22 +642,39 @@ void daemon_start(daemon_state s)
if (!s.daemon_init(&s))
failed = 1;
+ if (s.socket_fd >= FD_SETSIZE)
+ failed = 1; /* FD out of available selectable set */
+
+ sigfillset(&new_set);
+ sigprocmask(SIG_SETMASK, NULL, &old_set);
+
while (!failed) {
_reset_timeout(s);
FD_ZERO(&in);
FD_SET(s.socket_fd, &in);
- if (select(FD_SETSIZE, &in, NULL, NULL, _get_timeout(s)) < 0 && errno != EINTR)
- perror("select error");
+
+ sigprocmask(SIG_SETMASK, &new_set, NULL);
+ if (_shutdown_requested && !s.threads->next) {
+ sigprocmask(SIG_SETMASK, &old_set, NULL);
+ INFO(&s, "shutdown requested", s.name);
+ break;
+ }
+ ret = pselect(s.socket_fd + 1, &in, NULL, NULL, _get_timeout(s), &old_set);
+ sigprocmask(SIG_SETMASK, &old_set, NULL);
+
+ if (ret < 0) {
+ if (errno != EINTR && errno != EAGAIN &&
+ (EWOULDBLOCK == EAGAIN || errno != EWOULDBLOCK))
+ perror("select error");
+ continue;
+ }
+
if (FD_ISSET(s.socket_fd, &in)) {
timeout_count = 0;
_handle_connect(s);
}
-
_reap(s, 0);
- if (_shutdown_requested && !s.threads->next)
- break;
-
/* s.idle == NULL equals no shutdown on timeout */
if (_is_idle(s)) {
DEBUGLOG(&s, "timeout occured");
diff --git a/libdaemon/server/daemon-server.h b/libdaemon/server/daemon-server.h
index f8c0ca6..18fd3ad 100644
--- a/libdaemon/server/daemon-server.h
+++ b/libdaemon/server/daemon-server.h
@@ -47,7 +47,7 @@ struct timeval;
typedef struct {
volatile unsigned is_idle;
unsigned max_timeouts;
- struct timeval *ptimeout;
+ struct timespec *ptimeout;
} daemon_idle;
struct daemon_state;
5 years
stable-2.02 - tests: check vgsplit works with cache
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3ead62e24b6b616c4bd...
Commit: 3ead62e24b6b616c4bde093db37dc770a38669ae
Parent: fa025cdd9a7453c86e34bf550235a00537d059de
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Feb 1 23:45:12 2019 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Apr 16 12:57:18 2019 +0200
tests: check vgsplit works with cache
---
test/shell/vgsplit-cache.sh | 71 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/test/shell/vgsplit-cache.sh b/test/shell/vgsplit-cache.sh
new file mode 100644
index 0000000..3bbcc2d
--- /dev/null
+++ b/test/shell/vgsplit-cache.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2019 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# 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
+
+# Test vgsplit command options with cached volumes
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux have_cache 1 3 0 || skip
+
+aux prepare_vg 7
+
+lvcreate -L5 -n $lv2 $vg "$dev2"
+lvcreate -L5 -n $lv3 $vg "$dev3"
+lvconvert -y --type cache-pool --poolmetadata $vg/$lv2 $vg/$lv3
+
+# Cannot split data and metadata from cache-pool
+fail vgsplit $vg $vg1 "$dev2" 2>&1 | tee err
+grep "Cannot split cache pool data" err
+
+fail vgsplit $vg $vg1 "$dev3" 2>&1 | tee err
+grep "Cannot split cache pool data" err
+
+# Cache $lv1
+lvcreate -L1 -n $lv1 $vg "$dev1"
+lvconvert -y --cache --cachepool $vg/$lv3 $vg/$lv1
+
+
+
+# Cannot move active cache
+fail vgsplit $vg $vg1 "$dev1" "$dev2" "$dev3" 2>&1 | tee err
+grep "must be inactive" err
+
+vgchange -an $vg
+
+
+# Try spliting component into separe VG
+fail vgsplit $vg $vg1 "$dev1" 2>&1 | tee err
+grep "Cannot split cache origin" err
+
+fail vgsplit $vg $vg1 "$dev2" 2>&1 | tee err
+grep "Cannot split cache origin" err
+
+fail vgsplit $vg $vg1 "$dev3" 2>&1 | tee err
+grep "Cannot split cache origin" err
+
+fail vgsplit $vg $vg1 "$dev1" "$dev2" 2>&1 | tee err
+grep "Cannot split cache origin" err
+
+fail vgsplit $vg $vg1 "$dev2" "$dev3" 2>&1 | tee err
+
+# Finaly something that should pass
+vgsplit $vg $vg1 "$dev1" "$dev2" "$dev3"
+
+vgs $vg $vg1
+
+test 4 -eq "$(get vg_field $vg pv_count)"
+test 3 -eq "$(get vg_field $vg1 pv_count)"
+
+vgremove -ff $vg $vg1
5 years
stable-2.02 - cache: support vgsplit
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fa025cdd9a7453c86e3...
Commit: fa025cdd9a7453c86e34bf550235a00537d059de
Parent: f5d1f4f086f75148e25f7fda28bf2166e0c5a162
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Feb 1 21:29:22 2019 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Apr 16 12:57:18 2019 +0200
cache: support vgsplit
Enable vgsplit to work with VG containing cached LVs.
---
WHATS_NEW | 1 +
tools/vgsplit.c | 81 +++++++++++++++++++++++--------------------------------
2 files changed, 35 insertions(+), 47 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index b15ffa3..6457d4c 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.185 -
==================================
+ Add support for vgsplit with cached devices.
Fix signal delivery checking race in libdaemon (lvmetad).
Add missing Before=shutdown.target to LVM2 services to fix shutdown ordering.
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index 2d39111..e7ad4c0 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2009,2016 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2019 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -384,68 +384,55 @@ static int _move_cache(struct volume_group *vg_from,
dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
lv = dm_list_item(lvh, struct lv_list)->lv;
- data = meta = orig = NULL;
seg = first_seg(lv);
if (!lv_is_cache(lv) && !lv_is_cache_pool(lv))
continue;
- /*
- * FIXME: The code seems to move cache LVs fine, but it
- * hasn't been well tested and it causes problems
- * when just splitting PVs that don't contain
- * cache LVs.
- * Waiting for next release before fixing and enabling.
- */
- log_error("Unable to split VG while it contains cache LVs");
- return 0;
-
- /* NOTREACHED */
-
if (lv_is_cache(lv)) {
orig = seg_lv(seg, 0);
- data = seg_lv(first_seg(seg->pool_lv), 0);
- meta = first_seg(seg->pool_lv)->metadata_lv;
- /* Ensure all components are coming along */
- is_moving = _lv_is_in_vg(vg_to, orig);
- } else {
- if (!dm_list_empty(&seg->lv->segs_using_this_lv) &&
- !(cache_seg = get_only_segment_using_this_lv(seg->lv)))
- return_0;
- orig = seg_lv(cache_seg, 0);
- data = seg_lv(seg, 0);
- meta = seg->metadata_lv;
-
- if (_lv_is_in_vg(vg_to, data) ||
- _lv_is_in_vg(vg_to, meta))
- is_moving = 1;
+ seg = first_seg(seg->pool_lv);
+ } else { /* lv_is_cache_pool */
+ orig = NULL;
+ if (!dm_list_empty(&seg->lv->segs_using_this_lv)) {
+ if (!(cache_seg = get_only_segment_using_this_lv(seg->lv)))
+ return_0;
+ orig = seg_lv(cache_seg, 0);
+ }
}
- if (!lv_is_on_pvs(data, &vg_to->pvs))
- continue;
+ data = seg_lv(seg, 0);
+ meta = seg->metadata_lv;
- if (!lv_is_on_pvs(meta, &vg_to->pvs))
+ if ((orig && !lv_is_on_pvs(orig, &vg_to->pvs)) &&
+ !lv_is_on_pvs(data, &vg_to->pvs) &&
+ !lv_is_on_pvs(meta, &vg_to->pvs))
continue;
- if (orig && (_lv_is_in_vg(vg_to, orig) != is_moving)) {
- log_error("Can't split %s and its origin (%s)"
- " into separate VGs", lv->name, orig->name);
- return 0;
- }
+ /* Ensure all components are coming along */
+ if (orig) {
+ is_moving = _lv_is_in_vg(vg_to, orig);
- if (data && (_lv_is_in_vg(vg_to, data) != is_moving)) {
- log_error("Can't split %s and its cache pool"
- " data LV (%s) into separate VGs",
- lv->name, data->name);
- return 0;
- }
+ if (_lv_is_in_vg(vg_to, data) != is_moving) {
+ log_error("Cannot split cache origin %s and its cache pool data %s "
+ "into separate VGs.",
+ display_lvname(orig), display_lvname(data));
+ return 0;
+ }
- if (meta && (_lv_is_in_vg(vg_to, meta) != is_moving)) {
- log_error("Can't split %s and its cache pool"
- " metadata LV (%s) into separate VGs",
- lv->name, meta->name);
+ if (_lv_is_in_vg(vg_to, meta) != is_moving) {
+ log_error("Cannot split cache origin %s and its cache pool metadata %s "
+ "into separate VGs.",
+ display_lvname(orig), display_lvname(meta));
+ return 0;
+ }
+ } else if (_lv_is_in_vg(vg_to, data) != _lv_is_in_vg(vg_to, meta)) {
+ log_error("Cannot split cache pool data %s and its metadata %s "
+ "into separate VGs.",
+ display_lvname(data), display_lvname(meta));
return 0;
}
+
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
return_0;
}
5 years
stable-2.02 - Wiping require exclusive actvation
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f5d1f4f086f75148e25...
Commit: f5d1f4f086f75148e25f7fda28bf2166e0c5a162
Parent: 699bf8609049058875d84f129d508d4ccbed3900
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Mon Apr 15 20:39:23 2019 +0200
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Tue Apr 16 08:26:34 2019 +0200
Wiping require exclusive actvation
The master branch uses activate_lv only, but on the stable branch
activate_lv_excl_local was used. This patch restores the constraints.
Fix regression from bad cherry pick: 9b04851fc574ce9cffd30a51d2b750955239f316
---
lib/metadata/lv_manip.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index d039686..e72a1c9 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7240,9 +7240,9 @@ int activate_and_wipe_lvlist(struct dm_list *lv_list, int commit)
was_active = alloca(sz);
dm_list_iterate_items(lvl, lv_list)
- if (!(was_active[i++] = lv_is_active(lvl->lv))) {
+ if (!(was_active[i++] = lv_is_active_locally(lvl->lv))) {
lvl->lv->status |= LV_TEMPORARY;
- if (!activate_lv(vg->cmd, lvl->lv)) {
+ if (!activate_lv_excl_local(vg->cmd, lvl->lv)) {
log_error("Failed to activate localy %s for wiping.",
display_lvname(lvl->lv));
r = 0;
5 years
master - pvscan: handle case of scanning PV without metadata last
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=aa75b31db54782fb24b...
Commit: aa75b31db54782fb24b6b7e3c681a61b3579117c
Parent: 41ba2b568b3d3ad1d1ee2a26cf9f44a2b2e77e8f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Apr 15 11:27:49 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Apr 15 11:27:49 2019 -0500
pvscan: handle case of scanning PV without metadata last
Handle the case where pvscan --cache -aay (with no dev args)
gets to the final PV, completing the VG, but that final PV does not
have VG metadata. In this case, we need to use VG metadata from a
previously scanned PV in the same VG, which we saved for this
possibility. Using this saved metadata, we can find which VG
this PVID belongs to, and then check if that VG is now complete,
and if so add the VG name to the list of complete VGs to be
autoactivated.
---
test/shell/pvscan-autoactivate.sh | 66 ++++++++++++++++++------
tools/pvscan.c | 99 +++++++++++++++++++++++++++++++++++-
2 files changed, 145 insertions(+), 20 deletions(-)
diff --git a/test/shell/pvscan-autoactivate.sh b/test/shell/pvscan-autoactivate.sh
index 52258f4..6ed35db 100644
--- a/test/shell/pvscan-autoactivate.sh
+++ b/test/shell/pvscan-autoactivate.sh
@@ -27,7 +27,7 @@ _clear_online_files() {
. lib/inittest
-aux prepare_pvs 3
+aux prepare_pvs 8
vgcreate $vg1 "$dev1" "$dev2"
lvcreate -n $lv1 -l 4 -a n $vg1
@@ -59,6 +59,19 @@ pvscan --cache -aay "$dev1" "$dev2"
check lv_field $vg1/$lv1 lv_active "active"
lvchange -an $vg1
+# check that a cache command without aay will
+# just record online state, and that a following
+# pvscan cache aay that does not record any new
+# online files will activate the vg
+_clear_online_files
+pvscan --cache "$dev1"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache "$dev2"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache -aay
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
# Set up tests where one dev has no metadata
vgchange -an $vg1
@@ -94,22 +107,6 @@ lvchange -an $vg1
# is online without the -aay option to
# activate until after they are online
-# This part is disabled because it doesn't work if the
-# 'pvscan --cache -aay' without args ends up scanning
-# dev1 (without metadata) after dev2.
-
-#_clear_online_files
-
-#pvscan --cache "$dev1"
-#check lv_field $vg1/$lv1 lv_active ""
-#pvscan --cache "$dev2"
-#check lv_field $vg1/$lv1 lv_active ""
-#pvscan --cache -aay
-#check lv_field $vg1/$lv1 lv_active "active"
-#lvchange -an $vg1
-
-# like previous
-
_clear_online_files
pvscan --cache "$dev1"
@@ -172,4 +169,39 @@ grep $lv2 tmp
check lv_field $vg2/$lv2 lv_active "" --foreign
+# Test the case where pvscan --cache -aay (with no devs)
+# gets the final PV to complete the VG, where that final PV
+# does not hold VG metadata. In this case it needs to rely
+# on VG metadata that has been saved from a previously
+# scanned PV from the same VG.
+#
+# We can't control which order of devices pvscan will see,
+# so create several PVs without metadata surrounding one
+# PV with metadata, to make it likely that pvscan will
+# get a final PV without metadata.
+
+pvcreate --metadatacopies 0 "$dev4"
+pvcreate --metadatacopies 0 "$dev5"
+pvcreate --metadatacopies 1 "$dev6"
+pvcreate --metadatacopies 0 "$dev7"
+pvcreate --metadatacopies 0 "$dev8"
+vgcreate $vg3 "$dev4" "$dev5" "$dev6" "$dev7" "$dev8"
+lvcreate -n $lv1 -l 4 -a n $vg3
+
+_clear_online_files
+
+check lv_field $vg3/$lv1 lv_active ""
+pvscan --cache "$dev4"
+check lv_field $vg3/$lv1 lv_active ""
+pvscan --cache "$dev5"
+check lv_field $vg3/$lv1 lv_active ""
+pvscan --cache "$dev6"
+check lv_field $vg3/$lv1 lv_active ""
+pvscan --cache "$dev7"
+check lv_field $vg3/$lv1 lv_active ""
+pvscan --cache "$dev8"
+check lv_field $vg3/$lv1 lv_active ""
+pvscan --cache -aay
+check lv_field $vg3/$lv1 lv_active "active"
+lvchange -an $vg3
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 75c1a2b..a3786c4 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -547,10 +547,12 @@ static int _online_pvscan_single(struct metadata_area *mda, void *baton)
static int _online_pvscan_one(struct cmd_context *cmd, struct device *dev,
struct dm_list *dev_args,
struct dm_list *found_vgnames,
+ struct dm_list *all_vgs,
int disable_remove,
const char **pvid_without_metadata)
{
struct lvmcache_info *info;
+ struct vg_list *vgl;
struct _pvscan_baton baton;
const struct format_type *fmt;
/* Create a dummy instance. */
@@ -656,12 +658,89 @@ static int _online_pvscan_one(struct cmd_context *cmd, struct device *dev,
ret = _online_pv_found(cmd, dev, dev_args, baton.vg, found_vgnames);
- release_vg(baton.vg);
+ /*
+ * Save vg's in case they need to be used at the end for checking PVs
+ * without metadata (in _check_vg_with_pvid_complete).
+ */
+ if (all_vgs && baton.vg) {
+ int found = 0;
+ dm_list_iterate_items(vgl, all_vgs) {
+ if (!strcmp(baton.vg->name, vgl->vg->name)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ if ((vgl = malloc(sizeof(struct vg_list)))) {
+ vgl->vg = baton.vg;
+ baton.vg = NULL;
+ dm_list_add(all_vgs, &vgl->list);
+ }
+ }
+ }
+
+ if (baton.vg)
+ release_vg(baton.vg);
out:
return ret;
}
/*
+ * This is to handle the case where pvscan --cache -aay (with no dev args)
+ * gets to the final PV, completing the VG, but that final PV does not
+ * have VG metadata. In this case, we need to use VG metadata from a
+ * previously scanned PV in the same VG, which we saved in the all_vgs
+ * list. Using this saved metadata, we can find which VG this PVID
+ * belongs to, and then check if that VG is now complete, and if so
+ * add the VG name to the list of complete VGs to be autoactivated.
+ *
+ * The "pvid" arg here is the PVID of the PV that has just been scanned
+ * and didn't have metadata. We look through previously scanned VG
+ * metadata to find the VG this PVID belongs to, and then check that VG
+ * metadata to see if all the PVs are now online.
+ */
+static void _check_vg_with_pvid_complete(struct cmd_context *cmd,
+ struct dm_list *found_vgnames,
+ struct dm_list *all_vgs,
+ const char *pvid)
+{
+ struct vg_list *vgl;
+ struct pv_list *pvl;
+ struct volume_group *vg;
+ int pvids_not_online = 0;
+ int found;
+
+ dm_list_iterate_items(vgl, all_vgs) {
+ vg = vgl->vg;
+ found = 0;
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (strcmp((const char *)&pvl->pv->id.uuid, pvid))
+ continue;
+ found = 1;
+ break;
+ }
+ if (!found)
+ continue;
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (!_online_pvid_file_exists((const char *)&pvl->pv->id.uuid)) {
+ pvids_not_online++;
+ break;
+ }
+ }
+
+ if (!pvids_not_online) {
+ log_debug("pvid %s makes complete VG %s", pvid, vg->name);
+ if (!str_list_add(cmd->mem, found_vgnames, dm_pool_strdup(cmd->mem, vg->name)))
+ stack;
+ } else
+ log_debug("pvid %s incomplete VG %s", pvid, vg->name);
+ break;
+ }
+}
+
+/*
* dev_args is the list of devices that were specified on the
* pvscan command line.
*
@@ -676,8 +755,13 @@ static void _online_pvscan_all_devs(struct cmd_context *cmd,
struct dm_list *found_vgnames,
struct dm_list *dev_args)
{
+ struct dm_list all_vgs;
struct dev_iter *iter;
+ struct vg_list *vgl;
struct device *dev;
+ const char *pvid_without_metadata;
+
+ dm_list_init(&all_vgs);
label_scan(cmd);
@@ -692,12 +776,21 @@ static void _online_pvscan_all_devs(struct cmd_context *cmd,
break;
}
- if (!_online_pvscan_one(cmd, dev, dev_args, found_vgnames, 1, NULL)) {
+ pvid_without_metadata = NULL;
+
+ if (!_online_pvscan_one(cmd, dev, dev_args, found_vgnames, &all_vgs, 1, &pvid_without_metadata)) {
stack;
break;
}
+
+ /* This PV without metadata may complete a VG. */
+ if (pvid_without_metadata)
+ _check_vg_with_pvid_complete(cmd, found_vgnames, &all_vgs, pvid_without_metadata);
}
+ dm_list_iterate_items(vgl, &all_vgs)
+ release_vg(vgl->vg);
+
dev_iter_destroy(iter);
}
@@ -1034,7 +1127,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
add_single_count++;
- if (!_online_pvscan_one(cmd, dev, NULL, complete_vgnames, 0, &pvid_without_metadata))
+ if (!_online_pvscan_one(cmd, dev, NULL, complete_vgnames, NULL, 0, &pvid_without_metadata))
add_errors++;
}
}
5 years
master - tests: disable unworking pvscan case
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=41ba2b568b3d3ad1d1e...
Commit: 41ba2b568b3d3ad1d1ee2a26cf9f44a2b2e77e8f
Parent: d0b869e46a935003c8ed99dbbbd2d2e745315ff6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Apr 12 15:40:38 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Apr 12 15:40:38 2019 -0500
tests: disable unworking pvscan case
and add corresponding fixme in the code
---
test/shell/pvscan-autoactivate.sh | 22 +++++++++++++---------
tools/pvscan.c | 12 ++++++++++++
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/test/shell/pvscan-autoactivate.sh b/test/shell/pvscan-autoactivate.sh
index 6f00b43..52258f4 100644
--- a/test/shell/pvscan-autoactivate.sh
+++ b/test/shell/pvscan-autoactivate.sh
@@ -94,15 +94,19 @@ lvchange -an $vg1
# is online without the -aay option to
# activate until after they are online
-_clear_online_files
-
-pvscan --cache "$dev1"
-check lv_field $vg1/$lv1 lv_active ""
-pvscan --cache "$dev2"
-check lv_field $vg1/$lv1 lv_active ""
-pvscan --cache -aay
-check lv_field $vg1/$lv1 lv_active "active"
-lvchange -an $vg1
+# This part is disabled because it doesn't work if the
+# 'pvscan --cache -aay' without args ends up scanning
+# dev1 (without metadata) after dev2.
+
+#_clear_online_files
+
+#pvscan --cache "$dev1"
+#check lv_field $vg1/$lv1 lv_active ""
+#pvscan --cache "$dev2"
+#check lv_field $vg1/$lv1 lv_active ""
+#pvscan --cache -aay
+#check lv_field $vg1/$lv1 lv_active "active"
+#lvchange -an $vg1
# like previous
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 6a46490..75c1a2b 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -980,6 +980,18 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
cmd->pvscan_recreate_hints = 1;
pvscan_recreate_hints_begin(cmd);
+ /*
+ * FIXME: if _online_pvscan_all_devs scans a PV without
+ * metadata as the final PV to complete the VG, then
+ * that VG is not added to the complete_vgnames list.
+ * To fix this, we could also keep an incomplete_vg list,
+ * and each incomplete_vg entry would list the PVIDs it
+ * still needed. If a PV without metadata is scanned,
+ * its PVID would be removed from the incomplete_vg entry,
+ * and if the entry had no remaining PVs needed, the vgname
+ * would be added to complete_vgnames.
+ */
+
log_verbose("pvscan all devices for requested refresh.");
_online_files_remove(_pvs_online_dir);
_online_files_remove(_vgs_online_dir);
5 years