试图获得模拟pmem被libpmem识别为pmem

问题描述:

我正在尝试开发一些使用libpmem的软件。我正在建立一个测试环境,在那里我可以模拟pmem并让图书馆识别它。我要么遇到问题,要么不了解pmap如何由mmap处理。试图获得模拟pmem被libpmem识别为pmem

我都遵循这样的:http://pmem.io/2016/02/22/pm-emulation.html

一切看起来都很好。启动日志在我指定的范围内显示类型12的内存。我在/ dev/pmemXX上创建了一个ext4文件系统,然后用dax安装它。所以现在我有:

$ mount | grep pmem 
/dev/pmem0m on /mnt/mem type ext4 (rw,relatime,dax,data=ordered) 

现在我遇到了一个问题。我创建了一个文件/mnt/mem/data/test1。接下来,我从libpmem运行简单的复制示例。在此,我拨打电话:

addr = pmem_map_file("/mnt/mem/data/test2", ...) 

创建文件并将数据复制到其中。

is_pmem = pmem_is_pmem(addr, file_size) 

由调用返回的pmem_map_file不注册为PMEM地址:当我得到的结果问题来了。当我遍历代码时,很明显映射返回的addr不在我保留为模拟类型12内存的内存范围内。此外,当文件库使用文件统计信息时,到/mnt/mem/data/test2的文件路径不会注册为dax字符设备,因此映射的地址和文件路径都会使测试无法识别为pmem。

从关于DAX的阅读中可以看出,安装为DAX的文件系统会将文件内存直接映射,并且不会复制到实际的RAM中。我试图理解这个文件映射时返回的addr是什么意思。

我觉得我在这里错过了一些东西。在我查询它是否为pmem时,不应该将构建在仿真pmem上的文件系统中的映射文件装载为DAX,是否返回true?

***编辑

感谢Piotr的澄清。我可以使用PMEM_IS_PMEM_FORCE,但我也想看看设备dax操作。我正在尝试将名称空间重新配置为设备dax,但没有成功。

$ sudo strace ./local/opt/bin/ndctl create-namespace -f -e namespace0.0 -m dax 
. . . 
open("/sys/devices/platform/e820_pmem/ndbus0/region0/pfn0.0/align", 
O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) 
open("/sys/devices/platform/e820_pmem/ndbus0/region0/pfn0.0/resource", 
O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) 
open("/sys/devices/platform/e820_pmem/ndbus0/region0/pfn0.0/size", 
O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) 
getdents(3, /* 0 entries */, 32768)  = 0 
close(3)        = 0 
open("/sys/devices/platform/e820_pmem/ndbus0/region0/dax_seed", 
O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) 
write(2, "failed to reconfigure namespace:"..., 66failed to reconfigure 
namespace: Resource temporarily unavailable 
) = 66 
exit_group(245)       = ? 
+++ exited with 245 +++ 

也许这是我正在运行的内核的问题? (4.4.0-97 Ubuntu)

+0

我认为[tag:dax]标签指的是不同的东西。不知道是否有你的达克斯标签。 – mendosi

+0

对不起。修复。 – Megan

该库按预期工作。请参阅有关Linux内核实现的持久性存储器中的状态在当前的man 3 libpmem的说明(1.3在写作的时候)版本:

注:在Linux,pmem_is_pmem()返回true,只有在整个范围 直接从Device DAX(/dev/daxX.Y)映射而不需要中间文件系统。将来,随着文件系统变得支持使用pmem_persist()进行刷新的 可用,pmem_is_pmem() 将根据需要返回true。

警告:在pmem_is_pmem()返回 false的范围内使用pmem_persist()可能无效 - 使用msync(2)代替。

这是希望很快会改变,请参阅synchronous page faults patches

在此期间,你有两个选择,如果你想pmem_is_pmem()返回true:

  • 使用PMEM_IS_PMEM_FORCE=1环境变量,这会迫使该函数返回true。
  • 重新配置仿真的pmem设备到设备dax。对于这项任务,您将需要ndctl。命令是:ndctl create-namespace -f -e namespaceX.Y -m dax其中X是区域ID,Y是区域内名称空间的ID(如果只配置了一个仿真设备,最有可能为namespace0.0)。

设备DAX是一种特殊字符设备,允许一个mmap,并安全地在目前所有的Linux文件系统的情况下执行用户空间潮红,而有可能是背景/异步工作方式就像分配的程度,现场碎片整理等等 - 这意味着在常规fs上,尽管安装为dax,但您仍需要拨打msync()以确保数据的一致性。这就是pmem_is_pmem()通知你。

你可以阅读更多关于here的问题。

+0

谢谢你澄清。我并不清楚(并且仍然有点模糊),说明如何使用dax选项安装设备的dax函数与文件系统。正如你所建议的,我尝试用ndctl重新配置名称空间。出于某种原因,我不断收到错误“资源暂时不可用”。我已经尝试手动禁用命名空间,甚至试图删除它,但到目前为止我还没有能够得到它成功地重新配置。 – Megan

+0

我已在帖子中添加了关于DAX的更多信息。如果你对细节感兴趣,我鼓励你阅读我链接的LWN文章。 至于你的问题,恐怕我从未遇到过你的问题。你使用的是什么kernel/ndctl版本?我强烈建议使用最新的内核(编写本文时为4.13)和最新的ndctl(v58.2)。 –