render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
9119d9
From 1d70a81c71b2e09219377496f22ceabc22c89078 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <1d70a81c71b2e09219377496f22ceabc22c89078@dist-git>
9119d9
From: John Ferlan <jferlan@redhat.com>
9119d9
Date: Tue, 28 Oct 2014 22:13:33 -0400
9119d9
Subject: [PATCH] storage_conf: Resolve libvirtd crash matching scsi_host
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1146837
9119d9
9119d9
Resolve a crash in libvirtd resulting from commit id 'a4bd62ad' (1.0.6)
9119d9
which added parentaddr and unique_id to allow unique identification of
9119d9
a scsi_host, but assumed that all the pool entries and the incoming
9119d9
definition would be similarly defined. If the existing pool uses the
9119d9
'name' attribute and an incoming pool is using the parentaddr/unique_id,
9119d9
then the code will attempt to compare the existing name string against
9119d9
the incoming name string which doesn't exist (is NULL) and results in
9119d9
a core (STREQ).
9119d9
9119d9
Conversely, if the existing pool used the parentaddr/unique_id and the
9119d9
to be defined pool used the name, then the comparison would be against
9119d9
the parentaddr, but since the incoming pool doesn't have one - that would
9119d9
leave the comparison against a parentaddr of all 0's and a unique_id of 0,
9119d9
which will always comparison to fail. This means someone could define the
9119d9
same source adapter for two pools
9119d9
9119d9
In order to resolve this, adjust the code to get the 'host#' to be used
9119d9
by the storage scsi backend in order to check/start the pool and make sure
9119d9
the incoming definition doesn't match any of the existing pool defs.
9119d9
9119d9
(cherry picked from commit 3f99d64db8a64675eefed9485fad720c630a816e)
9119d9
Signed-off-by: John Ferlan <jferlan@redhat.com>
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/conf/storage_conf.c | 67 ++++++++++++++++++++++++++++++-------------------
9119d9
 1 file changed, 41 insertions(+), 26 deletions(-)
9119d9
9119d9
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
9119d9
index d42cde7..7fa3dbf 100644
9119d9
--- a/src/conf/storage_conf.c
9119d9
+++ b/src/conf/storage_conf.c
9119d9
@@ -2061,26 +2061,37 @@ virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
9119d9
     return ret;
9119d9
 }
9119d9
 
9119d9
-static bool
9119d9
-matchSCSIAdapterParent(virStoragePoolObjPtr pool,
9119d9
-                       virStoragePoolDefPtr def)
9119d9
+static int
9119d9
+getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
9119d9
+                  unsigned int *hostnum)
9119d9
 {
9119d9
-    virDevicePCIAddressPtr pooladdr =
9119d9
-        &pool->def->source.adapter.data.scsi_host.parentaddr;
9119d9
-    virDevicePCIAddressPtr defaddr =
9119d9
-        &def->source.adapter.data.scsi_host.parentaddr;
9119d9
-    int pool_unique_id =
9119d9
-        pool->def->source.adapter.data.scsi_host.unique_id;
9119d9
-    int def_unique_id =
9119d9
-        def->source.adapter.data.scsi_host.unique_id;
9119d9
-    if (pooladdr->domain == defaddr->domain &&
9119d9
-        pooladdr->bus == defaddr->bus &&
9119d9
-        pooladdr->slot == defaddr->slot &&
9119d9
-        pooladdr->function == defaddr->function &&
9119d9
-        pool_unique_id == def_unique_id) {
9119d9
-        return true;
9119d9
+    int ret = -1;
9119d9
+    unsigned int num;
9119d9
+    char *name = NULL;
9119d9
+
9119d9
+    if (adapter.data.scsi_host.has_parent) {
9119d9
+        virDevicePCIAddress addr = adapter.data.scsi_host.parentaddr;
9119d9
+        unsigned int unique_id = adapter.data.scsi_host.unique_id;
9119d9
+
9119d9
+        if (!(name = virGetSCSIHostNameByParentaddr(addr.domain,
9119d9
+                                                    addr.bus,
9119d9
+                                                    addr.slot,
9119d9
+                                                    addr.function,
9119d9
+                                                    unique_id)))
9119d9
+            goto cleanup;
9119d9
+        if (virGetSCSIHostNumber(name, &num) < 0)
9119d9
+            goto cleanup;
9119d9
+    } else {
9119d9
+        if (virGetSCSIHostNumber(adapter.data.scsi_host.name, &num) < 0)
9119d9
+            goto cleanup;
9119d9
     }
9119d9
-    return false;
9119d9
+
9119d9
+    *hostnum = num;
9119d9
+    ret = 0;
9119d9
+
9119d9
+ cleanup:
9119d9
+    VIR_FREE(name);
9119d9
+    return ret;
9119d9
 }
9119d9
 
9119d9
 int
9119d9
@@ -2129,14 +2140,14 @@ virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
9119d9
                        VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST &&
9119d9
                        def->source.adapter.type ==
9119d9
                        VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
9119d9
-                if (pool->def->source.adapter.data.scsi_host.name) {
9119d9
-                    if (STREQ(pool->def->source.adapter.data.scsi_host.name,
9119d9
-                              def->source.adapter.data.scsi_host.name))
9119d9
-                        matchpool = pool;
9119d9
-                } else {
9119d9
-                    if (matchSCSIAdapterParent(pool, def))
9119d9
-                        matchpool = pool;
9119d9
-                }
9119d9
+                unsigned int pool_hostnum, def_hostnum;
9119d9
+
9119d9
+                if (getSCSIHostNumber(pool->def->source.adapter,
9119d9
+                                      &pool_hostnum) < 0 ||
9119d9
+                    getSCSIHostNumber(def->source.adapter, &def_hostnum) < 0)
9119d9
+                    goto error;
9119d9
+                if (pool_hostnum == def_hostnum)
9119d9
+                    matchpool = pool;
9119d9
             }
9119d9
             break;
9119d9
         case VIR_STORAGE_POOL_ISCSI:
9119d9
@@ -2176,6 +2187,10 @@ virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
9119d9
         ret = -1;
9119d9
     }
9119d9
     return ret;
9119d9
+
9119d9
+ error:
9119d9
+    virStoragePoolObjUnlock(pool);
9119d9
+    return -1;
9119d9
 }
9119d9
 
9119d9
 void
9119d9
-- 
9119d9
2.1.3
9119d9