On 09/16/2016 05:43 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(a)oracle.com>
---
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..eea24b9 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:
+ 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,");
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* path */
+ if (sourceType == VIR_DOMAIN_CHR_TYPE_UNIX)
+ virBufferAsprintf(&buf, "path=%s,",
channel->source.data.nix.path);
Can this be added to the VIR_DOMAIN_CHR_TYPE_UNIX case above?
Looks good.
Regards,
Jim
+
+ /* 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: