From nobody Mon Feb 9 09:15:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.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 170.10.133.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=1633621184; cv=none; d=zohomail.com; s=zohoarc; b=as+jhYAO9PO3Zh4SJZB+lu9mAoqY+/oUYyLAfVViY26sU/UyWWKHYRi3P2UwwJFKfufenDZwRJvsGu2vMYkAZ5x6IwqrIf8nHQU002VJz530GcRmG35Y1Z6ZflRFW92KO25wr7My0F++3AuJ7UHaRrs1VfJKuxNKdcgab2PdY2o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1633621184; 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=590GFnrleuUwnw3v4cTVbfL5HaMjeJ7cQh2H71DEl7I=; b=FkX/hO9d1lrMPgse6GXtpsgw2EJTcF8d6Z5Y0TCW+T5htmErKX682KNn8ZEHuSBppxoEnta4FT9a4rQNQWsMWtnL9ao8JFZFRYbkteybd+UzoVZJH0GOQxQu+T9XCQGhdoKmfwcl0GoQ+r5ItL0zhLd1icp/RLfyGZaZ86W6FOo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.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 [170.10.133.124]) by mx.zohomail.com with SMTPS id 1633621184971166.27764389327012; Thu, 7 Oct 2021 08:39:44 -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-298-qOlHuchaPiKnqZV8ury9TQ-1; Thu, 07 Oct 2021 11:39:41 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D099A11811AC; Thu, 7 Oct 2021 15:31:57 +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 A611E2C3DF1; Thu, 7 Oct 2021 15:31:57 +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 742641803B30; Thu, 7 Oct 2021 15:31:57 +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 197FL18Y024410 for ; Thu, 7 Oct 2021 11:21:01 -0400 Received: by smtp.corp.redhat.com (Postfix) id C9E115F4F1; Thu, 7 Oct 2021 15:21:01 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.40.208.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2F9545D6BA for ; Thu, 7 Oct 2021 15:21:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633621183; 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=590GFnrleuUwnw3v4cTVbfL5HaMjeJ7cQh2H71DEl7I=; b=ZQdPXVCbSyXN1hYmVG0Sleu4jJxDEmS6s2Citye9KbflONEFBgaRv3wWpB5dWBt8y3B4TG wG2yl6tITmxNOkqQPLtCGCQ02qd7hbFgg5x2XxXCXCnIjJz5TfTPaUyoSmza12t5t49aoj 85TuHpbu5StRTIIwZUmYvjmrVyh6v2U= X-MC-Unique: qOlHuchaPiKnqZV8ury9TQ-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 080/103] qemuBuildDiskCommandLine: Generate via JSON Date: Thu, 7 Oct 2021 17:18:08 +0200 Message-Id: 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.84 on 10.5.11.23 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: 1633621185966100001 Content-Type: text/plain; charset="utf-8" The types for the special fields of the 'virtio-blk-pci' according to QEMU are: iothread=3D> ioeventfd=3D - on/off (default: true) event_idx=3D - on/off (default: true) scsi=3D - on/off (default: false) num-queues=3D - (default: 65535) queue-size=3D - (default: 256) For all disks we also use the following properties (based on 'scsi-hd'): device_id=3D share-rw=3D - (default: false) drive=3D - Node name or ID of a block device to use as a = backend chardev=3D - ID of a chardev to use as a backend <- vhost= -user-blk-pci bootindex=3D logical_block_size=3D - A power of two between 512 B and 2 MiB (def= ault: 0) physical_block_size=3D - A power of two between 512 B and 2 MiB (de= fault: 0) wwn=3D - (default: 0) rotation_rate=3D - (default: 0) vendor=3D product=3D removable=3D - on/off (default: false) write-cache=3D - on/off/auto (default: "auto") cyls=3D - (default: 0) heads=3D - (default: 0) secs=3D - (default: 0) bios-chs-trans=3D - Logical CHS translation algorithm= , auto/none/lba/large/rechs (default: "auto") <- ide-hd serial=3D werror=3D - Error handling policy, report/ignore/enospc/= stop/auto (default: "auto") rerror=3D - Error handling policy, report/ignore/enospc/= stop/auto (default: "auto") The 'wwn' field is changed from a hex string to a number since qemu actually treats it as a number. Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_command.c | 360 +++++++----------- src/qemu/qemu_command.h | 8 +- src/qemu/qemu_hotplug.c | 6 +- .../disk-ide-wwn.x86_64-latest.args | 2 +- .../disk-scsi-disk-wwn.x86_64-latest.args | 4 +- .../disk-scsi.x86_64-latest.args | 2 +- 6 files changed, 146 insertions(+), 236 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a13332f8f5..a8a93274c6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1995,31 +1995,6 @@ qemuBuildDiskFrontendAttributeErrorPolicy(virDomainD= iskDef *disk, } -static void -qemuBuildDiskFrontendAttributes(virDomainDiskDef *disk, - virBuffer *buf) -{ - /* generate geometry command string */ - if (disk->geometry.cylinders > 0 && - disk->geometry.heads > 0 && - disk->geometry.sectors > 0) { - virBufferAsprintf(buf, ",cyls=3D%u,heads=3D%u,secs=3D%u", - disk->geometry.cylinders, - disk->geometry.heads, - disk->geometry.sectors); - - if (disk->geometry.trans !=3D VIR_DOMAIN_DISK_TRANS_DEFAULT) - virBufferAsprintf(buf, ",bios-chs-trans=3D%s", - virDomainDiskGeometryTransTypeToString(disk-= >geometry.trans)); - } - - if (disk->serial) { - virBufferAddLit(buf, ",serial=3D"); - virBufferEscape(buf, '\\', " ", "%s", disk->serial); - } -} - - static char * qemuBuildDriveStr(virDomainDiskDef *disk, virQEMUCaps *qemuCaps) @@ -2092,82 +2067,46 @@ qemuBuildDriveStr(virDomainDiskDef *disk, } -static int -qemuBuildDriveDevCacheStr(virDomainDiskDef *disk, - virBuffer *buf, - virQEMUCaps *qemuCaps) -{ - bool wb; - - if (disk->cachemode =3D=3D VIR_DOMAIN_DISK_CACHE_DEFAULT) - return 0; - - /* VIR_DOMAIN_DISK_DEVICE_LUN translates into 'scsi-block' - * where any caching setting makes no sense. */ - if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_LUN) - return 0; - - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_WRITE_CACHE)) - return 0; - - if (qemuDomainDiskCachemodeFlags(disk->cachemode, &wb, NULL, NULL) < 0) - return -1; - - virBufferStrcat(buf, ",write-cache=3D", - virTristateSwitchTypeToString(virTristateSwitchFromBoo= l(wb)), - NULL); - - return 0; -} - - -char * -qemuBuildDiskDeviceStr(const virDomainDef *def, - virDomainDiskDef *disk, - virQEMUCaps *qemuCaps) +virJSONValue * +qemuBuildDiskDeviceProps(const virDomainDef *def, + virDomainDiskDef *disk, + virQEMUCaps *qemuCaps) { - g_auto(virBuffer) opt =3D VIR_BUFFER_INITIALIZER; - const char *contAlias; - g_autofree char *backendAlias =3D NULL; + g_autoptr(virJSONValue) props =3D NULL; + const char *driver =3D NULL; g_autofree char *scsiVPDDeviceId =3D NULL; - int controllerModel; + virTristateSwitch shareRW =3D VIR_TRISTATE_SWITCH_ABSENT; + g_autofree char *chardev =3D NULL; + g_autofree char *drive =3D NULL; + unsigned int bootindex =3D 0; + unsigned int logical_block_size =3D 0; + unsigned int physical_block_size =3D 0; + g_autoptr(virJSONValue) wwn =3D NULL; + g_autofree char *serial =3D NULL; + virTristateSwitch removable =3D VIR_TRISTATE_SWITCH_ABSENT; + virTristateSwitch writeCache =3D VIR_TRISTATE_SWITCH_ABSENT; + const char *biosCHSTrans =3D NULL; + const char *wpolicy =3D NULL; + const char *rpolicy =3D NULL; switch ((virDomainDiskBus) disk->bus) { case VIR_DOMAIN_DISK_BUS_IDE: + case VIR_DOMAIN_DISK_BUS_SATA: if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, "ide-cd"); + driver =3D "ide-cd"; else - virBufferAddLit(&opt, "ide-hd"); + driver =3D "ide-hd"; - /* When domain has builtin IDE controller we don't put it onto cmd - * line. Therefore we can't set its alias. In that case, use the - * default one. */ - if (qemuDomainHasBuiltinIDE(def)) { - contAlias =3D "ide"; - } else { - if (!(contAlias =3D virDomainControllerAliasFind(def, - VIR_DOMAIN_CONT= ROLLER_TYPE_IDE, - disk->info.addr= .drive.controller))) - return NULL; - } - virBufferAsprintf(&opt, ",bus=3D%s.%d,unit=3D%d", - contAlias, - disk->info.addr.drive.bus, - disk->info.addr.drive.unit); break; case VIR_DOMAIN_DISK_BUS_SCSI: - controllerModel =3D qemuDomainFindSCSIControllerModel(def, &disk->= info); - if (controllerModel < 0) - return NULL; - if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_LUN) { - virBufferAddLit(&opt, "scsi-block"); + driver =3D "scsi-block"; } else { if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, "scsi-cd"); + driver =3D "scsi-cd"; else - virBufferAddLit(&opt, "scsi-hd"); + driver =3D "scsi-hd"; /* qemu historically used the name of -drive as one of the dev= ice * ids in the Vital Product Data Device Identification page if @@ -2184,116 +2123,56 @@ qemuBuildDiskDeviceStr(const virDomainDef *def, } } - if (!(contAlias =3D virDomainControllerAliasFind(def, VIR_DOMAIN_C= ONTROLLER_TYPE_SCSI, - disk->info.addr.dri= ve.controller))) - return NULL; - - switch ((virDomainControllerModelSCSI)controllerModel) { - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_NCR53C90: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_DC390: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AM53C974: - virBufferAsprintf(&opt, ",bus=3D%s.%d,scsi-id=3D%d", - contAlias, - disk->info.addr.drive.bus, - disk->info.addr.drive.unit); - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL: - virBufferAsprintf(&opt, ",bus=3D%s.0,channel=3D%d,scsi-id=3D%d= ,lun=3D%d", - contAlias, - disk->info.addr.drive.bus, - disk->info.addr.drive.target, - disk->info.addr.drive.unit); - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_DEFAULT: - case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unexpected SCSI controller model %d"), - controllerModel); - return NULL; - } - - if (scsiVPDDeviceId) - virBufferStrcat(&opt, ",device_id=3D", scsiVPDDeviceId, NULL); - break; - case VIR_DOMAIN_DISK_BUS_SATA: - if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, "ide-cd"); - else - virBufferAddLit(&opt, "ide-hd"); - - /* When domain has builtin SATA controller we don't put it onto cmd - * line. Therefore we can't set its alias. In that case, use the - * default one. */ - if (qemuDomainIsQ35(def) && - disk->info.addr.drive.controller =3D=3D 0) { - contAlias =3D "ide"; - } else { - if (!(contAlias =3D virDomainControllerAliasFind(def, - VIR_DOMAIN_CONT= ROLLER_TYPE_SATA, - disk->info.addr= .drive.controller))) - return NULL; - } - virBufferAsprintf(&opt, ",bus=3D%s.%d", - contAlias, - disk->info.addr.drive.unit); - break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: { + virTristateSwitch scsi =3D VIR_TRISTATE_SWITCH_ABSENT; + g_autofree char *iothread =3D NULL; - case VIR_DOMAIN_DISK_BUS_VIRTIO: - if (qemuBuildVirtioDevStr(&opt, qemuCaps, VIR_DOMAIN_DEVICE_DISK, = disk) < 0) - return NULL; + if (disk->iothread > 0) + iothread =3D g_strdup_printf("iothread%u", disk->iothread); - if (disk->iothread) - virBufferAsprintf(&opt, ",iothread=3Diothread%u", disk->iothre= ad); - - qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps); - if (disk->event_idx) { - virBufferAsprintf(&opt, ",event_idx=3D%s", - virTristateSwitchTypeToString(disk->event_id= x)); - } - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI) && - !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_D= ISABLED) && - disk->device !=3D VIR_DOMAIN_DISK_DEVICE_LUN)) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) { /* if sg_io is true but the scsi option isn't supported, * that means it's just always on in this version of qemu. */ - virBufferAsprintf(&opt, ",scsi=3D%s", - (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_= LUN) - ? "on" : "off"); + if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_LUN) { + scsi =3D VIR_TRISTATE_SWITCH_ON; + } else { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI_DE= FAULT_DISABLED)) + scsi =3D VIR_TRISTATE_SWITCH_OFF; + } } - if (disk->queues) { - virBufferAsprintf(&opt, ",num-queues=3D%u", disk->queues); - } - if (disk->queue_size > 0) { - virBufferAsprintf(&opt, ",queue-size=3D%u", disk->queue_size); - } + if (!(props =3D qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_DISK, di= sk, qemuCaps))) + return NULL; - if (qemuBuildDeviceAddressStr(&opt, def, &disk->info) < 0) + if (virJSONValueObjectAdd(props, + "S:iothread", iothread, + "T:ioeventfd", disk->ioeventfd, + "T:event_idx", disk->event_idx, + "T:scsi", scsi, + "p:num-queues", disk->queues, + "p:queue-size", disk->queue_size, + NULL) < 0) return NULL; + } break; case VIR_DOMAIN_DISK_BUS_USB: - virBufferAddLit(&opt, "usb-storage"); + driver =3D "usb-storage"; + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) { + if (disk->removable =3D=3D VIR_TRISTATE_SWITCH_ABSENT) + removable =3D VIR_TRISTATE_SWITCH_OFF; + else + removable =3D disk->removable; + } - if (qemuBuildDeviceAddressStr(&opt, def, &disk->info) < 0) - return NULL; break; case VIR_DOMAIN_DISK_BUS_FDC: - virBufferAsprintf(&opt, "floppy,unit=3D%d", disk->info.addr.drive.= unit); + driver =3D "floppy"; break; case VIR_DOMAIN_DISK_BUS_XEN: @@ -2308,74 +2187,105 @@ qemuBuildDiskDeviceStr(const virDomainDef *def, return NULL; } + if (driver) { + if (virJSONValueObjectCreate(&props, + "s:driver", driver, + NULL) < 0) + return NULL; + } + + if (disk->info.type =3D=3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + disk->info.addr.drive.diskbus =3D disk->bus; + + if (qemuBuildDeviceAddressProps(props, def, &disk->info) < 0) + return NULL; + if (disk->src->shared && virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_SHARE_RW)) - virBufferAddLit(&opt, ",share-rw=3Don"); + shareRW =3D VIR_TRISTATE_SWITCH_ON; if (virStorageSourceGetActualType(disk->src) =3D=3D VIR_STORAGE_TYPE_V= HOST_USER) { - backendAlias =3D qemuDomainGetVhostUserChrAlias(disk->info.alias); - - virBufferAsprintf(&opt, ",chardev=3D%s", backendAlias); + chardev =3D qemuDomainGetVhostUserChrAlias(disk->info.alias); } else { - if (qemuDomainDiskGetBackendAlias(disk, qemuCaps, &backendAlias) <= 0) + if (qemuDomainDiskGetBackendAlias(disk, qemuCaps, &drive) < 0) return NULL; - - if (backendAlias) - virBufferAsprintf(&opt, ",drive=3D%s", backendAlias); } - virBufferAsprintf(&opt, ",id=3D%s", disk->info.alias); /* bootindex for floppies is configured via the fdc controller */ - if (disk->device !=3D VIR_DOMAIN_DISK_DEVICE_FLOPPY && - disk->info.effectiveBootIndex > 0) - virBufferAsprintf(&opt, ",bootindex=3D%u", disk->info.effectiveBoo= tIndex); + if (disk->device !=3D VIR_DOMAIN_DISK_DEVICE_FLOPPY) + bootindex =3D disk->info.effectiveBootIndex; + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) { - if (disk->blockio.logical_block_size > 0) - virBufferAsprintf(&opt, ",logical_block_size=3D%u", - disk->blockio.logical_block_size); - if (disk->blockio.physical_block_size > 0) - virBufferAsprintf(&opt, ",physical_block_size=3D%u", - disk->blockio.physical_block_size); + logical_block_size =3D disk->blockio.logical_block_size; + physical_block_size =3D disk->blockio.physical_block_size; } if (disk->wwn) { - if (STRPREFIX(disk->wwn, "0x")) - virBufferAsprintf(&opt, ",wwn=3D%s", disk->wwn); - else - virBufferAsprintf(&opt, ",wwn=3D0x%s", disk->wwn); - } + unsigned long long w =3D 0; - if (disk->rotation_rate) - virBufferAsprintf(&opt, ",rotation_rate=3D%u", disk->rotation_rate= ); + if (virStrToLong_ull(disk->wwn, NULL, 16, &w) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Failed to parse wwn '%s' as number"), disk->= wwn); + return NULL; + } - if (disk->vendor) { - virBufferAddLit(&opt, ",vendor=3D"); - virQEMUBuildBufferEscapeComma(&opt, disk->vendor); + wwn =3D virJSONValueNewNumberUlong(w); } - if (disk->product) { - virBufferAddLit(&opt, ",product=3D"); - virQEMUBuildBufferEscapeComma(&opt, disk->product); - } + if (disk->cachemode !=3D VIR_DOMAIN_DISK_CACHE_DEFAULT) { + /* VIR_DOMAIN_DISK_DEVICE_LUN translates into 'scsi-block' + * where any caching setting makes no sense. */ + if (disk->device !=3D VIR_DOMAIN_DISK_DEVICE_LUN && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_WRITE_CACHE)) { + bool wb; - if (disk->bus =3D=3D VIR_DOMAIN_DISK_BUS_USB) { - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) { - if (disk->removable =3D=3D VIR_TRISTATE_SWITCH_ON) - virBufferAddLit(&opt, ",removable=3Don"); - else - virBufferAddLit(&opt, ",removable=3Doff"); + if (qemuDomainDiskCachemodeFlags(disk->cachemode, &wb, NULL, + NULL) < 0) + return NULL; + + writeCache =3D virTristateSwitchFromBool(wb); } } - if (qemuBuildDriveDevCacheStr(disk, &opt, qemuCaps) < 0) - return NULL; + if (disk->geometry.trans !=3D VIR_DOMAIN_DISK_TRANS_DEFAULT) + biosCHSTrans =3D virDomainDiskGeometryTransTypeToString(disk->geom= etry.trans); - qemuBuildDiskFrontendAttributes(disk, &opt); + if (disk->serial) { + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + + virBufferEscape(&buf, '\\', " ", "%s", disk->serial); + serial =3D virBufferContentAndReset(&buf); + } if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_STORAGE_WERROR)) - qemuBuildDiskFrontendAttributeErrorPolicy(disk, &opt); + qemuBuildDiskGetErrorPolicy(disk, &wpolicy, &rpolicy); - return virBufferContentAndReset(&opt); + if (virJSONValueObjectAdd(props, + "S:device_id", scsiVPDDeviceId, + "T:share-rw", shareRW, + "S:drive", drive, + "S:chardev", chardev, + "s:id", disk->info.alias, + "p:bootindex", bootindex, + "p:logical_block_size", logical_block_size, + "p:physical_block_size", physical_block_size, + "A:wwn", &wwn, + "p:rotation_rate", disk->rotation_rate, + "S:vendor", disk->vendor, + "S:product", disk->product, + "T:removable", removable, + "S:write-cache", qemuOnOffAuto(writeCache), + "p:cyls", disk->geometry.cylinders, + "p:heads", disk->geometry.heads, + "p:secs", disk->geometry.sectors, + "S:bios-chs-trans", biosCHSTrans, + "S:serial", serial, + "S:werror", wpolicy, + "S:rerror", rpolicy, + NULL) < 0) + return NULL; + + return g_steal_pointer(&props); } @@ -2605,7 +2515,7 @@ qemuBuildDiskCommandLine(virCommand *cmd, virDomainDiskDef *disk, virQEMUCaps *qemuCaps) { - g_autofree char *optstr =3D NULL; + g_autoptr(virJSONValue) devprops =3D NULL; if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0) return -1; @@ -2624,11 +2534,11 @@ qemuBuildDiskCommandLine(virCommand *cmd, if (qemuCommandAddExtDevice(cmd, &disk->info, qemuCaps) < 0) return -1; - virCommandAddArg(cmd, "-device"); + if (!(devprops =3D qemuBuildDiskDeviceProps(def, disk, qemuCaps))) + return -1; - if (!(optstr =3D qemuBuildDiskDeviceStr(def, disk, qemuCaps))) + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, qemuCaps) < 0) return -1; - virCommandAddArg(cmd, optstr); return 0; } diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 5b1b727b84..18d4c4130b 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -134,10 +134,10 @@ qemuBlockStorageSourceChainData * qemuBuildStorageSourceChainAttachPrepareBlockdevTop(virStorageSource *top, virStorageSource *back= ingStore); -char -*qemuBuildDiskDeviceStr(const virDomainDef *def, - virDomainDiskDef *disk, - virQEMUCaps *qemuCaps); +virJSONValue * +qemuBuildDiskDeviceProps(const virDomainDef *def, + virDomainDiskDef *disk, + virQEMUCaps *qemuCaps); char * qemuBuildVHostUserFsDevStr(virDomainFSDef *fs, diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 28cafd11d2..1b5f63f271 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -710,7 +710,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver, { g_autoptr(qemuBlockStorageSourceChainData) data =3D NULL; qemuDomainObjPrivate *priv =3D vm->privateData; - g_autofree char *devstr =3D NULL; + g_autoptr(virJSONValue) devprops =3D NULL; bool blockdev =3D virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV); bool extensionDeviceAttached =3D false; int rc; @@ -772,7 +772,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver, ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, = backend)); } - if (!(devstr =3D qemuBuildDiskDeviceStr(vm->def, disk, priv->qemuCaps)= )) + if (!(devprops =3D qemuBuildDiskDeviceProps(vm->def, disk, priv->qemuC= aps))) goto rollback; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -782,7 +782,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver, extensionDeviceAttached =3D true; if (rc =3D=3D 0) - rc =3D qemuMonitorAddDevice(priv->mon, devstr); + rc =3D qemuMonitorAddDeviceProps(priv->mon, &devprops); /* Setup throttling of disk via block_set_io_throttle QMP command. This * is a hack until the 'throttle' blockdev driver will support modific= ation diff --git a/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args b/tests= /qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args index 9a74262c15..8560754c24 100644 --- a/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args +++ b/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args @@ -29,7 +29,7 @@ XDG_CONFIG_HOME=3D/tmp/lib/domain--1-QEMUGuest1/.config \ -device piix3-usb-uhci,id=3Dusb,bus=3Dpci.0,addr=3D0x1.0x2 \ -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","no= de-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw= ","file":"libvirt-1-storage"}' \ --device ide-hd,bus=3Dide.0,unit=3D1,drive=3Dlibvirt-1-format,id=3Dide0-0-1= ,bootindex=3D1,wwn=3D0x5000c50015ea71ad,serial=3DWD-WMAP9A966149 \ +-device ide-hd,bus=3Dide.0,unit=3D1,drive=3Dlibvirt-1-format,id=3Dide0-0-1= ,bootindex=3D1,wwn=3D5764824127192592813,serial=3DWD-WMAP9A966149 \ -audiodev id=3Daudio1,driver=3Dnone \ -device virtio-balloon-pci,id=3Dballoon0,bus=3Dpci.0,addr=3D0x2 \ -sandbox on,obsolete=3Ddeny,elevateprivileges=3Ddeny,spawn=3Ddeny,resource= control=3Ddeny \ diff --git a/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args b= /tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args index 7648bfdc4e..887d2219af 100644 --- a/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args +++ b/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args @@ -31,10 +31,10 @@ XDG_CONFIG_HOME=3D/tmp/lib/domain--1-QEMUGuest1/.config= \ -device lsi,id=3Dscsi1,bus=3Dpci.0,addr=3D0x3 \ -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","no= de-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-2-format","read-only":true,"driver":"raw"= ,"file":"libvirt-2-storage"}' \ --device scsi-cd,bus=3Dscsi0.0,channel=3D0,scsi-id=3D1,lun=3D0,device_id=3D= WD-WMAP9A966149,drive=3Dlibvirt-2-format,id=3Dscsi0-0-1-0,wwn=3D0x5000c5001= 5ea71ac,serial=3DWD-WMAP9A966149 \ +-device scsi-cd,bus=3Dscsi0.0,channel=3D0,scsi-id=3D1,lun=3D0,device_id=3D= WD-WMAP9A966149,drive=3Dlibvirt-2-format,id=3Dscsi0-0-1-0,wwn=3D57648241271= 92592812,serial=3DWD-WMAP9A966149 \ -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest2","no= de-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw= ","file":"libvirt-1-storage"}' \ --device scsi-hd,bus=3Dscsi0.0,channel=3D0,scsi-id=3D0,lun=3D0,device_id=3D= drive-scsi0-0-0-0,drive=3Dlibvirt-1-format,id=3Dscsi0-0-0-0,bootindex=3D1,w= wn=3D0x5000c50015ea71ad \ +-device scsi-hd,bus=3Dscsi0.0,channel=3D0,scsi-id=3D0,lun=3D0,device_id=3D= drive-scsi0-0-0-0,drive=3Dlibvirt-1-format,id=3Dscsi0-0-0-0,bootindex=3D1,w= wn=3D5764824127192592813 \ -audiodev id=3Daudio1,driver=3Dnone \ -device virtio-balloon-pci,id=3Dballoon0,bus=3Dpci.0,addr=3D0x4 \ -sandbox on,obsolete=3Ddeny,elevateprivileges=3Ddeny,spawn=3Ddeny,resource= control=3Ddeny \ diff --git a/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args b/tests/qe= muxml2argvdata/disk-scsi.x86_64-latest.args index bcd998a968..d9971582ac 100644 --- a/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args +++ b/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args @@ -43,7 +43,7 @@ XDG_CONFIG_HOME=3D/tmp/lib/domain--1-QEMUGuest1/.config \ -device scsi-hd,bus=3Dscsi1.0,channel=3D0,scsi-id=3D0,lun=3D0,device_id=3D= abcdefghijklmn,drive=3Dlibvirt-4-format,id=3Dscsi1-0-0-0,serial=3Dabcdefghi= jklmn \ -blockdev '{"driver":"file","filename":"/tmp/scsidisk3.img","node-name":"l= ibvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw= ","file":"libvirt-3-storage"}' \ --device scsi-hd,bus=3Dscsi2.0,channel=3D0,scsi-id=3D0,lun=3D0,device_id=3D= drive-scsi2-0-0-0,drive=3Dlibvirt-3-format,id=3Dscsi2-0-0-0,wwn=3D0x5000c50= 015ea71ac \ +-device scsi-hd,bus=3Dscsi2.0,channel=3D0,scsi-id=3D0,lun=3D0,device_id=3D= drive-scsi2-0-0-0,drive=3Dlibvirt-3-format,id=3Dscsi2-0-0-0,wwn=3D576482412= 7192592812 \ -blockdev '{"driver":"file","filename":"/tmp/scsidisk4.img","node-name":"l= ibvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw= ","file":"libvirt-2-storage"}' \ -device scsi-hd,bus=3Dscsi3.0,channel=3D0,scsi-id=3D0,lun=3D0,device_id=3D= drive-scsi3-0-0-0,drive=3Dlibvirt-2-format,id=3Dscsi3-0-0-0 \ --=20 2.31.1