Add a dump|load test, fix multiple bugs in both new&old dump/load utils
Details: - New store dump/write-meta didn't use actual metadata parameters from the header - New store write-meta calculated small entry sizes incorrectly - Old store write-journal imported entries with checksums incorrectly - Old store write-meta didn't import block_csums at all (it was using a wrong json key)
This commit is contained in:
@@ -306,6 +306,78 @@ jobs:
|
||||
echo ""
|
||||
done
|
||||
|
||||
test_dump_load:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||
steps:
|
||||
- name: Run test
|
||||
id: test
|
||||
timeout-minutes: 3
|
||||
run: /root/vitastor/tests/test_dump_load.sh
|
||||
- name: Print logs
|
||||
if: always() && steps.test.outcome == 'failure'
|
||||
run: |
|
||||
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||
echo "-------- $i --------"
|
||||
cat $i
|
||||
echo ""
|
||||
done
|
||||
|
||||
test_dump_load_32k:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||
steps:
|
||||
- name: Run test
|
||||
id: test
|
||||
timeout-minutes: 3
|
||||
run: TEST_NAME=32k OSD_ARGS="--data_csum_type crc32c --csum_block_size 32k" OFFSET_ARGS="$OSD_ARGS" /root/vitastor/tests/test_dump_load.sh
|
||||
- name: Print logs
|
||||
if: always() && steps.test.outcome == 'failure'
|
||||
run: |
|
||||
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||
echo "-------- $i --------"
|
||||
cat $i
|
||||
echo ""
|
||||
done
|
||||
|
||||
test_old_dump_load:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||
steps:
|
||||
- name: Run test
|
||||
id: test
|
||||
timeout-minutes: 3
|
||||
run: OLD=1 /root/vitastor/tests/test_dump_load.sh
|
||||
- name: Print logs
|
||||
if: always() && steps.test.outcome == 'failure'
|
||||
run: |
|
||||
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||
echo "-------- $i --------"
|
||||
cat $i
|
||||
echo ""
|
||||
done
|
||||
|
||||
test_dump_load_old_32k:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||
steps:
|
||||
- name: Run test
|
||||
id: test
|
||||
timeout-minutes: 3
|
||||
run: TEST_NAME=old_32k OLD=1 OSD_ARGS="--data_csum_type crc32c --csum_block_size 32k" OFFSET_ARGS="$OSD_ARGS" /root/vitastor/tests/test_dump_load.sh
|
||||
- name: Print logs
|
||||
if: always() && steps.test.outcome == 'failure'
|
||||
run: |
|
||||
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||
echo "-------- $i --------"
|
||||
cat $i
|
||||
echo ""
|
||||
done
|
||||
|
||||
test_old_interrupted_rebalance:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
@@ -477,11 +477,15 @@ int disk_tool_t::write_json_journal(json11::Json entries)
|
||||
uint16_t type = t_it->second;
|
||||
if (type == JE_START)
|
||||
continue;
|
||||
uint32_t offset = (uint32_t)rec["offset"].uint64_value();
|
||||
uint32_t len = (uint32_t)rec["len"].uint64_value();
|
||||
uint32_t data_csum_blocks = !dsk.data_csum_type || !len ? 0 :
|
||||
(((offset + len - 1)/dsk.csum_block_size - offset/dsk.csum_block_size + 1));
|
||||
uint32_t data_csum_size = data_csum_blocks*(dsk.data_csum_type & 0xFF);
|
||||
uint32_t entry_size = (type == JE_START
|
||||
? sizeof(journal_entry_start)
|
||||
: (type == JE_SMALL_WRITE || type == JE_SMALL_WRITE_INSTANT
|
||||
? sizeof(journal_entry_small_write) + dsk.clean_entry_bitmap_size +
|
||||
(dsk.data_csum_type ? rec["len"].uint64_value()/dsk.csum_block_size*(dsk.data_csum_type & 0xFF) : 0)
|
||||
? sizeof(journal_entry_small_write) + dsk.clean_entry_bitmap_size + data_csum_size
|
||||
: (type == JE_BIG_WRITE || type == JE_BIG_WRITE_INSTANT
|
||||
? sizeof(journal_entry_big_write) + dsk.clean_entry_bitmap_size +
|
||||
(dsk.data_csum_type ? rec["len"].uint64_value()/dsk.csum_block_size*(dsk.data_csum_type & 0xFF) : 0)
|
||||
@@ -523,15 +527,12 @@ int disk_tool_t::write_json_journal(json11::Json entries)
|
||||
.stripe = sscanf_json(NULL, rec["stripe"]),
|
||||
},
|
||||
.version = rec["ver"].uint64_value(),
|
||||
.offset = (uint32_t)rec["offset"].uint64_value(),
|
||||
.len = (uint32_t)rec["len"].uint64_value(),
|
||||
.offset = offset,
|
||||
.len = len,
|
||||
.data_offset = (uint64_t)(new_journal_data-new_journal_buf),
|
||||
.crc32_data = !dsk.data_csum_type ? 0 : (uint32_t)sscanf_json("%x", rec["data_crc32"]),
|
||||
};
|
||||
uint32_t data_csum_blocks = !dsk.data_csum_type ? 0 :
|
||||
(((ne->small_write.offset+ne->small_write.len)/dsk.csum_block_size - ne->small_write.len/dsk.csum_block_size));
|
||||
uint32_t data_csum_size = data_csum_blocks*(dsk.data_csum_type & 0xFF);
|
||||
fromhexstr(rec["bitmap"].string_value(), dsk.clean_entry_bitmap_size, ((uint8_t*)ne) + sizeof(journal_entry_small_write) + data_csum_size);
|
||||
fromhexstr(rec["bitmap"].string_value(), dsk.clean_entry_bitmap_size, ((uint8_t*)ne) + sizeof(journal_entry_small_write));
|
||||
fromhexstr(rec["data"].string_value(), ne->small_write.len, new_journal_data);
|
||||
if (ne->small_write.len > 0 && !rec["data"].is_string())
|
||||
{
|
||||
@@ -545,7 +546,7 @@ int disk_tool_t::write_json_journal(json11::Json entries)
|
||||
ne->small_write.crc32_data = crc32c(0, new_journal_data, ne->small_write.len);
|
||||
else if (dsk.data_csum_type == BLOCKSTORE_CSUM_CRC32C)
|
||||
{
|
||||
uint32_t *block_csums = (uint32_t*)(((uint8_t*)ne) + sizeof(journal_entry_small_write));
|
||||
uint32_t *block_csums = (uint32_t*)(((uint8_t*)ne) + sizeof(journal_entry_small_write) + dsk.clean_entry_bitmap_size);
|
||||
for (uint32_t i = 0; i < data_csum_blocks; i++)
|
||||
{
|
||||
uint32_t block_begin = (ne->small_write.offset/dsk.csum_block_size + i) * dsk.csum_block_size;
|
||||
@@ -574,12 +575,9 @@ int disk_tool_t::write_json_journal(json11::Json entries)
|
||||
.len = (uint32_t)rec["len"].uint64_value(),
|
||||
.location = sscanf_json(NULL, rec["loc"]),
|
||||
};
|
||||
uint32_t data_csum_blocks = !dsk.data_csum_type ? 0 :
|
||||
(((ne->small_write.offset+ne->small_write.len)/dsk.csum_block_size - ne->small_write.len/dsk.csum_block_size));
|
||||
uint32_t data_csum_size = data_csum_blocks*(dsk.data_csum_type & 0xFF);
|
||||
fromhexstr(rec["bitmap"].string_value(), dsk.clean_entry_bitmap_size, ((uint8_t*)ne) + sizeof(journal_entry_big_write) + data_csum_size);
|
||||
fromhexstr(rec["bitmap"].string_value(), dsk.clean_entry_bitmap_size, ((uint8_t*)ne) + sizeof(journal_entry_big_write));
|
||||
if (dsk.data_csum_type)
|
||||
fromhexstr(rec["block_csums"].string_value(), data_csum_size, ((uint8_t*)ne) + sizeof(journal_entry_big_write));
|
||||
fromhexstr(rec["block_csums"].string_value(), data_csum_size, ((uint8_t*)ne) + sizeof(journal_entry_big_write) + dsk.clean_entry_bitmap_size);
|
||||
}
|
||||
else if (type == JE_STABLE || type == JE_ROLLBACK || type == JE_DELETE)
|
||||
{
|
||||
|
||||
@@ -95,6 +95,12 @@ close_error:
|
||||
journal_pos += read_len;
|
||||
}
|
||||
}
|
||||
dsk.meta_format = hdr->version;
|
||||
dsk.data_block_size = hdr->data_block_size;
|
||||
dsk.csum_block_size = hdr->csum_block_size;
|
||||
dsk.data_csum_type = hdr->data_csum_type;
|
||||
dsk.bitmap_granularity = hdr->bitmap_granularity;
|
||||
dsk.clean_entry_bitmap_size = (hdr->data_block_size / hdr->bitmap_granularity + 7) / 8;
|
||||
blockstore_heap_t *heap = new blockstore_heap_t(&dsk, buffer_area, log_level);
|
||||
// Load heap and just iterate it in memory
|
||||
hdr_fn(hdr);
|
||||
@@ -575,7 +581,7 @@ int disk_tool_t::write_json_meta(json11::Json meta)
|
||||
{
|
||||
if (new_data_csum_size)
|
||||
{
|
||||
fromhexstr(e["data_csum"].string_value(), new_data_csum_size,
|
||||
fromhexstr(e["block_csums"].string_value(), new_data_csum_size,
|
||||
((uint8_t*)new_entry) + sizeof(clean_disk_entry) + 2*new_clean_entry_bitmap_size);
|
||||
}
|
||||
uint32_t *new_entry_csum = (uint32_t*)(((uint8_t*)new_entry) + new_clean_entry_size - 4);
|
||||
@@ -616,6 +622,12 @@ int disk_tool_t::write_json_heap(json11::Json meta, json11::Json journal)
|
||||
new_data_csum_size = (new_meta_hdr->csum_block_size
|
||||
? ((new_meta_hdr->data_block_size+new_meta_hdr->csum_block_size-1)/new_meta_hdr->csum_block_size*(new_meta_hdr->data_csum_type & 0xFF))
|
||||
: 0);
|
||||
dsk.meta_format = new_meta_hdr->version;
|
||||
dsk.data_block_size = new_meta_hdr->data_block_size;
|
||||
dsk.csum_block_size = new_meta_hdr->csum_block_size;
|
||||
dsk.data_csum_type = new_meta_hdr->data_csum_type;
|
||||
dsk.bitmap_granularity = new_meta_hdr->bitmap_granularity;
|
||||
dsk.clean_entry_bitmap_size = (new_meta_hdr->data_block_size / new_meta_hdr->bitmap_granularity + 7) / 8;
|
||||
new_journal_buf = NULL;
|
||||
if (new_journal_len)
|
||||
{
|
||||
@@ -696,7 +708,7 @@ close_err0:
|
||||
wr->entry_type = wr_type | (write_entry["stable"].bool_value() ? BS_HEAP_STABLE : 0);
|
||||
wr->lsn = write_entry["lsn"].uint64_value();
|
||||
wr->version = write_entry["version"].uint64_value();
|
||||
wr->size = wr->get_size(&heap);
|
||||
wr->size = wr_size;
|
||||
if (wr_type == BS_HEAP_SMALL_WRITE || wr_type == BS_HEAP_INTENT_WRITE)
|
||||
{
|
||||
wr->small().offset = wr_offset;
|
||||
@@ -736,6 +748,7 @@ close_err0:
|
||||
bi.offset = wr_offset;
|
||||
bi.len = wr_len;
|
||||
}
|
||||
wr->size = wr->get_size(&heap);
|
||||
if (write_entry["bitmap"].is_string() && wr->get_int_bitmap(&heap))
|
||||
{
|
||||
fromhexstr(write_entry["bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_int_bitmap(&heap));
|
||||
@@ -794,7 +807,7 @@ close_err:
|
||||
fromhexstr(meta_entry["bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_int_bitmap(&heap));
|
||||
fromhexstr(meta_entry["ext_bitmap"].string_value(), new_clean_entry_bitmap_size, wr->get_ext_bitmap(&heap));
|
||||
if (new_data_csum_size)
|
||||
fromhexstr(meta_entry["data_csum"].string_value(), new_data_csum_size, wr->get_checksums(&heap));
|
||||
fromhexstr(meta_entry["block_csums"].string_value(), new_data_csum_size, wr->get_checksums(&heap));
|
||||
wr->crc32c = wr->calc_crc32c();
|
||||
assert((uint8_t*)wr + wr->size == new_meta_buf + meta_offset + used_space);
|
||||
auto j_it = journal_by_object.find(oid);
|
||||
|
||||
@@ -24,6 +24,11 @@ IMMEDIATE_COMMIT=1 ./test_interrupted_rebalance.sh
|
||||
SCHEME=ec ./test_interrupted_rebalance.sh
|
||||
SCHEME=ec IMMEDIATE_COMMIT=1 ./test_interrupted_rebalance.sh
|
||||
|
||||
./test_dump_load.sh
|
||||
TEST_NAME=32k OSD_ARGS="--data_csum_type crc32c --csum_block_size 32k" OFFSET_ARGS="$OSD_ARGS" ./test_dump_load.sh
|
||||
OLD=1 ./test_dump_load.sh
|
||||
TEST_NAME=old_32k OLD=1 OSD_ARGS="--data_csum_type crc32c --csum_block_size 32k" OFFSET_ARGS="$OSD_ARGS" ./test_dump_load.sh
|
||||
|
||||
OLD=1 ./test_interrupted_rebalance.sh
|
||||
OLD=1 IMMEDIATE_COMMIT=1 ./test_interrupted_rebalance.sh
|
||||
OLD=1 SCHEME=ec ./test_interrupted_rebalance.sh
|
||||
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
PG_COUNT=${PG_COUNT:-32}
|
||||
|
||||
. `dirname $0`/run_3osds.sh
|
||||
|
||||
$VITASTOR_FIO -bs=4M -direct=1 -iodepth=4 \
|
||||
-rw=write -end_fsync=1 -pool=1 -inode=1 -size=256M -runtime=10
|
||||
|
||||
$VITASTOR_FIO -bs=4k -direct=1 -iodepth=32 \
|
||||
-rw=randwrite -end_fsync=1 -pool=1 -inode=1 -size=256M -runtime=10 -number_ios=1024
|
||||
|
||||
for i in $(seq 1 $OSD_COUNT); do
|
||||
pid=OSD${i}_PID
|
||||
pid=${!pid}
|
||||
kill -9 $pid
|
||||
done
|
||||
|
||||
offsets=$(build/src/disk_tool/vitastor-disk simple-offsets --format json ./testdata/bin/test_osd1.bin $OFFSET_ARGS)
|
||||
opts=$(build/src/disk_tool/vitastor-disk simple-offsets --format options ./testdata/bin/test_osd1.bin $OFFSET_ARGS)
|
||||
meta_format=$(echo $offsets | jq -r .meta_format)
|
||||
journal_offset=$(echo $offsets | jq -r .journal_offset)
|
||||
meta_offset=$(echo $offsets | jq -r .meta_offset)
|
||||
data_offset=$(echo $offsets | jq -r .data_offset)
|
||||
if [[ "$meta_format" = "3" ]]; then
|
||||
build/src/disk_tool/vitastor-disk dump-meta --io cached $opts | jq '. + { "entries": .entries | sort_by(.stripe) }' >./testdata/meta.json
|
||||
build/src/disk_tool/vitastor-disk write-meta --io cached $opts <./testdata/meta.json
|
||||
build/src/disk_tool/vitastor-disk dump-meta --io cached $opts | jq '. + { "entries": .entries | sort_by(.stripe) }' >./testdata/meta2.json
|
||||
else
|
||||
build/src/disk_tool/vitastor-disk dump-journal --io cached --json ./testdata/bin/test_osd1.bin 4096 $journal_offset $((meta_offset-journal_offset)) | jq 'map(del(.crc32, .crc32_prev)) | map(if .type == "small_write" or .type == "small_write_instant" then del(.loc) elif .type == "start" then del(.start) else . end)' >./testdata/journal.json
|
||||
build/src/disk_tool/vitastor-disk write-journal --io cached --json ./testdata/bin/test_osd1.bin 4096 4 $journal_offset $((meta_offset-journal_offset)) <./testdata/journal.json
|
||||
build/src/disk_tool/vitastor-disk dump-journal --io cached --json ./testdata/bin/test_osd1.bin 4096 $journal_offset $((meta_offset-journal_offset)) | jq 'map(del(.crc32, .crc32_prev)) | map(if .type == "small_write" or .type == "small_write_instant" then del(.loc) elif .type == "start" then del(.start) else . end)' >./testdata/journal2.json
|
||||
diff ./testdata/journal.json ./testdata/journal2.json
|
||||
build/src/disk_tool/vitastor-disk dump-meta --io cached ./testdata/bin/test_osd1.bin 4096 $meta_offset $((data_offset-meta_offset)) >./testdata/meta.json
|
||||
build/src/disk_tool/vitastor-disk write-meta --io cached $opts <./testdata/meta.json
|
||||
build/src/disk_tool/vitastor-disk dump-meta --io cached ./testdata/bin/test_osd1.bin 4096 $meta_offset $((data_offset-meta_offset)) >./testdata/meta2.json
|
||||
fi
|
||||
diff ./testdata/meta.json ./testdata/meta2.json
|
||||
|
||||
format_green OK
|
||||
Reference in New Issue
Block a user