qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Acceptance test: Migration mechanism with FD
@ 2020-02-26 11:57 Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 1/3] python/qemu/machine: Adding functions _send_fds and _recv_fds Oksana Vohchana
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Oksana Vohchana @ 2020-02-26 11:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: ovoshcha, philmd, ehabkost, wainersm, crosa

To test migration through the file descriptor we should build and provide
a path to socket_scm_helper file. This way is inconvenient for acceptance
testing.
This series provides new functions to receive and send messages over a UNIX
socket. And adds a new migration test that depends on it

v2:
 -  Fix warning of line over 80 characters

v3:
 - Improve commit messages

Oksana Vohchana (3):
  python/qemu/machine: Adding functions _send_fds and _recv_fds
  python/qemu/machine: Updates send_fd_scm function
  Acceptance test: add FD migration

 python/qemu/machine.py        | 88 +++++++++++++++++++++++++----------
 tests/acceptance/migration.py | 21 +++++++++
 2 files changed, 85 insertions(+), 24 deletions(-)

-- 
2.21.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/3] python/qemu/machine: Adding functions _send_fds and _recv_fds
  2020-02-26 11:57 [PATCH v3 0/3] Acceptance test: Migration mechanism with FD Oksana Vohchana
@ 2020-02-26 11:57 ` Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 2/3] python/qemu/machine: Updates send_fd_scm function Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 3/3] Acceptance test: add FD migration Oksana Vohchana
  2 siblings, 0 replies; 4+ messages in thread
From: Oksana Vohchana @ 2020-02-26 11:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: ovoshcha, philmd, ehabkost, wainersm, crosa

To pass the fd via SCM_RIGHT we should use socket_scm_helper file. And the
path to it file should be provided on starting the virtual machine.
For acceptance tests, this is not convenient, but sometimes not possible to
get this binary file during the testing.
This patch provides new possibilities to send or receive data through the
Unix domain socket file descriptor.
This is useful for obtaining a socket that belongs to a different
network namespace.

Signed-off-by: Oksana Vohchana <ovoshcha@redhat.com>
---
 python/qemu/machine.py | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 183d8f3d38..976316e5f5 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -24,6 +24,7 @@ import subprocess
 import shutil
 import socket
 import tempfile
+import array
 
 from . import qmp
 
@@ -155,6 +156,29 @@ class QEMUMachine(object):
         self._args.append(','.join(options))
         return self
 
+    def _recv_fds(self, sock, msglen=8192, maxfds=4096):
+        """
+        Function from:
+        https://docs.python.org/3/library/socket.html#socket.socket.recvmsg
+        """
+        fds = array.array("i")
+        msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(
+            maxfds * fds.itemsize))
+        for cmsg_level, cmsg_type, cmsg_data in ancdata:
+            if (cmsg_level == socket.SOL_SOCKET and
+                    cmsg_type == socket.SCM_RIGHTS):
+                fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data)
+                    % fds.itemsize)])
+        return msg, list(fds)
+
+    def _send_fds(self, sock, msg, fds):
+        """
+        Function from:
+        https://docs.python.org/3/library/socket.html#socket.socket.sendmsg
+        """
+        return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
+                                      array.array("i", fds))])
+
     def send_fd_scm(self, fd=None, file_path=None):
         """
         Send an fd or file_path to socket_scm_helper.
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/3] python/qemu/machine: Updates send_fd_scm function
  2020-02-26 11:57 [PATCH v3 0/3] Acceptance test: Migration mechanism with FD Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 1/3] python/qemu/machine: Adding functions _send_fds and _recv_fds Oksana Vohchana
@ 2020-02-26 11:57 ` Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 3/3] Acceptance test: add FD migration Oksana Vohchana
  2 siblings, 0 replies; 4+ messages in thread
From: Oksana Vohchana @ 2020-02-26 11:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: ovoshcha, philmd, ehabkost, wainersm, crosa

This patch upgrades the send_fd_scm function to use it in way if not provide
socket_scm_helper. It uses new provided functions  _send_fds and _recv_fds that
depend on FD's and data that allow us to send a file/socket descriptor
(with access and permissions) from one process to another.
The parameter data include qmp message like getfd or add-fd.

Signed-off-by: Oksana Vohchana <ovoshcha@redhat.com>
---
 python/qemu/machine.py | 64 ++++++++++++++++++++++++++----------------
 1 file changed, 40 insertions(+), 24 deletions(-)

diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 976316e5f5..906ca118db 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -179,20 +179,27 @@ class QEMUMachine(object):
         return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
                                       array.array("i", fds))])
 
-    def send_fd_scm(self, fd=None, file_path=None):
+    def send_fd_scm(self, fd=None, file_path=None, data=None):
         """
-        Send an fd or file_path to socket_scm_helper.
+        Can be used in two different cases.
+        Send an fd or file_path to socket_scm_helper or
+        provide data and fd to send it to the socket.
 
-        Exactly one of fd and file_path must be given.
-        If it is file_path, the helper will open that file and pass its own fd.
+        Exactly one of fd and file_path must be given to the case of
+        socket_scm_helper. If it is file_path, the helper will open that file
+        and pass its own fd.
+
+        To second case need adds data that include a QMP request and fd
         """
         # In iotest.py, the qmp should always use unix socket.
         assert self._qmp.is_scm_available()
