qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] snapshot: fixed bdrv_get_full_backing_filename can


From: Jun Li
Subject: [Qemu-devel] [PATCH] snapshot: fixed bdrv_get_full_backing_filename can not get correct full_backing_filename
Date: Fri, 7 Nov 2014 22:48:17 +0800

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 <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]