[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 2/9] exec: split file_ram_alloc()
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v3 2/9] exec: split file_ram_alloc() |
Date: |
Fri, 2 Jun 2017 18:12:22 +0400 |
Move file opening part in a seperate function, file_ram_open(). This
allows for reuse of file_ram_alloc() with a given fd.
Signed-off-by: Marc-André Lureau <address@hidden>
---
exec.c | 83 +++++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 46 insertions(+), 37 deletions(-)
diff --git a/exec.c b/exec.c
index 9c6c3cfe87..97e01d75f0 100644
--- a/exec.c
+++ b/exec.c
@@ -1483,19 +1483,17 @@ static int64_t get_file_size(int fd)
return size;
}
-static void *file_ram_alloc(RAMBlock *block,
- ram_addr_t memory,
- const char *path,
- Error **errp)
+static int file_ram_open(const char *path,
+ const char *region_name,
+ bool *created,
+ Error **errp)
{
- bool unlink_on_error = false;
char *filename;
char *sanitized_name;
char *c;
- void *area = MAP_FAILED;
int fd = -1;
- int64_t file_size;
+ *created = false;
for (;;) {
fd = open(path, O_RDWR);
if (fd >= 0) {
@@ -1506,13 +1504,13 @@ static void *file_ram_alloc(RAMBlock *block,
/* @path names a file that doesn't exist, create it */
fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644);
if (fd >= 0) {
- unlink_on_error = true;
+ *created = true;
break;
}
} else if (errno == EISDIR) {
/* @path names a directory, create a file there */
/* Make name safe to use with mkstemp by replacing '/' with '_'. */
- sanitized_name = g_strdup(memory_region_name(block->mr));
+ sanitized_name = g_strdup(region_name);
for (c = sanitized_name; *c != '\0'; c++) {
if (*c == '/') {
*c = '_';
@@ -1535,7 +1533,7 @@ static void *file_ram_alloc(RAMBlock *block,
error_setg_errno(errp, errno,
"can't open backing store %s for guest RAM",
path);
- goto error;
+ return -1;
}
/*
* Try again on EINTR and EEXIST. The latter happens when
@@ -1543,6 +1541,17 @@ static void *file_ram_alloc(RAMBlock *block,
*/
}
+ return fd;
+}
+
+static void *file_ram_alloc(RAMBlock *block,
+ ram_addr_t memory,
+ int fd,
+ bool truncate,
+ Error **errp)
+{
+ void *area;
+
block->page_size = qemu_fd_getpagesize(fd);
block->mr->align = block->page_size;
#if defined(__s390x__)
@@ -1551,20 +1560,11 @@ static void *file_ram_alloc(RAMBlock *block,
}
#endif
- file_size = get_file_size(fd);
-
if (memory < block->page_size) {
error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
"or larger than page size 0x%zx",
memory, block->page_size);
- goto error;
- }
-
- if (file_size > 0 && file_size < memory) {
- error_setg(errp, "backing store %s size 0x%" PRIx64
- " does not match 'size' option 0x" RAM_ADDR_FMT,
- path, file_size, memory);
- goto error;
+ return NULL;
}
memory = ROUND_UP(memory, block->page_size);
@@ -1583,7 +1583,7 @@ static void *file_ram_alloc(RAMBlock *block,
* those labels. Therefore, extending the non-empty backend file
* is disabled as well.
*/
- if (!file_size && ftruncate(fd, memory)) {
+ if (truncate && ftruncate(fd, memory)) {
perror("ftruncate");
}
@@ -1592,30 +1592,19 @@ static void *file_ram_alloc(RAMBlock *block,
if (area == MAP_FAILED) {
error_setg_errno(errp, errno,
"unable to map backing store for guest RAM");
- goto error;
+ return NULL;
}
if (mem_prealloc) {
os_mem_prealloc(fd, area, memory, smp_cpus, errp);
if (errp && *errp) {
- goto error;
+ qemu_ram_munmap(area, memory);
+ return NULL;
}
}
block->fd = fd;
return area;
-
-error:
- if (area != MAP_FAILED) {
- qemu_ram_munmap(area, memory);
- }
- if (unlink_on_error) {
- unlink(path);
- }
- if (fd != -1) {
- close(fd);
- }
- return NULL;
}
#endif
@@ -1932,6 +1921,9 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size,
MemoryRegion *mr,
{
RAMBlock *new_block;
Error *local_err = NULL;
+ int fd;
+ bool created;
+ int64_t file_size;
if (xen_enabled()) {
error_setg(errp, "-mem-path not supported with Xen");
@@ -1955,15 +1947,32 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size,
MemoryRegion *mr,
return NULL;
}
+ fd = file_ram_open(mem_path, memory_region_name(mr), &created, errp);
+ if (fd < 0) {
+ return NULL;
+ }
+
size = HOST_PAGE_ALIGN(size);
+ file_size = get_file_size(fd);
+ if (file_size > 0 && file_size < size) {
+ error_setg(errp, "backing store %s size 0x%" PRIx64
+ " does not match 'size' option 0x" RAM_ADDR_FMT,
+ mem_path, file_size, size);
+ close(fd);
+ return NULL;
+ }
+
new_block = g_malloc0(sizeof(*new_block));
new_block->mr = mr;
new_block->used_length = size;
new_block->max_length = size;
new_block->flags = share ? RAM_SHARED : 0;
- new_block->host = file_ram_alloc(new_block, size,
- mem_path, errp);
+ new_block->host = file_ram_alloc(new_block, size, fd, !file_size, errp);
if (!new_block->host) {
+ if (created) {
+ unlink(mem_path);
+ }
+ close(fd);
g_free(new_block);
return NULL;
}
--
2.13.0.91.g00982b8dd
- [Qemu-devel] [PATCH v3 0/9] Add memfd memory backend, Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 1/9] exec: check kvm mmu notifiers earlier, Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 2/9] exec: split file_ram_alloc(),
Marc-André Lureau <=
- [Qemu-devel] [PATCH v3 3/9] exec: split qemu_ram_alloc_from_file(), Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 4/9] Add memory_region_init_ram_from_fd(), Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 5/9] ivshmem: use ram_from_fd(), Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 6/9] memory: remove memory_region_set_fd, Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 7/9] memfd: split qemu_memfd_alloc(), Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 8/9] Add memfd based hostmem, Marc-André Lureau, 2017/06/02
- [Qemu-devel] [PATCH v3 9/9] tests: use memfd in vhost-user-test, Marc-André Lureau, 2017/06/02
- Re: [Qemu-devel] [PATCH v3 0/9] Add memfd memory backend, Daniel P. Berrange, 2017/06/02