1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

Remove hard-coded 64k text metadata writing restriction.

This commit is contained in:
Alasdair Kergon 2005-06-07 11:00:07 +00:00
parent 8b80d2a57c
commit 5748cb17f8
6 changed files with 71 additions and 40 deletions

View File

@ -1,5 +1,6 @@
Version 2.01.11 -
==============================
Remove hard-coded 64k text metadata writing restriction.
Make VG name restrictions consistent.
Introduce lvconvert. So far only removes mirror images.
Allow mirror images to be resized.

View File

@ -30,7 +30,7 @@
struct formatter;
typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment,
const char *fmt, va_list ap);
typedef void (*nl_fn) (struct formatter * f);
typedef int (*nl_fn) (struct formatter * f);
/*
* The first half of this file deals with
* exporting the vg, ie. writing it to a file.
@ -42,7 +42,7 @@ struct formatter {
union {
FILE *fp; /* where we're writing to */
struct {
char *buf;
char *start;
uint32_t size;
uint32_t used;
} buf;
@ -95,22 +95,34 @@ static void _dec_indent(struct formatter *f)
/*
* Newline function for prettier layout.
*/
static void _nl_file(struct formatter *f)
static int _nl_file(struct formatter *f)
{
fprintf(f->data.fp, "\n");
return 1;
}
static void _nl_raw(struct formatter *f)
static int _nl_raw(struct formatter *f)
{
if (f->data.buf.used >= f->data.buf.size - 1)
return;
char *newbuf;
*f->data.buf.buf = '\n';
f->data.buf.buf += 1;
/* If metadata doesn't fit, double the buffer size */
if (f->data.buf.used + 2 > f->data.buf.size) {
if (!(newbuf = dbg_realloc(f->data.buf.start,
f->data.buf.size * 2))) {
stack;
return 0;
}
f->data.buf.start = newbuf;
f->data.buf.size *= 2;
}
*(f->data.buf.start + f->data.buf.used) = '\n';
f->data.buf.used += 1;
*f->data.buf.buf = '\0';
return;
*(f->data.buf.start + f->data.buf.used) = '\0';
return 1;
}
#define COMMENT_TAB 6
@ -153,17 +165,27 @@ static int _out_with_comment_raw(struct formatter *f, const char *comment,
const char *fmt, va_list ap)
{
int n;
char *newbuf;
n = vsnprintf(f->data.buf.buf, f->data.buf.size - f->data.buf.used,
fmt, ap);
retry:
n = vsnprintf(f->data.buf.start + f->data.buf.used,
f->data.buf.size - f->data.buf.used, fmt, ap);
if (n < 0 || (n > f->data.buf.size - f->data.buf.used - 1))
return 0;
/* If metadata doesn't fit, double the buffer size */
if (n < 0 || (n + f->data.buf.used + 2 > f->data.buf.size)) {
if (!(newbuf = dbg_realloc(f->data.buf.start,
f->data.buf.size * 2))) {
stack;
return 0;
}
f->data.buf.start = newbuf;
f->data.buf.size *= 2;
goto retry;
}
f->data.buf.buf += n;
f->data.buf.used += n;
f->nl(f);
outnl(f);
return 1;
}
@ -257,10 +279,10 @@ static int _print_header(struct formatter *f,
outf(f, "# Generated by LVM2: %s", ctime(&t));
outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\"");
outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE);
f->nl(f);
outnl(f);
outf(f, "description = \"%s\"", desc);
f->nl(f);
outnl(f);
outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
_utsname.sysname, _utsname.nodename, _utsname.release,
_utsname.version, _utsname.machine);
@ -309,7 +331,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
/* Default policy is NORMAL; INHERIT is meaningless */
if (vg->alloc != ALLOC_NORMAL && vg->alloc != ALLOC_INHERIT) {
f->nl(f);
outnl(f);
outf(f, "allocation_policy = \"%s\"",
get_alloc_string(vg->alloc));
}
@ -346,7 +368,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
return 0;
}
f->nl(f);
outnl(f);
outf(f, "%s {", name);
_inc_indent(f);
@ -360,7 +382,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
stack;
return 0;
}
f->nl(f);
outnl(f);
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) {
stack;
@ -407,7 +429,7 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
return 0;
}
f->nl(f);
outnl(f);
outf(f, "type = \"%s\"", seg->segtype->name);
if (!list_empty(&seg->tags)) {
@ -436,7 +458,7 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
const char *name;
unsigned int s;
f->nl(f);
outnl(f);
outf(f, "%ss = [", type);
_inc_indent(f);
@ -472,7 +494,7 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
char buffer[4096];
int seg_count;
f->nl(f);
outnl(f);
outf(f, "%s {", lv->name);
_inc_indent(f);
@ -509,7 +531,7 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
if (lv->minor >= 0)
outf(f, "minor = %d", lv->minor);
outf(f, "segment_count = %u", list_size(&lv->segments));
f->nl(f);
outnl(f);
seg_count = 1;
list_iterate_items(seg, &lv->segments) {
@ -641,11 +663,11 @@ static int _text_vg_export(struct formatter *f,
if (!_print_vg(f, vg))
fail;
f->nl(f);
outnl(f);
if (!_print_pvs(f, vg))
fail;
f->nl(f);
outnl(f);
if (!_print_lvs(f, vg))
fail;
@ -696,11 +718,10 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
}
/* Returns amount of buffer used incl. terminating NUL */
int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
uint32_t size)
int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
{
struct formatter *f;
int r;
int r = 0;
_init();
@ -710,8 +731,13 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
}
memset(f, 0, sizeof(*f));
f->data.buf.buf = buf;
f->data.buf.size = size;
f->data.buf.size = 65536; /* Initial metadata limit */
if (!(f->data.buf.start = dbg_malloc(f->data.buf.size))) {
log_error("text_export buffer allocation failed");
goto out;
}
f->indent = 0;
f->header = 0;
f->out_with_comment = &_out_with_comment_raw;
@ -719,11 +745,12 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
if (!_text_vg_export(f, vg, desc)) {
stack;
r = 0;
dbg_free(f->data.buf.start);
goto out;
}
r = f->data.buf.used + 1;
*buf = f->data.buf.start;
out:
dbg_free(f);
@ -731,3 +758,4 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
}
#undef outf
#undef outnl

