mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-18 10:04:20 +03:00
pvmove: automatically resolve whole stacked LV
When passing 'pvmove --name arg' try to automatically move all associated dependencies with given LV. i.e. 'pvmove --name thinpool vg vgnew' moves all thins and data and metadata LV into a new VG vgnew.
This commit is contained in:
parent
abc9265a06
commit
45f0c48365
@ -459,14 +459,33 @@ int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
|
|||||||
return _move_pv(vg_from, vg_to, pv_name, 1);
|
return _move_pv(vg_from, vg_to, pv_name, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vg_from_to {
|
||||||
|
struct volume_group *from;
|
||||||
|
struct volume_group *to;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _move_pvs_used_by_lv_cb(struct logical_volume *lv, void *data)
|
||||||
|
{
|
||||||
|
struct vg_from_to *v = (struct vg_from_to*) data;
|
||||||
|
struct lv_segment *lvseg;
|
||||||
|
unsigned s;
|
||||||
|
|
||||||
|
dm_list_iterate_items(lvseg, &lv->segments)
|
||||||
|
for (s = 0; s < lvseg->area_count; s++)
|
||||||
|
if (seg_type(lvseg, s) == AREA_PV)
|
||||||
|
if (!_move_pv(v->from, v->to,
|
||||||
|
pv_dev_name(seg_pv(lvseg, s)), 0))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int move_pvs_used_by_lv(struct volume_group *vg_from,
|
int move_pvs_used_by_lv(struct volume_group *vg_from,
|
||||||
struct volume_group *vg_to,
|
struct volume_group *vg_to,
|
||||||
const char *lv_name)
|
const char *lv_name)
|
||||||
{
|
{
|
||||||
struct lv_segment *lvseg;
|
struct vg_from_to data = { .from = vg_from, .to = vg_to };
|
||||||
unsigned s;
|
|
||||||
struct lv_list *lvl;
|
struct lv_list *lvl;
|
||||||
struct logical_volume *lv;
|
|
||||||
|
|
||||||
/* FIXME: handle tags */
|
/* FIXME: handle tags */
|
||||||
if (!(lvl = find_lv_in_vg(vg_from, lv_name))) {
|
if (!(lvl = find_lv_in_vg(vg_from, lv_name))) {
|
||||||
@ -475,28 +494,22 @@ int move_pvs_used_by_lv(struct volume_group *vg_from,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vg_bad_status_bits(vg_from, RESIZEABLE_VG) ||
|
if (vg_bad_status_bits(vg_from, RESIZEABLE_VG)) {
|
||||||
vg_bad_status_bits(vg_to, RESIZEABLE_VG))
|
log_error("Cannot move PV(s) from non resize volume group %s.", vg_from->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
dm_list_iterate_items(lvseg, &lvl->lv->segments) {
|
if (vg_bad_status_bits(vg_to, RESIZEABLE_VG)) {
|
||||||
if (lvseg->log_lv)
|
log_error("Cannot move PV(s) to non resize volume group %s.", vg_to->name);
|
||||||
if (!move_pvs_used_by_lv(vg_from, vg_to,
|
return 0;
|
||||||
lvseg->log_lv->name))
|
|
||||||
return_0;
|
|
||||||
for (s = 0; s < lvseg->area_count; s++) {
|
|
||||||
if (seg_type(lvseg, s) == AREA_PV) {
|
|
||||||
if (!_move_pv(vg_from, vg_to,
|
|
||||||
pv_dev_name(seg_pv(lvseg, s)), 0))
|
|
||||||
return_0;
|
|
||||||
} else if (seg_type(lvseg, s) == AREA_LV) {
|
|
||||||
lv = seg_lv(lvseg, s);
|
|
||||||
if (!move_pvs_used_by_lv(vg_from, vg_to,
|
|
||||||
lv->name))
|
|
||||||
return_0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!for_each_sub_lv(lvl->lv, _move_pvs_used_by_lv_cb, &data))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!_move_pvs_used_by_lv_cb(lvl->lv, &data))
|
||||||
|
return_0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user