static void ps_collect_proc_stat(struct stats *stats) { const char *path = "/proc/stat"; FILE *file = NULL; char file_buf[4096]; char *line = NULL; size_t line_size = 0; file = fopen(path, "r"); if (file == NULL) { ERROR("cannot open `%s': %m\n", path); goto out; } setvbuf(file, file_buf, _IOFBF, sizeof(file_buf)); while (getline(&line, &line_size, file) >= 0) { char *key, *rest = line; key = wsep(&rest); if (key == NULL || rest == NULL) continue; if (strncmp(key, "cpu", 3) == 0) continue; if (strcmp(key, "intr") == 0) continue; errno = 0; unsigned long long val = strtoull(rest, NULL, 0); if (errno == 0) stats_set(stats, key, val); } out: free(line); if (file != NULL) fclose(file); }
static void proc_collect_pid(struct stats_type *type, const char *pid) { struct stats *stats = NULL; char path[32]; char process[512]; FILE *file = NULL; char file_buf[4096]; char *line = NULL; size_t line_size = 0; char name[16]; char cmask[512]; char mmask[32]; TRACE("pid %s\n", pid); snprintf(path, sizeof(path), "/proc/%s/status", pid); file = fopen(path, "r"); if (file == NULL) { ERROR("cannot open `%s': %m\n",path); goto out; } setvbuf(file, file_buf, _IOFBF, sizeof(file_buf)); while (getline(&line, &line_size, file) >= 0) { char *key, *rest = line; key = wsep(&rest); if (key == NULL || rest == NULL) continue; rest[strlen(rest) - 1] = '\0'; if (strcmp(key, "Name:") == 0) { if (!strcmp("bash", rest) || !strcmp("ssh", rest) || !strcmp("sshd", rest) || !strcmp("metacity", rest)) goto out; strcpy(name, rest); } else if (strcmp(key, "Cpus_allowed_list:") == 0) { strcpy(cmask, rest); } else if (strcmp(key, "Mems_allowed_list:") == 0) { strcpy(mmask, rest); } } snprintf(process, sizeof(process), "%s/%s/%s/%s", name, pid, cmask, mmask); stats = get_current_stats(type, process); if (stats == NULL) goto out; fseek(file, 0, SEEK_SET); while (getline(&line, &line_size, file) >= 0) { char *key, *rest = line; key = wsep(&rest); if (key == NULL || rest == NULL) continue; errno = 0; key[strlen(key) - 1] = '\0'; unsigned long long val = strtoull(rest, NULL, 0); if (errno == 0) stats_set(stats, key, val); } out: free(line); if (file != NULL) fclose(file); }
static void collect_mdc_fs(struct stats *stats, const char *d_name) { char *path = NULL; FILE *file = NULL; char file_buf[4096]; char *line_buf = NULL; size_t line_buf_size = 0; if (asprintf(&path, "%s/%s/stats", MDC_DIR_PATH, d_name) < 0) { ERROR("cannot create path: %m\n"); goto out; } file = fopen(path, "r"); if (file == NULL) { ERROR("cannot open `%s': %m\n", path); goto out; } setvbuf(file, file_buf, _IOFBF, sizeof(file_buf)); // $ cat /proc/fs/lustre/mdc/work-MDT0000-mdc-ffff8104435c8c00/stats // snapshot_time 1315505833.280916 secs.usecs // req_waittime 1885503 samples [usec] 32 4826358 908745020 670751020176306 // req_active 1885503 samples [reqs] 1 357 2176198 17811836 // mds_getattr 231 samples [usec] 50 5735 45029 60616599 // mds_close 312481 samples [usec] 38 356200 47378914 142563767708 // mds_readpage 12187 samples [usec] 80 16719 3185676 4923626688 // mds_connect 1 samples [usec] 302 302 302 91204 // mds_getstatus 1 samples [usec] 273 273 273 74529 // mds_statfs 30 samples [usec] 130 444 7765 2137505 // mds_sync 262 samples [usec] 3042 4826358 33767303 73003166559545 // mds_quotactl 6030 samples [usec] 466 1667578 23448377 4610731893889 // ldlm_cancel 169832 samples [usec] 32 8257 25752413 4873947759 // obd_ping 112820 samples [usec] 40 1543848 548167082 592878039802964 /* Skip snapshot. */ getline(&line_buf, &line_buf_size, file); while (getline(&line_buf, &line_buf_size, file) >= 0) { char *line = line_buf; char *key = wsep(&line); if (key == NULL || line == NULL) continue; unsigned long long count = 0, sum = 0; if (sscanf(line, "%llu samples %*s %*u %*u %llu", &count, &sum) != 2) continue; if (strcmp(key, "req_waittime") == 0) { stats_set(stats, "reqs", count); stats_set(stats, "wait", sum); } else { stats_set(stats, key, count); } } out: free(line_buf); if (file != NULL) fclose(file); free(path); }
static void collect_irq_stats( struct stats_type *type, const char *path ) { FILE *file = NULL; char *line = NULL; size_t line_size = 0; file = fopen( path, "r" ); if ( file == NULL ) { //ERROR( "cannot open `%s': %m\n", path ); goto out; } while ( 0 <= getline( &line, &line_size, file ) ) { char *rest = line; char *key = wsep( &rest ); if ( key == NULL || rest == NULL ) continue; if ( ! strncasecmp( key, "cpu0", 4 ) ) continue; #define X(k,r...) k = 0 unsigned long long KEYS; #undef X if ( 0 < sscanf( rest, #define X(k,r...) " %llu" JOIN( KEYS ) #undef X #define X(k,r...) &k , KEYS ) ) { #undef X /* remove the colon */ char *t = key; do { if ( ':' == *t ) *t = '\0'; } while ( *t++ ); /* check if the key is a number of not */ strtoul( key, &t, 10 ); if ( '\0' == *t ) { /* so the key is a number, e.g. like the following CPU0 CPU1 CPU2 CPU3 0: 198 1 0 0 IO-APIC-edge timer 1: 0 2 2 3 IO-APIC-edge i8042 4: 0 0 4 0 IO-APIC-edge serial 6: 0 0 1 1 IO-APIC-edge floppy 8: 0 0 1 0 IO-APIC-edge rtc0 ... */ /* get the real device name from the last column(s) */ /* An x86 IRQ description is of form "%s-%s %s" where the first %s is from the "name" field, e.g. in arch/x86/kernel/apic/io_apic.c : static struct irq_chip ioapic_chip __read_mostly = { .name = "IO-APIC", .irq_startup = startup_ioapic_irq, .irq_mask = mask_ioapic_irq, .irq_unmask = unmask_ioapic_irq, .irq_ack = ack_apic_edge, .irq_eoi = ack_apic_level, #ifdef CONFIG_SMP .irq_set_affinity = ioapic_set_affinity, #endif .irq_retrigger = ioapic_retrigger_irq, }; */ /* ignore interrupts from certain devices, e.g. keyboard, floppy, USB, etc */ if ( strstr( rest, " i8042" ) || strstr( rest, " floppy" ) || strstr( rest, ":usb" ) || strstr( rest, " serial" ) ) continue; size_t s = strspn( rest, "0123456789: \t\n\r" ); if ( '\0' == rest[s] ) continue; /* there is no last column; move on */ rest += s; wsep( &rest ); if ( NULL == rest ) continue; s = strspn( rest, " \t\n\r" ); if ( '\0' == rest[s] ) continue; /* replace every space with underscore */ t = key = rest + s; do { if ( '\r' == *t || '\n' == *t ) *t = '\0'; if ( isspace( *t ) ) *t = '_'; } while ( *t++ ); } struct stats *stats = get_current_stats( type, key ); if ( NULL == stats ) break; #define X(k,r...) stats_set(stats, #k, k) KEYS; #undef X } } out: if ( NULL != line ) free( line ); if ( NULL != file ) fclose( file ); }