Skip to contentSkip to conversation

Block patches

GIT PULL New Kevin Wolf 2 participants 19 messages Jul 6, 2010

Subsystems (2)
lore
Share & tools
lore

Kevin Wolf

author
#0 lore raw

The following changes since commit 734003e6153b3552b9406ef598a1e67aac4a899e:
Anthony Liguori (1):
Merge remote branch 'kwolf/for-anthony' into staging

are available in the git repository at:

git://repo.or.cz/qemu/kevin.git for-anthony

Kevin Wolf (2):
qemu-img check: Distinguish different kinds of errors qcow2/vdi: Change check to distinguish error cases

MORITA Kazutaka (1):
block: add sheepdog driver for distributed storage support

Markus Armbruster (13):
blockdev: Clean up how readonly persists across virtual media change block migration: Fix test for read-only drive
raw-posix: Fix test for host CD-ROM
fdc: Reject unimplemented error actions
qdev: Don't hw_error() in qdev_init_nofail()
scsi: Reject unimplemented error actions
error: New qemu_opts_loc_restore()
scsi: Error locations for -drive if=scsi device initialization
ide: Improve error messages
ide: Replace IDEState members is_cdrom, is_cf by drive_kind
ide: Make ide_init_drive() return success
ide: Reject readonly drives unless CD-ROM
ide: Reject invalid CHS geometry

john cooper (1):
Add virtio disk identification support

 Makefile.objs          |    2 +-
 block-migration.c      |    2 +-
 block.c                |    9 +-
 block.h                |   10 +-
 block/qcow2-refcount.c |  120 ++--
 block/qcow2.c          |    4 +-
 block/qcow2.h          |    2 +-
 block/raw-posix.c      |   17 +-
 block/sheepdog.c       | 2036 ++++++++++++++++++++++++++++++++++++++++++++++++
 block/vdi.c            |   10 +-
 block_int.h            |    7 +-
 blockdev.c             |    2 +-
 hw/fdc.c               |   22 +-
 hw/ide/core.c          |   70 ++-
 hw/ide/internal.h      |    9 +-
 hw/ide/macio.c         |    2 +-
 hw/ide/microdrive.c    |    2 +-
 hw/ide/qdev.c          |   13 +-
 hw/qdev.c              |    6 +-
 hw/scsi-bus.c          |    4 +
 hw/scsi-disk.c         |    5 +
 hw/scsi-generic.c      |    9 +
 hw/virtio-blk.c        |   14 +
 hw/virtio-blk.h        |    3 +
 qemu-img.c             |   63 ++-
 qemu-option.c          |    5 +
 qemu-option.h          |    1 +
 27 files changed, 2308 insertions(+), 141 deletions(-)
 create mode 100644 block/sheepdog.c
author
#1 lore raw

PATCH 1/17 qemu-img check: Distinguish different kinds of errors

People think that their images are corrupted when in fact there are just some leaked clusters. Differentiating several error cases should make the messages more comprehensible.

---
 block.c    |   10 ++++++--
 block.h    |   10 ++++++++-
 qemu-img.c |   63 +++++++++++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 64 insertions(+), 19 deletions(-)
block.c +7 -3
index dd6dd76..b0ceef0 100644
@@ -710,15 +710,19 @@ DeviceState *bdrv_get_attached(BlockDriverState *bs)
 /*
  * Run consistency checks on an image
  *
- * Returns the number of errors or -errno when an internal error occurs
+ * Returns 0 if the check could be completed (it doesn't mean that the image is
+ * free of errors) or -errno when an internal error occured. The results of the
+ * check are stored in res.
  */
-int bdrv_check(BlockDriverState *bs)
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
 {
     if (bs->drv->bdrv_check == NULL) {
         return -ENOTSUP;
     }
 
-    return bs->drv->bdrv_check(bs);
+    memset(res, 0, sizeof(*res));
+    res->corruptions = bs->drv->bdrv_check(bs);
+    return res->corruptions < 0 ? res->corruptions : 0;
 }
 
 /* commit COW file into the raw image */
block.h +9 -1
index 3d03b3e..c2a7e4c 100644
@@ -74,7 +74,6 @@ void bdrv_close(BlockDriverState *bs);
 int bdrv_attach(BlockDriverState *bs, DeviceState *qdev);
 void bdrv_detach(BlockDriverState *bs, DeviceState *qdev);
 DeviceState *bdrv_get_attached(BlockDriverState *bs);
-int bdrv_check(BlockDriverState *bs);
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors);
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
@@ -97,6 +96,15 @@ int bdrv_change_backing_file(BlockDriverState *bs,
     const char *backing_file, const char *backing_fmt);
 void bdrv_register(BlockDriver *bdrv);
 
+
+typedef struct BdrvCheckResult {
+    int corruptions;
+    int leaks;
+    int check_errors;
+} BdrvCheckResult;
+
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
+
 /* async block I/O */
 typedef struct BlockDriverAIOCB BlockDriverAIOCB;
 typedef void BlockDriverCompletionFunc(void *opaque, int ret);
qemu-img.c +48 -15

87 lines not on this page · raw message

Signature · 1 line
1.6.6.1
author
#2 lore raw

PATCH 2/17 qcow2/vdi: Change check to distinguish error cases

