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:
bionic:
runs-on: ubuntu-18.04
strategy:
+ fail-fast: false
matrix:
rl: ['', 'libreadline', 'libedit']
steps:
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
focal-gcc10:
runs-on: ubuntu-20.04
strategy:
+ fail-fast: false
matrix:
rl: ['', 'libreadline', 'libedit']
steps:
- 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
focal-clang10:
runs-on: ubuntu-20.04
strategy:
+ fail-fast: false
matrix:
rl: ['', 'libreadline', 'libedit']
steps:
- 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
- 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
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 }}"
--- /dev/null
+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 }}"
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
- 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
--- /dev/null
+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
*.gz
*.d
\#*
+config.mk
cscope.files
cscope.out
kpartx/kpartx
tests/*.vgr
libmultipath/nvme-ioctl.c
libmultipath/nvme-ioctl.h
+libmultipath/autoconfig.h
*/*-nv.version
reference-abi
# Copyright (C) 2003 Christophe Varoqui, <christophe.varoqui@opensvc.com>
#
+TOPDIR := .
+
LIB_BUILDDIRS := \
libmpathcmd \
libmpathutil \
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
# 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
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
-#
+# -*- Makefile -*-
# Copyright (C) 2004 Christophe Varoqui, <christophe.varoqui@opensvc.com>
#
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 <string.h>\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' >>$@
+
========================
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:
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
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
------------------------
============
(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
- 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 <igroup_name>", and to enable ALUA:
"igroup set <igroup_name> alua yes".
--- /dev/null
+# 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 <urcu/uatomic.h>\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 <string.h>\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 <string.h>\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)" >>$@
#
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)
#include <ctype.h>
#include <errno.h>
#include <sys/sysmacros.h>
+#include "autoconfig.h"
#include "devmapper.h"
#include "kpartx.h"
#include <ctype.h>
#include <libdevmapper.h>
+#include "autoconfig.h"
#include "devmapper.h"
#include "crc32.h"
#include "lopart.h"
UUID=$3
if [ -z "$MAJOR" -o -z "$MINOR" ]; then
- echo "usage: $0 major minor"
+ echo "usage: $0 major minor UUID"
exit 1;
fi
#
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
.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)
#
# Copyright (C) 2015-2016 Gris Ge <fge@redhat.com>
#
+TOPDIR := ../..
include ../../Makefile.inc
_libdmmpdir=../$(libdmmpdir)
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 \
$(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)
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)
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)
#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];
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);
}
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);
}
#
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
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)
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));
validate_config_strvec(vector strvec, const char *file)
{
char *str = NULL;
- int i;
if (strvec && VECTOR_SIZE(strvec) > 0)
str = VECTOR_SLOT(strvec, 0);
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;
}
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)
#
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
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)
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)
include $(wildcard $(OBJS:.o=.d))
dep_clean:
- $(RM) $(OBJS:.o=.d)
+ $(Q)$(RM) $(OBJS:.o=.d)
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;
}
#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"
#ifndef _DEVMAPPER_H
#define _DEVMAPPER_H
-
+#include "autoconfig.h"
#include "structs.h"
#define TGT_MPATH "multipath"
#include <errno.h>
#include <inttypes.h>
#include <libudev.h>
+#include "autoconfig.h"
#include "mpath_cmd.h"
#include "dict.h"
#include "strbuf.h"
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)
{
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);
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);
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, \
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 \
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, \
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, \
}
-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,
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)
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)
/*
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);
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);
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);
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)
include $(wildcard $(OBJS:.o=.d))
dep_clean:
- $(RM) $(OBJS:.o=.d)
+ $(Q)$(RM) $(OBJS:.o=.d)
.prio_name = PRIO_ALUA,
},
{
- /* Nimble Storage / HPE Alletra 6000 */
+ /* Nimble Storage / HPE Alletra 5000/6000 */
.vendor = "Nimble",
.product = "Server",
.hwhandler = "1 alua",
.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",
.pgpolicy = MULTIBUS,
},
{
- /* SC Series, formerly Compellent */
+ /* SC Series (formerly Compellent) */
.vendor = "COMPELNT",
.product = "Compellent Vol",
.pgpolicy = GROUP_BY_PRIO,
{
/*
* ETERNUS AB/HB
+ *
* Maintainer: NetApp RDAC team <ng-eseries-upstream-maintainers@netapp.com>
*/
.vendor = "FUJITSU",
.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",
*/
{
/*
- * ONTAP family
+ * ONTAP FAS/AFF Series
*
* Maintainer: Martin George <marting@netapp.com>
*/
},
{
/*
- * SANtricity(RDAC) family
+ * SANtricity(RDAC) E/EF Series
*
* Maintainer: NetApp RDAC team <ng-eseries-upstream-maintainers@netapp.com>
*/
.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,
*/
{
/* OceanStor V3-V6 */
- // This config works with multibus and ALUA
- // ALUA is required by HyperMetro
.vendor = "HUAWEI",
.product = "XSG1",
.pgpolicy = GROUP_BY_PRIO,
.no_path_retry = 30,
},
{
- /* 3000 / 6000 Series - ALUA mode */
+ /* 3000 / 6000 Series (ALUA mode) */
.vendor = "VIOLIN",
.product = "SAN ARRAY ALUA",
.hwhandler = "1 alua",
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);
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);
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
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
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)
include $(wildcard $(OBJS:.o=.d))
dep_clean:
- $(RM) $(OBJS:.o=.d)
+ $(Q)$(RM) $(OBJS:.o=.d)
*/
#include <stdio.h>
+#include "autoconfig.h"
#include "nvme-lib.h"
#include "checkers.h"
#include "vector.h"
}
/*
- * 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)
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;
}
#include <sys/time.h>
#include <libudev.h>
+#include "autoconfig.h"
#include "debug.h"
#include "list.h"
#include "uevent.h"
#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"
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)
#
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),' $< >$@
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;
}
.\" 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
.
.
.\" ----------------------------------------------------------------------------
.
.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
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
.
.
.
.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
.
.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
.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)
.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
.
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<unset>\fR
+The default is: \fB0\fR
.RE
.
.
.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.
.
.
.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.
.
.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<hardware dependent>\fR
.RE
.
.
.
.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
.
.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
.
.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.
.
.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
.
.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.
.
.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
.
.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
.
.
The default is: \fBno\fR
.RE
.
-.
-
.
.\" ----------------------------------------------------------------------------
.SH "blacklist and blacklist_exceptions sections"
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
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
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"
.\" ----------------------------------------------------------------------------
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/.*\<Function\s*\*rl_completion_entry_function;.*/yes/p' /usr/include/editline/readline.h),yes)
RL_CPPFLAGS += -DBROKEN_RL_COMPLETION_FUNC
endif
endif
-
-ifdef SYSTEMD
- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD)
- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1)
- CLI_LIBDEPS += -lsystemd
- else
- CLI_LIBDEPS += -lsystemd-daemon
- endif
-endif
-ifeq ($(ENABLE_DMEVENTS_POLL),0)
- CPPFLAGS += -DNO_DMEVENTS_POLL
+ifeq ($(READLINE),libreadline)
+RL_CPPFLAGS := -DUSE_LIBREADLINE
+RL_LIBDEPS := -lreadline
endif
-OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \
+CLI_OBJS := multipathc.o cli.o
+OBJS := main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \
dmevents.o init_unwinder.o
-
-CLI_OBJS = multipathc.o cli.o
-
ifeq ($(FPIN_SUPPORT),1)
OBJS += fpin_handlers.o
endif
-
-
-EXEC = multipathd
-CLI = multipathc
-
all : $(EXEC) $(CLI)
$(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
- $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS)
+ @echo building $@ because of $?
+ $(Q)$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS)
multipathc.o: multipathc.c
- $(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $<
+ $(Q)$(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $<
$(CLI): $(CLI_OBJS)
- $(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS)
+ @echo building $@ because of $?
+ $(Q)$(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS)
cli_handlers.o: cli_handlers.c
- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $<
+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $<
install:
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir)
+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
+ $(Q)$(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir)
ifdef SYSTEMD
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir)
+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir)
+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir)
+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir)
endif
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir)
- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(man8dir)
+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8
+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8
+ $(Q)$(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8
uninstall:
- $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI)
- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8
- $(RM) $(DESTDIR)$(man8dir)/$(CLI).8
- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service
- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket
+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI)
+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8
+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8
+ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).service
+ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket
clean: dep_clean
- $(RM) core *.o $(EXEC) $(CLI)
+ $(Q)$(RM) core *.o $(EXEC) $(CLI)
include $(wildcard $(OBJS:.o=.d))
dep_clean:
- $(RM) $(OBJS:.o=.d)
+ $(Q)$(RM) $(OBJS:.o=.d)
show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp,
char *style)
{
- fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
-
- if ((width = alloc_path_layout()) == NULL)
- return 1;
- get_path_layout(vecs->pathvec, 1, width);
- if (snprint_path(reply, style, pp, 0) < 0)
+ if (snprint_path(reply, style, pp, NULL) < 0)
return 1;
return 0;
}
#ifndef __FPIN_H__
#define __FPIN_H__
+#include "autoconfig.h"
#ifdef FPIN_EVENT_HANDLER
void *fpin_fabric_notification_receiver(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) {
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);
* Copyright (c) 2005 Benjamin Marzinski, Redhat
* Copyright (c) 2005 Edward Goggin, EMC
*/
+#include "autoconfig.h"
#include <unistd.h>
#include <sys/stat.h>
#include <libdevmapper.h>
--- /dev/null
+# 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
# 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)
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)
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 $< ==
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))
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);
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;