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

📄 sadc.c

📁 linux下查看系统工具原码,如IOSTAT等
💻 C
📖 第 1 页 / 共 4 页
字号:
   int nb;   struct tm loc_time;   /* Check if file is locked */   if (!FILE_LOCKED(*flags))      ask_for_flock(ofd, flags, FATAL);   /* Reset the structure (not compulsory, but a bit cleaner */   memset(&file_stats, 0, FILE_STATS_SIZE);   file_stats.record_type = R_DUMMY;   /* Save time */   file_stats.ust_time = get_localtime(&loc_time);   file_stats.hour   = loc_time.tm_hour;   file_stats.minute = loc_time.tm_min;   file_stats.second = loc_time.tm_sec;   /* Write record now */   if ((nb = write(ofd, &file_stats, file_stats_size)) != file_stats_size)      p_write_error();}/* *************************************************************************** * Write stats. * NB: sadc provides all the stats, including: * -> CPU utilization per processor (on SMP machines only) * -> IRQ per processor (on SMP machines only) * -> number of each IRQ (if -I option passed to sadc), including APIC *    interrupts sources * -> device stats for sar -d (kernels 2.4 and newer only, and only if *    -d option passed to sadc) *************************************************************************** */void write_stats(int ofd, size_t file_stats_size, unsigned int *flags){   int nb;   /* Try to lock file */   if (!FILE_LOCKED(*flags)) {      if (ask_for_flock(ofd, flags, NON_FATAL))	 /* Unable to lock file: wait for next iteration to try again to save data */	 return;   }   if ((nb = write(ofd, &file_stats, file_stats_size)) != file_stats_size)      p_write_error();   if (cpu_nr > 0) {      if ((nb = write(ofd, st_cpu, STATS_ONE_CPU_SIZE * (cpu_nr + 1))) != (STATS_ONE_CPU_SIZE * (cpu_nr + 1)))	 p_write_error();   }   if (GET_ONE_IRQ(sadc_actflag)) {      if ((nb = write(ofd, interrupts, STATS_ONE_IRQ_SIZE)) != STATS_ONE_IRQ_SIZE)	 p_write_error();   }   if (pid_nr) {      /* Structures are packed together! */      if ((nb = write(ofd, pid_stats[0], PID_STATS_SIZE * pid_nr)) != (PID_STATS_SIZE * pid_nr))	 p_write_error();   }   if (serial_nr) {      if ((nb = write(ofd, st_serial, STATS_SERIAL_SIZE * serial_nr)) != (STATS_SERIAL_SIZE * serial_nr))	 p_write_error();   }   if (irqcpu_nr) {      if ((nb = write(ofd, st_irq_cpu, STATS_IRQ_CPU_SIZE * (cpu_nr + 1) * irqcpu_nr))	  != (STATS_IRQ_CPU_SIZE * (cpu_nr + 1) * irqcpu_nr))	 p_write_error();   }   if (iface_nr) {      if ((nb = write(ofd, st_net_dev, STATS_NET_DEV_SIZE * iface_nr)) != (STATS_NET_DEV_SIZE * iface_nr))	 p_write_error();   }   if (disk_nr && GET_DISK(sadc_actflag)) {      /* Disk stats written only if -d option used */      if ((nb = write(ofd, st_disk, DISK_STATS_SIZE * disk_nr)) != (DISK_STATS_SIZE * disk_nr))	 p_write_error();   }}/* *************************************************************************** * Create a system activity daily data file *************************************************************************** */void create_sa_file(int *ofd, char *ofile, size_t *file_stats_size,		    unsigned int *flags){   if ((*ofd = open(ofile, O_CREAT | O_WRONLY,		    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {      fprintf(stderr, _("Cannot open %s: %s\n"), ofile, strerror(errno));      exit(2);   }   /* Try to lock file */   ask_for_flock(*ofd, flags, FATAL);   /* Truncate file */   if (ftruncate(*ofd, 0) < 0) {      fprintf(stderr, _("Cannot open %s: %s\n"), ofile, strerror(errno));      exit(2);   }   /* Write file header */   setup_file_hdr(*ofd, file_stats_size);}/* *************************************************************************** * Get descriptor for stdout. *************************************************************************** */void open_stdout(int *stdfd, size_t *file_stats_size){   if (*stdfd >= 0) {      if ((*stdfd = dup(STDOUT_FILENO)) < 0) {	 perror("dup");	 exit(4);      }      /* Write file header on STDOUT */      setup_file_hdr(*stdfd, file_stats_size);   }}/* *************************************************************************** * Get descriptor for output file and write its header. * We may enter this function several times (when we rotate a file). *************************************************************************** */void open_ofile(int *ofd, char ofile[], size_t *file_stats_size, unsigned int *flags){   ssize_t size;   if (ofile[0]) {      /* Does file exist? */      if (access(ofile, F_OK) < 0)	 /* NO: create it */	 create_sa_file(ofd, ofile, file_stats_size, flags);      else {	 /* YES: append data to it if possible */	 if ((*ofd = open(ofile, O_APPEND | O_RDWR)) < 0) {	    fprintf(stderr, _("Cannot open %s: %s\n"), ofile, strerror(errno));	    exit(2);	 }		 /* Read file header */	 size = read(*ofd, &file_hdr, FILE_HDR_SIZE);	 if (!size) {	    close(*ofd);	    /* This is an empty file: create it again */	    create_sa_file(ofd, ofile, file_stats_size, flags);	    return;	 }	 if ((size != FILE_HDR_SIZE) || (file_hdr.sa_magic != SA_MAGIC)) {	    close(*ofd);	    if (USE_F_OPTION(*flags)) {	       /* -F option used: Truncate file */	       create_sa_file(ofd, ofile, file_stats_size, flags);	       return;	    }	    fprintf(stderr, _("Invalid system activity file: %s (%#x)\n"),		    ofile, file_hdr.sa_magic);	    exit(3);	 }	 /*	  * Ok: it's a true system activity file.	  * File activity flag prevails over that of the user	  * e.g. for the A_ONE_IRQ activity...	  * Same thing with file file_stats size.	  */	 sadc_actflag     = file_hdr.sa_actflag;	 *file_stats_size = file_hdr.sa_st_size;	 if (file_hdr.sa_proc != cpu_nr) {	    close(*ofd);	    if (USE_F_OPTION(*flags)) {	       create_sa_file(ofd, ofile, file_stats_size, flags);	       return;	    }	    fprintf(stderr, _("Cannot append data to that file\n"));	    exit(1);	 }		 /*	  * Force characteristics (nb of serial lines, network interfaces...)	  * to that of the file.	  */	 if (file_hdr.sa_serial != serial_nr) {	    serial_nr = file_hdr.sa_serial;	    SREALLOC(st_serial, struct stats_serial, STATS_SERIAL_SIZE * serial_nr);	 }	 if (file_hdr.sa_iface != iface_nr) {	    iface_nr = file_hdr.sa_iface;	    SREALLOC(st_net_dev, struct stats_net_dev, STATS_NET_DEV_SIZE * iface_nr);	 }	 if (file_hdr.sa_irqcpu != irqcpu_nr) {	    irqcpu_nr = file_hdr.sa_irqcpu;	    SREALLOC(st_irq_cpu, struct stats_irq_cpu,		     STATS_IRQ_CPU_SIZE * (cpu_nr + 1) * irqcpu_nr);	 }	 if (file_hdr.sa_nr_disk != disk_nr) {	    if (!file_hdr.sa_nr_disk)	       /* Remove use of option -d */	       sadc_actflag &= ~A_DISK;	    else {	       disk_nr = file_hdr.sa_nr_disk;	       SREALLOC(st_disk, struct disk_stats, DISK_STATS_SIZE * disk_nr);	    }	 }      }   }}/* *************************************************************************** * Read stats from /proc/stat *************************************************************************** */void read_proc_stat(unsigned int flags){   FILE *fp;   struct stats_one_cpu *st_cpu_i;   struct disk_stats *st_disk_i;   static char line[8192];   unsigned long long cc_user, cc_nice, cc_system, cc_hardirq, cc_softirq;   unsigned long long cc_idle, cc_iowait, cc_steal;   unsigned int v_tmp[5], v_major, v_index;   int proc_nb, i, pos;   if ((fp = fopen(STAT, "r")) == NULL) {      fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));      exit(2);   }   while (fgets(line, 8192, fp) != NULL) {      if (!strncmp(line, "cpu ", 4)) {	 /*	  * Read the number of jiffies spent in the different modes	  * (user, nice, etc.) among all proc. CPU usage is not reduced	  * to one processor to avoid rounding problems.	  */	 file_stats.cpu_iowait = 0;	/* For pre 2.5 kernels */	 file_stats.cpu_steal = 0;	 cc_hardirq = cc_softirq = 0;	 sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu",		&(file_stats.cpu_user),   &(file_stats.cpu_nice),		&(file_stats.cpu_system), &(file_stats.cpu_idle),		&(file_stats.cpu_iowait), &cc_hardirq, &cc_softirq,		&(file_stats.cpu_steal));	 /*	  * Time spent in system mode also includes time spent	  * servicing hard interrrupts and softirqs.	  */	 file_stats.cpu_system += cc_hardirq + cc_softirq;		 /*	  * Compute the uptime of the system in jiffies (1/100ths of a second	  * if HZ=100).	  * Machine uptime is multiplied by the number of processors here.	  * Note that overflow is not so far away: ULONG_MAX is 4294967295 on	  * 32 bit systems. Overflow happens when machine uptime is:	  * 497 days on a monoprocessor machine,	  * 248 days on a bi processor,	  * 124 days on a quad processor...	  */	 file_stats.uptime = file_stats.cpu_user   + file_stats.cpu_nice +	                     file_stats.cpu_system + file_stats.cpu_idle +	                     file_stats.cpu_iowait + file_stats.cpu_steal;      }      else if (!strncmp(line, "cpu", 3)) {	 if (cpu_nr > 0) {	    /*	     * Read the number of jiffies spent in the different modes	     * (user, nice, etc) for current proc.	     * This is done only on SMP machines.	     * Warning: st_cpu_i struct is _not_ allocated even if the kernel	     * has SMP support enabled.	     */	    cc_iowait = cc_steal = 0;	/* For pre 2.5 kernels */	    cc_hardirq = cc_softirq = 0;	    sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu",		   &proc_nb,		   &cc_user, &cc_nice, &cc_system, &cc_idle, &cc_iowait,		   &cc_hardirq, &cc_softirq, &cc_steal);	    cc_system += cc_hardirq + cc_softirq;		    if (proc_nb <= cpu_nr) {	       st_cpu_i = st_cpu + proc_nb;	       st_cpu_i->per_cpu_user   = cc_user;	       st_cpu_i->per_cpu_nice   = cc_nice;	       st_cpu_i->per_cpu_system = cc_system;	       st_cpu_i->per_cpu_idle   = cc_idle;	       st_cpu_i->per_cpu_iowait = cc_iowait;	       st_cpu_i->per_cpu_steal  = cc_steal;	    }	    /* else:	     * Additional CPUs have been dynamically registered in /proc/stat.	     * sar won't crash, but the CPU stats might be false...	     */		    if (!proc_nb)	       /* Compute uptime reduced to one proc using proc#0 */	       file_stats.uptime0 = cc_user + cc_nice + cc_system +	       			    cc_idle + cc_iowait + cc_steal;	 }      }      else if (!strncmp(line, "page ", 5))	 /* Read number of pages the system paged in and out */	 sscanf(line + 5, "%lu %lu",		&(file_stats.pgpgin), &(file_stats.pgpgout));      else if (!strncmp(line, "swap ", 5))	 /* Read number of swap pages brought in and out */	 sscanf(line + 5, "%lu %lu",		&(file_stats.pswpin), &(file_stats.pswpout));      else if (!strncmp(line, "intr ", 5)) {	 /* Read total number of interrupts received since system boot */	 sscanf(line + 5, "%llu", &(file_stats.irq_sum));	 pos = strcspn(line + 5, " ") + 5;	 if (GET_ONE_IRQ(sadc_actflag)) {	    /*	     * If -I option set on the command line,	     * read number of each interrupts received since system boot.	     */	    for (i = 0; i < NR_IRQS; i++) {	       sscanf(line + pos, " %u", &interrupts[i]);	       pos += strcspn(line + pos + 1, " ") + 1;	    }	 }      }      else if (!strncmp(line, "ctxt ", 5))	 /* Read number of context switches */	 sscanf(line + 5, "%llu", &(file_stats.context_swtch));      else if (!strncmp(line, "processes ", 10))	 /* Read number of processes created since system boot */	 sscanf(line + 10, "%lu", &(file_stats.processes));      else if (!HAS_DISKSTATS(flags) && !HAS_PPARTITIONS(flags)) {	 /*	  * Read possible disk stats from /proc/stat only if we are	  * sure they won't be read later from /proc/diskstats or	  * /proc/partitions.	  */	 if (!strncmp(line, "disk ", 5)) {	    /* Read number of I/O done since the last reboot */	    sscanf(line + 5, "%u %u %u %u",		   &(file_stats.dk_drive), &u_tmp[0], &u_tmp[1], &u_tmp[2]);	    file_stats.dk_drive += u_tmp[0] + u_tmp[1] + u_tmp[2];	 }	 else if (!strncmp(line, "disk_rio ", 9)) {	    /* Read number of read I/O */	    sscanf(line + 9, "%u %u %u %u",		   &(file_stats.dk_drive_rio), &u_tmp[0], &u_tmp[1], &u_tmp[2]);	    file_stats.dk_drive_rio += u_tmp[0] + u_tmp[1] + u_tmp[2];	 }	 else if (!strncmp(line, "disk_wio ", 9)) {	    /* Read number of write I/O */	    sscanf(line + 9, "%u %u %u %u",		   &(file_stats.dk_drive_wio), &u_tmp[0], &u_tmp[1], &u_tmp[2]);	    file_stats.dk_drive_wio += u_tmp[0] + u_tmp[1] + u_tmp[2];	 }	 else if (!strncmp(line, "disk_rblk ", 10)) {	    /* Read number of blocks read from disk */	    sscanf(line + 10, "%u %u %u %u",		   &(file_stats.dk_drive_rblk), &u_tmp[0], &u_tmp[1], &u_tmp[2]);	    file_stats.dk_drive_rblk += u_tmp[0] + u_tmp[1] + u_tmp[2];	 }	 else if (!strncmp(line, "disk_wblk ", 10)) {	    /* Read number of blocks written to disk */	    sscanf(line + 10, "%u %u %u %u",		   &(file_stats.dk_drive_wblk), &u_tmp[0], &u_tmp[1], &u_tmp[2]);	    file_stats.dk_drive_wblk += u_tmp[0] + u_tmp[1] + u_tmp[2];	 }	 else if (!strncmp(line, "disk_io: ", 9)) {	    unsigned int dsk = 0;	    init_dk_drive_stat();	    pos = 9;		    /* Read disks I/O statistics (for 2.4 kernels) */	    while (pos < strlen(line) - 1) {	/* Beware: a CR is already included in the line */	       sscanf(line + pos, "(%u,%u):(%u,%u,%u,%u,%u) ",		      &v_major, &v_index,		      &v_tmp[0], &v_tmp[1], &v_tmp[2], &v_tmp[3], &v_tmp[4]);	       file_stats.dk_drive += v_tmp[0];	       file_stats.dk_drive_rio  += v_tmp[1];	       file_stats.dk_drive_rblk += v_tmp[2];	       file_stats.dk_drive_wio  += v_tmp[3];	       file_stats.dk_drive_wblk += v_tmp[4];	       if (dsk < disk_nr) {		  st_disk_i = st_disk + dsk++;		  st_disk_i->major = v_major;		  st_disk_i->minor = v_index;		  st_disk_i->nr_ios = v_tmp[0];		  st_disk_i->rd_sect = v_tmp[2];		  st_disk_i->wr_sect = v_tmp[4];	       }	       pos += strcspn(line + pos, " ") + 1;	    }	    while (dsk < disk_nr) {	       /*		* Nb of disks has changed, or appending data to an old file		* with more disks than are actually available now.		*/	       st_disk_i = st_disk + dsk++;	       st_disk_i->major = st_disk_i->minor = 0;	    }	 }      }   }   fclose(fp);}/* *************************************************************************** * Read stats from /proc/loadavg *************************************************************************** */void read_proc_loadavg(void){   FILE *fp;   int load_tmp[3];   if ((fp = fopen(LOADAVG, "r")) != NULL) {      /* Read load averages and queue length */      fscanf(fp, "%d.%d %d.%d %d.%d %ld/%d %*d\n",	     &(load_tmp[0]), &(file_stats.load_avg_1),	     &(load_tmp[1]), &(file_stats.load_avg_5),	     &(load_tmp[2]), &(file_stats.load_avg_15),	     &(file_stats.nr_running),	     &(file_stats.nr_threads));      fclose(fp);      file_stats.load_avg_1  += load_tmp[0] * 100;      file_stats.load_avg_5  += load_tmp[1] * 100;      file_stats.load_avg_15 += load_tmp[2] * 100;      if (file_stats.nr_running)	 /* Do not take current process into account */	 file_stats.nr_running--;   }}/* *************************************************************************** * Read stats from /proc/meminfo ***************************************************************************

⌨️ 快捷键说明

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