vmdk driver changes for bdrv_reopen_xx functions to safely reopen image files. Reopening of image files while changing hostcache flag dynamically is handled here.
Signed-off-by: Supriya Kannery <supri...@linux.vnet.ibm.com> Index: qemu/block/vmdk.c =================================================================== --- qemu.orig/block/vmdk.c +++ qemu/block/vmdk.c @@ -115,6 +115,11 @@ typedef struct VmdkGrainMarker { uint8_t data[0]; } VmdkGrainMarker; +typedef struct BDRVVmdkReopenState { + BDRVReopenState reopen_state; + BDRVVmdkState *stash_s; +} BDRVVmdkReopenState; + static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) { uint32_t magic; @@ -588,7 +593,6 @@ static int vmdk_parse_extents(const char if (!strcmp(type, "FLAT")) { /* FLAT extent */ VmdkExtent *extent; - extent = vmdk_add_extent(bs, extent_file, true, sectors, 0, 0, 0, 0, sectors); extent->flat_start_offset = flat_offset << 9; @@ -675,6 +679,71 @@ fail: return ret; } +static int vmdk_reopen_prepare(BlockDriverState *bs, BDRVReopenState **prs, + int flags) +{ + BDRVVmdkReopenState *vmdk_rs = g_malloc0(sizeof(BDRVVmdkReopenState)); + int ret = 0; + BDRVVmdkState *s = bs->opaque; + + vmdk_rs->reopen_state.bs = bs; + + /* save state before reopen */ + vmdk_rs->stash_s = g_malloc0(sizeof(BDRVVmdkState)); + memcpy(vmdk_rs->stash_s, s, sizeof(BDRVVmdkState)); + s->num_extents = 0; + s->extents = NULL ; + *prs = &(vmdk_rs->reopen_state); + + /* create extents afresh with new flags */ + ret = vmdk_open(bs, flags); + return ret; +} + +static void vmdk_reopen_commit(BlockDriverState *bs, BDRVReopenState *rs) +{ + BDRVVmdkReopenState *vmdk_rs; + BDRVVmdkState *stashed_s; + VmdkExtent *e; + int i; + + vmdk_rs = container_of(rs, BDRVVmdkReopenState, reopen_state); + stashed_s = vmdk_rs->stash_s; + + /* clean up stashed state */ + for (i = 0; i < stashed_s->num_extents; i++) { + e = &stashed_s->extents[i]; + g_free(e->l1_table); + g_free(e->l2_cache); + g_free(e->l1_backup_table); + } + g_free(stashed_s->extents); + g_free(vmdk_rs->stash_s); + g_free(vmdk_rs); +} + +static void vmdk_reopen_abort(BlockDriverState *bs, BDRVReopenState *rs) +{ + BDRVVmdkReopenState *vmdk_rs; + BDRVVmdkState *s = bs->opaque; + VmdkExtent *e; + int i; + + vmdk_rs = container_of(rs, BDRVVmdkReopenState, reopen_state); + + /* revert to stashed state */ + for (i = 0; i < s->num_extents; i++) { + e = &s->extents[i]; + g_free(e->l1_table); + g_free(e->l2_cache); + g_free(e->l1_backup_table); + } + g_free(s->extents); + memcpy(s, vmdk_rs->stash_s, sizeof(BDRVVmdkState)); + g_free(vmdk_rs->stash_s); + g_free(vmdk_rs); +} + static int get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent, uint64_t cluster_offset, @@ -1382,7 +1451,6 @@ static int vmdk_create(const char *filen if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) { return -EINVAL; } - printf("vmdk_create\n"); /* Read out options */ while (options && options->name) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) { @@ -1517,8 +1585,8 @@ exit: static void vmdk_close(BlockDriverState *bs) { BDRVVmdkState *s = bs->opaque; - printf("vmdk_close\n"); + vmdk_free_extents(bs); migrate_del_blocker(s->migration_blocker); @@ -1595,6 +1663,12 @@ static BlockDriver bdrv_vmdk = { .instance_size = sizeof(BDRVVmdkState), .bdrv_probe = vmdk_probe, .bdrv_open = vmdk_open, + .bdrv_reopen_prepare + = vmdk_reopen_prepare, + .bdrv_reopen_commit + = vmdk_reopen_commit, + .bdrv_reopen_abort + = vmdk_reopen_abort, .bdrv_read = vmdk_co_read, .bdrv_write = vmdk_co_write, .bdrv_close = vmdk_close,