]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
bhyve: domain autostart support
authorDavid Shane Holden <dpejesh@yahoo.com>
Sun, 23 Mar 2014 09:16:09 +0000 (13:16 +0400)
committerRoman Bogorodskiy <bogorodskiy@gmail.com>
Sat, 5 Apr 2014 10:44:49 +0000 (14:44 +0400)
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
src/bhyve/bhyve_driver.c
src/bhyve/bhyve_utils.h

index 7a12d69db5260fdbab82118dda16248f2dbdfed0..eec598dd159d7ba8dda3efa7da719417db919c17 100644 (file)
@@ -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)
 {
@@ -261,6 +299,89 @@ bhyveDomainGetState(virDomainPtr domain,
     return ret;
 }
 
+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)
 {
@@ -729,7 +850,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,
@@ -743,6 +864,15 @@ bhyveStateInitialize(bool priveleged ATTRIBUTE_UNUSED,
     return -1;
 }
 
+static void
+bhyveStateAutoStart(void)
+{
+    if (!bhyve_driver)
+        return;
+
+    bhyveAutostartDomains(bhyve_driver);
+}
+
 static int
 bhyveConnectGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED,
                         const char *type)
@@ -832,6 +962,8 @@ static virDriver bhyveDriver = {
     .domainGetXMLDesc = bhyveDomainGetXMLDesc, /* 1.2.2 */
     .domainIsActive = bhyveDomainIsActive, /* 1.2.2 */
     .domainIsPersistent = bhyveDomainIsPersistent, /* 1.2.2 */
+    .domainGetAutostart = bhyveDomainGetAutostart, /* 1.2.4 */
+    .domainSetAutostart = bhyveDomainSetAutostart, /* 1.2.4 */
     .nodeGetCPUStats = bhyveNodeGetCPUStats, /* 1.2.2 */
     .nodeGetMemoryStats = bhyveNodeGetMemoryStats, /* 1.2.2 */
     .nodeGetInfo = bhyveNodeGetInfo, /* 1.2.3 */
@@ -846,6 +978,7 @@ static virDriver bhyveDriver = {
 static virStateDriver bhyveStateDriver = {
     .name = "bhyve",
     .stateInitialize = bhyveStateInitialize,
+    .stateAutoStart = bhyveStateAutoStart,
     .stateCleanup = bhyveStateCleanup,
 };
 
index 6c767705722eacc192d2c8c99bca201e396a8e46..94f31b085523821d7d5aede9e180428e06e92cad 100644 (file)
@@ -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);