Linux:直接访问C中的硬盘

时间:2009-06-10 19:56:50

标签: c memory filesystems hard-drive linux-device-driver

如何获取对HD的原始访问权限并知道该位置是否已使用或是否为可用空间? 只是一个例子,我可以通过在磁盘设备上打开和读取来获得直接访问,目标是知道是否使用了例如10.000字节。

7 个答案:

答案 0 :(得分:17)

您可以open阻止设备(例如,/dev/sda)并手动读取扇区。但是,这不会告诉你它是否是空的直接。空或不是在文件系统抽象级别定义的东西。文件系统数据结构存储了这种数据,您应该从原始块(不使用任何文件系统提供的函数)深入了解特定文件系统。

答案 1 :(得分:9)

在所有情况下,您不希望直接通过/ dev / sd *或/ dev / hd *访问块设备。正如其他人所说,你必须了解原始的底层文件系统,这将非常困难。

如果您正在编写一个想要将磁盘上的字节视为大线性地址空间的应用程序,那么请查看mmap()系统调用。您可以在磁盘上创建一个大的空文件,然后使用mmap()将其映射到您的进程空间。从那里,您可以使用常规内存操作来读取和写入底层大文件。请注意,写入是缓冲的,因此保证一致性可能很棘手。

这种方法的优点是即使底层文件是碎片化的,您的访问模式也可以将其视为字节的线性集合。

答案 2 :(得分:9)

谨慎行事......

不要忘记您必须配合现有的驱动程序堆栈自己的线程安全规定和内部缓存。系统中的许多线程可以(并且将)一直写入磁盘。要擦除一个免费的部门,你必须知道它是免费的,并且在你拥有它的同时保持自由。如果您擦除了文件系统已经决定使用的扇区,但是没有将该决定的证据刷新到磁盘上,那么您将无法知道它正在使用中。这可能会导致数据丢失,从而导致愤怒的用户。

如果您可以保证文件系统当前未安装,那么您至少可以打开/dev/sda(可能您想要的特定文件系统!)并解析磁盘上的数据结构,可以执行您需要执行的任何操作。实际上,这是实现fsckmkfs等实用程序的方式。

剩下的大问题是您必须与可能遇到的每个文件系统的每个版本保持同步。至少你有可用于文件系统本身的源代码供参考,但将它从内核移出并进入用户模式应用程序并不容易。

我的建议是使用文件系统本身来获得所需的保证。打开大文件并用您的擦除图案填充它们。将磁盘填满容量。请注意,如果这可能会对假定某些磁盘空间可用的任何正在运行的守护程序产生严重影响,那么可能仍需要在具有大多数守护程序且已杀死的守护程序上完成。如果你的目标是安全擦除,你仍然需要担心在传递之间实际将写入的块刷新到磁盘,因为普通文件系统中的所有内容都将尝试优化单个块的多次写入。

答案 3 :(得分:6)

如果您想要擦除文件系统中的所有可用空间,可以使用一个充满零的大文件填充文件系统,将其同步到磁盘,然后将其删除。这可能无法完全解决所有问题,特别是如果您正在处理日志文件系统等,但它会完成大部分工作。如果您想要擦除磁盘以便更好地压缩图像,这可能就是您需要做的全部工作。如果您出于安全原因想要清理磁盘......欢迎来到内核开发的世界,请深入了解并记住要穿阻燃的东西。

有一个名为zerofree的实用程序可以将ext文件系统中的空闲块清零,并且用于VM映像。请记住,这不是您应该对已安装的文件系统执行的操作。该页面还有一些旧的内核补丁,可能是在实时文件系统上执行此操作的一个有趣的起点。

答案 4 :(得分:5)

OH MY。

您的代码必须:

  1. 走分区表以查看属于哪个分区。
  2. 确定它是什么类型的文件系统。
  3. 对于您支持的每个文件系统,提供此类例程以查看该字节是否正在使用中
  4. 检查文件系统是否已挂载
  5. 如果是,请遍历内核记录以查明是否还有未写入磁盘的内容。
  6. 哦,如果您使用的是EXT4或REISER,您无法知道之前的答案,所以您可能会放弃。

如果我是你,我会重新考虑你要做的事情。

编辑:看到他对他实际上要做的事情的评论,

  • 接受分区而不是原始磁盘
  • 需要卸下
  • 致电e3fsck汇总期刊
  • 遍历每个inode,找到最后一个块并擦除该块中的任何可用空间(filesize应该告诉数据在块中的结束位置)
  • 遍历分配位图,找到任何未分配的块并擦除它们
  • 现在是棘手的部分,擦掉杂志。
  • 祝你好运
  • 哦,阅读文件系统文档

答案 5 :(得分:2)

非常依赖很多因素,例如

  • filesystem type
  • 操作系统类型
  • 中型

解决方案:

答案 6 :(得分:0)

您可以使用与文件系统和/或磁盘工具相同的功能来检查某个位置是否空闲。