Statistics
| Branch: | Revision:

root / hw / watchdog.c @ 8167ee88

History | View | Annotate | Download (3.5 kB)

1
/*
2
 * Virtual hardware watchdog.
3
 *
4
 * Copyright (C) 2009 Red Hat Inc.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * By Richard W.M. Jones (rjones@redhat.com).
20
 */
21

    
22
#include "qemu-common.h"
23
#include "sys-queue.h"
24
#include "sysemu.h"
25
#include "hw/watchdog.h"
26

    
27
static LIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
28

    
29
void watchdog_add_model(WatchdogTimerModel *model)
30
{
31
    LIST_INSERT_HEAD(&watchdog_list, model, entry);
32
}
33

    
34
/* Returns:
35
 *   0 = continue
36
 *   1 = exit program with error
37
 *   2 = exit program without error
38
 */
39
int select_watchdog(const char *p)
40
{
41
    WatchdogTimerModel *model;
42

    
43
    if (watchdog) {
44
        fprintf(stderr,
45
                 "qemu: only one watchdog option may be given\n");
46
        return 1;
47
    }
48

    
49
    /* -watchdog ? lists available devices and exits cleanly. */
50
    if (strcmp(p, "?") == 0) {
51
        LIST_FOREACH(model, &watchdog_list, entry) {
52
            fprintf(stderr, "\t%s\t%s\n",
53
                     model->wdt_name, model->wdt_description);
54
        }
55
        return 2;
56
    }
57

    
58
    LIST_FOREACH(model, &watchdog_list, entry) {
59
        if (strcasecmp(model->wdt_name, p) == 0) {
60
            watchdog = model;
61
            return 0;
62
        }
63
    }
64

    
65
    fprintf(stderr, "Unknown -watchdog device. Supported devices are:\n");
66
    LIST_FOREACH(model, &watchdog_list, entry) {
67
        fprintf(stderr, "\t%s\t%s\n",
68
                 model->wdt_name, model->wdt_description);
69
    }
70
    return 1;
71
}
72

    
73
int select_watchdog_action(const char *p)
74
{
75
    if (strcasecmp(p, "reset") == 0)
76
        watchdog_action = WDT_RESET;
77
    else if (strcasecmp(p, "shutdown") == 0)
78
        watchdog_action = WDT_SHUTDOWN;
79
    else if (strcasecmp(p, "poweroff") == 0)
80
        watchdog_action = WDT_POWEROFF;
81
    else if (strcasecmp(p, "pause") == 0)
82
        watchdog_action = WDT_PAUSE;
83
    else if (strcasecmp(p, "debug") == 0)
84
        watchdog_action = WDT_DEBUG;
85
    else if (strcasecmp(p, "none") == 0)
86
        watchdog_action = WDT_NONE;
87
    else
88
        return -1;
89

    
90
    return 0;
91
}
92

    
93
/* This actually performs the "action" once a watchdog has expired,
94
 * ie. reboot, shutdown, exit, etc.
95
 */
96
void watchdog_perform_action(void)
97
{
98
    switch(watchdog_action) {
99
    case WDT_RESET:             /* same as 'system_reset' in monitor */
100
        qemu_system_reset_request();
101
        break;
102

    
103
    case WDT_SHUTDOWN:          /* same as 'system_powerdown' in monitor */
104
        qemu_system_powerdown_request();
105
        break;
106

    
107
    case WDT_POWEROFF:          /* same as 'quit' command in monitor */
108
        exit(0);
109
        break;
110

    
111
    case WDT_PAUSE:             /* same as 'stop' command in monitor */
112
        vm_stop(0);
113
        break;
114

    
115
    case WDT_DEBUG:
116
        fprintf(stderr, "watchdog: timer fired\n");
117
        break;
118

    
119
    case WDT_NONE:
120
        break;
121
    }
122
}
123

    
124
void watchdog_pc_init(PCIBus *pci_bus)
125
{
126
    if (watchdog)
127
        watchdog->wdt_pc_init(pci_bus);
128
}
129

    
130
void register_watchdogs(void)
131
{
132
    wdt_ib700_init();
133
    wdt_i6300esb_init();
134
}