LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File xosview-1.9.2-diskstat.dif of Package xosview (Project X11:Utilities)

--- 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;