qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v8 2/3] block: ssh: Use libssh2_sftp_fsync (if suppo


From: Richard W.M. Jones
Subject: [Qemu-devel] [PATCH v8 2/3] block: ssh: Use libssh2_sftp_fsync (if supported by libssh2) to flush to disk.
Date: Tue, 9 Apr 2013 10:56:32 +0100

From: "Richard W.M. Jones" <address@hidden>

libssh2_sftp_fsync is an extension to libssh2 to support fsync(2) over
sftp, which is itself an extension of OpenSSH.

If both libssh2 and the ssh daemon support it, this will allow
bdrv_flush_to_disk to commit changes through to disk on the remote
server.
---
 block/ssh.c   | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 configure     | 25 +++++++++++++++++++++++++
 qemu-doc.texi |  6 ------
 3 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/block/ssh.c b/block/ssh.c
index e1322cb..b83c239 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -826,6 +826,50 @@ static coroutine_fn int ssh_co_writev(BlockDriverState *bs,
     return ret;
 }
 
+#ifdef HAS_LIBSSH2_SFTP_FSYNC
+
+static coroutine_fn int ssh_flush(BDRVSSHState *s)
+{
+    int r;
+    static int warned = 0;
+
+    DPRINTF("fsync");
+ again:
+    r = libssh2_sftp_fsync(s->sftp_handle);
+    if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
+        co_yield(s);
+        goto again;
+    }
+    if (r == LIBSSH2_ERROR_SFTP_PROTOCOL &&
+        libssh2_sftp_last_error(s->sftp) == LIBSSH2_FX_OP_UNSUPPORTED) {
+        if (!warned) {
+            error_report("warning: remote ssh server does not support fsync");
+            warned = 1;
+        }
+        return 0;
+    }
+    if (r < 0) {
+        sftp_error_report(s, "fsync failed");
+        return -EIO;
+    }
+
+    return 0;
+}
+
+static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
+{
+    BDRVSSHState *s = bs->opaque;
+    int ret;
+
+    qemu_co_mutex_lock(&s->lock);
+    ret = ssh_flush(s);
+    qemu_co_mutex_unlock(&s->lock);
+
+    return ret;
+}
+
+#endif /* HAS_LIBSSH2_SFTP_FSYNC */
+
 static int64_t ssh_getlength(BlockDriverState *bs)
 {
     BDRVSSHState *s = bs->opaque;
@@ -849,6 +893,9 @@ static BlockDriver bdrv_ssh = {
     .bdrv_co_readv                = ssh_co_readv,
     .bdrv_co_writev               = ssh_co_writev,
     .bdrv_getlength               = ssh_getlength,
+#ifdef HAS_LIBSSH2_SFTP_FSYNC
+    .bdrv_co_flush_to_disk        = ssh_co_flush,
+#endif
     .create_options               = ssh_create_options,
 };
 
diff --git a/configure b/configure
index 4dd65b0..fa79588 100755
--- a/configure
+++ b/configure
@@ -2357,6 +2357,31 @@ EOF
 fi
 
 ##########################################
+# libssh2_sftp_fsync probe
+
+if test "$libssh2" = "yes"; then
+  cat > $TMPC <<EOF
+#include <stdio.h>
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+int main(void) {
+    LIBSSH2_SESSION *session;
+    LIBSSH2_SFTP *sftp;
+    LIBSSH2_SFTP_HANDLE *sftp_handle;
+    session = libssh2_session_init ();
+    sftp = libssh2_sftp_init (session);
+    sftp_handle = libssh2_sftp_open (sftp, "/", 0, 0);
+    libssh2_sftp_fsync (sftp_handle);
+    return 0;
+}
+EOF
+  # libssh2_cflags/libssh2_libs defined in previous test.
+  if compile_prog "$libssh2_cflags" "$libssh2_libs" ; then
+    QEMU_CFLAGS="-DHAS_LIBSSH2_SFTP_FSYNC $QEMU_CFLAGS"
+  fi
+fi
+
+##########################################
 # linux-aio probe
 
 if test "$linux_aio" != "no" ; then
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 7a0f373..9e30667 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1072,12 +1072,6 @@ the standard ssh port (22) is used.
 Currently authentication must be done using ssh-agent.  Other
 authentication methods may be supported in future.
 
-Note: The ssh driver does not obey disk flush requests (ie. to commit
-data to the backing disk when the guest requests it).  This is because
-the underlying protocol (SFTP) does not support this.  Thus there is a
-risk of guest disk corruption if the remote server or network goes
-down during writes.
-
 @node pcsys_network
 @section Network emulation
 
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]