OSカーネル用 アスペクト指向システム KLASY

Slides:



Advertisements
Similar presentations
Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
Advertisements

アルゴリズムとデータ構造 第2回 線形リスト(復習).
ファイルキャッシュを考慮したディスク監視のオフロード
セキュリティ機構のオフロードを考慮した仮想マシンへの動的メモリ割当
クラウドにおける ネストした仮想化を用いた 安全な帯域外リモート管理
JTAG ICEによる 組み込みLinuxデバッグ
通信処理のカーネル内競合を 検出するアスペクト指向 カーネルレベルロガー
仮想マシンの並列処理性能に対するCPU割り当ての影響の評価
柳澤 佳里* 光来 健一* 千葉 滋* *東京工業大学 情報理工学研究科 数理・計算科学専攻
ファイルシステムキャッシュを 考慮した仮想マシン監視機構
侵入検知システム(IDS) 停止 IDS サーバへの不正アクセスが増加している
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
AspectScope によるアスペクトとクラスのつながりの視覚化
ネストした仮想化を用いた VMの安全な帯域外リモート管理
同期的にアドバイスを活性化できる分散動的アスペクト指向システム
ユーザ毎にカスタマイズ可能な Web アプリケーション用のフレームワークの実装
アスペクト指向プログラミングを用いたIDSオフロード
効率的なJava Dynamic AOPシステムを実現する Just-in-Time weaver
アスペクト指向プログラミングと Dependency Injection の融合
遠隔ポイントカット - 分散アスペクト指向プログラミング のための言語機構
柳澤 佳里 (学籍番号: 03M37311) 指導教官: 千葉 滋 東京工業大学 情報理工学研究科 数理・計算科学専攻
型付きアセンブリ言語を用いた安全なカーネル拡張
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
仮想マシン間にまたがる プロセススケジューリング
Xenによる ゲストOSの監視に基づく パケットフィルタリング
分散IDSの実行環境の分離 による安全性の向上
他のプロセスに あたえる影響が少ない 実行時ミラーリングシステム
理学部 情報科学科 指導教官 千葉 滋 助教授 学籍番号 03_03686 内河 綾
統合開発環境のための アスペクト指向システム
VM専用仮想メモリとの連携による VMマイグレーションの高速化
ユーザ毎にカスタマイズ可能な Webアプリケーションの 効率の良い実装方法
実行時情報に基づく OSカーネルのコンフィグ最小化
仮想メモリを用いた VMマイグレーションの高速化
仮想計算機を用いたサーバ統合に おける高速なリブートリカバリ
横断的関心事に対応したオブジェクト指向言語GluonJとその織り込み関係の可視化ツール
クラウドにおけるIntel SGXを用いた VMの安全な監視機構
豊富な情報を基にした pointcut を記述できるアスペクト指向言語
Recoveryアドバイスをもつ アスペクト指向システム
XenLASY: XenのI/O処理を 追跡するための アスペクト指向プロファイラ
カーネル用アスペクト指向システム KLAS
クラウドにおけるVM内コンテナを用いた 自動障害復旧システムの開発
未使用メモリに着目した 複数ホストにまたがる 仮想マシンの高速化
アスペクト指向言語のための 独立性の高いパッケージシステム
アプリケーション依存の先読みが可能なO/Rマッピングツール
仮想マシンを用いた 既存IDSのオフロード
Intel SGXを用いた仮想マシンの 安全な監視機構
アスペクト指向言語のための 独立性の高いパッケージシステム
C言語を用いたマシン非依存な JITコンパイラ作成フレームワーク
pointcut に関して高い記述力を持つ アスペクト指向言語 Josh
ウェブアプリケーションサーバの Degradation Schemeの 制御に向けて
仮想環境を用いた 侵入検知システムの安全な構成法
アルゴリズムとプログラミング (Algorithms and Programming)
Josh : バイトコードレベルでのJava用 Aspect Weaver
統合開発環境によって表現された 言語機構によるコードのモジュール化
IDE を活用した言語機構に頼らないコード再利用のためのモジュール化
同期処理のモジュール化を 可能にする アスペクト指向言語
仮想マシンに対する 高いサービス可用性を実現する パケットフィルタリング
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
アルゴリズムとデータ構造1 2009年6月15日
第5回 プログラミングⅡ 第5回
状況に応じて適切な 例外処理が行なえる アスペクト指向分散環境実験の 支援ツール
開発者との対話を活かした 横断的構造の表現
強制パススルー機構を用いた VMの安全な帯域外リモート管理
プログラムの一時停止時に 将来の実行情報を提供するデバッガ
アルゴリズムとデータ構造 2010年6月17日
プログラミング演習II 2003年12月10日(第7回) 木村巌.
GluonJ を用いたビジネスロジックからのデータベースアクセスの分離
Josh : バイトコードレベルでのJava用 Aspect Weaver
Presentation transcript:

