diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 5526bb037f..4fc504e347 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1017,6 +1017,32 @@ bhyveDomainDestroy(virDomainPtr dom) return ret; } +static int +bhyveDomainShutdown(virDomainPtr dom) +{ + virDomainObjPtr vm; + int ret = -1; + + if (!(vm = bhyveDomObjFromDomain(dom))) + goto cleanup; + + if (virDomainShutdownEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("Domain is not running")); + goto cleanup; + } + + ret = virBhyveProcessShutdown(vm); + + cleanup: + if (vm) + virObjectUnlock(vm); + return ret; +} + static int bhyveDomainOpenConsole(virDomainPtr dom, const char *dev_name ATTRIBUTE_UNUSED, @@ -1502,6 +1528,7 @@ static virHypervisorDriver bhyveHypervisorDriver = { .domainCreateWithFlags = bhyveDomainCreateWithFlags, /* 1.2.3 */ .domainCreateXML = bhyveDomainCreateXML, /* 1.2.4 */ .domainDestroy = bhyveDomainDestroy, /* 1.2.2 */ + .domainShutdown = bhyveDomainShutdown, /* 1.3.3 */ .domainLookupByUUID = bhyveDomainLookupByUUID, /* 1.2.2 */ .domainLookupByName = bhyveDomainLookupByName, /* 1.2.2 */ .domainLookupByID = bhyveDomainLookupByID, /* 1.2.3 */ diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index fe61a9aa30..6db070f6ba 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -308,6 +308,29 @@ virBhyveProcessStop(bhyveConnPtr driver, return ret; } +int +virBhyveProcessShutdown(virDomainObjPtr vm) +{ + if (vm->pid <= 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid PID %d for VM"), + (int)vm->pid); + return -1; + } + + /* Bhyve tries to perform ACPI shutdown when it receives + * SIGTERM signal. So we just issue SIGTERM here and rely + * on the bhyve monitor to clean things up if process disappears. + */ + if (virProcessKill(vm->pid, SIGTERM) != 0) { + VIR_WARN("Failed to terminate bhyve process for VM '%s': %s", + vm->def->name, virGetLastErrorMessage()); + return -1; + } + + return 0; +} + int virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm, unsigned long long *cpustats) diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h index cfa80af6aa..ebabe17d87 100644 --- a/src/bhyve/bhyve_process.h +++ b/src/bhyve/bhyve_process.h @@ -34,6 +34,8 @@ int virBhyveProcessStop(bhyveConnPtr driver, virDomainObjPtr vm, virDomainShutoffReason reason); +int virBhyveProcessShutdown(virDomainObjPtr vm); + int virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm, unsigned long long *cpustats);