/* --------------------------------------------------------------------------- */ float find_disk_space(double *total_size, double *total_free) { FILE *mounts; char procline[1024]; char *mount, *device, *type, *mode, *other; /* We report in GB = 1e9 bytes. */ double reported_units = 1e9; /* Track the most full disk partition, report with a percentage. */ float thispct, max=0.0; /* Read all currently mounted filesystems. */ mounts=fopen(MOUNTS,"r"); if (!mounts) { debug_msg("Df Error: could not open mounts file %s. Are we on the right OS?\n", MOUNTS); return max; } while ( fgets(procline, sizeof(procline), mounts) ) { device = procline; mount = index(procline, ' '); if (mount == NULL) continue; *mount++ = '\0'; type = index(mount, ' '); if (type == NULL) continue; *type++ = '\0'; mode = index(type, ' '); if (mode == NULL) continue; *mode++ = '\0'; other = index(mode, ' '); if (other != NULL) *other = '\0'; if (!strncmp(mode, "ro", 2)) continue; if (remote_mount(device, type)) continue; if (strncmp(device, "/dev/", 5) != 0 && strncmp(device, "/dev2/", 6) != 0 && strncmp(type, "zfs", 3) != 0) continue; thispct = device_space(mount, device, total_size, total_free); debug_msg("Counting device %s (%.2f %%)", device, thispct); if (!max || max<thispct) max = thispct; } fclose(mounts); *total_size = *total_size / reported_units; *total_free = *total_free / reported_units; debug_msg("For all disks: %.3f GB total, %.3f GB free for users.", *total_size, *total_free); DFcleanup(); return max; }
int scan_mounts(apr_pool_t *p) { FILE *mounts; char procline[256]; char mount[128], device[128], type[32], mode[128]; int rc; fs_info_t *fs; filesystems = apr_array_make(p, 2, sizeof(fs_info_t)); metric_info = apr_array_make(p, 2, sizeof(Ganglia_25metric)); mounts = fopen(MOUNTS, "r"); if (!mounts) { debug_msg("Df Error: could not open mounts file %s. Are we on the right OS?\n", MOUNTS); return -1; } while ( fgets(procline, sizeof(procline), mounts) ) { rc=sscanf(procline, "%s %s %s %s ", device, mount, type, mode); if (!rc) continue; //if (!strncmp(mode, "ro", 2)) continue; if (remote_mount(device, type)) continue; if (strncmp(device, "/dev/", 5) != 0 && strncmp(device, "/dev2/", 6) != 0) continue; fs = apr_array_push(filesystems); bzero(fs, sizeof(fs_info_t)); fs->device = apr_pstrdup(p, device); fs->mount_point = apr_pstrdup(p, mount); fs->fs_type = apr_pstrdup(p, type); set_ganglia_name(p, fs); create_metrics_for_device(p, metric_info, fs); //thispct = device_space(mount, device, total_size, total_free); debug_msg("Found device %s (%s)", device, type); } fclose(mounts); return 0; }
int readDiskCounters(HSP *sp, SFLHost_dsk_counters *dsk) { int gotData = NO; FILE *procFile; procFile= fopen("/proc/diskstats", "r"); if(procFile) { // ASCII numbers in /proc/diskstats may be 64-bit (if not now // then someday), so it seems safer to read into // 64-bit ints with scanf first, then copy them // into the host_dsk structure from there. uint32_t majorNo; uint32_t minorNo; uint64_t reads = 0; /* uint64_t reads_merged = 0;*/ uint64_t sectors_read = 0; uint64_t read_time_ms = 0; uint64_t writes = 0; /* uint64_t writes_merged = 0;*/ uint64_t sectors_written = 0; uint64_t write_time_ms = 0; // handle 64-bit counters specially uint64_t total_sectors_read = 0; uint64_t total_sectors_written = 0; // limit the number of chars we will read from each line // (there can be more than this - fgets will chop for us) #define MAX_PROC_LINE_CHARS 240 char line[MAX_PROC_LINE_CHARS]; char devName[MAX_PROC_LINE_CHARS]; while(fgets(line, MAX_PROC_LINE_CHARS, procFile)) { if(sscanf(line, "%"SCNu32" %"SCNu32" %s %"SCNu64" %*u %"SCNu64" %"SCNu64" %"SCNu64" %*u %"SCNu64" %"SCNu64"", &majorNo, &minorNo, devName, &reads, /*&reads_merged,*/ §ors_read, &read_time_ms, &writes, /*&writes_merged,*/ §ors_written, &write_time_ms) == 9) { gotData = YES; // report the sum over all disks dsk->reads += reads; total_sectors_read += sectors_read; dsk->read_time += read_time_ms; dsk->writes += writes; total_sectors_written += sectors_written; dsk->write_time += write_time_ms; } } fclose(procFile); // accumulate the 64-bit counters (they may only be 32-bit counters in this OS) sp->diskIO.bytes_read += (total_sectors_read - sp->diskIO.last_sectors_read) * ASSUMED_DISK_SECTOR_BYTES; sp->diskIO.last_sectors_read = total_sectors_read; sp->diskIO.bytes_written += (total_sectors_written - sp->diskIO.last_sectors_written) * ASSUMED_DISK_SECTOR_BYTES; sp->diskIO.last_sectors_written = total_sectors_written; // and copy the accumulated total into the output dsk->bytes_read = sp->diskIO.bytes_read; dsk->bytes_written = sp->diskIO.bytes_written; } // borrowed heavily from ganglia/linux/metrics.c for this part where // we read the mount points and then interrogate them to add up the // disk space on local disks. procFile = fopen("/proc/mounts", "r"); if(procFile) { #undef MAX_PROC_LINE_CHARS #define MAX_PROC_LINE_CHARS 240 char line[MAX_PROC_LINE_CHARS]; char device[MAX_PROC_LINE_CHARS]; char mount[MAX_PROC_LINE_CHARS]; char type[MAX_PROC_LINE_CHARS]; char mode[MAX_PROC_LINE_CHARS]; void *treeRoot = NULL; while(fgets(line, MAX_PROC_LINE_CHARS, procFile)) { if(sscanf(line, "%s %s %s %s", device, mount, type, mode) == 4) { // must start with /dev/ or /dev2/ if(strncmp(device, "/dev/", 5) == 0 || strncmp(device, "/dev2/", 6) == 0) { // must be read-write if(strncmp(mode, "ro", 2) != 0) { // must be local if(!remote_mount(device, type)) { // don't count it again if it was seen before if(tfind(device, &treeRoot, (comparison_fn_t)strcmp) == NULL) { // not found, so remember it tsearch(strdup(device), &treeRoot, (comparison_fn_t)strcmp); // and get the numbers struct statvfs svfs; if(statvfs(mount, &svfs) == 0) { if(svfs.f_blocks) { uint64_t dtot64 = (uint64_t)svfs.f_blocks * (uint64_t)svfs.f_bsize; uint64_t dfree64 = (uint64_t)svfs.f_bavail * (uint64_t)svfs.f_bsize; dsk->disk_total += dtot64; dsk->disk_free += dfree64; // percent used (as % * 100) uint32_t pc = (uint32_t)(((dtot64 - dfree64) * 10000) / dtot64); if(pc > dsk->part_max_used) dsk->part_max_used = pc; } } } } } } } } tdestroy(treeRoot, free); fclose(procFile); } return gotData; }