您现在的位置:首页 >> 污染防治

「底层原理」一层层剥开内核的面纱,彻底理解Linux内核

时间:2024-10-20 12:20:02

1024)=35GB hdb: 8589934592/(102410241024)=8GB hdd: 8589934592/(102410241024)=8GB

如果这是三块实质的物理SSD的话,的产品所大于的输显露功率就分别是37.5GB、8.5GB和8.5GB。可能有些童鞋明白真实世界机好像“假”,那么我就来看看实质SSD刚才是个啥样子。

;大角1:西部将近据集 500G SATA以太网 CentOS 5.5

实质输显露功率:500107862016B = 465.7GB

;大角2:希捷 160G SCSI以太网 CentOS 5.5

实质输显露功率:160041885696B=149GB

大家可以碰到,VMware一些公司的水准还是非常不错的,真实世界SSD和物理SSD“无论如何”看不显露相似之处,无论如何同属云和平台架构支撑者的风云人物嘛。

特别视频推荐

3个linux虚拟机的秘密,让你终究搞懂份FAT

剖析Linux虚拟机真实世界份FAT(VFS)架构

研习重定向:C/C++Linux路由器开发/一人开发者【零声普及教育】-研习视频教程-谷歌教学方法

所需C/C++ Linux路由器开发者研习资料加qun812855908(资料包括C/C++,Linux,golang核心技术,虚拟机,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg,生产商面试题 等)

以SSD/dev/hdd1为例,它是我一新增的一块一新盘,模板如此一来ext2后,根附录下只有一个lost+found附录,让我们来看一下它的中轴情况下,为了将来开始我们的份FAT旅行。

对于用作了ext2份FAT的的区来却说,有一个叫superblock的内部结构 ,superblock的形状为1024十六进制,只不过ext3的superblock也是1024十六进制。下面的小处理程序可以不太可能这一点:

#include #include #include int main(int argc,char** argv){ printf("sizeof of ext2 superblock=%d",sizeof(struct ext2_super_block)); printf("sizeof of ext3 superblock=%d",sizeof(struct ext3_super_block)); return 0;}******************【调试结果】******************sizeof of ext2 superblock=1024sizeof of ext3 superblock=1024

SSD的第一个十六进制比如说0开始代号,所以第一个十六进制是byte0,为了将类推。/dev/hdd1的区头部的1024个十六进制(从byte0~byte1023)都用0可用,因为/dev/hdd1不是;大引导盘。superblock比如说byte1024开始,占总1024B驱动器密闭。我们用dd擅自把superblock的的资讯浓缩显露来:

dd if=/dev/hdd1 of=./hdd1sb bs=1024 skip=1 count=1

上述擅自将从/dev/hdd1的区的byte1024处开始,浓缩1024个十六进制的将近据集驱动器到当在此之前附录下的hdd1sb份文件里头,该份文件里头就驱动器了我们superblock的所有的资讯,上头的处理程序稍稍整修,我们就可以以更是直观的方式碰到superblock的输显露了如下:

#include #include #include #include #include #include #include #include int main(int argc,char** argv){ printf("sizeof of ext2 superblock=%d",sizeof(struct ext2_super_block)); printf("sizeof of ext3 superblock=%d",sizeof(struct ext3_super_block)); char buf[1024] = {0}; int fd = -1; struct ext2_super_block hdd1sb; memset(Simonhdd1sb,0,1024); if(-1 == (fd=open("./hdd1sb",O_RDONLY,0777))){ printf("open file error!"); return 1; } if(-1 == read(fd,buf,1024)){ printf("read error!"); close(fd); return 1; } memcpy((char*)Simonhdd1sb,buf,1024); printf("inode count : %ld",hdd1sb.s_inodes_count); printf("block count : %ld",hdd1sb.s_blocks_count); printf("Reserved blocks count : %ld",hdd1sb.s_r_blocks_count); printf("Free blocks count : %ld",hdd1sb.s_free_blocks_count); printf("Free inodes count : %ld",hdd1sb.s_free_inodes_count); printf("First Data Block : %ld",hdd1sb.s_first_data_block); printf("Block size : %ld",1<<(hdd1sb.s_log_block_size+10)); printf("Fragment size : %ld",1<<(hdd1sb.s_log_frag_size+10)); printf("Blocks per group : %ld",hdd1sb.s_blocks_per_group); printf("Fragments per group : %ld",hdd1sb.s_frags_per_group); printf("Inodes per group : %ld",hdd1sb.s_inodes_per_group); printf("Magic signature : 0x%x",hdd1sb.s_magic); printf("size of inode structure : %d",hdd1sb.s_inode_size); close(fd); return 0;}******************【调试结果】******************inode count : 1048576block count : 2097065Reserved blocks count : 104853Free blocks count : 2059546Free inodes count : 1048565First Data Block : 0Block size : 4096Fragment size : 4096Blocks per group : 32768Fragments per group : 32768inodes per group : 16384Magic signature : 0xef53size of inode structure : 128

可以看算显露来,superblock 的依赖性就是日志份FAT的特性、block形状、block为将近、inode形状、inode为将近、group的为将近等的资讯。

对于ext2/ext3份FAT来却说身份测试Magic signature都是0xef53,如果不是那么它一定不是ext2/ext3份FAT。这里头我们可以碰到,我们的/dev/hdd1不太可能是ext2份FAT特性。hdd1中但会一合计值得注意到1048576个inode终端(inode代号从1开始),每个inode终端形状为128十六进制,所有inode耗损的驱动器密闭是1048576×128=128MB;多达值得注意到2097065个block,每个block形状为4096十六进制,每32768个block两组如此一来一个group,所以一合计有2097065/32768=63.99,即64个group(group代号从0开始,即Group0~Group63)。所以整个/dev/hdd1被划分如此一来了64个group,详情请如下:

用擅自tune2fs可以测试我们之在此之前的分析方法:

再通过擅自dumpe2fs /dev/hdd1的输显露,可以给与我们关注如下一小:

担纲来以Group0为例,;大superblock在Group0的block0里头,根据在此以后面的分析方法,我们可以画显露;大superblock在block0中但会的一段距离如下:

因为superblock是如此之重要,一旦它差错你的整个该系统就玩儿先了,所以份FAT中但会但会假定磁盘的多个相异一段距离但会假定;大superblock的硬碟复制,一旦该系统显露原因后还可以通过硬碟的superblock对份FAT先成修复。

第一版ext2份FAT的协作里头,每个Group里头都假定一份superblock的复制,然而这样动手的真实感也是非常明显,那就是严重减少了磁盘的密闭使用量。所以在后续ext2的协作预定义中但会,选择可用硬碟superblock的Group两组号的法理是3的N平方根、5的N平方根、7的N平方根其中但会N=0,1,2,3…。根据这个公式我们来计算一下/dev/hdd1中但会硬碟有supeblock的Group号:

也就是却说Group1、3、5、7、9、25、27、49里头都存放有superblock的副本,如下:

用block号分别总和32768就给与了硬碟superblock的Group号,和我们在上头碰到的结果恰当。我们来看一下/dev/hdd1中但会Group和block的关联:

从上左图中但会我们可以细致地看算显露来在用作了ext2份FAT的的区上,值得注意到有;大superblock的Group、硬碟superblock的Group以及很难硬碟superblock的Group的中轴情况下。驱动器了superblock的Group中但会有一个两组将近据结构(Group descriptors)后半段在superblock所在的block右边,占总一个block形状;同时还有个Reserved GDT跟在两组将近据结构的右边。

Reserved GDT的假定;大要是赞如此一来ext2份FAT的resize动态,它有自己的inode和data block,不论如何如果份FAT动态变大,Reserved GDT就正好可以腾显露一一小密闭让Group descriptor向下扩展。

担纲来我们来认识一下superblock,inode,block,group,group descriptor,block bitmap,inode table这些家伙。

superblock

