Example #1
0
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
    int is_read)
{
    BlockErrorAction action = bdrv_get_on_error(req->dev->bs, is_read);
    VirtIOBlock *s = req->dev;

    if (action == BLOCK_ERR_IGNORE) {
        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
        return 0;
    }

    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
            || action == BLOCK_ERR_STOP_ANY) {
        req->next = s->rq;
        s->rq = req;
        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);
        vm_stop(RUN_STATE_IO_ERROR);
        bdrv_iostatus_set_err(s->bs, error);
    } else {
        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
        bdrv_acct_done(s->bs, &req->acct);
        g_free(req);
        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_REPORT, is_read);
    }

    return 1;
}
Example #2
0
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
    int is_read)
{
    BlockErrorAction action = bdrv_get_on_error(req->dev->bs, is_read);
    VirtIOBlock *s = req->dev;

    if (action == BLOCK_ERR_IGNORE) {
        bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
        return 0;
    }

    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
            || action == BLOCK_ERR_STOP_ANY) {
        req->next = s->rq;
        s->rq = req;
        bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
        vm_stop(0);
    } else {
        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
    }

    return 1;
}
Example #3
0
static int scsi_generic_initfn(SCSIDevice *s)
{
    int sg_version;
    struct sg_scsi_id scsiid;

    if (!s->conf.bs) {
        error_report("drive property not set");
        return -1;
    }

    /* check we are really using a /dev/sg* file */
    if (!bdrv_is_sg(s->conf.bs)) {
        error_report("not /dev/sg*");
        return -1;
    }

    if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
        error_report("Device doesn't support drive option werror");
        return -1;
    }
    if (bdrv_get_on_error(s->conf.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->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
        sg_version < 30000) {
        error_report("scsi generic interface too old");
        return -1;
    }

    /* get LUN of the /dev/sg? */
    if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
        error_report("SG_GET_SCSI_ID ioctl failed");
        return -1;
    }

    /* define device state */
    s->type = scsiid.scsi_type;
    DPRINTF("device type %d\n", s->type);
    if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
        add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
    }

    switch (s->type) {
    case TYPE_TAPE:
        s->blocksize = get_stream_blocksize(s->conf.bs);
        if (s->blocksize == -1) {
            s->blocksize = 0;
        }
        break;

        /* Make a guess for block devices, we'll fix it when the guest sends.
         * READ CAPACITY.  If they don't, they likely would assume these sizes
         * anyway. (TODO: they could also send MODE SENSE).
         */
    case TYPE_ROM:
    case TYPE_WORM:
        s->blocksize = 2048;
        break;
    default:
        s->blocksize = 512;
        break;
    }

    DPRINTF("block size %d\n", s->blocksize);
    return 0;
}
Example #4
0
static int scsi_generic_initfn(SCSIDevice *dev)
{
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
    int sg_version;
    struct sg_scsi_id scsiid;

    if (!s->qdev.conf.bs) {
        error_report("scsi-generic: drive property not set");
        return -1;
    }
    s->bs = s->qdev.conf.bs;

    /* check we are really using a /dev/sg* file */
    if (!bdrv_is_sg(s->bs)) {
        error_report("scsi-generic: not /dev/sg*");
        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) {
        error_report("scsi-generic: scsi generic interface too old");
        return -1;
    }

    /* get LUN of the /dev/sg? */
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
        return -1;
    }

    /* define device state */
    s->lun = scsiid.lun;
    DPRINTF("LUN %d\n", s->lun);
    s->qdev.type = scsiid.scsi_type;
    DPRINTF("device type %d\n", s->qdev.type);
    if (s->qdev.type == TYPE_TAPE) {
        s->qdev.blocksize = get_stream_blocksize(s->bs);
        if (s->qdev.blocksize == -1)
            s->qdev.blocksize = 0;
    } else {
        s->qdev.blocksize = get_blocksize(s->bs);
        /* removable media returns 0 if not present */
        if (s->qdev.blocksize <= 0) {
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
                s->qdev.blocksize = 2048;
            else
                s->qdev.blocksize = 512;
        }
    }
    DPRINTF("block size %d\n", s->qdev.blocksize);
    s->driver_status = 0;
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
    bdrv_set_removable(s->bs, 0);
    return 0;
}