From cff08d2c72a5eb5010dfe611ad586874bcbfeae4 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Wed, 24 Sep 2025 02:32:54 +0300 Subject: [PATCH] Fix snapshotted bitmap reads not working in EC pools (fix #92) --- .gitea/workflows/test.yml | 54 ++++++++++++++++++++---------- src/osd/osd_primary_chain.cpp | 18 ++++++++-- tests/run_tests.sh | 4 +-- tests/test_snapshot_read_bitmap.sh | 39 +++++++++++++++++++++ 4 files changed, 92 insertions(+), 23 deletions(-) create mode 100755 tests/test_snapshot_read_bitmap.sh diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index b186179b..25c3d904 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -828,6 +828,42 @@ jobs: echo "" done + test_snapshot_pool2: + 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_snapshot_pool2.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_snapshot_read_bitmap: + 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_snapshot_read_bitmap.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_heal_csum_32k_dmj: runs-on: ubuntu-latest needs: build @@ -972,24 +1008,6 @@ jobs: echo "" done - test_snapshot_pool2: - 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_snapshot_pool2.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_osd_tags: runs-on: ubuntu-latest needs: build diff --git a/src/osd/osd_primary_chain.cpp b/src/osd/osd_primary_chain.cpp index 60acbb16..2d21b61e 100644 --- a/src/osd/osd_primary_chain.cpp +++ b/src/osd/osd_primary_chain.cpp @@ -17,10 +17,22 @@ void osd_t::continue_chained_read(osd_op_t *cur_op) else if (op_data->st == 4) goto resume_4; cur_op->reply.rw.bitmap_len = 0; - for (int role = 0; role < (pg ? pg->pg_data_size : 1); role++) + if (cur_op->req.rw.len == 0) { - op_data->stripes[role].read_start = op_data->stripes[role].req_start; - op_data->stripes[role].read_end = op_data->stripes[role].req_end; + // len=0 => bitmap read + for (int role = 0; role < (pg ? pg->pg_data_size : 1); role++) + { + op_data->stripes[role].read_start = 0; + op_data->stripes[role].read_end = UINT32_MAX; + } + } + else + { + for (int role = 0; role < (pg ? pg->pg_data_size : 1); role++) + { + op_data->stripes[role].read_start = op_data->stripes[role].req_start; + op_data->stripes[role].read_end = op_data->stripes[role].req_end; + } } resume_1: resume_2: diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 25221680..5c762bca 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -71,6 +71,8 @@ SCHEME=ec ./test_heal.sh ANTIETCD=1 ./test_heal.sh ./test_reweight_half.sh +./test_snapshot_pool2.sh +./test_snapshot_read_bitmap.sh TEST_NAME=csum_32k_dmj OSD_ARGS="--data_csum_type crc32c --csum_block_size 32k --inmemory_metadata false --inmemory_journal false" OFFSET_ARGS=$OSD_ARGS ./test_heal.sh TEST_NAME=csum_32k_dj OSD_ARGS="--data_csum_type crc32c --csum_block_size 32k --inmemory_journal false" OFFSET_ARGS=$OSD_ARGS ./test_heal.sh @@ -82,8 +84,6 @@ TEST_NAME=csum_4k OSD_ARGS="--data_csum_type crc32c" OFFSET_ARGS=$OSD_ARGS ./test_resize.sh ./test_resize_auto.sh -./test_snapshot_pool2.sh - ./test_osd_tags.sh ./test_enospc.sh diff --git a/tests/test_snapshot_read_bitmap.sh b/tests/test_snapshot_read_bitmap.sh new file mode 100755 index 00000000..863ade5e --- /dev/null +++ b/tests/test_snapshot_read_bitmap.sh @@ -0,0 +1,39 @@ +#!/bin/bash -ex + +SCHEME=${SCHEME:-ec} +. `dirname $0`/run_3osds.sh +check_qemu + +build/src/cmd/vitastor-cli --etcd_address $ETCD_URL create -s 128M testchain + +dd if=/dev/zero of=./testdata/bin/mirror.bin bs=4k seek=$(((128*1024-4)/4)) count=1 + +LD_PRELOAD="build/src/client/libfio_vitastor.so" \ + fio -thread -name=test -ioengine=build/src/client/libfio_vitastor.so -bs=32k -direct=1 -iodepth=4 -end_fsync=1 -rw=randwrite \ + -etcd=$ETCD_URL -image=testchain -mirror_file=./testdata/bin/mirror.bin -buffer_pattern=0xabcd -number_ios=1024 + +build/src/cmd/vitastor-cli --etcd_address $ETCD_URL snap-create testchain@snap1 + +LD_PRELOAD="build/src/client/libfio_vitastor.so" \ + fio -thread -name=test -ioengine=build/src/client/libfio_vitastor.so -bs=4k -direct=1 -iodepth=4 -end_fsync=1 -rw=randwrite -number_ios=32 \ + -etcd=$ETCD_URL -image=testchain -mirror_file=./testdata/bin/mirror.bin -buffer_pattern=0xabcd + +# Now read from the snapshot + +dd if=/dev/zero of=./testdata/bin/res.bin bs=4k seek=$(((128*1024-4)/4)) count=1 + +build/src/cmd/vitastor-cli --etcd_address $ETCD_URL dd iimg=testchain of=./testdata/bin/res.bin bs=$((PG_DATA_SIZE*128))k iodepth=4 --log_level 10 + +cmp ./testdata/bin/res.bin ./testdata/bin/mirror.bin + +build/src/cmd/vitastor-cli --etcd_address $ETCD_URL dd iimg=testchain of=./testdata/bin/res.bin bs=$((PG_DATA_SIZE*128))k iodepth=4 conv=nosparse + +cmp ./testdata/bin/res.bin ./testdata/bin/mirror.bin + +qemu-img convert -p \ + -f raw "vitastor:etcd_host=127.0.0.1\:$ETCD_PORT/v3:image=testchain" \ + -O raw ./testdata/bin/res.bin + +cmp ./testdata/bin/res.bin ./testdata/bin/mirror.bin + +format_green OK