Unverified Commit ec09a5a2 by Christian Brauner Committed by GitHub

Merge pull request #2008 from tych0/share-ns-in-execute

add --share-$NS= support to lxc-execute
parents 2e3890af c379af4c
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
#define OPT_USAGE 0x1000 #define OPT_USAGE 0x1000
#define OPT_VERSION OPT_USAGE - 1 #define OPT_VERSION OPT_USAGE - 1
#define QUOTE(macro) #macro
#define QUOTEVAL(macro) QUOTE(macro)
lxc_log_define(lxc_init, lxc); lxc_log_define(lxc_init, lxc);
static sig_atomic_t was_interrupted = 0; static sig_atomic_t was_interrupted = 0;
...@@ -92,6 +95,95 @@ static struct arguments my_args = { ...@@ -92,6 +95,95 @@ static struct arguments my_args = {
.shortopts = short_options .shortopts = short_options
}; };
static void prevent_forking(void)
{
FILE *f;
char name[MAXPATHLEN], path[MAXPATHLEN];
int ret;
f = fopen("/proc/self/cgroup", "r");
if (!f) {
SYSERROR("Failed to open \"/proc/self/cgroup\"");
return;
}
while (!feof(f)) {
int fd, i;
if (1 != fscanf(f, "%*d:%" QUOTEVAL(MAXPATHLEN) "s", name)) {
ERROR("Failed to parse \"/proc/self/cgroup\"");
goto out;
}
path[0] = 0;
for (i = 0; i < sizeof(name); i++) {
if (name[i] == ':') {
name[i] = 0;
strncpy(path, name + i + 1, sizeof(path));
break;
}
}
if (strcmp(name, "pids"))
continue;
ret = snprintf(name, sizeof(name), "/sys/fs/cgroup/pids/%s/pids.max", path);
if (ret < 0 || (size_t)ret >= sizeof(path)) {
ERROR("Failed to create string");
goto out;
}
fd = open(name, O_WRONLY);
if (fd < 0) {
SYSERROR("Failed to open \"%s\"", name);
goto out;
}
if (write(fd, "1", 1) != 1)
SYSERROR("Failed to write to \"%s\"", name);
close(fd);
break;
}
out:
fclose(f);
}
static void kill_children(pid_t pid)
{
FILE *f;
char path[PATH_MAX];
int ret;
ret = snprintf(path, sizeof(path), "/proc/%d/task/%d/children", pid, pid);
if (ret < 0 || (size_t)ret >= sizeof(path)) {
ERROR("Failed to create string");
return;
}
f = fopen(path, "r");
if (!f) {
SYSERROR("Failed to open %s", path);
return;
}
while (!feof(f)) {
pid_t pid;
if (fscanf(f, "%d ", &pid) != 1) {
ERROR("Failed to retrieve pid");
fclose(f);
return;
}
kill_children(pid);
kill(pid, SIGKILL);
}
fclose(f);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, ret; int i, ret;
...@@ -257,20 +349,35 @@ int main(int argc, char *argv[]) ...@@ -257,20 +349,35 @@ int main(int argc, char *argv[])
case SIGPWR: case SIGPWR:
case SIGTERM: case SIGTERM:
if (!shutdown) { if (!shutdown) {
pid_t mypid = getpid();
shutdown = 1; shutdown = 1;
prevent_forking();
if (mypid != 1) {
kill_children(mypid);
} else {
ret = kill(-1, SIGTERM); ret = kill(-1, SIGTERM);
if (ret < 0) if (ret < 0)
DEBUG("%s - Failed to send SIGTERM to " DEBUG("%s - Failed to send SIGTERM to "
"all children", strerror(errno)); "all children", strerror(errno));
}
alarm(1); alarm(1);
} }
break; break;
case SIGALRM: case SIGALRM: {
ret = kill(-1, SIGKILL); pid_t mypid = getpid();
prevent_forking();
if (mypid != 1) {
kill_children(mypid);
} else {
ret = kill(-1, SIGTERM);
if (ret < 0) if (ret < 0)
DEBUG("%s - Failed to send SIGKILL to all " DEBUG("%s - Failed to send SIGTERM to "
"children", strerror(errno)); "all children", strerror(errno));
}
break; break;
}
default: default:
ret = kill(pid, was_interrupted); ret = kill(pid, was_interrupted);
if (ret < 0) if (ret < 0)
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "arguments.h" #include "arguments.h"
#include "utils.h" #include "utils.h"
#include "version.h" #include "version.h"
#include "namespace.h"
static int build_shortopts(const struct option *a_options, char *a_shortopts, static int build_shortopts(const struct option *a_options, char *a_shortopts,
size_t a_size) size_t a_size)
...@@ -289,3 +290,34 @@ int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str) ...@@ -289,3 +290,34 @@ int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str)
return (int)val; return (int)val;
} }
bool lxc_setup_shared_ns(struct lxc_arguments *args, struct lxc_container *c)
{
int i;
for (i = 0; i < LXC_NS_MAX; i++) {
const char *key, *value;
value = args->share_ns[i];
if (!value)
continue;
if (i == LXC_NS_NET)
key = "lxc.namespace.net";
else if (i == LXC_NS_IPC)
key = "lxc.namespace.ipc";
else if (i == LXC_NS_UTS)
key = "lxc.namespace.uts";
else if (i == LXC_NS_PID)
key = "lxc.namespace.pid";
else
continue;
if (!c->set_config_item(c, key, value)) {
lxc_error(args, "Failed to set \"%s = %s\"", key, value);
return false;
}
}
return true;
}
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <lxc/lxccontainer.h>
struct lxc_arguments; struct lxc_arguments;
...@@ -159,6 +160,10 @@ struct lxc_arguments { ...@@ -159,6 +160,10 @@ struct lxc_arguments {
#define OPT_USAGE 0x1000 #define OPT_USAGE 0x1000
#define OPT_VERSION OPT_USAGE - 1 #define OPT_VERSION OPT_USAGE - 1
#define OPT_RCFILE OPT_USAGE - 2 #define OPT_RCFILE OPT_USAGE - 2
#define OPT_SHARE_NET OPT_USAGE - 3
#define OPT_SHARE_IPC OPT_USAGE - 4
#define OPT_SHARE_UTS OPT_USAGE - 5
#define OPT_SHARE_PID OPT_USAGE - 6
extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, extern int lxc_arguments_parse(struct lxc_arguments *args, int argc,
char *const argv[]); char *const argv[]);
...@@ -170,4 +175,6 @@ extern int lxc_arguments_str_to_int(struct lxc_arguments *args, ...@@ -170,4 +175,6 @@ extern int lxc_arguments_str_to_int(struct lxc_arguments *args,
if (!(arg)->quiet) \ if (!(arg)->quiet) \
fprintf(stderr, "%s: " fmt "\n", (arg)->progname, ##args) fprintf(stderr, "%s: " fmt "\n", (arg)->progname, ##args)
extern bool lxc_setup_shared_ns(struct lxc_arguments *args, struct lxc_container *c);
#endif /* __LXC_ARGUMENTS_H */ #endif /* __LXC_ARGUMENTS_H */
...@@ -63,6 +63,10 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) ...@@ -63,6 +63,10 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
case 'g': case 'g':
if (lxc_safe_uint(arg, &args->gid) < 0) if (lxc_safe_uint(arg, &args->gid) < 0)
return -1; return -1;
case OPT_SHARE_NET: args->share_ns[LXC_NS_NET] = arg; break;
case OPT_SHARE_IPC: args->share_ns[LXC_NS_IPC] = arg; break;
case OPT_SHARE_UTS: args->share_ns[LXC_NS_UTS] = arg; break;
case OPT_SHARE_PID: args->share_ns[LXC_NS_PID] = arg; break;
} }
return 0; return 0;
} }
...@@ -73,6 +77,10 @@ static const struct option my_longopts[] = { ...@@ -73,6 +77,10 @@ static const struct option my_longopts[] = {
{"define", required_argument, 0, 's'}, {"define", required_argument, 0, 's'},
{"uid", required_argument, 0, 'u'}, {"uid", required_argument, 0, 'u'},
{"gid", required_argument, 0, 'g'}, {"gid", required_argument, 0, 'g'},
{"share-net", required_argument, 0, OPT_SHARE_NET},
{"share-ipc", required_argument, 0, OPT_SHARE_IPC},
{"share-uts", required_argument, 0, OPT_SHARE_UTS},
{"share-pid", required_argument, 0, OPT_SHARE_PID},
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
...@@ -189,6 +197,11 @@ int main(int argc, char *argv[]) ...@@ -189,6 +197,11 @@ int main(int argc, char *argv[])
if (my_args.gid) if (my_args.gid)
c->lxc_conf->init_gid = my_args.gid; c->lxc_conf->init_gid = my_args.gid;
if (!lxc_setup_shared_ns(&my_args, c)) {
lxc_container_put(c);
exit(EXIT_FAILURE);
}
c->daemonize = my_args.daemonize == 1; c->daemonize = my_args.daemonize == 1;
bret = c->start(c, 1, my_args.argv); bret = c->start(c, 1, my_args.argv);
if (c->daemonize) if (c->daemonize)
......
...@@ -50,11 +50,6 @@ ...@@ -50,11 +50,6 @@
#include "confile.h" #include "confile.h"
#include "arguments.h" #include "arguments.h"
#define OPT_SHARE_NET OPT_USAGE + 1
#define OPT_SHARE_IPC OPT_USAGE + 2
#define OPT_SHARE_UTS OPT_USAGE + 3
#define OPT_SHARE_PID OPT_USAGE + 4
static struct lxc_list defines; static struct lxc_list defines;
static int ensure_path(char **confpath, const char *path) static int ensure_path(char **confpath, const char *path)
...@@ -152,7 +147,6 @@ Options :\n\ ...@@ -152,7 +147,6 @@ Options :\n\
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i;
struct lxc_conf *conf; struct lxc_conf *conf;
struct lxc_log log; struct lxc_log log;
const char *lxcpath; const char *lxcpath;
...@@ -284,27 +278,8 @@ int main(int argc, char *argv[]) ...@@ -284,27 +278,8 @@ int main(int argc, char *argv[])
} }
} }
for (i = 0; i < LXC_NS_MAX; i++) { if (!lxc_setup_shared_ns(&my_args, c))
const char *key, *value;
value = my_args.share_ns[i];
if (!value)
continue;
if (i == LXC_NS_NET)
key = "lxc.namespace.net";
else if (i == LXC_NS_IPC)
key = "lxc.namespace.ipc";
else if (i == LXC_NS_UTS)
key = "lxc.namespace.uts";
else if (i == LXC_NS_PID)
key = "lxc.namespace.pid";
else
continue;
if (!c->set_config_item(c, key, value))
goto out; goto out;
}
if (!my_args.daemonize) { if (!my_args.daemonize) {
c->want_daemonize(c, false); c->want_daemonize(c, false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment