xenconfig: add conversion of usb controller config to and from xml

libxl configuration files conversion can now handle USB controllers.
When parting libxl config file, USB controllers with type PV are
ignored as those aren't handled.

Signed-off-by: Chunyan Liu <cyliu@suse.com>
This commit is contained in:
Chunyan Liu 2016-06-15 14:00:12 +08:00 committed by Cédric Bosdonnat
parent f5359e55ec
commit 9a361bbba8
4 changed files with 235 additions and 0 deletions

View File

@ -502,6 +502,110 @@ xenParseXLInputDevs(virConfPtr conf, virDomainDefPtr def)
return 0;
}
static int
xenParseXLUSBController(virConfPtr conf, virDomainDefPtr def)
{
virConfValuePtr list = virConfGetValue(conf, "usbctrl");
virDomainControllerDefPtr controller = NULL;
if (list && list->type == VIR_CONF_LIST) {
list = list->list;
while (list) {
char type[8];
char version[4];
char ports[4];
char *key;
int usbctrl_version = 2; /* by default USB 2.0 */
int usbctrl_ports = 8; /* by default 8 ports */
int usbctrl_type = -1;
type[0] = version[0] = ports[0] = '\0';
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
goto skipusbctrl;
/* usbctrl=['type=pv,version=2,ports=8'] */
key = list->str;
while (key) {
char *data;
char *nextkey = strchr(key, ',');
if (!(data = strchr(key, '=')))
goto skipusbctrl;
data++;
if (STRPREFIX(key, "type=")) {
int len = nextkey ? (nextkey - data) : sizeof(type) - 1;
if (virStrncpy(type, data, len, sizeof(type)) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("type %s invalid"),
data);
goto skipusbctrl;
}
} else if (STRPREFIX(key, "version=")) {
int len = nextkey ? (nextkey - data) : sizeof(version) - 1;
if (virStrncpy(version, data, len, sizeof(version)) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("version %s invalid"),
data);
goto skipusbctrl;
}
if (virStrToLong_i(version, NULL, 16, &usbctrl_version) < 0)
goto skipusbctrl;
} else if (STRPREFIX(key, "ports=")) {
int len = nextkey ? (nextkey - data) : sizeof(ports) - 1;
if (virStrncpy(ports, data, len, sizeof(ports)) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("version %s invalid"),
data);
goto skipusbctrl;
}
if (virStrToLong_i(ports, NULL, 16, &usbctrl_ports) < 0)
goto skipusbctrl;
}
while (nextkey && (nextkey[0] == ',' ||
nextkey[0] == ' ' ||
nextkey[0] == '\t'))
nextkey++;
key = nextkey;
}
if (type[0] == '\0') {
if (usbctrl_version == 1)
usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1;
else
usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2;
} else {
if (STREQLEN(type, "qusb", 4)) {
if (usbctrl_version == 1)
usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1;
else
usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2;
} else {
goto skipusbctrl;
}
}
if (!(controller = virDomainControllerDefNew(VIR_DOMAIN_CONTROLLER_TYPE_USB)))
return -1;
controller->type = VIR_DOMAIN_CONTROLLER_TYPE_USB;
controller->model = usbctrl_type;
controller->opts.usbopts.ports = usbctrl_ports;
if (VIR_APPEND_ELEMENT(def->controllers, def->ncontrollers, controller) < 0) {
virDomainControllerDefFree(controller);
return -1;
}
skipusbctrl:
list = list->next;
}
}
return 0;
}
static int
xenParseXLUSB(virConfPtr conf, virDomainDefPtr def)
{
@ -613,6 +717,9 @@ xenParseXL(virConfPtr conf,
if (xenParseXLUSB(conf, def) < 0)
goto cleanup;
if (xenParseXLUSBController(conf, def) < 0)
goto cleanup;
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
xmlopt) < 0)
goto cleanup;
@ -1093,6 +1200,86 @@ xenFormatXLInputDevs(virConfPtr conf, virDomainDefPtr def)
return -1;
}
static int
xenFormatXLUSBController(virConfPtr conf,
virDomainDefPtr def)
{
virConfValuePtr usbctrlVal = NULL;
int hasUSBCtrl = 0;
size_t i;
for (i = 0; i < def->ncontrollers; i++) {
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
hasUSBCtrl = 1;
break;
}
}
if (!hasUSBCtrl)
return 0;
if (VIR_ALLOC(usbctrlVal) < 0)
return -1;
usbctrlVal->type = VIR_CONF_LIST;
usbctrlVal->list = NULL;
for (i = 0; i < def->ncontrollers; i++) {
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
virConfValuePtr val, tmp;
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (def->controllers[i]->model != -1) {
switch (def->controllers[i]->model) {
case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1:
virBufferAddLit(&buf, "type=qusb,version=1,");
break;
case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2:
virBufferAddLit(&buf, "type=qusb,version=2,");
break;
default:
goto error;
}
}
if (def->controllers[i]->opts.usbopts.ports != -1)
virBufferAsprintf(&buf, "ports=%x",
def->controllers[i]->opts.usbopts.ports);
if (VIR_ALLOC(val) < 0) {
virBufferFreeAndReset(&buf);
goto error;
}
val->type = VIR_CONF_STRING;
val->str = virBufferContentAndReset(&buf);
tmp = usbctrlVal->list;
while (tmp && tmp->next)
tmp = tmp->next;
if (tmp)
tmp->next = val;
else
usbctrlVal->list = val;
}
}
if (usbctrlVal->list != NULL) {
int ret = virConfSetValue(conf, "usbctrl", usbctrlVal);
usbctrlVal = NULL;
if (ret < 0)
return -1;
}
VIR_FREE(usbctrlVal);
return 0;
error:
virConfFreeValue(usbctrlVal);
return -1;
}
static int
xenFormatXLUSB(virConfPtr conf,
virDomainDefPtr def)
@ -1186,6 +1373,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn)
if (xenFormatXLUSB(conf, def) < 0)
goto cleanup;
if (xenFormatXLUSBController(conf, def) < 0)
goto cleanup;
return conf;
cleanup:

