2014年11月2日

archlinux on 树莓派注意事项

树莓派很早就有,两年前 HZLUG 还有线下活动的时候不少人都玩这个。而我一直是用多余的笔记本来当下载机的,所以直到不久前把老本送给老妈用(结果我从老家离开第二天,win7 系统就陷入无限自我修复循环,非常郁闷),才终于有口实入了一个。
真是小巧可爱,相见恨晚。稍稍折腾一下,可以很好的承担下载机甚至各种电视盒子的功能。于是这里记录一下 archlinux on Raspberry Pi B+ 的一些注意事项:
  • 系统
    archlinux 有 for 树莓派的版本,不二之选。对着 Installation 照做即可。不上桌面的话(可以直接用 xbmc)tf 卡其实不需要很大,我这里连 xbmc 都装完了才 1.8G。
  • 供电
    树莓派多数莫名其妙的不稳定问题都是出在供电上。我是最后翻出了以前带独立供电的 usb hub,硬盘和树莓派都从 hub 取电,现在 15 天了还算稳定。很多卖家推荐 5V2A 的充电器,但是线材的质量的影响也不小。可惜国内卖的线材极少有标注规格的,唉,我有点想念日本了,通常不用为这些边边角角的事情操心。
  • 花屏/显存
    B+ 直接上 archlinux 另一个常见问题是随机出现花屏。原因是显存没给够。在 /boot/config.ini 修改这一行即可 gpu_mem_512=128。
  • 下载
    transmission,有 web ui。目前除了某些文件名字特别长的种子(呀,貌似暴露了)会下载失败,没发现什么缺点。建议开启 blocklist,我用的是这个 http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=gz
  • samba
    外接的 usb 硬盘本来用的是 ntfs,结果树莓派机能本身就没那么强,基于 fuse 的 ntfs-3g 再多耗点 cpu,会导致实际传输速度的进一步降低。树莓派的网口只有 100M,本来就有约 10M 的上限,我用 ntfs 实测的速度大概是 4~5M。后来把 usb 硬盘格式化成 ext4,速度可以达到 5~6M,大概也就这样了。这个是目前最大的 regression,原来用笔记本千兆网卡飙到 40M 左右(机械硬盘的上限)是没问题的。如果路由器够强的话或许可以考虑把硬盘挂在路由器上。
  • xbmc 插件
    之前拿笔记本只当下载机。这次因为树莓派个头小,于是藏在了电视旁边,顺势折腾了一下 xbmc(就要改名 kodi 啦)。这东西还真是蛮强大,各种爱好者提供的 plugin 虽然不够精雕细琢,但是对于一个程序员来说,替换各种电视盒子的功能已经没啥障碍。这里给两个 plugin 的 repo,一个国内一个国外
  • xbmc 遥控器
    手机端推荐用 Yatse 当遥控器,比号称 xbmc 官方的那个好用。通常我是不开 xbmc 的(费电),需要的时候手机 ssh 到树莓派上(推荐 VX ConnectBot,用证书免密码登录自行 google 吧),运行 systemctl start xbmc(懒人当然要建个 alias)即可。看完片,遥控器直接 power off。

2014年11月1日

虫鸣

自从夏末以来,几乎每天下班,都能听到路边各色的虫鸣。蛐蛐、蝈蝈的声音在北方也很常见,我可以轻易分辨,但像这样婉约的,我还是第一次听到(为了上传这段音频才知道有 youlisten 这样的网站)。

Share Music - Embed Audio Files - Bug Buzz in Hangzhou China

生活中本不缺少美,缺少的是发现美的心情。

2014年10月19日

记忆里的家

很久没回老家了。前段时间正好趁年假即将过期,连着国庆狠狠回去住了些日子。

五味杂陈。

家乡已经有了不小的变化——新的马路,新的桥梁,新的楼盘——我只能像个外乡人一样,听司机、听同学、听父母浮光掠影的描述着他们所知的片段,然后附和的嗯嗯啊啊。

从我眼里望去,就在四车道马路对面高楼下巨幅招牌和闪烁的霓虹里,依稀还是当年绿树掩映下的四层红砖小楼,楼群的路口是漆了暖暖的淡黄色的围墙,墙上有镂空了的盆景造型,墙后不远还有个蓝色的垃圾箱,每周两次固定时间,都会有翻斗车缓缓开来,等着一旁的叉车来把垃圾箱高高举起。

老屋倒是没太大变化。只是母亲早就开始啰嗦屋小东西多。破家万贯,这是到了我这一辈仍难以改掉的陋习。父亲尤甚,他当年学徒时的笔记,乃至不知何年的物理化学课本仍是舍不得扔掉。而母亲又不想换大屋。于是我只能捡自己的回忆丢掉。几日之内,先后变卖了这些年来积攒的古旧硬件、软盘、光盘和书籍。再添置些新的电器,于改善生活品质虽不显著,毕竟聊胜于无。

只是,老屋的那种天然避风港的家的感觉,那种我置身其中就能慢慢回血,睡一觉就原地复活的神奇却从指缝间滑走了。我记得起老屋里每一件什物的前世今生,却感觉不到他们的主人和我曾是同一个人。

摘抄两个金句(忆自网络,大意):

  • 当你开始不自觉脱口而出『想当年』的时候,你已经老了。
  • 你热爱一切那些从前给你留下深刻印象的东西并奉为经典,而实际上你只是在怀念逝去的青春。

家一直都在。我回到从前的地方,寻到从前的事物,却再也触不到她。她只在我终将消散的记忆里,在我如水逝去的青春里。

