From f900ddb544fc88c97f6342c0ffb39ec9a1546264 Mon Sep 17 00:00:00 2001 From: Peter Rajnoha Date: Mon, 20 Sep 2010 14:23:20 +0000 Subject: [PATCH] Use dynamic allocation for metadata's tag buffer (removes 4096 char. limit). --- WHATS_NEW | 1 + lib/format_text/export.c | 26 ++++++++++++++--------- lib/format_text/import-export.h | 2 +- lib/format_text/tags.c | 37 ++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 5e9e8ae92..895621ca2 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.74 - ================================== + Use dynamic allocation for metadata's tag buffer (removes 4096 char. limit). Add random suffix to archive file names to prevent races when being created. Reinitialize archive and backup handling on toolcontext refresh. Fix opprobriously slow I/O to cluster mirrors created with --nosync. diff --git a/lib/format_text/export.c b/lib/format_text/export.c index bb558fce2..d16a7fcf6 100644 --- a/lib/format_text/export.c +++ b/lib/format_text/export.c @@ -366,6 +366,7 @@ static int _print_flag_config(struct formatter *f, uint64_t status, int type) static int _print_vg(struct formatter *f, struct volume_group *vg) { char buffer[4096]; + char *tag_buffer = NULL; if (!id_write_format(&vg->id, buffer, sizeof(buffer))) return_0; @@ -378,9 +379,10 @@ static int _print_vg(struct formatter *f, struct volume_group *vg) return_0; if (!dm_list_empty(&vg->tags)) { - if (!print_tags(&vg->tags, buffer, sizeof(buffer))) + if (!(tag_buffer = alloc_printed_tags(&vg->tags))) return_0; - outf(f, "tags = %s", buffer); + outf(f, "tags = %s", tag_buffer); + dm_free(tag_buffer); } if (vg->system_id && *vg->system_id) @@ -426,7 +428,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) struct pv_list *pvl; struct physical_volume *pv; char buffer[4096]; - char *buf; + char *buf, *tag_buffer = NULL; const char *name; outf(f, "physical_volumes {"); @@ -461,9 +463,10 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) return_0; if (!dm_list_empty(&pv->tags)) { - if (!print_tags(&pv->tags, buffer, sizeof(buffer))) + if (!(tag_buffer = alloc_printed_tags(&pv->tags))) return_0; - outf(f, "tags = %s", buffer); + outf(f, "tags = %s", tag_buffer); + dm_free(tag_buffer); } outsize(f, pv->size, "dev_size = %" PRIu64, pv->size); @@ -484,7 +487,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) static int _print_segment(struct formatter *f, struct volume_group *vg, int count, struct lv_segment *seg) { - char buffer[4096]; + char *tag_buffer = NULL; outf(f, "segment%u {", count); _inc_indent(f); @@ -497,9 +500,10 @@ static int _print_segment(struct formatter *f, struct volume_group *vg, outf(f, "type = \"%s\"", seg->segtype->name); if (!dm_list_empty(&seg->tags)) { - if (!print_tags(&seg->tags, buffer, sizeof(buffer))) + if (!(tag_buffer = alloc_printed_tags(&seg->tags))) return_0; - outf(f, "tags = %s", buffer); + outf(f, "tags = %s", tag_buffer); + dm_free(tag_buffer); } if (seg->segtype->ops->text_export && @@ -553,6 +557,7 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv) { struct lv_segment *seg; char buffer[4096]; + char *tag_buffer = NULL; int seg_count; outnl(f); @@ -569,9 +574,10 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv) return_0; if (!dm_list_empty(&lv->tags)) { - if (!print_tags(&lv->tags, buffer, sizeof(buffer))) + if (!(tag_buffer = alloc_printed_tags(&lv->tags))) return_0; - outf(f, "tags = %s", buffer); + outf(f, "tags = %s", tag_buffer); + dm_free(tag_buffer); } if (lv->alloc != ALLOC_INHERIT) diff --git a/lib/format_text/import-export.h b/lib/format_text/import-export.h index 019c739e7..e59a3c2ad 100644 --- a/lib/format_text/import-export.h +++ b/lib/format_text/import-export.h @@ -61,7 +61,7 @@ struct text_vg_version_ops *text_vg_vsn1_init(void); int print_flags(uint64_t status, int type, char *buffer, size_t size); int read_flags(uint64_t *status, int type, struct config_value *cv); -int print_tags(struct dm_list *tags, char *buffer, size_t size); +char *alloc_printed_tags(struct dm_list *tags); int read_tags(struct dm_pool *mem, struct dm_list *tags, struct config_value *cv); int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp); diff --git a/lib/format_text/tags.c b/lib/format_text/tags.c index eeb0af7b2..65db03e4e 100644 --- a/lib/format_text/tags.c +++ b/lib/format_text/tags.c @@ -19,29 +19,46 @@ #include "str_list.h" #include "lvm-string.h" -int print_tags(struct dm_list *tags, char *buffer, size_t size) +char *alloc_printed_tags(struct dm_list *tags) { struct str_list *sl; int first = 1; + size_t size = 0; + char *buffer, *buf; - if (!emit_to_buffer(&buffer, &size, "[")) - return_0; + dm_list_iterate_items(sl, tags) + /* '"' + tag + '"' + ',' + ' ' */ + size += strlen(sl->str) + 4; + /* '[' + ']' + '\0' */ + size += 3; + + if (!(buffer = buf = dm_malloc(size))) { + log_error("Could not allocate memory for tag list buffer."); + return NULL; + } + + if (!emit_to_buffer(&buf, &size, "[")) + goto bad; dm_list_iterate_items(sl, tags) { if (!first) { - if (!emit_to_buffer(&buffer, &size, ", ")) - return_0; + if (!emit_to_buffer(&buf, &size, ", ")) + goto bad; } else first = 0; - if (!emit_to_buffer(&buffer, &size, "\"%s\"", sl->str)) - return_0; + if (!emit_to_buffer(&buf, &size, "\"%s\"", sl->str)) + goto bad; } - if (!emit_to_buffer(&buffer, &size, "]")) - return_0; + if (!emit_to_buffer(&buf, &size, "]")) + goto bad; - return 1; + return buffer; + +bad: + dm_free(buffer); + return_NULL; } int read_tags(struct dm_pool *mem, struct dm_list *tags, struct config_value *cv) -- 2.43.5