[libvirt] [PATCH v3] Introduce <driver> under <filesystem> to support open-by-handle.

VirtFS allows the user to choose between path/handle based fs driver. As of now, libvirt hardcode to use 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> v3: - use enum for fs driver type (qemuDomainFSDriver) v2: - use 'path' instead of 'local' in xml terminology - added default enum for optional driver type --- docs/schemas/domaincommon.rng | 9 +++++++++ src/conf/domain_conf.c | 24 ++++++++++++++++++++++++ src/conf/domain_conf.h | 11 +++++++++++ src/qemu/qemu_command.c | 15 ++++++++++++++- 4 files changed, 58 insertions(+), 1 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 492a41d..3937393 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1025,6 +1025,15 @@ </choice> <optional> <ref name="address"/> + <element name="driver"> + <attribute name="type"> + <choice> + <value>path</value> + <value>handle</value> + </choice> + </attribute> + <empty/> + </element> <attribute name="accessmode"> <choice> <value>passthrough</value> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a537251..ede1f01 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -238,6 +238,11 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "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", @@ -2828,6 +2833,7 @@ virDomainFSDefParseXML(xmlNodePtr node, virDomainFSDefPtr def; xmlNodePtr cur; char *type = NULL; + char *fsdriver = NULL; char *source = NULL; char *target = NULL; char *accessmode = NULL; @@ -2878,11 +2884,23 @@ virDomainFSDefParseXML(xmlNodePtr node, 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; + } + } else { + def->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH; + } + if (source == NULL) { virDomainReportError(VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target); @@ -2905,6 +2923,7 @@ virDomainFSDefParseXML(xmlNodePtr node, cleanup: VIR_FREE(type); + VIR_FREE(fsdriver); VIR_FREE(target); VIR_FREE(source); VIR_FREE(accessmode); @@ -9351,6 +9370,7 @@ virDomainFSDefFormat(virBufferPtr buf, { 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, @@ -9369,6 +9389,10 @@ virDomainFSDefFormat(virBufferPtr buf, " <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: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e07fd2f..4f8993b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -368,6 +368,15 @@ enum virDomainFSType { 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, @@ -381,6 +390,7 @@ typedef struct _virDomainFSDef virDomainFSDef; typedef virDomainFSDef *virDomainFSDefPtr; struct _virDomainFSDef { int type; + int fsdriver; int accessmode; char *src; char *dst; @@ -1856,6 +1866,7 @@ VIR_ENUM_DECL(virDomainController) 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) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index cf99f89..b4f4bd8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -100,6 +100,12 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "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) @@ -1811,6 +1817,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, 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", @@ -1818,7 +1825,13 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, 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) { -- 1.7.1.1

On Tue, Oct 11, 2011 at 05:00:40PM +0530, Harsh Prateek Bora wrote:
VirtFS allows the user to choose between path/handle based fs driver. As of now, libvirt hardcode to use 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>
v3: - use enum for fs driver type (qemuDomainFSDriver) v2: - use 'path' instead of 'local' in xml terminology - added default enum for optional driver type
--- docs/schemas/domaincommon.rng | 9 +++++++++ src/conf/domain_conf.c | 24 ++++++++++++++++++++++++ src/conf/domain_conf.h | 11 +++++++++++ src/qemu/qemu_command.c | 15 ++++++++++++++- 4 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 492a41d..3937393 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1025,6 +1025,15 @@ </choice> <optional> <ref name="address"/> + <element name="driver"> + <attribute name="type"> + <choice> + <value>path</value> + <value>handle</value> + </choice> + </attribute> + <empty/> + </element> <attribute name="accessmode"> <choice> <value>passthrough</value> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a537251..ede1f01 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -238,6 +238,11 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "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", @@ -2828,6 +2833,7 @@ virDomainFSDefParseXML(xmlNodePtr node, virDomainFSDefPtr def; xmlNodePtr cur; char *type = NULL; + char *fsdriver = NULL; char *source = NULL; char *target = NULL; char *accessmode = NULL; @@ -2878,11 +2884,23 @@ virDomainFSDefParseXML(xmlNodePtr node, 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; + } + } else { + def->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH; + } + if (source == NULL) { virDomainReportError(VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target); @@ -2905,6 +2923,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
cleanup: VIR_FREE(type); + VIR_FREE(fsdriver); VIR_FREE(target); VIR_FREE(source); VIR_FREE(accessmode); @@ -9351,6 +9370,7 @@ virDomainFSDefFormat(virBufferPtr buf, { 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, @@ -9369,6 +9389,10 @@ virDomainFSDefFormat(virBufferPtr buf, " <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: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e07fd2f..4f8993b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -368,6 +368,15 @@ enum virDomainFSType { 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, @@ -381,6 +390,7 @@ typedef struct _virDomainFSDef virDomainFSDef; typedef virDomainFSDef *virDomainFSDefPtr; struct _virDomainFSDef { int type; + int fsdriver; int accessmode; char *src; char *dst; @@ -1856,6 +1866,7 @@ VIR_ENUM_DECL(virDomainController) 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) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index cf99f89..b4f4bd8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -100,6 +100,12 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "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) @@ -1811,6 +1817,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, 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", @@ -1818,7 +1825,13 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, 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) {
ACK, addressed all my comments now Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 10/11/2011 05:35 AM, Daniel P. Berrange wrote:
On Tue, Oct 11, 2011 at 05:00:40PM +0530, Harsh Prateek Bora wrote:
VirtFS allows the user to choose between path/handle based fs driver. As of now, libvirt hardcode to use 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>
--- docs/schemas/domaincommon.rng | 9 +++++++++ src/conf/domain_conf.c | 24 ++++++++++++++++
Oops - forgot to document it in docs/formatdomain.html.in.
src/qemu/qemu_command.c | 15 ++++++++++++++- 4 files changed, 58 insertions(+), 1 deletions(-)
Oops - forgot to add a test that exposes the new XML.
+++ b/docs/schemas/domaincommon.rng @@ -1025,6 +1025,15 @@ </choice> <optional> <ref name="address"/> +<element name="driver">
This must be wrapped in <optional>, to preserve backwards compatibility. Also, you want to tie it only to type='mount', rather than <filesystem> in general. Furthermore, I think our existing RNG for <address> was wrong.
+ if (fsdriver) { + if ((def->fsdriver = virDomainFSDriverTypeTypeFromString(fsdriver))< 0) {
Must be <= 0 so the parser rejects 'default'.
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown fs driver type '%s'"), fsdriver); + goto error; + } + } else { + def->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
This results in an output including <driver>, even if the input lacked it.
ACK, addressed all my comments now
I'm pushing with this squashed in: diff --git i/docs/formatdomain.html.in w/docs/formatdomain.html.in index 8daffb8..c007dff 100644 --- i/docs/formatdomain.html.in +++ w/docs/formatdomain.html.in @@ -1156,6 +1156,7 @@ <target dir='/'/> </filesystem> <filesystem type='mount' accessmode='passthrough'> + <driver type='path'/> <source dir='/export/to/guest'/> <target dir='/import/from/host'/> <readonly/> @@ -1178,6 +1179,11 @@ 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> diff --git i/docs/schemas/domaincommon.rng w/docs/schemas/domaincommon.rng index 3937393..c75ea37 100644 --- i/docs/schemas/domaincommon.rng +++ w/docs/schemas/domaincommon.rng @@ -995,9 +995,12 @@ </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"> @@ -1005,6 +1008,17 @@ </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> @@ -1024,16 +1038,6 @@ </group> </choice> <optional> - <ref name="address"/> - <element name="driver"> - <attribute name="type"> - <choice> - <value>path</value> - <value>handle</value> - </choice> - </attribute> - <empty/> - </element> <attribute name="accessmode"> <choice> <value>passthrough</value> @@ -1045,12 +1049,17 @@ </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 diff --git i/src/conf/domain_conf.c w/src/conf/domain_conf.c index 1ad3ebc..da72ebf 100644 --- i/src/conf/domain_conf.c +++ w/src/conf/domain_conf.c @@ -2892,13 +2892,11 @@ virDomainFSDefParseXML(xmlNodePtr node, } if (fsdriver) { - if ((def->fsdriver = virDomainFSDriverTypeTypeFromString(fsdriver)) < 0) { + if ((def->fsdriver = virDomainFSDriverTypeTypeFromString(fsdriver)) <= 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unknown fs driver type '%s'"), fsdriver); goto error; } - } else { - def->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH; } if (source == NULL) { diff --git i/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args w/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args index 6487fec..4c498ba 100644 --- i/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args +++ w/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args @@ -3,5 +3,8 @@ pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ 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 diff --git i/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml w/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml index 62b12bc..8e817e5 100644 --- i/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml +++ w/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml @@ -24,5 +24,10 @@ <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> -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Harsh Prateek Bora