文件系统ls实现与内核编码_第1页
文件系统ls实现与内核编码_第2页
文件系统ls实现与内核编码_第3页
文件系统ls实现与内核编码_第4页
文件系统ls实现与内核编码_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、文件系统ls实现与内核编码一. 设计目的操作系统是控制和管理计算机硬件和软件资源的虚拟机,其中的文件系统是对软件和设备进行管理的系统,文件系统是操作系统中非常重要的一个模块,它的实现占用了操作系统源码的最大编码量,其好坏也直接影响着用户对操作系统的感受程度。通过对操作系统课程设计的实践,进一步加深对文件系统的认识和理解,并在此基础上培养学生的工程应用能力。实验分别从用户态和内核态两个层实践文件系统的部分功能。二. 设计内容1.使用Linux编程实现用户态下带参数的ls命令功能ls命令支持以下功能:支持 -l 参数;输出结果按字典排序;列出“.”文件,支持-a参数,在没有-a时候不显示隐藏文件;

2、显示记录总数;支持对给定的目录进行操作,如 ls /tmp;正确显示文件特殊属性suid、sgid和sticky;支持-u参数,它会显示出文件的最后访问时间;当关掉一个文件的读权限,就不能打开这个文件来读。如果从一个终端登录,打开一个文件,保持文件的打开状态,然后从另外的终端登录,去掉文件的读权限,看会出现什么情况。编写一个程序,先用open()打开一个文件,用read()读一些内容,调用sleep()等待20s以后,再读一些内容,从另外的终端,再等待的20s内去掉文件的读权限,这样会有什么结果?2. 编写内核模块显示目录或文件的信息。调试Linux操作系统原理与应用第8章文件系统P215 的

3、例子给内核模块传入参数path,其中path为绝对路径当path为目录时,显示目录对应的dentrey结构中的相关信息(可打印的信息);当path为文件时,显示文件对应的indoe结构中的相关信息(可打印的信息);当路径错误时,有错误提示信息。三概要设计1功能模块图;实现ls命令功能 实现 ls运行命令修改文件权限chmod文件特殊权限eg:chmod7363 2.cls /指定目录ls -uls -als -l ls文件名按字典排序 在一终端运行1.c ,读出文件中的内容,在另一终端修改文件权限,再显示结果,然后在修改文件权限,再显示结果。 Ls -laLs -luLs -uaLs -lua

4、Ls 指定文件/指定目录 -l Ls 指定文件/指定目录 -uLs 指定文件/指定目录 -aLs 指定文件/指定目录 -laLs 指定文件/指定目录 -luLs 指定文件/指定目录 -uaLs 指定文件/指定目录 -lua编写内核模块编写内核模块,打印super_block结构中一些域的值。(课本上的例子) 运行 加锁遍历系统中的 超级块打印文件系统所在的主设备号和次设备号打印文件系统名遍历打印每个超级块中的所有索引节点号 解锁索引节点数量给内核模块传入参数path,其中path为绝对路径 运行 path=文件 错误路径 path=目录显示错误信息显示文件信息 显示目录信息2 各个模块详细的功

5、能描述。实现ls命令功能ls -l:每个文件单独占一行,显示文件的详细属性信息ls -a:显示包括隐藏文件在内的所有文件ls -u:显示出文件的最后访问时间ls:显示的文件名按字典顺序排序ls /指定目录:显示当前目录下的内容ls -lu:每个文件单独占一行,显示文件的详细属性信息,并且显示出文件的最后访问时间ls -la:显示包括隐藏文件在内的所有文件的详细属性信息ls -lua:显示包括隐藏文件在内的所有文件的详细属性信息,并且显示出文件的最后访问时间chmod 权限 文件名:修改文件的权限,并且显示出此文件是否受suid,sgid和sticky的控制chmod 权限(3位) 在一终端运行

6、程序,读取文件信息,在另一终端修改文件权限,看结果。编写内核模块编写内核模块,打印super_block结构中一些域的值。(课本上的例子)遍历系统中的超级块:list_head结构类型的字段名称为s_list。list_entry宏通过指向list_head节点的地址来得到外部超级块的首地址。获取系统中个超级块的地址,获得某个子进程的地址,打印文件系统所在的主设备号和次设备号和文件系统名。遍历打印每个超级块中的所有索引节点号,打印索引结点。给内核模块传入参数path,其中path为绝对路径path=路径时,显示如下信息:目录项标志哈希表短目录名目录项长度目录项名目录项计数器的引用path=文件

