diff options
| author | johnlev <none@none> | 2008-05-21 16:00:05 -0700 |
|---|---|---|
| committer | johnlev <none@none> | 2008-05-21 16:00:05 -0700 |
| commit | c48ac12eb805b96b1b8d7582c4168b4e4fa56865 (patch) | |
| tree | 89f6e64352bda38778f0899dc7820980ab185bde /usr/src/uts | |
| parent | b08d8a121e3928c888b68a3e56445554ced82733 (diff) | |
| download | illumos-joyent-c48ac12eb805b96b1b8d7582c4168b4e4fa56865.tar.gz | |
6677804 Can't shutdown Solaris HVM guest with PV drivers
Diffstat (limited to 'usr/src/uts')
| -rw-r--r-- | usr/src/uts/common/sys/uadmin.h | 3 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/i86hvm/io/xpv/xpv_support.c | 63 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/os/machdep.c | 10 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/sys/machsystm.h | 4 | ||||
| -rw-r--r-- | usr/src/uts/i86xpv/os/xen_machdep.c | 59 |
5 files changed, 67 insertions, 72 deletions
diff --git a/usr/src/uts/common/sys/uadmin.h b/usr/src/uts/common/sys/uadmin.h index e307462896..2bf889c9b7 100644 --- a/usr/src/uts/common/sys/uadmin.h +++ b/usr/src/uts/common/sys/uadmin.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -50,6 +50,7 @@ extern "C" { #define A_SWAPCTL 16 /* 17-21 reserved for obsolete interface */ +#define AD_UNKNOWN -1 /* no method */ #define AD_HALT 0 /* halt the processor */ #define AD_BOOT 1 /* multi-user reboot */ #define AD_IBOOT 2 /* multi-user reboot, ask for name of file */ diff --git a/usr/src/uts/i86pc/i86hvm/io/xpv/xpv_support.c b/usr/src/uts/i86pc/i86hvm/io/xpv/xpv_support.c index f5de99a175..b7122d09a1 100644 --- a/usr/src/uts/i86pc/i86hvm/io/xpv/xpv_support.c +++ b/usr/src/uts/i86pc/i86hvm/io/xpv/xpv_support.c @@ -327,13 +327,6 @@ taskq_t *xen_shutdown_tq; #define SHUTDOWN_TIMEOUT_SECS (60 * 5) -static const char *cmd_strings[SHUTDOWN_MAX] = { - "poweroff", - "reboot", - "suspend", - "halt" -}; - int xen_suspend_devices(dev_info_t *dip) { @@ -588,11 +581,8 @@ xen_dirty_shutdown(void *arg) static void xen_shutdown(void *arg) { - nvlist_t *attr_list = NULL; - sysevent_t *event = NULL; - sysevent_id_t eid; int cmd = (uintptr_t)arg; - int err; + proc_t *initpp; ASSERT(cmd > SHUTDOWN_INVALID && cmd < SHUTDOWN_MAX); @@ -601,38 +591,37 @@ xen_shutdown(void *arg) return; } - err = nvlist_alloc(&attr_list, NV_UNIQUE_NAME, KM_SLEEP); - if (err != DDI_SUCCESS) - goto failure; - - err = nvlist_add_string(attr_list, "shutdown", cmd_strings[cmd]); - if (err != DDI_SUCCESS) - goto failure; - - if ((event = sysevent_alloc("EC_xpvsys", "control", "SUNW:kern:xpv", - SE_SLEEP)) == NULL) - goto failure; - (void) sysevent_attach_attributes(event, - (sysevent_attr_list_t *)attr_list); + switch (cmd) { + case SHUTDOWN_POWEROFF: + force_shutdown_method = AD_POWEROFF; + break; + case SHUTDOWN_HALT: + force_shutdown_method = AD_HALT; + break; + case SHUTDOWN_REBOOT: + force_shutdown_method = AD_BOOT; + break; + } - err = log_sysevent(event, SE_SLEEP, &eid); - sysevent_detach_attributes(event); - sysevent_free(event); + /* + * If we're still booting and init(1) isn't set up yet, simply halt. + */ + mutex_enter(&pidlock); + initpp = prfind(P_INITPID); + mutex_exit(&pidlock); + if (initpp == NULL) { + extern void halt(char *); + halt("Power off the System"); /* just in case */ + } - if (err != 0) - goto failure; + /* + * else, graceful shutdown with inittab and all getting involved + */ + psignal(initpp, SIGPWR); (void) timeout(xen_dirty_shutdown, arg, SHUTDOWN_TIMEOUT_SECS * drv_usectohz(MICROSEC)); - - nvlist_free(attr_list); - return; - -failure: - if (attr_list != NULL) - nvlist_free(attr_list); - xen_dirty_shutdown(arg); } /*ARGSUSED*/ diff --git a/usr/src/uts/i86pc/os/machdep.c b/usr/src/uts/i86pc/os/machdep.c index 30861022a6..d39fde3140 100644 --- a/usr/src/uts/i86pc/os/machdep.c +++ b/usr/src/uts/i86pc/os/machdep.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -130,6 +130,11 @@ extern void audit_enterprom(int); extern void audit_exitprom(int); /* + * Occassionally the kernel knows better whether to power-off or reboot. + */ +int force_shutdown_method = AD_UNKNOWN; + +/* * The panicbuf array is used to record messages and state: */ char panicbuf[PANICBUFSIZE]; @@ -174,6 +179,9 @@ mdboot(int cmd, int fcn, char *mdep, boolean_t invoke_cb) affinity_set(CPU_CURRENT); } + if (force_shutdown_method != AD_UNKNOWN) + fcn = force_shutdown_method; + /* * XXX - rconsvp is set to NULL to ensure that output messages * are sent to the underlying "hardware" device using the diff --git a/usr/src/uts/i86pc/sys/machsystm.h b/usr/src/uts/i86pc/sys/machsystm.h index 7f5cb22437..8f0036af91 100644 --- a/usr/src/uts/i86pc/sys/machsystm.h +++ b/usr/src/uts/i86pc/sys/machsystm.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -136,6 +136,8 @@ extern page_t *page_get_physical(uintptr_t); extern int linear_pc(struct regs *rp, proc_t *p, caddr_t *linearp); extern int dtrace_linear_pc(struct regs *rp, proc_t *p, caddr_t *linearp); +extern int force_shutdown_method; + #ifdef __xpv #include <sys/xen_mmu.h> extern page_t *page_get_high_mfn(mfn_t); diff --git a/usr/src/uts/i86xpv/os/xen_machdep.c b/usr/src/uts/i86xpv/os/xen_machdep.c index 2ddfc1841f..4f832a3eaa 100644 --- a/usr/src/uts/i86xpv/os/xen_machdep.c +++ b/usr/src/uts/i86xpv/os/xen_machdep.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -756,11 +756,8 @@ xen_dirty_shutdown(void *arg) static void xen_shutdown(void *arg) { - nvlist_t *attr_list = NULL; - sysevent_t *event = NULL; - sysevent_id_t eid; int cmd = (uintptr_t)arg; - int err; + proc_t *initpp; ASSERT(cmd > SHUTDOWN_INVALID && cmd < SHUTDOWN_MAX); @@ -769,38 +766,36 @@ xen_shutdown(void *arg) return; } - err = nvlist_alloc(&attr_list, NV_UNIQUE_NAME, KM_SLEEP); - if (err != DDI_SUCCESS) - goto failure; - - err = nvlist_add_string(attr_list, "shutdown", cmd_strings[cmd]); - if (err != DDI_SUCCESS) - goto failure; - - if ((event = sysevent_alloc("EC_xpvsys", "control", "SUNW:kern:xpv", - SE_SLEEP)) == NULL) - goto failure; - (void) sysevent_attach_attributes(event, - (sysevent_attr_list_t *)attr_list); - - err = log_sysevent(event, SE_SLEEP, &eid); + switch (cmd) { + case SHUTDOWN_POWEROFF: + force_shutdown_method = AD_POWEROFF; + break; + case SHUTDOWN_HALT: + force_shutdown_method = AD_HALT; + break; + case SHUTDOWN_REBOOT: + force_shutdown_method = AD_BOOT; + break; + } - sysevent_detach_attributes(event); - sysevent_free(event); + /* + * If we're still booting and init(1) isn't set up yet, simply halt. + */ + mutex_enter(&pidlock); + initpp = prfind(P_INITPID); + mutex_exit(&pidlock); + if (initpp == NULL) { + extern void halt(char *); + halt("Power off the System"); /* just in case */ + } - if (err != 0) - goto failure; + /* + * else, graceful shutdown with inittab and all getting involved + */ + psignal(initpp, SIGPWR); (void) timeout(xen_dirty_shutdown, arg, SHUTDOWN_TIMEOUT_SECS * drv_usectohz(MICROSEC)); - - nvlist_free(attr_list); - return; - -failure: - if (attr_list != NULL) - nvlist_free(attr_list); - xen_dirty_shutdown(arg); } /*ARGSUSED*/ |
