summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2014-04-09 22:15:57 +0000
committerChris Wilson <chris+github@qwirx.com>2014-04-09 22:15:57 +0000
commitdc4ba0969146c6c4a82b1dace6bd9b11b818bcc9 (patch)
treef29918fdcab9a801685ebe6a6a7b5446c9cc69ba /lib
parent06af9253bc5df053dbe2208cbc724853294020a3 (diff)
Poll command socket regularly during file uploads.
Makes the daemon responsive to polling and commands, even during a file upload operation.
Diffstat (limited to 'lib')
-rw-r--r--lib/backupstore/BackupStoreException.txt1
-rw-r--r--lib/backupstore/BackupStoreFile.cpp6
-rw-r--r--lib/backupstore/BackupStoreFile.h7
-rw-r--r--lib/backupstore/BackupStoreFileDiff.cpp21
-rw-r--r--lib/backupstore/BackupStoreFileEncodeStream.cpp62
-rw-r--r--lib/backupstore/BackupStoreFileEncodeStream.h9
6 files changed, 76 insertions, 30 deletions
diff --git a/lib/backupstore/BackupStoreException.txt b/lib/backupstore/BackupStoreException.txt
index 9e21fc62..b49a9cf2 100644
--- a/lib/backupstore/BackupStoreException.txt
+++ b/lib/backupstore/BackupStoreException.txt
@@ -71,3 +71,4 @@ PatchChainInfoBadInDirectory 67 A directory contains inconsistent information. R
UnknownObjectRefCountRequested 68 A reference count was requested for an object whose reference count is not known.
MultiplyReferencedObject 69 Attempted to modify an object with multiple references, should be uncloned first
CorruptReferenceCountDatabase 70 The account's refcount database is corrupt and must be rebuilt by housekeeping.
+CancelledByBackgroundTask 71 The current task was cancelled on request by the background task.
diff --git a/lib/backupstore/BackupStoreFile.cpp b/lib/backupstore/BackupStoreFile.cpp
index e011f8f4..d4c73f8b 100644
--- a/lib/backupstore/BackupStoreFile.cpp
+++ b/lib/backupstore/BackupStoreFile.cpp
@@ -78,7 +78,8 @@ std::auto_ptr<BackupStoreFileEncodeStream> BackupStoreFile::EncodeFile(
const BackupStoreFilename &rStoreFilename,
int64_t *pModificationTime,
ReadLoggingStream::Logger* pLogger,
- RunStatusProvider* pRunStatusProvider)
+ RunStatusProvider* pRunStatusProvider,
+ BackgroundTask* pBackgroundTask)
{
// Create the stream
std::auto_ptr<BackupStoreFileEncodeStream> stream(
@@ -86,7 +87,8 @@ std::auto_ptr<BackupStoreFileEncodeStream> BackupStoreFile::EncodeFile(
// Do the initial setup
stream->Setup(Filename, 0 /* no recipe, just encode */, ContainerID,
- rStoreFilename, pModificationTime, pLogger, pRunStatusProvider);
+ rStoreFilename, pModificationTime, pLogger, pRunStatusProvider,
+ pBackgroundTask);
// Return the stream for the caller
return stream;
diff --git a/lib/backupstore/BackupStoreFile.h b/lib/backupstore/BackupStoreFile.h
index 8e2cefb6..776e6d22 100644
--- a/lib/backupstore/BackupStoreFile.h
+++ b/lib/backupstore/BackupStoreFile.h
@@ -27,6 +27,7 @@ typedef struct
int64_t mTotalFileStreamSize;
} BackupStoreFileStats;
+class BackgroundTask;
class RunStatusProvider;
// Uncomment to disable backwards compatibility
@@ -128,7 +129,8 @@ public:
int64_t ContainerID, const BackupStoreFilename &rStoreFilename,
int64_t *pModificationTime = 0,
ReadLoggingStream::Logger* pLogger = NULL,
- RunStatusProvider* pRunStatusProvider = NULL
+ RunStatusProvider* pRunStatusProvider = NULL,
+ BackgroundTask* pBackgroundTask = NULL
);
static std::auto_ptr<BackupStoreFileEncodeStream> EncodeFileDiff
(
@@ -138,7 +140,8 @@ public:
int Timeout,
DiffTimer *pDiffTimer,
int64_t *pModificationTime = 0,
- bool *pIsCompletelyDifferent = 0
+ bool *pIsCompletelyDifferent = 0,
+ BackgroundTask* pBackgroundTask = NULL
);
// Shortcut interface
static int64_t QueryStoreFileDiff(BackupProtocolCallable& protocol,
diff --git a/lib/backupstore/BackupStoreFileDiff.cpp b/lib/backupstore/BackupStoreFileDiff.cpp
index fa8cb892..176d56e1 100644
--- a/lib/backupstore/BackupStoreFileDiff.cpp
+++ b/lib/backupstore/BackupStoreFileDiff.cpp
@@ -128,7 +128,8 @@ std::auto_ptr<BackupStoreFileEncodeStream> BackupStoreFile::EncodeFileDiff
const std::string& Filename, int64_t ContainerID,
const BackupStoreFilename &rStoreFilename, int64_t DiffFromObjectID,
IOStream &rDiffFromBlockIndex, int Timeout, DiffTimer *pDiffTimer,
- int64_t *pModificationTime, bool *pIsCompletelyDifferent)
+ int64_t *pModificationTime, bool *pIsCompletelyDifferent,
+ BackgroundTask* pBackgroundTask)
{
// Is it a symlink?
{
@@ -144,7 +145,11 @@ std::auto_ptr<BackupStoreFileEncodeStream> BackupStoreFile::EncodeFileDiff
{
*pIsCompletelyDifferent = true;
}
- return EncodeFile(Filename, ContainerID, rStoreFilename, pModificationTime);
+ return EncodeFile(Filename, ContainerID, rStoreFilename,
+ pModificationTime,
+ NULL, // ReadLoggingStream::Logger
+ NULL, // RunStatusProvider
+ pBackgroundTask); // BackgroundTask
}
}
@@ -162,7 +167,11 @@ std::auto_ptr<BackupStoreFileEncodeStream> BackupStoreFile::EncodeFileDiff
{
*pIsCompletelyDifferent = true;
}
- return EncodeFile(Filename, ContainerID, rStoreFilename, pModificationTime);
+ return EncodeFile(Filename, ContainerID, rStoreFilename,
+ pModificationTime,
+ NULL, // ReadLoggingStream::Logger
+ NULL, // RunStatusProvider
+ pBackgroundTask); // BackgroundTask
}
// Pointer to recipe we're going to create
@@ -210,7 +219,11 @@ std::auto_ptr<BackupStoreFileEncodeStream> BackupStoreFile::EncodeFileDiff
new BackupStoreFileEncodeStream);
// Do the initial setup
- stream->Setup(Filename, precipe, ContainerID, rStoreFilename, pModificationTime);
+ stream->Setup(Filename, precipe, ContainerID, rStoreFilename,
+ pModificationTime,
+ NULL, // ReadLoggingStream::Logger
+ NULL, // RunStatusProvider
+ pBackgroundTask);
precipe = 0; // Stream has taken ownership of this
// Tell user about completely different status?
diff --git a/lib/backupstore/BackupStoreFileEncodeStream.cpp b/lib/backupstore/BackupStoreFileEncodeStream.cpp
index b53c4c26..b40bcd08 100644
--- a/lib/backupstore/BackupStoreFileEncodeStream.cpp
+++ b/lib/backupstore/BackupStoreFileEncodeStream.cpp
@@ -11,6 +11,7 @@
#include <string.h>
+#include "BackgroundTask.h"
#include "BackupClientFileAttributes.h"
#include "BackupStoreConstants.h"
#include "BackupStoreException.h"
@@ -40,25 +41,28 @@ using namespace BackupStoreFileCryptVar;
//
// --------------------------------------------------------------------------
BackupStoreFileEncodeStream::BackupStoreFileEncodeStream()
- : mpRecipe(0),
- mpFile(0),
- mpLogging(0),
- mpRunStatusProvider(NULL),
- mStatus(Status_Header),
- mSendData(true),
- mTotalBlocks(0),
- mAbsoluteBlockNumber(-1),
- mInstructionNumber(-1),
- mNumBlocks(0),
- mCurrentBlock(-1),
- mCurrentBlockEncodedSize(0),
- mPositionInCurrentBlock(0),
- mBlockSize(BACKUP_FILE_MIN_BLOCK_SIZE),
- mLastBlockSize(0),
- mTotalBytesSent(0),
- mpRawBuffer(0),
- mAllocatedBufferSize(0),
- mEntryIVBase(0)
+: mpRecipe(0),
+ mpFile(0),
+ mpLogging(0),
+ mpRunStatusProvider(NULL),
+ mpBackgroundTask(NULL),
+ mStatus(Status_Header),
+ mSendData(true),
+ mTotalBlocks(0),
+ mBytesToUpload(0),
+ mBytesUploaded(0),
+ mAbsoluteBlockNumber(-1),
+ mInstructionNumber(-1),
+ mNumBlocks(0),
+ mCurrentBlock(-1),
+ mCurrentBlockEncodedSize(0),
+ mPositionInCurrentBlock(0),
+ mBlockSize(BACKUP_FILE_MIN_BLOCK_SIZE),
+ mLastBlockSize(0),
+ mTotalBytesSent(0),
+ mpRawBuffer(0),
+ mAllocatedBufferSize(0),
+ mEntryIVBase(0)
{
}
@@ -115,7 +119,8 @@ void BackupStoreFileEncodeStream::Setup(const std::string& Filename,
BackupStoreFileEncodeStream::Recipe *pRecipe,
int64_t ContainerID, const BackupStoreFilename &rStoreFilename,
int64_t *pModificationTime, ReadLoggingStream::Logger* pLogger,
- RunStatusProvider* pRunStatusProvider)
+ RunStatusProvider* pRunStatusProvider,
+ BackgroundTask* pBackgroundTask)
{
// Pointer to a blank recipe which we might create
BackupStoreFileEncodeStream::Recipe *pblankRecipe = 0;
@@ -162,6 +167,7 @@ void BackupStoreFileEncodeStream::Setup(const std::string& Filename,
CalculateBlockSizes((*pRecipe)[inst].mSpaceBefore, numBlocks, blockSize, lastBlockSize);
// Add to accumlated total
mTotalBlocks += numBlocks;
+ mBytesToUpload += (*pRecipe)[inst].mSpaceBefore;
// Update maximum clear size
if(blockSize > maxBlockClearSize) maxBlockClearSize = blockSize;
if(lastBlockSize > maxBlockClearSize) maxBlockClearSize = lastBlockSize;
@@ -278,6 +284,7 @@ void BackupStoreFileEncodeStream::Setup(const std::string& Filename,
}
mpRunStatusProvider = pRunStatusProvider;
+ mpBackgroundTask = pBackgroundTask;
}
@@ -341,6 +348,19 @@ int BackupStoreFileEncodeStream::Read(void *pBuffer, int NBytes, int Timeout)
THROW_EXCEPTION(BackupStoreException, SignalReceived);
}
+ if(mpBackgroundTask)
+ {
+ BackgroundTask::State state = (mpRecipe->at(0).mBlocks == 0)
+ ? BackgroundTask::Uploading_Full
+ : BackgroundTask::Uploading_Patch;
+ if(!mpBackgroundTask->RunBackgroundTask(state, mBytesUploaded,
+ mBytesToUpload))
+ {
+ THROW_EXCEPTION(BackupStoreException,
+ CancelledByBackgroundTask);
+ }
+ }
+
int bytesToRead = NBytes;
uint8_t *buffer = (uint8_t*)pBuffer;
@@ -575,6 +595,8 @@ void BackupStoreFileEncodeStream::EncodeCurrentBlock()
// Encode it
mCurrentBlockEncodedSize = BackupStoreFile::EncodeChunk(mpRawBuffer,
blockRawSize, mEncodedBuffer);
+
+ mBytesUploaded += blockRawSize;
//TRACE2("Encode: Encoded size of block %d is %d\n", (int32_t)mCurrentBlock, (int32_t)mCurrentBlockEncodedSize);
diff --git a/lib/backupstore/BackupStoreFileEncodeStream.h b/lib/backupstore/BackupStoreFileEncodeStream.h
index a169e036..80bdff58 100644
--- a/lib/backupstore/BackupStoreFileEncodeStream.h
+++ b/lib/backupstore/BackupStoreFileEncodeStream.h
@@ -79,7 +79,8 @@ public:
const BackupStoreFilename &rStoreFilename,
int64_t *pModificationTime,
ReadLoggingStream::Logger* pLogger = NULL,
- RunStatusProvider* pRunStatusProvider = NULL);
+ RunStatusProvider* pRunStatusProvider = NULL,
+ BackgroundTask* pBackgroundTask = NULL);
virtual int Read(void *pBuffer, int NBytes, int Timeout);
virtual void Write(const void *pBuffer, int NBytes);
@@ -109,14 +110,18 @@ private:
CollectInBufferStream mData; // buffer for header and index entries
IOStream *mpLogging;
RunStatusProvider* mpRunStatusProvider;
+ BackgroundTask* mpBackgroundTask;
int mStatus;
bool mSendData; // true if there's file data to send (ie not a symlink)
int64_t mTotalBlocks; // Total number of blocks in the file
+ int64_t mBytesToUpload; // Total number of clear bytes to encode and upload
+ int64_t mBytesUploaded; // Total number of clear bytes already encoded
+ // excluding reused blocks already on the server.
int64_t mAbsoluteBlockNumber; // The absolute block number currently being output
// Instruction number
int64_t mInstructionNumber;
// All the below are within the current instruction
- int64_t mNumBlocks; // number of blocks. Last one will be a different size to the rest in most cases
+ int64_t mNumBlocks; // number of blocks. Last one will be a different size to the rest in most cases
int64_t mCurrentBlock;
int32_t mCurrentBlockEncodedSize;
int32_t mPositionInCurrentBlock; // for reading out