8
26
2014
1

ext4文件系统浅析----跨度之大的inode号

最近在研究ext4文件系统,系统同道之人能共同研究、探讨

 

背景:

在根目录底下

root@f303server:/mnt/sde3# ls -i

     14 2.txt   786433 dir1  1048577 dir3        1179649 mkfs

     15 3.txt   917505 dir2       11 lost+found       13 sde3.txt

 

问题:

用黄色标记的几个为目录项,其中lost+found是格式化、挂载文件系统时自带的目录,其余四个是我创建的。那么问题来了,为什么我创建目录结点的inode号那么的大?

 

 

解释:

在ext4中,文件系统为了保证数据能更加均匀地分布在磁盘上,所以在创建目录时,尽量均匀地分布在不同的flexible block_group(flexbg)中。且同一个目录下的文件和这个目录的inode号在一个flexbg中:

 

默认一个flexbg含有16个block group,故 一个flexbg中含有inode结点数为8196 * 16 = 131072 个。所以dir1786433 位于第6flexbg中(131072 * 6 + 1 = 786433,在dir1目录下的1.txt,查看其inode结点号为  786434

 

同理可以计算其他的三个目录分别在第789flexbg

 

 

 

ps:

1怎么查看一个group有多少个inode结点:

debugfs /dev/sde3

stats

显示如下

 

debugfs

Stats
Filesystem volume name:   <none>
Last mounted on:          /mnt/sde3
Filesystem UUID:          fea02b9a-41d1-4bf1-96ce-d3298d67778f
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              1310720
Block count:              5242880
Reserved block count:     262144
Free blocks:              5116587
Free inodes:              1310705
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      1022
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512  #Inode table所占的块数目
Flex block group size:    16         #下面前16个inode bitmap所在
Filesystem created:       Mon Jul 28 08:40:58 2014
Last mount time:          Tue Jul 29 19:53:03 2014
Last write time:          Tue Jul 29 19:53:03 2014
Mount count:              8
Maximum mount count:      -1
Last checked:             Mon Jul 28 08:40:58 2014
Check interval:           0 (<none>)
Lifetime writes:          454 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      0da457a4-59ff-402a-9181-c66156ea5991
Journal backup:           inode blocks
Directories:              6
Group  0: block bitmap at 1025, inode bitmap at 1041, inode table at 1057
           23513 free blocks, 8178 free inodes, 2 used directories, 8176 unused inodes
           [Checksum 0x7a6d]
 Group  1: block bitmap at 1026, inode bitmap at 1042, inode table at 1569
           31740 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Checksum 0x2c05]
 Group  2: block bitmap at 1027, inode bitmap at 1043, inode table at 2081
           32768 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Block not init, Checksum 0x7c29]
 Group  3: block bitmap at 1028, inode bitmap at 1044, inode table at 2593
           31743 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Checksum 0x1e2b]延迟初始化
………..
……..
Group 12: block bitmap at 1037, inode bitmap at 1053, inode table at 7201
           32768 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Block not init, Checksum 0x30ab]
 Group 13: block bitmap at 1038, inode bitmap at 1054, inode table at 7713
           32768 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Block not init, Checksum 0x8f81]
 Group 14: block bitmap at 1039, inode bitmap at 1055, inode table at 8225
           32768 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Block not init, Checksum 0x8aa2]
 Group 15: block bitmap at 1040, inode bitmap at 1056, inode table at 8737
           32768 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Block not init, Checksum 0x350d]
 Group 16: block bitmap at 524288, inode bitmap at 524304, inode table at 524320
           24544 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes
           [Inode not init, Checksum 0xb89c]

 

 

2.怎么查看flexbg包含16个block group

从上面的debugfs的group 显示结果可以看出,group 0至group 15的block bitmap,inode bitmap、inode table是连续存放的。而从group 16开始元数据不再连续了,这也说明flexbg为16个block group。

Category: 文件系统 | Tags: ext4
8
26
2014
73

linux中ext4文件系统目录项管理

Ext4文件系统目录项有两种实现方式:

方式一:线性方式

        该方式的目录项以ext4_dir_entry_2的结构一个接连一个直接存储在目录结点所指向的block块中。(缺省配置使用ext4_dir_entry_2这个结构)

 

方式二:Hash树的方式

        若目录下的文件数量很多,则若按照线性方式查找对应文件名的信息则会很低效。Hash树的方式,则可以用文件名来做hash计算,从而定位到对应文件的目录项结构所在的block,从而缩小查找范围、加快查找效率。

 

1.查看文件系统是否开启了方式二的目录管理方式

      root@f303server:~# tune2fs -l /dev/sde3 | grep dir_index

Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg 

  输入如上指令,则可以发现文件系统的目录已经开启了hash树的管理方式。

 

2.hash树管理方式的打开和关闭

      在上述开启状态下,我们可以关闭hash树目录管理方式。关闭之后再打开。

root@f303server:~# tune2fs -O ^dir_index /dev/sde3

tune2fs 1.42.11 (09-Jul-2014)

root@f303server:~# tune2fs -l /dev/sde3 | grep dir_index  # 查找不到了

root@f303server:~# tune2fs -O dir_index /dev/sde3

tune2fs 1.42.11 (09-Jul-2014)

root@f303server:~# tune2fs -l /dev/sde3 | grep dir_index

Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize

root@f303server:~# 

 

 

3.怎么判断某目录是否以hash树的方式管理

 

    文件系统开启了hash树管理目录结点的方式并不意味着所有的目录都按树形结构组织管理。在文件系统中,系统会根据某个目录底下文件的多少来自动进行目录管理方式的选择,只有当文件数量大于某个数时,才会采用hash树管理方式。

 

    怎么判断某目录的管理方式是那种?

   

    若不是hash树的管理方式,则htree中debugfs中则会有如下提示

 

debugfs:  htree linux-2.6.34.14

 

htree: Not a hash-indexed directory

 

 

     若是hash树的管理方式,则

debugfs:  htree linux-2.6.34.14/kernel 显示如下

 

 


Root node dump:
         Reserved zero: 0
         Hash Version: 1
         Info length: 8
         Indirect levels: 0
         Flags: 0
Number of entries (count): 2
Number of entries (limit): 508
Entry #0: Hash 0x00000000, block 1
Entry #1: Hash 0x775173ee, block 2

Entry #0: Hash 0x00000000, block 1
Reading directory block 1, phys 3154297
791969 0x33788c78-7df72ede (20) rtmutex.c   
791971 0x12e2688e-f00920c3 (28) .latencytop.o.cmd   
791973 0x6d76fd8a-f7dad208 (16) futex.o   
791974 0x1f1d389c-0beb6325 (20) ns_cgroup.c   
791975 0x21f726a2-367f43fb (24) .built-in.o.cmd   
791977 0x2a43c4ba-ae0695eb (16) itimer.o   
791978 0x6139ce78-4032f3c2 (16) user.c   
791979 0x615af808-2478500b (24) test_kprobes.c   
791981 0x30feba52-ba8da1e9 (20) audit_tree.c   
791982 0x24bb2b3c-8100eb0d (20) kallsyms.o   
791987 0x71a57d4c-81410e0a (20) .uid16.o.cmd   
791989 0x3e1650ba-3d29a28e (20) freezer.c   
791991 0x0ba6a23a-978af98d (20) spinlock.o   
791992 0x1c6819e6-010b1d97 (24) sched_clock.o   
791997 0x6dc7a2ac-6b0769cb (12) gcov   792005 0x1db5303a-76fff9c7 (16) cpu.o   
792009 0x74def468-a27557c6 (20) .timer.o.cmd   
792010 0x540fdfac-e9e8121b (20) slow-work.o   
792014 0x4c0dc1c8-05179835 (24) Kconfig.preempt   
792018 0x620198da-2fb834e3 (16) cred.c   
792019 0x5973e25e-39b86f3d (32) .cgroup_freezer.o.cmd   
792021 0x1077ffa8-16896967 (16) sys.o   
792025 0x4011172e-63cbf0ec (28) .audit_tree.o.cmd   
792026 0x4c92aabc-1f86d6e5 (20) seccomp.o   
792027 0x5d7f2368-8aaa1cf9 (20) latencytop.c   
792028 0x2ff6ae9c-7b348c25 (24) pid_namespace.o   
792030 0x5f780482-e9fe78e9 (16) groups.o   
792031 0x6079e2b2-acbbff3a (24) rcutree_plugin.h   
792034 0x624e25c0-64cbfd07 (20) stacktrace.o   
792035 0x6e2d0608-09d837e7 (24) .sys_ni.o.cmd   
792036 0x7035c67c-3620d4f6 (16) uid16.o   
792038 0x5b9c06d0-57b802ad (24) .rcutree.o.cmd   
792039 0x356bc37c-95dc4cfb (16) fork.o   
792042 0x46df975e-cef87f2d (16) async.c 

该文如下部分探讨按照方式1组织的目录结构:

1.为了理解后文,首先了解ext4_dir_entry_2的每一个元素

Offset

Size

Name

Description

0x0

__le32

inode

Number of the inode that this directory entry points to.

0x4

__le16

rec_len

Length of this directory entry.

0x6

__u8

name_len

Length of the file name.

0x7

__u8

file_type

File type code, one of:

0x0

Unknown.

0x1

Regular file.

0x2

Directory.

0x3

Character device file.

0x4

Block device file.

0x5

FIFO.

0x6

Socket.

0x7

Symbolic link.

0x8

char

name[EXT4_NAME_LEN]

File name.

 

上表我们可以看到该结构中共5个数据项,前四项占8byte,

通过根目录为例,通过hexdump查看其二进制代码,则“目录项的长度(ren_len)= 文件名长度(name_len) + 8 ”。但是在很多情况下rec_len > = name_len + 8。原因是因为目录项每一项的起始位置必须按照后两位 00 对齐。故有时候会浪费几个字节。

 

 2.通过hexdump指令直接查看二进制内容

先通过

debugfs /dev/sde3

stat .

查找到根目录文件数据所在的块为9249,块大小为4K,故根目录数据所在的起始地址36996k。

 

root@f303server:~# hexdump -C /dev/sde3 -s 36996k -n 4096

02421000  02 00 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|

02421010  0c 00 02 02 2e 2e 00 00  0b 00 00 00 14 00 0a 02  |................|

02421020  6c 6f 73 74 2b 66 6f 75  6e 64 00 00 01 00 0c 00  |lost+found......|

02421030  0c 00 04 02 64 69 72 31  01 00 0e 00 0c 00 04 02  |....dir1........|

02421040  64 69 72 32 0d 00 00 00  10 00 08 01 73 64 65 33  |dir2........sde3|

02421050  2e 74 78 74 0e 00 00 00  10 00 05 01 32 2e 74 78  |.txt........2.tx|

02421060  74 74 2e 73 11 00 00 00  10 00 05 01 33 2e 74 78  |tt.s........3.tx|

02421070  74 74 2e 73 01 00 10 00  0c 00 04 02 64 69 72 33  |tt.s........dir3|

02421080  01 00 12 00 0c 00 04 02  6d 6b 66 73 0c 00 00 00  |........mkfs....|

02421090  18 00 0e 01 62 6c 6b 74  72 61 63 65 5f 73 74 75  |....blktrace_stu|

024210a0  64 79 65 33 15 00 00 00  18 00 10 01 62 6c 6b 74  |dye3........blkt|

024210b0  72 61 63 65 5f 73 74 75  64 79 2e 63 10 00 00 00  |race_study.c....|

024210c0  14 00 0b 01 67 63 63 5f  62 6c 6b 74 2e 73 68 00  |....gcc_blkt.sh.|

024210d0  0f 00 00 00 10 00 07 01  6e 65 77 2e 74 78 74 63  |........new.txtc|

024210e0  12 00 00 00 1c 00 13 01  62 6c 6b 74 72 61 63 65  |........blktrace|

024210f0  5f 73 74 75 64 79 2d 76  31 2e 63 01 01 00 02 00  |_study-v1.c.....|

02421100  10 00 06 02 4e 65 77 44  69 72 61 63 13 00 00 00  |....NewDirac....|

02421110  1c 00 13 01 62 6c 6b 74  72 61 63 65 5f 73 74 75  |....blktrace_stu|

02421120  64 79 2d 76 32 2e 63 77  14 00 00 00 18 00 0e 01  |dy-v2.cw........|

02421130  64 72 6f 70 5f 63 61 63  68 65 73 2e 73 68 79 2e  |drop_caches.shy.|

02421140  01 00 04 00 10 00 06 02  73 64 65 31 63 70 15 01  |........sde1cp..|

02421150  01 00 08 00 b0 0e 0f 02  6c 69 6e 75 78 2d 32 2e  |........linux-2.|

02421160  36 2e 33 34 2e 31 34 00  00 00 00 00 00 00 00 00  |6.34.14.........|

02421170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

*

02422000

 

上图中每个颜色表示一个dentry的记录

 

1

观察lost+found目录:

Rec_len = 0x 00 14   name_len = 0a

 

rec_len = name_len +8 +2   则在对齐时浪费了第三行的第1112个字节。

 

2

我们看到2.txt的文件名变成了2.txtt.s

 

原因是最后三个字节是无效字节,在对齐时已经去掉,对齐时三个字节的内容是随便填充的。

 

 

 

 

 

8
2
2014
2

Linux文件系统,为什么设计group

前言:

linux内核是一个很伟大的东西。。。(好吧~我居然用“伟大”来形容了linux内核),不过说实话,内核代码绝对是c语言中经典的经典。里面的一些设计思想都值得反复推敲、琢磨(虽然我还看不大懂,在啃过程中)。。按照我导师的话来说:写linux内核的那帮人绝对是顶级聪明的人。

看聪明人的作品,熏陶 熏陶自己。

我们今天关注问题如下:why linux的文件系统设计group这个概念。有什么好处呢?linux文件系统已经够复杂了,为什么还要加上group这个管理单元?

那天导师问这问题时,我硬是没怎么反应过来,说了几个答案,但都没说到点上,这儿我总结一下:

面对问题的思考方法:

从多角度思考这个问题:

从用户角度:方便用户容量的扩充或减少

    很明显,有了group这个概念,我们的元数据区、数据区可以一个版块一个版块地管理,如果用户容量扩充,只需要在现有group后增加几个group,然后修改super block,GDT(块组描述符)等就可以了。减小容量也是如此;试想一下如下没有group这个概念,若要扩容,则inode bitmap,data bitmap,inode table所占的空间都要变大,那么整个数据区都要向后迁移,代价太大。

从计算机性能角度:一次IO能抓取所需元数据,提高访问速度

    首先我们要知道,在默认的配置中,一个group单元中的block bitmap的个数为32768,这个在格式化磁盘时,可以在输出信息上看到信息:32768 blocks per group。所以说block bitmap所需要的占用的存储空间大小刚好为1个block大小,即4k,所以说在一次IO读操作,我就可以把当前访问数据的bitmap区域的元数据一次性缓存,由于与访问的局部性,一段时间访问的数据很大概率都是位于这个block的,所以需要多次访问元数据,而这些元数据系统都cache住了,故性能得到很好地提高。

     上面说的是block bitmap为4k,默认一个group中inode bitmap为1k。也是可以一次IO都缓存下的。而且data区域4k*8*4k= 128M,这个大小都是一次调入Mem可以缓存下的。所以极大提高了cache命中率,也就提高了访问速率。

     其实上述的解释都可以类比于一个概念:对齐。在计算机系统结构中,一定要建立一个对齐的概念,对齐的概念我通过两个例子稍微解释。

例1:一个数据结构如果放在未对齐的内存中,则会引起两次访存操作。

例2:放在磁盘上一个4k的文件,如果跨了两个block,那么要进行两次访问disk的操作,效率大打折扣。

所以说计算机系统结构中,对齐是效率的一个关键点所在。

从磁盘寿命的角度:写均匀,延长寿命

元数据、数据写的区域因为布局方式的因素,因而把写均匀到了磁盘的各个区域。个人感觉有一定的延长寿命作用。

 

关于group概念还能带来什么好处,欢迎留言!

 

补充:

这里对group概念稍做介绍,文件系统结构图如下:

 

文件系统是以分区为单位的,所以说一个分区上的所有group的文件系统类型都相同。

整个分区group的inode是连续编号的,给定一个inode编号,可以通过取模、取余的方式可以知道该inode为那个group上的第几个inode。inode编号从1开始,故所在块组bg=inode_num -1)/ ext4_super_block.s_inodes_per_group 

所在 块组的index

index=(inode_num -1) % ext4_super_block.s_inodes_per_group 

Category: Linux | Tags: 文件系统 group
8
1
2014
1

Linux 运行自己的 mkfs 代码

1:背景:

     最近研究文件系统迫切地需要通过直接查看磁盘上的二进制源码来观察inode bitmap,databitmap,inode table,数据区的信息。可是如何知道各个区域在不同文件系统中所占的块大小,起始地址是个头疼的问题。我试着通过debugfs的一些功能来查找。具体尝试如下:

     debugfs /dev/sde3

     stat .

     可以查看根目录的数据所在的block,根目录数据区block为数据区第一个block,(我这么认为,模糊的记忆,有待求证)

     输入ls -i 查看根目录下各个文件的inode编号。本来想通过inode编号反向索引到inode table区的,但没有成功。。。

     于是当然就想到了直接看mkfs的源码,看格式化到底默认配置各个区各占多少个block。

 

2:怎样运行自己的mkfs 

     在系统中输入格式化指令时:mkfs.ext2  mkfs.ext3 mkfs.ext4等,系统就直接调用了其默认的mke2fs指令。首先我们要搞清楚如下的指令是等价的。

      mke2fs -t ext4  = mkfs -t ext4 = mkfs.ext4

     所以我们的关键是让系统能够运行我们自己的mke2fs执行文件,而不是系统默认的。步骤如下:

step1:http://sourceforge.net/projects/e2fsprogs/这个链接文件下下载e2fsprogs源码包

step2:把下载到的e2fsprogs-1.42.11.tar.gz包在linux下解压缩:比如说我解压缩的路径如下

root@f303server:/mnt/sde1/mkfs/e2fsprogs-1.42.11# tar zxvf e2fsprogs-1.42.11.tar.gz 

step3:更改congifure文件的执行属性

   打开解压缩的文件,文件下有一个配置文件congifure。将其改成可执行文件的属性  chmod +x congifure

   congifure 文件是配置文件,运行它能够根据你系统情况生成对应的makefile文件,从而为make做准备。

step4:运行configure文件

./configure  configure完成后,系统会生成makefile文件

step5: 编译

make  make完之后就生成可执行文件了

step6: 使用编译好的mke2fs

可执行文件mke2fs在misc目录下

cd misc/

ls

我们可以看到绿色的可执行文件标示:

 

有了它,我们就可以愉快的运行自己的mke2fs了。不过要记得在这里加上路径哦,在:/mnt/sde1/mkfs/e2fsprogs-1.42.11/e2fsprogs-1.42.11/misc路径下,如果直接输入mke2fs,则系统调用的是内核安装默认的。若想要运行我们编译的版本,需要做的是加上当前路径./mke2fs。

请看如下截图,我故意输入错误的mke2fs的指令,让其有Usage提示信息。以便于观察,我在自己的mke2fs版本的上的Usage提示信息加入了TSS,方便打印观察

 

 

上图可以看到,黑色标记部分证明了运行的是我编译的mke2fs文件。

到此为止我们就可以在/mnt/sde1/mkfs/e2fsprogs-1.42.11/e2fsprogs-1.42.11/misc路径下输入路径化的./mke2fs -t ext4 /dev/ram0 来用自己编译的mke2fs了。由于可以再mke2fs中间加入辅助打印信息,因此我们就可以方便的看到super block,GDT(块组描述符), inode bitmap , data bitmap,inode table以及数据区的具体位置了。这样用hexdump指令观察disk上的数据就更加有目标性了。为后续观察提供很大的便利。。给自己点个赞!

 

3.该过程的经历

上述6个步骤我哗啦啦地就总结完了,如果跟着做也哗啦啦很快做完了。可是其实我摸索的过程也挺崎岖的。。。

主要是自己还是too young,too simple,然后被一篇博客误导了。制作嵌入式文件系统工具mkfs.ext2 mkfs.ext2 mkfs.ext2。其实也不叫误导,人家题目都写清楚了是“嵌入式”的,而我确值看了后半句。。o(╯□╰)o~~他应该是在linux上编译e2fsprogs-1.42.11里面的文件,然后再在手机上运行,编译的机器和编译后可执行代码的设备机器不是同一个,所以需要用到交叉编译工具。以前我们嵌入式的课弄过交叉编译这玩意儿,可是没什么印象。我居然很逗地以为我也要交叉编译,按照那个步骤做。。然后一直在整那个交叉编译工具。。疯了~~~

 

附录:

1.默认格式化为ext2

root@f303server:/mnt/sde1/mkfs/e2fsprogs-1.42.11/e2fsprogs-1.42.11/misc# mkfs /dev/sde2
mke2fs 1.42.11 (09-Jul-2014)
/dev/sde2 contains a ext3 file system
created on Fri Aug  1 16:35:03 2014
Proceed anyway? (y,n) y
Creating filesystem with 1310720 4k blocks and 327680 inodes
Filesystem UUID: dfcd8416-8bdf-486f-8c33-10d2584a4e6f
Superblock backups stored on blocks: 
32768, 98304, 163840, 229376, 294912, 819200, 884736
 
Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done 
 
