!10 update lvm2 version to 2.03.09

Merge pull request !10 from wguanghao/develop
This commit is contained in:
openeuler-ci-bot 2020-07-23 10:59:20 +08:00 committed by Gitee
commit c407f8b36d
66 changed files with 168 additions and 3876 deletions

View File

@ -1,16 +0,0 @@
scripts/lvm2_lvmetad_systemd_red_hat.service.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/lvm2_lvmetad_systemd_red_hat.service.in b/scripts/lvm2_lvmetad_systemd_red_hat.service.in
index 8f4c60d..a1cedd2 100644
--- a/scripts/lvm2_lvmetad_systemd_red_hat.service.in
+++ b/scripts/lvm2_lvmetad_systemd_red_hat.service.in
@@ -9,7 +9,7 @@ Conflicts=shutdown.target
[Service]
Type=simple
NonBlocking=true
-ExecStart=@SBINDIR@/lvmetad -f
+ExecStart=@SBINDIR@/lvmetad -f -t 3600
Environment=SD_ACTIVATION=1
Restart=on-abort
PIDFile=@LVMETAD_PIDFILE@

View File

@ -1,12 +1,8 @@
conf/example.conf.in | 2 +-
lib/config/config_settings.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index c0afcb7..ec12918 100644
index 05b0857..7f0a687 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -106,7 +106,7 @@ devices {
@@ -122,7 +122,7 @@ devices {
# Example
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
#
@ -16,11 +12,11 @@ index c0afcb7..ec12918 100644
# Configuration option devices/filter.
# Limit the block devices that are used by LVM commands.
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 9017043..c06b6f0 100644
index 2bb72ba..f280156 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -205,7 +205,7 @@ cfg(devices_external_device_info_source_CFG, "external_device_info_source", devi
" compiled with udev support.\n"
@@ -269,7 +269,7 @@ cfg(devices_hints_CFG, "hints", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_
" Use no hints.\n"
"#\n")
-cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED , CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL, 0, NULL,

View File

@ -1,25 +1,21 @@
conf/example.conf.in | 2 +-
lib/config/defaults.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 4894d04..48afbd1 100644
index 7f0a687..39b5507 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -311,7 +311,7 @@ devices {
@@ -346,7 +346,7 @@ devices {
# or activating LVs in it while a PV appears on multiple devices.
# Enabling this setting allows the VG to be used as usual even with
# uncertain devices.
- allow_changes_with_duplicate_pvs = 0
+ allow_changes_with_duplicate_pvs = 1
}
# Configuration section allocation.
# Configuration option devices/allow_mixed_block_sizes.
# Allow PVs in the same VG with different logical block sizes.
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index d9e19d9..894b979 100644
index be4f5ff..3f0539e 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -45,7 +45,7 @@
@@ -56,7 +56,7 @@
#define DEFAULT_DATA_ALIGNMENT_DETECTION 1
#define DEFAULT_ISSUE_DISCARDS 0
#define DEFAULT_PV_MIN_SIZE_KB 2048

View File

@ -1,34 +0,0 @@
From 873e27006829b4973ac39db86499f4579325500a Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 11:19:18 +0800
Subject: [PATCH 01/17] mirrors: fix read_only_volume_list
If a mirror LV is listed in read_only_volume_list, it would
still be activated rw. The activation would initially be
readonly, but the monitoring function would immediately
change it to rw. This was a regression from commit
fade45b1d14c mirror: improve table update
The monitoring function needs to copy the read_only setting
into the new set of mirror activation options it uses.
---
lib/activate/activate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 56ec732..70cce30 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1851,6 +1851,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
if (!laopts)
laopts = &zlaopts;
+ else
+ mirr_laopts.read_only = laopts->read_only;
/* skip dmeventd code altogether */
if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
--
2.19.1

View File

@ -1,39 +0,0 @@
From 400ffe97d5db1a3a06de77851d44813ff48ebb9a Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 11:27:13 +0800
Subject: [PATCH 02/17] bcache: reduce MAX_IO to 256
This is the number of concurrent async io requests that
the scan layer will submit to the bcache layer. There
will be an open fd for each of these, so it is best to
keep this well below the default limit for max open files
(1024), otherwise lvm may get EMFILE from open(2) when
there are around 1024 devices to scan on the system.
---
lib/device/bcache.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index b1f7d2a..531d83b 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -196,7 +196,15 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
return true;
}
-#define MAX_IO 1024
+/*
+ * MAX_IO is returned to the layer above via bcache_max_prefetches() which
+ * tells the caller how many devices to submit io for concurrently. There will
+ * be an open file descriptor for each of these, so keep it low enough to avoid
+ * reaching the default max open file limit (1024) when there are over 1024
+ * devices being scanned.
+ */
+
+#define MAX_IO 256
#define MAX_EVENT 64
static bool _async_wait(struct io_engine *ioe, io_complete_fn fn)
--
2.19.1

View File

@ -1,31 +1,33 @@
From 862899cc88e1697211d478de58b2ddc0eaec9cd9 Mon Sep 17 00:00:00 2001
From 10d448be7aa5dcdafcd4dabc782ce7308af89c30 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 25 Jun 2019 14:50:05 +0200
Subject: [PATCH] cov: check result of dev_read_bytes
---
lib/format_text/format-text.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
lib/format_text/format-text.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 1a6c3a3..9b08e14 100644
index 268bd64..7385da5 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1224,8 +1224,12 @@ int read_metadata_location_summary(const struct format_type *fmt,
}
@@ -1545,9 +1545,13 @@ int read_metadata_location_summary(const struct format_type *fmt,
memset(namebuf, 0, sizeof(namebuf));
- if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, namebuf))
- stack;
-
+ if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, namebuf)) {
+ log_error("Can't read metadata location on %s at %llu.",
+ dev_name(dev_area->dev),
+ (unsigned long long)(dev_area->start + rlocn->offset));
+ return 0;
+ }
+
while (namebuf[len] && !isspace(namebuf[len]) && namebuf[len] != '{' &&
len < (NAME_LEN - 1))
len++;
--
2.19.1
1.8.3.1

View File

@ -1,118 +0,0 @@
From 0b14fe20d0aac79e99832bc53010abb5d8c6812c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 11:32:01 +0800
Subject: [PATCH 03/17] lvmetad: fix pvs for many devices
When using lvmetad, 'pvs' still evaluates full filters
on all devices (lvmetad only provides info about PVs,
but pvs needs to report info about all devices, at
least sometimes.)
Because some filters read the devices, pvs still reads
every device, even with lvmetad (i.e. lvmetad is no help
for the pvs command.) Because the device reads are not
being managed by the standard label scan layer, but only
happen incidentally through the filters, there is nothing
to control and limit the bcache content and the open file
descriptors for the devices. When there are a lot of devs
on the system, the number of open fd's excedes the limit
and all opens begin failing.
The proper solution for this would be for pvs to really
use lvmetad and not scan devs, or for pvs to do a proper
label scan even when lvmetad is enabled. To avoid any
major changes to the way this has worked, just work around
this problem by dropping bcache and closing the fd after
pvs evaluates the filter on each device.
---
tools/toollib.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 413937f..01686b0 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3931,7 +3931,7 @@ static int _get_arg_devices(struct cmd_context *cmd,
return ret_max;
}
-static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices)
+static int _get_all_devices_lvmetad(struct cmd_context *cmd, struct dm_list *all_devices)
{
struct dev_iter *iter;
struct device *dev;
@@ -3947,6 +3947,56 @@ static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices
return ECMD_FAILED;
}
+ /*
+ * The dev_iter_get applies the filter, which means it reads the device
+ * (since some filters read devices). The read is called from the
+ * filter, and done without label_scan_open, so the dev_read_bytes does
+ * the open. Since the open and read are not done from the label scan
+ * layer, there's nothing to do label_scan_invalidate and close devs
+ * that are not lvms. Hack around this by doing label_scan_invalidate
+ * here. It's dumb that we are reading all disks here when we're meant
+ * to be using lvmetad. process_each_pv with lvmetad should either
+ * just do a proper label_scan or find a way to not need to read devs
+ * at all. If we didn't close each dev here, all devs would remain
+ * open and lvm will have too many open fds. It's all because we're
+ * not using the label scan layer to do the scanning, but pretending a
+ * label scan isn't needed (because of lvmetad) and then secretly doing
+ * a scan anyway hidden down in the filters.
+ */
+
+ while ((dev = dev_iter_get(iter))) {
+ if (!(dil = dm_pool_alloc(cmd->mem, sizeof(*dil)))) {
+ log_error("device_id_list alloc failed.");
+ goto out;
+ }
+
+ strncpy(dil->pvid, dev->pvid, ID_LEN);
+ dil->dev = dev;
+ dm_list_add(all_devices, &dil->list);
+
+ label_scan_invalidate(dev);
+ }
+
+ r = ECMD_PROCESSED;
+out:
+ dev_iter_destroy(iter);
+ return r;
+}
+
+static int _get_all_devices_normal(struct cmd_context *cmd, struct dm_list *all_devices)
+{
+ struct dev_iter *iter;
+ struct device *dev;
+ struct device_id_list *dil;
+ int r = ECMD_FAILED;
+
+ log_debug("Getting list of all devices");
+
+ if (!(iter = dev_iter_create(cmd->full_filter, 1))) {
+ log_error("dev_iter creation failed.");
+ return ECMD_FAILED;
+ }
+
while ((dev = dev_iter_get(iter))) {
if (!(dil = dm_pool_alloc(cmd->mem, sizeof(*dil)))) {
log_error("device_id_list alloc failed.");
@@ -3964,6 +4014,14 @@ out:
return r;
}
+static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices)
+{
+ if (lvmetad_used())
+ return _get_all_devices_lvmetad(cmd, all_devices);
+ else
+ return _get_all_devices_normal(cmd, all_devices);
+}
+
static int _device_list_remove(struct dm_list *devices, struct device *dev)
{
struct device_id_list *dil;
--
2.19.1

View File

@ -1,4 +1,4 @@
From 0f30a9d3c2619cbaba323524f7aa9c9c4b01bcdd Mon Sep 17 00:00:00 2001
From 61a4f8a2f360b244a2cae2eb39eb7bd3b72ca6b6 Mon Sep 17 00:00:00 2001
From: geruijun <geruijun@huawei.com>
Date: Thu, 14 Feb 2019 04:55:01 -0500
Subject: [PATCH] lvm2: add 0002-bugfix-lvm2-add-SSD.patch
@ -8,17 +8,17 @@ Subject: [PATCH] lvm2: add 0002-bugfix-lvm2-add-SSD.patch
1 file changed, 1 insertion(+)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 32267e7..1f7b264 100644
index 39b5507..5d8f8dd 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -149,6 +149,7 @@ devices {
@@ -164,6 +164,7 @@ devices {
# global_filter are not opened by LVM.
# This configuration option has an automatic default value.
# global_filter = [ "a|.*/|" ]
# global_filter = [ "a|.*|" ]
+ types = [ "hio", 16 ]
# Configuration option devices/cache_dir.
# Directory in which to store the device cache file.
# Configuration option devices/types.
# List of additional acceptable block device types.
--
1.8.3.1

View File

@ -1,113 +0,0 @@
From bb468b6d7593b2ebbb541ceda240e115a8b8545c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:05:42 +0800
Subject: [PATCH 04/17] dmeventd: lvm2 plugin uses envvar registry
Thin plugin started to use configuble setting to allow to configure
usage of external scripts - however to read this value it needed to
execute internal command as dmeventd itself has no access to lvm.conf
and the API for dmeventd plugin has been kept stable.
The call of command itself was not normally 'a big issue' until users
started to use higher number of monitored LVs and execution of command
got stuck because other monitored resource already started to execute
some other lvm2 command and become blocked waiting on VG lock.
This scenario revealed necesity to somehow avoid calling lvm2 command
during resource registration - but this requires bigger changes - so
meanwhile this patch tries to minimize the possibility to hit this race
by obtaining any configurable setting just once - such patch is small
and covers majority of problem - yet better solution needs to be
introduced likely with bigger rework of dmeventd.
TODO: Avoid blocking registration of resource with execution of lvm2
commands since those can get stuck waiting on mutexes.
---
daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c | 49 +++++++++++++++-----
1 file changed, 38 insertions(+), 11 deletions(-)
diff --git a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
index 930f9fc..5be11f1 100644
--- a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
+++ b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
@@ -31,6 +31,13 @@ static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
+static DM_LIST_INIT(_env_registry);
+
+struct env_data {
+ struct dm_list list;
+ const char *cmd;
+ const char *data;
+};
DM_EVENT_LOG_FN("#lvm")
@@ -100,6 +107,7 @@ void dmeventd_lvm2_exit(void)
lvm2_run(_lvm_handle, "_memlock_dec");
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
+ dm_list_init(&_env_registry);
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
log_debug("lvm plugin exited.");
@@ -124,6 +132,8 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
static char _internal_prefix[] = "_dmeventd_";
char *vg = NULL, *lv = NULL, *layer;
int r;
+ struct env_data *env_data;
+ const char *env = NULL;
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
log_error("Unable to determine VG name from %s.",
@@ -137,18 +147,35 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
*layer = '\0';
if (!strncmp(cmd, _internal_prefix, sizeof(_internal_prefix) - 1)) {
- dmeventd_lvm2_lock();
- /* output of internal command passed via env var */
- if (!dmeventd_lvm2_run(cmd))
- cmd = NULL;
- else if ((cmd = getenv(cmd)))
- cmd = dm_pool_strdup(mem, cmd); /* copy with lock */
- dmeventd_lvm2_unlock();
-
- if (!cmd) {
- log_error("Unable to find configured command.");
- return 0;
+ /* check if ENVVAR wasn't already resolved */
+ dm_list_iterate_items(env_data, &_env_registry)
+ if (!strcmp(cmd, env_data->cmd)) {
+ env = env_data->data;
+ break;
+ }
+
+ if (!env) {
+ /* run lvm2 command to find out setting value */
+ dmeventd_lvm2_lock();
+ if (!dmeventd_lvm2_run(cmd) ||
+ !(env = getenv(cmd))) {
+ log_error("Unable to find configured command.");
+ return 0;
+ }
+ /* output of internal command passed via env var */
+ env = dm_pool_strdup(_mem_pool, env); /* copy with lock */
+ dmeventd_lvm2_unlock();
+ if (!env ||
+ !(env_data = dm_pool_zalloc(_mem_pool, sizeof(*env_data))) ||
+ !(env_data->cmd = dm_pool_strdup(_mem_pool, cmd))) {
+ log_error("Unable to allocate env memory.");
+ return 0;
+ }
+ env_data->data = env;
+ /* add to ENVVAR registry */
+ dm_list_add(&_env_registry, &env_data->list);
}
+ cmd = env;
}
r = dm_snprintf(buffer, size, "%s %s/%s", cmd, vg, lv);
--
2.19.1

View File

@ -1,39 +1,8 @@
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index 40b366b..0b03106 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -59,6 +59,7 @@ union semun
#endif
#endif
+#define UDEV_SEM_TIMEOUT 300
static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;
static char _sysfs_dir[PATH_MAX] = "/sys/";
static char _path0[PATH_MAX]; /* path buffer, safe 4kB on stack */
@@ -2611,6 +2612,9 @@ static int _udev_wait(uint32_t cookie, int *nowait)
int semid;
struct sembuf sb = {0, 0, 0};
int val;
+ struct timespec timeout;
+ timeout.tv_sec = UDEV_SEM_TIMEOUT;
+ timeout.tv_nsec = 0;
if (!cookie || !dm_udev_get_sync_support())
return 1;
@@ -2646,7 +2650,7 @@ static int _udev_wait(uint32_t cookie, int *nowait)
cookie, semid);
repeat_wait:
- if (semop(semid, &sb, 1) < 0) {
+ if (semtimedop(semid, &sb, 1,&timeout) < 0) {
if (errno == EINTR)
goto repeat_wait;
else if (errno == EIDRM)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index 3cdf862..af70a02 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -1131,6 +1131,7 @@ out:
diff --git a/libdm/dm-tools/dmsetup.c b/libdm/dm-tools/dmsetup.c
index d01b8f2..a5cb551 100644
--- a/libdm/dm-tools/dmsetup.c
+++ b/libdm/dm-tools/dmsetup.c
@@ -1130,6 +1130,7 @@ out:
static int _create_one_device(const char *name, const char *file)
{
int r = 0;
@ -41,7 +10,7 @@ index 3cdf862..af70a02 100644
struct dm_task *dmt;
uint32_t cookie = 0;
uint16_t udev_flags = 0;
@@ -1203,13 +1204,16 @@ static int _create_one_device(const char *name, const char *file)
@@ -1202,13 +1203,15 @@ static int _create_one_device(const char *name, const char *file)
out:
if (!_udev_cookie)
@ -55,11 +24,10 @@ index 3cdf862..af70a02 100644
+ if (!udev_wait_r)
+ return 0;
+
return r;
}
@@ -1430,6 +1434,7 @@ static int _create(CMD_ARGS)
@@ -1431,6 +1434,7 @@ static int _create(CMD_ARGS)
static int _do_rename(const char *name, const char *new_name, const char *new_uuid) {
int r = 0;
@ -67,7 +35,7 @@ index 3cdf862..af70a02 100644
struct dm_task *dmt;
uint32_t cookie = 0;
uint16_t udev_flags = 0;
@@ -1474,10 +1479,13 @@ static int _do_rename(const char *name, const char *new_name, const char *new_uu
@@ -1475,10 +1479,13 @@ static int _do_rename(const char *name, const char *new_name, const char *new_uu
out:
if (!_udev_cookie)
@ -82,7 +50,7 @@ index 3cdf862..af70a02 100644
return r;
}
@@ -1997,6 +2005,7 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
@@ -1999,6 +2006,7 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
int udev_wait_flag = task == DM_DEVICE_RESUME ||
task == DM_DEVICE_REMOVE;
int r = 0;
@ -90,7 +58,7 @@ index 3cdf862..af70a02 100644
struct dm_task *dmt;
@@ -2056,13 +2065,16 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
@@ -2058,13 +2066,16 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
out:
if (!_udev_cookie && udev_wait_flag)
@ -108,3 +76,34 @@ index 3cdf862..af70a02 100644
return r;
}
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index d75c704..e7c00f0 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -59,6 +59,7 @@ union semun
#endif
#endif
+#define UDEV_SEM_TIMEOUT 300
static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;
static char _sysfs_dir[PATH_MAX] = "/sys/";
static char _path0[PATH_MAX]; /* path buffer, safe 4kB on stack */
@@ -2730,6 +2731,9 @@ static int _udev_wait(uint32_t cookie, int *nowait)
int semid;
struct sembuf sb = {0, 0, 0};
int val;
+ struct timespec timeout;
+ timeout.tv_sec = UDEV_SEM_TIMEOUT;
+ timeout.tv_nsec = 0;
if (!cookie || !dm_udev_get_sync_support())
return 1;
@@ -2765,7 +2769,7 @@ static int _udev_wait(uint32_t cookie, int *nowait)
cookie, semid);
repeat_wait:
- if (semop(semid, &sb, 1) < 0) {
+ if (semtimedop(semid, &sb, 1,&timeout) < 0) {
if (errno == EINTR)
goto repeat_wait;
else if (errno == EIDRM)

View File

@ -1,336 +0,0 @@
From f4f4a850ea6f992beadd07288ddcb83343c30d27 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:07:23 +0800
Subject: [PATCH 05/17] metadata: prevent writing beyond metadata area
lvm uses a bcache block size of 128K. A bcache block
at the end of the metadata area will overlap the PEs
from which LVs are allocated. How much depends on
alignments. When lvm reads and writes one of these
bcache blocks to update VG metadata, it can also be
reading and writing PEs that belong to an LV.
If these overlapping PEs are being written to by the
LV user (e.g. filesystem) at the same time that lvm
is modifying VG metadata in the overlapping bcache
block, then the user's updates to the PEs can be lost.
This patch is a quick hack to prevent lvm from writing
past the end of the metadata area.
---
lib/device/bcache.c | 79 ++++++++++++++++++++++++++++++++++-
lib/device/bcache.h | 3 ++
lib/format_text/format-text.c | 10 +++++
lib/label/label.c | 35 +++++++++++++++-
lib/label/label.h | 2 +
lib/metadata/mirror.c | 4 ++
6 files changed, 130 insertions(+), 3 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 531d83b..6235256 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -156,6 +156,10 @@ static void _async_destroy(struct io_engine *ioe)
dm_free(e);
}
+static int _last_byte_fd;
+static uint64_t _last_byte_offset;
+static int _last_byte_sector_size;
+
static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
sector_t sb, sector_t se, void *data, void *context)
{
@@ -163,12 +167,53 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
struct iocb *cb_array[1];
struct control_block *cb;
struct async_engine *e = _to_async(ioe);
+ sector_t offset;
+ sector_t nbytes;
+ sector_t limit_nbytes;
+ sector_t extra_nbytes = 0;
if (((uintptr_t) data) & e->page_mask) {
log_warn("misaligned data buffer");
return false;
}
+ offset = sb << SECTOR_SHIFT;
+ nbytes = (se - sb) << SECTOR_SHIFT;
+
+ /*
+ * If bcache block goes past where lvm wants to write, then clamp it.
+ */
+ if ((d == DIR_WRITE) && _last_byte_offset && (fd == _last_byte_fd)) {
+ if (offset > _last_byte_offset) {
+ log_error("Limit write at %llu len %llu beyond last byte %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)_last_byte_offset);
+ return false;
+ }
+
+ if (offset + nbytes > _last_byte_offset) {
+ limit_nbytes = _last_byte_offset - offset;
+ if (limit_nbytes % _last_byte_sector_size)
+ extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
+
+ if (extra_nbytes) {
+ log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes,
+ (unsigned long long)(limit_nbytes + extra_nbytes));
+ nbytes = limit_nbytes + extra_nbytes;
+ } else {
+ log_debug("Limit write at %llu len %llu to len %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes);
+ nbytes = limit_nbytes;
+ }
+ }
+ }
+
cb = _cb_alloc(e->cbs, context);
if (!cb) {
log_warn("couldn't allocate control block");
@@ -179,10 +224,22 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
cb->cb.aio_fildes = (int) fd;
cb->cb.u.c.buf = data;
- cb->cb.u.c.offset = sb << SECTOR_SHIFT;
- cb->cb.u.c.nbytes = (se - sb) << SECTOR_SHIFT;
+ cb->cb.u.c.offset = offset;
+ cb->cb.u.c.nbytes = nbytes;
cb->cb.aio_lio_opcode = (d == DIR_READ) ? IO_CMD_PREAD : IO_CMD_PWRITE;
+#if 0
+ if (d == DIR_READ) {
+ log_debug("io R off %llu bytes %llu",
+ (unsigned long long)cb->cb.u.c.offset,
+ (unsigned long long)cb->cb.u.c.nbytes);
+ } else {
+ log_debug("io W off %llu bytes %llu",
+ (unsigned long long)cb->cb.u.c.offset,
+ (unsigned long long)cb->cb.u.c.nbytes);
+ }
+#endif
+
cb_array[0] = &cb->cb;
do {
r = io_submit(e->aio_context, 1, cb_array);
@@ -1153,3 +1210,21 @@ bool bcache_invalidate_fd(struct bcache *cache, int fd)
//----------------------------------------------------------------
+void bcache_set_last_byte(struct bcache *cache, int fd, uint64_t offset, int sector_size)
+{
+ _last_byte_fd = fd;
+ _last_byte_offset = offset;
+ _last_byte_sector_size = sector_size;
+ if (!sector_size)
+ _last_byte_sector_size = 512;
+}
+
+void bcache_unset_last_byte(struct bcache *cache, int fd)
+{
+ if (_last_byte_fd == fd) {
+ _last_byte_fd = 0;
+ _last_byte_offset = 0;
+ _last_byte_sector_size = 0;
+ }
+}
+
diff --git a/lib/device/bcache.h b/lib/device/bcache.h
index b0aebb4..cb902ef 100644
--- a/lib/device/bcache.h
+++ b/lib/device/bcache.h
@@ -158,6 +158,9 @@ bool bcache_write_bytes(struct bcache *cache, int fd, uint64_t start, size_t len
bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len);
bool bcache_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val);
+void bcache_set_last_byte(struct bcache *cache, int fd, uint64_t offset, int sector_size);
+void bcache_unset_last_byte(struct bcache *cache, int fd);
+
//----------------------------------------------------------------
#endif
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 5c7b72f..4160ba8 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -400,10 +400,14 @@ static int _raw_write_mda_header(const struct format_type *fmt,
MDA_HEADER_SIZE -
sizeof(mdah->checksum_xl)));
+ dev_set_last_byte(dev, start_byte + MDA_HEADER_SIZE);
+
if (!dev_write_bytes(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
+ dev_unset_last_byte(dev);
log_error("Failed to write mda header to %s fd %d", dev_name(dev), dev->bcache_fd);
return 0;
}
+ dev_unset_last_byte(dev);
return 1;
}
@@ -677,10 +681,13 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
(unsigned long long)(mdac->rlocn.size - new_wrap),
(unsigned long long)new_wrap);
+ dev_set_last_byte(mdac->area.dev, mdac->area.start + mdah->size);
+
if (!dev_write_bytes(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
(size_t) (mdac->rlocn.size - new_wrap),
fidtc->raw_metadata_buf)) {
log_error("Failed to write metadata to %s fd %d", dev_name(mdac->area.dev), mdac->area.dev->bcache_fd);
+ dev_unset_last_byte(mdac->area.dev);
goto out;
}
@@ -694,10 +701,13 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
(size_t) new_wrap,
fidtc->raw_metadata_buf + mdac->rlocn.size - new_wrap)) {
log_error("Failed to write metadata wrap to %s fd %d", dev_name(mdac->area.dev), mdac->area.dev->bcache_fd);
+ dev_unset_last_byte(mdac->area.dev);
goto out;
}
}
+ dev_unset_last_byte(mdac->area.dev);
+
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, (uint8_t *)fidtc->raw_metadata_buf,
(uint32_t) (mdac->rlocn.size -
new_wrap));
diff --git a/lib/label/label.c b/lib/label/label.c
index ac37713..e86b54b 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -172,6 +172,7 @@ int label_write(struct device *dev, struct label *label)
{
char buf[LABEL_SIZE] __attribute__((aligned(8)));
struct label_header *lh = (struct label_header *) buf;
+ uint64_t offset;
int r = 1;
if (!label->labeller->ops->write) {
@@ -206,11 +207,17 @@ int label_write(struct device *dev, struct label *label)
return 0;
}
- if (!dev_write_bytes(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf)) {
+ offset = label->sector << SECTOR_SHIFT;
+
+ dev_set_last_byte(dev, offset + LABEL_SIZE);
+
+ if (!dev_write_bytes(dev, offset, LABEL_SIZE, buf)) {
log_debug_devs("Failed to write label to %s", dev_name(dev));
r = 0;
}
+ dev_unset_last_byte(dev);
+
return r;
}
@@ -1256,9 +1263,12 @@ bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
}
}
+ dev_set_last_byte(dev, start + len);
+
if (!bcache_zero_bytes(scan_bcache, dev->bcache_fd, start, len)) {
log_error("Error writing device %s at %llu length %u.",
dev_name(dev), (unsigned long long)start, (uint32_t)len);
+ dev_unset_last_byte(dev);
label_scan_invalidate(dev);
return false;
}
@@ -1266,9 +1276,11 @@ bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
if (!bcache_flush(scan_bcache)) {
log_error("Error writing device %s at %llu length %u.",
dev_name(dev), (unsigned long long)start, (uint32_t)len);
+ dev_unset_last_byte(dev);
label_scan_invalidate(dev);
return false;
}
+ dev_unset_last_byte(dev);
return true;
}
@@ -1302,9 +1314,12 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
}
}
+ dev_set_last_byte(dev, start + len);
+
if (!bcache_set_bytes(scan_bcache, dev->bcache_fd, start, len, val)) {
log_error("Error writing device %s at %llu length %u.",
dev_name(dev), (unsigned long long)start, (uint32_t)len);
+ dev_unset_last_byte(dev);
label_scan_invalidate(dev);
return false;
}
@@ -1312,9 +1327,27 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
if (!bcache_flush(scan_bcache)) {
log_error("Error writing device %s at %llu length %u.",
dev_name(dev), (unsigned long long)start, (uint32_t)len);
+ dev_unset_last_byte(dev);
label_scan_invalidate(dev);
return false;
}
+
+ dev_unset_last_byte(dev);
return true;
}
+void dev_set_last_byte(struct device *dev, uint64_t offset)
+{
+ unsigned int phys_block_size = 0;
+ unsigned int block_size = 0;
+
+ dev_get_block_size(dev, &phys_block_size, &block_size);
+
+ bcache_set_last_byte(scan_bcache, dev->bcache_fd, offset, phys_block_size);
+}
+
+void dev_unset_last_byte(struct device *dev)
+{
+ bcache_unset_last_byte(scan_bcache, dev->bcache_fd);
+}
+
diff --git a/lib/label/label.h b/lib/label/label.h
index 5ed8bc8..e2b8263 100644
--- a/lib/label/label.h
+++ b/lib/label/label.h
@@ -125,5 +125,7 @@ bool dev_read_bytes(struct device *dev, uint64_t start, size_t len, void *data);
bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data);
bool dev_write_zeros(struct device *dev, uint64_t start, size_t len);
bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val);
+void dev_set_last_byte(struct device *dev, uint64_t offset);
+void dev_unset_last_byte(struct device *dev);
#endif
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 7f38d4f..b2a4dfb 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -302,10 +302,14 @@ static int _write_log_header(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
+ dev_set_last_byte(dev, sizeof(log_header));
+
if (!dev_write_bytes(dev, UINT64_C(0), sizeof(log_header), &log_header)) {
+ dev_unset_last_byte(dev);
log_error("Failed to write log header to %s.", name);
return 0;
}
+ dev_unset_last_byte(dev);
label_scan_invalidate(dev);
--
2.19.1

View File

@ -0,0 +1,13 @@
diff --git a/tools/command.c b/tools/command.c
index 50791b1..3270b26 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1375,7 +1375,7 @@ static int _copy_line(char *line, int max_line, int *position)
memset(line, 0, max_line);
- while (1) {
+ while ( p < strlen(_command_input) ) {
line[i] = _command_input[p];
i++;
p++;

View File

@ -1,45 +0,0 @@
From 4493c6a45c334751ab99428ca0f072f7486e3b2c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:13:16 +0800
Subject: [PATCH 06/17] libdm-stats: move no regions warning after
dm_stats_list()
It doesn't make sense to test or warn about the region count until
the stats handle has been listed: at this point it may or may not
contain valid information (but is guaranteed to be correct after
the list).
---
libdm/libdm-stats.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 94ad380..6b4e3d8 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -2336,11 +2336,6 @@ int dm_stats_populate(struct dm_stats *dms, const char *program_id,
return 0;
}
- if (!dms->nr_regions) {
- log_error("No regions registered.");
- return 0;
- }
-
/* allow zero-length program_id for populate */
if (!program_id)
program_id = dms->program_id;
@@ -2352,6 +2347,11 @@ int dm_stats_populate(struct dm_stats *dms, const char *program_id,
goto_bad;
}
+ if (!dms->nr_regions) {
+ log_verbose("No stats regions registered: %s", dms->name);
+ return 0;
+ }
+
dms->walk_flags = DM_STATS_WALK_REGION;
dm_stats_walk_start(dms);
do {
--
2.19.1

View File

@ -1,48 +0,0 @@
From fcae18ceb9a6db7182abbbea379d45cebb901313 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:14:43 +0800
Subject: [PATCH 07/17] dmsetup: fix stats report command output
Since the stats handle is neither bound nor listed before the
attempt to call dm_stats_get_nr_regions(), it will always return
zero: this prevents reporting of any dmstats regions on any
device.
Remove the dm_stats_get_nr_regions() check and instead rely on
the correct return status from dm_stats_populate() which only
returns 0 in the case that there are regions to inspect (and
which logs a specific error for all other cases).
Reported-by: Bryan Gurney <bgurney@redhat.com>
---
tools/dmsetup.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index af70a02..aca595d 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -910,17 +910,13 @@ static int _display_info_cols(struct dm_task *dmt, struct dm_info *info)
if (!(obj.stats = dm_stats_create(DM_STATS_PROGRAM_ID)))
goto_out;
- if (!dm_stats_get_nr_regions(obj.stats)) {
- log_debug("Skipping %s with no regions.", dm_task_get_name(dmt));
+ dm_stats_bind_devno(obj.stats, info->major, info->minor);
+
+ if (!dm_stats_populate(obj.stats, _program_id, DM_STATS_REGIONS_ALL)) {
r = 1;
goto out;
}
- dm_stats_bind_devno(obj.stats, info->major, info->minor);
-
- if (!dm_stats_populate(obj.stats, _program_id, DM_STATS_REGIONS_ALL))
- goto_out;
-
/* Update timestamps and handle end-of-interval accounting. */
_update_interval_times();
--
2.19.1

View File

@ -1,11 +1,12 @@
From 2f257461191b97e47a716f0cd0374e174041ddef Mon Sep 17 00:00:00 2001
From fd36f54943e58db6483472519c118bde68b6ee60 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Tue, 19 Mar 2019 16:43:16 +0800
Subject: [PATCH 2/2] add dfx log when error occur, or lvm resource change, it
will print the cmdline and ppid
Subject: [PATCH] add dfx log when error occur, or lvm resource change, it will
print the cmdline and ppid
---
conf/example.conf.in | 5 +++++
conf/example.conf.in | 4 ++++
conf/example.conf.in.rej | 13 +++++++++++++
lib/commands/toolcontext.c | 16 ++++++++++++++++
lib/commands/toolcontext.h | 4 ++++
lib/config/config_settings.h | 5 +++++
@ -14,29 +15,48 @@ Subject: [PATCH 2/2] add dfx log when error occur, or lvm resource change, it
lib/misc/lvm-globals.c | 11 +++++++++++
lib/misc/lvm-globals.h | 2 ++
tools/lvmcmdline.c | 1 +
9 files changed, 66 insertions(+), 3 deletions(-)
10 files changed, 78 insertions(+), 3 deletions(-)
create mode 100644 conf/example.conf.in.rej
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 9a465ca..4f2abae 100644
index f310789..d715d12 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -587,6 +587,11 @@ log {
@@ -775,6 +775,10 @@ log {
# There are 6 syslog-like log levels currently in use: 2 to 7 inclusive.
# 7 is the most verbose (LOG_DEBUG).
level = 3
+ #When the level of log messages is set as 2 or 3, set log_unless_silent
+ #to 1, it will also log some important warning level messages, such as,
+ #create/delete/change a lv/vg/pv, 0 is close this option.
+ log_unless_silent = 1
+
# Configuration option log/indent.
# Indent messages according to their severity.
indent = 1
diff --git a/conf/example.conf.in.rej b/conf/example.conf.in.rej
new file mode 100644
index 0000000..d90332a
--- /dev/null
+++ b/conf/example.conf.in.rej
@@ -0,0 +1,13 @@
+diff a/conf/example.conf.in b/conf/example.conf.in (rejected hunks)
+@@ -587,6 +587,11 @@ log {
+ # 7 is the most verbose (LOG_DEBUG).
+ level = 3
+
++ #When the level of log messages is set as 2 or 3, set log_unless_silent
++ #to 1, it will also log some important warning level messages, such as,
++ #create/delete/change a lv/vg/pv, 0 is close this option.
++ log_unless_silent = 1
++
+ # Configuration option log/indent.
+ # Indent messages according to their severity.
+ indent = 1
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index df9ca75..b1ecf77 100644
index 479d499..894c91d 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -49,6 +49,8 @@
@@ -46,6 +46,8 @@
static const size_t _linebuffer_size = 4096;
@ -45,7 +65,7 @@ index df9ca75..b1ecf77 100644
/*
* Copy the input string, removing invalid characters.
*/
@@ -314,6 +316,9 @@ static void _init_logging(struct cmd_context *cmd)
@@ -348,6 +350,9 @@ static void _init_logging(struct cmd_context *cmd)
find_config_tree_bool(cmd, log_silent_CFG, NULL);
init_silent(cmd->default_settings.silent);
@ -55,7 +75,7 @@ index df9ca75..b1ecf77 100644
/* Verbose level for tty output */
cmd->default_settings.verbose = find_config_tree_int(cmd, log_verbose_CFG, NULL);
init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
@@ -2240,6 +2245,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
@@ -1962,6 +1967,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
_destroy_filters(cmd);
@ -63,7 +83,7 @@ index df9ca75..b1ecf77 100644
if (cmd->mem)
dm_pool_destroy(cmd->mem);
dev_cache_exit();
@@ -2293,3 +2299,13 @@ void destroy_toolcontext(struct cmd_context *cmd)
@@ -2014,3 +2020,13 @@ void destroy_toolcontext(struct cmd_context *cmd)
fin_syslog();
reset_lvm_errno(0);
}
@ -78,10 +98,10 @@ index df9ca75..b1ecf77 100644
+ global_cmdline = cmdline;
+}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index da5d582..345dcc8 100644
index c09558a..a91174d 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -48,6 +48,7 @@ struct config_info {
@@ -47,6 +47,7 @@ struct config_info {
mode_t umask;
char unit_type;
char _padding[1];
@ -89,7 +109,7 @@ index da5d582..345dcc8 100644
};
struct dm_config_tree;
@@ -267,4 +268,7 @@ struct format_type *get_format_by_name(struct cmd_context *cmd, const char *form
@@ -275,4 +276,7 @@ struct format_type *get_format_by_name(struct cmd_context *cmd, const char *form
const char *system_id_from_string(struct cmd_context *cmd, const char *str);
@ -98,10 +118,10 @@ index da5d582..345dcc8 100644
+void set_global_cmdline(char *cmdline);
#endif
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index f8a577f..b637eb0 100644
index f280156..1b05163 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -686,6 +686,11 @@ cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL,
@@ -850,6 +850,11 @@ cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL,
"There are 6 syslog-like log levels currently in use: 2 to 7 inclusive.\n"
"7 is the most verbose (LOG_DEBUG).\n")
@ -110,22 +130,22 @@ index f8a577f..b637eb0 100644
+ "to 1, it will also log some important warning level messages, such as,\n"
+ "create/delete/change a lv/vg/pv, 0 is close this option.\n")
+
cfg(log_indent_CFG, "indent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_INDENT, vsn(1, 0, 0), NULL, 0, NULL,
cfg(log_indent_CFG, "indent", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_INDENT, vsn(1, 0, 0), NULL, 0, NULL,
"Indent messages according to their severity.\n")
diff --git a/lib/log/log.c b/lib/log/log.c
index 79fbd7a..d34e160 100644
index ebf26b4..136959e 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -19,6 +19,7 @@
#include "defaults.h"
#include "report.h"
#include "lvm-file.h"
+#include "toolcontext.h"
#include "lib/config/defaults.h"
#include "lib/report/report.h"
#include "lib/misc/lvm-file.h"
+#include "lib/commands/toolcontext.h"
#include <stdio.h>
#include <stdarg.h>
@@ -478,6 +479,7 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
@@ -494,6 +495,7 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
const char *trformat; /* Translated format string */
char *newbuf;
int use_stderr = log_stderr(level);
@ -133,7 +153,7 @@ index 79fbd7a..d34e160 100644
int log_once = log_once(level);
int log_bypass_report = log_bypass_report(level);
int fatal_internal_error = 0;
@@ -490,7 +492,9 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
@@ -506,7 +508,9 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
struct dm_report *orig_report;
int logged_via_report = 0;
@ -143,7 +163,7 @@ index 79fbd7a..d34e160 100644
if (_abort_on_internal_errors_env_present < 0) {
if ((env_str = getenv("DM_ABORT_ON_INTERNAL_ERRORS"))) {
@@ -632,8 +636,8 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
@@ -670,8 +674,8 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
va_end(ap);
}
@ -154,7 +174,7 @@ index 79fbd7a..d34e160 100644
if (fatal_internal_error)
abort();
return;
@@ -661,6 +665,19 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
@@ -714,6 +718,19 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
if (_syslog && (_log_while_suspended || !critical_section())) {
va_copy(ap, orig_ap);
@ -175,7 +195,7 @@ index 79fbd7a..d34e160 100644
va_end(ap);
}
diff --git a/lib/log/log.h b/lib/log/log.h
index 256fed0..7c22859 100644
index d3848a4..07f2eb4 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -50,6 +50,8 @@
@ -187,7 +207,7 @@ index 256fed0..7c22859 100644
#define log_level(x) ((x) & 0x0f) /* obtain message level */
#define log_stderr(x) ((x) & _LOG_STDERR) /* obtain stderr bit */
#define log_once(x) ((x) & _LOG_ONCE) /* obtain once bit */
@@ -100,7 +102,7 @@
@@ -107,7 +109,7 @@
#define log_very_verbose(args...) log_info(args)
#define log_verbose(args...) log_notice(args)
#define log_print(args...) LOG_LINE(_LOG_WARN, args)
@ -197,13 +217,13 @@ index 256fed0..7c22859 100644
#define log_error_suppress(s, args...) log_err_suppress(s, args)
#define log_error_once(args...) log_err_once(args)
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index 82c5706..2cb471e 100644
index 06855ff..37d2fae 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -54,12 +54,23 @@ static char _sysfs_dir_path[PATH_MAX] = "";
static int _dev_disable_after_error_count = DEFAULT_DISABLE_AFTER_ERROR_COUNT;
static uint64_t _pv_min_size = (DEFAULT_PV_MIN_SIZE_KB * 1024L >> SECTOR_SHIFT);
static const char *_unknown_device_name = DEFAULT_UNKNOWN_DEVICE_NAME;
static int _io_memory_size_kb = DEFAULT_IO_MEMORY_SIZE_KB;
+static int _log_unless_silent = 1;
void init_verbose(int level)
@ -225,21 +245,21 @@ index 82c5706..2cb471e 100644
{
_silent = silent;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index f985cfa..3374d0d 100644
index a54001c..8ae55f6 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -93,4 +93,6 @@ int dmeventd_monitor_mode(void);
#define NO_DEV_ERROR_COUNT_LIMIT 0
int dev_disable_after_error_count(void);
@@ -89,4 +89,6 @@ int io_memory_size(void);
#define DMEVENTD_MONITOR_IGNORE -1
int dmeventd_monitor_mode(void);
+void init_log_unless_silent(int unless_silent);
+int get_log_unless_silent(void);
#endif
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 298ead7..0b1a9b2 100644
index f147be3..650eff8 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2807,6 +2807,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
@@ -2973,6 +2973,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
/* The cmd_line string is only used for logging, not processing. */
if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv)))
return_ECMD_FAILED;
@ -248,5 +268,5 @@ index 298ead7..0b1a9b2 100644
/* Look up command - will be NULL if not recognised */
if (!(cmd->cname = _find_command_name(cmd->name)))
--
2.19.1
1.8.3.1

View File

@ -1,216 +0,0 @@
From 541efb3a013eed7dda561be66a66a11a3d500c78 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:16:56 +0800
Subject: [PATCH 08/17] io: use sync io if aio fails
io_setup() for aio may fail if a system has reached the
aio request limit. In this case, fall back to using
sync io. Also, lvm use of aio can be disabled entirely
with config setting global/use_aio=0.
The system limit for aio requests can be seen from
/proc/sys/fs/aio-max-nr
The current usage of aio requests can be seen from
/proc/sys/fs/aio-nr
The system limit for aio requests can be increased by
setting fs.aio-max-nr using sysctl.
Also add last-byte limit to the sync io code.
---
lib/commands/toolcontext.c | 2 ++
lib/config/config_settings.h | 3 +++
lib/config/defaults.h | 1 +
lib/device/bcache.c | 42 ++++++++++++++++++++++++++++++++++++
lib/label/label.c | 17 +++++++++++----
lib/misc/lvm-globals.c | 11 ++++++++++
lib/misc/lvm-globals.h | 2 ++
7 files changed, 74 insertions(+), 4 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index c9596e2..ecd8fd7 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -333,6 +333,8 @@ static void _init_logging(struct cmd_context *cmd)
find_config_tree_bool(cmd, global_test_CFG, NULL);
init_test(cmd->default_settings.test);
+ init_use_aio(find_config_tree_bool(cmd, global_use_aio_CFG, NULL));
+
/* Settings for logging to file */
if (find_config_tree_bool(cmd, log_overwrite_CFG, NULL))
append = 0;
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index e98ca6d..f8a577f 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -935,6 +935,9 @@ cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_pa
"Previously this was always shown as /dev/vgname/lvname even when that\n"
"was never a valid path in the /dev filesystem.\n")
+cfg(global_use_aio_CFG, "use_aio", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_AIO, vsn(2, 2, 183), NULL, 0, NULL,
+ "Use async I/O when reading and writing devices.\n")
+
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_LVMETAD, vsn(2, 2, 93), "@DEFAULT_USE_LVMETAD@", 0, NULL,
"Use lvmetad to cache metadata and reduce disk scanning.\n"
"When enabled (and running), lvmetad provides LVM commands with VG\n"
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 7cebd84..fc2f603 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -59,6 +59,7 @@
#define DEFAULT_METADATA_READ_ONLY 0
#define DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH 0
#define DEFAULT_UNKNOWN_DEVICE_NAME "[unknown]"
+#define DEFAULT_USE_AIO 1
#define DEFAULT_SANLOCK_LV_EXTEND_MB 256
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 6235256..571ee7a 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -388,6 +388,48 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
return false;
}
+ /*
+ * If bcache block goes past where lvm wants to write, then clamp it.
+ */
+ if ((d == DIR_WRITE) && _last_byte_offset && (fd == _last_byte_fd)) {
+ uint64_t offset = where;
+ uint64_t nbytes = len;
+ sector_t limit_nbytes = 0;
+ sector_t extra_nbytes = 0;
+
+ if (offset > _last_byte_offset) {
+ log_error("Limit write at %llu len %llu beyond last byte %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)_last_byte_offset);
+ return false;
+ }
+
+ if (offset + nbytes > _last_byte_offset) {
+ limit_nbytes = _last_byte_offset - offset;
+ if (limit_nbytes % _last_byte_sector_size)
+ extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
+
+ if (extra_nbytes) {
+ log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes,
+ (unsigned long long)(limit_nbytes + extra_nbytes));
+ nbytes = limit_nbytes + extra_nbytes;
+ } else {
+ log_debug("Limit write at %llu len %llu to len %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes);
+ nbytes = limit_nbytes;
+ }
+ }
+
+ where = offset;
+ len = nbytes;
+ }
+
while (len) {
do {
if (d == DIR_READ)
diff --git a/lib/label/label.c b/lib/label/label.c
index e86b54b..5114959 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -797,7 +797,7 @@ out:
static int _setup_bcache(int cache_blocks)
{
- struct io_engine *ioe;
+ struct io_engine *ioe = NULL;
if (cache_blocks < MIN_BCACHE_BLOCKS)
cache_blocks = MIN_BCACHE_BLOCKS;
@@ -805,9 +805,18 @@ static int _setup_bcache(int cache_blocks)
if (cache_blocks > MAX_BCACHE_BLOCKS)
cache_blocks = MAX_BCACHE_BLOCKS;
- if (!(ioe = create_async_io_engine())) {
- log_error("Failed to create bcache io engine.");
- return 0;
+ if (use_aio()) {
+ if (!(ioe = create_async_io_engine())) {
+ log_warn("Failed to set up async io, using sync io.");
+ init_use_aio(0);
+ }
+ }
+
+ if (!ioe) {
+ if (!(ioe = create_sync_io_engine())) {
+ log_error("Failed to set up sync io.");
+ return 0;
+ }
}
if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) {
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index 9941489..82c5706 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -24,6 +24,7 @@
static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _silent = 0;
static int _test = 0;
+static int _use_aio = 0;
static int _md_filtering = 0;
static int _internal_filtering = 0;
static int _fwraid_filtering = 0;
@@ -71,6 +72,11 @@ void init_test(int level)
_test = level;
}
+void init_use_aio(int use_aio)
+{
+ _use_aio = use_aio;
+}
+
void init_md_filtering(int level)
{
_md_filtering = level;
@@ -227,6 +233,11 @@ int test_mode(void)
return _test;
}
+int use_aio(void)
+{
+ return _use_aio;
+}
+
int md_filtering(void)
{
return _md_filtering;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index b383891..f985cfa 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -25,6 +25,7 @@ enum dev_ext_e;
void init_verbose(int level);
void init_silent(int silent);
void init_test(int level);
+void init_use_aio(int use_aio);
void init_md_filtering(int level);
void init_internal_filtering(int level);
void init_fwraid_filtering(int level);
@@ -58,6 +59,7 @@ const char *get_cmd_name(void);
void set_sysfs_dir_path(const char *path);
int test_mode(void);
+int use_aio(void);
int md_filtering(void);
int internal_filtering(void);
int fwraid_filtering(void);
--
2.19.1

View File

@ -1,126 +0,0 @@
From 7152c76a6b8949df3ed4ace7dd9148c5ef91a74f Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:21:50 +0800
Subject: [PATCH 09/17] bcache: sync io fixes
fix lseek error check
fix read/write error checks
handle zero return from read and write
don't return an error for short io
fix partial read/write loop
---
lib/device/bcache.c | 69 ++++++++++++++++++++++++++++++---------------
1 file changed, 47 insertions(+), 22 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 571ee7a..7384a32 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -328,7 +328,7 @@ struct io_engine *create_async_io_engine(void)
e->aio_context = 0;
r = io_setup(MAX_IO, &e->aio_context);
if (r < 0) {
- log_warn("io_setup failed");
+ log_debug("io_setup failed %d", r);
dm_free(e);
return NULL;
}
@@ -371,8 +371,11 @@ static void _sync_destroy(struct io_engine *ioe)
static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
sector_t sb, sector_t se, void *data, void *context)
{
- int r;
- uint64_t len = (se - sb) * 512, where;
+ int rv;
+ off_t off;
+ uint64_t where;
+ uint64_t pos = 0;
+ uint64_t len = (se - sb) * 512;
struct sync_engine *e = _to_sync(ioe);
struct sync_io *io = malloc(sizeof(*io));
if (!io) {
@@ -381,11 +384,17 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
}
where = sb * 512;
- r = lseek(fd, where, SEEK_SET);
- if (r < 0) {
- log_warn("unable to seek to position %llu", (unsigned long long) where);
- free(io);
- return false;
+
+ off = lseek(fd, where, SEEK_SET);
+ if (off == (off_t) -1) {
+ log_warn("Device seek error %d for offset %llu", errno, (unsigned long long)where);
+ free(io);
+ return false;
+ }
+ if (off != (off_t) where) {
+ log_warn("Device seek failed for offset %llu", (unsigned long long)where);
+ free(io);
+ return false;
}
/*
@@ -430,28 +439,44 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
len = nbytes;
}
- while (len) {
- do {
- if (d == DIR_READ)
- r = read(fd, data, len);
- else
- r = write(fd, data, len);
+ while (pos < len) {
+ if (d == DIR_READ)
+ rv = read(fd, (char *)data + pos, len - pos);
+ else
+ rv = write(fd, (char *)data + pos, len - pos);
- } while ((r < 0) && ((r == EINTR) || (r == EAGAIN)));
+ if (rv == -1 && errno == EINTR)
+ continue;
+ if (rv == -1 && errno == EAGAIN)
+ continue;
+
+ if (!rv)
+ break;
- if (r < 0) {
- log_warn("io failed %d", r);
+ if (rv < 0) {
+ if (d == DIR_READ)
+ log_debug("Device read error %d offset %llu len %llu", errno,
+ (unsigned long long)(where + pos),
+ (unsigned long long)(len - pos));
+ else
+ log_debug("Device write error %d offset %llu len %llu", errno,
+ (unsigned long long)(where + pos),
+ (unsigned long long)(len - pos));
free(io);
return false;
- }
-
- len -= r;
+ }
+ pos += rv;
}
- if (len) {
- log_warn("short io %u bytes remaining", (unsigned) len);
+ if (pos < len) {
+ if (d == DIR_READ)
+ log_warn("Device read short %u bytes remaining", (unsigned)(len - pos));
+ else
+ log_warn("Device write short %u bytes remaining", (unsigned)(len - pos));
+ /*
free(io);
return false;
+ */
}
--
2.19.1

View File

@ -1,37 +0,0 @@
From c04042cf7b7d4de3d892c6078787af8e29fd3c8a Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:23:39 +0800
Subject: [PATCH 10/17] lvmanip: uninitialized members in struct pv_list (#10)
Scenario: Given an existed LV `lvol0`, I want to create another LV
on the PVs used by `lvol0`.
I use `build_parallel_areas_from_lv()` to obtain the `pv_list` of each segments.
However, the returned `pv_list` is not properly initialized, which causes
segfault in subsequent operations.
(cherry picked from commit 859feb81e5b61ac2109b1d7850844ccf1ce3e5bf)
(cherry picked from commit 219ba4f54a462c175f5e9acaa0558afac94d5ff7)
Conflicts:
WHATS_NEW
---
lib/metadata/lv_manip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index e4293cc..d1389e7 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5860,7 +5860,7 @@ static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg,
if (find_pv_in_pv_list(&spvs->pvs, peg->pv))
return 1;
- if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
+ if (!(pvl = dm_pool_zalloc(cmd->mem, sizeof(*pvl)))) {
log_error("pv_list allocation failed");
return 0;
}
--
2.19.1

View File

@ -1,34 +0,0 @@
From bc10f60bdc1076b8b3405e9ce18a088cd770b268 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:39:13 +0800
Subject: [PATCH 11/17] apply obtain_device_list_from_udev to all libudev usage
udev_dev_is_md_component and udev_dev_is_mpath_component
are not used for obtaining the device list, but they still
use libudev for device info. When there are problems with
udev, these functions can get stuck. So, use the existing
obtain_device_list_from_udev config setting to also control
whether these "is component" functions are used, which gives
us a way to avoid using libudev entirely when it's causing
problems.
---
lib/device/dev-type.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index af4b407..e1671fa 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -1016,6 +1016,9 @@ int udev_dev_is_mpath_component(struct device *dev)
unsigned i = 0;
int ret = 0;
+ if (!obtain_device_list_from_udev())
+ return 0;
+
if (!udev_context) {
log_warn("WARNING: No udev context available to check if device %s is multipath component.", dev_name(dev));
return 0;
--
2.19.1

View File

@ -1,31 +0,0 @@
From 1e02c1dc7986800b92ec2662b74ebbf0e1e82f4c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:41:41 +0800
Subject: [PATCH 12/17] cov: dmstats check for failing malloc
Add missing check for allocation success.
Backported from: 9b7121226258f7dfe759cc1f8625cbfb80fec161
---
tools/dmsetup.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index aca595d..d47484b 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -5228,7 +5228,10 @@ static int _do_stats_create_regions(struct dm_stats *dms,
if (!segments || (info.target_count == 1))
region_ids = &region_id;
else
- region_ids = dm_malloc(info.target_count * sizeof(*region_ids));
+ if (!(region_ids = dm_malloc(info.target_count * sizeof(*region_ids)))) {
+ log_error("Failed to allocated region IDs.");
+ goto out;
+ }
do {
uint64_t segment_start, segment_len;
--
2.19.1

View File

@ -1,32 +0,0 @@
From 8b4941a9ebc83b49d25215ae914169db8441aafd Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:42:59 +0800
Subject: [PATCH 13/17] cov: ensure vars are set
Make sure, tmp_begin and tmp_end are always set, even for blind
coverity.
(cherry picked from commit 251366146727aac97af5de2eef855860d14910ca)
Conflicts:
device_mapper/libdm-report.c
---
libdm/libdm-report.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 6d140af..0401f9c 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -2380,7 +2380,7 @@ static const char *_get_reserved(struct dm_report *rh, unsigned type,
{
const struct dm_report_reserved_value *iter = implicit ? NULL : rh->reserved_values;
const struct dm_report_field_reserved_value *frv;
- const char *tmp_begin, *tmp_end, *tmp_s = s;
+ const char *tmp_begin = NULL, *tmp_end = NULL, *tmp_s = s;
const char *name = NULL;
char c;
--
2.19.1

View File

@ -1,43 +0,0 @@
From 673ff3585880ccacc53abaea01df027859ed5c1b Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:44:36 +0800
Subject: [PATCH 14/17] libdm: add memory barrier
Just for case ensure compiler is not able to optimize
memset() away for resources that are released.
This idea of using memory barrier is taken from openssl.
Other options would be to check for 'explicit_bzero' function.
(cherry picked from commit 55a8d6c86b4c6c6c707cfcc3dd887bca0632114f)
Conflicts:
device_mapper/ioctl/libdm-iface.c
---
libdm/ioctl/libdm-iface.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index 769b69c..7f48e37 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -466,6 +466,7 @@ static void _dm_zfree_string(char *string)
{
if (string) {
memset(string, 0, strlen(string));
+ asm volatile ("" ::: "memory"); /* Compiler barrier. */
dm_free(string);
}
}
@@ -474,6 +475,7 @@ static void _dm_zfree_dmi(struct dm_ioctl *dmi)
{
if (dmi) {
memset(dmi, 0, dmi->data_size);
+ asm volatile ("" ::: "memory"); /* Compiler barrier. */
dm_free(dmi);
}
}
--
2.19.1

View File

@ -1,51 +0,0 @@
From ebb978b547c4593de34d259e745824f12672614d Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:46:45 +0800
Subject: [PATCH 15/17] stats: fix error path when region is NULL
We should not call _stats_cleanup_region_ids() when regions
are NULL.
Also add backtracing for goto.
(cherry picked from commit 3750b0cff5ab1c41076afdf8275e3fa20aa756d0)
---
libdm/libdm-stats.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 6b4e3d8..ec9801a 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4867,24 +4867,24 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
group_id, &count, &regroup);
if (!regions)
- goto bad;
+ goto_out;
if (!dm_stats_list(dms, NULL))
- goto bad;
+ goto_bad;
/* regroup if there are regions to group */
if (regroup && (*regions != DM_STATS_REGION_NOT_PRESENT))
if (!_stats_group_file_regions(dms, regions, count, alias))
- goto bad;
+ goto_bad;
dm_free(bounds);
dm_free((char *) alias);
return regions;
bad:
_stats_cleanup_region_ids(dms, regions, count);
- dm_free(bounds);
- dm_free(regions);
out:
+ dm_free(regions);
+ dm_free(bounds);
dm_free((char *) alias);
return NULL;
}
--
2.19.1

View File

@ -1,29 +0,0 @@
From b6dae8eae08f85705248bc98120609d19d4424cf Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:47:57 +0800
Subject: [PATCH 16/17] stats: initilize regions to NULL
Commit 3750b0cff5ab1c41076afdf8275e3fa20aa756d0 used bad: error
path in more occasions thus it now needs regions defined as NULL.
(cherry picked from commit 83c6f7e7e6e76199d836bf694266c78e3cbc12f1)
---
libdm/libdm-stats.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index ec9801a..5d90231 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4807,7 +4807,7 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
{
struct dm_histogram *bounds = NULL;
int nr_bins, precise, regroup;
- uint64_t *regions, count = 0;
+ uint64_t *regions = NULL, count = 0;
const char *alias = NULL;
if (!dms->regions || !dm_stats_group_present(dms, group_id)) {
--
2.19.1

View File

@ -1,31 +0,0 @@
From d10584888038afb855099feebb117492c48d156c Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 14:49:08 +0800
Subject: [PATCH 17/17] dmsetup: Fix multi-line concise table parsing
Use the correct loop variable within the loop, instead of reusing the
initial value. Table lines after the first don't get terminated in
the right place.
Signed-off-by: Kurt Garloff <kurt@garloff.de>
(cherry picked from commit ccfbd505fea2f259f7c89dc23b020b838363a611)
---
tools/dmsetup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index d47484b..55fbd95 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -367,7 +367,7 @@ static int _parse_table_lines(struct dm_task *dmt)
do {
/* Identify and terminate each line */
- if ((next_pos = strchr(_table, '\n')))
+ if ((next_pos = strchr(pos, '\n')))
*next_pos++ = '\0';
if (!_parse_line(dmt, pos, "", ++line))
return_0;
--
2.19.1

View File

@ -1,194 +0,0 @@
From 80f7f6e0fdd7672a3bbb781b5edbc73c0699c539 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 17:13:26 +0800
Subject: [PATCH 01/19] Remove VG lock ordering check
Four commands lock two VGs at a time:
- vgsplit and vgmerge already have their own logic to
acquire the locks in the correct order.
- vgimportclone and vgrename disable this ordering check.
---
lib/cache/lvmcache.c | 66 -------------------------------------------
lib/cache/lvmcache.h | 1 -
lib/locking/locking.c | 5 ----
tools/toollib.c | 8 ------
tools/vgimportclone.c | 4 ---
tools/vgrename.c | 5 ----
6 files changed, 89 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 3e681a2..1a2e987 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -105,7 +105,6 @@ static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
-static int _suppress_lock_ordering = 0;
int lvmcache_init(struct cmd_context *cmd)
{
@@ -547,71 +546,6 @@ void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
_drop_metadata(vgname, drop_precommitted);
}
-/*
- * Ensure vgname2 comes after vgname1 alphabetically.
- * Orphan locks come last.
- * VG_GLOBAL comes first.
- */
-static int _vgname_order_correct(const char *vgname1, const char *vgname2)
-{
- if (is_global_vg(vgname1))
- return 1;
-
- if (is_global_vg(vgname2))
- return 0;
-
- if (is_orphan_vg(vgname1))
- return 0;
-
- if (is_orphan_vg(vgname2))
- return 1;
-
- if (strcmp(vgname1, vgname2) < 0)
- return 1;
-
- return 0;
-}
-
-void lvmcache_lock_ordering(int enable)
-{
- _suppress_lock_ordering = !enable;
-}
-
-/*
- * Ensure VG locks are acquired in alphabetical order.
- */
-int lvmcache_verify_lock_order(const char *vgname)
-{
- struct dm_hash_node *n;
- const char *vgname2;
-
- if (_suppress_lock_ordering)
- return 1;
-
- if (!_lock_hash)
- return 1;
-
- dm_hash_iterate(n, _lock_hash) {
- if (!dm_hash_get_data(_lock_hash, n))
- return_0;
-
- if (!(vgname2 = dm_hash_get_key(_lock_hash, n))) {
- log_error(INTERNAL_ERROR "VG lock %s hits NULL.",
- vgname);
- return 0;
- }
-
- if (!_vgname_order_correct(vgname2, vgname)) {
- log_errno(EDEADLK, INTERNAL_ERROR "VG lock %s must "
- "be requested before %s, not after.",
- vgname, vgname2);
- return 0;
- }
- }
-
- return 1;
-}
-
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unused)))
{
if (dm_hash_lookup(_lock_hash, vgname))
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index bf976e9..e9e6932 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -87,7 +87,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
-int lvmcache_verify_lock_order(const char *vgname);
/* Queries */
const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd, const char *vgname, const char *vgid, unsigned revalidate_labels);
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 2584227..093dbbd 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -319,11 +319,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
/* Global VG_ORPHANS lock covers all orphan formats. */
if (is_orphan_vg(vol))
vol = VG_ORPHANS;
- /* VG locks alphabetical, ORPHAN lock last */
- if ((lck_type != LCK_UNLOCK) &&
- !(flags & LCK_CACHE) &&
- !lvmcache_verify_lock_order(vol))
- return_0;
if ((flags == LCK_VG_DROP_CACHE) ||
(strcmp(vol, VG_GLOBAL) && strcmp(vol, VG_SYNC_NAMES))) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 01686b0..ce877cc 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -5514,14 +5514,6 @@ int pvcreate_each_device(struct cmd_context *cmd,
dm_list_add(&pp->arg_devices, &pd->list);
}
- /*
- * This function holds the orphans lock while reading VGs to look for
- * devices. This means the orphans lock is held while VG locks are
- * acquired, which is against lvmcache lock ordering rules, so disable
- * the lvmcache lock ordering checks.
- */
- lvmcache_lock_ordering(0);
-
/*
* Clear the cache before acquiring the orphan lock. (Clearing the
* cache with locks held is an error.) We want the orphan lock
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index c4c5d4c..087078a 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -342,9 +342,6 @@ retry_name:
log_debug("Changing VG %s to %s.", vp.old_vgname, vp.new_vgname);
- /* We don't care if the new name comes before the old in lock order. */
- lvmcache_lock_ordering(0);
-
if (!lock_vol(cmd, vp.new_vgname, LCK_VG_WRITE, NULL)) {
log_error("Can't get lock for new VG name %s", vp.new_vgname);
goto out;
@@ -363,7 +360,6 @@ out:
unlock_vg(cmd, NULL, VG_GLOBAL);
internal_filter_clear();
init_internal_filtering(0);
- lvmcache_lock_ordering(1);
destroy_processing_handle(cmd, handle);
/* Enable lvmetad again if no duplicates are left. */
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 4f2a08b..bbc3087 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -99,13 +99,8 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
* this uuid-for-name case.
*/
if (vp->lock_vg_old_first || vp->old_name_is_uuid) {
- if (vp->old_name_is_uuid)
- lvmcache_lock_ordering(0);
-
if (!_lock_new_vg_for_rename(cmd, vp->vg_name_new))
return ECMD_FAILED;
-
- lvmcache_lock_ordering(1);
}
dev_dir = cmd->dev_dir;
--
2.19.1

View File

@ -1,223 +0,0 @@
From b71954e7599a651470e51020c9aa9205a1551ad5 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 17:23:43 +0800
Subject: [PATCH 02/19] Fix use of orphan lock in commands
vgreduce, vgremove and vgcfgrestore were acquiring
the orphan lock in the midst of command processing
instead of at the start of the command. (The orphan
lock moved to being acquired at the start of the
command back when pvcreate/vgcreate/vgextend were
reworked based on pvcreate_each_device.)
vgsplit also needed a small update to avoid reacquiring
a VG lock that it already held (for the new VG name).
---
lib/metadata/metadata-exported.h | 4 ++++
lib/metadata/metadata.c | 10 ++--------
lib/metadata/vg.c | 14 ++++++--------
tools/vgcfgrestore.c | 12 ++++++------
tools/vgreduce.c | 7 +++++++
tools/vgremove.c | 7 +++++++
tools/vgsplit.c | 2 ++
7 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index f4fb112..e2fe76b 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -704,6 +704,10 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
const char *vgid, uint32_t read_flags, uint32_t lockd_state);
struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_name,
const char *vgid, uint32_t read_flags, uint32_t lockd_state);
+struct volume_group *vg_read_orphans(struct cmd_context *cmd,
+ uint32_t warn_flags,
+ const char *orphan_vgname,
+ int *consistent);
/*
* Test validity of a VG handle.
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 2292568..2c81623 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -600,14 +600,8 @@ int vg_remove(struct volume_group *vg)
{
int ret;
- if (!lock_vol(vg->cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
- log_error("Can't get lock for orphan PVs");
- return 0;
- }
-
ret = vg_remove_direct(vg);
- unlock_vg(vg->cmd, vg, VG_ORPHANS);
return ret;
}
@@ -3377,7 +3371,7 @@ static int _vg_read_orphan_pv(struct lvmcache_info *info, void *baton)
}
/* Make orphan PVs look like a VG. */
-static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
+struct volume_group *vg_read_orphans(struct cmd_context *cmd,
uint32_t warn_flags,
const char *orphan_vgname,
int *consistent)
@@ -3768,7 +3762,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
"with pre-commit.");
return NULL;
}
- return _vg_read_orphans(cmd, warn_flags, vgname, consistent);
+ return vg_read_orphans(cmd, warn_flags, vgname, consistent);
}
uuid[0] = '\0';
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index b8b1501..3bde1fd 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -722,6 +722,7 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
{
struct pv_list *pvl;
struct volume_group *orphan_vg = NULL;
+ int consistent;
int r = 0;
const char *name = pv_dev_name(pv);
@@ -730,6 +731,8 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
return r;
}
+ log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv));
+
if (pv_pe_alloc_count(pv)) {
log_error("Physical volume \"%s\" still in use", name);
return r;
@@ -741,11 +744,6 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
return r;
}
- if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
- log_error("Can't get lock for orphan PVs");
- return r;
- }
-
pvl = find_pv_in_vg(vg, name);
if (!archive(vg))
@@ -767,8 +765,8 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
vg->free_count -= pv_pe_count(pv) - pv_pe_alloc_count(pv);
vg->extent_count -= pv_pe_count(pv);
- orphan_vg = vg_read_for_update(cmd, vg->fid->fmt->orphan_vg_name,
- NULL, 0, 0);
+ /* FIXME: we don't need to vg_read the orphan vg here */
+ orphan_vg = vg_read_orphans(cmd, 0, vg->fid->fmt->orphan_vg_name, &consistent);
if (vg_read_error(orphan_vg))
goto bad;
@@ -806,6 +804,6 @@ bad:
/* If we are committing here or we had an error then we will free fid */
if (pvl && (commit || r != 1))
free_pv_fid(pvl->pv);
- unlock_and_release_vg(cmd, orphan_vg, VG_ORPHANS);
+ release_vg(orphan_vg);
return r;
}
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
index 48a2fa4..37df8cf 100644
--- a/tools/vgcfgrestore.c
+++ b/tools/vgcfgrestore.c
@@ -136,14 +136,14 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
lvmetad_rescan = 1;
}
- if (!lock_vol(cmd, vg_name, LCK_VG_WRITE, NULL)) {
- log_error("Unable to lock volume group %s", vg_name);
+ if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
+ log_error("Unable to lock orphans.");
return ECMD_FAILED;
}
- if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
- log_error("Unable to lock orphans");
- unlock_vg(cmd, NULL, vg_name);
+ if (!lock_vol(cmd, vg_name, LCK_VG_WRITE, NULL)) {
+ log_error("Unable to lock volume group %s.", vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return ECMD_FAILED;
}
@@ -156,8 +156,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
arg_str_value(cmd, file_ARG, ""),
arg_count(cmd, force_long_ARG)) :
backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) {
- unlock_vg(cmd, NULL, VG_ORPHANS);
unlock_vg(cmd, NULL, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
log_error("Restore failed.");
ret = ECMD_FAILED;
goto rescan;
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index e8479a8..aa35453 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -231,9 +231,16 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
handle->custom_handle = &vp;
if (!repairing) {
+ if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
+ log_error("Can't get lock for orphan PVs");
+ ret = ECMD_FAILED;
+ goto out;
+ }
+
/* FIXME: Pass private struct through to all these functions */
/* and update in batch afterwards? */
ret = process_each_pv(cmd, argc, argv, vg_name, 0, READ_FOR_UPDATE, handle, _vgreduce_single);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
goto out;
}
diff --git a/tools/vgremove.c b/tools/vgremove.c
index 8bf3841..5010e7d 100644
--- a/tools/vgremove.c
+++ b/tools/vgremove.c
@@ -108,10 +108,17 @@ int vgremove(struct cmd_context *cmd, int argc, char **argv)
*/
cmd->lockd_gl_disable = 1;
+ if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
+ log_error("Can't get lock for orphan PVs");
+ return ECMD_FAILED;
+ }
+
cmd->handles_missing_pvs = 1;
ret = process_each_vg(cmd, argc, argv, NULL, NULL,
READ_FOR_UPDATE, 0,
NULL, &_vgremove_single);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+
return ret;
}
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index 2d39111..fb1fb6b 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -749,8 +749,10 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
/*
* Finally, remove the EXPORTED flag from the new VG and write it out.
+ * We need to unlock vg_to because vg_read_for_update wants to lock it.
*/
if (!test_mode()) {
+ unlock_vg(cmd, NULL, vg_name_to);
release_vg(vg_to);
vg_to = vg_read_for_update(cmd, vg_name_to, NULL,
READ_ALLOW_EXPORTED, 0);
--
2.19.1

View File

@ -1,54 +0,0 @@
From d5b2f439a1a36938b4f7659bc7c40870db928c4a Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 17:38:14 +0800
Subject: [PATCH 03/19] metadata: remove an unused and incorrect overflow check
Remove another instance of an invalid check for metadata
overflow during read. The previous instance was removed
in commit 5fb15b193.
This was checking for metadata that that overflowed the
circular disk metadata buffer during read, but such metadata
cannot be written, so it shouldn't be possible to find see.
Also, the check was incorrect and could trigger when there
was no overflow.
---
lib/format_text/format-text.c | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 4160ba8..4e5b08e 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -553,14 +553,6 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
if (rlocn->offset + rlocn->size > mdah->size)
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
- if (wrap > rlocn->offset) {
- log_error("Metadata for VG %s on %s at %llu size %llu is too large for circular buffer.",
- vgname, dev_name(area->dev),
- (unsigned long long)(area->start + rlocn->offset),
- (unsigned long long)rlocn->size);
- goto out;
- }
-
vg = text_read_metadata(fid, NULL, vg_fmtdata, use_previous_vg, area->dev, primary_mda,
(off_t) (area->start + rlocn->offset),
(uint32_t) (rlocn->size - wrap),
@@ -1249,13 +1241,6 @@ int read_metadata_location_summary(const struct format_type *fmt,
if (rlocn->offset + rlocn->size > mdah->size)
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
- if (wrap > rlocn->offset) {
- log_error("Metadata location on %s at %llu is too large for circular buffer.",
- dev_name(dev_area->dev),
- (unsigned long long)(dev_area->start + rlocn->offset));
- return 0;
- }
-
/*
* Did we see this metadata before?
* Look in lvmcache to see if there is vg info matching
--
2.19.1

View File

@ -1,41 +0,0 @@
From 3d3b47975f25027b0dbc454f64fddea04a8c01f8 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 19:35:31 +0800
Subject: [PATCH 04/19] cov: dmeventd plugin fix memleak
Fix memory leak when policy command fails too frequently and
plugin decided to skip it.
---
daemons/dmeventd/plugins/thin/dmeventd_thin.c | 2 +-
daemons/dmeventd/plugins/vdo/dmeventd_vdo.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemons/dmeventd/plugins/thin/dmeventd_thin.c b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
index 29b0391..0330947 100644
--- a/daemons/dmeventd/plugins/thin/dmeventd_thin.c
+++ b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
@@ -286,7 +286,7 @@ void process_event(struct dm_task *dmt,
if (state->fails++ <= state->max_fails) {
log_debug("Postponing frequently failing policy (%u <= %u).",
state->fails - 1, state->max_fails);
- return;
+ goto out;
}
if (state->max_fails < MAX_FAILS)
state->max_fails <<= 1;
diff --git a/daemons/dmeventd/plugins/vdo/dmeventd_vdo.c b/daemons/dmeventd/plugins/vdo/dmeventd_vdo.c
index 389632c..6b35b2f 100644
--- a/daemons/dmeventd/plugins/vdo/dmeventd_vdo.c
+++ b/daemons/dmeventd/plugins/vdo/dmeventd_vdo.c
@@ -261,7 +261,7 @@ void process_event(struct dm_task *dmt,
if (state->fails++ <= state->max_fails) {
log_debug("Postponing frequently failing policy (%u <= %u).",
state->fails - 1, state->max_fails);
- return;
+ goto out;
}
if (state->max_fails < MAX_FAILS)
state->max_fails <<= 1;
--
2.19.1

View File

@ -1,26 +0,0 @@
From 0b3d3a5250810ace1770ca29afba9fc3bc0ca000 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 19:43:49 +0800
Subject: [PATCH 05/19] cov: fix missing null allocation check
---
base/data-struct/radix-tree.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/base/data-struct/radix-tree.c b/base/data-struct/radix-tree.c
index 222b350..52066eb 100644
--- a/base/data-struct/radix-tree.c
+++ b/base/data-struct/radix-tree.c
@@ -261,7 +261,8 @@ static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, uint8_t
if (kb[i] != pc->prefix[i])
break;
- pc2 = zalloc(sizeof(*pc2) + pc->len - i);
+ if (!(pc2 = zalloc(sizeof(*pc2) + pc->len - i)))
+ return false;
pc2->len = pc->len - i;
memmove(pc2->prefix, pc->prefix + i, pc2->len);
pc2->child = pc->child;
--
2.19.1

View File

@ -1,30 +0,0 @@
From 0049b42891ac6e095b91643320743a3c0a3ae882 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 19:47:31 +0800
Subject: [PATCH 06/19] cov: add check for positive value
As pgsize parameter for _init_free_list() can't be negative,
report problem in case for any reason we would get negative number.
---
lib/device/bcache.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 7384a32..0fc7364 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -1039,6 +1039,11 @@ struct bcache *bcache_create(sector_t block_sectors, unsigned nr_cache_blocks,
unsigned max_io = engine->max_io(engine);
long pgsize = sysconf(_SC_PAGESIZE);
+ if (pgsize < 0) {
+ log_warn("WARNING: _SC_PAGESIZE returns negative value.");
+ return NULL;
+ }
+
if (!nr_cache_blocks) {
log_warn("bcache must have at least one cache block");
return NULL;
--
2.19.1

View File

@ -1,43 +0,0 @@
From 494d1fdc82fa4c5a8ae0c976ea0076f9347ee800 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 19:55:12 +0800
Subject: [PATCH 07/19] cov: fix failing filter initialization
When persistent_filter_create() fails, the existing passed filter
should be preserved, so it could be properly deleted on
error path - so new pfilter is assigned instead.
---
lib/commands/toolcontext.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index ecd8fd7..df9ca75 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1197,7 +1197,7 @@ bad:
int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
{
const char *dev_cache;
- struct dev_filter *filter = NULL, *filter_components[2] = {0};
+ struct dev_filter *pfilter, *filter = NULL, *filter_components[2] = {0};
int nr_filt;
struct stat st;
const struct dm_config_node *cn;
@@ -1250,12 +1250,12 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
goto_bad;
- if (!(filter = persistent_filter_create(cmd->dev_types, filter, dev_cache))) {
+ if (!(pfilter = persistent_filter_create(cmd->dev_types, filter, dev_cache))) {
log_verbose("Failed to create persistent device filter.");
goto bad;
}
- cmd->filter = filter;
+ cmd->filter = filter = pfilter;
if (lvmetad_used()) {
nr_filt = 0;
--
2.19.1

View File

@ -1,53 +0,0 @@
From 71860814428050f4f180e9a264bab34c1916f15d Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 20:05:35 +0800
Subject: [PATCH 08/19] cov: check dev_close_immediate
Function can report log_error() on fail path.
---
lib/device/dev-cache.c | 4 ++--
lib/device/dev-io.c | 6 ++++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index c866ff9..8af1de9 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1344,8 +1344,8 @@ static int _check_for_open_devices(int close_immediate)
log_error("Device '%s' has been left open (%d remaining references).",
dev_name(dev), dev->open_count);
num_open++;
- if (close_immediate)
- dev_close_immediate(dev);
+ if (close_immediate && !dev_close_immediate(dev))
+ stack;
}
}
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index 2a4967f..8bf1847 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -510,7 +510,8 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
/* dev_close_immediate will decrement this */
dev->open_count++;
- dev_close_immediate(dev);
+ if (!dev_close_immediate(dev))
+ return_0;
// FIXME: dev with DEV_ALLOCED is released
// but code is referencing it
}
@@ -591,7 +592,8 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (!(dev->flags & DEV_REGULAR) &&
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: fstat failed: Has device name changed?", name);
- dev_close_immediate(dev);
+ if (!dev_close_immediate(dev))
+ stack;
return 0;
}
--
2.19.1

View File

@ -1,26 +0,0 @@
From 50e44b8fd06cd3af952b253249ab8e144d3296ec Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 20:09:56 +0800
Subject: [PATCH 09/19] cov: make sure label scans valid lvinfo
---
lib/label/label.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/label/label.c b/lib/label/label.c
index 5114959..86c84d8 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -991,7 +991,8 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
struct device *dev;
dev_t devt;
- lv_info(cmd, lv, 0, &lvinfo, 0, 0);
+ if (!lv_info(cmd, lv, 0, &lvinfo, 0, 0))
+ return;
devt = MKDEV(lvinfo.major, lvinfo.minor);
if ((dev = dev_cache_get_by_devt(devt, NULL)))
label_scan_invalidate(dev);
--
2.19.1

View File

@ -1,29 +0,0 @@
From ce4e728a2d7b9fd8fda7cb8cabb0af763abac886 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 20:14:33 +0800
Subject: [PATCH 10/19] cov: add missing error path check for label_scan_open
---
lib/label/label.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/label/label.c b/lib/label/label.c
index 86c84d8..63300d2 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1087,7 +1087,11 @@ int label_read_sector(struct device *dev, uint64_t read_sector)
block_sector = block_num * BCACHE_BLOCK_SIZE_IN_SECTORS;
start_sector = read_sector % BCACHE_BLOCK_SIZE_IN_SECTORS;
- label_scan_open(dev);
+ if (!label_scan_open(dev)) {
+ log_error("Error opening device %s for prefetch %llu sector.",
+ dev_name(dev), (unsigned long long)block_num);
+ return false;
+ }
bcache_prefetch(scan_bcache, dev->bcache_fd, block_num);
--
2.19.1

View File

@ -1,34 +0,0 @@
From 8ff7d5679a2300d09e9296f7fdfa0a0db90043e9 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 20:21:54 +0800
Subject: [PATCH 11/19] cov: pvscan ensure sigle_devs list is always
initialized
---
tools/pvscan.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 2915db5..5a43069 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -315,6 +315,7 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv)
int add_errors = 0;
int ret = ECMD_PROCESSED;
+ dm_list_init(&single_devs);
dm_list_init(&found_vgnames);
dm_list_init(&pp.changed_vgnames);
@@ -443,8 +444,6 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv)
/* Creates a list of dev names from /dev, sysfs, etc; does not read any. */
dev_cache_scan();
- dm_list_init(&single_devs);
-
while (argc--) {
pv_name = *argv++;
if (pv_name[0] == '/') {
--
2.19.1

View File

@ -1,65 +0,0 @@
From 73d1f273084f7a50c26f1ebc9586dbbffd3d082b Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 21:33:22 +0800
Subject: [PATCH 12/19] fix: cov: missed return value test
use the existing error paths
---
lib/format_text/format-text.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 4e5b08e..1a6c3a3 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -468,12 +468,14 @@ static struct raw_locn *_read_metadata_location_vg(struct device_area *dev_area,
*/
memset(vgnamebuf, 0, sizeof(vgnamebuf));
- dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf);
+ if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf))
+ goto fail;
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
return rlocn;
+fail:
log_error("Metadata on %s at %llu has wrong VG name \"%s\" expected %s.",
dev_name(dev_area->dev),
(unsigned long long)(dev_area->start + rlocn->offset),
@@ -1196,7 +1198,7 @@ int read_metadata_location_summary(const struct format_type *fmt,
struct raw_locn *rlocn;
uint32_t wrap = 0;
unsigned int len = 0;
- char buf[NAME_LEN + 1] __attribute__((aligned(8)));
+ char namebuf[NAME_LEN + 1] __attribute__((aligned(8)));
uint64_t buffer_size, current_usage;
if (mda_free_sectors)
@@ -1221,16 +1223,17 @@ int read_metadata_location_summary(const struct format_type *fmt,
return 0;
}
- dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, buf);
-
- while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
+ memset(namebuf, 0, sizeof(namebuf));
+ if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, namebuf))
+ stack;
+ while (namebuf[len] && !isspace(namebuf[len]) && namebuf[len] != '{' &&
len < (NAME_LEN - 1))
len++;
- buf[len] = '\0';
+ namebuf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
- if (!validate_name(buf)) {
+ if (!validate_name(namebuf)) {
log_error("Metadata location on %s at %llu begins with invalid VG name.",
dev_name(dev_area->dev),
(unsigned long long)(dev_area->start + rlocn->offset));
--
2.19.1

View File

@ -1,44 +0,0 @@
From 24d0326e17b1088751d005cf60783bc05114733b Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 21:54:28 +0800
Subject: [PATCH 13/19] cov: trace failing pthread_kill
---
daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c b/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
index 93697a0..d4614b5 100644
--- a/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
+++ b/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
@@ -175,6 +175,7 @@ void process_event(struct dm_task *dmt,
const char *device = dm_task_get_name(dmt);
int percent;
struct dm_info info;
+ int ret;
/* No longer monitoring, waiting for remove */
if (!state->percent_check)
@@ -205,7 +206,8 @@ void process_event(struct dm_task *dmt,
/* Maybe configurable ? */
_remove(dm_task_get_uuid(dmt));
#endif
- pthread_kill(pthread_self(), SIGALRM);
+ if ((ret = pthread_kill(pthread_self(), SIGALRM)) && (ret != ESRCH))
+ log_sys_error("pthread_kill", "self");
goto out;
}
@@ -213,7 +215,8 @@ void process_event(struct dm_task *dmt,
/* TODO eventually recognize earlier when room is enough */
log_info("Dropping monitoring of fully provisioned snapshot %s.",
device);
- pthread_kill(pthread_self(), SIGALRM);
+ if ((ret = pthread_kill(pthread_self(), SIGALRM)) && (ret != ESRCH))
+ log_sys_error("pthread_kill", "self");
goto out;
}
--
2.19.1

View File

@ -1,29 +0,0 @@
From 8630d2363be3b57569acff6d323f7d8a8c3d3ce9 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 21:56:11 +0800
Subject: [PATCH 14/19] cov: avoid unsing unchecked label_scan_open
Drop extra call too label_scan_open() without checking return value,
and let code go through next call bellow.
---
lib/label/label.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/label/label.c b/lib/label/label.c
index 63300d2..8efc89e 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1313,9 +1313,7 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
log_debug("Close and reopen to write %s", dev_name(dev));
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
-
- dev->flags |= DEV_BCACHE_WRITE;
- label_scan_open(dev);
+ /* goes to label_scan_open() since bcache_fd < 0 */
}
if (dev->bcache_fd <= 0) {
--
2.19.1

View File

@ -1,48 +0,0 @@
From ec6ba10081488699edaba1c80ef69f5a14bced00 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 22:20:42 +0800
Subject: [PATCH 15/19] lvmlockd: fix missing LV lock for lvconvert repair
Add missing lvmlockd LV lock for lvconvert repair
on mirror and thin/cache pools.
---
tools/lvconvert.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index d7a618d..794877e 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3461,6 +3461,18 @@ static int _lvconvert_repair_pvs_mirror(struct cmd_context *cmd, struct logical_
struct lvinfo info;
int ret;
+ /*
+ * We want to allow cmirror active on multiple nodes to be repaired,
+ * but normal mirror to only be repaired if active exclusively here.
+ * If the LV is active it already has the necessary lock, but if not
+ * active, then require ex since we cannot know the active state on
+ * other hosts.
+ */
+ if (!lv_is_active(lv)) {
+ if (!lockd_lv(cmd, lv, "ex", 0))
+ return_0;
+ }
+
/*
* FIXME: temporary use of lp because _lvconvert_mirrors_repair()
* and _aux() still use lp fields everywhere.
@@ -3594,6 +3606,10 @@ static int _lvconvert_repair_cachepool_thinpool(struct cmd_context *cmd, struct
int poolmetadataspare = arg_int_value(cmd, poolmetadataspare_ARG, DEFAULT_POOL_METADATA_SPARE);
struct dm_list *use_pvh;
+ /* ensure it's not active elsewhere. */
+ if (!lockd_lv(cmd, lv, "ex", 0))
+ return_0;
+
if (cmd->position_argc > 1) {
/* First pos arg is required LV, remaining are optional PVs. */
if (!(use_pvh = create_pv_list(cmd->mem, lv->vg, cmd->position_argc - 1, cmd->position_argv + 1, 0)))
--
2.19.1

View File

@ -1,25 +0,0 @@
From 9b898dc260048071fb5f0ab2d85580c73225e9d3 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 22:30:24 +0800
Subject: [PATCH 16/19] lvconvert: ensure proper init of pv_list
---
tools/lvconvert.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 794877e..9e9029e 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -483,7 +483,7 @@ static struct dm_list *_failed_pv_list(struct volume_group *vg)
if (pvl->pv->pe_alloc_count == 0)
continue;
- if (!(new_pvl = dm_pool_alloc(vg->vgmem, sizeof(*new_pvl)))) {
+ if (!(new_pvl = dm_pool_zalloc(vg->vgmem, sizeof(*new_pvl)))) {
log_error("Allocation of failed_pvs list entry failed.");
return NULL;
}
--
2.19.1

View File

@ -1,26 +0,0 @@
From 769dca1377ecbac623d78ca86a7e3c80b2d4d4f1 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 22:34:11 +0800
Subject: [PATCH 17/19] dmeventd: unlock lvm2 lock on error path
New code missed to unlock locked lvm2 on error path when
command is not configured.
---
daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
index 5be11f1..be58aac 100644
--- a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
+++ b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
@@ -159,6 +159,7 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
dmeventd_lvm2_lock();
if (!dmeventd_lvm2_run(cmd) ||
!(env = getenv(cmd))) {
+ dmeventd_lvm2_unlock();
log_error("Unable to find configured command.");
return 0;
}
--
2.19.1

View File

@ -1,27 +0,0 @@
From a805a5254b06f30574f8d322fa451763335c1ee1 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 22:37:32 +0800
Subject: [PATCH 18/19] mangenerator: check strdup was successfull
Check for strdup != NULL
and drop unneeded zeroing when buffer is overwritten.
---
tools/command.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/command.c b/tools/command.c
index f2a2722..9516fde 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1465,7 +1465,7 @@ int define_commands(struct cmd_context *cmdtool, const char *run_name)
if (_is_desc_line(line_argv[0]) && !skip && cmd) {
char *desc = dm_pool_strdup(cmdtool->libmem, line_orig);
- if (cmd->desc) {
+ if (cmd->desc && desc) {
int newlen = strlen(cmd->desc) + strlen(desc) + 2;
char *newdesc = dm_pool_alloc(cmdtool->libmem, newlen);
if (newdesc) {
--
2.19.1

View File

@ -1,43 +0,0 @@
From 3ac89d45f3b5091fa3864248a50a4d15ebacb6d9 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 13 Mar 2019 22:51:19 +0800
Subject: [PATCH 19/19] cov: ensure lock_type is not NULL
---
tools/vgchange.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 623517b..40c3c4d 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -932,7 +932,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
int lv_lock_count = 0;
/* Special recovery case. */
- if (lockopt && !strcmp(lock_type, "none") && !strcmp(lockopt, "force")) {
+ if (lock_type && lockopt && !strcmp(lock_type, "none") && !strcmp(lockopt, "force")) {
vg->status &= ~CLUSTERED;
vg->lock_type = "none";
vg->lock_args = NULL;
@@ -997,7 +997,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
}
/* none to clvm */
- if (!strcmp(vg->lock_type, "none") && !strcmp(lock_type, "clvm")) {
+ if (lock_type && !strcmp(vg->lock_type, "none") && !strcmp(lock_type, "clvm")) {
log_warn("New clvm lock type will not be usable with lvmlockd.");
vg->status |= CLUSTERED;
vg->lock_type = "clvm"; /* this is optional */
@@ -1110,7 +1110,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
}
/* ... to none */
- if (!strcmp(lock_type, "none")) {
+ if (lock_type && !strcmp(lock_type, "none")) {
vg->lock_type = NULL;
vg->system_id = cmd->system_id ? dm_pool_strdup(vg->vgmem, cmd->system_id) : NULL;
return 1;
--
2.19.1

View File

@ -1,411 +0,0 @@
From afb4ce9833dd60220f48a273c7b50c692c900164 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Sat, 23 Mar 2019 18:25:27 +0800
Subject: [PATCH] Remove checking for locked VGs
A few places were calling a function to check if a
VG lock was held. The only place it was actually
needed is for pvcreate which wants to do its own
locking (and scanning) around process_each_pv.
The locking/scanning exceptions for pvcreate in
process_each_pv/vg_read can be enabled by just passing
a couple of flags instead of checking if the VG is
already locked. This also means that these special
cases won't be enabled unknowingly in other places
where they shouldn't be used.
---
lib/cache/lvmcache.c | 13 -----
lib/cache/lvmcache.h | 1 -
lib/metadata/metadata-exported.h | 2 +
lib/metadata/metadata.c | 18 ++----
liblvm/lvm_vg.c | 2 -
tools/toollib.c | 94 +++++++++-----------------------
tools/vgreduce.c | 2 +-
7 files changed, 35 insertions(+), 97 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 1a2e987..a48c5e7 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -536,9 +536,6 @@ void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
if (!_saved_vg_hash)
return;
- if (lvmcache_vgname_is_locked(VG_GLOBAL))
- return;
-
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
if (!strcmp(vgname, VG_ORPHANS)) {
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0);
@@ -561,14 +558,6 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unuse
}
}
-int lvmcache_vgname_is_locked(const char *vgname)
-{
- if (!_lock_hash)
- return 0;
-
- return dm_hash_lookup(_lock_hash, is_orphan_vg(vgname) ? VG_ORPHANS : vgname) ? 1 : 0;
-}
-
void lvmcache_unlock_vgname(const char *vgname)
{
if (!dm_hash_lookup(_lock_hash, vgname))
@@ -1997,8 +1986,6 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
else if (!_lvmcache_update_vgid(NULL, vginfo, vgid)) /* Orphans */
return_0;
- _update_cache_vginfo_lock_state(vginfo, lvmcache_vgname_is_locked(vgname));
-
/* FIXME Check consistency of list! */
vginfo->fmt = fmt;
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index e9e6932..0567a81 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -107,7 +107,6 @@ char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid);
const char *lvmcache_vgname_from_info(struct lvmcache_info *info);
const struct format_type *lvmcache_fmt_from_info(struct lvmcache_info *info);
int lvmcache_vgs_locked(void);
-int lvmcache_vgname_is_locked(const char *vgname);
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd);
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index e2fe76b..a4ca17f 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -178,6 +178,8 @@
#define READ_OK_NOTFOUND 0x00040000U
#define READ_WARN_INCONSISTENT 0x00080000U
#define READ_FOR_UPDATE 0x00100000U /* A meta-flag, useful with toollib for_each_* functions. */
+#define PROCESS_SKIP_SCAN 0x00200000U /* skip lvmcache_label_scan in process_each_pv */
+#define PROCESS_SKIP_ORPHAN_LOCK 0x00400000U /* skip lock_vol(VG_ORPHAN) in vg_read */
/* vg's "read_status" field */
#define FAILED_INCONSISTENT 0x00000001U
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 2c81623..237e57b 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3118,12 +3118,6 @@ int vg_commit(struct volume_group *vg)
int cache_updated = 0;
struct pv_list *pvl;
- if (!lvmcache_vgname_is_locked(vg->name)) {
- log_error(INTERNAL_ERROR "Attempt to write new VG metadata "
- "without locking %s", vg->name);
- return cache_updated;
- }
-
cache_updated = _vg_commit_mdas(vg);
set_vg_notify(vg->cmd);
@@ -5465,8 +5459,8 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
uint32_t failure = 0;
uint32_t warn_flags = 0;
int is_shared = 0;
- int already_locked;
int write_lock_held = (lock_flags == LCK_VG_WRITE);
+ int skip_lock = is_orphan_vg(vg_name) && (read_flags & PROCESS_SKIP_ORPHAN_LOCK);
if ((read_flags & READ_ALLOW_INCONSISTENT) || (lock_flags != LCK_VG_WRITE))
consistent = 0;
@@ -5477,15 +5471,13 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
return NULL;
}
- already_locked = lvmcache_vgname_is_locked(vg_name);
-
- if (!already_locked &&
+ if (!skip_lock &&
!lock_vol(cmd, vg_name, lock_flags, NULL)) {
log_error("Can't get lock for %s", vg_name);
return _vg_make_handle(cmd, vg, FAILED_LOCKING);
}
- if (already_locked)
+ if (skip_lock)
log_very_verbose("Locking %s already done", vg_name);
if (is_orphan_vg(vg_name))
@@ -5553,13 +5545,13 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
goto_bad;
if (!(vg = _vg_make_handle(cmd, vg, failure)) || vg_read_error(vg))
- if (!already_locked)
+ if (!skip_lock)
unlock_vg(cmd, vg, vg_name);
return vg;
bad:
- if (!already_locked)
+ if (!skip_lock)
unlock_vg(cmd, vg, vg_name);
bad_no_unlock:
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index ee6fa4e..616c78f 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -186,8 +186,6 @@ int lvm_vg_close(vg_t vg)
struct saved_env e = store_user_env(vg->cmd);
if (vg_read_error(vg) == FAILED_LOCKING)
release_vg(vg);
- else if (!lvmcache_vgname_is_locked(vg->name))
- release_vg(vg);
else
unlock_and_release_vg(vg->cmd, vg, vg->name);
restore_user_env(&e);
diff --git a/tools/toollib.c b/tools/toollib.c
index ce877cc..3210e28 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1969,7 +1969,6 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
int skip;
int notfound;
int process_all = 0;
- int already_locked;
int do_report_ret_code = 1;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
@@ -2012,8 +2011,6 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
continue;
}
- already_locked = lvmcache_vgname_is_locked(vg_name);
-
vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state);
if (_ignore_vg(vg, vg_name, arg_vgnames, read_flags, &skip, &notfound)) {
stack;
@@ -2041,7 +2038,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
ret_max = ret;
}
- if (!vg_read_error(vg) && !already_locked)
+ if (!vg_read_error(vg))
unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
@@ -3681,8 +3678,6 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
continue;
}
- already_locked = lvmcache_vgname_is_locked(vg_name);
-
vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state);
if (_ignore_vg(vg, vg_name, arg_vgnames, read_flags, &skip, &notfound)) {
stack;
@@ -3701,8 +3696,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
if (ret > ret_max)
ret_max = ret;
- if (!already_locked)
- unlock_vg(cmd, vg, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -4400,7 +4394,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
int ret;
int skip;
int notfound;
- int already_locked;
+ int skip_lock;
int do_report_ret_code = 1;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
@@ -4434,7 +4428,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
log_debug("Processing PVs in VG %s", vg_name);
- already_locked = lvmcache_vgname_is_locked(vg_name);
+ skip_lock = is_orphan_vg(vg_name) && (read_flags & PROCESS_SKIP_ORPHAN_LOCK);
vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state);
if (_ignore_vg(vg, vg_name, NULL, read_flags, &skip, &notfound)) {
@@ -4462,7 +4456,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
if (ret > ret_max)
ret_max = ret;
- if (!skip && !already_locked)
+ if (!skip && !skip_lock)
unlock_vg(cmd, vg, vg->name);
endvg:
release_vg(vg);
@@ -4501,7 +4495,6 @@ int process_each_pv(struct cmd_context *cmd,
struct device_id_list *dil;
int process_all_pvs;
int process_all_devices;
- int orphans_locked;
int ret_max = ECMD_PROCESSED;
int ret;
@@ -4549,8 +4542,6 @@ int process_each_pv(struct cmd_context *cmd,
return ECMD_FAILED;
}
- orphans_locked = lvmcache_vgname_is_locked(VG_ORPHANS);
-
process_all_pvs = dm_list_empty(&arg_pvnames) && dm_list_empty(&arg_tags);
process_all_devices = process_all_pvs && (cmd->cname->flags & ENABLE_ALL_DEVS) && all_is_set;
@@ -4561,22 +4552,8 @@ int process_each_pv(struct cmd_context *cmd,
goto_out;
}
- /*
- * This full scan would be done by _get_all_devices() if
- * it were not done here first. It's called here first
- * so that get_vgnameids() will look at any new devices.
- * When orphans is already locked, these steps are done
- * before process_each_pv is called.
- */
- if (!trust_cache() && !orphans_locked) {
- lvmcache_destroy(cmd, 1, 0);
-
- /*
- * Scan all devices to populate lvmcache with initial
- * list of PVs and VGs.
- */
+ if (!(read_flags & PROCESS_SKIP_SCAN))
lvmcache_label_scan(cmd);
- }
if (!get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
ret_max = ret;
@@ -4647,11 +4624,9 @@ int process_each_pv(struct cmd_context *cmd,
ret_max = ret;
/*
- * If the orphans lock was held, there shouldn't be missed devices. If
- * there were, we cannot clear the cache while holding the orphans lock
- * anyway.
+ * If the orphans lock was held, there shouldn't be missed devices.
*/
- if (orphans_locked)
+ if (read_flags & PROCESS_SKIP_ORPHAN_LOCK)
goto skip_missed;
/*
@@ -4678,12 +4653,7 @@ int process_each_pv(struct cmd_context *cmd,
log_verbose("Some PVs were not found in first search, retrying.");
- lvmcache_destroy(cmd, 0, 0);
- if (!lvmcache_init(cmd)) {
- log_error("Failed to initalize lvm cache.");
- ret_max = ECMD_FAILED;
- goto out;
- }
+ lvmcache_label_scan(cmd);
lvmcache_seed_infos_from_lvmetad(cmd);
ret = _process_pvs_in_vgs(cmd, read_flags, &all_vgnameids, &all_devices,
@@ -5514,25 +5484,16 @@ int pvcreate_each_device(struct cmd_context *cmd,
dm_list_add(&pp->arg_devices, &pd->list);
}
- /*
- * Clear the cache before acquiring the orphan lock. (Clearing the
- * cache with locks held is an error.) We want the orphan lock
- * acquired before process_each_pv. If the orphan lock is not held
- * when process_each_pv is called, then process_each_pv clears the
- * cache.
- */
- lvmcache_destroy(cmd, 1, 0);
-
- /*
- * If no prompts require a user response, this orphan lock is held
- * throughout, and pvcreate_each_device() returns with it held so that
- * vgcreate/vgextend use the PVs created here to add to a VG.
- */
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Can't get lock for orphan PVs.");
return 0;
}
+ /*
+ * Scan before calling process_each_pv so we can set up the PV args
+ * first. We can then skip the scan that would normally occur at the
+ * beginning of process_each_pv.
+ */
lvmcache_label_scan(cmd);
/*
@@ -5556,9 +5517,8 @@ int pvcreate_each_device(struct cmd_context *cmd,
* If it's added to arg_process but needs a prompt or force option, then
* a corresponding prompt entry is added to pp->prompts.
*/
- process_each_pv(cmd, 0, NULL, NULL, 1, 0, handle,
- pp->is_remove ? _pvremove_check_single : _pvcreate_check_single);
-
+ process_each_pv(cmd, 0, NULL, NULL, 1, PROCESS_SKIP_SCAN | PROCESS_SKIP_ORPHAN_LOCK,
+ handle, pp->is_remove ? _pvremove_check_single : _pvcreate_check_single);
/*
* A fatal error was found while checking.
*/
@@ -5639,9 +5599,11 @@ int pvcreate_each_device(struct cmd_context *cmd,
goto do_command;
/*
- * Prompts require asking the user, so release the orphans lock, ask
- * the questions, reacquire the orphans lock, verify that the PVs were
- * not used during the questions, then do the create steps.
+ * Prompts require asking the user and make take some time, during
+ * which we don't want to block other commands. So, release the lock
+ * to prevent blocking other commands while we wait. After a response
+ * from the user, reacquire the lock, verify that the PVs were not used
+ * during the wait, then do the create steps.
*/
unlock_vg(cmd, NULL, VG_ORPHANS);
@@ -5676,14 +5638,11 @@ int pvcreate_each_device(struct cmd_context *cmd,
}
/*
- * Clear the cache, reacquire the orphans write lock, then check again
- * that the devices can still be used. If the second loop finds them
- * changed, or can't find them any more, then they aren't used.
- * Clear the cache here before locking orphans, since it won't be
- * done by process_each_pv with orphans already locked.
+ * Reacquire the lock that was released above before waiting, then
+ * check again that the devices can still be used. If the second loop
+ * finds them changed, or can't find them any more, then they aren't
+ * used.
*/
- lvmcache_destroy(cmd, 1, 0);
-
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Can't get lock for orphan PVs.");
goto out;
@@ -5705,7 +5664,8 @@ int pvcreate_each_device(struct cmd_context *cmd,
*/
dm_list_splice(&pp->arg_confirm, &pp->arg_process);
- process_each_pv(cmd, 0, NULL, NULL, 1, 0, handle, _pv_confirm_single);
+ process_each_pv(cmd, 0, NULL, NULL, 1, PROCESS_SKIP_SCAN | PROCESS_SKIP_ORPHAN_LOCK,
+ handle, _pv_confirm_single);
dm_list_iterate_items(pd, &pp->arg_confirm)
log_error("Device %s %s.", pd->name, dev_cache_filtered_reason(pd->name));
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index aa35453..aa68f0f 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -239,7 +239,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
/* FIXME: Pass private struct through to all these functions */
/* and update in batch afterwards? */
- ret = process_each_pv(cmd, argc, argv, vg_name, 0, READ_FOR_UPDATE, handle, _vgreduce_single);
+ ret = process_each_pv(cmd, argc, argv, vg_name, 0, READ_FOR_UPDATE | PROCESS_SKIP_ORPHAN_LOCK, handle, _vgreduce_single);
unlock_vg(cmd, NULL, VG_ORPHANS);
goto out;
}
--
2.19.1

View File

@ -1,27 +0,0 @@
From 4e7c9c0e627d9814f0502488fb830fc47b6a71e0 Mon Sep 17 00:00:00 2001
Date: Wed, 11 Sep 2019 01:35:09 +0800
Subject: [PATCH] lvm2: revert to use label_read in lvmetad_pvscan_single
reason: In e3e5beec74ac0037917f5e9a2693c6ccb16debac of stable-2.02
branch, it reduce scan disk.It may lead to the metadate cache
outdate when send pv_found to lvmetad.Revert it by calling
label_read in lvmetad_pvscan_single
---
lib/cache/lvmetad.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 4b1b095..80aee66 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -2256,6 +2256,7 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
return 1;
}
+ label_read(dev);
if (!(info = lvmcache_info_from_pvid(dev->pvid, dev, 0))) {
log_print_unless_silent("No PV info found on %s for PVID %s.", dev_name(dev), dev->pvid);
if (!lvmetad_pv_gone_by_dev(dev))
--
2.19.1

View File

@ -1,24 +0,0 @@
From b79f1e176f013167ca9798efb55eaf048d64e042 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Thu, 4 Apr 2019 10:18:07 +0200
Subject: [PATCH] bcache: Fix memory leak
---
lib/device/bcache.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 7384a32..f64931f 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -411,6 +411,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
(unsigned long long)offset,
(unsigned long long)nbytes,
(unsigned long long)_last_byte_offset);
+ free(io);
return false;
}
--
1.8.3.1

View File

@ -1,29 +0,0 @@
From 09aafb61e31c3781530795057c87afaeb53a2bd4 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 25 Jun 2019 15:37:01 +0200
Subject: [PATCH] cov: release iterator on error path
---
lib/label/label.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/label/label.c b/lib/label/label.c
index 4f8e135..9a3f8df 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -866,8 +866,11 @@ int label_scan(struct cmd_context *cmd)
}
while ((dev = dev_iter_get(iter))) {
- if (!(devl = dm_zalloc(sizeof(*devl))))
+ if (!(devl = dm_zalloc(sizeof(*devl)))) {
+ log_error("Failed to allocated device list.");
+ dev_iter_destroy(iter);
return 0;
+ }
devl->dev = dev;
dm_list_add(&all_devs, &devl->list);
--
1.8.3.1

View File

@ -1,27 +0,0 @@
From 5cf1c61152bfd5f1eef7f49509a877090f4cc26f Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 25 Jun 2019 15:11:05 +0200
Subject: [PATCH] cov: check for socket_path being set
As we check for existince on entering path
let's ensure it's there also on exit path.
---
libdaemon/server/daemon-server.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 79b54d0..bc58f7b 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -693,7 +693,7 @@ void daemon_start(daemon_state s)
out:
/* If activated by systemd, do not unlink the socket - systemd takes care of that! */
if (!_systemd_activation && s.socket_fd >= 0)
- if (unlink(s.socket_path))
+ if (s.socket_path && unlink(s.socket_path))
perror("unlink error");
if (s.socket_fd >= 0)
--
1.8.3.1

View File

@ -1,31 +0,0 @@
From 8bea252a636ff0de2266c1ce760b3a6047f0ff2f Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 25 Jun 2019 15:08:10 +0200
Subject: [PATCH] cov: clearer condition check
Make the code more obvious.
---
lib/activate/activate.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index b3b8a25..561a965 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2478,7 +2478,12 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
* If vg_commit() did not happen, lvmcache_get_saved_vg_latest
* returns the old metadata which we use to resume LVs.
*/
- if (!lv && lvid_s) {
+ if (!lv) {
+ if (!lvid_s) {
+ log_error(INTERNAL_ERROR "Requested resume of unindentified resource!");
+ return 0;
+ }
+
lvid = (const union lvid *) lvid_s;
vgid = (const char *)lvid->id[0].uuid;
--
1.8.3.1

View File

@ -1,175 +0,0 @@
From 5d6bf1efb225b964bfff398277e68345acdac1d0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 25 Sep 2019 14:23:14 -0500
Subject: [PATCH 126/180] lvmetad: fix sync cache to lvmetad
error could be reproduced follow those steps:
#!/bin/bash
vgcreate vgtest /dev/sdb
lvcreate -L 100M -n lv1 vgtest
while :
do
service lvm2-lvmetad restart
vgs &
pvscan &
lvcreate -L 100M -n lv2 vgtest &
lvchange /dev/vgtest/lv1 --addtag xxxxx &
wait
if ! lvs|grep lv2;then
echo "err create"
break
fi
sleep 1
lvremove -y /dev/vgtest/lv2
lvchange /dev/vgtest/lv1 --deltag xxxxx
done
and then fail to create vgtest/lv2, actually lv2 was created, while
the metadata written on disk is replaced by lvchange. It could look
up lv2 by calling dmsetup table, while lvs could not.
This is because, when lvmetad restarted, several lvm commands update
token concurrently, when lvcreate recieve "token_mismatch", it cancle
communicating with lvmetad, which leads to that lvmetad cache is not
sync with the metadata on disk, then lv2 is not committed to lvmetad
cache. The metadata of vgtest which lvchange query from lvmetad is
out of date. After lvchange, it use the old metadata cover the new one.
This patch let lvm process update token synchronously, only one command
update lvmetad token at a time.
lvmetad_pvscan_single send the metadata on a pv by sending "pv_found"
to lvmetad, while the metadata maybe out of date after waiting for the
chance to update lvmetad token. Call label_read to read metadata again.
Token mismatch may lead to problems, increase log level.
Signed-off-by: wangjufeng<wangjufeng@huawei.com>
---
daemons/lvmetad/lvmetad-core.c | 19 +++++++++++++++----
lib/cache/lvmetad.c | 31 +++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 72473d7..c274880 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2669,6 +2669,7 @@ static response handler(daemon_state s, client_handle h, request r)
int pid;
int cache_lock = 0;
int info_lock = 0;
+ uint64_t timegap = 0;
rq = daemon_request_str(r, "request", "NONE");
token = daemon_request_str(r, "token", "NONE");
@@ -2711,9 +2712,19 @@ static response handler(daemon_state s, client_handle h, request r)
state->update_cmd);
} else if (prev_in_progress && this_in_progress) {
+ timegap = _monotonic_seconds() - state->update_begin;
+ if (timegap < state->update_timeout) {
+ pthread_mutex_unlock(&state->token_lock);
+ return daemon_reply_simple("token_updating",
+ "expected = %s", state->token,
+ "update_pid = " FMTd64, (int64_t)state->update_pid,
+ "reason = %s", "another command has populated the cache",
+ NULL);
+ }
+
/* Current update is cancelled and replaced by a new update */
- DEBUGLOG(state, "token_update replacing pid %d begin %llu len %d cmd %s",
+ WARN(state, "token_update replacing pid %d begin %llu len %d cmd %s",
state->update_pid,
(unsigned long long)state->update_begin,
(int)(_monotonic_seconds() - state->update_begin),
@@ -2726,7 +2737,7 @@ static response handler(daemon_state s, client_handle h, request r)
state->update_pid = pid;
strncpy(state->update_cmd, cmd, CMD_NAME_SIZE - 1);
- DEBUGLOG(state, "token_update begin %llu timeout %d pid %d cmd %s",
+ WARN(state, "token_update begin %llu timeout %d pid %d cmd %s",
(unsigned long long)state->update_begin,
state->update_timeout,
state->update_pid,
@@ -2737,7 +2748,7 @@ static response handler(daemon_state s, client_handle h, request r)
if (state->update_pid != pid) {
/* If a pid doing update was cancelled, ignore its token update at the end. */
- DEBUGLOG(state, "token_update ignored from cancelled update pid %d", pid);
+ WARN(state, "token_update ignored from cancelled update pid %d", pid);
pthread_mutex_unlock(&state->token_lock);
return daemon_reply_simple("token_mismatch",
@@ -2748,7 +2759,7 @@ static response handler(daemon_state s, client_handle h, request r)
NULL);
}
- DEBUGLOG(state, "token_update end len %d pid %d new token %s",
+ WARN(state, "token_update end len %d pid %d new token %s",
(int)(_monotonic_seconds() - state->update_begin),
state->update_pid, token);
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 291a2b2..8dc12a6 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -552,7 +552,12 @@ static int _token_update(int *replaced_update)
const char *reply_str;
int update_pid;
int ending_our_update;
+ unsigned int wait_sec = 0;
+ uint64_t now = 0, wait_start = 0;
+ wait_sec = (unsigned int)_lvmetad_update_timeout;
+ unsigned int delay_usec = 0;
+retry:
log_debug_lvmetad("Sending lvmetad token_update %s", _lvmetad_token);
reply = _lvmetad_send(NULL, "token_update", NULL);
@@ -568,6 +573,28 @@ static int _token_update(int *replaced_update)
update_pid = (int)daemon_reply_int(reply, "update_pid", 0);
reply_str = daemon_reply_str(reply, "response", "");
+ if (!strcmp(reply_str, "token_updating")) {
+ daemon_reply_destroy(reply);
+ if (!(now = _monotonic_seconds())) {
+ log_print_unless_silent("_monotonic_seconds error");
+ return 0;
+ }
+
+ if (!wait_start)
+ wait_start = now;
+
+ if (now - wait_start <= wait_sec) {
+ log_warn("lvmetad is being updated, retry for %u more seconds.",
+ wait_sec - (unsigned int)(now - wait_start));
+ delay_usec = 1000000 + lvm_even_rand(&_lvmetad_cmd->rand_seed, 1000000);
+ usleep(delay_usec);
+ goto retry;
+ }
+
+ log_print_unless_silent("Not using lvmetad after %u sec lvmetad_update_wait_time, no more try.", wait_sec);
+ return 0;
+ }
+
/*
* A mismatch can only happen when this command attempts to set the
* token to filter:<hash> at the end of its update, but the update has
@@ -578,11 +605,11 @@ static int _token_update(int *replaced_update)
ending_our_update = strcmp(_lvmetad_token, LVMETAD_TOKEN_UPDATE_IN_PROGRESS);
- log_debug_lvmetad("Received token update mismatch expected \"%s\" our token \"%s\" update_pid %d our pid %d",
+ log_print_unless_silent("Received token update mismatch expected \"%s\" our token \"%s\" update_pid %d our pid %d",
token_expected, _lvmetad_token, update_pid, getpid());
if (ending_our_update && (update_pid != getpid())) {
- log_warn("WARNING: lvmetad was updated by another command (pid %d).", update_pid);
+ log_print_unless_silent("WARNING: lvmetad was updated by another command (pid %d).", update_pid);
} else {
/*
* Shouldn't happen.
--
2.19.1

View File

@ -1,148 +0,0 @@
From 6d4f36c2c7f782af31eca7eca63310791a4f8e93 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 10 Apr 2019 12:50:53 +0200
Subject: [PATCH] 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.
---
daemons/lvmetad/lvmetad-core.c | 2 +-
daemons/lvmpolld/lvmpolld-core.c | 2 +-
libdaemon/server/daemon-server.c | 38 +++++++++++++++++++++++---------
libdaemon/server/daemon-server.h | 2 +-
4 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index c274880..fddec2e 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2964,7 +2964,7 @@ static void usage(const char *prog, FILE *file)
int main(int argc, char *argv[])
{
signed char opt;
- struct timeval timeout;
+ struct timespec timeout;
daemon_idle di = { .ptimeout = &timeout };
lvmetad_state ls = { .log_config = "" };
daemon_state s = {
diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c
index fd73272..f1056c3 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 83f56db..53bee39 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -87,7 +87,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;
}
@@ -96,7 +96,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;
}
}
@@ -561,6 +561,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
@@ -628,8 +630,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.
*/
@@ -643,22 +644,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, "%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 2b9ceac..e77ac20 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;
--
2.19.1

View File

@ -1,35 +0,0 @@
From b41b112a4bf5f674acd45f12ff4efe7fa0d1d8be Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 29 Apr 2019 13:43:36 +0200
Subject: [PATCH] libdaemon: ensure threads are reaped before checking shutdown
Since we are checking _shutdown_requested - we expect all threads
are finished - that is currently checked only by checking ->next ptr
being NULL - so this can be NULL only when _reap() function clears
out all already finished threads.
I'm finding this design quite problematic in its core - but as a
'trivial hotfix' - lets _reap() linked list before check for signal.
There is likely a large potentical for few races - but the windows is
very very small - since lvmetad has been already purged from upstream,
lets go with this hotfix.
---
libdaemon/server/daemon-server.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 8534b79..79b54d0 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -655,6 +655,7 @@ void daemon_start(daemon_state s)
FD_ZERO(&in);
FD_SET(s.socket_fd, &in);
+ _reap(s, 0);
sigprocmask(SIG_SETMASK, &new_set, NULL);
if (_shutdown_requested && !s.threads->next) {
sigprocmask(SIG_SETMASK, &old_set, NULL);
--
1.8.3.1

View File

@ -1,63 +0,0 @@
From 61358d92cbf202dbb483d63a63d5adf0463bb934 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 25 Sep 2019 17:22:49 +0200
Subject: [PATCH 127/180] lvmetad: fix timeout on shutdown
When lvmetad is going to be shutdown - there were 2 issue:
If there was endless stream of command contacting lvmetad - the process
would never finish - so now when we recieved SIGTERM - we are no longer
accepting new connections and we just wait till the existing ones are
finished.
2nd. issue is that actually when we are waiting for finish of all client
threads - we basically want an usleep() and check if all threads
are already finished - proper solution would be to singal from a thread
there is some work to do for master thread - but that would be a bigger
change and since lvmetad is no longer developed - keep the change
minimal and just use pselect() as our '1sec.' sleeping call once
we are in 'shutdown' mode.
Reported-by: wangjufeng@huawei.com
---
libdaemon/server/daemon-server.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 71f7fae..90bf055 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -89,6 +89,13 @@ static int _is_idle(daemon_state s)
static struct timespec *_get_timeout(daemon_state s)
{
+ static struct timespec _tm = { 0 };
+
+ if (_shutdown_requested) {
+ _tm.tv_sec = 1;
+ return &_tm;
+ }
+
return s.idle ? s.idle->ptimeout : NULL;
}
@@ -506,7 +513,7 @@ static int _handle_connect(daemon_state s)
socklen_t sl = sizeof(sockaddr);
client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl);
- if (client.socket_fd < 0) {
+ if (client.socket_fd < 0 || _shutdown_requested) {
if (errno != EAGAIN || !_shutdown_requested)
ERROR(&s, "Failed to accept connection: %s.", strerror(errno));
return 0;
@@ -671,7 +678,7 @@ void daemon_start(daemon_state s)
continue;
}
- if (FD_ISSET(s.socket_fd, &in)) {
+ if (!_shutdown_requested && FD_ISSET(s.socket_fd, &in)) {
timeout_count = 0;
_handle_connect(s);
}
--
2.19.1

View File

@ -1,84 +0,0 @@
From 67bdae069751e4779e738283e3d8a5873622bfc0 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 1 Nov 2019 20:25:39 +0100
Subject: [PATCH 169/180] cov: missing checks of syscalls
Check for sigaction,sigprocmask,pthread_sigmask errors
---
daemons/clvmd/clvmd.c | 10 ++++++----
libdaemon/server/daemon-server.c | 9 ++++++---
tools/toollib.c | 3 ++-
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index 829c5e5..e1d8a79 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -887,7 +887,8 @@ static void main_loop(int cmd_timeout)
sigemptyset(&ss);
sigaddset(&ss, SIGINT);
sigaddset(&ss, SIGTERM);
- pthread_sigmask(SIG_UNBLOCK, &ss, NULL);
+ if (pthread_sigmask(SIG_UNBLOCK, &ss, NULL))
+ log_warn("WARNING: Failed to unblock SIGCHLD.");
/* Main loop */
while (!quit) {
fd_set in;
@@ -1731,11 +1732,12 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
SIGUSR2 (kills subthreads) */
sigemptyset(&ss);
sigaddset(&ss, SIGUSR1);
- pthread_sigmask(SIG_BLOCK, &ss, NULL);
-
+ if (pthread_sigmask(SIG_BLOCK, &ss, NULL))
+ log_warn("WARNING: Failed to block SIGUSR1.");
sigdelset(&ss, SIGUSR1);
sigaddset(&ss, SIGUSR2);
- pthread_sigmask(SIG_UNBLOCK, &ss, NULL);
+ if (pthread_sigmask(SIG_UNBLOCK, &ss, NULL))
+ log_warn("WARNING: Failed to unblock SIGUSR2.");
/* Loop around doing PRE and POST functions until the client goes away */
while (!client->bits.localsock.finished) {
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 62f403a..51e5866 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -663,14 +663,17 @@ void daemon_start(daemon_state s)
FD_SET(s.socket_fd, &in);
_reap(s, 0);
- sigprocmask(SIG_SETMASK, &new_set, NULL);
+ if (sigprocmask(SIG_SETMASK, &new_set, NULL))
+ perror("sigprocmask error");
if (_shutdown_requested && !s.threads->next) {
- sigprocmask(SIG_SETMASK, &old_set, NULL);
+ if (sigprocmask(SIG_SETMASK, &old_set, NULL))
+ perror("sigprocmask error");
INFO(&s, "%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 (sigprocmask(SIG_SETMASK, &old_set, NULL))
+ perror("sigprocmask error");
if (ret < 0) {
if (errno != EINTR && errno != EAGAIN &&
diff --git a/tools/toollib.c b/tools/toollib.c
index 42179d9..0c1c095 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -59,7 +59,8 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
log_verbose("Forking background process from command: %s", cmd->cmd_line);
- sigaction(SIGCHLD, &act, NULL);
+ if (sigaction(SIGCHLD, &act, NULL))
+ log_warn("WARNING: Failed to set SIGCHLD action.");
if (!skip_lvm)
if (!sync_local_dev_names(cmd)) { /* Flush ops and reset dm cookie */
--
1.8.3.1

View File

@ -1,26 +0,0 @@
From f90c3d69cedf94fa094bc71cc98376d58d970223 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 1 Nov 2019 21:01:51 +0100
Subject: [PATCH 170/180] cov: ensure read_ahead is available
Make sure read_ahead pointer is not NULL when quering for RA.
---
lib/activate/dev_manager.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index d281b60..4e7a631 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -258,7 +258,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
with_open_count, with_flush, 0)))
return_0;
- if (with_read_ahead && dminfo->exists) {
+ if (with_read_ahead && read_ahead && dminfo->exists) {
if (!dm_task_get_read_ahead(dmt, read_ahead))
goto_out;
} else if (read_ahead)
--
2.19.1

View File

@ -1,33 +0,0 @@
From 34bde8b6c7e517239a05334683a09f2b5075fdcc Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 8 Nov 2019 12:51:48 +0100
Subject: [PATCH 171/180] lvmcache: free resource on error path
Free allocated svg on error path.
Also explicitely ignore dm_strncpy() result.
(We know it will end with failure here.)
---
lib/cache/lvmcache.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 9890325..c12ec2b 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -325,10 +325,12 @@ void lvmcache_save_vg(struct volume_group *vg, int precommitted)
dm_list_init(&svg->saved_vg_to_free);
- dm_strncpy(svg->vgid, (const char *)vg->id.uuid, sizeof(svg->vgid));
+ /* Ignore result code, size we intentionally short-cut & pad with 0 */
+ (void) dm_strncpy(svg->vgid, (const char *)vg->id.uuid, sizeof(svg->vgid));
if (!dm_hash_insert(_saved_vg_hash, svg->vgid, svg)) {
log_error("lvmcache: failed to insert saved_vg %s", svg->vgid);
+ dm_free(svg);
return;
}
} else {
--
1.8.3.1

View File

@ -1,27 +0,0 @@
From bbdcdc12b2240e00f6ab8ff105e954629412b234 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 8 Nov 2019 13:10:49 +0100
Subject: [PATCH 173/180] daemons: check for non-zero thread_id
Do not call pthread_join if thread_id would be 0.
---
libdaemon/server/daemon-server.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index aa9ff2a..9408440 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -560,7 +560,8 @@ static void _reap(daemon_state s, int waiting)
while (ts) {
if (waiting || !ts->active) {
- if ((errno = pthread_join(ts->client.thread_id, &rv)))
+ if (ts->client.thread_id &&
+ (errno = pthread_join(ts->client.thread_id, &rv)))
ERROR(&s, "pthread_join failed: %s", strerror(errno));
last->next = ts->next;
dm_free(ts);
--
1.8.3.1

View File

@ -1,28 +0,0 @@
From 7517074585ca042c0bd06481a359d617fabdc032 Mon Sep 17 00:00:00 2001
From: wangjufeng <wangjufeng@huawei.com>
Date: Wed, 20 Nov 2019 17:37:03 +0800
Subject: [PATCH] revert "label_scan: remove extra label scan and read for
orphan PVs"
In commit 79c4971210a6337563ffa2fca08fb636423d93d4, it removed the
modification of *consistent in vg_read_orphans(), it will lead to pvs
--readonly return failure.
---
lib/metadata/metadata.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 237e57b..35f35bd 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3426,6 +3426,7 @@ struct volume_group *vg_read_orphans(struct cmd_context *cmd,
if (!lvmcache_foreach_pv(vginfo, _vg_read_orphan_pv, &baton))
return_NULL;
+ *consistent = 1;
return vg;
}
--
2.19.1

View File

@ -1,32 +0,0 @@
From 00e750b9e645f7a7fab9ce464419c72bd8535df0 Mon Sep 17 00:00:00 2001
From: wangjufeng <wangjufeng@huawei.com>
Date: Wed, 5 Feb 2020 13:39:39 +0800
Subject: [PATCH] lvmetad: fix heap memory leak
When lvmetad make reponse for clent request, it should add all
new chunk for the dm_config_tree of reponse, not the cft of
global s->vgid_to_metadata, or, it will keep malloc new chunk
for s->vgid_to_metadata, that will lead to RSS memory keep
growing.
Signed-off-by: wangjufeng <wangjufeng@huawei.com>
---
daemons/lvmetad/lvmetad-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index ef43b47..659d85c 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -730,7 +730,7 @@ static response vg_lookup(lvmetad_state *s, request r)
if (!(res.cft->root = n = dm_config_create_node(res.cft, "response")))
goto nomem_un;
- if (!(n->v = dm_config_create_value(cft)))
+ if (!(n->v = dm_config_create_value(res.cft)))
goto nomem_un;
n->parent = res.cft->root;
--
1.8.3.1

View File

@ -1,28 +0,0 @@
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index a1ab41a..e743a58 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -1467,7 +1467,9 @@ int lvmetad_get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids)
return 0;
}
- vgnl->vgid = dm_pool_strdup(cmd->mem, (char *)&vgid);
+ char vgid_buffer[ID_LEN+1] = {0x0};
+ memcpy(vgid_buffer, vgid.uuid, ID_LEN);
+ vgnl->vgid = dm_pool_strdup(cmd->mem, vgid_buffer);
vgnl->vg_name = dm_pool_strdup(cmd->mem, vg_name);
if (!vgnl->vgid || !vgnl->vg_name) {
diff --git a/tools/command.c b/tools/command.c
index 377d03f..f2a2722 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1364,7 +1364,7 @@ static int _copy_line(char *line, int max_line, int *position)
memset(line, 0, max_line);
- while (1) {
+ while ( p < strlen(_command_input) ) {
line[i] = _command_input[p];
i++;
p++;

Binary file not shown.

BIN
LVM2.2.03.09.tgz Normal file

Binary file not shown.

111
lvm2.spec
View File

@ -42,75 +42,22 @@
%global dlm_version 4.0.6-2
Name: lvm2
Version: 2.02.181
Release: 9
Version: 2.03.09
Release: 1
Epoch: 8
Summary: Tools for logical volume management
License: GPLv2 and LGPLv2
URL: http://sourceware.org/lvm2
Source0: ftp://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz
Patch0: 0000-lvm2-set-default-preferred_names.patch
Patch1: 0001-lvm2-lvmetad-timeout.patch
Patch2: 0002-mirrors-fix-read_only_volume_list.patch
Patch3: 0003-bcache-reduce-MAX_IO-to-256.patch
Patch4: 0004-lvmetad-fix-pvs-for-many-devices.patch
Patch5: 0005-dmeventd-lvm2-plugin-uses-envvar-registry.patch
Patch6: 0006-metadata-prevent-writing-beyond-metadata-area.patch
Patch7: 0007-libdm-stats-move-no-regions-warning-after-dm_stats_l.patch
Patch8: 0008-dmsetup-fix-stats-report-command-output.patch
Patch9: 0009-io-use-sync-io-if-aio-fails.patch
Patch10: 0010-bcache-sync-io-fixes.patch
Patch11: 0011-lvmanip-uninitialized-members-in-struct-pv_list-10.patch
Patch12: 0012-apply-obtain_device_list_from_udev-to-all-libudev-us.patch
Patch13: 0013-cov-dmstats-check-for-failing-malloc.patch
Patch14: 0014-cov-ensure-vars-are-set.patch
Patch15: 0015-libdm-add-memory-barrier.patch
Patch16: 0016-stats-fix-error-path-when-region-is-NULL.patch
Patch17: 0017-stats-initilize-regions-to-NULL.patch
Patch18: 0018-dmsetup-Fix-multi-line-concise-table-parsing.patch
Patch19: 0019-Remove-VG-lock-ordering-check.patch
Patch20: 0020-Fix-use-of-orphan-lock-in-commands.patch
Patch21: 0021-metadata-remove-an-unused-and-incorrect-overflow-che.patch
Patch22: 0022-cov-dmeventd-plugin-fix-memleak.patch
Patch23: 0023-cov-fix-missing-null-allocation-check.patch
Patch24: 0024-cov-add-check-for-positive-value.patch
Patch25: 0025-cov-fix-failing-filter-initialization.patch
Patch26: 0026-cov-check-dev_close_immediate.patch
Patch27: 0027-cov-make-sure-label-scans-valid-lvinfo.patch
Patch28: 0028-cov-add-missing-error-path-check-for-label_scan_open.patch
Patch29: 0029-cov-pvscan-ensure-sigle_devs-list-is-always-initiali.patch
Patch30: 0030-fix-cov-missed-return-value-test.patch
Patch31: 0031-cov-trace-failing-pthread_kill.patch
Patch32: 0032-cov-avoid-unsing-unchecked-label_scan_open.patch
Patch33: 0033-lvmlockd-fix-missing-LV-lock-for-lvconvert-repair.patch
Patch34: 0034-lvconvert-ensure-proper-init-of-pv_list.patch
Patch35: 0035-dmeventd-unlock-lvm2-lock-on-error-path.patch
Patch36: 0036-mangenerator-check-strdup-was-successfull.patch
Patch37: 0037-cov-ensure-lock_type-is-not-NULL.patch
Patch38: 0038-Remove-checking-for-locked-VGs.patch
Patch39: 0039-lvm2-default-allow-changes-with-duplicate-pvs.patch
Patch40: 0040-lvm2-revert-to-use-label_read-in-lvmetad_pvscan_sing.patch
Patch41: 0041-bcache-Fix-memory-leak.patch
Patch42: 0042-cov-release-iterator-on-error-path.patch
Patch43: 0043-cov-check-result-of-dev_read_bytes.patch
Patch44: 0044-cov-check-for-socket_path-being-set.patch
Patch45: 0045-cov-clearer-condition-check.patch
Patch46: 0046-lvmetad-fix-sync-cache-to-lvmetad.patch
Patch47: 0047-libdaemon-use-pselect-to-avoid-condition-checking-ra.patch
Patch48: 0048-libdaemon-ensure-threads-are-reaped-before-checking-.patch
Patch49: 0049-lvmetad-fix-timeout-on-shutdown.patch
Patch50: 0050-devs-check-for-no-dev-when-dropping-aliases.patch
Patch51: 0051-cov-missing-checks-of-syscalls.patch
Patch52: 0052-cov-ensure-read_ahead-is-available.patch
Patch53: 0053-lvmcache-free-resource-on-error-path.patch
Patch54: 0054-daemons-check-for-non-zero-thread_id.patch
Patch55: 0055-revert-label_scan-remove-extra-label-scan-and-read-f.patch
Patch56: 0056-lvmetad-fix-heap-memory-leak.patch
Patch57: 0057-bugfix-lvm2-add-SSD.patch
Patch58: 0058-bugfix-add-timeout-when-fail-to-wait-udev.patch
Patch59: 0059-bugfix-fix-the-code-maybe-lead-to-buffer-over-bound-access.patch
Patch60: 0060-enhancement-modify-default-log-level-to-error-level.patch
Patch61: 0061-enhancement-add-dfx-log.patch
Source0: https://sourceware.org/pub/lvm2/releases/LVM2.2.03.09.tgz
Patch1: 0001-lvm2-set-default-preferred_names.patch
Patch2: 0002-lvm2-default-allow-changes-with-duplicate-pvs.patch
Patch3: 0003-cov-check-result-of-dev_read_bytes.patch
Patch4: 0004-devs-check-for-no-dev-when-dropping-aliases.patch
Patch5: 0005-bugfix-lvm2-add-SSD.patch
Patch6: 0006-bugfix-add-timeout-when-fail-to-wait-udev.patch
Patch7: 0007-bugfix-fix-the-code-maybe-lead-to-buffer-over-bound-access.patch
Patch8: 0008-enhancement-modify-default-log-level-to-error-level.patch
Patch9: 0009-enhancement-add-dfx-log.patch
BuildRequires: gcc
BuildRequires: gcc-c++
@ -310,8 +257,6 @@ if [ "$1" = "1" ] ; then
systemctl enable lvm2-monitor.service
systemctl start lvm2-monitor.service >/dev/null 2>&1 || :
fi
%systemd_post lvm2-lvmetad.socket
systemctl start lvm2-lvmetad.socket >/dev/null 2>&1 || :
%systemd_post lvm2-lvmpolld.socket
systemctl enable lvm2-lvmpolld.socket
@ -319,12 +264,10 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || :
%preun
%systemd_preun blk-availability.service lvm2-monitor.service
%systemd_preun lvm2-lvmetad.service lvm2-lvmetad.socket
%systemd_preun lvm2-lvmpolld.service lvm2-lvmpolld.socket
%postun
%systemd_postun lvm2-monitor.service
%systemd_postun_with_restart lvm2-lvmetad.service
%systemd_postun_with_restart lvm2-lvmpolld.service
/sbin/ldconfig
@ -351,13 +294,11 @@ fi
%if %{use_lockd_dlm} || %{use_lockd_sanlock}
%post lockd
%systemd_post lvm2-lvmlockd.service lvm2-lvmlocking.service
%systemd_post lvmlockd.service lvmlocks.service
%preun lockd
%systemd_preun lvm2-lvmlockd.service lvm2-lvmlocking.service
%systemd_preun lvmlockd.service lvmlocks.service
%postun lockd
%systemd_postun lvm2-lvmlockd.service lvm2-lvmlocking.service
%systemd_postun lvmlockd.service lvmlocks.service
%endif
%if %{use_cluster}
@ -403,12 +344,9 @@ fi
%defattr(555,root,root,-)
%{_sbindir}/fsadm
%{_sbindir}/lvm
%{_sbindir}/lvmconf
%{_sbindir}/lvmconfig
%{_sbindir}/lvmdump
%{_sbindir}/lvmetad
%{_sbindir}/lvmpolld
%{_libdir}/liblvm2app.so.*
%{_libdir}/liblvm2cmd.so.*
%{_libdir}/libdevmapper-event-lvm2.so.*
@ -455,8 +393,6 @@ fi
%{_unitdir}/blk-availability.service
%{_unitdir}/lvm2-monitor.service
%attr(555, -, -) %{_prefix}/lib/systemd/system-generators/lvm2-activation-generator
%{_unitdir}/lvm2-lvmetad.socket
%{_unitdir}/lvm2-lvmetad.service
%{_unitdir}/lvm2-pvscan@.service
%{_unitdir}/lvm2-lvmpolld.socket
%{_unitdir}/lvm2-lvmpolld.service
@ -486,16 +422,13 @@ fi
%files devel
%defattr(444,root,root,-)
%{_libdir}/liblvm2app.so
%{_libdir}/liblvm2cmd.so
%{_libdir}/libdevmapper-event-lvm2.so
%{_libdir}/libdevmapper.so
%{_libdir}/libdevmapper-event.so
%{_includedir}/lvm2app.h
%{_includedir}/lvm2cmd.h
%{_includedir}/libdevmapper.h
%{_includedir}/libdevmapper-event.h
%{_libdir}/pkgconfig/lvm2app.pc
%{_libdir}/pkgconfig/devmapper.pc
%{_libdir}/pkgconfig/devmapper-event.pc
@ -504,17 +437,13 @@ fi
%{_mandir}/man7/*
%{_mandir}/man8/*
%files -n python3-lvm-deprecated
%{python3_sitearch}/*.so
%{python3_sitearch}/*.egg-info
%if %{use_lockd_dlm} || %{use_lockd_sanlock}
%files lockd
%defattr(444,root,root,-)
%%attr(555, -, -) %{_sbindir}/lvmlockd
%%attr(555, -, -) %{_sbindir}/lvmlockctl
%{_unitdir}/lvm2-lvmlockd.service
%{_unitdir}/lvm2-lvmlocking.service
%{_unitdir}/lvmlockd.service
%{_unitdir}/lvmlocks.service
%endif
%if %{use_cluster}
@ -551,7 +480,11 @@ fi
%changelog
* Thur Jul 2 2020 Wu Bo <wubo009@163.com> - 8:2.02.181-9
* Thu Jul 14 2020 wuguanghao <wuguanghao3@huawei.com> - 8:2.03.09-1
- update lvm2 version to 2.03.09-1
* Thu Jul 2 2020 Wu Bo <wubo009@163.com> - 8:2.02.181-9
- rebuild package
* Fri Mar 20 2020 hy-euler <eulerstoragemt@huawei.com> - 8:2.02.181-8