mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
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.
This commit is contained in:
parent
e5a600860c
commit
a9b4acd511
@ -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 lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
|
||||||
{
|
{
|
||||||
int r;
|
struct lv_status_raid *raid_status;
|
||||||
struct dev_manager *dm;
|
|
||||||
struct dm_status_raid *status;
|
|
||||||
|
|
||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
|
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
|
||||||
lv->vg->name, lv->name);
|
lv->vg->name, lv->name);
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
|
||||||
|
if (!lv_raid_status(lv, &raid_status))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
*data_offset = raid_status->raid->data_offset;
|
||||||
dev_manager_destroy(dm);
|
|
||||||
return_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data_offset = status->data_offset;
|
dm_pool_destroy(raid_status->mem);
|
||||||
|
|
||||||
dev_manager_destroy(dm);
|
return 1;
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
|
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
|
||||||
{
|
{
|
||||||
int r;
|
int r = 1;
|
||||||
struct dev_manager *dm;
|
struct lv_status_raid *raid_status;
|
||||||
struct dm_status_raid *status;
|
|
||||||
|
|
||||||
*dev_health = NULL;
|
*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.",
|
log_debug_activation("Checking raid device health for LV %s.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!lv_raid_status(lv, &raid_status))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(r = dev_manager_raid_status(dm, lv, &status)) ||
|
if (!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
|
||||||
!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
|
raid_status->raid->dev_health))) {
|
||||||
status->dev_health))) {
|
stack;
|
||||||
dev_manager_destroy(dm);
|
r = 0;
|
||||||
return_0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_manager_destroy(dm);
|
dm_pool_destroy(raid_status->mem);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
|
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
|
||||||
{
|
{
|
||||||
struct dev_manager *dm;
|
struct lv_status_raid *raid_status;
|
||||||
struct dm_status_raid *status;
|
|
||||||
|
|
||||||
*dev_cnt = 0;
|
*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",
|
log_debug_activation("Checking raid device count for LV %s/%s",
|
||||||
lv->vg->name, lv->name);
|
lv->vg->name, lv->name);
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
|
||||||
|
if (!lv_raid_status(lv, &raid_status))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!dev_manager_raid_status(dm, lv, &status)) {
|
*dev_cnt = raid_status->raid->dev_count;
|
||||||
dev_manager_destroy(dm);
|
|
||||||
return_0;
|
|
||||||
}
|
|
||||||
*dev_cnt = status->dev_count;
|
|
||||||
|
|
||||||
dev_manager_destroy(dm);
|
dm_pool_destroy(raid_status->mem);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
|
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
|
||||||
{
|
{
|
||||||
struct dev_manager *dm;
|
struct lv_status_raid *raid_status;
|
||||||
struct dm_status_raid *status;
|
|
||||||
|
|
||||||
*cnt = 0;
|
*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.",
|
log_debug_activation("Checking raid mismatch count for LV %s.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!lv_raid_status(lv, &raid_status))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!dev_manager_raid_status(dm, lv, &status)) {
|
*cnt = raid_status->raid->mismatch_count;
|
||||||
dev_manager_destroy(dm);
|
|
||||||
return_0;
|
|
||||||
}
|
|
||||||
*cnt = status->mismatch_count;
|
|
||||||
|
|
||||||
dev_manager_destroy(dm);
|
dm_pool_destroy(raid_status->mem);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
|
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
|
||||||
{
|
{
|
||||||
struct dev_manager *dm;
|
struct lv_status_raid *raid_status;
|
||||||
struct dm_status_raid *status;
|
int r = 1;
|
||||||
char *action;
|
|
||||||
|
|
||||||
*sync_action = NULL;
|
*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.",
|
log_debug_activation("Checking raid sync_action for LV %s.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!lv_raid_status(lv, &raid_status))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
/* status->sync_action can be NULL if dm-raid version < 1.5.0 */
|
/* status->sync_action can be NULL if dm-raid version < 1.5.0 */
|
||||||
if (!dev_manager_raid_status(dm, lv, &status) ||
|
if (!raid_status->raid->sync_action ||
|
||||||
!status->sync_action ||
|
!(*sync_action = dm_pool_strdup(lv->vg->cmd->mem,
|
||||||
!(action = dm_pool_strdup(lv->vg->cmd->mem,
|
raid_status->raid->sync_action))) {
|
||||||
status->sync_action))) {
|
stack;
|
||||||
dev_manager_destroy(dm);
|
r = 0;
|
||||||
return_0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*sync_action = action;
|
dm_pool_destroy(raid_status->mem);
|
||||||
|
|
||||||
dev_manager_destroy(dm);
|
return r;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
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;
|
int r = 0;
|
||||||
struct dev_manager *dm;
|
|
||||||
struct dm_status_raid *status;
|
|
||||||
|
|
||||||
if (!seg_is_raid(first_seg(lv))) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!lv_raid_status(lv, &raid_status))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
if (!raid_status->raid->sync_action) {
|
||||||
log_error("Failed to retrieve status of %s.",
|
|
||||||
display_lvname(lv));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!status->sync_action) {
|
|
||||||
log_error("Kernel driver does not support this action: %s", msg);
|
log_error("Kernel driver does not support this action: %s", msg);
|
||||||
goto out;
|
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);
|
log_error("\"%s\" is not a supported sync operation.", msg);
|
||||||
goto out;
|
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\".",
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
|
return_0;
|
||||||
|
|
||||||
r = dev_manager_raid_message(dm, lv, msg);
|
r = dev_manager_raid_message(dm, lv, msg);
|
||||||
out:
|
out:
|
||||||
|
if (dm)
|
||||||
dev_manager_destroy(dm);
|
dev_manager_destroy(dm);
|
||||||
|
dm_pool_destroy(raid_status->mem);
|
||||||
|
|
||||||
return r;
|
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 lv_writecache_message(const struct logical_volume *lv, const char *msg)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
@ -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_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_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_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_writecache_message(const struct logical_volume *lv, const char *msg);
|
||||||
int lv_cache_status(const struct logical_volume *cache_lv,
|
int lv_cache_status(const struct logical_volume *cache_lv,
|
||||||
struct lv_status_cache **status);
|
struct lv_status_cache **status);
|
||||||
|
@ -1437,7 +1437,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
|||||||
|
|
||||||
int dev_manager_raid_status(struct dev_manager *dm,
|
int dev_manager_raid_status(struct dev_manager *dm,
|
||||||
const struct logical_volume *lv,
|
const struct logical_volume *lv,
|
||||||
struct dm_status_raid **status)
|
struct lv_status_raid **status, int *exists)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
const char *dlid;
|
const char *dlid;
|
||||||
@ -1447,6 +1447,11 @@ int dev_manager_raid_status(struct dev_manager *dm,
|
|||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
char *params = NULL;
|
char *params = NULL;
|
||||||
const char *layer = lv_layer(lv);
|
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)))
|
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||||
return_0;
|
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)))
|
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!info.exists)
|
if (!(*exists = info.exists))
|
||||||
goto_out;
|
goto out;
|
||||||
|
|
||||||
|
log_debug_activation("Checking raid status for volume %s.",
|
||||||
|
display_lvname(lv));
|
||||||
|
|
||||||
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
|
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 */
|
/* 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;
|
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;
|
r = 1;
|
||||||
out:
|
out:
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
|
@ -59,7 +59,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
|||||||
dm_percent_t *percent, uint32_t *event_nr);
|
dm_percent_t *percent, uint32_t *event_nr);
|
||||||
int dev_manager_raid_status(struct dev_manager *dm,
|
int dev_manager_raid_status(struct dev_manager *dm,
|
||||||
const struct logical_volume *lv,
|
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,
|
int dev_manager_raid_message(struct dev_manager *dm,
|
||||||
const struct logical_volume *lv,
|
const struct logical_volume *lv,
|
||||||
const char *msg);
|
const char *msg);
|
||||||
|
@ -1239,6 +1239,11 @@ int collapse_mirrored_lv(struct logical_volume *lv);
|
|||||||
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
|
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
|
||||||
|
|
||||||
/* ++ metadata/raid_manip.c */
|
/* ++ 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);
|
int lv_is_raid_with_tracking(const struct logical_volume *lv);
|
||||||
uint32_t lv_raid_image_count(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,
|
int lv_raid_change_image_count(struct logical_volume *lv,
|
||||||
|
Loading…
Reference in New Issue
Block a user