You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.7 KiB
73 lines
2.7 KiB
5 years ago
|
From a397b69ce33d811aba7d64d54b5c8e0efb86fd15 Mon Sep 17 00:00:00 2001
|
||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||
|
Date: Fri, 10 May 2019 14:40:11 +0200
|
||
|
Subject: [PATCH] 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).
|
||
|
---
|
||
|
libdm/libdm-config.c | 18 +++++++++++++++---
|
||
|
1 file changed, 15 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/libdm/libdm-config.c b/libdm/libdm-config.c
|
||
|
index 3f0d2510e..382f86bbf 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;
|