From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
To: John Snow <jsnow@redhat.com>
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>,
Shiju Jose <shiju.jose@huawei.com>,
Cleber Rosa <crosa@redhat.com>,
linux-kernel@vger.kernel.org, qemu-devel@nongnu.org
Subject: Re: [PATCH v5 7/7] scripts/ghes_inject: add a script to generate GHES error inject
Date: Fri, 9 Aug 2024 08:26:09 +0200 [thread overview]
Message-ID: <20240809082609.1864eabe@foz.lan> (raw)
In-Reply-To: <20240809004137.01f97da2@foz.lan>
Em Fri, 9 Aug 2024 00:41:37 +0200
Mauro Carvalho Chehab <mchehab+huawei@kernel.org> escreveu:
> > You should be able to use e.g.
> >
> > legacy.py's QEMUMonitorProtocol class for synchronous connections, e.g.
> >
> > from qemu.qmp.legacy import QEMUMonitorProtocol
> >
> > qmp = QEMUMonitorProtocol((host, port))
> > qmp.connect(negotiate=True)
>
> That sounds interesting! I give it a try.
I applied the enclosed patch at the end of my patch series, but
somehow it is not working. For whatever reason, connect() is
raising a StateError apparently due to Runstate.CONNECTING.
I tried both as declaring (see enclosed patch):
class qmp(QEMUMonitorProtocol)
and using:
- super().__init__(self.host, self.port)
+ self.qmp_monitor = QEMUMonitorProtocol(self.host, self.port)
On both cases, it keeps waiting forever for a connection.
Regards,
Mauro
---
diff --git a/scripts/qmp_helper.py b/scripts/qmp_helper.py
index e9e9388bcb8b..62ca267cdc87 100644
--- a/scripts/qmp_helper.py
+++ b/scripts/qmp_helper.py
@@ -9,9 +9,23 @@
import socket
import sys
+from os import path
+
+try:
+ qemu_dir = path.abspath(path.dirname(path.dirname(__file__)))
+ sys.path.append(path.join(qemu_dir, 'python'))
+
+ from qemu.qmp.legacy import QEMUMonitorProtocol
+ from qemu.qmp.protocol import StateError
+
+except ModuleNotFoundError as exc:
+ print(f"Module '{exc.name}' not found.")
+ print("Try export PYTHONPATH=top-qemu-dir/python or run from top-qemu-dir")
+ sys.exit(1)
+
from base64 import b64encode
-class qmp:
+class qmp(QEMUMonitorProtocol):
"""
Opens a connection and send/receive QMP commands.
"""
@@ -21,22 +35,20 @@ def send_cmd(self, command, may_open=False,return_error=True):
if may_open:
self._connect()
- elif not self.socket:
- return None
+ elif not self.connected:
+ return False
if isinstance(command, dict):
data = json.dumps(command).encode("utf-8")
else:
data = command.encode("utf-8")
- self.socket.sendall(data)
- data = self.socket.recv(1024)
try:
- obj = json.loads(data.decode("utf-8"))
- except json.JSONDecodeError as e:
- print(f"Invalid QMP answer: {e}")
- self._close()
- return None
+ obj = self.cmd_obj(command)
+ except Exception as e:
+ print("Failed to inject error: {e}.")
+
+ print(obj)
if "return" in obj:
if isinstance(obj.get("return"), dict):
@@ -46,86 +58,47 @@ def send_cmd(self, command, may_open=False,return_error=True):
else:
return obj["return"]
- elif isinstance(obj.get("error"), dict):
- error = obj["error"]
- if return_error:
- print(f'{error["class"]}: {error["desc"]}')
- else:
- print(json.dumps(obj))
-
return None
def _close(self):
"""Shutdown and close the socket, if opened"""
- if not self.socket:
+ if not self.connected:
return
- self.socket.shutdown(socket.SHUT_WR)
- while 1:
- data = self.socket.recv(1024)
- if data == b"":
- break
- try:
- obj = json.loads(data.decode("utf-8"))
- except json.JSONDecodeError as e:
- print(f"Invalid QMP answer: {e}")
- self.socket.close()
- self.socket = None
- return
-
- if isinstance(obj.get("return"), dict):
- print(json.dumps(obj["return"]))
- if isinstance(obj.get("error"), dict):
- error = obj["error"]
- print(f'{error["class"]}: {error["desc"]}')
- else:
- print(json.dumps(obj))
-
- self.socket.close()
- self.socket = None
+ self.close()
+ self.connected = False
def _connect(self):
"""Connect to a QMP TCP/IP port, if not connected yet"""
- if self.socket:
+ if self.connected:
return True
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- self.socket.connect((self.host, self.port))
- except ConnectionRefusedError:
- sys.exit(f"Can't connect to QMP host {self.host}:{self.port}")
-
- data = self.socket.recv(1024)
- try:
- obj = json.loads(data.decode("utf-8"))
- except json.JSONDecodeError as e:
- print(f"Invalid QMP answer: {e}")
- self._close()
- return False
-
- if "QMP" not in obj:
- print(f"Invalid QMP answer: {data.decode('utf-8')}")
- self._close()
- return False
+ is_connecting = True
+ while is_connecting:
+ try:
+ ret = self.connect(negotiate=True)
+ self.accept()
+ is_connecting = False
+ except ConnectionError:
+ sys.exit(f"Can't connect to QMP host {self.host}:{self.port}")
+ return False
+ except StateError as e:
+ print(f"StateError: {e}")
- result = self.send_cmd('{ "execute": "qmp_capabilities" }')
- if not result:
- self._close()
- return False
+ self.connected = True
return True
def __init__(self, host, port, debug=False):
"""Initialize variables used by the QMP send logic"""
- self.socket = None
+ self.connected = False
self.host = host
self.port = port
self.debug = debug
- def __del__(self):
- self._close()
+ super().__init__(self.host, self.port)
#
# Socket QMP send command
@@ -168,8 +141,12 @@ def send_cper(self, guid, data):
self._connect()
- if self.send_cmd(command):
- print("Error injected.")
+ try:
+ self.cmd_obj(command)
+ except Exception as e:
+ print("Failed to inject error: {e}.")
+
+ print("Error injected.")
def search_qom(self, path, prop, regex):
"""
@@ -180,8 +157,9 @@ def search_qom(self, path, prop, regex):
...
"""
- found = []
+ self._connect()
+ found = []
i = 0
while 1:
dev = f"{path}[{i}]"
@@ -192,7 +170,11 @@ def search_qom(self, path, prop, regex):
'property': prop
}
}
- ret = self.send_cmd(cmd, may_open=True, return_error=False)
+ try:
+ ret = self.cmd_obj(cmd)
+ except Exception as e:
+ print("Failed to inject error: {e}.")
+
if not ret:
break
Thanks,
Mauro
next prev parent reply other threads:[~2024-08-09 6:27 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-02 21:43 [PATCH v5 0/7] Add ACPI CPER firmware first error injection on ARM emulation Mauro Carvalho Chehab
2024-08-02 21:43 ` [PATCH v5 1/7] arm/virt: place power button pin number on a define Mauro Carvalho Chehab
2024-08-06 8:57 ` Igor Mammedov
2024-08-02 21:43 ` [PATCH v5 2/7] acpi/generic_event_device: add an APEI error device Mauro Carvalho Chehab
2024-08-05 16:39 ` Jonathan Cameron via
2024-08-05 16:39 ` Jonathan Cameron
2024-08-06 5:50 ` Mauro Carvalho Chehab
2024-08-06 8:54 ` Igor Mammedov
2024-08-02 21:43 ` [PATCH v5 3/7] arm/virt: Wire up GPIO error source for ACPI / GHES Mauro Carvalho Chehab
2024-08-05 16:54 ` Jonathan Cameron
2024-08-05 16:54 ` Jonathan Cameron via
2024-08-06 5:56 ` Mauro Carvalho Chehab
2024-08-06 9:15 ` Igor Mammedov
2024-08-02 21:43 ` [PATCH v5 4/7] acpi/ghes: Support GPIO error source Mauro Carvalho Chehab
2024-08-05 16:56 ` Jonathan Cameron via
2024-08-05 16:56 ` Jonathan Cameron
2024-08-05 16:56 ` Jonathan Cameron via
2024-08-06 6:09 ` Mauro Carvalho Chehab
2024-08-06 9:18 ` Igor Mammedov
2024-08-06 9:32 ` Igor Mammedov
2024-08-07 7:15 ` Mauro Carvalho Chehab
2024-08-02 21:44 ` [PATCH v5 5/7] qapi/ghes-cper: add an interface to do generic CPER error injection Mauro Carvalho Chehab
2024-08-05 17:00 ` Jonathan Cameron
2024-08-05 17:00 ` Jonathan Cameron via
2024-08-06 9:15 ` Shiju Jose
2024-08-06 9:15 ` Shiju Jose via
2024-08-06 12:51 ` Igor Mammedov
2024-08-06 12:58 ` Mauro Carvalho Chehab
2024-08-08 8:50 ` Markus Armbruster
2024-08-08 14:11 ` Mauro Carvalho Chehab
2024-08-08 14:22 ` Igor Mammedov
2024-08-08 14:45 ` Markus Armbruster
2024-08-09 8:42 ` Mauro Carvalho Chehab
2024-08-02 21:44 ` [PATCH v5 6/7] acpi/ghes: add support for generic error injection via QAPI Mauro Carvalho Chehab
2024-08-05 17:03 ` Jonathan Cameron
2024-08-05 17:03 ` Jonathan Cameron via
2024-08-06 11:13 ` Shiju Jose
2024-08-06 11:13 ` Shiju Jose via
2024-08-06 14:31 ` Igor Mammedov
2024-08-07 7:47 ` Mauro Carvalho Chehab
2024-08-07 9:34 ` Jonathan Cameron
2024-08-07 9:34 ` Jonathan Cameron via
2024-08-07 13:23 ` Mauro Carvalho Chehab
2024-08-07 13:43 ` Igor Mammedov
2024-08-07 13:28 ` Igor Mammedov
2024-08-07 14:25 ` Jonathan Cameron
2024-08-07 14:25 ` Jonathan Cameron via
2024-08-08 8:11 ` Igor Mammedov
2024-08-08 18:19 ` Mauro Carvalho Chehab
2024-08-12 9:39 ` Igor Mammedov
2024-08-13 18:59 ` Mauro Carvalho Chehab
2024-08-08 12:11 ` Mauro Carvalho Chehab
2024-08-08 12:45 ` Igor Mammedov
2024-08-02 21:44 ` [PATCH v5 7/7] scripts/ghes_inject: add a script to generate GHES error inject Mauro Carvalho Chehab
2024-08-06 14:56 ` Igor Mammedov
2024-08-08 20:58 ` John Snow
2024-08-08 21:51 ` Mauro Carvalho Chehab
2024-08-08 21:21 ` John Snow
2024-08-08 22:41 ` Mauro Carvalho Chehab
2024-08-08 23:33 ` John Snow
2024-08-09 8:24 ` Mauro Carvalho Chehab
2024-08-09 19:26 ` John Snow
2024-08-09 6:26 ` Mauro Carvalho Chehab [this message]
2024-08-09 7:37 ` Mauro Carvalho Chehab
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=20240809082609.1864eabe@foz.lan \
--to=mchehab+huawei@kernel.org \
--cc=Jonathan.Cameron@huawei.com \
--cc=crosa@redhat.com \
--cc=jsnow@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
--cc=shiju.jose@huawei.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.