Setup a temporary directory for update_engine_sideload.
When running update_engine_sideload from recovery, the default temp
directory (/data/misc/update_engine/tmp) is not available. This
directory is currently used to store a blob when applying a bspatch
from a child process. This patch uses /tmp/update_engine_sideload as
a temporary directory when running update_engine_sideload from recovery.
Bug: 27178350
TEST=`adb sideload` an incremental update.
(cherry picked from commit 3295102ed64107f966d4cf8bfe733bb936646630)
Change-Id: Icef9dd48b00991975bcf6c39a148f952ef43d9e3
diff --git a/common/utils.cc b/common/utils.cc
index 19c63c0..166cfb4 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -87,6 +87,11 @@
// The path to the kernel's boot_id.
const char kBootIdPath[] = "/proc/sys/kernel/random/boot_id";
+// A pointer to a null-terminated string containing the root directory where all
+// the temporary files should be created. If null, the system default is used
+// instead.
+const char* root_temp_dir = nullptr;
+
// Return true if |disk_name| is an MTD or a UBI device. Note that this test is
// simply based on the name of the device.
bool IsMtdDeviceName(const string& disk_name) {
@@ -143,13 +148,17 @@
}
base::FilePath temp_dir;
+ if (root_temp_dir) {
+ temp_dir = base::FilePath(root_temp_dir);
+ } else {
#ifdef __ANDROID__
- temp_dir = base::FilePath(constants::kNonVolatileDirectory).Append("tmp");
+ temp_dir = base::FilePath(constants::kNonVolatileDirectory).Append("tmp");
+#else
+ TEST_AND_RETURN_FALSE(base::GetTempDir(&temp_dir));
+#endif // __ANDROID__
+ }
if (!base::PathExists(temp_dir))
TEST_AND_RETURN_FALSE(base::CreateDirectory(temp_dir));
-#else
- TEST_AND_RETURN_FALSE(base::GetTempDir(&temp_dir));
-#endif // __ANDROID__
*template_path = temp_dir.Append(path);
return true;
}
@@ -158,6 +167,10 @@
namespace utils {
+void SetRootTempDir(const char* new_root_temp_dir) {
+ root_temp_dir = new_root_temp_dir;
+}
+
string ParseECVersion(string input_line) {
base::TrimWhitespaceASCII(input_line, base::TRIM_ALL, &input_line);
diff --git a/common/utils.h b/common/utils.h
index 63328b6..24bf702 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -131,6 +131,13 @@
// only returns true if "/dev/ubi%d_0" becomes available in |timeout| seconds.
bool TryAttachingUbiVolume(int volume_num, int timeout);
+// Setup the directory |new_root_temp_dir| to be used as the root directory for
+// temporary files instead of the system's default. If the directory doesn't
+// exists, it will be created when first used.
+// NOTE: The memory pointed by |new_root_temp_dir| must be available until this
+// function is called again with a different value.
+void SetRootTempDir(const char* new_root_temp_dir);
+
// If |base_filename_template| is neither absolute (starts with "/") nor
// explicitly relative to the current working directory (starts with "./" or
// "../"), then it is prepended the system's temporary directory. On success,
diff --git a/sideload_main.cc b/sideload_main.cc
index 43d0f93..35ed11b 100644
--- a/sideload_main.cc
+++ b/sideload_main.cc
@@ -43,6 +43,11 @@
using std::vector;
using update_engine::UpdateStatus;
+namespace {
+// The root directory used for temporary files in update_engine_sideload.
+const char kSideloadRootTempDir[] = "/tmp/update_engine_sideload";
+} // namespace
+
namespace chromeos_update_engine {
namespace {
@@ -207,6 +212,10 @@
// xz-embedded requires to initialize its CRC-32 table once on startup.
xz_crc32_init();
+ // When called from recovery, /data is not accessible, so we need to use
+ // /tmp for temporary files.
+ chromeos_update_engine::utils::SetRootTempDir(kSideloadRootTempDir);
+
vector<string> headers = base::SplitString(
FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);