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