Skip to content

Instantly share code, notes, and snippets.

@pstadler
Forked from daviderickson/writes.dtrace
Created March 18, 2017 18:25

Revisions

  1. @daviderickson daviderickson created this gist Apr 3, 2016.
    138 changes: 138 additions & 0 deletions writes.dtrace
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,138 @@
    #!/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);
    }