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 { 30 void 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::ReadAll( 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 // 0x40: len32 Time of last check 58 // 0x108: len32 When the filesystem was created 59 60 time_t mount_time = 61 *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x2C]); 62 time_t write_time = 63 *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x30]); 64 uint16_t mount_count = 65 *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x34]); 66 uint16_t magic = *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x38]); 67 time_t check_time = 68 *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x40]); 69 time_t created_time = 70 *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x108]); 71 72 if (magic == 0xEF53) { 73 // Timestamps can be updated by fsck without updating mount count, 74 // log if any timestamp differ 75 if (! (write_time == created_time && check_time == created_time)) { 76 LOG(WARNING) << "Device have been modified after being created. " 77 << "Filesystem created on " 78 << base::Time::FromTimeT(created_time) << ", " 79 << "last written on " 80 << base::Time::FromTimeT(write_time) << ", " 81 << "last checked on " 82 << base::Time::FromTimeT(check_time) << "."; 83 } 84 if (mount_count > 0) { 85 LOG(WARNING) << "Device was remounted R/W " << mount_count << " times. " 86 << "Last remount happened on " 87 << base::Time::FromTimeT(mount_time) << "."; 88 } 89 } 90 } 91 } // namespace chromeos_update_engine 92