This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: How to get write/read offset?
- From: David Smith <dsmith at redhat dot com>
- To: "Olausson, Bjoern" <contactme at olausson dot de>
- Cc: systemtap at sourceware dot org
- Date: Fri, 11 Mar 2016 10:59:46 -0600
- Subject: Re: How to get write/read offset?
- Authentication-results: sourceware.org; auth=none
- References: <CAE7O3Tc5T8UfZgJegQ8H6mZ7r+fd+kSMtPUd9EmLvVS=S2ZyVQ at mail dot gmail dot com> <56E1C72B dot 1080402 at redhat dot com> <CAE7O3TcWYCkBPZO5JMLN7U7fDV9x634Qt2nx7kX_doS-32kLyw at mail dot gmail dot com> <56E2DB9D dot 5080901 at redhat dot com> <CAE7O3TcCYhi6oWPM3E6hBi75xzY7XyiEObQQtGDa7=wZxT8NRQ at mail dot gmail dot com>
On 03/11/2016 09:35 AM, Olausson, Bjoern wrote:
> On Fri, Mar 11, 2016 at 3:52 PM, David Smith <dsmith@redhat.com> wrote:
>> 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.
>>
> To bad, this function is implemented in SystemTap as of 2.9 when I am
> not mistaken and I am on CentOS 7 with SystemTap 2.8.
> I might give it a try to compile 2.9 or 3.0 on CentoOS 7
Ah, sorry. You should be able to write fullpath_struct_file() yourself.
It is just a wrapper around task_dentry_path(), which should already be
in 2.8. So, just steal the definition from the following link and add it
to your script.
<https://www.sourceware.org/git/gitweb.cgi?p=systemtap.git;a=blob;f=tapset/linux/dentry.stp;h=061876736abd6c56a55afb46442ef54c0b16f06c;hb=HEAD>
>>> 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?
>>
> I get the name "urandom" from $file for the probes vfs.{read|write}
> But that still does not explain why the name is empty on that fop
> probe.
> But it is not a big issue.
>
>
>>> 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.
>
> There seem to be many ways to get what one wants :) I found that one:
> filename = __file_filename(file)
>
> Is there somewhere a documentation of those helpers like __file_filename etc?
No, not really. Anything that starts with '__' is meant to be an
internal function or variable.
--
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)