From 0046c45bc1c70b5b985822f8639bb718f6d535a5 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Fri, 30 Sep 2011 19:28:45 +0200 Subject: savevm: teach qemu_fill_buffer to do partial refills We will need on next patch to be able to lookahead on next patch v2: rename "used" to "pending" (Alex Williams) Signed-off-by: Juan Quintela Reviewed-by: Anthony Liguori --- savevm.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index bf4d0e76c3..aa6fef08ab 100644 --- a/savevm.c +++ b/savevm.c @@ -455,6 +455,7 @@ void qemu_fflush(QEMUFile *f) static void qemu_fill_buffer(QEMUFile *f) { int len; + int pending; if (!f->get_buffer) return; @@ -462,10 +463,17 @@ static void qemu_fill_buffer(QEMUFile *f) if (f->is_write) abort(); - len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE); + pending = f->buf_size - f->buf_index; + if (pending > 0) { + memmove(f->buf, f->buf + f->buf_index, pending); + } + f->buf_index = 0; + f->buf_size = pending; + + len = f->get_buffer(f->opaque, f->buf + pending, f->buf_offset, + IO_BUF_SIZE - pending); if (len > 0) { - f->buf_index = 0; - f->buf_size = len; + f->buf_size += len; f->buf_offset += len; } else if (len != -EAGAIN) f->has_error = 1; -- cgit v1.2.3 From b9ce1454e14ec918acb90d899ce7724f69682f45 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 4 Oct 2011 13:55:32 +0200 Subject: savevm: some coding style cleanups This patch will make moving code on next patches and having checkpatch happy easier. Signed-off-by: Juan Quintela Reviewed-by: Anthony Liguori --- savevm.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index aa6fef08ab..6e4bb3a3df 100644 --- a/savevm.c +++ b/savevm.c @@ -536,8 +536,9 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) { int size, l; - if (f->is_write) + if (f->is_write) { abort(); + } size = size1; while (size > 0) { @@ -545,11 +546,13 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) if (l == 0) { qemu_fill_buffer(f); l = f->buf_size - f->buf_index; - if (l == 0) + if (l == 0) { break; + } } - if (l > size) + if (l > size) { l = size; + } memcpy(buf, f->buf + f->buf_index, l); f->buf_index += l; buf += l; @@ -560,26 +563,30 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) static int qemu_peek_byte(QEMUFile *f) { - if (f->is_write) + if (f->is_write) { abort(); + } if (f->buf_index >= f->buf_size) { qemu_fill_buffer(f); - if (f->buf_index >= f->buf_size) + if (f->buf_index >= f->buf_size) { return 0; + } } return f->buf[f->buf_index]; } int qemu_get_byte(QEMUFile *f) { - if (f->is_write) + if (f->is_write) { abort(); + } if (f->buf_index >= f->buf_size) { qemu_fill_buffer(f); - if (f->buf_index >= f->buf_size) + if (f->buf_index >= f->buf_size) { return 0; + } } return f->buf[f->buf_index++]; } -- cgit v1.2.3 From 65f3bb3da3d5b46daebbfc54bd41ee493fdaba86 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 6 Oct 2011 14:29:32 +0200 Subject: savevm: define qemu_get_byte() using qemu_peek_byte() Signed-off-by: Juan Quintela --- savevm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index 6e4bb3a3df..038099979e 100644 --- a/savevm.c +++ b/savevm.c @@ -578,17 +578,14 @@ static int qemu_peek_byte(QEMUFile *f) int qemu_get_byte(QEMUFile *f) { - if (f->is_write) { - abort(); - } + int result; - if (f->buf_index >= f->buf_size) { - qemu_fill_buffer(f); - if (f->buf_index >= f->buf_size) { - return 0; - } + result = qemu_peek_byte(f); + + if (f->buf_index < f->buf_size) { + f->buf_index++; } - return f->buf[f->buf_index++]; + return result; } int64_t qemu_ftell(QEMUFile *f) -- cgit v1.2.3 From c63807244fb55071675907460a0ecf228c1766c8 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 4 Oct 2011 15:28:31 +0200 Subject: savevm: improve subsections detection on load We add qemu_peek_buffer, that is identical to qemu_get_buffer, just that it don't update f->buf_index. We add a paramenter to qemu_peek_byte() to be able to peek more than one byte. Once this is done, to see if we have a subsection we look: - 1st byte is QEMU_VM_SUBSECTION - 2nd byte is a length, and is bigger than section name - 3rd element is a string that starts with section_name So, we shouldn't have false positives (yes, content could still get us wrong but probabilities are really low). v2: - Alex Williamsom found that we could get negative values on index. - Rework code to fix that part. - Rewrite qemu_get_buffer() using qemu_peek_buffer() v3: - return "done" on error case v4: - fix qemu_file_skip() off by one. Signed-off-by: Juan Quintela --- savevm.c | 110 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 35 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index 038099979e..a4cb3157bb 100644 --- a/savevm.c +++ b/savevm.c @@ -532,59 +532,85 @@ void qemu_put_byte(QEMUFile *f, int v) qemu_fflush(f); } -int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) +static void qemu_file_skip(QEMUFile *f, int size) { - int size, l; + if (f->buf_index + size <= f->buf_size) { + f->buf_index += size; + } +} + +static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset) +{ + int pending; + int index; if (f->is_write) { abort(); } - size = size1; - while (size > 0) { - l = f->buf_size - f->buf_index; - if (l == 0) { - qemu_fill_buffer(f); - l = f->buf_size - f->buf_index; - if (l == 0) { - break; - } - } - if (l > size) { - l = size; + index = f->buf_index + offset; + pending = f->buf_size - index; + if (pending < size) { + qemu_fill_buffer(f); + index = f->buf_index + offset; + pending = f->buf_size - index; + } + + if (pending <= 0) { + return 0; + } + if (size > pending) { + size = pending; + } + + memcpy(buf, f->buf + index, size); + return size; +} + +int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size) +{ + int pending = size; + int done = 0; + + while (pending > 0) { + int res; + + res = qemu_peek_buffer(f, buf, pending, 0); + if (res == 0) { + return done; } - memcpy(buf, f->buf + f->buf_index, l); - f->buf_index += l; - buf += l; - size -= l; + qemu_file_skip(f, res); + buf += res; + pending -= res; + done += res; } - return size1 - size; + return done; } -static int qemu_peek_byte(QEMUFile *f) +static int qemu_peek_byte(QEMUFile *f, int offset) { + int index = f->buf_index + offset; + if (f->is_write) { abort(); } - if (f->buf_index >= f->buf_size) { + if (index >= f->buf_size) { qemu_fill_buffer(f); - if (f->buf_index >= f->buf_size) { + index = f->buf_index + offset; + if (index >= f->buf_size) { return 0; } } - return f->buf[f->buf_index]; + return f->buf[index]; } int qemu_get_byte(QEMUFile *f) { int result; - result = qemu_peek_byte(f); - - if (f->buf_index < f->buf_size) { - f->buf_index++; - } + result = qemu_peek_byte(f, 0); + qemu_file_skip(f, 1); return result; } @@ -1684,22 +1710,36 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, return 0; } - while (qemu_peek_byte(f) == QEMU_VM_SUBSECTION) { + while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) { char idstr[256]; int ret; - uint8_t version_id, len; + uint8_t version_id, len, size; const VMStateDescription *sub_vmsd; - qemu_get_byte(f); /* subsection */ - len = qemu_get_byte(f); - qemu_get_buffer(f, (uint8_t *)idstr, len); - idstr[len] = 0; - version_id = qemu_get_be32(f); + len = qemu_peek_byte(f, 1); + if (len < strlen(vmsd->name) + 1) { + /* subsection name has be be "section_name/a" */ + return 0; + } + size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2); + if (size != len) { + return 0; + } + idstr[size] = 0; + if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) { + /* it don't have a valid subsection name */ + return 0; + } sub_vmsd = vmstate_get_subsection(sub, idstr); if (sub_vmsd == NULL) { return -ENOENT; } + qemu_file_skip(f, 1); /* subsection */ + qemu_file_skip(f, 1); /* len */ + qemu_file_skip(f, len); /* idstr */ + version_id = qemu_get_be32(f); + assert(!sub_vmsd->subsections); ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); if (ret) { -- cgit v1.2.3 From 3da9eebda96780ead8ba44b8140c54f4a54c61f6 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Fri, 30 Sep 2011 19:46:43 +0200 Subject: Revert "savevm: fix corruption in vmstate_subsection_load()." This reverts commit eb60260de0b050a5e8ab725e84d377d0b44c43ae. Conflicts: savevm.c We changed qemu_peek_byte() prototype, just fixed the rejects. Signed-off-by: Juan Quintela Reviewed-by: Anthony Liguori --- savevm.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index a4cb3157bb..ca9e233c9a 100644 --- a/savevm.c +++ b/savevm.c @@ -1704,12 +1704,6 @@ static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, void *opaque) { - const VMStateSubsection *sub = vmsd->subsections; - - if (!sub || !sub->needed) { - return 0; - } - while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) { char idstr[256]; int ret; @@ -1731,7 +1725,7 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, /* it don't have a valid subsection name */ return 0; } - sub_vmsd = vmstate_get_subsection(sub, idstr); + sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr); if (sub_vmsd == NULL) { return -ENOENT; } @@ -1740,7 +1734,6 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, qemu_file_skip(f, len); /* idstr */ version_id = qemu_get_be32(f); - assert(!sub_vmsd->subsections); ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); if (ret) { return ret; @@ -1764,7 +1757,6 @@ static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, qemu_put_byte(f, len); qemu_put_buffer(f, (uint8_t *)vmsd->name, len); qemu_put_be32(f, vmsd->version_id); - assert(!vmsd->subsections); vmstate_save_state(f, vmsd, opaque); } sub++; -- cgit v1.2.3 From dcd1d224dfcad1154a516e683ab55ea848497f50 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 21 Sep 2011 23:01:54 +0200 Subject: migration: change has_error to contain errno values We normally already have an errno value. When not, abuse EIO. Signed-off-by: Juan Quintela --- savevm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index ca9e233c9a..5bef618516 100644 --- a/savevm.c +++ b/savevm.c @@ -430,9 +430,9 @@ int qemu_file_has_error(QEMUFile *f) return f->has_error; } -void qemu_file_set_error(QEMUFile *f) +void qemu_file_set_error(QEMUFile *f, int ret) { - f->has_error = 1; + f->has_error = ret; } void qemu_fflush(QEMUFile *f) @@ -447,7 +447,7 @@ void qemu_fflush(QEMUFile *f) if (len > 0) f->buf_offset += f->buf_index; else - f->has_error = 1; + f->has_error = -EINVAL; f->buf_index = 0; } } @@ -476,7 +476,7 @@ static void qemu_fill_buffer(QEMUFile *f) f->buf_size += len; f->buf_offset += len; } else if (len != -EAGAIN) - f->has_error = 1; + f->has_error = len; } int qemu_fclose(QEMUFile *f) -- cgit v1.2.3 From 3934638539c763ad23026b70483e60be34078c57 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 22 Sep 2011 11:02:14 +0200 Subject: migration: return real error code make functions propagate errno, instead of just using -EIO. Add a comment about what are the return value of qemu_savevm_state_iterate(). Signed-off-by: Juan Quintela --- savevm.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index 5bef618516..b2f22bdc82 100644 --- a/savevm.c +++ b/savevm.c @@ -1504,6 +1504,7 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, int shared) { SaveStateEntry *se; + int ret; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if(se->set_params == NULL) { @@ -1535,15 +1536,21 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); } - - if (qemu_file_has_error(f)) { + ret = qemu_file_has_error(f); + if (ret != 0) { qemu_savevm_state_cancel(mon, f); - return -EIO; } - return 0; + return ret; + } +/* + * this funtion has three return values: + * negative: there was one error, and we have -errno. + * 0 : We haven't finished, caller have to go again + * 1 : We have finished, we can go to complete phase + */ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) { SaveStateEntry *se; @@ -1566,16 +1573,14 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) break; } } - - if (ret) - return 1; - - if (qemu_file_has_error(f)) { + if (ret != 0) { + return ret; + } + ret = qemu_file_has_error(f); + if (ret != 0) { qemu_savevm_state_cancel(mon, f); - return -EIO; } - - return 0; + return ret; } int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) @@ -1618,10 +1623,7 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) qemu_put_byte(f, QEMU_VM_EOF); - if (qemu_file_has_error(f)) - return -EIO; - - return 0; + return qemu_file_has_error(f); } void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) @@ -1661,8 +1663,9 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f) ret = qemu_savevm_state_complete(mon, f); out: - if (qemu_file_has_error(f)) - ret = -EIO; + if (ret == 0) { + ret = qemu_file_has_error(f); + } if (!ret && saved_vm_running) vm_start(); -- cgit v1.2.3 From 624b9cc20922fe7b046cd79c839d1f3a5a5fc27e Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 5 Oct 2011 01:02:52 +0200 Subject: migration: rename qemu_file_has_error to qemu_file_get_error Now the function returned errno, so it is better the new name. Signed-off-by: Juan Quintela Reviewed-by: Anthony Liguori --- savevm.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index b2f22bdc82..819a6f791e 100644 --- a/savevm.c +++ b/savevm.c @@ -425,7 +425,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, return f; } -int qemu_file_has_error(QEMUFile *f) +int qemu_file_get_error(QEMUFile *f) { return f->has_error; } @@ -1536,7 +1536,7 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); } - ret = qemu_file_has_error(f); + ret = qemu_file_get_error(f); if (ret != 0) { qemu_savevm_state_cancel(mon, f); } @@ -1576,7 +1576,7 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) if (ret != 0) { return ret; } - ret = qemu_file_has_error(f); + ret = qemu_file_get_error(f); if (ret != 0) { qemu_savevm_state_cancel(mon, f); } @@ -1623,7 +1623,7 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) qemu_put_byte(f, QEMU_VM_EOF); - return qemu_file_has_error(f); + return qemu_file_get_error(f); } void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) @@ -1664,7 +1664,7 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f) out: if (ret == 0) { - ret = qemu_file_has_error(f); + ret = qemu_file_get_error(f); } if (!ret && saved_vm_running) @@ -1885,8 +1885,9 @@ out: g_free(le); } - if (qemu_file_has_error(f)) + if (qemu_file_get_error(f)) { ret = -EIO; + } return ret; } -- cgit v1.2.3 From 3961b4dd0e72ae70e612be1097176d8910fc3f5e Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 5 Oct 2011 01:05:21 +0200 Subject: savevm: Rename has_error to last_error field Now the field contains the last error name, so rename acordingly. Signed-off-by: Juan Quintela Reviewed-by: Anthony Liguori --- savevm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index 819a6f791e..89147a6906 100644 --- a/savevm.c +++ b/savevm.c @@ -173,7 +173,7 @@ struct QEMUFile { int buf_size; /* 0 when writing */ uint8_t buf[IO_BUF_SIZE]; - int has_error; + int last_error; }; typedef struct QEMUFileStdio @@ -427,12 +427,12 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, int qemu_file_get_error(QEMUFile *f) { - return f->has_error; + return f->last_error; } void qemu_file_set_error(QEMUFile *f, int ret) { - f->has_error = ret; + f->last_error = ret; } void qemu_fflush(QEMUFile *f) @@ -447,7 +447,7 @@ void qemu_fflush(QEMUFile *f) if (len > 0) f->buf_offset += f->buf_index; else - f->has_error = -EINVAL; + f->last_error = -EINVAL; f->buf_index = 0; } } @@ -476,7 +476,7 @@ static void qemu_fill_buffer(QEMUFile *f) f->buf_size += len; f->buf_offset += len; } else if (len != -EAGAIN) - f->has_error = len; + f->last_error = len; } int qemu_fclose(QEMUFile *f) @@ -498,13 +498,13 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) { int l; - if (!f->has_error && f->is_write == 0 && f->buf_index > 0) { + if (!f->last_error && f->is_write == 0 && f->buf_index > 0) { fprintf(stderr, "Attempted to write to buffer while read buffer is not empty\n"); abort(); } - while (!f->has_error && size > 0) { + while (!f->last_error && size > 0) { l = IO_BUF_SIZE - f->buf_index; if (l > size) l = size; @@ -520,7 +520,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) void qemu_put_byte(QEMUFile *f, int v) { - if (!f->has_error && f->is_write == 0 && f->buf_index > 0) { + if (!f->last_error && f->is_write == 0 && f->buf_index > 0) { fprintf(stderr, "Attempted to write to buffer while read buffer is not empty\n"); abort(); -- cgit v1.2.3 From 42802d47dd09c6e70763676bb2ba59136427ec6a Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 5 Oct 2011 01:14:46 +0200 Subject: migration: use qemu_file_get_error() return value when possible Signed-off-by: Juan Quintela --- savevm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index 89147a6906..5b340b695f 100644 --- a/savevm.c +++ b/savevm.c @@ -1885,8 +1885,8 @@ out: g_free(le); } - if (qemu_file_get_error(f)) { - ret = -EIO; + if (ret == 0) { + ret = qemu_file_get_error(f); } return ret; -- cgit v1.2.3 From 2975725f6b3d634dbe924ea9d9f4d86b8a5b217d Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 19 Oct 2011 15:22:18 +0200 Subject: migration: make *save_live return errors Make *save_live() return negative values when there is one error, and updates all callers to check for the error. Signed-off-by: Juan Quintela --- savevm.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'savevm.c') diff --git a/savevm.c b/savevm.c index 5b340b695f..9e9c7835a0 100644 --- a/savevm.c +++ b/savevm.c @@ -1534,7 +1534,11 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, qemu_put_be32(f, se->instance_id); qemu_put_be32(f, se->version_id); - se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); + ret = se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); + if (ret < 0) { + qemu_savevm_state_cancel(mon, f); + return ret; + } } ret = qemu_file_get_error(f); if (ret != 0) { @@ -1565,7 +1569,7 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) qemu_put_be32(f, se->section_id); ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque); - if (!ret) { + if (ret <= 0) { /* Do not proceed to the next vmstate before this one reported completion of the current stage. This serializes the migration and reduces the probability that a faster changing state is @@ -1586,6 +1590,7 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) { SaveStateEntry *se; + int ret; cpu_synchronize_all_states(); @@ -1597,7 +1602,10 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) qemu_put_byte(f, QEMU_VM_SECTION_END); qemu_put_be32(f, se->section_id); - se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque); + ret = se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque); + if (ret < 0) { + return ret; + } } QTAILQ_FOREACH(se, &savevm_handlers, entry) { -- cgit v1.2.3