From 294ddff8a6d165b676108ca7eb1290ba3dee5eea Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 13 Feb 2002 13:29:16 +0000 Subject: [PATCH] o snapshot support for the text format. The logical_volumes, and snapshots sections of the text format are now optional. --- lib/format_text/export.c | 61 ++++++++++++++++++++++++++++++++-- lib/format_text/import.c | 72 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 126 insertions(+), 7 deletions(-) diff --git a/lib/format_text/export.c b/lib/format_text/export.c index c3e3ec859..c322a5d78 100644 --- a/lib/format_text/export.c +++ b/lib/format_text/export.c @@ -338,6 +338,12 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) char buffer[256]; int seg_count; + /* + * Don't bother with an lv section if there are no lvs. + */ + if (list_empty(&vg->lvs)) + return 1; + _out(f, "logical_volumes {"); _nl(f); _inc_indent(f); @@ -381,6 +387,55 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) return 1; } +static int _print_snapshot(struct formatter *f, struct snapshot *s, + unsigned int count) +{ + _nl(f); + _out(f, "snapshot%u {", count); + _inc_indent(f); + + _out(f, "chunk_size = %u", s->chunk_size); + _out(f, "origin = \"%s\"", s->origin->name); + _out(f, "cow_store = \"%s\"", s->cow->name); + + _dec_indent(f); + _out(f, "}"); + + return 1; +} + +static int _print_snapshots(struct formatter *f, struct volume_group *vg) +{ + struct list *sh; + struct snapshot *s; + unsigned int count = 0; + + /* + * Don't bother with a snapshot section if there are no + * snapshots. + */ + if (list_empty(&vg->snapshots)) + return 1; + + _out(f, "snapshots {"); + _nl(f); + _inc_indent(f); + + list_iterate (sh, &vg->snapshots) { + s = list_item(sh, struct snapshot_list)->snapshot; + + if (!_print_snapshot(f, s, count++)) { + stack; + return 0; + } + } + + _dec_indent(f); + _out(f, "}"); + + return 1; +} + /* * In the text format we refer to pv's as 'pv1', * 'pv2' etc. This function builds a hash table @@ -467,15 +522,17 @@ int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc) fail; _nl(f); - if (!_print_pvs(f, vg)) fail; _nl(f); - if (!_print_lvs(f, vg)) fail; + _nl(f); + if (!_print_snapshots(f, vg)) + fail; + #undef fail _dec_indent(f); diff --git a/lib/format_text/import.c b/lib/format_text/import.c index b2612a901..fcbd1e2da 100644 --- a/lib/format_text/import.c +++ b/lib/format_text/import.c @@ -398,17 +398,71 @@ static int _read_lv(struct pool *mem, return 1; } +static int _read_snapshot(struct pool *mem, + struct volume_group *vg, struct config_node *sn, + struct config_node *vgn, struct hash_table *pv_hash, + struct uuid_map *um) +{ + uint32_t chunk_size; + const char *org_name, *cow_name; + struct logical_volume *org, *cow; + + if (!(sn = sn->child)) { + log_err("Empty snapshot section."); + return 0; + } + + if (!_read_uint32(sn, "chunk_size", &chunk_size)) { + log_err("Couldn't read chunk size for snapshot."); + return 0; + } + + if (!(cow_name = find_config_str(sn, "cow_store", '/', NULL))) { + log_err("Snapshot cow storage not specified."); + return 0; + } + + if (!(org_name = find_config_str(sn, "origin", '/', NULL))) { + log_err("Snapshot origin not specified."); + return 0; + } + + if (!(cow = find_lv(vg, cow_name))) { + log_err("Unknown logical volume specified for " + "snapshot cow store."); + return 0; + } + + if (!(org = find_lv(vg, org_name))) { + log_err("Unknown logical volume specified for " + "snapshot origin."); + return 0; + } + + if (!vg_add_snapshot(vg, org, cow, 1, chunk_size)) { + stack; + return 0; + } + + return 1; +} + static int _read_sections(const char *section, section_fn fn, struct pool *mem, struct volume_group *vg, struct config_node *vgn, struct hash_table *pv_hash, - struct uuid_map *um) + struct uuid_map *um, + int optional) { struct config_node *n; if (!(n = find_config_node(vgn, section, '/'))) { - log_err("Couldn't find section '%s'.", section); - return 0; + if (!optional) { + log_err("Couldn't find section '%s'.", section); + return 0; + } + + return 1; } for (n = n->child; n; n = n->sib) { @@ -514,7 +568,7 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf, list_init(&vg->pvs); if (!_read_sections("physical_volumes", _read_pv, mem, vg, - vgn, pv_hash, um)) { + vgn, pv_hash, um, 0)) { log_err("Couldn't find all physical volumes for volume " "group %s.", vg->name); goto bad; @@ -522,12 +576,20 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf, list_init(&vg->lvs); if (!_read_sections("logical_volumes", _read_lv, mem, vg, - vgn, pv_hash, um)) { + vgn, pv_hash, um, 1)) { log_err("Couldn't read all logical volumes for volume " "group %s.", vg->name); goto bad; } + list_init(&vg->snapshots); + if (!_read_sections("snapshots", _read_snapshot, mem, vg, + vgn, pv_hash, um, 1)) { + log_err("Couldn't read all snapshots for volume group %s.", + vg->name); + goto bad; + } + hash_destroy(pv_hash); /*