diff --git a/include/.symlinks b/include/.symlinks index e9bba00fd..bce9c269d 100644 --- a/include/.symlinks +++ b/include/.symlinks @@ -1,12 +1,15 @@ ../lib/config/config.h -../lib/device/device.h +../lib/datastruct/hash.h +../lib/datastruct/list.h +../lib/datastruct/lvm-types.h ../lib/device/dev-cache.h +../lib/device/device.h ../lib/display/display.h +../lib/filters/filter.h +../lib/format1/format1.h ../lib/log/log.h ../lib/metadata/metadata.h +../lib/metadata/metadata.h ../lib/mm/dbg_malloc.h ../lib/mm/pool.h -../lib/datastruct/hash.h -../lib/datastruct/list.h -../lib/filters/filter.h -../lib/datastruct/lvm-types.h +../lib/mm/xlate.h diff --git a/lib/Makefile.in b/lib/Makefile.in index 8e18895fc..0dbe4305d 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -14,6 +14,7 @@ SOURCES=\ dev-mgr/dev-cache.c \ device/dev-cache.c \ device/dev-io.c \ + format1/disk-rep.c \ format1/format1.c \ log/log.c \ mm/dbg_malloc.c \ diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c index c8cbe2411..8a1b9c943 100644 --- a/lib/format1/disk-rep.c +++ b/lib/format1/disk-rep.c @@ -7,6 +7,8 @@ #include "disk-rep.h" #include "pool.h" +#include "xlate.h" +#include "log.h" #define fail do {stack; return 0;} while(0) #define xx16(v) disk->v = xlate16(disk->v) @@ -24,7 +26,7 @@ static void _xlate_pv(struct pv_disk *disk) xx32(pv_on_disk.base); xx32(pv_on_disk.size); xx32(vg_on_disk.base); xx32(vg_on_disk.size); - xx32(pv_uuid_on_disk.base); xx32(pv_uuid_on_disk.size); + xx32(pv_uuidlist_on_disk.base); xx32(pv_uuidlist_on_disk.size); xx32(lv_on_disk.base); xx32(lv_on_disk.size); xx32(pe_on_disk.base); xx32(pe_on_disk.size); @@ -94,16 +96,13 @@ static void _xlate_extents(struct pe_disk *extents, int count) } } -static int _read_pv(struct data_list *data) +static int _read_pv(struct disk_list *data) { struct pv_disk *pvd = &data->pv; if (dev_read(data->dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) fail; _xlate_pv(pvd); - memset(pvd->pv_name, 0, sizeof (pvd->pv_name)); - strncpy(pvd->pv_name, data->dev->name, sizeof(pvd->pv_name) - 1); - pvd->pv_dev = pvd->dev; return 1; } @@ -148,7 +147,7 @@ static int _read_uuids(struct disk_list *data) memcpy(ul->uuid, buffer, NAME_LEN); ul->uuid[NAME_LEN] = '\0'; - list_add(&ui->list, &data->uuids); + list_add(&ul->list, &data->uuids); pos += NAME_LEN; num_read++; @@ -161,10 +160,11 @@ static int _read_lvs(struct disk_list *data) { int i; unsigned long pos; + struct lvd_list *ll; for(i = 0; i < data->vg.lv_cur; i++) { pos = data->pv.lv_on_disk.base + (i * sizeof(struct lv_disk)); - struct lv_list *ll = pool_alloc(sizeof(*ll)); + ll = pool_alloc(data->mem, sizeof(*ll)); if (!ll) fail; @@ -180,7 +180,7 @@ static int _read_lvs(struct disk_list *data) static int _read_extents(struct disk_list *data) { - size_t len = sizeof(struct pe_disk) * data->pv->pe_total; + size_t len = sizeof(struct pe_disk) * data->pv.pe_total; struct pe_disk *extents = pool_alloc(data->mem, len); unsigned long pos = data->pv.pe_on_disk.base; @@ -203,7 +203,7 @@ struct disk_list *read_pv(struct device *dev, struct pool *mem, data->dev = dev; data->mem = mem; - if (!_read_pv(&data->pv)) { + if (!_read_pv(data)) { log_err("failed to read pv data from %s\n", dev->name); goto bad; } @@ -215,11 +215,12 @@ struct disk_list *read_pv(struct device *dev, struct pool *mem, } if (vg_name && strcmp(vg_name, data->pv.vg_name)) { - log_info("%s is not a member of the vg '%s'\n", vg_name); + log_info("%s is not a member of the vg '%s'\n", + dev->name, vg_name); goto bad; } - if (!_read_vg(data->pv.pv_vg_on_disk.base, &data->vg)) { + if (!_read_vg(data)) { log_err("failed to read vg data from pv (%s)\n", dev->name); goto bad; } @@ -242,7 +243,7 @@ struct disk_list *read_pv(struct device *dev, struct pool *mem, return data; bad: - pool_free(data); + pool_free(data->mem, data); return NULL; } @@ -252,20 +253,19 @@ struct disk_list *read_pv(struct device *dev, struct pool *mem, * allocated form the pool so we can free off all * the memory if something goes wrong. */ -int read_pvs_in_vg(struct v1 *v, const char *vg_name, +int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, struct pool *mem, struct list_head *head) { - struct dev_cache_iter *iter = dev_iter_create(v->filter); + struct dev_iter *iter = dev_iter_create(filter); struct device *dev; struct disk_list *data = NULL; for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) { - - if ((data = read_all_pv(dev, mem, vg_name))) + if ((data = read_pv(dev, mem, vg_name))) list_add(&data->list, head); - else - pool_free(mem, pvd); } + dev_iter_destroy(iter); + return 1; } @@ -286,7 +286,6 @@ static int _write_vg(struct disk_list *data) static int _write_uuids(struct disk_list *data) { - int num_read = 0; struct uuid_list *ul; struct list_head *tmp; ulong pos = data->pv.pv_uuidlist_on_disk.base; @@ -300,8 +299,8 @@ static int _write_uuids(struct disk_list *data) } ul = list_entry(tmp, struct uuid_list, list); - if (dev_write(data->dev, pos, - sizeof(NAME_LEN), NAME_LEN) != NAME_LEN) + if (dev_write(data->dev, pos, + sizeof(NAME_LEN), ul->uuid) != NAME_LEN) fail; pos += NAME_LEN; @@ -324,9 +323,11 @@ static int _write_lv(struct device *dev, ulong pos, struct lv_disk *disk) static int _write_lvs(struct disk_list *data) { struct list_head *tmp; + unsigned long pos; list_for_each(tmp, &data->lvs) { - struct lv_list *ll = list_entry(tmp, struct lv_list, list); + struct lvd_list *ll = list_entry(tmp, struct lvd_list, list); + pos = data->pv.lv_on_disk.base; if (!_write_lv(data->dev, pos, &ll->lv)) fail; @@ -341,7 +342,6 @@ static int _write_extents(struct disk_list *data) { size_t len = sizeof(struct pe_disk) * data->pv.pe_total; struct pe_disk *extents = data->extents; - unsigned long pos = data->pv.pe_on_disk.base; _xlate_extents(extents, data->pv.pe_total); if (dev_write(data->dev, 0, len, extents) != len) diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h index 3284c3590..28f55d88a 100644 --- a/lib/format1/disk-rep.h +++ b/lib/format1/disk-rep.h @@ -2,12 +2,21 @@ * Copyright (C) 2001 Sistina Software (UK) Limited. * * This file is released under the GPL. - * */ #ifndef DISK_REP_FORMAT1_H #define DISK_REP_FORMAT1_H +#include "lvm-types.h" +#include "metadata.h" +#include "pool.h" + +#define MAX_PV 256 +#define MAX_LV 256 +#define MAX_VG 99 + +#define UNMAPPED_EXTENT ((uint16_t) -1) + struct data_area { uint32_t base; uint32_t size; @@ -63,8 +72,8 @@ struct lv_disk { }; struct vg_disk { - uint8_t vg_uuid[UUID_LEN]; /* volume group UUID */ - uint8_t vg_name_dummy[NAME_LEN-UUID_LEN]; /* rest of v1 VG name */ + uint8_t vg_uuid[ID_LEN]; /* volume group UUID */ + uint8_t vg_name_dummy[NAME_LEN - ID_LEN]; /* rest of v1 VG name */ uint32_t vg_number; /* volume group number */ uint32_t vg_access; /* read/write */ uint32_t vg_status; /* active or not */ @@ -93,12 +102,13 @@ struct uuid_list { char uuid[NAME_LEN + 1]; }; -struct lv_list { +struct lvd_list { struct list_head list; struct lv_disk lv; -} +}; struct disk_list { + struct pool *mem; struct device *dev; struct list_head list; diff --git a/lib/format1/format1.c b/lib/format1/format1.c index c7351bb29..477b5cdca 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -9,13 +9,9 @@ #include "pool.h" #include "hash.h" #include "list.h" +#include "log.h" -struct v1 { - struct pool *mem; - struct dev_filter *filter; -}; - static int _import_vg(struct volume_group *vg, struct list_head *pvs) { struct list_head *tmp; @@ -31,8 +27,10 @@ static int _import_vg(struct volume_group *vg, struct list_head *pvs) memcpy(vg->id, &first->vg_uuid, ID_LEN); vg->name = NULL; - vg->status = first->vg_status; - vg->access = first->vg_access; + + // FIXME: encode flags + //vg->status = first->vg_status; + //vg->access = first->vg_access; vg->extent_size = first->pe_size; vg->extent_count = first->pe_total; vg->free_count = first->pe_total - first->pe_allocated; @@ -68,23 +66,25 @@ static int _import_pvs(struct pool *mem, struct volume_group *vg, pv = &pvl->pv; memcpy(&pv->id, &dl->pv.pv_uuid, ID_LEN); - pv->dev = ??; - pv->vg_name = pool_strdup(dl->pv.vg_name); + // FIXME: finish + //pv->dev = ??; + pv->vg_name = pool_strdup(mem, dl->pv.vg_name); if (!pv->vg_name) { stack; return 0; } - pv->exported = ??; + // FIXME: finish + //pv->exported = ??; pv->status = dl->pv.pv_status; pv->size = dl->pv.pv_size; pv->pe_size = dl->pv.pv_size; - pe_start = dl->pv.pe_start; - pe_count = dl->pv.pe_count; - pe_allocated = dl->pv.pe_allocated; + pv->pe_start = dl->pv.pe_start; + pv->pe_count = dl->pv.pe_total; + pv->pe_allocated = dl->pv.pe_allocated; - list_add(&pvl->list, vg->pvs); + list_add(&pvl->list, &vg->pvs); vg->pv_count++; } @@ -96,16 +96,35 @@ static struct logical_volume *_find_lv(struct volume_group *vg, { struct list_head *tmp; struct logical_volume *lv; + struct lv_list *ll; list_for_each(tmp, &vg->lvs) { - lv = list_entry(tmp, struct logical_volume, list); + ll = list_entry(tmp, struct lv_list, list); + lv = &ll->lv; if (!strcmp(name, lv->name)) return lv; } return NULL; } -static struct logical_volume *_add_lv(struct volume_group *vg, +static struct physical_volume *_find_pv(struct volume_group *vg, + struct device *dev) +{ + struct list_head *tmp; + struct physical_volume *pv; + struct pv_list *pl; + + list_for_each(tmp, &vg->lvs) { + pl = list_entry(tmp, struct pv_list, list); + pv = &pl->pv; + if (dev == pv->dev) + return pv; + } + return NULL; +} + +static struct logical_volume *_add_lv(struct pool *mem, + struct volume_group *vg, struct lv_disk *lvd) { struct logical_volume *lv = pool_alloc(mem, sizeof(*lv)); @@ -116,16 +135,17 @@ static struct logical_volume *_add_lv(struct volume_group *vg, } memset(lv->id, 0, sizeof(lv->id)); - if (!(lv->name = pool_dupstr(lvd->lv_name))) { + if (!(lv->name = pool_strdup(mem, lvd->lv_name))) { stack; return 0; } - lv->access = lvd->lv_access; - lv->status = lvd->lv_status; + // FIXME: finish + //lv->access = lvd->lv_access; + //lv->status = lvd->lv_status; lv->open = lvd->lv_open; lv->size = lvd->lv_size; - lv->le_count = lvd->lv_allocated_lv; + lv->le_count = lvd->lv_allocated_le; lv->map = pool_alloc(mem, sizeof(struct pe_specifier) * lv->le_count); if (!lv->map) { @@ -133,26 +153,25 @@ static struct logical_volume *_add_lv(struct volume_group *vg, return 0; } - return 1; + return lv; } static int _import_lvs(struct pool *mem, struct volume_group *vg, struct list_head *pvs) { - struct list_head *tmp, tmp2; + struct list_head *tmp, *tmp2; struct disk_list *dl; - struct lv_list *ll; + struct lvd_list *ll; struct lv_disk *lvd; - struct logical_volume *lv; - int i; list_for_each(tmp, pvs) { dl = list_entry(tmp, struct disk_list, list); list_for_each(tmp2, &dl->lvs) { - ll = list_entry(tmp2, struct lv_list, list); + ll = list_entry(tmp2, struct lvd_list, list); lvd = &ll->lv; - if (!_find_lv(vg, lvd->lvname) && !_add_lv(vg, lvd)) { + if (!_find_lv(vg, lvd->lv_name) && + !_add_lv(mem, vg, lvd)) { stack; return 0; } @@ -162,18 +181,17 @@ static int _import_lvs(struct pool *mem, struct volume_group *vg, return 1; } -static int _fill_lv_array(struct logical_volume *lvs, +static int _fill_lv_array(struct logical_volume **lvs, struct volume_group *vg, struct disk_list *dl) { struct list_head *tmp; - struct pv_disk *pvd = &dl->pv; struct logical_volume *lv; int i = 0; list_for_each(tmp, &dl->lvs) { - struct lv_list *ll = list_entry(tmp, struct lv_disk, list); + struct lvd_list *ll = list_entry(tmp, struct lvd_list, list); - if (!(lv = _find_lv(vg, ll->lv.name))) { + if (!(lv = _find_lv(vg, ll->lv.lv_name))) { stack; return 0; } @@ -190,7 +208,7 @@ static int _import_extents(struct pool *mem, struct volume_group *vg, { struct list_head *tmp; struct disk_list *dl; - struct logical_volume *lv, lvs[MAX_LV]; + struct logical_volume *lv, *lvs[MAX_LV]; struct physical_volume *pv; struct pe_disk *e; int i; @@ -198,7 +216,7 @@ static int _import_extents(struct pool *mem, struct volume_group *vg, list_for_each(tmp, pvs) { dl = list_entry(tmp, struct disk_list, list); - pv = _find_pv(vg, dl->pv.pv_name); + pv = _find_pv(vg, dl->dev); e = dl->extents; /* build an array of lv's for this pv */ @@ -217,7 +235,7 @@ static int _import_extents(struct pool *mem, struct volume_group *vg, log_err("invalid lv in extent map\n"); return 0; - else { + } else { lv = lvs[lv_num]; le = e[i].le_num; @@ -230,7 +248,7 @@ static int _import_extents(struct pool *mem, struct volume_group *vg, return 1; } -static struct volume_group _build_vg(struct pool *mem, struct list_head *pvs) +static struct volume_group *_build_vg(struct pool *mem, struct list_head *pvs) { struct volume_group *vg = pool_alloc(mem, sizeof(*vg)); @@ -250,6 +268,9 @@ static struct volume_group _build_vg(struct pool *mem, struct list_head *pvs) if (!_import_lvs(mem, vg, pvs)) goto bad; + if (!_import_extents(mem, vg, pvs)) + goto bad; + return vg; bad: @@ -258,7 +279,7 @@ static struct volume_group _build_vg(struct pool *mem, struct list_head *pvs) return NULL; } -static struct volume_group _vg_read(struct io_space *is, const char *vg_name) +static struct volume_group *_vg_read(struct io_space *is, const char *vg_name) { struct pool *mem = pool_create(1024 * 10); struct list_head pvs; @@ -282,8 +303,9 @@ static struct volume_group _vg_read(struct io_space *is, const char *vg_name) return vg; } -static struct disk_list _flatten_pv(struct pool *mem, struct volume_group *vg, - struct physical_volume *pv) +#if 0 +static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg, + struct physical_volume *pv) { } @@ -323,10 +345,11 @@ static int _vg_write(struct io_space *is, struct volume_group *vg) pool_destroy(mem); return r; } +#endif -struct io_space *create_lvm1_format(struct device_manager *mgr) +struct io_space *create_lvm1_format(void) { - + return NULL; } diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 096073107..91f9212f4 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -98,11 +98,11 @@ struct volume_group { /* physical volumes */ uint32_t pv_count; - struct physical_volume **pv; + struct list_head pvs; /* logical volumes */ uint32_t lv_count; - struct logical_volume **lv; + struct list_head lvs; }; struct name_list { @@ -115,6 +115,11 @@ struct pv_list { struct physical_volume pv; }; +struct lv_list { + struct list_head list; + struct logical_volume lv; +}; + /* ownership of returned objects passes */ struct io_space { /* Returns list of names of all vgs - vg @@ -158,6 +163,7 @@ struct io_space { /* Default to "/dev/" */ char *prefix; + struct pool *mem; struct dev_filter *filter; void *private; }; @@ -167,12 +173,6 @@ struct io_space *create_text_format(struct dev_filter *filter, const char *text_file); struct io_space *create_lvm_v1_format(struct dev_filter *filter); -inline int write_backup(struct io_space *orig, struct io_space *text) -{ - -} - - int id_eq(struct id *op1, struct id *op2); /* Create consistent new empty structures, populated with defaults */ diff --git a/lib/mm/xlate.h b/lib/mm/xlate.h new file mode 100644 index 000000000..6d4dc4bb3 --- /dev/null +++ b/lib/mm/xlate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + * + */ + +#ifndef _LVM_XLATE_H +#define _LVM_XLATE_H + +/* FIXME: finish these as inlines */ + +uint16_t shuffle16(uint16_t n); +uint32_t shuffle32(uint32_t n); +uint64_t shuffle64(uint64_t n); + +/* xlate functions move data between core and disk */ +#if __BYTE_ORDER == __BIG_ENDIAN +# define xlate16(x) shuffle16(x) +# define xlate32(x) shuffle32(x) +# define xlate64(x) shuffle64(x) + +#elif __BYTE_ORDER == __LITTLE_ENDIAN +# define xlate16(x) (x) +# define xlate32(x) (x) +# define xlate64(x) (x) + +#else +# error "__BYTE_ORDER must be defined as __LITTLE_ENDIAN or __BIG_ENDIAN" +#endif + +#endif