Skip to content

Instantly share code, notes, and snippets.

@pstadler
Forked from daviderickson/writes.dtrace
Created March 18, 2017 18:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pstadler/97591a2e5eb4bdfe16787cc1a72b7314 to your computer and use it in GitHub Desktop.
Save pstadler/97591a2e5eb4bdfe16787cc1a72b7314 to your computer and use it in GitHub Desktop.
Dtrace script to print all written-to files in FreeNAS, and their average write rate every 10 seconds.
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option defaultargs
#pragma D option switchrate=10hz
#pragma D option dynvarsize=4m
#pragma D option cleanrate=30hz
dtrace:::BEGIN
{
max_secs = 10;
secs = max_secs;
}
vfs::vop_write:entry
{
this->vp = args[0];
}
vfs::vop_write:entry
/this->vp/
{
this->ncp = &(this->vp->v_cache_dst) != NULL ?
this->vp->v_cache_dst.tqh_first : 0;
this->fi_name = this->ncp ? (this->ncp->nc_name != 0 ?
stringof(this->ncp->nc_name) : "<unknown>") : "<unknown>";
this->mount = this->vp->v_mount; /* ptr to vfs we are in */
this->fi_fs = this->mount != 0 ? stringof(this->mount->mnt_stat.f_fstypename)
: "<unknown>"; /* filesystem */
this->fi_mount = this->mount != 0 ? stringof(this->mount->mnt_stat.f_mntonname)
: "<unknown>";
}
/* A short cut */
vfs::vop_write:entry
/this->vp == 0 || this->fi_fs == "devfs" || this->fi_fs == 0 ||
this->fi_fs == "<unknown>" || this->fi_name == "<unknown>"/
{
this->ncp = 0;
}
vfs::vop_write:entry
/this->ncp/
{
this->dvp = this->ncp->nc_dvp != NULL ?
(&(this->ncp->nc_dvp->v_cache_dst) != NULL ?
this->ncp->nc_dvp->v_cache_dst.tqh_first : 0) : 0;
self->name[1] = this->dvp != 0 ? (this->dvp->nc_name != 0 ?
stringof(this->dvp->nc_name) : "<unknown>") : "<unknown>";
}
vfs::vop_write:entry
/self->name[1] == "<unknown>" || this->fi_fs == "devfs" ||
this->fi_fs == 0 || this->fi_fs == "<unknown>" || self->name[1] == "/"
|| self->name[1] == 0/
{
this->dvp = 0;
}
vfs::vop_write:entry
/this->dvp/
{
this->dvp = this->dvp->nc_dvp != NULL ? (&(this->dvp->nc_dvp->v_cache_dst) != NULL
? this->dvp->nc_dvp->v_cache_dst.tqh_first : 0) : 0;
self->name[2] = this->dvp != 0 ? (this->dvp->nc_name != 0 ?
stringof(this->dvp->nc_name) : "\0") : "\0";
}
vfs::vop_write:entry
/this->dvp/
{
this->dvp = this->dvp->nc_dvp != NULL ? (&(this->dvp->nc_dvp->v_cache_dst) != NULL
? this->dvp->nc_dvp->v_cache_dst.tqh_first : 0) : 0;
self->name[3] = this->dvp != 0 ? (this->dvp->nc_name != 0 ?
stringof(this->dvp->nc_name) : "\0") : "\0";
}
/*
vfs::vop_write:entry
/this->fi_mount != 0/
{
printf("%s/", this->fi_mount);
}
vfs::vop_write:entry
/self->name[3] != 0/
{
printf("%s/", self->name[3]);
}
vfs::vop_write:entry
/self->name[2] != 0/
{
printf("%s/", self->name[2]);
}
vfs::vop_write:entry
/self->name[1] != 0/
{
printf("%s/%s\n", self->name[1], this->fi_name);
}
vfs::vop_write:entry
{
self->name[1] = 0;
self->name[2] = 0;
self->name[3] = 0;
}
*/
vfs::vop_write:entry
{
@testAgg[this->fi_name != 0 ? this->fi_name : "unknown"] = sum(args[1]->a_uio->uio_resid);
@testAgg["TOTAL"] = sum(args[1]->a_uio->uio_resid);
/* printf("Entry %d\n", args[1]->a_uio->uio_resid); */
self->name[1] = 0;
self->name[2] = 0;
self->name[3] = 0;
}
profile:::tick-1sec
{
secs--;
}
profile:::tick-1sec
/secs == 0/
{
secs = max_secs;
/* normalize from bytes per max_secs to KB/s */
normalize(@testAgg, 1024*max_secs);
printf("%-60s Average Write Rate Over %d seconds\n", "File Name", max_secs);
printa("%-60s %10@d KB/s\n", @testAgg);
printf("\n\n");
trunc(@testAgg);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment