[libvirt] [PATCH v2 3/4] xenconfig: channels conversion support

Jim Fehlig jfehlig at suse.com
Fri Sep 23 22:18:25 UTC 2016


On 09/22/2016 01:53 PM, Joao Martins wrote:
> Add support for formating/parsing libxl channels.
>
> Syntax on xen libxl goes as following:
> channel=["connection=pty|socket,path=/path/to/socket,name=XXX",...]
>
> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
> ---
> Changes since v1:
> * Move path to UNIX case.
> ---
>  src/xenconfig/xen_xl.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 176 insertions(+)
>
> diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
> index 7774dfc..0c02e1f 100644
> --- a/src/xenconfig/xen_xl.c
> +++ b/src/xenconfig/xen_xl.c
> @@ -685,6 +685,93 @@ xenParseXLUSB(virConfPtr conf, virDomainDefPtr def)
>      return 0;
>  }
>  
> +static int
> +xenParseXLChannel(virConfPtr conf, virDomainDefPtr def)
> +{
> +    virConfValuePtr list = virConfGetValue(conf, "channel");
> +    virDomainChrDefPtr channel = NULL;
> +    char *name = NULL;
> +    char *path = NULL;
> +
> +    if (list && list->type == VIR_CONF_LIST) {
> +        list = list->list;
> +        while (list) {
> +            char type[10];
> +            char *key;
> +
> +            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
> +                goto skipchannel;
> +
> +            key = list->str;
> +            while (key) {
> +                char *data;
> +                char *nextkey = strchr(key, ',');
> +
> +                if (!(data = strchr(key, '=')))
> +                    goto skipchannel;
> +                data++;
> +
> +                if (STRPREFIX(key, "connection=")) {
> +                    int len = nextkey ? (nextkey - data) : sizeof(type) - 1;
> +                    if (virStrncpy(type, data, len, sizeof(type)) == NULL) {
> +                        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                                       _("connection %s too big"), data);
> +                        goto skipchannel;
> +                    }
> +                } else if (STRPREFIX(key, "name=")) {
> +                    int len = nextkey ? (nextkey - data) : strlen(data);
> +                    VIR_FREE(name);
> +                    if (VIR_STRNDUP(name, data, len) < 0)
> +                        goto cleanup;
> +                } else if (STRPREFIX(key, "path=")) {
> +                    int len = nextkey ? (nextkey - data) : strlen(data);
> +                    VIR_FREE(path);
> +                    if (VIR_STRNDUP(path, data, len) < 0)
> +                        goto cleanup;
> +                }
> +
> +                while (nextkey && (nextkey[0] == ',' ||
> +                                   nextkey[0] == ' ' ||
> +                                   nextkey[0] == '\t'))
> +                    nextkey++;
> +                key = nextkey;
> +            }
> +
> +            if (!(channel = virDomainChrDefNew()))
> +                goto cleanup;
> +
> +            if (STRPREFIX(type, "socket")) {
> +                channel->source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
> +                channel->source.data.nix.path = path;
> +                channel->source.data.nix.listen = 1;
> +            } else if (STRPREFIX(type, "pty")) {
> +                channel->source.type = VIR_DOMAIN_CHR_TYPE_PTY;
> +                VIR_FREE(path);
> +            } else {
> +                goto cleanup;
> +            }
> +
> +            channel->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL;
> +            channel->targetType = VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN;
> +            channel->target.name = name;
> +
> +            if (VIR_APPEND_ELEMENT(def->channels, def->nchannels, channel) < 0)
> +                goto cleanup;
> +
> +        skipchannel:
> +            list = list->next;
> +        }
> +    }
> +
> +    return 0;
> +
> + cleanup:

'error' is probably a better name for these labels that handle error cases, but
I see 'cleanup' is used in most of this file :-/.

ACK either way.

Regards,
Jim

> +    virDomainChrDefFree(channel);
> +    VIR_FREE(path);
> +    VIR_FREE(name);
> +    return -1;
> +}
> +
>  virDomainDefPtr
>  xenParseXL(virConfPtr conf,
>             virCapsPtr caps,
> @@ -720,6 +807,9 @@ xenParseXL(virConfPtr conf,
>      if (xenParseXLUSBController(conf, def) < 0)
>          goto cleanup;
>  
> +    if (xenParseXLChannel(conf, def) < 0)
> +        goto cleanup;
> +
>      if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
>                                xmlopt) < 0)
>          goto cleanup;
> @@ -1347,6 +1437,89 @@ xenFormatXLUSB(virConfPtr conf,
>      return -1;
>  }
>  
> +static int
> +xenFormatXLChannel(virConfValuePtr list, virDomainChrDefPtr channel)
> +{
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    int sourceType = channel->source.type;
> +    virConfValuePtr val, tmp;
> +
> +    /* connection */
> +    virBufferAddLit(&buf, "connection=");
> +    switch (sourceType) {
> +        case VIR_DOMAIN_CHR_TYPE_PTY:
> +            virBufferAddLit(&buf, "pty,");
> +            break;
> +        case VIR_DOMAIN_CHR_TYPE_UNIX:
> +            virBufferAddLit(&buf, "socket,");
> +            /* path */
> +            if (channel->source.data.nix.path)
> +                virBufferAsprintf(&buf, "path=%s,",
> +                                  channel->source.data.nix.path);
> +            break;
> +        default:
> +            goto cleanup;
> +    }
> +
> +    /* name */
> +    virBufferAsprintf(&buf, "name=%s", channel->target.name);
> +
> +    if (VIR_ALLOC(val) < 0)
> +        goto cleanup;
> +
> +    val->type = VIR_CONF_STRING;
> +    val->str = virBufferContentAndReset(&buf);
> +    tmp = list->list;
> +    while (tmp && tmp->next)
> +        tmp = tmp->next;
> +    if (tmp)
> +        tmp->next = val;
> +    else
> +        list->list = val;
> +    return 0;
> +
> + cleanup:
> +    virBufferFreeAndReset(&buf);
> +    return -1;
> +}
> +
> +static int
> +xenFormatXLDomainChannels(virConfPtr conf, virDomainDefPtr def)
> +{
> +    virConfValuePtr channelVal = NULL;
> +    size_t i;
> +
> +    if (VIR_ALLOC(channelVal) < 0)
> +        goto cleanup;
> +
> +    channelVal->type = VIR_CONF_LIST;
> +    channelVal->list = NULL;
> +
> +    for (i = 0; i < def->nchannels; i++) {
> +        virDomainChrDefPtr chr = def->channels[i];
> +
> +        if (chr->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN)
> +            continue;
> +
> +        if (xenFormatXLChannel(channelVal, def->channels[i]) < 0)
> +            goto cleanup;
> +    }
> +
> +    if (channelVal->list != NULL) {
> +        int ret = virConfSetValue(conf, "channel", channelVal);
> +        channelVal = NULL;
> +        if (ret < 0)
> +            goto cleanup;
> +    }
> +
> +    VIR_FREE(channelVal);
> +    return 0;
> +
> + cleanup:
> +    virConfFreeValue(channelVal);
> +    return -1;
> +}
> +
>  virConfPtr
>  xenFormatXL(virDomainDefPtr def, virConnectPtr conn)
>  {
> @@ -1376,6 +1549,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn)
>      if (xenFormatXLUSBController(conf, def) < 0)
>          goto cleanup;
>  
> +    if (xenFormatXLDomainChannels(conf, def) < 0)
> +        goto cleanup;
> +
>      return conf;
>  
>   cleanup:




More information about the libvir-list mailing list