试图让模拟的pmem被libpmem识别为pmem

时间:2017-10-18 22:12:46

标签: c linux-kernel

我正在尝试使用libpmem开发一些软件。我正在建立一个测试环境,在那里我可以模拟pmem并让库识别它。我要么遇到问题,要么不了解mmap如何处理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) 。接下来,我从libpmem运行简单的复制示例。在这,我打电话:

/mnt/mem/data/test1

创建文件并将数据复制到其中。当我从以下结果得到结果时出现问题:

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

调用is_pmem = pmem_is_pmem(addr, file_size) 返回的地址未注册为pmem。当我单步执行代码时,很明显映射返回的pmem_map_file不在我保留为模拟类型12内存的内存范围内。此外,当库使用文件stat时,addr的文件路径不会注册为dax字符设备,因此映射的地址和文件路径都会将测试识别为pmem。

从阅读DAX开始,听起来好像安装为DAX的文件系统会直接映射文件内存,而不会复制到实际的RAM中。我试图理解这对于映射文件时返回的/mnt/mem/data/test2意味着什么。

我觉得我在这里遗漏了一些东西。作为DAX安装的模拟pmem上构建的文件系统中的映射文件不应该在我查询它是否为pmem时返回true?

***编辑

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

PMEM_IS_PMEM_FORCE

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

1 个答案:

答案 0 :(得分:1)

库按预期工作。请参阅当前(撰写本文时为1.3)关于Linux内核启用持久性内存状态的man 3 libpmem版本的说明:

  

注意:在Linux上,pmem_is_pmem()仅在整个范围内返回true   直接从设备DAX(/dev/daxX.Y)映射而没有   介入文件系统。将来,随着文件系统的发展   支持使用pmem_persist(),pmem_is_pmem()进行刷新的可用   将在适当时返回true。

     

警告:在pmem_is_pmem()返回的范围内使用pmem_persist()   false可能没有做任何有用的事情 - 改为使用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