From: Manuel Bouyer <bouyer@netbsd.org>
To: xen-devel@lists.xenproject.org
Cc: Manuel Bouyer <bouyer@netbsd.org>,
Ian Jackson <iwj@xenproject.org>, Wei Liu <wl@xen.org>
Subject: [PATCH v2] NetBSD hotplug: Introduce locking functions
Date: Tue, 26 Jan 2021 23:47:48 +0100 [thread overview]
Message-ID: <20210126224800.1246-2-bouyer@netbsd.org> (raw)
In-Reply-To: <20210126224800.1246-1-bouyer@netbsd.org>
On NetBSD, some block device configuration requires serialisation.
Introcuce locking functions (derived from the Linux version), and use them
in the block script where appropriate.
Signed-off-by: Manuel Bouyer <bouyer@netbsd.org>
---
tools/hotplug/NetBSD/Makefile | 1 +
tools/hotplug/NetBSD/block | 5 +-
tools/hotplug/NetBSD/locking.sh | 121 ++++++++++++++++++++++++++++++++
3 files changed, 126 insertions(+), 1 deletion(-)
create mode 100644 tools/hotplug/NetBSD/locking.sh
diff --git a/tools/hotplug/NetBSD/Makefile b/tools/hotplug/NetBSD/Makefile
index 6926885ab8..114b223207 100644
--- a/tools/hotplug/NetBSD/Makefile
+++ b/tools/hotplug/NetBSD/Makefile
@@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
# Xen script dir and scripts to go there.
XEN_SCRIPTS =
+XEN_SCRIPTS += locking.sh
XEN_SCRIPTS += block
XEN_SCRIPTS += vif-bridge
XEN_SCRIPTS += vif-ip
diff --git a/tools/hotplug/NetBSD/block b/tools/hotplug/NetBSD/block
index c8b31a7b2b..eb5e80d640 100644
--- a/tools/hotplug/NetBSD/block
+++ b/tools/hotplug/NetBSD/block
@@ -5,6 +5,7 @@
DIR=$(dirname "$0")
. "${DIR}/hotplugpath.sh"
+. "${DIR}/locking.sh"
PATH=${bindir}:${sbindir}:${LIBEXEC_BIN}:/bin:/usr/bin:/sbin:/usr/sbin
export PATH
@@ -52,6 +53,7 @@ case $xstatus in
available_disks="$available_disks $disk"
eval $disk=free
done
+ claim_lock block
# Mark the used vnd(4) devices as ``used''.
for disk in `sysctl hw.disknames`; do
case $disk in
@@ -67,6 +69,7 @@ case $xstatus in
break
fi
done
+ release_lock block
if [ x$device = x ] ; then
error "no available vnd device"
fi
@@ -76,7 +79,7 @@ case $xstatus in
device=$xparams
;;
esac
- physical_device=$(stat -f '%r' "$device")
+ physical_device=$(stat -L -f '%r' "$device")
xenstore-write $xpath/physical-device $physical_device
xenstore-write $xpath/hotplug-status connected
exit 0
diff --git a/tools/hotplug/NetBSD/locking.sh b/tools/hotplug/NetBSD/locking.sh
new file mode 100644
index 0000000000..2098d0e3ab
--- /dev/null
+++ b/tools/hotplug/NetBSD/locking.sh
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+# Copyright (c) 2007 Red Hat
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Serialisation
+#
+
+LOCK_BASEDIR=$XEN_LOCK_DIR/xen-hotplug
+
+_setlockfd()
+{
+ _lockfd=9
+ _lockfile="$LOCK_BASEDIR/$1"
+}
+
+
+claim_lock()
+{
+ mkdir -p "$LOCK_BASEDIR"
+ _setlockfd $1
+ # The locking strategy is identical to that from with-lock-ex(1)
+ # from chiark-utils, except using flock. It has the benefit of
+ # it being possible to safely remove the lockfile when done.
+ # See below for a correctness proof.
+ local stat
+ while true; do
+ eval "exec $_lockfd<> $_lockfile"
+ # we can't flock $_lockfd here, as the shell closes it on exec.
+ # Workaround by redirecting to 0 for the command, and flock 0 instead.
+ flock -v -x 0 0<& $_lockfd|| exit 1
+ local file_stat
+ local fd_stat
+ if fd_stat=$(stat -f '%d.%i' 0<&$_lockfd 2>/dev/null) && file_stat=$(stat -f '%d.%i' $_lockfile 2>/dev/null )
+ then
+ if [ "$fd_stat" = "$file_stat" ] ; then break; fi
+ fi
+ # Some versions of bash appear to be buggy if the same
+ # $_lockfile is opened repeatedly. Close the current fd here.
+ eval "exec $_lockfd<&-"
+ done
+}
+
+
+release_lock()
+{
+ _setlockfd $1
+ rm "$_lockfile"
+}
+
+# Protocol and correctness proof:
+#
+# * The lock is owned not by a process but by an open-file (informally
+# an fd). Any process with an fd onto this open-file is a
+# lockholder and may perform the various operations; such a process
+# should only do so when its co-lockholder processes expect. Ie, we
+# will treat all processes holding fds onto the open-file as acting
+# in concert and not distinguish between them.
+#
+# * You are a lockholder if
+# - You have an fd onto an open-file which
+# currently holds an exclusive flock lock on its inum
+# - and that inum is currently linked at the lockfile path
+#
+# * The rules are:
+# - No-one but a lockholder may unlink the lockfile path
+# (or otherwise cause it to stop referring to a file it
+# refers to).
+# - Anyone may open the lockfile with O_CREAT
+#
+# * The protocol for locking is:
+# - Open the file (O_CREAT)
+# - flock it
+# - fstat the fd you have open
+# - stat the lockfile path
+# - if both are equal you have the lock, otherwise try again.
+#
+# * Informal proof of exclusivity:
+# - No two open-files can hold an fcntl lock onto the same file
+# at the same time
+# - No two files can have the same name at the same time
+#
+# * Informal proof of correctness of locking protocol:
+# - After you call flock successfully no-one other than you
+# (someone with the same open-file) can stop you having
+# that flock lock.
+# - Obviously the inum you get from the fstat is fixed
+# - At the point where you call stat there are two
+# possibilities:
+# (i) the lockfile path referred to some other inum
+# in which case you have failed
+# (ii) the lockfile path referred to the same file
+# in which case at that point you were the
+# lockholder (by definition).
+#
+# * Informal proof that no-one else can steal the lock:
+# - After you call flock successfully no-one other than you
+# can stop you having that flock lock
+# - No-one other than the lockholder is permitted to stop
+# the path referring to a particular inum. So if you
+# hold the lock then only you are allowed to stop the
+# path referring to the file whose flock you hold; so
+# it will continue to refer to that file.
+# That's both the conditions for being the lockholder.
+#
+# Thus once you hold the lock at any instant, you will
+# continue to do so until you voluntarily stop doing so
+# (eg by unlinking the lockfile or closing the fd).
--
2.29.2
next prev parent reply other threads:[~2021-01-26 22:48 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-26 22:47 [PATCH v2] Fix error: array subscript has type 'char' Manuel Bouyer
2021-01-26 22:47 ` Manuel Bouyer [this message]
2021-01-26 22:47 ` [PATCH v2] NetBSD hotplug: fix block unconfigure on destroy Manuel Bouyer
2021-01-28 11:45 ` Roger Pau Monné
2021-01-29 11:00 ` Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] NetBSD: use system-provided headers Manuel Bouyer
2021-01-28 11:21 ` Roger Pau Monné
2021-01-29 10:57 ` Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/call: fix build on NetBSD Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/foreignmemory: Implement " Manuel Bouyer
2021-01-27 20:15 ` Andrew Cooper
2021-01-28 10:48 ` Roger Pau Monné
2021-01-28 10:52 ` Andrew Cooper
2021-01-28 11:42 ` Andrew Cooper
2021-01-29 10:51 ` Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/gnttab: implement " Manuel Bouyer
2021-01-28 11:14 ` Roger Pau Monné
2021-01-26 22:47 ` [PATCH v2] libs/light: Switch NetBSD to QEMU_XEN Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/light: fix tv_sec printf format Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/light: fix uuid on NetBSD Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/light: make it build without setresuid() Manuel Bouyer
2021-01-28 11:06 ` Ian Jackson
2021-01-29 22:51 ` Andrew Cooper
2021-01-29 23:01 ` Manuel Bouyer
2021-01-29 23:05 ` Andrew Cooper
2021-01-29 23:16 ` Manuel Bouyer
2021-01-30 18:28 ` Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/light: pass some infos to qemu Manuel Bouyer
2021-01-28 11:08 ` Roger Pau Monné
2021-01-29 10:46 ` Manuel Bouyer
2021-01-29 14:52 ` Roger Pau Monné
2021-01-30 23:07 ` Manuel Bouyer
2021-01-30 11:50 ` Manuel Bouyer
2021-02-01 8:06 ` Roger Pau Monné
2021-02-01 9:39 ` Manuel Bouyer
2021-02-01 10:54 ` Roger Pau Monné
2021-02-01 11:21 ` Manuel Bouyer
2021-01-26 22:47 ` [PATCH v2] libs/store: make build without PTHREAD_STACK_MIN Manuel Bouyer
2021-01-28 10:57 ` Roger Pau Monné
2021-01-28 11:08 ` Andrew Cooper
2021-01-29 10:43 ` Manuel Bouyer
2021-01-26 22:48 ` [PATCH v2] xenpmd.c: use dynamic allocation Manuel Bouyer
2021-01-28 10:34 ` Roger Pau Monné
2021-01-27 19:30 ` [PATCH v2] Fix error: array subscript has type 'char' Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210126224800.1246-2-bouyer@netbsd.org \
--to=bouyer@netbsd.org \
--cc=iwj@xenproject.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).