/*
***************************************************************************
- * Count number of interrupts that are in /proc/stat file.
+ * Count number of processors in /sys.
*
* RETURNS:
- * Number of interrupts, including total number of interrupts.
+ * Number of processors (online and offline).
+ * A value of 0 means that /sys was not mounted.
+ * A value of N (!=0) means N processor(s) (cpu0 .. cpu(N-1)).
***************************************************************************
*/
-int get_irq_nr(void)
+int get_sys_cpu_nr(void)
{
- FILE *fp;
- char line[8192];
- int in = 0;
- int pos = 4;
+ DIR *dir;
+ struct dirent *drd;
+ struct stat buf;
+ char line[MAX_PF_NAME];
+ int proc_nr = 0;
- if ((fp = fopen(STAT, "r")) == NULL)
+ /* Open relevant /sys directory */
+ if ((dir = opendir(SYSFS_DEVCPU)) == NULL)
return 0;
- while (fgets(line, 8192, fp) != NULL) {
-
- if (!strncmp(line, "intr ", 5)) {
+ /* Get current file entry */
+ while ((drd = readdir(dir)) != NULL) {
- while (pos < strlen(line)) {
- in++;
- pos += strcspn(line + pos + 1, " ") + 1;
+ if (!strncmp(drd->d_name, "cpu", 3) && isdigit(drd->d_name[3])) {
+ snprintf(line, MAX_PF_NAME, "%s/%s", SYSFS_DEVCPU, drd->d_name);
+ line[MAX_PF_NAME - 1] = '\0';
+ if (stat(line, &buf) < 0)
+ continue;
+ if (S_ISDIR(buf.st_mode)) {
+ proc_nr++;
}
}
}
- fclose(fp);
+ /* Close directory */
+ closedir(dir);
- return in;
+ return proc_nr;
}
/*
***************************************************************************
- * Find number of serial lines that support tx/rx accounting
- * in /proc/tty/driver/serial file.
+ * Count number of processors in /proc/stat.
*
* RETURNS:
- * Number of serial lines supporting tx/rx accouting.
+ * Number of processors. The returned value is greater than or equal to the
+ * number of online processors.
+ * A value of 0 means one processor and non SMP kernel.
+ * A value of N (!=0) means N processor(s) (0 .. N-1) with SMP kernel.
***************************************************************************
*/
-int get_serial_nr(void)
+int get_proc_cpu_nr(void)
{
FILE *fp;
- char line[256];
- int sl = 0;
+ char line[16];
+ int num_proc, proc_nr = -1;
- if ((fp = fopen(SERIAL, "r")) == NULL)
- return 0; /* No SERIAL file */
+ if ((fp = fopen(STAT, "r")) == NULL) {
+ fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
+ exit(1);
+ }
- while (fgets(line, 256, fp) != NULL) {
- /*
- * tx/rx statistics are always present,
- * except when serial line is unknown.
- */
- if (strstr(line, "tx:") != NULL) {
- sl++;
+ while (fgets(line, 16, fp) != NULL) {
+
+ if (strncmp(line, "cpu ", 4) && !strncmp(line, "cpu", 3)) {
+ sscanf(line + 3, "%d", &num_proc);
+ if (num_proc > proc_nr) {
+ proc_nr = num_proc;
+ }
}
}
fclose(fp);
- return sl;
+ return (proc_nr + 1);
}
/*
***************************************************************************
- * Find number of interfaces (network devices) that are in /proc/net/dev
- * file.
+ * Count the number of processors on the machine.
+ * Try to use /sys for that, or /proc/stat if /sys doesn't exist.
+ *
+ * IN:
+ * @max_nr_cpus Maximum number of proc that sysstat can handle.
*
* RETURNS:
- * Number of network interfaces.
+ * Number of processors.
+ * 0: one proc and non SMP kernel.
+ * 1: one proc and SMP kernel (NB: On SMP machines where all the CPUs but
+ * one have been disabled, we get the total number of proc since we use
+ * /sys to count them).
+ * 2: two proc...
***************************************************************************
*/
-int get_iface_nr(void)
+int get_cpu_nr(unsigned int max_nr_cpus)
+{
+ int cpu_nr;
+
+ if ((cpu_nr = get_sys_cpu_nr()) == 0) {
+ /* /sys may be not mounted. Use /proc/stat instead */
+ cpu_nr = get_proc_cpu_nr();
+ }
+
+ if (cpu_nr > max_nr_cpus) {
+ fprintf(stderr, _("Cannot handle so many processors!\n"));
+ exit(1);
+ }
+
+ return cpu_nr;
+}
+
+/*
+ ***************************************************************************
+ * Find number of interrupts available per processor (use
+ * /proc/interrupts file or /proc/softirqs).
+ *
+ * IN:
+ * @file /proc file to read (interrupts or softirqs).
+ * @max_nr_irqcpu Maximum number of interrupts per processor that
+ * sadc can handle.
+ * @cpu_nr Number of processors.
+ *
+ * RETURNS:
+ * Number of interrupts per processor + a pre-allocation constant.
+ ***************************************************************************
+ */
+int get_irqcpu_nr(char *file, int max_nr_irqcpu, int cpu_nr)
{
FILE *fp;
- char line[128];
- int iface = 0;
+ char *line = NULL;
+ unsigned int irq = 0;
+ int p;
- if ((fp = fopen(NET_DEV, "r")) == NULL)
- return 0; /* No network device file */
+ if ((fp = fopen(file, "r")) == NULL)
+ return 0; /* No interrupts file */
- while (fgets(line, 128, fp) != NULL) {
- if (strchr(line, ':')) {
- iface++;
+ SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr);
+
+ while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr , fp) != NULL) &&
+ (irq < max_nr_irqcpu)) {
+ p = strcspn(line, ":");
+ if ((p > 0) && (p < 16)) {
+ irq++;
}
}
fclose(fp);
- return iface;
+ free(line);
+
+ return irq;
}
/*
return dev;
}
-/*
- ***************************************************************************
- * Get number of devices in /proc/diskstats.
- *
- * IN:
- * @f Non zero (true) if disks *and* partitions should be counted, and
- * zero (false) if only disks must be counted.
- *
- * RETURNS:
- * Number of devices.
- ***************************************************************************
- */
-int get_disk_nr(unsigned int f)
-{
- int disk_nr;
-
- /*
- * Partitions are taken into account by sar -d only with
- * kernels 2.6.25 and later.
- */
- disk_nr = get_diskstats_dev_nr(f, CNT_USED_DEV);
-
- return disk_nr;
-}
+#ifdef SOURCE_SADC
+/*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/
/*
***************************************************************************
- * Count number of processors in /sys.
+ * Count number of interrupts that are in /proc/stat file.
*
* RETURNS:
- * Number of processors (online and offline).
- * A value of 0 means that /sys was not mounted.
- * A value of N (!=0) means N processor(s) (cpu0 .. cpu(N-1)).
+ * Number of interrupts, including total number of interrupts.
***************************************************************************
*/
-int get_sys_cpu_nr(void)
+int get_irq_nr(void)
{
- DIR *dir;
- struct dirent *drd;
- struct stat buf;
- char line[MAX_PF_NAME];
- int proc_nr = 0;
+ FILE *fp;
+ char line[8192];
+ int in = 0;
+ int pos = 4;
- /* Open relevant /sys directory */
- if ((dir = opendir(SYSFS_DEVCPU)) == NULL)
+ if ((fp = fopen(STAT, "r")) == NULL)
return 0;
- /* Get current file entry */
- while ((drd = readdir(dir)) != NULL) {
+ while (fgets(line, 8192, fp) != NULL) {
- if (!strncmp(drd->d_name, "cpu", 3) && isdigit(drd->d_name[3])) {
- snprintf(line, MAX_PF_NAME, "%s/%s", SYSFS_DEVCPU, drd->d_name);
- line[MAX_PF_NAME - 1] = '\0';
- if (stat(line, &buf) < 0)
- continue;
- if (S_ISDIR(buf.st_mode)) {
- proc_nr++;
+ if (!strncmp(line, "intr ", 5)) {
+
+ while (pos < strlen(line)) {
+ in++;
+ pos += strcspn(line + pos + 1, " ") + 1;
}
}
}
- /* Close directory */
- closedir(dir);
+ fclose(fp);
- return proc_nr;
+ return in;
}
/*
***************************************************************************
- * Count number of processors in /proc/stat.
+ * Find number of serial lines that support tx/rx accounting
+ * in /proc/tty/driver/serial file.
*
* RETURNS:
- * Number of processors. The returned value is greater than or equal to the
- * number of online processors.
- * A value of 0 means one processor and non SMP kernel.
- * A value of N (!=0) means N processor(s) (0 .. N-1) with SMP kernel.
+ * Number of serial lines supporting tx/rx accouting.
***************************************************************************
*/
-int get_proc_cpu_nr(void)
+int get_serial_nr(void)
{
FILE *fp;
- char line[16];
- int num_proc, proc_nr = -1;
-
- if ((fp = fopen(STAT, "r")) == NULL) {
- fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
- exit(1);
- }
+ char line[256];
+ int sl = 0;
- while (fgets(line, 16, fp) != NULL) {
+ if ((fp = fopen(SERIAL, "r")) == NULL)
+ return 0; /* No SERIAL file */
- if (strncmp(line, "cpu ", 4) && !strncmp(line, "cpu", 3)) {
- sscanf(line + 3, "%d", &num_proc);
- if (num_proc > proc_nr) {
- proc_nr = num_proc;
- }
+ while (fgets(line, 256, fp) != NULL) {
+ /*
+ * tx/rx statistics are always present,
+ * except when serial line is unknown.
+ */
+ if (strstr(line, "tx:") != NULL) {
+ sl++;
}
}
fclose(fp);
- return (proc_nr + 1);
+ return sl;
}
/*
***************************************************************************
- * Count the number of processors on the machine.
- * Try to use /sys for that, or /proc/stat if /sys doesn't exist.
- *
- * IN:
- * @max_nr_cpus Maximum number of proc that sysstat can handle.
+ * Find number of interfaces (network devices) that are in /proc/net/dev
+ * file.
*
* RETURNS:
- * Number of processors.
- * 0: one proc and non SMP kernel.
- * 1: one proc and SMP kernel (NB: On SMP machines where all the CPUs but
- * one have been disabled, we get the total number of proc since we use
- * /sys to count them).
- * 2: two proc...
+ * Number of network interfaces.
***************************************************************************
*/
-int get_cpu_nr(unsigned int max_nr_cpus)
+int get_iface_nr(void)
{
- int cpu_nr;
+ FILE *fp;
+ char line[128];
+ int iface = 0;
- if ((cpu_nr = get_sys_cpu_nr()) == 0) {
- /* /sys may be not mounted. Use /proc/stat instead */
- cpu_nr = get_proc_cpu_nr();
- }
+ if ((fp = fopen(NET_DEV, "r")) == NULL)
+ return 0; /* No network device file */
- if (cpu_nr > max_nr_cpus) {
- fprintf(stderr, _("Cannot handle so many processors!\n"));
- exit(1);
+ while (fgets(line, 128, fp) != NULL) {
+ if (strchr(line, ':')) {
+ iface++;
+ }
}
- return cpu_nr;
+ fclose(fp);
+
+ return iface;
}
/*
***************************************************************************
- * Find number of interrupts available per processor (use
- * /proc/interrupts file or /proc/softirqs).
+ * Get number of devices in /proc/diskstats.
*
* IN:
- * @file /proc file to read (interrupts or softirqs).
- * @max_nr_irqcpu Maximum number of interrupts per processor that
- * sadc can handle.
- * @cpu_nr Number of processors.
+ * @f Non zero (true) if disks *and* partitions should be counted, and
+ * zero (false) if only disks must be counted.
*
* RETURNS:
- * Number of interrupts per processor + a pre-allocation constant.
+ * Number of devices.
***************************************************************************
*/
-int get_irqcpu_nr(char *file, int max_nr_irqcpu, int cpu_nr)
+int get_disk_nr(unsigned int f)
{
- FILE *fp;
- char *line = NULL;
- unsigned int irq = 0;
- int p;
-
- if ((fp = fopen(file, "r")) == NULL)
- return 0; /* No interrupts file */
-
- SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr);
-
- while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr , fp) != NULL) &&
- (irq < max_nr_irqcpu)) {
- p = strcspn(line, ":");
- if ((p > 0) && (p < 16)) {
- irq++;
- }
- }
-
- fclose(fp);
+ int disk_nr;
- free(line);
+ /*
+ * Partitions are taken into account by sar -d only with
+ * kernels 2.6.25 and later.
+ */
+ disk_nr = get_diskstats_dev_nr(f, CNT_USED_DEV);
- return irq;
+ return disk_nr;
}
/*
return fs;
}
+
+/*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
+#endif /* SOURCE_SADC */
#define _(string) (string)
#endif
-/*
- ***************************************************************************
- * Replace octal codes in string with their corresponding characters.
- *
- * IN:
- * @str String to parse.
- *
- * OUT:
- * @str String with octal codes replaced with characters.
- ***************************************************************************
- */
-void oct2chr(char *str)
-{
- int i = 0;
- int j, len;
-
- len = strlen(str);
-
- while (i < len - 3) {
- if ((str[i] == '\\') &&
- (str[i + 1] >= '0') && (str[i + 1] <= '3') &&
- (str[i + 2] >= '0') && (str[i + 2] <= '7') &&
- (str[i + 3] >= '0') && (str[i + 3] <= '7')) {
- /* Octal code found */
- str[i] = (str[i + 1] - 48) * 64 +
- (str[i + 2] - 48) * 8 +
- (str[i + 3] - 48);
- for (j = i + 4; j <= len; j++) {
- str[j - 3] = str[j];
- }
- len -= 3;
- }
- i++;
- }
-}
-
/*
***************************************************************************
* Read CPU statistics and machine uptime.
fclose(fp);
}
-/*
- ***************************************************************************
- * Read processes (tasks) creation and context switches statistics
- * from /proc/stat.
- *
- * IN:
- * @st_pcsw Structure where stats will be saved.
- *
- * OUT:
- * @st_pcsw Structure with statistics.
- ***************************************************************************
- */
-void read_stat_pcsw(struct stats_pcsw *st_pcsw)
-{
- FILE *fp;
- char line[8192];
-
- if ((fp = fopen(STAT, "r")) == NULL)
- return;
-
- while (fgets(line, 8192, fp) != NULL) {
-
- if (!strncmp(line, "ctxt ", 5)) {
- /* Read number of context switches */
- sscanf(line + 5, "%llu", &st_pcsw->context_switch);
- }
-
- else if (!strncmp(line, "processes ", 10)) {
- /* Read number of processes created since system boot */
- sscanf(line + 10, "%lu", &st_pcsw->processes);
- }
- }
-
- fclose(fp);
-}
-
/*
***************************************************************************
* Read interrupts statistics from /proc/stat.
fclose(fp);
}
-/*
- ***************************************************************************
- * Read queue and load statistics from /proc/loadavg and /proc/stat.
- *
- * IN:
- * @st_queue Structure where stats will be saved.
- *
- * OUT:
- * @st_queue Structure with statistics.
- ***************************************************************************
- */
-void read_loadavg(struct stats_queue *st_queue)
-{
- FILE *fp;
- char line[8192];
- int load_tmp[3];
-
- if ((fp = fopen(LOADAVG, "r")) == NULL)
- return;
-
- /* Read load averages and queue length */
- fscanf(fp, "%d.%d %d.%d %d.%d %ld/%d %*d\n",
- &load_tmp[0], &st_queue->load_avg_1,
- &load_tmp[1], &st_queue->load_avg_5,
- &load_tmp[2], &st_queue->load_avg_15,
- &st_queue->nr_running,
- &st_queue->nr_threads);
-
- fclose(fp);
-
- st_queue->load_avg_1 += load_tmp[0] * 100;
- st_queue->load_avg_5 += load_tmp[1] * 100;
- st_queue->load_avg_15 += load_tmp[2] * 100;
-
- if (st_queue->nr_running) {
- /* Do not take current process into account */
- st_queue->nr_running--;
- }
-
- /* Read nr of tasks blocked from /proc/stat */
- if ((fp = fopen(STAT, "r")) == NULL)
- return;
-
- while (fgets(line, 8192, fp) != NULL) {
-
- if (!strncmp(line, "procs_blocked ", 14)) {
- /* Read number of processes blocked */
- sscanf(line + 14, "%lu", &st_queue->procs_blocked);
- break;
- }
- }
-
- fclose(fp);
-}
-
/*
***************************************************************************
* Read memory statistics from /proc/meminfo.
fclose(fp);
}
+/*
+ ***************************************************************************
+ * Read machine uptime, independently of the number of processors.
+ *
+ * OUT:
+ * @uptime Uptime value in jiffies.
+ ***************************************************************************
+ */
+void read_uptime(unsigned long long *uptime)
+{
+ FILE *fp;
+ char line[128];
+ unsigned long up_sec, up_cent;
+
+ if ((fp = fopen(UPTIME, "r")) == NULL)
+ return;
+
+ if (fgets(line, 128, fp) == NULL) {
+ fclose(fp);
+ return;
+ }
+
+ sscanf(line, "%lu.%lu", &up_sec, &up_cent);
+ *uptime = (unsigned long long) up_sec * HZ +
+ (unsigned long long) up_cent * HZ / 100;
+
+ fclose(fp);
+
+}
+
+#ifdef SOURCE_SADC
+/*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/
+
+/*
+ ***************************************************************************
+ * Replace octal codes in string with their corresponding characters.
+ *
+ * IN:
+ * @str String to parse.
+ *
+ * OUT:
+ * @str String with octal codes replaced with characters.
+ ***************************************************************************
+ */
+void oct2chr(char *str)
+{
+ int i = 0;
+ int j, len;
+
+ len = strlen(str);
+
+ while (i < len - 3) {
+ if ((str[i] == '\\') &&
+ (str[i + 1] >= '0') && (str[i + 1] <= '3') &&
+ (str[i + 2] >= '0') && (str[i + 2] <= '7') &&
+ (str[i + 3] >= '0') && (str[i + 3] <= '7')) {
+ /* Octal code found */
+ str[i] = (str[i + 1] - 48) * 64 +
+ (str[i + 2] - 48) * 8 +
+ (str[i + 3] - 48);
+ for (j = i + 4; j <= len; j++) {
+ str[j - 3] = str[j];
+ }
+ len -= 3;
+ }
+ i++;
+ }
+}
+
+/*
+ ***************************************************************************
+ * Read processes (tasks) creation and context switches statistics
+ * from /proc/stat.
+ *
+ * IN:
+ * @st_pcsw Structure where stats will be saved.
+ *
+ * OUT:
+ * @st_pcsw Structure with statistics.
+ ***************************************************************************
+ */
+void read_stat_pcsw(struct stats_pcsw *st_pcsw)
+{
+ FILE *fp;
+ char line[8192];
+
+ if ((fp = fopen(STAT, "r")) == NULL)
+ return;
+
+ while (fgets(line, 8192, fp) != NULL) {
+
+ if (!strncmp(line, "ctxt ", 5)) {
+ /* Read number of context switches */
+ sscanf(line + 5, "%llu", &st_pcsw->context_switch);
+ }
+
+ else if (!strncmp(line, "processes ", 10)) {
+ /* Read number of processes created since system boot */
+ sscanf(line + 10, "%lu", &st_pcsw->processes);
+ }
+ }
+
+ fclose(fp);
+}
+
+/*
+ ***************************************************************************
+ * Read queue and load statistics from /proc/loadavg and /proc/stat.
+ *
+ * IN:
+ * @st_queue Structure where stats will be saved.
+ *
+ * OUT:
+ * @st_queue Structure with statistics.
+ ***************************************************************************
+ */
+void read_loadavg(struct stats_queue *st_queue)
+{
+ FILE *fp;
+ char line[8192];
+ int load_tmp[3];
+
+ if ((fp = fopen(LOADAVG, "r")) == NULL)
+ return;
+
+ /* Read load averages and queue length */
+ fscanf(fp, "%d.%d %d.%d %d.%d %ld/%d %*d\n",
+ &load_tmp[0], &st_queue->load_avg_1,
+ &load_tmp[1], &st_queue->load_avg_5,
+ &load_tmp[2], &st_queue->load_avg_15,
+ &st_queue->nr_running,
+ &st_queue->nr_threads);
+
+ fclose(fp);
+
+ st_queue->load_avg_1 += load_tmp[0] * 100;
+ st_queue->load_avg_5 += load_tmp[1] * 100;
+ st_queue->load_avg_15 += load_tmp[2] * 100;
+
+ if (st_queue->nr_running) {
+ /* Do not take current process into account */
+ st_queue->nr_running--;
+ }
+
+ /* Read nr of tasks blocked from /proc/stat */
+ if ((fp = fopen(STAT, "r")) == NULL)
+ return;
+
+ while (fgets(line, 8192, fp) != NULL) {
+
+ if (!strncmp(line, "procs_blocked ", 14)) {
+ /* Read number of processes blocked */
+ sscanf(line + 14, "%lu", &st_queue->procs_blocked);
+ break;
+ }
+ }
+
+ fclose(fp);
+}
+
/*
***************************************************************************
* Read swapping statistics from /proc/vmstat.
fclose(fp);
}
-/*
- ***************************************************************************
- * Read machine uptime, independently of the number of processors.
- *
- * OUT:
- * @uptime Uptime value in jiffies.
- ***************************************************************************
- */
-void read_uptime(unsigned long long *uptime)
-{
- FILE *fp;
- char line[128];
- unsigned long up_sec, up_cent;
-
- if ((fp = fopen(UPTIME, "r")) == NULL)
- return;
-
- if (fgets(line, 128, fp) == NULL) {
- fclose(fp);
- return;
- }
-
- sscanf(line, "%lu.%lu", &up_sec, &up_cent);
- *uptime = (unsigned long long) up_sec * HZ +
- (unsigned long long) up_cent * HZ / 100;
-
- fclose(fp);
-
-}
+/*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
+#endif /* SOURCE_SADC */