root@f303server:/mnt/sde1/mkfs/e2fsprogs-1.42.11/e2fsprogs-1.42.11/misc# mkfs -t ext3 /dev/sde2
mke2fs 1.42.11 (09-Jul-2014)
/dev/sde2 contains a ext2 file system (提示,该磁盘有了ext2文件系统,所以从该处推出上述格式化时默认版本为ext2)
created on Fri Aug  1 17:04:15 2014
Proceed anyway? (y,n) n

2.查看mkfs版本

root@f303server:/mnt/sde1/mkfs/e2fsprogs-1.42.11/e2fsprogs-1.42.11/misc# ./mke2fs -V 
mke2fs 1.42.11 (09-Jul-2014)
Using EXT2FS Library version 1.42.11
root@f303server:/mnt/sde1/mkfs/e2fsprogs-1.42.11/e2fsprogs-1.42.11/misc# mke2fs -V 
mke2fs 1.42.11 (09-Jul-2014)
Using EXT2FS Library version 1.42.11
 
看来刚刚下载的版本和系统自带的版本是同一个版本。
 
7
22
2014
17

调整系统时间

linux中的时间,我知道的有两种:系统时钟,硬件时钟

1.系统时钟

查看指令   date

修改指令1: date 月日时分年.秒

截图:

 

修改命令2: data -s 时:分:秒

 

 

 

2.硬件时钟

查看命令: hwclock --show

修改命令: hwclock --set --date="月/日/年 时:分:秒"

 

 

 

Category: 未分类 | Tags:
7
22
2014
2

dmesg 总结

1.dmesg介绍

在dmesg里我们可以查看到开机信息,printk产生的信息等。若研究内核代码,在代码中插入printk函数,然后通过dmesg观察是一个很好地方法。

 

2.dmesg输出含义

dmesg 输出的数字含义是什么,纠结了一会儿,下面给出解释

终端输入dmesg,可以看到每行最开始显示的是一个综括号,里面的数字为timestamp,时间戳,该时间指示的系统从开机到现在的运行时间,单位为s 秒。

 

图1

 

3.dmesg -c

  在显示的同时,clean掉dmesg缓存中信息

4.dmesg -T

  以当前时间的方式显示时间信息,而不是图1所示的开机时间

 

图2

 

3 dmesg -d 

显示dmesg中两条打印信息的时间间隔

 

图3

 

我们可以计算,上一行的时间戳 + 下一行的间隔 = 下一行的时间戳

例如:第一行和第二行,1069.638561 + 0.000003 = 1069.638564  这里的时间单位为秒

 

4.dmesg -d -T

-d和-T参数混合使用,效果可想而知

 

图4

 

5.dmesg | tail 显示dmesg最近一次的输出

 

由上面我们可以看到dmesg可以让我们获得很多信息,包括函数进入时间等,可以利用dmesg原本已有的功能进行辅助分析。dmesg 很~\(≧▽≦)/~赞

Category: Linux | Tags:
7
18
2014
0

gdb代码调试总结

1.gdb 编译、运行

编译:gcc -g -Wall hello.c -o hello

调试:./hello

 

2.设置断点

b 函数名

b 行号

上述b为break的简写

设置好断点后,可以通过info break查看设置的断点:

 

3.continue指令

运行到断点停止后,可以输入continue使代码继续运行

4.watch指令

watch s   变量s发生变化时中断 运行时 continue 继续执行遇到s变化时会显示old value以及new value以及watchpoint 号。如下:

 

 

顺便说一句,info break也可以看到watch对应的编号

 

5.run 运行

run 运行程序,若有参数,则在run后面加参数

 

6.print 查看变量

print value 查看value的值

 

7 清除断点

clear n 清除第n行的断点

delete breakpoint 1   其中1是breakpoint的num,该num可以通过info break查看

 

8.disable 清除watch点

disable 4  其中4是watch点的num,该num同样可以通过info来查看。

如下如在输入disable 4之前,Enb状态为y,输入后状态为n

 

之后要是用上了什么实用的gdb指令再完善该文章

Category: Linux | Tags: gdb
7
18
2014
5

文件系统--重命名的实质

在minix系统中输入如下指令

mv /tmp/test/a.txt /tmp/test/ttt/b.txt

文件系统具体的操作时什么?

step1 :找到/tmp/test所在目录项对应的数据块,得到a.txt文件的inode number,假设是0x18,并把inode number设为0,这样就把a.txt删除了

step2 :通过路径名得到/tmp/test/ttt目录所在的数据块,在其中添加一个新的目录项,并把该目录项的inode编号设置为Ox18,其他目录项的设置保持不变。这样就在/tmp/test/ttt下新建了一个b.txt。

