diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f4132b4c414005c9b733c917fbe1f1769007c008..c155e2ae060a1651397aec338d7b4bbdd222ca48 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -330,6 +330,10 @@
To set environment variables, use the initenv
element, one
for each variable.
+
+ To set a custom work directory for the init, use the initdir
+ element.
+
<os>
@@ -338,6 +342,7 @@
<initarg>--unit</initarg>
<initarg>emergency.service</initarg>
<initenv name='MYENV'>some value</initenv>
+ <initdir>/my/custom/cwd</initdir>
</os>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 930e31c42b48f368771734390a2fab6b9eb5adc5..412dba0b35d3457307245e436e7cc75ee5dbcecd 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -395,6 +395,11 @@
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 71b43ca236dc6e33f346ca8190d19afff862099e..c264d00737a1718bfae884de875971685b891eea 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2876,6 +2876,7 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->os.initargv);
for (i = 0; def->os.initenv && def->os.initenv[i]; i++)
VIR_FREE(def->os.initenv[i]);
+ VIR_FREE(def->os.initdir);
VIR_FREE(def->os.initenv);
VIR_FREE(def->os.kernel);
VIR_FREE(def->os.initrd);
@@ -17068,6 +17069,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def,
if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) {
def->os.init = virXPathString("string(./os/init[1])", ctxt);
def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt);
+ def->os.initdir = virXPathString("string(./os/initdir[1])", ctxt);
if ((n = virXPathNodeSet("./os/initarg", ctxt, &nodes)) < 0)
goto error;
@@ -24953,6 +24955,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
for (i = 0; def->os.initenv && def->os.initenv[i]; i++)
virBufferAsprintf(buf, "%s \n",
def->os.initenv[i]->name, def->os.initenv[i]->value);
+ if (def->os.initdir)
+ virBufferEscapeString(buf, "%s \n",
+ def->os.initdir);
if (def->os.loader)
virDomainLoaderDefFormat(buf, def->os.loader);
virBufferEscapeString(buf, "%s \n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3f34601016a8ae55ed872197a98692b0afa8e625..0be5506694ebbbb0355b9d1f7bae3fd64738137a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1869,6 +1869,7 @@ struct _virDomainOSDef {
char *init;
char **initargv;
virDomainOSEnvPtr *initenv;
+ char *initdir;
char *kernel;
char *initrd;
char *cmdline;
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index ffafc39d79d8a6a028b54361ea52776ef7670c72..8d8e1a735cdb21a371841f8784a46f59cb266fd9 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -245,6 +245,8 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef,
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_NAME", vmDef->name);
if (vmDef->os.cmdline)
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_CMDLINE", vmDef->os.cmdline);
+ if (vmDef->os.initdir)
+ virCommandSetWorkingDirectory(cmd, vmDef->os.initdir);
for (i = 0; vmDef->os.initenv[i]; i++) {
virCommandAddEnvPair(cmd, vmDef->os.initenv[i]->name,
diff --git a/tests/lxcxml2xmldata/lxc-initdir.xml b/tests/lxcxml2xmldata/lxc-initdir.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2940bda912929fd849e80ba769ebf47db9d48400
--- /dev/null
+++ b/tests/lxcxml2xmldata/lxc-initdir.xml
@@ -0,0 +1,30 @@
+
+ jessie
+ e21987a5-e98e-9c99-0e35-803e4d9ad1fe
+ 1048576
+ 1048576
+ 1
+
+ /machine
+
+
+ exe
+ /sbin/sh
+ /path/to/pwd
+
+
+ destroy
+ restart
+ restart
+
+ /usr/libexec/libvirt_lxc
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c
index 2a24b60b3b6766413b26a3b8194d21d66444bcd8..c81b0eace7e66d1bc000accbc37186646638814f 100644
--- a/tests/lxcxml2xmltest.c
+++ b/tests/lxcxml2xmltest.c
@@ -99,6 +99,7 @@ mymain(void)
DO_TEST_FULL("filesystem-root", 0, false,
VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS);
DO_TEST("initenv");
+ DO_TEST("initdir");
virObjectUnref(caps);
virObjectUnref(xmlopt);