Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d66a600 authored by David Anderson's avatar David Anderson Committed by Gerrit Code Review
Browse files

Merge "libsnapshot: Add a source_partition parameter to OpenSnapshotWriter."

parents bc7a365b 3feb3237
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,9 @@ class MockSnapshotManager : public ISnapshotManager {
                 std::string* snapshot_path),
                 std::string* snapshot_path),
                (override));
                (override));
    MOCK_METHOD(std::unique_ptr<ISnapshotWriter>, OpenSnapshotWriter,
    MOCK_METHOD(std::unique_ptr<ISnapshotWriter>, OpenSnapshotWriter,
                (const android::fs_mgr::CreateLogicalPartitionParams& params), (override));
                (const android::fs_mgr::CreateLogicalPartitionParams& params,
                 const std::optional<std::string>&),
                (override));
    MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override));
    MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override));
    MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override));
    MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override));
    MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions,
    MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions,
+15 −11
Original line number Original line Diff line number Diff line
@@ -182,9 +182,12 @@ class ISnapshotManager {
                                   std::string* snapshot_path) = 0;
                                   std::string* snapshot_path) = 0;


    // Create an ISnapshotWriter to build a snapshot against a target partition. The partition name
    // Create an ISnapshotWriter to build a snapshot against a target partition. The partition name
    // must be suffixed.
    // must be suffixed. If a source partition exists, it must be specified as well. The source
    // partition will only be used if raw bytes are needed. The source partition should be an
    // absolute path to the device, not a partition name.
    virtual std::unique_ptr<ISnapshotWriter> OpenSnapshotWriter(
    virtual std::unique_ptr<ISnapshotWriter> OpenSnapshotWriter(
            const android::fs_mgr::CreateLogicalPartitionParams& params) = 0;
            const android::fs_mgr::CreateLogicalPartitionParams& params,
            const std::optional<std::string>& source_device) = 0;


    // Unmap a snapshot device or CowWriter that was previously opened with MapUpdateSnapshot,
    // Unmap a snapshot device or CowWriter that was previously opened with MapUpdateSnapshot,
    // OpenSnapshotWriter. All outstanding open descriptors, writers, or
    // OpenSnapshotWriter. All outstanding open descriptors, writers, or
@@ -300,7 +303,8 @@ class SnapshotManager final : public ISnapshotManager {
    bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
    bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
                           std::string* snapshot_path) override;
                           std::string* snapshot_path) override;
    std::unique_ptr<ISnapshotWriter> OpenSnapshotWriter(
    std::unique_ptr<ISnapshotWriter> OpenSnapshotWriter(
            const android::fs_mgr::CreateLogicalPartitionParams& params) override;
            const android::fs_mgr::CreateLogicalPartitionParams& params,
            const std::optional<std::string>& source_device) override;
    bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
    bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
    bool NeedSnapshotsInFirstStageMount() override;
    bool NeedSnapshotsInFirstStageMount() override;
    bool CreateLogicalAndSnapshotPartitions(
    bool CreateLogicalAndSnapshotPartitions(
@@ -540,13 +544,13 @@ class SnapshotManager final : public ISnapshotManager {
    };
    };


    // Helpers for OpenSnapshotWriter.
    // Helpers for OpenSnapshotWriter.
    std::unique_ptr<ISnapshotWriter> OpenCompressedSnapshotWriter(LockedFile* lock,
    std::unique_ptr<ISnapshotWriter> OpenCompressedSnapshotWriter(
                                                                  const std::string& partition_name,
            LockedFile* lock, const std::optional<std::string>& source_device,
                                                                  const SnapshotStatus& status,
            const std::string& partition_name, const SnapshotStatus& status,
            const SnapshotPaths& paths);
            const SnapshotPaths& paths);
    std::unique_ptr<ISnapshotWriter> OpenKernelSnapshotWriter(LockedFile* lock,
    std::unique_ptr<ISnapshotWriter> OpenKernelSnapshotWriter(
                                                              const std::string& partition_name,
            LockedFile* lock, const std::optional<std::string>& source_device,
                                                              const SnapshotStatus& status,
            const std::string& partition_name, const SnapshotStatus& status,
            const SnapshotPaths& paths);
            const SnapshotPaths& paths);


    // Map the base device, COW devices, and snapshot device.
    // Map the base device, COW devices, and snapshot device.
+2 −1
Original line number Original line Diff line number Diff line
@@ -37,7 +37,8 @@ class SnapshotManagerStub : public ISnapshotManager {
    bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
    bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
                           std::string* snapshot_path) override;
                           std::string* snapshot_path) override;
    std::unique_ptr<ISnapshotWriter> OpenSnapshotWriter(
    std::unique_ptr<ISnapshotWriter> OpenSnapshotWriter(
            const android::fs_mgr::CreateLogicalPartitionParams& params) override;
            const android::fs_mgr::CreateLogicalPartitionParams& params,
            const std::optional<std::string>& source_device) override;
    bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
    bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
    bool NeedSnapshotsInFirstStageMount() override;
    bool NeedSnapshotsInFirstStageMount() override;
    bool CreateLogicalAndSnapshotPartitions(
    bool CreateLogicalAndSnapshotPartitions(
+7 −2
Original line number Original line Diff line number Diff line
@@ -33,13 +33,18 @@ class ISnapshotWriter : public ICowWriter {


    // Set the source device. This is used for AddCopy() operations, if the
    // Set the source device. This is used for AddCopy() operations, if the
    // underlying writer needs the original bytes (for example if backed by
    // underlying writer needs the original bytes (for example if backed by
    // dm-snapshot or if writing directly to an unsnapshotted region).
    // dm-snapshot or if writing directly to an unsnapshotted region). The
    void SetSourceDevice(android::base::unique_fd&& source_fd);
    // device is only opened on the first operation that requires it.
    void SetSourceDevice(const std::string& source_device);


    virtual std::unique_ptr<FileDescriptor> OpenReader() = 0;
    virtual std::unique_ptr<FileDescriptor> OpenReader() = 0;


  protected:
  protected:
    android::base::borrowed_fd GetSourceFd();

  private:
    android::base::unique_fd source_fd_;
    android::base::unique_fd source_fd_;
    std::optional<std::string> source_device_;
};
};


// Send writes to a COW or a raw device directly, based on a threshold.
// Send writes to a COW or a raw device directly, based on a threshold.
+19 −13
Original line number Original line Diff line number Diff line
@@ -2471,9 +2471,11 @@ bool SnapshotManager::MapUpdateSnapshot(const CreateLogicalPartitionParams& para
}
}


