mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
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>
This commit is contained in:
parent
0b21757124
commit
056b68af77
5 changed files with 38 additions and 22 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue