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);