スポンサードリンク


Warning: Illegal string offset 'cache_time' in /home/fumi/public_html/wp-content/plugins/tweetable/tweetable.php on line 404

Boxで50G貰い、boxfsでアクセスできるようになるまで

BoxにAndroidで登録すると50Gプレゼント、というのを3/23までやっています。
そろそろサーバのディスク容量も少なくなってきたので、すぐには使わない大容量のバックアップはLinuxでboxfsでマウントしてBoxにコピーしてしまおう!

手順

1. androidにboxのアプリをインストール

2. 登録



3. すると、以下のような画面が表示され50Gプレゼントされたようです。



PCからログインして確認しても、この通り50Gあります。





4. LinuxにFUSEのカーネルモジュールのインストール
CONFIG_FUSE_FS が設定されていれば使用できますが、自分のサーバは貧弱なので後述するように少し修正を加えています。

5. boxfsをコンパイルするために、以下をそれぞれインストール
5.1 libfuseのコンパイル
現時点では 2.8.7 が最新バージョンですが、それを使用すると

 "/bin/mount: 認識できないオプション`--no-canonicalize'です(/bin/mount: unrecognized option `--no-canonicalize')"

と言われてしまうため、古いバージョンを使用した。/bin/mount コマンドのバージョンによるようです。

$ tar zxvf fuse-2.8.5.tar.gz
$ cd fuse-2.8.5
$ ./configure --prefix=/usr/local
$ su
# make install

5.2 libzipのコンパイル

$ tar jxvf libzip-0.10.tar.bz2
$ cd libzip-0.10
$ ./configure --prefix=/usr/local
$ make
$ su
# make install

5.3 libappのコンパイル

$ tar zxvf drotiro-libapp-0.2.0-17-xxxxxx.tar.gz
$ cd drotiro-libapp-0.2.0-17-xxxxxx
$ make
$ su
#make install

6. boxfs のコンパイル

$ svn checkout http://boxfs.googlecode.com/svn/trunk/ boxfs-read-only
$ cd boxfs-read-only
$ vi Makefile
CFLAGS +=-I/usr/local/include
# LD_LIBRARY_PATH するのが面倒なので固定リンクしてしまう
LDFLAGS =-L/usr/local/lib -Wl,--rpath,/usr/local/lib
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig make
$ su
# make install

7. マウントしてみる

$ /usr/local/bin/boxfs -u メールアドレス -p パスワード -s -D 0755 /mnt/box_net

dfでみても、ちゃんと50g認識してる!

$ df -h Filesystem サイズ 使用 残り 使用% マウント位置
boxfs 50G 17M 50G 1% /mnt/box_net

box.netの無料ユーザには一ファイル当たりのファイルサイズの制限があります。そのため、数ギガのファイルはsplitで分割して書き込めばオッケー!(てへぺろ)、と思っていたところ、「空き容量がありません」といったエラーが出力されました。boxfsのソースを追ってみると、書き込む前に、/tmpに一時ファイルを作ってから、(http的には)アップロード、という流れのようで、/tmpへの書き込みが多重で実行されたために(/tmpの容量が足りないわたしの環境では)上記のような容量不足のエラーになっていたようです。

boxfsのソースを修正して、/tmp以外に一時ファイルを作るという解決案もあったが、多重で実行することをやめるようにソースを修正した。ソースの修正箇所はカーネルモジュールの方になりますので、修正後、再ビルド。(修正箇所は以下)

fs/fuse/inode.c

//#define FUSE_DEFAULT_MAX_BACKGROUND 12
#define FUSE_DEFAULT_MAX_BACKGROUND 1

# なお、boxfsのマウントオプションで自動的に25Mに分割して書き込むこともできるようです。(ただし一時ファイルは元のサイズで作成されるので、ウチには不向きであった)

カーネルモジュールのビルド後、modprobe -r fuse でモジュールをアンロードしたあと、モジュール を /lib/modules/xxx/ 配下に上書きコピーしたあとマウントしてみる。前回同様にsplitしながらコピーしても該当のエラーが出なくなりました。df で見ても、split しているサイズを越えることはなかったです。

splitされたファイルがアップロードされたあと、box.net上のファイルをcatで繋げてmd5sumとると、split前のファイルと同じで一安心。

50Gという大容量ですが、最大ファイルサイズが100Mなので、windowsから使用するとどうしても使いづらいですがLinuxでマウントすれば各種ツールが使えるのでぐっと実用的になりますよ!

Redhatのext3のマウントモードはorderedです!

LinusがExt3のデフォルトのdataモード(mountオプション)をWritebackに変えたんだけどRedhatはorderedのままなんだそうだ。会社ではRedhatだから良いんだけど、、、性能も求められるしなー。

RedhatクローンのCentOSもそうなのかなぁ。ウチの場合は最新カーネルのコンパイルを行なったからかwritebackになっているのかな。

参考:革命の日々! Redhatプロダクトではext3のデフォルトモードをwritebackに変えないよ

