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