[PATCH v2 0/3] bhyve: implement virDomainSetLifecycleAction() API
Changes since v1: Main changes are in the patch 2/3. The original series added lifecycle action handling to bhyve_monitor.c, but bhyve_driver.c still had the code to e.g. issue a shutdown command on reboot right away when onReboot was set to destroy, bypassing monitor. It does not play well together, and also it's confusing. In v2 monitor is the only place to handle lifecycle settings. Roman Bogorodskiy (3): bhyve: add validation for lifecycle actions bhyve: monitor: respect on_poweroff / on_reboot settings bhyve: implement virDomainSetLifecycleAction() API src/bhyve/bhyve_domain.c | 36 +++++++++++ src/bhyve/bhyve_domain.h | 3 + src/bhyve/bhyve_driver.c | 122 ++++++++++++++++++++++++++++++++++---- src/bhyve/bhyve_monitor.c | 20 +++++-- 4 files changed, 165 insertions(+), 16 deletions(-) -- 2.55.0
The bhyve driver currently supports redefining 'onPoweroff' and 'onReboot', and possible actions are 'destroy' and 'restart'. Redefining 'onCrash' is not supported. Validate all these in bhyveDomainDefValidate(). Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> --- src/bhyve/bhyve_domain.c | 36 ++++++++++++++++++++++++++++++++++++ src/bhyve/bhyve_domain.h | 3 +++ 2 files changed, 39 insertions(+) diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index 726cf1ffed..3ecb1d52cb 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -520,6 +520,39 @@ bhyveDomainDeviceDefValidate(const virDomainDeviceDef *dev, } +int +bhyveValidateLifecycleAction(virDomainLifecycleAction onPoweroff, + virDomainLifecycleAction onReboot, + virDomainLifecycleAction onCrash) +{ + if ((onPoweroff != VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY && + onPoweroff != VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) || + (onReboot != VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY && + onReboot != VIR_DOMAIN_LIFECYCLE_ACTION_RESTART)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("bhyve driver supports only 'restart' and 'destroy' actions for 'on_reboot'/'on_poweroff'")); + return -1; + } + + if (onCrash != VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("bhyve driver does not support 'on_crash' actions other than 'destroy'")); + return -1; + } + + return 0; +} + + +static int +bhyveValidateDomainLifecycleAction(const virDomainDef *def) +{ + return bhyveValidateLifecycleAction(def->onPoweroff, + def->onReboot, + def->onCrash); +} + + static int bhyveDomainDefValidate(const virDomainDef *def, void *opaque G_GNUC_UNUSED, @@ -607,6 +640,9 @@ bhyveDomainDefValidate(const virDomainDef *def, return -1; } + if (bhyveValidateDomainLifecycleAction(def) < 0) + return -1; + if (!def->os.loader) return 0; diff --git a/src/bhyve/bhyve_domain.h b/src/bhyve/bhyve_domain.h index fa7a685d59..c9fa776651 100644 --- a/src/bhyve/bhyve_domain.h +++ b/src/bhyve/bhyve_domain.h @@ -55,3 +55,6 @@ extern virXMLNamespace virBhyveDriverDomainXMLNamespace; int virBhyveDomainObjStartWorker(virDomainObj *dom); void virBhyveDomainObjStopWorker(virDomainObj *dom); int bhyveDomainNamePathsCleanup(const char *name, bool bestEffort); +int bhyveValidateLifecycleAction(virDomainLifecycleAction onPoweroff, + virDomainLifecycleAction onReboot, + virDomainLifecycleAction onCrash); -- 2.55.0
Currently, the bhyve driver respects domain's on_poweroff and on_reboot settings for when shutdown and reboot are triggered via libvirt API. However, they are not respected when the event is triggered within the guest. Address that by updating monitor to execute the configured action. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> --- src/bhyve/bhyve_driver.c | 12 ------------ src/bhyve/bhyve_monitor.c | 20 ++++++++++++++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 41bcf9b559..d46a401507 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1118,12 +1118,6 @@ bhyveDomainShutdownFlags(virDomainPtr dom, unsigned int flags) if (!(vm = bhyveDomObjFromDomain(dom))) goto cleanup; - if (vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART || - vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME) { - isReboot = true; - VIR_INFO("Domain on_poweroff setting overridden, attempting reboot"); - } - priv = vm->privateData; agentRequested = flags & VIR_DOMAIN_SHUTDOWN_GUEST_AGENT; signalRequested = flags & VIR_DOMAIN_SHUTDOWN_SIGNAL; @@ -1189,12 +1183,6 @@ bhyveDomainReboot(virDomainPtr dom, unsigned int flags) if (!(vm = bhyveDomObjFromDomain(dom))) goto cleanup; - if (vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY || - vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE) { - isReboot = false; - VIR_INFO("Domain on_reboot setting overridden, shutting down"); - } - priv = vm->privateData; agentRequested = flags & VIR_DOMAIN_REBOOT_GUEST_AGENT; signalRequested = flags & VIR_DOMAIN_REBOOT_SIGNAL; diff --git a/src/bhyve/bhyve_monitor.c b/src/bhyve/bhyve_monitor.c index 8391f10d34..379e588070 100644 --- a/src/bhyve/bhyve_monitor.c +++ b/src/bhyve/bhyve_monitor.c @@ -161,12 +161,24 @@ bhyveMonitorIO(int watch, int kq, int events G_GNUC_UNUSED, void *opaque) } else if (WIFEXITED(status)) { if (WEXITSTATUS(status) == 0 || mon->reboot) { /* 0 - reboot */ - VIR_INFO("Guest %s rebooted; restarting domain.", name); - virBhyveProcessRestart(driver, vm); + if (vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY || + vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE) { + VIR_INFO("Guest %s rebooted; domain on_reboot setting overridden, shutting down.", name); + virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN, false); + } else { + VIR_INFO("Guest %s rebooted; restarting domain.", name); + virBhyveProcessRestart(driver, vm); + } } else if (WEXITSTATUS(status) < 3) { /* 1 - shutdown, 2 - halt, 3 - triple fault. others - error */ - VIR_INFO("Guest %s shut itself down; destroying domain.", name); - virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN, false); + if (vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART || + vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME) { + VIR_INFO("Guest %s shut itself down; domain on_poweroff setting overridden, attempting reboot.", name); + virBhyveProcessRestart(driver, vm); + } else { + VIR_INFO("Guest %s shut itself down; destroying domain.", name); + virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN, false); + } } else { VIR_INFO("Guest %s had an error and exited with status %d; destroying domain.", name, WEXITSTATUS(status)); -- 2.55.0
Implement virDomainSetLifecycleAction() API for the bhyve driver. Support both config and live configuration update. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> --- src/bhyve/bhyve_driver.c | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index d46a401507..cf4e918472 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -2806,6 +2806,115 @@ bhyveDomainRename(virDomainPtr domain, return ret; } +static int +bhyveDomainSetLifecycleActionValidate(virDomainDef *def, + virDomainLifecycle type, + virDomainLifecycleAction action) +{ + virDomainLifecycleAction onPoweroff = def->onPoweroff; + virDomainLifecycleAction onReboot = def->onReboot; + virDomainLifecycleAction onCrash = def->onCrash; + + switch (type) { + case VIR_DOMAIN_LIFECYCLE_POWEROFF: + onPoweroff = action; + break; + case VIR_DOMAIN_LIFECYCLE_REBOOT: + onReboot = action; + break; + case VIR_DOMAIN_LIFECYCLE_CRASH: + onCrash = action; + break; + case VIR_DOMAIN_LIFECYCLE_LAST: + break; + } + + if (bhyveValidateLifecycleAction(onPoweroff, onReboot, onCrash) < 0) + return -1; + + return 0; +} + +static void +bhyveDomainModifyLifecycleAction(virDomainDef *def, + virDomainLifecycle type, + virDomainLifecycleAction action) +{ + switch (type) { + case VIR_DOMAIN_LIFECYCLE_POWEROFF: + def->onPoweroff = action; + break; + case VIR_DOMAIN_LIFECYCLE_REBOOT: + def->onReboot = action; + break; + case VIR_DOMAIN_LIFECYCLE_CRASH: + def->onCrash = action; + break; + case VIR_DOMAIN_LIFECYCLE_LAST: + break; + } +} + +static int +bhyveDomainSetLifecycleAction(virDomainPtr domain, + unsigned int type, + unsigned int action, + unsigned int flags) +{ + struct _bhyveConn *privconn = domain->conn->privateData; + virDomainObj *vm = NULL; + virDomainDef *def = NULL; + virDomainDef *persistentDef = NULL; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + if (!virDomainDefLifecycleActionAllowed(type, action)) + goto cleanup; + + if (!(vm = bhyveDomObjFromDomain(domain))) + return -1; + + if (virDomainSetLifecycleActionEnsureACL(domain->conn, vm->def) < 0) + goto cleanup; + + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto cleanup; + + if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0) + goto endjob; + + if ((def && bhyveDomainSetLifecycleActionValidate(def, type, action) < 0) || + (persistentDef && bhyveDomainSetLifecycleActionValidate(persistentDef, type, action) < 0)) + goto endjob; + + if (def) { + bhyveDomainModifyLifecycleAction(def, type, action); + + if (virDomainObjSave(vm, privconn->xmlopt, + BHYVE_STATE_DIR) < 0) + goto endjob; + } + + if (persistentDef) { + bhyveDomainModifyLifecycleAction(persistentDef, type, action); + + if (virDomainDefSave(persistentDef, privconn->xmlopt, + BHYVE_CONFIG_DIR) < 0) + goto endjob; + } + + ret = 0; + + endjob: + virDomainObjEndJob(vm); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + static int bhyveDomainAgentSetResponseTimeout(virDomainPtr domain, int timeout, @@ -3144,6 +3253,7 @@ static virHypervisorDriver bhyveHypervisorDriver = { .domainRename = bhyveDomainRename, /* 12.6.0 */ .domainAgentSetResponseTimeout = bhyveDomainAgentSetResponseTimeout, /* 12.7.0 */ .domainGetGuestInfo = bhyveDomainGetGuestInfo, /* 12.7.0 */ + .domainSetLifecycleAction = bhyveDomainSetLifecycleAction, /* 12.8.0 */ }; -- 2.55.0
On 9/2/26 20:49, Roman Bogorodskiy wrote:
Changes since v1:
Main changes are in the patch 2/3. The original series added lifecycle action handling to bhyve_monitor.c, but bhyve_driver.c still had the code to e.g. issue a shutdown command on reboot right away when onReboot was set to destroy, bypassing monitor. It does not play well together, and also it's confusing. In v2 monitor is the only place to handle lifecycle settings.
Roman Bogorodskiy (3): bhyve: add validation for lifecycle actions bhyve: monitor: respect on_poweroff / on_reboot settings bhyve: implement virDomainSetLifecycleAction() API
src/bhyve/bhyve_domain.c | 36 +++++++++++ src/bhyve/bhyve_domain.h | 3 + src/bhyve/bhyve_driver.c | 122 ++++++++++++++++++++++++++++++++++---- src/bhyve/bhyve_monitor.c | 20 +++++-- 4 files changed, 165 insertions(+), 16 deletions(-)
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Michal Prívozník -
Roman Bogorodskiy