用"RAID 0.0999" 写保护 Linux 硬盘分区

算机科学家 David Wheeler 有一句名言:"计算机科学中的任何问题,都可以通过加上一层逻辑层来解决。"这个原则在 Linux

Kernel 中的许多场合被广泛的应用。其中最为大家所熟知的应用,恐怕要算是在文件系统的层次上。Linux Kernel

为了能支持多种不同的文件系统,采取的解决办法,就是在 Kernel 和文件系统之间添加一个逻辑层,也即所谓的 VFS(Virtual

Filesystem Switch)。VFS 把来自 Kernel

的请求转发给各个不同的文件系统驱动进行处理。这些文件系统驱动,有的实现的是传统的硬盘分区上的文件系统,有的实现的是基于网络的分布式文件系统,甚至

还有一些更加富有想象力和实验性质的文件系统驱动。Linux 上丰富多彩的文件系统的实现都得益于 VFS 这一逻辑层的加入。

Linux Kernel 中软件 RAID 技术的实现,同样体现出了计算机科学家 David Wheeler 的这一原则。不过,我们首先要看到的是这一原则在 Linux Kernel 中的 Block 设备的实现上的应用。

Linux

Kernel 支持多种 Block 设备,比如基于 IDE 总线或者是 SCSI 总线的硬盘、光盘驱动器和磁带机,又比如在一个普通文件上实现的

Loopback Block 设备,或者是基于 TCP 的网络 Block 设备,甚至是基于内存的 RAM-DISK。这个对多种 Block

设备的支持,其实就是 Block 设备层这一逻辑层在发挥作用。每一个具体的 Block 设备的驱动,都要向 Kernel 中的 Block

设备层注册,并提供一组入口。这以后 Kernel 就可以通过这一组入口,访问这个 Block 设备。Block

设备驱动的这一组入口的确切定义如下。

struct block_device_operations {

int (*open) (struct inode *, struct file *);

int (*release) (struct inode *, struct file *);

int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);

int (*check_media_change) (kdev_t);

int (*revalidate) (kdev_t);

struct module *owner;

};

一个 Block

设备驱动向负责的逻辑层注册了这一组入口之后,系统用一个号码,也即所谓的 Major Number,标识这一 Block

设备。用户空间的程序通过访问文件系统上的 /dev 目录获知某一 Block 设备和 Major Number 之间的对应关系。Kernel

则通过这一 Major Number 区分不同的设备,把来自用户空间的请求转发给相应的设备驱动。在这里,Major Number 实际上担任了

Block 设备层这一逻辑层的转换开关这一角色。相应的,我们知道,在文件系统的 VFS 逻辑层上担任转换开关角色的则是文件系统的 Mount

路径。

前面简单地讲述了 Linux Kernel 中的 Block 设备。而 RAID

技术,我们知道,是利用多个 Block 设备来模拟一个单个的 Block

设备,并且,在这个模拟的过程中,提供一定程度的数据冗余,以保护用户数据不会因为某个单一的 Block

设备的故障而完全损毁。根据技术规范的细节的不同,RAID 又被分为几个级别。RAID 0 并不提供任何程度的数据冗余,而只是把单个硬盘

Block 设备的负载平均分担到参加 RAID 0 的所有硬盘 Block 设备上,这在一定程度上增加了对硬盘上的用户数据进行访问的速度。而

RAID 4,5 都提供了相当程度的数据冗余,可以保护用户数据不会因为某个单个硬盘 Block 设备的故障而损毁。关于 Linux

Kernel 中软件 RAID 技术的原理的介绍,读者可以参考 IBM developerWorks 上面的 Daniel Robbins

的相关文章,以及 Linux Documentation Project 上面的 The Software-RAID

HOWTO。相关链接,请参见文后所列参考文献。

本文所关心的,是这些不同级别的软件 RAID 技术在 Linux

Kernel 中的具体实现办法。在这里,我们看到 Linux Kernel 向上面说到的 Block 设备层这一逻辑层,注册了一个特殊的

Block 设备,称之为 Multi-Disk Block Device(md)。可以说,这个 Block

