diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-02-02 17:52:47 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-02-02 17:52:47 +0000 |
commit | 2723176e82ce1395f04b2d4328817b28eb499af3 (patch) | |
tree | 32eba048c41c33034617b72a725eaeb8f7dccf5d /sys/dev | |
parent | 848453065448cd57923a6f38a376e35ad6ee353b (diff) |
A few reliability improvements in the power management interface
Nathanael Rensen <nathanael at list ! polymorpheus ! com> came up with
a few improvements to the event watcher and power management interface,
namely:
o Make sure to put our watcher on a list before issuing an XS_WATCH
command since Xen will raise the event right after it's been set up.
o The first time xen_control is called the "control/shutdown" node
may not exist, so skip printing the error message in this case.
o Acknowledge requests by writing back an empty string.
o log(9) reboot and halt requests like vmt(4) does.
Huge thanks!
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pv/xen.c | 41 | ||||
-rw-r--r-- | sys/dev/pv/xenstore.c | 17 | ||||
-rw-r--r-- | sys/dev/pv/xenvar.h | 4 |
3 files changed, 43 insertions, 19 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c index 8aa7565cba8..5770d897ceb 100644 --- a/sys/dev/pv/xen.c +++ b/sys/dev/pv/xen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xen.c,v 1.48 2016/01/29 19:12:26 mikeb Exp $ */ +/* $OpenBSD: xen.c,v 1.49 2016/02/02 17:52:46 mikeb Exp $ */ /* * Copyright (c) 2015 Mike Belopuhov @@ -25,6 +25,7 @@ #include <sys/kernel.h> #include <sys/device.h> #include <sys/task.h> +#include <sys/syslog.h> #include <machine/bus.h> #include <machine/cpu.h> @@ -34,6 +35,8 @@ #include <machine/i82489var.h> +#include <dev/rndvar.h> + #include <dev/pv/pvvar.h> #include <dev/pv/pvreg.h> #include <dev/pv/xenreg.h> @@ -193,34 +196,48 @@ xen_control(void *arg) struct xen_softc *sc = arg; struct xs_transaction xst; char action[128]; + int error; memset(&xst, 0, sizeof(xst)); xst.xst_id = 0; xst.xst_sc = sc->sc_xs; - if (xs_getprop(sc, "control", "shutdown", action, sizeof(action))) { - printf("%s: failed to process control event\n", - sc->sc_dev.dv_xname); + error = xs_getprop(sc, "control", "shutdown", action, sizeof(action)); + if (error) { + if (error != ENOENT) + printf("%s: failed to process control event\n", + sc->sc_dev.dv_xname); return; } if (strlen(action) == 0) return; + /* Acknowledge the event */ + xs_setprop(sc, "control", "shutdown", "", 0); + if (strcmp(action, "halt") == 0 || strcmp(action, "poweroff") == 0) { extern int allowpowerdown; - if (allowpowerdown == 1) { - allowpowerdown = 0; - prsignal(initprocess, SIGUSR2); - } + if (allowpowerdown == 0) + return; + + suspend_randomness(); + + log(LOG_KERN | LOG_NOTICE, "Shutting down in response to " + "request from Xen host\n"); + prsignal(initprocess, SIGUSR2); } else if (strcmp(action, "reboot") == 0) { extern int allowpowerdown; - if (allowpowerdown == 1) { - allowpowerdown = 0; - prsignal(initprocess, SIGINT); - } + if (allowpowerdown == 0) + return; + + suspend_randomness(); + + log(LOG_KERN | LOG_NOTICE, "Rebooting in response to request " + "from Xen host\n"); + prsignal(initprocess, SIGINT); } else if (strcmp(action, "crash") == 0) { panic("xen told us to do this"); } else if (strcmp(action, "suspend") == 0) { diff --git a/sys/dev/pv/xenstore.c b/sys/dev/pv/xenstore.c index c1262cf9590..95b1fdc7fa2 100644 --- a/sys/dev/pv/xenstore.c +++ b/sys/dev/pv/xenstore.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xenstore.c,v 1.24 2016/01/29 19:04:30 mikeb Exp $ */ +/* $OpenBSD: xenstore.c,v 1.25 2016/02/02 17:52:46 mikeb Exp $ */ /* * Copyright (c) 2015 Mike Belopuhov @@ -850,15 +850,22 @@ xs_watch(struct xen_softc *sc, const char *path, const char *property, iov.iov_len = sizeof(xsw->xsw_token); iov_cnt = 1; + /* + * xs_watches must be prepared pre-emptively because a xenstore + * event is raised immediately after a watch is established. + */ + mtx_enter(&xs->xs_watchlck); + TAILQ_INSERT_TAIL(&xs->xs_watches, xsw, xsw_entry); + mtx_leave(&xs->xs_watchlck); + if ((error = xs_cmd(&xst, XS_WATCH, key, &iovp, &iov_cnt)) != 0) { + mtx_enter(&xs->xs_watchlck); + TAILQ_REMOVE(&xs->xs_watches, xsw, xsw_entry); + mtx_leave(&xs->xs_watchlck); free(xsw, M_DEVBUF, sizeof(*xsw)); return (error); } - mtx_enter(&xs->xs_watchlck); - TAILQ_INSERT_TAIL(&xs->xs_watches, xsw, xsw_entry); - mtx_leave(&xs->xs_watchlck); - return (0); } diff --git a/sys/dev/pv/xenvar.h b/sys/dev/pv/xenvar.h index 29c013d2ad0..34f381b78a7 100644 --- a/sys/dev/pv/xenvar.h +++ b/sys/dev/pv/xenvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xenvar.h,v 1.28 2016/01/29 19:12:26 mikeb Exp $ */ +/* $OpenBSD: xenvar.h,v 1.29 2016/02/02 17:52:46 mikeb Exp $ */ /* * Copyright (c) 2015 Mike Belopuhov @@ -19,7 +19,7 @@ #ifndef _XENVAR_H_ #define _XENVAR_H_ -#define XEN_DEBUG +/* #define XEN_DEBUG */ #ifdef XEN_DEBUG #define DPRINTF(x...) printf(x) |