mirror of
git://sourceware.org/git/lvm2.git
synced 2025-04-01 18:50:41 +03:00
Add %PVS extents option to lvresize, lvextend, and lvcreate.
This commit is contained in:
parent
6b9c7485f1
commit
1bfc4335bb
@ -1,5 +1,6 @@
|
||||
Version 2.02.29 -
|
||||
==================================
|
||||
Add %PVS extents option to lvresize, lvextend, and lvcreate.
|
||||
Moved the obsolete test subdirectory to old-tests.
|
||||
Remove no-longer-correct restrictions on PV arg count with stripes/mirrors.
|
||||
Fix strdup memory leak in str_list_dup().
|
||||
|
@ -329,6 +329,9 @@ int pv_resize_single(struct cmd_context *cmd,
|
||||
int pv_analyze(struct cmd_context *cmd, const char *pv_name,
|
||||
uint64_t label_sector);
|
||||
|
||||
/* FIXME: move internal to library */
|
||||
uint32_t pv_list_extents_free(struct list *pvh);
|
||||
|
||||
struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
|
||||
uint32_t extent_size, uint32_t max_pv,
|
||||
uint32_t max_lv, alloc_policy_t alloc,
|
||||
|
@ -214,6 +214,46 @@ void merge_pv_segments(struct pv_segment *peg1, struct pv_segment *peg2)
|
||||
list_del(&peg2->list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the overlap, in extents, between a struct pv_segment and
|
||||
* a struct pe_range.
|
||||
*/
|
||||
static uint32_t _overlap_pe(struct pv_segment *pvseg,
|
||||
struct pe_range *per)
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
|
||||
start = max(pvseg->pe, per->start);
|
||||
end = min(pvseg->pe + pvseg->len, per->start + per->count);
|
||||
if (end < start)
|
||||
return 0;
|
||||
else
|
||||
return end - start;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: number of free PEs in a struct pv_list
|
||||
*/
|
||||
uint32_t pv_list_extents_free(struct list *pvh)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct pe_range *per;
|
||||
uint32_t extents = 0;
|
||||
struct pv_segment *pvseg;
|
||||
|
||||
list_iterate_items(pvl, pvh) {
|
||||
list_iterate_items(per, pvl->pe_ranges) {
|
||||
list_iterate_items(pvseg, &pvl->pv->segments) {
|
||||
if (!pvseg->lvseg) /* free space */
|
||||
extents += _overlap_pe(pvseg, per);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extents;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check all pv_segments in VG for consistency
|
||||
*/
|
||||
|
@ -15,6 +15,16 @@
|
||||
#ifndef _LVM_UTIL_H
|
||||
#define _LVM_UTIL_H
|
||||
|
||||
#define min(a, b) ({ typeof(a) _a = (a); \
|
||||
typeof(b) _b = (b); \
|
||||
(void) (&_a == &_b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define max(a, b) ({ typeof(a) _a = (a); \
|
||||
typeof(b) _b = (b); \
|
||||
(void) (&_a == &_b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
char *last_path_component(char const *name);
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@ lvcreate \- create a logical volume in an existing volume group
|
||||
[\-A/\-\-autobackup y/n] [\-C/\-\-contiguous y/n] [\-d/\-\-debug]
|
||||
[\-h/\-?/\-\-help]
|
||||
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
|
||||
{\-l/\-\-extents LogicalExtentsNumber[%{VG|FREE}] |
|
||||
{\-l/\-\-extents LogicalExtentsNumber[%{VG|PVS|FREE}] |
|
||||
\-L/\-\-size LogicalVolumeSize[kKmMgGtT]}
|
||||
[\-M/\-\-persistent y/n] [\-\-minor minor]
|
||||
[\-m/\-\-mirrors Mirrors [\-\-nosync] [\-\-mirrorlog {disk|log}] [\-\-corelog]
|
||||
@ -63,12 +63,14 @@ StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
|
||||
For metadata in LVM2 format, the stripe size may be a larger
|
||||
power of 2 but must not exceed the physical extent size.
|
||||
.TP
|
||||
.I \-l, \-\-extents LogicalExtentsNumber[%{VG|FREE}]
|
||||
.I \-l, \-\-extents LogicalExtentsNumber[%{VG|PVS|FREE}]
|
||||
Gives the number of logical extents to allocate for the new
|
||||
logical volume.
|
||||
This can also be expressed as a percentage of the total space
|
||||
in the Volume Group with the suffix %VG or of the remaining free space
|
||||
with the suffix %FREE.
|
||||
in the Volume Group with the suffix %VG, of the remaining
|
||||
free space in the Volume Group with the suffix %FREE, or
|
||||
of the remaining free space for the specified PhysicalVolume(s)
|
||||
with the suffix %PVS,
|
||||
.TP
|
||||
.I \-L, \-\-size LogicalVolumeSize[kKmMgGtTpPeE]
|
||||
Gives the size to allocate for the new logical volume.
|
||||
|
@ -6,7 +6,7 @@ lvextend \- extend the size of a logical volume
|
||||
[\-\-alloc AllocationPolicy]
|
||||
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
|
||||
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
|
||||
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}] |
|
||||
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |
|
||||
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
|
||||
[\-t/\-\-test]
|
||||
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
|
||||
@ -21,14 +21,16 @@ volume use
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
.TP
|
||||
.I \-l, \-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}]
|
||||
.I \-l, \-\-extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE}]
|
||||
Extend or set the logical volume size in units of logical extents.
|
||||
With the + sign the value is added to the actual size
|
||||
of the logical volume and without it, the value is taken as an absolute one.
|
||||
The number can also be expressed as a percentage of the total space
|
||||
in the Volume Group with the suffix %VG or relative to the existing
|
||||
size of the Logical Volume with the suffix %LV or as a percentage of the remaining
|
||||
free space in the Volume Group with the suffix %FREE.
|
||||
in the Volume Group with the suffix %VG, relative to the existing
|
||||
size of the Logical Volume with the suffix %LV, of the remaining
|
||||
free space for the specified PhysicalVolume(s) with the suffix %PVS,
|
||||
or as a percentage of the remaining free space in the Volume Group
|
||||
with the suffix %FREE.
|
||||
.TP
|
||||
.I \-L, \-\-size [+]LogicalVolumeSize[kKmMgGtTpPeE]
|
||||
Extend or set the logical volume size in units of megabytes.
|
||||
@ -54,6 +56,10 @@ StripeSize must be 2^n (n = 2 to 9)
|
||||
that logical volume by 54MB on physical volume /dev/sdk3.
|
||||
This is only possible if /dev/sdk3 is a member of volume group vg01 and
|
||||
there are enough free physical extents in it.
|
||||
|
||||
"lvextend /dev/vg01/lvol01 /dev/sdk3" tries to extend the size of that
|
||||
logical volume by the amount of free space on physical volume /dev/sdk3.
|
||||
This is equivalent to specifying "-l +100%PVS" on the command line.
|
||||
.SH SEE ALSO
|
||||
.BR lvm (8),
|
||||
.BR lvcreate (8),
|
||||
|
@ -6,7 +6,7 @@ lvresize \- resize a logical volume
|
||||
[\-\-alloc AllocationPolicy]
|
||||
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
|
||||
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
|
||||
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}] |
|
||||
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |
|
||||
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
|
||||
[\-t/\-\-test]
|
||||
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
|
||||
@ -25,14 +25,16 @@ volume use
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
.TP
|
||||
.I \-l, \-\-extents [+/-]LogicalExtentsNumber[%{VG|LV|FREE}]
|
||||
.I \-l, \-\-extents [+/-]LogicalExtentsNumber[%{VG|LV|PVS|FREE}]
|
||||
Change or set the logical volume size in units of logical extents.
|
||||
With the + or - sign the value is added to or subtracted from the actual size
|
||||
of the logical volume and without it, the value is taken as an absolute one.
|
||||
The number can also be expressed as a percentage of the total space
|
||||
in the Volume Group with the suffix %VG or relative to the existing
|
||||
size of the Logical Volume with the suffix %LV or as a percentage of the remaining
|
||||
free space in the Volume Group with the suffix %FREE.
|
||||
in the Volume Group with the suffix %VG, relative to the existing
|
||||
size of the Logical Volume with the suffix %LV, as a percentage of
|
||||
the remaining free space of the PhysicalVolumes on the command line with the
|
||||
suffix %PVS, or as a percentage of the remaining free space in the
|
||||
Volume Group with the suffix %FREE.
|
||||
.TP
|
||||
.I \-L, \-\-size [+/-]LogicalVolumeSize[kKmMgGtTpPeE]
|
||||
Change or set the logical volume size in units of megabytes.
|
||||
|
@ -144,7 +144,7 @@ xx(lvcreate,
|
||||
"\t[-d|--debug]\n"
|
||||
"\t[-h|-?|--help]\n"
|
||||
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
||||
"\t{-l|--extents LogicalExtentsNumber[%{VG|LV|FREE}] |\n"
|
||||
"\t{-l|--extents LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |\n"
|
||||
"\t -L|--size LogicalVolumeSize[kKmMgGtTpPeE]}\n"
|
||||
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
|
||||
"\t[-n|--name LogicalVolumeName]\n"
|
||||
@ -209,7 +209,7 @@ xx(lvextend,
|
||||
"\t[-d|--debug]\n"
|
||||
"\t[-h|--help]\n"
|
||||
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
||||
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|FREE}] |\n"
|
||||
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|PVS|FREE}] |\n"
|
||||
"\t -L|--size [+]LogicalVolumeSize[kKmMgGtTpPeE]}\n"
|
||||
"\t[-m|--mirrors Mirrors]\n"
|
||||
"\t[-n|--nofsck]\n"
|
||||
@ -323,7 +323,7 @@ xx(lvresize,
|
||||
"\t[-d|--debug]\n"
|
||||
"\t[-h|--help]\n"
|
||||
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
||||
"\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|FREE}] |\n"
|
||||
"\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |\n"
|
||||
"\t -L|--size [+|-]LogicalVolumeSize[kKmMgGtTpPeE]}\n"
|
||||
"\t[-n|--nofsck]\n"
|
||||
"\t[-r|--resizefs]\n"
|
||||
|
@ -490,6 +490,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
char lv_name_buf[128];
|
||||
const char *lv_name;
|
||||
struct lvinfo info;
|
||||
uint32_t pv_extent_count;
|
||||
|
||||
status |= lp->permission | VISIBLE_LV;
|
||||
|
||||
@ -574,8 +575,18 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
case PERCENT_FREE:
|
||||
lp->extents = lp->extents * vg->free_count / 100;
|
||||
break;
|
||||
case PERCENT_PVS:
|
||||
if (!lp->pv_count) {
|
||||
log_error("Please specify physical volume(s) "
|
||||
"with %%PVS");
|
||||
return 0;
|
||||
}
|
||||
pv_extent_count = pv_list_extents_free(pvh);
|
||||
lp->extents = lp->extents * pv_extent_count / 100;
|
||||
break;
|
||||
case PERCENT_LV:
|
||||
log_error("Please express size as %%VG or %%FREE.");
|
||||
log_error("Please express size as %%VG, %%PVS, or "
|
||||
"%%FREE.");
|
||||
return 0;
|
||||
case PERCENT_NONE:
|
||||
break;
|
||||
|
@ -269,6 +269,9 @@ int int_arg_with_sign_and_percent(struct cmd_context *cmd __attribute((unused)),
|
||||
a->percent = PERCENT_VG;
|
||||
else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
|
||||
a->percent = PERCENT_LV;
|
||||
else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") ||
|
||||
!strcasecmp(ptr, "PVS"))
|
||||
a->percent = PERCENT_PVS;
|
||||
else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
|
||||
!strcasecmp(ptr, "FREE"))
|
||||
a->percent = PERCENT_FREE;
|
||||
|
@ -182,8 +182,20 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
if (!strcmp(cmd_name, "lvextend"))
|
||||
lp->resize = LV_EXTEND;
|
||||
|
||||
if (arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) != 1) {
|
||||
log_error("Please specify either size or extents (not both)");
|
||||
/*
|
||||
* Allow omission of extents and size if the user has given us
|
||||
* one or more PVs. Most likely, the intent was "resize this
|
||||
* LV the best you can with these PVs"
|
||||
*/
|
||||
if ((arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) == 0) &&
|
||||
(argc >= 2)) {
|
||||
lp->extents = 100;
|
||||
lp->percent = PERCENT_PVS;
|
||||
lp->sign = SIGN_PLUS;
|
||||
} else if ((arg_count(cmd, extents_ARG) +
|
||||
arg_count(cmd, size_ARG) != 1)) {
|
||||
log_error("Please specify either size or extents but not "
|
||||
"both.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -246,6 +258,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
|
||||
uint32_t seg_mirrors = 0;
|
||||
uint32_t extents_used = 0;
|
||||
uint32_t size_rest;
|
||||
uint32_t pv_extent_count = 0;
|
||||
alloc_policy_t alloc;
|
||||
struct logical_volume *lock_lv;
|
||||
struct lv_list *lvl;
|
||||
@ -319,6 +332,12 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
|
||||
lp->extents = lp->size / vg->extent_size;
|
||||
}
|
||||
|
||||
if (!(pvh = lp->argc ? create_pv_list(cmd->mem, vg, lp->argc,
|
||||
lp->argv, 1) : &vg->pvs)) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
switch(lp->percent) {
|
||||
case PERCENT_VG:
|
||||
lp->extents = lp->extents * vg->extent_count / 100;
|
||||
@ -329,6 +348,10 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
|
||||
case PERCENT_LV:
|
||||
lp->extents = lp->extents * lv->le_count / 100;
|
||||
break;
|
||||
case PERCENT_PVS:
|
||||
pv_extent_count = pv_list_extents_free(pvh);
|
||||
lp->extents = lp->extents * pv_extent_count / 100;
|
||||
break;
|
||||
case PERCENT_NONE:
|
||||
break;
|
||||
}
|
||||
@ -539,10 +562,6 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
|
||||
if (lp->resize == LV_REDUCE) {
|
||||
if (lp->argc)
|
||||
log_warn("Ignoring PVs on command line when reducing");
|
||||
} else if (!(pvh = lp->argc ? create_pv_list(cmd->mem, vg, lp->argc,
|
||||
lp->argv, 1) : &vg->pvs)) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (lp->resize == LV_REDUCE || lp->resizefs) {
|
||||
|
@ -83,7 +83,8 @@ typedef enum {
|
||||
PERCENT_NONE = 0,
|
||||
PERCENT_VG,
|
||||
PERCENT_FREE,
|
||||
PERCENT_LV
|
||||
PERCENT_LV,
|
||||
PERCENT_PVS
|
||||
} percent_t;
|
||||
|
||||
enum {
|
||||
|
Loading…
x
Reference in New Issue
Block a user