diff --git a/numactl-node-cpubind.patch b/numactl-node-cpubind.patch
new file mode 100644
index 0000000..d2add7e
--- /dev/null
+++ b/numactl-node-cpubind.patch
@@ -0,0 +1,292 @@
+--- numactl-0.9.8/libnuma.c.orig	2006-08-14 14:14:31.000000000 -0400
++++ numactl-0.9.8/libnuma.c	2006-08-14 14:14:37.000000000 -0400
+@@ -118,58 +118,28 @@
+ static int maxnode = -1; 
+ static int maxcpus = -1; 
+ 
+-static int number_of_cpus(void)
++static int number_of_configured_cpus(void)
+ { 
+-	char *line = NULL;
+-	size_t len = 0;
+-	char *s;
+-	FILE *f;
+-	int cpu;
+-	
++	int len = 16; 
++	int n;
++	int olde = errno;
++
+ 	if (maxcpus >= 0) 
+ 		return maxcpus + 1;
+ 
+-	f = fopen("/proc/cpuinfo","r"); 
+-	if (!f) {
+-		int n;
+-		int len = 8192; 
+-		for (;;) { 
+-			unsigned long buffer[CPU_LONGS(len)];
+-			memset(buffer, 0, sizeof(buffer));
+-			n = numa_sched_getaffinity_int(0, CPU_BYTES(len), 
+-						       buffer);
+-			if (n < 0 && errno == EINVAL && len < 1024*1024) {
+-				len *= 2;
+-				continue;
+-			}
+-			if (n >= 0) { 
+-				int i, k;
+-				for (i = 0; i < n / sizeof(long); i++) {
+-					if (!buffer[i])
+-						continue;
+-					for (k = 0; k< 8; k++) 
+-						if (buffer[i] & (1<<k))
+-							maxcpus = i*sizeof(long)+k;
+-				}
+-				return maxcpus;
+-			}
+-			break;
+-		}
+-		numa_warn(W_noproc, "/proc not mounted. Assuming zero nodes: %s", 
+-			  strerror(errno)); 
+-		return 0;
+-	}
+-	maxcpus = 0;
+-	while (getdelim(&line, &len, '\n', f) > 0) { 
+-		if (strncmp(line,"processor",9))
++	do { 
++		unsigned long buffer[CPU_LONGS(len)];
++		memset(buffer, 0, sizeof(buffer));
++		n = numa_sched_getaffinity_int(0, CPU_BYTES(len), buffer);
++		if (n < 0 && errno == EINVAL) {
++			if (len >= 1024*1024) 
++				break;
++			len *= 2;
+ 			continue;
+-		s = line + strcspn(line, "0123456789"); 
+-		if (sscanf(s, "%d", &cpu) == 1 && cpu > maxcpus) 
+-			maxcpus = cpu;
+-	} 
+-	free(line);
+-	fclose(f); 
+-	return maxcpus + 1;
++		}
++	} while (n < 0);
++	errno = olde;
++	return len;
+ } 
+ 
+ static int fallback_max_node(void)
+@@ -428,32 +398,67 @@
+ 
+ static unsigned long *node_cpu_mask[NUMA_NUM_NODES];  
+ 
++static void bad_cpumap(int ncpus, unsigned long *mask)
++{
++	int n;
++	for (n = 0; n < ncpus; n++)
++		set_bit(n, mask);
++}
++
++int numa_parse_bitmap(char *line, unsigned long *mask, int ncpus)
++{
++	int i;
++	char *p = strchr(line, '\n'); 
++	if (!p)
++		return -1;
++
++	for (i = 0; p > line;i++) {
++		char *oldp, *endp; 
++		oldp = p;
++		if (*p == ',') 
++			--p;
++		while (p > line && *p != ',')
++			--p;
++		/* Eat two 32bit fields at a time to get longs */
++		if (sizeof(unsigned long) == 8) {
++			oldp--;
++			memmove(p, p+1, oldp-p+1);
++			while (p > line && *p != ',')
++				--p;
++		}
++		if (*p == ',')
++			p++;
++		if (i >= CPU_LONGS(ncpus))
++			return -1;
++		mask[i] = strtoul(p, &endp, 16);
++		if (endp != oldp)
++			return -1;
++		p--;
++	}
++	return 0;
++}
++
+ /* This would be better with some locking, but I don't want to make libnuma
+    dependent on pthreads right now. The races are relatively harmless. */
+ int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) 
+ {
++	int err = 0;
+ 	char fn[64];
+ 	FILE *f; 
+ 	char *line = NULL; 
+ 	size_t len = 0; 
+-	char *s;
+-	int n;
+ 	int buflen_needed;
+-	unsigned long *mask, prev;
+-	int ncpus = number_of_cpus();
+-	int i;
+-	int mask_words;
+-	int bits_in_mask_0;
++	unsigned long *mask;
++	int ncpus = number_of_configured_cpus();
+ 
+ 	buflen_needed = CPU_BYTES(ncpus);
+ 	if ((unsigned)node > maxnode || bufferlen < buflen_needed) { 
+ 		errno = ERANGE;
+ 		return -1;
+ 	}
+-
++	if (bufferlen > buflen_needed)
++		memset(buffer, 0, bufferlen); 
+ 	if (node_cpu_mask[node]) { 
+-		if (bufferlen > buflen_needed)
+-			memset(buffer, 0, bufferlen); 
+ 		memcpy(buffer, node_cpu_mask[node], buflen_needed);
+ 		return 0;
+ 	}
+@@ -462,73 +467,43 @@
+ 	if (!mask) 
+ 		mask = (unsigned long *)buffer; 
+ 	memset(mask, 0, buflen_needed); 
+-			
++
+ 	sprintf(fn, "/sys/devices/system/node/node%d/cpumap", node); 
+ 	f = fopen(fn, "r"); 
+ 	if (!f || getdelim(&line, &len, '\n', f) < 1) { 
+ 		numa_warn(W_nosysfs2,
+ 		   "/sys not mounted or invalid. Assuming one node: %s",
+ 			  strerror(errno)); 
+-		for (n = 0; n < ncpus; n++)
+-			set_bit(n, (unsigned long *)mask);
+-		goto out;
++		bad_cpumap(ncpus, mask);
++		err = -1;
+ 	} 
+-        mask_words = 0;
+-	bits_in_mask_0 = 0;
+-	n = 0;
+-	s = line;
+-	prev = 0; 
+-        for (i = 0; s[i]; i++) {
+-                static const char hexdigits[] = "0123456789abcdef";
+-                char *w = strchr(hexdigits, tolower(s[i]));
+-                if (!w) {
+-                        if (isspace(s[i]) || s[i] == ',')
+-                                continue;
+-                        numa_warn(W_cpumap,
+-                                  "Unexpected character `%c' in sysfs cpumap", 
+-					s[i]);
+-                        set_bit(node, mask);
+-                        goto out;
+-		}
++	if (f)
++		fclose(f);
+ 
+-		/* if mask[0] is full shift left before adding another */
+-		if (bits_in_mask_0 >= sizeof(mask[0])*8) {
+-		        /* skip any leading zeros */
+-		        if (prev || mask[0]){
+-			        /* shift over any previously loaded masks */
+-			        memmove(mask+mask_words+1, mask+mask_words,
+-					sizeof(mask[0]) * mask_words);
+-				mask_words++;
+-				bits_in_mask_0 = 0;
+-				mask[0] = 0;
+-				prev = 1;
+-			}
+-		}
+- 
+-		mask[0] = (mask[0]*16) + (w - hexdigits);
+-	      	bits_in_mask_0 += 4; /* 4 bits per hex char */
++	if (line && numa_parse_bitmap(line, mask, ncpus) < 0) {
++		numa_warn(W_cpumap, "Cannot parse cpumap. Assuming one node");
++		bad_cpumap(ncpus, mask);
++		err = -1;
+ 	}
+- out:
+- 	free(line);
+-	if (f) 
+-		fclose(f);
++
++	free(line);
+ 	memcpy(buffer, mask, buflen_needed);
+ 
+ 	/* slightly racy, see above */ 
+ 	if (node_cpu_mask[node]) {
+-		if (mask != (unsigned long *)buffer)
++		if (mask != buffer)
+ 			free(mask); 	       
+ 	} else {
+-		node_cpu_mask[node] = (unsigned long *)mask; 
++		node_cpu_mask[node] = mask; 
+ 	} 
+-	return 0; 
++	return err; 
+ } 
+ 
+ make_internal_alias(numa_node_to_cpus);
+ 
+ int numa_run_on_node_mask(const nodemask_t *mask)
+ { 	
+-	int ncpus = number_of_cpus();
++	int ncpus = number_of_configured_cpus();
+ 	int i, k, err;
+ 	unsigned long cpus[CPU_LONGS(ncpus)], nodecpus[CPU_LONGS(ncpus)];
+ 	memset(cpus, 0, CPU_BYTES(ncpus));
+@@ -582,7 +557,7 @@
+ 
+ nodemask_t numa_get_run_node_mask(void)
+ { 
+-	int ncpus = number_of_cpus();
++	int ncpus = number_of_configured_cpus();
+ 	nodemask_t mask;
+ 	int i, k;
+ 	int max = numa_max_node_int();
+@@ -594,7 +569,7 @@
+ 		return numa_no_nodes; 
+ 	for (i = 0; i <= max; i++) {
+ 		if (numa_node_to_cpus_int(i, nodecpus, CPU_BYTES(ncpus)) < 0) {
+-			numa_warn(W_noderunmask, "Cannot read node cpumask from sysfs");
++			/* It's possible for the node to not exist */
+ 			continue;
+ 		}
+ 		for (k = 0; k < CPU_LONGS(ncpus); k++) {
+@@ -612,12 +587,15 @@
+ 
+ int numa_run_on_node(int node)
+ { 
+-	int ncpus = number_of_cpus();
++	int ncpus = number_of_configured_cpus();
+ 	unsigned long cpus[CPU_LONGS(ncpus)];
+ 
+-	if (node == -1)
+-		memset(cpus, 0xff, CPU_BYTES(ncpus));
+-	else if (node < NUMA_NUM_NODES) {
++	if (node == -1) {
++		int i;
++		memset(cpus, 0, CPU_BYTES(ncpus));
++		for (i = 0; i < ncpus; i++) 
++			cpus[i / BITS_PER_LONG] |= 1UL << (i%BITS_PER_LONG);
++	} else if (node < NUMA_NUM_NODES) {
+ 		if (numa_node_to_cpus_int(node, cpus, CPU_BYTES(ncpus)) < 0) {
+ 			numa_warn(W_noderunmask, "Cannot read node cpumask from sysfs");
+ 			return -1; 
+@@ -649,7 +627,7 @@
+ void numa_set_preferred(int node)
+ { 
+ 	nodemask_t n;
+-	if (node == -1) {
++	if (node < 0) {
+ 		nodemask_t empty;
+ 		nodemask_zero(&empty);
+ 		setpol(MPOL_DEFAULT, empty);
diff --git a/numactl.spec b/numactl.spec
index 42825c8..07316cf 100644
--- a/numactl.spec
+++ b/numactl.spec
@@ -1,7 +1,7 @@
 Name:		numactl
 Summary:	library for tuning for Non Uniform Memory Access machines
 Version:	0.9.8
-Release: %(R="$Revision: 1.31 $"; RR="${R##: }"; echo ${RR%%?})
+Release: %(R="$Revision: 1.32 $"; RR="${R##: }"; echo ${RR%%?})
 License:	LGPL/GPL
 Group: 		System Environment/Base
 URL: 		ftp://ftp.suse.com/pub/people/ak/numa/
@@ -10,11 +10,7 @@ Buildroot:	%{_tmppath}/%{name}-buildroot
 
 ExcludeArch: s390 s390x
 
-Patch1:	numactl-lib.patch
-Patch2: numactl-0.6.4-ppc.patch
-Patch3: numactl-0.6.4-commonalias.patch
-Patch4: numactl-64bit-overruns.patch
-Patch5: numactl-64bit-cpu-mask.patch
+Patch1: numactl-node-cpubind.patch
 
 %description
 Simple NUMA policy support. It consists of a numactl program to run
@@ -23,6 +19,7 @@ allocations with NUMA policy in applications.
 
 %prep
 %setup -q -c -a 0
+%patch1
 
 %build
 cd numactl-%{version}
@@ -63,6 +60,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man8/*.8*
 
 %changelog
+* Tue Aug 15 2006 Neil Horman <nhorman@redhat.com> - 0.9.8-1.32
+- add patch for broken cpu/nodebind output (bz 201906)
+
 * Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 0.9.8-1.31
 - rebuild
 
diff --git a/sources b/sources
index 73da56a..5cbac28 100644
--- a/sources
+++ b/sources
@@ -1,2 +1 @@
-4d79d74c69637e1d2a5d64dfc2662fab  numactl-0.6.4.tar.gz
 ebc1ed785733f5af9d4139cef32e1192  numactl-0.9.8.tar.gz