こんにちは。サイオステクノロジー OSS サポート担当何敏欽です。
2020年東京五輪・パラリンピックの暑さ対策として、サマータイム (Daylight Saving Time) 導入案が国会で検討されています。システムに導入された OSS はサマータイムに対応しているか、対応している場合、どうやって設定するか、対応していない場合、どのような影響が発生するかを確認したいですよね。今回はこれらの質問をもって、いくつの OSS を確認していきます。
サマータイムの対応有無の確認
■tomcat
tomcat はサマータイムに対応しているかどうかを確認しましたが、残念ながら、tomcat はサマータイムに対応していません。でも、焦らないてください。まずは tomcat はどこの時間を参照しているかをソースコードで確認します。
#java/org/apache/juli/FileHandler.java より抜粋 168 // Construct the timestamp we will use, if requested 169 Timestamp ts = new Timestamp(System.currentTimeMillis()); 170 String tsString = ts.toString().substring(0, 19); 171 String tsDate = tsString.substring(0, 10); 172 173 try { 174 writerLock.readLock().lock(); 175 // If the date has changed, switch log files 176 if (rotatable && !date.equals(tsDate)) { 177 try { 178 // Update to writeLock before we switch 179 writerLock.readLock().unlock(); 180 writerLock.writeLock().lock(); 181 182 // Make sure another thread hasn't already done this 183 if (!date.equals(tsDate)) { 184 closeWriter(); 185 date = tsDate; 186 openWriter(); 187 } 188 } finally { 189 writerLock.writeLock().unlock(); 190 // Down grade to read-lock. This ensures the writer rema ins valid 191 // until the log message is written 192 writerLock.readLock().lock(); 193 } 194 }
169行目、System.currentTimeMillis() を実行し、時間を取得していることがわかります。System.currentTimeMillis() の処理は、JVM で定義されています。java のソースコードを確認します。
#openjdk/hotspot/src/os/aix/vm/os_aix.cpp より抜粋 1103 jlong os::javaTimeMillis() { 1104 timeval time; 1105 int status = gettimeofday(&time, NULL); 1106 assert(status != -1, "aix error at gettimeofday()"); 1107 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); 1108 }
1105行目、gettimeofday()を使用して、時間を取得していることがわかります。System.currentTimeMillis() は gettimeofday() の返り値をそのまま使いますね。つまり、tomcat は OS のシステム時刻を参照します。
tomcat は OS のシステム時刻を参照ため、tomcat 自体はサマータイムへの対応は不要で、OS 側が対応するかどうかによります。OS 側の対処としては、サマータイムに対応したタイムゾーンの追加であり、またユーザはサマータイムに対応したタイムゾーンへシステムを変更することになります。
■Apache
Apache はサマータイムに対応しているかどうかを確認しましたが、残念ながら、Apache もサマータイムに対応していません。Apache ログ出力の際の時刻の基準をソースコードから確認しましたところ、gettimeofday 関数が該当することがわかりました。
#modules/loggers/mod_log_config.c より抜粋 768 static const char *log_request_duration(request_rec *r, char *a) 769 { 770 apr_time_t duration = get_request_end_time(r) - r->request_time; 771 return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, apr_time_sec(duration)); 772 } 773 774 static const char *log_request_duration_microseconds(request_rec *r, char *a) 775 { 776 return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, 777 (get_request_end_time(r) - r->request_time)); 778 } #modules/metadata/mod_headers.c より抜粋 171 static const char *header_request_duration(request_rec *r, char *a) 172 { 173 return apr_psprintf(r->pool, "D=%" APR_TIME_T_FMT, 174 (apr_time_now() - r->request_time)); 175 }
774 行目、ログへの書込時間 (%D のための文字列作成箇所) は、log_request_duration_microseconds() 内で、現在時刻と処理開始時間との差分を文字列に変換しています。%D は apr_time_now() – r->request_time から算出しています。
#modules/loggers/mod_log_config.c より抜粋 1092 static int config_log_transaction(request_rec *r, config_log_state *cls, (略) 1150 for (i = 0; i nelts; ++i) { 1151 strs[i] = process_item(r, orig, &items[i]); 1152 } (略) 1162 rv = log_writer(r, cls->log_writer, strs, strl, format->nelts, len);
1092行目、実際のログ書き込みのタイミングは、config_log_transaction() 内の log_writer() 部分で実際の書き込み処理が行われています。この関数内の process_item() [log_writer()が呼ばれる前] 内で log_request_duration_microseconds() の処理が行われます。
#modules/loggers/mod_log_config.c より抜粋 73 /* NB NB NB NB This returns GMT!!!!!!!!!! */ 74 APR_DECLARE(apr_time_t) apr_time_now(void) 75 { 76 struct timeval tv; 77 gettimeofday(&tv, NULL); 78 return tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec; 79 }
apr_time_now は非常に多く使われていますが、中身は gettimeofday であるようです。つまり、Apache も OS のシステム時刻を参照します。Apache は tomcat と同様に OS のシステム時刻を参照ため、Apache 自体はサマータイムへの対応は不要です。
■BIND、Postfix、Dovecot、freeradius、Tomcat-Connectors
BIND、Postfix、Dovecot、freeradius、Tomcat-Connectors はサマータイムに対応するかを確認しましたところ、これらの OSS もサマータイムに対応していません。でもこれらも全部 OS のシステム時刻を参照することを確認できましたので、tomcat と同様にそれぞれの OSS 自体はサマータイムへの対応は不要で、OS 側が対応するかどうかによります。
■OpenLDAP
OpenLDAP は、内部データについては GMT を使用するため、サマータイムの影響を受けません。また、ログについては rsyslog を介しての出力となり、ログの時刻は OS のシステム時刻を参照するため、tomcat と同様に OpenLDAP 自体はサマータイムへの対応は不要で、OS 側が対応するかどうかによります。
■Apache Ant
Apache Ant 1.7 (※) は全体としては OS の時刻を参照し、FTP 機能のみ別途サマータイム対応パラメータがあります。FTP はサーバとクライアント間でファイルを転送するプロトコルであり、サーバとクライアントが異なるタイムゾーンを使用する場合、時刻ずれが発生します。時刻ずれによる問題を防ぐため、FTP がサマータイムに対応するようになったと考えられます。
※ Apache Ant のマニュアルに Apache Ant 1.7 より FTP 機能はサマータイムに対応すると記載されています。
FTP がサマータイムに対応するということで、どのように設定すればいいかを調べたところ、こちらの URL が参考になりました。設定方法を下記に案内します。
<project name=”ftp-test” basedir=”.”>
<property name=”ftp.server.timezone” value=”GMT”/>
(略)
<target name=”timed.test.put.older”>
(略)
<ftp action=”put”
(略)
serverTimeZoneConfig=”${ftp.server.timezone}”
>
tzdata および tzdata-java パッケージ
今後日本にサマータイムが実際に導入されれば、ローカルタイムの元情報となる日本版サマータイムを追加したタイムゾーン情報や、適用期間ルールなどの情報を含む tzdata および tzdata-java パッケージがりリリースされると予想されます。
そのため、RHEL、CentOS、Fedora 等 RedHat 系のシステムであれば、tzdata および tzdata-java パッケージをアップデートすることで対応可能と考えられます。
以上で各 OSS はサマータイムに対応するか否か、それぞれの時刻参照先及び対応方法について説明しました。