qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Haozhong Zhang <haozhong.zhang@intel.com>
To: qemu-devel@nongnu.org, Eduardo Habkost <ehabkost@redhat.com>,
	Igor Mammedov <imammedo@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Richard Henderson <rth@twiddle.net>,
	Xiao Guangrong <guangrong.xiao@linux.intel.com>,
	Haozhong Zhang <haozhong.zhang@intel.com>
Subject: [Qemu-devel] [PATCH 1/2] exec.c: do not truncate non-empty memory backend file
Date: Mon, 24 Oct 2016 17:21:50 +0800	[thread overview]
Message-ID: <20161024092151.32386-2-haozhong.zhang@intel.com> (raw)
In-Reply-To: <20161024092151.32386-1-haozhong.zhang@intel.com>

For '-object memory-backend-file,mem-path=foo,size=xyz', if the size of
file 'foo' does not match the given size 'xyz', the current QEMU will
truncate the file to the given size, which may corrupt the existing data
in that file. To avoid such data corruption, this patch disables
truncating non-empty backend files.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
 exec.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index e63c5a1..95983c9 100644
--- a/exec.c
+++ b/exec.c
@@ -1188,6 +1188,15 @@ void qemu_mutex_unlock_ramlist(void)
 }
 
 #ifdef __linux__
+static int64_t get_file_size(int fd)
+{
+    int64_t size = lseek(fd, 0, SEEK_END);
+    if (size < 0) {
+        return -errno;
+    }
+    return size;
+}
+
 static void *file_ram_alloc(RAMBlock *block,
                             ram_addr_t memory,
                             const char *path,
@@ -1199,6 +1208,7 @@ static void *file_ram_alloc(RAMBlock *block,
     char *c;
     void *area = MAP_FAILED;
     int fd = -1;
+    int64_t file_size;
 
     if (kvm_enabled() && !kvm_has_sync_mmu()) {
         error_setg(errp,
@@ -1256,6 +1266,14 @@ static void *file_ram_alloc(RAMBlock *block,
     block->page_size = qemu_fd_getpagesize(fd);
     block->mr->align = MAX(block->page_size, QEMU_VMALLOC_ALIGN);
 
+    file_size = get_file_size(fd);
+    if (file_size < 0) {
+        error_setg_errno(errp, file_size,
+                         "can't get size of backing store %s",
+                         path);
+        goto error;
+    }
+
     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",
@@ -1266,12 +1284,29 @@ static void *file_ram_alloc(RAMBlock *block,
     memory = ROUND_UP(memory, block->page_size);
 
     /*
+     * Do not extend/shrink the backend file if it's not empty, or its
+     * size does not match the aligned 'size=xxx' option. Otherwise,
+     * it is possible to corrupt the existing data in the file.
+     *
+     * Disabling shrinking is not enough. For example, the current
+     * vNVDIMM implementation stores the guest NVDIMM labels at the
+     * end of the backend file. If the backend file is later extended,
+     * QEMU will not be able to find those labels. Therefore,
+     * extending the non-empty backend file is disabled as well.
+     */
+    if (file_size && file_size != memory) {
+        error_setg(errp, "backing store %s size %"PRId64
+                   " does not math with aligned 'size' option %"PRIu64,
+                   path, file_size, memory);
+        goto error;
+    }
+    /*
      * ftruncate is not supported by hugetlbfs in older
      * hosts, so don't bother bailing out on errors.
      * If anything goes wrong with it under other filesystems,
      * mmap will fail.
      */
-    if (ftruncate(fd, memory)) {
+    if (!file_size && ftruncate(fd, memory)) {
         perror("ftruncate");
     }
 
-- 
2.10.1

  reply	other threads:[~2016-10-24  9:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-24  9:21 [Qemu-devel] [PATCH 0/2] Improve truncation behavior of memory-backend-file Haozhong Zhang
2016-10-24  9:21 ` Haozhong Zhang [this message]
2016-10-25 19:30   ` [Qemu-devel] [PATCH 1/2] exec.c: do not truncate non-empty memory backend file Eduardo Habkost
2016-10-26  4:19     ` Haozhong Zhang
2016-10-24  9:21 ` [Qemu-devel] [PATCH 2/2] hostmem-file: allow option 'size' optional Haozhong Zhang
2016-10-25 19:50   ` Eduardo Habkost
2016-10-26  5:56     ` Haozhong Zhang
2016-10-26  7:49       ` Haozhong Zhang
2016-10-26 14:17         ` Eduardo Habkost
2016-10-26 14:30           ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161024092151.32386-2-haozhong.zhang@intel.com \
    --to=haozhong.zhang@intel.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=ehabkost@redhat.com \
    --cc=guangrong.xiao@linux.intel.com \
    --cc=imammedo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).