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

9.1-release9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 781fd04 was 781fd04, checked in by Ken Moore <ken@…>, 21 months ago

Make sure the mount tray disk space notifier only displays the warning for new devices that are over 90% full.

  • Property mode set to 100644
File size: 6.0 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      int iUsed = displayToInt(used);
38      int iTotal = displayToInt(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{
54      //Now parse out the info 
55      dfout[i].replace("\t"," ");
56      QString fs = dfout[i].section("  ",1,1,QString::SectionSkipEmpty).simplified();
57      if(fs != "zfs"){  //ignore zfs filesystems (already taken care of)
58        QString name = dfout[i].section("  ",6,6,QString::SectionSkipEmpty).simplified();
59        QString total = dfout[i].section("  ",2,2,QString::SectionSkipEmpty).simplified();
60        QString used = dfout[i].section("  ",3,3,QString::SectionSkipEmpty).simplified();
61        //Calculate the percent
62        int iUsed = displayToInt(used);
63        int iTotal = displayToInt(total);
64        int percent = calculatePercentage(iUsed, iTotal);
65        //qDebug() << "df Item:" << dfout[i];
66        //qDebug() << " - Detected:" << name << fs << iTotal << iUsed << percent;
67        //format the output string and add it in
68        output << name+"::"+fs+"::"+QString::number(iTotal)+"::"+QString::number(iUsed)+"::"+QString::number(percent);
69      }
70    }
71  }
72  //Return the results
73  //qDebug() << "FS output:" << output;
74  return output;
75 
76}
77
78int FSWatcher::displayToInt(QString entry){
79  //split the number from the size label
80  //qDebug() << "Display to Int conversion:" << entry;
81  QString units = entry.right(1); //last character
82  entry.chop(1); //remove the unit
83  double num = entry.toDouble();
84  //qDebug() << "initial number:" << num << "units:" << units;
85  if(units=="K"){} //Kilobytes (no change)
86  else if(units=="M"){ num=num*1024; } //Megabytes to K
87  else if(units=="G"){ num=num*1048576; } //Gigabytes to K
88  else{ num=0; } //smaller than a KB
89  //qDebug() << "number:" << num;
90  return num;
91}
92
93QString FSWatcher::intToDisplay(int K){
94  QString num;
95  //qDebug() << "Int to Display:" << K;
96  double kdb = K; //using pure integers causes errors with large numbers
97  if( K > 1048576 ){ num = QString::number( int((kdb*100)/1048576)/100.0 ) +"G"; }
98  else if(K > 1024){ num = QString::number( int((kdb*100)/1024)/100.0 ) +"M"; }
99  else{ num = QString::number(K) +"K"; }
100  //qDebug() << "Display:" << num;
101  return num;
102         
103}
104
105//====== Public Slot =======
106void FSWatcher::checkFS(){
107  QStringList devList = getFSmountpoints();
108  QStringList badDevs;
109  for(int i=0; i<devList.length(); i++){
110    int percent = devList[i].section("::",4,4).toInt();
111    if(percent > 90){
112      //Device greater than 90% full, warn the user
113      badDevs << devList[i].section("::",0,0); //list the mountpoint
114      qDebug() << "WARNING: Device almost full:" << devList[i].section("::",0,0)+": "+QString::number(percent)+"% full: Time: "+QTime::currentTime().toString();
115    }
116  }
117  if(!badDevs.isEmpty()){
118    //check to make sure these are new "bad" devices
119    bool newFound = FALSE;
120    for(int i=0; i<badDevs.length(); i++){
121      if( oldBadDevs.indexOf(badDevs[i]) == -1){ newFound = TRUE; }         
122    }
123    if(newFound){
124      QString title = tr("Disk(s) Almost Full");
125      QString message = badDevs.join(", ");
126      emit FSWarning(title,message);
127    }
128  }
129  //Save the current badDevs as the old list
130  oldBadDevs = badDevs;
131  //Reset the timer for the next time this function is to be called
132  timer->start(); //reset the timer again
133}
134
135//===== Calculate Percentages =====
136int FSWatcher::calculatePercentage(int used, int total){
137  double U = used;
138  double T = total;
139  double result = (U/T)*100.0;
140  return result; //will remove decimel places;
141}
142//====== Run System Command Function ======
143QStringList FSWatcher::runCMD(QString command){
144   QProcess p;
145   QString outstr;
146   //Make sure we use the system environment to properly read system variables, etc.
147   QProcessEnvironment penv = QProcessEnvironment::systemEnvironment();
148   penv.insert("BLOCKSIZE","K"); //make sure we use a 1KB block size
149   p.setProcessEnvironment(penv);
150   //Merge the output channels to retrieve all output possible
151   p.setProcessChannelMode(QProcess::MergedChannels);   
152   p.start(command);
153   while(p.state()==QProcess::Starting || p.state() == QProcess::Running){
154     p.waitForFinished(200);
155     QCoreApplication::processEvents();
156   }
157   QString tmp = p.readAllStandardOutput();
158   outstr.append(tmp);
159   if(outstr.endsWith("\n")){outstr.chop(1);} //remove the newline at the end
160   QStringList out = outstr.split("\n");
161   return out;
162}
Note: See TracBrowser for help on using the repository browser.