OSカーネル用 アスペクト指向システム KLASY 柳澤 佳里 光来 健一 千葉 滋 石川 零 東京工業大学 情報理工学研究科 数理・計算科学専攻

プロファイリングコードを 実行中のカーネルに挿入するには? 目的: 任意の点でタイムスタンプをロギング 性能チューニングのため 例) パケット到達からカーネルバッファにいたるまでの経過時間を調査 既存の方法 カーネルプロファイラを利用? 決まった点でしかログを取得できない カーネルソースコードを変更し、再コンパイル? 面倒くさくて、ミスしがち

プロファイリングコード ソースコードの指定した行にて 変数の値とタイムスタンプを 記録 再コンパイル、再起動 Linux カーネルソースコード (fs/attr.c) int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } 無しでプロファイリングしたい プロファイリングコード 挿入 struct timeval tv; do_gettimeofday(&tv) ; print_tv(tv); printk(“%ld”, inode->i_uid);

Kerninst [Tamches et al. ’99] 実行時コード操作ツール アセンブリレベルの抽象度 開発者は次のアドレスの調査が必要: コードを挿入する機械語のアドレス 記録する変数が格納された場所のアドレス サンプルコード: Kerninst を用いてログを取得 kmgr.findModule(“kernel”, &kmod); kmod.findFuction(“inode_change_ok”, &ifunc); ifunc.findEntryPoint(&entries); kmgr.findModule(“profiler”, &kmod); kmod.findFunction(“print_log”, &pf); hook = kapi_call_expr(pf.getEntryAddr(), args); kmgr.insertSnippet(hook, entries[0]); void print_log() { … __asm__ (“movl %%ebp, %0” : “=r”(ebp)); uid = ((struct inode*)ebp[11])->i_uid; /* ebp[11] is inode */

KLASY Kernel-level Aspect-Oriented System ソースコードレベルの抽象度 KLASYにより開発者は: アスペクト指向プログラミング(AOP)を用いた利点 KLASYにより開発者は: ソースコードレベルの視点で任意の実行点を選択可能 ポイントカット C言語でプロファイリングコードを記述可能 アドバイス 選択された点で実行されるコード 実行点で利用可能な変数にアクセス可能

ロギング AOPのキラーアプリケーション なぜ新しいAOPシステムが必要か? ロギング(or プロファイリング)コードは独立した別個のモジュールに分離 なぜ新しいAOPシステムが必要か? 既存のC言語用動的AOPシステムの問題 実行時コンテキストの取得が不可能: 変数アクセスができない 構造体メンバーアクセスのポイントカットが不可能 たとえば、inode->i_uidがアップデートされたときのタイムスタンプを調査不可能 プロファイリングに不可欠

KLASYのアスペクト例 pointcut advice アスペクト Linux カーネルコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice ポイントカットされるのはどこ?、inodeがNULLのときはどうする? 利用者は手動で選択するのか (河野先生)

KLASYのアスペクト例 アドバイスボディで使う ヘッダーファイルを指定 pointcut advice アスペクト Linux カーネルコード (fs/attr.c) アドバイスボディで使う ヘッダーファイルを指定 <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice

KLASYのアスペクト例 pointcut advice アスペクト Linux カーネルコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice

access(inode.i_uid) ポイントカットで inode->i_uid を選択 KLASYのアスペクト例 アスペクト Linux カーネルコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice access(inode.i_uid) ポイントカットで inode->i_uid を選択

within_function() により選択範囲を inode_change_ok関数内に制限。 KLASYのアスペクト例 アスペクト Linux カーネルコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice within_function() により選択範囲を inode_change_ok関数内に制限。

inode_valueに選択した構造体(inode)への参照を設定 KLASYのアスペクト例 アスペクト Linux カーネルコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice 実行時コンテキスト取得: inode_valueに選択した構造体(inode)への参照を設定

タイムスタンプを取得し、i_uidの値とともに保存 KLASYのアスペクト例 アスペクト Linux カーネルコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } pointcut 選択 advice タイムスタンプを取得し、i_uidの値とともに保存