所以说文件本身没有任何移动,在重命名指令下改变的只是目录项。

 

具体如下。

1.在/tmp/test目录项所在block找到a.txt,置为0.

022f060 00 00 62 2e 74 78 7400 00 00 00 00 00 00 00 00 |..a.txt.........|  “a.txt”文件,其inode number 
0022f070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|  被设为0 
 
2. 通过路径名翻译成磁盘上的位置得到“/tmp/test/ttt/”目录文件中的目录项,在其中添加一个新的目录项
0022f860 18 00 63 2e 74 78 7400 00 00 00 00 00 00 00 00 |..b.txt.........|  “b.txt”文件,其inode number 
0022f870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|  被设为0x18
 
橙色的内容62改成了63,其他内容没变,其实对应的是a.txt该名为b.txt,名字由a变成了b
Category: 文件系统 | Tags:
7
18
2014
0

模块化系统盘正在使用的文件系统类型

背景:

在我的博客将文件系统模块化一文中提到了系统盘所在分区的文件系统,不能运用那篇文章介绍的方法。原因很简单:举例说明:

系统盘所在的分区为/dev/sda1。该分区的文件系统内类型为ext4。启动系统,为保证系统能运行,系统就自动将内核中的ext4.ko插入到模块中了。所以已经不给你机会再插入自己编译的该模块了。

那如果我偏偏就像研究ext4文件系统呢,难不成要重装系统,然后把系统盘改成ext2,或者ext3格式~~~~No No!!用不成那么麻烦。其实呢方法很简单,就是把ext4模块重命名,比如说命名成a_ext4,嘿嘿~系统很傻的,这样它就会报重名的错误了。

具体怎么做呢?见下文,还是有一些需要注意的地方。

方法:

这里的具体做法参见文件系统模块化

step1:编译内核

将ext4改成M模式

step2:修改ext4的Makefile文件。

运行重新编译的内核。将内核源码目录下\linux-2.6.34.14\fs\ext4文件拷贝到/home/modulefs文件夹,修改/home/modulefs/ext4中的Makefile文件:

源文件如下:
 
#
# Makefile for the linux ext4-filesystem routines.
#

obj-$(CONFIG_EXT4_FS) += ext4.o

ext4-y	:= balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
		ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
		ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o

ext4-$(CONFIG_EXT4_FS_XATTR)		+= xattr.o xattr_user.o xattr_trusted.o
ext4-$(CONFIG_EXT4_FS_POSIX_ACL)	+= acl.o
ext4-$(CONFIG_EXT4_FS_SECURITY)		+= xattr_security.o

 

修改成如下

 
#
# Makefile for the linux ext4-filesystem routines.
#

obj-m += a_ext4.o

a_ext4-objs     := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
                ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
                ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o
KERNELDIR:=/usr/src/linux-2.6.34.14/
PWD:=$(shell pwd)
a_ext4-$(CONFIG_EXT4_FS_XATTR)          += xattr.o xattr_user.o xattr_trusted.o
a_ext4-$(CONFIG_EXT4_FS_POSIX_ACL)      += acl.o
a_ext4-$(CONFIG_EXT4_FS_SECURITY)               += xattr_security.o
default:
        make -C $(KERNELDIR) M=$(PWD) modules
clean:
        rm -rf *.o *.mod.c *.ko *.symvers

与上篇博客文件系统模块化中修改Makefile相比,可以发现我们将ext4模块重新命名了,命名为a_ext4

 

step3.修改内核代码

既然在我们改变了模块中ext4的名字,改成了a_ext4,则在/home/modulefs/ext4的代码中我们也做出相应的改变。

修改/home/modulefs/ext4/super.c中的如下内容

static struct file_system_type ext4_fs_type 以及

static int __init init_ext4_fs(void)

源文件如下:

static struct file_system_type ext4_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "ext4",
	.get_sb		= ext4_get_sb,
	.kill_sb	= kill_block_super,
	.fs_flags	= FS_REQUIRES_DEV,
};

