linux把查出的东西写进文件,block_dump观察Linux IO写入的具体文件

很多情况下开发者调测程序需要在Linux下获取具体的IO的状况,目前常用的IO观察工具用vmstat和iostat,具体功能上说当然是iostat更胜一筹,在IO统计上时间点上更具体精细。但二者都是在全局上看到IO,宏观上的数据对于判断IO到哪个文件上毫无帮助,这个时候block_dump的作用就显现出来了。

一、使用方法:

需要先停掉syslog功能,因为具体IO数据要通过printk输出,如果syslog存在,则会往message产生大量IO,干扰正常结果suse:~ # service syslog stop

Shutting down syslog services done

然后启动block_dumpsuse:~ # echo 1 > /proc/sys/vm/block_dump

先说效果:suse:~ # dmesg | tail

dmesg(3414): dirtied inode 9594 (LC_MONETARY) on sda1

dmesg(3414): dirtied inode 9238 (LC_COLLATE) on sda1

dmesg(3414): dirtied inode 9241 (LC_TIME) on sda1

dmesg(3414): dirtied inode 9606 (LC_NUMERIC) on sda1

dmesg(3414): dirtied inode 9350 (LC_CTYPE) on sda1

kjournald(506): WRITE block 3683672 on sda1

kjournald(506): WRITE block 3683680 on sda1

kjournald(506): WRITE block 3683688 on sda1

kjournald(506): WRITE block 3683696 on sda1

kjournald(506): WRITE block 3683704 on sda1

kjournald(506): WRITE block 3683712 on sda1

kjournald(506): WRITE block 3683720 on sda1

kjournald(506): WRITE block 3683728 on sda1

kjournald(506): WRITE block 3683736 on sda1

kjournald(506): WRITE block 3683744 on sda1

通过dmesg信息可以看到IO正在写那些文件,有进程号,inode号,文件名和磁盘设备名;但每个文件写了多少呢,仅仅通过dirtied inode就看不出来了,还需要分析WRITE block,后面的数字并不是真正的块号,而是内核IO层获取的扇区号,除以8即为块号,然后根据debugfs工具的icheck和ncheck选项,就可以获取该文件系统块属于哪个具体文件,具体请google之。

二、基本原理:

block_dump的原理其实很简单,内核在IO层根据标志block_dump在IO提交给磁盘的关口卡主过关的每一个BIO,将它们的数据打出来:void submit_bio(int rw, struct bio *bio)

{

int count = bio_sectors(bio);

bio->bi_rw |= rw;

/*

* If it's a regular read/write or a barrier with data attached,

* go through the normal accounting stuff before submission.

*/ if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {

if (rw & WRITE) {

count_vm_events(PGPGOUT, count);

} else {

task_io_account_read(bio->bi_size);

count_vm_events(PGPGIN, count);

}

if (unlikely(block_dump)) {

char b[BDEVNAME_SIZE];

printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)n",

current->comm, task_pid_nr(current),

(rw & WRITE) ? "WRITE" : "READ",

(unsigned long long)bio->bi_sector,

bdevname(bio->bi_bdev, b),

count);

}

}

generic_make_request(bio);

}

具体WRITE block块号和文件系统块号之间的对应关系在submit_bh函数中决定bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);

inode的block_dump实现是通过block_dump___mark_inode_dirty搞定的,这次把关口架在inode脏数据写回的路上,把每个过关的inode信息打出来:void __mark_inode_dirty(struct inode *inode, int flags)

{

if (unlikely(block_dump))

block_dump___mark_inode_dirty(inode);

}

static noinline void block_dump___mark_inode_dirty(struct inode *inode)

{

if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {

struct dentry *dentry;

const char *name = "?";

dentry = d_find_alias(inode);

if (dentry) {

spin_lock(&dentry->d_lock);

name = (const char *) dentry->d_name.name;

}

printk(KERN_DEBUG

"%s(%d): dirtied inode %lu (%s) on %sn",

current->comm, task_pid_nr(current), inode->i_ino,

name, inode->i_sb->s_id);

if (dentry) {

spin_unlock(&dentry->d_lock);

dput(dentry);

}

}

}

三、总结

1.内核由很多合适的关口来截获获取的IO信息,不改动内核,也可以用jprobe抢劫很多东西。

2.debugfs在大量的block-->file转换过程总太慢,自己用ext2fs写一个,效率应该能提高很多。

block_dump观察Linux IO写入的具体文件来自于OenHan

链接为:https://oenhan.com/block-dump-linux-io

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值