これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、MAC OS オンライン エミュレーターなど、複数の無料オンライン ワークステーションのいずれかを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド guestfs-internals です。
プログラム:
NAME
guestfs-internals - libguestfs のアーキテクチャと内部
DESCRIPTION
このマニュアルページは、libguestfs が内部でどのように機能するかを理解したいハッカー向けです。
これは libguestfs が現在どのように機能するかを説明したものであり、いつでも変更される可能性があります。
未来。
アーキテクチャ
内部的には、libguestfs はアプライアンスを実行することによって実装されます (特殊なタイプの小さな
仮想マシン) を使用 qemu(1)。 Qemu はメイン プログラムの子プロセスとして実行されます。
┌────────────────────┐
│メインプログラム│
││
│ │ 子プロセス / アプライアンス
│ │ ┌─────────────┐
│ │ │ ケム │
├────────────────────┤ RPC │ ┌──────────────────┐ │
│ libguestfs ◀╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍▶ guestfsd │ │
│ │ │ ├──────────────────┤ │
└────────────────────┘ │ │ Linuxカーネル │ │
│ └───┬───┘ │
└────────────────│──────────┘
│
│virtio-scsi
┌──────┴──────┐
│ デバイスまたは │
│ディスクイメージ│
└──────────────┘
メイン プログラムにリンクされたライブラリが子プロセスを作成し、それによってアプライアンスが作成されます。
「guestfs_launch」関数で。
アプライアンスの内部には、Linux カーネルとユーザー空間ツールの完全なスタック (
LVM および ext2 プログラム) と「guestfsd」と呼ばれる小さな制御デーモン。 図書館
リモート プロシージャ コール (RPC) を使用して "guestfsd" と通信します。 XNUMX対XNUMXがほとんどです
libguestfs API 呼び出しとデーモンへの RPC 呼び出しとの対応。 最後にディスク
イメージは、デバイス アクセスを変換する qemu プロセスに添付されます。
アプライアンスの Linux カーネルをイメージへのアクセスに追加します。
よくある誤解は、アプライアンスが「仮想マシン」であるというものです。 しかし、
接続しているディスク イメージは、一部の仮想マシン libguestfs でも使用される可能性があります。
これを知らない、または気にしない。 (しかし、libguestfs の qemu プロセスと
仮想マシンは同時にディスク イメージを更新しようとしています。
通常、大規模なディスクの破損が発生します)。
状態 機械
libguestfs はステート マシンを使用して子プロセスをモデル化します。
|
ゲストfs_create / ゲストfs_create_flags
|
|
____V_____
/\
| | 構成 |
\__________/
^ ^ \
| | \ \ guestfs_launch
| | _\__V______
| | / \
| | | | 打ち上げ |
| | \___________/
| | /
| | guestfs_launch
| | /
__|____V
/\
| | 準備完了 |
\_______/
通常の遷移は次のとおりです (1) CONFIG (ハンドルが作成されるが、子がない場合)
プロセス)、(2) LAUNCHING (子プロセスが起動しているとき)、(3) READY は、
アプライアンスが起動すると、子プロセスに対してアクションを発行して実行できます。
ゲストは「guestfs_kill_subprocess」によって強制終了されるか、任意のタイミングで非同期に終了する可能性があります
時間 (たとえば、何らかの内部エラーが原因) であり、それによって状態が遷移して元に戻ります。
設定します。
「guestfs_set_path」などの qemu の構成コマンドは、
構成状態。
API は、CONFIG から LAUNCHING を介して READY に至る XNUMX つの呼び出しを提供します。
「guestfs_launch」は、子プロセスがコマンドを受け入れる準備ができるまで (またはいくつかのプロセスが完了するまで) ブロックします。
失敗またはタイムアウト)。 「guestfs_launch」は内部的に状態を CONFIG から LAUNCHING に移行します
実行中。
「guestfs_mount」などの API アクションは、READY 状態の場合にのみ発行できます。 これらの API
コマンドが実行されるのを待っているブロックを呼び出します。 ノンブロッキングはありません
ハンドルごとに複数のコマンドを同時に発行する方法はありません。
最後に、子プロセスは次のような非同期メッセージをメイン プログラムに送り返します。
カーネル ログ メッセージ。 これらのメッセージを受信するコールバックを登録できます。
内部
アプライアンス BOOT プロセス
このプロセスは進化しており、進化し続けています。 ここの説明はあくまで対応
libguestfs の現在のバージョンに更新され、情報提供のみを目的としています。
以下に含まれる段階をたどるために、libguestfs のデバッグを有効にします (
環境変数 "LIBGUESTFS_DEBUG=1")。
アプライアンスを作成する
「supermin --build」が呼び出されて、カーネル、小さな initrd、およびアプライアンスが作成されます。
アプライアンスは次の場所にキャッシュされます /var/tmp/.guestfs- (または別のディレクトリにある場合
「LIBGUESTFS_CACHEDIR」または「TMPDIR」が設定されています)。
アプライアンスの作成方法とキャッシュ方法の詳細については、
スーパーミン(1)マニュアルページ。
qemu を起動してカーネルを起動する
カーネルを起動するために qemu が呼び出されます。
initrd を実行します。
「supermin --build」は小さな initrd をビルドします。 initrd はアプライアンスではありません。 の
initrd の目的は、アプライアンスが
それ自体をマウントして起動できます。
initrd は cpio アーカイブです。 /var/tmp/.guestfs- /appliance.d/initrd.
initrd が開始されると、カーネル モジュールが有効であることを示すメッセージが表示されます。
次のように読み込まれます。
supermin: ext2 mini initrd 起動中
スーパーミン:取り付け / sys
スーパーミン: 内部 insmod libcrc32c.ko
supermin: 内部 insmod crc32c-intel.ko
アプライアンス デバイスを見つけてマウントする
アプライアンスは、おなじみの ext2 ファイルシステムを含むスパース ファイルです。
(サイズは小さくなりますが) Linux オペレーティング システム。 普通に呼ばれるだろう
/var/tmp/.guestfs- /appliance.d/ルート.
libguestfs によって検査される通常のディスクは、qemu によって公開される最初のデバイスです。
(例: /dev/vda).
qemu に最後に追加されたディスクは、アプライアンス自体です (例: /dev/vdb だけだったら
XNUMX つの通常のディスク)。
したがって、initrd の最後の仕事は、アプライアンス ディスクを見つけてマウントし、切り替えることです。
アプライアンスにルートし、実行します /初期化 アプライアンスから。
これが正常に機能すると、次のようなメッセージが表示されます。
supermin: ルート デバイスとして /sys/block/vdb/dev を選択しました
supermin: ブロック スペシャルとして /dev/root を作成しています 252:16
supermin: 新しいルートをマウントします /ルート
スーパーミン: chroot
/init スクリプトを開始しています...
「Starting /init script ...」は、アプライアンスの init スクリプトが
現在実行中です。
アプライアンスの初期化
アプライアンス自体が初期化されます。 これには、特定のプロセスの開始が含まれます
「udev」のように、おそらくいくつかのデバッグ情報を出力し、最後にデーモンを実行します
(「guestfsd」)。
デーモン
最後に、アプライアンス内でデーモン (「guestfsd」) が実行されます。 実行すると、次のように表示されます。
詳細デーモンが有効
デーモンは、qemu によって公開され、接続されている名前付きの virtio-serial ポートを確認することを期待しています。
図書館の片隅。
デーモンはこのポート (つまりライブラリ) に接続し、XNUMX バイトの
通信プロトコルを開始するメッセージ「GUESTFS_LAUNCH_FLAG」(以下を参照)。
COMMUNICATION プロトコル
このプロトコルを直接使用することに依存しないでください。 このセクションでは、現在の方法について説明します
動作しますが、いつでも変更される可能性があります。
ライブラリとqemu内で実行されているデーモンとの間で通信するために使用されるプロトコル
仮想マシンは、XDR (RFC 1014、RFC 1832、RFC
4506)。
構造体の詳細なフォーマットは src/guestfs_protocol.x (注: このファイルは
自動的に生成されます)。
「FileIn」と「FileOut」を持たない通常の関数の XNUMX つの大まかなケースがあります。
パラメータは、非常に単純な要求/応答メッセージで処理されます。 次に、
同じリクエストを使用する「FileIn」または「FileOut」パラメータを持つ関数
返信メッセージを送信しますが、その後にチャンク エンコーディングを使用して送信されたファイルが続く場合もあります。
ORDINARY 関数 (NO ファイルイン/ファイルアウト パラメータ)
通常の関数の場合、リクエスト メッセージは次のとおりです。
全長 (ヘッダー + 引数、
ただし、長さの単語自体は含まれません)
struct guestfs_message_header (XDR としてエンコード)
struct guestfs_ _args (XDR としてエンコード)
全長フィールドにより、デーモンは固定サイズのバッファを割り当てることができます。
メッセージの残りを丸呑みします。 その結果、全長は次のように制限されます。
「GUESTFS_MESSAGE_MAX」バイト (現在は 4MB)、これはすべてのリクエストの有効サイズを意味します
このサイズ以下に限定されます。
多くの関数は引数を取らないことにも注意してください。
"guestfs_foo_args" は完全に省略されています。
ヘッダーには、受信者が認識する方法であるプロシージャ番号 (「guestfs_proc」) が含まれています。
予想される args 構造のタイプ、またはまったくない。
オプションの引数を取る関数の場合、オプションの引数は
"guestfs_foo_args" 通常の引数と同じように構造化します。 のビットマスク
header は、どのオプションの引数が意味を持つかを示します。 ビットマスクもチェックされます
デーモンが知らないビットセットが含まれているかどうかを確認します(たとえば、オプションの場合
引数はライブラリの新しいバージョンで追加されました)、これにより呼び出しが
拒否されました。
通常の関数の応答メッセージは次のとおりです。
全長 (ヘッダー + ret、
ただし、長さの単語自体は含まれません)
struct guestfs_message_header (XDR としてエンコード)
struct guestfs_ _ret (XDR としてエンコード)
上記の「guestfs_foo_ret" 関数の構造は完全に省略できます。
正式な戻り値を返しません。
上記のように、返信の合計の長さは「GUESTFS_MESSAGE_MAX」に制限されています。
エラーの場合、ヘッダにフラグを立て、返信メッセージを少し
かわった:
全長 (ヘッダー + エラー、
ただし、長さの単語自体は含まれません)
struct guestfs_message_header (XDR としてエンコード)
struct guestfs_message_error (XDR としてエンコード)
「guestfs_message_error」構造には、エラー メッセージが文字列として含まれています。
関数 THAT HAVE ファイルイン パラメーター
「FileIn」パラメータは、ファイルを転送することを示します に ゲスト。 通常のリクエスト
メッセージが送信されます (上記を参照)。 ただし、これには一連のファイル チャンクが続きます。
全長 (ヘッダー + 引数、
ただし、長さの単語自体は含まれません。
チャンクを含まない)
struct guestfs_message_header (XDR としてエンコード)
struct guestfs_ _args (XDR としてエンコード)
FileIn パラメータ #0 のチャンクのシーケンス
FileIn パラメータ #1 などのチャンクのシーケンス
「チャンクのシーケンス」は次のとおりです。
チャンクの長さ (長さワード自体は含まない)
struct guestfs_chunk (XDR としてエンコード)
チャンクの長さ
struct guestfs_chunk (XDR としてエンコード)
...
チャンクの長さ
struct guestfs_chunk (data.data_len == 0 を使用)
最後のチャンクには、「data_len」フィールドがゼロに設定されています。 さらに、フラグが
成功した完了または早期キャンセルのいずれかを示す最終チャンク。
執筆時点では、複数の FileIn パラメータを持つ関数はありません。
ただし、これは(理論的には)各チャンクのシーケンスを送信することでサポートされています
FileIn パラメータを次々と (左から右へ)。
ライブラリ(送信者)の両方 と デーモン (受信側) が転送をキャンセルする場合があります。 図書館
これは、キャンセルを示す特別なフラグが設定されたチャンクを送信することによって行われます。 とき
デーモンはこれを見て、RPC 全体をキャンセルし、 返信を送信し、に戻ります
次のリクエストを読んでいます。
デーモンがキャンセルされることもあります。 これは、特別な単語「GUESTFS_CANCEL_FLAG」を書き込むことによって行われます。
ソケットに。 ライブラリは転送中にこれをリッスンし、それを取得すると、
転送をキャンセルします (キャンセル チャンクを送信します)。 特別な言葉が選ばれるので、
キャンセルが転送の最後に発生した場合でも(図書館が
書き込みを終了し、応答のリッスンを開始した場合)、「偽の」キャンセル フラグが設定されます。
返信メッセージと混同しないでください。
このプロトコルでは、任意のサイズのファイルを転送できます (32 ビット制限なし)。
サイズが事前にわからないファイル (例: パイプやソケットから)。 しかし
チャンクはかなり小さい ("GUESTFS_MAX_CHUNK_SIZE") ため、ライブラリも
デーモンは多くのメモリを保持する必要があります。
関数 THAT HAVE ファイルアウト パラメーター
FileOut パラメータのプロトコルは FileIn パラメータのプロトコルとまったく同じですが、
デーモンとライブラリの役割が逆転。
全長 (ヘッダー + ret、
ただし、長さの単語自体は含まれません。
チャンクを含まない)
struct guestfs_message_header (XDR としてエンコード)
struct guestfs_ _ret (XDR としてエンコード)
FileOut パラメータ #0 のチャンクのシーケンス
FileOut パラメータ #1 などのチャンクのシーケンス
初期 MESSAGE
デーモンが起動すると、最初の単語 ("GUESTFS_LAUNCH_FLAG") が送信されます。
ゲストとデーモンが生きていること。 これは、「guestfs_launch」が待機するものです。
進捗 NOTIFICATION メッセージ
デーモンは、いつでも進捗通知メッセージを送信できます。 これらは区別されます
通常の長さの単語が「GUESTFS_PROGRESS_FLAG」に置き換えられ、その後に固定の
サイズ進行状況メッセージ。
存在する場合、ライブラリはそれらを進行状況コールバック (「GUESTFS_EVENT_PROGRESS」を参照) に変換します。
コールバックが登録されているか、登録されていない場合は破棄します。
デーモンは、送信する進捗メッセージの頻度を自己制限します (
"daemon/proto.c:notify_progress")。 すべての呼び出しで進行状況メッセージが生成されるわけではありません。
FIXED アプライアンス
libguestfs (または libguestfs ツール) が実行されると、パスを検索して
アプライアンス。 パスは libguestfs に組み込まれているか、「LIBGUESTFS_PATH」を使用して設定できます。
環境変数。
通常、supermin アプライアンスはこのパスにあります (「SUPERMIN アプライアンス」を参照)。
スーパーミン(1))。 libguestfs は、「supermin を実行して、これを完全なアプライアンスに再構築します。
- 建てる"。
ただし、より単純な「固定器具」を使用することもできます。 libguestfs はこれを調べて検出します
次のすべてのファイルを含むパス上のディレクトリの場合:
· kernel
· initrd
· ルート
· README.修正済み (注意してください しなければなりません も出席する)
固定アプライアンスが見つかった場合、libguestfs は supermin を完全にスキップして、
仮想マシン (qemu または現在のバックエンドを使用。「BACKEND」を参照) とカーネル、initrd
および固定アプライアンスからのルート ディスク。
したがって、固定アプライアンスは、プラットフォームまたは Linux ディストリビューションが対応していない場合に使用できます。
スーパーミンをサポートします。 スーパーミンをサポートするプラットフォーム上に固定アプライアンスを構築します
libguestfs-make-fixed-appliance(1)、それをコピーし、それを使用して libguestfs を実行します。
onworks.net サービスを使用してオンラインで guestfs-internals を使用する