blob: 2b3663de36b2715ba8a605ae3528ba059d3644af [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 "cros-disks/fuse_helper.h"
#include <algorithm>
#include <memory>
#include <utility>
#include <base/logging.h>
#include <base/strings/strcat.h>
#include <base/strings/string_util.h>
#include "cros-disks/fuse_mounter.h"
#include "cros-disks/mount_options.h"
#include "cros-disks/platform.h"
#include "cros-disks/system_mounter.h"
#include "cros-disks/uri.h"
namespace cros_disks {
const char FUSEHelper::kFilesUser[] = "chronos";
const char FUSEHelper::kFilesGroup[] = "chronos-access";
const char FUSEHelper::kOptionAllowOther[] = "allow_other";
const char FUSEHelper::kOptionDefaultPermissions[] = "default_permissions";
constexpr char kFUSEHelperWorkingDirParam[] = "_fuse_working_dir=";
FUSEHelper::FUSEHelper(const std::string& fuse_type,
const Platform* platform,
brillo::ProcessReaper* process_reaper,
const base::FilePath& mount_program_path,
const std::string& mount_user)
: fuse_type_(fuse_type),
platform_(platform),
process_reaper_(process_reaper),
mount_program_path_(mount_program_path),
mount_user_(mount_user) {}
FUSEHelper::~FUSEHelper() = default;
bool FUSEHelper::CanMount(const Uri& source) const {
return source.scheme() == type() && !source.path().empty();
}
std::string FUSEHelper::GetTargetSuffix(const Uri& source) const {
std::string path = source.path();
std::replace(path.begin(), path.end(), '/', '$');
std::replace(path.begin(), path.end(), '.', '_');
return path;
}
std::unique_ptr<MountPoint> FUSEHelper::MountWithDir(
const Mounter& mounter,
const base::FilePath& working_dir,
const std::string& source,
const base::FilePath& target_path,
std::vector<std::string> params,
MountErrorType* error) {
params.push_back(
base::StrCat({kFUSEHelperWorkingDirParam, working_dir.value()}));
return mounter.Mount(source, target_path, std::move(params), error);
}
std::unique_ptr<MountPoint> FUSEHelper::Mount(const std::string& source,
const base::FilePath& target_path,
std::vector<std::string> params,
MountErrorType* error) const {
base::FilePath working_dir;
for (auto it = params.begin(); it != params.end(); ++it) {
if (base::StartsWith(*it, kFUSEHelperWorkingDirParam,
base::CompareCase::SENSITIVE)) {
working_dir =
base::FilePath(it->substr(strlen(kFUSEHelperWorkingDirParam)));
params.erase(it);
break;
}
}
CHECK(!working_dir.empty());
CHECK(Uri::IsUri(source));
const auto impl =
CreateMounter(working_dir, Uri::Parse(source), target_path, params);
if (!impl) {
*error = MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
return nullptr;
}
return impl->Mount(source, target_path, std::move(params), error);
}
bool FUSEHelper::CanMount(const std::string& source,
const std::vector<std::string>& params,
base::FilePath* suggested_dir_name) const {
const Uri uri = Uri::Parse(source);
if (!uri.valid()) {
return false;
}
if (!CanMount(uri)) {
return false;
}
*suggested_dir_name = base::FilePath(GetTargetSuffix(uri));
return true;
}
std::unique_ptr<FUSEMounter> FUSEHelper::CreateMounter(
const base::FilePath& /*working_dir*/,
const Uri& /*source*/,
const base::FilePath& /*target_path*/,
const std::vector<std::string>& options) const {
MountOptions mount_options;
mount_options.Initialize(options, false, "", "");
return std::make_unique<FUSEMounterLegacy>(
FUSEMounterLegacy::Params{.filesystem_type = type(),
.mount_options = std::move(mount_options),
.mount_program = program_path().value(),
.mount_user = user(),
.platform = platform(),
.process_reaper = process_reaper()});
}
} // namespace cros_disks