[lvm-devel] dev-next - dev_manager: add lv_raid_status
David Teigland
teigland at sourceware.org
Mon Mar 22 15:39:13 UTC 2021
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a9b4acd511beb4d5ba8d0175ad1fb56927d92c03
Commit: a9b4acd511beb4d5ba8d0175ad1fb56927d92c03
Parent: e5a600860c1b00cd4199eafe26dbc668f8f583ff
Author: Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate: Wed Mar 17 09:50:09 2021 +0100
Committer: Zdenek Kabelac <zkabelac at 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,
More information about the lvm-devel
mailing list