[libvirt] [PATCH] Add support for RAM filesystems for LXC
Daniel Veillard
veillard at redhat.com
Mon Jun 25 07:41:52 UTC 2012
On Fri, Jun 22, 2012 at 11:29:40AM +0100, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
>
> Introduce a new syntax for filesystems to allow use of a RAM
> filesystem
>
> <filesystem type='ram'>
> <source usage='10' units='MiB'/>
> <target dir='/mnt'/>
> </filesystem>
>
> The usage units default to KiB 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 at redhat.com>
> ---
> docs/formatdomain.html.in | 9 ++++++-
> docs/schemas/domaincommon.rng | 18 +++++++++++++
> src/conf/domain_conf.c | 58 +++++++++++++++++++++++++++--------------
> src/conf/domain_conf.h | 5 ++++
> src/lxc/lxc_container.c | 49 ++++++++++++++++++++++++++++++++++
> 5 files changed, 118 insertions(+), 21 deletions(-)
>
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index 1f30772..99ca26e 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -1630,6 +1630,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 kibibytes.
I would add "Only used by LXC driver" there too ...
> + <span class="since"> (since 0.9.13)</span></dd>
> </dl>
>
> The filesystem block has an optional attribute <code>accessmode</code>
> @@ -1669,7 +1675,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 46e539d..4a04a65 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -1289,6 +1289,24 @@
> </element>
> </interleave>
> </group>
> + <group>
> + <attribute name="type">
> + <value>ram</value>
> + </attribute>
> + <interleave>
> + <element name="source">
> + <attribute name="usage">
> + <ref name="unsignedLong"/>
> + </attribute>
> + <optional>
> + <attribute name='unit'>
> + <ref name='unit'/>
> + </attribute>
> + </optional>
> + <empty/>
> + </element>
> + </interleave>
> + </group>
> </choice>
> <interleave>
> <element name="target">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 5ea264f..a653fe6 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -262,7 +262,8 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
> "mount",
> "block",
> "file",
> - "template")
> + "template",
> + "ram")
>
> VIR_ENUM_IMPL(virDomainFSDriverType, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
> "default",
> @@ -4210,6 +4211,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
> char *target = NULL;
> char *accessmode = NULL;
> char *wrpolicy = NULL;
> + char *usage = NULL;
>
> ctxt->node = node;
>
> @@ -4297,7 +4299,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;
> @@ -4309,6 +4312,16 @@ virDomainFSDefParseXML(xmlNodePtr node,
> goto error;
> }
>
> + if (def->type == VIR_DOMAIN_FS_TYPE_RAM) {
> + def->usage = VIR_DOMAIN_FS_RAM_DEFAULT_USAGE;
> + if (virDomainParseScaledValue("./source[0]", ctxt,
> + &def->usage,
> + 1024,
> + ULONG_LONG_MAX,
> + false) < 0)
> + goto error;
> + }
> +
> def->src = source;
> source = NULL;
> def->dst = target;
> @@ -4325,6 +4338,7 @@ cleanup:
> VIR_FREE(source);
> VIR_FREE(accessmode);
> VIR_FREE(wrpolicy);
> + VIR_FREE(usage);
>
> return def;
>
> @@ -11319,27 +11333,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' units='KiB'/>\n",
> + def->usage);
> + break;
> }
>
> virBufferEscapeString(buf, " <target dir='%s'/>\n",
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 86c1e63..b8d9c87 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -660,6 +660,7 @@ enum virDomainFSType {
> VIR_DOMAIN_FS_TYPE_BLOCK,
> VIR_DOMAIN_FS_TYPE_FILE,
> VIR_DOMAIN_FS_TYPE_TEMPLATE,
> + VIR_DOMAIN_FS_TYPE_RAM,
>
> VIR_DOMAIN_FS_TYPE_LAST
> };
> @@ -690,11 +691,15 @@ enum virDomainFSWrpolicy {
> VIR_DOMAIN_FS_WRPOLICY_LAST
> };
>
> +/* Allow 2 MB ram usage */
> +#define VIR_DOMAIN_FS_RAM_DEFAULT_USAGE (1024 * 2)
> +
> struct _virDomainFSDef {
> int type;
> int fsdriver;
> int accessmode;
> int wrpolicy; /* enum virDomainFSWrpolicy */
> + unsigned long long usage;
> char *src;
> char *dst;
> unsigned int readonly : 1;
> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> index 24b1017..b69255e 100644
> --- a/src/lxc/lxc_container.c
> +++ b/src/lxc/lxc_container.c
> @@ -335,6 +335,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",
> @@ -966,6 +968,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", MS_NOSUID|MS_NODEV, 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)
> {
> @@ -978,6 +1021,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"),
> @@ -1441,6 +1488,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;
>
ACK with the small nit on documentation above,
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list