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]

Re: How to get write/read offset?


On 03/10/2016 05:59 PM, Olausson, Bjoern wrote:
> On Thu, Mar 10, 2016 at 8:12 PM, David Smith <dsmith@redhat.com> wrote:
>> On 03/10/2016 06:32 AM, Olausson, Bjoern wrote:
>>> Hello Systemtap users,
>>>
>>> is there some straight forward way to get the offset for any read,
>>> write, pwrite etc. syscall?
>>>
>>> So for example if I trace the the IO to a file and the program issues
>>> a "seek" and writes reads n bytes starting from this position, is
>>> there any way to get that start position (offset) except from probing
>>> for an "seek" before a write/read?
>>>
>>> For example:
>>>
>>> probe syscall.write.return {
>>>  if (pid() == target()) {
>>>   time_stamp = timestamp()
>>>   p = pid()
>>>   fd = $fd
>>>   bytes = $return
>>>   latency = gettimeofday_us() - @entry(gettimeofday_us())
>>>   printf("%d;%d;%s;%s;%d;%d;%d\n", p, fd, filehandles[p, fd], name,
>>> bytes, time_stamp, latency)
>>>  }
>>> }
>>>
>>> If there is no straight forward way to get this information, what is
>>> the most native way to get the offset alongside with the time, latency
>>> and bytes_written/read?
>>
>> To get the file offset, you'll have to probe 1 level down. syscall.read
>> (sys_read()) is basically a wrapper around vfs.read (vfs_read()).
>> syscall.write (sys_write()) is basically a wrapper around vfs.write
>> (vfs_write()).
>>
>> So, you can (almost) replace syscall.write.return in your example above
>> with vfs.write.return. One of the differences are that you don't get $fd
>> anymore, instead you get a 'struct file' pointer.
>>
>>
>> --
>> David Smith
>> dsmith@redhat.com
>> Red Hat
>> http://www.redhat.com
>> 256.217.0141 (direct)
>> 256.837.0057 (fax)
> 
> Hello David,
> 
> thanks for the quick answer!
> 
> So far I managed to get what I want:
> --------------------------------------------------
> global start
> global filehandles
> 
> function timestamp:long() { return gettimeofday_us() - start }
> 
> probe begin {
>         start = gettimeofday_us()
>         printf("File Name;Syscall;Timestamp;Latency;Offset;Bytes to
> write/read;Bytes written/read;Bytes\n")
> }
> 
> probe generic.fop.open {
>         if (pid() == target()) {
>                  filehandles[ino] = filename
>         }
> }
> 
> probe vfs.write.return {
>         if (pid() == target()) {
>                 time_stamp = timestamp()
>                 latency = gettimeofday_us() - @entry(gettimeofday_us())
>                 #printf("%s\n", $$parms$$)
>                 offset = $file->f_pos
>                 filename = filehandles[ino]
>                 bytes = $return
>                 printf("%s;%s;%d;%d;%d;%d;%d;%d\n", filename, name,
> time_stamp, latency, offset, bytes_to_write, bytes_written, bytes)
>         }
> }
> 
> probe vfs.read.return {
>         if (pid() == target()) {
>                 time_stamp = timestamp()
>                 latency = gettimeofday_us() - @entry(gettimeofday_us())
>                 offset = $file->f_pos
>                 filename = filehandles[ino]
>                 bytes = $return
>                 printf("%s;%s;%d;%d;%d;%d;%d;%d\n", filename, name,
> time_stamp, latency, offset, bytes_to_read, bytes_read, bytes)
>         }
> }
> 
> #probe generic.fop.llseek.return {
> #       if (pid() == target()) {
> #               time_stamp = timestamp()
> #               latency = gettimeofday_us() - @entry(gettimeofday_us())
> #               ino = $file->
> #               filename = filehandles[ino]
> #               printf("%s;%s;%d;%d;%d;%d;%d;%d\n", filename, name,
> time_stamp, latency, offset)
> #       }
> #}
> --------------------------------------------------
> 
> I have three questions:
> 
> 1)
> How to get the inode info when I probe for a llseek to map it to a
> human readable filename.

In vfs.read, vfs.write, and generic.fop.lseek, you've got $file, which
is 'struct file' pointer. You can call the following:

fullpath_struct_file(task_current(), $file)

to get the full path for $file. That should simplify your script a bit
since you won't need the filehandles cache anymore.

> 2)
> When I read from e.g. /dev/urandom, "filename" in "generic.fop.open"
> is empty ("")

Hmm, I'm not sure on this one. Perhaps because that on a synthetic
filesystem?

> 3)
> Is there a direct way to get the filename from the array $file within
> vfs.{read|write|llseek}.return (I couldn't find it) so I can omit the
> mapping?

See above.

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)


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