<target dir='/import/from/host'/>
<readonly/>
</filesystem>
+ <filesystem type='file' accessmode='passthrough'>
+ <driver name='loop' type='raw'/>
+ <driver type='path' wrpolicy='immediate'/>
+ <source file='/export/to/guest.img'/>
+ <target dir='/import/from/host'/>
+ <readonly/>
+ </filesystem>
...
</devices>
...</pre>
</dd>
+ <dt><code>driver</code></dt>
+ <dd>
+ The optional driver element allows specifying further details
+ related to the hypervisor driver used to provide the filesystem.
+ <span class="since">Since 1.0.6</span>
+ <ul>
+ <li>
+ If the hypervisor supports multiple backend drivers, then
+ the <code>type</code> attribute selects the primary
+ backend driver name, while the <code>format</code>
+ attribute provides the format type. For example, LXC
+ supports a type of "loop", with a format of "raw". QEMU
+ supports a type of "path" or "handle", but no formats.
+ </li>
+ </ul>
+ </dd>
+
<dt><code>source</code></dt>
<dd>
The resource on the host that is being accessed in the guest. The
<define name="diskspec">
<interleave>
<optional>
- <ref name="driver"/>
+ <ref name="diskDriver"/>
</optional>
<optional>
<ref name='diskMirror'/>
<!--
Disk may use a special driver for access.
-->
- <define name="driver">
+ <define name="diskDriver">
<element name="driver">
<choice>
<group>
<optional>
<attribute name='type'>
<choice>
- <ref name='diskFormat'/>
+ <ref name='storageFormat'/>
<value>aio</value> <!-- back-compat for 'raw' -->
</choice>
</attribute>
</optional>
</define>
- <define name='diskFormat'>
+ <define name='storageFormat'>
<choice>
<value>raw</value>
<value>dir</value>
<attribute name="type">
<value>file</value>
</attribute>
+ <optional>
+ <ref name="fsDriver"/>
+ </optional>
<interleave>
<element name="source">
<attribute name="file">
<attribute name="type">
<value>block</value>
</attribute>
+ <optional>
+ <ref name="fsDriver"/>
+ </optional>
<interleave>
<element name="source">
<attribute name="dev">
<value>mount</value>
</attribute>
</optional>
+ <optional>
+ <ref name="fsDriver"/>
+ </optional>
<interleave>
<element name="source">
<attribute name="dir">
</attribute>
<empty/>
</element>
- <optional>
- <element name="driver">
- <attribute name="type">
- <choice>
- <value>path</value>
- <value>handle</value>
- </choice>
- </attribute>
- <optional>
- <attribute name="wrpolicy">
- <value>immediate</value>
- </attribute>
- </optional>
- <empty/>
- </element>
- </optional>
</interleave>
</group>
<group>
<value>bind</value>
</attribute>
</optional>
+ <optional>
+ <ref name="fsDriver"/>
+ </optional>
<interleave>
<element name="source">
<attribute name="dir">
<attribute name="type">
<value>template</value>
</attribute>
+ <optional>
+ <ref name="fsDriver"/>
+ </optional>
<interleave>
<element name="source">
<attribute name="name">
<attribute name="type">
<value>ram</value>
</attribute>
+ <optional>
+ <ref name="fsDriver"/>
+ </optional>
<interleave>
<element name="source">
<attribute name="usage">
</interleave>
</element>
</define>
+ <define name="fsDriver">
+ <element name="driver">
+ <!-- Annoying inconsistency. 'disk' uses 'name'
+ for this kind of info, and 'type' for the
+ storage format. We need the latter too, so
+ had to invent a new attribute name -->
+ <optional>
+ <attribute name="type">
+ <choice>
+ <value>path</value>
+ <value>handle</value>
+ <value>loop</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="format">
+ <ref name="storageFormat"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="wrpolicy">
+ <value>immediate</value>
+ </attribute>
+ </optional>
+ <empty/>
+ </element>
+ </define>
+
<!--
An interface description can either be of type bridge in which case
it will use a bridging source, or of type ethernet which uses a device
</attribute>
<optional>
<attribute name='format'>
- <ref name='diskFormat'/>
+ <ref name='storageFormat'/>
</attribute>
</optional>
<optional>
<element name='driver'>
<optional>
<attribute name='type'>
- <ref name='diskFormat'/>
+ <ref name='storageFormat'/>
</attribute>
</optional>
<empty/>
VIR_ENUM_IMPL(virDomainFSDriverType, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
"default",
"path",
- "handle")
+ "handle",
+ "loop")
VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST,
"passthrough",
char *fsdriver = NULL;
char *source = NULL;
char *target = NULL;
+ char *format = NULL;
char *accessmode = NULL;
char *wrpolicy = NULL;
char *usage = NULL;
target = virXMLPropString(cur, "dir");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = true;
- } else if (!fsdriver && xmlStrEqual(cur->name, BAD_CAST "driver")) {
- fsdriver = virXMLPropString(cur, "type");
- wrpolicy = virXMLPropString(cur, "wrpolicy");
+ } else if (xmlStrEqual(cur->name, BAD_CAST "driver")) {
+ if (!fsdriver)
+ fsdriver = virXMLPropString(cur, "type");
+ if (!wrpolicy)
+ wrpolicy = virXMLPropString(cur, "wrpolicy");
+ if (!format)
+ format = virXMLPropString(cur, "format");
}
}
cur = cur->next;
if (fsdriver) {
if ((def->fsdriver = virDomainFSDriverTypeTypeFromString(fsdriver)) <= 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown fs driver type '%s'"), fsdriver);
goto error;
}
}
+ if (format) {
+ if ((def->format = virStorageFileFormatTypeFromString(format)) <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown driver format value '%s'"), format);
+ goto error;
+ }
+ }
+
if (wrpolicy) {
if ((def->wrpolicy = virDomainFSWrpolicyTypeFromString(wrpolicy)) <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
VIR_FREE(wrpolicy);
VIR_FREE(usage);
VIR_FREE(unit);
+ VIR_FREE(format);
return def;
if (def->fsdriver) {
virBufferAsprintf(buf, " <driver type='%s'", fsdriver);
+ if (def->format)
+ virBufferAsprintf(buf, " format='%s'",
+ virStorageFileFormatTypeToString(def->format));
+
/* Don't generate anything if wrpolicy is set to default */
- if (def->wrpolicy) {
+ if (def->wrpolicy)
virBufferAsprintf(buf, " wrpolicy='%s'", wrpolicy);
- }
virBufferAddLit(buf, "/>\n");
}
VIR_DOMAIN_FS_DRIVER_TYPE_DEFAULT = 0,
VIR_DOMAIN_FS_DRIVER_TYPE_PATH,
VIR_DOMAIN_FS_DRIVER_TYPE_HANDLE,
+ VIR_DOMAIN_FS_DRIVER_TYPE_LOOP,
VIR_DOMAIN_FS_DRIVER_TYPE_LAST
};
struct _virDomainFSDef {
int type;
- int fsdriver;
- int accessmode;
+ int fsdriver; /* enum virDomainFSDriverType */
+ int accessmode; /* enum virDomainFSAccessMode */
int wrpolicy; /* enum virDomainFSWrpolicy */
+ int format; /* enum virStorageFileFormat */
unsigned long long usage;
char *src;
char *dst;
VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
"local",
"local",
- "handle");
+ "handle",
+ NULL);
/**
--- /dev/null
+<domain type='lxc'>
+ <name>demo</name>
+ <uuid>8369f1ac-7e46-e869-4ca5-759d51478066</uuid>
+ <memory unit='KiB'>500000</memory>
+ <currentMemory unit='KiB'>500000</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64'>exe</type>
+ <init>/bin/sh</init>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/libexec/libvirt_lxc</emulator>
+ <filesystem type='file' accessmode='passthrough'>
+ <driver type='loop' format='raw'/>
+ <source file='/root/container.img'/>
+ <target dir='/'/>
+ </filesystem>
+ <console type='pty'>
+ <target type='lxc' port='0'/>
+ </console>
+ </devices>
+</domain>
DO_TEST("systemd");
DO_TEST("hostdev");
+ DO_TEST("disk-formats");
virObjectUnref(caps);
virObjectUnref(xmlopt);