From patchwork Fri Apr 13 16:23:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 152346 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 92D15B700C for ; Sat, 14 Apr 2012 02:46:13 +1000 (EST) Received: from localhost ([::1]:39834 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIjIp-0001Ky-NN for incoming@patchwork.ozlabs.org; Fri, 13 Apr 2012 12:24:51 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45371) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIjIC-0008Mi-Dz for qemu-devel@nongnu.org; Fri, 13 Apr 2012 12:24:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SIjI5-0008Lt-ML for qemu-devel@nongnu.org; Fri, 13 Apr 2012 12:24:11 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:48107) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIjI5-0007uv-Bc for qemu-devel@nongnu.org; Fri, 13 Apr 2012 12:24:05 -0400 Received: by mail-pb0-f45.google.com with SMTP id uo5so4466860pbc.4 for ; Fri, 13 Apr 2012 09:24:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=Z1brGiMY4zOaEYTzfjFjMAY28W1AGGkNPu3GBl3BqjI=; b=N7MzNbydvdxGVYvc+9idzqEu2ua0bk7dqmV88DpwJ0a4LsaEhS+lYQrK2hUAoU0hlL qfTAq2RhcyNTHKx1QStiZgFmUxieBlEHXNDdKgi81mNgj4wjHzmt2Ise/GYIpf57AU2P N8jXn6jBWY+RKXmZDilIYEQ+LvIz3quorCLGt04vs9W57pIyslw+jHE+q14ydjcPZ3xS ZhTBuoPJTyaVEv7xKKqYasgm4Tnu1hMDIqgGDM7n4U2ZV/8A/TsrusfCXVEjLDJz5Zx5 aw/K2pJEew0MKEatPNVGJggcLs+4FzuWfPL/J/uEwa+FFqNtQf1qt6JhmFw8PHoLuMMg BbIw== Received: by 10.68.220.35 with SMTP id pt3mr5915545pbc.22.1334334244511; Fri, 13 Apr 2012 09:24:04 -0700 (PDT) Received: from yakj.usersys.redhat.com (93-34-182-16.ip50.fastwebnet.it. [93.34.182.16]) by mx.google.com with ESMTPS id s7sm9116719pbl.31.2012.04.13.09.24.00 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 13 Apr 2012 09:24:03 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 13 Apr 2012 18:23:17 +0200 Message-Id: <1334334198-30899-8-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.9.3 In-Reply-To: <1334334198-30899-1-git-send-email-pbonzini@redhat.com> References: <1334334198-30899-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: kwolf@redhat.com, fsimonce@redhat.com, mtosatti@redhat.com, eblake@redhat.com, stefanha@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen 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 Management needs a way for QEMU to confirm that no I/O has been sent to the target and not to the source. To provide this guarantee we rely on a file in local persistent storage. QEMU receives a file descriptor via SCM_RIGHTS and writes a single byte to it. If it fails, it will fail the drive-reopen command too and management knows that no I/O request has been issued to the new destination. Likewise, if management finds the file to have nonzero size it knows that the target is valid and that indeed I/O requests could have been submitted to it. The argument does not have an HMP equivalent. Signed-off-by: Paolo Bonzini --- blockdev.c | 24 +++++++++++++++++++++--- hmp.c | 2 +- qapi-schema.json | 10 +++++++++- qmp-commands.hx | 12 +++++++++++- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/blockdev.c b/blockdev.c index 08953fa..78b72f2 100644 --- a/blockdev.c +++ b/blockdev.c @@ -660,7 +660,7 @@ void do_commit(Monitor *mon, const QDict *qdict) } static void change_blockdev_image(BlockDriverState *bs, const char *new_image_file, - const char *format, Error **errp) + const char *format, int fd, Error **errp) { BlockDriver *old_drv, *proto_drv; BlockDriver *drv = NULL; @@ -702,6 +702,16 @@ static void change_blockdev_image(BlockDriverState *bs, const char *new_image_fi bdrv_close(bs); ret = bdrv_open(bs, new_image_file, flags, drv); + + if (ret == 0 && fd != -1) { + ret = write(fd, "", 1) == 1 ? 0 : -1; + qemu_fdatasync(fd); + close(fd); + if (ret < 0) { + bdrv_close(bs); + } + } + /* * If reopening the image file we just created fails, fall back * and try to re-open the original image. If that fails too, we @@ -718,9 +725,20 @@ static void change_blockdev_image(BlockDriverState *bs, const char *new_image_fi } void qmp_drive_reopen(const char *device, const char *new_image_file, - bool has_format, const char *format, Error **errp) + bool has_format, const char *format, + bool has_witness, const char *witness, + Error **errp) { BlockDriverState *bs; + int fd = -1; + + if (has_witness) { + fd = monitor_get_fd(cur_mon, witness); + if (fd == -1) { + error_set(errp, QERR_FD_NOT_FOUND, witness); + return; + } + } bs = bdrv_find(device); if (!bs) { @@ -731,7 +749,7 @@ void qmp_drive_reopen(const char *device, const char *new_image_file, block_job_cancel_sync(bs->job); } change_blockdev_image(bs, new_image_file, - has_format ? format : NULL, errp); + has_format ? format : NULL, fd, errp); } static void blockdev_do_action(int kind, void *data, Error **errp) diff --git a/hmp.c b/hmp.c index 28697ec..f67c441 100644 --- a/hmp.c +++ b/hmp.c @@ -744,7 +744,7 @@ void hmp_drive_reopen(Monitor *mon, const QDict *qdict) const char *format = qdict_get_try_str(qdict, "format"); Error *errp = NULL; - qmp_drive_reopen(device, filename, !!format, format, &errp); + qmp_drive_reopen(device, filename, !!format, format, false, NULL, &errp); hmp_handle_error(mon, &errp); } diff --git a/qapi-schema.json b/qapi-schema.json index 0bf3a25..2e5a925 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1228,6 +1228,13 @@ # # @format: #optional the format of the new image, default is 'qcow2'. # +# @witness: A file descriptor name that was passed via getfd. QEMU will write +# a single byte to this file descriptor before completing the command +# successfully. If the byte is not written to the file, it is +# guaranteed that the guest has not issued any I/O to the new image. +# Failure to write the byte is fatal just like failure to open the new +# image, and will cause the guest to revert to the currently open file. +# # Returns: nothing on success # If @device is not a valid block device, DeviceNotFound # If @new-image-file can't be opened, OpenFileFailed @@ -1236,7 +1243,8 @@ # Since 1.1 ## { 'command': 'drive-reopen', - 'data': { 'device': 'str', 'new-image-file': 'str', '*format': 'str' } } + 'data': { 'device': 'str', 'new-image-file': 'str', '*format': 'str', + '*witness': 'str' } } ## # @human-monitor-command: diff --git a/qmp-commands.hx b/qmp-commands.hx index 6ea0ef5..fedfc36 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -829,7 +829,7 @@ EQMP { .name = "drive-reopen", - .args_type = "device:B,new-image-file:s,format:s?", + .args_type = "device:B,new-image-file:s,format:s?,witness:s?", .mhandler.cmd_new = qmp_marshal_input_drive_reopen, }, @@ -842,11 +842,21 @@ guest is expecting the drive to change its content, the new image should contain the same data of the current one. One use case is to terminate a drive-mirror command. +The command can optionally write a single byte to a file descriptor name +that was passed via SCM rights (getfd). QEMU will write a single byte +to this file descriptor before completing the command successfully. +If the byte is not written to the file, it is guaranteed that the +guest has not issued any I/O to the new image. Failure to write the +byte is fatal just like failure to open the new image, and will cause +the guest to revert to the currently open file. + + Arguments: - "device": device name to operate on (json-string) - "new-image-file": name of new image file (json-string) - "format": format of new image (json-string, optional) +- "witness": file descriptor previously passed via SCM rights (json-string, optional) Example: