aboutsummaryrefslogtreecommitdiff
path: root/tests/acceptance
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2020-10-27 20:13:28 -0600
committerPeter Maydell <peter.maydell@linaro.org>2020-10-28 13:17:32 +0000
commit33dc9914eac581dea9bdea35dcda4d542531d66a (patch)
tree3828d7d3f0de8be2c574e7ea94747b03f9169259 /tests/acceptance
parentcddfbe07749a44f83d0f8241fff7ca96a6631882 (diff)
Revert series: virtiofsd: Announce submounts to the guest
This reverts the following commits due to their basis on a bogus linux kernel header update: c93a656f7b65 ("tests/acceptance: Add virtiofs_submounts.py") 45ced7ca2f27 ("tests/acceptance/boot_linux: Accept SSH pubkey") 08dce386e77e ("virtiofsd: Announce sub-mount points") eba8b096c17c ("virtiofsd: Store every lo_inode's parent_dev") ede24b6be798 ("virtiofsd: Add fuse_reply_attr_with_flags()") e2577435d343 ("virtiofsd: Add attr_flags to fuse_entry_param") 2f10415abfc5 ("virtiofsd: Announce FUSE_ATTR_FLAGS") 97d741cc96dd ("linux/fuse.h: Pull in from Linux") Cc: Max Reitz <mreitz@redhat.com> Cc: Stefan Hajnoczi <stefanha@redhat.com> Cc: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Message-id: 160385090886.20017.13382256442750027666.stgit@gimli.home Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/acceptance')
-rw-r--r--tests/acceptance/boot_linux.py13
-rw-r--r--tests/acceptance/virtiofs_submounts.py289
-rw-r--r--tests/acceptance/virtiofs_submounts.py.data/cleanup.sh46
-rw-r--r--tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh30
-rw-r--r--tests/acceptance/virtiofs_submounts.py.data/guest.sh138
-rw-r--r--tests/acceptance/virtiofs_submounts.py.data/host.sh127
6 files changed, 6 insertions, 637 deletions
diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index 1da4a53d6a..c743e231f4 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -57,7 +57,7 @@ class BootLinuxBase(Test):
self.cancel('Failed to download/prepare boot image')
return boot.path
- def download_cloudinit(self, ssh_pubkey=None):
+ def download_cloudinit(self):
self.log.info('Preparing cloudinit image')
try:
cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
@@ -67,8 +67,7 @@ class BootLinuxBase(Test):
password='password',
# QEMU's hard coded usermode router address
phone_home_host='10.0.2.2',
- phone_home_port=self.phone_home_port,
- authorized_key=ssh_pubkey)
+ phone_home_port=self.phone_home_port)
except Exception:
self.cancel('Failed to prepared cloudinit image')
return cloudinit_iso
@@ -81,19 +80,19 @@ class BootLinux(BootLinuxBase):
timeout = 900
chksum = None
- def setUp(self, ssh_pubkey=None):
+ def setUp(self):
super(BootLinux, self).setUp()
self.vm.add_args('-smp', '2')
self.vm.add_args('-m', '1024')
self.prepare_boot()
- self.prepare_cloudinit(ssh_pubkey)
+ self.prepare_cloudinit()
def prepare_boot(self):
path = self.download_boot()
self.vm.add_args('-drive', 'file=%s' % path)
- def prepare_cloudinit(self, ssh_pubkey=None):
- cloudinit_iso = self.download_cloudinit(ssh_pubkey)
+ def prepare_cloudinit(self):
+ cloudinit_iso = self.download_cloudinit()
self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
def launch_and_wait(self):
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
deleted file mode 100644
index 8b207b3e57..0000000000
--- a/tests/acceptance/virtiofs_submounts.py
+++ /dev/null
@@ -1,289 +0,0 @@
-import logging
-import re
-import os
-import subprocess
-import time
-
-from avocado import skipUnless
-from avocado_qemu import Test, BUILD_DIR
-from avocado_qemu import wait_for_console_pattern
-from avocado.utils import ssh
-
-from qemu.accel import kvm_available
-
-from boot_linux import BootLinux
-
-
-def run_cmd(args):
- subp = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- universal_newlines=True)
- stdout, stderr = subp.communicate()
- ret = subp.returncode
-
- return (stdout, stderr, ret)
-
-def has_passwordless_sudo():
- """
- This function is for use in a @avocado.skipUnless decorator, e.g.:
-
- @skipUnless(*has_passwordless_sudo())
- def test_something_that_needs_sudo(self):
- ...
- """
-
- _, stderr, exitcode = run_cmd(('sudo', '-n', 'true'))
- if exitcode != 0:
- return (False, f'Failed to use sudo -n: {stderr.strip()}')
- else:
- return (True, '')
-
-
-class VirtiofsSubmountsTest(BootLinux):
- """
- :avocado: tags=arch:x86_64
- """
-
- def get_portfwd(self):
- port = None
-
- res = self.vm.command('human-monitor-command',
- command_line='info usernet')
- for line in res.split('\r\n'):
- match = \
- re.search(r'TCP.HOST_FORWARD.*127\.0\.0\.1\s*(\d+)\s+10\.',
- line)
- if match is not None:
- port = match[1]
- break
-
- self.assertIsNotNone(port)
- self.log.debug('sshd listening on port: ' + port)
- return port
-
- def ssh_connect(self, username, keyfile):
- self.ssh_logger = logging.getLogger('ssh')
- port = self.get_portfwd()
- self.ssh_session = ssh.Session('127.0.0.1', port=int(port),
- user=username, key=keyfile)
- for i in range(10):
- try:
- self.ssh_session.connect()
- return
- except:
- time.sleep(4)
- pass
- self.fail('sshd timeout')
-
- def ssh_command(self, command):
- self.ssh_logger.info(command)
- result = self.ssh_session.cmd(command)
- stdout_lines = [line.rstrip() for line
- in result.stdout_text.splitlines()]
- for line in stdout_lines:
- self.ssh_logger.info(line)
- stderr_lines = [line.rstrip() for line
- in result.stderr_text.splitlines()]
- for line in stderr_lines:
- self.ssh_logger.warning(line)
-
- self.assertEqual(result.exit_status, 0,
- f'Guest command failed: {command}')
- return stdout_lines, stderr_lines
-
- def run(self, args, ignore_error=False):
- stdout, stderr, ret = run_cmd(args)
-
- if ret != 0:
- cmdline = ' '.join(args)
- if not ignore_error:
- self.fail(f'{cmdline}: Returned {ret}: {stderr}')
- else:
- self.log.warn(f'{cmdline}: Returned {ret}: {stderr}')
-
- return (stdout, stderr, ret)
-
- def set_up_shared_dir(self):
- atwd = os.getenv('AVOCADO_TEST_WORKDIR')
- self.shared_dir = os.path.join(atwd, 'virtiofs-shared')
-
- os.mkdir(self.shared_dir)
-
- self.run(('cp', self.get_data('guest.sh'),
- os.path.join(self.shared_dir, 'check.sh')))
-
- self.run(('cp', self.get_data('guest-cleanup.sh'),
- os.path.join(self.shared_dir, 'cleanup.sh')))
-
- def set_up_virtiofs(self):
- attmp = os.getenv('AVOCADO_TESTS_COMMON_TMPDIR')
- self.vfsdsock = os.path.join(attmp, 'vfsdsock')
-
- self.run(('sudo', '-n', 'rm', '-f', self.vfsdsock), ignore_error=True)
-
- self.virtiofsd = \
- subprocess.Popen(('sudo', '-n',
- 'tools/virtiofsd/virtiofsd',
- f'--socket-path={self.vfsdsock}',
- '-o', f'source={self.shared_dir}',
- '-o', 'cache=always',
- '-o', 'xattr',
- '-o', 'announce_submounts',
- '-f'),
- stdout=subprocess.DEVNULL,
- stderr=subprocess.PIPE,
- universal_newlines=True)
-
- while not os.path.exists(self.vfsdsock):
- if self.virtiofsd.poll() is not None:
- self.fail('virtiofsd exited prematurely: ' +
- self.virtiofsd.communicate()[1])
- time.sleep(0.1)
-
- self.run(('sudo', '-n', 'chmod', 'go+rw', self.vfsdsock))
-
- self.vm.add_args('-chardev',
- f'socket,id=vfsdsock,path={self.vfsdsock}',
- '-device',
- 'vhost-user-fs-pci,queue-size=1024,chardev=vfsdsock' \
- ',tag=host',
- '-object',
- 'memory-backend-file,id=mem,size=1G,' \
- 'mem-path=/dev/shm,share=on',
- '-numa',
- 'node,memdev=mem')
-
- def launch_vm(self):
- self.launch_and_wait()
- self.ssh_connect('root', self.ssh_key)
-
- def set_up_nested_mounts(self):
- scratch_dir = os.path.join(self.shared_dir, 'scratch')
- try:
- os.mkdir(scratch_dir)
- except FileExistsError:
- pass
-
- args = ['bash', self.get_data('host.sh'), scratch_dir]
- if self.seed:
- args += [self.seed]
-
- out, _, _ = self.run(args)
- seed = re.search(r'^Seed: \d+', out)
- self.log.info(seed[0])
-
- def mount_in_guest(self):
- self.ssh_command('mkdir -p /mnt/host')
- self.ssh_command('mount -t virtiofs host /mnt/host')
-
- def check_in_guest(self):
- self.ssh_command('bash /mnt/host/check.sh /mnt/host/scratch/share')
-
- def live_cleanup(self):
- self.ssh_command('bash /mnt/host/cleanup.sh /mnt/host/scratch')
-
- # It would be nice if the above was sufficient to make virtiofsd clear
- # all references to the mounted directories (so they can be unmounted
- # on the host), but unfortunately it is not. To do so, we have to
- # resort to a remount.
- self.ssh_command('mount -o remount /mnt/host')
-
- scratch_dir = os.path.join(self.shared_dir, 'scratch')
- self.run(('bash', self.get_data('cleanup.sh'), scratch_dir))
-
- @skipUnless(*has_passwordless_sudo())
- def setUp(self):
- vmlinuz = self.params.get('vmlinuz')
- if vmlinuz is None:
- self.cancel('vmlinuz parameter not set; you must point it to a '
- 'Linux kernel binary to test (to run this test with ' \
- 'the on-image kernel, set it to an empty string)')
-
- self.seed = self.params.get('seed')
-
- atwd = os.getenv('AVOCADO_TEST_WORKDIR')
- self.ssh_key = os.path.join(atwd, 'id_ed25519')
-
- self.run(('ssh-keygen', '-t', 'ed25519', '-f', self.ssh_key))
-
- pubkey = open(self.ssh_key + '.pub').read()
-
- super(VirtiofsSubmountsTest, self).setUp(pubkey)
-
- if len(vmlinuz) > 0:
- self.vm.add_args('-kernel', vmlinuz,
- '-append', 'console=ttyS0 root=/dev/sda1')
-
- # Allow us to connect to SSH
- self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
- '-device', 'e1000,netdev=vnet')
-
- if not kvm_available(self.arch, self.qemu_bin):
- self.cancel(KVM_NOT_AVAILABLE)
- self.vm.add_args('-accel', 'kvm')
-
- def tearDown(self):
- try:
- self.vm.shutdown()
- except:
- pass
-
- scratch_dir = os.path.join(self.shared_dir, 'scratch')
- self.run(('bash', self.get_data('cleanup.sh'), scratch_dir),
- ignore_error=True)
-
- def test_pre_virtiofsd_set_up(self):
- self.set_up_shared_dir()
-
- self.set_up_nested_mounts()
-
- self.set_up_virtiofs()
- self.launch_vm()
- self.mount_in_guest()
- self.check_in_guest()
-
- def test_pre_launch_set_up(self):
- self.set_up_shared_dir()
- self.set_up_virtiofs()
-
- self.set_up_nested_mounts()
-
- self.launch_vm()
- self.mount_in_guest()
- self.check_in_guest()
-
- def test_post_launch_set_up(self):
- self.set_up_shared_dir()
- self.set_up_virtiofs()
- self.launch_vm()
-
- self.set_up_nested_mounts()
-
- self.mount_in_guest()
- self.check_in_guest()
-
- def test_post_mount_set_up(self):
- self.set_up_shared_dir()
- self.set_up_virtiofs()
- self.launch_vm()
- self.mount_in_guest()
-
- self.set_up_nested_mounts()
-
- self.check_in_guest()
-
- def test_two_runs(self):
- self.set_up_shared_dir()
-
- self.set_up_nested_mounts()
-
- self.set_up_virtiofs()
- self.launch_vm()
- self.mount_in_guest()
- self.check_in_guest()
-
- self.live_cleanup()
- self.set_up_nested_mounts()
-
- self.check_in_guest()
diff --git a/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh b/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh
deleted file mode 100644
index 2a6579a0fe..0000000000
--- a/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-function print_usage()
-{
- if [ -n "$2" ]; then
- echo "Error: $2"
- echo
- fi
- echo "Usage: $1 <scratch dir>"
-}
-
-scratch_dir=$1
-if [ -z "$scratch_dir" ]; then
- print_usage "$0" 'Scratch dir not given' >&2
- exit 1
-fi
-
-cd "$scratch_dir/share" || exit 1
-mps=(mnt*)
-mp_i=0
-for mp in "${mps[@]}"; do
- mp_i=$((mp_i + 1))
- printf "Unmounting %i/%i...\r" "$mp_i" "${#mps[@]}"
-
- sudo umount -R "$mp"
- rm -rf "$mp"
-done
-echo
-
-rm some-file
-cd ..
-rmdir share
-
-imgs=(fs*.img)
-img_i=0
-for img in "${imgs[@]}"; do
- img_i=$((img_i + 1))
- printf "Detaching and deleting %i/%i...\r" "$img_i" "${#imgs[@]}"
-
- dev=$(losetup -j "$img" | sed -e 's/:.*//')
- sudo losetup -d "$dev"
- rm -f "$img"
-done
-echo
-
-echo 'Done.'
diff --git a/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh b/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh
deleted file mode 100644
index 729cb2d1a5..0000000000
--- a/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-function print_usage()
-{
- if [ -n "$2" ]; then
- echo "Error: $2"
- echo
- fi
- echo "Usage: $1 <scratch dir>"
-}
-
-scratch_dir=$1
-if [ -z "$scratch_dir" ]; then
- print_usage "$0" 'Scratch dir not given' >&2
- exit 1
-fi
-
-cd "$scratch_dir/share" || exit 1
-
-mps=(mnt*)
-mp_i=0
-for mp in "${mps[@]}"; do
- mp_i=$((mp_i + 1))
- printf "Unmounting %i/%i...\r" "$mp_i" "${#mps[@]}"
-
- sudo umount -R "$mp"
-done
-echo
-
-echo 'Done.'
diff --git a/tests/acceptance/virtiofs_submounts.py.data/guest.sh b/tests/acceptance/virtiofs_submounts.py.data/guest.sh
deleted file mode 100644
index 59ba40fde1..0000000000
--- a/tests/acceptance/virtiofs_submounts.py.data/guest.sh
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/bin/bash
-
-function print_usage()
-{
- if [ -n "$2" ]; then
- echo "Error: $2"
- echo
- fi
- echo "Usage: $1 <shared dir>"
- echo '(The shared directory is the "share" directory in the scratch' \
- 'directory)'
-}
-
-shared_dir=$1
-if [ -z "$shared_dir" ]; then
- print_usage "$0" 'Shared dir not given' >&2
- exit 1
-fi
-
-cd "$shared_dir"
-
-# FIXME: This should not be necessary, but it is. In order for all
-# submounts to be proper mount points, we need to visit them.
-# (Before we visit them, they will not be auto-mounted, and so just
-# appear as normal directories, with the catch that their st_ino will
-# be the st_ino of the filesystem they host, while the st_dev will
-# still be the st_dev of the parent.)
-# `find` does not work, because it will refuse to touch the mount
-# points as long as they are not mounted; their st_dev being shared
-# with the parent and st_ino just being the root node's inode ID
-# will practically ensure that this node exists elsewhere on the
-# filesystem, and `find` is required to recognize loops and not to
-# follow them.
-# Thus, we have to manually visit all nodes first.
-
-mnt_i=0
-
-function recursively_visit()
-{
- pushd "$1" >/dev/null
- for entry in *; do
- if [[ "$entry" == mnt* ]]; then
- mnt_i=$((mnt_i + 1))
- printf "Triggering auto-mount $mnt_i...\r"
- fi
-
- if [ -d "$entry" ]; then
- recursively_visit "$entry"
- fi
- done
- popd >/dev/null
-}
-
-recursively_visit .
-echo
-
-
-if [ -n "$(find -name not-mounted)" ]; then
- echo "Error: not-mounted files visible on mount points:" >&2
- find -name not-mounted >&2
- exit 1
-fi
-
-if [ ! -f some-file -o "$(cat some-file)" != 'root' ]; then
- echo "Error: Bad file in the share root" >&2
- exit 1
-fi
-
-shopt -s nullglob
-
-function check_submounts()
-{
- local base_path=$1
-
- for mp in mnt*; do
- printf "Checking submount %i...\r" "$((${#devs[@]} + 1))"
-
- mp_i=$(echo "$mp" | sed -e 's/mnt//')
- dev=$(stat -c '%D' "$mp")
-
- if [ -n "${devs[mp_i]}" ]; then
- echo "Error: $mp encountered twice" >&2
- exit 1
- fi
- devs[mp_i]=$dev
-
- pushd "$mp" >/dev/null
- path="$base_path$mp"
- while true; do
- expected_content="$(printf '%s\n%s\n' "$mp_i" "$path")"
- if [ ! -f some-file ]; then
- echo "Error: $PWD/some-file does not exist" >&2
- exit 1
- fi
-
- if [ "$(cat some-file)" != "$expected_content" ]; then
- echo "Error: Bad content in $PWD/some-file:" >&2
- echo '--- found ---'
- cat some-file
- echo '--- expected ---'
- echo "$expected_content"
- exit 1
- fi
- if [ "$(stat -c '%D' some-file)" != "$dev" ]; then
- echo "Error: $PWD/some-file has the wrong device ID" >&2
- exit 1
- fi
-
- if [ -d sub ]; then
- if [ "$(stat -c '%D' sub)" != "$dev" ]; then
- echo "Error: $PWD/some-file has the wrong device ID" >&2
- exit 1
- fi
- cd sub
- path="$path/sub"
- else
- if [ -n "$(echo mnt*)" ]; then
- check_submounts "$path/"
- fi
- break
- fi
- done
- popd >/dev/null
- done
-}
-
-root_dev=$(stat -c '%D' some-file)
-devs=()
-check_submounts ''
-echo
-
-reused_devs=$(echo "$root_dev ${devs[@]}" | tr ' ' '\n' | sort | uniq -d)
-if [ -n "$reused_devs" ]; then
- echo "Error: Reused device IDs: $reused_devs" >&2
- exit 1
-fi
-
-echo "Test passed for ${#devs[@]} submounts."
diff --git a/tests/acceptance/virtiofs_submounts.py.data/host.sh b/tests/acceptance/virtiofs_submounts.py.data/host.sh
deleted file mode 100644
index d8a9afebdb..0000000000
--- a/tests/acceptance/virtiofs_submounts.py.data/host.sh
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/bin/bash
-
-mount_count=128
-
-function print_usage()
-{
- if [ -n "$2" ]; then
- echo "Error: $2"
- echo
- fi
- echo "Usage: $1 <scratch dir> [seed]"
- echo "(If no seed is given, it will be randomly generated.)"
-}
-
-scratch_dir=$1
-if [ -z "$scratch_dir" ]; then
- print_usage "$0" 'No scratch dir given' >&2
- exit 1
-fi
-
-if [ ! -d "$scratch_dir" ]; then
- print_usage "$0" "$scratch_dir is not a directory" >&2
- exit 1
-fi
-
-seed=$2
-if [ -z "$seed" ]; then
- seed=$RANDOM
-fi
-RANDOM=$seed
-
-echo "Seed: $seed"
-
-set -e
-shopt -s nullglob
-
-cd "$scratch_dir"
-if [ -d share ]; then
- echo 'Error: This directory seems to be in use already' >&2
- exit 1
-fi
-
-for ((i = 0; i < $mount_count; i++)); do
- printf "Setting up fs %i/%i...\r" "$((i + 1))" "$mount_count"
-
- rm -f fs$i.img
- truncate -s 512M fs$i.img
- mkfs.xfs -q fs$i.img
- devs[i]=$(sudo losetup -f --show fs$i.img)
-done
-echo
-
-top_level_mounts=$((RANDOM % mount_count + 1))
-
-mkdir -p share
-echo 'root' > share/some-file
-
-for ((i = 0; i < $top_level_mounts; i++)); do
- printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count"
-
- mkdir -p share/mnt$i
- touch share/mnt$i/not-mounted
- sudo mount "${devs[i]}" share/mnt$i
- sudo chown "$(id -u):$(id -g)" share/mnt$i
-
- pushd share/mnt$i >/dev/null
- path=mnt$i
- nesting=$((RANDOM % 4))
- for ((j = 0; j < $nesting; j++)); do
- cat > some-file <<EOF
-$i
-$path
-EOF
- mkdir sub
- cd sub
- path="$path/sub"
- done
-cat > some-file <<EOF
-$i
-$path
-EOF
- popd >/dev/null
-done
-
-for ((; i < $mount_count; i++)); do
- printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count"
-
- mp_i=$((i % top_level_mounts))
-
- pushd share/mnt$mp_i >/dev/null
- path=mnt$mp_i
- while true; do
- sub_mp="$(echo mnt*)"
- if cd sub 2>/dev/null; then
- path="$path/sub"
- elif [ -n "$sub_mp" ] && cd "$sub_mp" 2>/dev/null; then
- path="$path/$sub_mp"
- else
- break
- fi
- done
- mkdir mnt$i
- touch mnt$i/not-mounted
- sudo mount "${devs[i]}" mnt$i
- sudo chown "$(id -u):$(id -g)" mnt$i
-
- cd mnt$i
- path="$path/mnt$i"
- nesting=$((RANDOM % 4))
- for ((j = 0; j < $nesting; j++)); do
- cat > some-file <<EOF
-$i
-$path
-EOF
- mkdir sub
- cd sub
- path="$path/sub"
- done
- cat > some-file <<EOF
-$i
-$path
-EOF
- popd >/dev/null
-done
-echo
-
-echo 'Done.'