Skip to content

Commit

Permalink
Refactor namespace inode resolution
Browse files Browse the repository at this point in the history
- Allow resolution of a single namespace inode.
- Use stat for resolution (instead of readlinkat) to avoid string
  parsing and optimize access.
  • Loading branch information
dtrugman committed May 31, 2021
1 parent dc1b1c9 commit 458db6c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 9 deletions.
2 changes: 2 additions & 0 deletions include/pfs/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class task final

net get_net() const;

ino_t get_ns(const std::string& ns) const;

std::unordered_map<std::string, ino_t> get_ns() const;

std::string get_root() const;
Expand Down
5 changes: 5 additions & 0 deletions include/pfs/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ std::set<std::string> enumerate_files(const std::string& dir,
// etc.
std::set<int> enumerate_numeric_files(const std::string& dir);

// Get the inode number of the file.
// If the linkname is relative, then it is interpreted relative to the directory
// referred to by the file descriptor dirfd.
ino_t get_inode(const std::string& path, int dirfd = AT_FDCWD);

// Return the path to which the specified link points.
// If the linkname is relative, then it is interpreted relative to the directory
// referred to by the file descriptor dirfd.
Expand Down
18 changes: 9 additions & 9 deletions src/task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,14 @@ net task::get_net() const
return net(_procfs_root);
}

ino_t task::get_ns(const std::string& ns) const
{
static const std::string NS_DIR("ns/");
auto path = _task_root + NS_DIR + ns;

return utils::get_inode(path);
}

std::unordered_map<std::string, ino_t> task::get_ns() const
{
static const std::string NS_DIR("ns/");
Expand All @@ -388,15 +396,7 @@ std::unordered_map<std::string, ino_t> task::get_ns() const
for (const auto& file :
utils::enumerate_files(path, /* include_dots */ false))
{
std::string link = utils::readlink(file, dirfd);

ino_t inode;
if (std::sscanf(link.c_str(), "%*[^:]:[%" PRIuMAX "]", &inode) != 1)
{
throw parser_error("Couldn't parse ns link", link);
}

ns.emplace(file, inode);
ns.emplace(file, utils::get_inode(file, dirfd));
}

return ns;
Expand Down
13 changes: 13 additions & 0 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ std::set<int> enumerate_numeric_files(const std::string& dir)
return files;
}

ino_t get_inode(const std::string& path, int dirfd)
{
struct stat st;
int err = fstatat(dirfd, path.c_str(), &st, 0);
if (err)
{
throw std::system_error(errno, std::system_category(),
"Couldn't stat file for inode");
}

return st.st_ino;
}

std::string readlink(const std::string& link, int dirfd)
{
std::string buffer;
Expand Down

0 comments on commit 458db6c

Please sign in to comment.