2012/2

怀念适之

先生过世已经整整50周年了,可先生充满智慧的话至今仍振聋发聩。无怪乎有人说“二十世纪是鲁迅的世纪,二十一世纪是胡适的世纪”!

1. “容忍比自由更重要 。

我常常用来自勉。

2. “宁鸣而死,不默而生。

适用于沉默的大多数。

3. “做学问要在不疑处有疑,待人时要在有疑处不疑。

适用于方舟子。

4. “有人告诉你‘牺牲你个人的自由去争取国家的自由’可是我要告诉你‘为个人争自由就是为国家争自由,争取个人的人格就是为社会争人格。真正自由平等的国家不是一群奴才建立起来的。’

适用于司马南、胡锡进这种奴才。

5. “一个肮脏的国家,如果人人讲规则而不是谈道德,最终会变成一个有人味儿正常国家,道德自然逐渐回归;一个干净的国家,如果人人都不讲规则而大谈道德、高尚,天天没事儿就谈道德规范,人人大公无私,最终会堕落成为一个伪君子遍布的肮脏国家。

适用于那些天天号召别人学习雷锋的人。

6. “美国人来了,既有面包也有自由;苏俄来了,只有面包没有自由;他们来了,既没有面包也没有自由。

原来先生几十年前就看破了……

关于 tmpfs

“tmpfs” 是 Linux 内核中另一个让人困惑的名字,它的实现是在 mm/shmem.c,”shmem” 猛一看和 “tmpfs” 根本不沾边,虽然我们知道 tmpfs 是基于内存的!我们可以通过看一下 tmpfs 都被用到哪些地方来了解它到底为什么叫这个名字。

你的桌面 Linux 系统中基本上都会挂载了 tmpfs:

% grep tmpfs /proc/mounts
devtmpfs /dev devtmpfs rw,seclabel,nosuid,relatime,size=1958956k,nr_inodes=489739,mode=755 0 0
tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev,relatime 0 0
tmpfs /run tmpfs rw,seclabel,nosuid,nodev,relatime,mode=755 0 0
tmpfs /sys/fs/cgroup tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
tmpfs /media tmpfs rw,rootcontext=system_u:object_r:mnt_t:s0,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0

正如这篇文章中提到的,/dev/shm 是 POSIX IPC 用到的,用来实现进程间通信。除了 sem_open(3) 的中 oflag 参数,基本上看不出来和文件有什么相关。

除此之外,另一个用到它的地方是 anonymous shared mapping!

mmap_region():

        if (file) {
        //...
        } else if (vm_flags & VM_SHARED) {
                error = shmem_zero_setup(vma);
                if (error)
                        goto free_vma;
        }

shmem_zero_setup() 在内核通过 kern_mount() 挂载的(用户不可见的) tmpfs 的根目录中创建了一个”dev/zero”的文件,注意,这里可以重复创建哦,因为内核跳过了类似 may_create() 的检查,而且这个文件本身很特殊,它一开始就是 unlinked 的。所以内核实际上是通过 tmpfs 中的一个文件来实现了匿名的共享映射!到此,你可以看出,tmpfs 这个名字其实名副其实了。

另外,tmpfs 本身可以随意挂载,通过 mount -t tmpfs,你可以在上面进行任意文件操作。所以,内核通过 tmpfs 一套代码把下面三个东西给统一起来了:1. 匿名共享映射;2. POSIX IPC;3. tmpfs 文件操作。Mel Gorman 这样解释到:

This is a very clean interface that is conceptually easy to understand but it does not help anonymous pages as there is no file backing. To keep this nice interface, Linux creates an artifical file-backing for anonymous pages using a RAM-based filesystem where each VMA is backed by a “file” in this filesystem. Every inode in the filesystem is placed on a linked list called shmem_inodes so that they may always be easily located. This allows the same file-based interface to be used without treating anonymous pages as a special case.

之所以用 tmpfs 而不是同样基于内存的 ramfs 是因为:1) tmpfs 文件是可以 swap 的;2) tmpfs 是有大小限制的,不会允许用户无限制使用内存从而导致 OOM。(注:只有当 CONFIG_SHMEM=n 时,tmpfs 才会调用 ramfs 代码。)