Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ed30145f4ad030b7…
Commit: ed30145f4ad030b751b529590ab0f6f41afa17bc
Parent: 3ac7f927e1e587089bbbbae04ecad1906af55485
Author: Mikulas Patocka <mpatocka(a)redhat.com>
AuthorDate: Mon Sep 16 15:23:54 2013 -0400
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Oct 17 11:57:33 2013 +0200
libdm: fix races with udev
On modern systems udev manages nodes in /dev/mapper directory.
It creates, deletes and renames the nodes according to the
state of the kernel driver.
When the dmsetup is compiled without udev support (--enable-udev_sync)
and runs on the system with running udevd it tries to manage nodes in
/dev/mapper too, so it can race with udev.
dmsetup checks if the node was created/deleted/renamed with the stat
syscall, and skips the operation if it was. However, if udev
creates/deletes/renames the node after the stat syscall and before the
mknod/unlink/rename syscall, dmsetup reports an error.
Since in the system everything happened as expected, skip reporting
error for such case.
These races can be easily provoked by inserting sleep at appropriate
places.
Signed-off-by: Mikulas Patocka <mpatocka(a)redhat.com>
---
WHATS_NEW_DM | 1 +
libdm/libdm-common.c | 10 +++++++---
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index b59a39e..6742ad4 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.83
==================================
+ Skip race errors when non-udev dmsetup build runs on udev-enabled system.
Skip error message when holders are not present in sysfs.
Use __linux__ instead of linux define to make libdevmapper.h C compliant.
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index 52be405..9a52f2e 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -966,7 +966,9 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
(void) dm_prepare_selinux_context(path, S_IFBLK);
old_mask = umask(0);
- if (mknod(path, S_IFBLK | mode, dev) < 0) {
+
+ /* The node may already have been created by udev. So ignore EEXIST. */
+ if (mknod(path, S_IFBLK | mode, dev) < 0 && errno != EEXIST) {
log_error("%s: mknod for %s failed: %s", path, dev_name, strerror(errno));
umask(old_mask);
(void) dm_prepare_selinux_context(NULL, 0);
@@ -998,7 +1000,8 @@ static int _rm_dev_node(const char *dev_name, int warn_if_udev_failed)
log_warn("Node %s was not removed by udev. "
"Falling back to direct node removal.", path);
- if (unlink(path) < 0) {
+ /* udev may already have deleted the node. Ignore ENOENT. */
+ if (unlink(path) < 0 && errno != ENOENT) {
log_error("Unable to unlink device node for '%s'", dev_name);
return 0;
}
@@ -1054,7 +1057,8 @@ static int _rename_dev_node(const char *old_name, const char *new_name,
"Falling back to direct node rename.",
oldpath, newpath);
- if (rename(oldpath, newpath) < 0) {
+ /* udev may already have renamed the node. Ignore ENOENT. */
+ if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
log_error("Unable to rename device node from '%s' to '%s'",
old_name, new_name);
return 0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3ac7f927e1e58708…
Commit: 3ac7f927e1e587089bbbbae04ecad1906af55485
Parent: efd1dc6bd3e38f9a98f67db28537c5655992c6f9
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Oct 17 11:12:02 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Oct 17 11:55:21 2013 +0200
libdm: do not show holders missing error
On older system this may not be present, so skip this error message.
---
WHATS_NEW_DM | 1 +
libdm/libdm-common.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index cf1cb18..b59a39e 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.83
==================================
+ Skip error message when holders are not present in sysfs.
Use __linux__ instead of linux define to make libdevmapper.h C compliant.
Version 1.02.82 - 4th October 2013
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index b66911c..52be405 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -1795,7 +1795,8 @@ int dm_device_has_holders(uint32_t major, uint32_t minor)
}
if (stat(sysfs_path, &st)) {
- log_sys_error("stat", sysfs_path);
+ if (errno != ENOENT)
+ log_sys_error("stat", sysfs_path);
return 0;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=efd1dc6bd3e38f9a…
Commit: efd1dc6bd3e38f9a98f67db28537c5655992c6f9
Parent: 3924a041ba3798c228749de1fc5491fd5411103b
Author: mpatocka(a)redhat.com <mpatocka(a)redhat.com>
AuthorDate: Thu Oct 17 11:14:07 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Oct 17 11:54:44 2013 +0200
headers: use __linux__ instead of linux
This file may be included by other programs, so it should be compliant
with the C standard.
* use __linux__ instead of linux - __linux__ is always defined, linux is
not defined when gcc runs in standard-compliant mode (with -std=c89 or
-std=c99) because the C standard doesn't allow polluting namespace
with arbitrary defines.
Signed-off-by: Mikulas Patocka <mpatocka(a)redhat.com>
---
WHATS_NEW_DM | 1 +
libdm/libdevmapper.h | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 6287fb4..cf1cb18 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.83
==================================
+ Use __linux__ instead of linux define to make libdevmapper.h C compliant.
Version 1.02.82 - 4th October 2013
==================================
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index aaf00b2..adfbb76 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -21,7 +21,7 @@
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef linux
+#ifdef __linux__
# include <linux/types.h>
#endif
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=73971e1e7b1164f4…
Commit: 73971e1e7b1164f4f7c677afc17aabbd09e11252
Parent: 7ab5f29a9cf94ef41e54e47f7f00898d44a700e3
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Oct 16 10:17:17 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Oct 16 10:54:59 2013 +0200
tests: test repairability of thin pool
Initial testing of thin pool's metadata with thin repairing tools.
Try to use tools from configuration settings, but allow them
to be overriden by settings of these variables:
LVM_TEST_THIN_CHECK_CMD,
LVM_TEST_THIN_DUMP_CMD,
LVM_TEST_THIN_REPAIR_CMD
FIXME: test reveals some more important bugs:
pvremove -ff also needs --yes
vgremove -ff doesn not remove metadata when there are no real LVs.
vgreduce is not able to reduce VG with pool without pool's PVs
---
test/Makefile.in | 8 ++-
test/shell/lvconvert-repair-thin.sh | 117 +++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+), 1 deletions(-)
diff --git a/test/Makefile.in b/test/Makefile.in
index 5685544..961eb9e 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -25,6 +25,9 @@ abs_top_builddir = "@abs_top_builddir@"
abs_top_srcdir = "@abs_top_srcdir@"
LVM_TEST_RESULTS ?= results
+LVM_TEST_THIN_DUMP_CMD ?= "@THIN_DUMP_CMD@"
+LVM_TEST_THIN_CHECK_CMD ?= "@THIN_CHECK_CMD@"
+LVM_TEST_THIN_REPAIR_CMD ?= "@THIN_REPAIR_CMD@"
SUBDIRS = api unit
SOURCES = lib/not.c lib/harness.c
@@ -58,12 +61,15 @@ help:
@echo " help Display callable targets."
@echo -e "\nSupported variables:"
@echo " LVM_TEST_DEVDIR Set to '/dev' to run on real /dev."
- @echo " LVM_TEST_DIR Where to create test files [TMPDIR]."
+ @echo " LVM_TEST_DIR Where to create test files [$(LVM_TEST_DIR)]."
@echo " LVM_TEST_LOCKING Normal (1), Cluster (3)."
@echo " LVM_TEST_LVMETAD Start lvmetad (1)."
@echo " LVM_TEST_NODEBUG Do not debug lvm commands."
@echo " LVM_TEST_PARALLEL May skip agresive wipe of LVMTEST resources."
@echo " LVM_TEST_RESULTS Where to create result files [results]."
+ @echo " LVM_TEST_THIN_CHECK_CMD Command for thin_check [$(LVM_TEST_THIN_CHECK_CMD)]."
+ @echo " LVM_TEST_THIN_DUMP_CMD Command for thin_dump [$(LVM_TEST_THIN_DUMP_CMD)]."
+ @echo " LVM_TEST_THIN_REPAIR_CMD Command for thin_repair [$(LVM_TEST_THIN_REPAIR_CMD)]."
@echo " LVM_TEST_UNLIMITED Set to get unlimited test log (>32MB)"
@echo " LVM_VERIFY_UDEV Default verify state for lvm.conf."
@echo " S Skip given test (regex)."
diff --git a/test/shell/lvconvert-repair-thin.sh b/test/shell/lvconvert-repair-thin.sh
new file mode 100644
index 0000000..f7687d4
--- /dev/null
+++ b/test/shell/lvconvert-repair-thin.sh
@@ -0,0 +1,117 @@
+#!/bin/sh
+
+# Copyright (C) 2013 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Test repairing of broken thin pool metadata
+
+. lib/test
+
+# Set tools from configuration (set by Makefile)
+# Allow user override to take tools from unusual places
+LVM_TEST_THIN_CHECK_CMD=${LVM_TEST_THIN_CHECK_CMD:-thin_check}
+LVM_TEST_THIN_DUMP_CMD=${LVM_TEST_THIN_DUMP_CMD:-thin_dump}
+LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD:-thin_repair}
+
+which mkfs.ext2 || skip
+
+# Maybe check also version of the tools here??
+which $LVM_TEST_THIN_CHECK_CMD || skip
+which $LVM_TEST_THIN_DUMP_CMD || skip
+which $LVM_TEST_THIN_REPAIR_CMD || skip
+
+#
+# Main
+#
+aux have_thin 1 0 0 || skip
+
+aux prepare_vg 4
+
+# Create LV
+lvcreate -T -L20 -V10 -n $lv1 $vg/pool "$dev1" "$dev2"
+lvcreate -T -V10 -n $lv2 $vg/pool
+
+mkfs.ext2 $DM_DEV_DIR/$vg/$lv1
+mkfs.ext2 $DM_DEV_DIR/$vg/$lv2
+
+lvcreate -L20 -n repair $vg
+lvcreate -L2 -n fixed $vg
+
+lvs -a -o+seg_pe_ranges $vg
+#aux error_dev "$dev2" 2050:1
+
+# Make some repairable metadata damage??
+vgchange -an $vg
+
+lvconvert --repair $vg/pool
+
+lvs -a $vg
+
+# Test swapping - swap out thin-pool's metadata with our repair volume
+lvconvert -y -f --poolmetadata $vg/repair --thinpool $vg/pool
+
+lvchange -aey $vg/repair $vg/fixed
+
+#dd if=$DM_DEV_DIR/$vg/repair of=back bs=1M
+
+# Make some 'repairable' damage??
+dd if=/dev/zero of=$DM_DEV_DIR/$vg/repair bs=1 seek=40960 count=1
+
+#dd if=$DM_DEV_DIR/$vg/repair of=back_trashed bs=1M
+#not vgchange -ay $vg
+
+#lvconvert --repair $vg/pool
+
+# Using now SHOULD - since thin tools currently do not seem to work
+should not $THIN_CHECK $DM_DEV_DIR/$vg/repair
+
+should not $LVM_TEST_THIN_DUMP_CMD $DM_DEV_DIR/$vg/repair | tee dump
+
+should $LVM_TEST_THIN_REPAIR_CMD -i $DM_DEV_DIR/$vg/repair -o $DM_DEV_DIR/$vg/fixed
+
+should $THIN_CHECK $DM_DEV_DIR/$vg/fixed
+
+# Swap repaired metadata back
+lvconvert -y -f --poolmetadata $vg/fixed --thinpool $vg/pool
+lvs -a $vg
+
+# Activate pool - this should now work
+should vgchange -ay $vg
+
+lvs -a -o+devices $vg
+dmsetup table
+dmsetup info -c
+dmsetup ls --tree
+
+# Currently in troubles - we can't remove thin volume from broken pool
+lvchange -an $vg/repair
+lvchange -an $vg/fixed
+lvchange -an $vg/pool_tmeta0
+dmsetup remove $vg-pool_tdata
+dmsetup remove $vg-pool_tmeta
+
+
+dmsetup table
+
+# FIXME: needs also --yes with double force
+pvremove --yes -ff "$dev1"
+pvremove --yes -ff "$dev2"
+
+# FIXME: pv1 & pv2 are removed so pv3 & pv4 have no real LVs,
+# yet vgremove is refusing to do its jobs and suggest --partial??
+should vgremove -ff $vg
+
+# FIXME: stressing even more - there are no pool PV, we do not pass...
+should vgreduce --removemissing -f $vg
+should vgremove -ff $vg
+
+# Let's do a final forced cleanup
+pvremove --yes -ff "$dev3"
+pvremove --yes -ff "$dev4"