1#!/usr/bin/env bash 2# group: rw quick 3# 4# Test image locking for POSIX locks 5# 6# Copyright 2017 Red Hat, Inc. 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program. If not, see <http://www.gnu.org/licenses/>. 20# 21 22# creator 23owner=famz@redhat.com 24 25seq="$(basename $0)" 26echo "QA output created by $seq" 27 28tmp=/tmp/$$ 29status=1 # failure is the default! 30 31_cleanup() 32{ 33 _cleanup_test_img 34 _rm_test_img "$TEST_IMG.overlay" 35 rm -f "$SOCK_DIR/nbd.socket" 36} 37trap "_cleanup; exit \$status" 0 1 2 3 15 38 39# get standard environment, filters and checks 40. ./common.rc 41. ./common.filter 42. ./common.qemu 43 44_supported_fmt qcow2 45_supported_proto file 46 47size=32M 48 49case "$QEMU_DEFAULT_MACHINE" in 50 s390-ccw-virtio) 51 virtioblk=virtio-blk-ccw 52 ;; 53 *) 54 virtioblk=virtio-blk-pci 55 ;; 56esac 57 58_make_test_img $size 59 60echo "Starting QEMU" 61_launch_qemu -drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \ 62 -device $virtioblk,drive=drive0 63 64echo 65echo "Starting a second QEMU using the same image should fail" 66echo 'quit' | $QEMU -nographic -monitor stdio \ 67 -drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \ 68 -device $virtioblk,drive=drive0 2>&1 | _filter_testdir 2>&1 | 69 _filter_qemu | 70 sed -e '/falling back to POSIX file/d' \ 71 -e '/locks can be lost unexpectedly/d' 72 73_cleanup_qemu 74 75echo 76echo '=== Testing reopen ===' 77echo 78 79# This tests that reopening does not unshare any permissions it should 80# not unshare 81# (There was a bug where reopening shared exactly the opposite of the 82# permissions it was supposed to share) 83 84_launch_qemu 85 86_send_qemu_cmd $QEMU_HANDLE \ 87 "{'execute': 'qmp_capabilities'}" \ 88 'return' 89 90# Open the image without any format layer (we are not going to access 91# it, so that is fine) 92# This should keep all permissions shared. 93success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \ 94 "{'execute': 'blockdev-add', 95 'arguments': { 96 'node-name': 'node0', 97 'driver': 'file', 98 'filename': '$TEST_IMG', 99 'locking': 'on' 100 } }" \ 101 'return' \ 102 'error' 103 104# This snapshot will perform a reopen to drop R/W to RO. 105# It should still keep all permissions shared. 106success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \ 107 "{'execute': 'blockdev-snapshot-sync', 108 'arguments': { 109 'node-name': 'node0', 110 'snapshot-file': '$TEST_IMG.overlay', 111 'snapshot-node-name': 'node1' 112 } }" \ 113 'return' \ 114 'error' 115 116# Now open the same file again 117# This does not require any permissions (and does not unshare any), so 118# this will not conflict with node0. 119success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \ 120 "{'execute': 'blockdev-add', 121 'arguments': { 122 'node-name': 'node1', 123 'driver': 'file', 124 'filename': '$TEST_IMG', 125 'locking': 'on' 126 } }" \ 127 'return' \ 128 'error' 129 130# Start an NBD server to which we can attach node1 131success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \ 132 "{'execute': 'nbd-server-start', 133 'arguments': { 134 'addr': { 135 'type': 'unix', 136 'data': { 137 'path': '$SOCK_DIR/nbd.socket' 138 } } } }" \ 139 'return' \ 140 'error' 141 142# Now we attach the image to the NBD server. This server does require 143# some permissions (at least WRITE and READ_CONSISTENT), so if 144# reopening node0 unshared any (which it should not have), this will 145# fail (but it should not). 146success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \ 147 "{'execute': 'nbd-server-add', 148 'arguments': { 149 'device': 'node1' 150 } }" \ 151 'return' \ 152 'error' 153 154_cleanup_qemu 155 156echo 157echo '=== Testing failure to loosen restrictions ===' 158echo 159 160_launch_qemu -drive file=$TEST_IMG,if=none,file.locking=on 161 162_send_qemu_cmd $QEMU_HANDLE \ 163 "{'execute': 'qmp_capabilities'}" \ 164 'return' 165 166_cleanup_test_img 167 168# When quitting qemu, it will try to drop its locks on the test image. 169# Because that file no longer exists, it will be unable to do so. 170# However, that is not fatal, so it should just move on. 171_send_qemu_cmd $QEMU_HANDLE \ 172 "{'execute': 'quit'}" \ 173 'return' 174 175wait=1 _cleanup_qemu 176 177# success, all done 178echo "*** done" 179rm -f $seq.full 180status=0 181