1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

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.
This commit is contained in:
Alasdair Kergon 2002-04-24 18:20:51 +00:00
parent 0ad98cabde
commit 63875e7591
88 changed files with 2400 additions and 1788 deletions

View File

@ -1 +1 @@
0.95.05-cvs (2002-04-23)
1.95.06-cvs (2002-04-24)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);
struct cs *c;
struct pool *mem = pool_create(10 * 1024);
if (!mem) {
stack;
return 0;
}
if (!mem) {
stack;
return 0;
}
if (!(c = pool_alloc(mem, sizeof(*c)))) {
stack;
pool_destroy(mem);
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;
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;
struct parser *p;
struct stat info;
int r = 1, fd;
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
stack;
return 0;
}
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;
}
/* 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;
}
if (info.st_size == 0) {
log_verbose("%s is empty", file);
return 1;
}
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;
if ((fd = open(file, O_RDONLY)) < 0) {
log_sys_error("open", file);
return 0;
}
/* parse */
p->tb = p->te = p->fb;
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;
}
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;
}
/* unmap the file */
if (munmap((char *) p->fb, info.st_size)) {
log_sys_error("munmap", file);
r = 0;
}
close(fd);
return r;
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++;
while ((p->te != p->fe) && (*p->te != '"')) {
if ((*p->te == '\\') && (p->te + 1 != p->fe))
p->te++;
p->te++;
}
break;
if (p->te != p->fe)
p->te++;
break;
case '}':
p->t = TOK_SECTION_E;
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;
case '[':
p->t = TOK_ARRAY_B;
p->te++;
break;
default:
p->t = TOK_IDENTIFIER;
while ((p->te != p->fe) && !isspace(*p->te) &&
(*p->te != '#') && (*p->te != '='))
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) {
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;
}

View File

@ -26,6 +26,8 @@
#define DEFAULT_UMASK 0077
#define DEFAULT_FORMAT "lvm1"
#ifdef READLINE_SUPPORT
#define DEFAULT_MAX_HISTORY 100
#endif

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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 {

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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));
}

View File

@ -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

View File

