Linuxの時計
概要
時計メモ
メモ
ノート: デフォルトでは systemd はハードウェアクロックに UTC を使用します。
用語
ハードウェアクロックまたはリアルタイムクロック(RTC)
- マザーボードが持つ内部時計であり、BIOS クロックやCMOS クロックとも呼ばれます。マザーボード上の IC に実装
- CentOSではデフォルトではハードウェアクロックをUTCを標準時を参照しているように考えてシステムクロックを設定するみたい。
- LINUXが起動する時に一度だけ参照。
- また、RTCはさほど精度が高くないこともあり、定期的にインターネット上のNTPサーバーから現在時刻を取得しRTCに書き込むということも行われます。最近のWindowsではデフォルトでマイクロソフトのNTPサーバーを参照しています。
- MacやLinuxでは、RTCからUTC(協定世界時)を設定しておきOS側でタイムゾーンや夏時間の時差を足し引きしてローカルタイムを表示しているようです。
システムクロック
- 一般的に、UTC を使う OS は起動時に CMOS (ハードウェアクロック) の時間を UTC 時間 (GMT, Greenwich time) だと認識して、あなたのタイムゾーンによってその時間を調整してシステム時刻を設定します。
- OSは起動されるとハードウェア クロックの時刻情報を読み出し、基準時刻からの経過秒数の形式に編集してOSが管理するメモリ内にシステム クロックとして格納します。
- システムクロックの更新はタイマー割り込み毎に加算され、基準時刻からの経過秒数で現在の時間を運用(時計の進行)する。
NTPの必要性
- ログの時間の整合性をあわせるなどなど、ネットワーク内の複数のシステムで同じ時間に合わせる必要があるのでNTPを利用する。
- 時間が正確
- /etc/ntp.conf でntpサーバを設定。ntpdを起動させる。
- 即時に合わせる場合、nttdate ntpサーバで合わせることができる。
まとめ
工場でマザーボード作成。現在の時間設定される。以後動き続ける。
↓
届く
↓
Linuxサーバ設定、起動
↓
起動時にRTCを参照。 LinuxではRTCをUTCをとして認識、そこからlinuxのタイムゾーンにあった時間に変換(システム クロックの設定)
↓ 運用
システムで時間を統一する必要ntpの導入(システムクロックの値はntpdから取得)
↓
問題
- RTCはずれる。「ハードウェア クロックはあまり正確ではない」と言われているくらいらしい
- RTCがずれたままだど再起動する度にずれた時間が設定される。(ntpdで修正されるも即時ではない場合、時間がかかる)
↓
システムクロックとRTCを同期する。 デフォルトでタイミングは再起動やシャットダウン
これでRTCとシステムクロック同期するのでずれない。 また、NTPで各サーバーの時間も同期。NTP使うので時間は正確。
参考
メモリメモ
コピーオンライトがあるのでスレッドよりもプロセスが重いなんてことはない。昔の話。
# cat /proc/meminfo MemTotal: 1020096 kB MemFree: 71060 kB Buffers: 45848 kB Cached: 762244 kB SwapCached: 5980 kB Active: 183652 kB Inactive: 668244 kB Active(anon): 13576 kB Inactive(anon): 30580 kB Active(file): 170076 kB Inactive(file): 637664 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 5079036 kB SwapFree: 5054380 kB Dirty: 248 kB Writeback: 0 kB AnonPages: 38924 kB Mapped: 12704 kB Shmem: 308 kB Slab: 76584 kB SReclaimable: 22564 kB SUnreclaim: 54020 kB KernelStack: 1600 kB PageTables: 2288 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 5589084 kB Committed_AS: 157228 kB VmallocTotal: 34359738367 kB VmallocUsed: 8340 kB VmallocChunk: 34359717896 kB HardwareCorrupted: 0 kB AnonHugePages: 2048 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 8180 kB DirectMap2M: 1040384 kB
物理メモリの配分
64ビットではLowメモリとHighメモリの区別もなくなる 全てのメモリ領域がカーネルが利用できるLowメモリ領域として認識される ユーザーメモリとカーネルメモリ
ユーザメモリの分類
Anonymous (anon)
プログラムの実行中に動的に確保したメモリ。mallocとか。
File-backed(file)
ディスクキャッシュなど、ディスク上にもある種類ものと対応がある。
active
最近利用
inactive
長時間利用されていない
4種類のLRUリスト(Least Recently Used)
- anon(active)
- anon(inactive)
- file(active)
- file(inactive)
プラス
- 原理的に開放できないもの Unevictableリスト
移動する
- メモリの状況によって移動する。
- anon(active) ←→ anon(inactive)
- file(active) ←→ file(inactive)
カーネルメモリの分類
- そもそも仮想空間ない。物理に直接
- そもそもカーネルでは2つのメモリ管理
- データの形式によって事前に2つの方式でまとめて確保している
- Buddyシステム(Buddyアロケータ)
- 4Kb以上
- Slabアロケータ
- 4KB以下
- Buddyシステム(Buddyアロケータ)
- vmalloc()
strace
概要
straceの使い方についてのメモ
スレッド
$ strace -p 3887 Process 3887 attached futex(0x7fc579e0b9d0, FUTEX_WAIT, 3889, NULL^CProcess 3887 detached
上記コマンドを打ったところ、プロセスはちゃんと働いているはずなのにここで止まってしまった。 そのプロセスからforkしたプロセスも対象にいれないといけませんでした。
$ strace -f -p 3887
これでドバーとシステムコールが表示される。
オプション
$ strace -ttT -ff -o ~/strace-log -p 3887
- tt: 行頭にタイムスタンプをマイクロ秒単位で出力
- T: 行末にシステムコール内での所要時間を出力
- ffとo:この2つを組み合わせることで
strace-log.スレッドID
毎にstraceのログを出力してくれる
$ strace -ttT -fc -p 3887 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 38.39 0.206970 10893 19 epoll_wait 36.90 0.198972 1442 138 46 futex 21.14 0.113984 18997 6 4 restart_syscall 3.13 0.016853 624 27 mmap 0.35 0.001882 1 2746 clock_gettime 0.05 0.000292 4 82 unlink 0.03 0.000164 4 44 munmap 0.00 0.000022 0 293 write 0.00 0.000013 0 1011 6 lstat 0.00 0.000000 0 15 read 0.00 0.000000 0 32 open 0.00 0.000000 0 34 close 0.00 0.000000 0 115 stat 0.00 0.000000 0 166 fstat 0.00 0.000000 0 4 mprotect 0.00 0.000000 0 1 rt_sigprocmask 0.00 0.000000 0 44 sched_yield 0.00 0.000000 0 1 madvise 0.00 0.000000 0 469 gettimeofday ------ ----------- ----------- --------- --------- ---------------- 100.00 0.539152 5247 56 total
cで統計表示。便利。
SystemTap Man
systemtapを動かすには
- 実行しているカーネルの kernel-devel
- 実行しているカーネルの kernel-debuginfo
- 実行しているカーネルの kernel-debuginfo-common
- gcc
- systemtap
kernel-debuginfo
とkernel-debuginfo-common
debuginfo-install kernel
でお目当てのバージョンをインストールする。
$ debuginfo-install kernel --skip-broken ============================================================================================================================================== Package Arch Version Repository Size ============================================================================================================================================== Installing: kernel-debuginfo x86_64 2.6.32-642.15.1.el6 base-debuginfo 282 M Updating: yum-plugin-auto-update-debug-info noarch 1.1.30-40.el6 base 27 k Installing for dependencies: kernel-debuginfo-common-x86_64 x86_64 2.6.32-642.15.1.el6 base-debuginfo 46 M Skipped (dependency problems): kernel-debuginfo x86_64 2.6.32-642.6.2.el6 base-debuginfo 282 M kernel-debuginfo x86_64 2.6.32-642.11.1.el6 base-debuginfo 282 M kernel-debuginfo x86_64 2.6.32-642.13.1.el6 base-debuginfo 282 M kernel-debuginfo x86_64 2.6.32-642.13.2.el6 base-debuginfo 282 M Transaction Summary ============================================================================================================================================== Install 2 Package(s) Upgrade 1 Package(s)
Version、 2.6.32-642.15.1.el6
OK
これで残りもインストールできたらsystemTapが使える。実際に使えた。が、インストールした翌日に再び実行してみると下記の様なエラーがでるようになった。
emantic error: missing x86_64 kernel/module debuginfo [man warning::debuginfo] under '/lib/modules/2.6.32-642.15.1.el6.x86_64/build'
よくよく調べるとyum-cronが走り。centos.plusたるものにアップデートされてた。
Packages Altered: Updated kernel-debuginfo-2.6.32-642.15.1.el6.x86_64 @base-debuginfo Update 2.6.32-642.15.1.el6.centos.plus.x86_64 @base-debuginfo Updated kernel-debuginfo-common-x86_64-2.6.32-642.15.1.el6.x86_64 @base-debuginfo Update 2.6.32-642.15.1.el6.centos.plus.x86_64 @base-debuginfo
yum install kernel-debuginfo
だと、centos.plusのやつが入るみたい。
入れ直し必要。
ヘッダファイル(C)
概要
Cはほぼ読むだけ。とりあえず備忘録としての自分まとめ。
ヘッダファイルを利用しない
- あるファイルの関数から別ファイルの関数を呼び出す場合、その呼び出す関数の引数、戻り値を知っていないといけない。それを知るために、呼び出し側ではその関数の宣言を利用する。
- 利用側で宣言を知ることができない場合、暗黙の宣言が利用される。
- 宣言が定義と合致しているかはちぇっくなし。
- 別ファイルの関数などを使う場合に都度、自分で宣言を書かないといけない
暗黙の宣言
- 呼び出し側で例えば関数の情報(宣言)を知ることができない場合int型を返す、引数なしの関数としてみなされる。
- 自分で宣言を書いて定義と異なっていたとしても同じ
- コンパイラの気持ちとしては別ファイルにあるはずなので
リンク時
にみつかるやろ~
エラー
- 発覚するのはリンク時。
コンパイル時
にエラー見つけたい。
ヘッダファイルを利用
- 宣言を一つにまとめられる。再利用できる。
- ヘッダファイルに、関数、変数の宣言かく。
コンパイル時
に例えば関数の呼び出し側、定義側、とヘッダファイルにかかれている宣言が正しい(引数、戻り値の型)などをチェックしてくれる。コンパイル時
にみつかる。