⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iostat.c

📁 linux下查看系统工具原码,如IOSTAT等
💻 C
📖 第 1 页 / 共 3 页
字号:
    * 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("%-10s", shi->name);   if (strlen(shi->name) > 10)      printf("\n          ");   /*       rrq/s wrq/s   r/s   w/s  rsec  wsec  rqsz  qusz await svctm %util */   printf(" %6.2f %6.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);}/* *************************************************************************** * Write basic stats, read from /proc/stat, /proc/{diskstats,partitions} * or from sysfs *************************************************************************** */void write_basic_stat(int curr, unsigned long long itv, int flags, int fctr,		      struct io_hdr_stats *shi, struct io_stats *ioi,		      struct io_stats *ioj){   unsigned long long rd_sec, wr_sec;   printf("%-13s", shi->name);   if (strlen(shi->name) > 13)      printf("\n             ");   if (HAS_SYSFS(flags) ||       HAS_DISKSTATS(flags) || HAS_PPARTITIONS(flags)) {      /* Print stats coming from /sys or /proc/{diskstats,partitions} */      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);   }   else {      /* Print stats coming from /proc/stat */      printf(" %8.2f %12.2f %12.2f %10lu %10lu\n",	     S_VALUE(ioj->dk_drive, ioi->dk_drive, itv),	     S_VALUE(ioj->dk_drive_rblk, ioi->dk_drive_rblk, itv) / fctr,	     S_VALUE(ioj->dk_drive_wblk, ioi->dk_drive_wblk, itv) / fctr,	     (ioi->dk_drive_rblk - ioj->dk_drive_rblk) / fctr,	     (ioi->dk_drive_wblk - ioj->dk_drive_wblk) / fctr);   }}/* *************************************************************************** * Print everything now (stats and uptime) *************************************************************************** */int write_stat(int curr, int flags, struct tm *loc_time){   int dev, i, fctr = 1;   unsigned long long itv;   struct io_hdr_stats *shi = st_hdr_iodev;   struct io_stats *ioi, *ioj;   struct io_dlist *st_dev_list_i;   /*    * Under very special circumstances, STDOUT may become unavailable,    * This is what we try to guess here    */   if (write(STDOUT_FILENO, "", 0) == -1) {      perror("stdout");      exit(6);   }   /* Print time stamp */   if (DISPLAY_TIMESTAMP(flags)) {      strftime(timestamp, sizeof(timestamp), "%X", loc_time);      printf(_("Time: %s\n"), timestamp);   }   /*    * itv is multiplied by the number of processors.    * This is OK to compute CPU usage since the number of jiffies spent in the    * different modes (user, nice, etc.) is the sum of all the processors.    * But itv should be reduced to one processor before displaying disk    * utilization.    */   if (!comm_stats[!curr].uptime)      /*       * This is the first report displaying stats since system startup.       * Only in this case we admit that the interval may be greater       * than 0xffffffff, else it was an overflow.       */      itv = comm_stats[curr].uptime;   else      /* uptime in jiffies */      itv = (comm_stats[curr].uptime - comm_stats[!curr].uptime)	 & 0xffffffff;   if (!itv)      itv = 1;   if (!DISPLAY_DISK_ONLY(flags))      /* Display CPU utilization */      write_cpu_stat(curr, itv);   if (cpu_nr) {      /* On SMP machines, reduce itv to one processor (see note above) */      if (!comm_stats[!curr].uptime0)	 itv = comm_stats[curr].uptime0;      else	 itv = (comm_stats[curr].uptime0 - comm_stats[!curr].uptime0)	    & 0xffffffff;      if (!itv)	 itv = 1;   }   if (!DISPLAY_CPU_ONLY(flags)) {      /* Display stats header */      write_stat_header(flags, &fctr);      if (DISPLAY_EXTENDED(flags) &&	  (HAS_OLD_KERNEL(flags) || HAS_PLAIN_KERNEL24(flags))) {	 /* No extended stats with old 2.2-2.4 kernels */	 printf("\n");	 return 1;      }      for (i = 0; i < iodev_nr; i++, shi++) {	 if (shi->used) {		    if (dlist_idx && !HAS_SYSFS(flags)) {	       /*		* With sysfs, only stats for the requested devices are read.		* With /proc/{diskstats,partitions}, stats for every devices		* are read. Thus we need to check if stats for current device		* are to be displayed.		*/	       for (dev = 0; dev < dlist_idx; dev++) {		  st_dev_list_i = st_dev_list + dev;		  if (!strcmp(shi->name, st_dev_list_i->dev_name))		     break;	       }	       if (dev == dlist_idx)		  /* Device not found in list: don't display it */		  continue;	    }		    ioi = st_iodev[curr] + i;	    ioj = st_iodev[!curr] + i;	    if (!DISPLAY_UNFILTERED(flags)) {	       if (HAS_OLD_KERNEL(flags) ||		   HAS_PLAIN_KERNEL24(flags)) {		  if (!ioi->dk_drive)		     continue;	       }	       else {		  if (!ioi->rd_ios && !ioi->wr_ios)		     continue;	       }	    }	    if (DISPLAY_EXTENDED(flags))	       write_ext_stat(curr, itv, flags, fctr, shi, ioi, ioj);	    else	       write_basic_stat(curr, itv, flags, fctr, shi, ioi, ioj);	 }      }      printf("\n");   }   return 1;}/* *************************************************************************** * Main loop: read I/O stats from the relevant sources, * and display them. *************************************************************************** */void rw_io_stat_loop(int flags, long int count, struct tm *loc_time){   int curr = 1;   int next;   do {      /* Read kernel statistics (CPU, and possibly disks for old kernels) */      read_proc_stat(curr, flags);      if (dlist_idx) {	 /*	  * A device or partition name was entered on the command line,	  * with or without -p option (but not -p ALL).	  */	 if (HAS_DISKSTATS(flags) && !DISPLAY_PARTITIONS(flags))	    read_diskstats_stat(curr, flags);	 else if (HAS_SYSFS(flags))	    read_sysfs_dlist_stat(curr, flags);	 else if (HAS_PPARTITIONS(flags) && !DISPLAY_PARTITIONS(flags))	    read_ppartitions_stat(curr, flags);      }      else {	 /*	  * No devices nor partitions entered on the command line	  * (for example if -p ALL was used).	  */	 if (HAS_DISKSTATS(flags))	    read_diskstats_stat(curr, flags);	 else if (HAS_SYSFS(flags))	    read_sysfs_stat(curr,flags);	 else if (HAS_PPARTITIONS(flags))	    read_ppartitions_stat(curr, flags);      }      /* Save time */      get_localtime(loc_time);      /* Print results */      if ((next = write_stat(curr, flags, loc_time))	  && (count > 0))	 count--;      fflush(stdout);      if (count) {	 pause();	 if (next)	    curr ^= 1;      }   }   while (count);}/* *************************************************************************** * Main entry to the iostat program *************************************************************************** */int main(int argc, char **argv){   int it = 0, flags = 0;   int opt = 1;   int i;   long count = 1;   struct utsname header;   struct io_dlist *st_dev_list_i;   struct tm loc_time;#ifdef USE_NLS   /* Init National Language Support */   init_nls();#endif   /* Allocate structures for device list */   if (argc > 1)      salloc_dev_list(argc - 1);   /* Process args... */   while (opt < argc) {      if (!strcmp(argv[opt], "-p")) {	 flags |= I_D_PARTITIONS;	 if (argv[++opt] && (strspn(argv[opt], DIGITS) != strlen(argv[opt])) &&	     (strncmp(argv[opt], "-", 1))) {	    flags |= I_D_UNFILTERED;	    if (!strcmp(argv[opt], K_ALL)) {	       flags |= I_D_PART_ALL;	       opt++;	    }	    else {	       /* Store device name */	       i = update_dev_list(&dlist_idx, device_name(argv[opt++]));	       st_dev_list_i = st_dev_list + i;	       st_dev_list_i->disp_part = TRUE;	    }	 }	 else	    flags |= I_D_PART_ALL;      }      else if (!strncmp(argv[opt], "-", 1)) {	 for (i = 1; *(argv[opt] + i); i++) {	    switch (*(argv[opt] + i)) {	     case 'c':	       flags |= I_D_CPU_ONLY;	/* Display cpu usage only */	       flags &= ~I_D_DISK_ONLY;	       break;	     case 'd':	       flags |= I_D_DISK_ONLY;	/* Display disk utilization only */	       flags &= ~I_D_CPU_ONLY;	       break;		     case 'k':	       if (DISPLAY_MEGABYTES(flags))		  usage(argv[0]);	       flags |= I_D_KILOBYTES;	/* Display stats in kB/s */	       break;	     case 'm':	       if (DISPLAY_KILOBYTES(flags))		  usage(argv[0]);	       flags |= I_D_MEGABYTES;	/* Display stats in MB/s */	       break;	     case 't':	       flags |= I_D_TIMESTAMP;	/* Display timestamp */	       break;		     case 'x':	       flags |= I_D_EXTENDED;	/* Display extended stats */	       break;	     case 'V':			/* Print version number and exit */	       print_version();	       break;		     default:	       usage(argv[0]);	    }	 }	 opt++;      }      else if (!isdigit(argv[opt][0])) {	 flags |= I_D_UNFILTERED;	 if (strcmp(argv[opt], K_ALL))	    /* Store device name */	    update_dev_list(&dlist_idx, device_name(argv[opt++]));	 else	    opt++;      }      else if (!it) {	 interval = atol(argv[opt++]);	 if (interval < 1) 	   usage(argv[0]);	 count = -1;	 it = 1;      }      else {	 count = atol(argv[opt++]);	 if (count < 1)	   usage(argv[0]);      }   }   /* Linux does not provide extended stats for partitions */   if (DISPLAY_PARTITIONS(flags) && DISPLAY_EXTENDED(flags)) {      fprintf(stderr, _("-x and -p options are mutually exclusive\n"));      exit(1);   }   /* Ignore device list if '-p ALL' entered on the command line */   if (DISPLAY_PART_ALL(flags))      dlist_idx = 0;   /* Init structures according to machine architecture */   io_sys_init(&flags);   get_localtime(&loc_time);   /* Get system name, release number and hostname */   uname(&header);   print_gal_header(&loc_time,		    header.sysname, header.release, header.nodename);   printf("\n");   /* Set a handler for SIGALRM */   alarm_handler(0);   /* Main loop */   rw_io_stat_loop(flags, count, &loc_time);   return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -