From a387127171e5e8d67de006400fe6afe19c82d496 Mon Sep 17 00:00:00 2001 From: bad Date: Mon, 4 Apr 2016 14:45:12 +0000 Subject: Guard the NetBSD block device hotplug script against concurrent execution. xl(1) runs the hotplug scripts in parallel. This causes failures when the next free vnd device is selected. Locking modeled after the Linux block hotplug script. --- sysutils/xentools45/Makefile | 5 +- sysutils/xentools45/PLIST | 3 +- sysutils/xentools45/distinfo | 5 +- sysutils/xentools45/files/locking.sh | 72 ++++++++++++++++++++++ .../patches/patch-hotplug_NetBSD_Makefile | 18 ++++-- .../xentools45/patches/patch-hotplug_NetBSD_block | 59 ++++++++++++++++++ 6 files changed, 151 insertions(+), 11 deletions(-) create mode 100644 sysutils/xentools45/files/locking.sh create mode 100644 sysutils/xentools45/patches/patch-hotplug_NetBSD_block (limited to 'sysutils') diff --git a/sysutils/xentools45/Makefile b/sysutils/xentools45/Makefile index 67d29776234..d284aa2ebd1 100644 --- a/sysutils/xentools45/Makefile +++ b/sysutils/xentools45/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.27 2016/04/04 14:35:12 bad Exp $ +# $NetBSD: Makefile,v 1.28 2016/04/04 14:45:12 bad Exp $ VERSION= 4.5.2 PKGREVISION= 1 @@ -112,7 +112,7 @@ SUBST_FILES.conf+= libxl/xl_cmdtable.c SUBST_FILES.conf+= ../docs/misc/xl-disk-configuration.txt SUBST_SED.conf= -e "s,@XENDCONFDIR@,${PKG_SYSCONFDIR},g" -XEND_SCRIPTS= block vif-bridge vif-ip qemu-ifup hotplugpath.sh +XEND_SCRIPTS= block vif-bridge vif-ip qemu-ifup hotplugpath.sh locking.sh SUBST_CLASSES.NetBSD+= proc SUBST_STAGE.proc= pre-configure @@ -162,6 +162,7 @@ pre-build: .for s in ${BLKTAP_FILES} ${CP} -f ${FILESDIR}/${s} ${WRKSRC}/blktap/drivers/ .endfor + ${CP} -f ${FILESDIR}/locking.sh ${WRKSRC}/hotplug/NetBSD/ ${SED} -e "s,@XENDCONFDIR@,${PKG_SYSCONFDIR},g" \ ${XENTOP}/docs/man/xenstore-chmod.pod.1 |\ pod2man >${WRKDIR}/xenstore-chmod.1 diff --git a/sysutils/xentools45/PLIST b/sysutils/xentools45/PLIST index 6bb18a2e0b0..f269e2d85ba 100644 --- a/sysutils/xentools45/PLIST +++ b/sysutils/xentools45/PLIST @@ -1,4 +1,4 @@ -@comment $NetBSD: PLIST,v 1.4 2015/12/31 13:27:10 jnemeth Exp $ +@comment $NetBSD: PLIST,v 1.5 2016/04/04 14:45:12 bad Exp $ bin/pygrub bin/qemu-img-xen bin/xen-detect @@ -273,6 +273,7 @@ share/examples/xen/cpupool share/examples/xen/oxenstored.conf share/examples/xen/scripts/block share/examples/xen/scripts/hotplugpath.sh +share/examples/xen/scripts/locking.sh share/examples/xen/scripts/qemu-ifup share/examples/xen/scripts/vif-bridge share/examples/xen/scripts/vif-ip diff --git a/sysutils/xentools45/distinfo b/sysutils/xentools45/distinfo index 8b6f233da34..4cee5a47ac9 100644 --- a/sysutils/xentools45/distinfo +++ b/sysutils/xentools45/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.18 2016/04/04 14:40:57 bad Exp $ +$NetBSD: distinfo,v 1.19 2016/04/04 14:45:12 bad Exp $ SHA1 (ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz) = fecadf952821e830ce1a1d19655288eef8488f88 RMD160 (ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz) = 539bfa12db7054228250d6dd380bbf96c1a040f8 @@ -30,7 +30,8 @@ SHA1 (patch-examples_Makefile) = 5fe7bb876d254cf0c4f774ed0f08dcaea5b355ff SHA1 (patch-firmware_etherboot_Makefile) = f55e14948b7191e533a82b8fc3575f1052f23c45 SHA1 (patch-firmware_etherboot_patches_series) = 2fa1342c78094c6dd5d60a07c236c4a1c0599fc4 SHA1 (patch-firmware_hvmloader_Makefile) = bc5e81ddfc5e95887c2af4bb32eced9c5748b3c6 -SHA1 (patch-hotplug_NetBSD_Makefile) = 5afbf8dc910c93fcc0904ba09164a441704e31a2 +SHA1 (patch-hotplug_NetBSD_Makefile) = 6f6ec768b595c332a8757437a64509c0370e52da +SHA1 (patch-hotplug_NetBSD_block) = 6f56f2c5927686ac128cf1913b419be20ce2e99d SHA1 (patch-hotplug_NetBSD_vif-bridge) = ac4cc7446715330b504b8cce8cbd47c8035cf33c SHA1 (patch-hotplug_NetBSD_vif-ip) = ed23b0c16d87bd05230399d921e28860c5857b01 SHA1 (patch-hotplug_common_Makefile) = 1c8af96a3d0d1d5e9c168b1eb75fabb3e2164a19 diff --git a/sysutils/xentools45/files/locking.sh b/sysutils/xentools45/files/locking.sh new file mode 100644 index 00000000000..88257f62b7b --- /dev/null +++ b/sysutils/xentools45/files/locking.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Copyright (c) 2016, Christoph Badura. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +LOCK_BASEDIR="$XEN_LOCK_DIR/xen-hotplug" + +_lockfd=9 +_have_lock=0 # lock not taken yet. + +SHLOCK="shlock ${_shlock_debug-}" + +_lock_set_vars() { + _lockfile="$LOCK_BASEDIR/$1.lock" + _lockfifo="$LOCK_BASEDIR/$1.fifo" +} + +_lock_init() { + mkdir -p "$LOCK_BASEDIR" 2>/dev/null || true + mkfifo $_lockfifo 2>/dev/null || true +} + +# +# use a named pipe as condition variable +# opening for read-only blocks when there's no writer. +# opening for read-write never blocks but unblocks any waiting readers. +# +_lock_wait_cv() { + eval "exec $_lockfd< $_lockfifo ; exec $_lockfd<&-" +} +_lock_signal_cv() { + eval "exec $_lockfd<> $_lockfifo ; exec $_lockfd<&-" +} + +claim_lock() { + _lock_set_vars $1 + _lock_init + until $SHLOCK -f $_lockfile -p $$; do + _lock_wait_cv + done + _have_lock=1 + # be sure to release the lock when the shell exits + trap "release_lock $1" 0 1 2 15 +} + +release_lock() { + _lock_set_vars $1 + [ "$_have_lock" != 0 -a -f $_lockfile ] && rm $_lockfile + _have_lock=0 + _lock_signal_cv; +} diff --git a/sysutils/xentools45/patches/patch-hotplug_NetBSD_Makefile b/sysutils/xentools45/patches/patch-hotplug_NetBSD_Makefile index ae90341de43..3efd8f79a6b 100644 --- a/sysutils/xentools45/patches/patch-hotplug_NetBSD_Makefile +++ b/sysutils/xentools45/patches/patch-hotplug_NetBSD_Makefile @@ -1,8 +1,14 @@ -$NetBSD: patch-hotplug_NetBSD_Makefile,v 1.1 2015/01/20 16:42:13 bouyer Exp $ +$NetBSD: patch-hotplug_NetBSD_Makefile,v 1.2 2016/04/04 14:45:12 bad Exp $ ---- hotplug/NetBSD/Makefile.orig 2015-01-12 17:53:24.000000000 +0100 -+++ hotplug/NetBSD/Makefile 2015-01-19 14:18:22.000000000 +0100 -@@ -8,7 +8,7 @@ +--- hotplug/NetBSD/Makefile.orig 2015-11-03 10:11:18.000000000 +0100 ++++ hotplug/NetBSD/Makefile 2016-03-25 15:21:34.000000000 +0100 +@@ -3,12 +3,13 @@ + + # 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 XEN_SCRIPT_DATA = @@ -11,7 +17,7 @@ $NetBSD: patch-hotplug_NetBSD_Makefile,v 1.1 2015/01/20 16:42:13 bouyer Exp $ .PHONY: all all: -@@ -21,10 +21,11 @@ +@@ -21,10 +22,11 @@ .PHONY: install-scripts install-scripts: @@ -25,7 +31,7 @@ $NetBSD: patch-hotplug_NetBSD_Makefile,v 1.1 2015/01/20 16:42:13 bouyer Exp $ done set -e; for i in $(XEN_SCRIPT_DATA); \ do \ -@@ -33,12 +34,12 @@ +@@ -33,12 +35,12 @@ .PHONY: install-rcd install-rcd: diff --git a/sysutils/xentools45/patches/patch-hotplug_NetBSD_block b/sysutils/xentools45/patches/patch-hotplug_NetBSD_block new file mode 100644 index 00000000000..c2f575fe458 --- /dev/null +++ b/sysutils/xentools45/patches/patch-hotplug_NetBSD_block @@ -0,0 +1,59 @@ +$NetBSD: patch-hotplug_NetBSD_block,v 1.1 2016/04/04 14:45:12 bad Exp $ + +Lock the block script to avoid races during vnd configuration. + +--- hotplug/NetBSD/block.orig 2015-11-03 10:11:18.000000000 +0100 ++++ hotplug/NetBSD/block 2016-03-25 14:37:34.000000000 +0100 +@@ -6,6 +6,7 @@ + + DIR=$(dirname "$0") + . "${DIR}/hotplugpath.sh" ++. "${DIR}/locking.sh" + + PATH=${BINDIR}:${SBINDIR}:${LIBEXEC_BIN}:/bin:/usr/bin:/sbin:/usr/sbin + export PATH +@@ -14,6 +15,7 @@ + echo "$@" >&2 + xenstore-write $xpath/hotplug-status error \ + $xpath/hotplug-error "$@" ++ release_lock block + exit 1 + } + +@@ -37,10 +39,12 @@ + # device removed + case $xtype in + file) ++ claim_lock block + vnd=$(xenstore-read "$xpath/vnd" || echo none) + if [ $vnd != none ]; then + vnconfig -u $vnd + fi ++ release_lock block + ;; + phy) + ;; +@@ -52,6 +56,7 @@ + exit 0 + ;; + 2) ++ claim_lock block + case $xtype in + file) + # Store the list of available vnd(4) devices in +@@ -78,6 +83,7 @@ + fi + done + if [ x$device = x ] ; then ++ release_lock block + error "no available vnd device" + fi + xenstore-write $xpath/vnd $device +@@ -89,6 +95,7 @@ + physical_device=$(stat -f '%r' "$device") + xenstore-write $xpath/physical-device $physical_device + xenstore-write $xpath/hotplug-status connected ++ release_lock block + exit 0 + ;; + *) -- cgit v1.2.3