提交 30ab31a9 编写于 作者: R Ryan Moeller 提交者: Daniel P. Berrangé

bhyve: monitor: Make bhyveMonitor a virClass

This makes lifecycle management a bit easier thanks to ref counting, and
it is closer to what the qemu driver does.
Reviewed-by: NDaniel P. Berrangé <berrange@redhat.com>
Signed-off-by: NRyan Moeller <ryan@iXsystems.com>
上级 fd54da1e
......@@ -32,24 +32,51 @@
#include "virerror.h"
#include "virfile.h"
#include "virlog.h"
#include "virobject.h"
#define VIR_FROM_THIS VIR_FROM_BHYVE
VIR_LOG_INIT("bhyve.bhyve_monitor");
struct _bhyveMonitor {
virObject parent;
int kq;
int watch;
bhyveConnPtr driver;
virDomainObjPtr vm;
};
static virClassPtr bhyveMonitorClass;
static void
bhyveMonitorDispose(void *obj)
{
bhyveMonitorPtr mon = obj;
VIR_FORCE_CLOSE(mon->kq);
virObjectUnref(mon->vm);
}
static int
bhyveMonitorOnceInit(void)
{
if (!VIR_CLASS_NEW(bhyveMonitor, virClassForObject()))
return -1;
return 0;
}
VIR_ONCE_GLOBAL_INIT(bhyveMonitor);
static void
bhyveMonitorIO(int watch, int kq, int events G_GNUC_UNUSED, void *opaque)
{
const struct timespec zerowait = { 0, 0 };
virDomainObjPtr vm = opaque;
bhyveDomainObjPrivatePtr priv = vm->privateData;
bhyveMonitorPtr mon = priv->mon;
bhyveMonitorPtr mon = opaque;
virDomainObjPtr vm = mon->vm;
bhyveConnPtr driver = mon->driver;
const char *name;
struct kevent kev;
int rc, status;
......@@ -82,60 +109,49 @@ bhyveMonitorIO(int watch, int kq, int events G_GNUC_UNUSED, void *opaque)
return;
}
name = vm->def->name;
status = kev.data;
if (WIFSIGNALED(status) && WCOREDUMP(status)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Guest %s got signal %d and crashed"),
vm->def->name,
WTERMSIG(status));
virBhyveProcessStop(mon->driver, vm,
VIR_DOMAIN_SHUTOFF_CRASHED);
name, WTERMSIG(status));
virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED);
} else if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == 0) {
/* 0 - reboot */
/* TODO: Implementing reboot is a little more complicated. */
VIR_INFO("Guest %s rebooted; destroying domain.",
vm->def->name);
virBhyveProcessStop(mon->driver, vm,
VIR_DOMAIN_SHUTOFF_SHUTDOWN);
VIR_INFO("Guest %s rebooted; destroying domain.", name);
virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
} else if (WEXITSTATUS(status) < 3) {
/* 1 - shutdown, 2 - halt, 3 - triple fault. others - error */
VIR_INFO("Guest %s shut itself down; destroying domain.",
vm->def->name);
virBhyveProcessStop(mon->driver, vm,
VIR_DOMAIN_SHUTOFF_SHUTDOWN);
VIR_INFO("Guest %s shut itself down; destroying domain.", name);
virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
} else {
VIR_INFO("Guest %s had an error and exited with status %d; destroying domain.",
vm->def->name, WEXITSTATUS(status));
virBhyveProcessStop(mon->driver, vm,
VIR_DOMAIN_SHUTOFF_UNKNOWN);
name, WEXITSTATUS(status));
virBhyveProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_UNKNOWN);
}
}
}
}
static void
bhyveMonitorRelease(void *opaque)
{
virDomainObjPtr vm = opaque;
bhyveDomainObjPrivatePtr priv = vm->privateData;
bhyveMonitorPtr mon = priv->mon;
VIR_FORCE_CLOSE(mon->kq);
VIR_FREE(mon);
}
bhyveMonitorPtr
bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver)
static bhyveMonitorPtr
bhyveMonitorOpenImpl(virDomainObjPtr vm, bhyveConnPtr driver)
{
bhyveMonitorPtr mon = NULL;
bhyveMonitorPtr mon;
struct kevent kev;
if (VIR_ALLOC(mon) < 0)
if (bhyveMonitorInitialize() < 0)
return NULL;
if (!(mon = virObjectNew(bhyveMonitorClass)))
return NULL;
mon->driver = driver;
virObjectRef(vm);
mon->vm = vm;
mon->kq = kqueue();
if (mon->kq < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
......@@ -150,14 +166,17 @@ bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver)
goto cleanup;
}
virObjectRef(mon);
mon->watch = virEventAddHandle(mon->kq,
VIR_EVENT_HANDLE_READABLE |
VIR_EVENT_HANDLE_ERROR |
VIR_EVENT_HANDLE_HANGUP,
bhyveMonitorIO,
vm,
bhyveMonitorRelease);
mon,
virObjectFreeCallback);
if (mon->watch < 0) {
VIR_DEBUG("failed to add event handle for mon %p", mon);
virObjectUnref(mon);
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to register monitor events"));
goto cleanup;
......@@ -166,18 +185,35 @@ bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver)
return mon;
cleanup:
bhyveMonitorRelease(mon);
bhyveMonitorClose(mon);
return NULL;
}
bhyveMonitorPtr
bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver)
{
bhyveMonitorPtr mon;
virObjectRef(vm);
mon = bhyveMonitorOpenImpl(vm, driver);
virObjectUnref(vm);
return mon;
}
void
bhyveMonitorClose(bhyveMonitorPtr mon)
{
if (mon == NULL)
return;
if (mon->watch > 0)
virEventRemoveHandle(mon->watch);
else
bhyveMonitorRelease(mon);
VIR_DEBUG("cleaning up bhyveMonitor %p", mon);
if (mon->watch < 0)
return;
virEventRemoveHandle(mon->watch);
mon->watch = -1;
virObjectUnref(mon);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册