aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block-migration.c6
-rw-r--r--block.c32
-rw-r--r--block.h1
-rw-r--r--block_int.h4
-rw-r--r--blockdev.c1
-rw-r--r--hw/ide/core.c15
-rw-r--r--hw/virtio-blk.c8
-rw-r--r--hw/virtio-pci.c1
-rw-r--r--hw/virtio.h1
-rw-r--r--qemu-options.hx2
10 files changed, 59 insertions, 12 deletions
diff --git a/block-migration.c b/block-migration.c
index a77106e25c..8eda307d7f 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -586,6 +586,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
addr >>= BDRV_SECTOR_BITS;
if (flags & BLK_MIG_FLAG_DEVICE_BLOCK) {
+ int ret;
/* get device name */
len = qemu_get_byte(f);
qemu_get_buffer(f, (uint8_t *)device_name, len);
@@ -601,9 +602,12 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
buf = qemu_malloc(BLOCK_SIZE);
qemu_get_buffer(f, buf, BLOCK_SIZE);
- bdrv_write(bs, addr, buf, BDRV_SECTORS_PER_DIRTY_CHUNK);
+ ret = bdrv_write(bs, addr, buf, BDRV_SECTORS_PER_DIRTY_CHUNK);
qemu_free(buf);
+ if (ret < 0) {
+ return ret;
+ }
} else if (flags & BLK_MIG_FLAG_PROGRESS) {
if (!banner_printed) {
printf("Receiving block device images\n");
diff --git a/block.c b/block.c
index f837876d85..452ae94eea 100644
--- a/block.c
+++ b/block.c
@@ -330,7 +330,7 @@ BlockDriver *bdrv_find_protocol(const char *filename)
return NULL;
}
-static BlockDriver *find_image_format(const char *filename)
+static int find_image_format(const char *filename, BlockDriver **pdrv)
{
int ret, score, score_max;
BlockDriver *drv1, *drv;
@@ -338,19 +338,27 @@ static BlockDriver *find_image_format(const char *filename)
BlockDriverState *bs;
ret = bdrv_file_open(&bs, filename, 0);
- if (ret < 0)
- return NULL;
+ if (ret < 0) {
+ *pdrv = NULL;
+ return ret;
+ }
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
if (bs->sg || !bdrv_is_inserted(bs)) {
bdrv_delete(bs);
- return bdrv_find_format("raw");
+ drv = bdrv_find_format("raw");
+ if (!drv) {
+ ret = -ENOENT;
+ }
+ *pdrv = drv;
+ return ret;
}
ret = bdrv_pread(bs, 0, buf, sizeof(buf));
bdrv_delete(bs);
if (ret < 0) {
- return NULL;
+ *pdrv = NULL;
+ return ret;
}
score_max = 0;
@@ -364,7 +372,11 @@ static BlockDriver *find_image_format(const char *filename)
}
}
}
- return drv;
+ if (!drv) {
+ ret = -ENOENT;
+ }
+ *pdrv = drv;
+ return ret;
}
/**
@@ -571,12 +583,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
/* Find the right image format driver */
if (!drv) {
- drv = find_image_format(filename);
+ ret = find_image_format(filename, &drv);
probed = 1;
}
if (!drv) {
- ret = -ENOENT;
goto unlink_and_fail;
}
@@ -1800,6 +1811,11 @@ int bdrv_can_snapshot(BlockDriverState *bs)
return 1;
}
+int bdrv_is_snapshot(BlockDriverState *bs)
+{
+ return !!(bs->open_flags & BDRV_O_SNAPSHOT);
+}
+
BlockDriverState *bdrv_snapshots(void)
{
BlockDriverState *bs;
diff --git a/block.h b/block.h
index c2a7e4c762..db131a3438 100644
--- a/block.h
+++ b/block.h
@@ -202,6 +202,7 @@ const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size);
int bdrv_can_snapshot(BlockDriverState *bs);
+int bdrv_is_snapshot(BlockDriverState *bs);
BlockDriverState *bdrv_snapshots(void);
int bdrv_snapshot_create(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info);
diff --git a/block_int.h b/block_int.h
index 96ff4cf1bc..f075a8cba5 100644
--- a/block_int.h
+++ b/block_int.h
@@ -243,7 +243,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
_conf.logical_block_size, 512), \
DEFINE_PROP_UINT16("physical_block_size", _state, \
_conf.physical_block_size, 512), \
- DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 512), \
- DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 512)
+ DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
+ DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0)
#endif /* BLOCK_INT_H */
diff --git a/blockdev.c b/blockdev.c
index 0a9dec364e..01e402bf3d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -590,6 +590,7 @@ int do_change_block(Monitor *mon, const char *device,
return -1;
}
bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
+ bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
qerror_report(QERR_OPEN_FILE_FAILED, filename);
return -1;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 56aed935c9..631673fc0f 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1643,6 +1643,21 @@ static void ide_atapi_cmd(IDEState *s)
ide_atapi_cmd_reply(s, len, max_len);
break;
}
+ case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
+ max_len = ube16_to_cpu(packet + 7);
+
+ if (packet[1] & 0x01) { /* polling */
+ /* We don't support any event class (yet). */
+ cpu_to_ube16(buf, 0x00); /* No event descriptor returned */
+ buf[2] = 0x80; /* No Event Available (NEA) */
+ buf[3] = 0x00; /* Empty supported event classes */
+ ide_atapi_cmd_reply(s, 4, max_len);
+ } else { /* asynchronous mode */
+ /* Only polling is supported, asynchronous mode is not. */
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ }
+ break;
default:
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_ILLEGAL_OPCODE);
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index f50069d20b..490cd41050 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -28,6 +28,7 @@ typedef struct VirtIOBlock
BlockConf *conf;
unsigned short sector_mask;
char sn[BLOCK_SERIAL_STRLEN];
+ DeviceState *qdev;
} VirtIOBlock;
static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -522,9 +523,16 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
+ s->qdev = dev;
register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
virtio_blk_save, virtio_blk_load, s);
bdrv_set_removable(s->bs, 0);
return &s->vdev;
}
+
+void virtio_blk_exit(VirtIODevice *vdev)
+{
+ VirtIOBlock *s = to_virtio_blk(vdev);
+ unregister_savevm(s->qdev, "virtio-blk", s);
+}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 31a711ef41..17c3d1539b 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -569,6 +569,7 @@ static int virtio_blk_exit_pci(PCIDevice *pci_dev)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+ virtio_blk_exit(proxy->vdev);
blockdev_mark_auto_del(proxy->block.bs);
return virtio_exit_pci(pci_dev);
}
diff --git a/hw/virtio.h b/hw/virtio.h
index e4306cd750..30e472aba7 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -194,6 +194,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
void virtio_net_exit(VirtIODevice *vdev);
+void virtio_blk_exit(VirtIODevice *vdev);
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
DEFINE_PROP_BIT("indirect_desc", _state, _field, \
diff --git a/qemu-options.hx b/qemu-options.hx
index 40cee704ea..db86feb09b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -118,7 +118,7 @@ ETEXI
DEF("drive", HAS_ARG, QEMU_OPTION_drive,
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
" [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
- " [,cache=writethrough|writeback|unsafe|none][,format=f]\n"
+ " [,cache=writethrough|writeback|none|unsafe][,format=f]\n"
" [,serial=s][,addr=A][,id=name][,aio=threads|native]\n"
" [,readonly=on|off]\n"
" use 'file' as a drive image\n", QEMU_ARCH_ALL)