从内核恐慌中调用用户空间应用程序

问题描述 投票:0回答:1

我需要一种方法来通知我的系统上的 U-Boot 发生了内核恐慌,我已经配置了所有相关的应用程序,例如

fw_setenv
,并且它在手动启动时可以正常工作。现在我需要自动化这个过程,以防发生内核恐慌,它应该更改 U-Boot 变量,为此我尝试使用
call_usermodehelper()
函数但不起作用,调用此函数的结果是 0 但没有正在启动。我尝试过在恐慌时使用
touch
call_usermodehelper()
来创建文件,但也不起作用,文件没有被创建。 我已经隔离了与此相关的代码,并创建了一个内核模块来探测其行为,在这个模块上,我只需调用
call_usermodehelper()
并且工作正常,但是当我将代码移至恐慌函数时,什么也没有发生。我读到一些关于
call_usermodehelper()
函数无法在 IRQ 处理程序中工作的内容,所以我也尝试使用工作人员,但没有成功。这段代码是我最后一次尝试,任何对此的帮助将非常感激。

struct work_cont {
        struct work_struct real_work;
        char cmd[250];
};

static struct work_cont execwq;

void cmdexec_worker(struct work_struct *work)
{
    static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
    char *argv[] = { "/bin/touch", "/a.txt", NULL };
        // struct work_cont *c_ptr = container_of(work, struct work_cont, real_work);
        set_current_state(TASK_INTERRUPTIBLE);
    printk(KERN_ERR "Executing worker\n");
        call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);

        return;
}

void panic(const char *fmt, ...)
{
    schedule_work(&execwq.real_work);
...
}

static int __init setup_crash_kexec_post_notifiers(char *s)
{
        INIT_WORK(&execwq.real_work, cmdexec_worker);
...
}

无论有或没有worker,都可以手动加载内核模块。没有程序或脚本可以通过恐慌函数工作,显示

printk()
,因此代码正在执行,但外部应用程序没有被调用。

linux-kernel kernel u-boot panic
1个回答
0
投票

从内核恐慌中调用用户空间应用程序

您似乎没有意识到内核恐慌不是一种正常情况,您可以访问 rootfs 来加载和执行用户空间应用程序(可能需要与共享对象链接)以执行更多 I/O。即使内核已经发生恐慌并基本上声明系统不稳定,您仍期望许多系统功能完好无损且可用。
如果恐慌与 rootfs 有关怎么办?那么如何才能访问程序的根文件系统呢?这会导致无限恐慌循环吗?在我看来,你需要重新考虑这个过于复杂的方案,这也会使 U-Boot 保存的环境面临风险。

我需要一种方法来通知我的系统上的 U-Boot 发生了内核恐慌

所以你实际上有一个 XY 问题。

您提出的 Y 解决方案让 U-Boot 只需测试其环境变量之一,但要求内核执行启动用户程序的不可能任务:(1) 读取文件(或原始扇区),(2) 修改内容并执行 CRC32 计算,然后 (3) 将该内容写回。所有这些步骤都将在系统因内核恐慌而不稳定时执行。请注意,如果启动步骤 3 但未能成功完成,则 U-Boot 将必须使用备份副本(如果可用)或恢复到环境的默认版本。

一种可能且更简单(从内核角度来看)的解决方案将利用现有的内核功能。系统可以构建为在发生紧急情况时转储内存(也称为“核心”)。 Ubuntu 文档 将此功能描述为:

当发生内核恐慌时,内核依靠 kexec 机制在系统启动时分配的预先保留的内存部分中快速重新启动内核的新实例(参见 xxx)。这允许现有内存区域保持不变,以便安全地将其内容复制到存储中。

大部分新开发现在将在 U-Boot 端进行,它必须确定是否已写入(新的)内核转储。


所以我需要一种方法来确保当系统崩溃时能够自行恢复......

然后确保将 CONFIG_PANIC_TIMEOUT 更改为默认值 0 以外的值。

© www.soinside.com 2019 - 2024. All rights reserved.