[libvirt] [PATCH] bhyve: domain autostart support

Re-submit patch provided by David back in February when bhyve driver was not in the tree. I did some changes to the patch on the way: - rebase to the current master - add ACL checks - use bhyveDomObjFromDomain() instead of custom virDomainObjListFindByUUID() - fix problems reported by 'syntax-check' David Shane Holden (1): bhyve: domain autostart support src/bhyve/bhyve_driver.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++- src/bhyve/bhyve_utils.h | 5 ++ 2 files changed, 139 insertions(+), 1 deletion(-) -- 1.8.4.2

From: David Shane Holden <dpejesh@yahoo.com> Signed-off-by: Roman Bogorodskiy <bogorodskiy@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

On 23.03.2014 10:16, Roman Bogorodskiy wrote:
From: David Shane Holden <dpejesh@yahoo.com>
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++- src/bhyve/bhyve_utils.h | 5 ++ 2 files changed, 139 insertions(+), 1 deletion(-)
ACK. However, wait before pushing this one until after the release. It's new feature not a bug fix after all. Michal

Michal Privoznik wrote:
On 23.03.2014 10:16, Roman Bogorodskiy wrote:
From: David Shane Holden <dpejesh@yahoo.com>
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++- src/bhyve/bhyve_utils.h | 5 ++ 2 files changed, 139 insertions(+), 1 deletion(-)
ACK. However, wait before pushing this one until after the release. It's new feature not a bug fix after all.
Thanks for the review! When the freeze is over, I'll push after rebasing and giving it one more round of testing to be sure. Roman Bogorodskiy

Roman Bogorodskiy wrote:
Michal Privoznik wrote:
On 23.03.2014 10:16, Roman Bogorodskiy wrote:
From: David Shane Holden <dpejesh@yahoo.com>
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++- src/bhyve/bhyve_utils.h | 5 ++ 2 files changed, 139 insertions(+), 1 deletion(-)
ACK. However, wait before pushing this one until after the release. It's new feature not a bug fix after all.
Thanks for the review! When the freeze is over, I'll push after rebasing and giving it one more round of testing to be sure.
Pushed now, thanks! David, congratulations on your first libvirt contribution! Roman Bogorodskiy
participants (2)
-
Michal Privoznik
-
Roman Bogorodskiy