[Qemu-block] [PATCH v6 1/8] vmdk: Move vmdk_find_offset_in_cluster() to the top

2017-06-05 Thread Ashijeet Acharya
Move the existing vmdk_find_offset_in_cluster() function to the top of
the driver.

Signed-off-by: Ashijeet Acharya 
Reviewed-by: Fam Zheng 
---
 block/vmdk.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index a9bd22b..22be887 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -242,6 +242,18 @@ static void vmdk_free_last_extent(BlockDriverState *bs)
 s->extents = g_renew(VmdkExtent, s->extents, s->num_extents);
 }
 
+static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
+   int64_t offset)
+{
+uint64_t extent_begin_offset, extent_relative_offset;
+uint64_t cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE;
+
+extent_begin_offset =
+(extent->end_sector - extent->sectors) * BDRV_SECTOR_SIZE;
+extent_relative_offset = offset - extent_begin_offset;
+return extent_relative_offset % cluster_size;
+}
+
 static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 {
 char *desc;
@@ -1266,18 +1278,6 @@ static VmdkExtent *find_extent(BDRVVmdkState *s,
 return NULL;
 }
 
-static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
-   int64_t offset)
-{
-uint64_t extent_begin_offset, extent_relative_offset;
-uint64_t cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE;
-
-extent_begin_offset =
-(extent->end_sector - extent->sectors) * BDRV_SECTOR_SIZE;
-extent_relative_offset = offset - extent_begin_offset;
-return extent_relative_offset % cluster_size;
-}
-
 static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent,
   int64_t sector_num)
 {
-- 
2.6.2




[Qemu-block] [PATCH v6 0/8] Optimize VMDK I/O by allocating multiple clusters

2017-06-05 Thread Ashijeet Acharya
Previously posted series patches:
v1 - http://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg02044.html
v2 - http://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg05080.html
v3 - http://lists.nongnu.org/archive/html/qemu-devel/2017-04/msg00074.html
v4 - http://lists.nongnu.org/archive/html/qemu-devel/2017-04/msg03851.html
v5 - http://lists.nongnu.org/archive/html/qemu-devel/2017-06/msg00929.html

This series helps to optimize the I/O performance of VMDK driver.

Patch 1 helps us to move vmdk_find_offset_in_cluster.

Patch 2 & 3 perform a simple function re-naming tasks.

Patch 4 is used to factor out metadata loading code and implement it in separate
functions. This will help us to avoid code duplication in future patches of this
series.

Patch 5 helps to set the upper limit of the bytes handled in one cycle.

Patch 6 adds new functions to help us allocate multiple clusters according to
the size requested, perform COW if required and return the offset of the first
newly allocated cluster.

Patch 7 changes the metadata update code to update the L2 tables for multiple
clusters at once.

Patch 8 helps us to finally change vmdk_get_cluster_offset() to find cluster 
offset
only as cluster allocation task is now handled by vmdk_alloc_clusters()

Optimization test results:

This patch series improves 128 KB sequential write performance to an
empty VMDK file by 54%

Benchmark command: ./qemu-img bench -w -c 1024 -s 128K -d 1 -t none -f
vmdk test.vmdk

Changes in v6:
- rename total_alloc_clusters as alloc_clusters_counter (fam)

Changes in v5:
- fix commit message and comment in patch 4 (fam)
- add vmdk_ prefix to handle_alloc() (fam)
- fix alignment issue in patch 6 (fam)
- use BDRV_SECTOR_BITS (fam)
- fix endianness calculation in patch 7 (fam)

Changes in v4:
- fix commit message in patch 1 (fam)
- drop size_to_clusters() function (fam)
- fix grammatical errors in function documentations (fam)
- factor out metadata loading coding in a separate patch (patch 4) (fam)
- rename vmdk_alloc_cluster_offset() to vmdk_alloc_clusters() (fam)
- break patch 4(in v3) into separate patches (patch 3 and 8) (fam)
- rename extent_size to extent_end (fam)
- use QEMU_ALIGN_UP instead of vmdk_align_offset. (fam)
- drop next and simply do m_data = m_data->next (fam)

Changes in v3:
- move size_to_clusters() from patch 1 to 3 (fam)
- use DIV_ROUND_UP in size_to_clusters (fam)
- make patch 2 compilable (fam)
- rename vmdk_L2update as vmdk_l2update and use UINT32_MAX (fam)
- combine patch 3 and patch 4 (as in v2) to make them compilable (fam)
- call bdrv_pwrite_sync() for batches of atmost 512 clusters at once (fam)

Changes in v2:
- segregate the ugly Patch 1 in v1 into 6 readable and sensible patches
- include benchmark test results in v2

Ashijeet Acharya (8):
  vmdk: Move vmdk_find_offset_in_cluster() to the top
  vmdk: Rename get_whole_cluster() to vmdk_perform_cow()
  vmdk: Rename get_cluster_offset() to vmdk_get_cluster_offset()
  vmdk: Factor out metadata loading code out of
vmdk_get_cluster_offset()
  vmdk: Set maximum bytes allocated in one cycle
  vmdk: New functions to assist allocating multiple clusters
  vmdk: Update metadata for multiple clusters
  vmdk: Make vmdk_get_cluster_offset() return cluster offset only

 block/vmdk.c | 529 +--
 1 file changed, 407 insertions(+), 122 deletions(-)

-- 
2.6.2




[Qemu-block] [PATCH v6 3/8] vmdk: Rename get_cluster_offset() to vmdk_get_cluster_offset()

2017-06-05 Thread Ashijeet Acharya
Rename the existing get_cluster_offset() to vmdk_get_cluster_offset()
and update name in all the callers accordingly.

Signed-off-by: Ashijeet Acharya 
Reviewed-by: Fam Zheng 
---
 block/vmdk.c | 46 +++---
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 73ae786..f403981 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1144,7 +1144,7 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData 
*m_data,
 }
 
 /**
- * get_cluster_offset
+ * vmdk_get_cluster_offset
  *
  * Look up cluster offset in extent file by sector number, and store in
  * @cluster_offset.
@@ -1163,14 +1163,14 @@ static int vmdk_L2update(VmdkExtent *extent, 
VmdkMetaData *m_data,
  *  VMDK_UNALLOC if cluster is not mapped and @allocate is false.
  *  VMDK_ERROR if failed.
  */
-static int get_cluster_offset(BlockDriverState *bs,
-  VmdkExtent *extent,
-  VmdkMetaData *m_data,
-  uint64_t offset,
-  bool allocate,
-  uint64_t *cluster_offset,
-  uint64_t skip_start_bytes,
-  uint64_t skip_end_bytes)
+static int vmdk_get_cluster_offset(BlockDriverState *bs,
+   VmdkExtent *extent,
+   VmdkMetaData *m_data,
+   uint64_t offset,
+   bool allocate,
+   uint64_t *cluster_offset,
+   uint64_t skip_start_bytes,
+   uint64_t skip_end_bytes)
 {
 unsigned int l1_index, l2_offset, l2_index;
 int min_index, i, j;
@@ -1304,9 +1304,9 @@ static int64_t coroutine_fn 
vmdk_co_get_block_status(BlockDriverState *bs,
 return 0;
 }
 qemu_co_mutex_lock(&s->lock);
-ret = get_cluster_offset(bs, extent, NULL,
- sector_num * 512, false, &offset,
- 0, 0);
+ret = vmdk_get_cluster_offset(bs, extent, NULL,
+  sector_num * 512, false, &offset,
+  0, 0);
 qemu_co_mutex_unlock(&s->lock);
 
 index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
@@ -1497,8 +1497,8 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, 
uint64_t bytes,
 ret = -EIO;
 goto fail;
 }
-ret = get_cluster_offset(bs, extent, NULL,
- offset, false, &cluster_offset, 0, 0);
+ret = vmdk_get_cluster_offset(bs, extent, NULL,
+  offset, false, &cluster_offset, 0, 0);
 offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
 
 n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
@@ -1584,10 +1584,10 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t 
offset,
 n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
  - offset_in_cluster);
 
-ret = get_cluster_offset(bs, extent, &m_data, offset,
- !(extent->compressed || zeroed),
- &cluster_offset, offset_in_cluster,
- offset_in_cluster + n_bytes);
+ret = vmdk_get_cluster_offset(bs, extent, &m_data, offset,
+  !(extent->compressed || zeroed),
+  &cluster_offset, offset_in_cluster,
+  offset_in_cluster + n_bytes);
 if (extent->compressed) {
 if (ret == VMDK_OK) {
 /* Refuse write to allocated cluster for streamOptimized */
@@ -1596,8 +1596,8 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t 
offset,
 return -EIO;
 } else {
 /* allocate */
-ret = get_cluster_offset(bs, extent, &m_data, offset,
- true, &cluster_offset, 0, 0);
+ret = vmdk_get_cluster_offset(bs, extent, &m_data, offset,
+  true, &cluster_offset, 0, 0);
 }
 }
 if (ret == VMDK_ERROR) {
@@ -2229,9 +2229,9 @@ static int vmdk_check(BlockDriverState *bs, 
BdrvCheckResult *result,
 sector_num);
 break;
 }
-ret = get_cluster_offset(bs, extent, NULL,
- sector_num << BDRV_SECTOR_BITS,
- false, &cluster_offset, 0, 0);
+ret = vmdk_get_cluster_offset(bs, extent, NULL,
+  sector_num << BDRV_SECTOR_BITS,
+  false, &cluster_offset, 0, 0);
 if (ret == VMDK_ERROR) {
 fprintf(

[Qemu-block] [PATCH v6 2/8] vmdk: Rename get_whole_cluster() to vmdk_perform_cow()

2017-06-05 Thread Ashijeet Acharya
Rename the existing function get_whole_cluster() to vmdk_perform_cow()
as its sole purpose is to perform COW for the first and the last
allocated clusters if needed.

Signed-off-by: Ashijeet Acharya 
Reviewed-by: Fam Zheng 
---
 block/vmdk.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 22be887..73ae786 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1028,8 +1028,8 @@ static void vmdk_refresh_limits(BlockDriverState *bs, 
Error **errp)
 }
 }
 
-/**
- * get_whole_cluster
+/*
+ * vmdk_perform_cow
  *
  * Copy backing file's cluster that covers @sector_num, otherwise write zero,
  * to the cluster at @cluster_sector_num.
@@ -1037,13 +1037,18 @@ static void vmdk_refresh_limits(BlockDriverState *bs, 
Error **errp)
  * If @skip_start_sector < @skip_end_sector, the relative range
  * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
  * it for call to write user data in the request.
+ *
+ * Returns:
+ *   VMDK_OK:   on success
+ *
+ *   VMDK_ERROR:in error cases
  */
