]> xenbits.xensource.com Git - libvirt.git/commitdiff
xenconfig: add conversion of usb controller config to and from xml
authorChunyan Liu <cyliu@suse.com>
Wed, 15 Jun 2016 06:00:12 +0000 (14:00 +0800)
committerCédric Bosdonnat <cbosdonnat@suse.com>
Tue, 2 Aug 2016 12:02:21 +0000 (14:02 +0200)
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>
src/xenconfig/xen_xl.c
tests/xlconfigdata/test-usbctrl.cfg [new file with mode: 0644]
tests/xlconfigdata/test-usbctrl.xml [new file with mode: 0644]
tests/xlconfigtest.c

index 25a3621084d4023ca69d0b1bf4c549e306356a08..7774dfc0096b6e2d324289bbd4fb1d283c033199 100644 (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:
diff --git a/tests/xlconfigdata/test-usbctrl.cfg b/tests/xlconfigdata/test-usbctrl.cfg
new file mode 100644 (file)
index 0000000..91e9460
--- /dev/null
@@ -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" ]
diff --git a/tests/xlconfigdata/test-usbctrl.xml b/tests/xlconfigdata/test-usbctrl.xml
new file mode 100644 (file)
index 0000000..3c03f37
--- /dev/null
@@ -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>
index 4248da13e20ecd3541953a60e1d8845508443b2a..401e5607d11cacf941cef1effe66d51c5942e992 100644 (file)
@@ -278,6 +278,7 @@ mymain(void)
 #endif
     DO_TEST("vif-typename");
     DO_TEST("usb");
+    DO_TEST("usbctrl");
 
     virObjectUnref(caps);
     virObjectUnref(xmlopt);