qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: John Levon <john.levon@nutanix.com>
Cc: qemu-devel@nongnu.org, "Cédric Le Goater" <clg@redhat.com>,
	"Thanos Makatos" <thanos.makatos@nutanix.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Zhao Liu" <zhao1.liu@intel.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Mark Cave-Ayland" <mark.caveayland@nutanix.com>
Subject: Re: [PATCH v4 3/3] tests/functional: add a vfio-user smoke test
Date: Mon, 8 Sep 2025 15:42:35 +0100	[thread overview]
Message-ID: <aL7rW6Tq9d-z8sGL@redhat.com> (raw)
In-Reply-To: <20250903201931.168317-4-john.levon@nutanix.com>

On Wed, Sep 03, 2025 at 10:19:31PM +0200, John Levon wrote:
> From: Mark Cave-Ayland <mark.caveayland@nutanix.com>
> 
> Add a basic test of the vfio-user PCI client implementation.
> 
> Co-authored-by: John Levon <john.levon@nutanix.com>
> Signed-off-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
> Signed-off-by: John Levon <john.levon@nutanix.com>
> ---
>  MAINTAINERS                                   |   1 +
>  tests/functional/x86_64/meson.build           |   1 +
>  .../x86_64/test_vfio_user_client.py           | 207 ++++++++++++++++++
>  3 files changed, 209 insertions(+)
>  create mode 100755 tests/functional/x86_64/test_vfio_user_client.py
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1ae28e8804..9987ac8a4d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4305,6 +4305,7 @@ F: docs/system/devices/vfio-user.rst
>  F: hw/vfio-user/*
>  F: include/hw/vfio-user/*
>  F: subprojects/libvfio-user
> +F: tests/functional/x86_64/test_vfio_user_client.py
>  
>  EBPF:
>  M: Jason Wang <jasowang@redhat.com>
> diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/meson.build
> index d0b4667bb8..eed1936976 100644
> --- a/tests/functional/x86_64/meson.build
> +++ b/tests/functional/x86_64/meson.build
> @@ -31,6 +31,7 @@ tests_x86_64_system_thorough = [
>    'replay',
>    'reverse_debug',
>    'tuxrun',
> +  'vfio_user_client',
>    'virtio_balloon',
>    'virtio_gpu',
>  ]
> diff --git a/tests/functional/x86_64/test_vfio_user_client.py b/tests/functional/x86_64/test_vfio_user_client.py
> new file mode 100755
> index 0000000000..a9cb2f4621
> --- /dev/null
> +++ b/tests/functional/x86_64/test_vfio_user_client.py
> @@ -0,0 +1,207 @@


> +    def prepare_images(self):
> +        """Set up the images for the VMs."""
> +        self.kernel_path = self.ASSET_KERNEL.fetch()
> +        rootfs_path = self.ASSET_ROOTFS.fetch()
> +
> +        self.server_rootfs_path = self.scratch_file('server.ext2')
> +        shutil.copy(rootfs_path, self.server_rootfs_path)
> +        os.chmod(self.server_rootfs_path, 0o600)
> +        self.client_rootfs_path = self.scratch_file('client.ext2')
> +        shutil.copy(rootfs_path, self.client_rootfs_path)
> +        os.chmod(self.client_rootfs_path, 0o600)

So copying the read-only asset to a writable file in the scratchdir....

> +
> +    def configure_server_vm_args(self, server_vm, sock_path):
> +        """
> +        Configuration for the server VM. Set up virtio-serial device backed by
> +        the given socket path.
> +        """
> +        server_vm.add_args('-kernel', self.kernel_path)
> +        server_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
> +        server_vm.add_args('-drive',
> +            f"file={self.server_rootfs_path},if=ide,format=raw,id=drv0")
> +        server_vm.add_args('-snapshot')

..but here you're using -snapshot, so surely the copying of the asset
into the scratch dir is not required ?

> +        server_vm.add_args('-chardev',
> +            f"socket,id=sock0,path={sock_path},telnet=off,server=on,wait=off")
> +        server_vm.add_args('-device', 'virtio-serial')
> +        server_vm.add_args('-device',
> +            'virtserialport,chardev=sock0,name=org.fedoraproject.port.0')
> +
> +    def configure_client_vm_args(self, client_vm, sock_path):
> +        """
> +        Configuration for the client VM. Point the vfio-user-pci device to the
> +        socket path configured above.
> +        """
> +
> +        client_vm.add_args('-kernel', self.kernel_path)
> +        client_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
> +        client_vm.add_args('-drive',
> +            f'file={self.client_rootfs_path},if=ide,format=raw,id=drv0')

...but  no using of -snapshot here, so copying the asset would be
required?

Can we just use -snapshot in both cases & avoid the copying ?

> +        client_vm.add_args('-device',
> +            '{"driver":"vfio-user-pci",' +
> +            '"socket":{"path": "%s", "type": "unix"}}' % sock_path)
> +

> +    def setup_vfio_user_pci_server(self, server_vm):
> +        """
> +        Start the libvfio-user server within the server VM, and arrange
> +        for data to shuttle between its socket and the virtio serial port.
> +        """
> +        wait_for_console_pattern(self, 'login:', None, server_vm)
> +        exec_command_and_wait_for_pattern(self, 'root', '#', None, server_vm)
> +
> +        exec_command_and_wait_for_pattern(self,
> +            'gpio-pci-idio-16 -v /tmp/vfio-user.sock >/var/tmp/gpio.out 2>&1 &',
> +            '#', None, server_vm)
> +        # wait for libvfio-user to initialize properly
> +        exec_command_and_wait_for_pattern(self, 'sleep 5', '#', None, server_vm)
> +        exec_command_and_wait_for_pattern(self,
> +            'socat UNIX-CONNECT:/tmp/vfio-user.sock /dev/vport0p1,ignoreeof ' +
> +            ' &', '#', None, server_vm)

Hardcoded socket paths in /tmp ...

> +
> +    def test_vfio_user_pci(self):
> +        self.prepare_images()
> +        self.set_machine('pc')
> +        self.require_device('virtio-serial')
> +        self.require_device('vfio-user-pci')
> +
> +        sock_dir = self.socket_dir()
> +        socket_path = sock_dir.name + '/vfio-user.sock'
> +        socket_path = '/tmp/vfio-user.sock'

This isn't honouring the temporary dir for the socket files.
This temp dir needs to be passed into setup_vfio_user_pci_server

> +
> +        server_vm = self.get_vm(name='server')
> +        server_vm.set_console()
> +        self.configure_server_vm_args(server_vm, socket_path)
> +
> +        server_vm.launch()
> +
> +        self.log.debug('starting libvfio-user server')
> +
> +        self.setup_vfio_user_pci_server(server_vm)
> +
> +        client_vm = self.get_vm(name="client")
> +        client_vm.set_console()
> +        self.configure_client_vm_args(client_vm, socket_path)
> +
> +        try:
> +            client_vm.launch()
> +        except:
> +            self.log.error('client VM failed to start, dumping server logs')
> +            exec_command_and_wait_for_pattern(self, 'cat /var/tmp/gpio.out',
> +                '#', None, server_vm)
> +            raise
> +
> +        self.log.debug('waiting for client VM boot')
> +
> +        wait_for_console_pattern(self, 'login:', None, client_vm)
> +        exec_command_and_wait_for_pattern(self, 'root', '#', None, client_vm)
> +
> +        #
> +        # Here, we'd like to actually interact with the gpio device a little
> +        # more as described at:
> +        #
> +        # https://github.com/nutanix/libvfio-user/blob/master/docs/qemu.md
> +        #
> +        # Unfortunately, the buildroot Linux kernel has some undiagnosed issue
> +        # so we don't get /sys/class/gpio. Nonetheless just the basic
> +        # initialization and setup is enough for basic testing of vfio-user.
> +        #
> +
> +        self.log.debug('collecting libvfio-user server output')
> +
> +        out = exec_command_and_wait_for_pattern(self,
> +            'cat /var/tmp/gpio.out',
> +            'gpio: region2: wrote 0 to (0x1:1)',
> +            None, server_vm)
> +
> +        pattern = re.compile(r'^gpio:')

Use of 're' is overkill here...

> +
> +        gpio_server_out = [s for s in out.decode().splitlines()
> +                                   if pattern.search(s)]

......  as this can just use s.startswith("gpio:")

> +
> +        for line in EXPECTED_SERVER_LINES:
> +            if line not in gpio_server_out:
> +                self.log.error(f'Missing server debug line: {line}')
> +                self.fail(False)
> +
> +
> +if __name__ == '__main__':
> +    QemuSystemTest.main()
> -- 
> 2.43.0
> 

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  reply	other threads:[~2025-09-08 14:44 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-03 20:19 [PATCH v4 0/3] vfio-user client functional test John Levon
2025-09-03 20:19 ` [PATCH v4 1/3] tests/functional: return output from cmd.py helpers John Levon
2025-09-08 14:32   ` Daniel P. Berrangé
2025-09-03 20:19 ` [PATCH v4 2/3] tests/functional: add vm param to " John Levon
2025-09-08 14:33   ` Daniel P. Berrangé
2025-09-03 20:19 ` [PATCH v4 3/3] tests/functional: add a vfio-user smoke test John Levon
2025-09-08 14:42   ` Daniel P. Berrangé [this message]
2025-09-09 14:44     ` John Levon
2025-09-09 13:58 ` [PATCH v4 0/3] vfio-user client functional test Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aL7rW6Tq9d-z8sGL@redhat.com \
    --to=berrange@redhat.com \
    --cc=clg@redhat.com \
    --cc=john.levon@nutanix.com \
    --cc=mark.caveayland@nutanix.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=thanos.makatos@nutanix.com \
    --cc=thuth@redhat.com \
    --cc=zhao1.liu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).