@@ -1173,6 +1173,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
return BLOCK_ERROR_ACTION_REPORT;
case BLOCKDEV_ON_ERROR_IGNORE:
return BLOCK_ERROR_ACTION_IGNORE;
+ case BLOCKDEV_ON_ERROR_AUTO:
default:
abort();
}
@@ -524,6 +524,7 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
switch (on_err) {
case BLOCKDEV_ON_ERROR_ENOSPC:
+ case BLOCKDEV_ON_ERROR_AUTO:
action = (error == ENOSPC) ?
BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
break;
@@ -54,6 +54,7 @@ void blkconf_blocksizes(BlockConf *conf)
void blkconf_apply_backend_options(BlockConf *conf)
{
BlockBackend *blk = conf->blk;
+ BlockdevOnError rerror, werror;
bool wce;
switch (conf->wce) {
@@ -64,7 +65,18 @@ void blkconf_apply_backend_options(BlockConf *conf)
abort();
}
+ rerror = conf->rerror;
+ if (rerror == BLOCKDEV_ON_ERROR_AUTO) {
+ rerror = blk_get_on_error(blk, true);
+ }
+
+ werror = conf->werror;
+ if (werror == BLOCKDEV_ON_ERROR_AUTO) {
+ werror = blk_get_on_error(blk, false);
+ }
+
blk_set_enable_write_cache(blk, wce);
+ blk_set_on_error(blk, rerror, werror);
}
void blkconf_geometry(BlockConf *conf, int *ptrans,
@@ -960,6 +960,7 @@ static void virtio_blk_instance_init(Object *obj)
static Property virtio_blk_properties[] = {
DEFINE_BLOCK_PROPERTIES(VirtIOBlock, conf.conf),
+ DEFINE_BLOCK_ERROR_PROPERTIES(VirtIOBlock, conf.conf),
DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlock, conf.conf),
DEFINE_PROP_STRING("serial", VirtIOBlock, conf.serial),
DEFINE_PROP_BIT("config-wce", VirtIOBlock, conf.config_wce, 0, true),
@@ -539,6 +539,19 @@ PropertyInfo qdev_prop_losttickpolicy = {
.set = set_enum,
};
+/* --- Block device error handling policy --- */
+
+QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
+
+PropertyInfo qdev_prop_blockdev_on_error = {
+ .name = "BlockdevOnError",
+ .description = "Error handling policy, "
+ "report/ignore/enospc/stop/auto",
+ .enum_table = BlockdevOnError_lookup,
+ .get = get_enum,
+ .set = set_enum,
+};
+
/* --- BIOS CHS translation */
QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
@@ -264,6 +264,7 @@ static int ide_drive_initfn(IDEDevice *dev)
#define DEFINE_IDE_DEV_PROPERTIES() \
DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
+ DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf), \
DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \
DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \
DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\
@@ -2849,6 +2849,7 @@ static const TypeInfo scsi_disk_base_info = {
#define DEFINE_SCSI_DISK_PROPERTIES() \
DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
+ DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
@@ -26,6 +26,8 @@ typedef struct BlockConf {
/* geometry, not all devices use this */
uint32_t cyls, heads, secs;
OnOffAuto wce;
+ BlockdevOnError rerror;
+ BlockdevOnError werror;
} BlockConf;
static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -58,6 +60,12 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
+#define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf) \
+ DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \
+ BLOCKDEV_ON_ERROR_AUTO), \
+ DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \
+ BLOCKDEV_ON_ERROR_AUTO)
+
/* Configuration helpers */
void blkconf_serial(BlockConf *conf, char **serial);
@@ -20,6 +20,7 @@ extern PropertyInfo qdev_prop_ptr;
extern PropertyInfo qdev_prop_macaddr;
extern PropertyInfo qdev_prop_on_off_auto;
extern PropertyInfo qdev_prop_losttickpolicy;
+extern PropertyInfo qdev_prop_blockdev_on_error;
extern PropertyInfo qdev_prop_bios_chs_trans;
extern PropertyInfo qdev_prop_fdc_drive_type;
extern PropertyInfo qdev_prop_drive;
@@ -161,6 +162,9 @@ extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
LostTickPolicy)
+#define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \
+ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
+ BlockdevOnError)
#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
@@ -664,10 +664,12 @@
# @stop: for guest operations, stop the virtual machine;
# for jobs, pause the job
#
+# @auto: inherit the error handling policy of the backend (since: 2.7)
+#
# Since: 1.3
##
{ 'enum': 'BlockdevOnError',
- 'data': ['report', 'ignore', 'enospc', 'stop'] }
+ 'data': ['report', 'ignore', 'enospc', 'stop', 'auto'] }
##
# @MirrorSyncMode: