This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tapsets/17920] File descriptor to pathname function


https://sourceware.org/bugzilla/show_bug.cgi?id=17920

David Smith <dsmith at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dsmith at redhat dot com

--- Comment #1 from David Smith <dsmith at redhat dot com> ---
I looked into this today. I'm not sure it is possible to do, at least cleanly.

For reference's sake, here's what I came up with. Note that this only works on
semi-recent kernels (I developed this on rawhide -
4.3.0-0.rc2.git1.1.fc24.x86_64) and isn't correct with respect to locking data
structures. See comments for details.

====
function task_fd_lookup:long(task:long, fd:long)
%{
        struct task_struct *t = (struct task_struct *)(long)STAP_ARG_task;
        unsigned int fd = (unsigned int)(unsigned long)STAP_ARG_fd;
        struct files_struct *files = NULL;
        struct file *file = NULL;
        int put_task_struct_needed = 0;

        /* Before using the task_struct pointer, make sure it is valid
         * to read. */
        (void)kderef_buffer(NULL, t, sizeof(struct task_struct));

        get_task_struct(t);
        put_task_struct_needed = 1;

        // This is *wrong*. We should be calling get_files_struct()
        // here, but it isn't exported. This means that we can't lock
        // the files_struct. So, let's hope keeping the task_struct
        // usage count increased is enough.
        files = t->files;

        if (files) {
                /* Before using the files_struct pointer, make sure it is
                 * valid to read. */
                (void)kderef_buffer(NULL, files, sizeof(struct files_struct));

                spin_lock(&files->file_lock);
                file = fcheck_files(files, fd);
                spin_unlock(&files->file_lock);
        }

        if (file) {
                // Sigh. This is really wrong also. We're returning a
                // pointer which isn't locked or has had its usage
                // count increased. There is nothing keeping this
                // pointer valid until we use it later.
                STAP_RETURN(file);
        }
        else {
            STAP_ERROR ("cannot find file in task");
        }

        CATCH_DEREF_FAULT();
        if (put_task_struct_needed)
                put_task_struct(t);
%}

probe begin
{
    file = task_fd_lookup(task_current(), 0)
    println(fullpath_struct_path(&@cast(file, "file")->f_path))
    exit()
}
====

Note that this code doesn't handle pipes, sockets, etc., but that is the least
of the worries about the above code.

Perhaps a better way of going here would be put a probe on vfs.open, vfs.write,
and vfs.read and if you aren't in your target process skip the probe. Something
like this:

====
probe vfs.read, vfs.write
{
    if (pid() != target()) next
    printf("%s: %s\n", name, fullpath_struct_path(&file->f_path))
}

probe vfs.open
{
    if (pid() != target()) next
    printf("%s: %s\n", name, pathname)
}
====

====
# stap ./file_monitor.stp -c "/bin/ls /dev/null"
/dev/null
vfs.open: /usr/bin/ls
vfs.read: /usr/bin/ls
vfs.read: /usr/bin/ls
vfs.read: /usr/bin/ls
vfs.open: /usr/lib64/ld-2.22.90.so
vfs.read: /usr/lib64/ld-2.22.90.so
vfs.read: /usr/lib64/ld-2.22.90.so
vfs.open: /etc/ld.so.cache
vfs.open: /usr/lib64/libselinux.so.1
vfs.read: /usr/lib64/libselinux.so.1
vfs.open: /usr/lib64/libcap.so.2.24
vfs.read: /usr/lib64/libcap.so.2.24
vfs.open: /usr/lib64/libc-2.22.90.so
vfs.read: /usr/lib64/libc-2.22.90.so
vfs.open: /usr/lib64/libpcre.so.1.2.5
vfs.read: /usr/lib64/libpcre.so.1.2.5
vfs.open: /usr/lib64/libdl-2.22.90.so
vfs.read: /usr/lib64/libdl-2.22.90.so
vfs.open: /usr/lib64/libattr.so.1.1.0
vfs.read: /usr/lib64/libattr.so.1.1.0
vfs.open: /usr/lib64/libpthread-2.22.90.so
vfs.read: /usr/lib64/libpthread-2.22.90.so
vfs.open: /usr/lib/locale/locale-archive
vfs.write: /dev/pts/2
====

-- 
You are receiving this mail because:
You are the assignee for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]