VirtFS allows the user to choose between path/handle based fs driver.
As of now, libvirt hardcoded path based driver only. This patch provides
a solution to allow user to choose between path/handle based fs driver.
Sample:
<filesystem type='mount'>
<driver type='handle'/>
<source dir='/folder/to/share1'/>
<target dir='mount_tag1'/>
</filesystem>
<filesystem type='mount'>
<driver type='path'/>
<source dir='/folder/to/share2'/>
<target dir='mount_tag2'/>
</filesystem>
Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
<target dir='/'/>
</filesystem>
<filesystem type='mount' accessmode='passthrough'>
+ <driver type='path'/>
<source dir='/export/to/guest'/>
<target dir='/import/from/host'/>
<readonly/>
OpenVZ <span class="since">(since 0.6.2)</span>
and QEMU/KVM <span class="since">(since 0.8.5)</span>.
This is the default <code>type</code> if one is not specified.
+ This mode also has an optional
+ sub-element <code>driver</code>, with an
+ attribute <code>type='path'</code>
+ or <code>type='handle'</code> <span class="since">(since
+ 0.9.7)</span>.
</dd>
<dt><code>type='template'</code></dt>
<dd>
</interleave>
</group>
<group>
- <attribute name="type">
- <value>mount</value>
- </attribute>
+ <!-- type='mount' is default -->
+ <optional>
+ <attribute name="type">
+ <value>mount</value>
+ </attribute>
+ </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>
+ <empty/>
+ </element>
+ </optional>
<ref name="filesystemtgt"/>
</interleave>
</group>
</group>
</choice>
<optional>
- <ref name="address"/>
<attribute name="accessmode">
<choice>
<value>passthrough</value>
</element>
</define>
<define name="filesystemtgt">
- <element name="target">
- <attribute name="dir">
- <ref name="absDirPath"/>
- </attribute>
- <empty/>
- </element>
+ <interleave>
+ <optional>
+ <ref name="address"/>
+ </optional>
+ <element name="target">
+ <attribute name="dir">
+ <ref name="absDirPath"/>
+ </attribute>
+ <empty/>
+ </element>
+ </interleave>
</define>
<!--
An interface description can either be of type bridge in which case
"file",
"template")
+VIR_ENUM_IMPL(virDomainFSDriverType, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
+ "default",
+ "path",
+ "handle")
+
VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST,
"passthrough",
"mapped",
virDomainFSDefPtr def;
xmlNodePtr cur;
char *type = NULL;
+ char *fsdriver = NULL;
char *source = NULL;
char *target = NULL;
char *accessmode = NULL;
target = virXMLPropString(cur, "dir");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
+ } else if ((fsdriver == NULL) && (xmlStrEqual(cur->name, BAD_CAST "driver"))) {
+ fsdriver = virXMLPropString(cur, "type");
}
}
cur = cur->next;
}
+ if (fsdriver) {
+ if ((def->fsdriver = virDomainFSDriverTypeTypeFromString(fsdriver)) <= 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown fs driver type '%s'"), fsdriver);
+ goto error;
+ }
+ }
+
if (source == NULL) {
virDomainReportError(VIR_ERR_NO_SOURCE,
target ? "%s" : NULL, target);
cleanup:
VIR_FREE(type);
+ VIR_FREE(fsdriver);
VIR_FREE(target);
VIR_FREE(source);
VIR_FREE(accessmode);
{
const char *type = virDomainFSTypeToString(def->type);
const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
+ const char *fsdriver = virDomainFSDriverTypeTypeToString(def->fsdriver);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
" <filesystem type='%s' accessmode='%s'>\n",
type, accessmode);
+ if (def->fsdriver) {
+ virBufferAsprintf(buf, " <driver type='%s'/>\n", fsdriver);
+ }
+
if (def->src) {
switch (def->type) {
case VIR_DOMAIN_FS_TYPE_MOUNT:
VIR_DOMAIN_FS_TYPE_LAST
};
+/* Filesystem driver type */
+enum virDomainFSDriverType {
+ VIR_DOMAIN_FS_DRIVER_TYPE_DEFAULT = 0,
+ VIR_DOMAIN_FS_DRIVER_TYPE_PATH,
+ VIR_DOMAIN_FS_DRIVER_TYPE_HANDLE,
+
+ VIR_DOMAIN_FS_DRIVER_TYPE_LAST
+};
+
/* Filesystem mount access mode */
enum virDomainFSAccessMode {
VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH,
typedef virDomainFSDef *virDomainFSDefPtr;
struct _virDomainFSDef {
int type;
+ int fsdriver;
int accessmode;
char *src;
char *dst;
VIR_ENUM_DECL(virDomainControllerModelSCSI)
VIR_ENUM_DECL(virDomainControllerModelUSB)
VIR_ENUM_DECL(virDomainFS)
+VIR_ENUM_DECL(virDomainFSDriverType)
VIR_ENUM_DECL(virDomainFSAccessMode)
VIR_ENUM_DECL(virDomainNet)
VIR_ENUM_DECL(virDomainNetBackend)
"vt82c686b-usb-uhci",
"pci-ohci");
+VIR_ENUM_DECL(qemuDomainFSDriver)
+VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
+ "local",
+ "local",
+ "handle");
+
static void
uname_normalize (struct utsname *ut)
virBitmapPtr qemuCaps ATTRIBUTE_UNUSED)
{
virBuffer opt = VIR_BUFFER_INITIALIZER;
+ const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
goto error;
}
- virBufferAddLit(&opt, "local");
+ if (!driver) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Filesystem driver type not supported"));
+ goto error;
+ }
+ virBufferAdd(&opt, driver, -1);
+
if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_MAPPED) {
virBufferAddLit(&opt, ",security_model=mapped");
} else if(fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
/dev/HostVG/QEMUGuest1 -fsdev local,security_model=passthrough,id=fsdev-fs0,\
path=/export/to/guest -device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,\
-mount_tag=/import/from/host,bus=pci.0,addr=0x3 -usb -device virtio-balloon-pci,\
-id=balloon0,bus=pci.0,addr=0x4
+mount_tag=/import/from/host,bus=pci.0,addr=0x3 \
+-fsdev handle,security_model=mapped,id=fsdev-fs1,\
+path=/export/to/guest2 -device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,\
+mount_tag=/import/from/host2,bus=pci.0,addr=0x4 \
+-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
<source dir='/export/to/guest'/>
<target dir='/import/from/host'/>
</filesystem>
+ <filesystem accessmode='mapped'>
+ <driver type='handle'/>
+ <source dir='/export/to/guest2'/>
+ <target dir='/import/from/host2'/>
+ </filesystem>
</devices>
</domain>