Changeset 3081


Ignore:
Timestamp:
Feb 2, 2012, 10:18:44 PM (4 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.