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
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index ad592e9..7985fcd 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -74,6 +74,7 @@
         "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 2df2c94..8112b5f 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 0000000..0d47468
--- /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 <ext4_utils/ext4_utils.h>
+
+#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 0000000..1f2ffe2
--- /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 <android-base/file.h>
+#include <payload_consumer/file_descriptor.h>
+
+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 1958f18..584f15e 100644
--- a/fs_mgr/libsnapshot/snapshot_writer.cpp
+++ b/fs_mgr/libsnapshot/snapshot_writer.cpp
@@ -19,10 +19,12 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <payload_consumer/file_descriptor.h>
+#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 @@
 }
 
 std::unique_ptr<FileDescriptor> 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<ReadFdFileDescriptor>(std::move(fd));
 }
 
 }  // namespace snapshot