diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2016-04-18 11:04:16 +0200 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2016-04-18 12:32:52 +0200 |
commit | 9cccf5245a97a64f900f253fcf948edd5d7ba8c0 (patch) | |
tree | 4e33acd3266d1c162b93fd9d9e4a32c7ebe2c83d | |
parent | e2cd882f2eef93f02711c34a741bd85d6313eb6e (diff) | |
download | lvm2-9cccf5245a97a64f900f253fcf948edd5d7ba8c0.tar.gz |
thin: improve recognizing of merge in progress
Rewrite too condensed condition in more readable form,
wher decision are clearly separated and commented and
also add debug messages for them.
-rw-r--r-- | lib/activate/dev_manager.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 665919017..2b108c9cf 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -2764,25 +2764,52 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, /* * Clear merge attributes if merge isn't currently possible: * either origin or merging snapshot are open - * - but use "snapshot-merge" if it is already in use + * - for old snaps use "snapshot-merge" if it is already in use * - open_count is always retrieved (as of dm-ioctl 4.7.0) * so just use the tree's existing nodes' info */ - /* An activating merging origin won't have a node in the tree yet */ - if (((dinfo = _cached_dm_info(dm->mem, dtree, lv, NULL)) && - dinfo->open_count) || - ((dinfo = _cached_dm_info(dm->mem, dtree, - seg_is_thin_volume(seg) ? - seg->lv : seg->cow, NULL)) && - dinfo->open_count)) - snap_dev_is_open = 1; - - /* Preload considers open devices. */ - /* Resume looks at the table that will be the live one after the operation. */ - if ((!laopts->resuming && snap_dev_is_open && (seg_is_thin_volume(seg) || !lv_has_target_type(dm->mem, lv, NULL, TARGET_NAME_SNAPSHOT_MERGE))) || - (laopts->resuming && - ((!seg_is_thin_volume(seg) && !lv_has_target_type(dm->mem, lv, NULL, TARGET_NAME_SNAPSHOT_MERGE)) || - (seg_is_thin_volume(seg) && !_thin_lv_has_device_id(dm->mem, lv, NULL, seg->device_id))))) { + if ((dinfo = _cached_dm_info(dm->mem, dtree, + seg_is_thin_volume(seg) ? + seg->lv : seg->cow, NULL))) { + if (seg_is_thin_volume(seg)) { + /* Active thin snapshot prevents merge */ + log_debug_activation("Merging thin snapshot %s is active.", + display_lvname(seg->lv)); + } else if (dinfo->open_count) { + log_debug_activation("Merging snapshot LV %s is openned.", + display_lvname(seg->lv)); + snap_dev_is_open = 1; + } + } + + if ((dinfo = _cached_dm_info(dm->mem, dtree, lv, NULL))) { + if (dinfo->open_count) { + log_debug_activation("Merging origin volume %s is openned.", display_lvname(seg->lv)); + snap_dev_is_open = 1; + } + + /* Check if decision needs to be preserved. + * Merging origin LV needs to be present in table in this case. */ + if (!laopts->resuming) { + if ((seg_is_thin_volume(seg) && _thin_lv_has_device_id(dm->mem, lv, NULL, seg->device_id)) || + (!seg_is_thin_volume(seg) && lv_has_target_type(dm->mem, lv, NULL, TARGET_NAME_SNAPSHOT_MERGE))) { + log_debug_activation("Merging of snapshot volume %s is in progress.", + display_lvname(seg->lv)); + /* Merging is already running and cannot be switched */ + snap_dev_is_open = 0; + } + } else { + if ((seg_is_thin_volume(seg) && !_thin_lv_has_device_id(dm->mem, lv, NULL, seg->device_id)) || + (!seg_is_thin_volume(seg) && !lv_has_target_type(dm->mem, lv, NULL, TARGET_NAME_SNAPSHOT_MERGE))) { + log_debug_activation("Merging of snapshot volume %s was not started before suspend.", + display_lvname(seg->lv)); + /* Merging targe table cannot be reloaded when suspend */ + snap_dev_is_open = 1; + } + } + } + + if (snap_dev_is_open) { log_debug_activation("Postponing pending snapshot merge for origin LV %s.", display_lvname(lv)); laopts->no_merging = 1; } |