Snap for 4585119 from d6183ebe202de48a022f962bb5d24d2bc359f815 to pi-release
Change-Id: I70872b5e26ca805830542eb795b53e463cd8f1ff
diff --git a/Android.mk b/Android.mk
index 5a3129e..d79d89b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -141,6 +141,7 @@
payload_consumer/file_writer.cc \
payload_consumer/filesystem_verifier_action.cc \
payload_consumer/install_plan.cc \
+ payload_consumer/mount_history.cc \
payload_consumer/payload_constants.cc \
payload_consumer/payload_verifier.cc \
payload_consumer/postinstall_runner_action.cc \
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index c4db0c7..a8b8a94 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -21,6 +21,7 @@
#include <map>
#include <sstream>
#include <string>
+#include <utility>
#include <vector>
#include <base/bind.h>
@@ -235,10 +236,12 @@
system_state->prefs());
string app_versions;
- // If we are upgrading to a more stable channel and we are allowed to do
+ // If we are downgrading to a more stable channel and we are allowed to do
// powerwash, then pass 0.0.0.0 as the version. This is needed to get the
// highest-versioned payload on the destination channel.
- if (params->to_more_stable_channel() && params->is_powerwash_allowed()) {
+ bool is_potential_downgrade =
+ params->to_more_stable_channel() && params->is_powerwash_allowed();
+ if (is_potential_downgrade) {
LOG(INFO) << "Passing OS version as 0.0.0.0 as we are set to powerwash "
<< "on downgrading to the version in the more stable channel";
app_versions = "version=\"0.0.0.0\" from_version=\"" +
@@ -276,8 +279,9 @@
string fingerprint_arg;
if (!params->os_build_fingerprint().empty()) {
- fingerprint_arg =
- "fingerprint=\"" + XmlEncodeWithDefault(params->os_build_fingerprint(), "") + "\" ";
+ fingerprint_arg = "fingerprint=\"" +
+ XmlEncodeWithDefault(params->os_build_fingerprint(), "") +
+ "\" ";
}
string buildtype_arg;
@@ -287,7 +291,7 @@
}
string product_components_args;
- if (!app_data.product_components.empty()) {
+ if (!is_potential_downgrade && !app_data.product_components.empty()) {
brillo::KeyValueStore store;
if (store.LoadFromString(app_data.product_components)) {
for (const string& key : store.GetKeys()) {
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index d57abe5..87dc404 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -812,7 +812,7 @@
TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBE) {
OmahaResponse response;
- // TODO set better default value for metrics::checkresult in
+ // TODO(senj): set better default value for metrics::checkresult in
// OmahaRequestAction::ActionCompleted.
fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
ASSERT_FALSE(TestUpdateCheck(nullptr, // request_params
@@ -2184,6 +2184,7 @@
params.set_root(tempdir.GetPath().value());
params.set_app_id("{22222222-2222-2222-2222-222222222222}");
params.set_app_version("1.2.3.4");
+ params.set_product_components("o.bundle=1");
params.set_current_channel("canary-channel");
EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
params.UpdateDownloadChannel();
@@ -2205,6 +2206,7 @@
"appid=\"{22222222-2222-2222-2222-222222222222}\" "
"version=\"0.0.0.0\" from_version=\"1.2.3.4\" "
"track=\"stable-channel\" from_track=\"canary-channel\" "));
+ EXPECT_EQ(string::npos, post_str.find("o.bundle"));
}
TEST_F(OmahaRequestActionTest, TestChangingToLessStableChannel) {
@@ -2217,6 +2219,7 @@
params.set_root(tempdir.GetPath().value());
params.set_app_id("{11111111-1111-1111-1111-111111111111}");
params.set_app_version("5.6.7.8");
+ params.set_product_components("o.bundle=1");
params.set_current_channel("stable-channel");
EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
params.UpdateDownloadChannel();
@@ -2239,6 +2242,7 @@
"version=\"5.6.7.8\" "
"track=\"canary-channel\" from_track=\"stable-channel\""));
EXPECT_EQ(string::npos, post_str.find("from_version"));
+ EXPECT_NE(string::npos, post_str.find("o.bundle.version=\"1\""));
}
// Checks that the initial ping with a=-1 r=-1 is not send when the device
diff --git a/omaha_request_params.h b/omaha_request_params.h
index 6284ee1..a9215ae 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -133,6 +133,9 @@
inline std::string product_components() const {
return image_props_.product_components;
}
+ inline void set_product_components(const std::string& product_components) {
+ image_props_.product_components = product_components;
+ }
inline std::string current_channel() const {
return image_props_.current_channel;
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 45ad58b..d5ae3e6 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -50,6 +50,7 @@
#include "update_engine/payload_consumer/extent_reader.h"
#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/file_descriptor_utils.h"
+#include "update_engine/payload_consumer/mount_history.h"
#if USE_MTD
#include "update_engine/payload_consumer/mtd_file_descriptor.h"
#endif
@@ -1079,8 +1080,10 @@
// Compare |calculated_hash| with source hash in |operation|, return false and
// dump hash and set |error| if don't match.
+// |source_fd| is the file descriptor of the source partition.
bool ValidateSourceHash(const brillo::Blob& calculated_hash,
const InstallOperation& operation,
+ const FileDescriptorPtr source_fd,
ErrorCode* error) {
brillo::Blob expected_source_hash(operation.src_sha256_hash().begin(),
operation.src_sha256_hash().end());
@@ -1107,6 +1110,9 @@
LOG(ERROR) << "Operation source (offset:size) in blocks: "
<< base::JoinString(source_extents, ",");
+ // Log remount history if this device is an ext4 partition.
+ LogMountHistory(source_fd);
+
*error = ErrorCode::kDownloadStateInitializationError;
return false;
}
@@ -1131,7 +1137,8 @@
&source_hash));
if (operation.has_src_sha256_hash()) {
- TEST_AND_RETURN_FALSE(ValidateSourceHash(source_hash, operation, error));
+ TEST_AND_RETURN_FALSE(
+ ValidateSourceHash(source_hash, operation, source_fd_, error));
}
return true;
@@ -1217,8 +1224,8 @@
total_blocks -= read_blocks;
}
TEST_AND_RETURN_FALSE(source_hasher.Finalize());
- TEST_AND_RETURN_FALSE(
- ValidateSourceHash(source_hasher.raw_hash(), operation, error));
+ TEST_AND_RETURN_FALSE(ValidateSourceHash(
+ source_hasher.raw_hash(), operation, source_fd_, error));
return true;
}
diff --git a/payload_consumer/mount_history.cc b/payload_consumer/mount_history.cc
new file mode 100644
index 0000000..43a75b3
--- /dev/null
+++ b/payload_consumer/mount_history.cc
@@ -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.
+//
+
+#include "update_engine/payload_consumer/mount_history.h"
+
+#include <inttypes.h>
+
+#include <string>
+#include <vector>
+
+#include <base/logging.h>
+#include <base/time/time.h>
+
+#include "update_engine/common/utils.h"
+
+namespace chromeos_update_engine {
+void LogMountHistory(const FileDescriptorPtr blockdevice_fd) {
+ static constexpr ssize_t kBlockSize = 4096;
+
+ if (blockdevice_fd == nullptr) {
+ return;
+ }
+
+ brillo::Blob block0_buffer(kBlockSize);
+ ssize_t bytes_read;
+
+ if (!utils::PReadAll(
+ blockdevice_fd, block0_buffer.data(), kBlockSize, 0, &bytes_read)) {
+ LOG(WARNING) << "PReadAll failed";
+ return;
+ }
+
+ if (bytes_read != kBlockSize) {
+ LOG(WARNING) << "Could not read an entire block";
+ return;
+ }
+
+ // https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout
+ // Super block starts from block 0, offset 0x400
+ // 0x2C: len32 Mount time
+ // 0x30: len32 Write time
+ // 0x34: len16 Number of mounts since the last fsck
+ // 0x38: len16 Magic signature 0xEF53
+
+ time_t mount_time =
+ *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x2C]);
+ uint16_t mount_count =
+ *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x34]);
+ uint16_t magic = *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x38]);
+
+ if (magic == 0xEF53) {
+ if (mount_count > 0) {
+ LOG(WARNING) << "Device was remounted R/W " << mount_count << " times. "
+ << "Last remount happened on "
+ << base::Time::FromTimeT(mount_time) << ".";
+ }
+ }
+}
+} // namespace chromeos_update_engine
diff --git a/payload_consumer/mount_history.h b/payload_consumer/mount_history.h
new file mode 100644
index 0000000..ba0c65d
--- /dev/null
+++ b/payload_consumer/mount_history.h
@@ -0,0 +1,28 @@
+//
+// 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 UPDATE_ENGINE_PAYLOAD_CONSUMER_MOUNT_HISTORY_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_MOUNT_HISTORY_H_
+
+#include "update_engine/payload_consumer/file_descriptor.h"
+
+namespace chromeos_update_engine {
+// Try to parse an ext4 from the partition specified by |blockdevice_fd|.
+// If ext4 header exists and remount is detected, log mount count and date.
+void LogMountHistory(const FileDescriptorPtr blockdevice_fd);
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_MOUNT_HISTORY_H_
diff --git a/update_engine.gyp b/update_engine.gyp
index f312a1d..f72ca14 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -181,6 +181,7 @@
'payload_consumer/file_writer.cc',
'payload_consumer/filesystem_verifier_action.cc',
'payload_consumer/install_plan.cc',
+ 'payload_consumer/mount_history.cc',
'payload_consumer/payload_constants.cc',
'payload_consumer/payload_verifier.cc',
'payload_consumer/postinstall_runner_action.cc',