截止目前为止的婚姻生活
那么,春节回家领完结婚证。星期二她回到北京,到现在还不到一个星期。
从昨晚到今天,一直的冷暴力。我对她说话,她也不回答,随时的不耐烦。
卡里依然不停被她转走的钱。和她过年前说的完全不一样。到发工资前,又只剩下一千不到。
我是努力告诉自己不要抱怨呢。可是才刚刚结婚一个月不到,就到这样的境地,让人怎么热爱这一切呢?
那么,春节回家领完结婚证。星期二她回到北京,到现在还不到一个星期。
从昨晚到今天,一直的冷暴力。我对她说话,她也不回答,随时的不耐烦。
卡里依然不停被她转走的钱。和她过年前说的完全不一样。到发工资前,又只剩下一千不到。
我是努力告诉自己不要抱怨呢。可是才刚刚结婚一个月不到,就到这样的境地,让人怎么热爱这一切呢?
The reason to mount NFS over SSH is simple for my case: my NAS is in my home, but I need to access it from my laptop when I'm outside my home. I chose NFS as I stay at home most of the time, in which case my laptop is in the same LAN as the NAS. There is obviously no need to set up another set of mechanism.
To secure the NAS, it is better that it stays in the LAN. It would be simpler to set only one port mapping rule from the configuration interface of the router, that is the port for SSH (I still need SSH anyway), from LAN port 22 to WAN port 20022.
In this way, I don't need to set up the authentication and encryption for NFS separately.
Installing NFS on the both machines is easy. Mounting can be easily done when connecting directly. However, when trying to mount over SSH, I found the steps found by Google does not work.
In my case, NFSv3 is used.
In addition to nfsd, mountd also need to be accessed from the client. By default, mountd uses a random port. However, to access mountd easily, I fixed the port used by mountd by adding those lines to /etc/services of the server:
mount 32759/udp
mount 32759/tcp
After restarting the server to make the changes into effect, running ssh on the client machine to forward the ports:
ssh home.kmxz.net -fNv -p 20022 -L 3049:localhost:2049
ssh home.kmxz.net -fNv -p 20022 -L 33759:localhost:32759
The next step is to mount the NFS on the client machine:
sudo mount -v -t nfs -o soft,intr,nolock,port=3049,mountport=33759,tcp localhost:/mnt/aufs /mnt/nas
nolock option is necessary, otherwise the client machine will try to lock files on the client itself. tcp is also necessary, as mountproto will be UDP by default, but SSH only support TCP forwarding.
自己电脑上各种资源实在太多,硬盘空间紧张。此时搭建一个 NAS 放在家里就显得很有必要了。于是今年终于动手了。

由于专门的 NAS 硬件太贵,动辄好几千。我便在淘宝上四百多块钱买了一块 12 * 12 cm 的主板,上面带一块 J1800 双核赛扬(有的 Atom 主板尺寸更小功耗更低,然而价格贵了些)。单独购买外置的 12 V 电源时,考虑到可能同时带一块 3.5" 硬盘和一块 2.5" 硬盘,于是买了 7 A 的适配器。又在淘宝上买了一块 3T 的西数红盘(WD30EFRX)作为硬盘。最后,把老笔记本上的 2G SO-DIMM 内存条拆下来装到主板上。

现在硬盘和主板直接放在柜子里,不过有个「机箱」更好。我于是拿卡尺量了一下它们的尺寸和螺丝孔的位置,画了一个外壳:由四片亚克力拼成,硬盘放下面,主板放上面。准备到淘宝上找商家切亚克力板,自己拿螺纹塞规钻出螺纹。

软件上考虑使用 NFS 实现文件访问。借用办公室的显示器和键盘安装 Ubuntu 15.04 后将 NAS 拿回家,搭建 NFS 服务器。
考虑到网络读写不稳定,且 NAS 很大作用是保证数据即使在其它客户端被攻陷后也不丢失损坏,便想到用 union mount。Union mount 简而言之就是把一个只读目录(lower)和一个可读写目录(upper)映射到同一个目录(union)里。用户读取 union 中的文件时,实际就是从 upper 或 lower 中读取,而用户修改 union 中的文件时,所有改动都会被存进 upper 里。这样 union 看起来就是一个完全可读写的普通目录,然而 lower 目录实际并不会被更改,因此处于相对安全的境地。我只要定期 ssh 到 NAS 上看看具体修改了哪些内容,把确定需要保留改动从 upper 里写入 lower 里就好。
Union mount 现在最常见的两个实现是 AuFS 和 OverlayFS。前者由于被 Docker 采用,前两年忽然又火了一阵,然而实现非常复杂。后者的原理和实现都非常简洁,且在 3.18 时被合并进了 Linux 内核。因此我选择了 OverlayFS,并且专门为其写了一个工具。事与愿违的是,我发现无法在 OverlayFS 之上建立 NFS 服务器(i.e. OverlayFS 无法被 export 到 NFS)。于是我只好改用 AuFS 了,毕竟 AuFS 官方主页里就有 export to NFS 的指南。
具体设置较为简单:AuFS 部分,在 /etc/fstab 中加入
none /mnt/aufs aufs noauto,x-systemd.automount,br=/var/userdata/upper=rw:/var/userdata/lower=ro 0 3
NFS 部分,安装 nfs-kernel-server 后在 /etc/exports 中加入
/mnt/aufs *(rw,async,fsid=0,crossmnt,root_squash,no_subtree_check)
就此,NFS 就已经可以在家里的内网放问了。然而,要在外网访问,需要考虑安全的问题。NFSv4 开始支持使用 Kerberos 进行身份验证。然而搭建 Kerberos 相对麻烦,我便想到曲线救国,直接使用 ssh 进行端口转发完成加密和认证。虽然这样会带来一些 overhead,不过由于我在外网访问 NAS 的频率低于在家里访问,所以问题尚不算大。
接下来就是在路由上设置端口转发允许外网访问到 NAS 的 22 端口。首先想到的是 MiniUPnPc,这样不用进入路由器设置里也可以完成端口映射,且不需要 NAS 有固定的内网 IP。然而联通配的路由器没有开启 UPnP。进路由器设置界面,发现里面既无法直接设置端口映射,也无法打开 UPnP。好在根据网上找到的方法破解了它后,就可以设置端口转发了。既然已经进了路由器管理界面,干脆直接给 NAS 设置了固定的 IP,打开固定的端口映射。再配合上 DDNS,就可以畅快地从外网也访问 NAS 了。
北京联通免费安装的 HG8346R GPON 终端实在非常糟糕。它自带了路由器的功能,但却无法开启端口映射或 UPnP。
于是我根据 [1] 和 [2] 的教程,花一个多小时快速破解了它,打开了这些设置。
在此记录下我的操作:

