1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-27 10:25:13 +03:00

o Added lvextend

o Full signed arguments to lvreduce/lvextend
o Consistent lv_number/pe map use
o Populate pv->pe_allocated
o Fixes for allocation/writing of multiple LVs
This commit is contained in:
Alasdair Kergon 2001-11-09 22:01:04 +00:00
parent 4f0a4a6a7a
commit 7858f6fb16
14 changed files with 365 additions and 92 deletions

View File

@ -196,6 +196,7 @@ static int _read_lvs(struct disk_list *data)
unsigned long pos;
struct lvd_list *ll;
/* FIXME May be gaps - use lv_max */
for(i = 0; i < data->vgd.lv_cur; i++) {
pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk));
ll = pool_alloc(data->mem, sizeof(*ll));
@ -384,9 +385,9 @@ static int _write_lvs(struct disk_list *data)
struct list *lvh;
unsigned long pos;
pos = data->pvd.lv_on_disk.base;
list_iterate(lvh, &data->lvds) {
struct lvd_list *ll = list_item(lvh, struct lvd_list);
pos = data->pvd.lv_on_disk.base;
if (!_write_lvd(data->dev, pos, &ll->lvd))
fail;

View File

@ -144,9 +144,9 @@ struct lvd_list {
};
struct disk_list {
struct list list;
struct pool *mem;
struct device *dev;
struct list list;
struct pv_disk pvd;
struct vg_disk vgd;

View File

@ -493,6 +493,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
}
export_lv(&lvdl->lvd, vg, &ll->lv, prefix);
lvdl->lvd.lv_number = lv_num;
if (!export_extents(dl, lv_num++, &ll->lv, pv)) {
stack;
return 0;
@ -556,11 +557,6 @@ void export_numbers(struct list *pvs, struct volume_group *vg)
list_iterate(pvh, pvs) {
dl = list_item(pvh, struct disk_list);
dl->pvd.pv_number = pv_num++;
list_iterate(lvh, &dl->lvds) {
ll = list_item(lvh, struct lvd_list);
ll->lvd.lv_number = _get_lv_number(vg, ll->lvd.lv_name);
}
}
}

View File

@ -64,11 +64,11 @@ static int _alloc_contiguous(struct logical_volume *lv,
struct pv_map *pvm;
struct pv_area *pva, *biggest;
list_iterate (tmp1, pvms) {
list_iterate(tmp1, pvms) {
pvm = list_item(tmp1, struct pv_map);
biggest = NULL;
list_iterate (tmp2, &pvm->areas) {
list_iterate(tmp2, &pvm->areas) {
pva = list_item(tmp2, struct pv_area);
if (!biggest || (pva->count > biggest->count))
@ -85,7 +85,7 @@ static int _alloc_contiguous(struct logical_volume *lv,
if (allocated != lv->le_count) {
log_error("Insufficient free extents to "
"allocate logical volume %s: %u required",
"allocate logical volume %s: %u required",
lv->name, lv->le_count);
return 0;
}
@ -104,10 +104,10 @@ static int _alloc_simple(struct logical_volume *lv,
struct pv_map *pvm;
struct pv_area *pva;
list_iterate (tmp1, pvms) {
list_iterate(tmp1, pvms) {
pvm = list_item(tmp1, struct pv_map);
list_iterate (tmp2, &pvm->areas) {
list_iterate(tmp2, &pvm->areas) {
pva = list_item(tmp2, struct pv_area);
allocated += _alloc_area(lv, allocated, pvm->pv, pva);
@ -115,13 +115,13 @@ static int _alloc_simple(struct logical_volume *lv,
break;
}
if (allocated == lv->le_count) /* FIXME: yuck, repeated test */
if (allocated == lv->le_count) /* FIXME: yuck, repeated test */
break;
}
if (allocated != lv->le_count) {
log_error("Insufficient free logical extents to "
"allocate logical volume %s: %u required",
"allocate logical volume %s: %u required",
lv->name, lv->le_count);
return 0;
}
@ -162,11 +162,10 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
r = _alloc_simple(lv, pvms, allocated);
if (r) {
vg->lv_count++;
vg->free_count -= lv->le_count - allocated;
}
out:
out:
pool_destroy(scratch);
return r;
}
@ -182,6 +181,7 @@ struct logical_volume *lv_create(struct io_space *ios,
{
struct lv_list *ll = NULL;
struct logical_volume *lv;
int i;
if (!extents) {
log_error("Unable to create logical volume %s with no extents",
@ -217,7 +217,6 @@ struct logical_volume *lv_create(struct io_space *ios,
goto bad;
}
lv->vg = vg;
lv->status = status;
lv->read_ahead = 0;
lv->stripes = stripes;
@ -234,18 +233,24 @@ struct logical_volume *lv_create(struct io_space *ios,
goto bad;
}
for (i = 0; i < lv->le_count; i++) {
lv->map[i].pv->pe_allocated++;
}
vg->lv_count++;
list_add(&vg->lvs, &ll->list);
lv->vg = vg;
return lv;
bad:
bad:
if (ll)
pool_free(ios->mem, ll);
return NULL;
}
int lv_reduce(struct io_space *ios,
struct logical_volume *lv, uint32_t extents)
int lv_reduce(struct io_space *ios, struct logical_volume *lv, uint32_t extents)
{
if (extents % lv->stripes) {
log_error("For a striped volume you must reduce by a "
@ -270,6 +275,7 @@ int lv_extend(struct io_space *ios,
{
struct pe_specifier *new_map;
struct logical_volume *new_lv;
int i;
if (!(new_map = pool_zalloc(ios->mem, sizeof(*new_map) *
(extents + lv->le_count)))) {
@ -289,18 +295,22 @@ int lv_extend(struct io_space *ios,
new_lv->map = new_map;
new_lv->le_count += extents;
if (!_allocate(new_lv->vg, new_lv, acceptable_pvs, new_lv->le_count)) {
if (!_allocate(new_lv->vg, new_lv, acceptable_pvs, lv->le_count)) {
stack;
goto bad;
}
for (i = lv->le_count; i < new_lv->le_count; i++) {
new_lv->map[i].pv->pe_allocated++;
}
memcpy(lv, new_lv, sizeof(*lv));
/* now you see why new_lv had to be allocated last */
pool_free(ios->mem, new_lv);
return 1;
bad:
bad:
pool_free(ios->mem, new_map);
return 0;
}

View File

@ -19,7 +19,7 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
struct physical_volume *pv;
log_verbose("Adding physical volume '%s' to volume group '%s'",
pv_name, vg->name);
pv_name, vg->name);
if (!(pvl = pool_alloc(ios->mem, sizeof (*pvl)))) {
log_error("pv_list allocation for '%s' failed", pv_name);
@ -100,7 +100,7 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
}
int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count,
char **pv_names)
char **pv_names)
{
int i;
@ -133,14 +133,13 @@ struct volume_group *vg_create(struct io_space *ios, const char *vg_name,
}
if (!id_create(&vg->id)) {
log_err("Couldn't create uuid for volume group '%s'.",
vg_name);
log_err("Couldn't create uuid for volume group '%s'.", vg_name);
goto bad;
}
/* Strip prefix if present */
if (!strncmp(vg_name, ios->prefix, strlen(ios->prefix)))
vg_name += strlen(ios->prefix);
/* Strip prefix if present */
if (!strncmp(vg_name, ios->prefix, strlen(ios->prefix)))
vg_name += strlen(ios->prefix);
if (!(vg->name = pool_strdup(ios->mem, vg_name))) {
stack;
@ -246,11 +245,11 @@ struct list *find_lv_in_vg(struct volume_group *vg, const char *lv_name)
else
ptr = lv_name;
list_iterate(lvh, &vg->lvs)
if (!strcmp(list_item(lvh, struct lv_list)->lv.name, ptr))
return lvh;
list_iterate(lvh, &vg->lvs)
if (!strcmp(list_item(lvh, struct lv_list)->lv.name, ptr))
return lvh;
return NULL;
return NULL;
}
struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name)
@ -266,23 +265,30 @@ struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name)
struct physical_volume *_find_pv(struct volume_group *vg, struct device *dev)
{
struct list *pvh;
struct physical_volume *pv;
struct pv_list *pl;
struct physical_volume *pv;
struct pv_list *pl;
list_iterate(pvh, &vg->pvs) {
pl = list_item(pvh, struct pv_list);
pv = &pl->pv;
if (dev == pv->dev)
return pv;
}
return NULL;
list_iterate(pvh, &vg->pvs) {
pl = list_item(pvh, struct pv_list);
pv = &pl->pv;
if (dev == pv->dev)
return pv;
}
return NULL;
}
int lv_remove(struct volume_group *vg, struct list *lvh)
{
int i;
struct logical_volume *lv;
lv = &list_item(lvh, struct lv_list)->lv;
for (i = 0; i < lv->le_count; i++) {
lv->map[i].pv->pe_allocated--;
}
list_del(lvh);
vg->lv_count--;
return 1;
}

View File

@ -24,6 +24,7 @@ SOURCES=\
lvchange.c \
lvcreate.c \
lvdisplay.c \
lvextend.c \
lvm.c \
lvmchange.c \
lvreduce.c \

View File

@ -39,11 +39,11 @@ xx(stripes_ARG, 'i', "stripes", int_arg)
xx(iop_version_ARG, 'i', "iop_version", NULL)
xx(logicalvolume_ARG, 'l', "logicalvolume", int_arg)
xx(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", int_arg)
xx(extents_ARG, 'l', "extents", int_arg)
xx(extents_ARG, 'l', "extents", int_arg_with_sign)
xx(lvmpartition_ARG, 'l', "lvmpartition", NULL)
xx(list_ARG, 'l', "list", NULL)
xx(size_ARG, 'L', "size", size_arg)
xx(logicalextent_ARG, 'L', "logicalextent", int_arg)
xx(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign)
xx(name_ARG, 'n', "name", string_arg)
xx(oldpath_ARG, 'n', "oldpath", NULL)
xx(nofsck_ARG, 'n', "nofsck", NULL)

View File

@ -144,9 +144,12 @@ int lvcreate(int argc, char **argv)
return EINVALID_CMD_LINE;
}
if (list_item(pvl, struct pv_list)->pv.pe_count ==
list_item(pvl, struct pv_list)->pv.pe_allocated)
list_item(pvl, struct pv_list)->pv.pe_allocated) {
log_error("No free extents on physical volume"
" %s", argv[opt]);
continue;
/* FIXME But check not null at end! */
}
list_add(pvh, pvl);
}
} else {

188
tools/lvextend.c Normal file
View File

@ -0,0 +1,188 @@
/*
* Copyright (C) 2001 Sistina Software
*
* LVM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* LVM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LVM; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "tools.h"
int lvextend(int argc, char **argv)
{
struct volume_group *vg;
struct logical_volume *lv;
uint32_t extents = 0;
uint32_t size = 0;
sign_t sign = SIGN_NONE;
char *lv_name, *vg_name;
char *st;
char *dummy;
struct list *lvh, *pvh, *pvl;
int opt = 0;
if (arg_count(extents_ARG) + arg_count(size_ARG) != 1) {
log_error("Please specify either size or extents (not both)");
return EINVALID_CMD_LINE;
}
if (arg_count(extents_ARG)) {
extents = arg_int_value(extents_ARG, 0);
sign = arg_sign_value(extents_ARG, SIGN_NONE);
}
if (arg_count(size_ARG)) {
size = arg_int_value(size_ARG, 0);
sign = arg_sign_value(extents_ARG, SIGN_NONE);
}
if (sign == SIGN_MINUS) {
log_error("Negative argument not permitted - use lvreduce");
return EINVALID_CMD_LINE;
}
if (!argc) {
log_error("Please provide the logical volume name");
return EINVALID_CMD_LINE;
}
lv_name = argv[0];
argv++;
argc--;
if (!(vg_name = extract_vgname(ios, lv_name))) {
log_error("Please provide a volume group name");
return EINVALID_CMD_LINE;
}
if ((st = strrchr(lv_name, '/')))
lv_name = st + 1;
/* does VG exist? */
log_verbose("Finding volume group %s", vg_name);
if (!(vg = ios->vg_read(ios, vg_name))) {
log_error("Volume group %s doesn't exist", vg_name);
return ECMD_FAILED;
}
if (!(vg->status & ACTIVE)) {
log_error("Volume group %s must be active before changing a "
"logical volume", vg_name);
return ECMD_FAILED;
}
/* does LV exist? */
if (!(lvh = find_lv_in_vg(vg, lv_name))) {
log_error("Logical volume %s not found in volume group %s",
lv_name, vg_name);
return ECMD_FAILED;
}
lv = &list_item(lvh, struct lv_list)->lv;
if (!(lv->status & ACTIVE)) {
log_error("Logical volume %s must be active before change",
lv_name);
return ECMD_FAILED;
}
if (argc) {
/* Build up list of PVs */
if (!(pvh = pool_alloc(ios->mem, sizeof (struct list)))) {
log_error("pvh list allocation failed");
return ECMD_FAILED;
}
list_init(pvh);
for (; opt < argc; opt++) {
if (!(pvl = find_pv_in_vg(vg, argv[opt]))) {
log_error("Physical Volume %s not found in "
"Volume Group %s", argv[opt],
vg->name);
return EINVALID_CMD_LINE;
}
if (list_item(pvl, struct pv_list)->pv.pe_count ==
list_item(pvl, struct pv_list)->pv.pe_allocated) {
log_error("No free extents on physical volume"
" %s", argv[opt]);
continue;
/* FIXME Buy check not empty at end! */
}
list_add(pvh, pvl);
}
} else {
/* Use full list from VG */
pvh = &vg->pvs;
}
if (size) {
/* No of 512-byte sectors */
extents = size * 2;
if (extents % vg->extent_size) {
char *s1;
extents += vg->extent_size -
(extents % vg->extent_size);
log_print("Rounding up size to full physical extent %s",
(s1 = display_size(extents / 2, SIZE_SHORT)));
dbg_free(s1);
}
extents /= vg->extent_size;
}
if (sign == SIGN_PLUS)
extents += lv->le_count;
if (extents <= lv->le_count) {
log_error("New size given (%d extents) not larger than "
"existing size (%d extents)", extents, lv->le_count);
return EINVALID_CMD_LINE;
}
if (!extents) {
log_error("New size of 0 not permitted");
return EINVALID_CMD_LINE;
}
log_print("Extending logical volume %s to %s", lv_name,
(dummy =
display_size(extents * vg->extent_size / 2, SIZE_SHORT)));
dbg_free(dummy);
lv_extend(ios, lv, extents - lv->le_count, pvh);
/* where parm is always *increase* not actual */
/********* FIXME Suspend lv ***********/
/* store vg on disk(s) */
if (!ios->vg_write(ios, vg))
return ECMD_FAILED;
/* FIXME Ensure it always displays errors? */
if (!lv_reactivate(lv))
return ECMD_FAILED;
/********* FIXME Resume *********/
/********* FIXME Backup
if ((ret = do_autobackup(vg_name, vg)))
return ret;
************/
log_print("Logical volume %s successfully extended", lv_name);
return 0;
}

View File

@ -157,6 +157,8 @@ void usage(const char *name)
int yes_no_arg(struct arg *a)
{
a->sign = SIGN_NONE;
if (!strcmp(a->value, "y"))
a->i_value = 1;
@ -169,15 +171,44 @@ int yes_no_arg(struct arg *a)
return 1;
}
int _get_int_arg(struct arg *a, char **ptr)
{
char *val;
long v;
val = a->value;
switch (*val) {
case '+':
a->sign = SIGN_PLUS;
val++;
break;
case '-':
a->sign = SIGN_MINUS;
val++;
break;
default:
a->sign = SIGN_NONE;
}
if (!isdigit(*val))
return 0;
v = strtol(val, ptr, 10);
if (*ptr == val)
return 0;
a->i_value = (uint32_t) v;
return 1;
}
int size_arg(struct arg *a)
{
static char *suffixes = "kmgt";
char *ptr;
int i;
long v = strtol(a->value, &ptr, 10);
static char *suffixes = "kmgt";
if (ptr == a->value)
if (!_get_int_arg(a, &ptr))
return 0;
if (*ptr) {
@ -189,10 +220,9 @@ int size_arg(struct arg *a)
return 0;
while (i-- > 0)
v *= 1024;
a->i_value *= 1024;
}
a->i_value = (int) v;
return 1;
}
@ -200,12 +230,20 @@ int size_arg(struct arg *a)
int int_arg(struct arg *a)
{
char *ptr;
long v = strtol(a->value, &ptr, 10);
if (ptr == a->value || *ptr)
if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS))
return 0;
return 1;
}
int int_arg_with_sign(struct arg *a)
{
char *ptr;
if (!_get_int_arg(a, &ptr) || (*ptr))
return 0;
a->i_value = (int) v;
return 1;
}
@ -216,6 +254,8 @@ int string_arg(struct arg *a)
int permission_arg(struct arg *a)
{
a->sign = SIGN_NONE;
if ((!strcmp(a->value, "rw")) || (!strcmp(a->value, "wr")))
a->i_value = LVM_READ | LVM_WRITE;
@ -242,8 +282,7 @@ char yes_no_prompt(const char *prompt, ...)
c = tolower(getchar());
}
while (getchar() != '\n')
;
while (getchar() != '\n') ;
return c;
}
@ -271,7 +310,7 @@ static void register_command(const char *name, command_fn fn,
va_end(ap);
/* allocate space for them */
if (!(args = dbg_malloc(sizeof (*args) * nargs))) {
if (!(args = dbg_malloc(sizeof(*args) * nargs))) {
log_fatal("Out of memory.");
exit(ECMD_FAILED);
}
@ -327,7 +366,7 @@ static void create_new_command(const char *name, command_fn command,
static void __alloc(int size)
{
if (!(_commands = dbg_realloc(_commands, sizeof (*_commands) * size))) {
if (!(_commands = dbg_realloc(_commands, sizeof(*_commands) * size))) {
log_fatal("Couldn't allocate memory.");
exit(ECMD_FAILED);
}
@ -385,7 +424,7 @@ static int process_command_line(struct command *com, int *argc, char ***argv)
add_getopt_arg(com->valid_args[i], &ptr, &o);
*ptr = '\0';
memset(o, 0, sizeof (*o));
memset(o, 0, sizeof(*o));
/* initialise getopt_long & scan for command line switches */
optarg = 0;
@ -609,7 +648,8 @@ static int dev_cache_setup(void)
"device cache");
return 0;
}
log_verbose("device/scan not in config file: Defaulting to /dev");
log_verbose
("device/scan not in config file: Defaulting to /dev");
return 1;
}
@ -619,14 +659,14 @@ static int dev_cache_setup(void)
"devices/scan");
return 0;
}
if (!dev_cache_add_dir(cv->v.str)) {
log_error("Failed to add %s to internal device cache",
log_error("Failed to add %s to internal device cache",
cv->v.str);
return 0;
}
}
}
return 1;
}
@ -669,7 +709,7 @@ static struct dev_filter *filter_setup(void)
return 0;
lvm_cache = find_config_str(_cf->root, "devices/cache", '/',
"/etc/lvm/.cache");
"/etc/lvm/.cache");
if (!(f4 = persistent_filter_create(f3, lvm_cache))) {
log_error("Failed to create persistent device filter");
@ -679,7 +719,7 @@ static struct dev_filter *filter_setup(void)
/* Should we ever dump persistent filter state? */
if (find_config_int(_cf->root, "devices/write_cache_state", '/', 1))
dump_filter = 1;
if (!stat(lvm_cache, &st) && !persistent_filter_load(f4))
log_verbose("Failed to load existing device cache from %s",
lvm_cache);
@ -694,7 +734,7 @@ static int init(void)
struct stat info;
struct pool *ios_pool;
/* FIXME: Override from config file. (Append trailing slash if reqd)*/
/* FIXME: Override from config file. (Append trailing slash if reqd) */
char *prefix = "/dev/";
if (!(_cf = create_config_file())) {
@ -781,15 +821,15 @@ static int run_script(int argc, char **argv)
if ((script = fopen(argv[0], "r")) == NULL)
return ENO_SUCH_CMD;
while (fgets(buffer, sizeof (buffer), script) != NULL) {
while (fgets(buffer, sizeof(buffer), script) != NULL) {
if (!magic_number) {
if (buffer[0] == '#' && buffer[1] == '!')
magic_number = 1;
else
return ENO_SUCH_CMD;
}
if ((strlen(buffer) == sizeof (buffer) - 1)
&& (buffer[sizeof (buffer) - 1] - 2 != '\n')) {
if ((strlen(buffer) == sizeof(buffer) - 1)
&& (buffer[sizeof(buffer) - 1] - 2 != '\n')) {
buffer[50] = '\0';
log_error("Line too long (max 255) beginning: %s",
buffer);
@ -901,7 +941,7 @@ static char *list_args(char *text, int state)
char c;
if (!(c = (the_args +
com->valid_args[match_no++])->short_arg))
continue;
continue;
sprintf(s, "-%c", c);
if (!strncmp(text, s, len))

View File

@ -25,22 +25,32 @@ int lvreduce(int argc, char **argv)
struct volume_group *vg;
struct logical_volume *lv;
struct list *lvh;
int32_t extents = 0;
int32_t size = 0;
uint32_t extents = 0;
uint32_t size = 0;
sign_t sign = SIGN_NONE;
char *lv_name, *vg_name;
char *st;
int i;
if (arg_count(extents_ARG) + arg_count(size_ARG) != 1) {
log_error("Please specify either size or extents (not both)");
return EINVALID_CMD_LINE;
}
/* FIXME signed use throughout halves the maximum... */
if (arg_count(extents_ARG))
if (arg_count(extents_ARG)) {
extents = arg_int_value(extents_ARG, 0);
sign = arg_sign_value(extents_ARG, SIGN_NONE);
}
if (arg_count(size_ARG))
if (arg_count(size_ARG)) {
size = arg_int_value(size_ARG, 0);
sign = arg_sign_value(extents_ARG, SIGN_NONE);
}
if (sign == SIGN_PLUS) {
log_error("Positive sign not permitted - use lvextend");
return EINVALID_CMD_LINE;
}
if (!argc) {
log_error("Please provide the logical volume name");
@ -94,15 +104,18 @@ int lvreduce(int argc, char **argv)
if (extents % vg->extent_size) {
char *s1;
extents += (signed) vg->extent_size -
(signed) (extents % vg->extent_size);
if (sign == SIGN_NONE)
extents += vg->extent_size -
(extents % vg->extent_size);
else
extents -= extents % vg->extent_size;
log_print("Rounding up size to full physical extent %s",
(s1 =
display_size(abs(extents) / 2, SIZE_SHORT)));
(s1 = display_size(extents / 2, SIZE_SHORT)));
dbg_free(s1);
}
extents /= (signed) vg->extent_size;
extents /= vg->extent_size;
}
if (!extents) {
@ -110,14 +123,14 @@ int lvreduce(int argc, char **argv)
return EINVALID_CMD_LINE;
}
if (extents < 0) {
if (1 - extents > lv->le_count) {
if (sign == SIGN_MINUS) {
if (extents >= lv->le_count) {
log_error("Unable to reduce %s below 1 extent",
lv_name);
return EINVALID_CMD_LINE;
}
lv->le_count += extents;
extents = lv->le_count - extents;
} else {
if (extents >= lv->le_count) {
log_error("New size given (%d extents) not less than "
@ -125,7 +138,6 @@ int lvreduce(int argc, char **argv)
lv->le_count);
return EINVALID_CMD_LINE;
}
lv->le_count = extents;
}
/************ FIXME Stripes
@ -144,7 +156,7 @@ int lvreduce(int argc, char **argv)
log_print("WARNING: Reducing active%s logical volume to %s",
(lv_open_count(lv) > 0) ? " and open" : "",
(dummy =
display_size(lv->le_count * vg->extent_size / 2,
display_size(extents * vg->extent_size / 2,
SIZE_SHORT)));
log_print("THIS MAY DESTROY YOUR DATA (filesystem etc.)");
dbg_free(dummy);
@ -159,6 +171,12 @@ int lvreduce(int argc, char **argv)
}
}
for (i = extents; i < lv->le_count; i++) {
lv->map[i].pv->pe_allocated--;
}
lv->le_count = extents;
/********* FIXME Suspend lv ***********/
/* store vg on disk(s) */
@ -180,4 +198,3 @@ int lvreduce(int argc, char **argv)
return 0;
}

View File

@ -121,4 +121,3 @@ int lvremove_single(char *lv_name)
log_print("logical volume %s successfully removed", lv_name);
return 0;
}

View File

@ -19,7 +19,6 @@
*/
int e2fsadm(int argc, char **argv) {return 1;}
int lvextend(int argc, char **argv) {return 1;}
int lvmdiskscan(int argc, char **argv) {return 1;}
int lvmsadc(int argc, char **argv) {return 1;}
int lvmsar(int argc, char **argv) {return 1;}

View File

@ -62,6 +62,12 @@ enum {
#undef xx
};
typedef enum {
SIGN_NONE = 0,
SIGN_PLUS = 1,
SIGN_MINUS = 2
} sign_t;
/* a global table of possible arguments */
struct arg {
char short_arg;
@ -69,7 +75,8 @@ struct arg {
int (*fn)(struct arg *a);
int count;
char *value;
int i_value;
uint32_t i_value;
sign_t sign;
};
extern struct arg the_args[ARG_COUNT + 1];
@ -80,6 +87,7 @@ void usage(const char *name);
int yes_no_arg(struct arg *a);
int size_arg(struct arg *a);
int int_arg(struct arg *a);
int int_arg_with_sign(struct arg *a);
int string_arg(struct arg *a);
int permission_arg(struct arg *a);
@ -99,11 +107,16 @@ static inline char *arg_str_value(int a, char *def)
return arg_count(a) ? the_args[a].value : def;
}
static inline int arg_int_value(int a, int def)
static inline uint32_t arg_int_value(int a, uint32_t def)
{
return arg_count(a) ? the_args[a].i_value : def;
}
static inline sign_t arg_sign_value(int a, sign_t def)
{
return arg_count(a) ? the_args[a].sign : def;
}
static inline int arg_count_increment(int a)
{
return the_args[a].count++;