Commit 0b7fe5ae authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-10-02' into staging



QAPI patches for 2017-10-02

# gpg: Signature made Mon 02 Oct 2017 12:09:32 BST
# gpg:                using RSA key 0x3870B400EB918653
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>"
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>"
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-qapi-2017-10-02:
  watchdog: Allow setting action on the fly
  watchdog.h: Drop local redefinition of actions enum
  qapi: Rename WatchdogExpirationAction enum

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 2c948221 f0df84c6
Loading
Loading
Loading
Loading
+33 −32
Original line number Diff line number Diff line
@@ -29,8 +29,9 @@
#include "qapi-event.h"
#include "hw/nmi.h"
#include "qemu/help_option.h"
#include "qmp-commands.h"

static int watchdog_action = WDT_RESET;
static WatchdogAction watchdog_action = WATCHDOG_ACTION_RESET;
static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;

void watchdog_add_model(WatchdogTimerModel *model)
@@ -77,27 +78,19 @@ int select_watchdog(const char *p)

int select_watchdog_action(const char *p)
{
    if (strcasecmp(p, "reset") == 0)
        watchdog_action = WDT_RESET;
    else if (strcasecmp(p, "shutdown") == 0)
        watchdog_action = WDT_SHUTDOWN;
    else if (strcasecmp(p, "poweroff") == 0)
        watchdog_action = WDT_POWEROFF;
    else if (strcasecmp(p, "pause") == 0)
        watchdog_action = WDT_PAUSE;
    else if (strcasecmp(p, "debug") == 0)
        watchdog_action = WDT_DEBUG;
    else if (strcasecmp(p, "none") == 0)
        watchdog_action = WDT_NONE;
    else if (strcasecmp(p, "inject-nmi") == 0)
        watchdog_action = WDT_NMI;
    else
        return -1;
    int action;
    char *qapi_value;

    qapi_value = g_ascii_strdown(p, -1);
    action = qapi_enum_parse(&WatchdogAction_lookup, qapi_value, -1, NULL);
    g_free(qapi_value);
    if (action < 0)
        return -1;
    qmp_watchdog_set_action(action, &error_abort);
    return 0;
}

int get_watchdog_action(void)
WatchdogAction get_watchdog_action(void)
{
    return watchdog_action;
}
@@ -108,42 +101,50 @@ int get_watchdog_action(void)
void watchdog_perform_action(void)
{
    switch (watchdog_action) {
    case WDT_RESET:             /* same as 'system_reset' in monitor */
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, &error_abort);
    case WATCHDOG_ACTION_RESET:     /* same as 'system_reset' in monitor */
        qapi_event_send_watchdog(WATCHDOG_ACTION_RESET, &error_abort);
        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
        break;

    case WDT_SHUTDOWN:          /* same as 'system_powerdown' in monitor */
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_SHUTDOWN, &error_abort);
    case WATCHDOG_ACTION_SHUTDOWN:  /* same as 'system_powerdown' in monitor */
        qapi_event_send_watchdog(WATCHDOG_ACTION_SHUTDOWN, &error_abort);
        qemu_system_powerdown_request();
        break;

    case WDT_POWEROFF:          /* same as 'quit' command in monitor */
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_POWEROFF, &error_abort);
    case WATCHDOG_ACTION_POWEROFF:  /* same as 'quit' command in monitor */
        qapi_event_send_watchdog(WATCHDOG_ACTION_POWEROFF, &error_abort);
        exit(0);

    case WDT_PAUSE:             /* same as 'stop' command in monitor */
    case WATCHDOG_ACTION_PAUSE:     /* same as 'stop' command in monitor */
        /* In a timer callback, when vm_stop calls qemu_clock_enable
         * you would get a deadlock.  Bypass the problem.
         */
        qemu_system_vmstop_request_prepare();
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, &error_abort);
        qapi_event_send_watchdog(WATCHDOG_ACTION_PAUSE, &error_abort);
        qemu_system_vmstop_request(RUN_STATE_WATCHDOG);
        break;

    case WDT_DEBUG:
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, &error_abort);
    case WATCHDOG_ACTION_DEBUG:
        qapi_event_send_watchdog(WATCHDOG_ACTION_DEBUG, &error_abort);
        fprintf(stderr, "watchdog: timer fired\n");
        break;

    case WDT_NONE:
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, &error_abort);
    case WATCHDOG_ACTION_NONE:
        qapi_event_send_watchdog(WATCHDOG_ACTION_NONE, &error_abort);
        break;

    case WDT_NMI:
        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_INJECT_NMI,
    case WATCHDOG_ACTION_INJECT_NMI:
        qapi_event_send_watchdog(WATCHDOG_ACTION_INJECT_NMI,
                                 &error_abort);
        nmi_monitor_handle(0, NULL);
        break;

    default:
        assert(0);
    }
}

void qmp_watchdog_set_action(WatchdogAction action, Error **errp)
{
    watchdog_action = action;
}
+3 −3
Original line number Diff line number Diff line
@@ -57,9 +57,9 @@ static void diag288_timer_expired(void *dev)
     * the BQL; reset before triggering the action to avoid races with
     * diag288 instructions. */
    switch (get_watchdog_action()) {
    case WDT_DEBUG:
    case WDT_NONE:
    case WDT_PAUSE:
    case WATCHDOG_ACTION_DEBUG:
    case WATCHDOG_ACTION_NONE:
    case WATCHDOG_ACTION_PAUSE:
        break;
    default:
        wdt_diag288_reset(dev);
+2 −10
Original line number Diff line number Diff line
@@ -23,15 +23,7 @@
#define QEMU_WATCHDOG_H

#include "qemu/queue.h"

/* Possible values for action parameter. */
#define WDT_RESET        1      /* Hard reset. */
#define WDT_SHUTDOWN     2      /* Shutdown. */
#define WDT_POWEROFF     3      /* Quit. */
#define WDT_PAUSE        4      /* Pause. */
#define WDT_DEBUG        5      /* Prints a message and continues running. */
#define WDT_NONE         6      /* Do nothing. */
#define WDT_NMI          7      /* Inject nmi into the guest. */
#include "qapi-types.h"

struct WatchdogTimerModel {
    QLIST_ENTRY(WatchdogTimerModel) entry;
@@ -46,7 +38,7 @@ typedef struct WatchdogTimerModel WatchdogTimerModel;
/* in hw/watchdog.c */
int select_watchdog(const char *p);
int select_watchdog_action(const char *action);
int get_watchdog_action(void);
WatchdogAction get_watchdog_action(void);
void watchdog_add_model(WatchdogTimerModel *model);
void watchdog_perform_action(void);

+2 −2
Original line number Diff line number Diff line
@@ -3541,8 +3541,8 @@ void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str)
        return;
    }
    readline_set_completion_index(rs, strlen(str));
    for (i = 0; i < WATCHDOG_EXPIRATION_ACTION__MAX; i++) {
        add_completion_option(rs, str, WatchdogExpirationAction_str(i));
    for (i = 0; i < WATCHDOG_ACTION__MAX; i++) {
        add_completion_option(rs, str, WatchdogAction_str(i));
    }
}

+9 −0
Original line number Diff line number Diff line
@@ -3191,3 +3191,12 @@
# Since 2.9
##
{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }

##
# @watchdog-set-action:
#
# Set watchdog action
#
# Since: 2.11
##
{ 'command': 'watchdog-set-action', 'data' : {'action': 'WatchdogAction'} }
Loading