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 - Version 2.01.11 -
============================== ==============================
Remove hard-coded 64k text metadata writing restriction.
Make VG name restrictions consistent. Make VG name restrictions consistent.
Introduce lvconvert. So far only removes mirror images. Introduce lvconvert. So far only removes mirror images.
Allow mirror images to be resized. Allow mirror images to be resized.

View File

@ -30,7 +30,7 @@
struct formatter; struct formatter;
typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment, typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment,
const char *fmt, va_list ap); 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 * The first half of this file deals with
* exporting the vg, ie. writing it to a file. * exporting the vg, ie. writing it to a file.
@ -42,7 +42,7 @@ struct formatter {
union { union {
FILE *fp; /* where we're writing to */ FILE *fp; /* where we're writing to */
struct { struct {
char *buf; char *start;
uint32_t size; uint32_t size;
uint32_t used; uint32_t used;
} buf; } buf;
@ -95,22 +95,34 @@ static void _dec_indent(struct formatter *f)
/* /*
* Newline function for prettier layout. * Newline function for prettier layout.
*/ */
static void _nl_file(struct formatter *f) static int _nl_file(struct formatter *f)
{ {
fprintf(f->data.fp, "\n"); 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) char *newbuf;
return;
*f->data.buf.buf = '\n'; /* If metadata doesn't fit, double the buffer size */
f->data.buf.buf += 1; 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.used += 1;
*f->data.buf.buf = '\0';
return; *(f->data.buf.start + f->data.buf.used) = '\0';
return 1;
} }
#define COMMENT_TAB 6 #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) const char *fmt, va_list ap)
{ {
int n; int n;
char *newbuf;
n = vsnprintf(f->data.buf.buf, f->data.buf.size - f->data.buf.used, retry:
fmt, ap); 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)) /* If metadata doesn't fit, double the buffer size */
return 0; 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->data.buf.used += n;
f->nl(f); outnl(f);
return 1; return 1;
} }
@ -257,10 +279,10 @@ static int _print_header(struct formatter *f,
outf(f, "# Generated by LVM2: %s", ctime(&t)); outf(f, "# Generated by LVM2: %s", ctime(&t));
outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\""); outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\"");
outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE); outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE);
f->nl(f); outnl(f);
outf(f, "description = \"%s\"", desc); outf(f, "description = \"%s\"", desc);
f->nl(f); outnl(f);
outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename, outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
_utsname.sysname, _utsname.nodename, _utsname.release, _utsname.sysname, _utsname.nodename, _utsname.release,
_utsname.version, _utsname.machine); _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 */ /* Default policy is NORMAL; INHERIT is meaningless */
if (vg->alloc != ALLOC_NORMAL && vg->alloc != ALLOC_INHERIT) { if (vg->alloc != ALLOC_NORMAL && vg->alloc != ALLOC_INHERIT) {
f->nl(f); outnl(f);
outf(f, "allocation_policy = \"%s\"", outf(f, "allocation_policy = \"%s\"",
get_alloc_string(vg->alloc)); get_alloc_string(vg->alloc));
} }
@ -346,7 +368,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
return 0; return 0;
} }
f->nl(f); outnl(f);
outf(f, "%s {", name); outf(f, "%s {", name);
_inc_indent(f); _inc_indent(f);
@ -360,7 +382,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
stack; stack;
return 0; return 0;
} }
f->nl(f); outnl(f);
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) { if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) {
stack; stack;
@ -407,7 +429,7 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
return 0; return 0;
} }
f->nl(f); outnl(f);
outf(f, "type = \"%s\"", seg->segtype->name); outf(f, "type = \"%s\"", seg->segtype->name);
if (!list_empty(&seg->tags)) { if (!list_empty(&seg->tags)) {
@ -436,7 +458,7 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
const char *name; const char *name;
unsigned int s; unsigned int s;
f->nl(f); outnl(f);
outf(f, "%ss = [", type); outf(f, "%ss = [", type);
_inc_indent(f); _inc_indent(f);
@ -472,7 +494,7 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
char buffer[4096]; char buffer[4096];
int seg_count; int seg_count;
f->nl(f); outnl(f);
outf(f, "%s {", lv->name); outf(f, "%s {", lv->name);
_inc_indent(f); _inc_indent(f);
@ -509,7 +531,7 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
if (lv->minor >= 0) if (lv->minor >= 0)
outf(f, "minor = %d", lv->minor); outf(f, "minor = %d", lv->minor);
outf(f, "segment_count = %u", list_size(&lv->segments)); outf(f, "segment_count = %u", list_size(&lv->segments));
f->nl(f); outnl(f);
seg_count = 1; seg_count = 1;
list_iterate_items(seg, &lv->segments) { list_iterate_items(seg, &lv->segments) {
@ -641,11 +663,11 @@ static int _text_vg_export(struct formatter *f,
if (!_print_vg(f, vg)) if (!_print_vg(f, vg))
fail; fail;
f->nl(f); outnl(f);
if (!_print_pvs(f, vg)) if (!_print_pvs(f, vg))
fail; fail;
f->nl(f); outnl(f);
if (!_print_lvs(f, vg)) if (!_print_lvs(f, vg))
fail; 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 */ /* Returns amount of buffer used incl. terminating NUL */
int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf, int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
uint32_t size)
{ {
struct formatter *f; struct formatter *f;
int r; int r = 0;
_init(); _init();
@ -710,8 +731,13 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
} }
memset(f, 0, sizeof(*f)); 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->indent = 0;
f->header = 0; f->header = 0;
f->out_with_comment = &_out_with_comment_raw; 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)) { if (!_text_vg_export(f, vg, desc)) {
stack; stack;
r = 0; dbg_free(f->data.buf.start);
goto out; goto out;
} }
r = f->data.buf.used + 1; r = f->data.buf.used + 1;
*buf = f->data.buf.start;
out: out:
dbg_free(f); dbg_free(f);
@ -731,3 +758,4 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
} }
#undef outf #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; struct pv_list *pvl;
int r = 0; int r = 0;
uint32_t new_wrap = 0, old_wrap = 0; uint32_t new_wrap = 0, old_wrap = 0;
char *buf = NULL;
/* FIXME Essential fix! Make dynamic (realloc? pool?) */
char buf[65536];
int found = 0; int found = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */ /* 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); rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0);
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah); 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); log_error("VG %s metadata writing failed", vg->name);
goto out; 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)) if (!r && !dev_close(mdac->area.dev))
stack; stack;
if (buf)
dbg_free(buf);
return r; 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 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_file(struct volume_group *vg, const char *desc, FILE *fp);
int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf, int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf);
uint32_t size);
struct volume_group *text_vg_import_file(struct format_instance *fid, struct volume_group *text_vg_import_file(struct format_instance *fid,
const char *file, const char *file,
time_t *when, char **desc); time_t *when, char **desc);

View File

@ -17,6 +17,7 @@
#define _LVM_TEXT_EXPORT_H #define _LVM_TEXT_EXPORT_H
#define outf(args...) do {if (!out_text(args)) {stack; return 0;}} while (0) #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 formatter;
struct lv_segment; 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. * 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, static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
struct list *pvms, struct pv_area **areas, struct list *pvms, struct pv_area **areas,
uint32_t areas_size, unsigned can_split, 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); _comp_area);
/* First time around, use smallest area as log_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, if (!_alloc_parallel_area(ah, needed, areas,
allocated, allocated,
(ah->log_count && !ah->log_area.len) ? (ah->log_count && !ah->log_area.len) ?
@ -994,7 +996,7 @@ int lv_extend(struct logical_volume *lv,
return 0; return 0;
} }
if (!mirrors) { if (mirrors < 2) {
if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size, if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
mirrored_pv, mirrored_pe, status, 0, NULL)) { mirrored_pv, mirrored_pe, status, 0, NULL)) {
stack; stack;