@ -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);
out:
r = 1;
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)
{
dbg_free(fi);
}
struct format_instance *fid;
struct metadata_area *mda;
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,
};
struct format_instance *create_lvm1_format(struct cmd_context *cmd)
{
struct format_instance *fi = dbg_malloc(sizeof(*fi));
if (!fi) {
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
stack;
return NULL;
}
fi->cmd = cmd;
fi->ops = &_format1_ops;
fi->private = NULL;
fid->fmt = fmt;
list_init(&fid->metadata_areas);
return fi;
/* 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)
{
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,
create_instance:_create_instance,
destroy_instance:_destroy_instance,
destroy: _destroy,
};
struct format_type *create_lvm1_format(struct cmd_context *cmd)
{
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
if (!fmt) {
stack;
return NULL;
}
fmt->cmd = cmd;
fmt->ops = &_format1_ops;
fmt->name = FMT_LVM1_NAME;
fmt->features = 0;
fmt->private = NULL;
return fmt;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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 - "

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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 (fclose(fp)) {
log_sys_error("fclose", tc->path);
if (fsync(fd)) {
log_sys_error("fsync", tc->path_edit);
fclose(fp);
return 0;
}
if (rename(temp_file, tc->path)) {
log_error("%s: rename to %s failed: %s", temp_file, tc->path,
strerror(errno));
if (fclose(fp)) {
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 struct list *_get_vgs(struct format_instance *fi)
static int _pv_commit(struct format_instance *fi, struct physical_volume *pv,
void *mdl)
{
struct text_c *tc = (struct text_c *) fi->private;
struct list *names = pool_alloc(fi->cmd->mem, sizeof(*names));
// 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;
}
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;
}
/* Add vgname to list if it's not already there */
static int _add_vgname(struct format_type *fmt, struct list *names,
char *vgname)
{
struct list *nlh;
struct name_list *nl;
list_iterate(nlh, names) {
nl = list_item(nlh, struct name_list);
if (!strcmp(vgname, nl->name))
return 1;
}
vgcache_add(vgname, NULL, NULL, fmt);
if (!(nl = pool_alloc(fmt->cmd->mem, sizeof(*nl)))) {
stack;
return 0;
}
if (!(nl->name = pool_strdup(fmt->cmd->mem, vgname))) {
log_error("strdup %s failed", vgname);
return 0;
}
list_add(names, &nl->list);
return 1;
}
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;
}
static struct list *_get_pvs(struct format_type *fmt, struct list *results)
{
struct pv_list *pvl, *rhl;
struct list *vgh;
struct list *pvh;
struct list *names = pool_alloc(fmt->cmd->mem, sizeof(*names));
struct list *rh;
struct name_list *nl;
struct volume_group *vg;
char *slash;
char *vgname;
if (!names) {
list_init(names);
if (!_get_vgs(fmt, names)) {
stack;
return NULL;
}
list_init(names);
/* 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);
}
vg = _vg_read(fi, vgname);
if (vg) {
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 names;
bad:
pool_free(fi->cmd->mem, names);
return NULL;
}
static struct list *_get_pvs(struct format_instance *fi)
{
struct pv_list *pvl;
struct list *vgh;
struct list *pvh;
struct list *results = pool_alloc(fi->cmd->mem, sizeof(*results));
struct list *vgs = _get_vgs(fi);
list_init(results);
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 (!(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);
pvl = pool_alloc(fi->cmd->mem, sizeof(*pvl));
if (!pvl) {
stack;
goto bad;
/* 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;
/* Look for the PV */
list_iterate(vgh, vgs) {
struct volume_group *vg;
struct name_list *nl;
/* 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;
}
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;
}
dbg_free(tc->path);
dbg_free(tc->desc);
dbg_free(tc);
dbg_free(fi);
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;
}
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))) {
return 0;
}
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 (!(d = dbg_strdup(desc))) {
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;
}
if (!(tc = dbg_malloc(sizeof(*tc)))) {
stack;
goto no_mem;
list_init(dir_list);
fmt->private = (void *) dir_list;
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;
}
tc->path = path;
tc->desc = d;
tc->um = um;
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
log_error("Invalid string in config file: "
"metadata/dirs");
goto err;
}
fi->cmd = cmd;
fi->ops = &_text_handler;
fi->private = tc;
if (!_add_dir(cv->v.str, dir_list)) {
log_error("Failed to add %s to internal device cache",
cv->v.str);
goto err;
}
}
return fi;
return fmt;
no_mem:
if (fi)
dbg_free(fi);
err:
_free_dirs(dir_list);
if (path)
dbg_free(path);
if (d)
dbg_free(path);
log_err("Couldn't allocate text format object.");
dbg_free(fmt);
return NULL;
}

View File

@ -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

View File

@ -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);

View File

@ -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(fid->fmt->cmd->mem, cf, when, desc);
_read_desc(cmd->mem, cf, when, desc);
out:
out:
destroy_config_file(cf);
return vg;
}

View File

@ -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;

View File

@ -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;
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];
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;
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;
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;
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);
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;
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];
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, &sectsize))
return 0;
if (!dev_open(dev, O_RDONLY))
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_get_size(dev, &size))
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);
if (!dev_get_sectsize(dev, &sectsize))
return 0;
/* Make sure datalen is a sensible size too */
if (incore->extra_len > sectsize)
continue;
if (!dev_open(dev, O_RDONLY))
return 0;
/* 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]);
dbg_free(block);
dev_close(dev);
/* 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;
return 0;
/* 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);
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];
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_size(dev, &size))
return 0;
if (!dev_get_sectsize(dev, &sectsize))
return 0;
if (!dev_get_sectsize(dev, &sectsize))
return 0;
/* Can the metata fit in the remaining space ? */
if (label->extra_len > sectsize - sizeof(struct label_ondisk))
return 0;
/* Can the metata fit in the remaining space ? */
if (label->extra_len > sectsize - sizeof(struct label_ondisk))
return 0;
block = dbg_malloc(sizeof(struct label_ondisk) + label->extra_len);
if (!block)
{
stack;
return 0;
}
ondisk = (struct label_ondisk *)block;
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]);
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));
/* 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;
}
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");
}
/* Write metadata to disk */
if (!dev_open(dev, O_RDWR))
{
dbg_free(block);
return 0;
}
dev_close(dev);
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);
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;
struct label *l;
int status;
struct filter_private *fp = (struct filter_private *) f->private;
status = lvm2_label_read(NULL, dev, &l);
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;
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_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_LESSEQUAL:
if (l->version[0] == fp->version[0] &&
l->version[1] <= fp->version[1])
return 1;
break;
case VERSION_MATCH_ANY:
return 1;
}
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];
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_size(dev, &size))
return 0;
if (!dev_get_sectsize(dev, &sectsize))
return 0;
if (!dev_get_sectsize(dev, &sectsize))
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;
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]);
/* 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[1], sectsize, block2))
goto finish;
dev_close(dev);
/* 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;
/* 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;
finish:
dbg_free(block2);
dbg_free(block1);
return 0;
}
ondisk1 = (struct label_ondisk *)block1;
ondisk2 = (struct label_ondisk *)block2;
get_label_locations(size, sectsize, &offset[0], &offset[1]);
/* 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[1], sectsize, block2))
goto finish;
dev_close(dev);
/* 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;
/* 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;
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, &sectsize))
return 0;
if (!dev_get_sectsize(dev, &sectsize))
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);
}

View File

@ -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

View File

@ -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

View File

@ -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];
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);
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);
}
/* 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);

View File

@ -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))

View File

@ -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;

View File

@ -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))

View File

@ -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;
}

View File

@ -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 this object.
* Destructor for format instance
*/
void (*destroy)(struct format_instance *fi);
void (*destroy_instance)(struct format_instance *fid);
/*
* Destructor for format type
*/
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,

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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");

View File

@ -74,7 +74,6 @@ int ttree_insert(struct ttree *tt, unsigned int *key, void *data)
} while (*c && count);
if (!*c) {
count++;

View File

@ -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);

View File

@ -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);

View File

@ -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);
if (!hash_insert(_vgidhash, vgn->vgid, vgn)) {
log_error("vgcache_add: vgid hash insertion "
"failed");
return 0;
}
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 (!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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
"\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
"\t[-h|--help]" "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
"\t[-M|--metadatatype lvm1/text] " "\n"
"\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\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",

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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();

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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))) {

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}