From patchwork Tue Sep 5 13:22:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Privoznik X-Patchwork-Id: 9939015 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DEF13600CB for ; Tue, 5 Sep 2017 13:24:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D060B28976 for ; Tue, 5 Sep 2017 13:24:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C51A02897C; Tue, 5 Sep 2017 13:24:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2ACCA28976 for ; Tue, 5 Sep 2017 13:24:52 +0000 (UTC) Received: from localhost ([::1]:58931 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpDqV-0007T8-E5 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 05 Sep 2017 09:24:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48449) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpDo9-0006Jj-Do for qemu-devel@nongnu.org; Tue, 05 Sep 2017 09:22:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpDnz-0007WA-J7 for qemu-devel@nongnu.org; Tue, 05 Sep 2017 09:22:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34782) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dpDnz-0007VK-AT for qemu-devel@nongnu.org; Tue, 05 Sep 2017 09:22:15 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 53A993F74C for ; Tue, 5 Sep 2017 13:22:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 53A993F74C Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=mprivozn@redhat.com Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7CB706A0AC; Tue, 5 Sep 2017 13:22:13 +0000 (UTC) From: Michal Privoznik To: qemu-devel@nongnu.org Date: Tue, 5 Sep 2017 15:22:04 +0200 Message-Id: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 05 Sep 2017 13:22:14 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2] watchdog: Allow setting action on the fly X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: armbru@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Currently, the only time that users can set watchdog action is at the start as all we expose is this -watchdog-action command line argument. This is suboptimal when users want to plug the device later via monitor. Alternatively, they might want to change the action for already existing device on the fly. At the same time, drop local redefinition of the actions eum in watchdog.h in favour of the ones defined in schema. Inspired by: https://bugzilla.redhat.com/show_bug.cgi?id=1447169 Signed-off-by: Michal Privoznik diff to v1: - instead of allowing 'action' to be arbitrary string, use enum for it and thus drop local redefinition of the enum. hw/watchdog/watchdog.c | 52 ++++++++++++++++++++++++----------------------- hw/watchdog/wdt_diag288.c | 6 +++--- include/sysemu/watchdog.h | 12 ++--------- qapi-schema.json | 9 ++++++++ 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c index 0c5c9cde1c..a3e9d7b59b 100644 --- a/hw/watchdog/watchdog.c +++ b/hw/watchdog/watchdog.c @@ -29,8 +29,11 @@ #include "qapi-event.h" #include "hw/nmi.h" #include "qemu/help_option.h" +#include "qmp-commands.h" +#include "qapi/qmp/qerror.h" +#include "qapi/util.h" -static int watchdog_action = WDT_RESET; +static WatchdogExpirationAction watchdog_action = WATCHDOG_EXPIRATION_ACTION_RESET; static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list; void watchdog_add_model(WatchdogTimerModel *model) @@ -77,27 +80,17 @@ 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; + action = qapi_enum_parse(WatchdogExpirationAction_lookup, p, + WATCHDOG_EXPIRATION_ACTION__MAX, -1, NULL); + if (action < 0) + return -1; + qmp_watchdog_set_action(action, NULL); return 0; } -int get_watchdog_action(void) +WatchdogExpirationAction get_watchdog_action(void) { return watchdog_action; } @@ -108,21 +101,21 @@ int get_watchdog_action(void) void watchdog_perform_action(void) { switch (watchdog_action) { - case WDT_RESET: /* same as 'system_reset' in monitor */ + case WATCHDOG_EXPIRATION_ACTION_RESET: /* same as 'system_reset' in monitor */ qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, &error_abort); qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); break; - case WDT_SHUTDOWN: /* same as 'system_powerdown' in monitor */ + case WATCHDOG_EXPIRATION_ACTION_SHUTDOWN: /* same as 'system_powerdown' in monitor */ qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_SHUTDOWN, &error_abort); qemu_system_powerdown_request(); break; - case WDT_POWEROFF: /* same as 'quit' command in monitor */ + case WATCHDOG_EXPIRATION_ACTION_POWEROFF: /* same as 'quit' command in monitor */ qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_POWEROFF, &error_abort); exit(0); - case WDT_PAUSE: /* same as 'stop' command in monitor */ + case WATCHDOG_EXPIRATION_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. */ @@ -131,19 +124,28 @@ void watchdog_perform_action(void) qemu_system_vmstop_request(RUN_STATE_WATCHDOG); break; - case WDT_DEBUG: + case WATCHDOG_EXPIRATION_ACTION_DEBUG: qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, &error_abort); fprintf(stderr, "watchdog: timer fired\n"); break; - case WDT_NONE: + case WATCHDOG_EXPIRATION_ACTION_NONE: qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, &error_abort); break; - case WDT_NMI: + case WATCHDOG_EXPIRATION_ACTION_INJECT_NMI: qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_INJECT_NMI, &error_abort); nmi_monitor_handle(0, NULL); break; + + case WATCHDOG_EXPIRATION_ACTION__MAX: + /* keep gcc happy */ + break; } } + +void qmp_watchdog_set_action(WatchdogExpirationAction action, Error **errp) +{ + watchdog_action = action; +} diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c index 47f289216a..451644eb89 100644 --- a/hw/watchdog/wdt_diag288.c +++ b/hw/watchdog/wdt_diag288.c @@ -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_EXPIRATION_ACTION_DEBUG: + case WATCHDOG_EXPIRATION_ACTION_NONE: + case WATCHDOG_EXPIRATION_ACTION_PAUSE: break; default: wdt_diag288_reset(dev); diff --git a/include/sysemu/watchdog.h b/include/sysemu/watchdog.h index 72a4da07a6..1b830df152 100644 --- a/include/sysemu/watchdog.h +++ b/include/sysemu/watchdog.h @@ -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); +WatchdogExpirationAction get_watchdog_action(void); void watchdog_add_model(WatchdogTimerModel *model); void watchdog_perform_action(void); diff --git a/qapi-schema.json b/qapi-schema.json index 802ea53d00..40605be36f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -6539,3 +6539,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': 'WatchdogExpirationAction'} }