master - tests: pvck dump from larger metadata areas
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f6667f94cb1204aad57...
Commit: f6667f94cb1204aad5703d129aeeca8286ebaf18
Parent: 1b711b955db17617e723abcfcb0b8e21eb0ce7f5
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Mar 3 13:44:59 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 13:47:07 2020 -0600
tests: pvck dump from larger metadata areas
---
test/shell/pvck-dump.sh | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/test/shell/pvck-dump.sh b/test/shell/pvck-dump.sh
index 17faa17..5c662f6 100644
--- a/test/shell/pvck-dump.sh
+++ b/test/shell/pvck-dump.sh
@@ -12,7 +12,7 @@
. lib/inittest
-aux prepare_devs 4
+aux prepare_devs 8 512
get_devs
dd if=/dev/zero of="$dev1" || true
@@ -129,3 +129,36 @@ diff area1 area3b
vgremove -ff $vg
+pvremove "$dev1"
+pvremove "$dev2"
+pvremove "$dev3"
+pvremove "$dev4"
+
+pvcreate --pvmetadatacopies 2 --metadatasize 32M "$dev1"
+
+vgcreate $SHARED -s 512K --metadatasize 32M $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5" "$dev6" "$dev7" "$dev8"
+
+for i in `seq 1 500`; do lvcreate -an -n lv$i -l1 $vg; done
+
+pvck --dump headers "$dev1" > h1
+
+pvck --dump metadata_search "$dev1" > m1
+grep "seqno 500" m1
+
+dd if="$dev1" of=dev1dd bs=1M count=32
+dd if=/dev/zero of="$dev1" bs=4K count=1
+
+# mda_size for mda1 is 32M - 4K
+pvck --dump metadata_search --settings "mda_num=1 mda_size=33550336" "$dev1" > m1b
+grep "seqno 500" m1b
+
+pvck --dump metadata_search --settings "mda_num=1 mda_size=33550336" dev1dd > m1c
+grep "seqno 500" m1c
+
+# mda_size for mda2 is 32M
+pvck --dump metadata_search --settings "mda_num=2 mda_size=33554432" "$dev1" > m2
+grep "seqno 500" m2
+
+dd if=dev1dd of="$dev1" bs=1M count=32
+
+vgremove -ff $vg
4 years, 1 month
master - pvck: allow dump from file
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1b711b955db17617e72...
Commit: 1b711b955db17617e723abcfcb0b8e21eb0ce7f5
Parent: f140620043eb22b192e7d87e17a42fcd0a3656a1
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Mar 2 16:26:44 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 13:47:07 2020 -0600
pvck: allow dump from file
---
tools/pvck.c | 154 ++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 111 insertions(+), 43 deletions(-)
diff --git a/tools/pvck.c b/tools/pvck.c
index 79e3af5..566dfc3 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -341,10 +341,62 @@ static uint64_t mda2_size_from_offset(struct device *dev, uint64_t mda2_offset)
return mda2_size;
}
+struct devicefile {
+ char path[PATH_MAX];
+ int fd;
+};
+
+static struct devicefile *get_devicefile(const char *path)
+{
+ struct stat sb;
+ struct devicefile *def;
+
+ if (stat(path, &sb))
+ return_NULL;
+
+ if ((sb.st_mode & S_IFMT) != S_IFREG)
+ return_NULL;
+
+ if (!(def = malloc(sizeof(struct devicefile))))
+ return_NULL;
+
+ if (dm_snprintf(def->path, PATH_MAX, "%s", path) < 0) {
+ free(def);
+ return_NULL;
+ }
+
+ if ((def->fd = open(path, O_RDONLY)) < 0) {
+ free(def);
+ return_NULL;
+ }
+
+ return def;
+}
+
+static bool _read_bytes(struct device *dev, struct devicefile *def, uint64_t start, size_t len, void *data)
+{
+ off_t off;
+ ssize_t rv;
+
+ if (dev)
+ return dev_read_bytes(dev, start, len, data);
+
+ off = lseek(def->fd, start, SEEK_SET);
+ if (off != start)
+ return false;
+
+ rv = read(def->fd, data, len);
+ if (rv < 0)
+ return false;
+ if (rv != len)
+ return false;
+ return true;
+}
/* all sizes and offsets in bytes */
-static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const char *tofile, struct device *dev,
+static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const char *tofile,
+ struct device *dev, struct devicefile *def,
int mda_num, uint64_t mda_offset, uint64_t mda_size, char *buf)
{
FILE *fp = NULL;
@@ -719,7 +771,7 @@ static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_of
* (the location of the metadata text in the metadata area.)
*/
-static int _dump_raw_locn(struct device *dev, int print_fields,
+static int _dump_raw_locn(struct device *dev, struct devicefile *def, int print_fields,
struct raw_locn *rlocn, int rlocn_index, uint64_t rlocn_offset,
int mda_num, uint64_t mda_offset, uint64_t mda_size,
uint64_t *meta_offset_ret,
@@ -789,7 +841,7 @@ static int _dump_raw_locn(struct device *dev, int print_fields,
return 1;
}
-static int _dump_meta_area(struct device *dev, const char *tofile,
+static int _dump_meta_area(struct device *dev, struct devicefile *def, const char *tofile,
uint64_t mda_offset, uint64_t mda_size)
{
FILE *fp;
@@ -801,7 +853,7 @@ static int _dump_meta_area(struct device *dev, const char *tofile,
if (!(meta_buf = zalloc(mda_size)))
return_0;
- if (!dev_read_bytes(dev, mda_offset, mda_size, meta_buf)) {
+ if (!_read_bytes(dev, def, mda_offset, mda_size, meta_buf)) {
log_print("CHECK: failed to read metadata area at offset %llu size %llu",
(unsigned long long)mda_offset, (unsigned long long)mda_size);
free(meta_buf);
@@ -827,7 +879,7 @@ static int _dump_meta_area(struct device *dev, const char *tofile,
/* all sizes and offsets in bytes */
-static int _dump_current_text(struct device *dev,
+static int _dump_current_text(struct device *dev, struct devicefile *def,
int print_fields, int print_metadata, const char *tofile,
int mda_num, int rlocn_index,
uint64_t mda_offset, uint64_t mda_size,
@@ -865,7 +917,7 @@ static int _dump_current_text(struct device *dev,
off_t offset_b = mda_offset + 512; /* continues after mda_header sector */
uint32_t size_b = wrap;
- if (!dev_read_bytes(dev, offset_a, size_a, meta_buf)) {
+ if (!_read_bytes(dev, def, offset_a, size_a, meta_buf)) {
log_print("CHECK: failed to read metadata text at mda_header_%d.raw_locn[%d].offset %llu size %llu part_a %llu %llu", mn, ri,
(unsigned long long)meta_offset, (unsigned long long)meta_size,
(unsigned long long)offset_a, (unsigned long long)size_a);
@@ -873,7 +925,7 @@ static int _dump_current_text(struct device *dev,
return 0;
}
- if (!dev_read_bytes(dev, offset_b, size_b, meta_buf + size_a)) {
+ if (!_read_bytes(dev, def, offset_b, size_b, meta_buf + size_a)) {
log_print("CHECK: failed to read metadata text at mda_header_%d.raw_locn[%d].offset %llu size %llu part_b %llu %llu", mn, ri,
(unsigned long long)meta_offset, (unsigned long long)meta_size,
(unsigned long long)offset_b, (unsigned long long)size_b);
@@ -881,7 +933,7 @@ static int _dump_current_text(struct device *dev,
return 0;
}
} else {
- if (!dev_read_bytes(dev, mda_offset + meta_offset, meta_size, meta_buf)) {
+ if (!_read_bytes(dev, def, mda_offset + meta_offset, meta_size, meta_buf)) {
log_print("CHECK: failed to read metadata text at mda_header_%d.raw_locn[%d].offset %llu size %llu", mn, ri,
(unsigned long long)meta_offset, (unsigned long long)meta_size);
free(meta_buf);
@@ -951,7 +1003,8 @@ static int _dump_current_text(struct device *dev,
/* all sizes and offsets in bytes */
-static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsector, struct device *dev,
+static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsector,
+ struct device *dev, struct devicefile *def,
int print_fields,
int *found_label,
uint64_t *mda1_offset, uint64_t *mda1_size,
@@ -975,7 +1028,7 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsect
lh_offset = labelsector * 512; /* from start of disk */
- if (!dev_read_bytes(dev, lh_offset, 512, buf)) {
+ if (!_read_bytes(dev, def, lh_offset, 512, buf)) {
log_print("CHECK: failed to read label_header at %llu",
(unsigned long long)lh_offset);
return 0;
@@ -985,7 +1038,7 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsect
* Not invalidating this range can cause an error reading
* a larger range that overlaps this.
*/
- if (!dev_invalidate_bytes(dev, lh_offset, 512))
+ if (dev && !dev_invalidate_bytes(dev, lh_offset, 512))
stack;
lh = (struct label_header *)buf;
@@ -1202,7 +1255,7 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsect
static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
int print_fields, int print_metadata, int print_area,
const char *tofile,
- struct device *dev,
+ struct device *dev, struct devicefile *def,
uint64_t mda_offset, uint64_t mda_size,
uint32_t *checksum0_ret,
int *found_header)
@@ -1232,7 +1285,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
* (Why was mda_header magic made only partially printable?)
*/
- if (!dev_read_bytes(dev, mda_offset, 512, buf)) {
+ if (!_read_bytes(dev, def, mda_offset, 512, buf)) {
log_print("CHECK: failed to read mda_header at %llu", (unsigned long long)mda_offset);
return 0;
}
@@ -1252,7 +1305,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
bad++;
if (print_area) {
- if (!_dump_meta_area(dev, tofile, mda_offset, mda_size))
+ if (!_dump_meta_area(dev, def, tofile, mda_offset, mda_size))
bad++;
goto out;
}
@@ -1274,7 +1327,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
meta_size = 0;
meta_checksum = 0;
- if (!_dump_raw_locn(dev, print_fields, rlocn0, 0, rlocn0_offset, mda_num, mda_offset, mda_size,
+ if (!_dump_raw_locn(dev, def, print_fields, rlocn0, 0, rlocn0_offset, mda_num, mda_offset, mda_size,
&meta_offset, &meta_size, &meta_checksum))
bad++;
@@ -1287,7 +1340,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
if ((void *)rlocn1 != (void *)(buf + rlocn1_offset - mda_offset))
log_print("CHECK: problem with rlocn1 offset calculation");
- if (!_dump_raw_locn(dev, print_fields, rlocn1, 1, rlocn1_offset, mda_num, mda_offset, mda_size,
+ if (!_dump_raw_locn(dev, def, print_fields, rlocn1, 1, rlocn1_offset, mda_num, mda_offset, mda_size,
NULL, NULL, NULL))
bad++;
@@ -1298,7 +1351,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
* looking at the current copy of metadata referenced by raw_locn
*/
if (print_metadata <= PRINT_CURRENT) {
- if (!_dump_current_text(dev, print_fields, print_metadata, tofile, mda_num, 0, mda_offset, mda_size, meta_offset, meta_size, meta_checksum))
+ if (!_dump_current_text(dev, def, print_fields, print_metadata, tofile, mda_num, 0, mda_offset, mda_size, meta_offset, meta_size, meta_checksum))
bad++;
}
@@ -1309,7 +1362,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
if (!(mda_buf = zalloc(mda_size)))
goto_out;
- if (!dev_read_bytes(dev, mda_offset, mda_size, mda_buf)) {
+ if (!_read_bytes(dev, def, mda_offset, mda_size, mda_buf)) {
log_print("CHECK: failed to read metadata area at offset %llu size %llu",
(unsigned long long)mda_offset, (unsigned long long)mda_size);
bad++;
@@ -1317,7 +1370,7 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
goto out;
}
- _dump_all_text(cmd, set, tofile, dev, mda_num, mda_offset, mda_size, mda_buf);
+ _dump_all_text(cmd, set, tofile, dev, def, mda_num, mda_offset, mda_size, mda_buf);
free(mda_buf);
}
@@ -1331,14 +1384,14 @@ static int _dump_mda_header(struct cmd_context *cmd, struct settings *set,
/* all sizes and offsets in bytes */
static int _dump_headers(struct cmd_context *cmd, const char *dump, struct settings *set,
- uint64_t labelsector, struct device *dev)
+ uint64_t labelsector, struct device *dev, struct devicefile *def)
{
uint64_t mda1_offset = 0, mda1_size = 0, mda2_offset = 0, mda2_size = 0; /* bytes */
uint32_t mda1_checksum, mda2_checksum;
int mda_count = 0;
int bad = 0;
- if (!_dump_label_and_pv_header(cmd, labelsector, dev, 1, NULL,
+ if (!_dump_label_and_pv_header(cmd, labelsector, dev, def, 1, NULL,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count))
bad++;
@@ -1350,11 +1403,11 @@ static int _dump_headers(struct cmd_context *cmd, const char *dump, struct setti
/*
* The first mda is always 4096 bytes from the start of the device.
*/
- if (!_dump_mda_header(cmd, set, 1, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum, NULL))
+ if (!_dump_mda_header(cmd, set, 1, 0, 0, NULL, dev, def, 4096, mda1_size, &mda1_checksum, NULL))
bad++;
if (mda2_offset) {
- if (!_dump_mda_header(cmd, set, 1, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum, NULL))
+ if (!_dump_mda_header(cmd, set, 1, 0, 0, NULL, dev, def, mda2_offset, mda2_size, &mda2_checksum, NULL))
bad++;
/* This probably indicates that one was committed and the other not. */
@@ -1372,7 +1425,7 @@ static int _dump_headers(struct cmd_context *cmd, const char *dump, struct setti
/* all sizes and offsets in bytes */
static int _dump_metadata(struct cmd_context *cmd, const char *dump, struct settings *set,
- uint64_t labelsector, struct device *dev,
+ uint64_t labelsector, struct device *dev, struct devicefile *def,
int print_metadata, int print_area)
{
const char *tofile = NULL;
@@ -1392,7 +1445,7 @@ static int _dump_metadata(struct cmd_context *cmd, const char *dump, struct sett
else if (arg_is_set(cmd, pvmetadatacopies_ARG))
mda_num = arg_int_value(cmd, pvmetadatacopies_ARG, 1);
- if (!_dump_label_and_pv_header(cmd, labelsector, dev, 0, NULL,
+ if (!_dump_label_and_pv_header(cmd, labelsector, dev, def, 0, NULL,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count))
bad++;
@@ -1405,14 +1458,14 @@ static int _dump_metadata(struct cmd_context *cmd, const char *dump, struct sett
* The first mda is always 4096 bytes from the start of the device.
*/
if (mda_num == 1) {
- if (!_dump_mda_header(cmd, set, 0, print_metadata, print_area, tofile, dev, 4096, mda1_size, &mda1_checksum, NULL))
+ if (!_dump_mda_header(cmd, set, 0, print_metadata, print_area, tofile, dev, def, 4096, mda1_size, &mda1_checksum, NULL))
bad++;
} else if (mda_num == 2) {
if (!mda2_offset) {
log_print("CHECK: second mda not found");
bad++;
} else {
- if (!_dump_mda_header(cmd, set, 0, print_metadata, print_area, tofile, dev, mda2_offset, mda2_size, &mda2_checksum, NULL))
+ if (!_dump_mda_header(cmd, set, 0, print_metadata, print_area, tofile, dev, def, mda2_offset, mda2_size, &mda2_checksum, NULL))
bad++;
}
}
@@ -1434,17 +1487,17 @@ static int _dump_found(struct cmd_context *cmd, struct settings *set, uint64_t l
int mda_count = 0;
int bad = 0;
- if (!_dump_label_and_pv_header(cmd, labelsector, dev, 0, &found_label,
+ if (!_dump_label_and_pv_header(cmd, labelsector, dev, NULL, 0, &found_label,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count))
bad++;
if (found_label && mda1_offset) {
- if (!_dump_mda_header(cmd, set, 0, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum, &found_header1))
+ if (!_dump_mda_header(cmd, set, 0, 0, 0, NULL, dev, NULL, 4096, mda1_size, &mda1_checksum, &found_header1))
bad++;
}
if (found_label && mda2_offset) {
- if (!_dump_mda_header(cmd, set, 0, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum, &found_header2))
+ if (!_dump_mda_header(cmd, set, 0, 0, 0, NULL, dev, NULL, mda2_offset, mda2_size, &mda2_checksum, &found_header2))
bad++;
}
@@ -1480,7 +1533,7 @@ static int _dump_found(struct cmd_context *cmd, struct settings *set, uint64_t l
*/
static int _dump_search(struct cmd_context *cmd, const char *dump, struct settings *set,
- uint64_t labelsector, struct device *dev)
+ uint64_t labelsector, struct device *dev, struct devicefile *def)
{
const char *tofile = NULL;
char *buf;
@@ -1496,7 +1549,7 @@ static int _dump_search(struct cmd_context *cmd, const char *dump, struct settin
return_0;
}
- _dump_label_and_pv_header(cmd, labelsector, dev, 0, &found_label,
+ _dump_label_and_pv_header(cmd, labelsector, dev, def, 0, &found_label,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count);
/*
@@ -1685,14 +1738,14 @@ static int _dump_search(struct cmd_context *cmd, const char *dump, struct settin
if (!(buf = zalloc(mda_size)))
return_0;
- if (!dev_read_bytes(dev, mda_offset, mda_size, buf)) {
+ if (!_read_bytes(dev, def, mda_offset, mda_size, buf)) {
log_print("CHECK: failed to read metadata area at offset %llu size %llu",
(unsigned long long)mda_offset, (unsigned long long)mda_size);
free(buf);
return 0;
}
- _dump_all_text(cmd, set, tofile, dev, mda_num, mda_offset, mda_size, buf);
+ _dump_all_text(cmd, set, tofile, dev, def, mda_num, mda_offset, mda_size, buf);
free(buf);
return 1;
@@ -1856,7 +1909,7 @@ static int _repair_label_header(struct cmd_context *cmd, const char *repair,
lh_offset = labelsector * 512; /* from start of disk */
- _dump_label_and_pv_header(cmd, labelsector, dev, 0, &found_label,
+ _dump_label_and_pv_header(cmd, labelsector, dev, NULL, 0, &found_label,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count);
if (!found_label) {
@@ -2188,7 +2241,7 @@ static int _repair_pv_header(struct cmd_context *cmd, const char *repair,
log_warn("WARNING: Cannot get device size.");
get_size = get_size_sectors << SECTOR_SHIFT;
- _dump_label_and_pv_header(cmd, labelsector, dev, 0, &found_label,
+ _dump_label_and_pv_header(cmd, labelsector, dev, NULL, 0, &found_label,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count);
/*
@@ -2549,7 +2602,7 @@ static int _repair_metadata(struct cmd_context *cmd, const char *repair,
return 0;
}
- _dump_label_and_pv_header(cmd, labelsector, dev, 0, &found_label,
+ _dump_label_and_pv_header(cmd, labelsector, dev, NULL, 0, &found_label,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count);
if (!found_label) {
@@ -2957,6 +3010,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
struct settings set;
struct metadata_file mf;
struct device *dev = NULL;
+ struct devicefile *def = NULL;
const char *dump, *repair;
const char *pv_name;
uint64_t labelsector = 1;
@@ -2975,7 +3029,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
if (arg_is_set(cmd, labelsector_ARG))
labelsector = arg_uint64_value(cmd, labelsector_ARG, UINT64_C(0));
- if (arg_is_set(cmd, dump_ARG) || arg_is_set(cmd, repairtype_ARG) || arg_is_set(cmd, repair_ARG)) {
+ if (arg_is_set(cmd, repairtype_ARG) || arg_is_set(cmd, repair_ARG)) {
pv_name = argv[0];
if (!(dev = dev_cache_get(cmd, pv_name, cmd->filter))) {
@@ -2984,6 +3038,20 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
}
}
+ if (arg_is_set(cmd, dump_ARG)) {
+ pv_name = argv[0];
+
+ dev = dev_cache_get(cmd, pv_name, cmd->filter);
+
+ if (!dev)
+ def = get_devicefile(pv_name);
+
+ if (!dev && !def) {
+ log_error("No device found for %s %s.", pv_name, dev_cache_filtered_reason(pv_name));
+ return ECMD_FAILED;
+ }
+ }
+
if (!_get_settings(cmd, &set))
return ECMD_FAILED;
@@ -3003,19 +3071,19 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
dump = arg_str_value(cmd, dump_ARG, NULL);
if (!strcmp(dump, "metadata"))
- ret = _dump_metadata(cmd, dump, &set, labelsector, dev, PRINT_CURRENT, 0);
+ ret = _dump_metadata(cmd, dump, &set, labelsector, dev, def, PRINT_CURRENT, 0);
else if (!strcmp(dump, "metadata_all"))
- ret = _dump_metadata(cmd, dump, &set, labelsector, dev, PRINT_ALL, 0);
+ ret = _dump_metadata(cmd, dump, &set, labelsector, dev, def, PRINT_ALL, 0);
else if (!strcmp(dump, "metadata_area"))
- ret = _dump_metadata(cmd, dump, &set, labelsector, dev, 0, 1);
+ ret = _dump_metadata(cmd, dump, &set, labelsector, dev, def, 0, 1);
else if (!strcmp(dump, "metadata_search"))
- ret = _dump_search(cmd, dump, &set, labelsector, dev);
+ ret = _dump_search(cmd, dump, &set, labelsector, dev, def);
else if (!strcmp(dump, "headers"))
- ret = _dump_headers(cmd, dump, &set, labelsector, dev);
+ ret = _dump_headers(cmd, dump, &set, labelsector, dev, def);
else if (!strcmp(dump, "backup_to_raw")) {
ret = _dump_backup_to_raw(cmd, &set);
4 years, 1 month
master - pvck: improve mda_offset mda_size choices
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c6746181a3c2c40447f...
Commit: c6746181a3c2c40447f5a33e15359b57567f8217
Parent: 1b79673845496402d9614784e8b08dbd284328ae
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Feb 28 12:00:23 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 13:47:07 2020 -0600
pvck: improve mda_offset mda_size choices
Attempt to calculate an offset or size if one only
value was specified in the settings.
Use header values when available.
---
tools/pvck.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 182 insertions(+), 17 deletions(-)
diff --git a/tools/pvck.c b/tools/pvck.c
index 745f0f9..ab85537 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -20,6 +20,8 @@
#include "lib/mm/xlate.h"
#include "lib/misc/crc.h"
+#define ONE_MB_IN_BYTES 1048576
+
#define PRINT_CURRENT 1
#define PRINT_ALL 2
@@ -297,6 +299,49 @@ static void _copy_line(char *in, char *out, int *len, int linesize)
*len = i+1;
}
+static uint64_t mda2_offset_from_size(struct device *dev, uint64_t mda2_size)
+{
+ uint64_t dev_sectors = 0;
+ uint64_t dev_bytes;
+ uint64_t extra_bytes;
+ uint64_t mda2_offset;
+
+ if (dev_get_size(dev, &dev_sectors))
+ stack;
+
+ dev_bytes = dev_sectors * 512;
+ extra_bytes = dev_bytes % ONE_MB_IN_BYTES;
+
+ if (dev_bytes < (2 * ONE_MB_IN_BYTES))
+ return_0;
+
+ mda2_offset = dev_bytes - extra_bytes - mda2_size;
+
+ return mda2_offset;
+}
+
+static uint64_t mda2_size_from_offset(struct device *dev, uint64_t mda2_offset)
+{
+ uint64_t dev_sectors = 0;
+ uint64_t dev_bytes;
+ uint64_t extra_bytes;
+ uint64_t mda2_size;
+
+ if (dev_get_size(dev, &dev_sectors))
+ stack;
+
+ dev_bytes = dev_sectors * 512;
+ extra_bytes = dev_bytes % ONE_MB_IN_BYTES;
+
+ if (dev_bytes < (2 * ONE_MB_IN_BYTES))
+ return_0;
+
+ mda2_size = dev_bytes - extra_bytes - mda2_offset;
+
+ return mda2_size;
+}
+
+
/* all sizes and offsets in bytes */
static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const char *tofile, struct device *dev,
@@ -1419,8 +1464,6 @@ static int _dump_found(struct cmd_context *cmd, struct settings *set, uint64_t l
return 1;
}
-#define ONE_MB_IN_BYTES 1048576
-
/*
* all sizes and offsets in bytes (except dev_sectors from dev_get_size)
*
@@ -1435,21 +1478,18 @@ static int _dump_search(struct cmd_context *cmd, const char *dump, struct settin
const char *tofile = NULL;
char *buf;
uint64_t mda1_offset = 0, mda1_size = 0, mda2_offset = 0, mda2_size = 0; /* bytes */
- uint64_t mda_offset, mda_size; /* bytes */
+ uint64_t mda_offset = 0, mda_size = 0; /* bytes */
+ int mda_num = 0;
+ int found_label = 0;
int mda_count = 0;
- int mda_num = 1;
+ int set_vals = 0;
if (arg_is_set(cmd, file_ARG)) {
if (!(tofile = arg_str_value(cmd, file_ARG, NULL)))
return_0;
}
- if (set->mda_num)
- mda_num = set->mda_num;
- else if (arg_is_set(cmd, pvmetadatacopies_ARG))
- mda_num = arg_int_value(cmd, pvmetadatacopies_ARG, 1);
-
- _dump_label_and_pv_header(cmd, labelsector, dev, 0, NULL,
+ _dump_label_and_pv_header(cmd, labelsector, dev, 0, &found_label,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count);
/*
@@ -1470,13 +1510,131 @@ static int _dump_search(struct cmd_context *cmd, const char *dump, struct settin
* at the end of device (mod 1MB extra) can make mda2 even
* larger.
*/
- if (set->mda_offset_set && set->mda_size_set) {
- mda_offset = set->mda_offset;
- mda_size = set->mda_size;
+
+ /*
+ * When mda offset or size is set in command line settings,
+ * use what is set and calculate an unspecified value.
+ */
+ if (set->mda_offset_set || set->mda_size_set) {
+ if (set->mda_offset_set) {
+ mda_offset = set->mda_offset;
+ set_vals++;
+ }
+ if (set->mda_size_set) {
+ mda_size = set->mda_size;
+ set_vals++;
+ }
+ if ((mda_num = set->mda_num))
+ set_vals++;
+
+ if (mda_offset && mda_size)
+ goto search;
+
+ if (set_vals < 2) {
+ log_error("Specify at least two values from: mda_num, mda_offset, mda_size.");
+ return 0;
+ }
+
+ if (!mda_size) {
+ if ((mda_num == 1) && mda1_size)
+ mda_size = mda1_size; /* from headers */
+ else if ((mda_num == 2) && mda2_size)
+ mda_size = mda2_size; /* from headers */
+ else if (mda_num == 1)
+ mda_size = ONE_MB_IN_BYTES - 4096;
+ else if (mda_num == 2)
+ mda_size = mda2_size_from_offset(dev, mda_offset);
+ }
+ if (!mda_offset) {
+ if (mda_num == 1)
+ mda_offset = 4096;
+ else if (mda_num == 2)
+ mda_offset = mda2_offset_from_size(dev, mda_size);
+ }
+
+ if (set->mda2_offset_set || set->mda2_size_set)
+ log_print("Ignoring mda2 values from settings.");
+
+ goto search;
+ }
+ if (set->mda2_offset_set || set->mda2_size_set) {
+ if (set->mda2_offset_set) {
+ mda_offset = set->mda2_offset;
+ set_vals++;
+ }
+ if (set->mda_size_set) {
+ mda_size = set->mda2_size;
+ set_vals++;
+ }
+ if ((mda_num = set->mda_num))
+ set_vals++;
+
+ if (mda_offset && mda_size)
+ goto search;
+
+ if (set_vals < 2) {
+ log_error("Specify at least two values from: mda_num, mda2_offset, mda2_size.");
+ return 0;
+ }
+
+ if (mda_num == 1) {
+ log_error("Invalid mda_num=1 and mda2 settings.");
+ return 0;
+ }
+
+ if (!mda_size) {
+ if (mda2_size)
+ mda_size = mda2_size; /* from headers */
+ else
+ mda_size = mda2_size_from_offset(dev, mda_offset);
+ }
+ if (!mda_offset) {
+ if (mda2_offset)
+ mda_offset = mda2_offset; /* from headers */
+ else
+ mda_offset = mda2_offset_from_size(dev, mda_size);
+ }
+
+ goto search;
+ }
+
+ /*
+ * When no mda offset or size is set in command line settings,
+ * the user can just set mda_num=1|2 to control if we pick defaults
+ * for mda1 or mda2. If unspecified, we search in the first mda.
+ */
+ if (set->mda_num)
+ mda_num = set->mda_num;
+ else if (arg_is_set(cmd, pvmetadatacopies_ARG))
+ mda_num = arg_int_value(cmd, pvmetadatacopies_ARG, 1);
+ else
+ mda_num = 1;
+
+ /*
+ * No mda offset or size was set in command line settings,
+ * so we use what's in the headers or defaults.
+ */
+ if ((mda_num == 1) && found_label && mda1_offset && mda1_size) {
+ /* use header values when available */
+ mda_offset = 4096;
+ mda_size = mda1_size;
+
} else if (mda_num == 1) {
+ /* use default values when header values are not available */
mda_offset = 4096;
mda_size = ONE_MB_IN_BYTES - 4096;
+
+ log_print("Using common defaults for first mda: offset %llu size %llu.",
+ (unsigned long long)mda_offset, (unsigned long long)mda_size);
+ log_print("Override defaults with --settings \"mda_offset=<bytes> mda_size=<bytes>\"");
+
+ } else if ((mda_num == 2) && found_label && mda2_offset && mda2_size) {
+ /* use header values when available */
+ mda_offset = mda2_offset;
+ mda_size = mda2_size;
+
} else if (mda_num == 2) {
+ /* use default values when header values are not available */
uint64_t dev_sectors = 0;
uint64_t dev_bytes;
uint64_t extra_bytes;
@@ -1492,17 +1650,24 @@ static int _dump_search(struct cmd_context *cmd, const char *dump, struct settin
mda_offset = dev_bytes - extra_bytes - ONE_MB_IN_BYTES;
mda_size = dev_bytes - mda_offset;
- } else
+
+ log_print("Using defaults for second mda: offset %llu size %llu.",
+ (unsigned long long)mda_offset, (unsigned long long)mda_size);
+ log_print("Override defaults with --settings \"mda_offset=<bytes> mda_size=<bytes>\"");
+ } else {
+ log_error("No mda location.");
return_0;
+ }
- if ((mda_num == 1) && (mda1_offset != mda_offset)) {
+ search:
+ if ((mda_num == 1) && ((mda1_offset && mda1_offset != mda_offset) || (mda1_size && mda1_size != mda_size))) {
log_print("Ignoring mda1_offset %llu mda1_size %llu from pv_header.",
(unsigned long long)mda1_offset,
(unsigned long long)mda1_size);
}
- if ((mda_num == 2) && (mda2_offset != mda_offset)) {
- log_print("Ignoring mda2_size %llu mda2_offset %llu from pv_header.",
+ if ((mda_num == 2) && ((mda2_offset && mda2_offset != mda_offset) || (mda2_size && mda2_size != mda_size))) {
+ log_print("Ignoring mda2_offset %llu mda2_size %llu from pv_header.",
(unsigned long long)mda2_offset,
(unsigned long long)mda2_size);
}
4 years, 1 month
master - pvck: fix reading large mda1
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f140620043eb22b192e...
Commit: f140620043eb22b192e7d87e17a42fcd0a3656a1
Parent: c6746181a3c2c40447f5a33e15359b57567f8217
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Mar 2 15:22:39 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 13:47:07 2020 -0600
pvck: fix reading large mda1
When mda_size is larger than io_memory_size, reading
the entire mda fails unless the previous read of the
label has been invalidated.
---
tools/pvck.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tools/pvck.c b/tools/pvck.c
index ab85537..79e3af5 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -981,6 +981,13 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsect
return 0;
}
+ /*
+ * Not invalidating this range can cause an error reading
+ * a larger range that overlaps this.
+ */
+ if (!dev_invalidate_bytes(dev, lh_offset, 512))
+ stack;
+
lh = (struct label_header *)buf;
if (print_fields) {
4 years, 1 month
master - pvck: print longer command description
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1b79673845496402d96...
Commit: 1b79673845496402d9614784e8b08dbd284328ae
Parent: b19b7b6111fb115cd3297e9141a41dfab74ffd2e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Feb 28 11:24:28 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 13:47:07 2020 -0600
pvck: print longer command description
---
tools/pvck.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/tools/pvck.c b/tools/pvck.c
index a199d73..745f0f9 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -280,6 +280,9 @@ static int _text_buf_parsable(char *text_buf, uint64_t text_size)
#define MAX_LINE_CHECK 128
+#define MAX_DESC 1024
+char desc_line[MAX_DESC];
+
static void _copy_line(char *in, char *out, int *len, int linesize)
{
int i;
@@ -502,18 +505,18 @@ static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const c
if (arg_is_set(cmd, verbose_ARG)) {
char *str1, *str2;
if ((str1 = strstr(text_buf, "description = "))) {
- memset(line, 0, sizeof(line));
- _copy_line(str1, line, &len, sizeof(line)-1);
- if ((p = strchr(line, '\n')))
+ memset(desc_line, 0, sizeof(desc_line));
+ _copy_line(str1, desc_line, &len, sizeof(desc_line)-1);
+ if ((p = strchr(desc_line, '\n')))
*p = '\0';
- log_print("%s", line);
+ log_print("%s", desc_line);
}
if (str1 && (str2 = strstr(str1, "creation_time = "))) {
- memset(line, 0, sizeof(line));
- _copy_line(str2, line, &len, sizeof(line)-1);
- if ((p = strchr(line, '\n')))
+ memset(desc_line, 0, sizeof(desc_line));
+ _copy_line(str2, desc_line, &len, sizeof(desc_line)-1);
+ if ((p = strchr(desc_line, '\n')))
*p = '\0';
- log_print("%s\n", line);
+ log_print("%s\n", desc_line);
}
}
4 years, 1 month
master - pvck: ensure text lines are terminated
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b19b7b6111fb115cd32...
Commit: b19b7b6111fb115cd3297e9141a41dfab74ffd2e
Parent: f50e7ce76c0c6b2745d0ed2a766f46cea07f310c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Feb 28 11:20:27 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 13:47:07 2020 -0600
pvck: ensure text lines are terminated
---
tools/pvck.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/pvck.c b/tools/pvck.c
index d57e026..a199d73 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -397,7 +397,7 @@ static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const c
* copy line of possible metadata to check for vgname
*/
memset(line, 0, sizeof(line));
- _copy_line(p, line, &len, sizeof(line));
+ _copy_line(p, line, &len, sizeof(line)-1);
p += len;
if (!_check_vgname_start(line, &vgnamelen)) {
@@ -411,7 +411,7 @@ static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const c
* copy next line of metadata, which should contain id
*/
memset(line, 0, sizeof(line));
- _copy_line(p, line, &len, sizeof(line));
+ _copy_line(p, line, &len, sizeof(line)-1);
p += len;
if (strncmp(line, "id = ", 5)) {
@@ -425,7 +425,7 @@ static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const c
* copy next line of metadata, which should contain seqno
*/
memset(line, 0, sizeof(line));
- _copy_line(p, line, &len, sizeof(line));
+ _copy_line(p, line, &len, sizeof(line)-1);
p += len;
if (strncmp(line, "seqno = ", 8)) {
@@ -503,14 +503,14 @@ static int _dump_all_text(struct cmd_context *cmd, struct settings *set, const c
char *str1, *str2;
if ((str1 = strstr(text_buf, "description = "))) {
memset(line, 0, sizeof(line));
- _copy_line(str1, line, &len, sizeof(line));
+ _copy_line(str1, line, &len, sizeof(line)-1);
if ((p = strchr(line, '\n')))
*p = '\0';
log_print("%s", line);
}
if (str1 && (str2 = strstr(str1, "creation_time = "))) {
memset(line, 0, sizeof(line));
- _copy_line(str2, line, &len, sizeof(line));
+ _copy_line(str2, line, &len, sizeof(line)-1);
if ((p = strchr(line, '\n')))
*p = '\0';
log_print("%s\n", line);
@@ -2481,7 +2481,7 @@ static int _backup_file_to_raw_metadata(char *back_buf, uint64_t back_size,
memset(line, 0, sizeof(line));
len = 0;
- _copy_line(p, line, &len, sizeof(line));
+ _copy_line(p, line, &len, sizeof(line)-1);
p += len;
back_pos += len;
@@ -2507,7 +2507,7 @@ static int _backup_file_to_raw_metadata(char *back_buf, uint64_t back_size,
len = 0;
len2 = 0;
- _copy_line(p, line, &len, sizeof(line));
+ _copy_line(p, line, &len, sizeof(line)-1);
if (line[0] == '\0')
break;
4 years, 1 month
stable-2.02 - bcache: Fix memory leak in error path
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=deaf304ee6d88cd4763...
Commit: deaf304ee6d88cd47632a345b92b3949cd06d752
Parent: 44c460954be5c63cf5338bd9151344fe2626565f
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Wed Mar 4 13:22:10 2020 +0100
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Wed Mar 4 13:22:10 2020 +0100
bcache: Fix memory leak in error path
---
lib/device/bcache.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 77d1543c0..a74b6b315 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -515,6 +515,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
(unsigned long long)limit_nbytes,
(unsigned long long)extra_nbytes,
(unsigned long long)_last_byte_sector_size);
+ free(io);
return false;
}
}
4 years, 1 month
stable-2.02 - Fix rounding writes up to sector size
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=44c460954be5c63cf53...
Commit: 44c460954be5c63cf5338bd9151344fe2626565f
Parent: 253d10f840682f85dad0e4c29f55ff50f94792fa
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jul 24 11:32:13 2019 -0500
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Wed Mar 4 13:20:36 2020 +0100
Fix rounding writes up to sector size
Do this at two levels, although one would be enough to
fix the problem seen recently:
- Ignore any reported sector size other than 512 of 4096.
If either sector size (physical or logical) is reported
as 512, then use 512. If neither are reported as 512,
and one or the other is reported as 4096, then use 4096.
If neither is reported as either 512 or 4096, then use 512.
- When rounding up a limited write in bcache to be a multiple
of the sector size, check that the resulting write size is
not larger than the bcache block itself. (This shouldn't
happen if the sector size is 512 or 4096.)
(cherry picked from commit 7550665ba49ac7d497d5b212e14b69298ef01361)
Conflicts:
lib/device/dev-io.c
---
lib/device/bcache.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 87 insertions(+), 2 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index b64707ecc..77d1543c0 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -169,6 +169,7 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
sector_t offset;
sector_t nbytes;
sector_t limit_nbytes;
+ sector_t orig_nbytes;
sector_t extra_nbytes = 0;
if (((uintptr_t) data) & e->page_mask) {
@@ -191,11 +192,41 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
return false;
}
+ /*
+ * If the bcache block offset+len goes beyond where lvm is
+ * intending to write, then reduce the len being written
+ * (which is the bcache block size) so we don't write past
+ * the limit set by lvm. If after applying the limit, the
+ * resulting size is not a multiple of the sector size (512
+ * or 4096) then extend the reduced size to be a multiple of
+ * the sector size (we don't want to write partial sectors.)
+ */
if (offset + nbytes > _last_byte_offset) {
limit_nbytes = _last_byte_offset - offset;
- if (limit_nbytes % _last_byte_sector_size)
+
+ if (limit_nbytes % _last_byte_sector_size) {
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
+ /*
+ * adding extra_nbytes to the reduced nbytes (limit_nbytes)
+ * should make the final write size a multiple of the
+ * sector size. This should never result in a final size
+ * larger than the bcache block size (as long as the bcache
+ * block size is a multiple of the sector size).
+ */
+ if (limit_nbytes + extra_nbytes > nbytes) {
+ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes,
+ (unsigned long long)extra_nbytes,
+ (unsigned long long)_last_byte_sector_size);
+ extra_nbytes = 0;
+ }
+ }
+
+ orig_nbytes = nbytes;
+
if (extra_nbytes) {
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
(unsigned long long)offset,
@@ -210,6 +241,22 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
(unsigned long long)limit_nbytes);
nbytes = limit_nbytes;
}
+
+ /*
+ * This shouldn't happen, the reduced+extended
+ * nbytes value should never be larger than the
+ * bcache block size.
+ */
+ if (nbytes > orig_nbytes) {
+ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu",
+ (unsigned long long)offset,
+ (unsigned long long)orig_nbytes,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes,
+ (unsigned long long)extra_nbytes,
+ (unsigned long long)_last_byte_sector_size);
+ return false;
+ }
}
}
@@ -403,6 +450,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
uint64_t nbytes = len;
sector_t limit_nbytes = 0;
sector_t extra_nbytes = 0;
+ sector_t orig_nbytes = 0;
if (offset > _last_byte_offset) {
log_error("Limit write at %llu len %llu beyond last byte %llu",
@@ -415,9 +463,30 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
if (offset + nbytes > _last_byte_offset) {
limit_nbytes = _last_byte_offset - offset;
- if (limit_nbytes % _last_byte_sector_size)
+
+ if (limit_nbytes % _last_byte_sector_size) {
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
+ /*
+ * adding extra_nbytes to the reduced nbytes (limit_nbytes)
+ * should make the final write size a multiple of the
+ * sector size. This should never result in a final size
+ * larger than the bcache block size (as long as the bcache
+ * block size is a multiple of the sector size).
+ */
+ if (limit_nbytes + extra_nbytes > nbytes) {
+ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu",
+ (unsigned long long)offset,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes,
+ (unsigned long long)extra_nbytes,
+ (unsigned long long)_last_byte_sector_size);
+ extra_nbytes = 0;
+ }
+ }
+
+ orig_nbytes = nbytes;
+
if (extra_nbytes) {
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
(unsigned long long)offset,
@@ -432,6 +501,22 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
(unsigned long long)limit_nbytes);
nbytes = limit_nbytes;
}
+
+ /*
+ * This shouldn't happen, the reduced+extended
+ * nbytes value should never be larger than the
+ * bcache block size.
+ */
+ if (nbytes > orig_nbytes) {
+ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu",
+ (unsigned long long)offset,
+ (unsigned long long)orig_nbytes,
+ (unsigned long long)nbytes,
+ (unsigned long long)limit_nbytes,
+ (unsigned long long)extra_nbytes,
+ (unsigned long long)_last_byte_sector_size);
+ return false;
+ }
}
where = offset;
4 years, 1 month
master - hints: free hint list in error exit path
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f50e7ce76c0c6b2745d...
Commit: f50e7ce76c0c6b2745d0ed2a766f46cea07f310c
Parent: c392ccaa470dbf1481cbf1c9e899ce9c59f2caea
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Mar 3 12:25:34 2020 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Mar 3 12:25:34 2020 -0600
hints: free hint list in error exit path
---
lib/label/hints.c | 14 +++++++++++++-
lib/label/hints.h | 2 ++
lib/label/label.c | 12 +-----------
3 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/lib/label/hints.c b/lib/label/hints.c
index f1a1519..48fb661 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -356,6 +356,16 @@ void hints_exit(struct cmd_context *cmd)
return _unlock_hints(cmd);
}
+void free_hints(struct dm_list *hints)
+{
+ struct hint *hint, *hint2;
+
+ dm_list_iterate_items_safe(hint, hint2, hints) {
+ dm_list_del(&hint->list);
+ free(hint);
+ }
+}
+
static struct hint *_find_hint_name(struct dm_list *hints, const char *name)
{
struct hint *hint;
@@ -787,8 +797,10 @@ static int _read_hint_file(struct cmd_context *cmd, struct dm_list *hints, int *
if (fclose(fp))
stack;
- if (!ret)
+ if (!ret) {
+ free_hints(hints);
return 0;
+ }
if (!found)
return 1;
diff --git a/lib/label/hints.h b/lib/label/hints.h
index 7f47648..5114334 100644
--- a/lib/label/hints.h
+++ b/lib/label/hints.h
@@ -24,6 +24,8 @@ struct hint {
unsigned chosen:1; /* this hint's dev was chosen for scanning */
};
+void free_hints(struct dm_list *hints);
+
int write_hint_file(struct cmd_context *cmd, int newhints);
void clear_hint_file(struct cmd_context *cmd);
diff --git a/lib/label/label.c b/lib/label/label.c
index 328e4e7..0458313 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -857,16 +857,6 @@ static int _setup_bcache(void)
return 1;
}
-static void _free_hints(struct dm_list *hints)
-{
- struct hint *hint, *hint2;
-
- dm_list_iterate_items_safe(hint, hint2, hints) {
- dm_list_del(&hint->list);
- free(hint);
- }
-}
-
/*
* We don't know how many of num_devs will be PVs that we need to
* keep open, but if it's greater than the soft limit, then we'll
@@ -1165,7 +1155,7 @@ int label_scan(struct cmd_context *cmd)
if (!validate_hints(cmd, &hints_list)) {
log_debug("Will scan %d remaining devices", dm_list_size(&all_devs));
_scan_list(cmd, cmd->filter, &all_devs, NULL);
- _free_hints(&hints_list);
+ free_hints(&hints_list);
using_hints = 0;
create_hints = 0;
} else {
4 years, 1 month