[Armadillo:08794] Re: 起動実行と手動実行で取得する時刻がJSTとUTCで変わる
Yasuhisa Nakamura
email@hidden
2013年 5月 15日 (水) 02:33:20 JST
中村@自己レスです。
結論を先に書いておきます。
ftpdでJSTにならない理由がわかりました。
busyboxのinetdのバグだと思います。
まず、訂正から。
[Armadillo:08789]で、
> init -> inet.d -> ftpd と起動されるどこかで
> タイムゾーンを設定してftpdに教えてあげれば
> ようさそうに思いますが・・・
と書きましたが、これは間違いでした。
init -> inet.d -> ftpd ではなくて、
init -> rc -> inet.d -> ftpd ですね。
あわてて書いて間違えました。
とすると、rcで export TZ=JST-9 しているのでinet.dには
TZが伝わっているはずなのに、なぜftpdには伝わらないのか?
これが問題です。
以下、ちょっと長くなりますが、せっかくなので
調査の方法も含めて結論まで書いておきます。
rcからinetdを起動したときにinetdに渡した環境変数は、
/proc/{pid}/environ
で調べることができます。
実際にArmadillo-420でやってみるとこうなってました。
# cat /proc/778/environ
USER=rootHOME=/TERM=vt102PATH=/bin:/sbin:/usr/bin:/usr/sbinSHELL=/bin/shPWD=/TZ=JST-9
次に、inetdから起動されるコマンドでの環境変数を調べます。
方法は簡単です。
/etc/inetd.confのtelnetを次のように書き換えて、inetdに
SIGHUPを送ります。
telnet stream tcp wait root /usr/bin/env env
外部からtelnetでつなぐと、次のようになりました。
$ telnet 192.168.0.100
Trying 192.168.0.100...
Connected to 192.168.0.100.
Escape character is '^]'.
inetd_dummy=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Connection closed by foreign host.
inetd_dummy以外、環境変数が何もありません。
ここからは、inetdのソース調査です。
inetd.cにこんなコードがありました。
INETD_FEATURE_ENABLEDのとき、environ を書き換えてます。
extern int inetd_main(int argc, char *argv[])
{
...
#ifdef INETD_FEATURE_ENABLED
extern char **environ;
...
Argv = argv;
if (environ == 0 || *environ == 0)
environ = argv;
while (*environ)
environ++;
LastArg = environ[-1] + strlen(environ[-1]);
#endif
...
INETD_FEATURE_ENABLEDは何かというと、これはビルトインの
echoサーバやtimeサーバなどをenableにしたときdefineされます。
そこで、make config でbuzyboxのinetdの設定を変更してみます。
[*] inetd
[ ] inetd: Support chargen service
[ ] inetd: Support daytime service
[ ] inetd: Support discard service
[ ] inetd: Support echo service
[ ] inetd: Support time service
これをビルドして、上のtelnetでのenv表示をやってみると
次のようになり、/proc/{pid}/environ の結果と一致します。
(増えたinetd_dummy以外は)
$ telnet 192.168.0.100
Trying 192.168.0.100...
Connected to 192.168.0.100.
Escape character is '^]'.
USER=root
HOME=/
TERM=vt102
PATH=/bin:/sbin:/usr/bin:/usr/sbin
SHELL=/bin/sh
PWD=/
TZ=JST-9
inetd_dummy=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Connection closed by foreign host.
この状態でftpでアクセスしてみると、lsでのタイムスタンプは
ちゃんとJSTになります。
ビルトインサーバを使うかどうかで environ を書き換えるか
どうかが違う(起動した子プロセスに渡される環境変数が
クリアされるかどうかが変わる)のですけど、これは
バグだと思います。
次のように書き換えたところ、ビルトインのサーバをONしていても、
引き継いだ環境変数はinetdの子プロセスに渡されるようになり、
ftpでのタイムスタンプもJSTになるようになりました。
--- inetd.c-orig 2012-12-28 11:30:59.000000000 +0900
+++ inetd.c 2013-05-15 01:36:25.000000000 +0900
@@ -744,6 +744,7 @@
#ifdef INETD_FEATURE_ENABLED
extern char **environ;
+ char **env = environ;
#endif
gid = getgid();
@@ -751,11 +752,11 @@
#ifdef INETD_FEATURE_ENABLED
Argv = argv;
- if (environ == 0 || *environ == 0)
- environ = argv;
- while (*environ)
- environ++;
- LastArg = environ[-1] + strlen(environ[-1]);
+ if (env == 0 || *env == 0)
+ env = argv;
+ while (*env)
+ env++;
+ LastArg = env[-1] + strlen(env[-1]);
#endif
#if defined(__uClinux__)
以上です。
--
なかむら
armadillo メーリングリストの案内