def get_all_eden_mount_points(mount_table: mtab.MountTable) -> Set[bytes]: all_system_mounts = mount_table.read() return { mount.mount_point for mount in all_system_mounts if mount.device == b"edenfs" and mount.vfstype == b"fuse" }
def get_all_stale_eden_mount_points( mount_table: mtab.MountTable) -> List[bytes]: log = logging.getLogger("eden.cli.doctor.stale_mounts") stale_eden_mount_points: Set[bytes] = set() for mount_point in get_all_eden_mount_points(mount_table): try: # All eden mounts should have a .eden directory. # If the edenfs daemon serving this mount point has died we # will get ENOTCONN when trying to access it. (Simply calling # lstat() on the root directory itself can succeed even in this # case.) eden_dir = os.path.join(mount_point, b".eden") mount_table.lstat(eden_dir) except OSError as e: if e.errno == errno.ENOTCONN: stale_eden_mount_points.add(mount_point) else: log.warning(f"Unclear whether {printable_bytes(mount_point)} " f"is stale or not. lstat() failed: {e}") return sorted(stale_eden_mount_points)
def _check_bind_mount_client_path( tracker: ProblemTracker, path: str, mount_table: mtab.MountTable, fs_util: filesystem.FsUtil, ) -> None: # Identify missing or non-directory client paths try: client_stat = mount_table.lstat(path) if not stat.S_ISDIR(client_stat.st_mode): tracker.add_problem(NonDirectoryFile(path)) except OSError as ex: if ex.errno == errno.ENOENT: tracker.add_problem(MissingBindMountClientDir(path, fs_util)) else: tracker.add_problem( Problem(f"Failed to lstat bind mount source directory: {path}: {ex}") )
def _check_bind_mount_path( tracker: ProblemTracker, mount_source: str, mount_point: str, checkout_path_stat: mtab.MTStat, mount_table: mtab.MountTable, fs_util: filesystem.FsUtil, ) -> None: # Identify missing or not mounted bind mounts try: bind_mount_stat = mount_table.lstat(mount_point) if not stat.S_ISDIR(bind_mount_stat.st_mode): tracker.add_problem(NonDirectoryFile(mount_point)) return if bind_mount_stat.st_dev == checkout_path_stat.st_dev: tracker.add_problem( BindMountNotMounted( mount_source, mount_point, mkdir=False, fs_util=fs_util, mount_table=mount_table, ) ) except OSError as ex: if ex.errno == errno.ENOENT: tracker.add_problem( BindMountNotMounted( mount_source, mount_point, mkdir=True, fs_util=fs_util, mount_table=mount_table, ) ) else: tracker.add_problem(Problem(f"Failed to lstat mount path: {mount_point}"))
def check_bind_mounts( tracker: ProblemTracker, checkout: EdenCheckout, mount_table: mtab.MountTable, fs_util: filesystem.FsUtil, ) -> None: """Check that bind mounts exist and have different device IDs than the top-level checkout mount path, to confirm that they are mounted.""" mount_path = str(checkout.path) try: checkout_path_stat = mount_table.lstat(mount_path) except OSError as ex: tracker.add_problem(Problem(f"Failed to stat eden mount: {mount_path}: {ex}")) return client_bind_mount_dir = str(checkout.state_dir / "bind-mounts") bind_mounts = checkout.get_config().bind_mounts # Create a dictionary of client paths : mount paths # Client directory eg. /data/users/bob/.eden/clients/fbsource-eden/bind-mounts # Mount directory eg. /data/users/bob/fbsource/ client_mount_path_dict = {} for client_suffix, mount_suffix in bind_mounts.items(): path_in_client_dir = os.path.join(client_bind_mount_dir, client_suffix) path_in_mount_dir = os.path.join(mount_path, mount_suffix) client_mount_path_dict[path_in_client_dir] = path_in_mount_dir for path_in_client_dir, path_in_mount_dir in client_mount_path_dict.items(): _check_bind_mount_client_path(tracker, path_in_client_dir, mount_table, fs_util) _check_bind_mount_path( tracker, path_in_client_dir, path_in_mount_dir, checkout_path_stat, mount_table, fs_util, )