std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenSnapshotWriter(
std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenSnapshotWriter(
        const android::fs_mgr::CreateLogicalPartitionParams& params) {
        const android::fs_mgr::CreateLogicalPartitionParams& params,
        const std::optional<std::string>& source_device) {
#if defined(LIBSNAPSHOT_NO_COW_WRITE)
#if defined(LIBSNAPSHOT_NO_COW_WRITE)
    (void)params;
    (void)params;
    (void)source_device;


    LOG(ERROR) << "Snapshots cannot be written in first-stage init or recovery";
    LOG(ERROR) << "Snapshots cannot be written in first-stage init or recovery";
    return nullptr;
    return nullptr;
@@ -2508,16 +2510,19 @@ std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenSnapshotWriter(
    }
    }


    if (IsCompressionEnabled()) {
    if (IsCompressionEnabled()) {
        return OpenCompressedSnapshotWriter(lock.get(), params.GetPartitionName(), status, paths);
        return OpenCompressedSnapshotWriter(lock.get(), source_device, params.GetPartitionName(),
                                            status, paths);
    }
    }
    return OpenKernelSnapshotWriter(lock.get(), params.GetPartitionName(), status, paths);
    return OpenKernelSnapshotWriter(lock.get(), source_device, params.GetPartitionName(), status,
                                    paths);
#endif
#endif
}
}


#if !defined(LIBSNAPSHOT_NO_COW_WRITE)
#if !defined(LIBSNAPSHOT_NO_COW_WRITE)
std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenCompressedSnapshotWriter(
std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenCompressedSnapshotWriter(
        LockedFile* lock, [[maybe_unused]] const std::string& partition_name,
        LockedFile* lock, const std::optional<std::string>& source_device,
        const SnapshotStatus& status, const SnapshotPaths& paths) {
        [[maybe_unused]] const std::string& partition_name, const SnapshotStatus& status,
        const SnapshotPaths& paths) {
    CHECK(lock);
    CHECK(lock);


    CowOptions cow_options;
    CowOptions cow_options;
@@ -2529,13 +2534,9 @@ std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenCompressedSnapshotWriter(
    CHECK(status.snapshot_size() == status.device_size());
    CHECK(status.snapshot_size() == status.device_size());


    auto writer = std::make_unique<CompressedSnapshotWriter>(cow_options);
    auto writer = std::make_unique<CompressedSnapshotWriter>(cow_options);

    if (source_device) {
    unique_fd base_fd(open(paths.target_device.c_str(), O_RDWR | O_CLOEXEC));
        writer->SetSourceDevice(*source_device);
    if (base_fd < 0) {
        PLOG(ERROR) << "OpenCompressedSnapshotWriter: open " << paths.target_device;
        return nullptr;
    }
    }
    writer->SetSourceDevice(std::move(base_fd));


    std::string cow_path;
    std::string cow_path;
    if (!GetMappedImageDevicePath(paths.cow_device_name, &cow_path)) {
    if (!GetMappedImageDevicePath(paths.cow_device_name, &cow_path)) {
@@ -2557,8 +2558,9 @@ std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenCompressedSnapshotWriter(
}
}


std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenKernelSnapshotWriter(
std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenKernelSnapshotWriter(
        LockedFile* lock, [[maybe_unused]] const std::string& partition_name,
        LockedFile* lock, const std::optional<std::string>& source_device,
        const SnapshotStatus& status, const SnapshotPaths& paths) {
        [[maybe_unused]] const std::string& partition_name, const SnapshotStatus& status,
        const SnapshotPaths& paths) {
    CHECK(lock);
    CHECK(lock);


    CowOptions cow_options;
    CowOptions cow_options;
@@ -2573,6 +2575,10 @@ std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenKernelSnapshotWriter(
        return nullptr;
        return nullptr;
    }
    }


    if (source_device) {
        writer->SetSourceDevice(*source_device);
    }

    uint64_t cow_size = status.cow_partition_size() + status.cow_file_size();
    uint64_t cow_size = status.cow_partition_size() + status.cow_file_size();
    writer->SetSnapshotDevice(std::move(fd), cow_size);
    writer->SetSnapshotDevice(std::move(fd), cow_size);


Loading