Paul van der Zwan
2006-Mar-24 14:37 UTC
[dtrace-discuss] Triggering on close of a written file.
I have just started my first ''serious'' dtrace script and can
use some
advice.
I want to have a probe triggered when close() occurs after a
succesfull write of /etc/hosts ( I want to regenerate the nameserver
zone files
from /etc/hosts after it has changed)
At the moment I have the following code:
syscall::open*:entry,
syscall::creat*:entry
{
self->file=arg0;
}
syscall::open*:return,
syscall::creat*:return
/basename(copyinstr(self->file)) == "hosts"/
{
self->hostsfd=arg1;
/* printf("Filename=%s fd=%d",basename(copyinstr(self-
>file)),arg1); */
}
syscall::write:entry
/arg0==self->hostsfd/
{
/* trace("Write hosts"); */
self->hostswritten=1;
}
syscall::close:entry
/arg0==self->hostsfd && self->hostswritten==1/
{
system("/usr/local/bin/regen-zonefiles");
self->hostsfd=-1 ;
}
Is there an easier/better way to do this, I think this script fails
to detect a failed write, what is the best way to do that...
Paul
Adam Leventhal
2006-Mar-24 18:16 UTC
[dtrace-discuss] Triggering on close of a written file.
Hi Paul, You''re correct that this script fails to detect a failed write. You can examine the value returned from write (arg1 in syscall::write:return) to check for errors. Another problem is that this script assumes a single- threaded process or at least that a single thread is opening, writing, and closing /etc/hosts. If you want to deal with a multi-threaded process you could use an associative array keyed by the pid rather than thread-local variables. Adam On Fri, Mar 24, 2006 at 03:37:32PM +0100, Paul van der Zwan wrote:> I have just started my first ''serious'' dtrace script and can use some > advice. > > I want to have a probe triggered when close() occurs after a > succesfull write of /etc/hosts ( I want to regenerate the nameserver > zone files > from /etc/hosts after it has changed) > > At the moment I have the following code: > > syscall::open*:entry, > syscall::creat*:entry > { > self->file=arg0; > } > > syscall::open*:return, > syscall::creat*:return > /basename(copyinstr(self->file)) == "hosts"/ > { > self->hostsfd=arg1; > /* printf("Filename=%s fd=%d",basename(copyinstr(self- > >file)),arg1); */ > } > > syscall::write:entry > /arg0==self->hostsfd/ > { > /* trace("Write hosts"); */ > self->hostswritten=1; > } > > syscall::close:entry > /arg0==self->hostsfd && self->hostswritten==1/ > { > system("/usr/local/bin/regen-zonefiles"); > self->hostsfd=-1 ; > } > > > Is there an easier/better way to do this, I think this script fails > to detect a failed write, what is the best way to do that... > > > Paul > > > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl
Paul van der Zwan,???
I don''t get an easier/better way to do this, just add
"write:retuen" to detect a failed write.
syscall::write:return
/self->hostswritten==1 && arg1 < 0 /
{
/* trace("Write failed"); */
self->hostswritten=0;
}
======= 2006-03-24 22:37:32 ????????======>
>I have just started my first ''serious'' dtrace script and
can use some
>advice.
>
>I want to have a probe triggered when close() occurs after a
>succesfull write of /etc/hosts ( I want to regenerate the nameserver
>zone files
>from /etc/hosts after it has changed)
>
>At the moment I have the following code:
>
>syscall::open*:entry,
>syscall::creat*:entry
>{
> self->file=arg0;
>}
>
>syscall::open*:return,
>syscall::creat*:return
>/basename(copyinstr(self->file)) == "hosts"/
>{
> self->hostsfd=arg1;
>/* printf("Filename=%s fd=%d",basename(copyinstr(self-
> >file)),arg1); */
>}
>
>syscall::write:entry
>/arg0==self->hostsfd/
>{
> /* trace("Write hosts"); */
> self->hostswritten=1;
>}
>
>syscall::close:entry
>/arg0==self->hostsfd && self->hostswritten==1/
>{
> system("/usr/local/bin/regen-zonefiles");
> self->hostsfd=-1 ;
>}
>
>
>Is there an easier/better way to do this, I think this script fails
>to detect a failed write, what is the best way to do that...
>
>
> Paul
>
>
>_______________________________________________
>dtrace-discuss mailing list
>dtrace-discuss at opensolaris.org
>
= = = = = = = = = = = = = = = = = = =
?????????
??
????????zheh
????????zheh at 163.com
??????????2006-03-25
On Sat, 25 Mar 2006, zheh wrote:> Paul van der Zwan,?????? > > I don''t get an easier/better way to do this, just add "write:retuen" to detect a failed write. > > syscall::write:return > /self->hostswritten==1 && arg1 < 0 / > { > /* trace("Write failed"); */ > self->hostswritten=0; > }Hi Paul, There is a good example of analyzing open() system call errors in /usr/demo/dtrace/specopen.d. The script uses speculations, which can be super useful for commiting traced data when an error occurs (this may not be needed in your case). Hope this helps, - Ryan -- UNIX Administrator http://daemons.net/~matty