[libvirt] [PATCH 0/4] Add support for reboot-timeout

This series introduces simple reboot timeout support. That means what should be done in case all boot options fail, reboot or not. And if yes, then how long the machine should wait. Before adding the support for that into XML parser, builder, and qemu, I felt the need to cleanup the boot parsing and enums (I couldn't look at that), so that's the first patch. Most of it is mechanical, the rest should be pretty straight-forward. --- I'd *love* to have it in 0.10.2, but I understand if it's too late :( Martin Kletzander (4): qemu: Cleanup boot parameter building Add support for reboot-timeout qemu: Add support for reboot-timeout QEMU Tests for reboot-timeout docs/formatdomain.html.in | 9 ++ docs/schemas/domaincommon.rng | 20 ++++ src/conf/domain_conf.c | 56 ++++++++- src/conf/domain_conf.h | 78 ++++++++----- src/libvirt_private.syms | 2 + src/qemu/qemu_capabilities.c | 4 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 129 +++++++++++++++++---- tests/qemuargv2xmltest.c | 4 + ...xml2argv-boot-menu-disable-drive-bootindex.args | 1 + .../qemuxml2argv-reboot-timeout-disabled.args | 3 + .../qemuxml2argv-reboot-timeout-disabled.xml | 21 ++++ .../qemuxml2argv-reboot-timeout-enabled.args | 3 + .../qemuxml2argv-reboot-timeout-enabled.xml | 21 ++++ tests/qemuxml2argvtest.c | 5 + tests/qemuxml2xmltest.c | 4 + 16 files changed, 304 insertions(+), 57 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml -- 1.7.12

This patch cleans up building the "-boot" parameter and while on that fixes one inconsistency by modifying these things: - First off, there's the cleanup for all *_LAST enum values to end without comma at the end. I chose this way because if it were the other way around, the patch would have 2 times more lines. - I completed the unfinished virDomainBootMenu enum by specifying LAST, declaring it and also declaring the TypeFromString and TypeToString parameters. - Previously mentioned TypeFromString and TypeToString are used when parsing the XML. - Last, but not least, visible change is that the "-boot" parameter is built and parsed properly: - The "order=" prefix is used only when additional parameters are used (menu, etc.). - It's rewritten in a way that other parameters can be added easily in the future (used in following patch). - The "order=" parameter is properly parsed regardless to where it is placed in the string (e.g. "menu=on,order=nc"). - The "menu=" parameter (and others in the future) are created when they should be (i.e. even when bootindex is supported and used, but not when bootloader is selected). --- src/conf/domain_conf.c | 16 +++- src/conf/domain_conf.h | 63 ++++++++------- src/libvirt_private.syms | 2 + src/qemu/qemu_command.c | 93 ++++++++++++++++------ ...xml2argv-boot-menu-disable-drive-bootindex.args | 1 + 5 files changed, 118 insertions(+), 57 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 15b360a..35814fb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -102,6 +102,11 @@ VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST, "hd", "network") +VIR_ENUM_IMPL(virDomainBootMenu, VIR_DOMAIN_BOOT_MENU_LAST, + "default", + "yes", + "no") + VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "acpi", "apic", @@ -8181,10 +8186,15 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt, bootstr = virXPathString("string(./os/bootmenu[1]/@enable)", ctxt); if (bootstr) { - if (STREQ(bootstr, "yes")) - def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_ENABLED; - else + def->os.bootmenu = virDomainBootMenuTypeFromString(bootstr); + if (def->os.bootmenu <= 0) { + /* In order not to break misconfigured machines, this + * should not emit an error, but rather set the bootmenu + * to disabled */ + VIR_WARN("disabling bootmenu due to unknown option '%s'", + bootstr); def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_DISABLED; + } VIR_FREE(bootstr); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f0dea48..510406a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -134,7 +134,7 @@ typedef enum { VIR_DOMAIN_DEVICE_CHR, VIR_DOMAIN_DEVICE_MEMBALLOON, - VIR_DOMAIN_DEVICE_LAST, + VIR_DOMAIN_DEVICE_LAST } virDomainDeviceType; typedef struct _virDomainDeviceDef virDomainDeviceDef; @@ -178,7 +178,7 @@ enum virDomainVirtType { VIR_DOMAIN_VIRT_PHYP, VIR_DOMAIN_VIRT_PARALLELS, - VIR_DOMAIN_VIRT_LAST, + VIR_DOMAIN_VIRT_LAST }; enum virDomainDeviceAddressType { @@ -289,7 +289,7 @@ enum virDomainSeclabelType { VIR_DOMAIN_SECLABEL_DYNAMIC, VIR_DOMAIN_SECLABEL_STATIC, - VIR_DOMAIN_SECLABEL_LAST, + VIR_DOMAIN_SECLABEL_LAST }; /* Security configuration for domain */ @@ -353,7 +353,7 @@ enum virDomainHostdevMode { VIR_DOMAIN_HOSTDEV_MODE_SUBSYS, VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES, - VIR_DOMAIN_HOSTDEV_MODE_LAST, + VIR_DOMAIN_HOSTDEV_MODE_LAST }; enum virDomainHostdevSubsysType { @@ -736,7 +736,7 @@ enum virDomainNetType { VIR_DOMAIN_NET_TYPE_DIRECT, VIR_DOMAIN_NET_TYPE_HOSTDEV, - VIR_DOMAIN_NET_TYPE_LAST, + VIR_DOMAIN_NET_TYPE_LAST }; /* the backend driver used for virtio interfaces */ @@ -745,7 +745,7 @@ enum virDomainNetBackendType { VIR_DOMAIN_NET_BACKEND_TYPE_QEMU, /* userland */ VIR_DOMAIN_NET_BACKEND_TYPE_VHOST, /* kernel */ - VIR_DOMAIN_NET_BACKEND_TYPE_LAST, + VIR_DOMAIN_NET_BACKEND_TYPE_LAST }; /* the TX algorithm used for virtio interfaces */ @@ -754,7 +754,7 @@ enum virDomainNetVirtioTxModeType { VIR_DOMAIN_NET_VIRTIO_TX_MODE_IOTHREAD, VIR_DOMAIN_NET_VIRTIO_TX_MODE_TIMER, - VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST, + VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST }; /* link interface states */ @@ -868,7 +868,7 @@ enum virDomainChrDeviceType { VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE, VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL, - VIR_DOMAIN_CHR_DEVICE_TYPE_LAST, + VIR_DOMAIN_CHR_DEVICE_TYPE_LAST }; enum virDomainChrChannelTargetType { @@ -876,7 +876,7 @@ enum virDomainChrChannelTargetType { VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD, VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO, - VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST, + VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST }; enum virDomainChrConsoleTargetType { @@ -887,7 +887,7 @@ enum virDomainChrConsoleTargetType { VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC, VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ, - VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST, + VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST }; enum virDomainChrType { @@ -903,7 +903,7 @@ enum virDomainChrType { VIR_DOMAIN_CHR_TYPE_UNIX, VIR_DOMAIN_CHR_TYPE_SPICEVMC, - VIR_DOMAIN_CHR_TYPE_LAST, + VIR_DOMAIN_CHR_TYPE_LAST }; enum virDomainChrTcpProtocol { @@ -912,7 +912,7 @@ enum virDomainChrTcpProtocol { VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNETS, /* secure telnet */ VIR_DOMAIN_CHR_TCP_PROTOCOL_TLS, - VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, + VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST }; enum virDomainChrSpicevmcName { @@ -920,7 +920,7 @@ enum virDomainChrSpicevmcName { VIR_DOMAIN_CHR_SPICEVMC_SMARTCARD, VIR_DOMAIN_CHR_SPICEVMC_USBREDIR, - VIR_DOMAIN_CHR_SPICEVMC_LAST, + VIR_DOMAIN_CHR_SPICEVMC_LAST }; /* The host side information for a character device. */ @@ -973,7 +973,7 @@ enum virDomainSmartcardType { VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES, VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH, - VIR_DOMAIN_SMARTCARD_TYPE_LAST, + VIR_DOMAIN_SMARTCARD_TYPE_LAST }; # define VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES 3 @@ -1002,7 +1002,7 @@ enum virDomainInputType { VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_TABLET, - VIR_DOMAIN_INPUT_TYPE_LAST, + VIR_DOMAIN_INPUT_TYPE_LAST }; enum virDomainInputBus { @@ -1110,7 +1110,7 @@ enum virDomainGraphicsType { VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP, VIR_DOMAIN_GRAPHICS_TYPE_SPICE, - VIR_DOMAIN_GRAPHICS_TYPE_LAST, + VIR_DOMAIN_GRAPHICS_TYPE_LAST }; enum virDomainGraphicsAuthConnectedType { @@ -1220,13 +1220,13 @@ enum virDomainGraphicsListenType { VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK, - VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST, + VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST }; enum virDomainHubType { VIR_DOMAIN_HUB_TYPE_USB, - VIR_DOMAIN_HUB_TYPE_LAST, + VIR_DOMAIN_HUB_TYPE_LAST }; typedef struct _virDomainGraphicsListenDef virDomainGraphicsListenDef; @@ -1352,13 +1352,15 @@ enum virDomainBootOrder { VIR_DOMAIN_BOOT_DISK, VIR_DOMAIN_BOOT_NET, - VIR_DOMAIN_BOOT_LAST, + VIR_DOMAIN_BOOT_LAST }; enum virDomainBootMenu { VIR_DOMAIN_BOOT_MENU_DEFAULT = 0, VIR_DOMAIN_BOOT_MENU_ENABLED, VIR_DOMAIN_BOOT_MENU_DISABLED, + + VIR_DOMAIN_BOOT_MENU_LAST }; enum virDomainFeature { @@ -1377,7 +1379,7 @@ enum virDomainApicEoi { VIR_DOMAIN_APIC_EOI_ON, VIR_DOMAIN_APIC_EOI_OFF, - VIR_DOMAIN_APIC_EOI_LAST, + VIR_DOMAIN_APIC_EOI_LAST }; enum virDomainLifecycleAction { @@ -1405,7 +1407,7 @@ enum virDomainPMState { VIR_DOMAIN_PM_STATE_ENABLED, VIR_DOMAIN_PM_STATE_DISABLED, - VIR_DOMAIN_PM_STATE_LAST, + VIR_DOMAIN_PM_STATE_LAST }; enum virDomainBIOSUseserial { @@ -1429,6 +1431,7 @@ struct _virDomainOSDef { char *machine; int nBootDevs; int bootDevs[VIR_DOMAIN_BOOT_LAST]; + /* enum virDomainBootMenu */ int bootmenu; char *init; char **initargv; @@ -1440,6 +1443,7 @@ struct _virDomainOSDef { char *bootloader; char *bootloaderArgs; int smbios_mode; + virDomainBIOSDef bios; }; @@ -1451,7 +1455,7 @@ enum virDomainTimerNameType { VIR_DOMAIN_TIMER_NAME_TSC, VIR_DOMAIN_TIMER_NAME_KVMCLOCK, - VIR_DOMAIN_TIMER_NAME_LAST, + VIR_DOMAIN_TIMER_NAME_LAST }; enum virDomainTimerTrackType { @@ -1459,7 +1463,7 @@ enum virDomainTimerTrackType { VIR_DOMAIN_TIMER_TRACK_GUEST, VIR_DOMAIN_TIMER_TRACK_WALL, - VIR_DOMAIN_TIMER_TRACK_LAST, + VIR_DOMAIN_TIMER_TRACK_LAST }; enum virDomainTimerTickpolicyType { @@ -1468,7 +1472,7 @@ enum virDomainTimerTickpolicyType { VIR_DOMAIN_TIMER_TICKPOLICY_MERGE, VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD, - VIR_DOMAIN_TIMER_TICKPOLICY_LAST, + VIR_DOMAIN_TIMER_TICKPOLICY_LAST }; enum virDomainTimerModeType { @@ -1478,14 +1482,14 @@ enum virDomainTimerModeType { VIR_DOMAIN_TIMER_MODE_PARAVIRT, VIR_DOMAIN_TIMER_MODE_SMPSAFE, - VIR_DOMAIN_TIMER_MODE_LAST, + VIR_DOMAIN_TIMER_MODE_LAST }; enum virDomainCpuPlacementMode { VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC = 0, VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO, - VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST, + VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST }; enum virDomainNumatuneMemPlacementMode { @@ -1493,7 +1497,7 @@ enum virDomainNumatuneMemPlacementMode { VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC, VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO, - VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST, + VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST }; typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef; @@ -1527,14 +1531,14 @@ enum virDomainClockOffsetType { VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE = 3, - VIR_DOMAIN_CLOCK_OFFSET_LAST, + VIR_DOMAIN_CLOCK_OFFSET_LAST }; enum virDomainClockBasis { VIR_DOMAIN_CLOCK_BASIS_UTC = 0, VIR_DOMAIN_CLOCK_BASIS_LOCALTIME = 1, - VIR_DOMAIN_CLOCK_BASIS_LAST, + VIR_DOMAIN_CLOCK_BASIS_LAST }; typedef struct _virDomainClockDef virDomainClockDef; @@ -2129,6 +2133,7 @@ VIR_ENUM_DECL(virDomainTaint) VIR_ENUM_DECL(virDomainVirt) VIR_ENUM_DECL(virDomainBoot) +VIR_ENUM_DECL(virDomainBootMenu) VIR_ENUM_DECL(virDomainFeature) VIR_ENUM_DECL(virDomainApicEoi) VIR_ENUM_DECL(virDomainLifecycle) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ec2e544..be49214 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -280,6 +280,8 @@ virDomainApicEoiTypeToString; virDomainAssignDef; virDomainBlockedReasonTypeFromString; virDomainBlockedReasonTypeToString; +virDomainBootMenuTypeFromString; +virDomainBootMenuTypeToString; virDomainChrConsoleTargetTypeFromString; virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index cbf4aee..f8012ec 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4879,6 +4879,8 @@ qemuBuildCommandLine(virConnectPtr conn, } if (!def->os.bootloader) { + int boot_nparams = 0; + virBuffer boot_buf = VIR_BUFFER_INITIALIZER; /* * We prefer using explicit bootindex=N parameters for predictable * results even though domain XML doesn't use per device boot elements. @@ -4901,7 +4903,6 @@ qemuBuildCommandLine(virConnectPtr conn, } if (!emitBootindex) { - virBuffer boot_buf = VIR_BUFFER_INITIALIZER; char boot[VIR_DOMAIN_BOOT_LAST+1]; for (i = 0 ; i < def->os.nBootDevs ; i++) { @@ -4925,19 +4926,38 @@ qemuBuildCommandLine(virConnectPtr conn, } boot[def->os.nBootDevs] = '\0'; - virCommandAddArg(cmd, "-boot"); + virBufferAsprintf(&boot_buf, "%s", boot); + boot_nparams++; + } + + if (def->os.bootmenu) { + if (qemuCapsGet(caps, QEMU_CAPS_BOOT_MENU)) { + if (boot_nparams++) + virBufferAddChar(&boot_buf, ','); - if (qemuCapsGet(caps, QEMU_CAPS_BOOT_MENU) && - def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) { if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED) - virBufferAsprintf(&boot_buf, "order=%s,menu=on", boot); - else if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_DISABLED) - virBufferAsprintf(&boot_buf, "order=%s,menu=off", boot); + virBufferAsprintf(&boot_buf, "menu=on"); + else + virBufferAsprintf(&boot_buf, "menu=off"); } else { - virBufferAdd(&boot_buf, boot, -1); + /* 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"); } - virCommandAddArgBuffer(cmd, &boot_buf); + } + + if (boot_nparams > 0) { + virCommandAddArg(cmd, "-boot"); + + if (boot_nparams < 2 || emitBootindex) { + virCommandAddArgBuffer(cmd, &boot_buf); + } else { + virCommandAddArgFormat(cmd, + "order=%s", + virBufferContentAndReset(&boot_buf)); + } } if (def->os.kernel) @@ -7861,6 +7881,26 @@ error: } +static void +qemuParseCommandLineBootDevs(virDomainDefPtr def, const char *str) { + int n, b = 0; + + for (n = 0 ; str[n] && b < VIR_DOMAIN_BOOT_LAST ; n++) { + if (str[n] == 'a') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_FLOPPY; + else if (str[n] == 'c') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_DISK; + else if (str[n] == 'd') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM; + else if (str[n] == 'n') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET; + else if (str[n] == ',') + break; + } + def->os.nBootDevs = b; +} + + /* * Analyse the env and argv settings and reconstruct a * virDomainDefPtr representing these settings as closely @@ -8218,24 +8258,27 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, if (!(def->os.cmdline = strdup(val))) goto no_memory; } else if (STREQ(arg, "-boot")) { - int n, b = 0; + const char *token = NULL; WANT_VALUE(); - for (n = 0 ; val[n] && b < VIR_DOMAIN_BOOT_LAST ; n++) { - if (val[n] == 'a') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_FLOPPY; - else if (val[n] == 'c') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_DISK; - else if (val[n] == 'd') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM; - else if (val[n] == 'n') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET; - else if (val[n] == ',') - break; - } - def->os.nBootDevs = b; - if (strstr(val, "menu=on")) - def->os.bootmenu = 1; + if (!strchr(val, ',')) + qemuParseCommandLineBootDevs(def, val); + else { + token = val; + while (token && *token) { + if (STRPREFIX(token, "order=")) { + token += strlen("order="); + qemuParseCommandLineBootDevs(def, token); + } else if (STRPREFIX(token, "menu=on")) { + def->os.bootmenu = 1; + } + token = strchr(token, ','); + /* This incrementation has to be done here in order to make it + * possible to pass the token pointer properly into the loop */ + if (token) + token++; + } + } } else if (STREQ(arg, "-name")) { char *process; WANT_VALUE(); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args index 5074e32..75b6b4c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args @@ -7,6 +7,7 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \ -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait \ -no-acpi \ +-boot menu=off \ -drive file=/dev/cdrom,if=none,media=cdrom,id=drive-ide0-1-0 \ -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0,bootindex=1 \ -usb \ -- 1.7.12

On 18.09.2012 17:36, Martin Kletzander wrote:
This patch cleans up building the "-boot" parameter and while on that fixes one inconsistency by modifying these things:
- First off, there's the cleanup for all *_LAST enum values to end without comma at the end. I chose this way because if it were the other way around, the patch would have 2 times more lines. - I completed the unfinished virDomainBootMenu enum by specifying LAST, declaring it and also declaring the TypeFromString and TypeToString parameters. - Previously mentioned TypeFromString and TypeToString are used when parsing the XML. - Last, but not least, visible change is that the "-boot" parameter is built and parsed properly: - The "order=" prefix is used only when additional parameters are used (menu, etc.). - It's rewritten in a way that other parameters can be added easily in the future (used in following patch). - The "order=" parameter is properly parsed regardless to where it is placed in the string (e.g. "menu=on,order=nc"). - The "menu=" parameter (and others in the future) are created when they should be (i.e. even when bootindex is supported and used, but not when bootloader is selected). --- src/conf/domain_conf.c | 16 +++- src/conf/domain_conf.h | 63 ++++++++------- src/libvirt_private.syms | 2 + src/qemu/qemu_command.c | 93 ++++++++++++++++------ ...xml2argv-boot-menu-disable-drive-bootindex.args | 1 + 5 files changed, 118 insertions(+), 57 deletions(-)
While it's true *_LAST shouldn't be followed by comma (they are the last items after all) you should save that for a separate patch as it is something different than cleaning up '-boot' parameter generation. ACK if you split this. The cleanup patch doesn't have to be part of this set anyway. Michal
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 15b360a..35814fb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -102,6 +102,11 @@ VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST, "hd", "network")
+VIR_ENUM_IMPL(virDomainBootMenu, VIR_DOMAIN_BOOT_MENU_LAST, + "default", + "yes", + "no") + VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "acpi", "apic", @@ -8181,10 +8186,15 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
bootstr = virXPathString("string(./os/bootmenu[1]/@enable)", ctxt); if (bootstr) { - if (STREQ(bootstr, "yes")) - def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_ENABLED; - else + def->os.bootmenu = virDomainBootMenuTypeFromString(bootstr); + if (def->os.bootmenu <= 0) { + /* In order not to break misconfigured machines, this + * should not emit an error, but rather set the bootmenu + * to disabled */ + VIR_WARN("disabling bootmenu due to unknown option '%s'", + bootstr); def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_DISABLED; + } VIR_FREE(bootstr); }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f0dea48..510406a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -134,7 +134,7 @@ typedef enum { VIR_DOMAIN_DEVICE_CHR, VIR_DOMAIN_DEVICE_MEMBALLOON,
- VIR_DOMAIN_DEVICE_LAST, + VIR_DOMAIN_DEVICE_LAST } virDomainDeviceType;
typedef struct _virDomainDeviceDef virDomainDeviceDef; @@ -178,7 +178,7 @@ enum virDomainVirtType { VIR_DOMAIN_VIRT_PHYP, VIR_DOMAIN_VIRT_PARALLELS,
- VIR_DOMAIN_VIRT_LAST, + VIR_DOMAIN_VIRT_LAST };
enum virDomainDeviceAddressType { @@ -289,7 +289,7 @@ enum virDomainSeclabelType { VIR_DOMAIN_SECLABEL_DYNAMIC, VIR_DOMAIN_SECLABEL_STATIC,
- VIR_DOMAIN_SECLABEL_LAST, + VIR_DOMAIN_SECLABEL_LAST };
/* Security configuration for domain */ @@ -353,7 +353,7 @@ enum virDomainHostdevMode { VIR_DOMAIN_HOSTDEV_MODE_SUBSYS, VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES,
- VIR_DOMAIN_HOSTDEV_MODE_LAST, + VIR_DOMAIN_HOSTDEV_MODE_LAST };
enum virDomainHostdevSubsysType { @@ -736,7 +736,7 @@ enum virDomainNetType { VIR_DOMAIN_NET_TYPE_DIRECT, VIR_DOMAIN_NET_TYPE_HOSTDEV,
- VIR_DOMAIN_NET_TYPE_LAST, + VIR_DOMAIN_NET_TYPE_LAST };
/* the backend driver used for virtio interfaces */ @@ -745,7 +745,7 @@ enum virDomainNetBackendType { VIR_DOMAIN_NET_BACKEND_TYPE_QEMU, /* userland */ VIR_DOMAIN_NET_BACKEND_TYPE_VHOST, /* kernel */
- VIR_DOMAIN_NET_BACKEND_TYPE_LAST, + VIR_DOMAIN_NET_BACKEND_TYPE_LAST };
/* the TX algorithm used for virtio interfaces */ @@ -754,7 +754,7 @@ enum virDomainNetVirtioTxModeType { VIR_DOMAIN_NET_VIRTIO_TX_MODE_IOTHREAD, VIR_DOMAIN_NET_VIRTIO_TX_MODE_TIMER,
- VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST, + VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST };
/* link interface states */ @@ -868,7 +868,7 @@ enum virDomainChrDeviceType { VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE, VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL,
- VIR_DOMAIN_CHR_DEVICE_TYPE_LAST, + VIR_DOMAIN_CHR_DEVICE_TYPE_LAST };
enum virDomainChrChannelTargetType { @@ -876,7 +876,7 @@ enum virDomainChrChannelTargetType { VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD, VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO,
- VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST, + VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST };
enum virDomainChrConsoleTargetType { @@ -887,7 +887,7 @@ enum virDomainChrConsoleTargetType { VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC, VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ,
- VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST, + VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST };
enum virDomainChrType { @@ -903,7 +903,7 @@ enum virDomainChrType { VIR_DOMAIN_CHR_TYPE_UNIX, VIR_DOMAIN_CHR_TYPE_SPICEVMC,
- VIR_DOMAIN_CHR_TYPE_LAST, + VIR_DOMAIN_CHR_TYPE_LAST };
enum virDomainChrTcpProtocol { @@ -912,7 +912,7 @@ enum virDomainChrTcpProtocol { VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNETS, /* secure telnet */ VIR_DOMAIN_CHR_TCP_PROTOCOL_TLS,
- VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, + VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST };
enum virDomainChrSpicevmcName { @@ -920,7 +920,7 @@ enum virDomainChrSpicevmcName { VIR_DOMAIN_CHR_SPICEVMC_SMARTCARD, VIR_DOMAIN_CHR_SPICEVMC_USBREDIR,
- VIR_DOMAIN_CHR_SPICEVMC_LAST, + VIR_DOMAIN_CHR_SPICEVMC_LAST };
/* The host side information for a character device. */ @@ -973,7 +973,7 @@ enum virDomainSmartcardType { VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES, VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH,
- VIR_DOMAIN_SMARTCARD_TYPE_LAST, + VIR_DOMAIN_SMARTCARD_TYPE_LAST };
# define VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES 3 @@ -1002,7 +1002,7 @@ enum virDomainInputType { VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_TABLET,
- VIR_DOMAIN_INPUT_TYPE_LAST, + VIR_DOMAIN_INPUT_TYPE_LAST };
enum virDomainInputBus { @@ -1110,7 +1110,7 @@ enum virDomainGraphicsType { VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP, VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- VIR_DOMAIN_GRAPHICS_TYPE_LAST, + VIR_DOMAIN_GRAPHICS_TYPE_LAST };
enum virDomainGraphicsAuthConnectedType { @@ -1220,13 +1220,13 @@ enum virDomainGraphicsListenType { VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK,
- VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST, + VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST };
enum virDomainHubType { VIR_DOMAIN_HUB_TYPE_USB,
- VIR_DOMAIN_HUB_TYPE_LAST, + VIR_DOMAIN_HUB_TYPE_LAST };
typedef struct _virDomainGraphicsListenDef virDomainGraphicsListenDef; @@ -1352,13 +1352,15 @@ enum virDomainBootOrder { VIR_DOMAIN_BOOT_DISK, VIR_DOMAIN_BOOT_NET,
- VIR_DOMAIN_BOOT_LAST, + VIR_DOMAIN_BOOT_LAST };
enum virDomainBootMenu { VIR_DOMAIN_BOOT_MENU_DEFAULT = 0, VIR_DOMAIN_BOOT_MENU_ENABLED, VIR_DOMAIN_BOOT_MENU_DISABLED, + + VIR_DOMAIN_BOOT_MENU_LAST };
enum virDomainFeature { @@ -1377,7 +1379,7 @@ enum virDomainApicEoi { VIR_DOMAIN_APIC_EOI_ON, VIR_DOMAIN_APIC_EOI_OFF,
- VIR_DOMAIN_APIC_EOI_LAST, + VIR_DOMAIN_APIC_EOI_LAST };
enum virDomainLifecycleAction { @@ -1405,7 +1407,7 @@ enum virDomainPMState { VIR_DOMAIN_PM_STATE_ENABLED, VIR_DOMAIN_PM_STATE_DISABLED,
- VIR_DOMAIN_PM_STATE_LAST, + VIR_DOMAIN_PM_STATE_LAST };
enum virDomainBIOSUseserial { @@ -1429,6 +1431,7 @@ struct _virDomainOSDef { char *machine; int nBootDevs; int bootDevs[VIR_DOMAIN_BOOT_LAST]; + /* enum virDomainBootMenu */ int bootmenu; char *init; char **initargv; @@ -1440,6 +1443,7 @@ struct _virDomainOSDef { char *bootloader; char *bootloaderArgs; int smbios_mode; + virDomainBIOSDef bios; };
@@ -1451,7 +1455,7 @@ enum virDomainTimerNameType { VIR_DOMAIN_TIMER_NAME_TSC, VIR_DOMAIN_TIMER_NAME_KVMCLOCK,
- VIR_DOMAIN_TIMER_NAME_LAST, + VIR_DOMAIN_TIMER_NAME_LAST };
enum virDomainTimerTrackType { @@ -1459,7 +1463,7 @@ enum virDomainTimerTrackType { VIR_DOMAIN_TIMER_TRACK_GUEST, VIR_DOMAIN_TIMER_TRACK_WALL,
- VIR_DOMAIN_TIMER_TRACK_LAST, + VIR_DOMAIN_TIMER_TRACK_LAST };
enum virDomainTimerTickpolicyType { @@ -1468,7 +1472,7 @@ enum virDomainTimerTickpolicyType { VIR_DOMAIN_TIMER_TICKPOLICY_MERGE, VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD,
- VIR_DOMAIN_TIMER_TICKPOLICY_LAST, + VIR_DOMAIN_TIMER_TICKPOLICY_LAST };
enum virDomainTimerModeType { @@ -1478,14 +1482,14 @@ enum virDomainTimerModeType { VIR_DOMAIN_TIMER_MODE_PARAVIRT, VIR_DOMAIN_TIMER_MODE_SMPSAFE,
- VIR_DOMAIN_TIMER_MODE_LAST, + VIR_DOMAIN_TIMER_MODE_LAST };
enum virDomainCpuPlacementMode { VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC = 0, VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO,
- VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST, + VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST };
enum virDomainNumatuneMemPlacementMode { @@ -1493,7 +1497,7 @@ enum virDomainNumatuneMemPlacementMode { VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC, VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST, + VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST };
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef; @@ -1527,14 +1531,14 @@ enum virDomainClockOffsetType { VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE = 3,
- VIR_DOMAIN_CLOCK_OFFSET_LAST, + VIR_DOMAIN_CLOCK_OFFSET_LAST };
enum virDomainClockBasis { VIR_DOMAIN_CLOCK_BASIS_UTC = 0, VIR_DOMAIN_CLOCK_BASIS_LOCALTIME = 1,
- VIR_DOMAIN_CLOCK_BASIS_LAST, + VIR_DOMAIN_CLOCK_BASIS_LAST };
typedef struct _virDomainClockDef virDomainClockDef; @@ -2129,6 +2133,7 @@ VIR_ENUM_DECL(virDomainTaint)
VIR_ENUM_DECL(virDomainVirt) VIR_ENUM_DECL(virDomainBoot) +VIR_ENUM_DECL(virDomainBootMenu) VIR_ENUM_DECL(virDomainFeature) VIR_ENUM_DECL(virDomainApicEoi) VIR_ENUM_DECL(virDomainLifecycle) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ec2e544..be49214 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -280,6 +280,8 @@ virDomainApicEoiTypeToString; virDomainAssignDef; virDomainBlockedReasonTypeFromString; virDomainBlockedReasonTypeToString; +virDomainBootMenuTypeFromString; +virDomainBootMenuTypeToString; virDomainChrConsoleTargetTypeFromString; virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index cbf4aee..f8012ec 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4879,6 +4879,8 @@ qemuBuildCommandLine(virConnectPtr conn, }
if (!def->os.bootloader) { + int boot_nparams = 0; + virBuffer boot_buf = VIR_BUFFER_INITIALIZER; /* * We prefer using explicit bootindex=N parameters for predictable * results even though domain XML doesn't use per device boot elements. @@ -4901,7 +4903,6 @@ qemuBuildCommandLine(virConnectPtr conn, }
if (!emitBootindex) { - virBuffer boot_buf = VIR_BUFFER_INITIALIZER; char boot[VIR_DOMAIN_BOOT_LAST+1];
for (i = 0 ; i < def->os.nBootDevs ; i++) { @@ -4925,19 +4926,38 @@ qemuBuildCommandLine(virConnectPtr conn, } boot[def->os.nBootDevs] = '\0';
- virCommandAddArg(cmd, "-boot"); + virBufferAsprintf(&boot_buf, "%s", boot); + boot_nparams++; + } + + if (def->os.bootmenu) { + if (qemuCapsGet(caps, QEMU_CAPS_BOOT_MENU)) { + if (boot_nparams++) + virBufferAddChar(&boot_buf, ',');
- if (qemuCapsGet(caps, QEMU_CAPS_BOOT_MENU) && - def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) { if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED) - virBufferAsprintf(&boot_buf, "order=%s,menu=on", boot); - else if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_DISABLED) - virBufferAsprintf(&boot_buf, "order=%s,menu=off", boot); + virBufferAsprintf(&boot_buf, "menu=on"); + else + virBufferAsprintf(&boot_buf, "menu=off"); } else { - virBufferAdd(&boot_buf, boot, -1); + /* 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"); }
- virCommandAddArgBuffer(cmd, &boot_buf); + } + + if (boot_nparams > 0) { + virCommandAddArg(cmd, "-boot"); + + if (boot_nparams < 2 || emitBootindex) { + virCommandAddArgBuffer(cmd, &boot_buf); + } else { + virCommandAddArgFormat(cmd, + "order=%s", + virBufferContentAndReset(&boot_buf)); + } }
if (def->os.kernel) @@ -7861,6 +7881,26 @@ error: }
+static void +qemuParseCommandLineBootDevs(virDomainDefPtr def, const char *str) { + int n, b = 0; + + for (n = 0 ; str[n] && b < VIR_DOMAIN_BOOT_LAST ; n++) { + if (str[n] == 'a') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_FLOPPY; + else if (str[n] == 'c') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_DISK; + else if (str[n] == 'd') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM; + else if (str[n] == 'n') + def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET; + else if (str[n] == ',') + break; + } + def->os.nBootDevs = b; +} + + /* * Analyse the env and argv settings and reconstruct a * virDomainDefPtr representing these settings as closely @@ -8218,24 +8258,27 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, if (!(def->os.cmdline = strdup(val))) goto no_memory; } else if (STREQ(arg, "-boot")) { - int n, b = 0; + const char *token = NULL; WANT_VALUE(); - for (n = 0 ; val[n] && b < VIR_DOMAIN_BOOT_LAST ; n++) { - if (val[n] == 'a') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_FLOPPY; - else if (val[n] == 'c') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_DISK; - else if (val[n] == 'd') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM; - else if (val[n] == 'n') - def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET; - else if (val[n] == ',') - break; - } - def->os.nBootDevs = b;
- if (strstr(val, "menu=on")) - def->os.bootmenu = 1; + if (!strchr(val, ',')) + qemuParseCommandLineBootDevs(def, val); + else { + token = val; + while (token && *token) { + if (STRPREFIX(token, "order=")) { + token += strlen("order="); + qemuParseCommandLineBootDevs(def, token); + } else if (STRPREFIX(token, "menu=on")) { + def->os.bootmenu = 1; + } + token = strchr(token, ','); + /* This incrementation has to be done here in order to make it + * possible to pass the token pointer properly into the loop */ + if (token) + token++; + } + } } else if (STREQ(arg, "-name")) { char *process; WANT_VALUE(); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args index 5074e32..75b6b4c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.args @@ -7,6 +7,7 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \ -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait \ -no-acpi \ +-boot menu=off \ -drive file=/dev/cdrom,if=none,media=cdrom,id=drive-ide0-1-0 \ -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0,bootindex=1 \ -usb \

Whenever the guest machine fails to boot, new parameter (reboot-timeout) controls whether it should reboot and after how many ms it should do so. Docs included. --- docs/formatdomain.html.in | 9 +++++++++ docs/schemas/domaincommon.rng | 20 ++++++++++++++++++++ src/conf/domain_conf.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 15 +++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 51f897c..b4050cf 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -106,6 +106,7 @@ <bootmenu enable='yes'/> <smbios mode='sysinfo'/> <bios useserial='yes'/> + <reboot-timeout enabled='yes' delay='0'/> </os> ...</pre> @@ -177,6 +178,14 @@ <a href="#elementCharSerial">serial port</a> defined. <span class="since">Since 0.9.4</span> </dd> + <dt><code>reboot-timeout</code></dt> + <dd>This element controls whether and after how long the guest should + start booting again in case the boot fails (according to BIOS). The + feature depends on mandatory parameter <code>enabled</enabled> with + values <code>yes</code> and <code>no</code>. When enabled, value of + the second parameter <code>delay</code> (in milliseconds) controls how + long before the boot starts again. Maximum delay is <code>65535</code> + milliseconds. <span class="since">QEMU since 0.10.2.</span></dd> </dl> <h4><a name="elementsOSBootloader">Host bootloader</a></h4> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index aafb10c..af3d856 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -264,6 +264,9 @@ <optional> <ref name="bios"/> </optional> + <optional> + <ref name="reboot-timeout"/> + </optional> </interleave> </element> </define> @@ -3199,6 +3202,23 @@ </element> </define> + <define name="reboot-timeout"> + <element name="reboot-timeout"> + <attribute name="enabled"> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + <optional> + <attribute name="delay"> + <ref name="unsignedShort"/> + </attribute> + </optional> + <empty/> + </element> + </define> + <define name="address"> <element name="address"> <choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 35814fb..98a39bb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -107,6 +107,11 @@ VIR_ENUM_IMPL(virDomainBootMenu, VIR_DOMAIN_BOOT_MENU_LAST, "yes", "no") +VIR_ENUM_IMPL(virDomainRebootTimeout, VIR_DOMAIN_REBOOT_TIMEOUT_LAST, + "default", + "yes", + "no") + VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "acpi", "apic", @@ -9788,6 +9793,32 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, def->os.smbios_mode = VIR_DOMAIN_SMBIOS_NONE; /* not present */ } + tmp = virXPathString("string(./os/reboot-timeout/@enabled)", ctxt); + if (tmp) { + int num = virDomainRebootTimeoutTypeFromString(tmp); + + if (num < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown value for reboot-timeout " + "enabled parameter '%s'"), tmp); + goto error; + } + + VIR_FREE(tmp); + def->os.rebootTimeout.enabled = num; + + if (num == VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED) { + if (virXPathInt("string(./os/reboot-timeout/@delay)", ctxt, &num) < 0 || + num < 0 || num > 0xffff) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("reboot-timeout delay value must " + "be in range [0,65535] and not")); + goto error; + } + def->os.rebootTimeout.delay = num; + } + } + /* Extract custom metadata */ if ((node = virXPathNode("./metadata[1]", ctxt)) != NULL) { def->metadata = xmlCopyNode(node, 1); @@ -13514,6 +13545,15 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAsprintf(buf, " <smbios mode='%s'/>\n", mode); } + if (def->os.rebootTimeout.enabled) { + virBufferAsprintf(buf, " <reboot-timeout enabled='%s'", + virDomainRebootTimeoutTypeToString(def->os.rebootTimeout.enabled)); + if (def->os.rebootTimeout.enabled == VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED) + virBufferAsprintf(buf, " delay='%d'", + def->os.rebootTimeout.delay); + virBufferAddLit(buf, "/>\n"); + } + virBufferAddLit(buf, " </os>\n"); if (def->features) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 510406a..c831d6d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1363,6 +1363,14 @@ enum virDomainBootMenu { VIR_DOMAIN_BOOT_MENU_LAST }; +enum virDomainRebootTimeout { + VIR_DOMAIN_REBOOT_TIMEOUT_DEFAULT = 0, + VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED, + VIR_DOMAIN_REBOOT_TIMEOUT_DISABLED, + + VIR_DOMAIN_REBOOT_TIMEOUT_LAST +}; + enum virDomainFeature { VIR_DOMAIN_FEATURE_ACPI, VIR_DOMAIN_FEATURE_APIC, @@ -1444,6 +1452,12 @@ struct _virDomainOSDef { char *bootloaderArgs; int smbios_mode; + struct { + /* enum virDomainRebootTimeout */ + int enabled; + int delay; + } rebootTimeout; + virDomainBIOSDef bios; }; @@ -2134,6 +2148,7 @@ VIR_ENUM_DECL(virDomainTaint) VIR_ENUM_DECL(virDomainVirt) VIR_ENUM_DECL(virDomainBoot) VIR_ENUM_DECL(virDomainBootMenu) +VIR_ENUM_DECL(virDomainRebootTimeout) VIR_ENUM_DECL(virDomainFeature) VIR_ENUM_DECL(virDomainApicEoi) VIR_ENUM_DECL(virDomainLifecycle) -- 1.7.12

On 18.09.2012 17:36, Martin Kletzander wrote:
Whenever the guest machine fails to boot, new parameter (reboot-timeout) controls whether it should reboot and after how many ms it should do so.
Docs included. --- docs/formatdomain.html.in | 9 +++++++++ docs/schemas/domaincommon.rng | 20 ++++++++++++++++++++ src/conf/domain_conf.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 15 +++++++++++++++ 4 files changed, 84 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 51f897c..b4050cf 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -106,6 +106,7 @@ <bootmenu enable='yes'/> <smbios mode='sysinfo'/> <bios useserial='yes'/> + <reboot-timeout enabled='yes' delay='0'/> </os> ...</pre>
@@ -177,6 +178,14 @@ <a href="#elementCharSerial">serial port</a> defined. <span class="since">Since 0.9.4</span> </dd> + <dt><code>reboot-timeout</code></dt> + <dd>This element controls whether and after how long the guest should + start booting again in case the boot fails (according to BIOS). The + feature depends on mandatory parameter <code>enabled</enabled> with + values <code>yes</code> and <code>no</code>. When enabled, value of + the second parameter <code>delay</code> (in milliseconds) controls how + long before the boot starts again. Maximum delay is <code>65535</code> + milliseconds. <span class="since">QEMU since 0.10.2.</span></dd> </dl>
Milliseconds is a bit overkill (too fine) for me. But I can see where is this coming from. So I can live with that.
<h4><a name="elementsOSBootloader">Host bootloader</a></h4> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index aafb10c..af3d856 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -264,6 +264,9 @@ <optional> <ref name="bios"/> </optional> + <optional> + <ref name="reboot-timeout"/> + </optional> </interleave> </element> </define> @@ -3199,6 +3202,23 @@ </element> </define>
+ <define name="reboot-timeout"> + <element name="reboot-timeout"> + <attribute name="enabled"> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + <optional> + <attribute name="delay"> + <ref name="unsignedShort"/> + </attribute> + </optional> + <empty/> + </element> + </define> +
Do we need 'enabled' and 'delay' at the same time? I mean, what if 'delay' would take [-1,65535] with -1 meaning its disabled?
<define name="address"> <element name="address"> <choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 35814fb..98a39bb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -107,6 +107,11 @@ VIR_ENUM_IMPL(virDomainBootMenu, VIR_DOMAIN_BOOT_MENU_LAST, "yes", "no")
+VIR_ENUM_IMPL(virDomainRebootTimeout, VIR_DOMAIN_REBOOT_TIMEOUT_LAST, + "default", + "yes", + "no") + VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "acpi", "apic", @@ -9788,6 +9793,32 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, def->os.smbios_mode = VIR_DOMAIN_SMBIOS_NONE; /* not present */ }
+ tmp = virXPathString("string(./os/reboot-timeout/@enabled)", ctxt); + if (tmp) { + int num = virDomainRebootTimeoutTypeFromString(tmp); + + if (num < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown value for reboot-timeout " + "enabled parameter '%s'"), tmp); + goto error; + } + + VIR_FREE(tmp); + def->os.rebootTimeout.enabled = num; + + if (num == VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED) { + if (virXPathInt("string(./os/reboot-timeout/@delay)", ctxt, &num) < 0 || + num < 0 || num > 0xffff) {
s/0xffff/65535/
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("reboot-timeout delay value must " + "be in range [0,65535] and not"));
unfinished sentence
+ goto error; + } + def->os.rebootTimeout.delay = num; + } + } + /* Extract custom metadata */ if ((node = virXPathNode("./metadata[1]", ctxt)) != NULL) { def->metadata = xmlCopyNode(node, 1); @@ -13514,6 +13545,15 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAsprintf(buf, " <smbios mode='%s'/>\n", mode); }
+ if (def->os.rebootTimeout.enabled) { + virBufferAsprintf(buf, " <reboot-timeout enabled='%s'", + virDomainRebootTimeoutTypeToString(def->os.rebootTimeout.enabled)); + if (def->os.rebootTimeout.enabled == VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED) + virBufferAsprintf(buf, " delay='%d'", + def->os.rebootTimeout.delay); + virBufferAddLit(buf, "/>\n"); + } + virBufferAddLit(buf, " </os>\n");
if (def->features) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 510406a..c831d6d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1363,6 +1363,14 @@ enum virDomainBootMenu { VIR_DOMAIN_BOOT_MENU_LAST };
+enum virDomainRebootTimeout { + VIR_DOMAIN_REBOOT_TIMEOUT_DEFAULT = 0, + VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED, + VIR_DOMAIN_REBOOT_TIMEOUT_DISABLED, + + VIR_DOMAIN_REBOOT_TIMEOUT_LAST +}; + enum virDomainFeature { VIR_DOMAIN_FEATURE_ACPI, VIR_DOMAIN_FEATURE_APIC, @@ -1444,6 +1452,12 @@ struct _virDomainOSDef { char *bootloaderArgs; int smbios_mode;
+ struct { + /* enum virDomainRebootTimeout */ + int enabled; + int delay; + } rebootTimeout; + virDomainBIOSDef bios; };
@@ -2134,6 +2148,7 @@ VIR_ENUM_DECL(virDomainTaint) VIR_ENUM_DECL(virDomainVirt) VIR_ENUM_DECL(virDomainBoot) VIR_ENUM_DECL(virDomainBootMenu) +VIR_ENUM_DECL(virDomainRebootTimeout) VIR_ENUM_DECL(virDomainFeature) VIR_ENUM_DECL(virDomainApicEoi) VIR_ENUM_DECL(virDomainLifecycle)
Take this as half ACK; I mean, the code is okay, but I am not sure about XML. Does anybody have any suggestions? Michal

On Tue, Sep 18, 2012 at 05:36:47PM +0200, Martin Kletzander wrote:
Whenever the guest machine fails to boot, new parameter (reboot-timeout) controls whether it should reboot and after how many ms it should do so.
Docs included. --- docs/formatdomain.html.in | 9 +++++++++ docs/schemas/domaincommon.rng | 20 ++++++++++++++++++++ src/conf/domain_conf.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 15 +++++++++++++++ 4 files changed, 84 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 51f897c..b4050cf 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -106,6 +106,7 @@ <bootmenu enable='yes'/> <smbios mode='sysinfo'/> <bios useserial='yes'/> + <reboot-timeout enabled='yes' delay='0'/>
I think it could be a bit misleading to have this element here. To me it suggests that it applies to OS reboots in general, where as it only really applies to the BIOS boot. Also having both an 'enabled' flag and 'delay' attribute is redundant. Surely delay=0 is the default and any non-zero value signifies it is enabled. I think I'd prefer to see <bootmenu enable='yes|no' rebootDelay='NNN'/> leave out the rebootDelay attribute when formatting XML if it is zero Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 09/18/2012 06:50 PM, Daniel P. Berrange wrote:
On Tue, Sep 18, 2012 at 05:36:47PM +0200, Martin Kletzander wrote:
Whenever the guest machine fails to boot, new parameter (reboot-timeout) controls whether it should reboot and after how many ms it should do so.
Docs included. --- docs/formatdomain.html.in | 9 +++++++++ docs/schemas/domaincommon.rng | 20 ++++++++++++++++++++ src/conf/domain_conf.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 15 +++++++++++++++ 4 files changed, 84 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 51f897c..b4050cf 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -106,6 +106,7 @@ <bootmenu enable='yes'/> <smbios mode='sysinfo'/> <bios useserial='yes'/> + <reboot-timeout enabled='yes' delay='0'/>
I think it could be a bit misleading to have this element here. To me it suggests that it applies to OS reboots in general, where as it only really applies to the BIOS boot. Also having both an 'enabled' flag and 'delay' attribute is redundant. Surely delay=0 is the default and any non-zero value signifies it is enabled.
I think I'd prefer to see
<bootmenu enable='yes|no' rebootDelay='NNN'/>
leave out the rebootDelay attribute when formatting XML if it is zero
Daniel
Thanks for suggestions, both of you. Inintially, I had that as reboot-timeout=[-1,65535], but since '0' is not the default [1], but a legitimate option (reboot immediately, which I guess I should've described in the commit message), I had a special value '-2' for the default and that's pretty awful without having virObject construct that due to virDomainDef initialization. With '-1' being the default, I had to come up with a system where zero(es) could be the default, but it would enable the use of '0' as an option as well. One version I've sent, the second one is having rebootTimeout as an int pointer and allocating the value when reboot-timeout is specified in the XML, which seems to me like an overkill for just one int. Martin [1] http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg00815.html

This patch adds support for "-boot reboot-timeout=rb_time" that is added in QEMU. --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 278b550..3582cbd 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -180,6 +180,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "ide-drive.wwn", "scsi-disk.wwn", "seccomp-sandbox", + + "reboot-timeout", /* 110 */ ); struct _qemuCaps { @@ -1191,6 +1193,8 @@ qemuCapsComputeCmdFlags(const char *help, qemuCapsSet(caps, QEMU_CAPS_NESTING); if (strstr(help, ",menu=on")) qemuCapsSet(caps, QEMU_CAPS_BOOT_MENU); + if (strstr(help, ",reboot-timeout=rb_time")) + qemuCapsSet(caps, QEMU_CAPS_REBOOT_TIMEOUT); if ((fsdev = strstr(help, "-fsdev"))) { qemuCapsSet(caps, QEMU_CAPS_FSDEV); if (strstr(fsdev, "readonly")) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 4da2a29..2201cb3 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -145,6 +145,7 @@ enum qemuCapsFlags { QEMU_CAPS_IDE_DRIVE_WWN = 107, /* Is ide-drive.wwn available? */ QEMU_CAPS_SCSI_DISK_WWN = 108, /* Is scsi-disk.wwn available? */ QEMU_CAPS_SECCOMP_SANDBOX = 109, /* -sandbox */ + QEMU_CAPS_REBOOT_TIMEOUT = 110, /* -boot reboot-timeout */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f8012ec..d35c5c3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4945,7 +4945,26 @@ qemuBuildCommandLine(virConnectPtr conn, VIR_WARN("bootmenu is enabled but not " "supported by this QEMU binary"); } + } + + if (def->os.rebootTimeout.enabled) { + if (!qemuCapsGet(caps, QEMU_CAPS_REBOOT_TIMEOUT)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("reboot timeout is not supported " + "by this QEMU binary")); + goto error; + } + if (boot_nparams++) + virBufferAddChar(&boot_buf, ','); + + if (def->os.rebootTimeout.enabled == VIR_DOMAIN_REBOOT_TIMEOUT_DISABLED) + virBufferAddLit(&boot_buf, + "reboot-timeout=-1"); + else + virBufferAsprintf(&boot_buf, + "reboot-timeout=%d", + def->os.rebootTimeout.delay); } if (boot_nparams > 0) { @@ -8271,6 +8290,23 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, qemuParseCommandLineBootDevs(def, token); } else if (STRPREFIX(token, "menu=on")) { def->os.bootmenu = 1; + } else if (STRPREFIX(token, "reboot-timeout=")) { + int num; + char *endptr = strchr(token, ','); + if (virStrToLong_i(token + strlen("reboot-timeout="), + &endptr, 0, &num) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot parse reboot-timeout value")); + goto error; + } + if (num < 0) { + def->os.rebootTimeout.enabled = VIR_DOMAIN_REBOOT_TIMEOUT_DISABLED; + } else { + def->os.rebootTimeout.enabled = VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED; + if (num > 0xffff) + num = 0xffff; + def->os.rebootTimeout.delay = num; + } } token = strchr(token, ','); /* This incrementation has to be done here in order to make it -- 1.7.12

On 18.09.2012 17:36, Martin Kletzander wrote:
This patch adds support for "-boot reboot-timeout=rb_time" that is added in QEMU. --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 278b550..3582cbd 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -180,6 +180,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "ide-drive.wwn", "scsi-disk.wwn", "seccomp-sandbox", + + "reboot-timeout", /* 110 */ );
struct _qemuCaps { @@ -1191,6 +1193,8 @@ qemuCapsComputeCmdFlags(const char *help, qemuCapsSet(caps, QEMU_CAPS_NESTING); if (strstr(help, ",menu=on")) qemuCapsSet(caps, QEMU_CAPS_BOOT_MENU); + if (strstr(help, ",reboot-timeout=rb_time")) + qemuCapsSet(caps, QEMU_CAPS_REBOOT_TIMEOUT); if ((fsdev = strstr(help, "-fsdev"))) { qemuCapsSet(caps, QEMU_CAPS_FSDEV); if (strstr(fsdev, "readonly")) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 4da2a29..2201cb3 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -145,6 +145,7 @@ enum qemuCapsFlags { QEMU_CAPS_IDE_DRIVE_WWN = 107, /* Is ide-drive.wwn available? */ QEMU_CAPS_SCSI_DISK_WWN = 108, /* Is scsi-disk.wwn available? */ QEMU_CAPS_SECCOMP_SANDBOX = 109, /* -sandbox */ + QEMU_CAPS_REBOOT_TIMEOUT = 110, /* -boot reboot-timeout */
QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f8012ec..d35c5c3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4945,7 +4945,26 @@ qemuBuildCommandLine(virConnectPtr conn, VIR_WARN("bootmenu is enabled but not " "supported by this QEMU binary"); } + } + + if (def->os.rebootTimeout.enabled) { + if (!qemuCapsGet(caps, QEMU_CAPS_REBOOT_TIMEOUT)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("reboot timeout is not supported " + "by this QEMU binary")); + goto error; + }
+ if (boot_nparams++) + virBufferAddChar(&boot_buf, ','); + + if (def->os.rebootTimeout.enabled == VIR_DOMAIN_REBOOT_TIMEOUT_DISABLED) + virBufferAddLit(&boot_buf, + "reboot-timeout=-1"); + else + virBufferAsprintf(&boot_buf, + "reboot-timeout=%d", + def->os.rebootTimeout.delay); }
if (boot_nparams > 0) { @@ -8271,6 +8290,23 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, qemuParseCommandLineBootDevs(def, token); } else if (STRPREFIX(token, "menu=on")) { def->os.bootmenu = 1; + } else if (STRPREFIX(token, "reboot-timeout=")) { + int num; + char *endptr = strchr(token, ','); + if (virStrToLong_i(token + strlen("reboot-timeout="), + &endptr, 0, &num) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot parse reboot-timeout value")); + goto error; + } + if (num < 0) { + def->os.rebootTimeout.enabled = VIR_DOMAIN_REBOOT_TIMEOUT_DISABLED; + } else { + def->os.rebootTimeout.enabled = VIR_DOMAIN_REBOOT_TIMEOUT_ENABLED; + if (num > 0xffff) + num = 0xffff; + def->os.rebootTimeout.delay = num;
s/0xffff/65535/g
+ } } token = strchr(token, ','); /* This incrementation has to be done here in order to make it
ACK Michal

--- tests/qemuargv2xmltest.c | 4 ++++ .../qemuxml2argv-reboot-timeout-disabled.args | 3 +++ .../qemuxml2argv-reboot-timeout-disabled.xml | 21 +++++++++++++++++++++ .../qemuxml2argv-reboot-timeout-enabled.args | 3 +++ .../qemuxml2argv-reboot-timeout-enabled.xml | 21 +++++++++++++++++++++ tests/qemuxml2argvtest.c | 5 +++++ tests/qemuxml2xmltest.c | 4 ++++ 7 files changed, 61 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index ad5f45b..c4c2cd9 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -151,6 +151,10 @@ mymain(void) /* Can't roundtrip xenner arch */ /*DO_TEST("bootloader");*/ + + DO_TEST("reboot-timeout-enabled"); + DO_TEST("reboot-timeout-disabled"); + DO_TEST("clock-utc"); DO_TEST("clock-localtime"); DO_TEST("disk-cdrom"); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args new file mode 100644 index 0000000..1a2bf4d --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args @@ -0,0 +1,3 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \ +-m 214 -smp 6 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot order=n,reboot-timeout=-1 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml new file mode 100644 index 0000000..c361fa8 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml @@ -0,0 +1,21 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>6</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='network'/> + <reboot-timeout enabled='no'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <controller type='usb' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args new file mode 100644 index 0000000..ab18b30 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args @@ -0,0 +1,3 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \ +-m 214 -smp 6 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot order=n,reboot-timeout=128 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml new file mode 100644 index 0000000..21e5dc1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml @@ -0,0 +1,21 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>6</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='network'/> + <reboot-timeout enabled='yes' delay='128'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <controller type='usb' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 0ec3c2c..629d767 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -373,6 +373,11 @@ mymain(void) QEMU_CAPS_BOOTINDEX, QEMU_CAPS_VIRTIO_BLK_SCSI, QEMU_CAPS_VIRTIO_BLK_SG_IO); DO_TEST("bootloader", QEMU_CAPS_DOMID, QEMU_CAPS_KVM); + + DO_TEST("reboot-timeout-disabled", QEMU_CAPS_REBOOT_TIMEOUT); + DO_TEST("reboot-timeout-enabled", QEMU_CAPS_REBOOT_TIMEOUT); + DO_TEST_FAILURE("reboot-timeout-enabled", NONE); + DO_TEST("bios", QEMU_CAPS_DEVICE, QEMU_CAPS_SGA); DO_TEST("clock-utc", NONE); DO_TEST("clock-localtime", NONE); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0a6da98..b968566 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -133,6 +133,10 @@ mymain(void) DO_TEST("boot-menu-disable"); DO_TEST("boot-order"); DO_TEST("bootloader"); + + DO_TEST("reboot-timeout-enabled"); + DO_TEST("reboot-timeout-disabled"); + DO_TEST("clock-utc"); DO_TEST("clock-localtime"); DO_TEST("cpu-kvmclock"); -- 1.7.12

On 18.09.2012 17:36, Martin Kletzander wrote:
--- tests/qemuargv2xmltest.c | 4 ++++ .../qemuxml2argv-reboot-timeout-disabled.args | 3 +++ .../qemuxml2argv-reboot-timeout-disabled.xml | 21 +++++++++++++++++++++ .../qemuxml2argv-reboot-timeout-enabled.args | 3 +++ .../qemuxml2argv-reboot-timeout-enabled.xml | 21 +++++++++++++++++++++ tests/qemuxml2argvtest.c | 5 +++++ tests/qemuxml2xmltest.c | 4 ++++ 7 files changed, 61 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml
ACK Michal

On 18.09.2012 17:36, Martin Kletzander wrote:
This series introduces simple reboot timeout support. That means what should be done in case all boot options fail, reboot or not. And if yes, then how long the machine should wait.
Before adding the support for that into XML parser, builder, and qemu, I felt the need to cleanup the boot parsing and enums (I couldn't look at that), so that's the first patch. Most of it is mechanical, the rest should be pretty straight-forward. --- I'd *love* to have it in 0.10.2, but I understand if it's too late :(
I don't feel like the one to make such decision but I'll review the patches anyway.
Martin Kletzander (4): qemu: Cleanup boot parameter building Add support for reboot-timeout qemu: Add support for reboot-timeout QEMU Tests for reboot-timeout
docs/formatdomain.html.in | 9 ++ docs/schemas/domaincommon.rng | 20 ++++ src/conf/domain_conf.c | 56 ++++++++- src/conf/domain_conf.h | 78 ++++++++----- src/libvirt_private.syms | 2 + src/qemu/qemu_capabilities.c | 4 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 129 +++++++++++++++++---- tests/qemuargv2xmltest.c | 4 + ...xml2argv-boot-menu-disable-drive-bootindex.args | 1 + .../qemuxml2argv-reboot-timeout-disabled.args | 3 + .../qemuxml2argv-reboot-timeout-disabled.xml | 21 ++++ .../qemuxml2argv-reboot-timeout-enabled.args | 3 + .../qemuxml2argv-reboot-timeout-enabled.xml | 21 ++++ tests/qemuxml2argvtest.c | 5 + tests/qemuxml2xmltest.c | 4 + 16 files changed, 304 insertions(+), 57 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-disabled.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-reboot-timeout-enabled.xml
-- 1.7.12
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (3)
-
Daniel P. Berrange
-
Martin Kletzander
-
Michal Privoznik