实验5添加一个文件系统.docx
《实验5添加一个文件系统.docx》由会员分享,可在线阅读,更多相关《实验5添加一个文件系统.docx(16页珍藏版)》请在冰豆网上搜索。
实验5添加一个文件系统
实验5添加一个文件系统
实验目的
文件系统是操作系统中最直观的部分,因为用户可以通过文件直接地和操作系统交互,操作系统也必须为用户提供数据计算、数据存储的功能。
本实验通过添加一个文件系统,进一步理解Linux中的文件系统原理及其实现。
深入理解操作系统文件系统原理
学习理解Linux的VFS文件系统管理技术
学习理解Linux的ext2文件系统实现技术
设计和实现自定义文件系统
实验内容
添加一个类似于ext2的自定义文件系统myext2。
实验主要内容:
添加一个和ext2完全相同的文件系统myext2
修改myext2的magicnumber
修改文件系统操作
添加文件系统创建工具
实验指导
1.问题描述
本实验的内容是要添加一个类似于ext2的自定义文件系统myext2。
myext2文件系统的描述如下:
1、myext2文件系统的物理格式定义与ext2基本一致,除了myext2的magicnumber是0x6666,而ext2的magicnumber是0xEF53。
2、myext2是ext2的定制版本,它只支持原来ext2文件系统的部分操作,以及修改了部分操作。
2.实验步骤
提示:
下面的操作步骤以3.6.6版本的内核为例,2.6.15版本的内核请参照教材,其它版本内核可能会有所区别。
2.1添加一个和ext2完全相同的文件系统myext2
要添加一个与ext2完全相同的文件系统myext2,首先是确定实现ext2文件系统的内核源码是由哪些文件组成。
Linux源代码结构很清楚地告诉我们:
fs/ext2目录下的所有文件是属于ext2文件系统的。
再检查一下这些文件所包含的头文件,可以初步总结出来Linux源代码中属于ext2文件系统的有:
fs/ext2/acl.c
fs/ext2/acl.h
fs/ext2/balloc.c
fs/ext2/bitmap.c
fs/ext2/dir.c
fs/ext2/ext2.h
fs/ext2/file.c
……
include/linux/ext2_fs.h
include/linux/ext2_fs_sb.h
接下来开始添加myext2文件系统的源代码到Linux源代码。
把ext2部分的源代码克隆到myext2去,即复制一份以上所列的ext2源代码文件给myext2用。
按照Linux源代码的组织结构,把myext2文件系统的源代码存放到fs/myext2下,头文件放到include/linux下。
在Linux的shell下,执行如下操作:
#cd~/linux-3.6.6 /*内核源代码目录,假设内核源代码解压在主目录的Linux-3.6.6只目录中*/
#cdfs
#cp–Rext2myext2
#cd../include/linux
#cpext2_fs.hmyext2_fs.h
#cpext2_fs_sb.hmyext2_fs_sb.h//3.6.6没有此文件
#cd~/linux-3.6.6/fs/myext2
#mvext2.hmyext2.h
#cd~/linux-3.6.6
#cdinclude/asm-generic/bitops
#cpext2-atomic.hmyext2-atomic.h
#cpext2-atomic-setbit.hmyext2-atomic-setbit.h //3.6.6修改此文件
这样就完成了克隆文件系统工作的第一步——源代码复制。
对于克隆文件系统来说,这样当然还远远不够,因为文件里面的数据结构名、函数名、以及相关的一些宏等内容还没有根据myext2改掉,连编译都通不过。
下面开始克隆文件系统的第二步:
修改上面添加的文件的内容。
为了简单起见,做了一个最简单的替换:
将原来“EXT2”替换成“MYEXT2”;将原来的“ext2”替换成“myext2”。
对于fs/myext2下面文件中字符串的替换,也可以使用下面的脚本:
#!
/bin/bash
SCRIPT=substitute.sh
forfin*
do
if[$f=$SCRIPT]
then
echo"skip$f"
continue
fi
echo-n"substituteext2tomyext2in$f..."
cat$f|sed's/ext2/myext2/g'>${f}_tmp
mv${f}_tmp$f
echo"done"
echo-n"substituteEXT2toMYEXT2in$f..."
cat$f|sed's/EXT2/MYEXT2/g'>${f}_tmp
mv${f}_tmp$f
echo"done"
done
把这个脚本命名为substitute.sh,放在fs/myext2下面,加上可执行权限,运行之后就可以把当前目录里所有文件里面的“ext2”和“EXT2”都替换成对应的“myext2”和“MYEXT2”。
用编辑器的替换功能,把include/linux/myext2_fs.h,include/linux/myext2_fs_sb.h(3.6.6没有此文件)和include/asm-generic/bitops/myext2-atomic.h,myext2-atomic-setbit.h(3.6.6为此文件)文件中的“ext2”、“EXT2”分别替换成“myext2”、“MYEXT2”
在include/asm-generic/bitops.h文件中添加:
kernel3.6.6 :
其他内核版本可能需要做:
在arch/x86/include/asm/bitops.h文件中添加:
kernel3.6.6 :
其他内核版本可能需要做:
在include/linux/magic.h文件中添加”#defineMYEXT2_SUPER_MAGIC0xEF53”
源代码的修改工作到此结束。
接下来就是第三步工作——编译源代码。
首先要把myext2加到编译选项中去,以便在做makemenuconfig的时候,可以将该选项加上去。
做这项工作只需要修改三个文件:
fs/Kconfig
fs/Makefile
fs/Kconfig中拷贝一份对应的对EXT2文件宏的定义和帮助信息,这样在做makemenuconfig的时候可以查看该选项的有关帮助的内容。
fs/Makefile的修改是告内核编译系统,当myext2对应的宏被选择上的时候,到fs/myext2目录下去编译myext2文件系统。
在kernel3.6.6,在fs/Kconfig文件中增加source“fs/myext2/Kconfig”,并且对“ext2”相关项的地方添加“myext2”项。
在fs/Makefile 文件中添加“obj-$(CONFIG_MYEXT2_FS) +=myext2/”
为了在makemencuconfig中看得更加清楚,修改fs/myext2/Kconfig文件中“Ext2”替换为“MYExt2”,“Second”前加上“MY”
一切都准备就绪了,使用makemenuconfig选择上myext2,如下:
#cd~/linux-3.6.6
#makemenuconfig
选中ext2和myext2文件系统对应的选项,即原来空白用空格键选中为*号:
保存修改,退出。
然后做make等重建内核的工作。
第一部分工作——克隆ext2文件系统已经完成了。
新编译出来的内核重新启动系统。
下面我们来对添加的myext2文件系统进行一下测试:
#pwd
/root
#ddif=/dev/zeroof=myfsbs=1Mcount=1
#/sbin/mkfs.ext2myfs
#cat/proc/filesystems|grepext
ext2
ext3
myext2
ext4
#sudomount–tmyext2–oloop./myfs/mnt
#mount
……
/dev/loop0on/mnttypemyext2(rw)
#sudoumount/mnt
#sudomount–text2–oloop./myfs/mnt
#mount
……
/dev/loop0on/mnttypeext2(rw)
#sudoumount/mnt
2.2修改myext2的magicnumber
在上面做的基础上。
找到myext2的magicnumber,并将其改为0x6666:
2.6.20以后内核版本,这个值在include/linux/magic.h文件中。
2.6.15内核参照教材。
-#defineMYEXT2_SUPER_MAGIC 0xEF53
+#defineMYEXT2_SUPER_MAGIC 0x6666
改动完成之后,再用make重新编译内核。
以新内核重新启动,准备下面的测试。
在我们测试这个部分之前,我们需要写个小程序changeMN.c,来修改我们创建的myfs文件系统的magicnumber。
因为它必须和内核中记录myext2文件系统的magicnumber匹配,myfs文件系统才能被正确地mount。
changeMN.c程序可以在课程网站中下载。
这个程序经过编译后产生的可执行程序名字为changeMN。
下面我们开始测试:
#ddif=/dev/zeroof=myfsbs=1Mcount=1
#/sbin/mkfs.ext2myfs
#./changeMNmyfs
#sudomount–tmyext2–oloop./fs.new/mnt
#mount
/home/user/fs.newon/mnttypemyext2(rw)
#sudoumount/mnt
#sudomount–text2–oloop./fs.new/mnt
mount:
wrongfstype,badoption,badsuperblockon/dev/loop0,…
#
2.3修改文件系统操作
myext2只是一个实验性质的文件系统,我们希望它只要能支持简单的文件操作即可。
因此在完成了myext2的总体框架以后,我们来修改掉myext2支持的一些操作,来加深对操作系统对文件系统的操作的理解。
下面以裁减myext2的mknod操作为例,了解这个过程的实现流程。
Linux将所有的对块设备、字符设备和命名管道的操作,都看成对文件的操作。
mknod操作是用来产生那些块设备、字符设备和命名管道所对应的节点文件。
在ext2文件系统中它的实现函数如下:
fs/ext2/namei.c,line144
144staticintext2_mknod(structinode*dir,structdentry*dentry,intmode,dev_trdev)
145{
146 structinode*inode;
147 interr;
148
149 if(!
new_valid_dev(rdev))
150 return-EINVAL;
151
152 inode=ext2_new_inode(dir,mode);
153 err=PTR_ERR(inode);
154 if(!
IS_ERR(inode)){
155 init_special_inode(inode,inode->i_mode,rdev);
156#ifdefCONFIG_EXT2_FS_XATTR
157 inode->i_op=&ext2_special_inode_operations;
158#endif
159 mark_inode_dirty(inode);
160 err=ext2_add_nondir(dentry,inode);
161 }
162 returnerr;
163}
它定义在结构ext2_dir_inode_operations中:
fs/ext2/namei.c,line400
392structinode_operationsext2_dir_inode_operations={
393 .create =ext2_create,
394 .lookup =ext2_lookup,
395 .link =ext2_link,
396 .unlink =ext2_unlink,
397 .symlink =ext2_symlink,
398 .mkdir =ext2_mkdir,
399 .rmdir =ext2_rmdir,
400 .mknod =ext2_mknod,
401 .rename =ext2_rename,
402#ifdefCONFIG_EXT2_FS_XATTR
403 .setxattr =generic_setxattr,
404 .getxattr =generic_getxattr,
405 .listxattr =ext2_listxattr,
406 .removexattr =generic_removexattr,
407#endif
408 .setattr =ext2_setattr,
409 .permission =ext2_permission,
410};
当然,从ext2克隆过去的myext2的myext2_mknod,以及myext2_dir_inode_operations和上面的程序是一样的。
对于mknod函数,我们在myext2中作如下修改:
fs/myext2/namei.c
staticintmyext2_mknod(structinode*dir,structdentry*dentry,intmode,intrdev)
{
printk(KERN_ERR“haha,mknodisnotsupportedbymyext2!
you’vebeencheated!
\n”);
return–EPERM;
}
添加的程序中:
第一行打印信息,说明mknod操作不被支持。
第二行将错误号为EPERM的结果返回给shell,即告诉shell,在myext2文件系统中,maknod不被支持。
修改完毕,然后重新编译内核。
以新生成的内核重新启动计算机,我们在shell下执行如下测试程序:
#sudomount–tmyext2–oloop./fs.new/mnt
#cd/mnt
#sudomknodmyfifop
mknod:
`myfifo':
Operationnotpermitted
#
第一行命令:
将fs.newmount到/mnt目录下。
第二行命令:
进入/mnt目录,也就是进入fs.new这个myext2文件系统。
第三行命令:
执行创建一个名为myfifo的命名管道的命令。
第四、五行是执行结果:
第四行是我们添加的myext2_mknod函数的printk的结果;第五行是返回错误号EPERM结果给shell,shell捕捉到这个错误后打出的出错信息。
需要注意的是,如果你是在图形界面下使用虚拟控制台,printk打印出来的信息不一定能在你的终端上显示出来,但是可以通过命令dmesg|tail来观察。
可见,我们的裁减工作取得了预期的效果。
2.4.添加文件系统创建工具
文件系统的创建对于一个文件系统来说是首要的。
因为,如果不存在一个文件系统,所有对它的操作都是空操作,也是无用的操作。
其实,前面的第一小节《添加一个和ext2完全相同的文件系统myext2》和第二小节《修改myext2的magicnumber》在测试实验结果的时候,已经陆陆续续地讲到了如何创建myext2文件系统。
下面工作的主要目的就是将这些内容总结一下,制作出一个更快捷方便的myext2文件系统的创建工具:
mkfs.myext2(名称上与mkfs.ext2保持一致)。
首先需要确定的是该程序的输入和输出。
为了灵活和方便起见,我们的输入为一个文件,这个文件的大小,就是myext2文件系统的大小。
输出就是带了myext2文件系统的文件。
我们在主目录下编辑如下的程序:
~/mkfs.myext2
#!
/bin/bash
/sbin/losetup-d/dev/loop2
/sbin/losetup/dev/loop2$1
/sbin/mkfs.ext2/dev/loop2
ddif=/dev/loop2of=./tmpfsbs=1kcount=2
./changeMN./tmpfs
ddif=./fs.newof=/dev/loop2
/sbin/losetup-d/dev/loop2
rm-f./tmpfs
第一行表明是shell程序。
第三行如果有程序用了/dev/loop2了,就将它释放。
第四行用losetup将第一个参数装到/dev/loop2上
第五行用mkfs.ext2格式化/dev/loop2。
也就是用ext2文件系统格式格式化我们的文件系统。
第六行将文件系统的头2K字节的内容取出来。
第七行调用程序changeMN将magicnumber改成0x6666
第八行再将2K字节的内容写回去。
第九行把我们的文件系统从loop2中卸下来。
第十行将临时文件删除。
编辑完了之后,做如下测试:
#ddif=/dev/zeroof=myfsbs=1Mcount=1
#./mkfs.myext2myfs (或sudobashmkfs.myext2myfs)
#sudomount–tmyext2–oloop./fs.new/mnt
#mount
/dev/loop0on/mntmyext2(rw)
#
至此,文件系统部分的实验已经全部完成了。
通过本实验,你对Linux整个文件系统的运作流程,如何添加一个文件系统,以及如何修改Linux对文件系统的操作,有了比较深的了解。
在本实验的基础上,你完全可以发挥自己的创造性,构造出自己的文件系统,然后将它添加到Linux中。
撰写实验报告的要求
1.按照实验报告模板格式撰写;
2.整个实验过程的截图;
3.程序的修改部分,运行结果的截图;
4.实验过程中遇到的问题及解决方法等。
5.心得体会