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 | |
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.
88 files changed, 2399 insertions, 1787 deletions
@@ -1 +1 @@ -0.95.05-cvs (2002-04-23) +1.95.06-cvs (2002-04-24) diff --git a/lib/activate/activate-lv.c b/lib/activate/activate-lv.c deleted file mode 100644 index dc4d7d9d..00000000 --- a/lib/activate/activate-lv.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2002 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#include "ll-activate.h" -#include "lvm-string.h" -#include "log.h" - -#include <libdevmapper.h> - -/* - * Emit a target for a given segment. - * FIXME: tidy this function. - */ -static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg) -{ - char params[1024]; - uint64_t esize = seg->lv->vg->extent_size; - uint32_t s, stripes = seg->stripes; - int w = 0, tw = 0, error = 0; - const char *no_space = - "Insufficient space to write target parameters."; - char *filler = "/dev/ioerror"; - char *target; - - if (stripes == 1) { - if (!seg->area[0].pv) { - target = "error"; - error = 1; - } - else - target = "linear"; - } - - if (stripes > 1) { - target = "striped"; - tw = lvm_snprintf(params, sizeof(params), "%u %u ", - stripes, seg->stripe_size); - - if (tw < 0) { - log_err(no_space); - return 0; - } - - w = tw; - } - - if (!error) { - for (s = 0; s < stripes; s++, w += tw) { - if (!seg->area[s].pv) - tw = lvm_snprintf( - params + w, sizeof(params) - w, - "%s 0%s", filler, - s == (stripes - 1) ? "" : " "); - else - tw = lvm_snprintf( - params + w, sizeof(params) - w, - "%s %" PRIu64 "%s", - dev_name(seg->area[s].pv->dev), - (seg->area[s].pv->pe_start + - (esize * seg->area[s].pe)), - s == (stripes - 1) ? "" : " "); - - if (tw < 0) { - log_err(no_space); - return 0; - } - } - } - - log_very_verbose("Adding target: %" PRIu64 " %" PRIu64 " %s %s", - esize * seg->le, esize * seg->len, - target, params); - - if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len, - target, params)) { - stack; - return 0; - } - - return 1; -} - -int device_populate_lv(struct dm_task *dmt, struct logical_volume *lv) -{ - struct list *segh; - struct stripe_segment *seg; - - log_very_verbose("Generating devmapper table for %s", lv->name); - list_iterate(segh, &lv->segments) { - seg = list_item(segh, struct stripe_segment); - if (!_emit_target(dmt, seg)) { - log_error("Unable to build table for '%s'", lv->name); - return 0; - } - } - - return 1; -} diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 79a6e411..9898e37c 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -189,24 +189,18 @@ static struct logical_volume *_lv_from_lvid(struct cmd_context *cmd, struct lv_list *lvl; struct volume_group *vg; union lvid *lvid; - char *vgname; lvid = (union lvid *) lvid_s; - /* FIXME Change vgread to accept vgid directly - can't rely on cache */ - if (!(vgname = vgname_from_vgid(cmd, &lvid->id[0]))) { + log_very_verbose("Finding volume group for uuid %s", lvid_s); + if (!(vg = vg_read_by_vgid(cmd, lvid->id[0].uuid))) { log_error("Volume group for uuid not found: %s", lvid_s); return NULL; } - log_verbose("Finding volume group \"%s\"", vgname); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vgname))) { - log_error("Volume group \"%s\" doesn't exist", vgname); - return NULL; - } - + log_verbose("Found volume group \"%s\"", vg->name); if (vg->status & EXPORTED_VG) { - log_error("Volume group \"%s\" is exported", vgname); + log_error("Volume group \"%s\" is exported", vg->name); return NULL; } diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 08245b0e..48c0bf20 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -1413,8 +1413,9 @@ static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv) /* Remove any snapshots with given origin */ list_iterate(sh, active_head) { active = list_item(sh, struct lv_list)->lv; - if ((s = find_cow(active)) && s->origin == lv) + if ((s = find_cow(active)) && s->origin == lv) { _remove_lv(active_head, active); + } } _remove_lv(active_head, lv); @@ -1427,8 +1428,9 @@ static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv) /* Was this the last active snapshot with this origin? */ list_iterate(sh, active_head) { active = list_item(sh, struct lv_list)->lv; - if ((s = find_cow(active)) && s->origin == old_origin) + if ((s = find_cow(active)) && s->origin == old_origin) { return 1; + } } return _add_lvs(dm->mem, &dm->reload_list, old_origin); diff --git a/lib/activate/dmfs-driver.h b/lib/activate/dmfs-driver.h deleted file mode 100644 index 3393bd35..00000000 --- a/lib/activate/dmfs-driver.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the GPL. - */ - -#ifndef DMFS_INTERFACE_H -#define DMFS_INTERFACE_H - -struct dmfs; - -struct dmfs *dmfs_create(void); -void dmfs_destroy(struct dmfs *dm); - -int dmfs_dev_is_present(struct dmfs *dm, const char *dev); -int dmfs_dev_is_active(struct dmfs *dm, const char *dev); - -int dmfs_table_is_present(struct dmfs *dm, const char *dev, const char *table); -int dmfs_table_is_active(struct dmfs *dm, const char *dev, const char *table); - -int dmfs_dev_create(struct dmfs *dm, const char *name); -int dmfs_dev_load_table(struct dmfs *dm, const char *dev, - const char *table, const char *file); -int dmfs_dev_drop_table(struct dmfs *dm, const char *dev, const char *table); - -int dmfs_dev_activate_table(struct dmfs *dm, const char *dev, - const char *table); - -int dmfs_dev_deactivate(struct dmfs *dm, const char *dev); - -#endif diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h index 1f4f4c9e..30894e64 100644 --- a/lib/commands/toolcontext.h +++ b/lib/commands/toolcontext.h @@ -18,7 +18,11 @@ struct cmd_context { /* format handler allocates all objects from here */ struct pool *mem; - struct format_instance *fid; + struct format_type *fmt; /* Current format to use by default */ + + /* FIXME Move into dynamic list */ + struct format_type *fmt1; /* Format1 */ + struct format_type *fmtt; /* Format_text */ char *cmd_line; char *dev_dir; diff --git a/lib/config/config.c b/lib/config/config.c index 8128b794..0a1e0e65 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -18,34 +18,34 @@ #include "log.h" enum { - TOK_INT, - TOK_FLOAT, - TOK_STRING, - TOK_EQ, - TOK_SECTION_B, - TOK_SECTION_E, - TOK_ARRAY_B, - TOK_ARRAY_E, - TOK_IDENTIFIER, + TOK_INT, + TOK_FLOAT, + TOK_STRING, + TOK_EQ, + TOK_SECTION_B, + TOK_SECTION_E, + TOK_ARRAY_B, + TOK_ARRAY_E, + TOK_IDENTIFIER, TOK_COMMA, TOK_EOF }; struct parser { - const char *fb, *fe; /* file limits */ + const char *fb, *fe; /* file limits */ - int t; /* token limits and type */ - const char *tb, *te; + int t; /* token limits and type */ + const char *tb, *te; - int fd; /* descriptor for file being parsed */ + int fd; /* descriptor for file being parsed */ int line; /* line number we are on */ - struct pool *mem; + struct pool *mem; }; struct cs { - struct config_file cf; - struct pool *mem; + struct config_file cf; + struct pool *mem; }; static void _get_token(struct parser *p); @@ -68,7 +68,6 @@ static char *_dup_tok(struct parser *p); } \ } while(0); - static int _tok_match(const char *str, const char *b, const char *e) { while (*str && (b != e)) { @@ -79,88 +78,92 @@ static int _tok_match(const char *str, const char *b, const char *e) return !(*str || (b != e)); } - /* * public interface */ struct config_file *create_config_file(void) { - struct cs *c; - struct pool *mem = pool_create(10 * 1024); - - if (!mem) { - stack; - return 0; - } - - if (!(c = pool_alloc(mem, sizeof(*c)))) { - stack; - pool_destroy(mem); - return 0; - } - - c->mem = mem; - c->cf.root = (struct config_node *)NULL; - return &c->cf; + struct cs *c; + struct pool *mem = pool_create(10 * 1024); + + if (!mem) { + stack; + return 0; + } + + if (!(c = pool_alloc(mem, sizeof(*c)))) { + stack; + pool_destroy(mem); + return 0; + } + + c->mem = mem; + c->cf.root = (struct config_node *) NULL; + return &c->cf; } void destroy_config_file(struct config_file *cf) { - pool_destroy(((struct cs *) cf)->mem); + pool_destroy(((struct cs *) cf)->mem); } int read_config(struct config_file *cf, const char *file) { struct cs *c = (struct cs *) cf; - struct parser *p; - struct stat info; - int r = 1, fd; - - if (!(p = pool_alloc(c->mem, sizeof(*p)))) { - stack; - return 0; - } + struct parser *p; + struct stat info; + int r = 1, fd; + + if (!(p = pool_alloc(c->mem, sizeof(*p)))) { + stack; + return 0; + } p->mem = c->mem; - /* memory map the file */ - if (stat(file, &info) || S_ISDIR(info.st_mode)) { - log_sys_error("stat", file); - return 0; - } - - if ((fd = open(file, O_RDONLY)) < 0) { - log_sys_error("open", file); - return 0; - } - - p->fb = mmap((caddr_t) 0, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (p->fb == MAP_FAILED) { - log_sys_error("mmap", file); - close(fd); - return 0; - } - p->fe = p->fb + info.st_size; - - /* parse */ - p->tb = p->te = p->fb; + /* memory map the file */ + if (stat(file, &info) || S_ISDIR(info.st_mode)) { + log_sys_error("stat", file); + return 0; + } + + if (info.st_size == 0) { + log_verbose("%s is empty", file); + return 1; + } + + if ((fd = open(file, O_RDONLY)) < 0) { + log_sys_error("open", file); + return 0; + } + + p->fb = mmap((caddr_t) 0, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (p->fb == (caddr_t) (-1)) { + log_sys_error("mmap", file); + close(fd); + return 0; + } + p->fe = p->fb + info.st_size; + + /* parse */ + p->tb = p->te = p->fb; p->line = 1; _get_token(p); - if (!(cf->root = _file(p))) { - stack; - r = 0; - } - - /* unmap the file */ - if (munmap((char *) p->fb, info.st_size)) { - log_sys_error("munmap", file); - r = 0; - } - - close(fd); - return r; + if (!(cf->root = _file(p))) { + stack; + r = 0; + } + + /* unmap the file */ + if (munmap((char *) p->fb, info.st_size)) { + log_sys_error("munmap", file); + r = 0; + } + + close(fd); + return r; } -static void _write_value(FILE *fp, struct config_value *v) +static void _write_value(FILE * fp, struct config_value *v) { switch (v->type) { case CFG_STRING: @@ -177,21 +180,21 @@ static void _write_value(FILE *fp, struct config_value *v) } } -static int _write_config(struct config_node *n, FILE *fp, int level) +static int _write_config(struct config_node *n, FILE * fp, int level) { - char space[MAX_INDENT + 1]; - int l = (level < MAX_INDENT) ? level : MAX_INDENT; - int i; + char space[MAX_INDENT + 1]; + int l = (level < MAX_INDENT) ? level : MAX_INDENT; + int i; if (!n) return 1; - for (i = 0; i < l; i++) - space[i] = ' '; - space[i] = '\0'; + for (i = 0; i < l; i++) + space[i] = ' '; + space[i] = '\0'; - while (n) { - fprintf(fp, "%s%s", space, n->key); + while (n) { + fprintf(fp, "%s%s", space, n->key); if (!n->v) { /* it's a sub section */ fprintf(fp, " {\n"); @@ -214,8 +217,8 @@ static int _write_config(struct config_node *n, FILE *fp, int level) _write_value(fp, v); } fprintf(fp, "\n"); - n = n->sib; - } + n = n->sib; + } /* FIXME: add error checking */ return 1; } @@ -223,17 +226,17 @@ static int _write_config(struct config_node *n, FILE *fp, int level) int write_config(struct config_file *cf, const char *file) { int r = 1; - FILE *fp = fopen(file, "w"); - if (!fp) { - log_sys_error("open", file); - return 0; - } + FILE *fp = fopen(file, "w"); + if (!fp) { + log_sys_error("open", file); + return 0; + } - if (!_write_config(cf->root, fp, 0)) { + if (!_write_config(cf->root, fp, 0)) { stack; r = 0; } - fclose(fp); + fclose(fp); return r; } @@ -260,7 +263,7 @@ static struct config_node *_file(struct parser *p) static struct config_node *_section(struct parser *p) { - /* IDENTIFIER '{' VALUE* '}' */ + /* IDENTIFIER '{' VALUE* '}' */ struct config_node *root, *n, *l = NULL; if (!(root = _create_node(p))) { stack; @@ -272,7 +275,7 @@ static struct config_node *_section(struct parser *p) return 0; } - match (TOK_IDENTIFIER); + match(TOK_IDENTIFIER); if (p->t == TOK_SECTION_B) { match(TOK_SECTION_B); @@ -297,17 +300,17 @@ static struct config_node *_section(struct parser *p) } } - return root; + return root; } static struct config_value *_value(struct parser *p) { - /* '[' TYPE* ']' | TYPE */ + /* '[' TYPE* ']' | TYPE */ struct config_value *h = 0, *l, *ll = 0; - if (p->t == TOK_ARRAY_B) { - match (TOK_ARRAY_B); - while (p->t != TOK_ARRAY_E) { - if (!(l = _type(p))) { + if (p->t == TOK_ARRAY_B) { + match(TOK_ARRAY_B); + while (p->t != TOK_ARRAY_E) { + if (!(l = _type(p))) { stack; return 0; } @@ -321,48 +324,48 @@ static struct config_value *_value(struct parser *p) if (p->t == TOK_COMMA) match(TOK_COMMA); } - match(TOK_ARRAY_E); - } else + match(TOK_ARRAY_E); + } else h = _type(p); - return h; + return h; } static struct config_value *_type(struct parser *p) { - /* [0-9]+ | [0-9]*\.[0-9]* | ".*" */ + /* [0-9]+ | [0-9]*\.[0-9]* | ".*" */ struct config_value *v = _create_value(p); - switch (p->t) { - case TOK_INT: + switch (p->t) { + case TOK_INT: v->type = CFG_INT; - v->v.i = strtol(p->tb, 0, 0); /* FIXME: check error */ - match(TOK_INT); - break; + v->v.i = strtol(p->tb, 0, 0); /* FIXME: check error */ + match(TOK_INT); + break; - case TOK_FLOAT: + case TOK_FLOAT: v->type = CFG_FLOAT; - v->v.r = strtod(p->tb, 0); /* FIXME: check error */ - match(TOK_FLOAT); - break; + v->v.r = strtod(p->tb, 0); /* FIXME: check error */ + match(TOK_FLOAT); + break; - case TOK_STRING: + case TOK_STRING: v->type = CFG_STRING; - p->tb++, p->te--; /* strip "'s */ + p->tb++, p->te--; /* strip "'s */ if (!(v->v.str = _dup_tok(p))) { stack; return 0; } p->te++; - match(TOK_STRING); - break; + match(TOK_STRING); + break; - default: + default: log_error("Parse error at line %d: expected a value", p->line); - return 0; - } - return v; + return 0; + } + return v; } static int _match_aux(struct parser *p, int t) @@ -379,106 +382,114 @@ static int _match_aux(struct parser *p, int t) */ static void _get_token(struct parser *p) { - p->tb = p->te; - _eat_space(p); - if (p->tb == p->fe) { + p->tb = p->te; + _eat_space(p); + if (p->tb == p->fe) { p->t = TOK_EOF; return; } - p->t = TOK_INT; /* fudge so the fall through for - floats works */ - switch (*p->te) { - case '{': - p->t = TOK_SECTION_B; - p->te++; - break; - - case '}': - p->t = TOK_SECTION_E; - p->te++; - break; - - case '[': - p->t = TOK_ARRAY_B; - p->te++; - break; - - case ']': - p->t = TOK_ARRAY_E; - p->te++; - break; - - case ',': - p->t = TOK_COMMA; - p->te++; - break; - - case '=': - p->t = TOK_EQ; - p->te++; - break; - - case '"': - p->t = TOK_STRING; + p->t = TOK_INT; /* fudge so the fall through for + floats works */ + switch (*p->te) { + case '{': + p->t = TOK_SECTION_B; + p->te++; + break; + + case '}': + p->t = TOK_SECTION_E; + p->te++; + break; + + case '[': + p->t = TOK_ARRAY_B; + p->te++; + break; + + case ']': + p->t = TOK_ARRAY_E; + p->te++; + break; + + case ',': + p->t = TOK_COMMA; + p->te++; + break; + + case '=': + p->t = TOK_EQ; + p->te++; + break; + + case '"': + p->t = TOK_STRING; + p->te++; + while ((p->te != p->fe) && (*p->te != '"')) { + if ((*p->te == '\\') && (p->te + 1 != p->fe)) + p->te++; + p->te++; + } + + if (p->te != p->fe) + p->te++; + break; + + case '.': + p->t = TOK_FLOAT; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': p->te++; - while ((p->te != p->fe) && (*p->te != '"')) { - if ((*p->te == '\\') && (p->te + 1 != p->fe)) - p->te++; - p->te++; - } - - if (p->te != p->fe) - p->te++; - break; - - case '.': - p->t = TOK_FLOAT; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - p->te++; - while (p->te != p->fe) { - if (*p->te == '.') { - if (p->t == TOK_FLOAT) - break; - p->t = TOK_FLOAT; - } else if (!isdigit((int) *p->te)) - break; - p->te++; - } - break; - - default: - p->t = TOK_IDENTIFIER; - while ((p->te != p->fe) && !isspace(*p->te) && - (*p->te != '#') && (*p->te != '=')) - p->te++; - break; - } + while (p->te != p->fe) { + if (*p->te == '.') { + if (p->t == TOK_FLOAT) + break; + p->t = TOK_FLOAT; + } else if (!isdigit((int) *p->te)) + break; + p->te++; + } + break; + + default: + p->t = TOK_IDENTIFIER; + while ((p->te != p->fe) && !isspace(*p->te) && + (*p->te != '#') && (*p->te != '=')) + p->te++; + break; + } } static void _eat_space(struct parser *p) { - while (p->tb != p->fe) { - if (*p->te == '#') { - while ((p->te != p->fe) && (*p->te != '\n')) - p->te++; + while (p->tb != p->fe) { + if (*p->te == '#') { + while ((p->te != p->fe) && (*p->te != '\n')) + p->te++; p->line++; } else if (isspace(*p->te)) { - while ((p->te != p->fe) && isspace(*p->te)) { + while ((p->te != p->fe) && isspace(*p->te)) { if (*p->te == '\n') p->line++; - p->te++; + p->te++; } } - else - return; + else + return; - p->tb = p->te; - } + p->tb = p->te; + } } /* @@ -525,8 +536,7 @@ struct config_node *find_config_node(struct config_node *cn, path++; /* find the end of this segment */ - for (e = path; *e && (*e != sep); e++) - ; + for (e = path; *e && (*e != sep); e++) ; /* hunt for the node */ while (cn) { @@ -547,20 +557,20 @@ struct config_node *find_config_node(struct config_node *cn, return cn; } -const char * -find_config_str(struct config_node *cn, - const char *path, char sep, const char *fail) +const char *find_config_str(struct config_node *cn, + const char *path, char sep, const char *fail) { struct config_node *n = find_config_node(cn, path, sep); if (n && n->v->type == CFG_STRING) { - log_very_verbose("Setting %s to %s", path, n->v->v.str); + if (*n->v->v.str) + log_very_verbose("Setting %s to %s", path, n->v->v.str); return n->v->v.str; } if (fail) log_very_verbose("%s not found in config: defaulting to %s", - path, fail); + path, fail); return fail; } @@ -574,7 +584,7 @@ int find_config_int(struct config_node *cn, const char *path, return n->v->v.i; } - log_very_verbose("%s not found in config: defaulting to %d", + log_very_verbose("%s not found in config: defaulting to %d", path, fail); return fail; } @@ -590,7 +600,7 @@ float find_config_float(struct config_node *cn, const char *path, } log_very_verbose("%s not found in config: defaulting to %f", - path, fail); + path, fail); return fail; @@ -609,8 +619,9 @@ static int _str_in_array(const char *str, const char *values[]) static int _str_to_bool(const char *str, int fail) { - static const char *_true_values[] = {"y", "yes", "on", "true", NULL}; - static const char *_false_values[] = {"n", "no", "off", "false", NULL}; + static const char *_true_values[] = { "y", "yes", "on", "true", NULL }; + static const char *_false_values[] = + { "n", "no", "off", "false", NULL }; if (_str_in_array(str, _true_values)) return 1; @@ -622,7 +633,7 @@ static int _str_to_bool(const char *str, int fail) } int find_config_bool(struct config_node *cn, const char *path, - char sep, int fail) + char sep, int fail) { struct config_node *n = find_config_node(cn, path, sep); struct config_value *v; @@ -644,7 +655,7 @@ int find_config_bool(struct config_node *cn, const char *path, } int get_config_uint32(struct config_node *cn, const char *path, - char sep, uint32_t *result) + char sep, uint32_t * result) { struct config_node *n; @@ -658,7 +669,7 @@ int get_config_uint32(struct config_node *cn, const char *path, } int get_config_uint64(struct config_node *cn, const char *path, - char sep, uint64_t *result) + char sep, uint64_t * result) { struct config_node *n; @@ -671,4 +682,3 @@ int get_config_uint64(struct config_node *cn, const char *path, *result = (uint64_t) n->v->v.i; return 1; } - diff --git a/lib/config/defaults.h b/lib/config/defaults.h index 4942eae4..21785d08 100644 --- a/lib/config/defaults.h +++ b/lib/config/defaults.h @@ -26,6 +26,8 @@ #define DEFAULT_UMASK 0077 +#define DEFAULT_FORMAT "lvm1" + #ifdef READLINE_SUPPORT #define DEFAULT_MAX_HISTORY 100 #endif diff --git a/lib/datastruct/bitset.c b/lib/datastruct/bitset.c index 44d69626..3d1a2875 100644 --- a/lib/datastruct/bitset.c +++ b/lib/datastruct/bitset.c @@ -12,7 +12,7 @@ /* FIXME: calculate this. */ #define INT_SHIFT 5 -bitset_t bitset_create(struct pool *mem, unsigned num_bits) +bitset_t bitset_create(struct pool * mem, unsigned num_bits) { int n = (num_bits / BITS_PER_INT) + 2; int size = sizeof(int) * n; @@ -33,7 +33,7 @@ void bitset_destroy(bitset_t bs) void bit_union(bitset_t out, bitset_t in1, bitset_t in2) { int i; - for(i = (in1[0] / BITS_PER_INT) + 1; i; i--) + for (i = (in1[0] / BITS_PER_INT) + 1; i; i--) out[i] = in1[i] | in2[i]; } @@ -58,7 +58,7 @@ int bit_get_next(bitset_t bs, int last_bit) last_bit++; /* otherwise we'll return the same bit again */ - while(last_bit < bs[0]) { + while (last_bit < bs[0]) { word = last_bit >> INT_SHIFT; test = bs[word + 1]; bit = last_bit & (BITS_PER_INT - 1); @@ -66,8 +66,8 @@ int bit_get_next(bitset_t bs, int last_bit) if ((bit = _test_word(test, bit)) >= 0) return (word * BITS_PER_INT) + bit; - last_bit = last_bit - (last_bit & (BITS_PER_INT - 1)) + - BITS_PER_INT; + last_bit = last_bit - (last_bit & (BITS_PER_INT - 1)) + + BITS_PER_INT; } return -1; diff --git a/lib/datastruct/btree.c b/lib/datastruct/btree.c index c27d489e..8e880628 100644 --- a/lib/datastruct/btree.c +++ b/lib/datastruct/btree.c @@ -40,8 +40,7 @@ static uint32_t _shuffle(uint32_t k) #if 1 return ((k & 0xff) << 24 | (k & 0xff00) << 8 | - (k & 0xff0000) >> 8 | - (k & 0xff000000) >> 24); + (k & 0xff0000) >> 8 | (k & 0xff000000) >> 24); #else return k; #endif diff --git a/lib/datastruct/hash.c b/lib/datastruct/hash.c index 3060ddc7..3277f157 100644 --- a/lib/datastruct/hash.c +++ b/lib/datastruct/hash.c @@ -4,7 +4,6 @@ * This file is released under the LGPL. */ - #include "dbg_malloc.h" #include "hash.h" #include "log.h" @@ -23,22 +22,30 @@ struct hash_table { /* Permutation of the Integers 0 through 255 */ static unsigned char _nums[] = { - 1, 14,110, 25, 97,174,132,119,138,170,125,118, 27,233,140, 51, - 87,197,177,107,234,169, 56, 68, 30, 7,173, 73,188, 40, 36, 65, - 49,213,104,190, 57,211,148,223, 48,115, 15, 2, 67,186,210, 28, - 12,181,103, 70, 22, 58, 75, 78,183,167,238,157,124,147,172,144, - 176,161,141, 86, 60, 66,128, 83,156,241, 79, 46,168,198, 41,254, - 178, 85,253,237,250,154,133, 88, 35,206, 95,116,252,192, 54,221, - 102,218,255,240, 82,106,158,201, 61, 3, 89, 9, 42,155,159, 93, - 166, 80, 50, 34,175,195,100, 99, 26,150, 16,145, 4, 33, 8,189, - 121, 64, 77, 72,208,245,130,122,143, 55,105,134, 29,164,185,194, - 193,239,101,242, 5,171,126, 11, 74, 59,137,228,108,191,232,139, - 6, 24, 81, 20,127, 17, 91, 92,251,151,225,207, 21, 98,113,112, - 84,226, 18,214,199,187, 13, 32, 94,220,224,212,247,204,196, 43, - 249,236, 45,244,111,182,153,136,129, 90,217,202, 19,165,231, 71, - 230,142, 96,227, 62,179,246,114,162, 53,160,215,205,180, 47,109, - 44, 38, 31,149,135, 0,216, 52, 63, 23, 37, 69, 39,117,146,184, - 163,200,222,235,248,243,219, 10,152,131,123,229,203, 76,120,209 + 1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51, + 87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65, + 49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28, + 12, 181, 103, 70, 22, 58, 75, 78, 183, 167, 238, 157, 124, 147, 172, + 144, + 176, 161, 141, 86, 60, 66, 128, 83, 156, 241, 79, 46, 168, 198, 41, 254, + 178, 85, 253, 237, 250, 154, 133, 88, 35, 206, 95, 116, 252, 192, 54, + 221, + 102, 218, 255, 240, 82, 106, 158, 201, 61, 3, 89, 9, 42, 155, 159, 93, + 166, 80, 50, 34, 175, 195, 100, 99, 26, 150, 16, 145, 4, 33, 8, 189, + 121, 64, 77, 72, 208, 245, 130, 122, 143, 55, 105, 134, 29, 164, 185, + 194, + 193, 239, 101, 242, 5, 171, 126, 11, 74, 59, 137, 228, 108, 191, 232, + 139, + 6, 24, 81, 20, 127, 17, 91, 92, 251, 151, 225, 207, 21, 98, 113, 112, + 84, 226, 18, 214, 199, 187, 13, 32, 94, 220, 224, 212, 247, 204, 196, + 43, + 249, 236, 45, 244, 111, 182, 153, 136, 129, 90, 217, 202, 19, 165, 231, + 71, + 230, 142, 96, 227, 62, 179, 246, 114, 162, 53, 160, 215, 205, 180, 47, + 109, + 44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184, + 163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120, + 209 }; static struct hash_node *_create_node(const char *str) @@ -83,7 +90,7 @@ struct hash_table *hash_create(unsigned size_hint) /* round size hint up to a power of two */ while (new_size < size_hint) - new_size = new_size << 1; + new_size = new_size << 1; hc->num_slots = new_size; len = sizeof(*(hc->slots)) * new_size; @@ -94,7 +101,7 @@ struct hash_table *hash_create(unsigned size_hint) memset(hc->slots, 0, len); return hc; - bad: + bad: dbg_free(hc->slots); dbg_free(hc); return 0; @@ -124,8 +131,8 @@ static inline struct hash_node **_find(struct hash_table *t, const char *key) unsigned h = _hash(key) & (t->num_slots - 1); struct hash_node **c; - for(c = &t->slots[h]; *c; c = &((*c)->next)) - if(!strcmp(key, (*c)->key)) + for (c = &t->slots[h]; *c; c = &((*c)->next)) + if (!strcmp(key, (*c)->key)) break; return c; @@ -141,7 +148,7 @@ int hash_insert(struct hash_table *t, const char *key, void *data) { struct hash_node **c = _find(t, key); - if(*c) + if (*c) (*c)->data = data; else { struct hash_node *n = _create_node(key); @@ -223,4 +230,3 @@ struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n) unsigned int h = _hash(n->key) & (t->num_slots - 1); return n->next ? n->next : _next_slot(t, h + 1); } - diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c index 42f3d2f2..fcc42805 100644 --- a/lib/device/dev-cache.c +++ b/lib/device/dev-cache.c @@ -46,7 +46,6 @@ static struct { } _cache; - #define _alloc(x) pool_alloc(_cache.mem, (x)) #define _free(x) pool_free(_cache.mem, (x)) @@ -194,7 +193,7 @@ static int _insert(const char *path, int rec) return 0; } - if (S_ISDIR(info.st_mode)) { /* add a directory */ + if (S_ISDIR(info.st_mode)) { /* add a directory */ if (rec) r = _insert_dir(path); @@ -255,7 +254,7 @@ int dev_cache_init(void) return 1; - bad: + bad: dev_cache_exit(); return 0; } @@ -268,7 +267,7 @@ void _check_closed(struct device *dev) static inline void _check_for_open_devices(void) { - hash_iter(_cache.names, (iterate_fn)_check_closed); + hash_iter(_cache.names, (iterate_fn) _check_closed); } void dev_cache_exit(void) @@ -313,8 +312,8 @@ const char *dev_name_confirmed(struct device *dev) char *name; int r; - while ((r = stat(name = list_item(dev->aliases.n, - struct str_list)->str, &buf)) || + while ((r = stat(name = list_item(dev->aliases.n, + struct str_list)->str, &buf)) || (buf.st_rdev != dev->dev)) { if (r < 0) log_sys_error("stat", name); @@ -342,7 +341,6 @@ const char *dev_name_confirmed(struct device *dev) return dev_name(dev); } - struct device *dev_cache_get(const char *name, struct dev_filter *f) { struct stat buf; @@ -399,4 +397,3 @@ struct device *dev_iter_get(struct dev_iter *iter) return NULL; } - diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c index 79b8a128..a8f24a72 100644 --- a/lib/device/dev-io.c +++ b/lib/device/dev-io.c @@ -13,9 +13,9 @@ #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> -#include <linux/fs.h> // UGH!!! for BLKSSZGET +#include <linux/fs.h> // UGH!!! for BLKSSZGET -int dev_get_size(struct device *dev, uint64_t *size) +int dev_get_size(struct device *dev, uint64_t * size) { int fd; long s; @@ -39,7 +39,7 @@ int dev_get_size(struct device *dev, uint64_t *size) return 1; } -int dev_get_sectsize(struct device *dev, uint32_t *size) +int dev_get_sectsize(struct device *dev, uint32_t * size) { int fd; int s; @@ -93,6 +93,8 @@ int dev_open(struct device *dev, int flags) return 0; } + dev->flags = 0; + return 1; } @@ -109,7 +111,8 @@ int dev_close(struct device *dev) return 0; } - _flush(dev->fd); + if (dev->flags & DEV_ACCESSED_W) + _flush(dev->fd); if (close(dev->fd)) log_sys_error("close", dev_name(dev)); @@ -142,7 +145,7 @@ int _read(int fd, void *buf, size_t count) return tot; } -int64_t dev_read(struct device *dev, uint64_t offset, +int64_t dev_read(struct device * dev, uint64_t offset, int64_t len, void *buffer) { const char *name = dev_name(dev); @@ -185,7 +188,7 @@ int _write(int fd, const void *buf, size_t count) return tot; } -int64_t dev_write(struct device *dev, uint64_t offset, +int64_t dev_write(struct device * dev, uint64_t offset, int64_t len, void *buffer) { const char *name = dev_name(dev); @@ -201,6 +204,8 @@ int64_t dev_write(struct device *dev, uint64_t offset, return 0; } + dev->flags |= DEV_ACCESSED_W; + return _write(fd, buffer, len); } @@ -237,6 +242,8 @@ int dev_zero(struct device *dev, uint64_t offset, int64_t len) } } + dev->flags |= DEV_ACCESSED_W; + /* FIXME: Always display error */ return (len == 0); } diff --git a/lib/device/device.c b/lib/device/device.c index a410a17c..12c5e226 100644 --- a/lib/device/device.c +++ b/lib/device/device.c @@ -38,8 +38,6 @@ #include <linux/major.h> #include <linux/genhd.h> - - #if 0 int _get_partition_type(struct dev_filter *filter, struct device *d); diff --git a/lib/device/device.h b/lib/device/device.h index 794f7eff..6d165e96 100644 --- a/lib/device/device.h +++ b/lib/device/device.h @@ -10,6 +10,8 @@ #include "lvm-types.h" #include "list.h" +#define DEV_ACCESSED_W 0x00000001 /* Device written to? */ + /* * All devices in LVM will be represented by one of these. * pointer comparisons are valid. @@ -20,6 +22,7 @@ struct device { /* private */ int fd; + uint32_t flags; }; struct device_list { diff --git a/lib/display/display.c b/lib/display/display.c index ebf1d7e8..989feb11 100644 --- a/lib/display/display.c +++ b/lib/display/display.c @@ -79,12 +79,12 @@ void pvdisplay_colons(struct physical_volume *pv) dev_name(pv->dev), pv->vg_name, pv->size, /* FIXME pv->pv_number, Derive or remove? */ pv->status, /* FIXME Support old or new format here? */ - pv->status & ALLOCATABLE_PV, /* FIXME remove? */ + pv->status & ALLOCATABLE_PV, /* FIXME remove? */ /* FIXME pv->lv_cur, Remove? */ pv->pe_size / 2, pv->pe_count, - pv->pe_count - pv->pe_allocated, - pv->pe_allocated, *uuid ? uuid : "none"); + pv->pe_count - pv->pe_alloc_count, + pv->pe_alloc_count, *uuid ? uuid : "none"); return; } @@ -131,7 +131,7 @@ void pvdisplay_full(struct physical_volume *pv) log_print("PV# %u", pv->pv_number); **********/ - pe_free = pv->pe_count - pv->pe_allocated; + pe_free = pv->pe_count - pv->pe_alloc_count; if (pv->pe_count && (pv->status & ALLOCATABLE_PV)) log_print("Allocatable yes %s", (!pe_free && pv->pe_count) ? "(but full)" : ""); @@ -144,7 +144,7 @@ void pvdisplay_full(struct physical_volume *pv) log_print("PE Size (KByte) %" PRIu64, pv->pe_size / 2); log_print("Total PE %u", pv->pe_count); log_print("Free PE %" PRIu64, pe_free); - log_print("Allocated PE %u", pv->pe_allocated); + log_print("Allocated PE %u", pv->pe_alloc_count); #ifdef LVM_FUTURE printf("Stale PE %u", pv->pe_stale); @@ -156,7 +156,8 @@ void pvdisplay_full(struct physical_volume *pv) return; } -int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, struct physical_volume *pv) +int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, + struct physical_volume *pv) { if (!pv) return 0; @@ -166,7 +167,7 @@ int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, struct phy log_print("PV Status %sallocatable", (pv->status & ALLOCATABLE_PV) ? "" : "NOT "); log_print("Total PE / Free PE %u / %u", - pv->pe_count, pv->pe_count - pv->pe_allocated); + pv->pe_count, pv->pe_count - pv->pe_alloc_count); log_print(" "); return 0; @@ -183,16 +184,13 @@ void lvdisplay_colons(struct logical_volume *lv) lv->vg->name, lv->name, lv->vg->name, - (lv->status & (LVM_READ | LVM_WRITE)) >> 8, - inkernel ? 1 : 0, + (lv->status & (LVM_READ | LVM_WRITE)) >> 8, inkernel ? 1 : 0, /* FIXME lv->lv_number, */ inkernel ? info.open_count : 0, lv->size, lv->le_count, /* FIXME Add num allocated to struct! lv->lv_allocated_le, */ ((lv->status & ALLOC_STRICT) + (lv->status & ALLOC_CONTIGUOUS) * 2), lv->read_ahead, - inkernel ? info.major : -1, - inkernel ? info.minor : -1 - ); + inkernel ? info.major : -1, inkernel ? info.minor : -1); return; } @@ -275,7 +273,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) log_print("LV Status suspended"); else log_print("LV Status %savailable", - inkernel ? "" : "NOT "); + inkernel ? "" : "NOT "); /********* FIXME lv_number log_print("LV # %u", lv->lv_number + 1); @@ -380,7 +378,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) *************/ if (inkernel) - log_print("Block device %d:%d", info.major, + log_print("Block device %d:%d", info.major, info.minor); log_print(" "); @@ -397,7 +395,7 @@ void _display_stripe(struct stripe_segment *seg, int s, const char *pre) if (seg->area[s].pv) log_print("%sphysical extents\t%d to %d", pre, - seg->area[s].pe, seg->area[s].pe + len - 1); + seg->area[s].pe, seg->area[s].pe + len - 1); } int lvdisplay_segments(struct logical_volume *lv) @@ -408,7 +406,7 @@ int lvdisplay_segments(struct logical_volume *lv) log_print("--- Segments ---"); - list_iterate (segh, &lv->segments) { + list_iterate(segh, &lv->segments) { seg = list_item(segh, struct stripe_segment); log_print("logical extent %d to %d:", @@ -433,8 +431,6 @@ int lvdisplay_segments(struct logical_volume *lv) return 1; } - - void vgdisplay_extents(struct volume_group *vg) { return; @@ -482,7 +478,9 @@ void vgdisplay_full(struct volume_group *vg) log_print ( "Act PV %u", vg->pv_act); *********/ - s1 = display_size((uint64_t) vg->extent_count * (vg->extent_size / 2), SIZE_SHORT); + s1 = + display_size((uint64_t) vg->extent_count * (vg->extent_size / 2), + SIZE_SHORT); log_print("VG Size %s", s1); dbg_free(s1); @@ -492,15 +490,16 @@ void vgdisplay_full(struct volume_group *vg) log_print("Total PE %u", vg->extent_count); - s1 = - display_size(((uint64_t) - vg->extent_count - vg->free_count) * + s1 = display_size(((uint64_t) + vg->extent_count - vg->free_count) * (vg->extent_size / 2), SIZE_SHORT); log_print("Alloc PE / Size %u / %s", vg->extent_count - vg->free_count, s1); dbg_free(s1); - s1 = display_size((uint64_t) vg->free_count * (vg->extent_size / 2), SIZE_SHORT); + s1 = + display_size((uint64_t) vg->free_count * (vg->extent_size / 2), + SIZE_SHORT); log_print("Free PE / Size %u / %s", vg->free_count, s1); dbg_free(s1); diff --git a/lib/filters/filter-composite.c b/lib/filters/filter-composite.c index 5b93e6d5..b388c169 100644 --- a/lib/filters/filter-composite.c +++ b/lib/filters/filter-composite.c @@ -36,7 +36,6 @@ static void _destroy(struct dev_filter *f) dbg_free(f); } - struct dev_filter *composite_filter_create(int n, ...) { struct dev_filter **filters = dbg_malloc(sizeof(*filters) * (n + 1)); diff --git a/lib/filters/filter-persistent.c b/lib/filters/filter-persistent.c index 8c65f8b6..6b6c924b 100644 --- a/lib/filters/filter-persistent.c +++ b/lib/filters/filter-persistent.c @@ -54,7 +54,7 @@ static int _read_array(struct pfilter *pf, struct config_file *cf, if (!(cn = find_config_node(cf->root, path, '/'))) { log_very_verbose("Couldn't find %s array in '%s'", - path, pf->file); + path, pf->file); return 0; } @@ -65,13 +65,13 @@ static int _read_array(struct pfilter *pf, struct config_file *cf, for (cv = cn->v; cv; cv = cv->next) { if (cv->type != CFG_STRING) { log_verbose("Devices array contains a value " - "which is not a string ... ignoring"); + "which is not a string ... ignoring"); continue; } if (!hash_insert(pf->devices, cv->v.str, data)) log_verbose("Couldn't add '%s' to filter ... ignoring", - cv->v.str); + cv->v.str); } return 1; } @@ -101,12 +101,12 @@ int persistent_filter_load(struct dev_filter *f) if (hash_get_num_entries(pf->devices)) r = 1; - out: + out: destroy_config_file(cf); return r; } -static void _write_array(struct pfilter *pf, FILE *fp, const char *path, +static void _write_array(struct pfilter *pf, FILE * fp, const char *path, void *data) { void *d; @@ -175,7 +175,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev) if (!l) { l = pf->real->passes_filter(pf->real, dev) ? - PF_GOOD_DEVICE : PF_BAD_DEVICE; + PF_GOOD_DEVICE : PF_BAD_DEVICE; list_iterate(ah, &dev->aliases) { sl = list_item(ah, struct str_list); @@ -232,7 +232,7 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real, return f; - bad: + bad: dbg_free(pf->file); if (pf->devices) hash_destroy(pf->devices); diff --git a/lib/filters/filter-regex.c b/lib/filters/filter-regex.c index bc8958aa..ae79451d 100644 --- a/lib/filters/filter-regex.c +++ b/lib/filters/filter-regex.c @@ -128,8 +128,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val) * the matcher gives. */ for (v = val, i = count - 1; v; v = v->next, i--) - if (!_extract_pattern(scratch, v->v.str, - regex, rf->accept, i)) { + if (!_extract_pattern(scratch, v->v.str, regex, rf->accept, i)) { log_info("invalid filter pattern"); goto out; } @@ -137,12 +136,12 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val) /* * build the matcher. */ - if (!(rf->engine = matcher_create(rf->mem, - (const char **) regex, count))) + if (!(rf->engine = matcher_create(rf->mem, (const char **) regex, + count))) stack; r = 1; - out: + out: pool_destroy(scratch); return r; } @@ -221,8 +220,7 @@ struct dev_filter *regex_filter_create(struct config_value *patterns) f->private = rf; return f; - bad: + bad: pool_destroy(mem); return NULL; } - diff --git a/lib/filters/filter.c b/lib/filters/filter.c index a2ca7c6f..e6f2e3fc 100644 --- a/lib/filters/filter.c +++ b/lib/filters/filter.c @@ -71,12 +71,12 @@ static int passes_lvm_type_device_filter(struct dev_filter *f, return 0; /* Check it's accessible */ - if ((fd = open(name, O_RDONLY)) < 0) { - log_debug("Unable to open %s: %s", name, strerror(errno)); + if ((fd = open(name, O_RDONLY)) < 0) { + log_debug("Unable to open %s: %s", name, strerror(errno)); return 0; } - close(fd); + close(fd); return 1; } @@ -85,7 +85,7 @@ struct dev_filter *lvm_type_filter_create(const char *proc) { struct dev_filter *f; - if (!(f = dbg_malloc(sizeof (struct dev_filter)))) { + if (!(f = dbg_malloc(sizeof(struct dev_filter)))) { log_error("LVM type filter allocation failed"); return NULL; } @@ -124,12 +124,13 @@ static int *scan_proc_dev(const char *proc) int *max_partitions_by_major; - if (!(max_partitions_by_major = dbg_malloc(sizeof (int) * NUMBER_OF_MAJORS))) { + if (!(max_partitions_by_major = + dbg_malloc(sizeof(int) * NUMBER_OF_MAJORS))) { log_error("Filter failed to allocate max_partitions_by_major"); return NULL; } - if (lvm_snprintf(proc_devices, sizeof(proc_devices), + if (lvm_snprintf(proc_devices, sizeof(proc_devices), "%s/devices", proc) < 0) { log_error("Failed to create /proc/devices string"); return NULL; @@ -140,7 +141,7 @@ static int *scan_proc_dev(const char *proc) return NULL; } - memset(max_partitions_by_major, 0, sizeof (int) * NUMBER_OF_MAJORS); + memset(max_partitions_by_major, 0, sizeof(int) * NUMBER_OF_MAJORS); while (fgets(line, 80, pd) != NULL) { i = 0; while (line[i] == ' ' && line[i] != '\0') @@ -168,7 +169,7 @@ static int *scan_proc_dev(const char *proc) _md_major = line_maj; /* Go through the valid device names and if there is a - match store max number of partitions */ + match store max number of partitions */ for (j = 0; device_info[j].name != NULL; j++) { dev_len = strlen(device_info[j].name); diff --git a/lib/filters/filter.h b/lib/filters/filter.h index 79b59c86..a7a5113b 100644 --- a/lib/filters/filter.h +++ b/lib/filters/filter.h @@ -21,7 +21,7 @@ #ifndef _LVM_FILTER_H #define _LVM_FILTER_H -struct dev_filter *lvm_type_filter_create(const char *); +struct dev_filter *lvm_type_filter_create(const char *proc); void lvm_type_filter_destroy(struct dev_filter *f); 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; } diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c index a53ec931..4b992413 100644 --- a/lib/format_text/archive.c +++ b/lib/format_text/archive.c @@ -23,7 +23,6 @@ #include <fcntl.h> #include <time.h> - /* * The format instance is given a directory path upon creation. * Each file in this directory whose name is of the form @@ -36,7 +35,6 @@ * Backup files that have expired will be removed. */ - /* * A list of these is built up for our volume group. Ordered * with the least recent at the head. @@ -48,12 +46,11 @@ struct archive_file { int index; }; - /* * Extract vg name and version number from a filename. */ static int _split_vg(const char *filename, char *vg, size_t vg_size, - uint32_t *index) + uint32_t * index) { int len, vg_len; char *dot, *underscore; @@ -93,7 +90,7 @@ static void _insert_file(struct list *head, struct archive_file *b) } /* index increases through list */ - list_iterate (bh, head) { + list_iterate(bh, head) { bf = list_item(bh, struct archive_file); if (bf->index > b->index) { @@ -180,7 +177,7 @@ static struct list *_scan_archive(struct pool *mem, _insert_file(results, af); } - out: + out: for (i = 0; i < count; i++) free(dirent[i]); free(dirent); @@ -239,8 +236,7 @@ int archive_vg(struct volume_group *vg, for (i = 0; i < 10; i++) { if (lvm_snprintf(archive_name, sizeof(archive_name), - "%s/%s_%05d.vg", - dir, vg->name, index) < 0) { + "%s/%s_%05d.vg", dir, vg->name, index) < 0) { log_err("archive file name too long."); return 0; } @@ -257,18 +253,28 @@ int archive_vg(struct volume_group *vg, static void _display_archive(struct cmd_context *cmd, struct uuid_map *um, struct archive_file *af) { - struct volume_group *vg; + struct volume_group *vg = NULL; + struct format_instance *tf; time_t when; char *desc; + void *context; log_print("path:\t\t%s", af->path); + if (!(context = create_text_context(cmd->fmtt, af->path, NULL)) || + !(tf = cmd->fmtt->ops->create_instance(cmd->fmtt, NULL, context))) { + log_error("Couldn't create text instance object."); + return; + } + /* * Read the archive file to ensure that it is valid, and * retrieve the archive time and description. */ - if (!(vg = text_vg_import(cmd, af->path, um, &when, &desc))) { + /* FIXME Use variation on _vg_read */ + if (!(vg = text_vg_import(tf, af->path, um, &when, &desc))) { log_print("Unable to read archive file."); + tf->fmt->ops->destroy_instance(tf); return; } @@ -276,6 +282,7 @@ static void _display_archive(struct cmd_context *cmd, struct uuid_map *um, log_print("time:\t\t%s", ctime(&when)); pool_free(cmd->mem, vg); + tf->fmt->ops->destroy_instance(tf); } int archive_list(struct cmd_context *cmd, struct uuid_map *um, @@ -292,7 +299,7 @@ int archive_list(struct cmd_context *cmd, struct uuid_map *um, if (list_empty(archives)) log_print("No archives found."); - list_iterate (ah, archives) { + list_iterate(ah, archives) { af = list_item(ah, struct archive_file); _display_archive(cmd, um, af); diff --git a/lib/format_text/export.c b/lib/format_text/export.c index 86727199..ee707849 100644 --- a/lib/format_text/export.c +++ b/lib/format_text/export.c @@ -16,14 +16,13 @@ #include <stdarg.h> #include <time.h> - /* * The first half of this file deals with * exporting the vg, ie. writing it to a file. */ struct formatter { struct pool *mem; /* pv names allocated from here */ - struct hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */ + struct hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */ FILE *fp; /* where we're writing to */ int indent; /* current level of indentation */ @@ -34,16 +33,14 @@ struct formatter { /* * Formatting functions. */ -static void _out_size(struct formatter *f, uint64_t size, - const char *fmt, ...) - __attribute__ (( format (printf, 3, 4) )); +static void _out_size(struct formatter *f, uint64_t size, const char *fmt, ...) + __attribute__ ((format(printf, 3, 4))); static void _out_hint(struct formatter *f, const char *fmt, ...) - __attribute__ (( format (printf, 2, 3) )); + __attribute__ ((format(printf, 2, 3))); static void _out(struct formatter *f, const char *fmt, ...) - __attribute__ (( format (printf, 2, 3) )); - + __attribute__ ((format(printf, 2, 3))); #define MAX_INDENT 5 static void _inc_indent(struct formatter *f) @@ -116,7 +113,7 @@ static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s) "Gigabytes", "Terrabytes", NULL - }; + }; int i; double d = (double) sectors; @@ -124,7 +121,7 @@ static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s) /* to convert to K */ d /= 2.0; - for (i = 0; (d > 1024.0) && _units[i]; i++) + for (i = 0; (d > 1024.0) && _units[i]; i++) d /= 1024.0; return lvm_snprintf(buffer, s, "# %g %s", d, _units[i]) > 0; @@ -134,8 +131,7 @@ static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s) * Appends a comment giving a size in more easily * readable form (eg, 4M instead of 8096). */ -static void _out_size(struct formatter *f, uint64_t size, - const char *fmt, ...) +static void _out_size(struct formatter *f, uint64_t size, const char *fmt, ...) { char buffer[64]; va_list ap; @@ -200,6 +196,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg) _out(f, "id = \"%s\"", buffer); + _out(f, "seqno = %u", vg->seqno); if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) { stack; return 0; @@ -219,12 +216,11 @@ static int _print_vg(struct formatter *f, struct volume_group *vg) * Get the pv%d name from the formatters hash * table. */ -static inline const char * -_get_pv_name(struct formatter *f, struct physical_volume *pv) +static inline const char *_get_pv_name(struct formatter *f, + struct physical_volume *pv) { return (pv) ? (const char *) - hash_lookup(f->pv_names, dev_name(pv->dev)) : - "Missing"; + hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing"; } static int _print_pvs(struct formatter *f, struct volume_group *vg) @@ -237,7 +233,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) _out(f, "physical_volumes {"); _inc_indent(f); - list_iterate (pvh, &vg->pvs) { + list_iterate(pvh, &vg->pvs) { pv = list_item(pvh, struct pv_list)->pv; @@ -259,8 +255,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) _out_hint(f, "device = \"%s\"", dev_name(pv->dev)); _nl(f); - if (!print_flags(pv->status, PV_FLAGS, - buffer, sizeof(buffer))) { + if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) { stack; return 0; } @@ -324,8 +319,8 @@ static int _count_segments(struct logical_volume *lv) int r = 0; struct list *segh; - list_iterate (segh, &lv->segments) - r++; + list_iterate(segh, &lv->segments) + r++; return r; } @@ -347,7 +342,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) _out(f, "logical_volumes {"); _inc_indent(f); - list_iterate (lvh, &vg->lvs) { + list_iterate(lvh, &vg->lvs) { lv = list_item(lvh, struct lv_list)->lv; _nl(f); @@ -362,8 +357,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) _out(f, "id = \"%s\"", buffer); - if (!print_flags(lv->status, LV_FLAGS, - buffer, sizeof(buffer))) { + if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) { stack; return 0; } @@ -376,7 +370,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) _nl(f); seg_count = 1; - list_iterate (segh, &lv->segments) { + list_iterate(segh, &lv->segments) { seg = list_item(segh, struct stripe_segment); if (!_print_segment(f, vg, seg_count++, seg)) { @@ -428,7 +422,7 @@ static int _print_snapshots(struct formatter *f, struct volume_group *vg) _out(f, "snapshots {"); _inc_indent(f); - list_iterate (sh, &vg->snapshots) { + list_iterate(sh, &vg->snapshots) { s = list_item(sh, struct snapshot_list)->snapshot; if (!_print_snapshot(f, s, count++)) { @@ -448,8 +442,7 @@ static int _print_snapshots(struct formatter *f, struct volume_group *vg) * 'pv2' etc. This function builds a hash table * to enable a quick lookup from device -> name. */ -static int _build_pv_names(struct formatter *f, - struct volume_group *vg) +static int _build_pv_names(struct formatter *f, struct volume_group *vg) { int count = 0; struct list *pvh; @@ -466,11 +459,10 @@ static int _build_pv_names(struct formatter *f, goto bad; } - list_iterate (pvh, &vg->pvs) { + list_iterate(pvh, &vg->pvs) { pv = list_item(pvh, struct pv_list)->pv; - if (lvm_snprintf(buffer, sizeof(buffer), - "pv%d", count++) < 0) { + if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) { stack; goto bad; } @@ -488,7 +480,7 @@ static int _build_pv_names(struct formatter *f, return 1; - bad: + bad: if (f->mem) pool_destroy(f->mem); @@ -498,7 +490,7 @@ static int _build_pv_names(struct formatter *f, return 0; } -int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc) +int text_vg_export(FILE * fp, struct volume_group *vg, const char *desc) { int r = 0; struct formatter *f; @@ -516,7 +508,6 @@ int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc) stack; goto out; } - #define fail do {stack; goto out;} while(0) if (!_print_header(f, vg, desc)) @@ -546,7 +537,7 @@ int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc) _out(f, "}"); r = !ferror(f->fp); - out: + out: if (f->mem) pool_destroy(f->mem); diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c index 7956a343..da0e82e9 100644 --- a/lib/format_text/flags.c +++ b/lib/format_text/flags.c @@ -62,7 +62,7 @@ static struct flag *_get_flags(int type) return NULL; } -static int _emit(char **buffer, size_t *size, const char *fmt, ...) +static int _emit(char **buffer, size_t * size, const char *fmt, ...) { size_t n; va_list ap; @@ -124,7 +124,7 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size) return 1; } -int read_flags(uint32_t *status, int type, struct config_value *cv) +int read_flags(uint32_t * status, int type, struct config_value *cv) { int f; uint32_t s = 0; diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index f4d145d9..076e228e 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -15,11 +15,14 @@ #include "display.h" #include "dbg_malloc.h" #include "toolcontext.h" +#include "vgcache.h" +#include "lvm-string.h" #include <unistd.h> #include <sys/types.h> #include <sys/file.h> #include <limits.h> +#include <dirent.h> /* Arbitrary limits copied from format1/disk_rep.h */ #define MAX_PV 256 @@ -27,16 +30,21 @@ #define MAX_VG 99 #define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */ +struct dir_list { + struct list list; + char dir[0]; +}; + +struct text_context { + char *path_live; /* Path to file holding live metadata */ + char *path_edit; /* Path to file holding edited metadata */ + char *desc; /* Description placed inside file */ +}; + /* * NOTE: Currently there can be only one vg per file. */ -struct text_c { - char *path; - char *desc; - struct uuid_map *um; -}; - static int _pv_setup(struct format_instance *fi, struct physical_volume *pv, struct volume_group *vg) { @@ -61,6 +69,11 @@ static int _vg_setup(struct format_instance *fi, struct volume_group *vg) if (vg->max_pv >= MAX_PV) vg->max_pv = MAX_PV - 1; + if (vg->extent_size & (vg->extent_size - 1)) { + log_error("Extent size must be power of 2"); + return 0; + } + return 1; } @@ -68,6 +81,9 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv) { uint64_t max_size = UINT_MAX; + if (!*lv->lvid.s) + lvid_create(&lv->lvid, &lv->vg->id); + if (lv->size > max_size) { char *dummy = display_size(max_size, SIZE_SHORT); log_error("logical volumes cannot be larger than %s", dummy); @@ -79,14 +95,15 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv) } static struct volume_group *_vg_read(struct format_instance *fi, - const char *vg_name) + const char *vgname, void *mdl) { - struct text_c *tc = (struct text_c *) fi->private; + struct text_context *tc = (struct text_context *) mdl; struct volume_group *vg; time_t when; char *desc; - if (!(vg = text_vg_import(fi->cmd, tc->path, tc->um, &when, &desc))) { + if (!(vg = text_vg_import(fi, tc->path_live, fi->fmt->cmd->um, &when, + &desc))) { stack; return NULL; } @@ -96,32 +113,33 @@ static struct volume_group *_vg_read(struct format_instance *fi, * text file (this restriction may remain). We need to * check that it contains the correct volume group. */ - if (strcmp(vg_name, vg->name)) { - pool_free(fi->cmd->mem, vg); + if (strcmp(vgname, vg->name)) { + pool_free(fi->fmt->cmd->mem, vg); log_err("'%s' does not contain volume group '%s'.", - tc->path, vg_name); + tc->path_live, vgname); return NULL; } return vg; } -static int _vg_write(struct format_instance *fi, struct volume_group *vg) +static int _vg_write(struct format_instance *fi, struct volume_group *vg, + void *mdl) { - struct text_c *tc = (struct text_c *) fi->private; + struct text_context *tc = (struct text_context *) mdl; FILE *fp; int fd; char *slash; char temp_file[PATH_MAX], temp_dir[PATH_MAX]; - slash = rindex(tc->path, '/'); + slash = rindex(tc->path_edit, '/'); if (slash == 0) strcpy(temp_dir, "."); - else if (slash - tc->path < PATH_MAX) { - strncpy(temp_dir, tc->path, slash - tc->path); - temp_dir[slash - tc->path] = '\0'; + else if (slash - tc->path_edit < PATH_MAX) { + strncpy(temp_dir, tc->path_edit, slash - tc->path_edit); + temp_dir[slash - tc->path_edit] = '\0'; } else { log_error("Text format failed to determine directory."); @@ -145,113 +163,196 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg) return 0; } + if (fsync(fd)) { + log_sys_error("fsync", tc->path_edit); + fclose(fp); + return 0; + } + if (fclose(fp)) { - log_sys_error("fclose", tc->path); + log_sys_error("fclose", tc->path_edit); + return 0; + } + + if (rename(temp_file, tc->path_edit)) { + log_error("%s: rename to %s failed: %s", temp_file, + tc->path_edit, strerror(errno)); + return 0; + } + + return 1; +} + +static int _pv_commit(struct format_instance *fi, struct physical_volume *pv, + void *mdl) +{ + // struct text_context *tc = (struct text_context *) mdl; + + return 1; +} + +static int _vg_commit(struct format_instance *fi, struct volume_group *vg, + void *mdl) +{ + struct text_context *tc = (struct text_context *) mdl; + + if (rename(tc->path_edit, tc->path_live)) { + log_error("%s: rename to %s failed: %s", tc->path_edit, + tc->path_edit, strerror(errno)); return 0; } - if (rename(temp_file, tc->path)) { - log_error("%s: rename to %s failed: %s", temp_file, tc->path, - strerror(errno)); + sync(); + + return 1; +} + +static int _vg_remove(struct format_instance *fi, struct volume_group *vg, + void *mdl) +{ + struct text_context *tc = (struct text_context *) mdl; + + if (path_exists(tc->path_edit) && unlink(tc->path_edit)) { + log_sys_error("unlink", tc->path_edit); return 0; } + if (path_exists(tc->path_live) && unlink(tc->path_live)) { + log_sys_error("unlink", tc->path_live); + return 0; + } + + sync(); + return 1; } -static struct list *_get_vgs(struct format_instance *fi) +/* Add vgname to list if it's not already there */ +static int _add_vgname(struct format_type *fmt, struct list *names, + char *vgname) { - struct text_c *tc = (struct text_c *) fi->private; - struct list *names = pool_alloc(fi->cmd->mem, sizeof(*names)); + struct list *nlh; struct name_list *nl; - struct volume_group *vg; - char *slash; - char *vgname; - if (!names) { - stack; - return NULL; + list_iterate(nlh, names) { + nl = list_item(nlh, struct name_list); + if (!strcmp(vgname, nl->name)) + return 1; } - list_init(names); + vgcache_add(vgname, NULL, NULL, fmt); - /* Determine the VG name from the file name */ - slash = rindex(tc->path, '/'); - if (slash) { - vgname = pool_alloc(fi->cmd->mem, strlen(slash)); - strcpy(vgname, slash + 1); - } else { - vgname = pool_alloc(fi->cmd->mem, strlen(tc->path) + 1); - strcpy(vgname, tc->path); + if (!(nl = pool_alloc(fmt->cmd->mem, sizeof(*nl)))) { + stack; + return 0; } - vg = _vg_read(fi, vgname); - if (vg) { + if (!(nl->name = pool_strdup(fmt->cmd->mem, vgname))) { + log_error("strdup %s failed", vgname); + return 0; + } - pool_free(fi->cmd->mem, vg); - if (!(nl = pool_alloc(fi->cmd->mem, sizeof(*nl)))) { - stack; - goto bad; - } - nl->name = vgname; + list_add(names, &nl->list); + return 1; +} - list_add(names, &nl->list); +static struct list *_get_vgs(struct format_type *fmt, struct list *names) +{ + struct dirent *dirent; + struct dir_list *dl; + struct list *dlh, *dir_list; + char *tmp; + DIR *d; + + dir_list = (struct list *) fmt->private; + + list_iterate(dlh, dir_list) { + dl = list_item(dlh, struct dir_list); + if (!(d = opendir(dl->dir))) { + log_sys_error("opendir", dl->dir); + continue; + } + while ((dirent = readdir(d))) + if (strcmp(dirent->d_name, ".") && + strcmp(dirent->d_name, "..") && + (!(tmp = strstr(dirent->d_name, ".tmp")) || + tmp != dirent->d_name + strlen(dirent->d_name) + - 4)) + if (!_add_vgname(fmt, names, dirent->d_name)) + return NULL; + + if (closedir(d)) + log_sys_error("closedir", dl->dir); } return names; - - bad: - pool_free(fi->cmd->mem, names); - return NULL; } -static struct list *_get_pvs(struct format_instance *fi) +static struct list *_get_pvs(struct format_type *fmt, struct list *results) { - struct pv_list *pvl; + struct pv_list *pvl, *rhl; struct list *vgh; struct list *pvh; - struct list *results = pool_alloc(fi->cmd->mem, sizeof(*results)); - struct list *vgs = _get_vgs(fi); + struct list *names = pool_alloc(fmt->cmd->mem, sizeof(*names)); + struct list *rh; + struct name_list *nl; + struct volume_group *vg; - list_init(results); + list_init(names); + if (!_get_vgs(fmt, names)) { + stack; + return NULL; + } - list_iterate(vgh, vgs) { - struct volume_group *vg; - struct name_list *nl; + list_iterate(vgh, names) { nl = list_item(vgh, struct name_list); - vg = _vg_read(fi, nl->name); - if (vg) { - list_iterate(pvh, &vg->pvs) { - struct pv_list *vgpv = - list_item(pvh, struct pv_list); - - pvl = pool_alloc(fi->cmd->mem, sizeof(*pvl)); - if (!pvl) { - stack; - goto bad; + if (!(vg = vg_read(fmt->cmd, nl->name))) { + log_error("format_text: _get_pvs failed to read VG %s", + nl->name); + continue; + } + /* FIXME Use temp hash! */ + list_iterate(pvh, &vg->pvs) { + pvl = list_item(pvh, struct pv_list); + + /* If in use, remove from list of orphans */ + list_iterate(rh, results) { + rhl = list_item(rh, struct pv_list); + if (id_equal(&rhl->pv->id, &pvl->pv->id)) { + if (*rhl->pv->vg_name) + log_err("PV %s in two VGs " + "%s and %s", + dev_name(rhl->pv->dev), + rhl->pv->vg_name, + vg->name); + else + memcpy(&rhl->pv, &pvl->pv, + sizeof(struct + physical_volume)); } - /* ?? do we need to clone the pv structure...really? Nah. */ - pvl->pv = vgpv->pv; - list_add(results, &pvl->list); } } } - return results; - bad: - pool_free(fi->cmd->mem, vgs); - return NULL; + pool_free(fmt->cmd->mem, names); + return results; } -static int _pv_write(struct format_instance *fi, struct physical_volume *pv) +static int _pv_write(struct format_instance *fi, struct physical_volume *pv, + void *mdl) { + /* No on-disk PV structure change required! */ + /* FIXME vgcache could be wrong */ + return 1; + //return (fi->fmt->cmd->fmt1->ops->pv_write(fi, pv, NULL)); +/*** FIXME Not required? struct volume_group *vg; struct list *pvh; vg = _vg_read(fi, pv->vg_name); - /* Find the PV in this VG */ + // Find the PV in this VG if (vg) { list_iterate(pvh, &vg->pvs) { struct pv_list *vgpv = list_item(pvh, struct pv_list); @@ -260,85 +361,190 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv) vgpv->pv->status = pv->status; vgpv->pv->size = pv->size; - /* Not sure if it's worth doing these */ + // Not sure if it's worth doing these vgpv->pv->pe_size = pv->pe_size; vgpv->pv->pe_count = pv->pe_count; vgpv->pv->pe_start = pv->pe_start; - vgpv->pv->pe_allocated = pv->pe_allocated; + vgpv->pv->pe_alloc_count = pv->pe_alloc_count; - /* Write it back */ + // Write it back _vg_write(fi, vg); - pool_free(fi->cmd->mem, vg); + pool_free(fi->fmt->cmd->mem, vg); return 1; } } - pool_free(fi->cmd->mem, vg); + pool_free(fi->fmt->cmd->mem, vg); } - /* Can't handle PVs not in a VG */ + // Can't handle PVs not in a VG return 0; +***/ } -static struct physical_volume *_pv_read(struct format_instance *fi, - const char *pv_name) +static int _pv_read(struct format_type *fmt, const char *pv_name, + struct physical_volume *pv) { - struct list *vgs = _get_vgs(fi); + struct pv_list *pvl; struct list *vgh; struct list *pvh; - struct physical_volume *pv; + struct list *names = pool_alloc(fmt->cmd->mem, sizeof(*names)); + struct name_list *nl; + struct volume_group *vg; + struct id *id; + + /* FIXME Push up to pv_read */ + if (!(id = uuid_map_lookup_label(fmt->cmd->mem, fmt->cmd->um, pv_name))) { + stack; + return 0; + } + + list_init(names); + if (!_get_vgs(fmt, names)) { + stack; + return 0; + } - /* Look for the PV */ - list_iterate(vgh, vgs) { - struct volume_group *vg; - struct name_list *nl; + list_iterate(vgh, names) { nl = list_item(vgh, struct name_list); - vg = _vg_read(fi, nl->name); - if (vg) { - list_iterate(pvh, &vg->pvs) { - struct pv_list *vgpv = - list_item(pvh, struct pv_list); - - if (!strcmp(dev_name(vgpv->pv->dev), pv_name)) { - pv = pool_alloc(fi->cmd->mem, - sizeof(*pv)); - if (!pv) { - stack; - pool_free(fi->cmd->mem, vg); - return NULL; - } - /* Memberwise copy */ - *pv = *vgpv->pv; - - pv->vg_name = - pool_alloc(fi->cmd->mem, - strlen(vgpv->pv-> - vg_name) + 1); - if (!pv->vg_name) { - stack; - pool_free(fi->cmd->mem, vg); - return NULL; - } - strcpy(pv->vg_name, vgpv->pv->vg_name); - pool_free(fi->cmd->mem, vg); - return pv; - } + if (!(vg = vg_read(fmt->cmd, nl->name))) { + log_error("format_text: _pv_read failed to read VG %s", + nl->name); + return 0; + } + list_iterate(pvh, &vg->pvs) { + pvl = list_item(pvh, struct pv_list); + if (id_equal(&pvl->pv->id, id)) { + memcpy(pv, pvl->pv, sizeof(*pv)); + break; } - pool_free(fi->cmd->mem, vg); } } - return NULL; + pool_free(fmt->cmd->mem, names); + return 1; } -static void _destroy(struct format_instance *fi) +static void _destroy_instance(struct format_instance *fid) { - struct text_c *tc = (struct text_c *) fi->private; + return; +} + +static void _free_dirs(struct list *dir_list) +{ + struct list *dl, *tmp; + + list_iterate_safe(dl, tmp, dir_list) { + list_del(dl); + dbg_free(dl); + } +} + +static void _destroy(struct format_type *fmt) +{ + if (fmt->private) { + _free_dirs((struct list *) fmt->private); + dbg_free(fmt->private); + } + + dbg_free(fmt); +} + +static struct format_instance *_create_text_instance(struct format_type *fmt, + const char *vgname, + void *context) +{ + struct format_instance *fid; + struct metadata_area *mda; + struct dir_list *dl; + struct list *dlh, *dir_list; + char path[PATH_MAX]; + + if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) { + log_error("Couldn't allocate format instance object."); + return NULL; + } + + fid->fmt = fmt; + + list_init(&fid->metadata_areas); + + if (!vgname) { + if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) { + stack; + return NULL; + } + mda->metadata_locn = context; + list_add(&fid->metadata_areas, &mda->list); + } else { + dir_list = (struct list *) fmt->private; + + list_iterate(dlh, dir_list) { + dl = list_item(dlh, struct dir_list); + if (lvm_snprintf(path, PATH_MAX, "%s/%s", + dl->dir, vgname) < 0) { + log_error("Name too long %s/%s", dl->dir, + vgname); + return NULL; + } + + context = create_text_context(fmt, path, NULL); + if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) { + stack; + return NULL; + } + mda->metadata_locn = context; + list_add(&fid->metadata_areas, &mda->list); + } + } + + return fid; - dbg_free(tc->path); - dbg_free(tc->desc); - dbg_free(tc); - dbg_free(fi); +} + +void *create_text_context(struct format_type *fmt, const char *path, + const char *desc) +{ + struct text_context *tc; + char *tmp; + + if ((tmp = strstr(path, ".tmp")) && (tmp == path + strlen(path) - 4)) { + log_error("%s: Volume group filename may not end in .tmp", + path); + return NULL; + } + + if (!(tc = pool_alloc(fmt->cmd->mem, sizeof(*tc)))) { + stack; + return NULL; + } + + if (!(tc->path_live = pool_strdup(fmt->cmd->mem, path))) { + stack; + goto no_mem; + } + + if (!(tc->path_edit = pool_alloc(fmt->cmd->mem, strlen(path) + 5))) { + stack; + goto no_mem; + } + sprintf(tc->path_edit, "%s.tmp", path); + + if (!desc) + desc = ""; + + if (!(tc->desc = pool_strdup(fmt->cmd->mem, desc))) { + stack; + goto no_mem; + } + + return (void *) tc; + + no_mem: + pool_free(fmt->cmd->mem, tc); + + log_err("Couldn't allocate text format context object."); + return NULL; } static struct format_handler _text_handler = { @@ -347,62 +553,86 @@ static struct format_handler _text_handler = { pv_read: _pv_read, pv_setup: _pv_setup, pv_write: _pv_write, + pv_commit: _pv_commit, vg_setup: _vg_setup, lv_setup: _lv_setup, vg_read: _vg_read, vg_write: _vg_write, + vg_remove: _vg_remove, + vg_commit: _vg_commit, + create_instance:_create_text_instance, + destroy_instance:_destroy_instance, destroy: _destroy }; -struct format_instance *text_format_create(struct cmd_context *cmd, - const char *file, - struct uuid_map *um, - const char *desc) +static int _add_dir(const char *dir, struct list *dir_list) { - struct format_instance *fi; - char *path, *d; - struct text_c *tc; + struct dir_list *dl; - if (!(fi = dbg_malloc(sizeof(*fi)))) { - stack; - goto no_mem; + if (create_dir(dir)) { + if (!(dl = dbg_malloc(sizeof(struct list) + strlen(dir) + 1))) { + log_error("_add_dir allocation failed"); + return 0; + } + strcpy(dl->dir, dir); + list_add(dir_list, &dl->list); + return 1; } - if (!(path = dbg_strdup(file))) { - stack; - goto no_mem; - } + return 0; +} - if (!(d = dbg_strdup(desc))) { +struct format_type *create_text_format(struct cmd_context *cmd) +{ + struct format_type *fmt; + struct config_node *cn; + struct config_value *cv; + struct list *dir_list; + + if (!(fmt = dbg_malloc(sizeof(*fmt)))) { stack; - goto no_mem; + return NULL; } - if (!(tc = dbg_malloc(sizeof(*tc)))) { - stack; - goto no_mem; + fmt->cmd = cmd; + fmt->ops = &_text_handler; + fmt->name = FMT_TEXT_NAME; + fmt->features = FMT_SEGMENTS; + + if (!(dir_list = dbg_malloc(sizeof(struct list)))) { + log_error("Failed to allocate dir_list"); + return NULL; } - tc->path = path; - tc->desc = d; - tc->um = um; + list_init(dir_list); + fmt->private = (void *) dir_list; - fi->cmd = cmd; - fi->ops = &_text_handler; - fi->private = tc; + if (!(cn = find_config_node(cmd->cf->root, "metadata/dirs", '/'))) { + log_verbose("metadata/dirs not in config file: Defaulting " + "to /etc/lvm/metadata"); + _add_dir("/etc/lvm/metadata", dir_list); + return fmt; + } - return fi; + for (cv = cn->v; cv; cv = cv->next) { + if (cv->type != CFG_STRING) { + log_error("Invalid string in config file: " + "metadata/dirs"); + goto err; + } - no_mem: - if (fi) - dbg_free(fi); + if (!_add_dir(cv->v.str, dir_list)) { + log_error("Failed to add %s to internal device cache", + cv->v.str); + goto err; + } + } - if (path) - dbg_free(path); + return fmt; - if (d) - dbg_free(path); + err: + _free_dirs(dir_list); - log_err("Couldn't allocate text format object."); + dbg_free(fmt); return NULL; } diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h index 6dbd1844..d5c77c71 100644 --- a/lib/format_text/format-text.h +++ b/lib/format_text/format-text.h @@ -32,9 +32,8 @@ int archive_list(struct cmd_context *cmd, struct uuid_map *um, /* * The text format can read and write a volume_group to a file. */ -struct format_instance *text_format_create(struct cmd_context *cmd, - const char *file, - struct uuid_map *um, - const char *desc); +struct format_type *create_text_format(struct cmd_context *cmd); +void *create_text_context(struct format_type *fmt, const char *path, + const char *desc); #endif diff --git a/lib/format_text/import-export.h b/lib/format_text/import-export.h index ed56e7c3..4e0629e7 100644 --- a/lib/format_text/import-export.h +++ b/lib/format_text/import-export.h @@ -25,7 +25,8 @@ int read_flags(uint32_t *status, int type, struct config_value *cv); int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc); -struct volume_group *text_vg_import(struct cmd_context *cmd, const char *file, +struct volume_group *text_vg_import(struct format_instance *fid, + const char *file, struct uuid_map *um, time_t *when, char **desc); diff --git a/lib/format_text/import.c b/lib/format_text/import.c index fac545bd..a8b28fa7 100644 --- a/lib/format_text/import.c +++ b/lib/format_text/import.c @@ -12,11 +12,10 @@ #include "hash.h" #include "toolcontext.h" - -typedef int (*section_fn)(struct pool *mem, - struct volume_group *vg, struct config_node *pvn, - struct config_node *vgn, struct hash_table *pv_hash, - struct uuid_map *um); +typedef int (*section_fn) (struct format_instance * fid, struct pool * mem, + struct volume_group * vg, struct config_node * pvn, + struct config_node * vgn, + struct hash_table * pv_hash, struct uuid_map * um); #define _read_int32(root, path, result) \ get_config_uint32(root, path, '/', result) @@ -50,11 +49,10 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path) return 1; } -static int _read_pv(struct pool *mem, +static int _read_pv(struct format_instance *fid, struct pool *mem, struct volume_group *vg, struct config_node *pvn, struct config_node *vgn, - struct hash_table *pv_hash, - struct uuid_map *um) + struct hash_table *pv_hash, struct uuid_map *um) { struct physical_volume *pv; struct pv_list *pvl; @@ -134,7 +132,8 @@ static int _read_pv(struct pool *mem, pv->pe_size = vg->extent_size; pv->size = pv->pe_size * (uint64_t) pv->pe_count; - pv->pe_allocated = 0; + pv->pe_alloc_count = 0; + pv->fid = fid; vg->pv_count++; list_add(&vg->pvs, &pvl->list); @@ -148,7 +147,7 @@ static void _insert_segment(struct logical_volume *lv, struct list *segh; struct stripe_segment *comp; - list_iterate (segh, &lv->segments) { + list_iterate(segh, &lv->segments) { comp = list_item(segh, struct stripe_segment); if (comp->le > seg->le) { @@ -178,8 +177,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg, } if (!_read_int32(sn, "stripes", &stripes)) { - log_err("Couldn't read 'stripes' for segment '%s'.", - sn->key); + log_err("Couldn't read 'stripes' for segment '%s'.", sn->key); return 0; } @@ -241,9 +239,8 @@ static int _read_segment(struct pool *mem, struct volume_group *vg, if (!(pv = hash_lookup(pv_hash, cv->v.str))) { log_err("Couldn't find physical volume '%s' for " "segment '%s'.", - cn->v->v.str ? cn->v->v.str : "NULL", - seg_name); - return 0; + cn->v->v.str ? cn->v->v.str : "NULL", seg_name); + return 0; } seg->area[s].pv = pv; @@ -264,7 +261,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg, * Adjust the extent counts in the pv and vg. */ allocated = seg->len / seg->stripes; - pv->pe_allocated += allocated; + pv->pe_alloc_count += allocated; vg->free_count -= allocated; } @@ -336,7 +333,7 @@ static int _read_segments(struct pool *mem, struct volume_group *vg, return 1; } -static int _read_lv(struct pool *mem, +static int _read_lv(struct format_instance *fid, struct pool *mem, struct volume_group *vg, struct config_node *lvn, struct config_node *vgn, struct hash_table *pv_hash, struct uuid_map *um) @@ -367,8 +364,7 @@ static int _read_lv(struct pool *mem, /* FIXME: read full lvid */ if (!_read_id(&lv->lvid.id[1], lvn, "id")) { - log_err("Couldn't read uuid for logical volume %s.", - lv->name); + log_err("Couldn't read uuid for logical volume %s.", lv->name); return 0; } @@ -410,7 +406,7 @@ static int _read_lv(struct pool *mem, return 1; } -static int _read_snapshot(struct pool *mem, +static int _read_snapshot(struct format_instance *fid, struct pool *mem, struct volume_group *vg, struct config_node *sn, struct config_node *vgn, struct hash_table *pv_hash, struct uuid_map *um) @@ -459,12 +455,12 @@ static int _read_snapshot(struct pool *mem, return 1; } -static int _read_sections(const char *section, section_fn fn, +static int _read_sections(struct format_instance *fid, + 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, - int optional) + struct uuid_map *um, int optional) { struct config_node *n; @@ -478,7 +474,7 @@ static int _read_sections(const char *section, section_fn fn, } for (n = n->child; n; n = n->sib) { - if (!fn(mem, vg, n, vgn, pv_hash, um)) { + if (!fn(fid, mem, vg, n, vgn, pv_hash, um)) { stack; return 0; } @@ -487,18 +483,17 @@ static int _read_sections(const char *section, section_fn fn, return 1; } -static struct volume_group *_read_vg(struct cmd_context *cmd, +static struct volume_group *_read_vg(struct format_instance *fid, struct config_file *cf, struct uuid_map *um) { struct config_node *vgn, *cn; struct volume_group *vg; struct hash_table *pv_hash = NULL; - struct pool *mem = cmd->mem; + struct pool *mem = fid->fmt->cmd->mem; /* skip any top-level values */ - for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib) - ; + for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib) ; if (!vgn) { log_err("Couldn't find volume group in file."); @@ -509,7 +504,11 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, stack; return NULL; } - vg->cmd = cmd; + vg->cmd = fid->fmt->cmd; + + /* FIXME Determine format type from file contents */ + /* eg Set to instance of fmt1 here if reading a format1 backup? */ + vg->fid = fid; if (!(vg->name = pool_strdup(mem, vgn->key))) { stack; @@ -532,8 +531,12 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, } if (!_read_id(&vg->id, vgn, "id")) { - log_err("Couldn't read uuid for volume group %s.", - vg->name); + log_err("Couldn't read uuid for volume group %s.", vg->name); + goto bad; + } + + if (!_read_int32(vgn, "seqno", &vg->seqno)) { + log_err("Couldn't read 'seqno' for volume group %s.", vg->name); goto bad; } @@ -582,7 +585,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, } list_init(&vg->pvs); - if (!_read_sections("physical_volumes", _read_pv, mem, vg, + if (!_read_sections(fid, "physical_volumes", _read_pv, mem, vg, vgn, pv_hash, um, 0)) { log_err("Couldn't find all physical volumes for volume " "group %s.", vg->name); @@ -590,7 +593,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, } list_init(&vg->lvs); - if (!_read_sections("logical_volumes", _read_lv, mem, vg, + if (!_read_sections(fid, "logical_volumes", _read_lv, mem, vg, vgn, pv_hash, um, 1)) { log_err("Couldn't read all logical volumes for volume " "group %s.", vg->name); @@ -598,7 +601,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, } list_init(&vg->snapshots); - if (!_read_sections("snapshots", _read_snapshot, mem, vg, + if (!_read_sections(fid, "snapshots", _read_snapshot, mem, vg, vgn, pv_hash, um, 1)) { log_err("Couldn't read all snapshots for volume group %s.", vg->name); @@ -612,7 +615,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, */ return vg; - bad: + bad: if (pv_hash) hash_destroy(pv_hash); @@ -621,7 +624,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, } static void _read_desc(struct pool *mem, - struct config_file *cf, time_t *when, char **desc) + struct config_file *cf, time_t * when, char **desc) { const char *d; unsigned int u = 0u; @@ -633,10 +636,10 @@ static void _read_desc(struct pool *mem, *when = u; } -struct volume_group *text_vg_import(struct cmd_context *cmd, +struct volume_group *text_vg_import(struct format_instance *fid, const char *file, struct uuid_map *um, - time_t *when, char **desc) + time_t * when, char **desc) { struct volume_group *vg = NULL; struct config_file *cf; @@ -654,16 +657,14 @@ struct volume_group *text_vg_import(struct cmd_context *cmd, goto out; } - if (!(vg = _read_vg(cmd, cf, um))) { + if (!(vg = _read_vg(fid, cf, um))) { stack; goto out; } - vg->cmd = cmd; - - _read_desc(cmd->mem, cf, when, desc); + _read_desc(fid->fmt->cmd->mem, cf, when, desc); - out: + out: destroy_config_file(cf); return vg; } diff --git a/lib/label/label.c b/lib/label/label.c index be2bcefa..dcc523ec 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -21,7 +21,6 @@ struct labeller_i { static struct list _labellers; - static struct labeller_i *_alloc_li(const char *name, struct labeller *l) { struct labeller_i *li; @@ -45,7 +44,6 @@ static void _free_li(struct labeller_i *li) dbg_free(li); } - int label_init(void) { list_init(&_labellers); @@ -82,7 +80,7 @@ struct labeller *label_get_handler(const char *name) struct list *lih; struct labeller_i *li; - list_iterate (lih, &_labellers) { + list_iterate(lih, &_labellers) { li = list_item(lih, struct labeller_i); if (!strcmp(li->name, name)) return li->l; @@ -96,7 +94,7 @@ static struct labeller *_find_labeller(struct device *dev) struct list *lih; struct labeller_i *li; - list_iterate (lih, &_labellers) { + list_iterate(lih, &_labellers) { li = list_item(lih, struct labeller_i); if (li->l->ops->can_handle(li->l, dev)) return li->l; @@ -124,7 +122,7 @@ int label_read(struct device *dev, struct label **result) struct list *lih; struct labeller_i *li; - list_iterate (lih, &_labellers) { + list_iterate(lih, &_labellers) { li = list_item(lih, struct labeller_i); if ((r = li->l->ops->read(li->l, dev, result))) { (*result)->labeller = li->l; diff --git a/lib/label/lvm2_label.c b/lib/label/lvm2_label.c index fe19e87e..d02675c0 100644 --- a/lib/label/lvm2_label.c +++ b/lib/label/lvm2_label.c @@ -27,324 +27,337 @@ #define BLOCK_SIZE 512 /* This is just the "struct lvm2_label" with the data pointer removed */ -struct label_ondisk -{ - uint32_t magic; - uint32_t crc; - uint64_t label1_loc; - uint64_t label2_loc; - uint16_t datalen; - uint16_t pad; - - uint32_t version[3]; - char disk_type[32]; +struct label_ondisk { + uint32_t magic; + uint32_t crc; + uint64_t label1_loc; + uint64_t label2_loc; + uint16_t datalen; + uint16_t pad; + + uint32_t version[3]; + char disk_type[32]; }; -struct filter_private -{ - void *mem; - char disk_type[32]; - uint32_t version[3]; - int version_match; +struct filter_private { + void *mem; + char disk_type[32]; + uint32_t version[3]; + int version_match; }; - /* Calculate CRC32 of a buffer */ -static uint32_t crc32(uint32_t initial, const unsigned char *databuf, size_t datalen) +static uint32_t crc32(uint32_t initial, const unsigned char *databuf, + size_t datalen) { - static const u_int crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - uint32_t idx, crc = initial; - - for (idx = 0; idx < datalen; idx++) { - crc ^= *databuf++; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - return crc; + static const u_int crctab[] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + uint32_t idx, crc = initial; + + for (idx = 0; idx < datalen; idx++) { + crc ^= *databuf++; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + } + return crc; } /* Calculate crc */ static uint32_t calc_crc(struct label_ondisk *label, char *data) { - uint32_t crcval = 0xffffffff; - - crcval = crc32(crcval, (char *)&label->magic, sizeof(label->magic)); - crcval = crc32(crcval, (char *)&label->label1_loc, sizeof(label->label1_loc)); - crcval = crc32(crcval, (char *)&label->label2_loc, sizeof(label->label2_loc)); - crcval = crc32(crcval, (char *)&label->datalen, sizeof(label->datalen)); - crcval = crc32(crcval, (char *)&label->version, sizeof(label->version)); - crcval = crc32(crcval, (char *)label->disk_type, strlen(label->disk_type)); - crcval = crc32(crcval, (char *)data, label->datalen); - - return crcval; + uint32_t crcval = 0xffffffff; + + crcval = crc32(crcval, (char *) &label->magic, sizeof(label->magic)); + crcval = + crc32(crcval, (char *) &label->label1_loc, + sizeof(label->label1_loc)); + crcval = + crc32(crcval, (char *) &label->label2_loc, + sizeof(label->label2_loc)); + crcval = + crc32(crcval, (char *) &label->datalen, sizeof(label->datalen)); + crcval = + crc32(crcval, (char *) &label->version, sizeof(label->version)); + crcval = + crc32(crcval, (char *) label->disk_type, strlen(label->disk_type)); + crcval = crc32(crcval, (char *) data, label->datalen); + + return crcval; } /* Calculate the locations we should find the labels in */ -static inline void get_label_locations(uint64_t size, uint32_t sectsize, long *first, long *second) +static inline void get_label_locations(uint64_t size, uint32_t sectsize, + long *first, long *second) { - *first = sectsize; - *second = size*BLOCK_SIZE - sectsize; + *first = sectsize; + *second = size * BLOCK_SIZE - sectsize; } /* Read a label off disk */ -static int lvm2_label_read(struct labeller *l, struct device *dev, struct label **label) +static int lvm2_label_read(struct labeller *l, struct device *dev, + struct label **label) { - uint64_t size; - uint32_t sectsize; - char *block; - struct label_ondisk *ondisk; - int status; - int iter; - long offset[2]; - - if (!dev_get_size(dev, &size)) - return 0; - - if (!dev_get_sectsize(dev, §size)) - return 0; + uint64_t size; + uint32_t sectsize; + char *block; + struct label_ondisk *ondisk; + int status; + int iter; + long offset[2]; + + if (!dev_get_size(dev, &size)) + return 0; - if (!dev_open(dev, O_RDONLY)) - return 0; + if (!dev_get_sectsize(dev, §size)) + return 0; - block = dbg_malloc(sectsize); - if (!block) - { - stack; - return 0; - } - ondisk = (struct label_ondisk *)block; - get_label_locations(size, sectsize, &offset[0], &offset[1]); - - /* If the first label is bad then use the second */ - for (iter = 0; iter <= 1; iter++) - { - status = dev_read(dev, offset[iter], sectsize, block); - if (status) - { - struct label *incore; - int i; - int found_nul; - - /* If the MAGIC doesn't match there's no point in - carrying on */ - if (xlate32(ondisk->magic) != LABEL_MAGIC) - continue; - - /* Look for a NUL in the disk_type string so we don't - SEGV is something has gone horribly wrong */ - found_nul = 0; - for (i=0; i<sizeof(ondisk->disk_type); i++) - if (ondisk->disk_type[i] == '\0') - found_nul = 1; - - if (!found_nul) - continue; - - incore = dbg_malloc(sizeof(struct label)); - if (incore == NULL) - { + if (!dev_open(dev, O_RDONLY)) return 0; - } - - /* Copy and convert endianness */ - strncpy(incore->volume_type, ondisk->disk_type, sizeof(incore->volume_type)); - incore->version[0] = xlate32(ondisk->version[0]); - incore->version[1] = xlate32(ondisk->version[1]); - incore->version[2] = xlate32(ondisk->version[2]); - incore->extra_len = xlate16(ondisk->datalen); - incore->extra_info = block + sizeof(struct label_ondisk); - - /* Make sure datalen is a sensible size too */ - if (incore->extra_len > sectsize) - continue; - - /* Check Crc */ - if (xlate32(ondisk->crc) != calc_crc(ondisk, incore->extra_info)) - { - log_error("Crc %d on device %s does not match. got %x, expected %x", - iter, dev_name(dev), xlate32(ondisk->crc), calc_crc(ondisk, incore->extra_info)); - continue; - } - - /* Check label locations match our view of the device */ - if (xlate64(ondisk->label1_loc) != offset[0]) - log_error("Label 1 location is wrong in label %d - check block size of the device\n", - iter); - if (xlate64(ondisk->label2_loc) != offset[1]) - log_error("Label 2 location is wrong in label %d - the size of the device must have changed\n", - iter); - - /* Copy to user's data area */ - *label = incore; - incore->extra_info = dbg_malloc(incore->extra_len); - if (!incore->extra_info) - { + + block = dbg_malloc(sectsize); + if (!block) { stack; return 0; - } - memcpy(incore->extra_info, block + sizeof(struct label_ondisk), incore->extra_len); - - dbg_free(block); - dev_close(dev); - return 1; } - } + ondisk = (struct label_ondisk *) block; + get_label_locations(size, sectsize, &offset[0], &offset[1]); + + /* If the first label is bad then use the second */ + for (iter = 0; iter <= 1; iter++) { + status = dev_read(dev, offset[iter], sectsize, block); + if (status) { + struct label *incore; + int i; + int found_nul; + + /* If the MAGIC doesn't match there's no point in + carrying on */ + if (xlate32(ondisk->magic) != LABEL_MAGIC) + continue; + + /* Look for a NUL in the disk_type string so we don't + SEGV is something has gone horribly wrong */ + found_nul = 0; + for (i = 0; i < sizeof(ondisk->disk_type); i++) + if (ondisk->disk_type[i] == '\0') + found_nul = 1; + + if (!found_nul) + continue; + + incore = dbg_malloc(sizeof(struct label)); + if (incore == NULL) { + return 0; + } + + /* Copy and convert endianness */ + strncpy(incore->volume_type, ondisk->disk_type, + sizeof(incore->volume_type)); + incore->version[0] = xlate32(ondisk->version[0]); + incore->version[1] = xlate32(ondisk->version[1]); + incore->version[2] = xlate32(ondisk->version[2]); + incore->extra_len = xlate16(ondisk->datalen); + incore->extra_info = + block + sizeof(struct label_ondisk); + + /* Make sure datalen is a sensible size too */ + if (incore->extra_len > sectsize) + continue; + + /* Check Crc */ + if (xlate32(ondisk->crc) != + calc_crc(ondisk, incore->extra_info)) { + log_error + ("Crc %d on device %s does not match. got %x, expected %x", + iter, dev_name(dev), xlate32(ondisk->crc), + calc_crc(ondisk, incore->extra_info)); + continue; + } + + /* Check label locations match our view of the device */ + if (xlate64(ondisk->label1_loc) != offset[0]) + log_error + ("Label 1 location is wrong in label %d - check block size of the device\n", + iter); + if (xlate64(ondisk->label2_loc) != offset[1]) + log_error + ("Label 2 location is wrong in label %d - the size of the device must have changed\n", + iter); + + /* Copy to user's data area */ + *label = incore; + incore->extra_info = dbg_malloc(incore->extra_len); + if (!incore->extra_info) { + stack; + return 0; + } + memcpy(incore->extra_info, + block + sizeof(struct label_ondisk), + incore->extra_len); + + dbg_free(block); + dev_close(dev); + return 1; + } + } - dbg_free(block); - dev_close(dev); + dbg_free(block); + dev_close(dev); - return 0; + return 0; } /* Write a label to a device */ -static int lvm2_label_write(struct labeller *l, struct device *dev, struct label *label) +static int lvm2_label_write(struct labeller *l, struct device *dev, + struct label *label) { - uint64_t size; - uint32_t sectsize; - char *block; - struct label_ondisk *ondisk; - int status1, status2; - long offset[2]; - - if (!dev_get_size(dev, &size)) - return 0; - - if (!dev_get_sectsize(dev, §size)) - return 0; - - /* Can the metata fit in the remaining space ? */ - if (label->extra_len > sectsize - sizeof(struct label_ondisk)) - return 0; + uint64_t size; + uint32_t sectsize; + char *block; + struct label_ondisk *ondisk; + int status1, status2; + long offset[2]; + + if (!dev_get_size(dev, &size)) + return 0; - block = dbg_malloc(sizeof(struct label_ondisk) + label->extra_len); - if (!block) - { - stack; - return 0; - } - ondisk = (struct label_ondisk *)block; - - get_label_locations(size, sectsize, &offset[0], &offset[1]); - - /* Make into ondisk format */ - ondisk->magic = xlate32(LABEL_MAGIC); - ondisk->version[0] = xlate32(label->version[0]); - ondisk->version[1] = xlate32(label->version[1]); - ondisk->version[2] = xlate32(label->version[2]); - ondisk->label1_loc = xlate64(offset[0]); - ondisk->label2_loc = xlate64(offset[1]); - ondisk->datalen = xlate16(label->extra_len); - strncpy(ondisk->disk_type, label->volume_type, sizeof(ondisk->disk_type)); - memcpy(block+sizeof(struct label_ondisk), label->extra_info, label->extra_len); - ondisk->crc = xlate32(calc_crc(ondisk, label->extra_info)); - - /* Write metadata to disk */ - if (!dev_open(dev, O_RDWR)) - { - dbg_free(block); - return 0; - } + if (!dev_get_sectsize(dev, §size)) + return 0; - status1 = dev_write(dev, offset[0], sizeof(struct label_ondisk) + label->extra_len, block); - if (!status1) - log_error("Error writing label 1\n"); + /* Can the metata fit in the remaining space ? */ + if (label->extra_len > sectsize - sizeof(struct label_ondisk)) + return 0; - /* Write another at the end of the device */ - status2 = dev_write(dev, offset[1], sizeof(struct label_ondisk) + label->extra_len, block); - if (!status2) - { - char zerobuf[sizeof(struct label_ondisk)]; - log_error("Error writing label 2\n"); + block = dbg_malloc(sizeof(struct label_ondisk) + label->extra_len); + if (!block) { + stack; + return 0; + } + ondisk = (struct label_ondisk *) block; + + get_label_locations(size, sectsize, &offset[0], &offset[1]); + + /* Make into ondisk format */ + ondisk->magic = xlate32(LABEL_MAGIC); + ondisk->version[0] = xlate32(label->version[0]); + ondisk->version[1] = xlate32(label->version[1]); + ondisk->version[2] = xlate32(label->version[2]); + ondisk->label1_loc = xlate64(offset[0]); + ondisk->label2_loc = xlate64(offset[1]); + ondisk->datalen = xlate16(label->extra_len); + strncpy(ondisk->disk_type, label->volume_type, + sizeof(ondisk->disk_type)); + memcpy(block + sizeof(struct label_ondisk), label->extra_info, + label->extra_len); + ondisk->crc = xlate32(calc_crc(ondisk, label->extra_info)); + + /* Write metadata to disk */ + if (!dev_open(dev, O_RDWR)) { + dbg_free(block); + return 0; + } - /* Wipe the first label so it doesn't get confusing */ - memset(zerobuf, 0, sizeof(struct label_ondisk)); - if (!dev_write(dev, offset[0], sizeof(struct label_ondisk), zerobuf)) - log_error("Error erasing label 1\n"); - } + status1 = + dev_write(dev, offset[0], + sizeof(struct label_ondisk) + label->extra_len, block); + if (!status1) + log_error("Error writing label 1\n"); + + /* Write another at the end of the device */ + status2 = + dev_write(dev, offset[1], + sizeof(struct label_ondisk) + label->extra_len, block); + if (!status2) { + char zerobuf[sizeof(struct label_ondisk)]; + log_error("Error writing label 2\n"); + + /* Wipe the first label so it doesn't get confusing */ + memset(zerobuf, 0, sizeof(struct label_ondisk)); + if (!dev_write + (dev, offset[0], sizeof(struct label_ondisk), + zerobuf)) log_error("Error erasing label 1\n"); + } - dbg_free(block); - dev_close(dev); + dbg_free(block); + dev_close(dev); - return ((status1 != 0) && (status2 != 0)); + return ((status1 != 0) && (status2 != 0)); } - - /* Return 1 for Yes, 0 for No */ static int lvm2_is_labelled(struct labeller *l, struct device *dev) { - struct label *label; - int status; + struct label *label; + int status; - status = lvm2_label_read(l, dev, &label); - if (status) label_free(label); + status = lvm2_label_read(l, dev, &label); + if (status) + label_free(label); - return status; + return status; } /* Check the device is labelled and has the right format_type */ static int _accept_format(struct dev_filter *f, struct device *dev) { - struct label *l; - int status; - struct filter_private *fp = (struct filter_private *) f->private; - - status = lvm2_label_read(NULL, dev, &l); - - if (status) - { - if (strcmp(l->volume_type, fp->disk_type) == 0) - { - switch (fp->version_match) - { - case VERSION_MATCH_EQUAL: - if (l->version[0] == fp->version[0] && - l->version[1] == fp->version[1] && - l->version[2] == fp->version[2]) - return 1; - break; - - case VERSION_MATCH_LESSTHAN: - if (l->version[0] == fp->version[0] && - l->version[1] < fp->version[1]) - return 1; - break; - - case VERSION_MATCH_LESSEQUAL: - if (l->version[0] == fp->version[0] && - l->version[1] <= fp->version[1]) - return 1; - break; - - case VERSION_MATCH_ANY: - return 1; - } + struct label *l; + int status; + struct filter_private *fp = (struct filter_private *) f->private; + + status = lvm2_label_read(NULL, dev, &l); + + if (status) { + if (strcmp(l->volume_type, fp->disk_type) == 0) { + switch (fp->version_match) { + case VERSION_MATCH_EQUAL: + if (l->version[0] == fp->version[0] && + l->version[1] == fp->version[1] && + l->version[2] == fp->version[2]) + return 1; + break; + + case VERSION_MATCH_LESSTHAN: + if (l->version[0] == fp->version[0] && + l->version[1] < fp->version[1]) + return 1; + break; + + case VERSION_MATCH_LESSEQUAL: + if (l->version[0] == fp->version[0] && + l->version[1] <= fp->version[1]) + return 1; + break; + + case VERSION_MATCH_ANY: + return 1; + } + } + label_free(l); } - label_free(l); - } - return 0; + return 0; } /* We just want to know if it's labelled or not */ static int _accept_label(struct dev_filter *f, struct device *dev) { - return lvm2_is_labelled(NULL, dev); + return lvm2_is_labelled(NULL, dev); } static void _destroy(struct dev_filter *f) { - struct filter_private *fp = (struct filter_private *) f->private; + struct filter_private *fp = (struct filter_private *) f->private; } /* A filter to find devices with a particular label type on them */ -struct dev_filter *lvm2_label_format_filter_create(char *disk_type, uint32_t version[3], int match_type) +struct dev_filter *lvm2_label_format_filter_create(char *disk_type, + uint32_t version[3], + int match_type) { - struct pool *mem; + struct pool *mem; struct filter_private *fp; struct dev_filter *f; @@ -353,7 +366,7 @@ struct dev_filter *lvm2_label_format_filter_create(char *disk_type, uint32_t ver match_type != VERSION_MATCH_LESSTHAN && match_type != VERSION_MATCH_LESSEQUAL && match_type != VERSION_MATCH_ANY) - return 0; + return 0; mem = pool_create(10 * 1024); if (!mem) { @@ -362,13 +375,13 @@ struct dev_filter *lvm2_label_format_filter_create(char *disk_type, uint32_t ver } if (!(f = pool_zalloc(mem, sizeof(*f)))) { - stack; - goto bad; + stack; + goto bad; } if (!(fp = pool_zalloc(mem, sizeof(*fp)))) { - stack; - goto bad; + stack; + goto bad; } fp->mem = mem; @@ -383,7 +396,7 @@ struct dev_filter *lvm2_label_format_filter_create(char *disk_type, uint32_t ver return f; - bad: + bad: pool_destroy(mem); return NULL; } @@ -401,13 +414,13 @@ struct dev_filter *lvm2_label_filter_create() } if (!(f = pool_zalloc(mem, sizeof(*f)))) { - stack; - goto bad; + stack; + goto bad; } if (!(fp = pool_zalloc(mem, sizeof(*fp)))) { - stack; - goto bad; + stack; + goto bad; } fp->mem = mem; @@ -417,7 +430,7 @@ struct dev_filter *lvm2_label_filter_create() return f; - bad: + bad: pool_destroy(mem); return NULL; } @@ -425,137 +438,132 @@ struct dev_filter *lvm2_label_filter_create() /* Return 1 if both labels are identical, 0 if not or there was an error */ static int lvm2_labels_match(struct labeller *l, struct device *dev) { - uint64_t size; - uint32_t sectsize; - char *block1; - char *block2; - struct label_ondisk *ondisk1; - struct label_ondisk *ondisk2; - int status = 0; - long offset[2]; - - if (!dev_get_size(dev, &size)) - return 0; + uint64_t size; + uint32_t sectsize; + char *block1; + char *block2; + struct label_ondisk *ondisk1; + struct label_ondisk *ondisk2; + int status = 0; + long offset[2]; + + if (!dev_get_size(dev, &size)) + return 0; - if (!dev_get_sectsize(dev, §size)) - return 0; + if (!dev_get_sectsize(dev, §size)) + return 0; /* Allocate some space for the blocks we are going to read in */ - block1 = dbg_malloc(sectsize); - if (!block1) - { - stack; - return 0; - } + block1 = dbg_malloc(sectsize); + if (!block1) { + stack; + return 0; + } - block2 = dbg_malloc(sectsize); - if (!block2) - { - stack; - dbg_free(block1); - return 0; - } - ondisk1 = (struct label_ondisk *)block1; - ondisk2 = (struct label_ondisk *)block2; + block2 = dbg_malloc(sectsize); + if (!block2) { + stack; + dbg_free(block1); + return 0; + } + ondisk1 = (struct label_ondisk *) block1; + ondisk2 = (struct label_ondisk *) block2; - get_label_locations(size, sectsize, &offset[0], &offset[1]); + get_label_locations(size, sectsize, &offset[0], &offset[1]); - /* Fetch em */ - if (!dev_open(dev, O_RDONLY)) - goto finish; + /* Fetch em */ + if (!dev_open(dev, O_RDONLY)) + goto finish; - if (!dev_read(dev, offset[0], sectsize, block1)) - goto finish; + if (!dev_read(dev, offset[0], sectsize, block1)) + goto finish; - if (!dev_read(dev, offset[1], sectsize, block2)) - goto finish; + if (!dev_read(dev, offset[1], sectsize, block2)) + goto finish; - dev_close(dev); + dev_close(dev); - /* Is it labelled? */ - if (xlate32(ondisk1->magic) != LABEL_MAGIC) - goto finish; + /* Is it labelled? */ + if (xlate32(ondisk1->magic) != LABEL_MAGIC) + goto finish; - /* Compare the whole structs */ - if (memcmp(ondisk1, ondisk2, sizeof(struct label_ondisk)) != 0) - goto finish; + /* Compare the whole structs */ + if (memcmp(ondisk1, ondisk2, sizeof(struct label_ondisk)) != 0) + goto finish; - /* OK, check the data area */ - if (memcmp(block1 + sizeof(struct label_ondisk), - block2 + sizeof(struct label_ondisk), - xlate16(ondisk1->datalen)) != 0) - goto finish; + /* OK, check the data area */ + if (memcmp(block1 + sizeof(struct label_ondisk), + block2 + sizeof(struct label_ondisk), + xlate16(ondisk1->datalen)) != 0) + goto finish; - /* They match !! */ - status = 1; + /* They match !! */ + status = 1; - finish: - dbg_free(block2); - dbg_free(block1); + finish: + dbg_free(block2); + dbg_free(block1); - return status; + return status; } static int lvm2_label_remove(struct labeller *l, struct device *dev) { - uint64_t size; - uint32_t sectsize; - char block[BLOCK_SIZE]; - int status1, status2; - long offset[2]; + uint64_t size; + uint32_t sectsize; + char block[BLOCK_SIZE]; + int status1, status2; + long offset[2]; - if (!dev_get_size(dev, &size)) - return 0; + if (!dev_get_size(dev, &size)) + return 0; - if (!dev_get_sectsize(dev, §size)) - return 0; + if (!dev_get_sectsize(dev, §size)) + return 0; - if (!dev_open(dev, O_RDWR)) - { - dbg_free(block); - return 0; - } + if (!dev_open(dev, O_RDWR)) { + dbg_free(block); + return 0; + } - get_label_locations(size, sectsize, &offset[0], &offset[1]); - memset(block, 0, BLOCK_SIZE); + get_label_locations(size, sectsize, &offset[0], &offset[1]); + memset(block, 0, BLOCK_SIZE); - /* Blank out the first label */ - status1 = dev_write(dev, offset[0], BLOCK_SIZE, block); - if (!status1) - log_error("Error erasing label 1\n"); + /* Blank out the first label */ + status1 = dev_write(dev, offset[0], BLOCK_SIZE, block); + if (!status1) + log_error("Error erasing label 1\n"); - /* ...and the other at the end of the device */ - status2 = dev_write(dev, offset[1], BLOCK_SIZE, block); - if (!status2) - log_error("Error erasing label 2\n"); + /* ...and the other at the end of the device */ + status2 = dev_write(dev, offset[1], BLOCK_SIZE, block); + if (!status2) + log_error("Error erasing label 2\n"); - dev_close(dev); + dev_close(dev); - return ((status1 != 0) && (status2 != 0)); + return ((status1 != 0) && (status2 != 0)); } static void lvm2_label_destroy(struct labeller *l) { } -static struct label_ops handler_ops = -{ - can_handle: lvm2_is_labelled, - write: lvm2_label_write, - remove: lvm2_label_remove, - read: lvm2_label_read, - verify: lvm2_labels_match, - destroy: lvm2_label_destroy, +static struct label_ops handler_ops = { + can_handle: lvm2_is_labelled, + write: lvm2_label_write, + remove: lvm2_label_remove, + read: lvm2_label_read, + verify: lvm2_labels_match, + destroy: lvm2_label_destroy, }; -static struct labeller this_labeller = -{ - private : NULL, - ops : &handler_ops, +static struct labeller this_labeller = { + private: NULL, + ops: &handler_ops, }; /* Don't know how this gets called... */ void lvm2_label_init() { - label_register_handler("LVM2", &this_labeller); + label_register_handler("LVM2", &this_labeller); } diff --git a/lib/label/uuid-map.c b/lib/label/uuid-map.c index 8280579c..0e31021c 100644 --- a/lib/label/uuid-map.c +++ b/lib/label/uuid-map.c @@ -12,12 +12,12 @@ #include "dbg_malloc.h" #include "log.h" #include "label.h" +#include "pool.h" struct uuid_map { struct dev_filter *filter; }; - struct uuid_map *uuid_map_create(struct dev_filter *devices) { struct uuid_map *um; @@ -67,4 +67,33 @@ struct device *uuid_map_lookup(struct uuid_map *um, struct id *id) return dev; } +struct id *uuid_map_lookup_label(struct pool *mem, struct uuid_map *um, + const char *name) +{ + struct device *dev; + struct label *lab; + struct id *id; + + if (!(dev = dev_cache_get(name, um->filter))) { + stack; + return NULL; + } + + if (!label_read(dev, &lab)) { + stack; + return NULL; + } + + if (!(id = pool_alloc(mem, sizeof(*id)))) { + stack; + label_destroy(lab); + return NULL; + } + memcpy(id, &lab->id, sizeof(*id)); + + label_destroy(lab); + + return id; +} + #endif diff --git a/lib/label/uuid-map.h b/lib/label/uuid-map.h index 082905d7..aff7a02f 100644 --- a/lib/label/uuid-map.h +++ b/lib/label/uuid-map.h @@ -9,6 +9,7 @@ #include "uuid.h" #include "dev-cache.h" +#include "pool.h" /* * Holds a mapping from uuid -> device. @@ -22,5 +23,7 @@ void uuid_map_destroy(struct uuid_map *um); * Find the device with a particular uuid. */ struct device *uuid_map_lookup(struct uuid_map *um, struct id *id); +struct id *uuid_map_lookup_label(struct pool *mem, struct uuid_map *um, + const char *name); #endif diff --git a/lib/locking/external_locking.c b/lib/locking/external_locking.c index 414fdc7a..8d33f12c 100644 --- a/lib/locking/external_locking.c +++ b/lib/locking/external_locking.c @@ -25,39 +25,39 @@ #include <signal.h> static void *locking_module = NULL; -static void (*end_fn)(void) = NULL; -static int (*lock_fn)(struct cmd_context *cmd, const char *resource, int flags) = NULL; -static int (*init_fn)(int type, struct config_file *cf) = NULL; +static void (*end_fn) (void) = NULL; +static int (*lock_fn) (struct cmd_context * cmd, const char *resource, + int flags) = NULL; +static int (*init_fn) (int type, struct config_file * cf) = NULL; -static int lock_resource(struct cmd_context *cmd, const char *resource, int flags) +static int lock_resource(struct cmd_context *cmd, const char *resource, + int flags) { - if (lock_fn) - return lock_fn(cmd, resource, flags); - else - return 0; + if (lock_fn) + return lock_fn(cmd, resource, flags); + else + return 0; } - static void fin_external_locking(void) { - if (end_fn) - end_fn(); + if (end_fn) + end_fn(); - dlclose(locking_module); + dlclose(locking_module); - locking_module = NULL; - end_fn = NULL; - lock_fn = NULL; + locking_module = NULL; + end_fn = NULL; + lock_fn = NULL; } int init_external_locking(struct locking_type *locking, struct config_file *cf) { - char _lock_lib[PATH_MAX]; + char _lock_lib[PATH_MAX]; - if (locking_module) - { - log_error("External locking already initialised\n"); - return 1; + if (locking_module) { + log_error("External locking already initialised"); + return 1; } locking->lock_resource = lock_resource; locking->fin_locking = fin_external_locking; @@ -67,51 +67,47 @@ int init_external_locking(struct locking_type *locking, struct config_file *cf) '/', "lvm2_locking.so"), sizeof(_lock_lib)); - /* If there is a module_dir in the config file then look for the locking module in there first and then using the normal dlopen(3) mechanism of looking down LD_LIBRARY_PATH and /lib, /usr/lib. If course, if the library name starts with a slash then just use the name... */ - if (_lock_lib[0] != '/') - { - struct stat st; - char _lock_lib1[PATH_MAX]; - - lvm_snprintf(_lock_lib1, sizeof(_lock_lib1), - "%s/%s", - find_config_str(cf->root, "global/module_dir", - '/', "RUBBISH"), - _lock_lib); - - /* Does it exist ? */ - if (stat(_lock_lib1, &st) == 0) - { - strcpy(_lock_lib, _lock_lib1); - } + if (_lock_lib[0] != '/') { + struct stat st; + char _lock_lib1[PATH_MAX]; + + lvm_snprintf(_lock_lib1, sizeof(_lock_lib1), + "%s/%s", + find_config_str(cf->root, "global/module_dir", + '/', "RUBBISH"), _lock_lib); + + /* Does it exist ? */ + if (stat(_lock_lib1, &st) == 0) { + strcpy(_lock_lib, _lock_lib1); + } } log_very_verbose("Opening locking library %s", _lock_lib); locking_module = dlopen(_lock_lib, RTLD_LAZY); - if (!locking_module) - { - log_error("Unable to open external locking module %s\n", _lock_lib); - return 0; + if (!locking_module) { + log_error("Unable to open external locking module %s", + _lock_lib); + return 0; } /* Get the functions we need */ init_fn = dlsym(locking_module, "init_locking"); lock_fn = dlsym(locking_module, "lock_resource"); - end_fn = dlsym(locking_module, "end_locking"); + end_fn = dlsym(locking_module, "end_locking"); /* Are they all there ? */ - if (!end_fn || !init_fn || !lock_fn) - { - log_error("shared library %s does not contain locking functions\n", _lock_lib); - dlclose(locking_module); - return 0; + if (!end_fn || !init_fn || !lock_fn) { + log_error ("Shared library %s does not contain locking " + "functions", _lock_lib); + dlclose(locking_module); + return 0; } log_verbose("Opened external locking module %s", _lock_lib); diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 441aeed4..4e51c7e8 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -197,6 +197,10 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags) return 0; break; case LCK_LV: + /* Skip if driver isn't loaded */ + /* FIXME Use /proc/misc instead? */ + if (!driver_version(NULL, 0)) + return 1; switch (flags & LCK_TYPE_MASK) { case LCK_UNLOCK: if (!lv_resume_if_active(cmd, resource)) diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index df3aac16..f46c3ab2 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -25,7 +25,7 @@ static void _get_extents(struct stripe_segment *seg) for (s = 0; s < seg->stripes; s++) { pv = seg->area[s].pv; count = seg->len / seg->stripes; - pv->pe_allocated += count; + pv->pe_alloc_count += count; } } @@ -38,8 +38,8 @@ static void _put_extents(struct stripe_segment *seg) pv = seg->area[s].pv; count = seg->len / seg->stripes; - assert(pv->pe_allocated >= count); - pv->pe_allocated -= count; + assert(pv->pe_alloc_count >= count); + pv->pe_alloc_count -= count; } } @@ -58,7 +58,7 @@ static struct stripe_segment *_alloc_segment(struct pool *mem, int stripes) static int _alloc_stripe_area(struct logical_volume *lv, uint32_t stripes, uint32_t stripe_size, - struct pv_area **areas, uint32_t *index) + struct pv_area **areas, uint32_t * index) { uint32_t count = lv->le_count - *index; uint32_t per_area = count / stripes; @@ -117,8 +117,8 @@ static int _alloc_striped(struct logical_volume *lv, struct pv_map *pvm; size_t len; - list_iterate (pvmh, pvms) - pv_count++; + list_iterate(pvmh, pvms) + pv_count++; /* allocate an array of pv_areas, one candidate per pv */ len = sizeof(*areas) * pv_count; @@ -130,7 +130,7 @@ static int _alloc_striped(struct logical_volume *lv, while (allocated != lv->le_count) { index = 0; - list_iterate (pvmh, pvms) { + list_iterate(pvmh, pvms) { pvm = list_item(pvmh, struct pv_map); if (list_empty(&pvm->areas)) @@ -143,8 +143,7 @@ static int _alloc_striped(struct logical_volume *lv, if (index < stripes) { log_error("Insufficient allocatable extents suitable " "for striping for logical volume " - "%s: %u required", - lv->name, lv->le_count); + "%s: %u required", lv->name, lv->le_count); goto out; } @@ -159,19 +158,18 @@ static int _alloc_striped(struct logical_volume *lv, } r = 1; - out: + out: dbg_free(areas); return r; } - /* * The heart of the allocation code. This function takes a * pv_area and allocates it to the lv. If the lv doesn't need * the complete area then the area is split, otherwise the area * is unlinked from the pv_map. */ -static int _alloc_linear_area(struct logical_volume *lv, uint32_t *index, +static int _alloc_linear_area(struct logical_volume *lv, uint32_t * index, struct pv_map *map, struct pv_area *pva) { uint32_t count, remaining; @@ -268,7 +266,7 @@ static int _alloc_simple(struct logical_volume *lv, } } - done: + done: if (allocated != lv->le_count) { log_error("Insufficient allocatable logical extents (%u) " "for logical volume %s: %u required", @@ -396,7 +394,7 @@ struct logical_volume *lv_create(struct format_instance *fi, if (stripes > list_size(acceptable_pvs)) { log_error("Number of stripes (%u) must not exceed " "number of physical volumes (%d)", stripes, - list_size(acceptable_pvs)); + list_size(acceptable_pvs)); return NULL; } @@ -426,7 +424,7 @@ struct logical_volume *lv_create(struct format_instance *fi, lv->status = status; lv->read_ahead = 0; lv->minor = -1; - lv->size = (uint64_t) extents * vg->extent_size; + lv->size = (uint64_t) extents *vg->extent_size; lv->le_count = extents; list_init(&lv->segments); @@ -435,7 +433,7 @@ struct logical_volume *lv_create(struct format_instance *fi, goto bad; } - if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) { + if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) { stack; goto bad; } @@ -445,7 +443,7 @@ struct logical_volume *lv_create(struct format_instance *fi, return lv; - bad: + bad: if (ll) pool_free(cmd->mem, ll); @@ -460,8 +458,7 @@ int lv_reduce(struct format_instance *fi, uint32_t count = extents; for (segh = lv->segments.p; - (segh != &lv->segments) && count; - segh = segh->p) { + (segh != &lv->segments) && count; segh = segh->p) { seg = list_item(segh, struct stripe_segment); if (seg->len <= count) { @@ -481,7 +478,7 @@ int lv_reduce(struct format_instance *fi, lv->le_count -= extents; lv->size = (uint64_t) lv->le_count * lv->vg->extent_size; - if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) { + if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) { stack; return 0; } @@ -492,16 +489,13 @@ int lv_reduce(struct format_instance *fi, int lv_extend(struct format_instance *fi, struct logical_volume *lv, uint32_t stripes, uint32_t stripe_size, - uint32_t extents, - struct list *acceptable_pvs) + uint32_t extents, struct list *acceptable_pvs) { uint32_t old_le_count = lv->le_count; uint64_t old_size = lv->size; lv->le_count += extents; - lv->size += (uint64_t) extents * lv->vg->extent_size; - - /* FIXME: Format1 must ensure stripes is consistent with 1st seg */ + lv->size += (uint64_t) extents *lv->vg->extent_size; if (!_allocate(lv->vg, lv, acceptable_pvs, old_le_count, stripes, stripe_size)) { @@ -516,7 +510,7 @@ int lv_extend(struct format_instance *fi, return 0; } - if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) { + if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) { stack; return 0; } @@ -536,8 +530,8 @@ int lv_remove(struct volume_group *vg, struct logical_volume *lv) } /* iterate through the lv's segments freeing off the pe's */ - list_iterate (segh, &lv->segments) - _put_extents(list_item(segh, struct stripe_segment)); + list_iterate(segh, &lv->segments) + _put_extents(list_item(segh, struct stripe_segment)); vg->lv_count--; vg->free_count += lv->le_count; diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c index 790c57ef..86220046 100644 --- a/lib/metadata/merge.c +++ b/lib/metadata/merge.c @@ -41,7 +41,7 @@ int lv_merge_segments(struct logical_volume *lv) struct list *segh; struct stripe_segment *current, *prev = NULL; - list_iterate (segh, &lv->segments) { + list_iterate(segh, &lv->segments) { current = list_item(segh, struct stripe_segment); if (_merge(prev, current)) diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index a8c7399f..b8a55e65 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -12,6 +12,7 @@ #include "toolcontext.h" #include "lvm-string.h" #include "uuid.h" +#include "vgcache.h" #include <string.h> @@ -20,17 +21,17 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg, { struct pv_list *pvl; struct physical_volume *pv; - struct pool *mem = fi->cmd->mem; + struct pool *mem = fi->fmt->cmd->mem; log_verbose("Adding physical volume '%s' to volume group '%s'", pv_name, vg->name); - if (!(pvl = pool_alloc(mem, sizeof (*pvl)))) { + if (!(pvl = pool_alloc(mem, sizeof(*pvl)))) { log_error("pv_list allocation for '%s' failed", pv_name); return 0; } - if (!(pv = fi->ops->pv_read(fi, pv_name))) { + if (!(pv = pv_read(fi->fmt->cmd, pv_name))) { log_error("Failed to read existing physical volume '%s'", pv_name); return 0; @@ -50,16 +51,20 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg, /* Units of 512-byte sectors */ pv->pe_size = vg->extent_size; + /* FIXME Do proper rounding-up alignment? */ + /* Reserved space for label; this holds 0 for PVs created by LVM1 */ + if (pv->pe_start < PE_ALIGN) + pv->pe_start = PE_ALIGN; + /* * The next two fields should be corrected * by fi->pv_setup. */ - pv->pe_start = 0; - pv->pe_count = pv->size / pv->pe_size; + pv->pe_count = (pv->size - pv->pe_start) / pv->pe_size; - pv->pe_allocated = 0; + pv->pe_alloc_count = 0; - if (!fi->ops->pv_setup(fi, pv, vg)) { + if (!fi->fmt->ops->pv_setup(fi, pv, vg)) { log_error("Format-specific setup of physical volume '%s' " "failed.", pv_name); return 0; @@ -113,42 +118,43 @@ const char *strip_dir(const char *vg_name, const char *dev_dir) return vg_name; } -struct volume_group *vg_create(struct format_instance *fi, const char *vg_name, +struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name, uint32_t extent_size, int max_pv, int max_lv, int pv_count, char **pv_names) { struct volume_group *vg; - struct pool *mem = fi->cmd->mem; + struct pool *mem = cmd->mem; - if (!(vg = pool_alloc(mem, sizeof (*vg)))) { + if (!(vg = pool_zalloc(mem, sizeof(*vg)))) { stack; return NULL; } /* is this vg name already in use ? */ init_partial(1); - if (fi->ops->vg_read(fi, vg_name)) { + if (vg_read(cmd, vg_name)) { log_err("A volume group called '%s' already exists.", vg_name); goto bad; } init_partial(0); 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; } /* Strip dev_dir if present */ - vg_name = strip_dir(vg_name, fi->cmd->dev_dir); + vg_name = strip_dir(vg_name, cmd->dev_dir); - vg->cmd = fi->cmd; + vg->cmd = cmd; if (!(vg->name = pool_strdup(mem, vg_name))) { stack; goto bad; } + vg->seqno = 0; + vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE); vg->system_id = pool_alloc(mem, NAME_LEN); *vg->system_id = '\0'; @@ -169,30 +175,35 @@ struct volume_group *vg_create(struct format_instance *fi, const char *vg_name, vg->snapshot_count = 0; list_init(&vg->snapshots); - if (!fi->ops->vg_setup(fi, vg)) { + if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg_name, + NULL))) { + log_error("Failed to create format instance"); + goto bad; + } + + if (!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) { log_error("Format specific setup of volume group '%s' failed.", vg_name); goto bad; } /* attach the pv's */ - if (!vg_extend(fi, vg, pv_count, pv_names)) + if (!vg_extend(vg->fid, vg, pv_count, pv_names)) goto bad; return vg; - bad: + bad: pool_free(mem, vg); return NULL; } -struct physical_volume *pv_create(struct format_instance *fi, +struct physical_volume *pv_create(struct format_instance *fid, const char *name, - struct id *id, - uint64_t size) + struct id *id, uint64_t size) { - struct pool *mem = fi->cmd->mem; - struct physical_volume *pv = pool_alloc(mem, sizeof (*pv)); + struct pool *mem = fid->fmt->cmd->mem; + struct physical_volume *pv = pool_alloc(mem, sizeof(*pv)); if (!pv) { stack; @@ -204,7 +215,7 @@ struct physical_volume *pv_create(struct format_instance *fi, else memcpy(&pv->id, id, sizeof(*id)); - if (!(pv->dev = dev_cache_get(name, fi->cmd->filter))) { + if (!(pv->dev = dev_cache_get(name, fid->fmt->cmd->filter))) { log_error("%s: Couldn't find device.", name); goto bad; } @@ -225,14 +236,14 @@ struct physical_volume *pv_create(struct format_instance *fi, if (size) { if (size > pv->size) log_print("WARNING: %s: Overriding real size. " - "You could lose data.", name); - log_verbose("%s: Pretending size is %" PRIu64 " sectors.", + "You could lose data.", name); + log_verbose("%s: Pretending size is %" PRIu64 " sectors.", name, size); pv->size = size; } - + if (pv->size < PV_MIN_SIZE) { - log_error("%s: Size must exceed minimum of %lu sectors.", + log_error("%s: Size must exceed minimum of %lu sectors.", name, PV_MIN_SIZE); goto bad; } @@ -240,9 +251,10 @@ struct physical_volume *pv_create(struct format_instance *fi, pv->pe_size = 0; pv->pe_start = 0; pv->pe_count = 0; - pv->pe_allocated = 0; + pv->pe_alloc_count = 0; + pv->fid = fid; - if (!fi->ops->pv_setup(fi, pv, NULL)) { + if (!fid->fmt->ops->pv_setup(fid, pv, NULL)) { log_error("%s: Format-specific setup of physical volume " "failed.", name); goto bad; @@ -324,3 +336,236 @@ struct physical_volume *find_pv(struct volume_group *vg, struct device *dev) return NULL; } +int vg_remove(struct volume_group *vg) +{ + struct list *mdah; + void *mdl; + + if (!vg->fid->fmt->ops->vg_remove) + return 1; + + /* FIXME Improve recovery situation? */ + /* Remove each copy of the metadata */ + list_iterate(mdah, &vg->fid->metadata_areas) { + mdl = list_item(mdah, struct metadata_area)->metadata_locn; + if (!vg->fid->fmt->ops->vg_remove(vg->fid, vg, mdl)) { + stack; + return 0; + } + } + + return 1; +} + +int vg_write(struct volume_group *vg) +{ + struct list *mdah; + void *mdl; + + vg->seqno++; + + /* Write to each copy of the metadata area */ + list_iterate(mdah, &vg->fid->metadata_areas) { + mdl = list_item(mdah, struct metadata_area)->metadata_locn; + if (!vg->fid->fmt->ops->vg_write(vg->fid, vg, mdl)) { + stack; + return 0; + } + } + + if (!vg->fid->fmt->ops->vg_commit) + return 1; + + /* Commit to each copy of the metadata area */ + list_iterate(mdah, &vg->fid->metadata_areas) { + mdl = list_item(mdah, struct metadata_area)->metadata_locn; + if (!vg->fid->fmt->ops->vg_commit(vg->fid, vg, mdl)) { + stack; + return 0; + } + } + + return 1; +} + +struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name) +{ + struct format_instance *fid; + struct format_type *fmt; + struct volume_group *vg, *correct_vg; + struct list *mdah, *names; + void *mdl; + int inconsistent = 0, first_time = 1; + + /* create format instance with appropriate metadata area */ + if (!(fmt = vgcache_find_format(vg_name))) { + /* Do full scan */ + if (!(names = get_vgs(cmd))) { + stack; + return NULL; + } + pool_free(cmd->mem, names); + if (!(fmt = vgcache_find_format(vg_name))) { + stack; + return NULL; + } + } + + if (!(fid = fmt->ops->create_instance(fmt, vg_name, NULL))) { + log_error("Failed to create format instance"); + return NULL; + } + + /* Ensure contents of all metadata areas match - else do recovery */ + list_iterate(mdah, &fid->metadata_areas) { + mdl = list_item(mdah, struct metadata_area)->metadata_locn; + if (!(vg = fid->fmt->ops->vg_read(fid, vg_name, mdl))) { + stack; + return NULL; + } + if (first_time) { + correct_vg = vg; + first_time = 0; + continue; + } + if (correct_vg->seqno != vg->seqno) { + inconsistent = 1; + if (vg->seqno > correct_vg->seqno) + correct_vg = vg; + } + } + + if (inconsistent) { + log_print("Inconsistent metadata copies found - updating " + "to use version %u", correct_vg->seqno); + if (!vg_write(correct_vg)) { + log_error("Automatic metadata correction failed"); + return NULL; + } + } + + vgcache_add(vg_name, correct_vg->id.uuid, NULL, fmt); + + return vg; +} + +struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid) +{ + char *vgname; + struct list *vgs, *vgh; + struct volume_group *vg; + + if (!(vgs = get_vgs(cmd))) { + log_error("vg_read_by_vgid: get_vgs failed"); + return NULL; + } + + list_iterate(vgh, vgs) { + vgname = list_item(vgh, struct name_list)->name; + if ((vg = vg_read(cmd, vgname)) && + !strncmp(vg->id.uuid, vgid, ID_LEN)) return vg; + } + + pool_free(cmd->mem, vgs); + return NULL; +} + +/* FIXME Use label functions instead of PV functions? */ +struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name) +{ + struct physical_volume *pv; + + if (!(pv = pool_zalloc(cmd->mem, sizeof(*pv)))) { + log_error("pv_list allocation for '%s' failed", pv_name); + return 0; + } + + /* Member of a format1 VG? */ + if (!(cmd->fmt1->ops->pv_read(cmd->fmt1, pv_name, pv))) { + log_error("Failed to read existing physical volume '%s'", + pv_name); + return 0; + } + + /* Member of a format_text VG? */ + if (!(cmd->fmtt->ops->pv_read(cmd->fmtt, pv_name, pv))) { + log_error("Failed to read existing physical volume '%s'", + pv_name); + return 0; + } + + if (!pv->size) + return NULL; + else + return pv; +} + +struct list *get_vgs(struct cmd_context *cmd) +{ + struct list *names; + + if (!(names = pool_alloc(cmd->mem, sizeof(*names)))) { + log_error("VG name list allocation failed"); + return NULL; + } + + list_init(names); + + if (!cmd->fmt1->ops->get_vgs(cmd->fmt1, names) || + !cmd->fmtt->ops->get_vgs(cmd->fmtt, names)) { + pool_free(cmd->mem, names); + return NULL; + } + + return names; +} + +struct list *get_pvs(struct cmd_context *cmd) +{ + struct list *results; + + if (!(results = pool_alloc(cmd->mem, sizeof(*results)))) { + log_error("PV list allocation failed"); + return NULL; + } + + list_init(results); + + /* fmtt modifies fmt1 output */ + if (!cmd->fmt1->ops->get_pvs(cmd->fmt1, results) || + !cmd->fmtt->ops->get_pvs(cmd->fmtt, results)) { + pool_free(cmd->mem, results); + return NULL; + } + + return results; +} + +int pv_write(struct cmd_context *cmd, struct physical_volume *pv) +{ + struct list *mdah; + void *mdl; + + /* Write to each copy of the metadata area */ + list_iterate(mdah, &pv->fid->metadata_areas) { + mdl = list_item(mdah, struct metadata_area)->metadata_locn; + if (!pv->fid->fmt->ops->pv_write(pv->fid, pv, mdl)) { + stack; + return 0; + } + } + + if (!pv->fid->fmt->ops->pv_commit) + return 1; + + /* Commit to each copy of the metadata area */ + list_iterate(mdah, &pv->fid->metadata_areas) { + mdl = list_item(mdah, struct metadata_area)->metadata_locn; + if (!pv->fid->fmt->ops->pv_commit(pv->fid, pv, mdl)) { + stack; + return 0; + } + } + + return 1; +} diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 6bba7857..3dceed6a 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -23,6 +23,7 @@ #define STRIPE_SIZE_MIN ( PAGE_SIZE/SECTOR_SIZE) /* PAGESIZE in sectors */ #define STRIPE_SIZE_MAX ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */ #define PV_MIN_SIZE ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */ +#define PE_ALIGN (65536UL / SECTOR_SIZE) /* PE alignment */ /* Various flags */ @@ -51,10 +52,15 @@ #define ALLOC_STRICT 0x00002000 /* LV */ #define ALLOC_CONTIGUOUS 0x00004000 /* LV */ +#define FMT_SEGMENTS 0x00000001 /* Arbitrary segment parameters? */ + +#define FMT_TEXT_NAME "text" +#define FMT_LVM1_NAME "lvm1" struct physical_volume { struct id id; struct device *dev; + struct format_instance *fid; char *vg_name; uint32_t status; @@ -64,13 +70,33 @@ struct physical_volume { uint64_t pe_size; uint64_t pe_start; uint32_t pe_count; - uint32_t pe_allocated; /* FIXME: change the name to alloc_count ? */ + uint32_t pe_alloc_count; }; struct cmd_context; +struct format_type { + struct cmd_context *cmd; + struct format_handler *ops; + const char *name; + uint32_t features; + void *private; +}; + +struct metadata_area { + struct list list; + void *metadata_locn; +}; + +struct format_instance { + struct format_type *fmt; + struct list metadata_areas; /* e.g. metadata locations */ +}; + struct volume_group { struct cmd_context *cmd; + struct format_instance *fid; + uint32_t seqno; /* Metadata sequence number */ struct id id; char *name; @@ -159,11 +185,6 @@ struct snapshot_list { struct snapshot *snapshot; }; -struct format_instance { - struct cmd_context *cmd; - struct format_handler *ops; - void *private; -}; /* @@ -173,18 +194,19 @@ struct format_handler { /* * Returns a name_list of vg's. */ - struct list *(*get_vgs)(struct format_instance *fi); + struct list *(*get_vgs)(struct format_type *fmt, struct list *names); /* * Returns pv_list of fully-populated pv structures. */ - struct list *(*get_pvs)(struct format_instance *fi); + struct list *(*get_pvs)(struct format_type *fmt, struct list *results); /* * Return PV with given path. */ - struct physical_volume *(*pv_read)(struct format_instance *fi, - const char *pv_name); + int (*pv_read)(struct format_type *fmt, + const char *pv_name, + struct physical_volume *pv); /* * Tweak an already filled out a pv ready for importing into a @@ -197,8 +219,10 @@ struct format_handler { * Write a PV structure to disk. Fails if the PV is in a VG ie * pv->vg_name must be null. */ - int (*pv_write)(struct format_instance *fi, - struct physical_volume *pv); + int (*pv_write)(struct format_instance *fi, struct physical_volume *pv, + void *mdl); + int (*pv_commit)(struct format_instance *fid, + struct physical_volume *pv, void *mdl); /* * Tweak an already filled out a lv eg, check there @@ -211,13 +235,16 @@ struct format_handler { * specific. */ int (*vg_setup)(struct format_instance *fi, struct volume_group *vg); + int (*vg_remove)(struct format_instance *fi, struct volume_group *vg, + void *mdl); /* * The name may be prefixed with the dev_dir from the * job_context. + * mdl is the metadata location to use */ struct volume_group *(*vg_read)(struct format_instance *fi, - const char *vg_name); + const char *vg_name, void *mdl); /* * Write out complete VG metadata. You must ensure internal @@ -233,25 +260,50 @@ struct format_handler { * in the volume_group structure it is handed. Note: format1 * does read all pv's currently. */ - int (*vg_write)(struct format_instance *fi, struct volume_group *vg); + int (*vg_write)(struct format_instance *fid, struct volume_group *vg, + void *mdl); + + int (*vg_commit)(struct format_instance *fid, struct volume_group *vg, + void *mdl); + /* + * Create format instance with a particular metadata area + */ + struct format_instance *(*create_instance)(struct format_type *fmt, + const char *vgname, + void *context); + + /* + * Destructor for format instance + */ + void (*destroy_instance)(struct format_instance *fid); /* - * Destructor for this object. + * Destructor for format type */ - void (*destroy)(struct format_instance *fi); + void (*destroy)(struct format_type *fmt); }; /* * Utility functions */ +int vg_write(struct volume_group *vg); +struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name); +struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid); +struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name); +struct list *get_pvs(struct cmd_context *cmd); +struct list *get_vgs(struct cmd_context *cmd); +int pv_write(struct cmd_context *cmd, struct physical_volume *pv); + + struct physical_volume *pv_create(struct format_instance *fi, const char *name, struct id *id, uint64_t size); -struct volume_group *vg_create(struct format_instance *fi, const char *name, +struct volume_group *vg_create(struct cmd_context *cmd, const char *name, uint32_t extent_size, int max_pv, int max_lv, int pv_count, char **pv_names); +int vg_remove(struct volume_group *vg); /* * This needs the format instance to check the @@ -341,6 +393,7 @@ int lv_is_origin(struct logical_volume *lv); int lv_is_cow(struct logical_volume *lv); struct snapshot *find_cow(struct logical_volume *lv); +struct snapshot *find_origin(struct logical_volume *lv); int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow, diff --git a/lib/metadata/pv_map.c b/lib/metadata/pv_map.c index 11b8d5f5..a30019e8 100644 --- a/lib/metadata/pv_map.c +++ b/lib/metadata/pv_map.c @@ -82,7 +82,7 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps) } /* populate the hash table */ - list_iterate (pvmh, maps) { + list_iterate(pvmh, maps) { pvm = list_item(pvmh, struct pv_map); if (!hash_insert(hash, dev_name(pvm->pv->dev), pvm)) { stack; @@ -91,18 +91,18 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps) } /* iterate through all the lv's setting bit's for used pe's */ - list_iterate (lvh, &vg->lvs) { + list_iterate(lvh, &vg->lvs) { lv = list_item(lvh, struct lv_list)->lv; - list_iterate (segh, &lv->segments) { + list_iterate(segh, &lv->segments) { seg = list_item(segh, struct stripe_segment); for (s = 0; s < seg->stripes; s++) { for (pe = 0; pe < (seg->len / seg->stripes); pe++) { if (!_set_allocated(hash, - seg->area[s].pv, - seg->area[s].pe + seg->area[s].pv, + seg->area[s].pe + pe)) { stack; goto out; @@ -113,7 +113,7 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps) } r = 1; - out: + out: hash_destroy(hash); return r; } @@ -131,7 +131,7 @@ static void _insert_area(struct list *head, struct pv_area *a) return; } - list_iterate (pvah, head) { + list_iterate(pvah, head) { pva = list_item(pvah, struct pv_area); if (pva->count < a->count) @@ -142,7 +142,7 @@ static void _insert_area(struct list *head, struct pv_area *a) } static int _create_single_area(struct pool *mem, struct pv_map *pvm, - uint32_t *extent) + uint32_t * extent) { uint32_t e = *extent, b, count = pvm->pv->pe_count; struct pv_area *pva; diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c index a9552039..7debcf7c 100644 --- a/lib/metadata/snapshot_manip.c +++ b/lib/metadata/snapshot_manip.c @@ -13,7 +13,7 @@ int lv_is_origin(struct logical_volume *lv) struct list *slh; struct snapshot *s; - list_iterate (slh, &lv->vg->snapshots) { + list_iterate(slh, &lv->vg->snapshots) { s = list_item(slh, struct snapshot_list)->snapshot; if (s->origin == lv) return 1; @@ -27,7 +27,7 @@ int lv_is_cow(struct logical_volume *lv) struct list *slh; struct snapshot *s; - list_iterate (slh, &lv->vg->snapshots) { + list_iterate(slh, &lv->vg->snapshots) { s = list_item(slh, struct snapshot_list)->snapshot; if (s->cow == lv) return 1; @@ -36,12 +36,26 @@ int lv_is_cow(struct logical_volume *lv) return 0; } +struct snapshot *find_origin(struct logical_volume *lv) +{ + struct list *slh; + struct snapshot *s; + + list_iterate(slh, &lv->vg->snapshots) { + s = list_item(slh, struct snapshot_list)->snapshot; + if (s->origin == lv) + return s; + } + + return NULL; +} + struct snapshot *find_cow(struct logical_volume *lv) { struct list *slh; struct snapshot *s; - list_iterate (slh, &lv->vg->snapshots) { + list_iterate(slh, &lv->vg->snapshots) { s = list_item(slh, struct snapshot_list)->snapshot; if (s->cow == lv) return s; @@ -52,8 +66,7 @@ struct snapshot *find_cow(struct logical_volume *lv) int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow, - int persistent, - uint32_t chunk_size) + int persistent, uint32_t chunk_size) { struct snapshot *s; struct snapshot_list *sl; @@ -94,7 +107,7 @@ int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow) struct list *slh; struct snapshot_list *sl; - list_iterate (slh, &vg->snapshots) { + list_iterate(slh, &vg->snapshots) { sl = list_item(slh, struct snapshot_list); if (sl->snapshot->cow == cow) { diff --git a/lib/mm/dbg_malloc.c b/lib/mm/dbg_malloc.c index a279ed43..157da0c0 100644 --- a/lib/mm/dbg_malloc.c +++ b/lib/mm/dbg_malloc.c @@ -14,19 +14,20 @@ #include "log.h" struct memblock { - struct memblock *prev, *next; /* All allocated blocks are linked */ - size_t length; /* Size of the requested block */ - int id; /* Index of the block */ - const char *file; /* File that allocated */ - int line; /* Line that allocated */ - void *magic; /* Address of this block */ + struct memblock *prev, *next; /* All allocated blocks are linked */ + size_t length; /* Size of the requested block */ + int id; /* Index of the block */ + const char *file; /* File that allocated */ + int line; /* Line that allocated */ + void *magic; /* Address of this block */ }; static struct { unsigned int blocks, mblocks; unsigned int bytes, mbytes; -} _mem_stats = {0, 0, 0, 0}; +} _mem_stats = { +0, 0, 0, 0}; static struct memblock *_head = 0; static struct memblock *_tail = 0; @@ -104,7 +105,7 @@ void free_aux(void *p) /* check data at the far boundary */ ptr = ((char *) mb) + sizeof(struct memblock) + mb->length; for (i = 0; i < sizeof(unsigned long); i++) - if(*ptr++ != (char) mb->id) + if (*ptr++ != (char) mb->id) assert(!"Damage at far end of block"); /* have we freed this before ? */ @@ -159,7 +160,7 @@ int dump_memory(void) log_very_verbose("You have a memory leak:"); for (mb = _head; mb; mb = mb->next) { - print_log(_LOG_INFO, mb->file, mb->line, + print_log(_LOG_INFO, mb->file, mb->line, "block %d at %p, size %" PRIdPTR, mb->id, mb->magic, mb->length); tot += mb->length; diff --git a/lib/mm/pool-fast.c b/lib/mm/pool-fast.c index cbe00b12..73b477f3 100644 --- a/lib/mm/pool-fast.c +++ b/lib/mm/pool-fast.c @@ -18,11 +18,11 @@ struct chunk { }; struct pool { - struct chunk *chunk, *spare_chunk; /* spare_chunk is a one entry free - list to stop 'bobbling' */ + struct chunk *chunk, *spare_chunk; /* spare_chunk is a one entry free + list to stop 'bobbling' */ size_t chunk_size; size_t object_len; - unsigned object_alignment; + unsigned object_alignment; }; void _align_chunk(struct chunk *c, unsigned alignment); @@ -75,12 +75,12 @@ void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment) struct chunk *c = p->chunk; void *r; - /* realign begin */ + /* realign begin */ if (c) _align_chunk(c, alignment); /* have we got room ? */ - if(!c || (c->begin > c->end) || (c->end - c->begin < s)) { + if (!c || (c->begin > c->end) || (c->end - c->begin < s)) { /* allocate new chunk */ int needed = s + alignment + sizeof(struct chunk); c = _new_chunk(p, (needed > p->chunk_size) ? @@ -225,7 +225,8 @@ struct chunk *_new_chunk(struct pool *p, size_t s) p->spare_chunk = 0; } else { if (!(c = dbg_malloc(s))) { - log_err("Out of memory. Requested %" PRIuPTR " bytes.", s); + log_err("Out of memory. Requested %" PRIuPTR " bytes.", + s); return NULL; } @@ -238,4 +239,3 @@ struct chunk *_new_chunk(struct pool *p, size_t s) return c; } - diff --git a/lib/regex/matcher.c b/lib/regex/matcher.c index 95f7765f..8a607463 100644 --- a/lib/regex/matcher.c +++ b/lib/regex/matcher.c @@ -25,7 +25,7 @@ struct state_queue { struct state_queue *next; }; -struct matcher { /* Instance variables for the lexer */ +struct matcher { /* Instance variables for the lexer */ struct dfa_state *start; int num_nodes, nodes_entered; struct rx_node **nodes; @@ -38,10 +38,10 @@ static int _count_nodes(struct rx_node *rx) { int r = 1; - if(rx->left) + if (rx->left) r += _count_nodes(rx->left); - if(rx->right) + if (rx->right) r += _count_nodes(rx->right); return r; @@ -51,10 +51,10 @@ static void _fill_table(struct matcher *m, struct rx_node *rx) { assert((rx->type != OR) || (rx->left && rx->right)); - if(rx->left) + if (rx->left) _fill_table(m, rx->left); - if(rx->right) + if (rx->right) _fill_table(m, rx->right); m->nodes[m->nodes_entered++] = rx; @@ -64,7 +64,7 @@ static void _create_bitsets(struct matcher *m) { int i; - for(i = 0; i < m->num_nodes; i++) { + for (i = 0; i < m->num_nodes; i++) { struct rx_node *n = m->nodes[i]; n->firstpos = bitset_create(m->scratch, m->num_nodes); n->lastpos = bitset_create(m->scratch, m->num_nodes); @@ -77,23 +77,23 @@ static void _calc_functions(struct matcher *m) int i, j, final = 1; struct rx_node *rx, *c1, *c2; - for(i = 0; i < m->num_nodes; i++) { + for (i = 0; i < m->num_nodes; i++) { rx = m->nodes[i]; c1 = rx->left; c2 = rx->right; - if(bit(rx->charset, TARGET_TRANS)) + if (bit(rx->charset, TARGET_TRANS)) rx->final = final++; - switch(rx->type) { + switch (rx->type) { case CAT: - if(c1->nullable) + if (c1->nullable) bit_union(rx->firstpos, c1->firstpos, c2->firstpos); else bit_copy(rx->firstpos, c1->firstpos); - if(c2->nullable) + if (c2->nullable) bit_union(rx->lastpos, c1->lastpos, c2->lastpos); else @@ -136,10 +136,10 @@ static void _calc_functions(struct matcher *m) * because PLUS and STAR do the * same thing. */ - switch(rx->type) { + switch (rx->type) { case CAT: - for(j = 0; j < m->num_nodes; j++) { - if(bit(c1->lastpos, j)) { + for (j = 0; j < m->num_nodes; j++) { + if (bit(c1->lastpos, j)) { struct rx_node *n = m->nodes[j]; bit_union(n->followpos, n->followpos, c2->firstpos); @@ -149,8 +149,8 @@ static void _calc_functions(struct matcher *m) case PLUS: case STAR: - for(j = 0; j < m->num_nodes; j++) { - if(bit(rx->lastpos, j)) { + for (j = 0; j < m->num_nodes; j++) { + if (bit(rx->lastpos, j)) { struct rx_node *n = m->nodes[j]; bit_union(n->followpos, n->followpos, rx->firstpos); @@ -178,7 +178,7 @@ static struct state_queue *_create_state_queue(struct pool *mem, } r->s = dfa; - r->bits = bitset_create(mem, bits[0]); /* first element is the size */ + r->bits = bitset_create(mem, bits[0]); /* first element is the size */ bit_copy(r->bits, bits); r->next = 0; return r; @@ -218,28 +218,30 @@ static int _calc_states(struct matcher *m, struct rx_node *rx) /* iterate through all the inputs for this state */ bit_clear_all(bs); - for(a = 0; a < 256; a++) { + for (a = 0; a < 256; a++) { /* iterate through all the states in firstpos */ - for(i = bit_get_first(dfa_bits); - i >=0; - i = bit_get_next(dfa_bits, i)) { - if(bit(m->nodes[i]->charset, a)) { - if(a == TARGET_TRANS) + for (i = bit_get_first(dfa_bits); + i >= 0; i = bit_get_next(dfa_bits, i)) { + if (bit(m->nodes[i]->charset, a)) { + if (a == TARGET_TRANS) dfa->final = m->nodes[i]->final; - bit_union(bs, bs, m->nodes[i]->followpos); + bit_union(bs, bs, + m->nodes[i]->followpos); set_bits = 1; } } - if(set_bits) { + if (set_bits) { ldfa = ttree_lookup(tt, bs + 1); - if(!ldfa) { + if (!ldfa) { /* push */ ldfa = _create_dfa_state(m->mem); ttree_insert(tt, bs + 1, ldfa); - tmp = _create_state_queue(m->scratch, ldfa, bs); - if(!h) + tmp = + _create_state_queue(m->scratch, + ldfa, bs); + if (!h) h = t = tmp; else { t->next = tmp; @@ -260,8 +262,7 @@ static int _calc_states(struct matcher *m, struct rx_node *rx) return 1; } -struct matcher *matcher_create(struct pool *mem, - const char **patterns, int num) +struct matcher *matcher_create(struct pool *mem, const char **patterns, int num) { char *all, *ptr; int i, len = 0; @@ -282,7 +283,7 @@ struct matcher *matcher_create(struct pool *mem, memset(m, 0, sizeof(*m)); /* join the regexps together, delimiting with zero */ - for(i = 0; i < num; i++) + for (i = 0; i < num; i++) len += strlen(patterns[i]) + 8; ptr = all = pool_alloc(scratch, len + 1); @@ -292,15 +293,14 @@ struct matcher *matcher_create(struct pool *mem, goto bad; } - for(i = 0; i < num; i++) { - ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i], - TARGET_TRANS); - if(i < (num - 1)) + for (i = 0; i < num; i++) { + ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i], TARGET_TRANS); + if (i < (num - 1)) *ptr++ = '|'; } /* parse this expression */ - if(!(rx = rx_parse_tok(scratch, all, ptr))) { + if (!(rx = rx_parse_tok(scratch, all, ptr))) { log_error("Couldn't parse regex"); goto bad; } @@ -324,7 +324,7 @@ struct matcher *matcher_create(struct pool *mem, return m; - bad: + bad: pool_destroy(scratch); pool_destroy(mem); return NULL; diff --git a/lib/regex/parse_rx.c b/lib/regex/parse_rx.c index 57e2c4c8..7dcef82f 100644 --- a/lib/regex/parse_rx.c +++ b/lib/regex/parse_rx.c @@ -12,7 +12,6 @@ #include <stdlib.h> #include <stdio.h> - struct parse_sp { /* scratch pad for the parsing process */ struct pool *mem; int type; /* token type, 0 indicates a charset */ @@ -21,10 +20,8 @@ struct parse_sp { /* scratch pad for the parsing process */ const char *rx_end; /* 1pte for the expression being parsed */ }; - static struct rx_node *_or_term(struct parse_sp *ps); - /* * Get the next token from the regular expression. * Returns: 1 success, 0 end of input, -1 error. @@ -34,16 +31,16 @@ static int _get_token(struct parse_sp *ps) int neg = 0, range = 0; char c, lc = 0; const char *ptr = ps->cursor; - if(ptr == ps->rx_end) { /* end of input ? */ + if (ptr == ps->rx_end) { /* end of input ? */ ps->type = -1; return 0; } - switch(*ptr) { - /* charsets and ncharsets */ + switch (*ptr) { + /* charsets and ncharsets */ case '[': ptr++; - if(*ptr == '^') { + if (*ptr == '^') { bit_set_all(ps->charset); /* never transition on zero */ @@ -54,40 +51,46 @@ static int _get_token(struct parse_sp *ps) } else bit_clear_all(ps->charset); - while((ptr < ps->rx_end) && (*ptr != ']')) { - if(*ptr == '\\') { + while ((ptr < ps->rx_end) && (*ptr != ']')) { + if (*ptr == '\\') { /* an escaped character */ ptr++; - switch(*ptr) { - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; + switch (*ptr) { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; default: c = *ptr; } - } else if(*ptr == '-' && lc) { + } else if (*ptr == '-' && lc) { /* we've got a range on our hands */ range = 1; ptr++; - if(ptr == ps->rx_end) { + if (ptr == ps->rx_end) { log_error("Incomplete range" - "specification"); + "specification"); return -1; } c = *ptr; } else c = *ptr; - if(range) { + if (range) { /* add lc - c into the bitset */ - if(lc > c) { + if (lc > c) { char tmp = c; c = lc; lc = tmp; } - for(; lc <= c; lc++) { - if(neg) + for (; lc <= c; lc++) { + if (neg) bit_clear(ps->charset, lc); else bit_set(ps->charset, lc); @@ -95,7 +98,7 @@ static int _get_token(struct parse_sp *ps) range = 0; } else { /* add c into the bitset */ - if(neg) + if (neg) bit_clear(ps->charset, c); else bit_set(ps->charset, c); @@ -104,7 +107,7 @@ static int _get_token(struct parse_sp *ps) lc = c; } - if(ptr >= ps->rx_end) { + if (ptr >= ps->rx_end) { ps->type = -1; return -1; } @@ -141,7 +144,7 @@ static int _get_token(struct parse_sp *ps) case '\\': /* escaped character */ ptr++; - if(ptr >= ps->rx_end) { + if (ptr >= ps->rx_end) { log_error("Badly quoted character at end " "of expression"); ps->type = -1; @@ -151,10 +154,16 @@ static int _get_token(struct parse_sp *ps) ps->type = 0; ps->cursor = ptr + 1; bit_clear_all(ps->charset); - switch(*ptr) { - case 'n': bit_set(ps->charset, (int) '\n'); break; - case 'r': bit_set(ps->charset, (int) '\r'); break; - case 't': bit_set(ps->charset, (int) '\t'); break; + switch (*ptr) { + case 'n': + bit_set(ps->charset, (int) '\n'); + break; + case 'r': + bit_set(ps->charset, (int) '\r'); + break; + case 't': + bit_set(ps->charset, (int) '\t'); + break; default: bit_set(ps->charset, (int) *ptr); } @@ -195,7 +204,7 @@ static struct rx_node *_term(struct parse_sp *ps) { struct rx_node *n; - switch(ps->type) { + switch (ps->type) { case 0: if (!(n = _node(ps->mem, CHARSET, NULL, NULL))) { stack; @@ -203,17 +212,17 @@ static struct rx_node *_term(struct parse_sp *ps) } bit_copy(n->charset, ps->charset); - _get_token(ps); /* match charset */ + _get_token(ps); /* match charset */ break; case '(': - _get_token(ps); /* match '(' */ + _get_token(ps); /* match '(' */ n = _or_term(ps); - if(ps->type != ')') { + if (ps->type != ')') { log_error("missing ')' in regular expression"); return 0; } - _get_token(ps); /* match ')' */ + _get_token(ps); /* match ')' */ break; default: @@ -227,11 +236,11 @@ static struct rx_node *_closure_term(struct parse_sp *ps) { struct rx_node *l, *n; - if(!(l = _term(ps))) + if (!(l = _term(ps))) return NULL; for (;;) { - switch(ps->type) { + switch (ps->type) { case '*': n = _node(ps->mem, STAR, l, NULL); break; @@ -289,7 +298,7 @@ static struct rx_node *_or_term(struct parse_sp *ps) if (ps->type != '|') return l; - _get_token(ps); /* match '|' */ + _get_token(ps); /* match '|' */ if (!(r = _or_term(ps))) { log_error("Badly formed 'or' expression"); @@ -317,7 +326,7 @@ struct rx_node *rx_parse_tok(struct pool *mem, ps->charset = bitset_create(mem, 256); ps->cursor = begin; ps->rx_end = end; - _get_token(ps); /* load the first token */ + _get_token(ps); /* load the first token */ if (!(r = _or_term(ps))) { log_error("Parse error in regex"); diff --git a/lib/regex/ttree.c b/lib/regex/ttree.c index fbc54bd5..32f070a6 100644 --- a/lib/regex/ttree.c +++ b/lib/regex/ttree.c @@ -74,7 +74,6 @@ int ttree_insert(struct ttree *tt, unsigned int *key, void *data) } while (*c && count); - if (!*c) { count++; diff --git a/lib/uuid/uuid.c b/lib/uuid/uuid.c index bc13775a..bff912de 100644 --- a/lib/uuid/uuid.c +++ b/lib/uuid/uuid.c @@ -19,6 +19,14 @@ static unsigned char _c[] = static int _built_inverse; static unsigned char _inverse_c[256]; +int lvid_create(union lvid *lvid, struct id *vgid) +{ + memcpy(lvid->id, vgid, sizeof(*lvid->id)); + id_create(&lvid->id[1]); + + return 1; +} + int lvid_from_lvnum(union lvid *lvid, struct id *vgid, int lv_num) { int i; @@ -116,7 +124,7 @@ int id_write_format(struct id *id, char *buffer, size_t size) { int i, tot; - static int group_size[] = {6, 4, 4, 4, 4, 4, 6}; + static int group_size[] = { 6, 4, 4, 4, 4, 4, 6 }; assert(ID_LEN == 32); diff --git a/lib/uuid/uuid.h b/lib/uuid/uuid.h index 810fc7c9..78c451a2 100644 --- a/lib/uuid/uuid.h +++ b/lib/uuid/uuid.h @@ -28,6 +28,7 @@ union lvid { int lvid_from_lvnum(union lvid *lvid, struct id *vgid, int lv_num); int lvnum_from_lvid(union lvid *lvid); +int lvid_create(union lvid *lvid, struct id *vgid); int id_create(struct id *id); int id_valid(struct id *id); int id_equal(struct id *lhs, struct id *rhs); diff --git a/lib/vgcache/vgcache.c b/lib/vgcache/vgcache.c index c81732a5..a6a92af2 100644 --- a/lib/vgcache/vgcache.c +++ b/lib/vgcache/vgcache.c @@ -50,6 +50,22 @@ struct list *vgcache_find(const char *vg_name) return &vgn->pvdevs; } +struct format_type *vgcache_find_format(const char *vg_name) +{ + struct vgname_entry *vgn; + + if (!_vghash) + return NULL; + + if (!vg_name) + vg_name = all_devices; + + if (!(vgn = hash_lookup(_vghash, vg_name))) + return NULL; + + return vgn->fmt; +} + struct list *vgcache_find_by_vgid(const char *vgid) { struct vgname_entry *vgn; @@ -78,7 +94,8 @@ void vgcache_del_orphan(struct device *dev) } } -int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev) +int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev, + struct format_type *fmt) { const char *pv_name; struct vgname_entry *vgn; @@ -92,6 +109,7 @@ int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev) } memset(vgn, 0, sizeof(struct vgname_entry)); + vgn->fmt = fmt; pvdevs = &vgn->pvdevs; list_init(pvdevs); @@ -104,19 +122,26 @@ int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev) log_error("vgcache_add: VG hash insertion failed"); return 0; } + } else if (!(vgn = hash_lookup(_vghash, vg_name))) { + log_error("vgcache_add: VG name entry %s not found", vg_name); + return 0; + } - if (vgid) { - memcpy(vgn->vgid, vgid, ID_LEN); - vgn->vgid[ID_LEN] = '\0'; + if (vgid && strncmp(vgid, vgn->vgid, ID_LEN)) { + hash_remove(_vgidhash, vgn->vgid); + + memcpy(vgn->vgid, vgid, ID_LEN); + vgn->vgid[ID_LEN] = '\0'; - if (!hash_insert(_vgidhash, vgn->vgid, vgn)) { - log_error("vgcache_add: vgid hash insertion " - "failed"); - return 0; - } + if (!hash_insert(_vgidhash, vgn->vgid, vgn)) { + log_error("vgcache_add: vgid hash insertion " "failed"); + return 0; } } + if (!dev) + return 1; + list_iterate(pvdh, pvdevs) { pvdev = list_item(pvdh, struct pvdev_list); if (dev == pvdev->dev) @@ -150,21 +175,25 @@ int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev) } /* vg_name of "\0" is an orphan PV; NULL means only add to all_devices */ -int vgcache_add(const char *vg_name, const char *vgid, struct device *dev) +int vgcache_add(const char *vg_name, const char *vgid, struct device *dev, + struct format_type *fmt) { if (!_vghash && !vgcache_init()) return 0; /* If orphan PV remove it */ - if (vg_name && !*vg_name) + if (dev && vg_name && !*vg_name) vgcache_del_orphan(dev); /* Add PV if vg_name supplied */ - if (vg_name && *vg_name && !vgcache_add_entry(vg_name, vgid, dev)) + if (vg_name && *vg_name && !vgcache_add_entry(vg_name, vgid, dev, fmt)) return 0; - /* Always add to all_devices */ - return vgcache_add_entry(all_devices, NULL, dev); + /* Add to all_devices */ + if (dev) + return vgcache_add_entry(all_devices, NULL, dev, fmt); + + return 1; } void vgcache_destroy_entry(struct vgname_entry *vgn) @@ -208,7 +237,6 @@ void vgcache_del(const char *vg_name) vgcache_destroy_entry(vgn); } - void vgcache_del_by_vgid(const char *vgid) { struct vgname_entry *vgn; @@ -230,11 +258,10 @@ void vgcache_del_by_vgid(const char *vgid) vgcache_destroy_entry(vgn); } - void vgcache_destroy() { if (_vghash) { - hash_iter(_vghash, (iterate_fn)vgcache_destroy_entry); + hash_iter(_vghash, (iterate_fn) vgcache_destroy_entry); hash_destroy(_vghash); _vghash = NULL; } @@ -266,4 +293,3 @@ char *vgname_from_vgid(struct cmd_context *cmd, struct id *vgid) return pool_strdup(cmd->mem, vgn->vgname); } - diff --git a/lib/vgcache/vgcache.h b/lib/vgcache/vgcache.h index 64b4e44f..47fd2ede 100644 --- a/lib/vgcache/vgcache.h +++ b/lib/vgcache/vgcache.h @@ -19,6 +19,7 @@ struct vgname_entry { struct list pvdevs; char *vgname; char vgid[ID_LEN + 1]; + struct format_type *fmt; }; struct pvdev_list { @@ -31,13 +32,15 @@ void vgcache_destroy(); /* Return list of PVs in named VG */ struct list *vgcache_find(const char *vg_name); +struct format_type *vgcache_find_format(const char *vg_name); struct list *vgcache_find_by_vgid(const char *vgid); /* FIXME Temporary function */ char *vgname_from_vgid(struct cmd_context *cmd, struct id *vgid); /* Add/delete a device */ -int vgcache_add(const char *vg_name, const char *vgid, struct device *dev); +int vgcache_add(const char *vg_name, const char *vgid, struct device *dev, + struct format_type *fmt); void vgcache_del(const char *vg_name); #endif diff --git a/tools/archive.c b/tools/archive.c index e505818f..56d1bcd0 100644 --- a/tools/archive.c +++ b/tools/archive.c @@ -157,6 +157,7 @@ static int __backup(struct volume_group *vg) struct format_instance *tf; char name[PATH_MAX]; char *desc; + void *context; if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) { stack; @@ -172,15 +173,19 @@ static int __backup(struct volume_group *vg) log_verbose("Creating volume group backup \"%s\"", name); - if (!(tf = text_format_create(vg->cmd, name, vg->cmd->um, desc))) { + if (!(context = create_text_context(vg->cmd->fmtt, name, desc)) || + !(tf = vg->cmd->fmtt->ops->create_instance(vg->cmd->fmtt, NULL, + context))) { stack; return 0; } - if (!(r = tf->ops->vg_write(tf, vg))) + if (!(r = tf->fmt->ops->vg_write(tf, vg, context)) || + !(r = tf->fmt->ops->vg_commit(tf, vg, context))) stack; - tf->ops->destroy(tf); + tf->fmt->ops->destroy_instance(tf); + return r; } @@ -227,16 +232,20 @@ static struct volume_group *_read_vg(struct cmd_context *cmd, { struct volume_group *vg; struct format_instance *tf; + void *context; - if (!(tf = text_format_create(cmd, file, cmd->um, cmd->cmd_line))) { + if (!(context = create_text_context(vg->cmd->fmtt, file, + cmd->cmd_line)) || + !(tf = vg->cmd->fmtt->ops->create_instance(cmd->fmtt, NULL, + context))) { log_error("Couldn't create text format object."); return NULL; } - if (!(vg = tf->ops->vg_read(tf, vg_name))) + if (!(vg = tf->fmt->ops->vg_read(tf, vg_name, context))) stack; - tf->ops->destroy(tf); + tf->fmt->ops->destroy_instance(tf); return vg; } @@ -264,7 +273,15 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, /* * Write the vg. */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) { + + /* FIXME How do I find what format to write out the VG in? */ + /* Must store the format type inside the backup? */ + if (!(vg->fid = cmd->fmt1->ops->create_instance(cmd->fmt1, NULL, NULL))) { + log_error("Failed to allocate format1 instance"); + return 0; + } + + if (!vg_write(vg)) { stack; return 0; } diff --git a/tools/args.h b/tools/args.h index 2c396edb..b2eda99c 100644 --- a/tools/args.h +++ b/tools/args.h @@ -46,6 +46,7 @@ arg(list_ARG, 'l', "list", NULL) arg(size_ARG, 'L', "size", size_arg) arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign) arg(persistent_ARG, 'M', "persistent", yes_no_arg) +arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg) arg(minor_ARG, 'm', "minor", minor_arg) arg(maps_ARG, 'm', "maps", NULL) arg(name_ARG, 'n', "name", string_arg) diff --git a/tools/commands.h b/tools/commands.h index 2961599c..5a940edb 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -87,8 +87,7 @@ xx(lvcreate, "\t[--version]\n" "\tVolumeGroupName [PhysicalVolumePath...]\n\n", - autobackup_ARG, chunksize_ARG, - contiguous_ARG, extents_ARG, minor_ARG, name_ARG, + autobackup_ARG, contiguous_ARG, extents_ARG, minor_ARG, name_ARG, permission_ARG, persistent_ARG, readahead_ARG, size_ARG, snapshot_ARG, stripes_ARG, stripesize_ARG, test_ARG, zero_ARG) @@ -393,9 +392,10 @@ xx(vgcreate, "vgcreate" "\n" "\t[-A|--autobackup {y|n}] " "\n" "\t[-d|--debug]" "\n" + "\t[-h|--help]" "\n" "\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n" + "\t[-M|--metadatatype lvm1/text] " "\n" "\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n" - "\t[-h|--help]" "\n" "\t[-s|--physicalextentsize PhysicalExtentSize[kKmMgGtT]] " "\n" "\t[-t|--test] " "\n" "\t[-v|--verbose]" "\n" @@ -403,7 +403,7 @@ xx(vgcreate, "\tVolumeGroupName PhysicalVolume [PhysicalVolume...]\n", autobackup_ARG, maxlogicalvolumes_ARG, maxphysicalvolumes_ARG, - physicalextentsize_ARG, test_ARG) + metadatatype_ARG, physicalextentsize_ARG, test_ARG) xx(vgdisplay, "Display volume group information", diff --git a/tools/lvchange.c b/tools/lvchange.c index 896a8854..6e6942e5 100644 --- a/tools/lvchange.c +++ b/tools/lvchange.c @@ -159,19 +159,19 @@ static int lvchange_permission(struct cmd_context *cmd, } log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); - if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) { - /* FIXME: Attempt reversion? */ - unlock_lv(cmd, lv->lvid.s); + if (!(lv->vg)) { + /* FIXME: Attempt reversion? */ + unlock_lv(cmd, lv->lvid.s); return 0; } backup(lv->vg); log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name); - if (!unlock_lv(cmd, lv->lvid.s)) { - log_error("Problem reactivating %s", lv->name); - return 0; - } + if (!unlock_lv(cmd, lv->lvid.s)) { + log_error("Problem reactivating %s", lv->name); + return 0; + } return 1; } @@ -248,18 +248,18 @@ static int lvchange_contiguous(struct cmd_context *cmd, } log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); - if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) { - /* FIXME: Attempt reversion? */ - unlock_lv(cmd, lv->lvid.s); + if (!vg_write(lv->vg)) { + /* FIXME: Attempt reversion? */ + unlock_lv(cmd, lv->lvid.s); return 0; } backup(lv->vg); - if (!unlock_lv(cmd, lv->lvid.s)) { - log_error("Problem reactivating %s", lv->name); - return 0; - } + if (!unlock_lv(cmd, lv->lvid.s)) { + log_error("Problem reactivating %s", lv->name); + return 0; + } return 1; @@ -296,18 +296,18 @@ static int lvchange_readahead(struct cmd_context *cmd, } log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); - if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) { - /* FIXME: Attempt reversion? */ - unlock_lv(cmd, lv->lvid.s); + if (!vg_write(lv->vg)) { + /* FIXME: Attempt reversion? */ + unlock_lv(cmd, lv->lvid.s); return 0; } backup(lv->vg); - if (!unlock_lv(cmd, lv->lvid.s)) { - log_error("Problem reactivating %s", lv->name); - return 0; - } + if (!unlock_lv(cmd, lv->lvid.s)) { + log_error("Problem reactivating %s", lv->name); + return 0; + } return 1; } @@ -348,18 +348,18 @@ static int lvchange_persistent(struct cmd_context *cmd, } log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); - if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) { - /* FIXME: Attempt reversion? */ - unlock_lv(cmd, lv->lvid.s); + if (!vg_write(lv->vg)) { + /* FIXME: Attempt reversion? */ + unlock_lv(cmd, lv->lvid.s); return 0; } backup(lv->vg); - if (!unlock_lv(cmd, lv->lvid.s)) { - log_error("Problem reactivating %s", lv->name); - return 0; - } + if (!unlock_lv(cmd, lv->lvid.s)) { + log_error("Problem reactivating %s", lv->name); + return 0; + } return 1; } diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 863c217f..b0114bdc 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -36,8 +36,7 @@ struct lvcreate_params { }; static int _read_name_params(struct lvcreate_params *lp, - struct cmd_context *cmd, int *pargc, - char ***pargv) + struct cmd_context *cmd, int *pargc, char ***pargv) { int argc = *pargc; char **argv = *pargv, *ptr; @@ -56,7 +55,7 @@ static int _read_name_params(struct lvcreate_params *lp, lp->origin = argv[0]; (*pargv)++, (*pargc)--; - if (!(lp->vg_name = extract_vgname(cmd->fid, lp->origin))) { + if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) { log_err("The origin name should include the " "volume group."); return 0; @@ -72,8 +71,7 @@ static int _read_name_params(struct lvcreate_params *lp, * environment. */ if (!argc) { - if (!(lp->vg_name = - extract_vgname(cmd->fid, lp->lv_name))) { + if (!(lp->vg_name = extract_vgname(cmd, lp->lv_name))) { log_err("Please provide a volume group name"); return 0; } @@ -85,7 +83,7 @@ static int _read_name_params(struct lvcreate_params *lp, */ if (lp->lv_name && strchr(lp->lv_name, '/')) { if (!(lp->vg_name = - extract_vgname(cmd->fid, lp->lv_name))) + extract_vgname(cmd, lp->lv_name))) return 0; if (strcmp(lp->vg_name, argv[0])) { @@ -109,8 +107,7 @@ static int _read_name_params(struct lvcreate_params *lp, } static int _read_size_params(struct lvcreate_params *lp, - struct cmd_context *cmd, int *pargc, - char ***pargv) + struct cmd_context *cmd, int *pargc, char ***pargv) { /* * There are two mutually exclusive ways of specifying @@ -311,7 +308,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) /* does VG exist? */ log_verbose("Finding volume group \"%s\"", lp->vg_name); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, lp->vg_name))) { + if (!(vg = vg_read(cmd, lp->vg_name))) { log_error("Volume group \"%s\" doesn't exist", lp->vg_name); return 0; } @@ -382,7 +379,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) return 0; } - if (!(lv = lv_create(cmd->fid, lp->lv_name, status, + if (!(lv = lv_create(vg->fid, lp->lv_name, status, lp->stripes, lp->stripe_size, lp->extents, vg, pvh))) return 0; @@ -401,7 +398,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) return 0; /* store vg on disk(s) */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) return 0; if (!lock_vol(cmd, lv->lvid.s, LCK_LV_ACTIVATE)) @@ -429,7 +426,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) } /* store vg on disk(s) */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) return 0; if (!unlock_lv(cmd, org->lvid.s)) { diff --git a/tools/lvm.c b/tools/lvm.c index 3c42a793..dd4e4de5 100644 --- a/tools/lvm.c +++ b/tools/lvm.c @@ -70,6 +70,8 @@ struct config_info { int archive; /* should we archive ? */ int backup; /* should we backup ? */ + struct format_type *fmt; + mode_t umask; }; @@ -118,7 +120,6 @@ int main(int argc, char **argv) char *namebase, *base; int ret, alias = 0; - setlocale(LC_ALL, ""); if (!init()) return -1; @@ -188,6 +189,20 @@ int yes_no_arg(struct arg *a) return 1; } +int metadatatype_arg(struct arg *a) +{ + if (!strcasecmp(a->value, cmd->fmtt->name)) + a->ptr = cmd->fmtt; + + else if (!strcasecmp(a->value, cmd->fmt1->name)) + a->ptr = cmd->fmt1; + + else + return 0; + + return 1; +} + int _get_int_arg(struct arg *a, char **ptr) { char *val; @@ -574,11 +589,11 @@ int version(struct cmd_context *cmd, int argc, char **argv) { char version[80]; - log_error("LVM version: %s", LVM_VERSION); + log_print("LVM version: %s", LVM_VERSION); if (library_version(version, sizeof(version))) - log_error("Library version: %s", version); + log_print("Library version: %s", version); if (driver_version(version, sizeof(version))) - log_error("Driver version: %s", version); + log_print("Driver version: %s", version); return ECMD_PROCESSED; } @@ -669,6 +684,8 @@ static void _use_settings(struct config_info *settings) archive_enable(settings->archive); backup_enable(settings->backup); + + cmd->fmt = arg_ptr_value(cmd, metadatatype_ARG, settings->fmt); } static char *_copy_command_line(struct pool *mem, int argc, char **argv) @@ -1048,8 +1065,12 @@ static int init(void) { struct stat info; char config_file[PATH_MAX] = ""; + const char *format; mode_t old_umask; + if (!setlocale(LC_ALL, "")) + log_error("setlocale failed"); + if (!_get_env_vars()) return 0; @@ -1139,9 +1160,20 @@ static int init(void) return 0; } - if (!(cmd->fid = create_lvm1_format(cmd))) + /* FIXME Replace with list, dynamic libs etc. */ + if (!(cmd->fmt1 = create_lvm1_format(cmd))) return 0; + if (!(cmd->fmtt = create_text_format(cmd))) + return 0; + + format = find_config_str(cmd->cf->root, "global/format", '/', + DEFAULT_FORMAT); + if (!strcasecmp(format, "text")) + _default_settings.fmt = cmd->fmtt; + else /* "lvm1" */ + _default_settings.fmt = cmd->fmt1; + _use_settings(&_default_settings); return 1; } @@ -1161,7 +1193,8 @@ static void fin(void) if (_dump_filter) persistent_filter_dump(cmd->filter); - cmd->fid->ops->destroy(cmd->fid); + cmd->fmt1->ops->destroy(cmd->fmt1); + cmd->fmtt->ops->destroy(cmd->fmtt); cmd->filter->destroy(cmd->filter); pool_destroy(cmd->mem); vgcache_destroy(); diff --git a/tools/lvmdiskscan.c b/tools/lvmdiskscan.c index 91d165ca..c573517a 100644 --- a/tools/lvmdiskscan.c +++ b/tools/lvmdiskscan.c @@ -44,7 +44,7 @@ int lvmdiskscan(struct cmd_context *cmd, int argc, char **argv) /* Do scan */ for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) { /* Try if it is a PV first */ - if ((pv = cmd->fid->ops->pv_read(cmd->fid, dev_name(dev)))) { + if ((pv = pv_read(cmd, dev_name(dev)))) { if (!dev_get_size(dev, &size)) { log_error("Couldn't get size of \"%s\"", dev_name(dev)); diff --git a/tools/lvremove.c b/tools/lvremove.c index b00f8c97..9b1c1a3c 100644 --- a/tools/lvremove.c +++ b/tools/lvremove.c @@ -50,23 +50,21 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv) return ECMD_FAILED; } - if (!lv_info(lv, &info)) { - stack; - return ECMD_FAILED; - } - - if (info.open_count) { - log_error("Can't remove open logical volume \"%s\"", lv->name); - return ECMD_FAILED; - } - - if (info.exists && !arg_count(cmd, force_ARG)) { - if (yes_no_prompt("Do you really want to remove active " - "logical volume \"%s\"? [y/n]: ", - lv->name) == 'n') { - log_print("Logical volume \"%s\" not removed", + if (lv_info(lv, &info)) { + if (info.open_count) { + log_error("Can't remove open logical volume \"%s\"", lv->name); - return 0; + return ECMD_FAILED; + } + + if (info.exists && !arg_count(cmd, force_ARG)) { + if (yes_no_prompt("Do you really want to remove active " + "logical volume \"%s\"? [y/n]: ", + lv->name) == 'n') { + log_print("Logical volume \"%s\" not removed", + lv->name); + return 0; + } } } @@ -81,7 +79,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv) if (lv_is_cow(lv)) { log_verbose("Removing snapshot %s", lv->name); - if (!vg_remove_snapshot(lv->vg, lv)) { + if (!vg_remove_snapshot(lv->vg, lv)) { stack; return ECMD_FAILED; } @@ -94,7 +92,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv) } /* store it on disks */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (vg_write(vg)) return ECMD_FAILED; backup(vg); diff --git a/tools/lvrename.c b/tools/lvrename.c index e9bea0f7..8f35f051 100644 --- a/tools/lvrename.c +++ b/tools/lvrename.c @@ -39,13 +39,13 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) lv_name_old = argv[0]; lv_name_new = argv[1]; - if (!(vg_name = extract_vgname(cmd->fid, lv_name_old))) { + if (!(vg_name = extract_vgname(cmd, lv_name_old))) { log_error("Please provide a volume group name"); return EINVALID_CMD_LINE; } if (strchr(lv_name_new, '/') && - (vg_name_new = extract_vgname(cmd->fid, lv_name_new)) && + (vg_name_new = extract_vgname(cmd, lv_name_new)) && strcmp(vg_name, vg_name_new)) { log_error("Logical volume names must " "have the same volume group (\"%s\" or \"%s\")", @@ -91,7 +91,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) return ECMD_FAILED; } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" doesn't exist", vg_name); goto error; } @@ -123,8 +123,8 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) if (!archive(lv->vg)) goto error; - if (!lock_vol(cmd, lv->lvid.s, LCK_LV_SUSPEND | LCK_HOLD | - LCK_NONBLOCK)) + if (!lock_vol(cmd, lv->lvid.s, LCK_LV_SUSPEND | LCK_HOLD | + LCK_NONBLOCK)) goto error; if (!(lv->name = pool_strdup(cmd->mem, lv_name_new))) { @@ -133,7 +133,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) } log_verbose("Writing out updated volume group"); - if (!(cmd->fid->ops->vg_write(cmd->fid, vg))) + if (!vg_write(vg)) goto lverror; unlock_lv(cmd, lv->lvid.s); @@ -147,7 +147,6 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) return 0; - lverror: unlock_lv(cmd, lv->lvid.s); diff --git a/tools/lvresize.c b/tools/lvresize.c index 4fec44a4..bd3c5d8d 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -29,6 +29,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) uint32_t size = 0; uint32_t stripes = 0, stripesize = 0; uint32_t seg_stripes = 0, seg_stripesize = 0, seg_size = 0; + uint32_t extents_used = 0; uint32_t size_rest; sign_t sign = SIGN_NONE; char *lv_name, *vg_name; @@ -76,16 +77,6 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } - if (arg_count(cmd, stripes_ARG)) { - log_print("Varied striping not yet supported. Ignoring."); - /* FUTURE stripes = arg_int_value(cmd,stripes_ARG, 1); */ - } - - if (arg_count(cmd, stripesize_ARG)) { - log_print("Varied stripesize not yet supported. Ignoring."); - /* FUTURE stripesize = 2 * arg_int_value(cmd,stripesize_ARG, 0); */ - } - if (!argc) { log_error("Please provide the logical volume name"); return EINVALID_CMD_LINE; @@ -95,7 +86,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) argv++; argc--; - if (!(vg_name = extract_vgname(cmd->fid, lv_name))) { + if (!(vg_name = extract_vgname(cmd, lv_name))) { log_error("Please provide a volume group name"); return EINVALID_CMD_LINE; } @@ -110,7 +101,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) return ECMD_FAILED; } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group %s doesn't exist", vg_name); goto error; } @@ -132,6 +123,20 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) goto error; } + if (arg_count(cmd, stripes_ARG)) { + if (vg->fid->fmt->features & FMT_SEGMENTS) + stripes = arg_int_value(cmd, stripes_ARG, 1); + else + log_print("Varied striping not supported. Ignoring."); + } + + if (arg_count(cmd, stripesize_ARG)) { + if (vg->fid->fmt->features & FMT_SEGMENTS) + stripesize = 2 * arg_int_value(cmd, stripesize_ARG, 0); + else + log_print("Varied stripesize not supported. Ignoring."); + } + lv = lvl->lv; if (size) { @@ -179,6 +184,8 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) goto error_cmdline; } + seg_size = extents - lv->le_count; + /* If extending, find stripes, stripesize & size of last segment */ if (extents > lv->le_count && !(stripes == 1 || (stripes > 1 && stripesize))) { @@ -205,15 +212,22 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) if (!stripes) stripes = seg_stripes; - if (!stripesize && stripes > 1) - stripesize = seg_stripesize; - - seg_size = extents - lv->le_count; + if (!stripesize && stripes > 1) { + if (seg_stripesize) { + log_print("Using stripesize of last segment " + "%dKB", seg_stripesize / 2); + stripesize = seg_stripesize; + } else { + log_print("Using default stripesize %dKB", + STRIPE_SIZE_DEFAULT); + stripesize = 2 * STRIPE_SIZE_DEFAULT; + } + } } /* If reducing, find stripes, stripesize & size of last segment */ if (extents < lv->le_count) { - uint32_t extents_used = 0; + extents_used = 0; if (stripes || stripesize) log_error("Ignoring stripes and stripesize arguments " @@ -240,9 +254,12 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) stripes = seg_stripes; } - if ((size_rest = seg_size % stripes)) { + if (stripes > 1 && !stripesize) { + log_error("Stripesize for striped segment should not be 0!"); + } else if ((stripes > 1) && + (size_rest = seg_size % (stripes * stripesize))) { log_print("Rounding size (%d extents) down to stripe boundary " - "size of last segment (%d extents)", extents, + "size for segment (%d extents)", extents, extents - size_rest); extents = extents - size_rest; } @@ -277,16 +294,17 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) if (argc) log_print("Ignoring PVs on command line when reducing"); - if (!lv_info(lv, &info)) { - stack; + memset(&info, 0, sizeof(info)); + + if (!lv_info(lv, &info) && driver_version(NULL, 0)) { + log_error("lv_info failed: aborting"); goto error; } if (info.exists) { - dummy = - display_size((uint64_t) - extents * (vg->extent_size / 2), - SIZE_SHORT); + dummy = display_size((uint64_t) + extents * (vg->extent_size / 2), + SIZE_SHORT); log_print("WARNING: Reducing active%s logical volume " "to %s", info.open_count ? " and open" : "", dummy); @@ -308,7 +326,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) if (!archive(vg)) goto error; - if (!lv_reduce(cmd->fid, lv, lv->le_count - extents)) + if (!lv_reduce(vg->fid, lv, lv->le_count - extents)) goto error; } @@ -332,7 +350,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) log_print("Extending logical volume %s to %s", lv_name, dummy); dbg_free(dummy); - if (!lv_extend(cmd->fid, lv, stripes, stripesize, + if (!lv_extend(vg->fid, lv, stripes, stripesize, extents - lv->le_count, pvh)) goto error; } @@ -343,7 +361,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) } /* store vg on disk(s) */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) { + if (!vg_write(vg)) { /* FIXME: Attempt reversion? */ unlock_lv(cmd, lv->lvid.s); goto error; diff --git a/tools/pvchange.c b/tools/pvchange.c index 97f22d0d..b509f007 100644 --- a/tools/pvchange.c +++ b/tools/pvchange.c @@ -52,7 +52,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv) log_verbose("Using physical volume(s) on command line"); for (; opt < argc; opt++) { pv_name = argv[opt]; - if (!(pv = cmd->fid->ops->pv_read(cmd->fid, pv_name))) { + if (!(pv = pv_read(cmd, pv_name))) { log_error ("Failed to read physical volume \"%s\"", pv_name); @@ -63,7 +63,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv) } } else { log_verbose("Scanning for physical volume names"); - if (!(pvs = cmd->fid->ops->get_pvs(cmd->fid))) { + if (!(pvs = get_pvs(cmd))) { return ECMD_FAILED; } @@ -103,7 +103,7 @@ int pvchange_single(struct cmd_context *cmd, struct physical_volume *pv) return ECMD_FAILED; } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, pv->vg_name))) { + if (!(vg = vg_read(cmd, pv->vg_name))) { unlock_vg(cmd, pv->vg_name); log_error("Unable to find volume group of \"%s\"", pv_name); @@ -163,7 +163,7 @@ int pvchange_single(struct cmd_context *cmd, struct physical_volume *pv) log_verbose("Updating physical volume \"%s\"", pv_name); if (*pv->vg_name) { - if (!(cmd->fid->ops->vg_write(cmd->fid, vg))) { + if (!vg_write(vg)) { unlock_vg(cmd, pv->vg_name); log_error("Failed to store physical volume \"%s\" in " "volume group \"%s\"", pv_name, vg->name); @@ -172,7 +172,7 @@ int pvchange_single(struct cmd_context *cmd, struct physical_volume *pv) backup(vg); unlock_vg(cmd, pv->vg_name); } else { - if (!(cmd->fid->ops->pv_write(cmd->fid, pv))) { + if (!(pv_write(cmd, pv))) { log_error("Failed to store physical volume \"%s\"", pv_name); return 0; diff --git a/tools/pvcreate.c b/tools/pvcreate.c index 9f58dd66..0cc1d95f 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -39,7 +39,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name) } /* is there a pv here already */ - if (!(pv = cmd->fid->ops->pv_read(cmd->fid, name))) + if (!(pv = pv_read(cmd, name))) return 1; /* orphan ? */ @@ -75,6 +75,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name) static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) { struct physical_volume *pv; + struct format_instance *fid; struct id id, *idp = NULL; char *uuid; uint64_t size = 0; @@ -95,8 +96,14 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) if (!pvcreate_check(cmd, pv_name)) return; - size = arg_int64_value(cmd, physicalvolumesize_ARG, 0) * 2; - if (!(pv = pv_create(cmd->fid, pv_name, idp, size))) { + size = arg_int64_value(cmd, physicalvolumesize_ARG, 0) * 2; + + /* FIXME Use config file/cmd line to specify format */ + if (!(fid = cmd->fmt1->ops->create_instance(cmd->fmt1, NULL, NULL))) { + log_error("Failed to create format1 instance"); + return; + } + if (!(pv = pv_create(fid, pv_name, idp, size))) { log_error("Failed to setup physical volume \"%s\"", pv_name); return; } @@ -106,7 +113,7 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) log_very_verbose("Writing physical volume data to disk \"%s\"", pv_name); - if (!(cmd->fid->ops->pv_write(cmd->fid, pv))) { + if (!(pv_write(cmd, pv))) { log_error("Failed to write physical volume \"%s\"", pv_name); return; } diff --git a/tools/pvdisplay.c b/tools/pvdisplay.c index 5f729dee..b526cc9b 100644 --- a/tools/pvdisplay.c +++ b/tools/pvdisplay.c @@ -38,7 +38,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv) log_very_verbose("Using physical volume(s) on command line"); for (; opt < argc; opt++) { - if (!(pv = cmd->fid->ops->pv_read(cmd->fid, argv[opt]))) { + if (!(pv = pv_read(cmd, argv[opt]))) { log_error("Failed to read physical " "volume \"%s\"", argv[opt]); continue; @@ -47,7 +47,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv) } } else { log_verbose("Scanning for physical volume names"); - if (!(pvs = cmd->fid->ops->get_pvs(cmd->fid))) + if (!(pvs = get_pvs(cmd))) return ECMD_FAILED; list_iterate(pvh, pvs) @@ -67,7 +67,7 @@ void pvdisplay_single(struct cmd_context *cmd, struct physical_volume *pv) if (!*pv->vg_name) size = pv->size; else - size = (pv->pe_count - pv->pe_allocated) * pv->pe_size; + size = (pv->pe_count - pv->pe_alloc_count) * pv->pe_size; if (arg_count(cmd, short_ARG)) { sz = display_size(size / 2, SIZE_SHORT); @@ -112,7 +112,7 @@ void pvdisplay_single(struct cmd_context *cmd, struct physical_volume *pv) return; /******* FIXME - if (pv->pe_allocated) { + if (pv->pe_alloc_count) { if (!(pv->pe = pv_read_pe(pv_name, pv))) goto pvdisplay_device_out; if (!(lvs = pv_read_lvs(pv))) { diff --git a/tools/pvscan.c b/tools/pvscan.c index 42edbc38..868dea47 100644 --- a/tools/pvscan.c +++ b/tools/pvscan.c @@ -57,7 +57,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv) persistent_filter_wipe(cmd->filter); log_verbose("Walking through all physical volumes"); - if (!(pvs = cmd->fid->ops->get_pvs(cmd->fid))) + if (!(pvs = get_pvs(cmd))) return ECMD_FAILED; /* eliminate exported/new if required */ @@ -65,8 +65,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv) pvl = list_item(pvh, struct pv_list); pv = pvl->pv; - if ( - (arg_count(cmd, exported_ARG) + if ((arg_count(cmd, exported_ARG) && !(pv->status & EXPORTED_VG)) || (arg_count(cmd, novolumegroup_ARG) && (*pv->vg_name))) { list_del(&pvl->list); @@ -90,7 +89,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv) size_new += pv->size; size_total += pv->size; } else - size_total += (pv->pe_count - pv->pe_allocated) + size_total += (pv->pe_count - pv->pe_alloc_count) * pv->pe_size; } @@ -175,7 +174,7 @@ void pvscan_display_single(struct cmd_context *cmd, struct physical_volume *pv) } if (!*pv->vg_name) { - log_print("PV %-*s %-*s [%s]", + log_print("PV %-*s %-*s [%s]", pv_max_name_len, pv_tmp_name, vg_max_name_len, " ", (s1 = display_size(pv->size / 2, SIZE_SHORT))); @@ -192,7 +191,7 @@ void pvscan_display_single(struct cmd_context *cmd, struct physical_volume *pv) display_size(pv->pe_count * pv->pe_size / 2, SIZE_SHORT)), - (s2 = display_size((pv->pe_count - pv->pe_allocated) + (s2 = display_size((pv->pe_count - pv->pe_alloc_count) * pv->pe_size / 2, SIZE_SHORT))); dbg_free(s1); dbg_free(s2); @@ -201,12 +200,13 @@ void pvscan_display_single(struct cmd_context *cmd, struct physical_volume *pv) sprintf(vg_tmp_name, "%s", pv->vg_name); log_print - ("PV %-*s VG %-*s [%s / %s free]", pv_max_name_len, + ("PV %-*s VG %-*s %s [%s / %s free]", pv_max_name_len, pv_tmp_name, vg_max_name_len, vg_tmp_name, + pv->fid ? pv->fid->fmt->name : " ", (s1 = display_size(pv->pe_count * pv->pe_size / 2, SIZE_SHORT)), (s2 = - display_size((pv->pe_count - pv->pe_allocated) * pv->pe_size / 2, - SIZE_SHORT))); + display_size((pv->pe_count - pv->pe_alloc_count) * pv->pe_size / + 2, SIZE_SHORT))); dbg_free(s1); dbg_free(s2); diff --git a/tools/toollib.c b/tools/toollib.c index 935d9f37..9b628ab0 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -57,30 +57,30 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, char *lv_name = argv[opt]; /* does VG exist? */ - if (!(vg_name = extract_vgname(cmd->fid, lv_name))) { + if (!(vg_name = extract_vgname(cmd, lv_name))) { if (ret_max < ECMD_FAILED) ret_max = ECMD_FAILED; continue; } log_verbose("Finding volume group \"%s\"", vg_name); - if (!lock_vol(cmd, vg_name, lock_type)) { - log_error("Can't lock %s: skipping", vg_name); - continue; - } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!lock_vol(cmd, vg_name, lock_type)) { + log_error("Can't lock %s: skipping", vg_name); + continue; + } + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" doesn't exist", vg_name); if (ret_max < ECMD_FAILED) ret_max = ECMD_FAILED; - unlock_vg(cmd, vg_name); + unlock_vg(cmd, vg_name); continue; } if (vg->status & EXPORTED_VG) { log_error("Volume group \"%s\" is exported", vg->name); - unlock_vg(cmd, vg_name); + unlock_vg(cmd, vg_name); return ECMD_FAILED; } @@ -102,26 +102,26 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, } } else { log_verbose("Finding all logical volumes"); - if (!(vgs = cmd->fid->ops->get_vgs(cmd->fid))) { + if (!(vgs = get_vgs(cmd))) { log_error("No volume groups found"); return ECMD_FAILED; } list_iterate(vgh, vgs) { vg_name = list_item(vgh, struct name_list)->name; - if (!lock_vol(cmd, vg_name, lock_type)) { - log_error("Can't lock %s: skipping", vg_name); - continue; - } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!lock_vol(cmd, vg_name, lock_type)) { + log_error("Can't lock %s: skipping", vg_name); + continue; + } + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" not found", vg_name); if (ret_max < ECMD_FAILED) ret_max = ECMD_FAILED; - unlock_vg(cmd, vg_name); + unlock_vg(cmd, vg_name); continue; } ret = process_each_lv_in_vg(cmd, vg, process_single); - unlock_vg(cmd, vg_name); + unlock_vg(cmd, vg_name); if (ret > ret_max) ret_max = ret; vg_count++; @@ -144,11 +144,19 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv, struct list *vgs; char *vg_name; + char *dev_dir = cmd->dev_dir; if (argc) { log_verbose("Using volume group(s) on command line"); for (; opt < argc; opt++) { vg_name = argv[opt]; + if (!strncmp(vg_name, dev_dir, strlen(dev_dir))) + vg_name += strlen(dev_dir); + if (strchr(vg_name, '/')) { + log_error("Invalid volume group name: %s", + vg_name); + continue; + } if (!lock_vol(cmd, vg_name, lock_type)) { log_error("Can't lock %s: skipping", vg_name); continue; @@ -159,7 +167,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv, } } else { log_verbose("Finding all volume groups"); - if (!(vgs = cmd->fid->ops->get_vgs(cmd->fid))) { + if (!(vgs = get_vgs(cmd))) { log_error("No volume groups found"); return ECMD_FAILED; } @@ -247,11 +255,11 @@ int is_valid_chars(char *n) return 1; } -char *extract_vgname(struct format_instance *fi, char *lv_name) +char *extract_vgname(struct cmd_context *cmd, char *lv_name) { char *vg_name = lv_name; char *st; - char *dev_dir = fi->cmd->dev_dir; + char *dev_dir = cmd->dev_dir; /* Path supplied? */ if (vg_name && strchr(vg_name, '/')) { @@ -267,7 +275,7 @@ char *extract_vgname(struct format_instance *fi, char *lv_name) return 0; } - vg_name = pool_strdup(fi->cmd->mem, vg_name); + vg_name = pool_strdup(cmd->mem, vg_name); if (!vg_name) { log_error("Allocation of vg_name failed"); return 0; @@ -277,7 +285,7 @@ char *extract_vgname(struct format_instance *fi, char *lv_name) return vg_name; } - if (!(vg_name = default_vgname(fi))) { + if (!(vg_name = default_vgname(cmd))) { if (lv_name) log_error("Path required for Logical Volume \"%s\"", lv_name); @@ -287,10 +295,10 @@ char *extract_vgname(struct format_instance *fi, char *lv_name) return vg_name; } -char *default_vgname(struct format_instance *fi) +char *default_vgname(struct cmd_context *cmd) { char *vg_path; - char *dev_dir = fi->cmd->dev_dir; + char *dev_dir = cmd->dev_dir; /* Take default VG from environment? */ vg_path = getenv("LVM_VG_NAME"); @@ -307,7 +315,7 @@ char *default_vgname(struct format_instance *fi) return 0; } - return pool_strdup(fi->cmd->mem, vg_path); + return pool_strdup(cmd->mem, vg_path); } struct list *create_pv_list(struct pool *mem, @@ -332,7 +340,7 @@ struct list *create_pv_list(struct pool *mem, return NULL; } - if (pvl->pv->pe_count == pvl->pv->pe_allocated) { + if (pvl->pv->pe_count == pvl->pv->pe_alloc_count) { log_err("No free extents on physical volume \"%s\"", argv[i]); continue; diff --git a/tools/toollib.h b/tools/toollib.h index aa2f7f9e..49f06fbe 100644 --- a/tools/toollib.h +++ b/tools/toollib.h @@ -54,8 +54,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg, int is_valid_chars(char *n); -char *default_vgname(struct format_instance *fi); -char *extract_vgname(struct format_instance *fi, char *lv_name); +char *default_vgname(struct cmd_context *cmd); +char *extract_vgname(struct cmd_context *cmd, char *lv_name); /* * Builds a list of pv's from the names in argv. Used in diff --git a/tools/tools.h b/tools/tools.h index 34dfdb5a..b3a934af 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -4,8 +4,8 @@ * This file is released under the LGPL. */ -#ifndef _LVM_LVM_H -#define _LVM_LVM_H +#ifndef _LVM_TOOLS_H +#define _LVM_TOOLS_H #include "pool.h" #include "dbg_malloc.h" @@ -75,6 +75,7 @@ struct arg { uint32_t i_value; uint64_t i64_value; sign_t sign; + void *ptr; }; /* a register of the lvm commands */ @@ -98,6 +99,7 @@ int int_arg_with_sign(struct arg *a); int minor_arg(struct arg *a); int string_arg(struct arg *a); int permission_arg(struct arg *a); +int metadatatype_arg(struct arg *a); char yes_no_prompt(const char *prompt, ...); @@ -129,6 +131,11 @@ static inline uint64_t arg_int64_value(struct cmd_context *cmd, int a, return arg_count(cmd, a) ? cmd->args[a].i64_value : def; } +static inline void *arg_ptr_value(struct cmd_context *cmd, int a, void *def) +{ + return arg_count(cmd, a) ? cmd->args[a].ptr : def; +} + static inline sign_t arg_sign_value(struct cmd_context *cmd, int a, sign_t def) { return arg_count(cmd, a) ? cmd->args[a].sign : def; diff --git a/tools/vgcfgbackup.c b/tools/vgcfgbackup.c index 93f65a17..b7419a20 100644 --- a/tools/vgcfgbackup.c +++ b/tools/vgcfgbackup.c @@ -12,17 +12,21 @@ static int _backup_to_file(const char *file, struct volume_group *vg) { int r; struct format_instance *tf; + void *context; - if (!(tf = text_format_create(vg->cmd, file, vg->cmd->um, - vg->cmd->cmd_line))) { + if (!(context = create_text_context(vg->cmd->fmtt, file, + vg->cmd->cmd_line)) || + !(tf = vg->cmd->fmtt->ops->create_instance(vg->cmd->fmtt, NULL, + context))) { log_error("Couldn't create backup object."); return 0; } - if (!(r = tf->ops->vg_write(tf, vg))) + if (!(r = tf->fmt->ops->vg_write(tf, vg, context)) || + !(r = tf->fmt->ops->vg_commit(tf, vg, context))) stack; - tf->ops->destroy(tf); + tf->fmt->ops->destroy_instance(tf); return r; } @@ -31,7 +35,7 @@ static int vg_backup_single(struct cmd_context *cmd, const char *vg_name) struct volume_group *vg; log_verbose("Checking for volume group \"%s\"", vg_name); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" not found", vg_name); return ECMD_FAILED; } diff --git a/tools/vgchange.c b/tools/vgchange.c index 4e680e27..87424f06 100644 --- a/tools/vgchange.c +++ b/tools/vgchange.c @@ -78,7 +78,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name) { struct volume_group *vg; - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Unable to find volume group \"%s\"", vg_name); return ECMD_FAILED; } @@ -158,7 +158,7 @@ void vgchange_resizeable(struct cmd_context *cmd, struct volume_group *vg) else vg->status &= ~RESIZEABLE_VG; - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) return; backup(vg); @@ -190,7 +190,7 @@ void vgchange_logicalvolume(struct cmd_context *cmd, struct volume_group *vg) vg->max_lv = max_lv; - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) return; backup(vg); diff --git a/tools/vgck.c b/tools/vgck.c index 12730b51..e90f5317 100644 --- a/tools/vgck.c +++ b/tools/vgck.c @@ -33,7 +33,7 @@ static int vgck_single(struct cmd_context *cmd, const char *vg_name) log_verbose("Checking volume group \"%s\"", vg_name); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" not found", vg_name); return ECMD_FAILED; } diff --git a/tools/vgcreate.c b/tools/vgcreate.c index 1eb5adef..7adc2f0e 100644 --- a/tools/vgcreate.c +++ b/tools/vgcreate.c @@ -80,7 +80,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) } /* Create the new VG */ - if (!(vg = vg_create(cmd->fid, vg_name, extent_size, max_pv, max_lv, + if (!(vg = vg_create(cmd, vg_name, extent_size, max_pv, max_lv, argc - 1, argv + 1))) return ECMD_FAILED; @@ -110,7 +110,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) } /* Store VG on disk(s) */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) { + if (!vg_write(vg)) { unlock_vg(cmd, vg_name); unlock_vg(cmd, ""); return ECMD_FAILED; diff --git a/tools/vgdisplay.c b/tools/vgdisplay.c index c3e494ba..dddd89ba 100644 --- a/tools/vgdisplay.c +++ b/tools/vgdisplay.c @@ -70,7 +70,7 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name) /* FIXME Do the active check here if activevolumegroups_ARG ? */ log_very_verbose("Finding volume group \"%s\"", vg_name); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" doesn't exist", vg_name); return ECMD_FAILED; } diff --git a/tools/vgexport.c b/tools/vgexport.c index 40502c89..31361d1a 100644 --- a/tools/vgexport.c +++ b/tools/vgexport.c @@ -41,7 +41,7 @@ static int vgexport_single(struct cmd_context *cmd, const char *vg_name) { struct volume_group *vg; - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Unable to find volume group \"%s\"", vg_name); goto error; } @@ -67,7 +67,7 @@ static int vgexport_single(struct cmd_context *cmd, const char *vg_name) vg->status |= EXPORTED_VG; - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) goto error; backup(vg); diff --git a/tools/vgextend.c b/tools/vgextend.c index 62ee8de3..81d903e4 100644 --- a/tools/vgextend.c +++ b/tools/vgextend.c @@ -52,7 +52,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) goto error; } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" not found.", vg_name); goto error; } @@ -83,7 +83,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) goto error; /* extend vg */ - if (!vg_extend(cmd->fid, vg, argc, argv)) + if (!vg_extend(vg->fid, vg, argc, argv)) goto error; /* ret > 0 */ @@ -91,7 +91,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) "physical volumes", vg_name, argc); /* store vg on disk(s) */ - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) goto error; backup(vg); diff --git a/tools/vgimport.c b/tools/vgimport.c index 1d377eb2..e16fe0fb 100644 --- a/tools/vgimport.c +++ b/tools/vgimport.c @@ -41,7 +41,7 @@ static int vgimport_single(struct cmd_context *cmd, const char *vg_name) { struct volume_group *vg; - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Unable to find exported volume group \"%s\"", vg_name); goto error; @@ -62,7 +62,7 @@ static int vgimport_single(struct cmd_context *cmd, const char *vg_name) vg->status &= ~EXPORTED_VG; - if (!cmd->fid->ops->vg_write(cmd->fid, vg)) + if (!vg_write(vg)) goto error; backup(vg); diff --git a/tools/vgmerge.c b/tools/vgmerge.c index 72c4b7e1..05bdcbe3 100644 --- a/tools/vgmerge.c +++ b/tools/vgmerge.c @@ -65,7 +65,7 @@ int vgmerge_single(struct cmd_context *cmd, const char *vg_name_to, return ECMD_FAILED; } - if (!(vg_to = cmd->fid->ops->vg_read(cmd->fid, vg_name_to))) { + if (!(vg_to = vg_read(cmd, vg_name_to))) { log_error("Volume group \"%s\" doesn't exist", vg_name_to); unlock_vg(cmd, vg_name_to); return ECMD_FAILED; @@ -90,7 +90,7 @@ int vgmerge_single(struct cmd_context *cmd, const char *vg_name_to, return ECMD_FAILED; } - if (!(vg_from = cmd->fid->ops->vg_read(cmd->fid, vg_name_from))) { + if (!(vg_from = vg_read(cmd, vg_name_from))) { log_error("Volume group \"%s\" doesn't exist", vg_name_from); goto error; } @@ -182,7 +182,7 @@ int vgmerge_single(struct cmd_context *cmd, const char *vg_name_to, /* store it on disks */ log_verbose("Writing out updated volume group"); - if (!(cmd->fid->ops->vg_write(cmd->fid, vg_to))) { + if (!vg_write(vg_to)) { goto error; } diff --git a/tools/vgreduce.c b/tools/vgreduce.c index 0bdfd33c..72d31c71 100644 --- a/tools/vgreduce.c +++ b/tools/vgreduce.c @@ -56,7 +56,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv) return ECMD_FAILED; } - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" doesn't exist", vg_name); unlock_vg(cmd, vg_name); return ECMD_FAILED; @@ -112,12 +112,12 @@ static int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg, struct pv_list *pvl; const char *name = dev_name(pv->dev); - if (pv->pe_allocated) { + if (pv->pe_alloc_count) { log_error("Physical volume \"%s\" still in use", name); return ECMD_FAILED; } -/********* FIXME: Is this unnecessary after checking pe_allocated? +/********* FIXME: Is this unnecessary after checking pe_alloc_count? if (pv->lv_cur > 0) { log_error ("can't reduce volume group \"%s\" by used physical volume \"%s\"", vg_name, error_pv_name); } @@ -141,16 +141,16 @@ static int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg, *pv->vg_name = '\0'; vg->pv_count--; - vg->free_count -= pv->pe_count - pv->pe_allocated; + vg->free_count -= pv->pe_count - pv->pe_alloc_count; vg->extent_count -= pv->pe_count; - if (!(cmd->fid->ops->vg_write(cmd->fid, vg))) { + if (!vg_write(vg)) { log_error("Removal of physical volume \"%s\" from " "\"%s\" failed", name, vg->name); return ECMD_FAILED; } - if (!cmd->fid->ops->pv_write(cmd->fid, pv)) { + if (!pv_write(cmd, pv)) { log_error("Failed to clear metadata from physical " "volume \"%s\" " "after removal from \"%s\"", name, vg->name); diff --git a/tools/vgremove.c b/tools/vgremove.c index 8b9753b1..2e47dfce 100644 --- a/tools/vgremove.c +++ b/tools/vgremove.c @@ -31,7 +31,7 @@ int vgremove(struct cmd_context *cmd, int argc, char **argv) return ECMD_FAILED; } - ret = process_each_vg(cmd, argc, argv, + ret = process_each_vg(cmd, argc, argv, LCK_VG | LCK_WRITE | LCK_NONBLOCK, &vgremove_single); @@ -48,7 +48,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name) int ret = 0; log_verbose("Checking for volume group \"%s\"", vg_name); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" doesn't exist", vg_name); return ECMD_FAILED; } @@ -73,12 +73,10 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name) if (!archive(vg)) return ECMD_FAILED; -/************ FIXME - if (vg_remove_dir_and_group_and_nodes(vg_name) < 0) { - log_error("removing special files of volume group \"%s\"", - vg_name); + if (!vg_remove(vg)) { + log_error("vg_remove %s failed", vg_name); + return ECMD_FAILED; } -*************/ /* init physical volumes */ list_iterate(pvh, &vg->pvs) { @@ -86,7 +84,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name) log_verbose("Removing physical volume \"%s\" from " "volume group \"%s\"", dev_name(pv->dev), vg_name); *pv->vg_name = '\0'; - if (!(cmd->fid->ops->pv_write(cmd->fid, pv))) { + if (!pv_write(cmd, pv)) { log_error("Failed to remove physical volume \"%s\"" " from volume group \"%s\"", dev_name(pv->dev), vg_name); diff --git a/tools/vgrename.c b/tools/vgrename.c index cde54217..b05003a1 100644 --- a/tools/vgrename.c +++ b/tools/vgrename.c @@ -74,7 +74,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv) return ECMD_FAILED; } - if (!(vg_old = cmd->fid->ops->vg_read(cmd->fid, vg_name_old))) { + if (!(vg_old = vg_read(cmd, vg_name_old))) { log_error("Volume group \"%s\" doesn't exist", vg_name_old); unlock_vg(cmd, vg_name_old); return ECMD_FAILED; @@ -112,7 +112,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv) return ECMD_FAILED; } - if ((vg_new = cmd->fid->ops->vg_read(cmd->fid, vg_name_new))) { + if ((vg_new = vg_read(cmd, vg_name_new))) { log_error("New volume group \"%s\" already exists", vg_name_new); goto error; @@ -150,7 +150,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv) /* store it on disks */ log_verbose("Writing out updated volume group"); - if (!(cmd->fid->ops->vg_write(cmd->fid, vg_old))) { + if (!vg_write(vg_old)) { goto error; } diff --git a/tools/vgscan.c b/tools/vgscan.c index 938553c4..504f5347 100644 --- a/tools/vgscan.c +++ b/tools/vgscan.c @@ -46,13 +46,14 @@ static int vgscan_single(struct cmd_context *cmd, const char *vg_name) log_verbose("Checking for volume group \"%s\"", vg_name); - if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) { + if (!(vg = vg_read(cmd, vg_name))) { log_error("Volume group \"%s\" not found", vg_name); return ECMD_FAILED; } - log_print("Found %svolume group \"%s\"", - (vg->status & EXPORTED_VG) ? "exported " : "", vg_name); + log_print("Found %svolume group \"%s\" using metadata type %s", + (vg->status & EXPORTED_VG) ? "exported " : "", vg_name, + vg->fid->fmt->name); return 0; } |