Compare commits

...

7 Commits

Author SHA1 Message Date
ComixHe 5a4eaff29f fix: explicitly cast MS_NOUSER to unsigned int
Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-21 17:22:44 +08:00
ComixHe e12e421143 chore: Begin development of 2.1.3
Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-21 16:28:37 +08:00
ComixHe caf2cec0d2 refactor: Add conditional compilation protection for SIGCLD signal
SIGCLD is a legacy signal in System V UNIX.
Mapping it with #ifdef SIGCLD in str_to_signal function
to improve cross-platform compatibility and avoid compilation errors
on platforms where SIGCLD is not defined (e.g. musl).

Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-20 16:40:05 +08:00
ComixHe 59ed24f214 refactor: add <sys/types.h> for mode_t
- fix inconsistencies between function parameter implementations and declared types.
- change the default permission of touched file.

Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-20 16:40:05 +08:00
ComixHe 27c0ae9643 refactor: remove __S_ISTYPE for improving portability
__S_ISTYPE is glibc internal macro.

Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-20 16:40:05 +08:00
ComixHe 8f1b042421 refactor: change the type of mount flag to unsigned int
Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-20 16:40:05 +08:00
ComixHe 613cc27af6 refactor: standardize preserve_fds type for better portability
Change preserve_fds from uint to int type

Signed-off-by: ComixHe <ComixHe1895@outlook.com>
2025-10-20 16:40:05 +08:00
11 changed files with 188 additions and 63 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()));

View File

@ -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 };

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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(

View File

@ -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);

View File

@ -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