Unverified Commit 15090139 by Serge Hallyn Committed by GitHub

Merge pull request #2042 from brauner/2017-12-15/bugfixes

start: tweaks + bugfixes
parents da5f5e3f c3184275
...@@ -290,7 +290,7 @@ lxc_create_SOURCES = tools/lxc_create.c tools/arguments.c ...@@ -290,7 +290,7 @@ lxc_create_SOURCES = tools/lxc_create.c tools/arguments.c
lxc_snapshot_SOURCES = tools/lxc_snapshot.c tools/arguments.c lxc_snapshot_SOURCES = tools/lxc_snapshot.c tools/arguments.c
lxc_usernsexec_SOURCES = tools/lxc_usernsexec.c tools/arguments.c lxc_usernsexec_SOURCES = tools/lxc_usernsexec.c tools/arguments.c
lxc_checkpoint_SOURCES = tools/lxc_checkpoint.c tools/arguments.c lxc_checkpoint_SOURCES = tools/lxc_checkpoint.c tools/arguments.c
lxc_user_nic_SOURCES = lxc_user_nic.c network.c network.h tools/arguments.c lxc_user_nic_SOURCES = lxc_user_nic.c namespace.c network.c tools/arguments.c
lxc_monitord_SOURCES = lxc_monitord.c tools/arguments.c lxc_monitord_SOURCES = lxc_monitord.c tools/arguments.c
if ENABLE_DEPRECATED if ENABLE_DEPRECATED
...@@ -304,7 +304,7 @@ endif ...@@ -304,7 +304,7 @@ endif
if HAVE_STATIC_LIBCAP if HAVE_STATIC_LIBCAP
sbin_PROGRAMS += init.lxc.static sbin_PROGRAMS += init.lxc.static
init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c parse.c init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c parse.c namespace.c
if !HAVE_GETLINE if !HAVE_GETLINE
if HAVE_FGETLN if HAVE_FGETLN
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <sys/un.h> #include <sys/un.h>
#include "log.h" #include "log.h"
#include "utils.h"
lxc_log_define(lxc_af_unix, lxc); lxc_log_define(lxc_af_unix, lxc);
...@@ -217,7 +218,7 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size) ...@@ -217,7 +218,7 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
struct iovec iov; struct iovec iov;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct ucred cred = { struct ucred cred = {
.pid = getpid(), .uid = getuid(), .gid = getgid(), .pid = lxc_raw_getpid(), .uid = getuid(), .gid = getgid(),
}; };
char cmsgbuf[CMSG_SPACE(sizeof(cred))] = {0}; char cmsgbuf[CMSG_SPACE(sizeof(cred))] = {0};
char buf[1] = {0}; char buf[1] = {0};
......
...@@ -1121,7 +1121,7 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1121,7 +1121,7 @@ int lxc_attach(const char *name, const char *lxcpath,
} }
} }
pid = syscall(SYS_getpid); pid = lxc_raw_getpid();
for (i = 0; i < LXC_NS_MAX; i++) { for (i = 0; i < LXC_NS_MAX; i++) {
int j, saved_errno; int j, saved_errno;
......
...@@ -764,7 +764,7 @@ static struct cgroup_process_info *lxc_cgroup_process_info_get_self(struct cgrou ...@@ -764,7 +764,7 @@ static struct cgroup_process_info *lxc_cgroup_process_info_get_self(struct cgrou
struct cgroup_process_info *i; struct cgroup_process_info *i;
i = lxc_cgroup_process_info_getx("/proc/self/cgroup", meta); i = lxc_cgroup_process_info_getx("/proc/self/cgroup", meta);
if (!i) if (!i)
i = lxc_cgroup_process_info_get(getpid(), meta); i = lxc_cgroup_process_info_get(lxc_raw_getpid(), meta);
return i; return i;
} }
...@@ -2480,7 +2480,7 @@ static bool cgfs_escape(void *hdata) ...@@ -2480,7 +2480,7 @@ static bool cgfs_escape(void *hdata)
if (!f) if (!f)
goto out; goto out;
written = fprintf(f, "%d\n", getpid()); written = fprintf(f, "%d\n", lxc_raw_getpid());
fclose(f); fclose(f);
if (written < 0) { if (written < 0) {
SYSERROR("writing tasks failed\n"); SYSERROR("writing tasks failed\n");
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "error.h" #include "error.h"
#include "commands.h" #include "commands.h"
#include "list.h" #include "list.h"
#include "namespace.h"
#include "conf.h" #include "conf.h"
#include "utils.h" #include "utils.h"
#include "log.h" #include "log.h"
...@@ -303,7 +304,7 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path ...@@ -303,7 +304,7 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path
static bool cgm_escape(void *hdata) static bool cgm_escape(void *hdata)
{ {
bool ret = true, cgm_needs_disconnect = false; bool ret = true, cgm_needs_disconnect = false;
pid_t me = getpid(); pid_t me = lxc_raw_getpid();
char **slist = subsystems; char **slist = subsystems;
int i; int i;
...@@ -359,6 +360,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path, ...@@ -359,6 +360,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
uid_t newuid) uid_t newuid)
{ {
int sv[2] = {-1, -1}, optval = 1, ret = -1; int sv[2] = {-1, -1}, optval = 1, ret = -1;
pid_t pid_self;
char buf[1]; char buf[1];
struct pollfd fds; struct pollfd fds;
...@@ -395,7 +397,9 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path, ...@@ -395,7 +397,9 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
ERROR("Error getting reply from server over socketpair"); ERROR("Error getting reply from server over socketpair");
goto out; goto out;
} }
if (send_creds(sv[0], getpid(), getuid(), getgid())) {
pid_self = lxc_raw_getpid();
if (send_creds(sv[0], pid_self, getuid(), getgid())) {
SYSERROR("Error sending pid over SCM_CREDENTIAL"); SYSERROR("Error sending pid over SCM_CREDENTIAL");
goto out; goto out;
} }
...@@ -410,7 +414,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path, ...@@ -410,7 +414,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
ERROR("Error getting reply from server over socketpair"); ERROR("Error getting reply from server over socketpair");
goto out; goto out;
} }
if (send_creds(sv[0], getpid(), newuid, 0)) { if (send_creds(sv[0], pid_self, newuid, 0)) {
SYSERROR("Error sending pid over SCM_CREDENTIAL"); SYSERROR("Error sending pid over SCM_CREDENTIAL");
goto out; goto out;
} }
...@@ -898,7 +902,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena ...@@ -898,7 +902,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
exit(1); exit(1);
} }
*cglast = '\0'; *cglast = '\0';
if (!lxc_cgmanager_enter(getpid(), controller, cgroup, abs_cgroup_supported())) { if (!lxc_cgmanager_enter(lxc_raw_getpid(), controller, cgroup, abs_cgroup_supported())) {
WARN("Failed to enter container cgroup %s:%s", controller, cgroup); WARN("Failed to enter container cgroup %s:%s", controller, cgroup);
ret = write(outp, &len, sizeof(len)); ret = write(outp, &len, sizeof(len));
if (ret != sizeof(len)) if (ret != sizeof(len))
...@@ -1038,7 +1042,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena ...@@ -1038,7 +1042,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
exit(1); exit(1);
} }
*cglast = '\0'; *cglast = '\0';
if (!lxc_cgmanager_enter(getpid(), controller, cgroup, abs_cgroup_supported())) { if (!lxc_cgmanager_enter(lxc_raw_getpid(), controller, cgroup, abs_cgroup_supported())) {
ERROR("Failed to enter container cgroup %s:%s", controller, cgroup); ERROR("Failed to enter container cgroup %s:%s", controller, cgroup);
ret = write(outp, &retval, sizeof(retval)); ret = write(outp, &retval, sizeof(retval));
if (ret != sizeof(retval)) if (ret != sizeof(retval))
...@@ -1278,7 +1282,7 @@ static bool verify_final_subsystems(const char *cgroup_use) ...@@ -1278,7 +1282,7 @@ static bool verify_final_subsystems(const char *cgroup_use)
} }
cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern"); cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern");
i = snprintf(tmpnam, 50, "lxcprobe-%d", getpid()); i = snprintf(tmpnam, 50, "lxcprobe-%d", lxc_raw_getpid());
if (i < 0 || i >= 50) { if (i < 0 || i >= 50) {
ERROR("Attack - format string modified?"); ERROR("Attack - format string modified?");
return false; return false;
......
...@@ -414,7 +414,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd) ...@@ -414,7 +414,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
console->peerpty.busy = sockfd; console->peerpty.busy = sockfd;
lxc_console_mainloop_add_peer(console); lxc_console_mainloop_add_peer(console);
DEBUG("%d %s peermaster:%d sockfd:%d", getpid(), __FUNCTION__, console->peerpty.master, sockfd); DEBUG("%d %s peermaster:%d sockfd:%d", lxc_raw_getpid(), __FUNCTION__, console->peerpty.master, sockfd);
return 0; return 0;
err1: err1:
......
...@@ -135,7 +135,7 @@ again: ...@@ -135,7 +135,7 @@ again:
*/ */
static bool apparmor_am_unconfined(void) static bool apparmor_am_unconfined(void)
{ {
char *p = apparmor_process_label_get(getpid()); char *p = apparmor_process_label_get(lxc_raw_getpid());
bool ret = false; bool ret = false;
if (!p || strcmp(p, "unconfined") == 0) if (!p || strcmp(p, "unconfined") == 0)
ret = true; ret = true;
...@@ -186,7 +186,7 @@ static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf ...@@ -186,7 +186,7 @@ static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf
return 0; return 0;
} }
curlabel = apparmor_process_label_get(getpid()); curlabel = apparmor_process_label_get(lxc_raw_getpid());
if (!aa_stacking_supported() && aa_needs_transition(curlabel)) { if (!aa_stacking_supported() && aa_needs_transition(curlabel)) {
/* we're already confined, and stacking isn't supported */ /* we're already confined, and stacking isn't supported */
......
...@@ -40,12 +40,13 @@ ...@@ -40,12 +40,13 @@
#include "error.h" #include "error.h"
#include "initutils.h" #include "initutils.h"
#include "log.h" #include "log.h"
#include "namespace.h"
#include "parse.h" #include "parse.h"
#include "version.h" #include "version.h"
/* option keys for long only options */ /* option keys for long only options */
#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 QUOTE(macro) #macro
#define QUOTEVAL(macro) QUOTE(macro) #define QUOTEVAL(macro) QUOTE(macro)
...@@ -61,14 +62,14 @@ static void interrupt_handler(int sig) ...@@ -61,14 +62,14 @@ static void interrupt_handler(int sig)
} }
static struct option long_options[] = { static struct option long_options[] = {
{ "name", required_argument, 0, 'n' }, { "name", required_argument, 0, 'n' },
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ "usage", no_argument, 0, OPT_USAGE }, { "usage", no_argument, 0, OPT_USAGE },
{ "version", no_argument, 0, OPT_VERSION }, { "version", no_argument, 0, OPT_VERSION },
{ "quiet", no_argument, 0, 'q' }, { "quiet", no_argument, 0, 'q' },
{ "logfile", required_argument, 0, 'o' }, { "logfile", required_argument, 0, 'o' },
{ "logpriority", required_argument, 0, 'l' }, { "logpriority", required_argument, 0, 'l' },
{ "lxcpath", required_argument, 0, 'P' }, { "lxcpath", required_argument, 0, 'P' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
static char short_options[] = "n:hqo:l:P:"; static char short_options[] = "n:hqo:l:P:";
...@@ -359,7 +360,7 @@ int main(int argc, char *argv[]) ...@@ -359,7 +360,7 @@ int main(int argc, char *argv[])
case SIGPWR: case SIGPWR:
case SIGTERM: case SIGTERM:
if (!shutdown) { if (!shutdown) {
pid_t mypid = getpid(); pid_t mypid = lxc_raw_getpid();
shutdown = 1; shutdown = 1;
prevent_forking(); prevent_forking();
...@@ -375,7 +376,7 @@ int main(int argc, char *argv[]) ...@@ -375,7 +376,7 @@ int main(int argc, char *argv[])
} }
break; break;
case SIGALRM: { case SIGALRM: {
pid_t mypid = getpid(); pid_t mypid = lxc_raw_getpid();
prevent_forking(); prevent_forking();
if (mypid != 1) { if (mypid != 1) {
......
...@@ -427,7 +427,7 @@ int main(int argc, char *argv[]) ...@@ -427,7 +427,7 @@ int main(int argc, char *argv[])
} }
NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s.", NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s.",
getpid(), mon.lxcpath); lxc_raw_getpid(), mon.lxcpath);
for (;;) { for (;;) {
ret = lxc_mainloop(&mon.descr, 1000 * 30); ret = lxc_mainloop(&mon.descr, 1000 * 30);
if (ret) { if (ret) {
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "config.h" #include "config.h"
#include "namespace.h"
#include "network.h" #include "network.h"
#include "utils.h" #include "utils.h"
...@@ -814,14 +815,16 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname, ...@@ -814,14 +815,16 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
int *container_veth_ifidx) int *container_veth_ifidx)
{ {
int ret; int ret;
pid_t pid_self;
uid_t ruid, suid, euid; uid_t ruid, suid, euid;
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
char *string_ret = NULL, *name = NULL; char *string_ret = NULL, *name = NULL;
int fd = -1, ifindex = -1, ofd = -1; int fd = -1, ifindex = -1, ofd = -1;
ofd = lxc_preserve_ns(getpid(), "net"); pid_self = lxc_raw_getpid();
ofd = lxc_preserve_ns(pid_self, "net");
if (ofd < 0) { if (ofd < 0) {
usernic_error("Failed opening network namespace path for %d", getpid()); usernic_error("Failed opening network namespace path for %d", pid_self);
return NULL; return NULL;
} }
...@@ -993,13 +996,15 @@ struct user_nic_args { ...@@ -993,13 +996,15 @@ struct user_nic_args {
static bool is_privileged_over_netns(int netns_fd) static bool is_privileged_over_netns(int netns_fd)
{ {
int ret; int ret;
pid_t pid_self;
uid_t euid, ruid, suid; uid_t euid, ruid, suid;
bool bret = false; bool bret = false;
int ofd = -1; int ofd = -1;
ofd = lxc_preserve_ns(getpid(), "net"); pid_self = lxc_raw_getpid();
ofd = lxc_preserve_ns(pid_self, "net");
if (ofd < 0) { if (ofd < 0) {
usernic_error("Failed opening network namespace path for %d", getpid()); usernic_error("Failed opening network namespace path for %d", pid_self);
return false; return false;
} }
......
...@@ -941,7 +941,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ...@@ -941,7 +941,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
/* become session leader */ /* become session leader */
ret = setsid(); ret = setsid();
if (ret < 0) if (ret < 0)
TRACE("Process %d is already process group leader", getpid()); TRACE("Process %d is already process group leader", lxc_raw_getpid());
} else { } else {
if (!am_single_threaded()) { if (!am_single_threaded()) {
ERROR("Cannot start non-daemonized container when threaded"); ERROR("Cannot start non-daemonized container when threaded");
...@@ -966,7 +966,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ...@@ -966,7 +966,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
return false; return false;
} }
if (fprintf(pid_fp, "%d\n", getpid()) < 0) { if (fprintf(pid_fp, "%d\n", lxc_raw_getpid()) < 0) {
SYSERROR("Failed to write '%s'", c->pidfile); SYSERROR("Failed to write '%s'", c->pidfile);
fclose(pid_fp); fclose(pid_fp);
pid_fp = NULL; pid_fp = NULL;
...@@ -4451,7 +4451,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c, ...@@ -4451,7 +4451,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
return false; return false;
} }
pid_outside = getpid(); pid_outside = lxc_raw_getpid();
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
ERROR("Failed to fork"); ERROR("Failed to fork");
......
...@@ -127,6 +127,23 @@ pid_t lxc_raw_clone(unsigned long flags) ...@@ -127,6 +127,23 @@ pid_t lxc_raw_clone(unsigned long flags)
#endif #endif
} }
pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags)
{
pid_t pid;
pid = lxc_raw_clone(flags);
if (pid < 0)
return -1;
/* exit() is not thread-safe and might mess with the parent's signal
* handlers and other stuff when exec() fails.
*/
if (pid == 0)
_exit(fn(args));
return pid;
}
/* Leave the user namespace at the first position in the array of structs so /* Leave the user namespace at the first position in the array of structs so
* that we always attach to it first when iterating over the struct and using * that we always attach to it first when iterating over the struct and using
* setns() to switch namespaces. This especially affects lxc_attach(): Suppose * setns() to switch namespaces. This especially affects lxc_attach(): Suppose
......
...@@ -23,8 +23,9 @@ ...@@ -23,8 +23,9 @@
#ifndef __LXC_NAMESPACE_H #ifndef __LXC_NAMESPACE_H
#define __LXC_NAMESPACE_H #define __LXC_NAMESPACE_H
#include <sys/syscall.h>
#include <sched.h> #include <sched.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "config.h" #include "config.h"
...@@ -112,11 +113,83 @@ int clone(int (*fn)(void *), void *child_stack, ...@@ -112,11 +113,83 @@ int clone(int (*fn)(void *), void *child_stack,
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ ); /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
#endif #endif
/**
* lxc_clone() - create a new process
*
* - allocate stack:
* This function allocates a new stack the size of page and passes it to the
* kernel.
*
* - support all CLONE_*flags:
* This function supports all CLONE_* flags. If in doubt or not sufficiently
* familiar with process creation in the kernel and interactions with libcs
* this function should be used.
*
* - pthread_atfork() handlers depending on libc:
* Whether this function runs pthread_atfork() handlers depends on the
* corresponding libc wrapper. glibc currently does not run pthread_atfork()
* handlers but does not guarantee that they are not. Other libcs might or
* might not run pthread_atfork() handlers. If you require guarantees please
* refer to the lxc_raw_clone*() functions below.
*
* - should call lxc_raw_getpid():
* The child should use lxc_raw_getpid() to retrieve its pid.
*/
extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags); extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags);
/**
* lxc_raw_clone() - create a new process
*
* - fork() behavior:
* This function returns 0 in the child and > 0 in the parent.
*
* - copy-on-write:
* This function does not allocate a new stack and relies on copy-on-write
* semantics.
*
* - supports subset of ClONE_* flags:
* lxc_raw_clone() intentionally only supports a subset of the flags available
* to the actual system call. Please refer to the implementation what flags
* cannot be used. Also, please don't assume that just because a flag isn't
* explicitly checked for as being unsupported that it is supported. If in
* doubt or not sufficiently familiar with process creation in the kernel and
* interactions with libcs this function should be used.
*
* - no pthread_atfork() handlers:
* This function circumvents - as much as this this is possible - any libc
* wrappers and thus does not run any pthread_atfork() handlers. Make sure
* that this is safe to do in the context you are trying to call this
* function.
*
* - must call lxc_raw_getpid():
* The child must use lxc_raw_getpid() to retrieve its pid.
*/
extern pid_t lxc_raw_clone(unsigned long flags); extern pid_t lxc_raw_clone(unsigned long flags);
/**
* lxc_raw_clone_cb() - create a new process
*
* - non-fork() behavior:
* Function does return pid of the child or -1 on error. Pass in a callback
* function via the "fn" argument that gets executed in the child process. The
* "args" argument is passed to "fn".
*
* All other comments that apply to lxc_raw_clone() apply to lxc_raw_clone_cb()
* as well.
*/
extern pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args,
unsigned long flags);
extern int lxc_namespace_2_cloneflag(const char *namespace); extern int lxc_namespace_2_cloneflag(const char *namespace);
extern int lxc_namespace_2_ns_idx(const char *namespace); extern int lxc_namespace_2_ns_idx(const char *namespace);
extern int lxc_fill_namespace_flags(char *flaglist, int *flags); extern int lxc_fill_namespace_flags(char *flaglist, int *flags);
/**
* Because of older glibc's pid cache (up to 2.25) whenever clone() is called
* the child must must retrieve it's own pid via lxc_raw_getpid().
*/
static inline pid_t lxc_raw_getpid(void)
{
return (pid_t) syscall(SYS_getpid);
}
#endif #endif
...@@ -2369,7 +2369,7 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler) ...@@ -2369,7 +2369,7 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
} }
ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d", ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d",
getpid(), handler->nsfd[LXC_NS_NET]); lxc_raw_getpid(), handler->nsfd[LXC_NS_NET]);
if (ret < 0 || ret >= sizeof(netns_path)) if (ret < 0 || ret >= sizeof(netns_path))
return false; return false;
...@@ -2693,7 +2693,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler) ...@@ -2693,7 +2693,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
TRACE("Moving physical network devices back to parent network namespace"); TRACE("Moving physical network devices back to parent network namespace");
oldfd = lxc_preserve_ns(getpid(), "net"); oldfd = lxc_preserve_ns(lxc_raw_getpid(), "net");
if (oldfd < 0) { if (oldfd < 0) {
SYSERROR("Failed to preserve network namespace"); SYSERROR("Failed to preserve network namespace");
return -1; return -1;
......
...@@ -726,7 +726,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -726,7 +726,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
*/ */
lxc_set_state(name, handler, STOPPING); lxc_set_state(name, handler, STOPPING);
self = getpid(); self = lxc_raw_getpid();
for (i = 0; i < LXC_NS_MAX; i++) { for (i = 0; i < LXC_NS_MAX; i++) {
if (handler->nsfd[i] < 0) if (handler->nsfd[i] < 0)
continue; continue;
...@@ -784,11 +784,6 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -784,11 +784,6 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
cgroup_destroy(handler); cgroup_destroy(handler);
/* This function will try to connect to the legacy lxc-monitord state
* server and only exists for backwards compatibility.
*/
lxc_monitor_send_state(name, STOPPED, handler->lxcpath);
if (handler->conf->reboot == 0) { if (handler->conf->reboot == 0) {
/* For all new state clients simply close the command socket. /* For all new state clients simply close the command socket.
* This will inform all state clients that the container is * This will inform all state clients that the container is
...@@ -798,6 +793,18 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -798,6 +793,18 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
*/ */
close(handler->conf->maincmd_fd); close(handler->conf->maincmd_fd);
handler->conf->maincmd_fd = -1; handler->conf->maincmd_fd = -1;
TRACE("Closed command socket");
/* This function will try to connect to the legacy lxc-monitord
* state server and only exists for backwards compatibility.
*/
lxc_monitor_send_state(name, STOPPED, handler->lxcpath);
/* The command socket is closed so no one can acces the command
* socket anymore so there's no need to lock it.
*/
handler->state = STOPPED;
TRACE("Set container state to \"STOPPED\"");
} else { } else {
lxc_set_state(name, handler, STOPPED); lxc_set_state(name, handler, STOPPED);
} }
...@@ -1006,7 +1013,7 @@ static int do_start(void *data) ...@@ -1006,7 +1013,7 @@ static int do_start(void *data)
} }
if (handler->clone_flags & CLONE_NEWCGROUP) { if (handler->clone_flags & CLONE_NEWCGROUP) {
fd = lxc_preserve_ns(syscall(SYS_getpid), "cgroup"); fd = lxc_preserve_ns(lxc_raw_getpid(), "cgroup");
if (fd < 0) { if (fd < 0) {
ERROR("%s - Failed to preserve cgroup namespace", strerror(errno)); ERROR("%s - Failed to preserve cgroup namespace", strerror(errno));
close(handler->data_sock[0]); close(handler->data_sock[0]);
...@@ -1263,8 +1270,8 @@ int resolve_clone_flags(struct lxc_handler *handler) ...@@ -1263,8 +1270,8 @@ int resolve_clone_flags(struct lxc_handler *handler)
* not reset anymore. * not reset anymore.
* However, if for whatever reason you - dear commiter - somehow need to get the * However, if for whatever reason you - dear commiter - somehow need to get the
* pid of the dummy intermediate process for do_share_ns() you need to call * pid of the dummy intermediate process for do_share_ns() you need to call
* syscall(__NR_getpid) directly. The next lxc_clone() call does not employ * lxc_raw_getpid(). The next lxc_raw_clone() call does not employ CLONE_VM and
* CLONE_VM and will be fine. * will be fine.
*/ */
static inline int do_share_ns(void *arg) static inline int do_share_ns(void *arg)
{ {
...@@ -1284,7 +1291,7 @@ static inline int do_share_ns(void *arg) ...@@ -1284,7 +1291,7 @@ static inline int do_share_ns(void *arg)
flags = handler->on_clone_flags; flags = handler->on_clone_flags;
flags |= CLONE_PARENT; flags |= CLONE_PARENT;
handler->pid = lxc_clone(do_start, handler, flags); handler->pid = lxc_raw_clone_cb(do_start, handler, flags);
if (handler->pid < 0) if (handler->pid < 0)
return -1; return -1;
...@@ -1414,7 +1421,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1414,7 +1421,7 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net; goto out_delete_net;
} }
} else { } else {
handler->pid = lxc_clone(do_start, handler, handler->on_clone_flags); handler->pid = lxc_raw_clone_cb(do_start, handler, handler->on_clone_flags);
} }
if (handler->pid < 0) { if (handler->pid < 0) {
SYSERROR(LXC_CLONE_ERROR); SYSERROR(LXC_CLONE_ERROR);
......
...@@ -1701,7 +1701,7 @@ int lxc_mount_proc_if_needed(const char *rootfs) ...@@ -1701,7 +1701,7 @@ int lxc_mount_proc_if_needed(const char *rootfs)
return -1; return -1;
} }
mypid = getpid(); mypid = lxc_raw_getpid();
INFO("I am %d, /proc/self points to \"%s\"", mypid, link); INFO("I am %d, /proc/self points to \"%s\"", mypid, link);
if (lxc_safe_int(link, &link_to_pid) < 0) if (lxc_safe_int(link, &link_to_pid) < 0)
...@@ -2389,17 +2389,6 @@ int lxc_make_tmpfile(char *template, bool rm) ...@@ -2389,17 +2389,6 @@ int lxc_make_tmpfile(char *template, bool rm)
return fd; return fd;
} }
uint64_t lxc_getpagesize(void)
{
int64_t pgsz;
pgsz = sysconf(_SC_PAGESIZE);
if (pgsz <= 0)
pgsz = 1 << 12;
return pgsz;
}
int parse_byte_size_string(const char *s, int64_t *converted) int parse_byte_size_string(const char *s, int64_t *converted)
{ {
int ret, suffix_len; int ret, suffix_len;
......
...@@ -519,7 +519,17 @@ extern bool has_fs_type(const char *path, fs_type_magic magic_val); ...@@ -519,7 +519,17 @@ extern bool has_fs_type(const char *path, fs_type_magic magic_val);
extern bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val); extern bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val);
extern bool lxc_nic_exists(char *nic); extern bool lxc_nic_exists(char *nic);
extern int lxc_make_tmpfile(char *template, bool rm); extern int lxc_make_tmpfile(char *template, bool rm);
extern uint64_t lxc_getpagesize(void);
static inline uint64_t lxc_getpagesize(void)
{
int64_t pgsz;
pgsz = sysconf(_SC_PAGESIZE);
if (pgsz <= 0)
pgsz = 1 << 12;
return pgsz;
}
/* If n is not a power of 2 this function will return the next power of 2 /* If n is not a power of 2 this function will return the next power of 2
* greater than that number. Note that this function always returns the *next* * greater than that number. Note that this function always returns the *next*
......
...@@ -116,9 +116,16 @@ int main(int argc, char *argv[]) ...@@ -116,9 +116,16 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
pid = lxc_raw_clone(CLONE_NEWUSER | CLONE_NEWCGROUP | CLONE_NEWNS | flags |= CLONE_NEWUSER;
CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWIPC | if (cgns_supported())
CLONE_NEWPID | CLONE_NEWUTS); flags |= CLONE_NEWCGROUP;
flags |= CLONE_NEWNS;
flags |= CLONE_NEWIPC;
flags |= CLONE_NEWNET;
flags |= CLONE_NEWIPC;
flags |= CLONE_NEWPID;
flags |= CLONE_NEWUTS;
pid = lxc_raw_clone(flags);
if (pid < 0) { if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER " lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER "
"| CLONE_NEWCGROUP | CLONE_NEWNS | " "| CLONE_NEWCGROUP | CLONE_NEWNS | "
...@@ -138,15 +145,6 @@ int main(int argc, char *argv[]) ...@@ -138,15 +145,6 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
flags |= CLONE_NEWUSER;
if (cgns_supported())
flags |= CLONE_NEWCGROUP;
flags |= CLONE_NEWNS;
flags |= CLONE_NEWIPC;
flags |= CLONE_NEWNET;
flags |= CLONE_NEWIPC;
flags |= CLONE_NEWPID;
flags |= CLONE_NEWUTS;
pid = lxc_raw_clone(flags); pid = lxc_raw_clone(flags);
if (pid < 0) { if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER " lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER "
...@@ -165,9 +163,81 @@ int main(int argc, char *argv[]) ...@@ -165,9 +163,81 @@ int main(int argc, char *argv[])
status = wait_for_pid(pid); status = wait_for_pid(pid);
if (status == 0) { if (status == 0) {
lxc_error("%s\n", "Failed to retrieve correct exit status"); lxc_error("%s\n", "Failed to retrieve correct exit status");
exit(EXIT_FAILURE);
}
pid = lxc_raw_clone(CLONE_VFORK);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_VFORK);");
exit(EXIT_FAILURE);
}
if (pid == 0) {
lxc_error("%s\n", "Child will exit(EXIT_SUCCESS)");
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
status = wait_for_pid(pid);
if (status != 0) {
lxc_error("%s\n", "Failed to retrieve correct exit status");
exit(EXIT_FAILURE);
}
pid = lxc_raw_clone(CLONE_VFORK);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_VFORK);");
exit(EXIT_FAILURE);
}
if (pid == 0) {
lxc_error("%s\n", "Child will exit(EXIT_FAILURE)");
exit(EXIT_FAILURE);
}
status = wait_for_pid(pid);
if (status == 0) {
lxc_error("%s\n", "Failed to retrieve correct exit status");
exit(EXIT_FAILURE);
}
pid = lxc_raw_clone(CLONE_FILES);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_FILES);");
exit(EXIT_FAILURE);
}
if (pid == 0) {
lxc_error("%s\n", "Child will exit(EXIT_SUCCESS)");
exit(EXIT_SUCCESS);
}
status = wait_for_pid(pid);
if (status != 0) {
lxc_error("%s\n", "Failed to retrieve correct exit status");
exit(EXIT_FAILURE);
}
pid = lxc_raw_clone(CLONE_FILES);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_FILES);");
exit(EXIT_FAILURE);
}
if (pid == 0) {
lxc_error("%s\n", "Child will exit(EXIT_FAILURE)");
exit(EXIT_FAILURE);
}
status = wait_for_pid(pid);
if (status == 0) {
lxc_error("%s\n", "Failed to retrieve correct exit status");
exit(EXIT_FAILURE);
}
lxc_debug("%s\n", "All lxc_raw_clone() tests successful"); lxc_debug("%s\n", "All lxc_raw_clone() tests successful");
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
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