From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Igor Mammedov <imammedo@redhat.com>
Subject: [Qemu-devel] [PULL 03/25] fix qemu exit on memory hotplug when allocation fails at prealloc time
Date: Tue, 2 Aug 2016 21:39:13 +0200 [thread overview]
Message-ID: <1470166775-3671-4-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1470166775-3671-1-git-send-email-pbonzini@redhat.com>
From: Igor Mammedov <imammedo@redhat.com>
When adding hostmem backend at runtime, QEMU might exit with error:
"os_mem_prealloc: Insufficient free host memory pages available to allocate guest RAM"
It happens due to os_mem_prealloc() not handling errors gracefully.
Fix it by passing errp argument so that os_mem_prealloc() could
report error to callers and undo performed allocation when
os_mem_prealloc() fails.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <1469008443-72059-1-git-send-email-imammedo@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem.c | 18 ++++++++++++++----
exec.c | 10 ++++++++--
include/qemu/osdep.h | 2 +-
util/oslib-posix.c | 26 +++++++++++++-------------
util/oslib-win32.c | 2 +-
5 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index ac80257..b7a208d 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -203,6 +203,7 @@ static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
static void host_memory_backend_set_prealloc(Object *obj, bool value,
Error **errp)
{
+ Error *local_err = NULL;
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
if (backend->force_prealloc) {
@@ -223,7 +224,11 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
- os_mem_prealloc(fd, ptr, sz);
+ os_mem_prealloc(fd, ptr, sz, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
backend->prealloc = true;
}
}
@@ -286,8 +291,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
if (bc->alloc) {
bc->alloc(backend, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- return;
+ goto out;
}
ptr = memory_region_get_ram_ptr(&backend->mr);
@@ -343,9 +347,15 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
* specified NUMA policy in place.
*/
if (backend->prealloc) {
- os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
+ os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz,
+ &local_err);
+ if (local_err) {
+ goto out;
+ }
}
}
+out:
+ error_propagate(errp, local_err);
}
static bool
diff --git a/exec.c b/exec.c
index 50e3ee2..8ffde75 100644
--- a/exec.c
+++ b/exec.c
@@ -1226,7 +1226,7 @@ static void *file_ram_alloc(RAMBlock *block,
char *filename;
char *sanitized_name;
char *c;
- void *area;
+ void *area = MAP_FAILED;
int fd = -1;
int64_t page_size;
@@ -1314,13 +1314,19 @@ static void *file_ram_alloc(RAMBlock *block,
}
if (mem_prealloc) {
- os_mem_prealloc(fd, area, memory);
+ os_mem_prealloc(fd, area, memory, errp);
+ if (errp && *errp) {
+ goto error;
+ }
}
block->fd = fd;
return area;
error:
+ if (area != MAP_FAILED) {
+ qemu_ram_munmap(area, memory);
+ }
if (unlink_on_error) {
unlink(path);
}
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index fbb8759..d7c111d 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -379,7 +379,7 @@ unsigned long qemu_getauxval(unsigned long type);
void qemu_set_tty_echo(int fd, bool echo);
-void os_mem_prealloc(int fd, char *area, size_t sz);
+void os_mem_prealloc(int fd, char *area, size_t sz, Error **errp);
int qemu_read_password(char *buf, int buf_size);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 6d70d9a..f2d4e9e 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -318,7 +318,7 @@ static void sigbus_handler(int signal)
siglongjmp(sigjump, 1);
}
-void os_mem_prealloc(int fd, char *area, size_t memory)
+void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
{
int ret;
struct sigaction act, oldact;
@@ -330,8 +330,9 @@ void os_mem_prealloc(int fd, char *area, size_t memory)
ret = sigaction(SIGBUS, &act, &oldact);
if (ret) {
- perror("os_mem_prealloc: failed to install signal handler");
- exit(1);
+ error_setg_errno(errp, errno,
+ "os_mem_prealloc: failed to install signal handler");
+ return;
}
/* unblock SIGBUS */
@@ -340,9 +341,8 @@ void os_mem_prealloc(int fd, char *area, size_t memory)
pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
if (sigsetjmp(sigjump, 1)) {
- fprintf(stderr, "os_mem_prealloc: Insufficient free host memory "
- "pages available to allocate guest RAM\n");
- exit(1);
+ error_setg(errp, "os_mem_prealloc: Insufficient free host memory "
+ "pages available to allocate guest RAM\n");
} else {
int i;
size_t hpagesize = qemu_fd_getpagesize(fd);
@@ -352,15 +352,15 @@ void os_mem_prealloc(int fd, char *area, size_t memory)
for (i = 0; i < numpages; i++) {
memset(area + (hpagesize * i), 0, 1);
}
+ }
- ret = sigaction(SIGBUS, &oldact, NULL);
- if (ret) {
- perror("os_mem_prealloc: failed to reinstall signal handler");
- exit(1);
- }
-
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ ret = sigaction(SIGBUS, &oldact, NULL);
+ if (ret) {
+ /* Terminate QEMU since it can't recover from error */
+ perror("os_mem_prealloc: failed to reinstall signal handler");
+ exit(1);
}
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 6debc2b..4c1dcf1 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -539,7 +539,7 @@ int getpagesize(void)
return system_info.dwPageSize;
}
-void os_mem_prealloc(int fd, char *area, size_t memory)
+void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
{
int i;
size_t pagesize = getpagesize();
--
2.7.4
next prev parent reply other threads:[~2016-08-02 19:39 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-02 19:39 [Qemu-devel] [PULL 00/25] Misc QEMU fixes for 2016-08-02 Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 01/25] util/qht: Document memory ordering assumptions Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 02/25] numa: set the memory backend "is_mapped" field Paolo Bonzini
2016-08-02 19:39 ` Paolo Bonzini [this message]
2016-08-02 19:39 ` [Qemu-devel] [PULL 04/25] checkpatch: add check for bzero Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 05/25] util: drop inet_nonblocking_connect() Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 06/25] util: drop unix_nonblocking_connect() Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 07/25] util: Drop inet_listen() Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 08/25] qht: do not segfault when gathering stats from an uninitialized qht Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 09/25] target-i386: fix typo in xsetbv implementation Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 10/25] qdist: fix memory leak during binning Paolo Bonzini
2016-08-02 21:13 ` Marc-André Lureau
2016-08-02 19:39 ` [Qemu-devel] [PULL 11/25] qdist: use g_realloc_n instead of g_realloc Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 12/25] qdist: return "(empty)" instead of NULL when printing an empty dist Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 13/25] mptsas: really fix migration compatibility Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 14/25] i2c: fix migration regression introduced by broadcast support Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 15/25] nbd: Fix bad flag detection on server Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 16/25] nbd: Limit nbdflags to 16 bits Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 17/25] osdep: Document differences in rounding macros Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 18/25] block: Cater to iscsi with non-power-of-2 discard Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 19/25] fw_cfg: Make base type "fw_cfg" abstract Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 20/25] apic: fix broken migration for kvm-apic Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 21/25] x86: ioapic: ignore level irq during processing Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 22/25] x86: ioapic: add support for explicit EOI Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 23/25] Reorganize help output of '-display' option Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 24/25] qdev: Fix use after free in qdev_init_nofail error path Paolo Bonzini
2016-08-02 19:39 ` [Qemu-devel] [PULL 25/25] util: Fix assertion in iov_copy() upon zero 'bytes' and non-zero 'offset' Paolo Bonzini
2016-08-03 10:52 ` [Qemu-devel] [PULL 00/25] Misc QEMU fixes for 2016-08-02 Peter Maydell
2016-08-03 16:24 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1470166775-3671-4-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=imammedo@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).