summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2015-10-27 11:12:59 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2015-10-27 11:42:40 +0100
commit5d76bdcdbdf6bef81872e8eef2cce156cfce228f (patch)
treed405529f78a8a8758862e9eac20c97e846b0409e
parent3b5939bbbb974913db3ff7ac363cc7f1154b894e (diff)
downloadlvm2-5d76bdcdbdf6bef81872e8eef2cce156cfce228f.tar.gz
dmeventd: event string parser handles empty field
Improve event string parser to avoid unneeded alloc+free. Daemon talk function uses '-' to mark NULL/missing field. So restore the NULL pointer back on parser. This should have made old tools like 'dmevent_tool' work again. As now 'uuid' or 'dso' could become NULL and then be properly used in _want_registered_device() function. Since lvm2 always fill these parameters, this change should have no effect on lvm2.
-rw-r--r--WHATS_NEW_DM1
-rw-r--r--daemons/dmeventd/dmeventd.c48
2 files changed, 32 insertions, 17 deletions
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index e09ab6394..961aec5ef 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.110 -
======================================
+ Fix/restore parsing of empty field '-' when processing dmeventd event.
Enhance dm_tree_node_size_changed() to recognize size reduction.
Support exit on idle for dmenventd (1 hour).
Add support to allow unmonitor device from plugin itself.
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index d6accbfea..42c724b8f 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -473,34 +473,48 @@ static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *
/*
* Fetch a string off src and duplicate it into *ptr.
- * Pay attention to zero-length strings.
+ * Pay attention to zero-length and 'empty' strings ('-').
*/
/* FIXME? move to libdevmapper to share with the client lib (need to
make delimiter a parameter then) */
static int _fetch_string(char **ptr, char **src, const int delimiter)
{
- int ret = 0;
+ int ret = 1;
char *p;
size_t len;
+ *ptr = NULL; /* Empty field returns NULL pointer */
- if ((p = strchr(*src, delimiter)))
- *p = 0;
-
- if ((*ptr = dm_strdup(*src))) {
- if ((len = strlen(*ptr)))
- *src += len;
- else {
- dm_free(*ptr);
- *ptr = NULL;
+ if ((*src)[0] == '-') {
+ /* Could be empty field '-', handle without allocation */
+ if ((*src)[1] == '\0') {
+ (*src)++;
+ goto out;
+ } else if ((*src)[1] == delimiter) {
+ (*src) += 2;
+ goto out;
}
-
- (*src)++;
- ret = 1;
}
- if (p)
- *p = delimiter;
-
+ if ((p = strchr(*src, delimiter))) {
+ if (*src < p) {
+ *p = 0; /* Temporary exit with \0 */
+ if (!(*ptr = dm_strdup(*src))) {
+ log_error("Failed to fetch item %s.", *src);
+ ret = 0; /* Allocation fail */
+ }
+ *p = delimiter;
+ *src = p;
+ }
+ (*src)++; /* Skip delmiter, next field */
+ } else if ((len = strlen(*src))) {
+ /* No delimiter, item ends with '\0' */
+ if (!(*ptr = dm_strdup(*src))) {
+ log_error("Failed to fetch last item %s.", *src);
+ ret = 0; /* Fail */
+ }
+ *src += len + 1;
+ }
+out:
return ret;
}