From 7b5d3aa2ccd886cd50216bc35fe3329e7487502e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 7 Mar 2012 08:00:26 +0100 Subject: [PATCH 1/6] wakeup on migration Wakeup the guest when the live part of the migation is finished. This avoids being in suspended state on migration, so we don't have to save the is_suspended bit. Signed-off-by: Gerd Hoffmann Reviewed-by: Luiz Capitulino --- migration.c | 1 + 1 file changed, 1 insertion(+) diff --git a/migration.c b/migration.c index 94f7839e8b..f9e968ee2a 100644 --- a/migration.c +++ b/migration.c @@ -252,6 +252,7 @@ static void migrate_fd_put_ready(void *opaque) int old_vm_running = runstate_is_running(); DPRINTF("done iterating\n"); + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); if (qemu_savevm_state_complete(s->file) < 0) { From 0a24c7b18eefcd1138a5c60fc77bc9b653c64082 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 27 Apr 2012 13:16:41 -0300 Subject: [PATCH 2/6] qapi-schema.json: fix RunState enums alphabetical order Signed-off-by: Luiz Capitulino --- qapi-schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index 4279259bc1..33f2f923a3 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -92,6 +92,8 @@ # # @debug: QEMU is running on a debugger # +# @finish-migrate: guest is paused to finish the migration process +# # @inmigrate: guest is paused waiting for an incoming migration # # @internal-error: An internal error that prevents further guest execution @@ -106,8 +108,6 @@ # # @prelaunch: QEMU was started with -S and guest has not started # -# @finish-migrate: guest is paused to finish the migration process -# # @restore-vm: guest is paused to restore VM state # # @running: guest is actively running From ad02b96ad86baf6dd72a43b04876b2d6ea957112 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 27 Apr 2012 13:33:36 -0300 Subject: [PATCH 3/6] runstate: introduce suspended state QEMU enters in this state when the guest suspends to ram (S3). This is important so that HMP users and QMP clients can know that the guest is suspended. QMP also has an event for this, but events are not reliable and are limited (ie. a client can connect to QEMU after the event has been emitted). Having a different state for S3 brings a new issue, though. Every device that doesn't run when the VM is stopped but wants to run when the VM is suspended has to check for RUN_STATE_SUSPENDED explicitly. This is the case for the keyboard and mouse devices, for example. Signed-off-by: Luiz Capitulino Acked-by: Gerd Hoffmann --- input.c | 4 ++-- qapi-schema.json | 4 +++- qmp.c | 2 ++ vl.c | 7 +++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/input.c b/input.c index 6b5c2c3371..6968b31781 100644 --- a/input.c +++ b/input.c @@ -130,7 +130,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) void kbd_put_keycode(int keycode) { - if (!runstate_is_running()) { + if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { return; } if (qemu_put_kbd_event) { @@ -154,7 +154,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) void *mouse_event_opaque; int width, height; - if (!runstate_is_running()) { + if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { return; } if (QTAILQ_EMPTY(&mouse_handlers)) { diff --git a/qapi-schema.json b/qapi-schema.json index 33f2f923a3..2ca7195d25 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -116,12 +116,14 @@ # # @shutdown: guest is shut down (and -no-shutdown is in use) # +# @suspended: guest is suspended (ACPI S3) +# # @watchdog: the watchdog action is configured to pause and has been triggered ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', - 'running', 'save-vm', 'shutdown', 'watchdog' ] } + 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } ## # @StatusInfo: diff --git a/qmp.c b/qmp.c index a182b5197e..fee9fb2a9d 100644 --- a/qmp.c +++ b/qmp.c @@ -151,6 +151,8 @@ void qmp_cont(Error **errp) runstate_check(RUN_STATE_SHUTDOWN)) { error_set(errp, QERR_RESET_REQUIRED); return; + } else if (runstate_check(RUN_STATE_SUSPENDED)) { + return; } bdrv_iterate(iostatus_bdrv_it, NULL); diff --git a/vl.c b/vl.c index ae91a8ab01..a7afc79c32 100644 --- a/vl.c +++ b/vl.c @@ -366,6 +366,11 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, + { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED }, + { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING }, + { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, @@ -1420,6 +1425,7 @@ static void qemu_system_suspend(void) { pause_all_vcpus(); notifier_list_notify(&suspend_notifiers, NULL); + runstate_set(RUN_STATE_SUSPENDED); monitor_protocol_event(QEVENT_SUSPEND, NULL); is_suspended = true; } @@ -1447,6 +1453,7 @@ void qemu_system_wakeup_request(WakeupReason reason) if (!(wakeup_reason_mask & (1 << reason))) { return; } + runstate_set(RUN_STATE_RUNNING); monitor_protocol_event(QEVENT_WAKEUP, NULL); notifier_list_notify(&wakeup_notifiers, &reason); reset_requested = 1; From 9abc62f6445795522d1bf5bf17f642e44eaf032d Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 27 Apr 2012 14:31:12 -0300 Subject: [PATCH 4/6] vl: drop is_suspended variable Check for the RUN_STATE_SUSPENDED state instead. Signed-off-by: Luiz Capitulino --- vl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/vl.c b/vl.c index a7afc79c32..5e0080b98f 100644 --- a/vl.c +++ b/vl.c @@ -1293,7 +1293,6 @@ static pid_t shutdown_pid; static int powerdown_requested; static int debug_requested; static int suspend_requested; -static bool is_suspended; static NotifierList suspend_notifiers = NOTIFIER_LIST_INITIALIZER(suspend_notifiers); static NotifierList wakeup_notifiers = @@ -1427,12 +1426,11 @@ static void qemu_system_suspend(void) notifier_list_notify(&suspend_notifiers, NULL); runstate_set(RUN_STATE_SUSPENDED); monitor_protocol_event(QEVENT_SUSPEND, NULL); - is_suspended = true; } void qemu_system_suspend_request(void) { - if (is_suspended) { + if (runstate_check(RUN_STATE_SUSPENDED)) { return; } suspend_requested = 1; @@ -1447,7 +1445,7 @@ void qemu_register_suspend_notifier(Notifier *notifier) void qemu_system_wakeup_request(WakeupReason reason) { - if (!is_suspended) { + if (!runstate_check(RUN_STATE_SUSPENDED)) { return; } if (!(wakeup_reason_mask & (1 << reason))) { @@ -1458,7 +1456,6 @@ void qemu_system_wakeup_request(WakeupReason reason) notifier_list_notify(&wakeup_notifiers, &reason); reset_requested = 1; qemu_notify_event(); - is_suspended = false; } void qemu_system_wakeup_enable(WakeupReason reason, bool enabled) From 6b0e33be88bbccc3bcb987026089aa09f9622de9 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 26 Apr 2012 16:48:41 -0300 Subject: [PATCH 5/6] hmp: expr_unary(): check for overflow in strtoul()/strtoull() It's not checked currently, so something like: (qemu) balloon -100000000000001111114334234 (qemu) Will just "work" (in this case the balloon command will get a random value). Fix it by checking if strtoul()/strtoull() overflowed. Signed-off-by: Luiz Capitulino Reviewed-by: Eric Blake --- monitor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monitor.c b/monitor.c index 8946a100c0..bf60984d8f 100644 --- a/monitor.c +++ b/monitor.c @@ -3120,11 +3120,15 @@ static int64_t expr_unary(Monitor *mon) n = 0; break; default: + errno = 0; #if TARGET_PHYS_ADDR_BITS > 32 n = strtoull(pch, &p, 0); #else n = strtoul(pch, &p, 0); #endif + if (errno == ERANGE) { + expr_error(mon, "number too large"); + } if (pch == p) { expr_error(mon, "invalid char in expression"); } From 911628498cea6617243761babbbacaeb8b3a062a Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 26 Apr 2012 17:34:30 -0300 Subject: [PATCH 6/6] hmp: fix bad value conversion for M type The M type converts from megabytes to bytes. However, the value can be negative before the conversion, which will lead to a flawed conversion. For example, this: (qemu) balloon -1000000000000011 (qemu) Just "works", but the value passed by the balloon command will be something else. This patch fixes this problem by requering a positive value before converting. There's really no reason to accept a negative value for the M type. Signed-off-by: Luiz Capitulino Reviewed-by: Eric Blake --- monitor.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index bf60984d8f..12a6fe25ad 100644 --- a/monitor.c +++ b/monitor.c @@ -89,8 +89,8 @@ * TODO lift the restriction * 'i' 32 bit integer * 'l' target long (32 or 64 bit) - * 'M' just like 'l', except in user mode the value is - * multiplied by 2^20 (think Mebibyte) + * 'M' Non-negative target long (32 or 64 bit), in user mode the + * value is multiplied by 2^20 (think Mebibyte) * 'o' octets (aka bytes) * user mode accepts an optional T, t, G, g, M, m, K, k * suffix, which multiplies the value by 2^40 for @@ -3622,6 +3622,10 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, monitor_printf(mon, "integer is for 32-bit values\n"); goto fail; } else if (c == 'M') { + if (val < 0) { + monitor_printf(mon, "enter a positive value\n"); + goto fail; + } val <<= 20; } qdict_put(qdict, key, qint_from_int(val));