blob: 4fde15039bd2cfaa42ca22589917fa2d37b0c5e6 [file] [log] [blame]
// Copyright 2016 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 "container_utils/fs_data.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utility>
#include <base/logging.h>
#include <base/memory/free_deleter.h>
namespace device_jail {
FsData::~FsData() {
for (const std::string& jail_path : owned_devices_) {
jail_control_->RemoveDevice(jail_path);
}
}
// static
std::unique_ptr<FsData> FsData::Create(const std::string& dev_dir,
const std::string& mount_point) {
base::ScopedFD root_fd(
open(dev_dir.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
if (!root_fd.is_valid()) {
PLOG(ERROR) << "couldn't open root directory";
return std::unique_ptr<FsData>();
}
std::unique_ptr<DeviceJailControl> jail_control =
DeviceJailControl::Create();
if (!jail_control)
return std::unique_ptr<FsData>();
std::unique_ptr<char, base::FreeDeleter> real_mount_point(
realpath(mount_point.c_str(), nullptr));
if (!real_mount_point) {
PLOG(ERROR) << "couldn't resolve mount point";
return std::unique_ptr<FsData>();
}
return std::unique_ptr<FsData>(new FsData(std::move(root_fd),
dev_dir,
real_mount_point.get(),
std::move(jail_control)));
}
int FsData::GetStatForJail(const std::string& path, struct stat* file_stat) {
std::string jail_path;
switch (jail_control_->AddDevice(path, &jail_path)) {
case DeviceJailControl::AddResult::ERROR:
return -ENOENT;
case DeviceJailControl::AddResult::CREATED:
owned_devices_.push_back(jail_path);
/* fallthrough */
case DeviceJailControl::AddResult::ALREADY_EXISTS:
return stat(jail_path.c_str(), file_stat);
}
LOG(FATAL) << "Unhandled AddDevice return";
return -ENOENT;
}
} // namespace device_jail