Up until now, the default has been rtl8139, but no check was in
place to make sure that device was actually available.
Now we try rtl8139, e1000 and virtio-net in turn, checking for
availability before using any of them: this means we have a much
better chance for the guest to be able to boot.
---
src/qemu/qemu_domain.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 91c632c..33cd463 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1193,7 +1193,8 @@ qemuDomainDefPostParse(virDomainDefPtr def,
}
static const char *
-qemuDomainDefaultNetModel(const virDomainDef *def)
+qemuDomainDefaultNetModel(const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps)
{
if (ARCH_IS_S390(def->os.arch))
return "virtio";
@@ -1211,7 +1212,23 @@ qemuDomainDefaultNetModel(const virDomainDef *def)
return "lan9118";
}
- return "rtl8139";
+ /* Try several network devices in turn; each of these devices is
+ * less likely be supported out-of-the-box by the guest operating
+ * system than the previous one.
+ *
+ * Note: Using rtl8139 as a last resort, even though by the time
+ * we get there we already know that it's not available, is an
+ * ugly hack needed to work around the fact that we don't have
+ * a way to mock capabilities in the test suite yet. Once we do,
+ * we should return NULL and raise an error instead */
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_RTL8139))
+ return "rtl8139";
+ else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_E1000))
+ return "e1000";
+ else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_NET))
+ return "virtio";
+ else
+ return "rtl8139";
}
static int
@@ -1220,18 +1237,24 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
virCapsPtr caps ATTRIBUTE_UNUSED,
void *opaque)
{
- int ret = -1;
virQEMUDriverPtr driver = opaque;
+ virQEMUCapsPtr qemuCaps = NULL;
virQEMUDriverConfigPtr cfg = NULL;
+ int ret = -1;
if (driver)
cfg = virQEMUDriverGetConfig(driver);
+ /* This condition is actually a (temporary) hack for test suite which
+ * does not create capabilities cache */
+ if (driver && driver->qemuCapsCache)
+ qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator);
+
if (dev->type == VIR_DOMAIN_DEVICE_NET &&
dev->data.net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
!dev->data.net->model) {
if (VIR_STRDUP(dev->data.net->model,
- qemuDomainDefaultNetModel(def)) < 0)
+ qemuDomainDefaultNetModel(def, qemuCaps)) < 0)
goto cleanup;
}
@@ -1357,6 +1380,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
ret = 0;
cleanup:
+ virObjectUnref(qemuCaps);
virObjectUnref(cfg);
return ret;
}
--
2.4.3