1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

move fields

This commit is contained in:
Alasdair Kergon 2003-05-06 12:06:02 +00:00
parent 8b99c8b6ec
commit 44c319cf0d
6 changed files with 148 additions and 45 deletions

View File

@ -58,7 +58,7 @@
#endif
#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
#ifdef READLINE_SUPPORT
@ -70,12 +70,12 @@
#define DEFAULT_REP_HEADINGS 1
#define DEFAULT_REP_SEPARATOR " "
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent"
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,move_percent"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,origin,snap_percent,lv_uuid"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,origin,snap_percent,move_pv,move_percent,lv_uuid"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"

View File

@ -231,11 +231,13 @@ static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
seg->lv = lv;
seg->type = SEG_MIRRORED;
seg->status = 0u;
seg->le = *ix;
seg->len = count;
seg->area_len = count;
seg->stripe_size = 0;
seg->area_count = 2;
seg->extents_moved = 0u;
/* FIXME Remove AREA_PV restriction here? */
seg->area[0].type = AREA_PV;
seg->area[0].u.pv.pv = mirrored_pv;
@ -274,14 +276,15 @@ static int _alloc_contiguous(struct logical_volume *lv,
/* first item in the list is the biggest */
pva = list_item(pvm->areas.n, struct pv_area);
if (pva->count < lv->le_count)
continue;
if (!_alloc_linear_area(lv, &allocated, pvm, pva)) {
stack;
return 0;
}
if (allocated == lv->le_count)
break;
break;
}
if (allocated != lv->le_count) {
@ -303,7 +306,9 @@ static int _alloc_mirrored(struct logical_volume *lv,
struct list *tmp1;
struct pv_map *pvm;
struct pv_area *pva;
uint32_t max_found = 0;
/* Try each PV in turn */
list_iterate(tmp1, pvms) {
pvm = list_item(tmp1, struct pv_map);
@ -312,6 +317,10 @@ static int _alloc_mirrored(struct logical_volume *lv,
/* first item in the list is the biggest */
pva = list_item(pvm->areas.n, struct pv_area);
if (pva->count < lv->le_count - allocated) {
max_found = pva->count;
continue;
}
if (!_alloc_mirrored_area(lv, &allocated, pvm, pva,
mirrored_pv, mirrored_pe)) {
@ -325,7 +334,7 @@ static int _alloc_mirrored(struct logical_volume *lv,
if (allocated != lv->le_count) {
log_error("Insufficient contiguous allocatable extents (%u) "
"for logical volume %s: %u required",
allocated, lv->name, lv->le_count);
allocated + max_found, lv->name, lv->le_count);
return 0;
}
@ -371,11 +380,13 @@ static int _alloc_next_free(struct logical_volume *lv,
static int _allocate(struct volume_group *vg, struct logical_volume *lv,
struct list *allocatable_pvs, uint32_t allocated,
uint32_t stripes, uint32_t stripe_size,
struct physical_volume *mirrored_pv, uint32_t mirrored_pe)
struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
uint32_t status)
{
int r = 0;
struct pool *scratch;
struct list *pvms, *old_tail = lv->segments.p, *segh;
struct lv_segment *seg;
if (!(scratch = pool_create(1024))) {
stack;
@ -413,8 +424,11 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
* Iterate through the new segments, updating pe
* counts in pv's.
*/
for (segh = lv->segments.p; segh != old_tail; segh = segh->p)
_get_extents(list_item(segh, struct lv_segment));
for (segh = lv->segments.p; segh != old_tail; segh = segh->p) {
seg = list_item(segh, struct lv_segment);
_get_extents(seg);
seg->status = status;
}
} else {
/*
* Put the segment list back how we found it.
@ -428,7 +442,7 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
return r;
}
static char *_generate_lv_name(struct volume_group *vg,
static char *_generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len)
{
struct list *lvh;
@ -438,14 +452,14 @@ static char *_generate_lv_name(struct volume_group *vg,
list_iterate(lvh, &vg->lvs) {
lv = (list_item(lvh, struct lv_list)->lv);
if (sscanf(lv->name, "lvol%d", &i) != 1)
if (sscanf(lv->name, format, &i) != 1)
continue;
if (i > high)
high = i;
}
if (lvm_snprintf(buffer, len, "lvol%d", high + 1) < 0)
if (lvm_snprintf(buffer, len, format, high + 1) < 0)
return NULL;
return buffer;
@ -453,6 +467,7 @@ static char *_generate_lv_name(struct volume_group *vg,
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
const char *name_format,
uint32_t status,
alloc_policy_t alloc,
struct volume_group *vg)
@ -468,7 +483,8 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
return NULL;
}
if (!name && !(name = _generate_lv_name(vg, dname, sizeof(dname)))) {
if (!name && !(name = _generate_lv_name(vg, name_format, dname,
sizeof(dname)))) {
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;
@ -547,7 +563,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
return NULL;
}
if (!(lv = lv_create_empty(fi, name, status, alloc, vg))) {
if (!(lv = lv_create_empty(fi, name, "lvol%d", status, alloc, vg))) {
stack;
return NULL;
}
@ -556,7 +572,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
lv->le_count = extents;
if (!_allocate(vg, lv, allocatable_pvs, 0u, stripes, stripe_size,
NULL, 0u)) {
NULL, 0u, 0u)) {
stack;
return NULL;
}
@ -618,7 +634,7 @@ int lv_extend(struct format_instance *fi,
lv->size += (uint64_t) extents *lv->vg->extent_size;
if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count,
stripes, stripe_size, NULL, 0u)) {
stripes, stripe_size, NULL, 0u, 0u)) {
lv->le_count = old_le_count;
lv->size = old_size;
stack;
@ -643,7 +659,8 @@ int lv_extend_mirror(struct format_instance *fid,
struct logical_volume *lv,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t extents, struct list *allocatable_pvs)
uint32_t extents, struct list *allocatable_pvs,
uint32_t status)
{
uint32_t old_le_count = lv->le_count;
uint64_t old_size = lv->size;
@ -652,7 +669,7 @@ int lv_extend_mirror(struct format_instance *fid,
lv->size += (uint64_t) extents *lv->vg->extent_size;
if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count,
1, extents, mirrored_pv, mirrored_pe)) {
1, extents, mirrored_pv, mirrored_pe, status)) {
lv->le_count = old_le_count;
lv->size = old_size;
stack;
@ -690,23 +707,6 @@ int lv_remove(struct volume_group *vg, struct logical_volume *lv)
return 1;
}
/* Lock a list of LVs */
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags)
{
struct list *lvh;
struct logical_volume *lv;
list_iterate(lvh, lvs) {
lv = list_item(lvh, struct lv_list)->lv;
if (!lock_vol(cmd, lv->lvid.s, flags)) {
log_error("Failed to lock %s", lv->name);
return 0;
}
}
return 1;
}
/* Unlock list of LVs */
int unlock_lvs(struct cmd_context *cmd, struct list *lvs)
{
@ -720,3 +720,22 @@ int unlock_lvs(struct cmd_context *cmd, struct list *lvs)
return 1;
}
/* Lock a list of LVs */
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags)
{
struct list *lvh;
struct logical_volume *lv;
list_iterate(lvh, lvs) {
lv = list_item(lvh, struct lv_list)->lv;
if (!lock_vol(cmd, lv->lvid.s, flags)) {
log_error("Failed to lock %s", lv->name);
/* FIXME Only unlock the locked ones */
unlock_lvs(cmd, lvs);
return 0;
}
}
return 1;
}

View File

@ -616,7 +616,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
}
}
if ((correct_vg->status & PVMOVE_VG) && !pvmove_mode()) {
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
log_error("WARNING: Interrupted pvmove detected in "
"volume group %s", vg->name);
log_error("Please restore the metadata by running "

View File

@ -39,7 +39,8 @@
#define FIXED_MINOR 0x00000080 /* LV */
/* FIXME Remove when metadata restructuring is completed */
#define SNAPSHOT 0x00001000 /* LV - tmp internal use only */
#define PVMOVE_VG 0x00002000 /* VG - tmp use only */
#define PVMOVE 0x00002000 /* VG LV SEG */
#define LOCKED 0x00004000 /* LV */
#define LVM_READ 0x00000100 /* LV VG */
#define LVM_WRITE 0x00000200 /* LV VG */
@ -179,6 +180,8 @@ struct lv_segment {
uint32_t le;
uint32_t len;
uint32_t status;
/* FIXME Fields depend on segment type */
uint32_t stripe_size;
uint32_t area_count;
@ -186,6 +189,7 @@ struct lv_segment {
struct logical_volume *origin;
struct logical_volume *cow;
uint32_t chunk_size;
uint32_t extents_moved;
/* There will be one area for each stripe */
struct {
@ -384,6 +388,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
const char *name_format,
uint32_t status,
alloc_policy_t alloc,
struct volume_group *vg);
@ -402,7 +407,8 @@ int lv_extend_mirror(struct format_instance *fid,
struct logical_volume *lv,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t extents, struct list *allocatable_pvs);
uint32_t extents, struct list *allocatable_pvs,
uint32_t status);
/* Lock list of LVs */
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags);
@ -485,8 +491,16 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv,
struct list *allocatable_pvs,
struct list *lvs_changed);
int remove_pvmove_mirrors(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv_mirr, int commit);
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr);
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev);
struct physical_volume *get_pvmove_pv_from_lv(struct logical_volume *lv);
struct physical_volume *get_pvmove_pv_from_lv_mirr(struct logical_volume
*lv_mirr);
float pvmove_percent(struct logical_volume *lv_mirr);
struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv);
static inline int validate_name(const char *n)
{

View File

@ -18,6 +18,8 @@ FIELD(LVS, lv, NUM, "LSize", size, 5, size64, "lv_size")
FIELD(LVS, lv, NUM, "#Seg", lvid, 4, lvsegcount, "seg_count")
FIELD(LVS, lv, STR, "Origin", lvid, 6, origin, "origin")
FIELD(LVS, lv, NUM, "Snap%", lvid, 6, snpercent, "snap_percent")
FIELD(LVS, lv, NUM, "Move%", lvid, 6, movepercent, "move_percent")
FIELD(LVS, lv, STR, "Move", lvid, 4, movepv, "move_pv")
FIELD(PVS, pv, STR, "Fmt", id, 3, pvfmt, "pv_fmt")
FIELD(PVS, pv, STR, "PV UUID", id, 38, uuid, "pv_uuid")

View File

@ -171,14 +171,18 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
return 0;
}
if (lv_is_origin(lv))
if (lv->status & PVMOVE)
repstr[0] = 'p';
else if (lv_is_origin(lv))
repstr[0] = 'o';
else if (find_cow(lv))
repstr[0] = 's';
else
repstr[0] = '-';
if (lv->status & LVM_WRITE)
if (lv->status & PVMOVE)
repstr[1] = '-';
else if (lv->status & LVM_WRITE)
repstr[1] = 'w';
else
repstr[1] = 'r';
@ -188,6 +192,9 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
else
repstr[2] = 'n';
if (lv->status & LOCKED)
repstr[2] = toupper(repstr[2]);
if (lv->status & FIXED_MINOR)
repstr[3] = 'm'; /* Fixed Minor */
else
@ -313,6 +320,28 @@ static int _origin_disp(struct report_handle *rh, struct field *field,
return 1;
}
static int _movepv_disp(struct report_handle *rh, struct field *field,
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
const char *name;
struct list *segh;
struct lv_segment *seg;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
if (!(seg->status & PVMOVE))
continue;
name = dev_name(seg->area[0].u.pv.pv->dev);
return _string_disp(rh, field, &name);
}
field->report_string = "";
field->sort_value = (const void *) field->report_string;
return 1;
}
static int _size32_disp(struct report_handle *rh, struct field *field,
const void *data)
{
@ -581,9 +610,6 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
return 0;
}
if (snap_percent == -1)
snap_percent = 100;
if (lvm_snprintf(repstr, 7, "%.2f", snap_percent) < 0) {
log_error("snapshot percentage too large");
return 0;
@ -596,6 +622,48 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
return 1;
}
static int _movepercent_disp(struct report_handle *rh, struct field *field,
const void *data)
{
struct logical_volume *lv = (struct logical_volume *) data;
float move_percent;
uint64_t *sortval;
char *repstr;
if (!(sortval = pool_alloc(rh->mem, sizeof(uint64_t)))) {
log_error("pool_alloc failed");
return 0;
}
if (!(lv->status & PVMOVE)) {
field->report_string = "";
*sortval = UINT64_C(0);
field->sort_value = sortval;
return 1;
}
/* Update percentage done in lv metadata in core */
lv_mirror_percent(lv, 0, &move_percent, NULL);
move_percent = pvmove_percent(lv);
if (!(repstr = pool_zalloc(rh->mem, 8))) {
log_error("pool_alloc failed");
return 0;
}
if (lvm_snprintf(repstr, 7, "%.2f", move_percent) < 0) {
log_error("move percentage too large");
return 0;
}
*sortval = move_percent * UINT64_C(1000);
field->sort_value = sortval;
field->report_string = repstr;
return 1;
}
/*
* Import column definitions
*/