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; }
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; }
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; }
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; }