source: src-qt4/pc-mounttray/fsWatcher.cpp @ f996b54

releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since f996b54 was f996b54, checked in by Ken Moore <ken@…>, 7 months ago

Make sure to exclude the "fusefs" filesystem from showing up in the pc-mounttray disk space watcher (to prevent showing the new PBI containers).

  • Property mode set to 100644
File size: 6.3 KB
Line 
1#include "fsWatcher.h"
2
3FSWatcher::FSWatcher() : QObject(){
4  //setup the timer
5  timer = new QTimer();
6  timer->setSingleShot(TRUE);
7  QObject::connect(timer, SIGNAL(timeout()), this, SLOT(checkFS()));
8}
9
10FSWatcher::~FSWatcher(){
11}
12
13void FSWatcher::start(int ms){ 
14    timer->stop();
15    timer->setInterval(ms); //max time between system checks
16    timer->start(); 
17    QTimer::singleShot(2000,this,SLOT(checkFS()) ); //make sure to perform a check when it starts up
18}
19
20void FSWatcher::stop(){
21  timer->stop();
22}
23
24QStringList FSWatcher::getFSmountpoints(){
25  //output line format: name::filesystem::totalspace::usedspace::percent
26  // -- sizes all in K
27  QStringList output; 
28  //ZFS Checks
29  QStringList zpools = runCMD("zpool list -o name");
30  if(zpools.length() > 1){ 
31    //Then there are ZFS pools available
32    for(int i=1; i<zpools.length(); i++){ //skip the header line
33      QStringList tmp = runCMD("zfs list -o available,used "+zpools[i]);
34      //second line contains the data
35      QString avail = tmp[1].section(" ",0,0,QString::SectionSkipEmpty);
36      QString used = tmp[1].section(" ",1,1,QString::SectionSkipEmpty);
37      double iUsed = floor(displayToDouble(used));
38      double iTotal = floor(displayToDouble(avail)) + iUsed;
39      int percent = calculatePercentage(iUsed, iTotal);
40      //qDebug() << "Percent calc: tot:"<<iTotal<<"used"<<iUsed<<"percent"<<percent;
41      //format the output string and add it in
42      output << zpools[i]+"::zfs::"+QString::number(iTotal)+"::"+QString::number(iUsed)+"::"+QString::number(percent);
43    }
44  }
45  //Now get all the rest of the mounted filesystems
46  QStringList dfout = runCMD("df -h -T");
47  //Format: name, filesystem, size, used, available, percent, mountpoint
48  for(int i=1; i<dfout.length(); i++){
49    //ignore certain filesystems
50    if(dfout[i].startsWith("devfs")){}
51    else if(dfout[i].startsWith("procfs")){}
52    else if(dfout[i].startsWith("linprocfs")){}
53    else if(dfout[i].startsWith("linsysfs")){}
54    else if(dfout[i].startsWith("fdescfs")){}
55    else{
56      //Now parse out the info 
57      dfout[i].replace("\t"," ");
58      QString fs = dfout[i].section("  ",1,1,QString::SectionSkipEmpty).simplified();
59      if(fs != "zfs" && fs!="cd9660" && fs!="nullfs" && fs!="fusefs"){  //ignore zfs filesystems (already taken care of)
60        QString name = dfout[i].section("  ",6,6,QString::SectionSkipEmpty).simplified();
61        QString total = dfout[i].section("  ",2,2,QString::SectionSkipEmpty).simplified();
62        QString used = dfout[i].section("  ",3,3,QString::SectionSkipEmpty).simplified();
63        //Calculate the percent
64        double iUsed = displayToDouble(used);
65        double iTotal = displayToDouble(total);
66        int percent = calculatePercentage(iUsed, iTotal);
67        //qDebug() << "df Item:" << dfout[i];
68        //qDebug() << " - Detected:" << name << fs << iTotal << iUsed << percent;
69        //format the output string and add it in
70        output << name+"::"+fs+"::"+QString::number(iTotal)+"::"+QString::number(iUsed)+"::"+QString::number(percent);
71      }
72    }
73  }
74  //Return the results
75  //qDebug() << "FS output:" << output;
76  return output;
77 
78}
79
80int FSWatcher::displayToDouble(QString entry){
81  //split the number from the size label
82  //qDebug() << "Display to Int conversion:" << entry;
83  QString units = entry.right(1); //last character
84  entry.chop(1); //remove the unit
85  double num = entry.toDouble();
86  //qDebug() << "initial number:" << num << "units:" << units;
87  QStringList unitL; unitL << "K" << "M" << "G" << "T" << "P" << "E" << "Z" << "Y";
88  bool ok = false;
89  for(int i=0; i< unitL.length(); i++){
90    if(units == unitL[i]){ num = num*pow(1024.0,i); ok = true; break;}
91  }
92  if(!ok){num=0; }
93  //qDebug() << "number:" << num;
94  return num;
95}
96
97QString FSWatcher::doubleToDisplay(double K){
98  QString num;
99  //qDebug() << "Int to Display:" << K;
100  double kdb = K; //using pure integers causes errors with large numbers
101  QStringList units; units << "K" << "M" << "G" << "T" << "P" << "E" << "Z" << "Y";
102  int i=0;
103  while( (kdb > 1000) && (i < 8) ){
104    kdb = kdb/1024;
105    i++;
106  }
107  if(i<8){
108    num = QString::number( int((kdb*100))/100.0) + units[i];
109  }else{
110    num = "??";
111  }
112  //qDebug() << "Display:" << num;
113  return num;
114         
115}
116
117//====== Public Slot =======
118void FSWatcher::checkFS(){
119  QStringList devList = getFSmountpoints();
120  QStringList badDevs;
121  for(int i=0; i<devList.length(); i++){
122    int percent = devList[i].section("::",4,4).toInt();
123    if(percent > 90){
124      //Device greater than 90% full, warn the user
125      badDevs << devList[i].section("::",0,0); //list the mountpoint
126      qDebug() << "WARNING: Device almost full:" << devList[i].section("::",0,0)+": "+QString::number(percent)+"% full: Time: "+QTime::currentTime().toString();
127    }
128  }
129  if(!badDevs.isEmpty()){
130    //check to make sure these are new "bad" devices
131    bool newFound = FALSE;
132    for(int i=0; i<badDevs.length(); i++){
133      if( oldBadDevs.indexOf(badDevs[i]) == -1){ newFound = TRUE; }         
134    }
135    if(newFound){
136      QString title = tr("Disk(s) Almost Full");
137      QString message = badDevs.join(", ");
138      emit FSWarning(title,message);
139    }
140  }
141  //Save the current badDevs as the old list
142  oldBadDevs = badDevs;
143  //Reset the timer for the next time this function is to be called
144  timer->start(); //reset the timer again
145}
146
147//===== Calculate Percentages =====
148int FSWatcher::calculatePercentage(double used, double total){
149  double U = used;
150  double T = total;
151  double result = (U/T)*100.0;
152  return result; //will remove decimel places;
153}
154//====== Run System Command Function ======
155QStringList FSWatcher::runCMD(QString command){
156   QProcess p;
157   QString outstr;
158   //Make sure we use the system environment to properly read system variables, etc.
159   QProcessEnvironment penv = QProcessEnvironment::systemEnvironment();
160   penv.insert("BLOCKSIZE","K"); //make sure we use a 1KB block size
161   p.setProcessEnvironment(penv);
162   //Merge the output channels to retrieve all output possible
163   p.setProcessChannelMode(QProcess::MergedChannels);   
164   p.start(command);
165   while(p.state()==QProcess::Starting || p.state() == QProcess::Running){
166     p.waitForFinished(200);
167     QCoreApplication::processEvents();
168   }
169   QString tmp = p.readAllStandardOutput();
170   outstr.append(tmp);
171   if(outstr.endsWith("\n")){outstr.chop(1);} //remove the newline at the end
172   QStringList out = outstr.split("\n");
173   return out;
174}
Note: See TracBrowser for help on using the repository browser.