O_TRUNCを指定してopenしたファイルをcloseするとsyncすることがある

Linuxのローカルファイルシステムの話です。かなりハマっていたので記事として残しておきます。

既存ファイルがある状態でO_TRUNCを指定してopen(2)を呼び出し、適当に書き込んだあとclose(2)すると、非同期ながらWritebackされ物理IOが発生します。close時はfsyncせず、書き込まれたデータはDirty状態でページキャッシュに保存されるだけのはずなのだが(参考:Linux の close は fsync 相当を調べる – naoyaのはてなダイアリー)。。。何を言っているのかわからねーと思うので、状況を再現する手順は以下のとおり。

  • ファイルを適当に作っておく。

$ echo test > test.dat

  • 以下のようなソースファイルを作成し、コンパイルしておく
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
  int fd;
  char *p = malloc(10*1024*1024);

  fd = open("test.dat", O_TRUNC | O_CREAT | O_WRONLY, 0666 );
  write(fd, p, 10*1024*1024);
  close(fd);

  return 0;
}
  • 実行する前に、/proc/meminfo の Dirty・Writeback の値を確認する。
  • 実行する(ディスクランプ・iostatでディスクへの書き込みを確認する)
  • 実行後、/proc/meminfo の Dirty・Writeback の値を10秒間程度確認し、実行前に比べDirtyの値が10M増えたままであればsyncされていないが、Dirtyの値が変わらない、もしくは、Dirtyの値が増えた後減って実行前の状態に戻った(そのときwritebackの値が0より大きい値)、ようであれば writeback されていることになる。

※ vm_dirty*** 系のパラメタはこのタイミングでwritebackされないように適当に大きくしておく。

色々試してみたところファイルシステム依存で、ext3(data=writeback), xfs についてはclose(2)時にディスクへの書き込みが行なわれた。ext3(data=ordered), ext2, reiserfsについてはそのようにはならなかった。また、ext3(data=writeback), xfs でも既存ファイルが無い状態での O_TRUNC ではWritebackされず、Dirtyのまま残る。

ファイルシステム毎に試してみたところ以下のようになった。(たぶん合っていると思いますが、間違っていたら指摘ください)

ファイルシステム 既存ファイル無しでO_TRUNC 既存ファイル有りでO_TRUNC
ext2 close(2)のタイミングでデータはwritebackされず、Dirtyのままである 同左
ext3
(data=ordered)
close(2)のタイミングでデータはwritebackされず、Dirtyのままであり、メタデータ・データはcommit間隔にて同期される。 close(2)のタイミングでデータはwritebackされず、Dirtyのままであり、メタデータ・データはcommit間隔にて同期される。(しかし、同期された後もDirtyからは消えない?)
ext3
(data=writeback)
メタデータはcommit間隔にて同期される。close(2)のタイミングでデータはwritebackされず、Dirtyのままとなる。 close(2)時にwritebackされる(close(2)はsyncの復帰を待たず復帰)
reiserfs close(2)のタイミングでデータはwritebackされず、Dirtyのままである 同左
xfs close(2)のタイミングでデータはwritebackされず、Dirtyのままとなる。 close(2)時にwritebackされる(close(2)はsyncの復帰を待たず復帰)

今まで、ファイルへの書き込みはLinuxのページキャッシュ機構により、非同期でwritebackされると思っていたがこういうタイミングでもwritebackされるとは思っていなかった。お仕事でLinuxを使う場合は、close(2)のターンアラウンドタイムとディスクアクセスが性能見積りと異なる場合があるので要注意かなぁ。(こういう仕組みになっているのは、どうやらジャーナルとデータとの関係のようだが詳細が分かったらまた追記します)どうやらtruncateしてファイルサイズが0でファイルの実体がsyncされていない状態でクラッシュすると、ファイルが失われるため、それを防止するためにtruncate時は早めにsyncするようです。

参考までにSDカードにファイルシステムを作ってみて、上記プログラムをstrace上で動かしてみたときのシステムコールの時間を残しておきます。

既存ファイル有りでO_TRUNC:(単位はms)

ext2 ext3(data=writeback) ext3(data=ordered) reiserfs xfs
open 0.065 0.0925 0.086 0.134 0.184
write 53.775 90.2 227.090 65.586 37.911
close 0.027 17.874 0.026 0.047 8.159

(太字にした)ext3, xfs のclose時にwritebackの処理のため(?)に時間がかかるようです。また既存ファイルが無い状態での同じプログラムを動かした結果は以下のようになり、close時のwritebackが行なわれませんでした。

既存ファイル無しでO_TRUNC:(単位はms)

ext2 ext3(data=writeback) ext3(data=ordered) reiserfs xfs
open 0.0685 0.075 0.074 0.1 0.134
write 55.501 93.967 134.721 67.165 37.093
close 0.0255 0.028 0.024 0.046 0.0815

2011/1/4 追記:
ext3 のマウントモードがwritebackである旨を追加し、ordered の場合の動作追記。

dovecot(Maildir)のためのXFSチューニング

MailboxFormat/Maildir – Dovecot WikiにあるXFSのあたりを適当和訳(以下)。

===============================

XFS

XFSのパフォーマンスは色々な要因に左右されそうだよ。要因はシステムもあるしファイルシステムのパラメタもあるよ。

(適当要約)
RaiserFSよりXFSがやや速いんだけど、RaiserFSっていろいろ微妙だからXFSの方がいいんじゃないの?

(適当要約)
ベストな唯一最高のFSなんて存在しないよ!
メールサーバで、MaildirにはXFSがおすすめ。

  • 誰かがwikiに「TSL 3.0.5(Trustix Secure Linux)のインストールでXFSはEXT3の2倍だよ」と更新している。
  • XFSが最良という比較記事(訳注:ここにマウントオプションやらXFSの作成時のオプションが記載されています):

http://www.thesmbexchange.com/eng/qmail_fs_benchmark.html
http://www.htiweb.inf.br/benchmark/fsbench.htm

===============================

という情報から、とりあえずXFSのマウントオプションに、”noatime,logbufs=8″ を付けることにした。

dovecotチューニング

とりあえず、MailLocation/LocalDisk – Dovecot Wiki に従って、

mail_fsync = never

とした。ちなみに、初期設定は optimized であり、オプションには以下のとおり説明が記載してある。

# When to use fsync() or fdatasync() calls:
#   optimized (default): Whenever necessary to avoid losing important data
#   always: Useful with e.g. NFS when write()s are delayed
#   never: Never use it (best performance, but crashes can lose data)

見ていたら、XFSのチューニングなんかもあったから今度見てみよう!

ウェブメール(Roundcube)実現までの道のり1(devecotインストール編)

今現在、メールはEmacsのWanderlust(&pop3)で管理していたが、家のメールに、スパムが異常に多くなった点、Amazonや楽天などからの(半分くらいスパムの)広告メールが届くようになってしまった。その状態で、例えば送り元に”Amazon”が場合では、ごちゃまぜディレクトリに放り込んでおくのは嫌なので、scmailの振分定義に Amazon の振分の定義と、振分先を定義する。それで終りなら良いのだけど、.folder にその振分先のディレクトリを追加しなければならない。この結構大変な2度手間が嫌になり、ウェブメールを自サーバ(Linux, CentOS)に導入することとした。

ウェブメールとしてはとしては、SquirrelMail が有名であるが、会社で以前使わされていて、HTMLベースで使いにくい印象しか残っていない。検索したところ、Roundcube というウェブメールクライアントを発見した。Ajex を使っていて、画面も Thunderbird などのメールクライアントと遜色ないので、Roundcube を使うことにする。

Roundcube を使うためには、IMAPのサーバが必要になる、ということで、Dovecotを自サーバに導入した。

  1. まず、Dovecot をダウンロードする。
  2. $ wget http://dovecot.org/releases/2.0/dovecot-2.0.7.tar.gz

    展開後、configureスクリプトを実行する。オールドタイプなので、/usr/local/dovecot にインストールされるようにする。また、LANだけ(どころか、localhost内)で使用するつもりなので、sslについても無効にした。

    $ ./configure –prefix=/usr/local/dovecot –without-ssl
    $ make
    $ su
    # make install

  3. 設定ファイルについては何も格納されていないので share 配下にあるファイルをコピーする。
  4. cd /usr/local/dovecot/share/doc/dovecot/example-config
    cp -r dovecot.conf conf.d/ /usr/local/dovecot/etc/dovecot

  5. 設定内容についてはまだあまり調べていないながら、以下のように設定しとりあえず使えるようになった。(変更点のみ)
  6. ■10-auth.conf
    mail_location = maildir:~/Maildir
    ■auth-system.conf.ext
    pam ではなく、shadow を使うようにする(?)
    ■dovecot.conf
    listen = *

  7. 実行ユーザについては、以下のとおり、143 に dovecot, 144 にdovenull ユーザを追加する。143 はIMAPのポート番号で、UIDとポート番号を合わせるのが個人的には好み。
  8. # groupadd -g 143 dovecot
    # useradd -M -u 143 -g dovecot -s /sbin/nologin dovecot
    # useradd -M -u 144 -g dovecot -s /sbin/nologin dovenull

  9. 使用するディレクトリを作っておく
  10. # mkdir /var/run/dovecot
    # chown dovecot:dovecot /var/run/dovecot

  11. rcスクリプトについては以下のとおりコピーする。
  12. # cp dovecot-2.0.7/doc/dovecot-initd.sh /etc/init.d/dovecot

    以下については修正必要。

    DAEMON=/usr/local/dovecot/sbin/dovecot

  13. そして起動
  14. # /etc/init.d/dovecot start

とりあえずこれで使えるようになったけど、チューニングパラメタなんかはいずれいじっていきたい。