diff --git a/SOURCES/2.25-blockdev-geom.patch b/SOURCES/2.25-blockdev-geom.patch
new file mode 100644
index 0000000..4bf6b61
--- /dev/null
+++ b/SOURCES/2.25-blockdev-geom.patch
@@ -0,0 +1,95 @@
+diff -up util-linux-2.23.2/disk-utils/blockdev.c.kzak util-linux-2.23.2/disk-utils/blockdev.c
+--- util-linux-2.23.2/disk-utils/blockdev.c.kzak	2015-06-23 11:29:27.818001654 +0200
++++ util-linux-2.23.2/disk-utils/blockdev.c	2015-06-23 11:29:43.752884860 +0200
+@@ -16,6 +16,7 @@
+ #include "blkdev.h"
+ #include "pathnames.h"
+ #include "closestream.h"
++#include "sysfs.h"
+ 
+ struct bdc {
+ 	long		ioc;		/* ioctl code */
+@@ -364,7 +365,7 @@ static void do_commands(int fd, char **a
+ 		}
+ 
+ 		if (res == -1) {
+-			perror(bdcms[j].iocname);
++			warn(_("ioctl error on %s"), bdcms[j].iocname);
+ 			if (verbose)
+ 				printf(_("%s failed.\n"), _(bdcms[j].help));
+ 			exit(EXIT_FAILURE);
+@@ -436,7 +437,8 @@ static void report_device(char *device,
+ 	int ro, ssz, bsz;
+ 	long ra;
+ 	unsigned long long bytes;
+-	struct hd_geometry g;
++	uint64_t start = 0;
++	struct stat st;
+ 
+ 	fd = open(device, O_RDONLY | O_NONBLOCK);
+ 	if (fd < 0) {
+@@ -446,15 +448,27 @@ static void report_device(char *device,
+ 	}
+ 
+ 	ro = ssz = bsz = 0;
+-	g.start = ra = 0;
++	ra = 0;
++	if (fstat(fd, &st) == 0 && !sysfs_devno_is_wholedisk(st.st_rdev)) {
++		struct sysfs_cxt cxt;
++
++		if (sysfs_init(&cxt, st.st_rdev, NULL))
++			err(EXIT_FAILURE,
++				_("%s: failed to initialize sysfs handler"),
++				device);
++		if (sysfs_read_u64(&cxt, "start", &start))
++			err(EXIT_FAILURE,
++				_("%s: failed to read partition start from sysfs"),
++				device);
++		sysfs_deinit(&cxt);
++	}
+ 	if (ioctl(fd, BLKROGET, &ro) == 0 &&
+ 	    ioctl(fd, BLKRAGET, &ra) == 0 &&
+ 	    ioctl(fd, BLKSSZGET, &ssz) == 0 &&
+ 	    ioctl(fd, BLKBSZGET, &bsz) == 0 &&
+-	    ioctl(fd, HDIO_GETGEO, &g) == 0 &&
+ 	    blkdev_get_size(fd, &bytes) == 0) {
+-		printf("%s %5ld %5d %5d %10ld %15lld   %s\n",
+-		       ro ? "ro" : "rw", ra, ssz, bsz, g.start, bytes, device);
++		printf("%s %5ld %5d %5d %10ju %15lld   %s\n",
++		       ro ? "ro" : "rw", ra, ssz, bsz, start, bytes, device);
+ 	} else {
+ 		if (!quiet)
+ 			warnx(_("ioctl error on %s"), device);
+diff -up util-linux-2.23.2/include/sysfs.h.kzak util-linux-2.23.2/include/sysfs.h
+--- util-linux-2.23.2/include/sysfs.h.kzak	2015-06-23 11:32:12.709793086 +0200
++++ util-linux-2.23.2/include/sysfs.h	2015-06-23 11:32:31.909652361 +0200
+@@ -72,6 +72,7 @@ extern int sysfs_is_partition_dirent(DIR
+ 
+ extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
+             size_t len, dev_t *diskdevno);
++extern int sysfs_devno_is_wholedisk(dev_t devno);
+ 
+ extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h,
+ 			       int *c, int *t, int *l);
+diff -up util-linux-2.23.2/lib/sysfs.c.kzak util-linux-2.23.2/lib/sysfs.c
+--- util-linux-2.23.2/lib/sysfs.c.kzak	2015-06-23 11:31:32.166090250 +0200
++++ util-linux-2.23.2/lib/sysfs.c	2015-06-23 11:31:59.684888551 +0200
+@@ -638,6 +638,18 @@ err:
+     return -1;
+ }
+ 
++/*
++ * Return 0 or 1, or < 0 in case of error
++ */
++int sysfs_devno_is_wholedisk(dev_t devno)
++{
++	dev_t disk;
++
++	if (sysfs_devno_to_wholedisk(devno, NULL, 0, &disk) != 0)
++		return -1;
++
++	return devno == disk;
++}
+ 
+ int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, int *c, int *t, int *l)
+ {
diff --git a/SOURCES/2.25-fstrim-all.patch b/SOURCES/2.25-fstrim-all.patch
new file mode 100644
index 0000000..233e2ec
--- /dev/null
+++ b/SOURCES/2.25-fstrim-all.patch
@@ -0,0 +1,496 @@
+diff -up util-linux-2.23.2/libmount/src/libmount.h.in.kzak util-linux-2.23.2/libmount/src/libmount.h.in
+--- util-linux-2.23.2/libmount/src/libmount.h.in.kzak	2015-06-23 11:54:00.510210784 +0200
++++ util-linux-2.23.2/libmount/src/libmount.h.in	2015-06-23 11:54:58.592785482 +0200
+@@ -420,6 +420,15 @@ extern int mnt_table_get_root_fs(struct
+ extern int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr,
+ 			      struct libmnt_fs *fs);
+ 
++enum {
++	MNT_UNIQ_FORWARD  = (1 << 1),	/* default is backward */
++	MNT_UNIQ_KEEPTREE = (1 << 2)
++};
++extern int mnt_table_uniq_fs(struct libmnt_table *tb, int flags,
++				int (*cmp)(struct libmnt_table *,
++					   struct libmnt_fs *,
++					   struct libmnt_fs *));
++
+ extern struct libmnt_fs *mnt_table_find_mountpoint(struct libmnt_table *tb,
+ 				const char *path, int direction);
+ extern struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb,
+diff -up util-linux-2.23.2/libmount/src/libmount.sym.kzak util-linux-2.23.2/libmount/src/libmount.sym
+--- util-linux-2.23.2/libmount/src/libmount.sym.kzak	2015-06-23 11:56:47.259989779 +0200
++++ util-linux-2.23.2/libmount/src/libmount.sym	2015-06-23 11:56:17.681206366 +0200
+@@ -256,3 +256,9 @@ global:
+ 	mnt_context_find_umount_fs;
+ 	mnt_table_find_mountpoint;
+ } MOUNT_2.22;
++
++/* backport from v2.25 to RHEL7 */
++MOUNT_2.25 {
++	mnt_table_uniq_fs;
++} MOUNT_2.23;
++
+diff -up util-linux-2.23.2/libmount/src/tab.c.kzak util-linux-2.23.2/libmount/src/tab.c
+--- util-linux-2.23.2/libmount/src/tab.c.kzak	2015-06-23 11:52:04.750058424 +0200
++++ util-linux-2.23.2/libmount/src/tab.c	2015-06-23 11:53:26.109462680 +0200
+@@ -398,6 +398,93 @@ int mnt_table_find_next_fs(struct libmnt
+ 	return 1;
+ }
+ 
++static int mnt_table_move_parent(struct libmnt_table *tb, int oldid, int newid)
++{
++	struct libmnt_iter itr;
++	struct libmnt_fs *fs;
++
++	if (!tb)
++		return -EINVAL;
++	if (list_empty(&tb->ents))
++		return 0;
++
++
++	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
++
++	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
++		if (fs->parent == oldid)
++			fs->parent = newid;
++	}
++	return 0;
++}
++
++/**
++ * mnt_table_uniq_fs:
++ * @tb: table
++ * @flags: MNT_UNIQ_*
++ * @cmp: function to compare filesystems
++ *
++ * This function de-duplicate the @tb, but does not change order of the
++ * filesystems. The @cmp function has to return 0 if the filesystems are
++ * equal, otherwise non-zero.
++ *
++ * The default is to keep in the table later mounted filesystems (function uses
++ * backward mode iterator).
++ *
++ * @MNT_UNIQ_FORWARD:  remove later mounted filesystems
++ * @MNT_UNIQ_KEEPTREE: keep parent->id relation ship stil valid
++ *
++ * Returns: negative number in case of error, or 0 o success.
++ */
++int mnt_table_uniq_fs(struct libmnt_table *tb, int flags,
++				int (*cmp)(struct libmnt_table *,
++					   struct libmnt_fs *,
++					   struct libmnt_fs *))
++{
++	struct libmnt_iter itr;
++	struct libmnt_fs *fs;
++	int direction = MNT_ITER_BACKWARD;
++
++	if (!tb || !cmp)
++		return -EINVAL;
++	if (list_empty(&tb->ents))
++		return 0;
++
++	if (flags & MNT_UNIQ_FORWARD)
++		direction = MNT_ITER_FORWARD;
++
++
++	mnt_reset_iter(&itr, direction);
++
++	if ((flags & MNT_UNIQ_KEEPTREE) && !is_mountinfo(tb))
++		flags &= ~MNT_UNIQ_KEEPTREE;
++
++	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
++		int want = 1;
++		struct libmnt_iter xtr;
++		struct libmnt_fs *x;
++
++		mnt_reset_iter(&xtr, direction);
++		while (want && mnt_table_next_fs(tb, &xtr, &x) == 0) {
++			if (fs == x)
++				break;
++			want = cmp(tb, x, fs) != 0;
++		}
++
++		if (!want) {
++			if (flags & MNT_UNIQ_KEEPTREE)
++				mnt_table_move_parent(tb, mnt_fs_get_id(fs),
++							  mnt_fs_get_parent_id(fs));
++
++
++
++			mnt_table_remove_fs(tb, fs);
++		}
++	}
++
++	return 0;
++}
++
+ /**
+  * mnt_table_set_iter:
+  * @tb: tab pointer
+diff -up util-linux-2.23.2/sys-utils/fstrim.c.kzak util-linux-2.23.2/sys-utils/fstrim.c
+--- util-linux-2.23.2/sys-utils/fstrim.c.kzak	2013-06-13 09:46:10.535651605 +0200
++++ util-linux-2.23.2/sys-utils/fstrim.c	2015-06-23 11:57:59.435461283 +0200
+@@ -41,6 +41,11 @@
+ #include "strutils.h"
+ #include "c.h"
+ #include "closestream.h"
++#include "pathnames.h"
++#include "sysfs.h"
++#include "exitcodes.h"
++
++#include <libmount.h>
+ 
+ #ifndef FITRIM
+ struct fstrim_range {
+@@ -51,16 +56,216 @@ struct fstrim_range {
+ #define FITRIM		_IOWR('X', 121, struct fstrim_range)
+ #endif
+ 
++/* returns: 0 = success, 1 = unsupported, < 0 = error */
++static int fstrim_filesystem(const char *path, struct fstrim_range *rangetpl,
++			    int verbose)
++{
++	int fd;
++	struct stat sb;
++	struct fstrim_range range;
++
++	/* kernel modifies the range */
++	memcpy(&range, rangetpl, sizeof(range));
++
++	fd = open(path, O_RDONLY);
++	if (fd < 0) {
++		warn(_("cannot open %s"), path);
++		return -1;
++	}
++	if (fstat(fd, &sb) == -1) {
++		warn(_("stat of %s failed"), path);
++		return -1;
++	}
++	if (!S_ISDIR(sb.st_mode)) {
++		warnx(_("%s: not a directory"), path);
++		return -1;
++	}
++	errno = 0;
++	if (ioctl(fd, FITRIM, &range)) {
++		int rc = errno == EOPNOTSUPP || errno == ENOTTY ? 1 : -1;
++
++		if (rc != 1)
++			warn(_("%s: FITRIM ioctl failed"), path);
++		close(fd);
++		return rc;
++	}
++
++	if (verbose) {
++		char *str = size_to_human_string(
++				SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
++				(uint64_t) range.len);
++		/* TRANSLATORS: The standard value here is a very large number. */
++		printf(_("%s: %s (%" PRIu64 " bytes) trimmed\n"),
++				path, str, (uint64_t) range.len);
++		free(str);
++	}
++	close(fd);
++	return 0;
++}
++
++static int has_discard(const char *devname, struct sysfs_cxt *wholedisk)
++{
++	struct sysfs_cxt cxt, *parent = NULL;
++	uint64_t dg = 0;
++	dev_t disk = 0, dev;
++	int rc;
++
++	dev = sysfs_devname_to_devno(devname, NULL);
++	if (!dev)
++		return 1;
++	/*
++	 * This is tricky to read the info from sys/, because the queue
++	 * atrributes are provided for whole devices (disk) only. We're trying
++	 * to reuse the whole-disk sysfs context to optimize this stuff (as
++	 * system usually have just one disk only).
++	 */
++	if (sysfs_devno_to_wholedisk(dev, NULL, 0, &disk) || !disk)
++		return 1;
++	if (dev != disk) {
++		if (wholedisk->devno != disk) {
++			sysfs_deinit(wholedisk);
++			if (sysfs_init(wholedisk, disk, NULL))
++				return 1;
++		}
++		parent = wholedisk;
++	}
++
++	rc = sysfs_init(&cxt, dev, parent);
++	if (!rc)
++		rc = sysfs_read_u64(&cxt, "queue/discard_granularity", &dg);
++
++	sysfs_deinit(&cxt);
++	return rc == 0 && dg > 0;
++}
++
++
++static int uniq_fs_target_cmp(
++		struct libmnt_table *tb __attribute__((__unused__)),
++		struct libmnt_fs *a,
++		struct libmnt_fs *b)
++{
++	return !mnt_fs_streq_target(a, mnt_fs_get_target(b));
++}
++
++static int uniq_fs_source_cmp(
++		struct libmnt_table *tb __attribute__((__unused__)),
++		struct libmnt_fs *a,
++		struct libmnt_fs *b)
++{
++	int eq;
++
++	if (mnt_fs_is_pseudofs(a) || mnt_fs_is_netfs(a) ||
++	    mnt_fs_is_pseudofs(b) || mnt_fs_is_netfs(b))
++		return 1;
++
++	eq = mnt_fs_streq_srcpath(a, mnt_fs_get_srcpath(b));
++	if (eq) {
++		const char *aroot = mnt_fs_get_root(a),
++			   *broot = mnt_fs_get_root(b);
++		if (!aroot || !broot)
++			eq = 0;
++		else if (strcmp(aroot, broot) != 0)
++			eq = 0;
++	}
++
++	return !eq;
++}
++
++/*
++ * fstrim --all follows "mount -a" return codes:
++ *
++ * 0  = all success
++ * 32 = all failed
++ * 64 = some failed, some success
++ */
++static int fstrim_all(struct fstrim_range *rangetpl, int verbose)
++{
++	struct libmnt_fs *fs;
++	struct libmnt_iter *itr;
++	struct libmnt_table *tab;
++	struct sysfs_cxt wholedisk = UL_SYSFSCXT_EMPTY;
++	int cnt = 0, cnt_err = 0;
++
++	mnt_init_debug(0);
++
++	itr = mnt_new_iter(MNT_ITER_BACKWARD);
++	if (!itr)
++		err(MOUNT_EX_FAIL, _("failed to initialize libmount iterator"));
++
++	tab = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
++	if (!tab)
++		err(MOUNT_EX_FAIL, _("failed to parse %s"), _PATH_PROC_MOUNTINFO);
++
++	/* de-duplicate by mountpoints */
++	mnt_table_uniq_fs(tab, 0, uniq_fs_target_cmp);
++
++	/* de-duplicate by source and root */
++	mnt_table_uniq_fs(tab, 0, uniq_fs_source_cmp);
++
++	while (mnt_table_next_fs(tab, itr, &fs) == 0) {
++		const char *src = mnt_fs_get_srcpath(fs),
++			   *tgt = mnt_fs_get_target(fs);
++		char *path;
++		int rc = 1;
++
++		if (!src || !tgt || *src != '/' ||
++		    mnt_fs_is_pseudofs(fs) ||
++		    mnt_fs_is_netfs(fs))
++			continue;
++
++		/* Is it really accessible mountpoint? Not all mountpoints are
++		 * accessible (maybe over mounted by another fylesystem) */
++		path = mnt_get_mountpoint(tgt);
++		if (path && strcmp(path, tgt) == 0)
++			rc = 0;
++		free(path);
++		if (rc)
++			continue;	/* overlaying mount */
++
++		if (!has_discard(src, &wholedisk))
++			continue;
++		cnt++;
++
++		/*
++		 * We're able to detect that the device supports discard, but
++		 * things also depend on filesystem or device mapping, for
++		 * example vfat or LUKS (by default) does not support FSTRIM.
++		 *
++		 * This is reason why we ignore EOPNOTSUPP and ENOTTY errors
++		 * from discard ioctl.
++		 */
++		if (fstrim_filesystem(tgt, rangetpl, verbose) < 0)
++		       cnt_err++;
++	}
++
++	sysfs_deinit(&wholedisk);
++	mnt_free_table(tab);
++	mnt_free_iter(itr);
++
++	if (cnt && cnt == cnt_err)
++		return MOUNT_EX_FAIL;		/* all failed */
++	if (cnt && cnt_err)
++		return MOUNT_EX_SOMEOK;		/* some ok */
++
++	return EXIT_SUCCESS;
++}
++
+ static void __attribute__((__noreturn__)) usage(FILE *out)
+ {
+ 	fputs(USAGE_HEADER, out);
+ 	fprintf(out,
+ 	      _(" %s [options] <mount point>\n"), program_invocation_short_name);
++
++	fputs(USAGE_SEPARATOR, out);
++	fputs(_("Discard unused blocks on a mounted filesystem.\n"), out);
++
+ 	fputs(USAGE_OPTIONS, out);
+-	fputs(_(" -o, --offset <num>  offset in bytes to discard from\n"
+-		" -l, --length <num>  length of bytes to discard from the offset\n"
+-		" -m, --minimum <num> minimum extent length to discard\n"
+-		" -v, --verbose       print number of discarded bytes\n"), out);
++	fputs(_(" -a, --all           trim all mounted filesystems that are supported\n"), out);
++	fputs(_(" -o, --offset <num>  the offset in bytes to start discarding from\n"), out);
++	fputs(_(" -l, --length <num>  the number of bytes to discard\n"), out);
++	fputs(_(" -m, --minimum <num> the minimum extent length to discard\n"), out);
++	fputs(_(" -v, --verbose       print number of discarded bytes\n"), out);
++
+ 	fputs(USAGE_SEPARATOR, out);
+ 	fputs(USAGE_HELP, out);
+ 	fputs(USAGE_VERSION, out);
+@@ -70,12 +275,12 @@ static void __attribute__((__noreturn__)
+ 
+ int main(int argc, char **argv)
+ {
+-	char *path;
+-	int c, fd, verbose = 0;
++	char *path = NULL;
++	int c, rc, verbose = 0, all = 0;
+ 	struct fstrim_range range;
+-	struct stat sb;
+ 
+ 	static const struct option longopts[] = {
++	    { "all",       0, 0, 'a' },
+ 	    { "help",      0, 0, 'h' },
+ 	    { "version",   0, 0, 'V' },
+ 	    { "offset",    1, 0, 'o' },
+@@ -93,8 +298,11 @@ int main(int argc, char **argv)
+ 	memset(&range, 0, sizeof(range));
+ 	range.len = ULLONG_MAX;
+ 
+-	while ((c = getopt_long(argc, argv, "hVo:l:m:v", longopts, NULL)) != -1) {
++	while ((c = getopt_long(argc, argv, "ahVo:l:m:v", longopts, NULL)) != -1) {
+ 		switch(c) {
++		case 'a':
++			all = 1;
++			break;
+ 		case 'h':
+ 			usage(stdout);
+ 			break;
+@@ -122,38 +330,26 @@ int main(int argc, char **argv)
+ 		}
+ 	}
+ 
+-	if (optind == argc)
+-		errx(EXIT_FAILURE, _("no mountpoint specified"));
+-
+-	path = argv[optind++];
++	if (!all) {
++		if (optind == argc)
++			errx(EXIT_FAILURE, _("no mountpoint specified"));
++		path = argv[optind++];
++	}
+ 
+ 	if (optind != argc) {
+ 		warnx(_("unexpected number of arguments"));
+ 		usage(stderr);
+ 	}
+ 
+-	if (stat(path, &sb) == -1)
+-		err(EXIT_FAILURE, _("stat failed %s"), path);
+-	if (!S_ISDIR(sb.st_mode))
+-		errx(EXIT_FAILURE, _("%s: not a directory"), path);
+-
+-	fd = open(path, O_RDONLY);
+-	if (fd < 0)
+-		err(EXIT_FAILURE, _("cannot open %s"), path);
+-
+-	if (ioctl(fd, FITRIM, &range))
+-		err(EXIT_FAILURE, _("%s: FITRIM ioctl failed"), path);
+-
+-	if (verbose) {
+-		char *str = size_to_human_string(SIZE_SUFFIX_3LETTER |
+-						 SIZE_SUFFIX_SPACE,
+-						 (uint64_t) range.len);
+-		/* TRANSLATORS: The standard value here is a very large number. */
+-		printf(_("%s: %s (%" PRIu64 " bytes) trimmed\n"),
+-						path, str,
+-						(uint64_t) range.len);
+-		free(str);
++	if (all)
++		rc = fstrim_all(&range, verbose);
++	else {
++		rc = fstrim_filesystem(path, &range, verbose);
++		if (rc == 1) {
++			warnx(_("%s: the discard operation is not supported"), path);
++			rc = EXIT_FAILURE;
++		}
+ 	}
+-	close(fd);
+-	return EXIT_SUCCESS;
++
++	return rc;
+ }
+diff -up util-linux-2.23.2/sys-utils/fstrim.service.in.kzak util-linux-2.23.2/sys-utils/fstrim.service
+--- util-linux-2.23.2/sys-utils/fstrim.service.in.kzak	2015-06-23 12:02:18.505564273 +0200
++++ util-linux-2.23.2/sys-utils/fstrim.service.in	2015-06-23 12:02:05.049662802 +0200
+@@ -0,0 +1,6 @@
++[Unit]
++Description=Discard unused blocks
++
++[Service]
++Type=oneshot
++ExecStart=@sbindir@/fstrim -a
+diff -up util-linux-2.23.2/sys-utils/fstrim.timer.kzak util-linux-2.23.2/sys-utils/fstrim.timer
+--- util-linux-2.23.2/sys-utils/fstrim.timer.kzak	2015-06-23 12:02:18.505564273 +0200
++++ util-linux-2.23.2/sys-utils/fstrim.timer	2015-06-23 12:02:05.049662802 +0200
+@@ -0,0 +1,11 @@
++[Unit]
++Description=Discard unused blocks once a week
++Documentation=man:fstrim
++
++[Timer]
++OnCalendar=weekly
++AccuracySec=1h
++Persistent=true
++
++[Install]
++WantedBy=multi-user.target
+diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am
+--- util-linux-2.23.2/sys-utils/Makemodule.am.kzak	2015-06-23 11:59:05.803975307 +0200
++++ util-linux-2.23.2/sys-utils/Makemodule.am	2015-06-23 12:01:18.682002323 +0200
+@@ -68,7 +68,18 @@ fsfreeze_SOURCES = sys-utils/fsfreeze.c
+ sbin_PROGRAMS += fstrim
+ dist_man_MANS += sys-utils/fstrim.8
+ fstrim_SOURCES = sys-utils/fstrim.c
+-fstrim_LDADD = $(LDADD) libcommon.la
++fstrim_LDADD = $(LDADD) libcommon.la libmount.la
++fstrim_CFLAGS = $(AM_CFLAGS) -I$(ul_libmount_incdir)
++
++if HAVE_SYSTEMD
++systemdsystemunit_DATA += \
++		sys-utils/fstrim.service \
++		sys-utils/fstrim.timer
++endif
++
++PATHFILES += sys-utils/fstrim.service
++EXTRA_DIST += sys-utils/fstrim.timer
++
+ 
+ sbin_PROGRAMS += blkdiscard
+ dist_man_MANS += sys-utils/blkdiscard.8
diff --git a/SOURCES/2.25-libblkid-return-codes.patch b/SOURCES/2.25-libblkid-return-codes.patch
new file mode 100644
index 0000000..6462359
--- /dev/null
+++ b/SOURCES/2.25-libblkid-return-codes.patch
@@ -0,0 +1,204 @@
+diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak util-linux-2.23.2/libblkid/src/partitions/partitions.c
+--- util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak	2015-08-11 14:00:27.930573965 +0200
++++ util-linux-2.23.2/libblkid/src/partitions/partitions.c	2015-08-11 14:13:11.213087814 +0200
+@@ -533,7 +533,7 @@ static int idinfo_probe(blkid_probe pr,
+ {
+ 	const struct blkid_idmag *mag = NULL;
+ 	blkid_loff_t off;
+-	int rc = BLKID_PROBE_NONE;		/* = nothing detected */
++	int rc = BLKID_PROBE_NONE;		/* default is nothing */
+ 
+ 	if (pr->size <= 0 || (id->minsz && id->minsz > pr->size))
+ 		goto nothing;	/* the device is too small */
+@@ -564,8 +564,10 @@ static int idinfo_probe(blkid_probe pr,
+ 		DBG(LOWPROBE, blkid_debug("%s: <--- (rc = %d)", id->name, rc));
+ 	}
+ 
+-nothing:
+ 	return rc;
++
++nothing:
++	return BLKID_PROBE_NONE;
+ }
+ 
+ /*
+@@ -620,7 +622,7 @@ static int partitions_probe(blkid_probe
+ 						strlen(name) + 1);
+ 		DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (type=%s) [PARTS idx=%d]",
+ 			name, chn->idx));
+-		rc = 0;
++		rc = BLKID_PROBE_OK;
+ 		break;
+ 	}
+ 
+@@ -637,10 +639,16 @@ details_only:
+ 	    (blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) {
+ 
+ 		int xrc = blkid_partitions_probe_partition(pr);
++
++		/* partition entry probing is optional, and "not-found" from
++		 * this sub-probing must not to overwrite previous success. */
+ 		if (xrc < 0)
+-			rc = xrc;	/* optional, care about errors only */
++			rc = xrc;			/* always propagate errors */
++		else if (rc == BLKID_PROBE_NONE)
++			rc = xrc;
+ 	}
+ 
++	DBG(LOWPROBE, blkid_debug("partitions probe done [rc=%d]", rc));
+ 	return rc;
+ }
+ 
+@@ -709,7 +717,6 @@ int blkid_partitions_do_subprobe(blkid_p
+ 
+ static int blkid_partitions_probe_partition(blkid_probe pr)
+ {
+-	int rc = BLKID_PROBE_NONE;
+ 	blkid_probe disk_pr = NULL;
+ 	blkid_partlist ls;
+ 	blkid_partition par;
+@@ -732,7 +739,9 @@ static int blkid_partitions_probe_partit
+ 		goto nothing;
+ 
+ 	par = blkid_partlist_devno_to_partition(ls, devno);
+-	if (par) {
++	if (!par)
++		goto nothing;
++	else {
+ 		const char *v;
+ 		blkid_parttable tab = blkid_partition_get_table(par);
+ 		dev_t disk = blkid_probe_get_devno(disk_pr);
+@@ -778,9 +787,13 @@ static int blkid_partitions_probe_partit
+ 		blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u",
+ 				major(disk), minor(disk));
+ 	}
+-	rc = BLKID_PROBE_OK;
++
++	DBG(LOWPROBE, blkid_debug("parts: end probing for partition entry [success]"));
++	return BLKID_PROBE_OK;
++
+ nothing:
+-	return rc;
++	DBG(LOWPROBE, blkid_debug("parts: end probing for partition entry [nothing]"));
++	return BLKID_PROBE_NONE;
+ }
+ 
+ /*
+diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c
+--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak	2015-07-03 10:35:05.456153560 +0200
++++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c	2015-08-11 14:08:42.572674469 +0200
+@@ -335,19 +335,24 @@ static int superblocks_probe(blkid_probe
+ 
+ 	if (!pr || chn->idx < -1)
+ 		return -EINVAL;
+-	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+-		goto nothing;
+ 
+ 	blkid_probe_chain_reset_vals(pr, chn);
+ 
+ 	DBG(LOWPROBE, blkid_debug("--> starting probing loop [SUBLKS idx=%d]",
+ 		chn->idx));
+ 
++	if (pr->flags & BLKID_FL_NOSCAN_DEV)
++		return BLKID_PROBE_NONE;
++
+ 	if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode)))
+ 		/* Ignore very very small block devices or regular files (e.g.
+ 		 * extended partitions). Note that size of the UBI char devices
+ 		 * is 1 byte */
+-		goto nothing;
++		return BLKID_PROBE_NONE;
++
++
++	DBG(LOWPROBE, blkid_debug("--> starting probing loop [SUBLKS idx=%d]",
++		chn->idx));
+ 
+ 	i = chn->idx < 0 ? 0 : chn->idx + 1U;
+ 
+@@ -417,7 +422,7 @@ static int superblocks_probe(blkid_probe
+ 					(unsigned char *) mag->magic);
+ 		if (rc) {
+ 			blkid_probe_chain_reset_vals(pr, chn);
+-			DBG(LOWPROBE, blkid_debug("failed to set result -- ingnore"));
++			DBG(LOWPROBE, blkid_debug("failed to set result -- ignore"));
+ 			continue;
+ 		}
+ 
+@@ -426,7 +431,6 @@ static int superblocks_probe(blkid_probe
+ 		return BLKID_PROBE_OK;
+ 	}
+ 
+-nothing:
+ 	DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
+ 			rc, chn->idx));
+ 	return rc;
+@@ -454,13 +458,12 @@ static int superblocks_safeprobe(blkid_p
+ 	int rc;
+ 
+ 	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+-		return 1;				/* nothing */
++		return BLKID_PROBE_NONE;
+ 
+ 	while ((rc = superblocks_probe(pr, chn)) == 0) {
+ 
+ 		if (blkid_probe_is_tiny(pr) && !count)
+-			/* floppy or so -- returns the first result. */
+-			return 0;
++			return BLKID_PROBE_OK;	/* floppy or so -- returns the first result. */
+ 
+ 		count++;
+ 
+@@ -489,7 +492,7 @@ static int superblocks_safeprobe(blkid_p
+ 		return -2;		/* error, ambivalent result (more FS) */
+ 	}
+ 	if (!count)
+-		return 1;		/* nothing detected */
++		return BLKID_PROBE_NONE;
+ 
+ 	if (idx != -1) {
+ 		/* restore the first result */
+@@ -506,7 +509,7 @@ static int superblocks_safeprobe(blkid_p
+ 	if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
+ 		pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
+ 
+-	return 0;
++	return BLKID_PROBE_OK;
+ }
+ 
+ int blkid_probe_set_version(blkid_probe pr, const char *version)
+diff -up util-linux-2.23.2/libblkid/src/topology/topology.c.kzak util-linux-2.23.2/libblkid/src/topology/topology.c
+--- util-linux-2.23.2/libblkid/src/topology/topology.c.kzak	2013-06-13 09:46:10.429650699 +0200
++++ util-linux-2.23.2/libblkid/src/topology/topology.c	2015-08-11 14:09:35.623361499 +0200
+@@ -150,7 +150,7 @@ static int topology_probe(blkid_probe pr
+ 		return -1;
+ 
+ 	if (!S_ISBLK(pr->mode))
+-		return -1;	/* nothing, works with block devices only */
++		return -EINVAL;	/* nothing, works with block devices only */
+ 
+ 	if (chn->binary) {
+ 		DBG(LOWPROBE, blkid_debug("initialize topology binary data"));
+@@ -163,7 +163,7 @@ static int topology_probe(blkid_probe pr
+ 			chn->data = calloc(1,
+ 					sizeof(struct blkid_struct_topology));
+ 			if (!chn->data)
+-				return -1;
++				return -ENOMEM;
+ 		}
+ 	}
+ 
+@@ -193,12 +193,12 @@ static int topology_probe(blkid_probe pr
+ 
+ 		DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (type=%s) [TOPOLOGY idx=%d]",
+ 			id->name, chn->idx));
+-		return 0;
++		return BLKID_PROBE_OK;
+ 	}
+ 
+ 	DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (failed) [TOPOLOGY idx=%d]",
+ 		chn->idx));
+-	return 1;
++	return BLKID_PROBE_NONE;
+ }
+ 
+ static void topology_free(blkid_probe pr __attribute__((__unused__)),
diff --git a/SOURCES/2.25-libblkid-thinpool.patch b/SOURCES/2.25-libblkid-thinpool.patch
index 0e5e565..b17b98c 100644
--- a/SOURCES/2.25-libblkid-thinpool.patch
+++ b/SOURCES/2.25-libblkid-thinpool.patch
@@ -1,6 +1,6 @@
 diff -up util-linux-2.23.2/fdisks/fdisk.c.kzak util-linux-2.23.2/fdisks/fdisk.c
---- util-linux-2.23.2/fdisks/fdisk.c.kzak	2013-07-30 10:39:26.195738131 +0200
-+++ util-linux-2.23.2/fdisks/fdisk.c	2015-07-03 10:30:50.378965526 +0200
+--- util-linux-2.23.2/fdisks/fdisk.c.kzak	2015-07-02 12:37:24.465906322 +0200
++++ util-linux-2.23.2/fdisks/fdisk.c	2015-07-02 12:37:57.870673753 +0200
 @@ -34,6 +34,7 @@
  #include "canonicalize.h"
  #include "strutils.h"
@@ -10,11 +10,11 @@ diff -up util-linux-2.23.2/fdisks/fdisk.c.kzak util-linux-2.23.2/fdisks/fdisk.c
  #include "fdisksunlabel.h"
  #include "fdisksgilabel.h"
 diff -up util-linux-2.23.2/include/sysfs.h.kzak util-linux-2.23.2/include/sysfs.h
---- util-linux-2.23.2/include/sysfs.h.kzak	2013-06-13 09:46:10.400650451 +0200
-+++ util-linux-2.23.2/include/sysfs.h	2015-07-03 10:30:50.378965526 +0200
-@@ -73,6 +73,8 @@ extern int sysfs_is_partition_dirent(DIR
- extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
+--- util-linux-2.23.2/include/sysfs.h.kzak	2015-07-02 12:12:50.408196320 +0200
++++ util-linux-2.23.2/include/sysfs.h	2015-07-02 12:13:09.708061372 +0200
+@@ -74,6 +74,8 @@ extern int sysfs_devno_to_wholedisk(dev_
              size_t len, dev_t *diskdevno);
+ extern int sysfs_devno_is_wholedisk(dev_t devno);
  
 +extern int sysfs_devno_is_lvm_private(dev_t devno);
 +
@@ -22,8 +22,8 @@ diff -up util-linux-2.23.2/include/sysfs.h.kzak util-linux-2.23.2/include/sysfs.
  			       int *c, int *t, int *l);
  extern char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt,
 diff -up util-linux-2.23.2/libblkid/src/blkidP.h.kzak util-linux-2.23.2/libblkid/src/blkidP.h
---- util-linux-2.23.2/libblkid/src/blkidP.h.kzak	2015-07-03 10:29:08.582688645 +0200
-+++ util-linux-2.23.2/libblkid/src/blkidP.h	2015-07-03 10:30:50.378965526 +0200
+--- util-linux-2.23.2/libblkid/src/blkidP.h.kzak	2015-07-02 12:18:27.349840375 +0200
++++ util-linux-2.23.2/libblkid/src/blkidP.h	2015-07-02 12:19:07.797557558 +0200
 @@ -221,6 +221,7 @@ struct blkid_struct_probe
  #define BLKID_FL_PRIVATE_FD	(1 << 1)	/* see blkid_new_probe_from_filename() */
  #define BLKID_FL_TINY_DEV	(1 << 2)	/* <= 1.47MiB (floppy or so) */
@@ -33,8 +33,8 @@ diff -up util-linux-2.23.2/libblkid/src/blkidP.h.kzak util-linux-2.23.2/libblkid
  /* private per-probing flags */
  #define BLKID_PROBE_FL_IGNORE_PT (1 << 1)	/* ignore partition table */
 diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak util-linux-2.23.2/libblkid/src/partitions/partitions.c
---- util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak	2015-07-03 10:29:08.582688645 +0200
-+++ util-linux-2.23.2/libblkid/src/partitions/partitions.c	2015-07-03 10:30:50.378965526 +0200
+--- util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak	2015-07-02 12:19:11.669530485 +0200
++++ util-linux-2.23.2/libblkid/src/partitions/partitions.c	2015-07-02 12:28:24.166667964 +0200
 @@ -537,6 +537,8 @@ static int idinfo_probe(blkid_probe pr,
  
  	if (pr->size <= 0 || (id->minsz && id->minsz > pr->size))
@@ -96,8 +96,8 @@ diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak util-linux-
  	if (!prc)
  		goto done;
 diff -up util-linux-2.23.2/libblkid/src/probe.c.kzak util-linux-2.23.2/libblkid/src/probe.c
---- util-linux-2.23.2/libblkid/src/probe.c.kzak	2015-07-03 10:29:08.583688638 +0200
-+++ util-linux-2.23.2/libblkid/src/probe.c	2015-07-03 10:30:50.378965526 +0200
+--- util-linux-2.23.2/libblkid/src/probe.c.kzak	2015-07-02 12:13:48.823787869 +0200
++++ util-linux-2.23.2/libblkid/src/probe.c	2015-07-02 12:38:20.110518915 +0200
 @@ -110,6 +110,7 @@
  
  #include "blkidP.h"
@@ -150,9 +150,9 @@ diff -up util-linux-2.23.2/libblkid/src/probe.c.kzak util-linux-2.23.2/libblkid/
  	blkid_probe_start(pr);
  
 diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c
---- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak	2015-07-03 10:29:08.586688617 +0200
-+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c	2015-07-03 10:30:50.378965526 +0200
-@@ -335,6 +335,9 @@ static int superblocks_probe(blkid_probe
+--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak	2015-07-02 12:29:32.370193121 +0200
++++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c	2015-07-02 12:31:06.897535008 +0200
+@@ -338,6 +338,9 @@ static int superblocks_probe(blkid_probe
  
  	if (!pr || chn->idx < -1)
  		return -EINVAL;
@@ -162,7 +162,7 @@ diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linu
  	blkid_probe_chain_reset_vals(pr, chn);
  
  	DBG(LOWPROBE, blkid_debug("--> starting probing loop [SUBLKS idx=%d]",
-@@ -450,6 +453,9 @@ static int superblocks_safeprobe(blkid_p
+@@ -453,6 +456,9 @@ static int superblocks_safeprobe(blkid_p
  	int intol = 0;
  	int rc;
  
@@ -173,8 +173,8 @@ diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linu
  
  		if (blkid_probe_is_tiny(pr) && !count)
 diff -up util-linux-2.23.2/libblkid/src/verify.c.kzak util-linux-2.23.2/libblkid/src/verify.c
---- util-linux-2.23.2/libblkid/src/verify.c.kzak	2013-06-13 09:46:10.429650699 +0200
-+++ util-linux-2.23.2/libblkid/src/verify.c	2015-07-03 10:30:50.378965526 +0200
+--- util-linux-2.23.2/libblkid/src/verify.c.kzak	2015-07-02 12:15:51.782928121 +0200
++++ util-linux-2.23.2/libblkid/src/verify.c	2015-07-02 12:16:45.078555470 +0200
 @@ -112,6 +112,10 @@ blkid_dev blkid_verify(blkid_cache cache
  		   (unsigned long)diff));
  #endif
@@ -187,13 +187,12 @@ diff -up util-linux-2.23.2/libblkid/src/verify.c.kzak util-linux-2.23.2/libblkid
  		cache->probe = blkid_new_probe();
  		if (!cache->probe) {
 diff -up util-linux-2.23.2/lib/sysfs.c.kzak util-linux-2.23.2/lib/sysfs.c
---- util-linux-2.23.2/lib/sysfs.c.kzak	2013-06-13 09:46:10.410650536 +0200
-+++ util-linux-2.23.2/lib/sysfs.c	2015-07-03 10:32:32.953236879 +0200
-@@ -638,6 +638,35 @@ err:
-     return -1;
+--- util-linux-2.23.2/lib/sysfs.c.kzak	2015-07-02 12:12:29.193344657 +0200
++++ util-linux-2.23.2/lib/sysfs.c	2015-07-02 12:12:13.565453930 +0200
+@@ -639,6 +639,35 @@ err:
  }
  
-+/*
+ /*
 + * Returns 1 if the device is private LVM device.
 + */
 +int sysfs_devno_is_lvm_private(dev_t devno)
@@ -222,6 +221,17 @@ diff -up util-linux-2.23.2/lib/sysfs.c.kzak util-linux-2.23.2/lib/sysfs.c
 +	return rc;
 +}
 +
++/*
+  * Return 0 or 1, or < 0 in case of error
+  */
+ int sysfs_devno_is_wholedisk(dev_t devno)
+@@ -651,6 +680,9 @@ int sysfs_devno_is_wholedisk(dev_t devno
+ 	return devno == disk;
+ }
  
++
++
++
  int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, int *c, int *t, int *l)
  {
+ 	char buf[PATH_MAX], *hctl;
diff --git a/SOURCES/2.25-libblkid-xfs-log.patch b/SOURCES/2.25-libblkid-xfs-log.patch
new file mode 100644
index 0000000..41f1ec8
--- /dev/null
+++ b/SOURCES/2.25-libblkid-xfs-log.patch
@@ -0,0 +1,133 @@
+diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c
+--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak	2015-06-24 12:58:20.790115492 +0200
++++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c	2015-06-24 12:57:57.961286166 +0200
+@@ -49,6 +49,8 @@
+  *
+  * @UUID_SUB: subvolume uuid (e.g. btrfs)
+  *
++ * @LOGUUID: external log UUID (e.g. xfs)
++ *
+  * @UUID_RAW: raw UUID from FS superblock
+  *
+  * @EXT_JOURNAL: external journal UUID
+@@ -113,6 +115,7 @@ static const struct blkid_idinfo *idinfo
+ 	&swsuspend_idinfo,
+ 	&swap_idinfo,
+ 	&xfs_idinfo,
++	&xfs_log_idinfo,
+ 	&ext4dev_idinfo,
+ 	&ext4_idinfo,
+ 	&ext3_idinfo,
+diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.h.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.h
+--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.h.kzak	2015-06-24 12:58:48.533908071 +0200
++++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.h	2015-06-24 12:59:00.098821476 +0200
+@@ -29,6 +29,7 @@ extern const struct blkid_idinfo ext2_id
+ extern const struct blkid_idinfo jbd_idinfo;
+ extern const struct blkid_idinfo jfs_idinfo;
+ extern const struct blkid_idinfo xfs_idinfo;
++extern const struct blkid_idinfo xfs_log_idinfo;
+ extern const struct blkid_idinfo gfs_idinfo;
+ extern const struct blkid_idinfo gfs2_idinfo;
+ extern const struct blkid_idinfo romfs_idinfo;
+diff -up util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak util-linux-2.23.2/libblkid/src/superblocks/xfs.c
+--- util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak	2015-06-24 12:39:34.300507071 +0200
++++ util-linux-2.23.2/libblkid/src/superblocks/xfs.c	2015-06-24 12:39:45.389427015 +0200
+@@ -4,6 +4,7 @@
+  * Copyright (C) 2001 by Andreas Dilger
+  * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+  * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
++ * Copyright (C) 2013 Eric Sandeen <sandeen@redhat.com>
+  *
+  * This file may be redistributed under the terms of the
+  * GNU Lesser General Public License.
+@@ -187,3 +188,90 @@ const struct blkid_idinfo xfs_idinfo =
+ 	}
+ };
+ 
++struct xlog_rec_header {
++	uint32_t	h_magicno;
++	uint32_t	h_dummy1[1];
++	uint32_t	h_version;
++	uint32_t	h_len;
++	uint32_t	h_dummy2[71];
++	uint32_t	h_fmt;
++	unsigned char	h_uuid[16];
++} __attribute__((packed));
++
++#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe
++
++/*
++ * For very small filesystems, the minimum log size
++ * can be smaller, but that seems vanishingly unlikely
++ * when used with an external log (which is used for
++ * performance reasons; tiny conflicts with that goal).
++ */
++#define XFS_MIN_LOG_BYTES	(10 * 1024 * 1024)
++
++#define XLOG_FMT_LINUX_LE	1
++#define XLOG_FMT_LINUX_BE	2
++#define XLOG_FMT_IRIX_BE	3
++
++#define XLOG_VERSION_1		1
++#define XLOG_VERSION_2		2	/* Large IClogs, Log sunit */
++#define XLOG_VERSION_OKBITS	(XLOG_VERSION_1 | XLOG_VERSION_2)
++
++static int xlog_valid_rec_header(struct xlog_rec_header *rhead)
++{
++	uint32_t hlen;
++
++	if (rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
++		return 0;
++
++	if (!rhead->h_version ||
++            (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS)))
++		return 0;
++
++	/* LR body must have data or it wouldn't have been written */
++	hlen = be32_to_cpu(rhead->h_len);
++	if (hlen <= 0 || hlen > INT_MAX)
++		return 0;
++
++	if (rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_LE) &&
++	    rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_BE) &&
++	    rhead->h_fmt != cpu_to_be32(XLOG_FMT_IRIX_BE))
++		return 0;
++
++	return 1;
++}
++
++/* xlog record header will be in some sector in the first 256k */
++static int probe_xfs_log(blkid_probe pr, const struct blkid_idmag *mag)
++{
++	int i;
++	struct xlog_rec_header *rhead;
++	unsigned char *buf;
++
++	buf = blkid_probe_get_buffer(pr, 0, 256*1024);
++	if (!buf)
++		return errno ? -errno : 1;
++
++	if (memcmp(buf, "XFSB", 4) == 0)
++		return 1;			/* this is regular XFS, ignore */
++
++	/* check the first 512 512-byte sectors */
++	for (i = 0; i < 512; i++) {
++		rhead = (struct xlog_rec_header *)&buf[i*512];
++
++		if (xlog_valid_rec_header(rhead)) {
++			blkid_probe_set_uuid_as(pr, rhead->h_uuid, "LOGUUID");
++			return 0;
++		}
++	}
++
++	return 1;
++}
++
++const struct blkid_idinfo xfs_log_idinfo =
++{
++	.name		= "xfs_external_log",
++	.usage		= BLKID_USAGE_OTHER,
++	.probefunc	= probe_xfs_log,
++	.magics		= BLKID_NONE_MAGIC,
++	.minsz		= XFS_MIN_LOG_BYTES,
++};
diff --git a/SOURCES/2.25-mount-man-default.patch b/SOURCES/2.25-mount-man-default.patch
new file mode 100644
index 0000000..f137025
--- /dev/null
+++ b/SOURCES/2.25-mount-man-default.patch
@@ -0,0 +1,27 @@
+diff -up util-linux-2.23.2/sys-utils/mount.8.kzak util-linux-2.23.2/sys-utils/mount.8
+--- util-linux-2.23.2/sys-utils/mount.8.kzak	2015-06-24 10:44:54.888929869 +0200
++++ util-linux-2.23.2/sys-utils/mount.8	2015-06-24 10:48:10.022436703 +0200
+@@ -865,9 +865,10 @@ Some of these options are only useful wh
+ .I /etc/fstab
+ file.
+ 
+-Some of these options could be enabled or disabled by default
+-in the system kernel. To check the current setting see the options
+-in /proc/mounts.
++Some of these  options  could be enabled or disabled by default in the system
++kernel.  To check the current setting see the options in /proc/mounts.  Note
++that filesystems also have per-filesystem specific default mount options (see
++for example tune2fs -l output for extN filesystems).
+ 
+ The following options apply to any filesystem that is being
+ mounted (but not every filesystem actually honors them - e.g., the
+@@ -973,6 +974,9 @@ For more details, see
+ .B defaults
+ Use default options:
+ .BR rw ", " suid ", " dev ", " exec ", " auto ", " nouser ", and " async.
++
++Note that the real set of the all default mount options depends on kernel
++and filesystem type. See the begin of this section for more details.
+ .TP
+ .B dev
+ Interpret character or block special devices on the filesystem.
diff --git a/SOURCES/2.26-libblkid-fat.patch b/SOURCES/2.26-libblkid-fat.patch
new file mode 100644
index 0000000..f6f87ad
--- /dev/null
+++ b/SOURCES/2.26-libblkid-fat.patch
@@ -0,0 +1,113 @@
+diff -up util-linux-2.23.2/libblkid/src/partitions/dos.c.kzak util-linux-2.23.2/libblkid/src/partitions/dos.c
+--- util-linux-2.23.2/libblkid/src/partitions/dos.c.kzak	2015-08-21 10:16:45.244332027 +0200
++++ util-linux-2.23.2/libblkid/src/partitions/dos.c	2015-08-21 10:22:07.181340367 +0200
+@@ -151,16 +151,6 @@ static int probe_dos_pt(blkid_probe pr,
+ 	if (memcmp(data, BLKID_AIX_MAGIC_STRING, BLKID_AIX_MAGIC_STRLEN) == 0)
+ 		goto nothing;
+ 
+-	/*
+-	 * Now that the 55aa signature is present, this is probably
+-	 * either the boot sector of a FAT filesystem or a DOS-type
+-	 * partition table.
+-	 */
+-	if (blkid_probe_is_vfat(pr) == 1) {
+-		DBG(LOWPROBE, blkid_debug("probably FAT -- ignore"));
+-		goto nothing;
+-	}
+-
+ 	p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
+ 
+ 	/*
+@@ -182,6 +172,16 @@ static int probe_dos_pt(blkid_probe pr,
+ 		}
+ 	}
+ 
++	/*
++	 * Now that the 55aa signature is present, this is probably
++	 * either the boot sector of a FAT filesystem or a DOS-type
++	 * partition table.
++	 */
++	if (blkid_probe_is_vfat(pr) == 1) {
++		DBG(LOWPROBE, blkid_debug("probably FAT -- ignore"));
++		goto nothing;
++	}
++
+ 	blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET,
+ 				  512 - BLKID_MSDOS_PT_OFFSET);
+ 
+diff -up util-linux-2.23.2/libblkid/src/partitions/dos.h.kzak util-linux-2.23.2/libblkid/src/partitions/dos.h
+--- util-linux-2.23.2/libblkid/src/partitions/dos.h.kzak	2015-08-21 10:34:14.919380422 +0200
++++ util-linux-2.23.2/libblkid/src/partitions/dos.h	2015-08-21 10:35:45.221807669 +0200
+@@ -12,6 +12,12 @@ struct dos_partition {
+ 
+ #define BLKID_MSDOS_PT_OFFSET		0x1be
+ 
++static inline struct dos_partition *mbr_get_partition(unsigned char *mbr, int i)
++{
++	return (struct dos_partition *)
++		(mbr + BLKID_MSDOS_PT_OFFSET + (i * sizeof(struct dos_partition)));
++}
++
+ /* assemble badly aligned little endian integer */
+ static inline unsigned int assemble4le(const unsigned char *p)
+ {
+diff -up util-linux-2.23.2/libblkid/src/superblocks/vfat.c.kzak util-linux-2.23.2/libblkid/src/superblocks/vfat.c
+--- util-linux-2.23.2/libblkid/src/superblocks/vfat.c.kzak	2015-08-21 10:10:12.111906711 +0200
++++ util-linux-2.23.2/libblkid/src/superblocks/vfat.c	2015-08-21 10:35:07.733045452 +0200
+@@ -16,6 +16,7 @@
+ #include <ctype.h>
+ #include <stdint.h>
+ 
++#include "partitions/dos.h"
+ #include "superblocks.h"
+ 
+ /* Yucky misaligned values */
+@@ -169,7 +170,8 @@ static unsigned char *search_fat_label(b
+ 	return NULL;
+ }
+ 
+-static int fat_valid_superblock(const struct blkid_idmag *mag,
++static int fat_valid_superblock(blkid_probe pr,
++			const struct blkid_idmag *mag,
+ 			struct msdos_super_block *ms,
+ 			struct vfat_super_block *vs,
+ 			uint32_t *cluster_count, uint32_t *fat_size)
+@@ -243,6 +245,20 @@ static int fat_valid_superblock(const st
+ 	if (cluster_count)
+ 		*cluster_count = __cluster_count;
+ 
++	if (blkid_probe_is_wholedisk(pr)) {
++		/* OK, seems like FAT, but it's possible that we found boot
++		 * sector with crazy FAT-like stuff (magic strings, media,
++		 * etc..) before MBR. Let's make sure that there is no MBR with
++		 * usable partition. */
++		unsigned char *buf = (unsigned char *) ms;
++		if (is_valid_mbr_signature(buf)) {
++			struct dos_partition *p0 = mbr_get_partition(buf, 0);
++			if (dos_partition_size(p0) != 0 &&
++			    (p0->boot_ind == 0 || p0->boot_ind == 0x80))
++				return 0;
++		}
++	}
++
+ 	return 1;	/* valid */
+ }
+ 
+@@ -270,7 +286,7 @@ int blkid_probe_is_vfat(blkid_probe pr)
+ 	if (!vs)
+ 		return errno ? -errno : 0;
+ 
+-	return fat_valid_superblock(mag, ms, vs, NULL, NULL);
++	return fat_valid_superblock(pr, mag, ms, vs, NULL, NULL);
+ }
+ 
+ /* FAT label extraction from the root directory taken from Kay
+@@ -293,7 +309,7 @@ static int probe_vfat(blkid_probe pr, co
+ 	if (!vs)
+ 		return errno ? -errno : 1;
+ 
+-	if (!fat_valid_superblock(mag, ms, vs, &cluster_count, &fat_size))
++	if (!fat_valid_superblock(pr, mag, ms, vs, &cluster_count, &fat_size))
+ 		return 1;
+ 
+ 	sector_size = unaligned_le16(&ms->ms_sector_size);
diff --git a/SOURCES/2.26-logger-man-kern.patch b/SOURCES/2.26-logger-man-kern.patch
new file mode 100644
index 0000000..b7b9434
--- /dev/null
+++ b/SOURCES/2.26-logger-man-kern.patch
@@ -0,0 +1,72 @@
+diff -up util-linux-2.23.2/misc-utils/logger.1.kzak util-linux-2.23.2/misc-utils/logger.1
+--- util-linux-2.23.2/misc-utils/logger.1.kzak	2015-06-24 12:18:23.938735038 +0200
++++ util-linux-2.23.2/misc-utils/logger.1	2015-06-24 12:18:33.154667053 +0200
+@@ -125,28 +125,49 @@ flag is not provided, standard input is
+ The
+ .B logger
+ utility exits 0 on success, and >0 if an error occurs.
+-.PP
++.SH FACILITIES AND LEVELS
+ Valid facility names are:
+-.IR auth , \ authpriv
+-(for security information of a sensitive nature),
+-.IR cron , \ daemon , \ ftp , \ kern
+-(can't be generated from user process),
+-.IR lpr , \ mail , \ news , \ security
+-(deprecated synonym for
+-.IR auth ), \ syslog , \ user , \ uucp ,
+-and
+-.IR local0 \ to \ local7 ,
+-inclusive.
++.IP
++.TS
++tab(:);
++left l l.
++\fBauth
++\fBauthpriv\fR:for security information of a sensitive nature
++\fBcron
++\fBdaemon
++\fBftp
++\fBkern\fR:cannot be generated from userspace process, automatically converted to \fBuser
++\fBlpr
++\fBmail
++\fBnews
++\fBsyslog
++\fBuser
++\fBuucp
++\fBlocal0
++  to:
++\fBlocal7
++\fBsecurity\fR:deprecated synonym for \fBauth
++.TE
+ .PP
+ Valid level names are:
+-.IR alert , \ crit , \ debug , \ emerg , \ err , \ error
+-(deprecated synonym for
+-.IR err ), \ info , \ notice , \ panic
+-(deprecated synonym for
+-.IR  emerg ), \ warning , \ warn
+-(deprecated synonym for
+-.IR warning ).
+-For the priority order and intended purposes of these levels, see
++.IP
++.TS
++tab(:);
++left l l.
++\fBemerg
++\fBalert
++\fBcrit
++\fBerr
++\fBwarning
++\fBnotice
++\fBinfo
++\fBdebug
++\fBpanic\fR:deprecated synonym for \fBemerg
++\fBerror\fR:deprecated synonym for \fBerr
++\fBwarn\fR:deprecated synonym for \fBwarning
++.TE
++.PP
++For the priority order and intended purposes of these facilities and levels, see
+ .BR syslog (3).
+ .SH EXAMPLES
+ logger System rebooted
diff --git a/SOURCES/2.26-login-SIGXFSZ.patch b/SOURCES/2.26-login-SIGXFSZ.patch
new file mode 100644
index 0000000..0f49c9a
--- /dev/null
+++ b/SOURCES/2.26-login-SIGXFSZ.patch
@@ -0,0 +1,39 @@
+diff -up util-linux-2.23.2/login-utils/login.c.kzak util-linux-2.23.2/login-utils/login.c
+--- util-linux-2.23.2/login-utils/login.c.kzak	2015-06-24 11:03:45.123285155 +0200
++++ util-linux-2.23.2/login-utils/login.c	2015-06-24 11:46:19.168114438 +0200
+@@ -495,6 +495,7 @@ static void log_audit(struct login_conte
+ 
+ static void log_lastlog(struct login_context *cxt)
+ {
++	struct sigaction sa, oldsa_xfsz;
+ 	struct lastlog ll;
+ 	time_t t;
+ 	int fd;
+@@ -502,9 +503,14 @@ static void log_lastlog(struct login_con
+ 	if (!cxt->pwd)
+ 		return;
+ 
++	/* lastlog is huge on systems with large UIDs, ignore SIGXFSZ */
++	memset(&sa, 0, sizeof(sa));
++	sa.sa_handler = SIG_IGN;
++	sigaction(SIGXFSZ, &sa, &oldsa_xfsz);
++
+ 	fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0);
+ 	if (fd < 0)
+-		return;
++		goto done;
+ 
+ 	if (lseek(fd, (off_t) cxt->pwd->pw_uid * sizeof(ll), SEEK_SET) == -1)
+ 		goto done;
+@@ -542,7 +548,10 @@ static void log_lastlog(struct login_con
+ 	if (write_all(fd, (char *)&ll, sizeof(ll)))
+ 		warn(_("write lastlog failed"));
+ done:
+-	close(fd);
++	if (fd >= 0)
++		close(fd);
++
++	sigaction(SIGXFSZ, &oldsa_xfsz, NULL);		/* restore original setting */
+ }
+ 
+ /*
diff --git a/SOURCES/2.26-lsblk-mpath.patch b/SOURCES/2.26-lsblk-mpath.patch
new file mode 100644
index 0000000..1e7fae2
--- /dev/null
+++ b/SOURCES/2.26-lsblk-mpath.patch
@@ -0,0 +1,64 @@
+diff -up util-linux-2.23.2/misc-utils/lsblk.c.kzak util-linux-2.23.2/misc-utils/lsblk.c
+--- util-linux-2.23.2/misc-utils/lsblk.c.kzak	2015-06-25 11:01:10.543344225 +0200
++++ util-linux-2.23.2/misc-utils/lsblk.c	2015-06-25 11:14:17.085404974 +0200
+@@ -953,11 +953,13 @@ static void set_tt_data(struct blkdev_cx
+ 	};
+ }
+ 
+-static void print_device(struct blkdev_cxt *cxt, struct tt_line *tt_parent)
++static void fill_table_line(struct blkdev_cxt *cxt, struct tt_line *tt_parent)
+ {
+ 	int i;
+ 
+ 	cxt->tt_line = tt_add_line(lsblk->tt, tt_parent);
++	if (!cxt->tt_line)
++		return;
+ 
+ 	for (i = 0; i < ncolumns; i++)
+ 		set_tt_data(cxt, i, get_column_id(i), cxt->tt_line);
+@@ -1084,7 +1086,7 @@ static int list_partitions(struct blkdev
+ 				goto next;
+ 
+ 			wholedisk_cxt->parent = &part_cxt;
+-			print_device(&part_cxt, parent_cxt ? parent_cxt->tt_line : NULL);
++			fill_table_line(&part_cxt, parent_cxt ? parent_cxt->tt_line : NULL);
+ 			if (!lsblk->nodeps)
+ 				process_blkdev(wholedisk_cxt, &part_cxt, 0, NULL);
+ 		} else {
+@@ -1098,7 +1100,7 @@ static int list_partitions(struct blkdev
+ 
+ 			/* Print whole disk only once */
+ 			if (r)
+-				print_device(wholedisk_cxt, parent_cxt ? parent_cxt->tt_line : NULL);
++				fill_table_line(wholedisk_cxt, parent_cxt ? parent_cxt->tt_line : NULL);
+ 			if (ps == 0 && !lsblk->nodeps)
+ 				process_blkdev(&part_cxt, wholedisk_cxt, 0, NULL);
+ 		}
+@@ -1171,9 +1173,11 @@ static int list_deps(struct blkdev_cxt *
+ 			    process_blkdev(&dep, cxt, 1, d->d_name);
+ 		}
+ 		/* The dependency is a whole device. */
+-		else if (!set_cxt(&dep, cxt, NULL, d->d_name))
+-			process_blkdev(&dep, cxt, 1, NULL);
+-
++		else if (!set_cxt(&dep, cxt, NULL, d->d_name)) {
++			/* For inverse tree we don't want to show partitions
++			 * if the dependence is pn whle-disk */
++			process_blkdev(&dep, cxt, lsblk->inverse ? 0 : 1, NULL); 
++		}
+ 		reset_blkdev_cxt(&dep);
+ 	}
+ 	closedir(dir);
+@@ -1185,9 +1189,10 @@ static int process_blkdev(struct blkdev_
+ 			  int do_partitions, const char *part_name)
+ {
+ 	if (do_partitions && cxt->npartitions)
+-		return list_partitions(cxt, parent, part_name);
++		list_partitions(cxt, parent, part_name);                /* partitoins + whole-disk */
++	else
++		fill_table_line(cxt, parent ? parent->tt_line : NULL); /* whole-disk only */
+ 
+-	print_device(cxt, parent ? parent->tt_line : NULL);
+ 	return list_deps(cxt);
+ }
+ 
diff --git a/SOURCES/2.26-su-coredump-message.patch b/SOURCES/2.26-su-coredump-message.patch
new file mode 100644
index 0000000..8d2b9ba
--- /dev/null
+++ b/SOURCES/2.26-su-coredump-message.patch
@@ -0,0 +1,17 @@
+diff -up util-linux-2.23.2/login-utils/su-common.c.kzak util-linux-2.23.2/login-utils/su-common.c
+--- util-linux-2.23.2/login-utils/su-common.c.kzak	2015-06-24 11:14:25.102395082 +0200
++++ util-linux-2.23.2/login-utils/su-common.c	2015-06-24 11:22:20.472859684 +0200
+@@ -359,10 +359,9 @@ create_watching_parent (void)
+       if (pid != (pid_t)-1)
+ 	if (WIFSIGNALED (status))
+ 	  {
+-	    status = WTERMSIG (status) + 128;
+-	    if (WCOREDUMP (status))
+-	      fprintf (stderr, _("%s (core dumped)\n"),
+-                 strsignal (WTERMSIG (status)));
++            fprintf (stderr, "%s%s\n", strsignal (WTERMSIG (status)),
++                     WCOREDUMP (status) ? _(" (core dumped)") : "");
++            status = WTERMSIG (status) + 128;
+ 	  }
+ 	else
+ 	  status = WEXITSTATUS (status);
diff --git a/SOURCES/2.26-unshare-rebase.patch b/SOURCES/2.26-unshare-rebase.patch
new file mode 100644
index 0000000..672ff36
--- /dev/null
+++ b/SOURCES/2.26-unshare-rebase.patch
@@ -0,0 +1,757 @@
+diff -up util-linux-2.23.2/include/pathnames.h.kzak util-linux-2.23.2/include/pathnames.h
+--- util-linux-2.23.2/include/pathnames.h.kzak	2015-06-26 10:00:19.111877564 +0200
++++ util-linux-2.23.2/include/pathnames.h	2015-06-26 10:00:51.623630869 +0200
+@@ -85,6 +85,10 @@
+ #define _PATH_PROC_LOCKS        "/proc/locks"
+ #define _PATH_PROC_CDROMINFO	"/proc/sys/dev/cdrom/info"
+ 
++#define _PATH_PROC_UIDMAP	"/proc/self/uid_map"
++#define _PATH_PROC_GIDMAP	"/proc/self/gid_map"
++#define _PATH_PROC_SETGROUPS	"/proc/self/setgroups"
++
+ #define _PATH_PROC_ATTR_CURRENT	"/proc/self/attr/current"
+ #define _PATH_PROC_ATTR_EXEC	"/proc/self/attr/exec"
+ #define _PATH_PROC_CAPLASTCAP	"/proc/sys/kernel/cap_last_cap"
+diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am
+diff -up util-linux-2.23.2/sys-utils/nsenter.1.kzak util-linux-2.23.2/sys-utils/nsenter.1
+--- util-linux-2.23.2/sys-utils/nsenter.1.kzak	2015-06-26 09:58:39.468633643 +0200
++++ util-linux-2.23.2/sys-utils/nsenter.1	2015-06-26 09:58:51.672541041 +0200
+@@ -1,44 +1,45 @@
+-.TH NSENTER 1 "January 2013" "util-linux" "User Commands"
++.TH NSENTER 1 "June 2013" "util-linux" "User Commands"
+ .SH NAME
+ nsenter \- run program with namespaces of other processes
+ .SH SYNOPSIS
+ .B nsenter
+-.RI [ options ]
+-.RI [ program ]
+-.RI [ arguments ]
++[options]
++.RI [ program
++.RI [ arguments ]]
+ .SH DESCRIPTION
+ Enters the namespaces of one or more other processes and then executes the specified
+ program.  Enterable namespaces are:
+ .TP
+ .B mount namespace
+-mounting and unmounting filesystems will not affect rest of the system
++Mounting and unmounting filesystems will not affect the rest of the system
+ .RB ( CLONE_\:NEWNS
+-flag), except for filesystems which are explicitly marked as shared (by mount
+---make-\:shared).  See /proc\:/self\:/mountinfo for the shared flag.
++flag), except for filesystems which are explicitly marked as shared (with
++\fBmount --make-\:shared\fP; see \fI/proc\:/self\:/mountinfo\fP for the
++\fBshared\fP flag).
+ .TP
+ .B UTS namespace
+-setting hostname, domainname will not affect rest of the system
++Setting hostname or domainname will not affect the rest of the system.
+ .RB ( CLONE_\:NEWUTS
+-flag).
++flag)
+ .TP
+ .B IPC namespace
+-process will have independent namespace for System V message queues, semaphore
+-sets and shared memory segments
++The process will have an independent namespace for System V message queues,
++semaphore sets and shared memory segments.
+ .RB ( CLONE_\:NEWIPC
+-flag).
++flag)
+ .TP
+ .B network namespace
+-process will have independent IPv4 and IPv6 stacks, IP routing tables, firewall
+-rules, the
++The process will have independent IPv4 and IPv6 stacks, IP routing tables,
++firewall rules, the
+ .I /proc\:/net
+ and
+ .I /sys\:/class\:/net
+-directory trees, sockets etc.
++directory trees, sockets, etc.
+ .RB ( CLONE_\:NEWNET
+-flag).
++flag)
+ .TP
+ .B PID namespace
+-children will have a set of PID to process mappings separate from the
++Children will have a set of PID to process mappings separate from the
+ .B nsenter
+ process
+ .RB ( CLONE_\:NEWPID
+@@ -46,18 +47,18 @@ flag).
+ .B nsenter
+ will fork by default if changing the PID namespace, so that the new program
+ and its children share the same PID namespace and are visible to each other.
+-If \-\-no\-fork is used, the new program will be exec'ed without forking.
+-.PP
+-See the
+-.BR clone (2)
+-for exact semantics of the flags.
++If \fB\-\-no\-fork\fP is used, the new program will be exec'ed without forking.
+ .TP
+-If program is not given, run ``${SHELL}'' (default: /bin\:/sh).
++.B user namespace
++The process will have a distinct set of UIDs, GIDs and capabilities.
++.RB ( CLONE_\:NEWUSER
++flag)
++.TP
++See \fBclone\fP(2) for the exact semantics of the flags.
++.TP
++If \fIprogram\fP is not given, then ``${SHELL}'' is run (default: /bin\:/sh).
+ 
+ .SH OPTIONS
+-Argument with square brakets, such as [\fIfile\fR], means optional argument.
+-Command line syntax to specify optional argument \-\-mount=/path\:/to\:/file.
+-Please notice the equals sign.
+ .TP
+ \fB\-t\fR, \fB\-\-target\fR \fIpid\fP
+ Specify a target process to get contexts from.  The paths to the contexts
+@@ -83,6 +84,9 @@ the network namespace
+ /proc/\fIpid\fR/ns/pid
+ the PID namespace
+ .TP
++/proc/\fIpid\fR/ns/user
++the user namespace
++.TP
+ /proc/\fIpid\fR/root
+ the root directory
+ .TP
+@@ -91,51 +95,71 @@ the working directory respectively
+ .PD
+ .RE
+ .TP
+-\fB\-m\fR, \fB\-\-mount\fR [\fIfile\fR]
+-Enter the mount namespace.  If no file is specified enter the mount namespace
+-of the target process.  If file is specified enter the mount namespace
++\fB\-m\fR, \fB\-\-mount\fR[=\fIfile\fR]
++Enter the mount namespace.  If no file is specified, enter the mount namespace
++of the target process.  If file is specified, enter the mount namespace
+ specified by file.
+ .TP
+-\fB\-u\fR, \fB\-\-uts\fR [\fIfile\fR]
+-Enter the UTS namespace.  If no file is specified enter the UTS namespace of
+-the target process.  If file is specified enter the UTS namespace specified by
++\fB\-u\fR, \fB\-\-uts\fR[=\fIfile\fR]
++Enter the UTS namespace.  If no file is specified, enter the UTS namespace of
++the target process.  If file is specified, enter the UTS namespace specified by
+ file.
+ .TP
+-\fB\-i\fR, \fB\-\-ipc\fR [\fIfile\fR]
+-Enter the IPC namespace.  If no file is specified enter the IPC namespace of
+-the target process.  If file is specified enter the IPC namespace specified by
++\fB\-i\fR, \fB\-\-ipc\fR[=\fIfile\fR]
++Enter the IPC namespace.  If no file is specified, enter the IPC namespace of
++the target process.  If file is specified, enter the IPC namespace specified by
+ file.
+ .TP
+-\fB\-n\fR, \fB\-\-net\fR [\fIfile\fR]
+-Enter the network namespace.  If no file is specified enter the network
+-namespace of the target process.  If file is specified enter the network
++\fB\-n\fR, \fB\-\-net\fR[=\fIfile\fR]
++Enter the network namespace.  If no file is specified, enter the network
++namespace of the target process.  If file is specified, enter the network
+ namespace specified by file.
+ .TP
+-\fB\-p\fR, \fB\-\-pid\fR [\fIfile\fR]
+-Enter the PID namespace.  If no file is specified enter the PID namespace of
+-the target process.  If file is specified enter the PID namespace specified by
++\fB\-p\fR, \fB\-\-pid\fR[=\fIfile\fR]
++Enter the PID namespace.  If no file is specified, enter the PID namespace of
++the target process.  If file is specified, enter the PID namespace specified by
+ file.
+ .TP
+-\fB\-r\fR, \fB\-\-root\fR [\fIdirectory\fR]
+-Set the root directory.  If no directory is specified set the root directory to
+-the root directory of the target process.  If directory is specified set the
++\fB\-U\fR, \fB\-\-user\fR[=\fIfile\fR]
++Enter the user namespace.  If no file is specified, enter the user namespace of
++the target process.  If file is specified, enter the user namespace specified by
++file.  See also the \fB\-\-setuid\fR and \fB\-\-setgid\fR options.
++.TP
++\fB\-G\fR, \fB\-\-setgid\fR \fIgid\fR
++Set the group ID which will be used in the entered namespace and drop
++supplementary groups.
++.BR nsenter (1)
++always sets GID for user namespaces, the default is 0.
++.TP
++\fB\-S\fR, \fB\-\-setuid\fR \fIuid\fR
++Set the user ID which will be used in the entered namespace.
++.BR nsenter (1)
++always sets UID for user namespaces, the default is 0.
++.TP
++\fB\-\-preserve\-credentials\fR
++Don't modify UID and GID when enter user namespace. The default is to
++drops supplementary groups and sets GID and UID to 0.
++.TP
++\fB\-r\fR, \fB\-\-root\fR[=\fIdirectory\fR]
++Set the root directory.  If no directory is specified, set the root directory to
++the root directory of the target process.  If directory is specified, set the
+ root directory to the specified directory.
+ .TP
+-\fB\-w\fR, \fB\-\-wd\fR [\fIdirectory\fR]
+-Set the working directory.  If no directory is specified set the working
++\fB\-w\fR, \fB\-\-wd\fR[=\fIdirectory\fR]
++Set the working directory.  If no directory is specified, set the working
+ directory to the working directory of the target process.  If directory is
+-specified set the working directory to the specified directory.
++specified, set the working directory to the specified directory.
+ .TP
+-\fB\-F\fR, \fB\-\-no-fork\fR
+-Do not fork before exec'ing the specified program.  By default when entering a
+-pid namespace enter calls fork before calling exec so that the children will be
+-in the newly entered pid namespace.
++\fB\-F\fR, \fB\-\-no\-fork\fR
++Do not fork before exec'ing the specified program.  By default, when entering a
++PID namespace, \fBnsenter\fP calls \fBfork\fP before calling \fBexec\fP so that
++any children will also be in the newly entered PID namespace.
+ .TP
+ \fB\-V\fR, \fB\-\-version\fR
+ Display version information and exit.
+ .TP
+ \fB\-h\fR, \fB\-\-help\fR
+-Print a help message.
++Display help text and exit.
+ .SH SEE ALSO
+ .BR setns (2),
+ .BR clone (2)
+diff -up util-linux-2.23.2/sys-utils/nsenter.c.kzak util-linux-2.23.2/sys-utils/nsenter.c
+--- util-linux-2.23.2/sys-utils/nsenter.c.kzak	2015-06-26 09:58:39.468633643 +0200
++++ util-linux-2.23.2/sys-utils/nsenter.c	2015-06-26 09:58:51.673541033 +0200
+@@ -28,6 +28,7 @@
+ #include <assert.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
++#include <grp.h>
+ 
+ #include "strutils.h"
+ #include "nls.h"
+@@ -42,7 +43,12 @@ static struct namespace_file {
+ 	int fd;
+ } namespace_files[] = {
+ 	/* Careful the order is significant in this array.
++	 *
++	 * The user namespace comes first, so that it is entered
++	 * first.  This gives an unprivileged user the potential to
++	 * enter the other namespaces.
+ 	 */
++	{ .nstype = CLONE_NEWUSER, .name = "ns/user", .fd = -1 },
+ 	{ .nstype = CLONE_NEWIPC,  .name = "ns/ipc",  .fd = -1 },
+ 	{ .nstype = CLONE_NEWUTS,  .name = "ns/uts",  .fd = -1 },
+ 	{ .nstype = CLONE_NEWNET,  .name = "ns/net",  .fd = -1 },
+@@ -56,18 +62,25 @@ static void usage(int status)
+ 	FILE *out = status == EXIT_SUCCESS ? stdout : stderr;
+ 
+ 	fputs(USAGE_HEADER, out);
+-	fprintf(out, _(" %s [options] <program> [args...]\n"),
++	fprintf(out, _(" %s [options] <program> [<argument>...]\n"),
+ 		program_invocation_short_name);
+ 
++	fputs(USAGE_SEPARATOR, out);
++	fputs(_("Run a program with namespaces of other processes.\n"), out);
++
+ 	fputs(USAGE_OPTIONS, out);
+ 	fputs(_(" -t, --target <pid>     target process to get namespaces from\n"), out);
+-	fputs(_(" -m, --mount [=<file>]  enter mount namespace\n"), out);
+-	fputs(_(" -u, --uts   [=<file>]  enter UTS namespace (hostname etc)\n"), out);
+-	fputs(_(" -i, --ipc   [=<file>]  enter System V IPC namespace\n"), out);
+-	fputs(_(" -n, --net   [=<file>]  enter network namespace\n"), out);
+-	fputs(_(" -p, --pid   [=<file>]  enter pid namespace\n"), out);
+-	fputs(_(" -r, --root  [=<dir>]   set the root directory\n"), out);
+-	fputs(_(" -w, --wd    [=<dir>]   set the working directory\n"), out);
++	fputs(_(" -m, --mount[=<file>]   enter mount namespace\n"), out);
++	fputs(_(" -u, --uts[=<file>]     enter UTS namespace (hostname etc)\n"), out);
++	fputs(_(" -i, --ipc[=<file>]     enter System V IPC namespace\n"), out);
++	fputs(_(" -n, --net[=<file>]     enter network namespace\n"), out);
++	fputs(_(" -p, --pid[=<file>]     enter pid namespace\n"), out);
++	fputs(_(" -U, --user[=<file>]    enter user namespace\n"), out);
++	fputs(_(" -S, --setuid <uid>     set uid in entered namespace\n"), out);
++	fputs(_(" -G, --setgid <gid>     set gid in entered namespace\n"), out);
++	fputs(_("     --preserve-credentials do not touch uids or gids\n"), out);
++	fputs(_(" -r, --root[=<dir>]     set the root directory\n"), out);
++	fputs(_(" -w, --wd[=<dir>]       set the working directory\n"), out);
+ 	fputs(_(" -F, --no-fork          do not fork before exec'ing <program>\n"), out);
+ 
+ 	fputs(USAGE_SEPARATOR, out);
+@@ -153,6 +166,9 @@ static void continue_as_child(void)
+ 
+ int main(int argc, char *argv[])
+ {
++	enum {
++		OPT_PRESERVE_CRED = CHAR_MAX + 1
++	};
+ 	static const struct option longopts[] = {
+ 		{ "help", no_argument, NULL, 'h' },
+ 		{ "version", no_argument, NULL, 'V'},
+@@ -162,24 +178,30 @@ int main(int argc, char *argv[])
+ 		{ "ipc", optional_argument, NULL, 'i' },
+ 		{ "net", optional_argument, NULL, 'n' },
+ 		{ "pid", optional_argument, NULL, 'p' },
++		{ "user", optional_argument, NULL, 'U' },
++		{ "setuid", required_argument, NULL, 'S' },
++		{ "setgid", required_argument, NULL, 'G' },
+ 		{ "root", optional_argument, NULL, 'r' },
+ 		{ "wd", optional_argument, NULL, 'w' },
+ 		{ "no-fork", no_argument, NULL, 'F' },
++		{ "preserve-credentials", no_argument, NULL, OPT_PRESERVE_CRED },
+ 		{ NULL, 0, NULL, 0 }
+ 	};
+ 
+ 	struct namespace_file *nsfile;
+-	int c, namespaces = 0;
+-	bool do_rd = false, do_wd = false;
++	int c, namespaces = 0, setgroups_nerrs = 0, preserve_cred = 0;
++	bool do_rd = false, do_wd = false, force_uid = false, force_gid = false;
+ 	int do_fork = -1; /* unknown yet */
++	uid_t uid = 0;
++	gid_t gid = 0;
+ 
+-	setlocale(LC_MESSAGES, "");
++	setlocale(LC_ALL, "");
+ 	bindtextdomain(PACKAGE, LOCALEDIR);
+ 	textdomain(PACKAGE);
+ 	atexit(close_stdout);
+ 
+ 	while ((c =
+-		getopt_long(argc, argv, "hVt:m::u::i::n::p::r::w::F",
++		getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::F",
+ 			    longopts, NULL)) != -1) {
+ 		switch (c) {
+ 		case 'h':
+@@ -221,6 +243,20 @@ int main(int argc, char *argv[])
+ 			else
+ 				namespaces |= CLONE_NEWPID;
+ 			break;
++		case 'U':
++			if (optarg)
++				open_namespace_fd(CLONE_NEWUSER, optarg);
++			else
++				namespaces |= CLONE_NEWUSER;
++			break;
++		case 'S':
++			uid = strtoul_or_err(optarg, _("failed to parse uid"));
++			force_uid = true;
++			break;
++		case 'G':
++			gid = strtoul_or_err(optarg, _("failed to parse gid"));
++			force_gid = true;
++			break;
+ 		case 'F':
+ 			do_fork = 0;
+ 			break;
+@@ -236,6 +272,9 @@ int main(int argc, char *argv[])
+ 			else
+ 				do_wd = true;
+ 			break;
++		case OPT_PRESERVE_CRED:
++			preserve_cred = 1;
++			break;
+ 		default:
+ 			usage(EXIT_FAILURE);
+ 		}
+@@ -253,6 +292,26 @@ int main(int argc, char *argv[])
+ 		open_target_fd(&wd_fd, "cwd", NULL);
+ 
+ 	/*
++	 * Update namespaces variable to contain all requested namespaces
++	 */
++	for (nsfile = namespace_files; nsfile->nstype; nsfile++) {
++		if (nsfile->fd < 0)
++			continue;
++		namespaces |= nsfile->nstype;
++	}
++
++	/* for user namespaces we always set UID and GID (default is 0)
++	 * and clear root's groups if --preserve-credentials is no specified */
++	if ((namespaces & CLONE_NEWUSER) && !preserve_cred) {
++		force_uid = true, force_gid = true;
++
++		/* We call setgroups() before and after we enter user namespace,
++		 * let's complain only if both fail */
++		if (setgroups(0, NULL) != 0)
++			setgroups_nerrs++;
++	}
++
++	/*
+ 	 * Now that we know which namespaces we want to enter, enter them.
+ 	 */
+ 	for (nsfile = namespace_files; nsfile->nstype; nsfile++) {
+@@ -302,6 +361,15 @@ int main(int argc, char *argv[])
+ 	if (do_fork == 1)
+ 		continue_as_child();
+ 
++	if (force_uid || force_gid) {
++		if (force_gid && setgroups(0, NULL) != 0 && setgroups_nerrs)	/* drop supplementary groups */
++			err(EXIT_FAILURE, _("setgroups failed"));
++		if (force_gid && setgid(gid) < 0)		/* change GID */
++			err(EXIT_FAILURE, _("setgid failed"));
++		if (force_uid && setuid(uid) < 0)		/* change UID */
++			err(EXIT_FAILURE, _("setuid failed"));
++	}
++
+ 	if (optind < argc) {
+ 		execvp(argv[optind], argv + optind);
+ 		err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+diff -up util-linux-2.23.2/sys-utils/unshare.1.kzak util-linux-2.23.2/sys-utils/unshare.1
+--- util-linux-2.23.2/sys-utils/unshare.1.kzak	2015-06-26 09:58:39.484633521 +0200
++++ util-linux-2.23.2/sys-utils/unshare.1	2015-06-26 09:58:51.673541033 +0200
+@@ -1,28 +1,27 @@
+-.\" Process this file with
+-.\" groff -man -Tascii lscpu.1
+-.\"
+-.TH UNSHARE 1 "July 2013" "util-linux" "User Commands"
++.TH UNSHARE 1 "July 2014" "util-linux" "User Commands"
+ .SH NAME
+ unshare \- run program with some namespaces unshared from parent
+ .SH SYNOPSIS
+ .B unshare
+-.RI [ options ]
++[options]
+ .I program
+ .RI [ arguments ]
+ .SH DESCRIPTION
+ Unshares the indicated namespaces from the parent process and then executes
+-the specified program.  The namespaces to be unshared are indicated via
++the specified \fIprogram\fR.  The namespaces to be unshared are indicated via
+ options.  Unshareable namespaces are:
+ .TP
+ .BR "mount namespace"
+ Mounting and unmounting filesystems will not affect the rest of the system
+ (\fBCLONE_NEWNS\fP flag), except for filesystems which are explicitly marked as
+-shared (with \fBmount --make-shared\fP; see \fI/proc/self/mountinfo\fP for the
+-\fBshared\fP flags).
+-
+-It's recommended to use \fBmount --make-rprivate\fP or \fBmount --make-rslave\fP
+-after \fBunshare --mount\fP to make sure that mountpoints in the new namespace
+-are really unshared from parental namespace.
++shared (with \fBmount --make-shared\fP; see \fI/proc/self/mountinfo\fP or
++\fBfindmnt -o+PROPAGATION\fP for the \fBshared\fP flags).
++.sp
++.B unshare
++automatically sets propagation to \fBprivate\fP
++in the new mount namespace to make sure that the new namespace is really
++unshared. This feature is possible to disable by option \fB\-\-propagation unchanged\fP.
++Note that \fBprivate\fP is the kernel default.
+ .TP
+ .BR "UTS namespace"
+ Setting hostname or domainname will not affect the rest of the system.
+@@ -40,13 +39,14 @@ sockets, etc.  (\fBCLONE_NEWNET\fP flag)
+ .BR "pid namespace"
+ Children will have a distinct set of PID to process mappings from their parent.
+ (\fBCLONE_NEWPID\fP flag)
++.TP
++.BR "user namespace"
++The process will have a distinct set of UIDs, GIDs and capabilities.
++(\fBCLONE_NEWUSER\fP flag)
+ .PP
+ See \fBclone\fR(2) for the exact semantics of the flags.
+ .SH OPTIONS
+ .TP
+-.BR \-h , " \-\-help"
+-Display help text and exit.
+-.TP
+ .BR \-i , " \-\-ipc"
+ Unshare the IPC namespace.
+ .TP
+@@ -63,16 +63,68 @@ See also the \fB--fork\fP and \fB--mount
+ .BR \-u , " \-\-uts"
+ Unshare the UTS namespace.
+ .TP
++.BR \-U , " \-\-user"
++Unshare the user namespace.
++.TP
+ .BR \-f , " \-\-fork"
+ Fork the specified \fIprogram\fR as a child process of \fBunshare\fR rather than
+ running it directly.  This is useful when creating a new pid namespace.
+ .TP
+-.BR \-\-mount-proc "[=\fImountpoint\fP]"
+-Just before running the program, mount the proc filesystem at the \fImountpoint\fP
++.BR \-\-mount\-proc "[=\fImountpoint\fP]"
++Just before running the program, mount the proc filesystem at \fImountpoint\fP
+ (default is /proc).  This is useful when creating a new pid namespace.  It also
+ implies creating a new mount namespace since the /proc mount would otherwise
+-mess up existing programs on the system. The new proc filesystem is explicitly
++mess up existing programs on the system.  The new proc filesystem is explicitly
+ mounted as private (by MS_PRIVATE|MS_REC).
++.TP
++.BR \-r , " \-\-map\-root\-user"
++Run the program only after the current effective user and group IDs have been mapped to
++the superuser UID and GID in the newly created user namespace.  This makes it possible to
++conveniently gain capabilities needed to manage various aspects of the newly created
++namespaces (such as configuring interfaces in the network namespace or mounting filesystems in
++the mount namespace) even when run unprivileged.  As a mere convenience feature, it does not support
++more sophisticated use cases, such as mapping multiple ranges of UIDs and GIDs.
++This option implies --setgroups=deny.
++.TP
++.BR "\-\-propagation \fIprivate|shared|slave|unchanged\fP"
++Recursively sets mount propagation flag in the new mount namespace. The default
++is to set the propagation to \fIprivate\fP, this feature is possible to disable
++by \fIunchanged\fP argument. The options is silently ignored when mount namespace (\fB\-\-mount\fP)
++is not requested.
++.TP
++.BR "\-\-setgroups \fIallow|deny\fP"
++Allow or deny
++.BR setgroups (2)
++syscall in user namespaces.
++
++.BR setgroups(2)
++is only callable with CAP_SETGID and CAP_SETGID in a user
++namespace (since Linux 3.19) does not give you permission to call setgroups(2)
++until after GID map has been set. The GID map is writable by root when
++.BR setgroups(2)
++is enabled and GID map becomes writable by unprivileged processes when
++.BR setgroups(2)
++is permanently disabled.
++.TP
++.BR \-V , " \-\-version"
++Display version information and exit.
++.TP
++.BR \-h , " \-\-help"
++Display help text and exit.
++.SH EXAMPLES
++.TP
++.B # unshare --fork --pid --mount-proc readlink /proc/self
++.TQ
++1
++.br
++Establish a PID namespace, ensure we're PID 1 in it against newly mounted
++procfs instance.
++.TP
++.B $ unshare --map-root-user --user sh -c whoami
++.TQ
++root
++.br
++Establish a user namespace as an unprivileged user with a root user within it.
+ .SH SEE ALSO
+ .BR unshare (2),
+ .BR clone (2),
+diff -up util-linux-2.23.2/sys-utils/unshare.c.kzak util-linux-2.23.2/sys-utils/unshare.c
+--- util-linux-2.23.2/sys-utils/unshare.c.kzak	2015-06-26 09:58:39.484633521 +0200
++++ util-linux-2.23.2/sys-utils/unshare.c	2015-06-26 09:58:51.673541033 +0200
+@@ -32,19 +32,117 @@
+ 
+ #include "nls.h"
+ #include "c.h"
++#include "closestream.h"
+ #include "namespace.h"
+ #include "exec_shell.h"
+ #include "xalloc.h"
+ #include "pathnames.h"
++#include "all-io.h"
+ 
++/* 'private' is kernel default */
++#define UNSHARE_PROPAGATION_DEFAULT	(MS_REC | MS_PRIVATE)
++
++enum {
++	SETGROUPS_NONE = -1,
++	SETGROUPS_DENY = 0,
++	SETGROUPS_ALLOW = 1,
++};
++
++static const char *setgroups_strings[] =
++{
++	[SETGROUPS_DENY] = "deny",
++	[SETGROUPS_ALLOW] = "allow"
++};
++
++static int setgroups_str2id(const char *str)
++{
++	size_t i;
++
++	for (i = 0; i < ARRAY_SIZE(setgroups_strings); i++)
++		if (strcmp(str, setgroups_strings[i]) == 0)
++			return i;
++
++	errx(EXIT_FAILURE, _("unsupported --setgroups argument '%s'"), str);
++}
++
++static void setgroups_control(int action)
++{
++	const char *file = _PATH_PROC_SETGROUPS;
++	const char *cmd;
++	int fd;
++
++	if (action < 0 || (size_t) action >= ARRAY_SIZE(setgroups_strings))
++		return;
++	cmd = setgroups_strings[action];
++
++	fd = open(file, O_WRONLY);
++	if (fd < 0) {
++		if (errno == ENOENT)
++			return;
++		 err(EXIT_FAILURE, _("cannot open %s"), file);
++	}
++
++	if (write_all(fd, cmd, strlen(cmd)))
++		err(EXIT_FAILURE, _("write failed %s"), file);
++	close(fd);
++}
++
++static void map_id(const char *file, uint32_t from, uint32_t to)
++{
++	char *buf;
++	int fd;
++
++	fd = open(file, O_WRONLY);
++	if (fd < 0)
++		 err(EXIT_FAILURE, _("cannot open %s"), file);
++
++	xasprintf(&buf, "%u %u 1", from, to);
++	if (write_all(fd, buf, strlen(buf)))
++		err(EXIT_FAILURE, _("write failed %s"), file);
++	free(buf);
++	close(fd);
++}
++
++static unsigned long parse_propagation(const char *str)
++{
++	size_t i;
++	static const struct prop_opts {
++		const char *name;
++		unsigned long flag;
++	} opts[] = {
++		{ "slave",	MS_REC | MS_SLAVE },
++		{ "private",	MS_REC | MS_PRIVATE },
++		{ "shared",     MS_REC | MS_SHARED },
++		{ "unchanged",        0 }
++	};
++
++	for (i = 0; i < ARRAY_SIZE(opts); i++) {
++		if (strcmp(opts[i].name, str) == 0)
++			return opts[i].flag;
++	}
++
++	errx(EXIT_FAILURE, _("unsupported propagation mode: %s"), str);
++}
++
++static void set_propagation(unsigned long flags)
++{
++	if (flags == 0)
++		return;
++
++	if (mount("none", "/", NULL, flags, NULL) != 0)
++		err(EXIT_FAILURE, _("cannot change root filesystem propagation"));
++}
+ 
+ static void usage(int status)
+ {
+ 	FILE *out = status == EXIT_SUCCESS ? stdout : stderr;
+ 
+ 	fputs(USAGE_HEADER, out);
+-	fprintf(out,
+-	      _(" %s [options] <program> [args...]\n"),	program_invocation_short_name);
++	fprintf(out, _(" %s [options] <program> [<argument>...]\n"),
++		program_invocation_short_name);
++
++	fputs(USAGE_SEPARATOR, out);
++	fputs(_("Run a program with some namespaces unshared from the parent.\n"), out);
+ 
+ 	fputs(USAGE_OPTIONS, out);
+ 	fputs(_(" -m, --mount               unshare mounts namespace\n"), out);
+@@ -52,8 +150,13 @@ static void usage(int status)
+ 	fputs(_(" -i, --ipc                 unshare System V IPC namespace\n"), out);
+ 	fputs(_(" -n, --net                 unshare network namespace\n"), out);
+ 	fputs(_(" -p, --pid                 unshare pid namespace\n"), out);
++	fputs(_(" -U, --user                unshare user namespace\n"), out);
+ 	fputs(_(" -f, --fork                fork before launching <program>\n"), out);
+ 	fputs(_("     --mount-proc[=<dir>]  mount proc filesystem first (implies --mount)\n"), out);
++	fputs(_(" -r, --map-root-user       map current user to root (implies --user)\n"), out);
++	fputs(_("     --propagation <slave|shared|private|unchanged>\n"
++	        "                           modify mount propagation in mount namespace\n"), out);
++	fputs(_(" -s, --setgroups allow|deny  control the setgroups syscall in user namespaces\n"), out);
+ 
+ 	fputs(USAGE_SEPARATOR, out);
+ 	fputs(USAGE_HELP, out);
+@@ -66,7 +169,9 @@ static void usage(int status)
+ int main(int argc, char *argv[])
+ {
+ 	enum {
+-		OPT_MOUNTPROC = CHAR_MAX + 1
++		OPT_MOUNTPROC = CHAR_MAX + 1,
++		OPT_PROPAGATION,
++		OPT_SETGROUPS
+ 	};
+ 	static const struct option longopts[] = {
+ 		{ "help", no_argument, 0, 'h' },
+@@ -76,20 +181,29 @@ int main(int argc, char *argv[])
+ 		{ "ipc", no_argument, 0, 'i' },
+ 		{ "net", no_argument, 0, 'n' },
+ 		{ "pid", no_argument, 0, 'p' },
++		{ "user", no_argument, 0, 'U' },
+ 		{ "fork", no_argument, 0, 'f' },
+ 		{ "mount-proc", optional_argument, 0, OPT_MOUNTPROC },
++		{ "map-root-user", no_argument, 0, 'r' },
++		{ "propagation", required_argument, 0, OPT_PROPAGATION },
++		{ "setgroups", required_argument, 0, OPT_SETGROUPS },
+ 		{ NULL, 0, 0, 0 }
+ 	};
+ 
++	int setgrpcmd = SETGROUPS_NONE;
+ 	int unshare_flags = 0;
+-	int c, forkit = 0;
++	int c, forkit = 0, maproot = 0;
+ 	const char *procmnt = NULL;
++	unsigned long propagation = UNSHARE_PROPAGATION_DEFAULT;
++	uid_t real_euid = geteuid();
++	gid_t real_egid = getegid();;
+ 
+ 	setlocale(LC_ALL, "");
+ 	bindtextdomain(PACKAGE, LOCALEDIR);
+ 	textdomain(PACKAGE);
++	atexit(close_stdout);
+ 
+-	while ((c = getopt_long(argc, argv, "+fhVmuinp", longopts, NULL)) != -1) {
++	while ((c = getopt_long(argc, argv, "+fhVmuinpUr", longopts, NULL)) != -1) {
+ 		switch (c) {
+ 		case 'f':
+ 			forkit = 1;
+@@ -114,10 +228,23 @@ int main(int argc, char *argv[])
+ 		case 'p':
+ 			unshare_flags |= CLONE_NEWPID;
+ 			break;
++		case 'U':
++			unshare_flags |= CLONE_NEWUSER;
++			break;
+ 		case OPT_MOUNTPROC:
+ 			unshare_flags |= CLONE_NEWNS;
+ 			procmnt = optarg ? optarg : "/proc";
+ 			break;
++		case 'r':
++			unshare_flags |= CLONE_NEWUSER;
++			maproot = 1;
++			break;
++		case OPT_SETGROUPS:
++			setgrpcmd = setgroups_str2id(optarg);
++			break;
++		case OPT_PROPAGATION:
++			propagation = parse_propagation(optarg);
++			break;
+ 		default:
+ 			usage(EXIT_FAILURE);
+ 		}
+@@ -146,6 +273,25 @@ int main(int argc, char *argv[])
+ 		}
+ 	}
+ 
++	if (maproot) {
++		if (setgrpcmd == SETGROUPS_ALLOW)
++			errx(EXIT_FAILURE, _("options --setgroups=allow and "
++					"--map-root-user are mutually exclusive"));
++
++		/* since Linux 3.19 unprivileged writing of /proc/self/gid_map
++		 * has s been disabled unless /proc/self/setgroups is written
++		 * first to permanently disable the ability to call setgroups
++		 * in that user namespace. */
++		setgroups_control(SETGROUPS_DENY);
++		map_id(_PATH_PROC_UIDMAP, 0, real_euid);
++		map_id(_PATH_PROC_GIDMAP, 0, real_egid);
++
++	} else if (setgrpcmd != SETGROUPS_NONE)
++		setgroups_control(setgrpcmd);
++
++	if ((unshare_flags & CLONE_NEWNS) && propagation)
++		set_propagation(propagation);
++
+ 	if (procmnt &&
+ 	    (mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0 ||
+ 	     mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0))
diff --git a/SOURCES/v2.26-nsenter-selinux.patch b/SOURCES/v2.26-nsenter-selinux.patch
new file mode 100644
index 0000000..0676127
--- /dev/null
+++ b/SOURCES/v2.26-nsenter-selinux.patch
@@ -0,0 +1,129 @@
+diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am
+--- util-linux-2.23.2/sys-utils/Makemodule.am.kzak	2015-06-26 10:21:34.337221288 +0200
++++ util-linux-2.23.2/sys-utils/Makemodule.am	2015-06-26 10:22:18.719885983 +0200
+@@ -308,7 +308,7 @@ if BUILD_NSENTER
+ usrbin_exec_PROGRAMS += nsenter
+ dist_man_MANS += sys-utils/nsenter.1
+ nsenter_SOURCES = sys-utils/nsenter.c
+-nsenter_LDADD = $(LDADD) libcommon.la
++nsenter_LDADD = $(LDADD) libcommon.la $(SELINUX_LIBS)
+ endif
+ 
+ if BUILD_HWCLOCK
+diff -up util-linux-2.23.2/sys-utils/nsenter.1.kzak util-linux-2.23.2/sys-utils/nsenter.1
+--- util-linux-2.23.2/sys-utils/nsenter.1.kzak	2015-06-26 10:14:00.947646586 +0200
++++ util-linux-2.23.2/sys-utils/nsenter.1	2015-06-26 10:21:34.337221288 +0200
+@@ -155,6 +155,11 @@ Do not fork before exec'ing the specifie
+ PID namespace, \fBnsenter\fP calls \fBfork\fP before calling \fBexec\fP so that
+ any children will also be in the newly entered PID namespace.
+ .TP
++\fB\-Z\fR, \fB\-\-follow\-context\fR
++Set the SELinux security context used for executing a new process according to
++already running process specified by \fB\-\-target\fR PID. (The util-linux has
++to be compiled with SELinux support otherwise the option is unavailable.)
++.TP
+ \fB\-V\fR, \fB\-\-version\fR
+ Display version information and exit.
+ .TP
+@@ -163,10 +168,14 @@ Display help text and exit.
+ .SH SEE ALSO
+ .BR setns (2),
+ .BR clone (2)
+-.SH AUTHOR
+-.MT ebiederm@xmission.com
++.SH AUTHORS
++.UR biederm@xmission.com
+ Eric Biederman
+-.ME
++.UE
++.br
++.UR kzak@redhat.com
++Karel Zak
++.UE
+ .SH AVAILABILITY
+ The nsenter command is part of the util-linux package and is available from
+ .UR ftp://\:ftp.kernel.org\:/pub\:/linux\:/utils\:/util-linux/
+diff -up util-linux-2.23.2/sys-utils/nsenter.c.kzak util-linux-2.23.2/sys-utils/nsenter.c
+--- util-linux-2.23.2/sys-utils/nsenter.c.kzak	2015-06-26 10:14:00.947646586 +0200
++++ util-linux-2.23.2/sys-utils/nsenter.c	2015-06-26 10:21:34.337221288 +0200
+@@ -30,6 +30,10 @@
+ #include <sys/wait.h>
+ #include <grp.h>
+ 
++#ifdef HAVE_LIBSELINUX
++# include <selinux/selinux.h>
++#endif
++
+ #include "strutils.h"
+ #include "nls.h"
+ #include "c.h"
+@@ -82,6 +86,9 @@ static void usage(int status)
+ 	fputs(_(" -r, --root[=<dir>]     set the root directory\n"), out);
+ 	fputs(_(" -w, --wd[=<dir>]       set the working directory\n"), out);
+ 	fputs(_(" -F, --no-fork          do not fork before exec'ing <program>\n"), out);
++#ifdef HAVE_LIBSELINUX
++	fputs(_(" -Z, --follow-context   set SELinux context according to --target PID\n"), out);
++#endif
+ 
+ 	fputs(USAGE_SEPARATOR, out);
+ 	fputs(USAGE_HELP, out);
+@@ -185,6 +192,9 @@ int main(int argc, char *argv[])
+ 		{ "wd", optional_argument, NULL, 'w' },
+ 		{ "no-fork", no_argument, NULL, 'F' },
+ 		{ "preserve-credentials", no_argument, NULL, OPT_PRESERVE_CRED },
++#ifdef HAVE_LIBSELINUX
++		{ "follow-context", no_argument, NULL, 'Z' },
++#endif
+ 		{ NULL, 0, NULL, 0 }
+ 	};
+ 
+@@ -194,6 +204,9 @@ int main(int argc, char *argv[])
+ 	int do_fork = -1; /* unknown yet */
+ 	uid_t uid = 0;
+ 	gid_t gid = 0;
++#ifdef HAVE_LIBSELINUX
++	bool selinux = 0;
++#endif
+ 
+ 	setlocale(LC_ALL, "");
+ 	bindtextdomain(PACKAGE, LOCALEDIR);
+@@ -201,7 +214,7 @@ int main(int argc, char *argv[])
+ 	atexit(close_stdout);
+ 
+ 	while ((c =
+-		getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::F",
++		getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::FZ",
+ 			    longopts, NULL)) != -1) {
+ 		switch (c) {
+ 		case 'h':
+@@ -275,11 +288,30 @@ int main(int argc, char *argv[])
+ 		case OPT_PRESERVE_CRED:
+ 			preserve_cred = 1;
+ 			break;
++#ifdef HAVE_LIBSELINUX
++		case 'Z':
++			selinux = 1;
++			break;
++#endif
+ 		default:
+ 			usage(EXIT_FAILURE);
+ 		}
+ 	}
+ 
++#ifdef HAVE_LIBSELINUX
++	if (selinux && is_selinux_enabled() > 0) {
++		char *scon = NULL;
++
++		if (!namespace_target_pid)
++			errx(EXIT_FAILURE, _("no target PID specified for --follow-context"));
++		if (getpidcon(namespace_target_pid, &scon) < 0)
++			errx(EXIT_FAILURE, _("failed to get %d SELinux context"),
++					(int) namespace_target_pid);
++		if (setexeccon(scon) < 0)
++			errx(EXIT_FAILURE, _("failed to set exec context to '%s'"), scon);
++		freecon(scon);
++	}
++#endif
+ 	/*
+ 	 * Open remaining namespace and directory descriptors.
+ 	 */
diff --git a/SPECS/util-linux.spec b/SPECS/util-linux.spec
index ee7c34d..c90240c 100644
--- a/SPECS/util-linux.spec
+++ b/SPECS/util-linux.spec
@@ -2,7 +2,7 @@
 Summary: A collection of basic system utilities
 Name: util-linux
 Version: 2.23.2
-Release: 22%{?dist}.1
+Release: 26%{?dist}
 License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain
 Group: System Environment/Base
 URL: http://en.wikipedia.org/wiki/Util-linux
@@ -167,12 +167,36 @@ Patch42: 2.26-blkdiscard.patch
 Patch43: 2.26-raw-stat.patch
 
 #
-# RHEL 7.1.Z
+# RHEL 7.2
 #
 Patch44: 2.25-uuidd-timeout.patch
-# 1238678 - os-prober attempts to mount thin pool devices
-Patch45: 2.25-libblkid-thinpool.patch
-
+# 1225235 - blockdev --report fails on loop and pmem devices
+Patch45: 2.25-blockdev-geom.patch
+# 1225053 - [RFE] backport fstrim -a and unit file
+Patch46: 2.25-fstrim-all.patch
+# 1131523 - mount does not appear to be correctly documented for default mount options
+Patch47: 2.25-mount-man-default.patch
+# 1147526 - Incorrect message printed when su is killed
+Patch48: 2.26-su-coredump-message.patch
+# 1165702 - make login(1) insensitive to SIGXFSZ and huge lastlog
+Patch49: 2.26-login-SIGXFSZ.patch
+# 1184558 - logger silently changes facility from kern to user
+Patch50: 2.26-logger-man-kern.patch
+# 1198243 - blkid does not recognize xfs external log device
+Patch51: 2.25-libblkid-xfs-log.patch
+# 1208081 - lsblk does not list dm-multipath and partitioned devices
+Patch52: 2.26-lsblk-mpath.patch
+# 1209594 - RHEL7: unshare: add --propagation, use MS_PRIVATE by default
+# 1229436 - Remove patch that disables User Namespaces
+Patch53: 2.26-unshare-rebase.patch
+# 1116100 - Add -Z SELInux option to nsenter
+Patch54: v2.26-nsenter-selinux.patch
+# 1199619 - os-prober attempts to mount thin pool devices
+Patch55: 2.25-libblkid-thinpool.patch
+# 1251250 - blkid outputs nothing for some partitions (e.g. sun label)
+Patch56: 2.25-libblkid-return-codes.patch
+# 1182831 - blkid incorrectly detects boot sec + MBR as FAT
+Patch57: 2.26-libblkid-fat.patch
 
 %description
 The util-linux package contains a large variety of low-level system
@@ -540,6 +564,8 @@ fi
 %ghost %attr(0644,root,root) %verify(not md5 size mtime) /var/log/lastlog
 %ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/mtab
 
+%{_unitdir}/fstrim.*
+
 %{_bindir}/cal
 %{_bindir}/chrt
 %{_bindir}/col
@@ -832,7 +858,7 @@ fi
 %doc Documentation/licenses/COPYING.GPLv2
 %{_mandir}/man8/uuidd.8*
 %{_sbindir}/uuidd
-%{_unitdir}/*
+%{_unitdir}/uuidd.*
 %dir %attr(2775, uuidd, uuidd) /var/lib/libuuid
 %dir %attr(2775, uuidd, uuidd) /run/uuidd
 %{compldir}/uuidd
@@ -890,8 +916,27 @@ fi
 %{_libdir}/pkgconfig/uuid.pc
 
 %changelog
-* Fri Jul  3 2015 Karel Zak <kzak@redhat.com> 2.23.2-22.el7_1.1
-- fix #1238678 - os-prober attempts to mount thin pool devices
+* Fri Aug 21 2015 Karel Zak <kzak@redhat.com> 2.23.2-26
+- fix #1182831 - blkid incorrectly detects boot sec + MBR as FAT
+
+* Wed Aug 12 2015 Karel Zak <kzak@redhat.com> 2.23.2-25
+- fix #1251250 - blkid outputs nothing for some partitions (e.g. sun label)
+
+* Thu Jul  2 2015 Karel Zak <kzak@redhat.com> 2.23.2-24
+- fix #1199619 - os-prober attempts to mount thin pool devices
+
+* Tue Jun 23 2015 Karel Zak <kzak@redhat.com> 2.23.2-23
+- fix #1225235 - blockdev --report fails on loop and pmem devices
+- fix #1225053 - [RFE] backport fstrim -a and unit file
+- fix #1131523 - mount does not appear to be correctly documented for default mount options
+- fix #1147526 - Incorrect message printed when su is killed
+- fix #1165702 - make login(1) insensitive to SIGXFSZ and huge lastlog
+- fix #1184558 - logger silently changes facility from kern to user
+- fix #1198243 - blkid does not recognize xfs external log device
+- fix #1208081 - lsblk does not list dm-multipath and partitioned devices
+- fix #1209594 - RHEL7: unshare: add --propagation, use MS_PRIVATE by default
+- fix #1229436 - Remove patch that disables User Namespaces
+- fix #1116100 - Add -Z SELInux option to nsenter
 
 * Mon Apr 20 2015 Karel Zak <kzak@redhat.com> 2.23.2-22
 - fix #1092039 - uuidd not configured to run permanently