Sketch out libsnapshot for update_engine integration.

This is a skeleton API so we can begin implementing both libsnapshot and
the relevant changes in update_engine.

Bug: 136678799
Test: builds
Change-Id: I5dc0fc1f401e94da2b5996cd69ab4076847282a4
This commit is contained in:
David Anderson 2019-07-03 13:59:47 -07:00
parent eb599db1c5
commit 8a0f82fefa
4 changed files with 198 additions and 0 deletions

View file

@ -0,0 +1,36 @@
//
// Copyright (C) 2018 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.
//
cc_library {
name: "libsnapshot",
recovery_available: true,
defaults: ["fs_mgr_defaults"],
cppflags: [
"-D_FILE_OFFSET_BITS=64",
],
srcs: [
"snapshot.cpp",
],
shared_libs: [
"libbase",
"liblog",
],
static_libs: [
"libdm",
"libext2_uuid",
],
export_include_dirs: ["include"],
}

View file

@ -0,0 +1,2 @@
dvander@google.com
elsk@google.com

View file

@ -0,0 +1,88 @@
// Copyright (C) 2019 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 <stdint.h>
#include <chrono>
#include <memory>
#include <string>
namespace android {
namespace snapshot {
enum class UpdateStatus {
// No update or merge is in progress.
None,
// An update is pending, but has not been successfully booted yet.
Unverified,
// The kernel is merging in the background.
Merging,
// Merging is complete, and needs to be acknowledged.
MergeCompleted
};
class SnapshotManager final {
public:
// Return a new SnapshotManager instance, or null on error.
static std::unique_ptr<SnapshotManager> New();
// Create a new snapshot device with the given name, base device, and COW device
// size. The new device path will be returned in |dev_path|. If timeout_ms is
// greater than zero, this function will wait the given amount of time for
// |dev_path| to become available, and fail otherwise. If timeout_ms is 0, then
// no wait will occur and |dev_path| may not yet exist on return.
bool CreateSnapshot(const std::string& name, const std::string& base_device, uint64_t cow_size,
std::string* dev_path, const std::chrono::milliseconds& timeout_ms);
// Map a snapshot device that was previously created with CreateSnapshot.
// If a merge was previously initiated, the device-mapper table will have a
// snapshot-merge target instead of a snapshot target. The timeout parameter
// is the same as in CreateSnapshotDevice.
bool MapSnapshotDevice(const std::string& name, const std::string& base_device,
const std::chrono::milliseconds& timeout_ms, std::string* dev_path);
// Unmap a snapshot device previously mapped with MapSnapshotDevice().
bool UnmapSnapshotDevice(const std::string& name);
// Remove the backing copy-on-write image for the named snapshot. If the
// device is still mapped, this will attempt an Unmap, and fail if the
// unmap fails.
bool DeleteSnapshot(const std::string& name);
// Initiate a merge on all snapshot devices. This should only be used after an
// update has been marked successful after booting.
bool InitiateMerge();
// Wait for the current merge to finish, then perform cleanup when it
// completes. It is necessary to call this after InitiateMerge(), or when
// a merge is detected for the first time after boot.
bool WaitForMerge();
// Find the status of the current update, if any.
//
// |progress| depends on the returned status:
// None: 0
// Unverified: 0
// Merging: Value in the range [0, 100)
// MergeCompleted: 100
UpdateStatus GetUpdateStatus(double* progress);
};
} // namespace snapshot
} // namespace android

View file

@ -0,0 +1,72 @@
// Copyright (C) 2019 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 <libsnapshot/snapshot.h>
namespace android {
namespace snapshot {
std::unique_ptr<SnapshotManager> SnapshotManager::New() {
return std::make_unique<SnapshotManager>();
}
bool SnapshotManager::CreateSnapshot(const std::string& name, const std::string& base_device,
uint64_t cow_size, std::string* dev_path,
const std::chrono::milliseconds& timeout_ms) {
// (1) Create COW device using libgsi_image.
// (2) Create snapshot device using libdm + DmTargetSnapshot.
// (3) Record partition in /metadata/ota.
(void)name;
(void)base_device;
(void)cow_size;
(void)dev_path;
(void)timeout_ms;
return false;
}
bool SnapshotManager::MapSnapshotDevice(const std::string& name, const std::string& base_device,
const std::chrono::milliseconds& timeout_ms,
std::string* dev_path) {
(void)name;
(void)base_device;
(void)dev_path;
(void)timeout_ms;
return false;
}
bool SnapshotManager::UnmapSnapshotDevice(const std::string& name) {
(void)name;
return false;
}
bool SnapshotManager::DeleteSnapshot(const std::string& name) {
(void)name;
return false;
}
bool SnapshotManager::InitiateMerge() {
return false;
}
bool SnapshotManager::WaitForMerge() {
return false;
}
UpdateStatus SnapshotManager::GetUpdateStatus(double* progress) {
*progress = 0.0f;
return UpdateStatus::None;
}
} // namespace snapshot
} // namespace android