main - devices: fix dev_name assumptions
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4eb04c8c05e52776891...
Commit: 4eb04c8c05e52776891f62863375ceacf866de77
Parent: 00c3069872ab488f66f14c8c2727bd080affc05e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Feb 22 15:03:11 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 24 17:22:04 2022 -0600
devices: fix dev_name assumptions
dev_name(dev) returns "[unknown]" if there are no names
on dev->aliases. It's meant mainly for log messages.
Many places assume a valid path name is returned, and
use it directly. A caller that wants to use the path
from dev_name() must first check if the dev has any
paths with dm_list_empty(&dev->aliases).
---
lib/activate/dev_manager.c | 9 ++++++++-
lib/device/dev-type.c | 3 +++
lib/device/device_id.c | 13 +++++++++++--
lib/label/hints.c | 2 ++
lib/label/label.c | 23 ++++++++++++++++++++++-
lib/locking/lvmlockd.c | 4 ++++
lib/metadata/mirror.c | 17 +++++++++++++----
lib/metadata/pv_list.c | 5 +++++
lib/metadata/vg.c | 5 +++++
test/shell/losetup-partscan.sh | 2 ++
10 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 63bfd9b74..2cae3bed1 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2947,6 +2947,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
for (s = start_area; s < areas; s++) {
+
+ /* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases)
+ but this knot of logic is too complex to pull apart without careful deconstruction. */
+
if ((seg_type(seg, s) == AREA_PV &&
(!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
!(name = dev_name(seg_dev(seg, s))) || !*name ||
@@ -2965,7 +2969,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
return_0;
num_error_areas++;
} else if (seg_type(seg, s) == AREA_PV) {
- if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL,
+ struct device *dev = seg_dev(seg, s);
+ name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev);
+
+ if (!dm_tree_node_add_target_area(node, name, NULL,
(seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s)))))
return_0;
num_existing_areas++;
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 0e77a009d..c67a86fa3 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -966,6 +966,9 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
+ if (dm_list_empty(&dev->aliases))
+ goto_out;
+
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
goto out;
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index c8df47345..7ce955b11 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -347,6 +347,8 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
}
else if (idtype == DEV_ID_TYPE_DEVNAME) {
+ if (dm_list_empty(&dev->aliases))
+ goto_bad;
if (!(idname = strdup(dev_name(dev))))
goto_bad;
return idname;
@@ -955,6 +957,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
if (!dev_get_partition_number(dev, &part))
return_0;
+ /* Ensure valid dev_name(dev) below. */
+ if (dm_list_empty(&dev->aliases))
+ return_0;
+
/*
* When enable_devices_file=0 and pending_devices_file=1 we let
* pvcreate/vgcreate add new du's to cmd->use_devices. These du's may
@@ -1842,6 +1848,9 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
if (dev->flags & DEV_SCAN_NOT_READ)
continue;
+ if (dm_list_empty(&dev->aliases))
+ continue;
+
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
log_warn("Devices file %s is excluded by filter: %s.",
dev_name(dev), dev_filtered_reason(dev));
@@ -2225,14 +2234,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
dm_list_iterate_items(dil, &search_pvids) {
char *dup_devname1, *dup_devname2, *dup_devname3;
- if (!dil->dev) {
+ if (!dil->dev || dm_list_empty(&dil->dev->aliases)) {
not_found++;
continue;
}
- found++;
dev = dil->dev;
devname = dev_name(dev);
+ found++;
if (!(du = get_du_for_pvid(cmd, dil->pvid))) {
/* shouldn't happen */
diff --git a/lib/label/hints.c b/lib/label/hints.c
index 35ae7f5cc..edce6f517 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -500,6 +500,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
if (!(iter = dev_iter_create(NULL, 0)))
return 0;
while ((dev = dev_iter_get(cmd, iter))) {
+ if (dm_list_empty(&dev->aliases))
+ continue;
if (!(hint = _find_hint_name(hints, dev_name(dev))))
continue;
diff --git a/lib/label/label.c b/lib/label/label.c
index 66d6e7db7..ffb393891 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1130,6 +1130,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
* sure to find the device.
*/
if (try_dev_scan) {
+ log_debug("Repeat dev cache scan to translate devnos.");
dev_cache_scan(cmd);
dm_list_iterate_items(po, &pvs_online) {
if (po->dev)
@@ -1736,6 +1737,12 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
struct lv_list *lvl;
dev_t devt;
+ /*
+ * FIXME: this is all unnecessary unless there are PVs stacked on LVs,
+ * so we can skip all of this if scan_lvs=0.
+ */
+ log_debug("invalidating devs for any pvs on lvs");
+
if (get_device_list(NULL, &devs, &devs_features)) {
if (devs_features & DM_DEVICE_LIST_HAS_UUID) {
dm_list_iterate_items(dm_dev, devs)
@@ -1879,10 +1886,24 @@ int label_scan_open_rw(struct device *dev)
int label_scan_reopen_rw(struct device *dev)
{
+ const char *name;
int flags = 0;
int prev_fd = dev->bcache_fd;
int fd;
+ if (dm_list_empty(&dev->aliases)) {
+ log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
+ return 0;
+ }
+
+ name = dev_name(dev);
+ if (!name || name[0] != '/') {
+ log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
+ return 0;
+ }
+
if (!(dev->flags & DEV_IN_BCACHE)) {
if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) {
/* shouldn't happen */
@@ -1912,7 +1933,7 @@ int label_scan_reopen_rw(struct device *dev)
flags |= O_NOATIME;
flags |= O_RDWR;
- fd = open(dev_name(dev), flags, 0777);
+ fd = open(name, flags, 0777);
if (fd < 0) {
log_error("Failed to open rw %s errno %d di %d fd %d.",
dev_name(dev), errno, dev->bcache_di, dev->bcache_fd);
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index b598df3d6..60c80f1b1 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -272,6 +272,8 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
i = 0;
dm_list_iterate_items(pvl, &vg->pvs) {
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
+ continue;
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for VG %s", vg->name);
@@ -341,6 +343,8 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
dm_list_iterate_items(pvl, &vg->pvs) {
if (lv_is_on_pv(lv, pvl->pv)) {
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
+ continue;
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for LV %s/%s",
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index e2bf191a1..46da57948 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -1231,14 +1231,23 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
{
struct lv_segment *seg;
+ struct device *dev;
dm_list_iterate_items(seg, &lv_mirr->segments) {
if (!seg_is_mirrored(seg))
continue;
- if (seg_type(seg, 0) == AREA_PV)
- return dev_name(seg_dev(seg, 0));
- if (seg_type(seg, 0) == AREA_LV)
- return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0));
+ if (seg_type(seg, 0) == AREA_PV) {
+ dev = seg_dev(seg, 0);
+ if (!dev || dm_list_empty(&dev->aliases))
+ return NULL;
+ return dev_name(dev);
+ }
+ if (seg_type(seg, 0) == AREA_LV) {
+ dev = seg_dev(first_seg(seg_lv(seg, 0)), 0);
+ if (!dev || dm_list_empty(&dev->aliases))
+ return NULL;
+ return dev_name(dev);
+ }
}
return NULL;
diff --git a/lib/metadata/pv_list.c b/lib/metadata/pv_list.c
index 813e8e525..fc3667db0 100644
--- a/lib/metadata/pv_list.c
+++ b/lib/metadata/pv_list.c
@@ -152,6 +152,11 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
struct pv_list *new_pvl = NULL, *pvl2;
struct dm_list *pe_ranges;
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) {
+ log_error("Failed to create PV entry for missing device.");
+ return 0;
+ }
+
pvname = pv_dev_name(pvl->pv);
if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
log_warn("WARNING: Physical volume %s not allocatable.", pvname);
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 85482552a..adc954bab 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -679,6 +679,11 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
return r;
}
+ if (!pv->dev || dm_list_empty(&pv->dev->aliases)) {
+ log_error("No device found for PV.");
+ return r;
+ }
+
log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv));
if (pv_pe_alloc_count(pv)) {
diff --git a/test/shell/losetup-partscan.sh b/test/shell/losetup-partscan.sh
index 99f552ad1..670568945 100644
--- a/test/shell/losetup-partscan.sh
+++ b/test/shell/losetup-partscan.sh
@@ -33,6 +33,8 @@ aux udev_wait
ls -la "${LOOP}"*
test -e "${LOOP}p1"
+aux lvmconf 'devices/scan = "/dev"'
+
aux extend_filter "a|$LOOP|"
aux extend_devices "$LOOP"
1 year, 7 months
main - devices: initial use of existing option
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=00c3069872ab488f66f...
Commit: 00c3069872ab488f66f14c8c2727bd080affc05e
Parent: 7e70041e324e1a4d49134a93323072e1b6ec661f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 24 16:10:37 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 24 17:22:03 2022 -0600
devices: initial use of existing option
Use dev_cache_get_existing() in a few common, high level
locations where it's obvious that only existing dev-cache
entries are wanted. This can be expanded and used in more
locations (or dev_cache_get can stop creating new entries.)
---
lib/device/device_id.c | 4 ++--
tools/toollib.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 003f10a96..c8df47345 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1577,7 +1577,7 @@ void device_ids_match_device_list(struct cmd_context *cmd)
dm_list_iterate_items(du, &cmd->use_devices) {
if (du->dev)
continue;
- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
+ if (!(du->dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
log_warn("Device not found for %s.", du->devname);
} else {
/* Should we set dev->id? Which idtype? Use --deviceidtype? */
@@ -1625,7 +1625,7 @@ void device_ids_match(struct cmd_context *cmd)
* the du/dev pairs in preparation for using the filters.
*/
if (du->devname &&
- (dev = dev_cache_get(cmd, du->devname, NULL))) {
+ (dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
/* On successful match, du, dev, and id are linked. */
if (_match_du_to_dev(cmd, du, dev))
continue;
diff --git a/tools/toollib.c b/tools/toollib.c
index b08c044fa..897adec34 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1488,7 +1488,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
goto out;
}
- if (!(dev = dev_cache_get(cmd, argv[opt], cmd->filter))) {
+ if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) {
log_error("Failed to find device "
"\"%s\".", argv[opt]);
ret_max = ECMD_FAILED;
@@ -3925,7 +3925,7 @@ static int _get_arg_devices(struct cmd_context *cmd,
return ECMD_FAILED;
}
- if (!(dil->dev = dev_cache_get(cmd, sl->str, cmd->filter))) {
+ if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) {
log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str));
ret_max = EINIT_FAILED;
} else {
@@ -5261,7 +5261,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
struct device *dev;
/* No filter used here */
- if (!(dev = dev_cache_get(cmd, pd->name, NULL))) {
+ if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) {
log_error("No device found for %s.", pd->name);
dm_list_del(&pd->list);
dm_list_add(&pp->arg_fail, &pd->list);
1 year, 7 months
main - devices: drop incorrect paths from aliases list
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7e70041e324e1a4d491...
Commit: 7e70041e324e1a4d49134a93323072e1b6ec661f
Parent: 1126be8f8dbce482e82d8f98a7e7f4b7cd2cac34
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 24 16:03:21 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 24 17:22:03 2022 -0600
devices: drop incorrect paths from aliases list
along with some basic checks for cases when a device
has no aliases.
lvm itself creates many situations where a struct device
has no valid paths, when it activates and opens an LV,
does something with it, e.g. zeroing, and then closes
and deactivates it. (dev-cache is intended for PVs, and
the use of LVs should be moved out of dev-cache in a
future patch.)
---
lib/device/dev-cache.c | 223 +++++++++++++++++++++++++++++++------------------
lib/device/dev-cache.h | 2 +-
lib/device/dev-io.c | 34 +++++---
lib/device/device.h | 3 -
4 files changed, 164 insertions(+), 98 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 1777628a8..8db28bd84 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -351,7 +351,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
goto out;
}
- if (!(path = dm_pool_strdup(_cache.mem, path)) ||
+ if (!(path = _strdup(path)) ||
!(sl = _zalloc(sizeof(*sl)))) {
log_error("Failed to add allias to dev cache.");
return 0;
@@ -1162,6 +1162,17 @@ static int _insert(const char *path, const struct stat *info,
return 1;
}
+static void _drop_all_aliases(struct device *dev)
+{
+ struct dm_str_list *strl, *strl2;
+
+ dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
+ log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str);
+ dm_hash_remove(_cache.names, strl->str);
+ dm_list_del(&strl->list);
+ }
+}
+
void dev_cache_scan(struct cmd_context *cmd)
{
log_debug_devs("Creating list of system devices.");
@@ -1371,59 +1382,6 @@ int dev_cache_add_dir(const char *path)
return 1;
}
-/* Check cached device name is still valid before returning it */
-/* This should be a rare occurrence */
-/* set quiet if the cache is expected to be out-of-date */
-/* FIXME Make rest of code pass/cache struct device instead of dev_name */
-const char *dev_name_confirmed(struct device *dev, int quiet)
-{
- struct stat buf;
- const char *name;
- int r;
-
- if ((dev->flags & DEV_REGULAR))
- return dev_name(dev);
-
- while ((r = stat(name = dm_list_item(dev->aliases.n,
- struct dm_str_list)->str, &buf)) ||
- (buf.st_rdev != dev->dev)) {
- if (r < 0) {
- if (quiet)
- log_sys_debug("stat", name);
- else
- log_sys_error("stat", name);
- }
- if (quiet)
- log_debug_devs("Path %s no longer valid for device(%d,%d)",
- name, (int) MAJOR(dev->dev),
- (int) MINOR(dev->dev));
- else
- log_warn("Path %s no longer valid for device(%d,%d)",
- name, (int) MAJOR(dev->dev),
- (int) MINOR(dev->dev));
-
- /* Remove the incorrect hash entry */
- dm_hash_remove(_cache.names, name);
-
- /* Leave list alone if there isn't an alternative name */
- /* so dev_name will always find something to return. */
- /* Otherwise add the name to the correct device. */
- if (dm_list_size(&dev->aliases) > 1) {
- dm_list_del(dev->aliases.n);
- if (!r)
- _insert(name, &buf, 0, obtain_device_list_from_udev());
- continue;
- }
-
- /* Scanning issues this inappropriately sometimes. */
- log_debug_devs("Aborting - please provide new pathname for what "
- "used to be %s", name);
- return NULL;
- }
-
- return dev_name(dev);
-}
-
struct device *dev_hash_get(const char *name)
{
return (struct device *) dm_hash_lookup(_cache.names, name);
@@ -1452,26 +1410,23 @@ static void _remove_alias(struct device *dev, const char *name)
* deactivated LV. Those old paths are all invalid and are dropped here.
*/
-static void _verify_aliases(struct device *dev, const char *newname)
+static void _verify_aliases(struct device *dev)
{
struct dm_str_list *strl, *strl2;
struct stat st;
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
- /* newname was just stat'd and added by caller */
- if (newname && !strcmp(strl->str, newname))
- continue;
-
if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) {
- log_debug("Drop invalid path %s for %d:%d (new path %s).",
- strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: "");
+ log_debug("Drop alias for %d:%d invalid path %s %d:%d.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str,
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev));
dm_hash_remove(_cache.names, strl->str);
dm_list_del(&strl->list);
}
}
}
-struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
+static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing)
{
struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
struct stat st;
@@ -1485,13 +1440,18 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
if (dev && (dev->flags & DEV_REGULAR))
return dev;
+ if (dev && dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_warn("Ignoring dev with no valid paths for %s.", name);
+ return NULL;
+ }
+
/*
- * The requested path is invalid, remove any dev-cache
- * info for it.
+ * The requested path is invalid, remove any dev-cache info for it.
*/
if (stat(name, &st)) {
if (dev) {
- log_print("Device path %s is invalid for %d:%d %s.",
+ log_debug("Device path %s is invalid for %d:%d %s.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
dm_hash_remove(_cache.names, name);
@@ -1499,11 +1459,17 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
- _verify_aliases(dev, NULL);
+ _verify_aliases(dev);
}
return NULL;
}
+ if (dev && dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_warn("Ignoring dev with no valid paths for %s.", name);
+ return NULL;
+ }
+
if (!S_ISBLK(st.st_mode)) {
log_debug("Not a block device %s.", name);
return NULL;
@@ -1514,26 +1480,110 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
* Remove incorrect info and then add new dev-cache entry.
*/
if (dev && (st.st_rdev != dev->dev)) {
- log_debug("Device path %s does not match %d:%d %s.",
- name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
+ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
+
+ /*
+ * lvm commands create this condition when they
+ * activate/deactivate LVs combined with creating new LVs.
+ * The command does not purge dev structs when deactivating
+ * an LV (which it probably should do), but the better
+ * approach would be not using dev-cache at all for LVs.
+ */
- dm_hash_remove(_cache.names, name);
+ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev),
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
- _remove_alias(dev, name);
+ _drop_all_aliases(dev);
- /* Remove any other names in dev->aliases that are incorrect. */
- _verify_aliases(dev, NULL);
+ if (dev_by_devt) {
+ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
+ (int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt),
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
- /* Add new dev-cache entry next. */
- dev = NULL;
+ _drop_all_aliases(dev_by_devt);
+ }
+
+#if 0
+ /*
+ * I think only lvm's own dm devs should be added here, so use
+ * a warning to look for any other unknown cases.
+ */
+ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
+ log_warn("WARNING: new device appeared %d:%d %s",
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
+ }
+#endif
+
+ if (!_insert_dev(name, st.st_rdev))
+ return_NULL;
+
+ /* Get the struct dev that was just added. */
+ dev = (struct device *) dm_hash_lookup(_cache.names, name);
+
+ if (!dev) {
+ log_error("Failed to get device %s", name);
+ return NULL;
+ }
+
+ goto out;
}
+ if (dev && dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_warn("Ignoring dev with no valid paths for %s.", name);
+ return NULL;
+ }
+
+ if (!dev && existing)
+ return_NULL;
+
/*
- * Either add a new struct dev for st_rdev and name,
- * or add name as a new alias for an existing struct dev
- * for st_rdev.
+ * This case should never be hit for a PV. It should only
+ * happen when the command is opening a new LV it has created.
+ * Add an arg to all callers indicating when the arg should be
+ * new (for an LV) and not existing.
+ * FIXME: fix this further by not using dev-cache struct devs
+ * at all for new dm devs (LVs) that lvm uses. Make the
+ * dev-cache contain only devs for PVs.
+ * Places to fix that use a dev for LVs include:
+ * . lv_resize opening lv to discard
+ * . wipe_lv opening lv to zero it
+ * . _extend_sanlock_lv opening lv to extend it
+ * . _write_log_header opening lv to write header
+ * Also, io to LVs should not go through bcache.
+ * bcache should contain only labels and metadata
+ * scanned from PVs.
*/
if (!dev) {
+ /*
+ * This case should only be used for new devices created by this
+ * command (opening LVs it's created), so if a dev exists for the
+ * dev_t referenced by the name, then drop all aliases for before
+ * _insert_dev adds the new name. lvm commands actually hit this
+ * fairly often when it uses some LV, deactivates the LV, then
+ * creates some new LV which ends up with the same major:minor.
+ * Without dropping the aliases, it's plausible that lvm commands
+ * could end up using the wrong dm device.
+ */
+ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
+ if (dev_by_devt) {
+ log_debug("Dropping aliases for %d:%d before adding new path %s.",
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
+ _drop_all_aliases(dev_by_devt);
+ }
+
+#if 0
+ /*
+ * I think only lvm's own dm devs should be added here, so use
+ * a warning to look for any other unknown cases.
+ */
+ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
+ log_warn("WARNING: new device appeared %d:%d %s",
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
+ }
+#endif
+
if (!_insert_dev(name, st.st_rdev))
return_NULL;
@@ -1544,10 +1594,9 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
log_error("Failed to get device %s", name);
return NULL;
}
-
- _verify_aliases(dev, name);
}
+ out:
/*
* The caller passed a filter if they only want the dev if it
* passes filters.
@@ -1577,6 +1626,16 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
return dev;
}
+struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f)
+{
+ return _dev_cache_get(cmd, name, f, 1);
+}
+
+struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
+{
+ return _dev_cache_get(cmd, name, f, 0);
+}
+
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
{
struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
@@ -1653,8 +1712,10 @@ int dev_fd(struct device *dev)
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();
+ if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases))
+ return dm_list_item(dev->aliases.n, struct dm_str_list)->str;
+ else
+ return unknown_device_name();
}
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index a88e3c282..622335982 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -53,7 +53,7 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
-
+struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
struct device *dev_hash_get(const char *name);
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index b4f1930b1..811ad8978 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -58,6 +58,9 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size)
const char *name = dev_name(dev);
struct stat info;
+ if (dm_list_empty(&dev->aliases))
+ return_0;
+
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
name, dev->size);
@@ -87,7 +90,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
int do_close = 0;
if (dm_list_empty(&dev->aliases))
- return 0;
+ return_0;
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
@@ -305,6 +308,13 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if ((flags & O_EXCL))
need_excl = 1;
+ if (dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
+ return 0;
+ }
+ name = dev_name(dev);
+
if (dev->fd >= 0) {
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
@@ -314,7 +324,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (dev->open_count && !need_excl)
log_debug_devs("%s: Already opened read-only. Upgrading "
- "to read-write.", dev_name(dev));
+ "to read-write.", name);
/* dev_close_immediate will decrement this */
dev->open_count++;
@@ -327,11 +337,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (critical_section())
/* FIXME Make this log_error */
- log_verbose("dev_open(%s) called while suspended",
- dev_name(dev));
-
- if (!(name = dev_name_confirmed(dev, quiet)))
- return_0;
+ log_verbose("dev_open(%s) called while suspended", name);
#ifdef O_DIRECT_SUPPORT
if (direct) {
@@ -372,9 +378,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
}
#endif
if (quiet)
- log_sys_debug("open", name);
+ log_debug("Failed to open device path %s (%d).", name, errno);
else
- log_sys_error("open", name);
+ log_error("Failed to open device path %s (%d).", name, errno);
dev->flags |= DEV_OPEN_FAILURE;
return 0;
@@ -415,10 +421,12 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if ((flags & O_CREAT) && !(flags & O_TRUNC))
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
- log_debug_devs("Opened %s %s%s%s", dev_name(dev),
- dev->flags & DEV_OPENED_RW ? "RW" : "RO",
- dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
- dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
+ if (!quiet) {
+ log_debug_devs("Opened %s %s%s%s", name,
+ dev->flags & DEV_OPENED_RW ? "RW" : "RO",
+ dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
+ dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
+ }
dev->flags &= ~DEV_OPEN_FAILURE;
return 1;
diff --git a/lib/device/device.h b/lib/device/device.h
index 8c3a8c30e..572994bb9 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -204,9 +204,6 @@ struct device *dev_create_file(const char *filename, struct device *dev,
struct dm_str_list *alias, int use_malloc);
void dev_destroy_file(struct device *dev);
-/* Return a valid device name from the alias list; NULL otherwise */
-const char *dev_name_confirmed(struct device *dev, int quiet);
-
int dev_mpath_init(const char *config_wwids_file);
void dev_mpath_exit(void);
1 year, 7 months
main - devices: simplify dev_cache_get_by_devt
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1126be8f8dbce482e82...
Commit: 1126be8f8dbce482e82d8f98a7e7f4b7cd2cac34
Parent: ac1f4bbbfd4c5f1387c3e0607f7d556409e7a4b4
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 24 15:57:29 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 24 17:21:58 2022 -0600
devices: simplify dev_cache_get_by_devt
remove unused args, and no callers need or want a
repeated dev_cache_scan if there is no dev from the
lookup.
---
lib/device/dev-cache.c | 60 +++++---------------------------------------------
lib/device/dev-cache.h | 2 +-
lib/label/label.c | 6 ++---
3 files changed, 9 insertions(+), 59 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index d3fae4948..1777628a8 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1577,63 +1577,13 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
return dev;
}
-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered)
+struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
{
- char path[PATH_MAX];
- const char *sysfs_dir;
- struct stat info;
- struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
- int ret;
-
- if (filtered)
- *filtered = 0;
-
- if (!d) {
- sysfs_dir = dm_sysfs_dir();
- if (sysfs_dir && *sysfs_dir) {
- /* First check if dev is sysfs to avoid useless scan */
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
- sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) {
- log_error("dm_snprintf partition failed.");
- return NULL;
- }
-
- if (lstat(path, &info)) {
- log_debug("No sysfs entry for %d:%d errno %d at %s.",
- (int)MAJOR(dev), (int)MINOR(dev), errno, path);
- return NULL;
- }
- }
-
- log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d",
- (int)MAJOR(dev), (int)MINOR(dev));
- dev_cache_scan(cmd);
- d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
-
- if (!d)
- return NULL;
- }
-
- if (d->flags & DEV_REGULAR)
- return d;
-
- if (!f)
- return d;
-
- ret = f->passes_filter(cmd, f, d, NULL);
-
- if (ret == -EAGAIN) {
- log_debug_devs("get device by number defer filter %s", dev_name(d));
- d->flags |= DEV_FILTER_AFTER_SCAN;
- ret = 1;
- }
-
- if (ret)
- return d;
-
- if (filtered)
- *filtered = 1;
+ struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
+ if (dev)
+ return dev;
+ log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt));
return NULL;
}
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 449bfeb75..a88e3c282 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -54,7 +54,7 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered);
+struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
struct device *dev_hash_get(const char *name);
diff --git a/lib/label/label.c b/lib/label/label.c
index fe2bc8fec..66d6e7db7 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1134,7 +1134,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
dm_list_iterate_items(po, &pvs_online) {
if (po->dev)
continue;
- if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno, NULL, NULL))) {
+ if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) {
log_error("No device found for %d:%d PVID %s",
(int)MAJOR(po->devno), (int)MINOR(po->devno), po->pvid);
goto bad;
@@ -1722,7 +1722,7 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) {
/* FIXME: Still unclear what is it supposed to find */
devt = MKDEV(lvinfo.major, lvinfo.minor);
- if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
+ if ((dev = dev_cache_get_by_devt(cmd, devt)))
label_scan_invalidate(dev);
}
}
@@ -1742,7 +1742,7 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
if (dm_dev->uuid &&
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
devt = MKDEV(dm_dev->major, dm_dev->minor);
- if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
+ if ((dev = dev_cache_get_by_devt(cmd, devt)))
label_scan_invalidate(dev);
}
/* ATM no further caching for any lvconvert command
1 year, 7 months
main - writecache: display block size from lvs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ac1f4bbbfd4c5f1387c...
Commit: ac1f4bbbfd4c5f1387c3e0607f7d556409e7a4b4
Parent: 6144dac897728a4857294d70645df8ed7a5ff11f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Feb 21 16:09:57 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Feb 21 16:11:13 2022 -0600
writecache: display block size from lvs
lvs was missing the ability to display writecache block size.
now possible with lvs -o writecache_block_size
---
lib/report/columns.h | 1 +
lib/report/properties.c | 2 ++
lib/report/report.c | 20 ++++++++++++++++++++
man/lvmcache.7_main | 4 ++++
test/shell/writecache-cache-blocksize.sh | 2 ++
5 files changed, 29 insertions(+)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 12b78b766..7e450dace 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -108,6 +108,7 @@ FIELD(LVS, lv, TIM, "RTime", lvid, 26, lvtimeremoved, lv_time_removed, "Removal
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
FIELD(LVS, lv, STR_LIST, "Modules", lvid, 0, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
FIELD(LVS, lv, BIN, "Historical", lvid, 0, lvhistorical, lv_historical, "Set if the LV is historical.", 0)
+FIELD(LVS, lv, NUM, "WCacheBlkSize", lvid, 0, writecache_block_size, writecache_block_size, "The writecache block size", 0)
/*
* End of LVS type fields
*/
diff --git a/lib/report/properties.c b/lib/report/properties.c
index 12ea890f4..6f302360f 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -353,6 +353,8 @@ GET_PV_STR_PROPERTY_FN(pv_device_id_type, pv->device_id_type)
#define _writecache_writeback_blocks_get prop_not_implemented_get
#define _writecache_error_set prop_not_implemented_set
#define _writecache_error_get prop_not_implemented_get
+#define _writecache_block_size_set prop_not_implemented_set
+#define _writecache_block_size_get prop_not_implemented_get
#define _vdo_operating_mode_set prop_not_implemented_set
#define _vdo_operating_mode_get prop_not_implemented_get
diff --git a/lib/report/report.c b/lib/report/report.c
index 60df417a4..c06b22674 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -3346,6 +3346,26 @@ static int _integritymismatches_disp(struct dm_report *rh __attribute__((unused)
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
+static int _writecache_block_size_disp(struct dm_report *rh __attribute__((unused)),
+ struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data,
+ void *private __attribute__((unused)))
+{
+ struct logical_volume *lv = (struct logical_volume *) data;
+ uint32_t bs = 0;
+
+ if (lv_is_writecache(lv)) {
+ struct lv_segment *seg = first_seg(lv);
+ bs = seg->writecache_block_size;
+ }
+
+ if (!bs)
+ return dm_report_field_int32(rh, field, &GET_TYPE_RESERVED_VALUE(num_undef_32));
+
+ return dm_report_field_uint32(rh, field, &bs);
+}
+
static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
index ce440bf49..8b8289c74 100644
--- a/man/lvmcache.7_main
+++ b/man/lvmcache.7_main
@@ -241,6 +241,10 @@ It is also possible to specify a sector size of 4096 to mkfs.xfs when
creating the file system. In this case the writecache block size of 4096
can be used.
.P
+The writecache block size is displayed by the command:
+.br
+lvs -o writecacheblocksize VG/LV
+.P
.SS dm-writecache memory usage
.P
The amount of main system memory used by dm-writecache can be a factor
diff --git a/test/shell/writecache-cache-blocksize.sh b/test/shell/writecache-cache-blocksize.sh
index 2579ef7b7..4e17effe5 100644
--- a/test/shell/writecache-cache-blocksize.sh
+++ b/test/shell/writecache-cache-blocksize.sh
@@ -222,6 +222,8 @@ vgextend $vg "$dev2"
lvcreate -n $lv1 -l 8 -an $vg "$dev1"
lvcreate -n $lv2 -l 4 -an $vg "$dev2"
lvconvert --yes --type writecache --cachevol $lv2 --cachesettings "block_size=4096" $vg/$lv1
+lvs -o writecacheblocksize $vg/$lv1 |tee out
+grep 4096 out
lvchange -ay $vg/$lv1
mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1" |tee out
grep "sectsz=4096" out
1 year, 7 months
main - man lvmcache: mention writecache memory usage
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6144dac897728a48572...
Commit: 6144dac897728a4857294d70645df8ed7a5ff11f
Parent: 96c99d647ef783abcd26a1f3f63f12e033195633
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Feb 21 11:35:58 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Feb 21 11:35:58 2022 -0600
man lvmcache: mention writecache memory usage
---
man/lvmcache.7_main | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
index dddd33cfa..ce440bf49 100644
--- a/man/lvmcache.7_main
+++ b/man/lvmcache.7_main
@@ -240,6 +240,18 @@ The writecache block size should be chosen to match the xfs sectsz value.
It is also possible to specify a sector size of 4096 to mkfs.xfs when
creating the file system. In this case the writecache block size of 4096
can be used.
+.P
+.SS dm-writecache memory usage
+.P
+The amount of main system memory used by dm-writecache can be a factor
+when selecting the writecache cachevol size and the writecache block size.
+.P
+.IP \[bu] 2
+writecache block size 4096: each 100 GiB of writecache cachevol uses
+slighly over 2 GiB of system memory.
+.IP \[bu] 2
+writecache block size 512: each 100 GiB of writecache cachevol uses
+a little over 16 GiB of system memory.
.
.SS dm-writecache settings
.
1 year, 7 months
main - man: update cachesettings option description
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=96c99d647ef783abcd2...
Commit: 96c99d647ef783abcd26a1f3f63f12e033195633
Parent: ec2119beddde9e38681cb096b93048ee25034c1e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 16 15:36:44 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 16 15:37:54 2022 -0600
man: update cachesettings option description
to be more consistent with man page description
---
tools/args.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index 3f4580b8d..56669645d 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -862,12 +862,13 @@ arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0,
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0,
- "Specifies tunable values for a cache LV in \"Key = Value\" form.\n"
- "Repeat this option to specify multiple values.\n"
- "(The default values should usually be adequate.)\n"
- "The special string value \\fBdefault\\fP switches\n"
- "settings back to their default kernel values and removes\n"
- "them from the list of settings stored in LVM metadata.\n"
+ "Specifies tunable kernel options for dm-cache or dm-writecache LVs.\n"
+ "Use the form 'option=value' or 'option1=value option2=value', or\n"
+ "repeat --cachesettings for each option being set.\n"
+ "These settings override the default kernel behaviors which are\n"
+ "usually adequate. To remove cachesettings and revert to the default\n"
+ "kernel behaviors, use --cachesettings 'default' for dm-cache or\n"
+ "an empty string --cachesettings '' for dm-writecache.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0,
1 year, 7 months
main - man lvmcache: add more writecache cachesettings info
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ec2119beddde9e38681...
Commit: ec2119beddde9e38681cb096b93048ee25034c1e
Parent: d4a0816a5824dc375d662e76823ee8ed77bb9983
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 16 15:21:09 2022 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 16 15:21:09 2022 -0600
man lvmcache: add more writecache cachesettings info
---
man/lvmcache.7_main | 51 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 39 insertions(+), 12 deletions(-)
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
index 8d7d3d17b..dddd33cfa 100644
--- a/man/lvmcache.7_main
+++ b/man/lvmcache.7_main
@@ -243,15 +243,40 @@ can be used.
.
.SS dm-writecache settings
.
-Tunable parameters can be passed to the dm-writecache kernel module using
-the --cachesettings option when caching is started, e.g.
+To specify dm-writecache tunable settings on the command line, use:
+.br
+--cachesettings 'option=N' or
+.br
+--cachesettings 'option1=N option2=N ...'
+.P
+For example, --cachesettings 'high_watermark=90 writeback_jobs=4'.
+.P
+To include settings when caching is started, run:
.P
.nf
# lvconvert --type writecache --cachevol fast \\
- --cachesettings 'high_watermark=N writeback_jobs=N' vg/main
+ --cachesettings 'option=N' vg/main
+.fi
+.P
+To change settings for an existing writecache, run:
+.P
+.nf
+# lvchange --cachesettings 'option=N' vg/main
+.fi
+.P
+To clear all settings that have been applied, run:
+.P
+.nf
+# lvchange --cachesettings '' vg/main
+.fi
+.P
+To view the settings that are applied to a writecache LV, run:
+.P
+.nf
+# lvs -o cachesettings vg/main
.fi
.P
-Tunable options are:
+Tunable settings are:
.
.TP
high_watermark = <percent>
@@ -301,11 +326,14 @@ writecache. Adding cleaner=0 to the splitcache command will skip the
cleaner mode, and any required flushing is performed in device suspend.
.SS dm-writecache using metadata profiles
-
-Writecache allows to set a variety of options. Lots of these settings
-can be specified in lvm.conf or profile settings. You can prepare
-a number of different profiles in the \fI#DEFAULT_SYS_DIR#/profile\fP directory
-and just specify the metadata profile file name when writecaching LV.
+.
+In addition to specifying writecache settings on the command line, they
+can also be set in lvm.conf, or in a profile file, using the
+allocation/cache_settings/writecache config structure shown below.
+.P
+It's possible to prepare a number of different profile files in the
+\fI#DEFAULT_SYS_DIR#/profile\fP directory and specify the file name
+of the profile when starting writecache.
.P
.I Example
.nf
@@ -327,11 +355,10 @@ writeback_jobs=1024
EOF
.P
-# lvcreate -an -L10G --name wcache vg /dev/fast_ssd
-# lvcreate --type writecache -L10G --name main --cachevol wcache \\
+# lvcreate -an -L10G --name fast vg /dev/fast_ssd
+# lvcreate --type writecache -L10G --name main --cachevol fast \\
--metadataprofile cache_writecache vg /dev/slow_hdd
.fi
-
.
.SS dm-cache with separate data and metadata LVs
.
1 year, 7 months
main - dev_manager: use list info for preset devs
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=d4a0816a5824dc375d6...
Commit: d4a0816a5824dc375d662e76823ee8ed77bb9983
Parent: fa7b67eeebfc28bce355991eebe1b5f21f075e9a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Feb 16 00:33:32 2022 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Feb 16 01:00:36 2022 +0100
dev_manager: use list info for preset devs
In some cases we can also use cached info obtained from DM_DEVICE_LIST
also to avoid extra ioctl check for present devices.
---
lib/activate/dev_manager.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index feea06a47..63bfd9b74 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2254,6 +2254,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
{
char *dlid, *name;
struct dm_info info, info2;
+ const struct dm_active_device *dev;
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
return_0;
@@ -2262,15 +2263,20 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return_0;
if (!dm->cmd->disable_dm_devs &&
- dm->cmd->cache_dm_devs &&
- !dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, NULL)) {
- log_debug("Cached as not present %s.", name);
- return 1;
- }
-
- if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
+ dm->cmd->cache_dm_devs) {
+ if (!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, &dev)) {
+ log_debug("Cached as not present %s.", name);
+ return 1;
+ }
+ info = (struct dm_info) {
+ .exists = 1,
+ .major = dev->major,
+ .minor = dev->minor,
+ };
+ log_debug("Cached as present %s %s (%d:%d).",
+ name, dlid, info.major, info.minor);
+ } else if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
return_0;
-
/*
* For top level volumes verify that existing device match
* requested major/minor and that major/minor pair is available for use
1 year, 7 months
main - dev_manager: do not query for open_count
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fa7b67eeebfc28bce35...
Commit: fa7b67eeebfc28bce355991eebe1b5f21f075e9a
Parent: 4fd76de4b69f8e5e6d5afa03d54cb4b8986c4bcc
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Feb 11 23:55:08 2022 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Feb 16 01:00:36 2022 +0100
dev_manager: do not query for open_count
Oepn count is not used along this code path.
---
lib/activate/dev_manager.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 4d18d9838..feea06a47 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2268,7 +2268,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return 1;
}
- if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL))
+ if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
return_0;
/*
1 year, 7 months