[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 01/38] exec: Fix memory allocation when memory path
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PATCH 01/38] exec: Fix memory allocation when memory path names new file |
Date: |
Mon, 29 Feb 2016 19:40:17 +0100 |
Commit 8d31d6b extended file_ram_alloc() to accept file names in
addition to directory names. Even though it passes O_CREAT to open(),
it actually works only for existing files. Reproducer adapted from
the commit's qemu-doc.texi update:
$ qemu-system-x86_64 -object
memory-backend-file,size=2M,mem-path=/dev/hugepages/my-shmem-file,id=mb1
qemu-system-x86_64: -object
memory-backend-file,size=2M,mem-path=/dev/hugepages/my-shmem-file,id=mb1:
failed to get page size of file /dev/hugepages/my-shmem-file: No such file or
directory
Rearrange the code to create the file (if necessary) before getting
its page size.
While there, replace "hugepages" by "guest RAM" in error messages,
because host memory backends can be used for purposes other than huge
pages, e.g. /dev/shm/ shared memory. Help text of -mem-path agrees.
Cc: Paolo Bonzini <address@hidden>
Signed-off-by: Markus Armbruster <address@hidden>
---
exec.c | 50 +++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/exec.c b/exec.c
index c62c439..81b0063 100644
--- a/exec.c
+++ b/exec.c
@@ -1235,36 +1235,25 @@ static void *file_ram_alloc(RAMBlock *block,
const char *path,
Error **errp)
{
+ bool unlink_on_error = false;
struct stat st;
char *filename;
char *sanitized_name;
char *c;
void *area;
- int fd;
+ int ret, fd;
uint64_t hpagesize;
Error *local_err = NULL;
- hpagesize = gethugepagesize(path, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto error;
- }
- block->mr->align = hpagesize;
-
- if (memory < hpagesize) {
- error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
- "or larger than huge page size 0x%" PRIx64,
- memory, hpagesize);
- goto error;
- }
-
if (kvm_enabled() && !kvm_has_sync_mmu()) {
error_setg(errp,
"host lacks kvm mmu notifiers, -mem-path unsupported");
- goto error;
+ return NULL;
}
- if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
+ ret = stat(path, &st);
+ if (!ret && S_ISDIR(st.st_mode)) {
+ /* path names a directory -> create a temporary file there */
/* Make name safe to use with mkstemp by replacing '/' with '_'. */
sanitized_name = g_strdup(memory_region_name(block->mr));
for (c = sanitized_name; *c != '\0'; c++) {
@@ -1282,13 +1271,32 @@ static void *file_ram_alloc(RAMBlock *block,
unlink(filename);
}
g_free(filename);
+ } else if (!ret) {
+ /* path names an existing file -> use it */
+ fd = open(path, O_RDWR);
} else {
+ /* create a new file */
fd = open(path, O_RDWR | O_CREAT, 0644);
+ unlink_on_error = true;
}
if (fd < 0) {
error_setg_errno(errp, errno,
- "unable to create backing store for hugepages");
+ "unable to create backing store for guest RAM");
+ return NULL;
+ }
+
+ hpagesize = gethugepagesize(path, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto error;
+ }
+ block->mr->align = hpagesize;
+
+ if (memory < hpagesize) {
+ error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
+ "or larger than page size 0x%" PRIx64,
+ memory, hpagesize);
goto error;
}
@@ -1307,7 +1315,7 @@ static void *file_ram_alloc(RAMBlock *block,
area = qemu_ram_mmap(fd, memory, hpagesize, block->flags & RAM_SHARED);
if (area == MAP_FAILED) {
error_setg_errno(errp, errno,
- "unable to map backing store for hugepages");
+ "unable to map backing store for guest RAM");
close(fd);
goto error;
}
@@ -1320,6 +1328,10 @@ static void *file_ram_alloc(RAMBlock *block,
return area;
error:
+ if (unlink_on_error) {
+ unlink(path);
+ }
+ close(fd);
return NULL;
}
#endif
--
2.4.3
- [Qemu-devel] [PATCH 36/38] ivshmem: Drop ivshmem property x-memdev, (continued)
- [Qemu-devel] [PATCH 36/38] ivshmem: Drop ivshmem property x-memdev, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 24/38] ivshmem: Propagate errors through ivshmem_recv_setup(), Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 23/38] ivshmem: Receive shared memory synchronously in realize(), Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 18/38] ivshmem: Leave INTx alone when using MSI-X, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 31/38] ivshmem: Inline check_shm_size() into its only caller, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 35/38] ivshmem: Clean up after the previous commit, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 29/38] ivshmem: Implement shm=... with a memory backend, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 27/38] ivshmem: Simplify how we cope with short reads from server, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 17/38] ivshmem: Clean up MSI-X conditions, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 20/38] ivshmem: Simplify rejection of invalid peer ID from server, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 01/38] exec: Fix memory allocation when memory path names new file,
Markus Armbruster <=
- [Qemu-devel] [PATCH 33/38] ivshmem: Replace int role_val by OnOffAuto master, Markus Armbruster, 2016/02/29
- [Qemu-devel] [PATCH 34/38] ivshmem: Split ivshmem-plain, ivshmem-doorbell off ivshmem, Markus Armbruster, 2016/02/29