On 01/05/2017 09:46 AM, Roman Bogorodskiy wrote:
As bhyve for a long time didn't have a notion of the explicit
SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
---
po/POTFILES.in | 1 +
src/bhyve/bhyve_command.c | 143 ++++++++++++++++-----
src/bhyve/bhyve_device.c | 33 ++---
src/bhyve/bhyve_domain.c | 60 ++++++++-
.../bhyvexml2argvdata/bhyvexml2argv-acpiapic.args | 4 +-
tests/bhyvexml2argvdata/bhyvexml2argv-base.args | 4 +-
.../bhyvexml2argv-bhyveload-bootorder.args | 5 +-
.../bhyvexml2argv-bhyveload-bootorder1.args | 5 +-
.../bhyvexml2argv-bhyveload-bootorder3.args | 5 +-
.../bhyvexml2argv-bhyveload-explicitargs.args | 4 +-
tests/bhyvexml2argvdata/bhyvexml2argv-console.args | 2 +-
.../bhyvexml2argv-custom-loader.args | 4 +-
.../bhyvexml2argv-disk-cdrom-grub.args | 4 +-
.../bhyvexml2argv-disk-cdrom.args | 4 +-
.../bhyvexml2argv-grub-bootorder.args | 6 +-
.../bhyvexml2argv-grub-bootorder2.args | 6 +-
.../bhyvexml2argv-grub-defaults.args | 4 +-
.../bhyvexml2argvdata/bhyvexml2argv-localtime.args | 4 +-
tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args | 4 +-
.../bhyvexml2argv-serial-grub-nocons.args | 2 +-
.../bhyvexml2argv-serial-grub.args | 2 +-
tests/bhyvexml2argvdata/bhyvexml2argv-serial.args | 2 +-
tests/bhyvexml2argvtest.c | 2 +-
.../bhyvexml2xmlout-acpiapic.xml | 4 +-
tests/bhyvexml2xmloutdata/bhyvexml2xmlout-base.xml | 4 +-
.../bhyvexml2xmlout-bhyveload-bootorder.xml | 4 +-
.../bhyvexml2xmlout-bhyveload-bootorder1.xml | 4 +-
.../bhyvexml2xmlout-bhyveload-bootorder2.xml | 4 +-
.../bhyvexml2xmlout-bhyveload-bootorder3.xml | 4 +-
.../bhyvexml2xmlout-bhyveload-bootorder4.xml | 4 +-
.../bhyvexml2xmlout-bhyveload-explicitargs.xml | 4 +-
.../bhyvexml2xmlout-console.xml | 4 +-
.../bhyvexml2xmlout-custom-loader.xml | 4 +-
.../bhyvexml2xmlout-disk-cdrom-grub.xml | 4 +-
.../bhyvexml2xmlout-disk-cdrom.xml | 4 +-
.../bhyvexml2xmlout-grub-bootorder.xml | 4 +-
.../bhyvexml2xmlout-grub-bootorder2.xml | 4 +-
.../bhyvexml2xmlout-grub-defaults.xml | 4 +-
.../bhyvexml2xmlout-localtime.xml | 4 +-
.../bhyvexml2xmlout-macaddr.xml | 4 +-
.../bhyvexml2xmlout-metadata.xml | 5 +-
.../bhyvexml2xmlout-serial-grub-nocons.xml | 4 +-
.../bhyvexml2xmlout-serial-grub.xml | 4 +-
.../bhyvexml2xmloutdata/bhyvexml2xmlout-serial.xml | 4 +-
tests/bhyvexml2xmltest.c | 2 +
45 files changed, 279 insertions(+), 118 deletions(-)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e66bb7a3a..632aa7736 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,6 +14,7 @@ src/access/viraccessdriverpolkit.c
src/access/viraccessmanager.c
src/bhyve/bhyve_command.c
src/bhyve/bhyve_device.c
+src/bhyve/bhyve_domain.c
src/bhyve/bhyve_driver.c
src/bhyve/bhyve_monitor.c
src/bhyve/bhyve_parse_command.c
diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 8a29977ff..a2fd40378 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -148,40 +148,97 @@ bhyveBuildConsoleArgStr(const virDomainDef *def, virCommandPtr
cmd)
}
static int
-bhyveBuildDiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk,
- virCommandPtr cmd)
+bhyveBuildAHCIControllerArgStr(const virDomainDef *def,
+ virDomainControllerDefPtr controller,
+ virConnectPtr conn,
+ virCommandPtr cmd)
{
- const char *bus_type;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virBuffer device = VIR_BUFFER_INITIALIZER;
const char *disk_source;
+ size_t i;
+ int ret = -1;
+
+ for (i = 0; i < def->ndisks; i++) {
+ virDomainDiskDefPtr disk = def->disks[i];
+ if (disk->bus != VIR_DOMAIN_DISK_BUS_SATA)
+ continue;
+
+ if (disk->info.addr.drive.controller != controller->idx)
+ continue;
Took a minute for me to see why you were doing this - so all the disks
attached to a controller are put directly into the controller's
commandline arg rather than them being separate args with a ref back to
the controller.
+
+ VIR_DEBUG("disk %zu controller %d", i, controller->idx);
+
+ if ((virDomainDiskGetType(disk) != VIR_STORAGE_TYPE_FILE) &&
+ (virDomainDiskGetType(disk) != VIR_STORAGE_TYPE_VOLUME)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unsupported disk type"));
+ goto error;
+ }
+
+ if (virStorageTranslateDiskSourcePool(conn, disk) < 0)
+ goto error;
+
+ disk_source = virDomainDiskGetSource(disk);
+
+ if ((disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
+ (disk_source == NULL)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("cdrom device without source path "
+ "not supported"));
+ goto error;
+ }
- switch (disk->bus) {
- case VIR_DOMAIN_DISK_BUS_SATA:
switch (disk->device) {
case VIR_DOMAIN_DISK_DEVICE_DISK:
- bus_type = "ahci-hd";
+ if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_AHCI32SLOT) != 0)
The "!= 0" is superfluous.
+ virBufferAsprintf(&device, ",hd:%s",
disk_source);
+ else
+ virBufferAsprintf(&device, "-hd,%s", disk_source);
break;
case VIR_DOMAIN_DISK_DEVICE_CDROM:
- bus_type = "ahci-cd";
+ if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_AHCI32SLOT) != 0)
Same here.
+ virBufferAsprintf(&device, ",cd:%s",
disk_source);
+ else
+ virBufferAsprintf(&device, "-cd,%s", disk_source);
It seems like there could be some consolidation of the multiple
nearly-identical printf's here. Possibly not worth the trouble though.
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("unsupported disk device"));
- return -1;
- }
- break;
- case VIR_DOMAIN_DISK_BUS_VIRTIO:
- if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
- bus_type = "virtio-blk";
- } else {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("unsupported disk device"));
- return -1;
+ goto error;
}
- break;
- default:
+ virBufferAddBuffer(&buf, &device);
+ virBufferFreeAndReset(&device);
+ }
+
+ if (virBufferCheckError(&buf) <0)
+ goto error;
+
+ virCommandAddArg(cmd, "-s");
+ virCommandAddArgFormat(cmd, "%d:0,ahci%s",
+ controller->info.addr.pci.slot,
+ virBufferCurrentContent(&buf));
+
+ ret = 0;
+ error:
+ virBufferFreeAndReset(&buf);
+ return ret;
+}
+
+static int
+bhyveBuildVirtIODiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk,
+ virConnectPtr conn,
+ virCommandPtr cmd)
+{
+ const char *disk_source;
+
+ if (virStorageTranslateDiskSourcePool(conn, disk) < 0)
+ return -1;
+
+ if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("unsupported disk bus type"));
+ _("unsupported disk device"));
return -1;
}
@@ -194,17 +251,9 @@ bhyveBuildDiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED,
disk_source = virDomainDiskGetSource(disk);
- if ((disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
- (disk_source == NULL)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("cdrom device without source path "
- "not supported"));
- return -1;
- }
-
virCommandAddArg(cmd, "-s");
- virCommandAddArgFormat(cmd, "%d:0,%s,%s",
- disk->info.addr.pci.slot, bus_type,
+ virCommandAddArgFormat(cmd, "%d:0,virtio-blk,%s",
+ disk->info.addr.pci.slot,
disk_source);
return 0;
@@ -278,6 +327,22 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL);
/* Devices */
+ for (i = 0; i < def->ncontrollers; i++) {
+ virDomainControllerDefPtr controller = def->controllers[i];
+ switch (controller->type) {
+ case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
+ if (controller->model != VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s", _("unsupported PCI
controller model: only PCI root supported"));
+ goto error;
+ }
+ break;
+ case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
+ if (bhyveBuildAHCIControllerArgStr(def, controller, conn, cmd) < 0)
+ goto error;
+ break;
+ }
+ }
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
if (bhyveBuildNetArgStr(def, net, cmd, dryRun) < 0)
@@ -286,11 +351,19 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
for (i = 0; i < def->ndisks; i++) {
virDomainDiskDefPtr disk = def->disks[i];
- if (virStorageTranslateDiskSourcePool(conn, disk) < 0)
- goto error;
-
- if (bhyveBuildDiskArgStr(def, disk, cmd) < 0)
+ switch (disk->bus) {
+ case VIR_DOMAIN_DISK_BUS_SATA:
+ /* Handled by AHCI controller */
+ break;
This is a bit odd, but I see why you're doing it. Maybe you should put
the full name of the function (bhyveBuildAHCIControllerArgStr) in the
comment rather than just "AHCI controller".
Aside from these minor nits, my only concern is that of compatibility
when migrating forward and backward, but since I don't have a system
with bhyve I can't test that, so I'll assume that you've done your due
diligence in that regard. (Also, I'm assuming that you've successfully
run make syntax-check in addition to make check). Based on those
assumptions, ACK.