Armadilloフォーラム

ntpclient時刻合わせで返ってこない

n.yamamoto

2015年6月13日 21時11分

Yamamotoです。

Armadillo-460でC言語によるsystem命令で"ntpclient -h ntp.nict.jp -s"を実行したところ返ってこないことがあることが解りました。

ネットワーク接続はFOMAアダプターによる接続中に実施しています。
下記は異常時のプロセス状態です。(異常時にプログラム内でsystem命令による"ps"実施)
------------------------------------------------------------------------------------------
1 root 680 S init
2 root SW< [kthreadd]
3 root SW< [ksoftirqd/0]
4 root SW< [events/0]
5 root SW< [khelper]
6 root SW< [kblockd/0]
7 root SW< [mxc_spi.2]
8 root SW< [ksuspend_usbd]
9 root SW< [khubd]
10 root SW< [kmmcd]
11 root SW [pdflush]
13 root SW< [kswapd0]
14 root SW< [aio/0]
15 root SW< [mtdblockd]
16 root DW [imx_adc_ts]
17 root SW [pdflush]
161 root 420 S < udevd --daemon
346 root 536 S syslogd -L
378 root 456 S klogd
983 root 796 S /sbin/pppd debug lock novj nodeflate modem crtscts /d
996 root 640 S inetd
1103 www-data 1236 S lighttpd -f /etc/lighttpd.conf
1243 avahi 1188 S avahi-daemon: running [armadillo460-0.local]
1288 root 956 S /usr/bin/mm2/runMM2
1292 root 656 S /sbin/getty -L 115200 ttymxc3 vt102
1314 root 636 S [userApp1]
1316 root 516 S [userApp2]
1317 root 520 S [userApp3]
1318 root 1288 S [userApp4]
1319 root 908 S [userApp5]
1321 root 568 S [userApp6]
1323 root 312 S [userApp7]
1326 root 384 S [userApp8]
30144 root 644 S sh -c ntpclient -h ntp.nict.jp -s
30145 root 660 S ntpclient -h ntp.nict.jp -s
30166 root 644 S sh -c ps
30167 root 752 R ps
------------------------------------------------------------------------------------------

何かの条件で終了しないことがあるのでしょうか?

終了しないことがあるとしたら強制的でも終了させるにはどの様にすればよいでしょうか?

よろしくお願いいたします。

コメント

kes-konishi

2015年6月15日 8時37分

KES)小西です。

killall ntpclient
で終了しませんか?

n.yamamoto

2015年6月15日 12時04分

Yamamotoです。

試しで仰る通り実施して、1回発生して正常に復帰したようなのですが、
もう出荷予定で時間が無いので一番安全そうな(変更量含め)方法としてお聞きしたかったのです。

行ったのは、下記のntpclientのID 30145をKillしました。
983 root 796 S /sbin/pppd debug lock novj nodeflate modem crtscts/d

30144 root 644 S sh -c ntpclient -h ntp.nict.jp -s
30145 root 660 S ntpclient -h ntp.nict.jp -s

不安だったのがID 30144のシェルも有ったので両方Killすべきか、それともいっそのことpppdをKillして回線を一旦切ってしまった方が良いのか悩んだためです。

お試しで実施したntpclientのIDでkill実施方向で対応して差試験を実施してみます。

kes-konishi

2015年6月15日 12時18分

KES)小西です。

30144 root 644 S sh -c ntpclient -h ntp.nict.jp -s
30145 root 660 S ntpclient -h ntp.nict.jp -s
のプロセスID 30144のshですが、

systemコールしているプロセス
 ↓
sh -c ntpclient -h ntp.nict.jp -sのシェル
 ↓
ntpclient -h ntp.nict.jp -s

でプロセスが親子間になっていると思いますので、
ntpclientをkillするとその親のshが戻ってきて、sh終了後に
system関数が抜けてくると思います。

このため、ntpclientをkillするとshも終了していると思いますので、
psで確認してみてください。

ただし、プロセスID 30144のshが他のsystemから生成されたshでない場合は
回答間違いになってしまいますが。。。

n.yamamoto

2015年6月15日 13時39分

Yamamotoです。

教えていただいた内容ではないかと推測はしていました。

確認時にntpclientのみをkillして
sh -c ntpclient -h ntp.nict.jp -s
ntpclient -h ntp.nict.jp -s
の両方がゾンビ化せずに終了している事も確認しています。

有難うございます。

y.nakamura

2016年10月7日 16時30分

中村です。

2015/06/13のもので、

> Yamamotoです。
>
> Armadillo-460でC言語によるsystem命令で"ntpclient -h ntp.nict.jp -s"を実行したところ返ってこないことがあることが解りました。
...
> 何かの条件で終了しないことがあるのでしょうか?
>
> 終了しないことがあるとしたら強制的でも終了させるにはどの様にすればよいでしょうか?

この2つの質問のうち、
終了しない理由が解決していないようなので・・・

たぶん、UDPの応答パケットを取得できなかったときに、
受信待ちタイムアウトまでntpclientが終了しないのが
原因だと思います。

タイムアウトのデフォルトは600秒で、
"-i"オプションでタイムアウトを変更できます。

たとえばタイムアウトを10秒(10秒でも長すぎかも)にするなら、
ntpclient -i 10 -h ntp.nict.jp -s
です。

"-i"は本来は繰り返し動作のときのインターバルの設定ですが、
select()のタイムアウトの指定も兼ねています。

ソース ntpclient.c に次のパッチをあてて、
デバッグの"-d"を付けて動かすと、
そのあたりの動作がわかります。

--- ntpclient.c-orig    2016-01-26 11:41:18.000000000 +0900
+++ ntpclient.c 2016-10-07 12:58:20.325808864 +0900
@@ -382,7 +382,15 @@
        for (;;) {
                FD_ZERO(&fds);
                FD_SET(usd,&fds);
+               if (debug) {
+                       printf("call select to.tv_sec=%ld to.tv_usec=%ld ...\n",
+                               to.tv_sec, to.tv_usec);
+               }
                i=select(usd+1,&fds,NULL,NULL,&to);  /* Wait on read or error */
+               if (debug) {
+                       printf("   returned to.tv_sec=%ld to.tv_usec=%ld\n",
+                               to.tv_sec, to.tv_usec);
+                }
                if ((i!=1)||(!FD_ISSET(usd,&fds))) {
                        if (i==EINTR) continue;
                        if (i<0) perror("select");

本題と関係ないですが、
このselect()の戻り値判定のところ、バグってます。
戻り値を変数iで受け取って、
if (i==EINTR) continue;
という処理をしてますが、ここはerrnoを見るべきです。

ML時代に、atmark-distのntpclientは古いから更新した方がいい、
ということを投稿したのですが、今のatmark-distに入っているのは、
古いままのようです。
http://lists.atmark-techno.com/pipermail/armadillo/2014-January/009409…

atmark-distのntpclientの更新については、
この後、別記事として投稿します。

--
なかむら