def _verify_orphans_extracted(self, log_dir: Path, expected_errors: List[ExpectedError], new_fsck=False) -> None: # Build the state that we expect to find in the lost+found directory expected = verify_mod.ExpectedFileSet() for error in expected_errors: if isinstance(error, OrphanInodes): self._build_expected_orphans(expected, error, new_fsck) elif isinstance(error, InvalidMaterializedInode): # The Python fsck code extracts broken data files into a separate # "broken_inodes" subdirectory, but the newer C++ logic puts everything # into the single "lost+found" directory. if new_fsck: extracted_path = os.path.join( str(error.parent_inode_number), os.path.basename(error.path)) expected.add_file(extracted_path, error.bad_data, perms=0o644) verifier = verify_mod.SnapshotVerifier() verifier.verify_directory(log_dir / "lost+found", expected) if verifier.errors: self.fail(f"found errors when checking extracted orphan inodes: " f"{verifier.errors}")
def _verify_contents(self, expected_files: verify_mod.ExpectedFileSet) -> None: verifier = verify_mod.SnapshotVerifier() with self.snapshot.edenfs() as eden: eden.start() verifier.verify_directory(self.snapshot.checkout_path, expected_files) if verifier.errors: self.fail( f"found errors when checking checkout contents: {verifier.errors}" )
def _verify_orphans_extracted(self, log_dir: Path, orphan_errors: OrphanInodes) -> None: # Build the state that we expect to find in the lost+found directory expected = verify_mod.ExpectedFileSet() # All of the orphan files should be extracted as regular files using their inode # number as the path. We cannot tell if the inodes were originally regular # files, symlinks, or sockets, so everything just gets extracted as a regular # file. for orphan_file in orphan_errors.files: expected.add_file( str(orphan_file.inode_number), orphan_file.file_info.contents, perms=0o600, ) # All of the orphan directories will be extracted as directories. # For their contents we know file types but not permissions. for orphan_dir in orphan_errors.dirs: dir_inode = Path(str(orphan_dir.inode_number)) for expected_file in orphan_dir.contents: orphan_path = dir_inode / expected_file.path.relative_to( orphan_dir.path) if expected_file.file_type == stat_mod.S_IFSOCK: # socket files are ignored and never extracted continue elif expected_file.file_type == stat_mod.S_IFLNK: expected.add_symlink(orphan_path, expected_file.contents, perms=0o777) elif expected_file.file_type == stat_mod.S_IFREG: expected.add_file(orphan_path, expected_file.contents, perms=0o600) else: raise Exception( "unknown file type for expected orphan inode") verifier = verify_mod.SnapshotVerifier() verifier.verify_directory(log_dir / "lost+found", expected) if verifier.errors: self.fail(f"found errors when checking extracted orphan inodes: " f"{verifier.errors}")