In reply to Kevin Wolf

This distinguishes between harmless leaks and real corruption. Hopefully users better understand what qemu-img check wants to tell them.

---
 block.c                |    3 +-
 block/qcow2-refcount.c |  120 ++++++++++++++++++++++++++----------------------
 block/qcow2.c          |    4 +-
 block/qcow2.h          |    2 +-
 block/vdi.c            |   10 ++--
 block_int.h            |    7 ++-
 6 files changed, 79 insertions(+), 67 deletions(-)
block.c +1 -2
index b0ceef0..65cf4dc 100644
@@ -721,8 +721,7 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
     }
 
     memset(res, 0, sizeof(*res));
-    res->corruptions = bs->drv->bdrv_check(bs);
-    return res->corruptions < 0 ? res->corruptions : 0;
+    return bs->drv->bdrv_check(bs, res);
 }
 
 /* commit COW file into the raw image */
block/qcow2-refcount.c +65 -55

315 lines not on this page · raw message

block/qcow2.c +2 -2
index 9ee34b6..a53014d 100644
@@ -1239,9 +1239,9 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 }
 
 
-static int qcow_check(BlockDriverState *bs)
+static int qcow_check(BlockDriverState *bs, BdrvCheckResult *result)
 {
-    return qcow2_check_refcounts(bs);
+    return qcow2_check_refcounts(bs, result);
 }
 
 #if 0
block/qcow2.h +1 -1
index c59b827..3ff162e 100644
@@ -185,7 +185,7 @@ void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
 int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     int64_t l1_table_offset, int l1_size, int addend);
 
-int qcow2_check_refcounts(BlockDriverState *bs);
+int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
 
 /* qcow2-cluster.c functions */
 int qcow2_grow_l1_table(BlockDriverState *bs, int min_size);
block/vdi.c +5 -5
index ee8cc7b..f72633c 100644
@@ -291,11 +291,10 @@ static void vdi_header_print(VdiHeader *header)
 }
 #endif
 
-static int vdi_check(BlockDriverState *bs)
+static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
 {
     /* TODO: additional checks possible. */
     BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
-    int n_errors = 0;
     uint32_t blocks_allocated = 0;
     uint32_t block;
     uint32_t *bmap;
@@ -315,11 +314,12 @@ static int vdi_check(BlockDriverState *bs)
                 } else {
                     fprintf(stderr, "ERROR: block index %" PRIu32
                             " also used by %" PRIu32 "\n", bmap[bmap_entry], bmap_entry);
+                    res->corruptions++;
                 }
             } else {
                 fprintf(stderr, "ERROR: block index %" PRIu32
                         " too large, is %" PRIu32 "\n", block, bmap_entry);
-                n_errors++;
+                res->corruptions++;
             }
         }
     }
@@ -327,12 +327,12 @@ static int vdi_check(BlockDriverState *bs)
         fprintf(stderr, "ERROR: allocated blocks mismatch, is %" PRIu32
                ", should be %" PRIu32 "\n",
                blocks_allocated, s->header.blocks_allocated);
-        n_errors++;
+        res->corruptions++;
     }
 
     qemu_free(bmap);
 
-    return n_errors;
+    return 0;
 }
 
 static int vdi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
block_int.h +5 -2
index a94b801..877e1e5 100644
@@ -119,8 +119,11 @@ struct BlockDriver {
     QEMUOptionParameter *create_options;
 
 
-    /* Returns number of errors in image, -errno for internal errors */
-    int (*bdrv_check)(BlockDriverState* bs);
+    /*
+     * Returns 0 for completed check, -errno for internal errors.
+     * The check results are stored in result.
+     */
+    int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result);
 
     void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
 
Signature · 1 line
1.6.6.1
author
#3 lore raw

PATCH 3/17 Add virtio disk identification support

In reply to Kevin Wolf

From: john cooper <[email protected]>

This patch adds the final missing bits for support of passing a serial/id string to a virtio-blk guest driver.

The guest-side component already exists in the virtio driver, and has recently been reworked by Ryan to export a /sys interface for retrieval of the id from guest userland.

---
 hw/virtio-blk.c |   14 ++++++++++++++
 hw/virtio-blk.h |    3 +++
 2 files changed, 17 insertions(+), 0 deletions(-)
hw/virtio-blk.c +14 -0
index f0b3ba5..0bd57b5 100644
@@ -26,6 +26,7 @@ typedef struct VirtIOBlock
     QEMUBH *bh;
     BlockConf *conf;
     unsigned short sector_mask;
+    char sn[BLOCK_SERIAL_STRLEN];
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -324,6 +325,12 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
         virtio_blk_handle_flush(req, mrb);
     } else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
         virtio_blk_handle_scsi(req);
+    } else if (req->out->type & VIRTIO_BLK_T_GET_ID) {
+        VirtIOBlock *s = req->dev;
+
+        memcpy(req->elem.in_sg[0].iov_base, s->sn,
+               MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
+        virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
     } else if (req->out->type & VIRTIO_BLK_T_OUT) {
         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
                                  req->elem.out_num - 1);
@@ -481,6 +488,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
     VirtIOBlock *s;
     int cylinders, heads, secs;
     static int virtio_blk_id;
+    DriveInfo *dinfo;
 
     s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                           sizeof(struct virtio_blk_config),
@@ -495,6 +503,12 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
     s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
 
+    /* NB: per existing s/n string convention the string is terminated
+     * by '\0' only when less than sizeof (s->sn)
+     */
+    dinfo = drive_get_by_blockdev(s->bs);
+    strncpy(s->sn, dinfo->serial, sizeof (s->sn));
+
     s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
 
     qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
hw/virtio-blk.h +3 -0
index 7a7ece3..fff46da 100644
@@ -59,6 +59,9 @@ struct virtio_blk_config
 /* Flush the volatile write cache */
 #define VIRTIO_BLK_T_FLUSH      4
 
+/* return the device ID string */
+#define VIRTIO_BLK_T_GET_ID     8
+
 /* Barrier before this op. */
 #define VIRTIO_BLK_T_BARRIER    0x80000000
 
Signature · 1 line
1.6.6.1
author
#4 lore raw

PATCH 4/17 blockdev: Clean up how readonly persists across virtual media change

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

Since commit cb4e5f8e, monitor command change makes the new media readonly iff the type hint is BDRV_TYPE_CDROM, i.e. the drive was created with media=cdrom. The intention is to avoid changing a block device's read-only-ness. However, BDRV_TYPE_CDROM is only a hint. It is currently sufficent for read-only. But it's not necessary, and it may not remain sufficient.

Use bdrv_is_read_only() instead.

---
 blockdev.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
blockdev.c +1 -1
index be88098..0a9dec3 100644
@@ -589,7 +589,7 @@ int do_change_block(Monitor *mon, const char *device,
     if (eject_device(mon, bs, 0) < 0) {
         return -1;
     }
-    bdrv_flags = bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM ? 0 : BDRV_O_RDWR;
+    bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
     if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
         qerror_report(QERR_OPEN_FILE_FAILED, filename);
         return -1;
Signature · 1 line
1.6.6.1
author
#5 lore raw

PATCH 5/17 block migration: Fix test for read-only drive

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

init_blk_migration_it() skips drives with type hint BDRV_TYPE_CDROM. The intention is to skip read-only drives. However, BDRV_TYPE_CDROM is only a hint. It is currently sufficent for read-only. But it's not necessary, and it may not remain sufficient.

Use bdrv_is_read_only() instead.

---
 block-migration.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
block-migration.c +1 -1
index 7d04d6d..7337349 100644
@@ -236,7 +236,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
     BlkMigDevState *bmds;
     int64_t sectors;
 
-    if (bs->type == BDRV_TYPE_HD) {
+    if (!bdrv_is_read_only(bs)) {
         sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
         if (sectors == 0) {
             return;
Signature · 1 line
1.6.6.1
author
#6 lore raw

PATCH 6/17 raw-posix: Fix test for host CD-ROM

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

raw_pread_aligned() retries up to two times if the block device backs a virtual CD-ROM (a drive with media=cdrom and if=ide, scsi, xen or none). This makes no sense. Whether retrying reads can correct read errors can only depend on what we're reading, not on how the result gets used. We need to check what whether we're reading from a physical CD-ROM or floppy here.

I doubt retrying is useful even then. Left for another day.

Impact:

* Virtual CD-ROM backed by host_cdrom behaves the same.

* Virtual CD-ROM backed by file or host_device no longer retries.

* A drive backed by host_cdrom now retries even if it's not a virtual CD-ROM.

* Any drive backed by host_floppy now retries.

While there, clean up gratuitous use of goto.

---
 block/raw-posix.c |   17 ++++++-----------
 1 files changed, 6 insertions(+), 11 deletions(-)
block/raw-posix.c +6 -11
index 3f0701b..291699f 100644
@@ -242,15 +242,14 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
 
     ret = pread(s->fd, buf, count, offset);
     if (ret == count)
-        goto label__raw_read__success;
+        return ret;
 
     /* Allow reads beyond the end (needed for pwrite) */
     if ((ret == 0) && bs->growable) {
         int64_t size = raw_getlength(bs);
         if (offset >= size) {
             memset(buf, 0, count);
-            ret = count;
-            goto label__raw_read__success;
+            return count;
         }
     }
 
@@ -260,13 +259,13 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
                       bs->total_sectors, ret, errno, strerror(errno));
 
     /* Try harder for CDrom. */
-    if (bs->type == BDRV_TYPE_CDROM) {
+    if (s->type != FTYPE_FILE) {
         ret = pread(s->fd, buf, count, offset);
         if (ret == count)
-            goto label__raw_read__success;
+            return ret;
         ret = pread(s->fd, buf, count, offset);
         if (ret == count)
-            goto label__raw_read__success;
+            return ret;
 
         DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                           "] retry read failed %d : %d = %s\n",
@@ -274,8 +273,6 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
                           bs->total_sectors, ret, errno, strerror(errno));
     }
 
-label__raw_read__success:
-
     return  (ret < 0) ? -errno : ret;
 }
 
@@ -298,15 +295,13 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
 
     ret = pwrite(s->fd, buf, count, offset);
     if (ret == count)
-        goto label__raw_write__success;
+        return ret;
 
     DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                       "] write failed %d : %d = %s\n",
                       s->fd, bs->filename, offset, buf, count,
                       bs->total_sectors, ret, errno, strerror(errno));
 
-label__raw_write__success:
-
     return  (ret < 0) ? -errno : ret;
 }
 
Signature · 1 line
1.6.6.1
author
#7 lore raw

PATCH 7/17 fdc: Reject unimplemented error actions

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

drive_init() doesn't permit them for if=floppy, but that's worthless:
we get them via if=none and -global.

This can make device initialization fail. Since all callers of fdctrl_init_isa() ignore its value, change it to die instead of returning failure. Without this, some callers would ignore the failure, and others would crash.

Wart: unlike drive_init(), we don't reject the default action when it's explicitly specified. That's because we can't distinguish "no rerror option" from "rerror=report", or "no werror" from "rerror=enospc". Left for another day.

---
 hw/fdc.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)
