[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, ¶ms);
-+
-+ 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 *)(¶m));
-+ 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(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8);
-+ buff_offset +=8 ;
-+ buff_offset +=8 ;
-+ break;
-+ case MPATH_PROTOCOL_ID_SAS:
-+ buff_offset += 3;
-+ memcpy(¶mp->private_buffer[buff_offset], ¶mp->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(¶mp->private_buffer[buff_offset], ¶mp->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