master - tests: fix mkdir pvs_online
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=edf3f86184a380994e3...
Commit: edf3f86184a380994e383b9884364e702e4ac647
Parent: 06439a256217b5d37ef33833051fc322a58b4859
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jul 10 14:19:46 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Jul 10 14:19:46 2018 -0500
tests: fix mkdir pvs_online
---
test/shell/pvscan-autoactivate.sh | 2 ++
test/shell/pvscan-nomda-bg.sh | 2 +-
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/test/shell/pvscan-autoactivate.sh b/test/shell/pvscan-autoactivate.sh
index af6f2b2..85a08cf 100644
--- a/test/shell/pvscan-autoactivate.sh
+++ b/test/shell/pvscan-autoactivate.sh
@@ -19,6 +19,8 @@ aux prepare_pvs 2
vgcreate $vg1 "$dev1" "$dev2"
lvcreate -n $lv1 -l 4 -a n $vg1
+mkdir /run/lvm/pvs_online || true
+
# the first pvscan scans all devs
rm /run/lvm/pvs_online/*
diff --git a/test/shell/pvscan-nomda-bg.sh b/test/shell/pvscan-nomda-bg.sh
index f8ecc08..d73f3da 100644
--- a/test/shell/pvscan-nomda-bg.sh
+++ b/test/shell/pvscan-nomda-bg.sh
@@ -26,7 +26,7 @@ check inactive $vg1 foo
# create a file in pvs_online to disable the pvscan init
# case which scans everything when the first dev appears.
-mkdir /run/lvm/pvs_online/
+mkdir /run/lvm/pvs_online || true
touch /run/lvm/pvs_online/foo
pvscan --cache --background "$dev2" -aay
5 years, 9 months
master - tests: autoactivation tests for use without lvmetad
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=06439a256217b5d37ef...
Commit: 06439a256217b5d37ef33833051fc322a58b4859
Parent: db741e75a21bd9327ed1478e42495f2b0a419be9
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jul 10 09:58:22 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Jul 10 10:49:34 2018 -0500
tests: autoactivation tests for use without lvmetad
Adjust a few lvmetad pvscan/autoactivation tests to be
used without lvmetad, and add a test to cover some cases
that have not been tested before.
---
.../shell/lvmetad-pvscan-autoactivation-polling.sh | 75 ----------
test/shell/lvmetad-pvscan-cache.sh | 63 ---------
test/shell/lvmetad-pvscan-nomda-bg.sh | 59 --------
test/shell/pvscan-autoactivate.sh | 143 ++++++++++++++++++++
test/shell/pvscan-autoactivation-polling.sh | 74 ++++++++++
test/shell/pvscan-cache.sh | 62 +++++++++
test/shell/pvscan-nomda-bg.sh | 41 ++++++
7 files changed, 320 insertions(+), 197 deletions(-)
diff --git a/test/shell/lvmetad-pvscan-autoactivation-polling.sh b/test/shell/lvmetad-pvscan-autoactivation-polling.sh
deleted file mode 100644
index 46c454b..0000000
--- a/test/shell/lvmetad-pvscan-autoactivation-polling.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (C) 2016 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
-
-SKIP_WITH_LVMLOCKD=1
-SKIP_WITHOUT_LVMETAD=1
-
-. lib/inittest
-
-# test if snapshot-merge target is available
-aux target_at_least dm-snapshot-merge 1 0 0 || skip
-
-which mkfs.ext3 || skip
-
-lvdev_() {
- echo "$DM_DEV_DIR/$1/$2"
-}
-
-snap_lv_name_() {
- echo ${1}_snap
-}
-
-setup_merge_() {
- local VG_NAME=$1
- local LV_NAME=$2
- local NUM_EXTRA_SNAPS=${3:-0}
- local BASE_SNAP_LV_NAME
-
- BASE_SNAP_LV_NAME=$(snap_lv_name_ $LV_NAME)
-
- lvcreate -aey -n $LV_NAME -l 50%FREE $VG_NAME
- lvs
- lvcreate -s -n $BASE_SNAP_LV_NAME -l 20%FREE ${VG_NAME}/${LV_NAME}
- mkfs.ext3 "$(lvdev_ $VG_NAME $LV_NAME)"
-
- if [ $NUM_EXTRA_SNAPS -gt 0 ]; then
- for i in $(seq 1 $NUM_EXTRA_SNAPS); do
- lvcreate -s -n ${BASE_SNAP_LV_NAME}_${i} -l 20%ORIGIN ${VG_NAME}/${LV_NAME}
- done
- fi
-}
-
-aux prepare_pvs 1 50
-
-vgcreate $vg1 "$dev1"
-mkdir test_mnt
-
-setup_merge_ $vg1 $lv1
-mount "$(lvdev_ $vg1 $lv1)" test_mnt
-lvconvert --merge "$vg1/$(snap_lv_name_ "$lv1")"
-umount test_mnt
-vgchange -an $vg1
-
-# check snapshot get removed on autoactivation
-pvscan --cache -aay "$dev1"
-
-check active $vg1 $lv1
-i=100
-while ! check lv_not_exists "$vg1/$(snap_lv_name_ "$lv1")"; do
- test $i -lt 0 && fail "Background polling failed to remove merged snapshot LV"
- sleep .1
- i=$((i-1))
-done
-
-# TODO: add similar simple tests for other interrupted/unfinished polling operation
-
-vgremove -ff $vg1
diff --git a/test/shell/lvmetad-pvscan-cache.sh b/test/shell/lvmetad-pvscan-cache.sh
deleted file mode 100644
index 367220e..0000000
--- a/test/shell/lvmetad-pvscan-cache.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (C) 2012 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
-
-SKIP_WITH_LVMLOCKD=1
-SKIP_WITHOUT_LVMETAD=1
-SKIP_WITH_LVMPOLLD=1
-
-. lib/inittest
-
-aux prepare_pvs 2
-
-vgcreate $vg1 "$dev1" "$dev2"
-vgs | grep $vg1
-
-pvscan --cache
-
-vgs | grep $vg1
-
-# Check that an LV cannot be activated by lvchange while VG is exported
-lvcreate -n $lv1 -l 4 -a n $vg1
-check lv_exists $vg1
-vgexport $vg1
-fail lvs $vg1
-fail lvchange -ay $vg1/$lv1
-vgimport $vg1
-check lv_exists $vg1
-check lv_field $vg1/$lv1 lv_active ""
-
-# Check that an LV cannot be activated by pvscan while VG is exported
-vgexport $vg1
-not pvscan --cache -aay "$dev1"
-not pvscan --cache -aay "$dev2"
-vgimport $vg1
-check lv_exists $vg1
-check lv_field $vg1/$lv1 lv_active ""
-pvscan --cache -aay "$dev1"
-pvscan --cache -aay "$dev2"
-check lv_field $vg1/$lv1 lv_active "active"
-lvchange -an $vg1/$lv1
-
-# When MDA is ignored on PV, do not read any VG
-# metadata from such PV as it may contain old
-# metadata which hasn't been updated for some
-# time and also since the MDA is marked as ignored,
-# it should really be *ignored*!
-pvchange --metadataignore y "$dev1"
-aux disable_dev "$dev2"
-pvscan --cache
-check pv_field "$dev1" vg_name "[unknown]"
-aux enable_dev "$dev2"
-pvscan --cache
-check pv_field "$dev1" vg_name "$vg1"
-
-vgremove -ff $vg1
diff --git a/test/shell/lvmetad-pvscan-nomda-bg.sh b/test/shell/lvmetad-pvscan-nomda-bg.sh
deleted file mode 100644
index 351e446..0000000
--- a/test/shell/lvmetad-pvscan-nomda-bg.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (C) 2015 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
-
-SKIP_WITH_LVMLOCKD=1
-SKIP_WITHOUT_LVMETAD=1
-SKIP_WITH_LVMPOLLD=1
-
-. lib/inittest
-
-kill "$(< LOCAL_LVMETAD)"
-rm LOCAL_LVMETAD
-
-aux prepare_devs 2
-
-pvcreate --metadatacopies 0 "$dev1"
-pvcreate --metadatacopies 1 "$dev2"
-vgcreate $vg1 "$dev1" "$dev2"
-lvcreate -n foo -l 1 -an --zero n $vg1
-
-# start lvmetad but make sure it doesn't know about $dev1 or $dev2
-aux disable_dev "$dev1" "$dev2"
-aux prepare_lvmetad
-lvs
-mv LOCAL_LVMETAD XXX
-aux enable_dev "$dev2" "$dev1"
-mv XXX LOCAL_LVMETAD
-
-aux lvmconf 'global/use_lvmetad = 0'
-check inactive $vg1 foo
-aux lvmconf 'global/use_lvmetad = 1'
-
-pvscan --cache --background "$dev2" -aay
-
-aux lvmconf 'global/use_lvmetad = 0'
-# FIXME: inconclusive. may be a timing issue
-check inactive $vg1 foo
-aux lvmconf 'global/use_lvmetad = 1'
-
-pvscan --cache --background "$dev1" -aay
-
-aux lvmconf 'global/use_lvmetad = 0'
-i=100
-while ! check active $vg1 foo; do
- test $i -lt 0 && fail "Failed to autoactivate"
- sleep .1
- i=$((i-1))
-done
-aux lvmconf 'global/use_lvmetad = 1'
-
-vgremove -ff $vg1
diff --git a/test/shell/pvscan-autoactivate.sh b/test/shell/pvscan-autoactivate.sh
new file mode 100644
index 0000000..af6f2b2
--- /dev/null
+++ b/test/shell/pvscan-autoactivate.sh
@@ -0,0 +1,143 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2012 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
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux prepare_pvs 2
+
+vgcreate $vg1 "$dev1" "$dev2"
+lvcreate -n $lv1 -l 4 -a n $vg1
+
+# the first pvscan scans all devs
+
+rm /run/lvm/pvs_online/*
+
+pvscan --cache -aay
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# the first pvscan scans all devs even when
+# only one device is specified
+
+rm /run/lvm/pvs_online/*
+
+pvscan --cache -aay "$dev1"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# touch foo to disable first-pvscan case,
+# then check pvscan with no args scans all
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache -aay
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# touch foo to disable first-pvscan case,
+# then check that vg is activated only after
+# both devs appear separately
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache -aay "$dev1"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache -aay "$dev2"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# touch foo to disable first-pvscan case,
+# then check that vg is activated when both
+# devs appear together
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache -aay "$dev1" "$dev2"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# Set up tests where one dev has no metadata
+
+vgchange -an $vg1
+vgremove -ff $vg1
+pvremove "$dev1"
+pvremove "$dev2"
+pvcreate --metadatacopies 0 "$dev1"
+pvcreate --metadatacopies 1 "$dev2"
+vgcreate $vg1 "$dev1" "$dev2"
+lvcreate -n $lv1 -l 4 -a n $vg1
+
+# touch foo to disable first-pvscan case,
+# test case where dev with metadata appears first
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache -aay "$dev2"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache -aay "$dev1"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# touch foo to disable first-pvscan case,
+# test case where dev without metadata
+# appears first which triggers scanning all
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache -aay "$dev1"
+check lv_field $vg1/$lv1 lv_active "active"
+pvscan --cache -aay "$dev2"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# dev without metadata is scanned, but
+# first-pvscan case scans all devs
+
+rm /run/lvm/pvs_online/*
+
+pvscan --cache -aay "$dev1"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# use the --cache option to record a dev
+# is online without the -aay option to
+# activate until after they are online
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache "$dev1"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache "$dev2"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache -aay
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
+# like previous
+
+rm /run/lvm/pvs_online/*
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache "$dev1"
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache -aay "$dev2"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1
+
diff --git a/test/shell/pvscan-autoactivation-polling.sh b/test/shell/pvscan-autoactivation-polling.sh
new file mode 100644
index 0000000..53adf51
--- /dev/null
+++ b/test/shell/pvscan-autoactivation-polling.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2016 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
+
+SKIP_WITH_LVMLOCKD=1
+
+. lib/inittest
+
+# test if snapshot-merge target is available
+aux target_at_least dm-snapshot-merge 1 0 0 || skip
+
+which mkfs.ext3 || skip
+
+lvdev_() {
+ echo "$DM_DEV_DIR/$1/$2"
+}
+
+snap_lv_name_() {
+ echo ${1}_snap
+}
+
+setup_merge_() {
+ local VG_NAME=$1
+ local LV_NAME=$2
+ local NUM_EXTRA_SNAPS=${3:-0}
+ local BASE_SNAP_LV_NAME
+
+ BASE_SNAP_LV_NAME=$(snap_lv_name_ $LV_NAME)
+
+ lvcreate -aey -n $LV_NAME -l 50%FREE $VG_NAME
+ lvs
+ lvcreate -s -n $BASE_SNAP_LV_NAME -l 20%FREE ${VG_NAME}/${LV_NAME}
+ mkfs.ext3 "$(lvdev_ $VG_NAME $LV_NAME)"
+
+ if [ $NUM_EXTRA_SNAPS -gt 0 ]; then
+ for i in $(seq 1 $NUM_EXTRA_SNAPS); do
+ lvcreate -s -n ${BASE_SNAP_LV_NAME}_${i} -l 20%ORIGIN ${VG_NAME}/${LV_NAME}
+ done
+ fi
+}
+
+aux prepare_pvs 1 50
+
+vgcreate $vg1 "$dev1"
+mkdir test_mnt
+
+setup_merge_ $vg1 $lv1
+mount "$(lvdev_ $vg1 $lv1)" test_mnt
+lvconvert --merge "$vg1/$(snap_lv_name_ "$lv1")"
+umount test_mnt
+vgchange -an $vg1
+
+# check snapshot get removed on autoactivation
+pvscan --cache -aay "$dev1"
+
+check active $vg1 $lv1
+i=100
+while ! check lv_not_exists "$vg1/$(snap_lv_name_ "$lv1")"; do
+ test $i -lt 0 && fail "Background polling failed to remove merged snapshot LV"
+ sleep .1
+ i=$((i-1))
+done
+
+# TODO: add similar simple tests for other interrupted/unfinished polling operation
+
+vgremove -ff $vg1
diff --git a/test/shell/pvscan-cache.sh b/test/shell/pvscan-cache.sh
new file mode 100644
index 0000000..c272c6c
--- /dev/null
+++ b/test/shell/pvscan-cache.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2012 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
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux prepare_pvs 2
+
+vgcreate $vg1 "$dev1" "$dev2"
+vgs | grep $vg1
+
+pvscan --cache
+
+vgs | grep $vg1
+
+# Check that an LV cannot be activated by lvchange while VG is exported
+lvcreate -n $lv1 -l 4 -a n $vg1
+check lv_exists $vg1
+vgexport $vg1
+fail lvs $vg1
+fail lvchange -ay $vg1/$lv1
+vgimport $vg1
+check lv_exists $vg1
+check lv_field $vg1/$lv1 lv_active ""
+
+# Check that an LV cannot be activated by pvscan while VG is exported
+vgexport $vg1
+not pvscan --cache -aay "$dev1"
+not pvscan --cache -aay "$dev2"
+vgimport $vg1
+check lv_exists $vg1
+check lv_field $vg1/$lv1 lv_active ""
+pvscan --cache -aay "$dev1"
+pvscan --cache -aay "$dev2"
+check lv_field $vg1/$lv1 lv_active "active"
+lvchange -an $vg1/$lv1
+
+# When MDA is ignored on PV, do not read any VG
+# metadata from such PV as it may contain old
+# metadata which hasn't been updated for some
+# time and also since the MDA is marked as ignored,
+# it should really be *ignored*!
+pvchange --metadataignore y "$dev1"
+aux disable_dev "$dev2"
+pvscan --cache
+check pv_field "$dev1" vg_name "[unknown]"
+aux enable_dev "$dev2"
+pvscan --cache
+check pv_field "$dev1" vg_name "$vg1"
+
+vgremove -ff $vg1
diff --git a/test/shell/pvscan-nomda-bg.sh b/test/shell/pvscan-nomda-bg.sh
new file mode 100644
index 0000000..f8ecc08
--- /dev/null
+++ b/test/shell/pvscan-nomda-bg.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2015 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
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux prepare_devs 2
+
+pvcreate --metadatacopies 0 "$dev1"
+pvcreate --metadatacopies 1 "$dev2"
+vgcreate $vg1 "$dev1" "$dev2"
+lvcreate -n foo -l 1 -an --zero n $vg1
+
+check inactive $vg1 foo
+
+# create a file in pvs_online to disable the pvscan init
+# case which scans everything when the first dev appears.
+mkdir /run/lvm/pvs_online/
+touch /run/lvm/pvs_online/foo
+
+pvscan --cache --background "$dev2" -aay
+
+check inactive $vg1 foo
+
+pvscan --cache --background "$dev1" -aay
+
+check active $vg1 foo
+
+rm /run/lvm/pvs_online/foo
+vgremove -ff $vg1
5 years, 9 months
master - pvscan: autoactivate without lvmetad
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=db741e75a21bd9327ed...
Commit: db741e75a21bd9327ed1478e42495f2b0a419be9
Parent: c47655f23154c5483c6f097cdd1918deb9fe2f89
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jun 28 14:48:03 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 9 16:11:24 2018 -0500
pvscan: autoactivate without lvmetad
When lvmetad is not used, use temporary files to record
which PVs have appeared. Use these temp files to determine
when a VG is complete, to trigger autoactivation.
This change allows us to remove lvmetad while keeping the
same autoactivation behavior that lvmetad provides.
The temp files are created in /run/lvm/pvs_online/ and are
named for the PVID of the PV. The files contain the
major:minor of the device the PV was read from.
e.g. if VG foo has dev1 and dev2, then:
. pvscan --cache -aay dev1
reads vg metadata from dev1
creates /run/lvm/pvs_online/<pvid-of-dev1>
checks if all vg->pvs are online: no
. pvscan --cache -aay dev2
reads vg metadata from dev2
creates /run/lvm/pvs_online/<pvid-of-dev2>
checks if all vg->pvs are online: yes
autoactivates vg
A 'pvscan --cache dev' (without -aay) still records that
dev is online.
A 'pvscan --cache --major X --minor Y' after a device is
gone will remove the temp file for it.
A 'pvscan --cache [-aay]' (no devs) resets the state of
temp files by removing them all, then scanning all devs
and creating temp files for PVs that are found.
If no online files exist, the first pvscan --cache scans
all devs and creates temp files for any PVs found.
The scope of the temp files is only pvscan, and they are only
used for pvscan-based autoactivation. No other commands are
concerned with or aware of these temp files. When lvm creates
or removes PVs, no attempt is made to update the temp files.
---
lib/cache/lvmcache.c | 12 +-
lib/cache/lvmcache.h | 2 +
tools/pvscan.c | 655 +++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 659 insertions(+), 10 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index f15b352..f20928b 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -419,7 +419,7 @@ int vg_has_duplicate_pvs(struct volume_group *vg)
return 0;
}
-static int _dev_in_device_list(struct device *dev, struct dm_list *head)
+int dev_in_device_list(struct device *dev, struct dm_list *head)
{
struct device_list *devl;
@@ -432,7 +432,7 @@ static int _dev_in_device_list(struct device *dev, struct dm_list *head)
int lvmcache_dev_is_unchosen_duplicate(struct device *dev)
{
- return _dev_in_device_list(dev, &_unused_duplicate_devs);
+ return dev_in_device_list(dev, &_unused_duplicate_devs);
}
/*
@@ -601,8 +601,8 @@ next:
continue;
}
- prev_unchosen1 = _dev_in_device_list(dev1, &_unused_duplicate_devs);
- prev_unchosen2 = _dev_in_device_list(dev2, &_unused_duplicate_devs);
+ prev_unchosen1 = dev_in_device_list(dev1, &_unused_duplicate_devs);
+ prev_unchosen2 = dev_in_device_list(dev2, &_unused_duplicate_devs);
if (!prev_unchosen1 && !prev_unchosen2) {
/*
@@ -612,8 +612,8 @@ next:
* want the same duplicate preference to be preserved
* in each instance of lvmcache for a single command.
*/
- prev_unchosen1 = _dev_in_device_list(dev1, &cmd->unused_duplicate_devs);
- prev_unchosen2 = _dev_in_device_list(dev2, &cmd->unused_duplicate_devs);
+ prev_unchosen1 = dev_in_device_list(dev1, &cmd->unused_duplicate_devs);
+ prev_unchosen2 = dev_in_device_list(dev2, &cmd->unused_duplicate_devs);
}
dev1_major = MAJOR(dev1->dev);
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 008f110..92e27a2 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -210,4 +210,6 @@ struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted);
struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid);
void lvmcache_drop_saved_vgid(const char *vgid);
+int dev_in_device_list(struct device *dev, struct dm_list *head);
+
#endif
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 17fc1a6..393edb5 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -17,6 +17,11 @@
#include "lib/cache/lvmetad.h"
#include "lib/cache/lvmcache.h"
+#include "lib/metadata/metadata.h"
+
+#include <dirent.h>
+
+static int _pvscan_online_aa(struct cmd_context *cmd, int argc, char **argv);
struct pvscan_params {
int new_pvs_found;
@@ -35,7 +40,7 @@ struct pvscan_aa_params {
struct dm_list changed_vgnames;
};
-static int _pvscan_display_single(struct cmd_context *cmd,
+static int _pvscan_display_pv(struct cmd_context *cmd,
struct physical_volume *pv,
struct pvscan_params *params)
{
@@ -101,7 +106,7 @@ static int _pvscan_display_single(struct cmd_context *cmd,
return ECMD_PROCESSED;
}
-static int _pvscan_single(struct cmd_context *cmd, struct volume_group *vg,
+static int _pvscan_display_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv, struct processing_handle *handle)
{
struct pvscan_params *params = (struct pvscan_params *)handle->custom_handle;
@@ -122,7 +127,7 @@ static int _pvscan_single(struct cmd_context *cmd, struct volume_group *vg,
params->size_total += (uint64_t) pv_pe_count(pv) * pv_pe_size(pv);
}
- _pvscan_display_single(cmd, pv, params);
+ _pvscan_display_pv(cmd, pv, params);
return ECMD_PROCESSED;
}
@@ -650,6 +655,9 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
const char *reason = NULL;
int ret;
+ if (arg_is_set(cmd, cache_long_ARG) && !lvmetad_used())
+ return _pvscan_online_aa(cmd, argc, argv);
+
if (arg_is_set(cmd, cache_long_ARG))
return _pvscan_cache(cmd, argc, argv);
@@ -704,7 +712,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
handle->custom_handle = ¶ms;
- ret = process_each_pv(cmd, argc, argv, NULL, 0, 0, handle, _pvscan_single);
+ ret = process_each_pv(cmd, argc, argv, NULL, 0, 0, handle, _pvscan_display_single);
if (!params.pvs_found)
log_print_unless_silent("No matching physical volumes found");
@@ -722,3 +730,642 @@ out:
return ret;
}
+
+static const char *_pvs_online_dir = DEFAULT_RUN_DIR "/pvs_online";
+
+/*
+ * When a device goes offline we only know its major:minor, not its PVID.
+ * Since the dev isn't around, we can't read it to get its PVID, so we have to
+ * read the PVID files to find the one containing this major:minor and remove
+ * that one. This means that the PVID files need to contain the devno's they
+ * were created from.
+ */
+
+static void _online_pvid_file_remove_devno(int major, int minor)
+{
+ char path[PATH_MAX];
+ char buf[32];
+ char buf_in[32];
+ DIR *dir;
+ struct dirent *de;
+ int fd, rv;
+
+ memset(buf, 0, sizeof(buf));
+ snprintf(buf, sizeof(buf), "%d:%d\n", major, minor);
+
+ log_debug("Remove pv online devno %d:%d", major, minor);
+
+ if (!(dir = opendir(_pvs_online_dir)))
+ return;
+
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.')
+ continue;
+
+ memset(path, 0, sizeof(path));
+ snprintf(path, sizeof(path), "%s/%s", _pvs_online_dir, de->d_name);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ log_debug("Failed to open %s", path);
+ continue;
+ }
+
+ rv = read(fd, buf_in, sizeof(buf_in));
+ if (!rv || rv < 0) {
+ log_debug("Failed to read %s", path);
+ continue;
+ }
+
+ if (!strncmp(buf, buf_in, strlen(buf))) {
+ log_debug("Unlink pv online %s %s", buf, path);
+ unlink(path);
+ break;
+ }
+ }
+ closedir(dir);
+}
+
+static void _online_pvid_files_remove(void)
+{
+ char path[PATH_MAX];
+ DIR *dir;
+ struct dirent *de;
+
+ if (!(dir = opendir(_pvs_online_dir)))
+ return;
+
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.')
+ continue;
+
+ memset(path, 0, sizeof(path));
+ snprintf(path, sizeof(path), "%s/%s", _pvs_online_dir, de->d_name);
+ unlink(path);
+ }
+ closedir(dir);
+}
+
+static void _online_pvid_file_create(struct device *dev)
+{
+ char path[PATH_MAX];
+ char buf[32];
+ int major, minor;
+ int fd;
+ int rv;
+
+ memset(path, 0, sizeof(path));
+
+ major = (int)MAJOR(dev->dev);
+ minor = (int)MINOR(dev->dev);
+
+ snprintf(path, sizeof(path), "%s/%s", _pvs_online_dir, dev->pvid);
+
+ snprintf(buf, sizeof(buf), "%d:%d\n", major, minor);
+
+ log_debug("Create pv online: %s %d:%d %s", path, major, minor, dev_name(dev));
+
+ fd = open(path, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ log_warn("Failed to open %s: %d", path, errno);
+ return;
+ }
+
+ rv = write(fd, buf, strlen(buf));
+ if (!rv || rv < 0)
+ log_warn("Failed to write fd %d buf %s dev %s to %s: %d",
+ fd, buf, dev_name(dev), path, errno);
+
+ /* We don't care about syncing, these files are not even persistent. */
+
+ close(fd);
+}
+
+static int _online_pvid_file_exists(const char *pvid)
+{
+ char path[PATH_MAX];
+ struct stat buf;
+ int rv;
+
+ memset(path, 0, sizeof(path));
+
+ snprintf(path, sizeof(path), "%s/%s", _pvs_online_dir, pvid);
+
+ log_debug("Check pv online: %s", path);
+
+ rv = stat(path, &buf);
+ if (!rv) {
+ log_debug("Check pv online: yes");
+ return 1;
+ }
+ log_debug("Check pv online: no");
+ return 0;
+}
+
+static void _online_pvid_dir_setup(void)
+{
+ struct stat st;
+ int rv;
+
+ if (!stat(_pvs_online_dir, &st))
+ return;
+
+ dm_prepare_selinux_context(_pvs_online_dir, S_IFDIR);
+ rv = mkdir(_pvs_online_dir, 0777);
+ dm_prepare_selinux_context(NULL, 0);
+
+ if (rv < 0)
+ log_debug("Failed to create %s", _pvs_online_dir);
+}
+
+static int _online_pvid_files_missing(void)
+{
+ DIR *dir;
+ struct dirent *de;
+
+ if (!(dir = opendir(_pvs_online_dir))) {
+ log_debug("Failed to open %s", _pvs_online_dir);
+ return 1;
+ }
+
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.')
+ continue;
+ closedir(dir);
+ return 0;
+ }
+ closedir(dir);
+ return 1;
+}
+
+static int _online_pv_found(struct cmd_context *cmd,
+ struct device *dev, struct dm_list *dev_args,
+ struct volume_group *vg,
+ struct dm_list *found_vgnames)
+{
+ struct pv_list *pvl;
+ int pvids_not_online = 0;
+ int dev_args_in_vg = 0;
+
+ /*
+ * Create file named for pvid to record this PV is online.
+ */
+
+ _online_pvid_file_create(dev);
+
+ if (!vg || !found_vgnames)
+ return 1;
+
+ /*
+ * Check if all the PVs for this VG are online. This is only
+ * needed when autoactivating the VG which should be run only
+ * when the VG is complete. If the arrival of this dev completes
+ * the VG, then we want to activate the VG.
+ */
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (!_online_pvid_file_exists((const char *)&pvl->pv->id.uuid))
+ pvids_not_online++;
+
+ /* Check if one of the devs on the command line is in this VG. */
+ if (dev_args && dev_in_device_list(pvl->pv->dev, dev_args))
+ dev_args_in_vg = 1;
+ }
+
+ /*
+ * Return if we did not find an online file for one of the PVIDs
+ * in the VG, which means the VG is not yet complete.
+ */
+
+ if (pvids_not_online)
+ return 1;
+
+ /*
+ * When all PVIDs from the VG are online, then add vgname to
+ * found_vgnames.
+ */
+
+ log_debug("online dev %s completes VG %s.", dev_name(dev), vg->name);
+
+ /*
+ * We either want to return all complete VGs that are found on any devs
+ * we are scanning, or we want to return complete VGs only when they
+ * contain PVs that were specified on the command line.
+ */
+
+ if (!dev_args || dev_args_in_vg) {
+ log_debug("online dev %s can autoactivate VG %s", dev_name(dev), vg->name);
+ if (!str_list_add(cmd->mem, found_vgnames, dm_pool_strdup(cmd->mem, vg->name)))
+ stack;
+ }
+
+ return 1;
+}
+
+struct _pvscan_baton {
+ struct cmd_context *cmd;
+ struct volume_group *vg;
+ struct format_instance *fid;
+};
+
+static int _online_pvscan_single(struct metadata_area *mda, void *baton)
+{
+ struct _pvscan_baton *b = baton;
+ struct volume_group *vg;
+
+ if (mda_is_ignored(mda) ||
+ !(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL)))
+ return 1;
+
+ /* FIXME Also ensure contents match etc. */
+ if (!b->vg || vg->seqno > b->vg->seqno)
+ b->vg = vg;
+ else if (b->vg)
+ release_vg(vg);
+
+ return 1;
+}
+
+/*
+ * disable_remove is 1 when resetting the online state, which begins with
+ * removing all pvid files, and then creating new pvid files for PVs that
+ * are found, so we don't need to try to remove pvid files here when a PV
+ * is not found on a device.
+ */
+
+static int _online_pvscan_one(struct cmd_context *cmd, struct device *dev,
+ struct dm_list *dev_args,
+ struct dm_list *found_vgnames,
+ int disable_remove,
+ const char **pvid_without_metadata)
+{
+ struct label *label;
+ struct lvmcache_info *info;
+ struct _pvscan_baton baton;
+ const struct format_type *fmt;
+ /* Create a dummy instance. */
+ struct format_instance_ctx fic = { .type = 0 };
+ int ret = 0;
+
+ log_debug("pvscan metadata from dev %s", dev_name(dev));
+
+ if (udev_dev_is_mpath_component(dev)) {
+ log_debug("Ignore multipath component for pvscan.");
+ return 1;
+ }
+
+ if (!(info = lvmcache_info_from_pvid(dev->pvid, dev, 0))) {
+ log_debug("No PV info found on %s for PVID %s.", dev_name(dev), dev->pvid);
+ if (!disable_remove)
+ _online_pvid_file_remove_devno((int)MAJOR(dev->dev), (int)MINOR(dev->dev));
+ return 1;
+ }
+
+ if (!(label = lvmcache_get_label(info))) {
+ log_debug("No PV label found for %s.", dev_name(dev));
+ if (!disable_remove)
+ _online_pvid_file_remove_devno((int)MAJOR(dev->dev), (int)MINOR(dev->dev));
+ return 1;
+ }
+
+ fmt = lvmcache_fmt(info);
+
+ baton.cmd = cmd;
+ baton.vg = NULL;
+ baton.fid = fmt->ops->create_instance(fmt, &fic);
+
+ if (!baton.fid) {
+ ret = 0;
+ goto_out;
+ }
+
+ lvmcache_foreach_mda(info, _online_pvscan_single, &baton);
+
+ if (!baton.vg) {
+ if (pvid_without_metadata)
+ *pvid_without_metadata = dm_pool_strdup(cmd->mem, dev->pvid);
+ fmt->ops->destroy_instance(baton.fid);
+ }
+
+ ret = _online_pv_found(cmd, dev, dev_args, baton.vg, found_vgnames);
+
+ release_vg(baton.vg);
+out:
+ return ret;
+}
+
+/*
+ * dev_args is the list of devices that were specified on the
+ * pvscan command line.
+ *
+ * . When dev_args is NULL, any complete VGs that are found will
+ * be returned in found_vgnames.
+ *
+ * . When dev_args is set, then complete VGs that that contain
+ * devs in dev_args will be returned in found_vgnames.
+ */
+
+static void _online_pvscan_all_devs(struct cmd_context *cmd,
+ struct dm_list *found_vgnames,
+ struct dm_list *dev_args)
+{
+ struct dev_iter *iter;
+ struct device *dev;
+
+ label_scan(cmd);
+
+ if (!(iter = dev_iter_create(cmd->lvmetad_filter, 1))) {
+ log_error("dev_iter creation failed");
+ return;
+ }
+
+ while ((dev = dev_iter_get(cmd, iter))) {
+ if (sigint_caught()) {
+ stack;
+ break;
+ }
+
+ if (!_online_pvscan_one(cmd, dev, dev_args, found_vgnames, 1, NULL)) {
+ stack;
+ break;
+ }
+ }
+
+ dev_iter_destroy(iter);
+}
+
+static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name,
+ struct volume_group *vg, struct processing_handle *handle)
+{
+ struct pvscan_aa_params *pp = (struct pvscan_aa_params *)handle->custom_handle;
+
+ if (vg_is_clustered(vg))
+ return ECMD_PROCESSED;
+
+ if (vg_is_exported(vg))
+ return ECMD_PROCESSED;
+
+ if (vg_is_shared(vg))
+ return ECMD_PROCESSED;
+
+ log_debug("pvscan autoactivating VG %s.", vg_name);
+
+ if (!vgchange_activate(cmd, vg, CHANGE_AAY)) {
+ log_error("%s: autoactivation failed.", vg->name);
+ pp->activate_errors++;
+ }
+
+ return ECMD_PROCESSED;
+}
+
+static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
+ int all_vgs, struct dm_list *vgnames)
+{
+ struct processing_handle *handle = NULL;
+ int ret;
+
+ if (!all_vgs && dm_list_empty(vgnames)) {
+ log_debug("No VGs to autoactivate.");
+ return ECMD_PROCESSED;
+ }
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ handle->custom_handle = pp;
+
+ if (all_vgs) {
+ cmd->cname->flags |= ALL_VGS_IS_DEFAULT;
+ pp->refresh_all = 1;
+ }
+
+ ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_UPDATE, 0, handle, _pvscan_aa_single);
+
+ destroy_processing_handle(cmd, handle);
+
+ return ret;
+}
+
+static int _pvscan_online_aa(struct cmd_context *cmd, int argc, char **argv)
+{
+ struct pvscan_aa_params pp = { 0 };
+ struct dm_list single_devs;
+ struct dm_list found_vgnames;
+ struct device *dev;
+ struct device_list *devl;
+ const char *pv_name;
+ const char *pvid_without_metadata = NULL;
+ int32_t major = -1;
+ int32_t minor = -1;
+ int devno_args = 0;
+ struct arg_value_group_list *current_group;
+ dev_t devno;
+ int do_activate = arg_is_set(cmd, activate_ARG);
+ int all_vgs = 0;
+ int add_errors = 0;
+ int ret = ECMD_PROCESSED;
+
+ dm_list_init(&found_vgnames);
+
+ if (arg_is_set(cmd, major_ARG) + arg_is_set(cmd, minor_ARG))
+ devno_args = 1;
+
+ if (devno_args && (!arg_is_set(cmd, major_ARG) || !arg_is_set(cmd, minor_ARG))) {
+ log_error("Both --major and --minor required to identify devices.");
+ return EINVALID_CMD_LINE;
+ }
+
+ _online_pvid_dir_setup();
+
+ if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
+ log_error("Unable to obtain global lock.");
+ return ECMD_FAILED;
+ }
+
+ /*
+ * Scan all devices when no args are given.
+ */
+ if (!argc && !devno_args) {
+ log_verbose("pvscan all devices.");
+ _online_pvid_files_remove();
+ _online_pvscan_all_devs(cmd, NULL, NULL);
+ all_vgs = 1;
+ goto activate;
+ }
+
+ if (_online_pvid_files_missing()) {
+ log_verbose("pvscan all devices to initialize available PVs.");
+ _online_pvid_files_remove();
+ _online_pvscan_all_devs(cmd, NULL, NULL);
+ all_vgs = 1;
+ goto activate;
+ }
+
+ if (argc || devno_args) {
+ log_verbose("pvscan devices on command line.");
+ cmd->pvscan_cache_single = 1;
+ }
+
+ /* Creates a list of dev names from /dev, sysfs, etc; does not read any. */
+ dev_cache_scan();
+
+ dm_list_init(&single_devs);
+
+ while (argc--) {
+ pv_name = *argv++;
+ if (pv_name[0] == '/') {
+ if (!(dev = dev_cache_get(cmd, pv_name, cmd->lvmetad_filter))) {
+ log_debug("pvscan arg %s not found.", pv_name);
+ if ((dev = dev_cache_get(cmd, pv_name, NULL))) {
+ /* nothing to do for this dev name */
+ } else {
+ log_error("Physical Volume %s not found.", pv_name);
+ ret = ECMD_FAILED;
+ }
+ } else {
+ /*
+ * Scan device. This dev could still be removed
+ * below if it doesn't pass other filters.
+ */
+ log_debug("pvscan arg %s found.", pv_name);
+
+ if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
+ return_0;
+ devl->dev = dev;
+ dm_list_add(&single_devs, &devl->list);
+ }
+ } else {
+ if (sscanf(pv_name, "%d:%d", &major, &minor) != 2) {
+ log_warn("WARNING: Failed to parse major:minor from %s, skipping.", pv_name);
+ continue;
+ }
+ devno = MKDEV((dev_t)major, (dev_t)minor);
+
+ if (!(dev = dev_cache_get_by_devt(cmd, devno, cmd->lvmetad_filter))) {
+ log_debug("pvscan arg %d:%d not found.", major, minor);
+ _online_pvid_file_remove_devno(major, minor);
+ } else {
+ /*
+ * Scan device. This dev could still be removed
+ * below if it doesn't pass other filters.
+ */
+ log_debug("pvscan arg %d:%d found.", major, minor);
+
+ if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
+ return_0;
+ devl->dev = dev;
+ dm_list_add(&single_devs, &devl->list);
+ }
+ }
+
+ if (sigint_caught()) {
+ ret = ECMD_FAILED;
+ goto_out;
+ }
+ }
+
+ if (!dm_list_empty(&single_devs)) {
+ label_scan_devs(cmd, cmd->lvmetad_filter, &single_devs);
+
+ dm_list_iterate_items(devl, &single_devs) {
+ dev = devl->dev;
+
+ if (dev->flags & DEV_FILTER_OUT_SCAN)
+ continue;
+
+ /*
+ * Devices that exist and pass the lvmetad filter
+ * are online.
+ */
+ if (!_online_pvscan_one(cmd, dev, NULL, &found_vgnames, 0, &pvid_without_metadata))
+ add_errors++;
+ }
+ }
+
+ if (!devno_args)
+ goto activate;
+
+ dm_list_init(&single_devs);
+
+ /* Process any grouped --major --minor args */
+ dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
+ major = grouped_arg_int_value(current_group->arg_values, major_ARG, major);
+ minor = grouped_arg_int_value(current_group->arg_values, minor_ARG, minor);
+
+ if (major < 0 || minor < 0)
+ continue;
+
+ devno = MKDEV((dev_t)major, (dev_t)minor);
+
+ if (!(dev = dev_cache_get_by_devt(cmd, devno, cmd->lvmetad_filter))) {
+ log_debug("pvscan arg %d:%d not found.", major, minor);
+ _online_pvid_file_remove_devno(major, minor);
+ } else {
+ log_debug("pvscan arg %d:%d found.", major, minor);
+
+ if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
+ return_0;
+ devl->dev = dev;
+ dm_list_add(&single_devs, &devl->list);
+ }
+
+ if (sigint_caught()) {
+ ret = ECMD_FAILED;
+ goto_out;
+ }
+ }
+
+ if (!dm_list_empty(&single_devs)) {
+ label_scan_devs(cmd, cmd->lvmetad_filter, &single_devs);
+
+ dm_list_iterate_items(devl, &single_devs) {
+ dev = devl->dev;
+
+ if (dev->flags & DEV_FILTER_OUT_SCAN)
+ continue;
+
+ /*
+ * Devices that exist and pass the lvmetad filter
+ * are online.
+ */
+ if (!_online_pvscan_one(cmd, devl->dev, NULL, &found_vgnames, 0, &pvid_without_metadata))
+ add_errors++;
+ }
+ }
+
+activate:
+ /*
+ * Special case: pvscan --cache -aay dev
+ * where dev has no VG metadata, and it's the final device to
+ * complete the VG. In this case we want to autoactivate the
+ * VG, but the scanned device does not know what VG it's in or
+ * whether that VG is now complete. In this case we need to
+ * scan all devs and pick out the complete VG holding this
+ * device so we can then autoactivate that VG.
+ */
+ if (!dm_list_empty(&single_devs) && dm_list_empty(&found_vgnames) &&
+ pvid_without_metadata && do_activate) {
+ log_verbose("pvscan all devices for PV without metadata: %s.", pvid_without_metadata);
+ _online_pvscan_all_devs(cmd, &found_vgnames, &single_devs);
+ }
+
+ /*
+ * Step 2: when the PV was recorded online, we check if all the
+ * PVs for the VG are online. If so, the vgname was added to the
+ * list, and we can attempt to autoactivate LVs in the VG.
+ */
+ if (do_activate)
+ ret = _pvscan_aa(cmd, &pp, all_vgs, &found_vgnames);
+
+out:
+ if (add_errors || pp.activate_errors)
+ ret = ECMD_FAILED;
+
+ if (!sync_local_dev_names(cmd))
+ stack;
+ unlock_vg(cmd, NULL, VG_GLOBAL);
+ return ret;
+}
+
5 years, 9 months
master - tests: initial vdo tests
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c47655f23154c5483c6...
Commit: c47655f23154c5483c6f097cdd1918deb9fe2f89
Parent: faa126882a9cf2fb64dd143bb96414399e30edf2
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Jun 24 20:06:59 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:29:16 2018 +0200
tests: initial vdo tests
Basic functionality of lvcreate, lvchange.
---
test/lib/aux.sh | 8 +++
test/shell/lvchange-vdo.sh | 142 +++++++++++++++++++++++++++++++++++++++++++
test/shell/lvconvert-vdo.sh | 72 ++++++++++++++++++++++
test/shell/lvcreate-vdo.sh | 83 +++++++++++++++++++++++++
test/shell/profiles-vdo.sh | 50 +++++++++++++++
5 files changed, 355 insertions(+), 0 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 4eb9260..f72c851 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -1552,6 +1552,14 @@ have_thin() {
fi
}
+have_vdo() {
+ lvm segtypes 2>/dev/null | grep -q vdo$ || {
+ echo "VDO is not built-in." >&2
+ return 1
+ }
+ target_at_least dm-vdo "$@"
+}
+
have_raid() {
target_at_least dm-raid "$@"
diff --git a/test/shell/lvchange-vdo.sh b/test/shell/lvchange-vdo.sh
new file mode 100644
index 0000000..6d2b451
--- /dev/null
+++ b/test/shell/lvchange-vdo.sh
@@ -0,0 +1,142 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2018 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
+
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux have_vdo 6 2 0 || skip
+
+aux prepare_vg 2 6400
+
+lvcreate --vdo -L5G -n $lv1 $vg/vdopool
+
+# deduplication_ARG (default is 'yes')
+# compression_ARG (default is 'yes')
+
+# Wait till index gets openned
+for i in {1..10} ; do
+ sleep .1
+ check grep_dmsetup status $vg-vdopool " online online " || continue
+ break
+done
+
+
+# compression_ARG
+lvchange --compression n $vg/vdopool
+check grep_dmsetup status $vg-vdopool " online offline "
+lvchange --compression y $vg/vdopool
+check grep_dmsetup status $vg-vdopool " online online "
+
+# dedulication_ARG
+lvchange --deduplication n $vg/vdopool
+check grep_dmsetup status $vg-vdopool " offline online "
+lvchange --deduplication y $vg/vdopool
+check grep_dmsetup status $vg-vdopool " online online "
+
+
+lvchange --compression n --deduplication n $vg/vdopool
+check grep_dmsetup status $vg-vdopool " offline offline "
+
+
+lvchange -an $vg/$lv1
+
+# Test activation
+lvchange -aly $vg/$lv1
+check active $vg $lv1
+
+lvchange -aln $vg/$lv1
+check inactive $vg $lv1
+
+# Test for allowable changes
+#
+# contiguous_ARG
+lvchange -C y $vg/$lv1
+lvchange -C n $vg/$lv1
+
+# permission_ARG
+lvchange -p r $vg/$lv1
+lvchange -p rw $vg/$lv1
+
+# FIXME
+#should lvchange -p r $vg/vdopool
+#should lvchange -p rw $vg/vdopool
+
+# readahead_ARG
+lvchange -r none $vg/$lv1
+lvchange -r auto $vg/$lv1
+# FIXME
+# Think about more support
+
+# minor_ARG
+lvchange --yes -M y --minor 234 --major 253 $vg/$lv1
+lvchange -M n $vg/$lv1
+
+# cannot change major minor for pools
+not lvchange --yes -M y --minor 235 --major 253 $vg/vdopool
+not lvchange -M n $vg/vdopool
+
+# addtag_ARG
+lvchange --addtag foo $vg/$lv1
+lvchange --addtag foo $vg/vdopool
+
+# deltag_ARG
+lvchange --deltag foo $vg/$lv1
+lvchange --deltag foo $vg/vdopool
+
+
+#
+# Test for disallowed metadata changes
+#
+# resync_ARG
+not lvchange --resync $vg/$lv1
+
+# alloc_ARG
+#not lvchange --alloc anywhere $vg/$lv1
+
+# discards_ARG
+not lvchange --discards ignore $vg/$lv1
+
+# zero_ARG
+not lvchange --zero y $vg/$lv1
+
+
+#
+# Ensure that allowed args don't cause disallowed args to get through
+#
+not lvchange --resync -ay $vg/$lv1
+not lvchange --resync --addtag foo $vg/$lv1
+
+#
+# Play with tags and activation
+#
+TAG=$(uname -n)
+aux lvmconf "activation/volume_list = [ \"$vg/$lv2\", \"@mytag\" ]"
+
+lvchange -ay $vg/$lv1
+check inactive $vg $lv1
+
+lvchange --addtag mytag $vg/$lv1
+
+lvchange -ay @mytag_fake
+check inactive $vg $lv1
+
+lvchange -ay $vg/$lv1
+# Volume has matching tag
+check active $vg $lv1
+lvchange -an $vg/$lv1
+
+lvchange -ay @mytag
+check active $vg $lv1
+
+vgremove -ff $vg
diff --git a/test/shell/lvconvert-vdo.sh b/test/shell/lvconvert-vdo.sh
new file mode 100644
index 0000000..529f325
--- /dev/null
+++ b/test/shell/lvconvert-vdo.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2018 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
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+#
+# Main
+#
+aux have_vdo 6 2 0 || skip
+
+aux prepare_vg 2 6400
+
+# Conversion to vdo-pool
+lvcreate -L5G -n $lv1 $vg
+# Check there is big prompting warning
+not lvconvert --type vdo-pool $vg/$lv1 |& tee out
+grep "WARNING" out
+
+
+lvconvert -y --type vdo-pool $vg/$lv1
+lvremove -f $vg
+
+
+#
+lvcreate -L5G -n $lv1 $vg
+lvconvert -y --vdopool $vg/$lv1
+lvremove -f $vg
+
+
+lvcreate -L5G -n $lv1 $vg
+lvconvert -y --vdopool $vg/$lv1 -n $lv2
+check lv_field $vg/$lv1 segtype vdo-pool
+check lv_field $vg/${lv1}_vdata segtype linear -a
+check lv_field $vg/$lv2 segtype vdo
+lvremove -f $vg
+
+
+lvcreate -L5G -n $lv1 $vg
+lvconvert -y --type vdo-pool $vg/$lv1 -n $lv2 -V10G
+lvremove -f $vg
+
+
+lvcreate -L5G -n $lv1 $vg
+lvconvert -y --vdopool $vg/$lv1 -n $lv2 -V10G --compression n --deduplication n
+check lv_field $vg/$lv1 size "5.00g"
+check lv_field $vg/${lv1}_vdata size "5.00g" -a
+check lv_field $vg/$lv2 size "10.00g"
+lvremove -f $vg
+
+
+# Simple stacking works...
+# Just be sure test do not try to synchronize 5G of mirror!!
+lvcreate -L5G --type mirror --nosync -n $lv1 $vg
+lvconvert -y --vdopool $vg/$lv1 -n $lv2
+lvs -a $vg
+check lv_field $vg/${lv1}_vdata segtype mirror -a
+lvremove -f $vg
+
+
+vgremove -ff $vg
diff --git a/test/shell/lvcreate-vdo.sh b/test/shell/lvcreate-vdo.sh
new file mode 100644
index 0000000..64377cd
--- /dev/null
+++ b/test/shell/lvcreate-vdo.sh
@@ -0,0 +1,83 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2018 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
+
+
+SKIP_WITH_LVMPOLLD=1
+
+
+. lib/inittest
+
+#
+# Main
+#
+aux have_vdo 6 2 0 || skip
+which mkfs.ext4 || skip
+
+aux prepare_pvs 2 6400
+get_devs
+
+#aux lvmconf 'allocation/vdo_use_read_cache = 1' 'allocation/vdo_read_cache_size_mb = 64'
+
+#aux lvmconf 'allocation/vdo_use_compression = 0' 'allocation/vdo_use_deduplication = 0'
+
+#aux lvmconf 'allocation/vdo_hash_zone_threads = 0' \
+# 'allocation/vdo_logical_threads = 0' \
+# 'allocation/vdo_physical_threads = 0' \
+# 'allocation/vdo_cpu_threads = 1'
+
+aux lvmconf 'allocation/vdo_slab_size_mb = 128'
+
+
+vgcreate $SHARED -s 64K "$vg" "${DEVICES[@]}"
+
+# Create VDO device (vdo-pool is ATM internal volume type)
+lvcreate --type vdo -L4G -n $lv1 $vg/$lv2
+check lv_field $vg/$lv1 size "1.24g"
+check lv_field $vg/${lv2} size "4.00g"
+check lv_field $vg/${lv2}_vdata size "4.00g"
+lvremove -ff $vg
+
+
+lvcreate --vdo -L4G -V8G -n $lv1 $vg/$lv2
+check lv_field $vg/$lv1 size "8.00g"
+check lv_field $vg/${lv2} size "4.00g"
+check lv_field $vg/${lv2}_vdata size "4.00g"
+lvs -a $vg
+
+dmsetup table | grep $vg
+dmsetup status | grep $vg
+
+# Resize not yet supported
+not lvresize -y $vg/$lv1
+not lvresize -y $vg/${lv2}
+not lvresize -y $vg/${lv2}_vdata
+
+# Discard is very slow with VDO ATM so try to avoid it
+#time blkdiscard "$DM_DEV_DIR/$vg/$lv1"
+time mkfs.ext4 -E nodiscard "$DM_DEV_DIR/$vg/$lv1"
+#time mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+fsck -n "$DM_DEV_DIR/$vg/$lv1"
+
+# vpool itself is NOT usable filesystem
+not fsck -n "$DM_DEV_DIR/mapper/$vg-${lv2}"
+# not usable even when there is no linear mapping on top of it
+dmsetup remove ${vg}-$lv1
+not fsck -n "$DM_DEV_DIR/mapper/$vg-${lv2}"
+
+lvremove -ff $vg
+
+
+lvcreate --type vdo -L10G -V1T -n $lv1 $vg
+lvs -a $vg
+lvremove -ff $vg
+
+vgremove -ff $vg
diff --git a/test/shell/profiles-vdo.sh b/test/shell/profiles-vdo.sh
new file mode 100644
index 0000000..4a0f07e
--- /dev/null
+++ b/test/shell/profiles-vdo.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2018 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
+
+# Exercise obtaining cache parameter from various sources
+# Either commmand line or metadata profile or implicit default...
+
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux have_cache 1 8 0 || skip
+
+PDIR="$LVM_SYSTEM_DIR/profile"
+PFILE="vdo-test"
+
+aux prepare_profiles
+
+cat <<EOF > "$PDIR/${PFILE}.profile"
+allocation {
+ vdo_use_compression = 0
+ vdo_use_deduplication = 0
+ vdo_slab_size_mb = 128
+}
+EOF
+
+aux prepare_vg 2 1000000
+
+# Check chunk_size is grabbed from configuration
+lvcreate --vdo -L5G --config 'allocation/vdo_use_compression=0' $vg/vdopool
+lvdisplay -m $vg/vdopool | tee out
+grep "Compression.*no" out
+lvremove -f $vg
+
+# Without profile using 128MB slab it would NOT even pass
+lvcreate --vdo -L4G --metadataprofile "$PFILE" $vg/vdopool
+lvdisplay -m $vg/vdopool | tee out
+grep "Compression.*no" out
+lvremove -f $vg
+
+vgremove -ff $vg
5 years, 9 months
master - dmeventd: lvm vdo support
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=faa126882a9cf2fb64d...
Commit: faa126882a9cf2fb64dd143bb96414399e30edf2
Parent: 12213445b5f86155665ed6f027082e93c4f6cf85
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 9 11:43:12 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:29:16 2018 +0200
dmeventd: lvm vdo support
---
conf/example.conf.in | 44 +++++++++++++++++++++++++++++++++++++++++
lib/config/config_settings.h | 38 +++++++++++++++++++++++++++++++++++
lib/config/defaults.h | 4 +++
lib/vdo/vdo.c | 45 ++++++++++++++++++++++++++++++++++++++++++
tools/lvmcmdlib.c | 3 ++
5 files changed, 134 insertions(+), 0 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index f2bb77b..36204d3 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1533,6 +1533,33 @@ activation {
#
thin_pool_autoextend_percent = 20
+ # Configuration option activation/vdo_pool_autoextend_threshold.
+ # Auto-extend a VDO pool when its usage exceeds this percent.
+ # Setting this to 100 disables automatic extension.
+ # The minimum value is 50 (a smaller value is treated as 50.)
+ # Also see vdo_pool_autoextend_percent.
+ # Automatic extension requires dmeventd to be monitoring the LV.
+ #
+ # Example
+ # Using 70% autoextend threshold and 20% autoextend size, when a 10G
+ # VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
+ # 8.4G, it is extended to 14.4G:
+ # vdo_pool_autoextend_threshold = 70
+ #
+ vdo_pool_autoextend_threshold = 100
+
+ # Configuration option activation/vdo_pool_autoextend_percent.
+ # Auto-extending a VDO pool adds this percent extra space.
+ # The amount of additional space added to a VDO pool is this
+ # percent of its current size.
+ #
+ # Example
+ # Using 70% autoextend threshold and 20% autoextend size, when a 10G
+ # VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
+ # 8.4G, it is extended to 14.4G:
+ # This configuration option has an automatic default value.
+ # vdo_pool_autoextend_percent = 20
+
# Configuration option activation/mlock_filter.
# Do not mlock these memory areas.
# While activating devices, I/O to devices being (re)configured is
@@ -2154,6 +2181,23 @@ dmeventd {
# This configuration option has an automatic default value.
# thin_command = "lvm lvextend --use-policies"
+ # Configuration option dmeventd/vdo_library.
+ # The library dmeventd uses when monitoring a VDO pool device.
+ # libdevmapper-event-lvm2vdo.so monitors the filling of a pool
+ # and emits a warning through syslog when the usage exceeds 80%. The
+ # warning is repeated when 85%, 90% and 95% of the pool is filled.
+ # This configuration option has an automatic default value.
+ # vdo_library = "libdevmapper-event-lvm2vdo.so"
+
+ # Configuration option dmeventd/vdo_command.
+ # The plugin runs command with each 5% increment when VDO pool volume
+ # gets above 50%.
+ # Command which starts with 'lvm ' prefix is internal lvm command.
+ # You can write your own handler to customise behaviour in more details.
+ # User handler is specified with the full path starting with '/'.
+ # This configuration option has an automatic default value.
+ # vdo_command = "lvm lvextend --use-policies"
+
# Configuration option dmeventd/executable.
# The full path to the dmeventd binary.
# This configuration option has an automatic default value.
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 9026c2d..3417127 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -1478,6 +1478,30 @@ cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent",
"thin_pool_autoextend_percent = 20\n"
"#\n")
+cfg(activation_vdo_pool_autoextend_threshold_CFG, "vdo_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_VDO_POOL_AUTOEXTEND_THRESHOLD, VDO_1ST_VSN, NULL, 0, NULL,
+ "Auto-extend a VDO pool when its usage exceeds this percent.\n"
+ "Setting this to 100 disables automatic extension.\n"
+ "The minimum value is 50 (a smaller value is treated as 50.)\n"
+ "Also see vdo_pool_autoextend_percent.\n"
+ "Automatic extension requires dmeventd to be monitoring the LV.\n"
+ "#\n"
+ "Example\n"
+ "Using 70% autoextend threshold and 20% autoextend size, when a 10G\n"
+ "VDO pool exceeds 7G, it is extended to 12G, and when it exceeds\n"
+ "8.4G, it is extended to 14.4G:\n"
+ "vdo_pool_autoextend_threshold = 70\n"
+ "#\n")
+
+cfg(activation_vdo_pool_autoextend_percent_CFG, "vdo_pool_autoextend_percent", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_POOL_AUTOEXTEND_PERCENT, VDO_1ST_VSN, NULL, 0, NULL,
+ "Auto-extending a VDO pool adds this percent extra space.\n"
+ "The amount of additional space added to a VDO pool is this\n"
+ "percent of its current size.\n"
+ "#\n"
+ "Example\n"
+ "Using 70% autoextend threshold and 20% autoextend size, when a 10G\n"
+ "VDO pool exceeds 7G, it is extended to 12G, and when it exceeds\n"
+ "8.4G, it is extended to 14.4G:\n")
+
cfg_array(activation_mlock_filter_CFG, "mlock_filter", activation_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_ADVANCED, CFG_TYPE_STRING, NULL, vsn(2, 2, 62), NULL, 0, NULL,
"Do not mlock these memory areas.\n"
"While activating devices, I/O to devices being (re)configured is\n"
@@ -1965,6 +1989,20 @@ cfg(dmeventd_thin_command_CFG, "thin_command", dmeventd_CFG_SECTION, CFG_DEFAULT
"User handler is specified with the full path starting with '/'.\n")
/* TODO: systemd service handler */
+cfg(dmeventd_vdo_library_CFG, "vdo_library", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_VDO_LIB, VDO_1ST_VSN, NULL, 0, NULL,
+ "The library dmeventd uses when monitoring a VDO pool device.\n"
+ "libdevmapper-event-lvm2vdo.so monitors the filling of a pool\n"
+ "and emits a warning through syslog when the usage exceeds 80%. The\n"
+ "warning is repeated when 85%, 90% and 95% of the pool is filled.\n")
+
+cfg(dmeventd_vdo_command_CFG, "vdo_command", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_VDO_COMMAND, VDO_1ST_VSN, NULL, 0, NULL,
+ "The plugin runs command with each 5% increment when VDO pool volume\n"
+ "gets above 50%.\n"
+ "Command which starts with 'lvm ' prefix is internal lvm command.\n"
+ "You can write your own handler to customise behaviour in more details.\n"
+ "User handler is specified with the full path starting with '/'.\n")
+ /* TODO: systemd service handler */
+
cfg(dmeventd_executable_CFG, "executable", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_PATH, vsn(2, 2, 73), "@DMEVENTD_PATH@", 0, NULL,
"The full path to the dmeventd binary.\n")
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 2d70f53..9928fb1 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -83,6 +83,8 @@
#define DEFAULT_DMEVENTD_SNAPSHOT_LIB "libdevmapper-event-lvm2snapshot.so"
#define DEFAULT_DMEVENTD_THIN_LIB "libdevmapper-event-lvm2thin.so"
#define DEFAULT_DMEVENTD_THIN_COMMAND "lvm lvextend --use-policies"
+#define DEFAULT_DMEVENTD_VDO_LIB "libdevmapper-event-lvm2vdo.so"
+#define DEFAULT_DMEVENTD_VDO_COMMAND "lvm lvextend --use-policies"
#define DEFAULT_DMEVENTD_MONITOR 1
#define DEFAULT_BACKGROUND_POLLING 1
@@ -295,5 +297,7 @@
#define DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT 20
#define DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD 100
#define DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT 20
+#define DEFAULT_VDO_POOL_AUTOEXTEND_THRESHOLD 100
+#define DEFAULT_VDO_POOL_AUTOEXTEND_PERCENT 20
#endif /* _LVM_DEFAULTS_H */
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
index 80ddcfd..455ce5b 100644
--- a/lib/vdo/vdo.c
+++ b/lib/vdo/vdo.c
@@ -450,6 +450,38 @@ static int _vdo_modules_needed(struct dm_pool *mem,
return 1;
}
+
+# ifdef DMEVENTD
+/* FIXME Cache this */
+static int _vdo_pool_target_registered(struct lv_segment *seg, int *pending, int *monitored)
+{
+ return target_registered_with_dmeventd(seg->lv->vg->cmd,
+ seg->segtype->dso,
+ seg->lv, pending, monitored);
+}
+
+/* FIXME This gets run while suspended and performs banned operations. */
+static int _vdo_pool_target_set_events(struct lv_segment *seg, int evmask, int set)
+{
+ /* FIXME Make timeout (10) configurable */
+ return target_register_events(seg->lv->vg->cmd,
+ seg->segtype->dso,
+ seg->lv, evmask, set, 10);
+}
+
+static int _vdo_pool_target_register_events(struct lv_segment *seg,
+ int events)
+{
+ return _vdo_pool_target_set_events(seg, events, 1);
+}
+
+static int _vdo_pool_target_unregister_events(struct lv_segment *seg,
+ int events)
+{
+ return _vdo_pool_target_set_events(seg, events, 0);
+}
+
+# endif /* DMEVENTD */
#endif
/* reused as _vdo_destroy */
@@ -487,6 +519,12 @@ static struct segtype_handler _vdo_pool_ops = {
.add_target_line = _vdo_pool_add_target_line,
.target_present = _vdo_target_present,
.modules_needed = _vdo_modules_needed,
+
+# ifdef DMEVENTD
+ .target_monitored = _vdo_pool_target_registered,
+ .target_monitor_events = _vdo_pool_target_register_events,
+ .target_unmonitor_events = _vdo_pool_target_unregister_events,
+# endif /* DMEVENTD */
#endif
.destroy = _vdo_pool_destroy,
};
@@ -515,6 +553,13 @@ int init_vdo_segtypes(struct cmd_context *cmd,
pool_segtype->name = SEG_TYPE_NAME_VDO_POOL;
pool_segtype->flags = SEG_VDO_POOL | SEG_ONLY_EXCLUSIVE;
pool_segtype->ops = &_vdo_pool_ops;
+#ifdef DEVMAPPER_SUPPORT
+# ifdef DMEVENTD
+ pool_segtype->dso = get_monitor_dso_path(cmd, dmeventd_vdo_library_CFG);
+ if (pool_segtype->dso)
+ pool_segtype->flags |= SEG_MONITORED;
+# endif /* DMEVENTD */
+#endif
if (!lvm_register_segtype(seglib, pool_segtype))
return_0;
diff --git a/tools/lvmcmdlib.c b/tools/lvmcmdlib.c
index b787d09..695d4dd 100644
--- a/tools/lvmcmdlib.c
+++ b/tools/lvmcmdlib.c
@@ -87,6 +87,9 @@ int lvm2_run(void *handle, const char *cmdline)
else if (!strcmp(cmdline, "_dmeventd_thin_command")) {
if (setenv(cmdline, find_config_tree_str(cmd, dmeventd_thin_command_CFG, NULL), 1))
ret = ECMD_FAILED;
+ } else if (!strcmp(cmdline, "_dmeventd_vdo_command")) {
+ if (setenv(cmdline, find_config_tree_str(cmd, dmeventd_vdo_command_CFG, NULL), 1))
+ ret = ECMD_FAILED;
} else
ret = lvm_run_command(cmd, argc, argv);
5 years, 9 months
master - vgchange: vdo support
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=12213445b5f86155665...
Commit: 12213445b5f86155665ed6f027082e93c4f6cf85
Parent: 7b8aa4af57a8064ea3fa29355283aada2dac0db0
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Jul 1 12:03:23 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:29:16 2018 +0200
vgchange: vdo support
Support vgchange usage with VDO segtype.
Also changing extent size need small update for vdo virtual extent.
TODO: API needs enhancements so it's not about adding ifs() everywhere.
---
lib/metadata/vg.c | 5 +++++
tools/vgchange.c | 7 ++++++-
2 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 75a054f..20c2aec 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -504,6 +504,11 @@ int vg_set_extent_size(struct volume_group *vg, uint32_t new_extent_size)
new_extent_size))
return_0;
+ if (!_recalc_extents(&seg->vdo_pool_virtual_extents, lv->name,
+ " virtual extents", old_extent_size,
+ new_extent_size))
+ return_0;
+
/* foreach area */
for (s = 0; s < seg->area_count; s++) {
switch (seg_type(seg, s)) {
diff --git a/tools/vgchange.c b/tools/vgchange.c
index c444c30..fa0fd53 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -107,6 +107,9 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd, struct volume_group *vg,
if (lv_is_mirror_image(lv) || lv_is_mirror_log(lv))
continue;
+ if (lv_is_vdo_pool(lv))
+ continue;
+
if (lv_activation_skip(lv, activate, arg_is_set(cmd, ignoreactivationskip_ARG)))
continue;
@@ -219,7 +222,9 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
if ((lv_open = lvs_in_vg_opened(vg))) {
dm_list_iterate_items(lvl, &vg->lvs) {
- if (lv_is_visible(lvl->lv) && !lv_check_not_in_use(lvl->lv, 1)) {
+ if (lv_is_visible(lvl->lv) &&
+ !lv_is_vdo_pool(lvl->lv) && // FIXME: API skip flag missing
+ !lv_check_not_in_use(lvl->lv, 1)) {
log_error("Can't deactivate volume group \"%s\" with %d open logical volume(s)",
vg->name, lv_open);
return 0;
5 years, 9 months
master - lvconvert: support to convert lv into vdopool
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7b8aa4af57a8064ea3f...
Commit: 7b8aa4af57a8064ea3fa29355283aada2dac0db0
Parent: 6206bd0e790b92c8ec53c340902f74932675836f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Jun 30 23:38:49 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:29:16 2018 +0200
lvconvert: support to convert lv into vdopool
Support:
lvconvert --type vdo-pool vg/lv
lvconvert --vdopool vg/lv --virtualsize 10G
---
tools/command-lines.in | 18 ++++++++
tools/lvconvert.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++
tools/lvmcmdline.c | 4 ++
tools/tools.h | 3 +
4 files changed, 137 insertions(+), 0 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 4db1a0a..bf36738 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -555,6 +555,24 @@ RULE: --poolmetadata not --readahead --stripesize --stripes_long
---
+lvconvert --type vdo-pool LV_linear_striped_raid_cache
+OO: --name LV_new, --virtualsize SizeMB, --compression Bool, --deduplication Bool, OO_LVCONVERT
+ID: lvconvert_to_vdopool
+DESC: Convert LV to type vdopool.
+RULE: all and lv_is_visible
+RULE: all not lv_is_locked lv_is_origin lv_is_merging_origin lv_is_external_origin lv_is_virtual
+
+lvconvert --vdopool LV_linear_striped_raid_cache
+OO: --type vdo-pool, OO_LVCONVERT,
+--name LV_new, --virtualsize SizeMB, --compression Bool, --deduplication Bool
+ID: lvconvert_to_vdopool_param
+DESC: Convert LV to type vdopool.
+RULE: all and lv_is_visible
+RULE: all not lv_is_locked lv_is_origin lv_is_merging_origin lv_is_external_origin lv_is_virtual
+FLAGS: SECONDARY_SYNTAX
+
+---
+
lvconvert --splitcache LV_cachepool_cache_thinpool
OO: OO_LVCONVERT
ID: lvconvert_split_and_keep_cachepool
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 11f7cee..0bb1dc9 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -4740,6 +4740,118 @@ int lvconvert_merge_cmd(struct cmd_context *cmd, int argc, char **argv)
return ret;
}
+static int _lvconvert_to_vdopool_single(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ struct processing_handle *handle)
+{
+ const char *vg_name = NULL;
+ struct volume_group *vg = lv->vg;
+ struct logical_volume *vdo_lv;
+ struct dm_vdo_target_params vdo_params; /* vdo */
+ struct lvcreate_params lvc = {
+ .activate = CHANGE_AEY,
+ .alloc = ALLOC_INHERIT,
+ .major = -1,
+ .minor = -1,
+ .suppress_zero_warn = 1, /* Suppress warning for this VDO */
+ .permission = LVM_READ | LVM_WRITE,
+ .pool_name = lv->name,
+ .pvh = &vg->pvs,
+ .read_ahead = DM_READ_AHEAD_AUTO,
+ .stripes = 1,
+ .lv_name = arg_str_value(cmd, name_ARG, NULL),
+ };
+
+ if (lvc.lv_name &&
+ !validate_restricted_lvname_param(cmd, &vg_name, &lvc.lv_name))
+ return_0;
+
+ lvc.virtual_extents = extents_from_size(cmd,
+ arg_uint_value(cmd, virtualsize_ARG, 0),
+ vg->extent_size);
+
+ if (!(lvc.segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_VDO)))
+ return_0;
+
+ if (vg_is_shared(vg)) {
+ /* FIXME: need to swap locks betwen LVs? */
+ log_error("Unable to convert VDO pool in VG with lock_type %s", vg->lock_type);
+ goto out;
+ }
+
+ if (!fill_vdo_target_params(cmd, &vdo_params, NULL))
+ 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 (!activate_lv(cmd, lv)) {
+ log_error("Cannot activate %s.", display_lvname(lv));
+ goto out;
+ }
+
+ log_warn("WARNING: Converting logical volume %s to VDO pool volume.",
+ lv->name);
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+
+ if (!arg_count(cmd, yes_ARG) &&
+ yes_no_prompt("Do you really want to convert %s? [y/n]: ",
+ lv->name) == 'n') {
+ log_error("Conversion aborted.");
+ goto out;
+ }
+
+ if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1, .do_wipe_signatures = 1 })) {
+ log_error("Aborting. Failed to wipe VDO data store.");
+ goto out;
+ }
+
+ if (!archive(vg))
+ goto_out;
+
+ if (!convert_vdo_pool_lv(lv, &vdo_params, &lvc.virtual_extents))
+ goto_out;
+
+ dm_list_init(&lvc.tags);
+
+ if (!(vdo_lv = lv_create_single(vg, &lvc)))
+ goto_out; /* FIXME: hmmm what to do now */
+
+ log_print_unless_silent("Converted %s to VDO pool volume and created virtual %s VDO volume.",
+ display_lvname(lv), display_lvname(vdo_lv));
+
+ return ECMD_PROCESSED;
+
+ out:
+ return ECMD_FAILED;
+}
+
+int lvconvert_to_vdopool_cmd(struct cmd_context *cmd, int argc, char **argv)
+{
+ return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
+ NULL, NULL, &_lvconvert_to_vdopool_single);
+}
+
+int lvconvert_to_vdopool_param_cmd(struct cmd_context *cmd, int argc, char **argv)
+{
+ /* Make the LV the first position arg. */
+ int i, p = cmd->position_argc;
+
+ for (i = 0; i < cmd->position_argc; i++)
+ cmd->position_argv[p] = cmd->position_argv[p-1];
+
+ cmd->position_argv[0] = (char *)arg_str_value(cmd, vdopool_ARG, NULL);
+ cmd->position_argc++;
+
+ return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
+ NULL, NULL, &_lvconvert_to_vdopool_single);
+}
+
/*
* All lvconvert command defs have their own function,
* so the generic function name is unused.
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 3e617c1..1146e7c 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -143,6 +143,10 @@ static const struct command_function _command_functions[CMD_COUNT] = {
/* redirected to merge_snapshot/merge_thin/merge_mirrors */
{ lvconvert_merge_CMD, lvconvert_merge_cmd },
+ /* lvconvert VDO pool */
+ { lvconvert_to_vdopool_CMD, lvconvert_to_vdopool_cmd },
+ { lvconvert_to_vdopool_param_CMD, lvconvert_to_vdopool_param_cmd },
+
};
diff --git a/tools/tools.h b/tools/tools.h
index 508da84..d605768 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -267,4 +267,7 @@ int lvconvert_change_region_size_cmd(struct cmd_context * cmd, int argc, char **
int lvconvert_merge_cmd(struct cmd_context *cmd, int argc, char **argv);
+int lvconvert_to_vdopool_cmd(struct cmd_context *cmd, int argc, char **argv);
+int lvconvert_to_vdopool_param_cmd(struct cmd_context *cmd, int argc, char **argv);
+
#endif
5 years, 9 months
master - lvchange: vdo support compression deduplication change
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6206bd0e790b92c8ec5...
Commit: 6206bd0e790b92c8ec53c340902f74932675836f
Parent: c58733ca1538d04a298c4c857492ca544a820064
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 2 10:51:45 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:29:15 2018 +0200
lvchange: vdo support compression deduplication change
Add basic support for changing compression and deduplication state
of a VDO pool volume.
Allowing to access it also via top-level VDO volume.
---
tools/command-lines.in | 3 +-
tools/lvchange.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 73 insertions(+), 1 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index de5c88b..4db1a0a 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -221,6 +221,7 @@ OO_LVCHANGE: --autobackup Bool, --force, --ignoremonitoring,
OO_LVCHANGE_META: --addtag Tag, --deltag Tag,
--alloc Alloc, --contiguous Bool,
+--compression Bool, --deduplication Bool,
--detachprofile, --metadataprofile String, --profile String,
--permission Permission, --readahead Readahead, --setactivationskip Bool,
--errorwhenfull Bool, --discards Discards, --zero Bool,
@@ -308,7 +309,7 @@ OO: --major Number, --activate Active, --poll Bool, --monitor Bool, OO_LVCHANGE
IO: --ignoreskippedcluster
ID: lvchange_persistent
DESC: Make the minor device number persistent for an LV.
-RULE: all not LV_thinpool LV_cachepool
+RULE: all not LV_thinpool LV_cachepool LV_vdopool
---
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 3ed6b06..6282a6f 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -934,6 +934,62 @@ static int _lvchange_activation_skip(struct logical_volume *lv, uint32_t *mr)
return 1;
}
+static int _lvchange_compression(struct logical_volume *lv, uint32_t *mr)
+{
+ struct cmd_context *cmd = lv->vg->cmd;
+ unsigned compression = arg_uint_value(cmd, compression_ARG, 0);
+ struct lv_segment *seg = first_seg(lv);
+
+ if (lv_is_vdo(lv))
+ seg = first_seg(seg_lv(seg, 0));
+ else if (!lv_is_vdo_pool(lv)) {
+ log_error("Unable to change compression for non VDO volume %s.",
+ display_lvname(lv));
+ return 0;
+ }
+
+ if (compression == seg->vdo_params.use_compression) {
+ log_error("Logical volume %s already uses --compression %c.",
+ display_lvname(lv), compression ? 'y' : 'n');
+ return 0;
+ }
+
+ seg->vdo_params.use_compression = compression;
+
+ /* Request caller to commit and reload metadata */
+ *mr |= MR_RELOAD;
+
+ return 1;
+}
+
+static int _lvchange_deduplication(struct logical_volume *lv, uint32_t *mr)
+{
+ struct cmd_context *cmd = lv->vg->cmd;
+ unsigned deduplication = arg_uint_value(cmd, deduplication_ARG, 0);
+ struct lv_segment *seg = first_seg(lv);
+
+ if (lv_is_vdo(lv))
+ seg = first_seg(seg_lv(seg, 0));
+ else if (!lv_is_vdo_pool(lv)) {
+ log_error("Unable to change deduplication for non VDO volume %s.",
+ display_lvname(lv));
+ return 0;
+ }
+
+ if (deduplication == seg->vdo_params.use_deduplication) {
+ log_error("Logical volume %s already uses --deduplication %c.",
+ display_lvname(lv), deduplication ? 'y' : 'n');
+ return 0;
+ }
+
+ seg->vdo_params.use_deduplication = deduplication;
+
+ /* Request caller to commit and reload metadata */
+ *mr |= MR_RELOAD;
+
+ return 1;
+}
+
/* Update and reload or commit and/or backup metadata for @lv as requested by @mr */
static int _commit_reload(struct logical_volume *lv, uint32_t mr)
{
@@ -966,6 +1022,8 @@ static int _option_allows_group_commit(int opt_enum)
permission_ARG,
alloc_ARG,
contiguous_ARG,
+ compression_ARG,
+ deduplication_ARG,
errorwhenfull_ARG,
readahead_ARG,
persistent_ARG,
@@ -1117,6 +1175,16 @@ static int _lvchange_properties_single(struct cmd_context *cmd,
doit += _lvchange_activation_skip(lv, &mr);
break;
+ case compression_ARG:
+ docmds++;
+ doit += _lvchange_compression(lv, &mr);
+ break;
+
+ case deduplication_ARG:
+ docmds++;
+ doit += _lvchange_deduplication(lv, &mr);
+ break;
+
default:
log_error(INTERNAL_ERROR "Failed to check for option %s",
arg_long_option_name(i));
@@ -1346,6 +1414,9 @@ static int _lvchange_activate_check(struct cmd_context *cmd,
return 0;
}
+ if (lv_is_vdo_pool(lv) && !lv_is_named_arg)
+ return 0; /* Skip VDO pool processing unless explicitely named */
+
return 1;
}
5 years, 9 months
master - lvcreate: vdo support
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c58733ca1538d04a298...
Commit: c58733ca1538d04a298c4c857492ca544a820064
Parent: 6945bbdbc6f997568707594b4b930f3551893910
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 29 13:16:08 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:29:12 2018 +0200
lvcreate: vdo support
Supports basic: 'lvcreate --vdo -LXXXG -VYYYG vg/vdoname -n lvname'
Allows to create basic VDO pool volume and virtual VDO volume.
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 3 +
lib/metadata/vdo_manip.c | 53 ++++++++++++++++++++++++++
tools/command-lines.in | 26 +++++++++++++
tools/lvcreate.c | 76 +++++++++++++++++++++++++++++++++++---
5 files changed, 153 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 54d6790..407cb7e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 3.0.0
=============
+ Add basic creation support for VDO target.
Never send any discard ioctl with test mode.
Fix thin-pool alloc which needs same PV for data and metadata.
Extend list of non-memlocked areas with newly linked libs.
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 92def2b..840f623 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1270,6 +1270,9 @@ struct logical_volume *convert_vdo_pool_lv(struct logical_volume *data_lv,
const struct dm_vdo_target_params *vtp,
uint32_t *virtual_extents);
int get_vdo_write_policy(enum dm_vdo_write_policy *vwp, const char *policy);
+int fill_vdo_target_params(struct cmd_context *cmd,
+ struct dm_vdo_target_params *vtp,
+ struct profile *profile);
/* -- 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 1286e84..0b3ed19 100644
--- a/lib/metadata/vdo_manip.c
+++ b/lib/metadata/vdo_manip.c
@@ -404,3 +404,56 @@ int get_vdo_write_policy(enum dm_vdo_write_policy *vwp, const char *policy)
return 1;
}
+
+int fill_vdo_target_params(struct cmd_context *cmd,
+ struct dm_vdo_target_params *vtp,
+ struct profile *profile)
+{
+ const char *policy;
+
+ // TODO: Postpone filling data to the moment when VG is known with profile.
+ // TODO: Maybe add more lvm cmdline switches to set profile settings.
+
+ vtp->use_compression =
+ find_config_tree_int(cmd, allocation_vdo_use_compression_CFG, profile);
+ vtp->use_deduplication =
+ find_config_tree_int(cmd, allocation_vdo_use_deduplication_CFG, profile);
+ vtp->emulate_512_sectors =
+ find_config_tree_int(cmd, allocation_vdo_emulate_512_sectors_CFG, profile);
+ vtp->block_map_cache_size_mb =
+ find_config_tree_int64(cmd, allocation_vdo_block_map_cache_size_mb_CFG, profile);
+ vtp->block_map_period =
+ find_config_tree_int(cmd, allocation_vdo_block_map_period_CFG, profile);
+ vtp->check_point_frequency =
+ find_config_tree_int(cmd, allocation_vdo_check_point_frequency_CFG, profile);
+ vtp->use_sparse_index =
+ find_config_tree_int(cmd, allocation_vdo_use_sparse_index_CFG, profile);
+ vtp->index_memory_size_mb =
+ find_config_tree_int64(cmd, allocation_vdo_index_memory_size_mb_CFG, profile);
+ vtp->use_read_cache =
+ find_config_tree_int(cmd, allocation_vdo_use_read_cache_CFG, profile);
+ vtp->read_cache_size_mb =
+ find_config_tree_int64(cmd, allocation_vdo_read_cache_size_mb_CFG, profile);
+ vtp->slab_size_mb =
+ find_config_tree_int(cmd, allocation_vdo_slab_size_mb_CFG, profile);
+ vtp->ack_threads =
+ find_config_tree_int(cmd, allocation_vdo_ack_threads_CFG, profile);
+ vtp->bio_threads =
+ find_config_tree_int(cmd, allocation_vdo_bio_threads_CFG, profile);
+ vtp->bio_rotation =
+ find_config_tree_int(cmd, allocation_vdo_bio_rotation_CFG, profile);
+ vtp->cpu_threads =
+ find_config_tree_int(cmd, allocation_vdo_cpu_threads_CFG, profile);
+ vtp->hash_zone_threads =
+ find_config_tree_int(cmd, allocation_vdo_hash_zone_threads_CFG, profile);
+ vtp->logical_threads =
+ find_config_tree_int(cmd, allocation_vdo_logical_threads_CFG, profile);
+ vtp->physical_threads =
+ find_config_tree_int(cmd, allocation_vdo_physical_threads_CFG, profile);
+
+ policy = find_config_tree_str(cmd, allocation_vdo_write_policy_CFG, profile);
+ if (!get_vdo_write_policy(&vtp->write_policy, policy))
+ return_0;
+
+ return 1;
+}
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 0155b33..de5c88b 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -731,6 +731,7 @@ OO_LVCREATE_POOL: --poolmetadatasize SizeMB, --poolmetadataspare Bool, --chunksi
OO_LVCREATE_THIN: --discards Discards, --errorwhenfull Bool
+OO_LVCREATE_VDO: --compression Bool, --deduplication Bool
---
lvcreate --type error --size SizeMB VG
@@ -741,6 +742,31 @@ FLAGS: SECONDARY_SYNTAX
---
+lvcreate --type vdo --size SizeMB VG
+OO: --vdo, OO_LVCREATE, OO_LVCREATE_VDO, --virtualsize SizeMB, --stripes Number, --stripesize SizeKB,
+OP: PV ...
+IO: --mirrors 0
+ID: lvcreate_vdo_vol
+DESC: Create an LV that returns VDO when used.
+
+lvcreate --vdo --size SizeMB VG
+OO: OO_LVCREATE, OO_LVCREATE_VDO, --virtualsize SizeMB, --stripes Number, --stripesize SizeKB
+OP: PV ...
+IO: --mirrors 0
+ID: lvcreate_vdo_vol
+DESC: Create an VDO LV with VDO pool.
+FLAGS: SECONDARY_SYNTAX
+
+lvcreate --vdopool LV --virtualsize SizeMB VG
+OO: --vdo, --type vdo
+OP: PV ...
+IO: --mirrors 0
+ID: lvcreate_vdo_vol
+DESC: Create an VDO LV using existing VDO pool.
+FLAGS: SECONDARY_SYNTAX
+
+---
+
lvcreate --type zero --size SizeMB VG
OO: OO_LVCREATE
ID: lvcreate_zero_vol
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 4009ea5..3c22794 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -61,6 +61,7 @@ static int _lvcreate_name_params(struct cmd_context *cmd,
return_0;
lp->pool_name = arg_str_value(cmd, thinpool_ARG, NULL)
+ ? : arg_str_value(cmd, vdopool_ARG, NULL)
? : arg_str_value(cmd, cachepool_ARG, NULL);
if (!validate_lvname_param(cmd, &lp->vg_name, &lp->pool_name))
return_0;
@@ -154,7 +155,7 @@ static int _lvcreate_name_params(struct cmd_context *cmd,
}
(*pargv)++, (*pargc)--;
- } else if ((seg_is_thin(lp) || seg_is_pool(lp)) && argc) {
+ } else if ((seg_is_pool(lp) || seg_is_thin(lp) || seg_is_vdo(lp)) && argc) {
/* argv[0] might be [/dev.../]vg or [/dev../]vg/pool */
vg_name = skip_dev_dir(cmd, argv[0], NULL);
@@ -766,6 +767,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
segtype_str = SEG_TYPE_NAME_CACHE;
else if (arg_is_set(cmd, thin_ARG) || arg_is_set(cmd, thinpool_ARG))
segtype_str = SEG_TYPE_NAME_THIN;
+ else if (arg_is_set(cmd, vdo_ARG))
+ segtype_str = SEG_TYPE_NAME_VDO;
else if (arg_is_set(cmd, virtualsize_ARG)) {
if (arg_is_set(cmd, virtualoriginsize_ARG))
segtype_str = SEG_TYPE_NAME_SNAPSHOT; /* --virtualoriginsize incompatible with pools */
@@ -852,6 +855,10 @@ static int _lvcreate_params(struct cmd_context *cmd,
discards_ARG,\
thinpool_ARG
+#define VDO_POOL_ARGS \
+ compression_ARG,\
+ deduplication_ARG
+
/* Cache and cache-pool segment type */
if (seg_is_cache(lp)) {
/* Only supported with --type cache, -H, --cache */
@@ -1034,6 +1041,46 @@ static int _lvcreate_params(struct cmd_context *cmd,
thin_ARG, THIN_POOL_ARGS,
-1))
return_0;
+ else if (seg_is_vdo(lp)) {
+ /* Only supported with --type thin, -T, --thin, -V */
+ if (arg_outside_list_is_set(cmd, "is unsupported with VDOs",
+ LVCREATE_ARGS,
+ PERSISTENT_ARGS,
+ SIZE_ARGS,
+ VDO_POOL_ARGS,
+ vdo_ARG,
+ virtualsize_ARG,
+ wipesignatures_ARG, zero_ARG,
+ -1))
+ return_0;
+
+ /* If size/extents given with thin, then we are also creating a thin-pool */
+ if (arg_is_set(cmd, size_ARG) || arg_is_set(cmd, extents_ARG)) {
+ if (arg_is_set(cmd, pooldatasize_ARG)) {
+ log_error("Please specify either size or pooldatasize.");
+ return 0;
+ }
+ lp->create_pool = 1;
+ } else if (arg_from_list_is_set(cmd, "is supported only with VDO pool creation",
+ VDO_POOL_ARGS,
+ SIZE_ARGS,
+ 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, 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 */
if (!seg_is_mirror(lp) && !seg_is_raid(lp)) {
@@ -1055,8 +1102,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
-1))
return_0;
- if (!lp->snapshot && !seg_is_thin_volume(lp) &&
- arg_from_list_is_set(cmd, "is supported only with sparse snapshots and thins",
+ if (!lp->snapshot && !seg_is_thin_volume(lp) && !seg_is_vdo(lp) &&
+ arg_from_list_is_set(cmd, "is supported only with vdo, sparse snapshots and thins",
virtualsize_ARG,
-1))
return_0;
@@ -1423,6 +1470,7 @@ static int _check_pool_parameters(struct cmd_context *cmd,
if (!seg_is_cache(lp) &&
!seg_is_thin_volume(lp) &&
+ !seg_is_vdo(lp) &&
!seg_is_pool(lp)) {
if (lp->pool_name && !lp->snapshot) {
log_error("Segment type %s cannot use pool %s.",
@@ -1444,13 +1492,14 @@ static int _check_pool_parameters(struct cmd_context *cmd,
return 0;
}
}
- if (seg_is_pool(lp)) {
+ if (seg_is_pool(lp) || seg_is_vdo(lp)) {
if (lp->major != -1 || lp->minor != -1) {
log_error("Persistent major and minor numbers are unsupported with pools.");
return 0;
}
/* When creating just pool the pool_name needs to be in lv_name */
- lp->lv_name = lp->pool_name;
+ if (seg_is_pool(lp))
+ lp->lv_name = lp->pool_name;
} else if (vg) {
/* FIXME: what better to do with --readahead and pools? */
if (arg_is_set(cmd, readahead_ARG)) {
@@ -1492,6 +1541,17 @@ static int _check_pool_parameters(struct cmd_context *cmd,
return 1;
}
+static int _check_vdo_parameters(struct volume_group *vg, struct lvcreate_params *lp,
+ struct lvcreate_cmdline_params *lcp)
+{
+ if (seg_is_vdo(lp) && lp->snapshot) {
+ log_error("Please either create VDO or snapshot.");
+ return 0;
+ }
+
+ return 1;
+}
+
/*
* Check zero_ARG with default value set to value of wipesignatures_ARG
* with its default set to 'n'. So if user specifies on command line either
@@ -1612,6 +1672,9 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
if (!_check_pool_parameters(cmd, vg, lp, lcp))
goto_out;
+ if (seg_is_vdo(lp) && !_check_vdo_parameters(vg, lp, lcp))
+ return_0;
+
/* All types are checked */
if (!_check_zero_parameters(cmd, lp))
return_0;
@@ -1622,7 +1685,8 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
if (seg_is_thin(lp) && !_validate_internal_thin_processing(lp))
goto_out;
- if (lp->create_pool) {
+ if (lp->create_pool && !seg_is_vdo(lp)) {
+ /* TODO: VDO does not use spare LV ATM, maybe later for rescue resize ? */
if (!handle_pool_metadata_spare(vg, lp->pool_metadata_extents,
lp->pvh, lp->pool_metadata_spare))
goto_out;
5 years, 9 months
master - lvresize: vdo support
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6945bbdbc6f99756870...
Commit: 6945bbdbc6f997568707594b4b930f3551893910
Parent: 96e9929f2f2d23d2113920efd67431d0272aba5f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 2 10:54:56 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Jul 9 15:28:35 2018 +0200
lvresize: vdo support
Unsupported ATM.
Wait till VDO kernel target starts to use updated resize sequence,
LOAD, SUSPEND, RESUME.
---
lib/metadata/lv_manip.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index d3c4e76..43e09a4 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4893,6 +4893,12 @@ static int _lvresize_check(struct logical_volume *lv,
return 0;
}
+ if (lv_is_vdo_type(lv)) {
+ log_error("Resize of VDO type volume %s is not yet supported.",
+ display_lvname(lv));
+ return 0;
+ }
+
if (lv_is_raid(lv) &&
lp->resize == LV_REDUCE) {
unsigned attrs;
5 years, 9 months