aboutsummaryrefslogtreecommitdiffstats
path: root/tools/blktap
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-10-20 15:08:24 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-10-20 15:08:24 +0100
commit942da08c6c66aa8ebd0db4d7cbe0b06426bc6c53 (patch)
treeaacba1b61c8cf722cff055fa778a89d367ff09a3 /tools/blktap
parent66e8c0272e475dcd10a644cd6aad308e0ff8314b (diff)
downloadxen-942da08c6c66aa8ebd0db4d7cbe0b06426bc6c53.tar.gz
xen-942da08c6c66aa8ebd0db4d7cbe0b06426bc6c53.tar.bz2
xen-942da08c6c66aa8ebd0db4d7cbe0b06426bc6c53.zip
blktap: Handle qcow backing files correctly.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'tools/blktap')
-rw-r--r--tools/blktap/drivers/block-qcow.c16
-rw-r--r--tools/blktap/drivers/block-qcow2.c60
2 files changed, 59 insertions, 17 deletions
diff --git a/tools/blktap/drivers/block-qcow.c b/tools/blktap/drivers/block-qcow.c
index 51a2e324a1..97cc5c6b6b 100644
--- a/tools/blktap/drivers/block-qcow.c
+++ b/tools/blktap/drivers/block-qcow.c
@@ -734,8 +734,8 @@ static int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flag
DPRINTF("QCOW: Opening %s\n",name);
- o_flags = O_DIRECT | O_LARGEFILE |
- ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+ /* Since we don't handle O_DIRECT correctly, don't use it */
+ o_flags = O_LARGEFILE | ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
fd = open(name, o_flags);
if (fd < 0) {
DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
@@ -1385,7 +1385,7 @@ static int tdqcow_get_parent_id(struct disk_driver *dd, struct disk_id *id)
filename[len] = '\0';
id->name = strdup(filename);
- id->drivertype = DISK_TYPE_QCOW;
+ id->drivertype = DISK_TYPE_AIO;
err = 0;
out:
free(buf);
@@ -1397,17 +1397,15 @@ static int tdqcow_validate_parent(struct disk_driver *child,
{
struct stat stats;
uint64_t psize, csize;
- struct tdqcow_state *c = (struct tdqcow_state *)child->private;
- struct tdqcow_state *p = (struct tdqcow_state *)parent->private;
- if (stat(p->name, &stats))
+ if (stat(parent->name, &stats))
return -EINVAL;
- if (get_filesize(p->name, &psize, &stats))
+ if (get_filesize(parent->name, &psize, &stats))
return -EINVAL;
- if (stat(c->name, &stats))
+ if (stat(child->name, &stats))
return -EINVAL;
- if (get_filesize(c->name, &csize, &stats))
+ if (get_filesize(child->name, &csize, &stats))
return -EINVAL;
if (csize != psize)
diff --git a/tools/blktap/drivers/block-qcow2.c b/tools/blktap/drivers/block-qcow2.c
index fe28a2ecb0..8bdd33ea37 100644
--- a/tools/blktap/drivers/block-qcow2.c
+++ b/tools/blktap/drivers/block-qcow2.c
@@ -34,6 +34,7 @@
#include "tapdisk.h"
#include "tapaio.h"
#include "bswap.h"
+#include "blk.h"
#define USE_AIO
@@ -1902,6 +1903,42 @@ repeat:
#endif
+static int get_filesize(char *filename, uint64_t *size, struct stat *st)
+{
+ int fd;
+ QCowHeader header;
+
+ /*Set to the backing file size*/
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ if (read(fd, &header, sizeof(header)) < sizeof(header)) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ be32_to_cpus(&header.magic);
+ be32_to_cpus(&header.version);
+ be64_to_cpus(&header.size);
+ if (header.magic == QCOW_MAGIC && header.version == QCOW_VERSION) {
+ *size = header.size >> SECTOR_SHIFT;
+ return 0;
+ }
+
+ if(S_ISBLK(st->st_mode)) {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ if (blk_getimagesize(fd, size) != 0) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ } else *size = (st->st_size >> SECTOR_SHIFT);
+ return 0;
+}
+
/**
* @return
* 0 if parent id successfully retrieved;
@@ -1916,7 +1953,7 @@ static int qcow_get_parent_id(struct disk_driver *dd, struct disk_id *id)
return TD_NO_PARENT;
id->name = strdup(s->backing_file);
- id->drivertype = DISK_TYPE_QCOW2;
+ id->drivertype = DISK_TYPE_AIO;
return 0;
}
@@ -1924,15 +1961,22 @@ static int qcow_get_parent_id(struct disk_driver *dd, struct disk_id *id)
static int qcow_validate_parent(struct disk_driver *child,
struct disk_driver *parent, td_flag_t flags)
{
- struct BDRVQcowState *cs = (struct BDRVQcowState*) child->private;
- struct BDRVQcowState *ps = (struct BDRVQcowState*) parent->private;
+ struct stat stats;
+ uint64_t psize, csize;
+
+ if (stat(parent->name, &stats))
+ return -EINVAL;
+ if (get_filesize(parent->name, &psize, &stats))
+ return -EINVAL;
- if (ps->total_sectors != cs->total_sectors) {
- DPRINTF("qcow_validate_parent(): %#"PRIx64" != %#"PRIx64"\n",
- ps->total_sectors, cs->total_sectors);
+ if (stat(child->name, &stats))
return -EINVAL;
- }
-
+ if (get_filesize(child->name, &csize, &stats))
+ return -EINVAL;
+
+ if (csize != psize)
+ return -EINVAL;
+
return 0;
}