diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 51b1a7035..7df6c0eb9 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -284,6 +284,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Init working directory
+
+ Sets the absolute path inside the container as the working directory for the containers.
+ LXC will switch to this directory before executing init.
+
+
+
+
+
+
+
+
+ Absolute path inside the container to use as the working directory.
+
+
+
+
+
+
Init ID
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index ae30b5b87..8234279f9 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3432,6 +3432,7 @@ void lxc_conf_free(struct lxc_conf *conf)
free(conf->rcfile);
free(conf->execute_cmd);
free(conf->init_cmd);
+ free(conf->init_cwd);
free(conf->unexpanded_config);
free(conf->pty_names);
free(conf->syslog);
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 58302cf30..fa10a41bf 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -359,6 +359,10 @@ struct lxc_conf {
struct lxc_cgroup cgroup_meta;
char *inherit_ns[LXC_NS_MAX];
+
+ /* init working directory */
+ char* init_cwd;
+
};
#ifdef HAVE_TLS
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index a2e5ba7c1..6bd71a0dd 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -95,6 +95,7 @@ lxc_config_define(hooks);
lxc_config_define(idmaps);
lxc_config_define(includefiles);
lxc_config_define(init_cmd);
+lxc_config_define(init_cwd);
lxc_config_define(init_gid);
lxc_config_define(init_uid);
lxc_config_define(log_file);
@@ -176,6 +177,7 @@ static struct lxc_config_t config[] = {
{ "lxc.init.cmd", false, set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
{ "lxc.init.gid", false, set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
{ "lxc.init.uid", false, set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
+ { "lxc.init.cwd", false, set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
{ "lxc.log.file", false, set_config_log_file, get_config_log_file, clr_config_log_file, },
{ "lxc.log.level", false, set_config_log_level, get_config_log_level, clr_config_log_level, },
{ "lxc.log.syslog", false, set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, },
@@ -945,6 +947,12 @@ static int set_config_init_cmd(const char *key, const char *value,
return set_config_path_item(&lxc_conf->init_cmd, value);
}
+static int set_config_init_cwd(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ return set_config_path_item(&lxc_conf->init_cwd, value);
+}
+
static int set_config_init_uid(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
@@ -3249,6 +3257,12 @@ static int get_config_init_cmd(const char *key, char *retv, int inlen,
return lxc_get_conf_str(retv, inlen, c->init_cmd);
}
+static int get_config_init_cwd(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_str(retv, inlen, c->init_cwd);
+}
+
static int get_config_init_uid(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
@@ -3665,6 +3679,14 @@ static inline int clr_config_init_cmd(const char *key, struct lxc_conf *c,
return 0;
}
+static inline int clr_config_init_cwd(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ free(c->init_cwd);
+ c->init_cwd = NULL;
+ return 0;
+}
+
static inline int clr_config_init_uid(const char *key, struct lxc_conf *c,
void *data)
{
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 1c47fd95e..a6bb80325 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -979,6 +979,11 @@ static int do_start(void *data)
setsid();
+ if (handler->conf->init_cwd && chdir(handler->conf->init_cwd)) {
+ SYSERROR("Could not change directory to \"%s\"", handler->conf->init_cwd);
+ goto out_warn_father;
+ }
+
if (lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP_LIMITS))
goto out_warn_father;