diff options
author | Alasdair Kergon <agk@redhat.com> | 2002-04-24 18:20:51 +0000 |
---|---|---|
committer | Alasdair Kergon <agk@redhat.com> | 2002-04-24 18:20:51 +0000 |
commit | 25b733809adcd2f6a8f288c100085068094dcc8a (patch) | |
tree | de7aea488a1c717d589134b324c664ba4aa505a7 /lib/format1 | |
parent | f06bdc437d7eab9569f80ba40cbfca55ffa27104 (diff) | |
download | lvm2-25b733809adcd2f6a8f288c100085068094dcc8a.tar.gz lvm2-25b733809adcd2f6a8f288c100085068094dcc8a.tar.xz lvm2-25b733809adcd2f6a8f288c100085068094dcc8a.zip |
Merge with text format branch.
Lots of changes/very little testing so far => there'll be bugs!
Use 'vgcreate -M text' to create a volume group with its metadata stored
in text files. Text format metadata changes should be reasonably atomic,
with a (basic) automatic recovery mechanism if the system crashes while a
change is in progress.
Add a metadata section to lvm.conf to specify multiple directories if
you want (recommended) to keep multiple copies of the metadata (eg on
different filesystems).
e.g. metadata {
dirs = ["/etc/lvm/metadata1","/usr/local/lvm/metadata2"]
}
Plenty of refinements still in the pipeline.
Diffstat (limited to 'lib/format1')
-rw-r--r-- | lib/format1/disk-rep.c | 109 | ||||
-rw-r--r-- | lib/format1/disk-rep.h | 21 | ||||
-rw-r--r-- | lib/format1/format1.c | 228 | ||||
-rw-r--r-- | lib/format1/format1.h | 2 | ||||
-rw-r--r-- | lib/format1/import-export.c | 71 | ||||
-rw-r--r-- | lib/format1/import-extents.c | 5 | ||||
-rw-r--r-- | lib/format1/layout.c | 25 | ||||
-rw-r--r-- | lib/format1/lvm1_label.c | 42 | ||||
-rw-r--r-- | lib/format1/vg_number.c | 11 |
9 files changed, 266 insertions, 248 deletions
diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c index 8cb6a925..0ddea822 100644 --- a/lib/format1/disk-rep.c +++ b/lib/format1/disk-rep.c @@ -135,7 +135,7 @@ static int _munge_formats(struct pv_disk *pvd) int read_pvd(struct device *dev, struct pv_disk *pvd) { if (dev_read(dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) { - log_very_verbose("Failed to read PV data from %s", + log_very_verbose("Failed to read PV data from %s", dev_name(dev)); return 0; } @@ -265,35 +265,35 @@ static void _munge_exported_vg(struct disk_list *data) int l, s; /* Return if PV not in a VG or VG not exported */ - if ((!*data->pvd.vg_name) || - !(data->vgd.vg_status & VG_EXPORTED)) + if ((!*data->pvd.vg_name) || !(data->vgd.vg_status & VG_EXPORTED)) return; l = strlen(data->pvd.vg_name); s = sizeof(EXPORTED_TAG); if (!strncmp(data->pvd.vg_name + l - s + 1, EXPORTED_TAG, s)) - data->pvd.vg_name[l - s + 1] = '\0'; + data->pvd.vg_name[l - s + 1] = '\0'; data->pvd.pv_status |= VG_EXPORTED; } -static struct disk_list *__read_disk(struct device *dev, struct pool *mem, +static struct disk_list *__read_disk(struct format_type *fmt, + struct device *dev, struct pool *mem, const char *vg_name) { - struct disk_list *data = pool_alloc(mem, sizeof(*data)); + struct disk_list *dl = pool_alloc(mem, sizeof(*dl)); const char *name = dev_name(dev); - if (!data) { + if (!dl) { stack; return NULL; } - data->dev = dev; - data->mem = mem; - list_init(&data->uuids); - list_init(&data->lvds); + dl->dev = dev; + dl->mem = mem; + list_init(&dl->uuids); + list_init(&dl->lvds); - if (!read_pvd(dev, &data->pvd)) { + if (!read_pvd(dev, &dl->pvd)) { stack; goto bad; } @@ -301,60 +301,60 @@ static struct disk_list *__read_disk(struct device *dev, struct pool *mem, /* * is it an orphan ? */ - if (!*data->pvd.vg_name) { - log_very_verbose("%s is not a member of any VG", name); + if (!*dl->pvd.vg_name) { + log_very_verbose("%s is not a member of any format1 VG", name); /* Update VG cache */ - vgcache_add(data->pvd.vg_name, NULL, dev); + vgcache_add(dl->pvd.vg_name, NULL, dev, fmt); - return (vg_name) ? NULL : data; + return (vg_name) ? NULL : dl; } - if (!_read_vgd(data)) { + if (!_read_vgd(dl)) { log_error("Failed to read VG data from PV (%s)", name); goto bad; } /* If VG is exported, set VG name back to the real name */ - _munge_exported_vg(data); + _munge_exported_vg(dl); /* Update VG cache with what we found */ - vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, dev); + vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); - if (vg_name && strcmp(vg_name, data->pvd.vg_name)) { + if (vg_name && strcmp(vg_name, dl->pvd.vg_name)) { log_very_verbose("%s is not a member of the VG %s", name, vg_name); goto bad; } - if (!_read_uuids(data)) { + if (!_read_uuids(dl)) { log_error("Failed to read PV uuid list from %s", name); goto bad; } - if (!_read_lvs(data)) { + if (!_read_lvs(dl)) { log_error("Failed to read LV's from %s", name); goto bad; } - if (!_read_extents(data)) { + if (!_read_extents(dl)) { log_error("Failed to read extents from %s", name); goto bad; } - log_very_verbose("Found %s in %sVG %s", name, - (data->vgd.vg_status & VG_EXPORTED) ? "exported " : "", - data->pvd.vg_name); + log_very_verbose("Found %s in %sVG %s", name, + (dl->vgd.vg_status & VG_EXPORTED) ? "exported " : "", + dl->pvd.vg_name); - return data; + return dl; bad: - pool_free(data->mem, data); + pool_free(dl->mem, dl); return NULL; } -struct disk_list *read_disk(struct device *dev, struct pool *mem, - const char *vg_name) +struct disk_list *read_disk(struct format_type *fmt, struct device *dev, + struct pool *mem, const char *vg_name) { struct disk_list *r; @@ -363,7 +363,7 @@ struct disk_list *read_disk(struct device *dev, struct pool *mem, return NULL; } - r = __read_disk(dev, mem, vg_name); + r = __read_disk(fmt, dev, mem, vg_name); if (!dev_close(dev)) stack; @@ -378,16 +378,16 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data) list_iterate(pvdh, head) { pvd = &list_item(pvdh, struct disk_list)->pvd; - if (!strncmp(data->pvd.pv_uuid, pvd->pv_uuid, + if (!strncmp(data->pvd.pv_uuid, pvd->pv_uuid, sizeof(pvd->pv_uuid))) { if (MAJOR(data->dev->dev) != md_major()) { log_very_verbose("Ignoring duplicate PV %s on " - "%s", pvd->pv_uuid, + "%s", pvd->pv_uuid, dev_name(data->dev)); return; } - log_very_verbose("Duplicate PV %s - using md %s", - pvd->pv_uuid, dev_name(data->dev)); + log_very_verbose("Duplicate PV %s - using md %s", + pvd->pv_uuid, dev_name(data->dev)); list_del(pvdh); break; } @@ -400,8 +400,9 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data) * We keep track of the first object allocated form the pool * so we can free off all the memory if something goes wrong. */ -int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, - struct pool *mem, struct list *head) +int read_pvs_in_vg(struct format_type *fmt, const char *vg_name, + struct dev_filter *filter, struct pool *mem, + struct list *head) { struct dev_iter *iter; struct device *dev; @@ -413,7 +414,7 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, if ((pvdh = vgcache_find(vg_name))) { list_iterate(pvdh2, pvdh) { dev = list_item(pvdh2, struct pvdev_list)->dev; - if (!(data = read_disk(dev, mem, vg_name))) + if (!(data = read_disk(fmt, dev, mem, vg_name))) break; _add_pv_to_list(head, data); } @@ -421,8 +422,7 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, /* Did we find the whole VG? */ if (!vg_name || !*vg_name || (data && *data->pvd.vg_name && - list_size(head) == data->vgd.pv_cur)) - return 1; + list_size(head) == data->vgd.pv_cur)) return 1; /* Something changed. Remove the hints. */ list_init(head); @@ -436,7 +436,7 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, /* Otherwise do a complete scan */ for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) { - if ((data = read_disk(dev, mem, vg_name))) { + if ((data = read_disk(fmt, dev, mem, vg_name))) { _add_pv_to_list(head, data); } } @@ -543,16 +543,16 @@ static int _write_pvd(struct disk_list *data) ulong pos = data->pvd.pv_on_disk.base; ulong size = data->pvd.pv_on_disk.size; - if(size < sizeof(struct pv_disk)) { + if (size < sizeof(struct pv_disk)) { log_error("Invalid PV structure size."); return 0; } - /* Make sure that the gap between the PV structure and + /* Make sure that the gap between the PV structure and the next one is zeroed in order to make non LVM tools happy (idea from AED) */ buf = dbg_malloc(size); - if(!buf) { + if (!buf) { log_err("Couldn't allocate temporary PV buffer."); return 0; } @@ -560,7 +560,7 @@ static int _write_pvd(struct disk_list *data) memset(buf, 0, size); memcpy(buf, &data->pvd, sizeof(struct pv_disk)); - _xlate_pvd((struct pv_disk *)buf); + _xlate_pvd((struct pv_disk *) buf); if (dev_write(data->dev, pos, size, buf) != size) { dbg_free(buf); fail; @@ -573,7 +573,7 @@ static int _write_pvd(struct disk_list *data) /* * assumes the device has been opened. */ -static int __write_all_pvd(struct disk_list *data) +static int __write_all_pvd(struct format_type *fmt, struct disk_list *data) { const char *pv_name = dev_name(data->dev); @@ -582,18 +582,19 @@ static int __write_all_pvd(struct disk_list *data) return 0; } - vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev); + vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, fmt); /* * Stop here for orphan pv's. */ if (data->pvd.vg_name[0] == '\0') { if (!test_mode()) - vgcache_add(data->pvd.vg_name, NULL, data->dev); + vgcache_add(data->pvd.vg_name, NULL, data->dev, fmt); return 1; } if (!test_mode()) - vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev); + vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, + fmt); if (!_write_vgd(data)) { log_error("Failed to write VG data to %s", pv_name); @@ -621,7 +622,7 @@ static int __write_all_pvd(struct disk_list *data) /* * opens the device and hands to the above fn. */ -static int _write_all_pvd(struct disk_list *data) +static int _write_all_pvd(struct format_type *fmt, struct disk_list *data) { int r; @@ -630,7 +631,7 @@ static int _write_all_pvd(struct disk_list *data) return 0; } - r = __write_all_pvd(data); + r = __write_all_pvd(fmt, data); if (!dev_close(data->dev)) stack; @@ -643,17 +644,17 @@ static int _write_all_pvd(struct disk_list *data) * little sanity checking, so make sure correct * data is passed to here. */ -int write_disks(struct list *pvs) +int write_disks(struct format_type *fmt, struct list *pvs) { struct list *pvh; struct disk_list *dl; list_iterate(pvh, pvs) { dl = list_item(pvh, struct disk_list); - if (!(_write_all_pvd(dl))) + if (!(_write_all_pvd(fmt, dl))) fail; - log_very_verbose("Successfully wrote data to %s", + log_very_verbose("Successfully wrote data to %s", dev_name(dl->dev)); } diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h index 66d68846..dbd8ac58 100644 --- a/lib/format1/disk-rep.h +++ b/lib/format1/disk-rep.h @@ -168,7 +168,6 @@ struct disk_list { * Layout constants. */ #define METADATA_ALIGN 4096UL -#define PE_ALIGN (65536UL / SECTOR_SIZE) #define METADATA_BASE 0UL #define PV_SIZE 1024UL @@ -188,13 +187,14 @@ int calculate_extent_count(struct physical_volume *pv); */ int read_pvd(struct device *dev, struct pv_disk *pvd); -struct disk_list *read_disk(struct device *dev, struct pool *mem, - const char *vg_name); +struct disk_list *read_disk(struct format_type *fmt, struct device *dev, + struct pool *mem, const char *vg_name); -int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, +int read_pvs_in_vg(struct format_type *fmt, const char *vg_name, + struct dev_filter *filter, struct pool *mem, struct list *results); -int write_disks(struct list *pvds); +int write_disks(struct format_type *fmt, struct list *pvds); /* @@ -223,7 +223,8 @@ int export_extents(struct disk_list *dl, int lv_num, struct logical_volume *lv, struct physical_volume *pv); -int import_pvs(struct pool *mem, struct volume_group *vg, +int import_pvs(struct format_instance *fid, struct pool *mem, + struct volume_group *vg, struct list *pvds, struct list *results, int *count); int import_lvs(struct pool *mem, struct volume_group *vg, @@ -241,10 +242,10 @@ void export_numbers(struct list *pvds, struct volume_group *vg); void export_pv_act(struct list *pvds); /* blech */ -int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg, - int *result); -int export_vg_number(struct list *pvds, const char *vg_name, - struct dev_filter *filter); +int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter, + const char *candidate_vg, int *result); +int export_vg_number(struct format_instance *fid, struct list *pvds, + const char *vg_name, struct dev_filter *filter); #endif diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 19daae03..9d48cf0a 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -50,7 +50,6 @@ static int _check_vgs(struct list *pvs, int *partial) } } - /* Remove any PVs with VG structs that differ from the first */ list_iterate_safe(pvh, t, pvs) { dl = list_item(pvh, struct disk_list); @@ -83,10 +82,10 @@ static int _check_vgs(struct list *pvs, int *partial) return 1; } -static struct volume_group *_build_vg(struct cmd_context *cmd, +static struct volume_group *_build_vg(struct format_instance *fid, struct list *pvs) { - struct pool *mem = cmd->mem; + struct pool *mem = fid->fmt->cmd->mem; struct volume_group *vg = pool_alloc(mem, sizeof(*vg)); struct disk_list *dl; int partial; @@ -99,7 +98,9 @@ static struct volume_group *_build_vg(struct cmd_context *cmd, memset(vg, 0, sizeof(*vg)); - vg->cmd = cmd; + vg->cmd = fid->fmt->cmd; + vg->fid = fid; + vg->seqno = 0; list_init(&vg->pvs); list_init(&vg->lvs); list_init(&vg->snapshots); @@ -112,7 +113,7 @@ static struct volume_group *_build_vg(struct cmd_context *cmd, if (!import_vg(mem, vg, dl, partial)) goto bad; - if (!import_pvs(mem, vg, pvs, &vg->pvs, &vg->pv_count)) + if (!import_pvs(fid, mem, vg, pvs, &vg->pvs, &vg->pv_count)) goto bad; if (!import_lvs(mem, vg, pvs)) @@ -126,14 +127,14 @@ static struct volume_group *_build_vg(struct cmd_context *cmd, return vg; - bad: + bad: stack; pool_free(mem, vg); return NULL; } -static struct volume_group *_vg_read(struct format_instance *fi, - const char *vg_name) +static struct volume_group *_vg_read(struct format_instance *fid, + const char *vg_name, void *mda) { struct pool *mem = pool_create(1024 * 10); struct list pvs; @@ -145,20 +146,21 @@ static struct volume_group *_vg_read(struct format_instance *fi, return NULL; } - /* Strip dev_dir if present */ - vg_name = strip_dir(vg_name, fi->cmd->dev_dir); + /* Strip dev_dir if present */ + vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir); - if (!read_pvs_in_vg(vg_name, fi->cmd->filter, mem, &pvs)) { + if (!read_pvs_in_vg + (fid->fmt, vg_name, fid->fmt->cmd->filter, mem, &pvs)) { stack; goto bad; } - if (!(vg = _build_vg(fi->cmd, &pvs))) { + if (!(vg = _build_vg(fid, &pvs))) { stack; goto bad; } - bad: + bad: pool_destroy(mem); return vg; } @@ -193,7 +195,8 @@ static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg, return dl; } -static int _flatten_vg(struct pool *mem, struct volume_group *vg, +static int _flatten_vg(struct format_instance *fid, struct pool *mem, + struct volume_group *vg, struct list *pvds, const char *dev_dir, struct dev_filter *filter) { @@ -215,7 +218,7 @@ static int _flatten_vg(struct pool *mem, struct volume_group *vg, export_numbers(pvds, vg); export_pv_act(pvds); - if (!export_vg_number(pvds, vg->name, filter)) { + if (!export_vg_number(fid, pvds, vg->name, filter)) { stack; return 0; } @@ -223,7 +226,8 @@ static int _flatten_vg(struct pool *mem, struct volume_group *vg, return 1; } -static int _vg_write(struct format_instance *fi, struct volume_group *vg) +static int _vg_write(struct format_instance *fid, struct volume_group *vg, + void *mdl) { struct pool *mem = pool_create(1024 * 10); struct list pvds; @@ -242,57 +246,56 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg) list_init(&pvds); - r = (_flatten_vg(mem, vg, &pvds, fi->cmd->dev_dir, fi->cmd->filter) && - write_disks(&pvds)); + r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir, + fid->fmt->cmd->filter) && + write_disks(fid->fmt, &pvds)); pool_destroy(mem); return r; } -static struct physical_volume *_pv_read(struct format_instance *fi, - const char *name) +int _pv_read(struct format_type *fmt, const char *name, + struct physical_volume *pv) { struct pool *mem = pool_create(1024); - struct physical_volume *pv = NULL; struct disk_list *dl; struct device *dev; + int r = 0; - log_very_verbose("Reading physical volume data %s from disk", name); + log_very_verbose("Reading physical volume data %s from disk", name); if (!mem) { stack; - return NULL; + return 0; } - if (!(dev = dev_cache_get(name, fi->cmd->filter))) { + if (!(dev = dev_cache_get(name, fmt->cmd->filter))) { stack; goto out; } - if (!(dl = read_disk(dev, mem, NULL))) { + if (!(dl = read_disk(fmt, dev, mem, NULL))) { stack; goto out; } - if (!(pv = pool_alloc(fi->cmd->mem, sizeof(*pv)))) { + if (!import_pv(fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd)) { stack; goto out; } - if (!import_pv(fi->cmd->mem, dl->dev, NULL, pv, &dl->pvd)) { - stack; - pool_free(fi->cmd->mem, pv); - pv = NULL; - } + pv->fid = fmt->ops->create_instance(fmt, NULL, NULL); + + r = 1; - out: + out: pool_destroy(mem); - return pv; + return r; } -static struct list *_get_pvs(struct format_instance *fi) +static struct list *_get_pvs(struct format_type *fmt, struct list *results) { struct pool *mem = pool_create(1024 * 10); - struct list pvs, *results; + struct list pvs; uint32_t count; if (!mem) { @@ -300,21 +303,14 @@ static struct list *_get_pvs(struct format_instance *fi) return NULL; } - if (!(results = pool_alloc(fi->cmd->mem, sizeof(*results)))) { - stack; - pool_destroy(mem); - return NULL; - } - list_init(&pvs); - list_init(results); - if (!read_pvs_in_vg(NULL, fi->cmd->filter, mem, &pvs)) { + if (!read_pvs_in_vg(fmt, NULL, fmt->cmd->filter, mem, &pvs)) { stack; goto bad; } - if (!import_pvs(fi->cmd->mem, NULL, &pvs, results, &count)) { + if (!import_pvs(NULL, fmt->cmd->mem, NULL, &pvs, results, &count)) { stack; goto bad; } @@ -322,8 +318,7 @@ static struct list *_get_pvs(struct format_instance *fi) pool_destroy(mem); return results; - bad: - pool_free(fi->cmd->mem, results); + bad: pool_destroy(mem); return NULL; } @@ -342,56 +337,55 @@ static int _find_vg_name(struct list *names, const char *vg) return 0; } -static struct list *_get_vgs(struct format_instance *fi) +static struct list *_get_vgs(struct format_type *fmt, struct list *names) { struct list *pvh; - struct list *pvs, *names = pool_alloc(fi->cmd->mem, sizeof(*names)); + struct list *pvs; struct name_list *nl; - if (!names) { - stack; - return NULL; + if (!(pvs = pool_alloc(fmt->cmd->mem, sizeof(*pvs)))) { + log_error("PV list allocation failed"); + goto err; } - list_init(names); + list_init(pvs); - if (!(pvs = _get_pvs(fi))) { + if (!_get_pvs(fmt, pvs)) { stack; - goto bad; + goto err; } list_iterate(pvh, pvs) { struct pv_list *pvl = list_item(pvh, struct pv_list); if (!(*pvl->pv->vg_name) || - _find_vg_name(names, pvl->pv->vg_name)) + _find_vg_name(names, pvl->pv->vg_name)) continue; - if (!(nl = pool_alloc(fi->cmd->mem, sizeof(*nl)))) { + if (!(nl = pool_alloc(fmt->cmd->mem, sizeof(*nl)))) { stack; - goto bad; + goto err; } - if (!(nl->name = pool_strdup(fi->cmd->mem, - pvl->pv->vg_name))) { + if (!(nl->name = pool_strdup(fmt->cmd->mem, pvl->pv->vg_name))) { stack; - goto bad; + goto err; } list_add(names, &nl->list); } if (list_empty(names)) - goto bad; + goto err; return names; - bad: - pool_free(fi->cmd->mem, names); + err: + pool_free(fmt->cmd->mem, pvs); return NULL; } -static int _pv_setup(struct format_instance *fi, struct physical_volume *pv, +static int _pv_setup(struct format_instance *fid, struct physical_volume *pv, struct volume_group *vg) { /* setup operations for the PV structure */ @@ -404,7 +398,7 @@ static int _pv_setup(struct format_instance *fi, struct physical_volume *pv, } /* Nothing more to do if pe_size isn't known */ - if (!vg) + if (!vg) return 1; /* @@ -438,11 +432,7 @@ static int _find_free_lvnum(struct logical_volume *lv) return i; } -/* - * Validate/populate LV structure for format1. - * Supplied LV structure can be for a new LV or for an already-existing one. - */ -static int _lv_setup(struct format_instance *fi, struct logical_volume *lv) +static int _lv_setup(struct format_instance *fid, struct logical_volume *lv) { uint64_t max_size = UINT_MAX; @@ -455,7 +445,7 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv) return 0; } if (lv->size > max_size) { - char *dummy = display_size(max_size, SIZE_SHORT); + char *dummy = display_size(max_size, SIZE_SHORT); log_error("logical volumes cannot be larger than %s", dummy); dbg_free(dummy); return 0; @@ -464,7 +454,8 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv) return 1; } -static int _pv_write(struct format_instance *fi, struct physical_volume *pv) +static int _pv_write(struct format_instance *fid, struct physical_volume *pv, + void *mdl) { struct pool *mem; struct disk_list *dl; @@ -472,14 +463,15 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv) list_init(&pvs); - if (*pv->vg_name || pv->pe_allocated ) { + if (*pv->vg_name || pv->pe_alloc_count) { log_error("Assertion failed: can't _pv_write non-orphan PV " "(in VG %s)", pv->vg_name); return 0; } /* Ensure any residual PE structure is gone */ - pv->pe_size = pv->pe_count = pv->pe_start = 0; + pv->pe_size = pv->pe_count = 0; + pv->pe_start = PE_ALIGN; if (!(mem = pool_create(1024))) { stack; @@ -502,9 +494,10 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv) dev_write in order to make other disk tools happy */ dl->pvd.pv_on_disk.base = METADATA_BASE; dl->pvd.pv_on_disk.size = PV_SIZE; + dl->pvd.pe_on_disk.base = PE_ALIGN * SECTOR_SIZE; list_add(&pvs, &dl->list); - if (!write_disks(&pvs)) { + if (!write_disks(fid->fmt, &pvs)) { stack; goto bad; } @@ -512,26 +505,26 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv) pool_destroy(mem); return 1; - bad: + bad: pool_destroy(mem); return 0; } -int _vg_setup(struct format_instance *fi, struct volume_group *vg) +int _vg_setup(struct format_instance *fid, struct volume_group *vg) { /* just check max_pv and max_lv */ if (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 - 1; if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) { char *dummy, *dummy2; log_error("Extent size must be between %s and %s", - (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT)), - (dummy2 = display_size(MAX_PE_SIZE / 2, SIZE_SHORT))); + (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT)), + (dummy2 = display_size(MAX_PE_SIZE / 2, SIZE_SHORT))); dbg_free(dummy); dbg_free(dummy2); @@ -541,7 +534,7 @@ int _vg_setup(struct format_instance *fi, struct volume_group *vg) if (vg->extent_size % MIN_PE_SIZE) { char *dummy; log_error("Extent size must be multiple of %s", - (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT))); + (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT))); dbg_free(dummy); return 0; } @@ -555,37 +548,72 @@ int _vg_setup(struct format_instance *fi, struct volume_group *vg) return 1; } -void _destroy(struct format_instance *fi) +struct format_instance *_create_instance(struct format_type *fmt, + const char *vgname, void *private) +{ + struct format_instance *fid; + struct metadata_area *mda; + + if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) { + stack; + return NULL; + } + + fid->fmt = fmt; + list_init(&fid->metadata_areas); + + /* Define a NULL metadata area */ + if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) { + stack; + pool_free(fmt->cmd->mem, fid); + return NULL; + } + + mda->metadata_locn = NULL; + list_add(&fid->metadata_areas, &mda->list); + + return fid; +} + +void _destroy_instance(struct format_instance *fid) { - dbg_free(fi); + return; } +void _destroy(struct format_type *fmt) +{ + dbg_free(fmt); +} 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, - lv_setup: _lv_setup, - vg_read: _vg_read, - vg_setup: _vg_setup, - vg_write: _vg_write, - destroy: _destroy, + get_vgs: _get_vgs, + get_pvs: _get_pvs, + pv_read: _pv_read, + pv_setup: _pv_setup, + pv_write: _pv_write, + lv_setup: _lv_setup, + vg_read: _vg_read, + vg_setup: _vg_setup, + vg_write: _vg_write, + create_instance:_create_instance, + destroy_instance:_destroy_instance, + destroy: _destroy, }; -struct format_instance *create_lvm1_format(struct cmd_context *cmd) +struct format_type *create_lvm1_format(struct cmd_context *cmd) { - struct format_instance *fi = dbg_malloc(sizeof(*fi)); + struct format_type *fmt = dbg_malloc(sizeof(*fmt)); - if (!fi) { + if (!fmt) { stack; return NULL; } - fi->cmd = cmd; - fi->ops = &_format1_ops; - fi->private = NULL; + fmt->cmd = cmd; + fmt->ops = &_format1_ops; + fmt->name = FMT_LVM1_NAME; + fmt->features = 0; + fmt->private = NULL; - return fi; + return fmt; } diff --git a/lib/format1/format1.h b/lib/format1/format1.h index a79a3fe8..6412e4bf 100644 --- a/lib/format1/format1.h +++ b/lib/format1/format1.h @@ -9,6 +9,6 @@ #include "metadata.h" -struct format_instance *create_lvm1_format(struct cmd_context *cmd); +struct format_type *create_lvm1_format(struct cmd_context *cmd); #endif diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index d549dd5c..f100f505 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -53,13 +53,13 @@ int import_pv(struct pool *mem, struct device *dev, /* Store system_id from first PV if PV belongs to a VG */ if (vg && !*vg->system_id) - strncpy(vg->system_id, pvd->system_id, NAME_LEN); + strncpy(vg->system_id, pvd->system_id, NAME_LEN); if (vg && strncmp(vg->system_id, pvd->system_id, sizeof(pvd->system_id))) - log_very_verbose("System ID %s on %s differs from %s for " - "volume group", pvd->system_id, - dev_name(pv->dev), vg->system_id); + log_very_verbose("System ID %s on %s differs from %s for " + "volume group", pvd->system_id, + dev_name(pv->dev), vg->system_id); /* * If exported, we still need to flag in pv->status too because @@ -75,7 +75,7 @@ int import_pv(struct pool *mem, struct device *dev, pv->pe_size = pvd->pe_size; pv->pe_start = pvd->pe_start; pv->pe_count = pvd->pe_total; - pv->pe_allocated = pvd->pe_allocated; + pv->pe_alloc_count = pvd->pe_allocated; return 1; } @@ -163,7 +163,7 @@ int export_pv(struct pool *mem, struct volume_group *vg, if (vg && (!*vg->system_id || strncmp(vg->system_id, pvd->system_id, sizeof(pvd->system_id)))) - strncpy(vg->system_id, pvd->system_id, NAME_LEN); + strncpy(vg->system_id, pvd->system_id, NAME_LEN); //pvd->pv_major = MAJOR(pv->dev); @@ -174,15 +174,14 @@ int export_pv(struct pool *mem, struct volume_group *vg, pvd->lv_cur = 0; /* this is set when exporting the lv list */ pvd->pe_size = pv->pe_size; pvd->pe_total = pv->pe_count; - pvd->pe_allocated = pv->pe_allocated; + pvd->pe_allocated = pv->pe_alloc_count; pvd->pe_start = pv->pe_start; return 1; } int import_vg(struct pool *mem, - struct volume_group *vg, struct disk_list *dl, - int partial) + struct volume_group *vg, struct disk_list *dl, int partial) { struct vg_disk *vgd = &dl->vgd; memcpy(vg->id.uuid, vgd->vg_uuid, ID_LEN); @@ -274,7 +273,7 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd) { lvid_from_lvnum(&lv->lvid, &lv->vg->id, lvd->lv_number); - if (!(lv->name = _create_lv_name(mem, lvd->lv_name))) { + if (!(lv->name = _create_lv_name(mem, lvd->lv_name))) { stack; return 0; } @@ -306,8 +305,8 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd) lv->status |= ALLOC_SIMPLE; lv->read_ahead = lvd->lv_read_ahead; - lv->size = lvd->lv_size; - lv->le_count = lvd->lv_allocated_le; + lv->size = lvd->lv_size; + lv->le_count = lvd->lv_allocated_le; list_init(&lv->segments); @@ -343,10 +342,10 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg, lvd->lv_stripes = list_item(lv->segments.n, struct stripe_segment)->stripes; lvd->lv_stripesize = list_item(lv->segments.n, - struct stripe_segment)->stripe_size; + struct stripe_segment)->stripe_size; - lvd->lv_size = lv->size; - lvd->lv_allocated_le = lv->le_count; + lvd->lv_size = lv->size; + lvd->lv_allocated_le = lv->le_count; if (lv->status & BADBLOCK_ON) lvd->lv_badblock = LV_BADBLOCK_ON; @@ -359,26 +358,25 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg, } int export_extents(struct disk_list *dl, int lv_num, - struct logical_volume *lv, - struct physical_volume *pv) + struct logical_volume *lv, struct physical_volume *pv) { struct list *segh; struct pe_disk *ped; struct stripe_segment *seg; uint32_t pe, s; - list_iterate (segh, &lv->segments) { + list_iterate(segh, &lv->segments) { seg = list_item(segh, struct stripe_segment); for (s = 0; s < seg->stripes; s++) { if (seg->area[s].pv != pv) - continue; /* not our pv */ + continue; /* not our pv */ for (pe = 0; pe < (seg->len / seg->stripes); pe++) { ped = &dl->extents[pe + seg->area[s].pe]; ped->lv_num = lv_num; ped->le_num = (seg->le / seg->stripes) + pe + - s * (lv->le_count / seg->stripes); + s * (lv->le_count / seg->stripes); } } } @@ -386,7 +384,8 @@ int export_extents(struct disk_list *dl, int lv_num, return 1; } -int import_pvs(struct pool *mem, struct volume_group *vg, +int import_pvs(struct format_instance *fid, struct pool *mem, + struct volume_group *vg, struct list *pvds, struct list *results, int *count) { struct list *pvdh; @@ -409,6 +408,7 @@ int import_pvs(struct pool *mem, struct volume_group *vg, return 0; } + pvl->pv->fid = fid; list_add(results, &pvl->list); (*count)++; } @@ -442,8 +442,7 @@ static struct logical_volume *_add_lv(struct pool *mem, return lv; } -int import_lvs(struct pool *mem, struct volume_group *vg, - struct list *pvds) +int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds) { struct disk_list *dl; struct lvd_list *ll; @@ -493,7 +492,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, } memset(dl->extents, 0, len); - list_iterate (lvh, &vg->lvs) { + list_iterate(lvh, &vg->lvs) { ll = list_item(lvh, struct lv_list); if (!(lvdl = pool_alloc(dl->mem, sizeof(*lvdl)))) { stack; @@ -524,7 +523,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, * Now we need to run through the snapshots, exporting * the SNAPSHOT_ORG flags etc. */ - list_iterate (sh, &vg->snapshots) { + list_iterate(sh, &vg->snapshots) { struct lv_disk *org, *cow; struct snapshot *s = list_item(sh, struct snapshot_list)->snapshot; @@ -549,7 +548,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, r = 1; - out: + out: hash_destroy(lvd_hash); return r; } @@ -569,10 +568,10 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, /* build an index of lv numbers */ memset(lvs, 0, sizeof(lvs)); - list_iterate (pvdh, pvds) { + list_iterate(pvdh, pvds) { dl = list_item(pvdh, struct disk_list); - list_iterate (lvdh, &dl->lvds) { + list_iterate(lvdh, &dl->lvds) { lvd = &(list_item(lvdh, struct lvd_list)->lvd); lvnum = lvd->lv_number; @@ -595,10 +594,10 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, /* * Now iterate through yet again adding the snapshots. */ - list_iterate (pvdh, pvds) { + list_iterate(pvdh, pvds) { dl = list_item(pvdh, struct disk_list); - list_iterate (lvdh, &dl->lvds) { + list_iterate(lvdh, &dl->lvds) { lvd = &(list_item(lvdh, struct lvd_list)->lvd); if (!(lvd->lv_access & LV_SNAPSHOT)) @@ -617,8 +616,7 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, continue; /* insert the snapshot */ - if (!vg_add_snapshot(org, cow, 1, - lvd->lv_chunk_size)) { + if (!vg_add_snapshot(org, cow, 1, lvd->lv_chunk_size)) { log_err("Couldn't add snapshot."); return 0; } @@ -628,8 +626,6 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, return 1; } - - int export_uuids(struct disk_list *dl, struct volume_group *vg) { struct uuid_list *ul; @@ -688,14 +684,14 @@ void export_pv_act(struct list *pvds) } } -int export_vg_number(struct list *pvds, const char *vg_name, - struct dev_filter *filter) +int export_vg_number(struct format_instance *fid, struct list *pvds, + const char *vg_name, struct dev_filter *filter) { struct list *pvdh; struct disk_list *dl; int vg_num; - if (!get_free_vg_number(filter, vg_name, &vg_num)) { + if (!get_free_vg_number(fid, filter, vg_name, &vg_num)) { stack; return 0; } @@ -707,4 +703,3 @@ int export_vg_number(struct list *pvds, const char *vg_name, return 1; } - diff --git a/lib/format1/import-extents.c b/lib/format1/import-extents.c index 9e56e95a..84791b58 100644 --- a/lib/format1/import-extents.c +++ b/lib/format1/import-extents.c @@ -249,7 +249,7 @@ static int _check_stripe(struct lv_map *lvm, struct stripe_segment *seg, */ for (st = 0; st < seg->stripes; st++) if ((lvm->map[le + st * len].pv != seg->area[st].pv) || - (lvm->map[le + st * len].pe != seg->area[st].pe + seg->len)) + (lvm->map[le + st * len].pe != seg->area[st].pe + seg->len)) return 0; return 1; @@ -266,8 +266,7 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm) if (lvm->lv->le_count % lvm->stripes) { log_error("Number of stripes (%u) incompatible " "with logical extent count (%u) for %s", - lvm->stripes, lvm->lv->le_count, - lvm->lv->name); + lvm->stripes, lvm->lv->le_count, lvm->lv->name); } len = lvm->lv->le_count / lvm->stripes; diff --git a/lib/format1/layout.c b/lib/format1/layout.c index 77e5857e..c9408242 100644 --- a/lib/format1/layout.c +++ b/lib/format1/layout.c @@ -8,7 +8,6 @@ #include "log.h" #include "dbg_malloc.h" - /* * Only works with powers of 2. */ @@ -51,17 +50,17 @@ static void _calc_simple_layout(struct pv_disk *pvd) pvd->pv_on_disk.base = METADATA_BASE; pvd->pv_on_disk.size = PV_SIZE; - pvd->vg_on_disk.base = _next_base(&pvd->pv_on_disk); - pvd->vg_on_disk.size = VG_SIZE; + pvd->vg_on_disk.base = _next_base(&pvd->pv_on_disk); + pvd->vg_on_disk.size = VG_SIZE; - pvd->pv_uuidlist_on_disk.base = _next_base(&pvd->vg_on_disk); - pvd->pv_uuidlist_on_disk.size = MAX_PV * NAME_LEN; + pvd->pv_uuidlist_on_disk.base = _next_base(&pvd->vg_on_disk); + pvd->pv_uuidlist_on_disk.size = MAX_PV * NAME_LEN; - pvd->lv_on_disk.base = _next_base(&pvd->pv_uuidlist_on_disk); - pvd->lv_on_disk.size = MAX_LV * sizeof(struct lv_disk); + pvd->lv_on_disk.base = _next_base(&pvd->pv_uuidlist_on_disk); + pvd->lv_on_disk.size = MAX_LV * sizeof(struct lv_disk); - pvd->pe_on_disk.base = _next_base(&pvd->lv_on_disk); - pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk); + pvd->pe_on_disk.base = _next_base(&pvd->lv_on_disk); + pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk); } int _check_vg_limits(struct disk_list *dl) @@ -103,7 +102,6 @@ int calculate_layout(struct disk_list *dl) return 1; } - /* * It may seem strange to have a struct physical_volume in here, * but the number of extents that can fit on a disk *is* metadata @@ -133,16 +131,15 @@ int calculate_extent_count(struct physical_volume *pv) return 0; } - do { pvd->pe_total--; _calc_simple_layout(pvd); - end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size + \ - SECTOR_SIZE - 1) / SECTOR_SIZE); + end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size + + SECTOR_SIZE - 1) / SECTOR_SIZE); pvd->pe_start = _round_up(end, PE_ALIGN); - } while((pvd->pe_start + (pvd->pe_total * pv->pe_size)) > pv->size); + } while ((pvd->pe_start + (pvd->pe_total * pv->pe_size)) > pv->size); if (pvd->pe_total > MAX_PE_TOTAL) { log_error("Metadata extent limit (%u) exceeded for %s - " diff --git a/lib/format1/lvm1_label.c b/lib/format1/lvm1_label.c index 39cc7fea..3f2e9b08 100644 --- a/lib/format1/lvm1_label.c +++ b/lib/format1/lvm1_label.c @@ -25,21 +25,20 @@ static int _can_handle(struct labeller *l, struct device *dev) struct pv_disk pvd; int r; - if (!dev_open(dev, O_RDONLY)) { - stack; - return 0; - } + if (!dev_open(dev, O_RDONLY)) { + stack; + return 0; + } r = read_pvd(dev, &pvd); - if (!dev_close(dev)) - stack; + if (!dev_close(dev)) + stack; return r; } -static int _write(struct labeller *l, - struct device *dev, struct label *label) +static int _write(struct labeller *l, struct device *dev, struct label *label) { _not_supported("write"); return 0; @@ -81,15 +80,15 @@ static int _read(struct labeller *l, struct device *dev, struct label **label) struct pv_disk pvd; int r = 0; - if (!dev_open(dev, O_RDONLY)) { - stack; - return 0; - } + if (!dev_open(dev, O_RDONLY)) { + stack; + return 0; + } r = read_pvd(dev, &pvd); - if (!dev_close(dev)) - stack; + if (!dev_close(dev)) + stack; if (!r) { stack; @@ -118,15 +117,14 @@ static void _destroy(struct labeller *l) dbg_free(l); } - struct label_ops _lvm1_ops = { - can_handle: _can_handle, - write: _write, - remove: _remove, - read: _read, - verify: _can_handle, - destroy_label: _destroy_label, - destroy: _destroy + can_handle: _can_handle, + write: _write, + remove: _remove, + read: _read, + verify: _can_handle, + destroy_label: _destroy_label, + destroy: _destroy }; struct labeller *lvm1_labeller_create(void) diff --git a/lib/format1/vg_number.c b/lib/format1/vg_number.c index 331d7c9f..e1d27899 100644 --- a/lib/format1/vg_number.c +++ b/lib/format1/vg_number.c @@ -15,8 +15,8 @@ * Put in separate file so it wouldn't contaminate * other code. */ -int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg, - int *result) +int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter, + const char *candidate_vg, int *result) { struct list *pvh; struct list all_pvs; @@ -31,7 +31,7 @@ int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg, return 0; } - if (!read_pvs_in_vg(NULL, filter, mem, &all_pvs)) { + if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs)) { stack; goto out; } @@ -40,8 +40,7 @@ int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg, list_iterate(pvh, &all_pvs) { dl = list_item(pvh, struct disk_list); - if (!*dl->pvd.vg_name || - !strcmp(dl->pvd.vg_name, candidate_vg)) + if (!*dl->pvd.vg_name || !strcmp(dl->pvd.vg_name, candidate_vg)) continue; numbers[dl->vgd.vg_number] = 1; @@ -55,7 +54,7 @@ int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg, } } - out: + out: pool_destroy(mem); return r; } |