利用crash分析内存unused dentry信息

2020-05-31 22:03:08 浏览数 (1)

读写文件频繁的环境经常碰到大量dentry占用内存高的情况,本文介绍一种通过crash找到这些dentry

对应的文件的方法。

通过cat /proc/sys/fs/dentry-state的信息可以看到正在运行系统的dentry数量:

# cat /proc/sys/fs/dentry-state

那么我们来看下内核是怎么统计dentry数量的。

从代码中可以看到unused状态的dentry成员dentry->d_lru是通过struct super_block 的struct list_head s_dentry_lru连接起来的:

代码语言:javascript复制
/*
 * dentry_lru_(add|del|prune|move_tail) must be called with d_lock held.
 */
static void dentry_lru_add(struct dentry *dentry)
{
    if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST))) {
        spin_lock(&dcache_lru_lock);
        dentry->d_flags |= DCACHE_LRU_LIST;
        list_add(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
        dentry->d_sb->s_nr_dentry_unused  ;
        dentry_stat.nr_unused  ;
        spin_unlock(&dcache_lru_lock);
    }
}

struct super_block {
....
struct list_head    s_dentry_lru;    /* unused dentry lru */
...
}
struct dentry {
    ...
    struct list_head d_lru;        /* LRU list */
   ...
};

根据以上信息就可以通过coredump找到所有的dentry信息了:

1、获取所有struct super_block的地址信息:

mount >/opt/mount.txt

cat mount.txt | grep -v SUPERBLK | awk '{print $2}' |sort -u > list_mount.txt

2、根据list super_block.s_dentry_lru -h ffff882fb855a000可以获取地址为ffff882fb855a000的super_block成员s_dentry_lru连接起来的所有dentry的成员d_lru,将文件list_mount.txt内容修改如下以获取所有文件系统对应的各自所有dentry.d_lru

vi list_mount.txt后在vi模块下执行如下命令在地址前添加字符串"list super_block.s_dentry_lru -h "

:%s/^/list super_block.s_dentry_lru -h /

注:ffff882fb855a000为super_block地址

3, 执行获取所有文件系统的dentry成员dentry->d_lru

< /opt/dump/list_mount.txt > /opt/dump/list_dentry_lru.txt

4,d_lru地址相对struct dentry的偏移0x88,因此将list_dentry_lru.txt文件中d_lru地址减去0x88就获得所有struct dentry的地址:

for i in `cat list_dentry_lru.txt | grep -v list` ;do printf 0x%x $((0x$i - 0x88));echo "";done > list_dentry.txt

5,修改list_dentry.txt文件得到crash指令获取dentry对应的文件名:

vi编辑list_dentry.txt在地址前添加字符串"struct dentry.d_iname "

:%s/^/struct dentry.d_iname /

6,执行如下命令完成后文件名被保存到list_file.txt中:

< /opt/dump/list_dentry.txt > /opt/dump/list_file.txt

参考:

https://patchwork.kernel.org/patch/9884869/

https://lkml.org/lkml/2014/5/28/566

https://access.redhat.com/solutions/4423151

0 人点赞