From 056b68af773b31fa98fe4538f6424c0079b61415 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 20 Jul 2016 11:54:03 +0200 Subject: 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 Message-Id: <1469008443-72059-1-git-send-email-imammedo@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- util/oslib-posix.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'util/oslib-posix.c') 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); } -- cgit v1.2.1