share_ns: improve error handling

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2020-03-10 17:52:35 +01:00
parent 7fa9063089
commit 2580145fe9
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
3 changed files with 44 additions and 21 deletions

View File

@ -41,7 +41,9 @@ lxc_test_shortlived_SOURCES = shortlived.c
lxc_test_shutdowntest_SOURCES = shutdowntest.c lxc_test_shutdowntest_SOURCES = shutdowntest.c
lxc_test_snapshot_SOURCES = snapshot.c lxc_test_snapshot_SOURCES = snapshot.c
lxc_test_startone_SOURCES = startone.c lxc_test_startone_SOURCES = startone.c
lxc_test_state_server_SOURCES = state_server.c lxctest.h lxc_test_state_server_SOURCES = state_server.c \
lxctest.h \
../lxc/compiler.h
lxc_test_utils_SOURCES = lxc-test-utils.c lxctest.h lxc_test_utils_SOURCES = lxc-test-utils.c lxctest.h
AM_CFLAGS=-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ AM_CFLAGS=-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \

View File

@ -16,6 +16,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#define _GNU_SOURCE
#include <alloca.h> #include <alloca.h>
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
@ -32,22 +33,24 @@
#include "lxctest.h" #include "lxctest.h"
#include "../lxc/compiler.h" #include "../lxc/compiler.h"
#define TEST_DEFAULT_BUF_SIZE 256
struct thread_args { struct thread_args {
int thread_id; int thread_id;
bool success; bool success;
pid_t init_pid; pid_t init_pid;
char inherited_ipc_ns[4096]; char inherited_ipc_ns[TEST_DEFAULT_BUF_SIZE];
char inherited_net_ns[4096]; char inherited_net_ns[TEST_DEFAULT_BUF_SIZE];
}; };
__noreturn void *ns_sharing_wrapper(void *data) __noreturn static void *ns_sharing_wrapper(void *data)
{ {
int init_pid; int init_pid;
ssize_t ret; ssize_t ret;
char name[100]; char name[100];
char owning_ns_init_pid[100]; char owning_ns_init_pid[100];
char proc_ns_path[256]; char proc_ns_path[TEST_DEFAULT_BUF_SIZE];
char ns_buf[256]; char ns_buf[TEST_DEFAULT_BUF_SIZE];
struct lxc_container *c; struct lxc_container *c;
struct thread_args *args = data; struct thread_args *args = data;
@ -75,6 +78,8 @@ __noreturn void *ns_sharing_wrapper(void *data)
goto out; goto out;
} }
c->clear_config(c);
if (!c->load_config(c, NULL)) { if (!c->load_config(c, NULL)) {
lxc_error("Failed to load config for container \"%s\"\n", name); lxc_error("Failed to load config for container \"%s\"\n", name);
goto out; goto out;
@ -132,7 +137,7 @@ __noreturn void *ns_sharing_wrapper(void *data)
lxc_error("Failed to retrieve ipc namespace for container \"%s\"\n", name); lxc_error("Failed to retrieve ipc namespace for container \"%s\"\n", name);
goto out; goto out;
} }
ns_buf[ret] = '\0'; ns_buf[ret == 0 ? ret : ret - 1] = '\0';
if (strcmp(args->inherited_ipc_ns, ns_buf) != 0) { if (strcmp(args->inherited_ipc_ns, ns_buf) != 0) {
lxc_error("Failed to inherit ipc namespace from container \"owning-ns\": %s != %s\n", args->inherited_ipc_ns, ns_buf); lxc_error("Failed to inherit ipc namespace from container \"owning-ns\": %s != %s\n", args->inherited_ipc_ns, ns_buf);
@ -152,7 +157,7 @@ __noreturn void *ns_sharing_wrapper(void *data)
lxc_error("Failed to retrieve ipc namespace for container \"%s\"\n", name); lxc_error("Failed to retrieve ipc namespace for container \"%s\"\n", name);
goto out; goto out;
} }
ns_buf[ret] = '\0'; ns_buf[ret == 0 ? ret : ret - 1] = '\0';
if (strcmp(args->inherited_net_ns, ns_buf) != 0) { if (strcmp(args->inherited_net_ns, ns_buf) != 0) {
lxc_error("Failed to inherit net namespace from container \"owning-ns\": %s != %s\n", args->inherited_net_ns, ns_buf); lxc_error("Failed to inherit net namespace from container \"owning-ns\": %s != %s\n", args->inherited_net_ns, ns_buf);
@ -169,6 +174,8 @@ out:
if (!c->destroy(c)) if (!c->destroy(c))
lxc_error("Failed to destroy container \"%s\"\n", name); lxc_error("Failed to destroy container \"%s\"\n", name);
lxc_container_put(c);
out_pthread_exit: out_pthread_exit:
pthread_exit(NULL); pthread_exit(NULL);
} }
@ -176,13 +183,13 @@ out_pthread_exit:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct thread_args *args = NULL; struct thread_args *args = NULL;
pthread_t *threads = NULL;
size_t nthreads = 10; size_t nthreads = 10;
int i, init_pid, j; int i, init_pid, j;
char proc_ns_path[4096]; char proc_ns_path[TEST_DEFAULT_BUF_SIZE];
char ipc_ns_buf[4096]; char ipc_ns_buf[TEST_DEFAULT_BUF_SIZE];
char net_ns_buf[4096]; char net_ns_buf[TEST_DEFAULT_BUF_SIZE];
pthread_attr_t attr; pthread_attr_t attr;
pthread_t threads[10];
struct lxc_container *c; struct lxc_container *c;
int ret = EXIT_FAILURE; int ret = EXIT_FAILURE;
@ -196,17 +203,17 @@ int main(int argc, char *argv[])
if (c->is_defined(c)) { if (c->is_defined(c)) {
lxc_error("%s\n", "Container \"owning-ns\" is defined"); lxc_error("%s\n", "Container \"owning-ns\" is defined");
goto on_error_put; goto on_error_stop;
} }
if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) { if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
lxc_error("%s\n", "Failed to create busybox container \"owning-ns\""); lxc_error("%s\n", "Failed to create busybox container \"owning-ns\"");
goto on_error_put; goto on_error_stop;
} }
if (!c->is_defined(c)) { if (!c->is_defined(c)) {
lxc_error("%s\n", "Container \"owning-ns\" is not defined"); lxc_error("%s\n", "Container \"owning-ns\" is not defined");
goto on_error_put; goto on_error_stop;
} }
c->clear_config(c); c->clear_config(c);
@ -269,15 +276,26 @@ int main(int argc, char *argv[])
goto on_error_stop; goto on_error_stop;
} }
threads = malloc(sizeof(pthread_t) * nthreads);
if (!threads) {
lxc_error("%s\n", "Failed to allocate memory");
goto on_error_stop;
}
for (j = 0; j < 10; j++) { for (j = 0; j < 10; j++) {
bool had_error = false;
lxc_debug("Starting namespace sharing test iteration %d\n", j); lxc_debug("Starting namespace sharing test iteration %d\n", j);
for (i = 0; i < nthreads; i++) { for (i = 0; i < nthreads; i++) {
memset(&args[i], 0, sizeof(struct thread_args));
memset(&threads[i], 0, sizeof(pthread_t));
args[i].thread_id = i; args[i].thread_id = i;
args[i].success = false; args[i].success = false;
args[i].init_pid = init_pid; args[i].init_pid = init_pid;
memcpy(args[i].inherited_ipc_ns, ipc_ns_buf, sizeof(args[i].inherited_ipc_ns)); snprintf(args[i].inherited_ipc_ns, sizeof(args[i].inherited_ipc_ns), "%s", ipc_ns_buf);
memcpy(args[i].inherited_net_ns, net_ns_buf, sizeof(args[i].inherited_net_ns)); snprintf(args[i].inherited_net_ns, sizeof(args[i].inherited_net_ns), "%s", net_ns_buf);
ret = pthread_create(&threads[i], &attr, ns_sharing_wrapper, (void *)&args[i]); ret = pthread_create(&threads[i], &attr, ns_sharing_wrapper, (void *)&args[i]);
if (ret != 0) if (ret != 0)
@ -291,15 +309,19 @@ int main(int argc, char *argv[])
if (!args[i].success) { if (!args[i].success) {
lxc_error("ns sharing thread %d failed\n", args[i].thread_id); lxc_error("ns sharing thread %d failed\n", args[i].thread_id);
goto on_error_stop; had_error = true;
} }
} }
if (had_error)
goto on_error_stop;
} }
ret = EXIT_SUCCESS; ret = EXIT_SUCCESS;
on_error_stop: on_error_stop:
free(args); free(args);
free(threads);
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
if (c->is_running(c) && !c->stop(c)) if (c->is_running(c) && !c->stop(c))
@ -308,7 +330,6 @@ on_error_stop:
if (!c->destroy(c)) if (!c->destroy(c))
lxc_error("%s\n", "Failed to destroy container \"owning-ns\""); lxc_error("%s\n", "Failed to destroy container \"owning-ns\"");
on_error_put:
lxc_container_put(c); lxc_container_put(c);
if (ret == EXIT_SUCCESS) if (ret == EXIT_SUCCESS)
lxc_debug("%s\n", "All state namespace sharing tests passed"); lxc_debug("%s\n", "All state namespace sharing tests passed");

View File

@ -30,6 +30,7 @@
#include "lxc/lxccontainer.h" #include "lxc/lxccontainer.h"
#include "lxctest.h" #include "lxctest.h"
#include "../lxc/compiler.h"
struct thread_args { struct thread_args {
int thread_id; int thread_id;
@ -38,7 +39,7 @@ struct thread_args {
struct lxc_container *c; struct lxc_container *c;
}; };
static void *state_wrapper(void *data) __noreturn static void *state_wrapper(void *data)
{ {
struct thread_args *args = data; struct thread_args *args = data;
@ -50,7 +51,6 @@ static void *state_wrapper(void *data)
args->thread_id, args->timeout, args->success ? "SUCCESS" : "FAILED"); args->thread_id, args->timeout, args->success ? "SUCCESS" : "FAILED");
pthread_exit(NULL); pthread_exit(NULL);
return NULL;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])