On Fri, Jun 22, 2012 at 11:29:40AM +0100, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > 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@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list