设备形成了又一个逻辑层,来支持不同级别的 RAID 技术,甚至还可以支持其它的多硬盘 Block 设备,比如

LVM,逻辑卷控制等。我们看到,为了支持不同级别的 RAID 技术而引进的这又一个逻辑层,并没有妨碍其它 Block

设备。其它的那些不牵扯到多硬盘技术的 Block 设备,并不需要通过 md 这一个逻辑层,这保证了这些设备的效率不会受到影响。

自然而然,我们就要问道,在 md 这一逻辑层上担任转换开关角色的是谁呢?并且,我们还要问,各种级别的软件 RAID,是如何向这一逻辑层进行注册的呢?

先回答第一个问题,在 md 这一逻辑层上担任转换开关角色的是 Block 设备的 Minor Number。用户程序从文件系统上的 /dev

目录下找到一个设备名,随之就找到了一个 Major Number 以及一个 Minor Number。而 Linux Kernel 就根据

Major Number 找到 Block 设备的驱动,在我们这里,就是 md 多硬盘设备。然后 md 逻辑层根据 Minor Number

再往下找。找什么呢?找不同的 Personality,这是 Linux Kernel 中的 md 逻辑层所使用的术语,它的具体定义如下。

struct mdk_personality_s {

char *name;

int (*make_request) (mddev_t *mddev, int rw, struct buffer_head * bh);

int (*run) (mddev_t *mddev);

int (*stop) (mddev_t *mddev);

int (*status) (char *page, mddev_t *mddev);

int (*error_handler) (mddev_t *mddev, kdev_t dev);

int (*diskop) (mddev_t *mddev, mdp_disk_t **descriptor, int state);

int (*stop_resync) (mddev_t *mddev);

int (*restart_resync) (mddev_t *mddev);

int (*sync_request) (mddev_t *mddev, unsigned long block_nr);

};

从上面的简略介绍,我们看到,

Linux Kernel 引入 Block 设备层这一逻辑层,来支持多种不同的 Block 设备驱动的实现。然后,在 Block

设备层下面又引入 md 设备层这一较小的逻辑层,来实现对多个级别的 RAID 技术的支持。在这两个层次中担任转换开关角色的,分别是 Block

设备的 Major Number 和 Minor Number。

接下来,我们再从另一个角度,来看一看 Linux Kernel 中的软件 RAID 技术的实现。在这里,我们要关注的是在 Linux Kernel 中,用户数据的移动路径。

比如说要读一个用户文件。首先,用户程序传递给 Kernel 一个路径名,比如 /etc/passwd。然后,Kernel 中的 VFS 逻辑层根据当时它记录下来的文件系统的 Mount 的情况,找到相应的文件系统驱动,就指挥它去找用户程序所请求的文件。

于我们这里所要关心的基于硬盘的传统的文件系统来说,硬盘呈现在它面前的样子就是连续的一长串的

Blocks。所以,对于硬盘文件系统来说,它所要做的,就是要根据用户程序所请求的文件的路径名,找到相对应的若干个

Blocks,这样以后,它的任务就算完成了,接下来的事情,就是属于硬盘 Block

设备驱动的了。对于传统的硬盘文件系统来说,它们通过在硬盘分区的开头的固定位置上,维持一些索引信息,也即所谓的 Meta

Information,来完成这一任务。对于 Linux 上比较流行的 Ext2/3 文件系统的硬盘布局的详细介绍,请参见作者在 IBM

developerWorks 上的另一篇文章。相关链接,请参见文后的参考文献。

在文件系统之后,接下来登场的就是硬盘

Block 设备的驱动了。它所要完成的任务,就是在文件系统请求某一个 Block

中的数据的时候,把这个数据从硬盘上读出来。我们看到,文件系统根据 VFS 中记录的 Mount 信息,找到相关的设备,比如

/dev/hda1,或者是某一个硬盘 RAID 设备,告诉它,我要读你上面的第几个 Block 的数据。对于一个普通的硬盘 Block

设备驱动来说,它把这个 Block 号数翻译成硬盘上的硬件地址,比如 IDE 设备的 C/H/S 地址或者是 LBA

地址,然后,把来自文件系统的请求转发给 IDE 驱动就行了。

而对于我们所关心的 RAID

