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@xxxxxxxxxx> > --- > 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: -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list