[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