File xosview-1.9.2-diskstat.dif of Package xosview
--- linux/diskmeter.cc
+++ linux/diskmeter.cc 2008-05-15 15:52:19.000000000 +0000
@@ -219,8 +219,8 @@ void DiskMeter::update_info(unsigned lon
}
// convert rate from bytes/microsec into bytes/second
- fields_[0] = ((rsum - sysfs_read_prev_ ) * 1e6 ) / itim;
- fields_[1] = ((wsum - sysfs_write_prev_) * 1e6 ) / itim;
+ fields_[0] = ((rsum - sysfs_read_prev_ ) * 1e5 ) / itim;
+ fields_[1] = ((wsum - sysfs_write_prev_) * 1e5 ) / itim;
// fix overflow (conversion bug?)
if (fields_[0] < 0.0)
@@ -257,19 +257,14 @@ void DiskMeter::getsysfsdiskinfo( void )
// just sum up everything in /sys/block/*/stat
std::string sysfs_dir = _statFileName;
- std::string disk;
struct stat buf;
- std::ifstream diskstat;
// the sum of all disks:
unsigned long long all_bytes_read,all_bytes_written;
// ... while this is only one disk's value:
- unsigned long sec_read,sec_written;
unsigned long sect_size;
- unsigned long dummy;
-
IntervalTimerStop();
total_ = maxspeed_;
@@ -281,29 +276,83 @@ void DiskMeter::getsysfsdiskinfo( void )
// reset all sums
all_bytes_read=all_bytes_written=0L;
- sect_size=0L;
// visit every /sys/block/*/stat and sum up the values:
for (struct dirent *dirent; (dirent = readdir(dir)) != NULL; ) {
+ std::string disk;
+
if (strncmp(dirent->d_name, ".", 1) == 0
- || strncmp(dirent->d_name, "..", 2) == 0)
+ || strncmp(dirent->d_name, "..", 2) == 0
+ || strncmp(dirent->d_name, "loop", 4) == 0
+ || strncmp(dirent->d_name, "ram", 3) == 0
+ || strncmp(dirent->d_name, "fd", 2) == 0)
continue;
disk = sysfs_dir + "/" + dirent->d_name;
if (stat(disk.c_str(), &buf) == 0 && buf.st_mode & S_IFDIR) {
+ std::string tmp;
+
+ // only scan for real HW (raid, md, and lvm all mapped on them)
+ tmp = disk + "/device";
+ if (lstat(tmp.c_str(), &buf) != 0 || (buf.st_mode & S_IFLNK) == 0)
+ continue;
+
+ // ignore removable devices
+ tmp = disk + "/removable";
+ if (stat(tmp.c_str(), &buf) == 0 && buf.st_mode & S_IFREG) {
+ std::ifstream removable;
+ int isremovable = 0;
+
+ removable.open(tmp.c_str());
+ if (removable.good()) {
+ removable >> isremovable;
+ removable.close();
+ removable.clear();
+ }
+
+ if (isremovable) continue;
+ }
+
+ sect_size = 0UL;
+
+ tmp = "/dev/";
+ tmp += dirent->d_name;
+ if (lstat(tmp.c_str(), &buf) == 0)
+ sect_size = (unsigned long)buf.st_blksize;
+
+ if (sect_size == 0UL) {
+ tmp = disk + "/queue/max_sectors_kb";
+ if (stat(tmp.c_str(), &buf) == 0 && (buf.st_mode & S_IFREG)) {
+ std::ifstream max_sectors_kb;
+
+ max_sectors_kb.open(tmp.c_str());
+ if (max_sectors_kb.good()) {
+ max_sectors_kb >> sect_size;
+ //XOSDEBUG("disk stat: %lu\n", sect_size);
+ max_sectors_kb.close();
+ max_sectors_kb.clear();
+ }
+ }
+ }
+
+ if (sect_size == 0UL)
+ sect_size = 512; // XXX: not always true
+
// is a dir, locate 'stat' file in it
disk = disk + "/stat";
if (stat(disk.c_str(), &buf) == 0 && buf.st_mode & S_IFREG) {
+ std::ifstream diskstat;
+
//XOSDEBUG("disk stat: %s\n",disk.c_str() );
diskstat.open(disk.c_str());
if ( diskstat.good() ) {
+ unsigned long sec_read, sec_written, dummy;
+
sec_read=sec_written=0L;
diskstat >> dummy >> dummy >> sec_read >> dummy >> dummy >> dummy >> sec_written;
- sect_size = 512; // XXX: not always true
-
// XXX: ignoring wrap around case for each disk
// (would require saving old vals for each disk etc..)
all_bytes_read += (unsigned long long) sec_read * (unsigned long long) sect_size;