blob: cd39bec5982a3efe575b0ddca688c8e34bb4569e [file] [log] [blame]
// 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 "imageloader/dlc.h"
#include <set>
#include <base/files/file_util.h>
#include <chromeos/constants/imageloader.h>
#include <chromeos/dbus/service_constants.h>
#include "imageloader/component.h"
#include "imageloader/manifest.h"
namespace imageloader {
namespace {
// The name of the image.
constexpr char kImageName[] = "dlc.img";
constexpr char kSlotAName[] = "dlc_a";
constexpr char kSlotBName[] = "dlc_b";
constexpr char kManifestFileName[] = "imageloader.json";
constexpr char kTableFileName[] = "table";
AOrB GetImageAOrB(const std::string& a_or_b) {
if (a_or_b == imageloader::kSlotNameA) {
return AOrB::kDlcA;
} else if (a_or_b == imageloader::kSlotNameB) {
return AOrB::kDlcB;
} else {
return AOrB::kUnknown;
}
}
} // namespace
Dlc::Dlc(const std::string& id,
const std::string& package,
const base::FilePath& mount_base)
: id_(id), package_(package), mount_base_(mount_base) {}
base::FilePath Dlc::GetManifestPath() {
return base::FilePath(kDlcManifestRootpath)
.Append(id_)
.Append(package_)
.Append(kManifestFileName);
}
base::FilePath Dlc::GetTablePath() {
return base::FilePath(kDlcManifestRootpath)
.Append(id_)
.Append(package_)
.Append(kTableFileName);
}
base::FilePath Dlc::GetImagePath(const AOrB a_or_b) {
base::FilePath root =
base::FilePath(kDlcImageRootpath).Append(id_).Append(package_);
if (a_or_b == AOrB::kDlcA) {
return root.Append(kSlotAName).Append(kImageName);
} else if (a_or_b == AOrB::kDlcB) {
return root.Append(kSlotBName).Append(kImageName);
} else {
return base::FilePath();
}
}
// static
base::FilePath Dlc::GetMountPoint(const base::FilePath& mount_base,
const std::string& id,
const std::string& package) {
return mount_base.Append(id).Append(package);
}
base::FilePath Dlc::GetMountPoint() {
return GetMountPoint(mount_base_, id_, package_);
}
bool Dlc::Mount(HelperProcessProxy* proxy, const std::string& a_or_b_str) {
AOrB a_or_b = GetImageAOrB(a_or_b_str);
if (a_or_b == AOrB::kUnknown) {
LOG(ERROR) << "Unknown image type: " << a_or_b_str;
return false;
}
return Mount(proxy, GetImagePath(a_or_b), GetManifestPath(), GetTablePath(),
GetMountPoint());
}
bool Dlc::Mount(HelperProcessProxy* proxy,
const base::FilePath& image_path,
const base::FilePath& manifest_path,
const base::FilePath& table_path,
const base::FilePath& mount_point) {
std::string manifest_raw;
if (!base::ReadFileToStringWithMaxSize(manifest_path, &manifest_raw,
kMaximumFilesize)) {
LOG(ERROR) << "Could not read manifest file: " << manifest_path.value();
return false;
}
Manifest manifest;
if (!manifest.ParseManifest(manifest_raw))
return false;
std::string table;
if (!base::ReadFileToStringWithMaxSize(table_path, &table,
kMaximumFilesize)) {
LOG(ERROR) << "Could not read table.";
return false;
}
base::File image(image_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!image.IsValid()) {
LOG(ERROR) << "Could not open image file '" << image_path.value()
<< "': " << base::File::ErrorToString(image.error_details());
return false;
}
base::ScopedFD image_fd(image.TakePlatformFile());
return proxy->SendMountCommand(image_fd.get(), mount_point.value(),
manifest.fs_type(), table);
}
} // namespace imageloader