質問
私はに取り組んでいます init
Linux用のC ++のinitramfsの場合。このスクリプトは、暗号化されたドライブをw/ luksのDMクリプトのロックを解除するために使用され、LVMドライブを使用できるように設定します。
私はの機能を再現する必要がないので cryptsetup
と gpg
システムコールを使用して実行可能ファイルを呼び出しています。システムコールを使用するためにGPGを呼び出すと、システムが完全に育てられている場合は正常に動作します(既にそれを持ち上げるのに正常に動作するbashスクリプトベースのinitramfsがあり、grubを使用してコマンドラインを編集して、古いinitramfs)。しかし、initramfsでは、呼ばれるようには決して動作しません。のようなコマンドでさえ system("echo BLAH");
不合格。
だから、誰かが何かを持っていますか?
編集:それで、私は自分のエラーの原因となっているものを見つけました。手がかりがありません どうして それはエラーを引き起こしますが、私はそれを見つけました。
ホットプラグを許可するために、私は書く必要がありました /sbin/mdev
に /proc/sys/kernel/hotplug
...しかし、私は最終的にパラメーターの周りを切り替えました(関数で自分自身を書いた)ので、私は書いていました /proc/sys/kernel/hotplug
に /sbin/mdev
.
なぜそれが問題を引き起こすのかについての手がかりはありませんが、それはそうしました。
解決
Amardeepは正しいです、 system()
POSIXタイプのシステムでは、コマンドを実行します /bin/sh
.
ボーンのシェルを通してあなたが話しているこれらのプログラムを呼び出す正当な必要性が実際にあるとは思わない。正当な理由は、環境変数のデフォルトセットを持つために必要な場合ですが、それ以降 /etc/profile
また、おそらくブーツプロセスの早い段階で利用できない可能性がありますが、ここでどのように当てはまるのかわかりません。
代わりに、標準を使用します fork()/exec()
パターン:
int system_alternative(const char* pgm, char *const argv[])
{
pid_t pid = fork();
if (pid > 0) {
// We're the parent, so wait for child to finish
int status;
waitpid(pid, &status, 0);
return status;
}
else if (pid == 0) {
// We're the child, so run the specified program. Our exit status will
// be that of the child program unless the execv() syscall fails.
return execv(pgm, argv);
}
else {
// Something horrible happened, like system out of memory
return -1;
}
}
呼び出されたプロセスからstdoutを読むか、そのstdinにデータを送信する必要がある場合は、標準のハンドルリダイレクトを介して実行する必要があります pipe()
また dup2()
そこで。
この種のことについては、優れたUNIXプログラミングブックで学ぶことができます。私はお勧め UNIX環境での高度なプログラミング W.リチャードスティーブンス。 Ragoが共著した第2版は、StevensがLinuxやOS Xのような初版を書いてから登場したプラットフォームをカバーするための素材を追加しますが、このような基本は元版以来変更されていません。
他のヒント
System()関数はシェルでコマンドを実行すると思います。シェル実行可能ファイルは取り付けられており、スタートアッププロセスの早い段階で利用可能ですか? fork()とexecve()を使用して調べることをお勧めします。
編集:暗号化ツールもマウントされたボリュームにあることを確認してください。
initramfsには何がありますか?次のことができます。
int main() {
return system("echo hello world");
}
そして、このようなinitscriptでそれをstraceします:
strace -o myprog.log myprog
システムが起動したら、ログを見てください