aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2011-05-03 13:45:49 +0200
committerHannes Reinecke <hare@suse.de>2011-05-03 13:45:49 +0200
commit90773ba8f164285092f347089c95df0055c98de1 (patch)
treee744f4a38fc6f80c3ef2f69a4180db6491304855
parentc919aea24b617f239d1a8d973b2f4593a6948bfa (diff)
downloadmultipath-tools-90773ba8f164285092f347089c95df0055c98de1.tar.gz
libmultipath: resolve hash collisions in pgcmp()
pgcmp() is using a simple xor algorithm for hashing. Main intention here is to have a quick comparison if two paths are identical. However, this algorithm is prone to hash collisions, so even if two hashes match we should still check the individual paths to avoid collisions. Signed-off-by: Hannes Reinecke <hare@suse.de>
-rw-r--r--libmultipath/configure.c3
-rw-r--r--libmultipath/structs.c20
-rw-r--r--libmultipath/structs.h1
3 files changed, 23 insertions, 1 deletions
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
index d512a1a..95406a5 100644
--- a/libmultipath/configure.c
+++ b/libmultipath/configure.c
@@ -132,7 +132,8 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp)
compute_pgid(pgp);
vector_foreach_slot (cmpp->pg, cpgp, j) {
- if (pgp->id == cpgp->id) {
+ if (pgp->id == cpgp->id &&
+ !pathcmp(pgp, cpgp)) {
r = 0;
break;
}
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
index 82df680..25a5a0e 100644
--- a/libmultipath/structs.c
+++ b/libmultipath/structs.c
@@ -371,6 +371,26 @@ pathcount (struct multipath * mpp, int state)
return count;
}
+extern int
+pathcmp (struct pathgroup *pgp, struct pathgroup *cpgp)
+{
+ int i, j;
+ struct path *pp, *cpp;
+ int pnum = 0, found = 0;
+
+ vector_foreach_slot(pgp->paths, pp, i) {
+ pnum++;
+ vector_foreach_slot(cpgp->paths, cpp, j) {
+ if ((long)pp == (long)cpp) {
+ found++;
+ break;
+ }
+ }
+ }
+
+ return pnum - found;
+}
+
struct path *
first_path (struct multipath * mpp)
{
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index e793028..cab9828 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -251,6 +251,7 @@ struct path * first_path (struct multipath * mpp);
int pathcountgr (struct pathgroup *, int);
int pathcount (struct multipath *, int);
+int pathcmp (struct pathgroup *, struct pathgroup *);
void setup_feature(struct multipath *, char *);
extern char sysfs_path[PATH_SIZE];