|
|
218e99 |
From a49a3e6984fdb8562003cff96a82b2ac7d9bcc0d Mon Sep 17 00:00:00 2001
|
|
|
218e99 |
Message-Id: <a49a3e6984fdb8562003cff96a82b2ac7d9bcc0d.1383564115.git.minovotn@redhat.com>
|
|
|
218e99 |
In-Reply-To: <5575e0aec51f40ebec46e98ec085cda053283aba.1383564115.git.minovotn@redhat.com>
|
|
|
218e99 |
References: <5575e0aec51f40ebec46e98ec085cda053283aba.1383564115.git.minovotn@redhat.com>
|
|
|
218e99 |
From: Markus Armbruster <armbru@redhat.com>
|
|
|
218e99 |
Date: Fri, 27 Sep 2013 13:31:13 +0200
|
|
|
218e99 |
Subject: [PATCH 03/14] vl: Fix -boot order and once regressions, and related
|
|
|
218e99 |
bugs
|
|
|
218e99 |
|
|
|
218e99 |
RH-Author: Markus Armbruster <armbru@redhat.com>
|
|
|
218e99 |
Message-id: <1380288680-26645-4-git-send-email-armbru@redhat.com>
|
|
|
218e99 |
Patchwork-id: 54567
|
|
|
218e99 |
O-Subject: [PATCH 7.0 qemu-kvm 03/10] vl: Fix -boot order and once regressions, and related bugs
|
|
|
218e99 |
Bugzilla: 997817
|
|
|
218e99 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
|
|
|
218e99 |
|
|
|
218e99 |
From: Markus Armbruster <armbru@redhat.com>
|
|
|
218e99 |
|
|
|
218e99 |
Option "once" sets up a different boot order just for the initial
|
|
|
218e99 |
boot. Boot order reverts back to normal on reset. Option "order"
|
|
|
218e99 |
changes the normal boot order.
|
|
|
218e99 |
|
|
|
218e99 |
The reversal is implemented by reset handler restore_boot_devices(),
|
|
|
218e99 |
which takes the boot order to revert to as argument.
|
|
|
218e99 |
restore_boot_devices() does nothing on its first call, because that
|
|
|
218e99 |
must be the initial machine reset. On its second call, it changes the
|
|
|
218e99 |
boot order back, and unregisters itself.
|
|
|
218e99 |
|
|
|
218e99 |
Because we register the handler right when -boot gets parsed, we can
|
|
|
218e99 |
revert to an incorrect normal boot order, and multiple -boot can
|
|
|
218e99 |
interact in funny ways.
|
|
|
218e99 |
|
|
|
218e99 |
Here's how things work without -boot once or order:
|
|
|
218e99 |
|
|
|
218e99 |
* boot_devices is "".
|
|
|
218e99 |
|
|
|
218e99 |
* main() passes machine->boot_order to to machine->init(), because
|
|
|
218e99 |
boot_devices is "". machine->init() configures firmware
|
|
|
218e99 |
accordingly. For PC machines, machine->boot_order is "cad", and
|
|
|
218e99 |
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
|
|
|
218e99 |
|
|
|
218e99 |
Now consider -boot order=:
|
|
|
218e99 |
|
|
|
218e99 |
* boot_devices is "".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot order= sets boot_devices to "" (no change).
|
|
|
218e99 |
|
|
|
218e99 |
* main() passes machine->boot_order to to machine->init(), because
|
|
|
218e99 |
boot_devices is "", as above.
|
|
|
218e99 |
|
|
|
218e99 |
Bug: -boot order= has no effect. Broken in commit e4ada29e.
|
|
|
218e99 |
|
|
|
218e99 |
Next, consider -boot once=a:
|
|
|
218e99 |
|
|
|
218e99 |
* boot_devices is "".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot once=a registers restore_boot_devices() with argument "", and
|
|
|
218e99 |
sets boot_devices to "a".
|
|
|
218e99 |
|
|
|
218e99 |
* main() passes boot_devices "a" to machine->init(), which configures
|
|
|
218e99 |
firmware accordingly. For PC machines, pc_cmos_init() writes the
|
|
|
218e99 |
boot order to RTC CMOS.
|
|
|
218e99 |
|
|
|
218e99 |
* main() calls qemu_system_reset(). This runs reset handlers.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "". Does
|
|
|
218e99 |
nothing, because it's the first call.
|
|
|
218e99 |
|
|
|
218e99 |
* Machine boots, boot order is "a".
|
|
|
218e99 |
|
|
|
218e99 |
* Machine resets (e.g. monitor command). Reset handlers run.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "". Calls
|
|
|
218e99 |
qemu_boot_set("") to reconfigure firmware. For PC machines,
|
|
|
218e99 |
pc_boot_set() writes it into RTC CMOS. Reset handler
|
|
|
218e99 |
unregistered.
|
|
|
218e99 |
|
|
|
218e99 |
Bug: boot order reverts to "" instead of machine->boot_order. The
|
|
|
218e99 |
actual boot order depends on how firmware interprets "". Broken
|
|
|
218e99 |
in commit e4ada29e.
|
|
|
218e99 |
|
|
|
218e99 |
Next, consider -boot once=a -boot order=c:
|
|
|
218e99 |
|
|
|
218e99 |
* boot_devices is "".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot once=a registers restore_boot_devices() with argument "", and
|
|
|
218e99 |
sets boot_devices to "a".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot order=c sets boot_devices to "c".
|
|
|
218e99 |
|
|
|
218e99 |
* main() passes boot_devices "c" to machine->init(), which configures
|
|
|
218e99 |
firmware accordingly. For PC machines, pc_cmos_init() writes the
|
|
|
218e99 |
boot order to RTC CMOS.
|
|
|
218e99 |
|
|
|
218e99 |
* main() calls qemu_system_reset(). This runs reset handlers.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "". Does
|
|
|
218e99 |
nothing, because it's the first call.
|
|
|
218e99 |
|
|
|
218e99 |
* Machine boots, boot order is "c".
|
|
|
218e99 |
|
|
|
218e99 |
Bug: it should be "a". I figure this has always been broken.
|
|
|
218e99 |
|
|
|
218e99 |
* Machine resets (e.g. monitor command). Reset handlers run.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "". Calls
|
|
|
218e99 |
qemu_boot_set("") to reconfigure firmware. For PC machines,
|
|
|
218e99 |
pc_boot_set() writes it into RTC CMOS. Reset handler
|
|
|
218e99 |
unregistered.
|
|
|
218e99 |
|
|
|
218e99 |
Bug: boot order reverts to "" instead of "c". I figure this has
|
|
|
218e99 |
always been broken, just differently broken before commit
|
|
|
218e99 |
e4ada29e.
|
|
|
218e99 |
|
|
|
218e99 |
Next, consider -boot once=a -boot once=b -boot once=c:
|
|
|
218e99 |
|
|
|
218e99 |
* boot_devices is "".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot once=a registers restore_boot_devices() with argument "", and
|
|
|
218e99 |
sets boot_devices to "a".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot once=b registers restore_boot_devices() with argument "a", and
|
|
|
218e99 |
sets boot_devices to "b".
|
|
|
218e99 |
|
|
|
218e99 |
* -boot once=c registers restore_boot_devices() with argument "b", and
|
|
|
218e99 |
sets boot_devices to "c".
|
|
|
218e99 |
|
|
|
218e99 |
* main() passes boot_devices "c" to machine->init(), which configures
|
|
|
218e99 |
firmware accordingly. For PC machines, pc_cmos_init() writes the
|
|
|
218e99 |
boot order to RTC CMOS.
|
|
|
218e99 |
|
|
|
218e99 |
* main() calls qemu_system_reset(). This runs reset handlers.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "". Does
|
|
|
218e99 |
nothing, because it's the first call.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "a". Calls
|
|
|
218e99 |
qemu_boot_set("a") to reconfigure firmware. For PC machines,
|
|
|
218e99 |
pc_boot_set() writes it into RTC CMOS. Reset handler
|
|
|
218e99 |
unregistered.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "b". Calls
|
|
|
218e99 |
qemu_boot_set("b") to reconfigure firmware. For PC machines,
|
|
|
218e99 |
pc_boot_set() writes it into RTC CMOS. Reset handler
|
|
|
218e99 |
unregistered.
|
|
|
218e99 |
|
|
|
218e99 |
* Machine boots, boot order is "b".
|
|
|
218e99 |
|
|
|
218e99 |
Bug: should really be "c", because that came last, and for all other
|
|
|
218e99 |
-boot options, the last one wins. I figure this was broken some
|
|
|
218e99 |
time before commit 37905d6a, and fixed there only for a single
|
|
|
218e99 |
occurence of "once".
|
|
|
218e99 |
|
|
|
218e99 |
* Machine resets (e.g. monitor command). Reset handlers run.
|
|
|
218e99 |
|
|
|
218e99 |
- restore_boot_devices() gets called with argument "". Calls
|
|
|
218e99 |
qemu_boot_set("") to reconfigure firmware. For PC machines,
|
|
|
218e99 |
pc_boot_set() writes it into RTC CMOS. Reset handler
|
|
|
218e99 |
unregistered.
|
|
|
218e99 |
|
|
|
218e99 |
Same bug as above: boot order reverts to "" instead of
|
|
|
218e99 |
machine->boot_order.
|
|
|
218e99 |
|
|
|
218e99 |
Fix by acting upon -boot options order, once and menu only after
|
|
|
218e99 |
option parsing is complete, and the machine is known. This is how the
|
|
|
218e99 |
other -boot options work already.
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
|
|
218e99 |
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
|
218e99 |
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
|
|
|
218e99 |
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
|
218e99 |
(cherry picked from commit 8281abd548d840d84223e66812491918c713e56c)
|
|
|
218e99 |
---
|
|
|
218e99 |
vl.c | 59 ++++++++++++++++++++++++++++++-----------------------------
|
|
|
218e99 |
1 file changed, 30 insertions(+), 29 deletions(-)
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Michal Novotny <minovotn@redhat.com>
|
|
|
218e99 |
---
|
|
|
218e99 |
vl.c | 59 ++++++++++++++++++++++++++++++-----------------------------
|
|
|
218e99 |
1 file changed, 30 insertions(+), 29 deletions(-)
|
|
|
218e99 |
|
|
|
218e99 |
diff --git a/vl.c b/vl.c
|
|
|
218e99 |
index a5663ad..1c3236c 100644
|
|
|
218e99 |
--- a/vl.c
|
|
|
218e99 |
+++ b/vl.c
|
|
|
218e99 |
@@ -2795,7 +2795,7 @@ int main(int argc, char **argv, char **envp)
|
|
|
218e99 |
const char *icount_option = NULL;
|
|
|
218e99 |
const char *initrd_filename;
|
|
|
218e99 |
const char *kernel_filename, *kernel_cmdline;
|
|
|
218e99 |
- char boot_devices[33] = "";
|
|
|
218e99 |
+ const char *boot_order = NULL;
|
|
|
218e99 |
DisplayState *ds;
|
|
|
218e99 |
int cyls, heads, secs, translation;
|
|
|
218e99 |
QemuOpts *hda_opts = NULL, *opts, *machine_opts;
|
|
|
218e99 |
@@ -3086,31 +3086,9 @@ int main(int argc, char **argv, char **envp)
|
|
|
218e99 |
drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
|
|
|
218e99 |
break;
|
|
|
218e99 |
case QEMU_OPTION_boot:
|
|
|
218e99 |
- {
|
|
|
218e99 |
- char *standard_boot_devices;
|
|
|
218e99 |
- const char *order, *once;
|
|
|
218e99 |
-
|
|
|
218e99 |
- opts = qemu_opts_parse(qemu_find_opts("boot-opts"),
|
|
|
218e99 |
- optarg, 1);
|
|
|
218e99 |
- if (!opts) {
|
|
|
218e99 |
- exit(1);
|
|
|
218e99 |
- }
|
|
|
218e99 |
-
|
|
|
218e99 |
- order = qemu_opt_get(opts, "order");
|
|
|
218e99 |
- if (order) {
|
|
|
218e99 |
- validate_bootdevices(order);
|
|
|
218e99 |
- pstrcpy(boot_devices, sizeof(boot_devices), order);
|
|
|
218e99 |
- }
|
|
|
218e99 |
-
|
|
|
218e99 |
- once = qemu_opt_get(opts, "once");
|
|
|
218e99 |
- if (once) {
|
|
|
218e99 |
- validate_bootdevices(once);
|
|
|
218e99 |
- standard_boot_devices = g_strdup(boot_devices);
|
|
|
218e99 |
- pstrcpy(boot_devices, sizeof(boot_devices), once);
|
|
|
218e99 |
- qemu_register_reset(restore_boot_devices,
|
|
|
218e99 |
- standard_boot_devices);
|
|
|
218e99 |
- }
|
|
|
218e99 |
- boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
|
|
|
218e99 |
+ opts = qemu_opts_parse(qemu_find_opts("boot-opts"), optarg, 1);
|
|
|
218e99 |
+ if (!opts) {
|
|
|
218e99 |
+ exit(1);
|
|
|
218e99 |
}
|
|
|
218e99 |
break;
|
|
|
218e99 |
case QEMU_OPTION_fda:
|
|
|
218e99 |
@@ -4049,6 +4027,31 @@ int main(int argc, char **argv, char **envp)
|
|
|
218e99 |
initrd_filename = qemu_opt_get(machine_opts, "initrd");
|
|
|
218e99 |
kernel_cmdline = qemu_opt_get(machine_opts, "append");
|
|
|
218e99 |
|
|
|
218e99 |
+ if (!boot_order) {
|
|
|
218e99 |
+ boot_order = machine->boot_order;
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+ opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
|
|
|
218e99 |
+ if (opts) {
|
|
|
218e99 |
+ char *normal_boot_order;
|
|
|
218e99 |
+ const char *order, *once;
|
|
|
218e99 |
+
|
|
|
218e99 |
+ order = qemu_opt_get(opts, "order");
|
|
|
218e99 |
+ if (order) {
|
|
|
218e99 |
+ validate_bootdevices(order);
|
|
|
218e99 |
+ boot_order = order;
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
+ once = qemu_opt_get(opts, "once");
|
|
|
218e99 |
+ if (once) {
|
|
|
218e99 |
+ validate_bootdevices(once);
|
|
|
218e99 |
+ normal_boot_order = g_strdup(boot_order);
|
|
|
218e99 |
+ boot_order = once;
|
|
|
218e99 |
+ qemu_register_reset(restore_boot_devices, normal_boot_order);
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
+ boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
|
|
|
218e99 |
+ }
|
|
|
218e99 |
+
|
|
|
218e99 |
if (!kernel_cmdline) {
|
|
|
218e99 |
kernel_cmdline = "";
|
|
|
218e99 |
}
|
|
|
218e99 |
@@ -4213,9 +4216,7 @@ int main(int argc, char **argv, char **envp)
|
|
|
218e99 |
qdev_machine_init();
|
|
|
218e99 |
|
|
|
218e99 |
QEMUMachineInitArgs args = { .ram_size = ram_size,
|
|
|
218e99 |
- .boot_device = (boot_devices[0] == '\0') ?
|
|
|
218e99 |
- machine->boot_order :
|
|
|
218e99 |
- boot_devices,
|
|
|
218e99 |
+ .boot_device = boot_order,
|
|
|
218e99 |
.kernel_filename = kernel_filename,
|
|
|
218e99 |
.kernel_cmdline = kernel_cmdline,
|
|
|
218e99 |
.initrd_filename = initrd_filename,
|
|
|
218e99 |
--
|
|
|
218e99 |
1.7.11.7
|
|
|
218e99 |
|