On Thu, Sep 17, 2020 at 04:23:54PM +0100, Daniel P. Berrangé wrote:
From: Prakhar Bansal <prakharbansal0910(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;
+ }
No need to check failure - these abort on OOM.
+
+ 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();
Check error here.
+
+ 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;
+}
-destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list
G_GNUC_UNUSED)
+destroyCell(virJailhouseCellId cell_id)
{
+ int err = -1;
+ VIR_AUTOCLOSE fd = -1;
+
+ fd = openDev();
Check error
- /* 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;
+ }
+typedef struct _virJailhousePreloadImage virJailhousePreloadImage;
+typedef virJailhousePreloadImage *virJailhousePreloadImagePtr;
+
+struct _virJailhousePreloadImage {
+ __u64 source_address;
uint64_t, etc
+ __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[];
+};
+
+
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.
Forgot to mention this on previous patches, but we only want C style
comments /* ... */, never C++ style.
+ 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;
+ }
+ }
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 */
Introduced a whitespace bug
+ .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 */
Regards,
Daniel
--
|:
https://berrange.com -o-
https://www.flickr.com/photos/dberrange :|
|:
https://libvirt.org -o-
https://fstop138.berrange.com :|
|:
https://entangle-photo.org -o-
https://www.instagram.com/dberrange :|