* [Qemu-devel] [PATCH 0/12] write/create for Parallels images
@ 2014-12-22 13:05 Denis V. Lunev
2014-12-22 13:05 ` [Qemu-devel] [PATCH 01/12] iotests, parallels: quote TEST_IMG in 076 test to be path-safe Denis V. Lunev
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:05 UTC (permalink / raw)
Cc: Kevin Wolf, Roman Kagan, Jeff Cody, qemu-devel, Stefan Hajnoczi,
Denis V. Lunev
This patchset provides an ability to create of/write to Parallels
images and some testing of the new code. Writes are not optimized
now at all, we just modify catalog_bitmap and write those changes
to the image itself at once. This will be improved in next steps.
This patchset consists of not problematic part of the previous
patchset aka
[PATCH v4 0/16] parallels format support improvements
and new write/create code but it does not contradict questionable code
with XML handling there.
Kevin, I would appreciate if you will quick look into proof-of-concept
patch aka
[RFC PATCH 1/1] block/parallels: new concept for DiskDescriptor.xml
to validate that approach for DiskDescriptor.xml problem.
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 01/12] iotests, parallels: quote TEST_IMG in 076 test to be path-safe
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
@ 2014-12-22 13:05 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 02/12] block/parallels: rename parallels_header to ParallelsHeader Denis V. Lunev
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:05 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
suggested by Jeff Cody
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
tests/qemu-iotests/076 | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076
index ed2be35..0139976 100755
--- a/tests/qemu-iotests/076
+++ b/tests/qemu-iotests/076
@@ -49,31 +49,31 @@ nb_sectors_offset=$((0x24))
echo
echo "== Read from a valid v1 image =="
_use_sample_img parallels-v1.bz2
-{ $QEMU_IO -c "read -P 0x11 0 64k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
echo
echo "== Negative catalog size =="
_use_sample_img parallels-v1.bz2
poke_file "$TEST_IMG" "$catalog_entries_offset" "\xff\xff\xff\xff"
-{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
echo
echo "== Overflow in catalog allocation =="
_use_sample_img parallels-v1.bz2
poke_file "$TEST_IMG" "$nb_sectors_offset" "\xff\xff\xff\xff"
poke_file "$TEST_IMG" "$catalog_entries_offset" "\x01\x00\x00\x40"
-{ $QEMU_IO -c "read 64M 64M" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read 64M 64M" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
echo
echo "== Zero sectors per track =="
_use_sample_img parallels-v1.bz2
poke_file "$TEST_IMG" "$tracks_offset" "\x00\x00\x00\x00"
-{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
echo
echo "== Read from a valid v2 image =="
_use_sample_img parallels-v2.bz2
-{ $QEMU_IO -c "read -P 0x11 0 64k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
# success, all done
echo "*** done"
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 02/12] block/parallels: rename parallels_header to ParallelsHeader
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
2014-12-22 13:05 ` [Qemu-devel] [PATCH 01/12] iotests, parallels: quote TEST_IMG in 076 test to be path-safe Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 03/12] block/parallels: switch to bdrv_read Denis V. Lunev
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
this follows QEMU coding convention
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 4f9cd8d..dca0df6 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -35,7 +35,7 @@
#define HEADER_SIZE 64
// always little-endian
-struct parallels_header {
+typedef struct ParallelsHeader {
char magic[16]; // "WithoutFreeSpace"
uint32_t version;
uint32_t heads;
@@ -46,7 +46,7 @@ struct parallels_header {
uint32_t inuse;
uint32_t data_off;
char padding[12];
-} QEMU_PACKED;
+} QEMU_PACKED ParallelsHeader;
typedef struct BDRVParallelsState {
CoMutex lock;
@@ -61,7 +61,7 @@ typedef struct BDRVParallelsState {
static int parallels_probe(const uint8_t *buf, int buf_size, const char *filename)
{
- const struct parallels_header *ph = (const void *)buf;
+ const ParallelsHeader *ph = (const void *)buf;
if (buf_size < HEADER_SIZE)
return 0;
@@ -79,7 +79,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
{
BDRVParallelsState *s = bs->opaque;
int i;
- struct parallels_header ph;
+ ParallelsHeader ph;
int ret;
bs->read_only = 1; // no write support yet
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 03/12] block/parallels: switch to bdrv_read
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
2014-12-22 13:05 ` [Qemu-devel] [PATCH 01/12] iotests, parallels: quote TEST_IMG in 076 test to be path-safe Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 02/12] block/parallels: rename parallels_header to ParallelsHeader Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 04/12] block/parallels: read up to cluster end in one go Denis V. Lunev
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Roman Kagan, Jeff Cody, qemu-devel, Stefan Hajnoczi,
Denis V. Lunev
From: Roman Kagan <rkagan@parallels.com>
Switch the .bdrv_read method implementation from using bdrv_pread() to
bdrv_read() on the underlying file, since the latter is subject to i/o
throttling while the former is not.
Besides, since bdrv_read() operates in sectors rather than bytes, adjust
the helper functions to do so too.
Signed-off-by: Roman Kagan <rkagan@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index dca0df6..baefd3e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -146,9 +146,8 @@ fail:
return ret;
}
-static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
+static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
{
- BDRVParallelsState *s = bs->opaque;
uint32_t index, offset;
index = sector_num / s->tracks;
@@ -157,24 +156,27 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
/* not allocated */
if ((index >= s->catalog_size) || (s->catalog_bitmap[index] == 0))
return -1;
- return
- ((uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset) * 512;
+ return (uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset;
}
static int parallels_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
+ BDRVParallelsState *s = bs->opaque;
+
while (nb_sectors > 0) {
- int64_t position = seek_to_sector(bs, sector_num);
+ int64_t position = seek_to_sector(s, sector_num);
if (position >= 0) {
- if (bdrv_pread(bs->file, position, buf, 512) != 512)
- return -1;
+ int ret = bdrv_read(bs->file, position, buf, 1);
+ if (ret < 0) {
+ return ret;
+ }
} else {
- memset(buf, 0, 512);
+ memset(buf, 0, BDRV_SECTOR_SIZE);
}
nb_sectors--;
sector_num++;
- buf += 512;
+ buf += BDRV_SECTOR_SIZE;
}
return 0;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 04/12] block/parallels: read up to cluster end in one go
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (2 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 03/12] block/parallels: switch to bdrv_read Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 05/12] block/parallels: add get_block_status Denis V. Lunev
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Roman Kagan, Jeff Cody, qemu-devel, Stefan Hajnoczi,
Denis V. Lunev
From: Roman Kagan <rkagan@parallels.com>
Teach parallels_read() to do reads in coarser granularity than just a
single sector: if requested, read up to the cluster end in one go.
Signed-off-by: Roman Kagan <rkagan@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index baefd3e..8770c82 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -159,6 +159,13 @@ static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
return (uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset;
}
+static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
+ int nb_sectors)
+{
+ int ret = s->tracks - sector_num % s->tracks;
+ return MIN(nb_sectors, ret);
+}
+
static int parallels_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
@@ -166,17 +173,18 @@ static int parallels_read(BlockDriverState *bs, int64_t sector_num,
while (nb_sectors > 0) {
int64_t position = seek_to_sector(s, sector_num);
+ int n = cluster_remainder(s, sector_num, nb_sectors);
if (position >= 0) {
- int ret = bdrv_read(bs->file, position, buf, 1);
+ int ret = bdrv_read(bs->file, position, buf, n);
if (ret < 0) {
return ret;
}
} else {
- memset(buf, 0, BDRV_SECTOR_SIZE);
+ memset(buf, 0, n << BDRV_SECTOR_BITS);
}
- nb_sectors--;
- sector_num++;
- buf += BDRV_SECTOR_SIZE;
+ nb_sectors -= n;
+ sector_num += n;
+ buf += n << BDRV_SECTOR_BITS;
}
return 0;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 05/12] block/parallels: add get_block_status
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (3 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 04/12] block/parallels: read up to cluster end in one go Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 06/12] block/parallels: provide _co_readv routine for parallels format driver Denis V. Lunev
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Roman Kagan, Jeff Cody, qemu-devel, Stefan Hajnoczi,
Denis V. Lunev
From: Roman Kagan <rkagan@parallels.com>
Implement VFS method for get_block_status to Parallels format driver.
Signed-off-by: Roman Kagan <rkagan@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/block/parallels.c b/block/parallels.c
index 8770c82..b469984 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -166,6 +166,26 @@ static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
return MIN(nb_sectors, ret);
}
+static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, int *pnum)
+{
+ BDRVParallelsState *s = bs->opaque;
+ int64_t offset;
+
+ qemu_co_mutex_lock(&s->lock);
+ offset = seek_to_sector(s, sector_num);
+ qemu_co_mutex_unlock(&s->lock);
+
+ *pnum = cluster_remainder(s, sector_num, nb_sectors);
+
+ if (offset < 0) {
+ return 0;
+ }
+
+ return (offset << BDRV_SECTOR_BITS) |
+ BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
+}
+
static int parallels_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
@@ -213,6 +233,7 @@ static BlockDriver bdrv_parallels = {
.bdrv_open = parallels_open,
.bdrv_read = parallels_co_read,
.bdrv_close = parallels_close,
+ .bdrv_co_get_block_status = parallels_co_get_block_status,
};
static void bdrv_parallels_init(void)
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 06/12] block/parallels: provide _co_readv routine for parallels format driver
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (4 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 05/12] block/parallels: add get_block_status Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 07/12] block/parallels: replace magic constants 4, 64 with proper sizeofs Denis V. Lunev
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
Main approach is taken from qcow2_co_readv.
The patch drops coroutine lock for the duration of IO operation and
peforms normal scatter-gather IO using standard QEMU backend.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 46 +++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index b469984..64b169b 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -186,37 +186,45 @@ static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
}
-static int parallels_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
+static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
{
BDRVParallelsState *s = bs->opaque;
+ uint64_t bytes_done = 0;
+ QEMUIOVector hd_qiov;
+ int ret = 0;
+ qemu_iovec_init(&hd_qiov, qiov->niov);
+
+ qemu_co_mutex_lock(&s->lock);
while (nb_sectors > 0) {
int64_t position = seek_to_sector(s, sector_num);
int n = cluster_remainder(s, sector_num, nb_sectors);
- if (position >= 0) {
- int ret = bdrv_read(bs->file, position, buf, n);
+ int nbytes = n << BDRV_SECTOR_BITS;
+
+ if (position < 0) {
+ qemu_iovec_memset(qiov, bytes_done, 0, nbytes);
+ } else {
+ qemu_iovec_reset(&hd_qiov);
+ qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
+
+ qemu_co_mutex_unlock(&s->lock);
+ ret = bdrv_co_readv(bs->file, position, n, &hd_qiov);
+ qemu_co_mutex_lock(&s->lock);
+
if (ret < 0) {
- return ret;
+ goto fail;
}
- } else {
- memset(buf, 0, n << BDRV_SECTOR_BITS);
}
+
nb_sectors -= n;
sector_num += n;
- buf += n << BDRV_SECTOR_BITS;
+ bytes_done += nbytes;
}
- return 0;
-}
-
-static coroutine_fn int parallels_co_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- int ret;
- BDRVParallelsState *s = bs->opaque;
- qemu_co_mutex_lock(&s->lock);
- ret = parallels_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
+
+fail:
+ qemu_iovec_destroy(&hd_qiov);
return ret;
}
@@ -231,9 +239,9 @@ static BlockDriver bdrv_parallels = {
.instance_size = sizeof(BDRVParallelsState),
.bdrv_probe = parallels_probe,
.bdrv_open = parallels_open,
- .bdrv_read = parallels_co_read,
.bdrv_close = parallels_close,
.bdrv_co_get_block_status = parallels_co_get_block_status,
+ .bdrv_co_readv = parallels_co_readv,
};
static void bdrv_parallels_init(void)
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 07/12] block/parallels: replace magic constants 4, 64 with proper sizeofs
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (5 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 06/12] block/parallels: provide _co_readv routine for parallels format driver Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 08/12] block/parallels: _co_writev callback for Parallels format Denis V. Lunev
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
simple purification..
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 64b169b..306f2e3 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -32,7 +32,6 @@
#define HEADER_MAGIC "WithoutFreeSpace"
#define HEADER_MAGIC2 "WithouFreSpacExt"
#define HEADER_VERSION 2
-#define HEADER_SIZE 64
// always little-endian
typedef struct ParallelsHeader {
@@ -63,7 +62,7 @@ static int parallels_probe(const uint8_t *buf, int buf_size, const char *filenam
{
const ParallelsHeader *ph = (const void *)buf;
- if (buf_size < HEADER_SIZE)
+ if (buf_size < sizeof(ParallelsHeader))
return 0;
if ((!memcmp(ph->magic, HEADER_MAGIC, 16) ||
@@ -116,7 +115,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
}
s->catalog_size = le32_to_cpu(ph.catalog_entries);
- if (s->catalog_size > INT_MAX / 4) {
+ if (s->catalog_size > INT_MAX / sizeof(uint32_t)) {
error_setg(errp, "Catalog too large");
ret = -EFBIG;
goto fail;
@@ -127,7 +126,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- ret = bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4);
+ ret = bdrv_pread(bs->file, sizeof(ParallelsHeader),
+ s->catalog_bitmap, s->catalog_size * sizeof(uint32_t));
if (ret < 0) {
goto fail;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 08/12] block/parallels: _co_writev callback for Parallels format
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (6 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 07/12] block/parallels: replace magic constants 4, 64 with proper sizeofs Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 09/12] iotests, parallels: test for write into Parallels image Denis V. Lunev
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
Support write on Parallels images. The code is almost the same as one
in the previous patch implemented scatter-gather IO for read.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 2 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 306f2e3..dca3d0b 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -81,8 +81,6 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
ParallelsHeader ph;
int ret;
- bs->read_only = 1; // no write support yet
-
ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
if (ret < 0) {
goto fail;
@@ -159,6 +157,37 @@ static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
return (uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset;
}
+static int64_t allocate_sector(BlockDriverState *bs, int64_t sector_num)
+{
+ BDRVParallelsState *s = bs->opaque;
+ uint32_t idx, offset, tmp;
+ int64_t pos;
+ int ret;
+
+ idx = sector_num / s->tracks;
+ offset = sector_num % s->tracks;
+
+ if (idx >= s->catalog_size) {
+ return -EINVAL;
+ }
+ if (s->catalog_bitmap[idx] != 0) {
+ return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset;
+ }
+
+ pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
+ bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS);
+ s->catalog_bitmap[idx] = pos / s->off_multiplier;
+
+ tmp = cpu_to_le32(s->catalog_bitmap[idx]);
+
+ ret = bdrv_pwrite_sync(bs->file,
+ sizeof(ParallelsHeader) + idx * sizeof(tmp), &tmp, sizeof(tmp));
+ if (ret < 0) {
+ return ret;
+ }
+ return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset;
+}
+
static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
int nb_sectors)
{
@@ -186,6 +215,49 @@ static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
}
+static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
+{
+ BDRVParallelsState *s = bs->opaque;
+ uint64_t bytes_done = 0;
+ QEMUIOVector hd_qiov;
+ int ret = 0;
+
+ qemu_iovec_init(&hd_qiov, qiov->niov);
+
+ qemu_co_mutex_lock(&s->lock);
+ while (nb_sectors > 0) {
+ int64_t position = allocate_sector(bs, sector_num);
+ int n = cluster_remainder(s, sector_num, nb_sectors);
+ int nbytes = n << BDRV_SECTOR_BITS;
+
+ if (position < 0) {
+ ret = (int)position;
+ break;
+ }
+
+ qemu_iovec_reset(&hd_qiov);
+ qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
+
+ qemu_co_mutex_unlock(&s->lock);
+ ret = bdrv_co_writev(bs->file, position, n, &hd_qiov);
+ qemu_co_mutex_lock(&s->lock);
+
+ if (ret < 0) {
+ goto fail;
+ }
+
+ nb_sectors -= n;
+ sector_num += n;
+ bytes_done += nbytes;
+ }
+ qemu_co_mutex_unlock(&s->lock);
+
+fail:
+ qemu_iovec_destroy(&hd_qiov);
+ return ret;
+}
+
static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
{
@@ -242,6 +314,7 @@ static BlockDriver bdrv_parallels = {
.bdrv_close = parallels_close,
.bdrv_co_get_block_status = parallels_co_get_block_status,
.bdrv_co_readv = parallels_co_readv,
+ .bdrv_co_writev = parallels_co_writev,
};
static void bdrv_parallels_init(void)
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 09/12] iotests, parallels: test for write into Parallels image
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (7 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 08/12] block/parallels: _co_writev callback for Parallels format Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 10/12] block/parallels: support parallels image creation Denis V. Lunev
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
tests/qemu-iotests/076 | 5 +++++
tests/qemu-iotests/076.out | 10 ++++++++++
2 files changed, 15 insertions(+)
diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076
index 0139976..c9b55a9 100755
--- a/tests/qemu-iotests/076
+++ b/tests/qemu-iotests/076
@@ -74,6 +74,11 @@ echo
echo "== Read from a valid v2 image =="
_use_sample_img parallels-v2.bz2
{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "write -P 0x21 1024k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "write -P 0x22 1025k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read -P 0x21 1024k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read -P 0x22 1025k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+{ $QEMU_IO -c "read -P 0 1026k 62k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out
index 32ade08..b0000ae 100644
--- a/tests/qemu-iotests/076.out
+++ b/tests/qemu-iotests/076.out
@@ -19,4 +19,14 @@ no file open, try 'help open'
== Read from a valid v2 image ==
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 1048576
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 1049600
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 1048576
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 1049600
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 63488/63488 bytes at offset 1050624
+62 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 10/12] block/parallels: support parallels image creation
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (8 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 09/12] iotests, parallels: test for write into Parallels image Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 11/12] iotests, parallels: test for newly created parallels image via qemu-img Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 12/12] parallels: change copyright information in the image header Denis V. Lunev
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
Do not even care to create WithoutFreeSpace image, it is obsolete.
Always create WithouFreSpacExt one.
The code also does not spend a lot of efforts to fill cylinders and
heads fields, they are not used actually in a real life neither in
QEMU nor in Parallels products.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/block/parallels.c b/block/parallels.c
index dca3d0b..bea1217 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -33,6 +33,9 @@
#define HEADER_MAGIC2 "WithouFreSpacExt"
#define HEADER_VERSION 2
+#define DEFAULT_CLUSTER_SIZE 1048576 /* 1 MiB */
+
+
// always little-endian
typedef struct ParallelsHeader {
char magic[16]; // "WithoutFreeSpace"
@@ -300,12 +303,103 @@ fail:
return ret;
}
+static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
+{
+ int64_t total_size, cl_size;
+ uint8_t tmp[BDRV_SECTOR_SIZE];
+ Error *local_err = NULL;
+ BlockDriverState *file;
+ uint32_t cat_entries, cat_sectors;
+ ParallelsHeader header;
+ int ret;
+
+ total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+ BDRV_SECTOR_SIZE);
+ cl_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
+ DEFAULT_CLUSTER_SIZE), BDRV_SECTOR_SIZE);
+
+ ret = bdrv_create_file(filename, opts, &local_err);
+ if (ret < 0) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+
+ file = NULL;
+ ret = bdrv_open(&file, filename, NULL, NULL,
+ BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
+ if (ret < 0) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+ ret = bdrv_truncate(file, 0);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ cat_entries = DIV_ROUND_UP(total_size, cl_size);
+ cat_sectors = DIV_ROUND_UP(cat_entries * sizeof(uint32_t) +
+ sizeof(ParallelsHeader), cl_size);
+ cat_sectors = (cat_sectors * cl_size) >> BDRV_SECTOR_BITS;
+
+ memset(&header, 0, sizeof(header));
+ memcpy(header.magic, HEADER_MAGIC2, sizeof(header.magic));
+ header.version = cpu_to_le32(HEADER_VERSION);
+ /* don't care much about geometry, it is not used on image level */
+ header.heads = cpu_to_le32(16);
+ header.cylinders = cpu_to_le32(total_size / BDRV_SECTOR_SIZE / 16 / 32);
+ header.tracks = cpu_to_le32(cl_size >> BDRV_SECTOR_BITS);
+ header.catalog_entries = cpu_to_le32(cat_entries);
+ header.nb_sectors = cpu_to_le64(DIV_ROUND_UP(total_size, BDRV_SECTOR_SIZE));
+ header.data_off = cpu_to_le32(cat_sectors);
+
+ /* write all the data */
+ memset(tmp, 0, sizeof(tmp));
+ memcpy(tmp, &header, sizeof(header));
+
+ ret = bdrv_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE);
+ if (ret < 0) {
+ goto exit;
+ }
+ ret = bdrv_write_zeroes(file, 1, cat_sectors - 1, 0);
+ if (ret < 0) {
+ goto exit;
+ }
+ ret = 0;
+
+done:
+ bdrv_unref(file);
+ return ret;
+
+exit:
+ error_setg_errno(errp, -ret, "Failed to create Parallels image");
+ goto done;
+}
+
static void parallels_close(BlockDriverState *bs)
{
BDRVParallelsState *s = bs->opaque;
g_free(s->catalog_bitmap);
}
+static QemuOptsList parallels_create_opts = {
+ .name = "parallels-create-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(parallels_create_opts.head),
+ .desc = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Virtual disk size",
+ },
+ {
+ .name = BLOCK_OPT_CLUSTER_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Parallels image cluster size",
+ .def_value_str = stringify(DEFAULT_CLUSTER_SIZE),
+ },
+ { /* end of list */ }
+ }
+};
+
static BlockDriver bdrv_parallels = {
.format_name = "parallels",
.instance_size = sizeof(BDRVParallelsState),
@@ -315,6 +409,9 @@ static BlockDriver bdrv_parallels = {
.bdrv_co_get_block_status = parallels_co_get_block_status,
.bdrv_co_readv = parallels_co_readv,
.bdrv_co_writev = parallels_co_writev,
+
+ .bdrv_create = parallels_create,
+ .create_opts = ¶llels_create_opts,
};
static void bdrv_parallels_init(void)
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 11/12] iotests, parallels: test for newly created parallels image via qemu-img
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (9 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 10/12] block/parallels: support parallels image creation Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 12/12] parallels: change copyright information in the image header Denis V. Lunev
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Kevin Wolf, Denis V. Lunev, Jeff Cody, qemu-devel,
Stefan Hajnoczi
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
CC: Jeff Cody <jcody@redhat.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
tests/qemu-iotests/115 | 68 ++++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/115.out | 24 ++++++++++++++++
tests/qemu-iotests/group | 1 +
3 files changed, 93 insertions(+)
create mode 100755 tests/qemu-iotests/115
create mode 100644 tests/qemu-iotests/115.out
diff --git a/tests/qemu-iotests/115 b/tests/qemu-iotests/115
new file mode 100755
index 0000000..f45afa7
--- /dev/null
+++ b/tests/qemu-iotests/115
@@ -0,0 +1,68 @@
+#!/bin/bash
+#
+# parallels format validation tests (created by QEMU)
+#
+# Copyright (C) 2014 Denis V. Lunev <den@openvz.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=den@openvz.org
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt parallels
+_supported_proto file
+_supported_os Linux
+
+size=64M
+CLUSTER_SIZE=64k
+IMGFMT=parallels
+_make_test_img $size
+
+echo == read empty image ==
+{ $QEMU_IO -c "read -P 0 32k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+echo == write more than 1 block in a row ==
+{ $QEMU_IO -c "write -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+echo == read less than block ==
+{ $QEMU_IO -c "read -P 0x11 32k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+echo == read exactly 1 block ==
+{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+echo == read more than 1 block ==
+{ $QEMU_IO -c "read -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+echo == check that there is no trash after written ==
+{ $QEMU_IO -c "read -P 0 160k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+echo == check that there is no trash before written ==
+{ $QEMU_IO -c "read -P 0 0 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/115.out b/tests/qemu-iotests/115.out
new file mode 100644
index 0000000..6a73104
--- /dev/null
+++ b/tests/qemu-iotests/115.out
@@ -0,0 +1,24 @@
+QA output created by 115
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+== read empty image ==
+read 65536/65536 bytes at offset 32768
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== write more than 1 block in a row ==
+wrote 131072/131072 bytes at offset 32768
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== read less than block ==
+read 32768/32768 bytes at offset 32768
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== read exactly 1 block ==
+read 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== read more than 1 block ==
+read 131072/131072 bytes at offset 32768
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== check that there is no trash after written ==
+read 32768/32768 bytes at offset 163840
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== check that there is no trash before written ==
+read 32768/32768 bytes at offset 0
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index a4742c6..77377b3 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -115,3 +115,4 @@
111 rw auto quick
113 rw auto quick
114 rw auto quick
+115 rw auto quick
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 12/12] parallels: change copyright information in the image header
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
` (10 preceding siblings ...)
2014-12-22 13:06 ` [Qemu-devel] [PATCH 11/12] iotests, parallels: test for newly created parallels image via qemu-img Denis V. Lunev
@ 2014-12-22 13:06 ` Denis V. Lunev
11 siblings, 0 replies; 13+ messages in thread
From: Denis V. Lunev @ 2014-12-22 13:06 UTC (permalink / raw)
Cc: Denis V. Lunev, qemu-devel
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Roman Kagan <rkagan@parallels.com>
---
block/parallels.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/block/parallels.c b/block/parallels.c
index bea1217..e3abf4e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -2,8 +2,12 @@
* Block driver for Parallels disk image format
*
* Copyright (c) 2007 Alex Beregszaszi
+ * Copyright (c) 2014 Denis V. Lunev <den@openvz.org>
*
- * This code is based on comparing different disk images created by Parallels.
+ * This code was originally based on comparing different disk images created
+ * by Parallels. Currently it is based on opened OpenVZ sources
+ * available at
+ * http://git.openvz.org/?p=ploop;a=summary
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-12-22 13:05 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-22 13:05 [Qemu-devel] [PATCH 0/12] write/create for Parallels images Denis V. Lunev
2014-12-22 13:05 ` [Qemu-devel] [PATCH 01/12] iotests, parallels: quote TEST_IMG in 076 test to be path-safe Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 02/12] block/parallels: rename parallels_header to ParallelsHeader Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 03/12] block/parallels: switch to bdrv_read Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 04/12] block/parallels: read up to cluster end in one go Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 05/12] block/parallels: add get_block_status Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 06/12] block/parallels: provide _co_readv routine for parallels format driver Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 07/12] block/parallels: replace magic constants 4, 64 with proper sizeofs Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 08/12] block/parallels: _co_writev callback for Parallels format Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 09/12] iotests, parallels: test for write into Parallels image Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 10/12] block/parallels: support parallels image creation Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 11/12] iotests, parallels: test for newly created parallels image via qemu-img Denis V. Lunev
2014-12-22 13:06 ` [Qemu-devel] [PATCH 12/12] parallels: change copyright information in the image header Denis V. Lunev
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).