From nobody Mon Feb 9 02:12:46 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1507585163058533.5097217458753; Mon, 9 Oct 2017 14:39:23 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8CD54267D5; Mon, 9 Oct 2017 21:39:21 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 946C462487; Mon, 9 Oct 2017 21:39:20 +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 9C203410B3; Mon, 9 Oct 2017 21:39:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v99Ko3ZM022414 for ; Mon, 9 Oct 2017 16:50:03 -0400 Received: by smtp.corp.redhat.com (Postfix) id EC5DD17C5E; Mon, 9 Oct 2017 20:50:03 +0000 (UTC) Received: from mx1.redhat.com (ext-mx09.extmail.prod.ext.phx2.redhat.com [10.5.110.38]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 919C4189D9 for ; Mon, 9 Oct 2017 20:50:01 +0000 (UTC) Received: from mail-qk0-f179.google.com (mail-qk0-f179.google.com [209.85.220.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E8DCB4ACA7 for ; Mon, 9 Oct 2017 20:49:59 +0000 (UTC) Received: by mail-qk0-f179.google.com with SMTP id f199so11649613qke.2 for ; Mon, 09 Oct 2017 13:49:59 -0700 (PDT) Received: from dawid-fedora.datto.lan ([47.19.105.250]) by smtp.gmail.com with ESMTPSA id y31sm5505361qta.83.2017.10.09.13.49.58 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 09 Oct 2017 13:49:58 -0700 (PDT) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8CD54267D5 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=datto.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8CD54267D5 Authentication-Results: mx1.redhat.com; dkim=fail reason="signature verification failed" (2048-bit key) header.d=datto-com.20150623.gappssmtp.com header.i=@datto-com.20150623.gappssmtp.com header.b="ZDZjd2OE" DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E8DCB4ACA7 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=datto.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dzamirski@datto.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com E8DCB4ACA7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=datto-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=hQr5PZKEYx9vNTe2UqdUkA+1DuSyBg5WdYW4zeSCekM=; b=ZDZjd2OEufuWueNQwyefebe8Co5b4qqg+EI7HH62igVKDhXwlztRAdRdvLEvmcV/oj piLouxakzVGeFyZ/YjT5XW2yh/YSFysvsQqabmVS7/ui1pv3iIslFNDAJDX7s/fnPqZ6 lMRMN61ieVt/cevCbBfT7jTgEA7655D27osMmDoQkeYpBbgcuN28a41elZFNobSjfxzj dlrpGEmF27hst2AXsTnXGeVyISgiON/K3sPpDvRQjKqSY+zaynDfb2j9B/gn8crIwod0 W/sx7SkJDi88iDxKJlZCQooNpvRwn7TGYLc2wuItsa6aMpZPdV5Vpcxn8M/hAC9KmqMo 4swA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=hQr5PZKEYx9vNTe2UqdUkA+1DuSyBg5WdYW4zeSCekM=; b=fCDC08T/GgjLEGUqjinrxHmPze/V7dv221uqCeT5YgaoQS+tw0Hh2LRvtUxO0hPTHF 33qytLC8Bcp10NqnGFrBZ+CCwM/9ia1h16efX3X5XpJXWweH7ZCQhDrYuyqIPv+lTh3s 4L2SlkTJMJdXYP4p5QWnt7YbBdRgCKt5dnIzo5cHxruVuUX3LRfl1LvVYH5SvAQwAghE +gJ1FOMAgLPQFS9DrtCCFcOym+lBfJx/lv2w22xHQgVMsPEHeX38KQx7Lr5tDVjfZgj/ qtKZVgaES2jKNTGVoaXGvqpRJAXaHj9nHJKFjvXqR2zoUbJ2TU3HxPmIKDsp/iNxdoCn 3V9A== X-Gm-Message-State: AMCzsaV4ET8592OI0j5NyJVc69R9jB0LUMfhi1TPC3SWWrcJ0dJVWbwQ YzwIqZO+Qwz1BTZ2y/aDk+p/4l3mlgA= X-Google-Smtp-Source: AOwi7QCdVZE5hz/1IZiJOKFrYFICVR59wzc7nUTBr2OfwPOP4cB55DtlEQpZKZZynGLjK00+usdf6w== X-Received: by 10.55.16.34 with SMTP id a34mr11704491qkh.353.1507582198723; Mon, 09 Oct 2017 13:49:58 -0700 (PDT) From: Dawid Zamirski X-Google-Original-From: Dawid Zamirski To: libvir-list@redhat.com Date: Mon, 9 Oct 2017 16:49:53 -0400 Message-Id: <20171009204954.11382-6-dzrudy@gmail.com> In-Reply-To: <20171009204954.11382-1-dzrudy@gmail.com> References: <20171009204954.11382-1-dzrudy@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 09 Oct 2017 20:50:00 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 09 Oct 2017 20:50:00 +0000 (UTC) for IP:'209.85.220.179' DOMAIN:'mail-qk0-f179.google.com' HELO:'mail-qk0-f179.google.com' FROM:'dzamirski@datto.com' RCPT:'' X-RedHat-Spam-Score: -0.031 (DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS) 209.85.220.179 mail-qk0-f179.google.com 209.85.220.179 mail-qk0-f179.google.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.38 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 5/6] vbox: Process controller definitions from xml. 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 09 Oct 2017 21:39:22 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Dawid Zamirski Until now the vbox driver was completely ignoring element for storage in the XML definition. This patch adds support for interpretting element for storage devices. With this the following other changes were made to the whole storage attachment code: * vboxAttachDrives no longer "computes" deviceSlot and devicePort values based on the disk device name. This was causing the driver to ignore the values set by
element of the device. If that element is omitted in XML, the values produced by default by virDomainDiskDefAssign address should work well. * if any part of storage attachment code fails, i.e wherever we call virReportError, we also fail the DefineXML caller rather than ignoring those issues and moving on. * the DefineXML cleanup part of the code was changed to make sure that any critical failure in device attachment code does not leave any partially defined VM behind. * do not require disk source for removable drives so that "empty" drives can be created for cdrom and floppy types. --- src/vbox/vbox_common.c | 535 ++++++++++++++++++++++++++-------------------= ---- src/vbox/vbox_common.h | 8 + src/vbox/vbox_tmpl.c | 43 ++-- 3 files changed, 310 insertions(+), 276 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 92ee37164..7645b29a0 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -324,6 +324,9 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, StorageBus_SC= SI, &maxPortPerIn= st[StorageBus_SCSI]); + gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, + StorageBus_SA= S, + &maxPortPerIn= st[StorageBus_SAS]); gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, StorageBus_Fl= oppy, &maxPortPerIn= st[StorageBus_Floppy]); @@ -337,6 +340,9 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, StorageB= us_SCSI, &maxSlot= PerPort[StorageBus_SCSI]); + gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, + StorageB= us_SAS, + &maxSlot= PerPort[StorageBus_SAS]); gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, StorageB= us_Floppy, &maxSlot= PerPort[StorageBus_Floppy]); @@ -346,68 +352,6 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, return true; } =20 -/** - * function to get the StorageBus, Port number - * and Device number for the given devicename - * e.g: hda has StorageBus =3D IDE, port =3D 0, - * device =3D 0 - * - * @returns true on Success, false on failure. - * @param deviceName Input device name - * @param aMaxPortPerInst Input array of max port per device instance - * @param aMaxSlotPerPort Input array of max slot per device port - * @param storageBus Input storage bus type - * @param deviceInst Output device instance number - * @param devicePort Output port number - * @param deviceSlot Output slot number - * - */ -static bool vboxGetDeviceDetails(const char *deviceName, - PRUint32 *aMaxPortPerInst, - PRUint32 *aMaxSlotPerPort, - PRUint32 storageBus, - PRInt32 *deviceInst, - PRInt32 *devicePort, - PRInt32 *deviceSlot) -{ - int total =3D 0; - PRUint32 maxPortPerInst =3D 0; - PRUint32 maxSlotPerPort =3D 0; - - if (!deviceName || - !deviceInst || - !devicePort || - !deviceSlot || - !aMaxPortPerInst || - !aMaxSlotPerPort) - return false; - - if ((storageBus < StorageBus_IDE) || - (storageBus > StorageBus_Floppy)) - return false; - - total =3D virDiskNameToIndex(deviceName); - - maxPortPerInst =3D aMaxPortPerInst[storageBus]; - maxSlotPerPort =3D aMaxSlotPerPort[storageBus]; - - if (!maxPortPerInst || - !maxSlotPerPort || - (total < 0)) - return false; - - *deviceInst =3D total / (maxPortPerInst * maxSlotPerPort); - *devicePort =3D (total % (maxPortPerInst * maxSlotPerPort)) / maxSlotP= erPort; - *deviceSlot =3D (total % (maxPortPerInst * maxSlotPerPort)) % maxSlotP= erPort; - - VIR_DEBUG("name=3D%s, total=3D%d, storageBus=3D%u, deviceInst=3D%d, " - "devicePort=3D%d deviceSlot=3D%d, maxPortPerInst=3D%u maxSlotPer= Port=3D%u", - deviceName, total, storageBus, *deviceInst, *devicePort, - *deviceSlot, maxPortPerInst, maxSlotPerPort); - - return true; -} - /** * function to generate the name for medium, * for e.g: hda, sda, etc @@ -441,7 +385,7 @@ static char *vboxGenerateMediumName(PRUint32 storageBus, return NULL; =20 if ((storageBus < StorageBus_IDE) || - (storageBus > StorageBus_Floppy)) + (storageBus > StorageBus_SAS)) return NULL; =20 maxPortPerInst =3D aMaxPortPerInst[storageBus]; @@ -452,8 +396,9 @@ static char *vboxGenerateMediumName(PRUint32 storageBus, =20 if (storageBus =3D=3D StorageBus_IDE) { prefix =3D "hd"; - } else if ((storageBus =3D=3D StorageBus_SATA) || - (storageBus =3D=3D StorageBus_SCSI)) { + } else if (storageBus =3D=3D StorageBus_SATA || + storageBus =3D=3D StorageBus_SCSI || + storageBus =3D=3D StorageBus_SAS) { prefix =3D "sd"; } else if (storageBus =3D=3D StorageBus_Floppy) { prefix =3D "fd"; @@ -468,6 +413,124 @@ static char *vboxGenerateMediumName(PRUint32 storageB= us, return name; } =20 +static int +vboxSetStorageController(virDomainControllerDefPtr controller, + vboxDriverPtr data, IMachine *machine) +{ + PRUnichar *controllerName =3D NULL; + PRInt32 vboxModel =3D StorageControllerType_Null; + PRInt32 vboxBusType =3D StorageBus_Null; + IStorageController *vboxController =3D NULL; + nsresult rc =3D 0; + int ret =3D -1; + + /* libvirt controller type =3D> vbox bus type */ + switch (controller->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_FDC: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, &controllerName); + vboxBusType =3D StorageBus_Floppy; + + break; + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME, &controllerName); + vboxBusType =3D StorageBus_IDE; + + break; + case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, &controllerName); + vboxBusType =3D StorageBus_SCSI; + + break; + case VIR_DOMAIN_CONTROLLER_TYPE_SATA: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME, &controllerName); + vboxBusType =3D StorageBus_SATA; + + break; + } + + /* libvirt scsi model =3D> vbox scsi model */ + if (controller->type =3D=3D VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + switch (controller->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: + vboxModel =3D StorageControllerType_LsiLogic; + + break; + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: + vboxModel =3D StorageControllerType_BusLogic; + + break; + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: + /* in vbox, lsisas has a dedicated SAS bus type with no model = */ + VBOX_UTF16_FREE(controllerName); + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, &controllerName); + vboxBusType =3D StorageBus_SAS; + + break; + } + } + + /* libvirt ide model =3D> vbox ide model */ + if (controller->type =3D=3D VIR_DOMAIN_CONTROLLER_TYPE_IDE) { + switch (controller->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3: + vboxModel =3D StorageControllerType_PIIX3; + + break; + case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4: + vboxModel =3D StorageControllerType_PIIX4; + + break; + case VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6: + vboxModel =3D StorageControllerType_ICH6; + + break; + } + } + + rc =3D gVBoxAPI.UIMachine.AddStorageController(machine, controllerName, + vboxBusType, &vboxControl= ler); + + if (NS_FAILED(rc)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to add storage controller " + "(type: %s, index=3D%d), rc=3D%08x"), + virDomainControllerTypeToString(controller->type), + controller->idx, (unsigned) rc); + goto cleanup; + } + + if (vboxModel !=3D StorageControllerType_Null) { + rc =3D gVBoxAPI.UIStorageController.SetControllerType(vboxControll= er, + vboxModel); + if (NS_FAILED(rc)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to change storage controller model, " + "rc=3D%08x"), (unsigned) rc); + goto cleanup; + } + } + + ret =3D 0; + cleanup: + VBOX_UTF16_FREE(controllerName); + VBOX_RELEASE(vboxController); + + return ret; +} + +static int +vboxAttachStorageControllers(virDomainDefPtr def, vboxDriverPtr data, + IMachine *machine) +{ + size_t i; + for (i =3D 0; i < def->ncontrollers; i++) { + if (vboxSetStorageController(def->controllers[i], data, machine) <= 0) + return -1; + } + + return 0; +} + static virDrvOpenStatus vboxConnectOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, @@ -1017,209 +1080,168 @@ vboxSetBootDeviceOrder(virDomainDefPtr def, vboxD= riverPtr data, } } =20 -static void +static int vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machin= e) { + int ret =3D 0; size_t i; nsresult rc =3D 0; - PRUint32 maxPortPerInst[StorageBus_Floppy + 1] =3D {}; - PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] =3D {}; PRUnichar *storageCtlName =3D NULL; - bool error =3D false; + virDomainDiskDefPtr disk =3D NULL; =20 - /* get the max port/slots/etc for the given storage bus */ - error =3D !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, - maxSlotPerPort); - - /* add a storage controller for the mediums to be attached */ - /* this needs to change when multiple controller are supported for - * ver > 3.1 */ - { - IStorageController *storageCtl =3D NULL; - PRUnichar *sName =3D NULL; - - VBOX_UTF8_TO_UTF16("IDE Controller", &sName); - gVBoxAPI.UIMachine.AddStorageController(machine, - sName, - StorageBus_IDE, - &storageCtl); - VBOX_UTF16_FREE(sName); - VBOX_RELEASE(storageCtl); - - VBOX_UTF8_TO_UTF16("SATA Controller", &sName); - gVBoxAPI.UIMachine.AddStorageController(machine, - sName, - StorageBus_SATA, - &storageCtl); - VBOX_UTF16_FREE(sName); - VBOX_RELEASE(storageCtl); - - VBOX_UTF8_TO_UTF16("SCSI Controller", &sName); - gVBoxAPI.UIMachine.AddStorageController(machine, - sName, - StorageBus_SCSI, - &storageCtl); - VBOX_UTF16_FREE(sName); - VBOX_RELEASE(storageCtl); - - VBOX_UTF8_TO_UTF16("Floppy Controller", &sName); - gVBoxAPI.UIMachine.AddStorageController(machine, - sName, - StorageBus_Floppy, - &storageCtl); - VBOX_UTF16_FREE(sName); - VBOX_RELEASE(storageCtl); - } - - for (i =3D 0; i < def->ndisks && !error; i++) { - const char *src =3D virDomainDiskGetSource(def->disks[i]); - int type =3D virDomainDiskGetType(def->disks[i]); - int format =3D virDomainDiskGetFormat(def->disks[i]); - - VIR_DEBUG("disk(%zu) type: %d", i, type); - VIR_DEBUG("disk(%zu) device: %d", i, def->disks[i]->device); - VIR_DEBUG("disk(%zu) bus: %d", i, def->disks[i]->bus); - VIR_DEBUG("disk(%zu) src: %s", i, src); - VIR_DEBUG("disk(%zu) dst: %s", i, def->disks[i]->dst); - VIR_DEBUG("disk(%zu) driverName: %s", i, - virDomainDiskGetDriver(def->disks[i])); - VIR_DEBUG("disk(%zu) driverType: %s", i, - virStorageFileFormatTypeToString(format)); - VIR_DEBUG("disk(%zu) cachemode: %d", i, def->disks[i]->cachemode); - VIR_DEBUG("disk(%zu) readonly: %s", i, (def->disks[i]->src->read= only - ? "True" : "False")); - VIR_DEBUG("disk(%zu) shared: %s", i, (def->disks[i]->src->shar= ed - ? "True" : "False")); - - if (type =3D=3D VIR_STORAGE_TYPE_FILE && src) { - IMedium *medium =3D NULL; - vboxIID mediumUUID; - PRUnichar *mediumFileUtf16 =3D NULL; - PRUint32 storageBus =3D StorageBus_Null; - PRUint32 deviceType =3D DeviceType_Null; - PRUint32 accessMode =3D AccessMode_ReadOnly; - PRInt32 deviceInst =3D 0; - PRInt32 devicePort =3D 0; - PRInt32 deviceSlot =3D 0; + for (i =3D 0; i < def->ndisks; i++) { + disk =3D def->disks[i]; + const char *src =3D virDomainDiskGetSource(disk); + int type =3D virDomainDiskGetType(disk); =20 - VBOX_IID_INITIALIZE(&mediumUUID); - VBOX_UTF8_TO_UTF16(src, &mediumFileUtf16); + if (type !=3D VIR_STORAGE_TYPE_FILE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported storage type %s, the only suppor= ted " + "type is %s"), + virStorageTypeToString(type), + virStorageTypeToString(VIR_STORAGE_TYPE_FILE)); + return -1; + } =20 - if (def->disks[i]->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK) { - deviceType =3D DeviceType_HardDisk; - accessMode =3D AccessMode_ReadWrite; - } else if (def->disks[i]->device =3D=3D VIR_DOMAIN_DISK_DEVICE= _CDROM) { - deviceType =3D DeviceType_DVD; - accessMode =3D AccessMode_ReadOnly; - } else if (def->disks[i]->device =3D=3D VIR_DOMAIN_DISK_DEVICE= _FLOPPY) { - deviceType =3D DeviceType_Floppy; - accessMode =3D AccessMode_ReadWrite; - } else { - VBOX_UTF16_FREE(mediumFileUtf16); - continue; - } + if (!src && disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Missing disk source file path")); + return -1; + } =20 - gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, mediumFileUt= f16, - deviceType, accessMode, &me= dium); + IMedium *medium =3D NULL; + vboxIID mediumUUID; + PRUnichar *mediumFileUtf16 =3D NULL; + PRUint32 deviceType =3D DeviceType_Null; + PRUint32 accessMode =3D AccessMode_ReadOnly; + PRInt32 deviceSlot =3D disk->info.addr.drive.bus; + PRInt32 devicePort =3D disk->info.addr.drive.unit; + int model =3D -1; + + if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK) { + deviceType =3D DeviceType_HardDisk; + accessMode =3D AccessMode_ReadWrite; + } else if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_CDROM) { + deviceType =3D DeviceType_DVD; + accessMode =3D AccessMode_ReadOnly; + } else if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_FLOPPY) { + deviceType =3D DeviceType_Floppy; + accessMode =3D AccessMode_ReadWrite; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported disk device type %s"), + virDomainDiskDeviceTypeToString(disk->device)); + ret =3D -1; + goto cleanup; + } =20 - if (!medium) { - PRUnichar *mediumEmpty =3D NULL; + if (src) { + VBOX_IID_INITIALIZE(&mediumUUID); + VBOX_UTF8_TO_UTF16(src, &mediumFileUtf16); =20 - VBOX_UTF8_TO_UTF16("", &mediumEmpty); + rc =3D gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, mediu= mFileUtf16, + deviceType, accessMode= , &medium); =20 - rc =3D gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj, - mediumFileUtf16, - deviceType, accessMo= de, - &medium); - VBOX_UTF16_FREE(mediumEmpty); + /* The following is not needed for vbox 4.2+ but older version= s have + * distinct find and open operations where former looks in vbo= x media + * registry and latter at storage location. In 4.2+, the OpenM= edium call + * takes care of both cases internally. + */ + if (!medium) { + rc =3D gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj, med= iumFileUtf16, + deviceType, accessMo= de, &medium); } =20 if (!medium) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to attach the following disk/dvd/= floppy " - "to the machine: %s, rc=3D%08x"), + _("Failed to open the following disk/dvd/fl= oppy " + "image file: %s, rc=3D%08x"), src, (unsigned)rc); - VBOX_UTF16_FREE(mediumFileUtf16); - continue; + ret =3D -1; + goto cleanup; } =20 rc =3D gVBoxAPI.UIMedium.GetId(medium, &mediumUUID); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("can't get the uuid of the file to be att= ached " + _("Can't get the uuid of the file to be att= ached " "as harddisk/dvd/floppy: %s, rc=3D%08x"), src, (unsigned)rc); - VBOX_MEDIUM_RELEASE(medium); - VBOX_UTF16_FREE(mediumFileUtf16); - continue; + ret =3D -1; + goto cleanup; } + } =20 - if (def->disks[i]->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK) { - if (def->disks[i]->src->readonly) { - gVBoxAPI.UIMedium.SetType(medium, MediumType_Immutable= ); - VIR_DEBUG("setting harddisk to immutable"); - } else if (!def->disks[i]->src->readonly) { - gVBoxAPI.UIMedium.SetType(medium, MediumType_Normal); - VIR_DEBUG("setting harddisk type to normal"); - } + if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK) { + if (disk->src->readonly) { + gVBoxAPI.UIMedium.SetType(medium, MediumType_Immutable); + } else if (!disk->src->readonly) { + gVBoxAPI.UIMedium.SetType(medium, MediumType_Normal); } + } =20 - if (def->disks[i]->bus =3D=3D VIR_DOMAIN_DISK_BUS_IDE) { - VBOX_UTF8_TO_UTF16("IDE Controller", &storageCtlName); - storageBus =3D StorageBus_IDE; - } else if (def->disks[i]->bus =3D=3D VIR_DOMAIN_DISK_BUS_SATA)= { - VBOX_UTF8_TO_UTF16("SATA Controller", &storageCtlName); - storageBus =3D StorageBus_SATA; - } else if (def->disks[i]->bus =3D=3D VIR_DOMAIN_DISK_BUS_SCSI)= { - VBOX_UTF8_TO_UTF16("SCSI Controller", &storageCtlName); - storageBus =3D StorageBus_SCSI; - } else if (def->disks[i]->bus =3D=3D VIR_DOMAIN_DISK_BUS_FDC) { - VBOX_UTF8_TO_UTF16("Floppy Controller", &storageCtlName); - storageBus =3D StorageBus_Floppy; - } + /* asssociate bus to controller */ =20 - /* get the device details i.e instance, port and slot */ - if (!vboxGetDeviceDetails(def->disks[i]->dst, - maxPortPerInst, - maxSlotPerPort, - storageBus, - &deviceInst, - &devicePort, - &deviceSlot)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("can't get the port/slot number of " - "harddisk/dvd/floppy to be attached: " - "%s, rc=3D%08x"), - src, (unsigned)rc); - VBOX_MEDIUM_RELEASE(medium); - vboxIIDUnalloc(&mediumUUID); - VBOX_UTF16_FREE(mediumFileUtf16); - continue; - } + switch (disk->bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME, &storageCtlName); =20 - /* attach the harddisk/dvd/Floppy to the storage controller */ - rc =3D gVBoxAPI.UIMachine.AttachDevice(machine, - storageCtlName, - devicePort, - deviceSlot, - deviceType, - medium); + break; =20 - if (NS_FAILED(rc)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("could not attach the file as " - "harddisk/dvd/floppy: %s, rc=3D%08x"), - src, (unsigned)rc); - } else { - DEBUGIID("Attached HDD/DVD/Floppy with UUID", &mediumUUID); + case VIR_DOMAIN_DISK_BUS_SATA: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME, &storageCtlName); + + break; + + case VIR_DOMAIN_DISK_BUS_SCSI: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, &storageCtlName); + + model =3D virDomainDeviceFindControllerModel(def, &disk->info, + VIR_DOMAIN_CONTROLL= ER_TYPE_SCSI); + + /* if the model is lsisas1068, set vbox bus type to SAS */ + if (model =3D=3D VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) { + VBOX_UTF16_FREE(storageCtlName); + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, &storageCtlNa= me); } =20 - VBOX_MEDIUM_RELEASE(medium); - vboxIIDUnalloc(&mediumUUID); - VBOX_UTF16_FREE(mediumFileUtf16); - VBOX_UTF16_FREE(storageCtlName); + break; + + case VIR_DOMAIN_DISK_BUS_FDC: + VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, &storageCtlNam= e); + devicePort =3D 0; + deviceSlot =3D disk->info.addr.drive.unit; + + break; } + + /* attach the harddisk/dvd/Floppy to the storage controller */ + rc =3D gVBoxAPI.UIMachine.AttachDevice(machine, + storageCtlName, + devicePort, + deviceSlot, + deviceType, + medium); + + if (NS_FAILED(rc)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not attach the file as " + "harddisk/dvd/floppy: %s, rc=3D%08x"), + src, (unsigned)rc); + ret =3D -1; + } + + cleanup: + vboxIIDUnalloc(&mediumUUID); + VBOX_MEDIUM_RELEASE(medium); + VBOX_UTF16_FREE(mediumFileUtf16); + VBOX_UTF16_FREE(storageCtlName); + + if (ret < 0) + break; } + + return ret; } =20 static void @@ -1853,6 +1875,7 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const ch= ar *xml, unsigned int flags char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainPtr ret =3D NULL; unsigned int parse_flags =3D VIR_DOMAIN_DEF_PARSE_INACTIVE; + int success =3D 0; =20 virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL); =20 @@ -1948,7 +1971,10 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const c= har *xml, unsigned int flags gVBoxAPI.UISession.GetMachine(data->vboxSession, &machine); =20 vboxSetBootDeviceOrder(def, data, machine); - vboxAttachDrives(def, data, machine); + if (vboxAttachStorageControllers(def, data, machine) < 0) + goto cleanup; + if (vboxAttachDrives(def, data, machine) < 0) + goto cleanup; vboxAttachSound(def, machine); if (vboxAttachNetwork(def, data, machine) < 0) goto cleanup; @@ -1959,30 +1985,40 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const = char *xml, unsigned int flags vboxAttachUSB(def, data, machine); vboxAttachSharedFolder(def, data, machine); =20 - /* Save the machine settings made till now and close the - * session. also free up the mchiid variable used. - */ + success =3D 1; + + cleanup: + /* Save the machine settings made till now, even if incomplete */ rc =3D gVBoxAPI.UIMachine.SaveSettings(machine); - if (NS_FAILED(rc)) { + if (NS_FAILED(rc)) virReportError(VIR_ERR_INTERNAL_ERROR, - _("failed no saving settings, rc=3D%08x"), (unsigne= d)rc); - goto cleanup; + _("failed to save VM settings, rc=3D%08x"), + (unsigned) rc); + + if (success) { + ret =3D virGetDomain(conn, def->name, def->uuid, -1); + } else { + /* Unregister incompletely configured VM to not leave garbage behi= nd */ + gVBoxAPI.UISession.Close(data->vboxSession); + rc =3D gVBoxAPI.unregisterMachine(data, &mchiid, &machine); + if (NS_SUCCEEDED(rc)) { + gVBoxAPI.deleteConfig(machine); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("could not cleanup partial domain after failu= re " + "to define, rc=3D%08x"), + (unsigned) rc); + } } =20 gVBoxAPI.UISession.Close(data->vboxSession); vboxIIDUnalloc(&mchiid); =20 - ret =3D virGetDomain(conn, def->name, def->uuid, -1); VBOX_RELEASE(machine); =20 virDomainDefFree(def); =20 return ret; - - cleanup: - VBOX_RELEASE(machine); - virDomainDefFree(def); - return NULL; } =20 static virDomainPtr @@ -3057,8 +3093,8 @@ vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr da= ta, IMachine *machine) bool error =3D false; int diskCount =3D 0; size_t i; - PRUint32 maxPortPerInst[StorageBus_Floppy + 1] =3D {}; - PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] =3D {}; + PRUint32 maxPortPerInst[StorageBus_SAS + 1] =3D {}; + PRUint32 maxSlotPerPort[StorageBus_SAS + 1] =3D {}; =20 def->ndisks =3D 0; gVBoxAPI.UArray.vboxArrayGet(&mediumAttachments, machine, @@ -3151,7 +3187,8 @@ vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr da= ta, IMachine *machine) def->disks[diskCount]->bus =3D VIR_DOMAIN_DISK_BUS_IDE; } else if (storageBus =3D=3D StorageBus_SATA) { def->disks[diskCount]->bus =3D VIR_DOMAIN_DISK_BUS_SATA; - } else if (storageBus =3D=3D StorageBus_SCSI) { + } else if (storageBus =3D=3D StorageBus_SCSI || + storageBus =3D=3D StorageBus_SAS) { def->disks[diskCount]->bus =3D VIR_DOMAIN_DISK_BUS_SCSI; } else if (storageBus =3D=3D StorageBus_Floppy) { def->disks[diskCount]->bus =3D VIR_DOMAIN_DISK_BUS_FDC; diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h index b08ad1e3e..23940fc63 100644 --- a/src/vbox/vbox_common.h +++ b/src/vbox/vbox_common.h @@ -326,6 +326,14 @@ enum HardDiskVariant # define VBOX_E_INVALID_SESSION_STATE 0x80BB000B # define VBOX_E_OBJECT_IN_USE 0x80BB000C =20 +/* VBOX storage controller name definitions */ +# define VBOX_CONTROLLER_IDE_NAME "IDE Controller" +# define VBOX_CONTROLLER_FLOPPY_NAME "Floppy Controller" +# define VBOX_CONTROLLER_SATA_NAME "SATA Controller" +# define VBOX_CONTROLLER_SCSI_NAME "SCSI Controller" +# define VBOX_CONTROLLER_SAS_NAME "SAS Controller" + + /* Simplied definitions in vbox_CAPI_*.h */ =20 typedef void const *PCVBOXXPCOM; diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 6592cbd63..b7ced62dc 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -684,7 +684,9 @@ _virtualboxCreateHardDisk(IVirtualBox *vboxObj, PRUnich= ar *format, #if VBOX_API_VERSION < 5000000 return vboxObj->vtbl->CreateHardDisk(vboxObj, format, location, medium= ); #elif VBOX_API_VERSION >=3D 5000000 /*VBOX_API_VERSION >=3D 5000000*/ - return vboxObj->vtbl->CreateMedium(vboxObj, format, location, AccessMo= de_ReadWrite, DeviceType_HardDisk, medium); + return vboxObj->vtbl->CreateMedium(vboxObj, format, location, + AccessMode_ReadWrite, + DeviceType_HardDisk, medium); #endif /*VBOX_API_VERSION >=3D 5000000*/ } =20 @@ -696,37 +698,28 @@ _virtualboxRegisterMachine(IVirtualBox *vboxObj, IMac= hine *machine) =20 static nsresult _virtualboxFindHardDisk(IVirtualBox *vboxObj, PRUnichar *location, - PRUint32 deviceType ATTRIBUTE_UNUSED, - PRUint32 accessMode ATTRIBUTE_UNUSED, - IMedium **medium) + PRUint32 deviceType, + PRUint32 accessMode ATTRIBUTE_UNUSED, IMedium **me= dium) { #if VBOX_API_VERSION < 4002000 - return vboxObj->vtbl->FindMedium(vboxObj, location, - deviceType, medium); + return vboxObj->vtbl->FindMedium(vboxObj, location, deviceType, medium= ); #else /* VBOX_API_VERSION >=3D 4002000 */ - return vboxObj->vtbl->OpenMedium(vboxObj, location, - deviceType, accessMode, PR_FALSE, med= ium); + return vboxObj->vtbl->OpenMedium(vboxObj, location, deviceType, access= Mode, + PR_FALSE, medium); #endif /* VBOX_API_VERSION >=3D 4002000 */ } =20 static nsresult -_virtualboxOpenMedium(IVirtualBox *vboxObj ATTRIBUTE_UNUSED, - PRUnichar *location ATTRIBUTE_UNUSED, - PRUint32 deviceType ATTRIBUTE_UNUSED, - PRUint32 accessMode ATTRIBUTE_UNUSED, - IMedium **medium ATTRIBUTE_UNUSED) +_virtualboxOpenMedium(IVirtualBox *vboxObj, PRUnichar *location, + PRUint32 deviceType, PRUint32 accessMode, + IMedium **medium) { #if VBOX_API_VERSION =3D=3D 4000000 - return vboxObj->vtbl->OpenMedium(vboxObj, - location, - deviceType, accessMode, + return vboxObj->vtbl->OpenMedium(vboxObj, location, deviceType, access= Mode, medium); #elif VBOX_API_VERSION >=3D 4001000 - return vboxObj->vtbl->OpenMedium(vboxObj, - location, - deviceType, accessMode, - false, - medium); + return vboxObj->vtbl->OpenMedium(vboxObj, location, deviceType, access= Mode, + false, medium); #endif } =20 @@ -778,12 +771,8 @@ _machineGetStorageControllerByName(IMachine *machine, = PRUnichar *name, } =20 static nsresult -_machineAttachDevice(IMachine *machine ATTRIBUTE_UNUSED, - PRUnichar *name ATTRIBUTE_UNUSED, - PRInt32 controllerPort ATTRIBUTE_UNUSED, - PRInt32 device ATTRIBUTE_UNUSED, - PRUint32 type ATTRIBUTE_UNUSED, - IMedium * medium ATTRIBUTE_UNUSED) +_machineAttachDevice(IMachine *machine, PRUnichar *name, PRInt32 controlle= rPort, + PRInt32 device, PRUint32 type, IMedium * medium) { return machine->vtbl->AttachDevice(machine, name, controllerPort, device, type, medium); --=20 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list