Changeset 3084


Ignore:
Timestamp:
Feb 12, 2012, 12:29:56 PM (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.