sapling/eden/integration/edenclient_test.py

25 lines
778 B
Python
Raw Normal View History

Allow rm of files with corrupt overlay Summary: Sometimes, Eden's overlay (in `$client_dir/local/`) gets corrupt. In particular, sometimes overlay files can be truncated or missing after a hard reboot where the underlying filesystem state was not flushed to disk. For such files, open(), stat(), unlink(), etc. from Eden report ENOENT, yet readdir() on the containing directory shows that the file does exist. In other words, the problematic file is undeletable: ``` $ ls -la dir/ /bin/ls: cannot access dir/corrupt_file: No such file or directory total 0 drwxr-xr-x. 3 strager 0 Jul 10 21:41 . drwxr-xr-x. 48 strager 0 Jul 10 21:41 .. -?????????? ? ? ? ? corrupt_file $ rm dir/corrupt_file rm: cannot remove ‘dir/corrupt_file’: No such file or directory ``` Allow users to delete these problematic files (if the file was a regular file and not a directory) by doing the following: * Allow corrupt regular files to be unlink()d successfully. * Allow corrupt regular files to be stat()d. Making stat() succeed is a requirement by FUSE: * For unlink(), FUSE performs FUSE_LOOKUP before FUSE_UNLINK. If FUSE_LOOKUP fails, unlink() fails. Therefore, we must make FUSE_LOOKUP succeed for corrupt files. * For stat(), FUSE performs FUSE_LOOKUP and sometimes FUSE_GETATTR. Since we must make FUSE_LOOKUP succeed (for unlink()), it's natural to make FUSE_GETATTR succeed too. A future diff will fix corrupted directories. Reviewed By: chadaustin Differential Revision: D8884793 fbshipit-source-id: 1100037bf52475fcca66f39946b917ce604f12dc
2018-07-26 06:52:58 +03:00
#!/usr/bin/env python3
# Copyright (c) Facebook, Inc. and its affiliates.
Allow rm of files with corrupt overlay Summary: Sometimes, Eden's overlay (in `$client_dir/local/`) gets corrupt. In particular, sometimes overlay files can be truncated or missing after a hard reboot where the underlying filesystem state was not flushed to disk. For such files, open(), stat(), unlink(), etc. from Eden report ENOENT, yet readdir() on the containing directory shows that the file does exist. In other words, the problematic file is undeletable: ``` $ ls -la dir/ /bin/ls: cannot access dir/corrupt_file: No such file or directory total 0 drwxr-xr-x. 3 strager 0 Jul 10 21:41 . drwxr-xr-x. 48 strager 0 Jul 10 21:41 .. -?????????? ? ? ? ? corrupt_file $ rm dir/corrupt_file rm: cannot remove ‘dir/corrupt_file’: No such file or directory ``` Allow users to delete these problematic files (if the file was a regular file and not a directory) by doing the following: * Allow corrupt regular files to be unlink()d successfully. * Allow corrupt regular files to be stat()d. Making stat() succeed is a requirement by FUSE: * For unlink(), FUSE performs FUSE_LOOKUP before FUSE_UNLINK. If FUSE_LOOKUP fails, unlink() fails. Therefore, we must make FUSE_LOOKUP succeed for corrupt files. * For stat(), FUSE performs FUSE_LOOKUP and sometimes FUSE_GETATTR. Since we must make FUSE_LOOKUP succeed (for unlink()), it's natural to make FUSE_GETATTR succeed too. A future diff will fix corrupted directories. Reviewed By: chadaustin Differential Revision: D8884793 fbshipit-source-id: 1100037bf52475fcca66f39946b917ce604f12dc
2018-07-26 06:52:58 +03:00
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2.
Allow rm of files with corrupt overlay Summary: Sometimes, Eden's overlay (in `$client_dir/local/`) gets corrupt. In particular, sometimes overlay files can be truncated or missing after a hard reboot where the underlying filesystem state was not flushed to disk. For such files, open(), stat(), unlink(), etc. from Eden report ENOENT, yet readdir() on the containing directory shows that the file does exist. In other words, the problematic file is undeletable: ``` $ ls -la dir/ /bin/ls: cannot access dir/corrupt_file: No such file or directory total 0 drwxr-xr-x. 3 strager 0 Jul 10 21:41 . drwxr-xr-x. 48 strager 0 Jul 10 21:41 .. -?????????? ? ? ? ? corrupt_file $ rm dir/corrupt_file rm: cannot remove ‘dir/corrupt_file’: No such file or directory ``` Allow users to delete these problematic files (if the file was a regular file and not a directory) by doing the following: * Allow corrupt regular files to be unlink()d successfully. * Allow corrupt regular files to be stat()d. Making stat() succeed is a requirement by FUSE: * For unlink(), FUSE performs FUSE_LOOKUP before FUSE_UNLINK. If FUSE_LOOKUP fails, unlink() fails. Therefore, we must make FUSE_LOOKUP succeed for corrupt files. * For stat(), FUSE performs FUSE_LOOKUP and sometimes FUSE_GETATTR. Since we must make FUSE_LOOKUP succeed (for unlink()), it's natural to make FUSE_GETATTR succeed too. A future diff will fix corrupted directories. Reviewed By: chadaustin Differential Revision: D8884793 fbshipit-source-id: 1100037bf52475fcca66f39946b917ce604f12dc
2018-07-26 06:52:58 +03:00
import pathlib
from .lib import testcase
@testcase.eden_repo_test
class EdenClientTest(testcase.EdenRepoTest):
def populate_repo(self) -> None:
self.repo.write_file("hello", "hola\n")
self.repo.commit("Initial commit.")
def test_client_dir_for_mount(self) -> None:
clone_path = pathlib.Path(self.tmp_dir, "test_checkout")
self.eden.run_cmd("clone", self.repo.path, str(clone_path))
Allow rm of files with corrupt overlay Summary: Sometimes, Eden's overlay (in `$client_dir/local/`) gets corrupt. In particular, sometimes overlay files can be truncated or missing after a hard reboot where the underlying filesystem state was not flushed to disk. For such files, open(), stat(), unlink(), etc. from Eden report ENOENT, yet readdir() on the containing directory shows that the file does exist. In other words, the problematic file is undeletable: ``` $ ls -la dir/ /bin/ls: cannot access dir/corrupt_file: No such file or directory total 0 drwxr-xr-x. 3 strager 0 Jul 10 21:41 . drwxr-xr-x. 48 strager 0 Jul 10 21:41 .. -?????????? ? ? ? ? corrupt_file $ rm dir/corrupt_file rm: cannot remove ‘dir/corrupt_file’: No such file or directory ``` Allow users to delete these problematic files (if the file was a regular file and not a directory) by doing the following: * Allow corrupt regular files to be unlink()d successfully. * Allow corrupt regular files to be stat()d. Making stat() succeed is a requirement by FUSE: * For unlink(), FUSE performs FUSE_LOOKUP before FUSE_UNLINK. If FUSE_LOOKUP fails, unlink() fails. Therefore, we must make FUSE_LOOKUP succeed for corrupt files. * For stat(), FUSE performs FUSE_LOOKUP and sometimes FUSE_GETATTR. Since we must make FUSE_LOOKUP succeed (for unlink()), it's natural to make FUSE_GETATTR succeed too. A future diff will fix corrupted directories. Reviewed By: chadaustin Differential Revision: D8884793 fbshipit-source-id: 1100037bf52475fcca66f39946b917ce604f12dc
2018-07-26 06:52:58 +03:00
self.assertEqual(
self.eden.client_dir_for_mount(clone_path),
pathlib.Path(self.eden_dir, "clients", "test_checkout"),
)