double ll_s_value(unsigned long long value1, unsigned long long value2,
		  unsigned long long itv)
{
	if ((value2 < value1) && (value1 <= 0xffffffff))
		/* Counter's type was unsigned long and has overflown */
		return ((double) ((value2 - value1) & 0xffffffff)) / itv * HZ;
	else
		return S_VALUE(value1, value2, itv);
}
Exemple #2
0
/*
 ***************************************************************************
 * Write basic stats, read from /proc/diskstats or from sysfs.
 *
 * IN:
 * @curr	Index in array for current sample statistics.
 * @itv		Interval of time.
 * @fctr	Conversion factor.
 * @shi		Structures describing the devices and partitions.
 * @ioi		Current sample statistics.
 * @ioj		Previous sample statistics.
 ***************************************************************************
 */
void write_basic_stat(int curr, unsigned long long itv, int fctr,
		      struct io_hdr_stats *shi, struct io_stats *ioi,
		      struct io_stats *ioj)
{
	char *devname = NULL;
	unsigned long long rd_sec, wr_sec;

	/* Print device name */
	if (DISPLAY_PERSIST_NAME_I(flags)) {
		devname = get_persistent_name_from_pretty(shi->name);
	}
	if (!devname) {
		devname = shi->name;
	}
	if (DISPLAY_HUMAN_READ(flags)) {
		cprintf_in(IS_STR, "%s\n", devname, 0);
		printf("%13s", "");
	}
	else {
		cprintf_in(IS_STR, "%-13s", devname, 0);
	}

	/* Print stats coming from /sys or /proc/diskstats */
	rd_sec = ioi->rd_sectors - ioj->rd_sectors;
	if ((ioi->rd_sectors < ioj->rd_sectors) && (ioj->rd_sectors <= 0xffffffff)) {
		rd_sec &= 0xffffffff;
	}
	wr_sec = ioi->wr_sectors - ioj->wr_sectors;
	if ((ioi->wr_sectors < ioj->wr_sectors) && (ioj->wr_sectors <= 0xffffffff)) {
		wr_sec &= 0xffffffff;
	}

