-void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
- BlockdevOnError on_write_error)
-{
- bs->on_read_error = on_read_error;
- bs->on_write_error = on_write_error;
-}
-
-BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read)
-{
- return is_read ? bs->on_read_error : bs->on_write_error;
-}
-
-BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error)
-{
- BlockdevOnError on_err = is_read ? bs->on_read_error : bs->on_write_error;
-
- switch (on_err) {
- case BLOCKDEV_ON_ERROR_ENOSPC:
- return (error == ENOSPC) ?
- BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
- case BLOCKDEV_ON_ERROR_STOP:
- return BLOCK_ERROR_ACTION_STOP;
- case BLOCKDEV_ON_ERROR_REPORT:
- return BLOCK_ERROR_ACTION_REPORT;
- case BLOCKDEV_ON_ERROR_IGNORE:
- return BLOCK_ERROR_ACTION_IGNORE;
- default:
- abort();
- }
-}
-
-static void send_qmp_error_event(BlockDriverState *bs,
- BlockErrorAction action,
- bool is_read, int error)
-{
- IoOperationType optype;
-
- optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
- qapi_event_send_block_io_error(bdrv_get_device_name(bs), optype, action,
- bdrv_iostatus_is_enabled(bs),
- error == ENOSPC, strerror(error),
- &error_abort);
-}
-
-/* This is done by device models because, while the block layer knows
- * about the error, it does not know whether an operation comes from
- * the device or the block layer (from a job, for example).
- */
-void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
- bool is_read, int error)
-{
- assert(error >= 0);
-
- if (action == BLOCK_ERROR_ACTION_STOP) {
- /* First set the iostatus, so that "info block" returns an iostatus
- * that matches the events raised so far (an additional error iostatus
- * is fine, but not a lost one).
- */
- bdrv_iostatus_set_err(bs, error);
-
- /* Then raise the request to stop the VM and the event.
- * qemu_system_vmstop_request_prepare has two effects. First,
- * it ensures that the STOP event always comes after the
- * BLOCK_IO_ERROR event. Second, it ensures that even if management
- * can observe the STOP event and do a "cont" before the STOP
- * event is issued, the VM will not stop. In this case, vm_start()
- * also ensures that the STOP/RESUME pair of events is emitted.
- */
- qemu_system_vmstop_request_prepare();
- send_qmp_error_event(bs, action, is_read, error);
- qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
- } else {
- send_qmp_error_event(bs, action, is_read, error);
- }
-}
-