source: box/trunk/lib/backupstore/BackupStoreCheck.h @ 3037

Revision 3037, 6.1 KB checked in by chris, 7 months ago (diff)

Allow getting the number of errors found by a store checker object.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    BackupStoreCheck.h
5//              Purpose: Check a store for consistency
6//              Created: 21/4/04
7//
8// --------------------------------------------------------------------------
9
10#ifndef BACKUPSTORECHECK__H
11#define BACKUPSTORECHECK__H
12
13#include <string>
14#include <map>
15#include <vector>
16#include <set>
17
18#include "NamedLock.h"
19#include "BackupStoreDirectory.h"
20
21class IOStream;
22class BackupStoreFilename;
23
24/*
25
26The following problems can be fixed:
27
28        * Spurious files deleted
29        * Corrupted files deleted
30        * Root ID as file, deleted
31        * Dirs with wrong object id inside, deleted
32        * Direcetory entries pointing to non-existant files, deleted
33        * Doubly references files have second reference deleted
34        * Wrong directory container IDs fixed
35        * Missing root recreated
36        * Reattach files which exist, but aren't referenced
37                - files go into directory original directory, if it still exists
38                - missing directories are inferred, and recreated
39                - or if all else fails, go into lost+found
40                - file dir entries take the original name and mod time
41                - directories go into lost+found
42        * Container IDs on directories corrected
43        * Inside directories,
44                - only one object per name has old version clear
45                - IDs aren't duplicated
46        * Bad store info files regenerated
47        * Bad sizes of files in directories fixed
48
49*/
50
51
52// Size of blocks in the list of IDs
53#ifdef BOX_RELEASE_BUILD
54        #define BACKUPSTORECHECK_BLOCK_SIZE             (64*1024)
55#else
56        #define BACKUPSTORECHECK_BLOCK_SIZE             8
57#endif
58
59// The object ID type -- can redefine to uint32_t to produce a lower memory version for smaller stores
60typedef int64_t BackupStoreCheck_ID_t;
61// Can redefine the size type for lower memory usage too
62typedef int64_t BackupStoreCheck_Size_t;
63
64// --------------------------------------------------------------------------
65//
66// Class
67//              Name:    BackupStoreCheck
68//              Purpose: Check a store for consistency
69//              Created: 21/4/04
70//
71// --------------------------------------------------------------------------
72class BackupStoreCheck
73{
74public:
75        BackupStoreCheck(const std::string &rStoreRoot, int DiscSetNumber, int32_t AccountID, bool FixErrors, bool Quiet);
76        ~BackupStoreCheck();
77private:
78        // no copying
79        BackupStoreCheck(const BackupStoreCheck &);
80        BackupStoreCheck &operator=(const BackupStoreCheck &);
81public:
82
83        // Do the exciting things
84        void Check();
85       
86        bool ErrorsFound() {return mNumberErrorsFound > 0;}
87        inline int64_t GetNumErrorsFound()
88        {
89                return mNumberErrorsFound;
90        }
91
92private:
93        enum
94        {
95                // Bit mask
96                Flags_IsDir = 1,
97                Flags_IsContained = 2,
98                // Mask
99                Flags__MASK = 3,
100                // Number of bits
101                Flags__NumFlags = 2,
102                // Items per uint8_t
103                Flags__NumItemsPerEntry = 4     // ie 8 / 2
104        };
105
106        typedef struct
107        {
108                // Note use arrays within the block, rather than the more obvious array of
109                // objects, to be more memory efficient -- think alignment of the byte values.
110                uint8_t mFlags[BACKUPSTORECHECK_BLOCK_SIZE * Flags__NumFlags / Flags__NumItemsPerEntry];
111                BackupStoreCheck_ID_t mID[BACKUPSTORECHECK_BLOCK_SIZE];
112                BackupStoreCheck_ID_t mContainer[BACKUPSTORECHECK_BLOCK_SIZE];
113                BackupStoreCheck_Size_t mObjectSizeInBlocks[BACKUPSTORECHECK_BLOCK_SIZE];
114        } IDBlock;
115       
116        // Phases of the check
117        void CheckObjects();
118        void CheckDirectories();
119        void CheckRoot();
120        void CheckUnattachedObjects();
121        void FixDirsWithWrongContainerID();
122        void FixDirsWithLostDirs();
123        void WriteNewStoreInfo();
124
125        // Checking functions
126        int64_t CheckObjectsScanDir(int64_t StartID, int Level, const std::string &rDirName);
127        void CheckObjectsDir(int64_t StartID);
128        bool CheckAndAddObject(int64_t ObjectID, const std::string &rFilename);
129        bool CheckDirectoryEntry(BackupStoreDirectory::Entry& rEntry,
130                int64_t DirectoryID, int32_t indexInDirBlock,
131                bool& rIsModified);
132        int64_t CheckFile(int64_t ObjectID, IOStream &rStream);
133        int64_t CheckDirInitial(int64_t ObjectID, IOStream &rStream);   
134
135        // Fixing functions
136        bool TryToRecreateDirectory(int64_t MissingDirectoryID);
137        void InsertObjectIntoDirectory(int64_t ObjectID, int64_t DirectoryID, bool IsDirectory);
138        int64_t GetLostAndFoundDirID();
139        void CreateBlankDirectory(int64_t DirectoryID, int64_t ContainingDirID);
140
141        // Data handling
142        void FreeInfo();
143        void AddID(BackupStoreCheck_ID_t ID, BackupStoreCheck_ID_t Container, BackupStoreCheck_Size_t ObjectSize, bool IsFile);
144        IDBlock *LookupID(BackupStoreCheck_ID_t ID, int32_t &rIndexOut);
145        inline void SetFlags(IDBlock *pBlock, int32_t Index, uint8_t Flags)
146        {
147                ASSERT(pBlock != 0);
148                ASSERT(Index < BACKUPSTORECHECK_BLOCK_SIZE);
149                ASSERT(Flags < (1 << Flags__NumFlags));
150               
151                pBlock->mFlags[Index / Flags__NumItemsPerEntry]
152                        |= (Flags << ((Index % Flags__NumItemsPerEntry) * Flags__NumFlags));
153        }
154        inline uint8_t GetFlags(IDBlock *pBlock, int32_t Index)
155        {
156                ASSERT(pBlock != 0);
157                ASSERT(Index < BACKUPSTORECHECK_BLOCK_SIZE);
158
159                return (pBlock->mFlags[Index / Flags__NumItemsPerEntry] >> ((Index % Flags__NumItemsPerEntry) * Flags__NumFlags)) & Flags__MASK;
160        }
161       
162#ifndef BOX_RELEASE_BUILD
163        void DumpObjectInfo();
164        #define DUMP_OBJECT_INFO DumpObjectInfo();
165#else
166        #define DUMP_OBJECT_INFO
167#endif
168
169private:
170        std::string mStoreRoot;
171        int mDiscSetNumber;
172        int32_t mAccountID;
173        std::string mAccountName;
174        bool mFixErrors;
175        bool mQuiet;
176       
177        int64_t mNumberErrorsFound;
178       
179        // Lock for the store account
180        NamedLock mAccountLock;
181       
182        // Storage for ID data
183        typedef std::map<BackupStoreCheck_ID_t, IDBlock*> Info_t;
184        Info_t mInfo;
185        BackupStoreCheck_ID_t mLastIDInInfo;
186        IDBlock *mpInfoLastBlock;
187        int32_t mInfoLastBlockEntries;
188       
189        // List of stuff to fix
190        std::vector<BackupStoreCheck_ID_t> mDirsWithWrongContainerID;
191        // This is a map of lost dir ID -> existing dir ID
192        std::map<BackupStoreCheck_ID_t, BackupStoreCheck_ID_t>
193                mDirsWhichContainLostDirs;
194       
195        // Set of extra directories added
196        std::set<BackupStoreCheck_ID_t> mDirsAdded;
197       
198        // Misc stuff
199        int32_t mLostDirNameSerial;
200        int64_t mLostAndFoundDirectoryID;
201       
202        // Usage
203        int64_t mBlocksUsed;
204        int64_t mBlocksInCurrentFiles;
205        int64_t mBlocksInOldFiles;
206        int64_t mBlocksInDeletedFiles;
207        int64_t mBlocksInDirectories;
208        int64_t mNumFiles;
209        int64_t mNumOldFiles;
210        int64_t mNumDeletedFiles;
211        int64_t mNumDirectories;
212};
213
214#endif // BACKUPSTORECHECK__H
215
Note: See TracBrowser for help on using the repository browser.