From nobody Mon Feb 9 09:15:33 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1633624097; cv=none; d=zohomail.com; s=zohoarc; b=G0KDXawfiX+uKGoxBSHQYyH5uyJy2wCuPQe8ERc8bQZ4mVZ88zOJUBkU5vWxu9riilPvFGlu5EZxKC8mhJvWLaflPFovS2Y3mznWnEYAJmMHZHJ+mTWCFwezK6E6HCpUYollL2NYFx0nbwdH/huIUu5tZHIlBanzwSI14XuY984= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1633624097; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=dEZySIi5Xxml5JOdgKz66Y0CMy4KaTwmv+aquEhvZFA=; b=AfCxpKEf5xQLe9FXoRYtpaXkmndKV3Mrez1xfiMxh3mrq0T5QL9nQdKjTfI0xZx7yhAOvRb3qQINPr4kixCYbhfG/HMkfuzXeLZfdgTmSuhuAD1aeBRil6GIUAxcCU4Cjfrv9Ep9Pd49lT6WHznUx6z35KtrxG53ciGKV1jkEUY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1633624097487515.8717254836348; Thu, 7 Oct 2021 09:28:17 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-277-LuS03bmxNpSPudUKsOEJtQ-1; Thu, 07 Oct 2021 12:28:13 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 25EA31971B99; Thu, 7 Oct 2021 15:56:27 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E77FAA7AC; Thu, 7 Oct 2021 15:55:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B26211800B8B; Thu, 7 Oct 2021 15:55:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 197FL2sd024420 for ; Thu, 7 Oct 2021 11:21:02 -0400 Received: by smtp.corp.redhat.com (Postfix) id D2B215F4E7; Thu, 7 Oct 2021 15:21:02 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.40.208.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id 407475D6BA for ; Thu, 7 Oct 2021 15:21:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633624096; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=dEZySIi5Xxml5JOdgKz66Y0CMy4KaTwmv+aquEhvZFA=; b=TPdhstTOjpOIKqhSbPpf85oL6+8g3eN0tLVCuDp2JHC2r4OZdOWCNN57Zvn4el4SBjoz2a BnJ50uWy8c45yHcI6NPXu+bXU63JdBEK+kf4cMQyfAgXcNHlJVw1D/qV3hPcATmN6y1xsU lJj5Of1Pq2sqXnmvbSXBmy95NUk0eyA= X-MC-Unique: LuS03bmxNpSPudUKsOEJtQ-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 081/103] qemuBuildInterfaceCommandLine: Generate via JSON Date: Thu, 7 Oct 2021 17:18:09 +0200 Message-Id: <8ab9b4d741e51ab016ea9830b694b71f7bcc94e5.1633619630.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1633624099107100001 Content-Type: text/plain; charset="utf-8" virtio-net-pci specific properties and their types according to QEMU: tx=3D ioeventfd=3D - on/off (default: true) event_idx=3D - on/off (default: true) csum=3D - on/off (default: true) gso=3D - on/off (default: true) host_tso4=3D - on/off (default: true) host_tso6=3D - on/off (default: true) host_ecn=3D - on/off (default: true) host_ufo=3D - on/off (default: true) mrg_rxbuf=3D - on/off (default: true) guest_csum=3D - on/off (default: true) guest_tso4=3D - on/off (default: true) guest_tso6=3D - on/off (default: true) guest_ecn=3D - on/off (default: true) guest_ufo=3D - on/off (default: true) mq=3D - on/off (default: false) vectors=3D - (default: 4294967295) rx_queue_size=3D - (default: 256) tx_queue_size=3D - (default: 256) host_mtu=3D - (default: 0) failover=3D - (default: false) properties common for all network interfaces: netdev=3D - ID of a netdev to use as a backend mac=3D - Ethernet 6-byte MAC Address, example: 52:54:00= :12:34:56 bootindex=3D Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_command.c | 166 +++++++++++++++++----------------------- src/qemu/qemu_command.h | 9 ++- src/qemu/qemu_hotplug.c | 6 +- 3 files changed, 78 insertions(+), 103 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a8a93274c6..54f50c9a5e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3859,37 +3859,29 @@ qemuBuildLegacyNicStr(virDomainNetDef *net) } -char * -qemuBuildNicDevStr(virDomainDef *def, - virDomainNetDef *net, - size_t vhostfdSize, - virQEMUCaps *qemuCaps) +virJSONValue * +qemuBuildNicDevProps(virDomainDef *def, + virDomainNetDef *net, + size_t vhostfdSize, + virQEMUCaps *qemuCaps) { - g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; - bool usingVirtio =3D false; + g_autoptr(virJSONValue) props =3D NULL; char macaddr[VIR_MAC_STRING_BUFLEN]; if (virDomainNetIsVirtioModel(net)) { - if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_NET, n= et) < 0) { - return NULL; - } - - usingVirtio =3D true; - } else { - virBufferAddStr(&buf, virDomainNetGetModelString(net)); - } + const char *tx =3D NULL; + virTristateSwitch mq =3D VIR_TRISTATE_SWITCH_ABSENT; + unsigned long long vectors =3D 0; + virTristateSwitch failover =3D VIR_TRISTATE_SWITCH_ABSENT; - if (usingVirtio) { - if (net->driver.virtio.txmode && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) { - virBufferAddLit(&buf, ",tx=3D"); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) { switch (net->driver.virtio.txmode) { case VIR_DOMAIN_NET_VIRTIO_TX_MODE_IOTHREAD: - virBufferAddLit(&buf, "bh"); + tx =3D "bh"; break; case VIR_DOMAIN_NET_VIRTIO_TX_MODE_TIMER: - virBufferAddLit(&buf, "timer"); + tx =3D "timer"; break; case VIR_DOMAIN_NET_VIRTIO_TX_MODE_DEFAULT: @@ -3905,100 +3897,80 @@ qemuBuildNicDevStr(virDomainDef *def, return NULL; } } - qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps= ); - if (net->driver.virtio.event_idx) { - virBufferAsprintf(&buf, ",event_idx=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.event_idx)); - } - if (net->driver.virtio.host.csum) { - virBufferAsprintf(&buf, ",csum=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.csum)); - } - if (net->driver.virtio.host.gso) { - virBufferAsprintf(&buf, ",gso=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.gso)); - } - if (net->driver.virtio.host.tso4) { - virBufferAsprintf(&buf, ",host_tso4=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.tso4)); - } - if (net->driver.virtio.host.tso6) { - virBufferAsprintf(&buf, ",host_tso6=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.tso6)); - } - if (net->driver.virtio.host.ecn) { - virBufferAsprintf(&buf, ",host_ecn=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.ecn)); - } - if (net->driver.virtio.host.ufo) { - virBufferAsprintf(&buf, ",host_ufo=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.ufo)); - } - if (net->driver.virtio.host.mrg_rxbuf) { - virBufferAsprintf(&buf, ",mrg_rxbuf=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.host.mrg_rxbuf)); - } - if (net->driver.virtio.guest.csum) { - virBufferAsprintf(&buf, ",guest_csum=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.guest.csum)); - } - if (net->driver.virtio.guest.tso4) { - virBufferAsprintf(&buf, ",guest_tso4=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.guest.tso4)); - } - if (net->driver.virtio.guest.tso6) { - virBufferAsprintf(&buf, ",guest_tso6=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.guest.tso6)); - } - if (net->driver.virtio.guest.ecn) { - virBufferAsprintf(&buf, ",guest_ecn=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.guest.ecn)); - } - if (net->driver.virtio.guest.ufo) { - virBufferAsprintf(&buf, ",guest_ufo=3D%s", - virTristateSwitchTypeToString(net->driver.vi= rtio.guest.ufo)); - } if (vhostfdSize > 1) { if (net->info.type =3D=3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { /* ccw provides a one to one relation of fds to queues and * does not support the vectors option */ - virBufferAddLit(&buf, ",mq=3Don"); + mq =3D VIR_TRISTATE_SWITCH_ON; } else { /* As advised at https://www.linux-kvm.org/page/Multiqueue * we should add vectors=3D2*N+2 where N is the vhostfdSize */ - virBufferAsprintf(&buf, ",mq=3Don,vectors=3D%zu", 2 * vhos= tfdSize + 2); + mq =3D VIR_TRISTATE_SWITCH_ON; + vectors =3D 2 * vhostfdSize + 2; } } - if (net->driver.virtio.rx_queue_size) - virBufferAsprintf(&buf, ",rx_queue_size=3D%u", net->driver.vir= tio.rx_queue_size); - - if (net->driver.virtio.tx_queue_size) - virBufferAsprintf(&buf, ",tx_queue_size=3D%u", net->driver.vir= tio.tx_queue_size); + if (net->teaming && net->teaming->type =3D=3D VIR_DOMAIN_NET_TEAMI= NG_TYPE_PERSISTENT) + failover =3D VIR_TRISTATE_SWITCH_ON; - if (net->mtu) - virBufferAsprintf(&buf, ",host_mtu=3D%u", net->mtu); + if (!(props =3D qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_NET, net= , qemuCaps))) + return NULL; - if (net->teaming && net->teaming->type =3D=3D VIR_DOMAIN_NET_TEAMI= NG_TYPE_PERSISTENT) - virBufferAddLit(&buf, ",failover=3Don"); + if (virJSONValueObjectAdd(props, + "S:tx", tx, + "T:ioeventfd", net->driver.virtio.ioeven= tfd, + "T:event_idx", net->driver.virtio.event_= idx, + "T:csum", net->driver.virtio.host.csum, + "T:gso", net->driver.virtio.host.gso, + "T:host_tso4", net->driver.virtio.host.t= so4, + "T:host_tso6", net->driver.virtio.host.t= so6, + "T:host_ecn", net->driver.virtio.host.ec= n, + "T:host_ufo", net->driver.virtio.host.uf= o, + "T:mrg_rxbuf", net->driver.virtio.host.m= rg_rxbuf, + "T:guest_csum", net->driver.virtio.guest= .csum, + "T:guest_tso4", net->driver.virtio.guest= .tso4, + "T:guest_tso6", net->driver.virtio.guest= .tso6, + "T:guest_ecn", net->driver.virtio.guest.= ecn, + "T:guest_ufo", net->driver.virtio.guest.= ufo, + "T:mq", mq, + "P:vectors", vectors, + "p:rx_queue_size", net->driver.virtio.rx= _queue_size, + "p:tx_queue_size", net->driver.virtio.tx= _queue_size, + "p:host_mtu", net->mtu, + "T:failover", failover, + NULL) < 0) + return NULL; + } else { + if (virJSONValueObjectCreate(&props, + "s:driver", virDomainNetGetModelStrin= g(net), + NULL) < 0) + return NULL; } - virBufferAsprintf(&buf, ",netdev=3Dhost%s", net->info.alias); - virBufferAsprintf(&buf, ",id=3D%s", net->info.alias); - virBufferAsprintf(&buf, ",mac=3D%s", - virMacAddrFormat(&net->mac, macaddr)); + virMacAddrFormat(&net->mac, macaddr); - if (qemuBuildDeviceAddressStr(&buf, def, &net->info) < 0) + if (virJSONValueObjectAdd(props, + "f:netdev", g_strdup_printf("host%s", net->i= nfo.alias), + "s:id", net->info.alias, + "s:mac", macaddr, + NULL) < 0) return NULL; - if (qemuBuildRomStr(&buf, &net->info) < 0) + + if (qemuBuildDeviceAddressProps(props, def, &net->info) < 0) return NULL; - if (net->info.effectiveBootIndex > 0) - virBufferAsprintf(&buf, ",bootindex=3D%u", net->info.effectiveBoot= Index); - return virBufferContentAndReset(&buf); + if (qemuBuildRomProps(props, &net->info) < 0) + return NULL; + + if (virJSONValueObjectAdd(props, + "p:bootindex", net->info.effectiveBootIndex, + NULL) < 0) + return NULL; + + return g_steal_pointer(&props); } @@ -8747,6 +8719,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, { virDomainDef *def =3D vm->def; int ret =3D -1; + g_autoptr(virJSONValue) nicprops =3D NULL; g_autofree char *nic =3D NULL; g_autofree char *chardev =3D NULL; int *tapfd =3D NULL; @@ -9010,9 +8983,10 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, if (qemuCommandAddExtDevice(cmd, &net->info, qemuCaps) < 0) goto cleanup; - if (!(nic =3D qemuBuildNicDevStr(def, net, net->driver.virtio.queu= es, qemuCaps))) + if (!(nicprops =3D qemuBuildNicDevProps(def, net, net->driver.virt= io.queues, qemuCaps))) + goto cleanup; + if (qemuBuildDeviceCommandlineFromJSON(cmd, nicprops, qemuCaps) < = 0) goto cleanup; - virCommandAddArgList(cmd, "-device", nic, NULL); } else if (!requireNicdev) { if (qemuCommandAddExtDevice(cmd, &net->info, qemuCaps) < 0) goto cleanup; diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 18d4c4130b..29db16e729 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -98,10 +98,11 @@ virJSONValue *qemuBuildHostNetStr(virDomainNetDef *net, const char *vdpadev); /* Current, best practice */ -char *qemuBuildNicDevStr(virDomainDef *def, - virDomainNetDef *net, - size_t vhostfdSize, - virQEMUCaps *qemuCaps); +virJSONValue * +qemuBuildNicDevProps(virDomainDef *def, + virDomainNetDef *net, + size_t vhostfdSize, + virQEMUCaps *qemuCaps); char *qemuDeviceDriveHostAlias(virDomainDiskDef *disk); bool qemuDiskBusIsSD(int bus); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 1b5f63f271..1c0056da16 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1175,7 +1175,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, int *vhostfd =3D NULL; size_t vhostfdSize =3D 0; size_t queueSize =3D 0; - g_autofree char *nicstr =3D NULL; + g_autoptr(virJSONValue) nicprops =3D NULL; g_autoptr(virJSONValue) netprops =3D NULL; int ret =3D -1; bool releaseaddr =3D false; @@ -1484,7 +1484,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, for (i =3D 0; i < vhostfdSize; i++) VIR_FORCE_CLOSE(vhostfd[i]); - if (!(nicstr =3D qemuBuildNicDevStr(vm->def, net, queueSize, priv->qem= uCaps))) + if (!(nicprops =3D qemuBuildNicDevProps(vm->def, net, queueSize, priv-= >qemuCaps))) goto try_remove; qemuDomainObjEnterMonitor(driver, vm); @@ -1495,7 +1495,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, goto try_remove; } - if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) { + if (qemuMonitorAddDeviceProps(priv->mon, &nicprops) < 0) { ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &net->info= )); ignore_value(qemuDomainObjExitMonitor(driver, vm)); virDomainAuditNet(vm, NULL, net, "attach", false); --=20 2.31.1