You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.9 KiB
96 lines
2.9 KiB
// Copyright 2018 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <brillo/blkdev_utils/device_mapper_task.h>
|
|
|
|
#include <libdevmapper.h>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include <brillo/blkdev_utils/device_mapper.h>
|
|
|
|
namespace brillo {
|
|
|
|
DevmapperTaskImpl::DevmapperTaskImpl(int type)
|
|
: task_(DmTaskPtr(dm_task_create(type), &dm_task_destroy)) {}
|
|
|
|
bool DevmapperTaskImpl::SetName(const std::string& name) {
|
|
if (!task_ || !dm_task_set_name(task_.get(), name.c_str())) {
|
|
LOG(ERROR) << "SetName failed";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool DevmapperTaskImpl::AddTarget(uint64_t start,
|
|
uint64_t length,
|
|
const std::string& type,
|
|
const SecureBlob& parameters) {
|
|
// Strings stored in SecureBlob don't end with '\0'. Unfortunately,
|
|
// this causes accesses beyond the allocated storage space if any
|
|
// of the functions expecting a c-string get passed a SecureBlob.data().
|
|
// Temporarily, assign to a string.
|
|
// TODO(sarthakkukreti): Evaluate creation of a SecureCString to keep
|
|
// string data safe.
|
|
std::string parameters_str = parameters.to_string();
|
|
if (!task_ ||
|
|
!dm_task_add_target(task_.get(), start, length, type.c_str(),
|
|
parameters_str.c_str())) {
|
|
LOG(ERROR) << "AddTarget failed";
|
|
return false;
|
|
}
|
|
// Clear the string.
|
|
parameters_str.clear();
|
|
return true;
|
|
}
|
|
|
|
bool DevmapperTaskImpl::GetNextTarget(uint64_t* start,
|
|
uint64_t* length,
|
|
std::string* type,
|
|
SecureBlob* parameters) {
|
|
if (!task_) {
|
|
LOG(ERROR) << "GetNextTarget: invalid task.";
|
|
return false;
|
|
}
|
|
|
|
char *type_cstr, *parameters_cstr;
|
|
next_target_ = dm_get_next_target(task_.get(), next_target_, start, length,
|
|
&type_cstr, ¶meters_cstr);
|
|
|
|
if (type_cstr)
|
|
*type = std::string(type_cstr);
|
|
if (parameters_cstr) {
|
|
SecureBlob parameters_blob(parameters_cstr);
|
|
memset(parameters_cstr, 0, parameters_blob.size());
|
|
*parameters = std::move(parameters_blob);
|
|
}
|
|
|
|
return (next_target_ != nullptr);
|
|
}
|
|
|
|
bool DevmapperTaskImpl::Run(bool udev_sync) {
|
|
uint32_t cookie = 0;
|
|
|
|
if (!task_) {
|
|
LOG(ERROR) << "Invalid task.";
|
|
return false;
|
|
}
|
|
|
|
if (udev_sync && !dm_task_set_cookie(task_.get(), &cookie, 0)) {
|
|
LOG(ERROR) << "dm_task_set_cookie failed";
|
|
return false;
|
|
}
|
|
|
|
if (!dm_task_run(task_.get())) {
|
|
LOG(ERROR) << "dm_task_run failed";
|
|
return false;
|
|
}
|
|
|
|
// Make sure the node exists before continuing.
|
|
// TODO(sarthakkukreti): move to dm_udev_wait_immediate() on uprevving lvm2.
|
|
return udev_sync ? (dm_udev_wait(cookie) != 0) : true;
|
|
}
|
|
|
|
} // namespace brillo
|