[Qemu-block] [PATCH 0/5] ide: avoid main-loop hang on CDROM/NFS failure

2015-09-21 Thread Peter Lieven
This series aims at avoiding a hanging main-loop if a vserver has a
CDROM image mounted from a NFS share and that NFS share goes down.
Typical situation is that users mount an CDROM ISO to install something
and then forget to eject that CDROM afterwards.
As a consequence this mounted CD is able to bring down the
whole vserver if the backend NFS share is unreachable. This is bad
especially if the CDROM itself is not needed anymore at this point.

This series aims at fixing 3 blocking I/O operations that would
hang if the NFS server is unavailable:
 - ATAPI PIO read requests used sync calls to blk_read, convert
   them to an async variant.
 - If a busmaster DMA request is cancelled all requests are drained.
   Convert the drain to an async request canceling.
 - query-block in the HMP or QMP hangs because it indirectly calls
   bdrv_get_allocated_file_size.

Note that Patch 5 is only included for completeness.

Peter

Peter Lieven (5):
  ide/atapi: make PIO read requests async
  ide/atapi: blk_aio_readv may return NULL
  ide: add support for cancelable read requests
  ide/atapi: enable cancelable requests
  block/nfs: cache allocated filesize for read-only files

 block/nfs.c   | 36 ++
 hw/ide/atapi.c| 75 +++
 hw/ide/core.c | 55 
 hw/ide/internal.h | 16 
 hw/ide/pci.c  | 42 ---
 5 files changed, 183 insertions(+), 41 deletions(-)

-- 
1.9.1




[Qemu-block] [PATCH 1/5] ide/atapi: make PIO read requests async

2015-09-21 Thread Peter Lieven
PIO read requests on the ATAPI interface used to be sync blk requests.
This has to siginificant drawbacks. First the main loop hangs util an
I/O request is completed and secondly if the I/O request does not
complete (e.g. due to an unresponsive storage) Qemu hangs completely.

Signed-off-by: Peter Lieven 
---
 hw/ide/atapi.c | 69 --
 1 file changed, 43 insertions(+), 26 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 747f466..9257e1c 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -105,31 +105,51 @@ static void cd_data_to_raw(uint8_t *buf, int lba)
 memset(buf, 0, 288);
 }
 
-static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)
+static void cd_read_sector_cb(void *opaque, int ret)
 {
-int ret;
+IDEState *s = opaque;
 
-switch(sector_size) {
-case 2048:
-block_acct_start(blk_get_stats(s->blk), >acct,
- 4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
-ret = blk_read(s->blk, (int64_t)lba << 2, buf, 4);
-block_acct_done(blk_get_stats(s->blk), >acct);
-break;
-case 2352:
-block_acct_start(blk_get_stats(s->blk), >acct,
- 4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
-ret = blk_read(s->blk, (int64_t)lba << 2, buf + 16, 4);
-block_acct_done(blk_get_stats(s->blk), >acct);
-if (ret < 0)
-return ret;
-cd_data_to_raw(buf, lba);
-break;
-default:
-ret = -EIO;
-break;
+block_acct_done(blk_get_stats(s->blk), >acct);
+
+if (ret < 0) {
+ide_atapi_io_error(s, ret);
+return;
+}
+
+if (s->cd_sector_size == 2352) {
+cd_data_to_raw(s->io_buffer, s->lba);
 }
-return ret;
+
+s->lba++;
+s->io_buffer_index = 0;
+s->status &= ~BUSY_STAT;
+
+ide_atapi_cmd_reply_end(s);
+}
+
+static int cd_read_sector(IDEState *s, int lba, void *buf, int sector_size)
+{
+if (sector_size != 2048 && sector_size != 2352) {
+return -EINVAL;
+}
+
+s->iov.iov_base = buf;
+if (sector_size == 2352) {
+buf += 4;
+}
+
+s->iov.iov_len = 4 * BDRV_SECTOR_SIZE;
+qemu_iovec_init_external(>qiov, >iov, 1);
+
+if (blk_aio_readv(s->blk, (int64_t)lba << 2, >qiov, 4,
+  cd_read_sector_cb, s) == NULL) {
+return -EIO;
+}
+
+block_acct_start(blk_get_stats(s->blk), >acct,
+ 4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
+s->status |= BUSY_STAT;
+return 0;
 }
 
 void ide_atapi_cmd_ok(IDEState *s)
@@ -190,10 +210,8 @@ void ide_atapi_cmd_reply_end(IDEState *s)
 ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size);
 if (ret < 0) {
 ide_atapi_io_error(s, ret);
-return;
 }
-s->lba++;
-s->io_buffer_index = 0;
+return;
 }
 if (s->elementary_transfer_size > 0) {
 /* there are some data left to transmit in this elementary
@@ -275,7 +293,6 @@ static void ide_atapi_cmd_read_pio(IDEState *s, int lba, 
int nb_sectors,
 s->io_buffer_index = sector_size;
 s->cd_sector_size = sector_size;
 
-s->status = READY_STAT | SEEK_STAT;
 ide_atapi_cmd_reply_end(s);
 }
 
-- 
1.9.1




[Qemu-block] [PATCH 2/5] ide/atapi: blk_aio_readv may return NULL

2015-09-21 Thread Peter Lieven
Signed-off-by: Peter Lieven 
---
 hw/ide/atapi.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 9257e1c..b209ed9 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -371,6 +371,10 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int 
ret)
 s->bus->dma->aiocb = blk_aio_readv(s->blk, (int64_t)s->lba << 2,
>bus->dma->qiov, n * 4,
ide_atapi_cmd_read_dma_cb, s);
+if (s->bus->dma->aiocb == NULL) {
+ide_atapi_io_error(s, -EIO);
+goto eot;
+}
 return;
 
 eot:
-- 
1.9.1




[Qemu-block] [PATCH 3/5] ide: add support for cancelable read requests

2015-09-21 Thread Peter Lieven
this patch adds a new aio readv compatible function which copies
all data through a bounce buffer. The benefit is that these requests
can be flagged as canceled to avoid guest memory corruption when
a canceled request is completed by the backend at a later stage.

If an IDE protocol wants to use this function it has to pipe
all read requests through ide_readv_cancelable and it may then
enable requests_cancelable in the IDEState.

If this state is enable we can avoid the blocking blk_drain_all
in case of a BMDMA reset.

Currently only read operations are cancelable thus we can only
use this logic for read-only devices.

Signed-off-by: Peter Lieven 
---
 hw/ide/core.c | 54 ++
 hw/ide/internal.h | 16 
 hw/ide/pci.c  | 42 --
 3 files changed, 98 insertions(+), 14 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 317406d..24547ce 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -561,6 +561,59 @@ static bool ide_sect_range_ok(IDEState *s,
 return true;
 }
 
+static void ide_readv_cancelable_cb(void *opaque, int ret)
+{
+IDECancelableRequest *req = opaque;
+if (!req->canceled) {
+if (!ret) {
+qemu_iovec_from_buf(req->org_qiov, 0, req->buf, 
req->org_qiov->size);
+}
+req->org_cb(req->org_opaque, ret);
+}
+QLIST_REMOVE(req, list);
+qemu_vfree(req->buf);
+qemu_iovec_destroy(>qiov);
+g_free(req);
+}
+
+#define MAX_CANCELABLE_REQS 16
+
+BlockAIOCB *ide_readv_cancelable(IDEState *s, int64_t sector_num,
+ QEMUIOVector *iov, int nb_sectors,
+ BlockCompletionFunc *cb, void *opaque)
+{
+BlockAIOCB *aioreq;
+IDECancelableRequest *req;
+int c = 0;
+
+QLIST_FOREACH(req, >cancelable_requests, list) {
+c++;
+}
+if (c > MAX_CANCELABLE_REQS) {
+return NULL;
+}
+
+req = g_new0(IDECancelableRequest, 1);
+qemu_iovec_init(>qiov, 1);
+req->buf = qemu_blockalign(blk_bs(s->blk), iov->size);
+qemu_iovec_add(>qiov, req->buf, iov->size);
+req->org_qiov = iov;
+req->org_cb = cb;
+req->org_opaque = opaque;
+
+aioreq = blk_aio_readv(s->blk, sector_num, >qiov, nb_sectors,
+   ide_readv_cancelable_cb, req);
+if (aioreq == NULL) {
+qemu_vfree(req->buf);
+qemu_iovec_destroy(>qiov);
+g_free(req);
+} else {
+QLIST_INSERT_HEAD(>cancelable_requests, req, list);
+}
+
+return aioreq;
+}
+
 static void ide_sector_read(IDEState *s);
 
 static void ide_sector_read_cb(void *opaque, int ret)
@@ -805,6 +858,7 @@ void ide_start_dma(IDEState *s, BlockCompletionFunc *cb)
 s->bus->retry_unit = s->unit;
 s->bus->retry_sector_num = ide_get_sector(s);
 s->bus->retry_nsector = s->nsector;
+s->bus->s = s;
 if (s->bus->dma->ops->start_dma) {
 s->bus->dma->ops->start_dma(s->bus->dma, s, cb);
 }
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 05e93ff..ad188c2 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -343,6 +343,16 @@ enum ide_dma_cmd {
 #define ide_cmd_is_read(s) \
((s)->dma_cmd == IDE_DMA_READ)
 
+typedef struct IDECancelableRequest {
+QLIST_ENTRY(IDECancelableRequest) list;
+QEMUIOVector qiov;
+uint8_t *buf;
+QEMUIOVector *org_qiov;
+BlockCompletionFunc *org_cb;
+void *org_opaque;
+bool canceled;
+} IDECancelableRequest;
+
 /* NOTE: IDEState represents in fact one drive */
 struct IDEState {
 IDEBus *bus;
@@ -396,6 +406,8 @@ struct IDEState {
 BlockAIOCB *pio_aiocb;
 struct iovec iov;
 QEMUIOVector qiov;
+QLIST_HEAD(, IDECancelableRequest) cancelable_requests;
+bool requests_cancelable;
 /* ATA DMA state */
 int32_t io_buffer_offset;
 int32_t io_buffer_size;
@@ -468,6 +480,7 @@ struct IDEBus {
 uint8_t retry_unit;
 int64_t retry_sector_num;
 uint32_t retry_nsector;
+IDEState *s;
 };
 
 #define TYPE_IDE_DEVICE "ide-device"
@@ -572,6 +585,9 @@ void ide_set_inactive(IDEState *s, bool more);
 BlockAIOCB *ide_issue_trim(BlockBackend *blk,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
 BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *ide_readv_cancelable(IDEState *s, int64_t sector_num,
+ QEMUIOVector *iov, int nb_sectors,
+ BlockCompletionFunc *cb, void *opaque);
 
 /* hw/ide/atapi.c */
 void ide_atapi_cmd(IDEState *s);
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index d31ff88..5587183 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -240,21 +240,35 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
 /* Ignore writes to SSBM if it keeps the old value */
 if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {
 if (!(val & BM_CMD_START)) {
-/*
- * We can't cancel Scatter Gather DMA 

[Qemu-block] [PATCH 4/5] ide/atapi: enable cancelable requests

2015-09-21 Thread Peter Lieven
Signed-off-by: Peter Lieven 
---
 hw/ide/atapi.c | 4 ++--
 hw/ide/core.c  | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index b209ed9..ab45495 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -141,7 +141,7 @@ static int cd_read_sector(IDEState *s, int lba, void *buf, 
int sector_size)
 s->iov.iov_len = 4 * BDRV_SECTOR_SIZE;
 qemu_iovec_init_external(>qiov, >iov, 1);
 
-if (blk_aio_readv(s->blk, (int64_t)lba << 2, >qiov, 4,
+if (ide_readv_cancelable(s, (int64_t)lba << 2, >qiov, 4,
   cd_read_sector_cb, s) == NULL) {
 return -EIO;
 }
@@ -368,7 +368,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
 s->bus->dma->iov.iov_len = n * 4 * 512;
 qemu_iovec_init_external(>bus->dma->qiov, >bus->dma->iov, 1);
 
-s->bus->dma->aiocb = blk_aio_readv(s->blk, (int64_t)s->lba << 2,
+s->bus->dma->aiocb = ide_readv_cancelable(s, (int64_t)s->lba << 2,
>bus->dma->qiov, n * 4,
ide_atapi_cmd_read_dma_cb, s);
 if (s->bus->dma->aiocb == NULL) {
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 24547ce..5c7a346 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2330,6 +2330,7 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, 
IDEDriveKind kind,
 if (kind == IDE_CD) {
 blk_set_dev_ops(blk, _cd_block_ops, s);
 blk_set_guest_block_size(blk, 2048);
+s->requests_cancelable = true;
 } else {
 if (!blk_is_inserted(s->blk)) {
 error_report("Device needs media, but drive is empty");
-- 
1.9.1




[Qemu-block] [PATCH 5/5] block/nfs: cache allocated filesize for read-only files

2015-09-21 Thread Peter Lieven
If the file is readonly its not expected to grow so
save the blocking call to nfs_fstat_async and use
the value saved at connection time. Also important
the monitor (and thus the main loop) will not hang
if block device info is queried and the NFS share
is unresponsive.

Signed-off-by: Peter Lieven 
Reviewed-by: Max Reitz 
Reviewed-by: Jeff Cody 
---
 block/nfs.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/block/nfs.c b/block/nfs.c
index c026ff6..5ffd19f 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -43,6 +43,7 @@ typedef struct NFSClient {
 int events;
 bool has_zero_init;
 AioContext *aio_context;
+blkcnt_t st_blocks;
 } NFSClient;
 
 typedef struct NFSRPC {
@@ -374,6 +375,7 @@ static int64_t nfs_client_open(NFSClient *client, const 
char *filename,
 }
 
 ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);
+client->st_blocks = st.st_blocks;
 client->has_zero_init = S_ISREG(st.st_mode);
 goto out;
 fail:
@@ -464,6 +466,11 @@ static int64_t 
nfs_get_allocated_file_size(BlockDriverState *bs)
 NFSRPC task = {0};
 struct stat st;
 
+if (bdrv_is_read_only(bs) &&
+!(bs->open_flags & BDRV_O_NOCACHE)) {
+return client->st_blocks * 512;
+}
+
 task.st = 
 if (nfs_fstat_async(client->context, client->fh, nfs_co_generic_cb,
 ) != 0) {
@@ -484,6 +491,34 @@ static int nfs_file_truncate(BlockDriverState *bs, int64_t 
offset)
 return nfs_ftruncate(client->context, client->fh, offset);
 }
 
+/* Note that this will not re-establish a connection with the NFS server
+ * - it is effectively a NOP.  */
+static int nfs_reopen_prepare(BDRVReopenState *state,
+  BlockReopenQueue *queue, Error **errp)
+{
+NFSClient *client = state->bs->opaque;
+struct stat st;
+int ret = 0;
+
+if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) {
+error_setg(errp, "Cannot open a read-only mount as read-write");
+return -EACCES;
+}
+
+/* Update cache for read-only reopens */
+if (!(state->flags & BDRV_O_RDWR)) {
+ret = nfs_fstat(client->context, client->fh, );
+if (ret < 0) {
+error_setg(errp, "Failed to fstat file: %s",
+   nfs_get_error(client->context));
+return ret;
+}
+client->st_blocks = st.st_blocks;
+}
+
+return 0;
+}
+
 static BlockDriver bdrv_nfs = {
 .format_name= "nfs",
 .protocol_name  = "nfs",
@@ -499,6 +534,7 @@ static BlockDriver bdrv_nfs = {
 .bdrv_file_open = nfs_file_open,
 .bdrv_close = nfs_file_close,
 .bdrv_create= nfs_file_create,
+.bdrv_reopen_prepare= nfs_reopen_prepare,
 
 .bdrv_co_readv  = nfs_co_readv,
 .bdrv_co_writev = nfs_co_writev,
-- 
1.9.1




[Qemu-block] [PATCH v5 31/46] qapi: use 'type' in generated C code to match QMP union wire form

2015-09-21 Thread Eric Blake
When dealing with simple qapi unions, the code was generating a
discriminator field of 'kind' even though the discriminator is
sent as 'type' over QMP.  Renaming things to match gets us one
step closer to reusing common generator code for both simple and
flat unions, without having to special case the naming choice
for simple unions.  It also gets rid of some TODO markers in
using the raw QAPISchemaObjectTypeVariants.tag_name field,
although we can't yet convert that field to private until later
fixes to alternate types also quit using it.

However, this patch does not rename the generated enum, which is
still 'unionnameKind'; if we wanted, a further patch could
generate implicit enums as 'unionnameType', with even more
churn to C code to react, and probably update the qapi generator
to reserve the 'fooType' namespace instead of 'fooKind', or better
yet ensure that generated names do not conflict with user names.
But that is a lot harder, as we already have existing qapi usage
of types that end in 'Type'.

Signed-off-by: Eric Blake 
---
 block/qcow2.c   |  2 +-
 block/vmdk.c|  2 +-
 blockdev.c  | 16 
 hmp.c   | 12 ++--
 hw/input/hid.c  |  2 +-
 hw/input/ps2.c  |  2 +-
 hw/input/virtio-input-hid.c |  2 +-
 hw/mem/pc-dimm.c|  2 +-
 net/dump.c  |  2 +-
 net/hub.c   |  2 +-
 net/l2tpv3.c|  2 +-
 net/net.c   | 20 ++--
 net/slirp.c |  2 +-
 net/socket.c|  2 +-
 net/tap.c   |  4 ++--
 net/vhost-user.c|  2 +-
 numa.c  |  4 ++--
 qemu-char.c | 24 
 scripts/qapi-types.py   |  7 ++-
 scripts/qapi-visit.py   |  9 +
 tests/test-qmp-commands.c   |  2 +-
 tests/test-qmp-input-visitor.c  |  8 
 tests/test-qmp-output-visitor.c |  6 +++---
 tpm.c   |  2 +-
 ui/input-keymap.c   | 10 +-
 ui/input-legacy.c   |  2 +-
 ui/input.c  | 22 +++---
 util/qemu-sockets.c | 12 ++--
 28 files changed, 87 insertions(+), 97 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 56ad808..28aa74d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2736,7 +2736,7 @@ static ImageInfoSpecific 
*qcow2_get_specific_info(BlockDriverState *bs)
 ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);

 *spec_info = (ImageInfoSpecific){
-.kind  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
+.type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
 {
 .qcow2 = g_new(ImageInfoSpecificQCow2, 1),
 },
diff --git a/block/vmdk.c b/block/vmdk.c
index be0d640..695780c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -2156,7 +2156,7 @@ static ImageInfoSpecific 
*vmdk_get_specific_info(BlockDriverState *bs)
 ImageInfoList **next;

 *spec_info = (ImageInfoSpecific){
-.kind = IMAGE_INFO_SPECIFIC_KIND_VMDK,
+.type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
 {
 .vmdk = g_new0(ImageInfoSpecificVmdk, 1),
 },
diff --git a/blockdev.c b/blockdev.c
index 32b04b4..bf8a7a2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1052,12 +1052,12 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
 }
 }

-static void blockdev_do_action(int kind, void *data, Error **errp)
+static void blockdev_do_action(int type, void *data, Error **errp)
 {
 TransactionAction action;
 TransactionActionList list;

-action.kind = kind;
+action.type = type;
 action.data = data;
 list.value = 
 list.next = NULL;
@@ -1297,7 +1297,7 @@ static void internal_snapshot_prepare(BlkTransactionState 
*common,
 InternalSnapshotState *state;
 int ret1;

-g_assert(common->action->kind ==
+g_assert(common->action->type ==
  TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC);
 internal = common->action->blockdev_snapshot_internal_sync;
 state = DO_UPCAST(InternalSnapshotState, common, common);
@@ -1439,7 +1439,7 @@ static void external_snapshot_prepare(BlkTransactionState 
*common,
 TransactionAction *action = common->action;

 /* get parameters */
-g_assert(action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
+g_assert(action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);

 has_device = action->blockdev_snapshot_sync->has_device;
 device = action->blockdev_snapshot_sync->device;
@@ -1579,7 +1579,7 @@ static void drive_backup_prepare(BlkTransactionState 
*common, Error **errp)
 DriveBackup *backup;
 Error *local_err = NULL;

-assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
+assert(common->action->type == 

[Qemu-block] [PATCH v5 36/46] qapi: Avoid use of 'data' member of qapi unions

2015-09-21 Thread Eric Blake
qapi code generators currently create a 'void *data' member as
part of the anonymous union embedded in the C struct corresponding
to a qapi union.  However, directly assigning to this member of
the union feels a bit fishy, when we can directly use the rest
of the struct instead.

Signed-off-by: Eric Blake 
---
 blockdev.c | 22 --
 ui/input.c |  2 +-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index bf8a7a2..28a3375 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1052,14 +1052,11 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
 }
 }

-static void blockdev_do_action(int type, void *data, Error **errp)
+static void blockdev_do_action(TransactionAction *action, Error **errp)
 {
-TransactionAction action;
 TransactionActionList list;

-action.type = type;
-action.data = data;
-list.value = 
+list.value = action;
 list.next = NULL;
 qmp_transaction(, errp);
 }
@@ -1085,8 +1082,11 @@ void qmp_blockdev_snapshot_sync(bool has_device, const 
char *device,
 .has_mode = has_mode,
 .mode = mode,
 };
-blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
-   , errp);
+TransactionAction action = {
+.type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
+.blockdev_snapshot_sync = ,
+};
+blockdev_do_action(, errp);
 }

 void qmp_blockdev_snapshot_internal_sync(const char *device,
@@ -1097,9 +1097,11 @@ void qmp_blockdev_snapshot_internal_sync(const char 
*device,
 .device = (char *) device,
 .name = (char *) name
 };
-
-blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC,
-   , errp);
+TransactionAction action = {
+.type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC,
+.blockdev_snapshot_internal_sync = ,
+};
+blockdev_do_action(, errp);
 }

 SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
diff --git a/ui/input.c b/ui/input.c
index fd86571..edd237d 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -452,7 +452,7 @@ InputEvent *qemu_input_event_new_move(InputEventKind kind,
 InputMoveEvent *move = g_new0(InputMoveEvent, 1);

 evt->type = kind;
-evt->data = move;
+evt->rel = move; /* also would work as evt->abs */
 move->axis = axis;
 move->value = value;
 return evt;
-- 
2.4.3




Re: [Qemu-block] [PATCH v5 14/38] block: Remove wr_highest_sector from BlockAcctStats

2015-09-21 Thread Eric Blake
On 09/21/2015 01:57 AM, Kevin Wolf wrote:

>>> +- "wr_highest_offset": The offset after the greatest byte written to 
>>> the
>>> +   BlockDriverState since it has been opened 
>>> (json-int)
>>
>> ...someday, I'd really like to have this stat show as non-zero even when
>> first opening the device (before writing to it). Right now, you have no
>> clue how full a backing device is prior to starting a block-commit; you
>> have to start writing to it to get a feel for its current usage.
> 
> With which value would it start? You don't want the file/device size
> because for block devices that's more than is actually used yet.
> 
> What you really want to know is a number for the parent node, which
> isn't readily available for qcow2 (you would have to scan the refcounts
> in the last refcount block on startup) and doesn't really exist for most
> other formats (very few of them can be used on block devices, most rely
> on the file size).

Libvirt only uses the stat on qcow2 format atop block devices, and uses
it precisely because that is the one place where relying on device size
is wrong.  And yes, it really WOULD be nice for the value to read the
last refcount block on startup, as that IS the correct value.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-block] [Qemu-devel] [PATCH 0/5] ide: avoid main-loop hang on CDROM/NFS failure

2015-09-21 Thread John Snow


On 09/21/2015 08:25 AM, Peter Lieven wrote:
> This series aims at avoiding a hanging main-loop if a vserver has a
> CDROM image mounted from a NFS share and that NFS share goes down.
> Typical situation is that users mount an CDROM ISO to install something
> and then forget to eject that CDROM afterwards.
> As a consequence this mounted CD is able to bring down the
> whole vserver if the backend NFS share is unreachable. This is bad
> especially if the CDROM itself is not needed anymore at this point.
> 
> This series aims at fixing 3 blocking I/O operations that would
> hang if the NFS server is unavailable:
>  - ATAPI PIO read requests used sync calls to blk_read, convert
>them to an async variant.
>  - If a busmaster DMA request is cancelled all requests are drained.
>Convert the drain to an async request canceling.
>  - query-block in the HMP or QMP hangs because it indirectly calls
>bdrv_get_allocated_file_size.
> 
> Note that Patch 5 is only included for completeness.
> 
> Peter
> 
> Peter Lieven (5):
>   ide/atapi: make PIO read requests async
>   ide/atapi: blk_aio_readv may return NULL
>   ide: add support for cancelable read requests
>   ide/atapi: enable cancelable requests
>   block/nfs: cache allocated filesize for read-only files
> 
>  block/nfs.c   | 36 ++
>  hw/ide/atapi.c| 75 
> +++
>  hw/ide/core.c | 55 
>  hw/ide/internal.h | 16 
>  hw/ide/pci.c  | 42 ---
>  5 files changed, 183 insertions(+), 41 deletions(-)
> 

I assume this supersedes both:

[Qemu-devel] [PATCH 0/2] ide/atapi: partially avoid deadlock if the
storage backend is dead

and

[Qemu-devel] [PATCH] ide/atapi: make PIO read requests async

right?

--js



Re: [Qemu-block] [Qemu-devel] [PATCH 0/5] ide: avoid main-loop hang on CDROM/NFS failure

2015-09-21 Thread Peter Lieven


> Am 21.09.2015 um 22:58 schrieb John Snow :
> 
> 
> 
>> On 09/21/2015 08:25 AM, Peter Lieven wrote:
>> This series aims at avoiding a hanging main-loop if a vserver has a
>> CDROM image mounted from a NFS share and that NFS share goes down.
>> Typical situation is that users mount an CDROM ISO to install something
>> and then forget to eject that CDROM afterwards.
>> As a consequence this mounted CD is able to bring down the
>> whole vserver if the backend NFS share is unreachable. This is bad
>> especially if the CDROM itself is not needed anymore at this point.
>> 
>> This series aims at fixing 3 blocking I/O operations that would
>> hang if the NFS server is unavailable:
>> - ATAPI PIO read requests used sync calls to blk_read, convert
>>   them to an async variant.
>> - If a busmaster DMA request is cancelled all requests are drained.
>>   Convert the drain to an async request canceling.
>> - query-block in the HMP or QMP hangs because it indirectly calls
>>   bdrv_get_allocated_file_size.
>> 
>> Note that Patch 5 is only included for completeness.
>> 
>> Peter
>> 
>> Peter Lieven (5):
>>  ide/atapi: make PIO read requests async
>>  ide/atapi: blk_aio_readv may return NULL
>>  ide: add support for cancelable read requests
>>  ide/atapi: enable cancelable requests
>>  block/nfs: cache allocated filesize for read-only files
>> 
>> block/nfs.c   | 36 ++
>> hw/ide/atapi.c| 75 
>> +++
>> hw/ide/core.c | 55 
>> hw/ide/internal.h | 16 
>> hw/ide/pci.c  | 42 ---
>> 5 files changed, 183 insertions(+), 41 deletions(-)
> 
> I assume this supersedes both:
> 
> [Qemu-devel] [PATCH 0/2] ide/atapi: partially avoid deadlock if the
> storage backend is dead
> 
> and
> 
> [Qemu-devel] [PATCH] ide/atapi: make PIO read requests async
> 
> right?

yes, the first patch was wrong as Stefan pointed out and the second is the same 
version as previously on the list.

Peter 

> 
> --js