Compare commits
7 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
5a4eaff29f | |
|
|
e12e421143 | |
|
|
caf2cec0d2 | |
|
|
59ed24f214 | |
|
|
27c0ae9643 | |
|
|
8f1b042421 | |
|
|
613cc27af6 |
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.11.4) # for RHEL 8
|
|||
|
||||
project(
|
||||
linyaps-box
|
||||
VERSION 2.1.0
|
||||
VERSION 2.1.3
|
||||
DESCRIPTION "A simple OCI runtime for desktop applications"
|
||||
HOMEPAGE_URL "https://github.com/OpenAtom-Linyaps/linyaps-box"
|
||||
LANGUAGES CXX)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ struct run_options
|
|||
std::string ID;
|
||||
std::string bundle;
|
||||
std::string config;
|
||||
uint preserve_fds;
|
||||
int preserve_fds;
|
||||
};
|
||||
|
||||
struct kill_options
|
||||
|
|
|
|||
|
|
@ -121,37 +121,42 @@ std::ostream &operator<<(std::ostream &os, const sync_message message)
|
|||
|
||||
struct MountFlag
|
||||
{
|
||||
std::underlying_type_t<decltype(MS_RDONLY)> flag;
|
||||
unsigned int flag;
|
||||
std::string_view name;
|
||||
};
|
||||
|
||||
constexpr std::array<MountFlag, 27> mount_flags{ MountFlag{ MS_RDONLY, "MS_RDONLY" },
|
||||
{ MS_NOSUID, "MS_NOSUID" },
|
||||
{ MS_NODEV, "MS_NODEV" },
|
||||
{ MS_NOEXEC, "MS_NOEXEC" },
|
||||
{ MS_SYNCHRONOUS, "MS_SYNCHRONOUS" },
|
||||
{ MS_REMOUNT, "MS_REMOUNT" },
|
||||
{ MS_MANDLOCK, "MS_MANDLOCK" },
|
||||
{ MS_DIRSYNC, "MS_DIRSYNC" },
|
||||
{ LINGYAPS_MS_NOSYMFOLLOW, "MS_NOSYMFOLLOW" },
|
||||
{ MS_NOATIME, "MS_NOATIME" },
|
||||
{ MS_NODIRATIME, "MS_NODIRATIME" },
|
||||
{ MS_BIND, "MS_BIND" },
|
||||
{ MS_MOVE, "MS_MOVE" },
|
||||
{ MS_REC, "MS_REC" },
|
||||
{ MS_SILENT, "MS_SILENT" },
|
||||
{ MS_POSIXACL, "MS_POSIXACL" },
|
||||
{ MS_UNBINDABLE, "MS_UNBINDABLE" },
|
||||
{ MS_PRIVATE, "MS_PRIVATE" },
|
||||
{ MS_SLAVE, "MS_SLAVE" },
|
||||
{ MS_SHARED, "MS_SHARED" },
|
||||
{ MS_RELATIME, "MS_RELATIME" },
|
||||
{ MS_KERNMOUNT, "MS_KERNMOUNT" },
|
||||
{ MS_I_VERSION, "MS_I_VERSION" },
|
||||
{ MS_STRICTATIME, "MS_STRICTATIME" },
|
||||
{ MS_LAZYTIME, "MS_LAZYTIME" },
|
||||
{ MS_ACTIVE, "MS_ACTIVE" },
|
||||
{ MS_NOUSER, "MS_NOUSER" } };
|
||||
constexpr std::array<MountFlag, 27> mount_flags{
|
||||
MountFlag{ MS_RDONLY, "MS_RDONLY" },
|
||||
{ MS_NOSUID, "MS_NOSUID" },
|
||||
{ MS_NODEV, "MS_NODEV" },
|
||||
{ MS_NOEXEC, "MS_NOEXEC" },
|
||||
{ MS_SYNCHRONOUS, "MS_SYNCHRONOUS" },
|
||||
{ MS_REMOUNT, "MS_REMOUNT" },
|
||||
{ MS_MANDLOCK, "MS_MANDLOCK" },
|
||||
{ MS_DIRSYNC, "MS_DIRSYNC" },
|
||||
{ LINGYAPS_MS_NOSYMFOLLOW, "MS_NOSYMFOLLOW" },
|
||||
{ MS_NOATIME, "MS_NOATIME" },
|
||||
{ MS_NODIRATIME, "MS_NODIRATIME" },
|
||||
{ MS_BIND, "MS_BIND" },
|
||||
{ MS_MOVE, "MS_MOVE" },
|
||||
{ MS_REC, "MS_REC" },
|
||||
{ MS_SILENT, "MS_SILENT" },
|
||||
{ MS_POSIXACL, "MS_POSIXACL" },
|
||||
{ MS_UNBINDABLE, "MS_UNBINDABLE" },
|
||||
{ MS_PRIVATE, "MS_PRIVATE" },
|
||||
{ MS_SLAVE, "MS_SLAVE" },
|
||||
{ MS_SHARED, "MS_SHARED" },
|
||||
{ MS_RELATIME, "MS_RELATIME" },
|
||||
{ MS_KERNMOUNT, "MS_KERNMOUNT" },
|
||||
{ MS_I_VERSION, "MS_I_VERSION" },
|
||||
{ MS_STRICTATIME, "MS_STRICTATIME" },
|
||||
{ MS_LAZYTIME, "MS_LAZYTIME" },
|
||||
{ MS_ACTIVE, "MS_ACTIVE" },
|
||||
// MS_NOUSER will be overflowed before 2.42.9000
|
||||
// refer:
|
||||
// https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=3263675250cbcbbcc76ede4f7c660418bd345a11;hp=cd335350021fd0b7ac533c83717ee38832fd9887
|
||||
{ static_cast<unsigned int>(MS_NOUSER), "MS_NOUSER" }
|
||||
};
|
||||
|
||||
[[maybe_unused]] auto dump_mount_flags(unsigned long flags) noexcept -> std::string
|
||||
{
|
||||
|
|
@ -1032,14 +1037,16 @@ private:
|
|||
|
||||
void configure_device(const std::filesystem::path &destination,
|
||||
mode_t mode,
|
||||
int type,
|
||||
std::filesystem::file_type type,
|
||||
dev_t dev,
|
||||
uid_t uid,
|
||||
gid_t gid)
|
||||
{
|
||||
assert(destination.is_absolute());
|
||||
|
||||
if (type != S_IFCHR && type != S_IFBLK && type != S_IFIFO) {
|
||||
if (type != std::filesystem::file_type::character
|
||||
&& type != std::filesystem::file_type::block
|
||||
&& type != std::filesystem::file_type::fifo) {
|
||||
throw std::runtime_error("unsupported device type");
|
||||
}
|
||||
|
||||
|
|
@ -1055,27 +1062,13 @@ private:
|
|||
if (destination_fd.has_value()) {
|
||||
// if already exists, check if it is a required device
|
||||
auto stat = linyaps_box::utils::lstatat(*destination_fd, "");
|
||||
auto cur_type = linyaps_box::utils::to_fs_file_type(stat.st_mode);
|
||||
bool satisfied{ true };
|
||||
if (__S_ISTYPE(stat.st_mode, type)) {
|
||||
auto dump_mode = [](mode_t mode) {
|
||||
if (S_ISCHR(mode)) {
|
||||
return "Character";
|
||||
}
|
||||
|
||||
if (S_ISBLK(mode)) {
|
||||
return "Block";
|
||||
}
|
||||
|
||||
if (S_ISFIFO(mode)) {
|
||||
return "FIFO";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
if (linyaps_box::utils::is_type(stat.st_mode, type)) {
|
||||
LINYAPS_BOX_DEBUG()
|
||||
<< "the type of existing device: " << destination << " is not required\n"
|
||||
<< "expect " << dump_mode(mode) << ", got " << dump_mode(stat.st_mode);
|
||||
<< "expect " << linyaps_box::utils::to_string(type) << ", got "
|
||||
<< linyaps_box::utils::to_string(cur_type);
|
||||
satisfied = false;
|
||||
}
|
||||
|
||||
|
|
@ -1105,7 +1098,9 @@ private:
|
|||
|
||||
try {
|
||||
auto path = destination.relative_path();
|
||||
linyaps_box::utils::mknodat(root, path, mode | type, dev);
|
||||
auto f_type = static_cast<unsigned int>(linyaps_box::utils::to_linux_file_type(type));
|
||||
|
||||
linyaps_box::utils::mknodat(root, path, mode | f_type, dev);
|
||||
|
||||
auto new_dev = linyaps_box::utils::open_at(root, path, O_PATH);
|
||||
path = new_dev.proc_path();
|
||||
|
|
@ -1138,14 +1133,16 @@ private:
|
|||
LINYAPS_BOX_DEBUG() << "Configure default devices";
|
||||
|
||||
constexpr auto default_mode = 0666;
|
||||
constexpr auto default_type = std::filesystem::file_type::character;
|
||||
auto uid = container.get_config().process.user.uid;
|
||||
auto gid = container.get_config().process.user.gid;
|
||||
this->configure_device("/dev/null", default_mode, S_IFCHR, makedev(1, 3), uid, gid);
|
||||
this->configure_device("/dev/zero", default_mode, S_IFCHR, makedev(1, 5), uid, gid);
|
||||
this->configure_device("/dev/full", default_mode, S_IFCHR, makedev(1, 7), uid, gid);
|
||||
this->configure_device("/dev/random", default_mode, S_IFCHR, makedev(1, 8), uid, gid);
|
||||
this->configure_device("/dev/urandom", default_mode, S_IFCHR, makedev(1, 9), uid, gid);
|
||||
this->configure_device("/dev/tty", default_mode, S_IFCHR, makedev(5, 0), uid, gid);
|
||||
|
||||
this->configure_device("/dev/null", default_mode, default_type, makedev(1, 3), uid, gid);
|
||||
this->configure_device("/dev/zero", default_mode, default_type, makedev(1, 5), uid, gid);
|
||||
this->configure_device("/dev/full", default_mode, default_type, makedev(1, 7), uid, gid);
|
||||
this->configure_device("/dev/random", default_mode, default_type, makedev(1, 8), uid, gid);
|
||||
this->configure_device("/dev/urandom", default_mode, default_type, makedev(1, 9), uid, gid);
|
||||
this->configure_device("/dev/tty", default_mode, default_type, makedev(5, 0), uid, gid);
|
||||
|
||||
// bind mount /dev/pts/ptmx to /dev/ptmx
|
||||
// https://docs.kernel.org/filesystems/devpts.html
|
||||
|
|
@ -1680,7 +1677,7 @@ try {
|
|||
STDOUT_FILENO,
|
||||
STDERR_FILENO,
|
||||
};
|
||||
for (uint fd = 0; fd < args.container->preserve_fds(); ++fd) {
|
||||
for (auto fd = 0; fd < args.container->preserve_fds(); ++fd) {
|
||||
except_fds.insert(fd + 3);
|
||||
}
|
||||
except_fds.insert(static_cast<unsigned int>(args.socket.get()));
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct container_data;
|
|||
struct create_container_options_t
|
||||
{
|
||||
cgroup_manager_t manager;
|
||||
uint preserve_fds;
|
||||
int preserve_fds;
|
||||
std::string ID;
|
||||
std::filesystem::path bundle;
|
||||
std::filesystem::path config;
|
||||
|
|
@ -47,7 +47,7 @@ public:
|
|||
|
||||
private:
|
||||
void cgroup_preenter(const cgroup_options &options, utils::file_descriptor &dirfd);
|
||||
uint preserve_fds_;
|
||||
int preserve_fds_;
|
||||
gid_t host_gid_;
|
||||
uid_t host_uid_;
|
||||
container_data *data{ nullptr };
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
#include "linyaps_box/utils/fstat.h"
|
||||
|
||||
#include "linyaps_box/utils/log.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace linyaps_box::utils {
|
||||
|
||||
auto fstatat(const file_descriptor &fd, std::filesystem::path path, int flag) -> struct stat
|
||||
|
|
@ -46,5 +50,114 @@ auto statfs(const file_descriptor &fd) -> struct statfs
|
|||
}
|
||||
|
||||
return statbuf;
|
||||
|
||||
}
|
||||
|
||||
auto
|
||||
to_linux_file_type(std::filesystem::file_type type) noexcept -> int
|
||||
|
||||
{
|
||||
switch (type) {
|
||||
case std::filesystem::file_type::regular:
|
||||
return S_IFREG;
|
||||
case std::filesystem::file_type::directory:
|
||||
return S_IFDIR;
|
||||
case std::filesystem::file_type::symlink:
|
||||
return S_IFLNK;
|
||||
case std::filesystem::file_type::block:
|
||||
return S_IFBLK;
|
||||
case std::filesystem::file_type::character:
|
||||
return S_IFCHR;
|
||||
case std::filesystem::file_type::fifo:
|
||||
return S_IFIFO;
|
||||
case std::filesystem::file_type::socket:
|
||||
return S_IFSOCK;
|
||||
case std::filesystem::file_type::unknown: {
|
||||
LINYAPS_BOX_WARNING() << "Try to convert unknown type to linux file type";
|
||||
return 0;
|
||||
}
|
||||
case std::filesystem::file_type::none: {
|
||||
LINYAPS_BOX_DEBUG() << "Try to convert none type to linux file type";
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
case std::filesystem::file_type::not_found: {
|
||||
LINYAPS_BOX_WARNING() << "Try to convert not_found type to linux file type";
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
default: {
|
||||
LINYAPS_BOX_ERR() << "Try to convert unhandled file type " << static_cast<int>(type)
|
||||
<< " to linux file type";
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto to_fs_file_type(mode_t type) noexcept -> std::filesystem::file_type
|
||||
{
|
||||
switch (type) {
|
||||
case S_IFREG:
|
||||
return std::filesystem::file_type::regular;
|
||||
case S_IFDIR:
|
||||
return std::filesystem::file_type::directory;
|
||||
case S_IFLNK:
|
||||
return std::filesystem::file_type::symlink;
|
||||
case S_IFBLK:
|
||||
return std::filesystem::file_type::block;
|
||||
case S_IFCHR:
|
||||
return std::filesystem::file_type::character;
|
||||
case S_IFIFO:
|
||||
return std::filesystem::file_type::fifo;
|
||||
case S_IFSOCK:
|
||||
return std::filesystem::file_type::socket;
|
||||
default:
|
||||
return std::filesystem::file_type::unknown;
|
||||
}
|
||||
}
|
||||
|
||||
auto is_type(mode_t mode, std::filesystem::file_type type) noexcept -> bool
|
||||
{
|
||||
auto f_type = to_linux_file_type(type);
|
||||
if (f_type <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_type(mode, f_type);
|
||||
}
|
||||
|
||||
auto is_type(mode_t mode, mode_t type) noexcept -> bool
|
||||
{
|
||||
return (mode & S_IFMT) == type;
|
||||
}
|
||||
|
||||
auto to_string(std::filesystem::file_type type) noexcept -> std::string_view
|
||||
{
|
||||
switch (type) {
|
||||
case std::filesystem::file_type::none:
|
||||
return "None";
|
||||
case std::filesystem::file_type::not_found:
|
||||
return "Not found";
|
||||
case std::filesystem::file_type::regular:
|
||||
return "Regular";
|
||||
case std::filesystem::file_type::directory:
|
||||
return "Directory";
|
||||
case std::filesystem::file_type::symlink:
|
||||
return "Symlink";
|
||||
case std::filesystem::file_type::block:
|
||||
return "Block";
|
||||
case std::filesystem::file_type::character:
|
||||
return "Character";
|
||||
case std::filesystem::file_type::fifo:
|
||||
return "FIFO";
|
||||
case std::filesystem::file_type::socket:
|
||||
return "Socket";
|
||||
case std::filesystem::file_type::unknown:
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
} // namespace linyaps_box::utils
|
||||
|
|
|
|||
|
|
@ -16,4 +16,10 @@ auto fstatat(const file_descriptor &fd, std::filesystem::path path, int flag) ->
|
|||
auto fstatat(const file_descriptor &fd, const std::filesystem::path &path) -> struct stat;
|
||||
auto lstatat(const file_descriptor &fd, const std::filesystem::path &path) -> struct stat;
|
||||
auto statfs(const file_descriptor &fd) -> struct statfs;
|
||||
|
||||
auto to_linux_file_type(std::filesystem::file_type type) noexcept -> int;
|
||||
auto to_fs_file_type(mode_t type) noexcept -> std::filesystem::file_type;
|
||||
auto is_type(mode_t mode, std::filesystem::file_type type) noexcept -> bool;
|
||||
auto is_type(mode_t mode, mode_t type) noexcept -> bool;
|
||||
auto to_string(std::filesystem::file_type type) noexcept -> std::string_view;
|
||||
} // namespace linyaps_box::utils
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "linyaps_box/utils/file_describer.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace linyaps_box::utils {
|
||||
|
||||
auto mkdir(const file_descriptor &root, std::filesystem::path path, mode_t mode = 0755)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <filesystem>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace linyaps_box::utils {
|
||||
void mknodat(const file_descriptor &root,
|
||||
const std::filesystem::path &path,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace {
|
|||
auto open_at_fallback(const linyaps_box::utils::file_descriptor &root,
|
||||
const std::filesystem::path &path,
|
||||
int flag,
|
||||
uint mode) -> linyaps_box::utils::file_descriptor
|
||||
mode_t mode) -> linyaps_box::utils::file_descriptor
|
||||
{
|
||||
LINYAPS_BOX_DEBUG() << "fallback openat " << path.c_str() << " at FD=" << root.get() << " with "
|
||||
<< linyaps_box::utils::inspect_fcntl_or_open_flags(
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ auto str_to_signal(std::string_view str) -> int
|
|||
{ "SIGTTIN", SIGTTIN }, { "SIGTTOU", SIGTTOU }, { "SIGURG", SIGURG },
|
||||
{ "SIGUSR1", SIGUSR1 }, { "SIGUSR2", SIGUSR2 }, { "SIGVTALRM", SIGVTALRM },
|
||||
{ "SIGWINCH", SIGWINCH }, { "SIGXCPU", SIGXCPU }, { "SIGXFSZ", SIGXFSZ },
|
||||
{ "SIGIO", SIGIO }, { "SIGIOT", SIGIOT }, { "SIGCLD", SIGCLD },
|
||||
{ "SIGIO", SIGIO }, { "SIGIOT", SIGIOT },
|
||||
#ifdef SIGCLD
|
||||
{ "SIGCLD", SIGCLD },
|
||||
#endif
|
||||
};
|
||||
|
||||
auto it = sigMap.find(str);
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
#include "linyaps_box/utils/file_describer.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace linyaps_box::utils {
|
||||
|
||||
auto touch(const file_descriptor &root,
|
||||
const std::filesystem::path &path,
|
||||
int flag,
|
||||
mode_t mode = 0700) -> file_descriptor;
|
||||
mode_t mode = 0644) -> file_descriptor;
|
||||
|
||||
} // namespace linyaps_box::utils
|
||||
|
|
|
|||
Loading…
Reference in New Issue