서버를 다시 시작하는 프로세스를 확인하는 방법이 있습니까?

서버를 다시 시작하는 프로세스를 확인하는 방법이 있습니까?

무작위로 재부팅되는 것처럼 보이는 kvm 가상 머신이 있습니다. 재부팅, 종료, 오류, 코어 덤프, 패닉 등에 대한 내용이 syslog에 표시되지 않습니다. 호스트의 libvirtd 로그에 오류가 없고, qemu 로그에도 오류가 없으며, 호스트에도 오류가 없습니다.

일부 임의의 프로세스가 가상 머신 내부에서 다시 시작 시스템 호출을 호출하는 것 같습니다. 그게 내가 생각할 수 있는 전부야...

이 문제의 원인이 무엇인지 어떻게 알 수 있나요? 운영체제는 데비안입니다.

답변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"를 실행하면 됩니다.

관련 정보