From e4b7c72b3ab2274cc5572032b6e17210e471d6a3 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Mon, 31 Jan 2011 19:52:40 +0000 Subject: [PATCH] Fix udev synchronization for no-locking mode Instead of implicitly syncing udev operation in clustered and file locking code - call synchronization directly in lock_vol() when the operation unlocks VG The problem is missing implicit fs_unlock() in the no_locking code. This is used with --sysinit on read-only filesystem locking dir. In this case vgchange -ay could exit before all udev nodes are properly synchronised and may cause problems with accessing such node right after vgchange --sysinint command is finished. Add test case for vgchange --sysinit. --- WHATS_NEW | 1 + daemons/clvmd/clvmd-command.c | 1 - lib/locking/file_locking.c | 1 - lib/locking/locking.c | 4 +++ test/t-vgchange-sysinit.sh | 50 +++++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100755 test/t-vgchange-sysinit.sh diff --git a/WHATS_NEW b/WHATS_NEW index d02dd523c..8e6efee26 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.83 - =================================== + Fix udev synchronization with no-locking --sysinit (2.02.80). Updating man pages for pvcreate, pvremove, pvresize, pvscan. Avoid rebuilding of uuid validation table. Always use O_DIRECT when opening block devices to check for partitioning. diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c index 387270213..6d0dee4ad 100644 --- a/daemons/clvmd/clvmd-command.c +++ b/daemons/clvmd/clvmd-command.c @@ -217,7 +217,6 @@ static int lock_vg(struct local_client *client) if (lkid == 0) return EINVAL; - lvm_do_fs_unlock(); /* Wait for devices */ status = sync_unlock(lockname, lkid); if (status) status = errno; diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 0c8bbed4f..68b0420b8 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -215,7 +215,6 @@ static int _lock_file(const char *file, uint32_t flags) state = 'W'; break; case LCK_UNLOCK: - fs_unlock(); /* Wait until devices are available */ return _release_lock(file, 1); default: log_error("Unrecognised lock type: %d", flags & LCK_TYPE_MASK); diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 645f25d57..c92361044 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -442,6 +442,10 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags) /* If LVM1 driver knows about the VG, it can't be accessed. */ if (!check_lvm1_vg_inactive(cmd, vol)) return_0; + + /* Before unlocking VG wait until devices are available. */ + if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK) + sync_local_dev_names(cmd); break; case LCK_LV: /* All LV locks are non-blocking. */ diff --git a/test/t-vgchange-sysinit.sh b/test/t-vgchange-sysinit.sh new file mode 100755 index 000000000..c89882f69 --- /dev/null +++ b/test/t-vgchange-sysinit.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright (C) 2011 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 + +. lib/test + +which mkfs.ext3 || exit 200 + +aux prepare_pvs 2 8 + +var_lock="$DM_DEV_DIR/$vg1/$lv1" +# keep in sync with aux configured lockingdir +mount_dir="$TESTDIR/var/lock/lvm" + +cleanup_mounted_and_teardown() +{ + umount $mount_dir || true + aux teardown +} + +vgcreate -c n $vg1 $dev1 +vgcreate -c n $vg2 $dev2 + +lvcreate -l 1 -n $lv2 $vg2 +vgchange -an $vg2 + +lvcreate -n $lv1 -l 100%FREE $vg1 +mkfs.ext3 -b4096 -j $var_lock + +trap 'cleanup_mounted_and_teardown' EXIT +mount -n -r $var_lock $mount_dir + +# locking must fail on read-only filesystem +not vgchange -ay $vg2 + +# no-locking with --sysinit +vgchange --sysinit -ay $vg2 +test -b "$DM_DEV_DIR/$vg2/$lv2" + +vgchange --sysinit -an $vg2 +test ! -b "$DM_DEV_DIR/$vg2/$lv2" + +vgchange --ignorelockingfailure -ay $vg2 -- 2.43.5