web-dev-qa-db-ja.com

カーネルとBusyBoxを備えた最小限のLinux:/ etc / inittabは無視され、/ initのみが実行されます

カーネル(デフォルトオプションでコンパイルされた)とBusyBox(デフォルトオプション+静的でコンパイルされた、_/sbin/init_を含むすべてのアプレットが存在する)のみを含む、小さくて機能的なライブLinux CDを作成できました。 initrdを作成して_/dev_、_/proc_、および_/sys_を入力する問題はありませんでした。また、_/init_シェルスクリプトでもまったく問題ありませんでした。

最近、BusyBoxが_/etc/inittab_構成を(少なくともある程度)サポートしていることを読んだので、次のいずれかを実行したいと思います。

  • _/init_シェルスクリプトを忘れて、_/etc/inittab_構成に完全に依存します。
  • _/init_シェルスクリプトと_/etc/inittab_構成の両方を使用します。

今、実際の問題-ディストリビューションの起動時に_/etc/inittab_が完全に無視されているようです。症状は次のとおりです。

  • _/init_を削除して_/etc/inittab_のみを残すと、カーネルパニックが発生します。私の仮定は、カーネルが_/sbin/init_をまったく実行しない、または_/sbin/init_が_/etc/inittab_を検出(または読み取り)しないことです。
  • BusyBoxは_/etc/inittab_がなくても問題なく動作するはずだと読みました。だから、私は_/init_と_/etc/inittab_の両方を削除し、何を推測した-カーネルパニックが再び発生した。
  • 私はシェルから_/sbin/init_を実行しようとしましたが、_exec /sbin/init_、_setsid /sbin/init_および_exec setsid /sbin/init_を含むいくつかの推測の後、カーネルパニックが発生しました。ファイルシステムに/ etc/inittabが存在する場合と存在しない場合の両方。

これが私の_/init_シェルスクリプトの内容です。

_#!/bin/sh
dmesg -n 1
mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys
setsid cttyhack /bin/sh
_

この時点では、設定が実際に機能していることを知る方法がある限り、_/etc/inittab_の内容はどうでもいいです。私はいくつかの_/etc/inittab_構成を試しましたが、すべて私が見つけた情報に基づいています here

最低限、私の/ etc/inittabには次の1行だけが含まれています。

_::sysinit:/bin/sh
_

繰り返しますが、カーネルパニックに陥り、_/etc/inittab_が無視されたようです。

私の小さなライブディストリビューションがBusyBoxの_/etc/inittab_で正常に動作するように強制する方法の提案は高く評価されます!

更新:

  • 明確にするために-私はしないでください現在の_/init_シェルスクリプトで_/etc/inittab_がある場合とない場合の両方でカーネルパニックの問題があります。すべて正常に動作し、私の_/bin/ash_コンソールは問題なく動作し、予期しない問題は発生しません。唯一の問題は、上で説明したように、_/etc/inittab_が完全に無視されることです。
  • 3つの異なるライブLinuxディストリビューション、Slax、Finnix、SysResCDを調べました。それらのすべてに_/init_があり、_/etc/inittab_を持つものはありません。さらに このWiki記事 は、_/sbin/init_がまったく呼び出されないという私の疑いを締めくくります。
12
Ivan Davidov

わかりました。私は多くの広範な調査を行い、何が問題だったのかを発見しました。 1つずつ始めましょう。

  • initramfsブートスキームを使用する場合、カーネルが呼び出す最初のプロセスは/initスクリプトです。カーネルが/sbin/initを直接実行することは決してありません。
  • /initにはプロセス識別子1が割り当てられています。これは非常に重要です!
  • ここでの問題は、/sbin/initPID 1としてのみ開始できるということですが、/initはPID 1としてすでに実行されています。
  • 解決策は、exec /sbin/initの中にいる間にコマンドライン/initを実行することです。このようにして、新しいプロセス(/sbin/init)はその親(PID 1の/init)からPIDを継承するので、これで完了です。

私の初期構成で発生した問題(質問を参照)は、私の/initスクリプトが最後に行うことは、新しいPIDが割り当てられた新しい/bin/shプロセスを生成することでした。この時点から、インタラクティブコンソールから/sbin/initを直接実行することはできません。コマンドラインexec /sbin/initを実行する場合でも、シェルにすでに割り当てられている同じPIDを割り当てることが最善の方法です。 PIDはPID 1ではありません。

要するに、コマンドラインexec /sbin/init/initから直接実行すれば、それだけです。

11
Ivan Davidov