summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml111
-rw-r--r--HACKING55
-rw-r--r--MAINTAINERS6
-rw-r--r--block/io.c1
-rw-r--r--blockjob.c6
-rw-r--r--hw/arm/imx25_pdk.c7
-rw-r--r--hw/arm/kzm.c7
-rw-r--r--hw/arm/netduino2.c7
-rw-r--r--hw/arm/xlnx-ep108.c7
-rw-r--r--include/block/blockjob.h5
-rw-r--r--include/qapi/error.h15
-rw-r--r--include/qemu/iov.h34
-rw-r--r--util/iov.c8
-rw-r--r--vl.c7
14 files changed, 192 insertions, 84 deletions
diff --git a/.travis.yml b/.travis.yml
index 0428aed0ec..9e5873b28c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,38 @@
+sudo: false
language: c
python:
- "2.4"
compiler:
- gcc
- clang
+cache: ccache
+addons:
+ apt:
+ packages:
+ - libaio-dev
+ - libattr1-dev
+ - libbrlapi-dev
+ - libcap-ng-dev
+ - libgnutls-dev
+ - libgtk-3-dev
+ - libiscsi-dev
+ - liblttng-ust-dev
+ - libncurses5-dev
+ - libnss3-dev
+ - libpixman-1-dev
+ - libpng12-dev
+ - librados-dev
+ - libsdl1.2-dev
+ - libseccomp-dev
+ - libspice-protocol-dev
+ - libspice-server-dev
+ - libssh2-1-dev
+ - liburcu-dev
+ - libusb-1.0-0-dev
+ - libvte-2.90-dev
+ - sparse
+ - uuid-dev
+
notifications:
irc:
channels:
@@ -12,29 +41,16 @@ notifications:
on_failure: always
env:
global:
- - TEST_CMD=""
+ - TEST_CMD="make check"
- EXTRA_CONFIG=""
- # Development packages, EXTRA_PKGS saved for additional builds
- - CORE_PKGS="libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev"
- - NET_PKGS="libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev libspice-protocol-dev libnss3-dev"
- - GUI_PKGS="libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev"
- - EXTRA_PKGS=""
matrix:
# Group major targets together with their linux-user counterparts
- - TARGETS=alpha-softmmu,alpha-linux-user
+ - TARGETS=alpha-softmmu,alpha-linux-user,cris-softmmu,cris-linux-user,m68k-softmmu,m68k-linux-user,microblaze-softmmu,microblazeel-softmmu,microblaze-linux-user,microblazeel-linux-user
- TARGETS=arm-softmmu,arm-linux-user,armeb-linux-user,aarch64-softmmu,aarch64-linux-user
- - TARGETS=cris-softmmu,cris-linux-user
- TARGETS=i386-softmmu,i386-linux-user,x86_64-softmmu,x86_64-linux-user
- - TARGETS=m68k-softmmu,m68k-linux-user
- - TARGETS=microblaze-softmmu,microblazeel-softmmu,microblaze-linux-user,microblazeel-linux-user
- - TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
- - TARGETS=mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,mipsn32-linux-user,mipsn32el-linux-user
- - TARGETS=or32-softmmu,or32-linux-user
- - TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu,ppc-linux-user,ppc64-linux-user,ppc64abi32-linux-user,ppc64le-linux-user
- - TARGETS=s390x-softmmu,s390x-linux-user
- - TARGETS=sh4-softmmu,sh4eb-softmmu,sh4-linux-user sh4eb-linux-user
- - TARGETS=sparc-softmmu,sparc64-softmmu,sparc-linux-user,sparc32plus-linux-user,sparc64-linux-user
- - TARGETS=unicore32-softmmu,unicore32-linux-user
+ - TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,mipsn32-linux-user,mipsn32el-linux-user
+ - TARGETS=or32-softmmu,or32-linux-user,ppc-softmmu,ppc64-softmmu,ppcemb-softmmu,ppc-linux-user,ppc64-linux-user,ppc64abi32-linux-user,ppc64le-linux-user
+ - TARGETS=s390x-softmmu,s390x-linux-user,sh4-softmmu,sh4eb-softmmu,sh4-linux-user,sh4eb-linux-user,sparc-softmmu,sparc64-softmmu,sparc-linux-user,sparc32plus-linux-user,sparc64-linux-user,unicore32-softmmu,unicore32-linux-user
# Group remaining softmmu only targets into one build
- TARGETS=lm32-softmmu,moxie-softmmu,tricore-softmmu,xtensa-softmmu,xtensaeb-softmmu
git:
@@ -43,8 +59,6 @@ git:
before_install:
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
- - sudo apt-get update -qq
- - sudo apt-get install -qq ${CORE_PKGS} ${NET_PKGS} ${GUI_PKGS} ${EXTRA_PKGS}
before_script:
- ./configure --target-list=${TARGETS} --enable-debug-tcg ${EXTRA_CONFIG}
script:
@@ -52,44 +66,59 @@ script:
matrix:
# We manually include a number of additional build for non-standard bits
include:
- # Make check target (we only do this once)
- - env:
- - TARGETS=alpha-softmmu,arm-softmmu,aarch64-softmmu,cris-softmmu,i386-softmmu,x86_64-softmmu,m68k-softmmu,microblaze-softmmu,microblazeel-softmmu,mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu,or32-softmmu,ppc-softmmu,ppc64-softmmu,ppcemb-softmmu,s390x-softmmu,sh4-softmmu,sh4eb-softmmu,sparc-softmmu,sparc64-softmmu,unicore32-softmmu,unicore32-linux-user,lm32-softmmu,moxie-softmmu,tricore-softmmu,xtensa-softmmu,xtensaeb-softmmu
- TEST_CMD="make check"
- compiler: gcc
# Debug related options
- - env: TARGETS=i386-softmmu,x86_64-softmmu
+ - env: TARGETS=x86_64-softmmu
EXTRA_CONFIG="--enable-debug"
compiler: gcc
- - env: TARGETS=i386-softmmu,x86_64-softmmu
+ # We currently disable "make check"
+ - env: TARGETS=alpha-softmmu
EXTRA_CONFIG="--enable-debug --enable-tcg-interpreter"
+ TEST_CMD=""
compiler: gcc
- # All the extra -dev packages
- - env: TARGETS=i386-softmmu,x86_64-softmmu
- EXTRA_PKGS="libaio-dev libcap-ng-dev libattr1-dev libbrlapi-dev uuid-dev libusb-1.0.0-dev"
+ # Disable a few of the optional features
+ - env: TARGETS=x86_64-softmmu
+ EXTRA_CONFIG="--disable-linux-aio --disable-cap-ng --disable-attr --disable-brlapi --disable-uuid --disable-libusb"
compiler: gcc
# Currently configure doesn't force --disable-pie
- - env: TARGETS=i386-softmmu,x86_64-softmmu
+ - env: TARGETS=x86_64-softmmu
EXTRA_CONFIG="--enable-gprof --enable-gcov --disable-pie"
compiler: gcc
- - env: TARGETS=i386-softmmu,x86_64-softmmu
- EXTRA_PKGS="sparse"
+ # Sparse
+ - env: TARGETS=x86_64-softmmu
EXTRA_CONFIG="--enable-sparse"
compiler: gcc
+ # Modules
+ - env: TARGETS=arm-softmmu,x86_64-softmmu
+ EXTRA_CONFIG="--enable-modules"
+ compiler: gcc
# All the trace backends (apart from dtrace)
- - env: TARGETS=i386-softmmu,x86_64-softmmu
+ - env: TARGETS=i386-softmmu
EXTRA_CONFIG="--enable-trace-backends=log"
compiler: gcc
- - env: TARGETS=i386-softmmu,x86_64-softmmu
+ # We currently disable "make check" (until 41fc57e44ed regression fixed)
+ - env: TARGETS=x86_64-softmmu
EXTRA_CONFIG="--enable-trace-backends=simple"
+ TEST_CMD=""
compiler: gcc
- - env: TARGETS=i386-softmmu,x86_64-softmmu
+ # We currently disable "make check"
+ - env: TARGETS=x86_64-softmmu
EXTRA_CONFIG="--enable-trace-backends=ftrace"
+ TEST_CMD=""
compiler: gcc
- - env: TARGETS=i386-softmmu,x86_64-softmmu
- EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
- EXTRA_CONFIG="--enable-trace-backends=ust"
+ # We currently disable "make check"
+ - env: TARGETS=x86_64-softmmu
+ EXTRA_CONFIG="--enable-trace-backends=ust"
+ TEST_CMD=""
compiler: gcc
- - env: TARGETS=i386-softmmu,x86_64-softmmu
- EXTRA_CONFIG="--enable-modules"
+ # All the co-routine backends (apart from windows)
+ # We currently disable "make check"
+ - env: TARGETS=x86_64-softmmu
+ EXTRA_CONFIG="--with-coroutine=gthread"
+ TEST_CMD=""
+ compiler: gcc
+ - env: TARGETS=x86_64-softmmu
+ EXTRA_CONFIG="--with-coroutine=ucontext"
+ compiler: gcc
+ - env: TARGETS=x86_64-softmmu
+ EXTRA_CONFIG="--with-coroutine=sigaltstack"
compiler: gcc
diff --git a/HACKING b/HACKING
index 12fbc8afe4..058aa8fd49 100644
--- a/HACKING
+++ b/HACKING
@@ -157,3 +157,58 @@ painful. These are:
* you may assume that integers are 2s complement representation
* you may assume that right shift of a signed integer duplicates
the sign bit (ie it is an arithmetic shift, not a logical shift)
+
+7. Error handling and reporting
+
+7.1 Reporting errors to the human user
+
+Do not use printf(), fprintf() or monitor_printf(). Instead, use
+error_report() or error_vreport() from error-report.h. This ensures the
+error is reported in the right place (current monitor or stderr), and in
+a uniform format.
+
+Use error_printf() & friends to print additional information.
+
+error_report() prints the current location. In certain common cases
+like command line parsing, the current location is tracked
+automatically. To manipulate it manually, use the loc_*() from
+error-report.h.
+
+7.2 Propagating errors
+
+An error can't always be reported to the user right where it's detected,
+but often needs to be propagated up the call chain to a place that can
+handle it. This can be done in various ways.
+
+The most flexible one is Error objects. See error.h for usage
+information.
+
+Use the simplest suitable method to communicate success / failure to
+callers. Stick to common methods: non-negative on success / -1 on
+error, non-negative / -errno, non-null / null, or Error objects.
+
+Example: when a function returns a non-null pointer on success, and it
+can fail only in one way (as far as the caller is concerned), returning
+null on failure is just fine, and certainly simpler and a lot easier on
+the eyes than propagating an Error object through an Error ** parameter.
+
+Example: when a function's callers need to report details on failure
+only the function really knows, use Error **, and set suitable errors.
+
+Do not report an error to the user when you're also returning an error
+for somebody else to handle. Leave the reporting to the place that
+consumes the error returned.
+
+7.3 Handling errors
+
+Calling exit() is fine when handling configuration errors during
+startup. It's problematic during normal operation. In particular,
+monitor commands should never exit().
+
+Do not call exit() or abort() to handle an error that can be triggered
+by the guest (e.g., some unimplemented corner case in guest code
+translation or device emulation). Guests should not be able to
+terminate QEMU.
+
+Note that &error_fatal is just another way to exit(1), and &error_abort
+is just another way to abort().
diff --git a/MAINTAINERS b/MAINTAINERS
index 2d78eea5d6..02710f857c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1571,6 +1571,12 @@ L: qemu-block@nongnu.org
S: Supported
F: tests/image-fuzzer/
+Build and test automation
+-------------------------
+M: Alex Bennée <alex.bennee@linaro.org>
+L: qemu-devel@nongnu.org
+S: Supported
+F: .travis.yml
Documentation
-------------
diff --git a/block/io.c b/block/io.c
index 343ff1f233..a69bfc4197 100644
--- a/block/io.c
+++ b/block/io.c
@@ -301,6 +301,7 @@ void bdrv_drain_all(void)
if (bs->job) {
block_job_pause(bs->job);
}
+ bdrv_drain_recurse(bs);
aio_context_release(aio_context);
if (!g_slist_find(aio_ctxs, aio_context)) {
diff --git a/blockjob.c b/blockjob.c
index a402181835..9fc37ca965 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -296,7 +296,9 @@ static int block_job_finish_sync(BlockJob *job,
return -EBUSY;
}
while (!job->completed) {
- aio_poll(bdrv_get_aio_context(bs), true);
+ aio_poll(job->deferred_to_main_loop ? qemu_get_aio_context() :
+ bdrv_get_aio_context(bs),
+ true);
}
ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;
block_job_unref(job);
@@ -470,6 +472,7 @@ static void block_job_defer_to_main_loop_bh(void *opaque)
aio_context = bdrv_get_aio_context(data->job->bs);
aio_context_acquire(aio_context);
+ data->job->deferred_to_main_loop = false;
data->fn(data->job, data->opaque);
aio_context_release(aio_context);
@@ -489,6 +492,7 @@ void block_job_defer_to_main_loop(BlockJob *job,
data->aio_context = bdrv_get_aio_context(job->bs);
data->fn = fn;
data->opaque = opaque;
+ job->deferred_to_main_loop = true;
qemu_bh_schedule(data->bh);
}
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
index b167e19f5a..e3cffd190c 100644
--- a/hw/arm/imx25_pdk.c
+++ b/hw/arm/imx25_pdk.c
@@ -65,7 +65,6 @@ static struct arm_boot_info imx25_pdk_binfo;
static void imx25_pdk_init(MachineState *machine)
{
IMX25PDK *s = g_new0(IMX25PDK, 1);
- Error *err = NULL;
unsigned int ram_size;
unsigned int alias_offset;
int i;
@@ -74,11 +73,7 @@ static void imx25_pdk_init(MachineState *machine)
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
&error_abort);
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
- if (err != NULL) {
- error_report_err(err);
- exit(1);
- }
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
/* We need to initialize our memory */
if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 55fb36021c..2eeb9d8973 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -64,7 +64,6 @@ static struct arm_boot_info kzm_binfo = {
static void kzm_init(MachineState *machine)
{
IMX31KZM *s = g_new0(IMX31KZM, 1);
- Error *err = NULL;
unsigned int ram_size;
unsigned int alias_offset;
unsigned int i;
@@ -73,11 +72,7 @@ static void kzm_init(MachineState *machine)
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
&error_abort);
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
- if (err != NULL) {
- error_report_err(err);
- exit(1);
- }
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
/* Check the amount of memory is compatible with the SOC */
if (machine->ram_size > (FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE)) {
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
index 86065d360a..49da6e360d 100644
--- a/hw/arm/netduino2.c
+++ b/hw/arm/netduino2.c
@@ -30,18 +30,13 @@
static void netduino2_init(MachineState *machine)
{
DeviceState *dev;
- Error *err = NULL;
dev = qdev_create(NULL, TYPE_STM32F205_SOC);
if (machine->kernel_filename) {
qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
}
qdev_prop_set_string(dev, "cpu-model", "cortex-m3");
- object_property_set_bool(OBJECT(dev), true, "realized", &err);
- if (err != NULL) {
- error_report_err(err);
- exit(1);
- }
+ object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
}
static void netduino2_machine_init(MachineClass *mc)
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 2cd69b5faf..0de132abd2 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -32,7 +32,6 @@ static void xlnx_ep108_init(MachineState *machine)
{
XlnxEP108 *s = g_new0(XlnxEP108, 1);
int i;
- Error *err = NULL;
uint64_t ram_size = machine->ram_size;
/* Create the memory region to pass to the SoC */
@@ -58,11 +57,7 @@ static void xlnx_ep108_init(MachineState *machine)
object_property_set_link(OBJECT(&s->soc), OBJECT(&s->ddr_ram),
"ddr-ram", &error_abort);
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
- if (err) {
- error_report_err(err);
- exit(1);
- }
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
SSIBus *spi_bus;
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index d84ccd8d2c..8bedc4936c 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -130,6 +130,11 @@ struct BlockJob {
*/
bool ready;
+ /**
+ * Set to true when the job has deferred work to the main loop.
+ */
+ bool deferred_to_main_loop;
+
/** Status that is published by the query-block-jobs QMP API */
BlockDeviceIoStatus iostatus;
diff --git a/include/qapi/error.h b/include/qapi/error.h
index 45d6c72dee..e64fe54cf9 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -27,11 +27,11 @@
* error_setg(&err, "invalid quark\n"
* "Valid quarks are up, down, strange, charm, top, bottom.");
*
- * Report an error to stderr:
+ * Report an error to the current monitor if we have one, else stderr:
* error_report_err(err);
* This frees the error object.
*
- * Report an error to stderr with additional text prepended:
+ * Likewise, but with additional text prepended:
* error_reportf_err(err, "Could not frobnicate '%s': ", name);
*
* Report an error somewhere else:
@@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);
* human-readable error message is made from printf-style @fmt, ...
* The resulting message should be a single phrase, with no newline or
* trailing punctuation.
+ * Please don't error_setg(&error_fatal, ...), use error_report() and
+ * exit(), because that's more obvious.
+ * Likewise, don't error_setg(&error_abort, ...), use assert().
*/
#define error_setg(errp, fmt, ...) \
error_setg_internal((errp), __FILE__, __LINE__, __func__, \
@@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,
* the error object.
* Else, move the error object from @local_err to *@dst_errp.
* On return, @local_err is invalid.
+ * Please don't error_propagate(&error_fatal, ...), use
+ * error_report_err() and exit(), because that's more obvious.
*/
void error_propagate(Error **dst_errp, Error *local_err);
@@ -291,12 +296,14 @@ void error_set_internal(Error **errp,
GCC_FMT_ATTR(6, 7);
/*
- * Pass to error_setg() & friends to abort() on error.
+ * Special error destination to abort on error.
+ * See error_setg() and error_propagate() for details.
*/
extern Error *error_abort;
/*
- * Pass to error_setg() & friends to exit(1) on error.
+ * Special error destination to exit(1) on error.
+ * See error_setg() and error_propagate() for details.
*/
extern Error *error_fatal;
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
index 569b2c2a23..28475516eb 100644
--- a/include/qemu/iov.h
+++ b/include/qemu/iov.h
@@ -39,10 +39,36 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
* such "large" value is -1 (sinice size_t is unsigned),
* so specifying `-1' as `bytes' means 'up to the end of iovec'.
*/
-size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
- size_t offset, const void *buf, size_t bytes);
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
- size_t offset, void *buf, size_t bytes);
+size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
+ size_t offset, const void *buf, size_t bytes);
+size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
+ size_t offset, void *buf, size_t bytes);
+
+static inline size_t
+iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
+ size_t offset, const void *buf, size_t bytes)
+{
+ if (__builtin_constant_p(bytes) && iov_cnt &&
+ offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset) {
+ memcpy(iov[0].iov_base + offset, buf, bytes);
+ return bytes;
+ } else {
+ return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
+ }
+}
+
+static inline size_t
+iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+ size_t offset, void *buf, size_t bytes)
+{
+ if (__builtin_constant_p(bytes) && iov_cnt &&
+ offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset) {
+ memcpy(buf, iov[0].iov_base + offset, bytes);
+ return bytes;
+ } else {
+ return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
+ }
+}
/**
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
diff --git a/util/iov.c b/util/iov.c
index e802ee15bc..062f4e50c3 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -20,8 +20,8 @@
#include "qemu/iov.h"
#include "qemu/sockets.h"
-size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
- size_t offset, const void *buf, size_t bytes)
+size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
+ size_t offset, const void *buf, size_t bytes)
{
size_t done;
unsigned int i;
@@ -39,8 +39,8 @@ size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
return done;
}
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
- size_t offset, void *buf, size_t bytes)
+size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
+ size_t offset, void *buf, size_t bytes)
{
size_t done;
unsigned int i;
diff --git a/vl.c b/vl.c
index 00dc9979e1..175ebccb81 100644
--- a/vl.c
+++ b/vl.c
@@ -4557,12 +4557,7 @@ int main(int argc, char **argv, char **envp)
net_check_clients();
if (boot_once) {
- Error *local_err = NULL;
- qemu_boot_set(boot_once, &local_err);
- if (local_err) {
- error_report_err(local_err);
- exit(1);
- }
+ qemu_boot_set(boot_once, &error_fatal);
qemu_register_reset(restore_boot_order, g_strdup(boot_order));
}