On 14.11.2014 17:03, Conrad Meyer wrote: > Reboot requires more sophistication and is left as a future work item -- > but at least part of the plumbing is in place. > --- > Looking for feedback. I'm pretty unfamiliar with libvirt; maybe this isn't > quite the right way to do this. Sorry. If you want me to rework it in some way, > just let me know. > > I tried to model this off of DrvQEMU, which I knew to support this behavior. > > Reboot should probably be processed on a threadpool thread outside of the event > loop, so I omitted it for now. > > P.S., the 'read-non-seekable' check test seems to just hang forever on FreeBSD. > I haven't dug into it, but POSIX FIFO behavior is pretty weird. > --- > src/Makefile.am | 2 + > src/bhyve/bhyve_monitor.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++ > src/bhyve/bhyve_monitor.h | 36 +++++++++ > src/bhyve/bhyve_process.c | 14 +++- > 4 files changed, 233 insertions(+), 3 deletions(-) > create mode 100644 src/bhyve/bhyve_monitor.c > create mode 100644 src/bhyve/bhyve_monitor.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index d8fe624..b6c1701 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -833,6 +833,8 @@ BHYVE_DRIVER_SOURCES = \ > bhyve/bhyve_domain.h \ > bhyve/bhyve_driver.h \ > bhyve/bhyve_driver.c \ > + bhyve/bhyve_monitor.c \ > + bhyve/bhyve_monitor.h \ > bhyve/bhyve_process.c \ > bhyve/bhyve_process.h \ > bhyve/bhyve_utils.h \ > diff --git a/src/bhyve/bhyve_monitor.c b/src/bhyve/bhyve_monitor.c > new file mode 100644 > index 0000000..cd3cf6e > --- /dev/null > +++ b/src/bhyve/bhyve_monitor.c > @@ -0,0 +1,184 @@ > +/* > + * bhyve_monitor.c: Tear-down or reboot bhyve domains on guest shutdown > + * > + * Copyright (C) 2014 Conrad Meyer > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library. If not, see > + * <http://www.gnu.org/licenses/>. > + * > + * Author: Conrad Meyer <cse.cem@xxxxxxxxx> > + */ > + > +#include <config.h> > + > +#include <sys/types.h> > +#include <sys/event.h> > +#include <sys/time.h> > +#include <sys/wait.h> > + > +#include "bhyve_monitor.h" > +#include "bhyve_process.h" > +#include "viralloc.h" > +#include "virerror.h" > +#include "virfile.h" > +#include "virlog.h" > + > +#define VIR_FROM_THIS VIR_FROM_BHYVE > + > +VIR_LOG_INIT("bhyve.bhyve_monitor"); > + > +struct _bhyveMonitor { > + int kq; > + int watch; > + virDomainObjPtr vm; > + bhyveConnPtr driver; > +}; > + > +static void > +bhyveMonitorIO(int watch, int kq, int events ATTRIBUTE_UNUSED, void *opaque) > +{ > + const struct timespec zerowait = {}; > + bhyveMonitorPtr mon = opaque; > + struct kevent kev; > + int rc, status; > + > + if (watch != mon->watch || kq != mon->kq) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("event from unexpected fd %d!=%d / watch %d!=%d"), > + mon->kq, kq, mon->watch, watch); > + return; > + } > + > + rc = kevent(kq, NULL, 0, &kev, 1, &zerowait); > + if (rc < 0) { > + virReportSystemError(errno, "%s", _("Unable to query kqueue")); > + return; > + } > + > + if (rc == 0) > + return; > + > + if ((kev.flags & EV_ERROR) != 0) { > + virReportSystemError(kev.data, "%s", _("Unable to query kqueue")); > + return; > + } > + > + if (kev.filter == EVFILT_PROC && (kev.fflags & NOTE_EXIT) != 0) { > + if ((pid_t)kev.ident != mon->vm->pid) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("event from unexpected proc %ju!=%ju"), > + (uintmax_t)mon->vm->pid, (uintmax_t)kev.ident); > + return; > + } > + > + status = kev.data; > + if (WIFSIGNALED(status) && WCOREDUMP(status)) { > + VIR_ERROR("Guest %s got signal %d and crashed", mon->vm->def->name, > + WTERMSIG(status)); This needs to be virReportError(). And since you're doing gettext translations _() you need to change po/POTFILES.in too. > + virBhyveProcessStop(mon->driver, mon->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.", > + mon->vm->def->name); > + virBhyveProcessStop(mon->driver, mon->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.", > + mon->vm->def->name); > + virBhyveProcessStop(mon->driver, mon->vm, > + VIR_DOMAIN_SHUTOFF_SHUTDOWN); > + } else { > + VIR_INFO("Guest %s had an error and exited with status %d; destroying domain.", > + mon->vm->def->name, WEXITSTATUS(status)); > + virBhyveProcessStop(mon->driver, mon->vm, > + VIR_DOMAIN_SHUTOFF_UNKNOWN); > + } > + } > + } > +} ACKed with this squashed in: diff --git a/po/POTFILES.in b/po/POTFILES.in index f17b35f..d07b75a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -11,6 +11,7 @@ src/access/viraccessmanager.c src/bhyve/bhyve_command.c src/bhyve/bhyve_device.c src/bhyve/bhyve_driver.c +src/bhyve/bhyve_monitor.c src/bhyve/bhyve_process.c src/conf/capabilities.c src/conf/cpu_conf.c diff --git a/src/bhyve/bhyve_monitor.c b/src/bhyve/bhyve_monitor.c index cd3cf6e..7f19c6e 100644 --- a/src/bhyve/bhyve_monitor.c +++ b/src/bhyve/bhyve_monitor.c @@ -84,8 +84,10 @@ bhyveMonitorIO(int watch, int kq, int events ATTRIBUTE_UNUSED, void *opaque) status = kev.data; if (WIFSIGNALED(status) && WCOREDUMP(status)) { - VIR_ERROR("Guest %s got signal %d and crashed", mon->vm->def->name, - WTERMSIG(status)); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Guest %s got signal %d and crashed"), + mon->vm->def->name, + WTERMSIG(status)); virBhyveProcessStop(mon->driver, mon->vm, VIR_DOMAIN_SHUTOFF_CRASHED); } else if (WIFEXITED(status)) { Fixed and pushed. Michal -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list