From 67196bdc205ca16d302d341a5e1d8fb33a8932ed Mon Sep 17 00:00:00 2001 From: TizenOpenSource Date: Fri, 13 Jan 2023 15:41:16 +0900 Subject: [PATCH] Imported Upstream version 0.9.4 --- .github/workflows/abi.yaml | 2 +- .github/workflows/build-and-unittest.yaml | 21 +- .github/workflows/coverity.yaml | 2 +- .github/workflows/foreign.yaml | 63 +++--- .github/workflows/multiarch.yaml | 80 +++++++ .github/workflows/native.yaml | 77 +------ .github/workflows/rolling.yaml | 33 +++ .gitignore | 2 + Makefile | 58 +++-- Makefile.inc | 246 ++++++++-------------- README.md | 82 ++++++-- create-config.mk | 170 +++++++++++++++ kpartx/Makefile | 52 +++-- kpartx/devmapper.c | 1 + kpartx/kpartx.c | 1 + kpartx/kpartx_id | 2 +- libdmmp/Makefile | 65 +++--- libdmmp/test/Makefile | 9 +- libmpathcmd/Makefile | 47 ++--- libmpathpersist/Makefile | 59 ++---- libmpathpersist/mpath_updatepr.c | 23 +- libmpathutil/Makefile | 55 +---- libmpathutil/parser.c | 109 +++++----- libmpathvalid/Makefile | 47 ++--- libmultipath/Makefile | 100 ++------- libmultipath/checkers/Makefile | 10 +- libmultipath/configure.c | 3 +- libmultipath/defaults.h | 2 +- libmultipath/devmapper.h | 2 +- libmultipath/dict.c | 117 +++++++++- libmultipath/discovery.c | 3 +- libmultipath/foreign/Makefile | 10 +- libmultipath/hwtable.c | 27 ++- libmultipath/lock.h | 9 + libmultipath/print.c | 8 +- libmultipath/prioritizers/Makefile | 12 +- libmultipath/propsel.c | 5 +- libmultipath/structs.c | 143 ++++++------- libmultipath/uevent.c | 1 + libmultipath/version.h | 4 +- mpathpersist/Makefile | 18 +- multipath/Makefile | 60 +++--- multipath/main.c | 3 +- multipath/multipath.conf.5 | 96 +++++---- multipathd/Makefile | 104 ++++----- multipathd/cli_handlers.c | 7 +- multipathd/fpin.h | 1 + multipathd/fpin_handlers.c | 7 +- multipathd/main.c | 1 + rules.mk | 18 ++ tests/Makefile | 36 ++-- tests/directio.c | 20 +- 52 files changed, 1163 insertions(+), 970 deletions(-) create mode 100644 .github/workflows/multiarch.yaml create mode 100644 .github/workflows/rolling.yaml create mode 100644 create-config.mk create mode 100644 rules.mk diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml index 89b971c..644fcb6 100644 --- a/.github/workflows/abi.yaml +++ b/.github/workflows/abi.yaml @@ -32,7 +32,7 @@ jobs: libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - name: create ABI - run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - name: save ABI uses: actions/upload-artifact@v1 with: diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml index a5a0717..abf17bf 100644 --- a/.github/workflows/build-and-unittest.yaml +++ b/.github/workflows/build-and-unittest.yaml @@ -11,6 +11,7 @@ jobs: bionic: runs-on: ubuntu-18.04 strategy: + fail-fast: false matrix: rl: ['', 'libreadline', 'libedit'] steps: @@ -32,11 +33,11 @@ jobs: libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - name: build - run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - name: test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) test + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - name: valgrind-test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - name: valgrind-results run: cat tests/*.vgr - name: clean-nonroot-artifacts @@ -46,6 +47,7 @@ jobs: focal-gcc10: runs-on: ubuntu-20.04 strategy: + fail-fast: false matrix: rl: ['', 'libreadline', 'libedit'] steps: @@ -65,11 +67,11 @@ jobs: - name: set CC run: echo CC=gcc-10 >> $GITHUB_ENV - name: build - run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - name: test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) test + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - name: valgrind-test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - name: valgrind-results run: cat tests/*.vgr - name: clean-nonroot-artifacts @@ -79,6 +81,7 @@ jobs: focal-clang10: runs-on: ubuntu-20.04 strategy: + fail-fast: false matrix: rl: ['', 'libreadline', 'libedit'] steps: @@ -98,11 +101,11 @@ jobs: - name: set CC run: echo CC=clang >> $GITHUB_ENV - name: build - run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - name: test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) test + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - name: valgrind-test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - name: valgrind-results run: cat tests/*.vgr - name: clean-nonroot-artifacts diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml index 3c6b382..321b94e 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 -O -j"$(grep -c ^processor /proc/cpuinfo)" + cov-build --dir cov-int make -Orecurse -j"$(grep -c ^processor /proc/cpuinfo)" - 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 bd4e9c1..2937b72 100644 --- a/.github/workflows/foreign.yaml +++ b/.github/workflows/foreign.yaml @@ -9,63 +9,62 @@ on: jobs: - build: + cross-build: runs-on: ubuntu-20.04 strategy: + fail-fast: false matrix: - os: [bullseye] - arch: ['ppc64le', 'aarch64', 's390x'] - container: mwilck/multipath-build-${{ matrix.os }}-${{ matrix.arch }} + os: [bullseye, sid] + arch: [ppc64le, arm64, s390x] + container: ghcr.io/mwilck/multipath-cross-debian_cross-${{ matrix.os }}-${{ matrix.arch }} steps: - name: checkout uses: actions/checkout@v1 - - name: build and test - if: ${{ matrix.arch == '' || matrix.arch == '-i386' }} - run: make test - name: build - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - # The build path is different between builder and runner - run: make TESTDIR=${{ github.workspace }}/tests test-progs - - name: archive - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + run: make -j8 -Orecurse TESTDIR=/build/tests test-progs + - name: create binary archive run: > tar cfv binaries.tar - Makefile* + Makefile* config.mk libmpathcmd/*.so* libmultipath/*.so* libmpathutil/*.so* libmultipath/checkers/*.so libmultipath/prioritizers/*.so libmultipath/foreign/*.so tests/lib tests/*-test tests/Makefile tests/*.so* - - uses: actions/upload-artifact@v1 - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + - name: upload binary archive + uses: actions/upload-artifact@v1 with: - name: multipath-${{ matrix.os }}-${{ matrix.arch }} + name: cross-${{ matrix.os }}-${{ matrix.arch }} path: binaries.tar test: runs-on: ubuntu-20.04 - needs: build + needs: cross-build strategy: + fail-fast: false matrix: - os: [bullseye] - arch: ['ppc64le', 'aarch64', 's390x'] + os: [bullseye, sid] + arch: [ppc64le, arm64, s390x] steps: - - name: get binaries + - name: set container arch + run: echo CONTAINER_ARCH="${{ matrix.arch }}" >> $GITHUB_ENV + if: ${{ matrix.arch != 'armhf' }} + - name: set container arch + run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV + if: ${{ matrix.arch == 'armhf' }} + - name: download binary archive uses: actions/download-artifact@v1 with: - name: multipath-${{ matrix.os }}-${{ matrix.arch }} - - name: unpack - run: tar xfv multipath-${{ matrix.os }}-${{ matrix.arch }}/binaries.tar + name: cross-${{ matrix.os }}-${{ matrix.arch }} + - name: unpack binary archive + run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/binaries.tar - name: enable foreign arch - run: sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset + uses: dbhi/qus/action@main - name: run tests - # GitHub actions doesn't support referencing docker images with - # context variables. Workaround: use mosteo-actions/docker-run action - # See https://github.community/t/expressions-in-docker-uri/16271 uses: mosteo-actions/docker-run@v1 with: - image: mwilck/multipath-run-${{ matrix.os }}-${{ matrix.arch }} - # The runner is an image that has "make" as entrypoint and uses - # github.workspace as both host dir and guest volume by default. - # See https://github.com/mosteo-actions/docker-run/blob/v1/action.yml - # So run "make -C tests" here + image: ghcr.io/mwilck/multipath-run-debian-${{ matrix.os }} + guest-dir: /build + host-dir: ${{ github.workspace }} command: -C tests + params: "--platform linux/${{ env.CONTAINER_ARCH }}" + pull-params: "--platform linux/${{ env.CONTAINER_ARCH }}" diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml new file mode 100644 index 0000000..513021b --- /dev/null +++ b/.github/workflows/multiarch.yaml @@ -0,0 +1,80 @@ +name: multiarch compile and unit test +on: + push: + branches: + - master + - queue + - tip + pull_request: + +jobs: + + build-current: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + os: + - alpine + - debian-sid + - opensuse-tumbleweed + - opensuse-leap + - fedora-rawhide + - centos-8 + - centos-7 + arch: [amd64, ppc64le, aarch64, s390x] + exclude: + - os: centos-8 + arch: s390x + - os: centos-7 + arch: s390x + include: + - os: alpine + arch: 386 + - os: alpine + arch: arm/v7 + - os: debian-sid + arch: 386 + - os: opensuse-tumbleweed + arch: 386 + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: enable foreign arch + uses: dbhi/qus/action@main + - name: compile and run unit tests + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + guest-dir: /build + host-dir: ${{ github.workspace }} + command: test + params: "--platform linux/${{ matrix.arch }}" + pull-params: "--platform linux/${{ matrix.arch }}" + + build-old: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + os: + - debian-buster + - debian-jessie + - ubuntu-trusty + arch: [amd64, 386] + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: enable foreign arch + uses: dbhi/qus/action@main + - name: compile and run unit tests + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + guest-dir: /build + host-dir: ${{ github.workspace }} + command: test + params: "--platform linux/${{ matrix.arch }}" + pull-params: "--platform linux/${{ matrix.arch }}" diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index 8b59920..a7ad4c8 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -11,13 +11,15 @@ jobs: stable: runs-on: ubuntu-20.04 strategy: + fail-fast: false matrix: - os: [buster, jessie, bullseye, fedora-36] - arch: ['', '-i386'] - exclude: - - os: fedora-36 - arch: '-i386' - container: mwilck/multipath-build-${{ matrix.os }}${{ matrix.arch }} + os: + - debian-buster + - debian-jessie + - debian-bullseye + - fedora-36 + - opensuse-leap + container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} steps: - name: checkout uses: actions/checkout@v1 @@ -27,75 +29,16 @@ jobs: - name: build and test (jessie) # On jessie, we use libreadline 5 (no licensing issue) if: ${{ matrix.os == 'jessie' }} - run: make READLINE=libreadline test + run: make -j -Orecurse READLINE=libreadline test - name: clean run: make clean - name: clang if: ${{ matrix.os != 'jessie' }} env: CC: clang - run: make test + run: make -j -Orecurse test - name: clang (jessie) if: ${{ matrix.os == 'jessie' }} env: CC: clang run: make READLINE=libreadline test - - rolling: - runs-on: ubuntu-20.04 - strategy: - matrix: - os: ['debian:sid', 'alpine', 'fedora:rawhide'] - arch: ['amd64', 'i386'] - exclude: - - os: 'fedora:rawhide' - arch: 'i386' - container: ${{ matrix.arch }}/${{ matrix.os }} - steps: - - name: update - if: ${{ matrix.os == 'debian:sid' }} - run: apt-get update - - name: dependencies-debian - if: ${{ matrix.os == 'debian:sid' }} - run: > - apt-get install --yes -o APT::Immediate-Configure=0 - gcc clang make pkg-config - libdevmapper-dev - libreadline-dev - libaio-dev - libudev-dev - libjson-c-dev - liburcu-dev - libcmocka-dev - libedit-dev - - name: dependencies-alpine - if: ${{ matrix.os == 'alpine' }} - run: > - apk add make gcc clang cmocka - musl-dev lvm2-dev libaio-dev readline-dev ncurses-dev eudev-dev - userspace-rcu-dev json-c-dev cmocka-dev libedit-dev - - name: dependencies-fedora - if: ${{ matrix.os == 'fedora:rawhide' }} - run: > - dnf install -y - make clang gcc pkgconfig - libaio-devel - device-mapper-devel - libselinux-devel - libsepol-devel - readline-devel - ncurses-devel - userspace-rcu-devel - json-c-devel - libcmocka-devel - libedit-devel - - name: checkout - uses: actions/checkout@v1 - - name: build and test - run: make test - - name: clean - run: make clean - - name: clang - env: - CC: clang - run: make test diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml new file mode 100644 index 0000000..55b6ee3 --- /dev/null +++ b/.github/workflows/rolling.yaml @@ -0,0 +1,33 @@ +name: compile and unit test on rolling distros +on: + push: + branches: + - master + - queue + - tip + pull_request: + schedule: + - cron: '30 06 * * 1' + +jobs: + rolling: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + os: + - debian-sid + - alpine + - fedora-rawhide + container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + steps: + - name: checkout + uses: actions/checkout@v1 + - 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 diff --git a/.gitignore b/.gitignore index 83f8a55..535353e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ *.gz *.d \#* +config.mk cscope.files cscope.out kpartx/kpartx @@ -35,5 +36,6 @@ tests/*.out tests/*.vgr libmultipath/nvme-ioctl.c libmultipath/nvme-ioctl.h +libmultipath/autoconfig.h */*-nv.version reference-abi diff --git a/Makefile b/Makefile index 27b4641..4df5f16 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ # Copyright (C) 2003 Christophe Varoqui, # +TOPDIR := . + LIB_BUILDDIRS := \ libmpathcmd \ libmpathutil \ @@ -30,22 +32,32 @@ BUILDDIRS.clean := $(BUILDDIRS:=.clean) tests.clean all: $(BUILDDIRS) -$(BUILDDIRS): - $(MAKE) -C $@ +config.mk libmultipath/autoconfig.h: + @$(MAKE) -f create-config.mk +ifeq ($(V),1) + @echo ==== config.mk ==== + @cat config.mk + @echo ==== autoconfig.h ==== + @cat libmultipath/autoconfig.h +endif + +$(BUILDDIRS): config.mk + @$(MAKE) -C $@ $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) - $(MAKE) -C ${@:.abi=} abi + @$(MAKE) -C ${@:.abi=} abi # Create formal representation of the ABI # Useful for verifying ABI compatibility # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) .PHONY: abi abi: $(LIB_BUILDDIRS:=.abi) - mkdir -p $@ - ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) + @echo creating abi + @mkdir -p $@ + $(Q)ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) abi.tar.gz: abi - tar cfz $@ abi + $(Q)tar cfz $@ abi # Check the ABI against a reference. # This requires the ABI from a previous run to be present @@ -70,8 +82,8 @@ abi-test: abi reference-abi $(wildcard abi/*.abi) # Create compile_commands.json, useful for using clangd with an IDE # Requires bear (https://github.com/rizsotto/Bear) compile_commands.json: Makefile Makefile.inc $(BUILDDIRS:=/Makefile) - $(MAKE) clean - bear -- $(MAKE) + $(Q)$(MAKE) clean + $(Q)bear -- $(MAKE) libmpathutil libdmmp: libmpathcmd libmultipath: libmpathutil @@ -83,33 +95,37 @@ libmultipath/checkers.install \ libmultipath/prioritizers.install \ libmultipath/foreign.install: libmultipath.install -$(BUILDDIRS.clean): - $(MAKE) -C ${@:.clean=} clean +%.clean: + @$(MAKE) -C ${@:.clean=} clean %.install: % - $(MAKE) -C ${@:.install=} install + @$(MAKE) -C ${@:.install=} install $(BUILDDIRS:=.uninstall): - $(MAKE) -C ${@:.uninstall=} uninstall + @$(MAKE) -C ${@:.uninstall=} uninstall -clean: $(BUILDDIRS.clean) - rm -rf abi abi.tar.gz abi-test compile_commands.json +# If config.mk is missing, "make clean" in subdir either fails, or tries to +# build it. Both is undesirable. Avoid it by creating config.mk temporarily. +clean: + @touch config.mk + $(Q)$(MAKE) $(BUILDDIRS:=.clean) tests.clean || true + $(Q)$(RM) -r abi abi.tar.gz abi-test compile_commands.json config.mk install: $(BUILDDIRS:=.install) uninstall: $(BUILDDIRS:=.uninstall) test-progs: all - $(MAKE) -C tests progs + @$(MAKE) -C tests progs test: all - $(MAKE) -C tests all + @$(MAKE) -C tests all valgrind-test: all - $(MAKE) -C tests valgrind + @$(MAKE) -C tests valgrind .PHONY: TAGS TAGS: - etags -a libmultipath/*.c - etags -a libmultipath/*.h - etags -a multipathd/*.c - etags -a multipathd/*.h + @etags -a libmultipath/*.c + @etags -a libmultipath/*.h + @etags -a multipathd/*.c + @etags -a multipathd/*.h diff --git a/Makefile.inc b/Makefile.inc index 4d843ce..2e25d2e 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -1,4 +1,4 @@ -# +# -*- Makefile -*- # Copyright (C) 2004 Christophe Varoqui, # @@ -20,191 +20,111 @@ SCSI_DH_MODULES_PRELOAD := EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) +# PKGCONFIG must be read from the environment to enable compilation +# in Debian multiarch setups PKGCONFIG ?= pkg-config ifeq ($(TOPDIR),) TOPDIR = .. endif - -ifndef LIB - ifeq ($(shell test -d /lib64 && echo 1),1) - LIB=lib64 - else - LIB=lib - endif -endif - -ifndef RUN - ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) - RUN=run - else - RUN=var/run - endif -endif - -ifndef SYSTEMD - ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') - else - ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell systemctl --version 2> /dev/null | \ - sed -n 's/systemd \([0-9]*\).*/\1/p') - endif - endif -endif - -ifndef SYSTEMDPATH - SYSTEMDPATH=usr/lib +ifneq ($(CREATE_CONFIG),1) +include $(TOPDIR)/config.mk endif -ifndef DEVMAPPER_INCDIR - ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) - DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) - else - DEVMAPPER_INCDIR = /usr/include - endif +# Paths. All these can be overridden on the "make" command line. +prefix := +# Prefix for binaries +exec_prefix := $(prefix) +# Prefix for non-essential libraries (libdmmp) +usr_prefix := $(prefix) +# Where to install systemd-related files. systemd is usually installed under /usr +# Note: some systemd installations use separate "prefix" and "rootprefix". +# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +systemd_prefix := /usr +unitdir := $(systemd_prefix)/lib/systemd/system +tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d +modulesloaddir := $(systemd_prefix)/lib/modules-load.d +libudevdir := $(systemd_prefix)/lib/udev +udevrulesdir := $(libudevdir)/rules.d +bindir := $(exec_prefix)/sbin +mandir := $(usr_prefix)/share/man +LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) +syslibdir := $(prefix)/$(LIB) +usrlibdir := $(usr_prefix)/$(LIB) +includedir := $(usr_prefix)/include +pkgconfdir := $(usrlibdir)/pkgconfig +plugindir := $(prefix)/$(LIB)/multipath +configdir := $(prefix)/etc/multipath/conf.d +runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) +devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/usr/include) +libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) +kernel_incdir := /usr/include + +ifeq ($(V),) +Q := @ +# make's "Entering directory" messages are confusing in parallel mode +#MAKEFLAGS = --no-print-directory endif -ifndef LIBUDEV_INCDIR - ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) - LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) - else - LIBUDEV_INCDIR = /usr/include - endif -endif +GZIP_PROG := gzip -9 -c +RM := rm -f +LN := ln -sf +INSTALL_PROGRAM := install -# Allow user to override default location. -ifndef LINUX_HEADERS_INCDIR - LINUX_HEADERS_INCDIR = /usr/include -endif +ORIG_CPPFLAGS := $(CPPFLAGS) +ORIG_CFLAGS := $(CFLAGS) +ORIG_LDFLAGS := $(LDFLAGS) -prefix = -exec_prefix = $(prefix) -usr_prefix = $(prefix) -bindir = $(exec_prefix)/sbin -libudevdir = $(prefix)/$(SYSTEMDPATH)/udev -tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d -udevrulesdir = $(libudevdir)/rules.d -modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d -multipathdir = $(TOPDIR)/libmultipath -daemondir = $(TOPDIR)/multipathd -mpathutildir = $(TOPDIR)/libmpathutil -man8dir = $(prefix)/share/man/man8 -man5dir = $(prefix)/share/man/man5 -man3dir = $(prefix)/share/man/man3 -syslibdir = $(prefix)/$(LIB) -usrlibdir = $(usr_prefix)/$(LIB) -libdir = $(prefix)/$(LIB)/multipath -unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system -mpathpersistdir = $(TOPDIR)/libmpathpersist -mpathcmddir = $(TOPDIR)/libmpathcmd -mpathvaliddir = $(TOPDIR)/libmpathvalid -thirdpartydir = $(TOPDIR)/third-party -libdmmpdir = $(TOPDIR)/libdmmp -nvmedir = $(TOPDIR)/libmultipath/nvme -includedir = $(prefix)/include -pkgconfdir = $(usrlibdir)/pkgconfig -plugindir := $(prefix)/$(LIB)/multipath -configdir := $(prefix)/etc/multipath/conf.d -runtimedir := /$(RUN) - -GZIP_PROG = gzip -9 -c -RM = rm -f -LN = ln -sf -INSTALL_PROGRAM = install -NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) - -# $(call TEST_CC_OPTION,option,fallback) -# Test if the C compiler supports the option. -# Evaluates to "option" if yes, and "fallback" otherwise. -TEST_CC_OPTION = $(shell \ - if echo 'int main(void){return 0;}' | \ - $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ - then \ - echo "$(1)"; \ - else \ - echo "$(2)"; \ - fi) - -# "make" on some distros will fail on explicit '#' or '\#' in the program text below -__HASH__ := \# -# Check if _DFORTIFY_SOURCE=3 is supported. -# On some distros (e.g. Debian Buster) it will be falsely reported as supported -# but it doesn't seem to make a difference wrt the compilation result. -FORTIFY_OPT := $(shell \ - if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ - $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ - then \ - echo "-D_FORTIFY_SOURCE=3"; \ - else \ - echo "-D_FORTIFY_SOURCE=2"; \ - fi) - -STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) -WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) -WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) +SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) +SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) -CPPFLAGS := $(FORTIFY_OPT) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) +CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" \ -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe -BIN_CFLAGS = -fPIE -DPIE -LIB_CFLAGS = -fPIC -SHARED_FLAGS = -shared +BIN_CFLAGS := -fPIE -DPIE +LIB_CFLAGS := -fPIC +SHARED_FLAGS := -shared LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs -BIN_LDFLAGS = -pie - -# Check whether a function with name $1 has been declared in header file $2. -check_func = $(shell \ - if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ - found=1; \ - status="yes"; \ - else \ - found=0; \ - status="no"; \ - fi; \ - echo 1>&2 "Checking for $1 in $2 ... $$status"; \ - echo "$$found" \ - ) - -# Checker whether a file with name $1 exists -check_file = $(shell \ - if [ -f "$1" ]; then \ - found=1; \ - status="yes"; \ - else \ - found=0; \ - status="no"; \ - fi; \ - echo 1>&2 "Checking if $1 exists ... $$status"; \ - echo "$$found" \ - ) - -# Check whether a file contains a variable with name $1 in header file $2 -check_var = $(shell \ - if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ - found=1; \ - status="yes"; \ - else \ - found=0; \ - status="no"; \ - fi; \ - echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ - echo "$$found" \ - ) +BIN_LDFLAGS := -pie + +# Source code directories. Don't modify. + +multipathdir := $(TOPDIR)/libmultipath +daemondir := $(TOPDIR)/multipathd +mpathutildir := $(TOPDIR)/libmpathutil +mpathpersistdir := $(TOPDIR)/libmpathpersist +mpathcmddir := $(TOPDIR)/libmpathcmd +mpathvaliddir := $(TOPDIR)/libmpathvalid +thirdpartydir := $(TOPDIR)/third-party +libdmmpdir := $(TOPDIR)/libdmmp +nvmedir := $(TOPDIR)/libmultipath/nvme + +# Common code for libraries - library Makefiles just set DEVLIB +# SONAME defaults to 0 (we use version scripts) +SONAME := 0 +LIBS = $(DEVLIB).$(SONAME) +VERSION_SCRIPT = $(DEVLIB:%.so=%.version) +NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) %.o: %.c @echo building $@ because of $? - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< %.abi: %.so.0 - abidw $< >$@ + $(Q)abidw $< >$@ %.abi: %.so - abidw $< >$@ + $(Q)abidw $< >$@ + +%-nv.version: %.version + @echo creating $@ from $< + @printf 'NOVERSION {\nglobal:\n' >$@ + @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ + @printf 'local:\n\t*;\n};\n' >>$@ + diff --git a/README.md b/README.md index d003e1d..5e04f5c 100644 --- a/README.md +++ b/README.md @@ -53,14 +53,9 @@ Building multipath-tools ======================== Prerequisites: development packages of for `libdevmapper`, `libaio`, `libudev`, -`libjson-c`, `liburcu`, and `libsystemd`. - -To enable commandline history and TAB completion in the interactive mode *(which -is entered with `multipathd -k` or `multipathc`)* you might also set `READLINE` -make variable to `libedit` or `libreadline`, like `make READLINE=libreadline`. -That requires a development package for the library you chose. Note that using -libreadline may [make binary indistributable due to license -incompatibility](https://github.com/opensvc/multipath-tools/issues/36). +`libjson-c`, `liburcu`, and `libsystemd`. If commandline editing is enabled +(see below), the development package for either `libedit` or `libreadline` is +required as well. Then, build and install multipath-tools with: @@ -71,17 +66,37 @@ To uninstall, type: make uninstall +By default, the build will run quietly, just printing one-line messages +about the files being built. To enable more verbose output, run `make V=1`. + Customizing the build --------------------- +**Note**: With very few exceptions, the build process does not read +configuration from the environment. So using syntax like + + SOME_VAR=some_value make + +will **not** have the intended effect. Use the following instead: + + make SOME_VAR=some_value + +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. * `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. * `configdir="/some/path"` : directory to search for configuration files. This used to be the run-time option `config_dir` in earlier versions. The default is `/etc/multipath/conf.d`. + * `READLINE=libedit` or `READLINE=libreadline`: enable command line history + and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. + The respective development package will be required for building. + By default, command line editing is disabled. + Note that using libreadline may + [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). * `ENABLE_LIBDMMP=0`: disable building libdmmp * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event polling API. For use with pre-5.0 kernels that don't support dmevent polling @@ -93,15 +108,44 @@ The following variables can be passed to the `make` command line: early. This option causes a *modules-load.d(5)* configuration file to be created, thus it depends on functionality provided by *systemd*. This variable only matters for `make install`. - -Note: The usefulness of the preload list depends on the kernel configuration. -It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and -other device handler modules are built as modules. If `scsi_mod` itself is compiled -as a module, it might make more sense to use a module softdep for the same -purpose. - -See `Makefile.inc` for additional variables to customize paths and compiler -flags. + + **Note**: The usefulness of the preload list depends on the kernel configuration. + It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and + other device handler modules are built as modules. If `scsi_mod` itself is compiled + as a module, it might make more sense to use a module softdep for the same + purpose. + +### Installation Paths + + * `prefix`: The directory prefix for (almost) all files to be installed. + Distributions may want to set this to `/usr`. + **Note**: for multipath-tools, unlike many other packages, `prefix` + defaults to the empty string, which resolves to the root directory (`/`). + * `usr_prefix`: where to install those parts of the code that aren't necessary + for booting. You may want to set this to `/usr` if `prefix` is empty. + * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. + Some systemd installations use separate `prefix` and `rootprefix`. On such + a distribution, set `prefix`, and override `unitdir` to use systemd's + `rootprefix`. + * `LIB`: the subdirectory under `prefix` where shared libraries will be + installed. By default, the makefile uses `/lib64` if this directory is + found on the build system, and `/lib` otherwise. + +See also `configdir` and `plugindir` above. See `Makefile.inc` for more +fine-grained control. + +### Compiler Options + +Use `OPTFLAGS` to change optimization-related compiler options; +e.g. `OPTFLAGS="-g -O0"` to disable all optimizations. + +### Passing standard compiler flags + +Contrary to most other variables, the standard variables `CFLAGS`, +`CPPFLAGS`, and `LDFLAGS` **must** be passed to **make** via the environment +if they need to be customized: + + CPPFLAGS="-D_SECRET_=secret" make Special Makefile targets ------------------------ @@ -128,7 +172,7 @@ Mailing list ============ (subscribers-only) -To subscribe and archives: https://www.redhat.com/mailman/listinfo/dm-devel +To subscribe and archives: https://listman.redhat.com/mailman/listinfo/dm-devel Searchable: https://marc.info/?l=dm-devel @@ -175,7 +219,7 @@ To enable ALUA, the following options should be changed: - LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and rebranded arrays: "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". -- NetApp ONTAP: +- NetApp ONTAP FAS/AFF Series: To check ALUA state: "igroup show -v ", and to enable ALUA: "igroup set alua yes". diff --git a/create-config.mk b/create-config.mk new file mode 100644 index 0000000..2a95ec5 --- /dev/null +++ b/create-config.mk @@ -0,0 +1,170 @@ +# Copyright (c) SUSE LLC +# SPDX-License-Identifier: GPL-2.0-or-later + +TOPDIR := . +CREATE_CONFIG := 1 +include $(TOPDIR)/Makefile.inc + +# "make" on some distros will fail on explicit '#' or '\#' in the program text below +__HASH__ := \# + +# Check whether a given shell command succeeds +check_cmd = $(shell \ + if $1; then \ + found=1; \ + status="yes"; \ + else \ + found=0; \ + status="no"; \ + fi; \ + echo 1>&2 "Checking $(if $3,$3,command \"$1\") ... $$status"; \ + echo "$$found" \ + ) + +# Check whether a function with name $1 has been declared in header file $2. +check_func = $(shell \ + if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ + found=1; \ + status="yes"; \ + else \ + found=0; \ + status="no"; \ + fi; \ + echo 1>&2 "Checking for $1 in $2 ... $$status"; \ + echo "$$found" \ + ) + +# Checker whether a file with name $1 exists +check_file = $(shell \ + if [ -f "$1" ]; then \ + found=1; \ + status="yes"; \ + else \ + found=0; \ + status="no"; \ + fi; \ + echo 1>&2 "Checking if $1 exists ... $$status"; \ + echo "$$found" \ + ) + +# Check whether a file contains a variable with name $1 in header file $2 +check_var = $(shell \ + if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ + found=1; \ + status="yes"; \ + else \ + found=0; \ + status="no"; \ + fi; \ + echo 1>&2 "Checking for $1 in $2 ... $$status"; \ + echo "$$found" \ + ) + +# Test special behavior of gcc 4.8 with nested initializers +# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers +TEST_MISSING_INITIALIZERS = $(shell \ + echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ + $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ + || echo -Wno-missing-field-initializers) + +# gcc 4.8.4 and certain versions of liburcu fail to compile this with -Werror=type-limits +TEST_URCU_TYPE_LIMITS = $(shell \ + echo -e '$(__HASH__)include \nint main() { int z=8; return uatomic_sub_return(&z, 1); }' | \ + $(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \ + || echo -Wno-type-limits ) + +DEFINES := + +ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) + DEFINES += LIBDM_API_FLUSH +endif + +ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + DEFINES += LIBDM_API_GET_ERRNO +endif + +ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + DEFINES += LIBDM_API_COOKIE +endif + +ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) + DEFINES += LIBUDEV_API_RECVBUF +endif + +ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) + DEFINES += LIBDM_API_DEFERRED +endif + +ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) + DEFINES += LIBDM_API_HOLD_CONTROL +endif + +ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + DEFINES += FPIN_EVENT_HANDLER + FPIN_SUPPORT = 1 +endif + +ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) + ANA_SUPPORT := 1 +endif + +ENABLE_LIBDMMP := $(call check_cmd,$(PKGCONFIG) --exists json-c) + +ifeq ($(ENABLE_DMEVENTS_POLL),0) + DEFINES += -DNO_DMEVENTS_POLL +endif + +SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ + $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + + +# $(call TEST_CC_OPTION,option,fallback) +# Test if the C compiler supports the option. +# Evaluates to "option" if yes, and "fallback" otherwise. +TEST_CC_OPTION = $(shell \ + if echo 'int main(void){return 0;}' | \ + $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ + then \ + echo "$(1)"; \ + else \ + echo "$(2)"; \ + fi) + +# Check if _DFORTIFY_SOURCE=3 is supported. +# On some distros (e.g. Debian Buster) it will be falsely reported as supported +# but it doesn't seem to make a difference wrt the compilation result. +FORTIFY_OPT := $(shell \ + if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ + $(CC) -o /dev/null $(OPTFLAGS) -c -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ + then \ + echo "-D_FORTIFY_SOURCE=3"; \ + elif /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ + $(CC) -o /dev/null $(OPTFLAGS) -c -Werror -D_FORTIFY_SOURCE=2 -xc - 2>/dev/null; \ + then \ + echo "-D_FORTIFY_SOURCE=2"; \ + fi) + +STACKPROT := + +all: $(TOPDIR)/config.mk + +$(multipathdir)/autoconfig.h: + @echo creating $@ + @echo '#ifndef _AUTOCONFIG_H' >$@ + @echo '#define _AUTOCONFIG_H' >>$@ + @for x in $(DEFINES); do echo "#define $$x" >>$@; done + @echo '#endif' >>$@ + +$(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h + @echo creating $@ + @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ + @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ + @echo "SYSTEMD := $(SYSTEMD)" >>$@ + @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ + @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ + @echo "ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)" >>$@ + @echo "WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)" >>$@ + @echo "WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)" >>$@ + @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ + @echo "W_URCU_TYPE_LIMITS := $(call TEST_URCU_TYPE_LIMITS)" >>$@ + @echo "ENABLE_LIBDMMP := $(ENABLE_LIBDMMP)" >>$@ diff --git a/kpartx/Makefile b/kpartx/Makefile index 742d3bc..7720a74 100644 --- a/kpartx/Makefile +++ b/kpartx/Makefile @@ -3,51 +3,47 @@ # include ../Makefile.inc +EXEC := kpartx + CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 CFLAGS += $(BIN_CFLAGS) LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -ldevmapper -ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE -endif - -OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ +OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o -EXEC = kpartx - all: $(EXEC) $(EXEC): $(OBJS) - $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + @echo building $@ because of $? + $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) install: $(EXEC) $(EXEC).8 - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) - $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d - $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules - $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules - $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) + $(Q)$(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d + $(Q)$(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules + $(Q)$(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules + $(Q)$(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 - $(RM) $(DESTDIR)$(libudevdir)/kpartx_id - $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules - $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules - $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules - $(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(libudevdir)/kpartx_id + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules clean: dep_clean - $(RM) core *.o $(EXEC) + $(Q)$(RM) core *.o $(EXEC) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c index bf14c78..f12762c 100644 --- a/kpartx/devmapper.c +++ b/kpartx/devmapper.c @@ -9,6 +9,7 @@ #include #include #include +#include "autoconfig.h" #include "devmapper.h" #include "kpartx.h" diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c index 1d568c9..46cb76b 100644 --- a/kpartx/kpartx.c +++ b/kpartx/kpartx.c @@ -34,6 +34,7 @@ #include #include +#include "autoconfig.h" #include "devmapper.h" #include "crc32.h" #include "lopart.h" diff --git a/kpartx/kpartx_id b/kpartx/kpartx_id index 18732e7..4672927 100755 --- a/kpartx/kpartx_id +++ b/kpartx/kpartx_id @@ -28,7 +28,7 @@ MINOR=$2 UUID=$3 if [ -z "$MAJOR" -o -z "$MINOR" ]; then - echo "usage: $0 major minor" + echo "usage: $0 major minor UUID" exit 1; fi diff --git a/libdmmp/Makefile b/libdmmp/Makefile index e458925..6d28caf 100644 --- a/libdmmp/Makefile +++ b/libdmmp/Makefile @@ -5,15 +5,14 @@ # include ../Makefile.inc -LIBDMMP_VERSION=0.2.0 -SONAME=$(LIBDMMP_VERSION) -DEVLIB = libdmmp.so -LIBS = $(DEVLIB).$(SONAME) -PKGFILE = libdmmp.pc -EXTRA_MAN_FILES = libdmmp.h.3 -HEADERS = libdmmp/libdmmp.h +LIBDMMP_VERSION := 0.2.0 +SONAME := $(LIBDMMP_VERSION) +DEVLIB := libdmmp.so +PKGFILE := libdmmp.pc +EXTRA_MAN_FILES := libdmmp.h.3 +HEADERS := libdmmp/libdmmp.h -OBJS = libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o +OBJS := libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o CPPFLAGS += -I$(libdmmpdir) -I$(mpathcmddir) $(shell $(PKGCONFIG) --cflags json-c) CFLAGS += $(LIB_CFLAGS) -fvisibility=hidden @@ -24,62 +23,62 @@ all: $(LIBS) doc .PHONY: doc clean install uninstall check speed_test dep_clean $(LIBS): $(OBJS) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ + $(Q)$(LN) $(LIBS) $@ abi: $(DEVLIB:%.so=%.abi) install: - mkdir -p $(DESTDIR)$(usrlibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 644 -D \ + @mkdir -p $(DESTDIR)$(usrlibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) + $(Q)$(INSTALL_PROGRAM) -m 644 -D \ $(HEADERS) $(DESTDIR)$(includedir)/$(HEADERS) - $(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) - $(INSTALL_PROGRAM) -m 644 -D \ + $(Q)$(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) + $(Q)$(INSTALL_PROGRAM) -m 644 -D \ $(PKGFILE).in $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ + $(Q)sed -i 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ + $(Q)sed -i 's|__LIBDIR__|$(usrlibdir)|g' \ $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ + $(Q)sed -i 's|__INCLUDEDIR__|$(includedir)|g' \ $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(man3dir) - $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(man3dir) docs/man/*.3 + $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 + $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 uninstall: - $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) - $(RM) $(DESTDIR)$(includedir)/$(HEADERS) - $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) - @for file in $(DESTDIR)$(man3dir)/dmmp_*; do \ + $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) + $(Q)$(RM) $(DESTDIR)$(includedir)/$(HEADERS) + $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) + @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ $(RM) $$file; \ done - $(RM) $(DESTDIR)$(man3dir)/libdmmp.h* - $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + $(Q)$(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* + $(Q)$(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) clean: dep_clean - $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - $(MAKE) -C test clean + $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + @$(MAKE) -C test clean include $(wildcard $(OBJS:.o=.d)) check: all - $(MAKE) -C test check + @$(MAKE) -C test check speed_test: all - $(MAKE) -C test speed_test + @$(MAKE) -C test speed_test doc: docs/man/dmmp_strerror.3 docs/man/dmmp_strerror.3: $(HEADERS) - TEMPFILE=$(shell mktemp); \ + $(Q)TEMPFILE=$(shell mktemp); \ cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ LC_ALL=C \ KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ perl docs/kernel-doc -man $$TEMPFILE | \ perl docs/split-man.pl docs/man; \ - rm -f $$TEMPFILE + $(RM) -f $$TEMPFILE dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile index 76b24d6..9d0817c 100644 --- a/libdmmp/test/Makefile +++ b/libdmmp/test/Makefile @@ -2,6 +2,7 @@ # # Copyright (C) 2015-2016 Gris Ge # +TOPDIR := ../.. include ../../Makefile.inc _libdmmpdir=../$(libdmmpdir) @@ -15,7 +16,7 @@ LDFLAGS += -L$(_libdmmpdir) -ldmmp all: $(TEST_EXEC) $(SPD_TEST_EXEC) check: $(TEST_EXEC) $(SPD_TEST_EXEC) - sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ + $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ valgrind --quiet --leak-check=full \ --show-reachable=no --show-possibly-lost=no \ --trace-children=yes --error-exitcode=1 \ @@ -23,15 +24,15 @@ check: $(TEST_EXEC) $(SPD_TEST_EXEC) $(MAKE) speed_test speed_test: $(SPD_TEST_EXEC) - sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ + $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ time -p ./$(SPD_TEST_EXEC) clean: dep_clean - rm -f $(TEST_EXEC) $(SPD_TEST_EXEC) + $(Q)$(RM) -f $(TEST_EXEC) $(SPD_TEST_EXEC) OBJS = $(TEST_EXEC).o $(SPD_TEST_EXEC).o include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile index 0f83fe7..be615c2 100644 --- a/libmpathcmd/Makefile +++ b/libmpathcmd/Makefile @@ -1,51 +1,30 @@ include ../Makefile.inc -SONAME = 0 -DEVLIB = libmpathcmd.so -LIBS = $(DEVLIB).$(SONAME) -VERSION_SCRIPT := libmpathcmd.version - +DEVLIB := libmpathcmd.so CFLAGS += $(LIB_CFLAGS) - -OBJS = mpath_cmd.o +OBJS := mpath_cmd.o all: $(DEVLIB) -$(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) - @printf 'NOVERSION {\nglobal:\n' >$@ - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ - -$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) - -$(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ +include $(TOPDIR)/rules.mk install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) - $(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) + $(Q)$(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - $(RM) $(DESTDIR)$(includedir)/mpath_cmd.h + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_cmd.h clean: dep_clean - $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile index 4e1717e..8f9a43f 100644 --- a/libmpathpersist/Makefile +++ b/libmpathpersist/Makefile @@ -1,60 +1,39 @@ include ../Makefile.inc -SONAME = 0 -DEVLIB = libmpathpersist.so -LIBS = $(DEVLIB).$(SONAME) -VERSION_SCRIPT:= libmpathpersist.version - +DEVLIB := libmpathpersist.so CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) LDFLAGS += -L$(multipathdir) -L$(mpathutildir) -L$(mpathcmddir) - LIBDEPS += -lmultipath -lmpathutil -lmpathcmd -ldevmapper -lpthread -ldl -OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o +OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o all: $(DEVLIB) -$(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) - @printf 'NOVERSION {\nglobal:\n' >$@ - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ - -$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) - -$(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ +include $(TOPDIR)/rules.mk install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(man3dir) - $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(man3dir) - $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 + $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) + $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 + $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 + $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) - $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_in.3 - $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_out.3 - $(RM) $(DESTDIR)$(includedir)/mpath_persist.h - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 + $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 + $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_persist.h + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) clean: dep_clean - $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c index 5824c16..4529a82 100644 --- a/libmpathpersist/mpath_updatepr.c +++ b/libmpathpersist/mpath_updatepr.c @@ -18,7 +18,7 @@ #include "mpathpr.h" -static int do_update_pr(char *alias, char *arg) +static int do_update_pr(char *alias, char *cmd, char *key) { int fd; char str[256]; @@ -31,7 +31,10 @@ static int do_update_pr(char *alias, char *arg) return -1; } - snprintf(str,sizeof(str),"map %s %s", alias, arg); + if (key) + snprintf(str,sizeof(str),"%s map %s key %s", cmd, alias, key); + else + snprintf(str,sizeof(str),"%s map %s", cmd, alias); condlog (2, "%s: pr message=%s", alias, str); if (send_packet(fd, str) != 0) { condlog(2, "%s: message=%s send error=%d", alias, str, errno); @@ -56,18 +59,16 @@ static int do_update_pr(char *alias, char *arg) } int update_prflag(char *mapname, int set) { - return do_update_pr(mapname, (set)? "setprstatus" : "unsetprstatus"); + return do_update_pr(mapname, (set)? "setprstatus" : "unsetprstatus", + NULL); } int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags) { char str[256]; - char *flagstr = ""; - if (sa_flags & MPATH_F_APTPL_MASK) - flagstr = ":aptpl"; - if (prkey) - sprintf(str, "setprkey key %" PRIx64 "%s", prkey, flagstr); - else - sprintf(str, "unsetprkey"); - return do_update_pr(mapname, str); + if (!prkey) + return do_update_pr(mapname, "unsetprkey", NULL); + sprintf(str, "%" PRIx64 "%s", prkey, + (sa_flags & MPATH_F_APTPL_MASK) ? ":aptpl" : ""); + return do_update_pr(mapname, "setprkey", str); } diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile index 68b1c7d..aebd8cc 100644 --- a/libmpathutil/Makefile +++ b/libmpathutil/Makefile @@ -3,24 +3,10 @@ # include ../Makefile.inc -SONAME = 0 -DEVLIB = libmpathutil.so -LIBS = $(DEVLIB).$(SONAME) -VERSION_SCRIPT := libmpathutil.version - -CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) +DEVLIB := libmpathutil.so +CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE - -LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd - -ifdef SYSTEMD - CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) - ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) - LIBDEPS += -lsystemd - else - LIBDEPS += -lsystemd-daemon - endif -endif +LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) -lrt # object files referencing MULTIPATH_DIR or CONFIG_DIR # they need to be recompiled for unit tests @@ -31,40 +17,21 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ all: $(DEVLIB) -make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) - -$(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -$(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - -$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) - @printf 'NOVERSION {\nglobal:\n' >$@ - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ - -$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +include $(TOPDIR)/rules.mk install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) clean: dep_clean - $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) + $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmpathutil/parser.c b/libmpathutil/parser.c index 8d3ac53..29b212c 100644 --- a/libmpathutil/parser.c +++ b/libmpathutil/parser.c @@ -333,59 +333,33 @@ void * set_value(vector strvec) { char *str = VECTOR_SLOT(strvec, 1); - size_t size; - int i = 0; - int len = 0; char *alloc = NULL; - char *tmp; if (!str) { condlog(0, "option '%s' missing value", (char *)VECTOR_SLOT(strvec, 0)); return NULL; } - if (!is_quote(str)) { - size = strlen(str); - if (size == 0) { - condlog(0, "option '%s' has empty value", - (char *)VECTOR_SLOT(strvec, 0)); - return NULL; - } - alloc = calloc(1, sizeof (char) * (size + 1)); - if (alloc) - memcpy(alloc, str, size); - else - goto oom; - return alloc; - } - /* Even empty quotes counts as a value (An empty string) */ - alloc = (char *)calloc(1, sizeof (char)); - if (!alloc) - goto oom; - for (i = 2; i < VECTOR_SIZE(strvec); i++) { - str = VECTOR_SLOT(strvec, i); - if (!str) { - free(alloc); - condlog(0, "parse error for option '%s'", - (char *)VECTOR_SLOT(strvec, 0)); - return NULL; + if (is_quote(str)) { + if (VECTOR_SIZE(strvec) > 2) { + str = VECTOR_SLOT(strvec, 2); + if (!str) { + condlog(0, "parse error for option '%s'", + (char *)VECTOR_SLOT(strvec, 0)); + return NULL; + } } - if (is_quote(str)) - break; - tmp = alloc; - /* The first +1 is for the NULL byte. The rest are for the - * spaces between words */ - len += strlen(str) + 1; - alloc = realloc(alloc, sizeof (char) * len); - if (!alloc) { - free(tmp); - goto oom; + /* Even empty quotes counts as a value (An empty string) */ + if (is_quote(str)) { + alloc = (char *)calloc(1, sizeof (char)); + if (!alloc) + goto oom; + return alloc; } - if (*alloc != '\0') - strncat(alloc, " ", len - strlen(alloc)); - strncat(alloc, str, len - strlen(alloc) - 1); } - return alloc; + alloc = strdup(str); + if (alloc) + return alloc; oom: condlog(0, "can't allocate memory for option '%s'", (char *)VECTOR_SLOT(strvec, 0)); @@ -442,7 +416,6 @@ int validate_config_strvec(vector strvec, const char *file) { char *str = NULL; - int i; if (strvec && VECTOR_SIZE(strvec) > 0) str = VECTOR_SLOT(strvec, 0); @@ -485,21 +458,41 @@ validate_config_strvec(vector strvec, const char *file) condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file); return 0; } - for (i = 2; i < VECTOR_SIZE(strvec); i++) { - str = VECTOR_SLOT(strvec, i); - if (str == NULL) { - condlog(0, "can't parse value on line %d of %s", - line_nr, file); - return -1; - } - if (is_quote(str)) { - if (VECTOR_SIZE(strvec) > i + 1) - condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr, file); - return 0; - } + if (VECTOR_SIZE(strvec) == 2) { + condlog(0, "missing closing quotes on line %d of %s", + line_nr, file); + return 0; + } + str = VECTOR_SLOT(strvec, 2); + if (str == NULL) { + condlog(0, "can't parse value on line %d of %s", + line_nr, file); + return -1; + } + if (is_quote(str)) { + if (VECTOR_SIZE(strvec) > 3) + condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 3), line_nr, file); + return 0; + } + if (VECTOR_SIZE(strvec) == 3) { + condlog(0, "missing closing quotes on line %d of %s", + line_nr, file); + return 0; + } + str = VECTOR_SLOT(strvec, 3); + if (str == NULL) { + condlog(0, "can't parse value on line %d of %s", + line_nr, file); + return -1; + } + if (!is_quote(str)) { + /* There should only ever be one token between quotes */ + condlog(0, "parsing error starting with '%s' on line %d of %s", + str, line_nr, file); + return -1; } - condlog(0, "missing closing quotes on line %d of %s", - line_nr, file); + if (VECTOR_SIZE(strvec) > 4) + condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 4), line_nr, file); return 0; } diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile index 5dbfb92..791a039 100644 --- a/libmpathvalid/Makefile +++ b/libmpathvalid/Makefile @@ -1,52 +1,33 @@ include ../Makefile.inc -SONAME = 0 -DEVLIB = libmpathvalid.so -LIBS = $(DEVLIB).$(SONAME) -VERSION_SCRIPT := libmpathvalid.version - +DEVLIB := libmpathvalid.so CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) CFLAGS += $(LIB_CFLAGS) - LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev -OBJS = mpath_valid.o - -all: $(LIBS) - -$(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) \ - -Wl,--version-script=$(VERSION_SCRIPT) - $(LN) $(LIBS) $(DEVLIB) - -$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) - @printf 'NOVERSION {\nglobal:\n' >$@ - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ +OBJS := mpath_valid.o -$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +all: $(DEVLIB) -abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +include $(TOPDIR)/rules.mk install: $(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) - $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) + $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) + $(Q)$(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - $(RM) $(DESTDIR)$(includedir)/mpath_valid.h + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_valid.h clean: dep_clean - $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmultipath/Makefile b/libmultipath/Makefile index 3b60a52..3df851e 100644 --- a/libmultipath/Makefile +++ b/libmultipath/Makefile @@ -3,52 +3,11 @@ # include ../Makefile.inc -SONAME = 0 -DEVLIB = libmultipath.so -LIBS = $(DEVLIB).$(SONAME) -VERSION_SCRIPT := libmultipath.version - -CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE +DEVLIB := libmultipath.so +CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) CFLAGS += $(LIB_CFLAGS) - -LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lurcu -laio - -ifdef SYSTEMD - CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) - ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) - LIBDEPS += -lsystemd - else - LIBDEPS += -lsystemd-daemon - endif -endif - -ifneq ($(call check_func,dm_task_no_flush,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_FLUSH -endif - -ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO -endif - -ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE -endif - -ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(LIBUDEV_INCDIR)/libudev.h),0) - CPPFLAGS += -DLIBUDEV_API_RECVBUF -endif - -ifneq ($(call check_func,dm_task_deferred_remove,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_DEFERRED -endif - -ifneq ($(call check_func,dm_hold_control_dev,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_HOLD_CONTROL -endif - -ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER -endif +LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ + -lurcu -laio $(SYSTEMD_LIBDEPS) # object files referencing MULTIPATH_DIR or CONFIG_DIR # they need to be recompiled for unit tests @@ -69,67 +28,50 @@ OBJS := $(OBJS-O) $(OBJS-U) all: $(DEVLIB) +include $(TOPDIR)/rules.mk + nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h - $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< # there are lots of "unused parameters" in dict.c # because not all handler / snprint methods need all parameters dict.o: dict.c - $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) nvme-ioctl.c: nvme/nvme-ioctl.c - $(call make_static,$<,$@) + $(Q)$(call make_static,$<,$@) nvme-ioctl.h: nvme/nvme-ioctl.h - $(call make_static,$<,$@) - - -$(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -$(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - -$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) - @printf 'NOVERSION {\nglobal:\n' >$@ - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ - -$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - -abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) + $(Q)$(call make_static,$<,$@) ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) - $(LN) $@ ${@:.so.0=.so} + $(Q)$(LN) $@ ${@:.so.0=.so} # This rule is invoked from tests/Makefile, overriding configdir and plugindir %-test.o: %.c @echo building $@ because of $? - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< test-lib: ../tests/$(LIBS) install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) + $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) + $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) clean: dep_clean - $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) + $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile index c9a2c4c..6f7cfb9 100644 --- a/libmultipath/checkers/Makefile +++ b/libmultipath/checkers/Makefile @@ -22,16 +22,16 @@ LIBS= \ all: $(LIBS) libcheck%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) install: - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done + $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done clean: dep_clean - $(RM) core *.a *.o *.gz *.so + $(Q)$(RM) core *.a *.o *.gz *.so OBJS := $(LIBS:libcheck%.so=%.o) .SECONDARY: $(OBJS) @@ -39,4 +39,4 @@ OBJS := $(LIBS:libcheck%.so=%.o) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmultipath/configure.c b/libmultipath/configure.c index e5249fc..e551047 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -662,7 +662,8 @@ static bool is_udev_ready(struct multipath *cmpp) env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); rc = (env != NULL && !strcmp(env, "1")); udev_device_unref(mpp_ud); - condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); + condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, + env ? env : "", rc); return rc; } diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h index 3d552b3..a5e9ea0 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -62,7 +62,7 @@ #define DEV_LOSS_TMO_UNSET 0U #define MAX_DEV_LOSS_TMO UINT_MAX -#define DEFAULT_PIDFILE "/" RUN_DIR "/multipathd.pid" +#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" #define DEFAULT_CONFIGFILE "/etc/multipath.conf" #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h index 703f3bf..42f8ecc 100644 --- a/libmultipath/devmapper.h +++ b/libmultipath/devmapper.h @@ -1,6 +1,6 @@ #ifndef _DEVMAPPER_H #define _DEVMAPPER_H - +#include "autoconfig.h" #include "structs.h" #define TGT_MPATH "multipath" diff --git a/libmultipath/dict.c b/libmultipath/dict.c index aa93fe4..2e9b45f 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -24,6 +24,7 @@ #include #include #include +#include "autoconfig.h" #include "mpath_cmd.h" #include "dict.h" #include "strbuf.h" @@ -115,6 +116,58 @@ set_str(vector strvec, void *ptr, const char *file, int line_nr) return 0; } +static int +set_arg_str(vector strvec, void *ptr, int count_idx, const char *file, + int line_nr) +{ + char **str_ptr = (char **)ptr; + char *old_str = *str_ptr; + const char * const spaces = " \f\r\t\v"; + char *p, *end; + int idx = -1; + long int count = -1; + + *str_ptr = set_value(strvec); + if (!*str_ptr) { + free(old_str); + return 1; + } + p = *str_ptr; + while (*p != '\0') { + p += strspn(p, spaces); + if (*p == '\0') + break; + idx += 1; + if (idx == count_idx) { + errno = 0; + count = strtol(p, &end, 10); + if (errno == ERANGE || end == p || + !(isspace(*end) || *end == '\0')) { + count = -1; + break; + } + } + p += strcspn(p, spaces); + } + if (count < 0) { + condlog(1, "%s line %d, missing argument count for %s", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0)); + goto fail; + } + if (count != idx - count_idx) { + condlog(1, "%s line %d, invalid argument count for %s:, got '%ld' expected '%d'", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), count, + idx - count_idx); + goto fail; + } + free(old_str); + return 0; +fail: + free(*str_ptr); + *str_ptr = old_str; + return 0; +} + static int set_path(vector strvec, void *ptr, const char *file, int line_nr) { @@ -129,6 +182,7 @@ set_path(vector strvec, void *ptr, const char *file, int line_nr) if ((*str_ptr)[0] != '/'){ condlog(1, "%s line %d, %s is not an absolute path. Ignoring", file, line_nr, *str_ptr); + free(*str_ptr); *str_ptr = old_str; } else free(old_str); @@ -149,6 +203,7 @@ set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) if (strchr(*str_ptr, '/')) { condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", file, line_nr, *str_ptr); + free(*str_ptr); *str_ptr = old_str; } else free(old_str); @@ -285,6 +340,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ } +#define declare_def_arg_str_handler(option, count_idx) \ +static int \ +def_ ## option ## _handler (struct config *conf, vector strvec, \ + const char *file, int line_nr) \ +{ \ + return set_arg_str(strvec, &conf->option, count_idx, file, line_nr); \ +} + #define declare_def_snprint(option, function) \ static int \ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ @@ -337,6 +400,17 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ } +#define declare_hw_arg_str_handler(option, count_idx) \ +static int \ +hw_ ## option ## _handler (struct config *conf, vector strvec, \ + const char *file, int line_nr) \ +{ \ + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ + if (!hwe) \ + return 1; \ + return set_arg_str(strvec, &hwe->option, count_idx, file, line_nr); \ +} + #define declare_hw_snprint(option, function) \ static int \ @@ -368,6 +442,16 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ file, line_nr); \ } +#define declare_ovr_arg_str_handler(option, count_idx) \ +static int \ +ovr_ ## option ## _handler (struct config *conf, vector strvec, \ + const char *file, int line_nr) \ +{ \ + if (!conf->overrides) \ + return 1; \ + return set_arg_str(strvec, &conf->overrides->option, count_idx, file, line_nr); \ +} + #define declare_ovr_snprint(option, function) \ static int \ snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ @@ -398,6 +482,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ } +#define declare_mp_arg_str_handler(option, count_idx) \ +static int \ +mp_ ## option ## _handler (struct config *conf, vector strvec, \ + const char *file, int line_nr) \ +{ \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ + return set_arg_str(strvec, &mpe->option, count_idx, file, line_nr); \ +} + #define declare_mp_snprint(option, function) \ static int \ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ @@ -581,13 +676,13 @@ snprint_def_marginal_pathgroups(struct config *conf, struct strbuf *buff, } -declare_def_handler(selector, set_str) +declare_def_arg_str_handler(selector, 1) declare_def_snprint_defstr(selector, print_str, DEFAULT_SELECTOR) -declare_hw_handler(selector, set_str) +declare_hw_arg_str_handler(selector, 1) declare_hw_snprint(selector, print_str) -declare_ovr_handler(selector, set_str) +declare_ovr_arg_str_handler(selector, 1) declare_ovr_snprint(selector, print_str) -declare_mp_handler(selector, set_str) +declare_mp_arg_str_handler(selector, 1) declare_mp_snprint(selector, print_str) static int snprint_uid_attrs(struct config *conf, struct strbuf *buff, @@ -660,13 +755,13 @@ declare_hw_snprint(prio_args, print_str) declare_mp_handler(prio_args, set_str) declare_mp_snprint(prio_args, print_str) -declare_def_handler(features, set_str) +declare_def_arg_str_handler(features, 0) declare_def_snprint_defstr(features, print_str, DEFAULT_FEATURES) -declare_ovr_handler(features, set_str) +declare_ovr_arg_str_handler(features, 0) declare_ovr_snprint(features, print_str) -declare_hw_handler(features, set_str) +declare_hw_arg_str_handler(features, 0) declare_hw_snprint(features, print_str) -declare_mp_handler(features, set_str) +declare_mp_arg_str_handler(features, 0) declare_mp_snprint(features, print_str) declare_def_handler(checker_name, set_str) @@ -1818,7 +1913,7 @@ declare_hw_snprint(revision, print_str) declare_hw_handler(bl_product, set_str) declare_hw_snprint(bl_product, print_str) -declare_hw_handler(hwhandler, set_str) +declare_hw_arg_str_handler(hwhandler, 0) declare_hw_snprint(hwhandler, print_str) /* @@ -2102,7 +2197,7 @@ init_keywords(vector keywords) install_keyword("no_path_retry", &hw_no_path_retry_handler, &snprint_hw_no_path_retry); install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_minio); install_keyword("rr_min_io_rq", &hw_minio_rq_handler, &snprint_hw_minio_rq); - install_keyword("pg_timeout", &deprecated_handler, &snprint_deprecated); + install_keyword("pg_timeout", &deprecated_pg_timeout_handler, &snprint_deprecated); install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del); install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail); install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); @@ -2191,7 +2286,7 @@ init_keywords(vector keywords) install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry); install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_minio); install_keyword("rr_min_io_rq", &mp_minio_rq_handler, &snprint_mp_minio_rq); - install_keyword("pg_timeout", &deprecated_handler, &snprint_deprecated); + install_keyword("pg_timeout", &deprecated_pg_timeout_handler, &snprint_deprecated); install_keyword("flush_on_last_del", &mp_flush_on_last_del_handler, &snprint_mp_flush_on_last_del); install_keyword("features", &mp_features_handler, &snprint_mp_features); install_keyword("mode", &mp_mode_handler, &snprint_mp_mode); diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index f3fcced..d9ee2cb 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -218,7 +218,8 @@ path_discovery (vector pathvec, int flag) udevice, flag) == PATHINFO_OK) num_paths++; } - udevice = udev_device_unref(udevice); + udev_device_unref(udevice); + udevice = NULL; } ret = total_paths - num_paths; condlog(4, "Discovered %d/%d paths", num_paths, total_paths); diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile index d0232f2..b83213d 100644 --- a/libmultipath/foreign/Makefile +++ b/libmultipath/foreign/Makefile @@ -14,16 +14,16 @@ LIBS = libforeign-nvme.so all: $(LIBS) libforeign-%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) install: - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done + $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done clean: dep_clean - $(RM) core *.a *.o *.gz *.so + $(Q)$(RM) core *.a *.o *.gz *.so OBJS := $(LIBS:libforeign-%.so=%.o) .SECONDARY: $(OBJS) @@ -31,4 +31,4 @@ OBJS := $(LIBS:libforeign-%.so=%.o) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c index 2085aba..3c4f866 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c @@ -232,7 +232,7 @@ static struct hwentry default_hw[] = { .prio_name = PRIO_ALUA, }, { - /* Nimble Storage / HPE Alletra 6000 */ + /* Nimble Storage / HPE Alletra 5000/6000 */ .vendor = "Nimble", .product = "Server", .hwhandler = "1 alua", @@ -339,6 +339,12 @@ static struct hwentry default_hw[] = { .pgpolicy = MULTIBUS, .no_path_retry = 6, }, + { + /* PowerMax NVMe */ + .vendor = "NVME", + .product = "EMC PowerMax", + .no_path_retry = NO_PATH_RETRY_QUEUE, + }, { /* DGC CLARiiON CX/AX / VNX and Unity */ .vendor = "^DGC", @@ -367,7 +373,7 @@ static struct hwentry default_hw[] = { .pgpolicy = MULTIBUS, }, { - /* SC Series, formerly Compellent */ + /* SC Series (formerly Compellent) */ .vendor = "COMPELNT", .product = "Compellent Vol", .pgpolicy = GROUP_BY_PRIO, @@ -456,6 +462,7 @@ static struct hwentry default_hw[] = { { /* * ETERNUS AB/HB + * * Maintainer: NetApp RDAC team */ .vendor = "FUJITSU", @@ -672,7 +679,7 @@ static struct hwentry default_hw[] = { .pgfailback = -FAILBACK_IMMEDIATE, }, { - // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / + // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 .vendor = "IBM", .product = "^2145", @@ -808,7 +815,7 @@ static struct hwentry default_hw[] = { */ { /* - * ONTAP family + * ONTAP FAS/AFF Series * * Maintainer: Martin George */ @@ -825,7 +832,7 @@ static struct hwentry default_hw[] = { }, { /* - * SANtricity(RDAC) family + * SANtricity(RDAC) E/EF Series * * Maintainer: NetApp RDAC team */ @@ -1049,12 +1056,12 @@ static struct hwentry default_hw[] = { .prio_name = PRIO_ALUA, }, /* - * Linux-IO Target + * Linux */ { - /* Linux-IO Target */ + /* Linux-IO (LIO) Target */ .vendor = "(LIO-ORG|SUSE)", - .product = ".", + .product = ".*", .hwhandler = "1 alua", .pgpolicy = GROUP_BY_PRIO, .pgfailback = -FAILBACK_IMMEDIATE, @@ -1107,8 +1114,6 @@ static struct hwentry default_hw[] = { */ { /* OceanStor V3-V6 */ - // This config works with multibus and ALUA - // ALUA is required by HyperMetro .vendor = "HUAWEI", .product = "XSG1", .pgpolicy = GROUP_BY_PRIO, @@ -1202,7 +1207,7 @@ static struct hwentry default_hw[] = { .no_path_retry = 30, }, { - /* 3000 / 6000 Series - ALUA mode */ + /* 3000 / 6000 Series (ALUA mode) */ .vendor = "VIOLIN", .product = "SAN ARRAY ALUA", .hwhandler = "1 alua", diff --git a/libmultipath/lock.h b/libmultipath/lock.h index 20ca77e..9814be7 100644 --- a/libmultipath/lock.h +++ b/libmultipath/lock.h @@ -13,6 +13,11 @@ struct mutex_lock { int waiters; /* uatomic access only */ }; +#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + static inline void init_lock(struct mutex_lock *a) { pthread_mutex_init(&a->mutex, NULL); @@ -46,6 +51,10 @@ static inline bool lock_has_waiters(struct mutex_lock *a) return (uatomic_read(&a->waiters) > 0); } +#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 +#pragma GCC diagnostic pop +#endif + #define lock_cleanup_pop(a) pthread_cleanup_pop(1) void cleanup_lock (void * data); diff --git a/libmultipath/print.c b/libmultipath/print.c index d7d522c..3193dbe 100644 --- a/libmultipath/print.c +++ b/libmultipath/print.c @@ -734,8 +734,12 @@ snprint_host_adapter (struct strbuf *buff, const struct path * pp) static int snprint_path_checker (struct strbuf *buff, const struct path * pp) { - const struct checker * c = &pp->checker; - return snprint_str(buff, checker_name(c)); + const char * n = checker_name(&pp->checker); + + if (n) + return snprint_str(buff, n); + else + return snprint_str(buff, "(null)"); } static int diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile index 400f773..fdec36e 100644 --- a/libmultipath/prioritizers/Makefile +++ b/libmultipath/prioritizers/Makefile @@ -26,7 +26,7 @@ LIBS = \ libpriopath_latency.so \ libpriosysfs.so -ifneq ($(call check_file,$(LINUX_HEADERS_INCDIR)/linux/nvme_ioctl.h),0) +ifneq ($(ANA_SUPPORT),1) LIBS += libprioana.so CPPFLAGS += -I../nvme endif @@ -34,16 +34,16 @@ endif all: $(LIBS) libprio%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) install: $(LIBS) - $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) + $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done + $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done clean: dep_clean - $(RM) core *.a *.o *.gz *.so + $(Q)$(RM) core *.a *.o *.gz *.so OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o .SECONDARY: $(OBJS) @@ -51,4 +51,4 @@ OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index d4f1989..a25cc92 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -5,6 +5,7 @@ */ #include +#include "autoconfig.h" #include "nvme-lib.h" #include "checkers.h" #include "vector.h" @@ -567,13 +568,13 @@ out: } /* - * Current RDAC (NetApp E-Series) firmware relies + * Current RDAC (NetApp E/EF Series) firmware relies * on periodic REPORT TARGET PORT GROUPS for * internal load balancing. * Using the sysfs priority checker defeats this purpose. * * Moreover, NetApp would also prefer the RDAC checker over ALUA. - * (https://www.redhat.com/archives/dm-devel/2017-September/msg00326.html) + * (https://listman.redhat.com/archives/dm-devel/2017-September/msg00326.html) */ static int check_rdac(struct path * pp) diff --git a/libmultipath/structs.c b/libmultipath/structs.c index 7a2ff58..87e84d5 100644 --- a/libmultipath/structs.c +++ b/libmultipath/structs.c @@ -604,149 +604,150 @@ first_path (const struct multipath * mpp) return pgp?VECTOR_SLOT(pgp->paths, 0):NULL; } -int add_feature(char **f, const char *n) +int add_feature(char **features_p, const char *new_feat) { - int c = 0, d, l; - char *e, *t; - const char *p; + int count = 0, new_count, len; + char *tmp, *feats; + const char *ptr; - if (!f) + if (!features_p) return 1; /* Nothing to do */ - if (!n || *n == '\0') + if (!new_feat || *new_feat == '\0') return 0; - l = strlen(n); - if (isspace(*n) || isspace(*(n + l - 1))) { - condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n); + len = strlen(new_feat); + if (isspace(*new_feat) || isspace(*(new_feat + len - 1))) { + condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", + new_feat); return 1; } - p = n; - d = 1; - while (*p != '\0') { - if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0') - d++; - p++; + ptr = new_feat; + new_count = 1; + while (*ptr != '\0') { + if (isspace(*ptr) && !isspace(*(ptr + 1)) && *(ptr + 1) != '\0') + new_count++; + ptr++; } /* default feature is null */ - if(!*f) + if(!*features_p) { - l = asprintf(&t, "%0d %s", d, n); - if(l == -1) + len = asprintf(&feats, "%0d %s", new_count, new_feat); + if(len == -1) return 1; - *f = t; + *features_p = feats; return 0; } /* Check if feature is already present */ - e = *f; - while ((e = strstr(e, n)) != NULL) { - if (isspace(*(e - 1)) && - (isspace(*(e + l)) || *(e + l) == '\0')) + tmp = *features_p; + while ((tmp = strstr(tmp, new_feat)) != NULL) { + if (isspace(*(tmp - 1)) && + (isspace(*(tmp + len)) || *(tmp + len) == '\0')) return 0; - e += l; + tmp += len; } /* Get feature count */ - c = strtoul(*f, &e, 10); - if (*f == e || (!isspace(*e) && *e != '\0')) { - condlog(0, "parse error in feature string \"%s\"", *f); + count = strtoul(*features_p, &tmp, 10); + if (*features_p == tmp || (!isspace(*tmp) && *tmp != '\0')) { + condlog(0, "parse error in feature string \"%s\"", *features_p); return 1; } - c += d; - if (asprintf(&t, "%0d%s %s", c, e, n) < 0) + count += new_count; + if (asprintf(&feats, "%0d%s %s", count, tmp, new_feat) < 0) return 1; - free(*f); - *f = t; + free(*features_p); + *features_p = feats; return 0; } -int remove_feature(char **f, const char *o) +int remove_feature(char **features_p, const char *old_feat) { - int c = 0, d; - char *e, *p, *n; - const char *q; + int count = 0, len; + char *feats_start, *ptr, *new; - if (!f || !*f) + if (!features_p || !*features_p) return 1; /* Nothing to do */ - if (!o || *o == '\0') + if (!old_feat || *old_feat == '\0') return 0; - d = strlen(o); - if (isspace(*o) || isspace(*(o + d - 1))) { - condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", o); + len = strlen(old_feat); + if (isspace(*old_feat) || isspace(*(old_feat + len - 1))) { + condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", + old_feat); return 1; } /* Check if present and not part of a larger feature token*/ - p = *f + 1; /* the size must be at the start of the features string */ - while ((p = strstr(p, o)) != NULL) { - if (isspace(*(p - 1)) && - (isspace(*(p + d)) || *(p + d) == '\0')) + ptr = *features_p + 1; + while ((ptr = strstr(ptr, old_feat)) != NULL) { + if (isspace(*(ptr - 1)) && + (isspace(*(ptr + len)) || *(ptr + len) == '\0')) break; - p += d; + ptr += len; } - if (!p) + if (!ptr) return 0; /* Get feature count */ - c = strtoul(*f, &e, 10); - if (*f == e || !isspace(*e)) { - condlog(0, "parse error in feature string \"%s\"", *f); + count = strtoul(*features_p, &feats_start, 10); + if (*features_p == feats_start || !isspace(*feats_start)) { + condlog(0, "parse error in feature string \"%s\"", *features_p); return 1; } /* Update feature count */ - c--; - q = o; - while (*q != '\0') { - if (isspace(*q) && !isspace(*(q + 1)) && *(q + 1) != '\0') - c--; - q++; + count--; + while (*old_feat != '\0') { + if (isspace(*old_feat) && !isspace(*(old_feat + 1)) && + *(old_feat + 1) != '\0') + count--; + old_feat++; } /* Quick exit if all features have been removed */ - if (c == 0) { - n = malloc(2); - if (!n) + if (count == 0) { + new = malloc(2); + if (!new) return 1; - strcpy(n, "0"); + strcpy(new, "0"); goto out; } /* Update feature count space */ - n = malloc(strlen(*f) - d + 1); - if (!n) + new = malloc(strlen(*features_p) - len + 1); + if (!new) return 1; /* Copy the feature count */ - sprintf(n, "%0d", c); + sprintf(new, "%0d", count); /* * Copy existing features up to the feature * about to be removed */ - strncat(n, e, (size_t)(p - e)); + strncat(new, feats_start, (size_t)(ptr - feats_start)); /* Skip feature to be removed */ - p += d; + ptr += len; /* Copy remaining features */ - while (isspace(*p)) - p++; - if (*p != '\0') - strcat(n, p); + while (isspace(*ptr)) + ptr++; + if (*ptr != '\0') + strcat(new, ptr); else - strchop(n); + strchop(new); out: - free(*f); - *f = n; + free(*features_p); + *features_p = new; return 0; } diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c index 57447ca..bbc8e9e 100644 --- a/libmultipath/uevent.c +++ b/libmultipath/uevent.c @@ -42,6 +42,7 @@ #include #include +#include "autoconfig.h" #include "debug.h" #include "list.h" #include "uevent.h" diff --git a/libmultipath/version.h b/libmultipath/version.h index cc9a5ac..2da0045 100644 --- a/libmultipath/version.h +++ b/libmultipath/version.h @@ -20,9 +20,9 @@ #ifndef _VERSION_H #define _VERSION_H -#define VERSION_CODE 0x000903 +#define VERSION_CODE 0x000904 /* MMDDYY, in hex */ -#define DATE_CODE 0x0A1A16 +#define DATE_CODE 0x0C1316 #define PROG "multipath-tools" diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile index 2219c86..f57c105 100644 --- a/mpathpersist/Makefile +++ b/mpathpersist/Makefile @@ -14,22 +14,22 @@ OBJS = main.o all: $(EXEC) $(EXEC): $(OBJS) - $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) + $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 clean: dep_clean - $(RM) core *.o $(EXEC) + $(Q)$(RM) core *.o $(EXEC) include $(wildcard $(OBJS:.o=.d)) uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) diff --git a/multipath/Makefile b/multipath/Makefile index 116348e..73db991 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -3,57 +3,59 @@ # include ../Makefile.inc +EXEC := multipath + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) CFLAGS += $(BIN_CFLAGS) LDFLAGS += $(BIN_LDFLAGS) LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ldl -ludev -EXEC = multipath - -OBJS = main.o +OBJS := main.o all: $(EXEC) multipath.rules tmpfiles.conf $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + @echo building $@ because of $? + $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) - $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) - $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) + $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ifneq ($(SCSI_DH_MODULES_PRELOAD),) - $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ + $(Q)$(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(Q)for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ >>$(DESTDIR)$(modulesloaddir)/scsi_dh.conf endif uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 clean: dep_clean - $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf + $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) %: %.in - sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ + @echo creating $@ + $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ diff --git a/multipath/main.c b/multipath/main.c index 7b69a3c..b9f360b 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -435,7 +435,8 @@ static bool released_to_systemd(void) bool ret; ret = dm_mp_dev_path != NULL && !strcmp(dm_mp_dev_path, "0"); - condlog(4, "%s: %s=%s -> %d", __func__, dmdp, dm_mp_dev_path, ret); + condlog(4, "%s: %s=%s -> %d", __func__, dmdp, + dm_mp_dev_path ? dm_mp_dev_path : "", ret); return ret; } diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 index 1fea9d5..b4dccd1 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -6,7 +6,7 @@ .\" Update the date below if you make any significant change. .\" ---------------------------------------------------------------------------- . -.TH MULTIPATH.CONF 5 2022-09-09 Linux +.TH MULTIPATH.CONF 5 2022-10-01 Linux . . .\" ---------------------------------------------------------------------------- @@ -178,7 +178,7 @@ The default is: \fBno\fR . .TP .B multipath_dir -This option is not supported any more. The value is ignored. +(Deprecated) This option is not supported any more, and the value is ignored. . . .TP @@ -205,10 +205,6 @@ of outstanding I/O to the path and its relative throughput. estimation of future service time based on the history of previous I/O submitted to each path. .TP -.I "io-affinity 0" -(Since 5.11 kernel) Choose the path for the next bunch of I/O based on a CPU to -path mapping the user passes in and what CPU we are executing on. -.TP The default is: \fBservice-time 0\fR .RE . @@ -242,6 +238,11 @@ The default is: \fBfailover\fR . . .TP +.B pg_timeout +(Deprecated) This option is not supported any more, and the value is ignored. +. +. +.TP .B uid_attrs . Setting this option activates \fBmerging uevents\fR by WWID, which may improve @@ -283,7 +284,7 @@ The default is: \fBID_WWN\fR, for NVMe devices . .TP .B getuid_callout -This option is not supported any more. The value is ignored. +(Deprecated) This option is not supported any more, and the value is ignored. . . .TP @@ -315,7 +316,8 @@ accepts the optional prio_arg \fIexclusive_pref_bit\fR. .TP .I ontap (Hardware-dependent) -Generate the path priority for NetApp ONTAP class, and rebranded arrays. +Generate the path priority for NetApp ONTAP FAS/AFF Series and rebranded arrays, +with ONTAP native mode(not ALUA). .TP .I rdac (Hardware-dependent) @@ -358,7 +360,7 @@ prio_args keyword. .PP The default depends on the \fBdetect_prio\fR setting: If \fBdetect_prio\fR is \fByes\fR (default), the default priority algorithm is \fBsysfs\fR (except for -NetAPP E-Series, where it is \fBalua\fR). If \fBdetect_prio\fR is +NetAPP E/EF Series, where it is \fBalua\fR). If \fBdetect_prio\fR is \fBno\fR, the default priority algorithm is \fBconst\fR. .RE . @@ -467,7 +469,7 @@ cannot be changed. \fInvme:tcp\fR paths are only supported in multipath devices with queue_mode set to \fIbio\fR. multipath will automatically set this when creating a device with \fInvme:tcp\fR paths. .TP -The default is: \fB\fR +The default is: \fB0\fR .RE . . @@ -483,7 +485,7 @@ second, until \fIchecker_timeout\fR seconds have elapsed. Possible values are: .TP 12 .I readsector0 (Deprecated) Read the first sector of the device. This checker is being -deprecated, please use \fItur\fR instead. +deprecated, please use \fItur\fR or \fIdirectio\fR instead. .TP .I tur Issue a \fITEST UNIT READY\fR command to the device. @@ -555,7 +557,7 @@ The default is: \fBmanual\fR . . .TP -.B rr_min_io +.B rr_min_io Number of I/O requests to route to a path before switching to the next in the same path group. This is only for \fIBlock I/O\fR(BIO) based multipath and only apply to \fIround-robin\fR path_selector. @@ -706,18 +708,33 @@ The default is: \fB5\fR . .TP .B dev_loss_tmo -Specify the number of seconds the SCSI layer will wait after a problem has -been detected on a FC remote port before removing it from the system. This -can be set to "infinity" which sets it to the max value of 2147483647 -seconds, or 68 years. It will be automatically adjusted to the overall -retry interval \fIno_path_retry\fR * \fIpolling_interval\fR -if a number of retries is given with \fIno_path_retry\fR and the -overall retry interval is longer than the specified \fIdev_loss_tmo\fR value. -The Linux kernel will cap this value to \fI600\fR if \fIfast_io_fail_tmo\fR -is not set. See KNOWN ISSUES. +Specify the number of seconds the SCSI layer will wait after a connection loss has +been detected on a remote port before removing it from the system. This +can be set to "infinity", which effectively means 136 years (2^32-1 seconds). +This parameter is only applied to Fibre Channel and SAS devices. .RS +.LP +The value of \fIdev_loss_tmo\fR is restricted by other settings. +If \fIfast_io_fail_tmo\fR is set to a positive value, \fBmultipathd\fR +will make sure that the value of \fIdev_loss_tmo\fR is larger than +\fIno_path_retry\fR * \fIpolling_interval\fR. +If \fIfast_io_fail_tmo\fR is not set, the kernel limits the \fIdev_loss_tmo\fR +value to 600 seconds. +In this case, the user has to make sure that \fIno_path_retry\fR is smaller +than \fIdev_loss_tmo / polling_interval\fR. In particular, +\fIno_path_retry\fR must not be set to \(dq\fIqueue\fR\(dq. See KNOWN ISSUES. +.LP +When path devices reappear after a connection loss, it is much easier for +the kernel to simply reactivate an inactive device than to re-add +a previously deleted one. It is therefore recommended to set +\fIdev_loss_tmo\fR to a large value within the restrictions mentioned above. +.LP +Fibre Channel and SAS devices have hardware-dependent defaults, which are left +unchanged if \fIdev_loss_tmo\fR is not specified. For a few storage arrays, +the multipath-tools built-in settings override the default. Run \fImultipath -T\fR +to see the settings for your device. .TP -The default is: \fB600\fR +The default is: \fB\fR .RE . . @@ -739,7 +756,7 @@ The default is: \fB\fR . .TP .B bindings_file -This option is deprecated, and will be removed in a future release. +(Deprecated) This option is deprecated, and will be removed in a future release. The full pathname of the binding file to be used when the user_friendly_names option is set. .RS @@ -750,7 +767,7 @@ The default is: \fB/etc/multipath/bindings\fR . .TP .B wwids_file -This option is deprecated, and will be removed in a future release. +(Deprecated) This option is deprecated, and will be removed in a future release. The full pathname of the WWIDs file, which is used by multipath to keep track of the WWIDs for LUNs it has created multipath devices on in the past. .RS @@ -761,7 +778,7 @@ The default is: \fB/etc/multipath/wwids\fR . .TP .B prkeys_file -This option is deprecated, and will be removed in a future release. +(Deprecated) This option is deprecated, and will be removed in a future release. The full pathname of the prkeys file, which is used by multipathd to keep track of the persistent reservation key used for a specific WWID, when \fIreservation_key\fR is set to \fBfile\fR. @@ -933,7 +950,7 @@ The default is: \fB\fR . .TP .B config_dir -This option is not supported any more. The value is ignored. +(Deprecated) This option is not supported any more, and the value is ignored. . . .TP @@ -1046,7 +1063,7 @@ The default is: \fBno\fR . .TP .B delay_watch_checks -This option is \fBdeprecated\fR, and mapped to \fIsan_path_err_forget_rate\fR. +(Deprecated) This option is \fBdeprecated\fR, and mapped to \fIsan_path_err_forget_rate\fR. If this is set to a value greater than 0 and no \fIsan_path_err\fR options are set, \fIsan_path_err_forget_rate\fR will be set to the value of \fIdelay_watch_checks\fR and \fIsan_path_err_threshold\fR will be set to 1. @@ -1060,7 +1077,7 @@ The default is: \fBno\fR . .TP .B delay_wait_checks -This option is \fBdeprecated\fR, and mapped to \fIsan_path_err_recovery_time\fR. +(Deprecated) This option is \fBdeprecated\fR, and mapped to \fIsan_path_err_recovery_time\fR. If this is set to a value greater than 0 and no \fIsan_path_err\fR options are set, \fIsan_path_err_recovery_time\fR will be set to the value of \fIdelay_wait_checks\fR times \fImax_polling_interval\fR. This will give @@ -1227,8 +1244,7 @@ The default is: \fBno\fR . .TP .B disable_changed_wwids -This option is deprecated and ignored. If the WWID of a path suddenly changes, -multipathd handles it as if it was removed and then added again. +(Deprecated) This option is not supported any more, and the value is ignored. .RE . . @@ -1292,8 +1308,6 @@ wwid. The default is: \fBno\fR .RE . -. - . .\" ---------------------------------------------------------------------------- .SH "blacklist and blacklist_exceptions sections" @@ -1849,10 +1863,10 @@ normal pathgroup. The logic of determining \(dqshaky\(dq condition, as well as the logic when to reinstate, differs between the three methods. .TP 8 .B \(dqdelay_checks\(dq failure tracking -This method is \fBdeprecated\fR and mapped to the \(dqsan_path_err\(dq method. +(Deprecated) This method is \fBdeprecated\fR and mapped to the \(dqsan_path_err\(dq method. See the \fIdelay_watch_checks\fR and \fIdelay_wait_checks\fR options above for more information. - +. .TP .B \(dqmarginal_path\(dq failure tracking If a second failure event (good->bad transition) occurs within @@ -1877,18 +1891,19 @@ increase and the threshold is never reached. Ticks are the time between path checks by multipathd, which is variable and controlled by the \fIpolling_interval\fR and \fImax_polling_interval\fR parameters. . +.RS 8 +.LP +This algorithm is superseded by the \(dqmarginal_path\(dq failure tracking, +but remains supported for backward compatibility. +. +.RE .TP -.B \(dqFPIN \(dq failure tracking +.B \(dqFPIN\(dq failure tracking Fibre channel fabrics can notify hosts about fabric-level issues such as integrity failures or congestion with so-called Fabric Performance Impact Notifications (FPINs).On receiving the fpin notifications through ELS multipathd will move the affected path and port states to marginal. . -.RS 8 -.LP -This method is \fBdeprecated\fR in favor of the \(dqmarginal_path\(dq failure -tracking method, and only offered for backward compatibility. -. .RE .LP See the documentation @@ -1924,6 +1939,7 @@ size=167772160 features='n/a' hwhandler='ANA' wp=rw The \(dqnvme\(dq foreign library provides support for NVMe native multipathing in the kernel. It is part of the standard multipath package. . +. .\" ---------------------------------------------------------------------------- .SH "KNOWN ISSUES" .\" ---------------------------------------------------------------------------- diff --git a/multipathd/Makefile b/multipathd/Makefile index 3ce9465..9d53132 100644 --- a/multipathd/Makefile +++ b/multipathd/Makefile @@ -1,109 +1,87 @@ include ../Makefile.inc -ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO -endif +EXEC := multipathd +CLI := multipathc + +CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ + $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ + awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ + -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) -ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - FPIN_SUPPORT = 1 -endif # # debugging stuff # #CPPFLAGS += -DLCKDBG -#CPPFLAGS += -D_DEBUG_ #CPPFLAGS += -DLOGDBG -CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ - $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ - awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ - -DBINDIR='"$(bindir)"' CFLAGS += $(BIN_CFLAGS) LDFLAGS += $(BIN_LDFLAGS) -CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread -LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -ldevmapper $(CLI_LIBDEPS) - +CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ + -ludev -ldl -lurcu -lpthread $(SYSTEMD_LIBDEPS) +LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ + -ldevmapper $(CLI_LIBDEPS) ifeq ($(READLINE),libedit) -RL_CPPFLAGS = -DUSE_LIBEDIT -RL_LIBDEPS += -ledit -endif -ifeq ($(READLINE),libreadline) -RL_CPPFLAGS += -DUSE_LIBREADLINE -RL_LIBDEPS += -lreadline -# See comment in uxclnt.c +RL_CPPFLAGS := -DUSE_LIBEDIT +RL_LIBDEPS := -ledit +# See comment in multipathc.c ifeq ($(shell sed -En 's/.*\pathvec, 1, width); - if (snprint_path(reply, style, pp, 0) < 0) + if (snprint_path(reply, style, pp, NULL) < 0) return 1; return 0; } diff --git a/multipathd/fpin.h b/multipathd/fpin.h index bfcc1ce..3c37444 100644 --- a/multipathd/fpin.h +++ b/multipathd/fpin.h @@ -1,5 +1,6 @@ #ifndef __FPIN_H__ #define __FPIN_H__ +#include "autoconfig.h" #ifdef FPIN_EVENT_HANDLER void *fpin_fabric_notification_receiver(void *unused); diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c index a2de301..8f464f0 100644 --- a/multipathd/fpin_handlers.c +++ b/multipathd/fpin_handlers.c @@ -517,6 +517,8 @@ void *fpin_fabric_notification_receiver(__attribute__((unused))void *unused) goto out; } for ( ; ; ) { + struct nlmsghdr *msghdr; + condlog(4, "Waiting for ELS...\n"); ret = read(fd, buf, DEF_RX_BUF_SIZE); if (ret < 0) { @@ -524,12 +526,13 @@ void *fpin_fabric_notification_receiver(__attribute__((unused))void *unused) continue; } condlog(4, "Got a new request %d\n", ret); - if (!NLMSG_OK((struct nlmsghdr *)buf, (unsigned int)ret)) { + msghdr = (struct nlmsghdr *)buf; + if (!NLMSG_OK(msghdr, (unsigned int)ret)) { condlog(0, "bad els frame read (%d)", ret); continue; } /* Push the frame to appropriate frame list */ - plen = NLMSG_PAYLOAD((struct nlmsghdr *)buf, 0); + plen = NLMSG_PAYLOAD(msghdr, 0); fc_event = (struct fc_nl_event *)NLMSG_DATA(buf); if (plen < sizeof(*fc_event)) { condlog(0, "too short (%d) to be an FC event", ret); diff --git a/multipathd/main.c b/multipathd/main.c index ba52d39..1e1b254 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -4,6 +4,7 @@ * Copyright (c) 2005 Benjamin Marzinski, Redhat * Copyright (c) 2005 Edward Goggin, EMC */ +#include "autoconfig.h" #include #include #include diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..c3a8e7a --- /dev/null +++ b/rules.mk @@ -0,0 +1,18 @@ +# Copyright (c) SUSE LLC +# SPDX-License-Identifier: GPL-2.0-or-later + +$(DEVLIB): $(LIBS) + $(Q)$(LN) $(LIBS) $@ + +$(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + +$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + +abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) + +$(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: + $(Q)$(MAKE) -C $(TOPDIR) -f create-config.mk diff --git a/tests/Makefile b/tests/Makefile index 3a5b161..860338b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,14 +3,6 @@ include ../Makefile.inc # directory where to run the tests TESTDIR := $(CURDIR) -# Test special behavior of gcc 4.8 with nested initializers -# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers -TEST_MISSING_INITIALIZERS = $(shell \ - echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ - $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ - || echo -Wno-missing-field-initializers) -W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) -I$(daemondir) \ -DTESTCONFDIR=\"$(TESTDIR)/conf.d\" CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) @@ -20,7 +12,6 @@ TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ alias directio valid devt mpathvalid strbuf sysfs features cli HELPERS := test-lib.o test-log.o -.SILENT: $(TESTS:%=%.o) .PRECIOUS: $(TESTS:%=%-test) all: $(TESTS:%=%.out) @@ -79,15 +70,16 @@ features-test_LIBDEPS := -ludev -lpthread cli-test_OBJDEPS := $(daemondir)/cli.o %.o: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< + @echo building $@ because of $? + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< lib/libchecktur.so: - mkdir -p lib - cd lib && ln -s ../$(multipathdir)/*/*.so . + @mkdir -p lib + $(Q)cd lib && ln -s ../$(multipathdir)/*/*.so . %.out: %-test lib/libchecktur.so @echo == running $< == - @LD_LIBRARY_PATH=.:$(mpathutildir):$(mpathcmddir) ./$< >$@ 2>&1 + @LD_LIBRARY_PATH=.:$(mpathutildir):$(mpathcmddir) ./$< >$@ 2>&1 || { cat "$@"; false; } %.vgr: %-test lib/libchecktur.so @echo == running valgrind for $< == @@ -97,34 +89,38 @@ lib/libchecktur.so: OBJS = $(TESTS:%=%.o) $(HELPERS) test_clean: - $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* + $(Q)$(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* valgrind_clean: - $(RM) $(TESTS:%=%.vgr) + $(Q)$(RM) $(TESTS:%=%.vgr) clean: test_clean valgrind_clean dep_clean - $(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap - $(RM) -rf lib conf.d + $(Q)$(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap + $(Q)$(RM) -rf lib conf.d .SECONDARY: $(OBJS) include $(wildcard $(OBJS:.o=.d)) dep_clean: - $(RM) $(OBJS:.o=.d) + $(Q)$(RM) $(OBJS:.o=.d) %.o.wrap: %.c @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ sort -u | tr '\n' ' ' >$@ +# Pass the original values of CFLAGS etc. to the sub-make, which will include +# Makefile.in again. Otherwise, the flags would be added twice. libmultipath.so.0: $(multipathdir)/libmultipath.so.0 - make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib + @CFLAGS=$(ORIG_CFLAGS) CPPFLAGS=$(ORIG_CPPFLAGS) LDFLAGS=$(ORIG_LDFLAGS) \ + $(MAKE) -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib # COLON will get expanded during second expansion below COLON:=: .SECONDEXPANSION: %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ libmultipath.so.0 $(mpathutildir)/libmpathutil.so.0 $(mpathcmddir)/libmpathcmd.so.0 Makefile - $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ + @echo building $@ + $(Q)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ $(LIBDEPS) $($@_LIBDEPS) \ $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) diff --git a/tests/directio.c b/tests/directio.c index 01fdef2..db9643e 100644 --- a/tests/directio.c +++ b/tests/directio.c @@ -34,9 +34,15 @@ int ev_off = 0; struct timespec zero_timeout = { .tv_sec = 0 }; struct timespec full_timeout = { .tv_sec = -1 }; -int __real_ioctl(int fd, unsigned long request, void *argp); +#ifdef __GLIBC__ +#define ioctl_request_t unsigned long +#else +#define ioctl_request_t int +#endif + +int __real_ioctl(int fd, ioctl_request_t request, void *argp); -int __wrap_ioctl(int fd, unsigned long request, void *argp) +int __wrap_ioctl(int fd, ioctl_request_t request, void *argp) { #ifdef DIO_TEST_DEV mock_type(int); @@ -45,7 +51,15 @@ int __wrap_ioctl(int fd, unsigned long request, void *argp) int *blocksize = (int *)argp; assert_int_equal(fd, test_fd); - assert_int_equal(request, BLKBSZGET); + /* + * On MUSL libc, the "request" arg is an int (glibc: unsigned long). + * cmocka casts the args of assert_int_equal() to "unsigned long". + * BLKSZGET = 80081270 is sign-extended to ffffffff80081270 + * when cast from int to unsigned long on s390x. + * BLKSZGET must be cast to "int" and back to "unsigned long", + * otherwise the assertion below will fail. + */ + assert_int_equal(request, (ioctl_request_t)BLKBSZGET); assert_non_null(blocksize); *blocksize = mock_type(int); return 0; -- 2.34.1