[PATCH 5/7] qemu: Added NFS JSON props methods

Peter Krempa pkrempa at redhat.com
Mon Jan 4 14:34:22 UTC 2021


On Tue, Dec 29, 2020 at 15:21:27 -0600, Ryan Gahagan wrote:
> Signed-off-by: Ryan Gahagan <rgahagan at 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;

This check belongs into the validation function.

> +    }
> +
> +    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;
> +    }

This check belongs to the validation function.

> +
> +    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)
> 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"));

Here you must also check that the 'port' is not provided and that the
protocol is TCP. Otherwise you'd accept configurations which can't be
represented in qemu silently.


> +    }
> +
>      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)

The typecast to virStorageNetProtocol is required only when you want to
use a 'switch' statement so that the complier checks that all cases are
handled. It's not necessary in a single if-condition.

> +        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;
> +    }




More information about the libvir-list mailing list