再始動コマンドは再始動システム呼び出しを呼び出しませんか?

再始動コマンドは再始動システム呼び出しを呼び出しませんか?

オペレーティングシステムはDebianです。

私の質問によると:

サーバーを再起動するプロセスを確認する方法はありますか?

システムコールテーブルを変更して再起動システムコールを傍受するカーネルモジュールを作成しました。

デフォルトでは、次のように古い関数ポインタを保存します。

old_reboot = (void *) *(sys_call_table + __NR_reboot);

その後、書き込み可能にし、次の操作をsys_call_table行います。

*(sys_call_table + __NR_reboot) = (unsigned long) my_reboot;

sys_call_tableその後、読み取り専用に切り替えます。私の再起動システムコールは次のとおりです。

asmlinkage long my_reboot(int magic1, int magic2, unsigned int cmd, void __user *arg)
{
    printk(KERN_INFO "Intercepted sys_reboot\n");
    return old_reboot(magic1, magic2, cmd, arg);
}

次に、bashで "reboot"コマンドを実行してコードをテストしました。

ただし、dmesg / syslogにログに記録されるカスタム再起動機能は表示されませんが、モジュールがロードまたはアンロードされたときにログが表示されるため、少なくともその部分は機能します。

openだから私はsyscallの代わりにシステムコールを使って同じことを試しましたが、うまくいきrebootました。したがって、パブリックシステムコールを傍受して呼び出すプロセスのpidを取得し、その情報をdmesg / syslogなどに記録できます。

この方法でオープンシステムコールを傍受できますが、再起動システムコールが傍受できないのはなぜですか?

再起動すると、実際に再起動システムコールが呼び出されますか?それとも私がここで何か間違っているのでしょうか?

編集する:

再起動システムコールを直接呼び出す小さなプログラムを書いていました。 (カーネルモジュールを介して再起動システムコールを傍受することができます)

再起動_テスト.c:

#include <unistd.h>
#include <sys/reboot.h>

int main()
{
        sync();
        reboot(RB_AUTOBOOT);
        return 0;
}

ただし、再起動コマンドを使用して再起動しようとすると、ブロックされた再起動システムコールは記録されません。

追加のテストで以下を実行します。

strace -f reboot

再起動システムコールを表示しませんが、私の小さなCプログラムを使用すると、straceは再起動システムコールを表示します。 (再起動する前の最後の行)

  1. systemdが再起動システムコールを使用しないのはなぜですか?

  2. すべての再起動が再起動システムコールを使用するようにシステムをどのように設定しますか?

答え1

私はこれが完全な答えではないと確信しています。 systemdソースコードを調べてみると、緊急再起動が必要な場合(おそらく "reboot -f"コマンドのために??)、再起動(2)と同じエントリポイントに直接システムコールが行われますが、それをバイパスしているようです。 glibc、glibcライブラリでサポートされていない5番目のパラメータを追加します。通常の再起動が呼び出されると、再起動する前に少なくとも同期してファイルシステムをアンマウントする/usr/lib/systemd/systemd-shutdownを呼び出すようです。それ現れる再起動システムコールを実行しますが、ロジックはかなり複雑です。

関連情報