? fix_proc_part_scan.diff
Index: main.c
===================================================================
RCS file: /cvs/cluster/cluster/cman/qdisk/main.c,v
retrieving revision 1.12
diff -u -r1.12 main.c
--- main.c	15 Nov 2007 04:14:15 -0000	1.12
+++ main.c	28 Nov 2007 18:43:43 -0000
@@ -1492,7 +1492,7 @@
 	
 	if (ctx.qc_label) {
 		memset(device, 0, sizeof(device));
-		if (find_partitions("/dev",
+		if (find_partitions("/sys/block",
 				    ctx.qc_label, device,
 				    sizeof(device), 0) != 0) {
 			clulog_and_print(LOG_CRIT, "Unable to match label"
Index: mkqdisk.c
===================================================================
RCS file: /cvs/cluster/cluster/cman/qdisk/mkqdisk.c,v
retrieving revision 1.5
diff -u -r1.5 mkqdisk.c
--- mkqdisk.c	15 Nov 2007 04:14:15 -0000	1.5
+++ mkqdisk.c	28 Nov 2007 18:43:43 -0000
@@ -46,12 +46,12 @@
 		case 'L':
 			/* List */
 			close(2);
-			return find_partitions("/dev",
+			return find_partitions("/sys/block",
 					       NULL, NULL, 0, 1);
 			break;
 		case 'f':
 			close(2);
-			return find_partitions("/dev",
+			return find_partitions("/sys/block",
 					       optarg, device,
 					       sizeof(device), 1);
 		case 'c':
Index: proc.c
===================================================================
RCS file: /cvs/cluster/cluster/cman/qdisk/proc.c,v
retrieving revision 1.4
diff -u -r1.4 proc.c
--- proc.c	15 Nov 2007 04:14:15 -0000	1.4
+++ proc.c	28 Nov 2007 18:43:43 -0000
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/sysmacros.h>
 #include <platform.h>
 #include <stdlib.h>
 #include <string.h>
@@ -69,31 +70,113 @@
 }
 
 
+static int
+is_removable(char *path)
+{
+	char devpath[256];
+	struct stat sb;
+	int i = 0;
+	FILE *f;
+
+	snprintf(devpath, sizeof(devpath), "%s/removable", path);
+
+	if (!lstat(devpath, &sb)) {
+		f = fopen(devpath, "r");
+		if (f) {
+			fscanf(f, "%d\n", &i);
+			fclose(f);
+		}
+	}
+
+	return i;
+}
+
+static int
+is_dev(char *path, int *maj, int *min)
+{
+	char devpath[256];
+	struct stat sb;
+	FILE *f;
+
+	snprintf(devpath, sizeof(devpath), "%s/dev", path);
+
+	if (!lstat(devpath, &sb)) {
+		f = fopen(devpath, "r");
+		if (f) {
+			fscanf(f, "%d:%d", maj, min);
+			fclose(f);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static void
+give_me_a_device_pretty_please(char *path, int maj, int min, char *buf)
+{
+	struct dirent **namelist;
+	struct stat sb;
+	char newpath[256];
+	int n, i;
+
+	i = scandir(path, &namelist, 0, alphasort);
+	if (i <= 0)
+		return;
+
+	for (n = 0; n < i; n++) {
+		if (namelist[n]->d_name[0] != '.') {
+			snprintf(newpath, sizeof(newpath), "%s/%s", path,
+				 namelist[n]->d_name);
+
+			if(!lstat(newpath, &sb)) {
+				if (S_ISDIR(sb.st_mode)) {
+					give_me_a_device_pretty_please(newpath, maj, min, buf);
+					if (strlen(buf))
+						return;
+				}
+				if (S_ISBLK(sb.st_mode)) {
+					if((maj == major(sb.st_rdev)) && min == minor((sb.st_rdev))) {
+						strncpy(buf, newpath, strlen(newpath));
+						return;
+					}
+				}
+			}
+		}
+	}
+	return;
+}
+
 int
 find_partitions(const char *devdir, const char *label,
 	        char *devname, size_t devlen, int print)
 {
 	struct dirent **namelist;
 	struct stat sb;
-	char newpath[256];
-	int n;
+	char newpath[256], buf[256];
+	int n, i, maj, min;
 	quorum_header_t qh;
 
-	n = scandir(devdir, &namelist, 0, alphasort);
-	if (n <= 0)
+	i = scandir(devdir, &namelist, 0, alphasort);
+	if (i <= 0)
 		return -1;
 
-	while (n--) {
-		/* filter out:
-		 * . and ..
-		 * .static and .udev that are typical udev dirs that we don't want to scan
-		 */
-		if (strcmp(namelist[n]->d_name, ".") &&
-		    strcmp(namelist[n]->d_name, "..") &&
-		    strcmp(namelist[n]->d_name, ".static") &&
-		    strcmp(namelist[n]->d_name, ".udev")) {
-			snprintf(newpath, sizeof(newpath), "%s/%s", devdir, namelist[n]->d_name);
-			if (!lstat(newpath, &sb)) {
+	/* we go in alphabetic order */
+	for (n = 0; n < i; n++) {
+
+		/* filter out all hidden entries.. */
+		if (namelist[n]->d_name[0] != '.') {
+
+			snprintf(newpath, sizeof(newpath), "%s/%s", devdir,
+				 namelist[n]->d_name);
+
+			/* So far we know that if we pass this check:
+			 * it's a non-removable block device that contains a
+			 * maj/min set and we need to dig into it. 
+			 */
+			if (!lstat(newpath, &sb) && !is_removable(newpath) &&
+			    is_dev(newpath, &maj, &min)) {
+
 				/* dive into directories */
 				if (S_ISDIR(sb.st_mode)) {
 					if (!find_partitions(newpath, label, devname, devlen, print)) {
@@ -101,23 +184,32 @@
 							return 0;
 					}
 				}
-				/* check if it's a block device */
-				if (S_ISBLK(sb.st_mode)) {
-					if (!check_device(newpath, (char *)label, &qh)) {
-						if (print) {
-							time_t timestamp = qh.qh_timestamp;
-							printf("%s:\n", newpath);
-							printf("\tMagic:   %08x\n", qh.qh_magic);
-							printf("\tLabel:   %s\n", qh.qh_cluster);
-							printf("\tCreated: %s",
-								ctime((time_t *)&timestamp));
-							printf("\tHost:    %s\n\n", qh.qh_updatehost);
-						}
 
-						if (devname && devlen) {
-							strncpy(devname, newpath, devlen);
-							return 0;
-						}
+				memset(buf, 0, sizeof(buf));
+				give_me_a_device_pretty_please("/dev", maj, min, buf);
+
+				/* HUGLY HACK.. to attempt to solve a race where a device might
+				 * have been created in /sys but in /dev yet..
+				 */
+				if (!strlen(buf)) {
+					sleep(2);
+					give_me_a_device_pretty_please("/dev", maj, min, buf);
+				}
+
+				if (strlen(buf) && !check_device(buf, (char *)label, &qh)) {
+					if (print) {
+						time_t timestamp = qh.qh_timestamp;
+						printf("%s:\n", buf);
+						printf("\tMagic:   %08x\n", qh.qh_magic);
+						printf("\tLabel:   %s\n", qh.qh_cluster);
+						printf("\tCreated: %s",
+							ctime((time_t *)&timestamp));
+						printf("\tHost:    %s\n\n", qh.qh_updatehost);
+					}
+
+					if (devname && devlen) {
+						strncpy(devname, buf, devlen);
+						return 0;
 					}
 				}
 			}
