2014-11-26

ssh を通じてパイプから読む tar にはなぜ -B が必要か

説明を書くことがあったので、なくさないように保存。間違いがあったら教えてください。

ファイルというものは、種類によって特性がいろいろあります。
特性とは、いいかえると、できることと、できないことです。

ディスクファイルは一番制約の少ないものです。
  • メディア容量いっぱいまで無制限に伸ばせる有限のバイト列が、1つのプロセスにつながっている
  • lseek(2) によって任意バイト目のに位置づけすることができて(後退も可能)、
  • その現在位置から任意個バイトを read(2) することができ、
  • ファイル終端で read するとゼロが返ることで、「読めるわけではないがエラーでもない状態」が通知され、
  • あるいは現在位置から任意個バイトを write(2) することもできてその後は破壊されず、
  • 要すれば現在位置から後の全データを truncate(2) によって破棄することもできる。
パイプはちょっと制約があります:
  • バイトストリーム(遡れない流れのイメージ)の両側がプロセスにつながっており、
    write する側と read する側が決まっている
  • write したバイト数だけパイプに入って、それ以下の数だけ read したときはその内容が得られる
    パイプに入っているバイト数を超えた数を read すると、入っているバイト数だけしか読めない
  • パイプに入るバイト数が決まっている(512バイトとか、Linuxだと4096バイトとか、そんなにデカくない)。
    満杯のパイプに書き込むと write がブロック(吸い出してもらえるまで止まる)し、
    空のパイプから読み出すと read がブロック(書き込んでもらえるまで停止)する
  • lseek(2) は常にエラーになり、つまり後退はできない
  • 書き込み側プロセスが先にパイプを閉じたとき、ファイルの終端と同じ状態になり、読み側 read() に 0 が返される
    逆に、読み込み側プロセスが先にパイプを閉じたとき、書き込み側が write(2) すると、シグナル SIGPIPE を受ける (ふつう13番だから exit code 141 に見える)
TCPソケットもパイプに似た特徴を持ちますが、書き込み側プロセスが書いたバイト列が一気にすぐ読み出し側プロセスに届くわけでなく(なにせ別ホストですからね)、read で何バイト取れるかはもっと予想がつきません。

テープは全然ちがいます:
  • ファイルはバイトではなくブロックの列
  • ブロックは「1回 write したバイト列」、昔は固定長だったみたいだが、いまどきは可変長、つまり書き込み側が指定できる(512バイトの倍数限定かも)
  • ブロックはテープに書かれていて、read はブロック単位でしか行えない。
    ブロック長以下の read はブロック先頭だけが読み出され、ブロック長を超える read はブロック長だけしか読み出せない
  • ファイル内の read 以外での前後移動はできないとおもったほうがよい。
  • テープ上のファイルの終わりは書き込みプロセスが close したら勝手にできる
    テープに書き込む際は、メディア上の後続のファイルは必ず破壊されるので、ftruncate にあたる別操作はない(必ず行われる)
  • テープ上のファイルの終わりでは read(2) が 0 を返すことはディスクファイルと同じ
  • 巻き戻しをしないテープデバイスでは、ファイルの終わりを読み出して close した直後に、次のファイルに移動している

このような特性は Linux なら st(7) や pipe(7) で説明されている、はずなのですが、あの文章では一見さんお断りですわね。
ともあれそれをふまえると、-B やら SIGPIPE の問題もよくわかると思います。

  • tar は、固定のブロック長で read/write を行う、つまり、1ブロックが1回で読めることを前提にしている
  • ブロック長は 512 バイトかける -b オプションの数
  • tar アーカイブに入れるファイル長がブロック長の倍数でないときは、末尾にゼロが埋められる(パディング)
  • テープから tar が読む場合、書き込んだときのブロック長が読み出されるので、自動的にブロック長を判定できる
  • パイプから tar が読む場合(特にネットワーク越しならなおさら)は、書き込んだときのブロック長はわからないし、1ブロックが1回で read できるとも限らない。
    1ブロック(と思い込んでいるバイト数)が1回で読めない場合、続きの読み出しをリトライさせるのが -B オプション。
  • また、パイプから読む tar はブロック長がわからないので、必要なファイルを解読したら終了してしまうようになっていると(gtar はそうではないと思う)、
    書き込み側はパディングを続けている間に読み出し側が終了して、SIGPIPE を受けて爆死、ということになるのでしょう。

2014-11-21

ソフトウェアデザイン12月号にコンテナ型仮想化環境 Docker の記事がある

正直これまでどんなもんだかまったく分からなかったのだが、ハイパーバイザと
比べると、 chroot(2) の進化の系列にあるという説明は腑に落ちた。
セマンティクスが普段と違って使い方が覚えられないものは普及しない、という
のは、まあ他にもあるかもしれないが SELinux のことをいっているのだろう。
http://gihyo.jp/magazine/SD/archive/2014/201412

平成26年度 数値予報研修テキスト

平成26年度 数値予報研修テキスト が気象業務支援センター http://www.jmbsc.or.jp/ から発売になったそうです。

そのうち、気象庁ホームページ http://www.jma.go.jp/jma/kishou/books/nwptext/nwptext.html にも掲載されるはずですが、このボリュームだと印刷物をみたいという方もあると思いますので、上記ご参考まで。

2014-11-13

他人からもらった JSON を eval してはいけない。かわりに JSON.parse() しよう

ということみたいだ。ポータビリティもありそう。

参照:

http://en.wikipedia.org/wiki/JSON#Security_issues

http://www.websec-room.com/2013/07/28/876

配信資料に関する技術情報 第406号 地方海上分布予報の提供開始について

11月12日づけで発出された、標記資料が気象庁ホームページに掲載されました。
http://www.data.jma.go.jp/add/suishin/jyouhou/pdf/406.pdf

画像(PNG)形式とGRIB2形式の両方で提供があります。GRIB2マニア的には、
PDT4.0なのは普通ですが、ビットマップが使われてい るのが特徴的でしょうか。

「東京」の気象観測地点の移転について(お知らせ出ました)

お問い合わせは、このお知らせに書かれている東京管区気象台の窓口にお願いいたします。

http://www.jma-net.go.jp/tokyo/sub_index/tokyo/kitanomaru/kitanomaru.html

2014-11-11

世界の自然災害の犠牲者数は20世紀前半とそれ以後でみれば大きく減っているらしい

ちょっと興味があってぐぐってみたらこんなページがみつかった。
http://www.ourworldindata.org/data/environmental-change/natural-catastrophes/

このデータの信憑性についてはよくわからないが、20世紀前半までは10万人ちか
い犠牲者を伴うような疫病・水害・旱魃があって、それはここ数十年はみられな いというこ
とはそれなりに説得力はある。

どうやって人類はそれを乗り越えたかというと衛生、治水、灌漑、いろいろあろうが、それをひとま
とめで呼ぶなら文明と言ってもいいんじゃないかと思う。一定の文明があたり まえに
なった後だけを論じれば、気候変動で文明が脆弱になってきているという論はできるのかも
しれないが、それなら文明開化以前まで視野に入れないと、ものをよく見 た気がしない。