public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Andrea Bolognani <abologna@redhat.com>
To: passt-dev@passt.top
Subject: [PATCH] qrap: Support JSON syntax for -device
Date: Thu, 20 Oct 2022 11:04:19 +0200	[thread overview]
Message-ID: <20221020090419.820559-1-abologna@redhat.com> (raw)

Starting with version 8.1.0, libvirt uses JSON syntax when
generating the arguments to -device, so they will now look like

  {"driver":"virtio-scsi-pci","bus":"pci.3","addr":"0x0"}

instead of

  virtio-scsi-pci,bus=pci.3,addr=0x0

qrap needs to parse these arguments and extract the bus number
in order to figure out what address to use for the virtio-net
device it adds, and the libvirt change described above has
broken this parsing logic.

Tweak the code so that both styles are accepted and handled
correctly.

Note that, when JSON is in use, qrap needs to generate its own
command line options in that format as well or things will not
work as expected.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
 qrap.c | 51 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/qrap.c b/qrap.c
index a9a0fc1..3c6f5b8 100644
--- a/qrap.c
+++ b/qrap.c
@@ -69,6 +69,8 @@ static const struct drop_arg {
  * @name:		Device ("-device") name to insert
  * @template:		Prefix for device specification (first part of address)
  * @template_post:	Suffix for device specification (last part of address)
+ * @template_json:		Device prefix for when JSON is used
+ * @template_json_post:	Device suffix for when JSON is used
  * @first:		First usable PCI address
  * @last:		Last usable PCI address
  */
@@ -77,15 +79,29 @@ static const struct pci_dev {
 	char *name;
 	char *template;
 	char *template_post;
+	char *template_json;
+	char *template_json_post;
 	int first;
 	int last;
 } pci_devs[] = {
-	{ "pc-q35",	"virtio-net-pci",
-		"bus=pci.", ",addr=0x0",	3, /* 2: hotplug bus */	16 },
-	{ "pc-",	"virtio-net-pci",
-		"bus=pci.0,addr=0x", "",	2, /* 1: ISA bridge */	16 },
-	{ "s390-ccw",	"virtio-net-ccw",
-		"devno=fe.0.", "",		1,			16 },
+	{
+		"pc-q35", "virtio-net-pci",
+		"bus=pci.", ",addr=0x0",
+		"\"bus\":\"pci.", ",\"addr\":\"0x0\"",
+		3, /* 2: hotplug bus */ 16
+	},
+	{
+		"pc-", "virtio-net-pci",
+		"bus=pci.0,addr=0x", "",
+		"\"bus\":\"pci.0\",\"addr=0x", "",
+		2, /* 1: ISA bridge */ 16
+	},
+	{
+		"s390-ccw", "virtio-net-ccw",
+		"devno=fe.0.", "",
+		"\"devno\":\"fe.0.", "",
+		1, 16
+	},
 	{ 0 },
 };
 
@@ -115,7 +131,7 @@ void usage(const char *name)
  */
 int main(int argc, char **argv)
 {
-	int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0, retry_on_reset, rc;
+	int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0, has_json = 0, retry_on_reset, rc;
 	struct timeval tv = { .tv_sec = 0, .tv_usec = (long)(500 * 1000) };
 	char *qemu_argv[ARG_MAX], dev_str[ARG_MAX];
 	struct sockaddr_un addr = {
@@ -227,14 +243,22 @@ int main(int argc, char **argv)
 		}
 
 		if (!strcmp(argv[i], "-device") && i + 1 < argc) {
+			char *template = NULL;
 			char *p;
 
 			has_dev = 1;
 
 			if ((p = strstr(argv[i + 1], dev->template))) {
+				template = dev->template;
+			} else if ((p = strstr(argv[i + 1], dev->template_json))) {
+				template = dev->template_json;
+				has_json = 1;
+			}
+
+			if (template) {
 				long n;
 
-				n = strtol(p + strlen(dev->template), NULL, 16);
+				n = strtol(p + strlen(template), NULL, 16);
 				if (!errno)
 					addr_map |= (1 << n);
 			}
@@ -254,8 +278,15 @@ int main(int argc, char **argv)
 
 	if (has_dev) {
 		qemu_argv[qemu_argc++] = "-device";
-		snprintf(dev_str, ARG_MAX, "%s,%s%x%s,netdev=hostnet0,x-txburst=4096",
-			 dev->name, dev->template, i, dev->template_post);
+		if (!has_json) {
+			snprintf(dev_str, ARG_MAX,
+			         "%s,%s%x%s,netdev=hostnet0,x-txburst=4096",
+			         dev->name, dev->template, i, dev->template_post);
+		} else {
+			snprintf(dev_str, ARG_MAX,
+			         "{\"driver\":\"%s\",%s%x\"%s,\"netdev\":\"hostnet0\",\"x-txburst\":4096}",
+			         dev->name, dev->template_json, i, dev->template_json_post);
+		}
 		qemu_argv[qemu_argc++] = dev_str;
 	}
 
-- 
@@ -69,6 +69,8 @@ static const struct drop_arg {
  * @name:		Device ("-device") name to insert
  * @template:		Prefix for device specification (first part of address)
  * @template_post:	Suffix for device specification (last part of address)
+ * @template_json:		Device prefix for when JSON is used
+ * @template_json_post:	Device suffix for when JSON is used
  * @first:		First usable PCI address
  * @last:		Last usable PCI address
  */
@@ -77,15 +79,29 @@ static const struct pci_dev {
 	char *name;
 	char *template;
 	char *template_post;
+	char *template_json;
+	char *template_json_post;
 	int first;
 	int last;
 } pci_devs[] = {
-	{ "pc-q35",	"virtio-net-pci",
-		"bus=pci.", ",addr=0x0",	3, /* 2: hotplug bus */	16 },
-	{ "pc-",	"virtio-net-pci",
-		"bus=pci.0,addr=0x", "",	2, /* 1: ISA bridge */	16 },
-	{ "s390-ccw",	"virtio-net-ccw",
-		"devno=fe.0.", "",		1,			16 },
+	{
+		"pc-q35", "virtio-net-pci",
+		"bus=pci.", ",addr=0x0",
+		"\"bus\":\"pci.", ",\"addr\":\"0x0\"",
+		3, /* 2: hotplug bus */ 16
+	},
+	{
+		"pc-", "virtio-net-pci",
+		"bus=pci.0,addr=0x", "",
+		"\"bus\":\"pci.0\",\"addr=0x", "",
+		2, /* 1: ISA bridge */ 16
+	},
+	{
+		"s390-ccw", "virtio-net-ccw",
+		"devno=fe.0.", "",
+		"\"devno\":\"fe.0.", "",
+		1, 16
+	},
 	{ 0 },
 };
 
@@ -115,7 +131,7 @@ void usage(const char *name)
  */
 int main(int argc, char **argv)
 {
-	int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0, retry_on_reset, rc;
+	int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0, has_json = 0, retry_on_reset, rc;
 	struct timeval tv = { .tv_sec = 0, .tv_usec = (long)(500 * 1000) };
 	char *qemu_argv[ARG_MAX], dev_str[ARG_MAX];
 	struct sockaddr_un addr = {
@@ -227,14 +243,22 @@ int main(int argc, char **argv)
 		}
 
 		if (!strcmp(argv[i], "-device") && i + 1 < argc) {
+			char *template = NULL;
 			char *p;
 
 			has_dev = 1;
 
 			if ((p = strstr(argv[i + 1], dev->template))) {
+				template = dev->template;
+			} else if ((p = strstr(argv[i + 1], dev->template_json))) {
+				template = dev->template_json;
+				has_json = 1;
+			}
+
+			if (template) {
 				long n;
 
-				n = strtol(p + strlen(dev->template), NULL, 16);
+				n = strtol(p + strlen(template), NULL, 16);
 				if (!errno)
 					addr_map |= (1 << n);
 			}
@@ -254,8 +278,15 @@ int main(int argc, char **argv)
 
 	if (has_dev) {
 		qemu_argv[qemu_argc++] = "-device";
-		snprintf(dev_str, ARG_MAX, "%s,%s%x%s,netdev=hostnet0,x-txburst=4096",
-			 dev->name, dev->template, i, dev->template_post);
+		if (!has_json) {
+			snprintf(dev_str, ARG_MAX,
+			         "%s,%s%x%s,netdev=hostnet0,x-txburst=4096",
+			         dev->name, dev->template, i, dev->template_post);
+		} else {
+			snprintf(dev_str, ARG_MAX,
+			         "{\"driver\":\"%s\",%s%x\"%s,\"netdev\":\"hostnet0\",\"x-txburst\":4096}",
+			         dev->name, dev->template_json, i, dev->template_json_post);
+		}
 		qemu_argv[qemu_argc++] = dev_str;
 	}
 
-- 
2.37.3


             reply	other threads:[~2022-10-20  9:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-20  9:04 Andrea Bolognani [this message]
2022-10-22  8:19 ` [PATCH] qrap: Support JSON syntax for -device Stefano Brivio
2022-10-24 10:08   ` Andrea Bolognani
2022-10-24 12:12     ` Stefano Brivio

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=20221020090419.820559-1-abologna@redhat.com \
    --to=abologna@redhat.com \
    --cc=passt-dev@passt.top \
    /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.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

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 IMAP folder(s).