Ubuntu18.0.4でDeleGateを動かす

(ITSのブログより続く)

おっとdelegate.orgのコピーが終わった。df。お、50%くらい埋まったか。12GBくらいだな。では DeleGateを起動。 sh httpd。ああ、80番がbindできないと。ではとりあえず、sudo sh httpd。おお動いた。ps ax。動いてる。外のブラウザから繋いでみる。おー、見えた。では chmod 4770 dgbind; chown ysato dgbind; sh httpd。よしよし、これで su にならなくても bind できるで。

バグが出た

あれ?でもなんだかフロントページがいつまでもクルクルして終わらないな。なんだこれは。HTTP用のDeleGateのログを見てみる。ありゃりゃ、SSI includeがクルクル回ってますがな。んー、includeがループしてるわけでも無いらく。。あれ、includeした後に、また同じところから自分を読んでる。んー、ファイルのオフセットの問題かな。カーネルの仕様でも変わったのだろうか?カーネルのバージョンは…

現行delegate.org
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-74-generic x86_64)

$ delegated -Fver
DeleGate/9.9.13 (October 30, 2014)

Config: Linux/3.13.0-74-generic; FileSize-Bits=64/64,64/32,64,64; socket=87380/16384,++NAT; sockpair=212992/212992,1002++U; char=signed; fcF=B; thread=PThread/pthread,64/128; zlib=112,308000; pam=3; stty=tcsetattr/termio; regex=regex; addr=A/44AFE0/7FFEB05F8918; fmem=246/510/1671M

$ uname -v
#118~precise1-Ubuntu SMP Fri Dec 18 10:38:55 UTC 2015

これは確か、Ubuntu 14.x LTE だったと…あいや、12.04.5か… そういう意味でもこれはオワコンだな。

新規delegate.org
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.0.0-1036-azure x86_64)

$ delegated -Fver
DeleGate/9.9.13 (October 30, 2014)

Config: Linux/5.0.0-1036-azure; FileSize-Bits=64/64,64/32,64,64; socket=131072/16384,++NAT; sockpair=212992/212992,1002++U; char=signed; fcF=B; thread=PThread/pthread,64/128; zlib=112,308024; pam=3; stty=tcsetattr/termio; regex=regex; addr=A/44AFE0/7FFC029527D8; fmem=81/107/897M

$ uname -v
#38-Ubuntu SMP Sun Mar 22 21:27:21 UTC 2020

おお!Linux/4.X をすっとばしてしまったみたいだ。それにしてもこのUbuntu 18.04.4 LTE、3月22日に出たばかりなのか…

開発環境整備

しかし、DeleGateを直すにしてもコンパイラが無いと… 再び sudo apt install g++。

Err:1 http://security.ubuntu.com/ubuntu bionic-updates/main amd64 binutils-common amd64 2.30-21ubuntu1~18.04.2
  404  Not Found [IP: 52.175.12.31 80]

だめか。apt とかよく知らんしなー。先人の知恵を借りよう。ぐぐる。おお、これか。

untu.com/questions/1159096/ubunutu-18-04-updates-404-error
Run sudo apt update before you install the packages.

ふむ。まず apt update をしろと。はい、やりました。ふたたび apt install g++。通った!ありがとう先人さん。

それにしても apt さんよ、エラーメッセージのあとに「apt updateするといいかもよ」くらいのアドバイスメッセージくらい出してくれてもいいんじゃないか…

原因追跡

では DeleGate を make。。あれ、途中でコンパイルエラーが… むむ、FILEの構造体にそんなメンバーは無いとな。いや、君は知らないかも知れないが、それは Linux 開闢以来そこにあったのだよ… cc -E して定義の実体を見てみる。おお、ちがう流派の Linux と判定してるようだ。predefined が変わったのか。とりあえず #if 1 で通す。再び make。とおった…が、また次のエラーが。なに、初期値が unsigned int と int で不整合と。なこと言われても昔からそれで通ってたのにな。コンスタントなんだし。まあ後で直しときます。とりあえず -Wno-narrowing。make。おお、通った。SSI incldue の件は FILE関係くさいからこれで動くのでは… あれれ、だめか。

SHTMLファイルを読む位置が前に戻るって症状は、やっぱ FILE のバッファリング関係のような気がする。setbufで_IONBFにしてみよう。だめかー。seek関係だろうか?うーん、でもftell()の位置は戻ってないぞ。man ftell。うん、そういや今時は fgetpos()だな。んー、ftell()怪しい。obsolete放置状態の可能性がある。んーftell() … なぬ?Solaris2ではオフセットが不思議な動きをすると、自分でプログラム中にコメントしてるじゃないか。いったいいつの話だよ…。なんにしてもftell()すごく怪しい。lseek()のと比べてみる。「値がちがうじゃん」。うーん、これってバッファリングかオフセットのキャッシュの問題か。でもこれまで全てのプラットフォームでDeleGateは動いてきたのに。最近のLinuxのライブラリでおかしくなったのだろうか?ftell()アンサポートになったのか?まあいい、強制的にSSI include 呼び出し前の位置に一致させちゃおう。えいっ!これでどうかな?おお!!通ったぁ。

まとめ

ftell()にはバグか、あるいは仕様上規定されてない振る舞いがある。子プロセスに受け継いだファイルディスクリプタで子プロセスがそれを動かした時に反映されない、ということではないかと思われる(だったような記憶もある)。それは高速化の観点から、あるいは生ファイルディスクリプタとは別にストリーム独自の状態を保つために、そう言う仕様でも仕方がないのかも?いやいや、それじゃ一貫性がおかしくなるだろう。以前からそうだったような気がしないでもないが、これまでは、ftell()を多用しているDeleGateで問題は起きていなかった。バグなのか仕様変更なのか調べる必要がある。DeleGate的には、ftell()にラッパーをかけて、lseek()を参照するものにしといたほうが安全かも知れない。

www.delegate.org 新規サーバ // Ubuntu 18.0.4 LTE // Azure // 2020-0429