[libvirt] [PATCH 2/3] fdstream: introduce virFDStreamOpenBlockDevice

Roman Bogorodskiy bogorodskiy at gmail.com
Fri Aug 15 08:44:21 UTC 2014


virStorageBackendVolDownloadLocal and virStorageBackendVolUploadLocal
use virFDStreamOpenFile function to work with the volume fd.

virFDStreamOpenFile calls virFDStreamOpenFileInternal that implements
handling of the non-blocking I/O. If a file is not a character device and
not a fifo, it uses libvirt_iohelper.

On FreeBSD, it doesn't work as expected because disks are exposed as
character devices.

To overcome this, introduce a forceIOHelper flag to
virFDStreamOpenFileInternal that forces using libvirt_iohelper. And
introduce virFDStreamOpenBlockDevice that calls
virFDStreamOpenFileInternal with the forceIOHelper set to true.
---
 src/fdstream.c                | 26 ++++++++++++++++++++------
 src/fdstream.h                |  5 +++++
 src/libvirt_private.syms      |  1 +
 src/storage/storage_backend.c |  6 ++++--
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/fdstream.c b/src/fdstream.c
index d236318..4cf152a 100644
--- a/src/fdstream.c
+++ b/src/fdstream.c
@@ -577,7 +577,8 @@ virFDStreamOpenFileInternal(virStreamPtr st,
                             unsigned long long offset,
                             unsigned long long length,
                             int oflags,
-                            int mode)
+                            int mode,
+                            bool forceIOHelper)
 {
     int fd = -1;
     int childfd = -1;
@@ -623,8 +624,8 @@ virFDStreamOpenFileInternal(virStreamPtr st,
      * the I/O so we just have a fifo. Or use AIO :-(
      */
     if ((st->flags & VIR_STREAM_NONBLOCK) &&
-        (!S_ISCHR(sb.st_mode) &&
-         !S_ISFIFO(sb.st_mode))) {
+        ((!S_ISCHR(sb.st_mode) &&
+         !S_ISFIFO(sb.st_mode)) || forceIOHelper)) {
         int fds[2] = { -1, -1 };
 
         if ((oflags & O_ACCMODE) == O_RDWR) {
@@ -703,7 +704,7 @@ int virFDStreamOpenFile(virStreamPtr st,
     }
     return virFDStreamOpenFileInternal(st, path,
                                        offset, length,
-                                       oflags, 0);
+                                       oflags, 0, false);
 }
 
 int virFDStreamCreateFile(virStreamPtr st,
@@ -715,7 +716,8 @@ int virFDStreamCreateFile(virStreamPtr st,
 {
     return virFDStreamOpenFileInternal(st, path,
                                        offset, length,
-                                       oflags | O_CREAT, mode);
+                                       oflags | O_CREAT, mode,
+                                       false);
 }
 
 #ifdef HAVE_CFMAKERAW
@@ -730,7 +732,8 @@ int virFDStreamOpenPTY(virStreamPtr st,
 
     if (virFDStreamOpenFileInternal(st, path,
                                     offset, length,
-                                    oflags | O_CREAT, 0) < 0)
+                                    oflags | O_CREAT, 0,
+                                    false) < 0)
         return -1;
 
     fdst = st->privateData;
@@ -770,6 +773,17 @@ int virFDStreamOpenPTY(virStreamPtr st,
 }
 #endif /* !HAVE_CFMAKERAW */
 
+int virFDStreamOpenBlockDevice(virStreamPtr st,
+                               const char *path,
+                               unsigned long long offset,
+                               unsigned long long length,
+                               int oflags)
+{
+    return virFDStreamOpenFileInternal(st, path,
+                                       offset, length,
+                                       oflags, 0, true);
+}
+
 int virFDStreamSetInternalCloseCb(virStreamPtr st,
                                   virFDStreamInternalCloseCb cb,
                                   void *opaque,
diff --git a/src/fdstream.h b/src/fdstream.h
index 69d8328..2c913ea 100644
--- a/src/fdstream.h
+++ b/src/fdstream.h
@@ -56,6 +56,11 @@ int virFDStreamOpenPTY(virStreamPtr st,
                        unsigned long long offset,
                        unsigned long long length,
                        int oflags);
+int virFDStreamOpenBlockDevice(virStreamPtr st,
+                               const char *path,
+                               unsigned long long offset,
+                               unsigned long long length,
+                               int oflags);
 
 int virFDStreamSetInternalCloseCb(virStreamPtr st,
                                   virFDStreamInternalCloseCb cb,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 08111d4..ab7a39e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -823,6 +823,7 @@ virStreamClass;
 virFDStreamConnectUNIX;
 virFDStreamCreateFile;
 virFDStreamOpen;
+virFDStreamOpenBlockDevice;
 virFDStreamOpenFile;
 virFDStreamOpenPTY;
 virFDStreamSetInternalCloseCb;
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 9c775c9..00cfe74 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1718,7 +1718,8 @@ virStorageBackendVolUploadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     /* Not using O_CREAT because the file is required to already exist at
      * this point */
-    return virFDStreamOpenFile(stream, vol->target.path, offset, len, O_WRONLY);
+    return virFDStreamOpenBlockDevice(stream, vol->target.path,
+                                      offset, len, O_WRONLY);
 }
 
 int
@@ -1732,7 +1733,8 @@ virStorageBackendVolDownloadLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
 {
     virCheckFlags(0, -1);
 
-    return virFDStreamOpenFile(stream, vol->target.path, offset, len, O_RDONLY);
+    return virFDStreamOpenBlockDevice(stream, vol->target.path,
+                                      offset, len, O_RDONLY);
 }
 
 
-- 
1.9.0




More information about the libvir-list mailing list