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:26 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1722634602.git.mchehab+huawei@kernel.org>
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
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-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
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-06 9:15 ` Shiju Jose
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-06 11:13 ` Shiju Jose
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 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-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
[not found] ` <CAFn=p-bM3oECXtPt5zVZSh53dJx+TDciU_N+vCW4Xp-Jd0MaHw@mail.gmail.com>
2024-08-08 21:51 ` Mauro Carvalho Chehab
[not found] ` <CAFn=p-Y27zap1P5G3NibdZS26iGwCqh8U0vgW0Vw31f53+oU1w@mail.gmail.com>
2024-08-08 22:41 ` Mauro Carvalho Chehab
2024-08-09 6:26 ` Mauro Carvalho Chehab [this message]
2024-08-09 7:37 ` Mauro Carvalho Chehab
[not found] ` <CAFn=p-ZM8cgKvUx+5v7YU6TaPZySJL1QnHqjmN5rQpF=D_V=8Q@mail.gmail.com>
2024-08-09 8:24 ` 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox