Commit 9c4693b8 by Christian Seiler Committed by Serge Hallyn

lxc-attach: Completely rework lxc-attach and move to API function

- Move attach functionality to a completely new API function for attaching to containers. The API functions accepts the name of the container, the lxcpath, a structure indicating options for attaching and returns the pid of the attached process. The calling thread may then use waitpid() or similar to wait for the attached process to finish. lxc-attach itself is just a simple wrapper around the new API function. - Use CLONE_PARENT when creating the attached process from the intermediate process. This allows the intermediate process to exit immediately after attach and the original thread may supervise the attached process directly. - Since the intermediate process exits quickly, its only job is to send the original process the pid of the attached process (as seen from outside the pidns) and exit. This allows us to simplify the synchronisation logic by quite a bit. - Use O_CLOEXEC / SOCK_CLOEXEC on (hopefully) all FDs opened in the main thread by the attach logic so that other threads of the same program may safely fork+exec off. Also, use shutdown() on the synchronisation socket, so that if another thread forks off without exec'ing, the synchronisation will not fail. (Not tested whether this solves this issue.) - Instead of directly specifying a program to execute on the API level, one specifies a callback function and a payload. This allows code using the API to execute a custom function directly inside the container without having to execute a program. Two default callbacks are provided directly, one to execute an arbitrary program, another to execute a shell. The lxc-attach utility will always use either one of these default callbacks. - More fine-grained control of the attached process on the API level (not implemented in lxc-attach utility yet, some may not be sensible): * Specify which file descriptors should be stdin/stdout/stderr of the newly created process. If fds other than 0/1/2 are specified, they will be dup'd in the attached process (and the originals closed). This allows e.g. threaded applications to specify pipes for communication with the attached process without having to modify its own stdin/stdout/stderr before running lxc-attach. * Specify user and group id for the newly attached process. * Specify initial working directory for the newly attached process. * Fine-grained control on whether to do any, all or none of the following: move attached process into the container's init's cgroup, drop capabilities of the process, set the processes's personality, load the proper apparmor profile and (for partial attaches to any but not mount-namespaces) whether to unshare the mount namespace and remount /sys and /proc. If additional features (SELinux policy, SMACK policy, ...) are implemented, flags for those may also be provided. Signed-off-by: 's avatarChristian Seiler <christian@iwakd.de> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 650468bb
......@@ -25,6 +25,7 @@
#define _attach_h
#include <sys/types.h>
#include "attach_options.h"
struct lxc_proc_context_info {
char *aa_profile;
......@@ -34,11 +35,6 @@ struct lxc_proc_context_info {
extern struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid);
typedef enum lxc_attach_env_policy_t {
LXC_ATTACH_KEEP_ENV,
LXC_ATTACH_CLEAR_ENV
} lxc_attach_env_policy_t;
extern int lxc_attach_to_ns(pid_t other_pid, int which);
extern int lxc_attach_remount_sys_proc();
extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx);
......@@ -48,4 +44,6 @@ extern char *lxc_attach_getpwshell(uid_t uid);
extern void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid);
extern int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <daniel.lezcano at free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LXC_ATTACH_OPTIONS_H
#define _LXC_ATTACH_OPTIONS_H
#include <sys/types.h>
typedef enum lxc_attach_env_policy_t {
LXC_ATTACH_KEEP_ENV,
LXC_ATTACH_CLEAR_ENV
} lxc_attach_env_policy_t;
enum {
/* the following are on by default: */
LXC_ATTACH_MOVE_TO_CGROUP = 0x00000001,
LXC_ATTACH_DROP_CAPABILITIES = 0x00000002,
LXC_ATTACH_SET_PERSONALITY = 0x00000004,
LXC_ATTACH_APPARMOR = 0x00000008,
/* the following are off by default */
LXC_ATTACH_REMOUNT_PROC_SYS = 0x00010000,
/* we have 16 bits for things that are on by default
* and 16 bits that are off by default, that should
* be sufficient to keep binary compatibility for
* a while
*/
LXC_ATTACH_DEFAULT = 0x0000FFFF
};
typedef struct lxc_attach_options_t lxc_attach_options_t;
typedef int (*lxc_attach_exec_t)(void* payload);
struct lxc_attach_options_t {
/* any combination of the above enum */
int attach_flags;
/* the namespaces to attach to (CLONE_NEW... flags) */
int namespaces;
/* initial personality, -1 to autodetect
* (may be ignored if lxc is compiled w/o personality support) */
long personality;
/* inital current directory, use NULL to use cwd
* (might not exist in container, then / will be
* used because of kernel defaults)
*/
char* initial_cwd;
/* the uid and gid to attach to,
* -1 for default (init uid/gid for userns containers,
* otherwise or if detection fails 0/0)
*/
uid_t uid;
gid_t gid;
/* environment handling */
lxc_attach_env_policy_t env_policy;
char** extra_env_vars;
char** extra_keep_env;
/* file descriptors for stdin, stdout and stderr,
* dup2() will be used before calling exec_function,
* (assuming not 0, 1 and 2 are specified) and the
* original fds are closed before passing control
* over. Any O_CLOEXEC flag will be removed after
* that
*/
int stdin_fd;
int stdout_fd;
int stderr_fd;
};
#define LXC_ATTACH_OPTIONS_DEFAULT \
{ \
/* .attach_flags = */ LXC_ATTACH_DEFAULT, \
/* .namespaces = */ -1, \
/* .personality = */ -1, \
/* .initial_cwd = */ NULL, \
/* .uid = */ (uid_t)-1, \
/* .gid = */ (gid_t)-1, \
/* .env_policy = */ LXC_ATTACH_KEEP_ENV, \
/* .extra_env_vars = */ NULL, \
/* .extra_keep_env = */ NULL, \
/* .stdin_fd = */ 0, 1, 2 \
}
typedef struct lxc_attach_command_t {
char* program; /* the program to run (passed to execvp) */
char** argv; /* the argv pointer of that program, including the program itself in argv[0] */
} lxc_attach_command_t;
/* default execution functions:
* run_command: pointer to lxc_attach_command_t
* run_shell: no payload, will be ignored
*/
extern int lxc_attach_run_command(void* payload);
extern int lxc_attach_run_shell(void* payload);
#endif
......@@ -25,6 +25,7 @@
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include "config.h"
/* returns 1 on success, 0 if there were any failures */
......
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