Merge "Run lstat on correct path. Do not follow symlinks."
diff --git a/src/traced/probes/filesystem/inode_file_data_source.cc b/src/traced/probes/filesystem/inode_file_data_source.cc
index abc1fa0..6c324f2 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.cc
+++ b/src/traced/probes/filesystem/inode_file_data_source.cc
@@ -40,21 +40,27 @@
std::vector<std::string> queue{root_directory};
while (!queue.empty()) {
struct dirent* entry;
- std::string filepath = queue.back();
+ std::string directory = queue.back();
queue.pop_back();
- DIR* dir = opendir(filepath.c_str());
- filepath += "/";
+ DIR* dir = opendir(directory.c_str());
+ directory += "/";
if (dir == nullptr)
continue;
while ((entry = readdir(dir)) != nullptr) {
std::string filename = entry->d_name;
if (filename == "." || filename == "..")
continue;
+ std::string filepath = directory + filename;
struct stat buf;
if (lstat(filepath.c_str(), &buf) != 0)
continue;
+ // This might happen on filesystems that do not return
+ // information in entry->d_type.
+ if (S_ISLNK(buf.st_mode))
+ continue;
+
Inode inode_number = entry->d_ino;
BlockDeviceID block_device_id = buf.st_dev;
@@ -63,13 +69,13 @@
// Readdir and stat not guaranteed to have directory info for all systems
if (entry->d_type == DT_DIR || S_ISDIR(buf.st_mode)) {
// Continue iterating through files if current entry is a directory
- queue.push_back(filepath + filename);
+ queue.push_back(filepath);
type = protos::pbzero::InodeFileMap_Entry_Type_DIRECTORY;
} else if (entry->d_type == DT_REG || S_ISREG(buf.st_mode)) {
type = protos::pbzero::InodeFileMap_Entry_Type_FILE;
}
- fn(block_device_id, inode_number, filepath + filename, type);
+ fn(block_device_id, inode_number, filepath, type);
}
closedir(dir);
}