所以也就释然了,该去的就让他去吧。

2014年7月19日

无题

一个同事走了。今天应该是头七。
跟他相识很早,那时他还是实习生。后来相忘于江湖,虽然还是同事,却基本没怎么打过交道。印象里始终是那个真诚的腼腆的大男孩。
这里是他最后的文字。其实每个心灵都有柔软的一面。
今天应该是头七,无以为祭。谨聆一曲『我用所有报答爱』,故人如歌。

2014年5月11日

我的又一个 fuse 客户端——upyunfs

我写 fuse 客户端可能有点上瘾,是因为我觉得对于在线存储类的服务,能够映射到本地存储,对用户来说是路径最短,学习成本最低、体验最友好的方式。而要实现类似的效果,据我所知要么用 fuse 把远端的存储挂载到本地(如 sshfs、amazon s3fs),要么写个后台服务实现本地和远端的双向同步(同步远端可以轮询或用某种 push 技术,同步本地可以用 inotify,典型案例是 dropbox)。而我之所以倾向前者,是因为 fuse 的实现成本要小很多,对于个人开发者来说性价比完胜。

有了上述前提,什么专门的 GUI 管理工具啦,专门的 shell 啦,在我看来都比较无聊——当远端的文件系统已经变成本地的一部分时,用户可以使用任意自己熟悉的文件管理工具(无论 GUI 还是 CLI),可以使用任意自己熟悉的 shell 环境(包括相应的各种工具),来完成对远端的文件管理任务。比如将 dropbox 同步到 upyun,在我看来只需要这样就可以了:
upyunfs -b lyman_foo ~/cloud/upyun # 挂载 upyunfs
rsync -avh ~/cloud/dropbox/ ~/cloud/upyun/ # 用 rsync 同步两个文件夹
所以看到 upyun 搞了开发者比赛的时候,我实在是忍不住,便写了这个 upyunfs

对实现细节不感兴趣的同学可以忽略下面的文字了,不过还是希望各位能给 upyunfs 投个票:到项目页面里找到 upyunfs-for-UPYUN,点击「投票」按钮即可。

接下来大概分析一下 upyunfs(以及类似存储系统)的实现要点。

一、技术选择

fuse 有各种语言的 binding,从执行效率角度考虑首选当然是 c/c++。但是如 upyun 这样提供 RESTful 接口的服务,用到字符串操作的地方不少,所以用脚本写起来更方便。python 的 binding 我试过一次,问题不少文档不多,所以我一直用 perl。

二、roadmap

  1. 基本功能
    这个阶段基本上只要做好 fuse 回调和 RESTful api 的映射就好了。具体一点,在线存储系统基本上必不可少的 upload/download/list 操作,大抵就可以对应到 fuse 的 read/write/getdir 上。此时如果有合手的 sdk,完成第一阶段会格外快。即使没有 sdk(这年头能直接提供 perl sdk 的公司实在是不多),用 libwww 实现一个也不复杂——像 upyun 官方的 python sdk 那样只包装了签名认证的,写一个也就个把小时。

    这一阶段的难点是 api 映射。因为 fuse 的回调基本上是标准的 unix 风格,文件需要先 open,read/write 之后再 release。了解 fuse 各个回调的语义及调用时机至关重要。如 upyun 并不支持带 offset、length  header 的 GET 操作(至少文档上没说),而 fuse read 每次被调用只读取 4k-128k 的片段,因此有必要将下载的远端内容缓存起来(阿里云的 oss 就可以无需如此)。同理,write 每次调用也是写一个片段,需要将写入远端的文件缓存起来,然后再一次性上传到远端。

    这一阶段完成后,基本的文件操作就都可以支持了。在网络条件很好的情况下也不会有太大的问题。
  2. 完善的功能
    这个阶段一是简化用户的使用,比如支持通过配置文件来读取用户名/密码/bucket;二是支持在线存储独有的功能,比如 upyun 对图片文件就可以通过配置一系列 x_gmkerl header 来改变上传行为。
  3. 优化
    这是个无底洞。根据使用场景不同,会有很多不同的策略和实现途径。

    比如在多数家庭网络条件下(adsl,下行带宽>>上行带宽),在 release 时的同步上传就会让 release block 颇久。而 gnome 3.12 在这种情况下是会死锁的。于是,对于使用 adsl 的 gnome 用户来说,release 就需要优化——比如通过线程来异步完成上传操作,而异步的引入会令数据一致性的维持变得复杂起来(目前 upyunfs 已经实现到这里)。

    再进一步,upyunfs 在第一次 read 文件的时候,就需要把整个文件从远端下载到内存中,如果用户的网络还要差,或者文件比较大,这会导致第一次 read 也 block 很久。那么是不是应该优化下载过程,把原来一句简单的 $respond = $ua->request($req) 替换成其它实现,可以不用等到整个文件下载完成才返回?

    再进一步,如果用户的内存不太够,是不是应该支持用户把读写 cache 设置成本地文件系统的一个临时目录?

    还有,对 fuse 回调实现,需要其行为多大程度上跟其 unix 同名 api 的语义一致?如 open、read 的时候是否需要参考诸如 O_TRUNC/O_NONBLOCK 这样的 flag?

    如上所述,这个阶段有太多的如果,而且每个点都不可避免的导致设计复杂或者代码激增,从而需要更多的投入。但不能否认,这些细节才是 upyunfs 是否成熟的标志。
ps. 给阿里云 oss 写的 ossfs 已经 outdated 了,测试用例挂了一堆,有空我会看下是不是 oss 有啥改动。