这个东西不太可能很重要,在此以后面我们现在见识过。为此,份FAT还有意精挑细选的找了N多后备Group,在这些Group中但会都就其superblock的复制,你就知道它有多重要了。

却说白了,superblock 的依赖性就是日志份FAT的特性、block形状、block为将近、inode形状、inode为将近、group的为将近等等。

group descriptors

千万不要以为这就是一个两组将近据结构,碰到descriptor右边加了个s就知道这是N多将近据结构的论域。不太可能,这是份FAT中但会所有group的将近据结构所构如此一来的一个将近两组,它的内部结构表述在include/linux/ext2_fs.h中但会:

//Structure of a blocks group descriptorstruct ext2_group_desc{ 脚注le32 bg_block_bitmap; /* group中但会block bitmap所在的第一个block号 */ 脚注le32 bg_inode_bitmap; /* group中但会inode bitmap 所在的第一个block号 */ 脚注le32 bg_inode_table; /* group中但会inodes table 所在的第一个block号 */ 脚注le16 bg_free_blocks_count; /* group中但会在在的block为将近 */ 脚注le16 bg_free_inodes_count; /* group中但会在在的inode为将近*/ 脚注le16 bg_used_dirs_count; /* 附录将近 */ 脚注le16 bg_pad; 脚注le32 bg_reserved[3];};

下面的处理程序可以帮助探究一下/dev/hdd1中但会所有group的descriptor的详情请:

#define B_LEN 32 //一个struct ext2_group_desc{}占总固定32十六进制int main(int argc,char** argv){ char buf[B_LEN] = {0}; int i=0,fd = -1; struct ext2_group_desc gd; memset(Simongd,0,B_LEN); if(-1 == (fd=open(argv[1],O_RDONLY,0777))){ printf("open file error!"); return 1; } while(i<64){ //因为我现在知道了/dev/hdd1中但会只有64个group if(-1 == read(fd,buf,B_LEN)){ printf("read error!"); close(fd); return 1; } memcpy((char*)Simongd,buf,B_LEN); printf("========== Group %d: ==========",i); printf("Blocks bitmap block %ld ",gd.bg_block_bitmap); printf("Inodes bitmap block %ld ",gd.bg_inode_bitmap); printf("Inodes table block %ld ",gd.bg_inode_table); printf("Free blocks count %d ",gd.bg_free_blocks_count); printf("Free inodes count %d ",gd.bg_free_inodes_count); printf("Directories count %d ",gd.bg_used_dirs_count); memset(buf,0,B_LEN); i++; } close(fd); return 0;}

调试结果和dumpe2fs /dev/hdd1的输显露对比如下:

其中但会,份文件gp0decp是由擅自“dd if=/dev/hdd1 of=./gp0decp bs=4096 skip=1 count=1”生如此一来。每个group descriptor里头日志了该group中但会的inode table的接续block号,因为inode table有可能但会征用连续的多个block;在在的block、inode将近等等。

block bitmap:

在份FAT中但会每个都可都有一个特别联的inode终端(这句话有些不太正确地,因为下标客户端和它的目标份文件合计用一个inode),里头驱动器了一个都可(份文件或附录)的的资讯有职责、所占总十六进制将近、创始整整、修改整整、客户端将近、属;大ID、两组ID,如果是份文件的话还但会值得注意到份文件内容征用的block为将近以及block号。inode比如说1代号,这一点相异于block。

所需格外注意到。另外,/dev/hdd1是一新可携带的SSD,模板如此一来ext2后并很难任何将近据集,只有一个lost+found附录。担纲来我们用擅自“dd if=/dev/hdd1 of=./gp0 bs=4096 count=32768”将Group0里头的所有将近据集浓缩显露来。

在此以后面现在探究了Group0的一些基本上的资讯如下:

Group 0: (Blocks 0-32767) Primary superblock at 0, Group descriptors at 1-1 Reserved GDT blocks at 2-512 Block bitmap at 513 (+513), Inode bitmap at 514 (+514) Inode table at 515-1026 (+515) 31739 free blocks, 16374 free inodes, 1 directories #值得注意到一个附录 Free blocks: 1028-1031, 1033-32767 #一合计有31739个在在block Free inodes: 11-16384 #一合计有16374个在在inode

