*
* Authors:
* Daniel Lezcano <daniel.lezcano at free.fr>
+ * Serge Hallyn <serge@hallyn.com>
+ * Christian Brauner <christian.brauner@ubuntu.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*
* Authors:
* Daniel Lezcano <daniel.lezcano at free.fr>
+ * Serge Hallyn <serge@hallyn.com>
+ * Christian Brauner <christian.brauner@ubuntu.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#define __LXC_START_H
#include <signal.h>
+#include <stdbool.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <stdbool.h>
#include "conf.h"
#include "config.h"
-#include "state.h"
#include "namespace.h"
+#include "state.h"
struct lxc_handler {
- bool am_root;
- pid_t pid;
- char *name;
- lxc_state_t state;
+ /* The clone flags that were requested. */
int clone_flags;
- int sigfd;
- sigset_t oldmask;
- struct lxc_conf *conf;
- struct lxc_operations *ops;
- void *data;
- int sv[2];
+
+ /* File descriptors referring to the network namespace of the container. */
+ int netnsfd;
+
+ /* File descriptor to pin the rootfs for privileged containers. */
int pinfd;
- const char *lxcpath;
- void *cgroup_data;
+
+ /* Signal file descriptor. */
+ int sigfd;
+
+ /* List of file descriptors referring to the namespaces of the
+ * container. Note that these are not necessarily identical to
+ * the "clone_flags" handler field in case namespace inheritance is
+ * requested.
+ */
+ int nsfd[LXC_NS_MAX];
/* Abstract unix domain SOCK_DGRAM socketpair to pass arbitrary data
* between child and parent.
*/
int data_sock[2];
- /* indicates whether should we close std{in,out,err} on start */
- bool backgrounded;
- int nsfd[LXC_NS_MAX];
- int netnsfd;
-
/* The socketpair() fds used to wait on successful daemonized startup. */
int state_socket_pair[2];
+
+ /* Socketpair to synchronize processes during container creation. */
+ int sync_sock[2];
+
+ /* The name of the container. */
+ char *name;
+
+ /* The path the container is running in. */
+ const char *lxcpath;
+
+ /* Whether the container's startup process euid is 0. */
+ bool am_root;
+
+ /* Indicates whether should we close std{in,out,err} on start. */
+ bool backgrounded;
+
+ /* The child's pid. */
+ pid_t pid;
+
+ /* The signal mask prior to setting up the signal file descriptor. */
+ sigset_t oldmask;
+
+ /* The container's in-memory configuration. */
+ struct lxc_conf *conf;
+
+ /* A list of clients registered to be informed about a container state. */
struct lxc_list state_clients;
+
+ /* A set of operations to be performed at various stages of the
+ * container's life.
+ */
+ struct lxc_operations *ops;
+
+ /* This holds the cgroup information. Note that the data here is
+ * specific to the cgroup driver used.
+ */
+ void *cgroup_data;
+
+ /* Data to be passed to handler ops. */
+ void *data;
+
+ /* Current state of the container. */
+ lxc_state_t state;
};
struct lxc_operations {
*/
extern int lxc_check_inherited(struct lxc_conf *conf, bool closeall,
int *fds_to_ignore, size_t len_fds);
-int __lxc_start(const char *, struct lxc_handler *, struct lxc_operations *,
- void *, const char *, bool);
+extern int __lxc_start(const char *, struct lxc_handler *,
+ struct lxc_operations *, void *, const char *, bool);
extern void resolve_clone_flags(struct lxc_handler *handler);
#endif
int lxc_sync_barrier_parent(struct lxc_handler *handler, int sequence)
{
- return __sync_barrier(handler->sv[0], sequence);
+ return __sync_barrier(handler->sync_sock[0], sequence);
}
int lxc_sync_barrier_child(struct lxc_handler *handler, int sequence)
{
- return __sync_barrier(handler->sv[1], sequence);
+ return __sync_barrier(handler->sync_sock[1], sequence);
}
int lxc_sync_wake_parent(struct lxc_handler *handler, int sequence)
{
- return __sync_wake(handler->sv[0], sequence);
+ return __sync_wake(handler->sync_sock[0], sequence);
}
int lxc_sync_wait_parent(struct lxc_handler *handler, int sequence)
{
- return __sync_wait(handler->sv[0], sequence);
+ return __sync_wait(handler->sync_sock[0], sequence);
}
int lxc_sync_wait_child(struct lxc_handler *handler, int sequence)
{
- return __sync_wait(handler->sv[1], sequence);
+ return __sync_wait(handler->sync_sock[1], sequence);
}
int lxc_sync_wake_child(struct lxc_handler *handler, int sequence)
{
- return __sync_wake(handler->sv[1], sequence);
+ return __sync_wake(handler->sync_sock[1], sequence);
}
int lxc_sync_init(struct lxc_handler *handler)
{
int ret;
- ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv);
+ ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sync_sock);
if (ret) {
SYSERROR("failed to create synchronization socketpair");
return -1;
}
/* Be sure we don't inherit this after the exec */
- fcntl(handler->sv[0], F_SETFD, FD_CLOEXEC);
+ fcntl(handler->sync_sock[0], F_SETFD, FD_CLOEXEC);
return 0;
}
void lxc_sync_fini_child(struct lxc_handler *handler)
{
- if (handler->sv[0] != -1) {
- close(handler->sv[0]);
- handler->sv[0] = -1;
+ if (handler->sync_sock[0] != -1) {
+ close(handler->sync_sock[0]);
+ handler->sync_sock[0] = -1;
}
}
void lxc_sync_fini_parent(struct lxc_handler *handler)
{
- if (handler->sv[1] != -1) {
- close(handler->sv[1]);
- handler->sv[1] = -1;
+ if (handler->sync_sock[1] != -1) {
+ close(handler->sync_sock[1]);
+ handler->sync_sock[1] = -1;
}
}