-static int get_whole_cluster(BlockDriverState *bs,
- VmdkExtent *extent,
- uint64_t cluster_offset,
- uint64_t offset,
- uint64_t skip_start_bytes,
- uint64_t skip_end_bytes)
+static int vmdk_perform_cow(BlockDriverState *bs,
+VmdkExtent *extent,
+uint64_t cluster_offset,
+uint64_t offset,
+uint64_t skip_start_bytes,
+uint64_t skip_end_bytes)
 {
 int ret = VMDK_OK;
 int64_t cluster_bytes;
@@ -1244,7 +1249,7 @@ static int get_cluster_offset(BlockDriverState *bs,
  * This problem may occur because of insufficient space on host disk
  * or inappropriate VM shutdown.
  */
-ret = get_whole_cluster(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
+ret = vmdk_perform_cow(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
 offset, skip_start_bytes, skip_end_bytes);
 if (ret) {
 return ret;
-- 
2.6.2




[Qemu-block] [PATCH v6 5/8] vmdk: Set maximum bytes allocated in one cycle

2017-06-05 Thread Ashijeet Acharya
Set the maximum bytes allowed to get allocated at once to be not more
than the extent size boundary to handle writes at two separate extents
appropriately.

Signed-off-by: Ashijeet Acharya 
Reviewed-by: Fam Zheng 
---
 block/vmdk.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 5647f53..fe2046b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1624,6 +1624,7 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t 
offset,
 uint64_t cluster_offset;
 uint64_t bytes_done = 0;
 VmdkMetaData m_data;
+uint64_t extent_end;
 
 if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) {
 error_report("Wrong offset: offset=0x%" PRIx64
@@ -1637,9 +1638,17 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t 
offset,
 if (!extent) {
 return -EIO;
 }
+extent_end = extent->end_sector * BDRV_SECTOR_SIZE;
+
 offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
-n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
- - offset_in_cluster);
+
+/* truncate n_bytes to first cluster because we need to perform COW */
+if (offset_in_cluster > 0) {
+n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
+ - offset_in_cluster);
+} else {
+n_bytes = MIN(bytes, extent_end - offset);
+}
 
 ret = vmdk_get_cluster_offset(bs, extent, &m_data, offset,
   !(extent->compressed || zeroed),
-- 
2.6.2




[Qemu-block] [PATCH v6 4/8] vmdk: Factor out metadata loading code out of vmdk_get_cluster_offset()

2017-06-05 Thread Ashijeet Acharya
Move the cluster tables loading code out of the existing
vmdk_get_cluster_offset() function and implement it in separate
get_cluster_table() and vmdk_l2load() functions.

Signed-off-by: Ashijeet Acharya 
Reviewed-by: Fam Zheng 
---
 block/vmdk.c | 153 ---
 1 file changed, 105 insertions(+), 48 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f403981..5647f53 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1143,6 +1143,105 @@ static int vmdk_L2update(VmdkExtent *extent, 
VmdkMetaData *m_data,
 return VMDK_OK;
 }
 
+/*
+ * vmdk_l2load
+ *
+ * Load a new L2 table into memory. If the table is in the cache, the cache
+ * is used; otherwise the L2 table is loaded from the image file.
+ *
+ * Returns:
+ *   VMDK_OK:   on success
+ *   VMDK_ERROR:in error cases
+ */
+static int vmdk_l2load(VmdkExtent *extent, uint64_t offset, int l2_offset,
+   uint32_t **new_l2_table, int *new_l2_index)
+{
+int min_index, i, j;
+uint32_t *l2_table;
+uint32_t min_count;
+
+for (i = 0; i < L2_CACHE_SIZE; i++) {
+if (l2_offset == extent->l2_cache_offsets[i]) {
+/* increment the hit count */
+if (++extent->l2_cache_counts[i] == UINT32_MAX) {
+for (j = 0; j < L2_CACHE_SIZE; j++) {
+extent->l2_cache_counts[j] >>= 1;
+}
+}
+l2_table = extent->l2_cache + (i * extent->l2_size);
+goto found;
+}
+}
+/* not found: load a new entry in the least used one */
+min_index = 0;
+min_count = UINT32_MAX;
+for (i = 0; i < L2_CACHE_SIZE; i++) {
+if (extent->l2_cache_counts[i] < min_count) {
+min_count = extent->l2_cache_counts[i];
+min_index = i;
+}
+}
+l2_table = extent->l2_cache + (min_index * extent->l2_size);
+if (bdrv_pread(extent->file,
+(int64_t)l2_offset * 512,
+l2_table,
+extent->l2_size * sizeof(uint32_t)
+) != extent->l2_size * sizeof(uint32_t)) {
+return VMDK_ERROR;
+}
+
+extent->l2_cache_offsets[min_index] = l2_offset;
+extent->l2_cache_counts[min_index] = 1;
+found:
+*new_l2_index = ((offset >> 9) / extent->cluster_sectors) % 
extent->l2_size;
+*new_l2_table = l2_table;
+
+return VMDK_OK;
+}
+
+/*
+ * get_cluster_table
+ *
+ * For a given offset, load (and allocate if needed) the l2 table.
+ *
+ * Returns:
+ *   VMDK_OK:on success
+ *
+ *   VMDK_UNALLOC:   if cluster is not mapped
+ *
+ *   VMDK_ERROR: in error cases
+ */
+static int get_cluster_table(VmdkExtent *extent, uint64_t offset,
+ int *new_l1_index, int *new_l2_offset,
+ int *new_l2_index, uint32_t **new_l2_table)
+{
+int l1_index, l2_offset, l2_index;
+uint32_t *l2_table;
+int ret;
+
+offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE;
+l1_index = (offset >> 9) / extent->l1_entry_sectors;
+if (l1_index >= extent->l1_size) {
+return VMDK_ERROR;
+}
+l2_offset = extent->l1_table[l1_index];
+if (!l2_offset) {
+return VMDK_UNALLOC;
+}
+
+ret = vmdk_l2load(extent, offset, l2_offset, &l2_table, &l2_index);
+if (ret < 0) {
+return ret;
+}
+
+*new_l1_index = l1_index;
+*new_l2_offset = l2_offset;
+*new_l2_index = l2_index;
+*new_l2_table = l2_table;
+
+return VMDK_OK;
+}
+
 /**
  * vmdk_get_cluster_offset
  *
@@ -1172,66 +1271,24 @@ static int vmdk_get_cluster_offset(BlockDriverState *bs,
uint64_t skip_start_bytes,
uint64_t skip_end_bytes)
 {
-unsigned int l1_index, l2_offset, l2_index;
-int min_index, i, j;
-uint32_t min_count, *l2_table;
+int l1_index, l2_offset, l2_index;
+uint32_t *l2_table;
 bool zeroed = false;
 int64_t ret;
 int64_t cluster_sector;
 
-if (m_data) {
-m_data->valid = 0;
-}
 if (extent->flat) {
 *cluster_offset = extent->flat_start_offset;
 return VMDK_OK;
 }
 
-offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE;
-l1_index = (offset >> 9) / extent->l1_entry_sectors;
-if (l1_index >= extent->l1_size) {
-return VMDK_ERROR;
-}
-l2_offset = extent->l1_table[l1_index];
-if (!l2_offset) {
-return VMDK_UNALLOC;
-}
-for (i = 0; i < L2_CACHE_SIZE; i++) {
-if (l2_offset == extent->l2_cache_offsets[i]) {
-/* increment the hit count */
-if (++extent->l2_cache_counts[i] == 0x) {
-for (j = 0; j < L2_CACHE_SIZE; j++) {
-extent->l2_cache_counts[j] >>= 1;
-}
-}
-l2_table = extent->l2_cache + (i * extent->l2_size);
-goto found;
-}
-}
-/* not found: load a new entry in t

[Qemu-block] [PATCH v6 6/8] vmdk: New functions to assist allocating multiple clusters

2017-06-05 Thread Ashijeet Acharya
Introduce two new helper functions handle_alloc() and
vmdk_alloc_cluster_offset(). handle_alloc() helps to allocate multiple
clusters at once starting from a given offset on disk and performs COW
if necessary for first and last allocated clusters.
vmdk_alloc_cluster_offset() helps to return the offset of the first of
the many newly allocated clusters. Also, provide proper documentation
for both.

Signed-off-by: Ashijeet Acharya 
---
 block/vmdk.c | 192 +++
 1 file changed, 182 insertions(+), 10 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index fe2046b..b671dc9 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -136,6 +136,7 @@ typedef struct VmdkMetaData {
 unsigned int l2_offset;
 int valid;
 uint32_t *l2_cache_entry;
+uint32_t nb_clusters;
 } VmdkMetaData;
 
 typedef struct VmdkGrainMarker {
@@ -1242,6 +1243,174 @@ static int get_cluster_table(VmdkExtent *extent, 
uint64_t offset,
 return VMDK_OK;
 }
 
+/*
+ * vmdk_handle_alloc
+ *
+ * Allocate new clusters for an area that either is yet unallocated or needs a
+ * copy on write. If *cluster_offset is non_zero, clusters are only allocated 
if
+ * the new allocation can match the specified host offset.
+ *
+ * Returns:
+ *   VMDK_OK:   if new clusters were allocated, *bytes may be decreased if
+ *  the new allocation doesn't cover all of the requested area.
+ *  *cluster_offset is updated to contain the offset of the
+ *  first newly allocated cluster.
+ *
+ *   VMDK_UNALLOC:  if no clusters could be allocated. *cluster_offset is left
+ *  unchanged.
+ *
+ *   VMDK_ERROR:in error cases
+ */
+static int vmdk_handle_alloc(BlockDriverState *bs, VmdkExtent *extent,
+ uint64_t offset, uint64_t *cluster_offset,
+ int64_t *bytes, VmdkMetaData *m_data,
+ bool allocate, uint32_t *alloc_clusters_counter)
+{
+int l1_index, l2_offset, l2_index;
+uint32_t *l2_table;
+uint32_t cluster_sector;
+uint32_t nb_clusters;
+bool zeroed = false;
+uint64_t skip_start_bytes, skip_end_bytes;
+int ret;
+
+ret = get_cluster_table(extent, offset, &l1_index, &l2_offset,
+&l2_index, &l2_table);
+if (ret < 0) {
+return ret;
+}
+
+cluster_sector = le32_to_cpu(l2_table[l2_index]);
+
+skip_start_bytes = vmdk_find_offset_in_cluster(extent, offset);
+/* Calculate the number of clusters to look for. Here we truncate the last
+ * cluster, i.e. 1 less than the actual value calculated as we may need to
+ * perform COW for the last one. */
+nb_clusters = DIV_ROUND_UP(skip_start_bytes + *bytes,
+   extent->cluster_sectors << BDRV_SECTOR_BITS) - 
1;
+
+nb_clusters = MIN(nb_clusters, extent->l2_size - l2_index);
+assert(nb_clusters <= INT_MAX);
+
+/* update bytes according to final nb_clusters value */
+if (nb_clusters != 0) {
+*bytes = ((nb_clusters * extent->cluster_sectors) << BDRV_SECTOR_BITS)
+ - skip_start_bytes;
+} else {
+nb_clusters = 1;
+}
+*alloc_clusters_counter += nb_clusters;
+skip_end_bytes = skip_start_bytes + MIN(*bytes,
+ extent->cluster_sectors * BDRV_SECTOR_SIZE
+- skip_start_bytes);
+
+if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
+zeroed = true;
+}
+
+if (!cluster_sector || zeroed) {
+if (!allocate) {
+return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
+}
+
+cluster_sector = extent->next_cluster_sector;
+extent->next_cluster_sector += extent->cluster_sectors
+* nb_clusters;
+
+ret = vmdk_perform_cow(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
+   offset, skip_start_bytes,
+   skip_end_bytes);
+if (ret < 0) {
+return ret;
+}
+if (m_data) {
+m_data->valid = 1;
+m_data->l1_index = l1_index;
+m_data->l2_index = l2_index;
+m_data->l2_offset = l2_offset;
+m_data->l2_cache_entry = &l2_table[l2_index];
+m_data->nb_clusters = nb_clusters;
+}
+}
+*cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
+return VMDK_OK;
+}
+
+/*
+ * vmdk_alloc_clusters
+ *
+ * For a given offset on the virtual disk, find the cluster offset in vmdk
+ * file. If the offset is not found, allocate a new cluster.
+ *
+ * If the cluster is newly allocated, m_data->nb_clusters is set to the number
+ * of contiguous clusters that have been allocated. In this case, the other
+ * fields of m_data are valid and contain information about the first allocated
+ * cluster.
+ *
+ * Returns:
+ *
+ *   VMDK_OK:   on success a

[Qemu-block] [PATCH v6 7/8] vmdk: Update metadata for multiple clusters

2017-06-05 Thread Ashijeet Acharya
Include a next pointer in VmdkMetaData struct to point to the previous
allocated L2 table. Modify vmdk_L2update to start updating metadata for
allocation of multiple clusters at once.

Signed-off-by: Ashijeet Acharya 
---
 block/vmdk.c | 128 ++-
 1 file changed, 101 insertions(+), 27 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index b671dc9..9fa2414 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -137,6 +137,8 @@ typedef struct VmdkMetaData {
 int valid;
 uint32_t *l2_cache_entry;
 uint32_t nb_clusters;
+uint32_t offset;
+struct VmdkMetaData *next;
 } VmdkMetaData;
 
 typedef struct VmdkGrainMarker {
@@ -1116,34 +1118,87 @@ exit:
 return ret;
 }
 
-static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
- uint32_t offset)
+static int vmdk_alloc_cluster_link_l2(VmdkExtent *extent,
+  VmdkMetaData *m_data, bool zeroed)
 {
-offset = cpu_to_le32(offset);
+int i;
+uint32_t offset, temp_offset;
+int *l2_table_array;
+int l2_array_size;
+
+if (zeroed) {
+temp_offset = VMDK_GTE_ZEROED;
+} else {
+temp_offset = m_data->offset;
+}
+
+l2_array_size = sizeof(uint32_t) * m_data->nb_clusters;
+l2_table_array = qemu_try_blockalign(extent->file->bs,
+ QEMU_ALIGN_UP(l2_array_size,
+   BDRV_SECTOR_SIZE));
+if (l2_table_array == NULL) {
+return VMDK_ERROR;
+}
+memset(l2_table_array, 0, QEMU_ALIGN_UP(l2_array_size, BDRV_SECTOR_SIZE));
 /* update L2 table */
+offset = temp_offset;
+for (i = 0; i < m_data->nb_clusters; i++) {
+l2_table_array[i] = cpu_to_le32(offset);
+if (!zeroed) {
+offset += 128;
+}
+}
 if (bdrv_pwrite_sync(extent->file,
-((int64_t)m_data->l2_offset * 512)
-+ (m_data->l2_index * sizeof(offset)),
-&offset, sizeof(offset)) < 0) {
+ ((int64_t)m_data->l2_offset * 512)
+ + ((m_data->l2_index) * sizeof(offset)),
+ l2_table_array, l2_array_size) < 0) {
 return VMDK_ERROR;
 }
 /* update backup L2 table */
 if (extent->l1_backup_table_offset != 0) {
 m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
 if (bdrv_pwrite_sync(extent->file,
-((int64_t)m_data->l2_offset * 512)
-+ (m_data->l2_index * sizeof(offset)),
-&offset, sizeof(offset)) < 0) {
+ ((int64_t)m_data->l2_offset * 512)
+ + ((m_data->l2_index) * sizeof(offset)),
+ l2_table_array, l2_array_size) < 0) {
 return VMDK_ERROR;
 }
 }
+
+offset = temp_offset;
 if (m_data->l2_cache_entry) {
-*m_data->l2_cache_entry = offset;
+for (i = 0; i < m_data->nb_clusters; i++) {
+*m_data->l2_cache_entry = cpu_to_le32(offset);
+m_data->l2_cache_entry++;
+
+if (!zeroed) {
+offset += 128;
+}
+}
 }
 
+qemu_vfree(l2_table_array);
 return VMDK_OK;
 }
 
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
+ bool zeroed)
+{
+int ret;
+
+while (m_data->next != NULL) {
+
+ret = vmdk_alloc_cluster_link_l2(extent, m_data, zeroed);
+if (ret < 0) {
+return ret;
+}
+
+m_data = m_data->next;
+ }
+
+ return VMDK_OK;
+}
+
 /*
  * vmdk_l2load
  *
@@ -1261,9 +1316,10 @@ static int get_cluster_table(VmdkExtent *extent, 
uint64_t offset,
  *
  *   VMDK_ERROR:in error cases
  */
