Changeset 353


Ignore:
Timestamp:
30/01/2006 20:04:53 (6 years ago)
Author:
ben
Message:

Merge chris/bb-save-state, resolving conflicts

Location:
box/trunk
Files:
13 edited
1 copied

Legend:

Unmodified
Added
Removed
  • box/trunk/BUGS.txt

    r217 r353  
    99* bbackupquery restore, if not root, then won't do file ownership properly, but won't alert the user to this fact 
    1010* empty (real) directories in the store aren't deleted when they're empty (and will never be used again) -- uses up disc space unnecessarily 
     11* need unit tests for SSL keepalives and state saving (serialisation) 
     12* make Archive derive from Protocol 
     13* more automated tests for win32 
     14* change off_t to box_off_t in preparation for win32 large file support 
     15* support large files on win32 by using native *i64 functions instead of posix 
  • box/trunk/bin/bbackupd/BackupClientDirectoryRecord.cpp

    r341 r353  
    2626#include "BackupDaemon.h" 
    2727#include "BackupStoreException.h" 
     28#include "Archive.h" 
    2829 
    2930#include "MemLeakFindOn.h" 
     
    12271228{ 
    12281229} 
     1230 
     1231// -------------------------------------------------------------------------- 
     1232// 
     1233// Function 
     1234//              Name:    BackupClientDirectoryRecord::Deserialize(Archive & rArchive) 
     1235//              Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction. 
     1236// 
     1237//              Created: 2005/04/11 
     1238// 
     1239// -------------------------------------------------------------------------- 
     1240void BackupClientDirectoryRecord::Deserialize(Archive & rArchive) 
     1241{ 
     1242        // Make deletion recursive 
     1243        DeleteSubDirectories(); 
     1244 
     1245        // Delete maps 
     1246        if(mpPendingEntries != 0) 
     1247        { 
     1248                delete mpPendingEntries; 
     1249                mpPendingEntries = 0; 
     1250        } 
     1251 
     1252        // 
     1253        // 
     1254        // 
     1255        rArchive.Read(mObjectID); 
     1256        rArchive.Read(mSubDirName); 
     1257        rArchive.Read(mInitialSyncDone); 
     1258        rArchive.Read(mSyncDone); 
     1259 
     1260        // 
     1261        // 
     1262        // 
     1263        int64_t iCount = 0; 
     1264        rArchive.Read(iCount); 
     1265 
     1266        if (iCount != sizeof(mStateChecksum)/sizeof(mStateChecksum[0])) 
     1267        { 
     1268                // we have some kind of internal system representation change: throw for now 
     1269                THROW_EXCEPTION(CommonException, Internal) 
     1270        } 
     1271 
     1272        for (int v = 0; v < iCount; v++) 
     1273        { 
     1274                // Load each checksum entry 
     1275                rArchive.Read(mStateChecksum[v]); 
     1276        } 
     1277 
     1278        // 
     1279        // 
     1280        // 
     1281        iCount = 0; 
     1282        rArchive.Read(iCount); 
     1283 
     1284        if (iCount > 0) 
     1285        { 
     1286                // load each pending entry 
     1287                mpPendingEntries = new std::map<std::string, box_time_t>; 
     1288                if (!mpPendingEntries) 
     1289                { 
     1290                        throw std::bad_alloc(); 
     1291                } 
     1292 
     1293                for (int v = 0; v < iCount; v++) 
     1294                { 
     1295                        std::string strItem; 
     1296                        box_time_t btItem; 
     1297 
     1298                        rArchive.Read(strItem); 
     1299                        rArchive.Read(btItem); 
     1300                        (*mpPendingEntries)[strItem] = btItem; 
     1301                } 
     1302        } 
     1303 
     1304        // 
     1305        // 
     1306        // 
     1307        iCount = 0; 
     1308        rArchive.Read(iCount); 
     1309 
     1310        if (iCount > 0) 
     1311        { 
     1312                for (int v = 0; v < iCount; v++) 
     1313                { 
     1314                        std::string strItem; 
     1315                        rArchive.Read(strItem); 
     1316 
     1317                        BackupClientDirectoryRecord* pSubDirRecord =  
     1318                                new BackupClientDirectoryRecord(0, "");  
     1319                        // will be deserialized anyway, give it id 0 for now 
     1320 
     1321                        if (!pSubDirRecord) 
     1322                        { 
     1323                                throw std::bad_alloc(); 
     1324                        } 
     1325 
     1326                        /***** RECURSE *****/ 
     1327                        pSubDirRecord->Deserialize(rArchive); 
     1328                        mSubDirectories[strItem] = pSubDirRecord; 
     1329                } 
     1330        } 
     1331} 
     1332 
     1333// -------------------------------------------------------------------------- 
     1334// 
     1335// Function 
     1336//              Name:    BackupClientDirectoryRecord::Serialize(Archive & rArchive) 
     1337//              Purpose: Serializes this object instance into a stream of bytes, using an Archive abstraction. 
     1338// 
     1339//              Created: 2005/04/11 
     1340// 
     1341// -------------------------------------------------------------------------- 
     1342void BackupClientDirectoryRecord::Serialize(Archive & rArchive) const 
     1343{ 
     1344        // 
     1345        // 
     1346        // 
     1347        rArchive.Write(mObjectID); 
     1348        rArchive.Write(mSubDirName); 
     1349        rArchive.Write(mInitialSyncDone); 
     1350        rArchive.Write(mSyncDone); 
     1351 
     1352        // 
     1353        // 
     1354        // 
     1355        int64_t iCount = 0; 
     1356 
     1357        // when reading back the archive, we will  
     1358        // need to know how many items there are. 
     1359        iCount = sizeof(mStateChecksum) / sizeof(mStateChecksum[0]); 
     1360        rArchive.Write(iCount);  
     1361 
     1362        for (int v = 0; v < iCount; v++) 
     1363        { 
     1364                rArchive.Write(mStateChecksum[v]); 
     1365        } 
     1366 
     1367        // 
     1368        // 
     1369        // 
     1370        if (!mpPendingEntries) 
     1371        { 
     1372                iCount = 0; 
     1373                rArchive.Write(iCount); 
     1374        } 
     1375        else 
     1376        { 
     1377                iCount = mpPendingEntries->size(); 
     1378                rArchive.Write(iCount); 
     1379 
     1380                for (std::map<std::string, box_time_t>::const_iterator 
     1381                        i =  mpPendingEntries->begin();  
     1382                        i != mpPendingEntries->end(); i++) 
     1383                { 
     1384                        rArchive.Write(i->first); 
     1385                        rArchive.Write(i->second); 
     1386                } 
     1387        } 
     1388        // 
     1389        // 
     1390        // 
     1391        iCount = mSubDirectories.size(); 
     1392        rArchive.Write(iCount); 
     1393 
     1394        for (std::map<std::string, BackupClientDirectoryRecord*>::const_iterator 
     1395                i =  mSubDirectories.begin();  
     1396                i != mSubDirectories.end(); i++) 
     1397        { 
     1398                const BackupClientDirectoryRecord* pSubItem = i->second; 
     1399                ASSERT(pSubItem); 
     1400 
     1401                rArchive.Write(i->first); 
     1402                pSubItem->Serialize(rArchive); 
     1403        } 
     1404} 
  • box/trunk/bin/bbackupd/BackupClientDirectoryRecord.h

    r217 r353  
    1919#include "MD5Digest.h" 
    2020 
     21class Archive; 
    2122class BackupClientContext; 
    2223class BackupDaemon; 
     
    3536        BackupClientDirectoryRecord(int64_t ObjectID, const std::string &rSubDirName); 
    3637        ~BackupClientDirectoryRecord(); 
     38 
     39        void Deserialize(Archive & rArchive); 
     40        void Serialize(Archive & rArchive) const; 
    3741private: 
    3842        BackupClientDirectoryRecord(const BackupClientDirectoryRecord &); 
  • box/trunk/bin/bbackupd/BackupDaemon.cpp

    r341 r353  
    1111 
    1212#include <stdio.h> 
     13#include <string.h> 
    1314#include <unistd.h> 
    1415 
    15 #ifndef WIN32 
     16#ifdef HAVE_SIGNAL_H 
    1617        #include <signal.h> 
     18#endif 
     19#ifdef HAVE_SYSLOG_H 
    1720        #include <syslog.h> 
     21#endif 
     22#ifdef HAVE_SYS_PARAM_H 
    1823        #include <sys/param.h> 
     24#endif 
     25#ifdef HAVE_SYS_WAIT_H 
    1926        #include <sys/wait.h> 
    2027#endif 
     
    6269#include "IOStreamGetLine.h" 
    6370#include "Conversion.h" 
     71#include "Archive.h" 
    6472 
    6573#include "MemLeakFindOn.h" 
     
    468476        box_time_t lastSyncTime = 0; 
    469477 
     478        // -------------------------------------------------------------------------------------------- 
     479  
     480        // And what's the current client store marker? 
     481        int64_t clientStoreMarker =  
     482                BackupClientContext::ClientStoreMarker_NotKnown; 
     483        // haven't contacted the store yet 
     484 
     485        DeserializeStoreObjectInfo(clientStoreMarker, lastSyncTime,  
     486                nextSyncTime); 
     487  
    470488        // -------------------------------------------------------------------------------------------- 
    471489         
    472         // And what's the current client store marker? 
    473         int64_t clientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown;            // haven't contacted the store yet 
    474490 
    475491        // Set state 
     
    675691                                // Log 
    676692                                ::syslog(LOG_INFO, "Finished scan of local files"); 
     693 
     694                                // -------------------------------------------------------------------------------------------- 
     695 
     696                                // We had a successful backup, save the store info 
     697                                SerializeStoreObjectInfo(clientStoreMarker, lastSyncTime, nextSyncTime); 
     698 
     699                                // -------------------------------------------------------------------------------------------- 
    677700                        } 
    678701                        catch(BoxException &e) 
     
    18321855} 
    18331856 
     1857// -------------------------------------------------------------------------- 
     1858 
     1859typedef struct 
     1860{ 
     1861        int32_t mMagicValue;    // also the version number 
     1862        int32_t mNumEntries; 
     1863        int64_t mObjectID;              // this object ID 
     1864        int64_t mContainerID;   // ID of container 
     1865        uint64_t mAttributesModTime; 
     1866        int32_t mOptionsPresent;        // bit mask of optional sections / features present 
     1867 
     1868} loc_StreamFormat; 
    18341869 
    18351870// -------------------------------------------------------------------------- 
     
    18711906} 
    18721907 
     1908// -------------------------------------------------------------------------- 
     1909// 
     1910// Function 
     1911//              Name:    BackupDaemon::Location::Deserialize(Archive & rArchive) 
     1912//              Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction. 
     1913// 
     1914//              Created: 2005/04/11 
     1915// 
     1916// -------------------------------------------------------------------------- 
     1917void BackupDaemon::Location::Deserialize(Archive &rArchive) 
     1918{ 
     1919        // 
     1920        // 
     1921        // 
     1922        mpDirectoryRecord.reset(NULL); 
     1923        if (mpExcludeFiles) 
     1924        { 
     1925                delete mpExcludeFiles; 
     1926                mpExcludeFiles = NULL; 
     1927        } 
     1928        if (mpExcludeDirs) 
     1929        { 
     1930                delete mpExcludeDirs; 
     1931                mpExcludeDirs = NULL; 
     1932        } 
     1933 
     1934        // 
     1935        // 
     1936        // 
     1937        rArchive.Read(mName); 
     1938        rArchive.Read(mPath); 
     1939        rArchive.Read(mIDMapIndex); 
     1940 
     1941        // 
     1942        // 
     1943        // 
     1944        int64_t aMagicMarker = 0; 
     1945        rArchive.Read(aMagicMarker); 
     1946 
     1947        if (aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP) 
     1948        { 
     1949                // NOOP 
     1950        } 
     1951        else if (aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE) 
     1952        { 
     1953                BackupClientDirectoryRecord *pSubRecord = new BackupClientDirectoryRecord(0, ""); 
     1954                if (!pSubRecord) 
     1955                        throw std::bad_alloc(); 
     1956 
     1957                mpDirectoryRecord.reset(pSubRecord); 
     1958                mpDirectoryRecord->Deserialize(rArchive); 
     1959        } 
     1960        else 
     1961        { 
     1962                // there is something going on here 
     1963                THROW_EXCEPTION(CommonException, Internal) 
     1964        } 
     1965 
     1966        // 
     1967        // 
     1968        // 
     1969        rArchive.Read(aMagicMarker); 
     1970 
     1971        if (aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP) 
     1972        { 
     1973                // NOOP 
     1974        } 
     1975        else if (aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE) 
     1976        { 
     1977                mpExcludeFiles = new ExcludeList; 
     1978                if (!mpExcludeFiles) 
     1979                        throw std::bad_alloc(); 
     1980 
     1981                mpExcludeFiles->Deserialize(rArchive); 
     1982        } 
     1983        else 
     1984        { 
     1985                // there is something going on here 
     1986                THROW_EXCEPTION(CommonException, Internal) 
     1987        } 
     1988 
     1989        // 
     1990        // 
     1991        // 
     1992        rArchive.Read(aMagicMarker); 
     1993 
     1994        if (aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP) 
     1995        { 
     1996                // NOOP 
     1997        } 
     1998        else if (aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE) 
     1999        { 
     2000                mpExcludeDirs = new ExcludeList; 
     2001                if (!mpExcludeDirs) 
     2002                        throw std::bad_alloc(); 
     2003 
     2004                mpExcludeDirs->Deserialize(rArchive); 
     2005        } 
     2006        else 
     2007        { 
     2008                // there is something going on here 
     2009                THROW_EXCEPTION(CommonException, Internal) 
     2010        } 
     2011} 
     2012 
     2013// -------------------------------------------------------------------------- 
     2014// 
     2015// Function 
     2016//              Name:    BackupDaemon::Location::Serialize(Archive & rArchive) 
     2017//              Purpose: Serializes this object instance into a stream of bytes, using an Archive abstraction. 
     2018// 
     2019//              Created: 2005/04/11 
     2020// 
     2021// -------------------------------------------------------------------------- 
     2022void BackupDaemon::Location::Serialize(Archive & rArchive) const 
     2023{ 
     2024        // 
     2025        // 
     2026        // 
     2027        rArchive.Write(mName); 
     2028        rArchive.Write(mPath); 
     2029        rArchive.Write(mIDMapIndex); 
     2030 
     2031        // 
     2032        // 
     2033        // 
     2034        if (mpDirectoryRecord.get() == NULL) 
     2035        { 
     2036                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP; 
     2037                rArchive.Write(aMagicMarker); 
     2038        } 
     2039        else 
     2040        { 
     2041                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows 
     2042                rArchive.Write(aMagicMarker); 
     2043 
     2044                mpDirectoryRecord->Serialize(rArchive); 
     2045        } 
     2046 
     2047        // 
     2048        // 
     2049        // 
     2050        if (!mpExcludeFiles) 
     2051        { 
     2052                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP; 
     2053                rArchive.Write(aMagicMarker); 
     2054        } 
     2055        else 
     2056        { 
     2057                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows 
     2058                rArchive.Write(aMagicMarker); 
     2059 
     2060                mpExcludeFiles->Serialize(rArchive); 
     2061        } 
     2062 
     2063        // 
     2064        // 
     2065        // 
     2066        if (!mpExcludeDirs) 
     2067        { 
     2068                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP; 
     2069                rArchive.Write(aMagicMarker); 
     2070        } 
     2071        else 
     2072        { 
     2073                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows 
     2074                rArchive.Write(aMagicMarker); 
     2075 
     2076                mpExcludeDirs->Serialize(rArchive); 
     2077        } 
     2078} 
    18732079 
    18742080// -------------------------------------------------------------------------- 
     
    19022108        } 
    19032109} 
     2110 
     2111// -------------------------------------------------------------------------- 
     2112// 
     2113// Function 
     2114//              Name:    BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) 
     2115//              Purpose: Serializes remote directory and file information into a stream of bytes, using an Archive abstraction. 
     2116// 
     2117//              Created: 2005/04/11 
     2118// 
     2119// -------------------------------------------------------------------------- 
     2120 
     2121static const int STOREOBJECTINFO_MAGIC_ID_VALUE = 0x7777525F; 
     2122static const std::string STOREOBJECTINFO_MAGIC_ID_STRING = "BBACKUPD-STATE"; 
     2123static const int STOREOBJECTINFO_VERSION = 1; 
     2124 
     2125void BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const 
     2126{ 
     2127        if(!GetConfiguration().KeyExists("StoreObjectInfoFile")) 
     2128        { 
     2129                return; 
     2130        } 
     2131 
     2132        std::string StoreObjectInfoFile =  
     2133                GetConfiguration().GetKeyValue("StoreObjectInfoFile"); 
     2134 
     2135        if (StoreObjectInfoFile.size() <= 0) 
     2136        { 
     2137                return; 
     2138        } 
     2139 
     2140        try 
     2141        { 
     2142                FileStream aFile(StoreObjectInfoFile.c_str(),  
     2143                        O_WRONLY | O_CREAT | O_TRUNC); 
     2144                Archive anArchive(aFile, 0); 
     2145 
     2146                anArchive.Write(STOREOBJECTINFO_MAGIC_ID_VALUE); 
     2147                anArchive.Write(STOREOBJECTINFO_MAGIC_ID_STRING);  
     2148                anArchive.Write(STOREOBJECTINFO_VERSION); 
     2149                anArchive.Write(GetLoadedConfigModifiedTime()); 
     2150                anArchive.Write(aClientStoreMarker); 
     2151                anArchive.Write(theLastSyncTime); 
     2152                anArchive.Write(theNextSyncTime); 
     2153 
     2154                // 
     2155                // 
     2156                // 
     2157                int64_t iCount = mLocations.size(); 
     2158                anArchive.Write(iCount); 
     2159 
     2160                for (int v = 0; v < iCount; v++) 
     2161                { 
     2162                        ASSERT(mLocations[v]); 
     2163                        mLocations[v]->Serialize(anArchive); 
     2164                } 
     2165 
     2166                // 
     2167                // 
     2168                // 
     2169                iCount = mIDMapMounts.size(); 
     2170                anArchive.Write(iCount); 
     2171 
     2172                for (int v = 0; v < iCount; v++) 
     2173                        anArchive.Write(mIDMapMounts[v]); 
     2174 
     2175                // 
     2176                // 
     2177                // 
     2178                aFile.Close(); 
     2179                ::syslog(LOG_INFO, "Saved store object info file '%s'",  
     2180                        StoreObjectInfoFile.c_str()); 
     2181        } 
     2182        catch (...) 
     2183        { 
     2184                ::syslog(LOG_WARNING, "Requested store object info file '%s' " 
     2185                        "not accessible or could not be created",  
     2186                        StoreObjectInfoFile.c_str()); 
     2187        } 
     2188} 
     2189 
     2190// -------------------------------------------------------------------------- 
     2191// 
     2192// Function 
     2193//              Name:    BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime) 
     2194//              Purpose: Deserializes remote directory and file information from a stream of bytes, using an Archive abstraction. 
     2195// 
     2196//              Created: 2005/04/11 
     2197// 
     2198// -------------------------------------------------------------------------- 
     2199void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime) 
     2200{ 
     2201        // 
     2202        // 
     2203        // 
     2204        DeleteAllLocations(); 
     2205 
     2206        // 
     2207        // 
     2208        // 
     2209        if(!GetConfiguration().KeyExists("StoreObjectInfoFile")) 
     2210        { 
     2211                return; 
     2212        } 
     2213 
     2214        std::string StoreObjectInfoFile =  
     2215                GetConfiguration().GetKeyValue("StoreObjectInfoFile"); 
     2216 
     2217        if (StoreObjectInfoFile.size() <= 0) 
     2218        { 
     2219                return; 
     2220        } 
     2221 
     2222        try 
     2223        { 
     2224                FileStream aFile(StoreObjectInfoFile.c_str(), O_RDONLY); 
     2225                Archive anArchive(aFile, 0); 
     2226 
     2227                // 
     2228                // see if the content looks like a valid serialised archive 
     2229                // 
     2230                int iMagicValue = 0; 
     2231                anArchive.Read(iMagicValue); 
     2232 
     2233                if (iMagicValue != STOREOBJECTINFO_MAGIC_ID_VALUE) 
     2234                { 
     2235                        ::syslog(LOG_WARNING, "Store object info file '%s' " 
     2236                                "is not a valid or compatible serialised " 
     2237                                "archive. Will re-cache from store.",  
     2238                                StoreObjectInfoFile.c_str()); 
     2239                        return; 
     2240                } 
     2241 
     2242                // 
     2243                // get a bit optimistic and read in a string identifier 
     2244                // 
     2245                std::string strMagicValue; 
     2246                anArchive.Read(strMagicValue); 
     2247 
     2248                if (strMagicValue != STOREOBJECTINFO_MAGIC_ID_STRING) 
     2249                { 
     2250                        ::syslog(LOG_WARNING, "Store object info file '%s' " 
     2251                                "is not a valid or compatible serialised " 
     2252                                "archive. Will re-cache from store.",  
     2253                                StoreObjectInfoFile.c_str()); 
     2254                        return; 
     2255                } 
     2256 
     2257                // 
     2258                // check if we are loading some future format 
     2259                // version by mistake 
     2260                // 
     2261                int iVersion = 0; 
     2262                anArchive.Read(iVersion); 
     2263 
     2264                if (iVersion != STOREOBJECTINFO_VERSION) 
     2265                { 
     2266                        ::syslog(LOG_WARNING, "Store object info file '%s' " 
     2267                                "version [%d] unsupported. " 
     2268                                "Will re-cache from store.",  
     2269                                StoreObjectInfoFile.c_str(),  
     2270                                iVersion); 
     2271                        return; 
     2272                } 
     2273 
     2274                // 
     2275                // check if this state file is even valid  
     2276                // for the loaded bbackupd.conf file 
     2277                // 
     2278                box_time_t lastKnownConfigModTime; 
     2279                anArchive.Read(lastKnownConfigModTime); 
     2280 
     2281                if (lastKnownConfigModTime != GetLoadedConfigModifiedTime()) 
     2282                { 
     2283                        ::syslog(LOG_WARNING, "Store object info file '%s' " 
     2284                                "out of date. Will re-cache from store",  
     2285                                StoreObjectInfoFile.c_str()); 
     2286                        return; 
     2287                } 
     2288 
     2289                // 
     2290                // this is it, go at it 
     2291                // 
     2292                anArchive.Read(aClientStoreMarker); 
     2293                anArchive.Read(theLastSyncTime); 
     2294                anArchive.Read(theNextSyncTime); 
     2295 
     2296                // 
     2297                // 
     2298                // 
     2299                int64_t iCount = 0; 
     2300                anArchive.Read(iCount); 
     2301 
     2302                for (int v = 0; v < iCount; v++) 
     2303                { 
     2304                        Location* pLocation = new Location; 
     2305                        if (!pLocation) 
     2306                                throw std::bad_alloc(); 
     2307 
     2308                        pLocation->Deserialize(anArchive); 
     2309                        mLocations.push_back(pLocation); 
     2310                } 
     2311 
     2312                // 
     2313                // 
     2314                // 
     2315                iCount = 0; 
     2316                anArchive.Read(iCount); 
     2317 
     2318                for (int v = 0; v < iCount; v++) 
     2319                { 
     2320                        std::string strItem; 
     2321                        anArchive.Read(strItem); 
     2322 
     2323                        mIDMapMounts.push_back(strItem); 
     2324                } 
     2325 
     2326                // 
     2327                // 
     2328                // 
     2329                aFile.Close(); 
     2330                ::syslog(LOG_INFO, "Loaded store object info file '%s', " 
     2331                        "version [%d]", StoreObjectInfoFile.c_str(),  
     2332                        iVersion); 
     2333 
     2334                if (::unlink(StoreObjectInfoFile.c_str()) != 0) 
     2335                { 
     2336                        ::syslog(LOG_ERR, "Failed to delete the old " 
     2337                                "store object info file '%s': %s", 
     2338                                StoreObjectInfoFile.c_str(), strerror(errno)); 
     2339                } 
     2340        } 
     2341        catch (...) 
     2342        { 
     2343                DeleteAllLocations(); 
     2344 
     2345                aClientStoreMarker =  
     2346                        BackupClientContext::ClientStoreMarker_NotKnown; 
     2347                theLastSyncTime = 0; 
     2348                theNextSyncTime = 0; 
     2349 
     2350                ::syslog(LOG_WARNING, "Requested store object info file '%s' " 
     2351                        "does not exist, not accessible, or inconsistent. " 
     2352                        "Will re-cache from store.",  
     2353                        StoreObjectInfoFile.c_str()); 
     2354        } 
     2355} 
  • box/trunk/bin/bbackupd/BackupDaemon.h

    r217 r353  
    1515#include <memory> 
    1616 
     17#include "BoxTime.h" 
    1718#include "Daemon.h" 
    18 #include "BoxTime.h" 
    1919#include "Socket.h" 
    2020#include "SocketListen.h" 
     
    2828class ExcludeList; 
    2929class IOStreamGetLine; 
     30class Archive; 
    3031 
    3132// -------------------------------------------------------------------------- 
     
    4243        BackupDaemon(); 
    4344        ~BackupDaemon(); 
     45 
     46        // methods below do partial (specialized) serialization of client state only 
     47        void SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const; 
     48        void DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime); 
    4449private: 
    4550        BackupDaemon(const BackupDaemon &); 
     
    118123                Location(); 
    119124                ~Location(); 
     125 
     126                void Deserialize(Archive & rArchive); 
     127                void Serialize(Archive & rArchive) const; 
    120128        private: 
    121129                Location(const Location &);     // copy not allowed 
  • box/trunk/bin/bbackupd/bbackupd-config

    r217 r353  
    383383CommandSocket = /var/run/bbackupd.sock 
    384384 
     385# Uncomment the StoreObjectInfoFile to enable the experimental archiving 
     386# of the daemon's state (including client store marker and configuration) 
     387# between backup runs. This saves time and increases efficiency when 
     388# bbackupd is frequently stopped and started, since it removes the need 
     389# to rescan all directories on the remote server. However, it is new and 
     390# not yet heavily tested, so use with caution. 
     391 
     392# StoreObjectInfoFile = $working_dir/bbackupd.state 
    385393 
    386394Server 
  • box/trunk/configure.ac

    r341 r353  
    7575AC_HEADER_STDC 
    7676AC_HEADER_SYS_WAIT 
    77 AC_CHECK_HEADERS([execinfo.h netinet/in.h regex.h sys/types.h sys/xattr.h]) 
    78 AC_CHECK_HEADERS([sys/endian.h asm/byteorder.h syslog.h signal.h sys/time.h]) 
    79 AC_CHECK_HEADERS([time.h]) 
     77AC_CHECK_HEADERS([execinfo.h regex.h signal.h syslog.h time.h]) 
     78AC_CHECK_HEADERS([asm/byteorder.h]) 
     79AC_CHECK_HEADERS([netinet/in.h]) 
     80AC_CHECK_HEADERS([sys/endian.h sys/param.h sys/types.h sys/wait.h sys/xattr.h sys/time.h]) 
    8081 
    8182 
  • box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp

    r341 r353  
    8686        {"CommandSocket", 0, 0, 0},                             // not compulsory to have this 
    8787        {"KeepAliveTime", 0, ConfigTest_IsInt, 0},                              // optional 
     88        {"StoreObjectInfoFile", 0, 0, 0},                               // optional 
    8889 
    8990        {"NotifyScript", 0, 0, 0},                              // optional script to run when backup needs attention, eg store full 
     
    104105        0 
    105106}; 
    106  
  • box/trunk/lib/common/CommonException.txt

    r217 r353  
    4444IOStreamGetLineNotEnoughDataToIgnore    37      Bad value passed to IOStreamGetLine::IgnoreBufferedData() 
    4545TempDirPathTooLong                              38      Your temporary directory path is too long. Check the TMP and TEMP environment variables. 
     46ArchiveBlockIncompleteRead              39      The Store Object Info File is too short or corrupted, and will be rewritten automatically when the next backup completes. 
  • box/trunk/lib/common/ExcludeList.cpp

    r217 r353  
    1818#include "Utils.h" 
    1919#include "Configuration.h" 
     20#include "Archive.h" 
    2021 
    2122#include "MemLeakFindOn.h" 
     
    131132                                // Store in list of regular expressions 
    132133                                mRegex.push_back(pregex); 
     134                                // Store in list of regular expression string for Serialize 
     135                                mRegexStr.push_back(i->c_str()); 
    133136                        } 
    134137                        catch(...) 
     
    214217} 
    215218 
    216  
    217          
    218  
    219  
     219// -------------------------------------------------------------------------- 
     220// 
     221// Function 
     222//              Name:    ExcludeList::Deserialize(Archive & rArchive) 
     223//              Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction. 
     224// 
     225//              Created: 2005/04/11 
     226// 
     227// -------------------------------------------------------------------------- 
     228void ExcludeList::Deserialize(Archive & rArchive) 
     229{ 
     230        // 
     231        // 
     232        // 
     233        mDefinite.clear(); 
     234 
     235#ifndef PLATFORM_REGEX_NOT_SUPPORTED 
     236        // free regex memory 
     237        while(mRegex.size() > 0) 
     238        { 
     239                regex_t *pregex = mRegex.back(); 
     240                mRegex.pop_back(); 
     241                // Free regex storage, and the structure itself 
     242                ::regfree(pregex); 
     243                delete pregex; 
     244        } 
     245 
     246        mRegexStr.clear(); 
     247#endif 
     248 
     249        // Clean up exceptions list 
     250        if(mpAlwaysInclude != 0) 
     251        { 
     252                delete mpAlwaysInclude; 
     253                mpAlwaysInclude = 0; 
     254        } 
     255 
     256        // 
     257        // 
     258        // 
     259        int64_t iCount = 0; 
     260        rArchive.Read(iCount); 
     261 
     262        if (iCount > 0) 
     263        { 
     264                for (int v = 0; v < iCount; v++) 
     265                { 
     266                        // load each one 
     267                        std::string strItem; 
     268                        rArchive.Read(strItem); 
     269                        mDefinite.insert(strItem); 
     270                } 
     271        } 
     272 
     273        // 
     274        // 
     275        // 
     276#ifndef PLATFORM_REGEX_NOT_SUPPORTED 
     277        rArchive.Read(iCount); 
     278 
     279        if (iCount > 0) 
     280        { 
     281                for (int v = 0; v < iCount; v++) 
     282                { 
     283                        std::string strItem; 
     284                        rArchive.Read(strItem); 
     285 
     286                        // Allocate memory 
     287                        regex_t* pregex = new regex_t; 
     288                         
     289                        try 
     290                        { 
     291                                // Compile 
     292                                if(::regcomp(pregex, strItem.c_str(),  
     293                                        REG_EXTENDED | REG_NOSUB) != 0) 
     294                                { 
     295                                        THROW_EXCEPTION(CommonException,  
     296                                                BadRegularExpression) 
     297                                } 
     298                                 
     299                                // Store in list of regular expressions 
     300                                mRegex.push_back(pregex); 
     301 
     302                                // Store in list of regular expression strings 
     303                                // for Serialize 
     304                                mRegexStr.push_back(strItem); 
     305                        } 
     306                        catch(...) 
     307                        { 
     308                                delete pregex; 
     309                                throw; 
     310                        } 
     311                } 
     312        } 
     313#endif // PLATFORM_REGEX_NOT_SUPPORTED 
     314 
     315        // 
     316        // 
     317        // 
     318        int64_t aMagicMarker = 0; 
     319        rArchive.Read(aMagicMarker); 
     320 
     321        if (aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP) 
     322        { 
     323                // NOOP 
     324        } 
     325        else if (aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE) 
     326        { 
     327                mpAlwaysInclude = new ExcludeList; 
     328                if (!mpAlwaysInclude) 
     329                { 
     330                        throw std::bad_alloc(); 
     331                } 
     332 
     333                mpAlwaysInclude->Deserialize(rArchive); 
     334        } 
     335        else 
     336        { 
     337                // there is something going on here 
     338                THROW_EXCEPTION(CommonException, Internal) 
     339        } 
     340} 
     341 
     342// -------------------------------------------------------------------------- 
     343// 
     344// Function 
     345//              Name:    ExcludeList::Serialize(Archive & rArchive) 
     346//              Purpose: Serializes this object instance into a stream of bytes, using an Archive abstraction. 
     347// 
     348//              Created: 2005/04/11 
     349// 
     350// -------------------------------------------------------------------------- 
     351void ExcludeList::Serialize(Archive & rArchive) const 
     352{ 
     353        // 
     354        // 
     355        // 
     356        int64_t iCount = mDefinite.size(); 
     357        rArchive.Write(iCount); 
     358 
     359        for (std::set<std::string>::const_iterator i = mDefinite.begin();  
     360                i != mDefinite.end(); i++) 
     361        { 
     362                rArchive.Write(*i); 
     363        } 
     364 
     365        // 
     366        // 
     367        // 
     368#ifndef PLATFORM_REGEX_NOT_SUPPORTED 
     369        // don't even try to save compiled regular expressions, 
     370        // use string copies instead. 
     371        ASSERT(mRegex.size() == mRegexStr.size());       
     372 
     373        iCount = mRegexStr.size(); 
     374        rArchive.Write(iCount); 
     375 
     376        for (std::vector<std::string>::const_iterator i = mRegexStr.begin();  
     377                i != mRegexStr.end(); i++) 
     378        { 
     379                rArchive.Write(*i); 
     380        } 
     381#endif // PLATFORM_REGEX_NOT_SUPPORTED 
     382 
     383        // 
     384        // 
     385        // 
     386        if (!mpAlwaysInclude) 
     387        { 
     388                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP; 
     389                rArchive.Write(aMagicMarker); 
     390        } 
     391        else 
     392        { 
     393                int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows 
     394                rArchive.Write(aMagicMarker); 
     395 
     396                mpAlwaysInclude->Serialize(rArchive); 
     397        } 
     398} 
  • box/trunk/lib/common/ExcludeList.h

    r217 r353  
    2020#endif 
    2121 
     22class Archive; 
     23 
    2224// -------------------------------------------------------------------------- 
    2325// 
     
    3335        ExcludeList(); 
    3436        ~ExcludeList(); 
     37 
     38        void Deserialize(Archive & rArchive); 
     39        void Serialize(Archive & rArchive) const; 
    3540 
    3641        void AddDefiniteEntries(const std::string &rEntries); 
     
    5661#ifdef HAVE_REGEX_H 
    5762        std::vector<regex_t *> mRegex; 
     63        std::vector<std::string> mRegexStr;     // save original regular expression string-based source for Serialize 
    5864#endif 
    5965 
  • box/trunk/lib/server/Daemon.cpp

    r217 r353  
    1010#include "Box.h" 
    1111 
     12#include <errno.h> 
    1213#include <stdio.h> 
    1314#include <unistd.h> 
     
    1617#include <stdarg.h> 
    1718 
    18 #ifndef WIN32 
    19 #include <syslog.h> 
     19#ifdef HAVE_SYSLOG_H 
     20        #include <syslog.h> 
    2021#endif 
    2122 
     
    2526#include "Guards.h" 
    2627#include "UnixUser.h" 
     28#include "FileModificationTime.h" 
    2729 
    2830#include "MemLeakFindOn.h" 
     
    9395 
    9496        std::string pidFileName; 
    95         const char *configfile = 0; 
    9697 
    9798        try 
    9899        { 
    99100                // Find filename of config file 
    100                 configfile = DefaultConfigFile; 
     101                mConfigFileName = DefaultConfigFile; 
    101102                if(argc >= 2) 
    102103                { 
     
    104105                        if(::strcmp(argv[1], "-c") == 0 && argc >= 3) 
    105106                        { 
    106                                 configfile = argv[2]; 
     107                                mConfigFileName = argv[2]; 
    107108                        } 
    108109                        else 
    109110                        { 
    110                                 configfile = argv[1]; 
     111                                mConfigFileName = argv[1]; 
    111112                        } 
    112113                } 
     
    124125                // Load the configuration file. 
    125126                std::string errors; 
    126                 std::auto_ptr<Configuration> pconfig = Configuration::LoadAndVerify(configfile, GetConfigVerify(), errors); 
     127                std::auto_ptr<Configuration> pconfig =  
     128                        Configuration::LoadAndVerify( 
     129                                mConfigFileName.c_str(),  
     130                                GetConfigVerify(), errors); 
    127131 
    128132                // Got errors? 
     
    130134                { 
    131135                        // Tell user about errors 
    132                         fprintf(stderr, "%s: Errors in config file %s:\n%s", DaemonName(), configfile, errors.c_str()); 
     136                        fprintf(stderr, "%s: Errors in config file %s:\n%s",  
     137                                DaemonName(), mConfigFileName.c_str(),  
     138                                errors.c_str()); 
    133139                        // And give up 
    134140                        return 1; 
     
    137143                // Store configuration 
    138144                mpConfiguration = pconfig.release(); 
     145                mLoadedConfigModifiedTime = GetConfigFileModifiedTime(); 
    139146                 
    140147                // Server configuration 
     
    229236                ::openlog(DaemonName(), LOG_PID, LOG_LOCAL6); 
    230237                // Log the start message 
    231                 ::syslog(LOG_INFO, "Starting daemon (config: %s) (version " BOX_VERSION ")", configfile); 
     238                ::syslog(LOG_INFO, "Starting daemon (config: %s) (version "  
     239                        BOX_VERSION ")", mConfigFileName.c_str()); 
    232240 
    233241#ifndef WIN32 
     
    307315                        { 
    308316                                // Need to reload that config file... 
    309                                 ::syslog(LOG_INFO, "Reloading configuration (config: %s)", configfile); 
     317                                ::syslog(LOG_INFO, "Reloading configuration " 
     318                                        "(config: %s)",  
     319                                        mConfigFileName.c_str()); 
    310320                                std::string errors; 
    311                                 std::auto_ptr<Configuration> pconfig = Configuration::LoadAndVerify(configfile, GetConfigVerify(), errors); 
     321                                std::auto_ptr<Configuration> pconfig =  
     322                                        Configuration::LoadAndVerify( 
     323                                                mConfigFileName.c_str(), 
     324                                                GetConfigVerify(), errors); 
    312325 
    313326                                // Got errors? 
     
    315328                                { 
    316329                                        // Tell user about errors 
    317                                         ::syslog(LOG_ERR, "Errors in config file %s:\n%s", configfile, errors.c_str()); 
     330                                        ::syslog(LOG_ERR, "Errors in config " 
     331                                                "file %s:\n%s",  
     332                                                mConfigFileName.c_str(), 
     333                                                errors.c_str()); 
    318334                                        // And give up 
    319335                                        return 1; 
     
    326342                                // Store configuration 
    327343                                mpConfiguration = pconfig.release(); 
     344                                mLoadedConfigModifiedTime = 
     345                                        GetConfigFileModifiedTime(); 
    328346                                 
    329347                                // Stop being marked for loading config again 
     
    548566#endif // HAVE_SETPROCTITLE 
    549567} 
     568 
     569 
     570// -------------------------------------------------------------------------- 
     571// 
     572// Function 
     573//              Name:    Daemon::GetConfigFileModifiedTime() 
     574//              Purpose: Returns the timestamp when the configuration file 
     575//                       was last modified 
     576// 
     577//              Created: 2006/01/29 
     578// 
     579// -------------------------------------------------------------------------- 
     580 
     581box_time_t Daemon::GetConfigFileModifiedTime() const 
     582{ 
     583        struct stat st; 
     584 
     585        if(::stat(GetConfigFileName().c_str(), &st) != 0) 
     586        { 
     587                if (errno == ENOENT) 
     588                { 
     589                        return 0; 
     590                } 
     591                THROW_EXCEPTION(CommonException, OSFileError) 
     592        } 
     593         
     594        return FileModificationTime(st); 
     595} 
     596 
     597// -------------------------------------------------------------------------- 
     598// 
     599// Function 
     600//              Name:    Daemon::GetLoadedConfigModifiedTime() 
     601//              Purpose: Returns the timestamp when the configuration file 
     602//                       had been last modified, at the time when it was  
     603//                       loaded 
     604// 
     605//              Created: 2006/01/29 
     606// 
     607// -------------------------------------------------------------------------- 
     608 
     609box_time_t Daemon::GetLoadedConfigModifiedTime() const 
     610{ 
     611        return mLoadedConfigModifiedTime; 
     612} 
     613 
  • box/trunk/lib/server/Daemon.h

    r217 r353  
    1616#ifndef DAEMON__H 
    1717#define DAEMON__H 
     18 
     19#include <string> 
     20 
     21#include "BoxTime.h" 
    1822 
    1923class Configuration; 
     
    4145        virtual void Run(); 
    4246        const Configuration &GetConfiguration() const; 
    43          
     47        const std::string &GetConfigFileName() const {return mConfigFileName;} 
     48 
    4449        virtual const char *DaemonName() const; 
    4550        virtual const char *DaemonBanner() const; 
     
    5863         
    5964        static void SetProcessTitle(const char *format, ...); 
     65 
     66protected: 
     67        box_time_t GetLoadedConfigModifiedTime() const; 
    6068         
    6169private: 
    6270        static void SignalHandler(int sigraised); 
     71        box_time_t GetConfigFileModifiedTime() const; 
    6372         
    6473private: 
     74        std::string mConfigFileName; 
    6575        Configuration *mpConfiguration; 
     76        box_time_t mLoadedConfigModifiedTime; 
    6677        bool mReloadConfigWanted; 
    6778        bool mTerminateWanted; 
Note: See TracChangeset for help on using the changeset viewer.