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:
parent
8b80d2a57c
commit
5748cb17f8
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user