diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c index f421af5121..a7b2285886 100644 --- a/src/ch/ch_conf.c +++ b/src/ch/ch_conf.c @@ -22,6 +22,7 @@ #include "configmake.h" #include "vircommand.h" +#include "virfile.h" #include "virlog.h" #include "virobject.h" #include "virstring.h" @@ -67,8 +68,16 @@ virCaps *virCHDriverCapsInit(void) guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, caps->host.arch, NULL, NULL, 0, NULL); - virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM, - NULL, NULL, 0, NULL); + if (virFileExists("/dev/kvm")) { + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM, + NULL, NULL, 0, NULL); + } + + if (virFileExists("/dev/mshv")) { + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV, + NULL, NULL, 0, NULL); + } + return g_steal_pointer(&caps); } diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index 96de5044ac..2601eea44b 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -889,6 +889,15 @@ static int chStateInitialize(bool privileged, if (!(ch_driver->caps = virCHDriverCapsInit())) goto cleanup; + if (!virCapabilitiesDomainSupported(ch_driver->caps, -1, + VIR_ARCH_NONE, VIR_DOMAIN_VIRT_KVM) && + !virCapabilitiesDomainSupported(ch_driver->caps, -1, + VIR_ARCH_NONE, VIR_DOMAIN_VIRT_HYPERV)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("/dev/kvm and /dev/mshv are missing. CH driver failed to initialize.")); + return VIR_DRV_STATE_INIT_ERROR; + } + if (!(ch_driver->xmlopt = chDomainXMLConfInit(ch_driver))) goto cleanup; diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c index b371181fb2..7488b1d65d 100644 --- a/src/ch/ch_process.c +++ b/src/ch/ch_process.c @@ -644,6 +644,46 @@ chProcessAddNetworkDevices(virCHDriver *driver, return 0; } +/** + * virCHProcessStartValidate: + * @driver: pointer to driver structure + * @vm: domain object + * + * Checks done before starting a VM. + * + * Returns 0 on success or -1 in case of error + */ +static int +virCHProcessStartValidate(virCHDriver *driver, + virDomainObj *vm) +{ + if (vm->def->virtType == VIR_DOMAIN_VIRT_KVM) { + VIR_DEBUG("Checking for KVM availability"); + if (!virCapabilitiesDomainSupported(driver->caps, -1, + VIR_ARCH_NONE, VIR_DOMAIN_VIRT_KVM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Domain requires KVM, but it is not available. Check that virtualization is enabled in the host BIOS, and host configuration is setup to load the kvm modules.")); + return -1; + } + } else if (vm->def->virtType == VIR_DOMAIN_VIRT_HYPERV) { + VIR_DEBUG("Checking for mshv availability"); + if (!virCapabilitiesDomainSupported(driver->caps, -1, + VIR_ARCH_NONE, VIR_DOMAIN_VIRT_HYPERV)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Domain requires MSHV device, but it is not available. Check that virtualization is enabled in the host BIOS, and host configuration is setup to load the mshv modules.")); + return -1; + } + + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("virt type '%1$s' is not supported"), + virDomainVirtTypeToString(vm->def->virtType)); + return -1; + } + + return 0; +} + /** * virCHProcessStart: * @driver: pointer to driver structure @@ -671,6 +711,10 @@ virCHProcessStart(virCHDriver *driver, return -1; } + if (virCHProcessStartValidate(driver, vm) < 0) { + return -1; + } + if (!priv->monitor) { /* And we can get the first monitor connection now too */ if (!(priv->monitor = virCHProcessConnectMonitor(driver, vm))) {