Пример #1
0
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"
    }
Пример #2
0
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)
Пример #3
0
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}")
            )
Пример #4
0
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}"))
Пример #5
0
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,
        )