在 macOS 系统上创建、挂载 Ramdisk(aka: RamFS、tmpfs)

1. 计算扇区数(Sectors)

扇区这个概念是从机械硬盘时代有的,后来为了保证向前兼容,在目前早已没有扇区的 SSD、优盘上仍旧保留了逻辑上的「扇区」概念。
一个扇区是 512 字节(bytes),所以 64MiB 的 RamFS,扇区数就是:

 64MiB * 1024KiB/MiB * 1024B/KiB / 512B/sector = 131072(sectors) 

2. 创建基于内存的设备文件

在 OS X 10.4 以上的操作系统中,对于储存类设备文件的管理已经交由 hdiutil 这个基于 DiskImages 框架的命令行工具进行管理类。[1]
所以我们的这个 RamFS 的设备文件的创建也不例外。先打开 Terminal,执行如下命令:

$hdiutil attach -nomount ram://131072

然后终端上会显示出创建的设备文件
/dev/disk2
命令中:131072 即为扇区数。nomount 表示不要挂载,待会儿我们创建完文件系统再手动挂载。

3. 创建文件系统

光有了基于内存的设备还不够,我们还需要在其之上创建文件系统。就像买了一张软盘,买回来之后我们还需要格式化才能使用一样。(这里举例没有使用优盘、硬盘的例子是因为这些相对「现代」的存储设备一般在出厂前都预先格式化过了。而大部分的软盘出厂前是没有格式化的,当然后期的软盘会格式化啦)这里我们创建 HFS+ 格式的文件系统,卷标为「Ram Disk」:

$newfs_hfs -v 'Ramdisk' /dev/disk2

然后终端上会回显信息:
Initialized /dev/rdisk2 as a 64 MB case-insensitive HFS Plus volume
其中带「r」的「/dev/rdisk2」是 /dev/disk2 的原始设备。

4. 挂载 Ramdisk

这里就很常规了,我们可以使用 UNIX 上传统的 mount 命令,把 /dev/disk2 挂在到任意目录。比如:编译时候的中间目录、浏览器缓存、Web 服务需要大量 IO 的目录,等等。

$mkdir -p ~/Ramdisk
$mount -o noatime -t hfs /dev/disk2 ~/Ramdisk

5. 搞定了

上一步其实就完成了,我们可以在 Finder 中个人 Home 文件夹下找到 Ramdisk 并打开了,在左侧也能看到被挂载的 Ramdisk。
其中 mount 命令中 noatime 选项是为了让文件系统不更新访问时间,以减少磁盘 IO,进而提高性能[2](注:参考文献是针对 Linux 的)。不过实际效果可能很有限。
Finder 中展示 Ramdisk
在 Finder 中显示已挂载好的 Ramdisk

6. 接下来。。。

可能会有些担忧,毕竟在 Finder 中左侧 Navbar 中直接展示出 Ramdisk 中感觉会比较显眼,可能不知道什么时候就给随手 eject 出去了。
所以,我们把他隐藏起来。这里可以 UNIX 上传统的 mount 命令(在 -o 选项中加入 nobrowse 参数)或者,也可以使用来自 Apple 的 hdiutil 工具。方法是在用 hdiutil 挂载时,使用 -nobrowse 开关。

$hdiutil mount -nobrowse /dev/disk2

注:如果已经挂载了,记得先用 umount /dev/disk2 命令卸载。
终端会回显:
/dev/disk2 /Volumes/Ramdisk
然后,在 Finder 中就不会出现了。

7. 再接下来。。。

我们可以设置开机自启动,虽然自从用了 macOS 重启的次数几乎很少了。

7.1. 创建脚本

以下以替换系统的临时目录(/private/tmp)为例:
保存文件为 ramdisk.sh 到 root 的 Home 文件夹(/var/root)中(需要 root 权限),当然其他地方也可以,但要注意修改之后步骤的路径:

#!/bin/bash
ramdisk_size_in_mb=64
mount_point=/private/tmp
 
ramdisk_size_in_sectors=$((${ramdisk_size_in_mb}*1024*1024/512))
 
ramdisk_dev_file=`hdid -nomount ram://${ramdisk_size_in_sectors}`
newfs_hfs -v 'Ramdisk' ${ramdisk_dev_file}
mkdir -p ${mount_point}
mount -o rw,noatime,nobrowse -t hfs ${ramdisk_dev_file} ${mount_point}
chown root:wheel ${mount_point}
chmod 1777 ${mount_point}

执行「sudo chmod +x /var/root/ramdisk.sh」,加上执行权限。

7.2 再接下来。。。

创建文件 com.emitial.ramdisk.plist 到 /Library/LaunchDaemons/ 中:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
 3 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 4 <plist version="1.0">
 5     <dict>
 6         <key>Label</key>
 7         <string>com.emitial.ramdisk</string>
 8         <key>ProgramArguments</key>
 9         <array>
10             <string>/var/root/ramdisk.sh</string>
11         </array>
12         <key>RunAtLoad</key>
13         <true/>
14     </dict>
15 </plist>

8. Finally

至此,结束。

fin.

Note:
[1] hdiutil(1) Mac OS X Manual Page
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/hdiutil.1.html
[2] Securing and Optimizing Linux: RedHat Edition -A Hands on Guide
http://www.tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap6sec73.html

Bibliography:
[1] hdiutil(1) Mac OS X Manual Page
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/hdiutil.1.html

posted @ 2017-03-18 18:38  emitial  阅读(3300)  评论(0编辑  收藏  举报