19dd986ccSRichard W.M. Jones /* 29dd986ccSRichard W.M. Jones * Virtual hardware watchdog. 39dd986ccSRichard W.M. Jones * 49dd986ccSRichard W.M. Jones * Copyright (C) 2009 Red Hat Inc. 59dd986ccSRichard W.M. Jones * 69dd986ccSRichard W.M. Jones * This program is free software; you can redistribute it and/or 79dd986ccSRichard W.M. Jones * modify it under the terms of the GNU General Public License 89dd986ccSRichard W.M. Jones * as published by the Free Software Foundation; either version 2 99dd986ccSRichard W.M. Jones * of the License, or (at your option) any later version. 109dd986ccSRichard W.M. Jones * 119dd986ccSRichard W.M. Jones * This program is distributed in the hope that it will be useful, 129dd986ccSRichard W.M. Jones * but WITHOUT ANY WARRANTY; without even the implied warranty of 139dd986ccSRichard W.M. Jones * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 149dd986ccSRichard W.M. Jones * GNU General Public License for more details. 159dd986ccSRichard W.M. Jones * 169dd986ccSRichard W.M. Jones * You should have received a copy of the GNU General Public License 178167ee88SBlue Swirl * along with this program; if not, see <http://www.gnu.org/licenses/>. 189dd986ccSRichard W.M. Jones * 199dd986ccSRichard W.M. Jones * By Richard W.M. Jones (rjones@redhat.com). 209dd986ccSRichard W.M. Jones */ 219dd986ccSRichard W.M. Jones 220430891cSPeter Maydell #include "qemu/osdep.h" 231de7afc9SPaolo Bonzini #include "qemu/option.h" 241de7afc9SPaolo Bonzini #include "qemu/config-file.h" 251de7afc9SPaolo Bonzini #include "qemu/queue.h" 26e688df6bSMarkus Armbruster #include "qapi/error.h" 27112ed241SMarkus Armbruster #include "qapi/qapi-commands-run-state.h" 289af23989SMarkus Armbruster #include "qapi/qapi-events-run-state.h" 2954d31236SMarkus Armbruster #include "sysemu/runstate.h" 300d09e41aSPaolo Bonzini #include "sysemu/watchdog.h" 31795dc6e4SMao Chuan Li #include "hw/nmi.h" 32f348b6d1SVeronia Bahaa #include "qemu/help_option.h" 33*6f10a29eSDaniel P. Berrangé #include "trace.h" 349dd986ccSRichard W.M. Jones 354c7f4426SMichal Privoznik static WatchdogAction watchdog_action = WATCHDOG_ACTION_RESET; 369dd986ccSRichard W.M. Jones 374c7f4426SMichal Privoznik WatchdogAction get_watchdog_action(void) 380d035b6cSBo Tu { 390d035b6cSBo Tu return watchdog_action; 400d035b6cSBo Tu } 410d035b6cSBo Tu 429dd986ccSRichard W.M. Jones /* This actually performs the "action" once a watchdog has expired, 439dd986ccSRichard W.M. Jones * ie. reboot, shutdown, exit, etc. 449dd986ccSRichard W.M. Jones */ 459dd986ccSRichard W.M. Jones void watchdog_perform_action(void) 469dd986ccSRichard W.M. Jones { 47*6f10a29eSDaniel P. Berrangé trace_watchdog_perform_action(watchdog_action); 48*6f10a29eSDaniel P. Berrangé 499dd986ccSRichard W.M. Jones switch (watchdog_action) { 504c7f4426SMichal Privoznik case WATCHDOG_ACTION_RESET: /* same as 'system_reset' in monitor */ 513ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_RESET); 52cf83f140SEric Blake qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 539dd986ccSRichard W.M. Jones break; 549dd986ccSRichard W.M. Jones 554c7f4426SMichal Privoznik case WATCHDOG_ACTION_SHUTDOWN: /* same as 'system_powerdown' in monitor */ 563ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_SHUTDOWN); 579dd986ccSRichard W.M. Jones qemu_system_powerdown_request(); 589dd986ccSRichard W.M. Jones break; 599dd986ccSRichard W.M. Jones 604c7f4426SMichal Privoznik case WATCHDOG_ACTION_POWEROFF: /* same as 'quit' command in monitor */ 613ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_POWEROFF); 629dd986ccSRichard W.M. Jones exit(0); 639dd986ccSRichard W.M. Jones 644c7f4426SMichal Privoznik case WATCHDOG_ACTION_PAUSE: /* same as 'stop' command in monitor */ 6530e5210aSPaolo Bonzini /* In a timer callback, when vm_stop calls qemu_clock_enable 6630e5210aSPaolo Bonzini * you would get a deadlock. Bypass the problem. 6730e5210aSPaolo Bonzini */ 6830e5210aSPaolo Bonzini qemu_system_vmstop_request_prepare(); 693ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_PAUSE); 7030e5210aSPaolo Bonzini qemu_system_vmstop_request(RUN_STATE_WATCHDOG); 719dd986ccSRichard W.M. Jones break; 729dd986ccSRichard W.M. Jones 734c7f4426SMichal Privoznik case WATCHDOG_ACTION_DEBUG: 743ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_DEBUG); 759dd986ccSRichard W.M. Jones fprintf(stderr, "watchdog: timer fired\n"); 769dd986ccSRichard W.M. Jones break; 779dd986ccSRichard W.M. Jones 784c7f4426SMichal Privoznik case WATCHDOG_ACTION_NONE: 793ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_NONE); 809dd986ccSRichard W.M. Jones break; 81795dc6e4SMao Chuan Li 824c7f4426SMichal Privoznik case WATCHDOG_ACTION_INJECT_NMI: 833ab72385SPeter Xu qapi_event_send_watchdog(WATCHDOG_ACTION_INJECT_NMI); 84f7e981f2SBandan Das nmi_monitor_handle(0, NULL); 85795dc6e4SMao Chuan Li break; 864c7f4426SMichal Privoznik 874c7f4426SMichal Privoznik default: 884c7f4426SMichal Privoznik assert(0); 899dd986ccSRichard W.M. Jones } 909dd986ccSRichard W.M. Jones } 91f0df84c6SMichal Privoznik 92f0df84c6SMichal Privoznik void qmp_watchdog_set_action(WatchdogAction action, Error **errp) 93f0df84c6SMichal Privoznik { 94f0df84c6SMichal Privoznik watchdog_action = action; 95*6f10a29eSDaniel P. Berrangé trace_watchdog_set_action(watchdog_action); 96f0df84c6SMichal Privoznik } 97