[lvm-devel] [PATCH] Use dynamic allocation for tag buffer when writing metadata out
Peter Rajnoha
prajnoha at redhat.com
Mon Sep 13 14:30:48 UTC 2010
Statically allocated buffer of 4096 is not enough is some situations for tag
buffer (see also rhbz #633033). So let's use dynamic allocation instead to make
enough room for it.
Peter
---
lib/format_text/export.c | 26 ++++++++++++++++----------
lib/format_text/import-export.h | 2 +-
lib/format_text/tags.c | 35 ++++++++++++++++++++++++++---------
3 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index bb558fc..95b2f02 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 (!print_tags(&vg->tags, &tag_buffer))
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 (!print_tags(&pv->tags, &tag_buffer))
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 (!print_tags(&seg->tags, &tag_buffer))
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 (!print_tags(&lv->tags, &tag_buffer))
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 019c739..2a64734 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);
+int print_tags(struct dm_list *tags, char **buffer);
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 eeb0af7..9c5bc3f 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)
+int print_tags(struct dm_list *tags, char **buffer)
{
struct str_list *sl;
int first = 1;
+ size_t size = 0;
+ char *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 0;
+ }
+
+ if (!emit_to_buffer(&buf, &size, "["))
+ goto error;
dm_list_iterate_items(sl, tags) {
if (!first) {
- if (!emit_to_buffer(&buffer, &size, ", "))
- return_0;
+ if (!emit_to_buffer(&buf, &size, ", "))
+ goto error;
} else
first = 0;
- if (!emit_to_buffer(&buffer, &size, "\"%s\"", sl->str))
- return_0;
+ if (!emit_to_buffer(&buf, &size, "\"%s\"", sl->str))
+ goto error;
}
- if (!emit_to_buffer(&buffer, &size, "]"))
- return_0;
+ if (!emit_to_buffer(&buf, &size, "]"))
+ goto error;
return 1;
+
+error:
+ dm_free(*buffer);
+ return_0;
}
int read_tags(struct dm_pool *mem, struct dm_list *tags, struct config_value *cv)
More information about the lvm-devel
mailing list