back cfg by tftp svrip 192.168.1.2 remotefile hw_ctree.xml 将配置文件导出至 192.168.1.2。su,此时需使用 [2] 中提供的 Python 脚本计算出验证码。restorehwmode.sh 将 HG8346R 从联通版本的界面恢复至华为版本的界面,并恢复了出厂设置。成功进入功能完整的管理界面。但是由于设置已被覆盖,此时无法连接广域网,此时可选择以下其中一种方法:
aescrypt2 先将配置文件解密后修改,再重新加密后上传。解开后发现这款路由器一旦恢复华为界面,功能还是非常强大的。DDNS 什么的都有内置支持,甚至还可以作轻量级 NAS 用。
不得不万分感谢前人的努力和他们无私的分享!
7 月初的时候有幸去了新竹,参加「两岸清华与香港科大程式设计竞赛」。这个比赛每年举办一次,在北京、新竹和香港三地由三校轮流举办。运气很好,今年是去新竹,而非留在香港或是回北京。
周四早上从香港出发,周日中午便回来,时间并不算长。然而,给我留下的记忆恐怕却比半个月后再次去台湾环岛的那十多天留下的记忆深刻。
第一天晚上到了新竹,所住的旅店并不大,也并不奢华。和我住同一间的两个学弟,其中 YQ 君是湖北来的新生。当晚睡觉前,我提议先上 Codeforces 做上几题练手。随后便发现,他的实力比我不知高到哪里去——每一题都能很快想出来,并且写出来。而他说的数据结构我甚至都没听说过。

第二天比赛时,果然基本是靠 YQ 君一个人做题;而我们作为科大二队,最后运气很好拿到了全场第三,次于两只清华的队,领先于一队、清大的两只队和女队。
于是我常常是庆幸的——虽然由于各种阴差阳错,我到了大四才进入 programming team,并且最终也只参加了一次 ICPC regional。
大学的前两年,我根本没有听说过学校有 programming team——因为那时每年招新的邮件都只发给 CS 的学生,而我那时还没有进 CS 的邮件列表。到了后来我知道有 programming team 时,和 YW 君一起刷了半个月的题,然而最后校内选拔时,最终只解出一道题排在第七——那年招了六个人组两只队。那天晚上我心情可谓沉痛,看了看,有两三道题都是差一点点细节就能做对的。
到 final year 进了 team 后,我才意识到事情完全不是这样。每次 training 时,队友都展现出远胜于我的知识和熟练度;而比赛时他们的沉着和自信也完全不是我能比的。在这个 team 里,我总能深深体会到,比我年轻的 teammates,各方面比我强得太多——我能够混进 team 已经是全靠运气。
一路上他们的谈话跟我都不是在一个 level 上的——他们拿着 above 4 的 GPA,修着 pure mathematics (advanced) 专业,上着全理论的 PG 课——尽管只是新生萌妹子。
于是我总意识到,自己的水平和努力程度远远不如别人,怎么可能能有资格幻想美好的前途。
比赛之后的夜晚,我就和萌妹子 RY 君去清大打 Ingress,做校徽拼图的 mission——虽然她半途而废了。校园里当是时下着阵雨,于是我们不得不打伞和避雨。她的手机看来是比我快不少,每次都能抢在我前面拿到 UPC。
她先回旅店之后,我一个人回到清大校园继续完成校徽拼图的 mission。
清大的校园有不少和清华神似的地方——譬如狭长的大草坪和其边的日晷。而在校园里的山坡边上见到有 portal 是「西南联大时期校歌纪念碑」;联想起我创建的西南联大的 mission,我瞬间有了种历史的苍凉感——尤其是再一联想到,校门外面那条路名赫然是「光复路」,更觉得一丝凄凉。
就在雨后的凄凉里做完所有 30 个 mission,已经凌晨两点。第二天晚上又和 RY 君在周边散步,做了几个闲杂 mission。