From nobody Sun May 19 00:42:50 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1603851302; cv=none; d=zohomail.com; s=zohoarc; b=AT5YLOB9kFULavoRfhX/kuruEYQ5n//4bzr6uNSWdgASCAhIo5FToBVT5dlbn0GMqmHZ3yBK9sABCqk/UCFNkfyBp/crhOl0Aj4YU+HP3hQpBozu0YKGQyEfS6bbE06kmrXuV0YTbFYcPgF3OmRvjixWjYgnaJycmcfHWAYsucw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1603851302; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=YDcNA62nWdW89VOM29XwVuknxsxXCQcBQqV5y9oBawo=; b=GC04OMGBTPLRcQ5kLV8W4PTvKkpKWAo1BZVi57/fYHjb6bpeKEA7walvMc97oPRaHD2qKTj0v1wbDFlLE7w+yt4zydKd/kylNip7UPF5HitnkRXE48apRHKujEhw3G7Md935yNnXMAaqabcPqTLeKOupE3il+gdmqzkN1YG0wf0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1603851302924478.0755224314223; Tue, 27 Oct 2020 19:15:02 -0700 (PDT) Received: from localhost ([::1]:48082 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kXazN-0004cm-EE for importer@patchew.org; Tue, 27 Oct 2020 22:15:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49562) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kXayG-0003me-Cb for qemu-devel@nongnu.org; Tue, 27 Oct 2020 22:13:52 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:21878) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kXayC-0001YP-4s for qemu-devel@nongnu.org; Tue, 27 Oct 2020 22:13:51 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-273-9GDhhC0nMYeKj2jcMprT8w-1; Tue, 27 Oct 2020 22:13:39 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 73EF3809DE0; Wed, 28 Oct 2020 02:13:38 +0000 (UTC) Received: from gimli.home (ovpn-112-213.phx2.redhat.com [10.3.112.213]) by smtp.corp.redhat.com (Postfix) with ESMTP id 80B116EF62; Wed, 28 Oct 2020 02:13:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1603851226; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=YDcNA62nWdW89VOM29XwVuknxsxXCQcBQqV5y9oBawo=; b=hrffw7j5HQI8YageUh+qC22xsiY4/OvLS0Zoz0IJBpDBEXDopw0p2lBVXjJm0IcO5Ri0iY e75blWkmIAvH2j4lp0D9uyiWtUzdf/tdi+tEbGfBNnU6/dDS2o5dRo3xxMuzc7sNlmCUNd PdKbWkg1kk+hjNQ57UxLTDUZ3QU/lHs= X-MC-Unique: 9GDhhC0nMYeKj2jcMprT8w-1 Subject: [PATCH] Revert series: virtiofsd: Announce submounts to the guest From: Alex Williamson To: peter.maydell@linaro.org Date: Tue, 27 Oct 2020 20:13:28 -0600 Message-ID: <160385090886.20017.13382256442750027666.stgit@gimli.home> User-Agent: StGit/0.21-dirty MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=alex.williamson@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=alex.williamson@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/27 22:13:46 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_SHORT=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cjia@nvidia.com, mjrosato@linux.ibm.com, qemu-devel@nongnu.org, "Dr. David Alan Gilbert" , kwankhede@nvidia.com, Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) 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 Cc: Stefan Hajnoczi Cc: Dr. David Alan Gilbert Signed-off-by: Alex Williamson Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Max Reitz --- The following pull request, based on legitimate v5.10-rc1 kernel headers, applies cleanly after this revert: https://lists.nongnu.org/archive/html/qemu-devel/2020-10/msg07849.html include/standard-headers/linux/fuse.h | 11 - tests/acceptance/boot_linux.py | 13 - tests/acceptance/virtiofs_submounts.py | 289 ----------------= ---- .../virtiofs_submounts.py.data/cleanup.sh | 46 --- .../virtiofs_submounts.py.data/guest-cleanup.sh | 30 -- .../acceptance/virtiofs_submounts.py.data/guest.sh | 138 ---------- .../acceptance/virtiofs_submounts.py.data/host.sh | 127 --------- tools/virtiofsd/fuse_common.h | 8 - tools/virtiofsd/fuse_lowlevel.c | 34 -- tools/virtiofsd/fuse_lowlevel.h | 20 - tools/virtiofsd/helper.c | 1=20 tools/virtiofsd/passthrough_ll.c | 84 +----- 12 files changed, 21 insertions(+), 780 deletions(-) delete mode 100644 tests/acceptance/virtiofs_submounts.py delete mode 100644 tests/acceptance/virtiofs_submounts.py.data/cleanup.sh delete mode 100644 tests/acceptance/virtiofs_submounts.py.data/guest-clean= up.sh delete mode 100644 tests/acceptance/virtiofs_submounts.py.data/guest.sh delete mode 100644 tests/acceptance/virtiofs_submounts.py.data/host.sh diff --git a/include/standard-headers/linux/fuse.h b/include/standard-heade= rs/linux/fuse.h index 7dd7a3b992c8..f4df0a40f604 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -227,7 +227,7 @@ struct fuse_attr { uint32_t gid; uint32_t rdev; uint32_t blksize; - uint32_t flags; + uint32_t padding; }; =20 struct fuse_kstatfs { @@ -310,7 +310,6 @@ struct fuse_file_lock { * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit requ= est * FUSE_MAP_ALIGNMENT: map_alignment field is valid - * FUSE_ATTR_FLAGS: fuse_attr.flags is present and valid */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -339,7 +338,6 @@ struct fuse_file_lock { #define FUSE_NO_OPENDIR_SUPPORT (1 << 24) #define FUSE_EXPLICIT_INVAL_DATA (1 << 25) #define FUSE_MAP_ALIGNMENT (1 << 26) -#define FUSE_ATTR_FLAGS (1 << 27) =20 /** * CUSE INIT request/reply flags @@ -415,13 +413,6 @@ struct fuse_file_lock { */ #define FUSE_FSYNC_FDATASYNC (1 << 0) =20 -/** - * fuse_attr flags - * - * FUSE_ATTR_SUBMOUNT: File/directory is a submount point - */ -#define FUSE_ATTR_SUBMOUNT (1 << 0) - enum fuse_opcode { FUSE_LOOKUP =3D 1, FUSE_FORGET =3D 2, /* no reply */ diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py index ad997c3f2eed..0055dc7cee77 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 =20 - def download_cloudinit(self, ssh_pubkey=3DNone): + def download_cloudinit(self): self.log.info('Preparing cloudinit image') try: cloudinit_iso =3D os.path.join(self.workdir, 'cloudinit.iso') @@ -67,8 +67,7 @@ class BootLinuxBase(Test): password=3D'password', # QEMU's hard coded usermode router address phone_home_host=3D'10.0.2.2', - phone_home_port=3Dself.phone_home_port, - authorized_key=3Dssh_pubkey) + phone_home_port=3Dself.phone_home_port) except Exception: self.cancel('Failed to prepared cloudinit image') return cloudinit_iso @@ -81,19 +80,19 @@ class BootLinux(BootLinuxBase): timeout =3D 900 chksum =3D None =20 - def setUp(self, ssh_pubkey=3DNone): + 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() =20 def prepare_boot(self): path =3D self.download_boot() self.vm.add_args('-drive', 'file=3D%s' % path) =20 - def prepare_cloudinit(self, ssh_pubkey=3DNone): - cloudinit_iso =3D self.download_cloudinit(ssh_pubkey) + def prepare_cloudinit(self): + cloudinit_iso =3D self.download_cloudinit() self.vm.add_args('-drive', 'file=3D%s,format=3Draw' % cloudinit_is= o) =20 def launch_and_wait(self): diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virt= iofs_submounts.py deleted file mode 100644 index 8b207b3e577f..000000000000 --- 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 =3D subprocess.Popen(args, - stdout=3Dsubprocess.PIPE, - stderr=3Dsubprocess.PIPE, - universal_newlines=3DTrue) - stdout, stderr =3D subp.communicate() - ret =3D 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 =3D run_cmd(('sudo', '-n', 'true')) - if exitcode !=3D 0: - return (False, f'Failed to use sudo -n: {stderr.strip()}') - else: - return (True, '') - - -class VirtiofsSubmountsTest(BootLinux): - """ - :avocado: tags=3Darch:x86_64 - """ - - def get_portfwd(self): - port =3D None - - res =3D self.vm.command('human-monitor-command', - command_line=3D'info usernet') - for line in res.split('\r\n'): - match =3D \ - re.search(r'TCP.HOST_FORWARD.*127\.0\.0\.1\s*(\d+)\s+10\.', - line) - if match is not None: - port =3D 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 =3D logging.getLogger('ssh') - port =3D self.get_portfwd() - self.ssh_session =3D ssh.Session('127.0.0.1', port=3Dint(port), - user=3Dusername, key=3Dkeyfile) - 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 =3D self.ssh_session.cmd(command) - stdout_lines =3D [line.rstrip() for line - in result.stdout_text.splitlines()] - for line in stdout_lines: - self.ssh_logger.info(line) - stderr_lines =3D [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=3DFalse): - stdout, stderr, ret =3D run_cmd(args) - - if ret !=3D 0: - cmdline =3D ' '.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 =3D os.getenv('AVOCADO_TEST_WORKDIR') - self.shared_dir =3D 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 =3D os.getenv('AVOCADO_TESTS_COMMON_TMPDIR') - self.vfsdsock =3D os.path.join(attmp, 'vfsdsock') - - self.run(('sudo', '-n', 'rm', '-f', self.vfsdsock), ignore_error= =3DTrue) - - self.virtiofsd =3D \ - subprocess.Popen(('sudo', '-n', - 'tools/virtiofsd/virtiofsd', - f'--socket-path=3D{self.vfsdsock}', - '-o', f'source=3D{self.shared_dir}', - '-o', 'cache=3Dalways', - '-o', 'xattr', - '-o', 'announce_submounts', - '-f'), - stdout=3Dsubprocess.DEVNULL, - stderr=3Dsubprocess.PIPE, - universal_newlines=3DTrue) - - 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=3Dvfsdsock,path=3D{self.vfsdsock}', - '-device', - 'vhost-user-fs-pci,queue-size=3D1024,chardev=3Dvf= sdsock' \ - ',tag=3Dhost', - '-object', - 'memory-backend-file,id=3Dmem,size=3D1G,' \ - 'mem-path=3D/dev/shm,share=3Don', - '-numa', - 'node,memdev=3Dmem') - - def launch_vm(self): - self.launch_and_wait() - self.ssh_connect('root', self.ssh_key) - - def set_up_nested_mounts(self): - scratch_dir =3D os.path.join(self.shared_dir, 'scratch') - try: - os.mkdir(scratch_dir) - except FileExistsError: - pass - - args =3D ['bash', self.get_data('host.sh'), scratch_dir] - if self.seed: - args +=3D [self.seed] - - out, _, _ =3D self.run(args) - seed =3D 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 c= lear - # all references to the mounted directories (so they can be unmoun= ted - # 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 =3D 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 =3D 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 wit= h ' \ - 'the on-image kernel, set it to an empty string)') - - self.seed =3D self.params.get('seed') - - atwd =3D os.getenv('AVOCADO_TEST_WORKDIR') - self.ssh_key =3D os.path.join(atwd, 'id_ed25519') - - self.run(('ssh-keygen', '-t', 'ed25519', '-f', self.ssh_key)) - - pubkey =3D open(self.ssh_key + '.pub').read() - - super(VirtiofsSubmountsTest, self).setUp(pubkey) - - if len(vmlinuz) > 0: - self.vm.add_args('-kernel', vmlinuz, - '-append', 'console=3DttyS0 root=3D/dev/sda1') - - # Allow us to connect to SSH - self.vm.add_args('-netdev', 'user,id=3Dvnet,hostfwd=3D:127.0.0.1:0= -:22', - '-device', 'e1000,netdev=3Dvnet') - - 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 =3D os.path.join(self.shared_dir, 'scratch') - self.run(('bash', self.get_data('cleanup.sh'), scratch_dir), - ignore_error=3DTrue) - - 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 2a6579a0fea6..000000000000 --- 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=3D$1 -if [ -z "$scratch_dir" ]; then - print_usage "$0" 'Scratch dir not given' >&2 - exit 1 -fi - -cd "$scratch_dir/share" || exit 1 -mps=3D(mnt*) -mp_i=3D0 -for mp in "${mps[@]}"; do - mp_i=3D$((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=3D(fs*.img) -img_i=3D0 -for img in "${imgs[@]}"; do - img_i=3D$((img_i + 1)) - printf "Detaching and deleting %i/%i...\r" "$img_i" "${#imgs[@]}" - - dev=3D$(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 729cb2d1a5ec..000000000000 --- 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=3D$1 -if [ -z "$scratch_dir" ]; then - print_usage "$0" 'Scratch dir not given' >&2 - exit 1 -fi - -cd "$scratch_dir/share" || exit 1 - -mps=3D(mnt*) -mp_i=3D0 -for mp in "${mps[@]}"; do - mp_i=3D$((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/a= cceptance/virtiofs_submounts.py.data/guest.sh deleted file mode 100644 index 59ba40fde179..000000000000 --- 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 " - echo '(The shared directory is the "share" directory in the scratch' \ - 'directory)' -} - -shared_dir=3D$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=3D0 - -function recursively_visit() -{ - pushd "$1" >/dev/null - for entry in *; do - if [[ "$entry" =3D=3D mnt* ]]; then - mnt_i=3D$((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)" !=3D 'root' ]; then - echo "Error: Bad file in the share root" >&2 - exit 1 -fi - -shopt -s nullglob - -function check_submounts() -{ - local base_path=3D$1 - - for mp in mnt*; do - printf "Checking submount %i...\r" "$((${#devs[@]} + 1))" - - mp_i=3D$(echo "$mp" | sed -e 's/mnt//') - dev=3D$(stat -c '%D' "$mp") - - if [ -n "${devs[mp_i]}" ]; then - echo "Error: $mp encountered twice" >&2 - exit 1 - fi - devs[mp_i]=3D$dev - - pushd "$mp" >/dev/null - path=3D"$base_path$mp" - while true; do - expected_content=3D"$(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)" !=3D "$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)" !=3D "$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)" !=3D "$dev" ]; then - echo "Error: $PWD/some-file has the wrong device ID" >= &2 - exit 1 - fi - cd sub - path=3D"$path/sub" - else - if [ -n "$(echo mnt*)" ]; then - check_submounts "$path/" - fi - break - fi - done - popd >/dev/null - done -} - -root_dev=3D$(stat -c '%D' some-file) -devs=3D() -check_submounts '' -echo - -reused_devs=3D$(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/ac= ceptance/virtiofs_submounts.py.data/host.sh deleted file mode 100644 index d8a9afebdb54..000000000000 --- a/tests/acceptance/virtiofs_submounts.py.data/host.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/bash - -mount_count=3D128 - -function print_usage() -{ - if [ -n "$2" ]; then - echo "Error: $2" - echo - fi - echo "Usage: $1 [seed]" - echo "(If no seed is given, it will be randomly generated.)" -} - -scratch_dir=3D$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=3D$2 -if [ -z "$seed" ]; then - seed=3D$RANDOM -fi -RANDOM=3D$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 =3D 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]=3D$(sudo losetup -f --show fs$i.img) -done -echo - -top_level_mounts=3D$((RANDOM % mount_count + 1)) - -mkdir -p share -echo 'root' > share/some-file - -for ((i =3D 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=3Dmnt$i - nesting=3D$((RANDOM % 4)) - for ((j =3D 0; j < $nesting; j++)); do - cat > some-file < some-file </dev/null -done - -for ((; i < $mount_count; i++)); do - printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count" - - mp_i=3D$((i % top_level_mounts)) - - pushd share/mnt$mp_i >/dev/null - path=3Dmnt$mp_i - while true; do - sub_mp=3D"$(echo mnt*)" - if cd sub 2>/dev/null; then - path=3D"$path/sub" - elif [ -n "$sub_mp" ] && cd "$sub_mp" 2>/dev/null; then - path=3D"$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=3D"$path/mnt$i" - nesting=3D$((RANDOM % 4)) - for ((j =3D 0; j < $nesting; j++)); do - cat > some-file < some-file </dev/null -done -echo - -echo 'Done.' diff --git a/tools/virtiofsd/fuse_common.h b/tools/virtiofsd/fuse_common.h index 870544fe132f..686c42c0a528 100644 --- a/tools/virtiofsd/fuse_common.h +++ b/tools/virtiofsd/fuse_common.h @@ -352,14 +352,6 @@ struct fuse_file_info { */ #define FUSE_CAP_NO_OPENDIR_SUPPORT (1 << 24) =20 -/** - * Indicates that the client will provide fuse_attr.flags, and the kernel = will - * interpret it. - * - * This feature is enabled by default when supported by the kernel. - */ -#define FUSE_CAP_ATTR_FLAGS (1 << 27) - /** * Ioctl flags * diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowleve= l.c index 5198f627bcb3..4d1ba2925d1b 100644 --- a/tools/virtiofsd/fuse_lowlevel.c +++ b/tools/virtiofsd/fuse_lowlevel.c @@ -329,8 +329,7 @@ static unsigned int calc_timeout_nsec(double t) } } =20 -static void fill_entry(struct fuse_session *se, - struct fuse_entry_out *arg, +static void fill_entry(struct fuse_entry_out *arg, const struct fuse_entry_param *e) { *arg =3D (struct fuse_entry_out){ @@ -342,10 +341,6 @@ static void fill_entry(struct fuse_session *se, .attr_valid_nsec =3D calc_timeout_nsec(e->attr_timeout), }; convert_stat(&e->attr, &arg->attr); - - if (se->conn.capable & FUSE_CAP_ATTR_FLAGS) { - arg->attr.flags =3D e->attr_flags; - } } =20 /* @@ -370,7 +365,7 @@ size_t fuse_add_direntry_plus(fuse_req_t req, char *buf= , size_t bufsize, =20 struct fuse_direntplus *dp =3D (struct fuse_direntplus *)buf; memset(&dp->entry_out, 0, sizeof(dp->entry_out)); - fill_entry(req->se, &dp->entry_out, e); + fill_entry(&dp->entry_out, e); =20 struct fuse_dirent *dirent =3D &dp->dirent; *dirent =3D (struct fuse_dirent){ @@ -408,7 +403,7 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_= entry_param *e) size_t size =3D sizeof(arg); =20 memset(&arg, 0, sizeof(arg)); - fill_entry(req->se, &arg, e); + fill_entry(&arg, e); return send_reply_ok(req, &arg, size); } =20 @@ -421,13 +416,13 @@ int fuse_reply_create(fuse_req_t req, const struct fu= se_entry_param *e, struct fuse_open_out *oarg =3D (struct fuse_open_out *)(buf + entrysiz= e); =20 memset(buf, 0, sizeof(buf)); - fill_entry(req->se, earg, e); + fill_entry(earg, e); fill_open(oarg, f); return send_reply_ok(req, buf, entrysize + sizeof(struct fuse_open_out= )); } =20 -int fuse_reply_attr_with_flags(fuse_req_t req, const struct stat *attr, - double attr_timeout, uint32_t attr_flags) +int fuse_reply_attr(fuse_req_t req, const struct stat *attr, + double attr_timeout) { struct fuse_attr_out arg; size_t size =3D sizeof(arg); @@ -437,19 +432,9 @@ int fuse_reply_attr_with_flags(fuse_req_t req, const s= truct stat *attr, arg.attr_valid_nsec =3D calc_timeout_nsec(attr_timeout); convert_stat(attr, &arg.attr); =20 - if (req->se->conn.capable & FUSE_CAP_ATTR_FLAGS) { - arg.attr.flags =3D attr_flags; - } - return send_reply_ok(req, &arg, size); } =20 -int fuse_reply_attr(fuse_req_t req, const struct stat *attr, - double attr_timeout) -{ - return fuse_reply_attr_with_flags(req, attr, attr_timeout, 0); -} - int fuse_reply_readlink(fuse_req_t req, const char *linkname) { return send_reply_ok(req, linkname, strlen(linkname)); @@ -2003,9 +1988,6 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, bufsize =3D max_bufsize; } } - if (arg->flags & FUSE_ATTR_FLAGS) { - se->conn.capable |=3D FUSE_CAP_ATTR_FLAGS; - } #ifdef HAVE_SPLICE #ifdef HAVE_VMSPLICE se->conn.capable |=3D FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE; @@ -2032,7 +2014,6 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, LL_SET_DEFAULT(1, FUSE_CAP_ASYNC_DIO); LL_SET_DEFAULT(1, FUSE_CAP_IOCTL_DIR); LL_SET_DEFAULT(1, FUSE_CAP_ATOMIC_O_TRUNC); - LL_SET_DEFAULT(1, FUSE_CAP_ATTR_FLAGS); LL_SET_DEFAULT(se->op.write_buf, FUSE_CAP_SPLICE_READ); LL_SET_DEFAULT(se->op.getlk && se->op.setlk, FUSE_CAP_POSIX_LOCKS); LL_SET_DEFAULT(se->op.flock, FUSE_CAP_FLOCK_LOCKS); @@ -2122,9 +2103,6 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, if (se->conn.want & FUSE_CAP_POSIX_ACL) { outarg.flags |=3D FUSE_POSIX_ACL; } - if (se->conn.want & FUSE_CAP_ATTR_FLAGS) { - outarg.flags |=3D FUSE_ATTR_FLAGS; - } outarg.max_readahead =3D se->conn.max_readahead; outarg.max_write =3D se->conn.max_write; if (se->conn.max_background >=3D (1 << 16)) { diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowleve= l.h index 1ff6ba1e4f1e..562fd5241ed4 100644 --- a/tools/virtiofsd/fuse_lowlevel.h +++ b/tools/virtiofsd/fuse_lowlevel.h @@ -102,11 +102,6 @@ struct fuse_entry_param { * large value. */ double entry_timeout; - - /** - * Flags for fuse_attr.flags that do not fit into attr. - */ - uint32_t attr_flags; }; =20 /** @@ -1313,21 +1308,6 @@ int fuse_reply_create(fuse_req_t req, const struct f= use_entry_param *e, int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout); =20 -/** - * Reply with attributes and set fuse_attr.flags - * - * Possible requests: - * getattr, setattr - * - * @param req request handle - * @param attr the attributes - * @param attr_timeout validity timeout (in seconds) for the attributes - * @param attr_flags flags to put into fuse_attr.flags - * @return zero for success, -errno for failure to send reply - */ -int fuse_reply_attr_with_flags(fuse_req_t req, const struct stat *attr, - double attr_timeout, uint32_t attr_flags); - /** * Reply with the contents of a symbolic link * diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c index a212f329317b..2e181a49b5ff 100644 --- a/tools/virtiofsd/helper.c +++ b/tools/virtiofsd/helper.c @@ -178,7 +178,6 @@ void fuse_cmdline_help(void) " default: depends on cache=3D op= tion.\n" " -o writeback|no_writeback enable/disable writeback cache\= n" " default: no_writeback\n" - " -o announce_submounts Announce sub-mount points to th= e guest\n" " -o xattr|no_xattr enable/disable xattr\n" " default: no_xattr\n" " -o modcaps=3DCAPLIST Modify the list of capabiliti= es\n" diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough= _ll.c index 4db50046d49f..a0beb986f36a 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -40,7 +40,6 @@ #include "fuse_virtio.h" #include "fuse_log.h" #include "fuse_lowlevel.h" -#include "standard-headers/linux/fuse.h" #include #include #include @@ -126,14 +125,6 @@ struct lo_inode { GHashTable *posix_locks; /* protected by lo_inode->plock_mutex */ =20 mode_t filetype; - - /* - * So we can detect crossmount roots - * (As such, this only needs to be valid for directories. Note - * that files can have multiple parents due to hard links, and so - * their parent_dev may fluctuate.) - */ - dev_t parent_dev; }; =20 struct lo_cred { @@ -174,7 +165,6 @@ struct lo_data { int timeout_set; int readdirplus_set; int readdirplus_clear; - int announce_submounts; int allow_direct_io; struct lo_inode root; GHashTable *inodes; /* protected by lo->mutex */ @@ -213,7 +203,6 @@ static const struct fuse_opt lo_opts[] =3D { { "cache=3Dalways", offsetof(struct lo_data, cache), CACHE_ALWAYS }, { "readdirplus", offsetof(struct lo_data, readdirplus_set), 1 }, { "no_readdirplus", offsetof(struct lo_data, readdirplus_clear), 1 }, - { "announce_submounts", offsetof(struct lo_data, announce_submounts), = 1 }, { "allow_direct_io", offsetof(struct lo_data, allow_direct_io), 1 }, { "no_allow_direct_io", offsetof(struct lo_data, allow_direct_io), 0 }, FUSE_OPT_END @@ -611,52 +600,22 @@ static void lo_init(void *userdata, struct fuse_conn_= info *conn) } } =20 -/** - * Call fstatat() and set st_rdev whenever a directory's st_dev - * differs from the rparent's st_dev (@parent_dev). This will - * announce submounts to the FUSE client (unless @announce_submounts - * is false). - */ -static int do_fstatat(int dirfd, const char *pathname, struct stat *statbu= f, - int flags, dev_t parent_dev, uint32_t *fuse_attr_fla= gs) -{ - int res =3D fstatat(dirfd, pathname, statbuf, flags); - if (res =3D=3D -1) { - return res; - } - - if (statbuf->st_dev !=3D parent_dev && S_ISDIR(statbuf->st_mode) && - fuse_attr_flags) - { - *fuse_attr_flags |=3D FUSE_ATTR_SUBMOUNT; - } - - return 0; -} - static void lo_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { int res; struct stat buf; struct lo_data *lo =3D lo_data(req); - struct lo_inode *inode =3D lo_inode(req, ino); - uint32_t fuse_attr_flags =3D 0; =20 (void)fi; =20 - res =3D do_fstatat(inode->fd, "", &buf, AT_EMPTY_PATH | AT_SYMLINK_NOF= OLLOW, - inode->parent_dev, &fuse_attr_flags); - lo_inode_put(lo, &inode); + res =3D + fstatat(lo_fd(req, ino), "", &buf, AT_EMPTY_PATH | AT_SYMLINK_NOFO= LLOW); if (res =3D=3D -1) { return (void)fuse_reply_err(req, errno); } =20 - if (!lo->announce_submounts) { - fuse_attr_flags &=3D ~FUSE_ATTR_SUBMOUNT; - } - - fuse_reply_attr_with_flags(req, &buf, lo->timeout, fuse_attr_flags); + fuse_reply_attr(req, &buf, lo->timeout); } =20 static int lo_fi_fd(fuse_req_t req, struct fuse_file_info *fi) @@ -852,16 +811,11 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t pa= rent, const char *name, goto out_err; } =20 - res =3D do_fstatat(newfd, "", &e->attr, AT_EMPTY_PATH | AT_SYMLINK_NOF= OLLOW, - dir->key.dev, &e->attr_flags); + res =3D fstatat(newfd, "", &e->attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLL= OW); if (res =3D=3D -1) { goto out_err; } =20 - if (!lo->announce_submounts) { - e->attr_flags &=3D ~FUSE_ATTR_SUBMOUNT; - } - inode =3D lo_find(lo, &e->attr); if (inode) { close(newfd); @@ -893,7 +847,6 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t pare= nt, const char *name, g_hash_table_insert(lo->inodes, &inode->key, inode); pthread_mutex_unlock(&lo->mutex); } - inode->parent_dev =3D dir->key.dev; e->ino =3D inode->fuse_ino; lo_inode_put(lo, &inode); lo_inode_put(lo, &dir); @@ -1107,17 +1060,11 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino,= fuse_ino_t parent, goto out_err; } =20 - res =3D do_fstatat(inode->fd, "", &e.attr, - AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, - parent_inode->key.dev, &e.attr_flags); + res =3D fstatat(inode->fd, "", &e.attr, AT_EMPTY_PATH | AT_SYMLINK_NOF= OLLOW); if (res =3D=3D -1) { goto out_err; } =20 - if (!lo->announce_submounts) { - e.attr_flags &=3D ~FUSE_ATTR_SUBMOUNT; - } - pthread_mutex_lock(&lo->mutex); inode->nlookup++; pthread_mutex_unlock(&lo->mutex); @@ -1126,14 +1073,6 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino, = fuse_ino_t parent, fuse_log(FUSE_LOG_DEBUG, " %lli/%s -> %lli\n", (unsigned long long)pa= rent, name, (unsigned long long)e.ino); =20 - /* - * No need to update inode->parent_dev, because - * (1) We cannot, the inode now has more than one parent, - * (2) Directories cannot have more than one parent, so link() - * does not work for them; but parent_dev only needs to be - * valid for directories. - */ - fuse_reply_entry(req, &e); lo_inode_put(lo, &parent_inode); lo_inode_put(lo, &inode); @@ -1152,21 +1091,14 @@ static struct lo_inode *lookup_name(fuse_req_t req,= fuse_ino_t parent, { int res; struct stat attr; - struct lo_data *lo =3D lo_data(req); - struct lo_inode *dir =3D lo_inode(req, parent); =20 - if (!dir) { - return NULL; - } - - res =3D do_fstatat(dir->fd, name, &attr, - AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, dir->key.dev, NU= LL); - lo_inode_put(lo, &dir); + res =3D fstatat(lo_fd(req, parent), name, &attr, + AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW); if (res =3D=3D -1) { return NULL; } =20 - return lo_find(lo, &attr); + return lo_find(lo_data(req), &attr); } =20 static void lo_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)