master - lvmlockd vdo: add support
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2272a32e6f9b99f9851...
Commit: 2272a32e6f9b99f98514e58de82f8a3baa8b46da
Parent: 82e270c18a76d68e2efc28a194bca2e428c18fae
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Sep 29 14:33:44 2020 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Sep 29 14:43:27 2020 -0500
lvmlockd vdo: add support
lvmlockd handling for vdo lv and vdo pool is like
thin lv and thin pool.
---
lib/locking/lvmlockd.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/metadata/lv_manip.c | 21 ++++++++++++--
2 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 9d11077e3..24b7ff6f7 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -2311,6 +2311,49 @@ static int _lockd_lv_thin(struct cmd_context *cmd, struct logical_volume *lv,
pool_lv->lock_args, def_mode, flags);
}
+static int _lockd_lv_vdo(struct cmd_context *cmd, struct logical_volume *lv,
+ const char *def_mode, uint32_t flags)
+{
+ struct logical_volume *pool_lv = NULL;
+
+ if (lv_is_vdo(lv)) {
+ if (first_seg(lv))
+ pool_lv = seg_lv(first_seg(lv), 0);
+
+ } else if (lv_is_vdo_pool(lv)) {
+ pool_lv = lv;
+
+ } else if (lv_is_vdo_pool_data(lv)) {
+ return 1;
+
+ } else {
+ /* This should not happen AFAIK. */
+ log_error("Lock on incorrect vdo lv type %s/%s",
+ lv->vg->name, lv->name);
+ return 0;
+ }
+
+ if (!pool_lv) {
+ /* This happens in lvremove where it's harmless. */
+ log_debug("No vdo pool for %s/%s", lv->vg->name, lv->name);
+ return 0;
+ }
+
+ /*
+ * Locking a locked lv (pool in this case) is a no-op.
+ * Unlock when the pool is no longer active.
+ */
+
+ if (def_mode && !strcmp(def_mode, "un") &&
+ lv_is_vdo_pool(pool_lv) && lv_is_active(lv_lock_holder(pool_lv)))
+ return 1;
+
+ flags |= LDLV_MODE_NO_SH;
+
+ return lockd_lv_name(cmd, pool_lv->vg, pool_lv->name, &pool_lv->lvid.id[1],
+ pool_lv->lock_args, def_mode, flags);
+}
+
/*
* If the VG has no lock_type, then this function can return immediately.
* The LV itself may have no lock (NULL lv->lock_args), but the lock request
@@ -2352,6 +2395,9 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_thin_type(lv))
return _lockd_lv_thin(cmd, lv, def_mode, flags);
+ if (lv_is_vdo_type(lv))
+ return _lockd_lv_vdo(cmd, lv, def_mode, flags);
+
/*
* An LV with NULL lock_args does not have a lock of its own.
*/
@@ -2724,6 +2770,27 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
return 0;
}
+ } else if (seg_is_vdo(lp)) {
+ struct lv_list *lvl;
+
+ /*
+ * A vdo lv is being created in a vdo pool. The vdo lv does
+ * not have its own lock, the lock of the vdo pool is used, and
+ * the vdo pool needs to be locked to create a vdo lv in it.
+ */
+
+ if (!(lvl = find_lv_in_vg(vg, lp->pool_name))) {
+ log_error("Failed to find vdo pool %s/%s", vg->name, lp->pool_name);
+ return 0;
+ }
+
+ if (!lockd_lv(cmd, lvl->lv, "ex", LDLV_PERSISTENT)) {
+ log_error("Failed to lock vdo pool %s/%s", vg->name, lp->pool_name);
+ return 0;
+ }
+ lv->lock_args = NULL;
+ return 1;
+
} else {
/* Creating a normal lv. */
/* lv_name_lock = lv_name; */
@@ -2963,6 +3030,12 @@ int lockd_lv_uses_lock(struct logical_volume *lv)
if (lv_is_pool_metadata_spare(lv))
return 0;
+ if (lv_is_vdo(lv))
+ return 0;
+
+ if (lv_is_vdo_pool_data(lv))
+ return 0;
+
if (lv_is_cache_vol(lv))
return 0;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 9dbb6e1b5..a907130ff 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1222,8 +1222,19 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
}
/* When removed last VDO user automatically removes VDO pool */
- if (lv_is_vdo_pool(lv) && dm_list_empty(&(lv->segs_using_this_lv)))
- return lv_remove(lv); /* FIXME: any upper level reporting */
+ if (lv_is_vdo_pool(lv) && dm_list_empty(&(lv->segs_using_this_lv))) {
+ struct volume_group *vg = lv->vg;
+
+ if (!lv_remove(lv)) /* FIXME: any upper level reporting */
+ return_0;
+
+ if (vg_is_shared(vg)) {
+ if (!lockd_lv_name(vg->cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args, "un", LDLV_PERSISTENT))
+ log_error("Failed to unlock vdo pool in lvmlockd.");
+ lockd_free_lv(vg->cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args);
+ }
+ return 1;
+ }
return 1;
}
@@ -8730,9 +8741,15 @@ struct logical_volume *lv_create_single(struct volume_group *vg,
/* The VDO segment needs VDO pool which is layer above created striped data LV */
if (!(lp->segtype = get_segtype_from_string(vg->cmd, SEG_TYPE_NAME_VDO_POOL)))
return_NULL;
+
+ /* We want a lockd lock for the new vdo pool, but not the vdo lv. */
+ lp->needs_lockd_init = 1;
+
/* Use vpool names for vdo-pool */
if (!(lv = _lv_create_an_lv(vg, lp, lp->pool_name ? : "vpool%d")))
return_NULL;
+
+ lp->needs_lockd_init = 0;
} else {
log_error(INTERNAL_ERROR "Creation of pool for unsupported segment type %s.",
lp->segtype->name);
3 years, 2 months
master - lvmlockd vdo: disallow use of shared lock on LV
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=82e270c18a76d68e2ef...
Commit: 82e270c18a76d68e2efc28a194bca2e428c18fae
Parent: af8044da3ab6891495f4d96b51a52bc4ae457ffb
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Sep 28 13:48:46 2020 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Sep 29 14:43:26 2020 -0500
lvmlockd vdo: disallow use of shared lock on LV
vdo cannot be active on multiple hosts concurrently
---
lib/locking/lvmlockd.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index dca7954ab..9d11077e3 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -2374,6 +2374,7 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv,
lv_is_thin_type(lv) ||
lv_is_mirror_type(lv) ||
lv_is_raid_type(lv) ||
+ lv_is_vdo_type(lv) ||
lv_is_cache_type(lv)) {
flags |= LDLV_MODE_NO_SH;
}
3 years, 2 months
master - tests: thin-flags
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=af8044da3ab6891495f...
Commit: af8044da3ab6891495f4d96b51a52bc4ae457ffb
Parent: 6728788bf5b7327a167675e99a1e00c168c6c563
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Sep 27 01:24:17 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
tests: thin-flags
---
test/shell/thin-flags.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/shell/thin-flags.sh b/test/shell/thin-flags.sh
index 91bcad12e..78a4b2cd7 100644
--- a/test/shell/thin-flags.sh
+++ b/test/shell/thin-flags.sh
@@ -92,6 +92,9 @@ check lv_attr_bit health $vg/pool "M"
check lv_field $vg/pool lv_health_status "metadata_read_only"
check lv_attr_bit health $vg/$lv2 "-"
+not lvcreate -s $vg/$lv2
+not lvcreate -V10 -n $lv3 $vg/pool
+
lvs -ao+seg_pe_ranges $vg
# needs_check needs newer version
3 years, 2 months
master - debug: remove stacktrace on regular path
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6728788bf5b7327a167...
Commit: 6728788bf5b7327a167675e99a1e00c168c6c563
Parent: 0c89c5a40f8aeda6939a9596615c5d5c1471f352
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Sep 26 14:52:27 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
debug: remove stacktrace on regular path
Here _insert is expected to also fail, so just regular 'return 0'.
---
lib/device/dev-cache.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 7f5e55e8c..84d65c4db 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1158,13 +1158,13 @@ static int _insert(const char *path, const struct stat *info,
}
if (rec && !_insert_dir(path))
- return_0;
+ return 0;
} else { /* add a device */
if (!S_ISBLK(info->st_mode))
return 1;
if (!_insert_dev(path, info->st_rdev))
- return_0;
+ return 0;
}
return 1;
3 years, 2 months
master - debug: update debug message
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=0c89c5a40f8aeda6939...
Commit: 0c89c5a40f8aeda6939a9596615c5d5c1471f352
Parent: bd0d4de4e2bbf7c858482193936311376c916025
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Sep 26 14:54:50 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
debug: update debug message
---
lib/activate/activate.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 7168d24fa..311d33a52 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2934,8 +2934,7 @@ int revert_lv(struct cmd_context *cmd, const struct logical_volume *lv)
ret = lv_resume_if_active(cmd, NULL, 0, 0, 1, lv_committed(lv));
- critical_section_dec(cmd, "unlocking on resume");
+ critical_section_dec(cmd, "unlocking on revert");
return ret;
}
-
3 years, 2 months
master - active: fix compilation without devmapper
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=bd0d4de4e2bbf7c8584...
Commit: bd0d4de4e2bbf7c858482193936311376c916025
Parent: 4cd356b26b85e075490be29b9e1e40b3aafe2d5b
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 28 18:56:58 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
active: fix compilation without devmapper
Better support for compilation without device-mapper.
---
lib/activate/activate.c | 31 +++++++++++++++++--------------
lib/metadata/lv_manip.c | 8 ++++----
lib/metadata/thin_manip.c | 4 ++--
lib/raid/raid.c | 34 +++++++++++++++++-----------------
4 files changed, 40 insertions(+), 37 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 27f44e820..7168d24fa 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -185,8 +185,8 @@ void set_activation(int act, int silent)
if (warned || !act)
return;
- log_error("Compiled without libdevmapper support. "
- "Can't enable activation.");
+ log_warn("WARNING: Compiled without libdevmapper support. "
+ "Can't enable activation.");
warned = 1;
}
@@ -221,23 +221,13 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la
{
return 0;
}
-int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
- struct lvinfo *info, int with_open_count, int with_read_ahead)
-{
- return 0;
-}
-int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
- const struct lv_segment *lv_seg, int use_layer,
+int lv_info_with_seg_status(struct cmd_context *cmd,
+ const struct lv_segment *lv_seg,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead)
{
return 0;
}
-int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
- int use_layer, struct lv_seg_status *lv_seg_status)
-{
- return 0;
-}
int lv_cache_status(const struct logical_volume *cache_lv,
struct lv_status_cache **status)
{
@@ -284,6 +274,10 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
{
return 0;
}
+int lv_writecache_message(const struct logical_volume *lv, const char *msg)
+{
+ return 0;
+}
int lv_thin_pool_status(const struct logical_volume *lv, int flush,
struct lv_status_thin_pool **thin_pool_status)
{
@@ -298,6 +292,15 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
{
return 0;
}
+int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_vdo **vdo_status)
+{
+ return 0;
+}
+int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent)
+{
+ return 0;
+}
int lvs_in_vg_activated(const struct volume_group *vg)
{
return 0;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index d913607fa..9dbb6e1b5 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -8010,10 +8010,10 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
/* Does LV need to be zeroed? */
- if (lp->zero && !seg_is_thin(lp)) {
- log_error("Can't wipe start of new LV without using "
- "device-mapper kernel driver.");
- return NULL;
+ if (lp->zero) {
+ log_warn("WARNING: Skipping zeroing and wipping, compiled without activation support.");
+ lp->zero = 0;
+ lp->wipe_signatures = 0;
}
}
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 91d2317e3..4591dd797 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -545,8 +545,8 @@ int update_pool_lv(struct logical_volume *lv, int activate)
}
if (!lv_is_active(lv)) {
(void) init_dmeventd_monitor(monitored);
- log_error("Cannot activate thin pool %s, perhaps skipped in lvm.conf volume_list?",
- display_lvname(lv));
+ log_error("Cannot activate thin pool %s%s", display_lvname(lv),
+ activation() ? ", perhaps skipped in lvm.conf volume_list?" : ".");
return 0;
}
} else
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index e88a15408..a72e486e9 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -25,10 +25,6 @@
#include "lib/metadata/metadata.h"
#include "lib/metadata/lv_alloc.h"
-static int _raid_target_present(struct cmd_context *cmd,
- const struct lv_segment *seg __attribute__((unused)),
- unsigned *attributes);
-
static void _raid_display(const struct lv_segment *seg)
{
unsigned s;
@@ -240,6 +236,22 @@ static int _raid_text_export(const struct lv_segment *seg, struct formatter *f)
return _raid_text_export_raid(seg, f);
}
+static int _raid_target_status_compatible(const char *type)
+{
+ return (strstr(type, "raid") != NULL);
+}
+
+static void _raid_destroy(struct segment_type *segtype)
+{
+ free((void *) segtype->dso);
+ free(segtype);
+}
+
+#ifdef DEVMAPPER_SUPPORT
+static int _raid_target_present(struct cmd_context *cmd,
+ const struct lv_segment *seg __attribute__((unused)),
+ unsigned *attributes);
+
static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
struct dm_pool *mem __attribute__((unused)),
struct cmd_context *cmd __attribute__((unused)),
@@ -357,18 +369,6 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
return add_areas_line(dm, seg, node, 0u, seg->area_count);
}
-static int _raid_target_status_compatible(const char *type)
-{
- return (strstr(type, "raid") != NULL);
-}
-
-static void _raid_destroy(struct segment_type *segtype)
-{
- free((void *) segtype->dso);
- free(segtype);
-}
-
-#ifdef DEVMAPPER_SUPPORT
static int _raid_target_percent(void **target_state,
dm_percent_t *percent,
struct dm_pool *mem,
@@ -569,9 +569,9 @@ static struct segtype_handler _raid_ops = {
.text_import_area_count = _raid_text_import_area_count,
.text_import = _raid_text_import,
.text_export = _raid_text_export,
- .add_target_line = _raid_add_target_line,
.target_status_compatible = _raid_target_status_compatible,
#ifdef DEVMAPPER_SUPPORT
+ .add_target_line = _raid_add_target_line,
.target_percent = _raid_target_percent,
.target_present = _raid_target_present,
.check_transient_status = _raid_transient_status,
3 years, 2 months
master - thin: remove unneeded code test
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4cd356b26b85e075490...
Commit: 4cd356b26b85e075490be29b9e1e40b3aafe2d5b
Parent: 18c74666ee668c5d4569c868f38c3d8ae950dda1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Sep 27 02:20:50 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
thin: remove unneeded code test
Since we detect already transaction if before starting
to build dm tree - this extra check is a duplicate
that would only capture very tiny 'race' and we later
validate transaction_id with suspended snapshot origin.
---
lib/thin/thin.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 9c4bfb39c..ba0da712d 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -265,8 +265,6 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
char *metadata_dlid, *pool_dlid;
const struct lv_thin_message *lmsg;
const struct logical_volume *origin;
- struct lvinfo info;
- uint64_t transaction_id = 0;
unsigned attr;
uint64_t low_water_mark;
int threshold;
@@ -351,24 +349,6 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
case DM_THIN_MESSAGE_CREATE_THIN:
origin = first_seg(lmsg->u.lv)->origin;
/* Check if the origin is suspended */
- if (origin && lv_info(cmd, origin, 1, &info, 0, 0) &&
- info.exists && !info.suspended) {
- /* Origin is not suspended, but the transaction may have been
- * already transfered, so test for transaction_id and
- * allow to pass in the message for dmtree processing
- * so it will skip all messages later.
- */
- if (!lv_thin_pool_transaction_id(seg->lv, &transaction_id))
- return_0; /* Thin pool should exist and work */
- if ((transaction_id + 1) != seg->transaction_id) {
- log_error("Omitting suspend of thin snapshot origin %s with expected "
- "transaction_id " FMTu64 ", but active pool has " FMTu64 ".",
- display_lvname(origin),
- !seg->transaction_id ? 0 : seg->transaction_id - 1,
- transaction_id);
- return 0;
- }
- }
log_debug_activation("Thin pool create_%s %s.", (!origin) ? "thin" : "snap", lmsg->u.lv->name);
if (!dm_tree_node_add_thin_pool_message(node,
(!origin) ? lmsg->type : DM_THIN_MESSAGE_CREATE_SNAP,
3 years, 2 months
master - thin: validate thin-pool state before sending messages
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=18c74666ee668c5d456...
Commit: 18c74666ee668c5d4569c868f38c3d8ae950dda1
Parent: 4de6f58085c533c79ce2e0db6cdeb6ed06fe05f8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 28 23:12:48 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
thin: validate thin-pool state before sending messages
Alhtough lvm2 does validation on its side, ensure DM code
is not sending messages to failed thin pool.
---
device_mapper/libdm-deptree.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
index a98b1fcdd..d9e1683ca 100644
--- a/device_mapper/libdm-deptree.c
+++ b/device_mapper/libdm-deptree.c
@@ -1666,6 +1666,15 @@ static int _thin_pool_node_send_messages(struct dm_tree_node *dnode,
if (!have_messages || !send)
return 1; /* transaction_id is matching */
+ if (stp.fail || stp.read_only || stp.needs_check) {
+ log_error("Cannot send messages to thin pool %s%s%s%s.",
+ _node_name(dnode),
+ stp.fail ? " in failed state" : "",
+ stp.read_only ? " with read only metadata" : "",
+ stp.needs_check ? " which needs check first" : "");
+ return 0;
+ }
+
dm_list_iterate_items(tmsg, &seg->thin_messages) {
if (!(_thin_pool_node_message(dnode, tmsg)))
return_0;
3 years, 2 months
master - thin: use lv_status_thin and lv_status_thin_pool
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4de6f58085c533c79ce...
Commit: 4de6f58085c533c79ce2e0db6cdeb6ed06fe05f8
Parent: 92c0e8c17f506b551c1b7c0a448d60279e7fdae6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Sep 27 01:11:47 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
thin: use lv_status_thin and lv_status_thin_pool
Introduce structures lv_status_thin_pool and
lv_status_thin (pair to lv_status_cache, lv_status_vdo)
Convert lv_thin_percent() -> lv_thin_status()
and lv_thin_pool_percent() + lv_thin_pool_transaction_id() ->
lv_thin_pool_status().
This way a function user can see not only percentages, but also
other important status info about thin-pool.
TODO:
This patch tries to not change too many other things,
but pool_below_threshold() now uses new thin-pool info to return
failure if thin-pool cannot be actually modified.
This should be handle separately in a better way.
---
lib/activate/activate.c | 83 ++++++++-------------------
lib/activate/activate.h | 10 ++--
lib/activate/dev_manager.c | 118 +++++++++++++++++++++++++--------------
lib/activate/dev_manager.h | 16 ++----
lib/display/display.c | 22 +++++---
lib/metadata/lv_manip.c | 26 +++++----
lib/metadata/metadata-exported.h | 14 +++++
lib/metadata/thin_manip.c | 73 ++++++++++++++++++------
lib/report/properties.c | 60 ++++++++++++--------
9 files changed, 247 insertions(+), 175 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 2e8f0e467..27f44e820 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -284,18 +284,13 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
{
return 0;
}
-int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- dm_percent_t *percent)
+int lv_thin_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **thin_pool_status)
{
return 0;
}
-int lv_thin_percent(const struct logical_volume *lv, int mapped,
- dm_percent_t *percent)
-{
- return 0;
-}
-int lv_thin_pool_transaction_id(const struct logical_volume *lv,
- uint64_t *transaction_id)
+int lv_thin_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin **thin_status)
{
return 0;
}
@@ -1248,86 +1243,52 @@ int lv_cache_status(const struct logical_volume *cache_lv,
return 1;
}
-/*
- * Returns data or metadata percent usage, depends on metadata 0/1.
- * Returns 1 if percent set, else 0 on failure.
- */
-int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- dm_percent_t *percent)
+int lv_thin_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **thin_pool_status)
{
- int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
return 0;
- log_debug_activation("Checking thin %sdata percent for LV %s.",
- (metadata) ? "meta" : "", display_lvname(lv));
+ log_debug_activation("Checking thin pool status for LV %s.",
+ display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
- if (!(r = dev_manager_thin_pool_percent(dm, lv, metadata, percent)))
- stack;
+ if (!dev_manager_thin_pool_status(dm, lv, flush, thin_pool_status)) {
+ dev_manager_destroy(dm);
+ return_0;
+ }
- dev_manager_destroy(dm);
+ /* User has to call dm_pool_destroy(thin_pool_status->mem)! */
- return r;
+ return 1;
}
-/*
- * Returns 1 if percent set, else 0 on failure.
- */
-int lv_thin_percent(const struct logical_volume *lv,
- int mapped, dm_percent_t *percent)
+int lv_thin_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin **thin_status)
{
- int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
- log_debug_activation("Checking thin percent for LV %s.",
+ log_debug_activation("Checking thin status for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
- if (!(r = dev_manager_thin_percent(dm, lv, mapped, percent)))
- stack;
-
- dev_manager_destroy(dm);
-
- return r;
-}
-
-/*
- * Returns 1 if transaction_id set, else 0 on failure.
- */
-int lv_thin_pool_transaction_id(const struct logical_volume *lv,
- uint64_t *transaction_id)
-{
- int r;
- struct dev_manager *dm;
- struct dm_status_thin_pool *status;
-
- if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
- return 0;
-
- log_debug_activation("Checking thin-pool transaction id for LV %s.",
- display_lvname(lv));
-
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ if (!dev_manager_thin_status(dm, lv, flush, thin_status)) {
+ dev_manager_destroy(dm);
return_0;
+ }
- if (!(r = dev_manager_thin_pool_status(dm, lv, &status, 0)))
- stack;
- else
- *transaction_id = status->transaction_id;
-
- dev_manager_destroy(dm);
+ /* User has to call dm_pool_destroy(thin_status->mem)! */
- return r;
+ return 1;
}
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index e3c1bb35e..3f4d128be 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -191,13 +191,11 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg);
int lv_writecache_message(const struct logical_volume *lv, const char *msg);
int lv_cache_status(const struct logical_volume *cache_lv,
struct lv_status_cache **status);
-int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- dm_percent_t *percent);
-int lv_thin_percent(const struct logical_volume *lv, int mapped,
- dm_percent_t *percent);
-int lv_thin_pool_transaction_id(const struct logical_volume *lv,
- uint64_t *transaction_id);
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id);
+int lv_thin_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin **status);
+int lv_thin_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **status);
int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
struct lv_status_vdo **status);
int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent);
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index a626b000a..85cfda246 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1564,9 +1564,6 @@ int dev_manager_cache_status(struct dev_manager *dm,
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
- return_0;
-
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
return_0;
@@ -1589,8 +1586,11 @@ int dev_manager_cache_status(struct dev_manager *dm,
if (!dm_get_status_cache(dm->mem, params, &c))
goto_out;
- (*status)->cache = c;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
+ goto_out;
+
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
+ (*status)->cache = c;
if (c->fail || c->error) {
(*status)->data_usage =
(*status)->metadata_usage =
@@ -1612,10 +1612,10 @@ out:
}
int dev_manager_thin_pool_status(struct dev_manager *dm,
- const struct logical_volume *lv,
- struct dm_status_thin_pool **status,
- int flush)
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **status)
{
+ struct dm_status_thin_pool *dm_status;
const char *dlid;
struct dm_task *dmt;
struct dm_info info;
@@ -1636,11 +1636,31 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
- /* FIXME Check for thin and check there's exactly one target */
+ if (!type || strcmp(type, TARGET_NAME_THIN_POOL)) {
+ log_error("Expected %s segment type but got %s instead.",
+ TARGET_NAME_THIN_POOL, type ? type : "NULL");
+ goto out;
+ }
- if (!dm_get_status_thin_pool(dm->mem, params, status))
+ if (!dm_get_status_thin_pool(dm->mem, params, &dm_status))
goto_out;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin_pool))))
+ goto_out;
+
+ (*status)->mem = dm->mem;
+ (*status)->thin_pool = dm_status;
+
+ if (dm_status->fail || dm_status->error) {
+ (*status)->data_usage =
+ (*status)->metadata_usage = DM_PERCENT_INVALID;
+ } else {
+ (*status)->data_usage = dm_make_percent(dm_status->used_data_blocks,
+ dm_status->total_data_blocks);
+ (*status)->metadata_usage = dm_make_percent(dm_status->used_metadata_blocks,
+ dm_status->total_metadata_blocks);
+ }
+
r = 1;
out:
dm_task_destroy(dmt);
@@ -1648,52 +1668,68 @@ out:
return r;
}
-int dev_manager_thin_pool_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int metadata, dm_percent_t *percent)
+int dev_manager_thin_status(struct dev_manager *dm,
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin **status)
{
- char *name;
+ struct dm_status_thin *dm_status;
const char *dlid;
- const char *layer = lv_layer(lv);
+ struct dm_task *dmt;
+ struct dm_info info;
+ uint64_t start, length;
+ char *type = NULL;
+ char *params = NULL;
+ uint64_t csize;
+ int r = 0;
- /* Build a name for the top layer */
- if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
+ if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
+ if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
return_0;
- log_debug_activation("Getting device status percentage for %s.", name);
-
- if (!(_percent(dm, name, dlid, TARGET_NAME_THIN_POOL, 0,
- (metadata) ? lv : NULL, percent, NULL, 1)))
- return_0;
+ if (!info.exists)
+ goto_out;
- return 1;
-}
+ dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
-int dev_manager_thin_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int mapped, dm_percent_t *percent)
-{
- char *name;
- const char *dlid;
- const char *layer = lv_layer(lv);
+ if (!type || strcmp(type, TARGET_NAME_THIN)) {
+ log_error("Expected %s segment type but got %s instead.",
+ TARGET_NAME_THIN, type ? type : "NULL");
+ goto out;
+ }
- /* Build a name for the top layer */
- if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
- return_0;
+ if (!dm_get_status_thin(dm->mem, params, &dm_status))
+ goto_out;
- if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
- return_0;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin))))
+ goto_out;
- log_debug_activation("Getting device status percentage for %s", name);
+ (*status)->mem = dm->mem;
+ (*status)->thin = dm_status;
+
+ if (dm_status->fail)
+ (*status)->usage = DM_PERCENT_INVALID;
+ else {
+ /* Pool allocates whole chunk so round-up to nearest one */
+ csize = first_seg(first_seg(lv)->pool_lv)->chunk_size;
+ csize = ((lv->size + csize - 1) / csize) * csize;
+ if (dm_status->mapped_sectors > csize) {
+ log_warn("WARNING: LV %s maps %s while the size is only %s.",
+ display_lvname(lv),
+ display_size(dm->cmd, dm_status->mapped_sectors),
+ display_size(dm->cmd, csize));
+ /* Don't show nonsense numbers like i.e. 1000% full */
+ dm_status->mapped_sectors = csize;
+ }
+ (*status)->usage = dm_make_percent(dm_status->mapped_sectors, csize);
+ }
- if (!(_percent(dm, name, dlid, TARGET_NAME_THIN, 0,
- (mapped) ? NULL : lv, percent, NULL, 1)))
- return_0;
+ r = 1;
+out:
+ dm_task_destroy(dmt);
- return 1;
+ return r;
}
/*
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h
index 5bff47799..557418201 100644
--- a/lib/activate/dev_manager.h
+++ b/lib/activate/dev_manager.h
@@ -69,19 +69,15 @@ int dev_manager_writecache_message(struct dev_manager *dm,
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_cache **status);
-int dev_manager_thin_pool_status(struct dev_manager *dm,
- const struct logical_volume *lv,
- struct dm_status_thin_pool **status,
- int flush);
-int dev_manager_thin_pool_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int metadata, dm_percent_t *percent);
-int dev_manager_thin_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int mapped, dm_percent_t *percent);
+int dev_manager_thin_status(struct dev_manager *dm,
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin **status);
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id);
+int dev_manager_thin_pool_status(struct dev_manager *dm,
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **status);
int dev_manager_vdo_pool_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_vdo **vdo_status,
diff --git a/lib/display/display.c b/lib/display/display.c
index 36c9879b3..6ef46f1e8 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -406,10 +406,12 @@ int lvdisplay_full(struct cmd_context *cmd,
struct lv_segment *seg = NULL;
int lvm1compat;
dm_percent_t snap_percent;
- int thin_data_active = 0, thin_metadata_active = 0;
+ int thin_pool_active = 0;
dm_percent_t thin_data_percent, thin_metadata_percent;
int thin_active = 0;
dm_percent_t thin_percent;
+ struct lv_status_thin *thin_status = NULL;
+ struct lv_status_thin_pool *thin_pool_status = NULL;
struct lv_status_cache *cache_status = NULL;
struct lv_status_vdo *vdo_status = NULL;
@@ -503,15 +505,18 @@ int lvdisplay_full(struct cmd_context *cmd,
if (seg->merge_lv)
log_print("LV merging to %s",
seg->merge_lv->name);
- if (inkernel)
- thin_active = lv_thin_percent(lv, 0, &thin_percent);
+ if (inkernel && (thin_active = lv_thin_status(lv, 0, &thin_status))) {
+ thin_percent = thin_status->usage;
+ dm_pool_destroy(thin_status->mem);
+ }
if (lv_is_merging_origin(lv))
log_print("LV merged with %s",
find_snapshot(lv)->lv->name);
} else if (lv_is_thin_pool(lv)) {
- if (lv_info(cmd, lv, 1, &info, 1, 1) && info.exists) {
- thin_data_active = lv_thin_pool_percent(lv, 0, &thin_data_percent);
- thin_metadata_active = lv_thin_pool_percent(lv, 1, &thin_metadata_percent);
+ if ((thin_pool_active = lv_thin_pool_status(lv, 0, &thin_pool_status))) {
+ thin_data_percent = thin_pool_status->data_usage;
+ thin_metadata_percent = thin_pool_status->metadata_usage;
+ dm_pool_destroy(thin_pool_status->mem);
}
/* FIXME: display thin_pool targets transid for activated LV as well */
seg = first_seg(lv);
@@ -591,13 +596,12 @@ int lvdisplay_full(struct cmd_context *cmd,
dm_pool_destroy(cache_status->mem);
}
- if (thin_data_active)
+ if (thin_pool_active) {
log_print("Allocated pool data %s%%",
display_percent(cmd, thin_data_percent));
-
- if (thin_metadata_active)
log_print("Allocated metadata %s%%",
display_percent(cmd, thin_metadata_percent));
+ }
if (thin_active)
log_print("Mapped size %s%%",
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 6a89f1ec0..d913607fa 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4960,6 +4960,7 @@ static int _lvresize_adjust_policy(const struct logical_volume *lv,
dm_percent_t percent;
dm_percent_t min_threshold;
int policy_threshold, policy_amount;
+ struct lv_status_thin_pool *thin_pool_status;
*amount = *meta_amount = 0;
@@ -5009,18 +5010,19 @@ static int _lvresize_adjust_policy(const struct logical_volume *lv,
}
if (lv_is_thin_pool(lv)) {
- if (!lv_thin_pool_percent(lv, 1, &percent))
+ if (!lv_thin_pool_status(lv, 0, &thin_pool_status))
goto_bad;
/* Resize below the minimal usable value */
min_threshold = pool_metadata_min_threshold(first_seg(lv)) / DM_PERCENT_1;
- *meta_amount = _adjust_amount(percent, (min_threshold < policy_threshold) ?
+ *meta_amount = _adjust_amount(thin_pool_status->metadata_usage,
+ (min_threshold < policy_threshold) ?
min_threshold : policy_threshold, policy_amount);
if (*meta_amount)
/* Compensate possible extra space consumption by kernel on resize */
(*meta_amount)++;
- if (!lv_thin_pool_percent(lv, 0, &percent))
- goto_bad;
+ percent = thin_pool_status->data_usage;
+ dm_pool_destroy(thin_pool_status->mem);
} else if (lv_is_vdo_pool(lv)) {
if (!lv_vdo_pool_percent(lv, &percent))
goto_bad;
@@ -8464,17 +8466,21 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
* and needs to be restored to the state from this canceled segment.
* TODO: there is low chance actual suspend has failed
*/
- if (!lv_thin_pool_transaction_id(pool_lv, &transaction_id)) {
+ struct lv_status_thin_pool *tpstatus;
+ if (!lv_thin_pool_status(pool_lv, 1, &tpstatus))
log_error("Aborting. Failed to read transaction_id from thin pool %s.",
display_lvname(pool_lv)); /* Can't even get thin pool transaction id ??? */
- } else if (transaction_id != first_seg(pool_lv)->transaction_id) {
- if (transaction_id == seg->transaction_id)
- log_debug_metadata("Reverting back transaction_id " FMTu64 " for thin pool %s.",
- seg->transaction_id, display_lvname(pool_lv));
- else
+ else {
+ transaction_id = tpstatus->thin_pool->transaction_id;
+ dm_pool_destroy(tpstatus->mem);
+
+ if ((transaction_id != first_seg(pool_lv)->transaction_id) &&
+ (transaction_id != seg->transaction_id))
log_warn("WARNING: Metadata for thin pool %s have transaction_id " FMTu64
", but active pool has " FMTu64 ".",
display_lvname(pool_lv), seg->transaction_id, transaction_id);
+ log_debug_metadata("Restoring previous transaction_id " FMTu64 " for thin pool %s.",
+ seg->transaction_id, display_lvname(pool_lv));
first_seg(pool_lv)->transaction_id = seg->transaction_id;
first_seg(lv)->device_id = 0; /* no delete of never existing thin device */
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index b109d5b6d..c4d51998b 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -887,6 +887,20 @@ int update_thin_pool_params(struct cmd_context *cmd,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_method, uint32_t *chunk_size,
thin_discards_t *discards, thin_zero_t *zero_new_blocks);
+
+struct lv_status_thin_pool {
+ struct dm_pool *mem;
+ struct dm_status_thin_pool *thin_pool;
+ dm_percent_t data_usage;
+ dm_percent_t metadata_usage;
+};
+
+struct lv_status_thin {
+ struct dm_pool *mem;
+ struct dm_status_thin *thin;
+ dm_percent_t usage;
+};
+
const char *get_pool_discards_name(thin_discards_t discards);
int set_pool_discards(thin_discards_t *discards, const char *str);
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index e3364ddc8..91d2317e3 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -243,49 +243,86 @@ int pool_metadata_min_threshold(const struct lv_segment *pool_seg)
int pool_below_threshold(const struct lv_segment *pool_seg)
{
struct cmd_context *cmd = pool_seg->lv->vg->cmd;
- dm_percent_t percent;
+ struct lv_status_thin_pool *thin_pool_status = NULL;
dm_percent_t min_threshold = pool_metadata_min_threshold(pool_seg);
dm_percent_t threshold = DM_PERCENT_1 *
find_config_tree_int(cmd, activation_thin_pool_autoextend_threshold_CFG,
lv_config_profile(pool_seg->lv));
+ int ret = 1;
- /* Data */
- if (!lv_thin_pool_percent(pool_seg->lv, 0, &percent))
+ if (threshold > DM_PERCENT_100)
+ threshold = DM_PERCENT_100;
+
+ /* FIXME: currently with FLUSH - this may block pool while holding VG lock
+ * maybe try 2-phase version - 1st. check without commit
+ * 2nd. quickly following with commit */
+ if (!lv_thin_pool_status(pool_seg->lv, 1, &thin_pool_status))
return_0;
- if (percent > threshold || percent >= DM_PERCENT_100) {
+ if (thin_pool_status->thin_pool->fail |
+ thin_pool_status->thin_pool->out_of_data_space |
+ thin_pool_status->thin_pool->needs_check |
+ thin_pool_status->thin_pool->error |
+ thin_pool_status->thin_pool->read_only) {
+ log_warn("WARNING: Thin pool %s%s%s%s%s%s.",
+ display_lvname(pool_seg->lv),
+ thin_pool_status->thin_pool->fail ? " is failed" : "",
+ thin_pool_status->thin_pool->out_of_data_space ? " is out of data space" : "",
+ thin_pool_status->thin_pool->needs_check ? " needs check" : "",
+ thin_pool_status->thin_pool->error ? " is erroring" : "",
+ thin_pool_status->thin_pool->read_only ? " has read-only metadata" : "");
+ ret = 0;
+ if (thin_pool_status->thin_pool->fail)
+ goto out;
+ }
+
+ /* Data */
+
+ if (thin_pool_status->data_usage > threshold) {
log_debug("Threshold configured for free data space in "
"thin pool %s has been reached (%s%% >= %s%%).",
display_lvname(pool_seg->lv),
- display_percent(cmd, percent),
+ display_percent(cmd, thin_pool_status->data_usage),
display_percent(cmd, threshold));
- return 0;
+ ret = 0;
}
/* Metadata */
- if (!lv_thin_pool_percent(pool_seg->lv, 1, &percent))
- return_0;
- if (percent >= min_threshold) {
+ if (thin_pool_status->metadata_usage >= min_threshold) {
log_warn("WARNING: Remaining free space in metadata of thin pool %s "
"is too low (%s%% >= %s%%). "
"Resize is recommended.",
display_lvname(pool_seg->lv),
- display_percent(cmd, percent),
+ display_percent(cmd, thin_pool_status->metadata_usage),
display_percent(cmd, min_threshold));
- return 0;
+ ret = 0;
}
- if (percent > threshold) {
+ if (thin_pool_status->metadata_usage > threshold) {
log_debug("Threshold configured for free metadata space in "
"thin pool %s has been reached (%s%% > %s%%).",
display_lvname(pool_seg->lv),
- display_percent(cmd, percent),
+ display_percent(cmd, thin_pool_status->metadata_usage),
display_percent(cmd, threshold));
- return 0;
+ ret = 0;
}
- return 1;
+ if ((thin_pool_status->thin_pool->transaction_id != pool_seg->transaction_id) &&
+ (dm_list_empty(&pool_seg->thin_messages) ||
+ ((thin_pool_status->thin_pool->transaction_id + 1) != pool_seg->transaction_id))) {
+ log_warn("WARNING: Thin pool %s has unexpected transaction id " FMTu64
+ ", expecting " FMTu64 "%s.",
+ display_lvname(pool_seg->lv),
+ thin_pool_status->thin_pool->transaction_id,
+ pool_seg->transaction_id,
+ dm_list_empty(&pool_seg->thin_messages) ? "" : " or lower by 1");
+ ret = 0;
+ }
+out:
+ dm_pool_destroy(thin_pool_status->mem);
+
+ return ret;
}
/*
@@ -853,6 +890,7 @@ int check_new_thin_pool(const struct logical_volume *pool_lv)
{
struct cmd_context *cmd = pool_lv->vg->cmd;
uint64_t transaction_id;
+ struct lv_status_thin_pool *status = NULL;
/* For transaction_id check LOCAL activation is required */
if (!activate_lv(cmd, pool_lv)) {
@@ -862,12 +900,15 @@ int check_new_thin_pool(const struct logical_volume *pool_lv)
}
/* With volume lists, check pool really is locally active */
- if (!lv_thin_pool_transaction_id(pool_lv, &transaction_id)) {
+ if (!lv_thin_pool_status(pool_lv, 1, &status)) {
log_error("Cannot read thin pool %s transaction id locally, perhaps skipped in lvm.conf volume_list?",
display_lvname(pool_lv));
return 0;
}
+ transaction_id = status->thin_pool->transaction_id;
+ dm_pool_destroy(status->mem);
+
/* Require pool to have same transaction_id as new */
if (first_seg(pool_lv)->transaction_id != transaction_id) {
log_error("Cannot use thin pool %s with transaction id "
diff --git a/lib/report/properties.c b/lib/report/properties.c
index d4ac8c47e..ef2888f50 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -142,47 +142,63 @@ static dm_percent_t _snap_percent(const struct logical_volume *lv)
static dm_percent_t _data_percent(const struct logical_volume *lv)
{
- dm_percent_t percent;
- struct lv_status_cache *status;
+ dm_percent_t percent = DM_PERCENT_INVALID;
+ struct lv_status_cache *cache_status;
+ struct lv_status_thin *thin_status;
+ struct lv_status_thin_pool *thin_pool_status;
if (lv_is_cow(lv))
return _snap_percent(lv);
if (lv_is_cache(lv) || lv_is_used_cache_pool(lv)) {
- if (!lv_cache_status(lv, &status)) {
+ if (!lv_cache_status(lv, &cache_status))
+ stack;
+ else {
+ percent = cache_status->data_usage;
+ dm_pool_destroy(cache_status->mem);
+ }
+ } else if (lv_is_thin_volume(lv)) {
+ if (!lv_thin_status(lv, 0, &thin_status))
stack;
- return DM_PERCENT_INVALID;
+ else {
+ percent = thin_status->usage;
+ dm_pool_destroy(thin_status->mem);
+ }
+ } else if (lv_is_thin_pool(lv)) {
+ if (!lv_thin_pool_status(lv, 0, &thin_pool_status))
+ stack;
+ else {
+ percent = thin_pool_status->metadata_usage;
+ dm_pool_destroy(thin_pool_status->mem);
}
- percent = status->data_usage;
- dm_pool_destroy(status->mem);
- return percent;
}
- if (lv_is_thin_volume(lv))
- return lv_thin_percent(lv, 0, &percent) ? percent : DM_PERCENT_INVALID;
-
- return lv_thin_pool_percent(lv, 0, &percent) ? percent : DM_PERCENT_INVALID;
+ return percent;
}
static dm_percent_t _metadata_percent(const struct logical_volume *lv)
{
- dm_percent_t percent;
- struct lv_status_cache *status;
+ dm_percent_t percent = DM_PERCENT_INVALID;
+ struct lv_status_cache *cache_status;
+ struct lv_status_thin_pool *thin_pool_status;
if (lv_is_cache(lv) || lv_is_used_cache_pool(lv)) {
- if (!lv_cache_status(lv, &status)) {
+ if (!lv_cache_status(lv, &cache_status))
+ stack;
+ else {
+ percent = cache_status->metadata_usage;
+ dm_pool_destroy(cache_status->mem);
+ }
+ } else if (lv_is_thin_pool(lv)) {
+ if (!lv_thin_pool_status(lv, 0, &thin_pool_status))
stack;
- return DM_PERCENT_INVALID;
+ else {
+ percent = thin_pool_status->metadata_usage;
+ dm_pool_destroy(thin_pool_status->mem);
}
- percent = status->metadata_usage;
- dm_pool_destroy(status->mem);
- return percent;
}
- if (lv_is_thin_pool(lv))
- return lv_thin_pool_percent(lv, 1, &percent) ? percent : DM_PERCENT_INVALID;
-
- return DM_PERCENT_INVALID;
+ return percent;
}
/* PV */
3 years, 2 months
master - writecache: archive before modification of metadata
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=92c0e8c17f506b551c1...
Commit: 92c0e8c17f506b551c1b7c0a448d60279e7fdae6
Parent: 08e838f488415ce6c7df594327c383cdc7c2dcd7
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 28 19:17:54 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
writecache: archive before modification of metadata
Archive before we start to modify metadata.
---
lib/metadata/lv_manip.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 793a86d1f..6a89f1ec0 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6506,6 +6506,9 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
+ if (!archive(vg))
+ return_0;
+
if (!lv_detach_writecache_cachevol(lv, 1)) {
log_error("Failed to detach writecache from %s", display_lvname(lv));
return 0;
3 years, 2 months