Changeset 3081


Ignore:
Timestamp:
02/02/12 22:18:44 (2 years ago)
Author:
chris
Message:

If a location was not present (on disk) when bbackupd started, don't forget
about it but start backing it up if it appears subsequently.

Location:
box/trunk/bin/bbackupd
Files:
2 edited

Legend:

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

    r3032 r3081  
    325325{ 
    326326        // Run through, and delete everything 
    327         for(std::vector<Location *>::iterator i = mLocations.begin(); 
     327        for(Locations::iterator i = mLocations.begin(); 
    328328                i != mLocations.end(); ++i) 
    329329        { 
     
    965965        // need to do it here so we have a  
    966966        // (potential) connection to use 
    967         if(mLocations.empty()) 
    968967        { 
    969968                const Configuration &locations( 
     
    989988                                         
    990989        // Go through the records, syncing them 
    991         for(std::vector<Location *>::const_iterator  
     990        for(Locations::const_iterator  
    992991                i(mLocations.begin());  
    993992                i != mLocations.end(); ++i) 
     
    10361035        mClientStoreMarker = clientContext.GetClientStoreMarker(); 
    10371036        mStorageLimitExceeded = clientContext.StorageLimitExceeded(); 
    1038         mReadErrorsOnFilesystemObjects = 
     1037        mReadErrorsOnFilesystemObjects |= 
    10391038                params.mReadErrorsOnFilesystemObjects; 
    10401039 
     
    21052104void BackupDaemon::SetupLocations(BackupClientContext &rClientContext, const Configuration &rLocationsConf) 
    21062105{ 
    2107         if(!mLocations.empty()) 
    2108         { 
    2109                 // Looks correctly set up 
    2110                 return; 
    2111         } 
    2112  
    2113         // Make sure that if a directory is reinstated, then it doesn't get deleted      
    2114         mDeleteUnusedRootDirEntriesAfter = 0; 
    2115         mUnusedRootDirEntries.clear(); 
    2116  
    2117         // Just a check to make sure it's right. 
    2118         DeleteAllLocations(); 
    2119          
    21202106        // Going to need a copy of the root directory. Get a connection, 
    21212107        // and fetch it. 
     
    22242210        std::vector<std::string> locNames = 
    22252211                rLocationsConf.GetSubConfigurationNames(); 
    2226          
     2212 
     2213        // We only want completely configured locations to be in the list 
     2214        // when this function exits, so move them all to a temporary list. 
     2215        // Entries matching a properly configured location will be moved 
     2216        // back to mLocations. Anything left in this list after the loop 
     2217        // finishes will be deleted. 
     2218        Locations tmpLocations = mLocations; 
     2219        mLocations.clear(); 
     2220 
     2221        // The ID map list will be repopulated automatically by this loop 
     2222        mIDMapMounts.clear(); 
     2223 
    22272224        for(std::vector<std::string>::iterator 
    22282225                pLocName  = locNames.begin(); 
     
    22302227                pLocName++) 
    22312228        { 
     2229                Location* pLoc = NULL; 
     2230 
     2231                // Try to find and reuse an existing Location object 
     2232                for(Locations::const_iterator 
     2233                        i  = tmpLocations.begin(); 
     2234                        i != tmpLocations.end(); i++) 
     2235                { 
     2236                        if ((*i)->mName == *pLocName) 
     2237                        { 
     2238                                BOX_TRACE("Location already configured: " << *pLocName); 
     2239                                pLoc = *i; 
     2240                                break; 
     2241                        } 
     2242                } 
     2243                         
    22322244                const Configuration& rConfig( 
    22332245                        rLocationsConf.GetSubConfiguration(*pLocName)); 
    2234                 BOX_TRACE("new location: " << *pLocName); 
    2235                  
    2236                 // Create a record for it 
    2237                 std::auto_ptr<Location> apLoc(new Location); 
     2246                std::auto_ptr<Location> apLoc; 
    22382247 
    22392248                try 
    22402249                { 
    2241                         // Setup names in the location record 
    2242                         apLoc->mName = *pLocName; 
    2243                         apLoc->mPath = rConfig.GetKeyValue("Path"); 
    2244                          
    2245                         // Read the exclude lists from the Configuration 
    2246                         apLoc->mpExcludeFiles = BackupClientMakeExcludeList_Files(rConfig); 
    2247                         apLoc->mpExcludeDirs = BackupClientMakeExcludeList_Dirs(rConfig); 
     2250                        if(pLoc == NULL) 
     2251                        { 
     2252                                // Create a record for it 
     2253                                BOX_TRACE("New location: " << *pLocName); 
     2254                                pLoc = new Location; 
     2255 
     2256                                // ensure deletion if setup fails 
     2257                                apLoc.reset(pLoc); 
     2258 
     2259                                // Setup names in the location record 
     2260                                pLoc->mName = *pLocName; 
     2261                                pLoc->mPath = rConfig.GetKeyValue("Path"); 
     2262                                 
     2263                                // Read the exclude lists from the Configuration 
     2264                                pLoc->mpExcludeFiles = BackupClientMakeExcludeList_Files(rConfig); 
     2265                                pLoc->mpExcludeDirs = BackupClientMakeExcludeList_Dirs(rConfig); 
     2266                        } 
    22482267 
    22492268                        // Does this exist on the server? 
     
    22522271                        // consider to remote one for deletion. 
    22532272                        BackupStoreDirectory::Iterator iter(dir); 
    2254                         BackupStoreFilenameClear dirname(apLoc->mName); // generate the filename 
     2273                        BackupStoreFilenameClear dirname(pLoc->mName);  // generate the filename 
    22552274                        BackupStoreDirectory::Entry *en = iter.FindMatchingClearName(dirname); 
    22562275                        int64_t oid = 0; 
     
    22722291#ifdef HAVE_STRUCT_STATVFS_F_MNTONNAME 
    22732292                                struct statvfs s; 
    2274                                 if(::statvfs(apLoc->mPath.c_str(), &s) != 0) 
     2293                                if(::statvfs(pLoc->mPath.c_str(), &s) != 0) 
    22752294#else // HAVE_STRUCT_STATVFS_F_MNTONNAME 
    22762295                                struct statfs s; 
    2277                                 if(::statfs(apLoc->mPath.c_str(), &s) != 0) 
     2296                                if(::statfs(pLoc->mPath.c_str(), &s) != 0) 
    22782297#endif // HAVE_STRUCT_STATVFS_F_MNTONNAME 
    22792298                                { 
    2280                                         BOX_LOG_SYS_WARNING("Failed to stat location " 
    2281                                                 "path '" << apLoc->mPath << 
    2282                                                 "', skipping location '" << 
    2283                                                 apLoc->mName << "'"); 
    2284                                         continue; 
     2299                                        BOX_THROW_SYS_ERROR("Failed to stat " 
     2300                                                "path '" << pLoc->mPath << 
     2301                                                "' for location '" << 
     2302                                                pLoc->mName << "'"); 
    22852303                                } 
    22862304 
     
    22912309 
    22922310                                // Warn in logs if the directory isn't absolute 
    2293                                 if(apLoc->mPath[0] != '/') 
     2311                                if(pLoc->mPath[0] != '/') 
    22942312                                { 
    22952313                                        BOX_WARNING("Location path '" 
    2296                                                 << apLoc->mPath  
     2314                                                << pLoc->mPath  
    22972315                                                << "' is not absolute"); 
    22982316                                } 
     
    23092327                                                // (sorting order ensures this) 
    23102328                                                BOX_TRACE("checking against mount point " << *i); 
    2311                                                 if(::strncmp(i->c_str(), apLoc->mPath.c_str(), i->size()) == 0) 
     2329                                                if(::strncmp(i->c_str(), pLoc->mPath.c_str(), i->size()) == 0) 
    23122330                                                { 
    23132331                                                        // Match 
     
    23172335                                        } 
    23182336                                        BOX_TRACE("mount point chosen for " 
    2319                                                 << apLoc->mPath << " is " 
     2337                                                << pLoc->mPath << " is " 
    23202338                                                << mountName); 
    23212339                                } 
     
    23282346                                { 
    23292347                                        // Yes -- store the index 
    2330                                         apLoc->mIDMapIndex = f->second; 
     2348                                        pLoc->mIDMapIndex = f->second; 
    23312349                                } 
    23322350                                else 
    23332351                                { 
    23342352                                        // No -- new index 
    2335                                         apLoc->mIDMapIndex = numIDMaps; 
     2353                                        pLoc->mIDMapIndex = numIDMaps; 
    23362354                                        mounts[mountName] = numIDMaps; 
    23372355                                         
     
    23532371                                try 
    23542372                                { 
    2355                                         attr.ReadAttributes(apLoc->mPath.c_str(),  
     2373                                        attr.ReadAttributes(pLoc->mPath.c_str(),  
    23562374                                                true /* directories have zero mod times */, 
    23572375                                                0 /* not interested in mod time */,  
     
    23612379                                { 
    23622380                                        BOX_ERROR("Failed to get attributes " 
    2363                                                 "for path '" << apLoc->mPath 
     2381                                                "for path '" << pLoc->mPath 
    23642382                                                << "', skipping location '" << 
    2365                                                 apLoc->mName << "'"); 
    2366                                         continue; 
     2383                                                pLoc->mName << "'"); 
     2384                                        throw; 
    23672385                                } 
    23682386                                 
     
    23822400                                { 
    23832401                                        BOX_ERROR("Failed to create remote " 
    2384                                                 "directory '/" << apLoc->mName << 
     2402                                                "directory '/" << pLoc->mName << 
    23852403                                                "', skipping location '" << 
    2386                                                 apLoc->mName << "'"); 
    2387                                         continue; 
     2404                                                pLoc->mName << "'"); 
     2405                                        throw; 
    23882406                                } 
    23892407 
     
    23922410                        // Create and store the directory object for the root of this location 
    23932411                        ASSERT(oid != 0); 
    2394                         BackupClientDirectoryRecord *precord = 
    2395                                 new BackupClientDirectoryRecord(oid, *pLocName); 
    2396                         apLoc->mpDirectoryRecord.reset(precord); 
     2412                        if(pLoc->mpDirectoryRecord.get() == NULL) 
     2413                        { 
     2414                                BackupClientDirectoryRecord *precord = 
     2415                                        new BackupClientDirectoryRecord(oid, *pLocName); 
     2416                                pLoc->mpDirectoryRecord.reset(precord); 
     2417                        } 
    23972418                         
     2419                        // Remove it from the temporary list to avoid deletion 
     2420                        tmpLocations.remove(pLoc); 
     2421 
    23982422                        // Push it back on the vector of locations 
    2399                         mLocations.push_back(apLoc.release()); 
     2423                        mLocations.push_back(pLoc); 
     2424 
     2425                        if(apLoc.get() != NULL) 
     2426                        { 
     2427                                // Don't delete it now! 
     2428                                apLoc.release(); 
     2429                        } 
    24002430                } 
    24012431                catch (std::exception &e) 
    24022432                { 
    24032433                        BOX_ERROR("Failed to configure location '" 
    2404                                 << apLoc->mName << "' path '" 
    2405                                 << apLoc->mPath << "': " << e.what() << 
     2434                                << pLoc->mName << "' path '" 
     2435                                << pLoc->mPath << "': " << e.what() << 
    24062436                                ": please check for previous errors"); 
    2407                         throw; 
     2437                        mReadErrorsOnFilesystemObjects = true; 
    24082438                } 
    24092439                catch(...) 
    24102440                { 
    24112441                        BOX_ERROR("Failed to configure location '" 
    2412                                 << apLoc->mName << "' path '" 
    2413                                 << apLoc->mPath << "': please check for " 
     2442                                << pLoc->mName << "' path '" 
     2443                                << pLoc->mPath << "': please check for " 
    24142444                                "previous errors"); 
    2415                         throw; 
    2416                 } 
    2417         } 
     2445                        mReadErrorsOnFilesystemObjects = true; 
     2446                } 
     2447        } 
     2448 
     2449        // Now remove any leftovers 
     2450        for(BackupDaemon::Locations::iterator 
     2451                i  = tmpLocations.begin(); 
     2452                i != tmpLocations.end(); i++) 
     2453        { 
     2454                BOX_INFO("Removing obsolete location from memory: " << 
     2455                        (*i)->mName); 
     2456                delete *i; 
     2457        } 
     2458 
     2459        tmpLocations.clear(); 
    24182460         
    24192461        // Any entries in the root directory which need deleting? 
     
    26892731{ 
    26902732        // Search for the location 
    2691         for(std::vector<Location *>::const_iterator i(mLocations.begin()); i != mLocations.end(); ++i) 
     2733        for(Locations::const_iterator i(mLocations.begin()); i != mLocations.end(); ++i) 
    26922734        { 
    26932735                if((*i)->mName == rLocationName) 
     
    30513093                anArchive.Write(iCount); 
    30523094 
    3053                 for(int v = 0; v < iCount; v++) 
    3054                 { 
    3055                         ASSERT(mLocations[v]); 
    3056                         mLocations[v]->Serialize(anArchive); 
     3095                for(Locations::const_iterator i = mLocations.begin(); 
     3096                        i != mLocations.end(); i++) 
     3097                { 
     3098                        ASSERT(*i); 
     3099                        (*i)->Serialize(anArchive); 
    30573100                } 
    30583101 
  • box/trunk/bin/bbackupd/BackupDaemon.h

    r2992 r3081  
    158158 
    159159public: 
    160         typedef const std::vector<Location *> Locations; 
     160        typedef std::list<Location *> Locations; 
    161161        Locations GetLocations() { return mLocations; } 
    162162         
     
    164164        int mState;             // what the daemon is currently doing 
    165165 
    166         std::vector<Location *> mLocations; 
     166        Locations mLocations; 
    167167         
    168168        std::vector<std::string> mIDMapMounts; 
Note: See TracChangeset for help on using the changeset viewer.