+
 static int vmdk_handle_alloc(BlockDriverState *bs, VmdkExtent *extent,
  uint64_t offset, uint64_t *cluster_offset,
- int64_t *bytes, VmdkMetaData *m_data,
+ int64_t *bytes, VmdkMetaData **m_data,
  bool allocate, uint32_t *alloc_clusters_counter)
 {
 int l1_index, l2_offset, l2_index;
@@ -1272,6 +1328,7 @@ static int vmdk_handle_alloc(BlockDriverState *bs, 
VmdkExtent *extent,
 uint32_t nb_clusters;
 bool zeroed = false;
 uint64_t skip_start_bytes, skip_end_bytes;
+VmdkMetaData *old_m_data;
 int ret;
 
 ret = get_cluster_table(extent, offset, &l1_index, &l2_offset,
@@ -1323,13 +1380,21 @@ static int vmdk_handle_alloc(BlockDriverState *bs, 
VmdkExtent *extent,
 if (ret < 0) {
 return ret;
 }
-if (m_data) {
-m_data->valid = 1;
-m_data->l1_index = l1_index;
-m_data->l2_index = l2_index;
-m_data->l2_offset = l2_offset;
-m_data->l2_cache_entry = &l2_table[l2_index];
- 

[Qemu-block] [PATCH v6 8/8] vmdk: Make vmdk_get_cluster_offset() return cluster offset only

2017-06-05 Thread Ashijeet Acharya
vmdk_alloc_clusters() introduced earlier now handles the task of
allocating clusters and performing COW when needed. Thus we can change
vmdk_get_cluster_offset() to stick to the sole purpose of returning
cluster offset using sector number. Update the changes at all call
sites.

Signed-off-by: Ashijeet Acharya 
---
 block/vmdk.c | 56 
 1 file changed, 12 insertions(+), 44 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 9fa2414..accf1c3 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1485,25 +1485,16 @@ static int vmdk_alloc_clusters(BlockDriverState *bs,
  * For flat extents, the start offset as parsed from the description file is
  * returned.
  *
- * For sparse extents, look up in L1, L2 table. If allocate is true, return an
- * offset for a new cluster and update L2 cache. If there is a backing file,
- * COW is done before returning; otherwise, zeroes are written to the allocated
- * cluster. Both COW and zero writing skips the sector range
- * [@skip_start_sector, @skip_end_sector) passed in by caller, because caller
- * has new data to write there.
+ * For sparse extents, look up the L1, L2 table.
  *
  * Returns: VMDK_OK if cluster exists and mapped in the image.
- *  VMDK_UNALLOC if cluster is not mapped and @allocate is false.
- *  VMDK_ERROR if failed.
+ *  VMDK_UNALLOC if cluster is not mapped.
+ *  VMDK_ERROR if failed
  */
 static int vmdk_get_cluster_offset(BlockDriverState *bs,
VmdkExtent *extent,
-   VmdkMetaData *m_data,
uint64_t offset,
-   bool allocate,
-   uint64_t *cluster_offset,
-   uint64_t skip_start_bytes,
-   uint64_t skip_end_bytes)
+   uint64_t *cluster_offset)
 {
 int l1_index, l2_offset, l2_index;
 uint32_t *l2_table;
@@ -1528,31 +1519,9 @@ static int vmdk_get_cluster_offset(BlockDriverState *bs,
 }
 
 if (!cluster_sector || zeroed) {
-if (!allocate) {
-return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
-}
-
-cluster_sector = extent->next_cluster_sector;
-extent->next_cluster_sector += extent->cluster_sectors;
-
-/* First of all we write grain itself, to avoid race condition
- * that may to corrupt the image.
- * This problem may occur because of insufficient space on host disk
- * or inappropriate VM shutdown.
- */
-ret = vmdk_perform_cow(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
-offset, skip_start_bytes, skip_end_bytes);
-if (ret) {
-return ret;
-}
-if (m_data) {
-m_data->valid = 1;
-m_data->l1_index = l1_index;
-m_data->l2_index = l2_index;
-m_data->l2_offset = l2_offset;
-m_data->l2_cache_entry = &l2_table[l2_index];
-}
+return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
 }
+
 *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
 return VMDK_OK;
 }
@@ -1595,9 +1564,7 @@ static int64_t coroutine_fn 
vmdk_co_get_block_status(BlockDriverState *bs,
 return 0;
 }
 qemu_co_mutex_lock(&s->lock);
-ret = vmdk_get_cluster_offset(bs, extent, NULL,
-  sector_num * 512, false, &offset,
-  0, 0);
+ret = vmdk_get_cluster_offset(bs, extent, sector_num * 512, &offset);
 qemu_co_mutex_unlock(&s->lock);
 
 index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
@@ -1788,13 +1755,14 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, 
uint64_t bytes,
 ret = -EIO;
 goto fail;
 }
-ret = vmdk_get_cluster_offset(bs, extent, NULL,
-  offset, false, &cluster_offset, 0, 0);
+
 offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
 
 n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
  - offset_in_cluster);
 
+ret = vmdk_get_cluster_offset(bs, extent, offset, &cluster_offset);
+
 if (ret != VMDK_OK) {
 /* if not allocated, try to read from parent image, if exist */
 if (bs->backing && ret != VMDK_ZEROED) {
@@ -2541,9 +2509,9 @@ static int vmdk_check(BlockDriverState *bs, 
BdrvCheckResult *result,
 sector_num);
 break;
 }
-ret = vmdk_get_cluster_offset(bs, extent, NULL,
+ret = vmdk_get_cluster_offset(bs, extent,
   sector_num << BDRV_SECTOR_BITS,
-  false, &cluster_offset, 0, 0);
+  &cluster_offset);
 if (ret == VMDK_ERROR) {
 

Re: [Qemu-block] [Qemu-devel] [PATCH v2 06/16] backup: Request BLK_PERM_AIO_CONTEXT_CHANGE on target

2017-06-05 Thread Fam Zheng
On Thu, 06/01 14:26, Stefan Hajnoczi wrote:
> On Wed, May 31, 2017 at 05:57:46PM +0800, Fam Zheng wrote:
> > On Wed, 05/31 10:39, Stefan Hajnoczi wrote:
> > > On Wed, May 24, 2017 at 10:18:44AM +0800, Fam Zheng wrote:
> > > > On Thu, 05/11 15:41, Stefan Hajnoczi wrote:
> > > > > On Wed, Apr 19, 2017 at 05:43:46PM +0800, Fam Zheng wrote:
> > > > > > What's done in the source's context change notifier is moving the
> > > > > > target's context to follow the new one, so we request this 
> > > > > > permission
> > > > > > here.
> > > > > 
> > > > > It's true that the backup block job must be able to set target's
> > > > > AioContext, but does this change also allow other users to set 
> > > > > target's
> > > > > AioContext while the backup job is running?  If yes, then we need to
> > > > > handle that.
> > > > 
> > > > If through job->target, yes, but I don't think there is any user of 
> > > > job->target.
> > > > Otherwise, it's not allowed, because the second parameter of blk_new 
> > > > doesn't
> > > > have BLK_PERM_AIO_CONTEXT_CHANGE.
> > > > 
> > > > So it's okay.
> > > 
> > > What about blockdev-backup?  It allows the user to specify 'target'.
> > > Therefore the user can also run other monitor commands on target.  Some
> > > of them could change the AioContext and the backup job wouldn't know!
> > 
> > That will be rejected.
> > 
> > The contract is that any code that wants to change the AioContext of a BDS, 
> > in
> > this case the "target BDS", must do this:
> > 
> > 1) create its own BB with perm.BLK_PERM_AIO_CONTEXT_CHANGE
> > 
> > 2) attach BDS to this BB
> > 
> > 3) call blk_set_aio_context and change the AioContext
> > 
> > This is basically how all users of a BDS coordinate through Kevin's new op
> > blocker API, and in your concerned case, when a user runs a second monitor
> > command that changes AioContext, step 2 will fail, because as in this 
> > patch, the
> > first job->target BB didn't set shared_perm.BLK_PERM_AIO_CONTEXT_CHANGE.
> 
> I was wondering how that works since do_blockdev_backup() does not use
> BB to access target, but it does check whether a BB is already attached:
> 
> target_bs = bdrv_lookup_bs(backup->target, backup->target, errp);
> if (!target_bs) {
> goto out;
> }
> 
> if (bdrv_get_aio_context(target_bs) != aio_context) {
> if (!bdrv_has_blk(target_bs)) {   <- fails when job is running
> /* The target BDS is not attached, we can safely move it to 
> another
>  * AioContext. */
> bdrv_set_aio_context(target_bs, aio_context);
> } else {
> error_setg(errp, "Target is attached to a different thread from "
>  "source.");
> goto out;
> }
> }

Yeah, this is the current way (before this series), and is incomplete in some
cases but too strict in others, for obvious reasons.  It is changed to always
create a BB in patch 7.

Fam



[Qemu-block] [PATCH v1 0/1] qemu/migration: fix the migration bug found by qemu-iotests case 068

2017-06-05 Thread QingFeng Hao
Hi all,
This patch is to fix the migration bug found by qemu-iotests case 068
and based on upstream master's commit:
cb8b8ef4578:  Merge remote-tracking branch 
'remotes/elmarco/tags/chrfe-pull-request' into staging.
The bug was introduced by commit "660819b migration: shut src return path 
unconditionally".
Thanks!

QingFeng Hao (1):
  qemu/migration: fix the double free problem on from_src_file

 migration/savevm.c | 1 -
 1 file changed, 1 deletion(-)

-- 
2.11.2




[Qemu-block] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread QingFeng Hao
In load_vmstate, mis->from_src_file is freed twice, the first free is by
qemu_fclose, the second is by migration_incoming_state_destroy and
it causes Illegal instruction exception. The fix is just to remove the
first free.

This problem is found by qemu-iotests case 068 since commit
"660819b migration: shut src return path unconditionally". The error is:
068 1s ... - output mismatch (see 068.out.bad)
--- tests/qemu-iotests/068.out  2017-05-06 01:00:26.417270437 +0200
+++ 068.out.bad 2017-06-03 13:59:55.360274640 +0200
@@ -6,6 +6,8 @@
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm 0
 (qemu) quit
+./common.config: line 107: 242472 Illegal instruction (core dumped) ( 
if [ -n "${QEMU_NEED_PID}" ]; then
+echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
+fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
 QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) quit
-*** done
+(qemu) *** done

Signed-off-by: QingFeng Hao 
---
 migration/savevm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f59d0..853e14e34e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
 
 aio_context_acquire(aio_context);
 ret = qemu_loadvm_state(f);
-qemu_fclose(f);
 aio_context_release(aio_context);
 
 migration_incoming_state_destroy();
-- 
2.11.2




Re: [Qemu-block] [Qemu-devel] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread Dr. David Alan Gilbert
* QingFeng Hao (ha...@linux.vnet.ibm.com) wrote:
> In load_vmstate, mis->from_src_file is freed twice, the first free is by
> qemu_fclose, the second is by migration_incoming_state_destroy and
> it causes Illegal instruction exception. The fix is just to remove the
> first free.
> 
> This problem is found by qemu-iotests case 068 since commit
> "660819b migration: shut src return path unconditionally". The error is:
> 068 1s ... - output mismatch (see 068.out.bad)
> --- tests/qemu-iotests/068.out2017-05-06 01:00:26.417270437 +0200
> +++ 068.out.bad   2017-06-03 13:59:55.360274640 +0200
> @@ -6,6 +6,8 @@
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) savevm 0
>  (qemu) quit
> +./common.config: line 107: 242472 Illegal instruction (core dumped) 
> ( if [ -n "${QEMU_NEED_PID}" ]; then
> +echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
> +fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
>  QEMU X.Y.Z monitor - type 'help' for more information
> -(qemu) quit
> -*** done
> +(qemu) *** done
> 
> Signed-off-by: QingFeng Hao 
> ---
>  migration/savevm.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/migration/savevm.c b/migration/savevm.c
> index 9c320f59d0..853e14e34e 100644
> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
>  
>  aio_context_acquire(aio_context);
>  ret = qemu_loadvm_state(f);
> -qemu_fclose(f);
>  aio_context_release(aio_context);

Thanks!

Reviewed-by: Dr. David Alan Gilbert 

>  
>  migration_incoming_state_destroy();
> -- 
> 2.11.2
> 
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



[Qemu-block] [PATCH] block/qcow.c: Fix memory leak in qcow_create()

2017-06-05 Thread Peter Maydell
Coverity points out that the code path in qcow_create() for
the magic "fat:" backing file name leaks the memory used to
store the filename (CID 1307771). Free the memory before
we overwrite the pointer.

Signed-off-by: Peter Maydell 
---
 block/qcow.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qcow.c b/block/qcow.c
index 95ab123..7bd94dc 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -852,6 +852,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 header_size += backing_filename_len;
 } else {
 /* special backing file for vvfat */
+g_free(backing_file);
 backing_file = NULL;
 }
 header.cluster_bits = 9; /* 512 byte cluster to avoid copying
-- 
2.7.4




Re: [Qemu-block] [Qemu-devel] [PATCH] block/qcow.c: Fix memory leak in qcow_create()

2017-06-05 Thread Eric Blake
On 06/05/2017 08:55 AM, Peter Maydell wrote:
> Coverity points out that the code path in qcow_create() for
> the magic "fat:" backing file name leaks the memory used to
> store the filename (CID 1307771). Free the memory before
> we overwrite the pointer.
> 
> Signed-off-by: Peter Maydell 
> ---
>  block/qcow.c | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Eric Blake 

> 
> diff --git a/block/qcow.c b/block/qcow.c
> index 95ab123..7bd94dc 100644
> --- a/block/qcow.c
> +++ b/block/qcow.c
> @@ -852,6 +852,7 @@ static int qcow_create(const char *filename, QemuOpts 
> *opts, Error **errp)
>  header_size += backing_filename_len;
>  } else {
>  /* special backing file for vvfat */
> +g_free(backing_file);
>  backing_file = NULL;
>  }
>  header.cluster_bits = 9; /* 512 byte cluster to avoid copying
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-block] [Qemu-devel] [PATCH] block/qcow.c: Fix memory leak in qcow_create()

2017-06-05 Thread Philippe Mathieu-Daudé

On 06/05/2017 10:55 AM, Peter Maydell wrote:

Coverity points out that the code path in qcow_create() for
the magic "fat:" backing file name leaks the memory used to
store the filename (CID 1307771). Free the memory before
we overwrite the pointer.

Signed-off-by: Peter Maydell 


Reviewed-by: Philippe Mathieu-Daudé 


---
 block/qcow.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qcow.c b/block/qcow.c
index 95ab123..7bd94dc 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -852,6 +852,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 header_size += backing_filename_len;
 } else {
 /* special backing file for vvfat */
+g_free(backing_file);
 backing_file = NULL;
 }
 header.cluster_bits = 9; /* 512 byte cluster to avoid copying





[Qemu-block] [PATCH] block/gluster.c: Handle qdict_array_entries() failure

2017-06-05 Thread Peter Maydell
In qemu_gluster_parse_json(), the call to qdict_array_entries()
could return a negative error code, which we were ignoring
because we assigned the result to an unsigned variable.
Fix this by using the 'int' type instead, which matches the
return type of qdict_array_entries() and also the type
we use for the loop enumeration variable 'i'.

(Spotted by Coverity, CID 1360960.)

Signed-off-by: Peter Maydell 
---
 block/gluster.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 031596a..addceed 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -493,8 +493,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 Error *local_err = NULL;
 char *str = NULL;
 const char *ptr;
-size_t num_servers;
-int i, type;
+int i, type, num_servers;
 
 /* create opts info from runtime_json_opts list */
 opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);
-- 
2.7.4




Re: [Qemu-block] [Qemu-devel] [PATCH] block/gluster.c: Handle qdict_array_entries() failure

2017-06-05 Thread Eric Blake
On 06/05/2017 12:01 PM, Peter Maydell wrote:
> In qemu_gluster_parse_json(), the call to qdict_array_entries()
> could return a negative error code, which we were ignoring
> because we assigned the result to an unsigned variable.
> Fix this by using the 'int' type instead, which matches the
> return type of qdict_array_entries() and also the type
> we use for the loop enumeration variable 'i'.
> 
> (Spotted by Coverity, CID 1360960.)
> 
> Signed-off-by: Peter Maydell 
> ---
>  block/gluster.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-block] [PATCH v3 1/4] qemu-io: Don't die on second open

2017-06-05 Thread Eric Blake
Most callback commands in qemu-io return 0 to keep the interpreter
loop running, or 1 to quit immediately.  However, open_f() just
passed through the return value of openfile(), which has different
semantics of returning 0 if a file was opened, or 1 on any failure.

