This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: How to get write/read offset?
- From: "Olausson, Bjoern" <contactme at olausson dot de>
- To: David Smith <dsmith at redhat dot com>
- Cc: systemtap at sourceware dot org
- Date: Fri, 11 Mar 2016 00:59:55 +0100
- 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>
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.
2)
When I read from e.g. /dev/urandom, "filename" in "generic.fop.open"
is empty ("")
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?
Thanks a lot for your support!
Greetings,
Bjoern