From ae0e62573c16087d79f56a8e3299ebb91543ecf9 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 11 Nov 2025 15:52:53 -0500 Subject: [PATCH 01/37] mpathpersist: Fix REPORT CAPABILITIES output mpathpersist was incorrectly parsing the REPORT CAPABILITES service action output. In reality, the type mask is two bytes where the type information is stored in bits 7, 6, 5, 3, & 1 (0xea) of the first byte and bit 0 (0x01) of the second byte. libmpathpersist was treating these two bytes as a big endian 16 bit number, but mpathpersist was looking for bits in that number as if it was little endian number. Ideally, libmpathpersist would treat prin_capdescr.pr_type_mask as two bytes, like it does for the flags. But we already expose this as a 16 bit number, where we treated the input bytes as a big endian number. There's no great reason to mess with the libmpathpersist API, when we can just make mpathpersist treat this data like libmpathpersist provides it. So, fix mpathpersist to print the data out correctly. Additionally, instead of printing a 1 or a 0 to indicate if a type was supported or not, it was printing the value of the type flag. Also, Persist Through Power Loss Capable (PTPL_C) was being reported if any bit in flags[0] was set. Fix these as well. Reformat all of the capability printing lines, since it is less confusing than only reformatting some of them. Fixes: ae4e8a6 ("mpathpersist: Add new utility for managing persistent reservation on dm multipath device") Signed-off-by: Benjamin Marzinski Reviewed-by: Martin Wilck (cherry picked from commit c8ed5e6eea98244745904adaaa4aef83a8722fb0) --- libmpathpersist/mpath_persist.h | 4 ++- mpathpersist/main.c | 43 +++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h index 32aa7ffec..fff816677 100644 --- a/libmpathpersist/mpath_persist.h +++ b/libmpathpersist/mpath_persist.h @@ -110,7 +110,9 @@ struct prin_capdescr { uint16_t length; uint8_t flags[2]; - uint16_t pr_type_mask; + uint16_t pr_type_mask; /* The two bytes of the type mask are treated + as a single big-endian number. So the valid + type bits are 0xea01 */ uint16_t _reserved; }; diff --git a/mpathpersist/main.c b/mpathpersist/main.c index efb46b95e..62cba5dcc 100644 --- a/mpathpersist/main.c +++ b/mpathpersist/main.c @@ -750,25 +750,42 @@ void mpath_print_buf_readcap( struct prin_resp *pr_buff) printf("Report capabilities response:\n"); - printf(" Compatible Reservation Handling(CRH): %d\n", !!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x10)); - printf(" Specify Initiator Ports Capable(SIP_C): %d\n",!!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x8)); - printf(" All Target Ports Capable(ATP_C): %d\n",!!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x4 )); - printf(" Persist Through Power Loss Capable(PTPL_C): %d\n",!!(pr_buff->prin_descriptor.prin_readcap.flags[0])); - printf(" Type Mask Valid(TMV): %d\n", !!(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x80)); - printf(" Allow Commands: %d\n", !!(( pr_buff->prin_descriptor.prin_readcap.flags[1] >> 4) & 0x7)); + printf(" Compatible Reservation Handling(CRH): %d\n", + !!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x10)); + printf(" Specify Initiator Ports Capable(SIP_C): %d\n", + !!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x8)); + printf(" All Target Ports Capable(ATP_C): %d\n", + !!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x4)); + printf(" Persist Through Power Loss Capable(PTPL_C): %d\n", + !!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x1)); + printf(" Type Mask Valid(TMV): %d\n", + !!(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x80)); + printf(" Allow Commands: %d\n", + !!((pr_buff->prin_descriptor.prin_readcap.flags[1] >> 4) & 0x7)); printf(" Persist Through Power Loss Active(PTPL_A): %d\n", - !!(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x1)); + !!(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x1)); if(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x80) { printf(" Support indicated in Type mask:\n"); - printf(" %s: %d\n", pr_type_strs[7], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x80); - printf(" %s: %d\n", pr_type_strs[6], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x40); - printf(" %s: %d\n", pr_type_strs[5], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x20); - printf(" %s: %d\n", pr_type_strs[3], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x8); - printf(" %s: %d\n", pr_type_strs[1], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x2); - printf(" %s: %d\n", pr_type_strs[8], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x100); + printf(" %s: %d\n", pr_type_strs[7], + !!(pr_buff->prin_descriptor.prin_readcap.pr_type_mask & + 0x8000)); + printf(" %s: %d\n", pr_type_strs[6], + !!(pr_buff->prin_descriptor.prin_readcap.pr_type_mask & + 0x4000)); + printf(" %s: %d\n", pr_type_strs[5], + !!(pr_buff->prin_descriptor.prin_readcap.pr_type_mask & + 0x2000)); + printf(" %s: %d\n", pr_type_strs[3], + !!(pr_buff->prin_descriptor.prin_readcap.pr_type_mask & + 0x800)); + printf(" %s: %d\n", pr_type_strs[1], + !!(pr_buff->prin_descriptor.prin_readcap.pr_type_mask & + 0x200)); + printf(" %s: %d\n", pr_type_strs[8], + !!(pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x1)); } } From 9359e8580585e8a8c4614b4562956ad8469cba57 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 14 Nov 2025 12:12:46 +0100 Subject: [PATCH 02/37] GitHub workflows: Update runners to ubuntu-24.04 Signed-off-by: Martin Wilck (cherry picked from commit 541e36e5e5f9394e9aa4a5af3d70ffbaaff8eeff) --- .github/workflows/abi-stable.yaml | 4 ++-- .github/workflows/abi.yaml | 3 ++- .github/workflows/build-and-unittest.yaml | 2 +- .github/workflows/coverity.yaml | 2 +- .github/workflows/foreign.yaml | 6 +++--- .github/workflows/multiarch-stable.yaml | 2 +- .github/workflows/multiarch.yaml | 2 +- .github/workflows/native.yaml | 6 +++--- .github/workflows/rolling.yaml | 2 +- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml index 238a06bf3..8b2c83a85 100644 --- a/.github/workflows/abi-stable.yaml +++ b/.github/workflows/abi-stable.yaml @@ -15,7 +15,7 @@ on: jobs: reference-abi: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: get parent tag (push) run: > @@ -51,7 +51,7 @@ jobs: path: abi check-abi: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: reference-abi steps: - name: get parent tag (push) diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml index b1282493f..70ceb89df 100644 --- a/.github/workflows/abi.yaml +++ b/.github/workflows/abi.yaml @@ -18,7 +18,7 @@ env: jobs: save-and-test-ABI: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: set ABI branch if: ${{ env.ABI_BRANCH == '' }} @@ -42,6 +42,7 @@ jobs: gcc make pkg-config abigail-tools libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + libmount-dev - name: create ABI run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - name: save ABI diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml index 4f568131c..a3ee7d8e7 100644 --- a/.github/workflows/build-and-unittest.yaml +++ b/.github/workflows/build-and-unittest.yaml @@ -13,7 +13,7 @@ on: - 'stable-*' jobs: jammy: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml index 678d0d2a3..3ade6771b 100644 --- a/.github/workflows/coverity.yaml +++ b/.github/workflows/coverity.yaml @@ -6,7 +6,7 @@ on: jobs: upload-coverity-scan: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: checkout uses: actions/checkout@v4 diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml index a25179710..47affb7ac 100644 --- a/.github/workflows/foreign.yaml +++ b/.github/workflows/foreign.yaml @@ -27,7 +27,7 @@ on: jobs: cross-build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -52,7 +52,7 @@ jobs: overwrite: true test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: cross-build strategy: fail-fast: false @@ -94,7 +94,7 @@ jobs: pull-params: "--platform linux/${{ env.CONTAINER_ARCH }}" root-test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: cross-build strategy: fail-fast: false diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml index 2a30a8605..4c4bf95c0 100644 --- a/.github/workflows/multiarch-stable.yaml +++ b/.github/workflows/multiarch-stable.yaml @@ -26,7 +26,7 @@ on: jobs: build-old: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml index c453446a6..c94f19ee6 100644 --- a/.github/workflows/multiarch.yaml +++ b/.github/workflows/multiarch.yaml @@ -30,7 +30,7 @@ on: jobs: build-current: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 6b38fa712..7b7e8c64a 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -26,7 +26,7 @@ on: jobs: stable: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -85,7 +85,7 @@ jobs: overwrite: true clang: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -117,7 +117,7 @@ jobs: command: -j -Orecurse READLINE=libreadline test root-test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: stable strategy: fail-fast: false diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml index 503625e04..b5ff4f516 100644 --- a/.github/workflows/rolling.yaml +++ b/.github/workflows/rolling.yaml @@ -29,7 +29,7 @@ on: jobs: rolling: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: From 6c7d25ce950f083cbc013534d1a3858e51ab164e Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 14 Nov 2025 13:02:50 +0100 Subject: [PATCH 03/37] GitHub workflows: native.yaml: add fedora-43 Signed-off-by: Martin Wilck (cherry picked from commit 1dbc6ff522fdb188d750abb97b7fc714ded54c95) --- .github/workflows/native.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 7b7e8c64a..dbe701f0f 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -36,7 +36,7 @@ jobs: - debian-bullseye - debian-bookworm - debian-trixie - - fedora-42 + - fedora-43 - opensuse-leap steps: - name: checkout @@ -95,7 +95,7 @@ jobs: - debian-bullseye - debian-bookworm - debian-trixie - - fedora-42 + - fedora-43 - opensuse-leap steps: - name: checkout @@ -128,7 +128,7 @@ jobs: - debian-bullseye - debian-bookworm - debian-trixie - - fedora-42 + - fedora-43 - opensuse-leap steps: - name: mpath From f50d96bc0110c19b81549ebaa361544a84691ccd Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 14 Nov 2025 13:03:15 +0100 Subject: [PATCH 04/37] GitHub workflows: native.yaml: add openSUSE Leap 16.0 and 15.6 "opensuse-leap" would use 15.6 already, but make this explicit. Signed-off-by: Martin Wilck (cherry picked from commit 6e09ca12218621589e2dfe7c59ef62d55bc4279d) --- .github/workflows/native.yaml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index dbe701f0f..f6ee8699f 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -37,7 +37,8 @@ jobs: - debian-bookworm - debian-trixie - fedora-43 - - opensuse-leap + - opensuse-leap-15.6 + - opensuse-leap-16.0 steps: - name: checkout uses: actions/checkout@v4 @@ -45,10 +46,10 @@ jobs: - name: set archive name # Leap containers have cpio but not tar run: echo ARCHIVE_TGT=test-progs.cpio >> $GITHUB_ENV - if: ${{ matrix.os == 'opensuse-leap' }} + if: ${{ startswith(matrix.os, 'opensuse-leap-15') }} - name: set archive name run: echo ARCHIVE_TGT=test-progs.tar >> $GITHUB_ENV - if: ${{ matrix.os != 'opensuse-leap' }} + if: ${{ !startswith(matrix.os, 'opensuse-leap-15') }} - name: build and test if: ${{ matrix.os != 'debian-jessie' }} @@ -96,7 +97,8 @@ jobs: - debian-bookworm - debian-trixie - fedora-43 - - opensuse-leap + - opensuse-leap-15.6 + - opensuse-leap-16.0 steps: - name: checkout uses: actions/checkout@v4 @@ -129,7 +131,8 @@ jobs: - debian-bookworm - debian-trixie - fedora-43 - - opensuse-leap + - opensuse-leap-15.6 + - opensuse-leap-16.0 steps: - name: mpath run: sudo modprobe dm_multipath @@ -145,10 +148,10 @@ jobs: name: native-${{ matrix.os }} - name: unpack binary archive run: cpio -idv < test-progs.cpio - if: ${{ matrix.os == 'opensuse-leap' }} + if: ${{ startswith(matrix.os, 'opensuse-leap-15') }} - name: unpack binary archive run: tar xfmv test-progs.tar - if: ${{ matrix.os != 'opensuse-leap' }} + if: ${{ !startswith(matrix.os, 'opensuse-leap-15') }} - name: run root tests uses: mosteo-actions/docker-run@v1 From 047b27fdf7c2de910cc932fae6c72a3f0fa9b1f9 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 14 Nov 2025 14:38:52 +0100 Subject: [PATCH 05/37] GitHub workflows: run arm64 tests on native runner GitHub provides arm64 runners now [1]. Use them. The workflows don't seem to run faster than before, but the tests should be more realistic. [1] https://github.blog/changelog/2025-01-16-linux-arm64-hosted-runners-now-available-for-free-in-public-repositories-public-preview/ Signed-off-by: Martin Wilck (cherry picked from commit 00cdcbc43e149aa41c1d81022350a74c9d2b4d69) --- .github/workflows/multiarch-stable.yaml | 4 ---- .github/workflows/multiarch.yaml | 5 +++- .github/workflows/native.yaml | 31 ++++++++++++++++++++----- .github/workflows/rolling.yaml | 13 +++++++++-- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml index 4c4bf95c0..76ff1026d 100644 --- a/.github/workflows/multiarch-stable.yaml +++ b/.github/workflows/multiarch-stable.yaml @@ -37,14 +37,10 @@ jobs: - ubuntu-trusty arch: [386, arm/v7] include: - - os: debian-trixie - arch: aarch64 - os: debian-trixie arch: s390x - os: debian-trixie arch: ppc64le - - os: debian-bookworm - arch: aarch64 - os: debian-bookworm arch: s390x - os: debian-bookworm diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml index c94f19ee6..b11ba06d5 100644 --- a/.github/workflows/multiarch.yaml +++ b/.github/workflows/multiarch.yaml @@ -39,12 +39,15 @@ jobs: - debian-sid - fedora-rawhide - opensuse-tumbleweed - arch: [amd64, ppc64le, aarch64, s390x, 386, arm/v7] + arch: [ppc64le, s390x, 386, arm/v7] exclude: - os: fedora-rawhide arch: 386 - os: fedora-rawhide arch: arm/v7 + include: + - os: alpine + arch: aarch64 steps: - name: checkout uses: actions/checkout@v4 diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index f6ee8699f..93eed5ff6 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -26,7 +26,6 @@ on: jobs: stable: - runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -39,6 +38,12 @@ jobs: - fedora-43 - opensuse-leap-15.6 - opensuse-leap-16.0 + variant: + - arch: x86_64 + runner: ubuntu-24.04 + - arch: aarch64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.variant.runner }} steps: - name: checkout uses: actions/checkout@v4 @@ -81,17 +86,15 @@ jobs: - name: upload binary archive uses: actions/upload-artifact@v4 with: - name: native-${{ matrix.os }} + name: native-${{ matrix.os }}-${{ matrix.variant.arch }} path: ${{ env.ARCHIVE_TGT }} overwrite: true clang: - runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: os: - - debian-jessie - debian-buster - debian-bullseye - debian-bookworm @@ -99,6 +102,17 @@ jobs: - fedora-43 - opensuse-leap-15.6 - opensuse-leap-16.0 + variant: + - arch: x86_64 + runner: ubuntu-24.04 + - arch: aarch64 + runner: ubuntu-24.04-arm + include: + - os: debian-jessie + variant: + arch: x86_64 + runner: ubuntu-24.04 + runs-on: ${{ matrix.variant.runner }} steps: - name: checkout uses: actions/checkout@v4 @@ -119,7 +133,6 @@ jobs: command: -j -Orecurse READLINE=libreadline test root-test: - runs-on: ubuntu-24.04 needs: stable strategy: fail-fast: false @@ -133,6 +146,12 @@ jobs: - fedora-43 - opensuse-leap-15.6 - opensuse-leap-16.0 + variant: + - arch: x86_64 + runner: ubuntu-24.04 + - arch: aarch64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.variant.runner }} steps: - name: mpath run: sudo modprobe dm_multipath @@ -145,7 +164,7 @@ jobs: - name: download binary archive uses: actions/download-artifact@v4 with: - name: native-${{ matrix.os }} + name: native-${{ matrix.os }}-${{ matrix.variant.arch }} - name: unpack binary archive run: cpio -idv < test-progs.cpio if: ${{ startswith(matrix.os, 'opensuse-leap-15') }} diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml index b5ff4f516..a4b67a0ef 100644 --- a/.github/workflows/rolling.yaml +++ b/.github/workflows/rolling.yaml @@ -29,15 +29,24 @@ on: jobs: rolling: - runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: os: - debian-sid - - alpine - opensuse-tumbleweed - fedora-rawhide + variant: + - arch: x86_64 + runner: ubuntu-24.04 + - arch: aarch64 + runner: ubuntu-24.04-arm + include: + - os: alpine + variant: + arch: x86_64 + runner: ubuntu-24.04 + runs-on: ${{ matrix.variant.runner }} container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} steps: - name: checkout From 6b4ff33334fec2790655c8fae12a7eb8d3fcc7a7 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 17 Nov 2025 13:07:57 +0100 Subject: [PATCH 06/37] GitHub workflows: rolling: upload binaries on error This will allow debugging CI failures (to some extent, as we compile with optimization by default). Signed-off-by: Martin Wilck (cherry picked from commit aee2310bb6e8671e8311ea098df581bbf1acfdcb) --- .github/workflows/rolling.yaml | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml index a4b67a0ef..34efcff68 100644 --- a/.github/workflows/rolling.yaml +++ b/.github/workflows/rolling.yaml @@ -41,21 +41,38 @@ jobs: runner: ubuntu-24.04 - arch: aarch64 runner: ubuntu-24.04-arm + compiler: + - gcc + - clang include: - os: alpine variant: arch: x86_64 runner: ubuntu-24.04 + compiler: gcc + - os: alpine + variant: + arch: x86_64 + runner: ubuntu-24.04 + compiler: clang runs-on: ${{ matrix.variant.runner }} container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} steps: - name: checkout uses: actions/checkout@v4 - name: build and test - run: make READLINE=libreadline -j -Orecurse test - - name: clean - run: make -j -Orecurse clean - - name: clang - env: - CC: clang - run: make READLINE=libedit -j -Orecurse test + id: test + run: make CC=${{ matrix.compiler }} READLINE=libreadline -j -Orecurse test + continue-on-error: true + - name: create binary archive + run: make test-progs.tar + if: steps.test.outcome != 'success' + - name: upload binary archive + uses: actions/upload-artifact@v4 + with: + name: binaries-${{ matrix.os }}-${{ matrix.variant.arch }}-${{ matrix.compiler }} + path: test-progs.tar + if: steps.test.outcome != 'success' + - name: fail + run: /bin/false + if: steps.test.outcome != 'success' From d27fbdd4966992c68714e6d7b6a8f2dbcd77dae6 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 17 Nov 2025 13:31:25 +0100 Subject: [PATCH 07/37] GitHub workflows: multiarch-stable: upload binaries on error Signed-off-by: Martin Wilck (cherry picked from commit 34746cd08af6fa4969b0bc062d62d92750bef6f8) --- .github/workflows/multiarch-stable.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml index 76ff1026d..b8c770e40 100644 --- a/.github/workflows/multiarch-stable.yaml +++ b/.github/workflows/multiarch-stable.yaml @@ -53,6 +53,7 @@ jobs: with: image: tonistiigi/binfmt:latest - name: compile and run unit tests + id: test uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} @@ -61,3 +62,23 @@ jobs: command: test params: "--platform linux/${{ matrix.arch }}" pull-params: "--platform linux/${{ matrix.arch }}" + continue-on-error: true + - name: create binary archive + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + guest-dir: /build + host-dir: ${{ github.workspace }} + command: test-progs.tar + params: "--platform linux/${{ matrix.arch }}" + pull-params: "--platform linux/${{ matrix.arch }}" + if: steps.test.outcome != 'success' + - name: upload binary archive + uses: actions/upload-artifact@v4 + with: + name: binaries-${{ matrix.os }}-${{ matrix.arch }} + path: test-progs.tar + if: steps.test.outcome != 'success' + - name: fail + run: /bin/false + if: steps.test.outcome != 'success' From d98b31ca30f6055135ff34b2867b880bfc0e8ae7 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 17 Nov 2025 13:31:47 +0100 Subject: [PATCH 08/37] GitHub workflows: native: upload binaries on error Signed-off-by: Martin Wilck (cherry picked from commit f3bdfef8f63b9647de0cf9d65fbbe2c9b31751cd) --- .github/workflows/native.yaml | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 93eed5ff6..94e5ef22d 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -57,18 +57,23 @@ jobs: if: ${{ !startswith(matrix.os, 'opensuse-leap-15') }} - name: build and test + id: test if: ${{ matrix.os != 'debian-jessie' }} uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} command: -j -Orecurse test + continue-on-error: true + - name: build and test (jessie) + id: test_jessie # On jessie, we use libreadline 5 (no licensing issue) if: ${{ matrix.os == 'debian-jessie' }} uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} command: -j -Orecurse READLINE=libreadline test + continue-on-error: true - name: create ${{ env.ARCHIVE_TGT }} if: ${{ matrix.os != 'debian-jessie' }} @@ -90,6 +95,13 @@ jobs: path: ${{ env.ARCHIVE_TGT }} overwrite: true + - name: fail + run: /bin/false + if: >- + ${{ ( matrix.os == 'debian-jessie' && + steps.test_jessie.outcome != 'success' ) || + ( matrix.os != 'debian-jessie' && + steps.test.outcome != 'success' ) }} clang: strategy: fail-fast: false @@ -117,20 +129,75 @@ jobs: - name: checkout uses: actions/checkout@v4 + - name: set archive name + # Leap containers have cpio but not tar + run: echo ARCHIVE_TGT=test-progs.cpio >> $GITHUB_ENV + if: ${{ startswith(matrix.os, 'opensuse-leap-15') }} + - name: set archive name + run: echo ARCHIVE_TGT=test-progs.tar >> $GITHUB_ENV + if: ${{ !startswith(matrix.os, 'opensuse-leap-15') }} + - name: clang + id: test if: ${{ matrix.os != 'debian-jessie' }} uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} params: -e CC=clang command: -j -Orecurse test + continue-on-error: true - name: clang (jessie) + id: test_jessie if: ${{ matrix.os == 'debian-jessie' }} uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} params: -e CC=clang command: -j -Orecurse READLINE=libreadline test + continue-on-error: true + + - name: create ${{ env.ARCHIVE_TGT }} + if: ${{ matrix.os != 'debian-jessie' }} + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + command: ${{ env.ARCHIVE_TGT }} + if: >- + ${{ ( matrix.os == 'debian-jessie' && + steps.test_jessie.outcome != 'success' ) || + ( matrix.os != 'debian-jessie' && + steps.test.outcome != 'success' ) }} + - name: create ${{ env.ARCHIVE_TGT }} (jessie) + if: ${{ matrix.os == 'debian-jessie' }} + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + command: READLINE=libreadline ${{ env.ARCHIVE_TGT }} + if: >- + ${{ ( matrix.os == 'debian-jessie' && + steps.test_jessie.outcome != 'success' ) || + ( matrix.os != 'debian-jessie' && + steps.test.outcome != 'success' ) }} + + - name: upload binary archive + uses: actions/upload-artifact@v4 + with: + name: clang-${{ matrix.os }}-${{ matrix.variant.arch }} + path: ${{ env.ARCHIVE_TGT }} + overwrite: true + if: >- + ${{ ( matrix.os == 'debian-jessie' && + steps.test_jessie.outcome != 'success' ) || + ( matrix.os != 'debian-jessie' && + steps.test.outcome != 'success' ) }} + + - name: fail + run: /bin/false + if: >- + ${{ ( matrix.os == 'debian-jessie' && + steps.test_jessie.outcome != 'success' ) || + ( matrix.os != 'debian-jessie' && + steps.test.outcome != 'success' ) }} root-test: needs: stable From 4171c525021bb9ab874f1fcc641bdcf51f49c30a Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 17 Nov 2025 13:35:08 +0100 Subject: [PATCH 09/37] GitHub workflows: multiarch: upload binaries on error Signed-off-by: Martin Wilck (cherry picked from commit b854c7b9208d3fffff7cfb5fabb18d5e8db4770f) --- .github/workflows/multiarch.yaml | 22 +++++++++++++++++++++- .github/workflows/native.yaml | 2 -- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml index b11ba06d5..806275a13 100644 --- a/.github/workflows/multiarch.yaml +++ b/.github/workflows/multiarch.yaml @@ -56,6 +56,7 @@ jobs: with: image: tonistiigi/binfmt:latest - name: compile and run unit tests + id: test uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} @@ -64,4 +65,23 @@ jobs: command: test params: "--platform linux/${{ matrix.arch }}" pull-params: "--platform linux/${{ matrix.arch }}" - + continue-on-error: true + - name: create binary archive + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + guest-dir: /build + host-dir: ${{ github.workspace }} + command: test-progs.tar + params: "--platform linux/${{ matrix.arch }}" + pull-params: "--platform linux/${{ matrix.arch }}" + if: steps.test.outcome != 'success' + - name: upload binary archive + uses: actions/upload-artifact@v4 + with: + name: binaries-${{ matrix.os }}-${{ matrix.arch }} + path: test-progs.tar + if: steps.test.outcome != 'success' + - name: fail + run: /bin/false + if: steps.test.outcome != 'success' diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 94e5ef22d..7baded415 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -157,7 +157,6 @@ jobs: continue-on-error: true - name: create ${{ env.ARCHIVE_TGT }} - if: ${{ matrix.os != 'debian-jessie' }} uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} @@ -168,7 +167,6 @@ jobs: ( matrix.os != 'debian-jessie' && steps.test.outcome != 'success' ) }} - name: create ${{ env.ARCHIVE_TGT }} (jessie) - if: ${{ matrix.os == 'debian-jessie' }} uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} From 4eac742e8b4c8e3e9a2c547d737feb998d5b55f6 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 17 Nov 2025 15:05:47 +0100 Subject: [PATCH 10/37] GitHub workflows: use -j$(nproc) consistently The workflow files were using make's -j flag inconsistently. Fix it. Signed-off-by: Martin Wilck (cherry picked from commit f24aca35628371c25d92d14f8067b71972d16a00) --- .github/workflows/abi-stable.yaml | 4 ++-- .github/workflows/abi.yaml | 2 +- .github/workflows/build-and-unittest.yaml | 12 ++++++------ .github/workflows/coverity.yaml | 2 +- .github/workflows/foreign.yaml | 2 +- .github/workflows/native.yaml | 8 ++++---- .github/workflows/rolling.yaml | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml index 8b2c83a85..1ba9e7fa6 100644 --- a/.github/workflows/abi-stable.yaml +++ b/.github/workflows/abi-stable.yaml @@ -43,7 +43,7 @@ jobs: with: ref: ${{ env.PARENT_TAG }} - name: build ABI for ${{ env.PARENT_TAG }} - run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi + run: make -j$(nproc) -Orecurse abi - name: save ABI uses: actions/upload-artifact@v4 with: @@ -88,7 +88,7 @@ jobs: libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - name: check ABI of ${{ github.ref }} against ${{ env.PARENT_TAG }} id: check_abi - run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi-test + run: make -j$(nproc) -Orecurse abi-test continue-on-error: true - name: save differences if: ${{ steps.check_abi.outcome != 'success' }} diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml index 70ceb89df..adc2081f1 100644 --- a/.github/workflows/abi.yaml +++ b/.github/workflows/abi.yaml @@ -44,7 +44,7 @@ jobs: libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev libmount-dev - name: create ABI - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + run: make -Orecurse -j$(nproc) abi.tar.gz - name: save ABI uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml index a3ee7d8e7..2fb5327d4 100644 --- a/.github/workflows/build-and-unittest.yaml +++ b/.github/workflows/build-and-unittest.yaml @@ -46,16 +46,16 @@ jobs: if: ${{ matrix.cc == 'clang' }} - name: build run: > - make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) + make -Orecurse -j$(nproc) READLINE=${{ matrix.rl }} OPTFLAGS="$OPT" - name: test run: > - make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) + make -Orecurse -j$(nproc) OPTFLAGS="$OPT" test - name: valgrind-test id: valgrind run: > - make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) + make -Orecurse -j$(nproc) OPTFLAGS="$OPT" valgrind-test continue-on-error: true - name: valgrind-results @@ -92,12 +92,12 @@ jobs: - name: set CC run: echo CC=${{ matrix.cc }} >> $GITHUB_ENV - name: build - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + run: make -Orecurse -j$(nproc) READLINE=${{ matrix.rl }} - name: test - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + run: make -Orecurse -j$(nproc) test - name: valgrind-test id: valgrind - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + run: make -Orecurse -j$(nproc) valgrind-test continue-on-error: true - name: valgrind-results run: cat tests/*.vgr diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml index 3ade6771b..3c04c2124 100644 --- a/.github/workflows/coverity.yaml +++ b/.github/workflows/coverity.yaml @@ -32,7 +32,7 @@ jobs: - name: build with cov-build run: > PATH="$PWD/coverity/bin:$PATH" - cov-build --dir cov-int make -Orecurse -j"$(grep -c ^processor /proc/cpuinfo)" + cov-build --dir cov-int make -Orecurse -j"$(nproc)" - name: pack results run: tar cfz multipath-tools.tgz cov-int - name: submit results diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml index 47affb7ac..b232b60c1 100644 --- a/.github/workflows/foreign.yaml +++ b/.github/workflows/foreign.yaml @@ -43,7 +43,7 @@ jobs: - name: checkout uses: actions/checkout@v4 - name: build - run: make -j -Orecurse test-progs.tar + run: make -j$(nproc) -Orecurse test-progs.tar - name: upload binary archive uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 7baded415..9e89780b1 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -62,7 +62,7 @@ jobs: uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} - command: -j -Orecurse test + command: -j$(nproc) -Orecurse test continue-on-error: true - name: build and test (jessie) @@ -72,7 +72,7 @@ jobs: uses: mosteo-actions/docker-run@v1 with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} - command: -j -Orecurse READLINE=libreadline test + command: -j$(nproc) -Orecurse READLINE=libreadline test continue-on-error: true - name: create ${{ env.ARCHIVE_TGT }} @@ -144,7 +144,7 @@ jobs: with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} params: -e CC=clang - command: -j -Orecurse test + command: -j$(nproc) -Orecurse test continue-on-error: true - name: clang (jessie) id: test_jessie @@ -153,7 +153,7 @@ jobs: with: image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} params: -e CC=clang - command: -j -Orecurse READLINE=libreadline test + command: -j$(nproc) -Orecurse READLINE=libreadline test continue-on-error: true - name: create ${{ env.ARCHIVE_TGT }} diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml index 34efcff68..a4706e52e 100644 --- a/.github/workflows/rolling.yaml +++ b/.github/workflows/rolling.yaml @@ -62,7 +62,7 @@ jobs: uses: actions/checkout@v4 - name: build and test id: test - run: make CC=${{ matrix.compiler }} READLINE=libreadline -j -Orecurse test + run: make CC=${{ matrix.compiler }} READLINE=libreadline -j$(nproc) -Orecurse test continue-on-error: true - name: create binary archive run: make test-progs.tar From f6ce7fe528493eb16a09b4192251cf6c622369f7 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 17 Nov 2025 16:37:07 +0100 Subject: [PATCH 11/37] GitHub workflows: install libmount-dev on Ubuntu Without it, the workflows will fail. Signed-off-by: Martin Wilck --- .github/workflows/abi-stable.yaml | 2 ++ .github/workflows/coverity.yaml | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml index 1ba9e7fa6..8f9a9dbf3 100644 --- a/.github/workflows/abi-stable.yaml +++ b/.github/workflows/abi-stable.yaml @@ -38,6 +38,7 @@ jobs: gcc make pkg-config abigail-tools libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + libmount-dev - name: checkout ${{ env.PARENT_TAG }} uses: actions/checkout@v4 with: @@ -86,6 +87,7 @@ jobs: gcc make pkg-config abigail-tools libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + libmount-dev - name: check ABI of ${{ github.ref }} against ${{ env.PARENT_TAG }} id: check_abi run: make -j$(nproc) -Orecurse abi-test diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml index 3c04c2124..30e5471d3 100644 --- a/.github/workflows/coverity.yaml +++ b/.github/workflows/coverity.yaml @@ -16,6 +16,7 @@ jobs: gcc make pkg-config libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + libmount-dev - name: download coverity run: > curl -o cov-analysis-linux64.tar.gz From 3e095eaefeb9d8170b1554abed54fa853f630abb Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 21 Nov 2025 12:16:52 +0100 Subject: [PATCH 12/37] libdmmp: update man page time stamps c78cf64 ("multipath-tools: replace FSF licences boilerplate with a SPDX-License-Identifier") updated libdmmp.h. This will cause the multipath build process to update it as well, even though the man page content doesn't change. Avoid that by updating the time stamps. Signed-off-by: Martin Wilck (cherry picked from commit 196b3d14682401e0b2e6aa5fbf34d03eb4bfac6e) --- libdmmp/docs/man/dmmp_context_free.3 | 2 +- libdmmp/docs/man/dmmp_context_log_func_set.3 | 2 +- libdmmp/docs/man/dmmp_context_log_priority_get.3 | 2 +- libdmmp/docs/man/dmmp_context_log_priority_set.3 | 2 +- libdmmp/docs/man/dmmp_context_new.3 | 2 +- libdmmp/docs/man/dmmp_context_timeout_get.3 | 2 +- libdmmp/docs/man/dmmp_context_timeout_set.3 | 2 +- libdmmp/docs/man/dmmp_context_userdata_get.3 | 2 +- libdmmp/docs/man/dmmp_context_userdata_set.3 | 2 +- libdmmp/docs/man/dmmp_flush_mpath.3 | 2 +- libdmmp/docs/man/dmmp_last_error_msg.3 | 2 +- libdmmp/docs/man/dmmp_log_priority_str.3 | 2 +- libdmmp/docs/man/dmmp_mpath_array_free.3 | 2 +- libdmmp/docs/man/dmmp_mpath_array_get.3 | 2 +- libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 | 2 +- libdmmp/docs/man/dmmp_mpath_name_get.3 | 2 +- libdmmp/docs/man/dmmp_mpath_wwid_get.3 | 2 +- libdmmp/docs/man/dmmp_path_array_get.3 | 2 +- libdmmp/docs/man/dmmp_path_blk_name_get.3 | 2 +- libdmmp/docs/man/dmmp_path_group_array_get.3 | 2 +- libdmmp/docs/man/dmmp_path_group_id_get.3 | 2 +- libdmmp/docs/man/dmmp_path_group_priority_get.3 | 2 +- libdmmp/docs/man/dmmp_path_group_selector_get.3 | 2 +- libdmmp/docs/man/dmmp_path_group_status_get.3 | 2 +- libdmmp/docs/man/dmmp_path_group_status_str.3 | 2 +- libdmmp/docs/man/dmmp_path_status_get.3 | 2 +- libdmmp/docs/man/dmmp_path_status_str.3 | 2 +- libdmmp/docs/man/dmmp_reconfig.3 | 2 +- libdmmp/docs/man/dmmp_strerror.3 | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libdmmp/docs/man/dmmp_context_free.3 b/libdmmp/docs/man/dmmp_context_free.3 index 2a9bbb10f..ce74cfb00 100644 --- a/libdmmp/docs/man/dmmp_context_free.3 +++ b/libdmmp/docs/man/dmmp_context_free.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_free" 3 "dmmp_context_free" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_free" 3 "dmmp_context_free" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_free \- Release the memory of struct dmmp_context. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_log_func_set.3 b/libdmmp/docs/man/dmmp_context_log_func_set.3 index f593eb57b..05b1cd0f1 100644 --- a/libdmmp/docs/man/dmmp_context_log_func_set.3 +++ b/libdmmp/docs/man/dmmp_context_log_func_set.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_log_func_set" 3 "dmmp_context_log_func_set" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_log_func_set" 3 "dmmp_context_log_func_set" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_log_func_set \- Set log handler function. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_log_priority_get.3 b/libdmmp/docs/man/dmmp_context_log_priority_get.3 index 6f7c3204f..62f671ff2 100644 --- a/libdmmp/docs/man/dmmp_context_log_priority_get.3 +++ b/libdmmp/docs/man/dmmp_context_log_priority_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_log_priority_get" 3 "dmmp_context_log_priority_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_log_priority_get" 3 "dmmp_context_log_priority_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_log_priority_get \- Get log priority. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_log_priority_set.3 b/libdmmp/docs/man/dmmp_context_log_priority_set.3 index c1ff3715e..991d5bf92 100644 --- a/libdmmp/docs/man/dmmp_context_log_priority_set.3 +++ b/libdmmp/docs/man/dmmp_context_log_priority_set.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_log_priority_set" 3 "dmmp_context_log_priority_set" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_log_priority_set" 3 "dmmp_context_log_priority_set" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_log_priority_set \- Set log priority. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_new.3 b/libdmmp/docs/man/dmmp_context_new.3 index 487ccde8c..25ce6ad9c 100644 --- a/libdmmp/docs/man/dmmp_context_new.3 +++ b/libdmmp/docs/man/dmmp_context_new.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_new" 3 "dmmp_context_new" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_new" 3 "dmmp_context_new" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_new \- Create struct dmmp_context. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_timeout_get.3 b/libdmmp/docs/man/dmmp_context_timeout_get.3 index b738fb97b..317b3f4c8 100644 --- a/libdmmp/docs/man/dmmp_context_timeout_get.3 +++ b/libdmmp/docs/man/dmmp_context_timeout_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_timeout_get" 3 "dmmp_context_timeout_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_timeout_get" 3 "dmmp_context_timeout_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_timeout_get \- Get IPC timeout. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_timeout_set.3 b/libdmmp/docs/man/dmmp_context_timeout_set.3 index af84be94d..9db1d2591 100644 --- a/libdmmp/docs/man/dmmp_context_timeout_set.3 +++ b/libdmmp/docs/man/dmmp_context_timeout_set.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_timeout_set" 3 "dmmp_context_timeout_set" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_timeout_set" 3 "dmmp_context_timeout_set" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_timeout_set \- Set IPC timeout. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_userdata_get.3 b/libdmmp/docs/man/dmmp_context_userdata_get.3 index 23e1da41d..ef5755e8e 100644 --- a/libdmmp/docs/man/dmmp_context_userdata_get.3 +++ b/libdmmp/docs/man/dmmp_context_userdata_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_userdata_get" 3 "dmmp_context_userdata_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_userdata_get" 3 "dmmp_context_userdata_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_userdata_get \- Get user data pointer. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_context_userdata_set.3 b/libdmmp/docs/man/dmmp_context_userdata_set.3 index 8a4a76561..cd21644a3 100644 --- a/libdmmp/docs/man/dmmp_context_userdata_set.3 +++ b/libdmmp/docs/man/dmmp_context_userdata_set.3 @@ -1,4 +1,4 @@ -.TH "dmmp_context_userdata_set" 3 "dmmp_context_userdata_set" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_context_userdata_set" 3 "dmmp_context_userdata_set" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_context_userdata_set \- Set user data pointer. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_flush_mpath.3 b/libdmmp/docs/man/dmmp_flush_mpath.3 index e5690edb2..f8cb83e8d 100644 --- a/libdmmp/docs/man/dmmp_flush_mpath.3 +++ b/libdmmp/docs/man/dmmp_flush_mpath.3 @@ -1,4 +1,4 @@ -.TH "dmmp_flush_mpath" 3 "dmmp_flush_mpath" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_flush_mpath" 3 "dmmp_flush_mpath" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_flush_mpath \- Flush specified multipath device map if unused. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_last_error_msg.3 b/libdmmp/docs/man/dmmp_last_error_msg.3 index 548e1a75a..7aa980bdf 100644 --- a/libdmmp/docs/man/dmmp_last_error_msg.3 +++ b/libdmmp/docs/man/dmmp_last_error_msg.3 @@ -1,4 +1,4 @@ -.TH "dmmp_last_error_msg" 3 "dmmp_last_error_msg" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_last_error_msg" 3 "dmmp_last_error_msg" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_last_error_msg \- Retrieves the last error message. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_log_priority_str.3 b/libdmmp/docs/man/dmmp_log_priority_str.3 index cf3155642..1252e17c8 100644 --- a/libdmmp/docs/man/dmmp_log_priority_str.3 +++ b/libdmmp/docs/man/dmmp_log_priority_str.3 @@ -1,4 +1,4 @@ -.TH "dmmp_log_priority_str" 3 "dmmp_log_priority_str" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_log_priority_str" 3 "dmmp_log_priority_str" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_log_priority_str \- Convert log priority to string. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_mpath_array_free.3 b/libdmmp/docs/man/dmmp_mpath_array_free.3 index 8d2090e64..2a1f1aee8 100644 --- a/libdmmp/docs/man/dmmp_mpath_array_free.3 +++ b/libdmmp/docs/man/dmmp_mpath_array_free.3 @@ -1,4 +1,4 @@ -.TH "dmmp_mpath_array_free" 3 "dmmp_mpath_array_free" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_mpath_array_free" 3 "dmmp_mpath_array_free" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_mpath_array_free \- Free 'struct dmmp_mpath' pointer array. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_mpath_array_get.3 b/libdmmp/docs/man/dmmp_mpath_array_get.3 index 4191571ee..2bb7b186e 100644 --- a/libdmmp/docs/man/dmmp_mpath_array_get.3 +++ b/libdmmp/docs/man/dmmp_mpath_array_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_mpath_array_get" 3 "dmmp_mpath_array_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_mpath_array_get" 3 "dmmp_mpath_array_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_mpath_array_get \- Query all existing multipath devices. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 b/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 index 261bea6a9..f368cc294 100644 --- a/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 +++ b/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_mpath_kdev_name_get" 3 "dmmp_mpath_kdev_name_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_mpath_kdev_name_get" 3 "dmmp_mpath_kdev_name_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_mpath_kdev_name_get \- Retrieve kernel DEVNAME of certain mpath. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_mpath_name_get.3 b/libdmmp/docs/man/dmmp_mpath_name_get.3 index 894d318f8..20cc09b6d 100644 --- a/libdmmp/docs/man/dmmp_mpath_name_get.3 +++ b/libdmmp/docs/man/dmmp_mpath_name_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_mpath_name_get" 3 "dmmp_mpath_name_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_mpath_name_get" 3 "dmmp_mpath_name_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_mpath_name_get \- Retrieve name(alias) of certain mpath. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_mpath_wwid_get.3 b/libdmmp/docs/man/dmmp_mpath_wwid_get.3 index e6afcb1a8..09c79aa6a 100644 --- a/libdmmp/docs/man/dmmp_mpath_wwid_get.3 +++ b/libdmmp/docs/man/dmmp_mpath_wwid_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_mpath_wwid_get" 3 "dmmp_mpath_wwid_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_mpath_wwid_get" 3 "dmmp_mpath_wwid_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_mpath_wwid_get \- Retrieve WWID of certain mpath. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_array_get.3 b/libdmmp/docs/man/dmmp_path_array_get.3 index de29c9d1e..7bd19e709 100644 --- a/libdmmp/docs/man/dmmp_path_array_get.3 +++ b/libdmmp/docs/man/dmmp_path_array_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_array_get" 3 "dmmp_path_array_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_array_get" 3 "dmmp_path_array_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_array_get \- Retrieve path pointer array. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_blk_name_get.3 b/libdmmp/docs/man/dmmp_path_blk_name_get.3 index 167e81c31..984ae9d4c 100644 --- a/libdmmp/docs/man/dmmp_path_blk_name_get.3 +++ b/libdmmp/docs/man/dmmp_path_blk_name_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_blk_name_get" 3 "dmmp_path_blk_name_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_blk_name_get" 3 "dmmp_path_blk_name_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_blk_name_get \- Retrieve block name. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_group_array_get.3 b/libdmmp/docs/man/dmmp_path_group_array_get.3 index b9b663f67..7faa89c90 100644 --- a/libdmmp/docs/man/dmmp_path_group_array_get.3 +++ b/libdmmp/docs/man/dmmp_path_group_array_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_group_array_get" 3 "dmmp_path_group_array_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_group_array_get" 3 "dmmp_path_group_array_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_group_array_get \- Retrieve path groups pointer array. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_group_id_get.3 b/libdmmp/docs/man/dmmp_path_group_id_get.3 index 67ba5c00e..fb3cea644 100644 --- a/libdmmp/docs/man/dmmp_path_group_id_get.3 +++ b/libdmmp/docs/man/dmmp_path_group_id_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_group_id_get" 3 "dmmp_path_group_id_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_group_id_get" 3 "dmmp_path_group_id_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_group_id_get \- Retrieve path group ID. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_group_priority_get.3 b/libdmmp/docs/man/dmmp_path_group_priority_get.3 index 09cbea9c5..ae8a08aa5 100644 --- a/libdmmp/docs/man/dmmp_path_group_priority_get.3 +++ b/libdmmp/docs/man/dmmp_path_group_priority_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_group_priority_get" 3 "dmmp_path_group_priority_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_group_priority_get" 3 "dmmp_path_group_priority_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_group_priority_get \- Retrieve path group priority. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_group_selector_get.3 b/libdmmp/docs/man/dmmp_path_group_selector_get.3 index dc73fa82e..8fae07360 100644 --- a/libdmmp/docs/man/dmmp_path_group_selector_get.3 +++ b/libdmmp/docs/man/dmmp_path_group_selector_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_group_selector_get" 3 "dmmp_path_group_selector_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_group_selector_get" 3 "dmmp_path_group_selector_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_group_selector_get \- Retrieve path group selector. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_group_status_get.3 b/libdmmp/docs/man/dmmp_path_group_status_get.3 index a7662b634..6adfeba65 100644 --- a/libdmmp/docs/man/dmmp_path_group_status_get.3 +++ b/libdmmp/docs/man/dmmp_path_group_status_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_group_status_get" 3 "dmmp_path_group_status_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_group_status_get" 3 "dmmp_path_group_status_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_group_status_get \- Retrieve path group status. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_group_status_str.3 b/libdmmp/docs/man/dmmp_path_group_status_str.3 index 160c8a7ed..a2d654348 100644 --- a/libdmmp/docs/man/dmmp_path_group_status_str.3 +++ b/libdmmp/docs/man/dmmp_path_group_status_str.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_group_status_str" 3 "dmmp_path_group_status_str" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_group_status_str" 3 "dmmp_path_group_status_str" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_group_status_str \- Convert path group status to string. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_status_get.3 b/libdmmp/docs/man/dmmp_path_status_get.3 index 92e64331b..33d103f70 100644 --- a/libdmmp/docs/man/dmmp_path_status_get.3 +++ b/libdmmp/docs/man/dmmp_path_status_get.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_status_get" 3 "dmmp_path_status_get" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_status_get" 3 "dmmp_path_status_get" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_status_get \- Retrieve the path status. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_path_status_str.3 b/libdmmp/docs/man/dmmp_path_status_str.3 index 456cf24e2..e69c8be69 100644 --- a/libdmmp/docs/man/dmmp_path_status_str.3 +++ b/libdmmp/docs/man/dmmp_path_status_str.3 @@ -1,4 +1,4 @@ -.TH "dmmp_path_status_str" 3 "dmmp_path_status_str" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_path_status_str" 3 "dmmp_path_status_str" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_path_status_str \- Convert path status to string. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_reconfig.3 b/libdmmp/docs/man/dmmp_reconfig.3 index 413a3e6fc..b17c2d689 100644 --- a/libdmmp/docs/man/dmmp_reconfig.3 +++ b/libdmmp/docs/man/dmmp_reconfig.3 @@ -1,4 +1,4 @@ -.TH "dmmp_reconfig" 3 "dmmp_reconfig" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_reconfig" 3 "dmmp_reconfig" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_reconfig \- Instruct multipathd daemon to do reconfiguration. .SH SYNOPSIS diff --git a/libdmmp/docs/man/dmmp_strerror.3 b/libdmmp/docs/man/dmmp_strerror.3 index 202941c9c..c1f80d315 100644 --- a/libdmmp/docs/man/dmmp_strerror.3 +++ b/libdmmp/docs/man/dmmp_strerror.3 @@ -1,4 +1,4 @@ -.TH "dmmp_strerror" 3 "dmmp_strerror" "August 2024" "Device Mapper Multipath API - libdmmp Manual" +.TH "dmmp_strerror" 3 "dmmp_strerror" "June 2025" "Device Mapper Multipath API - libdmmp Manual" .SH NAME dmmp_strerror \- Convert error code to string. .SH SYNOPSIS From 39ffee7baad6bde6c144b3b82672cd6585d9291b Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Sat, 15 Nov 2025 15:50:10 +0100 Subject: [PATCH 13/37] multipath-tools: add Seagate Exos and Nytro series to hwtable Config from, #102: https://www.seagate.com/content/dam/seagate/migrated-assets/www-content/support-content/raid-storage-systems/corvault/_shared/files/205042000-01-B_CORVAULT_SMG.pdf Cc: Martin Wilck Cc: Benjamin Marzinski Cc: Christophe Varoqui Cc: DM_DEVEL-ML Signed-off-by: Xose Vazquez Perez Reviewed-by: Martin Wilck (cherry picked from commit 9889faee3ad2453a3976caaec50646aea1f4a798) --- libmultipath/hwtable.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c index 925230422..2734b78ea 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c @@ -1326,6 +1326,15 @@ static struct hwentry default_hw[] = { .prio_name = PRIO_ALUA, .no_path_retry = 30, }, + { + // Exos / Nytro series + .vendor = "SEAGATE", + .product = "^[456]", + .pgpolicy = GROUP_BY_PRIO, + .pgfailback = -FAILBACK_IMMEDIATE, + .prio_name = PRIO_ALUA, + .no_path_retry = 30, + }, /* * AccelStor */ From 04acd55a5b964cc4ae4d5eddd8fc1cb81a8d7a81 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Sun, 16 Nov 2025 15:20:19 +0100 Subject: [PATCH 14/37] multipath-tools: identify more Storwize models multipath is also supported by V3500 and V3700 Cc: Martin Wilck Cc: Benjamin Marzinski Cc: Christophe Varoqui Cc: DM_DEVEL-ML Signed-off-by: Xose Vazquez Perez Reviewed-by: Martin Wilck (cherry picked from commit 5bdafa5f299a34fa418b24bb9c4f24f3c495b564) --- libmultipath/hwtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c index 2734b78ea..23c549335 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c @@ -682,7 +682,7 @@ static struct hwentry default_hw[] = { .pgfailback = -FAILBACK_IMMEDIATE, }, { - // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) + // Storwize V3x00/V5000/V7000 lines / SAN Volume Controller (SVC) // Flex System V7000 / FlashSystem V840/V9000 and 5x00/7x00/9x00/Cx00 .vendor = "IBM", .product = "^2145", From 7361bc6a32c1e5fbd54e6c864c7f79188623db5b Mon Sep 17 00:00:00 2001 From: Itxaka Date: Fri, 5 Dec 2025 09:28:06 +0100 Subject: [PATCH 15/37] multipathd: Dont pthread_join twice Currently it seems that urcu would already call pthread_join when calling call_rcu_data_free since a couple of years ago (since version v0.14.0)[0] so calling pthread_join on the just released one is problematic under musl systems. It seems like under glibc this has several checks in place before trying to dereference the thread but under musl it has nothing in place to validate so this causes a coredump on program shutdown. This is currently present in all version when compiled under musl, running multipathd -d and sending a SIGTERM to it, you can see the coredump happening at this point in the code. The patch runs only the old behaviour in urcu older than 0.14.0 to maintain the same bahaviour. In higher versions its not neccesary so we skip it. [0] https://github.com/urcu/userspace-rcu/commit/1cf55ba47342156cdf25335264b9774a16e0bb2d Signed-off-by: Itxaka Reviewed-by: Martin Wilck (cherry picked from commit 5835dca56c7fe0b06aad99183de4e8e179e3c56b) --- multipathd/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/multipathd/main.c b/multipathd/main.c index 2d5c146d4..afa42c3ce 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -3745,18 +3745,21 @@ static struct call_rcu_data *mp_rcu_data; static void cleanup_rcu(void) { - pthread_t rcu_thread; - /* Wait for any pending RCU calls */ rcu_barrier(); if (mp_rcu_data != NULL) { +#if (URCU_VERSION < 0x000E00) + pthread_t rcu_thread; rcu_thread = get_call_rcu_thread(mp_rcu_data); +#endif /* detach this thread from the RCU thread */ set_thread_call_rcu_data(NULL); synchronize_rcu(); /* tell RCU thread to exit */ call_rcu_data_free(mp_rcu_data); +#if (URCU_VERSION < 0x000E00) pthread_join(rcu_thread, NULL); +#endif } rcu_unregister_thread(); } From 5bef4d8a8eba4e09fa39d2c00b96f417c1315e3f Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 21 Nov 2025 13:09:57 +0100 Subject: [PATCH 16/37] GitHub actions: spelling: ignore generic hex number patterns Fix the spelling CI complaints about "0xea01". Signed-off-by: Martin Wilck (cherry picked from commit 7ef482e8c0e89a69de729cff60d4981ca261d7e3) --- .github/actions/spelling/patterns.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index f2ef14240..55d4742eb 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -10,6 +10,11 @@ #commit \b[0-9a-f]{7}\b +# Generic Hex numbers +\b0x[0-9a-f]{4}\b +\b0x[0-9a-f]{8}\b +\b0x[0-9a-f]{16}\b + # WWNN/WWPN (NAA identifiers) \b(?:0x)?10[0-9a-f]{14}\b \b(?:0x|3)?[25][0-9a-f]{15}\b From 36605acda6abb0320546c3053b62c72139972f78 Mon Sep 17 00:00:00 2001 From: Michal Rostecki Date: Wed, 7 Jan 2026 12:09:51 +0000 Subject: [PATCH 17/37] libmultipath: Remove the undefined symbol from the linker script dm_get_multipath() is a static function, not a symbol that can be exported. Clang is strict about not allowing undefined symbols in linker scripts and therefore its presence prevents clang from building libmultipath. It looks like it's a linker error and it's thrown only by lld. lld enabled --no-undefined-version as a default option [0]. Choice of a compiler (gcc, clang) shouldn't matter. One can reproduce the error on any system by specifying lld explicitly: $ make LDFLAGS="-fuse-ld=lld" Or by passing --no-undefined-version (and making the warning fatal), which throws an error wyth any linker: $ make LDFLAGS="-fuse-ld=mold -Wl,--no-undefined-version -Wl,--fatal-warnings". [0] https://reviews.llvm.org/D135402 Fixes: https://github.com/opensvc/multipath-tools/issues/132 Fixes: bf3a4ad ("libmultipath: simplify dm_get_maps()") Signed-off-by: Michal Rostecki Reviewed-by: Martin Wilck (cherry picked from commit a2986033c13de3b51002c6592dcfd59a6a8240dd) --- libmultipath/libmultipath.version | 1 - 1 file changed, 1 deletion(-) diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version index a67183556..dc00a41de 100644 --- a/libmultipath/libmultipath.version +++ b/libmultipath/libmultipath.version @@ -84,7 +84,6 @@ global: dm_geteventnr; dm_get_major_minor; dm_get_maps; - dm_get_multipath; dm_is_mpath; dm_mapname; dm_prereq; From 0678ad93dd42cb7f7c8695eb86ad836ee08bb7bf Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 8 Dec 2025 15:18:01 +0100 Subject: [PATCH 18/37] multipath-tools: Fix ISO C23 errors with strchr() In ISO C23, memchr, strchr, strpbrk, strrchr and strstr become const-preserving macros [1], meaning that the return value inherits the const qualifier from the function argument. This has turned up a few glitches in our code. [1] https://gustedt.gitlabpages.inria.fr/c23-library/#memchr Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 9f611e2f10a4456477b6447641eea041ecee1019) --- libmpathutil/parser.c | 2 +- libmpathutil/util.c | 2 +- libmultipath/prkey.c | 2 +- libmultipath/prkey.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libmpathutil/parser.c b/libmpathutil/parser.c index 131a5ed03..bf7c411b8 100644 --- a/libmpathutil/parser.c +++ b/libmpathutil/parser.c @@ -144,7 +144,7 @@ snprint_keyword(struct strbuf *buff, const char *fmt, struct keyword *kw, const void *data) { int r = 0; - char *f; + const char *f; struct config *conf; STRBUF_ON_STACK(sbuf); diff --git a/libmpathutil/util.c b/libmpathutil/util.c index 38e984fc8..37412c662 100644 --- a/libmpathutil/util.c +++ b/libmpathutil/util.c @@ -38,7 +38,7 @@ strchop(char *str) */ const char *libmp_basename(const char *filename) { - char *p = strrchr(filename, '/'); + const char *p = strrchr(filename, '/'); return p ? p + 1 : filename; } diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c index c66d293b9..af4a28267 100644 --- a/libmultipath/prkey.c +++ b/libmultipath/prkey.c @@ -50,7 +50,7 @@ static int parse_prkey(const char *ptr, uint64_t *prkey) return 0; } -int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags) +int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags) { char *flagstr; diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h index a89a617bd..806795ed3 100644 --- a/libmultipath/prkey.h +++ b/libmultipath/prkey.h @@ -15,7 +15,7 @@ int print_reservation_key(struct strbuf *buff, struct be64 key, uint8_t flags, int source); -int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); +int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags); int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, uint8_t sa_flags); int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags); From b65f108b6e2587adc02a82f31b2690fb1c5357a5 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Tue, 16 Dec 2025 21:58:42 +0100 Subject: [PATCH 19/37] Makefile: fix CI build errors with cmocka 2.0 cmocka 2.0.0 introduces a couple of changes that require version-dependent code to be used. Add macros to determine the cmocka version. If the version can't be determined, assume 1.1.0. Use a different approach here than in the stable branch, because the fix there is rather large. Instead of replacing all deprecated macros, just treat the respective warnings as non-fatal by adding the compiler flag -Wno-error=deprecated-declarations for the CI code. cmocka 2.0.1 added a macro to suppress these warnings altogether, but we should also be able to build against 2.0.0. Fixes: https://github.com/opensvc/multipath-tools/issues/129 Signed-off-by: Martin Wilck --- Makefile.inc | 2 +- create-config.mk | 5 +++++ tests/Makefile | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile.inc b/Makefile.inc index 9e3dc4661..3dbcdcfad 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -112,7 +112,7 @@ WARNFLAGS := $(WERROR) -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)imp -W$(ERROR)implicit-function-declaration -W$(ERROR)format-security \ $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ +CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) $(D_CMOCKA_VERSION) \ -D_FILE_OFFSET_BITS=64 \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ diff --git a/create-config.mk b/create-config.mk index 3c3ba069e..2d6ade856 100644 --- a/create-config.mk +++ b/create-config.mk @@ -77,6 +77,10 @@ URCU_VERSION = $(shell \ $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') +CMOCKA_VERSION = $(shell \ + ($(PKG_CONFIG) --modversion cmocka 2>/dev/null || echo "1.1.0" ) | \ + awk -F. '{ printf("%d", 256 * ( 256 * $$1 + $$2) + $$3); }') + DEFINES := ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) @@ -185,6 +189,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ @echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@ + @echo "CMOCKA_VERSION := $(call CMOCKA_VERSION)" >>$@ @echo "SYSTEMD := $(SYSTEMD)" >>$@ @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ diff --git a/tests/Makefile b/tests/Makefile index 28c00ad2d..0ec036ebd 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -5,7 +5,8 @@ TESTDIR := $(CURDIR) CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) -I$(daemondir) \ -DTESTCONFDIR=\"$(TESTDIR)/conf.d\" -CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) +CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) \ + $(if $(shell [ $(CMOCKA_VERSION) -ge 131072 ] && echo yes),-Wno-error=deprecated-declarations) LIBDEPS += -L. -L $(mpathutildir) -L$(mpathcmddir) -lmultipath -lmpathutil -lmpathcmd -lcmocka TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ From 02ce277bb1a98f06c924664c53c51c974cd9e7e8 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 1 Dec 2025 22:02:11 -0500 Subject: [PATCH 20/37] multipath-tools man pages: fix multipathd commands keyword ordering multipathd now has a fixed ordering of the keywords. Specifically, verbs must come first. Fix the man page to reflect the ordering. Fixes: f812466f6 ("multipathd: more robust command parsing") Signed-off-by: Benjamin Marzinski Reviewed-by: Martin Wilck (cherry picked from commit f3ba2e719567d5f21076e90aea9ba10b04004abd) --- multipathd/multipathd.8.in | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in index 8815e099f..7ffb8d4c4 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -344,48 +344,48 @@ will not be disabled when the daemon stops. Restores configured queue_without_daemon mode. . .TP -.B map|multipath $map setprstatus +.B setprstatus map|multipath $map Enable persistent reservation management on $map. . .TP -.B map|multipath $map unsetprstatus +.B unsetprstatus map|multipath $map Disable persistent reservation management on $map. . .TP -.B map|multipath $map getprstatus +.B getprstatus map|multipath $map Get the current persistent reservation management status of $map. . .TP -.B map|multipath $map getprkey +.B getprkey map|multipath $map Get the current persistent reservation key associated with $map. . .TP -.B map|multipath $map setprkey key $key +.B setprkey map|multipath $map key $key Set the persistent reservation key associated with $map to $key in the \fIprkeys_file\fR. This key will only be used by multipathd if \fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. . .TP -.B map|multipath $map unsetprkey +.B unsetprkey map|multipath $map Remove the persistent reservation key associated with $map from the \fIprkeys_file\fR. This will only unset the key used by multipathd if \fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. . .TP -.B path $path setmarginal +.B setmarginal path $path move $path to a marginal pathgroup. The path will remain in the marginal path group until \fIunsetmarginal\fR is called. This command will only work if \fImarginal_pathgroups\fR is enabled and there is no Shaky paths detection method configured (see the multipath.conf man page for details). . .TP -.B path $path unsetmarginal +.B unsetmarginal path $path return marginal path $path to its normal pathgroup. This command will only work if \fImarginal_pathgroups\fR is enabled and there is no Shaky paths detection method configured (see the multipath.conf man page for details). . .TP -.B map $map unsetmarginal +.B unsetmarginal map $map return all marginal paths in $map to their normal pathgroups. This command will only work if \fImarginal_pathgroups\fR is enabled and there is no Shaky paths detection method configured (see the multipath.conf man page for details). From 80a1ce0f28b4b7dac8d5e78d6eae545bfed24737 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Wed, 26 Nov 2025 22:16:21 +0100 Subject: [PATCH 21/37] libmultipath: don't access path members in free_pgvec() It can happen that a path group contains references to paths that are already freed. If we access pp->pgindex in such a case, a use-after-free occurs. In particular, this occurs if we call remove_map() from configure() -> coalesce_paths(), and some paths are freed in orphan_paths() because they are in INIT_PARTIAL or INIT_REMOVED state. The paths of the removed map may still be referenced by maps in the "old" mpvec in configure(). The UAF occurs when configure() calls remove_maps(vecs). This code has been introduced in cd912cf ("libmultipath: fix handling of pp->pgindex"). The commit message stated: "The hunk in group_paths is mostly redundant with the hunk in free_pgvec(), but because we're looping over pg->paths in the former and over pg->pgp in the latter, I think it's better too play safe". It turns out that it would have been better not to "play safe" here. No caller of free_pgvec() requires the pgindex to be reset. For the functions in pgpolicies.c, the reset of pgindex is redundant, as remarked in cd912cf. disassemble_map() will set the pgindex later anyway, and update_multipath_strings() will call disassemble_map(). The other callers remove the struct multipath, in which case the paths will eventually be orphaned or freed (except for the special case of coalesce_paths() mentioned above). Fixes: cd912cf ("libmultipath: fix handling of pp->pgindex") Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 7a07023b59065e301bde5e4c8cd405f7b95647f2) --- libmultipath/structs.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/libmultipath/structs.c b/libmultipath/structs.c index dfa547bb3..ee02b7aca 100644 --- a/libmultipath/structs.c +++ b/libmultipath/structs.c @@ -239,18 +239,8 @@ free_pgvec (vector pgvec, enum free_path_mode free_paths) if (!pgvec) return; - vector_foreach_slot(pgvec, pgp, i) { - - /* paths are going to be re-grouped, reset pgindex */ - if (free_paths != FREE_PATHS) { - struct path *pp; - int j; - - vector_foreach_slot(pgp->paths, pp, j) - pp->pgindex = 0; - } + vector_foreach_slot (pgvec, pgp, i) free_pathgroup(pgp, free_paths); - } vector_free(pgvec); } From efb23f577fb3a828b6a423aaebf42559ee1b685a Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Wed, 10 Dec 2025 20:00:33 +0100 Subject: [PATCH 22/37] multipathd: join the init_unwinder dummy thread This closes a minor memory leak (thread-local storage of the dummy thread is never freed). Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 29f262b7c7ee4ba1b384eac76be956b3efbfe99f) --- multipathd/init_unwinder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/multipathd/init_unwinder.c b/multipathd/init_unwinder.c index b1cd283d5..d39e4282f 100644 --- a/multipathd/init_unwinder.c +++ b/multipathd/init_unwinder.c @@ -34,5 +34,7 @@ int init_unwinder(void) pthread_mutex_unlock(&dummy_mtx); - return pthread_cancel(dummy); + rc = pthread_cancel(dummy); + pthread_join(dummy, NULL); + return rc; } From 4f967e2b3a1a61e18391b9c5911329d748fd8722 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Wed, 10 Dec 2025 23:39:02 +0100 Subject: [PATCH 23/37] kpartx: fix some memory leaks These leaks were reported by LeakSanitizer. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 8c39e60cba6c6ce6f9153f3d219574fbdb8e6ea0) --- kpartx/kpartx.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c index a1495e55e..7ec89b479 100644 --- a/kpartx/kpartx.c +++ b/kpartx/kpartx.c @@ -227,6 +227,11 @@ xmalloc (size_t size) { return t; } +static void cleanup_charp(char **p) +{ + free(*p); +} + int main(int argc, char **argv){ int i, j, m, n, op, off, arg, c, d, ro=0; @@ -237,10 +242,10 @@ main(int argc, char **argv){ char *type, *diskdevice, *device, *progname; int verbose = 0; char partname[PARTNAME_SIZE], params[PARTNAME_SIZE + 16]; - char * loopdev = NULL; - char * delim = NULL; - char *uuid = NULL; - char *mapname = NULL; + char *loopdev __attribute__((cleanup(cleanup_charp))) = NULL; + char *delim __attribute__((cleanup(cleanup_charp))) = NULL; + char *uuid __attribute__((cleanup(cleanup_charp))) = NULL; + char *mapname __attribute__((cleanup(cleanup_charp))) = NULL; int hotplug = 0; int loopcreated = 0; struct stat buf; @@ -292,7 +297,9 @@ main(int argc, char **argv){ verbose = 1; break; case 'p': - delim = optarg; + delim = strdup(optarg); + if (!delim) + exit(1); break; case 'l': what = LIST; @@ -674,7 +681,6 @@ main(int argc, char **argv){ if (verbose) fprintf(stderr, "loop deleted : %s\n", device); } - end: dm_lib_exit(); From b2c4fa40058f18e146929b756767e5b8dde7553a Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Thu, 15 Jan 2026 23:08:39 +0100 Subject: [PATCH 24/37] kpartx: avoid double-free of mapname The variable mapname is sometimes allocated and sometimes not. To avoid double-free and still free allocated memory cleanly, introduce a helper pointer for storing possibly allocated memory. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 02e0933b1ea022c24d4d4aa2233082324b2771a1) --- kpartx/kpartx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c index 7ec89b479..6f2ec4ea0 100644 --- a/kpartx/kpartx.c +++ b/kpartx/kpartx.c @@ -245,7 +245,8 @@ main(int argc, char **argv){ char *loopdev __attribute__((cleanup(cleanup_charp))) = NULL; char *delim __attribute__((cleanup(cleanup_charp))) = NULL; char *uuid __attribute__((cleanup(cleanup_charp))) = NULL; - char *mapname __attribute__((cleanup(cleanup_charp))) = NULL; + char *_mapname __attribute__((cleanup(cleanup_charp))) = NULL; + char *mapname; int hotplug = 0; int loopcreated = 0; struct stat buf; @@ -388,11 +389,15 @@ main(int argc, char **argv){ off = find_devname_offset(device); if (!loopdev) { - mapname = dm_mapname(major(buf.st_rdev), minor(buf.st_rdev)); - if (mapname) - uuid = dm_mapuuid(mapname); + _mapname = dm_mapname(major(buf.st_rdev), minor(buf.st_rdev)); + if (_mapname) + uuid = dm_mapuuid(_mapname); } + mapname = _mapname; + if (!mapname) + mapname = device + off; + /* * We are called for a non-DM device. * Make up a fake UUID for the device, unless "-d -f" is given. @@ -402,9 +407,6 @@ main(int argc, char **argv){ if (!uuid && !(what == DELETE && force_devmap)) uuid = nondm_create_uuid(buf.st_rdev); - if (!mapname) - mapname = device + off; - if (delim == NULL) { delim = xmalloc(DELIM_SIZE); memset(delim, 0, DELIM_SIZE); From aaa7074446be8ea7db6e9d698446033ba8179021 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 9 Jan 2026 15:26:48 +0100 Subject: [PATCH 25/37] libmultipath: warn only once in scsi_tmo_error_msg() The intention of this code was to warn only once for each unsupported protocol. But the condition statement is missing. Fixes: 6ad77db ("libmultipath: Set the scsi timeout parameters by path") Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 958c826862d04779a7405349b7c75db8fd0ddad1) (cherry picked from commit a44bea0c9e031dac16fb9e9ddeebc5f2df52def8) --- libmultipath/discovery.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 31db8758b..6d5fea635 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -880,6 +880,8 @@ scsi_tmo_error_msg(struct path *pp) STRBUF_ON_STACK(proto_buf); unsigned int proto_id = bus_protocol_id(pp); + if (is_bit_set_in_bitfield(proto_id, bf)) + return; snprint_path_protocol(&proto_buf, pp); condlog(2, "%s: setting scsi timeouts is unsupported for protocol %s", pp->dev, get_strbuf_str(&proto_buf)); From 5fc97b0d6c9350f49ba70f5a72e58866272f2e51 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 9 Jan 2026 18:23:52 +0100 Subject: [PATCH 26/37] multipath-tools: compile with -fno-strict-aliasing multipath-tools uses container_of() and similar macros, which imply casts between different types, which isn't stricly compliant with strict aliasing rules. The issue that lead to the previous commit "libmpathutil: use union for bitfield" was one example where this can fail. While that one could be fixed relatively easily, it shows that surprises can happen any time when we compile our code with strict aliasing enabled. This can be seen clearly when we compile with "-fstrict-aliasing -Wstrict-aliasing=1" (note that the bitfield problem is only reported by gcc with "-Wstrict-aliasing=1", other levels of aliasing detection miss it with gcc 15). Use -fno-strict-aliasing to disable it. The kernel does the same. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 1ef540a323ab37993efba517ca150715e3ef42d7) (cherry picked from commit 579a66714be3b66c84be595d23f3c471d3b40511) --- Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index 3dbcdcfad..539415dac 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -122,7 +122,7 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) $(D_CMOCKA_VERSION) \ -DWSTRINGOP_TRUNCATION=$(if $(WSTRINGOP_TRUNCATION),1,0) \ -MMD -MP CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions + -fexceptions -fno-strict-aliasing BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared From 6c4608c779b4741f836a3b0fe05030d0dbda2aec Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 16 Jan 2026 11:44:55 +0100 Subject: [PATCH 27/37] multipathd: fix an uninitialized variable warning This isn't necessary in practice, but it fixes a compile warning. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit c032ba1e013283f1171817e8524b92d5f9814113) (cherry picked from commit cd8116755679f105c8c9eeb1e32ebc51fdf9f436) --- multipathd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multipathd/main.c b/multipathd/main.c index afa42c3ce..ddffc4dfa 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -3799,7 +3799,7 @@ child (__attribute__((unused)) void *param) int rc; struct config *conf; char *envp; - enum daemon_status state; + enum daemon_status state = DAEMON_INIT; int exit_code = 1; int fpin_marginal_paths = 0; From a6be30eade82dc0c451b84e11b40759f469025e0 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 16 Jan 2026 11:37:41 +0100 Subject: [PATCH 28/37] Makefiles: add "ASAN=1" make parameter for AddressSanitizer It's now possible to enable AddressSanitizer by passing the parameter `ASAN=1` on the "make" command line. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit 5e5d2102f7a409d2cc9165605d0117457bc9fe41) (cherry picked from commit 56a2bba6851d2ccd7bbac023bd4c4a47345d6864) --- .github/actions/spelling/expect.txt | 4 ++++ Makefile.inc | 7 +++++-- README.md | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index cddf09c27..441ab8f3b 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -6,6 +6,7 @@ alloc alltgpt alua aptpl +ASAN ascq ata autoconfig @@ -76,6 +77,7 @@ getrlimit getuid github gitlab +google GPT hbtl hds @@ -191,6 +193,8 @@ rpmbuild rport rtpi rtprio +sanitizer +sanitizers sas sbp scsi diff --git a/Makefile.inc b/Makefile.inc index 539415dac..8356254a8 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -9,6 +9,9 @@ # Uncomment to disable dmevents polling support # ENABLE_DMEVENTS_POLL = 0 # +# Use ASAN=1 on make command line to enable address sanitizer +ASAN := +# # Readline library to use, libedit, libreadline, or empty # Caution: Using libreadline may make the multipathd binary undistributable, # see https://github.com/opensvc/multipath-tools/issues/36 @@ -122,11 +125,11 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) $(D_CMOCKA_VERSION) \ -DWSTRINGOP_TRUNCATION=$(if $(WSTRINGOP_TRUNCATION),1,0) \ -MMD -MP CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions -fno-strict-aliasing + -fexceptions -fno-strict-aliasing $(if $(ASAN),-fsanitize=address) BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared -LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs +LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs $(if $(ASAN),-lasan) BIN_LDFLAGS := -pie # Source code directories. Don't modify. diff --git a/README.md b/README.md index 530caed7d..8ff139c7a 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,9 @@ See "Passing standard compiler flags" below for an exception. The following variables can be passed to the `make` command line: * `V=1`: enable verbose build. + * `ASAN=1`: Enable + [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer) + during build for debugging memory allocation. This is off by default. * `plugindir="/some/path"`: directory where libmultipath plugins (path checkers, prioritizers, and foreign multipath support) will be looked up. This used to be the run-time option `multipath_dir` in earlier versions. From 7d4522078b3260d30ded3edbb57745aa9734ccf2 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Fri, 16 Jan 2026 11:39:22 +0100 Subject: [PATCH 29/37] Makefiles: add "OPT=" make parameter Our OPTFLAGS variable contains stack protection options which are intended to be overridable by distribution build scripts. When developers just want to experiment with optimization levels, they often just want to modify the `-O` level. Introduce a variable `OPT` that allows to do just that by passing e.g. `OPT=-O0` to the `make` command line. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski (cherry picked from commit c94c65cc7357ca609e46438bff84a1a4bd82268e) (cherry picked from commit 47bee74edb37fa10a301d90c900fd4a064b70afa) --- Makefile.inc | 5 ++++- README.md | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index 8356254a8..c6aa6eda2 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,6 +12,9 @@ # Use ASAN=1 on make command line to enable address sanitizer ASAN := # +# Override on make command line if desired +OPT := -O2 + # Readline library to use, libedit, libreadline, or empty # Caution: Using libreadline may make the multipathd binary undistributable, # see https://github.com/opensvc/multipath-tools/issues/36 @@ -105,7 +108,7 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ echo "modprobe@dm_multipath.service") -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +OPTFLAGS := $(OPT) -g $(STACKPROT) --param=ssp-buffer-size=4 # Set WARN_ONLY=1 to avoid compilation erroring out due to warnings. Useful during development. WARN_ONLY := diff --git a/README.md b/README.md index 8ff139c7a..888998b7e 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,12 @@ See "Passing standard compiler flags" below for an exception. The following variables can be passed to the `make` command line: * `V=1`: enable verbose build. + * `OPT=`: set optimization flags. You may want to set `OPT="-O0"` for + debugging, for example. The default is `-O2`. Note that it is also + possible to set `OPTFLAGS`, which takes precedence over `OPT`. `OPTFLAGS` + sets additional options by default, which are intended for distribution + build environments to override. For quick customization of the optimization + level, use `OPT`. * `ASAN=1`: Enable [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer) during build for debugging memory allocation. This is off by default. From e76073ea9dd2ddd590e9ba1843e66db16bb5c21f Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 19 Jan 2026 11:45:40 +0100 Subject: [PATCH 30/37] multipath-tools tests: suppress a compiler warning for vpd.c The following warning has been observed with gcc 15.2.1 on Fedora Rawhide: vpd.c: In function 'create_vpd83.constprop': vpd.c:265:55: error: '%s' directive output truncated writing 64 bytes into a region of size 40 [-Werror=format-truncation=] 265 | len = snprintf((char *)(desc + 4), maxlen, "%s%s", | ^~ In file included from /usr/include/stdio.h:974, from vpd.c:8: In function 'snprintf', inlined from 'create_scsi_string_desc' at vpd.c:265:8, inlined from 'create_vpd83.constprop' at vpd.c:313:7: /usr/include/bits/stdio2.h:68:10: note: '__builtin___snprintf_chk' output 65 or more bytes into a destination of size 40 68 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 | __glibc_objsize (__s), __fmt, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 | __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors Fix it. Signed-off-by: Martin Wilck (cherry picked from commit 888187ed1336cf6e938d625c59593661bb359882) (cherry picked from commit 283b1c2a165432eecfd4fb67142d7a2304cf8626) --- tests/vpd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/vpd.c b/tests/vpd.c index e3212e614..a72865337 100644 --- a/tests/vpd.c +++ b/tests/vpd.c @@ -262,8 +262,20 @@ static int create_scsi_string_desc(unsigned char *desc, assert_in_range(type, STR_EUI, STR_IQN); assert_true(maxlen % 4 == 0); +#if defined(__GNUC__) && __GNUC__ >= 15 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-truncation=" + /* + * This is called from test_vpd_str_XYZ() functions, where + * we deliberately use the overlong input string test_id. + * So format truncation is expected here. + */ +#endif len = snprintf((char *)(desc + 4), maxlen, "%s%s", str_prefix[type], id); +#if defined(__GNUC__) && __GNUC__ >= 15 +#pragma GCC diagnostic pop +#endif if (len > maxlen) len = maxlen; /* zero-pad */ @@ -451,7 +463,6 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \ int n, ret; \ int exp_len; \ int type = typ & STR_MASK; \ - \ n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, \ 8, typ, len); \ exp_len = len - strlen(str_prefix[type]); \ From 5a0a0e9c92d19f695e2f23d51eb00632d5fe305a Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Tue, 20 Jan 2026 16:01:50 +0100 Subject: [PATCH 31/37] Spelling: pull in changes from master branch Signed-off-by: Martin Wilck --- .github/actions/spelling/expect.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 441ab8f3b..481df933d 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -14,6 +14,7 @@ autodetected autoresize barbie BINDIR +bitfield blkid bmarzins Bsymbolic @@ -60,12 +61,14 @@ ECKD emc Engenio EVPD +Exos failback failover fds fexceptions FFFFFFFF fge +fno followover forcequeueing fpin @@ -123,6 +126,7 @@ libudevdir liburcu linux LIO +lld lpthread Lun lvm @@ -142,12 +146,13 @@ multipathing multipaths multiqueue mwilck +NFINIDAT NOLOG nompath NOSCAN Nosync nvme -NFINIDAT +Nytro OBJDEPS oneshot ontap @@ -157,8 +162,10 @@ OPTFLAGS paramp partx pathgroup +pathlist petabytes pgpolicy +pgvec plugindir PNR ppc @@ -193,14 +200,12 @@ rpmbuild rport rtpi rtprio -sanitizer sanitizers sas sbp scsi SCST sda -sdc Seagate setmarginal setprkey @@ -222,12 +227,11 @@ suse svg switchgroup sys +SYSDIR sysfs sysinit -systemd tcp terabytes -SYSDIR TESTDEPS testname tgill @@ -262,11 +266,11 @@ VNX vpd VSN wakka -watchdogsec weightedpath wholedisk Wilck wildcards +Wno workflows wrt wwid From 3d232f836a57862b1777b7d7fa87e832953c1ac6 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Tue, 20 Jan 2026 13:54:39 +0100 Subject: [PATCH 32/37] Update NEWS.md for 0.12.2 Signed-off-by: Martin Wilck --- NEWS.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/NEWS.md b/NEWS.md index f7d15d26e..35a7b6c75 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,38 @@ release. These bug fixes will be tracked in stable branches. See [README.md](README.md) for additional information. +## multipath-tools 0.12.2, 2026/01 + +### Bug fixes + +* Fix `mpathpersist --report-capabilities` output. Fixes 0.5.0. +* Fix command descriptions in the multipathd man page. Fixes 0.9.2. +* Fix an undefined symbol error with the LLVM lld linker. + Fixes [#132](https://github.com/opensvc/multipath-tools/issues/132), 0.10.0. +* Fix ISO C23 compatibility issue causing errors with new compilers. +* Fix use-after-free error in free_pgvec(). + Fixes [#128](https://github.com/opensvc/multipath-tools/issues/128), 0.12.0. +* Fix memory leak caused by not joining the "init unwinder" thread. + Fixes 0.8.6. +* Fix memory leaks in kpartx. Fixes any version. +* Print the warning "setting scsi timeouts is unsupported for protocol" only + once per protocol. Fixes 0.9.0. +* Make sure multipath-tools is compiled with the compiler flag + `-fno-strict-aliasing`. This turns out to be necessary because our code + uses techniques like `container_of()` which don't work well with + strict aliasing rules. + Fixes [#130](https://github.com/opensvc/multipath-tools/issues/130). + +### Other changes + +* Hardware table: add Seagate Exos and Nytro series. +* Avoid joining threads twice with liburcu 0.14.0 and newer. +* CI updates (GitHub workflows). +* Fix CI for cmocka 2.0 by adding the `-Wno-error=deprecated-declarations` + compiler flag. + Fixes [#129](https://github.com/opensvc/multipath-tools/issues/129) +* Add the ASAN=1 and OPT= make variables (see README.md). + ## multipath-tools 0.12.1, 2025/10 ### Other changes From ab0dcc0495ca268c7605136613d919ec793d4190 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Tue, 20 Jan 2026 13:55:29 +0100 Subject: [PATCH 33/37] libmultipath: bump version to 0.12.2 Signed-off-by: Martin Wilck --- libmultipath/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/version.h b/libmultipath/version.h index 9dc860c8e..15f5556d2 100644 --- a/libmultipath/version.h +++ b/libmultipath/version.h @@ -11,9 +11,9 @@ #ifndef VERSION_H_INCLUDED #define VERSION_H_INCLUDED -#define VERSION_CODE 0x000C01 +#define VERSION_CODE 0x000C02 /* MMDDYY, in hex */ -#define DATE_CODE 0x0A1B19 +#define DATE_CODE 0x01141A #define PROG "multipath-tools" From 4299f78ab48fe84be70695fcfe9f71096de9c5e6 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 21 Jan 2026 16:03:11 -0500 Subject: [PATCH 34/37] multipathd: finish initalization of paths added while offline If a path in a mulitpath device is offline while multipathd is reconfigured, it will get added to the updated multipath device, just like it was in the old multipath device. However the device will still be in the INIT_NEW state because it can't get initilized while offline. This is different than the INIT_PARTIAL state because the path was discovered in path_discovery(). INIT_PARTIAL is for paths that multipathd did not discover in path_discovery() or receive a uevent for, but are part of a multipath device that was added, and which should receive a uevent shortly. There is no reason to expect a uevent for these offline paths. When the path comes back online, multipathd will run the checker and prioritizer on it. The only two pathinfo checks that won't happen are the DI_WWID and DI_IOCTL ones. Modify pathinfo() to make sure that if DI_IOCTL was skipped for offline paths, it gets called the next time pathinfo() is called after the fd can be opened. Also, make sure that when one of these offline paths becomes usable, its WWID is rechecked. With those changes, all the DI_ALL checks will be accounted for, and the path can be marked INIT_OK. Signed-off-by: Benjamin Marzinski Reviewed-by: Martin Wilck (cherry picked from commit 1942fb136a388c9bdd964741116ed0a89cf9e198) --- libmultipath/discovery.c | 2 ++ multipathd/main.c | 54 ++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 6d5fea635..4da8ea4a9 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -2559,6 +2559,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) * Recoverable error, for example faulty or offline path */ pp->chkrstate = pp->state = PATH_DOWN; + if (mask & DI_IOCTL && pp->ioctl_info == IOCTL_INFO_NOT_REQUESTED) + pp->ioctl_info = IOCTL_INFO_SKIPPED; if (pp->initialized == INIT_NEW || pp->initialized == INIT_FAILED) memset(pp->wwid, 0, WWID_SIZE); diff --git a/multipathd/main.c b/multipathd/main.c index ddffc4dfa..947ed9834 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -2520,6 +2520,26 @@ sync_mpp(struct vectors * vecs, struct multipath *mpp, unsigned int ticks) return do_sync_mpp(vecs, mpp); } +/* + * pp->wwid should never be empty when this function is called, but if it + * is, this function can set it. + */ +static bool new_path_wwid_changed(struct path *pp, int state) +{ + char wwid[WWID_SIZE]; + + strlcpy(wwid, pp->wwid, WWID_SIZE); + if (get_uid(pp, state, pp->udev, 1) != 0) { + strlcpy(pp->wwid, wwid, WWID_SIZE); + return false; + } + if (strlen(wwid) && strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { + strlcpy(pp->wwid, wwid, WWID_SIZE); + return true; + } + return false; +} + static int update_path_state (struct vectors * vecs, struct path * pp) { @@ -2548,14 +2568,34 @@ update_path_state (struct vectors * vecs, struct path * pp) pp->tick = 1; return CHECK_PATH_SKIPPED; } - if (pp->recheck_wwid == RECHECK_WWID_ON && - (newstate == PATH_UP || newstate == PATH_GHOST) && + + if ((newstate == PATH_UP || newstate == PATH_GHOST) && ((pp->state != PATH_UP && pp->state != PATH_GHOST) || - pp->dmstate == PSTATE_FAILED) && - check_path_wwid_change(pp)) { - condlog(0, "%s: path wwid change detected. Removing", pp->dev); - return handle_path_wwid_change(pp, vecs)? CHECK_PATH_REMOVED : - CHECK_PATH_SKIPPED; + pp->dmstate == PSTATE_FAILED)) { + bool wwid_changed = false; + + if (pp->initialized == INIT_NEW) { + /* + * Path was added to map while offline, mark it as + * initialized. + * DI_SYSFS was checked when the path was added + * DI_IOCTL was checked when the checker was selected + * DI_CHECKER just got checked + * DI_WWID is about to be checked + * DI_PRIO will get checked at the end of this checker + * loop + */ + pp->initialized = INIT_OK; + wwid_changed = new_path_wwid_changed(pp, newstate); + } else if (pp->recheck_wwid == RECHECK_WWID_ON) + wwid_changed = check_path_wwid_change(pp); + if (wwid_changed) { + condlog(0, "%s: path wwid change detected. Removing", + pp->dev); + return handle_path_wwid_change(pp, vecs) + ? CHECK_PATH_REMOVED + : CHECK_PATH_SKIPPED; + } } if ((newstate != PATH_UP && newstate != PATH_GHOST && newstate != PATH_PENDING) && (pp->state == PATH_DELAYED)) { From 2a0a131255c48e0e85e0e4b48167c895ba9938ba Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 21 Jan 2026 16:03:13 -0500 Subject: [PATCH 35/37] multipathd: print path offline message even without a checker If a path has a checker selected and is offline, multipathd will print a "path offline" message. However if the checker isn't selected, for instance because multipathd was started or reconfigured while the path was offline, multipathd was not printing the "path offline" message. Fix that. Signed-off-by: Benjamin Marzinski Reviewed-by: Martin Wilck (cherry picked from commit 1a364a1699baec8cb886c0e82a5e4699142ac153) --- multipathd/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/multipathd/main.c b/multipathd/main.c index 947ed9834..efb3df9f3 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -94,12 +94,11 @@ void * mpath_pr_event_handler_fn (void * ); #define LOG_MSG(lvl, pp) \ do { \ - if (pp->mpp && checker_selected(&pp->checker) && \ - lvl <= libmp_verbosity) { \ - if (pp->sysfs_state == PATH_DOWN) \ + if (pp->mpp && lvl <= libmp_verbosity) { \ + if (pp->sysfs_state != PATH_UP) \ condlog(lvl, "%s: %s - path offline", \ pp->mpp->alias, pp->dev); \ - else { \ + else if (checker_selected(&pp->checker)) { \ const char *__m = \ checker_message(&pp->checker); \ \ From edbe49492e792de720965169bb4b86d69905afd4 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Thu, 22 Jan 2026 20:53:17 +0100 Subject: [PATCH 36/37] update NEWS.md Signed-off-by: Martin Wilck --- NEWS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.md b/NEWS.md index 35a7b6c75..19dccf380 100644 --- a/NEWS.md +++ b/NEWS.md @@ -30,6 +30,11 @@ See [README.md](README.md) for additional information. uses techniques like `container_of()` which don't work well with strict aliasing rules. Fixes [#130](https://github.com/opensvc/multipath-tools/issues/130). +* Fix initialization of paths that were offline during path detection. +* Fix printing the "path offline" log message for offline paths that don't + have a path checker configured. +* kpartx: Fix freeing static buffer when operating on regular files. + Fixes [#139](https://github.com/opensvc/multipath-tools/issues/139). ### Other changes From 44c022737b0b07d5a8180eef63474464b3cc1774 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 26 Jan 2026 12:29:31 +0100 Subject: [PATCH 37/37] kpartx: fix segfault when operating on regular files The following problem has been introduced in multipath-tools 0.14.0: > truncate -s1G /tmp/img > kpartx -a /tmp/img double free or corruption (out) Aborted (core dumped) kpartx -a /tmp/img Fix it by always allocating "uuid" on the heap, rather than using a static char array. Fixes: 8c39e60 ("kpartx: fix some memory leaks") Fixes: https://github.com/opensvc/multipath-tools/issues/139 Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski --- kpartx/devmapper.c | 16 ++++++++-------- kpartx/kpartx.c | 5 ++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c index d49c6806a..45dac585e 100644 --- a/kpartx/devmapper.c +++ b/kpartx/devmapper.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2004, 2005 Christophe Varoqui */ +#define _GNU_SOURCE #include #include #include @@ -699,14 +700,13 @@ int dm_find_part(const char *parent, const char *delim, int part, char *nondm_create_uuid(dev_t devt) { -#define NONDM_UUID_BUFLEN (34 + sizeof(NONDM_UUID_PREFIX) + \ - sizeof(NONDM_UUID_SUFFIX)) - static char uuid_buf[NONDM_UUID_BUFLEN]; - snprintf(uuid_buf, sizeof(uuid_buf), "%s_%u:%u_%s", - NONDM_UUID_PREFIX, major(devt), minor(devt), - NONDM_UUID_SUFFIX); - uuid_buf[NONDM_UUID_BUFLEN-1] = '\0'; - return uuid_buf; + char *uuid; + + if (asprintf(&uuid, "%s_%u:%u_%s", NONDM_UUID_PREFIX, major(devt), + minor(devt), NONDM_UUID_SUFFIX) >= 0) + return uuid; + else + return NULL; } int nondm_parse_uuid(const char *uuid, unsigned int *major, unsigned int *minor) diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c index 6f2ec4ea0..3724b7bf4 100644 --- a/kpartx/kpartx.c +++ b/kpartx/kpartx.c @@ -404,8 +404,11 @@ main(int argc, char **argv){ * This allows deletion of partitions created with older kpartx * versions which didn't use the fake UUID during creation. */ - if (!uuid && !(what == DELETE && force_devmap)) + if (!uuid && !(what == DELETE && force_devmap)) { uuid = nondm_create_uuid(buf.st_rdev); + if (!uuid) + exit(1); + } if (delim == NULL) { delim = xmalloc(DELIM_SIZE);