From: Zdenek Kabelac <zkabelac@sourceware.org>
To: lvm-devel@redhat.com
Subject: main - dev_manager: add lv_raid_status
Date: Thu, 18 Mar 2021 18:14:58 +0000 (GMT) [thread overview]
Message-ID: <20210318181458.E26313848011@sourceware.org> (raw)
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a9b4acd511beb4d5ba8d0175ad1fb56927d92c03
Commit: a9b4acd511beb4d5ba8d0175ad1fb56927d92c03
Parent: e5a600860c1b00cd4199eafe26dbc668f8f583ff
Author: Zdenek Kabelac <zkabelac@redhat.com>
AuthorDate: Wed Mar 17 09:50:09 2021 +0100
Committer: Zdenek Kabelac <zkabelac@redhat.com>
CommitterDate: Thu Mar 18 18:34:57 2021 +0100
dev_manager: add lv_raid_status
Just like with other segtype use this function to get whole
raid status info available per a single ioctl call.
Also it nicely simplifies read of percentage info about
in_sync portion of raid volume.
TODO: drop use of other calls then lv_raid_status call,
since all such calls could already use status - so it just
adds unnecessary duplication.
---
lib/activate/activate.c | 133 +++++++++++++++++++--------------------
lib/activate/activate.h | 1 +
lib/activate/dev_manager.c | 20 ++++--
lib/activate/dev_manager.h | 2 +-
lib/metadata/metadata-exported.h | 5 ++
5 files changed, 88 insertions(+), 73 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 08afd6f38..8151293c3 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -972,35 +972,28 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
{
- int r;
- struct dev_manager *dm;
- struct dm_status_raid *status;
+ struct lv_status_raid *raid_status;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
lv->vg->name, lv->name);
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
- return_0;
- if (!(r = dev_manager_raid_status(dm, lv, &status))) {
- dev_manager_destroy(dm);
- return_0;
- }
+ if (!lv_raid_status(lv, &raid_status))
+ return_0;
- *data_offset = status->data_offset;
+ *data_offset = raid_status->raid->data_offset;
- dev_manager_destroy(dm);
+ dm_pool_destroy(raid_status->mem);
- return r;
+ return 1;
}
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
{
- int r;
- struct dev_manager *dm;
- struct dm_status_raid *status;
+ int r = 1;
+ struct lv_status_raid *raid_status;
*dev_health = NULL;
@@ -1010,25 +1003,23 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
log_debug_activation("Checking raid device health for LV %s.",
display_lvname(lv));
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
- return_0;
+ if (!lv_raid_status(lv, &raid_status))
+ return_0;
- if (!(r = dev_manager_raid_status(dm, lv, &status)) ||
- !(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
- status->dev_health))) {
- dev_manager_destroy(dm);
- return_0;
+ if (!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
+ raid_status->raid->dev_health))) {
+ stack;
+ r = 0;
}
- dev_manager_destroy(dm);
+ dm_pool_destroy(raid_status->mem);
return r;
}
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
{
- struct dev_manager *dm;
- struct dm_status_raid *status;
+ struct lv_status_raid *raid_status;
*dev_cnt = 0;
@@ -1037,24 +1028,20 @@ int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
log_debug_activation("Checking raid device count for LV %s/%s",
lv->vg->name, lv->name);
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
- return_0;
- if (!dev_manager_raid_status(dm, lv, &status)) {
- dev_manager_destroy(dm);
+ if (!lv_raid_status(lv, &raid_status))
return_0;
- }
- *dev_cnt = status->dev_count;
- dev_manager_destroy(dm);
+ *dev_cnt = raid_status->raid->dev_count;
+
+ dm_pool_destroy(raid_status->mem);
return 1;
}
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
{
- struct dev_manager *dm;
- struct dm_status_raid *status;
+ struct lv_status_raid *raid_status;
*cnt = 0;
@@ -1064,25 +1051,20 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
log_debug_activation("Checking raid mismatch count for LV %s.",
display_lvname(lv));
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ if (!lv_raid_status(lv, &raid_status))
return_0;
- if (!dev_manager_raid_status(dm, lv, &status)) {
- dev_manager_destroy(dm);
- return_0;
- }
- *cnt = status->mismatch_count;
+ *cnt = raid_status->raid->mismatch_count;
- dev_manager_destroy(dm);
+ dm_pool_destroy(raid_status->mem);
return 1;
}
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
{
- struct dev_manager *dm;
- struct dm_status_raid *status;
- char *action;
+ struct lv_status_raid *raid_status;
+ int r = 1;
*sync_action = NULL;
@@ -1092,30 +1074,27 @@ int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
log_debug_activation("Checking raid sync_action for LV %s.",
display_lvname(lv));
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ if (!lv_raid_status(lv, &raid_status))
return_0;
/* status->sync_action can be NULL if dm-raid version < 1.5.0 */
- if (!dev_manager_raid_status(dm, lv, &status) ||
- !status->sync_action ||
- !(action = dm_pool_strdup(lv->vg->cmd->mem,
- status->sync_action))) {
- dev_manager_destroy(dm);
- return_0;
+ if (!raid_status->raid->sync_action ||
+ !(*sync_action = dm_pool_strdup(lv->vg->cmd->mem,
+ raid_status->raid->sync_action))) {
+ stack;
+ r = 0;
}
- *sync_action = action;
-
- dev_manager_destroy(dm);
+ dm_pool_destroy(raid_status->mem);
- return 1;
+ return r;
}
int lv_raid_message(const struct logical_volume *lv, const char *msg)
{
+ struct lv_status_raid *raid_status;
+ struct dev_manager *dm = NULL;
int r = 0;
- struct dev_manager *dm;
- struct dm_status_raid *status;
if (!seg_is_raid(first_seg(lv))) {
/*
@@ -1140,16 +1119,10 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
return 0;
}
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ if (!lv_raid_status(lv, &raid_status))
return_0;
- if (!(r = dev_manager_raid_status(dm, lv, &status))) {
- log_error("Failed to retrieve status of %s.",
- display_lvname(lv));
- goto out;
- }
-
- if (!status->sync_action) {
+ if (!raid_status->raid->sync_action) {
log_error("Kernel driver does not support this action: %s", msg);
goto out;
}
@@ -1171,19 +1144,43 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
log_error("\"%s\" is not a supported sync operation.", msg);
goto out;
}
- if (strcmp(status->sync_action, "idle")) {
+ if (strcmp(raid_status->raid->sync_action, "idle")) {
log_error("%s state is currently \"%s\". Unable to switch to \"%s\".",
- display_lvname(lv), status->sync_action, msg);
+ display_lvname(lv), raid_status->raid->sync_action, msg);
goto out;
}
+ if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ return_0;
+
r = dev_manager_raid_message(dm, lv, msg);
out:
- dev_manager_destroy(dm);
+ if (dm)
+ dev_manager_destroy(dm);
+ dm_pool_destroy(raid_status->mem);
return r;
}
+int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status)
+{
+ struct dev_manager *dm;
+ int exists;
+
+ if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ return_0;
+
+ if (!dev_manager_raid_status(dm, lv, status, &exists)) {
+ dev_manager_destroy(dm);
+ if (exists)
+ stack;
+ return 0;
+ }
+ /* User has to call dm_pool_destroy(status->mem)! */
+
+ return 1;
+}
+
int lv_writecache_message(const struct logical_volume *lv, const char *msg)
{
int r = 0;
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 4c9328a66..edd385aef 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -188,6 +188,7 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
int lv_raid_message(const struct logical_volume *lv, const char *msg);
+int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status);
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);
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 40b9ef31d..98917dc38 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1437,7 +1437,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
int dev_manager_raid_status(struct dev_manager *dm,
const struct logical_volume *lv,
- struct dm_status_raid **status)
+ struct lv_status_raid **status, int *exists)
{
int r = 0;
const char *dlid;
@@ -1447,6 +1447,11 @@ int dev_manager_raid_status(struct dev_manager *dm,
char *type = NULL;
char *params = NULL;
const char *layer = lv_layer(lv);
+ struct dm_status_raid *sr;
+
+ *exists = -1;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
+ return_0;
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
return_0;
@@ -1454,8 +1459,11 @@ int dev_manager_raid_status(struct dev_manager *dm,
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
return_0;
- if (!info.exists)
- goto_out;
+ if (!(*exists = info.exists))
+ goto out;
+
+ log_debug_activation("Checking raid status for volume %s.",
+ display_lvname(lv));
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
@@ -1467,9 +1475,13 @@ int dev_manager_raid_status(struct dev_manager *dm,
/* FIXME Check there's only one target */
- if (!dm_get_status_raid(dm->mem, params, status))
+ if (!dm_get_status_raid(dm->mem, params, &sr))
goto_out;
+ (*status)->mem = dm->mem; /* User has to destroy this mem pool later */
+ (*status)->raid = sr;
+ (*status)->in_sync = dm_make_percent(sr->insync_regions, sr->total_regions);
+
r = 1;
out:
dm_task_destroy(dmt);
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h
index dcd08818d..27092f2b9 100644
--- a/lib/activate/dev_manager.h
+++ b/lib/activate/dev_manager.h
@@ -59,7 +59,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
dm_percent_t *percent, uint32_t *event_nr);
int dev_manager_raid_status(struct dev_manager *dm,
const struct logical_volume *lv,
- struct dm_status_raid **status);
+ struct lv_status_raid **status, int *exists);
int dev_manager_raid_message(struct dev_manager *dm,
const struct logical_volume *lv,
const char *msg);
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 874088993..8ae067ebc 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1239,6 +1239,11 @@ int collapse_mirrored_lv(struct logical_volume *lv);
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
/* ++ metadata/raid_manip.c */
+struct lv_status_raid {
+ struct dm_pool *mem;
+ struct dm_status_raid *raid;
+ dm_percent_t in_sync;
+};
int lv_is_raid_with_tracking(const struct logical_volume *lv);
uint32_t lv_raid_image_count(const struct logical_volume *lv);
int lv_raid_change_image_count(struct logical_volume *lv,
reply other threads:[~2021-03-18 18:14 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210318181458.E26313848011@sourceware.org \
--to=zkabelac@sourceware.org \
--cc=lvm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.