	cprintf_f(1, 8, 2,
		  S_VALUE(ioj->rd_ios + ioj->wr_ios, ioi->rd_ios + ioi->wr_ios, itv));
	cprintf_f(2, 12, 2,
		  S_VALUE(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
		  S_VALUE(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr);
	cprintf_u64(2, 10,
		    (unsigned long long) rd_sec / fctr,
		    (unsigned long long) wr_sec / fctr);
	printf("\n");
}
Exemple #3
0
/*
 ***************************************************************************
 * Write NFS stats read from /proc/self/mountstats.
 *
 * IN:
 * @curr	Index in array for current sample statistics.
 * @itv		Interval of time.
 * @fctr	Conversion factor.
 * @shi		Structures describing the NFS filesystems.
 * @ioi		Current sample statistics.
 * @ioj		Previous sample statistics.
 ***************************************************************************
 */
void write_nfs_stat(int curr, unsigned long long itv, int fctr,
		    struct io_hdr_stats *shi, struct io_nfs_stats *ioni,
		    struct io_nfs_stats *ionj)
{
	if (DISPLAY_HUMAN_READ(flags)) {
		printf("%-22s\n%23s", shi->name, "");
	}
	else {
		printf("%-22s ", shi->name);
	}
	printf("%12.2f %12.2f %12.2f %12.2f %12.2f %12.2f %9.2f %9.2f %9.2f\n",
	       S_VALUE(ionj->rd_normal_bytes, ioni->rd_normal_bytes, itv) / fctr,
	       S_VALUE(ionj->wr_normal_bytes, ioni->wr_normal_bytes, itv) / fctr,
	       S_VALUE(ionj->rd_direct_bytes, ioni->rd_direct_bytes, itv) / fctr,
	       S_VALUE(ionj->wr_direct_bytes, ioni->wr_direct_bytes, itv) / fctr,
	       S_VALUE(ionj->rd_server_bytes, ioni->rd_server_bytes, itv) / fctr,
	       S_VALUE(ionj->wr_server_bytes, ioni->wr_server_bytes, itv) / fctr,
	       S_VALUE(ionj->rpc_sends, ioni->rpc_sends, itv),
	       S_VALUE(ionj->nfs_rops,  ioni->nfs_rops,  itv),
	       S_VALUE(ionj->nfs_wops,  ioni->nfs_wops,  itv));
}
Exemple #4
0
/*
 ***************************************************************************
 * Compute "extended" device statistics (service time, etc.).
 *
 * IN:
 * @sdc		Structure with current device statistics.
 * @sdp		Structure with previous device statistics.
 * @itv		Interval of time in jiffies.
 *
 * OUT:
 * @xds		Structure with extended statistics.
 ***************************************************************************
*/
void compute_ext_disk_stats(struct stats_disk *sdc, struct stats_disk *sdp,
			    unsigned long long itv, struct ext_disk_stats *xds)
{
	double tput
		= ((double) (sdc->nr_ios - sdp->nr_ios)) * HZ / itv;

	xds->util  = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv);
	xds->svctm = tput ? xds->util / tput : 0.0;
	/*
	 * Kernel gives ticks already in milliseconds for all platforms
	 * => no need for further scaling.
	 */
	xds->await = (sdc->nr_ios - sdp->nr_ios) ?
		((sdc->rd_ticks - sdp->rd_ticks) + (sdc->wr_ticks - sdp->wr_ticks)) /
		((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
	xds->arqsz = (sdc->nr_ios - sdp->nr_ios) ?
		((sdc->rd_sect - sdp->rd_sect) + (sdc->wr_sect - sdp->wr_sect)) /
		((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
}
/*
 ***************************************************************************
 * Write CIFS stats read from /proc/fs/cifs/Stats.
 *
 * IN:
 * @curr	Index in array for current sample statistics.
 * @itv		Interval of time.
 * @fctr	Conversion factor.
 * @shi		Structures describing the CIFS filesystems.
 * @ioi		Current sample statistics.
 * @ioj		Previous sample statistics.
 ***************************************************************************
 */
void write_cifs_stat(int curr, unsigned long long itv, int fctr,
		     struct io_hdr_stats *shi, struct cifs_stats *ioni,
		     struct cifs_stats *ionj)
{
	if (DISPLAY_HUMAN_READ(flags)) {
		printf("%-22s\n%23s", shi->name, "");
	}
	else {
		printf("%-22s ", shi->name);
	}

	/*       rB/s   wB/s   fo/s   fc/s   fd/s*/
	printf("%12.2f %12.2f %9.2f %9.2f %12.2f %12.2f %12.2f \n",
	       S_VALUE(ionj->rd_bytes, ioni->rd_bytes, itv) / fctr,
	       S_VALUE(ionj->wr_bytes, ioni->wr_bytes, itv) / fctr,
	       S_VALUE(ionj->rd_ops, ioni->rd_ops, itv),
	       S_VALUE(ionj->wr_ops, ioni->wr_ops, itv),
	       S_VALUE(ionj->fopens, ioni->fopens, itv),
	       S_VALUE(ionj->fcloses, ioni->fcloses, itv),
	       S_VALUE(ionj->fdeletes, ioni->fdeletes, itv));
}
Exemple #6
0
/*
 ***************************************************************************
 * Write basic stats, read from /proc/diskstats or from sysfs.
 *
 * IN:
 * @curr	Index in array for current sample statistics.
 * @itv		Interval of time.
 * @fctr	Conversion factor.
 * @shi		Structures describing the devices and partitions.
 * @ioi		Current sample statistics.
 * @ioj		Previous sample statistics.
 ***************************************************************************
 */
void write_basic_stat(int curr, unsigned long long itv, int fctr,
		      struct io_hdr_stats *shi, struct io_stats *ioi,
		      struct io_stats *ioj)
{
	char *devname = NULL;
	unsigned long long rd_sec, wr_sec;

	/* Print device name */
	if (DISPLAY_PERSIST_NAME_I(flags)) {
		devname = get_persistent_name_from_pretty(shi->name);
	}
	if (!devname) {
		devname = shi->name;
	}
	if (DISPLAY_HUMAN_READ(flags)) {
		printf("%s\n%13s", devname, "");
	}
	else {
		printf("%-13s", devname);
	}

	/* Print stats coming from /sys or /proc/diskstats */
	rd_sec = ioi->rd_sectors - ioj->rd_sectors;
	if ((ioi->rd_sectors < ioj->rd_sectors) && (ioj->rd_sectors <= 0xffffffff)) {
		rd_sec &= 0xffffffff;
	}
	wr_sec = ioi->wr_sectors - ioj->wr_sectors;
	if ((ioi->wr_sectors < ioj->wr_sectors) && (ioj->wr_sectors <= 0xffffffff)) {
		wr_sec &= 0xffffffff;
	}

	printf(" %8.2f %12.2f %12.2f %10llu %10llu\n",
	       S_VALUE(ioj->rd_ios + ioj->wr_ios, ioi->rd_ios + ioi->wr_ios, itv),
	       ll_s_value(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
	       ll_s_value(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr,
	       (unsigned long long) rd_sec / fctr,
	       (unsigned long long) wr_sec / fctr);
}
Exemple #7
0
/*
 ***************************************************************************
 * Display extended stats, read from /proc/{diskstats,partitions} or /sys.
 *
 * IN:
 * @curr	Index in array for current sample statistics.
 * @itv		Interval of time.
 * @fctr	Conversion factor.
 * @shi		Structures describing the devices and partitions.
 * @ioi		Current sample statistics.
 * @ioj		Previous sample statistics.
 ***************************************************************************
 */
void write_ext_stat(int curr, unsigned long long itv, int fctr,
		    struct io_hdr_stats *shi, struct io_stats *ioi,
		    struct io_stats *ioj)
{
	char *devname = NULL;
	struct stats_disk sdc, sdp;
	struct ext_disk_stats xds;
	double r_await, w_await;

	/*
	 * Counters overflows are possible, but don't need to be handled in
	 * a special way: The difference is still properly calculated if the
	 * result is of the same type as the two values.
	 * Exception is field rq_ticks which is incremented by the number of
	 * I/O in progress times the number of milliseconds spent doing I/O.
	 * But the number of I/O in progress (field ios_pgr) happens to be
	 * sometimes negative...
	 */
	sdc.nr_ios    = ioi->rd_ios + ioi->wr_ios;
	sdp.nr_ios    = ioj->rd_ios + ioj->wr_ios;

	sdc.tot_ticks = ioi->tot_ticks;
	sdp.tot_ticks = ioj->tot_ticks;

	sdc.rd_ticks  = ioi->rd_ticks;
	sdp.rd_ticks  = ioj->rd_ticks;
	sdc.wr_ticks  = ioi->wr_ticks;
	sdp.wr_ticks  = ioj->wr_ticks;

	sdc.rd_sect   = ioi->rd_sectors;
	sdp.rd_sect   = ioj->rd_sectors;
	sdc.wr_sect   = ioi->wr_sectors;
	sdp.wr_sect   = ioj->wr_sectors;

	compute_ext_disk_stats(&sdc, &sdp, itv, &xds);

	r_await = (ioi->rd_ios - ioj->rd_ios) ?
		  (ioi->rd_ticks - ioj->rd_ticks) /
		  ((double) (ioi->rd_ios - ioj->rd_ios)) : 0.0;
	w_await = (ioi->wr_ios - ioj->wr_ios) ?
		  (ioi->wr_ticks - ioj->wr_ticks) /
		  ((double) (ioi->wr_ios - ioj->wr_ios)) : 0.0;

	/* Print device name */
	if (DISPLAY_PERSIST_NAME_I(flags)) {
		devname = get_persistent_name_from_pretty(shi->name);
	}
	if (!devname) {
		devname = shi->name;
	}
	if (DISPLAY_HUMAN_READ(flags)) {
		printf("%s\n%13s", devname, "");
	}
	else {
		printf("%-13s", devname);
	}

	/*       rrq/s wrq/s   r/s   w/s  rsec  wsec  rqsz  qusz await r_await w_await svctm %util */
	printf(" %8.2f %8.2f %7.2f %7.2f %8.2f %8.2f %8.2f %8.2f %7.2f %7.2f %7.2f %6.2f %6.2f\n",
	       S_VALUE(ioj->rd_merges, ioi->rd_merges, itv),
	       S_VALUE(ioj->wr_merges, ioi->wr_merges, itv),
	       S_VALUE(ioj->rd_ios, ioi->rd_ios, itv),
	       S_VALUE(ioj->wr_ios, ioi->wr_ios, itv),
	       S_VALUE(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
	       S_VALUE(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr,
	       xds.arqsz,
	       S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0,
	       xds.await,
	       r_await,
	       w_await,
	       /* The ticks output is biased to output 1000 ticks per second */
	       xds.svctm,
	       /*
	        * Again: Ticks in milliseconds.
		* In the case of a device group (option -g), shi->used is the number of
		* devices in the group. Else shi->used equals 1.
		*/
	       shi->used ? xds.util / 10.0 / (double) shi->used
	                 : xds.util / 10.0);	/* shi->used should never be null here */
}
Exemple #8
0
/*
 ***************************************************************************
 * Display extended stats, read from /proc/{diskstats,partitions} or /sys
 ***************************************************************************
 */
void write_ext_stat(int curr, unsigned long long itv, int flags, int fctr,
		    struct io_hdr_stats *shi, struct io_stats *ioi,
		    struct io_stats *ioj, int scan_type, int first_time )
{
   unsigned long long rd_sec, wr_sec;
   double tput, util, await, svctm, arqsz, nr_ios;

   int size, year, mon, day, hour, min, sec;
	
   /*
    * Counters overflows are possible, but don't need to be handled in
    * a special way: the difference is still properly calculated if the
    * result is of the same type as the two values.
    * Exception is field rq_ticks which is incremented by the number of
    * I/O in progress times the number of milliseconds spent doing I/O.
    * But the number of I/O in progress (field ios_pgr) happens to be
    * sometimes negative...
    */
   nr_ios = (ioi->rd_ios - ioj->rd_ios) + (ioi->wr_ios - ioj->wr_ios);
   tput = ((double) nr_ios) * HZ / itv;
   util = S_VALUE(ioj->tot_ticks, ioi->tot_ticks, itv);
   svctm = tput ? util / tput : 0.0;
   /*
    * kernel gives ticks already in milliseconds for all platforms
    * => no need for further scaling.
    */
   await = nr_ios ?
      ((ioi->rd_ticks - ioj->rd_ticks) + (ioi->wr_ticks - ioj->wr_ticks)) /
      nr_ios : 0.0;

   rd_sec = ioi->rd_sectors - ioj->rd_sectors;
   if ((ioi->rd_sectors < ioj->rd_sectors) && (ioj->rd_sectors <= 0xffffffff))
      rd_sec &= 0xffffffff;
   wr_sec = ioi->wr_sectors - ioj->wr_sectors;
   if ((ioi->wr_sectors < ioj->wr_sectors) && (ioj->wr_sectors <= 0xffffffff))
      wr_sec &= 0xffffffff;

   arqsz = nr_ios ? (rd_sec + wr_sec) / nr_ios : 0.0;

/*   printf("%-13s", shi->name); 
   if (strlen(shi->name) > 10)
      printf("\n          ");
*/
   memcpy( &Disk_usage.device, shi->name, strlen(shi->name) );

   /*       rrq/s wrq/s   r/s   w/s  rsec  wsec  rqsz  qusz await svctm %util */
/*   printf(" %8.2f %8.2f %5.2f %5.2f %8.2f %8.2f %8.2f %8.2f %7.2f %6.2f %6.2f\n",
	  S_VALUE(ioj->rd_merges, ioi->rd_merges, itv),
	  S_VALUE(ioj->wr_merges, ioi->wr_merges, itv),
	  S_VALUE(ioj->rd_ios, ioi->rd_ios, itv),
	  S_VALUE(ioj->wr_ios, ioi->wr_ios, itv),
	  ll_s_value(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
	  ll_s_value(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr,
	  arqsz,
	  S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0,
	  await,
*/
	  /* The ticks output is biased to output 1000 ticks per second */
/*
	  svctm,
*/
	  /* Again: ticks in milliseconds */
/*
	  util / 10.0);
*/

    Disk_usage.read_requests = S_VALUE(ioj->rd_ios, ioi->rd_ios, itv);
    Disk_usage.write_requests = S_VALUE(ioj->wr_ios, ioi->wr_ios, itv);
    Disk_usage.kb_read = ll_s_value(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr;
    Disk_usage.kb_write = ll_s_value(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr;
    Disk_usage.await = await;
    Disk_usage.svctm = svctm;
    Disk_usage.util = util / 10.0;

    Total_kb_read += Disk_usage.kb_read;
    Total_kb_write += Disk_usage.kb_write;
    Total_await += await;
    Total_svctm += svctm;
    Total_util += Disk_usage.util;
    Total_reports++;

    /* If the gnuplot file is open, write Disk stats to file. */
    if( Disk_fd < 0 )
       return;

    /* Did a start of volume event occur? */
    if( VOLUME_EVENT == scan_type ){

        unix_time( &Scan_info.scan_time, &year, &mon, &day, &hour, &min, &sec );
        if( year >= 2000 )
            year -= 2000;

        else
            year -= 1900;

        /* Do only the first time through. */
        if( first_time ){

          memset( Buffer, 0, sizeof(Buffer) );
          sprintf( Buffer, "#===========================================================\
==========================================\n" );

          size = strlen( Buffer );
          if( write( Disk_fd, Buffer, size ) != size )
              fprintf( stderr, "Write to Disk_fd Failed\n" );

           memset( Buffer, 0, sizeof(Buffer) );
           sprintf( Buffer, "# %02d/%02d/%02d %02d:%02d:%02d   VOLUME #: %4d   VCP: %3d\n",
                    mon, day, year, hour, min, sec, Volume_num, Scan_info.vcp );

           size = strlen( Buffer );
           if( write( Disk_fd, Buffer, size ) != size )
              fprintf( stderr, "Write to Disk_fd Failed\n" );

           memset( Buffer, 0, sizeof(Buffer) );
           sprintf( Buffer,"# Cut    Time (s)    Total (s)      Read (KB)    Write (KB)    Await (ms)  \
SvcTime (ms)      Util (%%)\n" );    

           size = strlen( Buffer );
           if( write( Disk_fd, Buffer, size ) != size )
               fprintf( stderr, "Write to Disk_fd Failed\n" );

        }

    }