Package init

This commit is contained in:
overweight 2019-09-30 11:03:04 -04:00
commit 982b051619
47 changed files with 3889 additions and 0 deletions

View File

@ -0,0 +1,30 @@
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
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -106,7 +106,7 @@ devices {
# Example
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
#
- # This configuration option does not have a default value defined.
+ preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
# 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
--- 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"
"#\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,
+cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#S^/dev/mpath/#S^/dev/mapper/mpath#S^/dev/[hs]d", vsn(1, 2, 19), NULL, 0, NULL,
"Select which path name to display for a block device.\n"
"If multiple path names exist for a block device, and LVM needs to\n"
"display a name for the device, the path names are matched against\n"

View File

@ -0,0 +1,16 @@
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

@ -0,0 +1,34 @@
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

@ -0,0 +1,39 @@
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

@ -0,0 +1,118 @@
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

@ -0,0 +1,113 @@
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

@ -0,0 +1,336 @@
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,45 @@
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

@ -0,0 +1,48 @@
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

@ -0,0 +1,216 @@
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

@ -0,0 +1,126 @@
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

@ -0,0 +1,37 @@
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

@ -0,0 +1,34 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,32 @@
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

@ -0,0 +1,43 @@
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

@ -0,0 +1,51 @@
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

@ -0,0 +1,29 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,194 @@
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

@ -0,0 +1,223 @@
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

@ -0,0 +1,54 @@
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

@ -0,0 +1,41 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,30 @@
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

@ -0,0 +1,43 @@
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

@ -0,0 +1,53 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,29 @@
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

@ -0,0 +1,34 @@
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

@ -0,0 +1,65 @@
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

@ -0,0 +1,44 @@
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

@ -0,0 +1,29 @@
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

@ -0,0 +1,48 @@
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

@ -0,0 +1,25 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,27 @@
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

@ -0,0 +1,43 @@
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

@ -0,0 +1,411 @@
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

@ -0,0 +1,30 @@
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
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -311,7 +311,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.
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index d9e19d9..894b979 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -45,7 +45,7 @@
#define DEFAULT_DATA_ALIGNMENT_DETECTION 1
#define DEFAULT_ISSUE_DISCARDS 0
#define DEFAULT_PV_MIN_SIZE_KB 2048
-#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 0
+#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 1
#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so"
#define DEFAULT_ERROR_WHEN_FULL 0

View File

@ -0,0 +1,26 @@
From 0f30a9d3c2619cbaba323524f7aa9c9c4b01bcdd 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
DTS/AR:
reason:
---
conf/example.conf.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 32267e7..1f7b264 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -149,6 +149,7 @@ devices {
# global_filter are not opened by LVM.
# This configuration option has an automatic default value.
# global_filter = [ "a|.*/|" ]
+ types = [ "hio", 16 ]
# Configuration option devices/cache_dir.
# Directory in which to store the device cache file.
--
1.8.3.1

View File

@ -0,0 +1,110 @@
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:
static int _create_one_device(const char *name, const char *file)
{
int r = 0;
+ int udev_wait_r = 1;
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)
out:
if (!_udev_cookie)
- (void) dm_udev_wait(cookie);
+ udev_wait_r = dm_udev_wait(cookie);
if (r && _switches[VERBOSE_ARG])
r = _display_info(dmt);
dm_task_destroy(dmt);
+ if(!udev_wait_r)
+ return 0;
+
return r;
}
@@ -1430,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;
+ int udev_wait_r = 1;
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
out:
if (!_udev_cookie)
- (void) dm_udev_wait(cookie);
+ udev_wait_r = dm_udev_wait(cookie);
dm_task_destroy(dmt);
+ if (!udev_wait_r)
+ return 0;
+
return r;
}
@@ -1997,6 +2005,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;
+ int udev_wait_r = 1;
struct dm_task *dmt;
@@ -2056,13 +2065,16 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
out:
if (!_udev_cookie && udev_wait_flag)
- (void) dm_udev_wait(cookie);
+ udev_wait_r = dm_udev_wait(cookie);
if (r && display && _switches[VERBOSE_ARG])
r = _display_info(dmt);
dm_task_destroy(dmt);
+ if(!udev_wait_r)
+ return 0;
+
return r;
}

