From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
Eduardo Habkost <ehabkost@redhat.com>,
qemu-block@nongnu.org, Hanna Reitz <hreitz@redhat.com>,
Cleber Rosa <crosa@redhat.com>, John Snow <jsnow@redhat.com>
Subject: [PATCH v2 09/17] python/qmp: add send_fd_scm directly to QEMUMonitorProtocol
Date: Wed, 22 Sep 2021 20:49:30 -0400 [thread overview]
Message-ID: <20210923004938.3999963-10-jsnow@redhat.com> (raw)
In-Reply-To: <20210923004938.3999963-1-jsnow@redhat.com>
It turns out you can do this directly from Python ... and because of
this, you don't need to worry about setting the inheritability of the
fds or spawning another process.
Doing this is helpful because it allows QEMUMonitorProtocol to keep its
file descriptor and socket object as private implementation
details. /that/ is helpful in turn because it allows me to write a
compatible, alternative implementation.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
---
python/qemu/machine/machine.py | 44 +++++++---------------------------
python/qemu/qmp/__init__.py | 21 +++++++---------
2 files changed, 18 insertions(+), 47 deletions(-)
diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index ae945ca3c94..1c6532a3d68 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -213,48 +213,22 @@ def add_fd(self: _T, fd: int, fdset: int,
def send_fd_scm(self, fd: Optional[int] = None,
file_path: Optional[str] = None) -> int:
"""
- Send an fd or file_path to socket_scm_helper.
+ Send an fd or file_path to the remote via SCM_RIGHTS.
- 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. If it is
+ file_path, the file will be opened read-only and the new file
+ descriptor will be sent to the remote.
"""
- # 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)
-
- # This did not exist before 3.4, but since then it is
- # mandatory for our purpose
- if hasattr(os, 'set_inheritable'):
- os.set_inheritable(self._qmp.get_sock_fd(), True)
- if fd is not None:
- os.set_inheritable(fd, True)
-
- 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)
+ with open(file_path, "rb") as passfile:
+ fd = passfile.fileno()
+ self._qmp.send_fd_scm(fd)
else:
assert fd is not None
- fd_param.append(str(fd))
+ self._qmp.send_fd_scm(fd)
- proc = subprocess.run(
- fd_param,
- stdin=subprocess.DEVNULL,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- check=False,
- close_fds=False,
- )
- if proc.stdout:
- LOG.debug(proc.stdout)
-
- return proc.returncode
+ return 0
@staticmethod
def _remove_if_exists(path: str) -> None:
diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py
index c27594b66a2..358c0971d06 100644
--- a/python/qemu/qmp/__init__.py
+++ b/python/qemu/qmp/__init__.py
@@ -21,6 +21,7 @@
import json
import logging
import socket
+import struct
from types import TracebackType
from typing import (
Any,
@@ -408,18 +409,14 @@ def settimeout(self, timeout: Optional[float]) -> None:
raise ValueError(msg)
self.__sock.settimeout(timeout)
- def get_sock_fd(self) -> int:
+ def send_fd_scm(self, fd: int) -> None:
"""
- Get the socket file descriptor.
-
- @return The file descriptor number.
- """
- return self.__sock.fileno()
-
- def is_scm_available(self) -> bool:
+ Send a file descriptor to the remote via SCM_RIGHTS.
"""
- Check if the socket allows for SCM_RIGHTS.
+ if self.__sock.family != socket.AF_UNIX:
+ raise RuntimeError("Can't use SCM_RIGHTS on non-AF_UNIX socket.")
- @return True if SCM_RIGHTS is available, otherwise False.
- """
- return self.__sock.family == socket.AF_UNIX
+ self.__sock.sendmsg(
+ [b' '],
+ [(socket.SOL_SOCKET, socket.SCM_RIGHTS, struct.pack('@i', fd))]
+ )
--
2.31.1
next prev parent reply other threads:[~2021-09-23 0:57 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-23 0:49 [PATCH v2 00/17] Switch iotests to using Async QMP John Snow
2021-09-23 0:49 ` [PATCH v2 01/17] python/aqmp: add greeting property to QMPClient John Snow
2021-09-23 0:49 ` [PATCH v2 02/17] python/aqmp: add .empty() method to EventListener John Snow
2021-09-23 0:49 ` [PATCH v2 03/17] python/aqmp: Return cleared events from EventListener.clear() John Snow
2021-09-23 0:49 ` [PATCH v2 04/17] python/aqmp: add send_fd_scm John Snow
2021-10-07 14:52 ` Eric Blake
2021-10-07 16:27 ` John Snow
2021-10-07 21:46 ` Eric Blake
2021-09-23 0:49 ` [PATCH v2 05/17] python/aqmp: Add dict conversion method to Greeting object John Snow
2021-10-07 14:53 ` Eric Blake
2021-09-23 0:49 ` [PATCH v2 06/17] python/aqmp: Reduce severity of EOFError-caused loop terminations John Snow
2021-10-07 14:55 ` Eric Blake
2021-09-23 0:49 ` [PATCH v2 07/17] python/aqmp: Disable logging messages by default John Snow
2021-10-07 15:02 ` Eric Blake
2021-09-23 0:49 ` [PATCH v2 08/17] python/qmp: clear events on get_events() call John Snow
2021-09-23 0:49 ` John Snow [this message]
2021-09-23 0:49 ` [PATCH v2 10/17] python, iotests: remove socket_scm_helper John Snow
2021-09-23 0:49 ` [PATCH v2 11/17] python/machine: remove has_quit argument John Snow
2021-10-12 15:30 ` Hanna Reitz
2021-09-23 0:49 ` [PATCH v2 12/17] python/machine: Handle QMP errors on close more meticulously John Snow
2021-10-07 15:07 ` Eric Blake
2021-10-07 16:34 ` John Snow
2021-10-07 16:52 ` John Snow
2021-10-12 15:56 ` Hanna Reitz
2021-09-23 0:49 ` [PATCH v2 13/17] iotests: Accommodate async QMP Exception classes John Snow
2021-10-12 16:06 ` Hanna Reitz
2021-10-12 16:38 ` John Snow
2021-09-23 0:49 ` [PATCH v2 14/17] iotests: Conditionally silence certain AQMP errors John Snow
2021-09-23 0:49 ` [PATCH v2 15/17] python/aqmp: Create sync QMP wrapper for iotests John Snow
2021-10-06 10:13 ` Paolo Bonzini
2021-10-06 14:24 ` John Snow
2021-10-06 14:32 ` Paolo Bonzini
2021-10-06 15:12 ` John Snow
2021-09-23 0:49 ` [PATCH v2 16/17] python/aqmp: Remove scary message John Snow
2021-09-23 0:49 ` [PATCH v2 17/17] python, iotests: replace qmp with aqmp John Snow
2021-10-06 10:14 ` [PATCH v2 00/17] Switch iotests to using Async QMP Paolo Bonzini
2021-10-06 15:01 ` John Snow
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=20210923004938.3999963-10-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=crosa@redhat.com \
--cc=ehabkost@redhat.com \
--cc=hreitz@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vsementsov@virtuozzo.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).