免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1562 | 回复: 3
打印 上一主题 下一主题

[其他] 发个 mmap 的笔记 [复制链接]

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-01-10 14:01 |只看该作者 |倒序浏览
do_mmap 函数自己本身并不真做 mmap, 它基本上只是检查参数, 准备必要的数据结构; 但这也不是没有可说的, 事实上, glibc 函数 mmap 的需要注意的点, 再这个函数里面还真有几个。

先看 mmap 原型

void* mmap(void* addr, sie_t length, int prot, int flags, int fd, offset_t offset)

参数含义可以 man, 不多说, 单看几个 prot | flags 偏门组合:

1. PROT_READ | MAP_SHARED

这意思是, 我只读, 但别人的写得给我看到;

那么这个和 PROT_READ | MAP_PRIVATE 有区别吗?先从字面意思理解 PROT_READ | MAP_PRIVATE, 似乎是说, 我只读, 别人写的也别给我看到; 但实际上并非如此, 任意的写, PROT_READ | MAP_PRIVATE 还是能看到, 只要写的那方别是 COW 就成。 其实似乎 PROT_READ | MAP_PRIVATE 这个组合似乎不是没意义, 至少可以用来做某具体时间文件内容的 snapshot; 但事实现在就是如此。

虽然没区别, 但这两个组合一旦再于  MAP_ANONYMOUS 或 fd  组合起来, 就有点其他问题了;

单说 fd, 忽略 MAP_ANONYMOUS, 因为这两个其实表达一个意思; 虽然优先起作用的是 MAP_ANONYMOUS, 但 fd 写起来简单。

fd != -1, 说明有 backup storage,  fd == -1, 说明是再 shm 文件系统分配的一个叫做 dev/zero 的文件, 这个文件系统挂在 /dev/shm 目录下, 但这个文件 ls 这些命令是看不到的, 涉及到 readdir 实现及 vfs 逻辑, 不说。

fd != -1 的情况下, 似乎本方永远不会 COW, 因为 read 嘛, 永远不会写, 不管 MAP_PRIVATE, 还是 MAP_SHARED。

然而, do_mmap 的实现中存在这这样一个逻辑, 就是如果 fd 是以 read 方式打开的, 则更改 MAP_SHARED 为 MAP_PRIVATE。 为啥?

因为一个特殊情况, 在调试器中加断点, 由于代码是以 read 方式打开的, 以 MAP_SHARED 方式映射的, 如何处理? 一个是不允许加, 因为是 MAP_SHARED 嘛, 一旦加了, 就真的写入磁盘了, 这个跟 read only 的打开方式矛盾, 也情理之中不允许。 另一个办法是允许加, 但如何避免将这个断点写入磁盘呢, 采取的措施就是将 MAP_SHARED 改成 MAP_PRIVATE。 就像 map 的时候本来就是 MAP_PRIVATE 方式 map 的一样。 但还是有问题, 加完断点后, 这个被修改的页面就 COW 了, 这个页面被其他的人修改了怎么办, 因为 MAP_SHARED 语意是要求看到其他方的修改的。 这里没有处理措施, linus 原话:

“  so it's clearly not "correct" either, but it's certainly a million times better than writing out breakpoints to shared files..”。

fd == -1 的情况呢? 自然之前的问题都可以解决了, 本来就是 PRIVATE 语意嘛; 看不到是自然的, 被修改后 COW 也是自然的;

2。 再看 MAP_SHARED | PROT_WRITE 与 MAP_PRIVATE | PROT_WRITE

这个没什么可说, MAP_SHARED | PROT_WRITE 允许写, 并被更新到磁盘, 只要 fd 是以可写方式打开的, 如果fd 不可写, 则 mmap 会失败;

整体看起来有点古怪的是,  MAP_SHARED | PROT_READ 可以映射 read only 的 fd, 然后 mmap 还允许它写(通过将MAP_SHARED 改成 MAP_PRIVATE);  MAP_SHARED | PROT_WRITE 却没有这样的待遇, 并不能通过自动降到 MAP_PRIVATE 而在 read only 的 fd  上映射, 唯一原因, 只不过这里很显然是不合理的组合, 而上面那个是没办法了, 只能开后门来支持调试器。

MAP_PRIVATE | PROT_WRITE 允许写,不更新到磁盘。然而 fd 则又需要注意, 不管它是不是以可写方式打开的, 都允许写, 这个似乎又有点和 fd open 时的语意冲突; 但现实就是这样的。

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
2 [报告]
发表于 2013-01-11 13:38 |只看该作者

LZ你写文章太烂了, 我根本没看懂.

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
3 [报告]
发表于 2013-01-11 13:42 |只看该作者
captivated 发表于 2013-01-11 13:38
LZ你写文章太烂了, 我根本没看懂.

论坛徽章:
0
4 [报告]
发表于 2013-01-11 15:36 |只看该作者
可能是楼主基于自己的上下文在写呢,咱是有点衔接不上
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP