locate (2)

ipadのアプリが更新されたんで、新しく出来ると案内が出てきた。よくある風景。

じゃアップデートするか。updateボタンをクリックしたら、暫くして、HDD?SDD の容量不足でアップデート出来ませんとか言ってきた。

設定、一般、ストレージとiCloudの確認画面で、残り容量を確認してくださいってさ。普段、そんなの気にした事無いぞ。 言われた通りに、容量確認したら、残りが1Gを切ってた。

おかしいなあ、容量を喰いそうなのは入っていないはずなのに。容量を喰うのは AV系と心得ている。音系と画像系ね。音楽も聴かないし、動画を溜める事も無いし、 ましてや写真を撮る事も無いから。。

アプルの偉い所は、残りDisk容量を報告するとともに、アプリが抱え込んでいる データも含めて、アプリ毎の使用量を表示してくれるのね。それも、容量順に。

こういう親切な所は、無骨なOSじゃ決してやらないだろう。ユーザー心理を先回り してくれてると思うぞ。

で、一番容量を喰ってるのは、女房御用達の某アプリ。4Gに膨れあがっていた。 これを消せば、一気に4Gの空きが出来るな。でも、そんな事をしたらぶっ飛ばされ そう。触らぬ神に祟り無しって言うから、消すのは次点のアプリからにした。

一応、消していいか女房に確認しながらね。ipadを手に入れた頃は、面白がって 色々なアプリを入れたけど、その後さっぱり使っていないのが山積だったよ。 それらを気前よく消して行く。そして、何とか3Gの空きを作った。 これで、暫くは安泰だろう。

でも疑問が。女房が一番使ってる某アプリ。使ってるうちにごみを残すBugが 内在してるっぽい。一番確かなのは、一度アプリを削除して、再インストール してみる事。

アプリ毎の独立性を高める為、それぞれのアプリ領域内にデータエリアが内在 してるはずなんで、アプリを消せば、データも削除されるはず。

その大事なアプリがストアに残っているか、ちと心配。危ない橋を渡るより、 空きエリアを増やしたので、様子見という方向で、取りあえず決着させよう。

波風を立てること無いよね。

OpenBSD 6.0

「OpenBSD 6.0」が公開が 予定通りに公開された。案内によると、Linuxのエミュレーションが、 セキュリティーを理由に削除されたらしい。

強固にするには、どんな小さな穴でも塞いでおかないと、そこが最大の弱点に なるからね。この時期、台風が猛威を振るっていて、堤防の決壊がよく話題に なる。堤防の決壊と言うと、大雨で堤防が傷み、わずかに水が染み出した所を 見つけ、そこに自分の手で蓋をして、決壊を防いだと言う逸話を思い出す。

勿論、大災害はそれだけでなく、溢れによっても発生する。 SYNフラッド攻撃に対抗するための処置も施されたらしい。SYNパケットの 溢れによる対策って事で、これも洪水だろう。益々、強固になるOpenBSDで この秋を乗り切りましょう。そうすれば、DDoS攻撃で、ネットが繋がりにくく なっています、なんて案内を見る事も少なくなるだろう。

攻撃が一巡したら、視察と称して、どんなOSを使ってたか調べてみるかな。 あの場所とこの場所とその場所と、、、オイラーが定期巡回してる所が 軒並みやられていたからね。

インストール中は、オイラーの所にも洪水攻撃の余波が回ってきた。 arm-none-eabi-gcc-linaroなんていう巨大なやつを落としている時、DLスピードが突然低下した。 これは好機とばかり、pkg_addの挙動を観察。そしたら、pkg_add等が、

[ob: ~]$ file /usr/sbin/pkg*
/usr/sbin/pkg_add:        a /usr/bin/perl script text executable
/usr/sbin/pkg_check:      a /usr/bin/perl script text executable
/usr/sbin/pkg_create:     a /usr/bin/perl script text executable
/usr/sbin/pkg_delete:     a /usr/bin/perl script text executable
/usr/sbin/pkg_info:       a /usr/bin/perl script text executable
/usr/sbin/pkg_mklocatedb: a /usr/bin/perl script text executable
/usr/sbin/pkg_sign:       a /usr/bin/perl script text executable

こんな具合に皆perl製だった。実体は、pmになってて、/usr/libdata/perl5/OpenBSD に、58個も属が登録されてた。

OpenBSDは、デフォでperlが入っていたのね。 FreeBSDみたいに、積極的にPerlを排除していったのとは対照的だなあ。

ああ、perlと双璧を成すpythonは、デフォでは入っていないけど、gdbを 入れると、それに釣られて入ってくる。2系ってのが、ちょっと気に障るな。

rubyはどうかと思って調べてみると、

 ruby-1.8.7.374p7.tgz                                  2.2M
 ruby-2.0.0.648p1.tgz                                  5.7M
 ruby-2.1.9p1.tgz                                      6.2M
 ruby-2.2.5p1.tgz                                      6.4M
 ruby-2.3.1p1.tgz                                      7.0M

こんな具合に、好きなの持ってて状態でした。2系でどんと容量が増えて いるのは、あの人のこだわりによるのかな?

こだわりと言えば、qemuが2.6になって、raspi2をサポートしました。 今まで無かったのが不思議。ラズパイ財団の特許が切れたので、公式に 解禁になったのでしょうかね?

ついでにgnuplotも入れた。わんさかとお供を伴ってやってきた。起動したら

set terminal unknow

なんていう不吉な事をぬかす。5.9で調べたら、x11って答えてきたんだけどね。 セキュリティー的な理由で、x11なデバイスは使えないようにしてるの? portsに有る、Makefileを調べてみるか。

BUILD_DEPENDS = emacs->=24:editors/emacs

FLAVORS =       no_cairo no_x11
.if ${FLAVOR:Mno_x11}
CONFIGURE_ARGS += --without-x \
                  --without-gd
.else
LIB_DEPENDS +=  converters/libiconv graphics/gd
WANTLIB +=      X11 fontconfig freetype gd iconv jpeg png tiff vpx
CONFIGURE_ARGS += --with-x
.endif

という設定になってた。設定をenableにして作り直し。インストールしようと したら、pkg作りでエラー。しょうがないので、マニュアルで強引にインストール。

# make install
Making install in wxterminal
Making install in qtterminal
 .././install-sh -c -d '/usr/local/bin'
  /usr/bin/install -c gnuplot '/usr/local/bin'
 .././install-sh -c -d '/usr/local/libexec/gnuplot/4.6'
  /usr/bin/install -c gnuplot_x11 '/usr/local/libexec/gnuplot/4.6'

起動してみると、x11が出てきた。

plot sin(x)

とかするとDISPLAYが見当たらんとか言われたので、

export DISPLAY=WINDOWS7_IPAddr:0

とかやったら、やっとサイン波を拝めた。やれやれ。それにしても、以前は DISPLAY設定が必要無かったけど、今回から必要になったのは、テオ君の 締め付けがきつくなったからだろな。これを設定しないと動かないって事は、 以前は、開けっ広げな設定だったって事?

ワイルドカード

今回の表題、locate (2) って、unixに精通した人には誤解されそうだな。 locateっていうシステムコールが有ると思っちゃうから。

manのセクション2って、システムコールの説明だ。セクション1は、通常の ユーザーが使うコマンドが載ってる。

同名のものが有ると、紛らわしいので、括弧を付けて、セクションを指示する のが、昔からの慣わしだから。と、年寄り臭い事を言っちゃった。

shellには、ワイルドカード(誤解を恐れず言えば、正規表現の一部)が用意されてる。 hoge* って、指定すれば、hogeの後ろに、どんな文字が来ても、マッチする。

ならば、* を単独で使った場合はどうか? 前回、locateの検索で問題になったあれ

[ob: z]$ locate * | wc
   15699   15699  765951
[ob: z]$ cd
[ob: ~]$ locate * | wc
   94764   94764 4629968
[ob: ~]$ cd /tmp;  locate * | wc
       1       1      24
[ob: tmp]$ locate '*' | wc
  270802  270803 12166914

最初の実行は、自分のHOMEDIR内、次は、/tmpに移動しての実行、最後は、ワイルド カードの機能を殺した場合。

同じDBを検索してるはずなのに、三者三様の結果になった。ジョーカーの使い方は 難しいのよと、悩むなかれ!

[ob: tmp]$ echo *
emacs1000 uscreens vi.recover
[ob: tmp]$ cd; echo *
CAT GZ OUT SICP forth hello src win xv6-armv7 z
[ob: ~]$ echo '*'
*

ワイルドカード文字が単独で与えられると、カレントdirをlsしたのと等価の 働きをするのがshellの約束。シングルクォートでくくると、ジョーカーの 意味を失い、文字そのものが、表示される。

BSDのlocateの統計情報

前回やった、どうだ凄いだろうと言う、統計情報。下記のようなデータを 見せられても、何のこっちゃいなんで、意味を紐解いてみる。

[ob: ~]$ locate -S

Database: /var/db/locate.database
Compression: Front: 18.92%, Bigram: 55.23%, Total: 13.07%
Filenames: 258508, Characters: 11599699, Database size: 1516307
Bigram characters: 678782, Integers: 5691, 8-Bit characters: 0

元のDBの表面的な状態は下記。

[ob: ~]$ ls -l /var/db/locate.database
-r--r--r--  1 root  wheel  1516307 Sep  7 06:55 /var/db/locate.database

そんな開けっ広げで委員会? locateのmanのBUGSに

     The locate database is built by user “nobody” using find(1).  This will
     skip directories which are not readable by user “nobody”, group “nobody”,
     or the world.  E.g., if your home directory is not world-readable, your
     files will not appear in the database.

こういう注意書きが有った。権利の弱い立場で、スキャンするよ。それで読めなかった ものは飛ばすよ。言い換えれば、誰でも読んでいいってやつだけだかんね。 だから、公開したくないやつは、Linuxみたいに壁を作っておけ。古き佳き習慣が 息づいています。何処かの田舎の、家を留守にする時も鍵をかけない習慣。 Linuxは、都会風に、コンビニにちょっと出かける時もドアに鍵をかける習慣。 隣は何をする人ぞってなっちゃったのね。

昔のunixは、隣の人から技を盗む共同社会だったからなあ、と、爺のたわ言。

この統計情報は、fastfind.cの中で定義されてました。 数値がもろに表示されてるのは、そのままの意味なんで。パーセントで表示される ものに注目します。

        (void)printf("Compression: Front: %2.2f%%, ",
            (float)(100 * (size + big - (2 * NBG))) / chars);
        (void)printf("Bigram: %2.2f%%, ", (float)(100 * (size - big)) / size);
        (void)printf("Total: %2.2f%%\n",
            (float)(100 * (size - (2 * NBG))) / chars);

ここで、sizeは、DBファイルのサイズ、bigは、バイグラム文字数、NBGは128、 charは、印字文字数(バイグラムに属さない文字)って事になるかな。

オイラー的には、Frontの数値、18%が注目かな。findで検索した文字列を、2文字 づつにぶった切った時、約5個に一つは、128種の組み合わせのどれかになるって事。

256種に拡張したらどうなるだろう?ロングテールの法則で、占有率は倍には ならないだろうね。

locate.code.c をちょっと見

余り変な所を見てもしょうがないので、code.cの部分を見ておく。

(gdb) b main
Breakpoint 1 at 0xb06: file locate.code.c, line 122.
(gdb) r bi.txt < fl.txt > z
Starting program: /tmp/locate.code bi.txt < fl.txt > z

Breakpoint 1, main (argc=2, argv=0xcf7c8f64) at locate.code.c:122

これ、emacs上からのターゲット起動。こんな風にリダイレクトも受け付けて くれるのね。

これは便利。emacs上でgdbを操作してる時、debug対象のプログラムから出力が 有った場合、emacsが気を利かせて、表示用のwindowが出来て、そちらにカーソル が行ってしまう。その結果、gdb制御用windowsがHideされちゃう。それが いやで、gdbserverから対象プログラムを起動してた。が、OpenBSDには、 gdbserverなんていうのが用意されていないんだ。

リダイレクト出来るなら、

(gdb) r > /tmp/hoge

とかやっておいて

tail -f /tmp/hoge

こんな具合に監視すれば良い。何? それじゃ、対象プログラムに会話的な 入力が出来ないじゃん。全くもってその通り。だけど、そういうプログラムを 今までdebugする事はまれだったよ。その必要が有るなら、Linuxででも。。。。

                          if ((code = BGINDEX(cp)) != (bg_t)-1) {
                                  /*
                                   * print *one* as bigram
                                   * Found, so mark byte with
                                   *  parity bit.
                                   */
  =>                              if (putchar((code / 2) | PARITY) == EOF)
                                          err(1, "stdout");
                                  cp += 2;

ここが核心部分かな。文字列中にbigramが見つかると、その位置がcodeに代入される。 それを2で割って、インデックス番号に直し、PARITYのビットとORしてる。 PARITYって名前は、人を惑わすよなあ。せめてMSBとかって名前が良いぞ。 EOFって何って思って調べると、putcharの所に

RETURN VALUES
     The functions fputc(), putc(), and putchar() return the character
     written.  If an error occurs, the value EOF is returned and the global
     variable errno is set to indicate the error.

簡単にエラーを調べる方法にEOFと付き合せるとな。

下記は、bigramが見つかった時の状況。arってのは、頻出語って事ですな。

(gdb) p cp
$4 = (u_char *) 0x3680c842 <buf2+2> "ar/www/logs"
(gdb) p code
$5 = 132
[ob: src]$ dc
16 o
132 p
84
q

10進、16進の変換方法を忘れるので、メモしたぞ。そして、 hexdumpで調べてみると

00000080  6d 65 70 6c 61 72 6e 66  6c 6f 72 61 74 61 73 5f  |meplarnfloratas_|

確かに存在してた。なお、BGINDEXのマクロは、下記のような定義だった。

#define BGINDEX(x) (big[(u_char)*x][(u_char)*(x + 1)])

ここで参照される配列bigは、mainの中程で、下記のように初期化されている。

        for (i = 0; i < UCHAR_MAX + 1; i++)
                for (j = 0; j < UCHAR_MAX + 1; j++)
                        big[i][j] = (bg_t)-1;

        for (cp = bigrams, i = 0; *cp != '\0'; i += 2, cp += 2)
                big[(u_char)*cp][(u_char)*(cp + 1)] = (bg_t)i;

最初、全エリアに、-1を書く。次にbigramを2文字づつ使って、bigのインデックス 番号とし、そこにbigram文字列位置を書いている。

こういう使い方って、暗号で出て来る換字表そのものだな。暗号のキーは、 勿論bigramを構成する256分の文字列。

mlocate

Fedoraでupdatedbを実施すると、大概はすぐに実行が終了する。BSD系とは大違い。 この差は何?

調べてみると、Fedoraが出た頃は、slocateってのが使われていた模様。頭文字のsは、 セキュリティーのsらしい。それが、ある時期からmに変わったとな。 なんじゃい、そのmってのは?

mlocateに説明が有った。

The 'm' stands for "merging": updatedb reuses the existing database to avoid 
rereading most of the file system,

へぇ、そんなに良い物なら、FreeBSDにも導入してやろう。 取って来て、第一の難関のconfigureは無事に通過。コンパイルの段でエラーだよ。

mlocate/mlocate.db"' -DLOCALEDIR='"/home/sakae/MINE/share/locale"'  -DGROUPNAME='"mlocate"' -DUPDATEDB_CONF='"/home/sakae/MINE/etc/updatedb.conf"'   -g -O2  -Wall -W -Wcast-align -Wmissing-noreturn -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings -MT src/src_updatedb-updatedb.o -MD -MP -MF src/.deps/src_updatedb-updatedb.Tpo -c -o src/src_updatedb-updatedb.o `test -f 'src/updatedb.c' || echo './'`src/updatedb.c
src/updatedb.c:39:20: fatal error: mntent.h: No such file or directory
 #include <mntent.h>
                    ^
compilation terminated.
*** Error code 1

無いヘッダーファイルって、何方面なの? getmntent使用例 例によって、リナ専用っぽいな。

ざっとコードを見ると、src/updatedb.cの中の下記関数内で使われている事が 判明。DBへの登録を除外するか否かの検出みたいだったので、除外はしないよ 関数にして、逃げた。

/* Return true if PATH is a mount point of an excluded filesystem */
static bool
filesystem_is_excluded (const char *path)
{
  return false;
}

これで、コンパイル出来たんで、実行してみると、DISKにがたがたとアクセス してて、最後に、

$ bin/updatedb
bin/updatedb: can not find group `mlocate'

こんなエラーで落ちた。グループを追加。一度logoutしてからloginし直し。 こうしないと、グループが有効にならなかったはず。

再度、実行。そして、再度エラー(笑)

$ MINE/bin/updatedb
MINE/bin/updatedb: can not change group of file `/home/sakae/MINE/var/mlocate/mlocate.db.1b5032' to `mlocate': Operation not permitted

このエラーでピンときた。ソースを見なくても原因が分かった。グループにオイラーも 混ぜて貰おう。

$ id
uid=1001(sakae) gid=0(wheel) groups=0(wheel),5(operator),61234(mlocate)
$ time MINE/bin/updatedb

real    6m37.84s
user    0m0.14s
sys     0m19.01s

どうやら、旨く行ったみたい。6分もかかっていて、実際に動いたのは、ほんの ちょっとの時間って、Windows側がいじわるしてて、diskアクセスをさっさと進行 させてくれないからだな。

$ MINE/bin/locate hoge
/usr/home/sakae/Lean/HS/hoge.hs
/usr/home/sakae/Lean/Scheme/CAL_FILE_Example/hoge.c
$ locate hoge
/usr/home/sakae/Lean/HS/hoge.hs
/usr/home/sakae/Lean/Scheme/CAL_FILE_Example/hoge.c

一応、動いてるっぽい。元々有った、BSD由来のものとも検索結果が一致したし。

それじゃ、マージの威力を確認するか。適当なファイルを作成してから、updatedb。 その実行時間を計測。反映されたか、確認。

$ MINE/bin/locate zipzaptic
$ touch zipzaptic
$ time MINE/bin/updatedb

real    0m1.96s
user    0m0.05s
sys     0m1.85s
$ MINE/bin/locate zipzaptic
/usr/home/sakae/zipzaptic

ちゃんと反映されてるし、更新も、あっという間に終了って事で宜しいでしょうかね。

sakae@debian:~$ locate -S
Database /var/lib/mlocate/mlocate.db:
        13,933 directories
        134,565 files
        7,106,441 bytes in file names
        2,681,007 bytes used to store database
sakae@debian:~$ sudo ls -l /var/lib/mlocate/mlocate.db
-rw-r----- 1 root mlocate 2681007 Sep  7 14:28 /var/lib/mlocate/mlocate.db

mlocateにも統計情報が得られるオプションが有った。

折角なのでソースも見ておくか。で、開いてみたんだけど、何か落ち着かない。 インデントは浅いし、GNU流のスタイルだし。ここは、慣れ親しんだBSD風に 置き換えておくかな。

indent -bsd -i4 -br *.c