As a result of mixing the return semantics, we are forcing the
qemu-io interpreter to exit early on any failures, which is rather
annoying when some of the failures are obviously trying to give
the user a hint of how to proceed (if we didn't then kill qemu-io
out from under the user's feet):

$ qemu-io
qemu-io> open foo
qemu-io> open foo
file open already, try 'help close'
$ echo $?
0

In general, we WANT openfile() to report failures, since it is the
function used in the form 'qemu-io -c "$something" no_such_file'
for performing one or more -c options on a single file, and it is
not worth attempting $something if the file itself cannot be opened.
So the solution is to fix open_f() to always return 0 (when we are
in interactive mode, even failure to open should not end the
session), and save the return value of openfile() for command line
use in main().

Note, however, that we do have some qemu-iotests that do 'qemu-io
-c "open file" -c "$something"'; such tests will now proceed to
attempt $something whether or not the open succeeded, the same way
as if the two commands had been attempted in interactive mode; but it
also means that it is now possible to use -c close and have a single
qemu-io command line operate on more than one file even without
using interactive mode.  Although the '-c open' action is a subtle
change in behavior, remember that qemu-io is for debugging purposes,
so as long as it serves the needs of qemu-iotests while still being
reasonable for interactive use, it should not be a problem.

This has been awkward since at least as far back as commit
e3aff4f, in 2009.

Signed-off-by: Eric Blake 
Reviewed-by: Fam Zheng 

---
v3: tweak commit message to distinguish that '-c open' has a subtle
new behavior from the command line
v2: fix open_f(), not openfile()
---
 qemu-io.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index 8e38b28..8074656 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -230,13 +230,14 @@ static int open_f(BlockBackend *blk, int argc, char 
**argv)
 qemu_opts_reset(&empty_opts);

 if (optind == argc - 1) {
-return openfile(argv[optind], flags, writethrough, force_share, opts);
+openfile(argv[optind], flags, writethrough, force_share, opts);
 } else if (optind == argc) {
-return openfile(NULL, flags, writethrough, force_share, opts);
+openfile(NULL, flags, writethrough, force_share, opts);
 } else {
 QDECREF(opts);
-return qemuio_command_usage(&open_cmd);
+qemuio_command_usage(&open_cmd);
 }
+return 0;
 }

 static int quit_f(BlockBackend *blk, int argc, char **argv)
-- 
2.9.4




[Qemu-block] [PATCH v3 0/4] more blkdebug tweaks

2017-06-05 Thread Eric Blake
I found a crasher and some odd behavior while rebasing my
bdrv_get_block_status series, so I figured I'd get these things
fixed first.  This is based on top of Max's block branch.

Available as a tag at:
git fetch git://repo.or.cz/qemu/ericb.git nbd-blkdebug-status-v3

Since v2:
- defer the original patch 3 to a later series
- rebase to make sure test 177 passes at all times (I didn't
pinpoint which recent merge caused it, but the test now produces
json:{...} instead of blkdebug:... during patch 2)
- add more documentation of BDRV_BLOCK_RAW
- add R-b where appropriate

001/4:[] [--] 'qemu-io: Don't die on second open'
002/4:[0002] [FC] 'block: Guarantee that *file is set on 
bdrv_get_block_status()'
003/4:[0006] [FC] 'block: Simplify use of BDRV_BLOCK_RAW'
004/4:[0002] [FC] 'blkdebug: Support .bdrv_co_get_block_status'

Eric Blake (4):
  qemu-io: Don't die on second open
  block: Guarantee that *file is set on bdrv_get_block_status()
  block: Simplify use of BDRV_BLOCK_RAW
  blkdebug: Support .bdrv_co_get_block_status

 include/block/block.h  |  6 +++---
 block/blkdebug.c   | 11 +++
 block/commit.c |  2 +-
 block/io.c |  5 +++--
 block/mirror.c |  2 +-
 block/raw-format.c |  2 +-
 block/vpc.c|  2 +-
 qemu-io.c  |  7 ---
 tests/qemu-iotests/177 |  3 +++
 tests/qemu-iotests/177.out |  5 +
 10 files changed, 33 insertions(+), 12 deletions(-)

-- 
2.9.4




[Qemu-block] [PATCH v3 4/4] blkdebug: Support .bdrv_co_get_block_status

2017-06-05 Thread Eric Blake
Without a passthrough status of BDRV_BLOCK_RAW, anything wrapped by
blkdebug appears 100% allocated as data.  Better is treating it the
same as the underlying file being wrapped.

Update iotest 177 for the new expected output.

Signed-off-by: Eric Blake 
Reviewed-by: Fam Zheng 
Reviewed-by: Max Reitz 

---
v3: rebase to earlier changes
v2: tweak commit message
---
 block/blkdebug.c   | 11 +++
 tests/qemu-iotests/177.out |  5 -
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index a5196e8..1ad8d65 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -642,6 +642,16 @@ static int coroutine_fn 
blkdebug_co_pdiscard(BlockDriverState *bs,
 return bdrv_co_pdiscard(bs->file->bs, offset, count);
 }

+static int64_t coroutine_fn blkdebug_co_get_block_status(
+BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
+BlockDriverState **file)
+{
+*pnum = nb_sectors;
+*file = bs->file->bs;
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
+(sector_num << BDRV_SECTOR_BITS);
+}
+
 static void blkdebug_close(BlockDriverState *bs)
 {
 BDRVBlkdebugState *s = bs->opaque;
@@ -912,6 +922,7 @@ static BlockDriver bdrv_blkdebug = {
 .bdrv_co_flush_to_disk  = blkdebug_co_flush,
 .bdrv_co_pwrite_zeroes  = blkdebug_co_pwrite_zeroes,
 .bdrv_co_pdiscard   = blkdebug_co_pdiscard,
+.bdrv_co_get_block_status = blkdebug_co_get_block_status,

 .bdrv_debug_event   = blkdebug_debug_event,
 .bdrv_debug_breakpoint  = blkdebug_debug_breakpoint,
diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
index fcfbfa3..43a7778 100644
--- a/tests/qemu-iotests/177.out
+++ b/tests/qemu-iotests/177.out
@@ -46,6 +46,9 @@ read 30408704/30408704 bytes at offset 80740352
 read 23068672/23068672 bytes at offset 49056
 22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Offset  Length  File
-0   0x800   json:{"image": {"driver": "IMGFMT", "file": 
{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}, "driver": "blkdebug", 
"align": "4k"}
+0   0x80TEST_DIR/t.IMGFMT
+0x900x240   TEST_DIR/t.IMGFMT
+0x3c0   0x110   TEST_DIR/t.IMGFMT
+0x6a0   0x160   TEST_DIR/t.IMGFMT
 No errors were found on the image.
 *** done
-- 
2.9.4




[Qemu-block] [PATCH v3 2/4] block: Guarantee that *file is set on bdrv_get_block_status()

2017-06-05 Thread Eric Blake
We document that *file is valid if the return is not an error and
includes BDRV_BLOCK_OFFSET_VALID, but forgot to obey this contract
when a driver (such as blkdebug) lacks a callback.  Messed up in
commit 67a0fd2 (v2.6), when we added the file parameter.

Enhance qemu-iotest 177 to cover this, using a sequence that would
print garbage or even SEGV, because it was dererefencing through
uninitialized memory.  [The resulting test output shows that we
have less-than-ideal block status from the blkdebug driver, but
that's a separate fix coming up soon.]

Setting *file on all paths that return BDRV_BLOCK_OFFSET_VALID is
enough to fix the crash, but we can go one step further: always
setting *file, even on error, means that a broken caller that
blindly dereferences file without checking for error is now more
likely to get a reliable SEGV instead of randomly acting on garbage,
making it easier to diagnose such buggy callers.  Adding an
assertion that file is set where expected doesn't hurt either.

CC: qemu-sta...@nongnu.org
Signed-off-by: Eric Blake 
Reviewed-by: Fam Zheng 
Reviewed-by: Max Reitz 

---
v3: tweak commit message [Max], rebase test to pass
v2: drop redundant assignment
---
 block/io.c | 5 +++--
 tests/qemu-iotests/177 | 3 +++
 tests/qemu-iotests/177.out | 2 ++
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/block/io.c b/block/io.c
index ed31810..ce6cb0c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1736,6 +1736,7 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 int64_t n;
 int64_t ret, ret2;

+*file = NULL;
 total_sectors = bdrv_nb_sectors(bs);
 if (total_sectors < 0) {
 return total_sectors;
@@ -1756,11 +1757,11 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
 if (bs->drv->protocol_name) {
 ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
+*file = bs;
 }
 return ret;
 }

-*file = NULL;
 bdrv_inc_in_flight(bs);
 ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,
 file);
@@ -1770,7 +1771,7 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 }

 if (ret & BDRV_BLOCK_RAW) {
-assert(ret & BDRV_BLOCK_OFFSET_VALID);
+assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);
 ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
*pnum, pnum, file);
 goto out;
diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
index 2005c17..f8ed8fb 100755
--- a/tests/qemu-iotests/177
+++ b/tests/qemu-iotests/177
@@ -43,6 +43,7 @@ _supported_proto file
 CLUSTER_SIZE=1M
 size=128M
 options=driver=blkdebug,image.driver=qcow2
+nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG

 echo
 echo "== setting up files =="
@@ -106,6 +107,8 @@ function verify_io()
 }

 verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \
+| _filter_qemu_img_map

 _check_test_img

diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
index e887542..fcfbfa3 100644
--- a/tests/qemu-iotests/177.out
+++ b/tests/qemu-iotests/177.out
@@ -45,5 +45,7 @@ read 30408704/30408704 bytes at offset 80740352
 29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 23068672/23068672 bytes at offset 49056
 22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Offset  Length  File
