[S390] sclp: undo quiesce handler override on resume
In a system where the ctrl-alt-del init action initiated by signal quiesce suspends the machine the quiesce handler override for _machine_restart, _machine_halt and _machine_power_off needs to be undone, otherwise the override is still present in the resumed system. The next shutdown would then load the quiesce state psw instead of performing the correct shutdown action. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
b89031e087
commit
8b94c1ed4d
|
@ -20,9 +20,12 @@
|
|||
|
||||
#include "sclp.h"
|
||||
|
||||
static void (*old_machine_restart)(char *);
|
||||
static void (*old_machine_halt)(void);
|
||||
static void (*old_machine_power_off)(void);
|
||||
|
||||
/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
|
||||
static void
|
||||
do_machine_quiesce(void)
|
||||
static void do_machine_quiesce(void)
|
||||
{
|
||||
psw_t quiesce_psw;
|
||||
|
||||
|
@ -33,23 +36,48 @@ do_machine_quiesce(void)
|
|||
}
|
||||
|
||||
/* Handler for quiesce event. Start shutdown procedure. */
|
||||
static void
|
||||
sclp_quiesce_handler(struct evbuf_header *evbuf)
|
||||
static void sclp_quiesce_handler(struct evbuf_header *evbuf)
|
||||
{
|
||||
_machine_restart = (void *) do_machine_quiesce;
|
||||
_machine_halt = do_machine_quiesce;
|
||||
_machine_power_off = do_machine_quiesce;
|
||||
if (_machine_restart != (void *) do_machine_quiesce) {
|
||||
old_machine_restart = _machine_restart;
|
||||
old_machine_halt = _machine_halt;
|
||||
old_machine_power_off = _machine_power_off;
|
||||
_machine_restart = (void *) do_machine_quiesce;
|
||||
_machine_halt = do_machine_quiesce;
|
||||
_machine_power_off = do_machine_quiesce;
|
||||
}
|
||||
ctrl_alt_del();
|
||||
}
|
||||
|
||||
/* Undo machine restart/halt/power_off modification on resume */
|
||||
static void sclp_quiesce_pm_event(struct sclp_register *reg,
|
||||
enum sclp_pm_event sclp_pm_event)
|
||||
{
|
||||
switch (sclp_pm_event) {
|
||||
case SCLP_PM_EVENT_RESTORE:
|
||||
if (old_machine_restart) {
|
||||
_machine_restart = old_machine_restart;
|
||||
_machine_halt = old_machine_halt;
|
||||
_machine_power_off = old_machine_power_off;
|
||||
old_machine_restart = NULL;
|
||||
old_machine_halt = NULL;
|
||||
old_machine_power_off = NULL;
|
||||
}
|
||||
break;
|
||||
case SCLP_PM_EVENT_FREEZE:
|
||||
case SCLP_PM_EVENT_THAW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct sclp_register sclp_quiesce_event = {
|
||||
.receive_mask = EVTYP_SIGQUIESCE_MASK,
|
||||
.receiver_fn = sclp_quiesce_handler
|
||||
.receiver_fn = sclp_quiesce_handler,
|
||||
.pm_event_fn = sclp_quiesce_pm_event
|
||||
};
|
||||
|
||||
/* Initialize quiesce driver. */
|
||||
static int __init
|
||||
sclp_quiesce_init(void)
|
||||
static int __init sclp_quiesce_init(void)
|
||||
{
|
||||
return sclp_register(&sclp_quiesce_event);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue