Compare commits
No commits in common. "c9" and "c8" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/LVM2.2.03.24.tgz
|
SOURCES/LVM2.2.03.14.tgz
|
||||||
|
@ -1 +1 @@
|
|||||||
7c2dcac585dc89dbd0070216262a3a8446e7f222 SOURCES/LVM2.2.03.24.tgz
|
e5d4364e823d72b9a08b3aecc13cd677972830f0 SOURCES/LVM2.2.03.14.tgz
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
From 645992ca32dfd41b07997a97b2aef81563ad6f02 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 12:12:06 +0200
|
|
||||||
Subject: [PATCH 1/7] RHEL9
|
|
||||||
|
|
||||||
---
|
|
||||||
VERSION | 2 +-
|
|
||||||
VERSION_DM | 2 +-
|
|
||||||
WHATS_NEW | 4 ++++
|
|
||||||
WHATS_NEW_DM | 4 ++++
|
|
||||||
doc/release-notes/2.03.24.mdwn | 8 ++------
|
|
||||||
5 files changed, 12 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/VERSION b/VERSION
|
|
||||||
index c41928e80..794c58868 100644
|
|
||||||
--- a/VERSION
|
|
||||||
+++ b/VERSION
|
|
||||||
@@ -1 +1 @@
|
|
||||||
-2.03.24(2) (2024-05-16)
|
|
||||||
+2.03.24(2)-RHEL9 (2024-05-16)
|
|
||||||
diff --git a/VERSION_DM b/VERSION_DM
|
|
||||||
index 63629f72c..8dea6c328 100644
|
|
||||||
--- a/VERSION_DM
|
|
||||||
+++ b/VERSION_DM
|
|
||||||
@@ -1 +1 @@
|
|
||||||
-1.02.198 (2024-05-16)
|
|
||||||
+1.02.198-RHEL9 (2024-05-16)
|
|
||||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
|
||||||
index 1c5f4b223..c7de3914a 100644
|
|
||||||
--- a/WHATS_NEW
|
|
||||||
+++ b/WHATS_NEW
|
|
||||||
@@ -1,3 +1,6 @@
|
|
||||||
+Version 2.03.25 -
|
|
||||||
+==================
|
|
||||||
+
|
|
||||||
Version 2.03.24 - 16th May 2024
|
|
||||||
===============================
|
|
||||||
Lvconvert supports VDO options for thin-pool with vdo conversion.
|
|
||||||
@@ -5450,3 +5453,4 @@ Display output. Some metadata information cannot yet be displayed.
|
|
||||||
Recovery tools to salvage "lost" metadata directly from the disks:
|
|
||||||
but we hope the new format will mean such tools are hardly ever needed!
|
|
||||||
|
|
||||||
+
|
|
||||||
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
|
||||||
index b1508f08f..a2277c53b 100644
|
|
||||||
--- a/WHATS_NEW_DM
|
|
||||||
+++ b/WHATS_NEW_DM
|
|
||||||
@@ -1,3 +1,6 @@
|
|
||||||
+Version 1.02.199 -
|
|
||||||
+===================
|
|
||||||
+
|
|
||||||
Version 1.02.198 - 16th May 2024
|
|
||||||
================================
|
|
||||||
Fix static only compilation of libdevmapper.a and dmsetup tool.
|
|
||||||
@@ -1554,3 +1557,4 @@ Version 1.00.08 - 27 Feb 2004
|
|
||||||
Updated README/INSTALL to reflect move to sources.redhat.com.
|
|
||||||
Updated autoconf files to 2003-06-17.
|
|
||||||
|
|
||||||
+
|
|
||||||
diff --git a/doc/release-notes/2.03.24.mdwn b/doc/release-notes/2.03.24.mdwn
|
|
||||||
index 71aa8add7..4d2c57497 100644
|
|
||||||
--- a/doc/release-notes/2.03.24.mdwn
|
|
||||||
+++ b/doc/release-notes/2.03.24.mdwn
|
|
||||||
@@ -72,9 +72,5 @@ Also few more minor improvements:
|
|
||||||
|
|
||||||
"""]]
|
|
||||||
|
|
||||||
-<!-- remove the pending tag on release, remove draft tag once editing is complete -->
|
|
||||||
-[[!tag draft pending]]
|
|
||||||
-<!--
|
|
||||||
-For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
|
|
||||||
-\[[!meta date="Tue Nov 21 14:26:07 2023 +0100"]]
|
|
||||||
--->
|
|
||||||
+[[!tag]]
|
|
||||||
+[[meta date="Thu May 16 12:12:06 2024 +0200"]]
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
545
SOURCES/0001-Revert-new-udev-autoactivation.patch
Normal file
545
SOURCES/0001-Revert-new-udev-autoactivation.patch
Normal file
@ -0,0 +1,545 @@
|
|||||||
|
From 63c4458aaf67d114c677baf657a7e9e43440f349 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 20 Dec 2021 14:22:02 -0600
|
||||||
|
Subject: [PATCH 01/54] Revert "new udev autoactivation"
|
||||||
|
|
||||||
|
This reverts commit 67722b312390cdab29c076c912e14bd739c5c0f6.
|
||||||
|
---
|
||||||
|
scripts/Makefile.in | 1 +
|
||||||
|
test/shell/udev-pvscan-vgchange.sh | 403 -----------------------------
|
||||||
|
udev/69-dm-lvm.rules.in | 87 -------
|
||||||
|
udev/Makefile.in | 2 +-
|
||||||
|
5 files changed, 4 insertions(+), 492 deletions(-)
|
||||||
|
delete mode 100644 test/shell/udev-pvscan-vgchange.sh
|
||||||
|
delete mode 100644 udev/69-dm-lvm.rules.in
|
||||||
|
|
||||||
|
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
|
||||||
|
index 0d7f45680..ee0acb6f6 100644
|
||||||
|
--- a/scripts/Makefile.in
|
||||||
|
+++ b/scripts/Makefile.in
|
||||||
|
@@ -92,6 +92,7 @@ install_systemd_generators:
|
||||||
|
install_systemd_units: install_dbus_service
|
||||||
|
@echo " [INSTALL] systemd_units"
|
||||||
|
$(Q) $(INSTALL_DIR) $(systemd_unit_dir)
|
||||||
|
+ $(Q) $(INSTALL_DATA) lvm2-pvscan.service $(systemd_unit_dir)/lvm2-pvscan@.service
|
||||||
|
ifeq ("@BUILD_DMEVENTD@", "yes")
|
||||||
|
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.socket $(systemd_unit_dir)/dm-event.socket
|
||||||
|
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.service $(systemd_unit_dir)/dm-event.service
|
||||||
|
diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh
|
||||||
|
deleted file mode 100644
|
||||||
|
index c81acf0ce..000000000
|
||||||
|
--- a/test/shell/udev-pvscan-vgchange.sh
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,403 +0,0 @@
|
||||||
|
-#!/usr/bin/env bash
|
||||||
|
-
|
||||||
|
-# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
|
||||||
|
-#
|
||||||
|
-# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
-# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
-# of the GNU General Public License v.2.
|
||||||
|
-#
|
||||||
|
-# You should have received a copy of the GNU General Public License
|
||||||
|
-# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
-
|
||||||
|
-test_description='udev rule and systemd unit run vgchange'
|
||||||
|
-
|
||||||
|
-SKIP_WITH_LVMPOLLD=1
|
||||||
|
-SKIP_WITH_LVMLOCKD=1
|
||||||
|
-
|
||||||
|
-. lib/inittest
|
||||||
|
-
|
||||||
|
-#
|
||||||
|
-# $ cat /tmp/devs
|
||||||
|
-# /dev/sdb
|
||||||
|
-# /dev/sdc
|
||||||
|
-# /dev/sdd
|
||||||
|
-#
|
||||||
|
-# Specify this file as LVM_TEST_DEVICE_LIST=/tmp/devs
|
||||||
|
-# when running the test.
|
||||||
|
-#
|
||||||
|
-# This test will wipe these devices.
|
||||||
|
-#
|
||||||
|
-
|
||||||
|
-if [ -z ${LVM_TEST_DEVICE_LIST+x} ]; then echo "LVM_TEST_DEVICE_LIST is unset" && skip; else echo "LVM_TEST_DEVICE_LIST is set to '$LVM_TEST_DEVICE_LIST'"; fi
|
||||||
|
-
|
||||||
|
-test -e "$LVM_TEST_DEVICE_LIST" || skip
|
||||||
|
-
|
||||||
|
-num_devs=$(cat $LVM_TEST_DEVICE_LIST | wc -l)
|
||||||
|
-
|
||||||
|
-RUNDIR="/run"
|
||||||
|
-test -d "$RUNDIR" || RUNDIR="/var/run"
|
||||||
|
-PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online"
|
||||||
|
-VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online"
|
||||||
|
-PVS_LOOKUP_DIR="$RUNDIR/lvm/pvs_lookup"
|
||||||
|
-
|
||||||
|
-_clear_online_files() {
|
||||||
|
- # wait till udev is finished
|
||||||
|
- aux udev_wait
|
||||||
|
- rm -f "$PVS_ONLINE_DIR"/*
|
||||||
|
- rm -f "$VGS_ONLINE_DIR"/*
|
||||||
|
- rm -f "$PVS_LOOKUP_DIR"/*
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-test -d "$PVS_ONLINE_DIR" || mkdir -p "$PVS_ONLINE_DIR"
|
||||||
|
-test -d "$VGS_ONLINE_DIR" || mkdir -p "$VGS_ONLINE_DIR"
|
||||||
|
-test -d "$PVS_LOOKUP_DIR" || mkdir -p "$PVS_LOOKUP_DIR"
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-aux prepare_real_devs
|
||||||
|
-
|
||||||
|
-aux lvmconf 'devices/dir = "/dev"'
|
||||||
|
-aux lvmconf 'devices/use_devicesfile = 1'
|
||||||
|
-DFDIR="$LVM_SYSTEM_DIR/devices"
|
||||||
|
-DF="$DFDIR/system.devices"
|
||||||
|
-mkdir $DFDIR || true
|
||||||
|
-not ls $DF
|
||||||
|
-
|
||||||
|
-get_real_devs
|
||||||
|
-
|
||||||
|
-wipe_all() {
|
||||||
|
- for dev in "${REAL_DEVICES[@]}"; do
|
||||||
|
- wipefs -a $dev
|
||||||
|
- done
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-# udevadm trigger runs udev rule which runs systemd-run --no-wait vgchange -aay
|
||||||
|
-# Because of --no-wait, we need to wait for the transient systemd
|
||||||
|
-# service to be gone before checking the effects of the vgchange.
|
||||||
|
-
|
||||||
|
-wait_lvm_activate() {
|
||||||
|
- local vgw=$1
|
||||||
|
- local wait=0
|
||||||
|
-
|
||||||
|
- while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do
|
||||||
|
- sleep .2
|
||||||
|
- wait=$(( wait + 1 ))
|
||||||
|
- done
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-# Test requires 3 devs
|
||||||
|
-test $num_devs -gt 2 || skip
|
||||||
|
-BDEV1=$(basename "$dev1")
|
||||||
|
-BDEV2=$(basename "$dev2")
|
||||||
|
-BDEV3=$(basename "$dev3")
|
||||||
|
-
|
||||||
|
-wipe_all
|
||||||
|
-touch $DF
|
||||||
|
-for dev in "${REAL_DEVICES[@]}"; do
|
||||||
|
- pvcreate $dev
|
||||||
|
-done
|
||||||
|
-
|
||||||
|
-# 1 dev, 1 vg, 1 lv
|
||||||
|
-
|
||||||
|
-vgcreate $vg1 "$dev1"
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg1 "$dev1"
|
||||||
|
-
|
||||||
|
-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-udevadm trigger --settle -c add /sys/block/$BDEV1
|
||||||
|
-
|
||||||
|
-wait_lvm_activate $vg1
|
||||||
|
-
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg1"
|
||||||
|
-journalctl -u lvm-activate-$vg1 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-check lv_field $vg1/$lv1 lv_active "active"
|
||||||
|
-
|
||||||
|
-vgchange -an $vg1
|
||||||
|
-vgremove -y $vg1
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-# 2 devs, 1 vg, 2 lvs
|
||||||
|
-
|
||||||
|
-vgcreate $vg2 "$dev1" "$dev2"
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg2 "$dev1"
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg2 "$dev2"
|
||||||
|
-
|
||||||
|
-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-udevadm trigger --settle -c add /sys/block/$BDEV1
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
||||||
|
-not ls "$RUNDIR/lvm/vgs_online/$vg2"
|
||||||
|
-journalctl -u lvm-activate-$vg2 | tee out || true
|
||||||
|
-not grep "now active" out
|
||||||
|
-check lv_field $vg2/$lv1 lv_active ""
|
||||||
|
-check lv_field $vg2/$lv2 lv_active ""
|
||||||
|
-
|
||||||
|
-udevadm trigger --settle -c add /sys/block/$BDEV2
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID2"
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg2"
|
||||||
|
-
|
||||||
|
-wait_lvm_activate $vg2
|
||||||
|
-
|
||||||
|
-journalctl -u lvm-activate-$vg2 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-check lv_field $vg2/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg2/$lv2 lv_active "active"
|
||||||
|
-
|
||||||
|
-vgchange -an $vg2
|
||||||
|
-vgremove -y $vg2
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-# 3 devs, 1 vg, 4 lvs, concurrent pvscans
|
||||||
|
-# (attempting to have the pvscans run concurrently and race
|
||||||
|
-# to activate the VG)
|
||||||
|
-
|
||||||
|
-vgcreate $vg3 "$dev1" "$dev2" "$dev3"
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg3 "$dev1"
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg3 "$dev2"
|
||||||
|
-lvcreate -l1 -an -n $lv3 $vg3 "$dev3"
|
||||||
|
-lvcreate -l8 -an -n $lv4 -i 2 $vg3 "$dev1" "$dev2"
|
||||||
|
-
|
||||||
|
-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV1 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV2 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV3
|
||||||
|
-
|
||||||
|
-aux udev_wait
|
||||||
|
-wait_lvm_activate $vg3
|
||||||
|
-
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID2"
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID3"
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg3"
|
||||||
|
-journalctl -u lvm-activate-$vg3 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-check lv_field $vg3/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg3/$lv2 lv_active "active"
|
||||||
|
-check lv_field $vg3/$lv3 lv_active "active"
|
||||||
|
-check lv_field $vg3/$lv4 lv_active "active"
|
||||||
|
-
|
||||||
|
-vgchange -an $vg3
|
||||||
|
-vgremove -y $vg3
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-# 3 devs, 1 vg, 4 lvs, concurrent pvscans, metadata on only 1 PV
|
||||||
|
-
|
||||||
|
-wipe_all
|
||||||
|
-rm $DF
|
||||||
|
-touch $DF
|
||||||
|
-pvcreate --metadatacopies 0 "$dev1"
|
||||||
|
-pvcreate --metadatacopies 0 "$dev2"
|
||||||
|
-pvcreate "$dev3"
|
||||||
|
-
|
||||||
|
-vgcreate $vg4 "$dev1" "$dev2" "$dev3"
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg4 "$dev1"
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg4 "$dev2"
|
||||||
|
-lvcreate -l1 -an -n $lv3 $vg4 "$dev3"
|
||||||
|
-lvcreate -l8 -an -n $lv4 -i 2 $vg4 "$dev1" "$dev2"
|
||||||
|
-
|
||||||
|
-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}')
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV1 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV2 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV3
|
||||||
|
-
|
||||||
|
-aux udev_wait
|
||||||
|
-wait_lvm_activate $vg4
|
||||||
|
-
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID2"
|
||||||
|
-ls "$RUNDIR/lvm/pvs_online/$PVID3"
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg4"
|
||||||
|
-journalctl -u lvm-activate-$vg4 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-check lv_field $vg4/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg4/$lv2 lv_active "active"
|
||||||
|
-check lv_field $vg4/$lv3 lv_active "active"
|
||||||
|
-check lv_field $vg4/$lv4 lv_active "active"
|
||||||
|
-
|
||||||
|
-vgchange -an $vg4
|
||||||
|
-vgremove -y $vg4
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-# 3 devs, 3 vgs, 2 lvs in each vg, concurrent pvscans
|
||||||
|
-
|
||||||
|
-wipe_all
|
||||||
|
-rm $DF
|
||||||
|
-touch $DF
|
||||||
|
-
|
||||||
|
-vgcreate $vg5 "$dev1"
|
||||||
|
-vgcreate $vg6 "$dev2"
|
||||||
|
-vgcreate $vg7 "$dev3"
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg5
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg5
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg6
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg6
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg7
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg7
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV1 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV2 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV3
|
||||||
|
-
|
||||||
|
-aux udev_wait
|
||||||
|
-wait_lvm_activate $vg5
|
||||||
|
-wait_lvm_activate $vg6
|
||||||
|
-wait_lvm_activate $vg7
|
||||||
|
-
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg5"
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg6"
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg7"
|
||||||
|
-journalctl -u lvm-activate-$vg5 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-journalctl -u lvm-activate-$vg6 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-journalctl -u lvm-activate-$vg7 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-check lv_field $vg5/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg5/$lv2 lv_active "active"
|
||||||
|
-check lv_field $vg6/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg6/$lv2 lv_active "active"
|
||||||
|
-check lv_field $vg7/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg7/$lv2 lv_active "active"
|
||||||
|
-
|
||||||
|
-vgchange -an $vg5
|
||||||
|
-vgremove -y $vg5
|
||||||
|
-vgchange -an $vg6
|
||||||
|
-vgremove -y $vg6
|
||||||
|
-vgchange -an $vg7
|
||||||
|
-vgremove -y $vg7
|
||||||
|
-
|
||||||
|
-# 3 devs, 1 vg, 1000 LVs
|
||||||
|
-
|
||||||
|
-wipe_all
|
||||||
|
-rm $DF
|
||||||
|
-touch $DF
|
||||||
|
-pvcreate --metadatacopies 0 "$dev1"
|
||||||
|
-pvcreate "$dev2"
|
||||||
|
-pvcreate "$dev3"
|
||||||
|
-vgcreate -s 128K $vg8 "$dev1" "$dev2" "$dev3"
|
||||||
|
-
|
||||||
|
-# Number of LVs to create
|
||||||
|
-TEST_DEVS=1000
|
||||||
|
-# On low-memory boxes let's not stress too much
|
||||||
|
-test "$(aux total_mem)" -gt 524288 || TEST_DEVS=256
|
||||||
|
-
|
||||||
|
-vgcfgbackup -f data $vg8
|
||||||
|
-
|
||||||
|
-# Generate a lot of devices (size of 1 extent)
|
||||||
|
-awk -v TEST_DEVS=$TEST_DEVS '/^\t\}/ {
|
||||||
|
- printf("\t}\n\tlogical_volumes {\n");
|
||||||
|
- cnt=0;
|
||||||
|
- for (i = 0; i < TEST_DEVS; i++) {
|
||||||
|
- printf("\t\tlvol%06d {\n", i);
|
||||||
|
- printf("\t\t\tid = \"%06d-1111-2222-3333-2222-1111-%06d\"\n", i, i);
|
||||||
|
- print "\t\t\tstatus = [\"READ\", \"WRITE\", \"VISIBLE\"]";
|
||||||
|
- print "\t\t\tsegment_count = 1";
|
||||||
|
- print "\t\t\tsegment1 {";
|
||||||
|
- print "\t\t\t\tstart_extent = 0";
|
||||||
|
- print "\t\t\t\textent_count = 1";
|
||||||
|
- print "\t\t\t\ttype = \"striped\"";
|
||||||
|
- print "\t\t\t\tstripe_count = 1";
|
||||||
|
- print "\t\t\t\tstripes = [";
|
||||||
|
- print "\t\t\t\t\t\"pv0\", " cnt++;
|
||||||
|
- printf("\t\t\t\t]\n\t\t\t}\n\t\t}\n");
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- {print}
|
||||||
|
-' data >data_new
|
||||||
|
-
|
||||||
|
-vgcfgrestore -f data_new $vg8
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV1 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV2 &
|
||||||
|
-udevadm trigger -c add /sys/block/$BDEV3
|
||||||
|
-
|
||||||
|
-aux udev_wait
|
||||||
|
-wait_lvm_activate $vg8
|
||||||
|
-
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg8"
|
||||||
|
-journalctl -u lvm-activate-$vg8 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-
|
||||||
|
-num_active=$(lvs $vg8 --noheading -o active | grep active | wc -l)
|
||||||
|
-
|
||||||
|
-test $num_active -eq $TEST_DEVS
|
||||||
|
-
|
||||||
|
-vgchange -an $vg8
|
||||||
|
-vgremove -y $vg8
|
||||||
|
-
|
||||||
|
-# 1 pv on an md dev, 1 vg
|
||||||
|
-
|
||||||
|
-wait_md_create() {
|
||||||
|
- local md=$1
|
||||||
|
-
|
||||||
|
- while :; do
|
||||||
|
- if ! grep "$(basename $md)" /proc/mdstat; then
|
||||||
|
- echo "$md not ready"
|
||||||
|
- cat /proc/mdstat
|
||||||
|
- sleep 2
|
||||||
|
- else
|
||||||
|
- break
|
||||||
|
- fi
|
||||||
|
- done
|
||||||
|
- echo "$md" > WAIT_MD_DEV
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-test -f /proc/mdstat && grep -q raid1 /proc/mdstat || \
|
||||||
|
- modprobe raid1 || skip
|
||||||
|
-
|
||||||
|
-mddev="/dev/md33"
|
||||||
|
-not grep $mddev /proc/mdstat || skip
|
||||||
|
-
|
||||||
|
-wipe_all
|
||||||
|
-rm $DF
|
||||||
|
-touch $DF
|
||||||
|
-
|
||||||
|
-mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev1" "$dev2"
|
||||||
|
-wait_md_create "$mddev"
|
||||||
|
-vgcreate $vg9 "$mddev"
|
||||||
|
-
|
||||||
|
-PVIDMD=`pvs $mddev --noheading -o uuid | tr -d - | awk '{print $1}'`
|
||||||
|
-BDEVMD=$(basename "$mddev")
|
||||||
|
-
|
||||||
|
-lvcreate -l1 -an -n $lv1 $vg9
|
||||||
|
-lvcreate -l1 -an -n $lv2 $vg9
|
||||||
|
-
|
||||||
|
-_clear_online_files
|
||||||
|
-
|
||||||
|
-udevadm trigger --settle -c add /sys/block/$BDEVMD
|
||||||
|
-
|
||||||
|
-wait_lvm_activate $vg9
|
||||||
|
-
|
||||||
|
-ls "$RUNDIR/lvm/vgs_online/$vg9"
|
||||||
|
-journalctl -u lvm-activate-$vg9 | tee out || true
|
||||||
|
-grep "now active" out
|
||||||
|
-check lv_field $vg9/$lv1 lv_active "active"
|
||||||
|
-check lv_field $vg9/$lv2 lv_active "active"
|
||||||
|
-
|
||||||
|
-vgchange -an $vg9
|
||||||
|
-vgremove -y $vg9
|
||||||
|
-
|
||||||
|
-mdadm --stop "$mddev"
|
||||||
|
-aux udev_wait
|
||||||
|
-wipe_all
|
||||||
|
-
|
||||||
|
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
|
||||||
|
deleted file mode 100644
|
||||||
|
index 39e5b9807..000000000
|
||||||
|
--- a/udev/69-dm-lvm.rules.in
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,87 +0,0 @@
|
||||||
|
-# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved.
|
||||||
|
-#
|
||||||
|
-# This file is part of LVM.
|
||||||
|
-#
|
||||||
|
-# This rule requires blkid to be called on block devices before so only devices
|
||||||
|
-# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member").
|
||||||
|
-
|
||||||
|
-SUBSYSTEM!="block", GOTO="lvm_end"
|
||||||
|
-(LVM_EXEC_RULE)
|
||||||
|
-
|
||||||
|
-ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-# Only process devices already marked as a PV - this requires blkid to be called before.
|
||||||
|
-ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
|
||||||
|
-ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
|
||||||
|
-ACTION=="remove", GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-# Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV
|
||||||
|
-ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}"
|
||||||
|
-
|
||||||
|
-# If the PV is a special device listed below, scan only if the device is
|
||||||
|
-# properly activated. These devices are not usable after an ADD event,
|
||||||
|
-# but they require an extra setup and they are ready after a CHANGE event.
|
||||||
|
-# Also support coldplugging with ADD event but only if the device is already
|
||||||
|
-# properly activated.
|
||||||
|
-# This logic should be eventually moved to rules where those particular
|
||||||
|
-# devices are processed primarily (MD and loop).
|
||||||
|
-
|
||||||
|
-# DM device:
|
||||||
|
-KERNEL!="dm-[0-9]*", GOTO="next"
|
||||||
|
-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan"
|
||||||
|
-GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-# MD device:
|
||||||
|
-LABEL="next"
|
||||||
|
-KERNEL!="md[0-9]*", GOTO="next"
|
||||||
|
-IMPORT{db}="LVM_MD_PV_ACTIVATED"
|
||||||
|
-ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
|
||||||
|
-ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
|
||||||
|
-ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan"
|
||||||
|
-ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
|
||||||
|
-GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-# Loop device:
|
||||||
|
-LABEL="next"
|
||||||
|
-KERNEL!="loop[0-9]*", GOTO="next"
|
||||||
|
-ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
|
||||||
|
-ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
|
||||||
|
-ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
|
||||||
|
-GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-LABEL="next"
|
||||||
|
-ACTION!="add", GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-LABEL="lvm_scan"
|
||||||
|
-
|
||||||
|
-ENV{SYSTEMD_READY}="1"
|
||||||
|
-
|
||||||
|
-# pvscan will check if this device completes a VG,
|
||||||
|
-# i.e. all PVs in the VG are now present with the
|
||||||
|
-# arrival of this PV. If so, it prints to stdout:
|
||||||
|
-# LVM_VG_NAME_COMPLETE='foo'
|
||||||
|
-#
|
||||||
|
-# When the VG is complete it can be activated, so
|
||||||
|
-# vgchange -aay <vgname> is run. It is run via
|
||||||
|
-# systemd since it can take longer to run than
|
||||||
|
-# udev wants to block when processing rules.
|
||||||
|
-# (if there are hundreds of LVs to activate,
|
||||||
|
-# the vgchange can take many seconds.)
|
||||||
|
-#
|
||||||
|
-# pvscan only reads the single device specified,
|
||||||
|
-# and uses temp files under /run/lvm to check if
|
||||||
|
-# other PVs in the VG are present.
|
||||||
|
-#
|
||||||
|
-# If event_activation=0 in lvm.conf, this pvscan
|
||||||
|
-# (using checkcomplete) will do nothing, so that
|
||||||
|
-# no event-based autoactivation will be happen.
|
||||||
|
-#
|
||||||
|
-# TODO: adjust the output of vgchange -aay so that
|
||||||
|
-# it's better suited to appearing in the journal.
|
||||||
|
-
|
||||||
|
-IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}"
|
||||||
|
-ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run -r --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay --nohints $env{LVM_VG_NAME_COMPLETE}"
|
||||||
|
-GOTO="lvm_end"
|
||||||
|
-
|
||||||
|
-LABEL="lvm_end"
|
||||||
|
-
|
||||||
|
diff --git a/udev/Makefile.in b/udev/Makefile.in
|
||||||
|
index e777dda16..e32cba921 100644
|
||||||
|
--- a/udev/Makefile.in
|
||||||
|
+++ b/udev/Makefile.in
|
||||||
|
@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
|
||||||
|
include $(top_builddir)/make.tmpl
|
||||||
|
|
||||||
|
DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
|
||||||
|
-LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules
|
||||||
|
+LVM_RULES=11-dm-lvm.rules 69-dm-lvm-metad.rules
|
||||||
|
|
||||||
|
DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
From d6b3f4f4dd526a5a4413e84f4cccb2e92699d1d8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 15:30:02 +0200
|
|
||||||
Subject: [PATCH 2/7] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3"
|
|
||||||
|
|
||||||
This reverts commit 038f9254d9554654197b59c160e3f775af27cdb1.
|
|
||||||
---
|
|
||||||
udev/10-dm.rules.in | 12 +-----------
|
|
||||||
1 file changed, 1 insertion(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in
|
|
||||||
index db4ee771d..ca255c793 100644
|
|
||||||
--- a/udev/10-dm.rules.in
|
|
||||||
+++ b/udev/10-dm.rules.in
|
|
||||||
@@ -12,9 +12,6 @@
|
|
||||||
# DM_NAME - actual DM device's name
|
|
||||||
# DM_UUID - UUID set for DM device (blank if not specified)
|
|
||||||
# DM_UDEV_RULES_VSN - DM udev rules version
|
|
||||||
-# DM_UDEV_DISABLE_OTHER_RULES_FLAG - a flag that indicates that
|
|
||||||
-# stacked layers shouldn't attempt to probe the device, and
|
|
||||||
-# should try to import relevant properties from the udev db.
|
|
||||||
#
|
|
||||||
# These rules cover only basic device-mapper functionality in udev.
|
|
||||||
#
|
|
||||||
@@ -25,11 +22,6 @@
|
|
||||||
# 11-dm-lvm.rules for LVM subsystem
|
|
||||||
# 11-dm-mpath.rules for multipath subsystem (since version 0.6.0, recommended!)
|
|
||||||
#
|
|
||||||
-# 11-dm<subsystem_name>.rules may use other DM related properties besides
|
|
||||||
-# those listed above, like .DM_SUSPENDED. These properties are considered
|
|
||||||
-# internal to device mapper, and subject to change without notice.
|
|
||||||
-# Rules that are executed after 13-dm-disk.rules shouldn't use them.
|
|
||||||
-#
|
|
||||||
# Even more specific rules may be required by subsystems so always
|
|
||||||
# check subsystem's upstream repository for recent set of rules.
|
|
||||||
# Also, keep in mind that recent rules may also require recent
|
|
||||||
@@ -152,9 +144,7 @@ LABEL="dm_suspended_set"
|
|
||||||
# possible future changes.
|
|
||||||
# VSN 1 - original rules
|
|
||||||
# VSN 2 - add support for synthesized events
|
|
||||||
-# VSN 3 - use DM_UDEV_DISABLE_OTHER_RULES_FLAG as the only "API"
|
|
||||||
-# to be consumed by non-dm rules.
|
|
||||||
-ENV{DM_UDEV_RULES_VSN}="3"
|
|
||||||
+ENV{DM_UDEV_RULES_VSN}="2"
|
|
||||||
|
|
||||||
ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/$env{DM_NAME}"
|
|
||||||
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
@ -0,0 +1,450 @@
|
|||||||
|
From 2091305b796d5552fd991c527a0359a0b4d8fde0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 20 Dec 2021 13:38:23 -0600
|
||||||
|
Subject: [PATCH 02/54] Revert "pvscan: only add device args to dev cache"
|
||||||
|
|
||||||
|
This reverts commit 33e47182f773c1a902b533580b63a803906de55d.
|
||||||
|
---
|
||||||
|
lib/device/dev-cache.c | 204 +++-----------------------------
|
||||||
|
lib/device/dev-cache.h | 6 +-
|
||||||
|
lib/device/device_id.c | 27 ++---
|
||||||
|
lib/device/device_id.h | 1 -
|
||||||
|
test/shell/devicesfile-basic.sh | 2 +-
|
||||||
|
tools/pvscan.c | 58 ++++-----
|
||||||
|
6 files changed, 52 insertions(+), 246 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index 33b75a9a9..c6e5f68cf 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -1852,7 +1852,7 @@ int setup_devices_file(struct cmd_context *cmd)
|
||||||
|
* Add all system devices to dev-cache, and attempt to
|
||||||
|
* match all devices_file entries to dev-cache entries.
|
||||||
|
*/
|
||||||
|
-int setup_devices(struct cmd_context *cmd)
|
||||||
|
+static int _setup_devices(struct cmd_context *cmd, int no_file_match)
|
||||||
|
{
|
||||||
|
int file_exists;
|
||||||
|
int lock_mode = 0;
|
||||||
|
@@ -1979,6 +1979,13 @@ int setup_devices(struct cmd_context *cmd)
|
||||||
|
*/
|
||||||
|
dev_cache_scan(cmd);
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * The caller uses "no_file_match" if it wants to match specific devs
|
||||||
|
+ * itself, instead of matching everything in device_ids_match.
|
||||||
|
+ */
|
||||||
|
+ if (no_file_match && cmd->enable_devices_file)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Match entries from cmd->use_devices with device structs in dev-cache.
|
||||||
|
*/
|
||||||
|
@@ -1987,6 +1994,16 @@ int setup_devices(struct cmd_context *cmd)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int setup_devices(struct cmd_context *cmd)
|
||||||
|
+{
|
||||||
|
+ return _setup_devices(cmd, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int setup_devices_no_file_match(struct cmd_context *cmd)
|
||||||
|
+{
|
||||||
|
+ return _setup_devices(cmd, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* The alternative to setup_devices() when the command is interested
|
||||||
|
* in using only one PV.
|
||||||
|
@@ -2055,188 +2072,3 @@ int setup_device(struct cmd_context *cmd, const char *devname)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * pvscan --cache is specialized/optimized to look only at command args,
|
||||||
|
- * so this just sets up the devices file, then individual devices are
|
||||||
|
- * added to dev-cache and matched with device_ids later in pvscan.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-int setup_devices_for_pvscan_cache(struct cmd_context *cmd)
|
||||||
|
-{
|
||||||
|
- if (cmd->enable_devices_list) {
|
||||||
|
- if (!_setup_devices_list(cmd))
|
||||||
|
- return_0;
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!setup_devices_file(cmd))
|
||||||
|
- return_0;
|
||||||
|
-
|
||||||
|
- if (!cmd->enable_devices_file)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
- if (!devices_file_exists(cmd)) {
|
||||||
|
- log_debug("Devices file not found, ignoring.");
|
||||||
|
- cmd->enable_devices_file = 0;
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!lock_devices_file(cmd, LOCK_SH)) {
|
||||||
|
- log_error("Failed to lock the devices file to read.");
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!device_ids_read(cmd)) {
|
||||||
|
- log_error("Failed to read the devices file.");
|
||||||
|
- unlock_devices_file(cmd);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- unlock_devices_file(cmd);
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-/* Get a device name from a devno. */
|
||||||
|
-
|
||||||
|
-static char *_get_devname_from_devno(struct cmd_context *cmd, dev_t devno)
|
||||||
|
-{
|
||||||
|
- char path[PATH_MAX];
|
||||||
|
- char devname[PATH_MAX];
|
||||||
|
- char namebuf[NAME_LEN];
|
||||||
|
- char line[1024];
|
||||||
|
- int major = MAJOR(devno);
|
||||||
|
- int minor = MINOR(devno);
|
||||||
|
- int line_major;
|
||||||
|
- int line_minor;
|
||||||
|
- uint64_t line_blocks;
|
||||||
|
- DIR *dir;
|
||||||
|
- struct dirent *dirent;
|
||||||
|
- FILE *fp;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * $ ls /sys/dev/block/8:0/device/block/
|
||||||
|
- * sda
|
||||||
|
- */
|
||||||
|
- if (major_is_scsi_device(cmd->dev_types, major)) {
|
||||||
|
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/device/block",
|
||||||
|
- dm_sysfs_dir(), major, minor) < 0) {
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!(dir = opendir(path)))
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- while ((dirent = readdir(dir))) {
|
||||||
|
- if (dirent->d_name[0] == '.')
|
||||||
|
- continue;
|
||||||
|
- if (dm_snprintf(devname, sizeof(devname), "/dev/%s", dirent->d_name) < 0) {
|
||||||
|
- devname[0] = '\0';
|
||||||
|
- stack;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- closedir(dir);
|
||||||
|
-
|
||||||
|
- if (devname[0]) {
|
||||||
|
- log_debug("Found %s for %d:%d from sys", devname, major, minor);
|
||||||
|
- return _strdup(devname);
|
||||||
|
- }
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * $ cat /sys/dev/block/253:3/dm/name
|
||||||
|
- * mpatha
|
||||||
|
- */
|
||||||
|
- if (major == cmd->dev_types->device_mapper_major) {
|
||||||
|
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/dm/name",
|
||||||
|
- dm_sysfs_dir(), major, minor) < 0) {
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!get_sysfs_value(path, namebuf, sizeof(namebuf), 0))
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- if (dm_snprintf(devname, sizeof(devname), "/dev/mapper/%s", namebuf) < 0) {
|
||||||
|
- devname[0] = '\0';
|
||||||
|
- stack;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (devname[0]) {
|
||||||
|
- log_debug("Found %s for %d:%d from sys", devname, major, minor);
|
||||||
|
- return _strdup(devname);
|
||||||
|
- }
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * /proc/partitions lists
|
||||||
|
- * major minor #blocks name
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- if (!(fp = fopen("/proc/partitions", "r")))
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- while (fgets(line, sizeof(line), fp)) {
|
||||||
|
- if (sscanf(line, "%u %u %llu %s", &line_major, &line_minor, (unsigned long long *)&line_blocks, namebuf) != 4)
|
||||||
|
- continue;
|
||||||
|
- if (line_major != major)
|
||||||
|
- continue;
|
||||||
|
- if (line_minor != minor)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- if (dm_snprintf(devname, sizeof(devname), "/dev/%s", namebuf) < 0) {
|
||||||
|
- devname[0] = '\0';
|
||||||
|
- stack;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- fclose(fp);
|
||||||
|
-
|
||||||
|
- if (devname[0]) {
|
||||||
|
- log_debug("Found %s for %d:%d from proc", devname, major, minor);
|
||||||
|
- return _strdup(devname);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * If necessary, this could continue searching by stat'ing /dev entries.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- return NULL;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname)
|
||||||
|
-{
|
||||||
|
- struct stat buf;
|
||||||
|
- struct device *dev;
|
||||||
|
-
|
||||||
|
- if (stat(devname, &buf) < 0) {
|
||||||
|
- log_error("Cannot access device %s.", devname);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!S_ISBLK(buf.st_mode)) {
|
||||||
|
- log_error("Invaild device type %s.", devname);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!_insert_dev(devname, buf.st_rdev))
|
||||||
|
- return_0;
|
||||||
|
-
|
||||||
|
- if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname)))
|
||||||
|
- return_0;
|
||||||
|
-
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno)
|
||||||
|
-{
|
||||||
|
- const char *devname;
|
||||||
|
-
|
||||||
|
- if (!(devname = _get_devname_from_devno(cmd, devno)))
|
||||||
|
- return_0;
|
||||||
|
-
|
||||||
|
- return setup_devname_in_dev_cache(cmd, devname);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
|
||||||
|
index 143848d6d..635dc4fc9 100644
|
||||||
|
--- a/lib/device/dev-cache.h
|
||||||
|
+++ b/lib/device/dev-cache.h
|
||||||
|
@@ -77,11 +77,7 @@ int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
|
||||||
|
|
||||||
|
int setup_devices_file(struct cmd_context *cmd);
|
||||||
|
int setup_devices(struct cmd_context *cmd);
|
||||||
|
+int setup_devices_no_file_match(struct cmd_context *cmd);
|
||||||
|
int setup_device(struct cmd_context *cmd, const char *devname);
|
||||||
|
|
||||||
|
-/* Normal device setup functions are split up for pvscan optimization. */
|
||||||
|
-int setup_devices_for_pvscan_cache(struct cmd_context *cmd);
|
||||||
|
-int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname);
|
||||||
|
-int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno);
|
||||||
|
-
|
||||||
|
#endif
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 167bf661b..eb06109ff 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1534,22 +1534,6 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev)
|
||||||
|
* passes the filter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-void device_ids_match_device_list(struct cmd_context *cmd)
|
||||||
|
-{
|
||||||
|
- struct dev_use *du;
|
||||||
|
-
|
||||||
|
- dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
- if (du->dev)
|
||||||
|
- continue;
|
||||||
|
- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
|
||||||
|
- log_warn("Device not found for %s.", du->devname);
|
||||||
|
- } else {
|
||||||
|
- /* Should we set dev->id? Which idtype? Use --deviceidtype? */
|
||||||
|
- du->dev->flags |= DEV_MATCHED_USE_ID;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void device_ids_match(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct dev_iter *iter;
|
||||||
|
@@ -1557,7 +1541,16 @@ void device_ids_match(struct cmd_context *cmd)
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
if (cmd->enable_devices_list) {
|
||||||
|
- device_ids_match_device_list(cmd);
|
||||||
|
+ dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
+ if (du->dev)
|
||||||
|
+ continue;
|
||||||
|
+ if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
|
||||||
|
+ log_warn("Device not found for %s.", du->devname);
|
||||||
|
+ } else {
|
||||||
|
+ /* Should we set dev->id? Which idtype? Use --deviceidtype? */
|
||||||
|
+ du->dev->flags |= DEV_MATCHED_USE_ID;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
|
||||||
|
index 0ada35c94..939b3a0f4 100644
|
||||||
|
--- a/lib/device/device_id.h
|
||||||
|
+++ b/lib/device/device_id.h
|
||||||
|
@@ -32,7 +32,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid,
|
||||||
|
void device_id_pvremove(struct cmd_context *cmd, struct device *dev);
|
||||||
|
void device_ids_match(struct cmd_context *cmd);
|
||||||
|
int device_ids_match_dev(struct cmd_context *cmd, struct device *dev);
|
||||||
|
-void device_ids_match_device_list(struct cmd_context *cmd);
|
||||||
|
void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate);
|
||||||
|
int device_ids_version_unchanged(struct cmd_context *cmd);
|
||||||
|
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate);
|
||||||
|
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
|
||||||
|
index 9c3455c76..7ba9e2c7f 100644
|
||||||
|
--- a/test/shell/devicesfile-basic.sh
|
||||||
|
+++ b/test/shell/devicesfile-basic.sh
|
||||||
|
@@ -283,7 +283,7 @@ not ls "$RUNDIR/lvm/pvs_online/$PVID3"
|
||||||
|
# arg in devices list
|
||||||
|
_clear_online_files
|
||||||
|
pvscan --devices "$dev3" --cache -aay "$dev3"
|
||||||
|
-pvscan --devices "$dev4","$dev3" --cache -aay "$dev4"
|
||||||
|
+pvscan --devices "$dev4" --cache -aay "$dev4"
|
||||||
|
check lv_field $vg2/$lv2 lv_active "active"
|
||||||
|
vgchange -an $vg2
|
||||||
|
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index 95d593d57..8e2611361 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -857,21 +857,11 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname,
|
||||||
|
|
||||||
|
devno = MKDEV(file_major, file_minor);
|
||||||
|
|
||||||
|
- if (!setup_devno_in_dev_cache(cmd, devno)) {
|
||||||
|
- log_error_pvscan(cmd, "No device set up for %d:%d PVID %s", file_major, file_minor, pvid);
|
||||||
|
- goto bad;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) {
|
||||||
|
log_error_pvscan(cmd, "No device found for %d:%d PVID %s", file_major, file_minor, pvid);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Do not need to match device_id here, see comment after
|
||||||
|
- * get_devs_from_saved_vg about relying on pvid online file.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
name1 = dev_name(dev);
|
||||||
|
name2 = pvl->pv->device_hint;
|
||||||
|
|
||||||
|
@@ -1109,11 +1099,17 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
|
||||||
|
* PROCESS_SKIP_SCAN: we have already done lvmcache_label_scan
|
||||||
|
* so tell process_each to skip it.
|
||||||
|
*/
|
||||||
|
+ if (do_all)
|
||||||
|
+ read_flags |= PROCESS_SKIP_SCAN;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * When the command is processing specific devs (not all), it
|
||||||
|
+ * has done setup_devices_no_file_match() to avoid matching ids
|
||||||
|
+ * fo all devs unnecessarily, but now that we're falling back
|
||||||
|
+ * to process_each_vg() we need to complete the id matching.
|
||||||
|
+ */
|
||||||
|
if (!do_all)
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
-
|
||||||
|
- read_flags |= PROCESS_SKIP_SCAN;
|
||||||
|
+ device_ids_match(cmd);
|
||||||
|
|
||||||
|
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, read_flags, 0, handle, _pvscan_aa_single);
|
||||||
|
}
|
||||||
|
@@ -1196,15 +1192,11 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
|
||||||
|
/* in common usage, no dev will be found for a devno */
|
||||||
|
|
||||||
|
dm_list_iterate_items(arg, pvscan_args) {
|
||||||
|
- if (arg->devname) {
|
||||||
|
- if (!setup_devname_in_dev_cache(cmd, arg->devname))
|
||||||
|
- log_error_pvscan(cmd, "No device set up for name arg %s", arg->devname);
|
||||||
|
+ if (arg->devname)
|
||||||
|
arg->dev = dev_cache_get(cmd, arg->devname, NULL);
|
||||||
|
- } else if (arg->devno) {
|
||||||
|
- if (!setup_devno_in_dev_cache(cmd, arg->devno))
|
||||||
|
- log_error_pvscan(cmd, "No device set up for devno arg %d", (int)arg->devno);
|
||||||
|
+ else if (arg->devno)
|
||||||
|
arg->dev = dev_cache_get_by_devt(cmd, arg->devno, NULL, NULL);
|
||||||
|
- } else
|
||||||
|
+ else
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1680,13 +1672,11 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
cmd->pvscan_cache_single = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Special pvscan-specific setup steps to avoid looking
|
||||||
|
- * at any devices except for device args.
|
||||||
|
- * Read devices file and determine if devices file will be used.
|
||||||
|
- * Does not do dev_cache_scan (adds nothing to dev-cache), and
|
||||||
|
- * does not do any device id matching.
|
||||||
|
+ * "no_file_match" means that when the devices file is used,
|
||||||
|
+ * setup_devices will skip matching devs to devices file entries.
|
||||||
|
+ * Specific devs must be matched later with device_ids_match_dev().
|
||||||
|
*/
|
||||||
|
- if (!setup_devices_for_pvscan_cache(cmd)) {
|
||||||
|
+ if (!setup_devices_no_file_match(cmd)) {
|
||||||
|
log_error_pvscan(cmd, "Failed to set up devices.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1745,21 +1735,17 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
log_debug("pvscan_cache_args: filter devs nodata");
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Match dev args with the devices file because special/optimized
|
||||||
|
- * device setup was used above which does not check the devices file.
|
||||||
|
- * If a match fails here do not exclude it, that will be done below by
|
||||||
|
- * passes_filter() which runs filter-deviceid. The
|
||||||
|
- * relax_deviceid_filter case needs to be able to work around
|
||||||
|
+ * Match dev args with the devices file because
|
||||||
|
+ * setup_devices_no_file_match() was used above which skipped checking
|
||||||
|
+ * the devices file. If a match fails here do not exclude it, that
|
||||||
|
+ * will be done below by passes_filter() which runs filter-deviceid.
|
||||||
|
+ * The relax_deviceid_filter case needs to be able to work around
|
||||||
|
* unmatching devs.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
if (cmd->enable_devices_file) {
|
||||||
|
- dm_list_iterate_items(devl, &pvscan_devs)
|
||||||
|
+ dm_list_iterate_items_safe(devl, devl2, &pvscan_devs)
|
||||||
|
device_ids_match_dev(cmd, devl->dev);
|
||||||
|
-
|
||||||
|
}
|
||||||
|
- if (cmd->enable_devices_list)
|
||||||
|
- device_ids_match_device_list(cmd);
|
||||||
|
|
||||||
|
if (cmd->enable_devices_file && device_ids_use_devname(cmd)) {
|
||||||
|
relax_deviceid_filter = 1;
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
From da6319b9f5d263a210cf51b471fdbf1c343facf3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 15:30:15 +0200
|
|
||||||
Subject: [PATCH 3/7] Revert "dm udev rules: don't export and save DM_NOSCAN"
|
|
||||||
|
|
||||||
This reverts commit a196752969320cfc34a97cc97afa1978fa57da73.
|
|
||||||
---
|
|
||||||
udev/11-dm-lvm.rules.in | 2 +-
|
|
||||||
udev/13-dm-disk.rules.in | 4 ++--
|
|
||||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in
|
|
||||||
index cfc022489..5b0cc5242 100644
|
|
||||||
--- a/udev/11-dm-lvm.rules.in
|
|
||||||
+++ b/udev/11-dm-lvm.rules.in
|
|
||||||
@@ -30,7 +30,7 @@ IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows
|
|
||||||
# so those selected rules are surely skipped.
|
|
||||||
# We don't need to save and restore the previous of DM_UDEV_DISABLE_OTHER_RULES_FLAG,
|
|
||||||
# that's taken care of in 10-dm.rules.
|
|
||||||
-ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
|
||||||
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
|
||||||
|
|
||||||
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
|
|
||||||
|
|
||||||
diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in
|
|
||||||
index b53bb62de..b748cc909 100644
|
|
||||||
--- a/udev/13-dm-disk.rules.in
|
|
||||||
+++ b/udev/13-dm-disk.rules.in
|
|
||||||
@@ -18,9 +18,9 @@ SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
|
|
||||||
ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
|
|
||||||
|
|
||||||
ENV{.DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
|
|
||||||
-ENV{.DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
|
|
||||||
+ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
|
|
||||||
ENV{.DM_SUSPENDED}=="1", GOTO="dm_end"
|
|
||||||
-ENV{.DM_NOSCAN}=="1", GOTO="dm_watch"
|
|
||||||
+ENV{DM_NOSCAN}=="1", GOTO="dm_watch"
|
|
||||||
|
|
||||||
(BLKID_RULE)
|
|
||||||
GOTO="dm_link"
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
34
SOURCES/0003-pvscan-fix-messages-from-coverity-changes.patch
Normal file
34
SOURCES/0003-pvscan-fix-messages-from-coverity-changes.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From a5a2d5fa1ec47a5a548db4cf435dc84de7ce7c31 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 20 Oct 2021 16:12:41 -0500
|
||||||
|
Subject: [PATCH 03/54] pvscan: fix messages from coverity changes
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/pvscan.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index 8e2611361..f60c4a2ca 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -1354,7 +1354,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
|
||||||
|
devsize = dev->size;
|
||||||
|
if (!devsize &&
|
||||||
|
!dev_get_size(dev, &devsize)) {
|
||||||
|
- log_print("pvscan[%d] PV %s can get device size.", getpid(), dev_name(dev));
|
||||||
|
+ log_print_pvscan(cmd, "PV %s missing device size.", dev_name(dev));
|
||||||
|
release_vg(vg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@@ -1786,7 +1786,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
int has_pvid;
|
||||||
|
|
||||||
|
if (!label_read_pvid(devl->dev, &has_pvid)) {
|
||||||
|
- log_print("pvscan[%d] %s cannot read.", getpid(), dev_name(devl->dev));
|
||||||
|
+ log_print_pvscan(cmd, "%s cannot read label.", dev_name(devl->dev));
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,88 +0,0 @@
|
|||||||
From 2e2303dd559fda3fb7d97f79094d04c3ccd9d519 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 15:30:24 +0200
|
|
||||||
Subject: [PATCH 4/7] Revert "dm udev rules: don't export and save
|
|
||||||
DM_SUSPENDED"
|
|
||||||
|
|
||||||
This reverts commit 21ca92c4325b6b161fb1e1f10942ad9f8d23c144.
|
|
||||||
---
|
|
||||||
udev/10-dm.rules.in | 14 ++++++--------
|
|
||||||
udev/12-dm-permissions.rules | 1 +
|
|
||||||
udev/13-dm-disk.rules.in | 4 ++--
|
|
||||||
3 files changed, 9 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in
|
|
||||||
index ca255c793..29fe71527 100644
|
|
||||||
--- a/udev/10-dm.rules.in
|
|
||||||
+++ b/udev/10-dm.rules.in
|
|
||||||
@@ -11,6 +11,7 @@
|
|
||||||
# for use in later rules:
|
|
||||||
# DM_NAME - actual DM device's name
|
|
||||||
# DM_UUID - UUID set for DM device (blank if not specified)
|
|
||||||
+# DM_SUSPENDED - suspended state of DM device (0 or 1)
|
|
||||||
# DM_UDEV_RULES_VSN - DM udev rules version
|
|
||||||
#
|
|
||||||
# These rules cover only basic device-mapper functionality in udev.
|
|
||||||
@@ -122,18 +123,15 @@ LABEL="dm_no_coldplug"
|
|
||||||
# The "suspended" item was added even later (kernels >= 2.6.31),
|
|
||||||
# so we also have to call dmsetup if the kernel version used
|
|
||||||
# is in between these releases.
|
|
||||||
-TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{.DM_SUSPENDED}="$attr{dm/suspended}"
|
|
||||||
+TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{DM_SUSPENDED}="$attr{dm/suspended}"
|
|
||||||
TEST!="dm", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended"
|
|
||||||
+ENV{DM_SUSPENDED}!="?*", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended"
|
|
||||||
|
|
||||||
-ENV{.DM_SUSPENDED}=="?*", GOTO="dm_suspended_set"
|
|
||||||
-TEST=="dm", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended"
|
|
||||||
# dmsetup tool provides suspended state information in textual
|
|
||||||
# form with values "Suspended"/"Active". We translate it to
|
|
||||||
# 0/1 respectively to be consistent with sysfs values.
|
|
||||||
-ENV{DM_SUSPENDED}=="Active", ENV{.DM_SUSPENDED}="0"
|
|
||||||
-ENV{DM_SUSPENDED}=="Suspended", ENV{.DM_SUSPENDED}="1"
|
|
||||||
-ENV{DM_SUSPENDED}=""
|
|
||||||
-LABEL="dm_suspended_set"
|
|
||||||
+ENV{DM_SUSPENDED}=="Active", ENV{DM_SUSPENDED}="0"
|
|
||||||
+ENV{DM_SUSPENDED}=="Suspended", ENV{DM_SUSPENDED}="1"
|
|
||||||
|
|
||||||
# This variable provides a reliable way to check that device-mapper
|
|
||||||
# rules were installed. It means that all needed variables are set
|
|
||||||
@@ -151,7 +149,7 @@ ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/
|
|
||||||
# Avoid processing and scanning a DM device in the other (foreign)
|
|
||||||
# rules if it is in suspended state. However, we still keep 'disk'
|
|
||||||
# and 'DM subsystem' related rules enabled in this case.
|
|
||||||
-ENV{.DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
|
||||||
+ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
|
||||||
|
|
||||||
GOTO="dm_end"
|
|
||||||
|
|
||||||
diff --git a/udev/12-dm-permissions.rules b/udev/12-dm-permissions.rules
|
|
||||||
index 9624ddc5e..8d3bc224a 100644
|
|
||||||
--- a/udev/12-dm-permissions.rules
|
|
||||||
+++ b/udev/12-dm-permissions.rules
|
|
||||||
@@ -14,6 +14,7 @@
|
|
||||||
# DM_UDEV_RULES_VSN - DM udev rules version
|
|
||||||
# DM_NAME - actual DM device's name
|
|
||||||
# DM_UUID - UUID set for DM device (blank if not specified)
|
|
||||||
+# DM_SUSPENDED - suspended state of DM device (0 or 1)
|
|
||||||
# DM_LV_NAME - logical volume name (not set if LVM device not present)
|
|
||||||
# DM_VG_NAME - volume group name (not set if LVM device not present)
|
|
||||||
# DM_LV_LAYER - logical volume layer (not set if LVM device not present)
|
|
||||||
diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in
|
|
||||||
index b748cc909..183693bf1 100644
|
|
||||||
--- a/udev/13-dm-disk.rules.in
|
|
||||||
+++ b/udev/13-dm-disk.rules.in
|
|
||||||
@@ -17,9 +17,9 @@ ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="dm_end"
|
|
||||||
SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
|
|
||||||
ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
|
|
||||||
|
|
||||||
-ENV{.DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
|
|
||||||
+ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
|
|
||||||
ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
|
|
||||||
-ENV{.DM_SUSPENDED}=="1", GOTO="dm_end"
|
|
||||||
+ENV{DM_SUSPENDED}=="1", GOTO="dm_end"
|
|
||||||
ENV{DM_NOSCAN}=="1", GOTO="dm_watch"
|
|
||||||
|
|
||||||
(BLKID_RULE)
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
39
SOURCES/0004-vgimportdevices-skip-lvmlockd-locking.patch
Normal file
39
SOURCES/0004-vgimportdevices-skip-lvmlockd-locking.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 074fce5c73c55e7a1547d5efff65a9f96e6db3b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 25 Oct 2021 12:11:17 -0500
|
||||||
|
Subject: [PATCH 04/54] vgimportdevices: skip lvmlockd locking
|
||||||
|
|
||||||
|
Help bootstrapping existing shared vgs into the devices file.
|
||||||
|
Reading the vg in vgimportdevices would require locking to be
|
||||||
|
started, but vgchange lockstart won't see the vg if it's not
|
||||||
|
in the devices file. The lvmlockd locks are not protecting
|
||||||
|
vg modifications so skipping them here won't be a problem.
|
||||||
|
---
|
||||||
|
tools/vgimportdevices.c | 11 +++++++++++
|
||||||
|
1 file changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
||||||
|
index 3f315f98f..2580613c4 100644
|
||||||
|
--- a/tools/vgimportdevices.c
|
||||||
|
+++ b/tools/vgimportdevices.c
|
||||||
|
@@ -172,6 +172,17 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
cmd->filter_regex_with_devices_file = 1;
|
||||||
|
cmd->create_edit_devices_file = 1;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * This helps a user bootstrap existing shared VGs into the devices
|
||||||
|
+ * file. Reading the vg to import devices requires locking, but
|
||||||
|
+ * lockstart won't find the vg before it's in the devices file.
|
||||||
|
+ * So, allow importing devices without an lvmlockd lock (in a
|
||||||
|
+ * a shared vg the vg metadata won't be updated with device ids,
|
||||||
|
+ * so the lvmlockd lock isn't protecting vg modification.)
|
||||||
|
+ */
|
||||||
|
+ cmd->lockd_gl_disable = 1;
|
||||||
|
+ cmd->lockd_vg_disable = 1;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* For each VG:
|
||||||
|
* device_id_add() each PV in the VG
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
From cc3214c24425eb283dd46435345c28e5398b3570 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 15:30:37 +0200
|
|
||||||
Subject: [PATCH 5/7] Revert "11-dm-lvm.rules: don't restore
|
|
||||||
DM_UDEV_DISABLE_OTHER_RULES_FLAG from db"
|
|
||||||
|
|
||||||
This reverts commit 2b2f11a74cd5cc05f266fd0c65f0e55eb8bafd9f.
|
|
||||||
---
|
|
||||||
udev/11-dm-lvm.rules.in | 13 ++++++++-----
|
|
||||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in
|
|
||||||
index 5b0cc5242..5f04ab329 100644
|
|
||||||
--- a/udev/11-dm-lvm.rules.in
|
|
||||||
+++ b/udev/11-dm-lvm.rules.in
|
|
||||||
@@ -26,11 +26,14 @@ IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows
|
|
||||||
# to zero any stale metadata found within the LV data area. Such stale
|
|
||||||
# metadata could cause false claim of the LV device, keeping it open etc.
|
|
||||||
#
|
|
||||||
-# If the NOSCAN flag is present, set DM_UDEV_DISABLE_OTHER_RULES_FLAG
|
|
||||||
-# so those selected rules are surely skipped.
|
|
||||||
-# We don't need to save and restore the previous of DM_UDEV_DISABLE_OTHER_RULES_FLAG,
|
|
||||||
-# that's taken care of in 10-dm.rules.
|
|
||||||
-ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
|
||||||
+# If the NOSCAN flag is present, backup selected existing flags used to
|
|
||||||
+# disable rules, then set them firmly so those selected rules are surely skipped.
|
|
||||||
+# Restore these flags once the NOSCAN flag is dropped (which is normally any
|
|
||||||
+# uevent that follows for this LV, even an artificially generated one).
|
|
||||||
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
|
||||||
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}!="1", IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_DISABLE_OTHER_RULES_FLAG_OLD"
|
|
||||||
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}!="1", ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}", \
|
|
||||||
+ ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="", ENV{DM_NOSCAN}=""
|
|
||||||
|
|
||||||
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
|
|
||||||
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
95
SOURCES/0005-hints-remove-the-cmd-hints-list.patch
Normal file
95
SOURCES/0005-hints-remove-the-cmd-hints-list.patch
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
From 00ebabfe6e1ebfceffcef335d44a6156a1c15418 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 1 Nov 2021 16:01:09 -0500
|
||||||
|
Subject: [PATCH 05/54] hints: remove the cmd hints list
|
||||||
|
|
||||||
|
which is no longer used after commit
|
||||||
|
"toollib: remove all devices list from process_each_pv"
|
||||||
|
---
|
||||||
|
lib/commands/toolcontext.c | 2 --
|
||||||
|
lib/commands/toolcontext.h | 1 -
|
||||||
|
lib/label/hints.c | 1 -
|
||||||
|
lib/label/label.c | 8 ++------
|
||||||
|
4 files changed, 2 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
|
||||||
|
index 105aecd5d..1b7170de1 100644
|
||||||
|
--- a/lib/commands/toolcontext.c
|
||||||
|
+++ b/lib/commands/toolcontext.c
|
||||||
|
@@ -1605,7 +1605,6 @@ struct cmd_context *create_config_context(void)
|
||||||
|
|
||||||
|
dm_list_init(&cmd->config_files);
|
||||||
|
dm_list_init(&cmd->tags);
|
||||||
|
- dm_list_init(&cmd->hints);
|
||||||
|
|
||||||
|
if (!_init_lvm_conf(cmd))
|
||||||
|
goto_out;
|
||||||
|
@@ -1670,7 +1669,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
|
||||||
|
dm_list_init(&cmd->formats);
|
||||||
|
dm_list_init(&cmd->segtypes);
|
||||||
|
dm_list_init(&cmd->tags);
|
||||||
|
- dm_list_init(&cmd->hints);
|
||||||
|
dm_list_init(&cmd->config_files);
|
||||||
|
label_init();
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
||||||
|
index 701b7a739..356c79f8a 100644
|
||||||
|
--- a/lib/commands/toolcontext.h
|
||||||
|
+++ b/lib/commands/toolcontext.h
|
||||||
|
@@ -206,7 +206,6 @@ struct cmd_context {
|
||||||
|
* Devices and filtering.
|
||||||
|
*/
|
||||||
|
struct dev_filter *filter;
|
||||||
|
- struct dm_list hints;
|
||||||
|
struct dm_list use_devices; /* struct dev_use for each entry in devices file */
|
||||||
|
const char *md_component_checks;
|
||||||
|
const char *search_for_devnames; /* config file setting */
|
||||||
|
diff --git a/lib/label/hints.c b/lib/label/hints.c
|
||||||
|
index 3dba9f8ec..e444a0c82 100644
|
||||||
|
--- a/lib/label/hints.c
|
||||||
|
+++ b/lib/label/hints.c
|
||||||
|
@@ -365,7 +365,6 @@ static void _unlock_hints(struct cmd_context *cmd)
|
||||||
|
|
||||||
|
void hints_exit(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
- free_hints(&cmd->hints);
|
||||||
|
if (_hints_fd == -1)
|
||||||
|
return;
|
||||||
|
_unlock_hints(cmd);
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index 3cd912270..479a5037a 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -1207,8 +1207,6 @@ int label_scan(struct cmd_context *cmd)
|
||||||
|
(unsigned long long)want_size_kb);
|
||||||
|
}
|
||||||
|
|
||||||
|
- dm_list_init(&cmd->hints);
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* If we're using hints to limit which devs we scanned, verify
|
||||||
|
* that those hints were valid, and if not we need to scan the
|
||||||
|
@@ -1220,18 +1218,16 @@ int label_scan(struct cmd_context *cmd)
|
||||||
|
_scan_list(cmd, cmd->filter, &all_devs, 0, NULL);
|
||||||
|
/* scan_devs are the devs that have been scanned */
|
||||||
|
dm_list_splice(&scan_devs, &all_devs);
|
||||||
|
- free_hints(&hints_list);
|
||||||
|
using_hints = 0;
|
||||||
|
create_hints = 0;
|
||||||
|
/* invalid hints means a new dev probably appeared and
|
||||||
|
we should search for any missing pvids again. */
|
||||||
|
unlink_searched_devnames(cmd);
|
||||||
|
- } else {
|
||||||
|
- /* The hints may be used by another device iteration. */
|
||||||
|
- dm_list_splice(&cmd->hints, &hints_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ free_hints(&hints_list);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Check if the devices_file content is up to date and
|
||||||
|
* if not update it.
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,49 +0,0 @@
|
|||||||
From 147498a07fd4e7dd0698b443bbcf15cfe6a6e104 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 15:30:48 +0200
|
|
||||||
Subject: [PATCH 6/7] Revert "10-dm-rules: don't restore
|
|
||||||
DM_UDEV_DISABLE_OTHER_RULES_FLAG from db"
|
|
||||||
|
|
||||||
This reverts commit f98d020eadafe7d8db7bec1f5a26915615e5a6a9.
|
|
||||||
---
|
|
||||||
udev/10-dm.rules.in | 12 ++----------
|
|
||||||
1 file changed, 2 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in
|
|
||||||
index 29fe71527..2c6903da7 100644
|
|
||||||
--- a/udev/10-dm.rules.in
|
|
||||||
+++ b/udev/10-dm.rules.in
|
|
||||||
@@ -53,14 +53,7 @@ OPTIONS+="db_persist"
|
|
||||||
# These flags are encoded in DM_COOKIE variable that was introduced in
|
|
||||||
# kernel version 2.6.31. Therefore, we can use this feature with
|
|
||||||
# kernels >= 2.6.31 only. Cookie is not decoded for remove event.
|
|
||||||
-ENV{DM_COOKIE}!="?*", GOTO="dm_no_cookie"
|
|
||||||
-IMPORT{program}="(DM_EXEC)/dmsetup udevflags $env{DM_COOKIE}"
|
|
||||||
-
|
|
||||||
-# Store the original flag from the cookie as DM_COOKIE_DISABLE_OTHER_RULES_FLAG
|
|
||||||
-# in the udev db. DM_UDEV_DISABLE_OTHER_RULES_FLAG will be or'd with other
|
|
||||||
-# conditions for use by upper, non-dm layers.
|
|
||||||
-ENV{DM_COOKIE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}"
|
|
||||||
-LABEL="dm_no_cookie"
|
|
||||||
+ENV{DM_COOKIE}=="?*", IMPORT{program}="(DM_EXEC)/dmsetup udevflags $env{DM_COOKIE}"
|
|
||||||
|
|
||||||
# There is no cookie set nor any flags encoded in events not originating
|
|
||||||
# in libdevmapper so we need to detect this and try to behave correctly.
|
|
||||||
@@ -70,13 +63,12 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_do
|
|
||||||
IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG"
|
|
||||||
IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG"
|
|
||||||
IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG"
|
|
||||||
-IMPORT{db}="DM_COOKIE_DISABLE_OTHER_RULES_FLAG"
|
|
||||||
+IMPORT{db}="DM_UDEV_DISABLE_OTHER_RULES_FLAG"
|
|
||||||
IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG"
|
|
||||||
IMPORT{db}="DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG"
|
|
||||||
IMPORT{db}="DM_UDEV_PRIMARY_SOURCE_FLAG"
|
|
||||||
IMPORT{db}="DM_UDEV_FLAG7"
|
|
||||||
IMPORT{db}="DM_UDEV_RULES_VSN"
|
|
||||||
-ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_COOKIE_DISABLE_OTHER_RULES_FLAG}"
|
|
||||||
LABEL="dm_flags_done"
|
|
||||||
|
|
||||||
# If DISK_RO is set, it's an uevent that changes the ro attribute of the device.
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
422
SOURCES/0006-filter-sysfs-skip-when-device-id-is-set.patch
Normal file
422
SOURCES/0006-filter-sysfs-skip-when-device-id-is-set.patch
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
From f73be4480a5dd104a77e3ef84d7dcc80b834e593 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 2 Nov 2021 15:42:26 -0500
|
||||||
|
Subject: [PATCH 06/54] filter-sysfs: skip when device id is set
|
||||||
|
|
||||||
|
When a device id is set for a device, using an idtype other
|
||||||
|
than devname, it means that sysfs has been used with the device
|
||||||
|
to match the device id. So, checking for a sysfs entry for the
|
||||||
|
device in filter-sysfs is redundant. For any other cases not
|
||||||
|
covered by this (e.g. devname ids), have filter-sysfs simply
|
||||||
|
stat /sys/dev/block/major:minor to test if the device exists
|
||||||
|
in sysfs.
|
||||||
|
|
||||||
|
The extensive processing done by filter-sysfs init is removed.
|
||||||
|
It was taking an immense amount of time with many devices, e.g.
|
||||||
|
. 1024 PVs in 520 VGs
|
||||||
|
. 520 concurrent vgchange -ay <vgname> commands
|
||||||
|
. vgchange scans only PVs in the named VG (based on pvs_online
|
||||||
|
files from a pending patch)
|
||||||
|
|
||||||
|
A large number of the vgchange commands were taking over 1 min,
|
||||||
|
and nearly half of that time was used by filter-sysfs init.
|
||||||
|
With this patch, the vgchange commands take about half the time.
|
||||||
|
---
|
||||||
|
lib/commands/toolcontext.c | 24 ++-
|
||||||
|
lib/filters/filter-sysfs.c | 296 +++----------------------------------
|
||||||
|
2 files changed, 32 insertions(+), 288 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
|
||||||
|
index 1b7170de1..a0c78ddd6 100644
|
||||||
|
--- a/lib/commands/toolcontext.c
|
||||||
|
+++ b/lib/commands/toolcontext.c
|
||||||
|
@@ -1143,19 +1143,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||||
|
* Update MAX_FILTERS definition above when adding new filters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * sysfs filter. Only available on 2.6 kernels. Non-critical.
|
||||||
|
- * Listed first because it's very efficient at eliminating
|
||||||
|
- * unavailable devices.
|
||||||
|
- *
|
||||||
|
- * TODO: I suspect that using the lvm_type and device_id
|
||||||
|
- * filters before this one may be more efficient.
|
||||||
|
- */
|
||||||
|
- if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
|
||||||
|
- if ((filters[nr_filt] = sysfs_filter_create()))
|
||||||
|
- nr_filt++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* internal filter used by command processing. */
|
||||||
|
if (!(filters[nr_filt] = internal_filter_create())) {
|
||||||
|
log_error("Failed to create internal device filter");
|
||||||
|
@@ -1195,6 +1182,17 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||||
|
}
|
||||||
|
nr_filt++;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * sysfs filter. Only available on 2.6 kernels. Non-critical.
|
||||||
|
+ * Eliminates unavailable devices.
|
||||||
|
+ * TODO: this may be unnecessary now with device ids
|
||||||
|
+ * (currently not used for devs match to device id using syfs)
|
||||||
|
+ */
|
||||||
|
+ if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
|
||||||
|
+ if ((filters[nr_filt] = sysfs_filter_create()))
|
||||||
|
+ nr_filt++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* usable device filter. Required. */
|
||||||
|
if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types, FILTER_MODE_NO_LVMETAD))) {
|
||||||
|
log_error("Failed to create usabled device filter");
|
||||||
|
diff --git a/lib/filters/filter-sysfs.c b/lib/filters/filter-sysfs.c
|
||||||
|
index 32ac324dd..672211057 100644
|
||||||
|
--- a/lib/filters/filter-sysfs.c
|
||||||
|
+++ b/lib/filters/filter-sysfs.c
|
||||||
|
@@ -17,288 +17,49 @@
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
-#include <sys/sysmacros.h>
|
||||||
|
-#include <dirent.h>
|
||||||
|
-
|
||||||
|
-static int _locate_sysfs_blocks(const char *sysfs_dir, char *path, size_t len,
|
||||||
|
- unsigned *sysfs_depth)
|
||||||
|
+static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||||
|
{
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+ const char *sysfs_dir;
|
||||||
|
struct stat info;
|
||||||
|
- unsigned i;
|
||||||
|
- static const struct dir_class {
|
||||||
|
- const char path[32];
|
||||||
|
- int depth;
|
||||||
|
- } classes[] = {
|
||||||
|
- /*
|
||||||
|
- * unified classification directory for all kernel subsystems
|
||||||
|
- *
|
||||||
|
- * /sys/subsystem/block/devices
|
||||||
|
- * |-- sda -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
|
||||||
|
- * |-- sda1 -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||||
|
- * `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||||
|
- *
|
||||||
|
- */
|
||||||
|
- { "subsystem/block/devices", 0 },
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * block subsystem as a class
|
||||||
|
- *
|
||||||
|
- * /sys/class/block
|
||||||
|
- * |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
|
||||||
|
- * |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||||
|
- * `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||||
|
- *
|
||||||
|
- */
|
||||||
|
- { "class/block", 0 },
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * old block subsystem layout with nested directories
|
||||||
|
- *
|
||||||
|
- * /sys/block/
|
||||||
|
- * |-- sda
|
||||||
|
- * | |-- capability
|
||||||
|
- * | |-- dev
|
||||||
|
- * ...
|
||||||
|
- * | |-- sda1
|
||||||
|
- * | | |-- dev
|
||||||
|
- * ...
|
||||||
|
- * |
|
||||||
|
- * `-- sr0
|
||||||
|
- * |-- capability
|
||||||
|
- * |-- dev
|
||||||
|
- * ...
|
||||||
|
- *
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- { "block", 1 }
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- for (i = 0; i < DM_ARRAY_SIZE(classes); ++i)
|
||||||
|
- if ((dm_snprintf(path, len, "%s%s", sysfs_dir, classes[i].path) >= 0) &&
|
||||||
|
- (stat(path, &info) == 0)) {
|
||||||
|
- *sysfs_depth = classes[i].depth;
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*----------------------------------------------------------------
|
||||||
|
- * We need to store a set of dev_t.
|
||||||
|
- *--------------------------------------------------------------*/
|
||||||
|
-struct entry {
|
||||||
|
- struct entry *next;
|
||||||
|
- dev_t dev;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-#define SET_BUCKETS 64
|
||||||
|
-struct dev_set {
|
||||||
|
- struct dm_pool *mem;
|
||||||
|
- const char *sys_block;
|
||||||
|
- unsigned sysfs_depth;
|
||||||
|
- int initialised;
|
||||||
|
- struct entry *slots[SET_BUCKETS];
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static struct dev_set *_dev_set_create(struct dm_pool *mem,
|
||||||
|
- const char *sys_block,
|
||||||
|
- unsigned sysfs_depth)
|
||||||
|
-{
|
||||||
|
- struct dev_set *ds;
|
||||||
|
-
|
||||||
|
- if (!(ds = dm_pool_zalloc(mem, sizeof(*ds))))
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- ds->mem = mem;
|
||||||
|
- if (!(ds->sys_block = dm_pool_strdup(mem, sys_block)))
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- ds->sysfs_depth = sysfs_depth;
|
||||||
|
- ds->initialised = 0;
|
||||||
|
-
|
||||||
|
- return ds;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static unsigned _hash_dev(dev_t dev)
|
||||||
|
-{
|
||||||
|
- return (major(dev) ^ minor(dev)) & (SET_BUCKETS - 1);
|
||||||
|
-}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Doesn't check that the set already contains dev.
|
||||||
|
- */
|
||||||
|
-static int _set_insert(struct dev_set *ds, dev_t dev)
|
||||||
|
-{
|
||||||
|
- struct entry *e;
|
||||||
|
- unsigned h = _hash_dev(dev);
|
||||||
|
-
|
||||||
|
- if (!(e = dm_pool_alloc(ds->mem, sizeof(*e))))
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- e->next = ds->slots[h];
|
||||||
|
- e->dev = dev;
|
||||||
|
- ds->slots[h] = e;
|
||||||
|
-
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
+ dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
|
||||||
|
|
||||||
|
-static int _set_lookup(struct dev_set *ds, dev_t dev)
|
||||||
|
-{
|
||||||
|
- unsigned h = _hash_dev(dev);
|
||||||
|
- struct entry *e;
|
||||||
|
+ /*
|
||||||
|
+ * Any kind of device id other than devname has been set
|
||||||
|
+ * using sysfs so we know that sysfs info exists for dev.
|
||||||
|
+ */
|
||||||
|
+ if (dev->id && dev->id->idtype && (dev->id->idtype != DEV_ID_TYPE_DEVNAME))
|
||||||
|
+ return 1;
|
||||||
|
|
||||||
|
- for (e = ds->slots[h]; e; e = e->next)
|
||||||
|
- if (e->dev == dev)
|
||||||
|
+ sysfs_dir = dm_sysfs_dir();
|
||||||
|
+ if (sysfs_dir && *sysfs_dir) {
|
||||||
|
+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
|
||||||
|
+ sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) {
|
||||||
|
+ log_debug("failed to create sysfs path");
|
||||||
|
return 1;
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*----------------------------------------------------------------
|
||||||
|
- * filter methods
|
||||||
|
- *--------------------------------------------------------------*/
|
||||||
|
-static int _parse_dev(const char *file, FILE *fp, dev_t *result)
|
||||||
|
-{
|
||||||
|
- unsigned major, minor;
|
||||||
|
- char buffer[64];
|
||||||
|
-
|
||||||
|
- if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||||
|
- log_error("Empty sysfs device file: %s", file);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (sscanf(buffer, "%u:%u", &major, &minor) != 2) {
|
||||||
|
- log_error("Incorrect format for sysfs device file: %s.", file);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- *result = makedev(major, minor);
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int _read_dev(const char *file, dev_t *result)
|
||||||
|
-{
|
||||||
|
- int r;
|
||||||
|
- FILE *fp;
|
||||||
|
-
|
||||||
|
- if (!(fp = fopen(file, "r"))) {
|
||||||
|
- log_sys_error("fopen", file);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- r = _parse_dev(file, fp, result);
|
||||||
|
-
|
||||||
|
- if (fclose(fp))
|
||||||
|
- log_sys_error("fclose", file);
|
||||||
|
-
|
||||||
|
- return r;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * Recurse through sysfs directories, inserting any devs found.
|
||||||
|
- */
|
||||||
|
-static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
|
||||||
|
-{
|
||||||
|
- struct dirent *d;
|
||||||
|
- DIR *dr;
|
||||||
|
- struct stat info;
|
||||||
|
- char path[PATH_MAX];
|
||||||
|
- char file[PATH_MAX];
|
||||||
|
- dev_t dev = { 0 };
|
||||||
|
- int r = 1;
|
||||||
|
-
|
||||||
|
- if (!(dr = opendir(dir))) {
|
||||||
|
- log_sys_error("opendir", dir);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- while ((d = readdir(dr))) {
|
||||||
|
- if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
|
||||||
|
- d->d_name) < 0) {
|
||||||
|
- log_warn("WARNING: sysfs path name too long: %s in %s.",
|
||||||
|
- d->d_name, dir);
|
||||||
|
- continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* devices have a "dev" file */
|
||||||
|
- if (dm_snprintf(file, sizeof(file), "%s/dev", path) < 0) {
|
||||||
|
- log_warn("WARNING: sysfs path name too long: %s in %s.",
|
||||||
|
- d->d_name, dir);
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!stat(file, &info)) {
|
||||||
|
- /* recurse if we found a device and expect subdirs */
|
||||||
|
- if (sysfs_depth)
|
||||||
|
- _read_devs(ds, path, sysfs_depth - 1);
|
||||||
|
-
|
||||||
|
- /* add the device we have found */
|
||||||
|
- if (_read_dev(file, &dev))
|
||||||
|
- _set_insert(ds, dev);
|
||||||
|
+ if (lstat(path, &info)) {
|
||||||
|
+ log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
|
||||||
|
+ dev->filtered_flags |= DEV_FILTERED_SYSFS;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (closedir(dr))
|
||||||
|
- log_sys_debug("closedir", dir);
|
||||||
|
-
|
||||||
|
- return r;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int _init_devs(struct dev_set *ds)
|
||||||
|
-{
|
||||||
|
- if (!_read_devs(ds, ds->sys_block, ds->sysfs_depth)) {
|
||||||
|
- ds->initialised = -1;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ds->initialised = 1;
|
||||||
|
-
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||||
|
-{
|
||||||
|
- struct dev_set *ds = (struct dev_set *) f->private;
|
||||||
|
-
|
||||||
|
- dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
|
||||||
|
-
|
||||||
|
- if (!ds->initialised)
|
||||||
|
- _init_devs(ds);
|
||||||
|
-
|
||||||
|
- /* Pass through if initialisation failed */
|
||||||
|
- if (ds->initialised != 1)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
- if (!_set_lookup(ds, dev->dev)) {
|
||||||
|
- log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
|
||||||
|
- dev->filtered_flags |= DEV_FILTERED_SYSFS;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _destroy(struct dev_filter *f)
|
||||||
|
{
|
||||||
|
- struct dev_set *ds = (struct dev_set *) f->private;
|
||||||
|
-
|
||||||
|
if (f->use_count)
|
||||||
|
log_error(INTERNAL_ERROR "Destroying sysfs filter while in use %u times.", f->use_count);
|
||||||
|
-
|
||||||
|
- dm_pool_destroy(ds->mem);
|
||||||
|
+ free(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dev_filter *sysfs_filter_create(void)
|
||||||
|
{
|
||||||
|
const char *sysfs_dir = dm_sysfs_dir();
|
||||||
|
- char sys_block[PATH_MAX];
|
||||||
|
- unsigned sysfs_depth;
|
||||||
|
- struct dm_pool *mem;
|
||||||
|
- struct dev_set *ds;
|
||||||
|
struct dev_filter *f;
|
||||||
|
|
||||||
|
if (!*sysfs_dir) {
|
||||||
|
@@ -306,26 +67,12 @@ struct dev_filter *sysfs_filter_create(void)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!_locate_sysfs_blocks(sysfs_dir, sys_block, sizeof(sys_block), &sysfs_depth))
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- if (!(mem = dm_pool_create("sysfs", 256))) {
|
||||||
|
- log_error("sysfs pool creation failed");
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!(ds = _dev_set_create(mem, sys_block, sysfs_depth))) {
|
||||||
|
- log_error("sysfs dev_set creation failed");
|
||||||
|
- goto bad;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!(f = dm_pool_zalloc(mem, sizeof(*f))))
|
||||||
|
+ if (!(f = zalloc(sizeof(*f))))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
f->passes_filter = _accept_p;
|
||||||
|
f->destroy = _destroy;
|
||||||
|
f->use_count = 0;
|
||||||
|
- f->private = ds;
|
||||||
|
f->name = "sysfs";
|
||||||
|
|
||||||
|
log_debug_devs("Sysfs filter initialised.");
|
||||||
|
@@ -333,7 +80,6 @@ struct dev_filter *sysfs_filter_create(void)
|
||||||
|
return f;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
- dm_pool_destroy(mem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
From 7d1b418ad8efa0c059197238ea3fcbf3f659d909 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Thu, 16 May 2024 15:34:28 +0200
|
|
||||||
Subject: [PATCH 7/7] WHATS_NEW: update
|
|
||||||
|
|
||||||
---
|
|
||||||
WHATS_NEW | 1 +
|
|
||||||
WHATS_NEW_DM | 4 ++++
|
|
||||||
2 files changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
|
||||||
index c7de3914a..1d56f8675 100644
|
|
||||||
--- a/WHATS_NEW
|
|
||||||
+++ b/WHATS_NEW
|
|
||||||
@@ -1,5 +1,6 @@
|
|
||||||
Version 2.03.25 -
|
|
||||||
==================
|
|
||||||
+ Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it.
|
|
||||||
|
|
||||||
Version 2.03.24 - 16th May 2024
|
|
||||||
===============================
|
|
||||||
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
|
||||||
index a2277c53b..da8df6914 100644
|
|
||||||
--- a/WHATS_NEW_DM
|
|
||||||
+++ b/WHATS_NEW_DM
|
|
||||||
@@ -1,5 +1,9 @@
|
|
||||||
Version 1.02.199 -
|
|
||||||
===================
|
|
||||||
+ Revert Increase DM_UDEV_RULES_VSN to 3 to indicate changed udev rules.
|
|
||||||
+ Revert Rename DM_NOSCAN to .DM_NOSCAN so it's not stored in udev db.
|
|
||||||
+ Revert Rename DM_SUSPENDED to .DM_SUSPENDED so it's not stored in udev db.
|
|
||||||
+ Revert Do not import DM_UDEV_DISABLE_OTHER_RULES_FLAG from db in 10-dm-disk.rules.
|
|
||||||
|
|
||||||
Version 1.02.198 - 16th May 2024
|
|
||||||
================================
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
61
SOURCES/0007-lvmdevices-increase-open-file-limit.patch
Normal file
61
SOURCES/0007-lvmdevices-increase-open-file-limit.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
From f732f3d53faee3732d0f4a666c378709e6c2f5e9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 29 Oct 2021 14:49:36 -0500
|
||||||
|
Subject: [PATCH 07/54] lvmdevices: increase open file limit
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/label/label.c | 4 ++--
|
||||||
|
lib/label/label.h | 2 ++
|
||||||
|
tools/lvmdevices.c | 3 +++
|
||||||
|
3 files changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index 479a5037a..9fac3e464 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -891,7 +891,7 @@ static int _setup_bcache(void)
|
||||||
|
|
||||||
|
#define BASE_FD_COUNT 32 /* Number of open files we want apart from devs */
|
||||||
|
|
||||||
|
-static void _prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
|
||||||
|
+void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PRLIMIT
|
||||||
|
struct rlimit old = { 0 }, new;
|
||||||
|
@@ -1165,7 +1165,7 @@ int label_scan(struct cmd_context *cmd)
|
||||||
|
* which we want to keep open) is higher than the current
|
||||||
|
* soft limit.
|
||||||
|
*/
|
||||||
|
- _prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
|
||||||
|
+ prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the main scan.
|
||||||
|
diff --git a/lib/label/label.h b/lib/label/label.h
|
||||||
|
index 8b510eb79..34563efd0 100644
|
||||||
|
--- a/lib/label/label.h
|
||||||
|
+++ b/lib/label/label.h
|
||||||
|
@@ -134,4 +134,6 @@ void dev_invalidate(struct device *dev);
|
||||||
|
void dev_set_last_byte(struct device *dev, uint64_t offset);
|
||||||
|
void dev_unset_last_byte(struct device *dev);
|
||||||
|
|
||||||
|
+void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||||
|
index 8d9634848..3f104f7de 100644
|
||||||
|
--- a/tools/lvmdevices.c
|
||||||
|
+++ b/tools/lvmdevices.c
|
||||||
|
@@ -176,6 +176,9 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
log_error("Failed to read the devices file.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ prepare_open_file_limit(cmd, dm_list_size(&cmd->use_devices));
|
||||||
|
+
|
||||||
|
dev_cache_scan(cmd);
|
||||||
|
device_ids_match(cmd);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,578 +0,0 @@
|
|||||||
From 16af82a5afe337cc3b0db3eaed0372e130b049ed Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Tue, 23 Apr 2024 17:08:26 -0500
|
|
||||||
Subject: [PATCH 08/13] Allow system.devices to be automatically created on
|
|
||||||
first boot
|
|
||||||
|
|
||||||
An OS installer can create system.devices for the system and
|
|
||||||
disks, but an OS image cannot create the system-specific
|
|
||||||
system.devices. The OS image can instead configure the
|
|
||||||
image so that lvm will create system.devices on first boot.
|
|
||||||
|
|
||||||
Image preparation steps to enable auto creation of system.devices:
|
|
||||||
- create empty file /etc/lvm/devices/auto-import-rootvg
|
|
||||||
- remove any existing /etc/lvm/devices/system.devices
|
|
||||||
- enable lvm-devices-import.path
|
|
||||||
- enable lvm-devices-import.service
|
|
||||||
|
|
||||||
On first boot of the prepared image:
|
|
||||||
- udev triggers vgchange -aay --autoactivation event <rootvg>
|
|
||||||
- vgchange activates LVs in the root VG
|
|
||||||
- vgchange finds the file /etc/lvm/devices/auto-import-rootvg,
|
|
||||||
and no /etc/lvm/devices/system.devices, so it creates
|
|
||||||
/run/lvm/lvm-devices-import
|
|
||||||
- lvm-devices-import.path is run when /run/lvm/lvm-devices-import
|
|
||||||
appears, and triggers lvm-devices-import.service
|
|
||||||
- lvm-devices-import.service runs vgimportdevices --rootvg --auto
|
|
||||||
- vgimportdevices finds /etc/lvm/devices/auto-import-rootvg,
|
|
||||||
and no system.devices, so it creates system.devices containing
|
|
||||||
PVs in the root VG, and removes /etc/lvm/devices/auto-import-rootvg
|
|
||||||
and /run/lvm/lvm-devices-import
|
|
||||||
|
|
||||||
Run directly, vgimportdevices --rootvg (without --auto), will create
|
|
||||||
a new system.devices for the root VG, or will add devices for the
|
|
||||||
root VG to an existing system.devices.
|
|
||||||
|
|
||||||
(cherry picked from commit c609dedc2f035f770b5f645c4695924abf15c2ca)
|
|
||||||
(cherry picked from commit 3321a669d8f2df99df9d6dcd4ebb2b4d30731c7a)
|
|
||||||
---
|
|
||||||
lib/commands/toolcontext.h | 1 +
|
|
||||||
lib/config/defaults.h | 2 +
|
|
||||||
lib/device/device_id.c | 5 +-
|
|
||||||
scripts/lvm-devices-import.path | 12 +++
|
|
||||||
scripts/lvm-devices-import.service | 12 +++
|
|
||||||
tools/args.h | 11 ++
|
|
||||||
tools/command-lines.in | 5 +
|
|
||||||
tools/pvscan.c | 4 +-
|
|
||||||
tools/tools.h | 2 +-
|
|
||||||
tools/vgchange.c | 155 ++++++++++++++++++++++++++++-
|
|
||||||
tools/vgimportdevices.c | 114 ++++++++++++++++++++-
|
|
||||||
11 files changed, 315 insertions(+), 8 deletions(-)
|
|
||||||
create mode 100644 scripts/lvm-devices-import.path
|
|
||||||
create mode 100644 scripts/lvm-devices-import.service
|
|
||||||
|
|
||||||
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
|
||||||
index fec0a52cf..043afbf76 100644
|
|
||||||
--- a/lib/commands/toolcontext.h
|
|
||||||
+++ b/lib/commands/toolcontext.h
|
|
||||||
@@ -217,6 +217,7 @@ struct cmd_context {
|
|
||||||
unsigned device_ids_check_hostname:1;
|
|
||||||
unsigned device_ids_refresh_trigger:1;
|
|
||||||
unsigned device_ids_invalid:1;
|
|
||||||
+ unsigned device_ids_auto_import:1;
|
|
||||||
unsigned get_vgname_from_options:1; /* used by lvconvert */
|
|
||||||
|
|
||||||
/*
|
|
||||||
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
|
|
||||||
index ed0c4f404..efe36d1fa 100644
|
|
||||||
--- a/lib/config/defaults.h
|
|
||||||
+++ b/lib/config/defaults.h
|
|
||||||
@@ -337,6 +337,8 @@
|
|
||||||
#define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online"
|
|
||||||
#define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup"
|
|
||||||
|
|
||||||
+#define DEVICES_IMPORT_PATH DEFAULT_RUN_DIR "/lvm-devices-import"
|
|
||||||
+
|
|
||||||
#define DEFAULT_DEVICE_ID_SYSFS_DIR "/sys/" /* trailing / to match dm_sysfs_dir() */
|
|
||||||
|
|
||||||
#define DEFAULT_DEVICESFILE_BACKUP_LIMIT 50
|
|
||||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
|
||||||
index 2b183810a..1ce7927ed 100644
|
|
||||||
--- a/lib/device/device_id.c
|
|
||||||
+++ b/lib/device/device_id.c
|
|
||||||
@@ -1726,9 +1726,10 @@ int device_ids_write(struct cmd_context *cmd)
|
|
||||||
|
|
||||||
if ((fc_bytes = snprintf(fc, sizeof(fc),
|
|
||||||
"# LVM uses devices listed in this file.\n" \
|
|
||||||
- "# Created by LVM command %s pid %d at %s" \
|
|
||||||
+ "# Created by LVM command %s%s pid %d at %s" \
|
|
||||||
"# HASH=%u\n",
|
|
||||||
- cmd->name, getpid(), ctime(&t), hash)) < 0) {
|
|
||||||
+ cmd->name, cmd->device_ids_auto_import ? " (auto)" : "",
|
|
||||||
+ getpid(), ctime(&t), hash)) < 0) {
|
|
||||||
log_error("Failed to write buffer for devices file content.");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
diff --git a/scripts/lvm-devices-import.path b/scripts/lvm-devices-import.path
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..bcf0dcd4c
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/scripts/lvm-devices-import.path
|
|
||||||
@@ -0,0 +1,12 @@
|
|
||||||
+[Unit]
|
|
||||||
+Description=lvm-devices-import to create system.devices
|
|
||||||
+
|
|
||||||
+# /run/lvm/lvm-devices-import created by vgchange -aay <rootvg>
|
|
||||||
+
|
|
||||||
+[Path]
|
|
||||||
+PathExists=/run/lvm/lvm-devices-import
|
|
||||||
+Unit=lvm-devices-import.service
|
|
||||||
+ConditionPathExists=!/etc/lvm/devices/system.devices
|
|
||||||
+
|
|
||||||
+[Install]
|
|
||||||
+WantedBy=multi-user.target
|
|
||||||
diff --git a/scripts/lvm-devices-import.service b/scripts/lvm-devices-import.service
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..9d3bda2ee
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/scripts/lvm-devices-import.service
|
|
||||||
@@ -0,0 +1,12 @@
|
|
||||||
+[Unit]
|
|
||||||
+Description=Create lvm system.devices
|
|
||||||
+
|
|
||||||
+[Service]
|
|
||||||
+Type=oneshot
|
|
||||||
+RemainAfterExit=no
|
|
||||||
+ExecStart=/usr/sbin/vgimportdevices --rootvg --auto
|
|
||||||
+ConditionPathExists=!/etc/lvm/devices/system.devices
|
|
||||||
+
|
|
||||||
+[Install]
|
|
||||||
+WantedBy=multi-user.target
|
|
||||||
+
|
|
||||||
diff --git a/tools/args.h b/tools/args.h
|
|
||||||
index 09b2ad551..ed0fb9620 100644
|
|
||||||
--- a/tools/args.h
|
|
||||||
+++ b/tools/args.h
|
|
||||||
@@ -94,6 +94,14 @@ arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0,
|
|
||||||
"which does not contain any newer settings for which LVM would\n"
|
|
||||||
"issue a warning message when checking the configuration.\n")
|
|
||||||
|
|
||||||
+arg(auto_ARG, '\0', "auto", 0, 0, 0,
|
|
||||||
+ "This option is used when automatically importing devices for the root VG.\n"
|
|
||||||
+ "The auto import is intended to be done once, on first boot, to create an\n"
|
|
||||||
+ "initial system.devices file for the root VG.\n"
|
|
||||||
+ "When this option is used, the vgimportdevices --rootvg command does nothing\n"
|
|
||||||
+ "if system.devices exists, or the file auto-import-rootvg does not exist\n"
|
|
||||||
+ "(both in the /etc/lvm/devices/ directory.)\n")
|
|
||||||
+
|
|
||||||
arg(autoactivation_ARG, '\0', "autoactivation", string_VAL, 0, 0,
|
|
||||||
"Specify if autoactivation is being used from an event.\n"
|
|
||||||
"This allows the command to apply settings that are specific\n"
|
|
||||||
@@ -754,6 +762,9 @@ arg(resync_ARG, '\0', "resync", 0, 0, 0,
|
|
||||||
"which the LV is without a complete redundant copy of the data.\n"
|
|
||||||
"See \\fBlvmraid\\fP(7) for more information.\n")
|
|
||||||
|
|
||||||
+arg(rootvg_ARG, '\0', "rootvg", 0, 0, 0,
|
|
||||||
+ "Import devices used for the root VG.\n")
|
|
||||||
+
|
|
||||||
arg(rows_ARG, '\0', "rows", 0, 0, 0,
|
|
||||||
"Output columns as rows.\n")
|
|
||||||
|
|
||||||
diff --git a/tools/command-lines.in b/tools/command-lines.in
|
|
||||||
index 1c728afa0..3ad5d3c46 100644
|
|
||||||
--- a/tools/command-lines.in
|
|
||||||
+++ b/tools/command-lines.in
|
|
||||||
@@ -1911,6 +1911,11 @@ OO: --foreign, --reportformat ReportFmt
|
|
||||||
ID: vgimportdevices_all
|
|
||||||
DESC: Add devices from all accessible VGs to the devices file.
|
|
||||||
|
|
||||||
+vgimportdevices --rootvg
|
|
||||||
+OO: --auto, --reportformat ReportFmt
|
|
||||||
+ID: vgimportdevices_root
|
|
||||||
+DESC: Add devices from root VG to the devices file.
|
|
||||||
+
|
|
||||||
---
|
|
||||||
|
|
||||||
vgmerge VG VG
|
|
||||||
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
|
||||||
index f88e1b751..0a9cb59df 100644
|
|
||||||
--- a/tools/pvscan.c
|
|
||||||
+++ b/tools/pvscan.c
|
|
||||||
@@ -495,7 +495,7 @@ static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name,
|
|
||||||
|
|
||||||
log_debug("pvscan autoactivating VG %s.", vg_name);
|
|
||||||
|
|
||||||
- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) {
|
|
||||||
+ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) {
|
|
||||||
log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name);
|
|
||||||
pp->activate_errors++;
|
|
||||||
}
|
|
||||||
@@ -755,7 +755,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
|
|
||||||
|
|
||||||
log_debug("pvscan autoactivating VG %s.", vgname);
|
|
||||||
|
|
||||||
- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) {
|
|
||||||
+ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) {
|
|
||||||
log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name);
|
|
||||||
pp->activate_errors++;
|
|
||||||
}
|
|
||||||
diff --git a/tools/tools.h b/tools/tools.h
|
|
||||||
index f4a0c94d7..58708c695 100644
|
|
||||||
--- a/tools/tools.h
|
|
||||||
+++ b/tools/tools.h
|
|
||||||
@@ -164,7 +164,7 @@ int mirror_remove_missing(struct cmd_context *cmd,
|
|
||||||
|
|
||||||
|
|
||||||
int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
|
||||||
- activation_change_t activate, int vg_complete_to_activate);
|
|
||||||
+ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid);
|
|
||||||
|
|
||||||
int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg);
|
|
||||||
|
|
||||||
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
|
||||||
index 378ded16e..2004d6e92 100644
|
|
||||||
--- a/tools/vgchange.c
|
|
||||||
+++ b/tools/vgchange.c
|
|
||||||
@@ -16,11 +16,14 @@
|
|
||||||
#include "tools.h"
|
|
||||||
#include "lib/device/device_id.h"
|
|
||||||
#include "lib/label/hints.h"
|
|
||||||
+#include "device_mapper/misc/dm-ioctl.h"
|
|
||||||
+#include <mntent.h>
|
|
||||||
|
|
||||||
struct vgchange_params {
|
|
||||||
int lock_start_count;
|
|
||||||
unsigned int lock_start_sanlock : 1;
|
|
||||||
unsigned int vg_complete_to_activate : 1;
|
|
||||||
+ char *root_dm_uuid; /* dm uuid of LV under root fs */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -197,7 +200,7 @@ int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg
|
|
||||||
}
|
|
||||||
|
|
||||||
int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
|
||||||
- activation_change_t activate, int vg_complete_to_activate)
|
|
||||||
+ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid)
|
|
||||||
{
|
|
||||||
int lv_open, active, monitored = 0, r = 1;
|
|
||||||
const struct lv_list *lvl;
|
|
||||||
@@ -279,6 +282,43 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Possibly trigger auto-generation of system.devices:
|
|
||||||
+ * - if root_dm_uuid contains vg->id, and
|
|
||||||
+ * - /etc/lvm/devices/auto-import-rootvg exists, and
|
|
||||||
+ * - /etc/lvm/devices/system.devices does not exist, then
|
|
||||||
+ * - create /run/lvm/lvm-devices-import to
|
|
||||||
+ * trigger lvm-devices-import.path and .service
|
|
||||||
+ * - lvm-devices-import will run vgimportdevices --rootvg
|
|
||||||
+ * to create system.devices
|
|
||||||
+ */
|
|
||||||
+ if (root_dm_uuid) {
|
|
||||||
+ char path[PATH_MAX];
|
|
||||||
+ struct stat info;
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
+ if (memcmp(root_dm_uuid + 4, &vg->id, ID_LEN))
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ if (cmd->enable_devices_file || devices_file_exists(cmd))
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ if (stat(path, &info) < 0)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ log_debug("Found %s creating %s", path, DEVICES_IMPORT_PATH);
|
|
||||||
+
|
|
||||||
+ if (!(fp = fopen(DEVICES_IMPORT_PATH, "w"))) {
|
|
||||||
+ log_debug("failed to create %s", DEVICES_IMPORT_PATH);
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ if (fclose(fp))
|
|
||||||
+ stack;
|
|
||||||
+ }
|
|
||||||
+out:
|
|
||||||
/* Print message only if there was not found a missing VG */
|
|
||||||
log_print_unless_silent("%d logical volume(s) in volume group \"%s\" now active",
|
|
||||||
lvs_in_vg_activated(vg), vg->name);
|
|
||||||
@@ -714,7 +754,7 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
|
||||||
|
|
||||||
if (arg_is_set(cmd, activate_ARG)) {
|
|
||||||
activate = (activation_change_t) arg_uint_value(cmd, activate_ARG, 0);
|
|
||||||
- if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate))
|
|
||||||
+ if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate, vp->root_dm_uuid))
|
|
||||||
return_ECMD_FAILED;
|
|
||||||
} else if (arg_is_set(cmd, refresh_ARG)) {
|
|
||||||
/* refreshes the visible LVs (which starts polling) */
|
|
||||||
@@ -735,6 +775,115 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Automatic creation of system.devices for root VG on first boot
|
|
||||||
+ * is useful for OS images where the OS installer is not used to
|
|
||||||
+ * customize the OS for system.
|
|
||||||
+ *
|
|
||||||
+ * - OS image prep:
|
|
||||||
+ * . rm /etc/lvm/devices/system.devices (if it exists)
|
|
||||||
+ * . touch /etc/lvm/devices/auto-import-rootvg
|
|
||||||
+ * . enable lvm-devices-import.path
|
|
||||||
+ * . enable lvm-devices-import.service
|
|
||||||
+ *
|
|
||||||
+ * - lvchange -ay <rootvg>/<rootlv>
|
|
||||||
+ * . run by initrd so root fs can be mounted
|
|
||||||
+ * . does not use system.devices
|
|
||||||
+ * . named <rootvg>/<rootlv> comes from kernel command line rd.lvm
|
|
||||||
+ * . uses first device that appears containing the named root LV
|
|
||||||
+ *
|
|
||||||
+ * - vgchange -aay <rootvg>
|
|
||||||
+ * . triggered by udev when all PVs from root VG are online
|
|
||||||
+ * . activate LVs in root VG (in addition to the already active root LV)
|
|
||||||
+ * . check for /etc/lvm/devices/auto-import-rootvg (found)
|
|
||||||
+ * . check for /etc/lvm/devices/system.devices (not found)
|
|
||||||
+ * . create /run/lvm/lvm-devices-import because
|
|
||||||
+ * auto-import-rootvg was found and system.devices was not found
|
|
||||||
+ *
|
|
||||||
+ * - lvm-devices-import.path
|
|
||||||
+ * . triggered by /run/lvm/lvm-devices-import
|
|
||||||
+ * . start lvm-devices-import.service
|
|
||||||
+ *
|
|
||||||
+ * - lvm-devices-import.service
|
|
||||||
+ * . check for /etc/lvm/devices/system.devices, do nothing if found
|
|
||||||
+ * . run vgimportdevices --rootvg --auto
|
|
||||||
+ *
|
|
||||||
+ * - vgimportdevices --rootvg --auto
|
|
||||||
+ * . check for /etc/lvm/devices/auto-import-rootvg (found)
|
|
||||||
+ * . check for /etc/lvm/devices/system.devices (not found)
|
|
||||||
+ * . creates /etc/lvm/devices/system.devices for PVs in root VG
|
|
||||||
+ * . removes /etc/lvm/devices/auto-import-rootvg
|
|
||||||
+ * . removes /run/lvm/lvm-devices-import
|
|
||||||
+ *
|
|
||||||
+ * On future startup, /etc/lvm/devices/system.devices will exist,
|
|
||||||
+ * and /etc/lvm/devices/auto-import-rootvg will not exist, so
|
|
||||||
+ * vgchange -aay <rootvg> will not create /run/lvm/lvm-devices-import,
|
|
||||||
+ * and lvm-devices-import.path and lvm-device-import.service will not run.
|
|
||||||
+ *
|
|
||||||
+ * lvm-devices-import.path:
|
|
||||||
+ * [Path]
|
|
||||||
+ * PathExists=/run/lvm/lvm-devices-import
|
|
||||||
+ * Unit=lvm-devices-import.service
|
|
||||||
+ * ConditionPathExists=!/etc/lvm/devices/system.devices
|
|
||||||
+ *
|
|
||||||
+ * lvm-devices-import.service:
|
|
||||||
+ * [Service]
|
|
||||||
+ * Type=oneshot
|
|
||||||
+ * RemainAfterExit=no
|
|
||||||
+ * ExecStart=/usr/sbin/vgimportdevices --rootvg --auto
|
|
||||||
+ * ConditionPathExists=!/etc/lvm/devices/system.devices
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+static void _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out)
|
|
||||||
+{
|
|
||||||
+ char path[PATH_MAX];
|
|
||||||
+ char dm_uuid[DM_UUID_LEN];
|
|
||||||
+ struct stat info;
|
|
||||||
+ FILE *fme = NULL;
|
|
||||||
+ struct mntent *me;
|
|
||||||
+ int found = 0;
|
|
||||||
+
|
|
||||||
+ if (cmd->enable_devices_file || devices_file_exists(cmd))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (stat(path, &info) < 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (!(fme = setmntent("/etc/mtab", "r")))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ while ((me = getmntent(fme))) {
|
|
||||||
+ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) {
|
|
||||||
+ found = 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ endmntent(fme);
|
|
||||||
+
|
|
||||||
+ if (!found)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (stat(me->mnt_dir, &info) < 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev)))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ log_debug("Found root dm_uuid %s", dm_uuid);
|
|
||||||
+
|
|
||||||
+ /* UUID_PREFIX = "LVM-" */
|
|
||||||
+ if (strncmp(dm_uuid, UUID_PREFIX, 4))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (strlen(dm_uuid) < 4 + ID_LEN)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
|
|
||||||
struct vgchange_params *vp,
|
|
||||||
int *skip_command,
|
|
||||||
@@ -778,6 +927,8 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
|
|
||||||
|
|
||||||
get_single_vgname_cmd_arg(cmd, NULL, &vgname);
|
|
||||||
|
|
||||||
+ _get_rootvg_dev(cmd, &vp->root_dm_uuid);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Lock the VG before scanning the PVs so _vg_read can avoid the normal
|
|
||||||
* lock_vol+rescan (READ_WITHOUT_LOCK avoids the normal lock_vol and
|
|
||||||
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
|
||||||
index bccd94f61..70d12e500 100644
|
|
||||||
--- a/tools/vgimportdevices.c
|
|
||||||
+++ b/tools/vgimportdevices.c
|
|
||||||
@@ -15,11 +15,16 @@
|
|
||||||
#include "tools.h"
|
|
||||||
#include "lib/cache/lvmcache.h"
|
|
||||||
#include "lib/device/device_id.h"
|
|
||||||
+#include "device_mapper/misc/dm-ioctl.h"
|
|
||||||
/* coverity[unnecessary_header] needed for MuslC */
|
|
||||||
#include <sys/file.h>
|
|
||||||
+#include <mntent.h>
|
|
||||||
|
|
||||||
struct vgimportdevices_params {
|
|
||||||
uint32_t added_devices;
|
|
||||||
+ int root_vg_found;
|
|
||||||
+ char *root_dm_uuid;
|
|
||||||
+ char *root_vg_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _vgimportdevices_single(struct cmd_context *cmd,
|
|
||||||
@@ -35,6 +40,13 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
|
||||||
int updated_pvs = 0;
|
|
||||||
const char *idtypestr = NULL; /* deviceidtype_ARG ? */
|
|
||||||
|
|
||||||
+ if (vp->root_dm_uuid) {
|
|
||||||
+ if (memcmp(vp->root_dm_uuid + 4, &vg->id, ID_LEN))
|
|
||||||
+ return ECMD_PROCESSED;
|
|
||||||
+ vp->root_vg_found = 1;
|
|
||||||
+ vp->root_vg_name = dm_pool_strdup(cmd->mem, vg_name);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
|
||||||
if (is_missing_pv(pvl->pv) || !pvl->pv->dev) {
|
|
||||||
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
|
|
||||||
@@ -86,6 +98,87 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
|
||||||
return ECMD_PROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out, int *skip)
|
|
||||||
+{
|
|
||||||
+ char path[PATH_MAX];
|
|
||||||
+ char dm_uuid[DM_UUID_LEN];
|
|
||||||
+ struct stat info;
|
|
||||||
+ FILE *fme = NULL;
|
|
||||||
+ struct mntent *me;
|
|
||||||
+ int found = 0;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * When --auto is set, the command does nothing
|
|
||||||
+ * if /etc/lvm/devices/system.devices exists, or
|
|
||||||
+ * if /etc/lvm/devices/auto-import-rootvg does not exist.
|
|
||||||
+ */
|
|
||||||
+ if (arg_is_set(cmd, auto_ARG)) {
|
|
||||||
+ if (devices_file_exists(cmd)) {
|
|
||||||
+ *skip = 1;
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ if (stat(path, &info) < 0) {
|
|
||||||
+ *skip = 1;
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * This flag is just used in device_ids_write to enable
|
|
||||||
+ * an extra comment in system.devices indicating that
|
|
||||||
+ * the file was auto generated for the root vg.
|
|
||||||
+ */
|
|
||||||
+ cmd->device_ids_auto_import = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!(fme = setmntent("/etc/mtab", "r")))
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ while ((me = getmntent(fme))) {
|
|
||||||
+ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) {
|
|
||||||
+ found = 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ endmntent(fme);
|
|
||||||
+
|
|
||||||
+ if (!found)
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ if (stat(me->mnt_dir, &info) < 0)
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev)))
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ /* UUID_PREFIX = "LVM-" */
|
|
||||||
+ if (strncmp(dm_uuid, UUID_PREFIX, 4))
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ if (strlen(dm_uuid) < 4 + ID_LEN)
|
|
||||||
+ return_0;
|
|
||||||
+
|
|
||||||
+ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid);
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void _clear_rootvg_auto(struct cmd_context *cmd)
|
|
||||||
+{
|
|
||||||
+ char path[PATH_MAX];
|
|
||||||
+
|
|
||||||
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (unlink(path) < 0)
|
|
||||||
+ log_debug("Failed to unlink %s", path);
|
|
||||||
+
|
|
||||||
+ if (unlink(DEVICES_IMPORT_PATH) < 0)
|
|
||||||
+ log_debug("Failed to unlink %s", DEVICES_IMPORT_PATH);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* This command always scans all devices on the system,
|
|
||||||
* any pre-existing devices_file does not limit the scope.
|
|
||||||
@@ -130,6 +223,19 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
|
||||||
/* So that we can warn about this. */
|
|
||||||
cmd->handles_missing_pvs = 1;
|
|
||||||
|
|
||||||
+ /* Import devices for the root VG. */
|
|
||||||
+ if (arg_is_set(cmd, rootvg_ARG)) {
|
|
||||||
+ int skip = 0;
|
|
||||||
+ if (!_get_rootvg_dev(cmd, &vp.root_dm_uuid, &skip)) {
|
|
||||||
+ log_error("Failed to find root VG.");
|
|
||||||
+ return ECMD_FAILED;
|
|
||||||
+ }
|
|
||||||
+ if (skip) {
|
|
||||||
+ log_print("Root VG auto import is not enabled.");
|
|
||||||
+ return ECMD_PROCESSED;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!lock_global(cmd, "ex"))
|
|
||||||
return ECMD_FAILED;
|
|
||||||
|
|
||||||
@@ -230,7 +336,13 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- log_print("Added %u devices to devices file.", vp.added_devices);
|
|
||||||
+ if (vp.root_vg_found)
|
|
||||||
+ log_print("Added %u devices to devices file for root VG %s.", vp.added_devices, vp.root_vg_name);
|
|
||||||
+ else
|
|
||||||
+ log_print("Added %u devices to devices file.", vp.added_devices);
|
|
||||||
+
|
|
||||||
+ if (vp.root_vg_found && arg_is_set(cmd, auto_ARG))
|
|
||||||
+ _clear_rootvg_auto(cmd);
|
|
||||||
out:
|
|
||||||
if ((ret == ECMD_FAILED) && created_file)
|
|
||||||
if (unlink(cmd->devices_file_path) < 0)
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
|||||||
|
From fad2b3dc8c44ba1222508ee78b5f161994efe638 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 9 Nov 2021 11:54:48 -0600
|
||||||
|
Subject: [PATCH 08/54] filter-sysfs: support old kernels without sys/dev/block
|
||||||
|
|
||||||
|
rhel5 for example doesn't have /sys/dev/block
|
||||||
|
---
|
||||||
|
lib/filters/filter-sysfs.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 28 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/filters/filter-sysfs.c b/lib/filters/filter-sysfs.c
|
||||||
|
index 672211057..d8de7940b 100644
|
||||||
|
--- a/lib/filters/filter-sysfs.c
|
||||||
|
+++ b/lib/filters/filter-sysfs.c
|
||||||
|
@@ -15,6 +15,8 @@
|
||||||
|
#include "lib/misc/lib.h"
|
||||||
|
#include "lib/filters/filter.h"
|
||||||
|
|
||||||
|
+static int _sys_dev_block_found;
|
||||||
|
+
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||||
|
@@ -23,6 +25,9 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
||||||
|
const char *sysfs_dir;
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
+ if (!_sys_dev_block_found)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -57,6 +62,26 @@ static void _destroy(struct dev_filter *f)
|
||||||
|
free(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void _check_sys_dev_block(void)
|
||||||
|
+{
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+ const char *sysfs_dir;
|
||||||
|
+ struct stat info;
|
||||||
|
+
|
||||||
|
+ sysfs_dir = dm_sysfs_dir();
|
||||||
|
+ if (sysfs_dir && *sysfs_dir) {
|
||||||
|
+ if (dm_snprintf(path, sizeof(path), "%sdev/block", sysfs_dir) < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (lstat(path, &info)) {
|
||||||
|
+ log_debug("filter-sysfs disabled: /sys/dev/block not found");
|
||||||
|
+ _sys_dev_block_found = 0;
|
||||||
|
+ } else {
|
||||||
|
+ _sys_dev_block_found = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct dev_filter *sysfs_filter_create(void)
|
||||||
|
{
|
||||||
|
const char *sysfs_dir = dm_sysfs_dir();
|
||||||
|
@@ -67,6 +92,9 @@ struct dev_filter *sysfs_filter_create(void)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* support old kernels that don't have this */
|
||||||
|
+ _check_sys_dev_block();
|
||||||
|
+
|
||||||
|
if (!(f = zalloc(sizeof(*f))))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
155
SOURCES/0009-device_id-match-different-dm-device-names.patch
Normal file
155
SOURCES/0009-device_id-match-different-dm-device-names.patch
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
From 459d931a9bfe4c9adcbbf2e76fdf35fda5b13c61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 12 Nov 2021 16:42:51 -0600
|
||||||
|
Subject: [PATCH 09/54] device_id: match different dm device names
|
||||||
|
|
||||||
|
If a devices file entry for a dm device is using the devname
|
||||||
|
for the device id, then recognize different dm names as matching.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 81 +++++++++++++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 69 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index eb06109ff..dea739fc4 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1360,6 +1360,10 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
|
||||||
|
static int _idtype_compatible_with_major_number(struct cmd_context *cmd, int idtype, int major)
|
||||||
|
{
|
||||||
|
+ /* devname can be used with any kind of device */
|
||||||
|
+ if (idtype == DEV_ID_TYPE_DEVNAME)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
if (idtype == DEV_ID_TYPE_MPATH_UUID ||
|
||||||
|
idtype == DEV_ID_TYPE_CRYPT_UUID ||
|
||||||
|
idtype == DEV_ID_TYPE_LVMLV_UUID)
|
||||||
|
@@ -1388,6 +1392,43 @@ static int _idtype_compatible_with_major_number(struct cmd_context *cmd, int idt
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ struct dev_id *id, struct dev_use *du)
|
||||||
|
+{
|
||||||
|
+ struct stat buf;
|
||||||
|
+
|
||||||
|
+ if (MAJOR(dev->dev) != cmd->dev_types->device_mapper_major)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (id->idname && du->idname && !strcmp(id->idname, du->idname))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (du->idname && !strcmp(du->idname, dev_name(dev))) {
|
||||||
|
+ log_debug("Match device_id %s %s to %s: ignoring idname %s",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname, dev_name(dev), id->idname ?: ".");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!du->idname)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* detect that a du entry is for a dm device */
|
||||||
|
+
|
||||||
|
+ if (!strncmp(du->idname, "/dev/dm-", 8) || !strncmp(du->idname, "/dev/mapper/", 12)) {
|
||||||
|
+ if (stat(du->idname, &buf))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if ((MAJOR(buf.st_rdev) == cmd->dev_types->device_mapper_major) &&
|
||||||
|
+ (MINOR(buf.st_rdev) == MINOR(dev->dev))) {
|
||||||
|
+ log_debug("Match device_id %s %s to %s: using other dm name, ignoring %s",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname, dev_name(dev), id->idname ?: ".");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* check for dev->ids entry with du->idtype, if found compare it,
|
||||||
|
* if not, system_read of this type and add entry to dev->ids, compare it.
|
||||||
|
@@ -1408,35 +1449,52 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
||||||
|
* so we can skip trying to match certain du entries based simply on
|
||||||
|
* the major number of dev.
|
||||||
|
*/
|
||||||
|
- if (!_idtype_compatible_with_major_number(cmd, du->idtype, (int)MAJOR(dev->dev)))
|
||||||
|
+ if (!_idtype_compatible_with_major_number(cmd, du->idtype, (int)MAJOR(dev->dev))) {
|
||||||
|
+ /*
|
||||||
|
+ log_debug("Mismatch device_id %s %s to %s: wrong major",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev));
|
||||||
|
+ */
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!dev_get_partition_number(dev, &part)) {
|
||||||
|
- log_debug("compare %s failed to get dev partition", dev_name(dev));
|
||||||
|
+ /*
|
||||||
|
+ log_debug("Mismatch device_id %s %s to %s: no partition",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev));
|
||||||
|
+ */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (part != du->part) {
|
||||||
|
/*
|
||||||
|
- log_debug("compare mis %s %s part %d to %s part %d",
|
||||||
|
- idtype_to_str(du->idtype), du->idname ?: ".", du->part, dev_name(dev), part);
|
||||||
|
+ log_debug("Mismatch device_id %s %s to %s: wrong partition %d vs %d",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), du->part, part);
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_list_iterate_items(id, &dev->ids) {
|
||||||
|
if (id->idtype == du->idtype) {
|
||||||
|
- if (id->idname && !strcmp(id->idname, du->idname)) {
|
||||||
|
+ if ((id->idtype == DEV_ID_TYPE_DEVNAME) && _match_dm_devnames(cmd, dev, id, du)) {
|
||||||
|
+ /* dm devs can have differing names that we know still match */
|
||||||
|
+ du->dev = dev;
|
||||||
|
+ dev->id = id;
|
||||||
|
+ dev->flags |= DEV_MATCHED_USE_ID;
|
||||||
|
+ log_debug("Match device_id %s %s to %s: dm names",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ } else if (id->idname && !strcmp(id->idname, du->idname)) {
|
||||||
|
du->dev = dev;
|
||||||
|
dev->id = id;
|
||||||
|
dev->flags |= DEV_MATCHED_USE_ID;
|
||||||
|
log_debug("Match device_id %s %s to %s",
|
||||||
|
idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
||||||
|
return 1;
|
||||||
|
+
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
- log_debug("compare mis %s %s to %s %s",
|
||||||
|
- idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev),
|
||||||
|
- ((id->idtype != DEV_ID_TYPE_DEVNAME) && id->idname) ? id->idname : "");
|
||||||
|
+ log_debug("Mismatch device_id %s %s to %s: idname %s",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), id->idname ?: ":");
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1456,7 +1514,7 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
||||||
|
id->dev = dev;
|
||||||
|
dm_list_add(&dev->ids, &id->list);
|
||||||
|
/*
|
||||||
|
- log_debug("compare mis %s %s to %s no idtype",
|
||||||
|
+ log_debug("Mismatch device_id %s %s to %s: no idtype",
|
||||||
|
idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev));
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
@@ -1481,9 +1539,8 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- log_debug("compare mis %s %s to %s %s",
|
||||||
|
- idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev),
|
||||||
|
- ((id->idtype != DEV_ID_TYPE_DEVNAME) && id->idname) ? id->idname : "");
|
||||||
|
+ log_debug("Mismatch device_id %s %s to %s: idname %s",
|
||||||
|
+ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), idname);
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
From fe58f4b87a2cd85f132775a2e475c128b89e7eb4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
|
||||||
Date: Fri, 24 May 2024 19:49:08 +0200
|
|
||||||
Subject: [PATCH 09/13] lvm: fix shell completion
|
|
||||||
|
|
||||||
Previous commit 82617852a4d3c89b09124eddedcc2c1859b9d50e
|
|
||||||
introduce bug in complession - as the rl_completion_matches()
|
|
||||||
needs to always advance to next element where the index
|
|
||||||
is held in static variable.
|
|
||||||
|
|
||||||
Add comment about this usage.
|
|
||||||
|
|
||||||
(cherry picked from commit 73298635b9db2c2a11bc4cc291b15d0f21907598)
|
|
||||||
(cherry picked from commit c33b0e11878a52aeaa42b4ebfd0692e5da7f5e07)
|
|
||||||
---
|
|
||||||
tools/lvm.c | 13 ++++++++-----
|
|
||||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/lvm.c b/tools/lvm.c
|
|
||||||
index 116b707b2..3a7e6dc6c 100644
|
|
||||||
--- a/tools/lvm.c
|
|
||||||
+++ b/tools/lvm.c
|
|
||||||
@@ -52,7 +52,8 @@ static char *_list_cmds(const char *text, int state)
|
|
||||||
|
|
||||||
for (;i < _cmdline->num_command_names;++i)
|
|
||||||
if (!strncmp(text, _cmdline->command_names[i].name, len))
|
|
||||||
- return strdup(_cmdline->command_names[i].name);
|
|
||||||
+ /* increase position for next iteration */
|
|
||||||
+ return strdup(_cmdline->command_names[i++].name);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@@ -102,9 +103,10 @@ static char *_list_args(const char *text, int state)
|
|
||||||
|
|
||||||
/* Short form arguments */
|
|
||||||
if (len < 3) {
|
|
||||||
- for (;match_no < cna->num_args; ++match_no) {
|
|
||||||
+ while (match_no < cna->num_args) {
|
|
||||||
char s[3];
|
|
||||||
- char c = (_cmdline->opt_names + cna->valid_args[match_no])->short_opt;
|
|
||||||
+ /* increase position for next iteration */
|
|
||||||
+ char c = _cmdline->opt_names[cna->valid_args[match_no++]].short_opt;
|
|
||||||
if (c) {
|
|
||||||
sprintf(s, "-%c", c);
|
|
||||||
if (!strncmp(text, s, len))
|
|
||||||
@@ -117,8 +119,9 @@ static char *_list_args(const char *text, int state)
|
|
||||||
if (match_no < cna->num_args)
|
|
||||||
match_no = cna->num_args;
|
|
||||||
|
|
||||||
- for (;match_no - cna->num_args < cna->num_args; ++match_no) {
|
|
||||||
- const char *l = (_cmdline->opt_names + cna->valid_args[match_no - cna->num_args])->long_opt;
|
|
||||||
+ while ((match_no - cna->num_args) < cna->num_args) {
|
|
||||||
+ /* increase position for next iteration */
|
|
||||||
+ const char *l = _cmdline->opt_names[cna->valid_args[match_no++ - cna->num_args]].long_opt;
|
|
||||||
if (*(l + 2) && !strncmp(text, l, len))
|
|
||||||
return strdup(l);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
134
SOURCES/0010-device_id-fix-search-on-filtered-device.patch
Normal file
134
SOURCES/0010-device_id-fix-search-on-filtered-device.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From 5533cd7bf4c1edc5d8fb0e95d2f83b2b2d446339 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 16 Nov 2021 09:29:24 -0600
|
||||||
|
Subject: [PATCH 10/54] device_id: fix search on filtered device
|
||||||
|
|
||||||
|
When devnames are used as device ids and devnames change,
|
||||||
|
then new devices need to be located for the PVs. If the old
|
||||||
|
devname is now used by a filtered device, this was preventing
|
||||||
|
the code from searching for the new device, so the PV was
|
||||||
|
reported as missing.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 16 ++++++-
|
||||||
|
test/shell/devicesfile-devname.sh | 69 +++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 83 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index dea739fc4..48f1682a3 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -2025,12 +2025,19 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
|
||||||
|
search_auto = !strcmp(cmd->search_for_devnames, "auto");
|
||||||
|
|
||||||
|
dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
- if (du->dev)
|
||||||
|
- continue;
|
||||||
|
if (!du->pvid)
|
||||||
|
continue;
|
||||||
|
if (du->idtype != DEV_ID_TYPE_DEVNAME)
|
||||||
|
continue;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * if the old incorrect devname is now a device that's
|
||||||
|
+ * filtered and not scanned, e.g. an mpath component,
|
||||||
|
+ * then we want to look for the pvid on a new device.
|
||||||
|
+ */
|
||||||
|
+ if (du->dev && !du->dev->filtered_flags)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
@@ -2055,6 +2062,11 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
|
||||||
|
* the searched file, so a subsequent lvm command will do the search
|
||||||
|
* again. In future perhaps we could add a policy to automatically
|
||||||
|
* remove a devices file entry that's not been found for some time.
|
||||||
|
+ *
|
||||||
|
+ * TODO: like the hint file, add a hash of all devnames to the searched
|
||||||
|
+ * file so it can be ignored and removed if the devs/hash change.
|
||||||
|
+ * If hints are enabled, the hints invalidation could also remove the
|
||||||
|
+ * searched file.
|
||||||
|
*/
|
||||||
|
if (_searched_devnames_exists(cmd)) {
|
||||||
|
log_debug("Search for PVIDs skipped for %s", _searched_file);
|
||||||
|
diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh
|
||||||
|
index f95be52b1..a99fe3e9a 100644
|
||||||
|
--- a/test/shell/devicesfile-devname.sh
|
||||||
|
+++ b/test/shell/devicesfile-devname.sh
|
||||||
|
@@ -545,4 +545,73 @@ grep "$PVID2" "$DF" |tee out
|
||||||
|
grep "$dev2" out
|
||||||
|
not grep "$dev1" out
|
||||||
|
|
||||||
|
+vgchange -an $vg1
|
||||||
|
+vgchange -an $vg2
|
||||||
|
+vgremove -ff $vg1
|
||||||
|
+vgremove -ff $vg2
|
||||||
|
+
|
||||||
|
+# devnames change so the new devname now refers to a filtered device,
|
||||||
|
+# e.g. an mpath or md component, which is not scanned
|
||||||
|
+
|
||||||
|
+wait_md_create() {
|
||||||
|
+ local md=$1
|
||||||
|
+
|
||||||
|
+ while :; do
|
||||||
|
+ if ! grep "$(basename $md)" /proc/mdstat; then
|
||||||
|
+ echo "$md not ready"
|
||||||
|
+ cat /proc/mdstat
|
||||||
|
+ sleep 2
|
||||||
|
+ else
|
||||||
|
+ break
|
||||||
|
+ fi
|
||||||
|
+ done
|
||||||
|
+ echo "$md" > WAIT_MD_DEV
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+aux wipefs_a "$dev1"
|
||||||
|
+aux wipefs_a "$dev2"
|
||||||
|
+aux wipefs_a "$dev3"
|
||||||
|
+aux wipefs_a "$dev4"
|
||||||
|
+
|
||||||
|
+mddev="/dev/md33"
|
||||||
|
+not grep $mddev /proc/mdstat || skip
|
||||||
|
+
|
||||||
|
+rm "$DF"
|
||||||
|
+touch "$DF"
|
||||||
|
+vgcreate $vg1 "$dev1" "$dev2"
|
||||||
|
+cat "$DF"
|
||||||
|
+cp "$DF" "$ORIG"
|
||||||
|
+
|
||||||
|
+# PVID with dashes for matching pvs -o+uuid output
|
||||||
|
+OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
|
||||||
|
+OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
|
||||||
|
+
|
||||||
|
+# PVID without dashes for matching devices file fields
|
||||||
|
+PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
||||||
|
+PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
||||||
|
+
|
||||||
|
+mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev3" "$dev4"
|
||||||
|
+wait_md_create "$mddev"
|
||||||
|
+
|
||||||
|
+sed -e "s|DEVNAME=$dev1|DEVNAME=$dev3|" "$ORIG" > tmp1.devices
|
||||||
|
+sed -e "s|IDNAME=$dev1|IDNAME=$dev3|" tmp1.devices > "$DF"
|
||||||
|
+cat "$DF"
|
||||||
|
+pvs -o+uuid |tee out
|
||||||
|
+grep "$dev1" out
|
||||||
|
+grep "$dev2" out
|
||||||
|
+grep "$OPVID1" out
|
||||||
|
+grep "$OPVID2" out
|
||||||
|
+not grep "$dev3" out
|
||||||
|
+not grep "$dev4" out
|
||||||
|
+
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+grep "$PVID1" "$DF"
|
||||||
|
+grep "$PVID2" "$DF"
|
||||||
|
+not grep "$dev3" "$DF"
|
||||||
|
+not grep "$dev4" "$DF"
|
||||||
|
+
|
||||||
|
+mdadm --stop "$mddev"
|
||||||
|
+aux udev_wait
|
||||||
|
+
|
||||||
|
vgremove -ff $vg1
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From 4b33a5a3999fa443dfe5e124e8bd984a936ac77c Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Thu, 30 May 2024 14:51:22 -0500
|
|
||||||
Subject: [PATCH 10/13] vgimportdevices: skip global lockd locking
|
|
||||||
|
|
||||||
Fix commit b65a2c3f3a767 "vgimportdevices: skip lvmlockd locking"
|
|
||||||
which intended to disable lvmlockd locking, but the lockd_gl_disable
|
|
||||||
flag was mistakenly set after lock_global() so it wasn't effective.
|
|
||||||
This caused vgimportdevices to fail unless locking was started.
|
|
||||||
|
|
||||||
(cherry picked from commit a8b8e1f074598d080bfb34e1fd04fe36ec122f93)
|
|
||||||
---
|
|
||||||
tools/vgimportdevices.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
|
||||||
index 70d12e500..2217fdad6 100644
|
|
||||||
--- a/tools/vgimportdevices.c
|
|
||||||
+++ b/tools/vgimportdevices.c
|
|
||||||
@@ -236,7 +236,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!lock_global(cmd, "ex"))
|
|
||||||
+ if (!lockf_global(cmd, "ex"))
|
|
||||||
return ECMD_FAILED;
|
|
||||||
|
|
||||||
/*
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
102
SOURCES/0011-device_id-searched_devnames-improvements.patch
Normal file
102
SOURCES/0011-device_id-searched_devnames-improvements.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From 39adf3e513ac7b1cbbbf0189f973573ade3c8939 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 16 Nov 2021 11:26:41 -0600
|
||||||
|
Subject: [PATCH 11/54] device_id: searched_devnames improvements
|
||||||
|
|
||||||
|
Remove the searched_devnames file in a couple more places:
|
||||||
|
. When hints need refreshing it's possible that a missing
|
||||||
|
devices file entry could be found by searching devices
|
||||||
|
again.
|
||||||
|
. When a devices file entry devname is first found to be
|
||||||
|
incorrect, a new search for missing entries may be
|
||||||
|
useful.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 28 ++++++++++++++++++++++++++--
|
||||||
|
lib/label/hints.c | 10 ++++++++++
|
||||||
|
2 files changed, 36 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 48f1682a3..ce7ded154 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -74,6 +74,8 @@ void unlink_searched_devnames(struct cmd_context *cmd)
|
||||||
|
|
||||||
|
if (unlink(_searched_file))
|
||||||
|
log_debug("unlink %s errno %d", _searched_file, errno);
|
||||||
|
+ else
|
||||||
|
+ log_debug("unlink %s", _searched_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _searched_devnames_exists(struct cmd_context *cmd)
|
||||||
|
@@ -780,7 +782,7 @@ static void _device_ids_update_try(struct cmd_context *cmd)
|
||||||
|
|
||||||
|
/* Defer updates to non-pvscan-cache commands. */
|
||||||
|
if (cmd->pvscan_cache_single) {
|
||||||
|
- log_print("pvscan[%d] skip updating devices file.", getpid());
|
||||||
|
+ log_print("Devices file update skipped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1441,8 +1443,22 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
||||||
|
const char *idname;
|
||||||
|
int part;
|
||||||
|
|
||||||
|
- if (!du->idname || !du->idtype)
|
||||||
|
+ /*
|
||||||
|
+ * The idname will be removed from an entry with devname type when the
|
||||||
|
+ * devname is read and found to hold a different PVID than the PVID in
|
||||||
|
+ * the entry. At that point we only have the PVID and no known
|
||||||
|
+ * location for it.
|
||||||
|
+ */
|
||||||
|
+ if (!du->idname || !du->idtype) {
|
||||||
|
+ /*
|
||||||
|
+ log_debug("Mismatch device_id %s %s %s to %s",
|
||||||
|
+ du->idtype ? idtype_to_str(du->idtype) : "idtype_missing",
|
||||||
|
+ du->idname ? du->idname : "idname_missing",
|
||||||
|
+ du->devname ? du->devname : "devname_missing",
|
||||||
|
+ dev_name(dev));
|
||||||
|
+ */
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some idtypes can only match devices with a specific major number,
|
||||||
|
@@ -1957,6 +1973,14 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||||
|
*device_ids_invalid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * When a new devname/pvid mismatch is discovered, a new search for the
|
||||||
|
+ * pvid should be permitted (searched_devnames may exist to suppress
|
||||||
|
+ * searching for other pvids.)
|
||||||
|
+ */
|
||||||
|
+ if (update_file)
|
||||||
|
+ unlink_searched_devnames(cmd);
|
||||||
|
+
|
||||||
|
/* FIXME: for wrong devname cases, wait to write new until device_ids_find_renamed_devs? */
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/lib/label/hints.c b/lib/label/hints.c
|
||||||
|
index e444a0c82..3ce9634f2 100644
|
||||||
|
--- a/lib/label/hints.c
|
||||||
|
+++ b/lib/label/hints.c
|
||||||
|
@@ -1390,6 +1390,16 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
|
||||||
|
log_debug("get_hints: needs refresh");
|
||||||
|
free_hints(&hints_list);
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * This is not related to hints, and is probably unnecessary,
|
||||||
|
+ * but it could possibly help. When hints become invalid it's
|
||||||
|
+ * usually becaues devs on the system have changed, and that
|
||||||
|
+ * also means that a missing devices file entry might be found
|
||||||
|
+ * by searching devices again. (the searched_devnames
|
||||||
|
+ * mechanism should eventually be replaced)
|
||||||
|
+ */
|
||||||
|
+ unlink_searched_devnames(cmd);
|
||||||
|
+
|
||||||
|
if (!_lock_hints(cmd, LOCK_EX, NONBLOCK))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
From d94090dae6e20135f0e9ba8ca0a645f2e3470a48 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marian Csontos <mcsontos@redhat.com>
|
|
||||||
Date: Wed, 26 Jun 2024 14:37:17 +0200
|
|
||||||
Subject: [PATCH 11/13] scripts: Install services for devices file init
|
|
||||||
|
|
||||||
Services introduced in commit c609dedc2f035f770b5f645c4695924abf15c2ca
|
|
||||||
need installing.
|
|
||||||
|
|
||||||
(cherry picked from commit 1b9bf5007bbfba5bcd622f039a099e6f7e0a8162)
|
|
||||||
---
|
|
||||||
scripts/Makefile.in | 2 ++
|
|
||||||
spec/packages.inc | 2 ++
|
|
||||||
2 files changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
|
|
||||||
index a79edbd4d..f683b7ab1 100644
|
|
||||||
--- a/scripts/Makefile.in
|
|
||||||
+++ b/scripts/Makefile.in
|
|
||||||
@@ -108,6 +108,8 @@ endif
|
|
||||||
ifeq ("@BUILD_LVMDBUSD@", "yes")
|
|
||||||
$(Q) $(INSTALL_DATA) lvm2_lvmdbusd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmdbusd.service
|
|
||||||
endif
|
|
||||||
+ $(Q) $(INSTALL_DATA) lvm-devices-import.path $(systemd_unit_dir)/lvm-devices-import.path
|
|
||||||
+ $(Q) $(INSTALL_DATA) lvm-devices-import.service $(systemd_unit_dir)/lvm-devices-import.service
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMDBUSD@", "yes")
|
|
||||||
install_dbus_service:
|
|
||||||
diff --git a/spec/packages.inc b/spec/packages.inc
|
|
||||||
index 05733e0df..ee67af590 100644
|
|
||||||
--- a/spec/packages.inc
|
|
||||||
+++ b/spec/packages.inc
|
|
||||||
@@ -193,6 +193,8 @@ fi
|
|
||||||
%{_unitdir}/lvm2-lvmpolld.service
|
|
||||||
%{_unitdir}/lvm2-lvmpolld.socket
|
|
||||||
%endif
|
|
||||||
+ %{_unitdir}/lvm-devices-import.service
|
|
||||||
+ %{_unitdir}/lvm-devices-import.path
|
|
||||||
%else
|
|
||||||
%{_sysconfdir}/rc.d/init.d/blk-availability
|
|
||||||
%{_sysconfdir}/rc.d/init.d/lvm2-monitor
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
@ -1,330 +0,0 @@
|
|||||||
From 0bb9ae53db66a2455b9655d16166877cd2c3f4c0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Wed, 12 Jun 2024 15:36:45 -0500
|
|
||||||
Subject: [PATCH 12/13] lvmlockd: avoid lockd_vg for local VGs
|
|
||||||
|
|
||||||
Previously, a command would call lockd_vg() for a local VG,
|
|
||||||
which would go to lvmlockd, which would send back ENOLS,
|
|
||||||
and the command would not care when it saw the VG was local.
|
|
||||||
The pointless back-and-forth to lvmlockd for local VGs can
|
|
||||||
be avoided by checking the VG lock_type in lvmcache (which
|
|
||||||
label_scan now saves there; this wasn't the case back when
|
|
||||||
the original lockd_vg logic was added.) If the lock_type
|
|
||||||
saved during label_scan indicates a local VG, then the
|
|
||||||
lockd_vg step is skipped.
|
|
||||||
|
|
||||||
(cherry picked from commit bf60cb4da23cac2f6b721170dd0d8bfd38b16466)
|
|
||||||
---
|
|
||||||
lib/cache/lvmcache.c | 10 +++++++++
|
|
||||||
lib/cache/lvmcache.h | 2 ++
|
|
||||||
lib/locking/lvmlockd.c | 12 ++++++++---
|
|
||||||
tools/lvconvert.c | 8 ++++---
|
|
||||||
tools/polldaemon.c | 9 +++++---
|
|
||||||
tools/toollib.c | 47 +++++++++++++++++++++++++++++++++++-------
|
|
||||||
6 files changed, 71 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
|
||||||
index 711a97fec..1ea4cb7db 100644
|
|
||||||
--- a/lib/cache/lvmcache.c
|
|
||||||
+++ b/lib/cache/lvmcache.c
|
|
||||||
@@ -3002,6 +3002,16 @@ int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const ch
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
|
||||||
+{
|
|
||||||
+ struct lvmcache_vginfo *vginfo;
|
|
||||||
+
|
|
||||||
+ if ((vginfo = lvmcache_vginfo_from_vgname(vgname, vgid)))
|
|
||||||
+ return is_lockd_type(vginfo->lock_type);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Example of reading four devs in sequence from the same VG:
|
|
||||||
*
|
|
||||||
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
|
|
||||||
index eccf29eb2..760ff6ba1 100644
|
|
||||||
--- a/lib/cache/lvmcache.h
|
|
||||||
+++ b/lib/cache/lvmcache.h
|
|
||||||
@@ -179,6 +179,8 @@ void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
|
|
||||||
|
|
||||||
int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
|
||||||
|
|
||||||
+int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
|
||||||
+
|
|
||||||
bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
|
||||||
|
|
||||||
int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, const char *pvid_arg);
|
|
||||||
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
|
|
||||||
index 9c24b619f..33150cb48 100644
|
|
||||||
--- a/lib/locking/lvmlockd.c
|
|
||||||
+++ b/lib/locking/lvmlockd.c
|
|
||||||
@@ -2014,9 +2014,15 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
|
||||||
* this result is passed into vg_read(). After vg_read() reads the VG,
|
|
||||||
* it checks if the VG lock_type (sanlock or dlm) requires a lock to be
|
|
||||||
* held, and if so, it verifies that the lock was correctly acquired by
|
|
||||||
- * looking at lockd_state. If vg_read() sees that the VG is a local VG,
|
|
||||||
- * i.e. lock_type is not sanlock or dlm, then no lock is required, and it
|
|
||||||
- * ignores lockd_state (which would indicate no lock was found.)
|
|
||||||
+ * looking at lockd_state.
|
|
||||||
+ *
|
|
||||||
+ * If vg_read() sees that the VG is a local VG, i.e. lock_type is not
|
|
||||||
+ * sanlock or dlm, then no lock is required, and it ignores lockd_state,
|
|
||||||
+ * which would indicate no lock was found.... although a newer
|
|
||||||
+ * optimization avoids calling lockd_vg() at all for local VGs
|
|
||||||
+ * by checking the lock_type in lvmcache saved by label_scan. In extremely
|
|
||||||
+ * rare case where the lock_type changes between label_scan and vg_read,
|
|
||||||
+ * the caller will go back and repeat lockd_vg()+vg_read().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
|
||||||
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
|
||||||
index dd40ef4f5..4e551a949 100644
|
|
||||||
--- a/tools/lvconvert.c
|
|
||||||
+++ b/tools/lvconvert.c
|
|
||||||
@@ -5788,10 +5788,12 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
|
|
||||||
struct logical_volume *lv_fast;
|
|
||||||
uint32_t lockd_state, error_flags;
|
|
||||||
uint64_t dirty;
|
|
||||||
+ int is_lockd;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
idl = dm_list_item(dm_list_first(&lr->poll_idls), struct convert_poll_id_list);
|
|
||||||
id = idl->id;
|
|
||||||
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: we should be able to save info about the dm device for this LV
|
|
||||||
@@ -5806,7 +5808,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
|
|
||||||
lockd_state = 0;
|
|
||||||
error_flags = 0;
|
|
||||||
|
|
||||||
- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
|
||||||
log_error("Detaching writecache interrupted - locking VG failed.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -5843,7 +5845,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
|
|
||||||
if (!lv_writecache_is_clean(cmd, lv, &dirty)) {
|
|
||||||
unlock_and_release_vg(cmd, vg, vg->name);
|
|
||||||
|
|
||||||
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
log_print_unless_silent("Detaching writecache cleaning %llu blocks", (unsigned long long)dirty);
|
|
||||||
@@ -5896,7 +5898,7 @@ out_release:
|
|
||||||
unlock_and_release_vg(cmd, vg, vg->name);
|
|
||||||
|
|
||||||
out_lockd:
|
|
||||||
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
|
|
||||||
index 730dfbcbb..3a9211768 100644
|
|
||||||
--- a/tools/polldaemon.c
|
|
||||||
+++ b/tools/polldaemon.c
|
|
||||||
@@ -156,6 +156,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
|
||||||
int finished = 0;
|
|
||||||
uint32_t lockd_state = 0;
|
|
||||||
uint32_t error_flags = 0;
|
|
||||||
+ int is_lockd;
|
|
||||||
int ret;
|
|
||||||
unsigned wait_before_testing = parms->wait_before_testing;
|
|
||||||
|
|
||||||
@@ -171,11 +172,13 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* An ex VG lock is needed because the check can call finish_copy
|
|
||||||
* which writes the VG.
|
|
||||||
*/
|
|
||||||
- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
|
||||||
log_error("ABORTING: Can't lock VG for %s.", id->display_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -229,7 +232,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
|
||||||
|
|
||||||
unlock_and_release_vg(cmd, vg, vg->name);
|
|
||||||
|
|
||||||
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
wait_before_testing = 1;
|
|
||||||
@@ -240,7 +243,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
|
||||||
out:
|
|
||||||
if (vg)
|
|
||||||
unlock_and_release_vg(cmd, vg, vg->name);
|
|
||||||
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
diff --git a/tools/toollib.c b/tools/toollib.c
|
|
||||||
index 080ee5429..686a5423c 100644
|
|
||||||
--- a/tools/toollib.c
|
|
||||||
+++ b/tools/toollib.c
|
|
||||||
@@ -2176,6 +2176,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
int ret;
|
|
||||||
int skip;
|
|
||||||
int notfound;
|
|
||||||
+ int is_lockd;
|
|
||||||
int process_all = 0;
|
|
||||||
int do_report_ret_code = 1;
|
|
||||||
|
|
||||||
@@ -2195,6 +2196,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
vg_uuid = vgnl->vgid;
|
|
||||||
skip = 0;
|
|
||||||
notfound = 0;
|
|
||||||
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
|
|
||||||
|
|
||||||
uuid[0] = '\0';
|
|
||||||
if (is_orphan_vg(vg_name)) {
|
|
||||||
@@ -2212,8 +2214,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
}
|
|
||||||
|
|
||||||
log_very_verbose("Processing VG %s %s", vg_name, uuid);
|
|
||||||
-
|
|
||||||
- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
|
||||||
+do_lockd:
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
|
||||||
stack;
|
|
||||||
ret_max = ECMD_FAILED;
|
|
||||||
report_log_ret_code(ret_max);
|
|
||||||
@@ -2235,6 +2237,14 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
if (skip || notfound)
|
|
||||||
goto endvg;
|
|
||||||
|
|
||||||
+ if (!is_lockd && vg_is_shared(vg)) {
|
|
||||||
+ /* The lock_type changed since label_scan, won't really occur in practice. */
|
|
||||||
+ log_debug("Repeat lock and read for local to shared vg");
|
|
||||||
+ unlock_and_release_vg(cmd, vg, vg_name);
|
|
||||||
+ is_lockd = 1;
|
|
||||||
+ goto do_lockd;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Process this VG? */
|
|
||||||
if ((process_all ||
|
|
||||||
(!dm_list_empty(arg_vgnames) && str_list_match_item(arg_vgnames, vg_name)) ||
|
|
||||||
@@ -2255,7 +2265,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
unlock_vg(cmd, vg, vg_name);
|
|
||||||
endvg:
|
|
||||||
release_vg(vg);
|
|
||||||
- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
log_set_report_object_name_and_id(NULL, NULL);
|
|
||||||
@@ -3873,6 +3883,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
|
||||||
int ret;
|
|
||||||
int skip;
|
|
||||||
int notfound;
|
|
||||||
+ int is_lockd;
|
|
||||||
int do_report_ret_code = 1;
|
|
||||||
|
|
||||||
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
|
|
||||||
@@ -3882,6 +3893,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
|
||||||
vg_uuid = vgnl->vgid;
|
|
||||||
skip = 0;
|
|
||||||
notfound = 0;
|
|
||||||
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
|
|
||||||
|
|
||||||
uuid[0] = '\0';
|
|
||||||
if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid)))
|
|
||||||
@@ -3927,7 +3939,8 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
|
||||||
|
|
||||||
log_very_verbose("Processing VG %s %s", vg_name, vg_uuid ? uuid : "");
|
|
||||||
|
|
||||||
- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
|
||||||
+do_lockd:
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
|
||||||
ret_max = ECMD_FAILED;
|
|
||||||
report_log_ret_code(ret_max);
|
|
||||||
continue;
|
|
||||||
@@ -3948,6 +3961,14 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
|
||||||
if (skip || notfound)
|
|
||||||
goto endvg;
|
|
||||||
|
|
||||||
+ if (!is_lockd && vg_is_shared(vg)) {
|
|
||||||
+ /* The lock_type changed since label_scan, won't really occur in practice. */
|
|
||||||
+ log_debug("Repeat lock and read for local to shared vg");
|
|
||||||
+ unlock_and_release_vg(cmd, vg, vg_name);
|
|
||||||
+ is_lockd = 1;
|
|
||||||
+ goto do_lockd;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg, 0,
|
|
||||||
handle, check_single_lv, process_single_lv);
|
|
||||||
if (ret != ECMD_PROCESSED)
|
|
||||||
@@ -3959,7 +3980,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
|
||||||
unlock_vg(cmd, vg, vg_name);
|
|
||||||
endvg:
|
|
||||||
release_vg(vg);
|
|
||||||
- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
log_set_report_object_name_and_id(NULL, NULL);
|
|
||||||
}
|
|
||||||
@@ -4513,6 +4534,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
int ret;
|
|
||||||
int skip;
|
|
||||||
int notfound;
|
|
||||||
+ int is_lockd;
|
|
||||||
int do_report_ret_code = 1;
|
|
||||||
|
|
||||||
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
|
|
||||||
@@ -4522,6 +4544,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
vg_uuid = vgnl->vgid;
|
|
||||||
skip = 0;
|
|
||||||
notfound = 0;
|
|
||||||
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
|
|
||||||
|
|
||||||
uuid[0] = '\0';
|
|
||||||
if (is_orphan_vg(vg_name)) {
|
|
||||||
@@ -4537,8 +4560,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
ret_max = ECMD_FAILED;
|
|
||||||
goto_out;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
|
||||||
+do_lockd:
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
|
||||||
ret_max = ECMD_FAILED;
|
|
||||||
report_log_ret_code(ret_max);
|
|
||||||
continue;
|
|
||||||
@@ -4561,6 +4584,14 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
|
||||||
if (notfound)
|
|
||||||
goto endvg;
|
|
||||||
|
|
||||||
+ if (vg && !is_lockd && vg_is_shared(vg)) {
|
|
||||||
+ /* The lock_type changed since label_scan, won't really occur in practice. */
|
|
||||||
+ log_debug("Repeat lock and read for local to shared vg");
|
|
||||||
+ unlock_and_release_vg(cmd, vg, vg_name);
|
|
||||||
+ is_lockd = 1;
|
|
||||||
+ goto do_lockd;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Don't call "continue" when skip is set, because we need to remove
|
|
||||||
* error_vg->pvs entries from devices list.
|
|
||||||
@@ -4583,7 +4614,7 @@ endvg:
|
|
||||||
if (error_vg)
|
|
||||||
unlock_and_release_vg(cmd, error_vg, vg_name);
|
|
||||||
release_vg(vg);
|
|
||||||
- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
|
||||||
+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
/* Quit early when possible. */
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
40
SOURCES/0012-tests-pv-ext-flags-work-with-devices-file.patch
Normal file
40
SOURCES/0012-tests-pv-ext-flags-work-with-devices-file.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
From 9c9bf13186d387d807f279c112745768c8b32513 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 16 Nov 2021 14:21:07 -0600
|
||||||
|
Subject: [PATCH 12/54] tests pv-ext-flags: work with devices file
|
||||||
|
|
||||||
|
---
|
||||||
|
test/shell/pv-ext-flags.sh | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/test/shell/pv-ext-flags.sh b/test/shell/pv-ext-flags.sh
|
||||||
|
index 3e6bcff76..ae4d6b7ff 100644
|
||||||
|
--- a/test/shell/pv-ext-flags.sh
|
||||||
|
+++ b/test/shell/pv-ext-flags.sh
|
||||||
|
@@ -57,9 +57,11 @@ dd if="$dev1" of=dev1_backup bs=1M
|
||||||
|
|
||||||
|
# pvcreate and pvremove can be forced even if the PV is marked as used
|
||||||
|
pvremove -ff -y "$dev1"
|
||||||
|
+lvmdevices --deldev "$dev1" || true
|
||||||
|
dd if=dev1_backup of="$dev1" bs=1M
|
||||||
|
pvcreate -ff -y "$dev1"
|
||||||
|
dd if=dev1_backup of="$dev1" bs=1M
|
||||||
|
+lvmdevices --adddev "$dev1" || true
|
||||||
|
|
||||||
|
# prepare a VG with $dev1 and $dev both having 1 MDA
|
||||||
|
aux enable_dev "$dev2"
|
||||||
|
@@ -116,9 +118,11 @@ dd if="$dev1" of=dev1_backup bs=1M
|
||||||
|
|
||||||
|
# pvcreate and pvremove can be forced even if the PV is marked as used
|
||||||
|
pvremove -ff -y "$dev1"
|
||||||
|
+lvmdevices --deldev "$dev1" || true
|
||||||
|
dd if=dev1_backup of="$dev1" bs=1M
|
||||||
|
pvcreate -ff -y "$dev1"
|
||||||
|
dd if=dev1_backup of="$dev1" bs=1M
|
||||||
|
+lvmdevices --adddev "$dev1" || true
|
||||||
|
|
||||||
|
# prepare a VG with $dev1 and $dev both having 1 MDA
|
||||||
|
aux enable_dev "$dev2"
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
91
SOURCES/0013-display-ignore-reportformat.patch
Normal file
91
SOURCES/0013-display-ignore-reportformat.patch
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
From 594c1fec1644fdf291aa0ff23de20db65c4cfadf Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 17 Nov 2021 10:40:27 -0600
|
||||||
|
Subject: [PATCH 13/54] display: ignore --reportformat
|
||||||
|
|
||||||
|
Using the option would do nothing useful but would
|
||||||
|
print extraneous braces.
|
||||||
|
---
|
||||||
|
tools/command-lines.in | 12 ++++++------
|
||||||
|
tools/lvmcmdline.c | 15 +++++++++++++++
|
||||||
|
2 files changed, 21 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/command-lines.in b/tools/command-lines.in
|
||||||
|
index 10b23e75d..00ac08934 100644
|
||||||
|
--- a/tools/command-lines.in
|
||||||
|
+++ b/tools/command-lines.in
|
||||||
|
@@ -1359,10 +1359,10 @@ OO: --aligned, --all, --binary, --colon, --columns,
|
||||||
|
--configreport ConfigReport, --foreign, --history, --ignorelockingfailure,
|
||||||
|
--logonly, --maps, --noheadings,
|
||||||
|
--nosuffix, --options String, --sort String, --readonly,
|
||||||
|
---reportformat ReportFmt, --segments, --select String, --separator String,
|
||||||
|
+--segments, --select String, --separator String,
|
||||||
|
--shared, --unbuffered, --units Units
|
||||||
|
OP: VG|LV|Tag ...
|
||||||
|
-IO: --partial, --ignoreskippedcluster
|
||||||
|
+IO: --partial, --ignoreskippedcluster, --reportformat ReportFmt
|
||||||
|
ID: lvdisplay_general
|
||||||
|
|
||||||
|
---
|
||||||
|
@@ -1590,10 +1590,10 @@ pvdisplay
|
||||||
|
OO: --aligned, --all, --binary, --colon, --columns, --configreport ConfigReport,
|
||||||
|
--foreign, --ignorelockingfailure,
|
||||||
|
--logonly, --maps, --noheadings, --nosuffix, --options String,
|
||||||
|
---readonly, --reportformat ReportFmt, --select String, --separator String, --shared,
|
||||||
|
+--readonly, --select String, --separator String, --shared,
|
||||||
|
--short, --sort String, --unbuffered, --units Units
|
||||||
|
OP: PV|Tag ...
|
||||||
|
-IO: --ignoreskippedcluster
|
||||||
|
+IO: --ignoreskippedcluster, --reportformat ReportFmt
|
||||||
|
ID: pvdisplay_general
|
||||||
|
|
||||||
|
---
|
||||||
|
@@ -1809,10 +1809,10 @@ vgdisplay
|
||||||
|
OO: --activevolumegroups, --aligned, --binary, --colon, --columns,
|
||||||
|
--configreport ConfigReport, --foreign, --ignorelockingfailure,
|
||||||
|
--logonly, --noheadings, --nosuffix,
|
||||||
|
---options String, --readonly, --reportformat ReportFmt, --select String,
|
||||||
|
+--options String, --readonly, --select String,
|
||||||
|
--shared, --short, --separator String, --sort String, --unbuffered, --units Units
|
||||||
|
OP: VG|Tag ...
|
||||||
|
-IO: --partial, --ignoreskippedcluster
|
||||||
|
+IO: --partial, --ignoreskippedcluster, --reportformat ReportFmt
|
||||||
|
ID: vgdisplay_general
|
||||||
|
|
||||||
|
---
|
||||||
|
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
|
||||||
|
index 1e12bedca..1727ba089 100644
|
||||||
|
--- a/tools/lvmcmdline.c
|
||||||
|
+++ b/tools/lvmcmdline.c
|
||||||
|
@@ -3058,6 +3058,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
int i;
|
||||||
|
int skip_hyphens;
|
||||||
|
int refresh_done = 0;
|
||||||
|
+ int io;
|
||||||
|
|
||||||
|
/* Avoid excessive access to /etc/localtime and set TZ variable for glibc
|
||||||
|
* so it does not need to check /etc/localtime everytime that needs that info */
|
||||||
|
@@ -3140,6 +3141,20 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
if (!(cmd->command = _find_command(cmd, cmd->name, &argc, argv)))
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * If option --foo is set which is listed in IO (ignore option) in
|
||||||
|
+ * command-lines.in, then unset foo. Commands won't usually use an
|
||||||
|
+ * ignored option, but there can be shared code that checks for --foo,
|
||||||
|
+ * and should not find it to be set.
|
||||||
|
+ */
|
||||||
|
+ for (io = 0; io < cmd->command->io_count; io++) {
|
||||||
|
+ int opt = cmd->command->ignore_opt_args[io].opt;
|
||||||
|
+ if (arg_is_set(cmd, opt)) {
|
||||||
|
+ log_debug("Ignore opt %d", opt);
|
||||||
|
+ cmd->opt_arg_values[opt].count = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Remaining position args after command name and --options are removed.
|
||||||
|
*/
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,86 +0,0 @@
|
|||||||
From a6dec74334d5b4c3d0774d8b120930dd6e008844 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Thu, 13 Jun 2024 13:34:23 -0500
|
|
||||||
Subject: [PATCH 13/13] lvmlockd: allow forced vgchange locktype from none
|
|
||||||
|
|
||||||
vgchange --locktype sanlock|dlm --lockopt force <vgname>
|
|
||||||
can be used to change the lock type without lvmlockd or
|
|
||||||
the lock manager involved.
|
|
||||||
|
|
||||||
(cherry picked from commit 4dc009c87227a137c8be50686b1104cebb9a88e2)
|
|
||||||
---
|
|
||||||
man/lvmlockd.8_main | 5 +++++
|
|
||||||
tools/vgchange.c | 17 +++++++++--------
|
|
||||||
2 files changed, 14 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main
|
|
||||||
index ea967d73d..38f9d958d 100644
|
|
||||||
--- a/man/lvmlockd.8_main
|
|
||||||
+++ b/man/lvmlockd.8_main
|
|
||||||
@@ -729,6 +729,11 @@ vgchange --locktype sanlock|dlm <vgname>
|
|
||||||
Start the VG on hosts to use it:
|
|
||||||
.br
|
|
||||||
vgchange --lockstart <vgname>
|
|
||||||
+.P
|
|
||||||
+If lvmlockd or the cluster manager are not available, the lock type can
|
|
||||||
+be forcibly changed with:
|
|
||||||
+.br
|
|
||||||
+vgchange --locktype sanlock|dlm \-\-lockopt force <vgname>
|
|
||||||
.
|
|
||||||
.SS Changing a shared VG to a local VG
|
|
||||||
.
|
|
||||||
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
|
||||||
index 2004d6e92..94c1feb8f 100644
|
|
||||||
--- a/tools/vgchange.c
|
|
||||||
+++ b/tools/vgchange.c
|
|
||||||
@@ -1176,7 +1176,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
|
|
||||||
+static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg, int *no_change)
|
|
||||||
{
|
|
||||||
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
|
|
||||||
const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
|
|
||||||
@@ -1206,6 +1206,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
|
|
||||||
if (lock_type && !strcmp(vg->lock_type, lock_type)) {
|
|
||||||
log_warn("WARNING: New lock type %s matches the current lock type %s.",
|
|
||||||
lock_type, vg->lock_type);
|
|
||||||
+ *no_change = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1344,9 +1345,14 @@ static int _vgchange_locktype_single(struct cmd_context *cmd, const char *vg_nam
|
|
||||||
struct volume_group *vg,
|
|
||||||
struct processing_handle *handle)
|
|
||||||
{
|
|
||||||
- if (!_vgchange_locktype(cmd, vg))
|
|
||||||
+ int no_change = 0;
|
|
||||||
+
|
|
||||||
+ if (!_vgchange_locktype(cmd, vg, &no_change))
|
|
||||||
return_ECMD_FAILED;
|
|
||||||
|
|
||||||
+ if (no_change)
|
|
||||||
+ return ECMD_PROCESSED;
|
|
||||||
+
|
|
||||||
if (!vg_write(vg) || !vg_commit(vg))
|
|
||||||
return_ECMD_FAILED;
|
|
||||||
|
|
||||||
@@ -1402,13 +1408,8 @@ int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv)
|
|
||||||
* just return success when they see the disable flag set.
|
|
||||||
*/
|
|
||||||
if (lockopt && !strcmp(lockopt, "force")) {
|
|
||||||
- if (lock_type && strcmp(lock_type, "none")) {
|
|
||||||
- log_error("Lock type can only be forced to \"none\" for recovery.");
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (!arg_is_set(cmd, yes_ARG) &&
|
|
||||||
- yes_no_prompt("Forcibly change VG lock type to none? [y/n]: ") == 'n') {
|
|
||||||
+ yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') {
|
|
||||||
log_error("VG lock type not changed.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
25
SOURCES/0014-fix-spelling-of-pruning.patch
Normal file
25
SOURCES/0014-fix-spelling-of-pruning.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From 7ac0b3c119b1cbb8e0b4969ece0b279637ace8c3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 19 Nov 2021 12:02:35 -0600
|
||||||
|
Subject: [PATCH 14/54] fix spelling of pruning
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/format_text/archive.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c
|
||||||
|
index 09a472b4c..2e8792a93 100644
|
||||||
|
--- a/lib/format_text/archive.c
|
||||||
|
+++ b/lib/format_text/archive.c
|
||||||
|
@@ -219,7 +219,7 @@ static void _remove_expired(const char *dir, const char *vgname,
|
||||||
|
|
||||||
|
sum /= 1024 * 1024;
|
||||||
|
if (sum > 128 || archives_size > 8192)
|
||||||
|
- log_print_unless_silent("Consider prunning %s VG archive with more then %u MiB in %u files (check archiving is needed in lvm.conf).",
|
||||||
|
+ log_print_unless_silent("Consider pruning %s VG archive with more then %u MiB in %u files (check archiving is needed in lvm.conf).",
|
||||||
|
vgname, (unsigned)sum, archives_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
From a5672ff088a027af04dc5586926841a48b693ee0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Heinz Mauelshagen <heinzm@redhat.com>
|
|
||||||
Date: Wed, 17 Jul 2024 17:08:20 +0200
|
|
||||||
Subject: [PATCH 14/14] lv_manip: avoid unreleased memory pool(s) message on
|
|
||||||
RAID extend
|
|
||||||
|
|
||||||
In case of different PV sizes in a VG, the lvm2 allocator falls short
|
|
||||||
to define extended segments resiliently asked for 100%FREE RaidLV extension
|
|
||||||
and a RAID distinct allocation check fails. Fix is to release a memory pool
|
|
||||||
on the resulting error path.
|
|
||||||
|
|
||||||
Until the lvm2 allocator gets enhanced (WIP) to do such complex (and other)
|
|
||||||
allocations proper, a workaround is to extend a RaidLV to any free space on
|
|
||||||
its already allocated PVs by defining those PVs on the lvextend command line
|
|
||||||
then iteratively run further such lvextend commands to extend it to its
|
|
||||||
final intended size. Mind, this may be a non-trivial extension interation.
|
|
||||||
|
|
||||||
(cherry picked from commit 557b2850cef7fa49e2cbacd36e77f679181f09ae)
|
|
||||||
---
|
|
||||||
WHATS_NEW | 5 +++++
|
|
||||||
lib/metadata/lv_manip.c | 3 ++-
|
|
||||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
|
||||||
index 1d56f8675..8647a8f87 100644
|
|
||||||
--- a/WHATS_NEW
|
|
||||||
+++ b/WHATS_NEW
|
|
||||||
@@ -1,3 +1,8 @@
|
|
||||||
+Version 2.03.26 -
|
|
||||||
+==================
|
|
||||||
+ Fix unreleased memory pools on RAID's lvextend.
|
|
||||||
+
|
|
||||||
+
|
|
||||||
Version 2.03.25 -
|
|
||||||
==================
|
|
||||||
Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it.
|
|
||||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
|
||||||
index bec363ef8..871d3bec9 100644
|
|
||||||
--- a/lib/metadata/lv_manip.c
|
|
||||||
+++ b/lib/metadata/lv_manip.c
|
|
||||||
@@ -4415,6 +4415,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
|
|
||||||
log_error("Failed to remove LV");
|
|
||||||
else if (!vg_write(vg) || !vg_commit(vg))
|
|
||||||
log_error("Failed to commit VG %s", vg->name);
|
|
||||||
+ dm_pool_free(vg->vgmem, lvl);
|
|
||||||
return_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -4571,7 +4572,7 @@ int lv_extend(struct logical_volume *lv,
|
|
||||||
alloc != ALLOC_ANYWHERE &&
|
|
||||||
!(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) {
|
|
||||||
log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv));
|
|
||||||
- if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg))
|
|
||||||
+ if (!old_extents && (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)))
|
|
||||||
return_0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
416
SOURCES/0015-man-lvmautoactivation.patch
Normal file
416
SOURCES/0015-man-lvmautoactivation.patch
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
From 25dbe3dd825a629ff7f67cb43342cc345071d3f7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 24 Nov 2021 16:03:39 -0600
|
||||||
|
Subject: [PATCH 15/54] man: lvmautoactivation
|
||||||
|
|
||||||
|
new topical man page describing autoactivation
|
||||||
|
---
|
||||||
|
man/Makefile.in | 2 +-
|
||||||
|
man/lvm.8_main | 1 +
|
||||||
|
man/lvmautoactivation.7_main | 280 +++++++++++++++++++++++++++++++++++
|
||||||
|
man/pvscan.8_des | 63 ++++----
|
||||||
|
4 files changed, 309 insertions(+), 37 deletions(-)
|
||||||
|
create mode 100644 man/lvmautoactivation.7_main
|
||||||
|
|
||||||
|
diff --git a/man/Makefile.in b/man/Makefile.in
|
||||||
|
index 40248d640..ba6f2046f 100644
|
||||||
|
--- a/man/Makefile.in
|
||||||
|
+++ b/man/Makefile.in
|
||||||
|
@@ -33,7 +33,7 @@ CMIRRORDMAN = cmirrord.8
|
||||||
|
LVMDBUSDMAN = lvmdbusd.8
|
||||||
|
|
||||||
|
MAN5=lvm.conf.5
|
||||||
|
-MAN7=lvmsystemid.7 lvmreport.7 lvmraid.7
|
||||||
|
+MAN7=lvmsystemid.7 lvmreport.7 lvmraid.7 lvmautoactivation.7
|
||||||
|
|
||||||
|
MAN8=lvm.8 lvmdump.8 lvm-fullreport.8 lvm-lvpoll.8 \
|
||||||
|
lvcreate.8 lvchange.8 lvmconfig.8 lvconvert.8 lvdisplay.8 \
|
||||||
|
diff --git a/man/lvm.8_main b/man/lvm.8_main
|
||||||
|
index 6f86d0353..a008a3bc0 100644
|
||||||
|
--- a/man/lvm.8_main
|
||||||
|
+++ b/man/lvm.8_main
|
||||||
|
@@ -579,6 +579,7 @@ Prepends source file name and code line number with libdm debugging.
|
||||||
|
.BR lvmraid (7),
|
||||||
|
.BR lvmthin (7),
|
||||||
|
.BR lvmcache (7),
|
||||||
|
+.BR lvmautoactivation (7),
|
||||||
|
.P
|
||||||
|
.BR dmsetup (8),
|
||||||
|
.BR dmstats (8),
|
||||||
|
diff --git a/man/lvmautoactivation.7_main b/man/lvmautoactivation.7_main
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..87c15a3d1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/man/lvmautoactivation.7_main
|
||||||
|
@@ -0,0 +1,280 @@
|
||||||
|
+.TH "LVMAUTOACTIVATION" "7" "LVM TOOLS #VERSION#" "Red Hat, Inc" "\""
|
||||||
|
+.
|
||||||
|
+.SH NAME
|
||||||
|
+.
|
||||||
|
+lvmautoactivation \(em LVM autoactivation
|
||||||
|
+.
|
||||||
|
+.SH DESCRIPTION
|
||||||
|
+.
|
||||||
|
+Autoactivation is the activation of LVs performed automatically by the
|
||||||
|
+system in response to LVM devices being attached to the machine. When all
|
||||||
|
+PVs in a VG have been attached, the VG is complete, and LVs in the VG are
|
||||||
|
+activated.
|
||||||
|
+.P
|
||||||
|
+Autoactivation of VGs, or specific LVs, can be prevented using vgchange or
|
||||||
|
+lvchange --setautoactivation n. The lvm.conf auto_activation_volume_list
|
||||||
|
+is another way to limit autoactivation.
|
||||||
|
+.P
|
||||||
|
+The most common form of autoactivation is "event based", in which complete
|
||||||
|
+VGs are activated in response to uevents which occur during system startup
|
||||||
|
+or at any time after the system has started. Another form of
|
||||||
|
+autoactivation is "service based" in which complete VGs are activated at a
|
||||||
|
+fixed point during system startup by a systemd service, and are not
|
||||||
|
+activated in response to uevents. This can be controlled with the
|
||||||
|
+lvm.conf setting event_activation.
|
||||||
|
+.P
|
||||||
|
+Event based autoactivation is driven by udev, udev rules, and systemd.
|
||||||
|
+When a device is attached to a machine, a uevent is generated by the
|
||||||
|
+kernel to notify userspace of the new device. systemd-udev runs udev
|
||||||
|
+rules to process the new device. Udev rules use blkid to identify the
|
||||||
|
+device as an LVM PV and then execute the lvm-specific udev rule for the
|
||||||
|
+device, which triggers autoactivation.
|
||||||
|
+.P
|
||||||
|
+There are two variations of event based autoactivation that may be used a
|
||||||
|
+system, depending on the LVM udev rule that is installed (found in
|
||||||
|
+/lib/udev/rules.d/.) The following summarizes the steps in each rule
|
||||||
|
+which lead to autoactivation:
|
||||||
|
+.P
|
||||||
|
+.B 69-dm-lvm-metad.rules
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+device /dev/name with major:minor X:Y is attached to the machine
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+systemd/udev runs blkid to identify /dev/name as an LVM PV
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+udev rule 69-dm-lvm-metad.rules is run for /dev/name
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+the lvm udev rule runs the systemd service lvm2-pvscan@X:Yservice
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+the lvm2-pvscan service runs:
|
||||||
|
+.br
|
||||||
|
+pvscan --cache -aay --major X --minor Y
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+pvscan reads the device, records that the PV is online
|
||||||
|
+(see pvs_online), and checks if the VG is complete.
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+if the VG is complete, pvscan creates the vgs_online temp file,
|
||||||
|
+and activates the VG.
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+the activation command output can be seen from
|
||||||
|
+systemctl status lvm2-pvscan*
|
||||||
|
+.P
|
||||||
|
+.B 69-dm-lvm.rules
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+device /dev/name with major:minor X:Y is attached to the machine
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+systemd/udev runs blkid to identify /dev/name as an LVM PV
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+udev rule 69-dm-lvm.rules is run for /dev/name
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+the lvm udev rule runs:
|
||||||
|
+.br
|
||||||
|
+pvscan --cache --listvg --checkcomplete --vgonline
|
||||||
|
+.br
|
||||||
|
+--autoactivation event --udevoutput --journal=output /dev/name
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+pvscan reads the device, records that the PV is online
|
||||||
|
+(see pvs_online), and checks if the VG is complete.
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+if the VG is complete, pvscan creates the vgs_online temp file,
|
||||||
|
+and prints the name of the VG for the udev rule to import:
|
||||||
|
+LVM_VG_NAME_COMPLETE='vgname'
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+if the lvm udev rule sees LVM_VG_NAME_COMPLETE from pvscan,
|
||||||
|
+it activates the VG using a transient systemd service named
|
||||||
|
+lvm-activate-<vgname>.
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+the lvm-activate-<vgname> service runs
|
||||||
|
+.br
|
||||||
|
+vgchange -aay --autoactivation event <vgname>
|
||||||
|
+.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+the activation command output can be seen from
|
||||||
|
+systemctl status lvm-activate-<vgname>
|
||||||
|
+.P
|
||||||
|
+.
|
||||||
|
+.SS pvscan options
|
||||||
|
+.P
|
||||||
|
+.B --cache
|
||||||
|
+.br
|
||||||
|
+Read the <device> arg (and only that device), and record that
|
||||||
|
+the PV is online by creating the /run/lvm/pvs_online/<pvid>
|
||||||
|
+file containing the name of the VG and the device for the PV.
|
||||||
|
+.P
|
||||||
|
+.B -aay
|
||||||
|
+.br
|
||||||
|
+Activate the VG from the pvscan command
|
||||||
|
+(includes implicit --checkcomplete and --vgonline.)
|
||||||
|
+.P
|
||||||
|
+.B --checkcomplete
|
||||||
|
+.br
|
||||||
|
+Check if the VG is complete, i.e. all PVs are present on
|
||||||
|
+the system, by checking /run/lvm/pvs_online/<pvid> files.
|
||||||
|
+.P
|
||||||
|
+.B --vgonline
|
||||||
|
+.br
|
||||||
|
+Create /run/lvm/vgs_online/<vgname> if the VG is complete
|
||||||
|
+(used to ensure only one command performs activation.)
|
||||||
|
+.P
|
||||||
|
+.B --autoactivation event
|
||||||
|
+.br
|
||||||
|
+Inform the command it is used for event based autoactivation.
|
||||||
|
+.P
|
||||||
|
+.B --listvg
|
||||||
|
+.br
|
||||||
|
+Print the name of the VG using the device.
|
||||||
|
+.P
|
||||||
|
+.B --udevoutput
|
||||||
|
+.br
|
||||||
|
+Only print output that can be imported to the udev rule,
|
||||||
|
+using the udev environment key format, i.e. NAME='value'.
|
||||||
|
+.P
|
||||||
|
+.B --journal=output
|
||||||
|
+.br
|
||||||
|
+Send standard command output to the journal (when stdout
|
||||||
|
+is reserved for udev output.)
|
||||||
|
+.P
|
||||||
|
+.SS Temp files
|
||||||
|
+.P
|
||||||
|
+Autoactivation commands use a number of temp files in /run/lvm (with the
|
||||||
|
+expectation that /run is cleared between boots.)
|
||||||
|
+.P
|
||||||
|
+.B pvs_online
|
||||||
|
+.br
|
||||||
|
+pvscan --cache creates a file here for each PV that is attached. The file
|
||||||
|
+is named with the PVID and contains the VG name and device information.
|
||||||
|
+The existence of the file is used to determine when all PVs for a given VG
|
||||||
|
+are present. The device information in these files is also used to
|
||||||
|
+optimize locating devices for a VG when the VG is activated.
|
||||||
|
+.P
|
||||||
|
+.B pvs_lookup
|
||||||
|
+.br
|
||||||
|
+pvscan --cache creates a file here named for a VG (if one doesn't already
|
||||||
|
+exist.) The file contains a list of PVIDs in the VG. This is needed when
|
||||||
|
+a PV is processed which has no VG metadata, in which case the list of
|
||||||
|
+PVIDs from the lookup file is used to check if the VG is complete.
|
||||||
|
+.P
|
||||||
|
+.B vgs_online
|
||||||
|
+.br
|
||||||
|
+The first activation command (pvscan or vgchange) to create a file here,
|
||||||
|
+named for the VG, will activate the VG. This resolves a race when
|
||||||
|
+concurrent commands attempt to activate a VG at once.
|
||||||
|
+.
|
||||||
|
+.SH EXAMPLES
|
||||||
|
+.P
|
||||||
|
+VG "vg" contains two PVs:
|
||||||
|
+.nf
|
||||||
|
+$ pvs -o name,vgname,uuid /dev/sdb /dev/sdc
|
||||||
|
+ PV VG PV UUID
|
||||||
|
+ /dev/sdb vg 1uKpaT-lFOZ-NLHX-j4jI-OBi1-QpdE-HZ5hZY
|
||||||
|
+ /dev/sdc vg 5J3tM8-aIPe-2vbd-DBe7-bvRq-TGj0-DaKV2G
|
||||||
|
+.fi
|
||||||
|
+.P
|
||||||
|
+use of --cache:
|
||||||
|
+.nf
|
||||||
|
+$ pvscan --cache /dev/sdb
|
||||||
|
+ pvscan[12922] PV /dev/sdb online.
|
||||||
|
+$ pvscan --cache /dev/sdc
|
||||||
|
+ pvscan[12923] PV /dev/sdc online.
|
||||||
|
+
|
||||||
|
+$ cat /run/lvm/pvs_online/1uKpaTlFOZNLHXj4jIOBi1QpdEHZ5hZY
|
||||||
|
+8:16
|
||||||
|
+vg:vg
|
||||||
|
+dev:/dev/sdb
|
||||||
|
+$ cat /run/lvm/pvs_online/5J3tM8aIPe2vbdDBe7bvRqTGj0DaKV2G
|
||||||
|
+8:32
|
||||||
|
+vg:vg
|
||||||
|
+dev:/dev/sdc
|
||||||
|
+.fi
|
||||||
|
+.P
|
||||||
|
+use of -aay:
|
||||||
|
+.nf
|
||||||
|
+$ pvscan --cache -aay /dev/sdb
|
||||||
|
+ pvscan[12935] PV /dev/sdb online, VG vg incomplete (need 1).
|
||||||
|
+$ pvscan --cache -aay /dev/sdc
|
||||||
|
+ pvscan[12936] PV /dev/sdc online, VG vg is complete.
|
||||||
|
+ pvscan[12936] VG vg run autoactivation.
|
||||||
|
+ 1 logical volume(s) in volume group "vg" now active
|
||||||
|
+
|
||||||
|
+$ cat /run/lvm/pvs_online/1uKpaTlFOZNLHXj4jIOBi1QpdEHZ5hZY
|
||||||
|
+8:16
|
||||||
|
+vg:vg
|
||||||
|
+dev:/dev/sdb
|
||||||
|
+$ cat /run/lvm/pvs_online/5J3tM8aIPe2vbdDBe7bvRqTGj0DaKV2G
|
||||||
|
+8:32
|
||||||
|
+vg:vg
|
||||||
|
+dev:/dev/sdc
|
||||||
|
+$ ls /run/lvm/vgs_online/vg
|
||||||
|
+/run/lvm/vgs_online/vg
|
||||||
|
+.fi
|
||||||
|
+.P
|
||||||
|
+use of --listvg:
|
||||||
|
+.nf
|
||||||
|
+$ pvscan --cache --listvg /dev/sdb
|
||||||
|
+ VG vg
|
||||||
|
+$ pvscan --cache --listvg /dev/sdc
|
||||||
|
+ VG vg
|
||||||
|
+
|
||||||
|
+$ cat /run/lvm/pvs_online/1uKpaTlFOZNLHXj4jIOBi1QpdEHZ5hZY
|
||||||
|
+8:16
|
||||||
|
+vg:vg
|
||||||
|
+dev:/dev/sdb
|
||||||
|
+$ cat /run/lvm/pvs_online/5J3tM8aIPe2vbdDBe7bvRqTGj0DaKV2G
|
||||||
|
+8:32
|
||||||
|
+vg:vg
|
||||||
|
+dev:/dev/sdc
|
||||||
|
+.fi
|
||||||
|
+.P
|
||||||
|
+use of --checkcomplete:
|
||||||
|
+.nf
|
||||||
|
+$ pvscan --cache --listvg --checkcomplete --vgonline /dev/sdb
|
||||||
|
+ pvscan[12996] PV /dev/sdb online, VG vg incomplete (need 1).
|
||||||
|
+ VG vg incomplete
|
||||||
|
+$ pvscan --cache --listvg --checkcomplete --vgonline /dev/sdc
|
||||||
|
+ pvscan[12997] PV /dev/sdc online, VG vg is complete.
|
||||||
|
+ VG vg complete
|
||||||
|
+.fi
|
||||||
|
+.P
|
||||||
|
+use of --udevoutput:
|
||||||
|
+.nf
|
||||||
|
+$ pvscan --cache --listvg --checkcomplete --vgonline --udevoutput /dev/sdb
|
||||||
|
+LVM_VG_NAME_INCOMPLETE='vg'
|
||||||
|
+$ pvscan --cache --listvg --checkcomplete --vgonline --udevoutput /dev/sdc
|
||||||
|
+LVM_VG_NAME_COMPLETE='vg'
|
||||||
|
+.fi
|
||||||
|
+.P
|
||||||
|
+use of --listlvs:
|
||||||
|
+.nf
|
||||||
|
+$ lvs -o name,devices vg
|
||||||
|
+ LV Devices
|
||||||
|
+ lvol0 /dev/sdb(0)
|
||||||
|
+ lvol1 /dev/sdc(0)
|
||||||
|
+ lvol2 /dev/sdb(1),/dev/sdc(1)
|
||||||
|
+
|
||||||
|
+$ pvscan --cache --listlvs --checkcomplete /dev/sdb
|
||||||
|
+ pvscan[13288] PV /dev/sdb online, VG vg incomplete (need 1).
|
||||||
|
+ VG vg incomplete
|
||||||
|
+ LV vg/lvol0 complete
|
||||||
|
+ LV vg/lvol2 incomplete
|
||||||
|
+$ pvscan --cache --listlvs --checkcomplete /dev/sdc
|
||||||
|
+ pvscan[13289] PV /dev/sdc online, VG vg is complete.
|
||||||
|
+ VG vg complete
|
||||||
|
+ LV vg/lvol1 complete
|
||||||
|
+ LV vg/lvol2 complete
|
||||||
|
+.fi
|
||||||
|
+
|
||||||
|
diff --git a/man/pvscan.8_des b/man/pvscan.8_des
|
||||||
|
index b20b987da..4c5929955 100644
|
||||||
|
--- a/man/pvscan.8_des
|
||||||
|
+++ b/man/pvscan.8_des
|
||||||
|
@@ -4,56 +4,47 @@ like
|
||||||
|
or
|
||||||
|
.BR pvdisplay (8).
|
||||||
|
.P
|
||||||
|
-When the --cache and -aay options are used, pvscan records which PVs are
|
||||||
|
-available on the system, and activates LVs in completed VGs. A VG is
|
||||||
|
-complete when pvscan sees that the final PV in the VG has appeared. This
|
||||||
|
-is used by event-based system startup (systemd, udev) to activate LVs.
|
||||||
|
-.P
|
||||||
|
-The four main variations of this are:
|
||||||
|
+When --cache is used, pvscan updates runtime lvm state on the system, or
|
||||||
|
+with -aay performs autoactivation.
|
||||||
|
.P
|
||||||
|
.B pvscan --cache
|
||||||
|
.I device
|
||||||
|
.P
|
||||||
|
-If device is present, lvm adds a record that the PV on device is online.
|
||||||
|
+If device is present, lvm records that the PV on device is online.
|
||||||
|
If device is not present, lvm removes the online record for the PV.
|
||||||
|
-In most cases, the pvscan will only read the named devices.
|
||||||
|
+pvscan only reads the named device.
|
||||||
|
.P
|
||||||
|
-.B pvscan --cache -aay
|
||||||
|
-.IR device ...
|
||||||
|
+.B pvscan --cache
|
||||||
|
.P
|
||||||
|
-This begins by performing the same steps as above. Afterward, if the VG
|
||||||
|
-for the specified PV is complete, then pvscan will activate LVs in the VG
|
||||||
|
-(the same as vgchange -aay vgname would do.)
|
||||||
|
+Updates the runtime state for all lvm devices.
|
||||||
|
.P
|
||||||
|
-.B pvscan --cache
|
||||||
|
+.B pvscan --cache -aay
|
||||||
|
+.I device
|
||||||
|
.P
|
||||||
|
-This first clears all existing PV online records, then scans all devices
|
||||||
|
-on the system, adding PV online records for any PVs that are found.
|
||||||
|
+Performs the --cache steps for the device, then checks if the VG using the
|
||||||
|
+device is complete. If so, LVs in the VG are autoactivated, the same as
|
||||||
|
+vgchange -aay vgname would do. (A device name may be replaced with major
|
||||||
|
+and minor numbers.)
|
||||||
|
.P
|
||||||
|
.B pvscan --cache -aay
|
||||||
|
.P
|
||||||
|
-This begins by performing the same steps as pvscan --cache. Afterward, it
|
||||||
|
-activates LVs in any complete VGs.
|
||||||
|
+Performs the --cache steps for all devices, then autoactivates any complete VGs.
|
||||||
|
.P
|
||||||
|
-To prevent devices from being scanned by pvscan --cache, add them
|
||||||
|
-to
|
||||||
|
-.BR lvm.conf (5)
|
||||||
|
-.B devices/global_filter.
|
||||||
|
-For more information, see:
|
||||||
|
-.br
|
||||||
|
-.B lvmconfig --withcomments devices/global_filter
|
||||||
|
+.B pvscan --cache --listvg|--listlvs
|
||||||
|
+.I device
|
||||||
|
+.P
|
||||||
|
+Performs the --cache steps for the device, then prints the name of the VG
|
||||||
|
+using the device, or the names of LVs using the device. --checkcomplete
|
||||||
|
+is usually included to check if all PVs for the VG or LVs are online.
|
||||||
|
+When this command is called by a udev rule, the output must conform to
|
||||||
|
+udev rule specifications (see --udevoutput.) The udev rule will use the
|
||||||
|
+results to perform autoactivation.
|
||||||
|
.P
|
||||||
|
-Auto-activation of VGs or LVs can be enabled/disabled using:
|
||||||
|
-.br
|
||||||
|
+Autoactivation of VGs or LVs can be enabled/disabled using vgchange or
|
||||||
|
+lvchange with --setautoactivation y|n, or by adding names to
|
||||||
|
.BR lvm.conf (5)
|
||||||
|
.B activation/auto_activation_volume_list
|
||||||
|
.P
|
||||||
|
-For more information, see:
|
||||||
|
-.br
|
||||||
|
-.B lvmconfig --withcomments activation/auto_activation_volume_list
|
||||||
|
-.P
|
||||||
|
-To disable auto-activation, explicitly set this list to an empty list,
|
||||||
|
-i.e. auto_activation_volume_list = [ ].
|
||||||
|
-.P
|
||||||
|
-When this setting is undefined (e.g. commented), then all LVs are
|
||||||
|
-auto-activated.
|
||||||
|
+See
|
||||||
|
+.BR lvmautoactivation (7)
|
||||||
|
+for more information about how pvscan is used for autoactivation.
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
From 10a4478e9b778dd8d4ff9737a503474b00ce9510 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 1 Dec 2021 08:56:05 -0600
|
||||||
|
Subject: [PATCH 17/54] tests devicesfile-devname.sh drop mdadm chunk
|
||||||
|
|
||||||
|
---
|
||||||
|
test/shell/devicesfile-devname.sh | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh
|
||||||
|
index a99fe3e9a..338637275 100644
|
||||||
|
--- a/test/shell/devicesfile-devname.sh
|
||||||
|
+++ b/test/shell/devicesfile-devname.sh
|
||||||
|
@@ -590,7 +590,7 @@ OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
|
||||||
|
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
||||||
|
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
||||||
|
|
||||||
|
-mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev3" "$dev4"
|
||||||
|
+mdadm --create --metadata=1.0 "$mddev" --level 1 --raid-devices=2 "$dev3" "$dev4"
|
||||||
|
wait_md_create "$mddev"
|
||||||
|
|
||||||
|
sed -e "s|DEVNAME=$dev1|DEVNAME=$dev3|" "$ORIG" > tmp1.devices
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
26
SOURCES/0018-devices-file-don-t-write-in-test-mode.patch
Normal file
26
SOURCES/0018-devices-file-don-t-write-in-test-mode.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 04770589b49effdb064c9b3790e8dd2fee2c3547 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 1 Dec 2021 10:08:08 -0600
|
||||||
|
Subject: [PATCH 18/54] devices file: don't write in test mode
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index ce7ded154..4c2b5a3dd 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -673,6 +673,9 @@ int device_ids_write(struct cmd_context *cmd)
|
||||||
|
cmd->enable_devices_file = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (test_mode())
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
if (_devices_file_version[0]) {
|
||||||
|
if (sscanf(_devices_file_version, "%u.%u.%u", &df_major, &df_minor, &df_counter) != 3) {
|
||||||
|
/* don't update a file we can't parse */
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
From 604fd528fb4f00a9f77e084a1b22eff2aeef0259 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 2 Dec 2021 12:40:52 -0600
|
||||||
|
Subject: [PATCH 19/54] print warning about unrecognized journal option value
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/log/log.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/log/log.c b/lib/log/log.c
|
||||||
|
index 7b4d537b3..5771a1d01 100644
|
||||||
|
--- a/lib/log/log.c
|
||||||
|
+++ b/lib/log/log.c
|
||||||
|
@@ -892,6 +892,7 @@ uint32_t log_journal_str_to_val(const char *str)
|
||||||
|
return LOG_JOURNAL_OUTPUT;
|
||||||
|
if (!strcasecmp(str, "debug"))
|
||||||
|
return LOG_JOURNAL_DEBUG;
|
||||||
|
+ log_warn("Ignoring unrecognized journal value.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From 357a807e81bbd1430b045eb2601a64b17d588400 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 2 Dec 2021 13:30:36 -0600
|
||||||
|
Subject: [PATCH 20/54] device_id: handle wwid with spaces or control
|
||||||
|
characters
|
||||||
|
|
||||||
|
non-standard wwid can be reported from sysfs with spaces/etc.
|
||||||
|
replace with "_"
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 10 ++++++----
|
||||||
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 4c2b5a3dd..0621bc858 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -304,6 +304,7 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
|
||||||
|
{
|
||||||
|
char sysbuf[PATH_MAX] = { 0 };
|
||||||
|
const char *idname = NULL;
|
||||||
|
+ int i;
|
||||||
|
|
||||||
|
if (idtype == DEV_ID_TYPE_SYS_WWID) {
|
||||||
|
read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf));
|
||||||
|
@@ -311,10 +312,6 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
|
||||||
|
if (!sysbuf[0])
|
||||||
|
read_sys_block(cmd, dev, "wwid", sysbuf, sizeof(sysbuf));
|
||||||
|
|
||||||
|
- /* scsi_debug wwid begins "t10.Linux scsi_debug ..." */
|
||||||
|
- if (strstr(sysbuf, "scsi_debug"))
|
||||||
|
- sysbuf[0] = '\0';
|
||||||
|
-
|
||||||
|
/* qemu wwid begins "t10.ATA QEMU HARDDISK ..." */
|
||||||
|
if (strstr(sysbuf, "QEMU HARDDISK"))
|
||||||
|
sysbuf[0] = '\0';
|
||||||
|
@@ -355,6 +352,11 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
|
||||||
|
return idname;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ for (i = 0; i < strlen(sysbuf); i++) {
|
||||||
|
+ if (isblank(sysbuf[i]) || isspace(sysbuf[i]) || iscntrl(sysbuf[i]))
|
||||||
|
+ sysbuf[i] = '_';
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!sysbuf[0])
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
From 7631c5b826b5a3eddfcd22db9b80574b249794c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 6 Dec 2021 13:20:32 -0600
|
||||||
|
Subject: [PATCH 21/54] man: add section about static autoactivation
|
||||||
|
|
||||||
|
---
|
||||||
|
man/lvmautoactivation.7_main | 48 ++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 41 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/lvmautoactivation.7_main b/man/lvmautoactivation.7_main
|
||||||
|
index 87c15a3d1..bf885991d 100644
|
||||||
|
--- a/man/lvmautoactivation.7_main
|
||||||
|
+++ b/man/lvmautoactivation.7_main
|
||||||
|
@@ -14,14 +14,16 @@ activated.
|
||||||
|
Autoactivation of VGs, or specific LVs, can be prevented using vgchange or
|
||||||
|
lvchange --setautoactivation n. The lvm.conf auto_activation_volume_list
|
||||||
|
is another way to limit autoactivation.
|
||||||
|
+.
|
||||||
|
+.SS event autoactivation
|
||||||
|
.P
|
||||||
|
The most common form of autoactivation is "event based", in which complete
|
||||||
|
VGs are activated in response to uevents which occur during system startup
|
||||||
|
or at any time after the system has started. Another form of
|
||||||
|
-autoactivation is "service based" in which complete VGs are activated at a
|
||||||
|
-fixed point during system startup by a systemd service, and are not
|
||||||
|
-activated in response to uevents. This can be controlled with the
|
||||||
|
-lvm.conf setting event_activation.
|
||||||
|
+autoactivation is "static" in which complete VGs are activated at a fixed
|
||||||
|
+point during system startup by a systemd service, and not in response to
|
||||||
|
+events. This can be controlled with the lvm.conf setting
|
||||||
|
+event_activation.
|
||||||
|
.P
|
||||||
|
Event based autoactivation is driven by udev, udev rules, and systemd.
|
||||||
|
When a device is attached to a machine, a uevent is generated by the
|
||||||
|
@@ -30,8 +32,8 @@ rules to process the new device. Udev rules use blkid to identify the
|
||||||
|
device as an LVM PV and then execute the lvm-specific udev rule for the
|
||||||
|
device, which triggers autoactivation.
|
||||||
|
.P
|
||||||
|
-There are two variations of event based autoactivation that may be used a
|
||||||
|
-system, depending on the LVM udev rule that is installed (found in
|
||||||
|
+There are two variations of event baed autoactivation that may be used on
|
||||||
|
+a system, depending on the LVM udev rule that is installed (found in
|
||||||
|
/lib/udev/rules.d/.) The following summarizes the steps in each rule
|
||||||
|
which lead to autoactivation:
|
||||||
|
.P
|
||||||
|
@@ -149,7 +151,7 @@ using the udev environment key format, i.e. NAME='value'.
|
||||||
|
Send standard command output to the journal (when stdout
|
||||||
|
is reserved for udev output.)
|
||||||
|
.P
|
||||||
|
-.SS Temp files
|
||||||
|
+.SS run files
|
||||||
|
.P
|
||||||
|
Autoactivation commands use a number of temp files in /run/lvm (with the
|
||||||
|
expectation that /run is cleared between boots.)
|
||||||
|
@@ -175,6 +177,38 @@ The first activation command (pvscan or vgchange) to create a file here,
|
||||||
|
named for the VG, will activate the VG. This resolves a race when
|
||||||
|
concurrent commands attempt to activate a VG at once.
|
||||||
|
.
|
||||||
|
+.SS static autoactivation
|
||||||
|
+.P
|
||||||
|
+When event autoactivation is disabled by setting lvm.conf
|
||||||
|
+event_activation=0, autoactivation is performed at one or more static
|
||||||
|
+points during system startup. At these points, a vgchange -aay command is
|
||||||
|
+run to activate complete VGs from devices that are present on the system
|
||||||
|
+at that time. pvscan commands (and lvm2-pvscan services) do not perform
|
||||||
|
+autoactivation in this mode. pvscan commands may still be run from
|
||||||
|
+uevents but will do nothing when they read the event_activation=0 setting.
|
||||||
|
+.P
|
||||||
|
+The static vgchange -aay commands are run by three systemd services at
|
||||||
|
+three points during startup: lvm2-activation-early, lvm2-activation, and
|
||||||
|
+lvm2-activation-net. These static activation services are "generated
|
||||||
|
+services", so the service files are created at run time by the
|
||||||
|
+lvm2-activation-generator command (run by systemd).
|
||||||
|
+lvm2-activation-generator creates the services if lvm.conf
|
||||||
|
+event_activation=0.
|
||||||
|
+.P
|
||||||
|
+The limitation of this method is that devices may not be attached to the
|
||||||
|
+system (or set up) at a reliable point in time during startup, and they
|
||||||
|
+may not be present when the services run vgchange. In this case, the VGs
|
||||||
|
+will not be autoactivated. So, the timing of device attachment/setup
|
||||||
|
+determines whether static autoactivation will produce the same results as
|
||||||
|
+event autoactivation. For this reason, static autoactivation is not
|
||||||
|
+recommended.
|
||||||
|
+.P
|
||||||
|
+Sometimes, static autoactivation is mistakenly expected to disable all
|
||||||
|
+autoactivation of particular VGs. This may appear to be effective if those
|
||||||
|
+VGs are slow to be attached or set up. But, the only correct and reliable
|
||||||
|
+way to disable autoactivation is using vgchange/lvchange
|
||||||
|
+--setautoactivation n, or lvm.conf auto_activation_volume_list.
|
||||||
|
+.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.P
|
||||||
|
VG "vg" contains two PVs:
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
35
SOURCES/0022-lvcreate-include-recent-options.patch
Normal file
35
SOURCES/0022-lvcreate-include-recent-options.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From af4bfa1f1f84194000bc50f43ddc906c0cd4b104 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 13 Dec 2021 08:59:31 -0600
|
||||||
|
Subject: [PATCH 22/54] lvcreate: include recent options
|
||||||
|
|
||||||
|
The permitted option list in lvcreate has not kept
|
||||||
|
up with command-lines.in.
|
||||||
|
---
|
||||||
|
tools/lvcreate.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index 0121c09a8..79af42685 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -824,12 +824,16 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
autobackup_ARG,\
|
||||||
|
available_ARG,\
|
||||||
|
contiguous_ARG,\
|
||||||
|
+ devices_ARG,\
|
||||||
|
+ devicesfile_ARG,\
|
||||||
|
ignoreactivationskip_ARG,\
|
||||||
|
ignoremonitoring_ARG,\
|
||||||
|
+ journal_ARG,\
|
||||||
|
metadataprofile_ARG,\
|
||||||
|
monitor_ARG,\
|
||||||
|
mirrors_ARG,\
|
||||||
|
name_ARG,\
|
||||||
|
+ nohints_ARG,\
|
||||||
|
noudevsync_ARG,\
|
||||||
|
permission_ARG,\
|
||||||
|
persistent_ARG,\
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From 61833dd5b6117e8ace84289cff656d1dfb0ed123 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 14 Dec 2021 12:02:08 -0600
|
||||||
|
Subject: [PATCH 23/54] man lvmautoactivation: replace systemctl with
|
||||||
|
journalctl
|
||||||
|
|
||||||
|
---
|
||||||
|
man/lvmautoactivation.7_main | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/man/lvmautoactivation.7_main b/man/lvmautoactivation.7_main
|
||||||
|
index bf885991d..54dab718b 100644
|
||||||
|
--- a/man/lvmautoactivation.7_main
|
||||||
|
+++ b/man/lvmautoactivation.7_main
|
||||||
|
@@ -107,7 +107,7 @@ vgchange -aay --autoactivation event <vgname>
|
||||||
|
.
|
||||||
|
.IP \[bu] 2
|
||||||
|
the activation command output can be seen from
|
||||||
|
-systemctl status lvm-activate-<vgname>
|
||||||
|
+journalctl -u lvm-activate-<vgname>
|
||||||
|
.P
|
||||||
|
.
|
||||||
|
.SS pvscan options
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
196
SOURCES/0024-make-generate.patch
Normal file
196
SOURCES/0024-make-generate.patch
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
From 4b26fb3543049f3d179b620ff937c44e922ada58 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marian Csontos <mcsontos@redhat.com>
|
||||||
|
Date: Tue, 4 Jan 2022 17:15:56 +0100
|
||||||
|
Subject: [PATCH 24/54] make: generate
|
||||||
|
|
||||||
|
---
|
||||||
|
man/lvdisplay.8_pregen | 12 --------
|
||||||
|
man/pvdisplay.8_pregen | 12 --------
|
||||||
|
man/pvscan.8_pregen | 63 ++++++++++++++++++------------------------
|
||||||
|
man/vgdisplay.8_pregen | 12 --------
|
||||||
|
4 files changed, 27 insertions(+), 72 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen
|
||||||
|
index a1740ebed..04aab4c09 100644
|
||||||
|
--- a/man/lvdisplay.8_pregen
|
||||||
|
+++ b/man/lvdisplay.8_pregen
|
||||||
|
@@ -61,8 +61,6 @@ and more, using a more compact and configurable output format.
|
||||||
|
.br
|
||||||
|
[ \fB--readonly\fP ]
|
||||||
|
.br
|
||||||
|
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
|
||||||
|
-.br
|
||||||
|
[ \fB--segments\fP ]
|
||||||
|
.br
|
||||||
|
[ \fB--separator\fP \fIString\fP ]
|
||||||
|
@@ -332,16 +330,6 @@ device-mapper kernel driver, so this option is unable to report whether
|
||||||
|
or not LVs are actually in use.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
|
||||||
|
-.br
|
||||||
|
-Overrides current output format for reports which is defined globally by
|
||||||
|
-the report/output_format setting in \fBlvm.conf\fP(5).
|
||||||
|
-\fBbasic\fP is the original format with columns and rows.
|
||||||
|
-If there is more than one report per command, each report is prefixed
|
||||||
|
-with the report name for identification. \fBjson\fP produces report
|
||||||
|
-output in JSON format. See \fBlvmreport\fP(7) for more information.
|
||||||
|
-.
|
||||||
|
-.HP
|
||||||
|
\fB--segments\fP
|
||||||
|
.br
|
||||||
|
.
|
||||||
|
diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen
|
||||||
|
index 22a0992b5..2f26a8727 100644
|
||||||
|
--- a/man/pvdisplay.8_pregen
|
||||||
|
+++ b/man/pvdisplay.8_pregen
|
||||||
|
@@ -61,8 +61,6 @@ and more, using a more compact and configurable output format.
|
||||||
|
.br
|
||||||
|
[ \fB--readonly\fP ]
|
||||||
|
.br
|
||||||
|
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
|
||||||
|
-.br
|
||||||
|
[ \fB--separator\fP \fIString\fP ]
|
||||||
|
.br
|
||||||
|
[ \fB--shared\fP ]
|
||||||
|
@@ -320,16 +318,6 @@ device-mapper kernel driver, so this option is unable to report whether
|
||||||
|
or not LVs are actually in use.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
|
||||||
|
-.br
|
||||||
|
-Overrides current output format for reports which is defined globally by
|
||||||
|
-the report/output_format setting in \fBlvm.conf\fP(5).
|
||||||
|
-\fBbasic\fP is the original format with columns and rows.
|
||||||
|
-If there is more than one report per command, each report is prefixed
|
||||||
|
-with the report name for identification. \fBjson\fP produces report
|
||||||
|
-output in JSON format. See \fBlvmreport\fP(7) for more information.
|
||||||
|
-.
|
||||||
|
-.HP
|
||||||
|
\fB-S\fP|\fB--select\fP \fIString\fP
|
||||||
|
.br
|
||||||
|
Select objects for processing and reporting based on specified criteria.
|
||||||
|
diff --git a/man/pvscan.8_pregen b/man/pvscan.8_pregen
|
||||||
|
index 9eb6b5bf9..1c96d5aab 100644
|
||||||
|
--- a/man/pvscan.8_pregen
|
||||||
|
+++ b/man/pvscan.8_pregen
|
||||||
|
@@ -91,59 +91,50 @@ like
|
||||||
|
or
|
||||||
|
.BR pvdisplay (8).
|
||||||
|
.P
|
||||||
|
-When the --cache and -aay options are used, pvscan records which PVs are
|
||||||
|
-available on the system, and activates LVs in completed VGs. A VG is
|
||||||
|
-complete when pvscan sees that the final PV in the VG has appeared. This
|
||||||
|
-is used by event-based system startup (systemd, udev) to activate LVs.
|
||||||
|
-.P
|
||||||
|
-The four main variations of this are:
|
||||||
|
+When --cache is used, pvscan updates runtime lvm state on the system, or
|
||||||
|
+with -aay performs autoactivation.
|
||||||
|
.P
|
||||||
|
.B pvscan --cache
|
||||||
|
.I device
|
||||||
|
.P
|
||||||
|
-If device is present, lvm adds a record that the PV on device is online.
|
||||||
|
+If device is present, lvm records that the PV on device is online.
|
||||||
|
If device is not present, lvm removes the online record for the PV.
|
||||||
|
-In most cases, the pvscan will only read the named devices.
|
||||||
|
+pvscan only reads the named device.
|
||||||
|
.P
|
||||||
|
-.B pvscan --cache -aay
|
||||||
|
-.IR device ...
|
||||||
|
+.B pvscan --cache
|
||||||
|
.P
|
||||||
|
-This begins by performing the same steps as above. Afterward, if the VG
|
||||||
|
-for the specified PV is complete, then pvscan will activate LVs in the VG
|
||||||
|
-(the same as vgchange -aay vgname would do.)
|
||||||
|
+Updates the runtime state for all lvm devices.
|
||||||
|
.P
|
||||||
|
-.B pvscan --cache
|
||||||
|
+.B pvscan --cache -aay
|
||||||
|
+.I device
|
||||||
|
.P
|
||||||
|
-This first clears all existing PV online records, then scans all devices
|
||||||
|
-on the system, adding PV online records for any PVs that are found.
|
||||||
|
+Performs the --cache steps for the device, then checks if the VG using the
|
||||||
|
+device is complete. If so, LVs in the VG are autoactivated, the same as
|
||||||
|
+vgchange -aay vgname would do. (A device name may be replaced with major
|
||||||
|
+and minor numbers.)
|
||||||
|
.P
|
||||||
|
.B pvscan --cache -aay
|
||||||
|
.P
|
||||||
|
-This begins by performing the same steps as pvscan --cache. Afterward, it
|
||||||
|
-activates LVs in any complete VGs.
|
||||||
|
+Performs the --cache steps for all devices, then autoactivates any complete VGs.
|
||||||
|
.P
|
||||||
|
-To prevent devices from being scanned by pvscan --cache, add them
|
||||||
|
-to
|
||||||
|
-.BR lvm.conf (5)
|
||||||
|
-.B devices/global_filter.
|
||||||
|
-For more information, see:
|
||||||
|
-.br
|
||||||
|
-.B lvmconfig --withcomments devices/global_filter
|
||||||
|
+.B pvscan --cache --listvg|--listlvs
|
||||||
|
+.I device
|
||||||
|
.P
|
||||||
|
-Auto-activation of VGs or LVs can be enabled/disabled using:
|
||||||
|
-.br
|
||||||
|
+Performs the --cache steps for the device, then prints the name of the VG
|
||||||
|
+using the device, or the names of LVs using the device. --checkcomplete
|
||||||
|
+is usually included to check if all PVs for the VG or LVs are online.
|
||||||
|
+When this command is called by a udev rule, the output must conform to
|
||||||
|
+udev rule specifications (see --udevoutput.) The udev rule will use the
|
||||||
|
+results to perform autoactivation.
|
||||||
|
+.P
|
||||||
|
+Autoactivation of VGs or LVs can be enabled/disabled using vgchange or
|
||||||
|
+lvchange with --setautoactivation y|n, or by adding names to
|
||||||
|
.BR lvm.conf (5)
|
||||||
|
.B activation/auto_activation_volume_list
|
||||||
|
.P
|
||||||
|
-For more information, see:
|
||||||
|
-.br
|
||||||
|
-.B lvmconfig --withcomments activation/auto_activation_volume_list
|
||||||
|
-.P
|
||||||
|
-To disable auto-activation, explicitly set this list to an empty list,
|
||||||
|
-i.e. auto_activation_volume_list = [ ].
|
||||||
|
-.P
|
||||||
|
-When this setting is undefined (e.g. commented), then all LVs are
|
||||||
|
-auto-activated.
|
||||||
|
+See
|
||||||
|
+.BR lvmautoactivation (7)
|
||||||
|
+for more information about how pvscan is used for autoactivation.
|
||||||
|
.
|
||||||
|
.SH USAGE
|
||||||
|
.
|
||||||
|
diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen
|
||||||
|
index 9c694921d..0a12b3c39 100644
|
||||||
|
--- a/man/vgdisplay.8_pregen
|
||||||
|
+++ b/man/vgdisplay.8_pregen
|
||||||
|
@@ -58,8 +58,6 @@ and more, using a more compact and configurable output format.
|
||||||
|
.br
|
||||||
|
[ \fB--readonly\fP ]
|
||||||
|
.br
|
||||||
|
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
|
||||||
|
-.br
|
||||||
|
[ \fB--shared\fP ]
|
||||||
|
.br
|
||||||
|
[ \fB--separator\fP \fIString\fP ]
|
||||||
|
@@ -312,16 +310,6 @@ device-mapper kernel driver, so this option is unable to report whether
|
||||||
|
or not LVs are actually in use.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
|
||||||
|
-.br
|
||||||
|
-Overrides current output format for reports which is defined globally by
|
||||||
|
-the report/output_format setting in \fBlvm.conf\fP(5).
|
||||||
|
-\fBbasic\fP is the original format with columns and rows.
|
||||||
|
-If there is more than one report per command, each report is prefixed
|
||||||
|
-with the report name for identification. \fBjson\fP produces report
|
||||||
|
-output in JSON format. See \fBlvmreport\fP(7) for more information.
|
||||||
|
-.
|
||||||
|
-.HP
|
||||||
|
\fB-S\fP|\fB--select\fP \fIString\fP
|
||||||
|
.br
|
||||||
|
Select objects for processing and reporting based on specified criteria.
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
141
SOURCES/0025-pvcreate-overwrite-partition-header-with-f.patch
Normal file
141
SOURCES/0025-pvcreate-overwrite-partition-header-with-f.patch
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
From a5c37afdca97d6565ea02bc4bc7d52f360823cd3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 8 Sep 2021 16:30:11 -0500
|
||||||
|
Subject: [PATCH 25/54] pvcreate: overwrite partition header with -f
|
||||||
|
|
||||||
|
$ pvcreate /dev/sdc
|
||||||
|
Cannot use /dev/sdc: device is partitioned
|
||||||
|
$ pvcreate -f /dev/sdc
|
||||||
|
Physical volume "/dev/sdc" successfully created.
|
||||||
|
---
|
||||||
|
lib/commands/toolcontext.h | 1 +
|
||||||
|
lib/filters/filter-partitioned.c | 3 +++
|
||||||
|
man/pvcreate.8_des | 7 ++++---
|
||||||
|
test/shell/test-partition.sh | 12 ++++++++++--
|
||||||
|
tools/toollib.c | 10 ++++++++++
|
||||||
|
5 files changed, 28 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
||||||
|
index 356c79f8a..b83883fb8 100644
|
||||||
|
--- a/lib/commands/toolcontext.h
|
||||||
|
+++ b/lib/commands/toolcontext.h
|
||||||
|
@@ -201,6 +201,7 @@ struct cmd_context {
|
||||||
|
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
|
||||||
|
unsigned backup_disabled:1; /* skip repeated debug message */
|
||||||
|
unsigned event_activation:1; /* whether event_activation is set */
|
||||||
|
+ unsigned filter_partitioned_skip:1; /* don't use filter-partitioned */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Devices and filtering.
|
||||||
|
diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c
|
||||||
|
index 642553ef2..8f468a567 100644
|
||||||
|
--- a/lib/filters/filter-partitioned.c
|
||||||
|
+++ b/lib/filters/filter-partitioned.c
|
||||||
|
@@ -27,6 +27,9 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
|
||||||
|
if (cmd->filter_nodata_only)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
+ if (cmd->filter_partitioned_skip)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
|
||||||
|
|
||||||
|
ret = dev_is_partitioned(cmd, dev);
|
||||||
|
diff --git a/man/pvcreate.8_des b/man/pvcreate.8_des
|
||||||
|
index 69bd133aa..4048eb71c 100644
|
||||||
|
--- a/man/pvcreate.8_des
|
||||||
|
+++ b/man/pvcreate.8_des
|
||||||
|
@@ -7,9 +7,10 @@ Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8)
|
||||||
|
to add the PV to an existing VG. Use \fBpvremove\fP(8) to remove the LVM
|
||||||
|
disk label from the device.
|
||||||
|
.P
|
||||||
|
-The force option will create a PV without confirmation. Repeating the
|
||||||
|
-force option (\fB-ff\fP) will forcibly create a PV, overriding checks that
|
||||||
|
-normally prevent it, e.g. if the PV is already in a VG.
|
||||||
|
+The force option will create a PV without confirmation, and will overwrite
|
||||||
|
+partition headers. Repeating the force option (\fB-ff\fP) will override other
|
||||||
|
+checks that would normally prevent a pvcreate, e.g. if the PV is already in a
|
||||||
|
+VG.
|
||||||
|
.P
|
||||||
|
.B Metadata location, size, and alignment
|
||||||
|
.P
|
||||||
|
diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh
|
||||||
|
index 0e92f00db..3a45f9089 100644
|
||||||
|
--- a/test/shell/test-partition.sh
|
||||||
|
+++ b/test/shell/test-partition.sh
|
||||||
|
@@ -16,7 +16,6 @@
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
SKIP_WITH_LVMPOLLD=1
|
||||||
|
|
||||||
|
LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
|
||||||
|
@@ -25,7 +24,7 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
|
||||||
|
|
||||||
|
which sfdisk || skip
|
||||||
|
|
||||||
|
-aux prepare_pvs 1 30
|
||||||
|
+aux prepare_pvs 2 30
|
||||||
|
|
||||||
|
pvs "$dev1"
|
||||||
|
|
||||||
|
@@ -33,3 +32,12 @@ pvs "$dev1"
|
||||||
|
echo "1 2" | sfdisk --force "$dev1"
|
||||||
|
|
||||||
|
not pvs "$dev1"
|
||||||
|
+
|
||||||
|
+wipefs -a "$dev2"
|
||||||
|
+echo "1 2" | sfdisk --force "$dev2"
|
||||||
|
+partprobe
|
||||||
|
+not pvcreate "$dev2"
|
||||||
|
+pvcreate -f "$dev2"
|
||||||
|
+pvs "$dev2"
|
||||||
|
+pvremove "$dev2"
|
||||||
|
+
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index d6f48aad2..80d3de57c 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -5243,6 +5243,10 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
||||||
|
if (cmd->enable_devices_file && !pp->is_remove)
|
||||||
|
cmd->filter_deviceid_skip = 1;
|
||||||
|
|
||||||
|
+ /* pvcreate -f overwrites partitions */
|
||||||
|
+ if (pp->force && !pp->is_remove)
|
||||||
|
+ cmd->filter_partitioned_skip = 1;
|
||||||
|
+
|
||||||
|
log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs));
|
||||||
|
label_scan_devs(cmd, cmd->filter, &scan_devs);
|
||||||
|
|
||||||
|
@@ -5257,6 +5261,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmd->filter_deviceid_skip = 0;
|
||||||
|
+ cmd->filter_partitioned_skip = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can the command continue if some specified devices were not found?
|
||||||
|
@@ -5469,6 +5474,9 @@ do_command:
|
||||||
|
if (cmd->enable_devices_file && !pp->is_remove)
|
||||||
|
cmd->filter_deviceid_skip = 1;
|
||||||
|
|
||||||
|
+ if (pp->force && !pp->is_remove)
|
||||||
|
+ cmd->filter_partitioned_skip = 1;
|
||||||
|
+
|
||||||
|
log_debug("Rescanning and filtering device args with exclusive open");
|
||||||
|
if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) {
|
||||||
|
log_debug("Failed to rescan devs excl");
|
||||||
|
@@ -5482,7 +5490,9 @@ do_command:
|
||||||
|
dm_list_add(&pp->arg_fail, &pd->list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
cmd->filter_deviceid_skip = 0;
|
||||||
|
+ cmd->filter_partitioned_skip = 0;
|
||||||
|
|
||||||
|
if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) {
|
||||||
|
log_debug("No devices to process.");
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,166 @@
|
|||||||
|
From bb477d63e336a10e5959962a9f26a028ea9e55eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 13 Jan 2022 14:52:54 -0600
|
||||||
|
Subject: [PATCH 26/54] lvmdevices check: error exit if update is needed
|
||||||
|
|
||||||
|
. error exit means that lvmdevices --update would make a change.
|
||||||
|
|
||||||
|
. remove check of PART field from --check because it isn't used.
|
||||||
|
|
||||||
|
. unlink searched_devnames file to ensure check|update will search
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 3 ++-
|
||||||
|
test/shell/devicesfile-realdevs.sh | 8 +++----
|
||||||
|
tools/args.h | 3 ++-
|
||||||
|
tools/lvmdevices.c | 37 +++++++++++++-----------------
|
||||||
|
4 files changed, 24 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 0621bc858..a33dcebe0 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -2271,7 +2271,8 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- log_warn("Devices file PVID %s updating IDNAME to %s.", dev->pvid, devname);
|
||||||
|
+ if (!noupdate)
|
||||||
|
+ log_warn("Devices file PVID %s updating IDNAME to %s.", dev->pvid, devname);
|
||||||
|
|
||||||
|
free(du->idname);
|
||||||
|
free(du->devname);
|
||||||
|
diff --git a/test/shell/devicesfile-realdevs.sh b/test/shell/devicesfile-realdevs.sh
|
||||||
|
index 8d4aa3e67..23d4bedb4 100644
|
||||||
|
--- a/test/shell/devicesfile-realdevs.sh
|
||||||
|
+++ b/test/shell/devicesfile-realdevs.sh
|
||||||
|
@@ -423,7 +423,7 @@ sed "s/$pvid1/badpvid/" "$DF.orig" |tee $DF
|
||||||
|
not grep $pvid1 $DF
|
||||||
|
grep $did1 $DF
|
||||||
|
|
||||||
|
-lvmdevices --check 2>&1|tee out
|
||||||
|
+not lvmdevices --check 2>&1|tee out
|
||||||
|
grep $dev1 out
|
||||||
|
grep badpvid out
|
||||||
|
grep $pvid1 out
|
||||||
|
@@ -493,7 +493,7 @@ rm $DF
|
||||||
|
d1=$(basename $dev1)
|
||||||
|
d3=$(basename $dev3)
|
||||||
|
sed "s/$d1/$d3/" "$DF.orig" |tee $DF
|
||||||
|
-lvmdevices --check 2>&1 |tee out
|
||||||
|
+not lvmdevices --check 2>&1 |tee out
|
||||||
|
grep $dev1 out
|
||||||
|
|
||||||
|
lvmdevices --update
|
||||||
|
@@ -515,7 +515,7 @@ sed "s/$d1/tmp/" "$DF.orig" |tee ${DF}_1
|
||||||
|
sed "s/$d2/$d1/" "${DF}_1" |tee ${DF}_2
|
||||||
|
sed "s/tmp/$d2/" "${DF}_2" |tee $DF
|
||||||
|
rm ${DF}_1 ${DF}_2
|
||||||
|
-lvmdevices --check 2>&1 |tee out
|
||||||
|
+not lvmdevices --check 2>&1 |tee out
|
||||||
|
grep $dev1 out
|
||||||
|
grep $dev2 out
|
||||||
|
|
||||||
|
@@ -536,7 +536,7 @@ rm $DF
|
||||||
|
d1=$(basename $dev1)
|
||||||
|
d3=$(basename $dev3)
|
||||||
|
sed "s/$d1/$d3/" "$DF.orig" |tee $DF
|
||||||
|
-lvmdevices --check 2>&1 |tee out
|
||||||
|
+not lvmdevices --check 2>&1 |tee out
|
||||||
|
grep $dev1 out
|
||||||
|
|
||||||
|
pvs -o+uuid,deviceid | grep $vg |tee out
|
||||||
|
diff --git a/tools/args.h b/tools/args.h
|
||||||
|
index 774ce33f4..9a7bf81b2 100644
|
||||||
|
--- a/tools/args.h
|
||||||
|
+++ b/tools/args.h
|
||||||
|
@@ -153,7 +153,8 @@ arg(cachesize_ARG, '\0', "cachesize", sizemb_VAL, 0, 0,
|
||||||
|
"The size of cache to use.\n")
|
||||||
|
|
||||||
|
arg(check_ARG, '\0', "check", 0, 0, 0,
|
||||||
|
- "Check the content of the devices file.\n")
|
||||||
|
+ "Checks the content of the devices file.\n"
|
||||||
|
+ "Reports incorrect device names or PVIDs for entries.\n")
|
||||||
|
|
||||||
|
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0,
|
||||||
|
"The command profile to use for command configuration.\n"
|
||||||
|
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||||
|
index 3f104f7de..c50c09f90 100644
|
||||||
|
--- a/tools/lvmdevices.c
|
||||||
|
+++ b/tools/lvmdevices.c
|
||||||
|
@@ -128,7 +128,6 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
struct device *dev;
|
||||||
|
struct dev_use *du, *du2;
|
||||||
|
const char *deviceidtype;
|
||||||
|
- int changes = 0;
|
||||||
|
|
||||||
|
dm_list_init(&search_pvids);
|
||||||
|
dm_list_init(&found_devs);
|
||||||
|
@@ -184,8 +183,11 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
|
||||||
|
if (arg_is_set(cmd, check_ARG) || arg_is_set(cmd, update_ARG)) {
|
||||||
|
int search_count = 0;
|
||||||
|
+ int update_needed = 0;
|
||||||
|
int invalid = 0;
|
||||||
|
|
||||||
|
+ unlink_searched_devnames(cmd);
|
||||||
|
+
|
||||||
|
label_scan_setup_bcache();
|
||||||
|
|
||||||
|
dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
@@ -225,6 +227,8 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
* run just above.
|
||||||
|
*/
|
||||||
|
device_ids_validate(cmd, NULL, &invalid, 1);
|
||||||
|
+ if (invalid)
|
||||||
|
+ update_needed = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and fix any devname entries that have moved to a
|
||||||
|
@@ -240,33 +244,24 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
label_scan_invalidate(du->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * check du->part
|
||||||
|
- */
|
||||||
|
- dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
- int part = 0;
|
||||||
|
- if (!du->dev)
|
||||||
|
- continue;
|
||||||
|
- dev = du->dev;
|
||||||
|
-
|
||||||
|
- dev_get_partition_number(dev, &part);
|
||||||
|
-
|
||||||
|
- if (part != du->part) {
|
||||||
|
- log_warn("Device %s partition %u has incorrect PART in devices file (%u)",
|
||||||
|
- dev_name(dev), part, du->part);
|
||||||
|
- du->part = part;
|
||||||
|
- changes++;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (arg_is_set(cmd, update_ARG)) {
|
||||||
|
- if (invalid || !dm_list_empty(&found_devs)) {
|
||||||
|
+ if (update_needed || !dm_list_empty(&found_devs)) {
|
||||||
|
if (!device_ids_write(cmd))
|
||||||
|
goto_bad;
|
||||||
|
log_print("Updated devices file to version %s", devices_file_version());
|
||||||
|
} else {
|
||||||
|
log_print("No update for devices file is needed.");
|
||||||
|
}
|
||||||
|
+ } else {
|
||||||
|
+ /*
|
||||||
|
+ * --check exits with an error if the devices file
|
||||||
|
+ * needs updates, i.e. running --update would make
|
||||||
|
+ * changes.
|
||||||
|
+ */
|
||||||
|
+ if (update_needed) {
|
||||||
|
+ log_error("Updates needed for devices file.");
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,140 @@
|
|||||||
|
From 9375aebad1db72267dd67e3ed768aa3b0e698d52 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 18 Jan 2022 12:16:52 -0600
|
||||||
|
Subject: [PATCH 27/54] Revert "pvcreate: overwrite partition header with -f"
|
||||||
|
|
||||||
|
This reverts commit a5c37afdca97d6565ea02bc4bc7d52f360823cd3.
|
||||||
|
|
||||||
|
This commit did not properly recognize GPT cases.
|
||||||
|
---
|
||||||
|
lib/commands/toolcontext.h | 1 -
|
||||||
|
lib/filters/filter-partitioned.c | 3 ---
|
||||||
|
man/pvcreate.8_des | 7 +++----
|
||||||
|
test/shell/test-partition.sh | 12 ++----------
|
||||||
|
tools/toollib.c | 10 ----------
|
||||||
|
5 files changed, 5 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
||||||
|
index b83883fb8..356c79f8a 100644
|
||||||
|
--- a/lib/commands/toolcontext.h
|
||||||
|
+++ b/lib/commands/toolcontext.h
|
||||||
|
@@ -201,7 +201,6 @@ struct cmd_context {
|
||||||
|
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
|
||||||
|
unsigned backup_disabled:1; /* skip repeated debug message */
|
||||||
|
unsigned event_activation:1; /* whether event_activation is set */
|
||||||
|
- unsigned filter_partitioned_skip:1; /* don't use filter-partitioned */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Devices and filtering.
|
||||||
|
diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c
|
||||||
|
index 8f468a567..642553ef2 100644
|
||||||
|
--- a/lib/filters/filter-partitioned.c
|
||||||
|
+++ b/lib/filters/filter-partitioned.c
|
||||||
|
@@ -27,9 +27,6 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
|
||||||
|
if (cmd->filter_nodata_only)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
- if (cmd->filter_partitioned_skip)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
|
||||||
|
|
||||||
|
ret = dev_is_partitioned(cmd, dev);
|
||||||
|
diff --git a/man/pvcreate.8_des b/man/pvcreate.8_des
|
||||||
|
index 4048eb71c..69bd133aa 100644
|
||||||
|
--- a/man/pvcreate.8_des
|
||||||
|
+++ b/man/pvcreate.8_des
|
||||||
|
@@ -7,10 +7,9 @@ Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8)
|
||||||
|
to add the PV to an existing VG. Use \fBpvremove\fP(8) to remove the LVM
|
||||||
|
disk label from the device.
|
||||||
|
.P
|
||||||
|
-The force option will create a PV without confirmation, and will overwrite
|
||||||
|
-partition headers. Repeating the force option (\fB-ff\fP) will override other
|
||||||
|
-checks that would normally prevent a pvcreate, e.g. if the PV is already in a
|
||||||
|
-VG.
|
||||||
|
+The force option will create a PV without confirmation. Repeating the
|
||||||
|
+force option (\fB-ff\fP) will forcibly create a PV, overriding checks that
|
||||||
|
+normally prevent it, e.g. if the PV is already in a VG.
|
||||||
|
.P
|
||||||
|
.B Metadata location, size, and alignment
|
||||||
|
.P
|
||||||
|
diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh
|
||||||
|
index 3a45f9089..0e92f00db 100644
|
||||||
|
--- a/test/shell/test-partition.sh
|
||||||
|
+++ b/test/shell/test-partition.sh
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
+
|
||||||
|
SKIP_WITH_LVMPOLLD=1
|
||||||
|
|
||||||
|
LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
|
||||||
|
@@ -24,7 +25,7 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
|
||||||
|
|
||||||
|
which sfdisk || skip
|
||||||
|
|
||||||
|
-aux prepare_pvs 2 30
|
||||||
|
+aux prepare_pvs 1 30
|
||||||
|
|
||||||
|
pvs "$dev1"
|
||||||
|
|
||||||
|
@@ -32,12 +33,3 @@ pvs "$dev1"
|
||||||
|
echo "1 2" | sfdisk --force "$dev1"
|
||||||
|
|
||||||
|
not pvs "$dev1"
|
||||||
|
-
|
||||||
|
-wipefs -a "$dev2"
|
||||||
|
-echo "1 2" | sfdisk --force "$dev2"
|
||||||
|
-partprobe
|
||||||
|
-not pvcreate "$dev2"
|
||||||
|
-pvcreate -f "$dev2"
|
||||||
|
-pvs "$dev2"
|
||||||
|
-pvremove "$dev2"
|
||||||
|
-
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 80d3de57c..d6f48aad2 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -5243,10 +5243,6 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
||||||
|
if (cmd->enable_devices_file && !pp->is_remove)
|
||||||
|
cmd->filter_deviceid_skip = 1;
|
||||||
|
|
||||||
|
- /* pvcreate -f overwrites partitions */
|
||||||
|
- if (pp->force && !pp->is_remove)
|
||||||
|
- cmd->filter_partitioned_skip = 1;
|
||||||
|
-
|
||||||
|
log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs));
|
||||||
|
label_scan_devs(cmd, cmd->filter, &scan_devs);
|
||||||
|
|
||||||
|
@@ -5261,7 +5257,6 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmd->filter_deviceid_skip = 0;
|
||||||
|
- cmd->filter_partitioned_skip = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can the command continue if some specified devices were not found?
|
||||||
|
@@ -5474,9 +5469,6 @@ do_command:
|
||||||
|
if (cmd->enable_devices_file && !pp->is_remove)
|
||||||
|
cmd->filter_deviceid_skip = 1;
|
||||||
|
|
||||||
|
- if (pp->force && !pp->is_remove)
|
||||||
|
- cmd->filter_partitioned_skip = 1;
|
||||||
|
-
|
||||||
|
log_debug("Rescanning and filtering device args with exclusive open");
|
||||||
|
if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) {
|
||||||
|
log_debug("Failed to rescan devs excl");
|
||||||
|
@@ -5490,9 +5482,7 @@ do_command:
|
||||||
|
dm_list_add(&pp->arg_fail, &pd->list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
cmd->filter_deviceid_skip = 0;
|
||||||
|
- cmd->filter_partitioned_skip = 0;
|
||||||
|
|
||||||
|
if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) {
|
||||||
|
log_debug("No devices to process.");
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,462 @@
|
|||||||
|
From 5403a6f05987b21addb50c9b056e36567d631df7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 17 Nov 2021 17:10:45 -0600
|
||||||
|
Subject: [PATCH 28/54] devices: exclude multipath components based on matching
|
||||||
|
wwid
|
||||||
|
|
||||||
|
If multipath component devices get through the filter and
|
||||||
|
cause lvm to see duplicate PVs, then check the wwid of the
|
||||||
|
devs and drop the component devices as if they had been
|
||||||
|
filtered. If a dm mpath device was found among the duplicates
|
||||||
|
then use that as the PV, otherwise do not use any of the
|
||||||
|
components as the PV.
|
||||||
|
|
||||||
|
"duplicate PVs" associated with multipath configs will no
|
||||||
|
longer stop commands from working.
|
||||||
|
---
|
||||||
|
lib/cache/lvmcache.c | 186 +++++++++++++++++++++++++-
|
||||||
|
lib/device/dev-mpath.c | 71 ++++++++++
|
||||||
|
lib/device/dev-type.h | 2 +
|
||||||
|
lib/device/device_id.c | 4 +-
|
||||||
|
lib/device/device_id.h | 2 +
|
||||||
|
test/shell/duplicate-pvs-multipath.sh | 67 ++++++++++
|
||||||
|
6 files changed, 323 insertions(+), 9 deletions(-)
|
||||||
|
create mode 100644 test/shell/duplicate-pvs-multipath.sh
|
||||||
|
|
||||||
|
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
||||||
|
index bee63ebb4..a0811d4ea 100644
|
||||||
|
--- a/lib/cache/lvmcache.c
|
||||||
|
+++ b/lib/cache/lvmcache.c
|
||||||
|
@@ -625,6 +625,102 @@ static void _warn_unused_duplicates(struct cmd_context *cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_info *info, const char *pvid,
|
||||||
|
+ struct dm_list *altdevs, struct device **dev_mpath)
|
||||||
|
+{
|
||||||
|
+ struct device_list *devl;
|
||||||
|
+ struct device *dev_mp = NULL;
|
||||||
|
+ struct device *dev1 = NULL;
|
||||||
|
+ struct device *dev;
|
||||||
|
+ const char *wwid1 = NULL;
|
||||||
|
+ const char *wwid;
|
||||||
|
+ int diff_wwid = 0;
|
||||||
|
+ int same_wwid = 0;
|
||||||
|
+ int dev_is_mp;
|
||||||
|
+
|
||||||
|
+ *dev_mpath = NULL;
|
||||||
|
+
|
||||||
|
+ /* This function only makes sense with more than one dev. */
|
||||||
|
+ if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) {
|
||||||
|
+ log_debug("Skip multipath component checks with single device for PVID %s", pvid);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_debug("Checking for multipath components for duplicate PVID %s", pvid);
|
||||||
|
+
|
||||||
|
+ if (info) {
|
||||||
|
+ dev = info->dev;
|
||||||
|
+ dev_is_mp = (cmd->dev_types->device_mapper_major == MAJOR(dev->dev)) && dev_has_mpath_uuid(cmd, dev, NULL);
|
||||||
|
+
|
||||||
|
+ if (dev_is_mp) {
|
||||||
|
+ if ((wwid1 = dev_mpath_component_wwid(cmd, dev))) {
|
||||||
|
+ dev_mp = dev;
|
||||||
|
+ dev1 = dev;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ if ((wwid1 = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID)))
|
||||||
|
+ dev1 = dev;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items(devl, altdevs) {
|
||||||
|
+ dev = devl->dev;
|
||||||
|
+ dev_is_mp = (cmd->dev_types->device_mapper_major == MAJOR(dev->dev)) && dev_has_mpath_uuid(cmd, dev, NULL);
|
||||||
|
+
|
||||||
|
+ if (dev_is_mp)
|
||||||
|
+ wwid = dev_mpath_component_wwid(cmd, dev);
|
||||||
|
+ else
|
||||||
|
+ wwid = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID);
|
||||||
|
+
|
||||||
|
+ if (!wwid && wwid1) {
|
||||||
|
+ log_print("Different wwids for duplicate PVs %s %s %s none",
|
||||||
|
+ dev_name(dev1), wwid1, dev_name(dev));
|
||||||
|
+ diff_wwid++;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!wwid)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!wwid1) {
|
||||||
|
+ wwid1 = wwid;
|
||||||
|
+ dev1 = dev;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Different wwids indicates these are not multipath components. */
|
||||||
|
+ if (strcmp(wwid1, wwid)) {
|
||||||
|
+ log_print("Different wwids for duplicate PVs %s %s %s %s",
|
||||||
|
+ dev_name(dev1), wwid1, dev_name(dev), wwid);
|
||||||
|
+ diff_wwid++;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Different mpath devs with the same wwid shouldn't happen. */
|
||||||
|
+ if (dev_is_mp && dev_mp) {
|
||||||
|
+ log_print("Found multiple multipath devices for PVID %s WWID %s: %s %s",
|
||||||
|
+ pvid, wwid1, dev_name(dev_mp), dev_name(dev));
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_debug("Same wwids for duplicate PVs %s %s", dev_name(dev1), dev_name(dev));
|
||||||
|
+ same_wwid++;
|
||||||
|
+
|
||||||
|
+ /* Save the mpath device so it can be used as the PV. */
|
||||||
|
+ if (dev_is_mp)
|
||||||
|
+ dev_mp = dev;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (diff_wwid || !same_wwid)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (dev_mp)
|
||||||
|
+ log_debug("Found multipath device %s for PVID %s WWID %s.", dev_name(dev_mp), pvid, wwid1);
|
||||||
|
+
|
||||||
|
+ *dev_mpath = dev_mp;
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* If we've found devices with the same PVID, decide which one
|
||||||
|
* to use.
|
||||||
|
@@ -680,6 +776,8 @@ static void _choose_duplicates(struct cmd_context *cmd,
|
||||||
|
struct device_list *devl, *devl_safe, *devl_add, *devl_del;
|
||||||
|
struct lvmcache_info *info;
|
||||||
|
struct device *dev1, *dev2;
|
||||||
|
+ struct device *dev_mpath;
|
||||||
|
+ struct device *dev_drop;
|
||||||
|
const char *device_id = NULL, *device_id_type = NULL;
|
||||||
|
const char *idname1 = NULL, *idname2 = NULL;
|
||||||
|
uint32_t dev1_major, dev1_minor, dev2_major, dev2_minor;
|
||||||
|
@@ -702,6 +800,7 @@ static void _choose_duplicates(struct cmd_context *cmd,
|
||||||
|
next:
|
||||||
|
dm_list_init(&altdevs);
|
||||||
|
pvid = NULL;
|
||||||
|
+ dev_mpath = NULL;
|
||||||
|
|
||||||
|
dm_list_iterate_items_safe(devl, devl_safe, &_initial_duplicates) {
|
||||||
|
if (!pvid) {
|
||||||
|
@@ -720,23 +819,97 @@ next:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ info = lvmcache_info_from_pvid(pvid, NULL, 0);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
- * Get rid of any md components before comparing alternatives.
|
||||||
|
- * (Since an md component can never be used, it's not an
|
||||||
|
- * option to use like other kinds of alternatives.)
|
||||||
|
+ * Usually and ideally, components of md and multipath devs should have
|
||||||
|
+ * been excluded by filters, and not scanned for a PV. In some unusual
|
||||||
|
+ * cases the components can get through the filters, and a PV can be
|
||||||
|
+ * found on them. Detecting the same PVID on both the component and
|
||||||
|
+ * the md/mpath device gives us a last chance to drop the component.
|
||||||
|
+ * An md/mpath component device is completely ignored, as if it had
|
||||||
|
+ * been filtered, and not kept in the list unused duplicates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- info = lvmcache_info_from_pvid(pvid, NULL, 0);
|
||||||
|
+ /*
|
||||||
|
+ * Get rid of multipath components based on matching wwids.
|
||||||
|
+ */
|
||||||
|
+ if (_all_multipath_components(cmd, info, pvid, &altdevs, &dev_mpath)) {
|
||||||
|
+ if (info && dev_mpath && (info->dev != dev_mpath)) {
|
||||||
|
+ /*
|
||||||
|
+ * info should be dropped from lvmcache and info->dev
|
||||||
|
+ * should be treated as if it had been excluded by a filter.
|
||||||
|
+ * dev_mpath should be added to lvmcache by the caller.
|
||||||
|
+ */
|
||||||
|
+ dev_drop = info->dev;
|
||||||
|
+
|
||||||
|
+ /* Have caller add dev_mpath to lvmcache. */
|
||||||
|
+ log_debug("Using multipath device %s for PVID %s.", dev_name(dev_mpath), pvid);
|
||||||
|
+ if ((devl_add = zalloc(sizeof(*devl_add)))) {
|
||||||
|
+ devl_add->dev = dev_mpath;
|
||||||
|
+ dm_list_add(add_cache_devs, &devl_add->list);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remove dev_mpath from altdevs. */
|
||||||
|
+ if ((devl = _get_devl_in_device_list(dev_mpath, &altdevs)))
|
||||||
|
+ dm_list_del(&devl->list);
|
||||||
|
+
|
||||||
|
+ /* Remove info from lvmcache that came from the component dev. */
|
||||||
|
+ log_debug("Ignoring multipath component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
|
||||||
|
+ lvmcache_del(info);
|
||||||
|
+ info = NULL;
|
||||||
|
+
|
||||||
|
+ /* Make the component dev look like it was filtered. */
|
||||||
|
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
|
||||||
|
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (info && !dev_mpath) {
|
||||||
|
+ /*
|
||||||
|
+ * Only mpath component devs were found and no actual
|
||||||
|
+ * multipath dev, so drop the component from lvmcache.
|
||||||
|
+ */
|
||||||
|
+ dev_drop = info->dev;
|
||||||
|
+
|
||||||
|
+ log_debug("Ignoring multipath component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
|
||||||
|
+ lvmcache_del(info);
|
||||||
|
+ info = NULL;
|
||||||
|
+
|
||||||
|
+ /* Make the component dev look like it was filtered. */
|
||||||
|
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
|
||||||
|
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
|
||||||
|
+ /*
|
||||||
|
+ * The altdevs are all mpath components that should look
|
||||||
|
+ * like they were filtered, they are not in lvmcache.
|
||||||
|
+ */
|
||||||
|
+ dev_drop = devl->dev;
|
||||||
|
+
|
||||||
|
+ log_debug("Ignoring multipath component %s with PVID %s (dropping duplicate)", dev_name(dev_drop), pvid);
|
||||||
|
+ dm_list_del(&devl->list);
|
||||||
|
+
|
||||||
|
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
|
||||||
|
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
+ }
|
||||||
|
+ goto next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Get rid of any md components.
|
||||||
|
+ * FIXME: use a function like _all_multipath_components to pick the actual md device.
|
||||||
|
+ */
|
||||||
|
if (info && dev_is_md_component(cmd, info->dev, NULL, 1)) {
|
||||||
|
/* does not go in del_cache_devs which become unused_duplicates */
|
||||||
|
- log_debug_cache("PV %s drop MD component from scan selection %s", pvid, dev_name(info->dev));
|
||||||
|
+ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(info->dev), pvid);
|
||||||
|
lvmcache_del(info);
|
||||||
|
info = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
|
||||||
|
if (dev_is_md_component(cmd, devl->dev, NULL, 1)) {
|
||||||
|
- log_debug_cache("PV %s drop MD component from scan duplicates %s", pvid, dev_name(devl->dev));
|
||||||
|
+ log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(devl->dev), pvid);
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -744,7 +917,6 @@ next:
|
||||||
|
if (dm_list_empty(&altdevs))
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Find the device for the pvid that's currently in lvmcache.
|
||||||
|
*/
|
||||||
|
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
|
||||||
|
index ba7bf9740..cbbad9dc9 100644
|
||||||
|
--- a/lib/device/dev-mpath.c
|
||||||
|
+++ b/lib/device/dev-mpath.c
|
||||||
|
@@ -482,3 +482,74 @@ found:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev)
|
||||||
|
+{
|
||||||
|
+ char slaves_path[PATH_MAX];
|
||||||
|
+ char wwid_path[PATH_MAX];
|
||||||
|
+ char sysbuf[PATH_MAX] = { 0 };
|
||||||
|
+ char *slave_name;
|
||||||
|
+ const char *wwid = NULL;
|
||||||
|
+ struct stat info;
|
||||||
|
+ DIR *dr;
|
||||||
|
+ struct dirent *de;
|
||||||
|
+
|
||||||
|
+ /* /sys/dev/block/253:7/slaves/sda/device/wwid */
|
||||||
|
+
|
||||||
|
+ if (dm_snprintf(slaves_path, sizeof(slaves_path), "%s/dev/block/%d:%d/slaves",
|
||||||
|
+ dm_sysfs_dir(), (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) {
|
||||||
|
+ log_warn("Sysfs path to check mpath components is too long.");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (stat(slaves_path, &info))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (!S_ISDIR(info.st_mode)) {
|
||||||
|
+ log_warn("Path %s is not a directory.", slaves_path);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get wwid from first component */
|
||||||
|
+
|
||||||
|
+ if (!(dr = opendir(slaves_path))) {
|
||||||
|
+ log_debug("Device %s has no slaves dir", dev_name(dev));
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while ((de = readdir(dr))) {
|
||||||
|
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ /* slave_name "sda" */
|
||||||
|
+ slave_name = de->d_name;
|
||||||
|
+
|
||||||
|
+ /* read /sys/block/sda/device/wwid */
|
||||||
|
+
|
||||||
|
+ if (dm_snprintf(wwid_path, sizeof(wwid_path), "%s/block/%s/device/wwid",
|
||||||
|
+ dm_sysfs_dir(), slave_name) < 0) {
|
||||||
|
+ log_warn("Failed to create sysfs wwid path for %s", slave_name);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ get_sysfs_value(wwid_path, sysbuf, sizeof(sysbuf), 0);
|
||||||
|
+ if (!sysbuf[0])
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (strstr(sysbuf, "scsi_debug")) {
|
||||||
|
+ int i;
|
||||||
|
+ for (i = 0; i < strlen(sysbuf); i++) {
|
||||||
|
+ if (sysbuf[i] == ' ')
|
||||||
|
+ sysbuf[i] = '_';
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((wwid = dm_pool_strdup(cmd->mem, sysbuf)))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (closedir(dr))
|
||||||
|
+ stack;
|
||||||
|
+
|
||||||
|
+ return wwid;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h
|
||||||
|
index f3521c6e0..36fb8f258 100644
|
||||||
|
--- a/lib/device/dev-type.h
|
||||||
|
+++ b/lib/device/dev-type.h
|
||||||
|
@@ -63,6 +63,8 @@ int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *signature
|
||||||
|
int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full);
|
||||||
|
int dasd_is_cdl_formatted(struct device *dev);
|
||||||
|
|
||||||
|
+const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev);
|
||||||
|
+
|
||||||
|
int dev_is_lvm1(struct device *dev, char *buf, int buflen);
|
||||||
|
int dev_is_pool(struct device *dev, char *buf, int buflen);
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index a33dcebe0..625576ec6 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -243,7 +243,7 @@ static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the dm uuid uses the wwid of the underlying dev */
|
||||||
|
-static int _dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out)
|
||||||
|
+int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out)
|
||||||
|
{
|
||||||
|
char sysbuf[PATH_MAX] = { 0 };
|
||||||
|
const char *idname;
|
||||||
|
@@ -988,7 +988,7 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAJOR(dev->dev) == cmd->dev_types->device_mapper_major) {
|
||||||
|
- if (_dev_has_mpath_uuid(cmd, dev, &idname)) {
|
||||||
|
+ if (dev_has_mpath_uuid(cmd, dev, &idname)) {
|
||||||
|
idtype = DEV_ID_TYPE_MPATH_UUID;
|
||||||
|
goto id_done;
|
||||||
|
}
|
||||||
|
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
|
||||||
|
index 939b3a0f4..4cf1374c8 100644
|
||||||
|
--- a/lib/device/device_id.h
|
||||||
|
+++ b/lib/device/device_id.h
|
||||||
|
@@ -55,4 +55,6 @@ void unlink_searched_devnames(struct cmd_context *cmd);
|
||||||
|
|
||||||
|
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
|
||||||
|
|
||||||
|
+int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..a145e4afb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+
|
||||||
|
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+# of the GNU General Public License v.2.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
+
|
||||||
|
+test_description='udev rule and systemd unit run vgchange'
|
||||||
|
+
|
||||||
|
+SKIP_WITH_LVMPOLLD=1
|
||||||
|
+SKIP_WITH_LVMLOCKD=1
|
||||||
|
+
|
||||||
|
+. lib/inittest
|
||||||
|
+
|
||||||
|
+# FIXME: skip until mpath/scsi_debug cleanup works after a failure
|
||||||
|
+skip
|
||||||
|
+
|
||||||
|
+modprobe --dry-run scsi_debug || skip
|
||||||
|
+multipath -l || skip
|
||||||
|
+multipath -l | grep scsi_debug && skip
|
||||||
|
+
|
||||||
|
+# Turn off multipath_component_detection so that the duplicate
|
||||||
|
+# resolution of mpath components is used.
|
||||||
|
+aux lvmconf 'devices/multipath_component_detection = 0'
|
||||||
|
+# Prevent wwids from being used for filtering.
|
||||||
|
+aux lvmconf 'devices/multipath_wwids_file = "/dev/null"'
|
||||||
|
+# Need to use /dev/mapper/mpath
|
||||||
|
+aux lvmconf 'devices/dir = "/dev"'
|
||||||
|
+aux lvmconf 'devices/scan = "/dev"'
|
||||||
|
+# Could set filter to $MP and the component /dev/sd devs
|
||||||
|
+aux lvmconf "devices/filter = [ \"a|.*|\" ]"
|
||||||
|
+aux lvmconf "devices/global_filter = [ \"a|.*|\" ]"
|
||||||
|
+
|
||||||
|
+modprobe scsi_debug dev_size_mb=100 num_tgts=1 vpd_use_hostno=0 add_host=4 delay=20 max_luns=2 no_lun_0=1
|
||||||
|
+sleep 2
|
||||||
|
+
|
||||||
|
+multipath -r
|
||||||
|
+sleep 2
|
||||||
|
+
|
||||||
|
+MPB=$(multipath -l | grep scsi_debug | cut -f1 -d ' ')
|
||||||
|
+echo $MPB
|
||||||
|
+MP=/dev/mapper/$MPB
|
||||||
|
+echo $MP
|
||||||
|
+
|
||||||
|
+pvcreate $MP
|
||||||
|
+vgcreate $vg1 $MP
|
||||||
|
+lvcreate -l1 $vg1
|
||||||
|
+vgchange -an $vg1
|
||||||
|
+
|
||||||
|
+pvs |tee out
|
||||||
|
+grep $MP out
|
||||||
|
+for i in $(grep -H scsi_debug /sys/block/sd*/device/model | cut -f4 -d /); do
|
||||||
|
+ not grep /dev/$i out;
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+vgchange -an $vg1
|
||||||
|
+vgremove -y $vg1
|
||||||
|
+
|
||||||
|
+sleep 2
|
||||||
|
+multipath -f $MP
|
||||||
|
+sleep 1
|
||||||
|
+rmmod scsi_debug
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,268 @@
|
|||||||
|
From 7b79acc6161b2cff81a03848c160dd6993a4477b Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 22 Nov 2021 15:10:43 -0600
|
||||||
|
Subject: [PATCH 29/54] devices: exclude md components when duplicate pvs are
|
||||||
|
seen
|
||||||
|
|
||||||
|
Improve handling of md components that get through the
|
||||||
|
filter, like the previous improvement for multipath.
|
||||||
|
If md components get through the filter and trigger
|
||||||
|
duplicate PV code, then eliminate any devs entirely
|
||||||
|
that are not an md device.
|
||||||
|
---
|
||||||
|
lib/cache/lvmcache.c | 168 ++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 149 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
||||||
|
index a0811d4ea..0e62cd267 100644
|
||||||
|
--- a/lib/cache/lvmcache.c
|
||||||
|
+++ b/lib/cache/lvmcache.c
|
||||||
|
@@ -673,7 +673,7 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
|
||||||
|
wwid = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID);
|
||||||
|
|
||||||
|
if (!wwid && wwid1) {
|
||||||
|
- log_print("Different wwids for duplicate PVs %s %s %s none",
|
||||||
|
+ log_debug("Different wwids for duplicate PVs %s %s %s none",
|
||||||
|
dev_name(dev1), wwid1, dev_name(dev));
|
||||||
|
diff_wwid++;
|
||||||
|
continue;
|
||||||
|
@@ -690,7 +690,7 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
|
||||||
|
|
||||||
|
/* Different wwids indicates these are not multipath components. */
|
||||||
|
if (strcmp(wwid1, wwid)) {
|
||||||
|
- log_print("Different wwids for duplicate PVs %s %s %s %s",
|
||||||
|
+ log_debug("Different wwids for duplicate PVs %s %s %s %s",
|
||||||
|
dev_name(dev1), wwid1, dev_name(dev), wwid);
|
||||||
|
diff_wwid++;
|
||||||
|
continue;
|
||||||
|
@@ -721,6 +721,52 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _all_md_components(struct cmd_context *cmd, struct lvmcache_info *info, const char *pvid,
|
||||||
|
+ struct dm_list *altdevs, struct device **dev_md_out)
|
||||||
|
+{
|
||||||
|
+ struct device_list *devl;
|
||||||
|
+ struct device *dev_md = NULL;
|
||||||
|
+ struct device *dev;
|
||||||
|
+ int real_dup = 0;
|
||||||
|
+
|
||||||
|
+ *dev_md_out = NULL;
|
||||||
|
+
|
||||||
|
+ /* There will often be no info struct because of the extra_md_checks function. */
|
||||||
|
+
|
||||||
|
+ if (info && (cmd->dev_types->md_major == MAJOR(info->dev->dev)))
|
||||||
|
+ dev_md = info->dev;
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items(devl, altdevs) {
|
||||||
|
+ dev = devl->dev;
|
||||||
|
+
|
||||||
|
+ if (cmd->dev_types->md_major == MAJOR(dev->dev)) {
|
||||||
|
+ if (dev_md) {
|
||||||
|
+ /* md devs themselves are dups */
|
||||||
|
+ log_debug("Found multiple md devices for PVID %s: %s %s",
|
||||||
|
+ pvid, dev_name(dev_md), dev_name(dev));
|
||||||
|
+ real_dup = 1;
|
||||||
|
+ break;
|
||||||
|
+ } else
|
||||||
|
+ dev_md = dev;
|
||||||
|
+ } else {
|
||||||
|
+ if (!dev_is_md_component(cmd, dev, NULL, 1)) {
|
||||||
|
+ /* md dev copied to another device */
|
||||||
|
+ real_dup = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (real_dup)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (dev_md)
|
||||||
|
+ log_debug("Found md device %s for PVID %s.", dev_name(dev_md), pvid);
|
||||||
|
+
|
||||||
|
+ *dev_md_out = dev_md;
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* If we've found devices with the same PVID, decide which one
|
||||||
|
* to use.
|
||||||
|
@@ -776,7 +822,7 @@ static void _choose_duplicates(struct cmd_context *cmd,
|
||||||
|
struct device_list *devl, *devl_safe, *devl_add, *devl_del;
|
||||||
|
struct lvmcache_info *info;
|
||||||
|
struct device *dev1, *dev2;
|
||||||
|
- struct device *dev_mpath;
|
||||||
|
+ struct device *dev_mpath, *dev_md;
|
||||||
|
struct device *dev_drop;
|
||||||
|
const char *device_id = NULL, *device_id_type = NULL;
|
||||||
|
const char *idname1 = NULL, *idname2 = NULL;
|
||||||
|
@@ -801,6 +847,7 @@ next:
|
||||||
|
dm_list_init(&altdevs);
|
||||||
|
pvid = NULL;
|
||||||
|
dev_mpath = NULL;
|
||||||
|
+ dev_md = NULL;
|
||||||
|
|
||||||
|
dm_list_iterate_items_safe(devl, devl_safe, &_initial_duplicates) {
|
||||||
|
if (!pvid) {
|
||||||
|
@@ -829,6 +876,11 @@ next:
|
||||||
|
* the md/mpath device gives us a last chance to drop the component.
|
||||||
|
* An md/mpath component device is completely ignored, as if it had
|
||||||
|
* been filtered, and not kept in the list unused duplicates.
|
||||||
|
+ *
|
||||||
|
+ * One issue related to eliminating mpath/md duplicate PVs here is
|
||||||
|
+ * that it occurs after label_scan, and hints are created based
|
||||||
|
+ * on what label_scan finds, so hints are disabled due to duplicate
|
||||||
|
+ * PVs that are later resolved here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -898,24 +950,89 @@ next:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get rid of any md components.
|
||||||
|
- * FIXME: use a function like _all_multipath_components to pick the actual md device.
|
||||||
|
*/
|
||||||
|
- if (info && dev_is_md_component(cmd, info->dev, NULL, 1)) {
|
||||||
|
- /* does not go in del_cache_devs which become unused_duplicates */
|
||||||
|
- log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(info->dev), pvid);
|
||||||
|
- lvmcache_del(info);
|
||||||
|
- info = NULL;
|
||||||
|
- }
|
||||||
|
+ if (_all_md_components(cmd, info, pvid, &altdevs, &dev_md)) {
|
||||||
|
+ if (info && dev_md && (info->dev != dev_md)) {
|
||||||
|
+ /*
|
||||||
|
+ * info should be dropped from lvmcache and info->dev
|
||||||
|
+ * should be treated as if it had been excluded by a filter.
|
||||||
|
+ * dev_md should be added to lvmcache by the caller.
|
||||||
|
+ * Often this info struct has been removed by
|
||||||
|
+ * lvmcache_extra_md_component_checks.
|
||||||
|
+ */
|
||||||
|
+ dev_drop = info->dev;
|
||||||
|
|
||||||
|
- dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
|
||||||
|
- if (dev_is_md_component(cmd, devl->dev, NULL, 1)) {
|
||||||
|
- log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(devl->dev), pvid);
|
||||||
|
- dm_list_del(&devl->list);
|
||||||
|
+ /* Have caller add dev_md to lvmcache. */
|
||||||
|
+ log_debug("Using md device %s for PVID %s.", dev_name(dev_md), pvid);
|
||||||
|
+ if ((devl_add = zalloc(sizeof(*devl_add)))) {
|
||||||
|
+ devl_add->dev = dev_md;
|
||||||
|
+ dm_list_add(add_cache_devs, &devl_add->list);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remove dev_md from altdevs. */
|
||||||
|
+ if ((devl = _get_devl_in_device_list(dev_md, &altdevs)))
|
||||||
|
+ dm_list_del(&devl->list);
|
||||||
|
+
|
||||||
|
+ /* Remove info from lvmcache that came from the component dev. */
|
||||||
|
+ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
|
||||||
|
+ lvmcache_del(info);
|
||||||
|
+ info = NULL;
|
||||||
|
+
|
||||||
|
+ /* Make the component dev look like it was filtered. */
|
||||||
|
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
|
||||||
|
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (dm_list_empty(&altdevs))
|
||||||
|
+ if (!info && dev_md) {
|
||||||
|
+ /*
|
||||||
|
+ * The info struct was from a component and was dropped
|
||||||
|
+ * and the actual md dev was found on initial_duplicates
|
||||||
|
+ * and the caller should add it to lvmcache.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ /* Have caller add dev_md to lvmcache. */
|
||||||
|
+ log_debug("Using md device %s for PVID %s.", dev_name(dev_md), pvid);
|
||||||
|
+ if ((devl_add = zalloc(sizeof(*devl_add)))) {
|
||||||
|
+ devl_add->dev = dev_md;
|
||||||
|
+ dm_list_add(add_cache_devs, &devl_add->list);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remove dev_md from altdevs. */
|
||||||
|
+ if ((devl = _get_devl_in_device_list(dev_md, &altdevs)))
|
||||||
|
+ dm_list_del(&devl->list);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (info && !dev_md) {
|
||||||
|
+ /*
|
||||||
|
+ * Only md component devs were found and no actual
|
||||||
|
+ * md dev, so drop the component from lvmcache.
|
||||||
|
+ */
|
||||||
|
+ dev_drop = info->dev;
|
||||||
|
+
|
||||||
|
+ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
|
||||||
|
+ lvmcache_del(info);
|
||||||
|
+ info = NULL;
|
||||||
|
+
|
||||||
|
+ /* Make the component dev look like it was filtered. */
|
||||||
|
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
|
||||||
|
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
|
||||||
|
+ /*
|
||||||
|
+ * The altdevs are all md components that should look
|
||||||
|
+ * like they were filtered, they are not in lvmcache.
|
||||||
|
+ */
|
||||||
|
+ dev_drop = devl->dev;
|
||||||
|
+
|
||||||
|
+ log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(dev_drop), pvid);
|
||||||
|
+ dm_list_del(&devl->list);
|
||||||
|
+
|
||||||
|
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
|
||||||
|
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
+ }
|
||||||
|
goto next;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the device for the pvid that's currently in lvmcache.
|
||||||
|
@@ -1321,6 +1438,18 @@ int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, con
|
||||||
|
* times it can be a clue that label_scan mistakenly read the pv from an md
|
||||||
|
* component device instead of from the md device itself. So for unmatching
|
||||||
|
* sizes, we do a full md component check on the device.
|
||||||
|
+ *
|
||||||
|
+ * It might be nice to do this checking in the filter (when passes_filter is
|
||||||
|
+ * called after the initial read), but that doesn't work because passes_filter
|
||||||
|
+ * is called before _text_read so metadata/pvsummary info is not yet available
|
||||||
|
+ * which this function uses.
|
||||||
|
+ *
|
||||||
|
+ * The unique value of this function is that it can eliminate md components
|
||||||
|
+ * without there being duplicate PVs. But, there will often be duplicate PVs,
|
||||||
|
+ * handled by _all_md_components(), where other devs with the same pvid will be
|
||||||
|
+ * in _initial_duplicates. One could be the md device itself which will be
|
||||||
|
+ * added to lvmcache by choose_duplicates, and other duplicates that are
|
||||||
|
+ * components will be dropped.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
|
||||||
|
@@ -1382,7 +1511,8 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
|
||||||
|
*/
|
||||||
|
if (pvsize && devsize && (pvsize != devsize))
|
||||||
|
do_check_size = 1;
|
||||||
|
- if (device_hint && !strncmp(device_hint, "/dev/md", 7))
|
||||||
|
+ if (device_hint && !strncmp(device_hint, "/dev/md", 7) &&
|
||||||
|
+ (MAJOR(info->dev->dev) != cmd->dev_types->md_major))
|
||||||
|
do_check_name = 1;
|
||||||
|
|
||||||
|
if (!do_check_size && !do_check_name)
|
||||||
|
@@ -1412,11 +1542,11 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
|
||||||
|
device_hint ?: "none", dev_name(dev));
|
||||||
|
|
||||||
|
if (dev_is_md_component(cmd, dev, NULL, 1)) {
|
||||||
|
- log_debug("dropping PV from md component %s", dev_name(dev));
|
||||||
|
+ log_debug("Ignoring PV from md component %s with PVID %s (metadata %s %llu)",
|
||||||
|
+ dev_name(dev), dev->pvid, device_hint ?: "none", (unsigned long long)pvsize);
|
||||||
|
dev->flags &= ~DEV_SCAN_FOUND_LABEL;
|
||||||
|
/* lvmcache_del will also delete vginfo if info was last one */
|
||||||
|
lvmcache_del(info);
|
||||||
|
- lvmcache_del_dev_from_duplicates(dev);
|
||||||
|
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
246
SOURCES/0030-lvmdevices-fix-checks-when-adding-entries.patch
Normal file
246
SOURCES/0030-lvmdevices-fix-checks-when-adding-entries.patch
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
From 4e72068216b006edc69c8bafba5198051e3ed1dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 25 Jan 2022 11:35:36 -0600
|
||||||
|
Subject: [PATCH 30/54] lvmdevices: fix checks when adding entries
|
||||||
|
|
||||||
|
Removes some incorrect and unnecessary checks for other entries
|
||||||
|
when adding a new devices. The removed checks and corrections were
|
||||||
|
mostly redundant with what is already done by device id matching.
|
||||||
|
Other checking is reworked so the warnings are a bit different.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 153 +++++++++++++----------------------------
|
||||||
|
1 file changed, 48 insertions(+), 105 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 625576ec6..ccc5f43a1 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -935,6 +935,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
|
||||||
|
struct dev_use *du, *update_du = NULL, *du_dev, *du_pvid, *du_devname, *du_devid;
|
||||||
|
struct dev_id *id;
|
||||||
|
int found_id = 0;
|
||||||
|
+ int part = 0;
|
||||||
|
+
|
||||||
|
+ if (!dev_get_partition_number(dev, &part))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When enable_devices_file=0 and pending_devices_file=1 we let
|
||||||
|
@@ -953,10 +957,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
|
||||||
|
*/
|
||||||
|
memcpy(&pvid, pvid_arg, ID_LEN);
|
||||||
|
|
||||||
|
- du_dev = get_du_for_dev(cmd, dev);
|
||||||
|
- du_pvid = get_du_for_pvid(cmd, pvid);
|
||||||
|
- du_devname = _get_du_for_devname(cmd, dev_name(dev));
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Choose the device_id type for the device being added.
|
||||||
|
*
|
||||||
|
@@ -1072,6 +1072,9 @@ id_done:
|
||||||
|
idtype = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * "dev" is the device we are adding.
|
||||||
|
+ * "id" is the device_id it's using, set in dev->id.
|
||||||
|
+ *
|
||||||
|
* Update the cmd->use_devices list for the new device. The
|
||||||
|
* use_devices list will be used to update the devices file.
|
||||||
|
*
|
||||||
|
@@ -1083,23 +1086,57 @@ id_done:
|
||||||
|
* those other entries to fix any incorrect info.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ /* Is there already an entry matched to this device? */
|
||||||
|
+ du_dev = get_du_for_dev(cmd, dev);
|
||||||
|
+
|
||||||
|
+ /* Is there already an entry matched to this device's pvid? */
|
||||||
|
+ du_pvid = get_du_for_pvid(cmd, pvid);
|
||||||
|
+
|
||||||
|
+ /* Is there already an entry using this device's name? */
|
||||||
|
+ du_devname = _get_du_for_devname(cmd, dev_name(dev));
|
||||||
|
+
|
||||||
|
+ /* Is there already an entry using the device_id for this device? */
|
||||||
|
du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname);
|
||||||
|
|
||||||
|
if (du_dev)
|
||||||
|
- log_debug("device_id_add %s pvid %s matches du_dev %p dev %s",
|
||||||
|
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s",
|
||||||
|
dev_name(dev), pvid, du_dev, dev_name(du_dev->dev));
|
||||||
|
if (du_pvid)
|
||||||
|
- log_debug("device_id_add %s pvid %s matches du_pvid %p dev %s pvid %s",
|
||||||
|
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same pvid %s",
|
||||||
|
dev_name(dev), pvid, du_pvid, du_pvid->dev ? dev_name(du_pvid->dev) : ".",
|
||||||
|
du_pvid->pvid);
|
||||||
|
if (du_devid)
|
||||||
|
- log_debug("device_id_add %s pvid %s matches du_devid %p dev %s pvid %s",
|
||||||
|
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same device_id %d %s",
|
||||||
|
dev_name(dev), pvid, du_devid, du_devid->dev ? dev_name(du_devid->dev) : ".",
|
||||||
|
- du_devid->pvid);
|
||||||
|
+ du_devid->idtype, du_devid->idname);
|
||||||
|
if (du_devname)
|
||||||
|
- log_debug("device_id_add %s pvid %s matches du_devname %p dev %s pvid %s",
|
||||||
|
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same devname %s",
|
||||||
|
dev_name(dev), pvid, du_devname, du_devname->dev ? dev_name(du_devname->dev) : ".",
|
||||||
|
- du_devname->pvid);
|
||||||
|
+ du_devname->devname);
|
||||||
|
+
|
||||||
|
+ if (du_pvid && (du_pvid->dev != dev))
|
||||||
|
+ log_warn("WARNING: adding device %s with PVID %s which is already used for %s.",
|
||||||
|
+ dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device");
|
||||||
|
+
|
||||||
|
+ if (du_devid && (du_devid->dev != dev)) {
|
||||||
|
+ if (!du_devid->dev) {
|
||||||
|
+ log_warn("WARNING: adding device %s with idname %s which is already used for missing device.",
|
||||||
|
+ dev_name(dev), id->idname);
|
||||||
|
+ } else {
|
||||||
|
+ int ret1, ret2;
|
||||||
|
+ dev_t devt1, devt2;
|
||||||
|
+ /* Check if both entries are partitions of the same device. */
|
||||||
|
+ ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1);
|
||||||
|
+ ret2 = dev_get_primary_dev(cmd->dev_types, du_devid->dev, &devt2);
|
||||||
|
+ if ((ret1 == 2) && (ret2 == 2) && (devt1 == devt2)) {
|
||||||
|
+ log_debug("Using separate entries for partitions of same device %s part %d %s part %d.",
|
||||||
|
+ dev_name(dev), part, dev_name(du_devid->dev), du_devid->part);
|
||||||
|
+ } else {
|
||||||
|
+ log_warn("WARNING: adding device %s with idname %s which is already used for %s.",
|
||||||
|
+ dev_name(dev), id->idname, dev_name(du_devid->dev));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If one of the existing entries (du_dev, du_pvid, du_devid, du_devname)
|
||||||
|
@@ -1112,29 +1149,6 @@ id_done:
|
||||||
|
dm_list_del(&update_du->list);
|
||||||
|
update_matching_kind = "device";
|
||||||
|
update_matching_name = dev_name(dev);
|
||||||
|
-
|
||||||
|
- if (du_devid && (du_devid != du_dev)) {
|
||||||
|
- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate device ID.",
|
||||||
|
- dev_name(dev), id->idname,
|
||||||
|
- (du_pvid && du_pvid->dev) ? dev_name(du_pvid->dev) : "none",
|
||||||
|
- du_pvid ? du_pvid->idname : "");
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (du_pvid && (du_pvid != du_dev)) {
|
||||||
|
- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate PVID %s",
|
||||||
|
- dev_name(dev), id->idname,
|
||||||
|
- du_pvid->dev ? dev_name(du_pvid->dev) : "none", du_pvid->idname,
|
||||||
|
- pvid);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (du_devname && (du_devname != du_dev)) {
|
||||||
|
- /* clear devname in another entry with our devname */
|
||||||
|
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s.",
|
||||||
|
- du_devname->pvid, du_devname->devname);
|
||||||
|
- free(du_devname->devname);
|
||||||
|
- du_devname->devname = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
} else if (du_pvid) {
|
||||||
|
/*
|
||||||
|
* If the device_id of the existing entry for PVID is the same
|
||||||
|
@@ -1154,11 +1168,6 @@ id_done:
|
||||||
|
update_matching_kind = "PVID";
|
||||||
|
update_matching_name = pvid;
|
||||||
|
} else {
|
||||||
|
- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate PVID %s",
|
||||||
|
- dev_name(dev), id->idname,
|
||||||
|
- du_pvid->dev ? dev_name(du_pvid->dev) : "none", du_pvid->idname,
|
||||||
|
- pvid);
|
||||||
|
-
|
||||||
|
if (!cmd->current_settings.yes &&
|
||||||
|
yes_no_prompt("Add device with duplicate PV to devices file?") == 'n') {
|
||||||
|
log_print("Device not added.");
|
||||||
|
@@ -1166,21 +1175,6 @@ id_done:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (du_devid && (du_devid != du_pvid)) {
|
||||||
|
- /* warn about another entry using the same device_id */
|
||||||
|
- log_warn("WARNING: duplicate device_id %s for PVIDs %s %s",
|
||||||
|
- du_devid->idname, du_devid->pvid, du_pvid->pvid);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (du_devname && (du_devname != du_pvid)) {
|
||||||
|
- /* clear devname in another entry with our devname */
|
||||||
|
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s.",
|
||||||
|
- du_devname->pvid, du_devname->devname);
|
||||||
|
- free(du_devname->devname);
|
||||||
|
- du_devname->devname = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
} else if (du_devid) {
|
||||||
|
/*
|
||||||
|
* Do we create a new du or update the existing du?
|
||||||
|
@@ -1195,64 +1189,13 @@ id_done:
|
||||||
|
* the same device_id (create a new du for dev.)
|
||||||
|
* If not, then update the existing du_devid.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
- if (du_devid->dev != dev)
|
||||||
|
- check_idname = device_id_system_read(cmd, du_devid->dev, id->idtype);
|
||||||
|
-
|
||||||
|
- if (check_idname && !strcmp(check_idname, id->idname)) {
|
||||||
|
- int ret1, ret2;
|
||||||
|
- dev_t devt1, devt2;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * two different devices have the same device_id,
|
||||||
|
- * create a new du for the device being added
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- /* dev_is_partitioned() the dev open to read it. */
|
||||||
|
- if (!label_scan_open(du_devid->dev))
|
||||||
|
- log_warn("Cannot open %s", dev_name(du_devid->dev));
|
||||||
|
-
|
||||||
|
- if (dev_is_partitioned(cmd, du_devid->dev)) {
|
||||||
|
- /* Check if existing entry is whole device and new entry is a partition of it. */
|
||||||
|
- ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1);
|
||||||
|
- if ((ret1 == 2) && (devt1 == du_devid->dev->dev))
|
||||||
|
- log_warn("Remove partitioned device %s from devices file.", dev_name(du_devid->dev));
|
||||||
|
- } else {
|
||||||
|
- /* Check if both entries are partitions of the same device. */
|
||||||
|
- ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1);
|
||||||
|
- ret2 = dev_get_primary_dev(cmd->dev_types, du_devid->dev, &devt2);
|
||||||
|
-
|
||||||
|
- if ((ret1 == 2) && (ret2 == 2) && (devt1 == devt2)) {
|
||||||
|
- log_warn("Partitions %s %s have same device_id %s",
|
||||||
|
- dev_name(dev), dev_name(du_devid->dev), id->idname);
|
||||||
|
- } else {
|
||||||
|
- log_warn("Duplicate device_id %s %s for %s and %s",
|
||||||
|
- idtype_to_str(id->idtype), check_idname,
|
||||||
|
- dev_name(dev), dev_name(du_devid->dev));
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- } else {
|
||||||
|
+ if (du_devid->dev == dev) {
|
||||||
|
/* update the existing entry with matching devid */
|
||||||
|
update_du = du_devid;
|
||||||
|
dm_list_del(&update_du->list);
|
||||||
|
update_matching_kind = "device_id";
|
||||||
|
update_matching_name = id->idname;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (du_devname && (du_devname != du_devid)) {
|
||||||
|
- /* clear devname in another entry with our devname */
|
||||||
|
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s",
|
||||||
|
- du_devname->pvid, du_devname->devname);
|
||||||
|
- free(du_devname->devname);
|
||||||
|
- du_devname->devname = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- } else if (du_devname) {
|
||||||
|
- /* clear devname in another entry with our devname */
|
||||||
|
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s",
|
||||||
|
- du_devname->pvid, du_devname->devname);
|
||||||
|
- free(du_devname->devname);
|
||||||
|
- du_devname->devname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free((void *)check_idname);
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,106 @@
|
|||||||
|
From df2b1555aff71452cde156badec70117065c9e2c Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 3 Feb 2022 16:56:03 -0600
|
||||||
|
Subject: [PATCH 31/54] lvmdevices: make deldev work for missing device
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 6 +++---
|
||||||
|
lib/device/device_id.h | 1 +
|
||||||
|
tools/lvmdevices.c | 33 ++++++++++++++++-----------------
|
||||||
|
3 files changed, 20 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index ccc5f43a1..aeaa1ffc6 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -894,7 +894,7 @@ struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static struct dev_use *_get_du_for_devname(struct cmd_context *cmd, const char *devname)
|
||||||
|
+struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname)
|
||||||
|
{
|
||||||
|
struct dev_use *du;
|
||||||
|
|
||||||
|
@@ -1093,7 +1093,7 @@ id_done:
|
||||||
|
du_pvid = get_du_for_pvid(cmd, pvid);
|
||||||
|
|
||||||
|
/* Is there already an entry using this device's name? */
|
||||||
|
- du_devname = _get_du_for_devname(cmd, dev_name(dev));
|
||||||
|
+ du_devname = get_du_for_devname(cmd, dev_name(dev));
|
||||||
|
|
||||||
|
/* Is there already an entry using the device_id for this device? */
|
||||||
|
du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname);
|
||||||
|
@@ -1514,7 +1514,7 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev)
|
||||||
|
struct dev_use *du;
|
||||||
|
|
||||||
|
/* First check the du entry with matching devname since it's likely correct. */
|
||||||
|
- if ((du = _get_du_for_devname(cmd, dev_name(dev)))) {
|
||||||
|
+ if ((du = get_du_for_devname(cmd, dev_name(dev)))) {
|
||||||
|
if (_match_du_to_dev(cmd, du, dev))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
|
||||||
|
index 4cf1374c8..2cd2fd7c6 100644
|
||||||
|
--- a/lib/device/device_id.h
|
||||||
|
+++ b/lib/device/device_id.h
|
||||||
|
@@ -40,6 +40,7 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
|
||||||
|
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
|
||||||
|
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
|
||||||
|
+struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname);
|
||||||
|
|
||||||
|
char *devices_file_version(void);
|
||||||
|
int devices_file_exists(struct cmd_context *cmd);
|
||||||
|
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||||
|
index c50c09f90..662b35f9a 100644
|
||||||
|
--- a/tools/lvmdevices.c
|
||||||
|
+++ b/tools/lvmdevices.c
|
||||||
|
@@ -383,28 +383,27 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
* No filter because we always want to allow removing a device
|
||||||
|
* by name from the devices file.
|
||||||
|
*/
|
||||||
|
- if (!(dev = dev_cache_get(cmd, devname, NULL))) {
|
||||||
|
- log_error("No device found for %s.", devname);
|
||||||
|
- goto bad;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * dev_cache_scan uses sysfs to check if an LV is using each dev
|
||||||
|
- * and sets this flag is so.
|
||||||
|
- */
|
||||||
|
- if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) {
|
||||||
|
- if (!arg_count(cmd, yes_ARG) &&
|
||||||
|
- yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') {
|
||||||
|
- log_error("Device not removed.");
|
||||||
|
- goto bad;
|
||||||
|
+ if ((dev = dev_cache_get(cmd, devname, NULL))) {
|
||||||
|
+ /*
|
||||||
|
+ * dev_cache_scan uses sysfs to check if an LV is using each dev
|
||||||
|
+ * and sets this flag is so.
|
||||||
|
+ */
|
||||||
|
+ if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) {
|
||||||
|
+ if (!arg_count(cmd, yes_ARG) &&
|
||||||
|
+ yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') {
|
||||||
|
+ log_error("Device not removed.");
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+ if ((du = get_du_for_dev(cmd, dev)))
|
||||||
|
+ goto dev_del;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!(du = get_du_for_dev(cmd, dev))) {
|
||||||
|
- log_error("Device not found in devices file.");
|
||||||
|
+ if (!(du = get_du_for_devname(cmd, devname))) {
|
||||||
|
+ log_error("No devices file entry for %s.", devname);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ dev_del:
|
||||||
|
dm_list_del(&du->list);
|
||||||
|
free_du(du);
|
||||||
|
device_ids_write(cmd);
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,144 @@
|
|||||||
|
From 08a5619a1d7a5a8dd6e0df6e4dedec47ce2533b7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 10 Feb 2022 14:00:25 -0600
|
||||||
|
Subject: [PATCH 32/54] devices file: do not clear PVID of unread devices
|
||||||
|
|
||||||
|
In a certain disconnected state, a block device is present on
|
||||||
|
the system, can be opened, reports a valid size, reports the
|
||||||
|
correct device id (wwid), and matches a devices file entry.
|
||||||
|
But, reading the device can still fail. In this case,
|
||||||
|
device_ids_validate() was misinterpreting the read error as
|
||||||
|
the device having no data/label on it (and no PVID).
|
||||||
|
The validate function would then clear the PVID from the
|
||||||
|
devices file entry for the device, thinking that it was
|
||||||
|
fixing the devices file (making it consistent with the on disk
|
||||||
|
state.) Fix this by not attempting to check and correct a
|
||||||
|
devices file entry that cannot be read. Also make this case
|
||||||
|
explicit in the hints validation code (which was doing the
|
||||||
|
right thing but indirectly.)
|
||||||
|
---
|
||||||
|
lib/device/device.h | 1 +
|
||||||
|
lib/device/device_id.c | 14 ++++++++++++++
|
||||||
|
lib/label/hints.c | 14 ++++++++++++++
|
||||||
|
lib/label/label.c | 8 ++++++++
|
||||||
|
4 files changed, 37 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device.h b/lib/device/device.h
|
||||||
|
index 9e471a9b5..8c3a8c30e 100644
|
||||||
|
--- a/lib/device/device.h
|
||||||
|
+++ b/lib/device/device.h
|
||||||
|
@@ -40,6 +40,7 @@
|
||||||
|
#define DEV_IS_NVME 0x00040000 /* set if dev is nvme */
|
||||||
|
#define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */
|
||||||
|
#define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */
|
||||||
|
+#define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Support for external device info.
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index aeaa1ffc6..7fe581571 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1724,6 +1724,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||||
|
if (scanned_devs && !dev_in_device_list(dev, scanned_devs))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * The matched device could not be read so we do not have
|
||||||
|
+ * the PVID from disk and cannot verify the devices file entry.
|
||||||
|
+ */
|
||||||
|
+ if (dev->flags & DEV_SCAN_NOT_READ)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* du and dev may have been matched, but the dev could still
|
||||||
|
* have been excluded by other filters during label scan.
|
||||||
|
@@ -1806,6 +1813,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||||
|
if (scanned_devs && !dev_in_device_list(dev, scanned_devs))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * The matched device could not be read so we do not have
|
||||||
|
+ * the PVID from disk and cannot verify the devices file entry.
|
||||||
|
+ */
|
||||||
|
+ if (dev->flags & DEV_SCAN_NOT_READ)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
|
||||||
|
log_warn("Devices file %s is excluded by filter: %s.",
|
||||||
|
dev_name(dev), dev_filtered_reason(dev));
|
||||||
|
diff --git a/lib/label/hints.c b/lib/label/hints.c
|
||||||
|
index 3ce9634f2..95d5d77b8 100644
|
||||||
|
--- a/lib/label/hints.c
|
||||||
|
+++ b/lib/label/hints.c
|
||||||
|
@@ -234,6 +234,7 @@ static int _touch_newhints(void)
|
||||||
|
return_0;
|
||||||
|
if (fclose(fp))
|
||||||
|
stack;
|
||||||
|
+ log_debug("newhints created");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -504,6 +505,19 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
|
||||||
|
if (!hint->chosen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * label_scan was unable to read the dev so we don't know its pvid.
|
||||||
|
+ * Since we are unable to verify the hint is correct, it's possible
|
||||||
|
+ * that the PVID is actually found on a different device, so don't
|
||||||
|
+ * depend on hints. (This would also fail the following pvid check.)
|
||||||
|
+ */
|
||||||
|
+ if (dev->flags & DEV_SCAN_NOT_READ) {
|
||||||
|
+ log_debug("Uncertain hint for unread device %d:%d %s",
|
||||||
|
+ major(hint->devt), minor(hint->devt), dev_name(dev));
|
||||||
|
+ ret = 0;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (strcmp(dev->pvid, hint->pvid)) {
|
||||||
|
log_debug("Invalid hint device %d:%d %s pvid %s had hint pvid %s",
|
||||||
|
major(hint->devt), minor(hint->devt), dev_name(dev),
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index 9fac3e464..354ab35e2 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -686,6 +686,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
|
||||||
|
dm_list_iterate_items_safe(devl, devl2, devs) {
|
||||||
|
|
||||||
|
+ devl->dev->flags &= ~DEV_SCAN_NOT_READ;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* If we prefetch more devs than blocks in the cache, then the
|
||||||
|
* cache will wait for earlier reads to complete, toss the
|
||||||
|
@@ -701,6 +703,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
dm_list_add(&reopen_devs, &devl->list);
|
||||||
|
+ devl->dev->flags |= DEV_SCAN_NOT_READ;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -724,6 +727,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
log_debug_devs("Scan failed to read %s.", dev_name(devl->dev));
|
||||||
|
scan_read_errors++;
|
||||||
|
scan_failed_count++;
|
||||||
|
+ devl->dev->flags |= DEV_SCAN_NOT_READ;
|
||||||
|
lvmcache_del_dev(devl->dev);
|
||||||
|
if (bb)
|
||||||
|
bcache_put(bb);
|
||||||
|
@@ -1113,6 +1117,10 @@ int label_scan(struct cmd_context *cmd)
|
||||||
|
* filter", and this result needs to be cleared (wiped) so that the
|
||||||
|
* complete set of filters (including those that require data) can be
|
||||||
|
* checked in _process_block, where headers have been read.
|
||||||
|
+ *
|
||||||
|
+ * FIXME: devs that are filtered with data in _process_block
|
||||||
|
+ * are not moved to the filtered_devs list like devs filtered
|
||||||
|
+ * here without data. Does that have any effect?
|
||||||
|
*/
|
||||||
|
log_debug_devs("Filtering devices to scan (nodata)");
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,35 @@
|
|||||||
|
From cdefd8635de24200b55822fa0b6bc23a638fb87a Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 21 Feb 2022 11:35:58 -0600
|
||||||
|
Subject: [PATCH 33/54] man lvmcache: mention writecache memory usage
|
||||||
|
|
||||||
|
---
|
||||||
|
man/lvmcache.7_main | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
|
||||||
|
index 48cf7b492..73680235b 100644
|
||||||
|
--- a/man/lvmcache.7_main
|
||||||
|
+++ b/man/lvmcache.7_main
|
||||||
|
@@ -240,6 +240,18 @@ The writecache block size should be chosen to match the xfs sectsz value.
|
||||||
|
It is also possible to specify a sector size of 4096 to mkfs.xfs when
|
||||||
|
creating the file system. In this case the writecache block size of 4096
|
||||||
|
can be used.
|
||||||
|
+.P
|
||||||
|
+.SS dm-writecache memory usage
|
||||||
|
+.P
|
||||||
|
+The amount of main system memory used by dm-writecache can be a factor
|
||||||
|
+when selecting the writecache cachevol size and the writecache block size.
|
||||||
|
+.P
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+writecache block size 4096: each 100 GiB of writecache cachevol uses
|
||||||
|
+slighly over 2 GiB of system memory.
|
||||||
|
+.IP \[bu] 2
|
||||||
|
+writecache block size 512: each 100 GiB of writecache cachevol uses
|
||||||
|
+a little over 16 GiB of system memory.
|
||||||
|
.
|
||||||
|
.SS dm-writecache settings
|
||||||
|
.
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
102
SOURCES/0034-writecache-display-block-size-from-lvs.patch
Normal file
102
SOURCES/0034-writecache-display-block-size-from-lvs.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From c047ff61f68d1b853569b153251f8bc5f88e23cd Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 21 Feb 2022 16:09:57 -0600
|
||||||
|
Subject: [PATCH 34/54] writecache: display block size from lvs
|
||||||
|
|
||||||
|
lvs was missing the ability to display writecache block size.
|
||||||
|
now possible with lvs -o writecache_block_size
|
||||||
|
---
|
||||||
|
lib/report/columns.h | 1 +
|
||||||
|
lib/report/properties.c | 2 ++
|
||||||
|
lib/report/report.c | 20 ++++++++++++++++++++
|
||||||
|
man/lvmcache.7_main | 4 ++++
|
||||||
|
test/shell/writecache-cache-blocksize.sh | 2 ++
|
||||||
|
5 files changed, 29 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/report/columns.h b/lib/report/columns.h
|
||||||
|
index 12b78b766..7e450dace 100644
|
||||||
|
--- a/lib/report/columns.h
|
||||||
|
+++ b/lib/report/columns.h
|
||||||
|
@@ -108,6 +108,7 @@ FIELD(LVS, lv, TIM, "RTime", lvid, 26, lvtimeremoved, lv_time_removed, "Removal
|
||||||
|
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
|
||||||
|
FIELD(LVS, lv, STR_LIST, "Modules", lvid, 0, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
|
||||||
|
FIELD(LVS, lv, BIN, "Historical", lvid, 0, lvhistorical, lv_historical, "Set if the LV is historical.", 0)
|
||||||
|
+FIELD(LVS, lv, NUM, "WCacheBlkSize", lvid, 0, writecache_block_size, writecache_block_size, "The writecache block size", 0)
|
||||||
|
/*
|
||||||
|
* End of LVS type fields
|
||||||
|
*/
|
||||||
|
diff --git a/lib/report/properties.c b/lib/report/properties.c
|
||||||
|
index 12ea890f4..6f302360f 100644
|
||||||
|
--- a/lib/report/properties.c
|
||||||
|
+++ b/lib/report/properties.c
|
||||||
|
@@ -353,6 +353,8 @@ GET_PV_STR_PROPERTY_FN(pv_device_id_type, pv->device_id_type)
|
||||||
|
#define _writecache_writeback_blocks_get prop_not_implemented_get
|
||||||
|
#define _writecache_error_set prop_not_implemented_set
|
||||||
|
#define _writecache_error_get prop_not_implemented_get
|
||||||
|
+#define _writecache_block_size_set prop_not_implemented_set
|
||||||
|
+#define _writecache_block_size_get prop_not_implemented_get
|
||||||
|
|
||||||
|
#define _vdo_operating_mode_set prop_not_implemented_set
|
||||||
|
#define _vdo_operating_mode_get prop_not_implemented_get
|
||||||
|
diff --git a/lib/report/report.c b/lib/report/report.c
|
||||||
|
index 60df417a4..c06b22674 100644
|
||||||
|
--- a/lib/report/report.c
|
||||||
|
+++ b/lib/report/report.c
|
||||||
|
@@ -3346,6 +3346,26 @@ static int _integritymismatches_disp(struct dm_report *rh __attribute__((unused)
|
||||||
|
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _writecache_block_size_disp(struct dm_report *rh __attribute__((unused)),
|
||||||
|
+ struct dm_pool *mem,
|
||||||
|
+ struct dm_report_field *field,
|
||||||
|
+ const void *data,
|
||||||
|
+ void *private __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ struct logical_volume *lv = (struct logical_volume *) data;
|
||||||
|
+ uint32_t bs = 0;
|
||||||
|
+
|
||||||
|
+ if (lv_is_writecache(lv)) {
|
||||||
|
+ struct lv_segment *seg = first_seg(lv);
|
||||||
|
+ bs = seg->writecache_block_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!bs)
|
||||||
|
+ return dm_report_field_int32(rh, field, &GET_TYPE_RESERVED_VALUE(num_undef_32));
|
||||||
|
+
|
||||||
|
+ return dm_report_field_uint32(rh, field, &bs);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
|
||||||
|
struct dm_report_field *field,
|
||||||
|
const void *data, void *private)
|
||||||
|
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
|
||||||
|
index 73680235b..519e352cb 100644
|
||||||
|
--- a/man/lvmcache.7_main
|
||||||
|
+++ b/man/lvmcache.7_main
|
||||||
|
@@ -241,6 +241,10 @@ It is also possible to specify a sector size of 4096 to mkfs.xfs when
|
||||||
|
creating the file system. In this case the writecache block size of 4096
|
||||||
|
can be used.
|
||||||
|
.P
|
||||||
|
+The writecache block size is displayed by the command:
|
||||||
|
+.br
|
||||||
|
+lvs -o writecacheblocksize VG/LV
|
||||||
|
+.P
|
||||||
|
.SS dm-writecache memory usage
|
||||||
|
.P
|
||||||
|
The amount of main system memory used by dm-writecache can be a factor
|
||||||
|
diff --git a/test/shell/writecache-cache-blocksize.sh b/test/shell/writecache-cache-blocksize.sh
|
||||||
|
index 2579ef7b7..4e17effe5 100644
|
||||||
|
--- a/test/shell/writecache-cache-blocksize.sh
|
||||||
|
+++ b/test/shell/writecache-cache-blocksize.sh
|
||||||
|
@@ -222,6 +222,8 @@ vgextend $vg "$dev2"
|
||||||
|
lvcreate -n $lv1 -l 8 -an $vg "$dev1"
|
||||||
|
lvcreate -n $lv2 -l 4 -an $vg "$dev2"
|
||||||
|
lvconvert --yes --type writecache --cachevol $lv2 --cachesettings "block_size=4096" $vg/$lv1
|
||||||
|
+lvs -o writecacheblocksize $vg/$lv1 |tee out
|
||||||
|
+grep 4096 out
|
||||||
|
lvchange -ay $vg/$lv1
|
||||||
|
mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1" |tee out
|
||||||
|
grep "sectsz=4096" out
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
148
SOURCES/0035-devices-simplify-dev_cache_get_by_devt.patch
Normal file
148
SOURCES/0035-devices-simplify-dev_cache_get_by_devt.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From 8552290efae4905fd1a942be8e752842b11f1881 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 24 Feb 2022 15:57:29 -0600
|
||||||
|
Subject: [PATCH 35/54] devices: simplify dev_cache_get_by_devt
|
||||||
|
|
||||||
|
remove unused args, and no callers need or want a
|
||||||
|
repeated dev_cache_scan if there is no dev from the
|
||||||
|
lookup.
|
||||||
|
---
|
||||||
|
lib/device/dev-cache.c | 60 ++++--------------------------------------
|
||||||
|
lib/device/dev-cache.h | 2 +-
|
||||||
|
lib/label/label.c | 2 +-
|
||||||
|
tools/pvscan.c | 6 ++---
|
||||||
|
4 files changed, 10 insertions(+), 60 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index c6e5f68cf..cc1af7c7a 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -1577,63 +1577,13 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered)
|
||||||
|
+struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
|
||||||
|
{
|
||||||
|
- char path[PATH_MAX];
|
||||||
|
- const char *sysfs_dir;
|
||||||
|
- struct stat info;
|
||||||
|
- struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- if (filtered)
|
||||||
|
- *filtered = 0;
|
||||||
|
-
|
||||||
|
- if (!d) {
|
||||||
|
- sysfs_dir = dm_sysfs_dir();
|
||||||
|
- if (sysfs_dir && *sysfs_dir) {
|
||||||
|
- /* First check if dev is sysfs to avoid useless scan */
|
||||||
|
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
|
||||||
|
- sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) {
|
||||||
|
- log_error("dm_snprintf partition failed.");
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (lstat(path, &info)) {
|
||||||
|
- log_debug("No sysfs entry for %d:%d errno %d at %s.",
|
||||||
|
- (int)MAJOR(dev), (int)MINOR(dev), errno, path);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d",
|
||||||
|
- (int)MAJOR(dev), (int)MINOR(dev));
|
||||||
|
- dev_cache_scan(cmd);
|
||||||
|
- d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
|
||||||
|
-
|
||||||
|
- if (!d)
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (d->flags & DEV_REGULAR)
|
||||||
|
- return d;
|
||||||
|
-
|
||||||
|
- if (!f)
|
||||||
|
- return d;
|
||||||
|
-
|
||||||
|
- ret = f->passes_filter(cmd, f, d, NULL);
|
||||||
|
-
|
||||||
|
- if (ret == -EAGAIN) {
|
||||||
|
- log_debug_devs("get device by number defer filter %s", dev_name(d));
|
||||||
|
- d->flags |= DEV_FILTER_AFTER_SCAN;
|
||||||
|
- ret = 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (ret)
|
||||||
|
- return d;
|
||||||
|
-
|
||||||
|
- if (filtered)
|
||||||
|
- *filtered = 1;
|
||||||
|
+ struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
|
||||||
|
|
||||||
|
+ if (dev)
|
||||||
|
+ return dev;
|
||||||
|
+ log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
|
||||||
|
index 635dc4fc9..7305eeb0e 100644
|
||||||
|
--- a/lib/device/dev-cache.h
|
||||||
|
+++ b/lib/device/dev-cache.h
|
||||||
|
@@ -54,7 +54,7 @@ int dev_cache_has_scanned(void);
|
||||||
|
int dev_cache_add_dir(const char *path);
|
||||||
|
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||||
|
|
||||||
|
-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered);
|
||||||
|
+struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
|
||||||
|
|
||||||
|
struct device *dev_hash_get(const char *name);
|
||||||
|
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index 354ab35e2..ffe925254 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -1443,7 +1443,7 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
|
||||||
|
if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) {
|
||||||
|
/* FIXME: Still unclear what is it supposed to find */
|
||||||
|
devt = MKDEV(lvinfo.major, lvinfo.minor);
|
||||||
|
- if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
|
||||||
|
+ if ((dev = dev_cache_get_by_devt(cmd, devt)))
|
||||||
|
label_scan_invalidate(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index f60c4a2ca..160a2c9a0 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -857,7 +857,7 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname,
|
||||||
|
|
||||||
|
devno = MKDEV(file_major, file_minor);
|
||||||
|
|
||||||
|
- if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) {
|
||||||
|
+ if (!(dev = dev_cache_get_by_devt(cmd, devno))) {
|
||||||
|
log_error_pvscan(cmd, "No device found for %d:%d PVID %s", file_major, file_minor, pvid);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
@@ -1195,7 +1195,7 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
|
||||||
|
if (arg->devname)
|
||||||
|
arg->dev = dev_cache_get(cmd, arg->devname, NULL);
|
||||||
|
else if (arg->devno)
|
||||||
|
- arg->dev = dev_cache_get_by_devt(cmd, arg->devno, NULL, NULL);
|
||||||
|
+ arg->dev = dev_cache_get_by_devt(cmd, arg->devno);
|
||||||
|
else
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
@@ -1257,7 +1257,7 @@ static void _set_pv_devices_online(struct cmd_context *cmd, struct volume_group
|
||||||
|
|
||||||
|
devno = MKDEV(major, minor);
|
||||||
|
|
||||||
|
- if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) {
|
||||||
|
+ if (!(dev = dev_cache_get_by_devt(cmd, devno))) {
|
||||||
|
log_print_pvscan(cmd, "VG %s PV %s no device found for %d:%d",
|
||||||
|
vg->name, pvid, major, minor);
|
||||||
|
pvl->pv->status |= MISSING_PV;
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,467 @@
|
|||||||
|
From 8ba6259b24cd4b99e061f2610c5cd0bcde890039 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 24 Feb 2022 16:03:21 -0600
|
||||||
|
Subject: [PATCH 36/54] devices: drop incorrect paths from aliases list
|
||||||
|
|
||||||
|
along with some basic checks for cases when a device
|
||||||
|
has no aliases.
|
||||||
|
|
||||||
|
lvm itself creates many situations where a struct device
|
||||||
|
has no valid paths, when it activates and opens an LV,
|
||||||
|
does something with it, e.g. zeroing, and then closes
|
||||||
|
and deactivates it. (dev-cache is intended for PVs, and
|
||||||
|
the use of LVs should be moved out of dev-cache in a
|
||||||
|
future patch.)
|
||||||
|
---
|
||||||
|
lib/device/dev-cache.c | 223 ++++++++++++++++++++++++++---------------
|
||||||
|
lib/device/dev-cache.h | 2 +-
|
||||||
|
lib/device/dev-io.c | 34 ++++---
|
||||||
|
lib/device/device.h | 3 -
|
||||||
|
4 files changed, 164 insertions(+), 98 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index cc1af7c7a..58e67e130 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -351,7 +351,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!(path = dm_pool_strdup(_cache.mem, path)) ||
|
||||||
|
+ if (!(path = _strdup(path)) ||
|
||||||
|
!(sl = _zalloc(sizeof(*sl)))) {
|
||||||
|
log_error("Failed to add allias to dev cache.");
|
||||||
|
return 0;
|
||||||
|
@@ -1162,6 +1162,17 @@ static int _insert(const char *path, const struct stat *info,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void _drop_all_aliases(struct device *dev)
|
||||||
|
+{
|
||||||
|
+ struct dm_str_list *strl, *strl2;
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
|
||||||
|
+ log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str);
|
||||||
|
+ dm_hash_remove(_cache.names, strl->str);
|
||||||
|
+ dm_list_del(&strl->list);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void dev_cache_scan(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
log_debug_devs("Creating list of system devices.");
|
||||||
|
@@ -1371,59 +1382,6 @@ int dev_cache_add_dir(const char *path)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Check cached device name is still valid before returning it */
|
||||||
|
-/* This should be a rare occurrence */
|
||||||
|
-/* set quiet if the cache is expected to be out-of-date */
|
||||||
|
-/* FIXME Make rest of code pass/cache struct device instead of dev_name */
|
||||||
|
-const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||||
|
-{
|
||||||
|
- struct stat buf;
|
||||||
|
- const char *name;
|
||||||
|
- int r;
|
||||||
|
-
|
||||||
|
- if ((dev->flags & DEV_REGULAR))
|
||||||
|
- return dev_name(dev);
|
||||||
|
-
|
||||||
|
- while ((r = stat(name = dm_list_item(dev->aliases.n,
|
||||||
|
- struct dm_str_list)->str, &buf)) ||
|
||||||
|
- (buf.st_rdev != dev->dev)) {
|
||||||
|
- if (r < 0) {
|
||||||
|
- if (quiet)
|
||||||
|
- log_sys_debug("stat", name);
|
||||||
|
- else
|
||||||
|
- log_sys_error("stat", name);
|
||||||
|
- }
|
||||||
|
- if (quiet)
|
||||||
|
- log_debug_devs("Path %s no longer valid for device(%d,%d)",
|
||||||
|
- name, (int) MAJOR(dev->dev),
|
||||||
|
- (int) MINOR(dev->dev));
|
||||||
|
- else
|
||||||
|
- log_warn("Path %s no longer valid for device(%d,%d)",
|
||||||
|
- name, (int) MAJOR(dev->dev),
|
||||||
|
- (int) MINOR(dev->dev));
|
||||||
|
-
|
||||||
|
- /* Remove the incorrect hash entry */
|
||||||
|
- dm_hash_remove(_cache.names, name);
|
||||||
|
-
|
||||||
|
- /* Leave list alone if there isn't an alternative name */
|
||||||
|
- /* so dev_name will always find something to return. */
|
||||||
|
- /* Otherwise add the name to the correct device. */
|
||||||
|
- if (dm_list_size(&dev->aliases) > 1) {
|
||||||
|
- dm_list_del(dev->aliases.n);
|
||||||
|
- if (!r)
|
||||||
|
- _insert(name, &buf, 0, obtain_device_list_from_udev());
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Scanning issues this inappropriately sometimes. */
|
||||||
|
- log_debug_devs("Aborting - please provide new pathname for what "
|
||||||
|
- "used to be %s", name);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return dev_name(dev);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
struct device *dev_hash_get(const char *name)
|
||||||
|
{
|
||||||
|
return (struct device *) dm_hash_lookup(_cache.names, name);
|
||||||
|
@@ -1452,26 +1410,23 @@ static void _remove_alias(struct device *dev, const char *name)
|
||||||
|
* deactivated LV. Those old paths are all invalid and are dropped here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static void _verify_aliases(struct device *dev, const char *newname)
|
||||||
|
+static void _verify_aliases(struct device *dev)
|
||||||
|
{
|
||||||
|
struct dm_str_list *strl, *strl2;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
|
||||||
|
- /* newname was just stat'd and added by caller */
|
||||||
|
- if (newname && !strcmp(strl->str, newname))
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) {
|
||||||
|
- log_debug("Drop invalid path %s for %d:%d (new path %s).",
|
||||||
|
- strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: "");
|
||||||
|
+ log_debug("Drop alias for %d:%d invalid path %s %d:%d.",
|
||||||
|
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str,
|
||||||
|
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev));
|
||||||
|
dm_hash_remove(_cache.names, strl->str);
|
||||||
|
dm_list_del(&strl->list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
|
||||||
|
+static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing)
|
||||||
|
{
|
||||||
|
struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||||
|
struct stat st;
|
||||||
|
@@ -1485,13 +1440,18 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
|
||||||
|
if (dev && (dev->flags & DEV_REGULAR))
|
||||||
|
return dev;
|
||||||
|
|
||||||
|
+ if (dev && dm_list_empty(&dev->aliases)) {
|
||||||
|
+ /* shouldn't happen */
|
||||||
|
+ log_warn("Ignoring dev with no valid paths for %s.", name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
- * The requested path is invalid, remove any dev-cache
|
||||||
|
- * info for it.
|
||||||
|
+ * The requested path is invalid, remove any dev-cache info for it.
|
||||||
|
*/
|
||||||
|
if (stat(name, &st)) {
|
||||||
|
if (dev) {
|
||||||
|
- log_print("Device path %s is invalid for %d:%d %s.",
|
||||||
|
+ log_debug("Device path %s is invalid for %d:%d %s.",
|
||||||
|
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
|
||||||
|
|
||||||
|
dm_hash_remove(_cache.names, name);
|
||||||
|
@@ -1499,11 +1459,17 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
|
||||||
|
_remove_alias(dev, name);
|
||||||
|
|
||||||
|
/* Remove any other names in dev->aliases that are incorrect. */
|
||||||
|
- _verify_aliases(dev, NULL);
|
||||||
|
+ _verify_aliases(dev);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (dev && dm_list_empty(&dev->aliases)) {
|
||||||
|
+ /* shouldn't happen */
|
||||||
|
+ log_warn("Ignoring dev with no valid paths for %s.", name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!S_ISBLK(st.st_mode)) {
|
||||||
|
log_debug("Not a block device %s.", name);
|
||||||
|
return NULL;
|
||||||
|
@@ -1514,26 +1480,110 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
|
||||||
|
* Remove incorrect info and then add new dev-cache entry.
|
||||||
|
*/
|
||||||
|
if (dev && (st.st_rdev != dev->dev)) {
|
||||||
|
- log_debug("Device path %s does not match %d:%d %s.",
|
||||||
|
- name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
|
||||||
|
+ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * lvm commands create this condition when they
|
||||||
|
+ * activate/deactivate LVs combined with creating new LVs.
|
||||||
|
+ * The command does not purge dev structs when deactivating
|
||||||
|
+ * an LV (which it probably should do), but the better
|
||||||
|
+ * approach would be not using dev-cache at all for LVs.
|
||||||
|
+ */
|
||||||
|
|
||||||
|
- dm_hash_remove(_cache.names, name);
|
||||||
|
+ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
|
||||||
|
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev),
|
||||||
|
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
|
||||||
|
|
||||||
|
- _remove_alias(dev, name);
|
||||||
|
+ _drop_all_aliases(dev);
|
||||||
|
|
||||||
|
- /* Remove any other names in dev->aliases that are incorrect. */
|
||||||
|
- _verify_aliases(dev, NULL);
|
||||||
|
+ if (dev_by_devt) {
|
||||||
|
+ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
|
||||||
|
+ (int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt),
|
||||||
|
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
|
||||||
|
|
||||||
|
- /* Add new dev-cache entry next. */
|
||||||
|
- dev = NULL;
|
||||||
|
+ _drop_all_aliases(dev_by_devt);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+ /*
|
||||||
|
+ * I think only lvm's own dm devs should be added here, so use
|
||||||
|
+ * a warning to look for any other unknown cases.
|
||||||
|
+ */
|
||||||
|
+ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
|
||||||
|
+ log_warn("WARNING: new device appeared %d:%d %s",
|
||||||
|
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ if (!_insert_dev(name, st.st_rdev))
|
||||||
|
+ return_NULL;
|
||||||
|
+
|
||||||
|
+ /* Get the struct dev that was just added. */
|
||||||
|
+ dev = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||||
|
+
|
||||||
|
+ if (!dev) {
|
||||||
|
+ log_error("Failed to get device %s", name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (dev && dm_list_empty(&dev->aliases)) {
|
||||||
|
+ /* shouldn't happen */
|
||||||
|
+ log_warn("Ignoring dev with no valid paths for %s.", name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!dev && existing)
|
||||||
|
+ return_NULL;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
- * Either add a new struct dev for st_rdev and name,
|
||||||
|
- * or add name as a new alias for an existing struct dev
|
||||||
|
- * for st_rdev.
|
||||||
|
+ * This case should never be hit for a PV. It should only
|
||||||
|
+ * happen when the command is opening a new LV it has created.
|
||||||
|
+ * Add an arg to all callers indicating when the arg should be
|
||||||
|
+ * new (for an LV) and not existing.
|
||||||
|
+ * FIXME: fix this further by not using dev-cache struct devs
|
||||||
|
+ * at all for new dm devs (LVs) that lvm uses. Make the
|
||||||
|
+ * dev-cache contain only devs for PVs.
|
||||||
|
+ * Places to fix that use a dev for LVs include:
|
||||||
|
+ * . lv_resize opening lv to discard
|
||||||
|
+ * . wipe_lv opening lv to zero it
|
||||||
|
+ * . _extend_sanlock_lv opening lv to extend it
|
||||||
|
+ * . _write_log_header opening lv to write header
|
||||||
|
+ * Also, io to LVs should not go through bcache.
|
||||||
|
+ * bcache should contain only labels and metadata
|
||||||
|
+ * scanned from PVs.
|
||||||
|
*/
|
||||||
|
if (!dev) {
|
||||||
|
+ /*
|
||||||
|
+ * This case should only be used for new devices created by this
|
||||||
|
+ * command (opening LVs it's created), so if a dev exists for the
|
||||||
|
+ * dev_t referenced by the name, then drop all aliases for before
|
||||||
|
+ * _insert_dev adds the new name. lvm commands actually hit this
|
||||||
|
+ * fairly often when it uses some LV, deactivates the LV, then
|
||||||
|
+ * creates some new LV which ends up with the same major:minor.
|
||||||
|
+ * Without dropping the aliases, it's plausible that lvm commands
|
||||||
|
+ * could end up using the wrong dm device.
|
||||||
|
+ */
|
||||||
|
+ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
|
||||||
|
+ if (dev_by_devt) {
|
||||||
|
+ log_debug("Dropping aliases for %d:%d before adding new path %s.",
|
||||||
|
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
|
||||||
|
+ _drop_all_aliases(dev_by_devt);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+ /*
|
||||||
|
+ * I think only lvm's own dm devs should be added here, so use
|
||||||
|
+ * a warning to look for any other unknown cases.
|
||||||
|
+ */
|
||||||
|
+ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
|
||||||
|
+ log_warn("WARNING: new device appeared %d:%d %s",
|
||||||
|
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (!_insert_dev(name, st.st_rdev))
|
||||||
|
return_NULL;
|
||||||
|
|
||||||
|
@@ -1544,10 +1594,9 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
|
||||||
|
log_error("Failed to get device %s", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- _verify_aliases(dev, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ out:
|
||||||
|
/*
|
||||||
|
* The caller passed a filter if they only want the dev if it
|
||||||
|
* passes filters.
|
||||||
|
@@ -1577,6 +1626,16 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f)
|
||||||
|
+{
|
||||||
|
+ return _dev_cache_get(cmd, name, f, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
|
||||||
|
+{
|
||||||
|
+ return _dev_cache_get(cmd, name, f, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
|
||||||
|
{
|
||||||
|
struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
|
||||||
|
@@ -1653,8 +1712,10 @@ int dev_fd(struct device *dev)
|
||||||
|
|
||||||
|
const char *dev_name(const struct device *dev)
|
||||||
|
{
|
||||||
|
- return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
|
||||||
|
- unknown_device_name();
|
||||||
|
+ if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases))
|
||||||
|
+ return dm_list_item(dev->aliases.n, struct dm_str_list)->str;
|
||||||
|
+ else
|
||||||
|
+ return unknown_device_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
|
||||||
|
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
|
||||||
|
index 7305eeb0e..51c3fc6c3 100644
|
||||||
|
--- a/lib/device/dev-cache.h
|
||||||
|
+++ b/lib/device/dev-cache.h
|
||||||
|
@@ -53,7 +53,7 @@ int dev_cache_has_scanned(void);
|
||||||
|
|
||||||
|
int dev_cache_add_dir(const char *path);
|
||||||
|
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||||
|
-
|
||||||
|
+struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||||
|
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
|
||||||
|
|
||||||
|
struct device *dev_hash_get(const char *name);
|
||||||
|
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
|
||||||
|
index b4f1930b1..811ad8978 100644
|
||||||
|
--- a/lib/device/dev-io.c
|
||||||
|
+++ b/lib/device/dev-io.c
|
||||||
|
@@ -58,6 +58,9 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size)
|
||||||
|
const char *name = dev_name(dev);
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
+ if (dm_list_empty(&dev->aliases))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
if (dev->size_seqno == _dev_size_seqno) {
|
||||||
|
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
|
||||||
|
name, dev->size);
|
||||||
|
@@ -87,7 +90,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||||
|
int do_close = 0;
|
||||||
|
|
||||||
|
if (dm_list_empty(&dev->aliases))
|
||||||
|
- return 0;
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
if (dev->size_seqno == _dev_size_seqno) {
|
||||||
|
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
|
||||||
|
@@ -305,6 +308,13 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||||
|
if ((flags & O_EXCL))
|
||||||
|
need_excl = 1;
|
||||||
|
|
||||||
|
+ if (dm_list_empty(&dev->aliases)) {
|
||||||
|
+ /* shouldn't happen */
|
||||||
|
+ log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ name = dev_name(dev);
|
||||||
|
+
|
||||||
|
if (dev->fd >= 0) {
|
||||||
|
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
|
||||||
|
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
|
||||||
|
@@ -314,7 +324,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||||
|
|
||||||
|
if (dev->open_count && !need_excl)
|
||||||
|
log_debug_devs("%s: Already opened read-only. Upgrading "
|
||||||
|
- "to read-write.", dev_name(dev));
|
||||||
|
+ "to read-write.", name);
|
||||||
|
|
||||||
|
/* dev_close_immediate will decrement this */
|
||||||
|
dev->open_count++;
|
||||||
|
@@ -327,11 +337,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||||
|
|
||||||
|
if (critical_section())
|
||||||
|
/* FIXME Make this log_error */
|
||||||
|
- log_verbose("dev_open(%s) called while suspended",
|
||||||
|
- dev_name(dev));
|
||||||
|
-
|
||||||
|
- if (!(name = dev_name_confirmed(dev, quiet)))
|
||||||
|
- return_0;
|
||||||
|
+ log_verbose("dev_open(%s) called while suspended", name);
|
||||||
|
|
||||||
|
#ifdef O_DIRECT_SUPPORT
|
||||||
|
if (direct) {
|
||||||
|
@@ -372,9 +378,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (quiet)
|
||||||
|
- log_sys_debug("open", name);
|
||||||
|
+ log_debug("Failed to open device path %s (%d).", name, errno);
|
||||||
|
else
|
||||||
|
- log_sys_error("open", name);
|
||||||
|
+ log_error("Failed to open device path %s (%d).", name, errno);
|
||||||
|
|
||||||
|
dev->flags |= DEV_OPEN_FAILURE;
|
||||||
|
return 0;
|
||||||
|
@@ -415,10 +421,12 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||||
|
if ((flags & O_CREAT) && !(flags & O_TRUNC))
|
||||||
|
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
|
||||||
|
|
||||||
|
- log_debug_devs("Opened %s %s%s%s", dev_name(dev),
|
||||||
|
- dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||||
|
- dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||||
|
- dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
|
||||||
|
+ if (!quiet) {
|
||||||
|
+ log_debug_devs("Opened %s %s%s%s", name,
|
||||||
|
+ dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||||
|
+ dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||||
|
+ dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
dev->flags &= ~DEV_OPEN_FAILURE;
|
||||||
|
return 1;
|
||||||
|
diff --git a/lib/device/device.h b/lib/device/device.h
|
||||||
|
index 8c3a8c30e..572994bb9 100644
|
||||||
|
--- a/lib/device/device.h
|
||||||
|
+++ b/lib/device/device.h
|
||||||
|
@@ -204,9 +204,6 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||||
|
struct dm_str_list *alias, int use_malloc);
|
||||||
|
void dev_destroy_file(struct device *dev);
|
||||||
|
|
||||||
|
-/* Return a valid device name from the alias list; NULL otherwise */
|
||||||
|
-const char *dev_name_confirmed(struct device *dev, int quiet);
|
||||||
|
-
|
||||||
|
int dev_mpath_init(const char *config_wwids_file);
|
||||||
|
void dev_mpath_exit(void);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
70
SOURCES/0037-devices-initial-use-of-existing-option.patch
Normal file
70
SOURCES/0037-devices-initial-use-of-existing-option.patch
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
From 7dc7ab8e99005da29aba22df2bb67e58e19a50f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 24 Feb 2022 16:10:37 -0600
|
||||||
|
Subject: [PATCH 37/54] devices: initial use of existing option
|
||||||
|
|
||||||
|
Use dev_cache_get_existing() in a few common, high level
|
||||||
|
locations where it's obvious that only existing dev-cache
|
||||||
|
entries are wanted. This can be expanded and used in more
|
||||||
|
locations (or dev_cache_get can stop creating new entries.)
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 4 ++--
|
||||||
|
tools/toollib.c | 6 +++---
|
||||||
|
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 7fe581571..bcb2e6bcf 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1565,7 +1565,7 @@ void device_ids_match(struct cmd_context *cmd)
|
||||||
|
dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
if (du->dev)
|
||||||
|
continue;
|
||||||
|
- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
|
||||||
|
+ if (!(du->dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
|
||||||
|
log_warn("Device not found for %s.", du->devname);
|
||||||
|
} else {
|
||||||
|
/* Should we set dev->id? Which idtype? Use --deviceidtype? */
|
||||||
|
@@ -1603,7 +1603,7 @@ void device_ids_match(struct cmd_context *cmd)
|
||||||
|
* the du/dev pairs in preparation for using the filters.
|
||||||
|
*/
|
||||||
|
if (du->devname &&
|
||||||
|
- (dev = dev_cache_get(cmd, du->devname, NULL))) {
|
||||||
|
+ (dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
|
||||||
|
/* On successful match, du, dev, and id are linked. */
|
||||||
|
if (_match_du_to_dev(cmd, du, dev))
|
||||||
|
continue;
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index d6f48aad2..16be336d4 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -1434,7 +1434,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!(dev = dev_cache_get(cmd, argv[opt], cmd->filter))) {
|
||||||
|
+ if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) {
|
||||||
|
log_error("Failed to find device "
|
||||||
|
"\"%s\".", argv[opt]);
|
||||||
|
ret_max = ECMD_FAILED;
|
||||||
|
@@ -3870,7 +3870,7 @@ static int _get_arg_devices(struct cmd_context *cmd,
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!(dil->dev = dev_cache_get(cmd, sl->str, cmd->filter))) {
|
||||||
|
+ if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) {
|
||||||
|
log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str));
|
||||||
|
ret_max = EINIT_FAILED;
|
||||||
|
} else {
|
||||||
|
@@ -5206,7 +5206,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
/* No filter used here */
|
||||||
|
- if (!(dev = dev_cache_get(cmd, pd->name, NULL))) {
|
||||||
|
+ if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) {
|
||||||
|
log_error("No device found for %s.", pd->name);
|
||||||
|
dm_list_del(&pd->list);
|
||||||
|
dm_list_add(&pp->arg_fail, &pd->list);
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
270
SOURCES/0038-devices-fix-dev_name-assumptions.patch
Normal file
270
SOURCES/0038-devices-fix-dev_name-assumptions.patch
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
From 591b5f006fca7e06bfbf0d5512da3ae5b0f6bbdd Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 22 Feb 2022 15:03:11 -0600
|
||||||
|
Subject: [PATCH 38/54] devices: fix dev_name assumptions
|
||||||
|
|
||||||
|
dev_name(dev) returns "[unknown]" if there are no names
|
||||||
|
on dev->aliases. It's meant mainly for log messages.
|
||||||
|
|
||||||
|
Many places assume a valid path name is returned, and
|
||||||
|
use it directly. A caller that wants to use the path
|
||||||
|
from dev_name() must first check if the dev has any
|
||||||
|
paths with dm_list_empty(&dev->aliases).
|
||||||
|
---
|
||||||
|
lib/activate/dev_manager.c | 9 ++++++++-
|
||||||
|
lib/device/dev-type.c | 3 +++
|
||||||
|
lib/device/device_id.c | 13 +++++++++++--
|
||||||
|
lib/label/hints.c | 2 ++
|
||||||
|
lib/label/label.c | 16 +++++++++++++++-
|
||||||
|
lib/locking/lvmlockd.c | 4 ++++
|
||||||
|
lib/metadata/mirror.c | 17 +++++++++++++----
|
||||||
|
lib/metadata/pv_list.c | 5 +++++
|
||||||
|
lib/metadata/vg.c | 5 +++++
|
||||||
|
test/shell/losetup-partscan.sh | 2 ++
|
||||||
|
10 files changed, 68 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
||||||
|
index a73a556b2..284254d68 100644
|
||||||
|
--- a/lib/activate/dev_manager.c
|
||||||
|
+++ b/lib/activate/dev_manager.c
|
||||||
|
@@ -2875,6 +2875,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||||
|
|
||||||
|
/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
|
||||||
|
for (s = start_area; s < areas; s++) {
|
||||||
|
+
|
||||||
|
+ /* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases)
|
||||||
|
+ but this knot of logic is too complex to pull apart without careful deconstruction. */
|
||||||
|
+
|
||||||
|
if ((seg_type(seg, s) == AREA_PV &&
|
||||||
|
(!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
|
||||||
|
!(name = dev_name(seg_dev(seg, s))) || !*name ||
|
||||||
|
@@ -2893,7 +2897,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||||
|
return_0;
|
||||||
|
num_error_areas++;
|
||||||
|
} else if (seg_type(seg, s) == AREA_PV) {
|
||||||
|
- if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL,
|
||||||
|
+ struct device *dev = seg_dev(seg, s);
|
||||||
|
+ name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev);
|
||||||
|
+
|
||||||
|
+ if (!dm_tree_node_add_target_area(node, name, NULL,
|
||||||
|
(seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s)))))
|
||||||
|
return_0;
|
||||||
|
num_existing_areas++;
|
||||||
|
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
|
||||||
|
index 0e77a009d..c67a86fa3 100644
|
||||||
|
--- a/lib/device/dev-type.c
|
||||||
|
+++ b/lib/device/dev-type.c
|
||||||
|
@@ -966,6 +966,9 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
|
||||||
|
|
||||||
|
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
|
||||||
|
|
||||||
|
+ if (dm_list_empty(&dev->aliases))
|
||||||
|
+ goto_out;
|
||||||
|
+
|
||||||
|
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
|
||||||
|
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
|
||||||
|
goto out;
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index bcb2e6bcf..82db6e4a5 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -347,6 +347,8 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (idtype == DEV_ID_TYPE_DEVNAME) {
|
||||||
|
+ if (dm_list_empty(&dev->aliases))
|
||||||
|
+ goto_bad;
|
||||||
|
if (!(idname = strdup(dev_name(dev))))
|
||||||
|
goto_bad;
|
||||||
|
return idname;
|
||||||
|
@@ -940,6 +942,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
|
||||||
|
if (!dev_get_partition_number(dev, &part))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ /* Ensure valid dev_name(dev) below. */
|
||||||
|
+ if (dm_list_empty(&dev->aliases))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* When enable_devices_file=0 and pending_devices_file=1 we let
|
||||||
|
* pvcreate/vgcreate add new du's to cmd->use_devices. These du's may
|
||||||
|
@@ -1820,6 +1826,9 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||||
|
if (dev->flags & DEV_SCAN_NOT_READ)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ if (dm_list_empty(&dev->aliases))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
|
||||||
|
log_warn("Devices file %s is excluded by filter: %s.",
|
||||||
|
dev_name(dev), dev_filtered_reason(dev));
|
||||||
|
@@ -2197,14 +2206,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
|
||||||
|
dm_list_iterate_items(dil, &search_pvids) {
|
||||||
|
char *dup_devname1, *dup_devname2, *dup_devname3;
|
||||||
|
|
||||||
|
- if (!dil->dev) {
|
||||||
|
+ if (!dil->dev || dm_list_empty(&dil->dev->aliases)) {
|
||||||
|
not_found++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- found++;
|
||||||
|
|
||||||
|
dev = dil->dev;
|
||||||
|
devname = dev_name(dev);
|
||||||
|
+ found++;
|
||||||
|
|
||||||
|
if (!(du = get_du_for_pvid(cmd, dil->pvid))) {
|
||||||
|
/* shouldn't happen */
|
||||||
|
diff --git a/lib/label/hints.c b/lib/label/hints.c
|
||||||
|
index 95d5d77b8..2a7b3dca7 100644
|
||||||
|
--- a/lib/label/hints.c
|
||||||
|
+++ b/lib/label/hints.c
|
||||||
|
@@ -498,6 +498,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
|
||||||
|
if (!(iter = dev_iter_create(NULL, 0)))
|
||||||
|
return 0;
|
||||||
|
while ((dev = dev_iter_get(cmd, iter))) {
|
||||||
|
+ if (dm_list_empty(&dev->aliases))
|
||||||
|
+ continue;
|
||||||
|
if (!(hint = _find_hint_name(hints, dev_name(dev))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index ffe925254..cf707f7a3 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -1565,10 +1565,24 @@ int label_scan_open_rw(struct device *dev)
|
||||||
|
|
||||||
|
int label_scan_reopen_rw(struct device *dev)
|
||||||
|
{
|
||||||
|
+ const char *name;
|
||||||
|
int flags = 0;
|
||||||
|
int prev_fd = dev->bcache_fd;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
+ if (dm_list_empty(&dev->aliases)) {
|
||||||
|
+ log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.",
|
||||||
|
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ name = dev_name(dev);
|
||||||
|
+ if (!name || name[0] != '/') {
|
||||||
|
+ log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.",
|
||||||
|
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!(dev->flags & DEV_IN_BCACHE)) {
|
||||||
|
if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) {
|
||||||
|
/* shouldn't happen */
|
||||||
|
@@ -1598,7 +1612,7 @@ int label_scan_reopen_rw(struct device *dev)
|
||||||
|
flags |= O_NOATIME;
|
||||||
|
flags |= O_RDWR;
|
||||||
|
|
||||||
|
- fd = open(dev_name(dev), flags, 0777);
|
||||||
|
+ fd = open(name, flags, 0777);
|
||||||
|
if (fd < 0) {
|
||||||
|
log_error("Failed to open rw %s errno %d di %d fd %d.",
|
||||||
|
dev_name(dev), errno, dev->bcache_di, dev->bcache_fd);
|
||||||
|
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
|
||||||
|
index b598df3d6..60c80f1b1 100644
|
||||||
|
--- a/lib/locking/lvmlockd.c
|
||||||
|
+++ b/lib/locking/lvmlockd.c
|
||||||
|
@@ -272,6 +272,8 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
|
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
|
||||||
|
+ continue;
|
||||||
|
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
|
||||||
|
if (!lock_pvs->path[i]) {
|
||||||
|
log_error("Fail to allocate PV path for VG %s", vg->name);
|
||||||
|
@@ -341,6 +343,8 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
|
||||||
|
|
||||||
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
|
if (lv_is_on_pv(lv, pvl->pv)) {
|
||||||
|
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
|
||||||
|
+ continue;
|
||||||
|
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
|
||||||
|
if (!lock_pvs->path[i]) {
|
||||||
|
log_error("Fail to allocate PV path for LV %s/%s",
|
||||||
|
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
|
||||||
|
index e2bf191a1..46da57948 100644
|
||||||
|
--- a/lib/metadata/mirror.c
|
||||||
|
+++ b/lib/metadata/mirror.c
|
||||||
|
@@ -1231,14 +1231,23 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
|
||||||
|
const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
|
||||||
|
{
|
||||||
|
struct lv_segment *seg;
|
||||||
|
+ struct device *dev;
|
||||||
|
|
||||||
|
dm_list_iterate_items(seg, &lv_mirr->segments) {
|
||||||
|
if (!seg_is_mirrored(seg))
|
||||||
|
continue;
|
||||||
|
- if (seg_type(seg, 0) == AREA_PV)
|
||||||
|
- return dev_name(seg_dev(seg, 0));
|
||||||
|
- if (seg_type(seg, 0) == AREA_LV)
|
||||||
|
- return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0));
|
||||||
|
+ if (seg_type(seg, 0) == AREA_PV) {
|
||||||
|
+ dev = seg_dev(seg, 0);
|
||||||
|
+ if (!dev || dm_list_empty(&dev->aliases))
|
||||||
|
+ return NULL;
|
||||||
|
+ return dev_name(dev);
|
||||||
|
+ }
|
||||||
|
+ if (seg_type(seg, 0) == AREA_LV) {
|
||||||
|
+ dev = seg_dev(first_seg(seg_lv(seg, 0)), 0);
|
||||||
|
+ if (!dev || dm_list_empty(&dev->aliases))
|
||||||
|
+ return NULL;
|
||||||
|
+ return dev_name(dev);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
diff --git a/lib/metadata/pv_list.c b/lib/metadata/pv_list.c
|
||||||
|
index 813e8e525..fc3667db0 100644
|
||||||
|
--- a/lib/metadata/pv_list.c
|
||||||
|
+++ b/lib/metadata/pv_list.c
|
||||||
|
@@ -152,6 +152,11 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
|
||||||
|
struct pv_list *new_pvl = NULL, *pvl2;
|
||||||
|
struct dm_list *pe_ranges;
|
||||||
|
|
||||||
|
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) {
|
||||||
|
+ log_error("Failed to create PV entry for missing device.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
pvname = pv_dev_name(pvl->pv);
|
||||||
|
if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
|
||||||
|
log_warn("WARNING: Physical volume %s not allocatable.", pvname);
|
||||||
|
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
|
||||||
|
index 85482552a..adc954bab 100644
|
||||||
|
--- a/lib/metadata/vg.c
|
||||||
|
+++ b/lib/metadata/vg.c
|
||||||
|
@@ -679,6 +679,11 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!pv->dev || dm_list_empty(&pv->dev->aliases)) {
|
||||||
|
+ log_error("No device found for PV.");
|
||||||
|
+ return r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv));
|
||||||
|
|
||||||
|
if (pv_pe_alloc_count(pv)) {
|
||||||
|
diff --git a/test/shell/losetup-partscan.sh b/test/shell/losetup-partscan.sh
|
||||||
|
index 99f552ad1..670568945 100644
|
||||||
|
--- a/test/shell/losetup-partscan.sh
|
||||||
|
+++ b/test/shell/losetup-partscan.sh
|
||||||
|
@@ -33,6 +33,8 @@ aux udev_wait
|
||||||
|
ls -la "${LOOP}"*
|
||||||
|
test -e "${LOOP}p1"
|
||||||
|
|
||||||
|
+aux lvmconf 'devices/scan = "/dev"'
|
||||||
|
+
|
||||||
|
aux extend_filter "a|$LOOP|"
|
||||||
|
aux extend_devices "$LOOP"
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,272 @@
|
|||||||
|
From 932b9720bb074e49ac920642b3fe9c3d84019787 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 28 Feb 2022 17:37:12 -0600
|
||||||
|
Subject: [PATCH 39/54] devices: use dev-cache aliases handling from label scan
|
||||||
|
functions
|
||||||
|
|
||||||
|
The label scan functions where doing some device alias validation
|
||||||
|
which is now better handled by the dev-cache layer, so just use
|
||||||
|
that.
|
||||||
|
---
|
||||||
|
lib/device/dev-cache.c | 4 +-
|
||||||
|
lib/device/dev-cache.h | 1 +
|
||||||
|
lib/label/label.c | 143 ++++++++++-------------------------------
|
||||||
|
3 files changed, 36 insertions(+), 112 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index 58e67e130..b0759b06c 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -1410,7 +1410,7 @@ static void _remove_alias(struct device *dev, const char *name)
|
||||||
|
* deactivated LV. Those old paths are all invalid and are dropped here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static void _verify_aliases(struct device *dev)
|
||||||
|
+void dev_cache_verify_aliases(struct device *dev)
|
||||||
|
{
|
||||||
|
struct dm_str_list *strl, *strl2;
|
||||||
|
struct stat st;
|
||||||
|
@@ -1459,7 +1459,7 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
|
||||||
|
_remove_alias(dev, name);
|
||||||
|
|
||||||
|
/* Remove any other names in dev->aliases that are incorrect. */
|
||||||
|
- _verify_aliases(dev);
|
||||||
|
+ dev_cache_verify_aliases(dev);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
|
||||||
|
index 51c3fc6c3..321a56d7b 100644
|
||||||
|
--- a/lib/device/dev-cache.h
|
||||||
|
+++ b/lib/device/dev-cache.h
|
||||||
|
@@ -55,6 +55,7 @@ int dev_cache_add_dir(const char *path);
|
||||||
|
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||||
|
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||||
|
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
|
||||||
|
+void dev_cache_verify_aliases(struct device *dev);
|
||||||
|
|
||||||
|
struct device *dev_hash_get(const char *name);
|
||||||
|
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index cf707f7a3..06958b502 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -458,7 +458,6 @@ static int _scan_dev_open(struct device *dev)
|
||||||
|
const char *name;
|
||||||
|
const char *modestr;
|
||||||
|
struct stat sbuf;
|
||||||
|
- int retried = 0;
|
||||||
|
int flags = 0;
|
||||||
|
int fd, di;
|
||||||
|
|
||||||
|
@@ -478,14 +477,23 @@ static int _scan_dev_open(struct device *dev)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ next_name:
|
||||||
|
/*
|
||||||
|
* All the names for this device (major:minor) are kept on
|
||||||
|
* dev->aliases, the first one is the primary/preferred name.
|
||||||
|
+ *
|
||||||
|
+ * The default name preferences in dev-cache mean that the first
|
||||||
|
+ * name in dev->aliases is not a symlink for scsi devices, but is
|
||||||
|
+ * the /dev/mapper/ symlink for mpath devices.
|
||||||
|
+ *
|
||||||
|
+ * If preferred names are set to symlinks, should this
|
||||||
|
+ * first attempt to open using a non-symlink?
|
||||||
|
+ *
|
||||||
|
+ * dm_list_first() returns NULL if the list is empty.
|
||||||
|
*/
|
||||||
|
if (!(name_list = dm_list_first(&dev->aliases))) {
|
||||||
|
- /* Shouldn't happen */
|
||||||
|
- log_error("Device open %s %d:%d has no path names.",
|
||||||
|
- dev_name(dev), (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||||
|
+ log_error("Device open %d:%d has no path names.",
|
||||||
|
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
name_sl = dm_list_item(name_list, struct dm_str_list);
|
||||||
|
@@ -513,50 +521,34 @@ static int _scan_dev_open(struct device *dev)
|
||||||
|
modestr = "ro";
|
||||||
|
}
|
||||||
|
|
||||||
|
-retry_open:
|
||||||
|
-
|
||||||
|
fd = open(name, flags, 0777);
|
||||||
|
-
|
||||||
|
if (fd < 0) {
|
||||||
|
if ((errno == EBUSY) && (flags & O_EXCL)) {
|
||||||
|
log_error("Can't open %s exclusively. Mounted filesystem?",
|
||||||
|
dev_name(dev));
|
||||||
|
+ return 0;
|
||||||
|
} else {
|
||||||
|
- int major, minor;
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
- * Shouldn't happen, if it does, print stat info to help figure
|
||||||
|
- * out what's wrong.
|
||||||
|
+ * drop name from dev->aliases and use verify_aliases to
|
||||||
|
+ * drop any other invalid aliases before retrying open with
|
||||||
|
+ * any remaining valid paths.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
- major = (int)MAJOR(dev->dev);
|
||||||
|
- minor = (int)MINOR(dev->dev);
|
||||||
|
-
|
||||||
|
- log_error("Device open %s %d:%d failed errno %d", name, major, minor, errno);
|
||||||
|
-
|
||||||
|
- if (stat(name, &sbuf)) {
|
||||||
|
- log_debug_devs("Device open %s %d:%d stat failed errno %d",
|
||||||
|
- name, major, minor, errno);
|
||||||
|
- } else if (sbuf.st_rdev != dev->dev) {
|
||||||
|
- log_debug_devs("Device open %s %d:%d stat %d:%d does not match.",
|
||||||
|
- name, major, minor,
|
||||||
|
- (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!retried) {
|
||||||
|
- /*
|
||||||
|
- * FIXME: remove this, the theory for this retry is that
|
||||||
|
- * there may be a udev race that we can sometimes mask by
|
||||||
|
- * retrying. This is here until we can figure out if it's
|
||||||
|
- * needed and if so fix the real problem.
|
||||||
|
- */
|
||||||
|
- usleep(5000);
|
||||||
|
- log_debug_devs("Device open %s retry", dev_name(dev));
|
||||||
|
- retried = 1;
|
||||||
|
- goto retry_open;
|
||||||
|
- }
|
||||||
|
+ log_debug("Drop alias for %d:%d failed open %s (%d)",
|
||||||
|
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), name, errno);
|
||||||
|
+ dev_cache_failed_path(dev, name);
|
||||||
|
+ dev_cache_verify_aliases(dev);
|
||||||
|
+ goto next_name;
|
||||||
|
}
|
||||||
|
- return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Verify that major:minor from the path still match dev. */
|
||||||
|
+ if ((fstat(fd, &sbuf) < 0) || (sbuf.st_rdev != dev->dev)) {
|
||||||
|
+ log_warn("Invalid path %s for device %d:%d, trying different path.",
|
||||||
|
+ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||||
|
+ (void)close(fd);
|
||||||
|
+ dev_cache_failed_path(dev, name);
|
||||||
|
+ dev_cache_verify_aliases(dev);
|
||||||
|
+ goto next_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->flags |= DEV_IN_BCACHE;
|
||||||
|
@@ -604,37 +596,6 @@ static int _scan_dev_close(struct device *dev)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void _drop_bad_aliases(struct device *dev)
|
||||||
|
-{
|
||||||
|
- struct dm_str_list *strl, *strl2;
|
||||||
|
- const char *name;
|
||||||
|
- struct stat sbuf;
|
||||||
|
- int major = (int)MAJOR(dev->dev);
|
||||||
|
- int minor = (int)MINOR(dev->dev);
|
||||||
|
- int bad;
|
||||||
|
-
|
||||||
|
- dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
|
||||||
|
- name = strl->str;
|
||||||
|
- bad = 0;
|
||||||
|
-
|
||||||
|
- if (stat(name, &sbuf)) {
|
||||||
|
- bad = 1;
|
||||||
|
- log_debug_devs("Device path check %d:%d %s stat failed errno %d",
|
||||||
|
- major, minor, name, errno);
|
||||||
|
- } else if (sbuf.st_rdev != dev->dev) {
|
||||||
|
- bad = 1;
|
||||||
|
- log_debug_devs("Device path check %d:%d %s stat %d:%d does not match.",
|
||||||
|
- major, minor, name,
|
||||||
|
- (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (bad) {
|
||||||
|
- log_debug_devs("Device path check %d:%d dropping path %s.", major, minor, name);
|
||||||
|
- dev_cache_failed_path(dev, name);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
// Like bcache_invalidate, only it throws any dirty data away if the
|
||||||
|
// write fails.
|
||||||
|
static void _invalidate_di(struct bcache *cache, int di)
|
||||||
|
@@ -662,10 +623,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
char headers_buf[HEADERS_BUF_SIZE];
|
||||||
|
struct dm_list wait_devs;
|
||||||
|
struct dm_list done_devs;
|
||||||
|
- struct dm_list reopen_devs;
|
||||||
|
struct device_list *devl, *devl2;
|
||||||
|
struct block *bb;
|
||||||
|
- int retried_open = 0;
|
||||||
|
int scan_read_errors = 0;
|
||||||
|
int scan_process_errors = 0;
|
||||||
|
int scan_failed_count = 0;
|
||||||
|
@@ -676,7 +635,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
|
||||||
|
dm_list_init(&wait_devs);
|
||||||
|
dm_list_init(&done_devs);
|
||||||
|
- dm_list_init(&reopen_devs);
|
||||||
|
|
||||||
|
log_debug_devs("Scanning %d devices for VG info", dm_list_size(devs));
|
||||||
|
|
||||||
|
@@ -700,9 +658,9 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
|
||||||
|
if (!_in_bcache(devl->dev)) {
|
||||||
|
if (!_scan_dev_open(devl->dev)) {
|
||||||
|
- log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
|
||||||
|
+ log_debug_devs("Scan failed to open %d:%d %s.",
|
||||||
|
+ (int)MAJOR(devl->dev->dev), (int)MINOR(devl->dev->dev), dev_name(devl->dev));
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
- dm_list_add(&reopen_devs, &devl->list);
|
||||||
|
devl->dev->flags |= DEV_SCAN_NOT_READ;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@@ -786,41 +744,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||||
|
if (!dm_list_empty(devs))
|
||||||
|
goto scan_more;
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * We're done scanning all the devs. If we failed to open any of them
|
||||||
|
- * the first time through, refresh device paths and retry. We failed
|
||||||
|
- * to open the devs on the reopen_devs list.
|
||||||
|
- *
|
||||||
|
- * FIXME: it's not clear if or why this helps.
|
||||||
|
- */
|
||||||
|
- if (!dm_list_empty(&reopen_devs)) {
|
||||||
|
- if (retried_open) {
|
||||||
|
- /* Don't try again. */
|
||||||
|
- scan_failed_count += dm_list_size(&reopen_devs);
|
||||||
|
- dm_list_splice(&done_devs, &reopen_devs);
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
- retried_open = 1;
|
||||||
|
-
|
||||||
|
- dm_list_iterate_items_safe(devl, devl2, &reopen_devs) {
|
||||||
|
- _drop_bad_aliases(devl->dev);
|
||||||
|
-
|
||||||
|
- if (dm_list_empty(&devl->dev->aliases)) {
|
||||||
|
- log_warn("WARNING: Scan ignoring device %d:%d with no paths.",
|
||||||
|
- (int)MAJOR(devl->dev->dev),
|
||||||
|
- (int)MINOR(devl->dev->dev));
|
||||||
|
-
|
||||||
|
- dm_list_del(&devl->list);
|
||||||
|
- lvmcache_del_dev(devl->dev);
|
||||||
|
- scan_failed_count++;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Put devs that failed to open back on the original list to retry. */
|
||||||
|
- dm_list_splice(devs, &reopen_devs);
|
||||||
|
- goto scan_more;
|
||||||
|
- }
|
||||||
|
-out:
|
||||||
|
log_debug_devs("Scanned devices: read errors %d process errors %d failed %d",
|
||||||
|
scan_read_errors, scan_process_errors, scan_failed_count);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
101
SOURCES/0040-writecache-check-memory-usage.patch
Normal file
101
SOURCES/0040-writecache-check-memory-usage.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From 10a598075a0fdf6d93cc2fefa73fc4a5f1d0de48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 1 Mar 2022 14:31:39 -0600
|
||||||
|
Subject: [PATCH 40/54] writecache: check memory usage
|
||||||
|
|
||||||
|
warn if writecache neds > 50% of system memory, and
|
||||||
|
confirm if writecache needs > 90% of system memory.
|
||||||
|
---
|
||||||
|
tools/lvconvert.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 69 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index 34b82ea02..a90946173 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -6072,6 +6072,69 @@ bad:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _check_writecache_memory(struct cmd_context *cmd, struct logical_volume *lv_fast,
|
||||||
|
+ uint32_t block_size_sectors)
|
||||||
|
+{
|
||||||
|
+ char line[128];
|
||||||
|
+ FILE *fp;
|
||||||
|
+ uint64_t cachevol_size_bytes = lv_fast->size * SECTOR_SIZE;
|
||||||
|
+ uint64_t need_mem_bytes = 0;
|
||||||
|
+ uint64_t proc_mem_bytes = 0;
|
||||||
|
+ uint64_t need_mem_gb;
|
||||||
|
+ uint64_t proc_mem_gb;
|
||||||
|
+ unsigned long long proc_mem_kb = 0;
|
||||||
|
+
|
||||||
|
+ if (!(fp = fopen("/proc/meminfo", "r")))
|
||||||
|
+ goto skip_proc;
|
||||||
|
+
|
||||||
|
+ while (fgets(line, sizeof(line), fp)) {
|
||||||
|
+ if (strncmp(line, "MemTotal:", 9))
|
||||||
|
+ continue;
|
||||||
|
+ if (sscanf(line, "%*s%llu%*s", &proc_mem_kb) != 1)
|
||||||
|
+ break;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ (void)fclose(fp);
|
||||||
|
+
|
||||||
|
+ proc_mem_bytes = proc_mem_kb * 1024;
|
||||||
|
+
|
||||||
|
+ skip_proc:
|
||||||
|
+ /* dm-writecache memory consumption per block is 88 bytes */
|
||||||
|
+ if (block_size_sectors == 8) {
|
||||||
|
+ need_mem_bytes = cachevol_size_bytes * 88 / 4096;
|
||||||
|
+ } else if (block_size_sectors == 1) {
|
||||||
|
+ need_mem_bytes = cachevol_size_bytes * 88 / 512;
|
||||||
|
+ } else {
|
||||||
|
+ /* shouldn't happen */
|
||||||
|
+ log_warn("Unknown memory usage for unknown writecache block_size_sectors %u", block_size_sectors);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ need_mem_gb = need_mem_bytes / 1073741824;
|
||||||
|
+ proc_mem_gb = proc_mem_bytes / 1073741824;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * warn if writecache needs > 50% of main memory, and
|
||||||
|
+ * confirm if writecache needs > 90% of main memory.
|
||||||
|
+ */
|
||||||
|
+ if (need_mem_bytes >= (proc_mem_bytes / 2)) {
|
||||||
|
+ log_warn("WARNING: writecache size %s will use %llu GiB of system memory (%llu GiB).",
|
||||||
|
+ display_size(cmd, lv_fast->size),
|
||||||
|
+ (unsigned long long)need_mem_gb,
|
||||||
|
+ (unsigned long long)proc_mem_gb);
|
||||||
|
+
|
||||||
|
+ if (need_mem_gb >= (proc_mem_gb * 9 / 10)) {
|
||||||
|
+ if (!arg_is_set(cmd, yes_ARG) &&
|
||||||
|
+ yes_no_prompt("Continue adding writecache? [y/n]: ") == 'n') {
|
||||||
|
+ log_error("Conversion aborted.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int lvconvert_writecache_attach_single(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv,
|
||||||
|
struct processing_handle *handle)
|
||||||
|
@@ -6160,6 +6223,12 @@ int lvconvert_writecache_attach_single(struct cmd_context *cmd,
|
||||||
|
goto_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!_check_writecache_memory(cmd, lv_fast, block_size_sectors)) {
|
||||||
|
+ if (!is_active && !deactivate_lv(cmd, lv))
|
||||||
|
+ stack;
|
||||||
|
+ goto_bad;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!is_active) {
|
||||||
|
if (!deactivate_lv(cmd, lv)) {
|
||||||
|
log_error("Failed to deactivate LV after checking block size %s", display_lvname(lv));
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
108
SOURCES/0041-change-messages-about-filtered-devices.patch
Normal file
108
SOURCES/0041-change-messages-about-filtered-devices.patch
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
From 090dc0c320f0abee8ab79f4eaea6561c195b5009 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 31 Mar 2022 11:38:08 -0500
|
||||||
|
Subject: [PATCH 41/54] change messages about filtered devices
|
||||||
|
|
||||||
|
Change messages that refer to devices being "excluded by filters"
|
||||||
|
to say just "excluded". This will avoid mistaking the word
|
||||||
|
"filters" with the lvm.conf filter setting.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 6 +++---
|
||||||
|
tools/lvmdevices.c | 4 ++--
|
||||||
|
tools/pvscan.c | 4 ++--
|
||||||
|
tools/vgimportclone.c | 4 ++--
|
||||||
|
4 files changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 82db6e4a5..6133e700a 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1744,7 +1744,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||||
|
* probably wants to do something about it.
|
||||||
|
*/
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
|
||||||
|
- log_warn("Devices file %s is excluded by filter: %s.",
|
||||||
|
+ log_warn("Devices file %s is excluded: %s.",
|
||||||
|
dev_name(dev), dev_filtered_reason(dev));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@@ -1830,7 +1830,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
|
||||||
|
- log_warn("Devices file %s is excluded by filter: %s.",
|
||||||
|
+ log_warn("Devices file %s is excluded: %s.",
|
||||||
|
dev_name(dev), dev_filtered_reason(dev));
|
||||||
|
/* FIXME: what if this dev is wrongly matched and should be checked below? */
|
||||||
|
continue;
|
||||||
|
@@ -2266,7 +2266,7 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
|
||||||
|
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
|
||||||
|
/* I don't think this would happen */
|
||||||
|
- log_warn("WARNING: new device %s for PVID %s does not pass filter %s.",
|
||||||
|
+ log_warn("WARNING: new device %s for PVID %s is excluded: %s.",
|
||||||
|
dev_name(dev), dil->pvid, dev_filtered_reason(dev));
|
||||||
|
if (du) /* Should not happen 'du' is NULL */
|
||||||
|
du->dev = NULL;
|
||||||
|
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||||
|
index 662b35f9a..8521b89ea 100644
|
||||||
|
--- a/tools/lvmdevices.c
|
||||||
|
+++ b/tools/lvmdevices.c
|
||||||
|
@@ -112,7 +112,7 @@ static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *sear
|
||||||
|
dev = devl->dev;
|
||||||
|
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
|
||||||
|
- log_warn("WARNING: PVID %s found on %s which is excluded by filter: %s",
|
||||||
|
+ log_warn("WARNING: PVID %s found on %s which is excluded: %s",
|
||||||
|
dev->pvid, dev_name(dev), dev_filtered_reason(dev));
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
}
|
||||||
|
@@ -310,7 +310,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
cmd->filter_deviceid_skip = 1;
|
||||||
|
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
|
||||||
|
- log_warn("WARNING: adding device %s that is excluded by filter: %s.",
|
||||||
|
+ log_warn("WARNING: adding device %s that is excluded: %s.",
|
||||||
|
dev_name(dev), dev_filtered_reason(dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index 160a2c9a0..50d46051a 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -1756,7 +1756,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
|
||||||
|
dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) {
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
||||||
|
- log_print_pvscan(cmd, "%s excluded by filters: %s.",
|
||||||
|
+ log_print_pvscan(cmd, "%s excluded: %s.",
|
||||||
|
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
}
|
||||||
|
@@ -1813,7 +1813,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
|
||||||
|
/* Applies all filters, including those that need data from dev. */
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
||||||
|
- log_print_pvscan(cmd, "%s excluded by filters: %s.",
|
||||||
|
+ log_print_pvscan(cmd, "%s excluded: %s.",
|
||||||
|
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||||
|
dm_list_del(&devl->list);
|
||||||
|
}
|
||||||
|
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
|
||||||
|
index 23bb6271f..cab501619 100644
|
||||||
|
--- a/tools/vgimportclone.c
|
||||||
|
+++ b/tools/vgimportclone.c
|
||||||
|
@@ -311,8 +311,8 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
*/
|
||||||
|
dm_list_iterate_items(devl, &vp.new_devs) {
|
||||||
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, "persistent")) {
|
||||||
|
- /* FIXME: print which filter */
|
||||||
|
- log_error("Device %s was excluded by filters.", dev_name(devl->dev));
|
||||||
|
+ log_error("Device %s is excluded: %s.",
|
||||||
|
+ dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 4aa92f3e18cb49470ee9b5d928abe6b4c86f3074 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 6 Apr 2022 12:20:26 -0500
|
||||||
|
Subject: [PATCH 42/54] vgimportdevices: fix incorrect deviceidtype usage
|
||||||
|
|
||||||
|
When a VG has PVs with different device id types,
|
||||||
|
it would try to use the idtype of the previous PV
|
||||||
|
in the loop. This would produce an unncessary warning,
|
||||||
|
or could lead to using the devname idtype when a better
|
||||||
|
idtype is available.
|
||||||
|
---
|
||||||
|
tools/vgimportdevices.c | 3 +--
|
||||||
|
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
||||||
|
index 2580613c4..ea205d941 100644
|
||||||
|
--- a/tools/vgimportdevices.c
|
||||||
|
+++ b/tools/vgimportdevices.c
|
||||||
|
@@ -57,8 +57,7 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
||||||
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
|
pv = pvl->pv;
|
||||||
|
|
||||||
|
- if (!idtypestr && pv->device_id_type)
|
||||||
|
- idtypestr = pv->device_id_type;
|
||||||
|
+ idtypestr = pv->device_id_type;
|
||||||
|
|
||||||
|
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
|
||||||
|
device_id_add(cmd, pv->dev, pvid, idtypestr, NULL);
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 6de2a6a378a7673168fad34aebe8ddcb564a5911 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 8 Apr 2022 11:28:53 -0500
|
||||||
|
Subject: [PATCH 43/54] lvmlockd: return error from vgcreate init_vg_sanlock
|
||||||
|
|
||||||
|
in vgcreate for shared sanlock vg, if sanlock_write_resource
|
||||||
|
returns an unexpected error, then make init_vg_sanlock fail
|
||||||
|
which will cause the vgcreate to fail.
|
||||||
|
---
|
||||||
|
daemons/lvmlockd/lvmlockd-sanlock.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||||
|
index e595eeffd..d87d1093b 100644
|
||||||
|
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||||
|
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||||
|
@@ -684,10 +684,10 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (rv) {
|
||||||
|
+ if (rv < 0) {
|
||||||
|
log_error("clear lv resource area %llu error %d",
|
||||||
|
(unsigned long long)offset, rv);
|
||||||
|
- break;
|
||||||
|
+ return rv;
|
||||||
|
}
|
||||||
|
offset += align_size;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From d96432835532fbcd8c72694c6ed68fca3ce98d5c Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 13 Apr 2022 12:16:57 -0500
|
||||||
|
Subject: [PATCH 44/54] devices file: remove extraneous unlock in vgchange -u
|
||||||
|
|
||||||
|
vgchange -u exit path was unlocking the devices file in cases
|
||||||
|
when it wasn't needed, which produced an warning.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 7 +++----
|
||||||
|
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 6133e700a..20901ab90 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1272,15 +1272,15 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
int update = 0;
|
||||||
|
|
||||||
|
if (!cmd->enable_devices_file)
|
||||||
|
- goto out;
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
/* Without this setting there is no stacking LVs on PVs. */
|
||||||
|
if (!cmd->scan_lvs)
|
||||||
|
- goto out;
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
/* Check if any devices file entries are stacked on LVs. */
|
||||||
|
if (!_device_ids_use_lvmlv(cmd))
|
||||||
|
- goto out;
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
memcpy(old_vgid, old_vg_id, ID_LEN);
|
||||||
|
memcpy(new_vgid, &vg->id, ID_LEN);
|
||||||
|
@@ -1310,7 +1310,6 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
if (update &&
|
||||||
|
!device_ids_write(cmd))
|
||||||
|
stack;
|
||||||
|
- out:
|
||||||
|
unlock_devices_file(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
458
SOURCES/0045-filter-mpath-use-multipath-blacklist.patch
Normal file
458
SOURCES/0045-filter-mpath-use-multipath-blacklist.patch
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
From 5d40b91bd4aa8580ee1f40d467b848f7847f39e3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 21 Apr 2022 13:45:01 -0500
|
||||||
|
Subject: [PATCH 45/54] filter-mpath: use multipath blacklist
|
||||||
|
|
||||||
|
Explicit wwid's from these sections control whether the
|
||||||
|
same wwid in /etc/multipath/wwids is recognized as a
|
||||||
|
multipath component. Other non-wwid keywords are not
|
||||||
|
used, and may require disabling the use of the multipath
|
||||||
|
wwids file in lvm.conf.
|
||||||
|
---
|
||||||
|
lib/device/dev-mpath.c | 181 ++++++++++++++++++++++++--
|
||||||
|
test/shell/duplicate-pvs-multipath.sh | 2 +-
|
||||||
|
test/shell/multipath-config.sh | 171 ++++++++++++++++++++++++
|
||||||
|
3 files changed, 342 insertions(+), 12 deletions(-)
|
||||||
|
create mode 100644 test/shell/multipath-config.sh
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
|
||||||
|
index cbbad9dc9..6eed03c5b 100644
|
||||||
|
--- a/lib/device/dev-mpath.c
|
||||||
|
+++ b/lib/device/dev-mpath.c
|
||||||
|
@@ -17,12 +17,14 @@
|
||||||
|
#include "lib/activate/activate.h"
|
||||||
|
#include "lib/commands/toolcontext.h"
|
||||||
|
#include "lib/device/device_id.h"
|
||||||
|
+#include "lib/datastruct/str_list.h"
|
||||||
|
#ifdef UDEV_SYNC_SUPPORT
|
||||||
|
#include <libudev.h>
|
||||||
|
#include "lib/device/dev-ext-udev-constants.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
|
||||||
|
#define MPATH_PREFIX "mpath-"
|
||||||
|
|
||||||
|
@@ -35,15 +37,167 @@
|
||||||
|
* If dm-3 is not an mpath device, then the constant "1" is stored in
|
||||||
|
* the hash table with the key of the dm minor number.
|
||||||
|
*/
|
||||||
|
-static struct dm_pool *_hash_mem;
|
||||||
|
+static struct dm_pool *_wwid_mem;
|
||||||
|
static struct dm_hash_table *_minor_hash_tab;
|
||||||
|
static struct dm_hash_table *_wwid_hash_tab;
|
||||||
|
+static struct dm_list _ignored;
|
||||||
|
+static struct dm_list _ignored_exceptions;
|
||||||
|
|
||||||
|
#define MAX_WWID_LINE 512
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * do we need to check the multipath.conf blacklist?
|
||||||
|
- */
|
||||||
|
+static void _read_blacklist_file(const char *path)
|
||||||
|
+{
|
||||||
|
+ FILE *fp;
|
||||||
|
+ char line[MAX_WWID_LINE];
|
||||||
|
+ char wwid[MAX_WWID_LINE];
|
||||||
|
+ char *word, *p;
|
||||||
|
+ int section_black = 0;
|
||||||
|
+ int section_exceptions = 0;
|
||||||
|
+ int found_quote;
|
||||||
|
+ int found_three;
|
||||||
|
+ int i, j;
|
||||||
|
+
|
||||||
|
+ if (!(fp = fopen(path, "r")))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ while (fgets(line, sizeof(line), fp)) {
|
||||||
|
+ word = NULL;
|
||||||
|
+
|
||||||
|
+ /* skip initial white space on the line */
|
||||||
|
+ for (i = 0; i < MAX_WWID_LINE; i++) {
|
||||||
|
+ if ((line[i] == '\n') || (line[i] == '\0'))
|
||||||
|
+ break;
|
||||||
|
+ if (isspace(line[i]))
|
||||||
|
+ continue;
|
||||||
|
+ word = &line[i];
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!word || word[0] == '#')
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ /* identify the start of the section we want to read */
|
||||||
|
+ if (strchr(word, '{')) {
|
||||||
|
+ if (!strncmp(word, "blacklist_exceptions", 20))
|
||||||
|
+ section_exceptions = 1;
|
||||||
|
+ else if (!strncmp(word, "blacklist", 9))
|
||||||
|
+ section_black = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ /* identify the end of the section we've been reading */
|
||||||
|
+ if (strchr(word, '}')) {
|
||||||
|
+ section_exceptions = 0;
|
||||||
|
+ section_black = 0;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ /* skip lines that are not in a section we want */
|
||||||
|
+ if (!section_black && !section_exceptions)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * read a wwid from the blacklist{_exceptions} section.
|
||||||
|
+ * does not recognize other non-wwid entries in the
|
||||||
|
+ * section, and skips those (should the entire mp
|
||||||
|
+ * config filtering be disabled if non-wwids are seen?
|
||||||
|
+ */
|
||||||
|
+ if (!(p = strstr(word, "wwid")))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ i += 4; /* skip "wwid" */
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * copy wwid value from the line.
|
||||||
|
+ * the wwids copied here need to match the
|
||||||
|
+ * wwids read from /etc/multipath/wwids,
|
||||||
|
+ * which are matched to wwids from sysfs.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ memset(wwid, 0, sizeof(wwid));
|
||||||
|
+ found_quote = 0;
|
||||||
|
+ found_three = 0;
|
||||||
|
+ j = 0;
|
||||||
|
+
|
||||||
|
+ for (; i < MAX_WWID_LINE; i++) {
|
||||||
|
+ if ((line[i] == '\n') || (line[i] == '\0'))
|
||||||
|
+ break;
|
||||||
|
+ if (!j && isspace(line[i]))
|
||||||
|
+ continue;
|
||||||
|
+ if (isspace(line[i]))
|
||||||
|
+ break;
|
||||||
|
+ /* quotes around wwid are optional */
|
||||||
|
+ if ((line[i] == '"') && !found_quote) {
|
||||||
|
+ found_quote = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ /* second quote is end of wwid */
|
||||||
|
+ if ((line[i] == '"') && found_quote)
|
||||||
|
+ break;
|
||||||
|
+ /* ignore first "3" in wwid */
|
||||||
|
+ if ((line[i] == '3') && !found_three) {
|
||||||
|
+ found_three = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ wwid[j] = line[i];
|
||||||
|
+ j++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (j < 8)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ log_debug("multipath wwid %s in %s %s",
|
||||||
|
+ wwid, section_exceptions ? "blacklist_exceptions" : "blacklist", path);
|
||||||
|
+
|
||||||
|
+ if (section_exceptions) {
|
||||||
|
+ if (!str_list_add(_wwid_mem, &_ignored_exceptions, dm_pool_strdup(_wwid_mem, wwid)))
|
||||||
|
+ stack;
|
||||||
|
+ } else {
|
||||||
|
+ if (!str_list_add(_wwid_mem, &_ignored, dm_pool_strdup(_wwid_mem, wwid)))
|
||||||
|
+ stack;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (fclose(fp))
|
||||||
|
+ stack;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _read_wwid_exclusions(void)
|
||||||
|
+{
|
||||||
|
+ char path[PATH_MAX] = { 0 };
|
||||||
|
+ DIR *dir;
|
||||||
|
+ struct dirent *de;
|
||||||
|
+ struct dm_str_list *sl, *sl2;
|
||||||
|
+ int rem_count = 0;
|
||||||
|
+
|
||||||
|
+ _read_blacklist_file("/etc/multipath.conf");
|
||||||
|
+
|
||||||
|
+ if ((dir = opendir("/etc/multipath/conf.d"))) {
|
||||||
|
+ while ((de = readdir(dir))) {
|
||||||
|
+ if (de->d_name[0] == '.')
|
||||||
|
+ continue;
|
||||||
|
+ snprintf(path, PATH_MAX-1, "/etc/multipath/conf.d/%s", de->d_name);
|
||||||
|
+ _read_blacklist_file(path);
|
||||||
|
+ }
|
||||||
|
+ closedir(dir);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* for each wwid in ignored_exceptions, remove it from ignored */
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items_safe(sl, sl2, &_ignored) {
|
||||||
|
+ if (str_list_match_item(&_ignored_exceptions, sl->str))
|
||||||
|
+ str_list_del(&_ignored, sl->str);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* for each wwid in ignored, remove it from wwid_hash */
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items(sl, &_ignored) {
|
||||||
|
+ dm_hash_remove_binary(_wwid_hash_tab, sl->str, strlen(sl->str));
|
||||||
|
+ rem_count++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (rem_count)
|
||||||
|
+ log_debug("multipath config ignored %d wwids", rem_count);
|
||||||
|
+}
|
||||||
|
|
||||||
|
static void _read_wwid_file(const char *config_wwids_file)
|
||||||
|
{
|
||||||
|
@@ -93,6 +247,9 @@ int dev_mpath_init(const char *config_wwids_file)
|
||||||
|
struct dm_hash_table *minor_tab;
|
||||||
|
struct dm_hash_table *wwid_tab;
|
||||||
|
|
||||||
|
+ dm_list_init(&_ignored);
|
||||||
|
+ dm_list_init(&_ignored_exceptions);
|
||||||
|
+
|
||||||
|
if (!(mem = dm_pool_create("mpath", 256))) {
|
||||||
|
log_error("mpath pool creation failed.");
|
||||||
|
return 0;
|
||||||
|
@@ -104,7 +261,7 @@ int dev_mpath_init(const char *config_wwids_file)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- _hash_mem = mem;
|
||||||
|
+ _wwid_mem = mem;
|
||||||
|
_minor_hash_tab = minor_tab;
|
||||||
|
|
||||||
|
/* multipath_wwids_file="" disables the use of the file */
|
||||||
|
@@ -116,16 +273,18 @@ int dev_mpath_init(const char *config_wwids_file)
|
||||||
|
if (!(wwid_tab = dm_hash_create(110))) {
|
||||||
|
log_error("mpath hash table creation failed.");
|
||||||
|
dm_hash_destroy(_minor_hash_tab);
|
||||||
|
- dm_pool_destroy(_hash_mem);
|
||||||
|
+ dm_pool_destroy(_wwid_mem);
|
||||||
|
_minor_hash_tab = NULL;
|
||||||
|
- _hash_mem = NULL;
|
||||||
|
+ _wwid_mem = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_wwid_hash_tab = wwid_tab;
|
||||||
|
|
||||||
|
- if (config_wwids_file)
|
||||||
|
+ if (config_wwids_file) {
|
||||||
|
_read_wwid_file(config_wwids_file);
|
||||||
|
+ _read_wwid_exclusions();
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -136,12 +295,12 @@ void dev_mpath_exit(void)
|
||||||
|
dm_hash_destroy(_minor_hash_tab);
|
||||||
|
if (_wwid_hash_tab)
|
||||||
|
dm_hash_destroy(_wwid_hash_tab);
|
||||||
|
- if (_hash_mem)
|
||||||
|
- dm_pool_destroy(_hash_mem);
|
||||||
|
+ if (_wwid_mem)
|
||||||
|
+ dm_pool_destroy(_wwid_mem);
|
||||||
|
|
||||||
|
_minor_hash_tab = NULL;
|
||||||
|
_wwid_hash_tab = NULL;
|
||||||
|
- _hash_mem = NULL;
|
||||||
|
+ _wwid_mem = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
index a145e4afb..59c15b0d4 100644
|
||||||
|
--- a/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
+++ b/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
@@ -10,7 +10,7 @@
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-test_description='udev rule and systemd unit run vgchange'
|
||||||
|
+test_description='duplicate pv detection of mpath components using wwid'
|
||||||
|
|
||||||
|
SKIP_WITH_LVMPOLLD=1
|
||||||
|
SKIP_WITH_LVMLOCKD=1
|
||||||
|
diff --git a/test/shell/multipath-config.sh b/test/shell/multipath-config.sh
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..ffb7d632a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/shell/multipath-config.sh
|
||||||
|
@@ -0,0 +1,171 @@
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+
|
||||||
|
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+# of the GNU General Public License v.2.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
+
|
||||||
|
+test_description='using multipath blacklist'
|
||||||
|
+
|
||||||
|
+SKIP_WITH_LVMPOLLD=1
|
||||||
|
+SKIP_WITH_LVMLOCKD=1
|
||||||
|
+
|
||||||
|
+. lib/inittest
|
||||||
|
+
|
||||||
|
+# FIXME: don't run this test by default because it destroys the
|
||||||
|
+# local multipath config, the timing of multipath/dm/lvm interactions
|
||||||
|
+# is fragile, and there's insufficient cleanup after a test fails.
|
||||||
|
+skip
|
||||||
|
+
|
||||||
|
+systemctl stop multipathd
|
||||||
|
+multipath -F || true
|
||||||
|
+rm /etc/multipath/wwids || true
|
||||||
|
+rmmod scsi_debug || true
|
||||||
|
+rm /etc/multipath/conf.d/lvmtest.conf || true
|
||||||
|
+
|
||||||
|
+modprobe --dry-run scsi_debug || skip
|
||||||
|
+multipath -l || skip
|
||||||
|
+multipath -l | grep scsi_debug && skip
|
||||||
|
+ls /etc/multipath/wwids && skip
|
||||||
|
+
|
||||||
|
+# Need to use /dev/mapper/mpath
|
||||||
|
+aux lvmconf 'devices/dir = "/dev"'
|
||||||
|
+aux lvmconf 'devices/scan = "/dev"'
|
||||||
|
+# Could set filter to $MP and the component /dev/sd devs
|
||||||
|
+aux lvmconf "devices/filter = [ \"a|.*|\" ]"
|
||||||
|
+aux lvmconf "devices/global_filter = [ \"a|.*|\" ]"
|
||||||
|
+
|
||||||
|
+modprobe scsi_debug dev_size_mb=16 num_tgts=1
|
||||||
|
+sleep 2
|
||||||
|
+
|
||||||
|
+# Get scsi device name created by scsi_debug.
|
||||||
|
+# SD = sdh
|
||||||
|
+# SD_DEV = /dev/sdh
|
||||||
|
+
|
||||||
|
+SD=$(grep -H scsi_debug /sys/block/sd*/device/model | cut -f4 -d /);
|
||||||
|
+echo $SD
|
||||||
|
+SD_DEV=/dev/$SD
|
||||||
|
+echo $SD_DEV
|
||||||
|
+
|
||||||
|
+# if multipath claimed SD, then io will fail
|
||||||
|
+#dd if=$SD_DEV of=/dev/null bs=4k count=1 iflag=direct
|
||||||
|
+#dd if=/dev/zero of=$SD_DEV bs=4k count=1 oflag=direct
|
||||||
|
+
|
||||||
|
+# check if multipathd claimed the scsi dev when it appears and create mp dm device
|
||||||
|
+sleep 2
|
||||||
|
+multipath -l
|
||||||
|
+# create the mp dm device
|
||||||
|
+multipath $SD_DEV
|
||||||
|
+
|
||||||
|
+# Get mpath device name created by multipath.
|
||||||
|
+# MP = mpatha
|
||||||
|
+# MP_DEV = /dev/maper/mpatha
|
||||||
|
+
|
||||||
|
+MP=$(multipath -l | grep scsi_debug | cut -f1 -d ' ')
|
||||||
|
+echo $MP
|
||||||
|
+MP_DEV=/dev/mapper/$MP
|
||||||
|
+echo $MP_DEV
|
||||||
|
+
|
||||||
|
+dd if=$MP_DEV of=/dev/null bs=4k count=1 iflag=direct
|
||||||
|
+dd if=/dev/zero of=$MP_DEV bs=4k count=1 oflag=direct
|
||||||
|
+
|
||||||
|
+# Get wwid for the mp and sd dev.
|
||||||
|
+WWID=$(multipath -l $MP_DEV | head -1 | awk '{print $2}' | tr -d ')' | tr -d '(')
|
||||||
|
+echo $WWID
|
||||||
|
+
|
||||||
|
+grep $WWID /etc/multipath/wwids
|
||||||
|
+
|
||||||
|
+pvcreate $MP_DEV
|
||||||
|
+vgcreate $vg1 $MP_DEV
|
||||||
|
+
|
||||||
|
+not pvs $SD_DEV
|
||||||
|
+pvs $MP_DEV
|
||||||
|
+
|
||||||
|
+# remove mpath dm device then check that SD_DEV is
|
||||||
|
+# filtered based on /etc/multipath/wwids instead of
|
||||||
|
+# based on sysfs holder
|
||||||
|
+multipath -f $MP
|
||||||
|
+sleep 2
|
||||||
|
+not pvs $SD_DEV
|
||||||
|
+multipath $SD_DEV
|
||||||
|
+sleep 2
|
||||||
|
+multipath -l | grep $SD
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Add the wwid to the blacklist, then restart multipath
|
||||||
|
+# so the sd dev should no longer be used by multipath,
|
||||||
|
+# but the sd dev wwid is still in /etc/multipath/wwids.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+mkdir /etc/multipath/conf.d/ || true
|
||||||
|
+rm -f /etc/multipath/conf.d/lvmtest.conf
|
||||||
|
+
|
||||||
|
+cat <<EOF > "/etc/multipath/conf.d/lvmtest.conf"
|
||||||
|
+blacklist {
|
||||||
|
+ wwid $WWID
|
||||||
|
+}
|
||||||
|
+EOF
|
||||||
|
+
|
||||||
|
+cat /etc/multipath/conf.d/lvmtest.conf
|
||||||
|
+
|
||||||
|
+multipath -r
|
||||||
|
+sleep 2
|
||||||
|
+
|
||||||
|
+grep $WWID /etc/multipath/wwids
|
||||||
|
+
|
||||||
|
+multipath -l |tee out
|
||||||
|
+not grep $SD out
|
||||||
|
+not grep $MP out
|
||||||
|
+not grep $WWID out
|
||||||
|
+
|
||||||
|
+not pvs $MP_DEV
|
||||||
|
+pvs $SD_DEV
|
||||||
|
+vgs $vg1
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Add the wwid to the blacklist_exceptions, in addition
|
||||||
|
+# to the blacklist, then restart multipath so the
|
||||||
|
+# sd dev should again be used by multipath.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+rm -f /etc/multipath/conf.d/lvmtest.conf
|
||||||
|
+
|
||||||
|
+cat <<EOF > "/etc/multipath/conf.d/lvmtest.conf"
|
||||||
|
+blacklist {
|
||||||
|
+wwid $WWID
|
||||||
|
+}
|
||||||
|
+blacklist_exceptions {
|
||||||
|
+wwid $WWID
|
||||||
|
+}
|
||||||
|
+EOF
|
||||||
|
+
|
||||||
|
+cat /etc/multipath/conf.d/lvmtest.conf
|
||||||
|
+
|
||||||
|
+multipath -r
|
||||||
|
+sleep 2
|
||||||
|
+
|
||||||
|
+grep $WWID /etc/multipath/wwids
|
||||||
|
+
|
||||||
|
+multipath -l |tee out
|
||||||
|
+grep $SD out
|
||||||
|
+grep $MP out
|
||||||
|
+grep $WWID out
|
||||||
|
+
|
||||||
|
+pvs $MP_DEV
|
||||||
|
+not pvs $SD_DEV
|
||||||
|
+vgs $vg1
|
||||||
|
+lvs $vg1
|
||||||
|
+
|
||||||
|
+sleep 2
|
||||||
|
+vgremove -ff $vg1
|
||||||
|
+sleep 2
|
||||||
|
+multipath -f $MP
|
||||||
|
+rm /etc/multipath/conf.d/lvmtest.conf
|
||||||
|
+rm /etc/multipath/wwids
|
||||||
|
+sleep 1
|
||||||
|
+rmmod scsi_debug
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
28
SOURCES/0046-improve-description-of-devices-option.patch
Normal file
28
SOURCES/0046-improve-description-of-devices-option.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From e027f4da9bc7b4ed9b225af75089e3443595bf81 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 2 May 2022 09:46:28 -0500
|
||||||
|
Subject: [PATCH 46/54] improve description of devices option
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/args.h | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/args.h b/tools/args.h
|
||||||
|
index 9a7bf81b2..00a2ec817 100644
|
||||||
|
--- a/tools/args.h
|
||||||
|
+++ b/tools/args.h
|
||||||
|
@@ -235,8 +235,9 @@ arg(deviceidtype_ARG, '\0', "deviceidtype", string_VAL, 0, 0,
|
||||||
|
"then it will override the default type that lvm would use.\n")
|
||||||
|
|
||||||
|
arg(devices_ARG, '\0', "devices", pv_VAL, ARG_GROUPABLE, 0,
|
||||||
|
- "Devices that the command can use. This option can be repeated\n"
|
||||||
|
- "or accepts a comma separated list of devices. This overrides\n"
|
||||||
|
+ "Restricts the devices that are visible and accessible to the command.\n"
|
||||||
|
+ "Devices not listed will appear to be missing. This option can be\n"
|
||||||
|
+ "repeated, or accepts a comma separated list of devices. This overrides\n"
|
||||||
|
"the devices file.\n")
|
||||||
|
|
||||||
|
arg(devicesfile_ARG, '\0', "devicesfile", string_VAL, 0, 0,
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
576
SOURCES/0047-vdo-support-vdosettings.patch
Normal file
576
SOURCES/0047-vdo-support-vdosettings.patch
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
From 9c6954bc61b22ca03df8897d88eb9618e65fc3c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Wed, 13 Apr 2022 15:09:08 +0200
|
||||||
|
Subject: [PATCH 47/54] vdo: support --vdosettings
|
||||||
|
|
||||||
|
Allow to use --vdosettings with lvcreate,lvconvert,lvchange.
|
||||||
|
Support settings currenly only configurable via lvm.conf.
|
||||||
|
With lvchange we require inactivate LV for changes to be applied.
|
||||||
|
|
||||||
|
Settings block_map_era_length has supported alias block_map_period.
|
||||||
|
---
|
||||||
|
device_mapper/vdo/target.h | 6 +-
|
||||||
|
man/lvmvdo.7_main | 39 ++++++--
|
||||||
|
test/shell/lvchange-vdo.sh | 8 ++
|
||||||
|
test/shell/lvconvert-vdo.sh | 8 +-
|
||||||
|
test/shell/lvcreate-vdo.sh | 6 +-
|
||||||
|
tools/args.h | 9 ++
|
||||||
|
tools/command-lines.in | 6 +-
|
||||||
|
tools/lvchange.c | 43 ++++++++-
|
||||||
|
tools/lvconvert.c | 9 +-
|
||||||
|
tools/lvcreate.c | 34 ++++---
|
||||||
|
tools/toollib.c | 177 ++++++++++++++++++++++++++++++++++++
|
||||||
|
tools/toollib.h | 6 ++
|
||||||
|
12 files changed, 312 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/device_mapper/vdo/target.h b/device_mapper/vdo/target.h
|
||||||
|
index 51dde3f4d..60c5bff56 100644
|
||||||
|
--- a/device_mapper/vdo/target.h
|
||||||
|
+++ b/device_mapper/vdo/target.h
|
||||||
|
@@ -77,8 +77,10 @@ enum dm_vdo_write_policy {
|
||||||
|
struct dm_vdo_target_params {
|
||||||
|
uint32_t minimum_io_size; // in sectors
|
||||||
|
uint32_t block_map_cache_size_mb;
|
||||||
|
- uint32_t block_map_era_length; // format period
|
||||||
|
-
|
||||||
|
+ union {
|
||||||
|
+ uint32_t block_map_era_length; // format period
|
||||||
|
+ uint32_t block_map_period; // supported alias
|
||||||
|
+ };
|
||||||
|
uint32_t check_point_frequency;
|
||||||
|
uint32_t index_memory_size_mb; // format
|
||||||
|
|
||||||
|
diff --git a/man/lvmvdo.7_main b/man/lvmvdo.7_main
|
||||||
|
index 3b77173c4..14bd640b5 100644
|
||||||
|
--- a/man/lvmvdo.7_main
|
||||||
|
+++ b/man/lvmvdo.7_main
|
||||||
|
@@ -132,6 +132,19 @@ that can keep 100% incompressible data there.
|
||||||
|
# lvconvert --type vdo-pool -n vdo0 -V10G vg/ExistingLV
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
+.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV
|
||||||
|
+.
|
||||||
|
+Disable or enable the compression and deduplication for VDOPoolLV
|
||||||
|
+(the volume that maintains all VDO LV(s) associated with it).
|
||||||
|
+.P
|
||||||
|
+.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV
|
||||||
|
+.P
|
||||||
|
+.I Example
|
||||||
|
+.nf
|
||||||
|
+# lvchange --compression n vg/vdopool0
|
||||||
|
+# lvchange --deduplication y vg/vdopool1
|
||||||
|
+.fi
|
||||||
|
+.
|
||||||
|
.SS \n+[step]. Change the default settings used for creating a VDOPoolLV
|
||||||
|
.
|
||||||
|
VDO allows to set a large variety of options. Lots of these settings
|
||||||
|
@@ -173,17 +186,27 @@ EOF
|
||||||
|
# lvcreate --vdo -L10G --config 'allocation/vdo_cpu_threads=4' vg/vdopool1
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
-.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV
|
||||||
|
-.
|
||||||
|
-Disable or enable the compression and deduplication for VDOPoolLV
|
||||||
|
-(the volume that maintains all VDO LV(s) associated with it).
|
||||||
|
-.P
|
||||||
|
-.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV
|
||||||
|
+.SS \n+[step]. Set or change VDO settings with option --vdosettings
|
||||||
|
+.
|
||||||
|
+Use the form 'option=value' or 'option1=value option2=value',
|
||||||
|
+or repeat --vdosettings for each option being set.
|
||||||
|
+Options are listed in the Example section above, for the full description see
|
||||||
|
+.BR lvm.conf (5).
|
||||||
|
+Options can omit 'vdo_' and 'vdo_use_' prefixes and all its underscores.
|
||||||
|
+So i.e. vdo_use_metadata_hints=1 and metadatahints=1 are equivalent.
|
||||||
|
+To change the option for an already existing VDOPoolLV use
|
||||||
|
+.BR lvchange (8)
|
||||||
|
+command. However not all option can be changed.
|
||||||
|
+Only compression and deduplication options can be also changed for an active VDO LV.
|
||||||
|
+Lowest priority options are specified with configuration file,
|
||||||
|
+then with --vdosettings and highest are expliction option --compression
|
||||||
|
+and --deduplication.
|
||||||
|
.P
|
||||||
|
.I Example
|
||||||
|
+.P
|
||||||
|
.nf
|
||||||
|
-# lvchange --compression n vg/vdopool0
|
||||||
|
-# lvchange --deduplication y vg/vdopool1
|
||||||
|
+# lvcreate --vdo -L10G --vdosettings 'ack_threads=1 hash_zone_threads=2' vg/vdopool0
|
||||||
|
+# lvchange --vdosettings 'bio_threads=2 deduplication=1' vg/vdopool0
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
.SS \n+[step]. Checking the usage of VDOPoolLV
|
||||||
|
diff --git a/test/shell/lvchange-vdo.sh b/test/shell/lvchange-vdo.sh
|
||||||
|
index 461b7821f..7cc44d6bc 100644
|
||||||
|
--- a/test/shell/lvchange-vdo.sh
|
||||||
|
+++ b/test/shell/lvchange-vdo.sh
|
||||||
|
@@ -48,9 +48,17 @@ check grep_dmsetup status $vg-vdopool-vpool " online online "
|
||||||
|
lvchange --compression n --deduplication n $vg/vdopool
|
||||||
|
check grep_dmsetup status $vg-vdopool-vpool " offline offline "
|
||||||
|
|
||||||
|
+# --vdosettings needs inactive LV
|
||||||
|
+not lvchange --vdosettings 'ack_threads=8' $vg/vdopool
|
||||||
|
|
||||||
|
lvchange -an $vg/$lv1
|
||||||
|
|
||||||
|
+# With inactive vdo-pool changes are applied
|
||||||
|
+# explicit option --compression has highest priority
|
||||||
|
+lvchange --vdosettings 'ack_threads=5 compression=0' --compression y $vg/vdopool
|
||||||
|
+check lv_field $vg/$lv1 vdo_ack_threads "5"
|
||||||
|
+check lv_field $vg/$lv1 vdo_compression "enabled"
|
||||||
|
+
|
||||||
|
# Test activation
|
||||||
|
lvchange -aly $vg/$lv1
|
||||||
|
check active $vg $lv1
|
||||||
|
diff --git a/test/shell/lvconvert-vdo.sh b/test/shell/lvconvert-vdo.sh
|
||||||
|
index 529f325bd..c42d8f25a 100644
|
||||||
|
--- a/test/shell/lvconvert-vdo.sh
|
||||||
|
+++ b/test/shell/lvconvert-vdo.sh
|
||||||
|
@@ -28,12 +28,12 @@ lvcreate -L5G -n $lv1 $vg
|
||||||
|
not lvconvert --type vdo-pool $vg/$lv1 |& tee out
|
||||||
|
grep "WARNING" out
|
||||||
|
|
||||||
|
-
|
||||||
|
-lvconvert -y --type vdo-pool $vg/$lv1
|
||||||
|
+# Check --vdosettings is also applied to converted vdo-pool
|
||||||
|
+lvconvert -y --type vdo-pool --vdosettings 'ack_threads=5' $vg/$lv1
|
||||||
|
+check lv_field $vg/$lv1 vdo_ack_threads "5"
|
||||||
|
lvremove -f $vg
|
||||||
|
|
||||||
|
-
|
||||||
|
-#
|
||||||
|
+#
|
||||||
|
lvcreate -L5G -n $lv1 $vg
|
||||||
|
lvconvert -y --vdopool $vg/$lv1
|
||||||
|
lvremove -f $vg
|
||||||
|
diff --git a/test/shell/lvcreate-vdo.sh b/test/shell/lvcreate-vdo.sh
|
||||||
|
index 44f8bf094..3e807ac94 100644
|
||||||
|
--- a/test/shell/lvcreate-vdo.sh
|
||||||
|
+++ b/test/shell/lvcreate-vdo.sh
|
||||||
|
@@ -79,8 +79,12 @@ not fsck -n "$DM_DEV_DIR/mapper/$vg-${lv2}"
|
||||||
|
|
||||||
|
lvremove -ff $vg
|
||||||
|
|
||||||
|
+# Unknown settings does not pass
|
||||||
|
+# TODO: try to catch this in parser and 'fail'
|
||||||
|
+not lvcreate --type vdo --vdosettings 'ack_Xthreads=4' -L10G -V1T -ky -n $lv1 $vg
|
||||||
|
|
||||||
|
-lvcreate --type vdo -L10G -V1T -ky -n $lv1 $vg
|
||||||
|
+lvcreate --type vdo --vdosettings 'ack_threads=4' -L10G -V1T -ky -n $lv1 $vg
|
||||||
|
+check lv_field $vg/$lv1 vdo_ack_threads "4"
|
||||||
|
lvs -a $vg
|
||||||
|
lvremove -ff $vg
|
||||||
|
|
||||||
|
diff --git a/tools/args.h b/tools/args.h
|
||||||
|
index 00a2ec817..bfd848ce9 100644
|
||||||
|
--- a/tools/args.h
|
||||||
|
+++ b/tools/args.h
|
||||||
|
@@ -900,6 +900,15 @@ arg(vdopool_ARG, '\0', "vdopool", lv_VAL, 0, 0,
|
||||||
|
"The name of a VDO pool LV.\n"
|
||||||
|
"See \\fBlvmvdo\\fP(7) for more information about VDO usage.\n")
|
||||||
|
|
||||||
|
+arg(vdosettings_ARG, '\0', "vdosettings", string_VAL, ARG_GROUPABLE, 0,
|
||||||
|
+ "Specifies tunable VDO options for VDO LVs.\n"
|
||||||
|
+ "Use the form 'option=value' or 'option1=value option2=value', or\n"
|
||||||
|
+ "repeat --vdosettings for each option being set.\n"
|
||||||
|
+ "These settings override the default VDO behaviors.\n"
|
||||||
|
+ "To remove vdosettings and revert to the default\n"
|
||||||
|
+ "VDO behaviors, use --vdosettings 'default'.\n"
|
||||||
|
+ "See \\fBlvmvdo\\fP(7) for more information.\n")
|
||||||
|
+
|
||||||
|
arg(version_ARG, '\0', "version", 0, 0, 0,
|
||||||
|
"Display version information.\n")
|
||||||
|
|
||||||
|
diff --git a/tools/command-lines.in b/tools/command-lines.in
|
||||||
|
index 00ac08934..08302b34f 100644
|
||||||
|
--- a/tools/command-lines.in
|
||||||
|
+++ b/tools/command-lines.in
|
||||||
|
@@ -243,6 +243,7 @@ OO_LVCHANGE_META: --addtag Tag, --deltag Tag,
|
||||||
|
--setautoactivation Bool, --errorwhenfull Bool, --discards Discards, --zero Bool,
|
||||||
|
--cachemode CacheMode, --cachepolicy String, --cachesettings String,
|
||||||
|
--minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
|
||||||
|
+--vdosettings String,
|
||||||
|
--writebehind Number, --writemostly WriteMostlyPV, --persistent n
|
||||||
|
|
||||||
|
# It's unfortunate that activate needs to be optionally allowed here;
|
||||||
|
@@ -341,7 +342,8 @@ OO_LVCONVERT_CACHE: --cachemetadataformat CacheMetadataFormat,
|
||||||
|
--cachesettings String, --zero Bool
|
||||||
|
|
||||||
|
OO_LVCONVERT_VDO: --metadataprofile String, --readahead Readahead,
|
||||||
|
---compression Bool, --deduplication Bool, --zero Bool
|
||||||
|
+--compression Bool, --deduplication Bool, --vdosettings String,
|
||||||
|
+--zero Bool
|
||||||
|
|
||||||
|
OO_LVCONVERT: --alloc Alloc, --background, --force, --noudevsync
|
||||||
|
|
||||||
|
@@ -839,7 +841,7 @@ OO_LVCREATE_POOL: --poolmetadatasize SizeMB, --poolmetadataspare Bool, --chunksi
|
||||||
|
|
||||||
|
OO_LVCREATE_THINPOOL: --discards Discards, --errorwhenfull Bool
|
||||||
|
|
||||||
|
-OO_LVCREATE_VDO: --compression Bool, --deduplication Bool
|
||||||
|
+OO_LVCREATE_VDO: --compression Bool, --deduplication Bool, --vdosettings String
|
||||||
|
---
|
||||||
|
|
||||||
|
lvcreate --type error --size SizeMB VG
|
||||||
|
diff --git a/tools/lvchange.c b/tools/lvchange.c
|
||||||
|
index 0525bc53c..dc51786d7 100644
|
||||||
|
--- a/tools/lvchange.c
|
||||||
|
+++ b/tools/lvchange.c
|
||||||
|
@@ -755,6 +755,43 @@ out:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _lvchange_vdo(struct cmd_context *cmd,
|
||||||
|
+ struct logical_volume *lv,
|
||||||
|
+ uint32_t *mr)
|
||||||
|
+{
|
||||||
|
+ struct lv_segment *seg;
|
||||||
|
+ int updated = 0;
|
||||||
|
+
|
||||||
|
+ seg = first_seg(lv);
|
||||||
|
+
|
||||||
|
+ // With VDO LV given flip to VDO pool
|
||||||
|
+ if (seg_is_vdo(seg))
|
||||||
|
+ seg = first_seg(seg_lv(seg, 0));
|
||||||
|
+
|
||||||
|
+ if (!get_vdo_settings(cmd, &seg->vdo_params, &updated))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if ((updated & VDO_CHANGE_OFFLINE) &&
|
||||||
|
+ lv_info(cmd, seg->lv, 1, NULL, 0, 0)) {
|
||||||
|
+ log_error("Cannot change VDO settings for active VDO pool %s.",
|
||||||
|
+ display_lvname(seg->lv));
|
||||||
|
+ // TODO maybe add --force support with prompt here
|
||||||
|
+ log_print_unless_silent("VDO pool %s with all its LVs needs to be deactivated.",
|
||||||
|
+ display_lvname(seg->lv));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (updated) {
|
||||||
|
+ if (!dm_vdo_validate_target_params(&seg->vdo_params, 0 /* vdo_size */))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ /* Request caller to commit and reload metadata */
|
||||||
|
+ *mr |= MR_RELOAD;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
|
int arg, uint32_t *mr)
|
||||||
|
{
|
||||||
|
@@ -1154,6 +1191,7 @@ static int _option_requires_direct_commit(int opt_enum)
|
||||||
|
cachemode_ARG,
|
||||||
|
cachepolicy_ARG,
|
||||||
|
cachesettings_ARG,
|
||||||
|
+ vdosettings_ARG,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -1354,7 +1392,10 @@ static int _lvchange_properties_single(struct cmd_context *cmd,
|
||||||
|
docmds++;
|
||||||
|
doit += _lvchange_cache(cmd, lv, &mr);
|
||||||
|
break;
|
||||||
|
-
|
||||||
|
+ case vdosettings_ARG:
|
||||||
|
+ docmds++;
|
||||||
|
+ doit += _lvchange_vdo(cmd, lv, &mr);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
log_error(INTERNAL_ERROR "Failed to check for option %s",
|
||||||
|
arg_long_option_name(i));
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index a90946173..3d4b24fe3 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -5456,13 +5456,8 @@ static int _lvconvert_to_vdopool_single(struct cmd_context *cmd,
|
||||||
|
if (!fill_vdo_target_params(cmd, &vdo_params, &vdo_pool_header_size, vg->profile))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
- if (arg_is_set(cmd, compression_ARG))
|
||||||
|
- vdo_params.use_compression =
|
||||||
|
- arg_int_value(cmd, compression_ARG, 0);
|
||||||
|
-
|
||||||
|
- if (arg_is_set(cmd, deduplication_ARG))
|
||||||
|
- vdo_params.use_deduplication =
|
||||||
|
- arg_int_value(cmd, deduplication_ARG, 0);
|
||||||
|
+ if (!get_vdo_settings(cmd, &vdo_params, NULL))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
if (!activate_lv(cmd, lv)) {
|
||||||
|
log_error("Cannot activate %s.", display_lvname(lv));
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index 79af42685..8de6f3408 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -698,6 +698,23 @@ static int _read_cache_params(struct cmd_context *cmd,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _read_vdo_params(struct cmd_context *cmd,
|
||||||
|
+ struct lvcreate_params *lp)
|
||||||
|
+{
|
||||||
|
+ if (!seg_is_vdo(lp))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ // prefiling settings here
|
||||||
|
+ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ // override with optional vdo settings
|
||||||
|
+ if (!get_vdo_settings(cmd, &lp->vdo_params, NULL))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _read_activation_params(struct cmd_context *cmd,
|
||||||
|
struct volume_group *vg,
|
||||||
|
struct lvcreate_params *lp)
|
||||||
|
@@ -888,7 +905,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
#define VDO_POOL_ARGS \
|
||||||
|
vdopool_ARG,\
|
||||||
|
compression_ARG,\
|
||||||
|
- deduplication_ARG
|
||||||
|
+ deduplication_ARG,\
|
||||||
|
+ vdosettings_ARG
|
||||||
|
|
||||||
|
/* Cache and cache-pool segment type */
|
||||||
|
if (seg_is_cache(lp)) {
|
||||||
|
@@ -1098,19 +1116,6 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
zero_ARG,
|
||||||
|
-1))
|
||||||
|
return_0;
|
||||||
|
-
|
||||||
|
- // FIXME: prefiling here - this is wrong place
|
||||||
|
- // but will work for this moment
|
||||||
|
- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
|
||||||
|
- return_0;
|
||||||
|
-
|
||||||
|
- if (arg_is_set(cmd, compression_ARG))
|
||||||
|
- lp->vdo_params.use_compression =
|
||||||
|
- arg_int_value(cmd, compression_ARG, 0);
|
||||||
|
-
|
||||||
|
- if (arg_is_set(cmd, deduplication_ARG))
|
||||||
|
- lp->vdo_params.use_deduplication =
|
||||||
|
- arg_int_value(cmd, deduplication_ARG, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check options shared between more segment types */
|
||||||
|
@@ -1198,6 +1203,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
&lp->pool_metadata_size, &lp->pool_metadata_spare,
|
||||||
|
&lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) ||
|
||||||
|
!_read_cache_params(cmd, lp) ||
|
||||||
|
+ !_read_vdo_params(cmd, lp) ||
|
||||||
|
!_read_mirror_and_raid_params(cmd, lp))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 16be336d4..697baee82 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -1192,6 +1192,183 @@ out:
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Compare VDO option name, skip any '_' in name
|
||||||
|
+ * and also allow to use it without vdo_[use_] prefix
|
||||||
|
+ */
|
||||||
|
+static int _compare_vdo_option(const char *b1, const char *b2)
|
||||||
|
+{
|
||||||
|
+ if (strncasecmp(b1, "vdo", 3) == 0) // skip vdo prefix
|
||||||
|
+ b1 += 3;
|
||||||
|
+
|
||||||
|
+ if ((tolower(*b1) != tolower(*b2)) &&
|
||||||
|
+ (strncmp(b2, "use_", 4) == 0))
|
||||||
|
+ b2 += 4; // try again with skipped prefix 'use_'
|
||||||
|
+
|
||||||
|
+ while (*b1 && *b2) {
|
||||||
|
+ if (tolower(*b1) == tolower(*b2)) {
|
||||||
|
+ ++b1;
|
||||||
|
+ ++b2;
|
||||||
|
+ continue; // matching char
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (*b1 == '_')
|
||||||
|
+ ++b1; // skip to next char
|
||||||
|
+ else if (*b2 == '_')
|
||||||
|
+ ++b2; // skip to next char
|
||||||
|
+ else
|
||||||
|
+ break; // mismatch
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (*b1 || *b2) ? 0 : 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define CHECK_AND_SET(var, onoff) \
|
||||||
|
+ option = #var;\
|
||||||
|
+ if (_compare_vdo_option(cn->key, option)) {\
|
||||||
|
+ if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_INT))\
|
||||||
|
+ goto err;\
|
||||||
|
+ if (vtp->var != cn->v->v.i) {\
|
||||||
|
+ vtp->var = cn->v->v.i;\
|
||||||
|
+ u |= onoff;\
|
||||||
|
+ }\
|
||||||
|
+ continue;\
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#define DO_OFFLINE(var) \
|
||||||
|
+ CHECK_AND_SET(var, VDO_CHANGE_OFFLINE)
|
||||||
|
+
|
||||||
|
+#define DO_ONLINE(var) \
|
||||||
|
+ CHECK_AND_SET(var, VDO_CHANGE_ONLINE)
|
||||||
|
+
|
||||||
|
+int get_vdo_settings(struct cmd_context *cmd,
|
||||||
|
+ struct dm_vdo_target_params *vtp,
|
||||||
|
+ int *updated)
|
||||||
|
+{
|
||||||
|
+ const char *str, *option = NULL;
|
||||||
|
+ struct arg_value_group_list *group;
|
||||||
|
+ struct dm_config_tree *result = NULL, *prev = NULL, *current = NULL;
|
||||||
|
+ struct dm_config_node *cn;
|
||||||
|
+ int r = 0, u = 0, is_lvchange;
|
||||||
|
+ int use_compression = vtp->use_compression;
|
||||||
|
+ int use_deduplication = vtp->use_deduplication;
|
||||||
|
+ int checked_lvchange;
|
||||||
|
+
|
||||||
|
+ if (updated)
|
||||||
|
+ *updated = 0;
|
||||||
|
+
|
||||||
|
+ // Group all --vdosettings
|
||||||
|
+ dm_list_iterate_items(group, &cmd->arg_value_groups) {
|
||||||
|
+ if (!grouped_arg_is_set(group->arg_values, vdosettings_ARG))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!(current = dm_config_create()))
|
||||||
|
+ goto_out;
|
||||||
|
+ if (prev)
|
||||||
|
+ current->cascade = prev;
|
||||||
|
+ prev = current;
|
||||||
|
+
|
||||||
|
+ if (!(str = grouped_arg_str_value(group->arg_values,
|
||||||
|
+ vdosettings_ARG,
|
||||||
|
+ NULL)))
|
||||||
|
+ goto_out;
|
||||||
|
+
|
||||||
|
+ if (!dm_config_parse_without_dup_node_check(current, str, str + strlen(str)))
|
||||||
|
+ goto_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (current) {
|
||||||
|
+ if (!(result = dm_config_flatten(current)))
|
||||||
|
+ goto_out;
|
||||||
|
+
|
||||||
|
+ checked_lvchange = !strcmp(cmd->name, "lvchange");
|
||||||
|
+
|
||||||
|
+ /* Use all acceptable VDO options */
|
||||||
|
+ for (cn = result->root; cn; cn = cn->sib) {
|
||||||
|
+ is_lvchange = 0;
|
||||||
|
+ DO_OFFLINE(ack_threads);
|
||||||
|
+ DO_OFFLINE(bio_rotation);
|
||||||
|
+ DO_OFFLINE(bio_threads);
|
||||||
|
+ DO_OFFLINE(block_map_cache_size_mb);
|
||||||
|
+ DO_OFFLINE(block_map_era_length);
|
||||||
|
+ DO_OFFLINE(block_map_period); // alias for block_map_era_length
|
||||||
|
+ DO_OFFLINE(cpu_threads);
|
||||||
|
+ DO_OFFLINE(hash_zone_threads);
|
||||||
|
+ DO_OFFLINE(logical_threads);
|
||||||
|
+ DO_OFFLINE(max_discard);
|
||||||
|
+ DO_OFFLINE(physical_threads);
|
||||||
|
+
|
||||||
|
+ // Support also these - even when we have regular opts for them
|
||||||
|
+ DO_ONLINE(use_compression);
|
||||||
|
+ DO_ONLINE(use_deduplication);
|
||||||
|
+
|
||||||
|
+ // Settings bellow cannot be changed with lvchange command
|
||||||
|
+ is_lvchange = checked_lvchange;
|
||||||
|
+
|
||||||
|
+ DO_OFFLINE(check_point_frequency);
|
||||||
|
+ DO_OFFLINE(index_memory_size_mb);
|
||||||
|
+ DO_OFFLINE(minimum_io_size);
|
||||||
|
+ DO_OFFLINE(slab_size_mb);
|
||||||
|
+ DO_OFFLINE(use_metadata_hints);
|
||||||
|
+ DO_OFFLINE(use_sparse_index);
|
||||||
|
+
|
||||||
|
+ option = "write_policy";
|
||||||
|
+ if (_compare_vdo_option(cn->key, option)) {
|
||||||
|
+ if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_STRING))
|
||||||
|
+ goto err;
|
||||||
|
+ if (!set_vdo_write_policy(&vtp->write_policy, cn->v->v.str))
|
||||||
|
+ goto_out;
|
||||||
|
+ u |= VDO_CHANGE_OFFLINE;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_error("Unknown VDO setting \"%s\".", cn->key);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (arg_is_set(cmd, compression_ARG)) {
|
||||||
|
+ vtp->use_compression = arg_int_value(cmd, compression_ARG, 0);
|
||||||
|
+ if (vtp->use_compression != use_compression)
|
||||||
|
+ u |= VDO_CHANGE_ONLINE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (arg_is_set(cmd, deduplication_ARG)) {
|
||||||
|
+ vtp->use_deduplication = arg_int_value(cmd, deduplication_ARG, 0);
|
||||||
|
+ if (vtp->use_deduplication != use_deduplication)
|
||||||
|
+ u |= VDO_CHANGE_ONLINE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (updated) {
|
||||||
|
+ // validation of updated VDO option
|
||||||
|
+ if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) {
|
||||||
|
+err:
|
||||||
|
+ if (is_lvchange)
|
||||||
|
+ log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
|
||||||
|
+ option);
|
||||||
|
+ else
|
||||||
|
+ log_error("Invalid argument for VDO setting \"vdo_%s\".",
|
||||||
|
+ option);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *updated = u;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = 1;
|
||||||
|
+out:
|
||||||
|
+ if (result)
|
||||||
|
+ dm_config_destroy(result);
|
||||||
|
+
|
||||||
|
+ while (prev) {
|
||||||
|
+ current = prev->cascade;
|
||||||
|
+ dm_config_destroy(prev);
|
||||||
|
+ prev = current;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _get_one_writecache_setting(struct cmd_context *cmd, struct writecache_settings *settings,
|
||||||
|
char *key, char *val, uint32_t *block_size_sectors)
|
||||||
|
{
|
||||||
|
diff --git a/tools/toollib.h b/tools/toollib.h
|
||||||
|
index f3a60fbc4..2b38e4e4f 100644
|
||||||
|
--- a/tools/toollib.h
|
||||||
|
+++ b/tools/toollib.h
|
||||||
|
@@ -217,6 +217,12 @@ int get_cache_params(struct cmd_context *cmd,
|
||||||
|
const char **name,
|
||||||
|
struct dm_config_tree **settings);
|
||||||
|
|
||||||
|
+#define VDO_CHANGE_ONLINE 1
|
||||||
|
+#define VDO_CHANGE_OFFLINE 2
|
||||||
|
+int get_vdo_settings(struct cmd_context *cmd,
|
||||||
|
+ struct dm_vdo_target_params *vtp,
|
||||||
|
+ int *updated);
|
||||||
|
+
|
||||||
|
int get_writecache_settings(struct cmd_context *cmd, struct writecache_settings *settings,
|
||||||
|
uint32_t *block_size_sectors);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 45a2ccfa3bdf4c5b3f8b9e0cc5330fca345b0d26 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||||
|
Date: Thu, 5 May 2022 11:02:32 +0200
|
||||||
|
Subject: [PATCH 48/54] toollib: fix segfault when handling selection with
|
||||||
|
historical LVs
|
||||||
|
|
||||||
|
When processing historical LVs inside process_each_lv_in_vg for
|
||||||
|
selection, we need to use dummy "_historical_lv" for select_match_lv.
|
||||||
|
|
||||||
|
This is because a historical LV is not an actual LV, but only a tiny
|
||||||
|
representation with subset of original properties that we recorded
|
||||||
|
(name, uuid...).
|
||||||
|
|
||||||
|
To use the same processing functions we use for full-fledged non-historical
|
||||||
|
LVs, we need to use the prefilled "_historical_lv" structure which has all
|
||||||
|
the other missing properties hard-coded.
|
||||||
|
---
|
||||||
|
tools/toollib.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 697baee82..01ba03658 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -3392,13 +3392,14 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
process_lv = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- process_lv = process_lv && select_match_lv(cmd, handle, vg, lvl->lv) && _select_matches(handle);
|
||||||
|
+ _historical_lv.this_glv = glvl->glv;
|
||||||
|
+ _historical_lv.name = glvl->glv->historical->name;
|
||||||
|
+
|
||||||
|
+ process_lv = process_lv && select_match_lv(cmd, handle, vg, &_historical_lv) && _select_matches(handle);
|
||||||
|
|
||||||
|
if (!process_lv)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- _historical_lv.this_glv = glvl->glv;
|
||||||
|
- _historical_lv.name = glvl->glv->historical->name;
|
||||||
|
log_very_verbose("Processing historical LV %s in VG %s.", glvl->glv->historical->name, vg->name);
|
||||||
|
|
||||||
|
ret = process_single_lv(cmd, &_historical_lv, handle);
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,39 @@
|
|||||||
|
From eda98e4b9418568d6793d2c853aaa54db051cc9f Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 27 May 2022 12:38:43 -0500
|
||||||
|
Subject: [PATCH 49/54] devices file: move clean up after command is run
|
||||||
|
|
||||||
|
devices_file_exit wasn't being called between lvm_shell
|
||||||
|
commands, so the file lock wouldn't be released.
|
||||||
|
---
|
||||||
|
lib/commands/toolcontext.c | 1 -
|
||||||
|
tools/lvmcmdline.c | 1 +
|
||||||
|
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
|
||||||
|
index a0c78ddd6..7db5e11a1 100644
|
||||||
|
--- a/lib/commands/toolcontext.c
|
||||||
|
+++ b/lib/commands/toolcontext.c
|
||||||
|
@@ -1912,7 +1912,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
|
||||||
|
_destroy_segtypes(&cmd->segtypes);
|
||||||
|
_destroy_formats(cmd, &cmd->formats);
|
||||||
|
|
||||||
|
- devices_file_exit(cmd);
|
||||||
|
if (!dev_cache_exit())
|
||||||
|
stack;
|
||||||
|
_destroy_dev_types(cmd);
|
||||||
|
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
|
||||||
|
index 1727ba089..eb63fd9b5 100644
|
||||||
|
--- a/tools/lvmcmdline.c
|
||||||
|
+++ b/tools/lvmcmdline.c
|
||||||
|
@@ -3306,6 +3306,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
hints_exit(cmd);
|
||||||
|
lvmcache_destroy(cmd, 1, 1);
|
||||||
|
label_scan_destroy(cmd);
|
||||||
|
+ devices_file_exit(cmd);
|
||||||
|
|
||||||
|
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
|
||||||
|
dm_config_destroy(config_string_cft);
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
From bf0b3962088fb18f4a2aba00f38955e1fc6e31fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 27 May 2022 14:27:03 -0500
|
||||||
|
Subject: [PATCH 50/54] devices file: fail if --devicesfile filename doesn't
|
||||||
|
exist
|
||||||
|
|
||||||
|
A typo of the filename after --devicesfile should result in a
|
||||||
|
command error rather than the command falling back to using no
|
||||||
|
devices file at all. Exception is vgcreate|pvcreate which
|
||||||
|
create a new devices file if the file name doesn't exist.
|
||||||
|
---
|
||||||
|
lib/device/dev-cache.c | 9 +++++++++
|
||||||
|
test/shell/devicesfile-basic.sh | 4 ++++
|
||||||
|
2 files changed, 13 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index b0759b06c..0eb2568b5 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -1882,6 +1882,15 @@ static int _setup_devices(struct cmd_context *cmd, int no_file_match)
|
||||||
|
|
||||||
|
file_exists = devices_file_exists(cmd);
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Fail if user specifies a file name that doesn't exist and
|
||||||
|
+ * the command is not creating a new devices file.
|
||||||
|
+ */
|
||||||
|
+ if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) {
|
||||||
|
+ log_error("Devices file not found: %s", cmd->devices_file_path);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Removing the devices file is another way of disabling the use of
|
||||||
|
* a devices file, unless the command creates the devices file.
|
||||||
|
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
|
||||||
|
index 7ba9e2c7f..d1cfb6a35 100644
|
||||||
|
--- a/test/shell/devicesfile-basic.sh
|
||||||
|
+++ b/test/shell/devicesfile-basic.sh
|
||||||
|
@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices"
|
||||||
|
vgs --devicesfile test.devices $vg1
|
||||||
|
not vgs --devicesfile test.devices $vg2
|
||||||
|
|
||||||
|
+# misspelled override name fails
|
||||||
|
+not vgs --devicesfile doesnotexist $vg1
|
||||||
|
+not vgs --devicesfile doesnotexist $vg2
|
||||||
|
+
|
||||||
|
# devicesfile and devices cannot be used together
|
||||||
|
not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
From 25abb5730f4d8f79df69f0817881ffb9eed195a9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 6 Jun 2022 11:39:02 -0500
|
||||||
|
Subject: [PATCH 51/54] filter-mpath: handle other wwid types in blacklist
|
||||||
|
|
||||||
|
Fixes commit 494372b4eed0c8f6040e3357939eb7511ac25745
|
||||||
|
"filter-mpath: use multipath blacklist"
|
||||||
|
to handle wwids with initial type digits 1 and 2 used
|
||||||
|
for t10 and eui ids. Originally recognized type 3 naa.
|
||||||
|
---
|
||||||
|
lib/device/dev-mpath.c | 11 ++++++-----
|
||||||
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
|
||||||
|
index 6eed03c5b..7abbfb289 100644
|
||||||
|
--- a/lib/device/dev-mpath.c
|
||||||
|
+++ b/lib/device/dev-mpath.c
|
||||||
|
@@ -54,7 +54,7 @@ static void _read_blacklist_file(const char *path)
|
||||||
|
int section_black = 0;
|
||||||
|
int section_exceptions = 0;
|
||||||
|
int found_quote;
|
||||||
|
- int found_three;
|
||||||
|
+ int found_type;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (!(fp = fopen(path, "r")))
|
||||||
|
@@ -114,7 +114,7 @@ static void _read_blacklist_file(const char *path)
|
||||||
|
|
||||||
|
memset(wwid, 0, sizeof(wwid));
|
||||||
|
found_quote = 0;
|
||||||
|
- found_three = 0;
|
||||||
|
+ found_type = 0;
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
for (; i < MAX_WWID_LINE; i++) {
|
||||||
|
@@ -132,9 +132,10 @@ static void _read_blacklist_file(const char *path)
|
||||||
|
/* second quote is end of wwid */
|
||||||
|
if ((line[i] == '"') && found_quote)
|
||||||
|
break;
|
||||||
|
- /* ignore first "3" in wwid */
|
||||||
|
- if ((line[i] == '3') && !found_three) {
|
||||||
|
- found_three = 1;
|
||||||
|
+ /* exclude initial 3/2/1 for naa/eui/t10 */
|
||||||
|
+ if (!j && !found_type &&
|
||||||
|
+ ((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) {
|
||||||
|
+ found_type = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
56
SOURCES/0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch
Normal file
56
SOURCES/0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
From 7cb63b05dad453d015bbe462b799fb031dd6952c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Tue, 31 May 2022 22:48:38 +0200
|
||||||
|
Subject: [PATCH 52/54] vdo: fix conversion of vdo_slab_size_mb
|
||||||
|
|
||||||
|
When converting VDO volume, the parameter vdo_slabSize was
|
||||||
|
incorrectly copied as vdo_blockMapCacheSize, however this parameter
|
||||||
|
is then no longer used for any table line creation so the wrong
|
||||||
|
value was only stored in metadata.
|
||||||
|
|
||||||
|
Also use just single get_kb_size_with_unit_ and remove it's duplicate
|
||||||
|
functionality with get_mb_size_with_unit_.
|
||||||
|
|
||||||
|
Use $VERB for vdo remove call.
|
||||||
|
---
|
||||||
|
scripts/lvm_import_vdo.sh | 13 ++-----------
|
||||||
|
1 file changed, 2 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh
|
||||||
|
index 61a82e41e..beb55dbdb 100755
|
||||||
|
--- a/scripts/lvm_import_vdo.sh
|
||||||
|
+++ b/scripts/lvm_import_vdo.sh
|
||||||
|
@@ -125,15 +125,6 @@ get_kb_size_with_unit_() {
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
-get_mb_size_with_unit_() {
|
||||||
|
- case "$1" in
|
||||||
|
- *[mM]) echo $(( ${1%[mM]} )) ;;
|
||||||
|
- *[gG]) echo $(( ${1%[gG]} * 1024 )) ;;
|
||||||
|
- *[tT]) echo $(( ${1%[tT]} * 1024 * 1024 )) ;;
|
||||||
|
- *[pP]) echo $(( ${1%[pP]} * 1024 * 1024 * 1024 )) ;;
|
||||||
|
- esac
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
# Figure out largest possible extent size usable for VG
|
||||||
|
# $1 physical size
|
||||||
|
# $2 logical size
|
||||||
|
@@ -328,12 +319,12 @@ allocation {
|
||||||
|
vdo_use_deduplication = $(get_enabled_value_ "$vdo_deduplication")
|
||||||
|
vdo_use_metadata_hints=1
|
||||||
|
vdo_minimum_io_size = $vdo_logicalBlockSize
|
||||||
|
- vdo_block_map_cache_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize")
|
||||||
|
+ vdo_block_map_cache_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
|
||||||
|
vdo_block_map_period = $vdo_blockMapPeriod
|
||||||
|
vdo_check_point_frequency = $vdo_indexCfreq
|
||||||
|
vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse")
|
||||||
|
vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}")
|
||||||
|
- vdo_slab_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize")
|
||||||
|
+ vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
|
||||||
|
vdo_ack_threads = $vdo_ackThreads
|
||||||
|
vdo_bio_threads = $vdo_bioThreads
|
||||||
|
vdo_bio_rotation = $vdo_bioRotationInterval
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
741
SOURCES/0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
Normal file
741
SOURCES/0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
Normal file
@ -0,0 +1,741 @@
|
|||||||
|
From e36b180a6983c4fa07d6714a0bf81e6935487359 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 6 Jun 2022 14:04:20 -0500
|
||||||
|
Subject: [PATCH 53/54] filter-mpath: get wwids from sysfs vpd_pg83
|
||||||
|
|
||||||
|
to compare with wwids in /etc/multipath/wwids when
|
||||||
|
excluding multipath components. The wwid printed
|
||||||
|
from the sysfs wwid file may not be the wwid used
|
||||||
|
in multipath wwids. Save the wwids found for each
|
||||||
|
device on dev->wwids to avoid repeating reading
|
||||||
|
and parsing the sysfs files.
|
||||||
|
---
|
||||||
|
lib/Makefile.in | 1 +
|
||||||
|
lib/device/dev-cache.c | 18 ++++
|
||||||
|
lib/device/dev-cache.h | 1 +
|
||||||
|
lib/device/dev-mpath.c | 232 ++++++++++++++++++++++++++++++++++-------
|
||||||
|
lib/device/device.h | 13 +++
|
||||||
|
lib/device/device_id.c | 31 +++++-
|
||||||
|
lib/device/device_id.h | 2 +
|
||||||
|
lib/device/parse_vpd.c | 199 +++++++++++++++++++++++++++++++++++
|
||||||
|
8 files changed, 454 insertions(+), 43 deletions(-)
|
||||||
|
create mode 100644 lib/device/parse_vpd.c
|
||||||
|
|
||||||
|
diff --git a/lib/Makefile.in b/lib/Makefile.in
|
||||||
|
index 8b3eac60a..3077825d2 100644
|
||||||
|
--- a/lib/Makefile.in
|
||||||
|
+++ b/lib/Makefile.in
|
||||||
|
@@ -40,6 +40,7 @@ SOURCES =\
|
||||||
|
device/dev-luks.c \
|
||||||
|
device/dev-dasd.c \
|
||||||
|
device/dev-lvm1-pool.c \
|
||||||
|
+ device/parse_vpd.c \
|
||||||
|
display/display.c \
|
||||||
|
error/errseg.c \
|
||||||
|
unknown/unknown.c \
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index 0eb2568b5..65e1cb138 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev)
|
||||||
|
|
||||||
|
dm_list_init(&dev->aliases);
|
||||||
|
dm_list_init(&dev->ids);
|
||||||
|
+ dm_list_init(&dev->wwids);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dev_destroy_file(struct device *dev)
|
||||||
|
@@ -383,6 +384,22 @@ out:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ int fd;
|
||||||
|
+
|
||||||
|
+ fd = open(path, O_RDONLY);
|
||||||
|
+ if (fd < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ ret = read(fd, buf, buf_size);
|
||||||
|
+ close(fd);
|
||||||
|
+ if (ret <= 0)
|
||||||
|
+ return 0;
|
||||||
|
+ *retlen = ret;
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
@@ -1336,6 +1353,7 @@ int dev_cache_exit(void)
|
||||||
|
dm_hash_iterate(n, _cache.names) {
|
||||||
|
dev = (struct device *) dm_hash_get_data(_cache.names, n);
|
||||||
|
free_dids(&dev->ids);
|
||||||
|
+ free_wwids(&dev->wwids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
|
||||||
|
index 321a56d7b..c49e6265d 100644
|
||||||
|
--- a/lib/device/dev-cache.h
|
||||||
|
+++ b/lib/device/dev-cache.h
|
||||||
|
@@ -74,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path);
|
||||||
|
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
|
||||||
|
|
||||||
|
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
|
||||||
|
+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen);
|
||||||
|
int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
|
||||||
|
|
||||||
|
int setup_devices_file(struct cmd_context *cmd);
|
||||||
|
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
|
||||||
|
index 7abbfb289..3795c992d 100644
|
||||||
|
--- a/lib/device/dev-mpath.c
|
||||||
|
+++ b/lib/device/dev-mpath.c
|
||||||
|
@@ -200,11 +200,12 @@ static void _read_wwid_exclusions(void)
|
||||||
|
log_debug("multipath config ignored %d wwids", rem_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void _read_wwid_file(const char *config_wwids_file)
|
||||||
|
+static void _read_wwid_file(const char *config_wwids_file, int *entries)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char line[MAX_WWID_LINE];
|
||||||
|
char *wwid, *p;
|
||||||
|
+ char typestr[2] = { 0 };
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (config_wwids_file[0] != '/') {
|
||||||
|
@@ -226,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file)
|
||||||
|
if (line[0] == '/')
|
||||||
|
wwid++;
|
||||||
|
|
||||||
|
- /* skip the initial '3' */
|
||||||
|
- wwid++;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * the initial character is the id type,
|
||||||
|
+ * 1 is t10, 2 is eui, 3 is naa, 8 is scsi name.
|
||||||
|
+ * wwids are stored in the hash table without the type charater.
|
||||||
|
+ * It seems that sometimes multipath does not include
|
||||||
|
+ * the type charater (seen with t10 scsi_debug devs).
|
||||||
|
+ */
|
||||||
|
+ typestr[0] = *wwid;
|
||||||
|
+ if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3')
|
||||||
|
+ wwid++;
|
||||||
|
|
||||||
|
if ((p = strchr(wwid, '/')))
|
||||||
|
*p = '\0';
|
||||||
|
@@ -240,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file)
|
||||||
|
stack;
|
||||||
|
|
||||||
|
log_debug("multipath wwids read %d from %s", count, config_wwids_file);
|
||||||
|
+ *entries = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dev_mpath_init(const char *config_wwids_file)
|
||||||
|
@@ -247,6 +258,7 @@ int dev_mpath_init(const char *config_wwids_file)
|
||||||
|
struct dm_pool *mem;
|
||||||
|
struct dm_hash_table *minor_tab;
|
||||||
|
struct dm_hash_table *wwid_tab;
|
||||||
|
+ int entries = 0;
|
||||||
|
|
||||||
|
dm_list_init(&_ignored);
|
||||||
|
dm_list_init(&_ignored_exceptions);
|
||||||
|
@@ -283,10 +295,16 @@ int dev_mpath_init(const char *config_wwids_file)
|
||||||
|
_wwid_hash_tab = wwid_tab;
|
||||||
|
|
||||||
|
if (config_wwids_file) {
|
||||||
|
- _read_wwid_file(config_wwids_file);
|
||||||
|
+ _read_wwid_file(config_wwids_file, &entries);
|
||||||
|
_read_wwid_exclusions();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!entries) {
|
||||||
|
+ /* reading dev wwids is skipped with null wwid_hash_tab */
|
||||||
|
+ dm_hash_destroy(_wwid_hash_tab);
|
||||||
|
+ _wwid_hash_tab = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -432,10 +450,10 @@ static int _dev_is_mpath_component_udev(struct device *dev)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev)
|
||||||
|
+static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ int primary_result, dev_t primary_dev)
|
||||||
|
{
|
||||||
|
struct dev_types *dt = cmd->dev_types;
|
||||||
|
- const char *part_name;
|
||||||
|
const char *name; /* e.g. "sda" for "/dev/sda" */
|
||||||
|
char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */
|
||||||
|
char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */
|
||||||
|
@@ -449,25 +467,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
|
||||||
|
int dm_dev_major;
|
||||||
|
int dm_dev_minor;
|
||||||
|
struct stat info;
|
||||||
|
- dev_t primary_dev;
|
||||||
|
int is_mpath_component = 0;
|
||||||
|
|
||||||
|
- /* multipathing is only known to exist for SCSI or NVME devices */
|
||||||
|
- if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
|
||||||
|
+ switch (primary_result) {
|
||||||
|
|
||||||
|
case 2: /* The dev is partition. */
|
||||||
|
- part_name = dev_name(dev); /* name of original dev for log_debug msg */
|
||||||
|
|
||||||
|
/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
|
||||||
|
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
|
||||||
|
return_0;
|
||||||
|
-
|
||||||
|
- log_debug_devs("%s: Device is a partition, using primary "
|
||||||
|
- "device %s for mpath component detection",
|
||||||
|
- part_name, name);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* The dev is already a primary dev. Just continue with the dev. */
|
||||||
|
@@ -589,47 +597,189 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
|
||||||
|
return is_mpath_component;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev)
|
||||||
|
+static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ char *idbuf, int idbufsize)
|
||||||
|
{
|
||||||
|
- char sysbuf[PATH_MAX] = { 0 };
|
||||||
|
- char *wwid;
|
||||||
|
- long look;
|
||||||
|
+ char idtmp[DEV_WWID_SIZE];
|
||||||
|
|
||||||
|
- if (!_wwid_hash_tab)
|
||||||
|
+ if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) {
|
||||||
|
+ /* the wwid file is not under device for nvme devs */
|
||||||
|
+ if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize))
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (!idbuf[0])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf)))
|
||||||
|
+ /* in t10 id, replace series of spaces with one _ like multipath */
|
||||||
|
+ if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) {
|
||||||
|
+ if (idbufsize < DEV_WWID_SIZE)
|
||||||
|
+ return 0;
|
||||||
|
+ memcpy(idtmp, idbuf, DEV_WWID_SIZE);
|
||||||
|
+ memset(idbuf, 0, idbufsize);
|
||||||
|
+ format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize);
|
||||||
|
+ }
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define VPD_SIZE 4096
|
||||||
|
+
|
||||||
|
+static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ struct dm_list *ids)
|
||||||
|
+{
|
||||||
|
+ unsigned char vpd_data[VPD_SIZE] = { 0 };
|
||||||
|
+ int vpd_datalen = 0;
|
||||||
|
+
|
||||||
|
+ if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen))
|
||||||
|
+ return 0;
|
||||||
|
+ if (!vpd_datalen)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!sysbuf[0])
|
||||||
|
+ /* adds dev_wwid entry to dev->wwids for each id in vpd data */
|
||||||
|
+ parse_vpd_ids(vpd_data, vpd_datalen, ids);
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void free_wwids(struct dm_list *ids)
|
||||||
|
+{
|
||||||
|
+ struct dev_wwid *dw, *safe;
|
||||||
|
+
|
||||||
|
+ dm_list_iterate_items_safe(dw, safe, ids) {
|
||||||
|
+ dm_list_del(&dw->list);
|
||||||
|
+ free(dw);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int _wwid_type_num(char *id)
|
||||||
|
+{
|
||||||
|
+ if (!strncmp(id, "naa.", 4))
|
||||||
|
+ return 3;
|
||||||
|
+ else if (!strncmp(id, "eui.", 4))
|
||||||
|
+ return 2;
|
||||||
|
+ else if (!strncmp(id, "t10.", 4))
|
||||||
|
+ return 1;
|
||||||
|
+ else
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * TODO: if each of the different wwid types (naa/eui/t10) were
|
||||||
|
+ * represented by different DEV_ID_TYPE_FOO values, and used
|
||||||
|
+ * as device_id types, then we could drop struct dev_wwid and
|
||||||
|
+ * drop dev->wwids, and just use dev->ids for each of the
|
||||||
|
+ * different wwids found in vpd_pg83. This would also require
|
||||||
|
+ * the ability to handle both the original method of replacing
|
||||||
|
+ * every space in the id string with _ and the new/multipath
|
||||||
|
+ * format_t10_id replacing series of spaces with one _.
|
||||||
|
+ */
|
||||||
|
+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids)
|
||||||
|
+{
|
||||||
|
+ struct dev_wwid *dw;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ if (!id_type) {
|
||||||
|
+ id_type = _wwid_type_num(id);
|
||||||
|
+ if (id_type == -1)
|
||||||
|
+ log_debug("unknown wwid type %s", id);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(dw = zalloc(sizeof(struct dev_wwid))))
|
||||||
|
+ return NULL;
|
||||||
|
+ len = strlen(id);
|
||||||
|
+ if (len >= DEV_WWID_SIZE)
|
||||||
|
+ len = DEV_WWID_SIZE - 1;
|
||||||
|
+ memcpy(dw->id, id, len);
|
||||||
|
+ dw->type = id_type;
|
||||||
|
+ dm_list_add(ids, &dw->list);
|
||||||
|
+ return dw;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * we save ids with format: naa.<value>, eui.<value>, t10.<value>.
|
||||||
|
+ * multipath wwids file uses format: 3<value>, 2<value>, 1<value>.
|
||||||
|
+ * The values are saved in wwid_hash_tab without the type prefix.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ int primary_result, dev_t primary_dev)
|
||||||
|
+{
|
||||||
|
+ char idbuf[DEV_WWID_SIZE] = { 0 };
|
||||||
|
+ struct dev_wwid *dw;
|
||||||
|
+ char *wwid;
|
||||||
|
+
|
||||||
|
+ if (!_wwid_hash_tab)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * sysfs prints wwid as <typestr>.<value>
|
||||||
|
- * multipath wwid uses '3'<value>
|
||||||
|
- * does "<typestr>." always correspond to "3"?
|
||||||
|
+ * Check the primary device, not the partition.
|
||||||
|
*/
|
||||||
|
- if (!(wwid = strchr(sysbuf, '.')))
|
||||||
|
- return 0;
|
||||||
|
+ if (primary_result == 2) {
|
||||||
|
+ if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) {
|
||||||
|
+ log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* skip the type and dot, just as '3' was skipped from wwids entry */
|
||||||
|
- wwid++;
|
||||||
|
-
|
||||||
|
- look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid));
|
||||||
|
+ /*
|
||||||
|
+ * This function may be called multiple times for the same device, in
|
||||||
|
+ * particular if partitioned for each partition.
|
||||||
|
+ */
|
||||||
|
+ if (!dm_list_empty(&dev->wwids))
|
||||||
|
+ goto lookup;
|
||||||
|
|
||||||
|
- if (look) {
|
||||||
|
- log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid);
|
||||||
|
- return 1;
|
||||||
|
+ /*
|
||||||
|
+ * Get all the ids for the device from vpd_pg83 and check if any of
|
||||||
|
+ * those are in /etc/multipath/wwids. These ids should include the
|
||||||
|
+ * value printed from the sysfs wwid file.
|
||||||
|
+ */
|
||||||
|
+ _read_sys_vpd_wwids(cmd, dev, &dev->wwids);
|
||||||
|
+ if (!dm_list_empty(&dev->wwids))
|
||||||
|
+ goto lookup;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * This will read the sysfs wwid file, nvme devices in particular have
|
||||||
|
+ * a wwid file but not a vpd_pg83 file.
|
||||||
|
+ */
|
||||||
|
+ if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf)))
|
||||||
|
+ add_wwid(idbuf, 0, &dev->wwids);
|
||||||
|
+
|
||||||
|
+ lookup:
|
||||||
|
+ dm_list_iterate_items(dw, &dev->wwids) {
|
||||||
|
+ if (dw->type == 1 || dw->type == 2 || dw->type == 3)
|
||||||
|
+ wwid = &dw->id[4];
|
||||||
|
+ else
|
||||||
|
+ wwid = dw->id;
|
||||||
|
+
|
||||||
|
+ if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) {
|
||||||
|
+ log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
|
||||||
|
{
|
||||||
|
- if (_dev_is_mpath_component_sysfs(cmd, dev) == 1)
|
||||||
|
+ struct dev_types *dt = cmd->dev_types;
|
||||||
|
+ int primary_result;
|
||||||
|
+ dev_t primary_dev;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * multipath only uses SCSI or NVME devices
|
||||||
|
+ */
|
||||||
|
+ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * primary_result 2: dev is a partition, primary_dev is the whole device
|
||||||
|
+ * primary_result 1: dev is a whole device
|
||||||
|
+ */
|
||||||
|
+ primary_result = dev_get_primary_dev(dt, dev, &primary_dev);
|
||||||
|
+
|
||||||
|
+ if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev) == 1)
|
||||||
|
goto found;
|
||||||
|
|
||||||
|
- if (_dev_in_wwid_file(cmd, dev))
|
||||||
|
+ if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev))
|
||||||
|
goto found;
|
||||||
|
|
||||||
|
if (external_device_info_source() == DEV_EXT_UDEV) {
|
||||||
|
@@ -637,6 +787,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * TODO: save the result of this function in dev->flags and use those
|
||||||
|
+ * flags on repeated calls to avoid repeating the work multiple times
|
||||||
|
+ * for the same device when there are partitions on the device.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
found:
|
||||||
|
return 1;
|
||||||
|
diff --git a/lib/device/device.h b/lib/device/device.h
|
||||||
|
index 572994bb9..1c85f37a9 100644
|
||||||
|
--- a/lib/device/device.h
|
||||||
|
+++ b/lib/device/device.h
|
||||||
|
@@ -59,6 +59,14 @@ struct dev_ext {
|
||||||
|
void *handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
+#define DEV_WWID_SIZE 128
|
||||||
|
+
|
||||||
|
+struct dev_wwid {
|
||||||
|
+ struct dm_list list;
|
||||||
|
+ int type;
|
||||||
|
+ char id[DEV_WWID_SIZE];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#define DEV_ID_TYPE_SYS_WWID 0x0001
|
||||||
|
#define DEV_ID_TYPE_SYS_SERIAL 0x0002
|
||||||
|
#define DEV_ID_TYPE_MPATH_UUID 0x0003
|
||||||
|
@@ -105,6 +113,7 @@ struct dev_use {
|
||||||
|
*/
|
||||||
|
struct device {
|
||||||
|
struct dm_list aliases; /* struct dm_str_list */
|
||||||
|
+ struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */
|
||||||
|
struct dm_list ids; /* struct dev_id, different entries for different idtypes */
|
||||||
|
struct dev_id *id; /* points to the the ids entry being used for this dev */
|
||||||
|
dev_t dev;
|
||||||
|
@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev);
|
||||||
|
|
||||||
|
int dev_mpath_init(const char *config_wwids_file);
|
||||||
|
void dev_mpath_exit(void);
|
||||||
|
+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids);
|
||||||
|
+void free_wwids(struct dm_list *ids);
|
||||||
|
+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids);
|
||||||
|
+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 20901ab90..4d8fa5c9c 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize)
|
||||||
|
+static int _read_sys_block(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ const char *suffix, char *sysbuf, int sysbufsize,
|
||||||
|
+ int binary, int *retlen)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
dev_t devt = dev->dev;
|
||||||
|
@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- get_sysfs_value(path, sysbuf, sysbufsize, 0);
|
||||||
|
+ if (binary) {
|
||||||
|
+ ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen);
|
||||||
|
+ if (ret && !*retlen)
|
||||||
|
+ ret = 0;
|
||||||
|
+ } else {
|
||||||
|
+ ret = get_sysfs_value(path, sysbuf, sysbufsize, 0);
|
||||||
|
+ if (ret && !sysbuf[0])
|
||||||
|
+ ret = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (sysbuf[0]) {
|
||||||
|
- if (prim)
|
||||||
|
- log_debug("Using primary device_id for partition %s.", dev_name(dev));
|
||||||
|
+ if (ret) {
|
||||||
|
sysbuf[sysbufsize - 1] = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int read_sys_block(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ const char *suffix, char *sysbuf, int sysbufsize)
|
||||||
|
+{
|
||||||
|
+ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ const char *suffix, char *sysbuf, int sysbufsize,
|
||||||
|
+ int *retlen)
|
||||||
|
+{
|
||||||
|
+ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix)
|
||||||
|
{
|
||||||
|
if (!strncmp(sysbuf, prefix, strlen(prefix)))
|
||||||
|
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
|
||||||
|
index 2cd2fd7c6..e049e2333 100644
|
||||||
|
--- a/lib/device/device_id.h
|
||||||
|
+++ b/lib/device/device_id.h
|
||||||
|
@@ -55,6 +55,8 @@ void devices_file_exit(struct cmd_context *cmd);
|
||||||
|
void unlink_searched_devnames(struct cmd_context *cmd);
|
||||||
|
|
||||||
|
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
|
||||||
|
+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
|
||||||
|
+ const char *suffix, char *sysbuf, int sysbufsize, int *retlen);
|
||||||
|
|
||||||
|
int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
|
||||||
|
|
||||||
|
diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..4bafa7b9e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/lib/device/parse_vpd.c
|
||||||
|
@@ -0,0 +1,199 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2022 Red Hat, Inc. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * This file is part of LVM2.
|
||||||
|
+ *
|
||||||
|
+ * This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+ * modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+ * of the GNU Lesser General Public License v.2.1.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU Lesser General Public License
|
||||||
|
+ * along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "base/memory/zalloc.h"
|
||||||
|
+#include "lib/misc/lib.h"
|
||||||
|
+#include "lib/device/device.h"
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdarg.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/ioctl.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <dirent.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <assert.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Replace series of spaces with a single _.
|
||||||
|
+ */
|
||||||
|
+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
|
||||||
|
+{
|
||||||
|
+ int in_space = 0;
|
||||||
|
+ int retlen = 0;
|
||||||
|
+ int j = 0;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < in_bytes; i++) {
|
||||||
|
+ if (!in[i])
|
||||||
|
+ break;
|
||||||
|
+ if (j >= (out_bytes - 2))
|
||||||
|
+ break;
|
||||||
|
+ /* skip leading spaces */
|
||||||
|
+ if (!retlen && (in[i] == ' '))
|
||||||
|
+ continue;
|
||||||
|
+ /* replace one or more spaces with _ */
|
||||||
|
+ if (in[i] == ' ') {
|
||||||
|
+ in_space = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ /* spaces are finished so insert _ */
|
||||||
|
+ if (in_space) {
|
||||||
|
+ out[j++] = '_';
|
||||||
|
+ in_space = 0;
|
||||||
|
+ retlen++;
|
||||||
|
+ }
|
||||||
|
+ out[j++] = in[i];
|
||||||
|
+ retlen++;
|
||||||
|
+ }
|
||||||
|
+ return retlen;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
|
||||||
|
+{
|
||||||
|
+ int off = 0;
|
||||||
|
+ int num;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < in_bytes; i++) {
|
||||||
|
+ num = sprintf((char *)out + off, "%02x", in[i]);
|
||||||
|
+ if (num < 0)
|
||||||
|
+ break;
|
||||||
|
+ off += num;
|
||||||
|
+ if (off + 2 >= out_bytes)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return off;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define ID_BUFSIZE 1024
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * based on linux kernel function
|
||||||
|
+ */
|
||||||
|
+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids)
|
||||||
|
+{
|
||||||
|
+ char id[ID_BUFSIZE];
|
||||||
|
+ unsigned char tmp_str[ID_BUFSIZE];
|
||||||
|
+ const unsigned char *d, *cur_id_str;
|
||||||
|
+ size_t id_len = ID_BUFSIZE;
|
||||||
|
+ int id_size = -1;
|
||||||
|
+ uint8_t cur_id_size = 0;
|
||||||
|
+
|
||||||
|
+ memset(id, 0, ID_BUFSIZE);
|
||||||
|
+ for (d = vpd_data + 4;
|
||||||
|
+ d < vpd_data + vpd_datalen;
|
||||||
|
+ d += d[3] + 4) {
|
||||||
|
+ memset(tmp_str, 0, sizeof(tmp_str));
|
||||||
|
+
|
||||||
|
+ switch (d[1] & 0xf) {
|
||||||
|
+ case 0x1:
|
||||||
|
+ /* T10 Vendor ID */
|
||||||
|
+ cur_id_size = d[3];
|
||||||
|
+ if (cur_id_size + 4 > id_len)
|
||||||
|
+ cur_id_size = id_len - 4;
|
||||||
|
+ cur_id_str = d + 4;
|
||||||
|
+ format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str));
|
||||||
|
+ id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str);
|
||||||
|
+ if (id_size < 0)
|
||||||
|
+ break;
|
||||||
|
+ if (id_size >= ID_BUFSIZE)
|
||||||
|
+ id_size = ID_BUFSIZE - 1;
|
||||||
|
+ add_wwid(id, 1, ids);
|
||||||
|
+ break;
|
||||||
|
+ case 0x2:
|
||||||
|
+ /* EUI-64 */
|
||||||
|
+ cur_id_size = d[3];
|
||||||
|
+ cur_id_str = d + 4;
|
||||||
|
+ switch (cur_id_size) {
|
||||||
|
+ case 8:
|
||||||
|
+ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
|
||||||
|
+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
|
||||||
|
+ break;
|
||||||
|
+ case 12:
|
||||||
|
+ _to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str));
|
||||||
|
+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
|
||||||
|
+ break;
|
||||||
|
+ case 16:
|
||||||
|
+ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
|
||||||
|
+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (id_size < 0)
|
||||||
|
+ break;
|
||||||
|
+ if (id_size >= ID_BUFSIZE)
|
||||||
|
+ id_size = ID_BUFSIZE - 1;
|
||||||
|
+ add_wwid(id, 2, ids);
|
||||||
|
+ break;
|
||||||
|
+ case 0x3:
|
||||||
|
+ /* NAA */
|
||||||
|
+ cur_id_size = d[3];
|
||||||
|
+ cur_id_str = d + 4;
|
||||||
|
+ switch (cur_id_size) {
|
||||||
|
+ case 8:
|
||||||
|
+ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
|
||||||
|
+ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
|
||||||
|
+ break;
|
||||||
|
+ case 16:
|
||||||
|
+ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
|
||||||
|
+ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (id_size < 0)
|
||||||
|
+ break;
|
||||||
|
+ if (id_size >= ID_BUFSIZE)
|
||||||
|
+ id_size = ID_BUFSIZE - 1;
|
||||||
|
+ add_wwid(id, 3, ids);
|
||||||
|
+ break;
|
||||||
|
+ case 0x8:
|
||||||
|
+ /* SCSI name string */
|
||||||
|
+ cur_id_size = d[3];
|
||||||
|
+ cur_id_str = d + 4;
|
||||||
|
+ if (cur_id_size >= id_len)
|
||||||
|
+ cur_id_size = id_len - 1;
|
||||||
|
+ memcpy(id, cur_id_str, cur_id_size);
|
||||||
|
+ id_size = cur_id_size;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Not in the kernel version, copying multipath code,
|
||||||
|
+ * which checks if this string begins with naa or eui
|
||||||
|
+ * and if so does tolower() on the chars.
|
||||||
|
+ */
|
||||||
|
+ if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) {
|
||||||
|
+ int i;
|
||||||
|
+ for (i = 0; i < id_size; i++)
|
||||||
|
+ id[i] = tolower(id[i]);
|
||||||
|
+ }
|
||||||
|
+ add_wwid(id, 8, ids);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return id_size;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From e60d7ce8e748cb6d51552879c162d01aafa17160 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marian Csontos <mcsontos@redhat.com>
|
||||||
|
Date: Wed, 15 Jun 2022 11:53:51 +0200
|
||||||
|
Subject: [PATCH 54/54] build: Fix make rpm with VERSION_DM without dash
|
||||||
|
|
||||||
|
When building RPM from a branch based on a release tag the expected -git
|
||||||
|
suffix is missing breaking the script producing error like following one:
|
||||||
|
|
||||||
|
error: line 215: Unterminated rich dependency: (2021-53.ge36b180a6.el9: Requires: device-mapper-devel >= 1.02.181 (2021-53.ge36b180a6.el9
|
||||||
|
---
|
||||||
|
Makefile.in | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile.in b/Makefile.in
|
||||||
|
index 3b7e0ecaa..f7a46269a 100644
|
||||||
|
--- a/Makefile.in
|
||||||
|
+++ b/Makefile.in
|
||||||
|
@@ -110,7 +110,7 @@ rpm: dist
|
||||||
|
$(LN_S) -f $(abs_top_srcdir)/spec/build.inc $(rpmbuilddir)/SOURCES
|
||||||
|
$(LN_S) -f $(abs_top_srcdir)/spec/macros.inc $(rpmbuilddir)/SOURCES
|
||||||
|
$(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES
|
||||||
|
- DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\
|
||||||
|
+ DM_VER=$$(cut -d' ' -f1 $(top_srcdir)/VERSION_DM | cut -d- -f1);\
|
||||||
|
GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\
|
||||||
|
$(SED) -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
|
||||||
|
-e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,246 @@
|
|||||||
|
From 73b9a2805ca2f2c70f6f631b405f8fea3f72f23b Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 5 Jul 2022 17:08:00 -0500
|
||||||
|
Subject: [PATCH] exit with error when --devicesfile name doesn't exist
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/cache/lvmcache.c | 3 ++-
|
||||||
|
lib/label/label.c | 4 ++--
|
||||||
|
test/shell/devicesfile-basic.sh | 1 +
|
||||||
|
tools/pvcreate.c | 3 ++-
|
||||||
|
tools/pvremove.c | 3 ++-
|
||||||
|
tools/pvscan.c | 3 ++-
|
||||||
|
tools/toollib.c | 27 +++++++++++++++++++++------
|
||||||
|
tools/vgcfgrestore.c | 5 ++++-
|
||||||
|
tools/vgcreate.c | 5 ++++-
|
||||||
|
tools/vgextend.c | 3 ++-
|
||||||
|
tools/vgmerge.c | 3 ++-
|
||||||
|
tools/vgsplit.c | 3 ++-
|
||||||
|
12 files changed, 46 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
||||||
|
index 0e62cd267..61a2fee6d 100644
|
||||||
|
--- a/lib/cache/lvmcache.c
|
||||||
|
+++ b/lib/cache/lvmcache.c
|
||||||
|
@@ -1600,7 +1600,8 @@ int lvmcache_label_scan(struct cmd_context *cmd)
|
||||||
|
* with infos/vginfos based on reading headers from
|
||||||
|
* each device, and a vg summary from each mda.
|
||||||
|
*/
|
||||||
|
- label_scan(cmd);
|
||||||
|
+ if (!label_scan(cmd))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When devnames are used as device ids (which is dispreferred),
|
||||||
|
diff --git a/lib/label/label.c b/lib/label/label.c
|
||||||
|
index 06958b502..00ede2b76 100644
|
||||||
|
--- a/lib/label/label.c
|
||||||
|
+++ b/lib/label/label.c
|
||||||
|
@@ -800,7 +800,7 @@ static int _setup_bcache(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) {
|
||||||
|
- log_error("Failed to create bcache with %d cache blocks.", cache_blocks);
|
||||||
|
+ log_error("Failed to set up io layer with %d blocks.", cache_blocks);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1015,7 +1015,7 @@ int label_scan(struct cmd_context *cmd)
|
||||||
|
* data to invalidate.)
|
||||||
|
*/
|
||||||
|
if (!(iter = dev_iter_create(NULL, 0))) {
|
||||||
|
- log_error("Scanning failed to get devices.");
|
||||||
|
+ log_error("Failed to get device list.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while ((dev = dev_iter_get(cmd, iter))) {
|
||||||
|
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
|
||||||
|
index d1cfb6a35..2d197a73a 100644
|
||||||
|
--- a/test/shell/devicesfile-basic.sh
|
||||||
|
+++ b/test/shell/devicesfile-basic.sh
|
||||||
|
@@ -107,6 +107,7 @@ not vgs --devicesfile test.devices $vg2
|
||||||
|
# misspelled override name fails
|
||||||
|
not vgs --devicesfile doesnotexist $vg1
|
||||||
|
not vgs --devicesfile doesnotexist $vg2
|
||||||
|
+not vgs --devicesfile doesnotexist
|
||||||
|
|
||||||
|
# devicesfile and devices cannot be used together
|
||||||
|
not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1
|
||||||
|
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
|
||||||
|
index 71eb060a3..a1ef0e9e1 100644
|
||||||
|
--- a/tools/pvcreate.c
|
||||||
|
+++ b/tools/pvcreate.c
|
||||||
|
@@ -144,7 +144,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
|
||||||
|
cmd->create_edit_devices_file = 1;
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd))
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (!(handle = init_processing_handle(cmd, NULL))) {
|
||||||
|
log_error("Failed to initialize processing handle.");
|
||||||
|
diff --git a/tools/pvremove.c b/tools/pvremove.c
|
||||||
|
index 2dfdbd016..5c39ee0c7 100644
|
||||||
|
--- a/tools/pvremove.c
|
||||||
|
+++ b/tools/pvremove.c
|
||||||
|
@@ -45,7 +45,8 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
|
||||||
|
clear_hint_file(cmd);
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd))
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
|
||||||
|
/* When forcibly clearing a PV we don't care about a VG lock. */
|
||||||
|
if (pp.force == DONT_PROMPT_OVERRIDE)
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index 50d46051a..bce1fbb40 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -1626,7 +1626,8 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
* which we want 'pvscan --cache' to do, and that uses
|
||||||
|
* info from lvmcache, e.g. duplicate pv info.
|
||||||
|
*/
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
cmd->pvscan_recreate_hints = 0;
|
||||||
|
cmd->use_hints = 0;
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 01ba03658..210b3dca5 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -1601,7 +1601,10 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
|
||||||
|
|
||||||
|
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL);
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd)) {
|
||||||
|
+ ret_max = ECMD_FAILED;
|
||||||
|
+ goto_out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (argc) {
|
||||||
|
for (; opt < argc; opt++) {
|
||||||
|
@@ -2381,8 +2384,13 @@ int process_each_vg(struct cmd_context *cmd,
|
||||||
|
* Scan all devices to populate lvmcache with initial
|
||||||
|
* list of PVs and VGs.
|
||||||
|
*/
|
||||||
|
- if (!(read_flags & PROCESS_SKIP_SCAN))
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!(read_flags & PROCESS_SKIP_SCAN)) {
|
||||||
|
+ if (!lvmcache_label_scan(cmd)) {
|
||||||
|
+ ret_max = ECMD_FAILED;
|
||||||
|
+ goto_out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A list of all VGs on the system is needed when:
|
||||||
|
@@ -3932,7 +3940,10 @@ int process_each_lv(struct cmd_context *cmd,
|
||||||
|
* Scan all devices to populate lvmcache with initial
|
||||||
|
* list of PVs and VGs.
|
||||||
|
*/
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd)) {
|
||||||
|
+ ret_max = ECMD_FAILED;
|
||||||
|
+ goto_out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A list of all VGs on the system is needed when:
|
||||||
|
@@ -4568,8 +4579,12 @@ int process_each_pv(struct cmd_context *cmd,
|
||||||
|
goto_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!(read_flags & PROCESS_SKIP_SCAN))
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!(read_flags & PROCESS_SKIP_SCAN)) {
|
||||||
|
+ if (!lvmcache_label_scan(cmd)) {
|
||||||
|
+ ret_max = ECMD_FAILED;
|
||||||
|
+ goto_out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
|
||||||
|
ret_max = ret;
|
||||||
|
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
|
||||||
|
index e49313d14..9fcba89d4 100644
|
||||||
|
--- a/tools/vgcfgrestore.c
|
||||||
|
+++ b/tools/vgcfgrestore.c
|
||||||
|
@@ -132,7 +132,10 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
|
||||||
|
clear_hint_file(cmd);
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd)) {
|
||||||
|
+ unlock_vg(cmd, NULL, vg_name);
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
cmd->handles_unknown_segments = 1;
|
||||||
|
|
||||||
|
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
|
||||||
|
index dde3f1eac..14608777f 100644
|
||||||
|
--- a/tools/vgcreate.c
|
||||||
|
+++ b/tools/vgcreate.c
|
||||||
|
@@ -84,7 +84,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
|
||||||
|
cmd->create_edit_devices_file = 1;
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd)) {
|
||||||
|
+ unlock_vg(cmd, NULL, vp_new.vg_name);
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (lvmcache_vginfo_from_vgname(vp_new.vg_name, NULL)) {
|
||||||
|
unlock_vg(cmd, NULL, vp_new.vg_name);
|
||||||
|
diff --git a/tools/vgextend.c b/tools/vgextend.c
|
||||||
|
index 0856b4c78..fecd6bdd5 100644
|
||||||
|
--- a/tools/vgextend.c
|
||||||
|
+++ b/tools/vgextend.c
|
||||||
|
@@ -160,7 +160,8 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
|
||||||
|
cmd->edit_devices_file = 1;
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd))
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (!(handle = init_processing_handle(cmd, NULL))) {
|
||||||
|
log_error("Failed to initialize processing handle.");
|
||||||
|
diff --git a/tools/vgmerge.c b/tools/vgmerge.c
|
||||||
|
index 08615cd62..4ed4a8f0b 100644
|
||||||
|
--- a/tools/vgmerge.c
|
||||||
|
+++ b/tools/vgmerge.c
|
||||||
|
@@ -72,7 +72,8 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd))
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (strcmp(vg_name_to, vg_name_from) > 0)
|
||||||
|
lock_vg_from_first = 1;
|
||||||
|
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
|
||||||
|
index a085ac2ba..9d6534e89 100644
|
||||||
|
--- a/tools/vgsplit.c
|
||||||
|
+++ b/tools/vgsplit.c
|
||||||
|
@@ -559,7 +559,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
- lvmcache_label_scan(cmd);
|
||||||
|
+ if (!lvmcache_label_scan(cmd))
|
||||||
|
+ return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (!(vginfo_to = lvmcache_vginfo_from_vgname(vg_name_to, NULL))) {
|
||||||
|
if (!validate_name(vg_name_to)) {
|
||||||
|
--
|
||||||
|
2.34.3
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From 3f297c1b3bebcb8812db882f369fbb4c43f4ceb3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 25 Jul 2022 13:50:43 -0500
|
||||||
|
Subject: [PATCH] apply multipath_component_detection=0 to duplicate PV
|
||||||
|
handling
|
||||||
|
|
||||||
|
multipath_component_detection=0 has always applied to the filter-based
|
||||||
|
component detection. Also apply this setting to the duplicate-PV
|
||||||
|
handling which also eliminates multipath components (based on duplicate
|
||||||
|
PVs having the same wwid.)
|
||||||
|
|
||||||
|
(cherry picked from commit 99ce09ae778c2cc4aa2611e425bba5287b8b9513)
|
||||||
|
---
|
||||||
|
lib/cache/lvmcache.c | 3 +++
|
||||||
|
test/shell/duplicate-pvs-multipath.sh | 10 +++++++---
|
||||||
|
2 files changed, 10 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
||||||
|
index 61a2fee6d..04e9f0605 100644
|
||||||
|
--- a/lib/cache/lvmcache.c
|
||||||
|
+++ b/lib/cache/lvmcache.c
|
||||||
|
@@ -640,6 +640,9 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
|
||||||
|
|
||||||
|
*dev_mpath = NULL;
|
||||||
|
|
||||||
|
+ if (!find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
/* This function only makes sense with more than one dev. */
|
||||||
|
if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) {
|
||||||
|
log_debug("Skip multipath component checks with single device for PVID %s", pvid);
|
||||||
|
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
index 59c15b0d4..bc98d2d5a 100644
|
||||||
|
--- a/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
+++ b/test/shell/duplicate-pvs-multipath.sh
|
||||||
|
@@ -24,9 +24,13 @@ modprobe --dry-run scsi_debug || skip
|
||||||
|
multipath -l || skip
|
||||||
|
multipath -l | grep scsi_debug && skip
|
||||||
|
|
||||||
|
-# Turn off multipath_component_detection so that the duplicate
|
||||||
|
-# resolution of mpath components is used.
|
||||||
|
-aux lvmconf 'devices/multipath_component_detection = 0'
|
||||||
|
+# FIXME: setting multipath_component_detection=0 now also disables
|
||||||
|
+# the wwid-based mpath component detection, so this test will need
|
||||||
|
+# to find another way to disable only the filter-mpath code (using
|
||||||
|
+# sysfs and multipath/wwids) while keeping the code enabled that
|
||||||
|
+# eliminates duplicates based on their matching wwids which this
|
||||||
|
+# tries to test.
|
||||||
|
+
|
||||||
|
# Prevent wwids from being used for filtering.
|
||||||
|
aux lvmconf 'devices/multipath_wwids_file = "/dev/null"'
|
||||||
|
# Need to use /dev/mapper/mpath
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
From 87904fbbb84c10e6f733db1c5ba447537d1cf08c Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Fri, 19 Aug 2022 13:31:22 -0500
|
||||||
|
Subject: [PATCH 1/6] devices file: fix pvcreate --uuid matching pvid entry
|
||||||
|
with no device id
|
||||||
|
|
||||||
|
pvcreate with --uuid would segfault if a devices file entry matched
|
||||||
|
the specified pvid, but the devices file entry had no device_id, which
|
||||||
|
could happen if the entry has a devname idtype.
|
||||||
|
---
|
||||||
|
lib/device/device_id.c | 7 ++++---
|
||||||
|
test/shell/devicesfile-devname.sh | 13 +++++++++++++
|
||||||
|
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 4d8fa5c9c..c3816a66c 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1142,8 +1142,9 @@ id_done:
|
||||||
|
du_devname->devname);
|
||||||
|
|
||||||
|
if (du_pvid && (du_pvid->dev != dev))
|
||||||
|
- log_warn("WARNING: adding device %s with PVID %s which is already used for %s.",
|
||||||
|
- dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device");
|
||||||
|
+ log_warn("WARNING: adding device %s with PVID %s which is already used for %s device_id %s.",
|
||||||
|
+ dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device",
|
||||||
|
+ du_pvid->idname ?: "none");
|
||||||
|
|
||||||
|
if (du_devid && (du_devid->dev != dev)) {
|
||||||
|
if (!du_devid->dev) {
|
||||||
|
@@ -1189,7 +1190,7 @@ id_done:
|
||||||
|
else
|
||||||
|
check_idname = device_id_system_read(cmd, dev, du_pvid->idtype);
|
||||||
|
|
||||||
|
- if (check_idname && !strcmp(check_idname, du_pvid->idname)) {
|
||||||
|
+ if (!du_pvid->idname || (check_idname && !strcmp(check_idname, du_pvid->idname))) {
|
||||||
|
update_du = du_pvid;
|
||||||
|
dm_list_del(&update_du->list);
|
||||||
|
update_matching_kind = "PVID";
|
||||||
|
diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh
|
||||||
|
index 338637275..211f4dbed 100644
|
||||||
|
--- a/test/shell/devicesfile-devname.sh
|
||||||
|
+++ b/test/shell/devicesfile-devname.sh
|
||||||
|
@@ -550,6 +550,19 @@ vgchange -an $vg2
|
||||||
|
vgremove -ff $vg1
|
||||||
|
vgremove -ff $vg2
|
||||||
|
|
||||||
|
+# bz 2119473
|
||||||
|
+
|
||||||
|
+aux lvmconf "devices/search_for_devnames = \"none\""
|
||||||
|
+sed -e "s|DEVNAME=$dev1|DEVNAME=.|" "$ORIG" > tmp1.devices
|
||||||
|
+sed -e "s|IDNAME=$dev1|IDNAME=.|" tmp1.devices > "$DF"
|
||||||
|
+pvs
|
||||||
|
+lvmdevices
|
||||||
|
+pvcreate -ff --yes --uuid "$PVID1" --norestorefile $dev1
|
||||||
|
+grep "$PVID1" "$DF" |tee out
|
||||||
|
+grep "DEVNAME=$dev1" out
|
||||||
|
+grep "IDNAME=$dev1" out
|
||||||
|
+aux lvmconf "devices/search_for_devnames = \"auto\""
|
||||||
|
+
|
||||||
|
# devnames change so the new devname now refers to a filtered device,
|
||||||
|
# e.g. an mpath or md component, which is not scanned
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
From 73943825501daede9963bb5d15abbc4d36febb40 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Thu, 11 Aug 2022 11:44:58 +0200
|
||||||
|
Subject: [PATCH 2/6] lvconvert: correct test support for vdo-pool
|
||||||
|
|
||||||
|
(cherry picked from commit d0697be5004af0e040b1f746e619b8075350bc46)
|
||||||
|
---
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
lib/metadata/vdo_manip.c | 4 +++-
|
||||||
|
tools/lvconvert.c | 4 +++-
|
||||||
|
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 240234e4d..e626802ec 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.03.17 -
|
||||||
|
+===============================
|
||||||
|
+ Fix lvconvert --test --type vdo-pool execution.
|
||||||
|
+
|
||||||
|
Version 2.03.14 - 20th October 2021
|
||||||
|
===================================
|
||||||
|
Device scanning is skipping directories on different filesystems.
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index fa9c893cb..11a119a68 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -392,7 +392,9 @@ struct logical_volume *convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||||
|
|
||||||
|
/* Format data LV as VDO volume */
|
||||||
|
if (format) {
|
||||||
|
- if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) {
|
||||||
|
+ if (test_mode()) {
|
||||||
|
+ log_verbose("Test mode: Skipping formating of VDO pool volume.");
|
||||||
|
+ } else if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) {
|
||||||
|
log_error("Cannot format VDO pool volume %s.", display_lvname(data_lv));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index 3d4b24fe3..c1d373318 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -5482,7 +5482,9 @@ static int _lvconvert_to_vdopool_single(struct cmd_context *cmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vdo_pool_zero) {
|
||||||
|
- if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1, .do_wipe_signatures = 1,
|
||||||
|
+ if (test_mode()) {
|
||||||
|
+ log_verbose("Test mode: Skipping activation, zeroing and signature wiping.");
|
||||||
|
+ } else if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1, .do_wipe_signatures = 1,
|
||||||
|
.yes = arg_count(cmd, yes_ARG),
|
||||||
|
.force = arg_count(cmd, force_ARG)})) {
|
||||||
|
log_error("Aborting. Failed to wipe VDO data store.");
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
32
SOURCES/0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch
Normal file
32
SOURCES/0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From 0aa45120e92fe8b0f379d00f3a031e3c53feca43 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tony Asleson <tasleson@redhat.com>
|
||||||
|
Date: Wed, 24 Aug 2022 15:37:56 -0500
|
||||||
|
Subject: [PATCH 3/6] lvmdbusd: Set LVM_COMMAND_PROFILE=lvmdbusd
|
||||||
|
|
||||||
|
We need this to prevent lvm from interleaving the JSON output with errors
|
||||||
|
written to stderr.
|
||||||
|
|
||||||
|
(cherry picked from commit a5e6947d74f7b88f7f0df4328a923ad82a970634)
|
||||||
|
---
|
||||||
|
daemons/lvmdbusd/main.py | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py
|
||||||
|
index b0a82d492..eaea13ef8 100644
|
||||||
|
--- a/daemons/lvmdbusd/main.py
|
||||||
|
+++ b/daemons/lvmdbusd/main.py
|
||||||
|
@@ -112,8 +112,10 @@ def main():
|
||||||
|
|
||||||
|
use_session = os.getenv('LVMDBUSD_USE_SESSION', False)
|
||||||
|
|
||||||
|
- # Ensure that we get consistent output for parsing stdout/stderr
|
||||||
|
+ # Ensure that we get consistent output for parsing stdout/stderr and that we
|
||||||
|
+ # are using the lvmdbusd profile.
|
||||||
|
os.environ["LC_ALL"] = "C"
|
||||||
|
+ os.environ["LVM_COMMAND_PROFILE"] = "lvmdbusd"
|
||||||
|
|
||||||
|
cfg.args = parser.parse_args()
|
||||||
|
cfg.create_request_entry = RequestEntry
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,442 @@
|
|||||||
|
From f1d8c01dff3f8839355004e5fd77e9cd521e26cb Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Mon, 29 Aug 2022 15:17:36 -0500
|
||||||
|
Subject: [PATCH 1/4] vgimportdevices: change result when devices are not added
|
||||||
|
|
||||||
|
When using --all, if one VG is skipped, continue adding
|
||||||
|
other VGs, and do not return an error from the command
|
||||||
|
if some VGs are added. (A VG is skipped if it's missing PVs.)
|
||||||
|
|
||||||
|
If the command fails during devices file setup or device
|
||||||
|
scanning, then remove the devices file if it has been
|
||||||
|
newly created by the command, and exit with an error.
|
||||||
|
|
||||||
|
If devices from a named VG are not imported (e.g. the
|
||||||
|
VG is missing devices), then remove the devices file if
|
||||||
|
it has been newly created by the command, and exit with
|
||||||
|
an error.
|
||||||
|
|
||||||
|
If --all VGs are being imported, and no devices are found
|
||||||
|
to include in the devices file, then remove the devices
|
||||||
|
file if it has been newly created by the command, and
|
||||||
|
exit with an error.
|
||||||
|
---
|
||||||
|
test/shell/vgimportdevices.sh | 308 ++++++++++++++++++++++++++++++++++
|
||||||
|
tools/vgimportdevices.c | 41 +++--
|
||||||
|
2 files changed, 336 insertions(+), 13 deletions(-)
|
||||||
|
create mode 100644 test/shell/vgimportdevices.sh
|
||||||
|
|
||||||
|
diff --git a/test/shell/vgimportdevices.sh b/test/shell/vgimportdevices.sh
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..47363cec3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/shell/vgimportdevices.sh
|
||||||
|
@@ -0,0 +1,308 @@
|
||||||
|
+
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+
|
||||||
|
+# Copyright (C) 2020 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+# of the GNU General Public License v.2.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
+
|
||||||
|
+test_description='vgimportdevices'
|
||||||
|
+
|
||||||
|
+. lib/inittest
|
||||||
|
+
|
||||||
|
+aux prepare_devs 5
|
||||||
|
+
|
||||||
|
+DFDIR="$LVM_SYSTEM_DIR/devices"
|
||||||
|
+mkdir "$DFDIR" || true
|
||||||
|
+DF="$DFDIR/system.devices"
|
||||||
|
+
|
||||||
|
+aux lvmconf 'devices/use_devicesfile = 1'
|
||||||
|
+
|
||||||
|
+not ls "$DF"
|
||||||
|
+pvcreate "$dev1"
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vgimportdevices -a with no prev df
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# no devs found
|
||||||
|
+not vgimportdevices -a
|
||||||
|
+not ls "$DF"
|
||||||
|
+
|
||||||
|
+# one orphan pv, no vgs
|
||||||
|
+pvcreate "$dev1"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+not vgimportdevices -a
|
||||||
|
+not ls "$DF"
|
||||||
|
+
|
||||||
|
+# one complete vg
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# two complete vgs
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgcreate $vg2 "$dev2"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# one incomplete vg
|
||||||
|
+vgcreate $vg1 "$dev1" "$dev2"
|
||||||
|
+lvcreate -l1 -an $vg1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+not vgimportdevices -a
|
||||||
|
+not ls "$DF"
|
||||||
|
+vgs $vg1
|
||||||
|
+pvs "$dev2"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# three complete, one incomplete vg
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgcreate $vg2 "$dev2"
|
||||||
|
+vgcreate $vg3 "$dev3"
|
||||||
|
+vgcreate $vg4 "$dev4" "$dev5"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev5" bs=1M count=1
|
||||||
|
+vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+grep "$dev3" "$DF"
|
||||||
|
+not grep "$dev4" "$DF"
|
||||||
|
+not grep "$dev5" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev3" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev4" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vgimportdevices -a with existing df
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# no devs found
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+not vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+
|
||||||
|
+# one complete vg
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+vgcreate --devicesfile "" $vg2 "$dev2"
|
||||||
|
+not grep "$dev2" "$DF"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# two complete vgs
|
||||||
|
+vgcreate --devicesfile "" $vg1 "$dev1"
|
||||||
|
+vgcreate --devicesfile "" $vg2 "$dev2"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# one incomplete vg
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+vgcreate --devicesfile "" $vg2 "$dev2" "$dev3"
|
||||||
|
+not grep "$dev2" "$DF"
|
||||||
|
+not grep "$dev3" "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+not vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev3" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# import the same vg again
|
||||||
|
+vgcreate --devicesfile "" $vg1 "$dev1"
|
||||||
|
+not ls "$DF"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# import a series of vgs
|
||||||
|
+vgcreate --devicesfile "" $vg1 "$dev1"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+vgcreate --devicesfile "" $vg2 "$dev2"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+vgcreate --devicesfile "" $vg3 "$dev3"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+grep "$dev3" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev3" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vgimportdevices vg with no prev df
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# no devs found
|
||||||
|
+not vgimportdevices $vg1
|
||||||
|
+not ls "$DF"
|
||||||
|
+
|
||||||
|
+# one complete vg
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+vgimportdevices $vg1
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# two complete vgs
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgcreate $vg2 "$dev2"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+vgimportdevices $vg1
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+vgimportdevices $vg2
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev2" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# one incomplete vg
|
||||||
|
+vgcreate $vg1 "$dev1" "$dev2"
|
||||||
|
+lvcreate -l1 -an $vg1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+not vgimportdevices $vg1
|
||||||
|
+not ls "$DF"
|
||||||
|
+vgs $vg1
|
||||||
|
+pvs "$dev2"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# three complete, one incomplete vg
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgcreate $vg2 "$dev2"
|
||||||
|
+vgcreate $vg3 "$dev3"
|
||||||
|
+vgcreate $vg4 "$dev4" "$dev5"
|
||||||
|
+rm -f "$DF"
|
||||||
|
+dd if=/dev/zero of="$dev5" bs=1M count=1
|
||||||
|
+not vgimportdevices $vg4
|
||||||
|
+not ls "$DF"
|
||||||
|
+vgimportdevices $vg3
|
||||||
|
+ls "$DF"
|
||||||
|
+grep "$dev3" "$DF"
|
||||||
|
+not grep "$dev1" "$DF"
|
||||||
|
+not grep "$dev2" "$DF"
|
||||||
|
+not grep "$dev4" "$DF"
|
||||||
|
+not grep "$dev5" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev3" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev4" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vgimportdevices vg with existing df
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# vg not found
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+not vgimportdevices $vg2
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
+# vg incomplete
|
||||||
|
+vgcreate $vg1 "$dev1"
|
||||||
|
+vgimportdevices -a
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+vgcreate --devicesfile "" $vg2 "$dev2" "$dev3"
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+not vgimportdevices $vg2
|
||||||
|
+grep "$dev1" "$DF"
|
||||||
|
+not grep "$dev2" "$DF"
|
||||||
|
+not grep "$dev3" "$DF"
|
||||||
|
+
|
||||||
|
+# reset
|
||||||
|
+dd if=/dev/zero of="$dev1" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev2" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev3" bs=1M count=1
|
||||||
|
+dd if=/dev/zero of="$dev4" bs=1M count=1
|
||||||
|
+rm -f "$DF"
|
||||||
|
+
|
||||||
|
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
||||||
|
index ea205d941..9ade1b9e4 100644
|
||||||
|
--- a/tools/vgimportdevices.c
|
||||||
|
+++ b/tools/vgimportdevices.c
|
||||||
|
@@ -36,9 +36,9 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
||||||
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
|
if (is_missing_pv(pvl->pv) || !pvl->pv->dev) {
|
||||||
|
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
|
||||||
|
- log_error("Not importing devices for VG %s with missing PV %s.",
|
||||||
|
- vg->name, pvid);
|
||||||
|
- goto bad;
|
||||||
|
+ log_print("Not importing devices for VG %s with missing PV %s.",
|
||||||
|
+ vg->name, pvid);
|
||||||
|
+ return ECMD_PROCESSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -71,14 +71,17 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
||||||
|
updated_pvs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Writes the device_id of each PV into the vg metadata.
|
||||||
|
+ * This is not a critial step and should not influence
|
||||||
|
+ * the result of the command.
|
||||||
|
+ */
|
||||||
|
if (updated_pvs) {
|
||||||
|
if (!vg_write(vg) || !vg_commit(vg))
|
||||||
|
- goto_bad;
|
||||||
|
+ log_print("Failed to write device ids in VG metadata.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ECMD_PROCESSED;
|
||||||
|
-bad:
|
||||||
|
- return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -114,6 +117,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct vgimportdevices_params vp = { 0 };
|
||||||
|
struct processing_handle *handle;
|
||||||
|
+ int created_file = 0;
|
||||||
|
int ret = ECMD_FAILED;
|
||||||
|
|
||||||
|
if (arg_is_set(cmd, foreign_ARG))
|
||||||
|
@@ -139,9 +143,12 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
log_error("Devices file not enabled.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
- if (!devices_file_exists(cmd) && !devices_file_touch(cmd)) {
|
||||||
|
- log_error("Failed to create devices file.");
|
||||||
|
- return ECMD_FAILED;
|
||||||
|
+ if (!devices_file_exists(cmd)) {
|
||||||
|
+ if (!devices_file_touch(cmd)) {
|
||||||
|
+ log_error("Failed to create devices file.");
|
||||||
|
+ return ECMD_FAILED;
|
||||||
|
+ }
|
||||||
|
+ created_file = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -195,22 +202,30 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
*/
|
||||||
|
ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE,
|
||||||
|
0, handle, _vgimportdevices_single);
|
||||||
|
- if (ret == ECMD_FAILED)
|
||||||
|
- goto out;
|
||||||
|
+ if (ret == ECMD_FAILED) {
|
||||||
|
+ /*
|
||||||
|
+ * Error from setting up devices file or label_scan,
|
||||||
|
+ * _vgimportdevices_single does not return an error.
|
||||||
|
+ */
|
||||||
|
+ goto_out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!vp.added_devices) {
|
||||||
|
- log_print("No devices to add.");
|
||||||
|
+ log_error("No devices to add.");
|
||||||
|
+ ret = ECMD_FAILED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_ids_write(cmd)) {
|
||||||
|
- log_print("Failed to update devices file.");
|
||||||
|
+ log_error("Failed to write the devices file.");
|
||||||
|
ret = ECMD_FAILED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_print("Added %u devices to devices file.", vp.added_devices);
|
||||||
|
out:
|
||||||
|
+ if ((ret == ECMD_FAILED) && created_file)
|
||||||
|
+ unlink(cmd->devices_file_path);
|
||||||
|
destroy_processing_handle(cmd, handle);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,76 @@
|
|||||||
|
From 0b9d9963b8f15a6f12a0149a62809fa9b846c5c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 30 Aug 2022 14:40:48 -0500
|
||||||
|
Subject: [PATCH 2/4] vgimportdevices: fix locking when creating devices file
|
||||||
|
|
||||||
|
Take the devices file lock before creating a new devices file.
|
||||||
|
(Was missed by the change to preemptively create the devices
|
||||||
|
file prior to setup_devices(), which was done to improve the
|
||||||
|
error path.)
|
||||||
|
---
|
||||||
|
lib/device/dev-cache.c | 7 +++----
|
||||||
|
lib/device/device_id.c | 1 +
|
||||||
|
tools/vgimportdevices.c | 10 ++++++++--
|
||||||
|
3 files changed, 12 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
|
||||||
|
index 65e1cb138..0c9aaf785 100644
|
||||||
|
--- a/lib/device/dev-cache.c
|
||||||
|
+++ b/lib/device/dev-cache.c
|
||||||
|
@@ -1956,10 +1956,9 @@ static int _setup_devices(struct cmd_context *cmd, int no_file_match)
|
||||||
|
|
||||||
|
if (!file_exists) {
|
||||||
|
/*
|
||||||
|
- * pvcreate/vgcreate/vgimportdevices/lvmdevices-add create
|
||||||
|
- * a new devices file here if it doesn't exist.
|
||||||
|
- * They have the create_edit_devices_file flag set.
|
||||||
|
- * First they create/lock-ex the devices file lockfile.
|
||||||
|
+ * pvcreate/vgcreate create a new devices file here if it
|
||||||
|
+ * doesn't exist. They have create_edit_devices_file=1.
|
||||||
|
+ * First create/lock-ex the devices file lockfile.
|
||||||
|
* Other commands will not use a devices file if none exists.
|
||||||
|
*/
|
||||||
|
lock_mode = LOCK_EX;
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index c3816a66c..780e08404 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -2429,6 +2429,7 @@ static int _lock_devices_file(struct cmd_context *cmd, int mode, int nonblock, i
|
||||||
|
|
||||||
|
if (_devices_file_locked == mode) {
|
||||||
|
/* can happen when a command holds an ex lock and does an update in device_ids_validate */
|
||||||
|
+ /* can happen when vgimportdevices calls this directly, followed later by setup_devices */
|
||||||
|
if (held)
|
||||||
|
*held = 1;
|
||||||
|
return 1;
|
||||||
|
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
||||||
|
index 9ade1b9e4..23c2718ff 100644
|
||||||
|
--- a/tools/vgimportdevices.c
|
||||||
|
+++ b/tools/vgimportdevices.c
|
||||||
|
@@ -132,8 +132,10 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Prepare devices file preemptively because the error path for this
|
||||||
|
- * case from process_each is not as clean.
|
||||||
|
+ * Prepare/create devices file preemptively because the error path for
|
||||||
|
+ * this case from process_each/setup_devices is not as clean.
|
||||||
|
+ * This means that when setup_devices is called, it the devices
|
||||||
|
+ * file steps will be redundant, and need to handle being repeated.
|
||||||
|
*/
|
||||||
|
if (!setup_devices_file(cmd)) {
|
||||||
|
log_error("Failed to set up devices file.");
|
||||||
|
@@ -143,6 +145,10 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
log_error("Devices file not enabled.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
+ if (!lock_devices_file(cmd, LOCK_EX)) {
|
||||||
|
+ log_error("Failed to lock the devices file.");
|
||||||
|
+ return ECMD_FAILED;
|
||||||
|
+ }
|
||||||
|
if (!devices_file_exists(cmd)) {
|
||||||
|
if (!devices_file_touch(cmd)) {
|
||||||
|
log_error("Failed to create devices file.");
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,132 @@
|
|||||||
|
From 7db3a53d8a3aa7401337fb9aaf00f19cf4407e70 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Wed, 30 Mar 2022 14:16:11 +0200
|
||||||
|
Subject: [PATCH 3/4] thin: fix message processing on thin-pool extension
|
||||||
|
|
||||||
|
When thin-pool had queued some delete message on extension operation
|
||||||
|
such message has been 'lost' and thin-pool kernel metadata has been
|
||||||
|
left with a thin volume that no longer existed for lvm2 metadata.
|
||||||
|
|
||||||
|
(cherry picked from commit 09371131469f7398c597a5fb30dc565859253cc2)
|
||||||
|
---
|
||||||
|
WHATS_NEW | 4 ++
|
||||||
|
lib/metadata/lv_manip.c | 2 +-
|
||||||
|
test/shell/lvextend-thin-adddel.sh | 78 ++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 83 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 test/shell/lvextend-thin-adddel.sh
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index e626802ec..bffd24648 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -2,6 +2,10 @@ Version 2.03.17 -
|
||||||
|
===============================
|
||||||
|
Fix lvconvert --test --type vdo-pool execution.
|
||||||
|
|
||||||
|
+Version 2.03.16 -
|
||||||
|
+====================================
|
||||||
|
+ Fix lossing of delete message on thin-pool extension.
|
||||||
|
+
|
||||||
|
Version 2.03.14 - 20th October 2021
|
||||||
|
===================================
|
||||||
|
Device scanning is skipping directories on different filesystems.
|
||||||
|
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
||||||
|
index 003748d6f..9523e3e66 100644
|
||||||
|
--- a/lib/metadata/lv_manip.c
|
||||||
|
+++ b/lib/metadata/lv_manip.c
|
||||||
|
@@ -6179,7 +6179,7 @@ int lv_resize(struct logical_volume *lv,
|
||||||
|
|
||||||
|
if (lv_is_thin_pool(lock_lv)) {
|
||||||
|
/* Update lvm pool metadata (drop messages). */
|
||||||
|
- if (!update_pool_lv(lock_lv, 0))
|
||||||
|
+ if (!update_pool_lv(lock_lv, 1))
|
||||||
|
goto_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/test/shell/lvextend-thin-adddel.sh b/test/shell/lvextend-thin-adddel.sh
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..59b1bfa41
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/shell/lvextend-thin-adddel.sh
|
||||||
|
@@ -0,0 +1,78 @@
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+
|
||||||
|
+# Copyright (C) 2022 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+# of the GNU General Public License v.2.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Play with thin-pool and thin removal and creation in corner cases
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+SKIP_WITH_LVMLOCKD=1
|
||||||
|
+SKIP_WITH_LVMPOLLD=1
|
||||||
|
+
|
||||||
|
+export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
|
||||||
|
+
|
||||||
|
+. lib/inittest
|
||||||
|
+
|
||||||
|
+aux have_thin 1 0 0 || skip
|
||||||
|
+
|
||||||
|
+test -n "$LVM_TEST_THIN_RESTORE_CMD" || LVM_TEST_THIN_RESTORE_CMD=$(which thin_restore) || skip
|
||||||
|
+"$LVM_TEST_THIN_RESTORE_CMD" -V || skip
|
||||||
|
+
|
||||||
|
+aux have_thin 1 10 0 || skip
|
||||||
|
+
|
||||||
|
+aux prepare_vg 2
|
||||||
|
+
|
||||||
|
+lvcreate -V10 -n $lv1 -L10 -T $vg/pool
|
||||||
|
+lvcreate -V10 -n $lv2 $vg/pool
|
||||||
|
+
|
||||||
|
+# Forcibly 'error' _tmeta thin-pool metadata device
|
||||||
|
+not dmsetup remove -f $vg-pool_tmeta
|
||||||
|
+
|
||||||
|
+# Now try to schedule removal of thin volume id 1
|
||||||
|
+# that will fail with errored meta device
|
||||||
|
+not lvremove -y $vg/$lv1
|
||||||
|
+
|
||||||
|
+# Check we have queued 'message'
|
||||||
|
+vgcfgbackup -f out0 $vg
|
||||||
|
+grep "message1" out0
|
||||||
|
+
|
||||||
|
+vgchange -an $vg || true
|
||||||
|
+
|
||||||
|
+not dmsetup table ${vg}-pool-tpool
|
||||||
|
+
|
||||||
|
+# Reactivate thin-pool
|
||||||
|
+vgchange -ay $vg
|
||||||
|
+
|
||||||
|
+# Check message is still queued there
|
||||||
|
+vgcfgbackup -f out1 $vg
|
||||||
|
+grep "message1" out1
|
||||||
|
+
|
||||||
|
+lvchange -an $vg
|
||||||
|
+
|
||||||
|
+lvextend -L+10 $vg/pool
|
||||||
|
+
|
||||||
|
+# Messages should be now processed and gone
|
||||||
|
+vgcfgbackup -f out2 $vg
|
||||||
|
+not grep "message1" out2
|
||||||
|
+
|
||||||
|
+lvchange -an $vg
|
||||||
|
+
|
||||||
|
+lvchange -y -ay $vg/pool_tmeta
|
||||||
|
+
|
||||||
|
+# Kernel metadata must not see dev_id 1 either
|
||||||
|
+thin_dump $DM_DEV_DIR/$vg/pool_tmeta | tee meta
|
||||||
|
+not grep 'dev_id="1"' meta
|
||||||
|
+
|
||||||
|
+lvremove -ff $vg
|
||||||
|
+
|
||||||
|
+lvs -a $vg
|
||||||
|
+
|
||||||
|
+vgremove -ff $vg
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
52
SOURCES/0064-vdo-fix-vdosettings-parser.patch
Normal file
52
SOURCES/0064-vdo-fix-vdosettings-parser.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From b56e8fc94d4d2b6d384148e3f74c54f4e1d816e6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Mon, 15 Aug 2022 13:14:03 +0200
|
||||||
|
Subject: [PATCH 4/4] vdo: fix --vdosettings parser
|
||||||
|
|
||||||
|
Parser was incorrectly parsing vdo_use_features - move the skip
|
||||||
|
of 'use_' prefix into internal loop which handles skipping of '_'.
|
||||||
|
|
||||||
|
(cherry picked from commit bba96e8680ef7fa567d6361c269c0bfc05ce3d2c)
|
||||||
|
---
|
||||||
|
tools/toollib.c | 14 +++++++++-----
|
||||||
|
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 210b3dca5..d9a1a92ec 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -1198,13 +1198,11 @@ out:
|
||||||
|
*/
|
||||||
|
static int _compare_vdo_option(const char *b1, const char *b2)
|
||||||
|
{
|
||||||
|
+ int use_skipped = 0;
|
||||||
|
+
|
||||||
|
if (strncasecmp(b1, "vdo", 3) == 0) // skip vdo prefix
|
||||||
|
b1 += 3;
|
||||||
|
|
||||||
|
- if ((tolower(*b1) != tolower(*b2)) &&
|
||||||
|
- (strncmp(b2, "use_", 4) == 0))
|
||||||
|
- b2 += 4; // try again with skipped prefix 'use_'
|
||||||
|
-
|
||||||
|
while (*b1 && *b2) {
|
||||||
|
if (tolower(*b1) == tolower(*b2)) {
|
||||||
|
++b1;
|
||||||
|
@@ -1216,8 +1214,14 @@ static int _compare_vdo_option(const char *b1, const char *b2)
|
||||||
|
++b1; // skip to next char
|
||||||
|
else if (*b2 == '_')
|
||||||
|
++b2; // skip to next char
|
||||||
|
- else
|
||||||
|
+ else {
|
||||||
|
+ if (!use_skipped++ && (strncmp(b2, "use_", 4) == 0)) {
|
||||||
|
+ b2 += 4; // try again with skipped prefix 'use_'
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
break; // mismatch
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*b1 || *b2) ? 0 : 1;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
921
SOURCES/0065-make-generate.patch
Normal file
921
SOURCES/0065-make-generate.patch
Normal file
@ -0,0 +1,921 @@
|
|||||||
|
From 71354c39350b482ca8cf0fd9dcaf025b1d55b7d1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marian Csontos <mcsontos@redhat.com>
|
||||||
|
Date: Thu, 8 Dec 2022 14:32:23 +0100
|
||||||
|
Subject: [PATCH] make: generate
|
||||||
|
|
||||||
|
---
|
||||||
|
man/lvchange.8_pregen | 20 ++++++++++++++++++--
|
||||||
|
man/lvconvert.8_pregen | 22 ++++++++++++++++++++--
|
||||||
|
man/lvcreate.8_pregen | 24 ++++++++++++++++++++++--
|
||||||
|
man/lvdisplay.8_pregen | 5 +++--
|
||||||
|
man/lvextend.8_pregen | 5 +++--
|
||||||
|
man/lvm-fullreport.8_pregen | 5 +++--
|
||||||
|
man/lvm-lvpoll.8_pregen | 5 +++--
|
||||||
|
man/lvmconfig.8_pregen | 5 +++--
|
||||||
|
man/lvmdevices.8_pregen | 8 +++++---
|
||||||
|
man/lvmdiskscan.8_pregen | 5 +++--
|
||||||
|
man/lvreduce.8_pregen | 5 +++--
|
||||||
|
man/lvremove.8_pregen | 5 +++--
|
||||||
|
man/lvrename.8_pregen | 5 +++--
|
||||||
|
man/lvresize.8_pregen | 5 +++--
|
||||||
|
man/lvs.8_pregen | 5 +++--
|
||||||
|
man/lvscan.8_pregen | 5 +++--
|
||||||
|
man/pvchange.8_pregen | 5 +++--
|
||||||
|
man/pvck.8_pregen | 5 +++--
|
||||||
|
man/pvcreate.8_pregen | 5 +++--
|
||||||
|
man/pvdisplay.8_pregen | 5 +++--
|
||||||
|
man/pvmove.8_pregen | 5 +++--
|
||||||
|
man/pvremove.8_pregen | 5 +++--
|
||||||
|
man/pvresize.8_pregen | 5 +++--
|
||||||
|
man/pvs.8_pregen | 5 +++--
|
||||||
|
man/pvscan.8_pregen | 5 +++--
|
||||||
|
man/vgcfgbackup.8_pregen | 5 +++--
|
||||||
|
man/vgcfgrestore.8_pregen | 5 +++--
|
||||||
|
man/vgchange.8_pregen | 5 +++--
|
||||||
|
man/vgck.8_pregen | 5 +++--
|
||||||
|
man/vgconvert.8_pregen | 5 +++--
|
||||||
|
man/vgcreate.8_pregen | 5 +++--
|
||||||
|
man/vgdisplay.8_pregen | 5 +++--
|
||||||
|
man/vgexport.8_pregen | 5 +++--
|
||||||
|
man/vgextend.8_pregen | 5 +++--
|
||||||
|
man/vgimport.8_pregen | 5 +++--
|
||||||
|
man/vgimportclone.8_pregen | 5 +++--
|
||||||
|
man/vgimportdevices.8_pregen | 5 +++--
|
||||||
|
man/vgmerge.8_pregen | 5 +++--
|
||||||
|
man/vgmknodes.8_pregen | 5 +++--
|
||||||
|
man/vgreduce.8_pregen | 5 +++--
|
||||||
|
man/vgremove.8_pregen | 5 +++--
|
||||||
|
man/vgrename.8_pregen | 5 +++--
|
||||||
|
man/vgs.8_pregen | 5 +++--
|
||||||
|
man/vgscan.8_pregen | 5 +++--
|
||||||
|
man/vgsplit.8_pregen | 5 +++--
|
||||||
|
45 files changed, 188 insertions(+), 91 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/lvchange.8_pregen b/man/lvchange.8_pregen
|
||||||
|
index b559c89c9..27bee0f14 100644
|
||||||
|
--- a/man/lvchange.8_pregen
|
||||||
|
+++ b/man/lvchange.8_pregen
|
||||||
|
@@ -126,6 +126,8 @@ lvchange \(em Change the attributes of logical volume(s)
|
||||||
|
\fB--sysinit\fP
|
||||||
|
.br
|
||||||
|
\fB-t\fP|\fB--test\fP
|
||||||
|
+.br
|
||||||
|
+ \fB--vdosettings\fP \fIString\fP
|
||||||
|
.br
|
||||||
|
\fB-v\fP|\fB--verbose\fP
|
||||||
|
.br
|
||||||
|
@@ -202,6 +204,8 @@ required, after which the others are optional.
|
||||||
|
\fB--\fP[\fBraid\fP]\fBminrecoveryrate\fP \fISize\fP[k|UNIT]
|
||||||
|
.br
|
||||||
|
\fB--\fP[\fBraid\fP]\fBmaxrecoveryrate\fP \fISize\fP[k|UNIT]
|
||||||
|
+.br
|
||||||
|
+ \fB--vdosettings\fP \fIString\fP
|
||||||
|
.br
|
||||||
|
\fB--\fP[\fBraid\fP]\fBwritebehind\fP \fINumber\fP
|
||||||
|
.br
|
||||||
|
@@ -609,8 +613,9 @@ See \fBlvm.conf\fP(5) for more information about profiles.
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
@@ -927,6 +932,17 @@ error messages in multi-stage operations if a tool relies on reading
|
||||||
|
back metadata it believes has changed but hasn't.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
+\fB--vdosettings\fP \fIString\fP
|
||||||
|
+.br
|
||||||
|
+Specifies tunable VDO options for VDO LVs.
|
||||||
|
+Use the form 'option=value' or 'option1=value option2=value', or
|
||||||
|
+repeat --vdosettings for each option being set.
|
||||||
|
+These settings override the default VDO behaviors.
|
||||||
|
+To remove vdosettings and revert to the default
|
||||||
|
+VDO behaviors, use --vdosettings 'default'.
|
||||||
|
+See \fBlvmvdo\fP(7) for more information.
|
||||||
|
+.
|
||||||
|
+.HP
|
||||||
|
\fB-v\fP|\fB--verbose\fP ...
|
||||||
|
.br
|
||||||
|
Set verbose level. Repeat from 1 to 4 times to increase the detail
|
||||||
|
diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen
|
||||||
|
index 679519303..fa52da55c 100644
|
||||||
|
--- a/man/lvconvert.8_pregen
|
||||||
|
+++ b/man/lvconvert.8_pregen
|
||||||
|
@@ -155,6 +155,8 @@ lvconvert \(em Change logical volume layout
|
||||||
|
\fB--usepolicies\fP
|
||||||
|
.br
|
||||||
|
\fB--vdopool\fP \fILV\fP
|
||||||
|
+.br
|
||||||
|
+ \fB--vdosettings\fP \fIString\fP
|
||||||
|
.br
|
||||||
|
\fB-v\fP|\fB--verbose\fP
|
||||||
|
.br
|
||||||
|
@@ -742,6 +744,8 @@ Convert LV to type vdopool.
|
||||||
|
.br
|
||||||
|
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
|
||||||
|
.br
|
||||||
|
+[ \fB--vdosettings\fP \fIString\fP ]
|
||||||
|
+.br
|
||||||
|
[ COMMON_OPTIONS ]
|
||||||
|
.ad b
|
||||||
|
.RE
|
||||||
|
@@ -1131,8 +1135,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
@@ -1535,6 +1540,17 @@ The name of a VDO pool LV.
|
||||||
|
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
+\fB--vdosettings\fP \fIString\fP
|
||||||
|
+.br
|
||||||
|
+Specifies tunable VDO options for VDO LVs.
|
||||||
|
+Use the form 'option=value' or 'option1=value option2=value', or
|
||||||
|
+repeat --vdosettings for each option being set.
|
||||||
|
+These settings override the default VDO behaviors.
|
||||||
|
+To remove vdosettings and revert to the default
|
||||||
|
+VDO behaviors, use --vdosettings 'default'.
|
||||||
|
+See \fBlvmvdo\fP(7) for more information.
|
||||||
|
+.
|
||||||
|
+.HP
|
||||||
|
\fB-v\fP|\fB--verbose\fP ...
|
||||||
|
.br
|
||||||
|
Set verbose level. Repeat from 1 to 4 times to increase the detail
|
||||||
|
@@ -1808,6 +1824,8 @@ Convert LV to type vdopool.
|
||||||
|
.br
|
||||||
|
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
|
||||||
|
.br
|
||||||
|
+[ \fB--vdosettings\fP \fIString\fP ]
|
||||||
|
+.br
|
||||||
|
[ COMMON_OPTIONS ]
|
||||||
|
.ad b
|
||||||
|
.RE
|
||||||
|
diff --git a/man/lvcreate.8_pregen b/man/lvcreate.8_pregen
|
||||||
|
index 2cccbbe56..0ffe92a94 100644
|
||||||
|
--- a/man/lvcreate.8_pregen
|
||||||
|
+++ b/man/lvcreate.8_pregen
|
||||||
|
@@ -157,6 +157,8 @@ lvcreate \(em Create a logical volume
|
||||||
|
\fB--vdo\fP
|
||||||
|
.br
|
||||||
|
\fB--vdopool\fP \fILV\fP
|
||||||
|
+.br
|
||||||
|
+ \fB--vdosettings\fP \fIString\fP
|
||||||
|
.br
|
||||||
|
\fB-v\fP|\fB--verbose\fP
|
||||||
|
.br
|
||||||
|
@@ -537,6 +539,8 @@ Create a LV that returns VDO when used.
|
||||||
|
.br
|
||||||
|
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
|
||||||
|
.br
|
||||||
|
+[ \fB--vdosettings\fP \fIString\fP ]
|
||||||
|
+.br
|
||||||
|
[ COMMON_OPTIONS ]
|
||||||
|
.ad b
|
||||||
|
.RE
|
||||||
|
@@ -1003,8 +1007,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
@@ -1438,6 +1443,17 @@ The name of a VDO pool LV.
|
||||||
|
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
+\fB--vdosettings\fP \fIString\fP
|
||||||
|
+.br
|
||||||
|
+Specifies tunable VDO options for VDO LVs.
|
||||||
|
+Use the form 'option=value' or 'option1=value option2=value', or
|
||||||
|
+repeat --vdosettings for each option being set.
|
||||||
|
+These settings override the default VDO behaviors.
|
||||||
|
+To remove vdosettings and revert to the default
|
||||||
|
+VDO behaviors, use --vdosettings 'default'.
|
||||||
|
+See \fBlvmvdo\fP(7) for more information.
|
||||||
|
+.
|
||||||
|
+.HP
|
||||||
|
\fB-v\fP|\fB--verbose\fP ...
|
||||||
|
.br
|
||||||
|
Set verbose level. Repeat from 1 to 4 times to increase the detail
|
||||||
|
@@ -1966,6 +1982,8 @@ Create a VDO LV with VDO pool.
|
||||||
|
.br
|
||||||
|
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
|
||||||
|
.br
|
||||||
|
+[ \fB--vdosettings\fP \fIString\fP ]
|
||||||
|
+.br
|
||||||
|
[ COMMON_OPTIONS ]
|
||||||
|
.ad b
|
||||||
|
.RE
|
||||||
|
@@ -1996,6 +2014,8 @@ Create a VDO LV with VDO pool.
|
||||||
|
.br
|
||||||
|
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
|
||||||
|
.br
|
||||||
|
+[ \fB--vdosettings\fP \fIString\fP ]
|
||||||
|
+.br
|
||||||
|
[ COMMON_OPTIONS ]
|
||||||
|
.ad b
|
||||||
|
.RE
|
||||||
|
diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen
|
||||||
|
index 04aab4c09..387a7d30d 100644
|
||||||
|
--- a/man/lvdisplay.8_pregen
|
||||||
|
+++ b/man/lvdisplay.8_pregen
|
||||||
|
@@ -186,8 +186,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvextend.8_pregen b/man/lvextend.8_pregen
|
||||||
|
index be6992e94..8a3e1ea4e 100644
|
||||||
|
--- a/man/lvextend.8_pregen
|
||||||
|
+++ b/man/lvextend.8_pregen
|
||||||
|
@@ -328,8 +328,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvm-fullreport.8_pregen b/man/lvm-fullreport.8_pregen
|
||||||
|
index 02b38ef40..edae0efe3 100644
|
||||||
|
--- a/man/lvm-fullreport.8_pregen
|
||||||
|
+++ b/man/lvm-fullreport.8_pregen
|
||||||
|
@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvm-lvpoll.8_pregen b/man/lvm-lvpoll.8_pregen
|
||||||
|
index 7f45f6eb3..fa8027f8e 100644
|
||||||
|
--- a/man/lvm-lvpoll.8_pregen
|
||||||
|
+++ b/man/lvm-lvpoll.8_pregen
|
||||||
|
@@ -115,8 +115,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvmconfig.8_pregen b/man/lvmconfig.8_pregen
|
||||||
|
index 51946e1ec..e6762f989 100644
|
||||||
|
--- a/man/lvmconfig.8_pregen
|
||||||
|
+++ b/man/lvmconfig.8_pregen
|
||||||
|
@@ -156,8 +156,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvmdevices.8_pregen b/man/lvmdevices.8_pregen
|
||||||
|
index d64c3a31a..a2397e50f 100644
|
||||||
|
--- a/man/lvmdevices.8_pregen
|
||||||
|
+++ b/man/lvmdevices.8_pregen
|
||||||
|
@@ -322,7 +322,8 @@ Find a device with the PVID and add the device to the devices file.
|
||||||
|
.HP
|
||||||
|
\fB--check\fP
|
||||||
|
.br
|
||||||
|
-Check the content of the devices file.
|
||||||
|
+Checks the content of the devices file.
|
||||||
|
+Reports incorrect device names or PVIDs for entries.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
\fB--commandprofile\fP \fIString\fP
|
||||||
|
@@ -364,8 +365,9 @@ then it will override the default type that lvm would use.
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvmdiskscan.8_pregen b/man/lvmdiskscan.8_pregen
|
||||||
|
index 7fd3d941d..ac0931c88 100644
|
||||||
|
--- a/man/lvmdiskscan.8_pregen
|
||||||
|
+++ b/man/lvmdiskscan.8_pregen
|
||||||
|
@@ -102,8 +102,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvreduce.8_pregen b/man/lvreduce.8_pregen
|
||||||
|
index ea960eb53..cd2e38e5b 100644
|
||||||
|
--- a/man/lvreduce.8_pregen
|
||||||
|
+++ b/man/lvreduce.8_pregen
|
||||||
|
@@ -130,8 +130,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvremove.8_pregen b/man/lvremove.8_pregen
|
||||||
|
index 2bd7997a3..8a4afbdff 100644
|
||||||
|
--- a/man/lvremove.8_pregen
|
||||||
|
+++ b/man/lvremove.8_pregen
|
||||||
|
@@ -136,8 +136,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvrename.8_pregen b/man/lvrename.8_pregen
|
||||||
|
index d41a4c241..27ce2caeb 100644
|
||||||
|
--- a/man/lvrename.8_pregen
|
||||||
|
+++ b/man/lvrename.8_pregen
|
||||||
|
@@ -120,8 +120,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvresize.8_pregen b/man/lvresize.8_pregen
|
||||||
|
index f3ea2536c..10e7dda7c 100644
|
||||||
|
--- a/man/lvresize.8_pregen
|
||||||
|
+++ b/man/lvresize.8_pregen
|
||||||
|
@@ -286,8 +286,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvs.8_pregen b/man/lvs.8_pregen
|
||||||
|
index 2b2c5f193..94a74f9dd 100644
|
||||||
|
--- a/man/lvs.8_pregen
|
||||||
|
+++ b/man/lvs.8_pregen
|
||||||
|
@@ -172,8 +172,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/lvscan.8_pregen b/man/lvscan.8_pregen
|
||||||
|
index f459ab35b..8d79f22dd 100644
|
||||||
|
--- a/man/lvscan.8_pregen
|
||||||
|
+++ b/man/lvscan.8_pregen
|
||||||
|
@@ -119,8 +119,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvchange.8_pregen b/man/pvchange.8_pregen
|
||||||
|
index 4add9ca69..010845274 100644
|
||||||
|
--- a/man/pvchange.8_pregen
|
||||||
|
+++ b/man/pvchange.8_pregen
|
||||||
|
@@ -179,8 +179,9 @@ multiple tags at once. See \fBlvm\fP(8) for information about tags.
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvck.8_pregen b/man/pvck.8_pregen
|
||||||
|
index 88200f21e..7d6652342 100644
|
||||||
|
--- a/man/pvck.8_pregen
|
||||||
|
+++ b/man/pvck.8_pregen
|
||||||
|
@@ -351,8 +351,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvcreate.8_pregen b/man/pvcreate.8_pregen
|
||||||
|
index a74a5ec2a..6ffd596fe 100644
|
||||||
|
--- a/man/pvcreate.8_pregen
|
||||||
|
+++ b/man/pvcreate.8_pregen
|
||||||
|
@@ -229,8 +229,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen
|
||||||
|
index 2f26a8727..59628bedd 100644
|
||||||
|
--- a/man/pvdisplay.8_pregen
|
||||||
|
+++ b/man/pvdisplay.8_pregen
|
||||||
|
@@ -183,8 +183,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvmove.8_pregen b/man/pvmove.8_pregen
|
||||||
|
index 0f70497a2..f633b97d2 100644
|
||||||
|
--- a/man/pvmove.8_pregen
|
||||||
|
+++ b/man/pvmove.8_pregen
|
||||||
|
@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvremove.8_pregen b/man/pvremove.8_pregen
|
||||||
|
index 3d4a86c09..51c589fd7 100644
|
||||||
|
--- a/man/pvremove.8_pregen
|
||||||
|
+++ b/man/pvremove.8_pregen
|
||||||
|
@@ -103,8 +103,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvresize.8_pregen b/man/pvresize.8_pregen
|
||||||
|
index 87d87c8ce..9ce57e325 100644
|
||||||
|
--- a/man/pvresize.8_pregen
|
||||||
|
+++ b/man/pvresize.8_pregen
|
||||||
|
@@ -98,8 +98,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvs.8_pregen b/man/pvs.8_pregen
|
||||||
|
index 32c28e4d1..955b3f887 100644
|
||||||
|
--- a/man/pvs.8_pregen
|
||||||
|
+++ b/man/pvs.8_pregen
|
||||||
|
@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/pvscan.8_pregen b/man/pvscan.8_pregen
|
||||||
|
index 1c96d5aab..1e1cc11ab 100644
|
||||||
|
--- a/man/pvscan.8_pregen
|
||||||
|
+++ b/man/pvscan.8_pregen
|
||||||
|
@@ -369,8 +369,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgcfgbackup.8_pregen b/man/vgcfgbackup.8_pregen
|
||||||
|
index 5e658093a..cf984b04b 100644
|
||||||
|
--- a/man/vgcfgbackup.8_pregen
|
||||||
|
+++ b/man/vgcfgbackup.8_pregen
|
||||||
|
@@ -123,8 +123,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgcfgrestore.8_pregen b/man/vgcfgrestore.8_pregen
|
||||||
|
index 695e05582..6165cd36e 100644
|
||||||
|
--- a/man/vgcfgrestore.8_pregen
|
||||||
|
+++ b/man/vgcfgrestore.8_pregen
|
||||||
|
@@ -208,8 +208,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen
|
||||||
|
index 05c67aead..7c7030c0d 100644
|
||||||
|
--- a/man/vgchange.8_pregen
|
||||||
|
+++ b/man/vgchange.8_pregen
|
||||||
|
@@ -556,8 +556,9 @@ See \fBlvm.conf\fP(5) for more information about profiles.
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgck.8_pregen b/man/vgck.8_pregen
|
||||||
|
index a8fa33f4b..cfb828ff9 100644
|
||||||
|
--- a/man/vgck.8_pregen
|
||||||
|
+++ b/man/vgck.8_pregen
|
||||||
|
@@ -114,8 +114,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgconvert.8_pregen b/man/vgconvert.8_pregen
|
||||||
|
index 4d54c2b27..b99de39b8 100644
|
||||||
|
--- a/man/vgconvert.8_pregen
|
||||||
|
+++ b/man/vgconvert.8_pregen
|
||||||
|
@@ -124,8 +124,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgcreate.8_pregen b/man/vgcreate.8_pregen
|
||||||
|
index 9bb8d3868..d5316aa1c 100644
|
||||||
|
--- a/man/vgcreate.8_pregen
|
||||||
|
+++ b/man/vgcreate.8_pregen
|
||||||
|
@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen
|
||||||
|
index 0a12b3c39..b6cd294d5 100644
|
||||||
|
--- a/man/vgdisplay.8_pregen
|
||||||
|
+++ b/man/vgdisplay.8_pregen
|
||||||
|
@@ -180,8 +180,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgexport.8_pregen b/man/vgexport.8_pregen
|
||||||
|
index a87058946..6af64b82a 100644
|
||||||
|
--- a/man/vgexport.8_pregen
|
||||||
|
+++ b/man/vgexport.8_pregen
|
||||||
|
@@ -139,8 +139,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgextend.8_pregen b/man/vgextend.8_pregen
|
||||||
|
index 2b2650527..e55e0a110 100644
|
||||||
|
--- a/man/vgextend.8_pregen
|
||||||
|
+++ b/man/vgextend.8_pregen
|
||||||
|
@@ -147,8 +147,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgimport.8_pregen b/man/vgimport.8_pregen
|
||||||
|
index 5cd8fab84..9f8614205 100644
|
||||||
|
--- a/man/vgimport.8_pregen
|
||||||
|
+++ b/man/vgimport.8_pregen
|
||||||
|
@@ -128,8 +128,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgimportclone.8_pregen b/man/vgimportclone.8_pregen
|
||||||
|
index bf0af5841..80da5454b 100644
|
||||||
|
--- a/man/vgimportclone.8_pregen
|
||||||
|
+++ b/man/vgimportclone.8_pregen
|
||||||
|
@@ -113,8 +113,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgimportdevices.8_pregen b/man/vgimportdevices.8_pregen
|
||||||
|
index 5897e29ad..44e5fc663 100644
|
||||||
|
--- a/man/vgimportdevices.8_pregen
|
||||||
|
+++ b/man/vgimportdevices.8_pregen
|
||||||
|
@@ -132,8 +132,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgmerge.8_pregen b/man/vgmerge.8_pregen
|
||||||
|
index a36e0c7bd..dfe8e2f0f 100644
|
||||||
|
--- a/man/vgmerge.8_pregen
|
||||||
|
+++ b/man/vgmerge.8_pregen
|
||||||
|
@@ -107,8 +107,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgmknodes.8_pregen b/man/vgmknodes.8_pregen
|
||||||
|
index 0a03e1582..d7cd722a4 100644
|
||||||
|
--- a/man/vgmknodes.8_pregen
|
||||||
|
+++ b/man/vgmknodes.8_pregen
|
||||||
|
@@ -108,8 +108,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgreduce.8_pregen b/man/vgreduce.8_pregen
|
||||||
|
index f3178a618..63b0a20f3 100644
|
||||||
|
--- a/man/vgreduce.8_pregen
|
||||||
|
+++ b/man/vgreduce.8_pregen
|
||||||
|
@@ -199,8 +199,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgremove.8_pregen b/man/vgremove.8_pregen
|
||||||
|
index 779c0f13e..661ada673 100644
|
||||||
|
--- a/man/vgremove.8_pregen
|
||||||
|
+++ b/man/vgremove.8_pregen
|
||||||
|
@@ -109,8 +109,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgrename.8_pregen b/man/vgrename.8_pregen
|
||||||
|
index d3e776ca4..2b849d180 100644
|
||||||
|
--- a/man/vgrename.8_pregen
|
||||||
|
+++ b/man/vgrename.8_pregen
|
||||||
|
@@ -133,8 +133,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgs.8_pregen b/man/vgs.8_pregen
|
||||||
|
index ee5083a93..2ca98b0b0 100644
|
||||||
|
--- a/man/vgs.8_pregen
|
||||||
|
+++ b/man/vgs.8_pregen
|
||||||
|
@@ -166,8 +166,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgscan.8_pregen b/man/vgscan.8_pregen
|
||||||
|
index 824e7f673..a8da70d99 100644
|
||||||
|
--- a/man/vgscan.8_pregen
|
||||||
|
+++ b/man/vgscan.8_pregen
|
||||||
|
@@ -101,8 +101,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
diff --git a/man/vgsplit.8_pregen b/man/vgsplit.8_pregen
|
||||||
|
index 065c8b52a..99938a4e3 100644
|
||||||
|
--- a/man/vgsplit.8_pregen
|
||||||
|
+++ b/man/vgsplit.8_pregen
|
||||||
|
@@ -175,8 +175,9 @@ messages sent to the log file and/or syslog (if configured).
|
||||||
|
.HP
|
||||||
|
\fB--devices\fP \fIPV\fP
|
||||||
|
.br
|
||||||
|
-Devices that the command can use. This option can be repeated
|
||||||
|
-or accepts a comma separated list of devices. This overrides
|
||||||
|
+Restricts the devices that are visible and accessible to the command.
|
||||||
|
+Devices not listed will appear to be missing. This option can be
|
||||||
|
+repeated, or accepts a comma separated list of devices. This overrides
|
||||||
|
the devices file.
|
||||||
|
.
|
||||||
|
.HP
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
90
SOURCES/0066-vdo-use-single-validator.patch
Normal file
90
SOURCES/0066-vdo-use-single-validator.patch
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
From d0b5614d43ac41ee24a480a6272f256b1a242873 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Mon, 4 Jul 2022 16:08:30 +0200
|
||||||
|
Subject: [PATCH 1/3] vdo: use single validator
|
||||||
|
|
||||||
|
Add era lenght validation into dm_vdo_validate_target_params()
|
||||||
|
and reuse this validator also for _check_lv_segment().
|
||||||
|
|
||||||
|
(cherry picked from commit 8ca2b1bc213188037ecedfbf76de53de871c7f5b)
|
||||||
|
---
|
||||||
|
device_mapper/vdo/vdo_target.c | 9 ++++++++-
|
||||||
|
lib/metadata/merge.c | 37 ++--------------------------------
|
||||||
|
2 files changed, 10 insertions(+), 36 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c
|
||||||
|
index 2ffd29145..0e5abd162 100644
|
||||||
|
--- a/device_mapper/vdo/vdo_target.c
|
||||||
|
+++ b/device_mapper/vdo/vdo_target.c
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright (C) 2018 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -38,6 +38,13 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if ((vtp->block_map_era_length < DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) ||
|
||||||
|
+ (vtp->block_map_era_length > DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)) {
|
||||||
|
+ log_error("VDO block map era length %u out of range.",
|
||||||
|
+ vtp->block_map_era_length);
|
||||||
|
+ valid = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if ((vtp->index_memory_size_mb < DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB) ||
|
||||||
|
(vtp->index_memory_size_mb > DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB)) {
|
||||||
|
log_error("VDO index memory size %u out of range.",
|
||||||
|
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
|
||||||
|
index 8eff74297..5209f51b5 100644
|
||||||
|
--- a/lib/metadata/merge.c
|
||||||
|
+++ b/lib/metadata/merge.c
|
||||||
|
@@ -545,41 +545,8 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
|
||||||
|
seg_error("is missing a VDO pool data LV");
|
||||||
|
} else if (!lv_is_vdo_pool_data(seg_lv(seg, 0)))
|
||||||
|
seg_error("is not VDO pool data LV");
|
||||||
|
- if ((seg->vdo_params.minimum_io_size != (512 >> SECTOR_SHIFT)) &&
|
||||||
|
- (seg->vdo_params.minimum_io_size != (4096 >> SECTOR_SHIFT)))
|
||||||
|
- seg_error("sets unsupported VDO minimum io size");
|
||||||
|
- if ((seg->vdo_params.block_map_cache_size_mb < DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB) ||
|
||||||
|
- (seg->vdo_params.block_map_cache_size_mb > DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB))
|
||||||
|
- seg_error("sets unsupported VDO block map cache size");
|
||||||
|
- if ((seg->vdo_params.block_map_era_length < DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) ||
|
||||||
|
- (seg->vdo_params.block_map_era_length > DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM))
|
||||||
|
- seg_error("sets unsupported VDO block map era length");
|
||||||
|
- if ((seg->vdo_params.index_memory_size_mb < DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB) ||
|
||||||
|
- (seg->vdo_params.index_memory_size_mb > DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB))
|
||||||
|
- seg_error("sets unsupported VDO index memory size");
|
||||||
|
- if ((seg->vdo_params.slab_size_mb < DM_VDO_SLAB_SIZE_MINIMUM_MB) ||
|
||||||
|
- (seg->vdo_params.slab_size_mb > DM_VDO_SLAB_SIZE_MAXIMUM_MB))
|
||||||
|
- seg_error("sets unsupported VDO slab size");
|
||||||
|
- if ((seg->vdo_params.max_discard < DM_VDO_MAX_DISCARD_MINIMUM) ||
|
||||||
|
- (seg->vdo_params.max_discard > DM_VDO_MAX_DISCARD_MAXIMUM))
|
||||||
|
- seg_error("sets unsupported VDO max discard");
|
||||||
|
- if (seg->vdo_params.ack_threads > DM_VDO_ACK_THREADS_MAXIMUM)
|
||||||
|
- seg_error("sets unsupported VDO ack threads");
|
||||||
|
- if ((seg->vdo_params.bio_threads < DM_VDO_BIO_THREADS_MINIMUM) ||
|
||||||
|
- (seg->vdo_params.bio_threads > DM_VDO_BIO_THREADS_MAXIMUM))
|
||||||
|
- seg_error("sets unsupported VDO bio threads");
|
||||||
|
- if ((seg->vdo_params.bio_rotation < DM_VDO_BIO_ROTATION_MINIMUM) ||
|
||||||
|
- (seg->vdo_params.bio_rotation > DM_VDO_BIO_ROTATION_MAXIMUM))
|
||||||
|
- seg_error("sets unsupported VDO bio rotation");
|
||||||
|
- if ((seg->vdo_params.cpu_threads < DM_VDO_CPU_THREADS_MINIMUM) ||
|
||||||
|
- (seg->vdo_params.cpu_threads > DM_VDO_CPU_THREADS_MAXIMUM))
|
||||||
|
- seg_error("sets unsupported VDO cpu threads");
|
||||||
|
- if (seg->vdo_params.hash_zone_threads > DM_VDO_HASH_ZONE_THREADS_MAXIMUM)
|
||||||
|
- seg_error("sets unsupported VDO hash zone threads");
|
||||||
|
- if (seg->vdo_params.logical_threads > DM_VDO_LOGICAL_THREADS_MAXIMUM)
|
||||||
|
- seg_error("sets unsupported VDO logical threads");
|
||||||
|
- if (seg->vdo_params.physical_threads > DM_VDO_PHYSICAL_THREADS_MAXIMUM)
|
||||||
|
- seg_error("sets unsupported VDO physical threads");
|
||||||
|
+ if (!dm_vdo_validate_target_params(&seg->vdo_params, 0))
|
||||||
|
+ seg_error("sets invalid VDO parameter(s)");
|
||||||
|
} else { /* !VDO pool */
|
||||||
|
if (seg->vdo_pool_header_size)
|
||||||
|
seg_error("sets vdo_pool_header_size");
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,295 @@
|
|||||||
|
From b16082b05639d4321cbf699d3309fe24a8bc71fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Fri, 24 Jun 2022 15:54:08 +0200
|
||||||
|
Subject: [PATCH 2/3] vdo: use defines also for configuration defines
|
||||||
|
|
||||||
|
Keep single source for most of values printed in lvm.conf
|
||||||
|
(still needs some conversion)
|
||||||
|
|
||||||
|
Correct max for logical threads to 60
|
||||||
|
(we may refuse some older configuration which might eventually
|
||||||
|
user higher numbers - but so far let's assume no user have ever set this
|
||||||
|
as it's been non-trivial and if would complicate code unnecessarily.)
|
||||||
|
|
||||||
|
Accept maximum of 4PiB for virtual size of VDO LV
|
||||||
|
(lvm2 will drop 'header borders to 0 for this case').
|
||||||
|
|
||||||
|
(cherry picked from commit b5c8e591ed9ee30b67e79d60705d3c0bb8509a2a)
|
||||||
|
---
|
||||||
|
conf/example.conf.in | 9 +++---
|
||||||
|
device_mapper/vdo/vdo_limits.h | 55 ++++++++++++++++++----------------
|
||||||
|
device_mapper/vdo/vdo_target.c | 11 +++----
|
||||||
|
lib/config/config_settings.h | 32 +++++++++++++-------
|
||||||
|
4 files changed, 60 insertions(+), 47 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/conf/example.conf.in b/conf/example.conf.in
|
||||||
|
index a78ed7333..897622b9d 100644
|
||||||
|
--- a/conf/example.conf.in
|
||||||
|
+++ b/conf/example.conf.in
|
||||||
|
@@ -625,13 +625,12 @@ allocation {
|
||||||
|
# Enables or disables whether VDO volume should tag its latency-critical
|
||||||
|
# writes with the REQ_SYNC flag. Some device mapper targets such as dm-raid5
|
||||||
|
# process writes with this flag at a higher priority.
|
||||||
|
- # Default is enabled.
|
||||||
|
# This configuration option has an automatic default value.
|
||||||
|
# vdo_use_metadata_hints = 1
|
||||||
|
|
||||||
|
# Configuration option allocation/vdo_minimum_io_size.
|
||||||
|
# The minimum IO size for VDO volume to accept, in bytes.
|
||||||
|
- # Valid values are 512 or 4096. The recommended and default value is 4096.
|
||||||
|
+ # Valid values are 512 or 4096. The recommended value is 4096.
|
||||||
|
# This configuration option has an automatic default value.
|
||||||
|
# vdo_minimum_io_size = 4096
|
||||||
|
|
||||||
|
@@ -684,7 +683,7 @@ allocation {
|
||||||
|
# Configuration option allocation/vdo_bio_threads.
|
||||||
|
# Specifies the number of threads to use for submitting I/O
|
||||||
|
# operations to the storage device of VDO volume.
|
||||||
|
- # The value must be in range [1..100]
|
||||||
|
+ # The value must be in range [1..100].
|
||||||
|
# Each additional thread after the first will use an additional 18MiB of RAM,
|
||||||
|
# plus 1.12 MiB of RAM per megabyte of configured read cache size.
|
||||||
|
# This configuration option has an automatic default value.
|
||||||
|
@@ -698,7 +697,7 @@ allocation {
|
||||||
|
|
||||||
|
# Configuration option allocation/vdo_cpu_threads.
|
||||||
|
# Specifies the number of threads to use for CPU-intensive work such as
|
||||||
|
- # hashing or compression for VDO volume. The value must be in range [1..100]
|
||||||
|
+ # hashing or compression for VDO volume. The value must be in range [1..100].
|
||||||
|
# This configuration option has an automatic default value.
|
||||||
|
# vdo_cpu_threads = 2
|
||||||
|
|
||||||
|
@@ -716,7 +715,7 @@ allocation {
|
||||||
|
# processing based on the hash value computed from the block data.
|
||||||
|
# A logical thread count of 9 or more will require explicitly specifying
|
||||||
|
# a sufficiently large block map cache size, as well.
|
||||||
|
- # The value must be in range [0..100].
|
||||||
|
+ # The value must be in range [0..60].
|
||||||
|
# vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be
|
||||||
|
# either all zero or all non-zero.
|
||||||
|
# This configuration option has an automatic default value.
|
||||||
|
diff --git a/device_mapper/vdo/vdo_limits.h b/device_mapper/vdo/vdo_limits.h
|
||||||
|
index e145100b1..db365ace2 100644
|
||||||
|
--- a/device_mapper/vdo/vdo_limits.h
|
||||||
|
+++ b/device_mapper/vdo/vdo_limits.h
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright (C) 2018 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of the device-mapper userspace tools.
|
||||||
|
*
|
||||||
|
@@ -15,49 +15,52 @@
|
||||||
|
#ifndef DEVICE_MAPPER_VDO_LIMITS_H
|
||||||
|
#define DEVICE_MAPPER_VDO_LIMITS_H
|
||||||
|
|
||||||
|
+#ifndef SECTOR_SHIFT
|
||||||
|
+#define SECTOR_SHIFT 9L
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define DM_VDO_BLOCK_SIZE UINT64_C(8) // 4KiB in sectors
|
||||||
|
+#define DM_VDO_BLOCK_SIZE_KB (DM_VDO_BLOCK_SIZE << SECTOR_SHIFT)
|
||||||
|
|
||||||
|
#define DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB (128) // 128MiB
|
||||||
|
#define DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB (16 * 1024 * 1024 - 1) // 16TiB - 1
|
||||||
|
#define DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_PER_LOGICAL_THREAD (4096 * DM_VDO_BLOCK_SIZE_KB)
|
||||||
|
|
||||||
|
-#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM (1)
|
||||||
|
-#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM (16380)
|
||||||
|
+#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM 1
|
||||||
|
+#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM 16380
|
||||||
|
|
||||||
|
-#define DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB (256) // 0.25 GiB
|
||||||
|
+#define DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB 256 // 0.25 GiB
|
||||||
|
#define DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB (1024 * 1024 * 1024) // 1TiB
|
||||||
|
|
||||||
|
-//#define DM_VDO_READ_CACHE_SIZE_MINIMUM_MB (0)
|
||||||
|
-#define DM_VDO_READ_CACHE_SIZE_MAXIMUM_MB (16 * 1024 * 1024 - 1) // 16TiB - 1
|
||||||
|
-
|
||||||
|
-#define DM_VDO_SLAB_SIZE_MINIMUM_MB (128) // 128MiB
|
||||||
|
+#define DM_VDO_SLAB_SIZE_MINIMUM_MB 128 // 128MiB
|
||||||
|
#define DM_VDO_SLAB_SIZE_MAXIMUM_MB (32 * 1024) // 32GiB
|
||||||
|
+#define DM_VDO_SLABS_MAXIMUM 8192
|
||||||
|
|
||||||
|
-//#define DM_VDO_LOGICAL_SIZE_MINIMUM_MB (0)
|
||||||
|
-#define DM_VDO_LOGICAL_SIZE_MAXIMUM_MB (UINT64_C(4) * 1024 * 1024 * 1024) // 4PiB
|
||||||
|
+#define DM_VDO_LOGICAL_SIZE_MAXIMUM (UINT64_C(4) * 1024 * 1024 * 1024 * 1024 * 1024 >> SECTOR_SHIFT) // 4PiB
|
||||||
|
+#define DM_VDO_PHYSICAL_SIZE_MAXIMUM (UINT64_C(64) * DM_VDO_BLOCK_SIZE_KB * 1024 * 1024 * 1024 >> SECTOR_SHIFT) // 256TiB
|
||||||
|
|
||||||
|
-//#define DM_VDO_ACK_THREADS_MINIMUM (0)
|
||||||
|
-#define DM_VDO_ACK_THREADS_MAXIMUM (100)
|
||||||
|
+#define DM_VDO_ACK_THREADS_MINIMUM 0
|
||||||
|
+#define DM_VDO_ACK_THREADS_MAXIMUM 100
|
||||||
|
|
||||||
|
-#define DM_VDO_BIO_THREADS_MINIMUM (1)
|
||||||
|
-#define DM_VDO_BIO_THREADS_MAXIMUM (100)
|
||||||
|
+#define DM_VDO_BIO_THREADS_MINIMUM 1
|
||||||
|
+#define DM_VDO_BIO_THREADS_MAXIMUM 100
|
||||||
|
|
||||||
|
-#define DM_VDO_BIO_ROTATION_MINIMUM (1)
|
||||||
|
-#define DM_VDO_BIO_ROTATION_MAXIMUM (1024)
|
||||||
|
+#define DM_VDO_BIO_ROTATION_MINIMUM 1
|
||||||
|
+#define DM_VDO_BIO_ROTATION_MAXIMUM 1024
|
||||||
|
|
||||||
|
-#define DM_VDO_CPU_THREADS_MINIMUM (1)
|
||||||
|
-#define DM_VDO_CPU_THREADS_MAXIMUM (100)
|
||||||
|
+#define DM_VDO_CPU_THREADS_MINIMUM 1
|
||||||
|
+#define DM_VDO_CPU_THREADS_MAXIMUM 100
|
||||||
|
|
||||||
|
-//#define DM_VDO_HASH_ZONE_THREADS_MINIMUM (0)
|
||||||
|
-#define DM_VDO_HASH_ZONE_THREADS_MAXIMUM (100)
|
||||||
|
+#define DM_VDO_HASH_ZONE_THREADS_MINIMUM 0
|
||||||
|
+#define DM_VDO_HASH_ZONE_THREADS_MAXIMUM 100
|
||||||
|
|
||||||
|
-//#define DM_VDO_LOGICAL_THREADS_MINIMUM (0)
|
||||||
|
-#define DM_VDO_LOGICAL_THREADS_MAXIMUM (100)
|
||||||
|
+#define DM_VDO_LOGICAL_THREADS_MINIMUM 0
|
||||||
|
+#define DM_VDO_LOGICAL_THREADS_MAXIMUM 60
|
||||||
|
|
||||||
|
-//#define DM_VDO_PHYSICAL_THREADS_MINIMUM (0)
|
||||||
|
-#define DM_VDO_PHYSICAL_THREADS_MAXIMUM (16)
|
||||||
|
+#define DM_VDO_PHYSICAL_THREADS_MINIMUM 0
|
||||||
|
+#define DM_VDO_PHYSICAL_THREADS_MAXIMUM 16
|
||||||
|
|
||||||
|
-#define DM_VDO_MAX_DISCARD_MINIMUM (1)
|
||||||
|
-#define DM_VDO_MAX_DISCARD_MAXIMUM (UINT32_MAX / 4096)
|
||||||
|
+#define DM_VDO_MAX_DISCARD_MINIMUM 1
|
||||||
|
+#define DM_VDO_MAX_DISCARD_MAXIMUM (UINT32_MAX / (uint32_t)(DM_VDO_BLOCK_SIZE_KB))
|
||||||
|
|
||||||
|
#endif // DEVICE_MAPPER_VDO_LIMITS_H
|
||||||
|
diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c
|
||||||
|
index 0e5abd162..3ebe0592e 100644
|
||||||
|
--- a/device_mapper/vdo/vdo_target.c
|
||||||
|
+++ b/device_mapper/vdo/vdo_target.c
|
||||||
|
@@ -18,14 +18,15 @@
|
||||||
|
#include "vdo_limits.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
+/* validate vdo target parameters and 'vdo_size' in sectors */
|
||||||
|
bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||||
|
uint64_t vdo_size)
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
|
||||||
|
/* 512 or 4096 bytes only ATM */
|
||||||
|
- if ((vtp->minimum_io_size != 1) &&
|
||||||
|
- (vtp->minimum_io_size != 8)) {
|
||||||
|
+ if ((vtp->minimum_io_size != (512 >> SECTOR_SHIFT)) &&
|
||||||
|
+ (vtp->minimum_io_size != (4096 >> SECTOR_SHIFT))) {
|
||||||
|
log_error("VDO minimum io size %u is unsupported.",
|
||||||
|
vtp->minimum_io_size);
|
||||||
|
valid = false;
|
||||||
|
@@ -127,10 +128,10 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (vdo_size >= (DM_VDO_LOGICAL_SIZE_MAXIMUM_MB * UINT64_C(1024 * 2))) {
|
||||||
|
+ if (vdo_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) {
|
||||||
|
log_error("VDO logical size is by " FMTu64 "KiB bigger then limit " FMTu64 "TiB.",
|
||||||
|
- (vdo_size - (DM_VDO_LOGICAL_SIZE_MAXIMUM_MB * UINT64_C(1024 * 2))) / 2,
|
||||||
|
- DM_VDO_LOGICAL_SIZE_MAXIMUM_MB / UINT64_C(1024) / UINT64_C(1024));
|
||||||
|
+ (vdo_size - DM_VDO_LOGICAL_SIZE_MAXIMUM) / 2,
|
||||||
|
+ DM_VDO_LOGICAL_SIZE_MAXIMUM / (UINT64_C(1024) * 1024 * 1024 * 1024 >> SECTOR_SHIFT));
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
|
||||||
|
index d280e7adb..2c91e8bb6 100644
|
||||||
|
--- a/lib/config/config_settings.h
|
||||||
|
+++ b/lib/config/config_settings.h
|
||||||
|
@@ -118,6 +118,7 @@
|
||||||
|
* the previous default value was set (uncommented) in lvm.conf.
|
||||||
|
*/
|
||||||
|
#include "lib/config/defaults.h"
|
||||||
|
+#include "device_mapper/vdo/vdo_limits.h"
|
||||||
|
|
||||||
|
cfg_section(root_CFG_SECTION, "(root)", root_CFG_SECTION, 0, vsn(0, 0, 0), 0, NULL, NULL)
|
||||||
|
|
||||||
|
@@ -708,12 +709,11 @@ cfg(allocation_vdo_use_deduplication_CFG, "vdo_use_deduplication", allocation_CF
|
||||||
|
cfg(allocation_vdo_use_metadata_hints_CFG, "vdo_use_metadata_hints", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_USE_METADATA_HINTS, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Enables or disables whether VDO volume should tag its latency-critical\n"
|
||||||
|
"writes with the REQ_SYNC flag. Some device mapper targets such as dm-raid5\n"
|
||||||
|
- "process writes with this flag at a higher priority.\n"
|
||||||
|
- "Default is enabled.\n")
|
||||||
|
+ "process writes with this flag at a higher priority.\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_minimum_io_size_CFG, "vdo_minimum_io_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_MINIMUM_IO_SIZE, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"The minimum IO size for VDO volume to accept, in bytes.\n"
|
||||||
|
- "Valid values are 512 or 4096. The recommended and default value is 4096.\n")
|
||||||
|
+ "Valid values are 512 or 4096. The recommended value is 4096.\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_block_map_cache_size_mb_CFG, "vdo_block_map_cache_size_mb", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_BLOCK_MAP_CACHE_SIZE_MB, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Specifies the amount of memory in MiB allocated for caching block map\n"
|
||||||
|
@@ -726,7 +726,8 @@ cfg(allocation_vdo_block_map_era_length_CFG, "vdo_block_map_period", allocation_
|
||||||
|
"The speed with which the block map cache writes out modified block map pages.\n"
|
||||||
|
"A smaller era length is likely to reduce the amount time spent rebuilding,\n"
|
||||||
|
"at the cost of increased block map writes during normal operation.\n"
|
||||||
|
- "The maximum and recommended value is 16380; the minimum value is 1.\n")
|
||||||
|
+ "The maximum and recommended value is " DM_TO_STRING(DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)
|
||||||
|
+ "; the minimum value is " DM_TO_STRING(DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) ".\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_check_point_frequency_CFG, "vdo_check_point_frequency", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_CHECK_POINT_FREQUENCY, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"The default check point frequency for VDO volume.\n")
|
||||||
|
@@ -748,27 +749,34 @@ cfg(allocation_vdo_slab_size_mb_CFG, "vdo_slab_size_mb", allocation_CFG_SECTION,
|
||||||
|
cfg(allocation_vdo_ack_threads_CFG, "vdo_ack_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_ACK_THREADS, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Specifies the number of threads to use for acknowledging\n"
|
||||||
|
"completion of requested VDO I/O operations.\n"
|
||||||
|
- "The value must be at in range [0..100].\n")
|
||||||
|
+ "The value must be at in range [" DM_TO_STRING(DM_VDO_ACK_THREADS_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_ACK_THREADS_MAXIMUM) "].\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_bio_threads_CFG, "vdo_bio_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_BIO_THREADS, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Specifies the number of threads to use for submitting I/O\n"
|
||||||
|
"operations to the storage device of VDO volume.\n"
|
||||||
|
- "The value must be in range [1..100]\n"
|
||||||
|
+ "The value must be in range [" DM_TO_STRING(DM_VDO_BIO_THREADS_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_BIO_THREADS_MAXIMUM) "].\n"
|
||||||
|
"Each additional thread after the first will use an additional 18MiB of RAM,\n"
|
||||||
|
"plus 1.12 MiB of RAM per megabyte of configured read cache size.\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_bio_rotation_CFG, "vdo_bio_rotation", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_BIO_ROTATION, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Specifies the number of I/O operations to enqueue for each bio-submission\n"
|
||||||
|
- "thread before directing work to the next. The value must be in range [1..1024].\n")
|
||||||
|
+ "thread before directing work to the next. The value must be in range ["
|
||||||
|
+ DM_TO_STRING(DM_VDO_BIO_ROTATION_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_BIO_ROTATION_MAXIMUM) "].\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_cpu_threads_CFG, "vdo_cpu_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_CPU_THREADS, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Specifies the number of threads to use for CPU-intensive work such as\n"
|
||||||
|
- "hashing or compression for VDO volume. The value must be in range [1..100]\n")
|
||||||
|
+ "hashing or compression for VDO volume. The value must be in range ["
|
||||||
|
+ DM_TO_STRING(DM_VDO_CPU_THREADS_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_CPU_THREADS_MAXIMUM) "].\n")
|
||||||
|
|
||||||
|
cfg(allocation_vdo_hash_zone_threads_CFG, "vdo_hash_zone_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_HASH_ZONE_THREADS, VDO_1ST_VSN, NULL, 0, NULL,
|
||||||
|
"Specifies the number of threads across which to subdivide parts of the VDO\n"
|
||||||
|
"processing based on the hash value computed from the block data.\n"
|
||||||
|
- "The value must be at in range [0..100].\n"
|
||||||
|
+ "The value must be at in range [" DM_TO_STRING(DM_VDO_HASH_ZONE_THREADS_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_HASH_ZONE_THREADS_MAXIMUM) "].\n"
|
||||||
|
"vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n"
|
||||||
|
"either all zero or all non-zero.\n")
|
||||||
|
|
||||||
|
@@ -777,7 +785,8 @@ cfg(allocation_vdo_logical_threads_CFG, "vdo_logical_threads", allocation_CFG_SE
|
||||||
|
"processing based on the hash value computed from the block data.\n"
|
||||||
|
"A logical thread count of 9 or more will require explicitly specifying\n"
|
||||||
|
"a sufficiently large block map cache size, as well.\n"
|
||||||
|
- "The value must be in range [0..100].\n"
|
||||||
|
+ "The value must be in range [" DM_TO_STRING(DM_VDO_LOGICAL_THREADS_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_LOGICAL_THREADS_MAXIMUM) "].\n"
|
||||||
|
"vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n"
|
||||||
|
"either all zero or all non-zero.\n")
|
||||||
|
|
||||||
|
@@ -785,7 +794,8 @@ cfg(allocation_vdo_physical_threads_CFG, "vdo_physical_threads", allocation_CFG_
|
||||||
|
"Specifies the number of threads across which to subdivide parts of the VDO\n"
|
||||||
|
"processing based on physical block addresses.\n"
|
||||||
|
"Each additional thread after the first will use an additional 10MiB of RAM.\n"
|
||||||
|
- "The value must be in range [0..16].\n"
|
||||||
|
+ "The value must be in range [" DM_TO_STRING(DM_VDO_PHYSICAL_THREADS_MINIMUM) ".."
|
||||||
|
+ DM_TO_STRING(DM_VDO_PHYSICAL_THREADS_MAXIMUM) "].\n"
|
||||||
|
"vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n"
|
||||||
|
"either all zero or all non-zero.\n")
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
144
SOURCES/0068-vdo-report-supported-range-in-error-path.patch
Normal file
144
SOURCES/0068-vdo-report-supported-range-in-error-path.patch
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
From cce56ebaa6b67d53b0430d5b52b957e194c9527d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Sat, 9 Jul 2022 21:28:40 +0200
|
||||||
|
Subject: [PATCH 3/3] vdo: report supported range in error path
|
||||||
|
|
||||||
|
(cherry picked from commit 9f3eff002cc229d3c22dfd7db6da69dadc0bd460)
|
||||||
|
---
|
||||||
|
device_mapper/vdo/vdo_target.c | 63 ++++++++++++++++++++++++----------
|
||||||
|
1 file changed, 45 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c
|
||||||
|
index 3ebe0592e..ab3fff26a 100644
|
||||||
|
--- a/device_mapper/vdo/vdo_target.c
|
||||||
|
+++ b/device_mapper/vdo/vdo_target.c
|
||||||
|
@@ -27,81 +27,108 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||||
|
/* 512 or 4096 bytes only ATM */
|
||||||
|
if ((vtp->minimum_io_size != (512 >> SECTOR_SHIFT)) &&
|
||||||
|
(vtp->minimum_io_size != (4096 >> SECTOR_SHIFT))) {
|
||||||
|
- log_error("VDO minimum io size %u is unsupported.",
|
||||||
|
+ log_error("VDO minimum io size %u is unsupported [512, 4096].",
|
||||||
|
vtp->minimum_io_size);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->block_map_cache_size_mb < DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB) ||
|
||||||
|
(vtp->block_map_cache_size_mb > DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB)) {
|
||||||
|
- log_error("VDO block map cache size %u out of range.",
|
||||||
|
- vtp->block_map_cache_size_mb);
|
||||||
|
+ log_error("VDO block map cache size %u MiB is out of range [%u..%u].",
|
||||||
|
+ vtp->block_map_cache_size_mb,
|
||||||
|
+ DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB,
|
||||||
|
+ DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->block_map_era_length < DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) ||
|
||||||
|
(vtp->block_map_era_length > DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)) {
|
||||||
|
- log_error("VDO block map era length %u out of range.",
|
||||||
|
- vtp->block_map_era_length);
|
||||||
|
+ log_error("VDO block map era length %u is out of range [%u..%u].",
|
||||||
|
+ vtp->block_map_era_length,
|
||||||
|
+ DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM,
|
||||||
|
+ DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->index_memory_size_mb < DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB) ||
|
||||||
|
(vtp->index_memory_size_mb > DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB)) {
|
||||||
|
- log_error("VDO index memory size %u out of range.",
|
||||||
|
- vtp->index_memory_size_mb);
|
||||||
|
+ log_error("VDO index memory size %u MiB is out of range [%u..%u].",
|
||||||
|
+ vtp->index_memory_size_mb,
|
||||||
|
+ DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB,
|
||||||
|
+ DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->slab_size_mb < DM_VDO_SLAB_SIZE_MINIMUM_MB) ||
|
||||||
|
(vtp->slab_size_mb > DM_VDO_SLAB_SIZE_MAXIMUM_MB)) {
|
||||||
|
- log_error("VDO slab size %u out of range.",
|
||||||
|
- vtp->slab_size_mb);
|
||||||
|
+ log_error("VDO slab size %u MiB is out of range [%u..%u].",
|
||||||
|
+ vtp->slab_size_mb,
|
||||||
|
+ DM_VDO_SLAB_SIZE_MINIMUM_MB,
|
||||||
|
+ DM_VDO_SLAB_SIZE_MAXIMUM_MB);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->max_discard < DM_VDO_MAX_DISCARD_MINIMUM) ||
|
||||||
|
(vtp->max_discard > DM_VDO_MAX_DISCARD_MAXIMUM)) {
|
||||||
|
- log_error("VDO max discard %u out of range.",
|
||||||
|
- vtp->max_discard);
|
||||||
|
+ log_error("VDO max discard %u is out of range [%u..%u].",
|
||||||
|
+ vtp->max_discard,
|
||||||
|
+ DM_VDO_MAX_DISCARD_MINIMUM,
|
||||||
|
+ DM_VDO_MAX_DISCARD_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vtp->ack_threads > DM_VDO_ACK_THREADS_MAXIMUM) {
|
||||||
|
- log_error("VDO ack threads %u out of range.", vtp->ack_threads);
|
||||||
|
+ log_error("VDO ack threads %u is out of range [0..%u].",
|
||||||
|
+ vtp->ack_threads,
|
||||||
|
+ DM_VDO_ACK_THREADS_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->bio_threads < DM_VDO_BIO_THREADS_MINIMUM) ||
|
||||||
|
(vtp->bio_threads > DM_VDO_BIO_THREADS_MAXIMUM)) {
|
||||||
|
- log_error("VDO bio threads %u out of range.", vtp->bio_threads);
|
||||||
|
+ log_error("VDO bio threads %u is out of range [%u..%u].",
|
||||||
|
+ vtp->bio_threads,
|
||||||
|
+ DM_VDO_BIO_THREADS_MINIMUM,
|
||||||
|
+ DM_VDO_BIO_THREADS_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->bio_rotation < DM_VDO_BIO_ROTATION_MINIMUM) ||
|
||||||
|
(vtp->bio_rotation > DM_VDO_BIO_ROTATION_MAXIMUM)) {
|
||||||
|
- log_error("VDO bio rotation %u out of range.", vtp->bio_rotation);
|
||||||
|
+ log_error("VDO bio rotation %u is out of range [%u..%u].",
|
||||||
|
+ vtp->bio_rotation,
|
||||||
|
+ DM_VDO_BIO_ROTATION_MINIMUM,
|
||||||
|
+ DM_VDO_BIO_ROTATION_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vtp->cpu_threads < DM_VDO_CPU_THREADS_MINIMUM) ||
|
||||||
|
(vtp->cpu_threads > DM_VDO_CPU_THREADS_MAXIMUM)) {
|
||||||
|
- log_error("VDO cpu threads %u out of range.", vtp->cpu_threads);
|
||||||
|
+ log_error("VDO cpu threads %u is out of range [%u..%u].",
|
||||||
|
+ vtp->cpu_threads,
|
||||||
|
+ DM_VDO_CPU_THREADS_MINIMUM,
|
||||||
|
+ DM_VDO_CPU_THREADS_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vtp->hash_zone_threads > DM_VDO_HASH_ZONE_THREADS_MAXIMUM) {
|
||||||
|
- log_error("VDO hash zone threads %u out of range.", vtp->hash_zone_threads);
|
||||||
|
+ log_error("VDO hash zone threads %u is out of range [0..%u].",
|
||||||
|
+ vtp->hash_zone_threads,
|
||||||
|
+ DM_VDO_HASH_ZONE_THREADS_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vtp->logical_threads > DM_VDO_LOGICAL_THREADS_MAXIMUM) {
|
||||||
|
- log_error("VDO logical threads %u out of range.", vtp->logical_threads);
|
||||||
|
+ log_error("VDO logical threads %u is out of range [0..%u].",
|
||||||
|
+ vtp->logical_threads,
|
||||||
|
+ DM_VDO_LOGICAL_THREADS_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vtp->physical_threads > DM_VDO_PHYSICAL_THREADS_MAXIMUM) {
|
||||||
|
- log_error("VDO physical threads %u out of range.", vtp->physical_threads);
|
||||||
|
+ log_error("VDO physical threads %u is out of range [0..%u].",
|
||||||
|
+ vtp->physical_threads,
|
||||||
|
+ DM_VDO_PHYSICAL_THREADS_MAXIMUM);
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
35
SOURCES/0069-vdo-ensure-VDO-config-is-removed.patch
Normal file
35
SOURCES/0069-vdo-ensure-VDO-config-is-removed.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From c41468a8acff9fd71bf774c821ad7c92623889da Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Walsh <awalsh@redhat.com>
|
||||||
|
Date: Mon, 15 Nov 2021 10:49:06 -0500
|
||||||
|
Subject: [PATCH 069/115] vdo: ensure VDO config is removed
|
||||||
|
|
||||||
|
Make sure to remove the VDO config after conversion
|
||||||
|
of LVM-backed VDO.
|
||||||
|
|
||||||
|
Addresses point 3 in rhbz#1987024#c5
|
||||||
|
|
||||||
|
(cherry picked from commit 522561e64b5fe73cb9d01c2ee2d4b7624b0ddff4)
|
||||||
|
---
|
||||||
|
scripts/lvm_import_vdo.sh | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh
|
||||||
|
index beb55dbdb..cc09187e9 100755
|
||||||
|
--- a/scripts/lvm_import_vdo.sh
|
||||||
|
+++ b/scripts/lvm_import_vdo.sh
|
||||||
|
@@ -405,6 +405,12 @@ EOF
|
||||||
|
verbose "Converting to VDO pool."
|
||||||
|
dry "$LVM" lvconvert $YES $VERB $FORCE --config "$PARAMS" -Zn -V "${vdo_logicalSize}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool"
|
||||||
|
|
||||||
|
+ # Note: that this is spelled OPPOSITE the other $IS_LV checks.
|
||||||
|
+ if [ "$IS_LV" = "1" ]; then
|
||||||
|
+ verbose "Removing now-unused VDO entry from VDO config."
|
||||||
|
+ dry "$VDO" remove $VDOCONF --force --verbose --name "$VDONAME"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
rm -fr "$TEMPDIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
50
SOURCES/0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch
Normal file
50
SOURCES/0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From a147a14813d576a11ed2f9ff08090fad874e418a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Tue, 31 May 2022 22:48:38 +0200
|
||||||
|
Subject: [PATCH 070/115] vdo: fix conversion of vdo_slab_size_mb
|
||||||
|
|
||||||
|
When converting VDO volume, the parameter vdo_slabSize was
|
||||||
|
incorrectly copied as vdo_blockMapCacheSize, however this parameter
|
||||||
|
is then no longer used for any table line creation so the wrong
|
||||||
|
value was only stored in metadata.
|
||||||
|
|
||||||
|
Also use just single get_kb_size_with_unit_ and remove it's duplicate
|
||||||
|
functionality with get_mb_size_with_unit_.
|
||||||
|
|
||||||
|
Use $VERB for vdo remove call.
|
||||||
|
|
||||||
|
(cherry picked from commit 1b070f366ba57a6eb24df03241284732db5047e9)
|
||||||
|
---
|
||||||
|
WHATS_NEW | 3 ++-
|
||||||
|
scripts/lvm_import_vdo.sh | 2 +-
|
||||||
|
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index bffd24648..705fbde74 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
Version 2.03.17 -
|
||||||
|
===============================
|
||||||
|
- Fix lvconvert --test --type vdo-pool execution.
|
||||||
|
+ Fix lvconvert --test --type vdo-pool execution.
|
||||||
|
+ Fix vdo_slab_size_mb value for converted VDO volume.
|
||||||
|
|
||||||
|
Version 2.03.16 -
|
||||||
|
====================================
|
||||||
|
diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh
|
||||||
|
index cc09187e9..c10b3b050 100755
|
||||||
|
--- a/scripts/lvm_import_vdo.sh
|
||||||
|
+++ b/scripts/lvm_import_vdo.sh
|
||||||
|
@@ -408,7 +408,7 @@ EOF
|
||||||
|
# Note: that this is spelled OPPOSITE the other $IS_LV checks.
|
||||||
|
if [ "$IS_LV" = "1" ]; then
|
||||||
|
verbose "Removing now-unused VDO entry from VDO config."
|
||||||
|
- dry "$VDO" remove $VDOCONF --force --verbose --name "$VDONAME"
|
||||||
|
+ dry "$VDO" remove $VDOCONF $VERB --force --name "$VDONAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -fr "$TEMPDIR"
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
396
SOURCES/0071-tests-add-lvm_vdo_wrapper.patch
Normal file
396
SOURCES/0071-tests-add-lvm_vdo_wrapper.patch
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
From 2456b39b345a589949528bd439052a776d274d63 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Tue, 31 May 2022 22:45:29 +0200
|
||||||
|
Subject: [PATCH 071/115] tests: add lvm_vdo_wrapper
|
||||||
|
|
||||||
|
Introduce a replacement vdo manager wrapper for testing.
|
||||||
|
When using test suite on a system without vdo manager (which has got
|
||||||
|
deprecated) - we still need its functionality to prepare 'vdo volume'
|
||||||
|
for testing lvm_import_vdo.
|
||||||
|
|
||||||
|
Wrapper currently need 2 binaries from older 'vdo 6.2' package -
|
||||||
|
to be named:
|
||||||
|
oldvdoformat - format VDO metadata with older format
|
||||||
|
oldvdoprepareforlvm - shift vdo metadata by 1MiB
|
||||||
|
|
||||||
|
(cherry picked from commit 2ecfd503edadaf5d46115826c629754bf9fd573f)
|
||||||
|
---
|
||||||
|
test/Makefile.in | 1 +
|
||||||
|
test/lib/lvm_vdo_wrapper.sh | 353 ++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 354 insertions(+)
|
||||||
|
create mode 100755 test/lib/lvm_vdo_wrapper.sh
|
||||||
|
|
||||||
|
diff --git a/test/Makefile.in b/test/Makefile.in
|
||||||
|
index ecb9e4264..f69dc97b6 100644
|
||||||
|
--- a/test/Makefile.in
|
||||||
|
+++ b/test/Makefile.in
|
||||||
|
@@ -369,6 +369,7 @@ LIB = $(addprefix lib/, $(LIB_SECURETEST) $(LIB_DMSECURETEST) $(LIB_SHARED) $(LI
|
||||||
|
$(Q) $(LN_S) -f $(abs_top_srcdir)/conf/thin-performance.profile lib/
|
||||||
|
$(Q) $(LN_S) -f $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
|
||||||
|
$(Q) $(LN_S) -f $(abs_top_srcdir)/scripts/lvm_import_vdo.sh lib/lvm_import_vdo
|
||||||
|
+ $(Q) which vdo || $(LN_S) -f $(abs_top_srcdir)/test/lib/lvm_vdo_wrapper.sh lib/vdo
|
||||||
|
@test "$(srcdir)" = . || \
|
||||||
|
for i in $(LIB_LVMLOCKD_CONF) $(LIB_MKE2FS_CONF); do \
|
||||||
|
test -n "$(Q)" || echo "$(LN_S) -f $(abs_top_srcdir)/test/lib/$$i lib/"; \
|
||||||
|
diff --git a/test/lib/lvm_vdo_wrapper.sh b/test/lib/lvm_vdo_wrapper.sh
|
||||||
|
new file mode 100755
|
||||||
|
index 000000000..d622d6456
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/lib/lvm_vdo_wrapper.sh
|
||||||
|
@@ -0,0 +1,353 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+#
|
||||||
|
+# Wrapper script for 'naive' emulation of vdo manager tool for systems
|
||||||
|
+# that no longer have this tool present
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+set -euE -o pipefail
|
||||||
|
+
|
||||||
|
+# tool for formating 'old' VDO metadata format
|
||||||
|
+LVM_VDO_FORMAT=${LVM_VDO_FORMAT-"oldvdoformat"}
|
||||||
|
+# tool for shifting VDO metadata header by 2MiB
|
||||||
|
+LVM_VDO_PREPARE=${LVM_VDO_PREPARE-"oldvdoprepareforlvm"}
|
||||||
|
+# default vdo conf file
|
||||||
|
+LVM_VDO_DEFAULT_CONF=${LVM_VDO_DEFAULT_CONF-"/tmp/vdoconf.yml"}
|
||||||
|
+
|
||||||
|
+vdo_die_() {
|
||||||
|
+ echo -e "$@" >&2
|
||||||
|
+ return 1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+vdo_verbose_() {
|
||||||
|
+ test -z "$vdo_verbose" || echo "$0:" "$@"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+vdo_dry_() {
|
||||||
|
+ if test -n "$vdo_dry"; then
|
||||||
|
+ vdo_verbose_ "Dry execution" "$@"
|
||||||
|
+ return 0
|
||||||
|
+ fi
|
||||||
|
+ vdo_verbose_ "Executing" "$@"
|
||||||
|
+ "$@"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+vdo_get_kb_size_with_unit_() {
|
||||||
|
+ local sz=${2-1} # 2nd. arg as unit - default 'k'
|
||||||
|
+
|
||||||
|
+ case "$sz" in
|
||||||
|
+ [mM]) sz=1024 ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ case "$1" in
|
||||||
|
+ *[mM]) sz=1024 ;;
|
||||||
|
+ *[gG]) sz=$(( 1024 * 1024 )) ;;
|
||||||
|
+ *[tT]) sz=$(( 1024 * 1024 * 1024 )) ;;
|
||||||
|
+ *[pP]) sz=$(( 1024 * 1024 * 1024 * 1024 )) ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ echo $(( sz * ${1%[kKmMgGtTpP]} ))
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Emulate functionality of deprecated 'vdo create'
|
||||||
|
+#
|
||||||
|
+vdo_create_() {
|
||||||
|
+local cachesize=
|
||||||
|
+local devsize=
|
||||||
|
+local emulate512=disabled
|
||||||
|
+local logicalsize=
|
||||||
|
+local maxdiscardsize=
|
||||||
|
+local slabbits=0 # 4k
|
||||||
|
+local slabsize=
|
||||||
|
+local sparse=
|
||||||
|
+local table=
|
||||||
|
+local vdo_compression_msg=
|
||||||
|
+local vdo_dry=
|
||||||
|
+local vdo_index_msg=
|
||||||
|
+local vdo_logicalBlockSize=
|
||||||
|
+local vdo_verbose=
|
||||||
|
+
|
||||||
|
+local vdo_ackThreads=${vdo_ackThreads-1}
|
||||||
|
+local vdo_bioRotationInterval=${vdo_bioRotationInterval-64}
|
||||||
|
+local vdo_bioThreads=${vdo_bioThreads-4}
|
||||||
|
+local vdo_blockMapCacheSize=${vdo_blockMapCacheSize-128M}
|
||||||
|
+local vdo_blockMapPeriod=${vdo_blockMapPeriod-16380}
|
||||||
|
+local vdo_compression=${vdo_compression-enabled}
|
||||||
|
+local vdo_confFile=$LVM_VDO_DEFAULT_CONF # place some file in /tmp
|
||||||
|
+local vdo_cpuThreads=${vdo_cpuThreads-2}
|
||||||
|
+local vdo_deduplication=${vdo_deduplication-enabled}
|
||||||
|
+local vdo_hashZoneThreads=${vdo_hashZoneThreads-1}
|
||||||
|
+local vdo_indexCfreq=${vdo_indexCfreq-0}
|
||||||
|
+local vdo_indexMemory=${vdo_indexMemory-0.25}
|
||||||
|
+local vdo_indexSparse=${vdo_indexSparse-disabled}
|
||||||
|
+local vdo_indexThreads=${vdo_indexThreads-0}
|
||||||
|
+local vdo_logicalSize=${vdo_logicalSize-0}
|
||||||
|
+local vdo_logicalThreads=${vdo_logicalThreads-1}
|
||||||
|
+local vdo_maxDiscardSize=${vdo_maxDiscardSize-4K}
|
||||||
|
+local vdo_name=${vdo_name-VDONAME}
|
||||||
|
+local vdo_physicalThreads=${vdo_physicalThreads-1}
|
||||||
|
+local vdo_slabSize=${vdo_slabSize-2G}
|
||||||
|
+local vdo_uuid="VDO-$(uuidgen || echo \"f7a3ecdc-40a0-4e43-814c-4a7039a75de4\")"
|
||||||
|
+local vdo_writePolicy=${vdo_writePolicy-auto}
|
||||||
|
+
|
||||||
|
+while [ "$#" -ne 0 ]
|
||||||
|
+do
|
||||||
|
+ case "$1" in
|
||||||
|
+ "--blockMapCacheSize") shift; vdo_blockMapCacheSize=$1 ;;
|
||||||
|
+ "--blockMapPeriod") shift; vdo_blockMapPeriod=$1 ;;
|
||||||
|
+ "--compression") shift; vdo_compression=$1 ;;
|
||||||
|
+ "--confFile"|"-f") shift; vdo_confFile=$1 ;;
|
||||||
|
+ "--deduplication") shift; vdo_deduplication=$1 ;;
|
||||||
|
+ "--device") shift; vdo_device=$1 ;;
|
||||||
|
+ "--emulate512") shift; emulate512=$1 ;;
|
||||||
|
+ "--indexMem") shift; vdo_indexMemory=$1 ;;
|
||||||
|
+ "--maxDiscardSize") shift; vdo_maxDiscardSize=$1 ;;
|
||||||
|
+ "--name"|"-n") shift; vdo_name=$1 ;;
|
||||||
|
+ "--sparseIndex") shift; vdo_indexSparse=$1 ;;
|
||||||
|
+ "--uuid") shift ;; # ignored
|
||||||
|
+ "--vdoAckThreads") shift; vdo_ackThreads=$1 ;;
|
||||||
|
+ "--vdoBioRotationInterval") shift; vdo_bioRotationInterval=$1 ;;
|
||||||
|
+ "--vdoBioThreads") shift; vdo_bioThreads=$1 ;;
|
||||||
|
+ "--vdoCpuThreads") shift; vdo_cpuThreads=$1 ;;
|
||||||
|
+ "--vdoHashZoneThreads") shift; vdo_hashZoneThreads=$1 ;;
|
||||||
|
+ "--vdoLogicalSize") shift; vdo_logicalSize=$1 ;;
|
||||||
|
+ "--vdoLogicalThreads") shift; vdo_logicalThreads=$1 ;;
|
||||||
|
+ "--vdoLogLevel") shift ;; # ignored
|
||||||
|
+ "--vdoPhysicalThreads") shift; vdo_physicalSize=$1 ;;
|
||||||
|
+ "--vdoSlabSize") shift; vdo_slabSize=$1 ;;
|
||||||
|
+ "--verbose"|"-d"|"--debug") vdo_verbose="-v" ;;
|
||||||
|
+ "--writePolicy") shift; vdo_writePolicy=$1 ;;
|
||||||
|
+ esac
|
||||||
|
+ shift
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+# Convert when set
|
||||||
|
+case "$emulate512" in
|
||||||
|
+ "enabled") vdo_logicalBlockSize=512 ;;
|
||||||
|
+ "disabled") vdo_logicalBlockSize=4096 ;;
|
||||||
|
+ *) vdo_die_ "Invalid emulate512 setting."
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+case "$vdo_deduplication" in
|
||||||
|
+ "enabled") vdo_index_msg="index-enable" ;;
|
||||||
|
+ "disabled") vdo_index_msg="index-disable";;
|
||||||
|
+ *) vdo_die_ "Invalid deduplication setting."
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+case "$vdo_compression" in
|
||||||
|
+ "enabled") vdo_compression_msg="compression on" ;;
|
||||||
|
+ "disabled") vdo_compression_msg="compression off";;
|
||||||
|
+ *) vdo_die_ "Invalid compression setting."
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+test -n "${vdo_device-}" || vdo_die_ "VDO device is missing"
|
||||||
|
+
|
||||||
|
+blkid -s UUID -o value "${vdo_device}" || true
|
||||||
|
+
|
||||||
|
+devsize=$(blockdev --getsize64 "$vdo_device")
|
||||||
|
+devsize=$(( devsize / 4096 )) # convert to 4KiB units
|
||||||
|
+
|
||||||
|
+logicalsize=$(vdo_get_kb_size_with_unit_ "$vdo_logicalSize" M)
|
||||||
|
+logicalsize=$(( logicalsize * 2 )) # 512B units
|
||||||
|
+
|
||||||
|
+cachesize=$(vdo_get_kb_size_with_unit_ "$vdo_blockMapCacheSize" M)
|
||||||
|
+cachesize=$(( cachesize / 4 )) # 4KiB units
|
||||||
|
+
|
||||||
|
+maxdiscardsize=$(vdo_get_kb_size_with_unit_ "$vdo_maxDiscardSize" M)
|
||||||
|
+maxdiscardsize=$(( maxdiscardsize / 4 )) # 4KiB units
|
||||||
|
+
|
||||||
|
+test -e "$vdo_confFile" || {
|
||||||
|
+ cat > "$vdo_confFile" <<EOF
|
||||||
|
+####################################################################
|
||||||
|
+# THIS FILE IS MACHINE GENERATED. DO NOT EDIT THIS FILE BY HAND.
|
||||||
|
+####################################################################
|
||||||
|
+config: !Configuration
|
||||||
|
+ vdos:
|
||||||
|
+EOF
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+cat >> "$vdo_confFile" <<EOF
|
||||||
|
+ $vdo_name: !VDOService
|
||||||
|
+ _operationState: finished
|
||||||
|
+ ackThreads: $vdo_ackThreads
|
||||||
|
+ activated: enabled
|
||||||
|
+ bioRotationInterval: $vdo_bioRotationInterval
|
||||||
|
+ bioThreads: $vdo_bioThreads
|
||||||
|
+ blockMapCacheSize: $(( cachesize * 4 ))K
|
||||||
|
+ blockMapPeriod: $vdo_blockMapPeriod
|
||||||
|
+ compression: $vdo_compression
|
||||||
|
+ cpuThreads: $vdo_cpuThreads
|
||||||
|
+ deduplication: $vdo_deduplication
|
||||||
|
+ device: $vdo_device
|
||||||
|
+ hashZoneThreads: $vdo_hashZoneThreads
|
||||||
|
+ indexCfreq: $vdo_indexCfreq
|
||||||
|
+ indexMemory: $vdo_indexMemory
|
||||||
|
+ indexSparse: $vdo_indexSparse
|
||||||
|
+ indexThreads: $vdo_indexThreads
|
||||||
|
+ logicalBlockSize: $vdo_logicalBlockSize
|
||||||
|
+ logicalSize: $(( logicalsize / 2 ))K
|
||||||
|
+ logicalThreads: $vdo_logicalThreads
|
||||||
|
+ maxDiscardSize: $(( maxdiscardsize * 4 ))K
|
||||||
|
+ name: $vdo_name
|
||||||
|
+ physicalSize: $(( devsize * 4 ))K
|
||||||
|
+ physicalThreads: $vdo_physicalThreads
|
||||||
|
+ slabSize: $vdo_slabSize
|
||||||
|
+ uuid: $vdo_uuid
|
||||||
|
+ writePolicy: $vdo_writePolicy
|
||||||
|
+ version: 538380551
|
||||||
|
+EOF
|
||||||
|
+
|
||||||
|
+slabsize=$(vdo_get_kb_size_with_unit_ "$vdo_slabSize")
|
||||||
|
+while test "$slabsize" -gt 4 ; do
|
||||||
|
+ slabbits=$(( slabbits + 1 ))
|
||||||
|
+ slabsize=$(( slabsize / 2 ))
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+case "$vdo_indexSparse" in
|
||||||
|
+ "enabled") sparse="--uds-sparse" ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+vdo_dry_ "$LVM_VDO_FORMAT" $vdo_verbose $sparse\
|
||||||
|
+ --logical-size "$vdo_logicalSize" --slab-bits "$slabbits"\
|
||||||
|
+ --uds-checkpoint-frequency "$vdo_indexCfreq"\
|
||||||
|
+ --uds-memory-size "$vdo_indexMemory" "$vdo_device"
|
||||||
|
+
|
||||||
|
+# V2 format
|
||||||
|
+table="0 $logicalsize vdo V2 $vdo_device\
|
||||||
|
+ $devsize\
|
||||||
|
+ $vdo_logicalBlockSize\
|
||||||
|
+ $cachesize\
|
||||||
|
+ $vdo_blockMapPeriod\
|
||||||
|
+ on\
|
||||||
|
+ $vdo_writePolicy\
|
||||||
|
+ $vdo_name\
|
||||||
|
+ maxDiscard $maxdiscardsize\
|
||||||
|
+ ack $vdo_ackThreads\
|
||||||
|
+ bio $vdo_bioThreads\
|
||||||
|
+ bioRotationInterval $vdo_bioRotationInterval\
|
||||||
|
+ cpu $vdo_cpuThreads\
|
||||||
|
+ hash $vdo_hashZoneThreads\
|
||||||
|
+ logical $vdo_logicalThreads\
|
||||||
|
+ physical $vdo_physicalThreads"
|
||||||
|
+
|
||||||
|
+vdo_dry_ dmsetup create "$vdo_name" --uuid "$vdo_uuid" --table "$table"
|
||||||
|
+vdo_dry_ dmsetup message "$vdo_name" 0 "$vdo_index_msg"
|
||||||
|
+vdo_dry_ dmsetup message "$vdo_name" 0 "$vdo_compression_msg"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vdo stop
|
||||||
|
+#
|
||||||
|
+vdo_stop_() {
|
||||||
|
+local vdo_confFile=$LVM_VDO_DEFAULT_CONF
|
||||||
|
+local vdo_dry=
|
||||||
|
+local vdo_force=
|
||||||
|
+local vdo_name=
|
||||||
|
+local vdo_verbose=
|
||||||
|
+
|
||||||
|
+while [ "$#" -ne 0 ]
|
||||||
|
+do
|
||||||
|
+ case "$1" in
|
||||||
|
+ "--confFile"|"-f") shift; vdo_confFile=$1 ;;
|
||||||
|
+ "--name"|"-n") shift; vdo_name=$1 ;;
|
||||||
|
+ "--verbose"|"-d"|"--debug") vdo_verbose="-v" ;;
|
||||||
|
+ "--force") vdo_force="--force" ;;
|
||||||
|
+ esac
|
||||||
|
+ shift
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+vdo_dry_ dmsetup status --target vdo "$vdo_name" 2>/dev/null || return 0
|
||||||
|
+vdo_dry_ dmsetup remove $vdo_force "$vdo_name" || true
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vdo remove
|
||||||
|
+#
|
||||||
|
+vdo_remove_() {
|
||||||
|
+local vdo_confFile=$LVM_VDO_DEFAULT_CONF
|
||||||
|
+local vdo_name=
|
||||||
|
+
|
||||||
|
+vdo_stop_ "$@"
|
||||||
|
+while [ "$#" -ne 0 ]
|
||||||
|
+do
|
||||||
|
+ case "$1" in
|
||||||
|
+ "--confFile"|"-f") shift; vdo_confFile=$1 ;;
|
||||||
|
+ "--name"|"-n") shift; vdo_name=$1 ;;
|
||||||
|
+ esac
|
||||||
|
+ shift
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+# remove entry from conf file
|
||||||
|
+awk -v vdovolname="$vdo_name" 'BEGIN { have=0 }
|
||||||
|
+ $0 ~ "!VDOService" { have=0 }
|
||||||
|
+ $0 ~ vdovolname":" { have=1 }
|
||||||
|
+ { if (have==0) { print } ;}
|
||||||
|
+ ' "$vdo_confFile" >"${vdo_confFile}.new"
|
||||||
|
+
|
||||||
|
+mv "${vdo_confFile}.new" "$vdo_confFile"
|
||||||
|
+grep "!VDOService" "$vdo_confFile" || rm -f "$vdo_confFile"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# print_config_file
|
||||||
|
+#
|
||||||
|
+vdo_print_config_file_() {
|
||||||
|
+local vdo_confFile=$LVM_VDO_DEFAULT_CONF
|
||||||
|
+
|
||||||
|
+while [ "$#" -ne 0 ]
|
||||||
|
+do
|
||||||
|
+ case "$1" in
|
||||||
|
+ "--confFile"|"-f") shift; vdo_confFile=$1 ;;
|
||||||
|
+ "--verbose"|"-d"|"--debug") ;;
|
||||||
|
+ "--logfile") shift ;; # ignore
|
||||||
|
+ esac
|
||||||
|
+ shift
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+cat "$vdo_confFile"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# vdo convert
|
||||||
|
+#
|
||||||
|
+vdo_convert_() {
|
||||||
|
+local vdo_confFile=$LVM_VDO_DEFAULT_CONF
|
||||||
|
+local vdo_dry=
|
||||||
|
+local vdo_force=
|
||||||
|
+local vdo_name=
|
||||||
|
+local vdo_verbose=
|
||||||
|
+local vdo_device=
|
||||||
|
+
|
||||||
|
+while [ "$#" -ne 0 ]
|
||||||
|
+do
|
||||||
|
+ case "$1" in
|
||||||
|
+ "--confFile"|"-f") shift; vdo_confFile=$1 ;;
|
||||||
|
+ "--name"|"-n") shift; vdo_name=$1 ;;
|
||||||
|
+ "--verbose"|"-d"|"--debug") vdo_verbose="-v" ;;
|
||||||
|
+ "--force") vdo_force="--force" ;;
|
||||||
|
+ esac
|
||||||
|
+ shift
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+vdo_device=$(awk -v vdovolname="$vdo_name" 'BEGIN { have=0 }
|
||||||
|
+ $0 ~ "!VDOService" { have=0 }
|
||||||
|
+ $0 ~ vdovolname":" { have=1 }
|
||||||
|
+ { if (have==1 && $0 ~ "device:" ) { print $2 } ;}'\
|
||||||
|
+ "$vdo_confFile")
|
||||||
|
+
|
||||||
|
+#dmsetup status --target vdo "$vdo_name" || true
|
||||||
|
+vdo_dry_ "$LVM_VDO_PREPARE" "$vdo_device"
|
||||||
|
+vdo_dry_ vdo_remove_ -f "$vdo_confFile" -n "$vdo_name" || true
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# MAIN
|
||||||
|
+#
|
||||||
|
+case "$1" in
|
||||||
|
+ "create") shift; vdo_create_ "$@" ;;
|
||||||
|
+ "remove") shift; vdo_remove_ "$@" ;;
|
||||||
|
+ "stop") shift; vdo_stop_ "$@" ;;
|
||||||
|
+ "convert") shift; vdo_convert_ "$@" ;;
|
||||||
|
+ "printConfigFile") shift; vdo_print_config_file_ "$@" ;;
|
||||||
|
+esac
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
84
SOURCES/0072-tests-update-for-wrapper.patch
Normal file
84
SOURCES/0072-tests-update-for-wrapper.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
From 64a78a2904c0481de8c1f9894cedcbd5f6525287 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Tue, 7 Jun 2022 16:52:30 +0200
|
||||||
|
Subject: [PATCH 072/115] tests: update for wrapper
|
||||||
|
|
||||||
|
Update calling vdo manager since our vdo wrapper has a simple shell
|
||||||
|
arg parser so it needs args without '='
|
||||||
|
|
||||||
|
Also correct using DM_DEV_DIR for 'pvcreate'
|
||||||
|
|
||||||
|
(cherry picked from commit 4a498512077b4fe5cf6b806a91228bd23e513123)
|
||||||
|
---
|
||||||
|
test/shell/vdo-convert.sh | 13 +++++++------
|
||||||
|
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh
|
||||||
|
index 2a2026c2e..8b03344a7 100644
|
||||||
|
--- a/test/shell/vdo-convert.sh
|
||||||
|
+++ b/test/shell/vdo-convert.sh
|
||||||
|
@@ -54,7 +54,7 @@ vgcreate $vg "$dev1"
|
||||||
|
|
||||||
|
lvcreate -L5G -n $lv1 $vg
|
||||||
|
|
||||||
|
-vdo create $VDOCONF --name "$VDONAME" --device="$DM_DEV_DIR/$vg/$lv1" --vdoLogicalSize=10G
|
||||||
|
+vdo create $VDOCONF --name "$VDONAME" --device "$DM_DEV_DIR/$vg/$lv1" --vdoSlabSize 128M --vdoLogicalSize 10G
|
||||||
|
|
||||||
|
mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME"
|
||||||
|
|
||||||
|
@@ -75,7 +75,7 @@ lvremove -f $vg
|
||||||
|
# Test user can specify different VDO LV name (so the original LV is renamed)
|
||||||
|
lvcreate -y -L5G -n $lv1 $vg
|
||||||
|
|
||||||
|
-vdo create $VDOCONF --name "$VDONAME" --device="$DM_DEV_DIR/$vg/$lv1" --vdoLogicalSize=10G
|
||||||
|
+vdo create $VDOCONF --name "$VDONAME" --device "$DM_DEV_DIR/$vg/$lv1" --vdoSlabSize 128M --vdoLogicalSize 10G
|
||||||
|
|
||||||
|
lvm_import_vdo -y --name $vg/$lv2 "$DM_DEV_DIR/$vg/$lv1"
|
||||||
|
|
||||||
|
@@ -95,7 +95,7 @@ vgcreate $vg2 "$dev2"
|
||||||
|
#
|
||||||
|
# Check conversion of VDO volume on non-LV device and with >2T size
|
||||||
|
#
|
||||||
|
-vdo create $VDOCONF --name "$VDONAME" --device="$dev1" --vdoLogicalSize=3T
|
||||||
|
+vdo create $VDOCONF --name "$VDONAME" --device "$dev1" --vdoSlabSize 128M --vdoLogicalSize 3T
|
||||||
|
|
||||||
|
# Fail with an already existing volume group $vg2
|
||||||
|
not lvm_import_vdo --dry-run -y -v --name $vg2/$lv1 "$dev1" |& tee err
|
||||||
|
@@ -117,7 +117,7 @@ vgremove -f $vg
|
||||||
|
aux teardown_devs
|
||||||
|
aux prepare_devs 1 23456
|
||||||
|
|
||||||
|
-vdo create $VDOCONF --name "$VDONAME" --device="$dev1" --vdoLogicalSize=23G
|
||||||
|
+vdo create $VDOCONF --name "$VDONAME" --device "$dev1" --vdoSlabSize 128M --vdoLogicalSize 23G
|
||||||
|
|
||||||
|
mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME"
|
||||||
|
|
||||||
|
@@ -137,6 +137,7 @@ aux prepare_loop 60000 || skip
|
||||||
|
|
||||||
|
test -f LOOP
|
||||||
|
LOOP=$(< LOOP)
|
||||||
|
+LOOP="${DM_DEV_DIR}/${LOOP##/dev/}"
|
||||||
|
|
||||||
|
aux extend_filter "a|$LOOP|"
|
||||||
|
aux extend_devices "$LOOP"
|
||||||
|
@@ -155,7 +156,7 @@ aux extend_devices "$LOOP"
|
||||||
|
#
|
||||||
|
# automate...
|
||||||
|
#
|
||||||
|
-vdo create $VDOCONF --name "$VDONAME" --device="$LOOP" --vdoLogicalSize=23G \
|
||||||
|
+vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoLogicalSize 23G\
|
||||||
|
--blockMapCacheSize 192 \
|
||||||
|
--blockMapPeriod 2048 \
|
||||||
|
--emulate512 disabled \
|
||||||
|
@@ -173,7 +174,7 @@ vdo create $VDOCONF --name "$VDONAME" --device="$LOOP" --vdoLogicalSize=23G \
|
||||||
|
# Get VDO table line
|
||||||
|
dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig
|
||||||
|
|
||||||
|
-DM_DEV_DIR="" lvm_import_vdo -y --name $vg/$lv "$LOOP"
|
||||||
|
+lvm_import_vdo -y --name $vg/$lv "$LOOP"
|
||||||
|
lvs -a $vg
|
||||||
|
|
||||||
|
dmsetup table "$vg-${lv}_vpool-vpool" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee new-vdo-lv
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,73 @@
|
|||||||
|
From 8702e97022753c9f21c85af6deecea76b179911d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tony Asleson <tasleson@redhat.com>
|
||||||
|
Date: Wed, 25 May 2022 16:03:27 -0500
|
||||||
|
Subject: [PATCH 073/115] lvmdbusd: Change unit test vdo minimum size
|
||||||
|
|
||||||
|
(cherry picked from commit 47c61907b4adbdead50f5bb5ac95c0f5d0fe263e)
|
||||||
|
---
|
||||||
|
test/dbus/lvmdbustest.py | 14 +++++++++-----
|
||||||
|
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
|
||||||
|
index 6d692223f..3eef77fd7 100755
|
||||||
|
--- a/test/dbus/lvmdbustest.py
|
||||||
|
+++ b/test/dbus/lvmdbustest.py
|
||||||
|
@@ -23,6 +23,9 @@ import os
|
||||||
|
|
||||||
|
g_tmo = 0
|
||||||
|
|
||||||
|
+# Approx. min size
|
||||||
|
+VDO_MIN_SIZE = mib(8192)
|
||||||
|
+
|
||||||
|
# Prefix on created objects to enable easier clean-up
|
||||||
|
g_prefix = os.getenv('PREFIX', '')
|
||||||
|
|
||||||
|
@@ -1155,7 +1158,7 @@ class TestDbusService(unittest.TestCase):
|
||||||
|
return
|
||||||
|
|
||||||
|
# This may not pass
|
||||||
|
- for i in [48, 64, 128]:
|
||||||
|
+ for i in [64, 128]:
|
||||||
|
yes = self._test_expired_timer(i)
|
||||||
|
if yes:
|
||||||
|
break
|
||||||
|
@@ -1907,8 +1910,8 @@ class TestDbusService(unittest.TestCase):
|
||||||
|
vdo_pool_object_path = self.handle_return(
|
||||||
|
vg_proxy.VgVdo.CreateVdoPoolandLv(
|
||||||
|
pool_name, lv_name,
|
||||||
|
- dbus.UInt64(mib(4096)), # Appears to be minimum size
|
||||||
|
- dbus.UInt64(mib(8192)),
|
||||||
|
+ dbus.UInt64(VDO_MIN_SIZE),
|
||||||
|
+ dbus.UInt64(VDO_MIN_SIZE * 2),
|
||||||
|
dbus.Int32(g_tmo),
|
||||||
|
EOD))
|
||||||
|
|
||||||
|
@@ -1950,7 +1953,7 @@ class TestDbusService(unittest.TestCase):
|
||||||
|
vg_proxy = self._vg_create(vg_prefix="vdo_conv_")
|
||||||
|
lv = self._test_lv_create(
|
||||||
|
vg_proxy.Vg.LvCreate,
|
||||||
|
- (dbus.String(pool_name), dbus.UInt64(mib(4096)),
|
||||||
|
+ (dbus.String(pool_name), dbus.UInt64(VDO_MIN_SIZE),
|
||||||
|
dbus.Array([], signature='(ott)'), dbus.Int32(g_tmo),
|
||||||
|
EOD), vg_proxy.Vg, LV_BASE_INT)
|
||||||
|
lv_obj_path = self._lookup("%s/%s" % (vg_proxy.Vg.Name, pool_name))
|
||||||
|
@@ -1959,7 +1962,7 @@ class TestDbusService(unittest.TestCase):
|
||||||
|
vdo_pool_path = self.handle_return(
|
||||||
|
vg_proxy.VgVdo.CreateVdoPool(
|
||||||
|
dbus.ObjectPath(lv.object_path), lv_name,
|
||||||
|
- dbus.UInt64(mib(8192)),
|
||||||
|
+ dbus.UInt64(VDO_MIN_SIZE),
|
||||||
|
dbus.Int32(g_tmo),
|
||||||
|
EOD))
|
||||||
|
|
||||||
|
@@ -2083,6 +2086,7 @@ if __name__ == '__main__':
|
||||||
|
std_err_print('\n*** Testing only lvm shell mode ***\n')
|
||||||
|
|
||||||
|
for g_tmo in [0, 15]:
|
||||||
|
+ std_err_print('Testing TMO=%d\n' % g_tmo)
|
||||||
|
if mode == 0:
|
||||||
|
if set_execution(False, r):
|
||||||
|
r.register_result(unittest.main(exit=False))
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From e82e23447f830bd6c38bbefa600212e84cdb0f27 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Mon, 11 Jul 2022 01:07:24 +0200
|
||||||
|
Subject: [PATCH 074/115] vdo: fix conversion of vdo_slab_size_mb 2nd
|
||||||
|
|
||||||
|
Patch 1b070f366ba57a6eb24df03241284732db5047e9 should have
|
||||||
|
been already fixing this issue but since it the incorrect
|
||||||
|
patch rebasing the change to vdo_slabSize got lost.
|
||||||
|
So again now with explicit one-line patch.
|
||||||
|
|
||||||
|
(cherry picked from commit d2667bc25bccaf0f70cc2ded0fd3f25a79cb4f6c)
|
||||||
|
---
|
||||||
|
scripts/lvm_import_vdo.sh | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh
|
||||||
|
index c10b3b050..c4c1d152e 100755
|
||||||
|
--- a/scripts/lvm_import_vdo.sh
|
||||||
|
+++ b/scripts/lvm_import_vdo.sh
|
||||||
|
@@ -324,7 +324,7 @@ allocation {
|
||||||
|
vdo_check_point_frequency = $vdo_indexCfreq
|
||||||
|
vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse")
|
||||||
|
vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}")
|
||||||
|
- vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
|
||||||
|
+ vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_slabSize") / 1024 ))
|
||||||
|
vdo_ack_threads = $vdo_ackThreads
|
||||||
|
vdo_bio_threads = $vdo_bioThreads
|
||||||
|
vdo_bio_rotation = $vdo_bioRotationInterval
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
49
SOURCES/0075-vdo-update-info-about-memory.patch
Normal file
49
SOURCES/0075-vdo-update-info-about-memory.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From 1a39e0c2c24c7c505753658f9a74bf962fdf013b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Mon, 4 Jul 2022 15:00:26 +0200
|
||||||
|
Subject: [PATCH 075/115] vdo: update info about memory
|
||||||
|
|
||||||
|
Add more info about kernel target memory allocation associated with
|
||||||
|
VDO pool usage.
|
||||||
|
|
||||||
|
(cherry picked from commit f445624c339a5c1436a47d2b51046869f183eb03)
|
||||||
|
---
|
||||||
|
man/lvmvdo.7_main | 15 ++++++++++++---
|
||||||
|
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/lvmvdo.7_main b/man/lvmvdo.7_main
|
||||||
|
index 14bd640b5..8c3e3eeaa 100644
|
||||||
|
--- a/man/lvmvdo.7_main
|
||||||
|
+++ b/man/lvmvdo.7_main
|
||||||
|
@@ -12,7 +12,7 @@ for primary storage.
|
||||||
|
.P
|
||||||
|
Deduplication is a technique for reducing the consumption of storage
|
||||||
|
resources by eliminating multiple copies of duplicate blocks. Compression
|
||||||
|
-takes the individual unique blocks and shrinks them.
|
||||||
|
+takes the individual unique blocks and shrinks them.
|
||||||
|
These reduced blocks are then efficiently packed together into
|
||||||
|
physical blocks. Thin provisioning manages the mapping from logical blocks
|
||||||
|
presented by VDO to where the data has actually been physically stored,
|
||||||
|
@@ -358,8 +358,17 @@ take otherwise as device is already expected to be empty.
|
||||||
|
.
|
||||||
|
.SS \n+[step]. Memory usage
|
||||||
|
.
|
||||||
|
-The VDO target requires 370 MiB of RAM plus an additional 268 MiB
|
||||||
|
-per each 1 TiB of physical storage managed by the volume.
|
||||||
|
+The VDO target requires 38 MiB of RAM and several variable amounts:
|
||||||
|
+.IP \(bu 2
|
||||||
|
+1.15 MiB of RAM for each 1 MiB of configured block map cache size.
|
||||||
|
+The block map cache requires a minimum of 150 MiB RAM.
|
||||||
|
+.br
|
||||||
|
+.IP \(bu
|
||||||
|
+1.6 MiB of RAM for each 1 TiB of logical space.
|
||||||
|
+.br
|
||||||
|
+.IP \(bu
|
||||||
|
+268 MiB of RAM for each 1 TiB of physical storage managed by the volume.
|
||||||
|
+.br
|
||||||
|
.P
|
||||||
|
UDS requires a minimum of 250 MiB of RAM,
|
||||||
|
which is also the default amount that deduplication uses.
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
246
SOURCES/0076-vdo-check-vdo-memory-constrains.patch
Normal file
246
SOURCES/0076-vdo-check-vdo-memory-constrains.patch
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
From 783213e4da16a70f5e3d5efae2d409b92d899fc9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Fri, 8 Jul 2022 23:33:29 +0200
|
||||||
|
Subject: [PATCH 076/115] vdo: check vdo memory constrains
|
||||||
|
|
||||||
|
Add function to check for avaialble memory for particular VDO
|
||||||
|
configuration - to avoid unnecessary machine swapping for configs
|
||||||
|
that will not fit into memory (possibly in locked section).
|
||||||
|
|
||||||
|
Formula tries to estimate RAM size machine can use also with
|
||||||
|
swapping for kernel target - but still leaving some amount of
|
||||||
|
usable RAM.
|
||||||
|
|
||||||
|
Estimation is based on documented RAM usage of VDO target.
|
||||||
|
|
||||||
|
If the /proc/meminfo would be theoretically unavailable, try to use
|
||||||
|
'sysinfo()' function, however this is giving only free RAM without
|
||||||
|
the knowledge about how much RAM could be eventually swapped.
|
||||||
|
|
||||||
|
TODO: move _get_memory_info() into generic lvm2 API function used
|
||||||
|
by other targets with non-trivial memory requirements.
|
||||||
|
|
||||||
|
(cherry picked from commit ebad057579aeff0980a1b8af7eaacd56e62ed0c9)
|
||||||
|
---
|
||||||
|
lib/metadata/metadata-exported.h | 2 +
|
||||||
|
lib/metadata/vdo_manip.c | 144 +++++++++++++++++++++++++++++++
|
||||||
|
lib/vdo/vdo.c | 8 +-
|
||||||
|
tools/lvcreate.c | 4 +
|
||||||
|
4 files changed, 156 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||||||
|
index 7bac5b900..449c8d014 100644
|
||||||
|
--- a/lib/metadata/metadata-exported.h
|
||||||
|
+++ b/lib/metadata/metadata-exported.h
|
||||||
|
@@ -1377,6 +1377,8 @@ int fill_vdo_target_params(struct cmd_context *cmd,
|
||||||
|
struct dm_vdo_target_params *vtp,
|
||||||
|
uint64_t *vdo_pool_header_size,
|
||||||
|
struct profile *profile);
|
||||||
|
+int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size,
|
||||||
|
+ uint64_t virtual_size, struct dm_vdo_target_params *vtp);
|
||||||
|
/* -- metadata/vdo_manip.c */
|
||||||
|
|
||||||
|
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index 11a119a68..9f449ef8b 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -23,6 +23,8 @@
|
||||||
|
#include "lib/config/defaults.h"
|
||||||
|
#include "lib/misc/lvm-exec.h"
|
||||||
|
|
||||||
|
+#include <sys/sysinfo.h> // sysinfo
|
||||||
|
+
|
||||||
|
const char *get_vdo_compression_state_name(enum dm_vdo_compression_state state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
@@ -516,3 +518,145 @@ int fill_vdo_target_params(struct cmd_context *cmd,
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static int _get_sysinfo_memory(uint64_t *total_mb, uint64_t *available_mb)
|
||||||
|
+{
|
||||||
|
+ struct sysinfo si = { 0 };
|
||||||
|
+
|
||||||
|
+ *total_mb = *available_mb = UINT64_MAX;
|
||||||
|
+
|
||||||
|
+ if (sysinfo(&si) != 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ log_debug("Sysinfo free:%lu bufferram:%lu sharedram:%lu freehigh:%lu unit:%u.",
|
||||||
|
+ si.freeram >> 20, si.bufferram >> 20, si.sharedram >> 20,
|
||||||
|
+ si.freehigh >> 20, si.mem_unit);
|
||||||
|
+
|
||||||
|
+ *available_mb = ((uint64_t)(si.freeram + si.bufferram) * si.mem_unit) >> 30;
|
||||||
|
+ *total_mb = si.totalram >> 30;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+typedef struct mem_table_s {
|
||||||
|
+ const char *name;
|
||||||
|
+ uint64_t *value;
|
||||||
|
+} mem_table_t;
|
||||||
|
+
|
||||||
|
+static int _compare_mem_table_s(const void *a, const void *b){
|
||||||
|
+ return strcmp(((const mem_table_t*)a)->name, ((const mem_table_t*)b)->name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int _get_memory_info(uint64_t *total_mb, uint64_t *available_mb)
|
||||||
|
+{
|
||||||
|
+ uint64_t anon_pages, mem_available, mem_free, mem_total, shmem, swap_free;
|
||||||
|
+ uint64_t can_swap;
|
||||||
|
+ mem_table_t mt[] = {
|
||||||
|
+ { "AnonPages", &anon_pages },
|
||||||
|
+ { "MemAvailable", &mem_available },
|
||||||
|
+ { "MemFree", &mem_free },
|
||||||
|
+ { "MemTotal", &mem_total },
|
||||||
|
+ { "Shmem", &shmem },
|
||||||
|
+ { "SwapFree", &swap_free },
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ char line[128], namebuf[32], *e, *tail;
|
||||||
|
+ FILE *fp;
|
||||||
|
+ mem_table_t findme = { namebuf, NULL };
|
||||||
|
+ mem_table_t *found;
|
||||||
|
+
|
||||||
|
+ if (!(fp = fopen("/proc/meminfo", "r")))
|
||||||
|
+ return _get_sysinfo_memory(total_mb, available_mb);
|
||||||
|
+
|
||||||
|
+ while (fgets(line, sizeof(line), fp)) {
|
||||||
|
+ if (!(e = strchr(line, ':')))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if ((++e - line) > sizeof(namebuf))
|
||||||
|
+ continue; // something too long
|
||||||
|
+
|
||||||
|
+ (void)dm_strncpy((char*)findme.name, line, e - line);
|
||||||
|
+
|
||||||
|
+ found = bsearch(&findme, mt, DM_ARRAY_SIZE(mt), sizeof(mem_table_t),
|
||||||
|
+ _compare_mem_table_s);
|
||||||
|
+ if (!found)
|
||||||
|
+ continue; // not interesting
|
||||||
|
+
|
||||||
|
+ *(found->value) = (uint64_t) strtoull(e, &tail, 10);
|
||||||
|
+
|
||||||
|
+ if ((e == tail) || errno)
|
||||||
|
+ log_debug("Failing to parse value from %s.", line);
|
||||||
|
+ else
|
||||||
|
+ log_debug("Parsed %s = " FMTu64 " KiB.", found->name, *(found->value));
|
||||||
|
+ }
|
||||||
|
+ (void)fclose(fp);
|
||||||
|
+
|
||||||
|
+ // use at most 2/3 of swap space to keep machine usable
|
||||||
|
+ can_swap = (anon_pages + shmem) * 2 / 3;
|
||||||
|
+ swap_free = swap_free * 2 / 3;
|
||||||
|
+
|
||||||
|
+ if (can_swap > swap_free)
|
||||||
|
+ can_swap = swap_free;
|
||||||
|
+
|
||||||
|
+ // TODO: add more constrains, i.e. 3/4 of physical RAM...
|
||||||
|
+
|
||||||
|
+ *total_mb = mem_total >> 10;
|
||||||
|
+ *available_mb = (mem_available + can_swap) >> 10;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uint64_t _round_1024(uint64_t s)
|
||||||
|
+{
|
||||||
|
+ return (s + ((1 << 10) - 1)) >> 10;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uint64_t _round_sectors_to_tib(uint64_t s)
|
||||||
|
+{
|
||||||
|
+ return (s + ((UINT64_C(1) << (40 - SECTOR_SHIFT)) - 1)) >> (40 - SECTOR_SHIFT);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size,
|
||||||
|
+ uint64_t virtual_size, struct dm_vdo_target_params *vtp)
|
||||||
|
+{
|
||||||
|
+ uint64_t req_mb, total_mb, available_mb;
|
||||||
|
+ uint64_t phy_mb = _round_sectors_to_tib(UINT64_C(268) * physical_size); // 268 MiB per 1 TiB of physical size
|
||||||
|
+ uint64_t virt_mb = _round_1024(UINT64_C(1638) * _round_sectors_to_tib(virtual_size)); // 1.6 MiB per 1 TiB
|
||||||
|
+ uint64_t cache_mb = _round_1024(UINT64_C(1177) * vtp->block_map_cache_size_mb); // 1.15 MiB per 1 MiB cache size
|
||||||
|
+ char msg[512];
|
||||||
|
+
|
||||||
|
+ if (cache_mb < 150)
|
||||||
|
+ cache_mb = 150; // always at least 150 MiB for block map
|
||||||
|
+
|
||||||
|
+ // total required memory for VDO target
|
||||||
|
+ req_mb = 38 + vtp->index_memory_size_mb + virt_mb + phy_mb + cache_mb;
|
||||||
|
+
|
||||||
|
+ _get_memory_info(&total_mb, &available_mb);
|
||||||
|
+
|
||||||
|
+ (void)snprintf(msg, sizeof(msg), "VDO configuration needs %s RAM for physical volume size %s, "
|
||||||
|
+ "%s RAM for virtual volume size %s, %s RAM for block map cache size %s and "
|
||||||
|
+ "%s RAM for index memory.",
|
||||||
|
+ display_size(cmd, phy_mb << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(cmd, physical_size),
|
||||||
|
+ display_size(cmd, virt_mb << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(cmd, virtual_size),
|
||||||
|
+ display_size(cmd, cache_mb << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(cmd, ((uint64_t)vtp->block_map_cache_size_mb) << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(cmd, ((uint64_t)vtp->index_memory_size_mb) << (20 - SECTOR_SHIFT)));
|
||||||
|
+
|
||||||
|
+ if (req_mb > available_mb) {
|
||||||
|
+ log_error("Not enough free memory for VDO target. %s RAM is required, but only %s RAM is available.",
|
||||||
|
+ display_size(cmd, req_mb << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(cmd, available_mb << (20 - SECTOR_SHIFT)));
|
||||||
|
+ log_print_unless_silent("%s", msg);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_debug("VDO requires %s RAM, currently available %s RAM.",
|
||||||
|
+ display_size(cmd, req_mb << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(cmd, available_mb << (20 - SECTOR_SHIFT)));
|
||||||
|
+
|
||||||
|
+ log_verbose("%s", msg);
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
|
||||||
|
index 52e9443ea..b9bcc044f 100644
|
||||||
|
--- a/lib/vdo/vdo.c
|
||||||
|
+++ b/lib/vdo/vdo.c
|
||||||
|
@@ -355,8 +355,8 @@ static int _vdo_pool_target_status_compatible(const char *type)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||||
|
- struct dm_pool *mem __attribute__((unused)),
|
||||||
|
- struct cmd_context *cmd __attribute__((unused)),
|
||||||
|
+ struct dm_pool *mem,
|
||||||
|
+ struct cmd_context *cmd,
|
||||||
|
void **target_state __attribute__((unused)),
|
||||||
|
struct lv_segment *seg,
|
||||||
|
const struct lv_activate_opts *laopts __attribute__((unused)),
|
||||||
|
@@ -369,6 +369,10 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||||
|
log_error(INTERNAL_ERROR "Passed segment is not VDO pool.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (!check_vdo_constrains(cmd, seg->lv->size, seg_lv(seg, 0)->size, &seg->vdo_params))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
if (!(vdo_pool_name = dm_build_dm_name(mem, seg->lv->vg->name, seg->lv->name, lv_layer(seg->lv))))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index 8de6f3408..fb57d84bd 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -1729,6 +1729,10 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
|
||||||
|
if (!_update_extents_params(vg, lp, lcp))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
+ if (seg_is_vdo(lp) && !check_vdo_constrains(cmd, (uint64_t)lp->extents * vg->extent_size,
|
||||||
|
+ lcp->virtual_size, &lp->vdo_params))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
if (seg_is_thin(lp) && !_validate_internal_thin_processing(lp))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,79 @@
|
|||||||
|
From d2a2720ccb88d99c76423ebd5c3bb1f13dc60ab1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Sat, 9 Jul 2022 00:42:01 +0200
|
||||||
|
Subject: [PATCH 077/115] vdo: add reformating to extent size aligned virtual
|
||||||
|
size
|
||||||
|
|
||||||
|
Newer VDO kernel target require to have matching virtual size - this
|
||||||
|
however cause incompatiblity when lvcreate is let to format VDO data
|
||||||
|
device and read the usable size from vdoformat.
|
||||||
|
Altough this is a kernel regression and will likely get fixed,
|
||||||
|
lvm2 can actually reformat VDO device to use properly aligned VDO LV
|
||||||
|
size to make this problem disappear.
|
||||||
|
|
||||||
|
(cherry picked from commit a477490e812639fed3be495f215fcf1a7b65b7ee)
|
||||||
|
---
|
||||||
|
lib/metadata/vdo_manip.c | 22 +++++++++++++++++++---
|
||||||
|
1 file changed, 19 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index 9f449ef8b..f3a4a9534 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -227,10 +227,11 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||||
|
const struct dm_vdo_target_params *vtp,
|
||||||
|
uint64_t *logical_size)
|
||||||
|
{
|
||||||
|
- char *dpath;
|
||||||
|
+ char *dpath, *c;
|
||||||
|
const struct dm_config_node *cn;
|
||||||
|
const struct dm_config_value *cv;
|
||||||
|
struct pipe_data pdata;
|
||||||
|
+ uint64_t logical_size_aligned = 1;
|
||||||
|
FILE *f;
|
||||||
|
uint64_t lb;
|
||||||
|
unsigned slabbits;
|
||||||
|
@@ -247,7 +248,9 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+reformat:
|
||||||
|
if (*logical_size) {
|
||||||
|
+ logical_size_aligned = 0;
|
||||||
|
if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K",
|
||||||
|
(*logical_size / 2)) < 0)
|
||||||
|
return_0;
|
||||||
|
@@ -332,8 +335,8 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||||
|
log_verbose("Available VDO logical blocks " FMTu64 " (%s).",
|
||||||
|
lb, display_size(data_lv->vg->cmd, *logical_size));
|
||||||
|
}
|
||||||
|
- if ((dpath = strchr(buf, '\n')))
|
||||||
|
- *dpath = 0; /* cut last '\n' away */
|
||||||
|
+ if ((c = strchr(buf, '\n')))
|
||||||
|
+ *c = 0; /* cut last '\n' away */
|
||||||
|
if (buf[0])
|
||||||
|
log_print(" %s", buf); /* Print vdo_format messages */
|
||||||
|
}
|
||||||
|
@@ -348,6 +351,19 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (logical_size_aligned) {
|
||||||
|
+ // align obtained size to extent size
|
||||||
|
+ logical_size_aligned = *logical_size / data_lv->vg->extent_size * data_lv->vg->extent_size;
|
||||||
|
+ if (*logical_size != logical_size_aligned) {
|
||||||
|
+ *logical_size = logical_size_aligned;
|
||||||
|
+ argv[1] = (char*) "--force";
|
||||||
|
+ args = 2;
|
||||||
|
+ log_verbose("Reformating VDO to align virtual size %s by extent size.",
|
||||||
|
+ display_size(data_lv->vg->cmd, *logical_size));
|
||||||
|
+ goto reformat;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
172
SOURCES/0078-vdo-support-v4-kernel-target-line.patch
Normal file
172
SOURCES/0078-vdo-support-v4-kernel-target-line.patch
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
From c160f54ec5cc26b78db38058f1a8bd63da9e225d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Fri, 8 Jul 2022 23:35:06 +0200
|
||||||
|
Subject: [PATCH 078/115] vdo: support v4 kernel target line
|
||||||
|
|
||||||
|
Check and use new available table line v4, if kernel supports it.
|
||||||
|
|
||||||
|
(cherry picked from commit 1c18ed3b4ab2f2d5a15995b8f0a18d7d1c4d60ca)
|
||||||
|
---
|
||||||
|
device_mapper/all.h | 1 +
|
||||||
|
device_mapper/libdm-deptree.c | 37 +++++++++++++++++++++++------------
|
||||||
|
lib/metadata/segtype.h | 1 +
|
||||||
|
lib/vdo/vdo.c | 10 ++++++++--
|
||||||
|
test/shell/vdo-convert.sh | 2 ++
|
||||||
|
5 files changed, 37 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/device_mapper/all.h b/device_mapper/all.h
|
||||||
|
index 17f78d989..e45f5923a 100644
|
||||||
|
--- a/device_mapper/all.h
|
||||||
|
+++ b/device_mapper/all.h
|
||||||
|
@@ -1020,6 +1020,7 @@ int dm_tree_node_add_integrity_target(struct dm_tree_node *node,
|
||||||
|
*/
|
||||||
|
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||||
|
uint64_t size,
|
||||||
|
+ uint32_t vdo_version,
|
||||||
|
const char *vdo_pool_name,
|
||||||
|
const char *data_uuid,
|
||||||
|
uint64_t data_size,
|
||||||
|
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
|
||||||
|
index e4bf4c814..2d382037c 100644
|
||||||
|
--- a/device_mapper/libdm-deptree.c
|
||||||
|
+++ b/device_mapper/libdm-deptree.c
|
||||||
|
@@ -214,6 +214,7 @@ struct load_segment {
|
||||||
|
uint32_t device_id; /* Thin */
|
||||||
|
|
||||||
|
// VDO params
|
||||||
|
+ uint32_t vdo_version; /* VDO - version of target table line */
|
||||||
|
struct dm_tree_node *vdo_data; /* VDO */
|
||||||
|
struct dm_vdo_target_params vdo_params; /* VDO */
|
||||||
|
const char *vdo_name; /* VDO - device name is ALSO passed as table arg */
|
||||||
|
@@ -2865,18 +2866,28 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s "
|
||||||
|
- "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u",
|
||||||
|
- data_dev,
|
||||||
|
- seg->vdo_data_size / 8, // this parameter is in 4K units
|
||||||
|
- seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units
|
||||||
|
- seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units
|
||||||
|
- seg->vdo_params.block_map_era_length,
|
||||||
|
- seg->vdo_params.use_metadata_hints ? "on" : "off" ,
|
||||||
|
- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" :
|
||||||
|
- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" :
|
||||||
|
- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy
|
||||||
|
- seg->vdo_name,
|
||||||
|
+ if (seg->vdo_version < 4) {
|
||||||
|
+ EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s ",
|
||||||
|
+ data_dev,
|
||||||
|
+ seg->vdo_data_size / 8, // this parameter is in 4K units
|
||||||
|
+ seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units
|
||||||
|
+ seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units
|
||||||
|
+ seg->vdo_params.block_map_era_length,
|
||||||
|
+ seg->vdo_params.use_metadata_hints ? "on" : "off" ,
|
||||||
|
+ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" :
|
||||||
|
+ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" :
|
||||||
|
+ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy
|
||||||
|
+ seg->vdo_name);
|
||||||
|
+ } else {
|
||||||
|
+ EMIT_PARAMS(pos, "V4 %s " FMTu64 " %u " FMTu64 " %u ",
|
||||||
|
+ data_dev,
|
||||||
|
+ seg->vdo_data_size / 8, // this parameter is in 4K units
|
||||||
|
+ seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units
|
||||||
|
+ seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units
|
||||||
|
+ seg->vdo_params.block_map_era_length);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ EMIT_PARAMS(pos, "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u",
|
||||||
|
seg->vdo_params.max_discard,
|
||||||
|
seg->vdo_params.ack_threads,
|
||||||
|
seg->vdo_params.bio_threads,
|
||||||
|
@@ -4323,6 +4334,7 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
|
||||||
|
|
||||||
|
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||||
|
uint64_t size,
|
||||||
|
+ uint32_t vdo_version,
|
||||||
|
const char *vdo_pool_name,
|
||||||
|
const char *data_uuid,
|
||||||
|
uint64_t data_size,
|
||||||
|
@@ -4344,6 +4356,7 @@ int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||||
|
if (!_link_tree_nodes(node, seg->vdo_data))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ seg->vdo_version = vdo_version;
|
||||||
|
seg->vdo_params = *vtp;
|
||||||
|
seg->vdo_name = vdo_pool_name;
|
||||||
|
seg->vdo_data_size = data_size;
|
||||||
|
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
|
||||||
|
index 2f4949267..3e52f04a1 100644
|
||||||
|
--- a/lib/metadata/segtype.h
|
||||||
|
+++ b/lib/metadata/segtype.h
|
||||||
|
@@ -353,6 +353,7 @@ int init_vdo_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VDO_FEATURE_ONLINE_RENAME (1U << 0) /* version 6.2.3 */
|
||||||
|
+#define VDO_FEATURE_VERSION4 (1U << 1) /* version 8.2.0 */
|
||||||
|
|
||||||
|
int init_writecache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||||
|
|
||||||
|
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
|
||||||
|
index b9bcc044f..9efb424f0 100644
|
||||||
|
--- a/lib/vdo/vdo.c
|
||||||
|
+++ b/lib/vdo/vdo.c
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -364,6 +364,10 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||||
|
uint32_t *pvmove_mirror_count __attribute__((unused)))
|
||||||
|
{
|
||||||
|
char *vdo_pool_name, *data_uuid;
|
||||||
|
+ unsigned attrs = 0;
|
||||||
|
+
|
||||||
|
+ if (seg->segtype->ops->target_present)
|
||||||
|
+ seg->segtype->ops->target_present(cmd, NULL, &attrs);
|
||||||
|
|
||||||
|
if (!seg_is_vdo_pool(seg)) {
|
||||||
|
log_error(INTERNAL_ERROR "Passed segment is not VDO pool.");
|
||||||
|
@@ -381,6 +385,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||||
|
|
||||||
|
/* VDO uses virtual size instead of its physical size */
|
||||||
|
if (!dm_tree_node_add_vdo_target(node, get_vdo_pool_virtual_size(seg),
|
||||||
|
+ !(attrs & VDO_FEATURE_VERSION4) ? 2 : 4,
|
||||||
|
vdo_pool_name, data_uuid, seg_lv(seg, 0)->size,
|
||||||
|
&seg->vdo_params))
|
||||||
|
return_0;
|
||||||
|
@@ -390,7 +395,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||||
|
|
||||||
|
static int _vdo_target_present(struct cmd_context *cmd,
|
||||||
|
const struct lv_segment *seg __attribute__((unused)),
|
||||||
|
- unsigned *attributes __attribute__((unused)))
|
||||||
|
+ unsigned *attributes)
|
||||||
|
{
|
||||||
|
/* List of features with their kernel target version */
|
||||||
|
static const struct feature {
|
||||||
|
@@ -401,6 +406,7 @@ static int _vdo_target_present(struct cmd_context *cmd,
|
||||||
|
const char *feature;
|
||||||
|
} _features[] = {
|
||||||
|
{ 6, 2, 3, VDO_FEATURE_ONLINE_RENAME, "online_rename" },
|
||||||
|
+ { 8, 2, 0, VDO_FEATURE_VERSION4, "version4" },
|
||||||
|
};
|
||||||
|
static const char _lvmconf[] = "global/vdo_disabled_features";
|
||||||
|
static int _vdo_checked = 0;
|
||||||
|
diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh
|
||||||
|
index 8b03344a7..f1d04d596 100644
|
||||||
|
--- a/test/shell/vdo-convert.sh
|
||||||
|
+++ b/test/shell/vdo-convert.sh
|
||||||
|
@@ -174,6 +174,8 @@ vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoL
|
||||||
|
# Get VDO table line
|
||||||
|
dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig
|
||||||
|
|
||||||
|
+aux lvmconf 'global/vdo_disabled_features = [ "version4" ]'
|
||||||
|
+
|
||||||
|
lvm_import_vdo -y --name $vg/$lv "$LOOP"
|
||||||
|
lvs -a $vg
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
171
SOURCES/0079-vdo-enhance-lvcreate-validation.patch
Normal file
171
SOURCES/0079-vdo-enhance-lvcreate-validation.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
From aa75359c7c1baae43349416f3761754507cd5c1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Fri, 8 Jul 2022 23:38:34 +0200
|
||||||
|
Subject: [PATCH 079/115] vdo: enhance lvcreate validation
|
||||||
|
|
||||||
|
When creating VDO pool based of % values, lvm2 is now more clever
|
||||||
|
and avoids to create 'unsupportable' sizes of physical backend
|
||||||
|
volumes as 16TiB is maximum size supported by VDO target
|
||||||
|
(and also limited by maximum supportable slabs (8192) based on slab
|
||||||
|
size.
|
||||||
|
|
||||||
|
If the requested virtual size is approaching max supported size 4PiB,
|
||||||
|
switch header size to 0.
|
||||||
|
|
||||||
|
(cherry picked from commit e2e31d9acf1b96ab741c22dc0a2fefd672996d3a)
|
||||||
|
---
|
||||||
|
lib/metadata/metadata-exported.h | 2 ++
|
||||||
|
lib/metadata/vdo_manip.c | 14 ++++++++++
|
||||||
|
tools/lvcreate.c | 48 ++++++++++++++++++++++++++------
|
||||||
|
3 files changed, 56 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||||||
|
index 449c8d014..f735baa55 100644
|
||||||
|
--- a/lib/metadata/metadata-exported.h
|
||||||
|
+++ b/lib/metadata/metadata-exported.h
|
||||||
|
@@ -1364,6 +1364,8 @@ const char *get_vdo_operating_mode_name(enum dm_vdo_operating_mode mode);
|
||||||
|
const char *get_vdo_write_policy_name(enum dm_vdo_write_policy policy);
|
||||||
|
uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg);
|
||||||
|
int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg);
|
||||||
|
+uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
|
||||||
|
+ uint32_t extent_size);
|
||||||
|
int parse_vdo_pool_status(struct dm_pool *mem, const struct logical_volume *vdo_pool_lv,
|
||||||
|
const char *params, const struct dm_info *dminfo,
|
||||||
|
struct lv_status_vdo *status);
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index f3a4a9534..4ccde40b1 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -127,6 +127,20 @@ int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
|
||||||
|
+ uint32_t extent_size)
|
||||||
|
+{
|
||||||
|
+ uint64_t max_extents = (DM_VDO_PHYSICAL_SIZE_MAXIMUM + extent_size - 1) / extent_size;
|
||||||
|
+ uint64_t max_slab_extents = ((extent_size - 1 + DM_VDO_SLABS_MAXIMUM *
|
||||||
|
+ ((uint64_t)vtp->slab_size_mb << (20 - SECTOR_SHIFT))) /
|
||||||
|
+ extent_size);
|
||||||
|
+
|
||||||
|
+ max_extents = (max_slab_extents < max_extents) ? max_slab_extents : max_extents;
|
||||||
|
+
|
||||||
|
+ return (max_extents > UINT32_MAX) ? UINT32_MAX : (uint32_t)max_extents;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static int _sysfs_get_kvdo_value(const char *dm_name, const struct dm_info *dminfo,
|
||||||
|
const char *vdo_param, uint64_t *value)
|
||||||
|
{
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index fb57d84bd..3eee5de90 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -253,6 +253,7 @@ static int _update_extents_params(struct volume_group *vg,
|
||||||
|
uint32_t stripesize_extents;
|
||||||
|
uint32_t extents;
|
||||||
|
uint32_t base_calc_extents;
|
||||||
|
+ uint32_t vdo_pool_max_extents;
|
||||||
|
|
||||||
|
if (lcp->size &&
|
||||||
|
!(lp->extents = extents_from_size(vg->cmd, lcp->size,
|
||||||
|
@@ -322,6 +323,23 @@ static int _update_extents_params(struct volume_group *vg,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (seg_is_vdo(lp)) {
|
||||||
|
+ vdo_pool_max_extents = get_vdo_pool_max_extents(&lp->vdo_params, vg->extent_size);
|
||||||
|
+ if (extents > vdo_pool_max_extents) {
|
||||||
|
+ if (lcp->percent == PERCENT_NONE) {
|
||||||
|
+ log_error("Can't use %s size. Maximal supported VDO POOL volume size with slab size %s is %s.",
|
||||||
|
+ display_size(vg->cmd, (uint64_t)vg->extent_size * extents),
|
||||||
|
+ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)),
|
||||||
|
+ display_size(vg->cmd, (uint64_t)vg->extent_size * vdo_pool_max_extents));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ extents = vdo_pool_max_extents;
|
||||||
|
+ log_verbose("Using maximal supported VDO POOL volume size %s (with slab size %s).",
|
||||||
|
+ display_size(vg->cmd, (uint64_t)vg->extent_size * extents),
|
||||||
|
+ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (lcp->percent != PERCENT_NONE) {
|
||||||
|
/* FIXME Don't do the adjustment for parallel allocation with PERCENT_ORIGIN! */
|
||||||
|
lp->approx_alloc = 1;
|
||||||
|
@@ -699,15 +717,23 @@ static int _read_cache_params(struct cmd_context *cmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _read_vdo_params(struct cmd_context *cmd,
|
||||||
|
- struct lvcreate_params *lp)
|
||||||
|
+ struct lvcreate_params *lp,
|
||||||
|
+ struct lvcreate_cmdline_params *lcp)
|
||||||
|
{
|
||||||
|
if (!seg_is_vdo(lp))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// prefiling settings here
|
||||||
|
- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
|
||||||
|
+ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ if ((lcp->virtual_size <= DM_VDO_LOGICAL_SIZE_MAXIMUM) &&
|
||||||
|
+ ((lcp->virtual_size + lp->vdo_pool_header_size) > DM_VDO_LOGICAL_SIZE_MAXIMUM)) {
|
||||||
|
+ log_verbose("Dropping VDO pool header size to 0 to support maximal size %s.",
|
||||||
|
+ display_size(cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM));
|
||||||
|
+ lp->vdo_pool_header_size = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// override with optional vdo settings
|
||||||
|
if (!get_vdo_settings(cmd, &lp->vdo_params, NULL))
|
||||||
|
return_0;
|
||||||
|
@@ -1203,7 +1229,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
&lp->pool_metadata_size, &lp->pool_metadata_spare,
|
||||||
|
&lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) ||
|
||||||
|
!_read_cache_params(cmd, lp) ||
|
||||||
|
- !_read_vdo_params(cmd, lp) ||
|
||||||
|
+ !_read_vdo_params(cmd, lp, lcp) ||
|
||||||
|
!_read_mirror_and_raid_params(cmd, lp))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
@@ -1589,13 +1615,19 @@ static int _check_pool_parameters(struct cmd_context *cmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _check_vdo_parameters(struct volume_group *vg, struct lvcreate_params *lp,
|
||||||
|
- struct lvcreate_cmdline_params *lcp)
|
||||||
|
+ struct lvcreate_cmdline_params *lcp)
|
||||||
|
{
|
||||||
|
- if (seg_is_vdo(lp) && lp->snapshot) {
|
||||||
|
+ if (lp->snapshot) {
|
||||||
|
log_error("Please either create VDO or snapshot.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (lcp->virtual_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) {
|
||||||
|
+ log_error("Maximal supported VDO virtual size is %s.",
|
||||||
|
+ display_size(vg->cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1716,12 +1748,12 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
|
||||||
|
if (seg_is_thin(lp) && !_check_thin_parameters(vg, lp, lcp))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
- if (!_check_pool_parameters(cmd, vg, lp, lcp))
|
||||||
|
- goto_out;
|
||||||
|
-
|
||||||
|
if (seg_is_vdo(lp) && !_check_vdo_parameters(vg, lp, lcp))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ if (!_check_pool_parameters(cmd, vg, lp, lcp))
|
||||||
|
+ goto_out;
|
||||||
|
+
|
||||||
|
/* All types are checked */
|
||||||
|
if (!_check_zero_parameters(cmd, lp))
|
||||||
|
return_0;
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,58 @@
|
|||||||
|
From f5c194afc5d904e3a936dc167ac14b204c049969 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Sat, 9 Jul 2022 21:33:57 +0200
|
||||||
|
Subject: [PATCH 080/115] vdo: suffle code for better error path handling
|
||||||
|
|
||||||
|
For failing dm_ no need to report 2nd. error,
|
||||||
|
but we missed to report error with 'updated==NULL'.
|
||||||
|
|
||||||
|
(cherry picked from commit 493acb9195cef185b38ae4e4ffb84b984e5cc08c)
|
||||||
|
---
|
||||||
|
tools/toollib.c | 28 ++++++++++++++--------------
|
||||||
|
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index d9a1a92ec..71bf26d39 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -1343,23 +1343,23 @@ int get_vdo_settings(struct cmd_context *cmd,
|
||||||
|
u |= VDO_CHANGE_ONLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (updated) {
|
||||||
|
- // validation of updated VDO option
|
||||||
|
- if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) {
|
||||||
|
-err:
|
||||||
|
- if (is_lvchange)
|
||||||
|
- log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
|
||||||
|
- option);
|
||||||
|
- else
|
||||||
|
- log_error("Invalid argument for VDO setting \"vdo_%s\".",
|
||||||
|
- option);
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
+ // validation of updated VDO option
|
||||||
|
+ if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */))
|
||||||
|
+ goto_out;
|
||||||
|
|
||||||
|
+ if (updated)
|
||||||
|
*updated = u;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- r = 1;
|
||||||
|
+ r = 1; // success
|
||||||
|
+ goto out;
|
||||||
|
+err:
|
||||||
|
+ if (is_lvchange)
|
||||||
|
+ log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
|
||||||
|
+ option);
|
||||||
|
+ else
|
||||||
|
+ log_error("Invalid argument for VDO setting \"vdo_%s\".",
|
||||||
|
+ option);
|
||||||
|
+
|
||||||
|
out:
|
||||||
|
if (result)
|
||||||
|
dm_config_destroy(result);
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From fee817aff4bbd4a8dad7ceae7da179997dc7d359 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Mon, 15 Aug 2022 13:08:59 +0200
|
||||||
|
Subject: [PATCH 081/115] vdo: use only verbose log level for reformating
|
||||||
|
|
||||||
|
When lvcreate is makeing VDO pool and user has not specified -V size,
|
||||||
|
ATM we actually run 'vdoformat' twice to get properly 'extent' aligned
|
||||||
|
size matching lvm2 properties - so the 2nd. run of vdoformat actually
|
||||||
|
can stay with 'log_verbose()' so the standard printed result
|
||||||
|
is not showing confusing info (which is now also correctly using
|
||||||
|
print_unless_silent)
|
||||||
|
|
||||||
|
(cherry picked from commit fc5bc5985d03aef5846cb98882d17815fc00ca15)
|
||||||
|
---
|
||||||
|
lib/metadata/vdo_manip.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index 4ccde40b1..637fd1e5d 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -249,6 +249,7 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||||
|
FILE *f;
|
||||||
|
uint64_t lb;
|
||||||
|
unsigned slabbits;
|
||||||
|
+ unsigned reformating = 0;
|
||||||
|
int args = 1;
|
||||||
|
char buf_args[5][128];
|
||||||
|
char buf[256]; /* buffer for short disk header (64B) */
|
||||||
|
@@ -351,8 +352,12 @@ reformat:
|
||||||
|
}
|
||||||
|
if ((c = strchr(buf, '\n')))
|
||||||
|
*c = 0; /* cut last '\n' away */
|
||||||
|
- if (buf[0])
|
||||||
|
- log_print(" %s", buf); /* Print vdo_format messages */
|
||||||
|
+ if (buf[0]) {
|
||||||
|
+ if (reformating)
|
||||||
|
+ log_verbose(" %s", buf); /* Print vdo_format messages */
|
||||||
|
+ else
|
||||||
|
+ log_print_unless_silent(" %s", buf); /* Print vdo_format messages */
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pipe_close(&pdata)) {
|
||||||
|
@@ -372,6 +377,7 @@ reformat:
|
||||||
|
*logical_size = logical_size_aligned;
|
||||||
|
argv[1] = (char*) "--force";
|
||||||
|
args = 2;
|
||||||
|
+ reformating = 1;
|
||||||
|
log_verbose("Reformating VDO to align virtual size %s by extent size.",
|
||||||
|
display_size(data_lv->vg->cmd, *logical_size));
|
||||||
|
goto reformat;
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
27
SOURCES/0082-vdo-reset-errno-before-strtoull.patch
Normal file
27
SOURCES/0082-vdo-reset-errno-before-strtoull.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From a4f39c5bbff286cc1323f799d269e35bf8e615b6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Thu, 18 Aug 2022 13:55:29 +0200
|
||||||
|
Subject: [PATCH 082/115] vdo: reset errno before strtoull
|
||||||
|
|
||||||
|
Missed errno reset in commit ebad057579aeff0980a1b8af7eaacd56e62ed0c9.
|
||||||
|
|
||||||
|
(cherry picked from commit 309df239e3ee474f3a5337f8fa3c0a1f7b0a89e5)
|
||||||
|
---
|
||||||
|
lib/metadata/vdo_manip.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index 637fd1e5d..0db401537 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -618,6 +618,7 @@ static int _get_memory_info(uint64_t *total_mb, uint64_t *available_mb)
|
||||||
|
if (!found)
|
||||||
|
continue; // not interesting
|
||||||
|
|
||||||
|
+ errno = 0;
|
||||||
|
*(found->value) = (uint64_t) strtoull(e, &tail, 10);
|
||||||
|
|
||||||
|
if ((e == tail) || errno)
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
66
SOURCES/0083-vdo-extend-volume-and-pool-without-flush.patch
Normal file
66
SOURCES/0083-vdo-extend-volume-and-pool-without-flush.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From c3d533a0ea20aa26868c55959365a52f3eaf34d1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Fri, 19 Aug 2022 14:48:01 +0200
|
||||||
|
Subject: [PATCH 083/115] vdo: extend volume and pool without flush
|
||||||
|
|
||||||
|
When the volume size is extended, there is no need to flush
|
||||||
|
IO operations (nothing can be targeting new space yet).
|
||||||
|
VDO target is supported as target that can safely work with
|
||||||
|
this condition.
|
||||||
|
|
||||||
|
Such support is also needed, when extending VDOPOOL size
|
||||||
|
while the pool is reaching its capacity - since this allows
|
||||||
|
to continue working without reaching 'out-of-space' condition
|
||||||
|
due to flushing of all in flight IO.
|
||||||
|
|
||||||
|
(cherry picked from commit e26c21cb8d5841141dcfdfc77f46da1108a81255)
|
||||||
|
---
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
lib/activate/activate.c | 6 +++++-
|
||||||
|
lib/activate/dev_manager.c | 2 ++
|
||||||
|
3 files changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 705fbde74..48b1d7d86 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.03.17 -
|
||||||
|
===============================
|
||||||
|
+ Extend VDO and VDOPOOL without flushing and locking fs.
|
||||||
|
Fix lvconvert --test --type vdo-pool execution.
|
||||||
|
Fix vdo_slab_size_mb value for converted VDO volume.
|
||||||
|
|
||||||
|
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
|
||||||
|
index 727bd2386..76740bb2b 100644
|
||||||
|
--- a/lib/activate/activate.c
|
||||||
|
+++ b/lib/activate/activate.c
|
||||||
|
@@ -2124,7 +2124,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||||
|
* TODO: Relax this limiting condition further */
|
||||||
|
if (!flush_required &&
|
||||||
|
(lv_is_pvmove(lv) || pvmove_lv ||
|
||||||
|
- (!lv_is_mirror(lv) && !lv_is_thin_pool(lv) && !lv_is_thin_volume(lv)))) {
|
||||||
|
+ (!lv_is_mirror(lv) &&
|
||||||
|
+ !lv_is_thin_volume(lv) &&
|
||||||
|
+ !lv_is_thin_pool(lv) &&
|
||||||
|
+ !lv_is_vdo(lv) &&
|
||||||
|
+ !lv_is_vdo_pool(lv)))) {
|
||||||
|
log_debug("Requiring flush for LV %s.", display_lvname(lv));
|
||||||
|
flush_required = 1;
|
||||||
|
}
|
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
||||||
|
index 284254d68..9058510e4 100644
|
||||||
|
--- a/lib/activate/dev_manager.c
|
||||||
|
+++ b/lib/activate/dev_manager.c
|
||||||
|
@@ -3826,6 +3826,8 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||||
|
* non 'thin pool/volume' and size increase */
|
||||||
|
else if (!lv_is_thin_volume(lv) &&
|
||||||
|
!lv_is_thin_pool(lv) &&
|
||||||
|
+ !lv_is_vdo(lv) &&
|
||||||
|
+ !lv_is_vdo_pool(lv) &&
|
||||||
|
dm_tree_node_size_changed(root))
|
||||||
|
dm->flush_required = 1;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
52
SOURCES/0084-tests-vdo-emulation-without-vdo-binary.patch
Normal file
52
SOURCES/0084-tests-vdo-emulation-without-vdo-binary.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From fc1c105c75b81b4cecf24e7924605abcceb91d67 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Tue, 6 Sep 2022 16:44:24 +0200
|
||||||
|
Subject: [PATCH 084/115] tests: vdo emulation without vdo binary
|
||||||
|
|
||||||
|
Avoid inserting 'vdo' binary into path - and use
|
||||||
|
alias and VDO_BINARY shell vars for emulation.
|
||||||
|
|
||||||
|
(cherry picked from commit 15ad2b8e5585b89bc3f09a53567f17eb70f45714)
|
||||||
|
---
|
||||||
|
test/lib/lvm_vdo_wrapper.sh | 2 +-
|
||||||
|
test/shell/vdo-convert.sh | 11 ++++++++++-
|
||||||
|
2 files changed, 11 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/lib/lvm_vdo_wrapper.sh b/test/lib/lvm_vdo_wrapper.sh
|
||||||
|
index d622d6456..90d0b2ce8 100755
|
||||||
|
--- a/test/lib/lvm_vdo_wrapper.sh
|
||||||
|
+++ b/test/lib/lvm_vdo_wrapper.sh
|
||||||
|
@@ -344,7 +344,7 @@ vdo_dry_ vdo_remove_ -f "$vdo_confFile" -n "$vdo_name" || true
|
||||||
|
#
|
||||||
|
# MAIN
|
||||||
|
#
|
||||||
|
-case "$1" in
|
||||||
|
+case "${1-}" in
|
||||||
|
"create") shift; vdo_create_ "$@" ;;
|
||||||
|
"remove") shift; vdo_remove_ "$@" ;;
|
||||||
|
"stop") shift; vdo_stop_ "$@" ;;
|
||||||
|
diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh
|
||||||
|
index f1d04d596..5bf53d081 100644
|
||||||
|
--- a/test/shell/vdo-convert.sh
|
||||||
|
+++ b/test/shell/vdo-convert.sh
|
||||||
|
@@ -29,7 +29,16 @@ aux prepare_dmeventd
|
||||||
|
#
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
-which vdo || skip
|
||||||
|
+if not which vdo ; then
|
||||||
|
+ which lvm_vdo_wrapper || skip "Missing 'lvm_vdo_wrapper'."
|
||||||
|
+ which oldvdoformat || skip "Emulation of vdo manager 'oldvdoformat' missing."
|
||||||
|
+ which oldvdoprepareforlvm || skip "Emulation of vdo manager 'oldvdoprepareforlvm' missing."
|
||||||
|
+ # enable expansion of aliasis within script itself
|
||||||
|
+ shopt -s expand_aliases
|
||||||
|
+ alias vdo='lvm_vdo_wrapper'
|
||||||
|
+ export VDO_BINARY=lvm_vdo_wrapper
|
||||||
|
+ echo "Using 'lvm_vdo_wrapper' emulation of 'vdo' manager."
|
||||||
|
+fi
|
||||||
|
which mkfs.ext4 || skip
|
||||||
|
export MKE2FS_CONFIG="$TESTDIR/lib/mke2fs.conf"
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
373
SOURCES/0085-device_mapper-add-parser-for-vdo-metadata.patch
Normal file
373
SOURCES/0085-device_mapper-add-parser-for-vdo-metadata.patch
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
From fd16a667a985ef116f3deed1910b99aa0859f244 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Wed, 26 Oct 2022 14:33:09 +0200
|
||||||
|
Subject: [PATCH 085/115] device_mapper: add parser for vdo metadata
|
||||||
|
|
||||||
|
Add very simplistic parser of vdo metadata to be able to obtain
|
||||||
|
logical_blocks stored within vdo metadata - as lvm2 may
|
||||||
|
submit smaller value due to internal aligment rules.
|
||||||
|
|
||||||
|
To avoid creation of mismatching table line - use this number
|
||||||
|
instead the one provided by lvm2.
|
||||||
|
|
||||||
|
(cherry picked from commit 829ab017082eaad253ebd28ad7d7ae7f3936dbcb)
|
||||||
|
---
|
||||||
|
device_mapper/Makefile | 3 +-
|
||||||
|
device_mapper/libdm-deptree.c | 15 ++
|
||||||
|
device_mapper/vdo/target.h | 2 +
|
||||||
|
device_mapper/vdo/vdo_reader.c | 279 +++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 298 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 device_mapper/vdo/vdo_reader.c
|
||||||
|
|
||||||
|
diff --git a/device_mapper/Makefile b/device_mapper/Makefile
|
||||||
|
index d3b791eb5..a322235cb 100644
|
||||||
|
--- a/device_mapper/Makefile
|
||||||
|
+++ b/device_mapper/Makefile
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-# Copyright (C) 2018 Red Hat, Inc. All rights reserved.
|
||||||
|
+# Copyright (C) 2018 - 2022 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the device-mapper userspace tools.
|
||||||
|
#
|
||||||
|
@@ -29,6 +29,7 @@ DEVICE_MAPPER_SOURCE=\
|
||||||
|
device_mapper/regex/parse_rx.c \
|
||||||
|
device_mapper/regex/ttree.c \
|
||||||
|
device_mapper/vdo/status.c \
|
||||||
|
+ device_mapper/vdo/vdo_reader.c \
|
||||||
|
device_mapper/vdo/vdo_target.c
|
||||||
|
|
||||||
|
DEVICE_MAPPER_TARGET = device_mapper/libdevice-mapper.a
|
||||||
|
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
|
||||||
|
index 2d382037c..0445e1b4b 100644
|
||||||
|
--- a/device_mapper/libdm-deptree.c
|
||||||
|
+++ b/device_mapper/libdm-deptree.c
|
||||||
|
@@ -2857,6 +2857,7 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
|
||||||
|
int pos = 0;
|
||||||
|
char data[DM_FORMAT_DEV_BUFSIZE];
|
||||||
|
char data_dev[128]; // for /dev/dm-XXXX
|
||||||
|
+ uint64_t logical_blocks;
|
||||||
|
|
||||||
|
if (!_build_dev_string(data, sizeof(data), seg->vdo_data))
|
||||||
|
return_0;
|
||||||
|
@@ -2866,6 +2867,20 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (dm_vdo_parse_logical_size(data_dev, &logical_blocks)) {
|
||||||
|
+ logical_blocks *= 8;
|
||||||
|
+ if (seg->size != logical_blocks) {
|
||||||
|
+ if (seg->size > logical_blocks) {
|
||||||
|
+ log_error("Virtual size of VDO volume is smaller then expected (" FMTu64 " > " FMTu64 ").",
|
||||||
|
+ seg->size, logical_blocks);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ log_debug_activation("Increasing VDO virtual volume size from " FMTu64 " to " FMTu64 ".",
|
||||||
|
+ seg->size, logical_blocks);
|
||||||
|
+ seg->size = logical_blocks;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (seg->vdo_version < 4) {
|
||||||
|
EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s ",
|
||||||
|
data_dev,
|
||||||
|
diff --git a/device_mapper/vdo/target.h b/device_mapper/vdo/target.h
|
||||||
|
index 60c5bff56..bd21bb5d7 100644
|
||||||
|
--- a/device_mapper/vdo/target.h
|
||||||
|
+++ b/device_mapper/vdo/target.h
|
||||||
|
@@ -108,6 +108,8 @@ struct dm_vdo_target_params {
|
||||||
|
bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||||
|
uint64_t vdo_size);
|
||||||
|
|
||||||
|
+bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks);
|
||||||
|
+
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..b765af042
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/device_mapper/vdo/vdo_reader.c
|
||||||
|
@@ -0,0 +1,279 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2022 Red Hat, Inc. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * This file is part of the device-mapper userspace tools.
|
||||||
|
+ *
|
||||||
|
+ * This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+ * modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+ * of the GNU Lesser General Public License v.2.1.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU Lesser General Public License
|
||||||
|
+ * along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Based on VDO sources: https://github.com/dm-vdo/vdo
|
||||||
|
+ *
|
||||||
|
+ * Simplified parser of VDO superblock to obtain basic VDO parameteers
|
||||||
|
+ *
|
||||||
|
+ * TODO: maybe switch to some library in the future
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+//#define _GNU_SOURCE 1
|
||||||
|
+//#define _LARGEFILE64_SOURCE 1
|
||||||
|
+
|
||||||
|
+#include "device_mapper/misc/dmlib.h"
|
||||||
|
+
|
||||||
|
+#include "target.h"
|
||||||
|
+
|
||||||
|
+#include "lib/mm/xlate.h"
|
||||||
|
+//#include "linux/byteorder/big_endian.h"
|
||||||
|
+//#include "linux/byteorder/little_endian.h"
|
||||||
|
+//#define le32_to_cpu __le32_to_cpu
|
||||||
|
+//#define le64_to_cpu __le64_to_cpu
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <linux/fs.h> /* For block ioctl definitions */
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/ioctl.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+typedef unsigned char uuid_t[16];
|
||||||
|
+
|
||||||
|
+#define __packed __attribute__((packed))
|
||||||
|
+
|
||||||
|
+static const char _MAGIC_NUMBER[] = "dmvdo001";
|
||||||
|
+#define MAGIC_NUMBER_SIZE (sizeof(_MAGIC_NUMBER) - 1)
|
||||||
|
+
|
||||||
|
+struct vdo_version_number {
|
||||||
|
+ uint32_t major_version;
|
||||||
|
+ uint32_t minor_version;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * The registry of component ids for use in headers
|
||||||
|
+ */
|
||||||
|
+enum {
|
||||||
|
+ SUPER_BLOCK = 0,
|
||||||
|
+ FIXED_LAYOUT = 1,
|
||||||
|
+ RECOVERY_JOURNAL = 2,
|
||||||
|
+ SLAB_DEPOT = 3,
|
||||||
|
+ BLOCK_MAP = 4,
|
||||||
|
+ GEOMETRY_BLOCK = 5,
|
||||||
|
+}; /* ComponentID */
|
||||||
|
+
|
||||||
|
+struct vdo_header {
|
||||||
|
+ uint32_t id; /* The component this is a header for */
|
||||||
|
+ struct vdo_version_number version; /* The version of the data format */
|
||||||
|
+ size_t size; /* The size of the data following this header */
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+struct vdo_geometry_block {
|
||||||
|
+ char magic_number[MAGIC_NUMBER_SIZE];
|
||||||
|
+ struct vdo_header header;
|
||||||
|
+ uint32_t checksum;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+struct vdo_config {
|
||||||
|
+ uint64_t logical_blocks; /* number of logical blocks */
|
||||||
|
+ uint64_t physical_blocks; /* number of physical blocks */
|
||||||
|
+ uint64_t slab_size; /* number of blocks in a slab */
|
||||||
|
+ uint64_t recovery_journal_size; /* number of recovery journal blocks */
|
||||||
|
+ uint64_t slab_journal_blocks; /* number of slab journal blocks */
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+struct vdo_component_41_0 {
|
||||||
|
+ uint32_t state;
|
||||||
|
+ uint64_t complete_recoveries;
|
||||||
|
+ uint64_t read_only_recoveries;
|
||||||
|
+ struct vdo_config config; /* packed */
|
||||||
|
+ uint64_t nonce;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+enum vdo_volume_region_id {
|
||||||
|
+ VDO_INDEX_REGION = 0,
|
||||||
|
+ VDO_DATA_REGION = 1,
|
||||||
|
+ VDO_VOLUME_REGION_COUNT,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct vdo_volume_region {
|
||||||
|
+ /* The ID of the region */
|
||||||
|
+ enum vdo_volume_region_id id;
|
||||||
|
+ /*
|
||||||
|
+ * The absolute starting offset on the device. The region continues
|
||||||
|
+ * until the next region begins.
|
||||||
|
+ */
|
||||||
|
+ uint64_t start_block;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+struct vdo_index_config {
|
||||||
|
+ uint32_t mem;
|
||||||
|
+ uint32_t unused;
|
||||||
|
+ uint8_t sparse;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+struct vdo_volume_geometry {
|
||||||
|
+ uint32_t release_version;
|
||||||
|
+ uint64_t nonce;
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+ uint64_t bio_offset;
|
||||||
|
+ struct vdo_volume_region regions[VDO_VOLUME_REGION_COUNT];
|
||||||
|
+ struct vdo_index_config index_config;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/* Decoding mostly only some used stucture members */
|
||||||
|
+
|
||||||
|
+static void _vdo_decode_version(struct vdo_version_number *v)
|
||||||
|
+{
|
||||||
|
+ v->major_version = le32_to_cpu(v->major_version);
|
||||||
|
+ v->minor_version = le32_to_cpu(v->minor_version);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _vdo_decode_header(struct vdo_header *h)
|
||||||
|
+{
|
||||||
|
+ h->id = le32_to_cpu(h->id);
|
||||||
|
+ _vdo_decode_version(&h->version);
|
||||||
|
+ h->size = le64_to_cpu(h->size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _vdo_decode_geometry_region(struct vdo_volume_region *vr)
|
||||||
|
+{
|
||||||
|
+ vr->id = le32_to_cpu(vr->id);
|
||||||
|
+ vr->start_block = le32_to_cpu(vr->start_block);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg)
|
||||||
|
+{
|
||||||
|
+ vg->release_version = le64_to_cpu(vg->release_version);
|
||||||
|
+ vg->nonce = le64_to_cpu(vg->nonce);
|
||||||
|
+ _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _vdo_decode_config(struct vdo_config *vc)
|
||||||
|
+{
|
||||||
|
+ vc->logical_blocks = le64_to_cpu(vc->logical_blocks);
|
||||||
|
+ vc->physical_blocks = le64_to_cpu(vc->physical_blocks);
|
||||||
|
+ vc->slab_size = le64_to_cpu(vc->slab_size);
|
||||||
|
+ vc->recovery_journal_size = le64_to_cpu(vc->recovery_journal_size);
|
||||||
|
+ vc->slab_journal_blocks = le64_to_cpu(vc->slab_journal_blocks);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _vdo_decode_pvc(struct vdo_component_41_0 *pvc)
|
||||||
|
+{
|
||||||
|
+ _vdo_decode_config(&pvc->config);
|
||||||
|
+ pvc->nonce = le64_to_cpu(pvc->nonce);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks)
|
||||||
|
+{
|
||||||
|
+ char buffer[4096];
|
||||||
|
+ int fh, n;
|
||||||
|
+ bool r = false;
|
||||||
|
+ off_t l;
|
||||||
|
+ struct stat st;
|
||||||
|
+ uint64_t size;
|
||||||
|
+ uint64_t regpos;
|
||||||
|
+
|
||||||
|
+ struct vdo_header h;
|
||||||
|
+ struct vdo_version_number vn;
|
||||||
|
+ struct vdo_volume_geometry vg;
|
||||||
|
+ struct vdo_component_41_0 pvc;
|
||||||
|
+
|
||||||
|
+ *logical_blocks = 0;
|
||||||
|
+ if ((fh = open(vdo_path, O_RDONLY)) == -1) {
|
||||||
|
+ log_sys_error("Failed to open VDO backend %s", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ioctl(fh, BLKGETSIZE64, &size) == -1) {
|
||||||
|
+ if (errno != ENOTTY) {
|
||||||
|
+ log_sys_error("ioctl", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* lets retry for file sizes */
|
||||||
|
+ if (fstat(fh, &st) < 0) {
|
||||||
|
+ log_sys_error("fstat", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ size = st.st_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((n = read(fh, buffer, sizeof(buffer))) < 0) {
|
||||||
|
+ log_sys_error("read", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strncmp(buffer, _MAGIC_NUMBER, MAGIC_NUMBER_SIZE)) {
|
||||||
|
+ log_sys_error("mismatch header", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memcpy(&h, buffer + MAGIC_NUMBER_SIZE, sizeof(h));
|
||||||
|
+ _vdo_decode_header(&h);
|
||||||
|
+
|
||||||
|
+ if (h.version.major_version != 5) {
|
||||||
|
+ log_error("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg));
|
||||||
|
+ _vdo_decode_volume_geometry(&vg);
|
||||||
|
+
|
||||||
|
+ regpos = vg.regions[VDO_DATA_REGION].start_block * 4096;
|
||||||
|
+
|
||||||
|
+ if ((regpos + sizeof(buffer)) > size) {
|
||||||
|
+ log_error("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((l = lseek(fh, regpos, SEEK_SET)) < 0) {
|
||||||
|
+ log_sys_error("lseek", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((n = read(fh, buffer, sizeof(buffer))) < 0) {
|
||||||
|
+ log_sys_error("read error", vdo_path);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ memcpy(&vn, buffer + sizeof(struct vdo_geometry_block), sizeof(vn));
|
||||||
|
+ _vdo_decode_version(&vn);
|
||||||
|
+
|
||||||
|
+ if (vn.major_version > 41) {
|
||||||
|
+ log_error("Unknown VDO component version %u.", vn.major_version); // should be 41!
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memcpy(&pvc, buffer + sizeof(struct vdo_geometry_block) + sizeof(vn), sizeof(pvc));
|
||||||
|
+ _vdo_decode_pvc(&pvc);
|
||||||
|
+
|
||||||
|
+ if (pvc.nonce != vg.nonce) {
|
||||||
|
+ log_error("Mismatching VDO nonce " FMTu64 " != " FMTu64 ".", pvc.nonce, vg.nonce);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+ log_debug("LogBlocks " FMTu64 ".", pvc.config.logical_blocks);
|
||||||
|
+ log_debug("PhyBlocks " FMTu64 ".", pvc.config.physical_blocks);
|
||||||
|
+ log_debug("SlabSize " FMTu64 ".", pvc.config.slab_size);
|
||||||
|
+ log_debug("RecJourSize " FMTu64 ".", pvc.config.recovery_journal_size);
|
||||||
|
+ log_debug("SlabJouSize " FMTu64 ".", pvc.config.slab_journal_blocks);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ *logical_blocks = pvc.config.logical_blocks;
|
||||||
|
+ r = true;
|
||||||
|
+err:
|
||||||
|
+ (void) close(fh);
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
78
SOURCES/0086-dev_manager-accept-misalined-vdo-pools.patch
Normal file
78
SOURCES/0086-dev_manager-accept-misalined-vdo-pools.patch
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
From 13ce88a2b204e9b05206b624bbcca00446312ebb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Wed, 26 Oct 2022 14:38:29 +0200
|
||||||
|
Subject: [PATCH 086/115] dev_manager: accept misalined vdo pools.
|
||||||
|
|
||||||
|
Since lvm2 may create VDO pool virtual size aligned only on extent size
|
||||||
|
while VDO itself is just 4K aligned - we need to support such misalign.
|
||||||
|
|
||||||
|
(cherry picked from commit 2e79b005c2013fb03d8a48a3cfd8e70a982dd65b)
|
||||||
|
---
|
||||||
|
lib/activate/dev_manager.c | 8 +++++---
|
||||||
|
lib/metadata/vdo_manip.c | 10 ++--------
|
||||||
|
2 files changed, 7 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
||||||
|
index 9058510e4..5b72bf772 100644
|
||||||
|
--- a/lib/activate/dev_manager.c
|
||||||
|
+++ b/lib/activate/dev_manager.c
|
||||||
|
@@ -263,7 +263,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||||
|
int dmtask;
|
||||||
|
int with_flush; /* TODO: arg for _info_run */
|
||||||
|
void *target = NULL;
|
||||||
|
- uint64_t target_start, target_length, start, length, length_crop = 0;
|
||||||
|
+ uint64_t target_start, target_length, start, extent_size, length, length_crop = 0;
|
||||||
|
char *target_name, *target_params;
|
||||||
|
const char *devname;
|
||||||
|
|
||||||
|
@@ -292,8 +292,8 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||||
|
|
||||||
|
/* Query status only for active device */
|
||||||
|
if (seg_status && dminfo->exists) {
|
||||||
|
- start = length = seg_status->seg->lv->vg->extent_size;
|
||||||
|
- start *= seg_status->seg->le;
|
||||||
|
+ extent_size = length = seg_status->seg->lv->vg->extent_size;
|
||||||
|
+ start = extent_size * seg_status->seg->le;
|
||||||
|
length *= _seg_len(seg_status->seg);
|
||||||
|
|
||||||
|
/* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */
|
||||||
|
@@ -314,6 +314,8 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||||
|
|
||||||
|
if ((start == target_start) &&
|
||||||
|
((length == target_length) ||
|
||||||
|
+ ((lv_is_vdo_pool(seg_status->seg->lv)) && /* should fit within extent size */
|
||||||
|
+ (length < target_length) && ((length + extent_size) > target_length)) ||
|
||||||
|
(length_crop && (length_crop == target_length))))
|
||||||
|
break; /* Keep target_params when matching segment is found */
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||||
|
index 0db401537..1cd2130a7 100644
|
||||||
|
--- a/lib/metadata/vdo_manip.c
|
||||||
|
+++ b/lib/metadata/vdo_manip.c
|
||||||
|
@@ -263,7 +263,6 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-reformat:
|
||||||
|
if (*logical_size) {
|
||||||
|
logical_size_aligned = 0;
|
||||||
|
if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K",
|
||||||
|
@@ -374,13 +373,8 @@ reformat:
|
||||||
|
// align obtained size to extent size
|
||||||
|
logical_size_aligned = *logical_size / data_lv->vg->extent_size * data_lv->vg->extent_size;
|
||||||
|
if (*logical_size != logical_size_aligned) {
|
||||||
|
- *logical_size = logical_size_aligned;
|
||||||
|
- argv[1] = (char*) "--force";
|
||||||
|
- args = 2;
|
||||||
|
- reformating = 1;
|
||||||
|
- log_verbose("Reformating VDO to align virtual size %s by extent size.",
|
||||||
|
- display_size(data_lv->vg->cmd, *logical_size));
|
||||||
|
- goto reformat;
|
||||||
|
+ log_debug("Using bigger VDO virtual size unaligned on extent size by %s.",
|
||||||
|
+ display_size(data_lv->vg->cmd, *logical_size - logical_size_aligned));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user