+0   0x800   json:{"image": {"driver": "IMGFMT", "file": 
{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}, "driver": "blkdebug", 
"align": "4k"}
 No errors were found on the image.
 *** done
-- 
2.9.4




[Qemu-block] [PATCH v3 3/4] block: Simplify use of BDRV_BLOCK_RAW

2017-06-05 Thread Eric Blake
The lone caller that cares about a return of BDRV_BLOCK_RAW
(namely, io.c:bdrv_co_get_block_status) completely replaces the
return value, so there is no point in passing BDRV_BLOCK_DATA.

Signed-off-by: Eric Blake 

---
v3: further document BDRV_BLOCK_RAW
v2: fix subject, tweak commit message
---
 include/block/block.h | 6 +++---
 block/commit.c| 2 +-
 block/mirror.c| 2 +-
 block/raw-format.c| 2 +-
 block/vpc.c   | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/block/block.h b/include/block/block.h
index 9b355e9..0a60444 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -131,9 +131,9 @@ typedef struct HDGeometry {
  *   layer (short for DATA || ZERO), set by block layer
  *
  * Internal flag:
- * BDRV_BLOCK_RAW: used internally to indicate that the request was
- * answered by a passthrough driver such as raw and that the
- * block layer should recompute the answer from bs->file.
+ * BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
+ * that the block layer recompute the answer from the returned
+ * BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
  *
  * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK)
  * represent the offset in the returned BDS that is allocated for the
diff --git a/block/commit.c b/block/commit.c
index a3028b2..f56745b 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -239,7 +239,7 @@ static int64_t coroutine_fn 
bdrv_commit_top_get_block_status(
 {
 *pnum = nb_sectors;
 *file = bs->backing->bs;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

diff --git a/block/mirror.c b/block/mirror.c
index a2a9703..892d53a 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1052,7 +1052,7 @@ static int64_t coroutine_fn 
bdrv_mirror_top_get_block_status(
 {
 *pnum = nb_sectors;
 *file = bs->backing->bs;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

diff --git a/block/raw-format.c b/block/raw-format.c
index 36e6503..1136eba 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -259,7 +259,7 @@ static int64_t coroutine_fn 
raw_co_get_block_status(BlockDriverState *bs,
 *pnum = nb_sectors;
 *file = bs->file->bs;
 sector_num += s->offset / BDRV_SECTOR_SIZE;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

diff --git a/block/vpc.c b/block/vpc.c
index 4240ba9..b313c68 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -701,7 +701,7 @@ static int64_t coroutine_fn 
vpc_co_get_block_status(BlockDriverState *bs,
 if (be32_to_cpu(footer->type) == VHD_FIXED) {
 *pnum = nb_sectors;
 *file = bs->file->bs;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

-- 
2.9.4




Re: [Qemu-block] [Qemu-devel] [PATCH v3 0/4] more blkdebug tweaks

2017-06-05 Thread no-reply
Hi,

This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Message-id: 20170605190824.25184-1-ebl...@redhat.com
Subject: [Qemu-devel] [PATCH v3 0/4] more blkdebug tweaks
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=8
time make docker-test-quick@centos6
time make docker-test-mingw@fedora
time make docker-test-build@min-glib
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20170605190824.25184-1-ebl...@redhat.com -> 
patchew/20170605190824.25184-1-ebl...@redhat.com
Switched to a new branch 'test'
a760ce2 blkdebug: Support .bdrv_co_get_block_status
adfab47 block: Simplify use of BDRV_BLOCK_RAW
7b4fbb6 block: Guarantee that *file is set on bdrv_get_block_status()
b71a302 qemu-io: Don't die on second open

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-ie13aiac/src/dtc'...
Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-ie13aiac/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache tar git make gcc g++ zlib-devel 
glib2-devel SDL-devel pixman-devel epel-release
HOSTNAME=cd560983e1cf
TERM=xterm
MAKEFLAGS= -j8
HISTSIZE=1000
J=8
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu 
--prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix/var/tmp/qemu-build/install
BIOS directory/var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path   /tmp/qemu-test/src
C compilercc
Host C compiler   cc
C++ compiler  
Objective-C compiler cc
ARFLAGS   rv
CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS   -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -pthread 
-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -fPIE -DPIE -m64 -mcx16 
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes 
-Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes 
-fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels 
-Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security 
-Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration 
-Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS   -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make  make
install   install
pythonpython -B
smbd  /usr/sbin/smbd
module supportno
host CPU  x86_64
host big endian   no
target list   x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled no
sparse enabledno
strip binariesyes
profiler  no
static build  no
pixmansystem
SDL support   yes (1.2.14)
GTK support   no 
GTK GL supportno
VTE support   no 
TLS priority  NORMAL
GNUTLS supportno
GNUTLS rndno
libgcrypt no
libgcrypt kdf no
nettleno 
nettle kdfno
libtasn1  no
curses supportno
virgl support no
curl support  no
mingw32 support   no
Audio drivers oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS supportno
VNC support   yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support   no
brlapi supportno

Re: [Qemu-block] [Qemu-devel] [PATCH v3 0/4] more blkdebug tweaks

2017-06-05 Thread Eric Blake
On 06/05/2017 02:31 PM, no-re...@patchew.org wrote:
> Hi,
> 
> This series failed automatic build test. Please find the testing commands and
> their output below. If you have docker installed, you can probably reproduce 
> it
> locally.
> 

>   GTESTER tests/test-blockjob
>   GTESTER tests/test-blockjob-txn
>   GTESTER tests/test-x86-cpuid
>   GTESTER tests/test-xbzrle
>   GTESTER tests/test-vmstate
> Failed to load simple/primitive:b_1
> Failed to load simple/primitive:i64_2
> Failed to load simple/primitive:i32_1
> Failed to load simple/primitive:i32_1
> Failed to load test/with_tmp:a
> Failed to load test/tmp_child_parent:f
> Failed to load test/tmp_child:parent
> Failed to load test/with_tmp:tmp
> Failed to load test/tmp_child:diff
> Failed to load test/with_tmp:tmp
> Failed to load test/tmp_child:diff
> Failed to load test/with_tmp:tmp
>   GTESTER tests/test-cutils

Where is this noise coming from?


>   GTESTER tests/test-qmp-commands
>   GTESTER tests/test-string-input-visitor
>   GTESTER tests/test-string-output-visitor
>   GTESTER tests/test-qmp-event
>   GTESTER tests/test-opts-visitor
>   GTESTER tests/test-visitor-serialization
>   GTESTER tests/test-qht-par
> **
> ERROR:/tmp/qemu-test/src/tests/test-qga.c:894:test_qga_guest_exec: assertion 
> failed: (exited)
> socket_accept failed: Resource temporarily unavailable

Looks like a false negative, or a problem with the tester?  I don't see
how my patch could affect test-qga.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-block] [Qemu-devel] [PATCH v2 00/20] make bdrv_is_allocated[_above] byte-based

2017-06-05 Thread Eric Blake
ping

On 05/10/2017 09:20 PM, Eric Blake wrote:
> There are patches floating around to add NBD_CMD_BLOCK_STATUS,
> but NBD wants to report status on byte granularity (even if the
> reporting will probably be naturally aligned to sectors or even
> much higher levels).  I've therefore started the task of
> converting our block status code to report at a byte granularity
> rather than sectors.
> 
> This is part one of that conversion: bdrv_is_allocated().
> Other parts still need a v2, but here's the link to their v1:
> tracking dirty bitmaps by bytes:
> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg02163.html
> replacing bdrv_get_block_status() with a byte based callback
> in all the drivers:
> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg02642.html
> 
> Available as a tag at:
> git fetch git://repo.or.cz/qemu/ericb.git nbd-byte-allocated-v2
> 
> Since v1:
> - Add R-b from John as appropriate
> - Couple of new patches for cleanups he noticed
> - Rebase to Max's block branch
> 
> 001/20:[] [--] 'blockjob: Track job ratelimits via bytes, not sectors'
> 002/20:[] [--] 'trace: Show blockjob actions via bytes, not sectors'
> 003/20:[] [--] 'stream: Switch stream_populate() to byte-based'
> 004/20:[] [--] 'stream: Switch stream_run() to byte-based'
> 005/20:[] [--] 'commit: Switch commit_populate() to byte-based'
> 006/20:[] [--] 'commit: Switch commit_run() to byte-based'
> 007/20:[] [--] 'mirror: Switch MirrorBlockJob to byte-based'
> 008/20:[] [--] 'mirror: Switch mirror_do_zero_or_discard() to byte-based'
> 009/20:[down] 'mirror: Update signature of mirror_clip_sectors()'
> 010/20:[0013] [FC] 'mirror: Switch mirror_cow_align() to byte-based'
> 011/20:[] [-C] 'mirror: Switch mirror_do_read() to byte-based'
> 012/20:[0014] [FC] 'mirror: Switch mirror_iteration() to byte-based'
> 013/20:[] [--] 'block: Drop unused bdrv_round_sectors_to_clusters()'
> 014/20:[] [--] 'backup: Switch BackupBlockJob to byte-based'
> 015/20:[0008] [FC] 'backup: Switch block_backup.h to byte-based'
> 016/20:[] [--] 'backup: Switch backup_do_cow() to byte-based'
> 017/20:[] [--] 'backup: Switch backup_run() to byte-based'
> 018/20:[0039] [FC] 'block: Make bdrv_is_allocated() byte-based'
> 019/20:[down] 'block: Minimize raw use of bds->total_sectors'
> 020/20:[0026] [FC] 'block: Make bdrv_is_allocated_above() byte-based'
> 
> Eric Blake (20):
>   blockjob: Track job ratelimits via bytes, not sectors
>   trace: Show blockjob actions via bytes, not sectors
>   stream: Switch stream_populate() to byte-based
>   stream: Switch stream_run() to byte-based
>   commit: Switch commit_populate() to byte-based
>   commit: Switch commit_run() to byte-based
>   mirror: Switch MirrorBlockJob to byte-based
>   mirror: Switch mirror_do_zero_or_discard() to byte-based
>   mirror: Update signature of mirror_clip_sectors()
>   mirror: Switch mirror_cow_align() to byte-based
>   mirror: Switch mirror_do_read() to byte-based
>   mirror: Switch mirror_iteration() to byte-based
>   block: Drop unused bdrv_round_sectors_to_clusters()
>   backup: Switch BackupBlockJob to byte-based
>   backup: Switch block_backup.h to byte-based
>   backup: Switch backup_do_cow() to byte-based
>   backup: Switch backup_run() to byte-based
>   block: Make bdrv_is_allocated() byte-based
>   block: Minimize raw use of bds->total_sectors
>   block: Make bdrv_is_allocated_above() byte-based
> 
>  include/block/block.h|  10 +-
>  include/block/block_backup.h |  11 +-
>  include/qemu/ratelimit.h |   3 +-
>  block/backup.c   | 130 ---
>  block/commit.c   |  54 
>  block/io.c   |  92 +++--
>  block/mirror.c   | 300 
> ++-
>  block/replication.c  |  29 +++--
>  block/stream.c   |  35 +++--
>  block/vvfat.c|  34 +++--
>  migration/block.c|   9 +-
>  qemu-img.c   |  15 ++-
>  qemu-io-cmds.c   |  70 +-
>  block/trace-events   |  14 +-
>  14 files changed, 396 insertions(+), 410 deletions(-)
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-block] [Qemu-devel] [PATCH v2 00/20] make bdrv_is_allocated[_above] byte-based

2017-06-05 Thread John Snow


On 06/05/2017 03:39 PM, Eric Blake wrote:
> ping
> 

ACK.

> On 05/10/2017 09:20 PM, Eric Blake wrote:
>> There are patches floating around to add NBD_CMD_BLOCK_STATUS,
>> but NBD wants to report status on byte granularity (even if the
>> reporting will probably be naturally aligned to sectors or even
>> much higher levels).  I've therefore started the task of
>> converting our block status code to report at a byte granularity
>> rather than sectors.
>>
>> This is part one of that conversion: bdrv_is_allocated().
>> Other parts still need a v2, but here's the link to their v1:
>> tracking dirty bitmaps by bytes:
>> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg02163.html
>> replacing bdrv_get_block_status() with a byte based callback
>> in all the drivers:
>> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg02642.html
>>
>> Available as a tag at:
>> git fetch git://repo.or.cz/qemu/ericb.git nbd-byte-allocated-v2
>>
>> Since v1:
>> - Add R-b from John as appropriate
>> - Couple of new patches for cleanups he noticed
>> - Rebase to Max's block branch
>>
>> 001/20:[] [--] 'blockjob: Track job ratelimits via bytes, not sectors'
>> 002/20:[] [--] 'trace: Show blockjob actions via bytes, not sectors'
>> 003/20:[] [--] 'stream: Switch stream_populate() to byte-based'
>> 004/20:[] [--] 'stream: Switch stream_run() to byte-based'
>> 005/20:[] [--] 'commit: Switch commit_populate() to byte-based'
>> 006/20:[] [--] 'commit: Switch commit_run() to byte-based'
>> 007/20:[] [--] 'mirror: Switch MirrorBlockJob to byte-based'
>> 008/20:[] [--] 'mirror: Switch mirror_do_zero_or_discard() to byte-based'
>> 009/20:[down] 'mirror: Update signature of mirror_clip_sectors()'
>> 010/20:[0013] [FC] 'mirror: Switch mirror_cow_align() to byte-based'
>> 011/20:[] [-C] 'mirror: Switch mirror_do_read() to byte-based'
>> 012/20:[0014] [FC] 'mirror: Switch mirror_iteration() to byte-based'
>> 013/20:[] [--] 'block: Drop unused bdrv_round_sectors_to_clusters()'
>> 014/20:[] [--] 'backup: Switch BackupBlockJob to byte-based'
>> 015/20:[0008] [FC] 'backup: Switch block_backup.h to byte-based'
>> 016/20:[] [--] 'backup: Switch backup_do_cow() to byte-based'
>> 017/20:[] [--] 'backup: Switch backup_run() to byte-based'
>> 018/20:[0039] [FC] 'block: Make bdrv_is_allocated() byte-based'
>> 019/20:[down] 'block: Minimize raw use of bds->total_sectors'
>> 020/20:[0026] [FC] 'block: Make bdrv_is_allocated_above() byte-based'
>>
>> Eric Blake (20):
>>   blockjob: Track job ratelimits via bytes, not sectors
>>   trace: Show blockjob actions via bytes, not sectors
>>   stream: Switch stream_populate() to byte-based
>>   stream: Switch stream_run() to byte-based
>>   commit: Switch commit_populate() to byte-based
>>   commit: Switch commit_run() to byte-based
>>   mirror: Switch MirrorBlockJob to byte-based
>>   mirror: Switch mirror_do_zero_or_discard() to byte-based
>>   mirror: Update signature of mirror_clip_sectors()
>>   mirror: Switch mirror_cow_align() to byte-based
>>   mirror: Switch mirror_do_read() to byte-based
>>   mirror: Switch mirror_iteration() to byte-based
>>   block: Drop unused bdrv_round_sectors_to_clusters()
>>   backup: Switch BackupBlockJob to byte-based
>>   backup: Switch block_backup.h to byte-based
>>   backup: Switch backup_do_cow() to byte-based
>>   backup: Switch backup_run() to byte-based
>>   block: Make bdrv_is_allocated() byte-based
>>   block: Minimize raw use of bds->total_sectors
>>   block: Make bdrv_is_allocated_above() byte-based
>>
>>  include/block/block.h|  10 +-
>>  include/block/block_backup.h |  11 +-
>>  include/qemu/ratelimit.h |   3 +-
>>  block/backup.c   | 130 ---
>>  block/commit.c   |  54 
>>  block/io.c   |  92 +++--
>>  block/mirror.c   | 300 
>> ++-
>>  block/replication.c  |  29 +++--
>>  block/stream.c   |  35 +++--
>>  block/vvfat.c|  34 +++--
>>  migration/block.c|   9 +-
>>  qemu-img.c   |  15 ++-
>>  qemu-io-cmds.c   |  70 +-
>>  block/trace-events   |  14 +-
>>  14 files changed, 396 insertions(+), 410 deletions(-)
>>
> 



Re: [Qemu-block] [Qemu-devel] [PATCH v3 1/4] qemu-io: Don't die on second open

2017-06-05 Thread Eric Blake
On 06/05/2017 02:08 PM, Eric Blake wrote:

> 
> Note, however, that we do have some qemu-iotests that do 'qemu-io
> -c "open file" -c "$something"'; such tests will now proceed to
> attempt $something whether or not the open succeeded, the same way
> as if the two commands had been attempted in interactive mode; but it
> also means that it is now possible to use -c close and have a single
> qemu-io command line operate on more than one file even without
> using interactive mode.  Although the '-c open' action is a subtle
> change in behavior, remember that qemu-io is for debugging purposes,
> so as long as it serves the needs of qemu-iotests while still being
> reasonable for interactive use, it should not be a problem.

Bummer - iotest 60 catches me:

+++ 060.out.bad 2017-06-05 14:55:48.336814834 -0500
@@ -21,6 +21,7 @@
 refcount bits: 16
 corrupt: true
 can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot
be opened read/write
+no file open, try 'help open'
 read 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)

Looks like 114 and 153 as well.  I'll have to post a v4 (serves me right
for JUST testing 177).

Also, I'm seeing a segfault on 68 that exists on current master:

068 1s ... - output mismatch (see 068.out.bad)
--- /home/eblake/qemu/tests/qemu-iotests/068.out2017-06-01
17:01:25.113094957 -0500
+++ 068.out.bad 2017-06-05 14:55:54.140835402 -0500
@@ -6,6 +6,8 @@
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm 0
 (qemu) quit
+./common.config: line 107: 1 Segmentation fault  (core dumped)
( if [ -n "${QEMU_NEED_PID}" ]; then
+echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
+fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
 QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) quit
-*** done
+(qemu) *** done


-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-block] [Qemu-devel] [PATCH] block/gluster.c: Handle qdict_array_entries() failure

2017-06-05 Thread Philippe Mathieu-Daudé

On 06/05/2017 02:01 PM, Peter Maydell wrote:

In qemu_gluster_parse_json(), the call to qdict_array_entries()
could return a negative error code, which we were ignoring
because we assigned the result to an unsigned variable.
Fix this by using the 'int' type instead, which matches the
return type of qdict_array_entries() and also the type
we use for the loop enumeration variable 'i'.

(Spotted by Coverity, CID 1360960.)

Signed-off-by: Peter Maydell 


Reviewed-by: Philippe Mathieu-Daudé 


---
 block/gluster.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 031596a..addceed 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -493,8 +493,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 Error *local_err = NULL;
 char *str = NULL;
 const char *ptr;
-size_t num_servers;
-int i, type;
+int i, type, num_servers;

 /* create opts info from runtime_json_opts list */
 opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);





Re: [Qemu-block] [PATCH] block/gluster.c: Handle qdict_array_entries() failure

2017-06-05 Thread Jeff Cody
On Mon, Jun 05, 2017 at 06:01:38PM +0100, Peter Maydell wrote:
> In qemu_gluster_parse_json(), the call to qdict_array_entries()
> could return a negative error code, which we were ignoring
> because we assigned the result to an unsigned variable.
> Fix this by using the 'int' type instead, which matches the
> return type of qdict_array_entries() and also the type
> we use for the loop enumeration variable 'i'.
> 
> (Spotted by Coverity, CID 1360960.)
> 
> Signed-off-by: Peter Maydell 
> ---
>  block/gluster.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/block/gluster.c b/block/gluster.c
> index 031596a..addceed 100644
> --- a/block/gluster.c
> +++ b/block/gluster.c
> @@ -493,8 +493,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
> *gconf,
>  Error *local_err = NULL;
>  char *str = NULL;
>  const char *ptr;
> -size_t num_servers;
> -int i, type;
> +int i, type, num_servers;
>  
>  /* create opts info from runtime_json_opts list */
>  opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);
> -- 
> 2.7.4
> 

Thanks,

Reviewed-by: Jeff Cody 

Also - applied to my block branch:

git://github.com/codyprime/qemu-kvm-jtc block

-Jeff



[Qemu-block] [PATCH v4 0/4] more blkdebug tweaks

2017-06-05 Thread Eric Blake
I found a crasher and some odd behavior while rebasing my
bdrv_get_block_status series, so I figured I'd get these things
fixed first.  This is based on top of Max's block branch.

Available as a tag at:
git fetch git://repo.or.cz/qemu/ericb.git nbd-blkdebug-status-v4

Since v3:
- check all qemu-iotests (patch 1)

001/4:[0012] [FC] 'qemu-io: Don't die on second open'
002/4:[] [--] 'block: Guarantee that *file is set on 
bdrv_get_block_status()'
003/4:[] [--] 'block: Simplify use of BDRV_BLOCK_RAW'
004/4:[] [--] 'blkdebug: Support .bdrv_co_get_block_status'

Eric Blake (4):
  qemu-io: Don't die on second open
  block: Guarantee that *file is set on bdrv_get_block_status()
  block: Simplify use of BDRV_BLOCK_RAW
  blkdebug: Support .bdrv_co_get_block_status

 include/block/block.h  |  6 +++---
 block/blkdebug.c   | 11 +++
 block/commit.c |  2 +-
 block/io.c |  5 +++--
 block/mirror.c |  2 +-
 block/raw-format.c |  2 +-
 block/vpc.c|  2 +-
 qemu-io.c  |  7 ---
 tests/qemu-iotests/060.out |  1 +
 tests/qemu-iotests/114.out |  5 +++--
 tests/qemu-iotests/153.out |  6 ++
 tests/qemu-iotests/177 |  3 +++
 tests/qemu-iotests/177.out |  5 +
 13 files changed, 43 insertions(+), 14 deletions(-)

-- 
2.9.4




[Qemu-block] [PATCH v4 1/4] qemu-io: Don't die on second open

2017-06-05 Thread Eric Blake
Most callback commands in qemu-io return 0 to keep the interpreter
loop running, or 1 to quit immediately.  However, open_f() just
passed through the return value of openfile(), which has different
semantics of returning 0 if a file was opened, or 1 on any failure.

As a result of mixing the return semantics, we are forcing the
qemu-io interpreter to exit early on any failures, which is rather
annoying when some of the failures are obviously trying to give
the user a hint of how to proceed (if we didn't then kill qemu-io
out from under the user's feet):

$ qemu-io
qemu-io> open foo
qemu-io> open foo
file open already, try 'help close'
$ echo $?
0

In general, we WANT openfile() to report failures, since it is the
function used in the form 'qemu-io -c "$something" no_such_file'
for performing one or more -c options on a single file, and it is
not worth attempting $something if the file itself cannot be opened.
So the solution is to fix open_f() to always return 0 (when we are
in interactive mode, even failure to open should not end the
session), and save the return value of openfile() for command line
use in main().

Note, however, that we do have some qemu-iotests that do 'qemu-io
-c "open file" -c "$something"'; such tests will now proceed to
attempt $something whether or not the open succeeded, the same way
as if the two commands had been attempted in interactive mode.  As
such, the expected output for those tests has to be modified.  But it
also means that it is now possible to use -c close and have a single
qemu-io command line operate on more than one file even without
using interactive mode.  Although the '-c open' action is a subtle
change in behavior, remember that qemu-io is for debugging purposes,
so as long as it serves the needs of qemu-iotests while still being
reasonable for interactive use, it should not be a problem that we
are changing tests to the new behavior.

This has been awkward since at least as far back as commit
e3aff4f, in 2009.

Signed-off-by: Eric Blake 
Reviewed-by: Fam Zheng 

---
v4: cover ALL qemu-iotests
v3: tweak commit message to distinguish that '-c open' has a subtle
new behavior from the command line
v2: fix open_f(), not openfile()
---
 qemu-io.c  | 7 ---
 tests/qemu-iotests/060.out | 1 +
 tests/qemu-iotests/114.out | 5 +++--
 tests/qemu-iotests/153.out | 6 ++
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index 8e38b28..8074656 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -230,13 +230,14 @@ static int open_f(BlockBackend *blk, int argc, char 
**argv)
 qemu_opts_reset(&empty_opts);

 if (optind == argc - 1) {
-return openfile(argv[optind], flags, writethrough, force_share, opts);
+openfile(argv[optind], flags, writethrough, force_share, opts);
 } else if (optind == argc) {
-return openfile(NULL, flags, writethrough, force_share, opts);
+openfile(NULL, flags, writethrough, force_share, opts);
 } else {
 QDECREF(opts);
-return qemuio_command_usage(&open_cmd);
+qemuio_command_usage(&open_cmd);
 }
+return 0;
 }

 static int quit_f(BlockBackend *blk, int argc, char **argv)
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index 3bc1461..5ca3af4 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -21,6 +21,7 @@ Format specific information:
 refcount bits: 16
 corrupt: true
 can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be 
opened read/write
+no file open, try 'help open'
 read 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)

diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
index b6d10e4..1a47a52 100644
--- a/tests/qemu-iotests/114.out
+++ b/tests/qemu-iotests/114.out
@@ -1,6 +1,6 @@
 QA output created by 114
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
backing_file=TEST_DIR/t.IMGFMT.base 
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
backing_file=TEST_DIR/t.IMGFMT.base
 image: TEST_DIR/t.IMGFMT
 file format: IMGFMT
 virtual size: 64M (67108864 bytes)
@@ -8,6 +8,7 @@ cluster_size: 65536
 backing file: TEST_DIR/t.IMGFMT.base
 backing file format: foo
 can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown 
driver 'foo'
+no file open, try 'help open'
 read 4096/4096 bytes at offset 0
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
index 5ba0b63..5b917b1 100644
--- a/tests/qemu-iotests/153.out
+++ b/tests/qemu-iotests/153.out
@@ -33,10 +33,12 @@ Is another process using the image?
 _qemu_io_wrapper -c open  TEST_DIR/t.qcow2 -c read 0 512
 can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
 Is another process using the image?
+no file open, tr

[Qemu-block] [PATCH v4 3/4] block: Simplify use of BDRV_BLOCK_RAW

2017-06-05 Thread Eric Blake
The lone caller that cares about a return of BDRV_BLOCK_RAW
(namely, io.c:bdrv_co_get_block_status) completely replaces the
return value, so there is no point in passing BDRV_BLOCK_DATA.

Signed-off-by: Eric Blake 

---
v3: further document BDRV_BLOCK_RAW
v2: fix subject, tweak commit message
---
 include/block/block.h | 6 +++---
 block/commit.c| 2 +-
 block/mirror.c| 2 +-
 block/raw-format.c| 2 +-
 block/vpc.c   | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/block/block.h b/include/block/block.h
index 9b355e9..0a60444 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -131,9 +131,9 @@ typedef struct HDGeometry {
  *   layer (short for DATA || ZERO), set by block layer
  *
  * Internal flag:
- * BDRV_BLOCK_RAW: used internally to indicate that the request was
- * answered by a passthrough driver such as raw and that the
- * block layer should recompute the answer from bs->file.
+ * BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
+ * that the block layer recompute the answer from the returned
+ * BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
  *
  * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK)
  * represent the offset in the returned BDS that is allocated for the
diff --git a/block/commit.c b/block/commit.c
index a3028b2..f56745b 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -239,7 +239,7 @@ static int64_t coroutine_fn 
bdrv_commit_top_get_block_status(
 {
 *pnum = nb_sectors;
 *file = bs->backing->bs;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

diff --git a/block/mirror.c b/block/mirror.c
index a2a9703..892d53a 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1052,7 +1052,7 @@ static int64_t coroutine_fn 
bdrv_mirror_top_get_block_status(
 {
 *pnum = nb_sectors;
 *file = bs->backing->bs;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

diff --git a/block/raw-format.c b/block/raw-format.c
index 36e6503..1136eba 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -259,7 +259,7 @@ static int64_t coroutine_fn 
raw_co_get_block_status(BlockDriverState *bs,
 *pnum = nb_sectors;
 *file = bs->file->bs;
 sector_num += s->offset / BDRV_SECTOR_SIZE;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

diff --git a/block/vpc.c b/block/vpc.c
index 4240ba9..b313c68 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -701,7 +701,7 @@ static int64_t coroutine_fn 
vpc_co_get_block_status(BlockDriverState *bs,
 if (be32_to_cpu(footer->type) == VHD_FIXED) {
 *pnum = nb_sectors;
 *file = bs->file->bs;
-return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
(sector_num << BDRV_SECTOR_BITS);
 }

-- 
2.9.4




[Qemu-block] [PATCH v4 2/4] block: Guarantee that *file is set on bdrv_get_block_status()

2017-06-05 Thread Eric Blake
We document that *file is valid if the return is not an error and
includes BDRV_BLOCK_OFFSET_VALID, but forgot to obey this contract
when a driver (such as blkdebug) lacks a callback.  Messed up in
commit 67a0fd2 (v2.6), when we added the file parameter.

Enhance qemu-iotest 177 to cover this, using a sequence that would
print garbage or even SEGV, because it was dererefencing through
uninitialized memory.  [The resulting test output shows that we
have less-than-ideal block status from the blkdebug driver, but
that's a separate fix coming up soon.]

Setting *file on all paths that return BDRV_BLOCK_OFFSET_VALID is
enough to fix the crash, but we can go one step further: always
setting *file, even on error, means that a broken caller that
blindly dereferences file without checking for error is now more
likely to get a reliable SEGV instead of randomly acting on garbage,
making it easier to diagnose such buggy callers.  Adding an
assertion that file is set where expected doesn't hurt either.

CC: qemu-sta...@nongnu.org
Signed-off-by: Eric Blake 
Reviewed-by: Fam Zheng 
Reviewed-by: Max Reitz 

---
v3: tweak commit message [Max], rebase test to pass
v2: drop redundant assignment
---
 block/io.c | 5 +++--
 tests/qemu-iotests/177 | 3 +++
 tests/qemu-iotests/177.out | 2 ++
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/block/io.c b/block/io.c
index ed31810..ce6cb0c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1736,6 +1736,7 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 int64_t n;
 int64_t ret, ret2;

+*file = NULL;
 total_sectors = bdrv_nb_sectors(bs);
 if (total_sectors < 0) {
 return total_sectors;
@@ -1756,11 +1757,11 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
 if (bs->drv->protocol_name) {
 ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
+*file = bs;
 }
 return ret;
 }

-*file = NULL;
 bdrv_inc_in_flight(bs);
 ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,
 file);
@@ -1770,7 +1771,7 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 }

 if (ret & BDRV_BLOCK_RAW) {
-assert(ret & BDRV_BLOCK_OFFSET_VALID);
+assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);
 ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
*pnum, pnum, file);
 goto out;
diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
index 2005c17..f8ed8fb 100755
--- a/tests/qemu-iotests/177
+++ b/tests/qemu-iotests/177
@@ -43,6 +43,7 @@ _supported_proto file
 CLUSTER_SIZE=1M
 size=128M
 options=driver=blkdebug,image.driver=qcow2
+nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG

 echo
 echo "== setting up files =="
@@ -106,6 +107,8 @@ function verify_io()
 }

 verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \
+| _filter_qemu_img_map

 _check_test_img

diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
index e887542..fcfbfa3 100644
--- a/tests/qemu-iotests/177.out
+++ b/tests/qemu-iotests/177.out
@@ -45,5 +45,7 @@ read 30408704/30408704 bytes at offset 80740352
 29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 23068672/23068672 bytes at offset 49056
 22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Offset  Length  File
+0   0x800   json:{"image": {"driver": "IMGFMT", "file": 
{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}, "driver": "blkdebug", 
"align": "4k"}
 No errors were found on the image.
 *** done
-- 
2.9.4




[Qemu-block] [PATCH v4 4/4] blkdebug: Support .bdrv_co_get_block_status

2017-06-05 Thread Eric Blake
Without a passthrough status of BDRV_BLOCK_RAW, anything wrapped by
blkdebug appears 100% allocated as data.  Better is treating it the
same as the underlying file being wrapped.

Update iotest 177 for the new expected output.

Signed-off-by: Eric Blake 
Reviewed-by: Fam Zheng 
Reviewed-by: Max Reitz 

---
v3: rebase to earlier changes
v2: tweak commit message
---
 block/blkdebug.c   | 11 +++
 tests/qemu-iotests/177.out |  5 -
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index a5196e8..1ad8d65 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -642,6 +642,16 @@ static int coroutine_fn 
blkdebug_co_pdiscard(BlockDriverState *bs,
 return bdrv_co_pdiscard(bs->file->bs, offset, count);
 }

+static int64_t coroutine_fn blkdebug_co_get_block_status(
+BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
+BlockDriverState **file)
+{
+*pnum = nb_sectors;
+*file = bs->file->bs;
+return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
+(sector_num << BDRV_SECTOR_BITS);
+}
+
 static void blkdebug_close(BlockDriverState *bs)
 {
 BDRVBlkdebugState *s = bs->opaque;
@@ -912,6 +922,7 @@ static BlockDriver bdrv_blkdebug = {
 .bdrv_co_flush_to_disk  = blkdebug_co_flush,
 .bdrv_co_pwrite_zeroes  = blkdebug_co_pwrite_zeroes,
 .bdrv_co_pdiscard   = blkdebug_co_pdiscard,
+.bdrv_co_get_block_status = blkdebug_co_get_block_status,

 .bdrv_debug_event   = blkdebug_debug_event,
 .bdrv_debug_breakpoint  = blkdebug_debug_breakpoint,
diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
index fcfbfa3..43a7778 100644
--- a/tests/qemu-iotests/177.out
+++ b/tests/qemu-iotests/177.out
@@ -46,6 +46,9 @@ read 30408704/30408704 bytes at offset 80740352
 read 23068672/23068672 bytes at offset 49056
 22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Offset  Length  File
-0   0x800   json:{"image": {"driver": "IMGFMT", "file": 
{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}, "driver": "blkdebug", 
"align": "4k"}
+0   0x80TEST_DIR/t.IMGFMT
+0x900x240   TEST_DIR/t.IMGFMT
+0x3c0   0x110   TEST_DIR/t.IMGFMT
+0x6a0   0x160   TEST_DIR/t.IMGFMT
 No errors were found on the image.
 *** done
-- 
2.9.4




Re: [Qemu-block] [Qemu-devel] [PATCH v2 09/20] mirror: Update signature of mirror_clip_sectors()

2017-06-05 Thread John Snow


On 05/10/2017 10:20 PM, Eric Blake wrote:
> Rather than having a void function that modifies its input
> in-place as the output, change the signature to reduce a layer
> of indirection and return the result.
> 
> Suggested-by: John Snow 
> Signed-off-by: Eric Blake 
> 

Reviewed-by: John Snow 

> ---
> v2: new patch
> ---
>  block/mirror.c | 15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 



Re: [Qemu-block] [Qemu-devel] [PATCH v2 10/20] mirror: Switch mirror_cow_align() to byte-based

2017-06-05 Thread John Snow


On 05/10/2017 10:20 PM, Eric Blake wrote:
> We are gradually converting to byte-based interfaces, as they are
> easier to reason about than sector-based.  Convert another internal
> function (no semantic change), and add mirror_clip_bytes() as a
> counterpart to mirror_clip_sectors().  Some of the conversion is
> a bit tricky, requiring temporaries to convert between units; it
> will be cleared up in a following patch.
> 
> Signed-off-by: Eric Blake 

Reviewed-by: John Snow 

> 
> ---
> v2: tweak mirror_clip_bytes() signature to match previous patch
> ---



Re: [Qemu-block] [Qemu-devel] [PATCH v2 15/20] backup: Switch block_backup.h to byte-based

2017-06-05 Thread John Snow


On 05/10/2017 10:20 PM, Eric Blake wrote:
> We are gradually converting to byte-based interfaces, as they are
> easier to reason about than sector-based.  Continue by converting
> the public interface to backup jobs (no semantic change), including
> a change to CowRequest to track by bytes instead of cluster indices.
> 
> Note that this does not change the difference between the public
> interface (starting point, and size of the subsequent range) and
> the internal interface (starting and end points).
> 
> Signed-off-by: Eric Blake 
> 

Reviewed-by: John Snow 

> ---
> v2: change a couple more parameter names
> ---
>  include/block/block_backup.h | 11 +--
>  block/backup.c   | 33 -
>  block/replication.c  | 12 
>  3 files changed, 29 insertions(+), 27 deletions(-)
> 



Re: [Qemu-block] [Qemu-devel] [PATCH v2 18/20] block: Make bdrv_is_allocated() byte-based

2017-06-05 Thread John Snow


On 05/10/2017 10:20 PM, Eric Blake wrote:
> We are gradually moving away from sector-based interfaces, towards
> byte-based.  In the common case, allocation is unlikely to ever use
> values that are not naturally sector-aligned, but it is possible
> that byte-based values will let us be more precise about allocation
> at the end of an unaligned file that can do byte-based access.
> 
> Changing the signature of the function to use int64_t *pnum ensures
> that the compiler enforces that all callers are updated.  For now,
> the io.c layer still assert()s that all callers are sector-aligned
> on input and that *pnum is sector-aligned on return to the caller,
> but that can be relaxed when a later patch implements byte-based
> block status.  Therefore, this code adds usages like
> DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
> values, where the call might reasonbly give non-aligned results
> in the future; on the other hand, no rounding is needed for callers
> that should just continue to work with byte alignment.
> 
> For the most part this patch is just the addition of scaling at the
> callers followed by inverse scaling at bdrv_is_allocated().  But
> some code, particularly bdrv_commit(), gets a lot simpler because it
> no longer has to mess with sectors; also, it is now possible to pass
> NULL if the caller does not care how much of the image is allocated
> beyond the initial offset.
> 
> For ease of review, bdrv_is_allocated_above() will be tackled
> separately.
> 
> Signed-off-by: Eric Blake 
> 

Reviewed-by: John Snow 

> ---
> v2: rebase to earlier changes, tweak commit message
> ---
>  include/block/block.h |  4 +--
>  block/backup.c| 17 -
>  block/commit.c| 21 +++-
>  block/io.c| 49 +---
>  block/stream.c|  5 ++--
>  block/vvfat.c | 34 ++---
>  migration/block.c |  9 ---
>  qemu-img.c|  5 +++-
>  qemu-io-cmds.c| 70 
> +++
>  9 files changed, 114 insertions(+), 100 deletions(-)
> 



Re: [Qemu-block] [Qemu-devel] [PATCH v2 20/20] block: Make bdrv_is_allocated_above() byte-based

2017-06-05 Thread John Snow


On 05/10/2017 10:20 PM, Eric Blake wrote:
> -int64_t sector_num, int nb_sectors, int *pnum);
> +int64_t offset, int64_t bytes, int64_t *pnum);

Minor context conflict after this that, for whichever reason, git could
not resolve on its own for me.



Re: [Qemu-block] [Qemu-devel] [PATCH v2 20/20] block: Make bdrv_is_allocated_above() byte-based

2017-06-05 Thread John Snow


On 05/10/2017 10:20 PM, Eric Blake wrote:
> We are gradually moving away from sector-based interfaces, towards
> byte-based.  In the common case, allocation is unlikely to ever use
> values that are not naturally sector-aligned, but it is possible
> that byte-based values will let us be more precise about allocation
> at the end of an unaligned file that can do byte-based access.
> 
> Changing the signature of the function to use int64_t *pnum ensures
> that the compiler enforces that all callers are updated.  For now,
> the io.c layer still assert()s that all callers are sector-aligned,
> but that can be relaxed when a later patch implements byte-based
> block status.  Therefore, for the most part this patch is just the
> addition of scaling at the callers followed by inverse scaling at
> bdrv_is_allocated().  But some code, particularly stream_run(),
> gets a lot simpler because it no longer has to mess with sectors.
> 
> For ease of review, bdrv_is_allocated() was tackled separately.
> 
> Signed-off-by: Eric Blake 
>

Reviewed-by: John Snow 



Re: [Qemu-block] [Qemu-devel] [PATCH v4 2/4] block: Guarantee that *file is set on bdrv_get_block_status()

2017-06-05 Thread John Snow


On 06/05/2017 04:38 PM, Eric Blake wrote:
> We document that *file is valid if the return is not an error and
> includes BDRV_BLOCK_OFFSET_VALID, but forgot to obey this contract
> when a driver (such as blkdebug) lacks a callback.  Messed up in
> commit 67a0fd2 (v2.6), when we added the file parameter.
> 
> Enhance qemu-iotest 177 to cover this, using a sequence that would
> print garbage or even SEGV, because it was dererefencing through
> uninitialized memory.  [The resulting test output shows that we
> have less-than-ideal block status from the blkdebug driver, but
> that's a separate fix coming up soon.]
> 
> Setting *file on all paths that return BDRV_BLOCK_OFFSET_VALID is
> enough to fix the crash, but we can go one step further: always
> setting *file, even on error, means that a broken caller that
> blindly dereferences file without checking for error is now more
> likely to get a reliable SEGV instead of randomly acting on garbage,
> making it easier to diagnose such buggy callers.  Adding an
> assertion that file is set where expected doesn't hurt either.
> 
> CC: qemu-sta...@nongnu.org
> Signed-off-by: Eric Blake 
> Reviewed-by: Fam Zheng 
> Reviewed-by: Max Reitz 

Reviewed-by: John Snow 



Re: [Qemu-block] [Qemu-devel] [PATCH v4 1/4] qemu-io: Don't die on second open

2017-06-05 Thread John Snow


On 06/05/2017 04:38 PM, Eric Blake wrote:
> Most callback commands in qemu-io return 0 to keep the interpreter
> loop running, or 1 to quit immediately.  However, open_f() just
> passed through the return value of openfile(), which has different
> semantics of returning 0 if a file was opened, or 1 on any failure.
> 
> As a result of mixing the return semantics, we are forcing the
> qemu-io interpreter to exit early on any failures, which is rather
> annoying when some of the failures are obviously trying to give
> the user a hint of how to proceed (if we didn't then kill qemu-io
> out from under the user's feet):
> 
> $ qemu-io
> qemu-io> open foo
> qemu-io> open foo
> file open already, try 'help close'
> $ echo $?
> 0
> 
> In general, we WANT openfile() to report failures, since it is the
> function used in the form 'qemu-io -c "$something" no_such_file'
> for performing one or more -c options on a single file, and it is
> not worth attempting $something if the file itself cannot be opened.
> So the solution is to fix open_f() to always return 0 (when we are
> in interactive mode, even failure to open should not end the
> session), and save the return value of openfile() for command line
> use in main().
> 
> Note, however, that we do have some qemu-iotests that do 'qemu-io
> -c "open file" -c "$something"'; such tests will now proceed to
> attempt $something whether or not the open succeeded, the same way
> as if the two commands had been attempted in interactive mode.  As
> such, the expected output for those tests has to be modified.  But it
> also means that it is now possible to use -c close and have a single
> qemu-io command line operate on more than one file even without
> using interactive mode.  Although the '-c open' action is a subtle
> change in behavior, remember that qemu-io is for debugging purposes,
> so as long as it serves the needs of qemu-iotests while still being
> reasonable for interactive use, it should not be a problem that we
> are changing tests to the new behavior.
> 
> This has been awkward since at least as far back as commit
> e3aff4f, in 2009.
> 
> Signed-off-by: Eric Blake 
> Reviewed-by: Fam Zheng 


Reviewed-by: John Snow 




Re: [Qemu-block] [Qemu-devel] [PATCH v4 3/4] block: Simplify use of BDRV_BLOCK_RAW

2017-06-05 Thread Fam Zheng
On Mon, 06/05 15:38, Eric Blake wrote:
> The lone caller that cares about a return of BDRV_BLOCK_RAW
> (namely, io.c:bdrv_co_get_block_status) completely replaces the
> return value, so there is no point in passing BDRV_BLOCK_DATA.
> 
> Signed-off-by: Eric Blake 
> 
> ---
> v3: further document BDRV_BLOCK_RAW
> v2: fix subject, tweak commit message
> ---
>  include/block/block.h | 6 +++---
>  block/commit.c| 2 +-
>  block/mirror.c| 2 +-
>  block/raw-format.c| 2 +-
>  block/vpc.c   | 2 +-
>  5 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/include/block/block.h b/include/block/block.h
> index 9b355e9..0a60444 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -131,9 +131,9 @@ typedef struct HDGeometry {
>   *   layer (short for DATA || ZERO), set by block layer
>   *
>   * Internal flag:
> - * BDRV_BLOCK_RAW: used internally to indicate that the request was
> - * answered by a passthrough driver such as raw and that the
> - * block layer should recompute the answer from bs->file.
> + * BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
> + * that the block layer recompute the answer from the 
> returned
> + * BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
>   *
>   * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK)
>   * represent the offset in the returned BDS that is allocated for the
> diff --git a/block/commit.c b/block/commit.c
> index a3028b2..f56745b 100644
> --- a/block/commit.c
> +++ b/block/commit.c
> @@ -239,7 +239,7 @@ static int64_t coroutine_fn 
> bdrv_commit_top_get_block_status(
>  {
>  *pnum = nb_sectors;
>  *file = bs->backing->bs;
> -return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
> +return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
> (sector_num << BDRV_SECTOR_BITS);
>  }
> 
> diff --git a/block/mirror.c b/block/mirror.c
> index a2a9703..892d53a 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -1052,7 +1052,7 @@ static int64_t coroutine_fn 
> bdrv_mirror_top_get_block_status(
>  {
>  *pnum = nb_sectors;
>  *file = bs->backing->bs;
> -return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
> +return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
> (sector_num << BDRV_SECTOR_BITS);
>  }
> 
> diff --git a/block/raw-format.c b/block/raw-format.c
> index 36e6503..1136eba 100644
> --- a/block/raw-format.c
> +++ b/block/raw-format.c
> @@ -259,7 +259,7 @@ static int64_t coroutine_fn 
> raw_co_get_block_status(BlockDriverState *bs,
>  *pnum = nb_sectors;
>  *file = bs->file->bs;
>  sector_num += s->offset / BDRV_SECTOR_SIZE;
> -return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
> +return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
> (sector_num << BDRV_SECTOR_BITS);
>  }
> 
> diff --git a/block/vpc.c b/block/vpc.c
> index 4240ba9..b313c68 100644
> --- a/block/vpc.c
> +++ b/block/vpc.c
> @@ -701,7 +701,7 @@ static int64_t coroutine_fn 
> vpc_co_get_block_status(BlockDriverState *bs,
>  if (be32_to_cpu(footer->type) == VHD_FIXED) {
>  *pnum = nb_sectors;
>  *file = bs->file->bs;
> -return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
> +return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
> (sector_num << BDRV_SECTOR_BITS);
>  }
> 
> -- 
> 2.9.4
> 
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-block] [Qemu-devel] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread QingFeng Hao



在 2017/6/5 19:08, Dr. David Alan Gilbert 写道:

* QingFeng Hao (ha...@linux.vnet.ibm.com) wrote:

In load_vmstate, mis->from_src_file is freed twice, the first free is by
qemu_fclose, the second is by migration_incoming_state_destroy and
it causes Illegal instruction exception. The fix is just to remove the
first free.

This problem is found by qemu-iotests case 068 since commit
"660819b migration: shut src return path unconditionally". The error is:
068 1s ... - output mismatch (see 068.out.bad)
 --- tests/qemu-iotests/068.out 2017-05-06 01:00:26.417270437 +0200
 +++ 068.out.bad2017-06-03 13:59:55.360274640 +0200
 @@ -6,6 +6,8 @@
  QEMU X.Y.Z monitor - type 'help' for more information
  (qemu) savevm 0
  (qemu) quit
 +./common.config: line 107: 242472 Illegal instruction (core dumped) ( if [ -n 
"${QEMU_NEED_PID}" ]; then
 +echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
 +fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
  QEMU X.Y.Z monitor - type 'help' for more information
 -(qemu) quit
 -*** done
 +(qemu) *** done

Signed-off-by: QingFeng Hao 
---
  migration/savevm.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f59d0..853e14e34e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
  
  aio_context_acquire(aio_context);

  ret = qemu_loadvm_state(f);
-qemu_fclose(f);
  aio_context_release(aio_context);

Thanks!

Reviewed-by: Dr. David Alan Gilbert 

Thanks David!


  
  migration_incoming_state_destroy();

--
2.11.2



--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



--
Regards
QingFeng Hao




Re: [Qemu-block] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread Peter Xu
On Mon, Jun 05, 2017 at 12:48:51PM +0200, QingFeng Hao wrote:
> In load_vmstate, mis->from_src_file is freed twice, the first free is by
> qemu_fclose, the second is by migration_incoming_state_destroy and
> it causes Illegal instruction exception. The fix is just to remove the
> first free.
> 
> This problem is found by qemu-iotests case 068 since commit
> "660819b migration: shut src return path unconditionally". The error is:
> 068 1s ... - output mismatch (see 068.out.bad)
> --- tests/qemu-iotests/068.out2017-05-06 01:00:26.417270437 +0200
> +++ 068.out.bad   2017-06-03 13:59:55.360274640 +0200
> @@ -6,6 +6,8 @@
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) savevm 0
>  (qemu) quit
> +./common.config: line 107: 242472 Illegal instruction (core dumped) 
> ( if [ -n "${QEMU_NEED_PID}" ]; then
> +echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
> +fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
>  QEMU X.Y.Z monitor - type 'help' for more information
> -(qemu) quit
> -*** done
> +(qemu) *** done
> 
> Signed-off-by: QingFeng Hao 
> ---
>  migration/savevm.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/migration/savevm.c b/migration/savevm.c
> index 9c320f59d0..853e14e34e 100644
> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
>  
>  aio_context_acquire(aio_context);
>  ret = qemu_loadvm_state(f);
> -qemu_fclose(f);
>  aio_context_release(aio_context);
>  
>  migration_incoming_state_destroy();

Thanks QingFeng for the fix!

Reviewed-by: Peter Xu 

Though here instead of removing the fclose(), not sure whether this is
nicer:

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f5..1feb519 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2233,7 +2233,6 @@ int load_snapshot(const char *name, Error **errp)
 QEMUFile *f;
 int ret;
 AioContext *aio_context;
-MigrationIncomingState *mis = migration_incoming_get_current();
 
 if (!bdrv_all_can_snapshot(&bs)) {
 error_setg(errp,
@@ -2286,7 +2285,6 @@ int load_snapshot(const char *name, Error **errp)
 }
 
 qemu_system_reset(SHUTDOWN_CAUSE_NONE);
-mis->from_src_file = f;
 
 aio_context_acquire(aio_context);
 ret = qemu_loadvm_state(f);

Since I see we setup from_src_file but we don't really use it. If we
remove that line, we can also remove the
migration_incoming_get_current() call altogether.

Either way work for me. So my r-b stands always. :-)

-- 
Peter Xu



Re: [Qemu-block] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread QingFeng Hao



在 2017/6/6 11:03, Peter Xu 写道:

On Mon, Jun 05, 2017 at 12:48:51PM +0200, QingFeng Hao wrote:

In load_vmstate, mis->from_src_file is freed twice, the first free is by
qemu_fclose, the second is by migration_incoming_state_destroy and
it causes Illegal instruction exception. The fix is just to remove the
first free.

This problem is found by qemu-iotests case 068 since commit
"660819b migration: shut src return path unconditionally". The error is:
068 1s ... - output mismatch (see 068.out.bad)
 --- tests/qemu-iotests/068.out 2017-05-06 01:00:26.417270437 +0200
 +++ 068.out.bad2017-06-03 13:59:55.360274640 +0200
 @@ -6,6 +6,8 @@
  QEMU X.Y.Z monitor - type 'help' for more information
  (qemu) savevm 0
  (qemu) quit
 +./common.config: line 107: 242472 Illegal instruction (core dumped) ( if [ -n 
"${QEMU_NEED_PID}" ]; then
 +echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
 +fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
  QEMU X.Y.Z monitor - type 'help' for more information
 -(qemu) quit
 -*** done
 +(qemu) *** done

Signed-off-by: QingFeng Hao 
---
  migration/savevm.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f59d0..853e14e34e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
  
  aio_context_acquire(aio_context);

  ret = qemu_loadvm_state(f);
-qemu_fclose(f);
  aio_context_release(aio_context);
  
  migration_incoming_state_destroy();

Thanks QingFeng for the fix!

Reviewed-by: Peter Xu 

Though here instead of removing the fclose(), not sure whether this is
nicer:

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f5..1feb519 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2233,7 +2233,6 @@ int load_snapshot(const char *name, Error **errp)
  QEMUFile *f;
  int ret;
  AioContext *aio_context;
-MigrationIncomingState *mis = migration_incoming_get_current();

  if (!bdrv_all_can_snapshot(&bs)) {
  error_setg(errp,
@@ -2286,7 +2285,6 @@ int load_snapshot(const char *name, Error **errp)
  }

  qemu_system_reset(SHUTDOWN_CAUSE_NONE);
-mis->from_src_file = f;

  aio_context_acquire(aio_context);
  ret = qemu_loadvm_state(f);
Thanks Peter. I have a doubt on this change because I see there are 
several places
referencing from_src_file e.g. loadvm_postcopy_ram_handle_discard, and 
it seems to

get byte from the file and it's called by qemu_loadvm_state.
Anyway, you remind me for the description that is "In load_snapshot" 
rather than

"In load_vmstate". thanks

Since I see we setup from_src_file but we don't really use it. If we
remove that line, we can also remove the
migration_incoming_get_current() call altogether.

Either way work for me. So my r-b stands always. :-)



--
Regards
QingFeng Hao




Re: [Qemu-block] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread Peter Xu
On Tue, Jun 06, 2017 at 11:38:05AM +0800, QingFeng Hao wrote:
> 
> 
> 在 2017/6/6 11:03, Peter Xu 写道:
> >On Mon, Jun 05, 2017 at 12:48:51PM +0200, QingFeng Hao wrote:
> >>In load_vmstate, mis->from_src_file is freed twice, the first free is by
> >>qemu_fclose, the second is by migration_incoming_state_destroy and
> >>it causes Illegal instruction exception. The fix is just to remove the
> >>first free.
> >>
> >>This problem is found by qemu-iotests case 068 since commit
> >>"660819b migration: shut src return path unconditionally". The error is:
> >>068 1s ... - output mismatch (see 068.out.bad)
> >> --- tests/qemu-iotests/068.out 2017-05-06 01:00:26.417270437 +0200
> >> +++ 068.out.bad2017-06-03 13:59:55.360274640 +0200
> >> @@ -6,6 +6,8 @@
> >>  QEMU X.Y.Z monitor - type 'help' for more information
> >>  (qemu) savevm 0
> >>  (qemu) quit
> >> +./common.config: line 107: 242472 Illegal instruction (core 
> >> dumped) ( if [ -n "${QEMU_NEED_PID}" ]; then
> >> +echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
> >> +fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
> >>  QEMU X.Y.Z monitor - type 'help' for more information
> >> -(qemu) quit
> >> -*** done
> >> +(qemu) *** done
> >>
> >>Signed-off-by: QingFeng Hao 
> >>---
> >>  migration/savevm.c | 1 -
> >>  1 file changed, 1 deletion(-)
> >>
> >>diff --git a/migration/savevm.c b/migration/savevm.c
> >>index 9c320f59d0..853e14e34e 100644
> >>--- a/migration/savevm.c
> >>+++ b/migration/savevm.c
> >>@@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
> >>  aio_context_acquire(aio_context);
> >>  ret = qemu_loadvm_state(f);
> >>-qemu_fclose(f);
> >>  aio_context_release(aio_context);
> >>  migration_incoming_state_destroy();
> >Thanks QingFeng for the fix!
> >
> >Reviewed-by: Peter Xu 
> >
> >Though here instead of removing the fclose(), not sure whether this is
> >nicer:
> >
> >diff --git a/migration/savevm.c b/migration/savevm.c
> >index 9c320f5..1feb519 100644
> >--- a/migration/savevm.c
> >+++ b/migration/savevm.c
> >@@ -2233,7 +2233,6 @@ int load_snapshot(const char *name, Error **errp)
> >  QEMUFile *f;
> >  int ret;
> >  AioContext *aio_context;
> >-MigrationIncomingState *mis = migration_incoming_get_current();
> >
> >  if (!bdrv_all_can_snapshot(&bs)) {
> >  error_setg(errp,
> >@@ -2286,7 +2285,6 @@ int load_snapshot(const char *name, Error **errp)
> >  }
> >
> >  qemu_system_reset(SHUTDOWN_CAUSE_NONE);
> >-mis->from_src_file = f;
> >
> >  aio_context_acquire(aio_context);
> >  ret = qemu_loadvm_state(f);
> Thanks Peter. I have a doubt on this change because I see there are several
> places
> referencing from_src_file e.g. loadvm_postcopy_ram_handle_discard, and it
> seems to
> get byte from the file and it's called by qemu_loadvm_state.
> Anyway, you remind me for the description that is "In load_snapshot" rather
> than
> "In load_vmstate". thanks

Oh I didn't really notice that. :)

It shouldn't affect imho since load snapshot won't trigger postcopy
codes. But sure current fix is good enough for me at least.

Thanks,

-- 
Peter Xu



Re: [Qemu-block] [Qemu-devel] [PATCH v4 0/4] more blkdebug tweaks

2017-06-05 Thread John Snow


On 06/05/2017 04:38 PM, Eric Blake wrote:
> I found a crasher and some odd behavior while rebasing my
> bdrv_get_block_status series, so I figured I'd get these things
> fixed first.  This is based on top of Max's block branch.
> 
> Available as a tag at:
> git fetch git://repo.or.cz/qemu/ericb.git nbd-blkdebug-status-v4
> 
> Since v3:
> - check all qemu-iotests (patch 1)
> 
> 001/4:[0012] [FC] 'qemu-io: Don't die on second open'
> 002/4:[] [--] 'block: Guarantee that *file is set on 
> bdrv_get_block_status()'
> 003/4:[] [--] 'block: Simplify use of BDRV_BLOCK_RAW'
> 004/4:[] [--] 'blkdebug: Support .bdrv_co_get_block_status'
> 
> Eric Blake (4):
>   qemu-io: Don't die on second open
>   block: Guarantee that *file is set on bdrv_get_block_status()
>   block: Simplify use of BDRV_BLOCK_RAW
>   blkdebug: Support .bdrv_co_get_block_status
> 
>  include/block/block.h  |  6 +++---
>  block/blkdebug.c   | 11 +++
>  block/commit.c |  2 +-
>  block/io.c |  5 +++--
>  block/mirror.c |  2 +-
>  block/raw-format.c |  2 +-
>  block/vpc.c|  2 +-
>  qemu-io.c  |  7 ---
>  tests/qemu-iotests/060.out |  1 +
>  tests/qemu-iotests/114.out |  5 +++--
>  tests/qemu-iotests/153.out |  6 ++
>  tests/qemu-iotests/177 |  3 +++
>  tests/qemu-iotests/177.out |  5 +
>  13 files changed, 43 insertions(+), 14 deletions(-)
> 

3,4:

Reviewed-by: John Snow 



Re: [Qemu-block] [PATCH v1 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread QingFeng Hao



在 2017/6/6 11:50, Peter Xu 写道:

On Tue, Jun 06, 2017 at 11:38:05AM +0800, QingFeng Hao wrote:


在 2017/6/6 11:03, Peter Xu 写道:

On Mon, Jun 05, 2017 at 12:48:51PM +0200, QingFeng Hao wrote:

In load_vmstate, mis->from_src_file is freed twice, the first free is by
qemu_fclose, the second is by migration_incoming_state_destroy and
it causes Illegal instruction exception. The fix is just to remove the
first free.

This problem is found by qemu-iotests case 068 since commit
"660819b migration: shut src return path unconditionally". The error is:
068 1s ... - output mismatch (see 068.out.bad)
 --- tests/qemu-iotests/068.out 2017-05-06 01:00:26.417270437 +0200
 +++ 068.out.bad2017-06-03 13:59:55.360274640 +0200
 @@ -6,6 +6,8 @@
  QEMU X.Y.Z monitor - type 'help' for more information
  (qemu) savevm 0
  (qemu) quit
 +./common.config: line 107: 242472 Illegal instruction (core dumped) ( if [ -n 
"${QEMU_NEED_PID}" ]; then
 +echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
 +fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
  QEMU X.Y.Z monitor - type 'help' for more information
 -(qemu) quit
 -*** done
 +(qemu) *** done

Signed-off-by: QingFeng Hao 
---
  migration/savevm.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f59d0..853e14e34e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
  aio_context_acquire(aio_context);
  ret = qemu_loadvm_state(f);
-qemu_fclose(f);
  aio_context_release(aio_context);
  migration_incoming_state_destroy();

Thanks QingFeng for the fix!

Reviewed-by: Peter Xu 

Though here instead of removing the fclose(), not sure whether this is
nicer:

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f5..1feb519 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2233,7 +2233,6 @@ int load_snapshot(const char *name, Error **errp)
  QEMUFile *f;
  int ret;
  AioContext *aio_context;
-MigrationIncomingState *mis = migration_incoming_get_current();

  if (!bdrv_all_can_snapshot(&bs)) {
  error_setg(errp,
@@ -2286,7 +2285,6 @@ int load_snapshot(const char *name, Error **errp)
  }

  qemu_system_reset(SHUTDOWN_CAUSE_NONE);
-mis->from_src_file = f;

  aio_context_acquire(aio_context);
  ret = qemu_loadvm_state(f);

Thanks Peter. I have a doubt on this change because I see there are several
places
referencing from_src_file e.g. loadvm_postcopy_ram_handle_discard, and it
seems to
get byte from the file and it's called by qemu_loadvm_state.
Anyway, you remind me for the description that is "In load_snapshot" rather
than
"In load_vmstate". thanks

Oh I didn't really notice that. :)

It shouldn't affect imho since load snapshot won't trigger postcopy
codes. But sure current fix is good enough for me at least.

Ok, thanks!

Thanks,



--
Regards
QingFeng Hao




[Qemu-block] [PATCH v2 0/1] qemu/migration: fix the migration bug found by qemu-iotests case 068

2017-06-05 Thread QingFeng Hao
Hi all,
This patch is to fix the migration bug found by qemu-iotests case 068
and based on upstream master's commit:
199e19ee53: Merge remote-tracking branch 
'remotes/mjt/tags/trivial-patches-fetch' into staging.
The bug was introduced by commit "660819b migration: shut src return path 
unconditionally".

Change Log(v2):
Got reviewed-by from Dr. David Alan Gilbert and Peter Xu.

Thanks!

QingFeng Hao (1):
  qemu/migration: fix the double free problem on from_src_file

 migration/savevm.c | 1 -
 1 file changed, 1 deletion(-)

-- 
2.11.2




[Qemu-block] [PATCH v2 1/1] qemu/migration: fix the double free problem on from_src_file

2017-06-05 Thread QingFeng Hao
In load_snapshot, mis->from_src_file is freed twice, the first free is by
qemu_fclose, the second is by migration_incoming_state_destroy and
it causes Illegal instruction exception. The fix is just to remove the
first free.

This problem is found by qemu-iotests case 068 since commit
"660819b migration: shut src return path unconditionally". The error is:
068 1s ... - output mismatch (see 068.out.bad)
--- tests/qemu-iotests/068.out  2017-05-06 01:00:26.417270437 +0200
+++ 068.out.bad 2017-06-03 13:59:55.360274640 +0200
@@ -6,6 +6,8 @@
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm 0
 (qemu) quit
+./common.config: line 107: 242472 Illegal instruction (core dumped) ( 
if [ -n "${QEMU_NEED_PID}" ]; then
+echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid";
+fi; exec "$QEMU_PROG" $QEMU_OPTIONS "$@" )
 QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) quit
-*** done
+(qemu) *** done

Signed-off-by: QingFeng Hao 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Peter Xu 
---
 migration/savevm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 9c320f59d0..853e14e34e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2290,7 +2290,6 @@ int load_snapshot(const char *name, Error **errp)
 
 aio_context_acquire(aio_context);
 ret = qemu_loadvm_state(f);
-qemu_fclose(f);
 aio_context_release(aio_context);
 
 migration_incoming_state_destroy();
-- 
2.11.2