-        if self._socket_scm_helper is None:
-            raise QEMUMachineError("No path to socket_scm_helper set")
-        if not os.path.exists(self._socket_scm_helper):
-            raise QEMUMachineError("%s does not exist" %
-                                   self._socket_scm_helper)
+        if data is None:
+            if self._socket_scm_helper is None:
+                raise QEMUMachineError(
+                    "No path to socket_scm_helper set or data provided")
+            if not os.path.exists(self._socket_scm_helper):
+                raise QEMUMachineError("%s does not exist" %
+                                       self._socket_scm_helper)
 
         # This did not exist before 3.4, but since then it is
         # mandatory for our purpose
@@ -201,24 +208,33 @@ class QEMUMachine(object):
             if fd is not None:
                 os.set_inheritable(fd, True)
 
-        fd_param = ["%s" % self._socket_scm_helper,
-                    "%d" % self._qmp.get_sock_fd()]
+        if data is None:
+            fd_param = ["%s" % self._socket_scm_helper,
+                        "%d" % self._qmp.get_sock_fd()]
+            if file_path is not None:
+                assert fd is None
+                fd_param.append(file_path)
+            else:
+                assert fd is not None
+                fd_param.append(str(fd))
 
-        if file_path is not None:
-            assert fd is None
-            fd_param.append(file_path)
-        else:
-            assert fd is not None
-            fd_param.append(str(fd))
+            devnull = open(os.path.devnull, 'rb')
+            proc = subprocess.Popen(fd_param, stdin=devnull,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT, close_fds=False)
+            output = proc.communicate()[0]
+            if output:
+                LOG.debug(output)
 
-        devnull = open(os.path.devnull, 'rb')
-        proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT, close_fds=False)
-        output = proc.communicate()[0]
-        if output:
-            LOG.debug(output)
+            return proc.returncode
 
-        return proc.returncode
+        else:
+            sock_fd = socket.fromfd(self._qmp.get_sock_fd(), socket.AF_UNIX,
+                                    socket.SOCK_STREAM)
+            fds_param = [fd, self._qmp.get_sock_fd()]
+            self._send_fds(sock_fd, data, fds_param)
+            self._recv_fds(sock_fd)
+            return self
 
     @staticmethod
     def _remove_if_exists(path):
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 3/3] Acceptance test: add FD migration
  2020-02-26 11:57 [PATCH v3 0/3] Acceptance test: Migration mechanism with FD Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 1/3] python/qemu/machine: Adding functions _send_fds and _recv_fds Oksana Vohchana
  2020-02-26 11:57 ` [PATCH v3 2/3] python/qemu/machine: Updates send_fd_scm function Oksana Vohchana
@ 2020-02-26 11:57 ` Oksana Vohchana
  2 siblings, 0 replies; 4+ messages in thread
From: Oksana Vohchana @ 2020-02-26 11:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: ovoshcha, philmd, ehabkost, wainersm, crosa

The patch adds a new type of migration test through the file descriptor.

Signed-off-by: Oksana Vohchana <ovoshcha@redhat.com>
---
 tests/acceptance/migration.py | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/tests/acceptance/migration.py b/tests/acceptance/migration.py
index a8367ca023..7f4879ce5d 100644
--- a/tests/acceptance/migration.py
+++ b/tests/acceptance/migration.py
@@ -10,7 +10,10 @@
 # later.  See the COPYING file in the top-level directory.
 
 
+import os
 import tempfile
+from socket import socketpair, AF_UNIX, SOCK_STREAM
+
 from avocado_qemu import Test
 from avocado import skipUnless
 
@@ -75,3 +78,21 @@ class Migration(Test):
         """
         free_port = self._get_free_port()
         dest_uri = 'exec:nc -l localhost %u' % free_port
+
+    def test_migration_with_fd(self):
+        opaque = 'fd-migration'
+        data_to_send = b"{\"execute\": \"getfd\",  \"arguments\": \
+                        {\"fdname\": \"fd-migration\"}}"
+        send_socket, recv_socket = socketpair(AF_UNIX, SOCK_STREAM)
+        fd1 = send_socket.fileno()
+        fd2 = recv_socket.fileno()
+        os.set_inheritable(fd2, True)
+
+        source_vm = self.get_vm()
+        source_vm.launch()
+        source_vm.send_fd_scm(fd=fd1, data=data_to_send)
+
+        dest_vm = self.get_vm('-incoming', 'fd:%s' % fd2)
+        dest_vm.launch()
+        source_vm.qmp('migrate', uri='fd:%s' % opaque)
+        self.assert_migration(source_vm, dest_vm)
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-02-26 12:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-02-26 11:57 [PATCH v3 0/3] Acceptance test: Migration mechanism with FD Oksana Vohchana
2020-02-26 11:57 ` [PATCH v3 1/3] python/qemu/machine: Adding functions _send_fds and _recv_fds Oksana Vohchana
2020-02-26 11:57 ` [PATCH v3 2/3] python/qemu/machine: Updates send_fd_scm function Oksana Vohchana
2020-02-26 11:57 ` [PATCH v3 3/3] Acceptance test: add FD migration Oksana Vohchana

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).