From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49325) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XmkqF-0001lJ-Nl for qemu-devel@nongnu.org; Fri, 07 Nov 2014 09:48:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Xmkq6-0007IA-J4 for qemu-devel@nongnu.org; Fri, 07 Nov 2014 09:48:47 -0500 Received: from mail-pa0-x22a.google.com ([2607:f8b0:400e:c03::22a]:59531) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xmkq6-0007Ha-Bm for qemu-devel@nongnu.org; Fri, 07 Nov 2014 09:48:38 -0500 Received: by mail-pa0-f42.google.com with SMTP id bj1so3676974pad.29 for ; Fri, 07 Nov 2014 06:48:33 -0800 (PST) From: Jun Li Date: Fri, 7 Nov 2014 22:48:17 +0800 Message-Id: <1415371697-27908-1-git-send-email-junmuzi@gmail.com> Subject: [Qemu-devel] [PATCH] snapshot: fixed bdrv_get_full_backing_filename can not get correct full_backing_filename List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, juli@redhat.com, famz@redhat.com, Jun Li , stefanha@redhat.com When bs->filename and bs->backing_file are relative pathname and not under the same directory, path_combine() can not give the correct path for bs->backing_file. So add get_localfile_absolute_path to get absolute path for local file. e.g: $ pwd /tmp $ /opt/qemu-git-arm/bin/qemu-img create -f qcow2 ./test 5M Formatting './test', fmt=qcow2 size=5242880 encryption=off cluster_size=65536 lazy_refcounts=off $ /opt/qemu-git-arm/bin/qemu-img create -f qcow2 ./tmp/test1 -b ./test Formatting './tmp/test1', fmt=qcow2 size=5242880 backing_file='./test' encryption=off cluster_size=65536 lazy_refcounts=off $ /opt/qemu-git-arm/bin/qemu-img create -f qcow2 ./tmp/test2 -b ./tmp/test1 qemu-img: ./tmp/test2: Could not open './tmp/test1': Could not open backing file: Could not open './tmp/./test': No such file or directory: No such file or directory This patch also fixes the following bug: https://bugzilla.redhat.com/show_bug.cgi?id=1161582#c2 Signed-off-by: Jun Li --- block.c | 28 +++++++++++++++++++++++++++- include/block/block.h | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index dacd881..5e2f669 100644 --- a/block.c +++ b/block.c @@ -259,6 +259,32 @@ int path_is_absolute(const char *path) #endif } +void get_localfile_absolute_path(char *dest, int dest_size, + const char *filename) +{ + struct stat sb; + char *linkname; + + if (path_is_absolute(filename)) { + pstrcpy(dest, dest_size, filename); + } else { + if (lstat(filename, &sb) == -1) { + perror("lstat"); + exit(EXIT_FAILURE); + } + + /* Check linkname is a link or not */ + if (S_ISLNK(sb.st_mode)) { + linkname = malloc(sb.st_size + 1); + readlink(filename, linkname, sb.st_size + 1); + linkname[sb.st_size] = '\0'; + realpath(linkname, dest); + } else { + realpath(filename, dest); + } + } +} + /* if filename is absolute, just copy it to dest. Otherwise, build a path to it by considering it is relative to base_path. URL are supported. */ @@ -308,7 +334,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz) if (bs->backing_file[0] == '\0' || path_has_protocol(bs->backing_file)) { pstrcpy(dest, sz, bs->backing_file); } else { - path_combine(dest, sz, bs->filename, bs->backing_file); + get_localfile_absolute_path(dest, sz, bs->backing_file); } } diff --git a/include/block/block.h b/include/block/block.h index 13e4537..6ddb150 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -398,6 +398,8 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, int bdrv_is_snapshot(BlockDriverState *bs); int path_is_absolute(const char *path); +void get_localfile_absolute_path(char *dest, int dest_size, + const char *filename); void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); -- 1.9.3