Merge "Add a singleton CacheLocation to replace the hard coded locations"

am: 47cd789eed

Change-Id: I11c265d3adebc338e0603ed00c7d1aaaffae0253
This commit is contained in:
Tianjie Xu
2018-03-01 18:45:52 +00:00
committed by android-build-merger
11 changed files with 139 additions and 27 deletions
+5 -6
View File
@@ -40,10 +40,9 @@
#include "edify/expr.h" #include "edify/expr.h"
#include "otafault/ota_io.h" #include "otafault/ota_io.h"
#include "otautil/cache_location.h"
#include "otautil/print_sha1.h" #include "otautil/print_sha1.h"
std::string cache_temp_source = "/cache/saved.file";
static int LoadPartitionContents(const std::string& filename, FileContents* file); static int LoadPartitionContents(const std::string& filename, FileContents* file);
static size_t FileSink(const unsigned char* data, size_t len, int fd); static size_t FileSink(const unsigned char* data, size_t len, int fd);
static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch, static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch,
@@ -404,7 +403,7 @@ int applypatch_check(const char* filename, const std::vector<std::string>& patch
// If the source file is missing or corrupted, it might be because we were killed in the middle // If the source file is missing or corrupted, it might be because we were killed in the middle
// of patching it. A copy of it should have been made in cache_temp_source. If that file // of patching it. A copy of it should have been made in cache_temp_source. If that file
// exists and matches the sha1 we're looking for, the check still passes. // exists and matches the sha1 we're looking for, the check still passes.
if (LoadFileContents(cache_temp_source.c_str(), &file) != 0) { if (LoadFileContents(CacheLocation::location().cache_temp_source().c_str(), &file) != 0) {
printf("failed to load cache file\n"); printf("failed to load cache file\n");
return 1; return 1;
} }
@@ -526,7 +525,7 @@ int applypatch(const char* source_filename, const char* target_filename,
printf("source file is bad; trying copy\n"); printf("source file is bad; trying copy\n");
FileContents copy_file; FileContents copy_file;
if (LoadFileContents(cache_temp_source.c_str(), &copy_file) < 0) { if (LoadFileContents(CacheLocation::location().cache_temp_source().c_str(), &copy_file) < 0) {
printf("failed to read copy file\n"); printf("failed to read copy file\n");
return 1; return 1;
} }
@@ -621,7 +620,7 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
printf("not enough free space on /cache\n"); printf("not enough free space on /cache\n");
return 1; return 1;
} }
if (SaveFileContents(cache_temp_source.c_str(), &source_file) < 0) { if (SaveFileContents(CacheLocation::location().cache_temp_source().c_str(), &source_file) < 0) {
printf("failed to back up source file\n"); printf("failed to back up source file\n");
return 1; return 1;
} }
@@ -667,7 +666,7 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
} }
// Delete the backup copy of the source. // Delete the backup copy of the source.
unlink(cache_temp_source.c_str()); unlink(CacheLocation::location().cache_temp_source().c_str());
// Success! // Success!
return 0; return 0;
+2 -1
View File
@@ -33,6 +33,7 @@
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include "applypatch/applypatch.h" #include "applypatch/applypatch.h"
#include "otautil/cache_location.h"
static int EliminateOpenFiles(std::set<std::string>* files) { static int EliminateOpenFiles(std::set<std::string>* files) {
std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/proc"), closedir); std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/proc"), closedir);
@@ -92,7 +93,7 @@ static std::set<std::string> FindExpendableFiles() {
// We can't delete cache_temp_source; if it's there we might have restarted during // We can't delete cache_temp_source; if it's there we might have restarted during
// installation and could be depending on it to be there. // installation and could be depending on it to be there.
if (path == cache_temp_source) { if (path == CacheLocation::location().cache_temp_source()) {
continue; continue;
} }
@@ -34,12 +34,6 @@ struct FileContents {
std::vector<unsigned char> data; std::vector<unsigned char> data;
}; };
// When there isn't enough room on the target filesystem to hold the patched version of the file,
// we copy the original here and delete it to free up space. If the expected source file doesn't
// exist, or is corrupted, we look to see if the cached file contains the bits we want and use it as
// the source instead. The default location for the cached source is "/cache/saved.file".
extern std::string cache_temp_source;
using SinkFn = std::function<size_t(const unsigned char*, size_t)>; using SinkFn = std::function<size_t(const unsigned char*, size_t)>;
// applypatch.cpp // applypatch.cpp
+1
View File
@@ -21,6 +21,7 @@ cc_library_static {
"SysUtil.cpp", "SysUtil.cpp",
"DirUtil.cpp", "DirUtil.cpp",
"ThermalUtil.cpp", "ThermalUtil.cpp",
"cache_location.cpp",
"rangeset.cpp", "rangeset.cpp",
], ],
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "otautil/cache_location.h"
constexpr const char kDefaultCacheTempSource[] = "/cache/saved.file";
constexpr const char kDefaultLastCommandFile[] = "/cache/recovery/last_command";
constexpr const char kDefaultStashDirectoryBase[] = "/cache/recovery";
CacheLocation& CacheLocation::location() {
static CacheLocation cache_location;
return cache_location;
}
void CacheLocation::ResetLocations() {
cache_temp_source_ = kDefaultCacheTempSource;
last_command_file_ = kDefaultLastCommandFile;
stash_directory_base_ = kDefaultStashDirectoryBase;
}
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _OTAUTIL_OTAUTIL_CACHE_LOCATION_H_
#define _OTAUTIL_OTAUTIL_CACHE_LOCATION_H_
#include <string>
#include "android-base/macros.h"
// A singleton class to maintain the update related locations. The locations should be only set
// once at the start of the program.
class CacheLocation {
public:
static CacheLocation& location();
// Reset the locations to their default values.
void ResetLocations();
// getter and setter functions.
std::string cache_temp_source() const {
return cache_temp_source_;
}
void set_cache_temp_source(const std::string& temp_source) {
cache_temp_source_ = temp_source;
}
std::string last_command_file() const {
return last_command_file_;
}
void set_last_command_file(const std::string& last_command) {
last_command_file_ = last_command;
}
std::string stash_directory_base() const {
return stash_directory_base_;
}
void set_stash_directory_base(const std::string& base) {
stash_directory_base_ = base;
}
private:
CacheLocation() {}
DISALLOW_COPY_AND_ASSIGN(CacheLocation);
// When there isn't enough room on the target filesystem to hold the patched version of the file,
// we copy the original here and delete it to free up space. If the expected source file doesn't
// exist, or is corrupted, we look to see if the cached file contains the bits we want and use it
// as the source instead. The default location for the cached source is "/cache/saved.file".
std::string cache_temp_source_;
// Location to save the last command that stashes blocks.
std::string last_command_file_;
// The base directory to write stashes during update.
std::string stash_directory_base_;
};
#endif // _OTAUTIL_OTAUTIL_CACHE_LOCATION_H_
+3 -2
View File
@@ -35,6 +35,7 @@
#include "applypatch/applypatch.h" #include "applypatch/applypatch.h"
#include "applypatch/applypatch_modes.h" #include "applypatch/applypatch_modes.h"
#include "common/test_constants.h" #include "common/test_constants.h"
#include "otautil/cache_location.h"
#include "otautil/print_sha1.h" #include "otautil/print_sha1.h"
static void sha1sum(const std::string& fname, std::string* sha1, size_t* fsize = nullptr) { static void sha1sum(const std::string& fname, std::string* sha1, size_t* fsize = nullptr) {
@@ -93,14 +94,14 @@ class ApplyPatchCacheTest : public ApplyPatchTest {
protected: protected:
void SetUp() override { void SetUp() override {
ApplyPatchTest::SetUp(); ApplyPatchTest::SetUp();
cache_temp_source = old_file; CacheLocation::location().set_cache_temp_source(old_file);
} }
}; };
class ApplyPatchModesTest : public ::testing::Test { class ApplyPatchModesTest : public ::testing::Test {
protected: protected:
void SetUp() override { void SetUp() override {
cache_temp_source = cache_source.path; CacheLocation::location().set_cache_temp_source(cache_source.path);
} }
TemporaryFile cache_source; TemporaryFile cache_source;
+14 -7
View File
@@ -41,6 +41,7 @@
#include "common/test_constants.h" #include "common/test_constants.h"
#include "edify/expr.h" #include "edify/expr.h"
#include "otautil/SysUtil.h" #include "otautil/SysUtil.h"
#include "otautil/cache_location.h"
#include "otautil/error_code.h" #include "otautil/error_code.h"
#include "otautil/print_sha1.h" #include "otautil/print_sha1.h"
#include "updater/blockimg.h" #include "updater/blockimg.h"
@@ -104,7 +105,16 @@ class UpdaterTest : public ::testing::Test {
RegisterBuiltins(); RegisterBuiltins();
RegisterInstallFunctions(); RegisterInstallFunctions();
RegisterBlockImageFunctions(); RegisterBlockImageFunctions();
// Mock the location of last_command_file.
CacheLocation::location().set_cache_temp_source(temp_saved_source_.path);
CacheLocation::location().set_last_command_file(temp_last_command_.path);
CacheLocation::location().set_stash_directory_base(temp_stash_base_.path);
} }
TemporaryFile temp_saved_source_;
TemporaryFile temp_last_command_;
TemporaryDir temp_stash_base_;
}; };
TEST_F(UpdaterTest, getprop) { TEST_F(UpdaterTest, getprop) {
@@ -542,7 +552,7 @@ TEST_F(UpdaterTest, block_image_update_fail) {
expect("", script.c_str(), kNoCause, &updater_info); expect("", script.c_str(), kNoCause, &updater_info);
// Updater generates the stash name based on the input file name. // Updater generates the stash name based on the input file name.
std::string name_digest = get_sha1(update_file.path); std::string name_digest = get_sha1(update_file.path);
std::string stash_base = "/cache/recovery/" + name_digest; std::string stash_base = std::string(temp_stash_base_.path) + "/" + name_digest;
ASSERT_EQ(0, access(stash_base.c_str(), F_OK)); ASSERT_EQ(0, access(stash_base.c_str(), F_OK));
ASSERT_EQ(-1, access((stash_base + src_hash).c_str(), F_OK)); ASSERT_EQ(-1, access((stash_base + src_hash).c_str(), F_OK));
ASSERT_EQ(0, rmdir(stash_base.c_str())); ASSERT_EQ(0, rmdir(stash_base.c_str()));
@@ -709,8 +719,7 @@ TEST_F(UpdaterTest, brotli_new_data) {
} }
TEST_F(UpdaterTest, last_command_update) { TEST_F(UpdaterTest, last_command_update) {
TemporaryFile temp_file; std::string last_command_file = CacheLocation::location().last_command_file();
last_command_file = temp_file.path;
std::string block1 = std::string(4096, '1'); std::string block1 = std::string(4096, '1');
std::string block2 = std::string(4096, '2'); std::string block2 = std::string(4096, '2');
@@ -797,8 +806,7 @@ TEST_F(UpdaterTest, last_command_update) {
} }
TEST_F(UpdaterTest, last_command_update_unresumable) { TEST_F(UpdaterTest, last_command_update_unresumable) {
TemporaryFile temp_file; std::string last_command_file = CacheLocation::location().last_command_file();
last_command_file = temp_file.path;
std::string block1 = std::string(4096, '1'); std::string block1 = std::string(4096, '1');
std::string block2 = std::string(4096, '2'); std::string block2 = std::string(4096, '2');
@@ -853,8 +861,7 @@ TEST_F(UpdaterTest, last_command_update_unresumable) {
} }
TEST_F(UpdaterTest, last_command_verify) { TEST_F(UpdaterTest, last_command_verify) {
TemporaryFile temp_file; std::string last_command_file = CacheLocation::location().last_command_file();
last_command_file = temp_file.path;
std::string block1 = std::string(4096, '1'); std::string block1 = std::string(4096, '1');
std::string block2 = std::string(4096, '2'); std::string block2 = std::string(4096, '2');
+5 -4
View File
@@ -53,6 +53,7 @@
#include "edify/expr.h" #include "edify/expr.h"
#include "otafault/ota_io.h" #include "otafault/ota_io.h"
#include "otautil/cache_location.h"
#include "otautil/error_code.h" #include "otautil/error_code.h"
#include "otautil/print_sha1.h" #include "otautil/print_sha1.h"
#include "otautil/rangeset.h" #include "otautil/rangeset.h"
@@ -65,17 +66,15 @@
#define DEBUG_ERASE 0 #define DEBUG_ERASE 0
static constexpr size_t BLOCKSIZE = 4096; static constexpr size_t BLOCKSIZE = 4096;
static constexpr const char* STASH_DIRECTORY_BASE = "/cache/recovery";
static constexpr mode_t STASH_DIRECTORY_MODE = 0700; static constexpr mode_t STASH_DIRECTORY_MODE = 0700;
static constexpr mode_t STASH_FILE_MODE = 0600; static constexpr mode_t STASH_FILE_MODE = 0600;
std::string last_command_file = "/cache/recovery/last_command";
static CauseCode failure_type = kNoCause; static CauseCode failure_type = kNoCause;
static bool is_retry = false; static bool is_retry = false;
static std::unordered_map<std::string, RangeSet> stash_map; static std::unordered_map<std::string, RangeSet> stash_map;
static void DeleteLastCommandFile() { static void DeleteLastCommandFile() {
std::string last_command_file = CacheLocation::location().last_command_file();
if (unlink(last_command_file.c_str()) == -1 && errno != ENOENT) { if (unlink(last_command_file.c_str()) == -1 && errno != ENOENT) {
PLOG(ERROR) << "Failed to unlink: " << last_command_file; PLOG(ERROR) << "Failed to unlink: " << last_command_file;
} }
@@ -84,6 +83,7 @@ static void DeleteLastCommandFile() {
// Parse the last command index of the last update and save the result to |last_command_index|. // Parse the last command index of the last update and save the result to |last_command_index|.
// Return true if we successfully read the index. // Return true if we successfully read the index.
static bool ParseLastCommandFile(int* last_command_index) { static bool ParseLastCommandFile(int* last_command_index) {
std::string last_command_file = CacheLocation::location().last_command_file();
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(last_command_file.c_str(), O_RDONLY))); android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(last_command_file.c_str(), O_RDONLY)));
if (fd == -1) { if (fd == -1) {
if (errno != ENOENT) { if (errno != ENOENT) {
@@ -119,6 +119,7 @@ static bool ParseLastCommandFile(int* last_command_index) {
// Update the last command index in the last_command_file if the current command writes to the // Update the last command index in the last_command_file if the current command writes to the
// stash either explicitly or implicitly. // stash either explicitly or implicitly.
static bool UpdateLastCommandIndex(int command_index, const std::string& command_string) { static bool UpdateLastCommandIndex(int command_index, const std::string& command_string) {
std::string last_command_file = CacheLocation::location().last_command_file();
std::string last_command_tmp = last_command_file + ".tmp"; std::string last_command_tmp = last_command_file + ".tmp";
std::string content = std::to_string(command_index) + "\n" + command_string; std::string content = std::to_string(command_index) + "\n" + command_string;
android::base::unique_fd wfd( android::base::unique_fd wfd(
@@ -676,7 +677,7 @@ static std::string GetStashFileName(const std::string& base, const std::string&
return ""; return "";
} }
std::string fn(STASH_DIRECTORY_BASE); std::string fn(CacheLocation::location().stash_directory_base());
fn += "/" + base + "/" + id + postfix; fn += "/" + base + "/" + id + postfix;
return fn; return fn;
-1
View File
@@ -19,7 +19,6 @@
#include <string> #include <string>
extern std::string last_command_file;
void RegisterBlockImageFunctions(); void RegisterBlockImageFunctions();
#endif #endif
+5
View File
@@ -34,6 +34,7 @@
#include "otafault/config.h" #include "otafault/config.h"
#include "otautil/DirUtil.h" #include "otautil/DirUtil.h"
#include "otautil/SysUtil.h" #include "otautil/SysUtil.h"
#include "otautil/cache_location.h"
#include "otautil/error_code.h" #include "otautil/error_code.h"
#include "updater/blockimg.h" #include "updater/blockimg.h"
#include "updater/install.h" #include "updater/install.h"
@@ -168,6 +169,10 @@ int main(int argc, char** argv) {
} }
ota_io_init(za, state.is_retry); ota_io_init(za, state.is_retry);
// Initialize the cache_temp_source, last_command_file and stash_directory_base to their default
// locations.
CacheLocation::location().ResetLocations();
std::string result; std::string result;
bool status = Evaluate(&state, root, &result); bool status = Evaluate(&state, root, &result);