KLASYの対応する 主なポイントカット、アドバイス access 本研究で提案 構造体メンバーアクセスを選択 execution 関数実行を選択 アドバイス before 選択された点の前でプロファイリングコードを実行 after 選択された点の後でプロファイリングコードを実行

実行時コンテキストの取得に使う ポイントカット ポイントカット記述子 target accessポイントカットで選択したメンバーを持つ構造体変数への参照を取得 local_var accessポイントカットで選択した箇所でローカル変数への参照を取得 argument executionポイントカットで選択した関数の引数への 参照を取得 ローカル変数がないときにローカル変数を取ろうとすると…(京都大学: 八木先生)

KLASYの実装 Source-based binary-level dynamic weaving GNU C コンパイラ(gcc)を拡張 生成した拡張シンボル情報を用い: 構造体メンバーへのアクセスをポイントカット可能 実行時コンテキスト(変数のアドレス)を取得可能 Kerninstをバックエンドに利用 動的織り込みを実現 C言語でアドバイスを記述 ソースレベルの視点で記述可能 XML風のタグで囲まれている

処理の流れ OSカーネル OS アスペクト ソースコード KLASY アスペクトコンパイラー gcc 拡張シンボル情報 ポイントカット insmod ウィーバー OSカーネル コンパイル済み アドバイス OS カーネル 本体 フック

処理の流れ OSカーネル OS アスペクト ソースコード KLASY アスペクトコンパイラー gcc 拡張シンボル情報 ポイントカット insmod ウィーバー OSカーネル コンパイル済み アドバイス OS カーネル 本体 フック

KLASY gcc KLASY gccは次のシンボル情報を収集: 構造体メンバーアクセスのあるファイル名、行番号 コンパイラーのパーザーを拡張 従来のgccではこの情報は消失 各行の先頭命令のあるアドレス コンパイル時にデバッグオプション(-g)を利用 構造体メンバーアクセスのポイントカットにこれも必要

処理の流れ OSカーネル OS アスペクト ソースコード KLASY アスペクトコンパイラー gcc 拡張シンボル情報 ポイントカット insmod ウィーバー OSカーネル コンパイル済み アドバイス OS カーネル 本体 フック

ウィーバー Kerninstを用いポイントカットで選択した点に フック挿入 フック フック挿入アドレスの取得方法 アドバイスボディを呼び出すためのコード フック挿入アドレスの取得方法 構造体メンバーアクセス ファイル名、行番号 行の先頭アドレス 拡張シンボル情報を利用

アンウィーブ KLASYでは実行時にOSカーネルから織り込んだアスペクトを削除可能 プロファイリングには重要な機能 一般に利用者は様々なアスペクトを試用 観察効果を避けるため不要なアスペクトの削除は必要 利用者はわかりやすい名前でアスペクトを指定可能 Kerninstを用いてウィーバーの入れたフックを消去

アスペクト例における 実行時コンテキストの取得 Linux カーネルソースコード (fs/attr.c) <aspect> <import>linux/time.h</import> <advice><pointcut> access(inode.i_uid) AND within_function(inode_change_ok) AND target(inode_value) </pointcut> <before> struct inode *i = inode_value; struct timeval tv; do_gettimeofday(&tv); print(i->i_uid, tv.tv_sec, tv.tv_usec); </before> </advice> </aspect> int inode_change_ok(…) { … if ((ia_valid & ATTR_UID) && … attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) && } ポイントカット selected ローカル変数を取得し、 アドバイス内で利用 アドバイス

実行時コンテキストの取得の実装 ウィーバーとKLASY gccの連携により実現 ウィーバーにて参照を得るトランポリンコードを作成 ローカル変数から目的の構造体への参照に至る方法を保存 例) inode.length → &inode inode_ptr->length → inode_ptr ウィーバーにて参照を得るトランポリンコードを作成 ローカル変数の格納場所をデバッグ情報をから取得 Gccの作成したデバッグ情報を利用 保存された方法で構造体への参照を得、アドバイスに渡す

ケーススタディ: ネットワークI/Oサブシステムの調査 目的 過負荷におけるLinuxネットワークサブシステムの 性能ボトルネックを発見 Sk_buff構造体へのアクセスをトレース Sk_buff構造体はLinuxにてネットワークサブシステムでバッファとして利用 Sk_buffのトレースによりネットワークサブシステムの挙動を把握 KLASYの実行時コンテキスト取得機能を利用 個々のパケットを識別するため 無関係なパケットを無視するため

