Starting with v28.0 cloud-hypervisor requires the use of "payload" api to pass
kernel, initramfs and cmdline options. Extend ch driver to use the new
api based on ch version.
Signed-off-by: Praveen K Paladugu <prapal(a)linux.microsoft.com>
---
src/ch/ch_capabilities.c | 55 ++++++++++++++++++++++++++++++++++++++++
src/ch/ch_capabilities.h | 34 +++++++++++++++++++++++++
src/ch/ch_conf.h | 6 +++++
src/ch/ch_driver.c | 3 +++
src/ch/ch_monitor.c | 48 +++++++++++++++++++++++++++++++----
src/ch/ch_monitor.h | 4 ++-
src/ch/ch_process.c | 2 +-
src/ch/meson.build | 2 ++
8 files changed, 147 insertions(+), 7 deletions(-)
create mode 100644 src/ch/ch_capabilities.c
create mode 100644 src/ch/ch_capabilities.h
diff --git a/src/ch/ch_capabilities.c b/src/ch/ch_capabilities.c
new file mode 100644
index 0000000000..b10485820c
--- /dev/null
+++ b/src/ch/ch_capabilities.c
@@ -0,0 +1,55 @@
+/*
+ * 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);
+
+}
diff --git a/src/ch/ch_capabilities.h b/src/ch/ch_capabilities.h
new file mode 100644
index 0000000000..703a6dbfe2
--- /dev/null
+++ b/src/ch/ch_capabilities.h
@@ -0,0 +1,34 @@
+/*
+ * 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);
diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
index b927621a97..5b9b42540d 100644
--- a/src/ch/ch_conf.h
+++ b/src/ch/ch_conf.h
@@ -22,6 +22,7 @@
#include "virdomainobjlist.h"
#include "virthread.h"
+#include "ch_capabilities.h"
#define CH_DRIVER_NAME "CH"
#define CH_CMD "cloud-hypervisor"
@@ -54,6 +55,11 @@ struct _virCHDriver
* lockless access thereafter */
virCaps *caps;
+ /* Immutable pointer, Immutable object
+ * Initialized once and reused as needed
+ */
+ virBitmap *chCaps;
+
/* Immutable pointer, Immutable object */
virDomainXMLOption *xmlopt;
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index b62645a8c8..bd271fc0ee 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -20,6 +20,7 @@
#include <config.h>
+#include "ch_capabilities.h"
#include "ch_conf.h"
#include "ch_domain.h"
#include "ch_driver.h"
@@ -899,6 +900,8 @@ static int chStateInitialize(bool privileged,
goto cleanup;
}
+ ch_driver->chCaps = virCHCapsInitCHVersionCaps(ch_driver->version);
+
ch_driver->privileged = privileged;
ret = VIR_DRV_STATE_INIT_COMPLETE;
diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index 1691a4efb6..6f960c3a51 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -106,6 +106,37 @@ virCHMonitorBuildPTYJson(virJSONValue *content, virDomainDef *vmdef)
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)
{
@@ -425,7 +456,8 @@ virCHMonitorBuildDevicesJson(virJSONValue *content,
}
static int
-virCHMonitorBuildVMJson(virDomainDef *vmdef,
+virCHMonitorBuildVMJson(virCHDriver *driver,
+ virDomainDef *vmdef,
char **jsonstr,
size_t *nnicindexes,
int **nicindexes)
@@ -447,8 +479,13 @@ virCHMonitorBuildVMJson(virDomainDef *vmdef,
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;
@@ -840,7 +877,8 @@ virCHMonitorShutdownVMM(virCHMonitor *mon)
}
int
-virCHMonitorCreateVM(virCHMonitor *mon,
+virCHMonitorCreateVM(virCHDriver *driver,
+ virCHMonitor *mon,
size_t *nnicindexes,
int **nicindexes)
{
@@ -854,7 +892,7 @@ virCHMonitorCreateVM(virCHMonitor *mon,
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;
diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h
index ffc80e8910..bbfa77cdff 100644
--- a/src/ch/ch_monitor.h
+++ b/src/ch/ch_monitor.h
@@ -25,6 +25,7 @@
#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"
@@ -103,7 +104,8 @@ void virCHMonitorClose(virCHMonitor *mon);
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);
diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c
index 6d3a9612bd..f3bb4a7280 100644
--- a/src/ch/ch_process.c
+++ b/src/ch/ch_process.c
@@ -483,7 +483,7 @@ virCHProcessStart(virCHDriver *driver,
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"));
diff --git a/src/ch/meson.build b/src/ch/meson.build
index df246ef9b0..6311b84f3e 100644
--- a/src/ch/meson.build
+++ b/src/ch/meson.build
@@ -1,4 +1,6 @@
ch_driver_sources = [
+ 'ch_capabilities.h',
+ 'ch_capabilities.c',
'ch_conf.c',
'ch_conf.h',
'ch_domain.c',
--
2.41.0