我正在尝试使用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)
答案 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。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。