diff --git a/SOURCES/0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch b/SOURCES/0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch new file mode 100644 index 0000000..cd054ce --- /dev/null +++ b/SOURCES/0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch @@ -0,0 +1,26 @@ +From 07b154fbc817e93f58c597644570a633c38d1c72 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Jan 2021 12:51:02 +0100 +Subject: [PATCH] ci: PowerTools repo was renamed to powertools in RHEL 8.3 + +See: https://wiki.centos.org/Manuals/ReleaseNotes/CentOS8.2011#Yum_repo_file_and_repoid_changes + +rhel-only +Related: #1871827 +--- + ci/travis-centos-rhel8.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index cd0857fd29..43e2cb2585 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -95,7 +95,7 @@ for phase in "${PHASES[@]}"; do + # Upgrade the container to get the most recent environment + $DOCKER_EXEC dnf -y upgrade + # Install systemd's build dependencies +- $DOCKER_EXEC dnf -q -y --enablerepo "PowerTools" builddep systemd ++ $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd + ;; + RUN) + info "Run phase" diff --git a/SOURCES/0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch b/SOURCES/0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch new file mode 100644 index 0000000..db85595 --- /dev/null +++ b/SOURCES/0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch @@ -0,0 +1,33 @@ +From 2dd82aad646bde5a0d49df8562e2578c8b3d04f4 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Jan 2021 13:00:33 +0100 +Subject: [PATCH] ci: use quay.io instead of Docker Hub to avoid rate limits + +Docker Hub introduced rate limits for anonymous users (100 requests per +six hours), which break our CI in the busier periods. Let's try to use +the quay.io CentOS image to mitigate this. + +rhel-only +Related: #1871827 +--- + ci/travis-centos-rhel8.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index 43e2cb2585..ffe5813b1a 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -81,11 +81,11 @@ for phase in "${PHASES[@]}"; do + info "Setup phase" + info "Using Travis $CENTOS_RELEASE" + # Pull a Docker image and start a new container +- docker pull centos:$CENTOS_RELEASE ++ docker pull quay.io/centos/centos:$CENTOS_RELEASE + info "Starting container $CONT_NAME" + $DOCKER_RUN -v $REPO_ROOT:/build:rw \ + -w /build --privileged=true --name $CONT_NAME \ +- -dit --net=host centos:$CENTOS_RELEASE /sbin/init ++ -dit --net=host quay.io/centos/centos:$CENTOS_RELEASE /sbin/init + # Beautiful workaround for Fedora's version of Docker + sleep 1 + $DOCKER_EXEC dnf makecache diff --git a/SOURCES/0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch b/SOURCES/0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch new file mode 100644 index 0000000..70ba33f --- /dev/null +++ b/SOURCES/0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch @@ -0,0 +1,338 @@ +From 88ac207cc619935c64923e6f8fdef324a5b733d8 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Jan 2021 15:13:53 +0100 +Subject: [PATCH] ci: move jobs from Travis CI to GH Actions + +The OSS version of Travis CI is going to be merged with the commercial +one soon, essentially dropping the free tier, so let's move the CI jobs +to GitHub Actions to keep them up. + +rhel-only +Related: #1871827 +--- + .../workflows/unit_tests.sh | 28 +++---- + .github/workflows/unit_tests.yml | 28 +++++++ + .travis.yml | 48 ------------ + ci/travis-centos-rhel7.sh | 73 ------------------- + ci/travis_wait.bash | 61 ---------------- + 5 files changed, 37 insertions(+), 201 deletions(-) + rename ci/travis-centos-rhel8.sh => .github/workflows/unit_tests.sh (82%) + create mode 100644 .github/workflows/unit_tests.yml + delete mode 100644 .travis.yml + delete mode 100755 ci/travis-centos-rhel7.sh + delete mode 100644 ci/travis_wait.bash + +diff --git a/ci/travis-centos-rhel8.sh b/.github/workflows/unit_tests.sh +similarity index 82% +rename from ci/travis-centos-rhel8.sh +rename to .github/workflows/unit_tests.sh +index ffe5813b1a..ea4f7e7592 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/.github/workflows/unit_tests.sh +@@ -1,18 +1,9 @@ + #!/bin/bash + +-# Run this script from the root of the systemd's git repository +-# or set REPO_ROOT to a correct path. +-# +-# Example execution on Fedora: +-# dnf install docker +-# systemctl start docker +-# export CONT_NAME="my-fancy-container" +-# ci/travis-centos.sh SETUP RUN CLEANUP +- + PHASES=(${@:-SETUP RUN CLEANUP}) + CENTOS_RELEASE="${CENTOS_RELEASE:-latest}" + CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" +-DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" ++DOCKER_EXEC="${DOCKER_EXEC:-docker exec $CONT_NAME}" + DOCKER_RUN="${DOCKER_RUN:-docker run}" + REPO_ROOT="${REPO_ROOT:-$PWD}" + ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq diffutils) +@@ -71,9 +62,7 @@ function info() { + echo -e "\033[33;1m$1\033[0m" + } + +-set -e +- +-source "$(dirname $0)/travis_wait.bash" ++set -ex + + for phase in "${PHASES[@]}"; do + case $phase in +@@ -86,6 +75,7 @@ for phase in "${PHASES[@]}"; do + $DOCKER_RUN -v $REPO_ROOT:/build:rw \ + -w /build --privileged=true --name $CONT_NAME \ + -dit --net=host quay.io/centos/centos:$CENTOS_RELEASE /sbin/init ++ + # Beautiful workaround for Fedora's version of Docker + sleep 1 + $DOCKER_EXEC dnf makecache +@@ -97,10 +87,10 @@ for phase in "${PHASES[@]}"; do + # Install systemd's build dependencies + $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd + ;; +- RUN) ++ RUN|RUN_GCC) + info "Run phase" + # Build systemd +- docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}" ++ docker exec -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}" + $DOCKER_EXEC ninja -v -C build + # Let's install the new systemd and "reboot" the container to avoid + # unexpected fails due to incompatibilities with older systemd +@@ -108,16 +98,16 @@ for phase in "${PHASES[@]}"; do + docker restart $CONT_NAME + $DOCKER_EXEC ninja -C build test + ;; +- RUN_ASAN|RUN_CLANG_ASAN) ++ RUN_ASAN|RUN_GCC_ASAN|RUN_CLANG_ASAN) + if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then + ENV_VARS="-e CC=clang -e CXX=clang++" + MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764 + fi +- docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}" +- docker exec -it $CONT_NAME ninja -v -C build ++ docker exec $ENV_VARS $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}" ++ docker exec $CONT_NAME ninja -v -C build + + # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb. +- travis_wait docker exec --interactive=false \ ++ docker exec --interactive=false \ + -e UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 \ + -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \ + -e "TRAVIS=$TRAVIS" \ +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +new file mode 100644 +index 0000000000..15f5127a75 +--- /dev/null ++++ b/.github/workflows/unit_tests.yml +@@ -0,0 +1,28 @@ ++--- ++# vi: ts=2 sw=2 et: ++# ++name: Unit tests ++on: ++ pull_request: ++ branches: ++ - master ++ ++jobs: ++ build: ++ runs-on: ubuntu-20.04 ++ env: ++ CENTOS_RELEASE: "centos8" ++ CONT_NAME: "systemd-centos8-ci" ++ strategy: ++ fail-fast: false ++ matrix: ++ run_phase: [GCC, GCC_ASAN] ++ steps: ++ - name: Repository checkout ++ uses: actions/checkout@v1 ++ - name: Install build dependencies ++ run: sudo -E .github/workflows/unit_tests.sh SETUP ++ - name: Build & test (${{ matrix.run_phase }}) ++ run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }} ++ - name: Cleanup ++ run: sudo -E .github/workflows/unit_tests.sh CLEANUP +diff --git a/.travis.yml b/.travis.yml +deleted file mode 100644 +index 70c60cf24e..0000000000 +--- a/.travis.yml ++++ /dev/null +@@ -1,48 +0,0 @@ +-sudo: required +-dist: xenial +-services: +- - docker +- +-env: +- global: +- - CI_ROOT="$TRAVIS_BUILD_DIR/ci/" +- +-jobs: +- include: +- - name: CentOS 8 +- language: bash +- env: +- - CENTOS_RELEASE="centos8" +- - CONT_NAME="systemd-centos-$CENTOS_RELEASE" +- - DOCKER_EXEC="docker exec -ti $CONT_NAME" +- before_install: +- - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce +- - docker --version +- install: +- - $CI_ROOT/travis-centos-rhel8.sh SETUP +- script: +- - set -e +- # Build systemd +- - $CI_ROOT/travis-centos-rhel8.sh RUN +- - set +e +- after_script: +- - $CI_ROOT/travis-centos-rhel8.sh CLEANUP +- +- - name: CentOS 8 (ASan+UBSan) +- language: bash +- env: +- - CENTOS_RELEASE="centos8" +- - CONT_NAME="systemd-centos-$CENTOS_RELEASE" +- - DOCKER_EXEC="docker exec -ti $CONT_NAME" +- before_install: +- - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce +- - docker --version +- install: +- - $CI_ROOT/travis-centos-rhel8.sh SETUP +- script: +- - set -e +- # Build systemd +- - $CI_ROOT/travis-centos-rhel8.sh RUN_ASAN +- - set +e +- after_script: +- - $CI_ROOT/travis-centos-rhel8.sh CLEANUP +diff --git a/ci/travis-centos-rhel7.sh b/ci/travis-centos-rhel7.sh +deleted file mode 100755 +index 73416798ed..0000000000 +--- a/ci/travis-centos-rhel7.sh ++++ /dev/null +@@ -1,73 +0,0 @@ +-#!/bin/bash +- +-# Run this script from the root of the systemd's git repository +-# or set REPO_ROOT to a correct path. +-# +-# Example execution on Fedora: +-# dnf install docker +-# systemctl start docker +-# export CONT_NAME="my-fancy-container" +-# ci/travis-centos.sh SETUP RUN CLEANUP +- +-PHASES=(${@:-SETUP RUN CLEANUP}) +-CENTOS_RELEASE="${CENTOS_RELEASE:-latest}" +-CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" +-DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" +-DOCKER_RUN="${DOCKER_RUN:-docker run}" +-REPO_ROOT="${REPO_ROOT:-$PWD}" +-ADDITIONAL_DEPS=(yum-utils iputils hostname libasan libubsan clang llvm) +- +-function info() { +- echo -e "\033[33;1m$1\033[0m" +-} +- +-set -e +- +-source "$(dirname $0)/travis_wait.bash" +- +-for phase in "${PHASES[@]}"; do +- case $phase in +- SETUP) +- info "Setup phase" +- info "Using Travis $CENTOS_RELEASE" +- # Pull a Docker image and start a new container +- docker pull centos:$CENTOS_RELEASE +- info "Starting container $CONT_NAME" +- $DOCKER_RUN -v $REPO_ROOT:/build:rw \ +- -w /build --privileged=true --name $CONT_NAME \ +- -dit --net=host centos:$CENTOS_RELEASE /sbin/init +- # Beautiful workaround for Fedora's version of Docker +- sleep 1 +- $DOCKER_EXEC yum makecache +- # Install necessary build/test requirements +- $DOCKER_EXEC yum -y upgrade +- $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" +- $DOCKER_EXEC yum-builddep -y systemd +- ;; +- RUN) +- info "Run phase" +- # Build systemd +- $DOCKER_EXEC ./autogen.sh +- $DOCKER_EXEC ./configure --disable-timesyncd --disable-kdbus --disable-terminal \ +- --enable-gtk-doc --enable-compat-libs --disable-sysusers \ +- --disable-ldconfig --enable-lz4 --with-sysvinit-path=/etc/rc.d/init.d +- $DOCKER_EXEC make +- # Let's install the new systemd and "reboot" the container to avoid +- # unexpected fails due to incompatibilities with older systemd +- $DOCKER_EXEC make install +- docker restart $CONT_NAME +- if ! $DOCKER_EXEC make check; then +- $DOCKER_EXEC cat test-suite.log +- exit 1 +- fi +- ;; +- CLEANUP) +- info "Cleanup phase" +- docker stop $CONT_NAME +- docker rm -f $CONT_NAME +- ;; +- *) +- echo >&2 "Unknown phase '$phase'" +- exit 1 +- esac +-done +diff --git a/ci/travis_wait.bash b/ci/travis_wait.bash +deleted file mode 100644 +index acf6ad15e4..0000000000 +--- a/ci/travis_wait.bash ++++ /dev/null +@@ -1,61 +0,0 @@ +-# This was borrowed from https://github.com/travis-ci/travis-build/tree/master/lib/travis/build/bash +-# to get around https://github.com/travis-ci/travis-ci/issues/9979. It should probably be removed +-# as soon as Travis CI has started to provide an easy way to export the functions to bash scripts. +- +-travis_jigger() { +- local cmd_pid="${1}" +- shift +- local timeout="${1}" +- shift +- local count=0 +- +- echo -e "\\n" +- +- while [[ "${count}" -lt "${timeout}" ]]; do +- count="$((count + 1))" +- echo -ne "Still running (${count} of ${timeout}): ${*}\\r" +- sleep 60 +- done +- +- echo -e "\\n${ANSI_RED}Timeout (${timeout} minutes) reached. Terminating \"${*}\"${ANSI_RESET}\\n" +- kill -9 "${cmd_pid}" +-} +- +-travis_wait() { +- local timeout="${1}" +- +- if [[ "${timeout}" =~ ^[0-9]+$ ]]; then +- shift +- else +- timeout=20 +- fi +- +- local cmd=("${@}") +- local log_file="travis_wait_${$}.log" +- +- "${cmd[@]}" &>"${log_file}" & +- local cmd_pid="${!}" +- +- travis_jigger "${!}" "${timeout}" "${cmd[@]}" & +- local jigger_pid="${!}" +- local result +- +- { +- set +e +- wait "${cmd_pid}" 2>/dev/null +- result="${?}" +- ps -p"${jigger_pid}" &>/dev/null && kill "${jigger_pid}" +- set -e +- } +- +- if [[ "${result}" -eq 0 ]]; then +- echo -e "\\n${ANSI_GREEN}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}" +- else +- echo -e "\\n${ANSI_RED}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}" +- fi +- +- echo -e "\\n${ANSI_GREEN}Log:${ANSI_RESET}\\n" +- cat "${log_file}" +- +- return "${result}" +-} diff --git a/SOURCES/0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch b/SOURCES/0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch new file mode 100644 index 0000000..9f2143b --- /dev/null +++ b/SOURCES/0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch @@ -0,0 +1,31 @@ +From a11334f0eae67b5159a416193e2e37634281000a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 09:33:31 +0100 +Subject: [PATCH] unit: make UNIT() cast function deal with NULL pointers + +Fixes: #10681 +(cherry picked from commit bbf11206230d1b089118971f98a047151cb5c4fa) + +Related: #1871827 +--- + src/core/unit.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.h b/src/core/unit.h +index 6e37fd6f5a..ec45b5fb48 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -597,7 +597,12 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; + } + + /* For casting the various unit types into a unit */ +-#define UNIT(u) (&(u)->meta) ++#define UNIT(u) \ ++ ({ \ ++ typeof(u) _u_ = (u); \ ++ Unit *_w_ = _u_ ? &(_u_)->meta : NULL; \ ++ _w_; \ ++ }) + + #define UNIT_HAS_EXEC_CONTEXT(u) (UNIT_VTABLE(u)->exec_context_offset > 0) + #define UNIT_HAS_CGROUP_CONTEXT(u) (UNIT_VTABLE(u)->cgroup_context_offset > 0) diff --git a/SOURCES/0500-use-link-to-RHEL-8-docs.patch b/SOURCES/0500-use-link-to-RHEL-8-docs.patch new file mode 100644 index 0000000..ecc4968 --- /dev/null +++ b/SOURCES/0500-use-link-to-RHEL-8-docs.patch @@ -0,0 +1,25 @@ +From 6fb6c218fda0d5c3404049243b9392e9b0c7d537 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 11 Dec 2020 09:34:19 +0100 +Subject: [PATCH] use link to RHEL-8 docs + +RHEL-only + +Related: #1623116 +--- + man/systemctl.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 56f94d084c..ed60a0739f 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2005,7 +2005,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + For examples how to use systemctl in comparsion + with old service and chkconfig command please see: +- ++ + Managing System Services + + diff --git a/SOURCES/0501-cgroup-Also-set-blkio.bfq.weight.patch b/SOURCES/0501-cgroup-Also-set-blkio.bfq.weight.patch new file mode 100644 index 0000000..88ad896 --- /dev/null +++ b/SOURCES/0501-cgroup-Also-set-blkio.bfq.weight.patch @@ -0,0 +1,37 @@ +From af9f03ba48dd75be8c6a923f70da9804b3a3a2c3 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Wed, 25 Nov 2020 09:05:36 +0100 +Subject: [PATCH] cgroup: Also set blkio.bfq.weight + +Commit [1] added a workaround when unified cgroups are used but missed +legacy cgroups where there is the same issue. + +[1] + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 35e7a62ca32a30169a94693b831e53c832251984) + +Resolves: #1657810 +--- + src/core/cgroup.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f1ce070f9a..71e30fd4db 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1063,6 +1063,14 @@ static void cgroup_context_apply( + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set blkio.weight: %m"); + ++ /* FIXME: drop this when distro kernels properly support BFQ through "blkio.weight" ++ * See also: https://github.com/systemd/systemd/pull/13335 */ ++ xsprintf(buf, "%" PRIu64 "\n", weight); ++ r = cg_set_attribute("blkio", path, "blkio.bfq.weight", buf); ++ if (r < 0) ++ log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, ++ "Failed to set blkio.bfq.weight: %m"); ++ + if (has_io) { + CGroupIODeviceWeight *w; + diff --git a/SOURCES/0502-units-make-sure-initrd-cleanup.service-terminates-be.patch b/SOURCES/0502-units-make-sure-initrd-cleanup.service-terminates-be.patch new file mode 100644 index 0000000..3fdb46f --- /dev/null +++ b/SOURCES/0502-units-make-sure-initrd-cleanup.service-terminates-be.patch @@ -0,0 +1,37 @@ +From ea425381a675a2ce4d9519d534fe27c1012ac92e Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 28 Jan 2019 12:07:37 +0100 +Subject: [PATCH] units: make sure initrd-cleanup.service terminates before + switching to rootfs + +A follow-up for commit a8cb1dc3e0fa81aff. + +Commit a8cb1dc3e0fa81aff made sure that initrd-cleanup.service won't be stopped +when initrd-switch-root.target is isolated. + +However even with this change, it might happen that initrd-cleanup.service +survives the switch to rootfs (since it has no ordering constraints against +initrd-switch-root.target) and is stopped right after when default.target is +isolated. This led to initrd-cleanup.service entering in failed state as it +happens when oneshot services are stopped. + +This patch along with a8cb1dc3e0fa81aff should fix issue #4343. + +Fixes: #4343 +(cherry picked from commit e2c7c94ea35fe7e669afb51bfc2251158b522ea5) + +Related: #1657810 +--- + units/initrd-switch-root.target | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/initrd-switch-root.target b/units/initrd-switch-root.target +index ad82245121..ea4f02618f 100644 +--- a/units/initrd-switch-root.target ++++ b/units/initrd-switch-root.target +@@ -15,4 +15,4 @@ Requires=initrd-switch-root.service + Before=initrd-switch-root.service + AllowIsolate=yes + Wants=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target systemd-journald.service initrd-cleanup.service +-After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target ++After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target initrd-cleanup.service diff --git a/SOURCES/0503-core-reload-SELinux-label-cache-on-daemon-reload.patch b/SOURCES/0503-core-reload-SELinux-label-cache-on-daemon-reload.patch new file mode 100644 index 0000000..5e5d3d4 --- /dev/null +++ b/SOURCES/0503-core-reload-SELinux-label-cache-on-daemon-reload.patch @@ -0,0 +1,73 @@ +From c67be1c7d69a0662ab85720aa0209110c39479f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 27 Nov 2019 19:43:47 +0100 +Subject: [PATCH] core: reload SELinux label cache on daemon-reload + +Reloading the SELinux label cache here enables a light-wight follow-up of a SELinux policy change, e.g. adding a label for a RuntimeDirectory. + +Closes: #13363 +(cherry picked from commit a9dfac21ec850eb5dcaf1ae9ef729389e4c12802) + +Resolves: #1888912 +--- + src/basic/selinux-util.c | 20 ++++++++++++++++++++ + src/basic/selinux-util.h | 1 + + src/core/main.c | 2 ++ + 3 files changed, 23 insertions(+) + +diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c +index e15bd7e1fa..f69d88eb1e 100644 +--- a/src/basic/selinux-util.c ++++ b/src/basic/selinux-util.c +@@ -105,6 +105,26 @@ void mac_selinux_finish(void) { + #endif + } + ++void mac_selinux_reload(void) { ++ ++#if HAVE_SELINUX ++ struct selabel_handle *backup_label_hnd; ++ ++ if (!label_hnd) ++ return; ++ ++ backup_label_hnd = TAKE_PTR(label_hnd); ++ ++ /* try to initialize new handle ++ * on success close backup ++ * on failure restore backup */ ++ if (mac_selinux_init() == 0) ++ selabel_close(backup_label_hnd); ++ else ++ label_hnd = backup_label_hnd; ++#endif ++} ++ + int mac_selinux_fix(const char *path, LabelFixFlags flags) { + + #if HAVE_SELINUX +diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h +index 08314057fb..abcfabe777 100644 +--- a/src/basic/selinux-util.h ++++ b/src/basic/selinux-util.h +@@ -13,6 +13,7 @@ void mac_selinux_retest(void); + + int mac_selinux_init(void); + void mac_selinux_finish(void); ++void mac_selinux_reload(void); + + int mac_selinux_fix(const char *path, LabelFixFlags flags); + int mac_selinux_apply(const char *path, const char *label); +diff --git a/src/core/main.c b/src/core/main.c +index d897155644..d5c41da0c4 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1682,6 +1682,8 @@ static int invoke_main_loop( + saved_log_level = m->log_level_overridden ? log_get_max_level() : -1; + saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID; + ++ mac_selinux_reload(); ++ + (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock); + + set_manager_defaults(m); diff --git a/SOURCES/0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch b/SOURCES/0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch new file mode 100644 index 0000000..4b51123 --- /dev/null +++ b/SOURCES/0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch @@ -0,0 +1,140 @@ +From 4f4e8bbd9ad46fc146a36f52790bc4920f42ef1f Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 2 Jul 2018 10:22:56 +0200 +Subject: [PATCH] selinux: introduce mac_selinux_create_file_prepare_at() + +(cherry picked from commit 7e531a5265687aef5177b070c36ca4ceab42e768) + +Related: #1888912 +--- + src/basic/selinux-util.c | 83 ++++++++++++++++++++++++++++++---------- + src/basic/selinux-util.h | 1 + + 2 files changed, 63 insertions(+), 21 deletions(-) + +diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c +index f69d88eb1e..a078ce23ef 100644 +--- a/src/basic/selinux-util.c ++++ b/src/basic/selinux-util.c +@@ -336,48 +336,89 @@ char* mac_selinux_free(char *label) { + return NULL; + } + +-int mac_selinux_create_file_prepare(const char *path, mode_t mode) { +- + #if HAVE_SELINUX ++static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode) { + _cleanup_freecon_ char *filecon = NULL; ++ _cleanup_free_ char *path = NULL; + int r; + +- assert(path); +- +- if (!label_hnd) +- return 0; +- +- if (path_is_absolute(path)) +- r = selabel_lookup_raw(label_hnd, &filecon, path, mode); +- else { +- _cleanup_free_ char *newpath = NULL; +- +- r = path_make_absolute_cwd(path, &newpath); +- if (r < 0) +- return r; +- +- r = selabel_lookup_raw(label_hnd, &filecon, newpath, mode); +- } ++ assert(abspath); ++ assert(path_is_absolute(abspath)); + ++ r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode); + if (r < 0) { + /* No context specified by the policy? Proceed without setting it. */ + if (errno == ENOENT) + return 0; + +- log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path); ++ log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath); + } else { + if (setfscreatecon_raw(filecon) >= 0) + return 0; /* Success! */ + +- log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, path); ++ log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath); + } + + if (security_getenforce() > 0) + return -errno; + +-#endif + return 0; + } ++#endif ++ ++int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode) { ++ int r = 0; ++ ++#if HAVE_SELINUX ++ _cleanup_free_ char *abspath = NULL; ++ _cleanup_close_ int fd = -1; ++ ++ assert(path); ++ ++ if (!label_hnd) ++ return 0; ++ ++ if (!path_is_absolute(path)) { ++ _cleanup_free_ char *p = NULL; ++ ++ if (dirfd == AT_FDCWD) ++ r = safe_getcwd(&p); ++ else ++ r = fd_get_path(dirfd, &p); ++ if (r < 0) ++ return r; ++ ++ abspath = path_join(NULL, p, path); ++ if (!abspath) ++ return -ENOMEM; ++ ++ path = abspath; ++ } ++ ++ r = selinux_create_file_prepare_abspath(path, mode); ++#endif ++ return r; ++} ++ ++int mac_selinux_create_file_prepare(const char *path, mode_t mode) { ++ int r = 0; ++ ++#if HAVE_SELINUX ++ _cleanup_free_ char *abspath = NULL; ++ ++ assert(path); ++ ++ if (!label_hnd) ++ return 0; ++ ++ r = path_make_absolute_cwd(path, &abspath); ++ if (r < 0) ++ return r; ++ ++ r = selinux_create_file_prepare_abspath(abspath, mode); ++#endif ++ return r; ++} + + void mac_selinux_create_file_clear(void) { + +diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h +index abcfabe777..639c35b687 100644 +--- a/src/basic/selinux-util.h ++++ b/src/basic/selinux-util.h +@@ -24,6 +24,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char * + char* mac_selinux_free(char *label); + + int mac_selinux_create_file_prepare(const char *path, mode_t mode); ++int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode); + void mac_selinux_create_file_clear(void); + + int mac_selinux_create_socket_prepare(const char *label); diff --git a/SOURCES/0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch b/SOURCES/0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch new file mode 100644 index 0000000..4bba960 --- /dev/null +++ b/SOURCES/0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch @@ -0,0 +1,135 @@ +From 4e48673172b012a06575e4f5b681d3554eded2e2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Mon, 6 Jan 2020 15:27:23 +0100 +Subject: [PATCH] selinux: add trigger for policy reload to refresh internal + selabel cache + +Reload the internal selabel cache automatically on SELinux policy reloads so non pid-1 daemons are participating. + +Run the reload function `mac_selinux_reload()` not manually on daemon-reload, but rather pass it as callback to libselinux. +Trigger the callback prior usage of the systemd internal selabel cache by depleting the selinux netlink socket via `avc_netlink_check_nb()`. + +Improves: a9dfac21ec85 ("core: reload SELinux label cache on daemon-reload") +Improves: #13363 +(cherry picked from commit 61f3e897f13101f29fb8027e8839498a469ad58e) + +Related: #1888912 +--- + src/basic/selinux-util.c | 23 +++++++++++++++++++---- + src/basic/selinux-util.h | 1 - + src/core/main.c | 2 -- + 3 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c +index a078ce23ef..bfe3d015aa 100644 +--- a/src/basic/selinux-util.c ++++ b/src/basic/selinux-util.c +@@ -10,6 +10,7 @@ + #include + + #if HAVE_SELINUX ++#include + #include + #include + #include +@@ -32,6 +33,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); + #define _cleanup_freecon_ _cleanup_(freeconp) + #define _cleanup_context_free_ _cleanup_(context_freep) + ++static int mac_selinux_reload(int seqno); ++ + static int cached_use = -1; + static struct selabel_handle *label_hnd = NULL; + +@@ -63,6 +66,8 @@ int mac_selinux_init(void) { + usec_t before_timestamp, after_timestamp; + struct mallinfo before_mallinfo, after_mallinfo; + ++ selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload); ++ + if (label_hnd) + return 0; + +@@ -105,13 +110,12 @@ void mac_selinux_finish(void) { + #endif + } + +-void mac_selinux_reload(void) { +- + #if HAVE_SELINUX ++static int mac_selinux_reload(int seqno) { + struct selabel_handle *backup_label_hnd; + + if (!label_hnd) +- return; ++ return 0; + + backup_label_hnd = TAKE_PTR(label_hnd); + +@@ -122,8 +126,10 @@ void mac_selinux_reload(void) { + selabel_close(backup_label_hnd); + else + label_hnd = backup_label_hnd; +-#endif ++ ++ return 0; + } ++#endif + + int mac_selinux_fix(const char *path, LabelFixFlags flags) { + +@@ -152,6 +158,9 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) { + if (fstat(fd, &st) < 0) + return -errno; + ++ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ ++ (void) avc_netlink_check_nb(); ++ + if (selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode) < 0) { + r = -errno; + +@@ -345,6 +354,9 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode) + assert(abspath); + assert(path_is_absolute(abspath)); + ++ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ ++ (void) avc_netlink_check_nb(); ++ + r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode); + if (r < 0) { + /* No context specified by the policy? Proceed without setting it. */ +@@ -496,6 +508,9 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { + + path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path)); + ++ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ ++ (void) avc_netlink_check_nb(); ++ + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK); + else { +diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h +index 639c35b687..bd5207c318 100644 +--- a/src/basic/selinux-util.h ++++ b/src/basic/selinux-util.h +@@ -13,7 +13,6 @@ void mac_selinux_retest(void); + + int mac_selinux_init(void); + void mac_selinux_finish(void); +-void mac_selinux_reload(void); + + int mac_selinux_fix(const char *path, LabelFixFlags flags); + int mac_selinux_apply(const char *path, const char *label); +diff --git a/src/core/main.c b/src/core/main.c +index d5c41da0c4..d897155644 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1682,8 +1682,6 @@ static int invoke_main_loop( + saved_log_level = m->log_level_overridden ? log_get_max_level() : -1; + saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID; + +- mac_selinux_reload(); +- + (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock); + + set_manager_defaults(m); diff --git a/SOURCES/0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch b/SOURCES/0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch new file mode 100644 index 0000000..0ce9150 --- /dev/null +++ b/SOURCES/0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch @@ -0,0 +1,24 @@ +From fb58a56c6c1c2749ba634abd9ad76f4e718269a1 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 5 Jan 2021 12:30:15 +0100 +Subject: [PATCH] udev/net_id: give RHEL-8.4 naming scheme a name + +Follow-up for bb6114af097da0cd9c5081e42db718559130687f + +Related: #1827462 +--- + src/udev/udev-builtin-net_id.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index d8c56b62bb..7c153f0aef 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -150,6 +150,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.1", NAMING_RHEL_8_1 }, + { "rhel-8.2", NAMING_RHEL_8_2 }, + { "rhel-8.3", NAMING_RHEL_8_3 }, ++ { "rhel-8.4", NAMING_RHEL_8_4 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch b/SOURCES/0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch new file mode 100644 index 0000000..e9ac657 --- /dev/null +++ b/SOURCES/0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch @@ -0,0 +1,63 @@ +From 29c5b8dd6228c4401f034ca0aa85f99ac42cf8dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Thu, 5 Nov 2020 17:55:25 +0100 +Subject: [PATCH] basic/stat-util: make mtime check stricter and use entire + timestamp + +Note that st_mtime member of struct stat is defined as follows, + + #define st_mtime st_mtim.tv_sec + +Hence we omitted checking nanosecond part of the timestamp (struct +timespec) and possibly would miss modifications that happened within the +same second. + +(cherry picked from commit a59b0a9f768f6e27b25f4f1bab6de08842e78d74) + +Related: #1642728 +--- + src/basic/stat-util.c | 22 ++++++++++++++++++++++ + src/basic/stat-util.h | 2 ++ + 2 files changed, 24 insertions(+) + +diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c +index 26aee9bad6..c61c4c0517 100644 +--- a/src/basic/stat-util.c ++++ b/src/basic/stat-util.c +@@ -287,3 +287,25 @@ int fd_verify_regular(int fd) { + + return stat_verify_regular(&st); + } ++ ++bool stat_inode_unmodified(const struct stat *a, const struct stat *b) { ++ ++ /* Returns if the specified stat structures reference the same, unmodified inode. This check tries to ++ * be reasonably careful when detecting changes: we check both inode and mtime, to cater for file ++ * systems where mtimes are fixed to 0 (think: ostree/nixos type installations). We also check file ++ * size, backing device, inode type and if this refers to a device not the major/minor. ++ * ++ * Note that we don't care if file attributes such as ownership or access mode change, this here is ++ * about contents of the file. The purpose here is to detect file contents changes, and nothing ++ * else. */ ++ ++ return a && b && ++ (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */ ++ ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */ ++ a->st_mtim.tv_sec == b->st_mtim.tv_sec && ++ a->st_mtim.tv_nsec == b->st_mtim.tv_nsec && ++ (!S_ISREG(a->st_mode) || a->st_size == b->st_size) && /* if regular file, compare file size */ ++ a->st_dev == b->st_dev && ++ a->st_ino == b->st_ino && ++ (!(S_ISCHR(a->st_mode) || S_ISBLK(a->st_mode)) || a->st_rdev == b->st_rdev); /* if device node, also compare major/minor, because we can */ ++} +\ No newline at end of file +diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h +index f8014ed30b..9e1a2b70da 100644 +--- a/src/basic/stat-util.h ++++ b/src/basic/stat-util.h +@@ -58,3 +58,5 @@ int path_is_temporary_fs(const char *path); + + int stat_verify_regular(const struct stat *st); + int fd_verify_regular(int fd); ++ ++bool stat_inode_unmodified(const struct stat *a, const struct stat *b); diff --git a/SOURCES/0508-udev-make-algorithm-that-selects-highest-priority-de.patch b/SOURCES/0508-udev-make-algorithm-that-selects-highest-priority-de.patch new file mode 100644 index 0000000..e20137b --- /dev/null +++ b/SOURCES/0508-udev-make-algorithm-that-selects-highest-priority-de.patch @@ -0,0 +1,457 @@ +From 1d5f966c1758eb620755fcae54abd07a1ac36d3d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 6 Jan 2021 11:43:50 +0100 +Subject: [PATCH] udev: make algorithm that selects highest priority devlink + less susceptible to race conditions + +Previously it was very likely, when multiple contenders for the symlink +appear in parallel, that algorithm would select wrong symlink (i.e. one +with lower-priority). + +Now the algorithm is much more defensive and when we detect change in +set of contenders for the symlink we reevaluate the selection. Same +happens when new symlink replaces already existing symlink that points +to different device node. + +Resolves: #1642728 +--- + src/udev/udev-event.c | 71 +++++++----- + src/udev/udev-node.c | 244 ++++++++++++++++++++++++++++++------------ + 2 files changed, 216 insertions(+), 99 deletions(-) + +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index fd8406d959..9004634f65 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -833,6 +833,41 @@ static int rename_netif(struct udev_event *event) { + return 0; + } + ++static void update_devnode(struct udev_event *event) { ++ struct udev_device *dev = event->dev; ++ ++ if (major(udev_device_get_devnum(dev)) > 0) { ++ bool apply; ++ ++ /* remove/update possible left-over symlinks from old database entry */ ++ if (event->dev_db != NULL) ++ udev_node_update_old_links(dev, event->dev_db); ++ ++ if (!event->owner_set) ++ event->uid = udev_device_get_devnode_uid(dev); ++ ++ if (!event->group_set) ++ event->gid = udev_device_get_devnode_gid(dev); ++ ++ if (!event->mode_set) { ++ if (udev_device_get_devnode_mode(dev) > 0) { ++ /* kernel supplied value */ ++ event->mode = udev_device_get_devnode_mode(dev); ++ } else if (event->gid > 0) { ++ /* default 0660 if a group is assigned */ ++ event->mode = 0660; ++ } ++ else { ++ /* default 0600 */ ++ event->mode = 0600; ++ } ++ } ++ ++ apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set; ++ udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list); ++ } ++} ++ + void udev_event_execute_rules(struct udev_event *event, + usec_t timeout_usec, usec_t timeout_warn_usec, + struct udev_list *properties_list, +@@ -891,35 +926,7 @@ void udev_event_execute_rules(struct udev_event *event, + } + } + +- if (major(udev_device_get_devnum(dev)) > 0) { +- bool apply; +- +- /* remove/update possible left-over symlinks from old database entry */ +- if (event->dev_db != NULL) +- udev_node_update_old_links(dev, event->dev_db); +- +- if (!event->owner_set) +- event->uid = udev_device_get_devnode_uid(dev); +- +- if (!event->group_set) +- event->gid = udev_device_get_devnode_gid(dev); +- +- if (!event->mode_set) { +- if (udev_device_get_devnode_mode(dev) > 0) { +- /* kernel supplied value */ +- event->mode = udev_device_get_devnode_mode(dev); +- } else if (event->gid > 0) { +- /* default 0660 if a group is assigned */ +- event->mode = 0660; +- } else { +- /* default 0600 */ +- event->mode = 0600; +- } +- } +- +- apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set; +- udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list); +- } ++ update_devnode(event); + + /* preserve old, or get new initialization timestamp */ + udev_device_ensure_usec_initialized(event->dev, event->dev_db); +@@ -927,6 +934,12 @@ void udev_event_execute_rules(struct udev_event *event, + /* (re)write database file */ + udev_device_tag_index(dev, event->dev_db, true); + udev_device_update_db(dev); ++ ++ /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database, ++ * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure ++ * symlinks point to devices that claim them with the highest priority. */ ++ update_devnode(event); ++ + udev_device_set_is_initialized(dev); + + event->dev_db = udev_device_unref(event->dev_db); +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 333dcae6b9..2eeeccdd3a 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -13,19 +13,27 @@ + #include + + #include "device-nodes.h" ++#include "device-private.h" + #include "dirent-util.h" ++#include "fd-util.h" + #include "format-util.h" + #include "fs-util.h" ++#include "sd-device.h" + #include "selinux-util.h" + #include "smack-util.h" ++#include "stat-util.h" + #include "stdio-util.h" + #include "string-util.h" + #include "udev.h" ++#include "libudev-device-internal.h" + +-static int node_symlink(struct udev_device *dev, const char *node, const char *slink) { ++#define LINK_UPDATE_MAX_RETRIES 128 ++ ++static int node_symlink(sd_device *dev, const char *node, const char *slink) { + struct stat stats; + char target[UTIL_PATH_SIZE]; + char *s; ++ const char *id_filename; + size_t l; + char slink_tmp[UTIL_PATH_SIZE + 32]; + int i = 0; +@@ -89,7 +97,10 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s + } + + log_debug("atomically replace '%s'", slink); +- strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL); ++ err = device_get_id_filename(dev, &id_filename); ++ if (err < 0) ++ return log_error_errno(err, "Failed to get id_filename: %m"); ++ strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", id_filename, NULL); + unlink(slink_tmp); + do { + err = mkdir_parents_label(slink_tmp, 0755); +@@ -109,104 +120,187 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s + if (err != 0) { + log_error_errno(errno, "rename '%s' '%s' failed: %m", slink_tmp, slink); + unlink(slink_tmp); +- } ++ } else ++ /* Tell caller that we replaced already existing symlink. */ ++ return 1; + exit: + return err; + } + + /* find device node of device with highest priority */ +-static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) { +- struct udev *udev = udev_device_get_udev(dev); +- DIR *dir; ++static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) { ++ _cleanup_closedir_ DIR *dir = NULL; ++ _cleanup_free_ char *target = NULL; + struct dirent *dent; +- int priority = 0; +- const char *target = NULL; ++ int r, priority = 0; ++ ++ assert(!add || dev); ++ assert(stackdir); ++ assert(ret); + + if (add) { +- priority = udev_device_get_devlink_priority(dev); +- strscpy(buf, bufsize, udev_device_get_devnode(dev)); +- target = buf; ++ const char *devnode; ++ ++ r = device_get_devlink_priority(dev, &priority); ++ if (r < 0) ++ return r; ++ ++ r = sd_device_get_devname(dev, &devnode); ++ if (r < 0) ++ return r; ++ ++ target = strdup(devnode); ++ if (!target) ++ return -ENOMEM; + } + + dir = opendir(stackdir); +- if (dir == NULL) +- return target; ++ if (!dir) { ++ if (target) { ++ *ret = TAKE_PTR(target); ++ return 0; ++ } ++ ++ return -errno; ++ } ++ + FOREACH_DIRENT_ALL(dent, dir, break) { +- struct udev_device *dev_db; ++ _cleanup_(sd_device_unrefp) sd_device *dev_db = NULL; ++ const char *devnode, *id_filename; ++ int db_prio = 0; + + if (dent->d_name[0] == '\0') + break; + if (dent->d_name[0] == '.') + continue; + +- log_debug("found '%s' claiming '%s'", dent->d_name, stackdir); ++ log_debug("Found '%s' claiming '%s'", dent->d_name, stackdir); ++ ++ if (device_get_id_filename(dev, &id_filename) < 0) ++ continue; + + /* did we find ourself? */ +- if (streq(dent->d_name, udev_device_get_id_filename(dev))) ++ if (streq(dent->d_name, id_filename)) + continue; + +- dev_db = udev_device_new_from_device_id(udev, dent->d_name); +- if (dev_db != NULL) { +- const char *devnode; +- +- devnode = udev_device_get_devnode(dev_db); +- if (devnode != NULL) { +- if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) { +- log_debug("'%s' claims priority %i for '%s'", +- udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir); +- priority = udev_device_get_devlink_priority(dev_db); +- strscpy(buf, bufsize, devnode); +- target = buf; +- } +- } +- udev_device_unref(dev_db); ++ if (sd_device_new_from_device_id(&dev_db, dent->d_name) < 0) ++ continue; ++ ++ if (sd_device_get_devname(dev_db, &devnode) < 0) ++ continue; ++ ++ if (device_get_devlink_priority(dev_db, &db_prio) < 0) ++ continue; ++ ++ if (target && db_prio <= priority) ++ continue; ++ ++ if (DEBUG_LOGGING) { ++ const char *syspath = NULL; ++ ++ (void) sd_device_get_syspath(dev_db, &syspath); ++ log_debug("Device '%s' claims priority %i for '%s'", strnull(syspath), db_prio, stackdir); + } ++ ++ r = free_and_strdup(&target, devnode); ++ if (r < 0) ++ return r; ++ priority = db_prio; + } +- closedir(dir); +- return target; ++ ++ if (!target) ++ return -ENOENT; ++ ++ *ret = TAKE_PTR(target); ++ return 0; + } + ++ + /* manage "stack of names" with possibly specified device priorities */ +-static void link_update(struct udev_device *dev, const char *slink, bool add) { +- char name_enc[UTIL_PATH_SIZE]; +- char filename[UTIL_PATH_SIZE * 2]; +- char dirname[UTIL_PATH_SIZE]; +- const char *target; +- char buf[UTIL_PATH_SIZE]; ++static int link_update(sd_device *dev, const char *slink, bool add) { ++ _cleanup_free_ char *filename = NULL, *dirname = NULL; ++ char name_enc[PATH_MAX]; ++ const char *id_filename; ++ int i, r, retries; ++ ++ assert(dev); ++ assert(slink); ++ ++ r = device_get_id_filename(dev, &id_filename); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to get id_filename: %m"); + + util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc)); +- strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL); +- strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL); ++ dirname = path_join(NULL, "/run/udev/links/", name_enc); ++ if (!dirname) ++ return log_oom(); ++ filename = path_join(NULL, dirname, id_filename); ++ if (!filename) ++ return log_oom(); ++ ++ if (!add) { ++ if (unlink(filename) == 0) ++ (void) rmdir(dirname); ++ } else ++ for (;;) { ++ _cleanup_close_ int fd = -1; ++ ++ r = mkdir_parents(filename, 0755); ++ if (!IN_SET(r, 0, -ENOENT)) ++ return r; + +- if (!add && unlink(filename) == 0) +- rmdir(dirname); ++ fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); ++ if (fd >= 0) ++ break; ++ if (errno != ENOENT) ++ return -errno; ++ } + +- target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf)); +- if (target == NULL) { +- log_debug("no reference left, remove '%s'", slink); +- if (unlink(slink) == 0) +- rmdir_parents(slink, "/"); +- } else { +- log_debug("creating link '%s' to '%s'", slink, target); +- node_symlink(dev, target, slink); +- } ++ /* If the database entry is not written yet we will just do one iteration and possibly wrong symlink ++ * will be fixed in the second invocation. */ ++ (void) sd_device_get_is_initialized(dev, &r); ++ retries = r > 0 ? LINK_UPDATE_MAX_RETRIES : 1; + +- if (add) { +- int err; ++ for (i = 0; i < retries; i++) { ++ _cleanup_free_ char *target = NULL; ++ struct stat st1 = {}, st2 = {}; + +- do { +- int fd; ++ r = stat(dirname, &st1); ++ if (r < 0 && errno != ENOENT) ++ return -errno; + +- err = mkdir_parents(filename, 0755); +- if (!IN_SET(err, 0, -ENOENT)) ++ r = link_find_prioritized(dev, add, dirname, &target); ++ if (r == -ENOENT) { ++ log_debug("No reference left, removing '%s'", slink); ++ if (unlink(slink) == 0) ++ (void) rmdir_parents(slink, "/"); ++ ++ break; ++ } else if (r < 0) ++ return log_error_errno(r, "Failed to determine highest priority symlink: %m"); ++ ++ r = node_symlink(dev, target, slink); ++ if (r < 0) { ++ (void) unlink(filename); ++ break; ++ } else if (r == 1) ++ /* We have replaced already existing symlink, possibly there is some other device trying ++ * to claim the same symlink. Let's do one more iteration to give us a chance to fix ++ * the error if other device actually claims the symlink with higher priority. */ ++ continue; ++ ++ /* Skip the second stat() if the first failed, stat_inode_unmodified() would return false regardless. */ ++ if ((st1.st_mode & S_IFMT) != 0) { ++ r = stat(dirname, &st2); ++ if (r < 0 && errno != ENOENT) ++ return -errno; ++ ++ if (stat_inode_unmodified(&st1, &st2)) + break; +- fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); +- if (fd >= 0) +- close(fd); +- else +- err = -errno; +- } while (err == -ENOENT); ++ } + } ++ ++ return i < LINK_UPDATE_MAX_RETRIES ? 0 : -ELOOP; + } + + void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old) { +@@ -233,7 +327,7 @@ void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev + + log_debug("update old name, '%s' no longer belonging to '%s'", + name, udev_device_get_devpath(dev)); +- link_update(dev, name, false); ++ link_update(dev->device, name, false); + } + } + +@@ -338,11 +432,16 @@ void udev_node_add(struct udev_device *dev, bool apply, + xsprintf_dev_num_path(filename, + streq(udev_device_get_subsystem(dev), "block") ? "block" : "char", + udev_device_get_devnum(dev)); +- node_symlink(dev, udev_device_get_devnode(dev), filename); ++ node_symlink(dev->device, udev_device_get_devnode(dev), filename); + + /* create/update symlinks, add symlinks to name index */ +- udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) +- link_update(dev, udev_list_entry_get_name(list_entry), true); ++ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { ++ int r; ++ ++ r = link_update(dev->device, udev_list_entry_get_name(list_entry), true); ++ if (r < 0) ++ log_info_errno(r, "Failed to update device symlinks: %m"); ++ } + } + + void udev_node_remove(struct udev_device *dev) { +@@ -350,8 +449,13 @@ void udev_node_remove(struct udev_device *dev) { + char filename[DEV_NUM_PATH_MAX]; + + /* remove/update symlinks, remove symlinks from name index */ +- udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) +- link_update(dev, udev_list_entry_get_name(list_entry), false); ++ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { ++ int r; ++ ++ r = link_update(dev->device, udev_list_entry_get_name(list_entry), false); ++ if (r < 0) ++ log_info_errno(r, "Failed to update device symlinks: %m"); ++ } + + /* remove /dev/{block,char}/$major:$minor */ + xsprintf_dev_num_path(filename, diff --git a/SOURCES/0509-test-create-dev-null-in-test-udev.pl.patch b/SOURCES/0509-test-create-dev-null-in-test-udev.pl.patch new file mode 100644 index 0000000..4dccdbc --- /dev/null +++ b/SOURCES/0509-test-create-dev-null-in-test-udev.pl.patch @@ -0,0 +1,32 @@ +From 6a908a38135d050b7c271fdea9c061d7e7ad8ef7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 23 Oct 2018 07:23:01 +0900 +Subject: [PATCH] test: create /dev/null in test-udev.pl + +(cherry picked from commit a41ff38b0999fb83464309a29b8f39450b8d4b85) + +Related: #1642728 +--- + test/udev-test.pl | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 0433629c7c..a1c24f49b4 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1537,13 +1537,14 @@ sub udev_setup { + system("umount", $udev_tmpfs); + rmdir($udev_tmpfs); + mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; +- system("mount", "-o", "rw,mode=755,nosuid,noexec,nodev", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs"; ++ system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs"; + + mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n"; + # setting group and mode of udev_dev ensures the tests work + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; ++ system("mknod", $udev_dev . "/null", "c", "1", "3") && "unable to create $udev_dev/null"; + + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + diff --git a/SOURCES/0510-test-missing-die.patch b/SOURCES/0510-test-missing-die.patch new file mode 100644 index 0000000..959a689 --- /dev/null +++ b/SOURCES/0510-test-missing-die.patch @@ -0,0 +1,27 @@ +From 70bf708d5360372aa541e25ff512609230781dd6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 7 Nov 2018 14:56:20 +0900 +Subject: [PATCH] test: missing "die" + +Follow-up for a41ff38b0999fb83464309a29b8f39450b8d4b85. + +(cherry picked from commit 11d93952ea806de2b6e9fb381153115cccc7b5e8) + +Related: #1642728 +--- + test/udev-test.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a1c24f49b4..61bd3d703a 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1544,7 +1544,7 @@ sub udev_setup { + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; +- system("mknod", $udev_dev . "/null", "c", "1", "3") && "unable to create $udev_dev/null"; ++ system("mknod", $udev_dev . "/null", "c", "1", "3") && die "unable to create $udev_dev/null"; + + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + diff --git a/SOURCES/0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch b/SOURCES/0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch new file mode 100644 index 0000000..eeadbda --- /dev/null +++ b/SOURCES/0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch @@ -0,0 +1,33 @@ +From 1b133f2ca15f0a15b05407b2c04521d7de88dfa2 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 9 Nov 2018 03:14:04 +0100 +Subject: [PATCH] udev-test: remove a check for whether the test is run in a + container + +It's too broad a check that prevents the test from running on Travis CI. + +(cherry picked from commit 881886ef08d50951159633248b0f73977c5d6924) + +Related: #1642728 +--- + test/udev-test.pl | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 61bd3d703a..05b3e17188 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1646,13 +1646,6 @@ if ($? >> 8 == 0) { + exit($EXIT_TEST_SKIP); + } + +-# skip the test when running in a container +-system("systemd-detect-virt", "-c", "-q"); +-if ($? >> 8 == 0) { +- print "Running in a container, skipping the test.\n"; +- exit($EXIT_TEST_SKIP); +-} +- + udev_setup(); + + my $test_num = 1; diff --git a/SOURCES/0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch b/SOURCES/0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch new file mode 100644 index 0000000..37970ab --- /dev/null +++ b/SOURCES/0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch @@ -0,0 +1,94 @@ +From 8c82f3a4aa2d029dcc303cbf95a71194aa5ac9c3 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 9 Nov 2018 04:01:15 +0100 +Subject: [PATCH] udev-test: skip the test only if it can't setup its + environment + +This is basically a replacement for 0eb3cc88504b5d8f74. + +(cherry picked from commit 110a13202eab6d92678abcde08372d4afac1cc45) + +Related: #1642728 +--- + src/test/test-udev.c | 8 ++++++++ + test/udev-test.pl | 24 +++++++++++++++++++++--- + 2 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/src/test/test-udev.c b/src/test/test-udev.c +index bed51c1270..f098fab721 100644 +--- a/src/test/test-udev.c ++++ b/src/test/test-udev.c +@@ -65,6 +65,11 @@ int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + ++ if (!IN_SET(argc, 2, 3)) { ++ log_error("This program needs one or two arguments, %d given", argc - 1); ++ return EXIT_FAILURE; ++ } ++ + err = fake_filesystems(); + if (err < 0) + return EXIT_FAILURE; +@@ -73,6 +78,9 @@ int main(int argc, char *argv[]) { + if (udev == NULL) + return EXIT_FAILURE; + ++ if (argc == 2) ++ return EXIT_SUCCESS; ++ + log_debug("version %s", PACKAGE_VERSION); + mac_selinux_init(); + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 05b3e17188..aa38bae0b1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1537,18 +1537,28 @@ sub udev_setup { + system("umount", $udev_tmpfs); + rmdir($udev_tmpfs); + mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; +- system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs"; ++ ++ if (system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs)) { ++ warn "unable to mount tmpfs"; ++ return 0; ++ } + + mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n"; + # setting group and mode of udev_dev ensures the tests work + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; +- system("mknod", $udev_dev . "/null", "c", "1", "3") && die "unable to create $udev_dev/null"; ++ ++ if (system("mknod", $udev_dev . "/null", "c", "1", "3")) { ++ warn "unable to create $udev_dev/null"; ++ return 0; ++ } + + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + + system("rm", "-rf", "$udev_run"); ++ ++ return 1; + } + + sub run_test { +@@ -1646,7 +1656,15 @@ if ($? >> 8 == 0) { + exit($EXIT_TEST_SKIP); + } + +-udev_setup(); ++if (!udev_setup()) { ++ warn "Failed to set up the environment, skipping the test"; ++ exit($EXIT_TEST_SKIP); ++} ++ ++if (!system($udev_bin, "check")) { ++ warn "$udev_bin failed to set up the environment, skipping the test"; ++ exit($EXIT_TEST_SKIP); ++} + + my $test_num = 1; + my @list; diff --git a/SOURCES/0513-udev-test-fix-test-skip-condition.patch b/SOURCES/0513-udev-test-fix-test-skip-condition.patch new file mode 100644 index 0000000..165aadb --- /dev/null +++ b/SOURCES/0513-udev-test-fix-test-skip-condition.patch @@ -0,0 +1,33 @@ +From f44fcdde656036f0388fc8244b8960c1873a3a08 Mon Sep 17 00:00:00 2001 +From: Alexey Bogdanenko +Date: Sat, 8 Dec 2018 11:02:30 +0300 +Subject: [PATCH] udev-test: fix test skip condition + +When there is a failure to setup the environment, the following happens: + +1. Command "./test-udev check" exits with non-zero code. +2. Perl function "system" returns the code. +3. The code is evaluated as true by Perl. + +Then we stop the test. + +(cherry picked from commit 7935dae547caf164d807237f1009a9e9fa510337) + +Related: #1642728 +--- + test/udev-test.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index aa38bae0b1..3517feab15 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1661,7 +1661,7 @@ if (!udev_setup()) { + exit($EXIT_TEST_SKIP); + } + +-if (!system($udev_bin, "check")) { ++if (system($udev_bin, "check")) { + warn "$udev_bin failed to set up the environment, skipping the test"; + exit($EXIT_TEST_SKIP); + } diff --git a/SOURCES/0514-udev-test-fix-missing-directory-test-run.patch b/SOURCES/0514-udev-test-fix-missing-directory-test-run.patch new file mode 100644 index 0000000..5714a16 --- /dev/null +++ b/SOURCES/0514-udev-test-fix-missing-directory-test-run.patch @@ -0,0 +1,35 @@ +From 974431a70775d5127cd973c4b4705d2cf8884011 Mon Sep 17 00:00:00 2001 +From: Alexey Bogdanenko +Date: Sat, 8 Dec 2018 15:35:30 +0300 +Subject: [PATCH] udev-test: fix missing directory test/run + +Fixes the following error: + + Failed to mount test /run: No such file or directory + +By the time command "./test-udev check" calls function "fake_filesystems", +directory "test/run" must be present. + +(cherry picked from commit 1e5548c0e0962424b6ca5fdfd35c866b70760c8f) + +Related: #1642728 +--- + test/udev-test.pl | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 3517feab15..eb76ebd72e 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1558,6 +1558,11 @@ sub udev_setup { + + system("rm", "-rf", "$udev_run"); + ++ if (!mkdir($udev_run)) { ++ warn "unable to create directory $udev_run"; ++ return 0; ++ } ++ + return 1; + } + diff --git a/SOURCES/0515-udev-test-check-if-permitted-to-create-block-device-.patch b/SOURCES/0515-udev-test-check-if-permitted-to-create-block-device-.patch new file mode 100644 index 0000000..67037a2 --- /dev/null +++ b/SOURCES/0515-udev-test-check-if-permitted-to-create-block-device-.patch @@ -0,0 +1,31 @@ +From 57e9ee0f19098d56995955f6692437affdf94041 Mon Sep 17 00:00:00 2001 +From: Alexey Bogdanenko +Date: Tue, 11 Dec 2018 16:55:34 +0300 +Subject: [PATCH] udev-test: check if permitted to create block device nodes + +(cherry picked from commit dbfbc6c4e34366033cb340e8b0c3cbca683ff6f5) + +Related: #1642728 +--- + test/udev-test.pl | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index eb76ebd72e..957cda541c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1554,6 +1554,14 @@ sub udev_setup { + return 0; + } + ++ # check if we are permitted to create block device nodes ++ my $block_device_filename = $udev_dev . "/sda"; ++ if (system("mknod", $block_device_filename, "b", "8", "0")) { ++ warn "unable to create $block_device_filename"; ++ return 0; ++ } ++ unlink $block_device_filename; ++ + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + + system("rm", "-rf", "$udev_run"); diff --git a/SOURCES/0516-test-udev-add-a-testcase-of-too-long-line.patch b/SOURCES/0516-test-udev-add-a-testcase-of-too-long-line.patch new file mode 100644 index 0000000..7f712d8 --- /dev/null +++ b/SOURCES/0516-test-udev-add-a-testcase-of-too-long-line.patch @@ -0,0 +1,45 @@ +From 527d43064a93fae9a4490e5d152b120e91f5eade Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 18 Feb 2019 10:38:29 +0900 +Subject: [PATCH] test-udev: add a testcase of too long line + +(cherry picked from commit 1e797cf596df50a6bdd8cbf8e9b2467a3a934171) + +Related: #1642728 +--- + test/udev-test.pl | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 957cda541c..3a50694fa9 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -39,6 +39,11 @@ for (my $i = 1; $i <= 10000; ++$i) { + $rules_10k_tags .= 'KERNEL=="sda", TAG+="test' . $i . "\"\n"; + } + ++my $rules_10k_tags_continuation = ""; ++for (my $i = 1; $i <= 10000; ++$i) { ++ $rules_10k_tags_continuation .= 'KERNEL=="sda", TAG+="test' . $i . "\"\\\n"; ++} ++ + my @tests = ( + { + desc => "no rules", +@@ -1444,6 +1449,16 @@ EOF + exp_name => "found", + rules => $rules_10k_tags . < "don't crash with lots of tags with continuation", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad" , ++ rules => $rules_10k_tags_continuation . < +Date: Tue, 19 Feb 2019 09:21:42 +0900 +Subject: [PATCH] test-udev: use proper semantics for too long line with + continuation + +Follow-up for 1e797cf596df50a6bdd8cbf8e9b2467a3a934171. + +(cherry picked from commit e37a5d90b0c624b95f8d0c3400288fec60417ec4) + +Related: #1642728 +--- + test/udev-test.pl | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 3a50694fa9..58b5dc85e1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -39,10 +39,11 @@ for (my $i = 1; $i <= 10000; ++$i) { + $rules_10k_tags .= 'KERNEL=="sda", TAG+="test' . $i . "\"\n"; + } + +-my $rules_10k_tags_continuation = ""; +-for (my $i = 1; $i <= 10000; ++$i) { +- $rules_10k_tags_continuation .= 'KERNEL=="sda", TAG+="test' . $i . "\"\\\n"; ++my $rules_10k_tags_continuation = "KERNEL==\"sda\", \\\n"; ++for (my $i = 1; $i < 10000; ++$i) { ++ $rules_10k_tags_continuation .= 'TAG+="test' . $i . "\",\\\n"; + } ++$rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; + + my @tests = ( + { diff --git a/SOURCES/0518-test-udev-add-more-tests-for-line-continuations-and-.patch b/SOURCES/0518-test-udev-add-more-tests-for-line-continuations-and-.patch new file mode 100644 index 0000000..9689d81 --- /dev/null +++ b/SOURCES/0518-test-udev-add-more-tests-for-line-continuations-and-.patch @@ -0,0 +1,40 @@ +From 66c41fbbeb472563993724352b1984aa3e7e47db Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 19 Feb 2019 09:22:45 +0900 +Subject: [PATCH] test-udev: add more tests for line continuations and comments + +(cherry picked from commit d35976c670b0e5c2d4081b781e5af88c0689ff00) + +Related: #1642728 +--- + test/udev-test.pl | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 58b5dc85e1..a5e1f8cda3 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1453,13 +1453,21 @@ TAGS=="test1", TAGS=="test500", TAGS=="test1234", TAGS=="test9999", TAGS=="test1 + EOF + }, + { +- desc => "don't crash with lots of tags with continuation", ++ desc => "continuations", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad" , + rules => $rules_10k_tags_continuation . < +Date: Thu, 21 Feb 2019 18:03:32 +0900 +Subject: [PATCH] test-udev: add more tests for line continuation + +(cherry picked from commit 84a0819c9d89a2ddb195a5d975ae1fd5c62fde3c) + +Related: #1642728 +--- + test/udev-test.pl | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a5e1f8cda3..002fabd9fd 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1466,8 +1466,42 @@ TAG+="hoge1",\\ + TAG+="hoge2",\\ + # spaces before and after token are dropped + TAG+="hoge3", \\ ++\\ ++ \\ + TAG+="hoge4" + TAGS=="hoge1", TAGS=="hoge2", TAGS=="hoge3", TAGS=="hoge4", SYMLINK+="found" ++EOF ++ }, ++ { ++ desc => "continuations with empty line", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "continuations with white only line", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < +Date: Thu, 21 Feb 2019 18:04:12 +0900 +Subject: [PATCH] test-udev: fix alignment and drop unnecessary white spaces + +(cherry picked from commit 3dd2d524141d09d57443ae339e1a77d7ce40f847) + +Related: #1642728 +--- + test/udev-test.pl | 114 +++++++++++++++++++++++----------------------- + 1 file changed, 57 insertions(+), 57 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 002fabd9fd..122359e377 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -49,7 +49,7 @@ my @tests = ( + { + desc => "no rules", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda" , ++ exp_name => "sda", + exp_rem_error => "yes", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_name => "boot_disk", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_name => "boot_disk", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_name => "boot_disk", + rules => < "label test of scsi partition", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "label test of pattern match", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "label test of multiple sysfs files", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "label test of max sysfs files (skip invalid rule)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "catch device by *", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "catch device by * - take 2", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "catch device by ?", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "catch device by character class", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "replace kernel name", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle comment lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle comment lines in config file with whitespace (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle whitespace only lines (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "whitespace" , ++ exp_name => "whitespace", + rules => < "Handle empty lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle backslashed multi lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "subdirectory handling", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "sub/direct/ory/modem" , ++ exp_name => "sub/direct/ory/modem", + rules => < "parent device name match of scsi partition", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "first_disk5" , ++ exp_name => "first_disk5", + rules => < "test substitution chars", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , ++ exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0", + rules => < "sustitution of sysfs value (%s{file})", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk-ATA-sda" , ++ exp_name => "disk-ATA-sda", + rules => < "program result substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "special-device-5" , +- not_exp_name => "not" , ++ exp_name => "special-device-5", ++ not_exp_name => "not", + rules => < "program result substitution (newline removal)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "newline_removed" , ++ exp_name => "newline_removed", + rules => < "program result substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "test-0:0:0:0" , ++ exp_name => "test-0:0:0:0", + rules => < "program with lots of arguments", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo9" , ++ exp_name => "foo9", + rules => < "program with subshell", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "bar9" , ++ exp_name => "bar9", + rules => < "program arguments combined with apostrophes", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo7" , ++ exp_name => "foo7", + rules => < "program arguments combined with escaped double quotes, part 1", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_name => "foo2", + rules => < "program arguments combined with escaped double quotes, part 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_name => "foo2", + rules => < "program arguments combined with escaped double quotes, part 3", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_name => "foo2", + rules => < "characters before the %c{N} substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo9" , ++ exp_name => "my-foo9", + rules => < "substitute the second to last argument", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo8" , ++ exp_name => "my-foo8", + rules => < "test substitution by variable name 3", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "850:0:0:05" , ++ exp_name => "850:0:0:05", + rules => < "test substitution by variable name 4", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "855" , ++ exp_name => "855", + rules => < "test substitution by variable name 5", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "8550:0:0:0" , ++ exp_name => "8550:0:0:0", + rules => < "non matching SUBSYSTEMS", + devpath => "/devices/virtual/tty/console", +- exp_name => "TTY" , ++ exp_name => "TTY", + rules => < "ATTRS match", + devpath => "/devices/virtual/tty/console", +- exp_name => "foo" , ++ exp_name => "foo", + rules => < "ATTR (empty file)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "empty" , ++ exp_name => "empty", + rules => < "ATTR (non-existent file)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "non-existent" , ++ exp_name => "non-existent", + rules => < "program and bus type match", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0" , ++ exp_name => "scsi-0:0:0:0", + rules => < "sysfs parent hierarchy", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "name test with ! in the name", + devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "is/a/fake/blockdev0" , ++ exp_name => "is/a/fake/blockdev0", + rules => < "name test with ! in the name, but no matching rule", + devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "fake/blockdev0" , ++ exp_name => "fake/blockdev0", + exp_rem_error => "yes", + rules => < "KERNELS wildcard partial 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0", +- rules => < < "/devices/virtual/misc/misc-fake1", + exp_name => "node", + exp_majorminor => "4095:1", +- rules => < < "multiple symlinks with a lot of s p a c e s", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "one", +- not_exp_name => " ", ++ not_exp_name => " ", + rules => < "multiple symlinks", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "second-0" , ++ exp_name => "second-0", + rules => < "symlink name '.'", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => ".", +- exp_add_error => "yes", +- exp_rem_error => "yes", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", + rules => < "symlink node to itself", + devpath => "/devices/virtual/tty/tty0", + exp_name => "link", +- exp_add_error => "yes", +- exp_rem_error => "yes", +- option => "clean", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", ++ option => "clean", + rules => < "add and match tag", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", +- not_exp_name => "bad" , ++ not_exp_name => "bad", + rules => < "continuations", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", +- not_exp_name => "bad" , ++ not_exp_name => "bad", + rules => $rules_10k_tags_continuation . < +Date: Fri, 5 Jul 2019 11:24:55 -0400 +Subject: [PATCH] test/udev-test.pl: cleanup if skipping test + +In Ubuntu CI, udev-test.pl is run from the debian/test/udev script, +in a test dir created for it; but udev-test.pl setup mounts a +dir, so if it doesn't cleanup/unmount before exiting, the test dir +autopkgtest created for it can't be removed, and autopkgtest +aborts the entire test suite, for example this output (from a +test run inside an armhf container): + +autopkgtest [12:45:36]: test udev: [----------------------- +umount: test/tmpfs: no mount point specified. +mknod: test/tmpfs/dev/null: Operation not permitted +unable to create test/tmpfs/dev/null at ./udev-test.pl line 1611. +Failed to set up the environment, skipping the test at ./udev-test.pl line 1731. +autopkgtest [12:45:41]: test udev: -----------------------] +autopkgtest [12:45:44]: test udev: - - - - - - - - - - results - - - - - - - - - - +udev FAIL non-zero exit status 77 +rm: cannot remove '/tmp/autopkgtest.ocPFA6/autopkgtest_tmp/test/tmpfs': Device or resource busy +autopkgtest [12:46:22]: ERROR: "rm -rf /tmp/autopkgtest.ocPFA6/udev-artifacts /tmp/autopkgtest.ocPFA6/autopkgtest_tmp" failed with stderr "rm: + +(cherry picked from commit abb9cc50afb3949c442849f43301fb33578f3888) + +Related: #1642728 +--- + test/udev-test.pl | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 122359e377..2fea72875b 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1713,6 +1713,12 @@ sub run_test { + + } + ++sub cleanup { ++ system("rm", "-rf", "$udev_run"); ++ system("umount", "$udev_tmpfs"); ++ rmdir($udev_tmpfs); ++} ++ + # only run if we have root permissions + # due to mknod restrictions + if (!($<==0)) { +@@ -1729,11 +1735,13 @@ if ($? >> 8 == 0) { + + if (!udev_setup()) { + warn "Failed to set up the environment, skipping the test"; ++ cleanup(); + exit($EXIT_TEST_SKIP); + } + + if (system($udev_bin, "check")) { + warn "$udev_bin failed to set up the environment, skipping the test"; ++ cleanup(); + exit($EXIT_TEST_SKIP); + } + +@@ -1776,10 +1784,7 @@ if ($list[0]) { + + print "$error errors occurred\n\n"; + +-# cleanup +-system("rm", "-rf", "$udev_run"); +-system("umount", "$udev_tmpfs"); +-rmdir($udev_tmpfs); ++cleanup(); + + if ($error > 0) { + exit(1); diff --git a/SOURCES/0522-test-add-test-cases-for-empty-string-match.patch b/SOURCES/0522-test-add-test-cases-for-empty-string-match.patch new file mode 100644 index 0000000..acf7479 --- /dev/null +++ b/SOURCES/0522-test-add-test-cases-for-empty-string-match.patch @@ -0,0 +1,89 @@ +From 03bc565e6e3249385c4e1ca0ae27670ca2ad9a41 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 11 Sep 2019 09:06:15 +0900 +Subject: [PATCH] test: add test cases for empty string match + +(cherry picked from commit 48d26c90852c22ec94be961f5fbdcf462bb9a6e8) + +Related: #1642728 +--- + test/udev-test.pl | 66 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 2fea72875b..50d978391b 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1256,6 +1256,72 @@ KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1" + KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2" + KERNEL=="all|dontknow|ttyACM0", SYMLINK+="right" + KERNEL=="ttyACM0a|nothing", SYMLINK+="wrong3" ++EOF ++ }, ++ { ++ desc => "test multi matches 5", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 6", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 7", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 8", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 9", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 10", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < +Date: Sun, 12 Jul 2020 03:27:45 -0400 +Subject: [PATCH] test: add test case for multi matches when use "||" + +Signed-off-by: gaoyi +(cherry picked from commit 0d3a8bc7ebd76591e14f7098b4266fd2065ac4db) + +Related: #1642728 +--- + test/udev-test.pl | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 50d978391b..4bf97d82bb 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1322,6 +1322,17 @@ EOF + KERNEL=="sda", TAG="" + TAGS=="foo|", SYMLINK+="found" + TAGS=="aaa|bbb", SYMLINK+="bad" ++EOF ++ }, ++ { ++ desc => "test multi matches 11", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < +Date: Fri, 4 Sep 2020 18:09:20 +0200 +Subject: [PATCH] udev-test: do not rely on "mail" group being defined + +"audio" should be there, at least we declare it. "mail" nowadays is less +likely to exist than in the past. + +Fixes one of the items in #16942. + +(cherry picked from commit a9030b81c154c3ec92227d04cad6b13cc1125608) + +Related: #1642728 +--- + test/udev-test.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 4bf97d82bb..a4deffacb9 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -629,9 +629,9 @@ EOF + desc => "textual user/group id", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", +- exp_perms => "root:mail:0660", ++ exp_perms => "root:audio:0660", + rules => < +Date: Fri, 20 Apr 2018 22:38:30 +0200 +Subject: [PATCH] test/udev-test.pl: allow multiple devices per test + +Allow testing cases where multiple devices are added and removed. +This implies a change of the data structure: every test allows +for multiple devices to be added, and "exp_name" etc. are now properties +of the device, not of the test. + +(cherry picked from commit 255c05b72455dcad1b5552d12a813b31f68201a7) + +Related: #1642728 +--- + test/udev-test.pl | 1352 +++++++++++++++++++++++++++++++-------------- + 1 file changed, 929 insertions(+), 423 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a4deffacb9..bd5401da75 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -48,17 +48,28 @@ $rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; + my @tests = ( + { + desc => "no rules", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda" , ++ exp_rem_error => "yes", ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "sda1" , ++ exp_rem_error => "yes", ++ }], + rules => < "label test of scsi disc", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "boot_disk" , ++ }], + rules => < "label test of scsi disc", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "boot_disk" , ++ }], + rules => < "label test of scsi disc", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "boot_disk" , ++ }], + rules => < "label test of scsi partition", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "label test of pattern match", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "label test of multiple sysfs files", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "label test of max sysfs files (skip invalid rule)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "catch device by *", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "catch device by * - take 2", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "catch device by ?", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "catch device by character class", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "replace kernel name", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle comment lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle comment lines in config file with whitespace (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle whitespace only lines (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "whitespace", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "whitespace" , ++ }], + rules => < "Handle empty lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle backslashed multi lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "preserve backslashes, if they are not for a newline", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "aaa", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "aaa", ++ }], + rules => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "subdirectory handling", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "sub/direct/ory/modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "sub/direct/ory/modem" , ++ }], + rules => < "parent device name match of scsi partition", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "first_disk5", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "first_disk5" , ++ }], + rules => < "test substitution chars", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , ++ }], + rules => < "import of shell-value returned from program", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node12345678", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node12345678", ++ }], + rules => < "sustitution of sysfs value (%s{file})", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk-ATA-sda", ++ desc => "substitution of sysfs value (%s{file})", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "disk-ATA-sda" , ++ }], + rules => < "program result substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "special-device-5", +- not_exp_name => "not", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "special-device-5" , ++ not_exp_name => "not" , ++ }], + rules => < "program result substitution (newline removal)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "newline_removed", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "newline_removed" , ++ }], + rules => < "program result substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "test-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "test-0:0:0:0" , ++ }], + rules => < "program with lots of arguments", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo9", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo9" , ++ }], + rules => < "program with subshell", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "bar9", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "bar9" , ++ }], + rules => < "program arguments combined with apostrophes", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo7", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo7" , ++ }], + rules => < "program arguments combined with escaped double quotes, part 1", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo2" , ++ }], + rules => < "program arguments combined with escaped double quotes, part 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo2" , ++ }], + rules => < "program arguments combined with escaped double quotes, part 3", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo2" , ++ }], + rules => < "characters before the %c{N} substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo9", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "my-foo9" , ++ }], + rules => < "substitute the second to last argument", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo8", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "my-foo8" , ++ }], + rules => < "test substitution by variable name", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ }], + rules => < "test substitution by variable name 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ }], + rules => < "test substitution by variable name 3", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "850:0:0:05", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "850:0:0:05" , ++ }], + rules => < "test substitution by variable name 4", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "855", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "855" , ++ }], + rules => < "test substitution by variable name 5", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "8550:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "8550:0:0:0" , ++ }], + rules => < "non matching SUBSYSTEMS for device with no parent", +- devpath => "/devices/virtual/tty/console", +- exp_name => "TTY", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/console", ++ exp_name => "TTY", ++ }], + rules => < "non matching SUBSYSTEMS", +- devpath => "/devices/virtual/tty/console", +- exp_name => "TTY", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/console", ++ exp_name => "TTY" , ++ }], + rules => < "ATTRS match", +- devpath => "/devices/virtual/tty/console", +- exp_name => "foo", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/console", ++ exp_name => "foo" , ++ }], + rules => < "ATTR (empty file)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "empty", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "empty" , ++ }], + rules => < "ATTR (non-existent file)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "non-existent", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "non-existent" , ++ }], + rules => < "program and bus type match", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0" , ++ }], + rules => < "sysfs parent hierarchy", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "name test with ! in the name", +- devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "is/a/fake/blockdev0", ++ devices => [ ++ { ++ devpath => "/devices/virtual/block/fake!blockdev0", ++ exp_name => "is/a/fake/blockdev0" , ++ }], + rules => < "name test with ! in the name, but no matching rule", +- devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "fake/blockdev0", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/virtual/block/fake!blockdev0", ++ exp_name => "fake/blockdev0" , ++ exp_rem_error => "yes", ++ }], + rules => < "KERNELS rule", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], + rules => < "KERNELS wildcard all", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], + rules => < "KERNELS wildcard partial", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], + rules => < "KERNELS wildcard partial 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", +- rules => < [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], ++ rules => < "substitute attr with link target value (first match)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-sd", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "driver-is-sd", ++ }], + rules => < "substitute attr with link target value (currently selected device)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-ahci", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "driver-is-ahci", ++ }], + rules => < "ignore ATTRS attribute whitespace", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ignored", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ignored", ++ }], + rules => < "do not ignore ATTRS attribute whitespace", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "matched-with-space", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "matched-with-space", ++ }], + rules => < "permissions USER=bad GROUP=name", +- devpath => "/devices/virtual/tty/tty33", +- exp_name => "tty33", +- exp_perms => "0:0:0600", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/tty33", ++ exp_name => "tty33", ++ exp_perms => "0:0:0600", ++ }], + rules => < "permissions OWNER=1", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "1::0600", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "1::0600", ++ }], + rules => < "permissions GROUP=1", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => ":1:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => ":1:0660", ++ }], + rules => < "textual user id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "daemon::0600", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "daemon::0600", ++ }], + rules => < "textual group id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => ":daemon:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => ":daemon:0660", ++ }], + rules => < "textual user/group id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "root:audio:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "root:audio:0660", ++ }], + rules => < "permissions MODE=0777", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "::0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "::0777", ++ }], + rules => < "permissions OWNER=1 GROUP=1 MODE=0777", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "1:1:0777", ++ }], + rules => < "permissions OWNER to 1", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1::", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1::", ++ }], + rules => < "permissions GROUP to 1", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => ":1:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => ":1:0660", ++ }], + rules => < "permissions MODE to 0060", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "::0060", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "::0060", ++ }], + rules => < "permissions OWNER, GROUP, MODE", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:1:0777", ++ }], + rules => < "permissions only rule", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:1:0777", ++ }], + rules => < "multiple permissions only rule", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:1:0777", ++ }], + rules => < "permissions only rule with override at SYMLINK+ rule", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:2:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:2:0777", ++ }], + rules => < "major/minor number test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_majorminor => "8:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_majorminor => "8:0", ++ }], + rules => < "big major number test", +- devpath => "/devices/virtual/misc/misc-fake1", +- exp_name => "node", +- exp_majorminor => "4095:1", +- rules => < [ ++ { ++ devpath => "/devices/virtual/misc/misc-fake1", ++ exp_name => "node", ++ exp_majorminor => "4095:1", ++ }], ++ rules => < "big major and big minor number test", +- devpath => "/devices/virtual/misc/misc-fake89999", +- exp_name => "node", +- exp_majorminor => "4095:89999", ++ devices => [ ++ { ++ devpath => "/devices/virtual/misc/misc-fake89999", ++ exp_name => "node", ++ exp_majorminor => "4095:89999", ++ }], + rules => < "multiple symlinks with format char", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink2-ttyACM0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "symlink2-ttyACM0", ++ }], + rules => < "multiple symlinks with a lot of s p a c e s", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "one", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "one", ++ not_exp_name => " ", ++ }], + rules => < "symlink with spaces in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with leading space in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with trailing space in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with lots of space in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with multiple spaces in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with space and var with space, part 1", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "first", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "first", ++ not_exp_name => " ", ++ }], + rules => < "symlink with space and var with space, part 2", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with space and var with space, part 3", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "another_symlink", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "another_symlink", ++ not_exp_name => " ", ++ }], + rules => < "symlink creation (same directory)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem0", ++ }], + rules => < "multiple symlinks", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "second-0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "second-0" , ++ }], + rules => < "symlink name '.'", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => ".", +- exp_add_error => "yes", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => ".", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", ++ }], + rules => < "symlink node to itself", +- devpath => "/devices/virtual/tty/tty0", +- exp_name => "link", +- exp_add_error => "yes", +- exp_rem_error => "yes", +- option => "clean", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/tty0", ++ exp_name => "link", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", ++ }], ++ option => "clean", + rules => < "symlink %n substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "symlink0", ++ }], + rules => < "symlink %k substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink-ttyACM0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "symlink-ttyACM0", ++ }], + rules => < "symlink %M:%m substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "major-166:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "major-166:0", ++ }], + rules => < "symlink %b substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "symlink-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "symlink-0:0:0:0", ++ }], + rules => < "symlink %c substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "test", ++ }], + rules => < "symlink %c{N} substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "test", ++ }], + rules => < "symlink %c{N+} substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "this", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "this", ++ }], + rules => < "symlink only rule with %c{N+}", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "test", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "test", ++ }], + rules => < "symlink %s{filename} substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "166:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "166:0", ++ }], + rules => < "program result substitution (numbered part of)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "link1", ++ }], + rules => < "program result substitution (numbered part of+)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link4", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "link4", ++ }], + rules => < "SUBSYSTEM match test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ }], + rules => < "DRIVERS match test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ }], + rules => < "devnode substitution test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ }], + rules => < "parent node name substitution test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sda-part-1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "sda-part-1", ++ }], + rules => < "udev_root substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "start-/dev-end", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "start-/dev-end", ++ }], + rules => < "last_rule option", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "last", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "last", ++ }], + rules => < "negation KERNEL!=", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "match", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "match", ++ }], + rules => < "negation SUBSYSTEM!=", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "not-anything", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "not-anything", ++ }], + rules => < "negation PROGRAM!= exit code", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "nonzero-program", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "nonzero-program", ++ }], + rules => < "ENV{} test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test (assign)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test (assign 2 times)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test (assign2)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "part", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "part", ++ }], + rules => < "untrusted string sanitize", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sane", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "sane", ++ }], + rules => < "untrusted string sanitize (don't replace utf8)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "uber", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "uber", ++ }], + rules => < "untrusted string sanitize (replace invalid utf8)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "replaced", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "replaced", ++ }], + rules => < "read sysfs value from parent device", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "serial-354172020305000", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "serial-354172020305000", ++ }], + rules => < "match against empty key string", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ }], + rules => < "check ACTION value", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ }], + rules => < "final assignment", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", +- exp_perms => "root:tty:0640", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ exp_perms => "root:tty:0640", ++ }], + rules => < "final assignment 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", +- exp_perms => "root:tty:0640", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ exp_perms => "root:tty:0640", ++ }], + rules => < "env substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node-add-me", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node-add-me", ++ }], + rules => < "reset list to current value", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "three", +- not_exp_name => "two", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "three", ++ not_exp_name => "two", ++ }], + rules => < "test empty SYMLINK+ (empty override)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", +- not_exp_name => "wrong", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ not_exp_name => "wrong", ++ }], + rules => < "test multi matches", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 2", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 3", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 4", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 5", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ desc => "test multi matches 5", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 6", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 7", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 8", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 9", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 10", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 11", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "IMPORT parent test sequence 1/2 (keep)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "parent", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "parent", ++ }], + option => "keep", + rules => < "IMPORT parent test sequence 2/2 (keep)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "parentenv-parent_right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "parentenv-parent_right", ++ }], + option => "clean", + rules => < "GOTO test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "right", ++ }], + rules => < "GOTO label does not exist", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "right", ++ }], + rules => < "SYMLINK+ compare test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", +- not_exp_name => "wrong", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "right", ++ not_exp_name => "wrong", ++ }], + rules => < "invalid key operation", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "yes", ++ }], + rules => < "operator chars in attribute", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "yes", ++ }], + rules => < "overlong comment line", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "yes", ++ }], + rules => < "magic subsys/kernel lookup", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "00:16:41:e2:8d:ff", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "00:16:41:e2:8d:ff", ++ }], + rules => < "TEST absolute path", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "there", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "there", ++ }], + rules => < "TEST subsys/kernel lookup", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "yes", ++ }], + rules => < "TEST relative path", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "relative", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "relative", ++ }], + rules => < "TEST wildcard substitution (find queue/nr_requests)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found-subdir", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found-subdir", ++ }], + rules => < "TEST MODE=0000", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_perms => "0:0:0000", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda", ++ exp_perms => "0:0:0000", ++ exp_rem_error => "yes", ++ }], + rules => < "TEST PROGRAM feeds OWNER, GROUP, MODE", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_perms => "1:1:0400", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda", ++ exp_perms => "1:1:0400", ++ exp_rem_error => "yes", ++ }], + rules => < "TEST PROGRAM feeds MODE with overflow", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_perms => "0:0:0440", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda", ++ exp_perms => "0:0:0440", ++ exp_rem_error => "yes", ++ }], + rules => < "magic [subsys/sysname] attribute substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda-8741C4G-end", +- exp_perms => "0:0:0600", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda-8741C4G-end", ++ exp_perms => "0:0:0600", ++ }], + rules => < "builtin path_id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", ++ }], + rules => < "add and match tag", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad" , ++ }], + rules => < "don't crash with lots of tags", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ }], + rules => $rules_10k_tags . < "continuations", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => $rules_10k_tags_continuation . < "continuations with empty line", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ ++ }], + rules => < "continuations with white only line", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => <{desc}\n"; +- print "device \'$rules->{devpath}\' expecting node/link \'$rules->{exp_name}\'\n"; ++sub check_add { ++ my ($device) = @_; + +- $rc = udev("add", $rules->{devpath}, \$rules->{rules}); +- if ($rc != 0) { +- print "$udev_bin add failed with code $rc\n"; +- $error++; +- } +- if (defined($rules->{not_exp_name})) { +- if ((-e "$udev_dev/$rules->{not_exp_name}") || +- (-l "$udev_dev/$rules->{not_exp_name}")) { +- print "nonexistent: error \'$rules->{not_exp_name}\' not expected to be there\n"; ++ if (defined($device->{not_exp_name})) { ++ if ((-e "$udev_dev/$device->{not_exp_name}") || ++ (-l "$udev_dev/$device->{not_exp_name}")) { ++ print "nonexistent: error \'$device->{not_exp_name}\' not expected to be there\n"; + $error++; + sleep(1); + } + } +- +- if ((-e "$udev_dev/$rules->{exp_name}") || +- (-l "$udev_dev/$rules->{exp_name}")) { ++ if ((-e "$udev_dev/$device->{exp_name}") || ++ (-l "$udev_dev/$device->{exp_name}")) { + + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, +- $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$rules->{exp_name}"); ++ $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$device->{exp_name}"); + +- if (defined($rules->{exp_perms})) { +- permissions_test($rules, $uid, $gid, $mode); ++ if (defined($device->{exp_perms})) { ++ permissions_test($device, $uid, $gid, $mode); + } +- if (defined($rules->{exp_majorminor})) { +- major_minor_test($rules, $rdev); ++ if (defined($device->{exp_majorminor})) { ++ major_minor_test($device, $rdev); + } +- print "add: ok\n"; ++ print "add $device->{devpath}: ok\n"; + } else { +- print "add: error"; +- if ($rules->{exp_add_error}) { ++ print "add $device->{devpath}: error"; ++ if ($device->{exp_add_error}) { + print " as expected\n"; + } else { + print "\n"; +@@ -1755,21 +2231,15 @@ sub run_test { + sleep(1); + } + } ++} + +- if (defined($rules->{option}) && $rules->{option} eq "keep") { +- print "\n\n"; +- return; +- } ++sub check_remove { ++ my ($device) = @_; + +- $rc = udev("remove", $rules->{devpath}, \$rules->{rules}); +- if ($rc != 0) { +- print "$udev_bin remove failed with code $rc\n"; +- $error++; +- } +- if ((-e "$udev_dev/$rules->{exp_name}") || +- (-l "$udev_dev/$rules->{exp_name}")) { +- print "remove: error"; +- if ($rules->{exp_rem_error}) { ++ if ((-e "$udev_dev/$device->{exp_name}") || ++ (-l "$udev_dev/$device->{exp_name}")) { ++ print "remove $device->{devpath}: error"; ++ if ($device->{exp_rem_error}) { + print " as expected\n"; + } else { + print "\n"; +@@ -1779,7 +2249,43 @@ sub run_test { + sleep(1); + } + } else { +- print "remove: ok\n"; ++ print "remove $device->{devpath}: ok\n"; ++ } ++} ++ ++sub run_test { ++ my ($rules, $number) = @_; ++ my $rc; ++ my @devices = @{$rules->{devices}}; ++ ++ print "TEST $number: $rules->{desc}\n"; ++ foreach my $dev (@devices) { ++ print "device \'$dev->{devpath}\' expecting node/link \'$dev->{exp_name}\'\n"; ++ $rc = udev("add", $dev->{devpath}, \$rules->{rules}); ++ if ($rc != 0) { ++ print "$udev_bin add failed with code $rc\n"; ++ $error++; ++ } ++ } ++ ++ foreach my $dev (@devices) { ++ check_add($dev); ++ } ++ ++ if (defined($rules->{option}) && $rules->{option} eq "keep") { ++ print "\n\n"; ++ return; ++ } ++ ++ foreach my $dev (@devices) { ++ $rc = udev("remove", $dev->{devpath}, \$rules->{rules}); ++ if ($rc != 0) { ++ print "$udev_bin remove failed with code $rc\n"; ++ $error++; ++ } ++ } ++ foreach my $dev (@devices) { ++ check_remove($dev); + } + + print "\n"; diff --git a/SOURCES/0526-test-udev-test.pl-create-rules-only-once.patch b/SOURCES/0526-test-udev-test.pl-create-rules-only-once.patch new file mode 100644 index 0000000..b394455 --- /dev/null +++ b/SOURCES/0526-test-udev-test.pl-create-rules-only-once.patch @@ -0,0 +1,61 @@ +From 9aa12f2f564c208c4c1eaef613d18d1c0b481a16 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 23 Apr 2018 21:58:12 +0200 +Subject: [PATCH] test/udev-test.pl: create rules only once + +It's not necessary to write the rules for every udev run, as we +now may have many (rather than just 2) per test. + +(cherry picked from commit af7ee3eae689f9c31b49ea13758ad9c901918ce3) + +Related: #1642728 +--- + test/udev-test.pl | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index bd5401da75..8b5a97ad61 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2069,14 +2069,18 @@ EOF + }, + ); + +-sub udev { +- my ($action, $devpath, $rules) = @_; ++sub create_rules { ++ my ($rules) = @_; + + # create temporary rules + system("mkdir", "-p", "$udev_rules_dir"); + open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules"; + print CONF $$rules; + close CONF; ++} ++ ++sub udev { ++ my ($action, $devpath) = @_; + + if ($valgrind > 0) { + return system("$udev_bin_valgrind $action $devpath"); +@@ -2259,9 +2263,10 @@ sub run_test { + my @devices = @{$rules->{devices}}; + + print "TEST $number: $rules->{desc}\n"; ++ create_rules(\$rules->{rules}); + foreach my $dev (@devices) { + print "device \'$dev->{devpath}\' expecting node/link \'$dev->{exp_name}\'\n"; +- $rc = udev("add", $dev->{devpath}, \$rules->{rules}); ++ $rc = udev("add", $dev->{devpath}); + if ($rc != 0) { + print "$udev_bin add failed with code $rc\n"; + $error++; +@@ -2278,7 +2283,7 @@ sub run_test { + } + + foreach my $dev (@devices) { +- $rc = udev("remove", $dev->{devpath}, \$rules->{rules}); ++ $rc = udev("remove", $dev->{devpath}); + if ($rc != 0) { + print "$udev_bin remove failed with code $rc\n"; + $error++; diff --git a/SOURCES/0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch b/SOURCES/0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch new file mode 100644 index 0000000..f87307f --- /dev/null +++ b/SOURCES/0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch @@ -0,0 +1,169 @@ +From 618d56c7ac8bd8cd701344a0eaca8373a78dea95 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 23 Apr 2018 21:59:05 +0200 +Subject: [PATCH] test/udev-test.pl: allow concurrent additions and removals + +Allow testing cases where multiple devices are added and removed +simultaneously. Tests are started as synchronously as possible using a +semaphore, in order to test possible race conditions. If this isn't desired, +the test parameter "sleep_us" can be set to the number of microseconds to wait +between udev invocations. + +(cherry picked from commit 09a4062d70b3a10d022e40066e2adf09df05bbbc) + +Related: #1642728 +--- + test/udev-test.pl | 90 +++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 72 insertions(+), 18 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 8b5a97ad61..db25ef13c1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -18,6 +18,10 @@ + + use warnings; + use strict; ++use POSIX qw(WIFEXITED WEXITSTATUS); ++use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); ++use IPC::Semaphore; ++use Time::HiRes qw(usleep); + + my $udev_bin = "./test-udev"; + my $valgrind = 0; +@@ -2210,6 +2214,8 @@ sub check_add { + sleep(1); + } + } ++ ++ print "device \'$device->{devpath}\' expecting node/link \'$device->{exp_name}\'\n"; + if ((-e "$udev_dev/$device->{exp_name}") || + (-l "$udev_dev/$device->{exp_name}")) { + +@@ -2257,21 +2263,72 @@ sub check_remove { + } + } + ++sub run_udev { ++ my ($action, $dev, $sleep_us, $sema) = @_; ++ ++ # Notify main process that this worker has started ++ $sema->op(0, 1, 0); ++ ++ # Wait for start ++ $sema->op(0, 0, 0); ++ usleep($sleep_us) if defined ($sleep_us); ++ my $rc = udev($action, $dev->{devpath}); ++ exit $rc; ++} ++ ++sub fork_and_run_udev { ++ my ($action, $rules, $sema) = @_; ++ my @devices = @{$rules->{devices}}; ++ my $dev; ++ my $k = 0; ++ ++ $sema->setval(0, 1); ++ foreach $dev (@devices) { ++ my $pid = fork(); ++ ++ if (!$pid) { ++ run_udev($action, $dev, ++ defined($rules->{sleep_us}) ? $k * $rules->{sleep_us} : undef, ++ $sema); ++ } else { ++ $dev->{pid} = $pid; ++ } ++ $k++; ++ } ++ ++ # This operation waits for all workers to become ready, and ++ # starts them off when that's the case. ++ $sema->op(0, -($#devices + 2), 0); ++ ++ foreach $dev (@devices) { ++ my $rc; ++ my $pid; ++ ++ $pid = waitpid($dev->{pid}, 0); ++ if ($pid == -1) { ++ print "error waiting for pid dev->{pid}\n"; ++ $error += 1; ++ } ++ if (WIFEXITED($?)) { ++ $rc = WEXITSTATUS($?); ++ ++ if ($rc) { ++ print "$udev_bin $action for $dev->{devpath} failed with code $rc\n"; ++ $error += 1; ++ } ++ } ++ } ++} ++ + sub run_test { +- my ($rules, $number) = @_; ++ my ($rules, $number, $sema) = @_; + my $rc; + my @devices = @{$rules->{devices}}; + + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); +- foreach my $dev (@devices) { +- print "device \'$dev->{devpath}\' expecting node/link \'$dev->{exp_name}\'\n"; +- $rc = udev("add", $dev->{devpath}); +- if ($rc != 0) { +- print "$udev_bin add failed with code $rc\n"; +- $error++; +- } +- } ++ ++ fork_and_run_udev("add", $rules, $sema); + + foreach my $dev (@devices) { + check_add($dev); +@@ -2282,13 +2339,8 @@ sub run_test { + return; + } + +- foreach my $dev (@devices) { +- $rc = udev("remove", $dev->{devpath}); +- if ($rc != 0) { +- print "$udev_bin remove failed with code $rc\n"; +- $error++; +- } +- } ++ fork_and_run_udev("remove", $rules, $sema); ++ + foreach my $dev (@devices) { + check_remove($dev); + } +@@ -2350,12 +2402,13 @@ foreach my $arg (@ARGV) { + push(@list, $arg); + } + } ++my $sema = IPC::Semaphore->new(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR | IPC_CREAT); + + if ($list[0]) { + foreach my $arg (@list) { + if (defined($tests[$arg-1]->{desc})) { + print "udev-test will run test number $arg:\n\n"; +- run_test($tests[$arg-1], $arg); ++ run_test($tests[$arg-1], $arg, $sema); + } else { + print "test does not exist.\n"; + } +@@ -2365,11 +2418,12 @@ if ($list[0]) { + print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; + + foreach my $rules (@tests) { +- run_test($rules, $test_num); ++ run_test($rules, $test_num, $sema); + $test_num++; + } + } + ++$sema->remove; + print "$error errors occurred\n\n"; + + cleanup(); diff --git a/SOURCES/0528-test-udev-test.pl-use-computed-devnode-name.patch b/SOURCES/0528-test-udev-test.pl-use-computed-devnode-name.patch new file mode 100644 index 0000000..a20ebbd --- /dev/null +++ b/SOURCES/0528-test-udev-test.pl-use-computed-devnode-name.patch @@ -0,0 +1,260 @@ +From 5f34ea55a8c6723240eb1641a655db7df3c428a2 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 09:38:26 +0200 +Subject: [PATCH] test/udev-test.pl: use computed devnode name + +More often than not, the created devnode is the basename of the +sysfs entry. The "devnode" device may be used to override the +auto-detected node name. + +Permissions and major/minor number are now verified on the devnode +itself, not on symlinks. + +For those tests where exp_name is set to the computed devnode name, +the explicit "exp_name" can be removed. "exp_name" is only required for +symlinks. + +This allows separate testing for devnodes and symlinks an a follow-up +patch. + +(cherry picked from commit f0dccf01a7b4e72278e14effd74782ea83d0a73b) + +Related: #1642728 +--- + test/udev-test.pl | 92 +++++++++++++++++++++++++++++++++-------------- + 1 file changed, 66 insertions(+), 26 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index db25ef13c1..aa9a8dc2ff 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -55,12 +55,10 @@ my @tests = ( + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda" , + exp_rem_error => "yes", + }, + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sda1" , + exp_rem_error => "yes", + }], + rules => < [ + { + devpath => "/devices/virtual/block/fake!blockdev0", ++ devnode => "fake/blockdev0", + exp_name => "is/a/fake/blockdev0" , + }], + rules => < [ + { + devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "fake/blockdev0" , ++ devnode => "fake/blockdev0", + exp_rem_error => "yes", + }], + rules => < [ + { + devpath => "/devices/virtual/tty/tty33", +- exp_name => "tty33", + exp_perms => "0:0:0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1::", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => ":1:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "::0060", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:2:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", + exp_perms => "0:0:0000", + exp_rem_error => "yes", + }], +@@ -1935,7 +1925,6 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", + exp_perms => "1:1:0400", + exp_rem_error => "yes", + }], +@@ -1949,7 +1938,6 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", + exp_perms => "0:0:0440", + exp_rem_error => "yes", + }], +@@ -2203,6 +2191,44 @@ sub udev_setup { + return 1; + } + ++sub get_devnode { ++ my ($device) = @_; ++ my $devnode; ++ ++ if (defined($device->{devnode})) { ++ $devnode = "$udev_dev/$device->{devnode}"; ++ } else { ++ $devnode = "$device->{devpath}"; ++ $devnode =~ s!.*/!$udev_dev/!; ++ } ++ return $devnode; ++} ++ ++sub check_devnode { ++ my ($device) = @_; ++ my $devnode = get_devnode($device); ++ ++ my @st = lstat("$devnode"); ++ if (! (-b _ || -c _)) { ++ print "add $devnode: error\n"; ++ system("tree", "$udev_dev"); ++ $error++; ++ return undef; ++ } ++ ++ my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, ++ $atime, $mtime, $ctime, $blksize, $blocks) = @st; ++ ++ if (defined($device->{exp_perms})) { ++ permissions_test($device, $uid, $gid, $mode); ++ } ++ if (defined($device->{exp_majorminor})) { ++ major_minor_test($device, $rdev); ++ } ++ print "add $devnode: ok\n"; ++ return $devnode; ++} ++ + sub check_add { + my ($device) = @_; + +@@ -2215,19 +2241,13 @@ sub check_add { + } + } + ++ my $devnode = check_devnode($device); ++ + print "device \'$device->{devpath}\' expecting node/link \'$device->{exp_name}\'\n"; ++ return if (!defined($device->{exp_name})); ++ + if ((-e "$udev_dev/$device->{exp_name}") || + (-l "$udev_dev/$device->{exp_name}")) { +- +- my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, +- $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$device->{exp_name}"); +- +- if (defined($device->{exp_perms})) { +- permissions_test($device, $uid, $gid, $mode); +- } +- if (defined($device->{exp_majorminor})) { +- major_minor_test($device, $rdev); +- } + print "add $device->{devpath}: ok\n"; + } else { + print "add $device->{devpath}: error"; +@@ -2243,12 +2263,32 @@ sub check_add { + } + } + ++sub check_remove_devnode { ++ my ($device) = @_; ++ my $devnode = get_devnode($device); ++ ++ if (-e "$devnode") { ++ print "remove $devnode: error"; ++ print "\n"; ++ system("tree", "$udev_dev"); ++ print "\n"; ++ $error++; ++ sleep(1); ++ } else { ++ print "remove $devnode: ok\n"; ++ } ++} ++ + sub check_remove { + my ($device) = @_; + ++ check_remove_devnode($device); ++ ++ return if (!defined($device->{exp_name})); ++ + if ((-e "$udev_dev/$device->{exp_name}") || + (-l "$udev_dev/$device->{exp_name}")) { +- print "remove $device->{devpath}: error"; ++ print "remove $device->{exp_name}: error"; + if ($device->{exp_rem_error}) { + print " as expected\n"; + } else { +@@ -2259,7 +2299,7 @@ sub check_remove { + sleep(1); + } + } else { +- print "remove $device->{devpath}: ok\n"; ++ print "remove $device->{exp_name}: ok\n"; + } + } + diff --git a/SOURCES/0529-test-udev-test.pl-test-correctness-of-symlink-target.patch b/SOURCES/0529-test-udev-test.pl-test-correctness-of-symlink-target.patch new file mode 100644 index 0000000..3c6e624 --- /dev/null +++ b/SOURCES/0529-test-udev-test.pl-test-correctness-of-symlink-target.patch @@ -0,0 +1,61 @@ +From 8ee1cc626f616a2022d641a464fbde9108dd8ad9 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 10:50:24 +0200 +Subject: [PATCH] test/udev-test.pl: test correctness of symlink targets + +Test if symlinks are created correctly by comparing the symlink +targets to the devnode path. This implies (for the symlink) that +major/minor numbers and permissions are correct, as we have tested +that on the devnode already. + +(cherry picked from commit 997683c8f152e1c139a7ce537de81a0aeae4627f) + +Related: #1642728 +--- + test/udev-test.pl | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index aa9a8dc2ff..2e3089c5e0 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -22,6 +22,7 @@ use POSIX qw(WIFEXITED WEXITSTATUS); + use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); + use IPC::Semaphore; + use Time::HiRes qw(usleep); ++use Cwd qw(getcwd abs_path); + + my $udev_bin = "./test-udev"; + my $valgrind = 0; +@@ -2243,14 +2244,26 @@ sub check_add { + + my $devnode = check_devnode($device); + +- print "device \'$device->{devpath}\' expecting node/link \'$device->{exp_name}\'\n"; + return if (!defined($device->{exp_name})); + +- if ((-e "$udev_dev/$device->{exp_name}") || +- (-l "$udev_dev/$device->{exp_name}")) { +- print "add $device->{devpath}: ok\n"; ++ my @st = lstat("$udev_dev/$device->{exp_name}"); ++ if (-l _) { ++ my $cwd = getcwd(); ++ my $dir = "$udev_dev/$device->{exp_name}"; ++ $dir =~ s!/[^/]*$!!; ++ my $tgt = readlink("$udev_dev/$device->{exp_name}"); ++ $tgt = abs_path("$dir/$tgt"); ++ $tgt =~ s!^$cwd/!!; ++ ++ if ($tgt ne $devnode) { ++ print "symlink $device->{exp_name}: error, found -> $tgt\n"; ++ $error++; ++ system("tree", "$udev_dev"); ++ } else { ++ print "symlink $device->{exp_name}: ok\n"; ++ } + } else { +- print "add $device->{devpath}: error"; ++ print "symlink $device->{exp_name}: error"; + if ($device->{exp_add_error}) { + print " as expected\n"; + } else { diff --git a/SOURCES/0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch b/SOURCES/0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch new file mode 100644 index 0000000..f004054 --- /dev/null +++ b/SOURCES/0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch @@ -0,0 +1,1607 @@ +From fb8d10456d7d5a085e1adb5bfd45f1cda813ac22 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 17:15:58 +0200 +Subject: [PATCH] test/udev-test.pl: allow checking multiple symlinks + +Instead of testing the existence or non-exisitence of just a single +symlink, allow testing of several links per device. + +Change the test definitions accordingly. + +(cherry picked from commit e62acc3159935781f05fa59c48e5a74e85c61ce2) + +Related: #1642728 +--- + test/udev-test.pl | 495 +++++++++++++++++++++++++++------------------- + 1 file changed, 296 insertions(+), 199 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 2e3089c5e0..f5edecefd0 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -71,7 +71,7 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_links => ["boot_disk"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_links => ["boot_disk"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_links => ["boot_disk"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1", "boot_disk1-4", "boot_disk1-5"], ++ not_exp_links => ["boot_disk1-1", "boot_disk1-2", "boot_disk1-3"] + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1"], ++ not_exp_links => ["boot_diskX1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1", "boot_diskXY1"], ++ not_exp_links => ["boot_diskXX1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0", "catch-all"], + }], + rules => < "catch device by * - take 2", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0"], ++ not_exp_links => ["bad"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0"], ++ not_exp_links => ["modem/0-1", "modem/0-2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0"], ++ not_exp_links => ["modem/0-1", "modem/0-2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "whitespace" , ++ exp_links => ["whitespace"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "aaa", ++ exp_links => ["aaa"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "sub/direct/ory/modem" , ++ exp_links => ["sub/direct/ory/modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "first_disk5" , ++ exp_links => ["first_disk5"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , ++ exp_links => ["Major:8:minor:5:kernelnumber:5:id:0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node12345678", ++ exp_links => ["node12345678"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk-ATA-sda" , ++ exp_links => ["disk-ATA-sda"], ++ not_exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "special-device-5" , +- not_exp_name => "not" , ++ exp_links => ["special-device-5"], ++ not_exp_links => ["not"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "newline_removed" , ++ exp_links => ["newline_removed"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "test-0:0:0:0" , ++ exp_links => ["test-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo9" , ++ exp_links => ["foo9"], ++ not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo7", "foo8"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "bar9" , ++ exp_links => ["bar9"], ++ not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo7", "foo8"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo7" , ++ exp_links => ["foo7"], ++ not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo8"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_links => ["foo2"], ++ not_exp_links => ["foo1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_links => ["foo2"], ++ not_exp_links => ["foo1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_links => ["foo2"], ++ not_exp_links => ["foo1", "foo3"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo9" , ++ exp_links => ["my-foo9"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo8" , ++ exp_links => ["my-foo8"], ++ not_exp_links => ["my-foo3", "my-foo4", "my-foo5", "my-foo6", "my-foo7", "my-foo9"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ exp_links => ["Major:8-minor:5-kernelnumber:5-id:0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ exp_links => ["Major:8-minor:5-kernelnumber:5-id:0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "850:0:0:05" , ++ exp_links => ["850:0:0:05"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "855" , ++ exp_links => ["855"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "8550:0:0:0" , ++ exp_links => ["8550:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/virtual/tty/console", +- exp_name => "TTY", ++ exp_links => ["TTY"], ++ not_exp_links => ["foo"], + }], + rules => < [ + { + devpath => "/devices/virtual/tty/console", +- exp_name => "TTY" , ++ exp_links => ["TTY"], ++ not_exp_links => ["foo"], + }], + rules => < [ + { + devpath => "/devices/virtual/tty/console", +- exp_name => "foo" , ++ exp_links => ["foo", "TTY"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "empty" , ++ exp_links => ["empty", "not-something"], ++ not_exp_links => ["something", "not-empty"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "non-existent" , ++ exp_links => ["non-existent", "wrong"], ++ not_exp_links => ["something", "empty", "not-empty", ++ "not-something", "something"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0" , ++ exp_links => ["scsi-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < "/devices/virtual/block/fake!blockdev0", + devnode => "fake/blockdev0", +- exp_name => "is/a/fake/blockdev0" , ++ exp_links => ["is/a/fake/blockdev0"], ++ not_exp_links => ["is/not/a/fake/blockdev0", "modem"], + }], + rules => < "/devices/virtual/block/fake!blockdev0", + devnode => "fake/blockdev0", +- exp_rem_error => "yes", ++ not_exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0"], ++ not_exp_links => ["no-match", "short-id", "not-scsi"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0"], ++ not_exp_links => ["no-match", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-sd", ++ exp_links => ["driver-is-sd"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-ahci", ++ exp_links => ["driver-is-ahci"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ignored", ++ exp_links => ["ignored"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "matched-with-space", ++ exp_links => ["matched-with-space"], ++ not_exp_links => ["wrong-to-ignore"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "1::0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => ":1:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "daemon::0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => ":daemon:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "root:audio:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "::0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_majorminor => "8:0", + }], + rules => < [ + { + devpath => "/devices/virtual/misc/misc-fake1", +- exp_name => "node", ++ exp_links => ["node"], + exp_majorminor => "4095:1", + }], + rules => < [ + { + devpath => "/devices/virtual/misc/misc-fake89999", +- exp_name => "node", ++ exp_links => ["node"], + exp_majorminor => "4095:89999", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink2-ttyACM0", ++ exp_links => ["symlink1-0", "symlink2-ttyACM0", "symlink3-"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "one", +- not_exp_name => " ", ++ exp_links => ["one", "two"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < "symlink with space and var with space, part 1", ++ desc => "symlink with space and var with space", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "first", +- not_exp_name => " ", ++ exp_links => ["first"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "another_symlink", +- not_exp_name => " ", ++ exp_links => ["another_symlink"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem0", ++ exp_links => ["modem0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "second-0" , ++ exp_links => ["first-0", "second-0", "third-0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => ".", ++ exp_links => ["."], + exp_add_error => "yes", + exp_rem_error => "yes", + }], +@@ -1148,7 +1176,7 @@ EOF + devices => [ + { + devpath => "/devices/virtual/tty/tty0", +- exp_name => "link", ++ exp_links => ["link"], + exp_add_error => "yes", + exp_rem_error => "yes", + }], +@@ -1162,7 +1190,7 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink0", ++ exp_links => ["symlink0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink-ttyACM0", ++ exp_links => ["symlink-ttyACM0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "major-166:0", ++ exp_links => ["major-166:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "symlink-0:0:0:0", ++ exp_links => ["symlink-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ exp_links => ["test"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ exp_links => ["test"], ++ not_exp_links => ["symlink", "this"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "this", ++ exp_links => ["test", "this"], ++ not_exp_links => ["symlink"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "test", ++ exp_links => ["test", "this"], ++ not_exp_links => ["symlink"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "166:0", ++ exp_links => ["166:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link1", ++ exp_links => ["link1", "link2"], ++ not_exp_links => ["node"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link4", ++ exp_links => ["link1", "link2", "link3", "link4"], ++ not_exp_links => ["node"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], ++ not_exp_links => ["should_not_match", "should_not_match2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], ++ not_exp_links => ["should_not_match"] + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sda-part-1", ++ exp_links => ["sda-part-1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "start-/dev-end", ++ exp_links => ["start-/dev-end"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "last", ++ exp_links => ["last"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "match", ++ exp_links => ["match", "before"], ++ not_exp_links => ["matches-but-is-negated"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "not-anything", ++ exp_links => ["before", "not-anything"], ++ not_exp_links => ["matches-but-is-negated"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "nonzero-program", ++ exp_links => ["before", "nonzero-program"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true"], ++ not_exp_links => ["bad", "wrong"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true"], ++ not_exp_links => ["bad", "wrong", "no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true", "before"], ++ not_exp_links => ["no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true", "before"], ++ not_exp_links => ["no", "bad"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "part", +- }], ++ exp_links => ["part"], ++ not_exp_links => ["disk"], ++ }, ++ ], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sane", ++ exp_links => ["sane"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "uber", ++ exp_links => ["uber"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "replaced", ++ exp_links => ["replaced"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "serial-354172020305000", ++ exp_links => ["serial-354172020305000"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], ++ not_exp_links => ["not-1-ok", "not-2-ok", "not-3-ok"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], ++ not_exp_links => ["unknown-not-ok"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], + exp_perms => "root:tty:0640", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], + exp_perms => "root:tty:0640", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node-add-me", ++ exp_links => ["node-add-me"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "three", +- not_exp_name => "two", ++ exp_links => ["three"], ++ not_exp_links => ["two", "one"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", +- not_exp_name => "wrong", ++ exp_links => ["right"], ++ not_exp_links => ["wrong"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right", "before"], ++ not_exp_links => ["nomatch"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right"], ++ not_exp_links => ["nomatch", "wrong1", "wrong2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right"], ++ not_exp_links => ["nomatch", "wrong1", "wrong2", "wrong3"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "parent", ++ exp_links => ["parent"], + }], + option => "keep", + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "parentenv-parent_right", ++ exp_links => ["parentenv-parent_right"], + }], + option => "clean", + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ exp_links => ["right"], ++ not_exp_test => ["wrong", "wrong2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ exp_links => ["right"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", +- not_exp_name => "wrong", ++ exp_links => ["right", "link"], ++ not_exp_links => ["wrong"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ exp_links => ["yes"], ++ not_exp_links => ["no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ exp_links => ["yes"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ exp_links => ["yes"], ++ not_exp_links => ["no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "00:16:41:e2:8d:ff", ++ exp_links => ["00:16:41:e2:8d:ff"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "there", ++ exp_links => ["there"], ++ not_exp_links => ["notthere"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ exp_links => ["yes"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "relative", ++ exp_links => ["relative"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found-subdir", ++ exp_links => ["found-subdir"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda-8741C4G-end", ++ exp_links => ["sda-8741C4G-end"], + exp_perms => "0:0:0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", ++ exp_links => ["disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad" , ++ exp_links => ["found"], ++ not_exp_links => ["bad"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + }], + rules => $rules_10k_tags . < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => $rules_10k_tags_continuation . < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + + }], +@@ -2046,7 +2098,7 @@ TAGS=="aaa", SYMLINK+="bad" + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => <{not_exp_name})) { +- if ((-e "$udev_dev/$device->{not_exp_name}") || +- (-l "$udev_dev/$device->{not_exp_name}")) { +- print "nonexistent: error \'$device->{not_exp_name}\' not expected to be there\n"; +- $error++; +- sleep(1); +- } +- } ++sub get_link_target { ++ my ($link) = @_; + +- my $devnode = check_devnode($device); ++ my $cwd = getcwd(); ++ my $dir = "$udev_dev/$link"; ++ my $tgt = readlink("$udev_dev/$link"); ++ $dir =~ s!/[^/]*$!!; ++ $tgt = abs_path("$dir/$tgt"); ++ $tgt =~ s!^$cwd/!!; ++ return $tgt; ++} + +- return if (!defined($device->{exp_name})); ++sub check_link_add { ++ my ($link, $devnode, $err_expected) = @_; + +- my @st = lstat("$udev_dev/$device->{exp_name}"); ++ my @st = lstat("$udev_dev/$link"); + if (-l _) { +- my $cwd = getcwd(); +- my $dir = "$udev_dev/$device->{exp_name}"; +- $dir =~ s!/[^/]*$!!; +- my $tgt = readlink("$udev_dev/$device->{exp_name}"); +- $tgt = abs_path("$dir/$tgt"); +- $tgt =~ s!^$cwd/!!; ++ my $tgt = get_link_target($link); + + if ($tgt ne $devnode) { +- print "symlink $device->{exp_name}: error, found -> $tgt\n"; ++ print "symlink $link: error, found -> $tgt\n"; + $error++; + system("tree", "$udev_dev"); + } else { +- print "symlink $device->{exp_name}: ok\n"; ++ print "symlink $link: ok\n"; + } + } else { +- print "symlink $device->{exp_name}: error"; +- if ($device->{exp_add_error}) { ++ print "symlink $link: error"; ++ if ($err_expected) { + print " as expected\n"; + } else { + print "\n"; +@@ -2276,6 +2322,49 @@ sub check_add { + } + } + ++sub check_link_nonexistent { ++ my ($link, $devnode, $err_expected) = @_; ++ ++ if ((-e "$udev_dev/$link") || (-l "$udev_dev/$link")) { ++ my $tgt = get_link_target($link); ++ ++ if ($tgt ne $devnode) { ++ print "nonexistent: '$link' points to other device (ok)\n"; ++ } else { ++ print "nonexistent: error \'$link\' should not be there"; ++ if ($err_expected) { ++ print " (as expected)\n"; ++ } else { ++ print "\n"; ++ system("tree", "$udev_dev"); ++ print "\n"; ++ $error++; ++ sleep(1); ++ } ++ } ++ } else { ++ print "nonexistent $link: ok\n"; ++ } ++} ++ ++sub check_add { ++ my ($device) = @_; ++ my $devnode = check_devnode($device); ++ ++ if (defined($device->{exp_links})) { ++ foreach my $link (@{$device->{exp_links}}) { ++ check_link_add($link, $devnode, ++ $device->{exp_add_error}); ++ } ++ } ++ if (defined $device->{not_exp_links}) { ++ foreach my $link (@{$device->{not_exp_links}}) { ++ check_link_nonexistent($link, $devnode, ++ $device->{exp_nodev_error}); ++ } ++ } ++} ++ + sub check_remove_devnode { + my ($device) = @_; + my $devnode = get_devnode($device); +@@ -2292,17 +2381,13 @@ sub check_remove_devnode { + } + } + +-sub check_remove { +- my ($device) = @_; ++sub check_link_remove { ++ my ($link, $err_expected) = @_; + +- check_remove_devnode($device); +- +- return if (!defined($device->{exp_name})); +- +- if ((-e "$udev_dev/$device->{exp_name}") || +- (-l "$udev_dev/$device->{exp_name}")) { +- print "remove $device->{exp_name}: error"; +- if ($device->{exp_rem_error}) { ++ if ((-e "$udev_dev/$link") || ++ (-l "$udev_dev/$link")) { ++ print "remove $link: error"; ++ if ($err_expected) { + print " as expected\n"; + } else { + print "\n"; +@@ -2312,7 +2397,19 @@ sub check_remove { + sleep(1); + } + } else { +- print "remove $device->{exp_name}: ok\n"; ++ print "remove $link: ok\n"; ++ } ++} ++ ++sub check_remove { ++ my ($device) = @_; ++ ++ check_remove_devnode($device); ++ ++ return if (!defined($device->{exp_links})); ++ ++ foreach my $link (@{$device->{exp_links}}) { ++ check_link_remove($link, $device->{exp_rem_error}); + } + } + diff --git a/SOURCES/0531-test-udev-test.pl-fix-wrong-test-descriptions.patch b/SOURCES/0531-test-udev-test.pl-fix-wrong-test-descriptions.patch new file mode 100644 index 0000000..9c2ee94 --- /dev/null +++ b/SOURCES/0531-test-udev-test.pl-fix-wrong-test-descriptions.patch @@ -0,0 +1,83 @@ +From 0e0b90ffcf0731865846bfa2754a809cc2b8c53e Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 17:57:47 +0200 +Subject: [PATCH] test/udev-test.pl: fix wrong test descriptions + +udev hasn't supported renaming device nodes for some time. + +(cherry picked from commit 46bc71b2b73f8a1e27dc5e142730e9877dd05e3e) + +Related: #1642728 +--- + test/udev-test.pl | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index f5edecefd0..d5d0e130e3 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -212,7 +212,7 @@ KERNEL=="ttyACM[0-9]*", SYMLINK+="modem/%n" + EOF + }, + { +- desc => "replace kernel name", ++ desc => "don't replace kernel name", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -223,7 +223,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle comment lines in config file (and replace kernel name)", ++ desc => "Handle comment lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -236,7 +236,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle comment lines in config file with whitespace (and replace kernel name)", ++ desc => "Handle comment lines in config file with whitespace (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -249,7 +249,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle whitespace only lines (and replace kernel name)", ++ desc => "Handle whitespace only lines (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -267,7 +267,7 @@ KERNEL=="ttyACM0", SYMLINK+="whitespace" + EOF + }, + { +- desc => "Handle empty lines in config file (and replace kernel name)", ++ desc => "Handle empty lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -280,7 +280,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle backslashed multi lines in config file (and replace kernel name)", ++ desc => "Handle backslashed multi lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -303,8 +303,9 @@ EOF + KERNEL=="ttyACM0", PROGRAM=="/bin/echo -e \\101", RESULT=="A", SYMLINK+="aaa" + EOF + }, ++ # 20 + { +- desc => "Handle stupid backslashed multi lines in config file (and replace kernel name)", ++ desc => "Handle stupid backslashed multi lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", diff --git a/SOURCES/0532-test-udev-test.pl-last_rule-is-unsupported.patch b/SOURCES/0532-test-udev-test.pl-last_rule-is-unsupported.patch new file mode 100644 index 0000000..72021fb --- /dev/null +++ b/SOURCES/0532-test-udev-test.pl-last_rule-is-unsupported.patch @@ -0,0 +1,35 @@ +From 2d0b828715e67f7accda6f73481deb74febebcb6 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 18:08:18 +0200 +Subject: [PATCH] test/udev-test.pl: last_rule is unsupported + +the "last_rule" option hasn't been supported for some time. +Therefore this test fails if a "not_exp_links" attribute is added, +as it should be. Mark it appropriately. + +(cherry picked from commit 17cce031531a5d3f38a27374c99d1bdba5959dbd) + +Related: #1642728 +--- + test/udev-test.pl | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index d5d0e130e3..a9c2dd95f1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1373,11 +1373,14 @@ SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="start-%r-end" + EOF + }, + { ++ # This is not supported any more + desc => "last_rule option", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_links => ["last"], ++ not_exp_links => ["very-last"], ++ exp_nodev_error => "yes", + }], + rules => < +Date: Tue, 24 Apr 2018 18:09:50 +0200 +Subject: [PATCH] test/udev-test.pl: Make some tests a little harder + +Add some rules that make it a bit harder to pass, mainly the +non-existence checks. + +(cherry picked from commit 06d4d4e24e7d0b51120b165e540d278842e8b1a3) + +Related: #1642728 +--- + test/udev-test.pl | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a9c2dd95f1..7465b5859e 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1358,7 +1358,7 @@ EOF + exp_links => ["sda-part-1"], + }], + rules => < ["part"], + not_exp_links => ["disk"], + }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_links => ["disk"], ++ not_exp_links => ["part"], ++ }, + ], + rules => < < < "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_perms => "1:1:0400", +- exp_rem_error => "yes", + }], + rules => < +Date: Tue, 24 Apr 2018 18:16:59 +0200 +Subject: [PATCH] test/udev-test.pl: remove bogus rules from magic subsys test + +These rules have survived from an ancient version of the code +and save no purpose any more. + +(cherry picked from commit 86634df43b715f3f77c7de73a3ef6566e5cdf571) + +Related: #1642728 +--- + test/udev-test.pl | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 7465b5859e..6928439d14 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2017,8 +2017,6 @@ EOF + exp_perms => "0:0:0600", + }], + rules => < +Date: Tue, 24 Apr 2018 18:27:25 +0200 +Subject: [PATCH] test/udev-test.pl: merge "space and var with space" tests + +As we can check multiple links in a single test now, these 3 +tests can be merged into one. + +(cherry picked from commit 2084fe0d3290c525ecb9faa07d07c3abc2488e59) + +Related: #1642728 +--- + test/udev-test.pl | 31 +++---------------------------- + 1 file changed, 3 insertions(+), 28 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 6928439d14..880a73b10b 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1103,34 +1103,9 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_links => ["first"], +- not_exp_links => [" "], +- }], +- rules => < "symlink with space and var with space, part 2", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_links => ["name-one_two_three-end"], +- not_exp_links => [" "], +- }], +- rules => < "symlink with space and var with space, part 3", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_links => ["another_symlink"], +- not_exp_links => [" "], ++ exp_links => ["first", "name-one_two_three-end", ++ "another_symlink", "a", "b", "c"], ++ not_exp_links => [" "], + }], + rules => < +Date: Tue, 24 Apr 2018 18:30:09 +0200 +Subject: [PATCH] test/udev-test.pl: merge import parent tests into one + +As we can test multiple devices and multiple links per device +in one test now, these two tests can be merged into one. + +(cherry picked from commit a96cd21d31cb7af211862768e133b50b085634e7) + +Related: #1642728 +--- + test/udev-test.pl | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 880a73b10b..0344d2e89c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1781,28 +1781,21 @@ TAGS=="aaa||bbb||ccc", SYMLINK+="bad" + EOF + }, + { +- desc => "IMPORT parent test sequence 1/2 (keep)", ++ desc => "IMPORT parent test", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_links => ["parent"], +- }], +- option => "keep", +- rules => < "IMPORT parent test sequence 2/2 (keep)", +- devices => [ ++ }, + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_links => ["parentenv-parent_right"], + }], +- option => "clean", ++ sleep_us => 500000, # Serialized! We need to sleep here after adding sda + rules => < +Date: Tue, 24 Apr 2018 20:55:01 +0200 +Subject: [PATCH] test/udev-test.pl: count "good" results + +This is helpful to catch possible regressions in the test. +Also, don't count wait() errors, they are likely not udev errors. + +(cherry picked from commit b95c43982ab7d0253b552ad56cffb3d68fcbb4f6) + +Related: #1642728 +--- + test/udev-test.pl | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 0344d2e89c..813be70739 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2114,6 +2114,7 @@ sub udev { + } + + my $error = 0; ++my $good = 0; + + sub permissions_test { + my($rules, $uid, $gid, $mode) = @_; +@@ -2144,6 +2145,7 @@ sub permissions_test { + } + if ($wrong == 0) { + print "permissions: ok\n"; ++ $good++; + } else { + printf " expected permissions are: %s:%s:%#o\n", $1, $2, oct($3); + printf " created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; +@@ -2169,6 +2171,7 @@ sub major_minor_test { + } + if ($wrong == 0) { + print "major:minor: ok\n"; ++ $good++; + } else { + printf " expected major:minor is: %i:%i\n", $1, $2; + printf " created major:minor is : %i:%i\n", $major, $minor; +@@ -2254,6 +2257,7 @@ sub check_devnode { + major_minor_test($device, $rdev); + } + print "add $devnode: ok\n"; ++ $good++; + return $devnode; + } + +@@ -2282,11 +2286,13 @@ sub check_link_add { + system("tree", "$udev_dev"); + } else { + print "symlink $link: ok\n"; ++ $good++; + } + } else { + print "symlink $link: error"; + if ($err_expected) { + print " as expected\n"; ++ $good++; + } else { + print "\n"; + system("tree", "$udev_dev"); +@@ -2305,10 +2311,12 @@ sub check_link_nonexistent { + + if ($tgt ne $devnode) { + print "nonexistent: '$link' points to other device (ok)\n"; ++ $good++; + } else { + print "nonexistent: error \'$link\' should not be there"; + if ($err_expected) { + print " (as expected)\n"; ++ $good++; + } else { + print "\n"; + system("tree", "$udev_dev"); +@@ -2319,6 +2327,7 @@ sub check_link_nonexistent { + } + } else { + print "nonexistent $link: ok\n"; ++ $good++; + } + } + +@@ -2353,6 +2362,7 @@ sub check_remove_devnode { + sleep(1); + } else { + print "remove $devnode: ok\n"; ++ $good++; + } + } + +@@ -2364,6 +2374,7 @@ sub check_link_remove { + print "remove $link: error"; + if ($err_expected) { + print " as expected\n"; ++ $good++; + } else { + print "\n"; + system("tree", "$udev_dev"); +@@ -2373,6 +2384,7 @@ sub check_link_remove { + } + } else { + print "remove $link: ok\n"; ++ $good++; + } + } + +@@ -2432,7 +2444,6 @@ sub fork_and_run_udev { + $pid = waitpid($dev->{pid}, 0); + if ($pid == -1) { + print "error waiting for pid dev->{pid}\n"; +- $error += 1; + } + if (WIFEXITED($?)) { + $rc = WEXITSTATUS($?); +@@ -2440,6 +2451,8 @@ sub fork_and_run_udev { + if ($rc) { + print "$udev_bin $action for $dev->{devpath} failed with code $rc\n"; + $error += 1; ++ } else { ++ $good++; + } + } + } +@@ -2549,7 +2562,7 @@ if ($list[0]) { + } + + $sema->remove; +-print "$error errors occurred\n\n"; ++print "$error errors occurred. $good good results.\n\n"; + + cleanup(); + diff --git a/SOURCES/0538-tests-udev-test.pl-add-multiple-device-test.patch b/SOURCES/0538-tests-udev-test.pl-add-multiple-device-test.patch new file mode 100644 index 0000000..e01add4 --- /dev/null +++ b/SOURCES/0538-tests-udev-test.pl-add-multiple-device-test.patch @@ -0,0 +1,199 @@ +From 8ab9d11b925e7f39b350ce69a1e28752de411b35 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 22:04:55 +0200 +Subject: [PATCH] tests/udev-test.pl: add multiple device test + +Add 4 new tests using multiple devices. Number 2-4 use many +devices claiming the same symlink, where only one device has +a higher priority thatn the others. They fail sporadically with +the current code, if a race condition causes the symlink to point +to the wrong device. Test 4 is like test 2 with sleeps in between, +it's much less likely to fail. + +(cherry picked from commit 4a0ec82daf32446519e1d86329bb802325b82104) + +Related: #1642728 +--- + test/udev-test.pl | 169 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 169 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 813be70739..d964c664b6 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2085,6 +2085,175 @@ KERNEL=="sda", TAG+="aaa" \\ + KERNEL=="sdb", TAG+="bbb" + TAGS=="foo", SYMLINK+="found" + TAGS=="aaa", SYMLINK+="bad" ++EOF ++ }, ++ { ++ desc => "multiple devices", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ exp_links => ["part-10"], ++ }, ++ ], ++ rules => < "multiple devices, same link name, positive prio", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ not_exp_links => ["partition"], ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7", "partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ not_exp_links => ["partition"], ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ not_exp_links => ["partition"], ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ not_exp_links => ["partition"], ++ exp_links => ["part-10"], ++ }, ++ ], ++ rules => < "multiple devices, same link name, negative prio", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ not_exp_links => ["partition"], ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7", "partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ not_exp_links => ["partition"], ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ not_exp_links => ["partition"], ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ not_exp_links => ["partition"], ++ exp_links => ["part-10"], ++ }, ++ ], ++ rules => < "multiple devices, same link name, positive prio, sleep", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ not_exp_links => ["partition"], ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7", "partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ not_exp_links => ["partition"], ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ not_exp_links => ["partition"], ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ not_exp_links => ["partition"], ++ exp_links => ["part-10"], ++ }, ++ ], ++ sleep_us => 10000, ++ rules => < +Date: Tue, 24 Apr 2018 22:24:43 +0200 +Subject: [PATCH] test/udev-test.pl: add repeat count + +for easier reproduction of sporadic test failures. + +(cherry picked from commit 2ab0a8d00bc48d3531e953d938db889d8a932d65) + +Related: #1642728 +--- + test/udev-test.pl | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index d964c664b6..8b1ab3c06c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2125,6 +2125,7 @@ EOF + }, + { + desc => "multiple devices, same link name, positive prio", ++ repeat => 100, + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +@@ -2635,6 +2636,7 @@ sub run_test { + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); + ++ REPEAT: + fork_and_run_udev("add", $rules, $sema); + + foreach my $dev (@devices) { +@@ -2653,6 +2655,9 @@ sub run_test { + } + + print "\n"; ++ if (defined($rules->{repeat}) && --($rules->{repeat}) > 0) { ++ goto REPEAT; ++ } + + if (defined($rules->{option}) && $rules->{option} eq "clean") { + udev_setup(); diff --git a/SOURCES/0540-test-udev-test.pl-generator-for-large-list-of-block-.patch b/SOURCES/0540-test-udev-test.pl-generator-for-large-list-of-block-.patch new file mode 100644 index 0000000..02e407d --- /dev/null +++ b/SOURCES/0540-test-udev-test.pl-generator-for-large-list-of-block-.patch @@ -0,0 +1,101 @@ +From 6c3191e979165700f98903b76621c214186a110c Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 25 Apr 2018 09:54:26 +0200 +Subject: [PATCH] test/udev-test.pl: generator for large list of block devices + +Manually listing all devices in the test definition becomes cumbersome with +lots of devices. Add a function that scans on all block devices in +the test sysfs and generates a list of devices to test. + +(cherry picked from commit eb44d715ebee2fe11288433b99f8e1dc5fdac84a) + +Related: #1642728 +--- + test/udev-test.pl | 60 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 59 insertions(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 8b1ab3c06c..2866fdb77a 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -50,6 +50,50 @@ for (my $i = 1; $i < 10000; ++$i) { + } + $rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; + ++# Create a device list with all block devices under /sys ++# (except virtual devices and cd-roms) ++# the optional argument exp_func returns expected and non-expected ++# symlinks for the device. ++sub all_block_devs { ++ my ($exp_func) = @_; ++ my @devices; ++ ++ foreach my $bd (glob "$udev_sys/dev/block/*") { ++ my $tgt = readlink($bd); ++ my ($exp, $notexp) = (undef, undef); ++ ++ next if ($tgt =~ m!/virtual/! || $tgt =~ m!/sr[0-9]*$!); ++ ++ $tgt =~ s!^\.\./\.\.!!; ++ ($exp, $notexp) = $exp_func->($tgt) if defined($exp_func); ++ my $device = { ++ devpath => $tgt, ++ exp_links => $exp, ++ not_exp_links => $notexp, ++ }; ++ push(@devices, $device); ++ } ++ return \@devices; ++} ++ ++# This generator returns a suitable exp_func for use with ++# all_block_devs(). ++sub expect_for_some { ++ my ($pattern, $links, $donot) = @_; ++ my $_expect = sub { ++ my ($name) = @_; ++ ++ if ($name =~ /$pattern/) { ++ return ($links, undef); ++ } elsif ($donot) { ++ return (undef, $links); ++ } else { ++ return (undef, undef); ++ } ++ }; ++ return $_expect; ++} ++ + my @tests = ( + { + desc => "no rules", +@@ -2257,6 +2301,15 @@ SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partitio + KERNEL=="*7", OPTIONS+="link_priority=10" + EOF + }, ++ { ++ desc => 'all_block_devs', ++ generator => expect_for_some("\\/sda6\$", ["blockdev"]), ++ repeat => 10, ++ rules => <{devices}}; ++ my @devices; ++ ++ if (!defined $rules->{devices}) { ++ $rules->{devices} = all_block_devs($rules->{generator}); ++ } ++ @devices = @{$rules->{devices}}; + + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); diff --git a/SOURCES/0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch b/SOURCES/0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch new file mode 100644 index 0000000..fbe9d4b --- /dev/null +++ b/SOURCES/0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch @@ -0,0 +1,29 @@ +From 453df9eb2bbfa34f3e4b78e917812f0ac6958010 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 26 Apr 2018 13:25:11 +0200 +Subject: [PATCH] test/udev-test.pl: suppress umount error message at startup + +umount emits an error message "no mount point specified" if the +tmpfs isn't mounted yet, which is the normal case. +Suppress that by redirecting stderr. + +(cherry picked from commit f1cb0860549e775be5f91237b5a3b97698dd14dd) + +Related: #1642728 +--- + test/udev-test.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 2866fdb77a..33a76ad292 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2405,7 +2405,7 @@ sub major_minor_test { + } + + sub udev_setup { +- system("umount", $udev_tmpfs); ++ system("umount \"$udev_tmpfs\" 2>/dev/null"); + rmdir($udev_tmpfs); + mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; + diff --git a/SOURCES/0542-test-udev_test.pl-add-expected-good-count.patch b/SOURCES/0542-test-udev_test.pl-add-expected-good-count.patch new file mode 100644 index 0000000..d1f61ca --- /dev/null +++ b/SOURCES/0542-test-udev_test.pl-add-expected-good-count.patch @@ -0,0 +1,78 @@ +From e0cee95e0cc401ce120a1b56cdb7a8b9afbd6bcf Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 26 Apr 2018 14:07:27 +0200 +Subject: [PATCH] test/udev_test.pl: add "expected good" count + +Since 'test/udev-test.pl: count "good" results', we know how many +checks succeeded. Add an "expected good" count to make that number +more meaningful. + +(cherry picked from commit cbeb23d863d540408cd1fb274d78213f59639df2) + +Related: #1642728 +--- + test/udev-test.pl | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 33a76ad292..cf6ca6b80c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2338,6 +2338,7 @@ sub udev { + + my $error = 0; + my $good = 0; ++my $exp_good = 0; + + sub permissions_test { + my($rules, $uid, $gid, $mode) = @_; +@@ -2685,12 +2686,27 @@ sub run_test { + my ($rules, $number, $sema) = @_; + my $rc; + my @devices; ++ my $ntests; ++ my $cur_good = $good; ++ my $cur_error = $error; + + if (!defined $rules->{devices}) { + $rules->{devices} = all_block_devs($rules->{generator}); + } + @devices = @{$rules->{devices}}; ++ # For each device: exit status and devnode test for add & remove ++ $ntests += 4 * ($#devices + 1); + ++ foreach my $dev (@devices) { ++ $ntests += 2 * ($#{$dev->{exp_links}} + 1) ++ + ($#{$dev->{not_exp_links}} + 1) ++ + (defined $dev->{exp_perms} ? 1 : 0) ++ + (defined $dev->{exp_majorminor} ? 1 : 0); ++ } ++ if (defined $rules->{repeat}) { ++ $ntests *= $rules->{repeat}; ++ } ++ $exp_good += $ntests; + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); + +@@ -2712,10 +2728,11 @@ sub run_test { + check_remove($dev); + } + +- print "\n"; + if (defined($rules->{repeat}) && --($rules->{repeat}) > 0) { + goto REPEAT; + } ++ printf "TEST $number: errors: %d good: %d/%d\n\n", $error-$cur_error, ++ $good-$cur_good, $ntests; + + if (defined($rules->{option}) && $rules->{option} eq "clean") { + udev_setup(); +@@ -2794,7 +2811,7 @@ if ($list[0]) { + } + + $sema->remove; +-print "$error errors occurred. $good good results.\n\n"; ++print "$error errors occurred. $good/$exp_good good results.\n\n"; + + cleanup(); + diff --git a/SOURCES/0543-test-udev-test-gracefully-exit-when-imports-fail.patch b/SOURCES/0543-test-udev-test-gracefully-exit-when-imports-fail.patch new file mode 100644 index 0000000..3e5c348 --- /dev/null +++ b/SOURCES/0543-test-udev-test-gracefully-exit-when-imports-fail.patch @@ -0,0 +1,48 @@ +From 2e50a00f6930f1c65ca804b78f4a853e2ae2d2c0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 17 Nov 2020 17:13:31 +0100 +Subject: [PATCH] test/udev-test: gracefully exit when imports fail + +In Fedora rawhide various perl modules are now available as separate +packages that are not pulled in by dependencies. If we don't have some +package, skip the tests. + +This ugly code is apparently the way to do conditional imports: +https://www.cs.ait.ac.th/~on/O/oreilly/perl/cookbook/ch12_03.htm. + +(cherry picked from commit d40763838278246e2073d15ca927ee700e583afc) + +Related: #1642728 +--- + test/udev-test.pl | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index cf6ca6b80c..5b1e33504e 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -18,11 +18,19 @@ + + use warnings; + use strict; +-use POSIX qw(WIFEXITED WEXITSTATUS); +-use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); +-use IPC::Semaphore; +-use Time::HiRes qw(usleep); +-use Cwd qw(getcwd abs_path); ++ ++BEGIN { ++ my $EXIT_TEST_SKIP = 77; ++ ++ unless (eval "use POSIX qw(WIFEXITED WEXITSTATUS); ++ use Cwd qw(getcwd abs_path); ++ use IPC::Semaphore; ++ use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); ++ use Time::HiRes qw(usleep); 1") { ++ warn "Failed to import dependencies, skipping the test: $@"; ++ exit($EXIT_TEST_SKIP); ++ } ++} + + my $udev_bin = "./test-udev"; + my $valgrind = 0; diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index b4ce6a3..a3c4fe1 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 43%{?dist} +Release: 44%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -545,6 +545,54 @@ Patch0492: 0492-introduce-setsockopt_int-helper.patch Patch0493: 0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch Patch0494: 0494-core-add-new-PassPacketInfo-socket-unit-property.patch Patch0495: 0495-resolved-tweak-cmsg-calculation.patch +Patch0496: 0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch +Patch0497: 0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch +Patch0498: 0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch +Patch0499: 0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch +Patch0500: 0500-use-link-to-RHEL-8-docs.patch +Patch0501: 0501-cgroup-Also-set-blkio.bfq.weight.patch +Patch0502: 0502-units-make-sure-initrd-cleanup.service-terminates-be.patch +Patch0503: 0503-core-reload-SELinux-label-cache-on-daemon-reload.patch +Patch0504: 0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch +Patch0505: 0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch +Patch0506: 0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch +Patch0507: 0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch +Patch0508: 0508-udev-make-algorithm-that-selects-highest-priority-de.patch +Patch0509: 0509-test-create-dev-null-in-test-udev.pl.patch +Patch0510: 0510-test-missing-die.patch +Patch0511: 0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch +Patch0512: 0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch +Patch0513: 0513-udev-test-fix-test-skip-condition.patch +Patch0514: 0514-udev-test-fix-missing-directory-test-run.patch +Patch0515: 0515-udev-test-check-if-permitted-to-create-block-device-.patch +Patch0516: 0516-test-udev-add-a-testcase-of-too-long-line.patch +Patch0517: 0517-test-udev-use-proper-semantics-for-too-long-line-wit.patch +Patch0518: 0518-test-udev-add-more-tests-for-line-continuations-and-.patch +Patch0519: 0519-test-udev-add-more-tests-for-line-continuation.patch +Patch0520: 0520-test-udev-fix-alignment-and-drop-unnecessary-white-s.patch +Patch0521: 0521-test-udev-test.pl-cleanup-if-skipping-test.patch +Patch0522: 0522-test-add-test-cases-for-empty-string-match.patch +Patch0523: 0523-test-add-test-case-for-multi-matches-when-use.patch +Patch0524: 0524-udev-test-do-not-rely-on-mail-group-being-defined.patch +Patch0525: 0525-test-udev-test.pl-allow-multiple-devices-per-test.patch +Patch0526: 0526-test-udev-test.pl-create-rules-only-once.patch +Patch0527: 0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch +Patch0528: 0528-test-udev-test.pl-use-computed-devnode-name.patch +Patch0529: 0529-test-udev-test.pl-test-correctness-of-symlink-target.patch +Patch0530: 0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch +Patch0531: 0531-test-udev-test.pl-fix-wrong-test-descriptions.patch +Patch0532: 0532-test-udev-test.pl-last_rule-is-unsupported.patch +Patch0533: 0533-test-udev-test.pl-Make-some-tests-a-little-harder.patch +Patch0534: 0534-test-udev-test.pl-remove-bogus-rules-from-magic-subs.patch +Patch0535: 0535-test-udev-test.pl-merge-space-and-var-with-space-tes.patch +Patch0536: 0536-test-udev-test.pl-merge-import-parent-tests-into-one.patch +Patch0537: 0537-test-udev-test.pl-count-good-results.patch +Patch0538: 0538-tests-udev-test.pl-add-multiple-device-test.patch +Patch0539: 0539-test-udev-test.pl-add-repeat-count.patch +Patch0540: 0540-test-udev-test.pl-generator-for-large-list-of-block-.patch +Patch0541: 0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch +Patch0542: 0542-test-udev_test.pl-add-expected-good-count.patch +Patch0543: 0543-test-udev-test-gracefully-exit-when-imports-fail.patch %ifarch %{ix86} x86_64 aarch64 @@ -1173,6 +1221,56 @@ fi %files tests -f .file-list-tests %changelog +* Thu Jan 28 2021 systemd maintenance team - 239-44 +- ci: PowerTools repo was renamed to powertools in RHEL 8.3 (#1871827) +- ci: use quay.io instead of Docker Hub to avoid rate limits (#1871827) +- ci: move jobs from Travis CI to GH Actions (#1871827) +- unit: make UNIT() cast function deal with NULL pointers (#1871827) +- use link to RHEL-8 docs (#1623116) +- cgroup: Also set blkio.bfq.weight (#1657810) +- units: make sure initrd-cleanup.service terminates before switching to rootfs (#1657810) +- core: reload SELinux label cache on daemon-reload (#1888912) +- selinux: introduce mac_selinux_create_file_prepare_at() (#1888912) +- selinux: add trigger for policy reload to refresh internal selabel cache (#1888912) +- udev/net_id: give RHEL-8.4 naming scheme a name (#1827462) +- basic/stat-util: make mtime check stricter and use entire timestamp (#1642728) +- udev: make algorithm that selects highest priority devlink less susceptible to race conditions (#1642728) +- test: create /dev/null in test-udev.pl (#1642728) +- test: missing "die" (#1642728) +- udev-test: remove a check for whether the test is run in a container (#1642728) +- udev-test: skip the test only if it can't setup its environment (#1642728) +- udev-test: fix test skip condition (#1642728) +- udev-test: fix missing directory test/run (#1642728) +- udev-test: check if permitted to create block device nodes (#1642728) +- test-udev: add a testcase of too long line (#1642728) +- test-udev: use proper semantics for too long line with continuation (#1642728) +- test-udev: add more tests for line continuations and comments (#1642728) +- test-udev: add more tests for line continuation (#1642728) +- test-udev: fix alignment and drop unnecessary white spaces (#1642728) +- test/udev-test.pl: cleanup if skipping test (#1642728) +- test: add test cases for empty string match (#1642728) +- test: add test case for multi matches when use "||" (#1642728) +- udev-test: do not rely on "mail" group being defined (#1642728) +- test/udev-test.pl: allow multiple devices per test (#1642728) +- test/udev-test.pl: create rules only once (#1642728) +- test/udev-test.pl: allow concurrent additions and removals (#1642728) +- test/udev-test.pl: use computed devnode name (#1642728) +- test/udev-test.pl: test correctness of symlink targets (#1642728) +- test/udev-test.pl: allow checking multiple symlinks (#1642728) +- test/udev-test.pl: fix wrong test descriptions (#1642728) +- test/udev-test.pl: last_rule is unsupported (#1642728) +- test/udev-test.pl: Make some tests a little harder (#1642728) +- test/udev-test.pl: remove bogus rules from magic subsys test (#1642728) +- test/udev-test.pl: merge "space and var with space" tests (#1642728) +- test/udev-test.pl: merge import parent tests into one (#1642728) +- test/udev-test.pl: count "good" results (#1642728) +- tests/udev-test.pl: add multiple device test (#1642728) +- test/udev-test.pl: add repeat count (#1642728) +- test/udev-test.pl: generator for large list of block devices (#1642728) +- test/udev-test.pl: suppress umount error message at startup (#1642728) +- test/udev_test.pl: add "expected good" count (#1642728) +- test/udev-test: gracefully exit when imports fail (#1642728) + * Thu Nov 26 2020 systemd maintenance team - 239-43 - man: mention System Administrator's Guide in systemctl manpage (#1623116) - udev: introduce udev net_id "naming schemes" (#1827462)