mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Allow deactivation of final snapshot.
This commit is contained in:
parent
0e06dd31fd
commit
69e8a53ee4
@ -544,11 +544,11 @@ static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
|
|||||||
s == (stripes - 1) ? "" : " ");
|
s == (stripes - 1) ? "" : " ");
|
||||||
else
|
else
|
||||||
tw = lvm_snprintf(params + w, sizeof(params) - w,
|
tw = lvm_snprintf(params + w, sizeof(params) - w,
|
||||||
"%s %" PRIu64 "%s",
|
"%s %" PRIu64 "%s",
|
||||||
dev_name(seg->area[s].pv->dev),
|
dev_name(seg->area[s].pv->dev),
|
||||||
(seg->area[s].pv->pe_start +
|
(seg->area[s].pv->pe_start +
|
||||||
(esize * seg->area[s].pe)),
|
(esize * seg->area[s].pe)),
|
||||||
s == (stripes - 1) ? "" : " ");
|
s == (stripes - 1) ? "" : " ");
|
||||||
|
|
||||||
if (tw < 0)
|
if (tw < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -729,7 +729,6 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
|
static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
|
||||||
char *dlid)
|
char *dlid)
|
||||||
{
|
{
|
||||||
@ -1061,8 +1060,7 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
|
|||||||
|
|
||||||
/* FIXME Create and use a _suspend_parents() function instead */
|
/* FIXME Create and use a _suspend_parents() function instead */
|
||||||
/* Suspend? */
|
/* Suspend? */
|
||||||
if (_get_flag(dl, SUSPENDED) &&
|
if (_get_flag(dl, SUSPENDED) && (!_suspend_parent || !_suspend(dl))) {
|
||||||
(!_suspend_parent || !_suspend(dl))) {
|
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1098,9 +1096,8 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
|
|||||||
newname = _build_name(dm->mem, dm->vg_name, dl->lv->name,
|
newname = _build_name(dm->mem, dm->vg_name, dl->lv->name,
|
||||||
suffix);
|
suffix);
|
||||||
if (strcmp(newname, dl->name)) {
|
if (strcmp(newname, dl->name)) {
|
||||||
if (!_suspend_parent(parent) ||
|
if (!_suspend_parent(parent) ||
|
||||||
!_suspend(dl) ||
|
!_suspend(dl) || !_rename(dm, dl, newname)) {
|
||||||
!_rename(dm, dl, newname)) {
|
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1109,7 +1106,7 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
|
|||||||
|
|
||||||
/* Create? */
|
/* Create? */
|
||||||
if (!dl->info.exists) {
|
if (!dl->info.exists) {
|
||||||
if (!_suspend_parent(parent) ||
|
if (!_suspend_parent(parent) ||
|
||||||
!_load(dm, dl, DM_DEVICE_CREATE)) {
|
!_load(dm, dl, DM_DEVICE_CREATE)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1119,15 +1116,14 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
|
|||||||
|
|
||||||
/* Reload? */
|
/* Reload? */
|
||||||
if (_get_flag(dl, RELOAD) &&
|
if (_get_flag(dl, RELOAD) &&
|
||||||
(!_suspend_parent(parent) || !_suspend(dl) ||
|
(!_suspend_parent(parent) || !_suspend(dl) ||
|
||||||
!_load(dm, dl, DM_DEVICE_RELOAD))) {
|
!_load(dm, dl, DM_DEVICE_RELOAD))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resume? */
|
/* Resume? */
|
||||||
if (!_get_flag(dl, SUSPENDED) &&
|
if (!_get_flag(dl, SUSPENDED) && (!_suspend_parent || !_resume(dl))) {
|
||||||
(!_suspend_parent || !_resume(dl))) {
|
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1406,20 +1402,36 @@ static void _remove_lv(struct list *head, struct logical_volume *lv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove any snapshots with given origin */
|
static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv)
|
||||||
static void _remove_lvs(struct list *head, struct logical_volume *origin)
|
|
||||||
{
|
{
|
||||||
struct logical_volume *active;
|
struct logical_volume *active, *old_origin;
|
||||||
struct snapshot *s;
|
struct snapshot *s;
|
||||||
struct list *sh;
|
struct list *sh, *active_head;
|
||||||
|
|
||||||
list_iterate(sh, head) {
|
active_head = &dm->active_list;
|
||||||
|
|
||||||
|
/* Remove any snapshots with given origin */
|
||||||
|
list_iterate(sh, active_head) {
|
||||||
active = list_item(sh, struct lv_list)->lv;
|
active = list_item(sh, struct lv_list)->lv;
|
||||||
if ((s = find_cow(active)) && s->origin == origin)
|
if ((s = find_cow(active)) && s->origin == lv)
|
||||||
_remove_lv(head, active);
|
_remove_lv(active_head, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
_remove_lv(head, origin);
|
_remove_lv(active_head, lv);
|
||||||
|
|
||||||
|
if (!(s = find_cow(lv)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
old_origin = s->origin;
|
||||||
|
|
||||||
|
/* Was this the last active snapshot with this origin? */
|
||||||
|
list_iterate(sh, active_head) {
|
||||||
|
active = list_item(sh, struct lv_list)->lv;
|
||||||
|
if ((s = find_cow(active)) && s->origin == old_origin)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _add_lvs(dm->mem, &dm->reload_list, old_origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
|
static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
|
||||||
@ -1468,7 +1480,10 @@ static int _action(struct dev_manager *dm, struct logical_volume *lv,
|
|||||||
|
|
||||||
if (action == ACTIVATE || action == DEACTIVATE)
|
if (action == ACTIVATE || action == DEACTIVATE)
|
||||||
/* Get into known state - remove from active list if present */
|
/* Get into known state - remove from active list if present */
|
||||||
_remove_lvs(&dm->active_list, lv);
|
if (!_remove_lvs(dm, lv)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == ACTIVATE) {
|
if (action == ACTIVATE) {
|
||||||
/* Add to active & reload lists */
|
/* Add to active & reload lists */
|
||||||
@ -1508,4 +1523,3 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
|
|||||||
{
|
{
|
||||||
return _action(dm, lv, SUSPEND);
|
return _action(dm, lv, SUSPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user