mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
lvstatus: enhance seg_status to handle snapshot
Add more code to properly store status for snapshot segment maintaining lvm2 fiction of COW and snapshot internal volumes. The key issue here is however not though-through reporting logic - as there is no single answer for whole line state. It not counting with layer and we may need few more ioctl to cover all reporting needs depending upon what is actually needed. In reality we need to 'cache' more ioctl status queries for individual LVs and their segments (so they checked at most once). The other 'hard' topic for conversion is mirror segment handling. Also we definitelly need to relocate some logic into segment's methods, yet it might be complex as we have not clear border between targets. TODO: define more clearly how are reporting fields defined in case we 'stack' volumes like - cache of stacked thin LV snapshot origin.
This commit is contained in:
parent
067c0a23e5
commit
f7f395667e
@ -1,5 +1,6 @@
|
||||
Version 2.02.155 -
|
||||
================================
|
||||
Enhance internal seg_status handling to understand snapshots better.
|
||||
When refresh failed in suspend, call resume upon error path.
|
||||
Support passthrough cache mode when waiting for clean cache.
|
||||
Check cache status only for 'in-use' cache pools.
|
||||
|
@ -691,8 +691,36 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
|
||||
use_layer = 1;
|
||||
}
|
||||
|
||||
if (seg_status)
|
||||
if (seg_status) {
|
||||
/* TODO: for now it's mess with seg_status */
|
||||
seg_status->seg = seg;
|
||||
if (lv_is_merging_cow(lv)) {
|
||||
if (lv_has_target_type(cmd->mem, origin_from_cow(lv), NULL, TARGET_NAME_SNAPSHOT_MERGE)) {
|
||||
/*
|
||||
* When the snapshot-merge has not yet started, query COW LVs as is.
|
||||
* When merge is in progress, query merging origin LV instead.
|
||||
* COW volume is already mapped as error target in this case.
|
||||
*/
|
||||
lv = origin_from_cow(lv);
|
||||
seg_status->seg = first_seg(lv);
|
||||
log_debug_activation("Snapshot merge is in progress, querying status of %s instead.",
|
||||
display_lvname(lv));
|
||||
}
|
||||
} else if (!use_layer && lv_is_origin(lv) && !lv_is_external_origin(lv)) {
|
||||
/*
|
||||
* Query status for 'layered' (-real) device most of the time,
|
||||
* only when snapshot merge started, query its progress.
|
||||
* TODO: single LV may need couple status to be exposed at once....
|
||||
* but this needs more logical background
|
||||
*/
|
||||
if (!lv_is_merging_origin(lv) ||
|
||||
!lv_has_target_type(cmd->mem, origin_from_cow(lv), NULL, TARGET_NAME_SNAPSHOT_MERGE))
|
||||
use_layer = 1;
|
||||
} else if (lv_is_cow(lv)) {
|
||||
/* Hadle fictional lvm2 snapshot and query snapshotX volume */
|
||||
seg_status->seg = find_snapshot(lv);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_manager_info(cmd, lv,
|
||||
(use_layer) ? lv_layer(lv) : NULL,
|
||||
|
@ -127,6 +127,7 @@ static int _get_segment_status_from_target_params(const char *target_name,
|
||||
struct segment_type *segtype;
|
||||
|
||||
seg_status->type = SEG_STATUS_UNKNOWN;
|
||||
|
||||
/*
|
||||
* TODO: Add support for other segment types too!
|
||||
* The segment to report status for must be properly
|
||||
@ -134,19 +135,27 @@ static int _get_segment_status_from_target_params(const char *target_name,
|
||||
* linear/striped, old snapshots and raids have proper
|
||||
* segment selected for status!
|
||||
*/
|
||||
if (strcmp(target_name, TARGET_NAME_CACHE) &&
|
||||
strcmp(target_name, TARGET_NAME_THIN_POOL) &&
|
||||
strcmp(target_name, TARGET_NAME_THIN))
|
||||
return 1;
|
||||
if (!strcmp(target_name, TARGET_NAME_SNAPSHOT_MERGE) &&
|
||||
lv_is_merging_origin(seg_status->seg->lv)) {
|
||||
/* Snapshot merge has started, check snapshot status */
|
||||
if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, TARGET_NAME_SNAPSHOT)))
|
||||
return_0;
|
||||
} else {
|
||||
if (strcmp(target_name, TARGET_NAME_CACHE) &&
|
||||
strcmp(target_name, TARGET_NAME_SNAPSHOT) &&
|
||||
strcmp(target_name, TARGET_NAME_THIN_POOL) &&
|
||||
strcmp(target_name, TARGET_NAME_THIN))
|
||||
return 1; /* TODO: Do not know how to handle yet */
|
||||
|
||||
if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, target_name)))
|
||||
return_0;
|
||||
if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, target_name)))
|
||||
return_0;
|
||||
|
||||
if (segtype != seg_status->seg->segtype) {
|
||||
log_error(INTERNAL_ERROR "_get_segment_status_from_target_params: "
|
||||
"segment type %s found does not match expected segment type %s",
|
||||
segtype->name, seg_status->seg->segtype->name);
|
||||
return 0;
|
||||
if (segtype != seg_status->seg->segtype) {
|
||||
log_error(INTERNAL_ERROR "_get_segment_status_from_target_params: "
|
||||
"segment type %s found does not match expected segment type %s",
|
||||
segtype->name, seg_status->seg->segtype->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (segtype_is_cache(segtype)) {
|
||||
|
Loading…
Reference in New Issue
Block a user