>From 5aeda96eafd230af55343e7ef835e081ded484aa Mon Sep 17 00:00:00 2001
From: Chunyan Liu <cyliu@suse.com>
Date: Fri, 25 Jan 2013 17:37:14 +0800
Subject: [PATCH] support managed pci devices in xen driver

---
 src/xenxs/xen_sxpr.c |   22 ++++++++--------------
 src/xenxs/xen_xm.c   |   28 +++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 15 deletions(-)

Index: libvirt-1.2.18.2/src/xenconfig/xen_common.c
===================================================================
--- libvirt-1.2.18.2.orig/src/xenconfig/xen_common.c
+++ libvirt-1.2.18.2/src/xenconfig/xen_common.c
@@ -403,6 +403,8 @@ xenParsePCI(virConfPtr conf, virDomainDe
 {
     virConfValuePtr list = virConfGetValue(conf, "pci");
     virDomainHostdevDefPtr hostdev = NULL;
+    char *opt;
+    int managed = 0;
 
     if (list && list->type == VIR_CONF_LIST) {
         list = list->list;
@@ -424,6 +426,11 @@ xenParsePCI(virConfPtr conf, virDomainDe
             /* pci=['0000:00:1b.0','0000:00:13.0'] */
             if (!(key = list->str))
                 goto skippci;
+
+            opt = strchr(key, ',');
+            if (opt)
+                opt++;
+
             if (!(nextkey = strchr(key, ':')))
                 goto skippci;
             if (virStrncpy(domain, key, (nextkey - key), sizeof(domain)) == NULL) {
@@ -467,10 +474,31 @@ xenParsePCI(virConfPtr conf, virDomainDe
                 goto skippci;
             if (virStrToLong_i(func, NULL, 16, &funcID) < 0)
                 goto skippci;
+
+            if (opt) {
+                char opt_managed[2];
+                char *data;
+
+                opt_managed[0] = '\0';
+                data = strchr(opt, '=');
+                data++;
+
+                if (STRPREFIX(opt, "managed=")) {
+                    if (virStrncpy(opt_managed, data, 1, sizeof(opt_managed)) == NULL) {
+                        virReportError(VIR_ERR_INTERNAL_ERROR,
+                                       _("managed option %s too big for destination"),
+                                       data);
+                        goto skippci;
+                    }
+                }
+                if (virStrToLong_i(opt_managed, NULL, 10, &managed) < 0)
+                    goto skippci;
+            }
+
             if (!(hostdev = virDomainHostdevDefAlloc()))
                return -1;
 
-            hostdev->managed = false;
+            hostdev->managed = managed ? true : false;
             hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
             hostdev->source.subsys.u.pci.addr.domain = domainID;
             hostdev->source.subsys.u.pci.addr.bus = busID;
Index: libvirt-1.2.18.2/src/xenconfig/xen_sxpr.c
===================================================================
--- libvirt-1.2.18.2.orig/src/xenconfig/xen_sxpr.c
+++ libvirt-1.2.18.2/src/xenconfig/xen_sxpr.c
@@ -1070,6 +1070,7 @@ xenParseSxprPCI(virDomainDefPtr def,
         int busID;
         int slotID;
         int funcID;
+        bool managed;
 
         node = cur->u.s.car;
         if (!sexpr_lookup(node, "dev"))
@@ -1117,11 +1118,13 @@ xenParseSxprPCI(virDomainDefPtr def,
             goto error;
         }
 
+        managed = sexpr_int(node, "dev/opts/managed");
+
         if (!(dev = virDomainHostdevDefAlloc()))
            goto error;
 
         dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
-        dev->managed = false;
+        dev->managed = managed ? true : false;
         dev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
         dev->source.subsys.u.pci.addr.domain = domainID;
         dev->source.subsys.u.pci.addr.bus = busID;
@@ -2086,11 +2089,15 @@ static void
 xenFormatSxprPCI(virDomainHostdevDefPtr def,
                  virBufferPtr buf)
 {
-    virBufferAsprintf(buf, "(dev (domain 0x%04x)(bus 0x%02x)(slot 0x%02x)(func 0x%x))",
+    virBufferAsprintf(buf, "(dev (domain 0x%04x)(bus 0x%02x)(slot 0x%02x)(func 0x%x)",
                       def->source.subsys.u.pci.addr.domain,
                       def->source.subsys.u.pci.addr.bus,
                       def->source.subsys.u.pci.addr.slot,
                       def->source.subsys.u.pci.addr.function);
+
+    if (def->managed)
+        virBufferAddLit(buf, "(opts (managed 1))");
+    virBufferAddLit(buf, ")");
 }
 
 
@@ -2109,12 +2116,6 @@ xenFormatSxprOnePCI(virDomainHostdevDefP
                     virBufferPtr buf,
                     int detach)
 {
-    if (def->managed) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("managed PCI devices not supported with XenD"));
-        return -1;
-    }
-
     virBufferAddLit(buf, "(pci ");
     xenFormatSxprPCI(def, buf);
     if (detach)
@@ -2169,12 +2170,6 @@ xenFormatSxprAllPCI(virDomainDefPtr def,
     for (i = 0; i < def->nhostdevs; i++) {
         if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
             def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
-            if (def->hostdevs[i]->managed) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("managed PCI devices not supported with XenD"));
-                return -1;
-            }
-
             xenFormatSxprPCI(def->hostdevs[i], buf);
         }
     }
