[GSoC PATCH 4/9] Jailhouse driver: Implementation of DomainCreate* callbacks
by Prakhar Bansal
From: Prakhar Bansal <itsprakhar(a)gmail.com>
Implemented Jailhouse hypervisor APIs for cell
load/start/shutdown/destroy.
---
src/jailhouse/jailhouse_api.c | 100 ++++++++++++--
src/jailhouse/jailhouse_api.h | 29 +++++
src/jailhouse/jailhouse_driver.c | 217 +++++++++++++++++++++++++++++--
src/jailhouse/jailhouse_driver.h | 8 ++
4 files changed, 335 insertions(+), 19 deletions(-)
diff --git a/src/jailhouse/jailhouse_api.c b/src/jailhouse/jailhouse_api.c
index cda00b50e7..783903e939 100644
--- a/src/jailhouse/jailhouse_api.c
+++ b/src/jailhouse/jailhouse_api.c
@@ -43,11 +43,14 @@
#define JAILHOUSE_CELLS "/sys/devices/jailhouse/cells"
#define MAX_JAILHOUSE_SYS_CONFIG_FILE_SIZE 1024*1024
#define MAX_JAILHOUSE_CELL_CONFIG_FILE_SIZE 1024
+#define MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE 64*1024*1024
#define JAILHOUSE_ENABLE _IOW(0, 0, void *)
#define JAILHOUSE_DISABLE _IO(0, 1)
#define JAILHOUSE_CELL_CREATE _IOW(0, 2, virJailhouseCellCreate)
+#define JAILHOUSE_CELL_LOAD _IOW(0, 3, virJailhouseCellLoad)
+#define JAILHOUSE_CELL_START _IOW(0, 4, virJailhouseCellId)
#define JAILHOUSE_CELL_DESTROY _IOW(0, 5, virJailhouseCellId)
#define VIR_FROM_THIS VIR_FROM_JAILHOUSE
@@ -68,8 +71,6 @@ int cell_match(const struct dirent *dirent);
int createCell(const char *conf_file);
-int destroyCell(virJailhouseCellId cell_id);
-
int getCellInfo(const unsigned int id,
virJailhouseCellInfoPtr * cell_info);
@@ -254,7 +255,7 @@ readSysfsCellString(const unsigned int id, const char *entry)
}
int
-getCellInfo(const unsigned int id, virJailhouseCellInfoPtr * cell_info_ptr)
+getCellInfo(const unsigned int id, virJailhouseCellInfoPtr *cell_info_ptr)
{
char *tmp;
@@ -345,28 +346,105 @@ getJailhouseCellsInfo(void)
}
int
-destroyCell(virJailhouseCellId cell_id)
+loadImagesInCell(virJailhouseCellId cell_id, char **images, int num_images)
+{
+ virJailhousePreloadImagePtr image;
+ virJailhouseCellLoadPtr cell_load;
+ g_autofree char *buffer = NULL;
+ unsigned int n;
+ int len = -1, err = -1;
+ VIR_AUTOCLOSE fd = -1;
+
+
+ if (VIR_ALLOC(cell_load) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s",
+ _("Insufficient memory for cell load"));
+ return -1;
+ }
+
+
+ if (VIR_ALLOC_N(cell_load->image, num_images) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s",
+ _("Insufficient memory for cell load images"));
+ return -1;
+ }
+
+ cell_load->id = cell_id;
+ cell_load->num_preload_images = num_images;
+
+ for (n = 0, image = cell_load->image; n < num_images; n++, image++) {
+ len = virFileReadAll(images[n], MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE, &buffer);
+ if (len < 0 || !buffer) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Failed to read the image file %s"),
+ images[n]);
+ return -1;
+ }
+
+ image->source_address = (unsigned long)buffer;
+ image->size = len;
+
+ // TODO(Prakhar): Add support for target address.
+ image->target_address = 0;
+ }
+
+ fd = openDev();
+
+ err = ioctl(fd, JAILHOUSE_CELL_LOAD, cell_load);
+ if (err) {
+ virReportSystemError(errno,
+ _("Loading cell images for %d failed"),
+ cell_id.id);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+shutdownCell(virJailhouseCellId cell_id)
+{
+ // Loading 0 images in the cell causes cell to shutdown.
+ return loadImagesInCell(cell_id, NULL, 0);
+}
+
+int
+startCell(virJailhouseCellId cell_id)
{
int err = -1;
VIR_AUTOCLOSE fd = -1;
fd = openDev();
- err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
- if (err)
+ err = ioctl(fd, JAILHOUSE_CELL_START, &cell_id);
+ if (err) {
virReportSystemError(errno,
- _("Destroying cell %d failed"),
+ _("Start cell %d failed"),
cell_id.id);
+ return -1;
+ }
- return err;
+ return 0;
}
int
-destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list G_GNUC_UNUSED)
+destroyCell(virJailhouseCellId cell_id)
{
+ int err = -1;
+ VIR_AUTOCLOSE fd = -1;
+
+ fd = openDev();
- /* Iterate over all cells in cell_info_list and destroy each cell */
- // TODO: Not implemented yet.
+ err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
+ if (err) {
+ virReportSystemError(errno,
+ _("Destroying cell %d failed"),
+ cell_id.id);
+
+ return -1;
+ }
return 0;
}
diff --git a/src/jailhouse/jailhouse_api.h b/src/jailhouse/jailhouse_api.h
index 8362cb3d0f..ba39a4c8b7 100644
--- a/src/jailhouse/jailhouse_api.h
+++ b/src/jailhouse/jailhouse_api.h
@@ -48,6 +48,27 @@ struct _virJailhouseCellCreate {
__u32 padding;
};
+typedef struct _virJailhousePreloadImage virJailhousePreloadImage;
+typedef virJailhousePreloadImage *virJailhousePreloadImagePtr;
+
+struct _virJailhousePreloadImage {
+ __u64 source_address;
+ __u64 size;
+ __u64 target_address;
+ __u64 padding;
+};
+
+typedef struct _virJailhouseCellLoad virJailhouseCellLoad;
+typedef virJailhouseCellLoad *virJailhouseCellLoadPtr;
+
+struct _virJailhouseCellLoad {
+ struct _virJailhouseCellId id;
+ __u32 num_preload_images;
+ __u32 padding;
+ struct _virJailhousePreloadImage image[];
+};
+
+
// Enables the Jailhouse hypervisor by reading the hypervisor system
// configuration from the given file and calls the ioctl API to
// enable the hypervisor.
@@ -62,6 +83,14 @@ int jailhouseDisable(void);
// provided in the dir_name.
int createJailhouseCells(const char *dir_path);
+int loadImagesInCell(virJailhouseCellId cell_id, char **images, int num_images);
+
+int startCell(virJailhouseCellId cell_id);
+
+int shutdownCell(virJailhouseCellId cell_id);
+
+int destroyCell(virJailhouseCellId cell_id);
+
// Destroys Jailhouse cells using the cell IDs provided in
// the cell_info_list.
int destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list);
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 75bf41fc11..5b7bdc92d8 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -25,7 +25,6 @@
#include "configmake.h"
#include "datatypes.h"
#include "domain_conf.h"
-#include "jailhouse_driver.h"
#include "virtypedparam.h"
#include "virerror.h"
#include "virstring.h"
@@ -36,6 +35,9 @@
#include "vircommand.h"
#include "virpidfile.h"
#include "access/viraccessapicheck.h"
+#include "virdomainobjlist.h"
+
+#include "jailhouse_driver.h"
#define VIR_FROM_THIS VIR_FROM_JAILHOUSE
@@ -62,7 +64,6 @@ virJailhouseDriverConfigNew(void)
{
virJailhouseDriverConfigPtr cfg;
- // TODO: Check if the following has to be uncommented.
if (virJailhouseConfigInitialize() < 0)
return NULL;
@@ -135,6 +136,7 @@ jailhouseFreeDriver(virJailhouseDriverPtr driver)
return;
virMutexDestroy(&driver->lock);
+ virObjectUnref(driver->domains);
virObjectUnref(driver->config);
VIR_FREE(driver);
}
@@ -207,6 +209,9 @@ jailhouseStateInitialize(bool privileged G_GNUC_UNUSED,
return VIR_DRV_STATE_INIT_ERROR;
}
+ if (!(jailhouse_driver->domains = virDomainObjListNew()))
+ goto error;
+
if (!(cfg = virJailhouseDriverConfigNew()))
goto error;
@@ -259,10 +264,11 @@ jailhouseConnectGetHostname(virConnectPtr conn)
}
static int
-jailhouseNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
+jailhouseNodeGetInfo(virConnectPtr conn,
+ virNodeInfoPtr nodeinfo)
{
UNUSED(conn);
- UNUSED(info);
+ UNUSED(nodeinfo);
return -1;
}
@@ -300,11 +306,205 @@ jailhouseDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
return NULL;
}
+static virDomainObjPtr
+virJailhouseDomObjFromDomain(virDomainPtr domain)
+{
+ virDomainObjPtr cell;
+ virJailhouseDriverPtr driver = domain->conn->privateData;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ cell = virDomainObjListFindByUUID(driver->domains, domain->uuid);
+ if (!cell) {
+ virUUIDFormat(domain->uuid, uuidstr);
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s' (%s)"),
+ uuidstr, domain->name);
+ return NULL;
+ }
+
+ return cell;
+}
+
+
+
+static virJailhouseCellInfoPtr
+virJailhouseFindCellByName(virJailhouseDriverPtr driver,
+ char* name)
+{
+ virJailhouseCellInfoPtr *cell = driver->cell_info_list;
+
+ while (*cell) {
+ if (STRCASEEQ((*cell)->id.name, name))
+ return *cell;
+ cell++;
+ }
+
+ return NULL;
+}
+
+static int
+jailhouseDomainCreateWithFlags(virDomainPtr domain,
+ unsigned int flags)
+{
+ virJailhouseDriverPtr driver = domain->conn->privateData;
+ virDomainObjPtr cell;
+ virJailhouseCellInfoPtr cell_info;
+ int ret = -1;
+
+ virCheckFlags(VIR_DOMAIN_NONE, -1);
+
+ if (!domain->name) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error while reading the domain name"));
+ goto cleanup;
+ }
+
+ if (!domain->id) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error while reading the domain ID"));
+ goto cleanup;
+ }
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainCreateWithFlagsEnsureACL(domain->conn, cell->def) < 0)
+ goto cleanup;
+
+ if (!(cell_info = virJailhouseFindCellByName(driver, cell->def->name))) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name %s and ID %d)"),
+ cell->def->name, cell->def->id);
+ virDomainObjListRemove(driver->domains, cell);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
+
+}
+
static int
jailhouseDomainCreate(virDomainPtr domain)
{
- UNUSED(domain);
- return -1;
+ return jailhouseDomainCreateWithFlags(domain, 0);
+}
+
+static virDomainPtr
+jailhouseDomainCreateXML(virConnectPtr conn,
+ const char *xml,
+ unsigned int flags)
+{
+ virJailhouseDriverPtr driver = conn->privateData;
+ virJailhouseCellInfoPtr cell_info;
+ virDomainPtr dom = NULL;
+ virDomainDefPtr def = NULL;
+ virDomainObjPtr cell = NULL;
+ virDomainDiskDefPtr disk = NULL;
+ virJailhouseCellId cell_id;
+ char **images = NULL;
+ int num_images = 0, i = 0;
+ unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
+
+ if (flags & VIR_DOMAIN_START_VALIDATE)
+ parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
+
+ if ((def = virDomainDefParseString(xml, NULL,
+ NULL, parse_flags)) == NULL)
+ goto cleanup;
+
+ if ((cell = virDomainObjListFindByUUID(driver->domains, def->uuid)))
+ goto cleanup;
+
+ if (virDomainCreateXMLEnsureACL(conn, def) < 0)
+ goto cleanup;
+
+ if (!(cell_info = virJailhouseFindCellByName(driver, def->name))) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("cell info for %s not found"),
+ def->name);
+ goto cleanup;
+ }
+
+ // Assign cell Id to the domain.
+ def->id = cell_info->id.id;
+
+ if (!(cell = virDomainObjListAdd(driver->domains, def,
+ NULL,
+ VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+ VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL)))
+ goto cleanup;
+
+ def = NULL;
+
+ if (cell->def->ndisks < 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Domain XML doesn't contain any disk images"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(images, cell->def->ndisks) < 0)
+ goto cleanup;
+
+ for (i = 0; i < cell->def->ndisks; ++i) {
+ images[i] = NULL;
+
+ if (cell->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
+ virDomainDiskGetType(cell->def->disks[i]) == VIR_STORAGE_TYPE_FILE) {
+ disk = cell->def->disks[i];
+ const char *src = virDomainDiskGetSource(disk);
+ if (!src) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("First file-based harddisk has no source"));
+ goto cleanup;
+ }
+
+ images[i] = (char *)src;
+ num_images++;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("A Jailhouse doamin(cell) can ONLY have FILE type disks"));
+ goto cleanup;
+ }
+ }
+
+ // Initialize the cell_id.
+ cell_id.id = cell->def->id;
+ cell_id.padding = 0;
+ if (virStrncpy(cell_id.name, cell->def->name, JAILHOUSE_CELL_ID_NAMELEN, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Cell name %s length exceeded the limit"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ if (loadImagesInCell(cell_id, images, num_images) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to load images in the Cell %s"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Starting the domain...");
+
+ if (startCell(cell_id) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to start the Cell %s"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ virDomainObjSetState(cell, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED);
+
+ dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
+
+ cleanup:
+ virDomainDefFree(def);
+ virDomainObjEndAPI(&cell);
+ return dom;
}
static int
@@ -314,7 +514,6 @@ jailhouseDomainShutdown(virDomainPtr domain)
return -1;
}
-
static int
jailhouseDomainDestroy(virDomainPtr domain)
{
@@ -356,7 +555,9 @@ static virHypervisorDriver jailhouseHypervisorDriver = {
.connectListAllDomains = jailhouseConnectListAllDomains, /* 6.3.0 */
.connectGetType = jailhouseConnectGetType, /* 6.3.0 */
.connectGetHostname = jailhouseConnectGetHostname, /* 6.3.0 */
- .domainCreate = jailhouseDomainCreate, /* 6.3.0 */
+ .domainCreate = jailhouseDomainCreate, /*6.3.0 */
+ .domainCreateWithFlags = jailhouseDomainCreateWithFlags, /* 6.3.0 */
+ .domainCreateXML = jailhouseDomainCreateXML, /* 6.3.0 */
.domainShutdown = jailhouseDomainShutdown, /* 6.3.0 */
.domainDestroy = jailhouseDomainDestroy, /* 6.3.0 */
.domainGetInfo = jailhouseDomainGetInfo, /* 6.3.0 */
diff --git a/src/jailhouse/jailhouse_driver.h b/src/jailhouse/jailhouse_driver.h
index 8a0e111676..8fc99fe7d2 100644
--- a/src/jailhouse/jailhouse_driver.h
+++ b/src/jailhouse/jailhouse_driver.h
@@ -22,7 +22,9 @@
#include <linux/types.h>
+#include "domain_event.h"
#include "jailhouse_api.h"
+#include "virdomainobjlist.h"
int jailhouseRegister(void);
@@ -64,6 +66,12 @@ struct _virJailhouseDriver {
// All the cells created during connect open on the hypervisor.
virJailhouseCellInfoPtr *cell_info_list;
+
+ // XML options for domain XMLs.
+ virDomainXMLOptionPtr xmlopt;
+ virDomainObjListPtr domains;
+
+ virObjectEventStatePtr domainEventState;
};
struct _jailhouseCell {
--
2.17.1
4 years, 2 months
[GSoC PATCH 3/9] Jailhouse driver: Implementation of ConnectGetType
by Prakhar Bansal
From: Prakhar Bansal <itsprakhar(a)gmail.com>
---
src/jailhouse/jailhouse_driver.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index ac9da4c85d..75bf41fc11 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -32,8 +32,10 @@
#include "viralloc.h"
#include "virfile.h"
#include "virlog.h"
+#include "virutil.h"
#include "vircommand.h"
#include "virpidfile.h"
+#include "access/viraccessapicheck.h"
#define VIR_FROM_THIS VIR_FROM_JAILHOUSE
@@ -241,16 +243,19 @@ jailhouseStateInitialize(bool privileged G_GNUC_UNUSED,
static const char *
jailhouseConnectGetType(virConnectPtr conn)
{
- UNUSED(conn);
- return NULL;
+ if (virConnectGetTypeEnsureACL(conn) < 0)
+ return NULL;
+ return "JAILHOUSE";
}
static char *
jailhouseConnectGetHostname(virConnectPtr conn)
{
- UNUSED(conn);
- return NULL;
+ if (virConnectGetHostnameEnsureACL(conn) < 0)
+ return NULL;
+
+ return virGetHostname();
}
static int
@@ -263,7 +268,7 @@ jailhouseNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
static int
jailhouseConnectListAllDomains(virConnectPtr conn,
- virDomainPtr ** domain, unsigned int flags)
+ virDomainPtr **domain, unsigned int flags)
{
UNUSED(conn);
UNUSED(domain);
@@ -300,7 +305,6 @@ jailhouseDomainCreate(virDomainPtr domain)
{
UNUSED(domain);
return -1;
-
}
static int
@@ -350,18 +354,18 @@ static virHypervisorDriver jailhouseHypervisorDriver = {
.connectOpen = jailhouseConnectOpen, /* 6.3.0 */
.connectClose = jailhouseConnectClose, /* 6.3.0 */
.connectListAllDomains = jailhouseConnectListAllDomains, /* 6.3.0 */
- .domainLookupByID = jailhouseDomainLookupByID, /* 6.3.0 */
- .domainLookupByUUID = jailhouseDomainLookupByUUID, /* 6.3.0 */
- .domainLookupByName = jailhouseDomainLookupByName, /* 6.3.0 */
- .domainGetXMLDesc = jailhouseDomainGetXMLDesc, /* 6.3.0 */
- .domainCreate = jailhouseDomainCreate, /* 6.3.0 */
.connectGetType = jailhouseConnectGetType, /* 6.3.0 */
.connectGetHostname = jailhouseConnectGetHostname, /* 6.3.0 */
- .nodeGetInfo = jailhouseNodeGetInfo, /* 6.3.0 */
+ .domainCreate = jailhouseDomainCreate, /* 6.3.0 */
.domainShutdown = jailhouseDomainShutdown, /* 6.3.0 */
.domainDestroy = jailhouseDomainDestroy, /* 6.3.0 */
.domainGetInfo = jailhouseDomainGetInfo, /* 6.3.0 */
.domainGetState = jailhouseDomainGetState, /* 6.3.0 */
+ .domainLookupByID = jailhouseDomainLookupByID, /* 6.3.0 */
+ .domainLookupByUUID = jailhouseDomainLookupByUUID, /* 6.3.0 */
+ .domainLookupByName = jailhouseDomainLookupByName, /* 6.3.0 */
+ .domainGetXMLDesc = jailhouseDomainGetXMLDesc, /* 6.3.0 */
+ .nodeGetInfo = jailhouseNodeGetInfo, /* 6.3.0 */
};
--
2.17.1
4 years, 2 months
[GSoC PATCH 9/9] Jailhouse driver: Add events to events queue in DomainCreate/Shutdown/Destroy
by Prakhar Bansal
---
src/jailhouse/jailhouse_driver.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 45b1f35896..70f0f365cb 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -122,6 +122,7 @@ jailhouseCreateAndLoadCells(virJailhouseDriverPtr driver)
// Create all cells in the hypervisor.
if (createJailhouseCells(driver->config->cell_config_dir) < 0)
return -1;
+
// Get all cells created above.
driver->cell_info_list = getJailhouseCellsInfo();
@@ -137,6 +138,7 @@ jailhouseFreeDriver(virJailhouseDriverPtr driver)
virMutexDestroy(&driver->lock);
virObjectUnref(driver->xmlopt);
virObjectUnref(driver->domains);
+ virObjectUnref(driver->domainEventState);
virObjectUnref(driver->config);
VIR_FREE(driver);
}
@@ -222,6 +224,9 @@ jailhouseStateInitialize(bool privileged G_GNUC_UNUSED,
if (!(jailhouse_driver->domains = virDomainObjListNew()))
goto error;
+ if (!(jailhouse_driver->domainEventState = virObjectEventStateNew()))
+ goto error;
+
if (!(cfg = virJailhouseDriverConfigNew()))
goto error;
@@ -476,6 +481,7 @@ jailhouseDomainCreateXML(virConnectPtr conn,
virDomainDefPtr def = NULL;
virDomainObjPtr cell = NULL;
virJailhouseCellId cell_id;
+ virObjectEventPtr event = NULL;
char **images = NULL;
int num_images = 0, i = 0;
unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
@@ -573,12 +579,16 @@ jailhouseDomainCreateXML(virConnectPtr conn,
dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
+ event = virDomainEventLifecycleNewFromObj(cell,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_BOOTED);
cleanup:
if (!dom && removeInactive && !cell->persistent)
virDomainObjListRemove(driver->domains, cell);
virDomainDefFree(def);
virDomainObjEndAPI(&cell);
+ virObjectEventStateQueue(driver->domainEventState, event);
return dom;
}
@@ -589,6 +599,7 @@ jailhouseDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
virJailhouseCellInfoPtr cell_info;
virDomainObjPtr cell;
virJailhouseCellId cell_id;
+ virObjectEventPtr event = NULL;
int ret = -1;
virCheckFlags(0, -1);
@@ -627,8 +638,12 @@ jailhouseDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
ret = 0;
+ event = virDomainEventLifecycleNewFromObj(cell,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
cleanup:
virDomainObjEndAPI(&cell);
+ virObjectEventStateQueue(driver->domainEventState, event);
return ret;
}
@@ -644,6 +659,7 @@ jailhouseDomainDestroyFlags(virDomainPtr domain, unsigned int flags)
virJailhouseDriverPtr driver = domain->conn->privateData;
virJailhouseCellInfoPtr cell_info;
virDomainObjPtr cell;
+ virObjectEventPtr event = NULL;
int ret = -1;
virCheckFlags(0, -1);
@@ -674,8 +690,12 @@ jailhouseDomainDestroyFlags(virDomainPtr domain, unsigned int flags)
ret = 0;
+ event = virDomainEventLifecycleNewFromObj(cell,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
cleanup:
virDomainObjEndAPI(&cell);
+ virObjectEventStateQueue(driver->domainEventState, event);
return ret;
}
--
2.17.1
4 years, 2 months
[GSoC PATCH 8/9] Jailhouse driver: Fixes for creation of cells, fetching cell info, disabling jailhouse hypervisor
by Prakhar Bansal
- Added xmlopt to the Jailhouse driver
- Added ACL check in ConnectOpen
---
src/jailhouse/jailhouse_api.c | 48 +++++++++++++-------------
src/jailhouse/jailhouse_driver.c | 58 ++++++++++++++++++++------------
2 files changed, 61 insertions(+), 45 deletions(-)
diff --git a/src/jailhouse/jailhouse_api.c b/src/jailhouse/jailhouse_api.c
index 510e2f5f66..bb82b5a31e 100644
--- a/src/jailhouse/jailhouse_api.c
+++ b/src/jailhouse/jailhouse_api.c
@@ -69,15 +69,9 @@ char *readSysfsCellString(const unsigned int id, const char *entry);
int cell_match(const struct dirent *dirent);
-int createCell(const char *conf_file);
-
-int loadImagesInCell(virJailhouseCellId cell_id, char *images, int num_images);
-
-int shutdownCell(virJailhouseCellId cell_id);
+int cell_match_info(const struct dirent *dirent);
-int startCell(virJailhouseCellId cell_id);
-
-int destroyCell(virJailhouseCellId cell_id);
+int createCell(const char *conf_file);
int getCellInfo(const unsigned int id,
virJailhouseCellInfoPtr * cell_info);
@@ -121,25 +115,31 @@ jailhouseDisable(void)
fd = openDev();
err = ioctl(fd, JAILHOUSE_DISABLE);
- if (err)
+ if (err) {
virReportSystemError(errno,
"%s",
_("Failed to disable jailhouse: %s"));
+ return -1;
+ }
VIR_DEBUG("Jailhouse hypervisor is disabled");
- return err;
+ return 0;
}
int
cell_match(const struct dirent *dirent)
{
char *ext = strrchr(dirent->d_name, '.');
-
return dirent->d_name[0] != '.'
- && (STREQ(ext, JAILHOUSE_CELL_FILE_EXTENSION) == 0);
+ && STREQ(ext, JAILHOUSE_CELL_FILE_EXTENSION);
}
+int
+cell_match_info(const struct dirent *dirent)
+{
+ return dirent->d_name[0] != '.';
+}
int
createJailhouseCells(const char *dir_path)
{
@@ -150,7 +150,6 @@ createJailhouseCells(const char *dir_path)
if (strlen(dir_path) == 0)
return ret;
-
num_entries = scandir(dir_path, &namelist, cell_match, alphasort);
if (num_entries == -1) {
if (errno == ENOENT) {
@@ -170,7 +169,8 @@ createJailhouseCells(const char *dir_path)
for (i = 0; i < num_entries; i++) {
g_autofree char *file_path = g_strdup_printf("%s/%s", dir_path, namelist[i]->d_name);
- if (createCell(file_path) != 0) {
+
+ if (createCell(file_path) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Cell creation failed with conf found in %s."),
namelist[i]->d_name);
@@ -208,13 +208,13 @@ createCell(const char *conf_file)
VIR_AUTOCLOSE fd = -1;
if (strlen(conf_file) == 0)
- return err;
+ return -1;
len = virFileReadAll(conf_file, MAX_JAILHOUSE_CELL_CONFIG_FILE_SIZE, &buffer);
if (len < 0 || !buffer) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("Failed to read the system configuration file"));
- return err;
+ return -1;
}
cell_create.config_address = (unsigned long) buffer;
@@ -223,12 +223,14 @@ createCell(const char *conf_file)
fd = openDev();
err = ioctl(fd, JAILHOUSE_CELL_CREATE, &cell_create);
- if (err)
+ if (err) {
virReportSystemError(errno,
"%s",
_("Cell creation failed: %s"));
+ return -1;
+ }
- return err;
+ return 0;
}
void
@@ -243,11 +245,11 @@ cellInfoFree(virJailhouseCellInfoPtr cell_info)
char *
readSysfsCellString(const unsigned int id, const char *entry)
{
- g_autofree char *buffer = NULL;
+ char *buffer = NULL;
g_autofree char *file_path = NULL;
int len = -1;
- file_path = g_strdup_printf(JAILHOUSE_CELLS "%u/%s", id, entry);
+ file_path = g_strdup_printf(JAILHOUSE_CELLS "/%u/%s", id, entry);
len = virFileReadAll(file_path, 1024, &buffer);
if (len < 0 || !buffer) {
@@ -277,13 +279,12 @@ getCellInfo(const unsigned int id, virJailhouseCellInfoPtr *cell_info_ptr)
/* get cell name */
tmp = readSysfsCellString(id, "name");
- if (virStrncpy(cell_info->id.name, tmp, JAILHOUSE_CELL_ID_NAMELEN, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
+ if (virStrcpy(cell_info->id.name, tmp, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cell ID %s too long to be copied to the cell info"),
tmp);
return -1;
}
-
cell_info->id.name[JAILHOUSE_CELL_ID_NAMELEN] = 0;
VIR_FREE(tmp);
@@ -310,8 +311,7 @@ getJailhouseCellsInfo(void)
int num_entries;
size_t i;
- num_entries =
- scandir(JAILHOUSE_CELLS, &namelist, cell_match, alphasort);
+ num_entries = scandir(JAILHOUSE_CELLS, &namelist, cell_match_info, alphasort);
if (num_entries == -1) {
if (errno == ENOENT) {
virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 46c7759cb8..45b1f35896 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -122,7 +122,6 @@ jailhouseCreateAndLoadCells(virJailhouseDriverPtr driver)
// Create all cells in the hypervisor.
if (createJailhouseCells(driver->config->cell_config_dir) < 0)
return -1;
-
// Get all cells created above.
driver->cell_info_list = getJailhouseCellsInfo();
@@ -136,6 +135,7 @@ jailhouseFreeDriver(virJailhouseDriverPtr driver)
return;
virMutexDestroy(&driver->lock);
+ virObjectUnref(driver->xmlopt);
virObjectUnref(driver->domains);
virObjectUnref(driver->config);
VIR_FREE(driver);
@@ -147,7 +147,6 @@ jailhouseConnectOpen(virConnectPtr conn,
virConfPtr conf G_GNUC_UNUSED, unsigned int flags)
{
uid_t uid = geteuid();
-
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
if (!virConnectValidateURIPath(conn->uri->path, "jailhouse", uid == 0))
@@ -159,8 +158,10 @@ jailhouseConnectOpen(virConnectPtr conn,
return VIR_DRV_OPEN_ERROR;
}
- conn->privateData = jailhouse_driver;
+ if (virConnectOpenEnsureACL(conn) < 0)
+ return VIR_DRV_OPEN_ERROR;
+ conn->privateData = jailhouse_driver;
return VIR_DRV_OPEN_SUCCESS;
}
@@ -169,16 +170,19 @@ jailhouseConnectOpen(virConnectPtr conn,
static int
jailhouseConnectClose(virConnectPtr conn)
{
- conn->privateData = NULL;
+ conn->privateData = NULL;
- return 0;
+ return 0;
}
static int
jailhouseStateCleanup(void)
{
if (!jailhouse_driver)
- return -1;
+ return -1;
+
+ if (jailhouseDisable() < 0)
+ return -1;
if (jailhouse_driver->lockFD != -1)
virPidFileRelease(jailhouse_driver->config->stateDir,
@@ -187,6 +191,9 @@ jailhouseStateCleanup(void)
virMutexDestroy(&jailhouse_driver->lock);
jailhouseFreeDriver(jailhouse_driver);
+
+ jailhouse_driver = NULL;
+
return 0;
}
@@ -199,6 +206,9 @@ jailhouseStateInitialize(bool privileged G_GNUC_UNUSED,
virJailhouseDriverConfigPtr cfg = NULL;
int rc;
+ if (jailhouse_driver)
+ return VIR_DRV_STATE_INIT_COMPLETE;
+
jailhouse_driver = g_new0(virJailhouseDriver, 1);
jailhouse_driver->lockFD = -1;
@@ -220,6 +230,10 @@ jailhouseStateInitialize(bool privileged G_GNUC_UNUSED,
if (jailhouseLoadConf(cfg) < 0)
goto error;
+ if (!(jailhouse_driver->xmlopt = virDomainXMLOptionNew(NULL, NULL,
+ NULL, NULL, NULL)))
+ goto error;
+
if (virFileMakePath(cfg->stateDir) < 0) {
virReportSystemError(errno, _("Failed to create state dir %s"),
cfg->stateDir);
@@ -292,7 +306,7 @@ jailhouseConnectListAllDomains(virConnectPtr conn,
static virDomainPtr
jailhouseDomainLookupByID(virConnectPtr conn, int id)
{
-virJailhouseDriverPtr driver = conn->privateData;
+ virJailhouseDriverPtr driver = conn->privateData;
virDomainObjPtr cell;
virDomainPtr dom = NULL;
@@ -409,7 +423,6 @@ jailhouseDomainCreateWithFlags(virDomainPtr domain,
virJailhouseCellInfoPtr cell_info;
virDomainObjPtr cell;
int ret = -1;
-
virCheckFlags(VIR_DOMAIN_NONE, -1);
if (!domain->name) {
@@ -462,23 +475,23 @@ jailhouseDomainCreateXML(virConnectPtr conn,
virDomainPtr dom = NULL;
virDomainDefPtr def = NULL;
virDomainObjPtr cell = NULL;
- virDomainDiskDefPtr disk = NULL;
virJailhouseCellId cell_id;
char **images = NULL;
int num_images = 0, i = 0;
unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
+ bool removeInactive = false;
if (flags & VIR_DOMAIN_START_VALIDATE)
parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
- if ((def = virDomainDefParseString(xml, NULL,
- NULL, parse_flags)) == NULL)
+ if (!(def = virDomainDefParseString(xml, driver->xmlopt,
+ NULL, parse_flags)))
goto cleanup;
- if ((cell = virDomainObjListFindByUUID(driver->domains, def->uuid)))
+ if (virDomainCreateXMLEnsureACL(conn, def) < 0)
goto cleanup;
- if (virDomainCreateXMLEnsureACL(conn, def) < 0)
+ if ((cell = virDomainObjListFindByUUID(driver->domains, def->uuid)))
goto cleanup;
if (!(cell_info = virJailhouseFindCellByName(driver, def->name))) {
@@ -492,13 +505,13 @@ jailhouseDomainCreateXML(virConnectPtr conn,
def->id = cell_info->id.id;
if (!(cell = virDomainObjListAdd(driver->domains, def,
- NULL,
- VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
- VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL)))
+ driver->xmlopt, 0, NULL)))
goto cleanup;
def = NULL;
+ removeInactive = true;
+
if (cell->def->ndisks < 1) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Domain XML doesn't contain any disk images"));
@@ -513,7 +526,7 @@ jailhouseDomainCreateXML(virConnectPtr conn,
if (cell->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
virDomainDiskGetType(cell->def->disks[i]) == VIR_STORAGE_TYPE_FILE) {
- disk = cell->def->disks[i];
+ virDomainDiskDefPtr disk = cell->def->disks[i];
const char *src = virDomainDiskGetSource(disk);
if (!src) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -525,7 +538,7 @@ jailhouseDomainCreateXML(virConnectPtr conn,
num_images++;
} else {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("A Jailhouse doamin(cell) can ONLY have FILE type disks"));
+ _("A Jailhouse domain(cell) can ONLY have FILE type disks"));
goto cleanup;
}
}
@@ -533,7 +546,7 @@ jailhouseDomainCreateXML(virConnectPtr conn,
// Initialize the cell_id.
cell_id.id = cell->def->id;
cell_id.padding = 0;
- if (virStrncpy(cell_id.name, cell->def->name, JAILHOUSE_CELL_ID_NAMELEN, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
+ if (virStrcpy(cell_id.name, cell->def->name, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cell name %s length exceeded the limit"),
cell->def->name);
@@ -561,6 +574,9 @@ jailhouseDomainCreateXML(virConnectPtr conn,
dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
cleanup:
+ if (!dom && removeInactive && !cell->persistent)
+ virDomainObjListRemove(driver->domains, cell);
+
virDomainDefFree(def);
virDomainObjEndAPI(&cell);
return dom;
@@ -671,7 +687,7 @@ jailhouseDomainDestroy(virDomainPtr domain)
static int
virjailhouseGetDomainTotalCpuStats(virDomainObjPtr cell,
- unsigned long long *cpustats)
+ unsigned long long *cpustats)
{
// TODO(Prakhar): Not implemented yet.
UNUSED(cell);
@@ -721,7 +737,7 @@ jailhouseDomainGetState(virDomainPtr domain,
goto cleanup;
if (virDomainGetStateEnsureACL(domain->conn, cell->def) < 0)
- goto cleanup;
+ goto cleanup;
*state = virDomainObjGetState(cell, reason);
ret = 0;
--
2.17.1
4 years, 2 months
[GSoC PATCH 7/9] Jailhouse driver: Implementation of DomainShutdown/Destroy callbacks
by Prakhar Bansal
---
src/jailhouse/jailhouse_api.c | 8 +++
src/jailhouse/jailhouse_driver.c | 101 +++++++++++++++++++++++++++++--
2 files changed, 104 insertions(+), 5 deletions(-)
diff --git a/src/jailhouse/jailhouse_api.c b/src/jailhouse/jailhouse_api.c
index 783903e939..510e2f5f66 100644
--- a/src/jailhouse/jailhouse_api.c
+++ b/src/jailhouse/jailhouse_api.c
@@ -71,6 +71,14 @@ int cell_match(const struct dirent *dirent);
int createCell(const char *conf_file);
+int loadImagesInCell(virJailhouseCellId cell_id, char *images, int num_images);
+
+int shutdownCell(virJailhouseCellId cell_id);
+
+int startCell(virJailhouseCellId cell_id);
+
+int destroyCell(virJailhouseCellId cell_id);
+
int getCellInfo(const unsigned int id,
virJailhouseCellInfoPtr * cell_info);
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 8c84a23388..46c7759cb8 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -406,8 +406,8 @@ jailhouseDomainCreateWithFlags(virDomainPtr domain,
unsigned int flags)
{
virJailhouseDriverPtr driver = domain->conn->privateData;
- virDomainObjPtr cell;
virJailhouseCellInfoPtr cell_info;
+ virDomainObjPtr cell;
int ret = -1;
virCheckFlags(VIR_DOMAIN_NONE, -1);
@@ -566,18 +566,107 @@ jailhouseDomainCreateXML(virConnectPtr conn,
return dom;
}
+static int
+jailhouseDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
+{
+ virJailhouseDriverPtr driver = domain->conn->privateData;
+ virJailhouseCellInfoPtr cell_info;
+ virDomainObjPtr cell;
+ virJailhouseCellId cell_id;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainShutdownFlagsEnsureACL(domain->conn, cell->def, flags) < 0)
+ goto cleanup;
+
+ if (virDomainObjGetState(cell, NULL) != VIR_DOMAIN_RUNNING)
+ goto cleanup;
+
+ if (!(cell_info = virJailhouseFindCellByName(driver, cell->def->name))) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name %s and ID %d)"),
+ cell->def->name, cell->def->id);
+ virDomainObjListRemove(driver->domains, cell);
+ goto cleanup;
+ }
+
+ // Initialize the cell_id.
+ cell_id.id = cell->def->id;
+ cell_id.padding = 0;
+ if (virStrcpy(cell_id.name, cell->def->name, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Cell name %s length exceeded the limit"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ if (shutdownCell(cell_id) < 0)
+ goto cleanup;
+
+ virDomainObjSetState(cell, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
+}
+
static int
jailhouseDomainShutdown(virDomainPtr domain)
{
- UNUSED(domain);
- return -1;
+ return jailhouseDomainShutdownFlags(domain, 0);
+}
+
+static int
+jailhouseDomainDestroyFlags(virDomainPtr domain, unsigned int flags)
+{
+ virJailhouseDriverPtr driver = domain->conn->privateData;
+ virJailhouseCellInfoPtr cell_info;
+ virDomainObjPtr cell;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainDestroyFlagsEnsureACL(domain->conn, cell->def) < 0)
+ goto cleanup;
+
+ if (virDomainObjGetState(cell, NULL) != VIR_DOMAIN_SHUTOFF) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("Domain %s is still running."),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ if (!(cell_info = virJailhouseFindCellByName(driver, cell->def->name))) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name %s and ID %d)"),
+ cell->def->name, cell->def->id);
+ virDomainObjListRemove(driver->domains, cell);
+ goto cleanup;
+ }
+
+ // Remove the cell from the domain list.
+ virDomainObjListRemove(driver->domains, cell);
+
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
}
static int
jailhouseDomainDestroy(virDomainPtr domain)
{
- UNUSED(domain);
- return -1;
+ return jailhouseDomainDestroyFlags(domain, 0);
}
static int
@@ -675,7 +764,9 @@ static virHypervisorDriver jailhouseHypervisorDriver = {
.domainCreateWithFlags = jailhouseDomainCreateWithFlags, /* 6.3.0 */
.domainCreateXML = jailhouseDomainCreateXML, /* 6.3.0 */
.domainShutdown = jailhouseDomainShutdown, /* 6.3.0 */
+ .domainShutdownFlags = jailhouseDomainShutdownFlags, /* 6.3.0 */
.domainDestroy = jailhouseDomainDestroy, /* 6.3.0 */
+ .domainDestroyFlags = jailhouseDomainDestroyFlags, /* 6.3.0 */
.domainGetInfo = jailhouseDomainGetInfo, /* 6.3.0 */
.domainGetState = jailhouseDomainGetState, /* 6.3.0 */
.domainLookupByID = jailhouseDomainLookupByID, /* 6.3.0 */
--
2.17.1
4 years, 2 months
[GSoC PATCH 6/9] Jailhouse driver: Implementation of DomainLookup* callbacks
by Prakhar Bansal
---
src/jailhouse/jailhouse_driver.c | 70 ++++++++++++++++++++++++++++----
1 file changed, 61 insertions(+), 9 deletions(-)
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 2bb249f996..8c84a23388 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -292,25 +292,77 @@ jailhouseConnectListAllDomains(virConnectPtr conn,
static virDomainPtr
jailhouseDomainLookupByID(virConnectPtr conn, int id)
{
- UNUSED(conn);
- UNUSED(id);
- return NULL;
+virJailhouseDriverPtr driver = conn->privateData;
+ virDomainObjPtr cell;
+ virDomainPtr dom = NULL;
+
+ cell = virDomainObjListFindByID(driver->domains, id);
+
+ if (!cell) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching ID '%d'"), id);
+ goto cleanup;
+ }
+
+ if (virDomainLookupByIDEnsureACL(conn, cell->def) < 0)
+ goto cleanup;
+
+ dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return dom;
}
static virDomainPtr
jailhouseDomainLookupByName(virConnectPtr conn, const char *name)
{
- UNUSED(conn);
- UNUSED(name);
- return NULL;
+ virJailhouseDriverPtr driver = conn->privateData;
+ virDomainObjPtr cell;
+ virDomainPtr dom = NULL;
+
+ cell = virDomainObjListFindByName(driver->domains, name);
+
+ if (!cell) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching name '%s'"), name);
+ goto cleanup;
+ }
+
+ if (virDomainLookupByNameEnsureACL(conn, cell->def) < 0)
+ goto cleanup;
+
+ dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return dom;
}
static virDomainPtr
jailhouseDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
- UNUSED(conn);
- UNUSED(uuid);
- return NULL;
+ virJailhouseDriverPtr driver = conn->privateData;
+ virDomainObjPtr cell;
+ virDomainPtr dom = NULL;
+
+ cell = virDomainObjListFindByUUID(driver->domains, uuid);
+
+ if (!cell) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(uuid, uuidstr);
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching UUID '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (virDomainLookupByUUIDEnsureACL(conn, cell->def) < 0)
+ goto cleanup;
+
+ dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return dom;
}
static virDomainObjPtr
--
2.17.1
4 years, 2 months
[GSoC PATCH 5/9] Jailhouse driver: Implementation of DomainInfo/State/List
by Prakhar Bansal
---
src/jailhouse/jailhouse_driver.c | 102 +++++++++++++++++++++++++------
1 file changed, 83 insertions(+), 19 deletions(-)
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 5b7bdc92d8..2bb249f996 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -267,19 +267,26 @@ static int
jailhouseNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr nodeinfo)
{
- UNUSED(conn);
- UNUSED(nodeinfo);
- return -1;
+ if (virNodeGetInfoEnsureACL(conn) < 0)
+ return -1;
+
+ return virCapabilitiesGetNodeInfo(nodeinfo);
}
static int
jailhouseConnectListAllDomains(virConnectPtr conn,
- virDomainPtr **domain, unsigned int flags)
+ virDomainPtr **domains,
+ unsigned int flags)
{
- UNUSED(conn);
- UNUSED(domain);
- UNUSED(flags);
- return -1;
+ virJailhouseDriverPtr driver = conn->privateData;
+
+ virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
+
+ if (virConnectListAllDomainsEnsureACL(conn) < 0)
+ return -1;
+
+ return virDomainObjListExport(driver->domains, conn, domains,
+ virConnectListAllDomainsCheckACL, flags);
}
static virDomainPtr
@@ -522,30 +529,87 @@ jailhouseDomainDestroy(virDomainPtr domain)
}
static int
-jailhouseDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
+virjailhouseGetDomainTotalCpuStats(virDomainObjPtr cell,
+ unsigned long long *cpustats)
{
- UNUSED(domain);
- UNUSED(info);
+ // TODO(Prakhar): Not implemented yet.
+ UNUSED(cell);
+ UNUSED(cpustats);
return -1;
}
+static int
+jailhouseDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
+{
+ virDomainObjPtr cell;
+ int ret = -1;
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainGetInfoEnsureACL(domain->conn, cell->def) < 0)
+ goto cleanup;
+
+ if (virDomainObjIsActive(cell)) {
+ if (virjailhouseGetDomainTotalCpuStats(cell, &(info->cpuTime)) < 0)
+ goto cleanup;
+ } else {
+ info->cpuTime = 0;
+ }
+
+ info->state = virDomainObjGetState(cell, NULL);
+ info->maxMem = virDomainDefGetMemoryTotal(cell->def);
+ info->nrVirtCpu = virDomainDefGetVcpus(cell->def);
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
+}
+
static int
jailhouseDomainGetState(virDomainPtr domain,
int *state, int *reason, unsigned int flags)
{
- UNUSED(domain);
- UNUSED(state);
- UNUSED(reason);
- UNUSED(flags);
- return -1;
+ virDomainObjPtr cell;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainGetStateEnsureACL(domain->conn, cell->def) < 0)
+ goto cleanup;
+
+ *state = virDomainObjGetState(cell, reason);
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
}
static char *
jailhouseDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
{
- UNUSED(domain);
- UNUSED(flags);
- return NULL;
+ virDomainObjPtr cell;
+ char *ret = NULL;
+
+ virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainGetXMLDescEnsureACL(domain->conn, cell->def, flags) < 0)
+ goto cleanup;
+
+ ret = virDomainDefFormat(cell->def, NULL /* xmlopt */,
+ virDomainDefFormatConvertXMLFlags(flags));
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
}
static virHypervisorDriver jailhouseHypervisorDriver = {
--
2.17.1
4 years, 2 months
[GSoC PATCH 4/9] Jailhouse driver: Implementation of DomainCreate* callbacks
by Prakhar Bansal
Implemented Jailhouse hypervisor APIs for cell
load/start/shutdown/destroy.
---
src/jailhouse/jailhouse_api.c | 100 ++++++++++++--
src/jailhouse/jailhouse_api.h | 29 +++++
src/jailhouse/jailhouse_driver.c | 217 +++++++++++++++++++++++++++++--
src/jailhouse/jailhouse_driver.h | 8 ++
4 files changed, 335 insertions(+), 19 deletions(-)
diff --git a/src/jailhouse/jailhouse_api.c b/src/jailhouse/jailhouse_api.c
index cda00b50e7..783903e939 100644
--- a/src/jailhouse/jailhouse_api.c
+++ b/src/jailhouse/jailhouse_api.c
@@ -43,11 +43,14 @@
#define JAILHOUSE_CELLS "/sys/devices/jailhouse/cells"
#define MAX_JAILHOUSE_SYS_CONFIG_FILE_SIZE 1024*1024
#define MAX_JAILHOUSE_CELL_CONFIG_FILE_SIZE 1024
+#define MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE 64*1024*1024
#define JAILHOUSE_ENABLE _IOW(0, 0, void *)
#define JAILHOUSE_DISABLE _IO(0, 1)
#define JAILHOUSE_CELL_CREATE _IOW(0, 2, virJailhouseCellCreate)
+#define JAILHOUSE_CELL_LOAD _IOW(0, 3, virJailhouseCellLoad)
+#define JAILHOUSE_CELL_START _IOW(0, 4, virJailhouseCellId)
#define JAILHOUSE_CELL_DESTROY _IOW(0, 5, virJailhouseCellId)
#define VIR_FROM_THIS VIR_FROM_JAILHOUSE
@@ -68,8 +71,6 @@ int cell_match(const struct dirent *dirent);
int createCell(const char *conf_file);
-int destroyCell(virJailhouseCellId cell_id);
-
int getCellInfo(const unsigned int id,
virJailhouseCellInfoPtr * cell_info);
@@ -254,7 +255,7 @@ readSysfsCellString(const unsigned int id, const char *entry)
}
int
-getCellInfo(const unsigned int id, virJailhouseCellInfoPtr * cell_info_ptr)
+getCellInfo(const unsigned int id, virJailhouseCellInfoPtr *cell_info_ptr)
{
char *tmp;
@@ -345,28 +346,105 @@ getJailhouseCellsInfo(void)
}
int
-destroyCell(virJailhouseCellId cell_id)
+loadImagesInCell(virJailhouseCellId cell_id, char **images, int num_images)
+{
+ virJailhousePreloadImagePtr image;
+ virJailhouseCellLoadPtr cell_load;
+ g_autofree char *buffer = NULL;
+ unsigned int n;
+ int len = -1, err = -1;
+ VIR_AUTOCLOSE fd = -1;
+
+
+ if (VIR_ALLOC(cell_load) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s",
+ _("Insufficient memory for cell load"));
+ return -1;
+ }
+
+
+ if (VIR_ALLOC_N(cell_load->image, num_images) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s",
+ _("Insufficient memory for cell load images"));
+ return -1;
+ }
+
+ cell_load->id = cell_id;
+ cell_load->num_preload_images = num_images;
+
+ for (n = 0, image = cell_load->image; n < num_images; n++, image++) {
+ len = virFileReadAll(images[n], MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE, &buffer);
+ if (len < 0 || !buffer) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Failed to read the image file %s"),
+ images[n]);
+ return -1;
+ }
+
+ image->source_address = (unsigned long)buffer;
+ image->size = len;
+
+ // TODO(Prakhar): Add support for target address.
+ image->target_address = 0;
+ }
+
+ fd = openDev();
+
+ err = ioctl(fd, JAILHOUSE_CELL_LOAD, cell_load);
+ if (err) {
+ virReportSystemError(errno,
+ _("Loading cell images for %d failed"),
+ cell_id.id);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+shutdownCell(virJailhouseCellId cell_id)
+{
+ // Loading 0 images in the cell causes cell to shutdown.
+ return loadImagesInCell(cell_id, NULL, 0);
+}
+
+int
+startCell(virJailhouseCellId cell_id)
{
int err = -1;
VIR_AUTOCLOSE fd = -1;
fd = openDev();
- err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
- if (err)
+ err = ioctl(fd, JAILHOUSE_CELL_START, &cell_id);
+ if (err) {
virReportSystemError(errno,
- _("Destroying cell %d failed"),
+ _("Start cell %d failed"),
cell_id.id);
+ return -1;
+ }
- return err;
+ return 0;
}
int
-destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list G_GNUC_UNUSED)
+destroyCell(virJailhouseCellId cell_id)
{
+ int err = -1;
+ VIR_AUTOCLOSE fd = -1;
+
+ fd = openDev();
- /* Iterate over all cells in cell_info_list and destroy each cell */
- // TODO: Not implemented yet.
+ err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
+ if (err) {
+ virReportSystemError(errno,
+ _("Destroying cell %d failed"),
+ cell_id.id);
+
+ return -1;
+ }
return 0;
}
diff --git a/src/jailhouse/jailhouse_api.h b/src/jailhouse/jailhouse_api.h
index 8362cb3d0f..ba39a4c8b7 100644
--- a/src/jailhouse/jailhouse_api.h
+++ b/src/jailhouse/jailhouse_api.h
@@ -48,6 +48,27 @@ struct _virJailhouseCellCreate {
__u32 padding;
};
+typedef struct _virJailhousePreloadImage virJailhousePreloadImage;
+typedef virJailhousePreloadImage *virJailhousePreloadImagePtr;
+
+struct _virJailhousePreloadImage {
+ __u64 source_address;
+ __u64 size;
+ __u64 target_address;
+ __u64 padding;
+};
+
+typedef struct _virJailhouseCellLoad virJailhouseCellLoad;
+typedef virJailhouseCellLoad *virJailhouseCellLoadPtr;
+
+struct _virJailhouseCellLoad {
+ struct _virJailhouseCellId id;
+ __u32 num_preload_images;
+ __u32 padding;
+ struct _virJailhousePreloadImage image[];
+};
+
+
// Enables the Jailhouse hypervisor by reading the hypervisor system
// configuration from the given file and calls the ioctl API to
// enable the hypervisor.
@@ -62,6 +83,14 @@ int jailhouseDisable(void);
// provided in the dir_name.
int createJailhouseCells(const char *dir_path);
+int loadImagesInCell(virJailhouseCellId cell_id, char **images, int num_images);
+
+int startCell(virJailhouseCellId cell_id);
+
+int shutdownCell(virJailhouseCellId cell_id);
+
+int destroyCell(virJailhouseCellId cell_id);
+
// Destroys Jailhouse cells using the cell IDs provided in
// the cell_info_list.
int destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list);
diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c
index 75bf41fc11..5b7bdc92d8 100644
--- a/src/jailhouse/jailhouse_driver.c
+++ b/src/jailhouse/jailhouse_driver.c
@@ -25,7 +25,6 @@
#include "configmake.h"
#include "datatypes.h"
#include "domain_conf.h"
-#include "jailhouse_driver.h"
#include "virtypedparam.h"
#include "virerror.h"
#include "virstring.h"
@@ -36,6 +35,9 @@
#include "vircommand.h"
#include "virpidfile.h"
#include "access/viraccessapicheck.h"
+#include "virdomainobjlist.h"
+
+#include "jailhouse_driver.h"
#define VIR_FROM_THIS VIR_FROM_JAILHOUSE
@@ -62,7 +64,6 @@ virJailhouseDriverConfigNew(void)
{
virJailhouseDriverConfigPtr cfg;
- // TODO: Check if the following has to be uncommented.
if (virJailhouseConfigInitialize() < 0)
return NULL;
@@ -135,6 +136,7 @@ jailhouseFreeDriver(virJailhouseDriverPtr driver)
return;
virMutexDestroy(&driver->lock);
+ virObjectUnref(driver->domains);
virObjectUnref(driver->config);
VIR_FREE(driver);
}
@@ -207,6 +209,9 @@ jailhouseStateInitialize(bool privileged G_GNUC_UNUSED,
return VIR_DRV_STATE_INIT_ERROR;
}
+ if (!(jailhouse_driver->domains = virDomainObjListNew()))
+ goto error;
+
if (!(cfg = virJailhouseDriverConfigNew()))
goto error;
@@ -259,10 +264,11 @@ jailhouseConnectGetHostname(virConnectPtr conn)
}
static int
-jailhouseNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
+jailhouseNodeGetInfo(virConnectPtr conn,
+ virNodeInfoPtr nodeinfo)
{
UNUSED(conn);
- UNUSED(info);
+ UNUSED(nodeinfo);
return -1;
}
@@ -300,11 +306,205 @@ jailhouseDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
return NULL;
}
+static virDomainObjPtr
+virJailhouseDomObjFromDomain(virDomainPtr domain)
+{
+ virDomainObjPtr cell;
+ virJailhouseDriverPtr driver = domain->conn->privateData;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ cell = virDomainObjListFindByUUID(driver->domains, domain->uuid);
+ if (!cell) {
+ virUUIDFormat(domain->uuid, uuidstr);
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s' (%s)"),
+ uuidstr, domain->name);
+ return NULL;
+ }
+
+ return cell;
+}
+
+
+
+static virJailhouseCellInfoPtr
+virJailhouseFindCellByName(virJailhouseDriverPtr driver,
+ char* name)
+{
+ virJailhouseCellInfoPtr *cell = driver->cell_info_list;
+
+ while (*cell) {
+ if (STRCASEEQ((*cell)->id.name, name))
+ return *cell;
+ cell++;
+ }
+
+ return NULL;
+}
+
+static int
+jailhouseDomainCreateWithFlags(virDomainPtr domain,
+ unsigned int flags)
+{
+ virJailhouseDriverPtr driver = domain->conn->privateData;
+ virDomainObjPtr cell;
+ virJailhouseCellInfoPtr cell_info;
+ int ret = -1;
+
+ virCheckFlags(VIR_DOMAIN_NONE, -1);
+
+ if (!domain->name) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error while reading the domain name"));
+ goto cleanup;
+ }
+
+ if (!domain->id) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error while reading the domain ID"));
+ goto cleanup;
+ }
+
+ if (!(cell = virJailhouseDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainCreateWithFlagsEnsureACL(domain->conn, cell->def) < 0)
+ goto cleanup;
+
+ if (!(cell_info = virJailhouseFindCellByName(driver, cell->def->name))) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name %s and ID %d)"),
+ cell->def->name, cell->def->id);
+ virDomainObjListRemove(driver->domains, cell);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ virDomainObjEndAPI(&cell);
+ return ret;
+
+}
+
static int
jailhouseDomainCreate(virDomainPtr domain)
{
- UNUSED(domain);
- return -1;
+ return jailhouseDomainCreateWithFlags(domain, 0);
+}
+
+static virDomainPtr
+jailhouseDomainCreateXML(virConnectPtr conn,
+ const char *xml,
+ unsigned int flags)
+{
+ virJailhouseDriverPtr driver = conn->privateData;
+ virJailhouseCellInfoPtr cell_info;
+ virDomainPtr dom = NULL;
+ virDomainDefPtr def = NULL;
+ virDomainObjPtr cell = NULL;
+ virDomainDiskDefPtr disk = NULL;
+ virJailhouseCellId cell_id;
+ char **images = NULL;
+ int num_images = 0, i = 0;
+ unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
+
+ if (flags & VIR_DOMAIN_START_VALIDATE)
+ parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
+
+ if ((def = virDomainDefParseString(xml, NULL,
+ NULL, parse_flags)) == NULL)
+ goto cleanup;
+
+ if ((cell = virDomainObjListFindByUUID(driver->domains, def->uuid)))
+ goto cleanup;
+
+ if (virDomainCreateXMLEnsureACL(conn, def) < 0)
+ goto cleanup;
+
+ if (!(cell_info = virJailhouseFindCellByName(driver, def->name))) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("cell info for %s not found"),
+ def->name);
+ goto cleanup;
+ }
+
+ // Assign cell Id to the domain.
+ def->id = cell_info->id.id;
+
+ if (!(cell = virDomainObjListAdd(driver->domains, def,
+ NULL,
+ VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+ VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL)))
+ goto cleanup;
+
+ def = NULL;
+
+ if (cell->def->ndisks < 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Domain XML doesn't contain any disk images"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(images, cell->def->ndisks) < 0)
+ goto cleanup;
+
+ for (i = 0; i < cell->def->ndisks; ++i) {
+ images[i] = NULL;
+
+ if (cell->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
+ virDomainDiskGetType(cell->def->disks[i]) == VIR_STORAGE_TYPE_FILE) {
+ disk = cell->def->disks[i];
+ const char *src = virDomainDiskGetSource(disk);
+ if (!src) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("First file-based harddisk has no source"));
+ goto cleanup;
+ }
+
+ images[i] = (char *)src;
+ num_images++;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("A Jailhouse doamin(cell) can ONLY have FILE type disks"));
+ goto cleanup;
+ }
+ }
+
+ // Initialize the cell_id.
+ cell_id.id = cell->def->id;
+ cell_id.padding = 0;
+ if (virStrncpy(cell_id.name, cell->def->name, JAILHOUSE_CELL_ID_NAMELEN, JAILHOUSE_CELL_ID_NAMELEN) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Cell name %s length exceeded the limit"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ if (loadImagesInCell(cell_id, images, num_images) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to load images in the Cell %s"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Starting the domain...");
+
+ if (startCell(cell_id) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to start the Cell %s"),
+ cell->def->name);
+ goto cleanup;
+ }
+
+ virDomainObjSetState(cell, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED);
+
+ dom = virGetDomain(conn, cell->def->name, cell->def->uuid, cell->def->id);
+
+ cleanup:
+ virDomainDefFree(def);
+ virDomainObjEndAPI(&cell);
+ return dom;
}
static int
@@ -314,7 +514,6 @@ jailhouseDomainShutdown(virDomainPtr domain)
return -1;
}
-
static int
jailhouseDomainDestroy(virDomainPtr domain)
{
@@ -356,7 +555,9 @@ static virHypervisorDriver jailhouseHypervisorDriver = {
.connectListAllDomains = jailhouseConnectListAllDomains, /* 6.3.0 */
.connectGetType = jailhouseConnectGetType, /* 6.3.0 */
.connectGetHostname = jailhouseConnectGetHostname, /* 6.3.0 */
- .domainCreate = jailhouseDomainCreate, /* 6.3.0 */
+ .domainCreate = jailhouseDomainCreate, /*6.3.0 */
+ .domainCreateWithFlags = jailhouseDomainCreateWithFlags, /* 6.3.0 */
+ .domainCreateXML = jailhouseDomainCreateXML, /* 6.3.0 */
.domainShutdown = jailhouseDomainShutdown, /* 6.3.0 */
.domainDestroy = jailhouseDomainDestroy, /* 6.3.0 */
.domainGetInfo = jailhouseDomainGetInfo, /* 6.3.0 */
diff --git a/src/jailhouse/jailhouse_driver.h b/src/jailhouse/jailhouse_driver.h
index 8a0e111676..8fc99fe7d2 100644
--- a/src/jailhouse/jailhouse_driver.h
+++ b/src/jailhouse/jailhouse_driver.h
@@ -22,7 +22,9 @@
#include <linux/types.h>
+#include "domain_event.h"
#include "jailhouse_api.h"
+#include "virdomainobjlist.h"
int jailhouseRegister(void);
@@ -64,6 +66,12 @@ struct _virJailhouseDriver {
// All the cells created during connect open on the hypervisor.
virJailhouseCellInfoPtr *cell_info_list;
+
+ // XML options for domain XMLs.
+ virDomainXMLOptionPtr xmlopt;
+ virDomainObjListPtr domains;
+
+ virObjectEventStatePtr domainEventState;
};
struct _jailhouseCell {
--
2.17.1
4 years, 2 months
[PATCH v4 0/4] qemu: Support rbd namespace attribute
by Han Han
Diff from v3:
- add the check for capability of rbd namespace
- rename the item of rbd namespace in disk source struct
- combine the commit of doc into the commit of patch
- remove the code for -drive
gitlab branch:
https://gitlab.com/hhan2/libvirt/-/commits/rbd-namespace-v4
Han Han (4):
qemu_capabilities: Add QEMU_CAPS_RBD_NAMESPACE
conf: Support to parse rbd namespace attribute
qemu: Implement rbd namespace attribute
news: qemu: Support rbd namespace
NEWS.rst | 6 +++
docs/formatdomain.rst | 5 ++-
docs/schemas/domaincommon.rng | 3 ++
src/conf/domain_conf.c | 4 ++
src/qemu/qemu_block.c | 1 +
src/qemu/qemu_capabilities.c | 4 ++
src/qemu/qemu_capabilities.h | 3 ++
src/qemu/qemu_domain.c | 8 ++++
src/util/virstoragefile.h | 1 +
.../caps_5.0.0.aarch64.xml | 1 +
.../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 +
.../caps_5.0.0.riscv64.xml | 1 +
.../caps_5.0.0.x86_64.xml | 1 +
.../caps_5.1.0.x86_64.xml | 1 +
...k-network-rbd-namespace.x86_64-latest.args | 41 +++++++++++++++++++
.../disk-network-rbd-namespace.xml | 33 +++++++++++++++
tests/qemuxml2argvtest.c | 1 +
...sk-network-rbd-namespace.x86_64-latest.xml | 41 +++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
19 files changed, 156 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-namespace.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-namespace.xml
create mode 100644 tests/qemuxml2xmloutdata/disk-network-rbd-namespace.x86_64-latest.xml
--
2.27.0
4 years, 2 months
[GSoC] Take migration in Salt virt module to the next level
by Radostin Stoyanov
Hello again libvirt community!
This summer, I once again worked on a GSoC project with libvirt. This
time, the goal of my project was to improve the libvirt integration with
SaltStack and, in particular, the support for VM migration.
SaltStack is an incredibly valuable tool that helps with automation and
infrastructure management. This is accomplished with master/minion
topology where a master acts as a central control bus for the clients
(minions), and the minions connect back to the master. The Salt virt
module provides support for core cloud operations such as VM lifecycle
management, including VM migration, by allowing minions to connect with
libvirt virtualization host.
The Salt virt.migrate interface allows users to migrate a VM from one
host to another. However, the implementation of this function used to be
based on the virsh command-line tool (instead of the libvirt Python API
bindings), which had resulted in an increased code complexity (e.g.,
string concatenation, invoking Popen.subprocess, etc) and had a limited
number of migration options exposed to users.
My project was roughly separated into three phases. The aim of the first
phase was to improve the test coverage of the virt module by increasing
the number of integration tests (i.e., before applying any major code
changes). However, SaltStack is designed to run on different platforms,
and it has been extended over the years to support many applications and
tools. Consequently, the SaltStack test suite has grown in complexity
and number of dependencies as well. As a result, not all of them (e.g.,
libvirt and qemu) are available in the Jenkins CI environment. In
addition, our goal was to only be able to effectively test VM lifecycle
management features (start, destroy, list, etc.) but also to test VM
migration. To achieve this we packaged libvirt, qemu, and all required
SaltStack minion dependencies in a container image that allows us to
spawn multiple virtualization host instances on a single machine (with
low virtualization overhead).
In the second phase of the project, now with a test environment in
place, we were able to refactor the virt.migrate implementation to
utilize the Python bindings of libvirt and add support for additional
migration options (described in the “What's new?” section below).
The third phase was primarily focused on refining the set patches,
resolving merge conflicts with upstream changes or other related PRs.
One of the major challenges was to revisit the set of tests to make them
compatible with pytest as well to collaborate with the SaltStack
community to ensure that all proposed changes will be easy to maintain
in the future.
Contributions
============
Although the development work was done in several iterations, with code
reviews on regular basis, the final result was consolidated in a single
GitHub pull request: https://github.com/saltstack/salt/pull/57947
What’s new?
===========
https://docs.saltstack.com/en/master/ref/modules/all/salt.modules.virt.ht...
The virt.migrate interface of SaltStack has been extended to support
target URI format:
$ salt src virt.migrate guest qemu+ssh://dst/system
$ salt src virt.migrate guest qemu+tcp://dst/system
$ salt src virt.migrate guest qemu+tls://dst/system
with preserved backward compatibility:
$ salt src virt.migrate guest dst
$ salt src virt.migrate guest dst True
Support for the following migration options was introduced:
Disable live migration
$ salt src virt.migrate guest qemu+ssh://dst/system live=False
Leave the migrated VM transient on destination host
$ salt src virt.migrate guest qemu+ssh://dst/system persistent=False
Leave the domain defined on the source host
$ salt src virt.migrate guest qemu+ssh://dst/system undefinesource=False
Offline migration
$ salt src virt.migrate guest qemu+ssh://dst/system offline=False
Set maximum bandwidth (in MiB/s)
$ salt src virt.migrate guest qemu+tls://dst/system max_bandwidth=10
Set maximum tolerable downtime for live-migration (i.e. a number of
milliseconds the VM is allowed to be down at the end of live migration)
$ salt src virt.migrate guest qemu+tls://dst/system max_downtime=100
Set a number of parallel network connections for live migration
$ salt src virt.migrate guest qemu+tls://dst/system parallel_connections=10
Live migration with enabled compression
$ salt src virt.migrate guest qemu+tls://dst/system \
compressed=True \
comp_methods=mt \
comp_mt_level=5 \
comp_mt_threads=4 \
comp_mt_dthreads=4
$ salt src virt.migrate guest qemu+tls://dst/system \
compressed=True \
comp_methods=xbzrle \
comp_xbzrle_cache=1024
Migrate non-shared storage
(Full disk copy)
$ salt src virt.migrate guest qemu+tls://dst/system copy_storage=all
(Incremental copy)
$ salt src virt.migrate guest qemu+tls://dst/system copy_storage=inc
Using post-copy migration
$ salt src virt.migrate guest qemu+tls://dst/system postcopy=True
$ salt src virt.migrate_start_postcopy guest
Using post-copy migration with bandwidth limit (MiB/s)
$ salt src virt.migrate guest qemu+tls://dst/system \
postcopy=True \
postcopy_bandwidth=1
$ salt src virt.migrate_start_postcopy guest
Acknowledgments
===============
I would like to sincerely thank all those who provided me with their
time, assistance, and guidance during the course of this project, for
which I am enormously grateful.
I would like to thank Cedric Bosdonnat (cbosdo), Pedro Algarvio
(s0undt3ch), Wayne Werner (waynew), Charles McMarrow (cmcmarrow) and
Daniel Wozniak (dwoz) who offered a huge amount of support, expertise,
guidance and code reviews.
I would also like to thank Michal Privoznik (mprivozn), Martin
Kletzander (mkletzan) and the rest of the libvirt and SaltStack
communities who have been extremely supportive.
Best wishes,
Radostin
4 years, 2 months