Changeset 3084


Ignore:
Timestamp:
02/12/12 12:29:56 (3 years ago)
Author:
chris
Message:

Add experimental "TCP Nice" mode, disabled by default.

Location:
box/trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • box/trunk/bin/bbackupd/BackupClientContext.cpp

    r2983 r3084  
    2929#include "BackupStoreFile.h" 
    3030#include "Logging.h" 
     31#include "TcpNice.h" 
    3132 
    3233#include "MemLeakFindOn.h" 
     
    5051        bool ExtendedLogToFile, 
    5152        std::string ExtendedLogFile, 
    52         ProgressNotifier& rProgressNotifier 
     53        ProgressNotifier& rProgressNotifier, 
     54        bool TcpNiceMode 
    5355) 
    5456        : mrResolver(rResolver), 
     
    5759          mPort(Port), 
    5860          mAccountNumber(AccountNumber), 
    59           mpSocket(0), 
    60           mpConnection(0), 
    6161          mExtendedLogging(ExtendedLogging), 
    6262          mExtendedLogToFile(ExtendedLogToFile), 
     
    7272          mKeepAliveTimer(0, "KeepAliveTime"), 
    7373          mbIsManaged(false), 
    74           mrProgressNotifier(rProgressNotifier) 
     74          mrProgressNotifier(rProgressNotifier), 
     75          mTcpNiceMode(TcpNiceMode) 
    7576{ 
    7677} 
     
    108109{ 
    109110        // Already got it? Just return it. 
    110         if(mpConnection != 0) 
    111         { 
    112                 return *mpConnection; 
    113         } 
    114          
    115         // Get a socket connection 
    116         if(mpSocket == 0) 
    117         { 
    118                 mpSocket = new SocketStreamTLS; 
    119                 ASSERT(mpSocket != 0);  // will have exceptioned if this was a problem 
    120         } 
     111        if(mapConnection.get()) 
     112        { 
     113                return *mapConnection; 
     114        } 
     115         
     116        // there shouldn't be a connection open 
     117        ASSERT(mapSocket.get() == 0); 
     118         
     119        SocketStreamTLS *pSocket = new SocketStreamTLS; 
    121120         
    122121        try 
    123122        { 
    124123                // Defensive. 
    125                 if(mpConnection != 0) 
    126                 { 
    127                         delete mpConnection; 
    128                         mpConnection = 0; 
    129                 } 
     124                mapConnection.reset(); 
    130125                 
    131126                // Log intention 
     
    134129 
    135130                // Connect! 
    136                 mpSocket->Open(mrTLSContext, Socket::TypeINET, 
    137                         mHostname.c_str(), mPort); 
    138                  
    139                 // And create a procotol object 
    140                 mpConnection = new BackupProtocolClient(*mpSocket); 
     131                pSocket->Open(mrTLSContext, Socket::TypeINET, mHostname.c_str(), mPort); 
     132                 
     133                if(mTcpNiceMode) 
     134                { 
     135                        mapNice.reset(new NiceSocketStream(std::auto_ptr<SocketStream>(pSocket))); 
     136                        mapConnection.reset(new BackupProtocolClient(*mapNice)); 
     137                } 
     138                else 
     139                { 
     140                        mapConnection.reset(new BackupProtocolClient(*pSocket)); 
     141                } 
     142                 
     143                pSocket = NULL; 
    141144                 
    142145                // Set logging option 
    143                 mpConnection->SetLogToSysLog(mExtendedLogging); 
     146                mapConnection->SetLogToSysLog(mExtendedLogging); 
    144147                 
    145148                if (mExtendedLogToFile) 
     
    157160                        else 
    158161                        { 
    159                                 mpConnection->SetLogToFile(mpExtendedLogFileHandle); 
     162                                mapConnection->SetLogToFile(mpExtendedLogFileHandle); 
    160163                        } 
    161164                } 
    162165                 
    163166                // Handshake 
    164                 mpConnection->Handshake(); 
     167                mapConnection->Handshake(); 
    165168                 
    166169                // Check the version of the server 
    167170                { 
    168                         std::auto_ptr<BackupProtocolVersion> serverVersion(mpConnection->QueryVersion(BACKUP_STORE_SERVER_VERSION)); 
     171                        std::auto_ptr<BackupProtocolVersion> serverVersion( 
     172                                mapConnection->QueryVersion(BACKUP_STORE_SERVER_VERSION)); 
    169173                        if(serverVersion->GetVersion() != BACKUP_STORE_SERVER_VERSION) 
    170174                        { 
     
    174178 
    175179                // Login -- if this fails, the Protocol will exception 
    176                 std::auto_ptr<BackupProtocolLoginConfirmed> loginConf(mpConnection->QueryLogin(mAccountNumber, 0 /* read/write */)); 
     180                std::auto_ptr<BackupProtocolLoginConfirmed> loginConf( 
     181                        mapConnection->QueryLogin(mAccountNumber, 0 /* read/write */)); 
    177182                 
    178183                // Check that the client store marker is the one we expect 
     
    184189                                try 
    185190                                { 
    186                                         mpConnection->QueryFinished(); 
    187                                         mpSocket->Shutdown(); 
    188                                         mpSocket->Close(); 
     191                                        mapConnection->QueryFinished(); 
     192                                        mapSocket.reset(); 
     193                                        mapNice.reset(); 
    189194                                } 
    190195                                catch(...) 
     
    214219        { 
    215220                // Clean up. 
    216                 delete mpConnection; 
    217                 mpConnection = 0; 
    218                 delete mpSocket; 
    219                 mpSocket = 0; 
     221                mapConnection.reset(); 
     222                mapSocket.reset(); 
     223                mapNice.reset(); 
    220224                throw; 
    221225        } 
    222226         
    223         return *mpConnection; 
     227        return *mapConnection; 
    224228} 
    225229 
     
    234238void BackupClientContext::CloseAnyOpenConnection() 
    235239{ 
    236         if(mpConnection) 
     240        if(mapConnection.get()) 
    237241        { 
    238242                try 
     
    245249                                 
    246250                                // Set it on the store 
    247                                 mpConnection->QuerySetClientStoreMarker(marker); 
     251                                mapConnection->QuerySetClientStoreMarker(marker); 
    248252                                 
    249253                                // Record it so that it can be picked up later. 
     
    252256                 
    253257                        // Quit nicely 
    254                         mpConnection->QueryFinished(); 
     258                        mapConnection->QueryFinished(); 
    255259                } 
    256260                catch(...) 
     
    260264                 
    261265                // Delete it anyway. 
    262                 delete mpConnection; 
    263                 mpConnection = 0; 
    264         } 
    265          
    266         if(mpSocket) 
    267         { 
    268                 try 
    269                 { 
    270                         // Be nice about closing the socket 
    271                         mpSocket->Shutdown(); 
    272                         mpSocket->Close(); 
    273                 } 
    274                 catch(...) 
    275                 { 
    276                         // Ignore errors 
    277                 } 
    278                  
    279                 // Delete object 
    280                 delete mpSocket; 
    281                 mpSocket = 0; 
     266                mapConnection.reset(); 
     267        } 
     268 
     269        try 
     270        { 
     271                // Be nice about closing the socket 
     272                mapSocket.reset(); 
     273                mapNice.reset(); 
     274        } 
     275        catch(...) 
     276        { 
     277                // Ignore errors 
    282278        } 
    283279 
     
    308304int BackupClientContext::GetTimeout() const 
    309305{ 
    310         if(mpConnection) 
    311         { 
    312                 return mpConnection->GetTimeout(); 
     306        if(mapConnection.get()) 
     307        { 
     308                return mapConnection->GetTimeout(); 
    313309        } 
    314310         
     
    510506        mKeepAliveTime = iSeconds < 0 ? 0 : iSeconds; 
    511507        BOX_TRACE("Set keep-alive time to " << mKeepAliveTime << " seconds"); 
    512         mKeepAliveTimer = Timer(mKeepAliveTime, "KeepAliveTime"); 
     508        mKeepAliveTimer = Timer(mKeepAliveTime * 1000, "KeepAliveTime"); 
    513509} 
    514510 
     
    552548void BackupClientContext::DoKeepAlive() 
    553549{ 
    554         if (!mpConnection) 
     550        if (!mapConnection.get()) 
    555551        { 
    556552                return; 
     
    568564         
    569565        BOX_TRACE("KeepAliveTime reached, sending keep-alive message"); 
    570         mpConnection->QueryGetIsAlive(); 
    571          
    572         mKeepAliveTimer = Timer(mKeepAliveTime, "KeepAliveTime"); 
     566        mapConnection->QueryGetIsAlive(); 
     567         
     568        mKeepAliveTimer = Timer(mKeepAliveTime * 1000, "KeepAliveTime"); 
    573569} 
    574570 
  • box/trunk/bin/bbackupd/BackupClientContext.h

    r2696 r3084  
    1717#include "BackupStoreFile.h" 
    1818#include "ExcludeList.h" 
     19#include "TcpNice.h" 
    1920#include "Timer.h" 
    2021 
     
    5051                bool ExtendedLogToFile, 
    5152                std::string ExtendedLogFile, 
    52                 ProgressNotifier &rProgressNotifier 
     53                ProgressNotifier &rProgressNotifier, 
     54                bool TcpNiceMode 
    5355        ); 
    5456        virtual ~BackupClientContext(); 
     
    208210                return mrProgressNotifier; 
    209211        } 
     212         
     213        void SetNiceMode(bool enabled) 
     214        { 
     215                if(mTcpNiceMode) 
     216                { 
     217                        mapNice->SetEnabled(enabled); 
     218                } 
     219        } 
    210220 
    211221private: 
     
    215225        int mPort; 
    216226        uint32_t mAccountNumber; 
    217         SocketStreamTLS *mpSocket; 
    218         BackupProtocolClient *mpConnection; 
     227        std::auto_ptr<IOStream> mapSocket; 
     228        std::auto_ptr<NiceSocketStream> mapNice; 
     229        std::auto_ptr<BackupProtocolClient> mapConnection; 
    219230        bool mExtendedLogging; 
    220231        bool mExtendedLogToFile; 
     
    233244        int mMaximumDiffingTime; 
    234245        ProgressNotifier &mrProgressNotifier; 
     246        bool mTcpNiceMode; 
    235247}; 
    236248 
  • box/trunk/bin/bbackupd/BackupClientDirectoryRecord.cpp

    r3076 r3084  
    16721672         
    16731673                                rContext.UnManageDiffProcess(); 
     1674                                rContext.SetNiceMode(true); 
    16741675 
    16751676                                RateLimitingStream rateLimit(*patchStream, 
     
    16911692                                std::auto_ptr<BackupProtocolSuccess> stored(connection.QueryStoreFile(mObjectID, ModificationTime, 
    16921693                                                AttributesHash, isCompletelyDifferent?(0):(diffFromID), rStoreFilename, *pStreamToUpload)); 
     1694 
     1695                                rContext.SetNiceMode(false); 
    16931696                                 
    16941697                                // Get object ID from the result                 
     
    17161719                                        &(rParams.mrRunStatusProvider))); 
    17171720 
     1721                        rContext.SetNiceMode(true); 
     1722 
    17181723                        RateLimitingStream rateLimit(*upload, 
    17191724                                rParams.mMaxUploadRate); 
     
    17361741                                        0 /* no diff from file ID */,  
    17371742                                        rStoreFilename, *pStreamToUpload)); 
     1743 
     1744                        rContext.SetNiceMode(false); 
    17381745         
    17391746                        // Get object ID from the result                 
  • box/trunk/bin/bbackupd/BackupDaemon.cpp

    r3083 r3084  
    845845                conf.GetKeyValueBool("ExtendedLogging"), 
    846846                conf.KeyExists("ExtendedLogFile"), 
    847                 extendedLogFile, *mpProgressNotifier 
     847                extendedLogFile, 
     848                *mpProgressNotifier, 
     849                conf.GetKeyValueBool("TcpNice") 
    848850        ); 
    849851                 
  • box/trunk/infrastructure/m4/boxbackup_tests.m4

    r3027 r3084  
    132132AC_CHECK_HEADERS([dlfcn.h fcntl.h getopt.h process.h pwd.h signal.h]) 
    133133AC_CHECK_HEADERS([syslog.h time.h cxxabi.h]) 
    134 AC_CHECK_HEADERS([netinet/in.h]) 
     134AC_CHECK_HEADERS([netinet/in.h netinet/tcp.h]) 
    135135AC_CHECK_HEADERS([sys/file.h sys/param.h sys/socket.h sys/time.h sys/types.h sys/wait.h]) 
    136136AC_CHECK_HEADERS([sys/uio.h sys/xattr.h]) 
     
    194194AC_CHECK_MEMBERS([DIR.d_fd],,,  [[#include <dirent.h>]]) 
    195195AC_CHECK_MEMBERS([DIR.dd_fd],,, [[#include <dirent.h>]]) 
     196AC_CHECK_MEMBERS([struct tcp_info.tcpi_rtt],,, [[#include <netinet/tcp.h>]]) 
    196197 
    197198AC_CHECK_DECLS([INFTIM],,, [[#include <poll.h>]]) 
    198199AC_CHECK_DECLS([SO_PEERCRED],,, [[#include <sys/socket.h>]]) 
     200AC_CHECK_DECLS([SO_SNDBUF],,, [[#include <asm/socket.h>]]) 
    199201AC_CHECK_DECLS([O_BINARY],,,) 
     202AC_CHECK_DECLS([SOL_TCP],,, [[#include <netinet/tcp.h>]]) 
     203AC_CHECK_DECLS([TCP_INFO],,, [[#include <netinet/tcp.h>]]) 
    200204 
    201205# Solaris provides getpeerucred() instead of getpeereid() or SO_PEERCRED 
  • box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp

    r2844 r3084  
    118118        // optional maximum speed of uploads in kbytes per second 
    119119 
     120        ConfigurationVerifyKey("TcpNice", ConfigTest_IsBool, false), 
     121        // optional enable of tcp nice/background mode 
     122 
    120123        ConfigurationVerifyKey("CertificateFile", ConfigTest_Exists), 
    121124        ConfigurationVerifyKey("PrivateKeyFile", ConfigTest_Exists), 
  • box/trunk/lib/backupstore/BackupStoreFileDiff.cpp

    r2963 r3084  
    470470        if(pDiffTimer && pDiffTimer->IsManaged()) 
    471471        { 
    472                 maximumDiffingTime = Timer(pDiffTimer->GetMaximumDiffingTime(), 
     472                maximumDiffingTime = Timer(pDiffTimer->GetMaximumDiffingTime() * 1000, 
    473473                        "MaximumDiffingTime"); 
    474474        } 
  • box/trunk/lib/common/BoxTime.h

    r3079 r3084  
    2828        return ((box_time_t)Seconds * MICRO_SEC_IN_SEC_LL); 
    2929} 
     30inline uint64_t MilliSecondsToBoxTime(int64_t milliseconds) 
     31{ 
     32        return ((box_time_t)milliseconds * 1000); 
     33} 
    3034inline time_t BoxTimeToSeconds(box_time_t Time) 
    3135{ 
  • box/trunk/lib/common/Timer.cpp

    r2991 r3084  
    336336// 
    337337// Function 
    338 //              Name:    Timer::Timer(size_t timeoutSecs, 
     338//              Name:    Timer::Timer(size_t timeoutMillis, 
    339339//                       const std::string& rName) 
    340340//              Purpose: Standard timer constructor, takes a timeout in 
     
    345345// -------------------------------------------------------------------------- 
    346346 
    347 Timer::Timer(size_t timeoutSecs, const std::string& rName) 
    348 : mExpires(GetCurrentBoxTime() + SecondsToBoxTime(timeoutSecs)), 
     347Timer::Timer(size_t timeoutMillis, const std::string& rName) 
     348: mExpires(GetCurrentBoxTime() + MilliSecondsToBoxTime(timeoutMillis)), 
    349349  mExpired(false), 
    350350  mName(rName) 
     
    354354{ 
    355355        #ifndef BOX_RELEASE_BUILD 
    356         if (timeoutSecs == 0) 
    357         { 
    358                 BOX_TRACE(TIMER_ID "initialised for " << timeoutSecs <<  
    359                         " secs, will not fire"); 
     356        if (timeoutMillis == 0) 
     357        { 
     358                BOX_TRACE(TIMER_ID "initialised for " << timeoutMillis <<  
     359                        " ms, will not fire"); 
    360360        } 
    361361        else 
    362362        { 
    363                 BOX_TRACE(TIMER_ID "initialised for " << timeoutSecs << 
    364                         " secs, to fire at " << FormatTime(mExpires, false, true)); 
     363                BOX_TRACE(TIMER_ID "initialised for " << timeoutMillis << 
     364                        " ms, to fire at " << FormatTime(mExpires, false, true)); 
    365365        } 
    366366        #endif 
    367367 
    368         if (timeoutSecs == 0) 
     368        if (timeoutMillis == 0) 
    369369        { 
    370370                mExpires = 0; 
     
    373373        { 
    374374                Timers::Add(*this); 
    375                 Start(timeoutSecs * MICRO_SEC_IN_SEC_LL); 
     375                Start(timeoutMillis * 1000); 
    376376        } 
    377377} 
     
    409409// 
    410410// Function 
    411 //              Name:    Timer::Start(int64_t delayInMicros) 
     411//              Name:    Timer::Start(int64_t timeoutMillis) 
    412412//              Purpose: This internal function initialises an OS TimerQueue 
    413413//                       timer on Windows, with a specified delay already 
     
    418418// -------------------------------------------------------------------------- 
    419419 
    420 void Timer::Start(int64_t delayInMicros) 
     420void Timer::Start(int64_t timeoutMillis) 
    421421{ 
    422422#ifdef WIN32 
    423423        // only call me once! 
    424424        ASSERT(mTimerHandle == INVALID_HANDLE_VALUE); 
    425  
    426         int64_t delayInMillis = delayInMicros / 1000; 
    427425 
    428426        // Windows XP always seems to fire timers up to 20 ms late, 
     
    430428        // tests are precise enough that they will fail if we don't 
    431429        // correct for it. 
    432         delayInMillis -= 20; 
     430        timeoutMillis -= 20; 
    433431         
    434432        // Set a system timer to call our timer routine 
    435433        if (CreateTimerQueueTimer(&mTimerHandle, NULL, TimerRoutine, 
    436                 (PVOID)this, delayInMillis, 0, WT_EXECUTEINTIMERTHREAD) 
     434                (PVOID)this, timeoutMillis, 0, WT_EXECUTEINTIMERTHREAD) 
    437435                == FALSE) 
    438436        { 
     
    524522                BOX_TRACE(TIMER_ID "initialised from timer " << &rToCopy << ", " 
    525523                        "to fire at " << 
    526                         (int)(mExpires / 1000000) << "." << 
    527                         (int)(mExpires % 1000000)); 
     524                        (int)(mExpires / MICRO_SEC_IN_SEC_LL) << "." << 
     525                        (int)(mExpires % MICRO_SEC_IN_SEC_LL)); 
    528526        } 
    529527        #endif 
     
    565563                BOX_TRACE(TIMER_ID "initialised from timer " << &rToCopy << ", " 
    566564                        "to fire at " << 
    567                         (int)(rToCopy.mExpires / 1000000) << "." << 
    568                         (int)(rToCopy.mExpires % 1000000)); 
     565                        (int)(rToCopy.mExpires / MICRO_SEC_IN_SEC_LL) << "." << 
     566                        (int)(rToCopy.mExpires % MICRO_SEC_IN_SEC_LL)); 
    569567        } 
    570568        #endif 
  • box/trunk/lib/common/Timer.h

    r2206 r3084  
    5454{ 
    5555public: 
    56         Timer(size_t timeoutSecs, const std::string& rName = ""); 
     56        Timer(size_t timeoutMillis, const std::string& rName = ""); 
    5757        virtual ~Timer(); 
    5858        Timer(const Timer &); 
     
    7575 
    7676        void Start(); 
    77         void Start(int64_t delayInMicros); 
     77        void Start(int64_t timeoutMillis); 
    7878        void Stop(); 
    7979 
  • box/trunk/lib/server/SocketStream.h

    r2424 r3084  
    5252 
    5353protected: 
    54         tOSSocketHandle GetSocketHandle(); 
    5554        void MarkAsReadClosed() {mReadClosed = true;} 
    5655        void MarkAsWriteClosed() {mWriteClosed = true;} 
     
    7069        void ResetCounters() {mBytesRead = mBytesWritten = 0;} 
    7170        bool IsOpened() { return mSocketHandle != INVALID_SOCKET_VALUE; } 
     71         
     72        /** 
     73         * Only for use by NiceSocketStream! 
     74         */ 
     75        tOSSocketHandle GetSocketHandle(); 
    7276}; 
    7377 
Note: See TracChangeset for help on using the changeset viewer.