2017-07-28 03:18:19 +03:00
|
|
|
#!/usr/bin/env python3
|
2019-06-20 02:58:25 +03:00
|
|
|
# Copyright (c) Facebook, Inc. and its affiliates.
|
2017-07-28 03:18:19 +03:00
|
|
|
#
|
2019-06-20 02:58:25 +03:00
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2.
|
2017-07-28 03:18:19 +03:00
|
|
|
|
2018-11-20 05:22:41 +03:00
|
|
|
import os
|
2017-07-28 03:18:19 +03:00
|
|
|
from typing import Iterable
|
2018-05-10 07:33:49 +03:00
|
|
|
|
|
|
|
import eden.thrift
|
2018-11-20 05:22:41 +03:00
|
|
|
from facebook.eden.ttypes import TimeSpec
|
2018-05-10 07:33:49 +03:00
|
|
|
|
2018-04-24 22:51:13 +03:00
|
|
|
from . import edenclient
|
2017-07-28 03:18:19 +03:00
|
|
|
|
2018-05-10 07:33:49 +03:00
|
|
|
|
|
|
|
"""Utilities for inspecting the state of the Eden server via Thrift.
|
2017-07-28 03:18:19 +03:00
|
|
|
|
|
|
|
This utility is parameterized by a specific mount point so that it need not be
|
|
|
|
specified for each instance method.
|
2018-05-10 07:33:49 +03:00
|
|
|
"""
|
2017-07-28 03:18:19 +03:00
|
|
|
|
|
|
|
|
|
|
|
class EdenServerInspector(object):
|
2018-04-24 22:51:13 +03:00
|
|
|
def __init__(self, eden: edenclient.EdenFS, mount_point: str) -> None:
|
|
|
|
self._eden = eden
|
2017-07-28 03:18:19 +03:00
|
|
|
self._mount_point = mount_point
|
|
|
|
|
|
|
|
def create_thrift_client(self) -> eden.thrift.EdenClient:
|
2018-04-24 22:51:13 +03:00
|
|
|
return self._eden.get_thrift_client()
|
2017-07-28 03:18:19 +03:00
|
|
|
|
2018-05-10 07:33:49 +03:00
|
|
|
def unload_inode_for_path(self, path: str = "") -> None:
|
|
|
|
"""path: relative path to a directory under the mount."""
|
2017-07-28 03:18:19 +03:00
|
|
|
with self.create_thrift_client() as client:
|
2018-11-20 05:22:41 +03:00
|
|
|
client.unloadInodeForPath(
|
|
|
|
os.fsencode(self._mount_point), os.fsencode(path), age=TimeSpec(0, 0)
|
|
|
|
)
|
2017-07-28 03:18:19 +03:00
|
|
|
|
2018-05-10 07:33:49 +03:00
|
|
|
def get_inode_count(self, path: str = "") -> int:
|
|
|
|
"""path: relative path to a directory under the mount.
|
2017-07-28 03:18:19 +03:00
|
|
|
|
|
|
|
Use '' for the root. Note that this will include the inode count for
|
|
|
|
the root .hg and .eden entries.
|
2018-05-10 07:33:49 +03:00
|
|
|
"""
|
2017-07-28 03:18:19 +03:00
|
|
|
with self.create_thrift_client() as client:
|
2018-11-20 05:22:41 +03:00
|
|
|
debug_info = client.debugInodeStatus(
|
|
|
|
os.fsencode(self._mount_point), os.fsencode(path)
|
|
|
|
)
|
2017-07-28 03:18:19 +03:00
|
|
|
count = 0
|
|
|
|
for tree_inode_debug_info in debug_info:
|
2018-05-10 07:33:49 +03:00
|
|
|
count += sum(1 for entry in tree_inode_debug_info.entries if entry.loaded)
|
2017-07-28 03:18:19 +03:00
|
|
|
return count
|
|
|
|
|
2018-05-10 07:33:49 +03:00
|
|
|
def get_paths_for_inodes(self, path: str = "") -> Iterable[str]:
|
|
|
|
"""path: relative path to a directory under the mount."""
|
2017-07-28 03:18:19 +03:00
|
|
|
with self.create_thrift_client() as client:
|
2018-11-20 05:22:41 +03:00
|
|
|
debug_info = client.debugInodeStatus(
|
|
|
|
os.fsencode(self._mount_point), os.fsencode(path)
|
|
|
|
)
|
2017-07-28 03:18:19 +03:00
|
|
|
for tree_inode_debug_info in debug_info:
|
2018-05-10 07:33:49 +03:00
|
|
|
parent_dir = tree_inode_debug_info.path.decode("utf-8")
|
2017-07-28 03:18:19 +03:00
|
|
|
for entry in tree_inode_debug_info.entries:
|
|
|
|
if entry.loaded:
|
|
|
|
yield f'{parent_dir}/{entry.name.decode("utf-8")}'
|