dtrace:如何从文件中获取符号链接目标

时间:2013-11-18 16:33:45

标签: solaris solaris-10 dtrace

我正在使用dtrace记录所有被删除的文件。

是否有可能找出符号链接目标是什么(如果它是符号链接)?我想输出符号链接文件名和目标文件名以便日志记录,以防我以后需要恢复链接。

我想出的一个解决方案是使用dtrace“system”函数来调用我自己的程序,该程序将打印出符号链接目标: system(“myprogram%s”)其中%s是我要打印目标的符号链接的全名。

这个工作正常(这是一个非常短的C程序并完成工作) - 但有没有办法通过dtrace直接获取信息,因为我们正在处理文件,无论如何我们应该能够查找符号链接目标?

我查看了fileinfo_t结构,但它没有符号链接目标: http://docs.oracle.com/cd/E18752_01/html/817-6223/chp-io-args.html#chp-io-fileinfo

到目前为止,这是我的脚本: 这是在Solaris 10中。(这是探测fop_remove而不是syscall :: unlink,其原因是为了能够获取symlink目录,以防用户未在rm调用中指定目录)。 / p>

    #!/usr/sbin/dtrace -s

    #pragma D option quiet

    fbt::fop_remove:entry
    {
           self->dir = stringof(args[0]->v_path);
           self->file = stringof(args[1]);
    }

    fbt::fop_remove:return
    /self->file != NULL/
    {
           printf("%s/%s\n", self->dir, self->file);
           self->file = 0;
           self->dir = 0;
    }

谢谢!

2 个答案:

答案 0 :(得分:1)

在Solaris VFS级别(也称为vnode_t结构)上,符号链接目标附加到符号链接本身的节点。这是一个文件系统实现细节。

对于UFS文件系统,如果链接目标的路径名小于48字节(UFS称之为“快速符号链接”),则它与inode_t结构内联记录,您可以通过DTrace打印该值通过:

vnode = args[0];
inode = (inode_t*)vnode->v_data;

printf("symlink tgt: %47s\n",
    vnode->v_type != VLNK ||
    vnode->v_op != ufs_vnodeops ||
    inode->i_flags & I_FASTSYMLINK == 0 ?
        "[unresolved]" :
        (char *)inode->i_db);

对于其他文件系统/在一般情况下,您必须使用fsinfo::readlink:return(或fop::fop_readlink:return)探测点来获取目标 - 访问时,即它不会(通常)可以直接从vnode_t检索。

答案 1 :(得分:0)

我有以下可能的解决方案 - 就像你说的那样访问:

syscall::open:entry /strstr(stringof(copyinstr(arg0)), "mydirectory")!=NULL/ {
    self->file=copyinstr(arg0);
}

syscall::open:return /self->file != "" && strstr(stringof(fds[arg0].fi_pathname),   "mydirectory")!=NULL / {
    printf("%s %s\n", self-> file, fds[arg0].fi_pathname);
    self -> file=0;
}

syscall::open:return {
    self -> file=0;
}

(我在这里限制跟踪到mydirectory)。

因此,这利用了以下事实:在输入时,arg0是符号链接名称,并且在返回时,文件描述符可用于获取路径名,该路径名是实际文件的路径名。这将是符号链接的目标。 在删除时完成跟踪并不重要,只是符号链接 - >记录目标。