2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NetBSDAdvent Calendar 2024

Day 5

current_timeカーネルモジュールから見るカーネル内のタイムゾーン

Posted at

NetBSD Advent Calendar 2024 5日目の記事です。今日はNetBSD-10で追加されたカーネルモジュールサンプルを紹介しようと思います。

新たに追加されたカーネルモジュールサンプル

NetBSD-10の/usr/src/sys/modules/examplesを見ると、カーネルモジュールの新しいサンプルがいくつか追加されています。ざっと確認すると、以下のサンプルが追加されているようです。これらのサンプルを(分かる範囲で)見てゆこうと思います。

  • current_time
  • ddbping
  • fopsmapper
  • ping_block
  • pollpal

current_timeモジュール

さっそくカーネルモジュールをビルドして試してみます。 make してmodload(8)modload(8)を実行します。

# cd /usr/src/sys/modules/examples/current_time/
# make
/usr/src/tooldir.NetBSD-10.0-amd64/bin/x86_64--netbsd-gcc -O2 -g   -std=gnu99    -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wno-sign-compare  -Wsystem-headers   -Wno-traditional   -Wa,--fatal-warnings  -Wreturn-type -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wextra -Wno-unused-parameter -Wno-sign-compare -Wold-style-definition -Wsign-compare -Wformat=2  -Wno-format-zero-length  -Werror  -Wno-address-of-packed-member  -Wno-pointer-sign -Wno-attributes -Wno-type-limits  -ffreestanding  -fno-strict-aliasing -mno-red-zone -mno-mmx -mno-sse -mno-avx -msoft-float -mcmodel=kernel -fno-omit-frame-pointer   -I/usr/src/common/include --sysroot=/ -I/usr/src/common/include  -nostdinc -I. -I/usr/src/sys/modules/examples/current_time -isystem /usr/src/sys -isystem /usr/src/sys/arch -isystem /usr/src/sys/../common/include -D_KERNEL -D_MODULE -DSYSCTL_INCLUDE_DESCR  -DKDTRACE_HOOKS  -c    current_time.c -o current_time.o.o
/usr/src/tooldir.NetBSD-10.0-amd64/bin/nbctfconvert -L VERSION -o current_time.o current_time.o.o && rm -f current_time.o.o
#      link  current_time/current_time.kmod
/usr/src/tooldir.NetBSD-10.0-amd64/bin/x86_64--netbsd-gcc  --sysroot=/ -Wl,--warn-shared-textrel -Wl,-z,relro -nostdlib -r -Wl,-T,/usr/src/sys/../sys/modules/xldscripts/kmodule,-d  -Wl,-Map=current_time.kmod.map  -o current_time.kmod current_time.o
/usr/src/tooldir.NetBSD-10.0-amd64/bin/nbctfmerge -t -L VERSION -o current_time.kmod current_time.o
#
# cd /usr/src/sys/modules/examples/current_time/
root@nbsd2024test current_time # ls
CVS/                      current_time.c            current_time.o            x86@
Makefile                  current_time.kmod         i386@                     xen@
amd64@                    current_time.kmod.map     machine@
#
# modload ./current_time.kmod
# modunload current_time

コンソールには以下の表示となり、現在時刻がフォーマットされて出力されています。

img01.PNG

ソースコードは/usr/src/sys/modules/examples/current_time/current_time.cにあり、 modload でカーネルモジュールがロードされた際に print_current_time() が呼ばれています。

 66 static int
 67 current_time_modcmd(modcmd_t cmd, void *arg __unused)
 68 {
 69     switch (cmd) {
 70     case MODULE_CMD_INIT:
 71         printf("current_time example module loaded.\n");
 72         print_current_time();
 73         break;
 74     case MODULE_CMD_FINI:
 75         printf("current_time example module unloaded.\n");
 76         break;
 77     default:
 78         return ENOTTY;
 79     }
 80
 81     return 0;
 82 }

print_current_time() の実装を見てみます。 getmicrotime() でUNIXエポック秒を取得し、 clock_secs_to_ymdhms() で年・月・日といった値に変換するようです。

 45 static void
 46 print_current_time(void)
 47 {
 48     struct timeval tv;
 49     struct clock_ymdhms dt;
 50     const char *w_day[] = {
 51         "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
 52         "Friday", "Saturday"
 53     };
 54
 55     getmicrotime(&tv);
 56     clock_secs_to_ymdhms(tv.tv_sec, &dt);
 57
 58     printf("Current Time: %s, %04" PRIu64 "/%02" PRIu8 "/%02" PRIu8
 59         " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8 " UTC\n",
 60         w_day[dt.dt_wday], dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_hour,
 61         dt.dt_min, dt.dt_sec);
 62 }

関数のコメントを見てみます。"the kernel doesn't have the notion of local timezones."(カーネルはローカルタイムゾーンの概念を持っていない)とあり、改めて先ほどの実行結果を見るとたしかに GMT/UTC な時刻になっています。

 36 /*
 37  * Function print_time() fetches the epoch seconds/unix time from the
 38  * getmicrotime() function and sends its to clock_secs_to_ymdhms(..) in
 39  * dev/clock_subr to parse it into readable date and time format and print it.
 40  *
 41  * Please note that the current time is printed in GMT/UTC because the kernel
 42  * doesn't have the notion of local timezones.
 43  */

訳:
print_time()getmicrotime()から取得したUNIXエポック秒を取得し、/usr/src/sys/dev/clock_subr.c
あるclock_secs_to_ymdhms()でパースし、フォーマットされたものを表示します。
カーネルにはローカルタイムゾーンの概念が無いため、表示される時間はGMT/UTCであることに注意してください。

ユーザランド側のタイムゾーンが JST であっても、カーネル内では GMT/UTC として処理されているようです。

img02.png

まとめ

現在時刻を取得するカーネルモジュールサンプルを見てみました。個人的にカーネル内ではローカルタイムゾーンを持たないのは知らなかったので知見が増えました。カーネル内部では GMT/UTC であっても、ユーザランド側でローカルタイムゾーンに変更すればよいので特に問題はない(逆にカーネル側でタイムゾーンを意識すると複雑になる)という話なのかもしれません。そう考えると、 ja_JP.UTF-8 といったロケールなどの概念もカーネル側には存在しないのかもしれません(調べてないので真偽不明…)。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?