Changeset 353
- Timestamp:
- 30/01/2006 20:04:53 (6 years ago)
- Location:
- box/trunk
- Files:
-
- 13 edited
- 1 copied
-
BUGS.txt (modified) (1 diff)
-
bin/bbackupd/BackupClientDirectoryRecord.cpp (modified) (2 diffs)
-
bin/bbackupd/BackupClientDirectoryRecord.h (modified) (2 diffs)
-
bin/bbackupd/BackupDaemon.cpp (modified) (7 diffs)
-
bin/bbackupd/BackupDaemon.h (modified) (4 diffs)
-
bin/bbackupd/bbackupd-config (modified) (1 diff)
-
configure.ac (modified) (1 diff)
-
lib/backupclient/BackupDaemonConfigVerify.cpp (modified) (2 diffs)
-
lib/common/Archive.h (copied) (copied from box/chris/bb-save-state/lib/common/Archive.h)
-
lib/common/CommonException.txt (modified) (1 diff)
-
lib/common/ExcludeList.cpp (modified) (3 diffs)
-
lib/common/ExcludeList.h (modified) (3 diffs)
-
lib/server/Daemon.cpp (modified) (13 diffs)
-
lib/server/Daemon.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/BUGS.txt
r217 r353 9 9 * bbackupquery restore, if not root, then won't do file ownership properly, but won't alert the user to this fact 10 10 * 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 26 26 #include "BackupDaemon.h" 27 27 #include "BackupStoreException.h" 28 #include "Archive.h" 28 29 29 30 #include "MemLeakFindOn.h" … … 1227 1228 { 1228 1229 } 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 // -------------------------------------------------------------------------- 1240 void 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 // -------------------------------------------------------------------------- 1342 void 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 19 19 #include "MD5Digest.h" 20 20 21 class Archive; 21 22 class BackupClientContext; 22 23 class BackupDaemon; … … 35 36 BackupClientDirectoryRecord(int64_t ObjectID, const std::string &rSubDirName); 36 37 ~BackupClientDirectoryRecord(); 38 39 void Deserialize(Archive & rArchive); 40 void Serialize(Archive & rArchive) const; 37 41 private: 38 42 BackupClientDirectoryRecord(const BackupClientDirectoryRecord &); -
box/trunk/bin/bbackupd/BackupDaemon.cpp
r341 r353 11 11 12 12 #include <stdio.h> 13 #include <string.h> 13 14 #include <unistd.h> 14 15 15 #if ndef WIN3216 #ifdef HAVE_SIGNAL_H 16 17 #include <signal.h> 18 #endif 19 #ifdef HAVE_SYSLOG_H 17 20 #include <syslog.h> 21 #endif 22 #ifdef HAVE_SYS_PARAM_H 18 23 #include <sys/param.h> 24 #endif 25 #ifdef HAVE_SYS_WAIT_H 19 26 #include <sys/wait.h> 20 27 #endif … … 62 69 #include "IOStreamGetLine.h" 63 70 #include "Conversion.h" 71 #include "Archive.h" 64 72 65 73 #include "MemLeakFindOn.h" … … 468 476 box_time_t lastSyncTime = 0; 469 477 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 470 488 // -------------------------------------------------------------------------------------------- 471 489 472 // And what's the current client store marker?473 int64_t clientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown; // haven't contacted the store yet474 490 475 491 // Set state … … 675 691 // Log 676 692 ::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 // -------------------------------------------------------------------------------------------- 677 700 } 678 701 catch(BoxException &e) … … 1832 1855 } 1833 1856 1857 // -------------------------------------------------------------------------- 1858 1859 typedef 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; 1834 1869 1835 1870 // -------------------------------------------------------------------------- … … 1871 1906 } 1872 1907 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 // -------------------------------------------------------------------------- 1917 void 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 // -------------------------------------------------------------------------- 2022 void 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 } 1873 2079 1874 2080 // -------------------------------------------------------------------------- … … 1902 2108 } 1903 2109 } 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 2121 static const int STOREOBJECTINFO_MAGIC_ID_VALUE = 0x7777525F; 2122 static const std::string STOREOBJECTINFO_MAGIC_ID_STRING = "BBACKUPD-STATE"; 2123 static const int STOREOBJECTINFO_VERSION = 1; 2124 2125 void 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 // -------------------------------------------------------------------------- 2199 void 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 15 15 #include <memory> 16 16 17 #include "BoxTime.h" 17 18 #include "Daemon.h" 18 #include "BoxTime.h"19 19 #include "Socket.h" 20 20 #include "SocketListen.h" … … 28 28 class ExcludeList; 29 29 class IOStreamGetLine; 30 class Archive; 30 31 31 32 // -------------------------------------------------------------------------- … … 42 43 BackupDaemon(); 43 44 ~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); 44 49 private: 45 50 BackupDaemon(const BackupDaemon &); … … 118 123 Location(); 119 124 ~Location(); 125 126 void Deserialize(Archive & rArchive); 127 void Serialize(Archive & rArchive) const; 120 128 private: 121 129 Location(const Location &); // copy not allowed -
box/trunk/bin/bbackupd/bbackupd-config
r217 r353 383 383 CommandSocket = /var/run/bbackupd.sock 384 384 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 385 393 386 394 Server -
box/trunk/configure.ac
r341 r353 75 75 AC_HEADER_STDC 76 76 AC_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]) 77 AC_CHECK_HEADERS([execinfo.h regex.h signal.h syslog.h time.h]) 78 AC_CHECK_HEADERS([asm/byteorder.h]) 79 AC_CHECK_HEADERS([netinet/in.h]) 80 AC_CHECK_HEADERS([sys/endian.h sys/param.h sys/types.h sys/wait.h sys/xattr.h sys/time.h]) 80 81 81 82 -
box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp
r341 r353 86 86 {"CommandSocket", 0, 0, 0}, // not compulsory to have this 87 87 {"KeepAliveTime", 0, ConfigTest_IsInt, 0}, // optional 88 {"StoreObjectInfoFile", 0, 0, 0}, // optional 88 89 89 90 {"NotifyScript", 0, 0, 0}, // optional script to run when backup needs attention, eg store full … … 104 105 0 105 106 }; 106 -
box/trunk/lib/common/CommonException.txt
r217 r353 44 44 IOStreamGetLineNotEnoughDataToIgnore 37 Bad value passed to IOStreamGetLine::IgnoreBufferedData() 45 45 TempDirPathTooLong 38 Your temporary directory path is too long. Check the TMP and TEMP environment variables. 46 ArchiveBlockIncompleteRead 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 18 18 #include "Utils.h" 19 19 #include "Configuration.h" 20 #include "Archive.h" 20 21 21 22 #include "MemLeakFindOn.h" … … 131 132 // Store in list of regular expressions 132 133 mRegex.push_back(pregex); 134 // Store in list of regular expression string for Serialize 135 mRegexStr.push_back(i->c_str()); 133 136 } 134 137 catch(...) … … 214 217 } 215 218 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 // -------------------------------------------------------------------------- 228 void 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 // -------------------------------------------------------------------------- 351 void 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 20 20 #endif 21 21 22 class Archive; 23 22 24 // -------------------------------------------------------------------------- 23 25 // … … 33 35 ExcludeList(); 34 36 ~ExcludeList(); 37 38 void Deserialize(Archive & rArchive); 39 void Serialize(Archive & rArchive) const; 35 40 36 41 void AddDefiniteEntries(const std::string &rEntries); … … 56 61 #ifdef HAVE_REGEX_H 57 62 std::vector<regex_t *> mRegex; 63 std::vector<std::string> mRegexStr; // save original regular expression string-based source for Serialize 58 64 #endif 59 65 -
box/trunk/lib/server/Daemon.cpp
r217 r353 10 10 #include "Box.h" 11 11 12 #include <errno.h> 12 13 #include <stdio.h> 13 14 #include <unistd.h> … … 16 17 #include <stdarg.h> 17 18 18 #if ndef WIN3219 #include <syslog.h>19 #ifdef HAVE_SYSLOG_H 20 #include <syslog.h> 20 21 #endif 21 22 … … 25 26 #include "Guards.h" 26 27 #include "UnixUser.h" 28 #include "FileModificationTime.h" 27 29 28 30 #include "MemLeakFindOn.h" … … 93 95 94 96 std::string pidFileName; 95 const char *configfile = 0;96 97 97 98 try 98 99 { 99 100 // Find filename of config file 100 configfile = DefaultConfigFile;101 mConfigFileName = DefaultConfigFile; 101 102 if(argc >= 2) 102 103 { … … 104 105 if(::strcmp(argv[1], "-c") == 0 && argc >= 3) 105 106 { 106 configfile = argv[2];107 mConfigFileName = argv[2]; 107 108 } 108 109 else 109 110 { 110 configfile = argv[1];111 mConfigFileName = argv[1]; 111 112 } 112 113 } … … 124 125 // Load the configuration file. 125 126 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); 127 131 128 132 // Got errors? … … 130 134 { 131 135 // 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()); 133 139 // And give up 134 140 return 1; … … 137 143 // Store configuration 138 144 mpConfiguration = pconfig.release(); 145 mLoadedConfigModifiedTime = GetConfigFileModifiedTime(); 139 146 140 147 // Server configuration … … 229 236 ::openlog(DaemonName(), LOG_PID, LOG_LOCAL6); 230 237 // 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()); 232 240 233 241 #ifndef WIN32 … … 307 315 { 308 316 // 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()); 310 320 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); 312 325 313 326 // Got errors? … … 315 328 { 316 329 // 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()); 318 334 // And give up 319 335 return 1; … … 326 342 // Store configuration 327 343 mpConfiguration = pconfig.release(); 344 mLoadedConfigModifiedTime = 345 GetConfigFileModifiedTime(); 328 346 329 347 // Stop being marked for loading config again … … 548 566 #endif // HAVE_SETPROCTITLE 549 567 } 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 581 box_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 609 box_time_t Daemon::GetLoadedConfigModifiedTime() const 610 { 611 return mLoadedConfigModifiedTime; 612 } 613 -
box/trunk/lib/server/Daemon.h
r217 r353 16 16 #ifndef DAEMON__H 17 17 #define DAEMON__H 18 19 #include <string> 20 21 #include "BoxTime.h" 18 22 19 23 class Configuration; … … 41 45 virtual void Run(); 42 46 const Configuration &GetConfiguration() const; 43 47 const std::string &GetConfigFileName() const {return mConfigFileName;} 48 44 49 virtual const char *DaemonName() const; 45 50 virtual const char *DaemonBanner() const; … … 58 63 59 64 static void SetProcessTitle(const char *format, ...); 65 66 protected: 67 box_time_t GetLoadedConfigModifiedTime() const; 60 68 61 69 private: 62 70 static void SignalHandler(int sigraised); 71 box_time_t GetConfigFileModifiedTime() const; 63 72 64 73 private: 74 std::string mConfigFileName; 65 75 Configuration *mpConfiguration; 76 box_time_t mLoadedConfigModifiedTime; 66 77 bool mReloadConfigWanted; 67 78 bool mTerminateWanted;
Note: See TracChangeset
for help on using the changeset viewer.
