Re: [Qemu-block] [PATCH v1 07/15] iotests: fix 097 when run with qcow

2017-01-17 Thread Daniel P. Berrange
On Mon, Jan 16, 2017 at 09:04:31PM +0100, Max Reitz wrote:
> On 03.01.2017 19:27, Daniel P. Berrange wrote:
> > The previous commit:
> > 
> >   commit a3e1505daec31ef56f0489f8c8fff1b8e4ca92bd
> >   Author: Eric Blake 
> >   Date:   Mon Dec 5 09:49:34 2016 -0600
> > 
> > qcow2: Don't strand clusters near 2G intervals during commit
> > 
> > extended the 097 test case so that it did two passes, once
> > with an internal snapshot, once without.
> > 
> > qcow (v1) does not support internal snapshots, so this change
> > broke test 097 when run against qcow.
> > 
> > This splits 097 in two, creating a new 173 that tests the
> > internal snapshot codepath, effectively putting 097 back
> > to its content before the above commit.
> > 
> > Signed-off-by: Daniel P. Berrange 
> > ---
> >  tests/qemu-iotests/097 |  10 +---
> >  tests/qemu-iotests/097.out | 125 
> > ++--
> >  tests/qemu-iotests/173 | 126 
> > +
> >  tests/qemu-iotests/173.out | 119 ++
> >  tests/qemu-iotests/group   |   1 +
> >  5 files changed, 251 insertions(+), 130 deletions(-)
> >  create mode 100755 tests/qemu-iotests/173
> >  create mode 100644 tests/qemu-iotests/173.out
> 
> I don't think the effort is worth it, considering that probably
> literally nobody is still using qcow -- or so I hope, at least.

The reason I fixed this was because I wanted to be able to verify my
refactoring to qcow didn't break anything else. It is much easier if
I can just run "check -qcow" and not have to worry about which failures
are just test bugs, vs genuine code bugs I've created. IOW, as long as
qcow.c exists in the code base, IMHO, we should make sure the iotests
continue to pass

On that point, IMHO, it would be beneficial if we had some CI system
that was setup to run the iotests on all new changes, across all the
different disk formats we expect the iotests to work on. We get far
too many regressions with iotests breaking and no one noticing right
now :-(


Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://entangle-photo.org   -o-http://search.cpan.org/~danberr/ :|



Re: [Qemu-block] [PATCH RFC v2 2/6] replication: add shared-disk and shared-disk-id options

2017-01-17 Thread Stefan Hajnoczi
On Mon, Dec 05, 2016 at 04:35:00PM +0800, zhanghailiang wrote:
> @@ -85,6 +99,9 @@ static int replication_open(BlockDriverState *bs, QDict 
> *options,
>  QemuOpts *opts = NULL;
>  const char *mode;
>  const char *top_id;
> +const char *shared_disk_id;
> +BlockBackend *blk;
> +BlockDriverState *tmp_bs;
>  
>  ret = -EINVAL;
>  opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, 
> &error_abort);
> @@ -119,6 +136,25 @@ static int replication_open(BlockDriverState *bs, QDict 
> *options,
> "The option mode's value should be primary or secondary");
>  goto fail;
>  }
> +s->is_shared_disk = qemu_opt_get_bool(opts, REPLICATION_SHARED_DISK,
> +  false);
> +if (s->is_shared_disk && (s->mode == REPLICATION_MODE_PRIMARY)) {
> +shared_disk_id = qemu_opt_get(opts, REPLICATION_SHARED_DISK_ID);
> +if (!shared_disk_id) {
> +error_setg(&local_err, "Missing shared disk blk");
> +goto fail;
> +}
> +s->shared_disk_id = g_strdup(shared_disk_id);
> +blk = blk_by_name(s->shared_disk_id);
> +if (!blk) {
> +g_free(s->shared_disk_id);
> +error_setg(&local_err, "There is no %s block", 
> s->shared_disk_id);
> +goto fail;

Please move the g_free() to the fail label to prevent future code
changes from introducing a memory leak.


signature.asc
Description: PGP signature


Re: [Qemu-block] [Qemu-stable] [PATCH] block/iscsi: avoid data corruption with cache=writeback

2017-01-17 Thread Fam Zheng
On Mon, 01/16 16:17, Peter Lieven wrote:
> nb_cls_shrunk in iscsi_allocmap_update can become -1 if the
> request starts and ends within the same cluster. This results
> in passing -1 to bitmap_set and bitmap_clear and they don't
> handle negative values properly. In the end this leads to data
> corruption.
> 
> Fixes: e1123a3b40a1a9a625a29c8ed4debb7e206ea690
> Cc: qemu-sta...@nongnu.org
> Signed-off-by: Peter Lieven 
> ---
>  block/iscsi.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/block/iscsi.c b/block/iscsi.c
> index 6aeeb9e..1860f1b 100644
> --- a/block/iscsi.c
> +++ b/block/iscsi.c
> @@ -499,14 +499,18 @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t 
> sector_num,
>  if (allocated) {
>  bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
>  } else {
> -bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
> +if (nb_cls_shrunk > 0) {
> +bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
> +}
>  }
>  
>  if (iscsilun->allocmap_valid == NULL) {
>  return;
>  }
>  if (valid) {
> -bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
> +if (nb_cls_shrunk > 0) {
> +bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, 
> nb_cls_shrunk);
> +}
>  } else {
>  bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded,
>   nb_cls_expanded);
> -- 
> 1.9.1
> 
> 

It's probably a good idea to add assertions parameter in bitmap_*.

Reviewed-by: Fam Zheng 



Re: [Qemu-block] [Qemu-stable] [PATCH] block/iscsi: avoid data corruption with cache=writeback

2017-01-17 Thread Peter Lieven

Am 17.01.2017 um 12:28 schrieb Fam Zheng:

On Mon, 01/16 16:17, Peter Lieven wrote:

nb_cls_shrunk in iscsi_allocmap_update can become -1 if the
request starts and ends within the same cluster. This results
in passing -1 to bitmap_set and bitmap_clear and they don't
handle negative values properly. In the end this leads to data
corruption.

Fixes: e1123a3b40a1a9a625a29c8ed4debb7e206ea690
Cc: qemu-sta...@nongnu.org
Signed-off-by: Peter Lieven 
---
  block/iscsi.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 6aeeb9e..1860f1b 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -499,14 +499,18 @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t 
sector_num,
  if (allocated) {
  bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
  } else {
-bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
+if (nb_cls_shrunk > 0) {
+bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
+}
  }
  
  if (iscsilun->allocmap_valid == NULL) {

  return;
  }
  if (valid) {
-bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
+if (nb_cls_shrunk > 0) {
+bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
+}
  } else {
  bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded,
   nb_cls_expanded);
--
1.9.1



It's probably a good idea to add assertions parameter in bitmap_*.


yes, i will send a follow-up patch.

Peter




Re: [Qemu-block] [PATCH RFC v2 3/6] replication: Split out backup_do_checkpoint() from secondary_do_checkpoint()

2017-01-17 Thread Stefan Hajnoczi
On Mon, Dec 05, 2016 at 04:35:01PM +0800, zhanghailiang wrote:
> The helper backup_do_checkpoint() will be used for primary related
> codes. Here we split it out from secondary_do_checkpoint().
> 
> Besides, it is unnecessary to call backup_do_checkpoint() in
> replication starting and normally stop replication path.
> We only need call it while do real checkpointing.
> 
> Signed-off-by: zhanghailiang 
> ---
>  block/replication.c | 36 +++-
>  1 file changed, 19 insertions(+), 17 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [Qemu-block] [PATCH RFC v2 4/6] replication: fix code logic with the new shared_disk option

2017-01-17 Thread Stefan Hajnoczi
On Mon, Dec 05, 2016 at 04:35:02PM +0800, zhanghailiang wrote:
> Some code logic only be needed in non-shared disk, here
> we adjust these codes to prepare for shared disk scenario.
> 
> Signed-off-by: zhanghailiang 
> ---
>  block/replication.c | 47 ---
>  1 file changed, 28 insertions(+), 19 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [Qemu-block] [PATCH RFC v2 5/6] replication: Implement block replication for shared disk case

2017-01-17 Thread Stefan Hajnoczi
On Mon, Dec 05, 2016 at 04:35:03PM +0800, zhanghailiang wrote:
> @@ -663,8 +695,12 @@ static void replication_stop(ReplicationState *rs, bool 
> failover, Error **errp)
>  
>  switch (s->mode) {
>  case REPLICATION_MODE_PRIMARY:
> -s->replication_state = BLOCK_REPLICATION_DONE;
> -s->error = 0;
> +if (s->is_shared_disk && s->primary_disk->bs->job) {
> +block_job_cancel(s->primary_disk->bs->job);

Should this be block_job_cancel_sync()?

> +} else {
> +s->replication_state = BLOCK_REPLICATION_DONE;
> +s->error = 0;
> +}
>  break;
>  case REPLICATION_MODE_SECONDARY:
>  /*
> -- 
> 1.8.3.1
> 
> 


signature.asc
Description: PGP signature


Re: [Qemu-block] [Qemu-devel] [PATCH 3/3] block: get max_transfer limit for char (scsi-generic) devices

2017-01-17 Thread Eric Farman



On 01/17/2017 02:04 AM, Fam Zheng wrote:

On Mon, 01/16 22:12, Eric Farman wrote:

Commit 6f607174 introduced a routine to get the maximum number
of bytes for a single I/O transfer for block devices, however
scsi generic devices are character devices, not block.  Add
a condition for this, with slightly different logic because
the value is already in bytes, and need not be converted from
blocks as happens for block devices.

Signed-off-by: Eric Farman 
---
 block/file-posix.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index 2115155..c0843c2 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -679,6 +679,13 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 if (ret > 0 && ret <= BDRV_REQUEST_MAX_SECTORS) {
 bs->bl.max_transfer = pow2floor(ret << BDRV_SECTOR_BITS);
 }
+} else if (S_ISCHR(st.st_mode)) {
+/* sg returns transfer length in bytes already */
+int ret = hdev_get_max_transfer_length(bs, s->fd);
+if (ret > 0 &&
+(ret >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS) {
+bs->bl.max_transfer = pow2floor(ret);
+}


Please keep the sectors/bytes quirk in hdev_get_max_transfer_length and always
return bytes from there.


That's easy enough.  I'll allow a day or two before sending a v2, in 
case there's other considerations for the rats nest I've wandered into.


Thanks!

 - Eric




Re: [Qemu-block] [PATCH v6 0/2] allow blockdev-add for NFS

2017-01-17 Thread Peter Lieven

Am 31.10.2016 um 18:20 schrieb Kevin Wolf:

Am 31.10.2016 um 16:05 hat Ashijeet Acharya geschrieben:

Previously posted series patches:
v5: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg07580.html
v4: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg07449.html
v3: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg06903.html
v2: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg05844.html
v1: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04487.html

This series adds blockdev-add support for NFS block driver.

Thanks, fixed as commented on patch 1 and applied.


Hi,

it seems this series breaks passing options via URI.

1) in nfs_parse_uri

parse_uint_full(qp->p[i].value, NULL, 0)

segfaults, as the routine wants to set *NULL = val.

Program received signal SIGSEGV, Segmentation fault.
parse_uint (s=0x55d0ead0 "131072", value=value@entry=0x0, 
endptr=endptr@entry=0x7fffd870, base=base@entry=0) at util/cutils.c:475
475*value = val;
(gdb) bt full
#0  parse_uint (s=0x55d0ead0 "131072", value=value@entry=0x0, 
endptr=endptr@entry=0x7fffd870, base=base@entry=0) at util/cutils.c:475
r = 0
endp = 0x55d0ead6 ""
val = 131072
#1  0x55655ff2 in parse_uint_full (s=, 
value=value@entry=0x0, base=base@entry=0) at util/cutils.c:499
endp = 0x55d093f0 "\004"
r = 
#2  0x55603425 in nfs_parse_uri (filename=, 
options=0x55d093f0, errp=0x7fffd980) at block/nfs.c:116
uri = 0x55d0e920
qp = 0x55d0ea30
ret = -22
i = 0
__func__ = "nfs_parse_uri"
#3  0x5559c7bb in bdrv_fill_options (errp=0x7fffd968, flags=0x7fffd95c, 
filename=, options=) at block.c:1278
drvname = 
protocol = 
local_err = 0x0
parse_filename = true
drv = 0x558e3140 


2) all parameters that have a different names in options and qdict
e.g. readahead-size vs. readahead cannot be passed via URI.

$ qemu-img convert -p 
nfs://172.21.200.61/templates/VC_debian8-20170116.qcow2,linux\?readahead=131072 
iscsi://172.21.200.56:3260/iqn.2001-05.com.equallogic:0-8a0906-69d384e0a-aa3004e55e15878d-XXX/0

qemu-img: Could not open 
'nfs://172.21.200.61/vcore-dev-cdrom/templates/VC_debian8-20170116.qcow2,linux?readahead=131072':
 Block protocol 'nfs' doesn't support the option 'readahead-size'

Please let me know if the below fix would be correct:

lieven@lieven-pc:~/git/qemu$ git diff
diff --git a/block/nfs.c b/block/nfs.c
index a564340..0ff8268 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -108,30 +108,31 @@ static int nfs_parse_uri(const char *filename, QDict 
*options, Error **errp)
 qdict_put(options, "path", qstring_from_str(uri->path));

 for (i = 0; i < qp->n; i++) {
+unsigned long long val;
 if (!qp->p[i].value) {
 error_setg(errp, "Value for NFS parameter expected: %s",
qp->p[i].name);
 goto out;
 }
-if (parse_uint_full(qp->p[i].value, NULL, 0)) {
+if (parse_uint_full(qp->p[i].value, &val, 0)) {
 error_setg(errp, "Illegal value for NFS parameter: %s",
qp->p[i].name);
 goto out;
 }
 if (!strcmp(qp->p[i].name, "uid")) {
-qdict_put(options, "user",
+qdict_put(options, "uid",
   qstring_from_str(qp->p[i].value));
 } else if (!strcmp(qp->p[i].name, "gid")) {
-qdict_put(options, "group",
+qdict_put(options, "gid",
   qstring_from_str(qp->p[i].value));
 } else if (!strcmp(qp->p[i].name, "tcp-syncnt")) {
-qdict_put(options, "tcp-syn-count",
+qdict_put(options, "tcp-syncnt",
   qstring_from_str(qp->p[i].value));
 } else if (!strcmp(qp->p[i].name, "readahead")) {
-qdict_put(options, "readahead-size",
+qdict_put(options, "readahead",
   qstring_from_str(qp->p[i].value));
 } else if (!strcmp(qp->p[i].name, "pagecache")) {
-qdict_put(options, "page-cache-size",
+qdict_put(options, "pagecache",
   qstring_from_str(qp->p[i].value));
 } else if (!strcmp(qp->p[i].name, "debug")) {
 qdict_put(options, "debug",


Thanks,
Peter




Re: [Qemu-block] [Qemu-devel] [PATCH v2] pflash_cfi01: fix per device sector length in CFI table

2017-01-17 Thread David Engraf

Am 16.01.2017 um 11:26 schrieb Dr. David Alan Gilbert:

* Andrew Jones (drjo...@redhat.com) wrote:

On Thu, Jan 12, 2017 at 10:42:41AM +, Peter Maydell wrote:

On 12 January 2017 at 10:35, David Engraf  wrote:

The CFI entry for sector length must be set to sector length per device.
This is important for boards using multiple devices like the ARM Vexpress
board (width = 4, device-width = 2).

Linux and u-boots calculate the size ratio by dividing both values:

size_ratio = info->portwidth / info->chipwidth;

After that the sector length will be multiplied by the size_ratio, thus the
CFI entry for sector length is doubled. When Linux or u-boot send a sector
erase, they expect to erase the doubled sector length, but QEMU only erases
the board specified sector length.

This patch fixes the sector length in the CFI table to match the length per
device, equal to blocks_per_device.


Thanks for the patch. I haven't checked against the pflash spec yet,
but this looks like it's probably the right thing.

The only two machines which use a setup with multiple devices (ie
which specify device_width to the pflash_cfi01) are vexpress and virt.
For all other machines this patch leaves the behaviour unchanged.

Q: do we need to have some kind of nasty hack so that pre-2.9 virt
still gets the old broken values in the CFI table, for version and
migration compatibility? Ccing Drew for an opinion...



I'm pretty sure we need the nasty hack, but I'm also Ccing David for
his opinion.


Hmm I don't understand enough about pflash to understand the change here;
but generally if you need to keep something unchanged for older
machine types, add a property and then set that property in
the compatibility macros.

See include/hw/compat.h, I think you'd add the entry to HW_COMPAT_2_8
and follow a simple example like  old_msi_addr on intel-hda.c,
that should get picked up by aarch, x86, ppc etc versioned machine types.


This is a new version of the previous patch including the HW_COMPAT entry.

After further tests with u-boot and Linux, I found another problem with 
the blocks per device and write block size. Blocks per device must not 
be divided with the number of devices because the resulting device size 
would not match the overall size. However write block size must be 
modified depending on the number of devices because the entry is per 
device and when u-boot writes into the flash it calculates the write 
size by using the CFI entry (write size per device) multiplied by the 
number of chips.


Here is a configuration example of the vexpress board:

VEXPRESS_FLASH_SIZE = 64M
VEXPRESS_FLASH_SECT_SIZE 256K
num-blocks = VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE = 256
sector-length = 256K
width = 4
device-width = 2

The code will fill the CFI entry with the following entries
num-blocks = 256
sector-length = 128K
writeblock_size = 2048

This results in two chips, each with 256 * 128K = 32M device size and a 
write block size of 2048.


A sector erase will be send to both chips, thus 256K must be erased. 
When u-boot sends a block write command, it will write 4096 bytes data 
at once (2048 per device).


I did not modify the CFI entry for write block size. Instead I kept the 
hard coded value of 2048 in the CFI table and fixed the internal entry 
for writeblock_size.


Best regards
- David


Signed-off-by: David Engraf 

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 5f0ee9d..996daa3 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -99,6 +99,7 @@ struct pflash_t {
 char *name;
 void *storage;
 VMChangeStateEntry *vmstate;
+bool old_multiple_chip_handling;
 };
 
 static int pflash_post_load(void *opaque, int version_id);
@@ -703,7 +704,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 pflash_t *pfl = CFI_PFLASH01(dev);
 uint64_t total_len;
 int ret;
-uint64_t blocks_per_device, device_len;
+uint64_t blocks_per_device, sector_len_per_device, device_len;
 int num_devices;
 Error *local_err = NULL;
 
@@ -726,8 +727,14 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
  * in the cfi_table[].
  */
 num_devices = pfl->device_width ? (pfl->bank_width / pfl->device_width) : 1;
-blocks_per_device = pfl->nb_blocs / num_devices;
-device_len = pfl->sector_len * blocks_per_device;
+if (pfl->old_multiple_chip_handling) {
+blocks_per_device = pfl->nb_blocs / num_devices;
+sector_len_per_device = pfl->sector_len;
+} else {
+blocks_per_device = pfl->nb_blocs;
+sector_len_per_device = pfl->sector_len / num_devices;
+}
+device_len = sector_len_per_device * blocks_per_device;
 
 /* XXX: to be fixed */
 #if 0
@@ -832,6 +839,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 pfl->cfi_table[0x2A] = 0x0B;
 }
 pfl->writeblock_size = 1 << pfl->cfi_table[0x2A];
+if (!pfl->old_multiple_chip_handling && num_devices > 1)

Re: [Qemu-block] [PATCH RFC v2 5/6] replication: Implement block replication for shared disk case

2017-01-17 Thread Hailiang Zhang

Hi Stefan,

On 2017/1/17 21:19, Stefan Hajnoczi wrote:

On Mon, Dec 05, 2016 at 04:35:03PM +0800, zhanghailiang wrote:

@@ -663,8 +695,12 @@ static void replication_stop(ReplicationState *rs, bool 
failover, Error **errp)

  switch (s->mode) {
  case REPLICATION_MODE_PRIMARY:
-s->replication_state = BLOCK_REPLICATION_DONE;
-s->error = 0;
+if (s->is_shared_disk && s->primary_disk->bs->job) {
+block_job_cancel(s->primary_disk->bs->job);


Should this be block_job_cancel_sync()?



No, here it is different from the secondary side which needs to wait
until backup job been canceled before resumes to run (Or there will be
an error, https://patchwork.kernel.org/patch/9128841/).

For primary VM, Just as you can see the design scenario in patch 1,
It accesses the shared disk directly, the backup job whose source side
is just the shared disk does not influence primary VM's running,
So IMHO, it is safe to call block_job_cancel here.

Thanks,
Hailiang



+} else {
+s->replication_state = BLOCK_REPLICATION_DONE;
+s->error = 0;
+}
  break;
  case REPLICATION_MODE_SECONDARY:
  /*
--
1.8.3.1







Re: [Qemu-block] [PATCH RFC v2 4/6] replication: fix code logic with the new shared_disk option

2017-01-17 Thread Hailiang Zhang

On 2016/12/20 20:42, Changlong Xie wrote:

On 12/05/2016 04:35 PM, zhanghailiang wrote:

Some code logic only be needed in non-shared disk, here
we adjust these codes to prepare for shared disk scenario.

Signed-off-by: zhanghailiang 
---
   block/replication.c | 47 ---
   1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/block/replication.c b/block/replication.c
index 35e9ab3..6574cc2 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -531,21 +531,28 @@ static void replication_start(ReplicationState *rs, 
ReplicationMode mode,
   aio_context_release(aio_context);
   return;
   }
-bdrv_op_block_all(top_bs, s->blocker);
-bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);

-job = backup_job_create(NULL, s->secondary_disk->bs, 
s->hidden_disk->bs,
-0, MIRROR_SYNC_MODE_NONE, NULL, false,
+/*
+ * Only in the case of non-shared disk,
+ * the backup job is in the secondary side
+ */
+if (!s->is_shared_disk) {
+bdrv_op_block_all(top_bs, s->blocker);
+bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
+job = backup_job_create(NULL, s->secondary_disk->bs,
+s->hidden_disk->bs, 0,
+MIRROR_SYNC_MODE_NONE, NULL, false,
   BLOCKDEV_ON_ERROR_REPORT,
   BLOCKDEV_ON_ERROR_REPORT, BLOCK_JOB_INTERNAL,
   backup_job_completed, bs, NULL, &local_err);


Coding style here.



Will fix it in next version, thanks.


-if (local_err) {
-error_propagate(errp, local_err);
-backup_job_cleanup(bs);
-aio_context_release(aio_context);
-return;
+if (local_err) {
+error_propagate(errp, local_err);
+backup_job_cleanup(bs);
+aio_context_release(aio_context);
+return;
+}
+block_job_start(job);
   }
-block_job_start(job);

   secondary_do_checkpoint(s, errp);
   break;
@@ -575,14 +582,16 @@ static void replication_do_checkpoint(ReplicationState 
*rs, Error **errp)
   case REPLICATION_MODE_PRIMARY:
   break;
   case REPLICATION_MODE_SECONDARY:
-if (!s->secondary_disk->bs->job) {
-error_setg(errp, "Backup job was cancelled unexpectedly");
-break;
-}
-backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
-break;
+if (!s->is_shared_disk) {
+if (!s->secondary_disk->bs->job) {
+error_setg(errp, "Backup job was cancelled unexpectedly");
+break;
+}
+backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+break;
+}
   }
   secondary_do_checkpoint(s, errp);
   break;
@@ -663,7 +672,7 @@ static void replication_stop(ReplicationState *rs, bool 
failover, Error **errp)
* before the BDS is closed, because we will access hidden
* disk, secondary disk in backup_job_completed().
*/
-if (s->secondary_disk->bs->job) {
+if (!s->is_shared_disk && s->secondary_disk->bs->job) {
   block_job_cancel_sync(s->secondary_disk->bs->job);
   }






.






Re: [Qemu-block] [Qemu-devel] [PATCH RFC v2 2/6] replication: add shared-disk and shared-disk-id options

2017-01-17 Thread Hailiang Zhang

On 2016/12/6 0:22, Eric Blake wrote:

On 12/05/2016 02:35 AM, zhanghailiang wrote:

We use these two options to identify which disk is
shared

Signed-off-by: zhanghailiang 
Signed-off-by: Wen Congyang 
Signed-off-by: Zhang Chen 
---
v2:
- add these two options for BlockdevOptionsReplication to support
   qmp blockdev-add command.
- fix a memory leak found by Changlong
---



+++ b/qapi/block-core.json
@@ -2232,12 +2232,19 @@
  #  node who owns the replication node chain. Must not be given in
  #  primary mode.
  #
+# @shared-disk-id: #optional The id of shared disk while in replication mode.
+#
+# @shared-disk: #optional To indicate whether or not a disk is shared by
+#   primary VM and secondary VM.


Both of these need a '(since 2.9)' designation since they've missed 2.8,
and could probably also use documentation on the default value assumed
when the parameter is omitted.



OK, i will add it in next version, thanks.


+#
  # Since: 2.8
  ##
  { 'struct': 'BlockdevOptionsReplication',
'base': 'BlockdevOptionsGenericFormat',
'data': { 'mode': 'ReplicationMode',
-'*top-id': 'str' } }
+'*top-id': 'str',
+'*shared-disk-id': 'str',
+'*shared-disk': 'bool' } }

  ##
  # @NFSTransport








Re: [Qemu-block] [PATCH RFC v2 2/6] replication: add shared-disk and shared-disk-id options

2017-01-17 Thread Hailiang Zhang

On 2017/1/17 19:25, Stefan Hajnoczi wrote:

On Mon, Dec 05, 2016 at 04:35:00PM +0800, zhanghailiang wrote:

@@ -85,6 +99,9 @@ static int replication_open(BlockDriverState *bs, QDict 
*options,
  QemuOpts *opts = NULL;
  const char *mode;
  const char *top_id;
+const char *shared_disk_id;
+BlockBackend *blk;
+BlockDriverState *tmp_bs;

  ret = -EINVAL;
  opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, &error_abort);
@@ -119,6 +136,25 @@ static int replication_open(BlockDriverState *bs, QDict 
*options,
 "The option mode's value should be primary or secondary");
  goto fail;
  }
+s->is_shared_disk = qemu_opt_get_bool(opts, REPLICATION_SHARED_DISK,
+  false);
+if (s->is_shared_disk && (s->mode == REPLICATION_MODE_PRIMARY)) {
+shared_disk_id = qemu_opt_get(opts, REPLICATION_SHARED_DISK_ID);
+if (!shared_disk_id) {
+error_setg(&local_err, "Missing shared disk blk");
+goto fail;
+}
+s->shared_disk_id = g_strdup(shared_disk_id);
+blk = blk_by_name(s->shared_disk_id);
+if (!blk) {
+g_free(s->shared_disk_id);
+error_setg(&local_err, "There is no %s block", s->shared_disk_id);
+goto fail;


Please move the g_free() to the fail label to prevent future code
changes from introducing a memory leak.



OK, I will fix it in next version, thanks very much.