[libvirt] [PATCH] bhyve: domain autostart support

Roman Bogorodskiy bogorodskiy at gmail.com
Sun Mar 23 09:16:09 UTC 2014


From: David Shane Holden <dpejesh at yahoo.com>

Signed-off-by: Roman Bogorodskiy <bogorodskiy at gmail.com>
---
 src/bhyve/bhyve_driver.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/bhyve/bhyve_utils.h  |   5 ++
 2 files changed, 139 insertions(+), 1 deletion(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index a524d35..b06463e 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -72,6 +72,44 @@ bhyveDriverUnlock(bhyveConnPtr driver)
     virMutexUnlock(&driver->lock);
 }
 
+static int
+bhyveAutostartDomain(virDomainObjPtr vm, void *opaque)
+{
+    const struct bhyveAutostartData *data = opaque;
+    int ret = 0;
+    virObjectLock(vm);
+    if (vm->autostart && !virDomainObjIsActive(vm)) {
+        virResetLastError();
+        ret = virBhyveProcessStart(data->conn, data->driver, vm,
+                                   VIR_DOMAIN_RUNNING_BOOTED, 0);
+        if (ret < 0) {
+            virErrorPtr err = virGetLastError();
+            VIR_ERROR(_("Failed to autostart VM '%s': %s"),
+                      vm->def->name, err ? err->message : _("unknown error"));
+        }
+    }
+    virObjectUnlock(vm);
+    return ret;
+}
+
+static void
+bhyveAutostartDomains(bhyveConnPtr driver)
+{
+    /* XXX: Figure out a better way todo this. The domain
+     * startup code needs a connection handle in order
+     * to lookup the bridge associated with a virtual
+     * network
+     */
+    virConnectPtr conn = virConnectOpen("bhyve:///system");
+    /* Ignoring NULL conn which is mostly harmless here */
+
+    struct bhyveAutostartData data = { driver, conn };
+
+    virDomainObjListForEach(driver->domains, bhyveAutostartDomain, &data);
+
+    virObjectUnref(conn);
+}
+
 static virCapsPtr
 bhyveBuildCapabilities(void)
 {
@@ -262,6 +300,89 @@ cleanup:
 }
 
 static int
+bhyveDomainGetAutostart(virDomainPtr domain, int *autostart)
+{
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    if (!(vm = bhyveDomObjFromDomain(domain)))
+        goto cleanup;
+
+    if (virDomainGetAutostartEnsureACL(domain->conn, vm->def) < 0)
+        goto cleanup;
+
+    *autostart = vm->autostart;
+    ret = 0;
+
+cleanup:
+    virObjectUnlock(vm);
+    return ret;
+}
+
+static int
+bhyveDomainSetAutostart(virDomainPtr domain, int autostart)
+{
+    virDomainObjPtr vm;
+    char *configFile = NULL;
+    char *autostartLink = NULL;
+    int ret = -1;
+
+    if (!(vm = bhyveDomObjFromDomain(domain)))
+        goto cleanup;
+
+    if (virDomainSetAutostartEnsureACL(domain->conn, vm->def) < 0)
+        goto cleanup;
+
+    if (!vm->persistent) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("cannot set autostart for transient domain"));
+        goto cleanup;
+    }
+
+    autostart = (autostart != 0);
+
+    if (vm->autostart != autostart) {
+        if ((configFile = virDomainConfigFile(BHYVE_CONFIG_DIR, vm->def->name)) == NULL)
+            goto cleanup;
+        if ((autostartLink = virDomainConfigFile(BHYVE_AUTOSTART_DIR, vm->def->name)) == NULL)
+            goto cleanup;
+
+        if (autostart) {
+            if (virFileMakePath(BHYVE_AUTOSTART_DIR) < 0) {
+                virReportSystemError(errno,
+                                     _("cannot create autostart directory %s"),
+                                     BHYVE_AUTOSTART_DIR);
+                goto cleanup;
+            }
+
+            if (symlink(configFile, autostartLink) < 0) {
+                virReportSystemError(errno,
+                                     _("Failed to create symlink '%s' to '%s'"),
+                                     autostartLink, configFile);
+                goto cleanup;
+            }
+        } else {
+            if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
+                virReportSystemError(errno,
+                                     _("Failed to delete symlink '%s'"),
+                                     autostartLink);
+                goto cleanup;
+            }
+        }
+
+        vm->autostart = autostart;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(configFile);
+    VIR_FREE(autostartLink);
+    virObjectUnlock(vm);
+    return ret;
+}
+
+static int
 bhyveDomainIsActive(virDomainPtr domain)
 {
     virDomainObjPtr obj;
@@ -701,7 +822,7 @@ bhyveStateInitialize(bool priveleged ATTRIBUTE_UNUSED,
 
     if (virDomainObjListLoadAllConfigs(bhyve_driver->domains,
                                        BHYVE_CONFIG_DIR,
-                                       NULL, 0,
+                                       BHYVE_AUTOSTART_DIR, 0,
                                        bhyve_driver->caps,
                                        bhyve_driver->xmlopt,
                                        1 << VIR_DOMAIN_VIRT_BHYVE,
@@ -715,6 +836,15 @@ cleanup:
     return -1;
 }
 
+static void
+bhyveStateAutoStart(void)
+{
+    if (!bhyve_driver)
+        return;
+
+    bhyveAutostartDomains(bhyve_driver);
+}
+
 static int
 bhyveConnectGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED,
                         const char *type)
@@ -803,6 +933,8 @@ static virDriver bhyveDriver = {
     .domainGetXMLDesc = bhyveDomainGetXMLDesc, /* 1.2.2 */
     .domainIsActive = bhyveDomainIsActive, /* 1.2.2 */
     .domainIsPersistent = bhyveDomainIsPersistent, /* 1.2.2 */
+    .domainGetAutostart = bhyveDomainGetAutostart, /* 1.2.3 */
+    .domainSetAutostart = bhyveDomainSetAutostart, /* 1.2.3 */
     .nodeGetCPUStats = bhyveNodeGetCPUStats, /* 1.2.2 */
     .nodeGetMemoryStats = bhyveNodeGetMemoryStats, /* 1.2.2 */
     .nodeGetInfo = bhyveNodeGetInfo, /* 1.2.3 */
@@ -817,6 +949,7 @@ static virDriver bhyveDriver = {
 static virStateDriver bhyveStateDriver = {
     .name = "bhyve",
     .stateInitialize = bhyveStateInitialize,
+    .stateAutoStart = bhyveStateAutoStart,
     .stateCleanup = bhyveStateCleanup,
 };
 
diff --git a/src/bhyve/bhyve_utils.h b/src/bhyve/bhyve_utils.h
index 6c76770..94f31b0 100644
--- a/src/bhyve/bhyve_utils.h
+++ b/src/bhyve/bhyve_utils.h
@@ -46,6 +46,11 @@ struct _bhyveConn {
 typedef struct _bhyveConn bhyveConn;
 typedef struct _bhyveConn *bhyveConnPtr;
 
+struct bhyveAutostartData {
+    bhyveConnPtr driver;
+    virConnectPtr conn;
+};
+
 void bhyveDriverLock(bhyveConnPtr driver);
 void bhyveDriverUnlock(bhyveConnPtr driver);
 
-- 
1.8.4.2




More information about the libvir-list mailing list