| From 94c066bcc75fa2e57d1bc861a7a65f21891425fe Mon Sep 17 00:00:00 2001 |
| From: Max Reitz <mreitz@redhat.com> |
| Date: Mon, 4 Nov 2013 22:31:53 +0100 |
| Subject: [PATCH 02/87] block: move snapshot code in block.c to block/snapshot.c |
| |
| RH-Author: Max Reitz <mreitz@redhat.com> |
| Message-id: <1383604354-12743-3-git-send-email-mreitz@redhat.com> |
| Patchwork-id: 55302 |
| O-Subject: [RHEL-7.0 qemu-kvm PATCH 02/43] block: move snapshot code in block.c to block/snapshot.c |
| Bugzilla: 1026524 |
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> |
| RH-Acked-by: Laszlo Ersek <lersek@redhat.com> |
| RH-Acked-by: Fam Zheng <famz@redhat.com> |
| RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> |
| |
| From: Wenchao Xia <xiawenc@linux.vnet.ibm.com> |
| |
| BZ: 1026524 |
| |
| All snapshot related code, except bdrv_snapshot_dump() and |
| bdrv_is_snapshot(), is moved to block/snapshot.c. bdrv_snapshot_dump() |
| will be moved to another file later. bdrv_is_snapshot() is not related |
| with internal snapshot. It also fixes small code style errors reported |
| by check script. |
| |
| Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> |
| Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
| (cherry picked from commit de08c606f9ddafe647b6843e2b10a6d6030b0fc0) |
| |
| Signed-off-by: Max Reitz <mreitz@redhat.com> |
| |
| block.c | 100 ------------------------------ |
| block/Makefile.objs | 1 + |
| block/snapshot.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++ |
| include/block/block.h | 26 ++------ |
| include/block/snapshot.h | 53 ++++++++++++++++ |
| savevm.c | 23 +------ |
| 6 files changed, 217 insertions(+), 143 deletions(-) |
| create mode 100644 block/snapshot.c |
| create mode 100644 include/block/snapshot.h |
| |
| Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> |
| |
| block.c | 100 ----------------------------- |
| block/Makefile.objs | 1 + |
| block/snapshot.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++ |
| include/block/block.h | 26 ++------ |
| include/block/snapshot.h | 53 ++++++++++++++++ |
| savevm.c | 23 +------- |
| 6 files changed, 217 insertions(+), 143 deletions(-) |
| create mode 100644 block/snapshot.c |
| create mode 100644 include/block/snapshot.h |
| |
| diff --git a/block.c b/block.c |
| index 84a3a8d..69b70d0 100644 |
| |
| |
| @@ -3458,111 +3458,11 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag) |
| return false; |
| } |
| |
| -/**************************************************************/ |
| -/* handling of snapshots */ |
| - |
| -int bdrv_can_snapshot(BlockDriverState *bs) |
| -{ |
| - BlockDriver *drv = bs->drv; |
| - if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { |
| - return 0; |
| - } |
| - |
| - if (!drv->bdrv_snapshot_create) { |
| - if (bs->file != NULL) { |
| - return bdrv_can_snapshot(bs->file); |
| - } |
| - return 0; |
| - } |
| - |
| - return 1; |
| -} |
| - |
| int bdrv_is_snapshot(BlockDriverState *bs) |
| { |
| return !!(bs->open_flags & BDRV_O_SNAPSHOT); |
| } |
| |
| -int bdrv_snapshot_create(BlockDriverState *bs, |
| - QEMUSnapshotInfo *sn_info) |
| -{ |
| - BlockDriver *drv = bs->drv; |
| - if (!drv) |
| - return -ENOMEDIUM; |
| - 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 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, NULL, bs->open_flags); |
| - if (open_ret < 0) { |
| - bdrv_delete(bs->file); |
| - bs->drv = NULL; |
| - return open_ret; |
| - } |
| - return ret; |
| - } |
| - |
| - return -ENOTSUP; |
| -} |
| - |
| -int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) |
| -{ |
| - BlockDriver *drv = bs->drv; |
| - if (!drv) |
| - return -ENOMEDIUM; |
| - if (drv->bdrv_snapshot_delete) |
| - return drv->bdrv_snapshot_delete(bs, snapshot_id); |
| - if (bs->file) |
| - return bdrv_snapshot_delete(bs->file, snapshot_id); |
| - return -ENOTSUP; |
| -} |
| - |
| -int bdrv_snapshot_list(BlockDriverState *bs, |
| - QEMUSnapshotInfo **psn_info) |
| -{ |
| - BlockDriver *drv = bs->drv; |
| - if (!drv) |
| - return -ENOMEDIUM; |
| - if (drv->bdrv_snapshot_list) |
| - return drv->bdrv_snapshot_list(bs, psn_info); |
| - if (bs->file) |
| - return bdrv_snapshot_list(bs->file, psn_info); |
| - return -ENOTSUP; |
| -} |
| - |
| -int bdrv_snapshot_load_tmp(BlockDriverState *bs, |
| - const char *snapshot_name) |
| -{ |
| - BlockDriver *drv = bs->drv; |
| - if (!drv) { |
| - return -ENOMEDIUM; |
| - } |
| - if (!bs->read_only) { |
| - return -EINVAL; |
| - } |
| - if (drv->bdrv_snapshot_load_tmp) { |
| - return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); |
| - } |
| - return -ENOTSUP; |
| -} |
| - |
| /* backing_file can either be relative, or absolute, or a protocol. If it is |
| * relative, it must be relative to the chain. So, passing in bs->filename |
| * from a BDS as backing_file should not be done, as that may be relative to |
| diff --git a/block/Makefile.objs b/block/Makefile.objs |
| index 41a284b..162f270 100644 |
| |
| |
| @@ -4,6 +4,7 @@ block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o |
| block-obj-y += qed-check.o |
| block-obj-y += vhdx.o |
| block-obj-y += parallels.o blkdebug.o blkverify.o |
| +block-obj-y += snapshot.o |
| block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o |
| block-obj-$(CONFIG_POSIX) += raw-posix.o |
| block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o |
| diff --git a/block/snapshot.c b/block/snapshot.c |
| new file mode 100644 |
| index 0000000..6c6d9de |
| |
| |
| @@ -0,0 +1,157 @@ |
| +/* |
| + * Block layer snapshot related functions |
| + * |
| + * Copyright (c) 2003-2008 Fabrice Bellard |
| + * |
| + * Permission is hereby granted, free of charge, to any person obtaining a copy |
| + * of this software and associated documentation files (the "Software"), to deal |
| + * in the Software without restriction, including without limitation the rights |
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| + * copies of the Software, and to permit persons to whom the Software is |
| + * furnished to do so, subject to the following conditions: |
| + * |
| + * The above copyright notice and this permission notice shall be included in |
| + * all copies or substantial portions of the Software. |
| + * |
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| + * THE SOFTWARE. |
| + */ |
| + |
| +#include "block/snapshot.h" |
| +#include "block/block_int.h" |
| + |
| +int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, |
| + const char *name) |
| +{ |
| + QEMUSnapshotInfo *sn_tab, *sn; |
| + int nb_sns, i, ret; |
| + |
| + ret = -ENOENT; |
| + nb_sns = bdrv_snapshot_list(bs, &sn_tab); |
| + if (nb_sns < 0) { |
| + return ret; |
| + } |
| + for (i = 0; i < nb_sns; i++) { |
| + sn = &sn_tab[i]; |
| + if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) { |
| + *sn_info = *sn; |
| + ret = 0; |
| + break; |
| + } |
| + } |
| + g_free(sn_tab); |
| + return ret; |
| +} |
| + |
| +int bdrv_can_snapshot(BlockDriverState *bs) |
| +{ |
| + BlockDriver *drv = bs->drv; |
| + if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { |
| + return 0; |
| + } |
| + |
| + if (!drv->bdrv_snapshot_create) { |
| + if (bs->file != NULL) { |
| + return bdrv_can_snapshot(bs->file); |
| + } |
| + return 0; |
| + } |
| + |
| + return 1; |
| +} |
| + |
| +int bdrv_snapshot_create(BlockDriverState *bs, |
| + QEMUSnapshotInfo *sn_info) |
| +{ |
| + BlockDriver *drv = bs->drv; |
| + if (!drv) { |
| + return -ENOMEDIUM; |
| + } |
| + 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 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, NULL, bs->open_flags); |
| + if (open_ret < 0) { |
| + bdrv_delete(bs->file); |
| + bs->drv = NULL; |
| + return open_ret; |
| + } |
| + return ret; |
| + } |
| + |
| + return -ENOTSUP; |
| +} |
| + |
| +int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) |
| +{ |
| + BlockDriver *drv = bs->drv; |
| + if (!drv) { |
| + return -ENOMEDIUM; |
| + } |
| + if (drv->bdrv_snapshot_delete) { |
| + return drv->bdrv_snapshot_delete(bs, snapshot_id); |
| + } |
| + if (bs->file) { |
| + return bdrv_snapshot_delete(bs->file, snapshot_id); |
| + } |
| + return -ENOTSUP; |
| +} |
| + |
| +int bdrv_snapshot_list(BlockDriverState *bs, |
| + QEMUSnapshotInfo **psn_info) |
| +{ |
| + BlockDriver *drv = bs->drv; |
| + if (!drv) { |
| + return -ENOMEDIUM; |
| + } |
| + if (drv->bdrv_snapshot_list) { |
| + return drv->bdrv_snapshot_list(bs, psn_info); |
| + } |
| + if (bs->file) { |
| + return bdrv_snapshot_list(bs->file, psn_info); |
| + } |
| + return -ENOTSUP; |
| +} |
| + |
| +int bdrv_snapshot_load_tmp(BlockDriverState *bs, |
| + const char *snapshot_name) |
| +{ |
| + BlockDriver *drv = bs->drv; |
| + if (!drv) { |
| + return -ENOMEDIUM; |
| + } |
| + if (!bs->read_only) { |
| + return -EINVAL; |
| + } |
| + if (drv->bdrv_snapshot_load_tmp) { |
| + return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); |
| + } |
| + return -ENOTSUP; |
| +} |
| diff --git a/include/block/block.h b/include/block/block.h |
| index 3b3f40e..03ebc47 100644 |
| |
| |
| @@ -7,6 +7,11 @@ |
| #include "block/coroutine.h" |
| #include "qapi/qmp/qobject.h" |
| #include "qapi-types.h" |
| +/* |
| + * snapshot.h is needed since bdrv_snapshot_dump(), it can be removed when the |
| + * function is moved to other file. |
| + */ |
| +#include "block/snapshot.h" |
| |
| /* block.c */ |
| typedef struct BlockDriver BlockDriver; |
| @@ -27,17 +32,6 @@ typedef struct BlockFragInfo { |
| uint64_t compressed_clusters; |
| } BlockFragInfo; |
| |
| -typedef struct QEMUSnapshotInfo { |
| - char id_str[128]; /* unique snapshot id */ |
| - /* the following fields are informative. They are not needed for |
| - the consistency of the snapshot */ |
| - char name[256]; /* user chosen name */ |
| - uint64_t vm_state_size; /* VM state info size */ |
| - uint32_t date_sec; /* UTC date of the snapshot */ |
| - uint32_t date_nsec; |
| - uint64_t vm_clock_nsec; /* VM clock relative to boot */ |
| -} QEMUSnapshotInfo; |
| - |
| /* Callbacks for block device models */ |
| typedef struct BlockDevOps { |
| /* |
| @@ -360,17 +354,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, |
| char *dest, size_t sz); |
| BlockInfo *bdrv_query_info(BlockDriverState *s); |
| BlockStats *bdrv_query_stats(const BlockDriverState *bs); |
| -int bdrv_can_snapshot(BlockDriverState *bs); |
| int bdrv_is_snapshot(BlockDriverState *bs); |
| -int bdrv_snapshot_create(BlockDriverState *bs, |
| - QEMUSnapshotInfo *sn_info); |
| -int bdrv_snapshot_goto(BlockDriverState *bs, |
| - const char *snapshot_id); |
| -int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id); |
| -int bdrv_snapshot_list(BlockDriverState *bs, |
| - QEMUSnapshotInfo **psn_info); |
| -int bdrv_snapshot_load_tmp(BlockDriverState *bs, |
| - const char *snapshot_name); |
| char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); |
| |
| char *get_human_readable_size(char *buf, int buf_size, int64_t size); |
| diff --git a/include/block/snapshot.h b/include/block/snapshot.h |
| new file mode 100644 |
| index 0000000..eaf61f0 |
| |
| |
| @@ -0,0 +1,53 @@ |
| +/* |
| + * Block layer snapshot related functions |
| + * |
| + * Copyright (c) 2003-2008 Fabrice Bellard |
| + * |
| + * Permission is hereby granted, free of charge, to any person obtaining a copy |
| + * of this software and associated documentation files (the "Software"), to deal |
| + * in the Software without restriction, including without limitation the rights |
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| + * copies of the Software, and to permit persons to whom the Software is |
| + * furnished to do so, subject to the following conditions: |
| + * |
| + * The above copyright notice and this permission notice shall be included in |
| + * all copies or substantial portions of the Software. |
| + * |
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| + * THE SOFTWARE. |
| + */ |
| + |
| +#ifndef SNAPSHOT_H |
| +#define SNAPSHOT_H |
| + |
| +#include "qemu-common.h" |
| + |
| +typedef struct QEMUSnapshotInfo { |
| + char id_str[128]; /* unique snapshot id */ |
| + /* the following fields are informative. They are not needed for |
| + the consistency of the snapshot */ |
| + char name[256]; /* user chosen name */ |
| + uint64_t vm_state_size; /* VM state info size */ |
| + uint32_t date_sec; /* UTC date of the snapshot */ |
| + uint32_t date_nsec; |
| + uint64_t vm_clock_nsec; /* VM clock relative to boot */ |
| +} QEMUSnapshotInfo; |
| + |
| +int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, |
| + const char *name); |
| +int bdrv_can_snapshot(BlockDriverState *bs); |
| +int bdrv_snapshot_create(BlockDriverState *bs, |
| + QEMUSnapshotInfo *sn_info); |
| +int bdrv_snapshot_goto(BlockDriverState *bs, |
| + const char *snapshot_id); |
| +int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id); |
| +int bdrv_snapshot_list(BlockDriverState *bs, |
| + QEMUSnapshotInfo **psn_info); |
| +int bdrv_snapshot_load_tmp(BlockDriverState *bs, |
| + const char *snapshot_name); |
| +#endif |
| diff --git a/savevm.c b/savevm.c |
| index d9f3787..005bf35 100644 |
| |
| |
| @@ -40,6 +40,7 @@ |
| #include "trace.h" |
| #include "qemu/bitops.h" |
| #include "qemu/iov.h" |
| +#include "block/snapshot.h" |
| |
| #define SELF_ANNOUNCE_ROUNDS 5 |
| |
| @@ -2273,28 +2274,6 @@ static BlockDriverState *find_vmstate_bs(void) |
| return NULL; |
| } |
| |
| -static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, |
| - const char *name) |
| -{ |
| - QEMUSnapshotInfo *sn_tab, *sn; |
| - int nb_sns, i, ret; |
| - |
| - ret = -ENOENT; |
| - nb_sns = bdrv_snapshot_list(bs, &sn_tab); |
| - if (nb_sns < 0) |
| - return ret; |
| - for(i = 0; i < nb_sns; i++) { |
| - sn = &sn_tab[i]; |
| - if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) { |
| - *sn_info = *sn; |
| - ret = 0; |
| - break; |
| - } |
| - } |
| - g_free(sn_tab); |
| - return ret; |
| -} |
| - |
| /* |
| * Deletes snapshots of a given name in all opened images. |
| */ |
| -- |
| 1.7.1 |
| |