View File

@ -344,9 +344,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
struct pv_list *pvl;
int r = 0;
uint32_t new_wrap = 0, old_wrap = 0;
/* FIXME Essential fix! Make dynamic (realloc? pool?) */
char buf[65536];
char *buf = NULL;
int found = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
@ -373,7 +371,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0);
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", buf, sizeof(buf)))) {
if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", &buf))) {
log_error("VG %s metadata writing failed", vg->name);
goto out;
}
@ -433,6 +431,8 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!r && !dev_close(mdac->area.dev))
stack;
if (buf)
dbg_free(buf);
return r;
}

View File

@ -59,8 +59,7 @@ int print_tags(struct list *tags, char *buffer, size_t size);
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
uint32_t size);
int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf);
struct volume_group *text_vg_import_file(struct format_instance *fid,
const char *file,
time_t *when, char **desc);

View File

@ -17,6 +17,7 @@
#define _LVM_TEXT_EXPORT_H
#define outf(args...) do {if (!out_text(args)) {stack; return 0;}} while (0)
#define outnl(f) do {if (!f->nl(f)) {stack; return 0;}} while (0)
struct formatter;
struct lv_segment;

View File

@ -537,6 +537,7 @@ static int _check_contiguous(struct lv_segment *prev_lvseg,
/*
* Choose sets of parallel areas to use, respecting any constraints.
*/
/* FIXME Also accept existing areas new space must be parallel to */
static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
struct list *pvms, struct pv_area **areas,
uint32_t areas_size, unsigned can_split,
@ -634,6 +635,7 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
_comp_area);
/* First time around, use smallest area as log_area */
/* FIXME decide which PV to use at top of function instead */
if (!_alloc_parallel_area(ah, needed, areas,
allocated,
(ah->log_count && !ah->log_area.len) ?
@ -994,7 +996,7 @@ int lv_extend(struct logical_volume *lv,
return 0;
}
if (!mirrors) {
if (mirrors < 2) {
if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
mirrored_pv, mirrored_pe, status, 0, NULL)) {
stack;