Better output formatting for --help
This commit is contained in:
parent
e1402ed775
commit
924c8fa9f9
187
cmdline.cc
187
cmdline.cc
@ -42,6 +42,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -58,6 +59,7 @@
|
|||||||
namespace cmdline {
|
namespace cmdline {
|
||||||
|
|
||||||
#define _LOG_DEFAULT_FILE "/var/log/nsjail.log"
|
#define _LOG_DEFAULT_FILE "/var/log/nsjail.log"
|
||||||
|
#define _MAX_CONSOLE_OUTPUT_WIDTH 65
|
||||||
|
|
||||||
struct custom_option {
|
struct custom_option {
|
||||||
struct option opt;
|
struct option opt;
|
||||||
@ -69,10 +71,10 @@ struct custom_option custom_opts[] = {
|
|||||||
{ { "help", no_argument, NULL, 'h' }, "Help plz.." },
|
{ { "help", no_argument, NULL, 'h' }, "Help plz.." },
|
||||||
{ { "mode", required_argument, NULL, 'M' },
|
{ { "mode", required_argument, NULL, 'M' },
|
||||||
"Execution mode (default: 'o' [MODE_STANDALONE_ONCE]):\n"
|
"Execution mode (default: 'o' [MODE_STANDALONE_ONCE]):\n"
|
||||||
"\tl: Wait for connections on a TCP port (specified with --port) [MODE_LISTEN_TCP]\n"
|
" l: [MODE_LISTEN_TCP]\n\tWait for connections on a TCP port (specified with --port)\n"
|
||||||
"\to: Launch a single process on the console using clone/execve [MODE_STANDALONE_ONCE]\n"
|
" o: [MODE_STANDALONE_ONCE]\n\tLaunch a single process on the console using clone/execve\n"
|
||||||
"\te: Launch a single process on the console using execve [MODE_STANDALONE_EXECVE]\n"
|
" e: [MODE_STANDALONE_EXECVE]\n\tLaunch a single process on the console using execve\n"
|
||||||
"\tr: Launch a single process on the console with clone/execve, keep doing it forever [MODE_STANDALONE_RERUN]" },
|
" r: [MODE_STANDALONE_RERUN]\n\tLaunch a single process on the console with clone/execve, keep doing it forever" },
|
||||||
{ { "config", required_argument, NULL, 'C' }, "Configuration file in the config.proto ProtoBuf format (see configs/ directory for examples)" },
|
{ { "config", required_argument, NULL, 'C' }, "Configuration file in the config.proto ProtoBuf format (see configs/ directory for examples)" },
|
||||||
{ { "exec_file", required_argument, NULL, 'x' }, "File to exec (default: argv[0])" },
|
{ { "exec_file", required_argument, NULL, 'x' }, "File to exec (default: argv[0])" },
|
||||||
{ { "execute_fd", no_argument, NULL, 0x0607 }, "Use execveat() to execute a file-descriptor instead of executing the binary path. In such case argv[0]/exec_file denotes a file path before mount namespacing" },
|
{ { "execute_fd", no_argument, NULL, 0x0607 }, "Use execveat() to execute a file-descriptor instead of executing the binary path. In such case argv[0]/exec_file denotes a file path before mount namespacing" },
|
||||||
@ -172,8 +174,51 @@ struct custom_option custom_opts[] = {
|
|||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
static const char* logYesNo(bool yes) {
|
static const char *logYesNo(bool yes) { return (yes ? "true" : "false"); }
|
||||||
return (yes ? "true" : "false");
|
|
||||||
|
size_t GetConsoleLength(const std::string &str) {
|
||||||
|
int result = 0;
|
||||||
|
for (char c : str) {
|
||||||
|
if (c == '\t') {
|
||||||
|
result += 8;
|
||||||
|
} else {
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FormatLine(const std::string &line, size_t max_len = 80) {
|
||||||
|
std::string indent = line.substr(0, line.find_first_not_of(" \t"));
|
||||||
|
size_t indent_len = GetConsoleLength(indent);
|
||||||
|
size_t cursor = 0;
|
||||||
|
std::string formatted;
|
||||||
|
std::vector<std::string> words = util::strSplit(line.c_str(), ' ');
|
||||||
|
for (const auto &word : words) {
|
||||||
|
size_t wlen = GetConsoleLength(word);
|
||||||
|
std::string separator = cursor == 0 ? "" : " ";
|
||||||
|
size_t slen = GetConsoleLength(separator);
|
||||||
|
if (cursor != 0 && cursor + slen + wlen >= max_len) {
|
||||||
|
util::StrAppend(&formatted, "\n");
|
||||||
|
cursor = 0;
|
||||||
|
separator = indent;
|
||||||
|
slen = indent_len;
|
||||||
|
}
|
||||||
|
util::StrAppend(&formatted, "%s%s", separator.c_str(), word.c_str());
|
||||||
|
cursor += slen + wlen;
|
||||||
|
}
|
||||||
|
return formatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FormatDescription(const char *descr) {
|
||||||
|
std::string formatted;
|
||||||
|
std::vector<std::string> lines = util::strSplit(descr, '\n');
|
||||||
|
|
||||||
|
for (const auto &line : lines) {
|
||||||
|
util::StrAppend(&formatted, "%s\n",
|
||||||
|
FormatLine(std::string("\t") + line).c_str());
|
||||||
|
}
|
||||||
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmdlineOptUsage(struct custom_option *option) {
|
static void cmdlineOptUsage(struct custom_option *option) {
|
||||||
@ -184,7 +229,7 @@ static void cmdlineOptUsage(struct custom_option* option) {
|
|||||||
LOG_HELP_BOLD(" --%s %s", option->opt.name,
|
LOG_HELP_BOLD(" --%s %s", option->opt.name,
|
||||||
option->opt.has_arg == required_argument ? "VALUE" : "");
|
option->opt.has_arg == required_argument ? "VALUE" : "");
|
||||||
}
|
}
|
||||||
LOG_HELP("\t%s", option->descr);
|
LOG_HELP("%s", FormatDescription(option->descr).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmdlineUsage(const char *pname) {
|
static void cmdlineUsage(const char *pname) {
|
||||||
@ -211,7 +256,8 @@ void addEnv(nsjconf_t* nsjconf, const std::string& env) {
|
|||||||
}
|
}
|
||||||
char *e = getenv(env.c_str());
|
char *e = getenv(env.c_str());
|
||||||
if (!e) {
|
if (!e) {
|
||||||
LOG_W("Requested to use the %s envar, but it's not set. It'll be ignored", QC(env));
|
LOG_W("Requested to use the %s envar, but it's not set. It'll be ignored",
|
||||||
|
QC(env));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nsjconf->envs.push_back(std::string(env).append("=").append(e));
|
nsjconf->envs.push_back(std::string(env).append("=").append(e));
|
||||||
@ -237,44 +283,50 @@ void logParams(nsjconf_t* nsjconf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(
|
LOG_I(
|
||||||
"Jail parameters: hostname:'%s', chroot:%s, process:'%s', bind:[%s]:%d, "
|
"Jail parameters: hostname:'%s', chroot:%s, process:'%s', "
|
||||||
|
"bind:[%s]:%d, "
|
||||||
"max_conns:%u, max_conns_per_ip:%u, time_limit:%" PRId64
|
"max_conns:%u, max_conns_per_ip:%u, time_limit:%" PRId64
|
||||||
", personality:%#lx, daemonize:%s, clone_newnet:%s, "
|
", personality:%#lx, daemonize:%s, clone_newnet:%s, "
|
||||||
"clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, clone_newuts:%s, "
|
"clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, "
|
||||||
"clone_newcgroup:%s, clone_newtime:%s, keep_caps:%s, disable_no_new_privs:%s, "
|
"clone_newuts:%s, "
|
||||||
|
"clone_newcgroup:%s, clone_newtime:%s, keep_caps:%s, "
|
||||||
|
"disable_no_new_privs:%s, "
|
||||||
"max_cpus:%zu",
|
"max_cpus:%zu",
|
||||||
nsjconf->hostname.c_str(), QC(nsjconf->chroot),
|
nsjconf->hostname.c_str(), QC(nsjconf->chroot),
|
||||||
nsjconf->exec_file.empty() ? nsjconf->argv[0].c_str() : nsjconf->exec_file.c_str(),
|
nsjconf->exec_file.empty() ? nsjconf->argv[0].c_str()
|
||||||
nsjconf->bindhost.c_str(), nsjconf->port, nsjconf->max_conns, nsjconf->max_conns_per_ip,
|
: nsjconf->exec_file.c_str(),
|
||||||
nsjconf->tlimit, nsjconf->personality, logYesNo(nsjconf->daemonize),
|
nsjconf->bindhost.c_str(), nsjconf->port, nsjconf->max_conns,
|
||||||
logYesNo(nsjconf->clone_newnet), logYesNo(nsjconf->clone_newuser),
|
nsjconf->max_conns_per_ip, nsjconf->tlimit, nsjconf->personality,
|
||||||
logYesNo(nsjconf->clone_newns), logYesNo(nsjconf->clone_newpid),
|
logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet),
|
||||||
logYesNo(nsjconf->clone_newipc), logYesNo(nsjconf->clone_newuts),
|
logYesNo(nsjconf->clone_newuser), logYesNo(nsjconf->clone_newns),
|
||||||
logYesNo(nsjconf->clone_newcgroup), logYesNo(nsjconf->clone_newtime),
|
logYesNo(nsjconf->clone_newpid), logYesNo(nsjconf->clone_newipc),
|
||||||
logYesNo(nsjconf->keep_caps), logYesNo(nsjconf->disable_no_new_privs),
|
logYesNo(nsjconf->clone_newuts), logYesNo(nsjconf->clone_newcgroup),
|
||||||
nsjconf->max_cpus);
|
logYesNo(nsjconf->clone_newtime), logYesNo(nsjconf->keep_caps),
|
||||||
|
logYesNo(nsjconf->disable_no_new_privs), nsjconf->max_cpus);
|
||||||
|
|
||||||
for (const auto &p : nsjconf->mountpts) {
|
for (const auto &p : nsjconf->mountpts) {
|
||||||
LOG_I(
|
LOG_I("%s: %s", p.is_symlink ? "Symlink" : "Mount",
|
||||||
"%s: %s", p.is_symlink ? "Symlink" : "Mount", mnt::describeMountPt(p).c_str());
|
mnt::describeMountPt(p).c_str());
|
||||||
}
|
}
|
||||||
for (const auto &uid : nsjconf->uids) {
|
for (const auto &uid : nsjconf->uids) {
|
||||||
LOG_I("Uid map: inside_uid:%lu outside_uid:%lu count:%zu newuidmap:%s",
|
LOG_I("Uid map: inside_uid:%lu outside_uid:%lu count:%zu newuidmap:%s",
|
||||||
(unsigned long)uid.inside_id, (unsigned long)uid.outside_id, uid.count,
|
(unsigned long)uid.inside_id, (unsigned long)uid.outside_id,
|
||||||
uid.is_newidmap ? "true" : "false");
|
uid.count, uid.is_newidmap ? "true" : "false");
|
||||||
if (uid.outside_id == 0 && nsjconf->clone_newuser) {
|
if (uid.outside_id == 0 && nsjconf->clone_newuser) {
|
||||||
LOG_W(
|
LOG_W(
|
||||||
"Process will be UID/EUID=0 in the global user namespace, and will "
|
"Process will be UID/EUID=0 in the global user namespace, and "
|
||||||
|
"will "
|
||||||
"have user root-level access to files");
|
"have user root-level access to files");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &gid : nsjconf->gids) {
|
for (const auto &gid : nsjconf->gids) {
|
||||||
LOG_I("Gid map: inside_gid:%lu outside_gid:%lu count:%zu newgidmap:%s",
|
LOG_I("Gid map: inside_gid:%lu outside_gid:%lu count:%zu newgidmap:%s",
|
||||||
(unsigned long)gid.inside_id, (unsigned long)gid.outside_id, gid.count,
|
(unsigned long)gid.inside_id, (unsigned long)gid.outside_id,
|
||||||
gid.is_newidmap ? "true" : "false");
|
gid.count, gid.is_newidmap ? "true" : "false");
|
||||||
if (gid.outside_id == 0 && nsjconf->clone_newuser) {
|
if (gid.outside_id == 0 && nsjconf->clone_newuser) {
|
||||||
LOG_W(
|
LOG_W(
|
||||||
"Process will be GID/EGID=0 in the global user namespace, and will "
|
"Process will be GID/EGID=0 in the global user namespace, and "
|
||||||
|
"will "
|
||||||
"have group root-level access to files");
|
"have group root-level access to files");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +348,9 @@ uint64_t parseRLimit(int res, const char* optarg, unsigned long mul) {
|
|||||||
}
|
}
|
||||||
if (!util::isANumber(optarg)) {
|
if (!util::isANumber(optarg)) {
|
||||||
LOG_F(
|
LOG_F(
|
||||||
"RLIMIT %d needs a numeric or 'max'/'hard'/'def'/'soft'/'inf' value ('%s' "
|
"RLIMIT %d needs a numeric or 'max'/'hard'/'def'/'soft'/'inf' "
|
||||||
|
"value "
|
||||||
|
"('%s' "
|
||||||
"provided)",
|
"provided)",
|
||||||
res, optarg);
|
res, optarg);
|
||||||
}
|
}
|
||||||
@ -317,8 +371,8 @@ static std::string argFromVec(const std::vector<std::string>& vec, size_t pos) {
|
|||||||
|
|
||||||
static bool setupArgv(nsjconf_t *nsjconf, int argc, char **argv, int optind) {
|
static bool setupArgv(nsjconf_t *nsjconf, int argc, char **argv, int optind) {
|
||||||
/*
|
/*
|
||||||
* If user provided cmdline via nsjail [opts] -- [cmdline], then override the one from the
|
* If user provided cmdline via nsjail [opts] -- [cmdline], then override
|
||||||
* config file
|
* the one from the config file
|
||||||
*/
|
*/
|
||||||
if (optind < argc) {
|
if (optind < argc) {
|
||||||
nsjconf->argv.clear();
|
nsjconf->argv.clear();
|
||||||
@ -326,7 +380,7 @@ static bool setupArgv(nsjconf_t* nsjconf, int argc, char** argv, int optind) {
|
|||||||
nsjconf->argv.push_back(argv[i]);
|
nsjconf->argv.push_back(argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nsjconf->exec_file.empty() && nsjconf->argv.size() > 0) {
|
if (nsjconf->exec_file.empty() && !nsjconf->argv.empty()) {
|
||||||
nsjconf->exec_file = nsjconf->argv[0];
|
nsjconf->exec_file = nsjconf->argv[0];
|
||||||
}
|
}
|
||||||
if (nsjconf->exec_file.empty()) {
|
if (nsjconf->exec_file.empty()) {
|
||||||
@ -338,12 +392,15 @@ static bool setupArgv(nsjconf_t* nsjconf, int argc, char** argv, int optind) {
|
|||||||
if (nsjconf->use_execveat) {
|
if (nsjconf->use_execveat) {
|
||||||
#if !defined(__NR_execveat)
|
#if !defined(__NR_execveat)
|
||||||
LOG_E(
|
LOG_E(
|
||||||
"Your nsjail is compiled without support for the execveat() syscall, yet you "
|
"Your nsjail is compiled without support for the execveat() "
|
||||||
|
"syscall, "
|
||||||
|
"yet you "
|
||||||
"specified the --execute_fd flag");
|
"specified the --execute_fd flag");
|
||||||
return false;
|
return false;
|
||||||
#endif /* !defined(__NR_execveat) */
|
#endif /* !defined(__NR_execveat) */
|
||||||
if ((nsjconf->exec_fd = TEMP_FAILURE_RETRY(
|
if ((nsjconf->exec_fd = TEMP_FAILURE_RETRY(open(
|
||||||
open(nsjconf->exec_file.c_str(), O_RDONLY | O_PATH | O_CLOEXEC))) == -1) {
|
nsjconf->exec_file.c_str(), O_RDONLY | O_PATH | O_CLOEXEC))) ==
|
||||||
|
-1) {
|
||||||
PLOG_W("Couldn't open %s file", QC(nsjconf->exec_file));
|
PLOG_W("Couldn't open %s file", QC(nsjconf->exec_file));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -355,14 +412,18 @@ static bool setupMounts(nsjconf_t* nsjconf) {
|
|||||||
if (!(nsjconf->chroot.empty())) {
|
if (!(nsjconf->chroot.empty())) {
|
||||||
if (!mnt::addMountPtHead(nsjconf, nsjconf->chroot, "/", /* fstype= */ "",
|
if (!mnt::addMountPtHead(nsjconf, nsjconf->chroot, "/", /* fstype= */ "",
|
||||||
/* options= */ "",
|
/* options= */ "",
|
||||||
nsjconf->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE)
|
nsjconf->is_root_rw
|
||||||
|
? (MS_BIND | MS_REC | MS_PRIVATE)
|
||||||
: (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY),
|
: (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY),
|
||||||
/* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true, /* src_env= */ "",
|
/* is_dir= */ mnt::NS_DIR_YES,
|
||||||
/* dst_env= */ "", /* src_content= */ "", /* is_symlink= */ false)) {
|
/* is_mandatory= */ true, /* src_env= */ "",
|
||||||
|
/* dst_env= */ "", /* src_content= */ "",
|
||||||
|
/* is_symlink= */ false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!mnt::addMountPtHead(nsjconf, /* src= */ "", "/", "tmpfs",
|
if (!mnt::addMountPtHead(
|
||||||
|
nsjconf, /* src= */ "", "/", "tmpfs",
|
||||||
/* options= */ "", nsjconf->is_root_rw ? 0 : MS_RDONLY,
|
/* options= */ "", nsjconf->is_root_rw ? 0 : MS_RDONLY,
|
||||||
/* is_dir= */ mnt::NS_DIR_YES,
|
/* is_dir= */ mnt::NS_DIR_YES,
|
||||||
/* is_mandatory= */ true, /* src_env= */ "", /* dst_env= */ "",
|
/* is_mandatory= */ true, /* src_env= */ "", /* dst_env= */ "",
|
||||||
@ -372,9 +433,12 @@ static bool setupMounts(nsjconf_t* nsjconf) {
|
|||||||
}
|
}
|
||||||
if (!nsjconf->proc_path.empty()) {
|
if (!nsjconf->proc_path.empty()) {
|
||||||
if (!mnt::addMountPtTail(nsjconf, /* src= */ "", nsjconf->proc_path, "proc",
|
if (!mnt::addMountPtTail(nsjconf, /* src= */ "", nsjconf->proc_path, "proc",
|
||||||
/* options= */ "", nsjconf->is_proc_rw ? 0 : MS_RDONLY,
|
/* options= */ "",
|
||||||
/* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true, /* src_env= */ "",
|
nsjconf->is_proc_rw ? 0 : MS_RDONLY,
|
||||||
/* dst_env= */ "", /* src_content= */ "", /* is_symlink= */ false)) {
|
/* is_dir= */ mnt::NS_DIR_YES,
|
||||||
|
/* is_mandatory= */ true, /* src_env= */ "",
|
||||||
|
/* dst_env= */ "", /* src_content= */ "",
|
||||||
|
/* is_symlink= */ false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,7 +467,8 @@ void setupUsers(nsjconf_t* nsjconf) {
|
|||||||
|
|
||||||
std::string parseMACVlanMode(const char *optarg) {
|
std::string parseMACVlanMode(const char *optarg) {
|
||||||
if (strcasecmp(optarg, "private") != 0 && strcasecmp(optarg, "vepa") != 0 &&
|
if (strcasecmp(optarg, "private") != 0 && strcasecmp(optarg, "vepa") != 0 &&
|
||||||
strcasecmp(optarg, "bridge") != 0 && strcasecmp(optarg, "passthru") != 0) {
|
strcasecmp(optarg, "bridge") != 0 &&
|
||||||
|
strcasecmp(optarg, "passthru") != 0) {
|
||||||
LOG_F(
|
LOG_F(
|
||||||
"macvlan mode can only be one of the values: "
|
"macvlan mode can only be one of the values: "
|
||||||
"'private'/'vepa'/'bridge'/'passthru' ('%s' "
|
"'private'/'vepa'/'bridge'/'passthru' ('%s' "
|
||||||
@ -506,8 +571,10 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
|
|
||||||
int opt_index = 0;
|
int opt_index = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = getopt_long(argc, argv,
|
int c = getopt_long(
|
||||||
"x:H:D:C:c:p:i:u:g:l:L:t:M:NdvqQeh?E:R:B:T:m:s:P:I:U:G:", opts, &opt_index);
|
argc, argv,
|
||||||
|
"x:H:D:C:c:p:i:u:g:l:L:t:M:NdvqQeh?E:R:B:T:m:s:P:I:U:G:", opts,
|
||||||
|
&opt_index);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -701,7 +768,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
std::string o_id = argFromVec(subopts, 1);
|
std::string o_id = argFromVec(subopts, 1);
|
||||||
std::string cnt = argFromVec(subopts, 2);
|
std::string cnt = argFromVec(subopts, 2);
|
||||||
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
||||||
if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ false,
|
if (!user::parseId(nsjconf.get(), i_id, o_id, count,
|
||||||
|
/* is_gid= */ false,
|
||||||
/* is_newidmap= */ false)) {
|
/* is_newidmap= */ false)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -712,7 +780,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
std::string o_id = argFromVec(subopts, 1);
|
std::string o_id = argFromVec(subopts, 1);
|
||||||
std::string cnt = argFromVec(subopts, 2);
|
std::string cnt = argFromVec(subopts, 2);
|
||||||
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
||||||
if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ true,
|
if (!user::parseId(nsjconf.get(), i_id, o_id, count,
|
||||||
|
/* is_gid= */ true,
|
||||||
/* is_newidmap= */ false)) {
|
/* is_newidmap= */ false)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -723,7 +792,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
std::string o_id = argFromVec(subopts, 1);
|
std::string o_id = argFromVec(subopts, 1);
|
||||||
std::string cnt = argFromVec(subopts, 2);
|
std::string cnt = argFromVec(subopts, 2);
|
||||||
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
||||||
if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ false,
|
if (!user::parseId(nsjconf.get(), i_id, o_id, count,
|
||||||
|
/* is_gid= */ false,
|
||||||
/* is_newidmap= */ true)) {
|
/* is_newidmap= */ true)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -734,7 +804,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
std::string o_id = argFromVec(subopts, 1);
|
std::string o_id = argFromVec(subopts, 1);
|
||||||
std::string cnt = argFromVec(subopts, 2);
|
std::string cnt = argFromVec(subopts, 2);
|
||||||
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
size_t count = strtoul(cnt.c_str(), nullptr, 0);
|
||||||
if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ true,
|
if (!user::parseId(nsjconf.get(), i_id, o_id, count,
|
||||||
|
/* is_gid= */ true,
|
||||||
/* is_newidmap= */ true)) {
|
/* is_newidmap= */ true)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -746,7 +817,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
if (dst.empty()) {
|
if (dst.empty()) {
|
||||||
dst = src;
|
dst = src;
|
||||||
}
|
}
|
||||||
if (!mnt::addMountPtTail(nsjconf.get(), src, dst, /* fstype= */ "",
|
if (!mnt::addMountPtTail(
|
||||||
|
nsjconf.get(), src, dst, /* fstype= */ "",
|
||||||
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
|
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
|
||||||
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
|
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
|
||||||
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
||||||
@ -761,7 +833,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
if (dst.empty()) {
|
if (dst.empty()) {
|
||||||
dst = src;
|
dst = src;
|
||||||
}
|
}
|
||||||
if (!mnt::addMountPtTail(nsjconf.get(), src, dst, /* fstype= */ "",
|
if (!mnt::addMountPtTail(
|
||||||
|
nsjconf.get(), src, dst, /* fstype= */ "",
|
||||||
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
|
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
|
||||||
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
|
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
|
||||||
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
||||||
@ -770,7 +843,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 'T': {
|
case 'T': {
|
||||||
if (!mnt::addMountPtTail(nsjconf.get(), "", optarg, /* fstype= */ "tmpfs",
|
if (!mnt::addMountPtTail(
|
||||||
|
nsjconf.get(), "", optarg, /* fstype= */ "tmpfs",
|
||||||
/* options= */ "size=4194304", 0,
|
/* options= */ "size=4194304", 0,
|
||||||
/* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true,
|
/* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true,
|
||||||
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
||||||
@ -792,7 +866,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
optionsStream << ":" << subopts[i];
|
optionsStream << ":" << subopts[i];
|
||||||
}
|
}
|
||||||
std::string options = optionsStream.str();
|
std::string options = optionsStream.str();
|
||||||
if (!mnt::addMountPtTail(nsjconf.get(), src, dst, /* fstype= */ fs_type,
|
if (!mnt::addMountPtTail(
|
||||||
|
nsjconf.get(), src, dst, /* fstype= */ fs_type,
|
||||||
/* options= */ options, /* flags= */ 0,
|
/* options= */ options, /* flags= */ 0,
|
||||||
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
|
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
|
||||||
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
||||||
@ -804,7 +879,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
std::vector<std::string> subopts = util::strSplit(optarg, ':');
|
std::vector<std::string> subopts = util::strSplit(optarg, ':');
|
||||||
std::string src = argFromVec(subopts, 0);
|
std::string src = argFromVec(subopts, 0);
|
||||||
std::string dst = argFromVec(subopts, 1);
|
std::string dst = argFromVec(subopts, 1);
|
||||||
if (!mnt::addMountPtTail(nsjconf.get(), src, dst, /* fstype= */ "",
|
if (!mnt::addMountPtTail(
|
||||||
|
nsjconf.get(), src, dst, /* fstype= */ "",
|
||||||
/* options= */ "", /* flags= */ 0,
|
/* options= */ "", /* flags= */ 0,
|
||||||
/* is_dir= */ mnt::NS_DIR_NO, /* is_mandatory= */ true,
|
/* is_dir= */ mnt::NS_DIR_NO, /* is_mandatory= */ true,
|
||||||
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
|
||||||
@ -891,7 +967,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
nsjconf->cgroup_pids_parent = optarg;
|
nsjconf->cgroup_pids_parent = optarg;
|
||||||
break;
|
break;
|
||||||
case 0x821:
|
case 0x821:
|
||||||
nsjconf->cgroup_net_cls_classid = (unsigned int)strtoul(optarg, NULL, 0);
|
nsjconf->cgroup_net_cls_classid =
|
||||||
|
(unsigned int)strtoul(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 0x822:
|
case 0x822:
|
||||||
nsjconf->cgroup_net_cls_mount = optarg;
|
nsjconf->cgroup_net_cls_mount = optarg;
|
||||||
|
Loading…
Reference in New Issue
Block a user