libdm: Add DmTargetTypeInfo and a unit test.
This change refactors DmTarget. It was satisfying two separate use cases that have no overlap: (1) as a container for informational queries, and (2) for specifying table targets. The kernel's nomenclature for the former is a "target type," so the new class is named DmTargetTypeInfo. In addition, this change adds a unit test for DeviceMapper::GetAvailableTargets that ensures the device has at least a linear target type (with more TBD). Bug: 110035986 Test: libdm_test gtest Change-Id: Icb87976801e8a1e6ec79e48b1d58c308d36279e5
This commit is contained in:
parent
d41a1f9add
commit
c7def6849a
6 changed files with 83 additions and 27 deletions
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
cc_library_static {
|
||||
name: "libdm",
|
||||
defaults: ["fs_mgr_defaults"],
|
||||
recovery_available: true,
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
|
@ -35,3 +36,16 @@ cc_library_static {
|
|||
"liblog_headers",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "libdm_test",
|
||||
defaults: ["fs_mgr_defaults"],
|
||||
static_libs: [
|
||||
"libdm",
|
||||
"libbase",
|
||||
"liblog",
|
||||
],
|
||||
srcs: [
|
||||
"dm_test.cpp",
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ bool DeviceMapper::LoadTableAndActivate(const std::string& name, const DmTable&
|
|||
|
||||
// Reads all the available device mapper targets and their corresponding
|
||||
// versions from the kernel and returns in a vector
|
||||
bool DeviceMapper::GetAvailableTargets(std::vector<DmTarget>* targets) {
|
||||
bool DeviceMapper::GetAvailableTargets(std::vector<DmTargetTypeInfo>* targets) {
|
||||
targets->clear();
|
||||
|
||||
// calculate the space needed to read a maximum of kMaxPossibleDmTargets
|
||||
|
|
@ -178,7 +178,7 @@ bool DeviceMapper::GetAvailableTargets(std::vector<DmTarget>* targets) {
|
|||
struct dm_target_versions* vers =
|
||||
reinterpret_cast<struct dm_target_versions*>(static_cast<char*>(buffer.get()) + next);
|
||||
while (next && data_size) {
|
||||
targets->emplace_back((vers));
|
||||
targets->emplace_back(vers);
|
||||
if (vers->next == 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
37
fs_mgr/libdm/dm_test.cpp
Normal file
37
fs_mgr/libdm/dm_test.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libdm/dm.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace android::dm;
|
||||
|
||||
TEST(libdm, HasMinimumTargets) {
|
||||
DeviceMapper& dm = DeviceMapper::Instance();
|
||||
vector<DmTargetTypeInfo> targets;
|
||||
ASSERT_TRUE(dm.GetAvailableTargets(&targets));
|
||||
|
||||
map<string, DmTargetTypeInfo> by_name;
|
||||
for (const auto& target : targets) {
|
||||
by_name[target.name()] = target;
|
||||
}
|
||||
|
||||
auto iter = by_name.find("linear");
|
||||
EXPECT_NE(iter, by_name.end());
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ class DeviceMapper final {
|
|||
|
||||
// Returns true if a list of available device mapper targets registered in the kernel was
|
||||
// successfully read and stored in 'targets'. Returns 'false' otherwise.
|
||||
bool GetAvailableTargets(std::vector<DmTarget>* targets);
|
||||
bool GetAvailableTargets(std::vector<DmTargetTypeInfo>* targets);
|
||||
|
||||
// Return 'true' if it can successfully read the list of device mapper block devices
|
||||
// currently created. 'devices' will be empty if the kernel interactions
|
||||
|
|
|
|||
|
|
@ -27,45 +27,49 @@
|
|||
namespace android {
|
||||
namespace dm {
|
||||
|
||||
class DmTargetTypeInfo {
|
||||
public:
|
||||
DmTargetTypeInfo() : major_(0), minor_(0), patch_(0) {}
|
||||
DmTargetTypeInfo(const struct dm_target_versions* info)
|
||||
: name_(info->name),
|
||||
major_(info->version[0]),
|
||||
minor_(info->version[1]),
|
||||
patch_(info->version[2]) {}
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
std::string version() const {
|
||||
return std::to_string(major_) + "." + std::to_string(minor_) + "." + std::to_string(patch_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
uint32_t major_;
|
||||
uint32_t minor_;
|
||||
uint32_t patch_;
|
||||
};
|
||||
|
||||
class DmTarget {
|
||||
public:
|
||||
DmTarget(const std::string& name, uint64_t start = 0, uint64_t length = 0)
|
||||
: name_(name), v0_(0), v1_(0), v2_(0), start_(start), length_(length){};
|
||||
|
||||
// Creates a DmTarget object from dm_target_version as read from kernel
|
||||
// with DM_LIST_VERSION ioctl.
|
||||
DmTarget(const struct dm_target_versions* vers) : start_(0), length_(0) {
|
||||
CHECK(vers != nullptr) << "Can't create DmTarget with dm_target_versions set to nullptr";
|
||||
v0_ = vers->version[0];
|
||||
v1_ = vers->version[1];
|
||||
v2_ = vers->version[2];
|
||||
name_ = vers->name;
|
||||
}
|
||||
DmTarget(uint64_t start, uint64_t length) : start_(start), length_(length) {}
|
||||
|
||||
virtual ~DmTarget() = default;
|
||||
|
||||
// Returns name of the target.
|
||||
const std::string& name() const { return name_; }
|
||||
virtual const std::string& name() const = 0;
|
||||
|
||||
// Return the first logical sector represented by this target.
|
||||
uint64_t start() const { return start_; }
|
||||
|
||||
// Returns size in number of sectors when this target is part of
|
||||
// a DmTable, return 0 otherwise.
|
||||
uint64_t size() const { return length_; }
|
||||
|
||||
// Return string representation of the device mapper target version.
|
||||
std::string version() const {
|
||||
return std::to_string(v0_) + "." + std::to_string(v1_) + "." + std::to_string(v2_);
|
||||
}
|
||||
|
||||
// Function that converts this object to a string of arguments that can
|
||||
// be passed to the kernel for adding this target in a table. Each target (e.g. verity, linear)
|
||||
// must implement this, for it to be used on a device.
|
||||
virtual std::string Serialize() const { return ""; }
|
||||
virtual std::string Serialize() const = 0;
|
||||
|
||||
private:
|
||||
// Name of the target.
|
||||
std::string name_;
|
||||
// Target version.
|
||||
uint32_t v0_, v1_, v2_;
|
||||
// logical sector number start and total length (in terms of 512-byte sectors) represented
|
||||
// by this target within a DmTable.
|
||||
uint64_t start_, length_;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
using DeviceMapper = ::android::dm::DeviceMapper;
|
||||
using DmTable = ::android::dm::DmTable;
|
||||
using DmTarget = ::android::dm::DmTarget;
|
||||
using DmTargetTypeInfo = ::android::dm::DmTargetTypeInfo;
|
||||
using DmBlockDevice = ::android::dm::DeviceMapper::DmBlockDevice;
|
||||
|
||||
static int Usage(void) {
|
||||
|
|
@ -89,7 +90,7 @@ static int DmDeleteCmdHandler(int argc, char** argv) {
|
|||
}
|
||||
|
||||
static int DmListTargets(DeviceMapper& dm) {
|
||||
std::vector<DmTarget> targets;
|
||||
std::vector<DmTargetTypeInfo> targets;
|
||||
if (!dm.GetAvailableTargets(&targets)) {
|
||||
std::cerr << "Failed to read available device mapper targets" << std::endl;
|
||||
return -errno;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue