diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f6c4100
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/libhugetlbfs-2.21.tar.gz
diff --git a/.libhugetlbfs.metadata b/.libhugetlbfs.metadata
new file mode 100644
index 0000000..caaaac9
--- /dev/null
+++ b/.libhugetlbfs.metadata
@@ -0,0 +1 @@
+8ed79a12d07be1e858ef4e0148ab1f4115094ef6 SOURCES/libhugetlbfs-2.21.tar.gz
diff --git a/SOURCES/0001-testutils-fix-range_is_mapped.patch b/SOURCES/0001-testutils-fix-range_is_mapped.patch
new file mode 100644
index 0000000..2b3e9d6
--- /dev/null
+++ b/SOURCES/0001-testutils-fix-range_is_mapped.patch
@@ -0,0 +1,68 @@
+From 192ac21a3c057c5dedca4cdd1bf700f38992030c Mon Sep 17 00:00:00 2001
+Message-Id: <192ac21a3c057c5dedca4cdd1bf700f38992030c.1496667760.git.jstancek@redhat.com>
+From: Jan Stancek <jstancek@redhat.com>
+Date: Thu, 1 Jun 2017 09:48:41 +0200
+Subject: [PATCH v2 1/2] testutils: fix range_is_mapped()
+
+It doesn't return correct value when tested region is
+completely inside existing mapping:
+
+  +--------------------------------------+
+  ^ start                                ^ end
+           +----------------+
+           ^ low            ^ high
+
+Rather than testing for all combinations of 2 regions overlapping,
+flip the condition and test if they don't overlap.
+
+Signed-off-by: Jan Stancek <jstancek@redhat.com>
+---
+ tests/testutils.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+This is a v2 series for:
+  https://groups.google.com/forum/#!topic/libhugetlbfs/tAsWjuJ7x8k
+
+diff --git a/tests/testutils.c b/tests/testutils.c
+index 629837045465..f42852e1938b 100644
+--- a/tests/testutils.c
++++ b/tests/testutils.c
+@@ -190,19 +190,29 @@ int range_is_mapped(unsigned long low, unsigned long high)
+ 			return -1;
+ 		}
+ 
+-		if ((start >= low) && (start < high)) {
++		/*
++		 * (existing mapping)    (tested region)
++		 * +----------------+      +.......+
++		 * ^start           ^end   ^ low   ^high
++		 */
++		if (low >= end) {
+ 			fclose(f);
+-			return 1;
++			return 0;
+ 		}
+-		if ((end >= low) && (end < high)) {
++
++		/*
++		 * (tested region)  (existing mapping)
++		 *     +.....+      +----------------+
++		 *     ^low  ^high  ^ start          ^end
++		 */
++		if (high <= start) {
+ 			fclose(f);
+-			return 1;
++			return 0;
+ 		}
+-
+ 	}
+ 
+ 	fclose(f);
+-	return 0;
++	return 1;
+ }
+ 
+ /*
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0002-stack_grow_into_huge-don-t-clobber-existing-mappings.patch b/SOURCES/0002-stack_grow_into_huge-don-t-clobber-existing-mappings.patch
new file mode 100644
index 0000000..2d121fd
--- /dev/null
+++ b/SOURCES/0002-stack_grow_into_huge-don-t-clobber-existing-mappings.patch
@@ -0,0 +1,173 @@
+From a329008ea54056f0ed9d85cc3d0d9129474f7cd5 Mon Sep 17 00:00:00 2001
+Message-Id: <a329008ea54056f0ed9d85cc3d0d9129474f7cd5.1496667760.git.jstancek@redhat.com>
+In-Reply-To: <192ac21a3c057c5dedca4cdd1bf700f38992030c.1496667760.git.jstancek@redhat.com>
+References: <192ac21a3c057c5dedca4cdd1bf700f38992030c.1496667760.git.jstancek@redhat.com>
+From: Jan Stancek <jstancek@redhat.com>
+Date: Thu, 1 Jun 2017 10:00:47 +0200
+Subject: [PATCH v2 2/2] stack_grow_into_huge: don't clobber existing mappings
+
+This test allocates hugepages above stack using MAP_FIXED and then
+grows stack while it can. If a MAP_FIXED request is successful,
+then mapping established by mmap() replaces any previous mappings
+for the process' pages. If there's anything important there (libc
+mappings), these can get clobbered as described here:
+  http://marc.info/?l=linux-arm-kernel&m=149036535209519&w=2.
+
+This patch is creating extra stack for new child and maps
+one hugepage above it. The search starts at heap until it
+hits existing mapping or until it can successfully map
+huge page and stack below it.
+
+If suitable place can't be found, test PASSes as inconclusive.
+
+Signed-off-by: Jan Stancek <jstancek@redhat.com>
+---
+ tests/stack_grow_into_huge.c | 101 ++++++++++++++++++++++++++++---------------
+ 1 file changed, 67 insertions(+), 34 deletions(-)
+
+This is a v2 series for:
+  https://groups.google.com/forum/#!topic/libhugetlbfs/tAsWjuJ7x8k
+
+diff --git a/tests/stack_grow_into_huge.c b/tests/stack_grow_into_huge.c
+index a380da063264..9b8ea8d74887 100644
+--- a/tests/stack_grow_into_huge.c
++++ b/tests/stack_grow_into_huge.c
+@@ -25,6 +25,7 @@
+ #include <sys/mman.h>
+ #include <sys/resource.h>
+ #include <sys/wait.h>
++#include <sched.h>
+ 
+ #include <hugetlbfs.h>
+ #include "hugetests.h"
+@@ -54,7 +55,10 @@
+ #define STACK_ALLOCATION_SIZE	(16*1024*1024)
+ #endif
+ 
+-void do_child(void *stop_address)
++#define MIN_CHILD_STACK (2*1024*1024)
++#define STEP (STACK_ALLOCATION_SIZE)
++
++int do_child(void *stop_address)
+ {
+ 	struct rlimit r;
+ 	volatile int *x;
+@@ -71,15 +75,68 @@ void do_child(void *stop_address)
+ 		x = alloca(STACK_ALLOCATION_SIZE);
+ 		*x = 1;
+ 	} while ((void *)x >= stop_address);
++
++	return 0;
++}
++
++void *try_setup_stack_and_huge(int fd, void *hint)
++{
++	void *mmap_address, *stack_start, *tmp;
++	long hpage_size = gethugepagesize();
++	void *stop = alloca(1);
++
++	/*
++	 * Find a spot for huge page. We start at "hint" and
++	 * keep going down in "STEP" increments until we find
++	 * a place where we can mmap huge page.
++	 */
++	mmap_address = PALIGN(hint, hpage_size);
++	do {
++		mmap_address += STEP;
++		if (mmap_address >= stop)
++			return NULL;
++		if (range_is_mapped((unsigned long)mmap_address,
++			(unsigned long)mmap_address + hpage_size))
++			continue;
++		tmp = mmap(mmap_address, hpage_size,
++			PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
++	} while (tmp == MAP_FAILED);
++	verbose_printf("huge page is at: %p-%p\n",
++		mmap_address, mmap_address + hpage_size);
++
++	/*
++	 * Find a spot for stack below huge page. We start at end of
++	 * huge page we found above and keep trying to mmap stack
++	 * below. Because stack needs to grow into hugepage, we
++	 * also have to make sure nothing is mapped in gap between
++	 * stack and huge page.
++	 */
++	stack_start = mmap_address + hpage_size;
++	do {
++		if (range_is_mapped((unsigned long)stack_start,
++			(unsigned long)stack_start + STEP + MIN_CHILD_STACK)) {
++			verbose_printf("range is mapped: %p-%p\n", stack_start,
++				stack_start + STEP + MIN_CHILD_STACK);
++			munmap(mmap_address, hpage_size);
++			return NULL;
++		}
++		stack_start += STEP;
++		if (stack_start >= stop)
++			return NULL;
++		tmp = mmap(stack_start, MIN_CHILD_STACK, PROT_READ|PROT_WRITE,
++			MAP_GROWSDOWN|MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
++	} while (tmp == MAP_FAILED);
++
++	verbose_printf("Child stack is at %p-%p\n",
++		stack_start, stack_start + MIN_CHILD_STACK);
++	return stack_start + MIN_CHILD_STACK;
+ }
+ 
+ int main(int argc, char *argv[])
+ {
+ 	int fd, pid, s, ret;
+ 	struct rlimit r;
+-	char *b;
+-	long hpage_size = gethugepagesize();
+-	void *stack_address, *mmap_address, *heap_address;
++	void *stack_end;
+ 
+ 	test_init(argc, argv);
+ 
+@@ -94,37 +151,13 @@ int main(int argc, char *argv[])
+ 	if (fd < 0)
+ 		CONFIG("Couldn't get hugepage fd");
+ 
+-	stack_address = alloca(0);
+-	heap_address = sbrk(0);
++	stack_end = try_setup_stack_and_huge(fd, sbrk(0));
++	if (!stack_end)
++		PASS_INCONCLUSIVE();
+ 
+-	/*
+-	 * paranoia: start mapping two hugepages below the start of the stack,
+-	 * in case the alignment would cause us to map over something if we
+-	 * only used a gap of one hugepage.
+-	 */
+-	mmap_address = PALIGN(stack_address - 2 * hpage_size, hpage_size);
+-
+-	do {
+-		b = mmap(mmap_address, hpage_size, PROT_READ|PROT_WRITE,
+-						MAP_FIXED|MAP_SHARED, fd, 0);
+-		mmap_address -= hpage_size;
+-		/*
+-		 * if we get all the way down to the heap, stop trying
+-		 */
+-		if (mmap_address <= heap_address)
+-			break;
+-	} while (b == MAP_FAILED);
+-
+-	if (b == MAP_FAILED)
+-		FAIL("mmap: %s", strerror(errno));
+-
+-	if ((pid = fork()) < 0)
+-		FAIL("fork: %s", strerror(errno));
+-
+-	if (pid == 0) {
+-		do_child(mmap_address);
+-		exit(0);
+-	}
++	pid = clone(do_child, stack_end, SIGCHLD, 0);
++	if (pid < 0)
++		FAIL("clone: %s", strerror(errno));
+ 
+ 	ret = waitpid(pid, &s, 0);
+ 	if (ret == -1)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/build_flags.patch b/SOURCES/build_flags.patch
new file mode 100644
index 0000000..fc1c83c
--- /dev/null
+++ b/SOURCES/build_flags.patch
@@ -0,0 +1,56 @@
+diff --git a/Makefile b/Makefile
+index 51e41f0..573a799 100644
+--- a/Makefile
++++ b/Makefile
+@@ -25,9 +25,6 @@ NODEPTARGETS=<version.h> <clean>
+ 
+ INSTALL = install
+ 
+-LDFLAGS += -ldl
+-CFLAGS ?= -O2 -g
+-CFLAGS += -Wall -fPIC
+ CPPFLAGS += -D__LIBHUGETLBFS__
+ 
+ ARCH ?= $(shell uname -m | sed -e s/i.86/i386/)
+@@ -279,22 +276,22 @@ snapshot: $(VERSION)
+ obj32/%.o: %.c
+ 	@$(VECHO) CC32 $@
+ 	@mkdir -p obj32
+-	$(CC32) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
++	$(CC32) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $<
+ 
+ obj64/%.o: %.c
+ 	@$(VECHO) CC64 $@
+ 	@mkdir -p obj64
+-	$(CC64) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
++	$(CC64) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $<
+ 
+ obj32/%.o: %.S
+ 	@$(VECHO) AS32 $@
+ 	@mkdir -p obj32
+-	$(CC32) $(CPPFLAGS) -o $@ -c $<
++	$(CC32) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $<
+ 
+ obj64/%.o: %.S
+ 	@$(VECHO) AS64 $@
+ 	@mkdir -p obj64
+-	$(CC64) $(CPPFLAGS) -o $@ -c $<
++	$(CC64) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $<
+ 
+ obj32/libhugetlbfs.a: $(LIBOBJS32)
+ 	@$(VECHO) AR32 $@
+diff --git a/tests/Makefile b/tests/Makefile
+index 073df96..508a6ec 100644
+--- a/tests/Makefile
++++ b/tests/Makefile
+@@ -33,8 +33,8 @@ HELPERS = get_hugetlbfs_path compare_kvers
+ HELPER_LIBS = libheapshrink.so
+ BADTOOLCHAIN = bad-toolchain.sh
+ 
+-CFLAGS = -O2 -Wall -g
+-CPPFLAGS = -I..
++CFLAGS ?= -O2 -Wall -g
++CPPFLAGS += -I..
+ STATIC_LIBHUGE = -Wl,--whole-archive -lhugetlbfs -Wl,--no-whole-archive
+ STATIC_LDLIBS = -Wl,--no-as-needed -lpthread
+ LDLIBS = $(STATIC_LDLIBS) -ldl -lhugetlbfs_privutils
diff --git a/SOURCES/huge_page_setup_helper-python3-convert.patch b/SOURCES/huge_page_setup_helper-python3-convert.patch
new file mode 100644
index 0000000..a84ac5a
--- /dev/null
+++ b/SOURCES/huge_page_setup_helper-python3-convert.patch
@@ -0,0 +1,304 @@
+diff --git a/huge_page_setup_helper.py b/huge_page_setup_helper.py
+index 43c9916..7ba0c92 100755
+--- a/huge_page_setup_helper.py
++++ b/huge_page_setup_helper.py
+@@ -1,4 +1,4 @@
+-#!/usr/bin/python
++#!/usr/bin/env python3
+ 
+ #
+ # Tool to set up Linux large page support with minimal effort
+@@ -14,13 +14,13 @@ debug = False
+ 
+ # must be executed under the root to operate
+ if os.geteuid() != 0:
+-    print "You must be root to setup hugepages!"
++    print("You must be root to setup hugepages!")
+     os._exit(1)
+ 
+ # config files we need access to
+ sysctlConf = "/etc/sysctl.conf"
+ if not os.access(sysctlConf, os.W_OK):
+-    print "Cannot access %s" % sysctlConf
++    print("Cannot access %s" % sysctlConf)
+     if debug == False:
+         os._exit(1)
+ 
+@@ -41,7 +41,7 @@ for line in hugeadmexplain:
+         break
+ 
+ if memTotal == 0:
+-    print "Your version of libhugetlbfs' hugeadm utility is too old!"
++    print("Your version of libhugetlbfs' hugeadm utility is too old!")
+     os._exit(1)
+ 
+ 
+@@ -54,7 +54,7 @@ for line in poolList:
+         break
+ 
+ if hugePageSize == 0:
+-    print "Aborting, cannot determine system huge page size!"
++    print("Aborting, cannot determine system huge page size!")
+     os._exit(1)
+ 
+ # Get initial sysctl settings
+@@ -83,22 +83,22 @@ for line in groupNames:
+ 
+ 
+ # dump system config as we see it before we start tweaking it
+-print "Current configuration:"
+-print " * Total System Memory......: %6d MB" % memTotal
+-print " * Shared Mem Max Mapping...: %6d MB" % (shmmax / (1024 * 1024))
+-print " * System Huge Page Size....: %6d MB" % (hugePageSize / (1024 * 1024))
+-print " * Number of Huge Pages.....: %6d"    % hugePages
+-print " * Total size of Huge Pages.: %6d MB" % (hugePages * hugePageSize / (1024 * 1024))
+-print " * Remaining System Memory..: %6d MB" % (memTotal - (hugePages * hugePageSize / (1024 * 1024)))
+-print " * Huge Page User Group.....:  %s (%d)" % (hugeGIDName, hugeGID)
+-print
++print("Current configuration:")
++print(" * Total System Memory......: %6d MB" % memTotal)
++print(" * Shared Mem Max Mapping...: %6d MB" % (shmmax / (1024 * 1024)))
++print(" * System Huge Page Size....: %6d MB" % (hugePageSize / (1024 * 1024)))
++print(" * Number of Huge Pages.....: %6d"    % hugePages)
++print(" * Total size of Huge Pages.: %6d MB" % (hugePages * hugePageSize / (1024 * 1024)))
++print(" * Remaining System Memory..: %6d MB" % (memTotal - (hugePages * hugePageSize / (1024 * 1024))))
++print(" * Huge Page User Group.....:  %s (%d)" % (hugeGIDName, hugeGID))
++print()
+ 
+ 
+ # ask how memory they want to allocate for huge pages
+ userIn = None
+ while not userIn:
+     try:
+-        userIn = raw_input("How much memory would you like to allocate for huge pages? "
++        userIn = input("How much memory would you like to allocate for huge pages? "
+                            "(input in MB, unless postfixed with GB): ")
+         if userIn[-2:] == "GB":
+             userHugePageReqMB = int(userIn[0:-2]) * 1024
+@@ -113,19 +113,19 @@ while not userIn:
+         # As a sanity safeguard, require at least 128M not be allocated to huge pages
+         if userHugePageReqMB > (memTotal - 128):
+             userIn = None
+-            print "Refusing to allocate %d, you must leave at least 128MB for the system" % userHugePageReqMB
++            print("Refusing to allocate %d, you must leave at least 128MB for the system" % userHugePageReqMB)
+         elif userHugePageReqMB < (hugePageSize / (1024 * 1024)):
+             userIn = None
+-            print "Sorry, allocation must be at least a page's worth!"
++            print("Sorry, allocation must be at least a page's worth!")
+         else:
+             break
+     except ValueError:
+         userIn = None
+-        print "Input must be an integer, please try again!"
++        print("Input must be an integer, please try again!")
+ userHugePageReqKB = userHugePageReqMB * 1024
+ userHugePagesReq = userHugePageReqKB / (hugePageSize / 1024)
+-print "Okay, we'll try to allocate %d MB for huge pages..." % userHugePageReqMB
+-print
++print("Okay, we'll try to allocate %d MB for huge pages..." % userHugePageReqMB)
++print()
+ 
+ 
+ # some basic user input validation
+@@ -134,24 +134,24 @@ inputIsValid = False
+ # ask for the name of the group allowed access to huge pages
+ while inputIsValid == False:
+     foundbad = False
+-    userGroupReq = raw_input("What group should have access to the huge pages?"
++    userGroupReq = input("What group should have access to the huge pages?"
+                              "(The group will be created, if need be) [hugepages]: ")
+     if userGroupReq is '':
+         userGroupReq = 'hugepages'
+     if userGroupReq[0].isdigit() or userGroupReq[0] == "-":
+         foundbad = True
+-        print "Group names cannot start with a number or dash, please try again!"
++        print("Group names cannot start with a number or dash, please try again!")
+     for char in badchars:
+         if char in userGroupReq:
+             foundbad = True
+-            print "Illegal characters in group name, please try again!"
++            print("Illegal characters in group name, please try again!")
+             break
+     if len(userGroupReq) > 16:
+         foundbad = True
+-        print "Group names can't be more than 16 characaters, please try again!"
++        print("Group names can't be more than 16 characaters, please try again!")
+     if foundbad == False:
+         inputIsValid = True
+-print "Okay, we'll give group %s access to the huge pages" % userGroupReq
++print("Okay, we'll give group %s access to the huge pages" % userGroupReq)
+ 
+ 
+ # see if group already exists, use it if it does, if not, create it
+@@ -163,20 +163,20 @@ for line in groupNames:
+         break
+ 
+ if userGIDReq > -1:
+-    print "Group %s (gid %d) already exists, we'll use it" % (userGroupReq, userGIDReq)
++    print("Group %s (gid %d) already exists, we'll use it" % (userGroupReq, userGIDReq))
+ else:
+     if debug == False:
+         os.popen("/usr/sbin/groupadd %s" % userGroupReq)
+     else:
+-        print "/usr/sbin/groupadd %s" % userGroupReq
++        print("/usr/sbin/groupadd %s" % userGroupReq)
+     groupNames = os.popen("/usr/bin/getent group %s" % userGroupReq).readlines()
+     for line in groupNames:
+         curGroupName = line.split(":")[0]
+         if curGroupName == userGroupReq:
+             userGIDReq = int(line.split(":")[2])
+             break
+-    print "Created group %s (gid %d) for huge page use" % (userGroupReq, userGIDReq)
+-print
++    print("Created group %s (gid %d) for huge page use" % (userGroupReq, userGIDReq))
++print()
+ 
+ 
+ # basic user input validation, take 2
+@@ -186,20 +186,20 @@ inputIsValid = False
+ # ask for user(s) that should be in the huge page access group
+ while inputIsValid == False:
+     foundbad = False
+-    userUsersReq = raw_input("What user(s) should have access to the huge pages (space-delimited list, users created as needed)? ")
++    userUsersReq = input("What user(s) should have access to the huge pages (space-delimited list, users created as needed)? ")
+     for char in badchars:
+         if char in userUsersReq:
+             foundbad = True
+-            print "Illegal characters in user name(s) or invalid list format, please try again!"
++            print("Illegal characters in user name(s) or invalid list format, please try again!")
+             break
+     for n in userUsersReq.split():
+         if len(n) > 32:
+             foundbad = True
+-            print "User names can't be more than 32 characaters, please try again!"
++            print("User names can't be more than 32 characaters, please try again!")
+             break
+         if n[0] == "-":
+             foundbad = True
+-            print "User names cannot start with a dash, please try again!"
++            print("User names cannot start with a dash, please try again!")
+             break
+     if foundbad == False:
+         inputIsValid = True
+@@ -211,24 +211,24 @@ for hugeUser in hugePageUserList:
+     for line in curUserList:
+         curUser = line.split(":")[0]
+         if curUser == hugeUser:
+-            print "Adding user %s to huge page group" % hugeUser
++            print("Adding user %s to huge page group" % hugeUser)
+             userExists = True
+             if debug == False:
+                 os.popen("/usr/sbin/usermod -a -G %s %s" % (userGroupReq, hugeUser))
+             else:
+-                print "/usr/sbin/usermod -a -G %s %s" % (userGroupReq, hugeUser)
++                print("/usr/sbin/usermod -a -G %s %s" % (userGroupReq, hugeUser))
+         if userExists == True:
+             break
+     if userExists == False:
+-        print "Creating user %s with membership in huge page group" % hugeUser
++        print("Creating user %s with membership in huge page group" % hugeUser)
+         if debug == False:
+             if hugeUser == userGroupReq:
+                 os.popen("/usr/sbin/useradd %s -g %s" % (hugeUser, userGroupReq))
+             else:
+                 os.popen("/usr/sbin/useradd %s -G %s" % (hugeUser, userGroupReq))
+         else:
+-            print "/usr/sbin/useradd %s -G %s" % (hugeUser, userGroupReq)
+-print
++            print("/usr/sbin/useradd %s -G %s" % (hugeUser, userGroupReq))
++print()
+ 
+ 
+ # set values for the current running environment
+@@ -238,11 +238,11 @@ if debug == False:
+     os.popen("/usr/bin/hugeadm --set-shm-group %d" % userGIDReq)
+     os.popen("/usr/bin/hugeadm --set-recommended-shmmax")
+ else:
+-    print "/usr/bin/hugeadm --pool-pages-min DEFAULT:%sM" % userHugePageReqMB
+-    print "/usr/bin/hugeadm --pool-pages-max DEFAULT:%sM" % userHugePageReqMB
+-    print "/usr/bin/hugeadm --set-shm-group %d" % userGIDReq
+-    print "/usr/bin/hugeadm --set-recommended-shmmax"
+-    print
++    print("/usr/bin/hugeadm --pool-pages-min DEFAULT:%sM" % userHugePageReqMB)
++    print("/usr/bin/hugeadm --pool-pages-max DEFAULT:%sM" % userHugePageReqMB)
++    print("/usr/bin/hugeadm --set-shm-group %d" % userGIDReq)
++    print("/usr/bin/hugeadm --set-recommended-shmmax")
++    print()
+ 
+ # figure out what that shmmax value we just set was
+ hugeadmexplain = os.popen("/usr/bin/hugeadm --explain 2>/dev/null").readlines()
+@@ -258,7 +258,7 @@ if debug == False:
+         try:
+             sysctlConfLines = open(sysctlConf).readlines()
+             os.rename(sysctlConf, sysctlConf + ".backup")
+-            print("Saved original %s as %s.backup" % (sysctlConf, sysctlConf))
++            print(("Saved original %s as %s.backup" % (sysctlConf, sysctlConf)))
+         except:
+             pass
+ 
+@@ -279,11 +279,11 @@ if debug == False:
+     fd.close()
+ 
+ else:
+-    print "Add to %s:" % sysctlConf
+-    print "kernel.shmmax = %d" % shmmax
+-    print "vm.nr_hugepages = %d" % userHugePagesReq
+-    print "vm.hugetlb_shm_group = %d" % userGIDReq
+-    print
++    print("Add to %s:" % sysctlConf)
++    print("kernel.shmmax = %d" % shmmax)
++    print("vm.nr_hugepages = %d" % userHugePagesReq)
++    print("vm.hugetlb_shm_group = %d" % userGIDReq)
++    print()
+ 
+ 
+ # write out limits.conf changes to persist across reboot
+@@ -293,7 +293,7 @@ if debug == False:
+         try:
+             limitsConfLines = open(limitsConf).readlines()
+             os.rename(limitsConf, limitsConf + ".backup")
+-            print("Saved original %s as %s.backup" % (limitsConf, limitsConf))
++            print(("Saved original %s as %s.backup" % (limitsConf, limitsConf)))
+         except:
+             pass
+ 
+@@ -319,25 +319,25 @@ if debug == False:
+     fd.close()
+ 
+ else:
+-    print "Add to %s:" % limitsConf
++    print("Add to %s:" % limitsConf)
+     for hugeUser in hugePageUserList:
+-        print "%s		soft	memlock		%d" % (hugeUser, userHugePageReqKB)
+-        print "%s		hard	memlock		%d" % (hugeUser, userHugePageReqKB)
++        print("%s		soft	memlock		%d" % (hugeUser, userHugePageReqKB))
++        print("%s		hard	memlock		%d" % (hugeUser, userHugePageReqKB))
+ 
+ 
+ # dump the final configuration of things now that we're done tweaking
+-print
+-print "Final configuration:"
+-print " * Total System Memory......: %6d MB" % memTotal
++print()
++print("Final configuration:")
++print(" * Total System Memory......: %6d MB" % memTotal)
+ if debug == False:
+-    print " * Shared Mem Max Mapping...: %6d MB" % (shmmax / (1024 * 1024))
++    print(" * Shared Mem Max Mapping...: %6d MB" % (shmmax / (1024 * 1024)))
+ else:
+     # This should be what we *would* have set it to, had we actually run hugeadm --set-recommended-shmmax
+-    print " * Shared Mem Max Mapping...: %6d MB" % (userHugePagesReq * hugePageSize / (1024 * 1024))
+-print " * System Huge Page Size....: %6d MB" % (hugePageSize / (1024 * 1024))
+-print " * Available Huge Pages.....: %6d"    % userHugePagesReq
+-print " * Total size of Huge Pages.: %6d MB" % (userHugePagesReq * hugePageSize / (1024 * 1024))
+-print " * Remaining System Memory..: %6d MB" % (memTotal - userHugePageReqMB)
+-print " * Huge Page User Group.....:  %s (%d)" % (userGroupReq, userGIDReq)
+-print
++    print(" * Shared Mem Max Mapping...: %6d MB" % (userHugePagesReq * hugePageSize / (1024 * 1024)))
++print(" * System Huge Page Size....: %6d MB" % (hugePageSize / (1024 * 1024)))
++print(" * Available Huge Pages.....: %6d"    % userHugePagesReq)
++print(" * Total size of Huge Pages.: %6d MB" % (userHugePagesReq * hugePageSize / (1024 * 1024)))
++print(" * Remaining System Memory..: %6d MB" % (memTotal - userHugePageReqMB))
++print(" * Huge Page User Group.....:  %s (%d)" % (userGroupReq, userGIDReq))
++print()
+ 
diff --git a/SOURCES/run_tests-python3-convert.patch b/SOURCES/run_tests-python3-convert.patch
new file mode 100644
index 0000000..b83cea4
--- /dev/null
+++ b/SOURCES/run_tests-python3-convert.patch
@@ -0,0 +1,254 @@
+diff --git a/tests/run_tests.py b/tests/run_tests.py
+index 617ed93..036cef5 100755
+--- a/tests/run_tests.py
++++ b/tests/run_tests.py
+@@ -1,4 +1,4 @@
+-#! /usr/bin/env python
++#!/usr/bin/env python3
+ 
+ import subprocess
+ import types
+@@ -47,7 +47,7 @@ def bash(cmd):
+         # Abort and mark this a strange test result
+         return (127, "")
+     out = p.stdout.read().strip()
+-    return (rc, out)
++    return (rc, out.decode())
+ 
+ def snapshot_pool_state():
+     l = []
+@@ -60,7 +60,7 @@ def snapshot_pool_state():
+ def run_test_prog(bits, pagesize, cmd, **env):
+     if paranoid_pool_check:
+         beforepool = snapshot_pool_state()
+-        print "Pool state: %s" % str(beforepool)
++        print("Pool state: %s" % str(beforepool))
+ 
+     local_env = os.environ.copy()
+     local_env.update(env)
+@@ -75,7 +75,7 @@ def run_test_prog(bits, pagesize, cmd, **env):
+         rc = p.wait()
+     except KeyboardInterrupt:
+         # Abort and mark this a strange test result
+-        return (None, "")
++        return (127, "")
+     except OSError as e:
+         return (-e.errno, "")
+     out = p.stdout.read().strip()
+@@ -83,26 +83,26 @@ def run_test_prog(bits, pagesize, cmd, **env):
+     if paranoid_pool_check:
+         afterpool = snapshot_pool_state()
+         if afterpool != beforepool:
+-            print >>sys.stderr, "Hugepage pool state not preserved!"
+-            print >>sys.stderr, "BEFORE: %s" % str(beforepool)
+-            print >>sys.stderr, "AFTER: %s" % str(afterpool)
++            print("Hugepage pool state not preserved!", file=sys.stderr)
++            print("BEFORE: %s" % str(beforepool), file=sys.stderr)
++            print("AFTER: %s" % str(afterpool), file=sys.stderr)
+             sys.exit(98)
+ 
+-    return (rc, out)
++    return (rc, out.decode())
+ 
+ def setup_env(override, defaults):
+     """
+     Set up the environment for running commands in the shell.
+     """
+     # All items in override are unconditionally set or unset
+-    for (var, val) in override.items():
++    for (var, val) in list(override.items()):
+         if val == None:
+             if var in os.environ:
+                 del os.environ[var]
+         else:
+             os.environ[var] = val
+     # If not already set, these variables are given default values
+-    for (var, val) in defaults.items():
++    for (var, val) in list(defaults.items()):
+         if var not in os.environ or os.environ[var] == "":
+             os.environ[var] = val
+ 
+@@ -143,22 +143,22 @@ def print_per_size(title, values):
+     Print the results of a given result type on one line.  The results for all
+     page sizes and word sizes are written in a table format.
+     """
+-    print "*%20s: " % title,
++    print("*%20s: " % title, end=' ')
+     for sz in pagesizes:
+-        print "%4s   %4s   " % (values[sz][32], values[sz][64]),
+-    print
++        print("%4s   %4s   " % (values[sz][32], values[sz][64]), end=' ')
++    print()
+ 
+ def results_summary():
+     """
+     Display a summary of the test results
+     """
+-    print "********** TEST SUMMARY"
+-    print "*%21s" % "",
+-    for p in pagesizes: print "%-13s " % pretty_page_size(p),
+-    print
+-    print "*%21s" % "",
+-    for p in pagesizes: print "32-bit 64-bit ",
+-    print
++    print("********** TEST SUMMARY")
++    print("*%21s" % "", end=' ')
++    for p in pagesizes: print("%-13s " % pretty_page_size(p), end=' ')
++    print()
++    print("*%21s" % "", end=' ')
++    for p in pagesizes: print("32-bit 64-bit ", end=' ')
++    print()
+ 
+     print_per_size("Total testcases", R["total"])
+     print_per_size("Skipped", R["skip"])
+@@ -170,7 +170,7 @@ def results_summary():
+     print_per_size("Unexpected PASS", R["xpass"])
+     print_per_size("Test not present", R["nofile"])
+     print_per_size("Strange test result", R["strange"])
+-    print "**********"
++    print("**********")
+ 
+ def free_hpages():
+     """
+@@ -216,7 +216,7 @@ def clear_hpages():
+     cleaned up automatically and must be removed to free up the huge pages.
+     """
+     for mount in mounts:
+-        dir = mount + "/elflink-uid-" + `os.getuid()`
++        dir = mount + "/elflink-uid-" + repr(os.getuid())
+         for root, dirs, files in os.walk(dir, topdown=False):
+             for name in files:
+                 os.remove(os.path.join(root, name))
+@@ -270,13 +270,13 @@ def check_hugetlbfs_path():
+                 okbits.append(b)
+                 mounts.append(out)
+         if len(okbits) == 0:
+-            print "run_tests.py: No mountpoints available for page size %s" % \
+-                  pretty_page_size(p)
++            print("run_tests.py: No mountpoints available for page size %s" % \
++                  pretty_page_size(p))
+             wordsizes_by_pagesize[p] = set()
+             continue
+         for b in wordsizes - set(okbits):
+-            print "run_tests.py: The %i bit word size is not compatible with " \
+-                  "%s pages" % (b, pretty_page_size(p))
++            print("run_tests.py: The %i bit word size is not compatible with " \
++                  "%s pages" % (b, pretty_page_size(p)))
+         wordsizes_by_pagesize[p] = set(okbits)
+ 
+ def check_linkhuge_tests():
+@@ -298,10 +298,9 @@ def check_linkhuge_tests():
+ 
+ def print_cmd(pagesize, bits, cmd, env):
+     if env:
+-        print ' '.join(['%s=%s' % (k, v) for k, v in env.items()]),
+-    if type(cmd) != types.StringType:
+-        cmd = ' '.join(cmd)
+-    print "%s (%s: %i):\t" % (cmd, pretty_page_size(pagesize), bits),
++        print(' '.join(['%s=%s' % (k, v) for k, v in list(env.items())]), end=' ')
++
++    print("%s (%s: %i):\t" % (cmd, pretty_page_size(pagesize), bits), end=' ')
+     sys.stdout.flush()
+ 
+ def run_test(pagesize, bits, cmd, **env):
+@@ -321,7 +320,7 @@ def run_test(pagesize, bits, cmd, **env):
+ 
+     print_cmd(pagesize, bits, cmd, env)
+     (rc, out) = run_test_prog(bits, pagesize, cmd, **env)
+-    print out
++    print(out)
+ 
+     R["total"][pagesize][bits] += 1
+     if rc == 0:    R["pass"][pagesize][bits] += 1
+@@ -342,7 +341,7 @@ def skip_test(pagesize, bits, cmd, **env):
+     R["total"][pagesize][bits] += 1
+     R["skip"][pagesize][bits] += 1
+     print_cmd(pagesize, bits, cmd, env)
+-    print "SKIPPED"
++    print("SKIPPED")
+ 
+ def do_test(cmd, bits=None, **env):
+     """
+@@ -466,9 +465,9 @@ def setup_shm_sysctl(limit):
+         sysctls[f] = fh.read()
+         fh.close()
+         fh = open(f, "w")
+-        fh.write(`limit`)
++        fh.write(repr(limit))
+         fh.close()
+-    print "set shmmax limit to %s" % limit
++    print("set shmmax limit to %s" % limit)
+     return sysctls
+ 
+ def restore_shm_sysctl(sysctls):
+@@ -476,7 +475,7 @@ def restore_shm_sysctl(sysctls):
+     Restore the sysctls named in 'sysctls' to the given values.
+     """
+     if os.getuid() != 0: return
+-    for (file, val) in sysctls.items():
++    for (file, val) in list(sysctls.items()):
+         fh = open(file, "w")
+         fh.write(val)
+         fh.close()
+@@ -659,17 +658,17 @@ def stress_tests():
+     do_test("fallocate_stress.sh")
+ 
+ def print_help():
+-    print "Usage: %s [options]" % sys.argv[0]
+-    print "Options:"
+-    print "  -v	\t Verbose output."
+-    print "  -V	\t Highly verbose output."
+-    print "  -f	\t Force all tests."
+-    print "  -t <set> 	 Run test set, allowed are func and stress."
+-    print "  -b <wordsize>  Define wordsizes to be used. "
+-    print "  -p <pagesize>  Define the page sizes to be used."
+-    print "  -c	\t Do a paranoid pool check."
+-    print "  -l	\t Use custom ld scripts."
+-    print "  -h	\t This help."
++    print("Usage: %s [options]" % sys.argv[0])
++    print("Options:")
++    print("  -v	\t Verbose output.")
++    print("  -V	\t Highly verbose output.")
++    print("  -f	\t Force all tests.")
++    print("  -t <set> 	 Run test set, allowed are func and stress.")
++    print("  -b <wordsize>  Define wordsizes to be used. ")
++    print("  -p <pagesize>  Define the page sizes to be used.")
++    print("  -c	\t Do a paranoid pool check.")
++    print("  -l	\t Use custom ld scripts.")
++    print("  -h	\t This help.")
+     sys.exit(0)
+ 
+ def main():
+@@ -685,8 +684,8 @@ def main():
+ 
+     try:
+         opts, args = getopt.getopt(sys.argv[1:], "vVft:b:p:c:lh")
+-    except getopt.GetoptError, err:
+-        print str(err)
++    except getopt.GetoptError as err:
++        print(str(err))
+         sys.exit(1)
+     for opt, arg in opts:
+        if opt == "-v":
+@@ -715,8 +714,8 @@ def main():
+     if len(pagesizes) == 0: pagesizes = get_pagesizes()
+ 
+     if len(pagesizes) == 0:
+-        print "Unable to find available page sizes, are you sure hugetlbfs"
+-        print "is mounted and there are available huge pages?"
++        print("Unable to find available page sizes, are you sure hugetlbfs")
++        print("is mounted and there are available huge pages?")
+         return 1
+ 
+     setup_env(env_override, env_defaults)
+@@ -724,8 +723,8 @@ def main():
+ 
+     (rc, system_default_hpage_size) = hpage_size()
+     if rc != 0:
+-        print "Unable to find system default hugepage size."
+-        print "Is hugepage supported included in this kernel?"
++        print("Unable to find system default hugepage size.")
++        print("Is hugepage supported included in this kernel?")
+         return 1
+ 
+     check_hugetlbfs_path()
diff --git a/SOURCES/tests_shm-perms_adjust_max_segment_size_for_bigger_hugepages.patch b/SOURCES/tests_shm-perms_adjust_max_segment_size_for_bigger_hugepages.patch
new file mode 100644
index 0000000..39b04f3
--- /dev/null
+++ b/SOURCES/tests_shm-perms_adjust_max_segment_size_for_bigger_hugepages.patch
@@ -0,0 +1,26 @@
+diff --git a/tests/run_tests.py b/tests/run_tests.py
+index 3c95a03..f88e1e2 100755
+--- a/tests/run_tests.py
++++ b/tests/run_tests.py
+@@ -557,7 +557,7 @@ def functional_tests():
+         do_test("mremap-expand-slice-collision.sh")
+         do_test("mremap-fixed-normal-near-huge.sh")
+         do_test("mremap-fixed-huge-near-normal.sh")
+-    do_shm_test("shm-perms", 64*1024*1024)
++    do_shm_test("shm-perms", 1024*1024*1024)
+ 
+     # Tests requiring an active mount and hugepage COW
+     do_test("private")
+diff --git a/tests/shm-perms.c b/tests/shm-perms.c
+index 590a101..12d7609 100644
+--- a/tests/shm-perms.c
++++ b/tests/shm-perms.c
+@@ -32,7 +32,7 @@
+ 	"* to a segment with different permissions.  A segment is created  *\n"\
+ 	"* and children attach read-only to check reservation accounting.  *"
+ 
+-#define SEGMENT_SIZE	((size_t)0x4000000)
++#define SEGMENT_SIZE	((size_t)0x40000000)
+ #define SEGMENT_KEY	0x82ba15ff
+ #define STRIDE		0x200000
+ 
diff --git a/SPECS/libhugetlbfs.spec b/SPECS/libhugetlbfs.spec
new file mode 100644
index 0000000..3a6672a
--- /dev/null
+++ b/SPECS/libhugetlbfs.spec
@@ -0,0 +1,313 @@
+Name: libhugetlbfs
+Version: 2.21
+Release: 1%{?dist}
+Summary: A library which provides easy access to huge pages of memory
+
+Group: System Environment/Libraries
+License: LGPLv2+
+URL: https://github.com/libhugetlbfs/libhugetlbfs
+Source0: https://github.com/%{name}/%{name}/releases/download/%{version}/%{name}-%{version}.tar.gz
+
+# Patch0: build flags adjusts to build in stricter RHEL-8 buildroots
+Patch0: build_flags.patch
+# Patch1: huge_page_setup_helper.py Python3 conversion
+# Upstream tickets:
+# Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1598570
+# libhugetlbfs: https://github.com/libhugetlbfs/libhugetlbfs/issues/35
+Patch1: huge_page_setup_helper-python3-convert.patch
+# Downstream patch for further Python3 conversion RHBZ#1620250
+Patch2: run_tests-python3-convert.patch
+# Downstream patch testcases to avoid bogus annoying failures
+# RHBZ#1611780 && RHBZ#1611782
+Patch3: 0001-testutils-fix-range_is_mapped.patch
+Patch4: 0002-stack_grow_into_huge-don-t-clobber-existing-mappings.patch
+# RHBZ#1628794 undersized SHMMAX when running on aarch64
+# https://github.com/libhugetlbfs/libhugetlbfs/issues/39
+Patch5: tests_shm-perms_adjust_max_segment_size_for_bigger_hugepages.patch
+
+BuildRequires: glibc-devel
+BuildRequires: glibc-static
+BuildRequires: python3-devel
+BuildRequires: execstack
+
+%define ldscriptdir %{_datadir}/%{name}/ldscripts
+
+%description
+libhugetlbfs is a library which provides easy access to huge pages of memory.
+It is a wrapper for the hugetlbfs file system. Applications can use huge pages
+to fulfill malloc() requests without being recompiled by using LD_PRELOAD.
+Alternatively, applications can be linked against libhugetlbfs without source
+modifications to load BSS or BSS, data, and text segments into large pages.
+
+%package devel
+Summary:	Header files for libhugetlbfs
+Group:		Development/Libraries
+Requires:	%{name} = %{version}-%{release}
+%description devel
+Contains header files for building with libhugetlbfs.
+
+%package utils
+Summary:	Userspace utilities for configuring the hugepage environment
+Group:		Applications/System
+Requires:	%{name} = %{version}-%{release}
+%description utils
+This packages contains a number of utilities that will help administrate the
+use of huge pages on your system.  hugeedit modifies binaries to set default
+segment remapping behavior. hugectl sets environment variables for using huge
+pages and then execs the target program. hugeadm gives easy access to huge page
+pool size control. pagesize lists page sizes available on the machine.
+
+%prep
+%setup -q -n %{name}-%{version}
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+pathfix.py -i %{__python3} -pn huge_page_setup_helper.py \
+                                      tests/run_tests.py
+
+%build
+%set_build_flags
+# Parallel builds are not reliable
+make BUILDTYPE=NATIVEONLY V=1
+
+%install
+make install PREFIX=%{_prefix} DESTDIR=$RPM_BUILD_ROOT LDSCRIPTDIR=%{ldscriptdir} BUILDTYPE=NATIVEONLY
+make install-helper PREFIX=%{_prefix} DESTDIR=$RPM_BUILD_ROOT LDSCRIPTDIR=%{ldscriptdir} BUILDTYPE=NATIVEONLY
+mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/security/limits.d
+touch $RPM_BUILD_ROOT%{_sysconfdir}/security/limits.d/hugepages.conf
+
+# clear execstack flag
+execstack --clear-execstack %{buildroot}/%{_libdir}/libhugetlbfs.so
+
+# remove statically built libraries:
+rm -f $RPM_BUILD_ROOT/%{_libdir}/*.a
+# remove unused sbin directory
+rm -fr $RPM_BUILD_ROOT/%{_sbindir}/
+
+# fix up dangling symlink warnings on RPMDiff
+rm -f %{buildroot}/%{_libdir}/libhugetlbfs_privutils.so
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%{_libdir}/libhugetlbfs.so*
+%{_datadir}/%{name}/
+%{_mandir}/man7/libhugetlbfs.7.gz
+%ghost %config(noreplace) %{_sysconfdir}/security/limits.d/hugepages.conf
+%exclude %{_libdir}/libhugetlbfs_privutils.so
+%doc README HOWTO LGPL-2.1 NEWS
+
+%files devel
+%{_includedir}/hugetlbfs.h
+%{_mandir}/man3/getpagesizes.3.gz
+%{_mandir}/man3/free_huge_pages.3.gz
+%{_mandir}/man3/get_huge_pages.3.gz
+%{_mandir}/man3/gethugepagesize.3.gz
+%{_mandir}/man3/gethugepagesizes.3.gz
+%{_mandir}/man3/free_hugepage_region.3.gz
+%{_mandir}/man3/get_hugepage_region.3.gz
+%{_mandir}/man3/hugetlbfs_find_path.3.gz
+%{_mandir}/man3/hugetlbfs_find_path_for_size.3.gz
+%{_mandir}/man3/hugetlbfs_test_path.3.gz
+%{_mandir}/man3/hugetlbfs_unlinked_fd.3.gz
+%{_mandir}/man3/hugetlbfs_unlinked_fd_for_size.3.gz
+
+%files utils
+%{_bindir}/hugeedit
+%{_bindir}/hugeadm
+%{_bindir}/hugectl
+%{_bindir}/pagesize
+%{_bindir}/huge_page_setup_helper.py
+%exclude %{_bindir}/cpupcstat
+%exclude %{_bindir}/oprofile_map_events.pl
+%exclude %{_bindir}/oprofile_start.sh
+%{_mandir}/man8/hugeedit.8.gz
+%{_mandir}/man8/hugectl.8.gz
+%{_mandir}/man8/hugeadm.8.gz
+%{_mandir}/man1/pagesize.1.gz
+%{_mandir}/man1/ld.hugetlbfs.1.gz
+%exclude %{_mandir}/man8/cpupcstat.8.gz
+%exclude %{_libdir}/perl5/TLBC
+
+%changelog
+* Wed Oct  3 2018 Rafael Aquini <aquini@redhat.com> - 2.21-1
+- Fix small_const/small_data is not hugepage test failures (1628794)
+
+* Tue Sep 11 2018 Rafael Aquini <aquini@redhat.com> - 2.20-12
+- Finish up Python3 conversion fo tests/run_tests.py (1620250)
+
+* Mon Sep 10 2018 Rafael Aquini <aquini@redhat.com> - 2.20-11
+- Fix up rpmdiff execshield flag failures (1627532)
+
+* Tue Sep 04 2018 Rafael Aquini <aquini@redhat.com> - 2.20-10
+- Fix up annocheck distro flag failures (1624131)
+- Convert libhugetlbfs run_tests.py to Python3 (1620250)
+
+* Thu Aug 02 2018 Rafael Aquini <aquini@redhat.com> - 2.20-9
+- Fix up libhugetlbfs testcase problems (1611780 1611782)
+
+* Wed Aug 01 2018 Charalampos Stratakis <cstratak@redhat.com> - 2.20-8
+- Fix python shebangs
+
+* Thu Jul 05 2018 Rafael Aquini <aquini@redhat.com> - 2.20-7
+- Remove python2 dependency for RHEL8 mass rebuilds (1561516 1580761)
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.20-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.20-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.20-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.20-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.20-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Thu Dec 03 2015 Eric B Munson <emunson@mgebm.net> - 2.20-1
+- Update to 2.20 upstream
+
+* Wed Jul 01 2015 Eric B Munson <emunson@mgebm.net> - 2.19-1
+- Update to 2.19 upstream
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.18-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.18-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.18-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Mon Apr 07 2014 Eric B Munson <emunson@mgebm.net> - 2.18-2
+- Remove unnecessary ppc makefile patch
+
+* Sun Apr 06 2014 Eric B Munson <emunson@mgebm.net> - 2.18-1
+- Update to 2.18 upstream
+
+* Sat Mar 15 2014 Eric B Munson <emunson@mgebm.net> - 2.12-2
+- Add Patch to support building on ppc64le
+
+* Wed Jan 29 2014 Kyle McMartin <kyle@fedoraproject.org> - 2.17-1
+- Update for upstream 2.17 release (adds AArch64 support)
+- update libhugetlbfs-2.16-s390.patch for 2.17 changes to Makefile
+- add libhugetlbfs-2.17-ppc.patch to fix powerpc{,64}
+
+* Thu Jul 25 2013 Dan HorĂ¡k <dan[at]danny.cz> - 2.16-2
+- Fix build on s390/s390x (patch by aarapov@rh.c)
+- Use Fedora CFLAGS for build
+
+* Mon Apr 29 2013 Peter Robinson <pbrobinson@fedoraproject.org> 2.16-1
+- Upstream 2.16 release (adds ARM support)
+
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.15-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Sat Dec 08 2012 Eric B Munson <emunson@mgebm.net> - 2.15
+- Update for upstream 2.15 release
+
+* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.13-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Sat Mar 24 2012 Eric B Munson <emunson@mgebm.net>
+- Update for upstream 2.13 release
+
+* Wed Jul 20 2011 Eric B Munson <emunson@mgebm.net>
+- Update for upstream 2.12 release
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.9-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Apr 05 2010 Eric B Munson <ebmunson@us.ibm.com> 2.8-1
+- Update for upstream 2.8 release
+
+* Wed Feb 10 2010 Eric B Munson <ebmunson@us.ibm.com> 2.7-2
+- Include patch that fixes build on ppc
+
+* Tue Jan 05 2010 Eric B Munson <ebmunson@us.ibm.com> 2.7-1
+- Update for upstream 2.7 release
+
+* Fri Oct 02 2009 Jarod Wilson <jarod@redhat.com> 2.6-3
+- Add hopefully-about-to-be-merged-upstream hugeadm enhancements
+- Add huge pages setup helper script, using new hugeadm enhancements
+
+* Thu Sep 03 2009 Nils Philippsen <nils@redhat.com> 2.6-2
+- fix building on s390x
+
+* Mon Aug 31 2009 Eric Munson <ebmunson@us.ibm.com> 2.6-1
+- Updating for the libhugetlbfs-2.6 release
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.5-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Mon Jul 20 2009 Eric Munson <ebmunson@us.ibm.com> 2.5-2
+- Update Group for -utils package to Applications/System
+
+* Tue Jun 30 2009 Eric Munson <ebmunson@us.ibm.com> 2.5-1
+- Updating for the libhugetlbfs-2.5 release
+
+* Tue Jun 02 2009 Eric Munson <ebmunson@us.ibm.com> 2.4-2
+- Adding patch to remove S390 32 bit build
+
+* Fri May 29 2009 Eric Munson <ebmunson@us.ibm.com> 2.4-1
+- Updating for the libhugetlbfs-2.4 release
+
+* Wed Apr 15 2009 Eric Munson <ebmunson@us.ibm.com> 2.3-1
+- Updating for the libhugetlbfs-2.3 release
+
+* Wed Feb 11 2009 Eric Munson <ebmunson@us.ibm.com> 2.2-1
+- Updating for the libhugetlbfs-2.2 release
+
+* Fri Dec 19 2008 Eric Munson <ebmunson@us.ibm.com> 2.1.2-1
+- Updating for libhugetlbfs-2.1.2 release
+
+* Fri Dec 19 2008 Eric Munson <ebmunson@us.ibm.com> 2.1.1-1
+- Updating for libhugetlbfs-2.1.1 release
+
+* Thu Dec 18 2008 Josh Boyer <jwboyer@gmail.com> 2.1-2
+- Fix broken dependency caused by just dropping -test
+  subpackage
+
+* Thu Oct 16 2008 Eric Munson <ebmunson@us.ibm.com> 2.1-1
+- Updating for libhuge-2.1 release
+- Adding -devel and -utils subpackages for various utilities
+  and devel files.
+
+* Wed May 14 2008 Eric Munson <ebmunson@us.ibm.com> 1.3-1
+- Updating for libhuge-1.3 release
+
+* Tue Mar 25 2008 Eric Munson <ebmunson@us.ibm.com> 1.2-1
+- Removing test rpm target, and excluding test files
+
+* Mon Mar 26 2007 Steve Fox <drfickle@k-lug.org> - 1.1-1
+- New release (1.1)
+- Fix directory ownership
+
+* Wed Aug 30 2006 Steve Fox <drfickle@k-lug.org> - 0.20060825-1
+- New release (1.0-preview4)
+- patch0 (Makefile-ldscript.diff) merged upstream
+
+* Tue Jul 25 2006 Steve Fox <drfickle@k-lug.org> - 0.20060706-4
+- Bump for build system
+
+* Tue Jul 25 2006 Steve Fox <drfickle@k-lug.org> - 0.20060706-3
+- Don't use parallel build as it has random failures
+
+* Thu Jul 20 2006 Steve Fox <drfickle@k-lug.org> - 0.20060706-2
+- Fix the Makefile so that the ld.hugetlbfs script doesn't store the
+  DESTDIR in the path to the ldscripts dir
+
+* Fri Jul 7 2006 Steve Fox <drfickle@k-lug.org> - 0.20060706-1
+- New release which includes a fix for the syscall macro removal in the
+  Rawhide kernels
+
+* Thu Jun 29 2006 Steve Fox <drfickle@k-lug.org> - 0.20060628-1
+- First Fedora package