ppc/pnv: Add POWER10 quads
[qemu.git] / tests / avocado / virtiofs_submounts.py
blobe6dc32ffd4e619ad7a75c32bafe3f9d2e0221dc5
1 import logging
2 import re
3 import os
4 import subprocess
5 import time
7 from avocado import skipUnless
8 from avocado_qemu import LinuxTest, BUILD_DIR
9 from avocado_qemu import has_cmds
10 from avocado_qemu import run_cmd
11 from avocado_qemu import wait_for_console_pattern
12 from avocado.utils import ssh
15 class VirtiofsSubmountsTest(LinuxTest):
16 """
17 :avocado: tags=arch:x86_64
18 :avocado: tags=accel:kvm
19 """
21 def run(self, args, ignore_error=False):
22 stdout, stderr, ret = run_cmd(args)
24 if ret != 0:
25 cmdline = ' '.join(args)
26 if not ignore_error:
27 self.fail(f'{cmdline}: Returned {ret}: {stderr}')
28 else:
29 self.log.warn(f'{cmdline}: Returned {ret}: {stderr}')
31 return (stdout, stderr, ret)
33 def set_up_shared_dir(self):
34 self.shared_dir = os.path.join(self.workdir, 'virtiofs-shared')
36 os.mkdir(self.shared_dir)
38 self.run(('cp', self.get_data('guest.sh'),
39 os.path.join(self.shared_dir, 'check.sh')))
41 self.run(('cp', self.get_data('guest-cleanup.sh'),
42 os.path.join(self.shared_dir, 'cleanup.sh')))
44 def set_up_virtiofs(self):
45 attmp = os.getenv('AVOCADO_TESTS_COMMON_TMPDIR')
46 self.vfsdsock = os.path.join(attmp, 'vfsdsock')
48 self.run(('sudo', '-n', 'rm', '-f', self.vfsdsock), ignore_error=True)
50 self.virtiofsd = \
51 subprocess.Popen(('sudo', '-n',
52 'tools/virtiofsd/virtiofsd',
53 f'--socket-path={self.vfsdsock}',
54 '-o', f'source={self.shared_dir}',
55 '-o', 'cache=always',
56 '-o', 'xattr',
57 '-o', 'announce_submounts',
58 '-f'),
59 stdout=subprocess.DEVNULL,
60 stderr=subprocess.PIPE,
61 universal_newlines=True)
63 while not os.path.exists(self.vfsdsock):
64 if self.virtiofsd.poll() is not None:
65 self.fail('virtiofsd exited prematurely: ' +
66 self.virtiofsd.communicate()[1])
67 time.sleep(0.1)
69 self.run(('sudo', '-n', 'chmod', 'go+rw', self.vfsdsock))
71 self.vm.add_args('-chardev',
72 f'socket,id=vfsdsock,path={self.vfsdsock}',
73 '-device',
74 'vhost-user-fs-pci,queue-size=1024,chardev=vfsdsock' \
75 ',tag=host',
76 '-object',
77 'memory-backend-file,id=mem,size=1G,' \
78 'mem-path=/dev/shm,share=on',
79 '-numa',
80 'node,memdev=mem')
82 def set_up_nested_mounts(self):
83 scratch_dir = os.path.join(self.shared_dir, 'scratch')
84 try:
85 os.mkdir(scratch_dir)
86 except FileExistsError:
87 pass
89 args = ['bash', self.get_data('host.sh'), scratch_dir]
90 if self.seed:
91 args += [self.seed]
93 out, _, _ = self.run(args)
94 seed = re.search(r'^Seed: \d+', out)
95 self.log.info(seed[0])
97 def mount_in_guest(self):
98 self.ssh_command('mkdir -p /mnt/host')
99 self.ssh_command('mount -t virtiofs host /mnt/host')
101 def check_in_guest(self):
102 self.ssh_command('bash /mnt/host/check.sh /mnt/host/scratch/share')
104 def live_cleanup(self):
105 self.ssh_command('bash /mnt/host/cleanup.sh /mnt/host/scratch')
107 # It would be nice if the above was sufficient to make virtiofsd clear
108 # all references to the mounted directories (so they can be unmounted
109 # on the host), but unfortunately it is not. To do so, we have to
110 # resort to a remount.
111 self.ssh_command('mount -o remount /mnt/host')
113 scratch_dir = os.path.join(self.shared_dir, 'scratch')
114 self.run(('bash', self.get_data('cleanup.sh'), scratch_dir))
116 @skipUnless(*has_cmds(('sudo -n', ('sudo', '-n', 'true')),
117 'ssh-keygen', 'bash', 'losetup', 'mkfs.xfs', 'mount'))
118 def setUp(self):
119 vmlinuz = self.params.get('vmlinuz')
120 if vmlinuz is None:
122 The Linux kernel supports FUSE auto-submounts only as of 5.10.
123 boot_linux.py currently provides Fedora 31, whose kernel is too
124 old, so this test cannot pass with the on-image kernel (you are
125 welcome to try, hence the option to force such a test with
126 -p vmlinuz=''). Therefore, for now the user must provide a
127 sufficiently new custom kernel, or effectively explicitly
128 request failure with -p vmlinuz=''.
129 Once an image with a sufficiently new kernel is available
130 (probably Fedora 34), we can make -p vmlinuz='' the default, so
131 that this parameter no longer needs to be specified.
133 self.cancel('vmlinuz parameter not set; you must point it to a '
134 'Linux kernel binary to test (to run this test with ' \
135 'the on-image kernel, set it to an empty string)')
137 self.seed = self.params.get('seed')
139 self.ssh_key = os.path.join(self.workdir, 'id_ed25519')
141 self.run(('ssh-keygen', '-N', '', '-t', 'ed25519', '-f', self.ssh_key))
143 pubkey = self.ssh_key + '.pub'
145 super(VirtiofsSubmountsTest, self).setUp(pubkey)
147 if vmlinuz:
148 self.vm.add_args('-kernel', vmlinuz,
149 '-append', 'console=ttyS0 root=/dev/sda1')
151 self.require_accelerator("kvm")
152 self.vm.add_args('-accel', 'kvm')
154 def tearDown(self):
155 try:
156 self.vm.shutdown()
157 except:
158 pass
160 scratch_dir = os.path.join(self.shared_dir, 'scratch')
161 self.run(('bash', self.get_data('cleanup.sh'), scratch_dir),
162 ignore_error=True)
164 def test_pre_virtiofsd_set_up(self):
165 self.set_up_shared_dir()
167 self.set_up_nested_mounts()
169 self.set_up_virtiofs()
170 self.launch_and_wait()
171 self.mount_in_guest()
172 self.check_in_guest()
174 def test_pre_launch_set_up(self):
175 self.set_up_shared_dir()
176 self.set_up_virtiofs()
178 self.set_up_nested_mounts()
180 self.launch_and_wait()
181 self.mount_in_guest()
182 self.check_in_guest()
184 def test_post_launch_set_up(self):
185 self.set_up_shared_dir()
186 self.set_up_virtiofs()
187 self.launch_and_wait()
189 self.set_up_nested_mounts()
191 self.mount_in_guest()
192 self.check_in_guest()
194 def test_post_mount_set_up(self):
195 self.set_up_shared_dir()
196 self.set_up_virtiofs()
197 self.launch_and_wait()
198 self.mount_in_guest()
200 self.set_up_nested_mounts()
202 self.check_in_guest()
204 def test_two_runs(self):
205 self.set_up_shared_dir()
207 self.set_up_nested_mounts()
209 self.set_up_virtiofs()
210 self.launch_and_wait()
211 self.mount_in_guest()
212 self.check_in_guest()
214 self.live_cleanup()
215 self.set_up_nested_mounts()
217 self.check_in_guest()