On Thu, Sep 17, 2020 at 04:23:54PM +0100, Daniel P. Berrangé wrote: > From: Prakhar Bansal <prakharbansal0910@xxxxxxxxx> > > 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 :|