Add new function to manage adding the -boot options to the command
line removing that task from the mainline qemuBuildCommandLine.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/qemu/qemu_command.c | 282 +++++++++++++++++++++++++-----------------------
1 file changed, 150 insertions(+), 132 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 302c150..57e9bc7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4954,6 +4954,155 @@ qemuBuildPMCommandLine(virCommandPtr cmd,
static int
+qemuBuildBootCommandLine(virCommandPtr cmd,
+ const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps,
+ bool *emitBootindex)
+{
+ size_t i;
+ virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
+ char *boot_order_str = NULL, *boot_opts_str = NULL;
+
+ /*
+ * We prefer using explicit bootindex=N parameters for predictable
+ * results even though domain XML doesn't use per device boot elements.
+ * However, we can't use bootindex if boot menu was requested.
+ */
+ if (!def->os.nBootDevs) {
+ /* def->os.nBootDevs is guaranteed to be > 0 unless per-device boot
+ * configuration is used
+ */
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("hypervisor lacks deviceboot feature"));
+ goto error;
+ }
+ *emitBootindex = true;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
+ (def->os.bootmenu != VIR_TRISTATE_BOOL_YES ||
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) {
+ *emitBootindex = true;
+ }
+
+ if (!*emitBootindex) {
+ char boot[VIR_DOMAIN_BOOT_LAST+1];
+
+ for (i = 0; i < def->os.nBootDevs; i++) {
+ switch (def->os.bootDevs[i]) {
+ case VIR_DOMAIN_BOOT_CDROM:
+ boot[i] = 'd';
+ break;
+ case VIR_DOMAIN_BOOT_FLOPPY:
+ boot[i] = 'a';
+ break;
+ case VIR_DOMAIN_BOOT_DISK:
+ boot[i] = 'c';
+ break;
+ case VIR_DOMAIN_BOOT_NET:
+ boot[i] = 'n';
+ break;
+ default:
+ boot[i] = 'c';
+ break;
+ }
+ }
+ boot[def->os.nBootDevs] = '\0';
+
+ virBufferAsprintf(&boot_buf, "%s", boot);
+ if (virBufferCheckError(&boot_buf) < 0)
+ goto error;
+ boot_order_str = virBufferContentAndReset(&boot_buf);
+ }
+
+ if (def->os.bootmenu) {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU)) {
+ if (def->os.bootmenu == VIR_TRISTATE_BOOL_YES)
+ virBufferAddLit(&boot_buf, "menu=on,");
+ else
+ virBufferAddLit(&boot_buf, "menu=off,");
+ } else {
+ /* We cannot emit an error when bootmenu is enabled but
+ * unsupported because of backward compatibility */
+ VIR_WARN("bootmenu is enabled but not "
+ "supported by this QEMU binary");
+ }
+ }
+
+ if (def->os.bios.rt_set) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("reboot timeout is not supported "
+ "by this QEMU binary"));
+ goto error;
+ }
+
+ virBufferAsprintf(&boot_buf,
+ "reboot-timeout=%d,",
+ def->os.bios.rt_delay);
+ }
+
+ if (def->os.bm_timeout_set) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPLASH_TIMEOUT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("splash timeout is not supported "
+ "by this QEMU binary"));
+ goto error;
+ }
+
+ virBufferAsprintf(&boot_buf, "splash-time=%u,",
def->os.bm_timeout);
+ }
+
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_STRICT))
+ virBufferAddLit(&boot_buf, "strict=on,");
+
+ virBufferTrim(&boot_buf, ",", -1);
+
+ if (virBufferCheckError(&boot_buf) < 0)
+ goto error;
+
+ boot_opts_str = virBufferContentAndReset(&boot_buf);
+ if (boot_order_str || boot_opts_str) {
+ virCommandAddArg(cmd, "-boot");
+
+ if (boot_order_str && boot_opts_str) {
+ virCommandAddArgFormat(cmd, "order=%s,%s",
+ boot_order_str, boot_opts_str);
+ } else if (boot_order_str) {
+ virCommandAddArg(cmd, boot_order_str);
+ } else if (boot_opts_str) {
+ virCommandAddArg(cmd, boot_opts_str);
+ }
+ }
+ VIR_FREE(boot_opts_str);
+ VIR_FREE(boot_order_str);
+
+ if (def->os.kernel)
+ virCommandAddArgList(cmd, "-kernel", def->os.kernel, NULL);
+ if (def->os.initrd)
+ virCommandAddArgList(cmd, "-initrd", def->os.initrd, NULL);
+ if (def->os.cmdline)
+ virCommandAddArgList(cmd, "-append", def->os.cmdline, NULL);
+ if (def->os.dtb) {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DTB)) {
+ virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL);
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("dtb is not supported with this QEMU binary"));
+ goto error;
+ }
+ }
+
+ return 0;
+
+ error:
+ VIR_FREE(boot_order_str);
+ VIR_FREE(boot_opts_str);
+ virBufferFreeAndReset(&boot_buf);
+ return -1;
+}
+
+
+static int
qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
const virDomainDef *def,
virBufferPtr buf,
@@ -7277,8 +7426,6 @@ qemuBuildCommandLine(virConnectPtr conn,
VIR_DOMAIN_CONTROLLER_TYPE_CCID,
};
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
- char *boot_order_str = NULL, *boot_opts_str = NULL;
virBuffer fdc_opts = VIR_BUFFER_INITIALIZER;
char *fdc_opts_str = NULL;
int bootCD = 0, bootFloppy = 0, bootDisk = 0, bootHostdevNet = 0;
@@ -7387,135 +7534,9 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuBuildPMCommandLine(cmd, def, qemuCaps, monitor_json) < 0)
goto error;
- /*
- * We prefer using explicit bootindex=N parameters for predictable
- * results even though domain XML doesn't use per device boot elements.
- * However, we can't use bootindex if boot menu was requested.
- */
- if (!def->os.nBootDevs) {
- /* def->os.nBootDevs is guaranteed to be > 0 unless per-device boot
- * configuration is used
- */
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("hypervisor lacks deviceboot feature"));
- goto error;
- }
- emitBootindex = true;
- } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
- (def->os.bootmenu != VIR_TRISTATE_BOOL_YES ||
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) {
- emitBootindex = true;
- }
-
- if (!emitBootindex) {
- char boot[VIR_DOMAIN_BOOT_LAST+1];
-
- for (i = 0; i < def->os.nBootDevs; i++) {
- switch (def->os.bootDevs[i]) {
- case VIR_DOMAIN_BOOT_CDROM:
- boot[i] = 'd';
- break;
- case VIR_DOMAIN_BOOT_FLOPPY:
- boot[i] = 'a';
- break;
- case VIR_DOMAIN_BOOT_DISK:
- boot[i] = 'c';
- break;
- case VIR_DOMAIN_BOOT_NET:
- boot[i] = 'n';
- break;
- default:
- boot[i] = 'c';
- break;
- }
- }
- boot[def->os.nBootDevs] = '\0';
-
- virBufferAsprintf(&boot_buf, "%s", boot);
- if (virBufferCheckError(&boot_buf) < 0)
- goto error;
- boot_order_str = virBufferContentAndReset(&boot_buf);
- }
-
- if (def->os.bootmenu) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU)) {
- if (def->os.bootmenu == VIR_TRISTATE_BOOL_YES)
- virBufferAddLit(&boot_buf, "menu=on,");
- else
- virBufferAddLit(&boot_buf, "menu=off,");
- } else {
- /* We cannot emit an error when bootmenu is enabled but
- * unsupported because of backward compatibility */
- VIR_WARN("bootmenu is enabled but not "
- "supported by this QEMU binary");
- }
- }
-
- if (def->os.bios.rt_set) {
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("reboot timeout is not supported "
- "by this QEMU binary"));
- goto error;
- }
-
- virBufferAsprintf(&boot_buf,
- "reboot-timeout=%d,",
- def->os.bios.rt_delay);
- }
-
- if (def->os.bm_timeout_set) {
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPLASH_TIMEOUT)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("splash timeout is not supported "
- "by this QEMU binary"));
- goto error;
- }
-
- virBufferAsprintf(&boot_buf, "splash-time=%u,",
def->os.bm_timeout);
- }
-
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_STRICT))
- virBufferAddLit(&boot_buf, "strict=on,");
-
- virBufferTrim(&boot_buf, ",", -1);
-
- if (virBufferCheckError(&boot_buf) < 0)
+ if (qemuBuildBootCommandLine(cmd, def, qemuCaps, &emitBootindex) < 0)
goto error;
- boot_opts_str = virBufferContentAndReset(&boot_buf);
- if (boot_order_str || boot_opts_str) {
- virCommandAddArg(cmd, "-boot");
-
- if (boot_order_str && boot_opts_str) {
- virCommandAddArgFormat(cmd, "order=%s,%s",
- boot_order_str, boot_opts_str);
- } else if (boot_order_str) {
- virCommandAddArg(cmd, boot_order_str);
- } else if (boot_opts_str) {
- virCommandAddArg(cmd, boot_opts_str);
- }
- }
- VIR_FREE(boot_opts_str);
- VIR_FREE(boot_order_str);
-
- if (def->os.kernel)
- virCommandAddArgList(cmd, "-kernel", def->os.kernel, NULL);
- if (def->os.initrd)
- virCommandAddArgList(cmd, "-initrd", def->os.initrd, NULL);
- if (def->os.cmdline)
- virCommandAddArgList(cmd, "-append", def->os.cmdline, NULL);
- if (def->os.dtb) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DTB)) {
- virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL);
- } else {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("dtb is not supported with this QEMU binary"));
- goto error;
- }
- }
-
for (i = 0; i < def->ncontrollers; i++) {
virDomainControllerDefPtr cont = def->controllers[i];
if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
@@ -8888,9 +8909,6 @@ qemuBuildCommandLine(virConnectPtr conn,
return cmd;
error:
- VIR_FREE(boot_order_str);
- VIR_FREE(boot_opts_str);
- virBufferFreeAndReset(&boot_buf);
virObjectUnref(cfg);
/* free up any resources in the network driver
* but don't overwrite the original error */
--
2.5.0