block: Add error handling to bdrv_invalidate_cache()
PATCH v2 1/1 block: Add error handling to bdrv_invalidate_cache()
If it returns an error, the migrated VM will not be started, but qemu exits with an error message.
Signed-off-by Kevin Wolf <[email protected]>
Reviewed-by Juan Quintela <[email protected]>
Reviewed-by Eric Blake <[email protected]>
---
v2:
- Update quorum as well (not built by default, so it escaped my attention in v1)
block.c | 28 ++++++++++++++++++++++------ block/qcow2.c | 22 +++++++++++++++++++--- block/qed.c | 21 ++++++++++++++++++--- block/quorum.c | 9 +++++++-- include/block/block.h | 4 ++-- include/block/block_int.h | 2 +- migration.c | 8 +++++++- 7 files changed, 76 insertions(+), 18 deletions(-)
block.c +22 -6
@@ -4781,27 +4781,43 @@ flush_parent:return bdrv_co_flush (bs->file); } -void bdrv_invalidate_cache (BlockDriverState *bs) +void bdrv_invalidate_cache (BlockDriverState *bs,Error **errp) { +Error *local_err =NULL ; +int ret; +if (!bs->drv) {return ; }if (bs->drv->bdrv_invalidate_cache) { - bs->drv->bdrv_invalidate_cache (bs); + bs->drv->bdrv_invalidate_cache (bs, &local_err); }else if (bs->file) { -bdrv_invalidate_cache (bs->file); +bdrv_invalidate_cache (bs->file, &local_err); + } +if (local_err) { +error_propagate (errp, local_err); +return ; } -refresh_total_sectors (bs, bs->total_sectors); + ret =refresh_total_sectors (bs, bs->total_sectors); +if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not refresh total sector count" ); +return ; + } } -void bdrv_invalidate_cache_all (void ) +void bdrv_invalidate_cache_all (Error **errp) {BlockDriverState *bs; +Error *local_err =NULL ; QTAILQ_FOREACH(bs, &bdrv_states, device_list) { -bdrv_invalidate_cache (bs); +bdrv_invalidate_cache (bs, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } } }
block/qcow2.c +19 -3
@@ -1156,7 +1156,7 @@ static void qcow2_close(BlockDriverState *bs)qcow2_free_snapshots (bs); } -static void qcow2_invalidate_cache (BlockDriverState *bs) +static void qcow2_invalidate_cache (BlockDriverState *bs,Error **errp) {BDRVQcowState *s = bs->opaque;int flags = s->flags;
@@ -1164,6 +1164,8 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)AES_KEY aes_decrypt_key;uint32_t crypt_method =0 ;QDict *options; +Error *local_err =NULL ; +int ret;/* * Backing files are read-only which makes all of their metadata immutable,
@@ -1178,11 +1180,25 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)qcow2_close (bs); -bdrv_invalidate_cache (bs->file); +bdrv_invalidate_cache (bs->file, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + }memset (s,0 ,sizeof (BDRVQcowState)); options =qdict_clone_shallow (bs->options); -qcow2_open (bs, options, flags,NULL ); + + ret =qcow2_open (bs, options, flags, &local_err); +if (local_err) { +error_setg (errp,"Could not reopen qcow2 layer: %s" , +error_get_pretty (local_err)); +error_free (local_err); +return ; + }else if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not reopen qcow2 layer" ); +return ; + }QDECREF (options);
block/qed.c +18 -3
@@ -1558,16 +1558,31 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,return ret; } -static void bdrv_qed_invalidate_cache (BlockDriverState *bs) +static void bdrv_qed_invalidate_cache (BlockDriverState *bs,Error **errp) {BDRVQEDState *s = bs->opaque; +Error *local_err =NULL ; +int ret;bdrv_qed_close (bs); -bdrv_invalidate_cache (bs->file); +bdrv_invalidate_cache (bs->file, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + }memset (s,0 ,sizeof (BDRVQEDState)); -bdrv_qed_open (bs,NULL , bs->open_flags,NULL ); + ret =bdrv_qed_open (bs,NULL , bs->open_flags, &local_err); +if (local_err) { +error_setg (errp,"Could not reopen qed layer: %s" , +error_get_pretty (local_err)); +error_free (local_err); +return ; + }else if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not reopen qed layer" ); +return ; + } } static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
block/quorum.c +7 -2
@@ -625,13 +625,18 @@ static int64_t quorum_getlength(BlockDriverState *bs)return result; } -static void quorum_invalidate_cache (BlockDriverState *bs) +static void quorum_invalidate_cache (BlockDriverState *bs,Error **errp) {BDRVQuorumState *s = bs->opaque; +Error *local_err =NULL ;int i;for (i =0 ; i < s->num_children; i++) { -bdrv_invalidate_cache (s->bs[i]); +bdrv_invalidate_cache (s->bs[i], &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } } }
include/block/block.h +2 -2
@@ -329,8 +329,8 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque);/* Invalidate any cached metadata used by image formats */ -void bdrv_invalidate_cache (BlockDriverState *bs); -void bdrv_invalidate_cache_all (void ); +void bdrv_invalidate_cache (BlockDriverState *bs,Error **errp); +void bdrv_invalidate_cache_all (Error **errp);void bdrv_clear_incoming_migration_all (void );
include/block/block_int.h +1 -1
@@ -153,7 +153,7 @@ struct BlockDriver {/* * Invalidate any cached meta-data. */ -void (*bdrv_invalidate_cache)(BlockDriverState *bs); +void (*bdrv_invalidate_cache)(BlockDriverState *bs,Error **errp);/* * Flushes all data that was already written to the OS all the way down to
migration.c +7 -1
@@ -101,6 +101,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp)static void process_incoming_migration_co (void *opaque) {QEMUFile *f = opaque; +Error *local_err =NULL ;int ret; ret =qemu_loadvm_state (f);
@@ -115,7 +116,12 @@ static void process_incoming_migration_co(void *opaque)bdrv_clear_incoming_migration_all ();/* Make sure all file formats flush their mutable metadata */ -bdrv_invalidate_cache_all (); +bdrv_invalidate_cache_all (&local_err); +if (local_err) { +qerror_report_err (local_err); +error_free (local_err); +exit (EXIT_FAILURE ); + }if (autostart) {vm_start ();
Signature · 1 line
1.8.3.1
Quoted 246 lines · Kevin Wolf
If it returns an error, the migrated VM will not be started, but qemu exits with an error message.
Signed-off-by Kevin Wolf <[email protected]>Reviewed-by Juan Quintela <[email protected]>Reviewed-by Eric Blake <[email protected]>---
v2:
- Update quorum as well (not built by default, so it escaped my attention in v1)block.c | 28 ++++++++++++++++++++++------ block/qcow2.c | 22 +++++++++++++++++++--- block/qed.c | 21 ++++++++++++++++++--- block/quorum.c | 9 +++++++-- include/block/block.h | 4 ++-- include/block/block_int.h | 2 +- migration.c | 8 +++++++- 7 files changed, 76 insertions(+), 18 deletions(-)block.c +22
-6@@ -4781,27 +4781,43 @@ flush_parent:return bdrv_co_flush (bs->file); } -void bdrv_invalidate_cache (BlockDriverState *bs) +void bdrv_invalidate_cache (BlockDriverState *bs,Error **errp) { +Error *local_err =NULL ; +int ret; +if (!bs->drv) {return ; }if (bs->drv->bdrv_invalidate_cache) { - bs->drv->bdrv_invalidate_cache (bs); + bs->drv->bdrv_invalidate_cache (bs, &local_err); }else if (bs->file) { -bdrv_invalidate_cache (bs->file); +bdrv_invalidate_cache (bs->file, &local_err); + } +if (local_err) { +error_propagate (errp, local_err); +return ; } -refresh_total_sectors (bs, bs->total_sectors); + ret =refresh_total_sectors (bs, bs->total_sectors); +if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not refresh total sector count" ); +return ; + } } -void bdrv_invalidate_cache_all (void ) +void bdrv_invalidate_cache_all (Error **errp) {BlockDriverState *bs; +Error *local_err =NULL ; QTAILQ_FOREACH(bs, &bdrv_states, device_list) { -bdrv_invalidate_cache (bs); +bdrv_invalidate_cache (bs, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } } }block/qcow2.c +19
-3@@ -1156,7 +1156,7 @@ static void qcow2_close(BlockDriverState *bs)qcow2_free_snapshots (bs); } -static void qcow2_invalidate_cache (BlockDriverState *bs) +static void qcow2_invalidate_cache (BlockDriverState *bs,Error **errp) {BDRVQcowState *s = bs->opaque;int flags = s->flags;@@ -1164,6 +1164,8 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)AES_KEY aes_decrypt_key;uint32_t crypt_method =0 ;QDict *options; +Error *local_err =NULL ; +int ret;/* * Backing files are read-only which makes all of their metadata immutable, @@ -1178,11 +1180,25 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)qcow2_close (bs); -bdrv_invalidate_cache (bs->file); +bdrv_invalidate_cache (bs->file, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + }memset (s,0 ,sizeof (BDRVQcowState)); options =qdict_clone_shallow (bs->options); -qcow2_open (bs, options, flags,NULL ); + + ret =qcow2_open (bs, options, flags, &local_err); +if (local_err) { +error_setg (errp,"Could not reopen qcow2 layer: %s" , +error_get_pretty (local_err)); +error_free (local_err); +return ; + }else if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not reopen qcow2 layer" ); +return ; + }QDECREF (options);block/qed.c +18
-3@@ -1558,16 +1558,31 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,return ret; } -static void bdrv_qed_invalidate_cache (BlockDriverState *bs) +static void bdrv_qed_invalidate_cache (BlockDriverState *bs,Error **errp) {BDRVQEDState *s = bs->opaque; +Error *local_err =NULL ; +int ret;bdrv_qed_close (bs); -bdrv_invalidate_cache (bs->file); +bdrv_invalidate_cache (bs->file, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + }memset (s,0 ,sizeof (BDRVQEDState)); -bdrv_qed_open (bs,NULL , bs->open_flags,NULL ); + ret =bdrv_qed_open (bs,NULL , bs->open_flags, &local_err); +if (local_err) { +error_setg (errp,"Could not reopen qed layer: %s" , +error_get_pretty (local_err)); +error_free (local_err); +return ; + }else if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not reopen qed layer" ); +return ; + } } static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,block/quorum.c +7
-2@@ -625,13 +625,18 @@ static int64_t quorum_getlength(BlockDriverState *bs)return result; } -static void quorum_invalidate_cache (BlockDriverState *bs) +static void quorum_invalidate_cache (BlockDriverState *bs,Error **errp) {BDRVQuorumState *s = bs->opaque; +Error *local_err =NULL ;int i;for (i =0 ; i < s->num_children; i++) { -bdrv_invalidate_cache (s->bs[i]); +bdrv_invalidate_cache (s->bs[i], &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } } }include/block/block.h +2
-2@@ -329,8 +329,8 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque);/* Invalidate any cached metadata used by image formats */ -void bdrv_invalidate_cache (BlockDriverState *bs); -void bdrv_invalidate_cache_all (void ); +void bdrv_invalidate_cache (BlockDriverState *bs,Error **errp); +void bdrv_invalidate_cache_all (Error **errp);void bdrv_clear_incoming_migration_all (void );include/block/block_int.h +1
-1@@ -153,7 +153,7 @@ struct BlockDriver {/* * Invalidate any cached meta-data. */ -void (*bdrv_invalidate_cache)(BlockDriverState *bs); +void (*bdrv_invalidate_cache)(BlockDriverState *bs,Error **errp);/* * Flushes all data that was already written to the OS all the way down to migration.c +7
-1@@ -101,6 +101,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp)static void process_incoming_migration_co (void *opaque) {QEMUFile *f = opaque; +Error *local_err =NULL ;int ret; ret =qemu_loadvm_state (f);@@ -115,7 +116,12 @@ static void process_incoming_migration_co(void *opaque)bdrv_clear_incoming_migration_all ();/* Make sure all file formats flush their mutable metadata */ -bdrv_invalidate_cache_all (); +bdrv_invalidate_cache_all (&local_err); +if (local_err) { +qerror_report_err (local_err); +error_free (local_err); +exit (EXIT_FAILURE ); + }if (autostart) {vm_start ();Signature · 1 line
1.8.3.1
Look good
Reviewed-by Benoit Canet <[email protected]>