Signed-off-by: Vineeth Pillai <viremana(a)linux.microsoft.com>
Signed-off-by: Praveen Paladugu <prapal(a)linux.microsoft.com>
---
src/ch/ch_conf.h | 5 +++
src/ch/ch_domain.c | 26 +++++++++++++-
src/ch/ch_domain.h | 4 +--
src/ch/ch_driver.c | 4 ++-
src/ch/ch_monitor.c | 85 +++++++++++++++++++++++++++++++++++++++++----
src/ch/ch_monitor.h | 14 +++++++-
src/ch/ch_process.c | 6 +++-
src/ch/meson.build | 1 +
8 files changed, 132 insertions(+), 13 deletions(-)
diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
index 37c36d9a09..49f286f97a 100644
--- a/src/ch/ch_conf.h
+++ b/src/ch/ch_conf.h
@@ -44,6 +44,11 @@ struct _virCHDriver
{
virMutex lock;
+ bool privileged;
+
+ /* Embedded Mode: Not yet supported */
+ char *embeddedRoot;
+
/* Require lock to get a reference on the object,
* lockless access thereafter */
virCaps *caps;
diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index c0b0b1005a..e1030800aa 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -21,10 +21,12 @@
#include <config.h>
#include "ch_domain.h"
+#include "domain_driver.h"
#include "viralloc.h"
#include "virchrdev.h"
#include "virlog.h"
#include "virtime.h"
+#include "virsystemd.h"
#define VIR_FROM_THIS VIR_FROM_CH
@@ -136,7 +138,7 @@ virCHDomainObjEndJob(virDomainObj *obj)
}
static void *
-virCHDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
+virCHDomainObjPrivateAlloc(void *opaque)
{
virCHDomainObjPrivate *priv;
@@ -152,6 +154,7 @@ virCHDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
g_free(priv);
return NULL;
}
+ priv->driver = opaque;
return priv;
}
@@ -363,3 +366,24 @@ virCHDomainHasVcpuPids(virDomainObj *vm)
return false;
}
+
+char *virCHDomainGetMachineName(virDomainObj *vm)
+{
+ virCHDomainObjPrivate *priv = CH_DOMAIN_PRIVATE(vm);
+ virCHDriver *driver = priv->driver;
+ char *ret = NULL;
+
+ if (vm->pid > 0) {
+ ret = virSystemdGetMachineNameByPID(vm->pid);
+ if (!ret)
+ virResetLastError();
+ }
+
+ if (!ret)
+ ret = virDomainDriverGenerateMachineName("ch",
+ driver->embeddedRoot,
+ vm->def->id, vm->def->name,
+ driver->privileged);
+
+ return ret;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index e35777a9ec..3ac3421015 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -54,9 +54,7 @@ struct _virCHDomainObjPrivate {
struct virCHDomainJobObj job;
virChrdevs *chrdevs;
-
virCgroup *cgroup;
-
virCHDriver *driver;
virCHMonitor *monitor;
char *machineName;
@@ -94,3 +92,5 @@ virCHDomainObjEndJob(virDomainObj *obj);
int virCHDomainRefreshVcpuInfo(virDomainObj *vm);
pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid);
bool virCHDomainHasVcpuPids(virDomainObj *vm);
+
+char *virCHDomainGetMachineName(virDomainObj *vm);
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 62ca6c1994..ca854da123 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -944,7 +944,9 @@ static int chStateInitialize(bool privileged,
goto cleanup;
}
- ret = VIR_DRV_STATE_INIT_COMPLETE;
+ ch_driver->privileged = privileged;
+
+ return VIR_DRV_STATE_INIT_COMPLETE;
cleanup:
if (ret != VIR_DRV_STATE_INIT_COMPLETE)
diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index 691d1ce64b..c0ae031200 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -228,7 +228,8 @@ virCHMonitorBuildDisksJson(virJSONValue *content, virDomainDef
*vmdef)
}
static int
-virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef)
+virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef,
+ size_t *nnicindexes, int **nicindexes)
{
virDomainNetType netType = virDomainNetGetActualType(netdef);
char macaddr[VIR_MAC_STRING_BUFLEN];
@@ -263,6 +264,18 @@ virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef
*netdef)
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("ethernet type supports a single guest ip"));
}
+
+ /* network and bridge use a tap device, and direct uses a
+ * macvtap device
+ */
+ if (nicindexes && nnicindexes && netdef->ifname) {
+ int nicindex = 0;
+ if (virNetDevGetIndex(netdef->ifname, &nicindex) < 0)
+ return -1;
+ else
+ VIR_APPEND_ELEMENT(*nicindexes, *nnicindexes, nicindex);
+ }
+
break;
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
if ((virDomainChrType)netdef->data.vhostuser->type !=
VIR_DOMAIN_CHR_TYPE_UNIX) {
@@ -331,7 +344,8 @@ virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef)
}
static int
-virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef *vmdef)
+virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef *vmdef,
+ size_t *nnicindexes, int **nicindexes)
{
g_autoptr(virJSONValue) nets = NULL;
size_t i;
@@ -340,7 +354,8 @@ virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef *vmdef)
nets = virJSONValueNewArray();
for (i = 0; i < vmdef->nnets; i++) {
- if (virCHMonitorBuildNetJson(nets, vmdef->nets[i]) < 0)
+ if (virCHMonitorBuildNetJson(nets, vmdef->nets[i],
+ nnicindexes, nicindexes) < 0)
return -1;
}
if (virJSONValueObjectAppend(content, "net", &nets) < 0)
@@ -351,7 +366,57 @@ virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef
*vmdef)
}
static int
-virCHMonitorBuildVMJson(virDomainDef *vmdef, char **jsonstr)
+virCHMonitorBuildDeviceJson(virJSONValue *devices, virDomainHostdevDef *hostdevdef)
+{
+ g_autoptr(virJSONValue) device = NULL;
+
+
+ if (hostdevdef->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdevdef->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ g_autofree char *name = NULL;
+ g_autofree char *path = NULL;
+ virDomainHostdevSubsysPCI *pcisrc = &hostdevdef->source.subsys.u.pci;
+ device = virJSONValueNewObject();
+ name = g_strdup_printf(VIR_PCI_DEVICE_ADDRESS_FMT, pcisrc->addr.domain,
+ pcisrc->addr.bus, pcisrc->addr.slot,
+ pcisrc->addr.function);
+ path = g_strdup_printf("/sys/bus/pci/devices/%s/", name);
+ if (!virFileExists(path)) {
+ virReportError(VIR_ERR_DEVICE_MISSING,
+ _("host pci device %s not found"), path);
+ return -1;
+ }
+ if (virJSONValueObjectAppendString(device, "path", path) < 0)
+ return -1;
+ if (virJSONValueArrayAppend(devices, &device) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+virCHMonitorBuildDevicesJson(virJSONValue *content, virDomainDef *vmdef)
+{
+ g_autoptr(virJSONValue) devices = NULL;
+ size_t i;
+
+ if (vmdef->nhostdevs > 0) {
+ devices = virJSONValueNewArray();
+ for (i = 0; i < vmdef->nhostdevs; i++) {
+ if (virCHMonitorBuildDeviceJson(devices, vmdef->hostdevs[i]) < 0)
+ return -1;
+ }
+ if (virJSONValueObjectAppend(content, "devices", &devices) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+virCHMonitorBuildVMJson(virDomainDef *vmdef, char **jsonstr,
+ size_t *nnicindexes, int **nicindexes)
{
g_autoptr(virJSONValue) content = virJSONValueNewObject();
@@ -376,7 +441,12 @@ virCHMonitorBuildVMJson(virDomainDef *vmdef, char **jsonstr)
if (virCHMonitorBuildDisksJson(content, vmdef) < 0)
return -1;
- if (virCHMonitorBuildNetsJson(content, vmdef) < 0)
+
+ if (virCHMonitorBuildNetsJson(content, vmdef,
+ nnicindexes, nicindexes) < 0)
+ return -1;
+
+ if (virCHMonitorBuildDevicesJson(content, vmdef) < 0)
return -1;
if (!(*jsonstr = virJSONValueToString(content, false)))
@@ -673,7 +743,7 @@ virCHMonitorShutdownVMM(virCHMonitor *mon)
}
int
-virCHMonitorCreateVM(virCHMonitor *mon)
+virCHMonitorCreateVM(virCHMonitor *mon, size_t *nnicindexes, int **nicindexes)
{
g_autofree char *url = NULL;
int responseCode = 0;
@@ -685,7 +755,8 @@ 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) != 0)
+ if (virCHMonitorBuildVMJson(mon->vm->def, &payload,
+ nnicindexes, nicindexes) != 0)
return -1;
virObjectLock(mon);
diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h
index 0f684ca583..8ca9e17a9a 100644
--- a/src/ch/ch_monitor.h
+++ b/src/ch/ch_monitor.h
@@ -55,10 +55,22 @@ virCHMonitor *virCHMonitorNew(virDomainObj *vm, const char
*socketdir);
void virCHMonitorClose(virCHMonitor *mon);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCHMonitor, virCHMonitorClose);
-int virCHMonitorCreateVM(virCHMonitor *mon);
+
+int virCHMonitorCreateVM(virCHMonitor *mon,
+ size_t *nnicindexes, int **nicindexes);
int virCHMonitorBootVM(virCHMonitor *mon);
int virCHMonitorShutdownVM(virCHMonitor *mon);
int virCHMonitorRebootVM(virCHMonitor *mon);
int virCHMonitorSuspendVM(virCHMonitor *mon);
int virCHMonitorResumeVM(virCHMonitor *mon);
int virCHMonitorGetInfo(virCHMonitor *mon, virJSONValue **info);
+
+typedef struct _virCHMonitorCPUInfo virCHMonitorCPUInfo;
+struct _virCHMonitorCPUInfo {
+ pid_t tid;
+ bool online;
+};
+void virCHMonitorCPUInfoFree(virCHMonitorCPUInfo *cpus);
+int virCHMonitorGetCPUInfo(virCHMonitor *mon,
+ virCHMonitorCPUInfo **vcpus,
+ size_t maxvcpus);
diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c
index 1a01ca9384..3b7f6fcddf 100644
--- a/src/ch/ch_process.c
+++ b/src/ch/ch_process.c
@@ -149,6 +149,8 @@ int virCHProcessStart(virCHDriver *driver,
{
int ret = -1;
virCHDomainObjPrivate *priv = vm->privateData;
+ g_autofree int *nicindexes = NULL;
+ size_t nnicindexes = 0;
if (!priv->monitor) {
/* And we can get the first monitor connection now too */
@@ -158,7 +160,8 @@ int virCHProcessStart(virCHDriver *driver,
goto cleanup;
}
- if (virCHMonitorCreateVM(priv->monitor) < 0) {
+ if (virCHMonitorCreateVM(priv->monitor,
+ &nnicindexes, &nicindexes) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to create guest VM"));
goto cleanup;
@@ -171,6 +174,7 @@ int virCHProcessStart(virCHDriver *driver,
goto cleanup;
}
+ priv->machineName = virCHDomainGetMachineName(vm);
vm->pid = priv->monitor->pid;
vm->def->id = vm->pid;
diff --git a/src/ch/meson.build b/src/ch/meson.build
index 5c6cab2a9f..2b2bdda26c 100644
--- a/src/ch/meson.build
+++ b/src/ch/meson.build
@@ -29,6 +29,7 @@ if conf.has('WITH_CH')
],
include_directories: [
conf_inc_dir,
+ hypervisor_inc_dir,
],
link_with: [
virt_util_lib,
--
2.27.0