7、时,显示如下信息:文件索引节点的数量文件类型和权限用户ID用户组ID指定文件系统的读写访问标志文件大小索引节点的状态硬链接数引用记数文件的块数版本号以位为单位的块大小错误信息显示:Open file failed四详细设计1功能函数的调用关系图ls命令错误处理函数,打印出错误所在行的行数和错误信息void my_error(const char *error_string, int line);获取文件属性void show_file_attribute(struct stat buf,char *file_name,int flag_u)输出文件的文件名,若命令中没有-l选项,则输出文件时要

8、保证上下对齐void show_file_columns(char *file_name)根据命令行参数(存放在flag中)和完整路径名(存放在pathname中)显示目标文件void show_file(int flag,char *pathname)为显示某个目录下的文件做准备,path:要显示的目录void show_file_dir(int flag_param,char *path)main函数 show_fileshow_file_dir show_file_attribute show_file_columns my_error编写内核模块编写内核模块,打印super_block

9、结构中一些域的值。(课本上的例子) my_init module_init(my_init) my_exit module_exit(my_exit)给内核模块传入参数path,其中path为绝对路径 module_init(param_init) param_init kernel_file_open(p_pchar) kernel_dir_info()kernel_file_info(); param_init module_exit(param_exit)2 各功能函数的数据流程图ls命令获取文件属性void show_file_attribute(struct stat buf,cha

10、r *file_name,int flag_u) 获取并打印文件类型) 获取文件所有者的权限获取文件所有者同组的用户对该文件的操作权限获取并打印其他用户对文件的操作权限库函数getpwuid访问用户信息getgrgid访问组列表 获取时间输出文件的文件名,若命令中没有-l选项,则输出文件时要保证上下对齐void show_file_columns(char *file_name)本行不足以打印一个文件名则换行每两个相邻文件之间空2格根据命令行参数(存放在flag中)和完整路径名(存放在pathname中)显示目标文件void show_file(int flag,char *pathname)

11、从路径中解析出文件名ls -ulals -ulls -uals -als -uls -l ls为显示某个目录下的文件做准备,path:要显示的目录void show_file_dir(int flag_param,char *path)获取该目录下文件总数和最长的文件名对整个目录进行遍历获取该目录下所有的文件名文件名按最后访问时间进行排序文件名按字母顺序存储于filenames编写内核模块编写内核模块,打印super_block结构中一些域的值。(课本上的例子)打印super_blocks域 加锁遍历系统中的超级块获取系统中个超级块的地址打印文件系统所在的主设备号和次设备号和文件系统名遍历打印

