Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/cvd/cuttlefish/host/commands/assemble_cvd/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ cf_cc_library(
hdrs = ["clean.h"],
deps = [
"//cuttlefish/common/libs/utils:in_sandbox",
"//cuttlefish/common/libs/utils:proc_file_utils",
"//cuttlefish/common/libs/utils:subprocess",
"//cuttlefish/common/libs/utils:subprocess_managed_stdio",
"//cuttlefish/host/libs/config:config_utils",
Expand Down
83 changes: 64 additions & 19 deletions base/cvd/cuttlefish/host/commands/assemble_cvd/clean.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "absl/log/log.h"

#include "cuttlefish/common/libs/utils/in_sandbox.h"
#include "cuttlefish/common/libs/utils/proc_file_utils.h"
#include "cuttlefish/common/libs/utils/subprocess.h"
#include "cuttlefish/common/libs/utils/subprocess_managed_stdio.h"
#include "cuttlefish/host/libs/config/config_utils.h"
Expand Down Expand Up @@ -85,6 +86,64 @@ Result<void> CleanPriorFiles(const std::string& path,
return {};
}

Result<std::vector<pid_t>> GetPidsUsingFiles(
const std::vector<std::string>& prior_dirs,
const std::vector<std::string>& prior_files) {
std::vector<pid_t> pids_in_use;

VLOG(0) << "Checking if prior dirs or files are in use: ";
for (const auto& prior_dir : prior_dirs) {
VLOG(0) << prior_dir;
}
for (const auto& prior_file : prior_files) {
VLOG(0) << prior_file;
}
auto pids = CF_EXPECT(CollectPids(getuid()));
for (const auto pid : pids) {
std::string fd_dir_path = fmt::format("/proc/{}/fd", pid);
std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(fd_dir_path.c_str()),
closedir);
if (!dir) {
continue;
}
for (auto entity = readdir(dir.get()); entity != nullptr;
entity = readdir(dir.get())) {
std::string entity_name(entity->d_name);
if (entity_name == "." || entity_name == "..") {
continue;
}
std::string fd_path = fd_dir_path + "/" + entity_name;
std::string target;
if (!android::base::Readlink(fd_path, &target)) {
continue;
}

bool match = false;
for (const auto& prior_dir : prior_dirs) {
if (target.starts_with(prior_dir)) {
match = true;
break;
}
}
if (!match) {
for (const auto& prior_file : prior_files) {
if (target == prior_file) {
match = true;
break;
}
}
}

if (match) {
pids_in_use.push_back(pid);
break;
}
}
}

return pids_in_use;
}

Result<void> CleanPriorFiles(const std::vector<std::string>& paths,
const std::set<std::string>& preserving) {
std::vector<std::string> prior_dirs;
Expand All @@ -105,25 +164,11 @@ Result<void> CleanPriorFiles(const std::vector<std::string>& paths,

// TODO(schuffelen): Fix logic for host-sandboxing mode.
if (!InSandbox() && (!prior_dirs.empty() || !prior_files.empty())) {
Command lsof("lsof");
lsof.AddParameter("-t");
lsof.AddParameter("-Q"); // ignore failed search terms
for (const auto& prior_dir : prior_dirs) {
lsof.AddParameter("+D").AddParameter(prior_dir);
}
for (const auto& prior_file : prior_files) {
lsof.AddParameter(prior_file);
}

Result<std::string> lsof_out = RunAndCaptureStdout(std::move(lsof));
if (lsof_out.ok()) {
CF_EXPECTF(
lsof_out->empty(),
"Instance directory files in use. Try `cvd reset`? Observed PIDs: {}",
fmt::join(absl::StrSplit(*lsof_out, "\n"), ", "));
} else {
LOG(ERROR) << "Failed to run `lsof`: " << lsof_out.error();
}
auto pids = CF_EXPECT(GetPidsUsingFiles(prior_dirs, prior_files));
CF_EXPECTF(
pids.empty(),
"Instance directory files in use. Try `cvd reset`? Observed PIDs: {}",
fmt::join(pids, ", "));
}

for (const auto& path : paths) {
Expand Down
Loading