
On qemu-5.2.0-4.fc34.x86_64, libvirt v6.10.0-262-gbed50bcbbb with this patch series, by following script: #!/bin/bash - set -o nounset # Treat unset variables as an error VM=test NFS_EXPORT=/tmp/nfs IMG=disk1 DISK_XML=/tmp/nfs.xml mkdir -p $NFS_EXPORT echo "$NFS_EXPORT *(rw,no_root_squash,insecure)" > /etc/exports systemctl restart nfs-server qemu-img create nfs://localhost"$NFS_EXPORT/$IMG" 100M chmod 777 $NFS_EXPORT -R virsh start $VM --console echo "<disk type='network' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source protocol='nfs' name='$NFS_EXPORT/$IMG'> <host name='localhost'/> <nfs user='+107' group='+107'/> </source> <target dev='vdb' bus='virtio'/> </disk>" > $DISK_XML virsh attach-device $VM $DISK_XML virsh console $VM virsh detach-device $VM $DISK_XML virsh console $VM virsh destroy $VM virsh attach-device $VM $DISK_XML --config virsh start $VM --console virsh destroy $VM virsh detach-device $VM $DISK_XML --config It works for me. All attach/detach tests have passed. On Wed, Dec 30, 2020 at 5:23 AM Ryan Gahagan <rgahagan@cs.utexas.edu> wrote:
Signed-off-by: Ryan Gahagan <rgahagan@cs.utexas.edu> --- src/qemu/qemu_block.c | 79 +++++++++++++++++++++++++++++++++++++++++- src/qemu/qemu_domain.c | 47 +++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index b224a550f3..5413a4f0e8 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -574,6 +574,35 @@ qemuBlockStorageSourceBuildJSONInetSocketAddress(virStorageNetHostDefPtr host) }
+/** + * qemuBlockStorageSourceBuildJSONNFSServer(virStorageNetHostDefPtr host) + * @host: the virStorageNetHostDefPtr definition to build + * + * Formats @hosts into a json object conforming to the 'NFSServer' type + * in qemu. + * + * Returns a virJSONValuePtr for a single server. + */ +static virJSONValuePtr +qemuBlockStorageSourceBuildJSONNFSServer(virStorageNetHostDefPtr host) +{ + virJSONValuePtr ret = NULL; + + if (host->transport != VIR_STORAGE_NET_HOST_TRANS_TCP) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("only TCP protocol can be converted to NFSServer")); + return NULL; + } + + ignore_value(virJSONValueObjectCreate(&ret, + "s:host", host->name, + "s:type", "inet", + NULL)); + + return ret; +} + + /** * qemuBlockStorageSourceBuildHostsJSONInetSocketAddress: * @src: disk storage source @@ -674,6 +703,44 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src, }
+static virJSONValuePtr +qemuBlockStorageSourceGetNFSProps(virStorageSourcePtr src) +{ + g_autoptr(virJSONValue) server = NULL; + virJSONValuePtr ret = NULL; + + if (src->nhosts != 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("NFS protocol accepts only one host")); + return NULL; + } + + if (!(server = qemuBlockStorageSourceBuildJSONNFSServer(&src->hosts[0]))) + return NULL; + + /* NFS disk specification example: + * { driver:"nfs", + * user: "0", + * group: "0", + * path: "/foo/bar/baz", + * server: {type:"tcp", host:"1.2.3.4"}} + */ + ignore_value(virJSONValueObjectCreate(&ret, + "a:server", &server, + "S:path", src->path, NULL)); + + if (src->nfs_uid != -1 && + virJSONValueObjectAdd(ret, "i:user", src->nfs_uid, NULL) < 0) + return NULL; + + if (src->nfs_gid != -1 && + virJSONValueObjectAdd(ret, "i:group", src->nfs_gid, NULL) < 0) + return NULL; + + return ret; +} + + static virJSONValuePtr qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src, bool onlytarget) @@ -1181,6 +1248,11 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, break;
case VIR_STORAGE_NET_PROTOCOL_NFS: + driver = "nfs"; + if (!(fileprops = qemuBlockStorageSourceGetNFSProps(src))) + return NULL; + break; + case VIR_STORAGE_NET_PROTOCOL_NONE: case VIR_STORAGE_NET_PROTOCOL_LAST: virReportEnumRangeError(virStorageNetProtocol, src->protocol); @@ -2500,11 +2572,16 @@ qemuBlockStorageSourceCreateGetStorageProps(virStorageSourcePtr src, return -1; break;
+ case VIR_STORAGE_NET_PROTOCOL_NFS: + driver = "nfs"; + if (!(location = qemuBlockStorageSourceGetNFSProps(src))) + return -1; + break; + /* unsupported/impossible */ case VIR_STORAGE_NET_PROTOCOL_NBD: case VIR_STORAGE_NET_PROTOCOL_ISCSI: case VIR_STORAGE_NET_PROTOCOL_VXHS: - case VIR_STORAGE_NET_PROTOCOL_NFS: case VIR_STORAGE_NET_PROTOCOL_HTTP: case VIR_STORAGE_NET_PROTOCOL_HTTPS: case VIR_STORAGE_NET_PROTOCOL_FTP: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d91c32b2c5..8812df5138 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4626,6 +4626,14 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src, return -1; }
+ /* NFS protocol may only be used if current QEMU supports blockdev */ + if (actualType == VIR_STORAGE_TYPE_NETWORK && + src->protocol == VIR_STORAGE_NET_PROTOCOL_NFS && + !blockdev) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("'nfs' protocol is not supported with this QEMU binary")); + } + return 0; }
@@ -9590,6 +9598,42 @@ qemuProcessPrepareStorageSourceTLSNBD(virStorageSourcePtr src, }
+/* qemuPrepareStorageSourceNFS: + * @src: source for a disk + * + * If src is an NFS source, translate nfs_user and nfs_group + * into a uid and gid field. If these strings are empty (ie "") + * then provide the hypervisor default uid and gid. + */ +static int +qemuDomainPrepareStorageSourceNFS(virStorageSourcePtr src) +{ + if (virStorageSourceGetActualType(src) != VIR_STORAGE_TYPE_NETWORK) + return 0; + + if ((virStorageNetProtocol) src->protocol != VIR_STORAGE_NET_PROTOCOL_NFS) + return 0; + + if (src->nfs_user) { + if (virGetUserID(src->nfs_user, &src->nfs_uid) < 0) + return -1; + } else { + /* -1 indicates default UID */ + src->nfs_uid = -1; + } + + if (src->nfs_group) { + if (virGetGroupID(src->nfs_group, &src->nfs_gid) < 0) + return -1; + } else { + /* -1 indicates default GID */ + src->nfs_gid = -1; + } + + return 0; +} + + /* qemuProcessPrepareStorageSourceTLS: * @source: source for a disk * @cfg: driver configuration @@ -10401,6 +10445,9 @@ qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDefPtr disk, priv) < 0) return -1;
+ if (qemuDomainPrepareStorageSourceNFS(src) < 0) + return -1; + return 0; }
-- 2.29.2
-- Tested-by: Han Han <hhan@redhat.com>