import lvm2-2.03.05-5.el8
This commit is contained in:
commit
086538bddf
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/LVM2.2.03.05.tgz
|
1
.lvm2.metadata
Normal file
1
.lvm2.metadata
Normal file
@ -0,0 +1 @@
|
||||
edfa340a4bbdb3e995521bebbe5307fd7687ac3b SOURCES/LVM2.2.03.05.tgz
|
281
SOURCES/lvm2-2_03_06-Fix-rounding-writes-up-to-sector-size.patch
Normal file
281
SOURCES/lvm2-2_03_06-Fix-rounding-writes-up-to-sector-size.patch
Normal file
@ -0,0 +1,281 @@
|
||||
lib/device/bcache.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
lib/device/dev-io.c | 52 +++++++++++++++++++++++++++++++
|
||||
lib/device/device.h | 8 +++--
|
||||
lib/label/label.c | 30 ++++++++++++++----
|
||||
4 files changed, 169 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
|
||||
index 7b09353..04fbf35 100644
|
||||
--- a/lib/device/bcache.c
|
||||
+++ b/lib/device/bcache.c
|
||||
@@ -169,6 +169,7 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
sector_t offset;
|
||||
sector_t nbytes;
|
||||
sector_t limit_nbytes;
|
||||
+ sector_t orig_nbytes;
|
||||
sector_t extra_nbytes = 0;
|
||||
|
||||
if (((uintptr_t) data) & e->page_mask) {
|
||||
@@ -191,11 +192,41 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
return false;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * If the bcache block offset+len goes beyond where lvm is
|
||||
+ * intending to write, then reduce the len being written
|
||||
+ * (which is the bcache block size) so we don't write past
|
||||
+ * the limit set by lvm. If after applying the limit, the
|
||||
+ * resulting size is not a multiple of the sector size (512
|
||||
+ * or 4096) then extend the reduced size to be a multiple of
|
||||
+ * the sector size (we don't want to write partial sectors.)
|
||||
+ */
|
||||
if (offset + nbytes > _last_byte_offset) {
|
||||
limit_nbytes = _last_byte_offset - offset;
|
||||
- if (limit_nbytes % _last_byte_sector_size)
|
||||
+
|
||||
+ if (limit_nbytes % _last_byte_sector_size) {
|
||||
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
|
||||
|
||||
+ /*
|
||||
+ * adding extra_nbytes to the reduced nbytes (limit_nbytes)
|
||||
+ * should make the final write size a multiple of the
|
||||
+ * sector size. This should never result in a final size
|
||||
+ * larger than the bcache block size (as long as the bcache
|
||||
+ * block size is a multiple of the sector size).
|
||||
+ */
|
||||
+ if (limit_nbytes + extra_nbytes > nbytes) {
|
||||
+ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu",
|
||||
+ (unsigned long long)offset,
|
||||
+ (unsigned long long)nbytes,
|
||||
+ (unsigned long long)limit_nbytes,
|
||||
+ (unsigned long long)extra_nbytes,
|
||||
+ (unsigned long long)_last_byte_sector_size);
|
||||
+ extra_nbytes = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ orig_nbytes = nbytes;
|
||||
+
|
||||
if (extra_nbytes) {
|
||||
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
|
||||
(unsigned long long)offset,
|
||||
@@ -210,6 +241,22 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
(unsigned long long)limit_nbytes);
|
||||
nbytes = limit_nbytes;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * This shouldn't happen, the reduced+extended
|
||||
+ * nbytes value should never be larger than the
|
||||
+ * bcache block size.
|
||||
+ */
|
||||
+ if (nbytes > orig_nbytes) {
|
||||
+ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu",
|
||||
+ (unsigned long long)offset,
|
||||
+ (unsigned long long)orig_nbytes,
|
||||
+ (unsigned long long)nbytes,
|
||||
+ (unsigned long long)limit_nbytes,
|
||||
+ (unsigned long long)extra_nbytes,
|
||||
+ (unsigned long long)_last_byte_sector_size);
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,6 +450,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
uint64_t nbytes = len;
|
||||
sector_t limit_nbytes = 0;
|
||||
sector_t extra_nbytes = 0;
|
||||
+ sector_t orig_nbytes = 0;
|
||||
|
||||
if (offset > _last_byte_offset) {
|
||||
log_error("Limit write at %llu len %llu beyond last byte %llu",
|
||||
@@ -415,9 +463,30 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
|
||||
if (offset + nbytes > _last_byte_offset) {
|
||||
limit_nbytes = _last_byte_offset - offset;
|
||||
- if (limit_nbytes % _last_byte_sector_size)
|
||||
+
|
||||
+ if (limit_nbytes % _last_byte_sector_size) {
|
||||
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
|
||||
|
||||
+ /*
|
||||
+ * adding extra_nbytes to the reduced nbytes (limit_nbytes)
|
||||
+ * should make the final write size a multiple of the
|
||||
+ * sector size. This should never result in a final size
|
||||
+ * larger than the bcache block size (as long as the bcache
|
||||
+ * block size is a multiple of the sector size).
|
||||
+ */
|
||||
+ if (limit_nbytes + extra_nbytes > nbytes) {
|
||||
+ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu",
|
||||
+ (unsigned long long)offset,
|
||||
+ (unsigned long long)nbytes,
|
||||
+ (unsigned long long)limit_nbytes,
|
||||
+ (unsigned long long)extra_nbytes,
|
||||
+ (unsigned long long)_last_byte_sector_size);
|
||||
+ extra_nbytes = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ orig_nbytes = nbytes;
|
||||
+
|
||||
if (extra_nbytes) {
|
||||
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
|
||||
(unsigned long long)offset,
|
||||
@@ -432,6 +501,22 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
(unsigned long long)limit_nbytes);
|
||||
nbytes = limit_nbytes;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * This shouldn't happen, the reduced+extended
|
||||
+ * nbytes value should never be larger than the
|
||||
+ * bcache block size.
|
||||
+ */
|
||||
+ if (nbytes > orig_nbytes) {
|
||||
+ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu",
|
||||
+ (unsigned long long)offset,
|
||||
+ (unsigned long long)orig_nbytes,
|
||||
+ (unsigned long long)nbytes,
|
||||
+ (unsigned long long)limit_nbytes,
|
||||
+ (unsigned long long)extra_nbytes,
|
||||
+ (unsigned long long)_last_byte_sector_size);
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
where = offset;
|
||||
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
|
||||
index 3fe2647..5fa0b7a 100644
|
||||
--- a/lib/device/dev-io.c
|
||||
+++ b/lib/device/dev-io.c
|
||||
@@ -250,6 +250,58 @@ static int _dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64
|
||||
return 1;
|
||||
}
|
||||
|
||||
+int dev_get_direct_block_sizes(struct device *dev, unsigned int *physical_block_size,
|
||||
+ unsigned int *logical_block_size)
|
||||
+{
|
||||
+ int fd = dev->bcache_fd;
|
||||
+ int do_close = 0;
|
||||
+ unsigned int pbs = 0;
|
||||
+ unsigned int lbs = 0;
|
||||
+
|
||||
+ if (dev->physical_block_size || dev->logical_block_size) {
|
||||
+ *physical_block_size = dev->physical_block_size;
|
||||
+ *logical_block_size = dev->logical_block_size;
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (fd <= 0) {
|
||||
+ if (!dev_open_readonly(dev))
|
||||
+ return 0;
|
||||
+ fd = dev_fd(dev);
|
||||
+ do_close = 1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * BLKPBSZGET from kernel comment for blk_queue_physical_block_size:
|
||||
+ * "the lowest possible sector size that the hardware can operate on
|
||||
+ * without reverting to read-modify-write operations"
|
||||
+ */
|
||||
+ if (ioctl(fd, BLKPBSZGET, &pbs)) {
|
||||
+ stack;
|
||||
+ pbs = 0;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * BLKSSZGET from kernel comment for blk_queue_logical_block_size:
|
||||
+ * "the lowest possible block size that the storage device can address."
|
||||
+ */
|
||||
+ if (ioctl(fd, BLKSSZGET, &lbs)) {
|
||||
+ stack;
|
||||
+ lbs = 0;
|
||||
+ }
|
||||
+
|
||||
+ dev->physical_block_size = pbs;
|
||||
+ dev->logical_block_size = lbs;
|
||||
+
|
||||
+ *physical_block_size = pbs;
|
||||
+ *logical_block_size = lbs;
|
||||
+
|
||||
+ if (do_close && !dev_close_immediate(dev))
|
||||
+ stack;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*-----------------------------------------------------------------
|
||||
* Public functions
|
||||
*---------------------------------------------------------------*/
|
||||
diff --git a/lib/device/device.h b/lib/device/device.h
|
||||
index 30e1e79..bb65f84 100644
|
||||
--- a/lib/device/device.h
|
||||
+++ b/lib/device/device.h
|
||||
@@ -67,8 +67,10 @@ struct device {
|
||||
/* private */
|
||||
int fd;
|
||||
int open_count;
|
||||
- int phys_block_size;
|
||||
- int block_size;
|
||||
+ int phys_block_size; /* From either BLKPBSZGET or BLKSSZGET, don't use */
|
||||
+ int block_size; /* From BLKBSZGET, returns bdev->bd_block_size, likely set by fs, probably don't use */
|
||||
+ int physical_block_size; /* From BLKPBSZGET: lowest possible sector size that the hardware can operate on without reverting to read-modify-write operations */
|
||||
+ int logical_block_size; /* From BLKSSZGET: lowest possible block size that the storage device can address */
|
||||
int read_ahead;
|
||||
int bcache_fd;
|
||||
uint32_t flags;
|
||||
@@ -132,6 +134,8 @@ void dev_size_seqno_inc(void);
|
||||
* All io should use these routines.
|
||||
*/
|
||||
int dev_get_block_size(struct device *dev, unsigned int *phys_block_size, unsigned int *block_size);
|
||||
+int dev_get_direct_block_sizes(struct device *dev, unsigned int *physical_block_size,
|
||||
+ unsigned int *logical_block_size);
|
||||
int dev_get_size(struct device *dev, uint64_t *size);
|
||||
int dev_get_read_ahead(struct device *dev, uint32_t *read_ahead);
|
||||
int dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64_t size_bytes);
|
||||
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||
index 4c21d97..72be5ec 100644
|
||||
--- a/lib/label/label.c
|
||||
+++ b/lib/label/label.c
|
||||
@@ -1472,16 +1472,34 @@ 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)
|
||||
{
|
||||
- unsigned int phys_block_size = 0;
|
||||
- unsigned int block_size = 0;
|
||||
+ unsigned int physical_block_size = 0;
|
||||
+ unsigned int logical_block_size = 0;
|
||||
+ unsigned int bs;
|
||||
|
||||
- if (!dev_get_block_size(dev, &phys_block_size, &block_size)) {
|
||||
+ if (!dev_get_direct_block_sizes(dev, &physical_block_size, &logical_block_size)) {
|
||||
stack;
|
||||
- /* FIXME ASSERT or regular error testing is missing */
|
||||
- return;
|
||||
+ return; /* FIXME: error path ? */
|
||||
+ }
|
||||
+
|
||||
+ if ((physical_block_size == 512) && (logical_block_size == 512))
|
||||
+ bs = 512;
|
||||
+ else if ((physical_block_size == 4096) && (logical_block_size == 4096))
|
||||
+ bs = 4096;
|
||||
+ else if ((physical_block_size == 512) || (logical_block_size == 512)) {
|
||||
+ log_debug("Set last byte mixed block sizes physical %u logical %u using 512",
|
||||
+ physical_block_size, logical_block_size);
|
||||
+ bs = 512;
|
||||
+ } else if ((physical_block_size == 4096) || (logical_block_size == 4096)) {
|
||||
+ log_debug("Set last byte mixed block sizes physical %u logical %u using 4096",
|
||||
+ physical_block_size, logical_block_size);
|
||||
+ bs = 4096;
|
||||
+ } else {
|
||||
+ log_debug("Set last byte mixed block sizes physical %u logical %u using 512",
|
||||
+ physical_block_size, logical_block_size);
|
||||
+ bs = 512;
|
||||
}
|
||||
|
||||
- bcache_set_last_byte(scan_bcache, dev->bcache_fd, offset, phys_block_size);
|
||||
+ bcache_set_last_byte(scan_bcache, dev->bcache_fd, offset, bs);
|
||||
}
|
||||
|
||||
void dev_unset_last_byte(struct device *dev)
|
@ -0,0 +1,54 @@
|
||||
daemons/lvmlockd/Makefile.in | 21 ++++++++++++++-------
|
||||
daemons/lvmlockd/lvmlockd-core.c | 2 +-
|
||||
2 files changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/Makefile.in b/daemons/lvmlockd/Makefile.in
|
||||
index dca05b8..9c03401 100644
|
||||
--- a/daemons/lvmlockd/Makefile.in
|
||||
+++ b/daemons/lvmlockd/Makefile.in
|
||||
@@ -38,18 +38,25 @@ TARGETS = lvmlockd lvmlockctl
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
-CFLAGS += $(EXTRA_EXEC_CFLAGS) $(SYSTEMD_CFLAGS)
|
||||
+CFLAGS += $(EXTRA_EXEC_CFLAGS)
|
||||
INCLUDES += -I$(top_srcdir)/libdaemon/server
|
||||
-LDFLAGS += $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
|
||||
-LIBS += $(PTHREAD_LIBS) $(SYSTEMD_LIBS)
|
||||
+LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
|
||||
+LIBS += $(RT_LIBS) $(DAEMON_LIBS) $(PTHREAD_LIBS)
|
||||
|
||||
-lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/server/libdaemonserver.a $(INTERNAL_LIBS)
|
||||
+
|
||||
+ifeq ($(USE_SD_NOTIFY),yes)
|
||||
+ CFLAGS += $(shell pkg-config --cflags libsystemd) -DUSE_SD_NOTIFY
|
||||
+ LIBS += $(shell pkg-config --libs libsystemd)
|
||||
+endif
|
||||
+
|
||||
+lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
||||
+ $(top_builddir)/libdaemon/server/libdaemonserver.a
|
||||
@echo " [CC] $@"
|
||||
- $(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LOCK_LIBS) $(LIBS)
|
||||
+ $(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LOCK_LIBS) -ldaemonserver $(INTERNAL_LIBS) $(LIBS)
|
||||
|
||||
-lvmlockctl: lvmlockctl.o $(INTERNAL_LIBS)
|
||||
+lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a
|
||||
@echo " [CC] $@"
|
||||
- $(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
|
||||
+ $(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(INTERNAL_LIBS) $(LIBS)
|
||||
|
||||
install_lvmlockd: lvmlockd
|
||||
@echo " [INSTALL] $<"
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
|
||||
index 5609ccc..39275fb 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-core.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-core.c
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
-#ifdef NOTIFYDBUS_SUPPORT
|
||||
+#ifdef USE_SD_NOTIFY
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
@ -0,0 +1,15 @@
|
||||
WHATS_NEW | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index 3a58de5..cb693de 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,3 +1,7 @@
|
||||
+Version 2.03.06 -
|
||||
+================================
|
||||
+ Fix metadata writes from corrupting with large physical block size.
|
||||
+
|
||||
Version 2.03.05 - 15th June 2019
|
||||
================================
|
||||
Fix command definition for pvchange -a.
|
@ -0,0 +1,14 @@
|
||||
WHATS_NEW | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index cb693de..a7ccd39 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,5 +1,6 @@
|
||||
Version 2.03.06 -
|
||||
================================
|
||||
+ Prevent creating VGs with PVs with different logical block sizes.
|
||||
Fix metadata writes from corrupting with large physical block size.
|
||||
|
||||
Version 2.03.05 - 15th June 2019
|
135
SOURCES/lvm2-2_03_06-build-make-generate.patch
Normal file
135
SOURCES/lvm2-2_03_06-build-make-generate.patch
Normal file
@ -0,0 +1,135 @@
|
||||
conf/example.conf.in | 9 +++----
|
||||
man/lvconvert.8_pregen | 70 +++++++++++++++++++++++++++-----------------------
|
||||
2 files changed, 42 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/conf/example.conf.in b/conf/example.conf.in
|
||||
index b9cdf0c..ed6a3b6 100644
|
||||
--- a/conf/example.conf.in
|
||||
+++ b/conf/example.conf.in
|
||||
@@ -143,7 +143,7 @@ devices {
|
||||
#
|
||||
# Example
|
||||
# Accept every block device:
|
||||
- # filter = [ "a|.*/|" ]
|
||||
+ # filter = [ "a|.*|" ]
|
||||
# Reject the cdrom drive:
|
||||
# filter = [ "r|/dev/cdrom|" ]
|
||||
# Work with just loopback devices, e.g. for testing:
|
||||
@@ -151,10 +151,10 @@ devices {
|
||||
# Accept all loop devices and ide drives except hdc:
|
||||
# filter = [ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ]
|
||||
# Use anchors to be very specific:
|
||||
- # filter = [ "a|^/dev/hda8$|", "r|.*/|" ]
|
||||
+ # filter = [ "a|^/dev/hda8$|", "r|.*|" ]
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
- # filter = [ "a|.*/|" ]
|
||||
+ # filter = [ "a|.*|" ]
|
||||
|
||||
# Configuration option devices/global_filter.
|
||||
# Limit the block devices that are used by LVM system components.
|
||||
@@ -164,7 +164,7 @@ devices {
|
||||
# The syntax is the same as devices/filter. Devices rejected by
|
||||
# global_filter are not opened by LVM.
|
||||
# This configuration option has an automatic default value.
|
||||
- # global_filter = [ "a|.*/|" ]
|
||||
+ # global_filter = [ "a|.*|" ]
|
||||
|
||||
# Configuration option devices/types.
|
||||
# List of additional acceptable block device types.
|
||||
@@ -1752,7 +1752,6 @@ activation {
|
||||
# additional space for VG metadata. The --metadatasize option overrides
|
||||
# this setting.
|
||||
# This configuration option does not have a default value defined.
|
||||
- # This configuration option has an automatic default value.
|
||||
|
||||
# Configuration option metadata/pvmetadataignore.
|
||||
# Ignore metadata areas on a new PV.
|
||||
diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen
|
||||
index 7252f6f..846ea2d 100644
|
||||
--- a/man/lvconvert.8_pregen
|
||||
+++ b/man/lvconvert.8_pregen
|
||||
@@ -378,6 +378,44 @@ Convert LV to striped.
|
||||
.RE
|
||||
-
|
||||
|
||||
+Convert LV to type mirror (also see type raid1),
|
||||
+.br
|
||||
+.P
|
||||
+\fBlvconvert\fP \fB--type\fP \fBmirror\fP \fILV\fP
|
||||
+.br
|
||||
+.RS 4
|
||||
+.ad l
|
||||
+[ \fB-m\fP|\fB--mirrors\fP [\fB+\fP|\fB-\fP]\fINumber\fP ]
|
||||
+.ad b
|
||||
+.br
|
||||
+.ad l
|
||||
+[ \fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT] ]
|
||||
+.ad b
|
||||
+.br
|
||||
+.ad l
|
||||
+[ \fB-R\fP|\fB--regionsize\fP \fISize\fP[m|UNIT] ]
|
||||
+.ad b
|
||||
+.br
|
||||
+.ad l
|
||||
+[ \fB-i\fP|\fB--interval\fP \fINumber\fP ]
|
||||
+.ad b
|
||||
+.br
|
||||
+.ad l
|
||||
+[ \fB--stripes\fP \fINumber\fP ]
|
||||
+.ad b
|
||||
+.br
|
||||
+.ad l
|
||||
+[ \fB--mirrorlog\fP \fBcore\fP|\fBdisk\fP ]
|
||||
+.ad b
|
||||
+.br
|
||||
+[ COMMON_OPTIONS ]
|
||||
+.RE
|
||||
+.br
|
||||
+.RS 4
|
||||
+[ \fIPV\fP ... ]
|
||||
+.RE
|
||||
+-
|
||||
+
|
||||
Convert LV to raid or change raid layout
|
||||
.br
|
||||
(a specific raid level must be used, e.g. raid1).
|
||||
@@ -1636,38 +1674,6 @@ For example, LVM_VG_NAME can generally be substituted for a required VG paramete
|
||||
.SH ADVANCED USAGE
|
||||
Alternate command forms, advanced command usage, and listing of all valid syntax for completeness.
|
||||
.P
|
||||
-Convert LV to type mirror (also see type raid1),
|
||||
-.br
|
||||
-(also see lvconvert --mirrors).
|
||||
-.br
|
||||
-.P
|
||||
-\fBlvconvert\fP \fB--type\fP \fBmirror\fP \fILV\fP
|
||||
-.br
|
||||
-.RS 4
|
||||
-.ad l
|
||||
-[ \fB-m\fP|\fB--mirrors\fP [\fB+\fP|\fB-\fP]\fINumber\fP ]
|
||||
-.ad b
|
||||
-.br
|
||||
-.ad l
|
||||
-[ \fB-R\fP|\fB--regionsize\fP \fISize\fP[m|UNIT] ]
|
||||
-.ad b
|
||||
-.br
|
||||
-.ad l
|
||||
-[ \fB-i\fP|\fB--interval\fP \fINumber\fP ]
|
||||
-.ad b
|
||||
-.br
|
||||
-.ad l
|
||||
-[ \fB--mirrorlog\fP \fBcore\fP|\fBdisk\fP ]
|
||||
-.ad b
|
||||
-.br
|
||||
-[ COMMON_OPTIONS ]
|
||||
-.RE
|
||||
-.br
|
||||
-.RS 4
|
||||
-[ \fIPV\fP ... ]
|
||||
-.RE
|
||||
--
|
||||
-
|
||||
Change the region size of an LV.
|
||||
.br
|
||||
.P
|
@ -0,0 +1,56 @@
|
||||
test/shell/cache-single-options.sh | 2 +-
|
||||
tools/lvchange.c | 8 ++++++++
|
||||
tools/lvconvert.c | 8 ++++++++
|
||||
3 files changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/test/shell/cache-single-options.sh b/test/shell/cache-single-options.sh
|
||||
index da9cbba..6b71b2f 100644
|
||||
--- a/test/shell/cache-single-options.sh
|
||||
+++ b/test/shell/cache-single-options.sh
|
||||
@@ -228,7 +228,7 @@ lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||
|
||||
lvchange -ay $vg/$lv1
|
||||
|
||||
-lvchange --cachemode writeback $vg/$lv1
|
||||
+lvchange -y --cachemode writeback $vg/$lv1
|
||||
|
||||
check lv_field $vg/$lv1 cachemode "writeback"
|
||||
|
||||
diff --git a/tools/lvchange.c b/tools/lvchange.c
|
||||
index 7bdf997..92c6524 100644
|
||||
--- a/tools/lvchange.c
|
||||
+++ b/tools/lvchange.c
|
||||
@@ -635,6 +635,14 @@ static int _lvchange_cache(struct cmd_context *cmd,
|
||||
if (!get_cache_params(cmd, &chunk_size, &format, &mode, &name, &settings))
|
||||
goto_out;
|
||||
|
||||
+ if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv) && (mode == CACHE_MODE_WRITEBACK)) {
|
||||
+ log_warn("WARNING: repairing a damaged cachevol is not yet possible.");
|
||||
+ log_warn("WARNING: cache mode writethrough is suggested for safe operation.");
|
||||
+ if (!arg_count(cmd, yes_ARG) &&
|
||||
+ yes_no_prompt("Continue using writeback without repair?") == 'n')
|
||||
+ goto_out;
|
||||
+ }
|
||||
+
|
||||
if ((mode != CACHE_MODE_UNSELECTED) &&
|
||||
(mode != setting_seg->cache_mode) &&
|
||||
lv_is_cache(lv)) {
|
||||
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||
index 24db8d2..ebc2243 100644
|
||||
--- a/tools/lvconvert.c
|
||||
+++ b/tools/lvconvert.c
|
||||
@@ -3401,6 +3401,14 @@ static int _cache_vol_attach(struct cmd_context *cmd,
|
||||
if (!cache_vol_set_params(cmd, cache_lv, lv_fast, poolmetadatasize, chunk_size, cache_metadata_format, cache_mode, policy_name, policy_settings))
|
||||
goto_out;
|
||||
|
||||
+ if (cache_mode == CACHE_MODE_WRITEBACK) {
|
||||
+ log_warn("WARNING: repairing a damaged cachevol is not yet possible.");
|
||||
+ log_warn("WARNING: cache mode writethrough is suggested for safe operation.");
|
||||
+ if (!arg_count(cmd, yes_ARG) &&
|
||||
+ yes_no_prompt("Continue using writeback without repair?") == 'n')
|
||||
+ goto_out;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* lv/cache_lv keeps the same lockd lock it had before, the lock for
|
||||
* lv_fast is freed, and lv_corig has no lock.
|
@ -0,0 +1,16 @@
|
||||
lib/config/config_settings.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
|
||||
index 70fb36d..f14f0b8 100644
|
||||
--- a/lib/config/config_settings.h
|
||||
+++ b/lib/config/config_settings.h
|
||||
@@ -1694,7 +1694,7 @@ cfg(metadata_vgmetadatacopies_CFG, "vgmetadatacopies", metadata_CFG_SECTION, CFG
|
||||
"and allows you to control which metadata areas are used at the\n"
|
||||
"individual PV level using pvchange --metadataignore y|n.\n")
|
||||
|
||||
-cfg_runtime(metadata_pvmetadatasize_CFG, "pvmetadatasize", metadata_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(1, 0, 0), 0, NULL,
|
||||
+cfg_runtime(metadata_pvmetadatasize_CFG, "pvmetadatasize", metadata_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(1, 0, 0), 0, NULL,
|
||||
"The default size of the metadata area in units of 512 byte sectors.\n"
|
||||
"The metadata area begins at an offset of the page size from the start\n"
|
||||
"of the device. The first PE is by default at 1 MiB from the start of\n"
|
38
SOURCES/lvm2-2_03_06-config-remove-filter-typo.patch
Normal file
38
SOURCES/lvm2-2_03_06-config-remove-filter-typo.patch
Normal file
@ -0,0 +1,38 @@
|
||||
lib/config/config_settings.h | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
|
||||
index 3113fe1..70fb36d 100644
|
||||
--- a/lib/config/config_settings.h
|
||||
+++ b/lib/config/config_settings.h
|
||||
@@ -288,7 +288,7 @@ cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, C
|
||||
"preferred_names = [ \"^/dev/mpath/\", \"^/dev/mapper/mpath\", \"^/dev/[hs]d\" ]\n"
|
||||
"#\n")
|
||||
|
||||
-cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "#Sa|.*/|", vsn(1, 0, 0), NULL, 0, NULL,
|
||||
+cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "#Sa|.*|", vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Limit the block devices that are used by LVM commands.\n"
|
||||
"This is a list of regular expressions used to accept or reject block\n"
|
||||
"device path names. Each regex is delimited by a vertical bar '|'\n"
|
||||
@@ -306,7 +306,7 @@ cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENT
|
||||
"#\n"
|
||||
"Example\n"
|
||||
"Accept every block device:\n"
|
||||
- "filter = [ \"a|.*/|\" ]\n"
|
||||
+ "filter = [ \"a|.*|\" ]\n"
|
||||
"Reject the cdrom drive:\n"
|
||||
"filter = [ \"r|/dev/cdrom|\" ]\n"
|
||||
"Work with just loopback devices, e.g. for testing:\n"
|
||||
@@ -314,10 +314,10 @@ cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENT
|
||||
"Accept all loop devices and ide drives except hdc:\n"
|
||||
"filter = [ \"a|loop|\", \"r|/dev/hdc|\", \"a|/dev/ide|\", \"r|.*|\" ]\n"
|
||||
"Use anchors to be very specific:\n"
|
||||
- "filter = [ \"a|^/dev/hda8$|\", \"r|.*/|\" ]\n"
|
||||
+ "filter = [ \"a|^/dev/hda8$|\", \"r|.*|\" ]\n"
|
||||
"#\n")
|
||||
|
||||
-cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "#Sa|.*/|", vsn(2, 2, 98), NULL, 0, NULL,
|
||||
+cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "#Sa|.*|", vsn(2, 2, 98), NULL, 0, NULL,
|
||||
"Limit the block devices that are used by LVM system components.\n"
|
||||
"Because devices/filter may be overridden from the command line, it is\n"
|
||||
"not suitable for system-wide device filtering, e.g. udev.\n"
|
@ -0,0 +1,66 @@
|
||||
configure | 6 +++---
|
||||
configure.ac | 6 +++---
|
||||
2 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index ff3a59b..4c84765 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3077,7 +3077,7 @@ if test -z "$CFLAGS"; then :
|
||||
fi
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
- CLDFLAGS="${CLDFLAGS:"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
+ CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
# equivalent to -rdynamic
|
||||
ELDFLAGS="-Wl,--export-dynamic"
|
||||
# FIXME Generate list and use --dynamic-list=.dlopen.sym
|
||||
@@ -3098,7 +3098,7 @@ case "$host_os" in
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
|
||||
- CLDFLAGS="${CLDFLAGS:"$LDFLAGS"}"
|
||||
+ CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
|
||||
ELDFLAGS=
|
||||
CLDWHOLEARCHIVE="-all_load"
|
||||
CLDNOWHOLEARCHIVE=
|
||||
@@ -3111,7 +3111,7 @@ case "$host_os" in
|
||||
BLKDEACTIVATE=no
|
||||
;;
|
||||
*)
|
||||
- CLDFLAGS="${CLDFLAGS:"$LDFLAGS"}"
|
||||
+ CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
|
||||
;;
|
||||
esac
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 1e45c0e..9c82773 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -30,7 +30,7 @@ AC_CANONICAL_TARGET([])
|
||||
AS_IF([test -z "$CFLAGS"], [COPTIMISE_FLAG="-O2"])
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
- CLDFLAGS="${CLDFLAGS:"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
+ CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
# equivalent to -rdynamic
|
||||
ELDFLAGS="-Wl,--export-dynamic"
|
||||
# FIXME Generate list and use --dynamic-list=.dlopen.sym
|
||||
@@ -51,7 +51,7 @@ case "$host_os" in
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
|
||||
- CLDFLAGS="${CLDFLAGS:"$LDFLAGS"}"
|
||||
+ CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
|
||||
ELDFLAGS=
|
||||
CLDWHOLEARCHIVE="-all_load"
|
||||
CLDNOWHOLEARCHIVE=
|
||||
@@ -64,7 +64,7 @@ case "$host_os" in
|
||||
BLKDEACTIVATE=no
|
||||
;;
|
||||
*)
|
||||
- CLDFLAGS="${CLDFLAGS:"$LDFLAGS"}"
|
||||
+ CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
|
||||
;;
|
||||
esac
|
||||
|
@ -0,0 +1,16 @@
|
||||
libdaemon/server/daemon-server.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
|
||||
index 9dd0017..2df4e89 100644
|
||||
--- a/libdaemon/server/daemon-server.c
|
||||
+++ b/libdaemon/server/daemon-server.c
|
||||
@@ -690,7 +690,7 @@ void daemon_start(daemon_state s)
|
||||
out:
|
||||
/* If activated by systemd, do not unlink the socket - systemd takes care of that! */
|
||||
if (!_systemd_activation && s.socket_fd >= 0)
|
||||
- if (unlink(s.socket_path))
|
||||
+ if (s.socket_path && unlink(s.socket_path))
|
||||
perror("unlink error");
|
||||
|
||||
if (s.socket_fd >= 0)
|
@ -0,0 +1,34 @@
|
||||
tools/command.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/command.c b/tools/command.c
|
||||
index 724040e..2e69eff 100644
|
||||
--- a/tools/command.c
|
||||
+++ b/tools/command.c
|
||||
@@ -1935,7 +1935,7 @@ void print_usage(struct command *cmd, int longhelp, int desc_first)
|
||||
* see print_common_options_cmd()
|
||||
*/
|
||||
|
||||
- if ((cname->variants > 1) && cname->common_options[opt_enum])
|
||||
+ if (cname && (cname->variants > 1) && cname->common_options[opt_enum])
|
||||
continue;
|
||||
|
||||
printf("\n\t[");
|
||||
@@ -1975,7 +1975,7 @@ void print_usage(struct command *cmd, int longhelp, int desc_first)
|
||||
* see print_common_options_cmd()
|
||||
*/
|
||||
|
||||
- if ((cname->variants > 1) && cname->common_options[opt_enum])
|
||||
+ if (cname && (cname->variants > 1) && cname->common_options[opt_enum])
|
||||
continue;
|
||||
|
||||
printf("\n\t[");
|
||||
@@ -3438,7 +3438,7 @@ static int _print_man(char *name, char *des_file, int secondary)
|
||||
|
||||
if (!prev_cmd || strcmp(prev_cmd->name, cmd->name)) {
|
||||
printf(".SH NAME\n");
|
||||
- if (cname->desc)
|
||||
+ if (cname && cname->desc)
|
||||
printf("%s - %s\n", lvmname, cname->desc);
|
||||
else
|
||||
printf("%s\n", lvmname);
|
@ -0,0 +1,30 @@
|
||||
daemons/dmeventd/plugins/raid/dmeventd_raid.c | 16 ++++++----------
|
||||
1 file changed, 6 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/daemons/dmeventd/plugins/raid/dmeventd_raid.c b/daemons/dmeventd/plugins/raid/dmeventd_raid.c
|
||||
index aa2b578..3431f1e 100644
|
||||
--- a/daemons/dmeventd/plugins/raid/dmeventd_raid.c
|
||||
+++ b/daemons/dmeventd/plugins/raid/dmeventd_raid.c
|
||||
@@ -76,16 +76,12 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
|
||||
}
|
||||
|
||||
if (dead) {
|
||||
- if (status->insync_regions < status->total_regions) {
|
||||
- if (!state->warned) {
|
||||
- state->warned = 1;
|
||||
- log_warn("WARNING: waiting for resynchronization to finish "
|
||||
- "before initiating repair on RAID device %s.", device);
|
||||
- }
|
||||
-
|
||||
- goto out; /* Not yet done syncing with accessible devices */
|
||||
- }
|
||||
-
|
||||
+ /*
|
||||
+ * Use the first event to run a repair ignoring any additonal ones.
|
||||
+ *
|
||||
+ * We presume lvconvert to do pre-repair
|
||||
+ * checks to avoid bloat in this plugin.
|
||||
+ */
|
||||
if (state->failed)
|
||||
goto out; /* already reported */
|
||||
|
@ -0,0 +1,151 @@
|
||||
lib/device/dev-cache.c | 19 +++++++++++++++++++
|
||||
lib/device/dev-cache.h | 3 +++
|
||||
lib/device/dev-md.c | 6 +++---
|
||||
lib/label/label.c | 27 ++++++++++++++-------------
|
||||
tools/pvscan.c | 7 +++++++
|
||||
5 files changed, 46 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||
index 1492181..980dd3c 100644
|
||||
--- a/lib/device/dev-cache.c
|
||||
+++ b/lib/device/dev-cache.c
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "base/memory/zalloc.h"
|
||||
#include "lib/misc/lib.h"
|
||||
+#include "lib/device/dev-type.h"
|
||||
#include "lib/datastruct/btree.h"
|
||||
#include "lib/config/config.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
@@ -1634,3 +1635,21 @@ const char *dev_name(const struct device *dev)
|
||||
return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
|
||||
unknown_device_name();
|
||||
}
|
||||
+
|
||||
+bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
|
||||
+{
|
||||
+ struct btree_iter *iter = btree_first(_cache.devices);
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ while (iter) {
|
||||
+ dev = btree_get_data(iter);
|
||||
+
|
||||
+ if (dev_is_md_with_end_superblock(dt, dev))
|
||||
+ return true;
|
||||
+
|
||||
+ iter = btree_next(iter);
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
|
||||
index 8a1c277..46c86c2 100644
|
||||
--- a/lib/device/dev-cache.h
|
||||
+++ b/lib/device/dev-cache.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#define _LVM_DEV_CACHE_H
|
||||
|
||||
#include "lib/device/device.h"
|
||||
+#include "lib/device/dev-type.h"
|
||||
#include "lib/misc/lvm-wrappers.h"
|
||||
|
||||
struct cmd_context;
|
||||
@@ -71,4 +72,6 @@ void dev_reset_error_count(struct cmd_context *cmd);
|
||||
|
||||
void dev_cache_failed_path(struct device *dev, const char *path);
|
||||
|
||||
+bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
|
||||
+
|
||||
#endif
|
||||
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
|
||||
index 08143b7..9d0a363 100644
|
||||
--- a/lib/device/dev-md.c
|
||||
+++ b/lib/device/dev-md.c
|
||||
@@ -302,12 +302,12 @@ static int _md_sysfs_attribute_scanf(struct dev_types *dt,
|
||||
return ret;
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
- log_sys_error("fopen", path);
|
||||
+ log_debug("_md_sysfs_attribute_scanf fopen failed %s", path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||
- log_sys_error("fgets", path);
|
||||
+ log_debug("_md_sysfs_attribute_scanf fgets failed %s", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -449,7 +449,7 @@ int dev_is_md_with_end_superblock(struct dev_types *dt, struct device *dev)
|
||||
|
||||
if (_md_sysfs_attribute_scanf(dt, dev, attribute,
|
||||
"%s", &version_string) != 1)
|
||||
- return -1;
|
||||
+ return 0;
|
||||
|
||||
log_very_verbose("Device %s %s is %s.",
|
||||
dev_name(dev), attribute, version_string);
|
||||
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||
index a8d87ec..4c21d97 100644
|
||||
--- a/lib/label/label.c
|
||||
+++ b/lib/label/label.c
|
||||
@@ -901,6 +901,20 @@ int label_scan(struct cmd_context *cmd)
|
||||
dev_cache_scan();
|
||||
|
||||
/*
|
||||
+ * If we know that there will be md components with an end
|
||||
+ * superblock, then enable the full md filter before label
|
||||
+ * scan begins. FIXME: we could skip the full md check on
|
||||
+ * devs that are not identified as PVs, but then we'd need
|
||||
+ * to do something other than using the standard md filter.
|
||||
+ */
|
||||
+ if (cmd->md_component_detection && !cmd->use_full_md_check &&
|
||||
+ !strcmp(cmd->md_component_checks, "auto") &&
|
||||
+ dev_cache_has_md_with_end_superblock(cmd->dev_types)) {
|
||||
+ log_debug("Enable full md component check.");
|
||||
+ cmd->use_full_md_check = 1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Set up the iterator that is needed to step through each device in
|
||||
* dev cache.
|
||||
*/
|
||||
@@ -938,19 +952,6 @@ int label_scan(struct cmd_context *cmd)
|
||||
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
|
||||
_scan_dev_close(dev);
|
||||
}
|
||||
-
|
||||
- /*
|
||||
- * When md devices exist that use the old superblock at the
|
||||
- * end of the device, then in order to detect and filter out
|
||||
- * the component devices of those md devs, we enable the full
|
||||
- * md filter which scans both the start and the end of every
|
||||
- * device. This doubles the amount of scanning i/o, which we
|
||||
- * want to avoid. FIXME: this forces start+end scanning of
|
||||
- * every device, but it would be more efficient to limit the
|
||||
- * end scan only to PVs.
|
||||
- */
|
||||
- if (dev_is_md_with_end_superblock(cmd->dev_types, dev))
|
||||
- cmd->use_full_md_check = 1;
|
||||
};
|
||||
dev_iter_destroy(iter);
|
||||
|
||||
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||
index db813ad..0a91add 100644
|
||||
--- a/tools/pvscan.c
|
||||
+++ b/tools/pvscan.c
|
||||
@@ -938,6 +938,13 @@ int pvscan_cache_cmd(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();
|
||||
|
||||
+ if (cmd->md_component_detection && !cmd->use_full_md_check &&
|
||||
+ !strcmp(cmd->md_component_checks, "auto") &&
|
||||
+ dev_cache_has_md_with_end_superblock(cmd->dev_types)) {
|
||||
+ log_debug("Enable full md component check.");
|
||||
+ cmd->use_full_md_check = 1;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* For each device command arg (from either position or --major/--minor),
|
||||
* decide if that device is being added to the system (a dev node exists
|
629
SOURCES/lvm2-2_03_06-exported-vg-handling.patch
Normal file
629
SOURCES/lvm2-2_03_06-exported-vg-handling.patch
Normal file
@ -0,0 +1,629 @@
|
||||
lib/commands/toolcontext.h | 1 +
|
||||
lib/metadata/metadata-exported.h | 1 -
|
||||
lib/metadata/metadata.c | 42 ++++++++++++++++++++++----------
|
||||
tools/command.c | 1 +
|
||||
tools/commands.h | 29 +++++++++++-----------
|
||||
tools/lvmcmdline.c | 2 ++
|
||||
tools/pvchange.c | 7 +-----
|
||||
tools/pvresize.c | 7 +-----
|
||||
tools/toollib.c | 52 +++++++++++++++++++++++++++++++---------
|
||||
tools/tools.h | 2 ++
|
||||
tools/vgchange.c | 22 ++++-------------
|
||||
tools/vgck.c | 3 ---
|
||||
tools/vgimport.c | 6 ++---
|
||||
tools/vgimportclone.c | 4 ++--
|
||||
tools/vgreduce.c | 5 ++--
|
||||
tools/vgremove.c | 3 ---
|
||||
tools/vgrename.c | 3 +--
|
||||
tools/vgsplit.c | 12 ++++++++--
|
||||
18 files changed, 115 insertions(+), 87 deletions(-)
|
||||
|
||||
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
||||
index 6e4530c..488752c 100644
|
||||
--- a/lib/commands/toolcontext.h
|
||||
+++ b/lib/commands/toolcontext.h
|
||||
@@ -148,6 +148,7 @@ struct cmd_context {
|
||||
unsigned unknown_system_id:1;
|
||||
unsigned include_historical_lvs:1; /* also process/report/display historical LVs */
|
||||
unsigned record_historical_lvs:1; /* record historical LVs */
|
||||
+ unsigned include_exported_vgs:1;
|
||||
unsigned include_foreign_vgs:1; /* report/display cmds can reveal foreign VGs */
|
||||
unsigned include_shared_vgs:1; /* report/display cmds can reveal lockd VGs */
|
||||
unsigned include_active_foreign_vgs:1; /* cmd should process foreign VGs with active LVs */
|
||||
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||||
index 9029d3f..77b971b 100644
|
||||
--- a/lib/metadata/metadata-exported.h
|
||||
+++ b/lib/metadata/metadata-exported.h
|
||||
@@ -181,7 +181,6 @@
|
||||
#define MIRROR_SKIP_INIT_SYNC 0x00000010U /* skip initial sync */
|
||||
|
||||
/* vg_read and vg_read_for_update flags */
|
||||
-#define READ_ALLOW_EXPORTED 0x00020000U
|
||||
#define READ_OK_NOTFOUND 0x00040000U
|
||||
#define READ_WARN_INCONSISTENT 0x00080000U
|
||||
#define READ_FOR_UPDATE 0x00100000U /* A meta-flag, useful with toollib for_each_* functions. */
|
||||
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
|
||||
index 039a7d6..dc1b501 100644
|
||||
--- a/lib/metadata/metadata.c
|
||||
+++ b/lib/metadata/metadata.c
|
||||
@@ -593,9 +593,6 @@ int vg_remove_check(struct volume_group *vg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (!vg_check_status(vg, EXPORTED_VG))
|
||||
- return 0;
|
||||
-
|
||||
lv_count = vg_visible_lvs(vg);
|
||||
|
||||
if (lv_count) {
|
||||
@@ -3709,12 +3706,6 @@ uint32_t vg_bad_status_bits(const struct volume_group *vg, uint64_t status)
|
||||
/* Return because other flags are considered undefined. */
|
||||
return FAILED_CLUSTERED;
|
||||
|
||||
- if ((status & EXPORTED_VG) &&
|
||||
- vg_is_exported(vg)) {
|
||||
- log_error("Volume group %s is exported", vg->name);
|
||||
- failure |= FAILED_EXPORTED;
|
||||
- }
|
||||
-
|
||||
if ((status & LVM_WRITE) &&
|
||||
!(vg->status & LVM_WRITE)) {
|
||||
log_error("Volume group %s is read-only", vg->name);
|
||||
@@ -3733,7 +3724,7 @@ uint32_t vg_bad_status_bits(const struct volume_group *vg, uint64_t status)
|
||||
/**
|
||||
* vg_check_status - check volume group status flags and log error
|
||||
* @vg - volume group to check status flags
|
||||
- * @status - specific status flags to check (e.g. EXPORTED_VG)
|
||||
+ * @status - specific status flags to check
|
||||
*/
|
||||
int vg_check_status(const struct volume_group *vg, uint64_t status)
|
||||
{
|
||||
@@ -3914,6 +3905,28 @@ static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int _access_vg_exported(struct cmd_context *cmd, struct volume_group *vg)
|
||||
+{
|
||||
+ if (!vg_is_exported(vg))
|
||||
+ return 1;
|
||||
+
|
||||
+ if (cmd->include_exported_vgs)
|
||||
+ return 1;
|
||||
+
|
||||
+ /*
|
||||
+ * Some commands want the error printed by vg_read, others by ignore_vg.
|
||||
+ * Those using ignore_vg may choose to skip the error.
|
||||
+ */
|
||||
+ if (cmd->vg_read_print_access_error) {
|
||||
+ log_error("Volume group %s is exported", vg->name);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Silently ignore exported vgs. */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Test the validity of a VG handle returned by vg_read() or vg_read_for_update().
|
||||
*/
|
||||
@@ -4883,8 +4896,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
- if (writing && !(read_flags & READ_ALLOW_EXPORTED) && vg_is_exported(vg)) {
|
||||
- log_error("Volume group %s is exported", vg->name);
|
||||
+ if (!_access_vg_exported(cmd, vg)) {
|
||||
failure |= FAILED_EXPORTED;
|
||||
goto_bad;
|
||||
}
|
||||
@@ -4895,6 +4907,12 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
+ if (writing && !(vg->status & LVM_WRITE)) {
|
||||
+ log_error("Volume group %s is read-only", vg->name);
|
||||
+ failure |= FAILED_READ_ONLY;
|
||||
+ goto_bad;
|
||||
+ }
|
||||
+
|
||||
if (!cmd->handles_missing_pvs && (missing_pv_dev || missing_pv_flag) && writing) {
|
||||
log_error("Cannot change VG %s while PVs are missing.", vg->name);
|
||||
log_error("See vgreduce --removemissing and vgextend --restoremissing.");
|
||||
diff --git a/tools/command.c b/tools/command.c
|
||||
index bdd18d6..724040e 100644
|
||||
--- a/tools/command.c
|
||||
+++ b/tools/command.c
|
||||
@@ -137,6 +137,7 @@ static inline int configtype_arg(struct cmd_context *cmd __attribute__((unused))
|
||||
#define GET_VGNAME_FROM_OPTIONS 0x00001000
|
||||
#define CAN_USE_ONE_SCAN 0x00002000
|
||||
#define ALLOW_HINTS 0x00004000
|
||||
+#define ALLOW_EXPORTED 0x00008000
|
||||
|
||||
|
||||
/* create foo_CMD enums for command def ID's in command-lines.in */
|
||||
diff --git a/tools/commands.h b/tools/commands.h
|
||||
index 4006fab..c1670ae 100644
|
||||
--- a/tools/commands.h
|
||||
+++ b/tools/commands.h
|
||||
@@ -35,7 +35,7 @@ xx(help,
|
||||
|
||||
xx(fullreport,
|
||||
"Display full report",
|
||||
- PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | ALLOW_HINTS)
|
||||
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | ALLOW_HINTS | ALLOW_EXPORTED)
|
||||
|
||||
xx(lastlog,
|
||||
"Display last command's log report",
|
||||
@@ -71,7 +71,7 @@ xx(lvmconfig,
|
||||
|
||||
xx(lvmdiskscan,
|
||||
"List devices that may be used as physical volumes",
|
||||
- PERMITTED_READ_ONLY | ENABLE_ALL_DEVS)
|
||||
+ PERMITTED_READ_ONLY | ENABLE_ALL_DEVS | ALLOW_EXPORTED)
|
||||
|
||||
xx(lvmsadc,
|
||||
"Collect activity data",
|
||||
@@ -115,7 +115,7 @@ xx(pvresize,
|
||||
|
||||
xx(pvck,
|
||||
"Check metadata on physical volumes",
|
||||
- LOCKD_VG_SH)
|
||||
+ LOCKD_VG_SH | ALLOW_EXPORTED)
|
||||
|
||||
xx(pvcreate,
|
||||
"Initialize physical volume(s) for use by LVM",
|
||||
@@ -127,7 +127,7 @@ xx(pvdata,
|
||||
|
||||
xx(pvdisplay,
|
||||
"Display various attributes of physical volume(s)",
|
||||
- PERMITTED_READ_ONLY | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS)
|
||||
+ PERMITTED_READ_ONLY | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS | ALLOW_EXPORTED)
|
||||
|
||||
/* ALL_VGS_IS_DEFAULT is for polldaemon to find pvmoves in-progress using process_each_vg. */
|
||||
|
||||
@@ -145,11 +145,11 @@ xx(pvremove,
|
||||
|
||||
xx(pvs,
|
||||
"Display information about physical volumes",
|
||||
- PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS)
|
||||
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS | ALLOW_EXPORTED)
|
||||
|
||||
xx(pvscan,
|
||||
"List all physical volumes",
|
||||
- PERMITTED_READ_ONLY | LOCKD_VG_SH)
|
||||
+ PERMITTED_READ_ONLY | LOCKD_VG_SH | ALLOW_EXPORTED)
|
||||
|
||||
xx(segtypes,
|
||||
"List available segment types",
|
||||
@@ -165,11 +165,11 @@ xx(tags,
|
||||
|
||||
xx(vgcfgbackup,
|
||||
"Backup volume group configuration(s)",
|
||||
- PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH)
|
||||
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | ALLOW_EXPORTED)
|
||||
|
||||
xx(vgcfgrestore,
|
||||
"Restore volume group configuration",
|
||||
- 0)
|
||||
+ ALLOW_EXPORTED)
|
||||
|
||||
xx(vgchange,
|
||||
"Change volume group attributes",
|
||||
@@ -189,7 +189,7 @@ xx(vgcreate,
|
||||
|
||||
xx(vgdisplay,
|
||||
"Display volume group information",
|
||||
- PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS)
|
||||
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS | ALLOW_EXPORTED)
|
||||
|
||||
xx(vgexport,
|
||||
"Unregister volume group(s) from the system",
|
||||
@@ -201,10 +201,11 @@ xx(vgextend,
|
||||
|
||||
xx(vgimport,
|
||||
"Register exported volume group with system",
|
||||
- ALL_VGS_IS_DEFAULT)
|
||||
+ ALL_VGS_IS_DEFAULT | ALLOW_EXPORTED)
|
||||
|
||||
xx(vgimportclone,
|
||||
- "Import a VG from cloned PVs", 0)
|
||||
+ "Import a VG from cloned PVs",
|
||||
+ ALLOW_EXPORTED)
|
||||
|
||||
xx(vgmerge,
|
||||
"Merge volume groups",
|
||||
@@ -224,15 +225,15 @@ xx(vgremove,
|
||||
|
||||
xx(vgrename,
|
||||
"Rename a volume group",
|
||||
- ALLOW_UUID_AS_NAME)
|
||||
+ ALLOW_UUID_AS_NAME | ALLOW_EXPORTED)
|
||||
|
||||
xx(vgs,
|
||||
"Display information about volume groups",
|
||||
- PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS)
|
||||
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | CAN_USE_ONE_SCAN | ALLOW_HINTS | ALLOW_EXPORTED)
|
||||
|
||||
xx(vgscan,
|
||||
"Search for all volume groups",
|
||||
- PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH)
|
||||
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | LOCKD_VG_SH | ALLOW_EXPORTED)
|
||||
|
||||
xx(vgsplit,
|
||||
"Move physical volumes into a new or existing volume group",
|
||||
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
|
||||
index 3fec702..30f9d81 100644
|
||||
--- a/tools/lvmcmdline.c
|
||||
+++ b/tools/lvmcmdline.c
|
||||
@@ -2315,6 +2315,8 @@ static int _get_current_settings(struct cmd_context *cmd)
|
||||
if (cmd->cname->flags & CAN_USE_ONE_SCAN)
|
||||
cmd->can_use_one_scan = 1;
|
||||
|
||||
+ cmd->include_exported_vgs = (cmd->cname->flags & ALLOW_EXPORTED) ? 1 : 0;
|
||||
+
|
||||
cmd->scan_lvs = find_config_tree_bool(cmd, devices_scan_lvs_CFG, NULL);
|
||||
|
||||
/*
|
||||
diff --git a/tools/pvchange.c b/tools/pvchange.c
|
||||
index f37fd91..1ece34a 100644
|
||||
--- a/tools/pvchange.c
|
||||
+++ b/tools/pvchange.c
|
||||
@@ -35,11 +35,6 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
params->total++;
|
||||
|
||||
- if (vg && vg_is_exported(vg)) {
|
||||
- log_error("Volume group %s is exported", vg->name);
|
||||
- goto bad;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* The primary location of this check is in vg_write(), but it needs
|
||||
* to be copied here to prevent the pv_write() which is called before
|
||||
@@ -239,7 +234,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
clear_hint_file(cmd);
|
||||
|
||||
- ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _pvchange_single);
|
||||
+ ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE, handle, _pvchange_single);
|
||||
|
||||
log_print_unless_silent("%d physical volume%s changed / %d physical volume%s not changed",
|
||||
params.done, params.done == 1 ? "" : "s",
|
||||
diff --git a/tools/pvresize.c b/tools/pvresize.c
|
||||
index c7e750d..2c7f543 100644
|
||||
--- a/tools/pvresize.c
|
||||
+++ b/tools/pvresize.c
|
||||
@@ -36,11 +36,6 @@ static int _pvresize_single(struct cmd_context *cmd,
|
||||
}
|
||||
params->total++;
|
||||
|
||||
- if (vg && vg_is_exported(vg)) {
|
||||
- log_error("Volume group %s is exported", vg->name);
|
||||
- return ECMD_FAILED;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* Needed to change a property on an orphan PV.
|
||||
* i.e. the global lock is only needed for orphans.
|
||||
@@ -93,7 +88,7 @@ int pvresize(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
handle->custom_handle = ¶ms;
|
||||
|
||||
- ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _pvresize_single);
|
||||
+ ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE, handle, _pvresize_single);
|
||||
|
||||
log_print_unless_silent("%d physical volume(s) resized or updated / %d physical volume(s) "
|
||||
"not resized", params.done, params.total - params.done);
|
||||
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||
index 506ad2d..b2313f8 100644
|
||||
--- a/tools/toollib.c
|
||||
+++ b/tools/toollib.c
|
||||
@@ -223,6 +223,17 @@ static int _ignore_vg(struct cmd_context *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (read_error & FAILED_EXPORTED) {
|
||||
+ if (arg_vgnames && str_list_match_item(arg_vgnames, vg_name)) {
|
||||
+ log_error("Volume group %s is exported", vg_name);
|
||||
+ return 1;
|
||||
+ } else {
|
||||
+ read_error &= ~FAILED_EXPORTED; /* Check for other errors */
|
||||
+ log_verbose("Skipping exported volume group %s", vg_name);
|
||||
+ *skip = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Commands that operate on "all vgs" shouldn't be bothered by
|
||||
* skipping a foreign VG, and the command shouldn't fail when
|
||||
@@ -3032,11 +3043,6 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
dm_list_init(&final_lvs);
|
||||
dm_list_init(&found_arg_lvnames);
|
||||
|
||||
- if (!vg_check_status(vg, EXPORTED_VG)) {
|
||||
- ret_max = ECMD_FAILED;
|
||||
- goto_out;
|
||||
- }
|
||||
-
|
||||
if (tags_in && !dm_list_empty(tags_in))
|
||||
tags_supplied = 1;
|
||||
|
||||
@@ -4161,6 +4167,7 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
|
||||
int process_all_pvs,
|
||||
int process_all_devices,
|
||||
int skip,
|
||||
+ uint32_t error_flags,
|
||||
struct processing_handle *handle,
|
||||
process_single_pv_fn_t process_single_pv)
|
||||
{
|
||||
@@ -4216,21 +4223,42 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
process_pv = process_all_pvs;
|
||||
+ dil = NULL;
|
||||
|
||||
/* Remove each arg_devices entry as it is processed. */
|
||||
|
||||
- if (!process_pv && !dm_list_empty(arg_devices) &&
|
||||
- (dil = _device_list_find_dev(arg_devices, pv->dev))) {
|
||||
- process_pv = 1;
|
||||
- _device_list_remove(arg_devices, dil->dev);
|
||||
+ if (arg_devices && !dm_list_empty(arg_devices)) {
|
||||
+ if ((dil = _device_list_find_dev(arg_devices, pv->dev)))
|
||||
+ _device_list_remove(arg_devices, dil->dev);
|
||||
}
|
||||
|
||||
+ if (!process_pv && dil)
|
||||
+ process_pv = 1;
|
||||
+
|
||||
if (!process_pv && !dm_list_empty(arg_tags) &&
|
||||
str_list_match_list(arg_tags, &pv->tags, NULL))
|
||||
process_pv = 1;
|
||||
|
||||
process_pv = process_pv && select_match_pv(cmd, handle, vg, pv) && _select_matches(handle);
|
||||
|
||||
+ /*
|
||||
+ * The command has asked to process a specific PV
|
||||
+ * named on the command line, but the VG containing
|
||||
+ * that PV cannot be accessed. In this case report
|
||||
+ * and return an error. If the inaccessible PV is
|
||||
+ * not explicitly named on the command line, it is
|
||||
+ * silently skipped.
|
||||
+ */
|
||||
+ if (process_pv && skip && dil && error_flags) {
|
||||
+ if (error_flags & FAILED_EXPORTED)
|
||||
+ log_error("Cannot use PV %s in exported VG %s.", pv_name, vg->name);
|
||||
+ if (error_flags & FAILED_SYSTEMID)
|
||||
+ log_error("Cannot use PV %s in foreign VG %s.", pv_name, vg->name);
|
||||
+ if (error_flags & (FAILED_LOCK_TYPE | FAILED_LOCK_MODE))
|
||||
+ log_error("Cannot use PV %s in shared VG %s.", pv_name, vg->name);
|
||||
+ ret_max = ECMD_FAILED;
|
||||
+ }
|
||||
+
|
||||
if (process_pv) {
|
||||
if (skip)
|
||||
log_verbose("Skipping PV %s in VG %s.", pv_name, vg->name);
|
||||
@@ -4352,6 +4380,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||
|
||||
log_debug("Processing PVs in VG %s", vg_name);
|
||||
|
||||
+ error_flags = 0;
|
||||
+
|
||||
vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state, &error_flags, &error_vg);
|
||||
if (_ignore_vg(cmd, error_flags, error_vg, vg_name, NULL, read_flags, &skip, ¬found)) {
|
||||
stack;
|
||||
@@ -4359,7 +4389,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||
report_log_ret_code(ret_max);
|
||||
if (!skip)
|
||||
goto endvg;
|
||||
- /* Drop through to eliminate a clustered VG's PVs from the devices list */
|
||||
+ /* Drop through to eliminate unmpermitted PVs from the devices list */
|
||||
}
|
||||
if (notfound)
|
||||
goto endvg;
|
||||
@@ -4370,7 +4400,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||
*/
|
||||
|
||||
ret = _process_pvs_in_vg(cmd, vg ? vg : error_vg, all_devices, arg_devices, arg_tags,
|
||||
- process_all_pvs, process_all_devices, skip,
|
||||
+ process_all_pvs, process_all_devices, skip, error_flags,
|
||||
handle, process_single_pv);
|
||||
if (ret != ECMD_PROCESSED)
|
||||
stack;
|
||||
diff --git a/tools/tools.h b/tools/tools.h
|
||||
index 69132a5..b78c471 100644
|
||||
--- a/tools/tools.h
|
||||
+++ b/tools/tools.h
|
||||
@@ -136,6 +136,8 @@ struct arg_value_group_list {
|
||||
#define CAN_USE_ONE_SCAN 0x00002000
|
||||
/* Command can use hints file */
|
||||
#define ALLOW_HINTS 0x00004000
|
||||
+/* Command can access exported vg. */
|
||||
+#define ALLOW_EXPORTED 0x00008000
|
||||
|
||||
|
||||
void usage(const char *name);
|
||||
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
||||
index a17f456..1ef94d6 100644
|
||||
--- a/tools/vgchange.c
|
||||
+++ b/tools/vgchange.c
|
||||
@@ -630,13 +630,6 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||
{ detachprofile_ARG, &_vgchange_profile },
|
||||
};
|
||||
|
||||
- if (vg_is_exported(vg)) {
|
||||
- if (cmd->command->command_enum == vgchange_monitor_CMD)
|
||||
- return ECMD_PROCESSED;
|
||||
- log_error("Volume group \"%s\" is exported", vg_name);
|
||||
- return ECMD_FAILED;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* FIXME: DEFAULT_BACKGROUND_POLLING should be "unspecified".
|
||||
* If --poll is explicitly provided use it; otherwise polling
|
||||
@@ -982,11 +975,6 @@ static int _vgchange_locktype_single(struct cmd_context *cmd, const char *vg_nam
|
||||
struct volume_group *vg,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
- if (vg_is_exported(vg)) {
|
||||
- log_error("Volume group \"%s\" is exported", vg_name);
|
||||
- return ECMD_FAILED;
|
||||
- }
|
||||
-
|
||||
if (!archive(vg))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
@@ -1145,11 +1133,14 @@ int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
/* Disable the lockd_gl in process_each_vg. */
|
||||
cmd->lockd_gl_disable = 1;
|
||||
+ } else {
|
||||
+ /* If the VG was started when it was exported, allow it to be stopped. */
|
||||
+ cmd->include_exported_vgs = 1;
|
||||
}
|
||||
|
||||
handle->custom_handle = &vp;
|
||||
|
||||
- ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_ALLOW_EXPORTED, 0, handle, &_vgchange_lock_start_stop_single);
|
||||
+ ret = process_each_vg(cmd, argc, argv, NULL, NULL, 0, 0, handle, &_vgchange_lock_start_stop_single);
|
||||
|
||||
/* Wait for lock-start ops that were initiated in vgchange_lockstart. */
|
||||
|
||||
@@ -1178,11 +1169,6 @@ static int _vgchange_systemid_single(struct cmd_context *cmd, const char *vg_nam
|
||||
struct volume_group *vg,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
- if (vg_is_exported(vg)) {
|
||||
- log_error("Volume group \"%s\" is exported", vg_name);
|
||||
- return ECMD_FAILED;
|
||||
- }
|
||||
-
|
||||
if (!archive(vg))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
diff --git a/tools/vgck.c b/tools/vgck.c
|
||||
index 90fc5a3..46ad594 100644
|
||||
--- a/tools/vgck.c
|
||||
+++ b/tools/vgck.c
|
||||
@@ -71,9 +71,6 @@ static int vgck_single(struct cmd_context *cmd __attribute__((unused)),
|
||||
struct volume_group *vg,
|
||||
struct processing_handle *handle __attribute__((unused)))
|
||||
{
|
||||
- if (!vg_check_status(vg, EXPORTED_VG))
|
||||
- return_ECMD_FAILED;
|
||||
-
|
||||
if (!vg_validate(vg))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
diff --git a/tools/vgimport.c b/tools/vgimport.c
|
||||
index 26c6363..0d8b0f2 100644
|
||||
--- a/tools/vgimport.c
|
||||
+++ b/tools/vgimport.c
|
||||
@@ -87,8 +87,6 @@ int vgimport(struct cmd_context *cmd, int argc, char **argv)
|
||||
cmd->handles_missing_pvs = 1;
|
||||
}
|
||||
|
||||
- return process_each_vg(cmd, argc, argv, NULL, NULL,
|
||||
- READ_FOR_UPDATE | READ_ALLOW_EXPORTED,
|
||||
- 0, NULL,
|
||||
- &_vgimport_single);
|
||||
+ return process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE,
|
||||
+ 0, NULL, &_vgimport_single);
|
||||
}
|
||||
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
|
||||
index a3af841..be01861 100644
|
||||
--- a/tools/vgimportclone.c
|
||||
+++ b/tools/vgimportclone.c
|
||||
@@ -235,7 +235,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
log_debug("Finding devices to import.");
|
||||
cmd->cname->flags |= ENABLE_DUPLICATE_DEVS;
|
||||
- process_each_pv(cmd, argc, argv, NULL, 0, READ_ALLOW_EXPORTED, handle, _vgimportclone_pv_single);
|
||||
+ process_each_pv(cmd, argc, argv, NULL, 0, 0, handle, _vgimportclone_pv_single);
|
||||
|
||||
if (vp.found_args != argc) {
|
||||
log_error("Failed to find all devices.");
|
||||
@@ -342,7 +342,7 @@ retry_name:
|
||||
|
||||
clear_hint_file(cmd);
|
||||
|
||||
- ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, 0, handle, _vgimportclone_vg_single);
|
||||
+ ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE, 0, handle, _vgimportclone_vg_single);
|
||||
|
||||
unlock_vg(cmd, NULL, vp.new_vgname);
|
||||
out:
|
||||
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
|
||||
index bc1f5b6..b001ccb 100644
|
||||
--- a/tools/vgreduce.c
|
||||
+++ b/tools/vgreduce.c
|
||||
@@ -135,7 +135,7 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
{
|
||||
int r;
|
||||
|
||||
- if (!vg_check_status(vg, EXPORTED_VG | LVM_WRITE | RESIZEABLE_VG))
|
||||
+ if (!vg_check_status(vg, LVM_WRITE | RESIZEABLE_VG))
|
||||
return ECMD_FAILED;
|
||||
|
||||
r = vgreduce_single(cmd, vg, pv, 1);
|
||||
@@ -250,8 +250,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
init_ignore_suspended_devices(1);
|
||||
|
||||
- process_each_vg(cmd, 0, NULL, vg_name, NULL,
|
||||
- READ_FOR_UPDATE | READ_ALLOW_EXPORTED,
|
||||
+ process_each_vg(cmd, 0, NULL, vg_name, NULL, READ_FOR_UPDATE,
|
||||
0, handle, &_vgreduce_repair_single);
|
||||
|
||||
if (vp.already_consistent) {
|
||||
diff --git a/tools/vgremove.c b/tools/vgremove.c
|
||||
index 23640f6..8f73297 100644
|
||||
--- a/tools/vgremove.c
|
||||
+++ b/tools/vgremove.c
|
||||
@@ -42,9 +42,6 @@ static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
|
||||
unsigned lv_count, missing;
|
||||
int ret;
|
||||
|
||||
- if (!vg_check_status(vg, EXPORTED_VG))
|
||||
- return_ECMD_FAILED;
|
||||
-
|
||||
lv_count = vg_visible_lvs(vg);
|
||||
|
||||
if (lv_count) {
|
||||
diff --git a/tools/vgrename.c b/tools/vgrename.c
|
||||
index 4735e8b..8b76d0b 100644
|
||||
--- a/tools/vgrename.c
|
||||
+++ b/tools/vgrename.c
|
||||
@@ -233,8 +233,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
handle->custom_handle = &vp;
|
||||
|
||||
- ret = process_each_vg(cmd, 0, NULL, vg_name_old, NULL,
|
||||
- READ_FOR_UPDATE | READ_ALLOW_EXPORTED,
|
||||
+ ret = process_each_vg(cmd, 0, NULL, vg_name_old, NULL, READ_FOR_UPDATE,
|
||||
0, handle, _vgrename_single);
|
||||
|
||||
/* Needed if process_each_vg returns error before calling _single. */
|
||||
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
|
||||
index 61cb13b..1bcc308 100644
|
||||
--- a/tools/vgsplit.c
|
||||
+++ b/tools/vgsplit.c
|
||||
@@ -665,8 +665,16 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
|
||||
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);
|
||||
+
|
||||
+ /*
|
||||
+ * This command uses the exported vg flag internally, but
|
||||
+ * exported VGs are not allowed to be split from the command
|
||||
+ * level, so ALLOW_EXPORTED is not set in commands.h.
|
||||
+ */
|
||||
+ cmd->include_exported_vgs = 1;
|
||||
+
|
||||
+ vg_to = vg_read_for_update(cmd, vg_name_to, NULL, 0, 0);
|
||||
+
|
||||
if (vg_read_error(vg_to)) {
|
||||
log_error("Volume group \"%s\" became inconsistent: "
|
||||
"please fix manually", vg_name_to);
|
89
SOURCES/lvm2-2_03_06-increase-soft-open-file-limit.patch
Normal file
89
SOURCES/lvm2-2_03_06-increase-soft-open-file-limit.patch
Normal file
@ -0,0 +1,89 @@
|
||||
lib/label/label.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 61 insertions(+)
|
||||
|
||||
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||
index 72be5ec..09bbb92 100644
|
||||
--- a/lib/label/label.c
|
||||
+++ b/lib/label/label.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
+#include <sys/resource.h>
|
||||
|
||||
/* FIXME Allow for larger labels? Restricted to single sector currently */
|
||||
|
||||
@@ -867,6 +868,57 @@ static void _free_hints(struct dm_list *hints)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * We don't know how many of num_devs will be PVs that we need to
|
||||
+ * keep open, but if it's greater than the soft limit, then we'll
|
||||
+ * need the soft limit raised, so do that before starting.
|
||||
+ *
|
||||
+ * If opens approach the raised soft/hard limit while scanning, then
|
||||
+ * we could also attempt to raise the soft/hard limits during the scan.
|
||||
+ */
|
||||
+
|
||||
+#define BASE_FD_COUNT 32 /* Number of open files we want apart from devs */
|
||||
+
|
||||
+static void _prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
|
||||
+{
|
||||
+ struct rlimit old, new;
|
||||
+ unsigned int want = num_devs + BASE_FD_COUNT;
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = prlimit(0, RLIMIT_NOFILE, NULL, &old);
|
||||
+ if (rv < 0) {
|
||||
+ log_debug("Checking fd limit for num_devs %u failed %d", num_devs, errno);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ log_debug("Checking fd limit for num_devs %u want %u soft %lld hard %lld",
|
||||
+ num_devs, want, (long long)old.rlim_cur, (long long)old.rlim_max);
|
||||
+
|
||||
+ /* Current soft limit is enough */
|
||||
+ if (old.rlim_cur > want)
|
||||
+ return;
|
||||
+
|
||||
+ /* Soft limit already raised to max */
|
||||
+ if (old.rlim_cur == old.rlim_max)
|
||||
+ return;
|
||||
+
|
||||
+ /* Raise soft limit up to hard/max limit */
|
||||
+ new.rlim_cur = old.rlim_max;
|
||||
+ new.rlim_max = old.rlim_max;
|
||||
+
|
||||
+ log_debug("Setting fd limit for num_devs %u soft %lld hard %lld",
|
||||
+ num_devs, (long long)new.rlim_cur, (long long)new.rlim_max);
|
||||
+
|
||||
+ rv = prlimit(0, RLIMIT_NOFILE, &new, &old);
|
||||
+ if (rv < 0) {
|
||||
+ if (errno == EPERM)
|
||||
+ log_warn("WARNING: permission error setting open file limit for scanning %u devices.", num_devs);
|
||||
+ else
|
||||
+ log_warn("WARNING: cannot set open file limit for scanning %u devices.", num_devs);
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Scan devices on the system to discover which are LVM devices.
|
||||
* Info about the LVM devices (PVs) is saved in lvmcache in a
|
||||
* basic/summary form (info/vginfo structs). The vg_read phase
|
||||
@@ -984,6 +1036,15 @@ int label_scan(struct cmd_context *cmd)
|
||||
log_debug("Will scan %d devices skip %d", dm_list_size(&scan_devs), dm_list_size(&all_devs));
|
||||
|
||||
/*
|
||||
+ * If the total number of devices exceeds the soft open file
|
||||
+ * limit, then increase the soft limit to the hard/max limit
|
||||
+ * in case the number of PVs in scan_devs (it's only the PVs
|
||||
+ * which we want to keep open) is higher than the current
|
||||
+ * soft limit.
|
||||
+ */
|
||||
+ _prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
|
||||
+
|
||||
+ /*
|
||||
* Do the main scan.
|
||||
*/
|
||||
_scan_list(cmd, cmd->filter, &scan_devs, NULL);
|
@ -0,0 +1,22 @@
|
||||
tools/command-lines.in | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/command-lines.in b/tools/command-lines.in
|
||||
index 73a1e64..f914650 100644
|
||||
--- a/tools/command-lines.in
|
||||
+++ b/tools/command-lines.in
|
||||
@@ -343,13 +343,11 @@ DESC: Convert LV to striped.
|
||||
RULE: all not lv_is_locked lv_is_pvmove
|
||||
|
||||
lvconvert --type mirror LV
|
||||
-OO: --mirrors SNumber, --regionsize RegionSize, --interval Number, --mirrorlog MirrorLog, OO_LVCONVERT
|
||||
+OO: --mirrors SNumber, --stripes_long Number, --stripesize SizeKB, --regionsize RegionSize, --interval Number, --mirrorlog MirrorLog, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
ID: lvconvert_raid_types
|
||||
DESC: Convert LV to type mirror (also see type raid1),
|
||||
-DESC: (also see lvconvert --mirrors).
|
||||
RULE: all not lv_is_locked lv_is_pvmove
|
||||
-FLAGS: SECONDARY_SYNTAX
|
||||
|
||||
# When LV is already raid, this changes the raid layout
|
||||
# (changing layout of raid0 and raid1 not allowed.)
|
@ -0,0 +1,51 @@
|
||||
lib/metadata/metadata.c | 26 ++++++++++++++++++++++++--
|
||||
1 file changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
|
||||
index dc1b501..f7eeb52 100644
|
||||
--- a/lib/metadata/metadata.c
|
||||
+++ b/lib/metadata/metadata.c
|
||||
@@ -3504,19 +3504,41 @@ static void _set_pv_device(struct format_instance *fid,
|
||||
struct physical_volume *pv)
|
||||
{
|
||||
char buffer[64] __attribute__((aligned(8)));
|
||||
+ struct cmd_context *cmd = fid->fmt->cmd;
|
||||
+ struct device *dev;
|
||||
uint64_t size;
|
||||
|
||||
- if (!(pv->dev = lvmcache_device_from_pvid(fid->fmt->cmd, &pv->id, &pv->label_sector))) {
|
||||
+ if (!(dev = lvmcache_device_from_pvid(cmd, &pv->id, &pv->label_sector))) {
|
||||
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
|
||||
buffer[0] = '\0';
|
||||
|
||||
- if (fid->fmt->cmd && !fid->fmt->cmd->pvscan_cache_single)
|
||||
+ if (cmd && !cmd->pvscan_cache_single)
|
||||
log_warn("WARNING: Couldn't find device with uuid %s.", buffer);
|
||||
else
|
||||
log_debug_metadata("Couldn't find device with uuid %s.", buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
+ * If the device and PV are not the size, it's a clue that we might
|
||||
+ * be reading an MD component (but not necessarily). Skip this check:
|
||||
+ * . if md component detection is disabled
|
||||
+ * . if we are already doing full a md check in label scan
|
||||
+ * . if md_component_checks is auto, not none (full means use_full_md_check is set)
|
||||
+ */
|
||||
+ if (dev && (pv->size != dev->size) && cmd &&
|
||||
+ cmd->md_component_detection &&am |