Am 17.05.2010 12:19, schrieb MORITA Kazutaka: > When snapshot handlers are not defined in the format driver, it is > better to call the ones of the protocol driver. This enables us to > implement snapshot support in the protocol driver. > > We need to call bdrv_close() and bdrv_open() handlers of the format > driver before and after bdrv_snapshot_goto() call of the protocol. It is > because the contents of the block driver state may need to be changed > after loading vmstate. > > Signed-off-by: MORITA Kazutaka <morita.kazutaka@xxxxxxxxxxxxx> > --- > block.c | 61 +++++++++++++++++++++++++++++++++++++++++++------------------ > 1 files changed, 43 insertions(+), 18 deletions(-) > > diff --git a/block.c b/block.c > index f3bf3f2..c987e57 100644 > --- a/block.c > +++ b/block.c > @@ -1683,9 +1683,11 @@ int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, > BlockDriver *drv = bs->drv; > if (!drv) > return -ENOMEDIUM; > - if (!drv->bdrv_save_vmstate) > - return -ENOTSUP; > - return drv->bdrv_save_vmstate(bs, buf, pos, size); > + if (drv->bdrv_save_vmstate) > + return drv->bdrv_save_vmstate(bs, buf, pos, size); > + if (bs->file) > + return bdrv_save_vmstate(bs->file, buf, pos, size); > + return -ENOTSUP; > } > > int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, > @@ -1694,9 +1696,11 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, > BlockDriver *drv = bs->drv; > if (!drv) > return -ENOMEDIUM; > - if (!drv->bdrv_load_vmstate) > - return -ENOTSUP; > - return drv->bdrv_load_vmstate(bs, buf, pos, size); > + if (drv->bdrv_load_vmstate) > + return drv->bdrv_load_vmstate(bs, buf, pos, size); > + if (bs->file) > + return bdrv_load_vmstate(bs->file, buf, pos, size); > + return -ENOTSUP; > } > > void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) > @@ -1720,20 +1724,37 @@ int bdrv_snapshot_create(BlockDriverState *bs, > BlockDriver *drv = bs->drv; > if (!drv) > return -ENOMEDIUM; > - if (!drv->bdrv_snapshot_create) > - return -ENOTSUP; > - return drv->bdrv_snapshot_create(bs, sn_info); > + if (drv->bdrv_snapshot_create) > + return drv->bdrv_snapshot_create(bs, sn_info); > + if (bs->file) > + return bdrv_snapshot_create(bs->file, sn_info); > + return -ENOTSUP; > } > > int bdrv_snapshot_goto(BlockDriverState *bs, > const char *snapshot_id) > { > BlockDriver *drv = bs->drv; > + int ret, open_ret; > + > if (!drv) > return -ENOMEDIUM; > - if (!drv->bdrv_snapshot_goto) > - return -ENOTSUP; > - return drv->bdrv_snapshot_goto(bs, snapshot_id); > + if (drv->bdrv_snapshot_goto) > + return drv->bdrv_snapshot_goto(bs, snapshot_id); > + > + if (bs->file) { > + drv->bdrv_close(bs); > + ret = bdrv_snapshot_goto(bs->file, snapshot_id); > + open_ret = drv->bdrv_open(bs, bs->open_flags); > + if (open_ret < 0) { > + bdrv_delete(bs); I think you mean bs->file here. Kevin > + bs->drv = NULL; > + return open_ret; > + } > + return ret; > + } > + > + return -ENOTSUP; > } > > int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html