summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2019-05-10 14:40:11 +0200
committerZdenek Kabelac <zkabelac@redhat.com>2019-05-10 14:40:11 +0200
commit85dbcda1503eef81be11947be8b9abb0b8c41c9c (patch)
tree107e911763b53c652322e4d222a806c74406b4b4
parent1f7c9da554fdb9069bc46e973678e055a491ea1d (diff)
downloadlvm2-85dbcda1503eef81be11947be8b9abb0b8c41c9c.tar.gz
metadata: allow reading metadata with invalid creation_time
lvm2 till version 2.02.169 (commit 78d004efa8a1809cea68283e6204edfa9d7c1091) was printing invalid creation_time argument into metadata on 32bit arch. However with commit ba9820b14223b731125c83dbc9709aa44fdcdbf1 we started to properly validate all input numbers and thus we refused to accept invalid metadata with 'garbage' string - but this results in the situation where metadata produced on older lvm2 on 32 bit architecture will become unreadable after upgrade. To fix this case - extend libdm parser in a way, that whenever we find error integer value, we also check if the parsed value is not for creation_time node and in this case we let the metadata pass through with made-up date 2018-05-24 (release date of 2.02.169).
-rw-r--r--device_mapper/libdm-config.c18
-rw-r--r--libdm/libdm-config.c18
2 files changed, 30 insertions, 6 deletions
diff --git a/device_mapper/libdm-config.c b/device_mapper/libdm-config.c
index 092884342..d2ac43c85 100644
--- a/device_mapper/libdm-config.c
+++ b/device_mapper/libdm-config.c
@@ -51,6 +51,8 @@ struct parser {
struct dm_pool *mem;
int no_dup_node_check; /* whether to disable dup node checking */
+ const char *key; /* last obtained key */
+ unsigned ignored_creation_time;
};
struct config_output {
@@ -176,7 +178,7 @@ static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, co
/* TODO? if (start == end) return 1; */
struct parser *p;
- if (!(p = dm_pool_alloc(cft->mem, sizeof(*p))))
+ if (!(p = dm_pool_zalloc(cft->mem, sizeof(*p))))
return_0;
p->mem = cft->mem;
@@ -615,6 +617,7 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
match(TOK_SECTION_E);
} else {
match(TOK_EQ);
+ p->key = root->key;
if (!(value = _value(p)))
return_NULL;
if (root->v)
@@ -682,8 +685,17 @@ static struct dm_config_value *_type(struct parser *p)
errno = 0;
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
if (errno) {
- log_error("Failed to read int token.");
- return NULL;
+ if (errno == ERANGE && p->key &&
+ strcmp("creation_time", p->key) == 0) {
+ /* Due to a bug in some older 32bit builds (<2.02.169),
+ * lvm was able to produce invalid creation_time string */
+ v->v.i = 1527120000; /* Pick 2018-05-24 day instead */
+ if (!p->ignored_creation_time++)
+ log_warn("WARNING: Invalid creation_time found in metadata (repaired with next metadata update).");
+ } else {
+ log_error("Failed to read int token.");
+ return NULL;
+ }
}
match(TOK_INT);
break;
diff --git a/libdm/libdm-config.c b/libdm/libdm-config.c
index 3666fc9b0..6edeee2d1 100644
--- a/libdm/libdm-config.c
+++ b/libdm/libdm-config.c
@@ -51,6 +51,8 @@ struct parser {
struct dm_pool *mem;
int no_dup_node_check; /* whether to disable dup node checking */
+ const char *key; /* last obtained key */
+ unsigned ignored_creation_time;
};
struct config_output {
@@ -176,7 +178,7 @@ static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, co
/* TODO? if (start == end) return 1; */
struct parser *p;
- if (!(p = dm_pool_alloc(cft->mem, sizeof(*p))))
+ if (!(p = dm_pool_zalloc(cft->mem, sizeof(*p))))
return_0;
p->mem = cft->mem;
@@ -615,6 +617,7 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
match(TOK_SECTION_E);
} else {
match(TOK_EQ);
+ p->key = root->key;
if (!(value = _value(p)))
return_NULL;
if (root->v)
@@ -682,8 +685,17 @@ static struct dm_config_value *_type(struct parser *p)
errno = 0;
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
if (errno) {
- log_error("Failed to read int token.");
- return NULL;
+ if (errno == ERANGE && p->key &&
+ strcmp("creation_time", p->key) == 0) {
+ /* Due to a bug in some older 32bit builds (<2.02.169),
+ * lvm was able to produce invalid creation_time string */
+ v->v.i = 1527120000; /* Pick 2018-05-24 day instead */
+ if (!p->ignored_creation_time++)
+ log_warn("WARNING: Invalid creation_time found in metadata (repaired with next metadata update).");
+ } else {
+ log_error("Failed to read int token.");
+ return NULL;
+ }
}
match(TOK_INT);
break;