1 // 2 // Copyright (C) 2018 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "update_engine/payload_consumer/mount_history.h" 18 19 #include <inttypes.h> 20 21 #include <string> 22 #include <vector> 23 24 #include <base/logging.h> 25 #include <base/time/time.h> 26 27 #include "update_engine/common/utils.h" 28 29 namespace chromeos_update_engine { LogMountHistory(const FileDescriptorPtr blockdevice_fd)30void LogMountHistory(const FileDescriptorPtr blockdevice_fd) { 31 static constexpr ssize_t kBlockSize = 4096; 32 33 if (blockdevice_fd == nullptr) { 34 return; 35 } 36 37 brillo::Blob block0_buffer(kBlockSize); 38 ssize_t bytes_read; 39 40 if (!utils::PReadAll( 41 blockdevice_fd, block0_buffer.data(), kBlockSize, 0, &bytes_read)) { 42 LOG(WARNING) << "PReadAll failed"; 43 return; 44 } 45 46 if (bytes_read != kBlockSize) { 47 LOG(WARNING) << "Could not read an entire block"; 48 return; 49 } 50 51 // https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout 52 // Super block starts from block 0, offset 0x400 53 // 0x2C: len32 Mount time 54 // 0x30: len32 Write time 55 // 0x34: len16 Number of mounts since the last fsck 56 // 0x38: len16 Magic signature 0xEF53 57 58 time_t mount_time = 59 *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x2C]); 60 uint16_t mount_count = 61 *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x34]); 62 uint16_t magic = *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x38]); 63 64 if (magic == 0xEF53) { 65 if (mount_count > 0) { 66 LOG(WARNING) << "Device was remounted R/W " << mount_count << " times. " 67 << "Last remount happened on " 68 << base::Time::FromTimeT(mount_time) << "."; 69 } 70 } 71 } 72 } // namespace chromeos_update_engine 73