main - apply multipath_component_detection=0 to duplicate PV handling
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=99ce09ae778c2cc4aa2...
Commit: 99ce09ae778c2cc4aa2611e425bba5287b8b9513
Parent: c0f8e6675c62332263acdc7c3c2f61eca20bd60f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jul 25 13:50:43 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 25 13:50:43 2022 -0500
apply multipath_component_detection=0 to duplicate PV handling
multipath_component_detection=0 has always applied to the filter-based
component detection. Also apply this setting to the duplicate-PV
handling which also eliminates multipath components (based on duplicate
PVs having the same wwid.)
---
lib/cache/lvmcache.c | 3 +++
test/shell/duplicate-pvs-multipath.sh | 10 +++++++---
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index a1c4a61c8..00916885c 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -652,6 +652,9 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
*dev_mpath = NULL;
+ if (!find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL))
+ return 0;
+
/* This function only makes sense with more than one dev. */
if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) {
log_debug("Skip multipath component checks with single device for PVID %s", pvid);
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
index 59c15b0d4..bc98d2d5a 100644
--- a/test/shell/duplicate-pvs-multipath.sh
+++ b/test/shell/duplicate-pvs-multipath.sh
@@ -24,9 +24,13 @@ modprobe --dry-run scsi_debug || skip
multipath -l || skip
multipath -l | grep scsi_debug && skip
-# Turn off multipath_component_detection so that the duplicate
-# resolution of mpath components is used.
-aux lvmconf 'devices/multipath_component_detection = 0'
+# FIXME: setting multipath_component_detection=0 now also disables
+# the wwid-based mpath component detection, so this test will need
+# to find another way to disable only the filter-mpath code (using
+# sysfs and multipath/wwids) while keeping the code enabled that
+# eliminates duplicates based on their matching wwids which this
+# tries to test.
+
# Prevent wwids from being used for filtering.
aux lvmconf 'devices/multipath_wwids_file = "/dev/null"'
# Need to use /dev/mapper/mpath
1 year, 2 months
main - make: generate
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c0f8e6675c62332263a...
Commit: c0f8e6675c62332263acdc7c3c2f61eca20bd60f
Parent: 4d2f9a4ff3fbfe4ee0df08478d81ea10f75823de
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 11 01:02:22 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
make: generate
---
man/pvdisplay.8_pregen | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen
index 23d41b29b..e7767d0c4 100644
--- a/man/pvdisplay.8_pregen
+++ b/man/pvdisplay.8_pregen
@@ -61,6 +61,8 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
+.br
[ \fB--separator\fP \fIString\fP ]
.br
[ \fB--shared\fP ]
@@ -320,6 +322,16 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
+\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
+.br
+Overrides current output format for reports which is defined globally by
+the report/output_format setting in \fBlvm.conf\fP(5).
+\fBbasic\fP is the original format with columns and rows.
+If there is more than one report per command, each report is prefixed
+with the report name for identification. \fBjson\fP produces report
+output in JSON format. See \fBlvmreport\fP(7) for more information.
+.
+.HP
\fB-S\fP|\fB--select\fP \fIString\fP
.br
Select objects for processing and reporting based on specified criteria.
1 year, 2 months
main - cov: restore disable_dm_devs also for error path
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4d2f9a4ff3fbfe4ee0d...
Commit: 4d2f9a4ff3fbfe4ee0df08478d81ea10f75823de
Parent: 5c463584f6b0541cc0144335b49afd2d94745928
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Jul 9 02:50:08 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
cov: restore disable_dm_devs also for error path
Keep the structure correct for failing error path,
alhtough likely this particual var will not be used.
---
lib/activate/dev_manager.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 2cae3bed1..8cb31008e 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -3842,11 +3842,12 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
if (!seg_is_striped_target(first_seg(lv)) || (action == CLEAN))
dm->cmd->disable_dm_devs = 1;
- if (!(dtree = _create_partial_dtree(dm, lv, laopts->origin_only)))
- return_0;
-
+ dtree = _create_partial_dtree(dm, lv, laopts->origin_only);
dm->cmd->disable_dm_devs = tmp_state;
+ if (!dtree)
+ return_0;
+
if (!(root = dm_tree_find_node(dtree, 0, 0))) {
log_error("Lost dependency tree root node.");
goto out_no_root;
1 year, 2 months
main - cov: remove unused headers
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5c463584f6b0541cc01...
Commit: 5c463584f6b0541cc0144335b49afd2d94745928
Parent: 493acb9195cef185b38ae4e4ffb84b984e5cc08c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Jul 9 02:45:21 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
cov: remove unused headers
---
lib/device/online.c | 1 -
lib/label/hints.c | 1 -
libdaemon/server/daemon-server.c | 1 -
libdm/libdm-deptree.c | 1 -
4 files changed, 4 deletions(-)
diff --git a/lib/device/online.c b/lib/device/online.c
index 024485bb3..79652d990 100644
--- a/lib/device/online.c
+++ b/lib/device/online.c
@@ -16,7 +16,6 @@
#include "lib/misc/lib.h"
#include "lib/commands/toolcontext.h"
#include "lib/device/device.h"
-#include "lib/device/device_id.h"
#include "lib/device/online.h"
#include <dirent.h>
diff --git a/lib/label/hints.c b/lib/label/hints.c
index edce6f517..825788369 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -146,7 +146,6 @@
#include "lib/label/hints.h"
#include "lib/device/dev-type.h"
#include "lib/device/device_id.h"
-#include "lib/device/online.h"
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 96cfc392e..dde7f5982 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -20,7 +20,6 @@
#include <errno.h>
#include <fcntl.h> /* help musl C */
#include <pthread.h>
-#include <sys/file.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/time.h>
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index c14b6ef56..33a80cf4d 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -19,7 +19,6 @@
#include "libdm/misc/dm-ioctl.h"
#include <stdarg.h>
-#include <sys/param.h>
#include <sys/utsname.h>
#define MAX_TARGET_PARAMSIZE 500000
1 year, 2 months
main - vdo: suffle code for better error path handling
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=493acb9195cef185b38...
Commit: 493acb9195cef185b38ae4e4ffb84b984e5cc08c
Parent: e2e31d9acf1b96ab741c22dc0a2fefd672996d3a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Jul 9 21:33:57 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
vdo: suffle code for better error path handling
For failing dm_ no need to report 2nd. error,
but we missed to report error with 'updated==NULL'.
---
tools/toollib.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 544791808..c29ba2ab4 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1347,23 +1347,23 @@ int get_vdo_settings(struct cmd_context *cmd,
u |= VDO_CHANGE_ONLINE;
}
- if (updated) {
- // validation of updated VDO option
- if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) {
-err:
- if (is_lvchange)
- log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
- option);
- else
- log_error("Invalid argument for VDO setting \"vdo_%s\".",
- option);
- goto out;
- }
+ // validation of updated VDO option
+ if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */))
+ goto_out;
+ if (updated)
*updated = u;
- }
- r = 1;
+ r = 1; // success
+ goto out;
+err:
+ if (is_lvchange)
+ log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
+ option);
+ else
+ log_error("Invalid argument for VDO setting \"vdo_%s\".",
+ option);
+
out:
if (result)
dm_config_destroy(result);
1 year, 2 months
main - vdo: enhance lvcreate validation
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=e2e31d9acf1b96ab741...
Commit: e2e31d9acf1b96ab741c22dc0a2fefd672996d3a
Parent: 1c18ed3b4ab2f2d5a15995b8f0a18d7d1c4d60ca
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 8 23:38:34 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
vdo: enhance lvcreate validation
When creating VDO pool based of % values, lvm2 is now more clever
and avoids to create 'unsupportable' sizes of physical backend
volumes as 16TiB is maximum size supported by VDO target
(and also limited by maximum supportable slabs (8192) based on slab
size.
If the requested virtual size is approaching max supported size 4PiB,
switch header size to 0.
---
lib/metadata/metadata-exported.h | 2 ++
lib/metadata/vdo_manip.c | 14 ++++++++++++
tools/lvcreate.c | 48 +++++++++++++++++++++++++++++++++-------
3 files changed, 56 insertions(+), 8 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 191bf4326..6180ac88e 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1364,6 +1364,8 @@ const char *get_vdo_operating_mode_name(enum dm_vdo_operating_mode mode);
const char *get_vdo_write_policy_name(enum dm_vdo_write_policy policy);
uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg);
int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg);
+uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
+ uint32_t extent_size);
int parse_vdo_pool_status(struct dm_pool *mem, const struct logical_volume *vdo_pool_lv,
const char *params, const struct dm_info *dminfo,
struct lv_status_vdo *status);
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
index a7de55d36..250080b25 100644
--- a/lib/metadata/vdo_manip.c
+++ b/lib/metadata/vdo_manip.c
@@ -127,6 +127,20 @@ int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg)
return 1;
}
+uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
+ uint32_t extent_size)
+{
+ uint64_t max_extents = (DM_VDO_PHYSICAL_SIZE_MAXIMUM + extent_size - 1) / extent_size;
+ uint64_t max_slab_extents = ((extent_size - 1 + DM_VDO_SLABS_MAXIMUM *
+ ((uint64_t)vtp->slab_size_mb << (20 - SECTOR_SHIFT))) /
+ extent_size);
+
+ max_extents = (max_slab_extents < max_extents) ? max_slab_extents : max_extents;
+
+ return (max_extents > UINT32_MAX) ? UINT32_MAX : (uint32_t)max_extents;
+}
+
+
static int _sysfs_get_kvdo_value(const char *dm_name, const struct dm_info *dminfo,
const char *vdo_param, uint64_t *value)
{
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 6bdbe943e..9bf5f4821 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -253,6 +253,7 @@ static int _update_extents_params(struct volume_group *vg,
uint32_t stripesize_extents;
uint32_t extents;
uint32_t base_calc_extents;
+ uint32_t vdo_pool_max_extents;
if (lcp->size &&
!(lp->extents = extents_from_size(vg->cmd, lcp->size,
@@ -322,6 +323,23 @@ static int _update_extents_params(struct volume_group *vg,
return 0;
}
+ if (seg_is_vdo(lp)) {
+ vdo_pool_max_extents = get_vdo_pool_max_extents(&lp->vdo_params, vg->extent_size);
+ if (extents > vdo_pool_max_extents) {
+ if (lcp->percent == PERCENT_NONE) {
+ log_error("Can't use %s size. Maximal supported VDO POOL volume size with slab size %s is %s.",
+ display_size(vg->cmd, (uint64_t)vg->extent_size * extents),
+ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)),
+ display_size(vg->cmd, (uint64_t)vg->extent_size * vdo_pool_max_extents));
+ return 0;
+ }
+ extents = vdo_pool_max_extents;
+ log_verbose("Using maximal supported VDO POOL volume size %s (with slab size %s).",
+ display_size(vg->cmd, (uint64_t)vg->extent_size * extents),
+ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)));
+ }
+ }
+
if (lcp->percent != PERCENT_NONE) {
/* FIXME Don't do the adjustment for parallel allocation with PERCENT_ORIGIN! */
lp->approx_alloc = 1;
@@ -699,15 +717,23 @@ static int _read_cache_params(struct cmd_context *cmd,
}
static int _read_vdo_params(struct cmd_context *cmd,
- struct lvcreate_params *lp)
+ struct lvcreate_params *lp,
+ struct lvcreate_cmdline_params *lcp)
{
if (!seg_is_vdo(lp))
return 1;
// prefiling settings here
- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
+ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
return_0;
+ if ((lcp->virtual_size <= DM_VDO_LOGICAL_SIZE_MAXIMUM) &&
+ ((lcp->virtual_size + lp->vdo_pool_header_size) > DM_VDO_LOGICAL_SIZE_MAXIMUM)) {
+ log_verbose("Dropping VDO pool header size to 0 to support maximal size %s.",
+ display_size(cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM));
+ lp->vdo_pool_header_size = 0;
+ }
+
// override with optional vdo settings
if (!get_vdo_settings(cmd, &lp->vdo_params, NULL))
return_0;
@@ -1203,7 +1229,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
&lp->pool_metadata_size, &lp->pool_metadata_spare,
&lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) ||
!_read_cache_params(cmd, lp) ||
- !_read_vdo_params(cmd, lp) ||
+ !_read_vdo_params(cmd, lp, lcp) ||
!_read_mirror_and_raid_params(cmd, lp))
return_0;
@@ -1589,13 +1615,19 @@ static int _check_pool_parameters(struct cmd_context *cmd,
}
static int _check_vdo_parameters(struct volume_group *vg, struct lvcreate_params *lp,
- struct lvcreate_cmdline_params *lcp)
+ struct lvcreate_cmdline_params *lcp)
{
- if (seg_is_vdo(lp) && lp->snapshot) {
+ if (lp->snapshot) {
log_error("Please either create VDO or snapshot.");
return 0;
}
+ if (lcp->virtual_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) {
+ log_error("Maximal supported VDO virtual size is %s.",
+ display_size(vg->cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM));
+ return 0;
+ }
+
return 1;
}
@@ -1717,12 +1749,12 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
if (seg_is_thin(lp) && !_check_thin_parameters(vg, lp, lcp))
goto_out;
- if (!_check_pool_parameters(cmd, vg, lp, lcp))
- goto_out;
-
if (seg_is_vdo(lp) && !_check_vdo_parameters(vg, lp, lcp))
return_0;
+ if (!_check_pool_parameters(cmd, vg, lp, lcp))
+ goto_out;
+
/* All types are checked */
if (!_check_zero_parameters(cmd, lp))
return_0;
1 year, 2 months
main - vdo: support v4 kernel target line
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1c18ed3b4ab2f2d5a15...
Commit: 1c18ed3b4ab2f2d5a15995b8f0a18d7d1c4d60ca
Parent: a477490e812639fed3be495f215fcf1a7b65b7ee
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 8 23:35:06 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
vdo: support v4 kernel target line
Check and use new available table line v4, if kernel supports it.
---
device_mapper/all.h | 1 +
device_mapper/libdm-deptree.c | 37 +++++++++++++++++++++++++------------
lib/metadata/segtype.h | 1 +
lib/vdo/vdo.c | 10 ++++++++--
test/shell/vdo-convert.sh | 2 ++
5 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/device_mapper/all.h b/device_mapper/all.h
index c8f040b80..34d65885e 100644
--- a/device_mapper/all.h
+++ b/device_mapper/all.h
@@ -1049,6 +1049,7 @@ int dm_tree_node_add_integrity_target(struct dm_tree_node *node,
*/
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
uint64_t size,
+ uint32_t vdo_version,
const char *vdo_pool_name,
const char *data_uuid,
uint64_t data_size,
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
index e4bf4c814..2d382037c 100644
--- a/device_mapper/libdm-deptree.c
+++ b/device_mapper/libdm-deptree.c
@@ -214,6 +214,7 @@ struct load_segment {
uint32_t device_id; /* Thin */
// VDO params
+ uint32_t vdo_version; /* VDO - version of target table line */
struct dm_tree_node *vdo_data; /* VDO */
struct dm_vdo_target_params vdo_params; /* VDO */
const char *vdo_name; /* VDO - device name is ALSO passed as table arg */
@@ -2865,18 +2866,28 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
return 0;
}
- EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s "
- "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u",
- data_dev,
- seg->vdo_data_size / 8, // this parameter is in 4K units
- seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units
- seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units
- seg->vdo_params.block_map_era_length,
- seg->vdo_params.use_metadata_hints ? "on" : "off" ,
- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" :
- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" :
- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy
- seg->vdo_name,
+ if (seg->vdo_version < 4) {
+ EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s ",
+ data_dev,
+ seg->vdo_data_size / 8, // this parameter is in 4K units
+ seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units
+ seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units
+ seg->vdo_params.block_map_era_length,
+ seg->vdo_params.use_metadata_hints ? "on" : "off" ,
+ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" :
+ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" :
+ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy
+ seg->vdo_name);
+ } else {
+ EMIT_PARAMS(pos, "V4 %s " FMTu64 " %u " FMTu64 " %u ",
+ data_dev,
+ seg->vdo_data_size / 8, // this parameter is in 4K units
+ seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units
+ seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units
+ seg->vdo_params.block_map_era_length);
+ }
+
+ EMIT_PARAMS(pos, "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u",
seg->vdo_params.max_discard,
seg->vdo_params.ack_threads,
seg->vdo_params.bio_threads,
@@ -4323,6 +4334,7 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
uint64_t size,
+ uint32_t vdo_version,
const char *vdo_pool_name,
const char *data_uuid,
uint64_t data_size,
@@ -4344,6 +4356,7 @@ int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
if (!_link_tree_nodes(node, seg->vdo_data))
return_0;
+ seg->vdo_version = vdo_version;
seg->vdo_params = *vtp;
seg->vdo_name = vdo_pool_name;
seg->vdo_data_size = data_size;
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index 2f4949267..3e52f04a1 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -353,6 +353,7 @@ int init_vdo_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
#endif
#define VDO_FEATURE_ONLINE_RENAME (1U << 0) /* version 6.2.3 */
+#define VDO_FEATURE_VERSION4 (1U << 1) /* version 8.2.0 */
int init_writecache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
index b9bcc044f..9efb424f0 100644
--- a/lib/vdo/vdo.c
+++ b/lib/vdo/vdo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -364,6 +364,10 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
uint32_t *pvmove_mirror_count __attribute__((unused)))
{
char *vdo_pool_name, *data_uuid;
+ unsigned attrs = 0;
+
+ if (seg->segtype->ops->target_present)
+ seg->segtype->ops->target_present(cmd, NULL, &attrs);
if (!seg_is_vdo_pool(seg)) {
log_error(INTERNAL_ERROR "Passed segment is not VDO pool.");
@@ -381,6 +385,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
/* VDO uses virtual size instead of its physical size */
if (!dm_tree_node_add_vdo_target(node, get_vdo_pool_virtual_size(seg),
+ !(attrs & VDO_FEATURE_VERSION4) ? 2 : 4,
vdo_pool_name, data_uuid, seg_lv(seg, 0)->size,
&seg->vdo_params))
return_0;
@@ -390,7 +395,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
static int _vdo_target_present(struct cmd_context *cmd,
const struct lv_segment *seg __attribute__((unused)),
- unsigned *attributes __attribute__((unused)))
+ unsigned *attributes)
{
/* List of features with their kernel target version */
static const struct feature {
@@ -401,6 +406,7 @@ static int _vdo_target_present(struct cmd_context *cmd,
const char *feature;
} _features[] = {
{ 6, 2, 3, VDO_FEATURE_ONLINE_RENAME, "online_rename" },
+ { 8, 2, 0, VDO_FEATURE_VERSION4, "version4" },
};
static const char _lvmconf[] = "global/vdo_disabled_features";
static int _vdo_checked = 0;
diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh
index 8b03344a7..f1d04d596 100644
--- a/test/shell/vdo-convert.sh
+++ b/test/shell/vdo-convert.sh
@@ -174,6 +174,8 @@ vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoL
# Get VDO table line
dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig
+aux lvmconf 'global/vdo_disabled_features = [ "version4" ]'
+
lvm_import_vdo -y --name $vg/$lv "$LOOP"
lvs -a $vg
1 year, 2 months
main - vdo: add reformating to extent size aligned virtual size
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a477490e812639fed3b...
Commit: a477490e812639fed3be495f215fcf1a7b65b7ee
Parent: ebad057579aeff0980a1b8af7eaacd56e62ed0c9
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Jul 9 00:42:01 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
vdo: add reformating to extent size aligned virtual size
Newer VDO kernel target require to have matching virtual size - this
however cause incompatiblity when lvcreate is let to format VDO data
device and read the usable size from vdoformat.
Altough this is a kernel regression and will likely get fixed,
lvm2 can actually reformat VDO device to use properly aligned VDO LV
size to make this problem disappear.
---
lib/metadata/vdo_manip.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
index b83bff391..a7de55d36 100644
--- a/lib/metadata/vdo_manip.c
+++ b/lib/metadata/vdo_manip.c
@@ -227,10 +227,11 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
const struct dm_vdo_target_params *vtp,
uint64_t *logical_size)
{
- char *dpath;
+ char *dpath, *c;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
struct pipe_data pdata;
+ uint64_t logical_size_aligned = 1;
FILE *f;
uint64_t lb;
unsigned slabbits;
@@ -247,7 +248,9 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
return 0;
}
+reformat:
if (*logical_size) {
+ logical_size_aligned = 0;
if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K",
(*logical_size / 2)) < 0)
return_0;
@@ -332,8 +335,8 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
log_verbose("Available VDO logical blocks " FMTu64 " (%s).",
lb, display_size(data_lv->vg->cmd, *logical_size));
}
- if ((dpath = strchr(buf, '\n')))
- *dpath = 0; /* cut last '\n' away */
+ if ((c = strchr(buf, '\n')))
+ *c = 0; /* cut last '\n' away */
if (buf[0])
log_print(" %s", buf); /* Print vdo_format messages */
}
@@ -348,6 +351,19 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
return 0;
}
+ if (logical_size_aligned) {
+ // align obtained size to extent size
+ logical_size_aligned = *logical_size / data_lv->vg->extent_size * data_lv->vg->extent_size;
+ if (*logical_size != logical_size_aligned) {
+ *logical_size = logical_size_aligned;
+ argv[1] = (char*) "--force";
+ args = 2;
+ log_verbose("Reformating VDO to align virtual size %s by extent size.",
+ display_size(data_lv->vg->cmd, *logical_size));
+ goto reformat;
+ }
+ }
+
return 1;
}
1 year, 2 months
main - vdo: check vdo memory constrains
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ebad057579aeff0980a...
Commit: ebad057579aeff0980a1b8af7eaacd56e62ed0c9
Parent: 9f3eff002cc229d3c22dfd7db6da69dadc0bd460
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 8 23:33:29 2022 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 11 01:18:24 2022 +0200
vdo: check vdo memory constrains
Add function to check for avaialble memory for particular VDO
configuration - to avoid unnecessary machine swapping for configs
that will not fit into memory (possibly in locked section).
Formula tries to estimate RAM size machine can use also with
swapping for kernel target - but still leaving some amount of
usable RAM.
Estimation is based on documented RAM usage of VDO target.
If the /proc/meminfo would be theoretically unavailable, try to use
'sysinfo()' function, however this is giving only free RAM without
the knowledge about how much RAM could be eventually swapped.
TODO: move _get_memory_info() into generic lvm2 API function used
by other targets with non-trivial memory requirements.
---
lib/metadata/metadata-exported.h | 2 +
lib/metadata/vdo_manip.c | 144 +++++++++++++++++++++++++++++++++++++++
lib/vdo/vdo.c | 8 ++-
tools/lvcreate.c | 4 ++
4 files changed, 156 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index fd370d4b2..191bf4326 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1377,6 +1377,8 @@ int fill_vdo_target_params(struct cmd_context *cmd,
struct dm_vdo_target_params *vtp,
uint64_t *vdo_pool_header_size,
struct profile *profile);
+int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size,
+ uint64_t virtual_size, struct dm_vdo_target_params *vtp);
/* -- metadata/vdo_manip.c */
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
index fa9c893cb..b83bff391 100644
--- a/lib/metadata/vdo_manip.c
+++ b/lib/metadata/vdo_manip.c
@@ -23,6 +23,8 @@
#include "lib/config/defaults.h"
#include "lib/misc/lvm-exec.h"
+#include <sys/sysinfo.h> // sysinfo
+
const char *get_vdo_compression_state_name(enum dm_vdo_compression_state state)
{
switch (state) {
@@ -514,3 +516,145 @@ int fill_vdo_target_params(struct cmd_context *cmd,
return 1;
}
+
+static int _get_sysinfo_memory(uint64_t *total_mb, uint64_t *available_mb)
+{
+ struct sysinfo si = { 0 };
+
+ *total_mb = *available_mb = UINT64_MAX;
+
+ if (sysinfo(&si) != 0)
+ return 0;
+
+ log_debug("Sysinfo free:%lu bufferram:%lu sharedram:%lu freehigh:%lu unit:%u.",
+ si.freeram >> 20, si.bufferram >> 20, si.sharedram >> 20,
+ si.freehigh >> 20, si.mem_unit);
+
+ *available_mb = ((uint64_t)(si.freeram + si.bufferram) * si.mem_unit) >> 30;
+ *total_mb = si.totalram >> 30;
+
+ return 1;
+}
+
+typedef struct mem_table_s {
+ const char *name;
+ uint64_t *value;
+} mem_table_t;
+
+static int _compare_mem_table_s(const void *a, const void *b){
+ return strcmp(((const mem_table_t*)a)->name, ((const mem_table_t*)b)->name);
+}
+
+static int _get_memory_info(uint64_t *total_mb, uint64_t *available_mb)
+{
+ uint64_t anon_pages, mem_available, mem_free, mem_total, shmem, swap_free;
+ uint64_t can_swap;
+ mem_table_t mt[] = {
+ { "AnonPages", &anon_pages },
+ { "MemAvailable", &mem_available },
+ { "MemFree", &mem_free },
+ { "MemTotal", &mem_total },
+ { "Shmem", &shmem },
+ { "SwapFree", &swap_free },
+ };
+
+ char line[128], namebuf[32], *e, *tail;
+ FILE *fp;
+ mem_table_t findme = { namebuf, NULL };
+ mem_table_t *found;
+
+ if (!(fp = fopen("/proc/meminfo", "r")))
+ return _get_sysinfo_memory(total_mb, available_mb);
+
+ while (fgets(line, sizeof(line), fp)) {
+ if (!(e = strchr(line, ':')))
+ break;
+
+ if ((++e - line) > sizeof(namebuf))
+ continue; // something too long
+
+ (void)dm_strncpy((char*)findme.name, line, e - line);
+
+ found = bsearch(&findme, mt, DM_ARRAY_SIZE(mt), sizeof(mem_table_t),
+ _compare_mem_table_s);
+ if (!found)
+ continue; // not interesting
+
+ *(found->value) = (uint64_t) strtoull(e, &tail, 10);
+
+ if ((e == tail) || errno)
+ log_debug("Failing to parse value from %s.", line);
+ else
+ log_debug("Parsed %s = " FMTu64 " KiB.", found->name, *(found->value));
+ }
+ (void)fclose(fp);
+
+ // use at most 2/3 of swap space to keep machine usable
+ can_swap = (anon_pages + shmem) * 2 / 3;
+ swap_free = swap_free * 2 / 3;
+
+ if (can_swap > swap_free)
+ can_swap = swap_free;
+
+ // TODO: add more constrains, i.e. 3/4 of physical RAM...
+
+ *total_mb = mem_total >> 10;
+ *available_mb = (mem_available + can_swap) >> 10;
+
+ return 1;
+}
+
+static uint64_t _round_1024(uint64_t s)
+{
+ return (s + ((1 << 10) - 1)) >> 10;
+}
+
+static uint64_t _round_sectors_to_tib(uint64_t s)
+{
+ return (s + ((UINT64_C(1) << (40 - SECTOR_SHIFT)) - 1)) >> (40 - SECTOR_SHIFT);
+}
+
+int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size,
+ uint64_t virtual_size, struct dm_vdo_target_params *vtp)
+{
+ uint64_t req_mb, total_mb, available_mb;
+ uint64_t phy_mb = _round_sectors_to_tib(UINT64_C(268) * physical_size); // 268 MiB per 1 TiB of physical size
+ uint64_t virt_mb = _round_1024(UINT64_C(1638) * _round_sectors_to_tib(virtual_size)); // 1.6 MiB per 1 TiB
+ uint64_t cache_mb = _round_1024(UINT64_C(1177) * vtp->block_map_cache_size_mb); // 1.15 MiB per 1 MiB cache size
+ char msg[512];
+
+ if (cache_mb < 150)
+ cache_mb = 150; // always at least 150 MiB for block map
+
+ // total required memory for VDO target
+ req_mb = 38 + vtp->index_memory_size_mb + virt_mb + phy_mb + cache_mb;
+
+ _get_memory_info(&total_mb, &available_mb);
+
+ (void)snprintf(msg, sizeof(msg), "VDO configuration needs %s RAM for physical volume size %s, "
+ "%s RAM for virtual volume size %s, %s RAM for block map cache size %s and "
+ "%s RAM for index memory.",
+ display_size(cmd, phy_mb << (20 - SECTOR_SHIFT)),
+ display_size(cmd, physical_size),
+ display_size(cmd, virt_mb << (20 - SECTOR_SHIFT)),
+ display_size(cmd, virtual_size),
+ display_size(cmd, cache_mb << (20 - SECTOR_SHIFT)),
+ display_size(cmd, ((uint64_t)vtp->block_map_cache_size_mb) << (20 - SECTOR_SHIFT)),
+ display_size(cmd, ((uint64_t)vtp->index_memory_size_mb) << (20 - SECTOR_SHIFT)));
+
+ if (req_mb > available_mb) {
+ log_error("Not enough free memory for VDO target. %s RAM is required, but only %s RAM is available.",
+ display_size(cmd, req_mb << (20 - SECTOR_SHIFT)),
+ display_size(cmd, available_mb << (20 - SECTOR_SHIFT)));
+ log_print_unless_silent("%s", msg);
+ return 0;
+ }
+
+ log_debug("VDO requires %s RAM, currently available %s RAM.",
+ display_size(cmd, req_mb << (20 - SECTOR_SHIFT)),
+ display_size(cmd, available_mb << (20 - SECTOR_SHIFT)));
+
+ log_verbose("%s", msg);
+
+ return 1;
+}
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
index 52e9443ea..b9bcc044f 100644
--- a/lib/vdo/vdo.c
+++ b/lib/vdo/vdo.c
@@ -355,8 +355,8 @@ static int _vdo_pool_target_status_compatible(const char *type)
}
static int _vdo_pool_add_target_line(struct dev_manager *dm,
- struct dm_pool *mem __attribute__((unused)),
- struct cmd_context *cmd __attribute__((unused)),
+ struct dm_pool *mem,
+ struct cmd_context *cmd,
void **target_state __attribute__((unused)),
struct lv_segment *seg,
const struct lv_activate_opts *laopts __attribute__((unused)),
@@ -369,6 +369,10 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
log_error(INTERNAL_ERROR "Passed segment is not VDO pool.");
return 0;
}
+
+ if (!check_vdo_constrains(cmd, seg->lv->size, seg_lv(seg, 0)->size, &seg->vdo_params))
+ return_0;
+
if (!(vdo_pool_name = dm_build_dm_name(mem, seg->lv->vg->name, seg->lv->name, lv_layer(seg->lv))))
return_0;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 20d7e4690..6bdbe943e 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1730,6 +1730,10 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
if (!_update_extents_params(vg, lp, lcp))
goto_out;
+ if (seg_is_vdo(lp) && !check_vdo_constrains(cmd, (uint64_t)lp->extents * vg->extent_size,
+ lcp->virtual_size, &lp->vdo_params))
+ return_0;
+
if (seg_is_thin(lp) && !_validate_internal_thin_processing(lp))
goto_out;
1 year, 2 months