(ftrace)trace-cmdでfunction_graphを使ってみる
はじめに
少し前にid:yohei-aさんに、Brendan Greggさんのfuncgraphを教わり、中身がシェルだったので、そのシェルでftraceの使い方が少し解りました。ありがとうございます。
今回は、funcgraphと同じ事をtrace-cmdコマンドで実現する方法をまとめます。(trace-cmdのfunction_graphを使います。)
ftraceを使うためのセットアップ
(1)kenelのリビルド
不要です。最近のディストリビューションは全てftraceがONになっています。少なくとも、RHEL6、Fedora22、ubuntu14.04では不要でした。
(2)debugfsの/sys/kernel/debugへのマウント
不要です。trace-cmdコマンド実行時に自動的にマウントしてくれます。
(3)trace-cmdのインストール。
trace-cmdコマンドがなかったら、yumやapt-getコマンドで、trace-cmdをインストールしてください。
■Fedora/RHEL # yum install trace-cmd ■ubuntu # apt-get install trace-cmd
trace-cmdを使う
基本的な使い方(trace-cmdからコマンドを実行する)
# trace-cmd record -p function_graph -g [トレースするfunction] コマンド # trace-cmd report > trace.log
- "trace-cmd record"でコマンドを実行しトレースを取得します。
- "-g"オプションで取得したい関数を指定します。
- 指定可能な関数は"/sys/kernel/debug/tracing/available_filter_functions"で確認できます。
- 複数関数を指定する場合は、"-g"オプションを複数指定します。
- トレース取得データは、デフォルトではカレントディレクトリのtrace.datになります。
実行例
# trace-cmd record -p function_graph -g SyS_mmap -g SyS_brk ls plugin 'function_graph' a.log a.out ltrace.log mem.c test_ftrace.dat trace.dat trace.dat.cpu0 trace.dat.cpu1 Kernel buffer statistics: Note: "entries" are the entries left in the kernel ring buffer and are not recorded in the trace data. They should all be zero. CPU: 0 entries: 0 overrun: 0 commit overrun: 0 bytes: 1764 oldest event ts: 17309.292890 now ts: 17309.295092 dropped events: 0 read events: 7450 CPU: 1 entries: 0 overrun: 0 commit overrun: 0 bytes: 0 oldest event ts: 16818.044541 now ts: 17309.295277 dropped events: 0 read events: 0 CPU0 data recorded at offset=0x4e6000 303104 bytes in size CPU1 data recorded at offset=0x530000 0 bytes in size # trace-cmd report -t > trace.log
取得した結果(trace.log)
version = 6 CPU 1 is empty cpus=2 ls-10862 [000] 17309.286563606: funcgraph_entry: | SyS_brk() { ls-10862 [000] 17309.286588309: funcgraph_entry: | down_write() { ls-10862 [000] 17309.286589501: funcgraph_entry: 0.231 us | _cond_resched(); ls-10862 [000] 17309.286591455: funcgraph_exit: 2.024 us | } ls-10862 [000] 17309.286592097: funcgraph_entry: 0.200 us | up_write(); ls-10862 [000] 17309.286593610: funcgraph_exit: 5.743 us | } ls-10862 [000] 17309.286665524: funcgraph_entry: | SyS_mmap() { ls-10862 [000] 17309.286666667: funcgraph_entry: | sys_mmap_pgoff() { ls-10862 [000] 17309.286667488: funcgraph_entry: | vm_mmap_pgoff() { ls-10862 [000] 17309.286668370: funcgraph_entry: | security_mmap_file() { ls-10862 [000] 17309.286669192: funcgraph_entry: | apparmor_mmap_file() { ls-10862 [000] 17309.286669904: funcgraph_entry: 0.201 us | common_mmap(); ls-10862 [000] 17309.286671417: funcgraph_exit: 1.613 us | } ls-10862 [000] 17309.286672048: funcgraph_entry: 0.170 us | ima_file_mmap(); ls-10862 [000] 17309.286673511: funcgraph_exit: 4.520 us | } <以下略>
実行中のプロセスのトレースを取得する
実行中のプロセスのトレースを取得する場合は、"-P"オプションで取得したいプロセスのPIDを指定します。
# trace-cmd record -p function_graph -g [トレースするfunction] -P PID # trace-cmd report > trace.log
実行例
# trace-cmd record -p function_graph -g SyS_mmap -g SyS_brk -P 10894 plugin 'function_graph' Hit Ctrl^C to stop recording <取得が終了したら、Ctrl+Cで中止する> ^CKernel buffer statistics: Note: "entries" are the entries left in the kernel ring buffer and are not recorded in the trace data. They should all be zero. CPU: 0 entries: 0 overrun: 0 commit overrun: 0 bytes: 2580 oldest event ts: 17631.193419 now ts: 17634.029942 dropped events: 0 read events: 166 CPU: 1 entries: 0 overrun: 0 commit overrun: 0 bytes: 0 oldest event ts: 16818.044541 now ts: 17634.030212 dropped events: 0 read events: 0 CPU0 data recorded at offset=0x4e6000 8192 bytes in size CPU1 data recorded at offset=0x4e8000 0 bytes in size # trace-cmd report -t > trace.log
データ圧縮アルゴリズムを整理してみた
データ圧縮(可逆圧縮)方式についてまとめました。
まとめ
- 可逆圧縮の実用的アルゴリズムのほとんどは、LZ法を元にしている
- LZは、ジェイコブ・ジヴ(Jacob Ziv)とエイブラハム・レンペル(Abraham Lempel)が開発した圧縮アルゴリズム
- LZ法は、LZ77と、LZ78の2種類があり、それぞれ圧縮の符号方式が異なる。LZ77はsliding-window手法、LZ78はdictionaryによる符号化をする。
- LZ77、LZ78は基礎的なアルゴリズムであり、実際に利用されるのはLZ77/78をベースに改良した実用的なアルゴリズムが利用されている。
- 実用的なアルゴリズムの例としては、LZ77から派生した、LZSS(ARA、LZH)やDEFLATE(zip、gzip)、LZ78から派生した、LZW(GIF、TIFF)などがある。
Macbook Air(2010/A1370)にubuntu14.04(Trusty)を入れてみた
(2016/12追記)ubuntu16.04のインストールの話も別記事で書いていますので、そちらも参照下さい。
nopipi.hatenablog.com
1.はじめに
MacbookAir3.1(2010年モデル:A1370)に、Ubuntu14.04.3(Trusty Tahr)をインストールしました。結果的には、14.04では基本悩むところはなくサクサク行くのですが、ググるといろんな情報が出てきて戸惑う(多分古いバージョンのubuntuの情報)ので、まとめてみました。
【補足】
基本的には、ubuntuのページにMacBookへのインストール情報がまとまっているので、こちらを参考にすればOKです。が、MacbookAir3.1/Trusty(ubuntu14.04)という組み合わせが無く他の組み合わせを参考にしたのが戸惑いの原因でした。
前提は以下の通りです。
- 入れる箱(Mac)
- Macbook Air A1370(2010年モデル)
- 入れるもの
- Ubuntu14.04.3(Trusty Tahr)
- メディア作成環境
- Windows10(OSレスの中古で、"OS X"環境ないもので...と言い訳^^;)
2.準備(インストールメディア)
ubuntuのインストール用メディアのisoをUSBメモリに突っ込んで、USBメモリブートでインストールしました。
インストールメディアを用意
ubuntuからダウンロード(当たり前ですが)
【ハマったポイント】
Mac用にチューニングされたisoもあるのですが、こちらではUSBブートが(なぜか)できませんでした。MacbookAir5.1とかではこちらを使ってとあるので、やり方があるのかもしれませんが分かりませんでした。
USBメモリブートメディア作成
今回は、"Universal-USB"というツールを利用しました。
http://www.pendrivelinux.com/universal-usb-installer-easy-as-1-2-3/
手順は、下記サイトを参考にしました。
3.インストール
4.MacBook用のubuntu設定
古いバージョンのubuntuだとドライバーを追加で入れたり、いろいろやらなければならないようですが、14.04は悩む必要はありませんでした。使いやすい用に少しカスタマイズした程度です。
ファンクションキーの反転
初期状態では、ファンクションキーは音声や液晶の明るさ調整がメインで、F1やF2とかファンクションキーとして利用する場合は、fnキーと組み合わせる必要があります。ですが、日本語変換の時面倒なので機能を反転させます。
以下のページを参考にしました。
$ sudo vi /etc/rc.local 下記の行を追加 echo 2 > /sys/module/hid_apple/parameters/fnmode
マウス変更
2本指で操作できるように設定変更。左バーの「システム設定」→「マウスとタッチパッド」を選択して設定。
5.使いやすくするために
ランチャーへの登録
デフォルトではターミナルが、左メニューバー(Launcher)にないので追加します。
- ランチャーの一番上のボタンを押し検索画面を出す
- 検索ボックスから「Ter・・・」と入力すると、ターミナルが表示されるので実行する。
- 実行するとlauncherに実行アプリのボタンが追加されるので、右クリックして「Launcherに登録」を実行
アップデート
立ち上げて暫くするとアップデートを促するメニューが出てそれを実行すればよいですが、手動実行する場合は以下の通り実行します。
GUIから実行
- 検索から「update」と入力し、アプリを実行
パッケージの追加インストール
sudo apt-get install vim sudo apt-get install openssh-server sudo apt-get install gimp
【RHEL/CentOS】RHEL6.6にMemAbailableがバックポートされている件
はじめに
先日の下記の記事で「RHEL6ではバックポートされてMemAvailableが使えるよ」という情報を頂いたので、追加で情報を整理しました。
nopipi.hatenablog.com
RHEL6.6へのMemAvailableのバックポート
MemAvailableは、RHEL6.6でバックポートされてました。というのも、ググったらredhatのナレッジ情報が出てきました。
詳細はログインしないと見れないのですが、MemAvailableは"kernel-2.6.32-504.el6"以上で利用可能とあり、このバージョンがRHEL6.6のカーネルバージョンになります。
Backport "MemAvailable" field to /proc/meminfo in Red Hat Enterprise Linux 6. - Red Hat Customer Portal
使い方
MemAvailableの有効化
デフォルトでは互換性に配慮し非表示に設定されているため、カーネルパラメータvm.meminfo_legacy_layoutを無効する必要があります。
# vim /etc/sysctl.conf vm.meminfo_legacy_layout=0 書き込み後、下記コマンドで反映&確認。 # sysctl -p # sysctl vm.meminfo_legacy_layout vm.meminfo_legacy_layout = 0
表示
RHEL7とは表示位置が違ったり、freeコマンドの表示形式が違うとかありますが、availableがキチンと表示されます。
/proc/meminfo
一番最後の行に表示されます。取ってつけたようなとも思いますが、コード修正の影響を考えたらしょうがないですね。
# cat /proc/meminfo MemTotal: 1020236 kB MemFree: 76136 kB Buffers: 230192 kB Cached: 596980 kB SwapCached: 332 kB Active: 328452 kB Inactive: 519032 kB Active(anon): 3200 kB Inactive(anon): 17380 kB Active(file): 325252 kB Inactive(file): 501652 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1048572 kB SwapFree: 1046720 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 20084 kB Mapped: 7884 kB Shmem: 268 kB Slab: 72596 kB SReclaimable: 45560 kB SUnreclaim: 27036 kB KernelStack: 1312 kB PageTables: 5976 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 1558688 kB Committed_AS: 108076 kB VmallocTotal: 34359738367 kB VmallocUsed: 138664 kB VmallocChunk: 34359594564 kB HardwareCorrupted: 0 kB AnonHugePages: 2048 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 8192 kB DirectMap2M: 1040384 kB MemAvailable: 813196 kB
freeコマンド
freeコマンドは、"-a"オプションで表示されます。
# free -a total used free shared buffers cached available Mem: 1020236 944480 75756 268 230216 597172 813036 -/+ buffers/cache: 117092 903144 Swap: 1048572 1852 1046720
ちなみに、MemAvailableが無効化(vm.meminfo_legacy_layout=1)の場合、availableは0と表示されます。
# free -a total used free shared buffers cached available Mem: 1020236 944472 75764 268 230248 597192 0 -/+ buffers/cache: 117032 903204 Swap: 1048572 1852 1046720
補足
upstreamカーネルのMemAbailableコミット情報
ちなみにナレッジには以下の通り、upstream(コミュニティのカーネル)からRHEL6バックポートしているよと記載があります。
Backport upstream commit id: 34e431b0ae398fc54ea69ff85ec700722c9da773 to add MemAvailable field to /proc/meminfo in Red Hat Enterprise Linux 6
そして、このgitのコミットIDを探すとupstreamカーネルのコミットとLKMLの情報は以下の通りでした。
kernel/git/torvalds/linux.git - Linux kernel source tree
LKML: Rik van Riel: [RFC PATCH -mm] provide estimated available memory in /proc/meminfo
【RHEL】linuxメモリのfreeとmeminfoの関係を図解し利用率の計算方法を説明してみる
はじめに
linuxサーバを利用する上で何時も頭を悩ますものの一つが、メモリ利用状況の評価(メモリ利用率)ではないでしょうか。私も悩みます。そこでRHELベースですが、メモリ利用容量/メモリ利用率の評価をどう考えるかということを整理しました。
詳細は後述しますが、例えばRHEL7のfreeコマンドとmeminfoの関係を整理するとこんな感じになります。
ちなみにlinuxのメモリ解説&meminfoをどのように見ればいいかは、e.nakaiさんのページが参考になります。(私のメモリ周辺のバイブル的ページです^^;)
enakai00.hatenablog.com
linuxのメモリ利用容量(空き容量)の考え方
何を持って、「メモリが空いている」とするのか??
単純に考えると、何も利用していない(割り当てていない)領域を空き容量とすればいいはずです。しかしlinuxをはじめとする現在のOSでは、「使えるメモリはとことん使ってしまえ!!」という設計思想なため、空きメモリは積極的にファイルキャッシュ用途に利用してしまいます。その結果、「未割り当て領域を空き領域」と定義すると、メモリ利用率が常に100%となり「意味がねぇなぁ」という感じになってしまいます。
そこで改めて「メモリが空いている状態」を考える必要があります。そこで着目するのが、メモリ解放のカーネルの挙動です。カーネルはプロセスやドライバから新規メモリ(ページ)の確保要求があった時、未使用領域(freeコマンドやmeminfoで言うところのfree領域)から新規割り当てを行います。未使用領域が無い場合、既存のメモリを解放して空きを作り、新なメモリ割当を行います。この「既存メモリの解放処理」は2通りのやり方があり、一つはスワップアウトして空きを作る方法、もう一つはディスク同期してメモリ解放する方法になります。メモリ解放の方式を整理すると、以下の表のようになります。
メモリ解放方法 | 対象ページ | 対象ページの例 | 再アクセス時の挙動 |
---|---|---|---|
スワップアウトして解放 | 無名ページ (anonymous page) |
プロセスのメモリ(データ/スタック領域),共有メモリ,tmpfs | スワップイン |
ディスク同期して解放 | ファイルページ (file page) |
ファイルキャッシュ&バッファ、プロセスのテキスト領域 | ディスクから再読み込み |
※1 無名ページ&ファイルページについては、記事文末を参照。
※2 プロセスのテキスト領域とは、プロセスの実行イメージ(プログラム)を格納するメモリ領域です。
※3 もちろん、プロセス終了やプログラム中のfree()など、本当に不要になって開放するパターンもありますが、ここでは割愛します。
ここでサーバ用途の場合のメモリ設計を考えると、「可能な限りスワップを発生させないようにメモリサイジングする」ことが重要になります。特に(バッチ処理ではなく)オンライン系のサーバ(web,AP,DBサーバとか)の場合、スワップイン処理にかかるオーバーヘッドによるクライアントへのレスポンス遅延が一番気になるためです。例えば通常1秒以内でレスポンスが帰っている処理が数秒や最悪十数秒に伸びることで、利用者のユーザビリティが落ち「使えねーシステム」の烙印を押されることになることになるためです。
ということで、メモリ空き容量を評価する上は、「スワップが発生しない程度」の空きが保たれていることが重要というとになり、結果として「未割当て領域+ディスク同期による解放領域」を空きと見なすという考えになります。(説明がちょっと強引ですが。)
ここまでの話を、式にまとめると以下のような形になります。
メモリの空き容量 = 未割り当て容量(free) + ディスク同期にて解放可能な容量(ファイルページ≒バッファ&キャッシュ) メモリ利用容量 = メモリ合計容量 - メモリ空き容量 = メモリから解放不可な容量 + 解放時にスワップアウトしてしまう容量
linuxのメモリ利用容量/空き容量の計算方法
と前置きが長かったですが、ここからがlinuxの悩ましい所。
なぜなら、linuxでメモリ容量を確認するfreeコマンドで取得できるバッファ&キャッシュ領域には、スワップする領域も含まれており、単純に「メモリ利用容量=メモリ全体 - free - Buffer&Cache」としてしまうと、メモリ利用容量を過小評価してしまうためです。最近のlinuxカーネルはこの辺を考慮したメモリ情報を表示してくれるのですが(RHEL7とか。詳細は後述)、昔の特にRHEL5以前は真面目にやろうとすると結構しんどかったです。(カーネルのメモリ管理を理解していなかったという要素も大きいですが。。。)
以下に最新のRHEL7から順に、代々のバージョンでどのようにメモリ利用容量/利用率を計算していたかを説明します。こうやって整理すると、「昔は苦労したなぁ〜」というのがよくわかりますね。^^;
■RHEL7
最初にRHEL7ですが、RHEL7からはメモリ利用率の計算が劇的に楽になりました。
というのも、上でぐちゃぐちゃ説明したことを、freeコマンドの「available」というパラメータで表示してくれるからです。(厳密には/proc/meminfoに"MemAvailable:"という利用可能なメモリ容量の目安を表示してくれるようになったのですが)
なので、わざわざmeminfoをみなくても、freeコマンドの結果をちょっと加工すれば利用率をだせるようになりました。
【freeコマンドとmeminfoの図解】
【計算方法】
freeコマンドの結果をawkで処理させています。
#!/bin/bash export LANG=C, LC_ALL=C free | awk ' BEGIN{ total=0;used=0;available=0;rate=0; } /^Mem:/{ total=$2; available=$7; } END{ used=total-available; rate=100*used/total; printf("used%,total(KB),used(KB),available(KB)\n"); printf("%.1f,%d,%d,%d\n",rate,total,used,available); }';
freeコマンド表示例
# free total used free shared buff/cache available Mem: 1884812 106076 1615644 8632 163092 1624364 Swap: 2097148 0 2097148
/proc/meminfo表示例
# cat /proc/meminfo MemTotal: 1884812 kB MemFree: 1615784 kB MemAvailable: 1624504 kB Buffers: 880 kB Cached: 120396 kB SwapCached: 0 kB Active: 84932 kB Inactive: 95568 kB Active(anon): 59524 kB Inactive(anon): 8332 kB Active(file): 25408 kB Inactive(file): 87236 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 2097148 kB SwapFree: 2097148 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 59244 kB Mapped: 20852 kB Shmem: 8632 kB Slab: 41816 kB SReclaimable: 17396 kB SUnreclaim: 24420 kB KernelStack: 1680 kB PageTables: 3688 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3039552 kB Committed_AS: 268452 kB VmallocTotal: 34359738367 kB VmallocUsed: 156764 kB VmallocChunk: 34359575144 kB HardwareCorrupted: 0 kB AnonHugePages: 4096 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 53184 kB DirectMap2M: 2043904 kB
■RHEL6
RHEL6時代までのfreeコマンドでは、バッファ&キャッシュ領域にスワップアウトしてしまうメモリも含まれているため、meminfoを直接参照していました。ただRHEL5以前とは異なり、RHEL6ではメモリ管理にSplitLRUが導入され、無名ページとファイルページを分て管理するようになっており、meminfoでもactive,inactive(メモリ回収候補ページのリスト)の登録ページ数が種別ごとに表示されるようになっているので、それを利用してメモリ計算をしています。
【freeコマンドとmeminfoの図解】
【計算方法】
/proc/meminfoのデータをawkでガリガリ計算させています。
export LANG=C, LC_ALL=C awk ' BEGIN{ total=0;used=0;available=0;rate=0; } /^MemTotal:/ {total=$2;} /^MemFree:/ {available=available+$2;} /^Active\(file\):/ {available=available+$2;} /^Inactive\(file\):/ {available=available+$2;} END{ used=total-available; rate=100*used/total; printf("used%,total(KB),used(KB),available(KB)\n"); printf("%.1f,%d,%d,%d\n",rate,total,used,available); }' /proc/meminfo;
freeコマンド表示例
# free total used free shared buffers cached Mem: 1020236 147168 873068 268 17824 54444 -/+ buffers/cache: 74900 945336 Swap: 1048572 0 1048572
/proc/meminfo表示例
MemTotal: 1020236 kB MemFree: 873068 kB Buffers: 17832 kB Cached: 54460 kB SwapCached: 0 kB Active: 38724 kB Inactive: 51140 kB Active(anon): 17580 kB Inactive(anon): 256 kB Active(file): 21144 kB Inactive(file): 50884 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1048572 kB SwapFree: 1048572 kB Dirty: 60 kB Writeback: 0 kB AnonPages: 17588 kB Mapped: 15584 kB Shmem: 268 kB Slab: 34304 kB SReclaimable: 8984 kB SUnreclaim: 25320 kB KernelStack: 1280 kB PageTables: 5236 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 1558688 kB Committed_AS: 101760 kB VmallocTotal: 34359738367 kB VmallocUsed: 138664 kB VmallocChunk: 34359594564 kB HardwareCorrupted: 0 kB AnonHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 8192 kB DirectMap2M: 1040384 kB
- 追記(2015.9.19)
- RHEL6.6にMemAvailableがバックポートされているという情報を頂いたので、こちらに整理しました。->【RHEL/CentOS】RHEL6.6にMemAbailableがバックポートされている件 - のぴぴのメモ
■RHEL5以前
で、一番悩ましいRHEL5以前です。この時代はfreeコマンドがダメでかつ、この当時は無名ページとファイルページを一緒に管理(一つのLRUリストにゴジャッと登録していた)ため、meminfoでもファイルページ数を的確に把握することができませんでした。
そこでどうするかというと、ファイルキャッシュ&バッファとしてカウントされるもののうち、無名ページに該当するものほとんどは、(1)tmpfs用のメモリ,(2)IPCの共有メモリ用のメモリ、の2つになることに着目します。そこで、それぞれの利用状況を取得してその分をmeminfoから取得した値から引き算し近似的に利用可能な容量を計算するというやり方をします。
- キャッシュ&バッファから除外する容量の計算方法
- tmpfs --> dfコマンド結果から、tmpfsのusedの容量を足し算する
- IPC共有メモリ --> "ipcs -u"コマンドの"pages allocated"(共有メモリ様に割り当て済みのページ数)を取得
【freeコマンドとmeminfoの図解】
【計算方法】
dfコマンド、"ipcs -u"コマンド、と/proc/meminfoのデータを組み合わせて、awkで計算させています。
#!/bin/bash export LANG=C, LC_ALL=C #メモリファイル TMPFS=`/bin/df --portability |awk 'BEGIN{used=0;} /^tmpfs/{used=used+$3}END{print used}'` #IPC シェアードメモリ PAGE_SIZE=$((`/usr/bin/getconf PAGE_SIZE` / 1024)) IPC_SHM=`/usr/bin/ipcs -u |awk -v SIZE=${PAGE_SIZE} '/^pages allocated/{print $3 * SIZE}'` #シェアードメモリ合計(tmpfs + ipc_shm) SHMEM=$(( ${TMPFS} + ${IPC_SHM} )) awk -v shmem=${SHMEM} ' BEGIN{ total=0;used=0;available=0;rate=0; } /^MemTotal:/ {total=$2;} /^MemFree:/ {available=available+$2;} /^Buffers:/ {available=available+$2;} /^Cached:/ {available=available+$2;} END{ available=available-shmem used=total-available; rate=100*used/total; printf("used%,total(KB),used(KB),available(KB)\n"); printf("%.1f,%d,%d,%d\n",rate,total,used,available); }' /proc/meminfo;
freeコマンド表示例
# free total used free shared buffers cached Mem: 2058764 313972 1744792 0 19748 165736
- /+ buffers/cache: 128488 1930276
/proc/meminfo表示例
MemTotal: 2058764 kB MemFree: 1744792 kB Buffers: 19756 kB Cached: 165736 kB SwapCached: 0 kB Active: 103444 kB Inactive: 160096 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 2058764 kB LowFree: 1744792 kB SwapTotal: 4095992 kB SwapFree: 4095992 kB Dirty: 112 kB Writeback: 0 kB AnonPages: 78060 kB Mapped: 10520 kB Slab: 26440 kB PageTables: 3472 kB NFS_Unstable: 0 kB Bounce: 0 kB CommitLimit: 5125372 kB Committed_AS: 158884 kB VmallocTotal: 34359738367 kB VmallocUsed: 265472 kB VmallocChunk: 34359470723 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 Hugepagesize: 2048 kB
蛇足
その1:無名ページとファイルページ
まず、このページではファイルページと記載しましたが、正確には「ファイルバックド(file-backed)ページ」ですかね。また、ファイルページを記事内では「ディスクと同期して解放」と記載してますが、正確にはディスクと同期するのは未同期データの解放の時のみです。同期済みの場合は同期処理なく解放します。
無名ページとファイルページの違いをざっくりと書くと、本文にも記載しましたが以下の通りになります。
蛇足になりますが、10年前にカーネル本(オライリー&ペンギン黒本)を読んだ時は、いきなり「無名ページ」と出て来て、何が何だか分からず挫折した経験があります。それから10年経ってやっと「スワップする/しない、の差なのね」という理解に到達。この辺の理解している人としてない人の溝の深さが、カーネルを理解する上での障壁(カーネル難しぃ〜)の一つになっているのかなと思います。
その2:図解の内容のツッコミ
「SReclaimable」領域を、「ディスク同期して解放」で色塗りしていますが、実際は単純にslabとして未使用領域で、メモリが足りない場合は単純に開放するだけですね。後で気付いたのですが、図を修正するのが面倒なので、そのままにしちゃいました。
その3:RHEL6の計算
RHEL6では、"active(file)"と"inative(file)"から計算していますが、RHEL7のavailaleのカーネル内部の計算を見るに、"SReclaimable"も加算しなければならないですね。まあ全体量に対して、"SRelaimale"は小さいので加算しなくても大した影響はないとおもいますが。
【Fedora22】日本語入力設定のメモ
【RHEL7】sysctlのカーネルパニックオプション
sysctlのカーネルパニックオプション
ちょいとカーネルパニックをどう設定すればよいかという話があって、ためしにsyscltをpanicでgrepすると、意外にというかpanicに関するパラメータがバラバラ出てきてどうすればよいかイマイチわからない。
# sysctl -a|grep panic fs.xfs.panic_mask = 0 kernel.hung_task_panic = 0 kernel.panic = 0 kernel.panic_on_io_nmi = 0 kernel.panic_on_oops = 1 kernel.panic_on_stackoverflow = 0 kernel.panic_on_unrecovered_nmi = 0 kernel.panic_on_warn = 0 kernel.softlockup_panic = 0 kernel.unknown_nmi_panic = 0 vm.panic_on_oom = 0
ということで整理してみた。
panicの整理
整理するとこんな感じ。
- パニック本体設定
-
- kernel.panic
-
- トリガー設定
panic系パラメータの関係
カーネルソースから各パラメータの関係を整理すとこうなる。
それぞれのパラメータの挙動
kernel.panic
- 説明
- panic時の挙動設定。kdump利用時は、このパラメータが使われている処理ロジックの前に、kdumpのセカンドカーネル起動が走るため、パラメータが使われることはない。
- 設定
- kernel.panic > 0:n秒後まって再起動
- kernel.panic = 0:ハング(デフォルト)
- kernel.panic < 0:即時再起動
kernel.panic_on_unrecovered_nmi
kernel.unknown_nmi_panic
kernel.panic_on_io_nmi
kernel.panic_on_warn
kernel.softlockup_panic
- 説明
- カーネルのwatchdog監視が有効(kernel.nmi_watchdogか、kernel.watchdogが1の場合、有効)の場合で、watchdog監視に引っかかった時のpanic発生有無。
- 設定
- kernel.softlockup_panic=0:panicしない(デフォルト)
- kernel.softlockup_panic=1:panicする
kernel.hung_task_panic
- 説明
- khungtaskカーネルスレッドが、TASK_UNINTERRUPTIBLE状態が120秒(デフォルト)超過しているスレッドを監視していて、該当するスレッドがいた時にpanicさせるかの設定。
- 設定
- kernel.hung_task_panic=0:panicしない(デフォルト)
- kernel.hung_task_panic=1:panicする
kernel.panic_on_stackoverflow
RHEL7 initramfsの展開方法
今までのやり方では展開されない
普通、initramfsの中身を展開する場合は、gunzipあたりとcpioを使って以下のようにするはず。
$ cd /tmp $ cp /boot/initramfs.img initramfs.gz $ gunzip initramfs.gz $ mkdir ramdisk $ cd ramdisk $ cpio -i -d -H newc --no-absolute-filenames < ../initramfs
ところが、最近のFedora/CentOS/RHELで上記をやると、これは「gzipじゃない!!」と怒られてしまう。
$gunzip initramfs.gz gzip: initramfs.gz: not in gzip format
じゃあ、fileで確認するとcpioだというから直接cpioで展開すると、CPUのマイクロコードらしきものしか展開されない(´・ω・`)
$ mkdir ramdisk $ cd ramdisk $ file ../initramfs.gz ../initramfs.gz: ASCII cpio archive (SVR4 with no CRC) $ cpio -i -d -H newc --no-absolute-filenames < ../initramfs.gz 26 blocks $ find . . ./kernel ./kernel/x86 ./kernel/x86/microcode ./kernel/x86/microcode/GenuineIntel.bin ./early_cpio
[RHEL7/CentOS7/FC21]initramfsの展開方法
グーグルさんに聞いてみる
キーワードを変えていろいろ調べたら、出てきた。
forums.fedoraforum.org
手順
上記内容をちょっとだけ丁寧に解説。
バイナリ解析ツールのインストール
まずバイナリー解析用ツールを入れないといけないらしい。
yum -y install binwalk
なおRHELやCentOSのレポジトリにはbinwalkはないので、ネットからrpmパッケージをDLしてrpmコマンドで個別にインストールするか、ソースを落としてコンパイルする。
initramfsの解析と展開
$ cp /boot/initramfs-3.10.0-229.el7.x86_64.img . $ binwalk initramfs-3.10.0-229.el7.x86_64.img DECIMAL HEX DESCRIPTION ------------------------------------------------------------------------------------------------------- 13312 0x3400 gzip compressed data, from Unix, last modified: Thu Apr 30 13:18:46 2015, max compression 3412955 0x3413DB bzip2 compressed data $ dd if=initramfs-3.10.0-229.el7.x86_64.img of=initramfs.gz bs=13312 skip=1 1350+1 records in 1350+1 records out 17982993 bytes (18 MB) copied, 0.0431475 s, 417 MB/s $ gunzip initramfs.gz $ mkdir ramdisk $ cd ramdisk/ $ cpio -i -d -H newc --no-absolute-filenames < ../initramfs 80381 blocks
なおgzipが始まる位置はその時々で変わる(おそらくmicrocodeのデータサイズが変わるから)ため、都度binwalk解析の確認が必要。
RHEL6 squashfsの作り方
squashfsとは
squashfsとは、圧縮された読み込み専用のファイルシステムでLiveCD(CD/DVDブートして利用するOS)で利用されている。詳しくはwikipediaを見るのが手っ取り早いかと。
wikipedia:SquashFS
squashfsのファイルシステムの作り方
squashfsファイルシステムのマウント
出来上がったsqushfsはmountコマンドのループバックオプションでマウントする。
# mount -o loop File.squashfs /MountPoint/
fstabで自動マウント
fstabに登録するときは以下のように記載する。
- /etc/fstabに以下の行を追加
/Directory/File.squashfs /MountPoint squashfs loop 0 0
mountコマンドでマウントする。
# mount -a
追伸
昔、cloopで圧縮ファイルを作るということをやっていたけど(Fedora5/RHEL4 cloopでLinux圧縮ファイルシステムを作る - のぴぴのメモ、Upstreamにマージされていて各ディストリビューションにもデフォルトで入っているsquashfsのほうが使いやすいですよね。
Linux /proc/meminfoの統計情報を取得する。
/proc/meminfoの統計情報を取得する
Linuxのメモリ挙動を詳しく分析するためには/proc/meminfoを見る必要がある。がしかし、sarコマンドのように時系列でmeminfo情報を取得してくれるコマンドはなく、自作のスクリプトなどで取得するしかない。
そこで、スクリプトで/proc/meminfo情報を時系列で取得する方法を説明する。
- 2013.3.4 awkコマンド修正(ヘッダ末尾のリターンコード忘れてた)
コマンドで取得する(テストなどの秒間隔での取得)
ざっくりいうと、meminfoをawkでCSV形式に整形してログファイルに追加でリダイレクトするコマンドを、wlile分で無限ループさせているだけ。終了する場合は、CTRL+Cで強制終了させる。
LANG=C;( awk 'BEGIN{ printf "\"DATE\",\"TIME\""} {printf ",\"%s(%s)\"",$1,$3} END{printf "\n"}' /proc/meminfo > meminfo.csv ); while true;do ( awk 'BEGIN{ printf strftime("%Y/%m/%d, %H:%M:%S") } {printf ",%d",$2} END{printf "\n"}' /proc/meminfo >> meminfo.csv );sleep 1; done
これを動かすと、こんな結果が取得される。
"DATE","TIME","MemTotal:(kB)","MemFree:(kB)","Buffers:(kB)","Cached:(kB)","SwapCached:(kB)","Active:(kB)","Inactive:(kB)","Active(anon):(kB)","Inactive(anon):(kB)","Active(file):(kB)","Inactive(file):(kB)","Unevictable:(kB)","Mlocked:(kB)","SwapTotal:(kB)","SwapFree:(kB)","Dirty:(kB)","Writeback:(kB)","AnonPages:(kB)","Mapped:(kB)","Shmem:(kB)","Slab:(kB)","SReclaimable:(kB)","SUnreclaim:(kB)","KernelStack:(kB)","PageTables:(kB)","NFS_Unstable:(kB)","Bounce:(kB)","WritebackTmp:(kB)","CommitLimit:(kB)","Committed_AS:(kB)","VmallocTotal:(kB)","VmallocUsed:(kB)","VmallocChunk:(kB)","HardwareCorrupted:(kB)","AnonHugePages:(kB)","HugePages_Total:()","HugePages_Free:()","HugePages_Rsvd:()","HugePages_Surp:()","Hugepagesize:(kB)","DirectMap4k:(kB)","DirectMap2M:(kB)" 2013/03/03, 23:58:48,2054984,1161012,99012,605416,0,282204,439192,17128,8,265076,439184,0,0,4128760,4128760,8,0,16960,15536,172,132568,77788,54780,808,4056,0,0,0,5156252,140192,34359738367,274388,34359451196,0,0,0,0,0,0,2048,8192,2088960 2013/03/03, 23:58:49,2054984,1160996,99012,605412,0,282176,439192,17104,8,265072,439184,0,0,4128760,4128760,8,0,16976,15576,172,132580,77792,54788,816,4036,0,0,0,5156252,140192,34359738367,274388,34359451196,0,0,0,0,0,0,2048,8192,2088960 2013/03/03, 23:58:50,2054984,1160996,99020,605412,0,282176,439200,17104,8,265072,439192,0,0,4128760,4128760,20,0,16976,15576,172,132580,77792,54788,816,4036,0,0,0,5156252,140192,34359738367,274388,34359451196,0,0,0,0,0,0,2048,8192,2088960 2013/03/03, 23:58:51,2054984,1160996,99020,605412,0,282216,439200,17144,8,265072,439192,0,0,4128760,4128760,20,0,16972,15576,172,132580,77792,54788,816,4036,0,0,0,5156252,140192,34359738367,274388,34359451196,0,0,0,0,0,0,2048,8192,2088960
cronで取得する(日/週/月単位のトレンド取得)
長期のトレンドを見たい場合は、cronで分以上の間隔で取得するのが良い。
取得用のシェル
- /usr/lib64/sa/meminfo.sh
#!/bin/bash LANG=C PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin: export LANG PATH umask 022 LOGFILE_BASE="/var/log/sa/meminfo" LOGFILE="${LOGFILE_BASE}.`date +%Y%m%d`" # Write header, if LOGFILE does not exist. if [ ! -f ${LOGFILE} ]; then awk ' BEGIN{ printf "\"DATE\",\"TIME\"" } { printf ",\"%s(%s)\"",$1,$3 } END{ printf "\n" }' /proc/meminfo > ${LOGFILE} fi # Write data awk ' BEGIN{ printf strftime("%Y/%M/%d, %H:%M:%S") } { printf ",%d",$2 } END{ printf "\n" }' /proc/meminfo >> ${LOGFILE} exit 0
シェルをキックするcron設定
1分間隔で取得する。
- /etc/cron.d/meminfo
# Get meminfo. * * * * * root /usr/lib64/sa/meminfo > /dev/null 2>&1
ログのローテーションは。。。別に考えよう(^^;
シェル用のメッセージロギングツール
シェルのメッセージを一元的に出力する自作のツールです。
職場で使われているロギングツールがシンプルで使いやすいので、同じようなものを自作したものです。
ツールはgithubで公開しています。
- uploggerのページ → Uplogger by Noppy
- githubソース → Noppy/uplogger · GitHub
configureの作り方(autotoolsの使い方)
はじめに
オープンソースでよくある、configure → make → make installというセットアップの流れ。これはGNUのautotoolsというツール&フレームワーク群により実現されている。
本記事ではそのautotoolsによりconfigureを作成する手順を説明する。
- autotoolsの概要についてはこちら→Autotools - Wikipedia
作成の流れ
- 必要ファイルの作成(automake時に必要)
- Makefile.am作成(後の作成/修正も可)
- autoscanコマンドの実行
- configure.acファイルの作成&編集
- aclocal実行
- autoheader実行
- automake実行
- autoconf実行
ユーザが編集するファイルは、configure.acとMakefile.am。これらファイルを修正した時は、aclocalコマンド以降を都度実行してファイルを再生性する。なので、aclocalコマンド以降をシェル化して一気に実行するようにしておくと便利である。
手順詳細
必要ファイルの作成
automakeコマンド実行時に求められるファイルを作成する。とりあえずファイルがあればよいので、空ファイルを作成する。(内容は必要に応じ別途修正する)
$ touch INSTALL NEWS README LICENSE AUTHORS ChangeLog
Makefile.am作成(後の作成/修正も可)
次のautoscanコマンドで、AC_CONFIG_FILESを自動生成するため、とりあえずMakefile.amを作成する。とりあえずこの段階では空ファイルでもかまわない。(automake実行時に中身があればOK)
-> Makefile.amのつくり方(別途作成予定)
autoscanコマンドの実行
configure.scanを作成し、それをRenameしてconfigure.acを作成する。
$ autoscan $ mv configure.scan configure.ac
configure.acファイルの作成&編集
configure.acを修正する。詳細は別途作成
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. sAC_PREREQ([2.63]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) <== パッケージ&バージョン&連絡先を記入 AC_CONFIG_SRCDIR([src/uplog_util.c]) AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. AC_CHECK_HEADERS([fcntl.h limits.h locale.h stdlib.h string.h sys/socket.h syslog.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_PID_T # Checks for library functions. AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_STRNLEN AC_CHECK_FUNCS([dup2 getcwd gethostname gettimeofday memset realpath select setlocale socket strerror]) AC_CONFIG_FILES([Makefile conf/Makefile src/Makefile]) <==Makefile.amを増やしたらここに追加 AC_OUTPUT
aclocal実行以降
以後はシェル化し、Makefile.amやconfigure.ac修正時に都度実行すると楽。
echo aclocal aclocal echo autoheader autoheader echo automake automake --add-missing --copy echo autoconf autoconf
ESXi TeraTermマクロ自動化
本当はvSphere CLIをインストールして利用すればよいのだが、VMのPowerOnとハイパーバイザのシャットダウンだけで十分だったので、TeraTermのマクロで自動化。
前提
ESXiは、SSH 鍵認証でログインできること。
SSH設定詳細はこちら→ESXi5 SSH 有効化&鍵認証(TeraTermの自動ログインマクロ付) - のぴぴのメモ
ESXi Hypervisorシャットダウン
コマンド"vim-cmd hostsvc/standby_mode_enter'"で停止。
; ========================================================== ; Setting (IP, UserName, KEY file) HOSTADDR = 'xxx.xxx.xxx.xx' ;ESXiのIPアドレス USERNAME = 'root' KEY_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;ログインに使用する秘密鍵 CNF_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;TeraTermの設定ファイル ; ========================================================== ;; Generate login command COMMAND = HOSTADDR strconcat COMMAND ':22 /ssh /2 /auth=publickey /user=' strconcat COMMAND USERNAME strconcat COMMAND ' /keyfile="' strconcat COMMAND KEY_FILE strconcat COMMAND '" /F="' strconcat COMMAND CNF_FILE strconcat COMMAND '"' ;; Login connect COMMAND wait '~ #' ;; shutdown hypervisor sendln 'vim-cmd hostsvc/standby_mode_enter' sendln 'exit' end
VM PowerON
- "vim-cmd vmsvc/getallvms"コマンドで、VM一覧を取得
- 取得したVM一覧よりリストを生成、起動したいVMの番号をインプットボックスより入力
- "vim-cmd vmsvc/power.getstate vim"で、各VMのPower状態を取得
- "vim-cmd vmsvc/power.on VMID"コマンドでVMを起動
; ========================================================== ; Setting (IP, UserName, KEY file) HOSTADDR = 'xxx.xxx.xxx.xx' ;ESXiのIPアドレス USERNAME = 'root' KEY_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;ログインに使用する秘密鍵 CNF_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;TeraTermの設定ファイル ; ========================================================== ;; Initialize NUM=256 strdim VM_NO NUM strdim VM_NAME NUM strdim VM_STAT NUM timeout=1 ;; Generate login command COMMAND = HOSTADDR strconcat COMMAND ':22 /ssh /2 /auth=publickey /user=' strconcat COMMAND USERNAME strconcat COMMAND ' /keyfile="' strconcat COMMAND KEY_FILE strconcat COMMAND '" /F="' strconcat COMMAND CNF_FILE strconcat COMMAND '"' ;; Login connect COMMAND wait '~ #' ;;PowerOn VM count = 0 result = 1 sendln 'vim-cmd vmsvc/getallvms' waitln 'Vmid' while result ; receive VM list recvln if result = 0 then goto getall_fail endif strmatch inputstr '~ #' if result <> 0 then goto getall_fail endif ; Split strreplace inputstr 1 '\s+' ' ' strsplit inputstr " " VM_NO[count] = groupmatchstr1 VM_NAME[count] = groupmatchstr2 count = count + 1 goto getall_end :getall_fail result = 0 :getall_end endwhile ; Get VM power status for i 0 count-1 ; get VM stat MSG = 'vim-cmd vmsvc/power.getstate ' strconcat MSG VM_NO[i] sendln MSG waitln 'Retrieved' recvln strsplit inputstr " " VM_STAT[i] = groupmatchstr2 next ;;Select VM MSG="Select VM Number\n-----------------------------\n" for i 0 count-1 int2str stri i strconcat MSG stri strconcat MSG '.\t' strconcat MSG VM_STAT[i] strconcat MSG '\t' strconcat MSG VM_NAME[i] strconcat MSG '\n' next strconcat MSG '\n\n-1\tCancel\n-----------------------------' :select_RETRY inputbox MSG 'select VM' 1 str2int vmnum inputstr if result = 0 then goto select_RETRY endif if vmnum < 0 then goto EXIT_MACRO endif ; PowerON VM COMMAND= 'vim-cmd vmsvc/power.on ' strconcat COMMAND VM_NO[vmnum] sendln COMMAND wait '~ #' ;;exit :EXIT_MACRO sendln 'exit' end
VM PowerOFF
- "vim-cmd vmsvc/getallvms"コマンドで、VM一覧を取得
- 取得したVM一覧よりリストを生成、起動したいVMの番号をインプットボックスより入力
- "vim-cmd vmsvc/power.getstate vim"で、各VMのPower状態を取得
- "vim-cmd vmsvc/power.off VMID"コマンドでVMを停止
; ========================================================== ; Setting (IP, UserName, KEY file) HOSTADDR = 'xxx.xxx.xxx.xx' ;ESXiのIPアドレス USERNAME = 'root' KEY_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;ログインに使用する秘密鍵 CNF_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;TeraTermの設定ファイル ; =========================================================== ;; Initialize NUM=256 strdim VM_NO NUM strdim VM_NAME NUM strdim VM_STAT NUM timeout=1 ;; Generate login command COMMAND = HOSTADDR strconcat COMMAND ':22 /ssh /2 /auth=publickey /user=' strconcat COMMAND USERNAME strconcat COMMAND ' /keyfile="' strconcat COMMAND KEY_FILE strconcat COMMAND '" /F="' strconcat COMMAND CNF_FILE strconcat COMMAND '"' ;; Login connect COMMAND wait '~ #' ;;PowerOn VM count = 0 result = 1 sendln 'vim-cmd vmsvc/getallvms' waitln 'Vmid' while result ; receive VM list recvln if result = 0 then goto getall_fail endif strmatch inputstr '~ #' if result <> 0 then goto getall_fail endif ; Split strreplace inputstr 1 '\s+' ' ' strsplit inputstr " " VM_NO[count] = groupmatchstr1 VM_NAME[count] = groupmatchstr2 count = count + 1 goto getall_end :getall_fail result = 0 :getall_end endwhile ; Get VM power status for i 0 count-1 ; get VM stat MSG = 'vim-cmd vmsvc/power.getstate ' strconcat MSG VM_NO[i] sendln MSG waitln 'Retrieved' recvln strsplit inputstr " " VM_STAT[i] = groupmatchstr2 next ;;Select VM MSG="Select VM Number\n-----------------------------\n" for i 0 count-1 int2str stri i strconcat MSG stri strconcat MSG '.\t' strconcat MSG VM_STAT[i] strconcat MSG '\t' strconcat MSG VM_NAME[i] strconcat MSG '\n' next strconcat MSG '\n\n-1\tCancel\n-----------------------------' :select_RETRY inputbox MSG 'select VM' 1 str2int vmnum inputstr if result = 0 then goto select_RETRY endif if vmnum < 0 then goto EXIT_MACRO endif ; PowerON VM COMMAND= 'vim-cmd vmsvc/power.off ' strconcat COMMAND VM_NO[vmnum] sendln COMMAND wait '~ #' ;;exit :EXIT_MACRO sendln 'exit' end
ESXi5 SSH 有効化&鍵認証(TeraTermの自動ログインマクロ付)
VMware ESXi5をSSHでリモートで操作したい場合の設定手順を記録する。
1.ESXのSSHサービスを有効にする
SSHのサービス有効化は、コンソール画面とvSphereClientの2通りのがあるらしい。
ここではコンソール画面からの変更を記載する。
- "F2"キーを押し、コンソールにログインする
- "Trubleshooting Options"を選択する
- "Enable SSH"を選択し「リターン」キーを押す
これでSSHが有効化される。
ちなみにコンソール画面から直接操作するには、ひとつ上の項目"Enable ESXi shell"を有効化する。ついでに、コンソールシェル(ESXi shell)も有効化する。(必須ではない)
- "Trubleshooting Options" -> "Enable ESXi shell"でシェルを有効かする。
- ESXi shellを有効化したあと"ALT+F1"キーを押すとシェル画面に切り替わる
- 元の画面(System Coustomization)に戻るには、"ALT+F2"キーを押す
2.TeraTermからパスワード認証ログインを確認
TeraTermからSSHのパスワード認証でログイン可能なことを確認する。ここで中が必要なのは、ESXi5では「チャレンジレスポンス認証」を利用しているらしく、TeraTermのSSH認証で「チャレンジレスポンス認証を使う(キーボードインタラクティブ)」を選択する必要があることである。(下図参照)
3.鍵の設定
SSHでとりあえずログインできることを確認したら、ESXiにログインに利用する公開鍵を登録する。
- TeraTermで鍵を作成する(詳細はググルこと)
- ESXiにパスワード認証でログインする
~ # cd /etc/ssh/keys-root /etc/ssh/keys-root #
- TeraTermで作成した公開鍵をエディタで開きファイル内の文字列をauthorized_keysに貼り付ける
/etc/ssh/keys-root # cat > authorized_keys <<公開鍵のテキストカット&ペーストする>> "CTL+D"を押すと入力終了する /etc/ssh/keys-root #
4.TeraTerm鍵認証による自動ログインマクロ
参考までに、SSH鍵認証の場合の自動ログインマクロを公開。
; ========================================================== ; Setting (IP, UserName, KEY file) HOSTADDR = 'xxx.xxx.xxx.xx' ;ESXiのIPアドレス USERNAME = 'root' KEY_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;ログインに使用する秘密鍵 CNF_FILE = 'xxxxxxxxxxxxxxxxxxxx' ;TeraTermの設定ファイル ; ========================================================== ;; Generate login command COMMAND = HOSTADDR strconcat COMMAND ':22 /ssh /2 /auth=publickey /user=' strconcat COMMAND USERNAME strconcat COMMAND ' /keyfile="' strconcat COMMAND KEY_FILE strconcat COMMAND '" /F="' strconcat COMMAND CNF_FILE strconcat COMMAND '"' ;; Login connect COMMAND wait '~ #' end
ダイレクトIOの実装
ファイルシステム上のファイルにキャッシュを解さずread/writeするためには、DirectIOで操作する必要がある。DirectIOを操作するには、
- ファイルをオープンする時に、O_DIRECTオプションを付与する
- read/writeで操作する際のバッファは、512KB(Linux kernel2.6以降)でアライメントする(したがって、バッファ意はposix_memalignで確保する。mallocや配列で確保するとread()/write()時に、EINVALエラーとなる)
- コンパイル時に"_GNU_SOURCE"オプションを付与する。
サンプルコードは以下の通り。
#include <unistd.h> #include <fcntl.h> #define BLOCKSIZE 512 int main(void) { int fdi, fdo; int size = 100 * 1024 * 1024; /* 100MB */ char *buf; /* allocate buffer memory */ posix_memalign( (void **)&buf, BLOCKSIZE, size); /* open file */ fdi = open("file_in", O_RDONLY |O_DIRECT ); fdo = open("file_out",O_WRONLY|O_CREAT|O_TRUNC|O_DIRECT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP ); /* copy "fdi" file to "fdo" file. */ read(fdi, buf, size); write(fdo,buf, size); }
コンパイルコマンド
$ gcc -D_GNU_SOURCE -o directio directio.c
テスト
$ dd if=/dev/zero of=file_in bs=1024 count=102400 102400+0 records in 102400+0 records out 104857600 bytes (105 MB) copied, 1.31783 s, 79.6 MB/s $ ./directio
straceコマンドでシステムとレースしてみても
$ strace ./directio <中略> open("file_in", O_RDONLY|O_DIRECT) = 3 open("file_out", O_WRONLY|O_CREAT|O_TRUNC|O_DIRECT, 0660) = 4 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 104857600) = 104857600 write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 104857600) = 104857600 exit_group(104857600) = ? $