[GSoC PATCH 8/9] Jailhouse driver: Fixes for creation of cells, fetching cell info, disabling jailhouse hypervisor

Prakhar Bansal itsprakhar at gmail.com
Mon Aug 31 08:21:28 UTC 2020


From: Prakhar Bansal <itsprakhar at gmail.com>

- 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




More information about the libvir-list mailing list