hw/fdc.c +16 -6
index 6c74878..2d50bd6 100644
@@ -29,6 +29,7 @@
 
 #include "hw.h"
 #include "fdc.h"
+#include "qemu-error.h"
 #include "qemu-timer.h"
 #include "isa.h"
 #include "sysbus.h"
@@ -1844,7 +1845,7 @@ static void fdctrl_result_timer(void *opaque)
 }
 
 /* Init functions */
-static void fdctrl_connect_drives(FDCtrl *fdctrl)
+static int fdctrl_connect_drives(FDCtrl *fdctrl)
 {
     unsigned int i;
     FDrive *drive;
@@ -1852,12 +1853,24 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl)
     for (i = 0; i < MAX_FD; i++) {
         drive = &fdctrl->drives[i];
 
+        if (drive->bs) {
+            if (bdrv_get_on_error(drive->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
+                error_report("fdc doesn't support drive option werror");
+                return -1;
+            }
+            if (bdrv_get_on_error(drive->bs, 1) != BLOCK_ERR_REPORT) {
+                error_report("fdc doesn't support drive option rerror");
+                return -1;
+            }
+        }
+
         fd_init(drive);
         fd_revalidate(drive);
         if (drive->bs) {
             bdrv_set_removable(drive->bs, 1);
         }
     }
+    return 0;
 }
 
 FDCtrl *fdctrl_init_isa(DriveInfo **fds)
@@ -1871,8 +1884,7 @@ FDCtrl *fdctrl_init_isa(DriveInfo **fds)
     if (fds[1]) {
         qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
     }
-    if (qdev_init(&dev->qdev) < 0)
-        return NULL;
+    qdev_init_nofail(&dev->qdev);
     return &(DO_UPCAST(FDCtrlISABus, busdev, dev)->state);
 }
 
@@ -1950,9 +1962,7 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
 
     if (fdctrl->dma_chann != -1)
         DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
-    fdctrl_connect_drives(fdctrl);
-
-    return 0;
+    return fdctrl_connect_drives(fdctrl);
 }
 
 static int isabus_fdc_init1(ISADevice *dev)
Signature · 1 line
1.6.6.1
author
#8 lore raw

PATCH 8/17 qdev: Don't hw_error() in qdev_init_nofail()

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

Some of the failures are internal errors, and hw_error() is okay then. But the common way to fail is bad user input, e.g. -global isa-fdc.driveA=foo where drive foo has an unsupported rerror value.

exit(1) instead.

---
 hw/qdev.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
hw/qdev.c +4 -2
index 61f999c..00ceada 100644
@@ -326,8 +326,10 @@ void qdev_init_nofail(DeviceState *dev)
 {
     DeviceInfo *info = dev->info;
 
-    if (qdev_init(dev) < 0)
-        hw_error("Initialization of device %s failed\n", info->name);
+    if (qdev_init(dev) < 0) {
+        error_report("Initialization of device %s failed\n", info->name);
+        exit(1);
+    }
 }
 
 /* Unlink device from bus and free the structure.  */
Signature · 1 line
1.6.6.1
author
#9 lore raw

PATCH 9/17 scsi: Reject unimplemented error actions

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

drive_init() doesn't permit rerror for if=scsi, but that's worthless:
we get it via if=none and -device.

Moreover, scsi-generic doesn't support werror. Since drive_init() doesn't catch that, option werror was silently ignored even with if=scsi.

Wart: unlike drive_init(), we don't reject the default action when it's explicitly specified. That's because we can't distinguish "no rerror option" from "rerror=report", or "no werror" from "rerror=enospc". Left for another day.

---
 hw/scsi-disk.c    |    5 +++++
 hw/scsi-generic.c |    9 +++++++++
 2 files changed, 14 insertions(+), 0 deletions(-)
hw/scsi-disk.c +5 -0
index 3e41011..c30709c 100644
@@ -1059,6 +1059,11 @@ static int scsi_disk_initfn(SCSIDevice *dev)
     s->bs = s->qdev.conf.bs;
     is_cd = bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM;
 
+    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
+        error_report("Device doesn't support drive option rerror");
+        return -1;
+    }
+
     if (!s->serial) {
         /* try to fall back to value set with legacy -drive serial=... */
         dinfo = drive_get_by_blockdev(s->bs);
hw/scsi-generic.c +9 -0
index 3915e78..a8b4176 100644
@@ -474,6 +474,15 @@ static int scsi_generic_initfn(SCSIDevice *dev)
         return -1;
     }
 
+    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
+        error_report("Device doesn't support drive option werror");
+        return -1;
+    }
+    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
+        error_report("Device doesn't support drive option rerror");
+        return -1;
+    }
+
     /* check we are using a driver managing SG_IO (version 3 and after */
     if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
         sg_version < 30000) {
Signature · 1 line
1.6.6.1
author
#10 lore raw

PATCH 10/17 error: New qemu_opts_loc_restore()

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

Needed for decent error locations when complaining about options outside of qemu_opts_foreach(). That one sets the location already.

---
 qemu-option.c |    5 +++++
 qemu-option.h |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)
qemu-option.c +5 -0
index 30327d4..1f8f41a 100644
@@ -728,6 +728,11 @@ void qemu_opts_reset(QemuOptsList *list)
     }
 }
 
+void qemu_opts_loc_restore(QemuOpts *opts)
+{
+    loc_restore(&opts->loc);
+}
+
 int qemu_opts_set(QemuOptsList *list, const char *id,
                   const char *name, const char *value)
 {
qemu-option.h +1 -0
index 9e2406c..b515813 100644
@@ -116,6 +116,7 @@ int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists);
 void qemu_opts_reset(QemuOptsList *list);
+void qemu_opts_loc_restore(QemuOpts *opts);
 int qemu_opts_set(QemuOptsList *list, const char *id,
                   const char *name, const char *value);
 const char *qemu_opts_id(QemuOpts *opts);
Signature · 1 line
1.6.6.1
author
#11 lore raw

PATCH 11/17 scsi: Error locations for -drive if=scsi device initialization

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

---
 hw/scsi-bus.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
hw/scsi-bus.c +4 -0
index b84b9b9..d69c74c 100644
@@ -102,19 +102,23 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int
 
 int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
 {
+    Location loc;
     DriveInfo *dinfo;
     int res = 0, unit;
 
+    loc_push_none(&loc);
     for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
         dinfo = drive_get(IF_SCSI, bus->busnr, unit);
         if (dinfo == NULL) {
             continue;
         }
+        qemu_opts_loc_restore(dinfo->opts);
         if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit)) {
             res = -1;
             break;
         }
     }
+    loc_pop(&loc);
     return res;
 }
 
Signature · 1 line
1.6.6.1
author
#12 lore raw

PATCH 12/17 ide: Improve error messages

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

Use error_report(), because it points to the error location.

Reword "tried to assign twice" messages to make it clear that we're complaining about the unit property.

Report invalid unit property instead of failing silently.

---
 hw/ide/qdev.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)
hw/ide/qdev.c +5 -4
index 2977a16..221f387 100644
@@ -18,7 +18,7 @@
  */
 #include <hw/hw.h>
 #include "dma.h"
-
+#include "qemu-error.h"
 #include <hw/ide/internal.h>
 
 /* --------------------------------- */
