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 },
...@@ -44,13 +45,14 @@ static struct option options[] = { ...@@ -44,13 +45,14 @@ static struct option options[] = {
static void usage(void) { static void usage(void) {
fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n" fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n"
"Common options :\n" "Common options :\n"
" -j, --threads=N Threads to run concurrently\n" " -j, --threads=N Threads to run concurrently\n"
" (default: 5, use 1 for no threading)\n" " (default: 5, use 1 for no threading)\n"
" -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"
" -q, --quiet Don't produce any output\n" " -m, --modes=<mode,mode,...> Modes to run (create, start, stop, destroy)\n"
" -?, --help Give this help list\n" " -q, --quiet Don't produce any output\n"
" -?, --help Give this help list\n"
"\n" "\n"
"Mandatory or optional arguments to long options are also mandatory or optional\n" "Mandatory or optional arguments to long options are also mandatory or optional\n"
"for any corresponding short options.\n\n"); "for any corresponding short options.\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