From patchwork Mon Feb 29 18:40:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 590089 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 29B57140770 for ; Tue, 1 Mar 2016 05:43:47 +1100 (AEDT) Received: from localhost ([::1]:38385 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aaSnJ-0006tp-7G for incoming@patchwork.ozlabs.org; Mon, 29 Feb 2016 13:43:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59579) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aaSke-0001yA-SW for qemu-devel@nongnu.org; Mon, 29 Feb 2016 13:41:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aaSkc-0007kW-Ru for qemu-devel@nongnu.org; Mon, 29 Feb 2016 13:41:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37337) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aaSkc-0007je-KP for qemu-devel@nongnu.org; Mon, 29 Feb 2016 13:40:58 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id F2C6D8051A; Mon, 29 Feb 2016 18:40:56 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-22.ams2.redhat.com [10.36.116.22]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u1TIes5S011414 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 29 Feb 2016 13:40:56 -0500 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 2E532303F916; Mon, 29 Feb 2016 19:40:54 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Mon, 29 Feb 2016 19:40:17 +0100 Message-Id: <1456771254-17511-2-git-send-email-armbru@redhat.com> In-Reply-To: <1456771254-17511-1-git-send-email-armbru@redhat.com> References: <1456771254-17511-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: claudio.fontana@huawei.com, cam@cs.ualberta.ca, mlureau@redhat.com, david.marchand@6wind.com, pbonzini@redhat.com Subject: [Qemu-devel] [PATCH 01/38] exec: Fix memory allocation when memory path names new file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Signed-off-by: Markus Armbruster --- 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