@@ -40,7 +40,7 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
 
     if (!dev->conf.bs) {
-        fprintf(stderr, "%s: no drive specified\n", qdev->info->name);
+        error_report("No drive specified");
         goto err;
     }
     if (dev->unit == -1) {
@@ -49,19 +49,20 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
     switch (dev->unit) {
     case 0:
         if (bus->master) {
-            fprintf(stderr, "ide: tried to assign master twice\n");
+            error_report("IDE unit %d is in use", dev->unit);
             goto err;
         }
         bus->master = dev;
         break;
     case 1:
         if (bus->slave) {
-            fprintf(stderr, "ide: tried to assign slave twice\n");
+            error_report("IDE unit %d is in use", dev->unit);
             goto err;
         }
         bus->slave = dev;
         break;
     default:
+        error_report("Invalid IDE unit %d", dev->unit);
         goto err;
     }
     return info->init(dev);
Signature · 1 line
1.6.6.1
author
#13 lore raw

PATCH 13/17 ide: Replace IDEState members is_cdrom, is_cf by drive_kind

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

The two aren't independent variables. Make that obvious.

---
 hw/ide/core.c       |   40 ++++++++++++++++++++--------------------
 hw/ide/internal.h   |    5 +++--
 hw/ide/macio.c      |    2 +-
 hw/ide/microdrive.c |    2 +-
 4 files changed, 25 insertions(+), 24 deletions(-)
hw/ide/core.c +20 -20
index ebdceb5..58b88ee 100644
@@ -292,7 +292,7 @@ static void ide_set_signature(IDEState *s)
     /* put signature */
     s->nsector = 1;
     s->sector = 1;
-    if (s->is_cdrom) {
+    if (s->drive_kind == IDE_CD) {
         s->lcyl = 0x14;
         s->hcyl = 0xeb;
     } else if (s->bs) {
@@ -1827,15 +1827,15 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 
         switch(val) {
         case WIN_IDENTIFY:
-            if (s->bs && !s->is_cdrom) {
-                if (!s->is_cf)
+            if (s->bs && s->drive_kind != IDE_CD) {
+                if (s->drive_kind != IDE_CFATA)
                     ide_identify(s);
                 else
                     ide_cfata_identify(s);
                 s->status = READY_STAT | SEEK_STAT;
                 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
             } else {
-                if (s->is_cdrom) {
+                if (s->drive_kind == IDE_CD) {
                     ide_set_signature(s);
                 }
                 ide_abort_command(s);
@@ -1849,7 +1849,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             ide_set_irq(s->bus);
             break;
         case WIN_SETMULT:
-            if (s->is_cf && s->nsector == 0) {
+            if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
                 /* Disable Read and Write Multiple */
                 s->mult_sectors = 0;
                 s->status = READY_STAT | SEEK_STAT;
@@ -2033,7 +2033,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             ide_set_irq(s->bus);
             break;
         case WIN_SEEK:
-            if(s->is_cdrom)
+            if(s->drive_kind == IDE_CD)
                 goto abort_cmd;
             /* XXX: Check that seek is within bounds */
             s->status = READY_STAT | SEEK_STAT;
@@ -2041,7 +2041,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
             /* ATAPI commands */
         case WIN_PIDENTIFY:
-            if (s->is_cdrom) {
+            if (s->drive_kind == IDE_CD) {
                 ide_atapi_identify(s);
                 s->status = READY_STAT | SEEK_STAT;
                 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
@@ -2052,7 +2052,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         case WIN_DIAGNOSE:
             ide_set_signature(s);
-            if (s->is_cdrom)
+            if (s->drive_kind == IDE_CD)
                 s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
                                 * devices to return a clear status register
                                 * with READY_STAT *not* set. */
@@ -2064,14 +2064,14 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             ide_set_irq(s->bus);
             break;
         case WIN_SRST:
-            if (!s->is_cdrom)
+            if (s->drive_kind != IDE_CD)
                 goto abort_cmd;
             ide_set_signature(s);
             s->status = 0x00; /* NOTE: READY is _not_ set */
             s->error = 0x01;
             break;
         case WIN_PACKETCMD:
-            if (!s->is_cdrom)
+            if (s->drive_kind != IDE_CD)
                 goto abort_cmd;
             /* overlapping commands not supported */
             if (s->feature & 0x02)
@@ -2084,7 +2084,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         /* CF-ATA commands */
         case CFA_REQ_EXT_ERROR_CODE:
-            if (!s->is_cf)
+            if (s->drive_kind != IDE_CFATA)
                 goto abort_cmd;
             s->error = 0x09;    /* miscellaneous error */
             s->status = READY_STAT | SEEK_STAT;
@@ -2092,7 +2092,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         case CFA_ERASE_SECTORS:
         case CFA_WEAR_LEVEL:
-            if (!s->is_cf)
+            if (s->drive_kind != IDE_CFATA)
                 goto abort_cmd;
             if (val == CFA_WEAR_LEVEL)
                 s->nsector = 0;
@@ -2103,7 +2103,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             ide_set_irq(s->bus);
             break;
         case CFA_TRANSLATE_SECTOR:
-            if (!s->is_cf)
+            if (s->drive_kind != IDE_CFATA)
                 goto abort_cmd;
             s->error = 0x00;
             s->status = READY_STAT | SEEK_STAT;
@@ -2123,7 +2123,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             ide_set_irq(s->bus);
             break;
         case CFA_ACCESS_METADATA_STORAGE:
-            if (!s->is_cf)
+            if (s->drive_kind != IDE_CFATA)
                 goto abort_cmd;
             switch (s->feature) {
             case 0x02:	/* Inquiry Metadata Storage */
@@ -2143,7 +2143,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             ide_set_irq(s->bus);
             break;
         case IBM_SENSE_CONDITION:
-            if (!s->is_cf)
+            if (s->drive_kind != IDE_CFATA)
                 goto abort_cmd;
             switch (s->feature) {
             case 0x01:  /* sense temperature in device */
@@ -2157,7 +2157,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
 
 	case WIN_SMART:
-	    if (s->is_cdrom)
+	    if (s->drive_kind == IDE_CD)
 		goto abort_cmd;
 	    if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
 		goto abort_cmd;
@@ -2438,7 +2438,7 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
         /* high to low */
         for(i = 0;i < 2; i++) {
             s = &bus->ifs[i];
-            if (s->is_cdrom)
+            if (s->drive_kind == IDE_CD)
                 s->status = 0x00; /* NOTE: READY is _not_ set */
             else
                 s->status = READY_STAT | SEEK_STAT;
@@ -2540,7 +2540,7 @@ static void ide_reset(IDEState *s)
 #ifdef DEBUG_IDE
     printf("ide: reset\n");
 #endif
-    if (s->is_cf)
+    if (s->drive_kind == IDE_CFATA)
         s->mult_sectors = 0;
     else
         s->mult_sectors = MAX_MULT_SECTORS;
@@ -2614,7 +2614,7 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
     s->smart_errors = 0;
     s->smart_selftest_count = 0;
     if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
-        s->is_cdrom = 1;
+        s->drive_kind = IDE_CD;
         bdrv_set_change_cb(bs, cdrom_change_cb, s);
     }
     if (serial) {
@@ -2629,7 +2629,7 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
         pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);
     }
     ide_reset(s);
-    bdrv_set_removable(bs, s->is_cdrom);
+    bdrv_set_removable(bs, s->drive_kind == IDE_CD);
 }
 
 static void ide_init1(IDEBus *bus, int unit)
hw/ide/internal.h +3 -2
index 0125a9f..bd53660 100644
@@ -362,6 +362,8 @@ typedef struct BMDMAState BMDMAState;
 #define SMART_DISABLE         0xd9
 #define SMART_STATUS          0xda
 
+typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind;
+
 typedef void EndTransferFunc(IDEState *);
 
 /* NOTE: IDEState represents in fact one drive */
@@ -369,8 +371,7 @@ struct IDEState {
     IDEBus *bus;
     uint8_t unit;
     /* ide config */
-    int is_cdrom;
-    int is_cf;
+    IDEDriveKind drive_kind;
     int cylinders, heads, sectors;
     int64_t nb_sectors;
     int mult_sectors;
hw/ide/macio.c +1 -1
index f76c0fa..539c067 100644
@@ -162,7 +162,7 @@ static void pmac_ide_transfer(DBDMA_io *io)
     IDEState *s = idebus_active_if(&m->bus);
 
     s->io_buffer_size = 0;
-    if (s->is_cdrom) {
+    if (s->drive_kind == IDE_CD) {
         pmac_ide_atapi_transfer_cb(io, 0);
         return;
     }
hw/ide/microdrive.c +1 -1
index a7beac5..47c3c8c 100644
@@ -541,7 +541,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
 
     ide_init2_with_non_qdev_drives(&md->bus, bdrv, NULL,
                                    qemu_allocate_irqs(md_set_irq, md, 1)[0]);
-    md->bus.ifs[0].is_cf = 1;
+    md->bus.ifs[0].drive_kind = IDE_CFATA;
     md->bus.ifs[0].mdata_size = METADATA_SIZE;
     md->bus.ifs[0].mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE);
 
Signature · 1 line
1.6.6.1
author
#14 lore raw

PATCH 14/17 ide: Make ide_init_drive() return success

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

It still always succeeds. The next commits will add failures.

---
 hw/ide/core.c     |   13 +++++++++----
 hw/ide/internal.h |    4 ++--
 hw/ide/qdev.c     |    4 +++-
 3 files changed, 14 insertions(+), 7 deletions(-)
hw/ide/core.c +9 -4
index 58b88ee..dbb7acc 100644
@@ -26,6 +26,7 @@
 #include <hw/pc.h>
 #include <hw/pci.h>
 #include <hw/scsi.h>
+#include "qemu-error.h"
 #include "qemu-timer.h"
 #include "sysemu.h"
 #include "dma.h"
@@ -2594,8 +2595,8 @@ void ide_bus_reset(IDEBus *bus)
     ide_clear_hob(bus);
 }
 
-void ide_init_drive(IDEState *s, BlockDriverState *bs,
-                    const char *version, const char *serial)
+int ide_init_drive(IDEState *s, BlockDriverState *bs,
+                   const char *version, const char *serial)
 {
     int cylinders, heads, secs;
     uint64_t nb_sectors;
@@ -2630,6 +2631,7 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
     }
     ide_reset(s);
     bdrv_set_removable(bs, s->drive_kind == IDE_CD);
+    return 0;
 }
 
 static void ide_init1(IDEBus *bus, int unit)
@@ -2669,8 +2671,11 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
         dinfo = i == 0 ? hd0 : hd1;
         ide_init1(bus, i);
         if (dinfo) {
-            ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL,
-                           *dinfo->serial ? dinfo->serial : NULL);
+            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL,
+                               *dinfo->serial ? dinfo->serial : NULL) < 0) {
+                error_report("Can't set up IDE drive %s", dinfo->id);
+                exit(1);
+            }
         } else {
             ide_reset(&bus->ifs[i]);
         }
hw/ide/internal.h +2 -2
index bd53660..4165543 100644
@@ -556,8 +556,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
 void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
-void ide_init_drive(IDEState *s, BlockDriverState *bs,
-                    const char *version, const char *serial);
+int ide_init_drive(IDEState *s, BlockDriverState *bs,
+                   const char *version, const char *serial);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
                                     DriveInfo *hd1, qemu_irq irq);
hw/ide/qdev.c +3 -1
index 221f387..53468ed 100644
@@ -118,7 +118,9 @@ static int ide_drive_initfn(IDEDevice *dev)
         }
     }
 
-    ide_init_drive(s, dev->conf.bs, dev->version, serial);
+    if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) {
+        return -1;
+    }
 
     if (!dev->version) {
         dev->version = qemu_strdup(s->version);
Signature · 1 line
1.6.6.1
author
#15 lore raw

PATCH 15/17 ide: Reject readonly drives unless CD-ROM

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

drive_init() doesn't permit option readonly for if=ide, but that's
worthless: we get it via if=none and -device.

---
 hw/ide/core.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
hw/ide/core.c +5 -0
index dbb7acc..3b84bea 100644
@@ -2617,6 +2617,11 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs,
     if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
         s->drive_kind = IDE_CD;
         bdrv_set_change_cb(bs, cdrom_change_cb, s);
+    } else {
+        if (bdrv_is_read_only(bs)) {
+            error_report("Can't use a read-only drive");
+            return -1;
+        }
     }
     if (serial) {
         strncpy(s->drive_serial_str, serial, sizeof(s->drive_serial_str));
Signature · 1 line
1.6.6.1
author
#16 lore raw

PATCH 16/17 ide: Reject invalid CHS geometry

In reply to Kevin Wolf

From: Markus Armbruster <[email protected]>

drive_init() doesn't permit invalid CHS for if=ide, but that's
worthless: we get it via if=none and -device.

---
 hw/ide/core.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)
hw/ide/core.c +12 -0
index 3b84bea..af52c2c 100644
@@ -2604,6 +2604,18 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs,
     s->bs = bs;
     bdrv_get_geometry(bs, &nb_sectors);
     bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
+    if (cylinders < 1 || cylinders > 16383) {
+        error_report("cyls must be between 1 and 16383");
+        return -1;
+    }
+    if (heads < 1 || heads > 16) {
+        error_report("heads must be between 1 and 16");
+        return -1;
+    }
+    if (secs < 1 || secs > 63) {
+        error_report("secs must be between 1 and 63");
+        return -1;
+    }
     s->cylinders = cylinders;
     s->heads = heads;
     s->sectors = secs;
Signature · 1 line
1.6.6.1
author
#17 lore raw

PATCH 17/17 block: add sheepdog driver for distributed storage support

In reply to Kevin Wolf

From: MORITA Kazutaka <[email protected]>

Sheepdog is a distributed storage system for QEMU. It provides highly available block level storage volumes to VMs like Amazon EBS. This patch adds a qemu block driver for Sheepdog.

Sheepdog features are:
- No node in the cluster is special (no metadata node, no control node, etc)
- Linear scalability in performance and capacity
- No single point of failure
- Autonomous management (zero configuration)
- Useful volume management support such as snapshot and cloning
- Thin provisioning
- Autonomous load balancing

The more details are available at the project site:
http://www.osrg.net/sheepdog/

---
 Makefile.objs    |    2 +-
 block/sheepdog.c | 2036 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2037 insertions(+), 1 deletions(-)
 create mode 100644 block/sheepdog.c
Makefile.objs +1 -1
index 55417c9..67f1b21 100644
@@ -14,7 +14,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
 block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
 block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
-block-nested-y += parallels.o nbd.o blkdebug.o
+block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o
 block-nested-$(CONFIG_WIN32) += raw-win32.o
 block-nested-$(CONFIG_POSIX) += raw-posix.o
 block-nested-$(CONFIG_CURL) += curl.o
block/sheepdog.c new file +2036 -0

2,036 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#18 lore raw
In reply to Kevin Wolf
Quoted 4 lines · Kevin Wolf

The following changes since commit 734003e6153b3552b9406ef598a1e67aac4a899e:
Anthony Liguori (1):
Merge remote branch 'kwolf/for-anthony' into staging

Pulled. Thanks.

Regards,

Anthony Liguori

Quoted 61 lines

are available in the git repository at:

git://repo.or.cz/qemu/kevin.git for-anthony

Kevin Wolf (2):
qemu-img check: Distinguish different kinds of errors qcow2/vdi: Change check to distinguish error cases

MORITA Kazutaka (1):
block: add sheepdog driver for distributed storage support

Markus Armbruster (13):
blockdev: Clean up how readonly persists across virtual media change block migration: Fix test for read-only drive
raw-posix: Fix test for host CD-ROM
fdc: Reject unimplemented error actions
qdev: Don't hw_error() in qdev_init_nofail()
scsi: Reject unimplemented error actions
error: New qemu_opts_loc_restore()
scsi: Error locations for -drive if=scsi device initialization
ide: Improve error messages
ide: Replace IDEState members is_cdrom, is_cf by drive_kind
ide: Make ide_init_drive() return success
ide: Reject readonly drives unless CD-ROM
ide: Reject invalid CHS geometry

john cooper (1):
Add virtio disk identification support

  Makefile.objs          |    2 +-
  block-migration.c      |    2 +-
  block.c                |    9 +-
  block.h                |   10 +-
  block/qcow2-refcount.c |  120 ++--
  block/qcow2.c          |    4 +-
  block/qcow2.h          |    2 +-
  block/raw-posix.c      |   17 +-
  block/sheepdog.c       | 2036 ++++++++++++++++++++++++++++++++++++++++++++++++
  block/vdi.c            |   10 +-
  block_int.h            |    7 +-
  blockdev.c             |    2 +-
  hw/fdc.c               |   22 +-
  hw/ide/core.c          |   70 ++-
  hw/ide/internal.h      |    9 +-
  hw/ide/macio.c         |    2 +-
  hw/ide/microdrive.c    |    2 +-
  hw/ide/qdev.c          |   13 +-
  hw/qdev.c              |    6 +-
  hw/scsi-bus.c          |    4 +
  hw/scsi-disk.c         |    5 +
  hw/scsi-generic.c      |    9 +
  hw/virtio-blk.c        |   14 +
  hw/virtio-blk.h        |    3 +
  qemu-img.c             |   63 ++-
  qemu-option.c          |    5 +
  qemu-option.h          |    1 +
  27 files changed, 2308 insertions(+), 141 deletions(-)

create mode 100644 block/sheepdog.c