mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
thin: improve pool creation activation order
Pool creation involves clearing of metadata device which triggers udev watch rule we cannot udev synchronize with in current code. This metadata devices needs to be activated localy, so in cluster mode deactivation and reactivation is always needed. However for non-clustered mode we may reload table via suspend/resume path which avoids collision with udev watch rule which was occasionaly triggering retry deactivation loop. Code has been also split into 2 separate code paths for thin pools and thin volumes which improved readability of the code as well. Deactivation has been moved out of extend_pool() and decision is now in _lv_create_an_lv() which knows the change mode.
This commit is contained in:
parent
4e724f5f52
commit
08df7ba844
@ -1,5 +1,6 @@
|
||||
Version 2.02.99 -
|
||||
===================================
|
||||
Improve activation order when creating thin pools in non-clustered VG.
|
||||
List thin-pool and thin modules for thin volumes.
|
||||
Correct thin creation error paths.
|
||||
Use local activation for clearing snapshot COW device.
|
||||
|
@ -5701,6 +5701,19 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
|
||||
lp->activate = CHANGE_AN;
|
||||
}
|
||||
|
||||
/*
|
||||
* For thin pools - deactivate when inactive pool is requested or
|
||||
* for cluster give-up local lock and take proper exlusive lock
|
||||
*/
|
||||
if (lv_is_thin_pool(lv) &&
|
||||
(!is_change_activating(lp->activate) ||
|
||||
vg_is_clustered(lv->vg)) &&
|
||||
/* Deactivates cleared metadata LV */
|
||||
!deactivate_lv(lv->vg->cmd, lv)) {
|
||||
stack;
|
||||
goto deactivate_failed;
|
||||
}
|
||||
|
||||
/* store vg on disk(s) */
|
||||
if (!vg_write(vg) || !vg_commit(vg))
|
||||
return_NULL;
|
||||
@ -5712,7 +5725,32 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (seg_is_thin(lp)) {
|
||||
if (lv_is_thin_pool(lv)) {
|
||||
if (is_change_activating(lp->activate)) {
|
||||
if (vg_is_clustered(lv->vg)) {
|
||||
if (!activate_lv_excl(cmd, lv)) {
|
||||
log_error("Failed to activate pool %s.", lv->name);
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Suspend cleared plain metadata LV
|
||||
* but now already commited as pool LV
|
||||
* and resume it as a pool LV.
|
||||
*
|
||||
* This trick avoids collision with udev watch rule.
|
||||
*/
|
||||
if (!suspend_lv(cmd, lv)) {
|
||||
log_error("Failed to suspend pool %s.", lv->name);
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
if (!resume_lv(cmd, lv)) {
|
||||
log_error("Failed to resume pool %s.", lv->name);
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (lv_is_thin_volume(lv)) {
|
||||
/* For snapshot, suspend active thin origin first */
|
||||
if (org && lv_is_active(org) && lv_is_thin_volume(org)) {
|
||||
if (!suspend_lv_origin(cmd, org)) {
|
||||
@ -5731,16 +5769,14 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
|
||||
goto revert_new_lv;
|
||||
}
|
||||
}
|
||||
if ((lp->activate != CHANGE_AN) && (lp->activate != CHANGE_ALN)) {
|
||||
/* At this point send message to kernel thin mda */
|
||||
pool_lv = lv_is_thin_pool(lv) ? lv : first_seg(lv)->pool_lv;
|
||||
if (!update_pool_lv(pool_lv, 1)) {
|
||||
if (is_change_activating(lp->activate)) {
|
||||
/* Send message so that table preload knows new thin */
|
||||
if (!update_pool_lv(first_seg(lv)->pool_lv, 1)) {
|
||||
stack;
|
||||
goto deactivate_and_revert_new_lv;
|
||||
goto revert_new_lv;
|
||||
}
|
||||
if (!activate_lv_excl(cmd, lv)) {
|
||||
log_error("Aborting. Failed to activate thin %s.",
|
||||
lv->name);
|
||||
log_error("Failed to activate thin %s.", lv->name);
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
}
|
||||
@ -5838,8 +5874,9 @@ out:
|
||||
|
||||
deactivate_and_revert_new_lv:
|
||||
if (!deactivate_lv(cmd, lv)) {
|
||||
log_error("Unable to deactivate failed new LV. "
|
||||
"Manual intervention required.");
|
||||
deactivate_failed:
|
||||
log_error("Unable to deactivate failed new LV \"%s/%s\". "
|
||||
"Manual intervention required.", lv->vg->name, lv->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -473,13 +473,7 @@ int extend_pool(struct logical_volume *pool_lv, const struct segment_type *segty
|
||||
!set_lv(pool_lv->vg->cmd, pool_lv, UINT64_C(0), 0)) {
|
||||
log_error("Aborting. Failed to wipe pool metadata %s.",
|
||||
pool_lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv_local(pool_lv->vg->cmd, pool_lv)) {
|
||||
log_error("Aborting. Could not deactivate pool metadata %s.",
|
||||
pool_lv->name);
|
||||
return 0;
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
log_warn("WARNING: Pool %s is created without initialization.", pool_lv->name);
|
||||
|
Loading…
Reference in New Issue
Block a user