トレースに用いたアスペクト ワイルドカード <aspect><advice> <pointcut> access(sk_buff.%) AND target(arg0) </pointcut> <before> struct sk_buff *skb = arg0; unsigned long timestamp; if (skb->protocol != ETH_P_ARP) { STORE_DATA($pc$); STORE_DATA(skb); DO_RDTSC(timestamp); STORE_DATA(timestamp); } </before> </advice></aspect> skb->protocol プログラムカウンタ、 sk_buff出現位置、 タイムスタンプを保存 ARPパケットを無視

トレース結果 プロセススケジューリングがボトルネックと判明 Skb_copy_datagram_iovec関数はプロセスの発行した システムコールから呼び出されるので 差が大きい __kfree_skb ip_rcv skb_copy_datagram_iovec netif_receive_skb tcp_v4_rcv tcp_rcv_established 1000_clean_rx_irq ip_rcv_finish tcp_v4_do_rcv

ケーススタディでの accessポイントカットの有用性 Sk_buff構造体の全メンバーをaccessポイントカット Linuxネットワークサブシステムの挙動を把握 もし、executionポイントカットでやるとしたら… ネットワークサブシステムについての詳細な知識が必要 過不足なく関数を選択するため 本ケーススタディでは76箇所(関数21個)にてログ取得 最適化禁止が必須 Inline関数への対応が必要 現実と大幅に異なる OSカーネルは通常最適化オプションつきでコンパイルされる 例) Linux カーネルは-Os最適化オプションでコンパイル 本ケーススタディではstatic inline関数6箇所にてログ取得

KLASYの有用性 (まとめ) 構造体メンバーアクセスをポイントカット 実行時コンテキストの取得 構造体メンバーアクセスは大規模Cプログラムで使用 関数間でのデータの受け渡しに利用 ポリモルフィズムの実現に利用 メンバーに関数へのポインターを保持 例) 仮想ファイルシステム(VFS)、仮想デバイスなど 例) OS kernel (FreeBSD, Linux), X window System 実行時コンテキストの取得 実行時コンテキストがあると… 詳細な調査が可能 必要なデータのみのログ出力が可能 ログ保存領域を節約

既存の C言語用動的アスペクト指向システム TOSKANA [Engel ’05], DAC++ [Almajali ’05], TinyC2 [Zhang ’03],and Arachne [Douence ’05] 実行時コード操作 関数実行、呼び出しのみポイントカット可能 シンボル情報を不使用 TOSKANA-VM [Engel ’05] 仮想機械上でOSカーネルを実行 実際のハードウェア上のプロファイリングは不可能

実験 UnixBenchによるベンチマーク 実験環境 Linux: 通常gccでコンパイルしたカーネル -fomit-frame-pointerオプションあり KLASY: KLASY gccでコンパイルしたカーネル 実行時コンテキスト取得のため、-fomit-frame-pointerオプション 使用不可 デバッグ情報の示す変数位置と実位置がずれるため ほぼ-fomit-frame-pointer禁止によるオーバーヘッドを測定 実験環境 CPU: AthlonXP™ 1800+, Mem: 1GB, Linux 2.6.10 Kerninst 2.1.1, gcc 3.3.3, Intel Ethernet PRO/1000

実験結果 現実的なオーバーヘッドであることを確認 オーバーヘッド: 0 ~ 12 % 平均: 4.4 % dhry2reg: drystone syscall: システムコール pipe: pipeシステムコール execl: execlシステムコール context: コンテキストスイッチ

関連研究 C言語用静的アスペクト指向システム カーネルプロファイラー 実行中のカーネルを変更可能 プロファイリングコードの変更に再起動が必要 例) AspectC [Coady ’01], AspectC++ [Spinczyk ’02] カーネルプロファイラー LKST、 DTrace [Cantrill ’04]、SystemTAP [Prasad ’05]、 LTT [Yaghmour ’00] カーネル内で発生したイベントについてログを取得するツール プロファイラー開発者の設定した箇所でのみプロファイリング可能

まとめ KLASY (Kernel-level Aspect-oriented System)を提案 Source-based binary-level dynamic weaving 構造体メンバーへのアクセスをポイントカットで選択可能 実行時コンテキストを取得可能 ネットワークI/OサブシステムのプロファイリングにKLASYが有用であると確認 性能ボトルネックがプロセススケジューリングにあると判明 図4のグラフの分析を教えてほしい 図4の分析にて、ブレークポイント、ジャンプの挿入数、割合は調べていないのか 必ずしも通るpathとは限らないからやってなかった(^^;やろうと思えば$pc$を記録し、Kerninstのログと比較すればできそう。