ランダムに再起動されるように見えるkvm仮想マシンがあります。再起動、シャットダウン、エラー、コアダンプ、パニックなどの内容はsyslogに表示されません。ホストのlibvirtdログにエラーがなく、qemuログにもエラーがなく、ホストにもエラーがありません。
いくつかのランダムなプロセスは、仮想マシン内で再起動システムコールを呼び出すようです。それが私が考えることができるすべてです...
この問題の原因は何であるか、どうすればわかりますか?オペレーティングシステムはDebianです。
答え1
Cコードに触れても問題ない場合は、再起動/終了呼び出しを傍受してくださいprintk()
。
この回答良いスタートになるかもしれません。変更されたハンドラを呼び出す人が誰であるかを確認するには、次の点を確認してください。これ。
テストコード
上記のプロンプトを開発し、次のコードを思いつきました。
私のホームシステム(Ubuntu 22.04-LTS)では、カーネルモジュールをコンパイルしてインストールして動作するようです。一部記号:例__do_sys_swapon
:
Dec 15 22:38:51 mintaka kernel: [82534.879652] __do_sys_swapon called by PID 5381 (swapon)
しかし、いくつかの/proc/kallsyms
kprobeが必要な場合や、かなりの試行錯誤が必要なようです。プロンプトから呼び出すと__do_sys_reboot
記録されないようです。reboot
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/kprobes.h>
MODULE_LICENSE("GPL");
/**
* Pre handler
* @return int unless you're a kprobe geek
*/
static noinline int handler(struct kprobe *p, struct pt_regs *regs) {
struct task_struct *task = current;
printk(KERN_EMERG "%s called by PID %d (%s)\n", p->symbol_name, (int)task->pid, task->comm);
return 0;
}
// Verify that the symbol name is present in /proc/kallsyms
static struct kprobe kp = {
.symbol_name = "__do_sys_reboot",
.pre_handler = handler
};
/**
* Module initialization
*
* @returns int
*/
int init_module(void) {
int ret;
printk(KERN_INFO "loading whistlebooter\n");
// register_kprobe ultimately returns e.g. arch_copy_kprobe() which succeeds with 0
ret = register_kprobe(&kp);
if (ret < 0) {
if (-2 == ret) {
printk(KERN_INFO "register_kprobe did not find the requested symbol\n");
} else {
printk(KERN_INFO "register_kprobe failed with code %d\n", ret);
}
} else {
printk(KERN_INFO "kprobe registered at addr=%p for '%s'\n", kp.addr, kp.symbol_name);
}
return 0;
}
/**
* @returns void
*/
void cleanup_module(void) {
printk(KERN_INFO "unloading whistlebooter\n");
unregister_kprobe(&kp);
}
ファイルの生成
# vim: tabstop=4 sw=4 noexpandtab
obj-m += mymodule.o
PWD := $(CURDIR)
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
コンパイルするには " make
"を実行します。