summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2016-07-20 11:54:03 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2016-08-02 12:03:58 +0200
commit056b68af773b31fa98fe4538f6424c0079b61415 (patch)
tree2915a5d9bb46cde5af57ef14bc348ddedc6721ab /util
parent0b21757124d200ff86100a3bc7bb5f81521b42c4 (diff)
downloadqemu-056b68af773b31fa98fe4538f6424c0079b61415.tar.gz
fix qemu exit on memory hotplug when allocation fails at prealloc time
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>
Diffstat (limited to 'util')
-rw-r--r--util/oslib-posix.c26
-rw-r--r--util/oslib-win32.c2
2 files changed, 14 insertions, 14 deletions
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 6d70d9a706..f2d4e9e592 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 6debc2b8a6..4c1dcf1e66 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();