1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

More vgcreate error trapping

This commit is contained in:
Alasdair Kergon 2001-10-15 18:39:40 +00:00
parent 550380f9c8
commit df2e0dc751
7 changed files with 157 additions and 103 deletions

View File

@ -37,27 +37,21 @@ static struct volume_group *_build_vg(struct pool *mem, struct list_head *pvs)
struct volume_group *vg = pool_alloc(mem, sizeof(*vg)); struct volume_group *vg = pool_alloc(mem, sizeof(*vg));
struct disk_list *dl; struct disk_list *dl;
if (list_empty(pvs)) { if (!vg)
stack; goto bad;
return NULL;
} if (list_empty(pvs))
goto bad;
dl = list_entry(pvs->next, struct disk_list, list); dl = list_entry(pvs->next, struct disk_list, list);
if (!vg) {
stack;
return NULL;
}
memset(vg, 0, sizeof(*vg)); memset(vg, 0, sizeof(*vg));
INIT_LIST_HEAD(&vg->pvs); INIT_LIST_HEAD(&vg->pvs);
INIT_LIST_HEAD(&vg->lvs); INIT_LIST_HEAD(&vg->lvs);
if (!_check_vgs(pvs)) { if (!_check_vgs(pvs))
stack; goto bad;
return NULL;
}
if (!import_vg(mem, vg, dl)) if (!import_vg(mem, vg, dl))
goto bad; goto bad;
@ -130,6 +124,7 @@ static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
!export_lvs(dl, vg, pv, prefix) || !export_lvs(dl, vg, pv, prefix) ||
!calculate_layout(dl)) { !calculate_layout(dl)) {
stack; stack;
pool_free(mem, dl);
return NULL; return NULL;
} }
@ -239,6 +234,7 @@ static struct list_head *_get_pvs(struct io_space *is)
if (!(results = pool_alloc(is->mem, sizeof(*results)))) { if (!(results = pool_alloc(is->mem, sizeof(*results)))) {
stack; stack;
pool_destroy(mem);
return NULL; return NULL;
} }
@ -259,8 +255,8 @@ static struct list_head *_get_pvs(struct io_space *is)
return results; return results;
bad: bad:
pool_destroy(mem);
pool_free(mem, results); pool_free(mem, results);
pool_destroy(mem);
return NULL; return NULL;
} }
@ -359,7 +355,7 @@ static int _pv_write(struct io_space *is, struct physical_volume *pv)
if (!(dl = pool_alloc(mem, sizeof(*dl)))) { if (!(dl = pool_alloc(mem, sizeof(*dl)))) {
stack; stack;
return 0; goto bad;
} }
dl->mem = mem; dl->mem = mem;
dl->dev = pv->dev; dl->dev = pv->dev;
@ -386,11 +382,11 @@ static int _pv_write(struct io_space *is, struct physical_volume *pv)
int _vg_setup(struct io_space *is, struct volume_group *vg) int _vg_setup(struct io_space *is, struct volume_group *vg)
{ {
/* just check max_pv and max_lv */ /* just check max_pv and max_lv */
if (vg->max_lv > MAX_LV) if (vg->max_lv >= MAX_LV)
vg->max_lv = MAX_LV; vg->max_lv = MAX_LV - 1;
if (vg->max_pv > MAX_PV) if (vg->max_pv >= MAX_PV)
vg->max_pv = MAX_PV; vg->max_pv = MAX_PV - 1;
return 1; return 1;
} }
@ -398,6 +394,7 @@ int _vg_setup(struct io_space *is, struct volume_group *vg)
void _destroy(struct io_space *ios) void _destroy(struct io_space *ios)
{ {
dbg_free(ios->prefix); dbg_free(ios->prefix);
pool_destroy(ios->mem);
dbg_free(ios); dbg_free(ios);
} }

View File

@ -13,30 +13,44 @@
#include <string.h> #include <string.h>
int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg, int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
const char *name) const char *pv_name)
{ {
struct pv_list *pvl = pool_alloc(ios->mem, sizeof(*pvl)); struct pv_list *pvl;
struct physical_volume *pv = &pvl->pv; struct physical_volume *pv;
if (!pv) { log_verbose("Adding physical volume '%s' to volume group '%s'",
log_error("pv_list allocation for '%s' failed", name); pv_name, vg->name);
if (!(pvl = pool_alloc(ios->mem, sizeof (*pvl)))) {
log_error("pv_list allocation for '%s' failed", pv_name);
return 0; return 0;
} }
memset(pv, 0, sizeof(*pv)); if (!(pv = ios->pv_read(ios, pv_name))) {
log_error("Failed to read existing physical volume '%s'",
if (!(pv->dev = dev_cache_get(name, ios->filter))) { pv_name);
log_error("Physical volume '%s' not found.", name);
return 0; return 0;
} }
if (*pv->vg_name) {
log_error("Physical volume '%s' is already in volume group "
"'%s'", pv_name, pv->vg_name);
return 0;
}
/* FIXME For LVM2, set on PV creation instead of here? */
pv->status |= ALLOCATED_PV;
/* FIXME check this */
pv->exported = NULL;
if (!(pv->vg_name = pool_strdup(ios->mem, vg->name))) { if (!(pv->vg_name = pool_strdup(ios->mem, vg->name))) {
log_error("vg->name allocation failed for '%s'", name); log_error("vg->name allocation failed for '%s'", pv_name);
return 0; return 0;
} }
pv->exported = NULL; /* FIXME Tie this to activation or not? */
pv->status = ACTIVE; pv->status |= ACTIVE;
if (!dev_get_size(pv->dev, &pv->size)) { if (!dev_get_size(pv->dev, &pv->size)) {
stack; stack;
@ -55,91 +69,110 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
pv->pe_allocated = 0; pv->pe_allocated = 0;
if (!ios->pv_setup(ios, pv, vg)) { if (!ios->pv_setup(ios, pv, vg)) {
log_error("Format specific setup of physical volume '%s' " log_debug("Format specific setup of physical volume '%s' "
"failed.", name); "failed.", pv_name);
return 0; return 0;
} }
if (find_pv_in_vg(vg, pv_name)) {
log_error("Physical volume '%s' listed more than once.",
pv_name);
return 0;
}
if (vg->pv_count == vg->max_pv) {
log_error("No space for '%s' - volume group '%s' "
"holds max %d physical volume(s).", pv_name,
vg->name, vg->max_pv);
return 0;
}
memcpy(&pvl->pv, pv, sizeof (struct physical_volume));
list_add(&pvl->list, &vg->pvs); list_add(&pvl->list, &vg->pvs);
vg->pv_count++; vg->pv_count++;
return 1; return 1;
} }
struct volume_group *vg_create(struct io_space *ios, const char *name, struct volume_group *vg_create(struct io_space *ios, const char *vg_name,
uint64_t extent_size, int max_pv, int max_lv, uint64_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names) int pv_count, char **pv_names)
{ {
int i; int i;
struct volume_group *vg; struct volume_group *vg;
if (!(vg = pool_alloc(ios->mem, sizeof(*vg)))) { if (!(vg = pool_alloc(ios->mem, sizeof (*vg)))) {
stack; stack;
return NULL; return NULL;
} }
/* is this vg name already in use ? */ /* is this vg name already in use ? */
if (ios->vg_read(ios, name)) { if (ios->vg_read(ios, vg_name)) {
log_err("A volume group called '%s' already exists.", name); log_err("A volume group called '%s' already exists.", vg_name);
goto bad; goto bad;
} }
if (!id_create(&vg->id)) { if (!id_create(&vg->id)) {
log_err("Couldn't create uuid for volume group '%s'.", name); log_err("Couldn't create uuid for volume group '%s'.", vg_name);
goto bad; goto bad;
} }
if (!(vg->name = pool_strdup(ios->mem, name))) { /* 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; stack;
goto bad; goto bad;
} }
vg->status = (ACTIVE | EXTENDABLE_VG | LVM_READ | LVM_WRITE); vg->status = (ACTIVE | EXTENDABLE_VG | LVM_READ | LVM_WRITE);
vg->extent_size = extent_size; vg->extent_size = extent_size;
vg->extent_count = 0; vg->extent_count = 0;
vg->free_count = 0; vg->free_count = 0;
vg->max_lv = max_lv; vg->max_lv = max_lv;
vg->max_pv = max_pv; vg->max_pv = max_pv;
vg->pv_count = 0; vg->pv_count = 0;
INIT_LIST_HEAD(&vg->pvs); INIT_LIST_HEAD(&vg->pvs);
vg->lv_count = 0; vg->lv_count = 0;
INIT_LIST_HEAD(&vg->lvs); INIT_LIST_HEAD(&vg->lvs);
if (!ios->vg_setup(ios, vg)) { if (!ios->vg_setup(ios, vg)) {
log_err("Format specific setup of volume group '%s' failed.", log_error("Format specific setup of volume group '%s' failed.",
name); vg_name);
goto bad; goto bad;
} }
/* attach the pv's */ /* attach the pv's */
for (i = 0; i < pv_count; i++) for (i = 0; i < pv_count; i++)
if (!_add_pv_to_vg(ios, vg, pv_names[i])) { if (!_add_pv_to_vg(ios, vg, pv_names[i])) {
log_err("Unable to add physical volume '%s' to " log_error("Unable to add physical volume '%s' to "
"volume group '%s'.", pv_names[i], name); "volume group '%s'.", pv_names[i], vg_name);
goto bad; goto bad;
} }
return vg; return vg;
bad: bad:
pool_free(ios->mem, vg); pool_free(ios->mem, vg);
return NULL; return NULL;
} }
struct physical_volume *pv_create(struct io_space *ios, const char *name) struct physical_volume *pv_create(struct io_space *ios, const char *name)
{ {
struct physical_volume *pv = pool_alloc(ios->mem, sizeof(*pv)); struct physical_volume *pv = pool_alloc(ios->mem, sizeof (*pv));
if (!pv) { if (!pv) {
stack; stack;
return NULL; return NULL;
} }
id_create(&pv->id); id_create(&pv->id);
if (!(pv->dev = dev_cache_get(name, ios->filter))) { if (!(pv->dev = dev_cache_get(name, ios->filter))) {
log_err("Couldn't find device '%s'", name); log_err("Couldn't find device '%s'", name);
goto bad; goto bad;
@ -152,23 +185,32 @@ struct physical_volume *pv_create(struct io_space *ios, const char *name)
*pv->vg_name = 0; *pv->vg_name = 0;
pv->exported = NULL; pv->exported = NULL;
pv->status = 0; pv->status = 0;
if (!dev_get_size(pv->dev, &pv->size)) { if (!dev_get_size(pv->dev, &pv->size)) {
log_err("Couldn't get size of device '%s'", name); log_err("Couldn't get size of device '%s'", name);
goto bad; goto bad;
} }
pv->pe_size = 0; pv->pe_size = 0;
pv->pe_start = 0; pv->pe_start = 0;
pv->pe_count = 0; pv->pe_count = 0;
pv->pe_allocated = 0; pv->pe_allocated = 0;
return pv; return pv;
bad: bad:
pool_free(ios->mem, pv); pool_free(ios->mem, pv);
return NULL; return NULL;
} }
struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
{
struct list_head *pvh;
list_for_each(pvh, &vg->pvs) {
if (!strcmp(list_entry(pvh, struct pv_list, list)->pv.dev->name,
pv_name)) return pvh;
}
return NULL;
}

View File

@ -239,4 +239,7 @@ struct volume_group *vg_find(const char *lv_name);
/* Find an LV within a given VG */ /* Find an LV within a given VG */
struct logical_volume *lv_find(struct volume_group *vg, const char *lv_name); struct logical_volume *lv_find(struct volume_group *vg, const char *lv_name);
/* Find a PV within a given VG */
struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name);
#endif #endif

View File

@ -13,7 +13,7 @@ const char _really_init[] =
* See if we may pvcreate on this device. * See if we may pvcreate on this device.
* 0 indicates we may not. * 0 indicates we may not.
*/ */
static int _check(const char *name) static int pvcreate_check(const char *name)
{ {
struct physical_volume *pv; struct physical_volume *pv;
@ -36,6 +36,11 @@ static int _check(const char *name)
return 0; return 0;
} }
if (pv->status & ACTIVE) {
log_error("Can't create on active physical volume %s", name);
return 0;
}
/* we must have -ff to overwrite a non orphan */ /* we must have -ff to overwrite a non orphan */
if (arg_count(force_ARG) < 2) { if (arg_count(force_ARG) < 2) {
log_error("Can't initialize physical volume %s of " log_error("Can't initialize physical volume %s of "
@ -50,42 +55,38 @@ static int _check(const char *name)
return 0; return 0;
} }
if (pv->status & ACTIVE) { if (arg_count(force_ARG)) {
log_error("Can't create on active physical volume %s", name); log_print("WARNING: Forcing physical volume creation on "
return 0; "%s%s%s", name,
pv->vg_name[0] ? " of volume group " : "",
pv->vg_name[0] ? pv->vg_name : "");
} }
return 1; return 1;
} }
static void pvcreate_single(const char *name) static void pvcreate_single(const char *pv_name)
{ {
struct physical_volume *pv; struct physical_volume *pv;
if (arg_count(force_ARG)) { if (!pvcreate_check(pv_name))
log_print("WARNING: forcing physical volume creation on %s", return;
name);
if (pv->vg_name[0]) if (!(pv = pv_create(ios, pv_name))) {
log_print(" of volume group %s", pv->vg_name); log_err("Failed to setup physical volume %s", pv_name);
log_print(" ");
}
if (!(pv = pv_create(ios, name))) {
log_err("Failed to setup physical volume %s", name);
return; return;
} }
log_verbose("Set up physical volume for %s with %llu sectors", log_verbose("Set up physical volume for %s with %llu sectors",
name, pv->size); pv_name, pv->size);
log_verbose("Writing physical volume data to disk %s", pv_name);
log_verbose("Writing physical volume data to disk %s", name);
if (!(ios->pv_write(ios, pv))) { if (!(ios->pv_write(ios, pv))) {
log_error("Failed to write physical volume %s", name); log_error("Failed to write physical volume %s", pv_name);
return; return;
} }
log_print("Physical volume %s successfully created", name); log_print("Physical volume %s successfully created", pv_name);
} }
int pvcreate(int argc, char **argv) int pvcreate(int argc, char **argv)
@ -103,10 +104,6 @@ int pvcreate(int argc, char **argv)
} }
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
if (!_check(argv[i]))
continue;
pvcreate_single(argv[i]); pvcreate_single(argv[i]);
pool_empty(ios->mem); pool_empty(ios->mem);
} }

View File

@ -166,14 +166,3 @@ int is_valid_chars(char *n)
return 1; return 1;
} }
struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
{
struct list_head *pvh;
list_for_each(pvh, &vg->pvs) {
if (!strcmp(list_entry(pvh, struct pv_list, list)->pv.dev->name,
pv_name)) return pvh;
}
return NULL;
}

View File

@ -34,6 +34,4 @@ int process_each_pv(int argc, char **argv, struct volume_group *vg,
int is_valid_chars(char *n); int is_valid_chars(char *n);
struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name);
#endif #endif

View File

@ -6,9 +6,9 @@
#include "tools.h" #include "tools.h"
/* FIXME Config file? */ /* FIXME From config file? */
#define DEFAULT_PV 128 #define DEFAULT_PV 255
#define DEFAULT_LV 128 #define DEFAULT_LV 255
#define DEFAULT_EXTENT 8192 #define DEFAULT_EXTENT 8192
int vgcreate(int argc, char **argv) int vgcreate(int argc, char **argv)
@ -33,13 +33,41 @@ int vgcreate(int argc, char **argv)
max_pv = arg_int_value(maxphysicalvolumes_ARG, DEFAULT_PV); max_pv = arg_int_value(maxphysicalvolumes_ARG, DEFAULT_PV);
extent_size = arg_int_value(physicalextentsize_ARG, DEFAULT_EXTENT); extent_size = arg_int_value(physicalextentsize_ARG, DEFAULT_EXTENT);
if (max_lv < 1) {
log_error("maxlogicalvolumes too low");
return EINVALID_CMD_LINE;
}
if (max_pv < 1) {
log_error("maxphysicalvolumes too low");
return EINVALID_CMD_LINE;
}
/* Strip prefix if present */
if (!strncmp(vg_name, ios->prefix, strlen(ios->prefix)))
vg_name += strlen(ios->prefix);
if (!is_valid_chars(vg_name)) {
log_error("New volume group name '%s' has invalid characters",
vg_name);
return ECMD_FAILED;
}
/* create the new vg */ /* create the new vg */
if (!vg_create(ios, vg_name, extent_size, max_pv, max_lv, if (!(vg = vg_create(ios, vg_name, extent_size, max_pv, max_lv,
argc - 1, argv + 1)) argc - 1, argv + 1)))
return ECMD_FAILED; return ECMD_FAILED;
if (max_lv != vg->max_lv)
log_error("Warning: Setting maxlogicalvolumes to %d",
vg->max_lv);
if (max_pv != vg->max_pv)
log_error("Warning: Setting maxphysicalvolumes to %d",
vg->max_pv);
/* store vg on disk(s) */ /* store vg on disk(s) */
if (ios->vg_write(ios, vg)) if (!ios->vg_write(ios, vg))
return ECMD_FAILED; return ECMD_FAILED;
/* FIXME Create /dev/vg */ /* FIXME Create /dev/vg */