[libvirt PATCH 4/9] Jailhouse driver: Implementation of DomainCreate* callbacks
Daniel P. Berrangé
berrange at redhat.com
Wed Sep 23 08:32:47 UTC 2020
On Thu, Sep 17, 2020 at 04:23:54PM +0100, Daniel P. Berrangé wrote:
> From: Prakhar Bansal <prakharbansal0910 at 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 :|
More information about the libvir-list
mailing list