diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 51c8a1307..6abf55c81 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 @@ -14,6 +15,7 @@ autoresize backported barbie BINDIR +bitfield blkid bmarzins Bsymbolic @@ -60,12 +62,14 @@ ECKD emc Engenio EVPD +Exos failback failover fds fexceptions FFFFFFFF fge +fno followover forcequeueing fpin @@ -77,6 +81,7 @@ getrlimit getuid github gitlab +google GPT hbtl hds @@ -122,6 +127,7 @@ libudevdir liburcu linux LIO +lld lpthread Lun lvm @@ -141,12 +147,13 @@ multipathing multipaths multiqueue mwilck +NFINIDAT NOLOG nompath NOSCAN Nosync nvme -NFINIDAT +Nytro OBJDEPS oneshot ontap @@ -156,8 +163,10 @@ OPTFLAGS paramp partx pathgroup +pathlist petabytes pgpolicy +pgvec plugindir PNR ppc @@ -192,12 +201,12 @@ rpmbuild rport rtpi rtprio +sanitizers sas sbp scsi SCST sda -sdc Seagate setmarginal setprkey @@ -219,12 +228,11 @@ suse svg switchgroup sys +SYSDIR sysfs sysinit -systemd tcp terabytes -SYSDIR TESTDEPS testname tgill @@ -259,11 +267,11 @@ VNX vpd VSN wakka -watchdogsec weightedpath wholedisk Wilck wildcards +Wno workflows wrt wwid 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 diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml index 238a06bf3..8f9a9dbf3 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: > @@ -38,12 +38,13 @@ 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: 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: @@ -51,7 +52,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) @@ -86,9 +87,10 @@ 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$(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 b1282493f..adc2081f1 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,8 +42,9 @@ 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 + 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 4f568131c..2fb5327d4 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: @@ -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 678d0d2a3..30e5471d3 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 @@ -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 @@ -32,7 +33,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 4cdc784a1..fdcfaac69 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: @@ -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: @@ -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 @@ -92,7 +92,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..b8c770e40 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: @@ -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 @@ -57,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 }} @@ -65,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' diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml index c453446a6..806275a13 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: @@ -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 @@ -53,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 }} @@ -61,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 6b38fa712..9e89780b1 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -26,7 +26,6 @@ on: jobs: stable: - runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -36,8 +35,15 @@ jobs: - debian-bullseye - debian-bookworm - debian-trixie - - fedora-42 - - opensuse-leap + - 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 @@ -45,24 +51,29 @@ 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 + 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 + command: -j$(nproc) -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 + command: -j$(nproc) -Orecurse READLINE=libreadline test + continue-on-error: true - name: create ${{ env.ARCHIVE_TGT }} if: ${{ matrix.os != 'debian-jessie' }} @@ -80,44 +91,113 @@ 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 + - name: fail + run: /bin/false + if: >- + ${{ ( matrix.os == 'debian-jessie' && + steps.test_jessie.outcome != 'success' ) || + ( matrix.os != 'debian-jessie' && + steps.test.outcome != 'success' ) }} clang: - runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: os: - - debian-jessie - debian-buster - debian-bullseye - debian-bookworm - debian-trixie - - fedora-42 - - opensuse-leap + - 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 + - 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 + command: -j$(nproc) -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 + command: -j$(nproc) -Orecurse READLINE=libreadline test + continue-on-error: true + + - name: create ${{ env.ARCHIVE_TGT }} + 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) + 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: - runs-on: ubuntu-22.04 needs: stable strategy: fail-fast: false @@ -128,8 +208,15 @@ jobs: - debian-bullseye - debian-bookworm - debian-trixie - - fedora-42 - - opensuse-leap + - 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 @@ -142,13 +229,13 @@ 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: ${{ 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 diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml index 503625e04..a4706e52e 100644 --- a/.github/workflows/rolling.yaml +++ b/.github/workflows/rolling.yaml @@ -29,24 +29,50 @@ on: jobs: rolling: - runs-on: ubuntu-22.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 + 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$(nproc) -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' diff --git a/Makefile.inc b/Makefile.inc index 65f6efc8c..05564f4ad 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -9,6 +9,12 @@ # Uncomment to disable dmevents polling support # ENABLE_DMEVENTS_POLL = 0 # +# 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 @@ -99,7 +105,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 := @@ -109,18 +115,18 @@ 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)\" \ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions + -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/NEWS.md b/NEWS.md index 56c24f0a9..bacf85362 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,36 @@ release. These bug fixes will be tracked in stable branches. See [README.md](README.md) for additional information. +## multipath-tools 0.11.4, 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 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.11.3, 2025/10 ### Other changes diff --git a/README.md b/README.md index 530caed7d..888998b7e 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,15 @@ 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. * `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. diff --git a/create-config.mk b/create-config.mk index e8fa391cc..14ab9ba00 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/kpartx/kpartx.c b/kpartx/kpartx.c index a1495e55e..6f2ec4ea0 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,11 @@ 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; + char *mapname; int hotplug = 0; int loopcreated = 0; struct stat buf; @@ -292,7 +298,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; @@ -381,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. @@ -395,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); @@ -674,7 +683,6 @@ main(int argc, char **argv){ if (verbose) fprintf(stderr, "loop deleted : %s\n", device); } - end: dm_lib_exit(); diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h index d94205f08..3a924dc22 100644 --- a/libmpathpersist/mpath_persist.h +++ b/libmpathpersist/mpath_persist.h @@ -107,7 +107,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/libmpathutil/parser.c b/libmpathutil/parser.c index b1db433f4..05784f9fd 100644 --- a/libmpathutil/parser.c +++ b/libmpathutil/parser.c @@ -153,7 +153,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 125597427..32c76f4c1 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/discovery.c b/libmultipath/discovery.c index b58515615..abf84486e 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -879,6 +879,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)); diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c index 925230422..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", @@ -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 */ diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version index a0c8bacab..359565a89 100644 --- a/libmultipath/libmultipath.version +++ b/libmultipath/libmultipath.version @@ -82,7 +82,6 @@ global: dm_geteventnr; dm_get_major_minor; dm_get_maps; - dm_get_multipath; dm_is_mpath; dm_mapname; dm_prereq; 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); diff --git a/libmultipath/version.h b/libmultipath/version.h index 1f1a41642..03d838fc1 100644 --- a/libmultipath/version.h +++ b/libmultipath/version.h @@ -20,9 +20,9 @@ #ifndef VERSION_H_INCLUDED #define VERSION_H_INCLUDED -#define VERSION_CODE 0x000B03 +#define VERSION_CODE 0x000B04 /* MMDDYY, in hex */ -#define DATE_CODE 0x0A1B19 +#define DATE_CODE 0x01141A #define PROG "multipath-tools" 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)); } } diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in index 126875c31..64d1eb56e 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in @@ -197,22 +197,23 @@ kernel multipath target: .RS .TP 12 .I "round-robin 0" -Loop through every path in the path group, sending the same amount of I/O to -each. Some aspects of behavior can be controlled with the attributes: -\fIrr_min_io\fR, \fIrr_min_io_rq\fR and \fIrr_weight\fR. +Choose the path for the next bunch of I/O by looping through every path in the +path group, sending \fBthe same number of I/O requests\fR to each path. Some +aspects of behavior can be controlled with the attributes: \fIrr_min_io\fR, +\fIrr_min_io_rq\fR and \fIrr_weight\fR. .TP .I "queue-length 0" -(Since 2.6.31 kernel) Choose the path for the next bunch of I/O based on the amount -of outstanding I/O to the path. +(Since 2.6.31 kernel) Choose the path for the next bunch of I/O based on \fBthe lowest +number of outstanding in-flight I/O requests\fR to the path. .TP .I "service-time 0" -(Since 2.6.31 kernel) Choose the path for the next bunch of I/O based on the amount -of outstanding I/O to the path and its relative throughput. +(Since 2.6.31 kernel) Choose the path for the next bunch of I/O based on \fBthe +lowest total size (in bytes) of outstanding in-flight I/O requests\fR to the path. .TP .I "historical-service-time 0" -(Since 5.8 kernel) Choose the path for the next bunch of I/O based on the -estimation of future service time based on the history of previous I/O submitted -to each path. +(Since 5.8 kernel) Choose the path for the next bunch of I/O with \fBa dynamic +algorithm based on the historical service time and the number of outstanding +in-flight I/O requests\fR to the path. .TP The default is: \fBservice-time 0\fR .RE 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; } diff --git a/multipathd/main.c b/multipathd/main.c index 21f55891c..c8f004c95 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); \ \ @@ -2488,6 +2487,26 @@ sync_mpp(struct vectors * vecs, struct multipath *mpp, unsigned int ticks) 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) { @@ -2516,14 +2535,33 @@ 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_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 (pp->mpp->synced_count == 0) { do_sync_mpp(vecs, pp->mpp); @@ -3654,18 +3692,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(); } @@ -3705,7 +3746,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; diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in index 7bc8806eb..cd0d4dda1 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -313,48 +313,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). 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 \ 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]); \