一个block bitmap征用一个block形状,而block bitmap中但会每个bit回应一个特别联block的征用情况下,0回应特别联的block为空,为1回应反之亦然的block中但会就其将近据集。在/dev/hdd1中但会,一个group里头超过无论如何无法值得注意到8×4096=32768个block,这一点我们现在清楚了。担纲来我们来看一下Group0的block bitmap,如下:

辨认出block bitmap的在此之前128十六进制和第129十六进制的高4位都为1,明确指显露辨认出Group0中但会在此之前128×8+4=1028个block,即block0block1027都已被用作了。第129十六进制的高4位为0,回应block1028block1031四个block是在在的;第130十六进制的最高位是1,明确指显lock1032被征用了;从block1033~block32767的block bitmap都是0,所以这些block都是在在的,和上表输显露的结果恰当。

inode bitmap

和block bitmap类似,innode bitmap的每个比特回应反之亦然的inode是否被用作。Group0的inode bitmap如下:

/dev/hdd1里头inode为将近为1048576,要被均分到64个Group里头,所以每个Group中但会都值得注意到了16384个inode。要回应每个Group中但会16384个inode,inode bitmap多达所需用作2048(16384/8)十六进制。inode bitmap本身就占总据了一个block,所以它只用到了该block中但会的在此之前2048个十六进制,余下的2048十六进制都被可用如此一来1,如上左图请注意到。

我们可以碰到Group0中但会的inode bitmap在此之前两个十六进制分别是ff和03,明确指显露Group0里头的在此之前11个inode现在被用作了。其中但会在此之前10个inode被ext2留出起来,第11个inode就是lost+found附录,如下:

inode table

那么每个Group中但会的所有inode刚才存放在哪里头呢?答案就是inode table。它是每个Group中但会所有inode的聚合地。

因为一个inode占总128十六进制,所以每个Group里头的所有inode合计占总16384×128=2097152十六进制,多达耗损了512个block。Group的group descriptor里头日志了inode table的所占总block的接续号,所以就可以唯一确定每个Group里头inode table所在的block的接续号和结束号了。inode的内部结构如下:

这里头我们;大要关注的其中但会的将近据集block赋值一小。在此之前12个block赋值单独看如此一来了就其将近据集的block号;第13个block赋值所看如此一来的block中但会驱动器的并不是将近据集而是由其他block号,这些block号所特别联的block里头驱动器的才是真正的将近据集,即所谓的两级block赋值;第14个block为三级block赋值;第15个block为四级block赋值。先前真实感左图如下:

一个block为4096十六进制,每个块赋值4十六进制,所以一个block里头超过可以容纳4096/4=1024个block赋值,我们可以计算显露一个inode第二大能回应的单个份文件的第二大输显露功率如下:

单独block赋值(十六进制)

两级block赋值(十六进制)

三 级block赋值(十六进制)

四 级block赋值(十六进制)

单个份文件的第二大输显露功率(十六进制)

12×409

4096/4×4096

40962/4×4096

40963/4×4096

4TB

所以,我们可以算显露相异block形状,对单个份文件第二大输显露功率的受到影响。假设block形状为X十六进制,则:

如下表请注意到:

block形状(十六进制)

单个份文件输显露功率(十六进制)

1024

17247240192十六进制(16GB)

2048

275415826432十六进制(256GB)

4096

4402345672704十六进制(4TB)

先前来一张恰巧:

经常肚子疼拉肚子怎么回事
青岛装修设计
关节僵硬应该检查什么
北京看强直性脊柱炎那家医院好
多普泰脉血康胶囊怎么样
波比宁佐米曲普坦片
八子补肾胶囊抗衰老效果好吗
治打呼噜的药去哪买好
八子补肾胶囊的效果怎么样
长期熬夜精力透支怎么缓解