master - WHATS_NEW: concurrent pvscan autoactivation
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=eff33684f774bb732e6...
Commit: eff33684f774bb732e66898a65c52163d0987b70
Parent: 74a388cca15baa4149a24e37bccb421c53f726e5
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 21 15:31:23 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 21 15:31:23 2019 -0600
WHATS_NEW: concurrent pvscan autoactivation
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 8088060..b1b19d1 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.03.02 -
===================================
+ Fix pvscan autoactivation for concurrent pvscans.
Change scan_lvs default to 0 so LVs are not scanned for PVs.
Thin-pool selects power-of-2 chunk size by default.
Cache selects power-of-2 chunk size by default.
5 years, 1 month
master - pvscan: autoactivate a VG once
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=74a388cca15baa4149a...
Commit: 74a388cca15baa4149a24e37bccb421c53f726e5
Parent: f0089472e7fd679acbc004daf4b35e9a86fc11a9
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 13 14:21:56 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 21 15:17:41 2019 -0600
pvscan: autoactivate a VG once
When a VG has multiple PVs, and all those PVs come online
at the same time, concurrent pvscans for each PV will all
create the individual pvid files, and all will often see
the VG is now complete. This causes each of the pvscan
commands to think it should activate the VG, so there
are multiple activations of the same VG. The vg lock
serializes them, and only the first pvscan actually does
the activation, but there is still a lot of extra overhead
and time used by the other pvscans that attempt to
activate the already active VG. This can lead to a backlog
of pvscans and timeouts.
To fix this, this adds a new /run/lvm/vgs_online/ dir that
works like the existing /run/lvm/pvs_online/ dir. Each pvscan
that wants to activate a VG will first try to exlusively create
the file vgs_online/<vgname>. Only the first pvscan will
succeed, and that one will do the VG activation. The other
pvscans will find the vgname file exists and will not do the
activation step.
When a PV goes offline, the vgs_online file for the corresponding
VG is removed. This allows the VG to be autoactivated again
when the PV comes online again. This requires that the vgname be
stored in the pvid files.
---
test/shell/pvscan-autoactivate.sh | 39 ++++---
test/shell/pvscan-cache.sh | 20 +++-
tools/pvscan.c | 214 +++++++++++++++++++++++++++++++-----
3 files changed, 226 insertions(+), 47 deletions(-)
diff --git a/test/shell/pvscan-autoactivate.sh b/test/shell/pvscan-autoactivate.sh
index cd360e9..419fb9b 100644
--- a/test/shell/pvscan-autoactivate.sh
+++ b/test/shell/pvscan-autoactivate.sh
@@ -14,14 +14,15 @@ SKIP_WITH_LVMPOLLD=1
RUNDIR="/run"
test -d "$RUNDIR" || RUNDIR="/var/run"
-ONLINEDIR="$RUNDIR/lvm/pvs_online"
+PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online"
+VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online"
# FIXME: kills logic for running system
-_clear_online() {
+_clear_online_files() {
# wait till udev is finished
aux udev_wait
- rm -f "$ONLINEDIR"/*
- test -n "${1+varset}" || touch "$ONLINEDIR/foo"
+ rm -f "$PVS_ONLINE_DIR"/*
+ rm -f "$VGS_ONLINE_DIR"/*
}
. lib/inittest
@@ -32,8 +33,9 @@ vgcreate $vg1 "$dev1" "$dev2"
lvcreate -n $lv1 -l 4 -a n $vg1
# the first pvscan scans all devs
-test -d "$ONLINEDIR" || mkdir -p "$ONLINEDIR"
-_clear_online nofoo
+test -d "$PVS_ONLINE_DIR" || mkdir -p "$PVS_ONLINE_DIR"
+test -d "$VGS_ONLINE_DIR" || mkdir -p "$VGS_ONLINE_DIR"
+_clear_online_files
pvscan --cache -aay
check lv_field $vg1/$lv1 lv_active "active"
@@ -42,7 +44,7 @@ lvchange -an $vg1
# the first pvscan scans all devs even when
# only one device is specified
-_clear_online nofoo
+_clear_online_files
pvscan --cache -aay "$dev1"
check lv_field $vg1/$lv1 lv_active "active"
@@ -50,7 +52,8 @@ lvchange -an $vg1
# touch foo to disable first-pvscan case,
# then check pvscan with no args scans all
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache -aay
check lv_field $vg1/$lv1 lv_active "active"
@@ -60,7 +63,8 @@ lvchange -an $vg1
# then check that vg is activated only after
# both devs appear separately
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache -aay "$dev1"
check lv_field $vg1/$lv1 lv_active ""
@@ -72,7 +76,8 @@ lvchange -an $vg1
# then check that vg is activated when both
# devs appear together
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache -aay "$dev1" "$dev2"
check lv_field $vg1/$lv1 lv_active "active"
@@ -92,7 +97,8 @@ lvcreate -n $lv1 -l 4 -a n $vg1
# touch foo to disable first-pvscan case,
# test case where dev with metadata appears first
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache -aay "$dev2"
check lv_field $vg1/$lv1 lv_active ""
@@ -104,7 +110,8 @@ lvchange -an $vg1
# test case where dev without metadata
# appears first which triggers scanning all
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache -aay "$dev1"
check lv_field $vg1/$lv1 lv_active "active"
@@ -115,7 +122,7 @@ lvchange -an $vg1
# dev without metadata is scanned, but
# first-pvscan case scans all devs
-_clear_online nofoo
+_clear_online_files
pvscan --cache -aay "$dev1"
check lv_field $vg1/$lv1 lv_active "active"
@@ -125,7 +132,8 @@ lvchange -an $vg1
# is online without the -aay option to
# activate until after they are online
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache "$dev1"
check lv_field $vg1/$lv1 lv_active ""
@@ -137,7 +145,8 @@ lvchange -an $vg1
# like previous
-_clear_online
+_clear_online_files
+touch "$RUNDIR/lvm/pvs_online/foo"
pvscan --cache "$dev1"
check lv_field $vg1/$lv1 lv_active ""
diff --git a/test/shell/pvscan-cache.sh b/test/shell/pvscan-cache.sh
index c272c6c..e0576f9 100644
--- a/test/shell/pvscan-cache.sh
+++ b/test/shell/pvscan-cache.sh
@@ -13,6 +13,18 @@
SKIP_WITH_LVMLOCKD=1
SKIP_WITH_LVMPOLLD=1
+RUNDIR="/run"
+test -d "$RUNDIR" || RUNDIR="/var/run"
+PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online"
+VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online"
+
+_clear_online_files() {
+ # wait till udev is finished
+ aux udev_wait
+ rm -f "$PVS_ONLINE_DIR"/*
+ rm -f "$VGS_ONLINE_DIR"/*
+}
+
. lib/inittest
aux prepare_pvs 2
@@ -35,9 +47,12 @@ check lv_exists $vg1
check lv_field $vg1/$lv1 lv_active ""
# Check that an LV cannot be activated by pvscan while VG is exported
+vgchange -an $vg1
+_clear_online_files
vgexport $vg1
-not pvscan --cache -aay "$dev1"
-not pvscan --cache -aay "$dev2"
+pvscan --cache -aay "$dev1" || true
+pvscan --cache -aay "$dev2" || true
+_clear_online_files
vgimport $vg1
check lv_exists $vg1
check lv_field $vg1/$lv1 lv_active ""
@@ -51,6 +66,7 @@ lvchange -an $vg1/$lv1
# metadata which hasn't been updated for some
# time and also since the MDA is marked as ignored,
# it should really be *ignored*!
+_clear_online_files
pvchange --metadataignore y "$dev1"
aux disable_dev "$dev2"
pvscan --cache
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 5928f7e..c6f2902 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -37,6 +37,9 @@ struct pvscan_aa_params {
unsigned int activate_errors;
};
+
+static const char *_pvs_online_dir = DEFAULT_RUN_DIR "/pvs_online";
+static const char *_vgs_online_dir = DEFAULT_RUN_DIR "/vgs_online";
static const char *_online_file = DEFAULT_RUN_DIR "/pvs_online_lock";
static int _online_fd = -1;
@@ -228,7 +231,51 @@ out:
return ret;
}
-static const char *_pvs_online_dir = DEFAULT_RUN_DIR "/pvs_online";
+static char *_vgname_in_pvid_file_buf(char *buf)
+{
+ char *p, *n;
+
+ /*
+ * file contains:
+ * <major>:<minor>\n
+ * vg:<vgname>\n\0
+ */
+
+ if (!(p = strchr(buf, '\n')))
+ return NULL;
+
+ p++; /* skip \n */
+
+ if (*p && !strncmp(p, "vg:", 3)) {
+ if ((n = strchr(p, '\n')))
+ *n = '\0';
+ return p + 3;
+ }
+ return NULL;
+}
+
+#define MAX_PVID_FILE_SIZE 512
+
+/*
+ * When a PV goes offline, remove the vg online file for that VG
+ * (even if other PVs for the VG are still online). This means
+ * that the vg will be activated again when it becomes complete.
+ */
+
+static void _online_vg_file_remove(const char *vgname)
+{
+ char path[PATH_MAX];
+
+ if (dm_snprintf(path, sizeof(path), "%s/%s", _vgs_online_dir, vgname) < 0) {
+ log_error("Path %s/%s is too long.", _vgs_online_dir, vgname);
+ return;
+ }
+
+ log_debug("Unlink vg online: %s", path);
+
+ if (unlink(path))
+ log_sys_debug("unlink", path);
+}
/*
* When a device goes offline we only know its major:minor, not its PVID.
@@ -241,8 +288,9 @@ static const char *_pvs_online_dir = DEFAULT_RUN_DIR "/pvs_online";
static void _online_pvid_file_remove_devno(int major, int minor)
{
char path[PATH_MAX];
- char buf[32];
- char buf_in[32];
+ char buf[MAX_PVID_FILE_SIZE];
+ char buf_in[MAX_PVID_FILE_SIZE];
+ char *vgname = NULL;
DIR *dir;
struct dirent *de;
int fd, rv;
@@ -268,6 +316,8 @@ static void _online_pvid_file_remove_devno(int major, int minor)
continue;
}
+ memset(buf_in, 0, sizeof(buf_in));
+
rv = read(fd, buf_in, sizeof(buf_in));
if (close(fd))
log_sys_debug("close", path);
@@ -277,9 +327,16 @@ static void _online_pvid_file_remove_devno(int major, int minor)
}
if (!strncmp(buf, buf_in, strlen(buf))) {
- log_debug("Unlink pv online %s %s", buf, path);
+ log_debug("Unlink pv online %s", path);
if (unlink(path))
log_sys_debug("unlink", path);
+
+ /* vgname points to an offset in buf_in */
+ if ((vgname = _vgname_in_pvid_file_buf(buf_in)))
+ _online_vg_file_remove(vgname);
+ else
+ log_debug("No vgname in pvid file");
+
break;
}
}
@@ -287,13 +344,13 @@ static void _online_pvid_file_remove_devno(int major, int minor)
log_sys_debug("closedir", _pvs_online_dir);
}
-static void _online_pvid_files_remove(void)
+static void _online_files_remove(const char *dirpath)
{
char path[PATH_MAX];
DIR *dir;
struct dirent *de;
- if (!(dir = opendir(_pvs_online_dir)))
+ if (!(dir = opendir(dirpath)))
return;
while ((de = readdir(dir))) {
@@ -301,22 +358,26 @@ static void _online_pvid_files_remove(void)
continue;
memset(path, 0, sizeof(path));
- snprintf(path, sizeof(path), "%s/%s", _pvs_online_dir, de->d_name);
+ snprintf(path, sizeof(path), "%s/%s", dirpath, de->d_name);
if (unlink(path))
log_sys_debug("unlink", path);
}
if (closedir(dir))
- log_sys_debug("closedir", _pvs_online_dir);
+ log_sys_debug("closedir", dirpath);
}
-static int _online_pvid_file_create(struct device *dev)
+static int _online_pvid_file_create(struct device *dev, const char *vgname)
{
char path[PATH_MAX];
- char buf[32];
+ char buf[MAX_PVID_FILE_SIZE];
int major, minor;
int fd;
int rv;
int len;
+ int len1 = 0;
+ int len2 = 0;
+
+ memset(buf, 0, sizeof(buf));
major = (int)MAJOR(dev->dev);
minor = (int)MINOR(dev->dev);
@@ -326,16 +387,26 @@ static int _online_pvid_file_create(struct device *dev)
return 0;
}
- if ((len = dm_snprintf(buf, sizeof(buf), "%d:%d\n", major, minor)) < 0) {
- log_error("Device %d:%d is too long.", major, minor);
+ if ((len1 = dm_snprintf(buf, sizeof(buf), "%d:%d\n", major, minor)) < 0) {
+ log_error("Cannot create online pv file for %d:%d.", major, minor);
return 0;
}
+ if (vgname) {
+ if ((len2 = dm_snprintf(buf + len1, sizeof(buf) - len1, "vg:%s\n", vgname)) < 0) {
+ log_warn("Incomplete online pv file for %d:%d vg %s.", major, minor, vgname);
+ /* can still continue without vgname */
+ len2 = 0;
+ }
+ }
+
+ len = len1 + len2;
+
log_debug("Create pv online: %s %d:%d %s", path, major, minor, dev_name(dev));
fd = open(path, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
- log_error("Failed to open %s: %d", path, errno);
+ log_error("Failed to open create %s: %d", path, errno);
return 0;
}
@@ -380,20 +451,45 @@ static int _online_pvid_file_exists(const char *pvid)
return 0;
}
-static void _online_pvid_dir_setup(void)
+static void _online_dir_setup(void)
{
struct stat st;
int rv;
+ if (!stat(DEFAULT_RUN_DIR, &st))
+ goto do_pvs;
+
+ log_debug("Creating run_dir.");
+ dm_prepare_selinux_context(DEFAULT_RUN_DIR, S_IFDIR);
+ rv = mkdir(DEFAULT_RUN_DIR, 0755);
+ dm_prepare_selinux_context(NULL, 0);
+
+ if ((rv < 0) && stat(DEFAULT_RUN_DIR, &st))
+ log_error("Failed to create %s %d", DEFAULT_RUN_DIR, errno);
+
+do_pvs:
if (!stat(_pvs_online_dir, &st))
- return;
+ goto do_vgs;
+ log_debug("Creating pvs_online_dir.");
dm_prepare_selinux_context(_pvs_online_dir, S_IFDIR);
- rv = mkdir(_pvs_online_dir, 0777);
+ rv = mkdir(_pvs_online_dir, 0755);
+ dm_prepare_selinux_context(NULL, 0);
+
+ if ((rv < 0) && stat(_pvs_online_dir, &st))
+ log_error("Failed to create %s %d", _pvs_online_dir, errno);
+
+do_vgs:
+ if (!stat(_vgs_online_dir, &st))
+ return;
+
+ log_debug("Creating vgs_online_dir.");
+ dm_prepare_selinux_context(_vgs_online_dir, S_IFDIR);
+ rv = mkdir(_vgs_online_dir, 0755);
dm_prepare_selinux_context(NULL, 0);
- if (rv < 0)
- log_debug("Failed to create %s", _pvs_online_dir);
+ if ((rv < 0) && stat(_vgs_online_dir, &st))
+ log_error("Failed to create %s %d", _vgs_online_dir, errno);
}
static void _online_file_setup(void)
@@ -404,8 +500,10 @@ static void _online_file_setup(void)
if (!stat(_online_file, &st))
return;
- if (!(fp = fopen(_online_file, "w")))
+ if (!(fp = fopen(_online_file, "w"))) {
+ log_error("Failed to create %s %d", _online_file, errno);
return;
+ }
if (fclose(fp))
stack;
}
@@ -445,11 +543,13 @@ static int _online_pv_found(struct cmd_context *cmd,
* Create file named for pvid to record this PV is online.
*/
- if (!_online_pvid_file_create(dev))
+ if (!_online_pvid_file_create(dev, vg ? vg->name : NULL))
return_0;
- if (!vg || !found_vgnames)
+ if (!vg || !found_vgnames) {
+ log_print("pvscan[%d] PV %s online.", getpid(), dev_name(dev));
return 1;
+ }
/*
* Check if all the PVs for this VG are online. This is only
@@ -472,8 +572,13 @@ static int _online_pv_found(struct cmd_context *cmd,
* in the VG, which means the VG is not yet complete.
*/
- if (pvids_not_online)
+ if (pvids_not_online) {
+ log_print("pvscan[%d] PV %s online, VG %s incomplete (need %d).",
+ getpid(), dev_name(dev), vg->name, pvids_not_online);
return 1;
+ }
+
+ log_print("pvscan[%d] PV %s online, VG %s is complete.", getpid(), dev_name(dev), vg->name);
/*
* When all PVIDs from the VG are online, then add vgname to
@@ -544,7 +649,7 @@ static int _online_pvscan_one(struct cmd_context *cmd, struct device *dev,
log_debug("pvscan metadata from dev %s", dev_name(dev));
if (udev_dev_is_mpath_component(dev)) {
- log_debug("Ignore multipath component for pvscan.");
+ log_print("pvscan[%d] ignore multipath component %s.", getpid(), dev_name(dev));
return 1;
}
@@ -652,10 +757,37 @@ static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name,
return ECMD_PROCESSED;
}
+static int _online_vg_file_create(struct cmd_context *cmd, const char *vgname)
+{
+ char path[PATH_MAX];
+ int fd;
+
+ if (dm_snprintf(path, sizeof(path), "%s/%s", _vgs_online_dir, vgname) < 0) {
+ log_error("Path %s/%s is too long.", _vgs_online_dir, vgname);
+ return 0;
+ }
+
+ log_debug("Create vg online: %s", path);
+
+ fd = open(path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ log_debug("Failed to create %s: %d", path, errno);
+ return 0;
+ }
+
+ /* We don't care about syncing, these files are not even persistent. */
+
+ if (close(fd))
+ log_sys_debug("close", path);
+
+ return 1;
+}
+
static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
struct dm_list *vgnames)
{
struct processing_handle *handle = NULL;
+ struct dm_str_list *sl, *sl2;
int ret;
if (dm_list_empty(vgnames)) {
@@ -670,6 +802,27 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
handle->custom_handle = pp;
+ /*
+ * For each complete vg that can be autoactivated, see if this
+ * particular pvscan command should activate the vg. There can be
+ * multiple concurrent pvscans for the same completed vg (when all the
+ * PVs for the VG appear at once), and we want only one of the pvscans
+ * to run the activation. The first to create the file will do it.
+ */
+ dm_list_iterate_items_safe(sl, sl2, vgnames) {
+ if (!_online_vg_file_create(cmd, sl->str)) {
+ log_print("pvscan[%d] VG %s skip autoactivation.", getpid(), sl->str);
+ str_list_del(vgnames, sl->str);
+ continue;
+ }
+ log_print("pvscan[%d] VG %s run autoactivation.", getpid(), sl->str);
+ }
+
+ if (dm_list_empty(vgnames)) {
+ destroy_processing_handle(cmd, handle);
+ return ECMD_PROCESSED;
+ }
+
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_UPDATE, 0, handle, _pvscan_aa_single);
destroy_processing_handle(cmd, handle);
@@ -711,7 +864,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- _online_pvid_dir_setup();
+ _online_dir_setup();
_online_file_setup();
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
@@ -734,8 +887,8 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
_lock_online(LOCK_EX, 0);
log_verbose("pvscan all devices for requested refresh.");
- _online_pvid_files_remove();
- /* identify complete vgs, and only activate those vgs */
+ _online_files_remove(_pvs_online_dir);
+ _online_files_remove(_vgs_online_dir);
_online_pvscan_all_devs(cmd, complete_vgnames, NULL);
_unlock_online();
goto activate;
@@ -763,16 +916,17 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
* In the non-init case, a VG with two PVs, where both PVs appear at once,
* two parallel pvscans for each PV create the pvid files for each PV in
* parallel, then both pvscans see the vg has completed, and both pvscans
- * activate the VG in parallel. The activations should be serialized by
- * the VG lock.
+ * activate the VG in parallel. The first pvscan to create the vgname
+ * file in vgs_online will do the activation, any others will skip it.
*/
_lock_online(LOCK_EX, 0);
if (_online_pvid_files_missing()) {
log_verbose("pvscan all devices to initialize available PVs.");
- _online_pvid_files_remove();
- /* identify complete vgs, and only activate those vgs */
+ _online_files_remove(_pvs_online_dir);
+ _online_files_remove(_vgs_online_dir);
+ cmd->pvscan_cache_single = 1;
_online_pvscan_all_devs(cmd, complete_vgnames, NULL);
_unlock_online();
goto activate;
5 years, 1 month
master - pvscan: fix autoactivation from concurrent pvscans
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f0089472e7fd679acbc...
Commit: f0089472e7fd679acbc004daf4b35e9a86fc11a9
Parent: 71a302effe82f1cc89f0b26b358493cfaaed7de7
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 13 13:35:24 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 16:33:59 2019 -0600
pvscan: fix autoactivation from concurrent pvscans
Use a file lock to ensure that only one pvscan will do
initialization of pvs_online, otherwise multiple concurrent
pvscans may all see an empty pvs_online directory and
do initialization.
The pvscan that is doing initialization should also only
attempt to activate complete VGs.
---
tools/pvscan.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 120 insertions(+), 24 deletions(-)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 55b6f5f..5928f7e 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -20,6 +20,7 @@
#include "lib/label/hints.h"
#include <dirent.h>
+#include <sys/file.h>
struct pvscan_params {
int new_pvs_found;
@@ -33,10 +34,61 @@ struct pvscan_params {
};
struct pvscan_aa_params {
- int refresh_all;
unsigned int activate_errors;
};
+static const char *_online_file = DEFAULT_RUN_DIR "/pvs_online_lock";
+static int _online_fd = -1;
+
+static int _lock_online(int mode, int nonblock)
+{
+ int fd;
+ int op = mode;
+ int ret;
+
+ if (nonblock)
+ op |= LOCK_NB;
+
+ if (_online_fd != -1) {
+ log_warn("lock_online existing fd %d", _online_fd);
+ return 0;
+ }
+
+ fd = open(_online_file, O_RDWR | S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ log_debug("lock_online open errno %d", errno);
+ return 0;
+ }
+
+ ret = flock(fd, op);
+ if (!ret) {
+ _online_fd = fd;
+ return 1;
+ }
+
+ if (close(fd))
+ stack;
+ return 0;
+}
+
+static void _unlock_online(void)
+{
+ int ret;
+
+ if (_online_fd == -1) {
+ log_warn("unlock_online no existing fd");
+ return;
+ }
+
+ ret = flock(_online_fd, LOCK_UN);
+ if (ret)
+ log_warn("unlock_online flock errno %d", errno);
+
+ if (close(_online_fd))
+ stack;
+ _online_fd = -1;
+}
+
static int _pvscan_display_pv(struct cmd_context *cmd,
struct physical_volume *pv,
struct pvscan_params *params)
@@ -344,6 +396,20 @@ static void _online_pvid_dir_setup(void)
log_debug("Failed to create %s", _pvs_online_dir);
}
+static void _online_file_setup(void)
+{
+ FILE *fp;
+ struct stat st;
+
+ if (!stat(_online_file, &st))
+ return;
+
+ if (!(fp = fopen(_online_file, "w")))
+ return;
+ if (fclose(fp))
+ stack;
+}
+
static int _online_pvid_files_missing(void)
{
DIR *dir;
@@ -587,12 +653,12 @@ static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name,
}
static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
- int all_vgs, struct dm_list *vgnames)
+ struct dm_list *vgnames)
{
struct processing_handle *handle = NULL;
int ret;
- if (!all_vgs && dm_list_empty(vgnames)) {
+ if (dm_list_empty(vgnames)) {
log_debug("No VGs to autoactivate.");
return ECMD_PROCESSED;
}
@@ -604,11 +670,6 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
handle->custom_handle = pp;
- if (all_vgs) {
- cmd->cname->flags |= ALL_VGS_IS_DEFAULT;
- pp->refresh_all = 1;
- }
-
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_UPDATE, 0, handle, _pvscan_aa_single);
destroy_processing_handle(cmd, handle);
@@ -620,7 +681,8 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
{
struct pvscan_aa_params pp = { 0 };
struct dm_list single_devs;
- struct dm_list found_vgnames;
+ struct dm_list vgnames;
+ struct dm_list *complete_vgnames = NULL;
struct device *dev;
struct device_list *devl;
const char *pv_name;
@@ -631,13 +693,15 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
struct arg_value_group_list *current_group;
dev_t devno;
int do_activate = arg_is_set(cmd, activate_ARG);
- int all_vgs = 0;
int add_errors = 0;
int add_single_count = 0;
int ret = ECMD_PROCESSED;
dm_list_init(&single_devs);
- dm_list_init(&found_vgnames);
+ dm_list_init(&vgnames);
+
+ if (do_activate)
+ complete_vgnames = &vgnames;
if (arg_is_set(cmd, major_ARG) + arg_is_set(cmd, minor_ARG))
devno_args = 1;
@@ -648,6 +712,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
}
_online_pvid_dir_setup();
+ _online_file_setup();
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
log_error("Unable to obtain global lock.");
@@ -667,22 +732,53 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
cmd->pvscan_recreate_hints = 1;
pvscan_recreate_hints_begin(cmd);
- log_verbose("pvscan all devices.");
+ _lock_online(LOCK_EX, 0);
+ log_verbose("pvscan all devices for requested refresh.");
_online_pvid_files_remove();
- _online_pvscan_all_devs(cmd, NULL, NULL);
- all_vgs = 1;
-
- cmd->pvscan_recreate_hints = 0;
- cmd->use_hints = 0;
+ /* identify complete vgs, and only activate those vgs */
+ _online_pvscan_all_devs(cmd, complete_vgnames, NULL);
+ _unlock_online();
goto activate;
}
+ /*
+ * Initialization case:
+ * lock_online ex
+ * if empty
+ * pvscan all
+ * create pvid files
+ * identify complete vgs
+ * unlock_online
+ * activate complete vgs
+ *
+ * Non-initialization case:
+ * lock_online ex
+ * if not empty
+ * unlock_unlock
+ * pvscan devs
+ * create pvid files
+ * identify complete vgs
+ * activate complete vgs
+ *
+ * In the non-init case, a VG with two PVs, where both PVs appear at once,
+ * two parallel pvscans for each PV create the pvid files for each PV in
+ * parallel, then both pvscans see the vg has completed, and both pvscans
+ * activate the VG in parallel. The activations should be serialized by
+ * the VG lock.
+ */
+
+ _lock_online(LOCK_EX, 0);
+
if (_online_pvid_files_missing()) {
log_verbose("pvscan all devices to initialize available PVs.");
_online_pvid_files_remove();
- _online_pvscan_all_devs(cmd, NULL, NULL);
- all_vgs = 1;
+ /* identify complete vgs, and only activate those vgs */
+ _online_pvscan_all_devs(cmd, complete_vgnames, NULL);
+ _unlock_online();
goto activate;
+ } else {
+ log_verbose("pvscan only specific devices.");
+ _unlock_online();
}
if (argc || devno_args) {
@@ -761,7 +857,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
* Devices that exist and pass the lvmetad filter
* are online.
*/
- if (!_online_pvscan_one(cmd, dev, NULL, &found_vgnames, 0, &pvid_without_metadata))
+ if (!_online_pvscan_one(cmd, dev, NULL, complete_vgnames, 0, &pvid_without_metadata))
add_errors++;
}
}
@@ -814,7 +910,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
* Devices that exist and pass the lvmetad filter
* are online.
*/
- if (!_online_pvscan_one(cmd, devl->dev, NULL, &found_vgnames, 0, &pvid_without_metadata))
+ if (!_online_pvscan_one(cmd, devl->dev, NULL, complete_vgnames, 0, &pvid_without_metadata))
add_errors++;
}
}
@@ -839,10 +935,10 @@ activate:
* scan all devs and pick out the complete VG holding this
* device so we can then autoactivate that VG.
*/
- if (!dm_list_empty(&single_devs) && dm_list_empty(&found_vgnames) &&
+ if (!dm_list_empty(&single_devs) && complete_vgnames && dm_list_empty(complete_vgnames) &&
pvid_without_metadata && do_activate) {
log_verbose("pvscan all devices for PV without metadata: %s.", pvid_without_metadata);
- _online_pvscan_all_devs(cmd, &found_vgnames, &single_devs);
+ _online_pvscan_all_devs(cmd, complete_vgnames, &single_devs);
}
/*
@@ -851,7 +947,7 @@ activate:
* list, and we can attempt to autoactivate LVs in the VG.
*/
if (do_activate)
- ret = _pvscan_aa(cmd, &pp, all_vgs, &found_vgnames);
+ ret = _pvscan_aa(cmd, &pp, complete_vgnames);
out:
if (add_errors || pp.activate_errors)
5 years, 1 month
stable-2.02 - tests: add scan_lvs.sh
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=850e95f24a86c448736...
Commit: 850e95f24a86c4487363c6cf43b10c15a86b0c26
Parent: 083f162e8e01eca1a6c66b4d9bfeede05ed6feab
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 20 14:38:01 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 14:38:01 2019 -0600
tests: add scan_lvs.sh
---
test/shell/scan-lvs.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/test/shell/scan-lvs.sh b/test/shell/scan-lvs.sh
new file mode 100644
index 0000000..8e8a77d
--- /dev/null
+++ b/test/shell/scan-lvs.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Copyright (C) 2014 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 scan_lvs config setting
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux extend_filter_LVMTEST
+
+aux lvmconf 'devices/scan_lvs = 1'
+
+aux prepare_pvs 1
+
+vgcreate $SHARED $vg1 "$dev1"
+
+lvcreate -l1 -n $lv1 $vg1
+
+pvcreate "$DM_DEV_DIR/$vg1/$lv1"
+
+pvs "$DM_DEV_DIR/$vg1/$lv1"
+
+aux lvmconf 'devices/scan_lvs = 0'
+
+not pvs "$DM_DEV_DIR/$vg1/$lv1"
+
+pvs --config devices/scan_lvs=1 "$DM_DEV_DIR/$vg1/$lv1"
+
+not pvremove "$DM_DEV_DIR/$vg1/$lv1"
+
+pvremove --config devices/scan_lvs=1 "$DM_DEV_DIR/$vg1/$lv1"
+
+lvchange -an "$vg1/$lv1"
+
+lvremove "$vg1/$lv1"
+
+vgremove $vg1
+
5 years, 1 month
stable-2.02 - WHATS_NEW: scan_lvs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=083f162e8e01eca1a6c...
Commit: 083f162e8e01eca1a6c66b4d9bfeede05ed6feab
Parent: 7f56908c2beb6161256af4ccdbeaf86309a9b6cf
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 20 14:33:09 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 14:33:09 2019 -0600
WHATS_NEW: scan_lvs
---
WHATS_NEW | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 4d1ece4..cbb5505 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.184 -
=====================================
+ Change scan_lvs default to 0 so LVs are not scanned for PVs.
+ Add scan_lvs config setting to control if lvm scans LVs for PVs.
Fix missing proper initialization of pv_list struct when adding pv.
Version 2.02.183 - 07th December 2018
5 years, 1 month
stable-2.02 - tests: set scan_lvs=1 in tests that stack PVs on LVs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7f56908c2beb6161256...
Commit: 7f56908c2beb6161256af4ccdbeaf86309a9b6cf
Parent: 427e8ba3e3186e291ff26f014003d149da6ec2a8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 20 13:31:30 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 14:32:01 2019 -0600
tests: set scan_lvs=1 in tests that stack PVs on LVs
---
test/shell/discards-thin.sh | 2 ++
test/shell/lvconvert-thin.sh | 2 ++
test/shell/lvcreate-large-raid10.sh | 1 +
test/shell/lvcreate-large.sh | 2 ++
test/shell/pvcreate-restore.sh | 2 ++
test/shell/pvremove-thin.sh | 2 ++
test/shell/snapshot-remove-dmsetup.sh | 2 ++
test/shell/snapshot-usage-exa.sh | 2 ++
test/shell/snapshot-usage.sh | 2 ++
test/shell/vgsplit-stacked.sh | 2 ++
10 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/test/shell/discards-thin.sh b/test/shell/discards-thin.sh
index f27d4c3..3564a87 100644
--- a/test/shell/discards-thin.sh
+++ b/test/shell/discards-thin.sh
@@ -25,6 +25,8 @@ export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
#
aux have_thin 1 1 0 || skip
+aux lvmconf 'devices/scan_lvs = 1'
+
aux prepare_vg 2 64
get_devs
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 1f8d2ed..731c45b 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -17,6 +17,8 @@ export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
prepare_lvs() {
lvremove -f $vg
lvcreate -L10M -n $lv1 $vg
diff --git a/test/shell/lvcreate-large-raid10.sh b/test/shell/lvcreate-large-raid10.sh
index a46be37..1ad09aa 100644
--- a/test/shell/lvcreate-large-raid10.sh
+++ b/test/shell/lvcreate-large-raid10.sh
@@ -20,6 +20,7 @@ SKIP_WITH_LVMPOLLD=1
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
aux have_raid 1 3 0 || skip
+aux lvmconf 'devices/scan_lvs = 1'
aux prepare_vg 5
diff --git a/test/shell/lvcreate-large.sh b/test/shell/lvcreate-large.sh
index 473b0ed..b1cb0b0 100644
--- a/test/shell/lvcreate-large.sh
+++ b/test/shell/lvcreate-large.sh
@@ -17,6 +17,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
diff --git a/test/shell/pvcreate-restore.sh b/test/shell/pvcreate-restore.sh
index d0b46eb..789f45c 100644
--- a/test/shell/pvcreate-restore.sh
+++ b/test/shell/pvcreate-restore.sh
@@ -15,6 +15,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux prepare_vg 4
lvcreate --type snapshot -s -L10 -n $lv1 $vg --virtualsize 2T
diff --git a/test/shell/pvremove-thin.sh b/test/shell/pvremove-thin.sh
index 9859b6c..84a2a55 100644
--- a/test/shell/pvremove-thin.sh
+++ b/test/shell/pvremove-thin.sh
@@ -18,6 +18,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux prepare_vg
aux have_thin 1 8 0 || skip
diff --git a/test/shell/snapshot-remove-dmsetup.sh b/test/shell/snapshot-remove-dmsetup.sh
index a7925d5..a234e5a 100644
--- a/test/shell/snapshot-remove-dmsetup.sh
+++ b/test/shell/snapshot-remove-dmsetup.sh
@@ -19,6 +19,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
which mkfs.ext2 || skip
aux prepare_vg 5
diff --git a/test/shell/snapshot-usage-exa.sh b/test/shell/snapshot-usage-exa.sh
index 5d666bf..f537f0d 100644
--- a/test/shell/snapshot-usage-exa.sh
+++ b/test/shell/snapshot-usage-exa.sh
@@ -18,6 +18,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux can_use_16T || skip
aux prepare_pvs 1
diff --git a/test/shell/snapshot-usage.sh b/test/shell/snapshot-usage.sh
index bcfa16a..5cfdae6 100644
--- a/test/shell/snapshot-usage.sh
+++ b/test/shell/snapshot-usage.sh
@@ -17,6 +17,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
MKFS=mkfs.ext2
which $MKFS || skip
diff --git a/test/shell/vgsplit-stacked.sh b/test/shell/vgsplit-stacked.sh
index 331ee8e..09af3f7 100644
--- a/test/shell/vgsplit-stacked.sh
+++ b/test/shell/vgsplit-stacked.sh
@@ -15,6 +15,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux extend_filter_LVMTEST
aux prepare_pvs 3
5 years, 1 month
stable-2.02 - config: change scan_lvs default to 0
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=427e8ba3e3186e291ff...
Commit: 427e8ba3e3186e291ff26f014003d149da6ec2a8
Parent: 6a5575e9597c50a7ebc89895de154db3fa13d753
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 20 14:31:03 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 14:31:03 2019 -0600
config: change scan_lvs default to 0
so that lvm does not scan LVs for PVs by default.
---
lib/config/defaults.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 12d8e1d..7a5d365 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -267,6 +267,6 @@
#define DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD 100
#define DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT 20
-#define DEFAULT_SCAN_LVS 1
+#define DEFAULT_SCAN_LVS 0
#endif /* _LVM_DEFAULTS_H */
5 years, 1 month
stable-2.02 - filter: add config setting to skip scanning LVs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6a5575e9597c50a7ebc...
Commit: 6a5575e9597c50a7ebc89895de154db3fa13d753
Parent: 57cde6063f3073e73542c5f7f59d0269ad9b703b
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Aug 29 13:14:18 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 14:30:24 2019 -0600
filter: add config setting to skip scanning LVs
devices/scan_lvs (default 1) determines whether lvm
will scan LVs for layered PVs. The lvm behavior has
always been to scan LVs, but it's rare for LVs to have
layered PVs, and much more common for there to be many
LVs that substantially slow down scanning with no benefit.
This is implemented in the usable filter, and has the
same effect as listing all LVs in the global_filter.
---
lib/activate/activate.h | 1 +
lib/activate/dev_manager.c | 5 +++++
lib/commands/toolcontext.c | 4 ++--
lib/config/config_settings.h | 3 +++
lib/config/defaults.h | 2 ++
lib/filters/filter-usable.c | 27 ++++++++++++++++++++++-----
lib/filters/filter.h | 2 +-
7 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index d2c6db7..524d2bf 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -234,6 +234,7 @@ struct dev_usable_check_params {
unsigned int check_suspended:1;
unsigned int check_error_target:1;
unsigned int check_reserved:1;
+ unsigned int check_lv:1;
};
/*
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index d281b60..1f4ec65 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -640,6 +640,11 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check)
}
}
+ if (check.check_lv && uuid && !strncmp(uuid, "LVM-", 4)) {
+ /* Skip LVs */
+ goto out;
+ }
+
if (check.check_reserved && uuid &&
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index ecd8fd7..3289b38 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1115,7 +1115,7 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
nr_filt++;
/* usable device filter. Required. */
- if (!(filters[nr_filt] = usable_filter_create(cmd->dev_types,
+ if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types,
lvmetad_used() ? FILTER_MODE_PRE_LVMETAD
: FILTER_MODE_NO_LVMETAD))) {
log_error("Failed to create usabled device filter");
@@ -1235,7 +1235,7 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
}
nr_filt++;
}
- if (!(filter_components[nr_filt] = usable_filter_create(cmd->dev_types, FILTER_MODE_POST_LVMETAD))) {
+ if (!(filter_components[nr_filt] = usable_filter_create(cmd, cmd->dev_types, FILTER_MODE_POST_LVMETAD))) {
log_verbose("Failed to create usable device filter.");
goto bad;
}
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 3433d0c..8fe7ec9 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -345,6 +345,9 @@ cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, 0, CFG_TYPE_BOOL,
"This is a quick way of filtering out block devices that are not\n"
"present on the system. sysfs must be part of the kernel and mounted.)\n")
+cfg(devices_scan_lvs_CFG, "scan_lvs", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SCAN_LVS, vsn(2, 2, 182), NULL, 0, NULL,
+ "Scan LVM LVs for layered PVs.\n")
+
cfg(devices_multipath_component_detection_CFG, "multipath_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MULTIPATH_COMPONENT_DETECTION, vsn(2, 2, 89), NULL, 0, NULL,
"Ignore devices that are components of DM multipath devices.\n")
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index fc2f603..12d8e1d 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -267,4 +267,6 @@
#define DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD 100
#define DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT 20
+#define DEFAULT_SCAN_LVS 1
+
#endif /* _LVM_DEFAULTS_H */
diff --git a/lib/filters/filter-usable.c b/lib/filters/filter-usable.c
index 2de2a0f..bb392a9 100644
--- a/lib/filters/filter-usable.c
+++ b/lib/filters/filter-usable.c
@@ -20,6 +20,11 @@
#include "dev-ext-udev-constants.h"
#endif
+struct filter_data {
+ filter_mode_t mode;
+ int skip_lvs;
+};
+
static const char *_too_small_to_hold_pv_msg = "Too small to hold a PV";
static int _native_check_pv_min_size(struct device *dev)
@@ -101,7 +106,9 @@ static int _check_pv_min_size(struct device *dev)
static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
{
- filter_mode_t mode = *((filter_mode_t *) f->private);
+ struct filter_data *data = f->private;
+ filter_mode_t mode = data->mode;
+ int skip_lvs = data->skip_lvs;
struct dev_usable_check_params ucp = {0};
int r = 1;
@@ -114,6 +121,7 @@ static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
ucp.check_suspended = ignore_suspended_devices();
ucp.check_error_target = 1;
ucp.check_reserved = 1;
+ ucp.check_lv = skip_lvs;
break;
case FILTER_MODE_PRE_LVMETAD:
ucp.check_empty = 1;
@@ -121,6 +129,7 @@ static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
ucp.check_suspended = 0;
ucp.check_error_target = 1;
ucp.check_reserved = 1;
+ ucp.check_lv = skip_lvs;
break;
case FILTER_MODE_POST_LVMETAD:
ucp.check_empty = 0;
@@ -128,6 +137,7 @@ static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
ucp.check_suspended = ignore_suspended_devices();
ucp.check_error_target = 0;
ucp.check_reserved = 0;
+ ucp.check_lv = skip_lvs;
break;
}
@@ -161,8 +171,9 @@ static void _usable_filter_destroy(struct dev_filter *f)
dm_free(f);
}
-struct dev_filter *usable_filter_create(struct dev_types *dt __attribute__((unused)), filter_mode_t mode)
+struct dev_filter *usable_filter_create(struct cmd_context *cmd, struct dev_types *dt __attribute__((unused)), filter_mode_t mode)
{
+ struct filter_data *data;
struct dev_filter *f;
if (!(f = dm_zalloc(sizeof(struct dev_filter)))) {
@@ -173,14 +184,20 @@ struct dev_filter *usable_filter_create(struct dev_types *dt __attribute__((unus
f->passes_filter = _passes_usable_filter;
f->destroy = _usable_filter_destroy;
f->use_count = 0;
- if (!(f->private = dm_zalloc(sizeof(filter_mode_t)))) {
+
+ if (!(data = dm_zalloc(sizeof(struct filter_data)))) {
log_error("Usable device filter mode allocation failed");
dm_free(f);
return NULL;
}
- *((filter_mode_t *) f->private) = mode;
- log_debug_devs("Usable device filter initialised.");
+ data->mode = mode;
+
+ data->skip_lvs = !find_config_tree_bool(cmd, devices_scan_lvs_CFG, NULL);
+
+ f->private = data;
+
+ log_debug_devs("Usable device filter initialised (scan_lvs %d).", !data->skip_lvs);
return f;
}
diff --git a/lib/filters/filter.h b/lib/filters/filter.h
index 6245827..45572eb 100644
--- a/lib/filters/filter.h
+++ b/lib/filters/filter.h
@@ -52,7 +52,7 @@ typedef enum {
FILTER_MODE_PRE_LVMETAD,
FILTER_MODE_POST_LVMETAD
} filter_mode_t;
-struct dev_filter *usable_filter_create(struct dev_types *dt, filter_mode_t mode);
+struct dev_filter *usable_filter_create(struct cmd_context *cmd, struct dev_types *dt, filter_mode_t mode);
int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out);
5 years, 1 month
master - WHATS_NEW: scan_lvs default change
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=71a302effe82f1cc89f...
Commit: 71a302effe82f1cc89f0b26b358493cfaaed7de7
Parent: fedeab28c3096b5afb3fdc397fe8d18455247756
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 20 14:04:49 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 14:04:49 2019 -0600
WHATS_NEW: scan_lvs default change
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 29ade99..8088060 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.03.02 -
===================================
+ Change scan_lvs default to 0 so LVs are not scanned for PVs.
Thin-pool selects power-of-2 chunk size by default.
Cache selects power-of-2 chunk size by default.
Support reszing for VDOPoolLV and VDOLV.
5 years, 1 month
master - tests: set scan_lvs=1 in tests that stack PVs on LVs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fedeab28c3096b5afb3...
Commit: fedeab28c3096b5afb3fdc397fe8d18455247756
Parent: 7be6791e707da333e56aea3cc50c079ab6207bad
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 20 13:31:30 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 20 13:52:35 2019 -0600
tests: set scan_lvs=1 in tests that stack PVs on LVs
---
test/shell/discards-thin.sh | 2 ++
test/shell/lvconvert-thin.sh | 2 ++
test/shell/lvcreate-large-raid10.sh | 1 +
test/shell/lvcreate-large.sh | 2 ++
test/shell/pvcreate-restore.sh | 2 ++
test/shell/pvremove-thin.sh | 2 ++
test/shell/snapshot-remove-dmsetup.sh | 2 ++
test/shell/snapshot-usage-exa.sh | 2 ++
test/shell/snapshot-usage.sh | 2 ++
test/shell/vgsplit-stacked.sh | 2 ++
10 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/test/shell/discards-thin.sh b/test/shell/discards-thin.sh
index f27d4c3..3564a87 100644
--- a/test/shell/discards-thin.sh
+++ b/test/shell/discards-thin.sh
@@ -25,6 +25,8 @@ export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
#
aux have_thin 1 1 0 || skip
+aux lvmconf 'devices/scan_lvs = 1'
+
aux prepare_vg 2 64
get_devs
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 1f8d2ed..731c45b 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -17,6 +17,8 @@ export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
prepare_lvs() {
lvremove -f $vg
lvcreate -L10M -n $lv1 $vg
diff --git a/test/shell/lvcreate-large-raid10.sh b/test/shell/lvcreate-large-raid10.sh
index a46be37..1ad09aa 100644
--- a/test/shell/lvcreate-large-raid10.sh
+++ b/test/shell/lvcreate-large-raid10.sh
@@ -20,6 +20,7 @@ SKIP_WITH_LVMPOLLD=1
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
aux have_raid 1 3 0 || skip
+aux lvmconf 'devices/scan_lvs = 1'
aux prepare_vg 5
diff --git a/test/shell/lvcreate-large.sh b/test/shell/lvcreate-large.sh
index 473b0ed..b1cb0b0 100644
--- a/test/shell/lvcreate-large.sh
+++ b/test/shell/lvcreate-large.sh
@@ -17,6 +17,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
diff --git a/test/shell/pvcreate-restore.sh b/test/shell/pvcreate-restore.sh
index d0b46eb..789f45c 100644
--- a/test/shell/pvcreate-restore.sh
+++ b/test/shell/pvcreate-restore.sh
@@ -15,6 +15,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux prepare_vg 4
lvcreate --type snapshot -s -L10 -n $lv1 $vg --virtualsize 2T
diff --git a/test/shell/pvremove-thin.sh b/test/shell/pvremove-thin.sh
index 9859b6c..84a2a55 100644
--- a/test/shell/pvremove-thin.sh
+++ b/test/shell/pvremove-thin.sh
@@ -18,6 +18,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux prepare_vg
aux have_thin 1 8 0 || skip
diff --git a/test/shell/snapshot-remove-dmsetup.sh b/test/shell/snapshot-remove-dmsetup.sh
index 19411ce..916aec9 100644
--- a/test/shell/snapshot-remove-dmsetup.sh
+++ b/test/shell/snapshot-remove-dmsetup.sh
@@ -17,6 +17,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
which mkfs.ext2 || skip
aux prepare_vg 5
diff --git a/test/shell/snapshot-usage-exa.sh b/test/shell/snapshot-usage-exa.sh
index 5d666bf..f537f0d 100644
--- a/test/shell/snapshot-usage-exa.sh
+++ b/test/shell/snapshot-usage-exa.sh
@@ -18,6 +18,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux can_use_16T || skip
aux prepare_pvs 1
diff --git a/test/shell/snapshot-usage.sh b/test/shell/snapshot-usage.sh
index bcfa16a..5cfdae6 100644
--- a/test/shell/snapshot-usage.sh
+++ b/test/shell/snapshot-usage.sh
@@ -17,6 +17,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
MKFS=mkfs.ext2
which $MKFS || skip
diff --git a/test/shell/vgsplit-stacked.sh b/test/shell/vgsplit-stacked.sh
index 331ee8e..09af3f7 100644
--- a/test/shell/vgsplit-stacked.sh
+++ b/test/shell/vgsplit-stacked.sh
@@ -15,6 +15,8 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
+aux lvmconf 'devices/scan_lvs = 1'
+
aux extend_filter_LVMTEST
aux prepare_pvs 3
5 years, 1 month