View File

@ -0,0 +1,28 @@
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++;

View File

@ -0,0 +1,25 @@
From 2a0100ad8fd91ff367948fb79d7a2430380e1cb8 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Tue, 19 Mar 2019 15:44:17 +0800
Subject: [PATCH 1/2] modify default log level to error level
---
conf/example.conf.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 1f7b264..9a465ca 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -585,7 +585,7 @@ log {
# The level of log messages that are sent to the log file or syslog.
# There are 6 syslog-like log levels currently in use: 2 to 7 inclusive.
# 7 is the most verbose (LOG_DEBUG).
- level = 0
+ level = 3
# Configuration option log/indent.
# Indent messages according to their severity.
--
2.19.1

View File

@ -0,0 +1,252 @@
From 2f257461191b97e47a716f0cd0374e174041ddef 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
---
conf/example.conf.in | 5 +++++
lib/commands/toolcontext.c | 16 ++++++++++++++++
lib/commands/toolcontext.h | 4 ++++
lib/config/config_settings.h | 5 +++++
lib/log/log.c | 21 +++++++++++++++++++--
lib/log/log.h | 4 +++-
lib/misc/lvm-globals.c | 11 +++++++++++
lib/misc/lvm-globals.h | 2 ++
tools/lvmcmdline.c | 1 +
9 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 9a465ca..4f2abae 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -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
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -49,6 +49,8 @@
static const size_t _linebuffer_size = 4096;
+char *global_cmdline = NULL;
+
/*
* Copy the input string, removing invalid characters.
*/
@@ -314,6 +316,9 @@ static void _init_logging(struct cmd_context *cmd)
find_config_tree_bool(cmd, log_silent_CFG, NULL);
init_silent(cmd->default_settings.silent);
+ cmd->default_settings.log_unless_silent = find_config_tree_bool(cmd, log_unless_silent_CFG, NULL);
+ init_log_unless_silent(cmd->default_settings.log_unless_silent);
+
/* 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)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
_destroy_filters(cmd);
+ set_global_cmdline(NULL);
if (cmd->mem)
dm_pool_destroy(cmd->mem);
dev_cache_exit();
@@ -2293,3 +2299,13 @@ void destroy_toolcontext(struct cmd_context *cmd)
fin_syslog();
reset_lvm_errno(0);
}
+
+char *get_global_cmdline()
+{
+ return global_cmdline;
+}
+
+void set_global_cmdline(char *cmdline)
+{
+ global_cmdline = cmdline;
+}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index da5d582..345dcc8 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -48,6 +48,7 @@ struct config_info {
mode_t umask;
char unit_type;
char _padding[1];
+ int log_unless_silent;
};
struct dm_config_tree;
@@ -267,4 +268,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);
+char *get_global_cmdline();
+
+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
--- 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,
"There are 6 syslog-like log levels currently in use: 2 to 7 inclusive.\n"
"7 is the most verbose (LOG_DEBUG).\n")
+cfg(log_unless_silent_CFG, "log_unless_silent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 178), NULL, 0, NULL,
+ "When the level of log messages is set as 2 or 3, set log_unless_silent\n"
+ "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,
"Indent messages according to their severity.\n")
diff --git a/lib/log/log.c b/lib/log/log.c
index 79fbd7a..d34e160 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 <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
const char *trformat; /* Translated format string */
char *newbuf;
int use_stderr = log_stderr(level);
+ int force_syslog = (level & _LOG_IMPORTANT_TO_SYSLOG) ? 1 : 0;
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
struct dm_report *orig_report;
int logged_via_report = 0;
+ static int printcmdline = 1;
level = log_level(level);
+ force_syslog = (level!=0 && get_log_unless_silent()) ? force_syslog : 0;
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
va_end(ap);
}
- if ((level > debug_level()) ||
- (level >= _LOG_DEBUG && !debug_class_is_logged(dm_errno_or_class))) {
+ if (!force_syslog && ((level > debug_level()) ||
+ (level >= _LOG_DEBUG && !debug_class_is_logged(dm_errno_or_class)))) {
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
if (_syslog && (_log_while_suspended || !critical_section())) {
va_copy(ap, orig_ap);
+
+ if (level <= _LOG_WARN && printcmdline) {
+ char *cmdline = get_global_cmdline();
+ if (cmdline) {
+ printcmdline = 0;
+ char msg_addcmd[4096] = {0};
+
+ snprintf(msg_addcmd, sizeof(msg_addcmd),
+ "ppid=%lu, cmdline:%s", getppid(), cmdline);
+ syslog(level, "%s", msg_addcmd);
+ }
+ }
+
vsyslog(level, trformat, ap);
va_end(ap);
}
diff --git a/lib/log/log.h b/lib/log/log.h
index 256fed0..7c22859 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -50,6 +50,8 @@
#define _LOG_STDERR 0x0080 /* force things to go to stderr, even if loglevel would make them go to stdout */
#define _LOG_ONCE 0x0100 /* downgrade to NOTICE if this has been already logged */
#define _LOG_BYPASS_REPORT 0x0200 /* do not log through report even if report available */
+#define _LOG_IMPORTANT_TO_SYSLOG 0x10000 /*log to syslog even if loglevel number is bigger than _debug_level configuration,
+ unless _debug_level is 0*/
#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 @@
#define log_very_verbose(args...) log_info(args)
#define log_verbose(args...) log_notice(args)
#define log_print(args...) LOG_LINE(_LOG_WARN, args)
-#define log_print_unless_silent(args...) LOG_LINE(silent_mode() ? _LOG_NOTICE : _LOG_WARN, args)
+#define log_print_unless_silent(args...) LOG_LINE(silent_mode() ? _LOG_NOTICE : _LOG_WARN | _LOG_IMPORTANT_TO_SYSLOG, args)
#define log_error(args...) log_err(args)
#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
--- 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 _log_unless_silent = 1;
void init_verbose(int level)
{
_verbose_level = level;
}
+void init_log_unless_silent(int unless_silent)
+{
+ _log_unless_silent = unless_silent;
+}
+
+int get_log_unless_silent(void)
+{
+ return _log_unless_silent;
+}
+
void init_silent(int silent)
{
_silent = silent;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index f985cfa..3374d0d 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);
+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
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2807,6 +2807,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;
+ set_global_cmdline(cmd->cmd_line);
/* Look up command - will be NULL if not recognised */
if (!(cmd->cname = _find_command_name(cmd->name)))
--
2.19.1

BIN
LVM2.2.02.181.tgz Normal file

Binary file not shown.

538
lvm2.spec Normal file
View File

@ -0,0 +1,538 @@
%global use_cluster 1
%global use_cmirror 1
%global use_lockd_sanlock 1
%global use_lockd_dlm 1
%ifnarch i686 x86_64
%global use_cluster 0
%global use_cmirror 0
%global use_lockd_dlm 0
%endif
%ifnarch x86_64 aarch64
%global use_lockd_sanlock 0
%endif
%if %{use_cluster}
%global configure_cluster --with-cluster=internal --with-clvmd=corosync
%if %{use_cmirror}
%global configure_cmirror --enable-cmirrord
%endif
%else
%global configure_cluster --with-cluster=internal --with-clvmd=none
%endif
%if %{use_lockd_dlm}
%global configure_lockd_dlm --enable-lvmlockd-dlm
%endif
%if %{use_lockd_sanlock}
%global configure_lockd_sanlock --enable-lvmlockd-sanlock
%endif
%global libselinux_version 1.30.19-4
%global persistent_data_version 0.7.0-0.1.rc6
%global sanlock_version 3.3.0-2
%global device_mapper_version 1.02.150
%global systemd_version 189-3
%global dracut_version 002-18
%global util_linux_version 2.24
%global bash_version 4.0
%global corosync_version 1.99.9-1
%global resource_agents_version 3.9.5-12
%global dlm_version 4.0.6-2
Name: lvm2
Version: 2.02.181
Release: 2
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
Patch0000: 0000-lvm2-set-default-preferred_names.patch
Patch0001: 0001-lvm2-lvmetad-timeout.patch
Patch6000: 6000-mirrors-fix-read_only_volume_list.patch
Patch6001: 6001-bcache-reduce-MAX_IO-to-256.patch
Patch6002: 6002-lvmetad-fix-pvs-for-many-devices.patch
Patch6003: 6003-dmeventd-lvm2-plugin-uses-envvar-registry.patch
Patch6004: 6004-metadata-prevent-writing-beyond-metadata-area.patch
Patch6005: 6005-libdm-stats-move-no-regions-warning-after-dm_stats_l.patch
Patch6006: 6006-dmsetup-fix-stats-report-command-output.patch
Patch6007: 6007-io-use-sync-io-if-aio-fails.patch
Patch6008: 6008-bcache-sync-io-fixes.patch
Patch6009: 6009-lvmanip-uninitialized-members-in-struct-pv_list-10.patch
Patch6010: 6010-apply-obtain_device_list_from_udev-to-all-libudev-us.patch
Patch6011: 6011-cov-dmstats-check-for-failing-malloc.patch
Patch6012: 6012-cov-ensure-vars-are-set.patch
Patch6013: 6013-libdm-add-memory-barrier.patch
Patch6014: 6014-stats-fix-error-path-when-region-is-NULL.patch
Patch6015: 6015-stats-initilize-regions-to-NULL.patch
Patch6016: 6016-dmsetup-Fix-multi-line-concise-table-parsing.patch
Patch6017: 6017-Remove-VG-lock-ordering-check.patch
Patch6018: 6018-Fix-use-of-orphan-lock-in-commands.patch
Patch6019: 6019-metadata-remove-an-unused-and-incorrect-overflow-che.patch
Patch6020: 6020-cov-dmeventd-plugin-fix-memleak.patch
Patch6021: 6021-cov-fix-missing-null-allocation-check.patch
Patch6022: 6022-cov-add-check-for-positive-value.patch
Patch6023: 6023-cov-fix-failing-filter-initialization.patch
Patch6024: 6024-cov-check-dev_close_immediate.patch
Patch6025: 6025-cov-make-sure-label-scans-valid-lvinfo.patch
Patch6026: 6026-cov-add-missing-error-path-check-for-label_scan_open.patch
Patch6027: 6027-cov-pvscan-ensure-sigle_devs-list-is-always-initiali.patch
Patch6028: 6028-fix-cov-missed-return-value-test.patch
Patch6029: 6029-cov-trace-failing-pthread_kill.patch
Patch6030: 6030-cov-avoid-unsing-unchecked-label_scan_open.patch
Patch6031: 6031-lvmlockd-fix-missing-LV-lock-for-lvconvert-repair.patch
Patch6032: 6032-lvconvert-ensure-proper-init-of-pv_list.patch
Patch6033: 6033-dmeventd-unlock-lvm2-lock-on-error-path.patch
Patch6034: 6034-mangenerator-check-strdup-was-successfull.patch
Patch6035: 6035-cov-ensure-lock_type-is-not-NULL.patch
Patch6036: 6036-Remove-checking-for-locked-VGs.patch
Patch6037: 6037-lvm2-default-allow-changes-with-duplicate-pvs.patch
Patch9000: 9000-bugfix-lvm2-add-SSD.patch
Patch9001: 9001-bugfix-add-timeout-when-fail-to-wait-udev.patch
Patch9002: 9002-bugfix-fix-the-code-maybe-lead-to-buffer-over-bound-access.patch
Patch9003: 9003-enhancement-modify-default-log-level-to-error-level.patch
Patch9004: 9004-enhancement-add-dfx-log.patch
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: libselinux-devel >= %{libselinux_version}, libsepol-devel
BuildRequires: libblkid-devel >= %{util_linux_version}
BuildRequires: ncurses-devel
BuildRequires: readline-devel
BuildRequires: libaio-devel
BuildRequires: module-init-tools
BuildRequires: pkgconfig
BuildRequires: systemd-devel
BuildRequires: systemd-units
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-dbus
BuildRequires: python3-pyudev
BuildRequires: device-mapper-persistent-data >= %{persistent_data_version}
%if %{use_cluster}
BuildRequires: corosynclib-devel >= %{corosync_version}
%endif
%if %{use_cluster} || %{use_lockd_dlm}
BuildRequires: dlm-devel >= %{dlm_version}
%endif
%if %{use_lockd_sanlock}
BuildRequires: sanlock-devel >= %{sanlock_version}
%endif
Requires: bash >= %{bash_version}
Requires: module-init-tools
Requires: device-mapper-persistent-data >= %{persistent_data_version}
Requires: device-mapper-event = %{?epoch}:%{device_mapper_version}-%{release}
Requires(post): systemd-units >= %{systemd_version}, systemd-sysv
Requires(preun): systemd-units >= %{systemd_version}
Requires(postun): systemd-units >= %{systemd_version}
Provides: %{name}-libs
Obsoletes: %{name}-libs
%description
lvm2 refers to the userspace toolset that provide logical volume management facilities on linux.
%package devel
Summary: lvm2 devel files
License: LGPLv2
Requires: %{name} = %{?epoch}:%{version}-%{release}
Requires: pkgconfig
Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release}
Provides: device-mapper-devel = %{?epoch}:%{device_mapper_version}-%{release}
Obsoletes: device-mapper-devel
Provides: device-mapper-event-devel = %{?epoch}:%{device_mapper_version}-%{release}
Obsoletes: device-mapper-event-devel
%description devel
This package contains all include files, libraries files needed to develop programs that use lvm2.
%package help
Summary: Including man files for lvm2
Requires: man
BuildArch: noarch
%description help
This contains man files for the using of lvm2.
%package -n python3-lvm-deprecated
Summary: Python 3 api to lvm
License: LGPLv2
Provides: python3-lvm = %{?epoch}:%{version}-%{release}
%{?python_provide:%python_provide python3-lvm}
Provides: %{name}-python3-libs = %{?epoch}:%{version}-%{release}
Obsoletes: %{name}-python3-libs < %{?epoch}:%{version}-%{release}
Requires: %{name}-libs = %{?epoch}:%{version}-%{release}
%description -n python3-lvm-deprecated
Support python 3 to use lvm.
%if %{use_lockd_dlm} || %{use_lockd_sanlock}
%package lockd
Summary: LVM locking daemon
Requires: lvm2 = %{?epoch}:%{version}-%{release}
%if %{use_lockd_sanlock}
Requires: sanlock-lib >= %{sanlock_version}
%endif
%if %{use_lockd_dlm}
Requires: dlm-lib >= %{dlm_version}
%endif
Requires(post): systemd-units >= %{systemd_version}
Requires(preun): systemd-units >= %{systemd_version}
Requires(postun): systemd-units >= %{systemd_version}
%description lockd
LVM commands use lvmlockd to coordinate access to shared storage.
%endif
%if %{use_cluster}
%package cluster
Summary: cluster LVM daemon tools
License: GPLv2
Requires: lvm2 = %{?epoch}:%{version}-%{release}
Requires(preun): device-mapper >= %{?epoch}:%{device_mapper_version}
Requires(preun): lvm2 >= 2.02
Requires: corosync >= %{corosync_version}
Requires: dlm >= %{dlm_version}
Requires: resource-agents >= %{resource_agents_version}
Provides: cluster-standalone
Obsoletes: cluster-standalone
%description cluster
cluster distributes LVM metadata updates around a cluster.
%endif
%if %{use_cluster} && %{use_cmirror}
%package -n cmirror
Summary: cluster mirror log daemon
License: GPLv2
Requires: corosync >= %{corosync_version}
Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release}
Requires: resource-agents >= %{resource_agents_version}
Provides: cmirror-standalone
Obsoletes: cmirror-standalone
%description -n cmirror
cmirror tracks mirror log information in a cluster.
%endif
%package dbusd
Summary: LVM2 D-Bus daemon
License: GPLv2
Requires: lvm2 >= %{?epoch}:%{version}-%{release}
Requires: dbus
Requires: python3-dbus
Requires: python3-pyudev
Requires: python3-gobject-base
Requires(post): systemd-units >= %{systemd_version}
Requires(preun): systemd-units >= %{systemd_version}
Requires(postun): systemd-units >= %{systemd_version}
%description dbusd
dbusd is a service which provides a D-Bus API to the logical volume manager.
%package test
Summary: Testsuite for lvm2
License: LGPLv2 and GPLv2 and BSD-2-Clause
Provides: %{name}-testsuite
Obsoletes: %{name}-testsuite
%description test
An extensive functional testsuite for LVM2.
%prep
%autosetup -n LVM2.%{version} -p1
%package -n device-mapper
Summary: Low level logical volume management
Version: %{device_mapper_version}
License: LGPLv2
URL: http://sources.redhat.com/dm
Requires: util-linux >= %{util_linux_version}
Requires: systemd >= %{systemd_version}
Provides: device-mapper-libs = %{?epoch}:%{device_mapper_version}-%{release}
Obsoletes: device-mapper-libs
Conflicts: dracut < %{dracut_version}
%description -n device-mapper
Manages logical devices that use the device-mapper driver.
%package -n device-mapper-event
Summary: Handle device-mapper events
Version: %{device_mapper_version}
Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release}
Requires: systemd-units
Provides: device-mapper-event-libs = %{?epoch}:%{device_mapper_version}-%{release}
Obsoletes: device-mapper-event-libs
%description -n device-mapper-event
It contains tthe event monitoring daemon for device-mapper devices. Library plugins
can register and carryout actions triggered when particular events occur.
%build
%configure --with-default-dm-run-dir=/run --with-default-run-dir=/run/lvm --with-default-pid-dir=/run --with-default-locking-dir=/run/lock/lvm --with-usrlibdir=%{_libdir} --enable-fsadm --enable-write_install --with-user= --with-group= --with-device-uid=0 --with-device-gid=6 --with-device-mode=0660 --enable-pkgconfig --enable-applib --enable-cmdlib --enable-dmeventd --enable-blkid_wiping --enable-python3-bindings %{?configure_cluster} %{?configure_cmirror} --with-udevdir=%{_prefix}/lib/udev/rules.d --enable-udev_sync --with-thin=internal --enable-lvmetad --with-thin=internal --enable-lvmpolld %{?configure_lockd_dlm} %{?configure_lockd_sanlock} --enable-dbus-service --enable-notify-dbus --enable-dmfilemapd
make %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
make install_system_dirs DESTDIR=%{buildroot}
make install_systemd_units DESTDIR=%{buildroot}
make install_systemd_generators DESTDIR=%{buildroot}
make install_tmpfiles_configuration DESTDIR=%{buildroot}
make -C test install DESTDIR=%{buildroot}
%post
/sbin/ldconfig
%systemd_post blk-availability.service lvm2-monitor.service
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
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
%post -n device-mapper
/sbin/ldconfig
%postun -n device-mapper
/sbin/ldconfig
%post -n device-mapper-event
/sbin/ldconfig
%systemd_post dm-event.socket
systemctl enable dm-event.socket
systemctl start dm-event.socket >/dev/null 2>&1 || :
if [ -e %{_default_pid_dir}/dmeventd.pid ]; then
%{_sbindir}/dmeventd -R || echo "Failed to start dmeventd."
fi
%preun -n device-mapper-event
%systemd_preun dm-event.service dm-event.socket
%postun -n device-mapper-event
/sbin/ldconfig
%if %{use_lockd_dlm} || %{use_lockd_sanlock}
%post lockd
%systemd_post lvm2-lvmlockd.service lvm2-lvmlocking.service
%preun lockd
%systemd_preun lvm2-lvmlockd.service lvm2-lvmlocking.service
%postun lockd
%systemd_postun lvm2-lvmlockd.service lvm2-lvmlocking.service
%endif
%if %{use_cluster}
%post cluster
if [ -e /run/clvmd.pid ]; then
/usr/sbin/clvmd -S || echo "Failed to start clvmd."
fi
%systemd_post lvm2-clvmd.service lvm2-cluster-activation.service
%preun cluster
if [ "$1" = "0" ]; then
/sbin/lvmconf --disable-cluster
fi
%systemd_preun lvm2-clvmd.service lvm2-cluster-activation.service
%postun cluster
%systemd_postun lvm2-clvmd.service lvm2-cluster-activation.service
%endif
%if %{use_cluster} && %{use_cmirror}
%post -n cmirror
%systemd_post lvm2-cmirrord.service
%preun -n cmirror
%systemd_preun lvm2-cmirrord.service
%postun -n cmirror
%systemd_postun lvm2-cmirrord.service
%endif
%post dbusd
%systemd_post lvm2-lvmdbusd.service
%preun dbusd
%systemd_preun lvm2-lvmdbusd.service
%postun dbusd
%systemd_postun lvm2-lvmdbusd.service
%files
%license COPYING COPYING.LIB
%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.*
%defattr(444,root,root,-)
%{_sbindir}/lvchange
%{_sbindir}/lvconvert
%{_sbindir}/lvcreate
%{_sbindir}/lvdisplay
%{_sbindir}/lvextend
%{_sbindir}/lvmdiskscan
%{_sbindir}/lvmsadc
%{_sbindir}/lvmsar
%{_sbindir}/lvreduce
%{_sbindir}/lvremove
%{_sbindir}/lvrename
%{_sbindir}/lvresize
%{_sbindir}/lvs
%{_sbindir}/lvscan
%{_sbindir}/pv*
%{_sbindir}/vg*
%{_prefix}/lib/udev/rules.d/69-dm-lvm-metad.rules
%{_prefix}/lib/udev/rules.d/11-dm-lvm.rules
%dir %{_sysconfdir}/lvm
%ghost %{_sysconfdir}/lvm/cache/.cache
%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvm.conf
%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvmlocal.conf
%dir %{_sysconfdir}/lvm/profile
%{_sysconfdir}/lvm/profile/*
%dir %{_sysconfdir}/lvm/backup
%dir %{_sysconfdir}/lvm/cache
%dir %{_sysconfdir}/lvm/archive
%ghost %dir /run/lock/lvm
%ghost %dir /run/lvm
%dir %{_libdir}/device-mapper
%{_libdir}/device-mapper/*
%{_libdir}/libdevmapper-event-lvm2mirror.so
%{_libdir}/libdevmapper-event-lvm2snapshot.so
%{_libdir}/libdevmapper-event-lvm2raid.so
%{_libdir}/libdevmapper-event-lvm2thin.so
%{_libdir}/libdevmapper-event-lvm2vdo.so
%{_tmpfilesdir}/%{name}.conf
%{_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
%files -n device-mapper
%license COPYING COPYING.LIB
%doc udev/12-dm-permissions.rules
%defattr(555,root,root,-)
%{_sbindir}/dmsetup
%{_sbindir}/blkdeactivate
%{_sbindir}/dmstats
%{_sbindir}/dmfilemapd
%{_libdir}/libdevmapper.so.*
%defattr(444,root,root,-)
%{_prefix}/lib/udev/rules.d/10-dm.rules
%{_prefix}/lib/udev/rules.d/13-dm-disk.rules
%{_prefix}/lib/udev/rules.d/95-dm-notify.rules
%files -n device-mapper-event
%license COPYING.LIB
%defattr(555,root,root,-)
%{_sbindir}/dmeventd
%{_libdir}/libdevmapper-event.so.*
%defattr(444,root,root,-)
%{_unitdir}/dm-event.socket
%{_unitdir}/dm-event.service
%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
%files help
%{_mandir}/man5/*
%{_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
%endif
%if %{use_cluster}
%files cluster
%defattr(555,root,root,-)
%{_sbindir}/clvmd
%{_prefix}/lib/systemd/lvm2-cluster-activation
%defattr(444,root,root,-)
%{_unitdir}/lvm2-clvmd.service
%{_unitdir}/lvm2-cluster-activation.service
%endif
%if %{use_cluster} && %{use_cmirror}
%files -n cmirror
%defattr(555,root,root,-)
%{_sbindir}/cmirrord
%{_unitdir}/lvm2-cmirrord.service
%endif
%files dbusd
%defattr(555,root,root,-)
%{_sbindir}/lvmdbusd
%defattr(444,root,root,-)
%{_sysconfdir}/dbus-1/system.d/com.redhat.lvmdbus1.conf
%{_datadir}/dbus-1/system-services/com.redhat.lvmdbus1.service
%{_unitdir}/lvm2-lvmdbusd.service
%{python3_sitelib}/lvmdbusd/*
%files test
%license COPYING COPYING.LIB COPYING.BSD
%{_datadir}/lvm2-testsuite/
%{_libexecdir}/lvm2-testsuite/
%{_bindir}/lvm2-testsuite
%changelog
* Fri Sep 06 2019 wangjufeng <wangjufeng@huawei.com> - 2.02.181-2
- Package init