[libvirt] [PATCH] virsh: Fix a regression of detaching device

Osier Yang jyang at redhat.com
Mon Dec 19 11:01:19 UTC 2011


Since for node <address>, the values for attrs "domain", "bus", "slot",
"function" are all converted to heximal when parsing the XML. However
commit ea7182c29 tries to examine if the device represented by the XML
from user exists in the domain XML earlier before the XML parsing, and
thus if the user use different base to represent the device address, e.g.
  <address type='pci' domain='0' bus='0' slot='7'/>

vshCompleteXMLFromDomain won't find the device, and quit with error
"no such device" even if the device does exist.
---
 tools/virsh.c |   41 +++++++++++++++++++++++++++++++++++------
 1 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 3654589..5c78995 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -12107,12 +12107,14 @@ vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2)
 {
     xmlNodePtr child1, child2;
     xmlAttrPtr attr;
-    char *prop1, *prop2;
+    char *prop1 = NULL;
+    char *prop2 = NULL;
     bool found;
     bool visited;
     bool ret = false;
     long n1_child_size, n2_child_size, n1_iter;
-    virBitmapPtr bitmap;
+    virBitmapPtr bitmap = NULL;
+    unsigned int prop1_ui, prop2_ui;
 
     if (!n1 && !n2)
         return true;
@@ -12129,13 +12131,36 @@ vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2)
         if (attr->type == XML_ATTRIBUTE_NODE) {
             prop1 = virXMLPropString(n1, (const char *) attr->name);
             prop2 = virXMLPropString(n2, (const char *) attr->name);
-            if (STRNEQ_NULLABLE(prop1, prop2)) {
-                xmlFree(prop1);
-                xmlFree(prop2);
-                return false;
+
+            if (STREQ((const char *)n2->name, "address") &&
+                prop1 && prop2 &&
+                (STREQ((const char *)attr->name, "domain") ||
+                 STREQ((const char *)attr->name, "bus") ||
+                 STREQ((const char *)attr->name, "slot") ||
+                 STREQ((const char *)attr->name, "function"))) {
+                if (virStrToLong_ui(prop1, NULL, 0, &prop1_ui) < 0) {
+                    vshError(NULL, _("can't parse value for %s"), attr->name);
+                    goto cleanup;
+                }
+
+                if (virStrToLong_ui(prop2, NULL, 0, &prop2_ui) < 0) {
+                    vshError(NULL, _("can't parse value for %s"), attr->name);
+                    goto cleanup;
+                }
+
+                if (prop1_ui != prop2_ui) {
+                    goto cleanup;
+                }
+            } else {
+                if (STRNEQ_NULLABLE(prop1, prop2)) {
+                    goto cleanup;
+                }
             }
+
             xmlFree(prop1);
+            prop1 = NULL;
             xmlFree(prop2);
+            prop2 = NULL;
         }
         attr = attr->next;
     }
@@ -12207,6 +12232,10 @@ vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2)
     ret = true;
 
 cleanup:
+    if (prop1)
+        xmlFree(prop1);
+    if (prop2)
+        xmlFree(prop2);
     virBitmapFree(bitmap);
     return ret;
 }
-- 
1.7.7.3




More information about the libvir-list mailing list