[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen |
Date: |
Fri, 13 Apr 2012 18:23:17 +0200 |
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 <address@hidden>
---
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:
--
1.7.9.3
- Re: [Qemu-devel] [PATCH 6/8] block: add the drive-reopen command, (continued)
[Qemu-devel] [PATCH 4/8] block: add mirror job, Paolo Bonzini, 2012/04/13
[Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Paolo Bonzini, 2012/04/13
- Re: [Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Eric Blake, 2012/04/13
- Re: [Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Paolo Bonzini, 2012/04/13
- Re: [Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Eric Blake, 2012/04/13
- Re: [Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Paolo Bonzini, 2012/04/13
- Re: [Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Eric Blake, 2012/04/13
- Re: [Qemu-devel] [PATCH 8/8] docs: add mirroring to live block operations, Paolo Bonzini, 2012/04/16
[Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen,
Paolo Bonzini <=
- Re: [Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen, Eric Blake, 2012/04/13
- Re: [Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen, Paolo Bonzini, 2012/04/16
- Re: [Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen, Eric Blake, 2012/04/16
- Re: [Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen, Paolo Bonzini, 2012/04/17
- Re: [Qemu-devel] [PATCH 7/8] block: add witness argument to drive-reopen, Eric Blake, 2012/04/17
- Re: [Qemu-devel] [libvirt] [PATCH 7/8] block: add witness argument to drive-reopen, Michal Privoznik, 2012/04/17
Re: [Qemu-devel] [RFC PATCH 0/8] job-based mirroring implementation, Eric Blake, 2012/04/13