技术来说,它要在把来自文件系统的请求转发给底层的驱动(比如 IDE 驱动)之前,多做一些翻译工作。这个翻译工作,把呈现在文件系统面前的一长串的

Blocks 这一形象,翻译到多个硬盘 Block 设备上面。这个翻译工作,定义了 Linux Kernel 中的软件 RAID

技术的实现。对于各个不同级别的 RAID 来说,它们各个采用了不同的翻译技术。简单的 RAID 0,就是把这一长串的

Blocks,均匀的分配到各个硬盘 Block 设备上面。而 RAID 4 和 5 采用的翻译手段,就更为复杂一点。

从上面的分析,我们看到,在整个过程中只有少量的索引数据在各层驱动之间传递,只是到了最后,才出现用户数据的转移,这对整个系统的性能是非常有利的。

层保护膜,其实就是一个清空了的硬盘分区。每一个受到保护的硬盘分区,对应有一个保护膜。在每次系统重新启动之后,这层保护膜都会被清空。另外,在内存

中,每个保护膜都维持了一个关于被保护的硬盘分区的 Blocks 的 Bitmap,每一个 Block 对应于 Bitmap 中的一个

Bit。每次启动以后,Bitmap 都被全部置为 0。

保护膜的驱动是在 RAID 0

的基础上稍加改动得来的,我们称之为 RAID 0.0999。它向 Linux Kernel 中的 md 逻辑层注册了自己的

Personality,并负责维护自己的一份 Bitmap。当保护膜的驱动从文件系统接收到一个关于某个 Block

的读请求的时候,它查阅自己维护的 Bitmap。如果相应的位为 0,它就从被保护的硬盘分区上读取该 Block。如果相应的位为

1,它就从保护膜上读取相应的 Block。当保护膜的驱动从文件系统接收到一个关于某个 Block 的写请求的时候,它把自己维护的 Bitmap

的相应位置位为 1,并把数据写入保护膜上相应的 Block 中。这样就有效的实现了对相应的硬盘分区的写保护。

RAID

0.0999 有些什么用处呢?一个用处是对于在光盘上"实地"运行的 Linux 操作系统,由于光盘不可避免的是只读的,那么 RAID

0.0999 加上基于内存的 Block 设备 RAM-DISK 的支持,就可以提供一个可读可写的文件系统,使得在光盘上"实地"运行

Linux

成为一件简单的事情。另外一个用处是对于操作系统的安全方面,由于保证了一份完整的用户数据是只读的,而每次系统重新启动之后,保护膜又都被擦除干净,受

系统崩溃和黑客入侵的影响,在一定程度上就被减小了。当然,RAID 0.0999 最主要的用处是作为本文作者的一个小玩具而已。:-)

