[packages/multipath-tools] - updated to 0.5.0 - removed obsolete git patch - added format patch (fixes build with -Werror=forma

qboosh qboosh at pld-linux.org
Sun Feb 16 21:50:32 CET 2014


commit 17606c328534d7ad288a176df173724a1fc03138
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Sun Feb 16 21:52:41 2014 +0100

    - updated to 0.5.0
    - removed obsolete git patch
    - added format patch (fixes build with -Werror=format-security)

 multipath-tools-format.patch |    11 +
 multipath-tools-git.patch    | 25278 -----------------------------------------
 multipath-tools.spec         |    20 +-
 3 files changed, 23 insertions(+), 25286 deletions(-)
---
diff --git a/multipath-tools.spec b/multipath-tools.spec
index 61e4417..9ce46ed 100644
--- a/multipath-tools.spec
+++ b/multipath-tools.spec
@@ -5,20 +5,20 @@
 Summary:	Tools to manage multipathed devices with the device-mapper
 Summary(pl.UTF-8):	Implementacja wielotrasowego dostępu do zasobów przy użyciu device-mappera
 Name:		multipath-tools
-Version:	0.4.9
-Release:	10
+Version:	0.5.0
+Release:	1
 License:	GPL v2
 Group:		Base
 Source0:	http://christophe.varoqui.free.fr/multipath-tools/%{name}-%{version}.tar.bz2
-# Source0-md5:	a6d4b48afc28f1f50f5ee4b1b06d2765
+# Source0-md5:	faf261d4cc717bf4c979557dc7bf5f52
 Source100:	branch.sh
 Source1:	multipathd.init
 Source2:	multipathd.sysconfig
 Source3:	%{name}-bindings
-URL:		http://christophe.varoqui.free.fr/
-Patch100:	%{name}-git.patch
+Patch0:		%{name}-format.patch
 Patch1:		%{name}-kpartx-udev.patch
 Patch2:		config.patch
+URL:		http://christophe.varoqui.free.fr/
 BuildRequires:	device-mapper-devel >= 1.02.08
 BuildRequires:	libaio-devel
 BuildRequires:	linux-libc-headers >= 2.6.12.0-5
@@ -26,6 +26,8 @@ BuildRequires:	readline-devel
 BuildRequires:	rpmbuild(macros) >= 1.647
 BuildRequires:	sed >= 4.0
 BuildRequires:	sysfsutils-devel >= 2.0.0
+BuildRequires:	systemd-devel
+BuildRequires:	udev-devel
 %if %{with initrd}
 BuildRequires:	device-mapper-initrd-devel
 BuildRequires:	klibc-static
@@ -94,8 +96,8 @@ kpartx odwzorowuje liniowe mapy urządzeń na partycje urządzeń, co
 umożliwia tworzenie partycji na odwzorowaniach wielotrasowych.
 
 %prep
-%setup -qc
-%patch100 -p1
+%setup -q
+%patch0 -p1
 %patch1 -p1
 %patch2 -p1
 
@@ -121,7 +123,8 @@ rm -rf $RPM_BUILD_ROOT
 install -d $RPM_BUILD_ROOT{/etc/{rc.d/init.d,sysconfig},%{_sysconfdir}/multipath}
 
 %{__make} install \
-	DESTDIR=$RPM_BUILD_ROOT
+	DESTDIR=$RPM_BUILD_ROOT \
+	unitdir=%{systemdunitdir}
 
 install -p %{SOURCE1} $RPM_BUILD_ROOT/etc/rc.d/init.d/multipathd
 cp -p multipath.conf.defaults $RPM_BUILD_ROOT%{_sysconfdir}/multipath.conf
@@ -172,6 +175,7 @@ fi
 %dir %{_sysconfdir}/multipath
 %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/multipath/bindings
 %{systemdunitdir}/multipathd.service
+%{systemdunitdir}/multipathd.socket
 %{_mandir}/man5/multipath.conf.5*
 %{_mandir}/man8/mpathpersist.8*
 %{_mandir}/man8/multipath.8*
diff --git a/multipath-tools-format.patch b/multipath-tools-format.patch
new file mode 100644
index 0000000..10fce83
--- /dev/null
+++ b/multipath-tools-format.patch
@@ -0,0 +1,11 @@
+--- multipath-tools-0.5.0/libmultipath/checkers/rdac.c.orig	2013-12-17 22:40:41.000000000 +0100
++++ multipath-tools-0.5.0/libmultipath/checkers/rdac.c	2014-02-16 21:33:01.573751205 +0100
+@@ -308,7 +308,7 @@
+ done:
+ 	switch (ret) {
+ 	case PATH_DOWN:
+-		MSG(c, (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
++		MSG(c, "%s", (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
+ 			checker_msg_string(&inq));
+ 		break;
+ 	case PATH_UP:
diff --git a/multipath-tools-git.patch b/multipath-tools-git.patch
deleted file mode 100644
index 15ed895..0000000
--- a/multipath-tools-git.patch
+++ /dev/null
@@ -1,25278 +0,0 @@
-diff --git a/.gitignore b/.gitignore
-index 9b3f663..7f25d0e 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -5,6 +5,8 @@
- *.so.0
- *.a
- *.gz
--kpartx
--multipath
--multipathd
-+kpartx/kpartx
-+multipath/multipath
-+multipathd/multipathd
-+mpathpersist/mpathpersist
-+.nfs*
-diff --git a/Makefile b/Makefile
-index d0063d0..baf7753 100644
---- a/Makefile
-+++ b/Makefile
-@@ -23,8 +23,10 @@ BUILDDIRS = \
- 	libmultipath \
- 	libmultipath/prioritizers \
- 	libmultipath/checkers \
-+	libmpathpersist \
- 	multipath \
- 	multipathd \
-+	mpathpersist \
- 	kpartx
- 
- ifeq   ($(MULTIPATH_VERSION),)
-@@ -64,6 +66,13 @@ install:	recurse_install
- 
- uninstall:	recurse_uninstall
- 
-+.PHONY:	TAGS
-+TAGS:
-+	etags -a libmultipath/*.c
-+	etags -a libmultipath/*.h
-+	etags -a multipathd/*.c
-+	etags -a multipathd/*.h
-+
- release:
- 	sed -e "s/__VERSION__/${VERSION}/" \
- 	multipath-tools.spec.in > multipath-tools.spec
-diff --git a/Makefile.inc b/Makefile.inc
-index dbcbc3b..92d2289 100644
---- a/Makefile.inc
-+++ b/Makefile.inc
-@@ -28,14 +28,21 @@ libudevdir  = ${prefix}/lib/udev
- multipathdir = $(TOPDIR)/libmultipath
- mandir      = $(prefix)/usr/share/man/man8
- man5dir     = $(prefix)/usr/share/man/man5
-+man3dir      = $(prefix)/usr/share/man/man3
- rcdir	    = $(prefix)/etc/init.d
- syslibdir   = $(prefix)/$(LIB)
- libdir	    = $(prefix)/$(LIB)/multipath
-+unitdir     = $(prefix)/lib/systemd/system
-+mpathpersistdir = $(TOPDIR)/libmpathpersist
- 
--GZIP        = /bin/gzip -9 -c
-+GZIP        = gzip -9 -c
- INSTALL_PROGRAM = install
- 
--OPTFLAGS     = -pipe -g -Wall -Wunused -Wstrict-prototypes
-+ifndef RPM_OPT_FLAGS
-+	RPM_OPT_FLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
-+endif
-+
-+OPTFLAGS     = $(RPM_OPT_FLAGS) -Wunused -Wstrict-prototypes
- CFLAGS	     = $(OPTFLAGS) -fPIC -DLIB_STRING=\"${LIB}\"
- SHARED_FLAGS = -shared
- 
-diff --git a/kpartx/Makefile b/kpartx/Makefile
-index e1e9651..4ba38ba 100644
---- a/kpartx/Makefile
-+++ b/kpartx/Makefile
-@@ -6,9 +6,15 @@ include ../Makefile.inc
- 
- CFLAGS += -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
- 
-+LIBDM_API_COOKIE = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_set_cookie' /usr/include/libdevmapper.h)
-+
-+ifneq ($(strip $(LIBDM_API_COOKIE)),0)
-+	CFLAGS += -DLIBDM_API_COOKIE
-+endif
-+
- LDFLAGS = -ldevmapper
- OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \
--       gpt.o mac.o crc32.o lopart.o xstrncpy.o devmapper.o
-+       gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o
- EXEC = kpartx
- 
- all: $(EXEC)
-@@ -16,7 +22,7 @@ all: $(EXEC)
- $(EXEC): $(OBJS)
- 	$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS)
- 	$(GZIP) $(EXEC).8 > $(EXEC).8.gz
--	
-+
- install: $(EXEC) $(EXEC).8
- 	$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- 	$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
-@@ -30,6 +36,7 @@ install: $(EXEC) $(EXEC).8
- uninstall:
- 	rm -f $(DESTDIR)$(bindir)/$(EXEC)
- 	rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz
-+	rm -f $(DESTDIR)$(libudevdir)/kpartx_id
- 
- clean:
- 	rm -f core *.o $(EXEC) *.gz
-diff --git a/kpartx/byteorder.h b/kpartx/byteorder.h
-index 21962d6..199c66b 100644
---- a/kpartx/byteorder.h
-+++ b/kpartx/byteorder.h
-@@ -12,12 +12,16 @@
- #  define le16_to_cpu(x) (x)
- #  define be16_to_cpu(x) bswap_16(x)
- #  define le32_to_cpu(x) (x)
-+#  define le64_to_cpu(x) (x)
- #  define be32_to_cpu(x) bswap_32(x)
-+#  define be64_to_cpu(x) bswap_64(x)
- #elif BYTE_ORDER == BIG_ENDIAN
- #  define le16_to_cpu(x) bswap_16(x)
- #  define be16_to_cpu(x) (x)
- #  define le32_to_cpu(x) bswap_32(x)
-+#  define le64_to_cpu(x) bswap_64(x)
- #  define be32_to_cpu(x) (x)
-+#  define be64_to_cpu(x) (x)
- #else
- #  error unsupported
- #endif
-diff --git a/kpartx/dasd.h b/kpartx/dasd.h
-index 0ed7c80..42f94db 100644
---- a/kpartx/dasd.h
-+++ b/kpartx/dasd.h
-@@ -68,7 +68,7 @@ typedef struct volume_label
- 	char res2[4];	        /* reserved                                  */
- 	char lvtoc[14];	        /* owner code for LVTOC                      */
- 	char res3[28];	        /* reserved                                  */
--	char ldl_version;       /* version number, valid for ldl format      */
-+	uint8_t ldl_version;    /* version number, valid for ldl format      */
- 	uint64_t formatted_blocks; /* valid when ldl_version >= f2           */
- } __attribute__ ((packed)) volume_label_t;
- 
-diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c
-index f884511..24a43ee 100644
---- a/kpartx/devmapper.c
-+++ b/kpartx/devmapper.c
-@@ -12,6 +12,14 @@
- 
- #define UUID_PREFIX "part%d-"
- #define MAX_PREFIX_LEN 8
-+#define PARAMS_SIZE 1024
-+
-+#ifndef LIBDM_API_COOKIE
-+static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
-+{
-+	return 1;
-+}
-+#endif
- 
- extern int
- dm_prereq (char * str, int x, int y, int z)
-@@ -70,7 +78,7 @@ dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
- 	if (no_flush)
- 		dm_task_no_flush(dmt);
- 
--	if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, 0))
-+	if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, (udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK))
- 		goto out;
- 	r = dm_task_run(dmt);
- 
-@@ -81,7 +89,7 @@ dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
- 
- extern int
- dm_addmap (int task, const char *name, const char *target,
--	   const char *params, uint64_t size, const char *uuid, int part,
-+	   const char *params, uint64_t size, int ro, const char *uuid, int part,
- 	   mode_t mode, uid_t uid, gid_t gid, uint32_t *cookie) {
- 	int r = 0;
- 	struct dm_task *dmt;
-@@ -96,6 +104,9 @@ dm_addmap (int task, const char *name, const char *target,
- 	if (!dm_task_add_target (dmt, 0, size, target, params))
- 		goto addout;
- 
-+	if (ro && !dm_task_set_ro (dmt))
-+			goto addout;
-+
- 	if (task == DM_DEVICE_CREATE && uuid) {
- 		prefixed_uuid = malloc(MAX_PREFIX_LEN + strlen(uuid) + 1);
- 		if (!prefixed_uuid) {
-@@ -117,7 +128,7 @@ dm_addmap (int task, const char *name, const char *target,
- 
- 	dm_task_no_open_count(dmt);
- 
--	if (task == DM_DEVICE_CREATE && !dm_task_set_cookie(dmt, cookie, 0))
-+	if (task == DM_DEVICE_CREATE && !dm_task_set_cookie(dmt, cookie, (udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK))
- 		goto addout;
- 	r = dm_task_run (dmt);
- 
-@@ -268,3 +279,62 @@ out:
- 	return r;
- }
- 
-+int
-+dm_get_map(int major, int minor, char * outparams)
-+{
-+	int r = 1;
-+	struct dm_task *dmt;
-+	void *next = NULL;
-+	uint64_t start, length;
-+	char *target_type = NULL;
-+	char *params = NULL;
-+
-+	if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
-+		return 1;
-+
-+	dm_task_set_major(dmt, major);
-+	dm_task_set_minor(dmt, minor);
-+	dm_task_no_open_count(dmt);
-+
-+	if (!dm_task_run(dmt))
-+		goto out;
-+
-+	/* Fetch 1st target */
-+	next = dm_get_next_target(dmt, next, &start, &length,
-+				  &target_type, &params);
-+
-+	if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
-+		r = 0;
-+out:
-+	dm_task_destroy(dmt);
-+	return r;
-+}
-+
-+#define FEATURE_NO_PART "no_partitions"
-+
-+int
-+dm_no_partitions(int major, int minor)
-+{
-+	char params[PARAMS_SIZE], *ptr;
-+	int i, num_features;
-+
-+	if (dm_get_map(major, minor, params))
-+		return 0;
-+
-+	ptr = params;
-+	num_features = strtoul(params, &ptr, 10);
-+	if ((ptr == params) || num_features == 0) {
-+		/* No features found, return success */
-+		return 0;
-+	}
-+	for (i = 0; (i < num_features); i++) {
-+		if (!ptr || ptr > params + strlen(params))
-+			break;
-+		/* Skip whitespaces */
-+		while(ptr && *ptr == ' ') ptr++;
-+		if (!strncmp(ptr, FEATURE_NO_PART, strlen(FEATURE_NO_PART)))
-+			return 1;
-+		ptr = strchr(ptr, ' ');
-+	}
-+	return 0;
-+}
-diff --git a/kpartx/devmapper.h b/kpartx/devmapper.h
-index f8692cc..0edc063 100644
---- a/kpartx/devmapper.h
-+++ b/kpartx/devmapper.h
-@@ -2,12 +2,15 @@
- #define MINOR(dev)      ((dev & 0xff) | ((dev >> 12) & 0xfff00))
- #define MKDEV(ma,mi)    ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))
- 
-+extern int udev_sync;
-+
- int dm_prereq (char *, int, int, int);
- int dm_simplecmd (int, const char *, int, uint32_t *);
- int dm_addmap (int, const char *, const char *, const char *, uint64_t,
--	       const char *, int, mode_t, uid_t, gid_t, uint32_t *);
-+	       int, const char *, int, mode_t, uid_t, gid_t, uint32_t *);
- int dm_map_present (char *);
- char * dm_mapname(int major, int minor);
- dev_t dm_get_first_dep(char *devname);
- char * dm_mapuuid(int major, int minor);
- int dm_devn (char * mapname, int *major, int *minor);
-+int dm_no_partitions(int major, int minor);
-diff --git a/kpartx/dos.c b/kpartx/dos.c
-index 1691105..a1a9961 100644
---- a/kpartx/dos.c
-+++ b/kpartx/dos.c
-@@ -98,6 +98,8 @@ read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) {
- 			break;
- 		}
- 		if (is_extended(p.sys_type)) {
-+			sp[i].size = 2; /* extended partitions only get two
-+					   sectors mapped for LILO to install */
- 			n += read_extended_partition(fd, &p, i, sp+n, ns-n);
- 		}
- 	}
-diff --git a/kpartx/gpt.c b/kpartx/gpt.c
-index 047a829..0a22927 100644
---- a/kpartx/gpt.c
-+++ b/kpartx/gpt.c
-@@ -358,6 +358,24 @@ is_gpt_valid(int fd, uint64_t lba,
- 		return 0;
- 	}
- 
-+	/* Check that sizeof_partition_entry has the correct value */
-+	if (__le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
-+		// printf("GUID partition entry size check failed.\n");
-+		free(*gpt);
-+		*gpt = NULL;
-+		return 0;
-+	}
-+
-+
-+	/* Check that sizeof_partition_entry has the correct value */
-+	if (__le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
-+		// printf("GUID partition entry size check failed.\n");
-+		free(*gpt);
-+		*gpt = NULL;
-+		return 0;
-+	}
-+
-+
- 	if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) {
- 		free(*gpt);
- 		*gpt = NULL;
-@@ -619,6 +637,7 @@ read_gpt_pt (int fd, struct slice all, struct slice *sp, int ns)
- 	uint32_t i;
- 	int n = 0;
-         int last_used_index=-1;
-+	int sector_size_mul = get_sector_size(fd)/512;
- 
- 	if (!find_valid_gpt (fd, &gpt, &ptes) || !gpt || !ptes) {
- 		if (gpt)
-@@ -634,9 +653,11 @@ read_gpt_pt (int fd, struct slice all, struct slice *sp, int ns)
- 			sp[n].size = 0;
- 			n++;
- 		} else {
--			sp[n].start = __le64_to_cpu(ptes[i].starting_lba);
--			sp[n].size  = __le64_to_cpu(ptes[i].ending_lba) -
--				__le64_to_cpu(ptes[i].starting_lba) + 1;
-+			sp[n].start = sector_size_mul *
-+				      __le64_to_cpu(ptes[i].starting_lba);
-+			sp[n].size  = sector_size_mul *
-+				      (__le64_to_cpu(ptes[i].ending_lba) -
-+				       __le64_to_cpu(ptes[i].starting_lba) + 1);
-                         last_used_index=n;
- 			n++;
- 		}
-diff --git a/kpartx/kpartx.8 b/kpartx/kpartx.8
-index 923be1e..021ddc0 100644
---- a/kpartx/kpartx.8
-+++ b/kpartx/kpartx.8
-@@ -17,20 +17,52 @@ creation and deletion.
- .B \-a
- Add partition mappings
- .TP
-+.B \-r
-+Read-only partition mappings
-+.TP
- .B \-d
- Delete partition mappings
- .TP
-+.B \-u
-+Update partition mappings
-+.TP
- .B \-l
--List partition mappings that would be added -a
-+List partition mappings that would be added \-a
- .TP
- .B \-p
- set device name-partition number delimiter
- .TP
-+.B \-f
-+force creation of mappings; overrides 'no_partitions' feature
-+.TP
- .B \-g
- force GUID partition table (GPT)
- .TP
- .B \-v
- Operate verbosely
-+.TP
-+.B \-s
-+Sync mode. Don't return until the partitions are created
-+.SH EXAMPLE
-+To mount all the partitions in a raw disk image:
-+.IP
-+kpartx \-av disk.img
-+.PP
-+This will output lines such as:
-+.IP
-+loop3p1 : 0 20964762 /dev/loop3 63
-+.PP
-+The 
-+.I loop3p1
-+is the name of a device file under 
-+.I /dev/mapper
-+which you can use to access the partition, for example to fsck it:
-+.IP
-+fsck /dev/mapper/loop3p1
-+.PP
-+When you're done, you need to remove the devices:
-+.IP
-+kpartx \-d disk.img
- .SH "SEE ALSO"
- .BR multipath (8)
- .BR multipathd (8)
-diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
-index 3d33990..98d88c0 100644
---- a/kpartx/kpartx.c
-+++ b/kpartx/kpartx.c
-@@ -48,7 +48,7 @@
- 
- struct slice slices[MAXSLICES];
- 
--enum action { LIST, ADD, DELETE };
-+enum action { LIST, ADD, DELETE, UPDATE };
- 
- struct pt {
- 	char *type;
-@@ -56,6 +56,7 @@ struct pt {
- } pts[MAXTYPES];
- 
- int ptct = 0;
-+int udev_sync = 0;
- 
- static void
- addpts(char *t, ptreader f)
-@@ -80,21 +81,27 @@ initpts(void)
- 	addpts("dasd", read_dasd_pt);
- 	addpts("mac", read_mac_pt);
- 	addpts("sun", read_sun_pt);
-+	addpts("ps3", read_ps3_pt);
- }
- 
--static char short_opts[] = "ladgvp:t:s";
-+static char short_opts[] = "rladfgvp:t:su";
- 
- /* Used in gpt.c */
- int force_gpt=0;
- 
-+int force_devmap=0;
-+
- static int
- usage(void) {
--	printf("usage : kpartx [-a|-d|-l] [-v] wholedisk\n");
-+	printf("usage : kpartx [-a|-d|-l] [-f] [-v] wholedisk\n");
- 	printf("\t-a add partition devmappings\n");
-+	printf("\t-r devmappings will be readonly\n");
- 	printf("\t-d del partition devmappings\n");
-+	printf("\t-u update partition devmappings\n");
- 	printf("\t-l list partitions devmappings that would be added by -a\n");
- 	printf("\t-p set device name-partition number delimiter\n");
- 	printf("\t-g force GUID partition table (GPT)\n");
-+	printf("\t-f force devmap create\n");
- 	printf("\t-v verbose\n");
- 	printf("\t-s sync mode. Don't return until the partitions are created\n");
- 	return 1;
-@@ -185,7 +192,8 @@ get_hotplug_device(void)
- 
- int
- main(int argc, char **argv){
--	int fd, i, j, m, n, op, off, arg, c, d;
-+	int i, j, m, n, op, off, arg, c, d, ro=0;
-+	int fd = -1;
- 	struct slice all;
- 	struct pt *ptp;
- 	enum action what = LIST;
-@@ -199,7 +207,6 @@ main(int argc, char **argv){
- 	int loopro = 0;
- 	int hotplug = 0;
- 	int loopcreated = 0;
--	int sync = 0;
- 	struct stat buf;
- 	uint32_t cookie = 0;
- 
-@@ -233,6 +240,12 @@ main(int argc, char **argv){
- 	}
- 
- 	while ((arg = getopt(argc, argv, short_opts)) != EOF) switch(arg) {
-+		case 'r':
-+			ro=1;
-+			break;
-+		case 'f':
-+			force_devmap=1;
-+			break;
- 		case 'g':
- 			force_gpt=1;
- 			break;
-@@ -255,17 +268,22 @@ main(int argc, char **argv){
- 			what = DELETE;
- 			break;
- 		case 's':
--			sync = 1;
-+			udev_sync = 1;
-+			break;
-+		case 'u':
-+			what = UPDATE;
- 			break;
- 		default:
- 			usage();
- 			exit(1);
- 	}
- 
--	if (!sync)
-+#ifdef LIBDM_API_COOKIE
-+	if (!udev_sync)
- 		dm_udev_set_sync_support(0);
-+#endif
- 
--	if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE)) {
-+	if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE || what == UPDATE)) {
- 		fprintf(stderr, "device mapper prerequisites not met\n");
- 		exit(1);
- 	}
-@@ -306,12 +324,6 @@ main(int argc, char **argv){
- 		device = loopdev;
- 	}
- 
--	if (delim == NULL) {
--		delim = malloc(DELIM_SIZE);
--		memset(delim, 0, DELIM_SIZE);
--		set_delimiter(device, delim);
--	}
--
- 	off = find_devname_offset(device);
- 
- 	if (!loopdev) {
-@@ -326,6 +338,18 @@ main(int argc, char **argv){
- 
- 	if (!mapname)
- 		mapname = device + off;
-+	else if (!force_devmap &&
-+		 dm_no_partitions((unsigned int)MAJOR(buf.st_rdev),
-+				  (unsigned int)MINOR(buf.st_rdev))) {
-+		/* Feature 'no_partitions' is set, return */
-+		return 0;
-+	}
-+
-+	if (delim == NULL) {
-+		delim = malloc(DELIM_SIZE);
-+		memset(delim, 0, DELIM_SIZE);
-+		set_delimiter(mapname, delim);
-+	}
- 
- 	fd = open(device, O_RDONLY);
- 
-@@ -350,8 +374,10 @@ main(int argc, char **argv){
- 			printf("%s: %d slices\n", ptp->type, n);
- #endif
- 
--		if (n > 0)
-+		if (n > 0) {
- 			close(fd);
-+			fd = -1;
-+		}
- 		else
- 			continue;
- 
-@@ -399,15 +425,6 @@ main(int argc, char **argv){
- 					break;
- 			}
- 
--			if (loopcreated && S_ISREG (buf.st_mode)) {
--				if (del_loop(device)) {
--					if (verbose)
--						printf("can't del loop : %s\n",
--							device);
--					exit(1);
--				}
--				printf("loop deleted : %s\n", device);
--			}
- 			break;
- 
- 		case DELETE:
-@@ -443,6 +460,8 @@ main(int argc, char **argv){
- 			break;
- 
- 		case ADD:
-+		case UPDATE:
-+			/* ADD and UPDATE share the same code that adds new partitions. */
- 			for (j = 0, c = 0; j < n; j++) {
- 				if (slices[j].size == 0)
- 					continue;
-@@ -470,7 +489,7 @@ main(int argc, char **argv){
- 					DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
- 
- 				if (!dm_addmap(op, partname, DM_TARGET, params,
--					       slices[j].size, uuid, j+1,
-+					       slices[j].size, ro, uuid, j+1,
- 					       buf.st_mode & 0777, buf.st_uid,
- 					       buf.st_gid, &cookie)) {
- 					fprintf(stderr, "create/reload failed on %s\n",
-@@ -497,7 +516,6 @@ main(int argc, char **argv){
- 			d = c;
- 			while (c) {
- 				for (j = 0; j < n; j++) {
--					uint64_t start;
- 					int k = slices[j].container - 1;
- 
- 					if (slices[j].size == 0)
-@@ -523,11 +541,9 @@ main(int argc, char **argv){
- 					}
- 					strip_slash(partname);
- 
--					start = slices[j].start - slices[k].start;
--					if (safe_sprintf(params, "%d:%d %" PRIu64,
--							 slices[k].major,
--							 slices[k].minor,
--							 start)) {
-+					if (safe_sprintf(params, "%s %" PRIu64,
-+							 device,
-+							 slices[j].start)) {
- 						fprintf(stderr, "params too small\n");
- 						exit(1);
- 					}
-@@ -536,7 +552,7 @@ main(int argc, char **argv){
- 					      DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
- 
- 					dm_addmap(op, partname, DM_TARGET, params,
--						  slices[j].size, uuid, j+1,
-+						  slices[j].size, ro, uuid, j+1,
- 						  buf.st_mode & 0777,
- 						  buf.st_uid, buf.st_gid,
- 						  &cookie);
-@@ -559,7 +575,31 @@ main(int argc, char **argv){
- 				if (d == c)
- 					break;
- 			}
--			break;
-+
-+			if (what == ADD) {
-+				/* Skip code that removes devmappings for deleted partitions */
-+				break;
-+			}
-+
-+			for (j = MAXSLICES-1; j >= 0; j--) {
-+				if (safe_sprintf(partname, "%s%s%d",
-+					     mapname, delim, j+1)) {
-+					fprintf(stderr, "partname too small\n");
-+					exit(1);
-+				}
-+				strip_slash(partname);
-+
-+				if (slices[j].size || !dm_map_present(partname))
-+					continue;
-+
-+				if (!dm_simplecmd(DM_DEVICE_REMOVE,
-+						  partname, 1, &cookie)) {
-+					r++;
-+					continue;
-+				}
-+				if (verbose)
-+					printf("del devmap : %s\n", partname);
-+			}
- 
- 		default:
- 			break;
-@@ -568,7 +608,20 @@ main(int argc, char **argv){
- 		if (n > 0)
- 			break;
- 	}
-+	if (what == LIST && loopcreated && S_ISREG (buf.st_mode)) {
-+		if (fd != -1)
-+			close(fd);
-+		if (del_loop(device)) {
-+			if (verbose)
-+				printf("can't del loop : %s\n",
-+					device);
-+			exit(1);
-+		}
-+		printf("loop deleted : %s\n", device);
-+	}
-+#ifdef LIBDM_API_COOKIE
- 	dm_udev_wait(cookie);
-+#endif
- 	dm_lib_release();
- 	dm_lib_exit();
- 
-diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h
-index 43ae3f8..61d31b6 100644
---- a/kpartx/kpartx.h
-+++ b/kpartx/kpartx.h
-@@ -39,6 +39,7 @@ extern ptreader read_gpt_pt;
- extern ptreader read_dasd_pt;
- extern ptreader read_mac_pt;
- extern ptreader read_sun_pt;
-+extern ptreader read_ps3_pt;
- 
- char *getblock(int fd, unsigned int secnr);
- 
-diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
-index 8978b73..b96ec89 100644
---- a/kpartx/kpartx.rules
-+++ b/kpartx/kpartx.rules
-@@ -8,6 +8,8 @@ KERNEL!="dm-*", GOTO="kpartx_end"
- ACTION=="remove", GOTO="kpartx_end"
- 
- ENV{DM_TABLE_STATE}!="LIVE", GOTO="kpartx_end"
-+ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", GOTO="kpartx_end"
-+ENV{DM_DEPS}=="0", GOTO="kpartx_end"
- 
- ENV{DM_UUID}=="?*", IMPORT{program}=="kpartx_id %M %m $env{DM_UUID}"
- 
-@@ -16,20 +18,22 @@ OPTIONS="link_priority=50"
- # Create persistent links for multipath tables
- ENV{DM_UUID}=="mpath-*", \
- 	SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_NAME}"
--
--# Create persistent links for dmraid tables
--ENV{DM_UUID}=="dmraid-*", \
--        SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_NAME}"
-+ENV{DM_MPATH}=="?*", ENV{DM_PART}!="?*", \
-+	SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_MPATH}"
-+ENV{DM_WWN}=="?*", ENV{DM_PART}!="?*", \
-+	SYMLINK+="disk/by-id/wwn-$env{DM_WWN}"
- 
- # Create persistent links for partitions
- ENV{DM_PART}=="?*", \
-         SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_NAME}-part$env{DM_PART}"
-+ENV{DM_MPATH}=="?*", ENV{DM_PART}=="?*", \
-+	SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_MPATH}-part$env{DM_PART}"
-+ENV{DM_WWN}=="?*", ENV{DM_PART}=="?*", \
-+	SYMLINK+="disk/by-id/wwn-$env{DM_WWN}-part$env{DM_PART}"
- 
- # Create dm tables for partitions
--ENV{DM_STATE}=="ACTIVE", ENV{DM_UUID}=="mpath-*", \
--        RUN+="/sbin/kpartx -a -p -part /dev/$name"
--ENV{DM_STATE}=="ACTIVE", ENV{DM_UUID}=="dmraid-*", \
--        RUN+="/sbin/kpartx -a -p -part /dev/$name"
-+ENV{DM_STATE}!="SUSPENDED", ENV{DM_UUID}=="mpath-*", \
-+        RUN+="/sbin/kpartx -u -p -part /dev/$name"
- 
- LABEL="kpartx_end"
- 
-diff --git a/kpartx/kpartx_id b/kpartx/kpartx_id
-index 81f32bf..517b856 100644
---- a/kpartx/kpartx_id
-+++ b/kpartx/kpartx_id
-@@ -55,6 +55,9 @@ if [ "$dmtbl" = "part" ] ; then
-     # The name of the kpartx table is the name of the parent table
-     dmname=$($DMSETUP info  -c --noheadings -o name -u $dmuuid)
-     echo "DM_NAME=$dmname"
-+    if [ "$dmname" != ${dmuuid#mpath-} ] ; then
-+	echo "DM_MPATH=${dmuuid#mpath-}"
-+    fi
-     # We need the dependencies of the parent table to figure out
-     # the type if the parent is a multipath table
-     case "$dmuuid" in
-@@ -63,7 +66,10 @@ if [ "$dmtbl" = "part" ] ; then
- 	    ;;
-     esac
- elif [ "$dmtbl" = "mpath" ] ; then
--    dmname=$tblname
-+    if [ -n "$DM_NAME" -a "$DM_NAME" != "$dmuuid" ] ; then
-+	echo "DM_MPATH=$dmuuid"
-+    fi
-+    dmname="$dmuuid"
-     # We need the dependencies of the table to figure out the type
-     dmdeps=$($DMSETUP deps -u $UUID)
- elif [ "$dmtbl" = "dmraid" ] ; then
-@@ -77,13 +83,17 @@ fi
- if [ -n "$dmdeps" ] ; then
-     case "$dmdeps" in
- 	*\(94,*)
--            echo "DM_TYPE=dasd"
-+            echo "DM_TYPE=ccw"
-+	    ;;
-+	*\(104,* | *\(105,* | *\(106,* | *\(107,* | *\(108,* | *\(109,* | *\(110,* | *\(112,*)
-+	    echo "DM_TYPE=cciss"
- 	    ;;
- 	*\(9*)
-             echo "DM_TYPE=raid"
- 	    ;;
- 	*)
-             echo "DM_TYPE=scsi"
-+	    echo "DM_WWN=0x${dmname#?}"
- 	    ;;
-     esac
- else
-diff --git a/kpartx/lopart.c b/kpartx/lopart.c
-index 79d8328..79a7593 100644
---- a/kpartx/lopart.c
-+++ b/kpartx/lopart.c
-@@ -26,18 +26,7 @@
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <sysmacros.h>
--
--#if defined(__hppa__) || defined(__powerpc64__) || defined (__alpha__) \
-- || defined (__x86_64__)
--typedef unsigned long __kernel_old_dev_t;
--#elif defined(__powerpc__) || defined(__ia64__) || (defined(__sparc__) && defined (__arch64__))
--typedef unsigned int __kernel_old_dev_t;
--#else
--typedef unsigned short __kernel_old_dev_t;
--#endif
--
--#define dev_t __kernel_old_dev_t
--
-+#include <asm/posix_types.h>
- #include <linux/loop.h>
- 
- #include "lopart.h"
-@@ -216,13 +205,13 @@ find_unused_loop_device (void)
- 		fprintf(stderr,
- 		    "mount: Could not find any loop device, and, according to %s,\n"
- 		    "       this kernel does not know about the loop device.\n"
--		    "       (If so, then recompile or `insmod loop.o'.)",
-+		    "       (If so, then recompile or `modprobe loop'.)",
- 		      PROC_DEVICES);
- 
- 	    else
- 		fprintf(stderr,
- 		    "mount: Could not find any loop device. Maybe this kernel does not know\n"
--		    "       about the loop device (then recompile or `insmod loop.o'), or\n"
-+		    "       about the loop device (then recompile or `modprobe loop'), or\n"
- 		    "       maybe /dev/loop# has the wrong major number?");
- 
- 	} else
-@@ -286,6 +275,7 @@ set_loop (const char *device, const char *file, int offset, int *loopro)
- extern int 
- del_loop (const char *device)
- {
-+	int retries = 3;
- 	int fd;
- 
- 	if ((fd = open (device, O_RDONLY)) < 0) {
-@@ -295,10 +285,17 @@ del_loop (const char *device)
- 		return 1;
- 	}
- 
--	if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
--		perror ("ioctl: LOOP_CLR_FD");
--		close (fd);
--		return 1;
-+	while (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
-+		if (errno != EBUSY || retries-- <= 0) {
-+			perror ("ioctl: LOOP_CLR_FD");
-+			close (fd);
-+			return 1;
-+		}
-+		fprintf(stderr,
-+			"loop: device %s still in use, retrying delete\n",
-+			device);
-+		sleep(1);
-+		continue;
- 	}
- 
- 	close (fd);
-diff --git a/kpartx/ps3.c b/kpartx/ps3.c
-new file mode 100644
-index 0000000..d1e5d64
---- /dev/null
-+++ b/kpartx/ps3.c
-@@ -0,0 +1,77 @@
-+#include "kpartx.h"
-+#include "byteorder.h"
-+#include <sys/types.h>
-+#include <string.h>
-+
-+#define SECTOR_SIZE		512
-+#define MAX_ACL_ENTRIES		8
-+#define MAX_PARTITIONS		8
-+
-+#define MAGIC1			0x0FACE0FFULL
-+#define MAGIC2			0xDEADFACEULL
-+
-+struct p_acl_entry {
-+	u_int64_t laid;
-+	u_int64_t rights;
-+};
-+
-+struct d_partition {
-+	u_int64_t p_start;
-+	u_int64_t p_size;
-+	struct p_acl_entry p_acl[MAX_ACL_ENTRIES];
-+};
-+
-+struct disklabel {
-+	u_int8_t d_res1[16];
-+	u_int64_t d_magic1;
-+	u_int64_t d_magic2;
-+	u_int64_t d_res2;
-+	u_int64_t d_res3;
-+	struct d_partition d_partitions[MAX_PARTITIONS];
-+	u_int8_t d_pad[0x600 - MAX_PARTITIONS * sizeof(struct d_partition)- 0x30];
-+};
-+
-+static int
-+read_disklabel(int fd, struct disklabel *label) {
-+	unsigned char *data;
-+	int i;
-+
-+	for (i = 0; i < sizeof(struct disklabel) / SECTOR_SIZE; i++) {
-+		data = (unsigned char *) getblock(fd, i);
-+		if (!data)
-+			return 0;
-+
-+		memcpy((unsigned char *) label + i * SECTOR_SIZE, data, SECTOR_SIZE);
-+	}
-+
-+	return 1;
-+}
-+
-+int
-+read_ps3_pt(int fd, struct slice all, struct slice *sp, int ns) {
-+	struct disklabel label;
-+        int n = 0;
-+	int i;
-+
-+	if (!read_disklabel(fd, &label))
-+		return -1;
-+
-+	if ((be64_to_cpu(label.d_magic1) != MAGIC1) ||
-+	    (be64_to_cpu(label.d_magic2) != MAGIC2))
-+		return -1;
-+
-+	for (i = 0; i < MAX_PARTITIONS; i++) {
-+		if (label.d_partitions[i].p_start && label.d_partitions[i].p_size) {
-+			sp[n].start =  be64_to_cpu(label.d_partitions[i].p_start);
-+			sp[n].size =  be64_to_cpu(label.d_partitions[i].p_size);
-+			n++;
-+		}
-+	}
-+
-+	return n;
-+}
-+
-+
-+
-+
-+
-diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile
-new file mode 100644
-index 0000000..c4ec1c5
---- /dev/null
-+++ b/libmpathpersist/Makefile
-@@ -0,0 +1,49 @@
-+# Makefile
-+#
-+BUILD = glibc
-+include ../Makefile.inc
-+
-+INSTALL_PROGRAM = install
-+
-+SONAME=0
-+DEVLIB = libmpathpersist.so
-+LIBS = $(DEVLIB).$(SONAME)
-+
-+
-+CFLAGS += -I$(multipathdir) -I$(mpathpersistdir) 
-+LIBDEPS +=  -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
-+
-+OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o 
-+
-+all: $(LIBS)
-+
-+
-+$(LIBS): 
-+	$(CC) -Wall -fPIC -c $(CFLAGS) *.c 
-+	$(CC)  -shared $(LIBDEPS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS)
-+	ln -s $(LIBS) $(DEVLIB)
-+	$(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz	
-+	$(GZIP) mpath_persistent_reserve_out.3 > mpath_persistent_reserve_out.3.gz	
-+
-+install: $(LIBS)
-+	$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
-+	$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
-+	$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir)
-+	$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir)
-+	$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)/usr/include/
-+	$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)/usr/share/doc/mpathpersist/
-+	ln -sf $(DESTDIR)$(syslibdir)/$(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
-+	install -m 644 mpath_persistent_reserve_in.3.gz $(DESTDIR)$(man3dir)	
-+	install -m 644 mpath_persistent_reserve_out.3.gz $(DESTDIR)$(man3dir)	
-+	install -m 644 mpath_persist.h $(DESTDIR)/usr/include/
-+
-+uninstall:
-+	rm -f $(DESTDIR)$(syslibdir)/$(LIBS)
-+	rm $(DESTDIR)$(mandir)/mpath_persistent_reserve_in.3.gz	
-+	rm $(DESTDIR)$(mandir)/mpath_persistent_reserve_out.3.gz	
-+
-+clean:
-+	rm -f core *.a *.o 
-+	rm -f libmpathpersist.so.0
-+	rm -f libmpathpersist.so
-+	rm -f mpath_persistent_reserve_in.3.gz mpath_persistent_reserve_out.3.gz
-diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
-new file mode 100644
-index 0000000..3041089
---- /dev/null
-+++ b/libmpathpersist/mpath_persist.c
-@@ -0,0 +1,884 @@
-+#include "mpath_persist.h"
-+#include <libdevmapper.h>
-+#include <defaults.h>
-+#include <sys/stat.h>
-+#include <linux/kdev_t.h>
-+#include <fcntl.h>
-+#include <vector.h>
-+#include <checkers.h>
-+#include <structs.h>
-+#include <structs_vec.h>
-+
-+#include <prio.h>
-+#include <unistd.h>
-+#include <devmapper.h>
-+#include <debug.h>
-+#include <config.h>
-+#include <switchgroup.h>
-+#include <discovery.h>
-+#include <dmparser.h>
-+#include <ctype.h>
-+#include <propsel.h>
-+
-+#include "mpathpr.h"
-+#include "mpath_pr_ioctl.h"
-+
-+#include <pthread.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#define __STDC_FORMAT_MACROS 1
-+
-+
-+int
-+mpath_lib_init (void)
-+{
-+	if (load_config(DEFAULT_CONFIGFILE)){
-+		condlog(0, "Failed to initialize multipath config.");
-+		return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+int
-+mpath_lib_exit (void)
-+{
-+	dm_lib_release();
-+	dm_lib_exit();
-+	cleanup_prio();
-+	cleanup_checkers();
-+	free_config(conf);
-+	conf = NULL;
-+	return 0;
-+}
-+
-+static int
-+updatepaths (struct multipath * mpp)
-+{
-+	int i, j;
-+	struct pathgroup * pgp;
-+	struct path * pp;
-+
-+	if (!mpp->pg)
-+		return 0;
-+
-+	vector_foreach_slot (mpp->pg, pgp, i){
-+		if (!pgp->paths)
-+			continue;
-+
-+		vector_foreach_slot (pgp->paths, pp, j){
-+			if (!strlen(pp->dev)){
-+				if (devt2devname(pp->dev, pp->dev_t)){
-+					/*
-+					 * path is not in sysfs anymore
-+					 */
-+					pp->state = PATH_DOWN;
-+					continue;
-+				}
-+				pp->mpp = mpp;
-+				pathinfo(pp, conf->hwtable, DI_ALL);
-+				continue;
-+			}
-+			pp->mpp = mpp;
-+			if (pp->state == PATH_UNCHECKED ||
-+					pp->state == PATH_WILD)
-+				pathinfo(pp, conf->hwtable, DI_CHECKER);
-+
-+			if (pp->priority == PRIO_UNDEF)
-+				pathinfo(pp, conf->hwtable, DI_PRIO);
-+		}
-+	}
-+	return 0;
-+}
-+
-+int 
-+mpath_prin_activepath (struct multipath *mpp, int rq_servact,
-+	struct prin_resp * resp, int noisy)
-+{
-+	int i,j, ret = MPATH_PR_DMMP_ERROR;
-+	struct pathgroup *pgp = NULL;
-+	struct path *pp = NULL;
-+
-+	vector_foreach_slot (mpp->pg, pgp, j){
-+		vector_foreach_slot (pgp->paths, pp, i){
-+			if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
-+				condlog(2, "%s: %s not available. Skip.", mpp->wwid, pp->dev);
-+				condlog(3, "%s: status = %d.", mpp->wwid, pp->state);
-+				continue;
-+			}
-+
-+			condlog(3, "%s: sending pr in command to %s ", mpp->wwid, pp->dev);
-+			ret = mpath_send_prin_activepath(pp->dev, rq_servact, resp, noisy);
-+			switch(ret)
-+			{
-+				case MPATH_PR_SUCCESS:
-+				case MPATH_PR_SENSE_INVALID_OP:
-+					return ret;
-+				default:
-+					continue;
-+			}
-+		}
-+	}
-+	return ret;	
-+}
-+
-+int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp *resp, int noisy, int verbose)
-+{
-+	struct stat info;
-+	vector curmp = NULL;
-+	vector pathvec = NULL;
-+	char * alias;
-+	struct multipath * mpp;
-+	int map_present;
-+	int major, minor;
-+	int ret;
-+
-+	conf->verbosity = verbose;
-+
-+	if (fstat( fd, &info) != 0){
-+		condlog(0, "stat error %d", fd);
-+		return MPATH_PR_FILE_ERROR;
-+	} 
-+	if(!S_ISBLK(info.st_mode)){
-+		condlog(0, "Failed to get major:minor. fd = %d", fd);
-+		return MPATH_PR_FILE_ERROR;
-+	}
-+
-+	major = (int)MAJOR(info.st_rdev);
-+	minor = (int)MINOR(info.st_rdev);	
-+	condlog(4, "Device %d:%d:  ", major, minor);
-+
-+	/* get alias from major:minor*/
-+	alias = dm_mapname(major, minor);
-+	if (!alias){
-+		condlog(0, "%d:%d failed to get device alias.", major, minor);
-+		return MPATH_PR_DMMP_ERROR;
-+	}
-+
-+	condlog(3, "alias = %s", alias);
-+	map_present = dm_map_present(alias);
-+	if (map_present && dm_type(alias, TGT_MPATH) <= 0){
-+		condlog( 0, "%s: not a multipath device.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out;
-+	}
-+
-+	/*
-+	 * allocate core vectors to store paths and multipaths
-+	 */
-+	curmp = vector_alloc ();
-+	pathvec = vector_alloc ();
-+
-+	if (!curmp || !pathvec){
-+		condlog (0, "%s: vector allocation failed.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out;
-+	}
-+
-+	if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER)) {
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out1;
-+	}
-+
-+	/* get info of all paths from the dm device	*/
-+	if (get_mpvec (curmp, pathvec, alias)){
-+		condlog(0, "%s: failed to get device info.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out1;
-+	}
-+
-+	mpp = find_mp_by_alias(curmp, alias);
-+	if (!mpp){
-+		condlog(0, "%s: devmap not registered.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out1;
-+	}
-+
-+	ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy);
-+
-+out1:
-+	free_multipathvec(curmp, KEEP_PATHS);
-+	free_pathvec(pathvec, FREE_PATHS);	
-+out:
-+	FREE(alias);
-+	return ret; 						
-+}
-+
-+int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
-+		unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose)
-+{
-+
-+	struct stat info;
-+
-+	vector curmp = NULL;
-+	vector pathvec = NULL;
-+
-+	char * alias;
-+	struct multipath * mpp;
-+	int map_present;
-+	int major, minor;
-+	int ret;
-+	int j;
-+	unsigned char *keyp;
-+	uint64_t prkey;		
-+
-+	conf->verbosity = verbose;
-+
-+	if (fstat( fd, &info) != 0){
-+		condlog(0, "stat error fd=%d", fd);
-+		return MPATH_PR_FILE_ERROR;
-+	}
-+
-+	if(!S_ISBLK(info.st_mode)){
-+		condlog(3, "Failed to get major:minor. fd=%d", fd);
-+		return MPATH_PR_FILE_ERROR;	
-+	}	
-+
-+	major = (int)MAJOR(info.st_rdev);
-+	minor = (int)MINOR(info.st_rdev);
-+	condlog(4, "Device  %d:%d", major, minor);
-+
-+	/* get WWN of the device from major:minor*/
-+	alias = dm_mapname(major, minor);
-+	if (!alias){
-+		return MPATH_PR_DMMP_ERROR;
-+	}
-+
-+	condlog(3, "alias = %s", alias);
-+	map_present = dm_map_present(alias);
-+
-+	if (map_present && dm_type(alias, TGT_MPATH) <= 0){
-+		condlog(3, "%s: not a multipath device.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out;
-+	}
-+
-+	/*
-+	 * allocate core vectors to store paths and multipaths
-+	 */
-+	curmp = vector_alloc ();
-+	pathvec = vector_alloc ();
-+
-+	 if (!curmp || !pathvec){
-+                condlog (0, "%s: vector allocation failed.", alias);
-+                ret = MPATH_PR_DMMP_ERROR;
-+                goto out;
-+        }
-+
-+	if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER)) {
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out1;
-+	}
-+
-+	/* get info of all paths from the dm device     */
-+	if (get_mpvec(curmp, pathvec, alias)){
-+		condlog(0, "%s: failed to get device info.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out1;
-+	}
-+
-+	mpp = find_mp_by_alias(curmp, alias);
-+
-+	if (!mpp) {
-+		condlog(0, "%s: devmap not registered.", alias);
-+		ret = MPATH_PR_DMMP_ERROR;
-+		goto out1;
-+	}
-+
-+	select_reservation_key(mpp);
-+
-+	switch(rq_servact)
-+	{
-+		case MPATH_PROUT_REG_SA: 
-+		case MPATH_PROUT_REG_IGN_SA:  
-+			ret= mpath_prout_reg(mpp, rq_servact, rq_scope, rq_type, paramp, noisy);
-+			break;
-+		case MPATH_PROUT_RES_SA :  
-+		case MPATH_PROUT_PREE_SA :  
-+		case MPATH_PROUT_PREE_AB_SA :  
-+		case MPATH_PROUT_CLEAR_SA:  
-+			ret = mpath_prout_common(mpp, rq_servact, rq_scope, rq_type, paramp, noisy);
-+			break;
-+		case MPATH_PROUT_REL_SA:
-+			ret = mpath_prout_rel(mpp, rq_servact, rq_scope, rq_type, paramp, noisy);
-+			break;
-+		default:
-+			ret = MPATH_PR_OTHER;
-+			goto out1;
-+	}
-+
-+	if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_REG_SA) ||
-+				(rq_servact ==  MPATH_PROUT_REG_IGN_SA)))
-+	{
-+		keyp=paramp->sa_key;
-+		prkey = 0;
-+		for (j = 0; j < 8; ++j) {
-+			if (j > 0)
-+				prkey <<= 8;
-+			prkey |= *keyp;
-+			++keyp;
-+		}
-+		if (prkey == 0)
-+			update_prflag(alias, "unset", noisy);
-+		else
-+			update_prflag(alias, "set", noisy);
-+	} else {
-+		if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_CLEAR_SA) || 
-+					(rq_servact == MPATH_PROUT_PREE_AB_SA ))){
-+			update_prflag(alias, "unset", noisy);
-+		}
-+	}
-+out1:
-+	free_multipathvec(curmp, KEEP_PATHS);
-+	free_pathvec(pathvec, FREE_PATHS);
-+
-+out:
-+	FREE(alias);
-+	return ret; 
-+}
-+
-+int
-+get_mpvec (vector curmp, vector pathvec, char * refwwid)
-+{
-+	int i;
-+	struct multipath *mpp;
-+	char params[PARAMS_SIZE], status[PARAMS_SIZE];
-+
-+	if (dm_get_maps (curmp)){
-+		return 1;
-+	}
-+
-+	vector_foreach_slot (curmp, mpp, i){
-+		/*
-+		 * discard out of scope maps
-+		 */
-+		if (mpp->alias && refwwid && strncmp (mpp->alias, refwwid, WWID_SIZE)){
-+			free_multipath (mpp, KEEP_PATHS);
-+			vector_del_slot (curmp, i);
-+			i--;
-+			continue;
-+		}
-+
-+		dm_get_map(mpp->alias, &mpp->size, params);
-+		condlog(3, "params = %s", params);
-+		dm_get_status(mpp->alias, status);
-+                condlog(3, "status = %s", status);
-+		disassemble_map (pathvec, params, mpp);
-+		
-+		/*
-+		 * disassemble_map() can add new paths to pathvec.
-+		 * If not in "fast list mode", we need to fetch information
-+		 * about them
-+		 */
-+		updatepaths(mpp);
-+		mpp->bestpg = select_path_group (mpp);
-+		disassemble_status (status, mpp);
-+
-+	}
-+	return MPATH_PR_SUCCESS ;
-+}
-+
-+void * mpath_prin_pthread_fn (void *p)
-+{
-+	int ret;
-+	struct prin_param * pparam = (struct prin_param *)p;
-+
-+	ret = prin_do_scsi_ioctl(pparam->dev, pparam->rq_servact, pparam->resp,  pparam->noisy);
-+	pparam->status = ret;	
-+	pthread_exit(NULL);	
-+}
-+
-+int mpath_send_prin_activepath (char * dev, int rq_servact, struct prin_resp * resp, int noisy)
-+{
-+
-+	int rc;
-+
-+	rc = prin_do_scsi_ioctl(dev, rq_servact, resp,  noisy);
-+	
-+	return (rc);
-+}
-+
-+int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
-+	unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
-+{
-+
-+	int i, j;
-+	struct pathgroup *pgp = NULL;
-+	struct path *pp = NULL;
-+	int rollback = 0;
-+	int active_pathcount=0;	
-+	int rc;
-+	int count=0;
-+	int status = MPATH_PR_SUCCESS;
-+	uint64_t sa_key = 0;
-+
-+	if (!mpp)
-+		return MPATH_PR_DMMP_ERROR; 
-+
-+	active_pathcount = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
-+
-+	if (active_pathcount == 0) {
-+		condlog (0, "%s: no path available", mpp->wwid);
-+		return MPATH_PR_DMMP_ERROR;
-+	}
-+
-+	if ( paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK ) {
-+		condlog (1, "Warning: ALL_TG_PT is set. Configuration not supported");
-+	}
-+
-+	struct threadinfo thread[active_pathcount];
-+
-+	memset(thread, 0, sizeof(thread));
-+
-+	/* init thread parameter */
-+	for (i =0; i< active_pathcount; i++){
-+		thread[i].param.rq_servact = rq_servact;
-+		thread[i].param.rq_scope = rq_scope;
-+		thread[i].param.rq_type = rq_type;
-+		thread[i].param.paramp = paramp;
-+		thread[i].param.noisy = noisy;
-+		thread[i].param.status = -1;
-+
-+		condlog (3, "THRED ID [%d] INFO]", i);
-+		condlog (3, "rq_servact=%d ", thread[i].param.rq_servact);
-+		condlog (3, "rq_scope=%d ", thread[i].param.rq_scope); 
-+		condlog (3, "rq_type=%d ", thread[i].param.rq_type);  
-+		condlog (3, "rkey="); 
-+		condlog (3, "paramp->sa_flags =%02x ", thread[i].param.paramp->sa_flags); 
-+		condlog (3, "noisy=%d ", thread[i].param.noisy); 
-+		condlog (3, "status=%d ", thread[i].param.status); 
-+	}
-+
-+	pthread_attr_t attr;
-+	pthread_attr_init(&attr);
-+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-+
-+	vector_foreach_slot (mpp->pg, pgp, j){
-+		vector_foreach_slot (pgp->paths, pp, i){
-+			if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
-+				condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev);
-+				continue;
-+			}
-+			strncpy(thread[count].param.dev, pp->dev, FILE_NAME_SIZE);
-+
-+			if (count && (thread[count].param.paramp->sa_flags & MPATH_F_SPEC_I_PT_MASK)){
-+				/*
-+				 * Clearing SPEC_I_PT as transportids are already registered by now.
-+				 */
-+				thread[count].param.paramp->sa_flags &= (~MPATH_F_SPEC_I_PT_MASK);
-+			}
-+
-+			condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev);
-+
-+			rc = pthread_create(&thread[count].id, &attr, mpath_prout_pthread_fn, (void *)(&thread[count].param));
-+			if (rc){
-+				condlog (0, "%s: failed to create thread %d", mpp->wwid, rc);
-+			}
-+			count = count +1;
-+		}
-+	}
-+	for( i=0; i < active_pathcount ; i++){
-+		rc = pthread_join(thread[i].id, NULL);
-+		if (rc){
-+			condlog (0, "%s: Thread[%d] failed to join thread %d", mpp->wwid, i, rc);
-+		}
-+		if (!rollback && (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)){
-+			rollback = 1;
-+			sa_key = 0;
-+			for (i = 0; i < 8; ++i){
-+				if (i > 0)
-+					sa_key <<= 8;
-+				sa_key |= paramp->sa_key[i];
-+			}
-+			status = MPATH_PR_RESERV_CONFLICT ;
-+		}
-+		if (!rollback && (status == MPATH_PR_SUCCESS)){
-+			status = thread[i].param.status;
-+		}
-+	}
-+	if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){
-+		condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid);
-+		for( i=0 ; i < active_pathcount ; i++){
-+			if((thread[i].param.status == MPATH_PR_SUCCESS) &&
-+					((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
-+				memcpy(&thread[i].param.paramp->key, &thread[i].param.paramp->sa_key, 8);
-+				memset(&thread[i].param.paramp->sa_key, 0, 8);
-+				thread[i].param.status = MPATH_PR_SUCCESS;
-+				rc = pthread_create(&thread[i].id, &attr, mpath_prout_pthread_fn, 
-+						(void *)(&thread[count].param));
-+				if (rc){
-+					condlog (0, "%s: failed to create thread for rollback. %d",  mpp->wwid, rc);
-+				}
-+			}
-+		}
-+		for(i=0; i < active_pathcount ; i++){
-+			rc = pthread_join(thread[i].id, NULL);
-+			if (rc){
-+				condlog (3, "%s: failed to join thread while rolling back %d",
-+						mpp->wwid, i);
-+			}
-+		}
-+	}
-+
-+	pthread_attr_destroy(&attr);
-+	return (status);
-+}
-+
-+void * mpath_prout_pthread_fn(void *p)
-+{
-+	int ret;
-+	struct prout_param * param = (struct prout_param *)p;
-+
-+	ret = prout_do_scsi_ioctl( param->dev,param->rq_servact, param->rq_scope,
-+			param->rq_type, param->paramp, param->noisy);
-+	param->status = ret;
-+	pthread_exit(NULL);
-+}
-+
-+int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope,
-+        unsigned int rq_type, struct prout_param_descriptor* paramp, int noisy)
-+{
-+	int i,j, ret;
-+	struct pathgroup *pgp = NULL;
-+	struct path *pp = NULL;
-+
-+	vector_foreach_slot (mpp->pg, pgp, j){
-+		vector_foreach_slot (pgp->paths, pp, i){
-+			if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
-+				condlog (1, "%s: %s path not up. Skip", mpp->wwid, pp->dev); 
-+				continue;
-+			}
-+
-+			condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev);
-+			ret = send_prout_activepath(pp->dev, rq_servact, rq_scope, rq_type, 
-+					paramp, noisy); 
-+			return ret ;
-+		}
-+	}
-+	return MPATH_PR_SUCCESS;
-+}
-+
-+int send_prout_activepath(char * dev, int rq_servact, int rq_scope,
-+	unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
-+{
-+	struct prout_param param;
-+	param.rq_servact = rq_servact;
-+	param.rq_scope  = rq_scope;
-+	param.rq_type   = rq_type;
-+	param.paramp    = paramp;
-+	param.noisy = noisy;
-+	param.status = -1;
-+
-+	pthread_t thread;
-+	pthread_attr_t attr;
-+	int rc;
-+
-+	memset(&thread, 0, sizeof(thread));
-+	strncpy(param.dev, dev, FILE_NAME_SIZE);
-+	/* Initialize and set thread joinable attribute */
-+	pthread_attr_init(&attr);
-+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-+
-+	rc = pthread_create(&thread, &attr, mpath_prout_pthread_fn, (void *)(&param));
-+	if (rc){
-+		condlog (3, "%s: failed to create thread %d", dev, rc);
-+		exit(-1);
-+	}
-+	/* Free attribute and wait for the other threads */
-+	pthread_attr_destroy(&attr);
-+	rc = pthread_join(thread, NULL);
-+
-+	return (param.status);
-+}
-+
-+int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
-+        unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
-+{
-+	int i, j;
-+	int num = 0;
-+	struct pathgroup *pgp = NULL;
-+	struct path *pp = NULL;
-+	int active_pathcount = 0;
-+	pthread_attr_t attr;
-+	int rc, found = 0;;
-+	int count = 0;
-+	int status = MPATH_PR_SUCCESS;
-+	struct prin_resp resp;
-+	struct prout_param_descriptor *pamp;
-+	struct prin_resp *pr_buff;
-+	int length;
-+	struct transportid *pptr;	
-+
-+	if (!mpp)
-+		return MPATH_PR_DMMP_ERROR;
-+
-+	active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST);
-+
-+	struct threadinfo thread[active_pathcount];
-+	memset(thread, 0, sizeof(thread));
-+	for (i = 0; i < active_pathcount; i++){
-+		thread[i].param.rq_servact = rq_servact;
-+		thread[i].param.rq_scope = rq_scope;
-+		thread[i].param.rq_type = rq_type;
-+		thread[i].param.paramp = paramp;
-+		thread[i].param.noisy = noisy;
-+		thread[i].param.status = -1;
-+
-+		condlog (3, " path count = %d", i);
-+		condlog (3, "rq_servact=%d ", thread[i].param.rq_servact);
-+		condlog (3, "rq_scope=%d ", thread[i].param.rq_scope);
-+		condlog (3, "rq_type=%d ", thread[i].param.rq_type);
-+		condlog (3, "noisy=%d ", thread[i].param.noisy);
-+		condlog (3, "status=%d ", thread[i].param.status);
-+	}
-+
-+	pthread_attr_init (&attr);
-+	pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
-+
-+	vector_foreach_slot (mpp->pg, pgp, j){
-+		vector_foreach_slot (pgp->paths, pp, i){
-+			if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
-+				condlog (1, "%s: %s path not up.", mpp->wwid, pp->dev);
-+				continue;
-+			}
-+			
-+			strncpy(thread[count].param.dev, pp->dev, FILE_NAME_SIZE);
-+			condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev);
-+			rc = pthread_create (&thread[count].id, &attr, mpath_prout_pthread_fn,
-+					(void *) (&thread[count].param));
-+			if (rc)
-+				condlog (0, "%s: failed to create thread. %d",  mpp->wwid, rc);
-+			count = count + 1;
-+		}
-+	}
-+	pthread_attr_destroy (&attr);
-+	for (i = 0; i < active_pathcount; i++){
-+		rc = pthread_join (thread[i].id, NULL);
-+		if (rc){
-+			condlog (1, "%s: failed to join thread.  %d",  mpp->wwid,  rc);
-+		}
-+	}
-+
-+	for (i = 0; i < active_pathcount; i++){
-+		/*  check thread status here and return the status */
-+
-+		if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)
-+			status = MPATH_PR_RESERV_CONFLICT;
-+		else if (status == MPATH_PR_SUCCESS
-+				&& thread[i].param.status != MPATH_PR_RESERV_CONFLICT)
-+			status = thread[i].param.status;
-+	}
-+
-+	status = mpath_prin_activepath (mpp, MPATH_PRIN_RRES_SA, &resp, noisy);
-+	if (status != MPATH_PR_SUCCESS){
-+		condlog (0, "%s: pr in read reservation command failed.", mpp->wwid);
-+		return MPATH_PR_OTHER;
-+	}
-+
-+	num = resp.prin_descriptor.prin_readresv.additional_length / 8;
-+	if (num == 0){
-+		condlog (2, "%s: Path holding reservation is released.", mpp->wwid);
-+		return MPATH_PR_SUCCESS;	
-+	}
-+	condlog (2, "%s: Path holding reservation is not avialable.", mpp->wwid);
-+
-+	pr_buff =  mpath_alloc_prin_response(MPATH_PRIN_RFSTAT_SA);
-+	if (!pr_buff){
-+		condlog (0, "%s: failed to  alloc pr in response buffer.", mpp->wwid);	
-+		return MPATH_PR_OTHER;
-+	}
-+
-+	status = mpath_prin_activepath (mpp, MPATH_PRIN_RFSTAT_SA, pr_buff, noisy);
-+
-+	if (status != MPATH_PR_SUCCESS){
-+		condlog (0,  "%s: pr in read full status command failed.",  mpp->wwid);
-+		goto out;
-+	}
-+
-+	num = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor;
-+	if (0 == num){
-+		goto out;
-+	}
-+	length = sizeof (struct prout_param_descriptor) + (sizeof (struct transportid *));
-+
-+	pamp = (struct prout_param_descriptor *)malloc (length);
-+	if (!pamp){
-+		condlog (0, "%s: failed to alloc pr out parameter.", mpp->wwid);
-+		goto out1;
-+	}
-+
-+	memset(pamp, 0, length);
-+
-+	pamp->trnptid_list[0] = (struct transportid *) malloc (sizeof (struct transportid));
-+	if (!pamp->trnptid_list[0]){
-+		condlog (0, "%s: failed to alloc pr out transportid.", mpp->wwid);
-+		goto out1;
-+	}
-+
-+	if (mpp->reservation_key ){
-+		memcpy (pamp->key, mpp->reservation_key, 8);
-+		condlog (3, "%s: reservation key set.", mpp->wwid);
-+	}
-+
-+	mpath_prout_common (mpp, MPATH_PROUT_CLEAR_SA, rq_scope, rq_type, pamp,
-+			noisy);
-+
-+	pamp->num_transportid = 1;
-+	pptr=pamp->trnptid_list[0];
-+
-+	for (i = 0; i < num; i++){
-+		if (mpp->reservation_key && 
-+			memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key,
-+			mpp->reservation_key, 8)){	
-+			/*register with tarnsport id*/
-+			memset(pamp, 0, length);
-+			pamp->trnptid_list[0] = pptr;
-+			memset (pamp->trnptid_list[0], 0, sizeof (struct transportid));
-+			memcpy (pamp->sa_key,
-+					pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8);
-+			pamp->sa_flags = MPATH_F_SPEC_I_PT_MASK;
-+			pamp->num_transportid = 1;
-+
-+			memcpy (pamp->trnptid_list[0],
-+					&pr_buff->prin_descriptor.prin_readfd.descriptors[i]->trnptid,
-+					sizeof (struct transportid));
-+			status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type,
-+					pamp, noisy);
-+
-+			pamp->sa_flags = 0;
-+			memcpy (pamp->key, pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8);
-+			memset (pamp->sa_key, 0, 8);
-+			pamp->num_transportid = 0;
-+			status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type,
-+					pamp, noisy);
-+		}
-+		else
-+		{
-+			if (mpp->reservation_key)
-+				found = 1;
-+		}
-+
-+
-+	}
-+
-+	if (found){
-+		memset (pamp, 0, length);
-+		memcpy (pamp->sa_key, mpp->reservation_key, 8);
-+		memset (pamp->key, 0, 8);
-+		status = mpath_prout_reg(mpp, MPATH_PROUT_REG_SA, rq_scope, rq_type, pamp, noisy);	
-+	}
-+
-+
-+	free(pptr);
-+out1:
-+	free (pamp);
-+out:
-+	free (pr_buff);
-+	return (status);
-+}
-+
-+void * mpath_alloc_prin_response(int prin_sa)
-+{
-+	void * ptr = NULL;
-+	int size=0;
-+	switch (prin_sa)
-+	{
-+		case MPATH_PRIN_RKEY_SA:
-+			size = sizeof(struct prin_readdescr);
-+			ptr = malloc(size);
-+			memset(ptr, 0, size);
-+			break;
-+		case MPATH_PRIN_RRES_SA:
-+			size = sizeof(struct prin_resvdescr);
-+			ptr = malloc(size);
-+			memset(ptr, 0, size);
-+			break;
-+		case MPATH_PRIN_RCAP_SA:
-+			size=sizeof(struct prin_capdescr);
-+			ptr = malloc(size);
-+			memset(ptr, 0, size);
-+			break;
-+		case MPATH_PRIN_RFSTAT_SA:
-+			size = sizeof(struct print_fulldescr_list) + 
-+				sizeof(struct prin_fulldescr *)*MPATH_MX_TIDS;
-+			ptr = malloc(size);
-+			memset(ptr, 0, size);
-+			break;
-+	}
-+	return ptr;
-+}
-+
-+int update_map_pr(struct multipath *mpp)
-+{
-+	int noisy=0;
-+	struct prin_resp *resp;
-+	int i,j, ret, isFound;
-+	unsigned char *keyp;
-+	uint64_t prkey;
-+
-+	if (!mpp->reservation_key)
-+	{
-+		/* Nothing to do. Assuming pr mgmt feature is disabled*/
-+		condlog(3, "%s: reservation_key not set in multiapth.conf", mpp->alias);
-+		return MPATH_PR_SUCCESS;
-+	}
-+
-+	resp = mpath_alloc_prin_response(MPATH_PRIN_RKEY_SA);
-+	if (!resp)
-+	{
-+		condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias);
-+		return MPATH_PR_OTHER;
-+	}
-+	ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy);
-+
-+	if (ret != MPATH_PR_SUCCESS )
-+	{
-+		condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret);
-+		free(resp);
-+		return  ret;
-+	}
-+
-+	if (resp->prin_descriptor.prin_readkeys.additional_length == 0 )
-+	{
-+		condlog(0,"%s: No key found. Device may not be registered. ", mpp->alias);
-+		free(resp);
-+		return MPATH_PR_SUCCESS;
-+	}
-+
-+	prkey = 0;
-+	keyp = mpp->reservation_key;
-+	for (j = 0; j < 8; ++j) {
-+		if (j > 0)
-+			prkey <<= 8;
-+		prkey |= *keyp;
-+		++keyp;
-+	}
-+	condlog(2, "%s: Multipath  reservation_key: 0x%" PRIx64 " ", mpp->alias, prkey);
-+
-+	isFound =0;
-+	for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ )
-+	{
-+		condlog(2, "%s: PR IN READKEYS[%d]  reservation key:", mpp->alias, i);
-+		dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , 1);
-+
-+		if (!memcmp(mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
-+		{
-+			condlog(2, "%s: reservation key found in pr in readkeys response", mpp->alias);
-+			isFound =1;
-+		}
-+	}
-+
-+	if (isFound)
-+	{
-+		mpp->prflag = 1;
-+		condlog(2, "%s: prflag flag set.", mpp->alias );
-+	}
-+
-+	free(resp);
-+	return MPATH_PR_SUCCESS;
-+}
-+
-+
-+
-diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h
-new file mode 100644
-index 0000000..d8ff6f2
---- /dev/null
-+++ b/libmpathpersist/mpath_persist.h
-@@ -0,0 +1,241 @@
-+/* version - 1.0 */
-+
-+#ifndef MPATH_PERSIST_LIB_H
-+#define MPATH_PERSIST_LIB_H
-+
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include <inttypes.h>
-+
-+#define MPATH_MAX_PARAM_LEN	8192
-+
-+#define MPATH_MX_TIDS 		32	  /* Max number of transport ids"*/
-+#define MPATH_MX_TID_LEN	256	  /* Max lenght of transport id */
-+
-+/* PRIN Service Actions */
-+#define MPATH_PRIN_RKEY_SA	0x00	   /* READ KEYS SA*/
-+#define MPATH_PRIN_RRES_SA	0x01	   /* READ RESERVATION  SA*/
-+#define MPATH_PRIN_RCAP_SA	0x02	   /* REPORT CAPABILITIES SA*/
-+#define MPATH_PRIN_RFSTAT_SA	0x03	   /* READ FULL STATUS SA*/
-+
-+/* PROUT Service Actions */
-+#define MPATH_PROUT_REG_SA	0x00	    /* REGISTER SA */
-+#define MPATH_PROUT_RES_SA	0x01	    /* RESERVE SA*/
-+#define MPATH_PROUT_REL_SA	0x02	    /* RELEASE SA*/
-+#define MPATH_PROUT_CLEAR_SA	0x03	    /* CLEAR SA*/
-+#define MPATH_PROUT_PREE_SA	0x04	    /* PREEMPT SA*/
-+#define MPATH_PROUT_PREE_AB_SA	0x05	    /* PREEMPT AND ABORT SA*/
-+#define MPATH_PROUT_REG_IGN_SA	0x06	    /* REGISTER AND IGNORE EXISTING KEY SA*/
-+#define MPATH_PROUT_REG_MOV_SA	0x07	    /* REGISTER AND MOVE SA*/
-+
-+#define MPATH_LU_SCOPE		0x00	    /* LU_SCOPE */
-+
-+/* Persistent reservations type */
-+#define MPATH_PRTPE_WE	 	0x01	    /* Write Exclusive */
-+#define MPATH_PRTPE_EA 		0x03	    /* Exclusive Access*/
-+#define MPATH_PRTPE_WE_RO 	0x05	    /* WriteExclusive Registrants Only */
-+#define MPATH_PRTPE_EA_RO 	0x06	    /* Exclusive Access. Registrants Only*/
-+#define MPATH_PRTPE_WE_AR	0x07	    /* Write Exclusive. All Registrants*/
-+#define MPATH_PRTPE_EA_AR 	0x08	    /* Exclusive Access. All Registrants */
-+
-+
-+/* PR RETURN_STATUS */
-+#define MPATH_PR_SUCCESS 		0
-+#define MPATH_PR_SYNTAX_ERROR		1   /*  syntax error or invalid parameter */
-+					    /* status for check condition */
-+#define MPATH_PR_SENSE_NOT_READY 	2   /*	[sk,asc,ascq: 0x2,*,*] */
-+#define MPATH_PR_SENSE_MEDIUM_ERROR	3   /*	[sk,asc,ascq: 0x3,*,*] */
-+#define MPATH_PR_SENSE_HARDWARE_ERROR	4   /*	[sk,asc,ascq: 0x4,*,*] */
-+#define MPATH_PR_ILLEGAL_REQ 		5   /*	[sk,asc,ascq: 0x5,*,*]*/
-+#define MPATH_PR_SENSE_UNIT_ATTENTION	6   /*	[sk,asc,ascq: 0x6,*,*] */
-+#define MPATH_PR_SENSE_INVALID_OP	7   /* 	[sk,asc,ascq: 0x5,0x20,0x0]*/
-+#define MPATH_PR_SENSE_ABORTED_COMMAND  8   /*  [sk,asc,ascq: 0xb,*,*] */
-+#define MPATH_PR_NO_SENSE		9   /*	[sk,asc,ascq: 0x0,*,*] */
-+
-+#define MPATH_PR_SENSE_MALFORMED	10  /* Response to SCSI command malformed */
-+#define MPATH_PR_RESERV_CONFLICT	11  /* Reservation conflict on the device */
-+#define MPATH_PR_FILE_ERROR		12  /* file (device node) problems(e.g. not found)*/
-+#define MPATH_PR_DMMP_ERROR		13  /* DMMP related error.(e.g Error in getting dm info */
-+#define MPATH_PR_OTHER			14  /*other error/warning has occurred(transport
-+					      or driver error) */
-+
-+/* PR MASK */
-+#define MPATH_F_APTPL_MASK		0x01	/* APTPL MASK*/
-+#define MPATH_F_ALL_TG_PT_MASK		0x04	/* ALL_TG_PT MASK*/
-+#define MPATH_F_SPEC_I_PT_MASK		0x08	/* SPEC_I_PT MASK*/
-+#define MPATH_PR_TYPE_MASK 		0x0f	/* TYPE MASK*/
-+#define MPATH_PR_SCOPE_MASK		0xf0	/* SCOPE MASK*/
-+
-+/*Transport ID PROTOCOL IDENTIFIER values */
-+#define MPATH_PROTOCOL_ID_FC		0x00
-+#define MPATH_PROTOCOL_ID_ISCSI		0x05
-+#define MPATH_PROTOCOL_ID_SAS		0x06
-+
-+
-+/*Transport ID FORMATE CODE */
-+#define MPATH_WWUI_DEVICE_NAME		0x00	/* World wide unique initiator device name */
-+#define MPATH_WWUI_PORT_IDENTIFIER	0x40	/* World wide unique initiator port identifier	*/
-+
-+
-+
-+
-+struct prin_readdescr
-+{
-+	uint32_t prgeneration;
-+	uint32_t additional_length;	/* The value should be either 0 or divisible by 8.
-+					   0 indicates no registered reservation key. */
-+	uint8_t	 key_list[MPATH_MAX_PARAM_LEN];
-+};
-+
-+struct prin_resvdescr
-+{
-+	uint32_t prgeneration;
-+	uint32_t additional_length;	/* The value should be either 0 or 10h. 0 indicates
-+					   there is no reservation held. 10h indicates the
-+					   key[8] and scope_type have valid values */
-+	uint8_t  key[8];
-+	uint32_t _obsolete;
-+	uint8_t  _reserved;
-+	uint8_t  scope_type;            /* Use PR SCOPE AND TYPE MASK specified above */
-+	uint16_t _obsolete1;
-+};
-+
-+struct prin_capdescr
-+{
-+	uint16_t length;
-+	uint8_t  flags[2];
-+	uint16_t pr_type_mask;
-+	uint16_t _reserved;
-+};
-+
-+struct transportid
-+{
-+	uint8_t format_code;
-+	uint8_t protocol_id;
-+	union {
-+		uint8_t n_port_name[8];	/* FC transport*/
-+		uint8_t sas_address[8];	/* SAS transport */
-+		uint8_t iscsi_name[256]; /* ISCSI  transport */
-+	};
-+};
-+
-+struct prin_fulldescr
-+{
-+	uint8_t key[8];
-+	uint8_t flag; 			/* All_tg_pt and reservation holder */
-+	uint8_t scope_type;		/* Use PR SCOPE AND TYPE MASK specified above.
-+					   Meaningful only for reservation holder */
-+	uint16_t rtpi;
-+	struct transportid trnptid;
-+};
-+
-+struct print_fulldescr_list
-+{
-+	uint32_t prgeneration;
-+	uint32_t number_of_descriptor;
-+	uint8_t private_buffer[MPATH_MAX_PARAM_LEN]; /*Private buffer for list storage*/
-+	struct prin_fulldescr *descriptors[];
-+};
-+
-+struct prin_resp
-+{
-+	union
-+	{
-+		struct prin_readdescr prin_readkeys; /* for PRIN read keys SA*/
-+		struct prin_resvdescr prin_readresv; /* for PRIN read reservation SA*/
-+		struct prin_capdescr  prin_readcap;  /* for PRIN Report Capabilities SA*/
-+		struct print_fulldescr_list prin_readfd;   /* for PRIN read full status SA*/
-+	}prin_descriptor;
-+};
-+
-+struct prout_param_descriptor { 	/* PROUT parameter descriptor */
-+	uint8_t	 key[8];
-+	uint8_t	 sa_key[8];
-+	uint32_t _obsolete;
-+	uint8_t	 sa_flags;
-+	uint8_t _reserved;
-+	uint16_t _obsolete1;
-+	uint8_t  private_buffer[MPATH_MAX_PARAM_LEN]; /*private buffer for list storage*/
-+	uint32_t num_transportid;	/* Number of Transport ID listed in trnptid_list[]*/
-+	struct transportid *trnptid_list[];
-+};
-+
-+
-+/* Function declarations */
-+
-+/*
-+ * DESCRIPTION :
-+ *	Initialize device mapper multipath configuration. This function must be invoked first
-+ *	before performing reservation management functions.
-+ * RESTRICTIONS:
-+ *
-+ * RETURNS: 0->Success, 1->Failed.
-+ */
-+extern int mpath_lib_init (void );
-+
-+
-+/*
-+ * DESCRIPTION :
-+ *	Release device mapper multipath configuration. This function must be invoked after
-+ *	performing reservation management functions.
-+ * RESTRICTIONS:
-+ *
-+ * RETURNS: 0->Success, 1->Failed.
-+ */
-+extern int mpath_lib_exit (void );
-+
-+
-+/*
-+ * DESCRIPTION :
-+ * This function sends PRIN command to the DM device and get the response.
-+ *
-+ * @fd:	The file descriptor of a multipath device. Input argument.
-+ * @rq_servact: PRIN command service action. Input argument
-+ * @resp: The response from PRIN service action. The resp is a struct specified above. The caller should
-+ * 	manage the memory allocation of this struct
-+ * @noisy: Turn on debugging trace: Input argument. 0->Disable, 1->Enable
-+ * @verbose: Set verbosity level. Input argument. value:[0-3]. 0->disabled, 3->Max verbose
-+ *
-+ * RESTRICTIONS:
-+ *
-+ * RETURNS: MPATH_PR_SUCCESS if PR command successful else returns any of the status specified
-+ *       above in RETURN_STATUS.
-+ *
-+ */
-+extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp *resp,
-+		int noisy, int verbose);
-+
-+/*
-+ * DESCRIPTION :
-+ * This function sends PROUT command to the DM device and get the response.
-+ *
-+ * @fd: The file descriptor of a multipath device. Input argument.
-+ * @rq_servact: PROUT command service action. Input argument
-+ * @rq_scope: Persistent reservation scope. The value should be always LU_SCOPE (0h).
-+ * @rq_type: Persistent reservation type. The valid values of persistent reservation types are
-+ *	5h (Write exclusive - registrants only)
-+ *	6h (Exclusive access - registrants only)
-+ *	7h (Write exclusive - All registrants)
-+ *	8h (Exclusive access - All registrants).
-+ * @paramp: PROUT command parameter data. The paramp is a struct which describes PROUT
-+ * 	    parameter list. The caller should manage the memory allocation of this struct.
-+ * @noisy: Turn on debugging trace: Input argument.0->Disable, 1->Enable.
-+ * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 3->Max verbose
-+ *
-+ * RESTRICTIONS:
-+ *
-+ * RETURNS: MPATH_PR_SUCCESS if PR command successful else returns any of the status specified
-+ *       above in RETURN_STATUS.
-+ */
-+extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
-+		unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy,
-+		int verbose);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif  /*MPATH_PERSIST_LIB_H*/
-diff --git a/libmpathpersist/mpath_persistent_reserve_in.3 b/libmpathpersist/mpath_persistent_reserve_in.3
-new file mode 100644
-index 0000000..c404e13
---- /dev/null
-+++ b/libmpathpersist/mpath_persistent_reserve_in.3
-@@ -0,0 +1,80 @@
-+.\"
-+.TH MPATH_PERSISTENT_RESERVE_IN 3  2011-04-08 "Linux Manpage" 
-+.SH NAME
-+mpath_persistent_reserve_in
-+.SH SYNOPSIS
-+.B #include <mpath_persist.h>
-+.sp
-+.BI "int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp *resp, int noisy, int verbose)"
-+.sp
-+.SH DESCRIPTION
-+The function in the
-+.BR mpath_persistent_reserve_in ()
-+sends PRIN command to the DM device and gets the response.
-+.br
-+.BI Parameters:
-+.br
-+.I fd
-+.B The file descriptor of a multipath device. Input argument.
-+.br
-+.I rq_servact
-+.B PRIN command service action. Input argument
-+.br
-+.I resp
-+.B The response from PRIN service action. The caller should manage the memory allocation of this structure
-+.br
-+.I noisy
-+.B Turn on debugging trace: Input argument. 0->Disable, 1->Enable
-+.br
-+.I verbose
-+.B Set verbosity level. Input argument. value:[0-3]. 0->Crits and Errors, 1->Warnings, 2->Info, 3->Debug
-+.br
-+
-+.SH "RETURNS"
-+.I MPATH_PR_SUCCESS
-+.B if PR command successful
-+.br
-+.I MPATH_PR_SYNTAX_ERROR        
-+.B if  syntax error or invalid parameter
-+.br
-+.I MPATH_PR_SENSE_NOT_READY     
-+.B  if command fails with [sk,asc,ascq: 0x2,*,*]
-+.br
-+.I MPATH_PR_SENSE_MEDIUM_ERROR
-+.B  if command fails with [sk,asc,ascq: 0x3,*,*]
-+.br
-+.I MPATH_PR_SENSE_HARDWARE_ERROR
-+.B  if command fails with [sk,asc,ascq: 0x4,*,*]
-+.br
-+.I MPATH_PR_SENSE_INVALID_OP
-+.B  if command fails with [sk,asc,ascq: 0x5,0x20,0x0]
-+.br
-+.I MPATH_PR_ILLEGAL_REQ
-+.B  if command fails with [sk,asc,ascq: 0x5,*,*]
-+.br
-+.I MPATH_PR_SENSE_UNIT_ATTENTION
-+.B  if command fails with [sk,asc,ascq: 0x6,*,*]
-+.br
-+.I MPATH_PR_SENSE_ABORTED_COMMAND
-+.B  if command fails with [sk,asc,ascq: 0xb,*,*]
-+.br
-+.I MPATH_PR_NO_SENSE
-+.B  if command fails with [sk,asc,ascq: 0x0,*,*]
-+.br
-+.I MPATH_PR_SENSE_MALFORMED  
-+.B if command fails with SCSI command malformed
-+.br
-+.I MPATH_PR_FILE_ERROR
-+.B if command fails while accessing file (device node) problems(e.g. not found)
-+.br
-+.I MPATH_PR_DMMP_ERROR
-+.B if Device Mapper related error.(e.g Error in getting dm info) 
-+.br
-+.I MPATH_PR_OTHER
-+.B if other error/warning has occurred(e.g transport or driver error)
-+.br
-+
-+
-+.SH "SEE ALSO"
-+.I  mpath_persistent_reserve_out      mpathpersist     /usr/share/doc/mpathpersist/README
-+.br
-diff --git a/libmpathpersist/mpath_persistent_reserve_out.3 b/libmpathpersist/mpath_persistent_reserve_out.3
-new file mode 100644
-index 0000000..f7f84ff
---- /dev/null
-+++ b/libmpathpersist/mpath_persistent_reserve_out.3
-@@ -0,0 +1,92 @@
-+.\"
-+.TH MPATH_PERSISTENT_RESERVE_OUT 3  2011-04-08 "Linux Manpage" 
-+.SH NAME
-+mpath_persistent_reserve_out
-+.SH SYNOPSIS
-+.B #include <mpath_persist.h>
-+.sp
-+.BI "int mpath_persistent_reserve_out (int fd, int rq_servact, struct prin_resp *resp, int noisy, int verbose)"
-+.sp
-+.SH DESCRIPTION
-+The function in the
-+.BR mpath_persistent_reserve_out ()
-+sends PR OUT command to the DM device and gets the response.
-+.br
-+.BI Parameters:
-+.br
-+.I fd 
-+.B The file descriptor of a multipath device. Input argument.
-+.br
-+.I rq_servact
-+.B PROUT command service action. Input argument
-+.br
-+.I rq_scope
-+.B Persistent reservation scope. The value should be always LU_SCOPE (0h).
-+.br
-+.I rq_type
-+.B Persistent reservation type. The valid values of persistent reservation types are
-+      5h (Write exclusive - registrants only)
-+      6h (Exclusive access - registrants only)
-+      7h (Write exclusive - All registrants)
-+      8h (Exclusive access - All registrants).
-+.br
-+.I paramp
-+.B PROUT command parameter data. The paramp is a struct which describes PROUT parameter list. Caller should manage the memory allocation of this structure.
-+.br
-+.I noisy
-+.B Turn on debugging trace: Input argument. 0->Disable, 1->Enable.
-+.br
-+.I verbose
-+.B Set verbosity level. Input argument. value: 0 to 3. 0->Crits and Errors, 1->Warnings, 2->Info, 3->Debug
-+
-+.SH "RETURNS"
-+.I MPATH_PR_SUCCESS
-+.B if PR command successful else returns any one of the status mentioned below
-+.br
-+.I MPATH_PR_SYNTAX_ERROR        
-+.B if  syntax error or invalid parameter
-+.br
-+.I MPATH_PR_SENSE_NOT_READY     
-+.B  if command fails with [sk,asc,ascq: 0x2,*,*]
-+.br
-+.I MPATH_PR_SENSE_MEDIUM_ERROR
-+.B  if command fails with [sk,asc,ascq: 0x3,*,*]
-+.br
-+.I MPATH_PR_SENSE_HARDWARE_ERROR
-+.B  if command fails with [sk,asc,ascq: 0x4,*,*]
-+.br
-+.I MPATH_PR_SENSE_INVALID_OP
-+.B  if command fails with [sk,asc,ascq: 0x5,0x20,0x0]
-+.br
-+.I MPATH_PR_ILLEGAL_REQ
-+.B  if command fails with [sk,asc,ascq: 0x5,*,*]
-+.br
-+.I MPATH_PR_SENSE_UNIT_ATTENTION
-+.B  if command fails with [sk,asc,ascq: 0x6,*,*]
-+.br
-+.I MPATH_PR_SENSE_ABORTED_COMMAND
-+.B  if command fails with [sk,asc,ascq: 0xb,*,*]
-+.br
-+.I MPATH_PR_NO_SENSE
-+.B  if command fails with [sk,asc,ascq: 0x0,*,*]
-+.br
-+.I MPATH_PR_SENSE_MALFORMED  
-+.B if command fails with SCSI command malformed
-+.br
-+.I MPATH_PR_RESERV_CONFLICT
-+.B if command fails with reservation conflict
-+.br
-+.I MPATH_PR_FILE_ERROR
-+.B if command fails while accessing file (device node) problems(e.g. not found)
-+.br
-+.I MPATH_PR_DMMP_ERROR
-+.B if Device Mapper related error.(e.g Error in getting dm info) 
-+.br
-+.I MPATH_PR_OTHER
-+.B if other error/warning has occurred(e.g transport or driver error)
-+.br
-+
-+
-+.SH "SEE ALSO"
-+.I  mpath_persistent_reserve_in		mpathpersist     /usr/share/doc/mpathpersist/README
-+.br
-diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
-new file mode 100644
-index 0000000..de3292e
---- /dev/null
-+++ b/libmpathpersist/mpath_pr_ioctl.c
-@@ -0,0 +1,583 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <scsi/sg.h>
-+#include <scsi/scsi.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <sys/ioctl.h>
-+#include <unistd.h>
-+#include "mpath_pr_ioctl.h" 
-+#include <mpath_persist.h> 
-+
-+#include <debug.h>
-+
-+#define FILE_NAME_SIZE          256
-+
-+#define TIMEOUT 2000
-+#define MAXRETRY 5
-+
-+int prin_do_scsi_ioctl(char * dev, int rq_servact, struct prin_resp *resp, int noisy);
-+void mpath_format_readkeys(struct prin_resp *pr_buff, int len , int noisy);
-+void mpath_format_readfullstatus(struct prin_resp *pr_buff, int len, int noisy);
-+int mpath_translate_response (char * dev, struct sg_io_hdr io_hdr, SenseData_t Sensedata, int noisy);
-+void dumpHex(const char* str, int len, int no_ascii);
-+int prout_do_scsi_ioctl( char * dev, int rq_servact, int rq_scope,
-+                unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy);
-+uint32_t  format_transportids(struct prout_param_descriptor *paramp);
-+void mpath_reverse_uint32_byteorder(uint32_t *num);
-+void mpath_reverse_uint16_byteorder(uint16_t *num);
-+void decode_transport_id(struct prin_fulldescr *fdesc, unsigned char * p, int length);
-+int get_prin_length(int rq_servact);
-+int mpath_isLittleEndian(void);
-+
-+extern unsigned int mpath_mx_alloc_len;
-+
-+int prout_do_scsi_ioctl(char * dev, int rq_servact, int rq_scope,
-+                unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy)
-+{
-+
-+	int status, paramlen = 24, ret = 0;
-+	uint32_t translen=0;
-+	int retry = MAXRETRY;
-+	SenseData_t Sensedata;
-+	struct sg_io_hdr io_hdr;
-+	char devname[FILE_NAME_SIZE];
-+	int fd = -1;
-+
-+	snprintf(devname, FILE_NAME_SIZE, "/dev/%s",dev);
-+	fd = open(devname, O_WRONLY);
-+	if(fd < 0){
-+		condlog (1, "%s: unable to open device.", dev);
-+		return MPATH_PR_FILE_ERROR;
-+	}
-+
-+	unsigned char cdb[MPATH_PROUT_CMDLEN] =
-+	{MPATH_PROUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-+
-+
-+	if (paramp->sa_flags & MPATH_F_SPEC_I_PT_MASK)
-+	{
-+		translen = format_transportids(paramp);
-+		paramlen = 24 + translen;
-+	}	
-+	else
-+		paramlen = 24;
-+
-+	if ( rq_servact > 0)
-+		cdb[1] = (unsigned char)(rq_servact & 0x1f);
-+	cdb[2] = (((rq_scope & 0xf) << 4) | (rq_type & 0xf));
-+	cdb[7] = (unsigned char)((paramlen >> 8) & 0xff);
-+	cdb[8] = (unsigned char)(paramlen & 0xff);
-+
-+retry :
-+	condlog(3, "%s: rq_servact = %d", dev, rq_servact); 
-+	condlog(3, "%s: rq_scope = %d ", dev, rq_scope);
-+	condlog(3, "%s: rq_type = %d ", dev, rq_type);
-+	condlog(3, "%s: paramlen = %d", dev, paramlen);
-+
-+	if (noisy)
-+	{
-+		condlog(3, "%s: Persistent Reservation OUT parameter:", dev);
-+		dumpHex((const char *)paramp, paramlen,1);
-+	}
-+
-+	memset(&Sensedata, 0, sizeof(SenseData_t));
-+	memset(&io_hdr,0 , sizeof( struct sg_io_hdr));
-+	io_hdr.interface_id = 'S';
-+	io_hdr.cmd_len = MPATH_PROUT_CMDLEN;
-+	io_hdr.cmdp = cdb;
-+	io_hdr.sbp = (void *)&Sensedata;
-+	io_hdr.mx_sb_len = sizeof (SenseData_t);
-+	io_hdr.timeout = TIMEOUT;
-+
-+	if (paramlen > 0) {
-+		io_hdr.dxferp = (void *)paramp;
-+		io_hdr.dxfer_len = paramlen;
-+		io_hdr.dxfer_direction = SG_DXFER_TO_DEV ;
-+	}
-+	else {
-+		io_hdr.dxfer_direction = SG_DXFER_NONE;
-+	}
-+	ret = ioctl(fd, SG_IO, &io_hdr);
-+	if (ret < 0)
-+	{
-+		condlog(0, "%s: ioctl failed %d", dev, ret);
-+		close(fd);
-+		return ret;
-+	}
-+
-+	condlog(2, "%s: Duration=%u (ms)", dev, io_hdr.duration);
-+
-+	status = mpath_translate_response(dev, io_hdr, Sensedata, noisy);
-+	condlog(3, "%s: status = %d", dev, status);
-+
-+	if (status == MPATH_PR_SENSE_UNIT_ATTENTION && (retry > 0))
-+	{
-+		--retry;
-+		condlog(2, "%s: retrying for Unit Attention. Remaining retries = %d", 
-+			dev, retry);
-+		goto retry;
-+	}
-+
-+	if (((status == MPATH_PR_SENSE_NOT_READY )&& (Sensedata.ASC == 0x04)&&
-+				(Sensedata.ASCQ == 0x07))&& (retry > 0))
-+	{
-+		usleep(1000);
-+		--retry;
-+		condlog(2, "%s: retrying for sense 02/04/07."
-+			" Remaining retries = %d", dev, retry);
-+		goto retry;
-+	}
-+
-+	close(fd);	
-+	return status;
-+}
-+
-+uint32_t  format_transportids(struct prout_param_descriptor *paramp)
-+{
-+	int i = 0, len;	
-+	uint32_t buff_offset = 4;
-+	memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN);
-+	for (i=0; i < paramp->num_transportid; i++ )
-+	{
-+		paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)|
-+							(paramp->trnptid_list[i]->protocol_id & 0xff));
-+		buff_offset += 1;
-+		switch(paramp->trnptid_list[i]->protocol_id)
-+		{
-+			case MPATH_PROTOCOL_ID_FC:
-+				buff_offset += 7;
-+				memcpy(&paramp->private_buffer[buff_offset], &paramp->trnptid_list[i]->n_port_name, 8);
-+				buff_offset +=8 ;
-+				buff_offset +=8 ;
-+				break;
-+			case MPATH_PROTOCOL_ID_SAS:
-+				buff_offset += 3;
-+				memcpy(&paramp->private_buffer[buff_offset], &paramp->trnptid_list[i]->sas_address, 8);
-+				buff_offset += 12;
-+				break;
-+			case MPATH_PROTOCOL_ID_ISCSI:
-+				buff_offset += 1;
-+				len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2;	
-+				memcpy(&paramp->private_buffer[buff_offset], &paramp->trnptid_list[i]->iscsi_name,len);
-+				buff_offset += len ; 
-+				break;
-+		}
-+
-+	}
-+	buff_offset -= 4; 
-+	paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff);
-+	paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff);
-+	paramp->private_buffer[2] = (unsigned char)((buff_offset >> 8) & 0xff);
-+	paramp->private_buffer[3] = (unsigned char)(buff_offset & 0xff);
-+	buff_offset += 4; 
-+	return buff_offset;	
-+}
-+
-+void mpath_format_readkeys( struct prin_resp *pr_buff, int len, int noisy)
-+{
-+        mpath_reverse_uint32_byteorder(&pr_buff->prin_descriptor.prin_readkeys.prgeneration);
-+        mpath_reverse_uint32_byteorder(&pr_buff->prin_descriptor.prin_readkeys.additional_length);
-+}
-+
-+void mpath_format_readresv(struct prin_resp *pr_buff, int len, int noisy)
-+{
-+
-+        mpath_reverse_uint32_byteorder(&pr_buff->prin_descriptor.prin_readkeys.prgeneration);
-+        mpath_reverse_uint32_byteorder(&pr_buff->prin_descriptor.prin_readkeys.additional_length);
-+
-+        return;
-+}
-+
-+void mpath_format_reportcapabilities(struct prin_resp *pr_buff, int len, int noisy)
-+{
-+        mpath_reverse_uint16_byteorder(&pr_buff->prin_descriptor.prin_readcap.length);
-+        mpath_reverse_uint16_byteorder(&pr_buff->prin_descriptor.prin_readcap.pr_type_mask);
-+
-+        return;
-+}
-+
-+void mpath_format_readfullstatus(struct prin_resp *pr_buff, int len, int noisy)
-+{
-+	int num, k, tid_len_len=0;
-+	uint32_t fdesc_count=0;
-+	unsigned char *p;
-+	char  *ppbuff;
-+	uint32_t additional_length;
-+
-+
-+	mpath_reverse_uint32_byteorder(&pr_buff->prin_descriptor.prin_readfd.prgeneration);
-+	mpath_reverse_uint32_byteorder(&pr_buff->prin_descriptor.prin_readfd.number_of_descriptor);
-+
-+	if (0 == pr_buff->prin_descriptor.prin_readfd.number_of_descriptor)
-+	{
-+		return ;
-+	}
-+
-+
-+	if (pr_buff->prin_descriptor.prin_readfd.number_of_descriptor == 0)
-+	{
-+		condlog(2, "No registration or resrvation found.");
-+		return;
-+	}
-+
-+	additional_length = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor;
-+
-+	char tempbuff[MPATH_MAX_PARAM_LEN];
-+	struct prin_fulldescr fdesc;
-+	memset(&fdesc, 0, sizeof(struct prin_fulldescr));
-+
-+	memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,MPATH_MAX_PARAM_LEN );
-+	memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, MPATH_MAX_PARAM_LEN);
-+
-+	p =(unsigned char *)tempbuff;
-+	ppbuff = (char *)pr_buff->prin_descriptor.prin_readfd.private_buffer;
-+
-+	for (k = 0; k < additional_length; k += num, p += num) {
-+		memcpy(&fdesc.key, p, 8 );
-+		fdesc.flag = p[12];
-+		fdesc.scope_type =  p[13];
-+		fdesc.rtpi = ((p[18] << 8) | p[19]);
-+
-+		tid_len_len = ((p[20] << 24) | (p[21] << 16) |
-+				(p[22] << 8) | p[23]);
-+
-+		if (tid_len_len > 0)
-+			decode_transport_id( &fdesc, &p[24], tid_len_len);
-+
-+		num = 24 + tid_len_len;
-+		memcpy(ppbuff, &fdesc, sizeof(struct prin_fulldescr));
-+		pr_buff->prin_descriptor.prin_readfd.descriptors[fdesc_count]= (struct prin_fulldescr *)ppbuff;
-+		ppbuff += sizeof(struct prin_fulldescr);
-+		++fdesc_count;
-+	}
-+
-+	pr_buff->prin_descriptor.prin_readfd.number_of_descriptor = fdesc_count;
-+
-+	return;
-+}
-+
-+void
-+decode_transport_id(struct prin_fulldescr *fdesc, unsigned char * p, int length)
-+{
-+	int num, k;
-+	int jump;
-+	for (k = 0, jump = 24; k < length; k += jump, p += jump) {
-+		fdesc->trnptid.format_code = ((p[0] >> 6) & 0x3);
-+		fdesc->trnptid.protocol_id = (p[0] & 0xf);
-+		switch (fdesc->trnptid.protocol_id) {
-+			case MPATH_PROTOCOL_ID_FC:
-+				memcpy(&fdesc->trnptid.n_port_name, &p[8], 8);
-+				jump = 24;
-+				break;
-+			case MPATH_PROTOCOL_ID_ISCSI:
-+				num = ((p[2] << 8) | p[3]);
-+				memcpy(&fdesc->trnptid.iscsi_name, &p[4], num);
-+				jump = (((num + 4) < 24) ? 24 : num + 4);
-+				break;
-+			case MPATH_PROTOCOL_ID_SAS:
-+				memcpy(&fdesc->trnptid.sas_address, &p[4], 8);
-+				jump = 24;
-+				break;
-+			default:
-+				jump = 24;
-+				break;
-+		}
-+	}
-+}
-+
-+int prin_do_scsi_ioctl(char * dev, int rq_servact, struct prin_resp * resp, int noisy)
-+{
-+
-+	int ret, status, got, fd;
-+	int mx_resp_len;
-+	SenseData_t Sensedata;
-+	int retry = MAXRETRY;
-+	struct sg_io_hdr io_hdr;
-+	char devname[FILE_NAME_SIZE];
-+	unsigned char cdb[MPATH_PRIN_CMDLEN] =
-+	{MPATH_PRIN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-+
-+	snprintf(devname, FILE_NAME_SIZE, "/dev/%s",dev);
-+        fd = open(devname, O_WRONLY);
-+        if(fd < 0){
-+        	condlog(0, "%s: Unable to open device ", dev);
-+		return MPATH_PR_FILE_ERROR;
-+         }
-+
-+	if (mpath_mx_alloc_len)
-+		mx_resp_len = mpath_mx_alloc_len;
-+	else
-+		mx_resp_len = get_prin_length(rq_servact);
-+
-+	if (mx_resp_len == 0) {
-+		status = MPATH_PR_SYNTAX_ERROR;
-+		goto out;
-+	}
-+
-+	cdb[1] = (unsigned char)(rq_servact & 0x1f);
-+	cdb[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
-+	cdb[8] = (unsigned char)(mx_resp_len & 0xff);
-+
-+retry :
-+	memset(&Sensedata, 0, sizeof(SenseData_t));
-+	memset(&io_hdr,0 , sizeof( struct sg_io_hdr));
-+
-+	io_hdr.interface_id = 'S';
-+	io_hdr.cmd_len = MPATH_PRIN_CMDLEN;
-+	io_hdr.mx_sb_len = sizeof (SenseData_t);
-+	io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-+	io_hdr.cmdp = cdb;
-+	io_hdr.sbp = (void *)&Sensedata;
-+	io_hdr.timeout = TIMEOUT;
-+
-+
-+
-+	io_hdr.dxfer_len = mx_resp_len;
-+	io_hdr.dxferp = (void *)resp;
-+
-+	ret =ioctl(fd, SG_IO, &io_hdr);
-+	if (ret < 0){
-+		condlog(0, "%s: IOCTL failed %d", dev, ret);
-+		status = MPATH_PR_OTHER;
-+		goto out;
-+	}
-+
-+	got = mx_resp_len - io_hdr.resid;
-+
-+	condlog(2, "%s: duration = %u (ms)", dev, io_hdr.duration);
-+	condlog(2, "%s: persistent reservation in: requested %d bytes but got %d bytes)", dev, mx_resp_len, got);
-+
-+	status = mpath_translate_response(dev, io_hdr, Sensedata, noisy);
-+
-+	if (status == MPATH_PR_SENSE_UNIT_ATTENTION && (retry > 0))
-+	{
-+		--retry;
-+		condlog(2, "%s: retrying for Unit Attention. Remaining retries = %d", dev, retry);
-+		goto retry;
-+	}
-+
-+	if (((status == MPATH_PR_SENSE_NOT_READY )&& (Sensedata.ASC == 0x04)&&
-+				(Sensedata.ASCQ == 0x07))&& (retry > 0))
-+	{
-+		usleep(1000);
-+		--retry;
-+		condlog(2, "%s: retrying for 02/04/07. Remaining retries = %d", dev, retry);
-+		goto retry;
-+	}
-+
-+	if (status != MPATH_PR_SUCCESS)
-+		goto out;
-+
-+	if (noisy)
-+		dumpHex((const char *)resp, got , 1);
-+
-+
-+	switch (rq_servact)
-+	{
-+		case MPATH_PRIN_RKEY_SA :
-+			mpath_format_readkeys(resp, got, noisy);
-+			break;
-+		case MPATH_PRIN_RRES_SA :
-+			mpath_format_readresv(resp, got, noisy);
-+			break;
-+		case MPATH_PRIN_RCAP_SA :
-+			mpath_format_reportcapabilities(resp, got, noisy);
-+			break;
-+		case MPATH_PRIN_RFSTAT_SA :
-+			mpath_format_readfullstatus(resp, got, noisy);
-+	}
-+
-+out:
-+	close(fd);
-+	return status;
-+}
-+
-+int mpath_translate_response (char * dev, struct sg_io_hdr io_hdr, SenseData_t Sensedata, int noisy)
-+{
-+	condlog(3, "%s: status driver:%02x host:%02x scsi:%02x", dev, 
-+			io_hdr.driver_status, io_hdr.host_status ,io_hdr.status);
-+	io_hdr.status &= 0x7e;
-+	if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
-+			(0 == io_hdr.driver_status))
-+	{
-+		return MPATH_PR_SUCCESS;
-+	}
-+
-+	switch(io_hdr.status)
-+	{
-+		case SAM_STAT_GOOD:
-+			break;
-+		case SAM_STAT_CHECK_CONDITION:
-+			condlog(2, "%s: Sense_Key=%02x, ASC=%02x ASCQ=%02x", dev,
-+					Sensedata.Sense_Key, Sensedata.ASC, Sensedata.ASCQ);
-+			switch(Sensedata.Sense_Key)
-+			{
-+				case NO_SENSE:
-+					return MPATH_PR_NO_SENSE;
-+				case RECOVERED_ERROR:
-+					return MPATH_PR_SUCCESS;
-+				case NOT_READY:
-+					return MPATH_PR_SENSE_NOT_READY;
-+				case MEDIUM_ERROR:
-+					return MPATH_PR_SENSE_MEDIUM_ERROR;
-+				case BLANK_CHECK:
-+					return MPATH_PR_OTHER;
-+				case HARDWARE_ERROR:
-+					return MPATH_PR_SENSE_HARDWARE_ERROR;
-+				case ILLEGAL_REQUEST:
-+					return MPATH_PR_ILLEGAL_REQ;
-+				case UNIT_ATTENTION:
-+					return MPATH_PR_SENSE_UNIT_ATTENTION;
-+				case DATA_PROTECT:
-+				case COPY_ABORTED:
-+					return MPATH_PR_OTHER;
-+				case ABORTED_COMMAND:
-+					return MPATH_PR_SENSE_ABORTED_COMMAND;
-+
-+				default :
-+					return MPATH_PR_OTHER;
-+			}
-+		case SAM_STAT_RESERVATION_CONFLICT:
-+			return MPATH_PR_RESERV_CONFLICT;
-+
-+		default :
-+			return  MPATH_PR_OTHER;
-+	}
-+
-+	switch(io_hdr.host_status)
-+	{
-+		case DID_OK :
-+			break;
-+		default :
-+			return MPATH_PR_OTHER;
-+	}
-+	switch(io_hdr.driver_status)
-+	{
-+		case DRIVER_OK:
-+			break;
-+		default :
-+			return MPATH_PR_OTHER;
-+	}
-+	return MPATH_PR_SUCCESS;
-+}
-+
-+int mpath_isLittleEndian()
-+{
-+	int num = 1;
-+	if(*(char *)&num == 1)
-+	{
-+		condlog(2, "Little-Endian");
-+	}
-+	else
-+	{
-+		condlog(2, "Big-Endian");
-+	}
-+	return 0;
-+}
-+
-+void mpath_reverse_uint16_byteorder(uint16_t *num)
-+{
-+	uint16_t byte0, byte1;
-+
-+	byte0 = (*num & 0x000000FF) >>  0 ;
-+	byte1 = (*num & 0x0000FF00) >>  8 ;
-+
-+	*num = ((byte0 << 8) | (byte1 << 0));
-+}
-+
-+void mpath_reverse_uint32_byteorder(uint32_t *num)
-+{
-+	uint32_t byte0, byte1, byte2, byte3;
-+
-+	byte0 = (*num & 0x000000FF) >>  0 ;
-+	byte1 = (*num & 0x0000FF00) >>  8 ;
-+	byte2 = (*num & 0x00FF0000) >> 16 ;
-+	byte3 = (*num & 0xFF000000) >> 24 ;
-+
-+	*num = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | (byte3 << 0));
-+}
-+
-+void mpath_reverse_8bytes_order(char * var)
-+{
-+	char byte[8];
-+
-+	int i;
-+	for(i=0 ; i < 8 ; i++ )
-+	{
-+		byte[i] = var[i];
-+	}
-+	for(i=0 ; i < 8 ; i++ )
-+	{
-+		var[7 - i] = byte[i];
-+	}
-+}
-+
-+void
-+dumpHex(const char* str, int len, int log)
-+{
-+	const char * p = str;
-+	unsigned char c;
-+	char buff[82];
-+	const int bpstart = 5;
-+	int bpos = bpstart;
-+	int  k;
-+
-+	if (len <= 0)
-+		return;
-+	memset(buff, ' ', 80);
-+	buff[80] = '\0';
-+	for (k = 0; k < len; k++) {
-+		c = *p++;
-+		bpos += 3;
-+		if (bpos == (bpstart + (9 * 3)))
-+			bpos++;
-+		sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c);
-+		buff[bpos + 2] = ' ';
-+		if ((k > 0) && (0 == ((k + 1) % 16))) {
-+			if (log)
-+				condlog(0, "%.76s" , buff);
-+			else
-+				printf("%.76s" , buff);
-+			bpos = bpstart;
-+			memset(buff, ' ', 80);
-+		}
-+	}
-+	if (bpos > bpstart) {
-+		buff[bpos + 2] = '\0';
-+		if (log)
-+			condlog(0, "%s", buff);
-+		else
-+			printf("%s\n" , buff);
-+	}
-+	return;
-+}
-+
-+int get_prin_length(int rq_servact)
-+{
-+        int mx_resp_len;
-+        switch (rq_servact)
-+        {
-+                case MPATH_PRIN_RKEY_SA:
-+                        mx_resp_len =  sizeof(struct prin_readdescr);
-+                        break;
-+                case MPATH_PRIN_RRES_SA :
-+                        mx_resp_len =  sizeof(struct prin_resvdescr);
-+                        break;
-+                case MPATH_PRIN_RCAP_SA :
-+                        mx_resp_len = sizeof(struct prin_capdescr);
-+                        break;
-+                case MPATH_PRIN_RFSTAT_SA:
-+                        mx_resp_len = sizeof(struct print_fulldescr_list) + sizeof(struct prin_fulldescr *)*32;
-+                        break;
-+		default:
-+			condlog(0, "invalid service action, %d", rq_servact);
-+			mx_resp_len = 0;
-+			break;
-+        }
-+        return mx_resp_len;
-+}
-diff --git a/libmpathpersist/mpath_pr_ioctl.h b/libmpathpersist/mpath_pr_ioctl.h
-new file mode 100644
-index 0000000..573ff15
---- /dev/null
-+++ b/libmpathpersist/mpath_pr_ioctl.h
-@@ -0,0 +1,111 @@
-+#define MPATH_XFER_HOST_DEV              0   /*data transfer from initiator to target */
-+#define MPATH_XFER_DEV_HOST              1   /*data transfer from target to initiator */
-+#define MPATH_XFER_NONE                  2   /*no data transfer */
-+#define MPATH_XFER_UNKNOWN               3   /*data transfer direction is unknown */
-+
-+#if 0
-+static const char * pr_type_strs[] = {
-+    "obsolete [0]",
-+    "Write Exclusive",
-+    "obsolete [2]",
-+    "Exclusive Access",
-+    "obsolete [4]",
-+    "Write Exclusive, registrants only",
-+    "Exclusive Access, registrants only",
-+    "Write Exclusive, all registrants",
-+    "Exclusive Access, all registrants",
-+    "obsolete [9]", "obsolete [0xa]", "obsolete [0xb]", "obsolete [0xc]",
-+    "obsolete [0xd]", "obsolete [0xe]", "obsolete [0xf]",
-+};
-+#endif
-+
-+typedef unsigned int     LWORD;     /* unsigned numeric, bit patterns */
-+typedef unsigned char    BYTE;      /* unsigned numeric, bit patterns */
-+
-+typedef struct SenseData
-+{
-+    BYTE        Error_Code;
-+    BYTE        Segment_Number; /* not applicable to DAC */
-+    BYTE        Sense_Key;
-+    BYTE        Information[ 4 ];
-+    BYTE        Additional_Len;
-+    LWORD       Command_Specific_Info;
-+    BYTE        ASC;
-+    BYTE        ASCQ;
-+    BYTE        Field_Replaceable_Unit;
-+    BYTE        Sense_Key_Specific_Info[ 3 ];
-+    BYTE        Recovery_Action[ 2 ];
-+    BYTE        Total_Errors;
-+    BYTE        Total_Retries;
-+    BYTE        ASC_Stack_1;
-+    BYTE        ASCQ_Stack_1;
-+    BYTE        ASC_Stack_2;
-+    BYTE        ASCQ_Stack_2;
-+    BYTE        Additional_FRU_Info[ 8 ];
-+    BYTE        Error_Specific_Info[ 3 ];
-+    BYTE        Error_Detection_Point[ 4 ];
-+    BYTE        Original_CDB[10];
-+    BYTE        Host_ID;
-+    BYTE        Host_Descriptor[ 2 ];
-+    BYTE        Serial_Number[ 16 ];
-+    BYTE        Array_SW_Revision[ 4 ];
-+    BYTE        Data_Xfer_Operation;
-+    BYTE        LUN_Number;
-+    BYTE        LUN_Status;
-+    BYTE        Drive_ID;
-+    BYTE        Xfer_Start_Drive_ID;
-+    BYTE        Drive_SW_Revision[ 4 ];
-+    BYTE        Drive_Product_ID[ 16 ];
-+    BYTE        PowerUp_Status[ 2 ];
-+    BYTE        RAID_Level;
-+    BYTE        Drive_Sense_ID[ 2 ];
-+    BYTE        Drive_Sense_Data[ 32 ];
-+    BYTE        Reserved2[24];
-+} SenseData_t;
-+
-+#define MPATH_PRIN_CMD 0x5e
-+#define MPATH_PRIN_CMDLEN 10
-+#define MPATH_PROUT_CMD 0x5f
-+#define MPATH_PROUT_CMDLEN 10
-+
-+#define  DID_OK	0x00
-+/*
-+ *  Status codes
-+ */
-+#define SAM_STAT_GOOD            0x00
-+#define SAM_STAT_CHECK_CONDITION 0x02
-+#define SAM_STAT_CONDITION_MET   0x04
-+#define SAM_STAT_BUSY            0x08
-+#define SAM_STAT_INTERMEDIATE    0x10
-+#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
-+#define SAM_STAT_RESERVATION_CONFLICT 0x18
-+#define SAM_STAT_COMMAND_TERMINATED 0x22        /* obsolete in SAM-3 */
-+#define SAM_STAT_TASK_SET_FULL   0x28
-+#define SAM_STAT_ACA_ACTIVE      0x30
-+#define SAM_STAT_TASK_ABORTED    0x40
-+
-+#define STATUS_MASK          0x3e
-+
-+/*
-+ *  SENSE KEYS
-+ */
-+
-+#define NO_SENSE            0x00
-+#define RECOVERED_ERROR     0x01
-+#define NOT_READY           0x02
-+#define MEDIUM_ERROR        0x03
-+#define HARDWARE_ERROR      0x04
-+#define ILLEGAL_REQUEST     0x05
-+#define UNIT_ATTENTION      0x06
-+#define DATA_PROTECT        0x07
-+#define BLANK_CHECK         0x08
-+#define COPY_ABORTED        0x0a
-+#define ABORTED_COMMAND     0x0b
-+#define VOLUME_OVERFLOW     0x0d
-+#define MISCOMPARE          0x0e
-+
-+
-+/* Driver status */
-+#define DRIVER_OK 0x00
-+
-+
-diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c
-new file mode 100644
-index 0000000..8597d40
---- /dev/null
-+++ b/libmpathpersist/mpath_updatepr.c
-@@ -0,0 +1,51 @@
-+#include<stdio.h>
-+#include<unistd.h>
-+#include <errno.h>
-+
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <fcntl.h>
-+#include <sys/ioctl.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+#include <sys/poll.h>
-+#include <errno.h>
-+#include <debug.h>
-+#include "memory.h"
-+#include "../libmultipath/uxsock.h"
-+#include "../libmultipath/defaults.h"
-+
-+unsigned long mem_allocated;    /* Total memory used in Bytes */
-+
-+int update_prflag(char * arg1, char * arg2, int noisy)
-+{
-+	int fd;
-+	char str[64];
-+	char *reply;
-+	size_t len;
-+	int ret = 0;
-+
-+	fd = ux_socket_connect(DEFAULT_SOCKET);
-+	if (fd == -1) {
-+		condlog (0, "ux socket connect error");
-+		return 1 ;
-+	}
-+
-+	snprintf(str,sizeof(str),"map %s %s", arg1, arg2);
-+	condlog (2, "%s: pr flag message=%s", arg1, str);
-+	send_packet(fd, str, strlen(str) + 1);
-+	recv_packet(fd, &reply, &len);
-+
-+	condlog (2, "%s: message=%s reply=%s", arg1, str, reply);
-+	if (!reply || strncmp(reply,"ok", 2) == 0)
-+		ret = -1;
-+	else if (strncmp(reply, "fail", 4) == 0)
-+		ret = -2;
-+	else{
-+		ret = atoi(reply);
-+	}
-+
-+	free(reply);
-+	return ret;
-+}
-diff --git a/libmpathpersist/mpathpr.h b/libmpathpersist/mpathpr.h
-new file mode 100644
-index 0000000..54dfb3e
---- /dev/null
-+++ b/libmpathpersist/mpathpr.h
-@@ -0,0 +1,55 @@
-+#ifndef MPATHPR_H
-+#define MPATHPR_H
-+
-+struct prin_param {
-+	char dev[FILE_NAME_SIZE];
-+        int rq_servact;
-+        struct prin_resp *resp;
-+        int noisy;
-+        int status;
-+};
-+
-+struct prout_param {
-+	char dev[FILE_NAME_SIZE];
-+        int rq_servact;
-+        int rq_scope;
-+        unsigned int rq_type;
-+        struct prout_param_descriptor  *paramp;
-+        int noisy;
-+        int status;
-+};
-+
-+struct threadinfo {
-+        int status;
-+        pthread_t id;
-+        struct prout_param param;
-+};
-+
-+
-+struct config * conf;
-+
-+
-+int prin_do_scsi_ioctl(char * dev, int rq_servact, struct prin_resp * resp, int noisy);
-+int prout_do_scsi_ioctl( char * dev, int rq_servact, int rq_scope,
-+                unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy);
-+void * _mpath_pr_update (void *arg);
-+int mpath_send_prin_activepath (char * dev, int rq_servact, struct prin_resp * resp, int noisy);
-+int get_mpvec (vector curmp, vector pathvec, char * refwwid);
-+void * mpath_prout_pthread_fn(void *p);
-+void dumpHex(const char* , int len, int no_ascii);
-+
-+int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
-+        unsigned int rq_type,  struct prout_param_descriptor * paramp, int noisy);
-+int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope,
-+        unsigned int rq_type,  struct prout_param_descriptor * paramp, int noisy);
-+int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
-+        unsigned int rq_type,  struct prout_param_descriptor * paramp, int noisy);
-+int send_prout_activepath(char * dev, int rq_servact, int rq_scope,
-+        unsigned int rq_type,   struct prout_param_descriptor * paramp, int noisy);
-+
-+int update_prflag(char * arg1, char * arg2, int noisy);
-+void * mpath_alloc_prin_response(int prin_sa);
-+int update_map_pr(struct multipath *mpp);
-+int devt2devname (char *devname, char *devt);
-+
-+#endif  
-diff --git a/libmultipath/Makefile b/libmultipath/Makefile
-index 203833d..22d3844 100644
---- a/libmultipath/Makefile
-+++ b/libmultipath/Makefile
-@@ -7,15 +7,15 @@ include ../Makefile.inc
- SONAME=0
- DEVLIB = libmultipath.so
- LIBS = $(DEVLIB).$(SONAME)
--LIBDEPS = -lpthread -ldl -ldevmapper
-+LIBDEPS = -lpthread -ldl -ldevmapper -ludev
- 
--OBJS = memory.o parser.o vector.o devmapper.o callout.o \
-+OBJS = memory.o parser.o vector.o devmapper.o \
-        hwtable.o blacklist.o util.o dmparser.o config.o \
-        structs.o discovery.o propsel.o dict.o \
-        pgpolicies.o debug.o regex.o defaults.o uevent.o \
-        switchgroup.o uxsock.o print.o alias.o log_pthread.o \
-        log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
--       lock.o waiter.o
-+       lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o
- 
- LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h)
- 
-@@ -23,10 +23,23 @@ ifneq ($(strip $(LIBDM_API_FLUSH)),0)
- 	CFLAGS += -DLIBDM_API_FLUSH -D_GNU_SOURCE
- endif
- 
-+LIBDM_API_COOKIE = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_set_cookie' /usr/include/libdevmapper.h)
-+
-+ifneq ($(strip $(LIBDM_API_COOKIE)),0)
-+	CFLAGS += -DLIBDM_API_COOKIE
-+endif
-+
-+LIBUDEV_API_RECVBUF = $(shell grep -Ecs '^[a-z]*[[:space:]]+udev_monitor_set_resolve_buffer_size' /usr/include/libudev.h)
-+
-+ifneq ($(strip $(LIBUDEV_API_RECVBUF)),0)
-+	CFLAGS += -DLIBUDEV_API_RECVBUF
-+endif
-+
-+
- all: $(LIBS)
- 
- $(LIBS): $(OBJS)
--	$(CC) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS)
-+	$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS) $(LIBDEPS)
- 	ln -sf $@ $(DEVLIB)
- 
- install:
-diff --git a/libmultipath/alias.c b/libmultipath/alias.c
-index 95506b4..d913294 100644
---- a/libmultipath/alias.c
-+++ b/libmultipath/alias.c
-@@ -3,19 +3,19 @@
-  * Copyright (c) 2005 Benjamin Marzinski, Redhat
-  */
- #include <stdlib.h>
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <fcntl.h>
- #include <errno.h>
- #include <unistd.h>
- #include <string.h>
- #include <limits.h>
- #include <stdio.h>
--#include <signal.h>
- 
- #include "debug.h"
- #include "uxsock.h"
- #include "alias.h"
-+#include "file.h"
-+#include "vector.h"
-+#include "checkers.h"
-+#include "structs.h"
- 
- 
- /*
-@@ -36,178 +36,37 @@
-  * See the file COPYING included with this distribution for more details.
-  */
- 
--static int
--ensure_directories_exist(char *str, mode_t dir_mode)
--{
--	char *pathname;
--	char *end;
--	int err;
--
--	pathname = strdup(str);
--	if (!pathname){
--		condlog(0, "Cannot copy bindings file pathname : %s",
--			strerror(errno));
--		return -1;
--	}
--	end = pathname;
--	/* skip leading slashes */
--	while (end && *end && (*end == '/'))
--		end++;
--
--	while ((end = strchr(end, '/'))) {
--		/* if there is another slash, make the dir. */
--		*end = '\0';
--		err = mkdir(pathname, dir_mode);
--		if (err && errno != EEXIST) {
--			condlog(0, "Cannot make directory [%s] : %s",
--				pathname, strerror(errno));
--			free(pathname);
--			return -1;
--		}
--		if (!err)
--			condlog(3, "Created dir [%s]", pathname);
--		*end = '/';
--		end++;
--	}
--	free(pathname);
--	return 0;
--}
--
--static void
--sigalrm(int sig)
--{
--	/* do nothing */
--}
- 
- static int
--lock_bindings_file(int fd)
--{
--	struct sigaction act, oldact;
--	sigset_t set, oldset;
--	struct flock lock;
--	int err;
--
--	memset(&lock, 0, sizeof(lock));
--	lock.l_type = F_WRLCK;
--	lock.l_whence = SEEK_SET;
--
--	act.sa_handler = sigalrm;
--	sigemptyset(&act.sa_mask);
--	act.sa_flags = 0;
--	sigemptyset(&set);
--	sigaddset(&set, SIGALRM);
--
--	sigaction(SIGALRM, &act, &oldact);
--	sigprocmask(SIG_UNBLOCK, &set, &oldset);
--
--	alarm(BINDINGS_FILE_TIMEOUT);
--	err = fcntl(fd, F_SETLKW, &lock);
--	alarm(0);
--
--	if (err) {
--		if (errno != EINTR)
--			condlog(0, "Cannot lock bindings file : %s",
--					strerror(errno));
--		else
--			condlog(0, "Bindings file is locked. Giving up.");
--	}
--
--	sigprocmask(SIG_SETMASK, &oldset, NULL);
--	sigaction(SIGALRM, &oldact, NULL);
--	return err;
--
--}
--
--
--static int
--open_bindings_file(char *file, int *can_write)
--{
--	int fd;
--	struct stat s;
--
--	if (ensure_directories_exist(file, 0700))
--		return -1;
--	*can_write = 1;
--	fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
--	if (fd < 0) {
--		if (errno == EROFS) {
--			*can_write = 0;
--			condlog(3, "Cannot open bindings file [%s] read/write. "
--				" trying readonly", file);
--			fd = open(file, O_RDONLY);
--			if (fd < 0) {
--				condlog(0, "Cannot open bindings file [%s] "
--					"readonly : %s", file, strerror(errno));
--				return -1;
--			}
--		}
--		else {
--			condlog(0, "Cannot open bindings file [%s] : %s", file,
--				strerror(errno));
--			return -1;
--		}
--	}
--	if (*can_write && lock_bindings_file(fd) < 0)
--		goto fail;
--
--	memset(&s, 0, sizeof(s));
--	if (fstat(fd, &s) < 0){
--		condlog(0, "Cannot stat bindings file : %s", strerror(errno));
--		goto fail;
--	}
--	if (s.st_size == 0) {
--		if (*can_write == 0)
--			goto fail;
--		/* If bindings file is empty, write the header */
--		size_t len = strlen(BINDINGS_FILE_HEADER);
--		if (write_all(fd, BINDINGS_FILE_HEADER, len) != len) {
--			condlog(0,
--				"Cannot write header to bindings file : %s",
--				strerror(errno));
--			/* cleanup partially written header */
--			ftruncate(fd, 0);
--			goto fail;
--		}
--		fsync(fd);
--		condlog(3, "Initialized new bindings file [%s]", file);
--	}
--
--	return fd;
--
--fail:
--	close(fd);
--	return -1;
--}
--
--static int
--format_devname(char *name, int id, int len)
-+format_devname(char *name, int id, int len, char *prefix)
- {
- 	int pos;
-+	int prefix_len = strlen(prefix);
- 
- 	memset(name,0, len);
--	strcpy(name,"mpath");
--	for (pos = len - 1; pos >= 5; pos--) {
-+	strcpy(name, prefix);
-+	for (pos = len - 1; pos >= prefix_len; pos--) {
- 		name[pos] = 'a' + id % 26;
- 		if (id < 26)
- 			break;
- 		id /= 26;
- 		id--;
- 	}
--	memmove(name + 5, name + pos, len - pos);
--	name[5 + len - pos] = '\0';
--	return (5 + len - pos);
-+	memmove(name + prefix_len, name + pos, len - pos);
-+	name[prefix_len + len - pos] = '\0';
-+	return (prefix_len + len - pos);
- }
- 
- static int
--scan_devname(char *alias)
-+scan_devname(char *alias, char *prefix)
- {
- 	char *c;
- 	int i, n = 0;
- 
--	if (strncmp(alias, "mpath", 5))
-+	if (!prefix || strncmp(alias, prefix, strlen(prefix)))
- 		return -1;
- 
--	c = alias + 5;
-+	c = alias + strlen(prefix);
- 	while (*c != '\0' && *c != ' ' && *c != '\t') {
- 		i = *c - 'a';
- 		n = ( n * 26 ) + i;
-@@ -221,7 +80,7 @@ scan_devname(char *alias)
- }
- 
- static int
--lookup_binding(FILE *f, char *map_wwid, char **map_alias)
-+lookup_binding(FILE *f, char *map_wwid, char **map_alias, char *prefix)
- {
- 	char buf[LINE_MAX];
- 	unsigned int line_nr = 0;
-@@ -240,10 +99,10 @@ lookup_binding(FILE *f, char *map_wwid, char **map_alias)
- 		alias = strtok(buf, " \t");
- 		if (!alias) /* blank line */
- 			continue;
--		curr_id = scan_devname(alias);
-+		curr_id = scan_devname(alias, prefix);
- 		if (curr_id >= id)
- 			id = curr_id + 1;
--		wwid = strtok(NULL, "");
-+		wwid = strtok(NULL, " \t");
- 		if (!wwid){
- 			condlog(3,
- 				"Ignoring malformed line %u in bindings file",
-@@ -265,26 +124,26 @@ lookup_binding(FILE *f, char *map_wwid, char **map_alias)
- }
- 
- static int
--rlookup_binding(FILE *f, char **map_wwid, char *map_alias)
-+rlookup_binding(FILE *f, char *buff, char *map_alias)
- {
--	char buf[LINE_MAX];
-+	char line[LINE_MAX];
- 	unsigned int line_nr = 0;
- 	int id = 0;
- 
--	*map_wwid = NULL;
-+	buff[0] = '\0';
- 
--	while (fgets(buf, LINE_MAX, f)) {
-+	while (fgets(line, LINE_MAX, f)) {
- 		char *c, *alias, *wwid;
- 		int curr_id;
- 
- 		line_nr++;
--		c = strpbrk(buf, "#\n\r");
-+		c = strpbrk(line, "#\n\r");
- 		if (c)
- 			*c = '\0';
--		alias = strtok(buf, " \t");
-+		alias = strtok(line, " \t");
- 		if (!alias) /* blank line */
- 			continue;
--		curr_id = scan_devname(alias);
-+		curr_id = scan_devname(alias, NULL); /* TBD: Why this call? */
- 		if (curr_id >= id)
- 			id = curr_id + 1;
- 		wwid = strtok(NULL, " \t");
-@@ -294,13 +153,16 @@ rlookup_binding(FILE *f, char **map_wwid, char *map_alias)
- 				line_nr);
- 			continue;
- 		}
-+		if (strlen(wwid) > WWID_SIZE - 1) {
-+			condlog(3,
-+				"Ignoring too large wwid at %u in bindings file", line_nr);
-+			continue;
-+		}
- 		if (strcmp(alias, map_alias) == 0){
- 			condlog(3, "Found matching alias [%s] in bindings file."
- 				"\nSetting wwid to %s", alias, wwid);
--			*map_wwid = strdup(wwid);
--			if (*map_wwid == NULL)
--				condlog(0, "Cannot copy alias from bindings "
--					"file : %s", strerror(errno));
-+			strncpy(buff, wwid, WWID_SIZE);
-+			buff[WWID_SIZE - 1] = '\0';
- 			return id;
- 		}
- 	}
-@@ -309,7 +171,7 @@ rlookup_binding(FILE *f, char **map_wwid, char *map_alias)
- }
- 
- static char *
--allocate_binding(int fd, char *wwid, int id)
-+allocate_binding(int fd, char *wwid, int id, char *prefix)
- {
- 	char buf[LINE_MAX];
- 	off_t offset;
-@@ -321,7 +183,7 @@ allocate_binding(int fd, char *wwid, int id)
- 		return NULL;
- 	}
- 
--	i = format_devname(buf, id, LINE_MAX);
-+	i = format_devname(buf, id, LINE_MAX, prefix);
- 	c = buf + i;
- 	snprintf(c,LINE_MAX - i, " %s\n", wwid);
- 	buf[LINE_MAX - 1] = '\0';
-@@ -336,7 +198,9 @@ allocate_binding(int fd, char *wwid, int id)
- 		condlog(0, "Cannot write binding to bindings file : %s",
- 			strerror(errno));
- 		/* clear partial write */
--		ftruncate(fd, offset);
-+		if (ftruncate(fd, offset))
-+			condlog(0, "Cannot truncate the header : %s",
-+				strerror(errno));
- 		return NULL;
- 	}
- 	c = strchr(buf, ' ');
-@@ -352,10 +216,11 @@ allocate_binding(int fd, char *wwid, int id)
- }
- 
- char *
--get_user_friendly_alias(char *wwid, char *file)
-+get_user_friendly_alias(char *wwid, char *file, char *prefix,
-+			int bindings_read_only)
- {
- 	char *alias;
--	int fd, scan_fd, id;
-+	int fd, id;
- 	FILE *f;
- 	int can_write;
- 
-@@ -364,87 +229,67 @@ get_user_friendly_alias(char *wwid, char *file)
- 		return NULL;
- 	}
- 
--	fd = open_bindings_file(file, &can_write);
-+	fd = open_file(file, &can_write, BINDINGS_FILE_HEADER);
- 	if (fd < 0)
- 		return NULL;
- 
--	scan_fd = dup(fd);
--	if (scan_fd < 0) {
--		condlog(0, "Cannot dup bindings file descriptor : %s",
--			strerror(errno));
--		close(fd);
--		return NULL;
--	}
--
--	f = fdopen(scan_fd, "r");
-+	f = fdopen(fd, "r");
- 	if (!f) {
- 		condlog(0, "cannot fdopen on bindings file descriptor : %s",
- 			strerror(errno));
--		close(scan_fd);
- 		close(fd);
- 		return NULL;
- 	}
- 
--	id = lookup_binding(f, wwid, &alias);
-+	id = lookup_binding(f, wwid, &alias, prefix);
- 	if (id < 0) {
- 		fclose(f);
--		close(scan_fd);
--		close(fd);
- 		return NULL;
- 	}
- 
--	if (!alias && can_write)
--		alias = allocate_binding(fd, wwid, id);
-+	if (fflush(f) != 0) {
-+		condlog(0, "cannot fflush bindings file stream : %s",
-+			strerror(errno));
-+		fclose(f);
-+		return NULL;
-+	}
-+
-+	if (!alias && can_write && !bindings_read_only)
-+		alias = allocate_binding(fd, wwid, id, prefix);
- 
- 	fclose(f);
--	close(scan_fd);
--	close(fd);
- 	return alias;
- }
- 
--char *
--get_user_friendly_wwid(char *alias, char *file)
-+int
-+get_user_friendly_wwid(char *alias, char *buff, char *file)
- {
--	char *wwid;
--	int fd, scan_fd, id, unused;
-+	int fd, unused;
- 	FILE *f;
- 
- 	if (!alias || *alias == '\0') {
- 		condlog(3, "Cannot find binding for empty alias");
--		return NULL;
-+		return -1;
- 	}
- 
--	fd = open_bindings_file(file, &unused);
-+	fd = open_file(file, &unused, BINDINGS_FILE_HEADER);
- 	if (fd < 0)
--		return NULL;
--
--	scan_fd = dup(fd);
--	if (scan_fd < 0) {
--		condlog(0, "Cannot dup bindings file descriptor : %s",
--			strerror(errno));
--		close(fd);
--		return NULL;
--	}
-+		return -1;
- 
--	f = fdopen(scan_fd, "r");
-+	f = fdopen(fd, "r");
- 	if (!f) {
- 		condlog(0, "cannot fdopen on bindings file descriptor : %s",
- 			strerror(errno));
--		close(scan_fd);
- 		close(fd);
--		return NULL;
-+		return -1;
- 	}
- 
--	id = rlookup_binding(f, &wwid, alias);
--	if (id < 0) {
-+	rlookup_binding(f, buff, alias);
-+	if (!strlen(buff)) {
- 		fclose(f);
--		close(scan_fd);
--		close(fd);
--		return NULL;
-+		return -1;
- 	}
- 
- 	fclose(f);
--	close(scan_fd);
--	close(fd);
--	return wwid;
-+	return 0;
- }
-diff --git a/libmultipath/alias.h b/libmultipath/alias.h
-index fe1191b..8ddd0b5 100644
---- a/libmultipath/alias.h
-+++ b/libmultipath/alias.h
-@@ -1,4 +1,3 @@
--#define BINDINGS_FILE_TIMEOUT 30
- #define BINDINGS_FILE_HEADER \
- "# Multipath bindings, Version : 1.0\n" \
- "# NOTE: this file is automatically maintained by the multipath program.\n" \
-@@ -8,5 +7,6 @@
- "# alias wwid\n" \
- "#\n"
- 
--char *get_user_friendly_alias(char *wwid, char *file);
--char *get_user_friendly_wwid(char *alias, char *file);
-+char *get_user_friendly_alias(char *wwid, char *file, char *prefix,
-+			      int bindings_readonly);
-+int get_user_friendly_wwid(char *alias, char *buff, char *file);
-diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
-index f369517..49a40f9 100644
---- a/libmultipath/blacklist.c
-+++ b/libmultipath/blacklist.c
-@@ -96,50 +96,6 @@ set_ble_device (vector blist, char * vendor, char * product, int origin)
- }
- 
- int
--setup_default_blist (struct config * conf)
--{
--	struct blentry * ble;
--	struct hwentry *hwe;
--	char * str;
--	int i;
--
--	str = STRDUP("^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*");
--	if (!str)
--		return 1;
--	if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
--		return 1;
--
--	str = STRDUP("^hd[a-z]");
--	if (!str)
--		return 1;
--	if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
--		return 1;
--
--	str = STRDUP("^dcssblk[0-9]*");
--	if (!str)
--		return 1;
--	if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
--		return 1;
--
--	vector_foreach_slot (conf->hwtable, hwe, i) {
--		if (hwe->bl_product) {
--			if (alloc_ble_device(conf->blist_device))
--				return 1;
--			ble = VECTOR_SLOT(conf->blist_device,
--					  VECTOR_SIZE(conf->blist_device) -1);
--			if (set_ble_device(conf->blist_device,
--					   STRDUP(hwe->vendor),
--					   STRDUP(hwe->bl_product),
--					   ORIGIN_DEFAULT)) {
--				FREE(ble);
--				return 1;
--			}
--		}
--	}
--	return 0;
--}
--
--int
- _blacklist_exceptions (vector elist, char * str)
- {
- 	int i;
-@@ -193,6 +149,53 @@ _blacklist_device (vector blist, char * vendor, char * product)
- 	return 0;
- }
- 
-+int
-+setup_default_blist (struct config * conf)
-+{
-+	struct blentry * ble;
-+	struct hwentry *hwe;
-+	char * str;
-+	int i;
-+
-+	str = STRDUP("^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*");
-+	if (!str)
-+		return 1;
-+	if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
-+		return 1;
-+
-+	str = STRDUP("^hd[a-z]");
-+	if (!str)
-+		return 1;
-+	if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
-+		return 1;
-+
-+	str = STRDUP("^dcssblk[0-9]*");
-+	if (!str)
-+		return 1;
-+	if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
-+		return 1;
-+
-+	vector_foreach_slot (conf->hwtable, hwe, i) {
-+		if (hwe->bl_product) {
-+			if (_blacklist_device(conf->blist_device, hwe->vendor,
-+					      hwe->bl_product))
-+				continue;
-+			if (alloc_ble_device(conf->blist_device))
-+				return 1;
-+			ble = VECTOR_SLOT(conf->blist_device,
-+					  VECTOR_SIZE(conf->blist_device) -1);
-+			if (set_ble_device(conf->blist_device,
-+					   STRDUP(hwe->vendor),
-+					   STRDUP(hwe->bl_product),
-+					   ORIGIN_DEFAULT)) {
-+				FREE(ble);
-+				return 1;
-+			}
-+		}
-+	}
-+	return 0;
-+}
-+
- #define LOG_BLIST(M) \
- 	if (vendor && product)						 \
- 		condlog(3, "%s: (%s:%s) %s", dev, vendor, product, (M)); \
-diff --git a/libmultipath/callout.c b/libmultipath/callout.c
-deleted file mode 100644
-index 520343e..0000000
---- a/libmultipath/callout.c
-+++ /dev/null
-@@ -1,224 +0,0 @@
--/*
-- * Source: copy of the udev package source file
-- *
-- * Copyrights of the source file apply
-- * Copyright (c) 2004 Christophe Varoqui
-- */
--#include <stdio.h>
--#include <sys/stat.h>
--#include <string.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <stdlib.h>
--#include <fcntl.h>
--#include <sys/wait.h>
--#include <errno.h>
--
--#include "checkers.h"
--#include "vector.h"
--#include "structs.h"
--#include "debug.h"
--
--#define PROGRAM_SIZE	100
--#define FIELD_PROGRAM
--
--#define strfieldcpy(to, from) \
--do { \
--	to[sizeof(to)-1] = '\0'; \
--	strncpy(to, from, sizeof(to)-1); \
--} while (0)
--
--int execute_program(char *path, char *value, int len)
--{
--	int retval;
--	int count;
--	int status;
--	int fds[2], null_fd;
--	pid_t pid;
--	char *pos;
--	char arg[PROGRAM_SIZE];
--	char *argv[sizeof(arg) / 2];
--	int i;
--
--	i = 0;
--
--	if (strchr(path, ' ')) {
--		strfieldcpy(arg, path);
--		pos = arg;
--		while (pos != NULL) {
--			if (pos[0] == '\'') {
--				/* don't separate if in apostrophes */
--				pos++;
--				argv[i] = strsep(&pos, "\'");
--				while (pos[0] == ' ')
--					pos++;
--			} else {
--				argv[i] = strsep(&pos, " ");
--			}
--			i++;
--		}
--	} else {
--		argv[i++] = path;
--	}
--	argv[i] =  NULL;
--
--	retval = pipe(fds);
--
--	if (retval != 0) {
--		condlog(0, "error creating pipe for callout: %s", strerror(errno));
--		return -1;
--	}
--
--	pid = fork();
--
--	switch(pid) {
--	case 0:
--		/* child */
--		close(STDOUT_FILENO);
--
--		/* dup write side of pipe to STDOUT */
--		if (dup(fds[1]) < 0)
--			return -1;
--
--		/* Ignore writes to stderr */
--		null_fd = open("/dev/null", O_WRONLY);
--		if (null_fd > 0) {
--			close(STDERR_FILENO);
--			dup(null_fd);
--			close(null_fd);
--		}
--
--		retval = execv(argv[0], argv);
--		condlog(0, "error execing %s : %s", argv[0], strerror(errno));
--		exit(-1);
--	case -1:
--		condlog(0, "fork failed: %s", strerror(errno));
--		close(fds[0]);
--		close(fds[1]);
--		return -1;
--	default:
--		/* parent reads from fds[0] */
--		close(fds[1]);
--		retval = 0;
--		i = 0;
--		while (1) {
--			count = read(fds[0], value + i, len - i-1);
--			if (count <= 0)
--				break;
--
--			i += count;
--			if (i >= len-1) {
--				condlog(0, "not enough space for response from %s", argv[0]);
--				retval = -1;
--				break;
--			}
--		}
<Skipped 21398 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/multipath-tools.git/commitdiff/17606c328534d7ad288a176df173724a1fc03138



More information about the pld-cvs-commit mailing list