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

9.1-release9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since bb6089a was bb6089a, checked in by beanpole135 <ken@…>, 19 months ago

Add the ability for the mount tray to monitor/warn the user about disks that are almost full. Also add a new dialog that will show the current disk usage for the entire system. Still need to clean up the menu a bit, and add the ability to change settings for this.

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