View File

@ -0,0 +1,13 @@
name = "XenGuest1"
uuid = "45b60f51-88a9-47a8-a3b3-5e66d71b2283"
maxmem = 512
memory = 512
vcpus = 1
localtime = 0
on_poweroff = "preserve"
on_reboot = "restart"
on_crash = "preserve"
vif = [ "mac=5a:36:0e:be:00:09" ]
bootloader = "/usr/bin/pygrub"
disk = [ "format=qcow2,vdev=xvda,access=rw,backendtype=qdisk,target=/var/lib/xen/images/debian/disk.qcow2" ]
usbctrl = [ "type=qusb,version=2,ports=6" ]

View File

@ -0,0 +1,31 @@
<domain type='xen'>
<name>XenGuest1</name>
<uuid>45b60f51-88a9-47a8-a3b3-5e66d71b2283</uuid>
<memory unit='KiB'>524288</memory>
<currentMemory unit='KiB'>524288</currentMemory>
<vcpu placement='static'>1</vcpu>
<bootloader>/usr/bin/pygrub</bootloader>
<os>
<type arch='x86_64' machine='xenpv'>linux</type>
</os>
<clock offset='utc' adjustment='reset'/>
<on_poweroff>preserve</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>preserve</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/xen/images/debian/disk.qcow2'/>
<target dev='xvda' bus='xen'/>
</disk>
<controller type='usb' index='0' model='qusb2' ports='6'/>
<interface type='ethernet'>
<mac address='5a:36:0e:be:00:09'/>
</interface>
<console type='pty'>
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
<input type='keyboard' bus='xen'/>
</devices>
</domain>

View File

@ -278,6 +278,7 @@ mymain(void)
#endif
DO_TEST("vif-typename");
DO_TEST("usb");
DO_TEST("usbctrl");
virObjectUnref(caps);
virObjectUnref(xmlopt);