github.com/Cloud-Foundations/Dominator@v0.3.4/lib/filesystem/api.go (about) 1 package filesystem 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/Cloud-Foundations/Dominator/lib/filter" 8 "github.com/Cloud-Foundations/Dominator/lib/format" 9 "github.com/Cloud-Foundations/Dominator/lib/hash" 10 ) 11 12 type NumLinksTable map[uint64]int 13 14 type ListSelector uint8 15 16 const ( 17 ListSelectSkipMode = 1 << iota 18 ListSelectSkipNumLinks 19 ListSelectSkipUid 20 ListSelectSkipGid 21 ListSelectSkipSizeDevnum 22 ListSelectSkipMtime 23 ListSelectSkipName 24 ListSelectSkipData 25 26 ListSelectAll = 0 27 ) 28 29 type GenericInode interface { 30 GetGid() uint32 31 GetUid() uint32 32 List(w io.Writer, name string, numLinksTable NumLinksTable, 33 numLinks int, listSelector ListSelector, filter *filter.Filter) error 34 SetGid(gid uint32) 35 SetUid(uid uint32) 36 WriteMetadata(name string) error 37 } 38 39 type InodeTable map[uint64]GenericInode 40 type InodeToFilenamesTable map[uint64][]string 41 type FilenameToInodeTable map[string]uint64 42 type HashToInodesTable map[hash.Hash][]uint64 43 44 type FileSystem struct { 45 InodeTable InodeTable 46 inodeToFilenamesTable InodeToFilenamesTable 47 filenameToInodeTable FilenameToInodeTable 48 hashToInodesTable HashToInodesTable 49 NumRegularInodes uint64 50 TotalDataBytes uint64 51 numComputedRegularInodes *uint64 52 DirectoryCount uint64 53 DirectoryInode 54 } 55 56 func Decode(reader io.Reader) (*FileSystem, error) { 57 return decode(reader) 58 } 59 60 func (fs *FileSystem) BuildNumLinksTable() NumLinksTable { 61 return buildNumLinksTable(fs) 62 } 63 64 func (fs *FileSystem) ComputeTotalDataBytes() { 65 fs.computeTotalDataBytes() 66 } 67 68 func (fs *FileSystem) Encode(writer io.Writer) error { 69 return fs.encode(writer) 70 } 71 72 func (fs *FileSystem) EstimateUsage(blockSize uint64) uint64 { 73 return fs.estimateUsage(blockSize) 74 } 75 76 func (fs *FileSystem) FilenameToInodeTable() FilenameToInodeTable { 77 return fs.buildFilenameToInodeTable() 78 } 79 80 func (fs *FileSystem) Filter(filter *filter.Filter) *FileSystem { 81 return fs.filter(filter) 82 } 83 84 func (fs *FileSystem) ForEachFile( 85 fn func(name string, inodeNumber uint64, inode GenericInode) error) error { 86 return fs.forEachFile(fn) 87 } 88 89 func (fs *FileSystem) GetObjects() map[hash.Hash]uint64 { 90 return fs.getObjects() 91 } 92 93 func (fs *FileSystem) HashToInodesTable() HashToInodesTable { 94 return fs.buildHashToInodesTable() 95 } 96 97 func (fs *FileSystem) InodeToFilenamesTable() InodeToFilenamesTable { 98 return fs.buildInodeToFilenamesTable() 99 } 100 101 func (fs *FileSystem) List(w io.Writer) error { 102 return fs.list(w, ListSelectAll, nil) 103 } 104 105 func (fs *FileSystem) Listf(w io.Writer, listSelector ListSelector, 106 filter *filter.Filter) error { 107 return fs.list(w, listSelector, filter) 108 } 109 110 func (fs *FileSystem) NumComputedRegularInodes() uint64 { 111 return fs.computeNumComputedRegularInodes() 112 } 113 114 func (fs *FileSystem) RebuildInodePointers() error { 115 return fs.rebuildInodePointers() 116 } 117 118 func (fs *FileSystem) String() string { 119 return fmt.Sprintf("Tree: %d inodes, total file size: %s, number of regular inodes: %d", 120 len(fs.InodeTable), 121 format.FormatBytes(fs.TotalDataBytes), 122 fs.NumRegularInodes) 123 } 124 125 type DirectoryInode struct { 126 EntryList []*DirectoryEntry 127 EntriesByName map[string]*DirectoryEntry 128 Mode FileMode 129 Uid uint32 130 Gid uint32 131 } 132 133 func (directory *DirectoryInode) BuildEntryMap() { 134 directory.buildEntryMap() 135 } 136 137 func (inode *DirectoryInode) GetGid() uint32 { 138 return inode.Gid 139 } 140 141 func (inode *DirectoryInode) GetUid() uint32 { 142 return inode.Uid 143 } 144 145 func (inode *DirectoryInode) List(w io.Writer, name string, 146 numLinksTable NumLinksTable, numLinks int, 147 listSelector ListSelector, filter *filter.Filter) error { 148 return inode.list(w, name, numLinksTable, numLinks, listSelector, filter) 149 } 150 151 func (inode *DirectoryInode) RegisterStrings(registerFunc func(string)) { 152 inode.registerStrings(registerFunc) 153 } 154 155 func (inode *DirectoryInode) ReplaceStrings(replaceFunc func(string) string) { 156 inode.replaceStrings(replaceFunc) 157 } 158 159 func (inode *DirectoryInode) SetGid(gid uint32) { 160 inode.Gid = gid 161 } 162 163 func (inode *DirectoryInode) SetUid(uid uint32) { 164 inode.Uid = uid 165 } 166 167 func (inode *DirectoryInode) Write(name string) error { 168 return inode.write(name) 169 } 170 171 func (inode *DirectoryInode) WriteMetadata(name string) error { 172 return inode.writeMetadata(name) 173 } 174 175 type DirectoryEntry struct { 176 Name string 177 InodeNumber uint64 178 inode GenericInode // Keep private to avoid encoding/transmission. 179 } 180 181 func (dirent *DirectoryEntry) Inode() GenericInode { 182 return dirent.inode 183 } 184 185 func (dirent *DirectoryEntry) SetInode(inode GenericInode) { 186 dirent.inode = inode 187 } 188 189 func (dirent *DirectoryEntry) String() string { 190 return dirent.Name 191 } 192 193 type RegularInode struct { 194 Mode FileMode 195 Uid uint32 196 Gid uint32 197 MtimeNanoSeconds int32 198 MtimeSeconds int64 199 Size uint64 200 Hash hash.Hash 201 } 202 203 func (inode *RegularInode) GetGid() uint32 { 204 return inode.Gid 205 } 206 207 func (inode *RegularInode) GetUid() uint32 { 208 return inode.Uid 209 } 210 211 func (inode *RegularInode) List(w io.Writer, name string, 212 numLinksTable NumLinksTable, numLinks int, 213 listSelector ListSelector, filter *filter.Filter) error { 214 return inode.list(w, name, numLinksTable, numLinks, listSelector) 215 } 216 217 func (inode *RegularInode) SetGid(gid uint32) { 218 inode.Gid = gid 219 } 220 221 func (inode *RegularInode) SetUid(uid uint32) { 222 inode.Uid = uid 223 } 224 225 func (inode *RegularInode) WriteMetadata(name string) error { 226 return inode.writeMetadata(name) 227 } 228 229 type ComputedRegularInode struct { 230 Mode FileMode 231 Uid uint32 232 Gid uint32 233 Source string 234 } 235 236 func (inode *ComputedRegularInode) GetGid() uint32 { 237 return inode.Gid 238 } 239 240 func (inode *ComputedRegularInode) GetUid() uint32 { 241 return inode.Uid 242 } 243 244 func (inode *ComputedRegularInode) List(w io.Writer, name string, 245 numLinksTable NumLinksTable, numLinks int, 246 listSelector ListSelector, filter *filter.Filter) error { 247 return inode.list(w, name, numLinksTable, numLinks, listSelector) 248 } 249 250 func (inode *ComputedRegularInode) SetGid(gid uint32) { 251 inode.Gid = gid 252 } 253 254 func (inode *ComputedRegularInode) SetUid(uid uint32) { 255 inode.Uid = uid 256 } 257 258 func (inode *ComputedRegularInode) WriteMetadata(name string) error { 259 panic("cannot write metadata for computed file: " + name) 260 } 261 262 type SymlinkInode struct { 263 Uid uint32 264 Gid uint32 265 Symlink string 266 } 267 268 func (inode *SymlinkInode) GetGid() uint32 { 269 return inode.Gid 270 } 271 272 func (inode *SymlinkInode) GetUid() uint32 { 273 return inode.Uid 274 } 275 276 func (inode *SymlinkInode) List(w io.Writer, name string, 277 numLinksTable NumLinksTable, numLinks int, 278 listSelector ListSelector, filter *filter.Filter) error { 279 return inode.list(w, name, numLinksTable, numLinks, listSelector) 280 } 281 282 func (inode *SymlinkInode) SetGid(gid uint32) { 283 inode.Gid = gid 284 } 285 286 func (inode *SymlinkInode) SetUid(uid uint32) { 287 inode.Uid = uid 288 } 289 290 func (inode *SymlinkInode) Write(name string) error { 291 return inode.write(name) 292 } 293 294 func (inode *SymlinkInode) WriteMetadata(name string) error { 295 return inode.writeMetadata(name) 296 } 297 298 type SpecialInode struct { 299 Mode FileMode 300 Uid uint32 301 Gid uint32 302 MtimeNanoSeconds int32 303 MtimeSeconds int64 304 Rdev uint64 305 } 306 307 func (inode *SpecialInode) GetGid() uint32 { 308 return inode.Gid 309 } 310 311 func (inode *SpecialInode) GetUid() uint32 { 312 return inode.Uid 313 } 314 315 func (inode *SpecialInode) List(w io.Writer, name string, 316 numLinksTable NumLinksTable, numLinks int, 317 listSelector ListSelector, filter *filter.Filter) error { 318 return inode.list(w, name, numLinksTable, numLinks, listSelector) 319 } 320 321 func (inode *SpecialInode) SetGid(gid uint32) { 322 inode.Gid = gid 323 } 324 325 func (inode *SpecialInode) SetUid(uid uint32) { 326 inode.Uid = uid 327 } 328 329 func (inode *SpecialInode) Write(name string) error { 330 return inode.write(name) 331 } 332 333 func (inode *SpecialInode) WriteMetadata(name string) error { 334 return inode.writeMetadata(name) 335 } 336 337 type FileMode uint32 338 339 func (mode FileMode) String() string { 340 return mode.string() 341 } 342 343 func CompareFileSystems(left, right *FileSystem, logWriter io.Writer) bool { 344 return compareFileSystems(left, right, logWriter) 345 } 346 347 func CompareDirectoryInodes(left, right *DirectoryInode, 348 logWriter io.Writer) bool { 349 return compareDirectoryInodes(left, right, logWriter) 350 } 351 352 func CompareDirectoriesMetadata(left, right *DirectoryInode, 353 logWriter io.Writer) bool { 354 return compareDirectoriesMetadata(left, right, logWriter) 355 } 356 357 func CompareDirectoryEntries(left, right *DirectoryEntry, 358 logWriter io.Writer) bool { 359 return compareDirectoryEntries(left, right, logWriter) 360 } 361 362 func CompareInodes(left, right GenericInode, logWriter io.Writer) ( 363 sameType, sameMetadata, sameData bool) { 364 return compareInodes(left, right, logWriter) 365 } 366 367 func CompareRegularInodes(left, right *RegularInode, logWriter io.Writer) bool { 368 return compareRegularInodes(left, right, logWriter) 369 } 370 371 func CompareRegularInodesMetadata(left, right *RegularInode, 372 logWriter io.Writer) bool { 373 return compareRegularInodesMetadata(left, right, logWriter) 374 } 375 376 func CompareRegularInodesData(left, right *RegularInode, 377 logWriter io.Writer) bool { 378 return compareRegularInodesData(left, right, logWriter) 379 } 380 381 func CompareSymlinkInodes(left, right *SymlinkInode, logWriter io.Writer) bool { 382 return compareSymlinkInodes(left, right, logWriter) 383 } 384 385 func CompareSymlinkInodesMetadata(left, right *SymlinkInode, 386 logWriter io.Writer) bool { 387 return compareSymlinkInodesMetadata(left, right, logWriter) 388 } 389 390 func CompareSymlinkInodesData(left, right *SymlinkInode, 391 logWriter io.Writer) bool { 392 return compareSymlinkInodesData(left, right, logWriter) 393 } 394 395 func CompareSpecialInodes(left, right *SpecialInode, logWriter io.Writer) bool { 396 return compareSpecialInodes(left, right, logWriter) 397 } 398 399 func CompareSpecialInodesMetadata(left, right *SpecialInode, 400 logWriter io.Writer) bool { 401 return compareSpecialInodesMetadata(left, right, logWriter) 402 } 403 404 func CompareSpecialInodesData(left, right *SpecialInode, 405 logWriter io.Writer) bool { 406 return compareSpecialInodesData(left, right, logWriter) 407 } 408 409 func ForceWriteMetadata(inode GenericInode, name string) error { 410 return forceWriteMetadata(inode, name) 411 }