--- /dev/null
+/*
+ * Copyright Microsoft Corp. 2023
+ *
+ * ch_capabilities.h: CH capabilities
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "ch_capabilities.h"
+
+static void
+virCHCapsSet(virBitmap *chCaps,
+ virCHCapsFlags flag)
+{
+ ignore_value(virBitmapSetBit(chCaps, flag));
+}
+
+/**
+ * virCHCapsInitCHVersionCaps:
+ *
+ * Set all CH capabilities based on version of CH.
+ */
+virBitmap *
+virCHCapsInitCHVersionCaps(int version)
+{
+ g_autoptr(virBitmap) chCaps = NULL;
+ chCaps = virBitmapNew(CH_CAPS_LAST);
+
+ /* Version 28 deprecated kernel API:
+ * https://github.com/cloud-hypervisor/cloud-hypervisor/releases/tag/v28.0
+ */
+ if (version >= 28000000)
+ virCHCapsSet(chCaps, CH_KERNEL_API_DEPRCATED);
+
+
+ /* Starting Version 18, serial and console can be used in parallel */
+ if (version >= 18000000)
+ virCHCapsSet(chCaps, CH_SERIAL_CONSOLE_IN_PARALLEL);
+
+ return g_steal_pointer(&chCaps);
+
+}
--- /dev/null
+/*
+ * Copyright Microsoft Corp. 2023
+ *
+ * ch_capabilities.h: CH capabilities
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include "virbitmap.h"
+
+
+typedef enum {
+ /* 0 */
+ CH_KERNEL_API_DEPRCATED, /* Use `payload` in place of `kernel` api */
+ CH_SERIAL_CONSOLE_IN_PARALLEL, /* Serial and Console ports can work in parallel */
+
+ CH_CAPS_LAST /* this must always be the last item */
+} virCHCapsFlags;
+
+virBitmap *
+virCHCapsInitCHVersionCaps(int version);
#include "virdomainobjlist.h"
#include "virthread.h"
+#include "ch_capabilities.h"
#define CH_DRIVER_NAME "CH"
#define CH_CMD "cloud-hypervisor"
* lockless access thereafter */
virCaps *caps;
+ /* Immutable pointer, Immutable object
+ * Initialized once and reused as needed
+ */
+ virBitmap *chCaps;
+
/* Immutable pointer, Immutable object */
virDomainXMLOption *xmlopt;
#include <config.h>
+#include "ch_capabilities.h"
#include "ch_conf.h"
#include "ch_domain.h"
#include "ch_driver.h"
goto cleanup;
}
+ ch_driver->chCaps = virCHCapsInitCHVersionCaps(ch_driver->version);
+
ch_driver->privileged = privileged;
ret = VIR_DRV_STATE_INIT_COMPLETE;
return 0;
}
+static int
+virCHMonitorBuildPayloadJson(virJSONValue *content, virDomainDef *vmdef)
+{
+ g_autoptr(virJSONValue) payload = virJSONValueNewObject();
+
+
+ if (vmdef->os.kernel == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Kernel image path in this domain is not defined"));
+ return -1;
+ } else {
+ if (virJSONValueObjectAppendString(payload, "kernel", vmdef->os.kernel) < 0)
+ return -1;
+ }
+
+ if (vmdef->os.cmdline) {
+ if (virJSONValueObjectAppendString(payload, "cmdline", vmdef->os.cmdline) < 0)
+ return -1;
+ }
+
+ if (vmdef->os.initrd != NULL) {
+ if (virJSONValueObjectAppendString(payload, "initramfs", vmdef->os.initrd) < 0)
+ return -1;
+ }
+
+ if (virJSONValueObjectAppend(content, "payload", &payload) < 0)
+ return -1;
+
+ return 0;
+}
+
static int
virCHMonitorBuildKernelRelatedJson(virJSONValue *content, virDomainDef *vmdef)
{
}
static int
-virCHMonitorBuildVMJson(virDomainDef *vmdef,
+virCHMonitorBuildVMJson(virCHDriver *driver,
+ virDomainDef *vmdef,
char **jsonstr,
size_t *nnicindexes,
int **nicindexes)
if (virCHMonitorBuildMemoryJson(content, vmdef) < 0)
return -1;
- if (virCHMonitorBuildKernelRelatedJson(content, vmdef) < 0)
- return -1;
+ if (virBitmapIsBitSet(driver->chCaps, CH_KERNEL_API_DEPRCATED)) {
+ if (virCHMonitorBuildPayloadJson(content, vmdef) < 0)
+ return -1;
+ } else if (virCHMonitorBuildKernelRelatedJson(content, vmdef) < 0) {
+ return -1;
+ }
+
if (virCHMonitorBuildDisksJson(content, vmdef) < 0)
return -1;
}
int
-virCHMonitorCreateVM(virCHMonitor *mon,
+virCHMonitorCreateVM(virCHDriver *driver,
+ virCHMonitor *mon,
size_t *nnicindexes,
int **nicindexes)
{
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
- if (virCHMonitorBuildVMJson(mon->vm->def, &payload,
+ if (virCHMonitorBuildVMJson(driver, mon->vm->def, &payload,
nnicindexes, nicindexes) != 0)
return -1;
#include "virobject.h"
#include "virjson.h"
#include "domain_conf.h"
+#include "ch_conf.h"
#define URL_ROOT "http://localhost/api/v1"
#define URL_VMM_SHUTDOWN "vmm.shutdown"
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCHMonitor, virCHMonitorClose);
-int virCHMonitorCreateVM(virCHMonitor *mon,
+int virCHMonitorCreateVM(virCHDriver *driver,
+ virCHMonitor *mon,
size_t *nnicindexes,
int **nicindexes);
int virCHMonitorBootVM(virCHMonitor *mon);
goto cleanup;
}
- if (virCHMonitorCreateVM(priv->monitor,
+ if (virCHMonitorCreateVM(driver, priv->monitor,
&nnicindexes, &nicindexes) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to create guest VM"));
ch_driver_sources = [
+ 'ch_capabilities.h',
+ 'ch_capabilities.c',
'ch_conf.c',
'ch_conf.h',
'ch_domain.c',