Commit 3d67411d by Marek Majkowski

Merge remote-tracking branch 'lxc/master' into share-namespaces

parents 3c93577b bdb3f441
...@@ -135,6 +135,9 @@ int lxc_abstract_unix_connect(const char *path) ...@@ -135,6 +135,9 @@ int lxc_abstract_unix_connect(const char *path)
if (connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len)) { if (connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len)) {
int tmp = errno; int tmp = errno;
/* special case to connect to older containers */
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0)
return fd;
process_lock(); process_lock();
close(fd); close(fd);
process_unlock(); process_unlock();
......
...@@ -49,25 +49,6 @@ ...@@ -49,25 +49,6 @@
#include "config.h" #include "config.h"
#include "utils.h" #include "utils.h"
#ifndef HAVE_GETLINE
#ifdef HAVE_FGETLN
#include <../include/getline.h>
#endif
#endif
/* Define setns() if missing from the C library */
#ifndef HAVE_SETNS
static inline int setns(int fd, int nstype)
{
#ifdef __NR_setns
return syscall(__NR_setns, fd, nstype);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif
#if ISTEST #if ISTEST
#define CONF_FILE "/tmp/lxc-usernet" #define CONF_FILE "/tmp/lxc-usernet"
#define DB_FILE "/tmp/nics" #define DB_FILE "/tmp/nics"
...@@ -76,7 +57,6 @@ static inline int setns(int fd, int nstype) ...@@ -76,7 +57,6 @@ static inline int setns(int fd, int nstype)
#define DB_FILE LXC_USERNIC_DB #define DB_FILE LXC_USERNIC_DB
#endif #endif
#include "nl.h" #include "nl.h"
#ifndef IFLA_LINKMODE #ifndef IFLA_LINKMODE
......
...@@ -491,7 +491,7 @@ static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout) ...@@ -491,7 +491,7 @@ static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout)
} }
static bool wait_on_daemonized_start(struct lxc_container *c) static bool wait_on_daemonized_start(struct lxc_container *c, int pid)
{ {
/* we'll probably want to make this timeout configurable? */ /* we'll probably want to make this timeout configurable? */
int timeout = 5, ret, status; int timeout = 5, ret, status;
...@@ -500,12 +500,44 @@ static bool wait_on_daemonized_start(struct lxc_container *c) ...@@ -500,12 +500,44 @@ static bool wait_on_daemonized_start(struct lxc_container *c)
* our child is going to fork again, then exit. reap the * our child is going to fork again, then exit. reap the
* child * child
*/ */
ret = wait(&status); ret = waitpid(pid, &status, 0);
if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
DEBUG("failed waiting for first dual-fork child"); DEBUG("failed waiting for first dual-fork child");
return lxcapi_wait(c, "RUNNING", timeout); return lxcapi_wait(c, "RUNNING", timeout);
} }
static bool am_single_threaded(void)
{
struct dirent dirent, *direntp;
DIR *dir;
int count=0;
process_lock();
dir = opendir("/proc/self/task");
process_unlock();
if (!dir) {
INFO("failed to open /proc/self/task");
return false;
}
while (!readdir_r(dir, &dirent, &direntp)) {
if (!direntp)
break;
if (!strcmp(direntp->d_name, "."))
continue;
if (!strcmp(direntp->d_name, ".."))
continue;
if (++count > 1)
break;
}
process_lock();
closedir(dir);
process_unlock();
return count == 1;
}
/* /*
* I can't decide if it'd be more convenient for callers if we accept '...', * I can't decide if it'd be more convenient for callers if we accept '...',
* or a null-terminated array (i.e. execl vs execv) * or a null-terminated array (i.e. execl vs execv)
...@@ -575,7 +607,7 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv ...@@ -575,7 +607,7 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
return false; return false;
} }
if (pid != 0) if (pid != 0)
return wait_on_daemonized_start(c); return wait_on_daemonized_start(c, pid);
process_unlock(); // we're no longer sharing process_unlock(); // we're no longer sharing
/* second fork to be reparented by init */ /* second fork to be reparented by init */
...@@ -598,6 +630,11 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv ...@@ -598,6 +630,11 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
open("/dev/null", O_RDWR); open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR); open("/dev/null", O_RDWR);
setsid(); setsid();
} else {
if (!am_single_threaded()) {
ERROR("Cannot start non-daemonized container when threaded");
return false;
}
} }
reboot: reboot:
......
...@@ -36,6 +36,7 @@ static struct option options[] = { ...@@ -36,6 +36,7 @@ static struct option options[] = {
{ "iterations", required_argument, NULL, 'i' }, { "iterations", required_argument, NULL, 'i' },
{ "template", required_argument, NULL, 't' }, { "template", required_argument, NULL, 't' },
{ "delay", required_argument, NULL, 'd' }, { "delay", required_argument, NULL, 'd' },
{ "modes", required_argument, NULL, 'm' },
{ "quiet", no_argument, NULL, 'q' }, { "quiet", no_argument, NULL, 'q' },
{ "help", no_argument, NULL, '?' }, { "help", no_argument, NULL, '?' },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
...@@ -49,6 +50,7 @@ static void usage(void) { ...@@ -49,6 +50,7 @@ static void usage(void) {
" -i, --iterations=N Number times to run the test (default: 1)\n" " -i, --iterations=N Number times to run the test (default: 1)\n"
" -t, --template=t Template to use (default: busybox)\n" " -t, --template=t Template to use (default: busybox)\n"
" -d, --delay=N Delay in seconds between start and stop\n" " -d, --delay=N Delay in seconds between start and stop\n"
" -m, --modes=<mode,mode,...> Modes to run (create, start, stop, destroy)\n"
" -q, --quiet Don't produce any output\n" " -q, --quiet Don't produce any output\n"
" -?, --help Give this help list\n" " -?, --help Give this help list\n"
"\n" "\n"
...@@ -135,11 +137,12 @@ int main(int argc, char *argv[]) { ...@@ -135,11 +137,12 @@ int main(int argc, char *argv[]) {
pthread_t *threads; pthread_t *threads;
struct thread_args *args; struct thread_args *args;
char *modes[] = {"create", "start", "stop", "destroy", NULL}; char *modes_default[] = {"create", "start", "stop", "destroy", NULL};
char **modes = modes_default;
pthread_attr_init(&attr); pthread_attr_init(&attr);
while ((opt = getopt_long(argc, argv, "j:i:t:d:q", options, NULL)) != -1) { while ((opt = getopt_long(argc, argv, "j:i:t:d:m:q", options, NULL)) != -1) {
switch(opt) { switch(opt) {
case 'j': case 'j':
nthreads = atoi(optarg); nthreads = atoi(optarg);
...@@ -156,6 +159,19 @@ int main(int argc, char *argv[]) { ...@@ -156,6 +159,19 @@ int main(int argc, char *argv[]) {
case 'q': case 'q':
quiet = 1; quiet = 1;
break; break;
case 'm': {
char *mode_tok, *tok, *saveptr;
modes = NULL;
for (i = 0, mode_tok = optarg;
(tok = strtok_r(mode_tok, ",", &saveptr));
i++, mode_tok = NULL) {
modes = realloc(modes, sizeof(*modes) * (i+2));
modes[i] = tok;
}
modes[i] = NULL;
break;
}
default: /* '?' */ default: /* '?' */
usage(); usage();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
......
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