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

[Xen-devel] [RFC XEN PATCH 14/16] tools/libxl: add support to map files on pmem devices to guests



We can map host pmem devices or files on pmem devices to guests. This
patch adds support to map files on pmem devices. The implementation
relies on the Linux pmem driver and kernel APIs, so it currently
functions only when libxl is compiled for Linux.

Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx>
---
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 tools/libxl/libxl_nvdimm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/tools/libxl/libxl_nvdimm.c b/tools/libxl/libxl_nvdimm.c
index 7bcbaaf..b3ba19a 100644
--- a/tools/libxl/libxl_nvdimm.c
+++ b/tools/libxl/libxl_nvdimm.c
@@ -25,6 +25,9 @@
 #include <unistd.h>
 #include <errno.h>
 #include <stdint.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#include <linux/fiemap.h>
 
 #include "libxl_internal.h"
 #include "libxl_arch.h"
@@ -97,10 +100,78 @@ static int add_pages(libxl__gc *gc, uint32_t domid,
     return ret;
 }
 
+static uint64_t
+get_file_extents(libxl__gc *gc, int fd, unsigned long length,
+                 struct fiemap_extent **extents_r)
+{
+    struct fiemap *fiemap;
+    uint64_t nr_extents = 0, extents_size;
+
+    fiemap = libxl__zalloc(gc, sizeof(*fiemap));
+    if ( !fiemap )
+        goto out;
+
+    fiemap->fm_length = length;
+    if ( ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0 )
+        goto out;
+
+    nr_extents = fiemap->fm_mapped_extents;
+    extents_size = sizeof(struct fiemap_extent) * nr_extents;
+    fiemap = libxl__realloc(gc, fiemap, sizeof(*fiemap) + extents_size);
+    if ( !fiemap )
+        goto out;
+
+    memset(fiemap->fm_extents, 0, extents_size);
+    fiemap->fm_extent_count = nr_extents;
+    fiemap->fm_mapped_extents = 0;
+
+    if ( ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0 )
+        goto out;
+
+    *extents_r = fiemap->fm_extents;
+
+ out:
+    return nr_extents;
+}
+
 static int add_file(libxl__gc *gc, uint32_t domid, int fd,
                     xen_pfn_t mfn, xen_pfn_t gpfn, unsigned long nr_mfns)
 {
-    return -EINVAL;
+    struct fiemap_extent *extents;
+    uint64_t nr_extents, i;
+    int ret = 0;
+
+    nr_extents = get_file_extents(gc, fd, nr_mfns << XC_PAGE_SHIFT, &extents);
+    if ( !nr_extents )
+        return -EIO;
+
+    for ( i = 0; i < nr_extents; i++ )
+    {
+        uint64_t p_offset = extents[i].fe_physical;
+        uint64_t l_offset = extents[i].fe_logical;
+        uint64_t length = extents[i].fe_length;
+
+        if ( extents[i].fe_flags & ~FIEMAP_EXTENT_LAST )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
+        if ( (p_offset | l_offset | length) & ~XC_PAGE_MASK )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
+        ret = add_pages(gc, domid,
+                        mfn + (p_offset >> XC_PAGE_SHIFT),
+                        gpfn + (l_offset >> XC_PAGE_SHIFT),
+                        length >> XC_PAGE_SHIFT);
+        if ( ret )
+            break;
+    }
+
+    return ret;
 }
 
 int libxl_nvdimm_add_device(libxl__gc *gc,
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.