gpt4 book ai didi

c - 如何在 Linux 中不安全地删除 block 设备驱动程序

转载 作者:太空狗 更新时间:2023-10-29 12:25:29 25 4
gpt4 key购买 nike

我正在为 Linux 编写 block 设备驱动程序。支持不安全移除(如 USB 拔出)至关重要。换句话说,我希望能够在不造成内存泄漏/崩溃的情况下关闭 block 设备,即使应用程序持有打开的文件或在我的设备上执行 IO 或者如果它已安装文件系统。当然,不安全的删除可能会损坏存储在设备上的数据,但这是客户愿意接受的。

这是我完成的基本步骤:

  1. 在不安全删除时, block 设备会产生一个僵尸,它将自动使所有新的 IO 请求、ioctls 等失败。僵尸替换 make_request 函数并更改其他函数指针,因此内核将不需要原始 block 设备。
  2. block 设备等待所有正在运行的 IO(并使用我的内部资源)完成
  3. 它执行 del_gendisk();然而,这并没有真正释放内核资源,因为它们仍在使用中。
  4. 阻止设备自行释放。
  5. 僵尸跟踪 block 设备上 opens() 和 close() 的数量,当最后一次 close() 发生时,它会自动 free() 自己
    1. 结果 - 我没有泄露 block 设备、请求队列、生成磁盘等。

然而,这是一个非常困难的机制,需要大量代码并且极易出现竞争条件。我仍然在为极端情况、IO 的 per_cpu 计数和偶尔的崩溃而苦苦挣扎

我的问题:内核中是否有一种机制已经做到了这一点?我搜索了 block 设备驱动程序、ram 磁盘和 USB 驱动程序的手册、文献和无数源代码示例,但找不到解决方案。我敢肯定,我不是第一个遇到这个问题的人。

已编辑:我从 Dave S 的下面的答案中了解到热插拔机制,但它对我没有帮助。我需要一个关于如何安全关闭驱动程序而不是如何通知内核驱动程序已关闭的解决方案。

一个问题的例子:blk_queue_make_request() 注册了一个函数,我的 block 设备通过该函数提供 IO。在该函数中,我增加了 per_cpu 计数器以了解每个 cpu 正在运行的 IO 数量。然而,存在调用函数的竞争条件但计数器尚未增加,所以我的设备认为有 0 个 IO,释放资源然后 IO 出现并使系统崩溃。据我所知,Hotplug 不会帮助我解决这个问题

最佳答案

大约十年前,我在一个软件驱动程序项目中使用热插拔来安全地添加/删除连接到嵌入式 Linux 驱动机顶盒的外部 USB 磁盘驱动器。

对于您的项目,您还需要编写热插拔。热插拔是内核用来在发生某些重要(通常与硬件相关)事件时通知用户模式软件的程序。例如,刚插入或拔出 USB 设备时。

从 Linux 2.6 内核开始,热插拔已与驱动模型核心集成,因此任何总线或类都可以在添加或删除设备时报告热插拔事件。

在内核树中,/usr/src/linux/Documentation/usb/hotplug.txt 包含有关支持热插拔的 USB 设备驱动程序 API 的基本信息。另请参阅此链接和 GOOGLE 以获取示例和文档。

http://linux-hotplug.sourceforge.net/

可以在此处找到另一个非常有用的文档,该文档讨论了 block 设备的热插拔:

https://www.kernel.org/doc/pending/hotplug.txt

本文档还提供了一个很好的示例来说明热插拔事件处理:

下表列出了您应该注意的主要变量:

热插拔事件变量:

每个热插拔事件至少应该提供以下变量:

ACTION
The current hotplug action: "add" to add the device, "remove" to remove it.
The 2.6.22 kernel can also generate "change", "online", "offline", and
"move" actions.

DEVPATH
Path under /sys at which this device's sysfs directory can be found.

SUBSYSTEM
If this is "block", it's a block device. Anything other subsystem is
either a char device or does not have an associated device node.

还为某些设备提供了以下变量:

MAJOR and MINOR
If these are present, a device node can be created in /dev for this device.
Some devices (such as network cards) don't generate a /dev node.

DRIVER
If present, a suggested driver (module) for handling this device. No
relation to whether or not a driver is currently handling the device.

INTERFACE and IFINDEX
When SUBSYSTEM=net, these variables indicate the name of the interface
and a unique integer for the interface. (Note that "INTERFACE=eth0" could
be paired with "IFINDEX=2" because eth0 isn't guaranteed to come before lo
and the count doesn't start at 0.)

FIRMWARE
The system is requesting firmware for the device.

关于c - 如何在 Linux 中不安全地删除 block 设备驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42480410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com