Changeset 03c14f8


Ignore:
Timestamp:
09/12/13 07:12:47 (12 months ago)
Author:
Kris Moore <kris@…>
Branches:
master, 9.2-release, releng/10.0, releng/10.0.1, releng/10.0.2, releng/10.0.3
Children:
4ba4baf, de39bc3b
Parents:
c0e6494 (diff), b5a7675 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of github.com:pcbsd/pcbsd

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src-qt4/EasyPBI/mainGUI.cpp

    r7369d56 r9599cf7  
    14671467 
    14681468void MainGUI::slotPBIbuildFinished(int exitCode,QProcess::ExitStatus exitStatus){ 
     1469  //Make sure that the QProcess is actually finished 
     1470  if( p->state() !=  QProcess::NotRunning ){ 
     1471    qDebug() << "QProcess finished signal, but the process is still running"; 
     1472    return; 
     1473  } 
     1474         
    14691475  //Check to see if the PBI process finished successfully 
    14701476  qDebug() << "PBI build process Finished" << exitStatus << exitCode; 
  • src-qt4/life-preserver/LPBackend.h

    r284b216 rb5a7675  
    4444        //Mirroring Management 
    4545 
    46          
    47 private: 
     46        //General utility functions 
    4847        static QStringList getCmdOutput(QString); 
    49         static int runCmd(QString); 
     48        static int runCmd(QString);      
     49 
    5050}; 
    5151#endif 
  • src-qt4/life-preserver/LPTray.cpp

    r29fe4e9 rf698804  
    44LPTray::LPTray() : QSystemTrayIcon(){ 
    55  initPhase = true; //flag that we are in the startup process 
    6   //Start up the log file watcher 
    7   QString logfile = "/var/log/lpreserver/lpreserver.log"; 
     6  //Start up the log file watcher and connect the signals/slots 
     7  watcher = new LPWatcher(); 
     8        connect(watcher,SIGNAL(MessageAvailable(QString)),this,SLOT(watcherMessage(QString)) ); 
     9         
     10  /*QString logfile = "/var/log/lpreserver/lpreserver.log"; 
    811  watcher = new QFileSystemWatcher(); 
    912        if(!QFile::exists(logfile)){  
     
    1619  LFStream = new QTextStream(logFile); 
    1720        connect(watcher, SIGNAL(fileChanged(QString)),this,SLOT(slotNewLogMessage(QString)) ); //now connect the signal/slot 
     21        */ 
    1822  //Setup the context menu 
    1923  menu = new QMenu; 
     
    2226  this->setContextMenu(menu); 
    2327  //Setup the animated icon timer 
     28  /* 
    2429  timer = new QTimer(); 
    2530        timer->setInterval(100); 
    2631        connect(timer, SIGNAL(timeout()), this, SLOT(displayWorkingIcon()) ); 
     32  */ 
    2733  //Setup initial icon for the tray 
    2834  this->setIcon( QIcon(":/images/tray-icon-idle.png") ); 
     
    3238  connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)) ); 
    3339  //Make sure we check the latest line in the logfile 
    34   QTimer::singleShot(1000, this,SLOT(firstCheck())); 
     40  //QTimer::singleShot(1000, this,SLOT(firstCheck())); 
     41  //Start up the watcher 
     42  watcher->start(); 
     43  updateTrayIcon(); 
     44  updateToolTip(); 
    3545} 
    3646 
    3747LPTray::~LPTray(){ 
    38   if(statFile != 0){ statFile->close(); } 
    39   logFile->close(); 
    40   delete statFile; 
    41   delete logFile; 
     48  //if(statFile != 0){ statFile->close(); } 
     49  //logFile->close(); 
     50  //delete statFile; 
     51  //delete logFile; 
     52  watcher->stop(); 
    4253  delete watcher; 
    43   delete menu; 
    44   delete timer; 
     54  //delete menu; 
     55  //delete timer; 
    4556} 
    4657 
     
    4859//  PRIVATE FUNCTIONS 
    4960// =============== 
     61/* 
    5062void LPTray::parseLogMessage(QString log, bool quiet){ 
    5163  //Divide up the log into it's sections 
     
    188200  return num; 
    189201} 
     202*/ 
     203 
     204void LPTray::updateTrayIcon(){ 
     205  if( watcher->hasError() ){ 
     206    //Errors - show that attention is required 
     207    this->setIcon( QIcon(":/images/tray-icon-failed.png") ); 
     208  }else if( watcher->isRunning() ){ 
     209    //Show the working icon 
     210    this->setIcon( QIcon(":/images/tray-icon-active7.png") ); 
     211  }else{ 
     212    //Show the idle icon 
     213    this->setIcon( QIcon(":/images/tray-icon-idle.png") ); 
     214  } 
     215   
     216} 
     217 
     218void LPTray::updateToolTip(){ 
     219  QStringList info = watcher->getAllCurrentMessages(); 
     220  this->setToolTip( info.join("\n") );   
     221} 
    190222 
    191223// =============== 
    192224//     PRIVATE SLOTS 
    193225// =============== 
     226void LPTray::watcherMessage(QString type){ 
     227  qDebug() << "New Watcher Message:" << type; 
     228  QStringList info; 
     229  if(type=="message"){ 
     230    //Show the message pop-up 
     231    info << "time" << "message"; 
     232    info = watcher->getMessages(type,info); 
     233    if(!info.isEmpty()){ 
     234      this->showMessage( info[0], info[1], QSystemTrayIcon::Information, 5000); 
     235    } 
     236  }else if(type=="replication"){ 
     237    info << "id" << "time" << "message"; 
     238    info = watcher->getMessages(type,info); 
     239    if(info.isEmpty()){ return; } 
     240    if(info[0] == "STARTED"){ 
     241      this->showMessage( info[1], info[2], QSystemTrayIcon::Information, 5000); 
     242    }else if(info[0] == "RUNNING"){ 
     243      //don't show anything here - just let the tooltip update 
     244    }else if(info[0] == "FINISHED"){ 
     245      this->showMessage( info[1], info[2], QSystemTrayIcon::Information, 5000); 
     246    }else if(info[0] == "ERROR"){ 
     247      this->showMessage( info[1], info[2], QSystemTrayIcon::Warning, 5000); 
     248    } 
     249     
     250  }else if(type=="critical"){ 
     251           
     252  }else if(type=="mirror"){ 
     253           
     254  } 
     255  //Update the tray icon 
     256  updateTrayIcon(); 
     257  //Update the tooltip 
     258  updateToolTip(); 
     259} 
     260/* 
    194261void LPTray::firstCheck(){ 
    195262  slotNewLogMessage("/var/log/lpreserver/lpreserver.log"); 
     
    218285  } 
    219286} 
    220  
     287*/ 
    221288void LPTray::slotTrayClicked(QSystemTrayIcon::ActivationReason reason){ 
    222289  if(reason == QSystemTrayIcon::Trigger){  
     
    248315} 
    249316 
    250 void LPTray::displayWorkingIcon(){ 
     317/*void LPTray::displayWorkingIcon(){ 
    251318  QString ico = ":/images/tray-icon-active"+QString::number(wNum)+".png"; 
    252319  this->setIcon(QIcon(ico)); 
    253320  if(wNum == 16){ wNum = 1; } //go back to the beginning of the loop 
    254321  else{ wNum++; } 
    255 } 
     322}*/ 
  • src-qt4/life-preserver/LPTray.h

    r559e01f rf698804  
    2121 
    2222private: 
    23         QFileSystemWatcher *watcher; 
     23        //QFileSystemWatcher *watcher; 
     24        LPWatcher *watcher; 
    2425        QMenu *menu; 
    25         QTimer *timer; 
     26        //QTimer *timer; 
    2627        mainUI *GUI; 
    27         QString sFile; //location of the replication status file 
    28         QFile *logFile, *statFile; 
    29         QTextStream *LFStream, *SFStream; 
    30         QString repTotK, lastSize; 
    31         int wNum; //internal tracking of which frame of the icon animation we are on 
     28        //QString sFile; //location of the replication status file 
     29        //QFile *logFile, *statFile; 
     30        //QTextStream *LFStream, *SFStream; 
     31        //QString repTotK, lastSize; 
     32        //int wNum; //internal tracking of which frame of the icon animation we are on 
    3233        bool initPhase; 
    3334 
    34         void parseLogMessage(QString, bool quiet = false); 
    35         void parseStatusMessage(QString); 
    36         void setIdleToolTip(); 
    37         void startWorkingIcon(); 
    38         void stopWorkingIcon(); 
    39         double displayToDoubleK(QString); 
     35        //void parseLogMessage(QString, bool quiet = false); 
     36        //void parseStatusMessage(QString); 
     37        //void setIdleToolTip(); 
     38        //void startWorkingIcon(); 
     39        //void stopWorkingIcon(); 
     40        //double displayToDoubleK(QString); 
    4041 
     42        void updateTrayIcon(); 
     43        void updateToolTip(); 
     44         
    4145private slots: 
    42         void firstCheck(); 
    43         void slotNewLogMessage(QString); 
     46        void watcherMessage(QString); 
     47        //void firstCheck(); 
     48        //void slotNewLogMessage(QString); 
    4449        void slotTrayClicked(QSystemTrayIcon::ActivationReason); 
    4550        void slotClose(); 
    4651        void slotSingleInstance(); 
    4752        void startGUI(); 
    48         void displayWorkingIcon(); 
     53        //void displayWorkingIcon(); 
    4954}; 
    5055 
  • src-qt4/life-preserver/LPWatcher.cpp

    rea627be rb5a7675  
    44  Each set of 10 is a different type of status 
    55    "message" status: 10-19 
    6     "running" status: 20-29 
     6    "replication" status: 20-29 
    77    "critical" status: 30-39 
     8    "mirror" status: 40-49 
     9    "resilvering" status: 50-59 
     10    "scrub" status: 60-69 
    811  Within each set: 
    912    *0 = ID Code (for internal identification as necessary) 
    1013    *1 = dataset (example: tank1) 
    11     *2 = summary (shortened version of the message - good for titles) 
     14    *2 = summary (shortened version of the message - tooltips) 
    1215    *3 = message (full message) 
    1316    *4 = timestamp (full date/time timestamp in readable format) 
     
    1619  Valid Internal ID's: 
    1720    SNAPCREATED -> new snapshot created 
    18     REPSTARTED    -> Replication task started 
    19     REPFINISHED  -> Replication task finished 
    20     REPERROR       -> Replication task failed 
     21    STARTED     -> Task started 
     22    RUNNING     -> Task running (I.E. status update) 
     23    FINISHED    -> Task finished 
     24    ERROR               -> Task failed 
    2125     
    2226*/ 
     
    3236    connect(watcher, SIGNAL(fileChanged(QString)),this,SLOT(fileChanged(QString)) ); 
    3337  timer = new QTimer(); 
    34     timer->setInterval( 600000 ); //10 minute check time 
    35     connect(timer, SIGNAL(timeout()), this, SLOT(checkErrorFile()) ); 
     38    timer->setInterval( 300000 ); //5 minute check time 
     39    connect(timer, SIGNAL(timeout()), this, SLOT(checkPoolStatus()) ); 
    3640  //initialize the log file reader 
    3741  logfile = new QFile(FILE_LOG, this); 
     
    6569  watcher->addPath(FILE_LOG); 
    6670  //Now check for any current errors in the LPbackend 
    67   checkErrorFile(); 
     71  checkPoolStatus(); 
    6872  //And start up the error file watcher 
    6973  timer->start(); 
     
    8387  unsigned int base; 
    8488  if(type=="message"){base=10;} 
    85   else if(type=="running"){base=20;} 
     89  else if(type=="replicate"){base=20;} 
    8690  else if(type=="critical"){base=30;} 
     91  else if(type=="mirror"){base=40;} 
     92  else if(type=="resilvering"){base=50;} 
     93  else if(type=="scrub"){base=60;} 
    8794  else{ return output; } //invalid input type 
    8895  //Now fill the output array based upon requested outputs 
     
    99106  //Return the output list 
    100107  return output; 
     108} 
     109 
     110QStringList LPWatcher::getAllCurrentMessages(){ 
     111  //Useful for quickly displaying all latest messages in a tooltip or summary 
     112  QStringList output; 
     113  if(LOGS.contains(12) && LOGS.contains(14)){ output << LOGS[14]+" -- "+LOGS[12]; } 
     114  if(LOGS.contains(22) && LOGS.contains(24)){ output << LOGS[24]+" -- "+LOGS[22]; } 
     115  if(LOGS.contains(32) && LOGS.contains(34)){ output << LOGS[34]+" -- "+LOGS[32]; } 
     116  if(LOGS.contains(42) && LOGS.contains(44)){ output << LOGS[44]+" -- "+LOGS[42]; } 
     117  if(LOGS.contains(52) && LOGS.contains(54)){ output << LOGS[54]+" -- "+LOGS[52]; } 
     118  if(LOGS.contains(62) && LOGS.contains(64)){ output << LOGS[64]+" -- "+LOGS[62]; } 
     119  return output; 
     120} 
     121 
     122bool LPWatcher::isRunning(){ 
     123  if(LOGS.value(20) == "STARTED" || LOGS.value(20) == "RUNNING"){ return true; } 
     124  else if(LOGS.value(40) == "STARTED" || LOGS.value(40) == "RUNNING"){ return true; } 
     125  else if(LOGS.value(50) == "STARTED" || LOGS.value(50) == "RUNNING"){ return true; } 
     126  else if(LOGS.value(60) == "STARTED" || LOGS.value(60) == "RUNNING"){ return true; } 
     127  else{ return false; } 
     128} 
     129 
     130bool LPWatcher::hasError(){ 
     131  return (LOGS.value(20)=="ERROR" || LOGS.contains(30) || LOGS.value(40)=="ERROR" || LOGS.value(50)=="ERROR" || LOGS.value(60)=="ERROR"); 
    101132} 
    102133 
     
    114145    QString dev = log.section(":",4,4).simplified(); //dataset/snapshot/nothing 
    115146    //Now decide what to do/show because of the log message 
    116     qDebug() << "New Log Message:" << log; 
     147    //qDebug() << "New Log Message:" << log; 
    117148    if(message.contains("creating snapshot")){ 
    118149      dev = message.section(" ",-1).simplified(); 
     
    120151      LOGS.insert(10,"SNAPCREATED"); 
    121152      LOGS.insert(11,dev); //dataset 
    122       LOGS.insert(12, tr("New Snapshot") ); //summary 
     153      LOGS.insert(12, QString(tr("New snapshot of %1")).arg(dev) ); //summary 
    123154      LOGS.insert(13, QString(tr("Creating snapshot for %1")).arg(dev) ); 
    124155      LOGS.insert(14, timestamp); //full timestamp 
    125156      LOGS.insert(15, time); // time only 
    126       if(!quiet){ emit NotificationMessageAvailable(); } 
     157      if(!quiet){ emit MessageAvailable("message"); } 
    127158    }else if(message.contains("starting replication")){ 
    128159      //Setup the file watcher for this new log file 
     
    135166      // 23 - Full message set on update ping 
    136167      LOGS.insert(24, timestamp); //full timestamp 
    137       LOGS.insert(25, time); // time only       
    138       //let the first ping of the replication file watcher emit the signal - don't do it now 
     168      LOGS.insert(25, time); // time only 
     169      if(!quiet){ emit MessageAvailable("replication"); } 
    139170    }else if(message.contains("finished replication")){ 
    140171      stopRepFileWatcher(); 
     
    147178      LOGS.insert(24, timestamp); //full timestamp 
    148179      LOGS.insert(25, time); // time only       
    149       if(!quiet){ emit ProcessUpdateAvailable(); } 
     180      if(!quiet){ emit MessageAvailable("replication"); } 
    150181    }else if( message.contains("FAILED replication") ){ 
    151182      stopRepFileWatcher(); 
     
    160191      LOGS.insert(24, timestamp); //full timestamp 
    161192      LOGS.insert(25, time); // time only       
    162       if(!quiet){ emit ProcessUpdateAvailable(); } 
     193      if(!quiet){ emit MessageAvailable("replication"); } 
    163194    } 
    164195           
     
    201232      lastSize = cSize; //save the current size for later 
    202233      //Now set the current process status 
     234      LOGS.insert(20,"RUNNING"); 
    203235      LOGS.insert(21,dataset); 
    204236      LOGS.insert(23,txt); 
    205       if(!quiet){ emit ProcessUpdateAvailable(); } 
     237      if(!quiet){ emit MessageAvailable("replication"); } 
    206238    } 
    207239  } 
     
    251283} 
    252284 
    253 void LPWatcher::checkErrorFile(){ 
    254   //Check zpool status and report any errors/processes 
    255   if(QFile::exists(FILE_ERROR)){ 
    256     //Read the file to determine the cause of the error 
    257     QString msg, id, summary, timestamp, time, dataset; 
    258     QFile file(FILE_ERROR); 
    259       file.open(QIODevice::ReadOnly | QIODevice::Text); 
    260       QTextStream in(&file); 
    261       qDebug() << "Error File Parsing not implemented yet. \n - File Contents:"; 
    262       while(!in.atEnd()){ 
    263         QString line = in.readLine(); 
    264         //Now look for key information on this line 
    265         qDebug() << line; 
     285void LPWatcher::checkPoolStatus(){ 
     286  //Now check zpool status for bad/running statuses 
     287  QStringList zstat = LPBackend::getCmdOutput("zpool status"); 
     288    //parse the output 
     289    QString pool, state, timestamp; 
     290    qDebug() << "-----zpool status------"; 
     291    bool newresilver = false; 
     292    for(int i=0; i<zstat.length(); i++){ 
     293      zstat[i] = zstat[i].simplified(); 
     294      if(zstat[i].isEmpty()){ continue; } 
     295      qDebug() << zstat[i]; 
     296      if(zstat[i].startsWith("pool:")){ pool = zstat[i].section(":",1,10).simplified(); } 
     297      else if(zstat[i].startsWith("state:")){ state = zstat[i].section(":",1,10).simplified(); } 
     298      else if(zstat[i].startsWith("scan:")){ 
     299        //check for scrubs/resilvering progress 
     300        bool isnew = false; 
     301        // ------ SCRUB ------ 
     302        if(zstat[i].contains("scrub")){ 
     303          //Setup the latest/running scrub info 
     304          if(zstat[i].contains(" scrub repaired ")){ 
     305            zstat[i]  = zstat[i].replace("\t"," ").simplified(); 
     306            timestamp = zstat[i].section(" ",10,14,QString::SectionSkipEmpty); 
     307            QString numFixed = zstat[i].section(" ",3,3,QString::SectionSkipEmpty); 
     308            QString numErr = zstat[i].section(" ",7,7,QString::SectionSkipEmpty); 
     309            QString timeRun = zstat[i].section(" ",5,5,QString::SectionSkipEmpty); 
     310            //Scrub finished previously 
     311            if(numFixed.toInt() > 0){  
     312              if(LOGS.value(60)!="ERROR"){ isnew=true; } 
     313              LOGS.insert(60, "ERROR");  
     314              LOGS.insert(62, QString(tr("Scrub repaired %1 bad blocks")).arg(numFixed) ); 
     315              LOGS.insert(63, QString(tr("Scrub repaired %1 blocks in %2 with %3 errors")).arg(numFixed, timeRun, numErr) ); 
     316            }else{  
     317              if(LOGS.value(60)!= " " && LOGS.value(60)!="FINISHED"){ isnew=true; } 
     318              LOGS.insert(60,"FINISHED");  
     319              LOGS.insert(62, tr("Scrub completed") ); 
     320              LOGS.insert(63, tr("Scrub completed without needing repairs") ); 
     321            } 
     322            LOGS.insert(61,pool); 
     323            LOGS.insert(64, timestamp); 
     324            LOGS.insert(65, timestamp.section(" ",3,3) ); 
     325          }else{ 
     326            //Scrub is running - parse the line 
     327            timestamp = "??"; 
     328            QString percent = "??"; 
     329            QString remain = "??"; 
     330            if(LOGS.value(60) != "RUNNING"){isnew=true;} 
     331            LOGS.insert(60,"RUNNING"); 
     332            LOGS.insert(61,pool); 
     333            LOGS.insert(62, QString(tr("Resilvering: %1")).arg(percent) ); 
     334            LOGS.insert(63, QString(tr("Resilvering: %1 (%2 remaining)")).arg(percent, remain) ); 
     335            LOGS.insert(64, timestamp); 
     336            LOGS.insert(65, timestamp.section(" ",3,3) ); 
     337            qDebug() << "***Running Scrub: line needs parsing"; 
     338          } 
     339          if(isnew){ emit MessageAvailable("scrub"); } 
     340          if(LOGS.value(50) == "RUNNING"){ 
     341            //Resilvering is done - remove the info and send a ping 
     342            LOGS.insert(50,"FINISHED"); 
     343            LOGS.insert(51,pool); 
     344            LOGS.insert(52, tr("Resilvering complete")); 
     345            LOGS.insert(53, tr("Resilvering completed successfully")); 
     346            LOGS.insert(54, timestamp); 
     347            LOGS.insert(55, timestamp.section(" ",3,3) ); 
     348            emit MessageAvailable("resilvering"); 
     349          } 
     350        // --------- RESILVERING ------- 
     351        }else if(zstat[i].contains("resilver")){ 
     352          //Setup the running re-silvering progress 
     353          if(LOGS.value(50)!= " " && LOGS.value(50)!="RUNNING"){newresilver=true; } 
     354          LOGS.insert(50, "RUNNING"); 
     355          // 51 - need to put the actual device in here (not available on this line) 
     356          LOGS.insert(52, tr("Resilvering in progress")); 
     357          if(newresilver){ LOGS.insert(53, tr("Resilvering started") ); } 
     358          else{ LOGS.insert(53, tr("Resilvering in progress")); } 
     359          LOGS.insert(54, timestamp); 
     360          LOGS.insert(55, timestamp.section(" ",3,3) ); 
     361          if(isnew){ emit MessageAvailable("resilvering"); } 
     362        } 
     363      }else if(zstat[i].startsWith("errors:")){ 
     364        if(zstat[i] != "errors: No known data errors"){ 
     365          qDebug() << "New zpool status error line that needs parsing:" << zstat[i]; 
     366        } 
     367      }else if( state != "ONLINE" ){ 
     368        //Check for state/resilvering of all real devices 
     369        if(zstat[i].contains("NAME\tSTATE\tREAD")){continue;} //nothing on this header line 
     370        else if(zstat[i].contains("(resilvering)")){ LOGS.insert(51, zstat[i].section("\t",0,0,QString::SectionSkipEmpty) ); } 
     371        else if(zstat[i].contains("ONLINE")){continue;} //do nothing for this device - it is good 
     372        else if(zstat[i].contains("OFFLINE")){ } 
     373        else if(zstat[i].contains("DEGRADED")){ } 
     374        else if(zstat[i].contains("FAULTED")){ } 
     375        else if(zstat[i].contains("REMOVED")){ } 
     376        else if(zstat[i].contains("UNAVAIL")){ } 
    266377      } 
    267     //Now set the status and emit the signal 
    268     LOGS.insert(30, id); 
    269     LOGS.insert(31, dataset); //dataset 
    270     LOGS.insert(32, summary ); //summary 
    271     LOGS.insert(33, msg ); //message 
    272     LOGS.insert(34, timestamp); //full timestamp 
    273     LOGS.insert(35, time); // time only     
    274     emit CriticalMessageAvailable(); 
    275   } 
    276 } 
     378    } //end of loop over zpool status lines 
     379  if(newresilver){ emit MessageAvailable("resilvering"); } 
     380} 
  • src-qt4/life-preserver/LPWatcher.h

    r559e01f rb5a7675  
    1212#include <QDebug> 
    1313 
     14#include "LPBackend.h" 
     15 
    1416class LPWatcher : public QObject{ 
    1517        Q_OBJECT 
     
    1921 
    2022        QStringList getMessages(QString type, QStringList msgList); 
    21         //Valid types - "critical"/"running"/"message" 
    22         //Valid messages - "dataset","message","summary","id", "timestamp", "time" 
     23        QStringList getAllCurrentMessages(); 
     24        bool isRunning(); 
     25        bool hasError(); 
    2326 
    2427public slots: 
     
    4952private slots: 
    5053        void fileChanged(QString); //file system watcher saw a change 
    51         void checkErrorFile(); //check for serious system error file 
     54        void checkPoolStatus(); //check for serious system errors 
    5255 
    5356signals: 
    54         void CriticalMessageAvailable(); 
    55         void ProcessUpdateAvailable(); 
    56         void NotificationMessageAvailable(); 
     57        void MessageAvailable(QString type); 
    5758}; 
    5859 
  • src-sh/lpreserver/backend/functions.sh

    r59f367e rc0e6494  
    257257  if [ "$2" = "sync" -a "$REPTIME" != "sync" ] ; then return 0; fi 
    258258 
     259  # Doing a replication task, check if one is in progress 
     260  export pidFile="${DBDIR}/.reptask-`echo ${LDATA} | sed 's|/|-|g'`" 
     261  if [ -e "${pidFile}" ] ; then 
     262     pgrep -F ${pidFile} >/dev/null 2>/dev/null 
     263     if [ $? -eq 0 ] ; then 
     264        echo_log "Skipped replication on $LDATA, previous replication is still running." 
     265        return 0 
     266     else 
     267        rm ${pidFile} 
     268     fi 
     269  fi 
     270 
     271  # Save this PID 
     272  echo "$$" > ${pidFile} 
     273 
    259274  # Is this a sync-task we do at the time of a snapshot? 
    260275  if [ "$2" = "sync" -a "$REPTIME" = "sync" ] ; then 
     
    286301  if [ "$lastSEND" = "$lastSNAP" ] ; then 
    287302     queue_msg "`date`: Last snapshot $lastSNAP is already marked as replicated!" 
     303     rm ${pidFile} 
    288304     return 1 
    289305  fi 
     
    332348  fi 
    333349 
     350  rm ${pidFile} 
    334351  return $zStatus 
    335352} 
     
    552569   exit $? 
    553570} 
     571 
     572init_rep_task() { 
     573 
     574  LDATA="$1" 
     575 
     576  repLine=`cat ${REPCONF} | grep "^${LDATA}:"` 
     577  if [ -z "$repLine" ] ; then return 0; fi 
     578  
     579  # We have a replication task for this set, get some vars 
     580  hName=`hostname` 
     581  REPHOST=`echo $repLine | cut -d ':' -f 3` 
     582  REPUSER=`echo $repLine | cut -d ':' -f 4` 
     583  REPPORT=`echo $repLine | cut -d ':' -f 5` 
     584  REPRDATA=`echo $repLine | cut -d ':' -f 6` 
     585 
     586  # First check if we even have a dataset on the remote 
     587  ssh -p ${REPPORT} ${REPUSER}@${REPHOST} zfs list ${REPRDATA}/${hName} 2>/dev/null >/dev/null 
     588  if [ $? -eq 0 ] ; then 
     589     # Lets cleanup the remote side 
     590     echo "Removing remote dataset: ${REPRDATA}/${hName}" 
     591     ssh -p ${REPPORT} ${REPUSER}@${REPHOST} zfs destroy -r ${REPRDATA}/${hName} 
     592     if [ $? -ne 0 ] ; then 
     593        echo "Warning: Could not delete remote dataset ${REPRDATA}/${hName}" 
     594     fi 
     595  fi 
     596 
     597  # Now lets mark none of our datasets as replicated 
     598  lastSEND=`zfs get -r backup:lpreserver ${LDATA} | grep LATEST | awk '{$1=$1}1' OFS=" " | tail -1 | cut -d '@' -f 2 | cut -d ' ' -f 1` 
     599  if [ -n "$lastSEND" ] ; then 
     600     zfs set backup:lpreserver=' ' ${LDATA}@$lastSEND 
     601  fi 
     602 
     603} 
  • src-sh/lpreserver/backend/runsnap.sh

    rac48c86 rc0e6494  
    1818fi 
    1919 
     20# Make sure this is a valid DATASET 
     21zfs list ${DATASET} >/dev/null 2>/dev/null 
     22if [ $? -ne 0 ] ; then 
     23   exit_err "Invalid dataset specified ${DATASET}" 
     24fi 
     25 
    2026# Create the snapshot now with the "auto-" tag 
    2127echo_log "Creating snapshot on ${DATASET}" 
     
    2329if [ $? -ne 0 ] ; then 
    2430  echo_log "ERROR: Failed creating snapshot on ${DATASET}" 
    25   queue_msg "Snapshot ERROR" "ERROR: Failed creating snapshot on ${DATASET} @ `date`\n\r`cat $CMDLOG`" 
     31  queue_msg "ERROR: Failed creating snapshot on ${DATASET} @ `date`\n\r`cat $CMDLOG`" 
    2632  snapStat=1 
    2733else 
     
    3844done 
    3945 
    40 # Do any pruning 
    41 num=0 
    42 for snap in $rSnaps 
    43 do 
    44    # Only remove snapshots which are auto-created, so we don't delete one the user 
    45    # made specifically 
    46    cur="`echo $snap | cut -d '-' -f 1`"  
    47    if [ "$cur" != "auto" ] ; then 
    48      continue; 
    49    fi 
     46# Before we start pruning, check if any replication is running 
     47skipPrune=0 
     48export pidFile="${DBDIR}/.reptask-`echo ${DATASET} | sed 's|/|-|g'`" 
     49if [ -e "${pidFile}" ] ; then 
     50   pgrep -F ${pidFile} >/dev/null 2>/dev/null 
     51   if [ $? -eq 0 ] ; then skipPrune=1; fi 
     52fi 
    5053 
    51    num=`expr $num + 1` 
    52    if [ $num -gt $KEEP ] ; then 
    53       echo_log "Pruning old snapshot: $snap" 
    54       rmZFSSnap "${DATASET}" "$snap" 
    55       if [ $? -ne 0 ] ; then 
    56         echo_log "ERROR: Failed pruning snapshot $snap on ${DATASET}" 
    57         queue_msg "Snapshot ERROR" "ERROR: Failed pruning snapshot $snap on ${DATASET} @ `date`\n\r`cat $CMDLOG`" 
    58         snapStat=1 
    59       else 
    60         queue_msg "Success pruning snapshot $snap on ${DATASET} @ `date`\n\r`cat $CMDLOG`" 
     54if [ $skipPrune -eq 1 ] ; then 
     55  # No pruning since replication is currently running 
     56  echo_log "WARNING: Skipped pruning snapshots on ${DATASET} while replication is running." 
     57  queue_msg "WARNING: Skipped pruning snapshots on ${DATASET} while replication is running." 
     58 
     59else 
     60  # Do any pruning 
     61  num=0 
     62  for snap in $rSnaps 
     63  do 
     64     # Only remove snapshots which are auto-created, so we don't delete one the user 
     65     # made specifically 
     66     cur="`echo $snap | cut -d '-' -f 1`"  
     67     if [ "$cur" != "auto" ] ; then 
     68       continue; 
     69     fi 
     70 
     71     num=`expr $num + 1` 
     72     if [ $num -gt $KEEP ] ; then 
     73        echo_log "Pruning old snapshot: $snap" 
     74        rmZFSSnap "${DATASET}" "$snap" 
     75        if [ $? -ne 0 ] ; then 
     76          echo_log "ERROR: Failed pruning snapshot $snap on ${DATASET}" 
     77          queue_msg "ERROR: Failed pruning snapshot $snap on ${DATASET} @ `date`\n\r`cat $CMDLOG`" 
     78          snapStat=1 
     79        else 
     80          queue_msg "Success pruning snapshot $snap on ${DATASET} @ `date`\n\r`cat $CMDLOG`" 
     81        fi 
    6182      fi 
    62     fi 
    63 done 
     83  done 
     84fi 
    6485 
    6586# If we failed at any point, sent out a notice 
  • src-sh/lpreserver/lpreserver

    r7c0c657 rc0e6494  
    146146 
    147147Available Flags: 
     148 
     149         add - Add a new replication target 
     150        init - Initialize the remote side again 
    148151        list - List replication targets 
    149          add - Add a new replication target 
    150152      remove - Remove a replication target 
    151153 
     
    165167 
    166168        Will schedule replication of tank1 to tankbackup/backups at 10PM, notated in 24hour time 
     169 
     170 
     171Init Options: 
     172 
     173        init <localdataset/zpool>  
     174 
     175        Will re-init the remote side of the replication. This can be useful 
     176        when your replication gets stuck. Doing this option will remove 
     177        all the data on the remote side, and require a full re-sync again. 
    167178 
    168179Remove Options: 
     
    486497            case ${1} in 
    487498                add) add_rep_task "$2" "$3" "$4" "$5" "$6" "$7" ;; 
     499                init) init_rep_task "$2" ;; 
    488500                list) list_rep_task ;; 
    489501                remove) cat ${REPCONF} | grep -q "^${2}:"  
Note: See TracChangeset for help on using the changeset viewer.