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

o Split struct io_space into:

struct format_handler - format methods
   struct format_instance - links instance data, methods, and cmd
   struct cmd_context - dev_dir, memory allocator, device filter
This commit is contained in:
Joe Thornber 2001-11-12 12:16:57 +00:00
parent 3c02236767
commit 2107f48208
6 changed files with 194 additions and 201 deletions

View File

@ -27,6 +27,7 @@ static int _check_vgs(struct list *pvs)
if (!first) if (!first)
first = dl; first = dl;
else if (memcmp(&first->vgd, &dl->vgd, sizeof(first->vgd))) { else if (memcmp(&first->vgd, &dl->vgd, sizeof(first->vgd))) {
log_err("VG data differs between PVs %s and %s", log_err("VG data differs between PVs %s and %s",
dev_name(first->dev), dev_name(dl->dev)); dev_name(first->dev), dev_name(dl->dev));
@ -86,7 +87,8 @@ static struct volume_group *_build_vg(struct pool *mem, struct list *pvs)
return NULL; return NULL;
} }
static struct volume_group *_vg_read(struct io_space *is, const char *vg_name) static struct volume_group *_vg_read(struct format_instance *fi,
const char *vg_name)
{ {
struct pool *mem = pool_create(1024 * 10); struct pool *mem = pool_create(1024 * 10);
struct list pvs; struct list pvs;
@ -99,15 +101,14 @@ static struct volume_group *_vg_read(struct io_space *is, const char *vg_name)
} }
/* Strip prefix if present */ /* Strip prefix if present */
if (!strncmp(vg_name, is->prefix, strlen(is->prefix))) vg_name = strip_dir(vg_name, fi->cmd->dev_dir);
vg_name += strlen(is->prefix);
if (!read_pvs_in_vg(vg_name, is->filter, mem, &pvs)) { if (!read_pvs_in_vg(vg_name, fi->cmd->filter, mem, &pvs)) {
stack; stack;
return NULL; return NULL;
} }
if (!(vg = _build_vg(is->mem, &pvs))) if (!(vg = _build_vg(fi->cmd->mem, &pvs)))
stack; stack;
pool_destroy(mem); pool_destroy(mem);
@ -174,7 +175,7 @@ static int _flatten_vg(struct pool *mem, struct volume_group *vg,
return 1; return 1;
} }
static int _vg_write(struct io_space *is, struct volume_group *vg) static int _vg_write(struct format_instance *fi, struct volume_group *vg)
{ {
struct pool *mem = pool_create(1024 * 10); struct pool *mem = pool_create(1024 * 10);
struct list pvs; struct list pvs;
@ -187,17 +188,17 @@ static int _vg_write(struct io_space *is, struct volume_group *vg)
list_init(&pvs); list_init(&pvs);
r = (_flatten_vg(mem, vg, &pvs, is->prefix, is->filter) && r = (_flatten_vg(mem, vg, &pvs, fi->cmd->dev_dir, fi->cmd->filter) &&
write_pvds(&pvs)); write_pvds(&pvs));
pool_destroy(mem); pool_destroy(mem);
return r; return r;
} }
static struct physical_volume *_pv_read(struct io_space *is, static struct physical_volume *_pv_read(struct format_instance *fi,
const char *name) const char *name)
{ {
struct pool *mem = pool_create(1024); struct pool *mem = pool_create(1024);
struct physical_volume *pv; struct physical_volume *pv = NULL;
struct disk_list *dl; struct disk_list *dl;
struct device *dev; struct device *dev;
@ -208,35 +209,33 @@ static struct physical_volume *_pv_read(struct io_space *is,
return NULL; return NULL;
} }
if (!(dev = dev_cache_get(name, is->filter))) { if (!(dev = dev_cache_get(name, fi->cmd->filter))) {
stack; stack;
goto bad; goto out;
} }
if (!(dl = read_disk(dev, mem, NULL))) { if (!(dl = read_disk(dev, mem, NULL))) {
stack; stack;
goto bad; goto out;
} }
if (!(pv = pool_alloc(is->mem, sizeof(*pv)))) { if (!(pv = pool_alloc(fi->cmd->mem, sizeof(*pv)))) {
stack; stack;
goto bad; goto out;
} }
if (!import_pv(is->mem, dl->dev, pv, &dl->pvd)) { if (!import_pv(fi->cmd->mem, dl->dev, pv, &dl->pvd)) {
stack; stack;
goto bad; pool_free(fi->cmd->mem, pv);
pv = NULL;
} }
out:
pool_destroy(mem); pool_destroy(mem);
return pv; return pv;
bad:
pool_destroy(mem);
return NULL;
} }
static struct list *_get_pvs(struct io_space *is) static struct list *_get_pvs(struct format_instance *fi)
{ {
struct pool *mem = pool_create(1024 * 10); struct pool *mem = pool_create(1024 * 10);
struct list pvs, *results; struct list pvs, *results;
@ -247,7 +246,7 @@ static struct list *_get_pvs(struct io_space *is)
return NULL; return NULL;
} }
if (!(results = pool_alloc(is->mem, sizeof(*results)))) { if (!(results = pool_alloc(fi->cmd->mem, sizeof(*results)))) {
stack; stack;
pool_destroy(mem); pool_destroy(mem);
return NULL; return NULL;
@ -256,12 +255,12 @@ static struct list *_get_pvs(struct io_space *is)
list_init(&pvs); list_init(&pvs);
list_init(results); list_init(results);
if (!read_pvs_in_vg(NULL, is->filter, mem, &pvs)) { if (!read_pvs_in_vg(NULL, fi->cmd->filter, mem, &pvs)) {
stack; stack;
goto bad; goto bad;
} }
if (!import_pvs(is->mem, &pvs, results, &count)) { if (!import_pvs(fi->cmd->mem, &pvs, results, &count)) {
stack; stack;
goto bad; goto bad;
} }
@ -270,7 +269,7 @@ static struct list *_get_pvs(struct io_space *is)
return results; return results;
bad: bad:
pool_free(is->mem, results); pool_free(fi->cmd->mem, results);
pool_destroy(mem); pool_destroy(mem);
return NULL; return NULL;
} }
@ -289,10 +288,10 @@ static int _find_vg_name(struct list *names, const char *vg)
return 0; return 0;
} }
static struct list *_get_vgs(struct io_space *is) static struct list *_get_vgs(struct format_instance *fi)
{ {
struct list *pvh; struct list *pvh;
struct list *pvs, *names = pool_alloc(is->mem, sizeof(*names)); struct list *pvs, *names = pool_alloc(fi->cmd->mem, sizeof(*names));
struct name_list *nl; struct name_list *nl;
if (!names) { if (!names) {
@ -302,7 +301,7 @@ static struct list *_get_vgs(struct io_space *is)
list_init(names); list_init(names);
if (!(pvs = _get_pvs(is))) { if (!(pvs = _get_pvs(fi))) {
stack; stack;
goto bad; goto bad;
} }
@ -314,12 +313,12 @@ static struct list *_get_vgs(struct io_space *is)
_find_vg_name(names, pvl->pv.vg_name)) _find_vg_name(names, pvl->pv.vg_name))
continue; continue;
if (!(nl = pool_alloc(is->mem, sizeof(*nl)))) { if (!(nl = pool_alloc(fi->cmd->mem, sizeof(*nl)))) {
stack; stack;
goto bad; goto bad;
} }
if (!(nl->name = pool_strdup(is->mem, pvl->pv.vg_name))) { if (!(nl->name = pool_strdup(fi->cmd->mem, pvl->pv.vg_name))) {
stack; stack;
goto bad; goto bad;
} }
@ -333,11 +332,11 @@ static struct list *_get_vgs(struct io_space *is)
return names; return names;
bad: bad:
pool_free(is->mem, names); pool_free(fi->cmd->mem, names);
return NULL; return NULL;
} }
static int _pv_setup(struct io_space *is, struct physical_volume *pv, static int _pv_setup(struct format_instance *fi, struct physical_volume *pv,
struct volume_group *vg) struct volume_group *vg)
{ {
/* /*
@ -351,7 +350,7 @@ static int _pv_setup(struct io_space *is, struct physical_volume *pv,
return 1; return 1;
} }
static int _pv_write(struct io_space *is, struct physical_volume *pv) static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
{ {
struct pool *mem; struct pool *mem;
struct disk_list *dl; struct disk_list *dl;
@ -401,7 +400,7 @@ static int _pv_write(struct io_space *is, struct physical_volume *pv)
return 0; return 0;
} }
int _vg_setup(struct io_space *is, struct volume_group *vg) int _vg_setup(struct format_instance *fi, 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)
@ -439,44 +438,36 @@ int _vg_setup(struct io_space *is, struct volume_group *vg)
return 1; return 1;
} }
void _destroy(struct io_space *ios) void _destroy(struct format_instance *fi)
{ {
dbg_free(ios->prefix); dbg_free(fi);
pool_destroy(ios->mem);
dbg_free(ios);
} }
struct io_space *create_lvm1_format(const char *prefix, struct pool *mem,
struct dev_filter *filter)
{
struct io_space *ios = dbg_malloc(sizeof(*ios));
if (!ios) { static struct format_handler _format1_ops = {
get_vgs: _get_vgs,
get_pvs: _get_pvs,
pv_read: _pv_read,
pv_setup: _pv_setup,
pv_write: _pv_write,
vg_read: _vg_read,
vg_setup: _vg_setup,
vg_write: _vg_write,
destroy: _destroy,
};
struct format_instance *create_lvm1_format(struct cmd_context *cmd)
{
struct format_instance *fi = dbg_malloc(sizeof(*fi));
if (!fi) {
stack; stack;
return NULL; return NULL;
} }
ios->get_vgs = _get_vgs; fi->cmd = cmd;
ios->get_pvs = _get_pvs; fi->ops = &_format1_ops;
ios->pv_read = _pv_read; fi->private = NULL;
ios->pv_setup = _pv_setup;
ios->pv_write = _pv_write;
ios->vg_read = _vg_read;
ios->vg_setup = _vg_setup;
ios->vg_write = _vg_write;
ios->destroy = _destroy;
ios->prefix = dbg_malloc(strlen(prefix) + 1); return fi;
if (!ios->prefix) {
stack;
dbg_free(ios);
return 0;
}
strcpy(ios->prefix, prefix);
ios->mem = mem;
ios->filter = filter;
ios->private = NULL;
return ios;
} }

View File

@ -9,7 +9,6 @@
#include "metadata.h" #include "metadata.h"
struct io_space *create_lvm1_format(const char *prefix, struct pool *mem, struct filter_instance *create_lvm1_format(struct cmd_context *cmd);
struct dev_filter *filter);
#endif #endif

View File

@ -526,22 +526,6 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
return 1; return 1;
} }
static int _get_lv_number(struct volume_group *vg, const char *name)
{
/* FIXME: inefficient */
int r = 0;
struct list *lvh;
list_iterate(lvh, &vg->lvs) {
struct lv_list *ll = list_item(lvh, struct lv_list);
if (!strcmp(ll->lv.name, name))
break;
r++;
}
return r;
}
/* /*
* This calculates the nasty pv_number and * This calculates the nasty pv_number and
* lv_number fields used by LVM1. Very * lv_number fields used by LVM1. Very
@ -549,9 +533,8 @@ static int _get_lv_number(struct volume_group *vg, const char *name)
*/ */
void export_numbers(struct list *pvs, struct volume_group *vg) void export_numbers(struct list *pvs, struct volume_group *vg)
{ {
struct list *pvh, *lvh; struct list *pvh;
struct disk_list *dl; struct disk_list *dl;
struct lvd_list *ll;
int pv_num = 1; int pv_num = 1;
list_iterate(pvh, pvs) { list_iterate(pvh, pvs) {

View File

@ -112,13 +112,11 @@ static int _alloc_simple(struct logical_volume *lv,
allocated += _alloc_area(lv, allocated, pvm->pv, pva); allocated += _alloc_area(lv, allocated, pvm->pv, pva);
if (allocated == lv->le_count) if (allocated == lv->le_count)
break; goto done;
} }
if (allocated == lv->le_count) /* FIXME: yuck, repeated test */
break;
} }
done:
if (allocated != lv->le_count) { if (allocated != lv->le_count) {
log_error("Insufficient free logical extents to " log_error("Insufficient free logical extents to "
"allocate logical volume %s: %u required", "allocate logical volume %s: %u required",
@ -165,13 +163,12 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
vg->free_count -= lv->le_count - allocated; vg->free_count -= lv->le_count - allocated;
} }
out: out:
pool_destroy(scratch); pool_destroy(scratch);
return r; return r;
} }
struct logical_volume *lv_create(struct io_space *ios, struct logical_volume *lv_create(const char *name,
const char *name,
uint32_t status, uint32_t status,
uint32_t stripes, uint32_t stripes,
uint32_t stripe_size, uint32_t stripe_size,
@ -179,6 +176,7 @@ struct logical_volume *lv_create(struct io_space *ios,
struct volume_group *vg, struct volume_group *vg,
struct list *acceptable_pvs) struct list *acceptable_pvs)
{ {
struct cmd_context *cmd = vg->cmd;
struct lv_list *ll = NULL; struct lv_list *ll = NULL;
struct logical_volume *lv; struct logical_volume *lv;
int i; int i;
@ -201,7 +199,7 @@ struct logical_volume *lv_create(struct io_space *ios,
return NULL; return NULL;
} }
if (!(ll = pool_zalloc(ios->mem, sizeof(*ll)))) { if (!(ll = pool_zalloc(cmd->mem, sizeof(*ll)))) {
stack; stack;
return NULL; return NULL;
} }
@ -212,7 +210,7 @@ struct logical_volume *lv_create(struct io_space *ios,
strcpy(lv->id.uuid, ""); strcpy(lv->id.uuid, "");
if (!(lv->name = pool_strdup(ios->mem, name))) { if (!(lv->name = pool_strdup(cmd->mem, name))) {
stack; stack;
goto bad; goto bad;
} }
@ -223,7 +221,8 @@ struct logical_volume *lv_create(struct io_space *ios,
lv->size = extents * vg->extent_size; lv->size = extents * vg->extent_size;
lv->le_count = extents; lv->le_count = extents;
if (!(lv->map = pool_zalloc(ios->mem, sizeof(*lv->map) * extents))) { if (!(lv->map = pool_zalloc(cmd->mem,
sizeof(*lv->map) * extents))) {
stack; stack;
goto bad; goto bad;
} }
@ -233,9 +232,8 @@ struct logical_volume *lv_create(struct io_space *ios,
goto bad; goto bad;
} }
for (i = 0; i < lv->le_count; i++) { for (i = 0; i < lv->le_count; i++)
lv->map[i].pv->pe_allocated++; lv->map[i].pv->pe_allocated++;
}
vg->lv_count++; vg->lv_count++;
list_add(&vg->lvs, &ll->list); list_add(&vg->lvs, &ll->list);
@ -243,15 +241,16 @@ struct logical_volume *lv_create(struct io_space *ios,
return lv; return lv;
bad: bad:
if (ll) if (ll)
pool_free(ios->mem, ll); pool_free(cmd->mem, ll);
return NULL; return NULL;
} }
int lv_reduce(struct io_space *ios, struct logical_volume *lv, uint32_t extents) int lv_reduce(struct logical_volume *lv, uint32_t extents)
{ {
// FIXME: merge with Alasdair's version in tools
if (extents % lv->stripes) { if (extents % lv->stripes) {
log_error("For a striped volume you must reduce by a " log_error("For a striped volume you must reduce by a "
"multiple of the number of stripes"); "multiple of the number of stripes");
@ -269,15 +268,15 @@ int lv_reduce(struct io_space *ios, struct logical_volume *lv, uint32_t extents)
return 1; return 1;
} }
int lv_extend(struct io_space *ios, int lv_extend(struct logical_volume *lv, uint32_t extents,
struct logical_volume *lv, uint32_t extents,
struct list *acceptable_pvs) struct list *acceptable_pvs)
{ {
struct cmd_context *cmd = lv->vg->cmd;
struct pe_specifier *new_map; struct pe_specifier *new_map;
struct logical_volume *new_lv; struct logical_volume *new_lv;
int i; int i;
if (!(new_map = pool_zalloc(ios->mem, sizeof(*new_map) * if (!(new_map = pool_zalloc(cmd->mem, sizeof(*new_map) *
(extents + lv->le_count)))) { (extents + lv->le_count)))) {
stack; stack;
return 0; return 0;
@ -285,8 +284,8 @@ int lv_extend(struct io_space *ios,
memcpy(new_map, lv->map, sizeof(*new_map) * lv->le_count); memcpy(new_map, lv->map, sizeof(*new_map) * lv->le_count);
if (!(new_lv = pool_alloc(ios->mem, sizeof(*new_lv)))) { if (!(new_lv = pool_alloc(cmd->mem, sizeof(*new_lv)))) {
pool_free(ios->mem, new_map); pool_free(cmd->mem, new_map);
stack; stack;
return 0; return 0;
} }
@ -300,17 +299,20 @@ int lv_extend(struct io_space *ios,
goto bad; goto bad;
} }
for (i = lv->le_count; i < new_lv->le_count; i++) { for (i = lv->le_count; i < new_lv->le_count; i++)
new_lv->map[i].pv->pe_allocated++; new_lv->map[i].pv->pe_allocated++;
}
memcpy(lv, new_lv, sizeof(*lv)); memcpy(lv, new_lv, sizeof(*lv));
/* now you see why new_lv had to be allocated last */ /*
pool_free(ios->mem, new_lv); * new_lv had to be allocated last so we
* could free it without touching the new
* map
*/
pool_free(cmd->mem, new_lv);
return 1; return 1;
bad: bad:
pool_free(ios->mem, new_map); pool_free(cmd->mem, new_map);
return 0; return 0;
} }

View File

@ -12,21 +12,22 @@
#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 format_instance *fi, struct volume_group *vg,
const char *pv_name) const char *pv_name)
{ {
struct pv_list *pvl; struct pv_list *pvl;
struct physical_volume *pv; struct physical_volume *pv;
struct pool *mem = fi->cmd->mem;
log_verbose("Adding physical volume '%s' to volume group '%s'", 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)))) { if (!(pvl = pool_alloc(mem, sizeof (*pvl)))) {
log_error("pv_list allocation for '%s' failed", pv_name); log_error("pv_list allocation for '%s' failed", pv_name);
return 0; return 0;
} }
if (!(pv = ios->pv_read(ios, pv_name))) { if (!(pv = fi->ops->pv_read(fi, pv_name))) {
log_error("Failed to read existing physical volume '%s'", log_error("Failed to read existing physical volume '%s'",
pv_name); pv_name);
return 0; return 0;
@ -44,7 +45,7 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
/* FIXME check this */ /* FIXME check this */
pv->exported = NULL; pv->exported = NULL;
if (!(pv->vg_name = pool_strdup(ios->mem, vg->name))) { if (!(pv->vg_name = pool_strdup(mem, vg->name))) {
log_error("vg->name allocation failed for '%s'", pv_name); log_error("vg->name allocation failed for '%s'", pv_name);
return 0; return 0;
} }
@ -63,14 +64,14 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
/* /*
* The next two fields should be corrected * The next two fields should be corrected
* by ios->pv_setup. * by fi->pv_setup.
*/ */
pv->pe_start = 0; pv->pe_start = 0;
pv->pe_count = pv->size / pv->pe_size; pv->pe_count = pv->size / pv->pe_size;
pv->pe_allocated = 0; pv->pe_allocated = 0;
if (!ios->pv_setup(ios, pv, vg)) { if (!fi->ops->pv_setup(fi, pv, vg)) {
log_debug("Format-specific setup of physical volume '%s' " log_debug("Format-specific setup of physical volume '%s' "
"failed.", pv_name); "failed.", pv_name);
return 0; return 0;
@ -89,7 +90,7 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
return 0; return 0;
} }
memcpy(&pvl->pv, pv, sizeof (struct physical_volume)); memcpy(&pvl->pv, pv, sizeof(*pv));
list_add(&vg->pvs, &pvl->list); list_add(&vg->pvs, &pvl->list);
vg->pv_count++; vg->pv_count++;
@ -99,14 +100,14 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg,
return 1; return 1;
} }
int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count, int vg_extend(struct format_instance *fi,
char **pv_names) struct volume_group *vg, int pv_count, char **pv_names)
{ {
int i; int i;
/* attach each pv */ /* attach each pv */
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(fi, vg, pv_names[i])) {
log_error("Unable to add physical volume '%s' to " log_error("Unable to add physical volume '%s' to "
"volume group '%s'.", pv_names[i], vg->name); "volume group '%s'.", pv_names[i], vg->name);
return 0; return 0;
@ -115,33 +116,43 @@ int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count,
return 1; return 1;
} }
struct volume_group *vg_create(struct io_space *ios, const char *vg_name, const char *strip_prefix(const char *vg_name, const char *dev_dir)
{
int len = strlen(dev_dir);
if (!strncmp(vg_name, dev_dir, len))
vg_name += len;
return vg_name;
}
struct volume_group *vg_create(struct format_instance *fi, const char *vg_name,
uint32_t extent_size, int max_pv, int max_lv, uint32_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names) int pv_count, char **pv_names)
{ {
struct volume_group *vg; struct volume_group *vg;
struct pool *mem = fi->cmd->mem;
if (!(vg = pool_alloc(ios->mem, sizeof (*vg)))) { if (!(vg = pool_alloc(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, vg_name)) { if (fi->ops->vg_read(fi, vg_name)) {
log_err("A volume group called '%s' already exists.", vg_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'.", vg_name); log_err("Couldn't create uuid for volume group '%s'.",
vg_name);
goto bad; goto bad;
} }
/* Strip prefix if present */ /* Strip prefix if present */
if (!strncmp(vg_name, ios->prefix, strlen(ios->prefix))) vg_name = strip_dir(vg_name, fi->cmd->dev_dir);
vg_name += strlen(ios->prefix);
if (!(vg->name = pool_strdup(ios->mem, vg_name))) { if (!(vg->name = pool_strdup(mem, vg_name))) {
stack; stack;
goto bad; goto bad;
} }
@ -161,26 +172,27 @@ struct volume_group *vg_create(struct io_space *ios, const char *vg_name,
vg->lv_count = 0; vg->lv_count = 0;
list_init(&vg->lvs); list_init(&vg->lvs);
if (!ios->vg_setup(ios, vg)) { if (!fi->ops->vg_setup(fi, vg)) {
log_error("Format specific setup of volume group '%s' failed.", log_error("Format specific setup of volume group '%s' failed.",
vg_name); vg_name);
goto bad; goto bad;
} }
/* attach the pv's */ /* attach the pv's */
if (!vg_extend(ios, vg, pv_count, pv_names)) if (!vg_extend(fi, vg, pv_count, pv_names))
goto bad; goto bad;
return vg; return vg;
bad: bad:
pool_free(ios->mem, vg); pool_free(mem, vg);
return NULL; return NULL;
} }
struct physical_volume *pv_create(struct io_space *ios, const char *name) struct physical_volume *pv_create(struct format_instance *fi, const char *name)
{ {
struct physical_volume *pv = pool_alloc(ios->mem, sizeof (*pv)); struct pool *mem = fi->cmd->mem;
struct physical_volume *pv = pool_alloc(mem, sizeof (*pv));
if (!pv) { if (!pv) {
stack; stack;
@ -188,12 +200,12 @@ struct physical_volume *pv_create(struct io_space *ios, const char *name)
} }
id_create(&pv->id); id_create(&pv->id);
if (!(pv->dev = dev_cache_get(name, ios->filter))) { if (!(pv->dev = dev_cache_get(name, fi->cmd->filter))) {
log_err("Couldn't find device '%s'", name); log_err("Couldn't find device '%s'", name);
goto bad; goto bad;
} }
if (!(pv->vg_name = pool_alloc(ios->mem, NAME_LEN))) { if (!(pv->vg_name = pool_alloc(mem, NAME_LEN))) {
stack; stack;
goto bad; goto bad;
} }
@ -214,7 +226,7 @@ struct physical_volume *pv_create(struct io_space *ios, const char *name)
return pv; return pv;
bad: bad:
pool_free(ios->mem, pv); pool_free(mem, pv);
return NULL; return NULL;
} }

View File

@ -64,7 +64,11 @@ struct pe_specifier {
uint32_t pe; uint32_t pe;
}; };
struct cmd_context;
struct volume_group { struct volume_group {
struct cmd_context *cmd;
struct id id; struct id id;
char *name; char *name;
@ -119,101 +123,114 @@ struct lv_list {
struct logical_volume lv; struct logical_volume lv;
}; };
struct cmd_context {
/* format handler allocates all objects from here */
struct pool *mem;
/* misc. vars needed by format handler */
char *dev_dir;
struct dev_filter *filter;
};
struct format_instance {
struct cmd_context *cmd;
struct format_handler *ops;
void *private;
};
/* /*
* Ownership of objects passes to caller. * Ownership of objects passes to caller.
*/ */
struct io_space { struct format_handler {
/* /*
* Returns a name_list of vg's. * Returns a name_list of vg's.
*/ */
struct list *(*get_vgs)(struct io_space *is); struct list *(*get_vgs)(struct format_instance *fi);
/* /*
* Returns pv_list of fully-populated pv structures. * Returns pv_list of fully-populated pv structures.
*/ */
struct list *(*get_pvs)(struct io_space *is); struct list *(*get_pvs)(struct format_instance *fi);
/* /*
* Return PV with given path. * Return PV with given path.
*/ */
struct physical_volume *(*pv_read)(struct io_space *is, struct physical_volume *(*pv_read)(struct format_instance *fi,
const char *pv_name); const char *pv_name);
/* /*
* Tweak an already filled out a pv ready * Tweak an already filled out a pv ready for importing into a
* for importing into a vg. eg. pe_count * vg. eg. pe_count is format specific.
* is format specific.
*/ */
int (*pv_setup)(struct io_space *is, struct physical_volume *pv, int (*pv_setup)(struct format_instance *fi, struct physical_volume *pv,
struct volume_group *vg); struct volume_group *vg);
/* /*
* Write a PV structure to disk. Fails if * Write a PV structure to disk. Fails if the PV is in a VG ie
* the PV is in a VG ie pv->vg_name must * pv->vg_name must be null.
* be null.
*/ */
int (*pv_write)(struct io_space *is, struct physical_volume *pv); int (*pv_write)(struct format_instance *fi,
struct physical_volume *pv);
/* /*
* Tweak an already filled out vg. eg, * Tweak an already filled out vg. eg, max_pv is format
* max_pv is format specific. * specific.
*/ */
int (*vg_setup)(struct io_space *is, struct volume_group *vg); int (*vg_setup)(struct format_instance *fi, struct volume_group *vg);
/* /*
* If vg_name doesn't contain any slash, * The name may be prefixed with the dev_dir from the
* this function adds prefix. * job_context.
*/ */
struct volume_group *(*vg_read)(struct io_space *is, struct volume_group *(*vg_read)(struct format_instance *fi,
const char *vg_name); const char *vg_name);
/* /*
* Write out complete VG metadata. Ensure * Write out complete VG metadata. You must ensure internal
* *internal* consistency before writing * consistency before calling. eg. PEs can't refer to PVs not
* anything. eg. PEs can't refer to PVs * part of the VG.
* not part of the VG. Order write sequence *
* to aid recovery if process is aborted * It is also the responsibility of the caller to ensure external
* (eg flush entire set of changes to each * consistency, eg by calling pv_write() if removing PVs from
* disk in turn) It is the responsibility * a VG or calling vg_write() a second time if splitting a VG
* of the caller to ensure external * into two.
* consistency, eg by calling pv_write() *
* if removing PVs from a VG or calling * vg_write() must not read or write from any PVs not included
* vg_write() a second time if splitting a * in the volume_group structure it is handed. Note: format1
* VG into two. vg_write() must not read * does read all pv's currently.
* or write from any PVs not included in
* the volume_group structure it is
* handed.
*/ */
int (*vg_write)(struct io_space *is, struct volume_group *vg); int (*vg_write)(struct format_instance *fi, struct volume_group *vg);
/* /*
* Destructor for this object. * Destructor for this object.
*/ */
void (*destroy)(struct io_space *is); void (*destroy)(struct format_instance *fi);
/*
* Current volume group prefix.
*/
char *prefix;
struct pool *mem;
struct dev_filter *filter;
void *private;
}; };
/* /*
* Utility functions * Utility functions
*/ */
struct volume_group *vg_create(struct io_space *ios, const char *name, struct physical_volume *pv_create(struct format_instance *fi,
const char *name);
struct volume_group *vg_create(struct format_instance *fi, const char *name,
uint32_t extent_size, int max_pv, int max_lv, uint32_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names); int pv_count, char **pv_names);
struct physical_volume *pv_create(struct io_space *ios, const char *name);
/*
* This needs the format instance to check the
* pv's are orphaned.
*/
int vg_extend(struct format_instance *fi,
struct volume_group *vg, int pv_count, char **pv_names);
/* /*
* Create a new LV within a given volume group. * Create a new LV within a given volume group.
* *
*/ */
struct logical_volume *lv_create(struct io_space *ios, struct logical_volume *lv_create(const char *name,
const char *name,
uint32_t status, uint32_t status,
uint32_t stripes, uint32_t stripes,
uint32_t stripe_size, uint32_t stripe_size,
@ -221,30 +238,15 @@ struct logical_volume *lv_create(struct io_space *ios,
struct volume_group *vg, struct volume_group *vg,
struct list *acceptable_pvs); struct list *acceptable_pvs);
int lv_reduce(struct io_space *ios, int lv_reduce(struct logical_volume *lv, uint32_t extents);
struct logical_volume *lv,
uint32_t extents);
int lv_extend(struct io_space *ios, struct logical_volume *lv, int lv_extend(struct logical_volume *lv,
uint32_t extents, struct list *allocatable_pvs); uint32_t extents, struct list *allocatable_pvs);
int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count,
char **pv_names);
/* FIXME: Move to other files */ /* FIXME: Move to other files */
struct io_space *create_text_format(struct dev_filter *filter,
const char *text_file);
int id_eq(struct id *op1, struct id *op2); int id_eq(struct id *op1, struct id *op2);
/* Create consistent new empty structures, populated with defaults */
struct volume_group *vg_create();
int vg_destroy(struct volume_group *vg);
/* Manipulate PV structures */ /* Manipulate PV structures */
int pv_add(struct volume_group *vg, struct physical_volume *pv); int pv_add(struct volume_group *vg, struct physical_volume *pv);
int pv_remove(struct volume_group *vg, struct physical_volume *pv); int pv_remove(struct volume_group *vg, struct physical_volume *pv);
@ -269,5 +271,9 @@ struct volume_group *find_vg_with_lv(const char *lv_name);
struct physical_volume *_find_pv(struct volume_group *vg, struct device *dev); struct physical_volume *_find_pv(struct volume_group *vg, struct device *dev);
struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name); struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name);
/*
* Remove a prefix directory if present.
*/
const char *strip_dir(const char *vg_name, const char *dir);
#endif #endif