12、每个超级块中的所有索引节点号打印索引结点 解锁 索引节点数量给内核模块传入参数path,其中path为绝对路径文件信息通过file获取dentry再获取inode的相关信息输出文件索引节点的信息文件索引节点的数量文件类型和权限用户ID用户组ID指定文件系统的读写访问标志文件大小索引节点的状态硬链接数引用记数文件的块数版本号以位为单位的块大小目录信息通过file获取dentry相关信息输出目录项信息目录项标志哈希表短目录名目录项长度目录项名目录项计数器的引用3 重点设计及编码ls命令重点设计:为显示某个目录下的文件做准备,path:要显示的目录编码:void show_file_dir(int

13、flag_param,char *path)DIR *dir;/ 对目录进行操作struct dirent *ptr;/对目录的数据项进行操作int count=0;char filenames256PATH_MAX+1,tempPATH_MAX+1;char tempfilePATH_MAX+1;struct stat buf;int atimePATH_MAX+1,temp1;/获取该目录下文件总数和最长的文件名dir=opendir(path);if(dir=NULL)my_error("opendir",_LINE_);while(ptr=readdir(dir)!

14、=NULL)/对整个目录进行遍历if(filename_maxlen<strlen(ptr->d_name)filename_maxlen=strlen(ptr->d_name);count+;closedir(dir);if(count>256)my_error("这个目录下的文件太多了",_LINE_);int i,j,length=strlen(path);/获取该目录下所有的文件名dir=opendir(path);for(i=0;i<count;i+)ptr=readdir(dir);if(ptr=NULL)my_error(&quo

15、t;readdir",_LINE_);/_LINE_:预编译器内置宏,表示行数strcpy(tempfile,path);strcat(tempfile,ptr->d_name);if(lstat(tempfile,&buf) = -1)my_error("lstat", _LINE_);atimei = buf.st_atime;strncpy(filenamesi,path,length);/保存文件路径filenamesilength='0'strcat(filenamesi,ptr->d_name);/d_name:当前

16、目录下所有文件/子目录filenamesilength+strlen(ptr->d_name)='0'/文件名按最后访问时间进行排序if(flag_param = PARAM_U|(flag_param = PARAM_U+PARAM_A)for(i = 0;i < count-1;i+)for(j = i+1;j < count;j+)if(atimei < atimej)temp1 = atimei;atimei = atimej;atimej = temp1;strcpy(tempfile,filenamesi);strcpy(filenamesi

17、,filenamesj);strcpy(filenamesj,tempfile);else/文件名按字母顺序存储于filenames for(i = 0; i < count-1; i+) for(j = 0; j < count-1-i; j+) if( strcmp(filenamesj,filenamesj+1) > 0 ) strcpy(temp,filenamesj+1); tempstrlen(filenamesj+1) = '0' strcpy(filenamesj+1,filenamesj); filenamesj+1strlen(filena

18、mesj) = '0' strcpy(filenamesj, temp); filenamesjstrlen(temp) = '0' for(i = 0; i < count; i+) show_file(flag_param, filenamesi); closedir(dir);/如果命令中没有-l选项,打印一个换行符if(flag_param & PARAM_L)=0)printf("n");elseprintf("总记录数是:%dn",(int)sum/2);编写内核模块编写内核模块,打印super_

19、block结构中一些域的值。(课本上的例子)重点设计:遍历系统中的超级块编码:list_for_each(pos,(struct list_head *)SUPER_BLOCKS_ADDRESS)/list_entry宏通过指向list_head节点的地址来得到外部超级块的首地址/list_head结构类型的字段名称为s_list/ 获取系统中个超级块的地址sb=list_entry(pos,struct super_block,s_list);/某个子进程的地址/打印文件系统所在的主设备号和次设备号printk("ndev_t:%d:%dn",MAJOR(sb->s

20、_dev),MINOR(sb->s_dev);/打印文件系统名printk("file_type name:%s",sb->s_type->name);/遍历打印每个超级块中的所有索引节点号list_for_each(linode,&sb->s_inodes)pinode=list_entry(linode,struct inode,i_sb_list);count+;printk("%lut",pinode->i_ino);/打印索引结点给内核模块传入参数path,其中path为绝对路径重点设计:打开文件编码:st

21、atic int kernel_file_open(char *path)/O_DIRECTORY 如果参数所指的文件并非为一目录,则打开文件失败/ 以目录的形式打开file=filp_open(path,O_DIRECTORY,0);if(IS_ERR(file)file=filp_open(path,O_RDWR|O_CREAT,0777);if(IS_ERR(file)printk("Open file %s failed.n",path);/ 路径错误return 0;/文件printk("open file success!n");printk

22、("Path of file: %s",path);kernel_file_info();printk("ending!n");filp_close(file,NULL);return 1;else/目录printk("nThis is a diretory!n");printk("Path of directory: %s",path);kernel_dir_info();printk("ending!n");filp_close(file,NULL);return 0;5 测试数据及运行结果

23、1正常测试数据和运行结果ls命令lsls -l 并显示总记录数ls -als -uls -ulls -uals -lals -lauls /tmpls -l 文件名.c 修改文件的属性并看suid,sgid,sticky是否起作用了。修改文件权限读取3.txt中的内容修改3.txt的权限再读取3.txt修改3.txt权限再读取3.txt编写内核模块编写内核模块,打印super_block结构中一些域的值。(课本上的例子)插入:insmod卸载:rmmod显示:dmesg运行结果:显示主设备号,次设备号,文件类型名和索引节点数量。给内核模块传入参数path,其中path为绝对路径调试path=文件path=目录当目录中没有文件时,会自动创建指定文件路径错误时,报错2 异常测试数据及运行结果ls命令编写内核模块编写内核模块,打印super_block结构中一些域的值。(课本上的例子)给内核模块传入参数path,其中path为绝对路径六调试情况,设计技巧及体会1 改进方案在使用Linux编程实现用户态下带参数的ls命令功能的过程中,我实现了基本要求和部分高级要求,使得ls的部分命令可以实现,但是我的代码没有实现ls -R递归地列出目录中所有的文件包含子目录中的文件和输出结果分栏排序,每栏的宽度

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论