static int __init init_ext4_fs(void)
{
	int err;

	ext4_check_flag_values();
	err = init_ext4_system_zone();
	if (err)
		return err;
	ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
	if (!ext4_kset)
		goto out4;
	ext4_proc_root = proc_mkdir("fs/ext4", NULL);
	err = init_ext4_mballoc();
	if (err)
		goto out3;

	err = init_ext4_xattr();
	if (err)
		goto out2;
	err = init_inodecache();
	if (err)
		goto out1;
	register_as_ext2();
	register_as_ext3();
	err = register_filesystem(&ext4_fs_type);
	if (err)
		goto out;
	return 0;
out:
	unregister_as_ext2();
	unregister_as_ext3();
	destroy_inodecache();
out1:
	exit_ext4_xattr();
out2:
	exit_ext4_mballoc();
out3:
	remove_proc_entry("fs/ext4", NULL);
	kset_unregister(ext4_kset);
out4:
	exit_ext4_system_zone();
	return err;
}

 

把如下三处'ext4' 修改成a_ext4
修改前

.name = "ext4",

ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);

ext4_proc_root = proc_mkdir("fs/ext4", NULL);

修改后

.name = "a_ext4",

ext4_kset = kset_create_and_add("a_ext4", NULL, fs_kobj);

ext4_proc_root = proc_mkdir("fs/a_ext4", NULL);

 

step4:编译模块,然后插入模块

具体做法,同文件系统模块化

这里注意格式化和挂载磁盘时指令如下:

make clean

make

insmod a_ext4

mkfs -t a_ext4 /dev/ram0

mount /dev/ram0 /mnt/a_ext4

 

 总结:

    其实模块化系统盘所在分区文件系统的具体做法(称为A) 与 文件系统模块化(称为B) 有两个不一样:

1.A的Makefile需要改变模块的名字,B不需要

2.A需要修改内核的代码,B不需要

 

7
18
2014
0

查看模块相关信息

本文借鉴博客如下:

http://www.cppblog.com/deercoder/articles/109274.html

背景:

     最近在研究将文件系统模块化,将模块化的文件系统插入到内核中后想看看有关自己模块的信息。于是有了本文。

 

知识点:

      在成功插入模块后,即ismod *.ko成功后。在/sys/module和/proc/modules中都包含模块信息

1./proc/modules中模块信息

输入指令cat /proc/modules,显示如下:

root@f303server:/sys/module# cat /proc/modules 
ext2 68558 0 - Live 0xffffffffa01fd000
a_ext4 356624 1 - Live 0xffffffffa01a3000
psmouse 60571 0 - Live 0xffffffffa0192000
joydev 10686 0 - Live 0xffffffffa0189000
serio_raw 4871 0 - Live 0xffffffffa0185000
dcdbas 6958 0 - Live 0xffffffffa017d000
mac_hid 3798 0 - Live 0xffffffffa0019000
ext3 132950 1 - Live 0xffffffffa0151000
lp 10051 0 - Live 0xffffffffa0148000
jbd 53663 1 ext3, Live 0xffffffffa0131000
parport 39053 1 lp, Live 0xffffffffa011f000
ext4 354498 2 - Live 0xffffffffa00b2000
mbcache 8015 4 ext2,a_ext4,ext3,ext4, Live 0xffffffffa0015000
jbd2 87538 2 a_ext4,ext4, Live 0xffffffffa0090000
mptsas 52883 4 - Live 0xffffffffa0081000
mptscsih 35312 1 mptsas, Live 0xffffffffa0076000
usbhid 41734 0 - Live 0xffffffffa0069000
mptbase 92767 2 mptsas,mptscsih, Live 0xffffffffa0049000
hid 81741 1 usbhid, Live 0xffffffffa002d000
scsi_transport_sas 35238 1 mptsas, Live 0xffffffffa001b000
bnx2 75653 0 - Live 0xffffffffa0000000

下面以:ext2 68558 0 - Live 0xffffffffa01fd000这一行为例,说明各列含义

其中ext2(模块名) 68558(占用内存大小) 0(引用该模块基数) - Live(模块可用) 0xffffffffa01fd000(模块的起始地址)

 

2./sys/modules中模块的信息

输入

cd /sys/modules

ls

可以看到所有对应的模块

 

 

打开其中一个模块,以ext2为例,可以看到包含如下内容

root@f303server:/sys/module# cd ext2
root@f303server:/sys/module/ext2# ls
holders  initstate  notes  refcnt  sections  srcversion
 
其中holders notes sections为目录
holders:  持有人,写本模块的人,但目录为空

inistate:记录模块活动

notes :貌似记录本模块信息

refcnt: 引用模块数

sections:

srcversion: 模块版本号,类似于模块ID

 

Category: Linux | Tags: 模块

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com