master - lvmetad: Implement a "dump" request to capture lvmetad state.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a63b46bf36b22b...
Commit: a63b46bf36b22b83ff05f2d3529bc22a38ff56d3
Parent: b165e9f3f8fe757e2dc330f6952856908fb131d8
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 20:31:29 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 20:31:29 2012 +0200
lvmetad: Implement a "dump" request to capture lvmetad state.
---
daemons/lvmetad/lvmetad-core.c | 81 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 47b07aa..99ae99f 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -942,6 +942,82 @@ static response vg_remove(lvmetad_state *s, request r)
return daemon_reply_simple("OK", NULL);
}
+static void _dump_cft(struct buffer *buf, struct dm_hash_table *ht, const char *key_addr)
+{
+ struct dm_hash_node *n = dm_hash_get_first(ht);
+ while (n) {
+ struct dm_config_tree *cft = dm_hash_get_data(ht, n);
+ const char *key_backup = cft->root->key;
+ cft->root->key = dm_config_find_str(cft->root, key_addr, "unknown");
+ dm_config_write_node(cft->root, buffer_line, buf);
+ cft->root->key = key_backup;
+ n = dm_hash_get_next(ht, n);
+ }
+}
+
+static void _dump_pairs(struct buffer *buf, struct dm_hash_table *ht, const char *name, int int_key)
+{
+ char *append;
+ struct dm_hash_node *n = dm_hash_get_first(ht);
+
+ buffer_append(buf, name);
+ buffer_append(buf, " {\n");
+
+ while (n) {
+ const char *key = dm_hash_get_key(ht, n),
+ *val = dm_hash_get_data(ht, n);
+ buffer_append(buf, " ");
+ if (int_key)
+ dm_asprintf(&append, "%d = \"%s\"", *(int*)key, val);
+ else
+ dm_asprintf(&append, "%s = \"%s\"", key, val);
+ if (append)
+ buffer_append(buf, append);
+ buffer_append(buf, "\n");
+ dm_free(append);
+ n = dm_hash_get_next(ht, n);
+ }
+ buffer_append(buf, "}\n");
+}
+
+static response dump(lvmetad_state *s)
+{
+ response res;
+ struct buffer *b = &res.buffer;
+
+ buffer_init(b);
+
+ /* Lock everything so that we get a consistent dump. */
+
+ lock_vgid_to_metadata(s);
+ lock_pvid_to_pvmeta(s);
+ lock_pvid_to_vgid(s);
+
+ buffer_append(b, "# VG METADATA\n\n");
+ _dump_cft(b, s->vgid_to_metadata, "metadata/id");
+
+ buffer_append(b, "\n# PV METADATA\n\n");
+ _dump_cft(b, s->pvid_to_pvmeta, "pvmeta/id");
+
+ buffer_append(b, "\n# VGID to VGNAME mapping\n\n");
+ _dump_pairs(b, s->vgid_to_vgname, "vgid_to_vgname", 0);
+
+ buffer_append(b, "\n# VGNAME to VGID mapping\n\n");
+ _dump_pairs(b, s->vgname_to_vgid, "vgname_to_vgid", 0);
+
+ buffer_append(b, "\n# PVID to VGID mapping\n\n");
+ _dump_pairs(b, s->pvid_to_vgid, "pvid_to_vgid", 0);
+
+ buffer_append(b, "\n# DEVICE to PVID mapping\n\n");
+ _dump_pairs(b, s->device_to_pvid, "device_to_pvid", 1);
+
+ unlock_pvid_to_vgid(s);
+ unlock_pvid_to_pvmeta(s);
+ unlock_vgid_to_metadata(s);
+
+ return res;
+}
+
static response handler(daemon_state s, client_handle h, request r)
{
lvmetad_state *state = s.private;
@@ -956,7 +1032,7 @@ static response handler(daemon_state s, client_handle h, request r)
return daemon_reply_simple("OK", NULL);
}
- if (strcmp(token, state->token)) {
+ if (strcmp(token, state->token) && strcmp(rq, "dump")) {
pthread_mutex_unlock(&state->token_lock);
return daemon_reply_simple("token_mismatch",
"expected = %s", state->token,
@@ -997,6 +1073,9 @@ static response handler(daemon_state s, client_handle h, request r)
if (!strcmp(rq, "vg_list"))
return vg_list(state, r);
+ if (!strcmp(rq, "dump"))
+ return dump(state);
+
return reply_fail("request not implemented");
}
11 years, 7 months
master - test: Skip lvconvert-raid on kernels < 3.2 since they BUG out.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b165e9f3f8fe75...
Commit: b165e9f3f8fe757e2dc330f6952856908fb131d8
Parent: b07df8850ad1952edff67f263f1f161b1d4cf439
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 15:38:19 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 18:13:37 2012 +0200
test: Skip lvconvert-raid on kernels < 3.2 since they BUG out.
---
test/shell/lvconvert-raid.sh | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvconvert-raid.sh b/test/shell/lvconvert-raid.sh
index 7f4dd4b..4fa766d 100644
--- a/test/shell/lvconvert-raid.sh
+++ b/test/shell/lvconvert-raid.sh
@@ -23,6 +23,7 @@ get_image_pvs() {
# MAIN
########################################################
aux target_at_least dm-raid 1 1 0 || skip
+aux kernel_at_least 3 2 0 || skip
# 9 PVs needed for RAID10 testing (3-stripes/2-mirror - replacing 3 devs)
aux prepare_pvs 9 80
11 years, 7 months
master - libdaemon: Make buffer handling asymptotically more efficient.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b07df8850ad195...
Commit: b07df8850ad1952edff67f263f1f161b1d4cf439
Parent: 0a46160d94524cca9d07e2d183d62ff6df1ec48e
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 14:17:17 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 18:09:41 2012 +0200
libdaemon: Make buffer handling asymptotically more efficient.
---
daemons/lvmetad/lvmetad-core.c | 17 +++++--
libdaemon/client/config-util.c | 91 ++++++++++++++++++++++++--------------
libdaemon/client/config-util.h | 15 +++++-
libdaemon/client/daemon-client.c | 36 ++++++---------
libdaemon/client/daemon-client.h | 5 +-
libdaemon/client/daemon-io.c | 38 +++++++---------
libdaemon/client/daemon-io.h | 5 +-
libdaemon/server/daemon-server.c | 35 +++++++-------
libdaemon/server/daemon-server.h | 4 +-
9 files changed, 140 insertions(+), 106 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 8a1378a..47b07aa 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -287,7 +287,9 @@ static response pv_list(lvmetad_state *s, request r)
struct dm_config_node *cn = NULL, *cn_pvs;
struct dm_hash_node *n;
const char *id;
- response res = { .buffer = NULL };
+ response res;
+
+ buffer_init( &res.buffer );
if (!(res.cft = dm_config_create()))
return res; /* FIXME error reporting */
@@ -313,9 +315,11 @@ static response pv_lookup(lvmetad_state *s, request r)
{
const char *pvid = daemon_request_str(r, "uuid", NULL);
int64_t devt = daemon_request_int(r, "device", 0);
- response res = { .buffer = NULL };
+ response res;
struct dm_config_node *pv;
+ buffer_init( &res.buffer );
+
if (!pvid && !devt)
return reply_fail("need PVID or device");
@@ -355,7 +359,10 @@ static response vg_list(lvmetad_state *s, request r)
struct dm_hash_node *n;
const char *id;
const char *name;
- response res = { .buffer = NULL };
+ response res;
+
+ buffer_init( &res.buffer );
+
if (!(res.cft = dm_config_create()))
goto bad; /* FIXME: better error reporting */
@@ -422,11 +429,13 @@ static response vg_lookup(lvmetad_state *s, request r)
{
struct dm_config_tree *cft;
struct dm_config_node *metadata, *n;
- response res = { .buffer = NULL };
+ response res;
const char *uuid = daemon_request_str(r, "uuid", NULL);
const char *name = daemon_request_str(r, "name", NULL);
+ buffer_init( &res.buffer );
+
DEBUG(s, "vg_lookup: uuid = %s, name = %s", uuid, name);
if (!uuid || !name) {
diff --git a/libdaemon/client/config-util.c b/libdaemon/client/config-util.c
index 2573139..30fc4f8 100644
--- a/libdaemon/client/config-util.c
+++ b/libdaemon/client/config-util.c
@@ -21,17 +21,13 @@
#include "config-util.h"
#include "libdevmapper.h"
-char *format_buffer_v(const char *head, va_list ap)
+int buffer_append_vf(struct buffer *buf, va_list ap)
{
- char *buffer, *old;
+ char *append, *old;
char *next;
int keylen;
- dm_asprintf(&buffer, "%s", head);
- if (!buffer) goto fail;
-
while ((next = va_arg(ap, char *))) {
- old = buffer;
if (!strchr(next, '=')) {
log_error(INTERNAL_ERROR "Bad format string at '%s'", next);
goto fail;
@@ -39,36 +35,34 @@ char *format_buffer_v(const char *head, va_list ap)
keylen = strchr(next, '=') - next;
if (strstr(next, "%d") || strstr(next, "%" PRId64)) {
int64_t value = va_arg(ap, int64_t);
- dm_asprintf(&buffer, "%s%.*s= %" PRId64 "\n", buffer, keylen, next, value);
- dm_free(old);
+ dm_asprintf(&append, "%.*s= %" PRId64 "\n", keylen, next, value);
} else if (strstr(next, "%s")) {
char *value = va_arg(ap, char *);
- dm_asprintf(&buffer, "%s%.*s= \"%s\"\n", buffer, keylen, next, value);
- dm_free(old);
+ dm_asprintf(&append, "%.*s= \"%s\"\n", keylen, next, value);
} else if (strstr(next, "%b")) {
char *block = va_arg(ap, char *);
if (!block)
continue;
- dm_asprintf(&buffer, "%s%.*s%s", buffer, keylen, next, block);
- dm_free(old);
+ dm_asprintf(&append, "%.*s%s", keylen, next, block);
} else {
- dm_asprintf(&buffer, "%s%s", buffer, next);
- dm_free(old);
+ dm_asprintf(&append, "%s", next);
}
- if (!buffer) goto fail;
+ if (!append) goto fail;
+ buffer_append(buf, append);
+ dm_free(append);
}
- return buffer;
+ return 1;
fail:
- dm_free(buffer);
- return NULL;
+ dm_free(append);
+ return 0;
}
-char *format_buffer(const char *head, ...)
+int buffer_append_f(struct buffer *buf, ...)
{
va_list ap;
- va_start(ap, head);
- char *res = format_buffer_v(head, ap);
+ va_start(ap, buf);
+ int res = buffer_append_vf(buf, ap);
va_end(ap);
return res;
}
@@ -263,26 +257,57 @@ struct dm_config_node *config_make_nodes(struct dm_config_tree *cft,
return res;
}
-int buffer_rewrite(char **buf, const char *format, const char *string)
+int buffer_realloc(struct buffer *buf, int needed)
{
- char *old = *buf;
- int r = dm_asprintf(buf, format, *buf, string);
+ char *new;
+ int alloc = buf->allocated;
+ if (alloc < needed)
+ alloc = needed;
+
+ buf->allocated += alloc;
+ new = realloc(buf->mem, buf->allocated);
+ if (new)
+ buf->mem = new;
+ else { /* utter failure */
+ dm_free(buf->mem);
+ buf->mem = 0;
+ buf->allocated = buf->used = 0;
+ return 0;
+ }
+ return 1;
+}
+
+int buffer_append(struct buffer *buf, const char *string)
+{
+ int len = strlen(string);
+ char *new;
- dm_free(old);
+ if (buf->allocated - buf->used <= len)
+ buffer_realloc(buf, len + 1);
- return (r < 0) ? 0 : 1;
+ strcpy(buf->mem + buf->used, string);
+ buf->used += len;
+ return 1;
}
int buffer_line(const char *line, void *baton)
{
- char **buffer = baton;
-
- if (*buffer) {
- if (!buffer_rewrite(buffer, "%s\n%s", line))
- return 0;
- } else if (dm_asprintf(buffer, "%s\n", line) < 0)
+ struct buffer *buf = baton;
+ if (!buffer_append(buf, line))
+ return 0;
+ if (!buffer_append(buf, "\n"))
return 0;
-
return 1;
}
+void buffer_destroy(struct buffer *buf)
+{
+ dm_free(buf->mem);
+ buffer_init(buf);
+}
+
+void buffer_init(struct buffer *buf)
+{
+ buf->allocated = buf->used = 0;
+ buf->mem = 0;
+}
diff --git a/libdaemon/client/config-util.h b/libdaemon/client/config-util.h
index ae5e556..f03bcab 100644
--- a/libdaemon/client/config-util.h
+++ b/libdaemon/client/config-util.h
@@ -20,11 +20,20 @@
#include <stdarg.h>
-char *format_buffer_v(const char *head, va_list ap);
-char *format_buffer(const char *head, ...);
+struct buffer {
+ int allocated;
+ int used;
+ char *mem;
+};
+
+int buffer_append_vf(struct buffer *buf, va_list ap);
+int buffer_append_f(struct buffer *buf, ...);
+int buffer_append(struct buffer *buf, const char *string);
+void buffer_init(struct buffer *buf);
+void buffer_destroy(struct buffer *buf);
+int buffer_realloc(struct buffer *buf, int required);
int buffer_line(const char *line, void *baton);
-int buffer_rewrite(char **buf, const char *format, const char *string);
int set_flag(struct dm_config_tree *cft, struct dm_config_node *parent,
const char *field, const char *flag, int want);
diff --git a/libdaemon/client/daemon-client.c b/libdaemon/client/daemon-client.c
index c87856c..107882b 100644
--- a/libdaemon/client/daemon-client.c
+++ b/libdaemon/client/daemon-client.c
@@ -73,24 +73,24 @@ daemon_reply daemon_send(daemon_handle h, daemon_request rq)
{
daemon_reply reply = { .cft = NULL, .error = 0 };
assert(h.socket_fd >= 0);
- char *buffer = rq.buffer;
+ struct buffer buffer = rq.buffer;
- if (!buffer)
+ if (!buffer.mem)
dm_config_write_node(rq.cft->root, buffer_line, &buffer);
- assert(buffer);
- if (!write_buffer(h.socket_fd, buffer, strlen(buffer)))
+ assert(buffer.mem);
+ if (!buffer_write(h.socket_fd, &buffer))
reply.error = errno;
- if (read_buffer(h.socket_fd, &reply.buffer)) {
- reply.cft = dm_config_from_string(reply.buffer);
+ if (buffer_read(h.socket_fd, &reply.buffer)) {
+ reply.cft = dm_config_from_string(reply.buffer.mem);
if (!reply.cft)
reply.error = EPROTO;
} else
reply.error = errno;
- if (buffer != rq.buffer)
- dm_free(buffer);
+ if (buffer.mem != rq.buffer.mem)
+ buffer_destroy(&buffer);
return reply;
}
@@ -98,28 +98,22 @@ daemon_reply daemon_send(daemon_handle h, daemon_request rq)
void daemon_reply_destroy(daemon_reply r) {
if (r.cft)
dm_config_destroy(r.cft);
- dm_free(r.buffer);
+ buffer_destroy(&r.buffer);
}
daemon_reply daemon_send_simple_v(daemon_handle h, const char *id, va_list ap)
{
- static const daemon_reply err = { .error = ENOMEM, .buffer = NULL, .cft = NULL };
+ static const daemon_reply err = { .error = ENOMEM, .buffer = { 0, 0, NULL }, .cft = NULL };
daemon_request rq = { .cft = NULL };
daemon_reply repl;
- char *rq_line;
- rq_line = format_buffer("", "request = %s", id, NULL);
- if (!rq_line)
+ if (!buffer_append_f(&rq.buffer, "request = %s", id, NULL))
return err;
-
- rq.buffer = format_buffer_v(rq_line, ap);
- dm_free(rq_line);
-
- if (!rq.buffer)
+ if (!buffer_append_vf(&rq.buffer, ap))
return err;
repl = daemon_send(h, rq);
- dm_free(rq.buffer);
+ buffer_destroy(&rq.buffer);
return repl;
}
@@ -142,7 +136,7 @@ daemon_request daemon_request_make(const char *id)
{
daemon_request r;
r.cft = NULL;
- r.buffer = NULL;
+ buffer_init(&r.buffer);
if (!(r.cft = dm_config_create()))
goto bad;
@@ -181,6 +175,6 @@ int daemon_request_extend(daemon_request r, ...)
void daemon_request_destroy(daemon_request r) {
if (r.cft)
dm_config_destroy(r.cft);
- dm_free(r.buffer);
+ buffer_destroy(&r.buffer);
}
diff --git a/libdaemon/client/daemon-client.h b/libdaemon/client/daemon-client.h
index 2863d03..6ba65e6 100644
--- a/libdaemon/client/daemon-client.h
+++ b/libdaemon/client/daemon-client.h
@@ -16,6 +16,7 @@
#define _LVM_DAEMON_COMMON_CLIENT_H
#include "libdevmapper.h"
+#include "config-util.h"
typedef struct {
int socket_fd; /* the fd we use to talk to the daemon */
@@ -38,7 +39,7 @@ typedef struct {
} daemon_info;
typedef struct {
- char *buffer;
+ struct buffer buffer;
/*
* The request looks like this:
* request = "id"
@@ -55,7 +56,7 @@ typedef struct {
typedef struct {
int error; /* 0 for success */
- char *buffer; /* textual reply */
+ struct buffer buffer;
struct dm_config_tree *cft; /* parsed reply, if available */
} daemon_reply;
diff --git a/libdaemon/client/daemon-io.c b/libdaemon/client/daemon-io.c
index 4af9343..50ef9b2 100644
--- a/libdaemon/client/daemon-io.c
+++ b/libdaemon/client/daemon-io.c
@@ -29,26 +29,22 @@
*
* See also write_buffer about blocking (read_buffer has identical behaviour).
*/
-int read_buffer(int fd, char **buffer) {
- int bytes = 0;
- int buffersize = 32;
- char *new;
- *buffer = dm_malloc(buffersize + 1);
+int buffer_read(int fd, struct buffer *buffer) {
+ if (!buffer_realloc(buffer, 32)) /* ensure we have some space */
+ goto fail;
while (1) {
- int result = read(fd, (*buffer) + bytes, buffersize - bytes);
+ int result = read(fd, buffer->mem + buffer->used, buffer->allocated - buffer->used);
if (result > 0) {
- bytes += result;
- if (!strncmp((*buffer) + bytes - 4, "\n##\n", 4)) {
- *(*buffer + bytes - 4) = 0;
+ buffer->used += result;
+ if (!strncmp((buffer->mem) + buffer->used - 4, "\n##\n", 4)) {
+ *(buffer->mem + buffer->used - 4) = 0;
+ buffer->used -= 4;
break; /* success, we have the full message now */
}
- if (bytes == buffersize) {
- buffersize += 1024;
- if (!(new = realloc(*buffer, buffersize + 1)))
+ if (buffer->used - buffer->allocated < 32)
+ if (!buffer_realloc(buffer, 1024))
goto fail;
- *buffer = new;
- }
continue;
}
if (result == 0) {
@@ -61,8 +57,6 @@ int read_buffer(int fd, char **buffer) {
}
return 1;
fail:
- dm_free(*buffer);
- *buffer = NULL;
return 0;
}
@@ -72,18 +66,19 @@ fail:
*
* TODO use select on EWOULDBLOCK/EAGAIN/EINTR to avoid useless spinning
*/
-int write_buffer(int fd, const char *buffer, int length) {
- static const char terminate[] = "\n##\n";
+int buffer_write(int fd, struct buffer *buffer) {
+ struct buffer terminate = { .mem = (char *) "\n##\n", .used = 4 };
int done = 0;
int written = 0;
+ struct buffer *use = buffer;
write:
while (1) {
- int result = write(fd, buffer + written, length - written);
+ int result = write(fd, use->mem + written, use->used - written);
if (result > 0)
written += result;
if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR)
return 0; /* too bad */
- if (written == length) {
+ if (written == use->used) {
if (done)
return 1;
else
@@ -91,8 +86,7 @@ write:
}
}
- buffer = terminate;
- length = 4;
+ use = &terminate;
written = 0;
done = 1;
goto write;
diff --git a/libdaemon/client/daemon-io.h b/libdaemon/client/daemon-io.h
index e6e5f06..1f55af7 100644
--- a/libdaemon/client/daemon-io.h
+++ b/libdaemon/client/daemon-io.h
@@ -16,6 +16,7 @@
#define _LVM_DAEMON_IO_H
#include "configure.h"
+#include "config-util.h"
#include "libdevmapper.h"
#define _REENTRANT
@@ -24,7 +25,7 @@
/* TODO function names */
-int read_buffer(int fd, char **buffer);
-int write_buffer(int fd, const char *buffer, int length);
+int buffer_read(int fd, struct buffer *buffer);
+int buffer_write(int fd, struct buffer *buffer);
#endif /* _LVM_DAEMON_SHARED_H */
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 9dd911f..051e7c2 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -330,22 +330,20 @@ response daemon_reply_simple(const char *id, ...)
{
va_list ap;
response res = { .cft = NULL };
- char *res_line = NULL;
va_start(ap, id);
- if (!(res_line = format_buffer("", "response = %s", id, NULL))) {
+ buffer_init(&res.buffer);
+ if (!buffer_append_f(&res.buffer, "response = %s", id, NULL)) {
res.error = ENOMEM;
goto end;
}
-
- if (!(res.buffer = format_buffer_v(res_line, ap))) {
+ if (!buffer_append_vf(&res.buffer, ap)) {
res.error = ENOMEM;
goto end;
}
end:
- dm_free(res_line);
va_end(ap);
return res;
}
@@ -364,24 +362,27 @@ static response builtin_handler(daemon_state s, client_handle h, request r)
"version = %" PRId64, (int64_t) s.protocol_version, NULL);
}
- response res = { .buffer = NULL, .error = EPROTO };
+ response res = { .error = EPROTO };
+ buffer_init(&res.buffer);
return res;
}
static void *client_thread(void *baton)
{
struct thread_baton *b = baton;
- request req = { .buffer = NULL };
+ request req;
response res;
+ buffer_init(&req.buffer);
+
while (1) {
- if (!read_buffer(b->client.socket_fd, &req.buffer))
+ if (!buffer_read(b->client.socket_fd, &req.buffer))
goto fail;
- req.cft = dm_config_from_string(req.buffer);
+ req.cft = dm_config_from_string(req.buffer.mem);
if (!req.cft)
- fprintf(stderr, "error parsing request:\n %s\n", req.buffer);
+ fprintf(stderr, "error parsing request:\n %s\n", req.buffer.mem);
else
daemon_log_cft(b->s.log, DAEMON_LOG_WIRE, "<- ", req.cft->root);
@@ -390,27 +391,27 @@ static void *client_thread(void *baton)
if (res.error == EPROTO) /* Not a builtin, delegate to the custom handler. */
res = b->s.handler(b->s, b->client, req);
- if (!res.buffer) {
+ if (!res.buffer.mem) {
dm_config_write_node(res.cft->root, buffer_line, &res.buffer);
- if (!buffer_rewrite(&res.buffer, "%s\n\n", NULL))
+ if (!buffer_append(&res.buffer, "\n\n"))
goto fail;
dm_config_destroy(res.cft);
}
if (req.cft)
dm_config_destroy(req.cft);
- dm_free(req.buffer);
+ buffer_destroy(&req.buffer);
- daemon_log_multi(b->s.log, DAEMON_LOG_WIRE, "-> ", res.buffer);
- write_buffer(b->client.socket_fd, res.buffer, strlen(res.buffer));
+ daemon_log_multi(b->s.log, DAEMON_LOG_WIRE, "-> ", res.buffer.mem);
+ buffer_write(b->client.socket_fd, &res.buffer);
- free(res.buffer);
+ buffer_destroy(&res.buffer);
}
fail:
/* TODO what should we really do here? */
if (close(b->client.socket_fd))
perror("close");
- dm_free(req.buffer);
+ buffer_destroy(&req.buffer);
dm_free(baton);
return NULL;
}
diff --git a/libdaemon/server/daemon-server.h b/libdaemon/server/daemon-server.h
index df7ed8e..2109602 100644
--- a/libdaemon/server/daemon-server.h
+++ b/libdaemon/server/daemon-server.h
@@ -26,13 +26,13 @@ typedef struct {
typedef struct {
struct dm_config_tree *cft;
- char *buffer;
+ struct buffer buffer;
} request;
typedef struct {
int error;
struct dm_config_tree *cft;
- char *buffer;
+ struct buffer buffer;
} response;
struct daemon_state;
11 years, 7 months
master - lvm2api: add defined lvm_percent_to_float
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0a46160d94524c...
Commit: 0a46160d94524cca9d07e2d183d62ff6df1ec48e
Parent: 316ce655a37136375dc9ea1204f218838d77ce41
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Oct 11 17:25:14 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Oct 11 17:29:56 2012 +0200
lvm2api: add defined lvm_percent_to_float
Implement function which was somehow missing from it's original
placement in the header file lvm2api.h.
---
WHATS_NEW | 1 +
liblvm/lvm_base.c | 5 +++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 5a3364a..d614270 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.98 -
=================================
+ Add implementation of lvm2api function lvm_percent_to_float.
Allow non power of 2 thin chunk sizes if thin pool driver supports that.
Allow limited metadata changes when PVs are missing via [vg|lv]change.
Do not start dmeventd for lvchange --resync when monitoring is off.
diff --git a/liblvm/lvm_base.c b/liblvm/lvm_base.c
index 815151e..01ea0d7 100644
--- a/liblvm/lvm_base.c
+++ b/liblvm/lvm_base.c
@@ -126,3 +126,8 @@ const char *lvm_vgname_from_device(lvm_t libh, const char *device)
struct cmd_context *cmd = (struct cmd_context *)libh;
return find_vgname_from_pvname(cmd, device);
}
+
+float lvm_percent_to_float(percent_t v)
+{
+ return percent_to_float(v);
+}
11 years, 7 months
master - thin: raise required version to 1.4
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=316ce655a37136...
Commit: 316ce655a37136375dc9ea1204f218838d77ce41
Parent: 57460fe5a853c0824d35c02b2a77ef0afc8a5f2d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Oct 11 14:07:35 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Oct 11 14:09:07 2012 +0200
thin: raise required version to 1.4
Stay safe and require 1.4 (kernel 3.6) for non-power-of-2
support for thin pool chunk_size.
---
lib/thin/thin.c | 4 ++--
man/lvcreate.8.in | 2 +-
test/shell/lvcreate-thin-power2.sh | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index fd0c117..2b6c71f 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -244,7 +244,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
(seg->chunk_size & (seg->chunk_size - 1))) {
log_error("Thin pool target does not support %uKiB chunk size "
- "(needs kernel >= 3.5).", seg->chunk_size / 2);
+ "(needs kernel >= 3.6).", seg->chunk_size / 2);
return 0;
}
@@ -559,7 +559,7 @@ static int _thin_target_present(struct cmd_context *cmd,
/* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */
log_debug("Target " THIN_MODULE " does not support external origins.");
- if (maj >=1 && min >= 2)
+ if (maj >=1 && min >= 4)
_attrs |= THIN_FEATURE_BLOCK_SIZE;
else
/* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 0c39278..fb54cc6 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -133,7 +133,7 @@ For thin pools the value must be between 64KiB and
1048576KiB and the default value starts with 64 and scales
up to fit the pool metadata size within 128MB,
if the poolmetadata size is not specified.
-Older dm thin pool target version (<1.2) requires the value to be power of 2.
+Older dm thin pool target version (<1.4) requires the value to be power of 2.
The newer version requires to be the multiple of 64KiB, however discard is
not supported for non power of 2 values.
Default unit is in kilobytes.
diff --git a/test/shell/lvcreate-thin-power2.sh b/test/shell/lvcreate-thin-power2.sh
index e1c793c..882b05c 100644
--- a/test/shell/lvcreate-thin-power2.sh
+++ b/test/shell/lvcreate-thin-power2.sh
@@ -18,7 +18,7 @@
#
# Main
#
-aux have_thin 1 2 0 || skip
+aux have_thin 1 4 0 || skip
aux prepare_pvs 2 64
11 years, 7 months
master - test: Skip the topology test if setting up scsi_debug fails.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=57460fe5a853c0...
Commit: 57460fe5a853c0824d35c02b2a77ef0afc8a5f2d
Parent: deea86c7f49ea825608826e29b56a005e2c9e747
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Thu Oct 11 11:51:04 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Thu Oct 11 11:51:04 2012 +0200
test: Skip the topology test if setting up scsi_debug fails.
---
test/shell/topology-support.sh | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/test/shell/topology-support.sh b/test/shell/topology-support.sh
index cf2461c..e952dc0 100644
--- a/test/shell/topology-support.sh
+++ b/test/shell/topology-support.sh
@@ -53,7 +53,8 @@ PER_DEV_SIZE=34
DEV_SIZE=$(($NUM_DEVS*$PER_DEV_SIZE))
# Test that kernel supports topology
-aux prepare_scsi_debug_dev $DEV_SIZE
+aux prepare_scsi_debug_dev $DEV_SIZE || skip
+
if [ ! -e /sys/block/$(basename $(cat SCSI_DEBUG_DEV))/alignment_offset ] ; then
aux cleanup_scsi_debug_dev
skip
11 years, 7 months
master - pvscan --cache: Also read metadata from LVM1 PVs (BZ 863401).
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=deea86c7f49ea8...
Commit: deea86c7f49ea825608826e29b56a005e2c9e747
Parent: 2ba9fb4019f737783606d886b96db59570850937
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Wed Oct 10 21:49:40 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Wed Oct 10 21:55:24 2012 +0200
pvscan --cache: Also read metadata from LVM1 PVs (BZ 863401).
---
lib/cache/lvmetad.c | 6 ++++++
test/shell/lvmetad-lvm1.sh | 1 +
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index b5e3787..18794be 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -823,6 +823,12 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
goto_bad;
lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton);
+
+ /* LVM1 VGs have no MDAs. */
+ if (!baton.vg && lvmcache_fmt(info) == get_format_by_name(cmd, "lvm1"))
+ baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->
+ ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, 0);
+
if (!baton.vg)
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
diff --git a/test/shell/lvmetad-lvm1.sh b/test/shell/lvmetad-lvm1.sh
index c183fec..528eec2 100644
--- a/test/shell/lvmetad-lvm1.sh
+++ b/test/shell/lvmetad-lvm1.sh
@@ -17,5 +17,6 @@ pvcreate --metadatatype 1 $dev1
vgscan --cache
pvs | grep $dev1
vgcreate --metadatatype 1 $vg1 $dev1
+vgscan --cache
vgs | grep $vg1
pvs | grep $dev1
11 years, 7 months
master - lvmetad: Fix help output (flags and their meaning).
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2ba9fb4019f737...
Commit: 2ba9fb4019f737783606d886b96db59570850937
Parent: 14283662b9a1595e231f31bb7165a18d93d66cc2
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Wed Oct 10 14:38:25 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Wed Oct 10 21:55:24 2012 +0200
lvmetad: Fix help output (flags and their meaning).
---
daemons/lvmetad/lvmetad-core.c | 11 ++++-------
1 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 22625c5..8a1378a 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -1046,11 +1046,11 @@ static int fini(daemon_state *s)
static void usage(char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
- "%s [-V] [-h] [-d] [-d] [-d] [-f]\n\n"
+ "%s [-V] [-h] [-d [info[,debug[,wire]]]] [-f] [-s path]\n\n"
" -V Show version of lvmetad\n"
" -h Show this help information\n"
- " -d Log debug messages to syslog (-d, -dd, -ddd)\n"
- " -R Replace a running lvmetad instance, loading its data\n"
+ " -s Set path to the socket to listen on\n"
+ " -d Log messages to stderr (-d info,wire,debug)\n"
" -f Don't fork, run in the foreground\n\n", prog);
}
@@ -1078,7 +1078,7 @@ int main(int argc, char *argv[])
ls.debug_config = "";
// use getopt_long
- while ((opt = getopt(argc, argv, "?fhVd:Rs:")) != EOF) {
+ while ((opt = getopt(argc, argv, "?fhVd:s:")) != EOF) {
switch (opt) {
case 'h':
usage(argv[0], stdout);
@@ -1086,9 +1086,6 @@ int main(int argc, char *argv[])
case '?':
usage(argv[0], stderr);
exit(0);
- case 'R':
- _restart++;
- break;
case 'f':
s.foreground = 1;
break;
11 years, 7 months
master - test: use exclusive activation for created mirrors
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=14283662b9a159...
Commit: 14283662b9a1595e231f31bb7165a18d93d66cc2
Parent: 9db5217a3111f72298de31a6b94d33fff39401a3
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Oct 10 18:38:55 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Oct 10 21:22:12 2012 +0200
test: use exclusive activation for created mirrors
---
test/shell/lvconvert-thin.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 29beb93..97ccc09 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -22,8 +22,8 @@ aux prepare_pvs 4 64
vgcreate $vg -s 64K $(cat DEVICES)
# create mirrored LVs for data and metadata volumes
-lvcreate -l8 -m1 --mirrorlog core -n $lv1 $vg
-lvcreate -l4 -m1 --mirrorlog core -n $lv2 $vg
+lvcreate -aey -l8 -m1 --mirrorlog core -n $lv1 $vg
+lvcreate -aey -l4 -m1 --mirrorlog core -n $lv2 $vg
lvconvert -c 64K --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
11 years, 7 months
master - test: thin support for non power of 2 chunk size
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9db5217a3111f7...
Commit: 9db5217a3111f72298de31a6b94d33fff39401a3
Parent: 876514eb34d3b67cb1063ea2feca49a76be65229
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Oct 10 16:37:55 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Oct 10 21:22:12 2012 +0200
test: thin support for non power of 2 chunk size
---
test/shell/lvcreate-thin-power2.sh | 39 ++++++++++++++++++++++++++++++++++++
1 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvcreate-thin-power2.sh b/test/shell/lvcreate-thin-power2.sh
new file mode 100644
index 0000000..e1c793c
--- /dev/null
+++ b/test/shell/lvcreate-thin-power2.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# test support for non-power-of-2 thin chunk size
+#
+
+. lib/test
+
+#
+# Main
+#
+aux have_thin 1 2 0 || skip
+
+aux prepare_pvs 2 64
+
+vgcreate $vg -s 64K $(cat DEVICES)
+
+# create non-power-of-2 pool
+lvcreate -l100 -c 192 -T $vg/pool
+
+check lv_field $vg/pool discards "ignore"
+
+# check we cannot change discards settings
+not lvchange --discard passdown $vg/pool
+not lvchange --discard nopassdown $vg/pool
+
+# must be multiple of 64KB
+not lvcreate -l100 -c 168 -T $vg/pool1
+
+vgremove -ff $vg
11 years, 7 months