]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
fdstream: introduce virFDStreamOpenBlockDevice
authorRoman Bogorodskiy <bogorodskiy@gmail.com>
Fri, 15 Aug 2014 08:11:35 +0000 (12:11 +0400)
committerRoman Bogorodskiy <bogorodskiy@gmail.com>
Mon, 25 Aug 2014 06:46:13 +0000 (10:46 +0400)
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 disk devices (including
ZFS volumes) are exposed as character devices, and ZFS volumes do not
support open(2) with O_NONBLOCK.

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
src/fdstream.h
src/libvirt_private.syms
src/storage/storage_backend.c

index d236318994bb6f63fd3b8b4afc919790dae513e0..4cf152a0758674b6ba39bcd2f22e326308be385b 100644 (file)
@@ -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,
index 69d832817e7f9da681cf1146be125163492fef78..2c913ea14093347f275776fceb610ce95ac07c17 100644 (file)
@@ -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,
index e09ddd57cc3d55c80e0c2598b2850cb0d1d19133..6b9ee21c74a7f8a7714665e22b2734e3a071424d 100644 (file)
@@ -823,6 +823,7 @@ virStreamClass;
 virFDStreamConnectUNIX;
 virFDStreamCreateFile;
 virFDStreamOpen;
+virFDStreamOpenBlockDevice;
 virFDStreamOpenFile;
 virFDStreamOpenPTY;
 virFDStreamSetInternalCloseCb;
index 9c775c9557e0ccfb36f576e20d7a9e0b76c429cf..00cfe74c8824912811ff153b5d34082b06d578c7 100644 (file)
@@ -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);
 }