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