From patchwork Thu Jan 14 11:29:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 567328 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 324F814029E for ; Thu, 14 Jan 2016 22:31:39 +1100 (AEDT) Received: from localhost ([::1]:41481 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aJg7s-0001Bi-Vd for incoming@patchwork.ozlabs.org; Thu, 14 Jan 2016 06:31:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41219) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aJg5p-0005gL-SL for qemu-devel@nongnu.org; Thu, 14 Jan 2016 06:29:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aJg5o-0007Od-IF for qemu-devel@nongnu.org; Thu, 14 Jan 2016 06:29:29 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:20959 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aJg5n-0007OZ-UN for qemu-devel@nongnu.org; Thu, 14 Jan 2016 06:29:28 -0500 Received: from hades.sw.ru ([10.30.8.132]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id u0D67TFn010283; Wed, 13 Jan 2016 09:07:43 +0300 (MSK) From: "Denis V. Lunev" To: Date: Thu, 14 Jan 2016 14:29:00 +0300 Message-Id: <1452770941-21582-8-git-send-email-den@openvz.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1452770941-21582-1-git-send-email-den@openvz.org> References: <1452770941-21582-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Cc: Kevin Wolf , Juan Quintela , qemu-devel@nongnu.org, Markus Armbruster , Amit Shah , "Denis V. Lunev" Subject: [Qemu-devel] [PATCH 7/8] migration, qmp: add optional argument to specify BDS to save VM state to X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Denis V. Lunev CC: Kevin Wolf CC: Juan Quintela CC: Amit Shah CC: Markus Armbruster CC: Eric Blake --- block/snapshot.c | 40 ++++++++++++++++++++++++++++++++++++++-- hmp.c | 2 +- include/block/snapshot.h | 2 +- migration/savevm.c | 11 ++++++----- qapi-schema.json | 3 ++- qmp-commands.hx | 6 ++++-- 6 files changed, 52 insertions(+), 12 deletions(-) diff --git a/block/snapshot.c b/block/snapshot.c index 77affbc..237a015 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -25,6 +25,7 @@ #include "block/snapshot.h" #include "block/block_int.h" #include "qapi/qmp/qerror.h" +#include "sysemu/block-backend.h" QemuOptsList internal_snapshot_opts = { .name = "snapshot", @@ -475,18 +476,53 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, return err; } -BlockDriverState *bdrv_all_find_vmstate_bs(void) + +BlockDriverState *bdrv_all_find_vmstate_bs(const char *device, Error **errp) { bool not_found = true; BlockDriverState *bs = NULL; + AioContext *ctx; + + if (device != NULL) { + BlockBackend *blk = blk_by_name(device); + bool can_snapshot; + + if (blk == NULL) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, + "Device '%s' not found", device); + return NULL; + } + bs = blk_bs(blk); + if (bs == NULL) { + error_setg(errp, "Device '%s' does not have block driver attached", + device); + return NULL; + } + + ctx = bdrv_get_aio_context(bs); + + aio_context_acquire(ctx); + can_snapshot = bdrv_can_snapshot(bs); + aio_context_release(ctx); + + if (!can_snapshot) { + error_setg(errp, "Device '%s' does not support snapshots", device); + return NULL; + } + return bs; + } while (not_found && (bs = bdrv_next(bs))) { - AioContext *ctx = bdrv_get_aio_context(bs); + ctx = bdrv_get_aio_context(bs); aio_context_acquire(ctx); not_found = !bdrv_can_snapshot(bs); aio_context_release(ctx); } + + if (bs == NULL) { + error_setg(errp, "No block device can accept snapshots"); + } return bs; } diff --git a/hmp.c b/hmp.c index f65bbe7..2c6a9a0 100644 --- a/hmp.c +++ b/hmp.c @@ -2405,7 +2405,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) name = name_buf; } - qmp_savevm(name, &local_err); + qmp_savevm(name, false, NULL, &local_err); if (local_err != NULL) { error_report_err(local_err); diff --git a/include/block/snapshot.h b/include/block/snapshot.h index a8506e9..a2caca9 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -91,7 +91,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, uint64_t vm_state_size, BlockDriverState **first_bad_bs); -BlockDriverState *bdrv_all_find_vmstate_bs(void); +BlockDriverState *bdrv_all_find_vmstate_bs(const char *device, Error **errp); BlockDriverState *bdrv_all_validate_snapshot(const char *name, Error **errp); #endif diff --git a/migration/savevm.c b/migration/savevm.c index fed8664..16ff92a 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1905,7 +1905,8 @@ int qemu_loadvm_state(QEMUFile *f) return ret; } -void qmp_savevm(const char *name, Error **errp) +void qmp_savevm(const char *name, bool has_device, const char *device, + Error **errp) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; @@ -1932,9 +1933,8 @@ void qmp_savevm(const char *name, Error **errp) return; } - bs = bdrv_all_find_vmstate_bs(); + bs = bdrv_all_find_vmstate_bs(has_device ? device : NULL, errp); if (bs == NULL) { - error_setg(errp, "No block device can accept snapshots"); return; } aio_context = bdrv_get_aio_context(bs); @@ -2097,10 +2097,11 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) int total; int *available_snapshots; AioContext *aio_context; + Error *local_err = NULL; - bs = bdrv_all_find_vmstate_bs(); + bs = bdrv_all_find_vmstate_bs(NULL, &local_err); if (!bs) { - monitor_printf(mon, "No available block device supports snapshots\n"); + error_report_err(local_err); return; } aio_context = bdrv_get_aio_context(bs); diff --git a/qapi-schema.json b/qapi-schema.json index 7d48948..cd6d97f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4061,12 +4061,13 @@ # Save a VM snapshot. Old snapshot with the same name will be deleted if exists. # # @name: identifier of a snapshot to be created +# @device: #optional device name to save VM state to # # Returns: Nothing on success # # Since 2.6 ## -{ 'command': 'savevm', 'data': {'name': 'str'} } +{ 'command': 'savevm', 'data': {'name': 'str', '*device': 'str'} } ## # @delvm diff --git a/qmp-commands.hx b/qmp-commands.hx index 9cd1bfe..9133f2c 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -4807,17 +4807,19 @@ Save a VM snapshot. Old snapshot with the same name will be deleted if exists. Arguments: - "name": snapshot name +- "device": block device name Example: --> { "execute": "savevm", "arguments": { "name": "snapshot1" } } +-> { "execute": "savevm", + "arguments": { "name": "snapshot1", "device": "ide1-hd0" } } <- { "return": {} } EQMP { .name = "savevm", - .args_type = "name:s", + .args_type = "name:s,device:s?", .mhandler.cmd_new = qmp_marshal_savevm, },