xen/hotplug-Linux-block-performance-fix.patch
Charles Arnold 047483513a - Update to Xen Version 4.6.0
xen-4.6.0-testing-src.tar.bz2
  mini-os.tar.bz2
  blktap2-no-uninit.patch
  stubdom-have-iovec.patch
- Renamed
  xsa149.patch to CVE-2015-7969-xsa149.patch
- Dropped patches now contained in tarball or unnecessary
  xen-4.5.2-testing-src.tar.bz2
  54c2553c-grant-table-use-uint16_t-consistently-for-offset-and-length.patch
  54ca33bc-grant-table-refactor-grant-copy-to-reduce-duplicate-code.patch
  54ca340e-grant-table-defer-releasing-pages-acquired-in-a-grant-copy.patch
  54f4985f-libxl-fix-libvirtd-double-free.patch
  55103616-vm-assist-prepare-for-discontiguous-used-bit-numbers.patch
  551ac326-xentop-add-support-for-qdisk.patch
  552d0fd2-x86-hvm-don-t-include-asm-spinlock-h.patch
  552d0fe8-x86-mtrr-include-asm-atomic.h.patch
  552d293b-x86-vMSI-X-honor-all-mask-requests.patch
  552d2966-x86-vMSI-X-add-valid-bits-for-read-acceleration.patch
  5537a4d8-libxl-use-DEBUG-log-level-instead-of-INFO.patch
  5548e903-domctl-don-t-truncate-XEN_DOMCTL_max_mem-requests.patch
  5548e95d-x86-allow-to-suppress-M2P-user-mode-exposure.patch
  554c7aee-x86-provide-arch_fetch_and_add.patch
  554c7b00-arm-provide-arch_fetch_and_add.patch
  554cc211-libxl-add-qxl.patch 55534b0a-x86-provide-add_sized.patch
  55534b25-arm-provide-add_sized.patch
  5555a4f8-use-ticket-locks-for-spin-locks.patch
  5555a5b9-x86-arm-remove-asm-spinlock-h.patch
  5555a8ec-introduce-non-contiguous-allocation.patch
  556d973f-unmodified-drivers-tolerate-IRQF_DISABLED-being-undefined.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=387
2015-11-11 17:04:52 +00:00

205 lines
6.4 KiB
Diff

