📄 sar.c
字号:
} while (!eosaf); close(ifd);}/* *************************************************************************** * Read statistics sent by sadc, the data collector. *************************************************************************** */void read_stats(void){ short curr = 1, dis = 1; unsigned long lines = 0; unsigned int rows = 23, more = 1; /* Read stats header */ read_header_data(); /* Force '-P ALL' flag if -A option is used on SMP machines */ if (USE_A_OPTION(flags) && file_hdr.sa_proc) { init_bitmap(cpu_bitmap, ~0, NR_CPUS); flags |= S_F_ALL_PROC + S_F_PER_PROC; } /* * Check that data corresponding to requested activities * are sent by the data collector. */ if (GET_SERIAL(sar_actflag) && !file_hdr.sa_serial) { sar_actflag &= ~A_SERIAL; dis_hdr--; } if ((sar_actflag & (A_NET_DEV + A_NET_EDEV)) && !file_hdr.sa_iface) { if (GET_NET_DEV(sar_actflag) && GET_NET_EDEV(sar_actflag)) dis_hdr--; sar_actflag &= ~(A_NET_DEV + A_NET_EDEV); dis_hdr--; } if (GET_DISK(sar_actflag) && !file_hdr.sa_nr_disk) { sar_actflag &= ~A_DISK; dis_hdr--; } if (!sar_actflag) { fprintf(stderr, _("Requested activities not available\n")); exit(1); } if ((GET_SERIAL(sar_actflag) && (file_hdr.sa_serial > 1)) || ((GET_NET_DEV(sar_actflag) || GET_NET_EDEV(sar_actflag)) && (file_hdr.sa_iface > 1)) || (GET_DISK(sar_actflag) && (file_hdr.sa_nr_disk > 1))) dis_hdr = 9; if (!dis_hdr) { /* Get window size */ rows = get_win_height(); lines = rows; } /* Check use of -P option */ prep_smp_option(file_hdr.sa_proc); /* * No need to force sar_actflag to file_hdr.sa_actflag * since we are not reading stats from a file. */ /* Perform required allocations */ allocate_structures(USE_SADC); /* Print report header */ print_report_hdr(S_O_NONE, flags, &loc_time, &file_hdr); /* Read system statistics sent by the data collector */ read_stat_bunch(0); if (!dis_hdr) { if (file_hdr.sa_proc > 0) more = 2 + file_hdr.sa_proc; if (pid_nr) more = pid_nr; } if (!interval) /* Display stats since boot time and exit */ write_stats_startup(0); /* Save the first stats collected. Will be used to compute the average */ copy_structures(2, 0, USE_SADC); /* Main loop */ do { /* Get stats */ read_stat_bunch(curr); /* Print results */ if (!dis_hdr) { dis = lines / rows; if (dis) lines %= rows; lines += more; } write_stats(curr, dis, sar_actflag, USE_SADC, &count, NO_TM_START, tm_end.use, NO_RESET, ST_IMMEDIATE); fflush(stdout); /* Don't buffer data if redirected to a pipe... */ if (file_stats[curr].record_type == R_LAST_STATS) { /* File rotation is happening: re-read header data sent by sadc */ read_header_data(); allocate_structures(USE_SADC); } if (count > 0) count--; if (count) curr ^= 1; } while (count); /* Print statistics average */ write_stats_avg(curr, dis_hdr, sar_actflag, USE_SADC);}/* *************************************************************************** * Main entry to the sar program *************************************************************************** */int main(int argc, char **argv){ int opt = 1, args_idx = 2; int fd[2]; unsigned long pid = 0; char from_file[MAX_FILE_LEN], to_file[MAX_FILE_LEN]; char ltemp[20]; /* Compute page shift in kB */ kb_shift = get_kb_shift(); from_file[0] = to_file[0] = '\0';#ifdef USE_NLS /* Init National Language Support */ init_nls();#endif tm_start.use = tm_end.use = FALSE; init_bitmap(irq_bitmap, 0, NR_IRQS); init_bitmap(cpu_bitmap, 0, NR_CPUS); init_all_stats(); /* Process options */ while (opt < argc) { if (!strcmp(argv[opt], "-I")) { if (argv[++opt]) { dis_hdr++; /* Parse -I option */ if (parse_sar_I_opt(argv, &opt, &sar_actflag, &dis_hdr, irq_bitmap)) usage(argv[0]); } else usage(argv[0]); } else if (!strcmp(argv[opt], "-P")) { /* Parse -P option */ if (parse_sa_P_opt(argv, &opt, &flags, &dis_hdr, cpu_bitmap)) usage(argv[0]); } else if (!strcmp(argv[opt], "-o")) { /* Save stats to a file */ if ((argv[++opt]) && strncmp(argv[opt], "-", 1) && (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) { strncpy(to_file, argv[opt++], MAX_FILE_LEN); to_file[MAX_FILE_LEN - 1] = '\0'; } else strcpy(to_file, "-"); } else if (!strcmp(argv[opt], "-f")) { /* Read stats from a file */ if ((argv[++opt]) && strncmp(argv[opt], "-", 1) && (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) { strncpy(from_file, argv[opt++], MAX_FILE_LEN); from_file[MAX_FILE_LEN - 1] = '\0'; } else { get_localtime(&loc_time); snprintf(from_file, MAX_FILE_LEN, "%s/sa%02d", SA_DIR, loc_time.tm_mday); from_file[MAX_FILE_LEN - 1] = '\0'; } } else if (!strcmp(argv[opt], "-s")) { /* Get time start */ if (parse_timestamp(argv, &opt, &tm_start, DEF_TMSTART)) usage(argv[0]); } else if (!strcmp(argv[opt], "-e")) { /* Get time end */ if (parse_timestamp(argv, &opt, &tm_end, DEF_TMEND)) usage(argv[0]); } else if (!strcmp(argv[opt], "-i")) { if (!argv[++opt] || (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) usage(argv[0]); interval = atol(argv[opt++]); if (interval < 1) usage(argv[0]); flags |= S_F_I_OPTION; } else if (!strcmp(argv[opt], "-x") || !strcmp(argv[opt], "-X")) { if (argv[++opt]) { dis_hdr++; if (!strcmp(argv[opt], K_SADC)) { strcpy(ltemp, K_SELF); opt++; } else if (!strcmp(argv[opt], K_ALL)) { if (args_idx < MAX_ARGV_NR - 7) { dis_hdr = 9; salloc(args_idx++, argv[opt - 1]); /* "-x" or "-X" */ salloc(args_idx++, K_ALL); if (!strcmp(argv[opt - 1], "-x")) sar_actflag |= A_PID; else sar_actflag |= A_CPID; } opt++; continue; /* Next option */ } else { if (!strcmp(argv[opt], K_SELF)) { pid = getpid(); opt++; } else if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) usage(argv[0]); else { pid = atol(argv[opt++]); if (pid < 1) usage(argv[0]); } sprintf(ltemp, "%ld", pid); } if (args_idx < MAX_ARGV_NR - 7) { if (!strcmp(argv[opt - 2], "-x")) sar_actflag |= A_PID; else sar_actflag |= A_CPID; salloc(args_idx++, argv[opt - 2]); /* "-x" or "-X" */ salloc(args_idx++, ltemp); } } else usage(argv[0]); } else if (!strcmp(argv[opt], "-n")) { if (argv[++opt]) { dis_hdr++; /* Parse option -n */ if (parse_sar_n_opt(argv, &opt, &sar_actflag, &dis_hdr)) usage(argv[0]); } else usage(argv[0]); } else if (!strncmp(argv[opt], "-", 1)) { /* Other options not previously tested */ if (parse_sar_opt(argv, opt, &sar_actflag, &flags, &dis_hdr, C_SAR, irq_bitmap, cpu_bitmap)) usage(argv[0]); opt++; } else if (interval < 0) { /* Get interval */ if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) usage(argv[0]); interval = atol(argv[opt++]); if (interval < 0) usage(argv[0]); } else { /* Get count value */ if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) || !interval) usage(argv[0]); if (count) /* Count parameter already set */ usage(argv[0]); count = atol(argv[opt++]); if (count < 0) usage(argv[0]); else if (!count) count = -1; /* To generate a report continuously */ } } /* 'sar' is equivalent to 'sar -f' */ if ((argc == 1) || ((interval < 0) && !from_file[0] && !to_file[0])) { get_localtime(&loc_time); snprintf(from_file, MAX_FILE_LEN, "%s/sa%02d", SA_DIR, loc_time.tm_mday); from_file[MAX_FILE_LEN - 1] = '\0'; } /* * Check option dependencies */ /* You read from a file OR you write to it... */ if (from_file[0] && to_file[0]) { fprintf(stderr, _("-f and -o options are mutually exclusive\n")); exit(1); } /* Use time start or option -i only when reading stats from a file */ if ((tm_start.use || USE_I_OPTION(flags)) && !from_file[0]) { fprintf(stderr, _("Not reading from a system activity file (use -f option)\n")); exit(1); } /* Don't print stats since boot time if -o or -f options are used */ if (!interval && (from_file[0] || to_file[0])) usage(argv[0]); if (!count) { /* count parameter not set */ if (from_file[0]) /* Display all the contents of the daily data file */ count = -1; else /* Default value for the count parameter is 1 */ count = 1; } /* -x and -X options ignored when writing to a file */ if (to_file[0]) { sar_actflag &= ~A_PID; sar_actflag &= ~A_CPID; } /* Default is CPU activity... */ if (!sar_actflag) { /* * Still OK even when reading stats from a file * since A_CPU activity is always recorded. */ sar_actflag |= A_CPU; dis_hdr++; } /* ---Reading stats from file */ if (from_file[0]) { if (interval < 0) interval = 1; /* Read stats from file */ read_stats_from_file(from_file); return 0; } /* ---Reading stats from sadc */ /* Create anonymous pipe */ if (pipe(fd) == -1) { perror("pipe"); exit(4); } switch (fork()) { case -1: perror("fork"); exit(4); break; case 0: /* Child */ if (dup2(fd[1], STDOUT_FILENO) < 0) { perror("dup2"); exit(4); } CLOSE_ALL(fd); /* * Prepare options for sadc */ /* Program name */ salloc(0, SADC); /* Interval value */ if (interval < 0) usage(argv[0]); else if (!interval) strcpy(ltemp, "1"); else sprintf(ltemp, "%ld", interval); salloc(1, ltemp); /* Count number */ if (count >= 0) { sprintf(ltemp, "%ld", count + 1); salloc(args_idx++, ltemp); } /* Flags to be passed to sadc */ salloc(args_idx++, "-z"); if (GET_ONE_IRQ(sar_actflag)) salloc(args_idx++, "-I"); if (GET_DISK(sar_actflag)) salloc(args_idx++, "-d"); /* Outfile arg */ if (to_file[0]) salloc(args_idx++, to_file); /* Last arg is NULL */ args[args_idx] = NULL; /* Call now the data collector */ execv(SADC_PATH, args); execvp(SADC, args); /* * Note: don't use execl/execlp since we don't have a fixed number of * args to give to sadc. */ perror("exec"); exit(4); break; default: /* Parent */ if (dup2(fd[0], STDIN_FILENO) < 0) { perror("dup2"); exit(4); } CLOSE_ALL(fd); /* Get now the statistics */ read_stats(); break; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -