From 3e68bd331ed06b12a1abd1d4421970d4f8188c97 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 22 Sep 2020 14:03:41 -0700 Subject: [PATCH] libsnapshot: Implement OnlineKernelSnapshotWriter::OpenReader. Bug: 168554689 Test: vts_libsnapshot_test Test: full OTA with update_device.py Test: incremental OTA with update_device.py Change-Id: Ic5eb99be8ab1f89070a0db231d4660e123ae3967 --- fs_mgr/libsnapshot/Android.bp | 1 + fs_mgr/libsnapshot/snapshot.cpp | 1 + fs_mgr/libsnapshot/snapshot_reader.cpp | 77 ++++++++++++++++++++++++++ fs_mgr/libsnapshot/snapshot_reader.h | 50 +++++++++++++++++ fs_mgr/libsnapshot/snapshot_writer.cpp | 10 +++- 5 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 fs_mgr/libsnapshot/snapshot_reader.cpp create mode 100644 fs_mgr/libsnapshot/snapshot_reader.h diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp index ad592e9d0..7985fcd43 100644 --- a/fs_mgr/libsnapshot/Android.bp +++ b/fs_mgr/libsnapshot/Android.bp @@ -74,6 +74,7 @@ filegroup { "android/snapshot/snapshot.proto", "device_info.cpp", "snapshot.cpp", + "snapshot_reader.cpp", "snapshot_stats.cpp", "snapshot_stub.cpp", "snapshot_metadata_updater.cpp", diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 2df2c9467..8112b5fde 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -44,6 +44,7 @@ #include "device_info.h" #include "partition_cow_creator.h" #include "snapshot_metadata_updater.h" +#include "snapshot_reader.h" #include "utility.h" namespace android { diff --git a/fs_mgr/libsnapshot/snapshot_reader.cpp b/fs_mgr/libsnapshot/snapshot_reader.cpp new file mode 100644 index 000000000..0d47468ae --- /dev/null +++ b/fs_mgr/libsnapshot/snapshot_reader.cpp @@ -0,0 +1,77 @@ +// +// Copyright (C) 2020 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 + +#include "snapshot_reader.h" + +namespace android { +namespace snapshot { + +// Not supported. +bool ReadOnlyFileDescriptor::Open(const char*, int, mode_t) { + errno = EINVAL; + return false; +} + +bool ReadOnlyFileDescriptor::Open(const char*, int) { + errno = EINVAL; + return false; +} + +ssize_t ReadOnlyFileDescriptor::Write(const void*, size_t) { + errno = EINVAL; + return false; +} + +bool ReadOnlyFileDescriptor::BlkIoctl(int, uint64_t, uint64_t, int*) { + errno = EINVAL; + return false; +} + +ReadFdFileDescriptor::ReadFdFileDescriptor(android::base::unique_fd&& fd) : fd_(std::move(fd)) {} + +ssize_t ReadFdFileDescriptor::Read(void* buf, size_t count) { + return read(fd_.get(), buf, count); +} + +off64_t ReadFdFileDescriptor::Seek(off64_t offset, int whence) { + return lseek(fd_.get(), offset, whence); +} + +uint64_t ReadFdFileDescriptor::BlockDevSize() { + return get_block_device_size(fd_.get()); +} + +bool ReadFdFileDescriptor::Close() { + fd_ = {}; + return true; +} + +bool ReadFdFileDescriptor::IsSettingErrno() { + return true; +} + +bool ReadFdFileDescriptor::IsOpen() { + return fd_ >= 0; +} + +bool ReadFdFileDescriptor::Flush() { + return true; +} + +} // namespace snapshot +} // namespace android diff --git a/fs_mgr/libsnapshot/snapshot_reader.h b/fs_mgr/libsnapshot/snapshot_reader.h new file mode 100644 index 000000000..1f2ffe211 --- /dev/null +++ b/fs_mgr/libsnapshot/snapshot_reader.h @@ -0,0 +1,50 @@ +// +// Copyright (C) 2020 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. +// + +#pragma once + +#include +#include + +namespace android { +namespace snapshot { + +class ReadOnlyFileDescriptor : public chromeos_update_engine::FileDescriptor { + public: + bool Open(const char* path, int flags, mode_t mode) override; + bool Open(const char* path, int flags) override; + ssize_t Write(const void* buf, size_t count) override; + bool BlkIoctl(int request, uint64_t start, uint64_t length, int* result) override; +}; + +class ReadFdFileDescriptor : public ReadOnlyFileDescriptor { + public: + explicit ReadFdFileDescriptor(android::base::unique_fd&& fd); + + ssize_t Read(void* buf, size_t count) override; + off64_t Seek(off64_t offset, int whence) override; + uint64_t BlockDevSize() override; + bool Close() override; + bool IsSettingErrno() override; + bool IsOpen() override; + bool Flush() override; + + private: + android::base::unique_fd fd_; +}; + +} // namespace snapshot +} // namespace android diff --git a/fs_mgr/libsnapshot/snapshot_writer.cpp b/fs_mgr/libsnapshot/snapshot_writer.cpp index 1958f188b..584f15e78 100644 --- a/fs_mgr/libsnapshot/snapshot_writer.cpp +++ b/fs_mgr/libsnapshot/snapshot_writer.cpp @@ -19,10 +19,12 @@ #include #include #include +#include "snapshot_reader.h" namespace android { namespace snapshot { +using android::base::unique_fd; using chromeos_update_engine::FileDescriptor; ISnapshotWriter::ISnapshotWriter(const CowOptions& options) : ICowWriter(options) {} @@ -83,8 +85,12 @@ bool OnlineKernelSnapshotWriter::EmitCopy(uint64_t new_block, uint64_t old_block } std::unique_ptr OnlineKernelSnapshotWriter::OpenReader() { - LOG(ERROR) << "OnlineKernelSnapshotWriter::OpenReader not yet implemented"; - return nullptr; + unique_fd fd(dup(snapshot_fd_.get())); + if (fd < 0) { + PLOG(ERROR) << "dup2 failed in OpenReader"; + return nullptr; + } + return std::make_unique(std::move(fd)); } } // namespace snapshot