From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Introduce a new syntax for filesystems to allow use of a RAM filesystem <filesystem type='ram'> <source usage='1024'/> <target dir='/mnt'/> </filesystem> The usasge is in KB to limit consumption of host memory. * docs/formatdomain.html.in: Document new syntax * docs/schemas/domaincommon.rng: Add new attributes * src/conf/domain_conf.c: Parsing/formatting of RAM filesystems * src/lxc/lxc_container.c: Mounting of RAM filesystems Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- docs/formatdomain.html.in | 9 +++++++- docs/schemas/domaincommon.rng | 13 +++++++++++ src/conf/domain_conf.c | 43 ++++++++++++++++++++---------------- src/lxc/lxc_container.c | 49 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 20 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e1fe0c4..9d1e02b 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1617,6 +1617,12 @@ format will be autodetected. Only used by LXC driver <span class="since">(since 0.9.5)</span>. </dd> + <dt><code>type='ram'</code></dt> + <dd> + An in-memory filesystem, using memory from the host OS. + The source element has a single attribute <code>usage</code> + which gives the memory usage limit in kilobytes. + <span class="since"> (since 0.9.13)</span></dd> </dl> The filesystem block has an optional attribute <code>accessmode</code> @@ -1656,7 +1662,8 @@ The resource on the host that is being accessed in the guest. The <code>name</code> attribute must be used with <code>type='template'</code>, and the <code>dir</code> attribute must - be used with <code>type='mount'</code> + be used with <code>type='mount'</code>. The <code>usage</code> attribute + is used with <code>type='ram'</code> to set the memory limit in KB. </dd> <dt><code>target</code></dt> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 8419ccc..884680a 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1271,6 +1271,19 @@ </element> </interleave> </group> + <group> + <attribute name="type"> + <value>ram</value> + </attribute> + <interleave> + <element name="source"> + <attribute name="usage"> + <ref name="unsignedLong"/> + </attribute> + <empty/> + </element> + </interleave> + </group> </choice> <interleave> <element name="target"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c82971a..5d692d6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4177,7 +4177,8 @@ virDomainFSDefParseXML(xmlNodePtr node, def->wrpolicy = VIR_DOMAIN_FS_WRPOLICY_DEFAULT; } - if (source == NULL) { + if (source == NULL && + def->type != VIR_DOMAIN_FS_TYPE_RAM) { virDomainReportError(VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target); goto error; @@ -11086,27 +11087,31 @@ virDomainFSDefFormat(virBufferPtr buf, virBufferAddLit(buf, "/>\n"); } - if (def->src) { - switch (def->type) { - case VIR_DOMAIN_FS_TYPE_MOUNT: - virBufferEscapeString(buf, " <source dir='%s'/>\n", - def->src); - break; + switch (def->type) { + case VIR_DOMAIN_FS_TYPE_MOUNT: + virBufferEscapeString(buf, " <source dir='%s'/>\n", + def->src); + break; - case VIR_DOMAIN_FS_TYPE_BLOCK: - virBufferEscapeString(buf, " <source dev='%s'/>\n", - def->src); - break; + case VIR_DOMAIN_FS_TYPE_BLOCK: + virBufferEscapeString(buf, " <source dev='%s'/>\n", + def->src); + break; - case VIR_DOMAIN_FS_TYPE_FILE: - virBufferEscapeString(buf, " <source file='%s'/>\n", - def->src); - break; + case VIR_DOMAIN_FS_TYPE_FILE: + virBufferEscapeString(buf, " <source file='%s'/>\n", + def->src); + break; - case VIR_DOMAIN_FS_TYPE_TEMPLATE: - virBufferEscapeString(buf, " <source name='%s'/>\n", - def->src); - } + case VIR_DOMAIN_FS_TYPE_TEMPLATE: + virBufferEscapeString(buf, " <source name='%s'/>\n", + def->src); + break; + + case VIR_DOMAIN_FS_TYPE_RAM: + virBufferAsprintf(buf, " <source usage='%lld'/>\n", + def->usage); + break; } virBufferEscapeString(buf, " <target dir='%s'/>\n", diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 0636eab..f35b8f9 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -338,6 +338,8 @@ static int lxcContainerPivotRoot(virDomainFSDefPtr root) ret = -1; + VIR_DEBUG("Pivot via %s", root->src); + /* root->parent must be private, so make / private. */ if (mount("", "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) { virReportSystemError(errno, "%s", @@ -995,6 +997,47 @@ cleanup: } +static int lxcContainerMountFSTmpfs(virDomainFSDefPtr fs) +{ + int ret = -1; + char *data = NULL; + + if (virAsprintf(&data, "size=%lldk", fs->usage) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (virFileMakePath(fs->dst) < 0) { + virReportSystemError(errno, + _("Failed to create %s"), + fs->dst); + goto cleanup; + } + + if (mount("tmpfs", fs->dst, "tmpfs", 0, data) < 0) { + virReportSystemError(errno, + _("Failed to mount directory %s as tmpfs"), + fs->dst); + goto cleanup; + } + + if (fs->readonly) { + VIR_DEBUG("Binding %s readonly", fs->dst); + if (mount(fs->dst, fs->dst, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) { + virReportSystemError(errno, + _("Failed to make directory %s readonly"), + fs->dst); + } + } + + ret = 0; + +cleanup: + VIR_FREE(data); + return ret; +} + + static int lxcContainerMountFS(virDomainFSDefPtr fs, const char *srcprefix) { @@ -1007,6 +1050,10 @@ static int lxcContainerMountFS(virDomainFSDefPtr fs, if (lxcContainerMountFSBlock(fs, srcprefix) < 0) return -1; break; + case VIR_DOMAIN_FS_TYPE_RAM: + if (lxcContainerMountFSTmpfs(fs) < 0) + return -1; + break; case VIR_DOMAIN_FS_TYPE_FILE: lxcError(VIR_ERR_INTERNAL_ERROR, _("Unexpected filesystem type %s"), @@ -1196,6 +1243,8 @@ static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef) for (i = 0 ; i < vmDef->nfss ; i++) { virDomainFSDefPtr fs = vmDef->fss[i]; + if (!fs->src) + continue; if (virFileResolveAllLinks(fs->src, &newroot) < 0) return -1; -- 1.7.10.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list