Reference: bsc#941074
During the attachment of a loopback mounted image file, the mode of all
curent instances of this device already attached to other domains must be
checked. This requires finding all loopback devices pointing to the inode
of the shared image file, and then comparing the major and minor number of
these devices to the major and minor number of every vbd device found in the
xenstore database.
Prior to this patch, the entire xenstore database is walked for every instance
of every loopback device pointing to the same shared image file. This process
causes the block attachment process to becomes exponentially slower with every
additional attachment of a shared image.
Rather than scanning all of xenstore for every instance of a shared loopback
device, this patch creates a list of the major and minor numbers from all
matching loopback devices. After generating this list, Xenstore is walked
once, and major and minor numbers from every vbd are checked against the list.
If a match is found, the mode of that vbd is checked for compatibility with
the mode of the device being attached.
Signed-off-by: Mike Latimer <mlatimer@xxxxxxxx>
---
tools/hotplug/Linux/block | 89 ++++++++++++++++++++++++++++++-----------------
1 file changed, 57 insertions(+), 32 deletions(-)
Index: xen-4.6.0-testing/tools/hotplug/Linux/block
===================================================================
--- xen-4.6.0-testing.orig/tools/hotplug/Linux/block
+++ xen-4.6.0-testing/tools/hotplug/Linux/block
@@ -38,7 +38,7 @@ find_free_loopback_dev() {
}
##
-# check_sharing device mode
+# check_sharing devtype device mode [inode]
#
# Check whether the device requested is already in use. To use the device in
# read-only mode, it may be in use in read-only mode, but may not be in use in
@@ -47,19 +47,44 @@ find_free_loopback_dev() {
#
# Prints one of
#
-# 'local': the device may not be used because it is mounted in the current
-# (i.e. the privileged domain) in a way incompatible with the
-# requested mode;
-# 'guest': the device may not be used because it already mounted by a guest
-# in a way incompatible with the requested mode; or
-# 'ok': the device may be used.
+# 'local $d': the device ($d) may not be used because it is mounted in the
+# current (i.e. the privileged domain) in a way incompatible
+# with the requested mode;
+# 'guest $d': the device may not be used because it is already mounted
+# through device $d by a guest in a way incompatible with the
+# requested mode; or
+# 'ok': the device may be used.
#
check_sharing()
{
- local dev="$1"
- local mode="$2"
+ local devtype=$1
+ local dev="$2"
+ local mode="$3"
+ local devmm=","
+
+ if [ "$devtype" = "file" ];
+ then
+ local inode="$4"
+
+ shared_list=$(losetup -a |
+ sed -n -e "s@^\([^:]\+\)\(:[[:blank:]]\[0*${dev}\]:${inode}[[:blank:]](.*)\)@\1@p" )
+ for dev in $shared_list
+ do
+ if [ -n "$dev" ]
+ then
+ devmm="${devmm}$(device_major_minor $dev),"
+ fi
+ done
+ # if $devmm is unchanged, file being checked is not a shared loopback device
+ if [ "$devmm" = "," ];
+ then
+ echo 'ok'
+ return
+ fi
+ else
+ devmm=${devmm}$(device_major_minor "$dev")","
+ fi
- local devmm=$(device_major_minor "$dev")
local file
if [ "$mode" = 'w' ]
@@ -75,9 +100,10 @@ check_sharing()
then
local d=$(device_major_minor "$file")
- if [ "$d" = "$devmm" ]
+ # checking for $d in $devmm is best through the [[...]] bashism
+ if [[ "$devmm" == *",$d,"* ]]
then
- echo 'local'
+ echo "local $d"
return
fi
fi
@@ -90,13 +116,14 @@ check_sharing()
do
d=$(xenstore_read_default "$base_path/$dom/$dev/physical-device" "")
- if [ "$d" = "$devmm" ]
+ # checking for $d in $devmm is best through the [[...]] bashism
+ if [ -n "$d" ] && [[ "$devmm" == *",$d,"* ]]
then
if [ "$mode" = 'w' ]
then
if ! same_vm $dom
then
- echo 'guest'
+ echo "guest $d"
return
fi
else
@@ -107,7 +134,7 @@ check_sharing()
then
if ! same_vm $dom
then
- echo 'guest'
+ echo "guest $d"
return
fi
fi
@@ -129,6 +156,7 @@ check_device_sharing()
{
local dev="$1"
local mode=$(canonicalise_mode "$2")
+ local type="device"
local result
if [ "x$mode" = 'x!' ]
@@ -136,33 +164,38 @@ check_device_sharing()
return 0
fi
- result=$(check_sharing "$dev" "$mode")
+ result=$(check_sharing "$type" "$dev" "$mode")
if [ "$result" != 'ok' ]
then
- do_ebusy "Device $dev is mounted " "$mode" "$result"
+ do_ebusy "Device $dev is mounted " "$mode" "${result%% *}"
fi
}
##
-# check_device_sharing file dev mode
+# check_device_sharing file dev mode inode
#
-# Perform the sharing check for the given file mounted through the given
-# loopback interface, in the given mode.
+# Perform the sharing check for the given file, with its corresponding
+# device, inode and mode. As the file can be mounted multiple times,
+# the inode is passed through to check_sharing for all instances to be
+# checked.
#
check_file_sharing()
{
local file="$1"
local dev="$2"
local mode="$3"
+ local inode="$4"
+ local type="file"
+ local result
- result=$(check_sharing "$dev" "$mode")
+ result=$(check_sharing "$type" "$dev" "$mode" "$inode")
if [ "$result" != 'ok' ]
then
- do_ebusy "File $file is loopback-mounted through $dev,
-which is mounted " "$mode" "$result"
+ do_ebusy "File $file is loopback-mounted through ${result#* },
+which is mounted " "$mode" "${result%% *}"
fi
}
@@ -281,15 +314,7 @@ mount it read-write in a guest domain."
fatal "Unable to lookup $file: dev: $dev inode: $inode"
fi
- shared_list=$(losetup -a |
- sed -n -e "s@^\([^:]\+\)\(:[[:blank:]]\[0*${dev}\]:${inode}[[:blank:]](.*)\)@\1@p" )
- for dev in $shared_list
- do
- if [ -n "$dev" ]
- then
- check_file_sharing "$file" "$dev" "$mode"
- fi
- done
+ check_file_sharing "$file" "$dev" "$mode" "$inode"
fi
loopdev=$(losetup -f 2>/dev/null || find_free_loopback_dev)