]> xenbits.xensource.com Git - libvirt.git/commitdiff
ch: Enable hyperv hypervisor
authorPraveen K Paladugu <prapal@linux.microsoft.com>
Tue, 20 Feb 2024 22:06:03 +0000 (16:06 -0600)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 8 Mar 2024 12:01:00 +0000 (13:01 +0100)
Cloud-Hypervisor is capable of running VMs with kvm or mshv as the
hypervisor on Linux Host. Guest to hypevisor ABI with mshv hypervisor is
the same as in the case of VIR_DOMAIN_VIRT_HYPERV. So, VIR_DOMAIN_VIRT_HYPERV
type will be reused to represent the config with Linux Host and mshv as the
hypervisor.

While initializing ch driver, check if either of /dev/kvm or /dev/mshv
device is present on the host. Before starting ch domains, check if the
requested hypervisor device is present on the host.

Users can specify hypervisor in ch guests's domain definitions like
below:

<domain type='kvm'>

_or_

<domain type='hyperv'>

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Signed-off-by: Praveen K Paladugu <praveenkpaladugu@gmail.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/ch/ch_conf.c
src/ch/ch_driver.c
src/ch/ch_process.c

index f421af51212173945715a0d01df2d00e00fb8e1d..a7b228588634f6709cf8b4f25f38407063e87618 100644 (file)
@@ -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);
 }
 
index 96de5044ac57b695170664d7b0088d260d966ea8..2601eea44b0610a0b8efbc7c917aa7651a93f8a5 100644 (file)
@@ -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;
 
index b371181fb2299ace60bc3fa0656da1bca3afa692..7488b1d65d44ca3627175fd5e928f1010e077afd 100644 (file)
@@ -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))) {