From patchwork Thu Jul 2 17:57:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1321850 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=VCMBmSDu; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49yQnv3FJqz9sR4 for ; Fri, 3 Jul 2020 03:58:59 +1000 (AEST) Received: from localhost ([::1]:46946 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jr3U9-0001Z7-4v for incoming@patchwork.ozlabs.org; Thu, 02 Jul 2020 13:58:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54426) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jr3TX-0001XF-I9 for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:19 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:37557 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jr3TV-0003jp-Vp for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593712697; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+CXzYGuVtqvHVMxEYvuLtxepd9vfXyPQ+wABj5DhglU=; b=VCMBmSDubdxcpHkBkwfxJFbpNjH+C2yVNVeKni6K+ak9vB4Dqr2krvUrNOcK1GsZkzCDbe i4Tha9eKXfolcn3vMwR7POAykhirWXWljTeS71NsFcefpZ4tbAlVrUZFaU8nncARD8Qf2i BZA77lSgcv1/8/NpJE+mI/nZAdK33aw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-243-z665boTwOSeoedif6oMjUA-1; Thu, 02 Jul 2020 13:58:13 -0400 X-MC-Unique: z665boTwOSeoedif6oMjUA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 951E6800C64; Thu, 2 Jul 2020 17:58:12 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9FE5D75550; Thu, 2 Jul 2020 17:58:00 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 1/6] migration: improve error reporting of block driver state name Date: Thu, 2 Jul 2020 18:57:49 +0100 Message-Id: <20200702175754.2211821-2-berrange@redhat.com> In-Reply-To: <20200702175754.2211821-1-berrange@redhat.com> References: <20200702175754.2211821-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/02 04:18:28 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Krempa , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Markus Armbruster , Pavel Dovgalyuk , Paolo Bonzini , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" With blockdev, a BlockDriverState may not have an device name, so using a node name is required as an alternative. Signed-off-by: Daniel P. Berrangé Reviewed-by: Eric Blake --- migration/savevm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/migration/savevm.c b/migration/savevm.c index b979ea6e7f..72dbad95ed 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2648,7 +2648,7 @@ int save_snapshot(const char *name, Error **errp) if (!bdrv_all_can_snapshot(&bs)) { error_setg(errp, "Device '%s' is writable but does not support " - "snapshots", bdrv_get_device_name(bs)); + "snapshots", bdrv_get_device_or_node_name(bs)); return ret; } @@ -2657,7 +2657,7 @@ int save_snapshot(const char *name, Error **errp) ret = bdrv_all_delete_snapshot(name, &bs1, errp); if (ret < 0) { error_prepend(errp, "Error while deleting snapshot on device " - "'%s': ", bdrv_get_device_name(bs1)); + "'%s': ", bdrv_get_device_or_node_name(bs1)); return ret; } } @@ -2728,7 +2728,7 @@ int save_snapshot(const char *name, Error **errp) ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, &bs); if (ret < 0) { error_setg(errp, "Error while creating snapshot on '%s'", - bdrv_get_device_name(bs)); + bdrv_get_device_or_node_name(bs)); goto the_end; } @@ -2846,14 +2846,14 @@ int load_snapshot(const char *name, Error **errp) if (!bdrv_all_can_snapshot(&bs)) { error_setg(errp, "Device '%s' is writable but does not support snapshots", - bdrv_get_device_name(bs)); + bdrv_get_device_or_node_name(bs)); return -ENOTSUP; } ret = bdrv_all_find_snapshot(name, &bs); if (ret < 0) { error_setg(errp, "Device '%s' does not have the requested snapshot '%s'", - bdrv_get_device_name(bs), name); + bdrv_get_device_or_node_name(bs), name); return ret; } @@ -2882,7 +2882,7 @@ int load_snapshot(const char *name, Error **errp) ret = bdrv_all_goto_snapshot(name, &bs, errp); if (ret < 0) { error_prepend(errp, "Could not load snapshot '%s' on '%s': ", - name, bdrv_get_device_name(bs)); + name, bdrv_get_device_or_node_name(bs)); goto err_drain; } From patchwork Thu Jul 2 17:57:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1321851 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=beJe3wmo; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49yQnx4w5wz9sR4 for ; Fri, 3 Jul 2020 03:59:01 +1000 (AEST) Received: from localhost ([::1]:47074 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jr3UB-0001cp-D0 for incoming@patchwork.ozlabs.org; Thu, 02 Jul 2020 13:58:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54450) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jr3TZ-0001aH-JT for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:21 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:54861 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jr3TX-0003jy-NN for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593712698; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m/KbAh7YIy0hQqSIXEtGCgEiFAmAOg4VajFO8j8Qfd0=; b=beJe3wmowNDpna3A9w75roFho74g1EKVi2qgk4XaTqQuZEhnImEWT/lYtWmmTH4fcVqxa/ 9RSIlNUUxwf524bnMXyP53lkOYvOioW2i7GOXOmNd4V4gJQT5LWpZz8FhHgWfF1gY7LzXs TpwJLQmhai0td4p5PRm/wvmwt4yYeQU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-372-0-VGJiDFPeervNVqmd3eRQ-1; Thu, 02 Jul 2020 13:58:17 -0400 X-MC-Unique: 0-VGJiDFPeervNVqmd3eRQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5857C8031F6; Thu, 2 Jul 2020 17:58:16 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id E3D1B7554F; Thu, 2 Jul 2020 17:58:12 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 2/6] migration: introduce savevm, loadvm, delvm QMP commands Date: Thu, 2 Jul 2020 18:57:50 +0100 Message-Id: <20200702175754.2211821-3-berrange@redhat.com> In-Reply-To: <20200702175754.2211821-1-berrange@redhat.com> References: <20200702175754.2211821-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/02 04:00:43 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Krempa , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Markus Armbruster , Pavel Dovgalyuk , Paolo Bonzini , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" savevm, loadvm and delvm are some of the few commands that have never been converted to use QMP. The primary reason for this lack of conversion is that they block execution of the thread for as long as they run. Despite this downside, however, libvirt and applications using libvirt has used these commands for as long as QMP has existed, via the "human-monitor-command" passthrough command. IOW, while it is clearly desirable to be able to fix the blocking problem, this is not an immediate obstacle to real world usage. Meanwhile there is a need for other features which involve adding new parameters to the commands. This is possible with HMP passthrough, but it provides no reliable way for apps to introspect features, so using QAPI modelling is highly desirable. This patch thus introduces trival savevm, loadvm, delvm commands to QMP that are functionally identical to the HMP counterpart, including the blocking problem. Signed-off-by: Daniel P. Berrangé --- migration/savevm.c | 27 ++++++++++++++++ monitor/hmp-cmds.c | 18 ++--------- qapi/migration.json | 76 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 15 deletions(-) diff --git a/migration/savevm.c b/migration/savevm.c index 72dbad95ed..53586a6406 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2943,3 +2943,30 @@ bool vmstate_check_only_migratable(const VMStateDescription *vmsd) return !(vmsd && vmsd->unmigratable); } + +void qmp_savevm(const char *tag, Error **errp) +{ + save_snapshot(tag, errp); +} + +void qmp_loadvm(const char *tag, Error **errp) +{ + int saved_vm_running = runstate_is_running(); + + vm_stop(RUN_STATE_RESTORE_VM); + + if (load_snapshot(tag, errp) == 0 && saved_vm_running) { + vm_start(); + } +} + +void qmp_delvm(const char *tag, Error **errp) +{ + BlockDriverState *bs; + + if (bdrv_all_delete_snapshot(tag, &bs, errp) < 0) { + error_prepend(errp, + "deleting snapshot on device '%s': ", + bdrv_get_device_or_node_name(bs)); + } +} diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 2b0b58a336..26a5a1a701 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1089,15 +1089,9 @@ void hmp_balloon(Monitor *mon, const QDict *qdict) void hmp_loadvm(Monitor *mon, const QDict *qdict) { - int saved_vm_running = runstate_is_running(); - const char *name = qdict_get_str(qdict, "name"); Error *err = NULL; - vm_stop(RUN_STATE_RESTORE_VM); - - if (load_snapshot(name, &err) == 0 && saved_vm_running) { - vm_start(); - } + qmp_loadvm(qdict_get_str(qdict, "name"), &err); hmp_handle_error(mon, err); } @@ -1105,21 +1099,15 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - save_snapshot(qdict_get_try_str(qdict, "name"), &err); + qmp_savevm(qdict_get_try_str(qdict, "name"), &err); hmp_handle_error(mon, err); } void hmp_delvm(Monitor *mon, const QDict *qdict) { - BlockDriverState *bs; Error *err = NULL; - const char *name = qdict_get_str(qdict, "name"); - if (bdrv_all_delete_snapshot(name, &bs, &err) < 0) { - error_prepend(&err, - "deleting snapshot on device '%s': ", - bdrv_get_device_name(bs)); - } + qmp_delvm(qdict_get_str(qdict, "name"), &err); hmp_handle_error(mon, err); } diff --git a/qapi/migration.json b/qapi/migration.json index d5000558c6..849de38fb0 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1621,3 +1621,79 @@ ## { 'event': 'UNPLUG_PRIMARY', 'data': { 'device-id': 'str' } } + +## +# @savevm: +# +# Save a VM snapshot +# +# @tag: name of the snapshot to create. If it already +# exists it will be replaced. +# +# Note that execution of the VM will be paused during the time +# it takes to save the snapshot +# +# Returns: nothing +# +# Example: +# +# -> { "execute": "savevm", +# "data": { +# "tag": "my-snap" +# } +# } +# <- { "return": { } } +# +# Since: 5.2 +## +{ 'command': 'savevm', + 'data': { 'tag': 'str' } } + +## +# @loadvm: +# +# Load a VM snapshot +# +# @tag: name of the snapshot to load. +# +# Returns: nothing +# +# Example: +# +# -> { "execute": "loadvm", +# "data": { +# "tag": "my-snap" +# } +# } +# <- { "return": { } } +# +# Since: 5.2 +## +{ 'command': 'loadvm', + 'data': { 'tag': 'str' } } + +## +# @delvm: +# +# Delete a VM snapshot +# +# @tag: name of the snapshot to delete. +# +# Note that execution of the VM will be paused during the time +# it takes to delete the snapshot +# +# Returns: nothing +# +# Example: +# +# -> { "execute": "delvm", +# "data": { +# "tag": "my-snap" +# } +# } +# <- { "return": { } } +# +# Since: 5.2 +## +{ 'command': 'delvm', + 'data': { 'tag': 'str' } } From patchwork Thu Jul 2 17:57:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1321854 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dM1ktG3o; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49yQrT6YgQz9sR4 for ; Fri, 3 Jul 2020 04:01:13 +1000 (AEST) Received: from localhost ([::1]:53564 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jr3WJ-0004cf-Bx for incoming@patchwork.ozlabs.org; Thu, 02 Jul 2020 14:01:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54496) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jr3Tj-0001xC-KA for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:31 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:44041 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jr3Th-0003kg-DQ for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593712708; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7HPFMl02Y9MD4a4CgpIrdA3TQqVD3NTJ3aR1ejGSUMI=; b=dM1ktG3o6dVWj3HJQZuSbLSQBHBO2joGdQTa+z5+B5pbzQeYnLzncNpgphmdF+omelUzXU fSa5QlLKAU7rIHfw/WlED6NQPROZ856/e9Fj+qRi2WO3SSHoX48THk5OWVJ+TqdQSMlxsa I5QJwJqi0XPKOjQ9u0KAFsUY05+Zqbw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-319-FQVN0H24Np-A8zuE12P91w-1; Thu, 02 Jul 2020 13:58:24 -0400 X-MC-Unique: FQVN0H24Np-A8zuE12P91w-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6C6CE10059AB; Thu, 2 Jul 2020 17:58:22 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id A36465D9CA; Thu, 2 Jul 2020 17:58:16 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 3/6] block: add ability to filter out blockdevs during snapshot Date: Thu, 2 Jul 2020 18:57:51 +0100 Message-Id: <20200702175754.2211821-4-berrange@redhat.com> In-Reply-To: <20200702175754.2211821-1-berrange@redhat.com> References: <20200702175754.2211821-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/02 03:23:40 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Krempa , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Markus Armbruster , Pavel Dovgalyuk , Paolo Bonzini , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" When executing snapshot logic, currently blockdevs are filtered out if they are read-only or if there is no media present. In order to support snapshotting when UEFI firmware is in use, we need the ability to filter out the blockdev used for the firmware vars store. This can be achieved by having a list of node names that should be excluded from consideration for snapshots. Signed-off-by: Daniel P. Berrangé --- block/monitor/block-hmp-cmds.c | 4 ++-- block/snapshot.c | 41 ++++++++++++++++++++++------------ include/block/snapshot.h | 19 +++++++++------- migration/savevm.c | 18 +++++++-------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 4c8c375172..0ee6e7a4be 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -899,7 +899,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) ImageEntry *image_entry, *next_ie; SnapshotEntry *snapshot_entry; - bs = bdrv_all_find_vmstate_bs(); + bs = bdrv_all_find_vmstate_bs(NULL); if (!bs) { monitor_printf(mon, "No available block device supports snapshots\n"); return; @@ -951,7 +951,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) total = 0; for (i = 0; i < nb_sns; i++) { SnapshotEntry *next_sn; - if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) { + if (bdrv_all_find_snapshot(sn_tab[i].name, NULL, &bs1) == 0) { global_snapshots[total] = i; total++; QTAILQ_FOREACH(image_entry, &image_list, next) { diff --git a/block/snapshot.c b/block/snapshot.c index bd9fb01817..c8950b0b86 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -385,12 +385,22 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs, return ret; } -static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs) +static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs, + strList *exclude_bs) { + const char *node_name = bdrv_get_node_name(bs); + if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { return false; } + while (exclude_bs) { + if (g_str_equal(node_name, exclude_bs->value)) { + return false; + } + exclude_bs = exclude_bs->next; + } + /* Include all nodes that are either in use by a BlockBackend, or that * aren't attached to any node, but owned by the monitor. */ return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents); @@ -400,7 +410,7 @@ static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs) * These functions will properly handle dataplane (take aio_context_acquire * when appropriate for appropriate block drivers) */ -bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs) +bool bdrv_all_can_snapshot(strList *exclude_bs, BlockDriverState **first_bad_bs) { bool ok = true; BlockDriverState *bs; @@ -410,7 +420,7 @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs) AioContext *ctx = bdrv_get_aio_context(bs); aio_context_acquire(ctx); - if (bdrv_all_snapshots_includes_bs(bs)) { + if (bdrv_all_snapshots_includes_bs(bs, exclude_bs)) { ok = bdrv_can_snapshot(bs); } aio_context_release(ctx); @@ -425,8 +435,8 @@ fail: return ok; } -int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs, - Error **errp) +int bdrv_all_delete_snapshot(const char *name, strList *exclude_bs, + BlockDriverState **first_bad_bs, Error **errp) { int ret = 0; BlockDriverState *bs; @@ -437,7 +447,7 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs, AioContext *ctx = bdrv_get_aio_context(bs); aio_context_acquire(ctx); - if (bdrv_all_snapshots_includes_bs(bs) && + if (bdrv_all_snapshots_includes_bs(bs, exclude_bs) && bdrv_snapshot_find(bs, snapshot, name) >= 0) { ret = bdrv_snapshot_delete(bs, snapshot->id_str, @@ -456,8 +466,8 @@ fail: } -int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs, - Error **errp) +int bdrv_all_goto_snapshot(const char *name, strList *exclude_bs, + BlockDriverState **first_bad_bs, Error **errp) { int ret = 0; BlockDriverState *bs; @@ -467,7 +477,7 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs, AioContext *ctx = bdrv_get_aio_context(bs); aio_context_acquire(ctx); - if (bdrv_all_snapshots_includes_bs(bs)) { + if (bdrv_all_snapshots_includes_bs(bs, exclude_bs)) { ret = bdrv_snapshot_goto(bs, name, errp); } aio_context_release(ctx); @@ -482,7 +492,8 @@ fail: return ret; } -int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs) +int bdrv_all_find_snapshot(const char *name, strList *exclude_bs, + BlockDriverState **first_bad_bs) { QEMUSnapshotInfo sn; int err = 0; @@ -493,7 +504,7 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs) AioContext *ctx = bdrv_get_aio_context(bs); aio_context_acquire(ctx); - if (bdrv_all_snapshots_includes_bs(bs)) { + if (bdrv_all_snapshots_includes_bs(bs, exclude_bs)) { err = bdrv_snapshot_find(bs, &sn, name); } aio_context_release(ctx); @@ -511,6 +522,7 @@ fail: int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, BlockDriverState *vm_state_bs, uint64_t vm_state_size, + strList *exclude_bs, BlockDriverState **first_bad_bs) { int err = 0; @@ -524,7 +536,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, if (bs == vm_state_bs) { sn->vm_state_size = vm_state_size; err = bdrv_snapshot_create(bs, sn); - } else if (bdrv_all_snapshots_includes_bs(bs)) { + } else if (bdrv_all_snapshots_includes_bs(bs, exclude_bs)) { sn->vm_state_size = 0; err = bdrv_snapshot_create(bs, sn); } @@ -540,7 +552,7 @@ fail: return err; } -BlockDriverState *bdrv_all_find_vmstate_bs(void) +BlockDriverState *bdrv_all_find_vmstate_bs(strList *exclude_bs) { BlockDriverState *bs; BdrvNextIterator it; @@ -550,7 +562,8 @@ BlockDriverState *bdrv_all_find_vmstate_bs(void) bool found; aio_context_acquire(ctx); - found = bdrv_all_snapshots_includes_bs(bs) && bdrv_can_snapshot(bs); + found = bdrv_all_snapshots_includes_bs(bs, exclude_bs) && + bdrv_can_snapshot(bs); aio_context_release(ctx); if (found) { diff --git a/include/block/snapshot.h b/include/block/snapshot.h index 2bfcd57578..f20986ca37 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -25,7 +25,7 @@ #ifndef SNAPSHOT_H #define SNAPSHOT_H - +#include "qapi/qapi-builtin-types.h" #define SNAPSHOT_OPT_BASE "snapshot." #define SNAPSHOT_OPT_ID "snapshot.id" @@ -76,17 +76,20 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs, * These functions will properly handle dataplane (take aio_context_acquire * when appropriate for appropriate block drivers */ -bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs); -int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bsd_bs, - Error **errp); -int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs, - Error **errp); -int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs); +bool bdrv_all_can_snapshot(strList *exclude_bs, + BlockDriverState **first_bad_bs); +int bdrv_all_delete_snapshot(const char *name, strList *exclude_bs, + BlockDriverState **first_bsd_bs, Error **errp); +int bdrv_all_goto_snapshot(const char *name, strList *exclude_bs, + BlockDriverState **first_bad_bs, Error **errp); +int bdrv_all_find_snapshot(const char *name, strList *exclude_bs, + BlockDriverState **first_bad_bs); int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, BlockDriverState *vm_state_bs, uint64_t vm_state_size, + strList *exclude_bs, BlockDriverState **first_bad_bs); -BlockDriverState *bdrv_all_find_vmstate_bs(void); +BlockDriverState *bdrv_all_find_vmstate_bs(strList *exclude_bs); #endif diff --git a/migration/savevm.c b/migration/savevm.c index 53586a6406..4251aa0dde 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2646,7 +2646,7 @@ int save_snapshot(const char *name, Error **errp) return ret; } - if (!bdrv_all_can_snapshot(&bs)) { + if (!bdrv_all_can_snapshot(NULL, &bs)) { error_setg(errp, "Device '%s' is writable but does not support " "snapshots", bdrv_get_device_or_node_name(bs)); return ret; @@ -2654,7 +2654,7 @@ int save_snapshot(const char *name, Error **errp) /* Delete old snapshots of the same name */ if (name) { - ret = bdrv_all_delete_snapshot(name, &bs1, errp); + ret = bdrv_all_delete_snapshot(name, NULL, &bs1, errp); if (ret < 0) { error_prepend(errp, "Error while deleting snapshot on device " "'%s': ", bdrv_get_device_or_node_name(bs1)); @@ -2662,7 +2662,7 @@ int save_snapshot(const char *name, Error **errp) } } - bs = bdrv_all_find_vmstate_bs(); + bs = bdrv_all_find_vmstate_bs(NULL); if (bs == NULL) { error_setg(errp, "No block device can accept snapshots"); return ret; @@ -2725,7 +2725,7 @@ int save_snapshot(const char *name, Error **errp) aio_context_release(aio_context); aio_context = NULL; - ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, &bs); + ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, NULL, &bs); if (ret < 0) { error_setg(errp, "Error while creating snapshot on '%s'", bdrv_get_device_or_node_name(bs)); @@ -2843,13 +2843,13 @@ int load_snapshot(const char *name, Error **errp) return -EINVAL; } - if (!bdrv_all_can_snapshot(&bs)) { + if (!bdrv_all_can_snapshot(NULL, &bs)) { error_setg(errp, "Device '%s' is writable but does not support snapshots", bdrv_get_device_or_node_name(bs)); return -ENOTSUP; } - ret = bdrv_all_find_snapshot(name, &bs); + ret = bdrv_all_find_snapshot(name, NULL, &bs); if (ret < 0) { error_setg(errp, "Device '%s' does not have the requested snapshot '%s'", @@ -2857,7 +2857,7 @@ int load_snapshot(const char *name, Error **errp) return ret; } - bs_vm_state = bdrv_all_find_vmstate_bs(); + bs_vm_state = bdrv_all_find_vmstate_bs(NULL); if (!bs_vm_state) { error_setg(errp, "No block device supports snapshots"); return -ENOTSUP; @@ -2879,7 +2879,7 @@ int load_snapshot(const char *name, Error **errp) /* Flush all IO requests so they don't interfere with the new state. */ bdrv_drain_all_begin(); - ret = bdrv_all_goto_snapshot(name, &bs, errp); + ret = bdrv_all_goto_snapshot(name, NULL, &bs, errp); if (ret < 0) { error_prepend(errp, "Could not load snapshot '%s' on '%s': ", name, bdrv_get_device_or_node_name(bs)); @@ -2964,7 +2964,7 @@ void qmp_delvm(const char *tag, Error **errp) { BlockDriverState *bs; - if (bdrv_all_delete_snapshot(tag, &bs, errp) < 0) { + if (bdrv_all_delete_snapshot(tag, NULL, &bs, errp) < 0) { error_prepend(errp, "deleting snapshot on device '%s': ", bdrv_get_device_or_node_name(bs)); From patchwork Thu Jul 2 17:57:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1321853 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YhheYWls; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49yQrG1Pq7z9sSt for ; Fri, 3 Jul 2020 04:01:02 +1000 (AEST) Received: from localhost ([::1]:52980 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jr3W7-00048T-LO for incoming@patchwork.ozlabs.org; Thu, 02 Jul 2020 14:00:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54516) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jr3Tl-0001zz-35 for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:33 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:46202 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jr3Th-0003km-VG for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593712709; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2cnqQ9SUpodkmHJ9GHvFF4TamKwzMWJAZH9j3FPdITc=; b=YhheYWlsroAoJSoQWntmH0VVL1i0iGPc9tPcinzTmKqTxnvMs2WzWYdYKlzog+hye6BiAk nkDARXouJrU5EIo16a1XzFgd9oDc86jqGbzmTuw4NbgTodV7eZfGeRX/W0YHwnzlUCzvEa AtSBTQHS2J0Yyr0PnU+MSJjtp8jvRoM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-376-nXeHgWiqO8CVO-Q3bcn27g-1; Thu, 02 Jul 2020 13:58:27 -0400 X-MC-Unique: nXeHgWiqO8CVO-Q3bcn27g-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 509CC8031F6; Thu, 2 Jul 2020 17:58:26 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id B91945D9CA; Thu, 2 Jul 2020 17:58:22 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 4/6] block: allow specifying name of block device for vmstate storage Date: Thu, 2 Jul 2020 18:57:52 +0100 Message-Id: <20200702175754.2211821-5-berrange@redhat.com> In-Reply-To: <20200702175754.2211821-1-berrange@redhat.com> References: <20200702175754.2211821-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/02 04:00:43 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Krempa , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Markus Armbruster , Pavel Dovgalyuk , Paolo Bonzini , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Currently the vmstate will be stored in the first block device that supports snapshots. Historically this would have usually been the root device, but with UEFI it might be the variable store. There needs to be a way to override the choice of block device to store the state in. Signed-off-by: Daniel P. Berrangé --- block/monitor/block-hmp-cmds.c | 2 +- block/snapshot.c | 33 +++++++++++++++++++++++++++++---- include/block/snapshot.h | 4 +++- migration/savevm.c | 6 ++---- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 0ee6e7a4be..a698fac027 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -899,7 +899,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) ImageEntry *image_entry, *next_ie; SnapshotEntry *snapshot_entry; - bs = bdrv_all_find_vmstate_bs(NULL); + bs = bdrv_all_find_vmstate_bs(NULL, NULL, NULL); if (!bs) { monitor_printf(mon, "No available block device supports snapshots\n"); return; diff --git a/block/snapshot.c b/block/snapshot.c index c8950b0b86..4774a1890d 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -552,7 +552,9 @@ fail: return err; } -BlockDriverState *bdrv_all_find_vmstate_bs(strList *exclude_bs) +BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs, + strList *exclude_bs, + Error **errp) { BlockDriverState *bs; BdrvNextIterator it; @@ -560,16 +562,39 @@ BlockDriverState *bdrv_all_find_vmstate_bs(strList *exclude_bs) for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { AioContext *ctx = bdrv_get_aio_context(bs); bool found; + Error *err = NULL; aio_context_acquire(ctx); - found = bdrv_all_snapshots_includes_bs(bs, exclude_bs) && - bdrv_can_snapshot(bs); + if (vmstate_bs == NULL) { + found = bdrv_all_snapshots_includes_bs(bs, exclude_bs) && + bdrv_can_snapshot(bs); + } else { + if (g_str_equal(vmstate_bs, bdrv_get_node_name(bs))) { + found = bdrv_all_snapshots_includes_bs(bs, exclude_bs) && + bdrv_can_snapshot(bs); + if (!found) { + error_setg(&err, + "block device '%s' cannot accept snapshots", + vmstate_bs); + } + } else { + found = false; + } + } aio_context_release(ctx); - if (found) { + if (found || err) { bdrv_next_cleanup(&it); + if (err) { + error_propagate(errp, err); + return NULL; + } break; } } + + if (!bs) { + error_setg(errp, "No block device can accept snapshots"); + } return bs; } diff --git a/include/block/snapshot.h b/include/block/snapshot.h index f20986ca37..ff627df5cb 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -90,6 +90,8 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, strList *exclude_bs, BlockDriverState **first_bad_bs); -BlockDriverState *bdrv_all_find_vmstate_bs(strList *exclude_bs); +BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs, + strList *exclude_bs, + Error **errp); #endif diff --git a/migration/savevm.c b/migration/savevm.c index 4251aa0dde..b11c6a882d 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2662,9 +2662,8 @@ int save_snapshot(const char *name, Error **errp) } } - bs = bdrv_all_find_vmstate_bs(NULL); + bs = bdrv_all_find_vmstate_bs(NULL, NULL, errp); if (bs == NULL) { - error_setg(errp, "No block device can accept snapshots"); return ret; } aio_context = bdrv_get_aio_context(bs); @@ -2857,9 +2856,8 @@ int load_snapshot(const char *name, Error **errp) return ret; } - bs_vm_state = bdrv_all_find_vmstate_bs(NULL); + bs_vm_state = bdrv_all_find_vmstate_bs(NULL, NULL, errp); if (!bs_vm_state) { - error_setg(errp, "No block device supports snapshots"); return -ENOTSUP; } aio_context = bdrv_get_aio_context(bs_vm_state); From patchwork Thu Jul 2 17:57:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1321855 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dFn49tGR; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49yQvW1Ff8z9sSd for ; Fri, 3 Jul 2020 04:03:49 +1000 (AEST) Received: from localhost ([::1]:34588 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jr3Yn-0000Uc-Jr for incoming@patchwork.ozlabs.org; Thu, 02 Jul 2020 14:03:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54530) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jr3To-00027q-2o for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:36 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:47035 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jr3Tl-0003lM-S8 for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593712713; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tWV/1I/IjGPsoIAyNec9bR5w4pDHH9o9N+zoRMO4Jdw=; b=dFn49tGR9DaRl6vk7RiXGt2zZVm8HmWH2dMiZ9nAYW/WJ1ThAecbm0AJRi8X4J/o9V0XMJ h4gPlyExcyItW5riPM+3q5JaiK6ltUxeYlCWuRxk1ocpspng0oUUCfkWM2beU3tZtKtr6P zgyGodRqXIgf1iDeNOvPZJW6PsRpQ7w= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-287-jafgEZnzMAuxqUy91tq4fw-1; Thu, 02 Jul 2020 13:58:31 -0400 X-MC-Unique: jafgEZnzMAuxqUy91tq4fw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4F3A8107ACCD; Thu, 2 Jul 2020 17:58:30 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id A6BF95D9CA; Thu, 2 Jul 2020 17:58:26 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 5/6] migration: support excluding block devs in QMP snapshot commands Date: Thu, 2 Jul 2020 18:57:53 +0100 Message-Id: <20200702175754.2211821-6-berrange@redhat.com> In-Reply-To: <20200702175754.2211821-1-berrange@redhat.com> References: <20200702175754.2211821-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/02 03:23:40 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Krempa , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Markus Armbruster , Pavel Dovgalyuk , Paolo Bonzini , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This wires up support for a new "exclude" parameter to the QMP commands for snapshots (savevm, loadvm, delvm). This parameter accepts a list of block driver state node names. One use case for this would be a VM using OVMF firmware where the variables store is a raw disk image. Ideally the variable store would be qcow2, allowing its contents to be included in the snapshot, but typically today the variable store is raw. It is still useful to be able to snapshot VMs using OVMF, even if the varstore is excluded, as the main OS disk content is usually the stuff the user cares about. Signed-off-by: Daniel P. Berrangé --- include/migration/snapshot.h | 6 ++++-- migration/savevm.c | 38 +++++++++++++++++++++--------------- monitor/hmp-cmds.c | 6 +++--- qapi/migration.json | 21 ++++++++++++++------ replay/replay-snapshot.c | 4 ++-- softmmu/vl.c | 2 +- 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/include/migration/snapshot.h b/include/migration/snapshot.h index c85b6ec75b..dffb84dbe5 100644 --- a/include/migration/snapshot.h +++ b/include/migration/snapshot.h @@ -15,7 +15,9 @@ #ifndef QEMU_MIGRATION_SNAPSHOT_H #define QEMU_MIGRATION_SNAPSHOT_H -int save_snapshot(const char *name, Error **errp); -int load_snapshot(const char *name, Error **errp); +#include "qapi/qapi-builtin-types.h" + +int save_snapshot(const char *name, strList *exclude, Error **errp); +int load_snapshot(const char *name, strList *exclude, Error **errp); #endif diff --git a/migration/savevm.c b/migration/savevm.c index b11c6a882d..4b040676f7 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2624,7 +2624,7 @@ int qemu_load_device_state(QEMUFile *f) return 0; } -int save_snapshot(const char *name, Error **errp) +int save_snapshot(const char *name, strList *exclude, Error **errp) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; @@ -2646,7 +2646,7 @@ int save_snapshot(const char *name, Error **errp) return ret; } - if (!bdrv_all_can_snapshot(NULL, &bs)) { + if (!bdrv_all_can_snapshot(exclude, &bs)) { error_setg(errp, "Device '%s' is writable but does not support " "snapshots", bdrv_get_device_or_node_name(bs)); return ret; @@ -2654,7 +2654,7 @@ int save_snapshot(const char *name, Error **errp) /* Delete old snapshots of the same name */ if (name) { - ret = bdrv_all_delete_snapshot(name, NULL, &bs1, errp); + ret = bdrv_all_delete_snapshot(name, exclude, &bs1, errp); if (ret < 0) { error_prepend(errp, "Error while deleting snapshot on device " "'%s': ", bdrv_get_device_or_node_name(bs1)); @@ -2662,7 +2662,7 @@ int save_snapshot(const char *name, Error **errp) } } - bs = bdrv_all_find_vmstate_bs(NULL, NULL, errp); + bs = bdrv_all_find_vmstate_bs(NULL, exclude, errp); if (bs == NULL) { return ret; } @@ -2724,7 +2724,7 @@ int save_snapshot(const char *name, Error **errp) aio_context_release(aio_context); aio_context = NULL; - ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, NULL, &bs); + ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, exclude, &bs); if (ret < 0) { error_setg(errp, "Error while creating snapshot on '%s'", bdrv_get_device_or_node_name(bs)); @@ -2827,7 +2827,7 @@ void qmp_xen_load_devices_state(const char *filename, Error **errp) migration_incoming_state_destroy(); } -int load_snapshot(const char *name, Error **errp) +int load_snapshot(const char *name, strList *exclude, Error **errp) { BlockDriverState *bs, *bs_vm_state; QEMUSnapshotInfo sn; @@ -2842,13 +2842,13 @@ int load_snapshot(const char *name, Error **errp) return -EINVAL; } - if (!bdrv_all_can_snapshot(NULL, &bs)) { + if (!bdrv_all_can_snapshot(exclude, &bs)) { error_setg(errp, "Device '%s' is writable but does not support snapshots", bdrv_get_device_or_node_name(bs)); return -ENOTSUP; } - ret = bdrv_all_find_snapshot(name, NULL, &bs); + ret = bdrv_all_find_snapshot(name, exclude, &bs); if (ret < 0) { error_setg(errp, "Device '%s' does not have the requested snapshot '%s'", @@ -2856,7 +2856,7 @@ int load_snapshot(const char *name, Error **errp) return ret; } - bs_vm_state = bdrv_all_find_vmstate_bs(NULL, NULL, errp); + bs_vm_state = bdrv_all_find_vmstate_bs(NULL, exclude, errp); if (!bs_vm_state) { return -ENOTSUP; } @@ -2877,7 +2877,7 @@ int load_snapshot(const char *name, Error **errp) /* Flush all IO requests so they don't interfere with the new state. */ bdrv_drain_all_begin(); - ret = bdrv_all_goto_snapshot(name, NULL, &bs, errp); + ret = bdrv_all_goto_snapshot(name, exclude, &bs, errp); if (ret < 0) { error_prepend(errp, "Could not load snapshot '%s' on '%s': ", name, bdrv_get_device_or_node_name(bs)); @@ -2942,27 +2942,33 @@ bool vmstate_check_only_migratable(const VMStateDescription *vmsd) return !(vmsd && vmsd->unmigratable); } -void qmp_savevm(const char *tag, Error **errp) +void qmp_savevm(const char *tag, + bool has_exclude, strList *exclude, + Error **errp) { - save_snapshot(tag, errp); + save_snapshot(tag, exclude, errp); } -void qmp_loadvm(const char *tag, Error **errp) +void qmp_loadvm(const char *tag, + bool has_exclude, strList *exclude, + Error **errp) { int saved_vm_running = runstate_is_running(); vm_stop(RUN_STATE_RESTORE_VM); - if (load_snapshot(tag, errp) == 0 && saved_vm_running) { + if (load_snapshot(tag, exclude, errp) == 0 && saved_vm_running) { vm_start(); } } -void qmp_delvm(const char *tag, Error **errp) +void qmp_delvm(const char *tag, + bool has_exclude, strList *exclude, + Error **errp) { BlockDriverState *bs; - if (bdrv_all_delete_snapshot(tag, NULL, &bs, errp) < 0) { + if (bdrv_all_delete_snapshot(tag, exclude, &bs, errp) < 0) { error_prepend(errp, "deleting snapshot on device '%s': ", bdrv_get_device_or_node_name(bs)); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 26a5a1a701..fcde649100 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1091,7 +1091,7 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - qmp_loadvm(qdict_get_str(qdict, "name"), &err); + qmp_loadvm(qdict_get_str(qdict, "name"), false, NULL, &err); hmp_handle_error(mon, err); } @@ -1099,7 +1099,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - qmp_savevm(qdict_get_try_str(qdict, "name"), &err); + qmp_savevm(qdict_get_try_str(qdict, "name"), false, NULL, &err); hmp_handle_error(mon, err); } @@ -1107,7 +1107,7 @@ void hmp_delvm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - qmp_delvm(qdict_get_str(qdict, "name"), &err); + qmp_delvm(qdict_get_str(qdict, "name"), false, NULL, &err); hmp_handle_error(mon, err); } diff --git a/qapi/migration.json b/qapi/migration.json index 849de38fb0..2388664077 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1629,6 +1629,7 @@ # # @tag: name of the snapshot to create. If it already # exists it will be replaced. +# @exclude: list of block device node names to exclude # # Note that execution of the VM will be paused during the time # it takes to save the snapshot @@ -1639,7 +1640,8 @@ # # -> { "execute": "savevm", # "data": { -# "tag": "my-snap" +# "tag": "my-snap", +# "exclude": ["pflash0-vars"] # } # } # <- { "return": { } } @@ -1647,7 +1649,8 @@ # Since: 5.2 ## { 'command': 'savevm', - 'data': { 'tag': 'str' } } + 'data': { 'tag': 'str', + '*exclude': ['str'] } } ## # @loadvm: @@ -1655,6 +1658,7 @@ # Load a VM snapshot # # @tag: name of the snapshot to load. +# @exclude: list of block device node names to exclude # # Returns: nothing # @@ -1662,7 +1666,8 @@ # # -> { "execute": "loadvm", # "data": { -# "tag": "my-snap" +# "tag": "my-snap", +# "exclude": ["pflash0-vars"] # } # } # <- { "return": { } } @@ -1670,7 +1675,8 @@ # Since: 5.2 ## { 'command': 'loadvm', - 'data': { 'tag': 'str' } } + 'data': { 'tag': 'str', + '*exclude': ['str'] } } ## # @delvm: @@ -1678,6 +1684,7 @@ # Delete a VM snapshot # # @tag: name of the snapshot to delete. +# @exclude: list of block device node names to exclude # # Note that execution of the VM will be paused during the time # it takes to delete the snapshot @@ -1688,7 +1695,8 @@ # # -> { "execute": "delvm", # "data": { -# "tag": "my-snap" +# "tag": "my-snap", +# "exclude": ["pflash0-vars"] # } # } # <- { "return": { } } @@ -1696,4 +1704,5 @@ # Since: 5.2 ## { 'command': 'delvm', - 'data': { 'tag': 'str' } } + 'data': { 'tag': 'str', + '*exclude': ['str'] } } diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c index e26fa4c892..1351170c67 100644 --- a/replay/replay-snapshot.c +++ b/replay/replay-snapshot.c @@ -77,13 +77,13 @@ void replay_vmstate_init(void) if (replay_snapshot) { if (replay_mode == REPLAY_MODE_RECORD) { - if (save_snapshot(replay_snapshot, &err) != 0) { + if (save_snapshot(replay_snapshot, NULL, &err) != 0) { error_report_err(err); error_report("Could not create snapshot for icount record"); exit(1); } } else if (replay_mode == REPLAY_MODE_PLAY) { - if (load_snapshot(replay_snapshot, &err) != 0) { + if (load_snapshot(replay_snapshot, NULL, &err) != 0) { error_report_err(err); error_report("Could not load snapshot for icount replay"); exit(1); diff --git a/softmmu/vl.c b/softmmu/vl.c index 3e15ee2435..f7c8be8c6a 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -4452,7 +4452,7 @@ void qemu_init(int argc, char **argv, char **envp) register_global_state(); if (loadvm) { Error *local_err = NULL; - if (load_snapshot(loadvm, &local_err) < 0) { + if (load_snapshot(loadvm, NULL, &local_err) < 0) { error_report_err(local_err); autostart = 0; exit(1); From patchwork Thu Jul 2 17:57:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1321856 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=R4hjEZNC; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49yQx51jTvz9sR4 for ; Fri, 3 Jul 2020 04:05:13 +1000 (AEST) Received: from localhost ([::1]:36764 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jr3aB-0001hR-0h for incoming@patchwork.ozlabs.org; Thu, 02 Jul 2020 14:05:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54566) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jr3Tr-0002EW-HA for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:39 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:24718 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jr3Tp-0003mj-HQ for qemu-devel@nongnu.org; Thu, 02 Jul 2020 13:58:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593712716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NROZs6HderGG4OkHrcO2CRQWMJbU1tMrf9Vi7ZxYT0w=; b=R4hjEZNCBXlkGlMVo3WBOusWBqHBggkYUFHUFXFRVJyn62EH3cvywgwMxGbcyBkRV5r3/Y otmnHsG7FWEGyOeBy5MXWD00ESTd/dbxsGA5ufmMlgBwNeuZX67q3wYx4UljBuGXqi65aB uJ1S1+tSjZLbR15NYhMb8WwwU9/vpTw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-155-2jf1QIiKNkaz73YUukb6ag-1; Thu, 02 Jul 2020 13:58:35 -0400 X-MC-Unique: 2jf1QIiKNkaz73YUukb6ag-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 28CC5185B3B3; Thu, 2 Jul 2020 17:58:34 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id B17D25D9CA; Thu, 2 Jul 2020 17:58:30 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 6/6] migration: support picking vmstate disk in QMP snapshot commands Date: Thu, 2 Jul 2020 18:57:54 +0100 Message-Id: <20200702175754.2211821-7-berrange@redhat.com> In-Reply-To: <20200702175754.2211821-1-berrange@redhat.com> References: <20200702175754.2211821-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/02 03:23:40 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Krempa , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Markus Armbruster , Pavel Dovgalyuk , Paolo Bonzini , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This wires up support for a new "vmstate" parameter to the QMP commands for snapshots (savevm, loadvm). This parameter accepts block driver state node name. One use case for this would be a VM using OVMF firmware where the variables store is the first snapshottable disk image. The vmstate snapshot usually wants to be stored in the primary root disk of the VM, not the firmeware varstore. Thus there needs to be a mechanism to override the default choice of disk. Signed-off-by: Daniel P. Berrangé --- include/migration/snapshot.h | 8 ++++++-- migration/savevm.c | 16 ++++++++++------ monitor/hmp-cmds.c | 6 ++++-- qapi/migration.json | 6 ++++++ replay/replay-snapshot.c | 4 ++-- softmmu/vl.c | 2 +- 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/migration/snapshot.h b/include/migration/snapshot.h index dffb84dbe5..721147d3c1 100644 --- a/include/migration/snapshot.h +++ b/include/migration/snapshot.h @@ -17,7 +17,11 @@ #include "qapi/qapi-builtin-types.h" -int save_snapshot(const char *name, strList *exclude, Error **errp); -int load_snapshot(const char *name, strList *exclude, Error **errp); +int save_snapshot(const char *name, + const char *vmstate, strList *exclude, + Error **errp); +int load_snapshot(const char *name, + const char *vmstate, strList *exclude, + Error **errp); #endif diff --git a/migration/savevm.c b/migration/savevm.c index 4b040676f7..5fd593e475 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2624,7 +2624,8 @@ int qemu_load_device_state(QEMUFile *f) return 0; } -int save_snapshot(const char *name, strList *exclude, Error **errp) +int save_snapshot(const char *name, const char *vmstate, + strList *exclude, Error **errp) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; @@ -2662,7 +2663,7 @@ int save_snapshot(const char *name, strList *exclude, Error **errp) } } - bs = bdrv_all_find_vmstate_bs(NULL, exclude, errp); + bs = bdrv_all_find_vmstate_bs(vmstate, exclude, errp); if (bs == NULL) { return ret; } @@ -2827,7 +2828,8 @@ void qmp_xen_load_devices_state(const char *filename, Error **errp) migration_incoming_state_destroy(); } -int load_snapshot(const char *name, strList *exclude, Error **errp) +int load_snapshot(const char *name, const char *vmstate, + strList *exclude, Error **errp) { BlockDriverState *bs, *bs_vm_state; QEMUSnapshotInfo sn; @@ -2856,7 +2858,7 @@ int load_snapshot(const char *name, strList *exclude, Error **errp) return ret; } - bs_vm_state = bdrv_all_find_vmstate_bs(NULL, exclude, errp); + bs_vm_state = bdrv_all_find_vmstate_bs(vmstate, exclude, errp); if (!bs_vm_state) { return -ENOTSUP; } @@ -2943,13 +2945,15 @@ bool vmstate_check_only_migratable(const VMStateDescription *vmsd) } void qmp_savevm(const char *tag, + bool has_vmstate, const char *vmstate, bool has_exclude, strList *exclude, Error **errp) { - save_snapshot(tag, exclude, errp); + save_snapshot(tag, vmstate, exclude, errp); } void qmp_loadvm(const char *tag, + bool has_vmstate, const char *vmstate, bool has_exclude, strList *exclude, Error **errp) { @@ -2957,7 +2961,7 @@ void qmp_loadvm(const char *tag, vm_stop(RUN_STATE_RESTORE_VM); - if (load_snapshot(tag, exclude, errp) == 0 && saved_vm_running) { + if (load_snapshot(tag, vmstate, exclude, errp) == 0 && saved_vm_running) { vm_start(); } } diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index fcde649100..586676e179 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1091,7 +1091,8 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - qmp_loadvm(qdict_get_str(qdict, "name"), false, NULL, &err); + qmp_loadvm(qdict_get_str(qdict, "name"), + false, NULL, false, NULL, &err); hmp_handle_error(mon, err); } @@ -1099,7 +1100,8 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - qmp_savevm(qdict_get_try_str(qdict, "name"), false, NULL, &err); + qmp_savevm(qdict_get_try_str(qdict, "name"), + false, NULL, false, NULL, &err); hmp_handle_error(mon, err); } diff --git a/qapi/migration.json b/qapi/migration.json index 2388664077..91173f5b06 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1630,6 +1630,7 @@ # @tag: name of the snapshot to create. If it already # exists it will be replaced. # @exclude: list of block device node names to exclude +# @vmstate: block device node name to save vmstate to # # Note that execution of the VM will be paused during the time # it takes to save the snapshot @@ -1641,6 +1642,7 @@ # -> { "execute": "savevm", # "data": { # "tag": "my-snap", +# "vmstate": "disk0", # "exclude": ["pflash0-vars"] # } # } @@ -1650,6 +1652,7 @@ ## { 'command': 'savevm', 'data': { 'tag': 'str', + '*vmstate': 'str', '*exclude': ['str'] } } ## @@ -1659,6 +1662,7 @@ # # @tag: name of the snapshot to load. # @exclude: list of block device node names to exclude +# @vmstate: block device node name to load vmstate from # # Returns: nothing # @@ -1667,6 +1671,7 @@ # -> { "execute": "loadvm", # "data": { # "tag": "my-snap", +# "vmstate": "disk0", # "exclude": ["pflash0-vars"] # } # } @@ -1676,6 +1681,7 @@ ## { 'command': 'loadvm', 'data': { 'tag': 'str', + '*vmstate': 'str', '*exclude': ['str'] } } ## diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c index 1351170c67..f0f45a4f24 100644 --- a/replay/replay-snapshot.c +++ b/replay/replay-snapshot.c @@ -77,13 +77,13 @@ void replay_vmstate_init(void) if (replay_snapshot) { if (replay_mode == REPLAY_MODE_RECORD) { - if (save_snapshot(replay_snapshot, NULL, &err) != 0) { + if (save_snapshot(replay_snapshot, NULL, NULL, &err) != 0) { error_report_err(err); error_report("Could not create snapshot for icount record"); exit(1); } } else if (replay_mode == REPLAY_MODE_PLAY) { - if (load_snapshot(replay_snapshot, NULL, &err) != 0) { + if (load_snapshot(replay_snapshot, NULL, NULL, &err) != 0) { error_report_err(err); error_report("Could not load snapshot for icount replay"); exit(1); diff --git a/softmmu/vl.c b/softmmu/vl.c index f7c8be8c6a..fbaa326675 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -4452,7 +4452,7 @@ void qemu_init(int argc, char **argv, char **envp) register_global_state(); if (loadvm) { Error *local_err = NULL; - if (load_snapshot(loadvm, NULL, &local_err) < 0) { + if (load_snapshot(loadvm, NULL, NULL, &local_err) < 0) { error_report_err(local_err); autostart = 0; exit(1);