From patchwork Mon Feb 20 17:31:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 142171 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4F536B6FA2 for ; Tue, 21 Feb 2012 04:31:51 +1100 (EST) Received: from localhost ([::1]:60971 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzX5X-0002lK-TU for incoming@patchwork.ozlabs.org; Mon, 20 Feb 2012 12:31:47 -0500 Received: from eggs.gnu.org ([140.186.70.92]:45305) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzX5D-0002PH-SC for qemu-devel@nongnu.org; Mon, 20 Feb 2012 12:31:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RzX5B-0000CZ-Pv for qemu-devel@nongnu.org; Mon, 20 Feb 2012 12:31:27 -0500 Received: from mx1.redhat.com ([209.132.183.28]:2663) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzX5B-0000CP-H2 for qemu-devel@nongnu.org; Mon, 20 Feb 2012 12:31:25 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q1KHVOaC028104 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 20 Feb 2012 12:31:24 -0500 Received: from localhost ([10.3.112.11]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q1KHVMiH021676 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Mon, 20 Feb 2012 12:31:24 -0500 From: Jeff Cody To: qemu-devel@nongnu.org Date: Mon, 20 Feb 2012 12:31:12 -0500 Message-Id: <58b44a8409ab790a76212958928fa6f3ccbf9096.1329758006.git.jcody@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Markus Armbruster , Luiz Capitulino Subject: [Qemu-devel] [PATCH 3/3] qapi: Introduce blockdev-query-group-snapshot-failure 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 In the case of a failure in a group snapshot, it is possible for multiple file image failures to occur - for instance, failure of an original snapshot, and then failure of one or more of the attempted reopens of the original. Knowing all of the file images which failed could be useful or critical information, so this command returns a list of strings containing the filenames of all failures from the last invocation of blockdev-group-snapshot-sync. Signed-off-by: Jeff Cody --- blockdev.c | 42 +++++++++++++++++++++++++++++++++++++++++- qapi-schema.json | 25 +++++++++++++++++++++++++ qmp-commands.hx | 5 +++++ 3 files changed, 71 insertions(+), 1 deletions(-) diff --git a/blockdev.c b/blockdev.c index 0149720..cb44af5 100644 --- a/blockdev.c +++ b/blockdev.c @@ -727,6 +727,7 @@ typedef struct BlkGroupSnapshotData { QSIMPLEQ_ENTRY(BlkGroupSnapshotData) entry; } BlkGroupSnapshotData; +SnapshotFailList *group_snap_fail_list; /* * 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail * then we attempt to undo all of the pivots performed. @@ -739,10 +740,24 @@ void qmp_blockdev_group_snapshot_sync(SnapshotDevList *dev_list, SnapshotDev *dev_info = NULL; BlkGroupSnapshotData *snap_entry; BlockDriver *proto_drv; + SnapshotFailList *fail_entry = group_snap_fail_list; QSIMPLEQ_HEAD(gsnp_list, BlkGroupSnapshotData) gsnp_list; QSIMPLEQ_INIT(&gsnp_list); + /* + * clear out our failure list first, and reclaim memory + * we maintain the list, so if a group snapshot fails + * we can be queried about which devices failed + */ + SnapshotFailList *fail_entry_next = NULL; + while (NULL != fail_entry) { + g_free(fail_entry->value); + fail_entry_next = fail_entry->next; + g_free(fail_entry); + fail_entry = fail_entry_next; + } + /* We don't do anything in this loop that commits us to the snapshot */ while (NULL != dev_entry) { dev_info = dev_entry->value; @@ -815,6 +830,16 @@ void qmp_blockdev_group_snapshot_sync(SnapshotDevList *dev_list, */ if (ret != 0) { error_set(errp, QERR_OPEN_FILE_FAILED, snap_entry->snapshot_file); + /* + * We bail on the first failure, but add the failed filename to the + * return list in case any of the rollback pivots fail as well + */ + SnapshotFailList *failure; + failure = g_malloc0(sizeof(SnapshotFailList)); + failure->value = g_malloc0(sizeof(*failure->value)); + failure->value->failed_file = g_strdup(snap_entry->snapshot_file); + failure->next = group_snap_fail_list; + group_snap_fail_list = failure; goto error_rollback; } } @@ -829,7 +854,17 @@ error_rollback: ret = bdrv_open(snap_entry->bs, snap_entry->old_filename, snap_entry->flags, snap_entry->old_drv); if (ret != 0) { - /* This is very very bad */ + /* + * This is very very bad. Make sure the caller is aware + * of which files failed, since there could be more than + * one + */ + SnapshotFailList *failure; + failure = g_malloc0(sizeof(SnapshotFailList)); + failure->value = g_malloc0(sizeof(*failure->value)); + failure->value->failed_file = g_strdup(snap_entry->old_filename); + failure->next = group_snap_fail_list; + group_snap_fail_list = failure; error_set(errp, QERR_OPEN_FILE_FAILED, snap_entry->old_filename); } @@ -843,6 +878,11 @@ exit: return; } +SnapshotFailList *qmp_blockdev_query_group_snapshot_failure(Error **errp) +{ + return group_snap_fail_list; +} + static void eject_device(BlockDriverState *bs, int force, Error **errp) { diff --git a/qapi-schema.json b/qapi-schema.json index b8d66d0..c4b27a3 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1121,6 +1121,14 @@ 'data': {'device': 'str', 'snapshot-file': 'str', '*format': 'str' } } ## +# @SnapshotFail +# +# @failed_file: string of the filename that failed +## +{ 'type': 'SnapshotFail', + 'data': {'failed_file': 'str' } } + +## # @blockdev-group-snapshot-sync # # Generates a synchronous snapshot of a group of one or more block devices, @@ -1152,6 +1160,23 @@ 'data': { 'dev': [ 'SnapshotDev' ] } } ## +# @blockdev-query-group-snapshot-failure +# +# +# Returns: A list of @SnapshotFail, that contains the filenames for all failures +# of the last blockdev-group-snapshot-sync command. +# +# Notes: +# Since there could potentially be more than one file open or drive +# failures, the additional command 'blockdev-query-group-snapshot-failure' +# will return a list of all device files that have failed. This could +# include the original filename if the reopen of an original image file +# failed. +# +## +{ 'command': 'blockdev-query-group-snapshot-failure', 'returns': [ 'SnapshotFail' ] } + +## # @blockdev-snapshot-sync # # Generates a synchronous snapshot of a block device. diff --git a/qmp-commands.hx b/qmp-commands.hx index 2fe1e6e..9a80e08 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -706,6 +706,11 @@ Example: EQMP { + .name = "blockdev-query-group-snapshot-failure", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_blockdev_query_group_snapshot_failure, + }, + { .name = "blockdev-snapshot-sync", .args_type = "device:B,snapshot-file:s,format:s?", .mhandler.cmd_new = qmp_marshal_input_blockdev_snapshot_sync,