【问题标题】:Stop unloading the Linux kernel module停止卸载 Linux 内核模块
【发布时间】:2020-12-31 04:50:54
【问题描述】:

我有一个基于平台驱动程序的 Linux 内核模块。
我在那里实现了probe()remove() 方法。

struct platform_driver {
    int (*probe)(struct platform_device *);
    int (*remove)(struct platform_device *);
}

现在当用户执行rmmod <myModule> 然后 remove() 方法正在被调用。在这里,我执行了一些条件检查,并知道用户不应该在这里执行rmmod。在这里,我不想执行任何清理并使这个 rmmod 失败。

我尝试在remove() 中返回-1-EBUSY,但在rmmod <myModule> 之后它仍然被卸载并且不会显示在lsmod 的输出中。

有什么方法可以停止在remove() 方法中卸载我的模块?

【问题讨论】:

    标签: c linux linux-kernel linux-device-driver kernel-module


    【解决方案1】:

    无法取消(或停止)已由rmmod(或通过其他方式)发起的模块卸载。但是可以通过调用try_module_get防止模块卸载:

    // Before your module enters into the state, when its unloading is not desirable.
    
    // Prevent unloading of the module
    if(!try_module_get(THIS_MODULE)) {
      <failed to prevent module unloading>
    }
    
    <....> // This code will be protected from the module's unloading
    
    // Allow the module to be unloaded again
    module_put(THIS_MODULE);
    

    虽然(成功)调用try_module_get 有效,但rmmod 会立即拒绝模块卸载而不执行任何模块的代码。

    我不确定从module_init 函数调用try_module_get 是否会成功,从module_exit 函数调用它肯定会失败。但在所有其他地方,这个调用应该会成功。

    对于module_put 调用,不需要从调用try_module_get 的同一个函数中执行它。你可以不打电话给module_put,但如果可能的话应该避免。

    【讨论】:

    • 半肮脏的黑客。正确的方法是将其定义为内置(在Kconfig中使用bool)并提供.suppress_bind_attribute(或者它是如何调用的?)。
    • @0andriy:这可能是您的首选方法来防止模块卸载永远,但调用try_module_get绝对是防止模块卸载的正确方法一段时间
    • @Tsyvarev 谢谢伙计。这正是我所需要的
    猜你喜欢
    • 2016-01-24
    • 2020-04-17
    • 2014-06-22
    • 2016-10-12
    • 2012-04-11
    • 2013-12-17
    • 2020-04-20
    • 2015-07-20
    • 1970-01-01
    相关资源
    最近更新 更多