linux磁盘写保护怎么修改_用\RAID 0.0999\ 写保护 Linux 硬盘分区-me09-ChinaUnix博客...相关推荐

  1. CSDN 博客 修改文章搜索为 bing 搜索,且只搜索自己的博客的方法

    CSDN 博客 修改文章搜索为 bing 搜索,且只搜索自己的博客的方法 csdn 自带的博客搜索调用的百度的代码,但是搜索效果很不理想,而且默认为全站搜索. 在我们的博客里面进行搜索的大多数人,都应 ...

  2. linux服务器只读,linux文件只读怎么修改_网站服务器运行维护

    ubuntu如何查看系统版本信息_网站服务器运行维护 ubuntu查看系统版本信息的方法是:可以通过执行[cat /proc/version]命令来查看,该命令会输出linux内核版本号和ubuntu ...

  3. Linux磁盘格式化(mkfs、mkfs.xfs、mkfs.ext4)、Linux文件系统的校验(xfs_repair、fsck_ext4)

    一.mkfs命令 磁盘分区完毕后自然就是要进行文件系统的格式化 格式化其实就是创建文件系统.命令就是===>mkfs(make fileststem),这个命令只是个综合命令.它会调用正确的文件 ...

  4. linux hosts文件如何修改_3 种方法教你在 Linux 中修改打开文件数量限制

    当文件被打开访问时,操作系统临时分配一个名为文件句柄的数字.主内存的一个特殊区域是为文件句柄预留的,这个区域的大小决定了一次可以打开多少个文件. Linux上的进程受到许多限制,这些限制也阻碍它们正确 ...

  5. linux 磁盘管理3板斧,df、du、fdisk:Linux磁盘管理三板斧的使用心得

    磁盘是Linux系统中一项非常重要的资源,如何对其进行有效的管理直接关系到整个系统的性能问题.对Linux磁盘管理稍微有一些学习和经验的朋友们应该都知道df.du和fdisk这三个常用命令:df用于检 ...

  6. linux 磁盘管理3板斧,df、du、fdisk:Linux磁盘管理三板斧的使用心得 | 旺旺知识库...

    1.df df命令可以获取硬盘被占用了多少空间,目前还剩下多少空间等信息,它也可以显示所有文件系统对i节点和磁盘块的使用情况. df命令各个选项的含义如下: -a:显示所有文件系统的磁盘使用情况,包括 ...

  7. 用python搭建个人博客过程_技术分享|利用Python Django一步步搭建个人博客(四)...

    您好,欢迎来到本期"利用Python Django一步步搭建个人博客"系列的第四部分.在上一篇教程中,我们学习了如何编写URL并将其映射到页面.在我们继续之前,我们需要做的一件事是 ...

  8. 个人博客管理系统_教程 | 一文搭建你的第一个免费专属博客

    点击蓝字关注我 本文将详细介绍利用Github+hexo搭建一个免费.简洁的个人博客,从获取域名到菜单栏.搜索框.评论分享这些必要功能的配置,给自己一个个性化的内容分享平台. -▼- 我建了一个QQ学 ...

  9. 自定义依赖注解无效_关于Apt注解实践与总结【包含20篇博客】

    超详细!安卓巴士开发者大会嘉宾及主题介绍 目录介绍 00.注解系列博客汇总 01.什么是apt 02.annotationProcessor和apt区别 03.项目目录结构 04.该案例作用 05.使 ...

最新文章

  1. 定义自己的rm command
  2. 解决mysql建立的数据库名字不能带大写字母
  3. XML Schema用法
  4. Android JNI入门第四篇——jni头文件分析
  5. 九种食物帮你赶走忧郁
  6. Scott Hanselman's 推荐的的实用工具集合(2011版)
  7. GridSearchCV.grid_scores_和mean_validation_score报错
  8. input自适应_【正点原子FPGA连载】第十一章基于OV5640的自适应二值化实验-领航者ZYNQ之HLS 开发指南...
  9. ajax中dom,在(jQuery)ajax请求中获取当前脚本DOM对象
  10. 大数据时代数据库-云HBase架构生态实践
  11. (算法)最长递增子序列
  12. 第一节:从面向对象思想(oo)开发、接口、抽象类以及二者比较
  13. HDU-3460 Ancient Printer 字典树
  14. suse linux 11 HBA信息,HP BL660 GEN8 SUSE 11 查询HBA信息 驱动版本 固件版本 设备名称
  15. android 常用依赖库
  16. thinkphp+vue傻瓜式PS级可视化自助建站系统平台版
  17. 知识付费,下半场怎么走(附大会PPT下载)
  18. 05如何处理类别特征?
  19. 编译make px4_fmu-v2_default upload时,报错ERROR Board can accept larger flash images (2080768 bytes)
  20. KeilC51_v960版201905((含汉字补丁,STC15说明书,stc-isp-15xx-v6.86S).7z

热门文章

  1. 她二本科毕业,拿到阿里年薪40万offer!经验都记录在这几个公众号日记中
  2. 网络——VRRP、浮动路由(备份路由)
  3. plt.plot()函数解析(最清晰的解释)
  4. Python--Opencv:errorFindContours supports only CV_8UC1 images when mode = CV_RETR_FLOODFILL otherw
  5. 阿里云高级技术专家白常明:边缘云的技术挑战和应用创新
  6. 微擎支付返回商户单号_微信小程序支付流程
  7. Windows版Docker桌面
  8. 电路b-3—06刘晏辰
  9. Windows Server 2012 VDI 部署的前提条件
  10. 读书笔记2区块链与大数据