📄 sadc.c
字号:
if (!strncmp(line, "rc", 2)) sscanf(line + 2, "%u %u", &(file_stats.nfsd_rchits), &(file_stats.nfsd_rcmisses)); else if (!strncmp(line, "net", 3)) sscanf(line + 3, "%u %u %u", &(file_stats.nfsd_netcnt), &(file_stats.nfsd_netudpcnt), &(file_stats.nfsd_nettcpcnt)); else if (!strncmp(line, "rpc", 3)) sscanf(line + 3, "%u %u", &(file_stats.nfsd_rpccnt), &(file_stats.nfsd_rpcbad)); else if (!strncmp(line, "proc3", 5)) sscanf(line + 5, "%*u %*u %u %*u %*u %u %*u %u %u", &(file_stats.nfsd_getattcnt), &(file_stats.nfsd_accesscnt), &(file_stats.nfsd_readcnt), &(file_stats.nfsd_writecnt)); } fclose(fp);}/* *************************************************************************** * Read stats from /proc/diskstats *************************************************************************** */void read_diskstats_stat(void){ FILE *fp; static char line[256]; int dsk = 0; struct disk_stats *st_disk_i; unsigned int major, minor; unsigned long rd_ios, wr_ios, rd_ticks, wr_ticks; unsigned long tot_ticks, rq_ticks; unsigned long long rd_sec, wr_sec; if ((fp = fopen(DISKSTATS, "r")) != NULL) { init_dk_drive_stat(); while ((fgets(line, 256, fp) != NULL) && (dsk < disk_nr)) { if (sscanf(line, "%u %u %*s %lu %*u %llu %lu %lu %*u %llu" " %lu %*u %lu %lu", &major, &minor, &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks, &tot_ticks, &rq_ticks) == 10) { /* It's a device and not a partition */ if (!rd_ios && !wr_ios) /* Unused device: ignore it */ continue; st_disk_i = st_disk + dsk++; st_disk_i->major = major; st_disk_i->minor = minor; st_disk_i->nr_ios = rd_ios + wr_ios; st_disk_i->rd_sect = rd_sec; st_disk_i->wr_sect = wr_sec; st_disk_i->rd_ticks = rd_ticks; st_disk_i->wr_ticks = wr_ticks; st_disk_i->tot_ticks = tot_ticks; st_disk_i->rq_ticks = rq_ticks; file_stats.dk_drive += rd_ios + wr_ios; file_stats.dk_drive_rio += rd_ios; file_stats.dk_drive_rblk += (unsigned int) rd_sec; file_stats.dk_drive_wio += wr_ios; file_stats.dk_drive_wblk += (unsigned int) wr_sec; } } fclose(fp); } 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; }}/* *************************************************************************** * Read stats from /proc/partitions *************************************************************************** */void read_ppartitions_stat(void){ FILE *fp; static char line[256]; int dsk = 0; struct disk_stats *st_disk_i; unsigned int major, minor; unsigned long rd_ios, wr_ios, rd_ticks, wr_ticks, tot_ticks, rq_ticks; unsigned long long rd_sec, wr_sec; if ((fp = fopen(PPARTITIONS, "r")) != NULL) { init_dk_drive_stat(); while ((fgets(line, 256, fp) != NULL) && (dsk < disk_nr)) { if (sscanf(line, "%u %u %*u %*s %lu %*u %llu %lu %lu %*u %llu" " %lu %*u %lu %lu", &major, &minor, &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks, &tot_ticks, &rq_ticks) == 10) { if (ioc_iswhole(major, minor)) { /* OK: it's a device and not a partition */ st_disk_i = st_disk + dsk++; st_disk_i->major = major; st_disk_i->minor = minor; st_disk_i->nr_ios = rd_ios + wr_ios; st_disk_i->rd_sect = rd_sec; st_disk_i->wr_sect = wr_sec; st_disk_i->rd_ticks = rd_ticks; st_disk_i->wr_ticks = wr_ticks; st_disk_i->tot_ticks = tot_ticks; st_disk_i->rq_ticks = rq_ticks; file_stats.dk_drive += rd_ios + wr_ios; file_stats.dk_drive_rio += rd_ios; file_stats.dk_drive_rblk += (unsigned int) rd_sec; file_stats.dk_drive_wio += wr_ios; file_stats.dk_drive_wblk += (unsigned int) wr_sec; } } } fclose(fp); } 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; }}/* *************************************************************************** * Read system statistics from various files *************************************************************************** */void read_stats(unsigned int *flags){ read_proc_stat(*flags); read_proc_meminfo(); read_proc_loadavg(); read_proc_vmstat(); read_ktables_stat(); read_net_sock_stat(); read_net_nfs_stat(); read_net_nfsd_stat(); /* Read disk stats, at least for sar -b */ if (HAS_DISKSTATS(*flags)) read_diskstats_stat(); else if (HAS_PPARTITIONS(*flags)) read_ppartitions_stat(); /* else disks are in /proc/stat */ if (pid_nr) read_pid_stat(*flags); if (serial_nr) read_serial_stat(); if (irqcpu_nr) read_interrupts_stat(); if (iface_nr) read_net_dev_stat();}/* *************************************************************************** * Main loop: read stats from the relevant sources, * and display them. *************************************************************************** */void rw_sa_stat_loop(unsigned int *flags, long count, struct tm *loc_time, int stdfd, int ofd, size_t file_stats_size, char ofile[], char new_ofile[]){ int do_sa_rotat = 0; unsigned int save_flags; /* Main loop */ do { /* * Init file_stats structure. Every record of other structures * is set when reading corresponding stat file (records are set * to 0 if there are not enough data to fill the structure). */ memset(&file_stats, 0, FILE_STATS_SIZE); /* Set record type */ if (do_sa_rotat) file_stats.record_type = R_LAST_STATS; else file_stats.record_type = R_STATS; /* 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; /* Read then write stats */ read_stats(flags); if (stdfd >= 0) { save_flags = *flags; *flags &= ~S_F_L_OPTION; write_stats(stdfd, file_stats_size, flags); *flags = save_flags; } file_stats.record_type = R_STATS; if (ofile[0]) write_stats(ofd, file_stats_size, flags); if (do_sa_rotat) { /* * Stats are written at the end of previous file *and* at the * beginning of the new one (outfile must have been specified * as '-' on the command line). */ do_sa_rotat = FALSE; if (fdatasync(ofd) < 0) { /* Flush previous file */ perror("fdatasync"); exit(4); } close(ofd); strcpy(ofile, new_ofile); /* Recalculate nb of system items and reallocate structures */ sa_sys_init(flags); /* Rewrite header to stdout */ if (stdfd >= 0) setup_file_hdr(stdfd, &file_stats_size); /* Open and init new file */ open_ofile(&ofd, ofile, &file_stats_size, flags); /* Write stats again */ write_stats(ofd, file_stats_size, flags); } /* Flush data */ fflush(stdout); if (ofile[0] && (fdatasync(ofd) < 0)) { perror("fdatasync"); exit(4); } if (count > 0) count--; if (count) pause(); /* Rotate activity file if necessary */ if (WANT_SA_ROTAT(*flags)) { /* The user specified '-' as the filename to use */ get_localtime(loc_time); snprintf(new_ofile, MAX_FILE_LEN, "%s/sa%02d", SA_DIR, loc_time->tm_mday); new_ofile[MAX_FILE_LEN - 1] = '\0'; if (strcmp(ofile, new_ofile)) do_sa_rotat = TRUE; } } while (count); CLOSE(stdfd); CLOSE(ofd);}/* *************************************************************************** * Main entry to the program *************************************************************************** */int main(int argc, char **argv){ int opt = 0, optz = 0, i; unsigned long pid; char ofile[MAX_FILE_LEN]; char new_ofile[MAX_FILE_LEN]; unsigned int flags = 0; struct tm loc_time; int stdfd = 0, ofd = -1; long count = 0; /* * This variable contains: * - FILE_STATS_SIZE defined in sa.h if creating a new daily data file or * using STDOUT, * - the size of the file_stats structure defined in the header of the * file if appending data to an existing daily data file. */ size_t file_stats_size = FILE_STATS_SIZE; /* Compute page shift in kB */ kb_shift = get_kb_shift(); ofile[0] = new_ofile[0] = '\0';#ifdef USE_NLS /* Init National Language Support */ init_nls();#endif /* Init activity flag */ sadc_actflag = A_PROC + A_PAGE + A_IRQ + A_IO + A_CPU + A_CTXSW + A_SWAP + A_MEMORY + A_MEM_AMT + A_KTABLES + A_NET_SOCK + A_QUEUE + A_NET_NFS + A_NET_NFSD; while (++opt < argc) { if (!strcmp(argv[opt], "-I")) sadc_actflag |= A_ONE_IRQ; else if (!strcmp(argv[opt], "-d")) sadc_actflag |= A_DISK; else if (!strcmp(argv[opt], "-F")) flags |= S_F_F_OPTION; else if (!strcmp(argv[opt], "-L")) flags |= S_F_L_OPTION; else if (!strcmp(argv[opt], "-V")) print_version(); else if (!strcmp(argv[opt], "-z")) /* Set by sar command */ optz = 1; else if (!strcmp(argv[opt], "-x") || !strcmp(argv[opt], "-X")) { if (!GET_PID(sadc_actflag)) { /* Init PID flag the first time */ for (i = 0; i < MAX_PID_NR; i++) f_pids[i] = 0; } sadc_actflag |= A_PID; if (argv[++opt]) { if (!strcmp(argv[opt], K_ALL)) { flags |= S_F_X_ALL; set_pflag(strcmp(argv[opt - 1], "-x"), 0); continue; /* Next option */ } else if (!strcmp(argv[opt], K_SELF)) pid = getpid(); else { if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) usage(argv[0]); pid = atol(argv[opt]); if (pid < 1) usage(argv[0]); } set_pflag(strcmp(argv[opt - 1], "-x"), pid); } } else if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { if (!ofile[0]) { stdfd = -1; /* Don't write to STDOUT */ if (!strcmp(argv[opt], "-")) { /* File name set to '-' */ get_localtime(&loc_time); snprintf(ofile, MAX_FILE_LEN, "%s/sa%02d", SA_DIR, loc_time.tm_mday); ofile[MAX_FILE_LEN - 1] = '\0'; flags |= S_F_SA_ROTAT; } else if (!strncmp(argv[opt], "-", 1)) /* Bad option */ usage(argv[0]); else { /* Write data to file */ strncpy(ofile, argv[opt], MAX_FILE_LEN); ofile[MAX_FILE_LEN - 1] = '\0'; } } else /* Outfile already specified */ usage(argv[0]); } else if (!interval) { /* Get interval */ interval = atol(argv[opt]); if (interval < 1) usage(argv[0]); count = -1; } else if (count <= 0) { /* Get count value */ count = atol(argv[opt]); if (count < 1) usage(argv[0]); } else usage(argv[0]); } /* * If option -z used, write to STDOUT even if a filename * has been entered on the command line. */ if (optz) stdfd = 0; /* -x and -X options ignored when writing to a file */ if (ofile[0]) { pid_idx = 0; flags &= ~S_F_X_ALL; sadc_actflag &= ~A_PID; } else /* -L option ignored when writing to STDOUT */ flags &= ~S_F_L_OPTION; if (WANT_ALL_PIDS(flags)) pid_nr = MAX_PID_NR; else pid_nr = pid_idx; /* Init structures according to machine architecture */ sa_sys_init(&flags); if (GET_PID(sadc_actflag)) salloc_pid(pid_nr); /* * Open output file then STDOUT. Write header for each of them. * NB: Output file must be opened first because we may change * the activity flag to that of the file, and the activity flag * written on STDOUT must be consistent. */ open_ofile(&ofd, ofile, &file_stats_size, &flags); open_stdout(&stdfd, &file_stats_size); if (!interval) { /* Interval (and count) not set: write a dummy record and exit */ write_dummy_record(ofd, file_stats_size, &flags); CLOSE(ofd); CLOSE(stdfd); exit(0); } /* Set a handler for SIGALRM */ alarm_handler(0); /* Main loop */ rw_sa_stat_loop(&flags, count, &loc_time, stdfd, ofd, file_stats_size, ofile, new_ofile); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -