mkdir -p snapshot_path
mkdir -p for snapshot path is using EnsureDirectoryExists().
EnsureDirectoryExists() should consider link to directory,
though.
Say, in the path "/a/b/L/d," L is a link to the directory
c. "/a/b/L" and "/a/b/c" exists while "/a/b/c/d" does not.
Then, EnsureDirectoryExists() should only create d under
"/a/b/L" or "/a/b/c."
Bug: 285436984
Test: Run locally
Change-Id: I63b89af5af3621f79bc0ef58929f4b6c7d1257c6
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index 0ac4c00..1808165 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -112,6 +112,21 @@
if (DirectoryExists(directory_path)) {
return {};
}
+ if (FileExists(directory_path)) {
+ std::string target;
+ CF_EXPECTF(android::base::Readlink(directory_path, &target),
+ "As file \"{}\" exists, it must be a link to a directory.",
+ directory_path);
+ std::string real_path;
+ CF_EXPECTF(android::base::Realpath(directory_path, &real_path),
+ "While the link \"{}\" is broken and not a directory.",
+ directory_path);
+ CF_EXPECTF(DirectoryExists(real_path),
+ "The eventual target of \"{}\" to \"{}\" must"
+ "be a directory.",
+ directory_path, real_path);
+ return {};
+ }
const auto parent_dir = cpp_dirname(directory_path);
if (parent_dir.size() > 1) {
EnsureDirectoryExists(parent_dir, mode, group_name);
diff --git a/host/commands/cvd/common_utils.cpp b/host/commands/cvd/common_utils.cpp
index 0ac1c70..c2e8b33 100644
--- a/host/commands/cvd/common_utils.cpp
+++ b/host/commands/cvd/common_utils.cpp
@@ -82,27 +82,6 @@
return request;
}
-// given /a/b/c/d/e, ensures
-// all directories from /a through /a/b/c/d/e exist
-Result<void> EnsureDirectoryExistsAllTheWay(const std::string& dir) {
- CF_EXPECT(!dir.empty() && dir.at(0) == '/',
- "EnsureDirectoryExistsAllTheWay() handles absolute paths only.");
- if (dir == "/") {
- return {};
- }
- std::string path_exclude_root = dir.substr(1);
- std::vector<std::string> tokens =
- android::base::Tokenize(path_exclude_root, "/");
- std::string current_dir = "/";
- for (int i = 0; i < tokens.size(); i++) {
- current_dir.append(tokens[i]);
- CF_EXPECT(EnsureDirectoryExists(current_dir),
- current_dir << " does not exist and cannot be created.");
- current_dir.append("/");
- }
- return {};
-}
-
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& v) {
if (v.empty()) {
diff --git a/host/commands/cvd/common_utils.h b/host/commands/cvd/common_utils.h
index 9c94604..b950e7c 100644
--- a/host/commands/cvd/common_utils.h
+++ b/host/commands/cvd/common_utils.h
@@ -77,10 +77,6 @@
return ConcatToStream(concatenator, std::forward<Args>(args)...).str();
}
-// given /a/b/c/d/e, ensures
-// all directories from /a through /a/b/c/d/e exist
-Result<void> EnsureDirectoryExistsAllTheWay(const std::string& dir);
-
constexpr android::base::LogSeverity kCvdDefaultVerbosity = android::base::INFO;
Result<android::base::LogSeverity> EncodeVerbosity(
diff --git a/host/commands/cvd/selector/creation_analyzer.cpp b/host/commands/cvd/selector/creation_analyzer.cpp
index 16c773e..88a9e0f 100644
--- a/host/commands/cvd/selector/creation_analyzer.cpp
+++ b/host/commands/cvd/selector/creation_analyzer.cpp
@@ -28,6 +28,7 @@
#include <android-base/strings.h>
#include "common/libs/utils/contains.h"
+#include "common/libs/utils/files.h"
#include "common/libs/utils/flag_parser.h"
#include "common/libs/utils/users.h"
#include "host/commands/cvd/common_utils.h"
@@ -385,7 +386,7 @@
CF_EXPECT(ParentOfAutogeneratedHomes(client_uid, client_gid));
auto_generated_home.append("/" + std::to_string(client_uid));
auto_generated_home.append("/" + group_name_);
- CF_EXPECT(EnsureDirectoryExistsAllTheWay(auto_generated_home));
+ CF_EXPECT(EnsureDirectoryExists(auto_generated_home));
return auto_generated_home;
}
diff --git a/host/commands/cvd/selector/instance_database_impl.cpp b/host/commands/cvd/selector/instance_database_impl.cpp
index af19585..f109d7f 100644
--- a/host/commands/cvd/selector/instance_database_impl.cpp
+++ b/host/commands/cvd/selector/instance_database_impl.cpp
@@ -50,7 +50,7 @@
const AddInstanceGroupParam& param) {
CF_EXPECT(IsValidGroupName(param.group_name),
"GroupName " << param.group_name << " is ill-formed.");
- CF_EXPECT(EnsureDirectoryExistsAllTheWay(param.home_dir),
+ CF_EXPECT(EnsureDirectoryExists(param.home_dir),
"HOME dir, " << param.home_dir << " does not exist");
CF_EXPECT(PotentiallyHostArtifactsPath(param.host_artifacts_path),
"ANDROID_HOST_OUT, " << param.host_artifacts_path