2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/Makefile.inc
|
|
|
|
+++ multipath-tools-0.4.8/Makefile.inc
|
|
|
|
@@ -13,7 +13,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
TOPDIR = ..
|
|
|
|
endif
|
|
|
|
|
|
|
|
-prefix =
|
|
|
|
+prefix =
|
|
|
|
exec_prefix = $(prefix)
|
|
|
|
bindir = $(exec_prefix)/sbin
|
|
|
|
libudevdir = ${prefix}/lib/udev
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/Makefile
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/Makefile
|
|
|
|
@@ -15,21 +15,29 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
$(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)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 activate_dm_linear $(DESTDIR)$(bindir)
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)
|
|
|
|
$(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir)
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d
|
|
|
|
- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)/etc/udev/rules.d/
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)/etc/udev/rules.d/70-kpartx.rules
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
|
|
|
|
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)
|
|
|
|
+ $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/mkinitrd/scripts
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 boot-kpartx.sh $(DESTDIR)/lib/mkinitrd/scripts
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 setup-kpartx.sh $(DESTDIR)/lib/mkinitrd/scripts
|
|
|
|
|
|
|
|
uninstall:
|
|
|
|
rm -f $(DESTDIR)$(bindir)/$(EXEC)
|
|
|
|
- rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz
|
|
|
|
+ rm -f $(DESTDIR)$(bindir)/activate_dm_linear
|
|
|
|
+ rm -f $(DESTDIR)$(libudevdir)/kpartx_id
|
|
|
|
+ rm -f $(DESTDIR)/etc/udev/rules.d/70-kpartx.rules
|
|
|
|
+ rm -f $(DESTDIR)$(mandir)/$(EXEC).8
|
|
|
|
+ rm -f $(DESTDIR)/lib/mkinitrd/scripts/boot-kpartx.sh
|
|
|
|
+ rm -f $(DESTDIR)/lib/mkinitrd/scripts/setup-kpartx.sh
|
|
|
|
|
|
|
|
clean:
|
|
|
|
- rm -f core *.o $(EXEC) *.gz
|
|
|
|
+ rm -f core *.o $(EXEC)
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/activate_dm_linear
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/activate_dm_linear
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,72 @@
|
|
|
|
+#!/bin/sh
|
|
|
|
+#
|
|
|
|
+# activate_dm_linear
|
|
|
|
+#
|
|
|
|
+# Activate a linear mapping on top of an existing block device.
|
|
|
|
+# This allows for partitions to be mapped via kpartx, so all
|
|
|
|
+# partitions on a device can be accessed.
|
|
|
|
+#
|
|
|
|
+
|
|
|
|
+RULE=/etc/udev/rules.d/62-dm_linear.rules
|
|
|
|
+
|
|
|
|
+if [ -z "$1" ] ; then
|
|
|
|
+ echo "Usage: $0 [-d] devname"
|
|
|
|
+ exit 1
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+if [ "$1" == "-d" ] ; then
|
|
|
|
+ remove_only=1
|
|
|
|
+ shift
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+if [ ! -b "$1" ] ; then
|
|
|
|
+ echo "$1 is not a block device"
|
|
|
|
+ exit 1
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+dev=${1#/dev/}
|
|
|
|
+
|
|
|
|
+if [ ! -d /sys/block/$dev ] ; then
|
|
|
|
+ echo "$1 is not a disk device"
|
|
|
|
+ exit 1
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+blksize=$(/sbin/blockdev --getsize $1)
|
|
|
|
+if [ $? -ne 0 ] ; then
|
|
|
|
+ echo "blockdev --getsize $1 failed: $?"
|
|
|
|
+ exit 1
|
|
|
|
+fi
|
|
|
|
+
|
2008-09-25 01:03:35 +02:00
|
|
|
+for link in $(udevadm info -q symlink -p /block/$dev) ; do
|
2008-07-25 04:06:36 +02:00
|
|
|
+ case "$link" in
|
|
|
|
+ */by-id/ata*)
|
|
|
|
+ atalink=${link#*/by-id/ata-}
|
|
|
|
+ ;;
|
|
|
|
+ */by-id/scsi*)
|
|
|
|
+ scsilink=${link#*/by-id/scsi-}
|
|
|
|
+ ;;
|
|
|
|
+ esac
|
|
|
|
+done
|
|
|
|
+if [ "$atalink" ] ; then
|
|
|
|
+ # Remove existing rules
|
|
|
|
+ echo "/$atalink/d
|
|
|
|
+w
|
|
|
|
+q
|
|
|
|
+" | ed $RULE > /dev/null 2>&1
|
|
|
|
+ [ "$remove_only" = 1 ] && exit 0
|
|
|
|
+ cat >> $RULE <<EOF
|
|
|
|
+ACTION=="add", KERNEL=="sd*[!0-9]", ENV{ID_VENDOR}=="ATA", ENV{ID_ATA_COMPAT}=="$atalink", RUN+="/bin/bash -c 'echo 0 $blksize linear \$major:\$minor 0 | /sbin/dmsetup create ata-\$env{ID_ATA_COMPAT} -u linear-ata-\$env{ID_ATA_COMPAT}'"
|
|
|
|
+EOF
|
|
|
|
+fi
|
|
|
|
+if [ "$scsilink" ] ; then
|
|
|
|
+ # Remove existing rules
|
|
|
|
+ echo "/$scsilink/d
|
|
|
|
+w
|
|
|
|
+q
|
|
|
|
+" | ed $RULE > /dev/null 2>&1
|
|
|
|
+ [ "$remove_only" = 1 ] && exit 0
|
|
|
|
+ # And create a new one
|
|
|
|
+ cat >> $RULE <<EOF
|
|
|
|
+ACTION=="add", KERNEL=="sd*[!0-9]", ENV{ID_BUS}=="scsi", ENV{ID_SERIAL}=="$scsilink", RUN+="/bin/bash -c 'echo 0 $blksize linear \$major:\$minor 0 | /sbin/dmsetup create \$env{ID_BUS}-\$env{ID_SERIAL} -u linear-\$env{ID_BUS}-\$env{ID_SERIAL}'"
|
|
|
|
+EOF
|
|
|
|
+fi
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/boot-kpartx.sh
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/boot-kpartx.sh
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,5 @@
|
|
|
|
+#!/bin/bash
|
|
|
|
+#%stage: block
|
|
|
|
+#%depends: dmroot
|
|
|
|
+#%if: "$root_kpartx"
|
|
|
|
+#%programs: /sbin/kpartx /lib/udev/kpartx_id
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/devmapper.c
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/devmapper.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -13,6 +13,7 @@
|
|
|
|
|
|
|
|
#define UUID_PREFIX "part%d-"
|
|
|
|
#define MAX_PREFIX_LEN 8
|
|
|
|
+#define PARAMS_SIZE 1024
|
|
|
|
|
|
|
|
extern int
|
|
|
|
dm_prereq (char * str, int x, int y, int z)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -251,3 +252,63 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
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;
|
|
|
|
+}
|
|
|
|
+
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/devmapper.h
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/devmapper.h
|
|
|
|
@@ -7,3 +7,4 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
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);
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/kpartx.c
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/kpartx.c
|
|
|
|
@@ -257,7 +257,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE)) {
|
|
|
|
- fprintf(stderr, "device mapper prerequisites not met\n");
|
|
|
|
+ fprintf(stderr, "device mapper prerequisites not met\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -314,8 +314,13 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (!uuid)
|
|
|
|
uuid = device + off;
|
|
|
|
|
|
|
|
- if (!mapname)
|
|
|
|
+ if (!mapname) {
|
|
|
|
mapname = device + off;
|
|
|
|
+ } else if (dm_no_partitions((unsigned int)MAJOR(buf.st_rdev),
|
|
|
|
+ (unsigned int)MINOR(buf.st_rdev))) {
|
|
|
|
+ /* Feature 'no_partitions' is set, return */
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
fd = open(device, O_RDONLY);
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -423,7 +428,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ADD:
|
|
|
|
- for (j=0, c = 0; j<n; j++) {
|
|
|
|
+ for (j = 0, c = 0; j < n; j++) {
|
|
|
|
if (slices[j].size == 0)
|
|
|
|
continue;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -474,6 +479,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
d = c;
|
|
|
|
while (c) {
|
|
|
|
for (j = 0; j < n; j++) {
|
|
|
|
+ uint64_t start;
|
|
|
|
int k = slices[j].container - 1;
|
|
|
|
|
|
|
|
if (slices[j].size == 0)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -484,7 +490,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Skip all simple slices */
|
|
|
|
- if (k < 0)
|
|
|
|
+ if (slices[j].container == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Check container slice */
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -499,10 +505,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
strip_slash(partname);
|
|
|
|
|
|
|
|
+ start = slices[j].start - slices[k].start;
|
|
|
|
if (safe_sprintf(params, "%d:%d %" PRIu64,
|
|
|
|
slices[k].major,
|
|
|
|
slices[k].minor,
|
|
|
|
- slices[j].start)) {
|
|
|
|
+ start)) {
|
|
|
|
fprintf(stderr, "params too small\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/kpartx.rules
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/kpartx.rules
|
|
|
|
@@ -9,7 +9,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
ENV{DM_TABLE_STATE}!="LIVE", GOTO="kpartx_end"
|
|
|
|
|
|
|
|
-ENV{DM_UUID}=="?*", IMPORT{program}=="/lib/udev/kpartx_id %M %m $env{DM_UUID}"
|
|
|
|
+ENV{DM_UUID}=="?*", IMPORT{program}=="kpartx_id %M %m $env{DM_UUID}"
|
|
|
|
|
|
|
|
OPTIONS="link_priority=50"
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -18,7 +18,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_NAME}"
|
|
|
|
|
|
|
|
# Create persistent links for dmraid tables
|
|
|
|
-ENV{DM_UUID}=="mpath-*", \
|
|
|
|
+ENV{DM_UUID}=="dmraid-*", \
|
|
|
|
+ SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_NAME}"
|
|
|
|
+
|
|
|
|
+# Create persistent links for linear tables
|
|
|
|
+ENV{DM_UUID}=="linear-*", \
|
|
|
|
SYMLINK+="disk/by-id/$env{DM_TYPE}-$env{DM_NAME}"
|
|
|
|
|
|
|
|
# Create persistent links for partitions
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -27,9 +31,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
# Create dm tables for partitions
|
|
|
|
ENV{DM_STATE}=="ACTIVE", ENV{DM_UUID}=="mpath-*", \
|
|
|
|
- RUN+="/sbin/kpartx -a -p -part /dev/$kernel"
|
|
|
|
+ RUN+="/sbin/kpartx -a -p _part /dev/$kernel"
|
|
|
|
ENV{DM_STATE}=="ACTIVE", ENV{DM_UUID}=="dmraid-*", \
|
|
|
|
- RUN+="/sbin/kpartx -a -p -part /dev/$kernel"
|
|
|
|
+ RUN+="/sbin/kpartx -a -p _part /dev/$kernel"
|
|
|
|
+ENV{DM_STATE}=="ACTIVE", ENV{DM_UUID}=="linear-*", \
|
|
|
|
+ RUN+="/sbin/kpartx -a -p _part /dev/$kernel"
|
|
|
|
|
|
|
|
LABEL="kpartx_end"
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/kpartx_id
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/kpartx_id
|
|
|
|
@@ -50,7 +50,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
# Set the name of the table. We're only interested in dmraid,
|
|
|
|
-# multipath, and kpartx tables; everything else is ignored.
|
|
|
|
+# multipath, linear, and kpartx tables; everything else is ignored.
|
|
|
|
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)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -61,6 +61,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
mpath-*)
|
|
|
|
dmdeps=$($DMSETUP deps -u $dmuuid)
|
|
|
|
;;
|
|
|
|
+ linear-*)
|
|
|
|
+ dmtbl=linear
|
|
|
|
+ dmuuid=${dmuuid#*-}
|
|
|
|
+ ;;
|
|
|
|
esac
|
|
|
|
elif [ "$dmtbl" = "mpath" ] ; then
|
|
|
|
dmname=$tblname
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -72,8 +76,8 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
[ -n "$dmpart" ] && echo "DM_PART=$dmpart"
|
|
|
|
|
|
|
|
-# Figure out the type of the map. For non-multipath maps it's
|
|
|
|
-# always 'raid'.
|
|
|
|
+# Figure out the type of the map. For non-multipath non-linear
|
|
|
|
+# maps it's always 'raid'.
|
|
|
|
if [ -n "$dmdeps" ] ; then
|
|
|
|
case "$dmdeps" in
|
|
|
|
*\(94,*)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -86,6 +90,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
echo "DM_TYPE=scsi"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
+elif [ "$dmtbl" = linear ]; then
|
|
|
|
+ echo "DM_TYPE=${dmuuid%%-*}"
|
|
|
|
+ echo "DM_NAME=${dmuuid#*-}"
|
|
|
|
else
|
|
|
|
echo "DM_TYPE=raid"
|
|
|
|
fi
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/kpartx/setup-kpartx.sh
|
|
|
|
+++ multipath-tools-0.4.8/kpartx/setup-kpartx.sh
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,36 @@
|
|
|
|
+#!/bin/bash
|
|
|
|
+#
|
|
|
|
+#%stage: partitions
|
|
|
|
+#
|
|
|
|
+if [ -x /sbin/dmsetup ]; then
|
|
|
|
+ kpartx_blockdev=
|
|
|
|
+
|
|
|
|
+ # always activate kpartx when using dm block
|
|
|
|
+ [ "$DM_BLOCK" ] && root_kpartx=1
|
|
|
|
+ # always activate kpartx for multipathing
|
|
|
|
+ use_script multipath && root_kpartx=1
|
|
|
|
+ for bd in $blockdev ; do
|
|
|
|
+ update_blockdev $bd
|
|
|
|
+ if [ "$blockdriver" = device-mapper ]; then
|
|
|
|
+ dm_uuid=$(dmsetup info -c --noheadings -o uuid -j $blockmajor -m $blockminor)
|
|
|
|
+ case $dm_uuid in
|
|
|
|
+ part*)
|
|
|
|
+ dm_uuid="${dm_uuid#*-}"
|
|
|
|
+ kpartx_blockdev="$kpartx_blockdev $(majorminor2blockdev $(dmsetup info -u $dm_uuid --noheadings -c -o major,minor))"
|
|
|
|
+ root_kpartx=1
|
|
|
|
+ ;;
|
|
|
|
+ *)
|
|
|
|
+ kpartx_blockdev="$kpartx_blockdev $bd"
|
|
|
|
+ ;;
|
|
|
|
+ esac
|
|
|
|
+ else
|
|
|
|
+ kpartx_blockdev="$kpartx_blockdev $bd"
|
|
|
|
+ fi
|
|
|
|
+ done
|
|
|
|
+
|
|
|
|
+ blockdev="$kpartx_blockdev"
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+if use_script kpartx; then
|
|
|
|
+ cp /etc/udev/rules.d/70-kpartx.rules $tmp_mnt/etc/udev/rules.d
|
|
|
|
+fi
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/Makefile
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/Makefile
|
|
|
|
@@ -25,9 +25,8 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
$(LIBS): $(OBJS)
|
|
|
|
$(CC) $(SHARED_FLAGS) $(CFLAGS) -o $@ $(OBJS)
|
|
|
|
|
|
|
|
-install:
|
|
|
|
- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir)
|
|
|
|
- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir)/$(LIBS)
|
|
|
|
+install: $(LIBS)
|
|
|
|
+ $(INSTALL_PROGRAM) -D $(LIBS) $(DESTDIR)$(libdir)/$(LIBS)
|
|
|
|
|
|
|
|
uninstall:
|
|
|
|
rm -f $(DESTDIR)$(libdir)/$(LIBS)
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/alias.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/alias.c
|
|
|
|
@@ -86,7 +86,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
sigset_t set, oldset;
|
|
|
|
struct flock lock;
|
|
|
|
int err;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
memset(&lock, 0, sizeof(lock));
|
|
|
|
lock.l_type = F_WRLCK;
|
|
|
|
lock.l_whence = SEEK_SET;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -149,7 +149,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
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));
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -171,7 +171,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
fsync(fd);
|
|
|
|
condlog(3, "Initialized new bindings file [%s]", file);
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
return fd;
|
|
|
|
|
|
|
|
fail:
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/blacklist.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/blacklist.c
|
|
|
|
@@ -16,7 +16,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
store_ble (vector blist, char * str, int origin)
|
|
|
|
{
|
|
|
|
struct blentry * ble;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!str)
|
|
|
|
return 0;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -61,12 +61,12 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
vector_set_slot(blist, ble);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
extern int
|
|
|
|
set_ble_device (vector blist, char * vendor, char * product, int origin)
|
|
|
|
{
|
|
|
|
struct blentry_device * ble;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!blist)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -142,14 +142,14 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
int
|
|
|
|
_blacklist_exceptions (vector elist, char * str)
|
|
|
|
{
|
|
|
|
- int i;
|
|
|
|
- struct blentry * ele;
|
|
|
|
+ int i;
|
|
|
|
+ struct blentry * ele;
|
|
|
|
|
|
|
|
- vector_foreach_slot (elist, ele, i) {
|
|
|
|
- if (!regexec(&ele->regex, str, 0, NULL, 0))
|
|
|
|
+ vector_foreach_slot (elist, ele, i) {
|
|
|
|
+ if (!regexec(&ele->regex, str, 0, NULL, 0))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
- return 0;
|
|
|
|
+ return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -194,11 +194,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#define LOG_BLIST(M) \
|
|
|
|
- if (vendor && product) \
|
|
|
|
+ if (vendor && product) \
|
|
|
|
condlog(3, "%s: (%s:%s) %s", dev, vendor, product, (M)); \
|
|
|
|
- else if (wwid) \
|
|
|
|
- condlog(3, "%s: (%s) %s", dev, wwid, (M)); \
|
|
|
|
- else \
|
|
|
|
+ else if (wwid) \
|
|
|
|
+ condlog(3, "%s: (%s) %s", dev, wwid, (M)); \
|
|
|
|
+ else \
|
|
|
|
condlog(3, "%s: %s", dev, (M))
|
|
|
|
|
|
|
|
void
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -300,7 +300,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (r > 0)
|
|
|
|
return r;
|
|
|
|
r = _filter_device(conf->blist_device, conf->elist_device,
|
|
|
|
- pp->vendor_id, pp->product_id);
|
|
|
|
+ pp->vendor_id, pp->product_id);
|
|
|
|
if (r > 0)
|
|
|
|
return r;
|
|
|
|
r = _filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid);
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/callout.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/callout.c
|
|
|
|
@@ -83,8 +83,8 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
null_fd = open("/dev/null", O_WRONLY);
|
|
|
|
if (null_fd > 0) {
|
|
|
|
close(STDERR_FILENO);
|
|
|
|
- dup(null_fd);
|
|
|
|
- close(null_fd);
|
|
|
|
+ if (dup(null_fd) >= 0)
|
|
|
|
+ close(null_fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
retval = execv(argv[0], argv);
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/config.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/config.c
|
|
|
|
@@ -50,42 +50,55 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+hwe_regmatch (struct hwentry *hwe1, struct hwentry *hwe2)
|
|
|
|
+{
|
|
|
|
+ regex_t vre, pre, rre;
|
|
|
|
+ int retval = 1;
|
|
|
|
+
|
|
|
|
+ if (hwe1->vendor &&
|
|
|
|
+ regcomp(&vre, hwe1->vendor, REG_EXTENDED|REG_NOSUB))
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ if (hwe1->product &&
|
|
|
|
+ regcomp(&pre, hwe1->product, REG_EXTENDED|REG_NOSUB))
|
|
|
|
+ goto out_vre;
|
|
|
|
+
|
|
|
|
+ if (hwe1->revision &&
|
|
|
|
+ regcomp(&rre, hwe1->revision, REG_EXTENDED|REG_NOSUB))
|
|
|
|
+ goto out_pre;
|
|
|
|
+
|
|
|
|
+ if ((!hwe1->vendor || !regexec(&vre, hwe2->vendor, 0, NULL, 0)) &&
|
|
|
|
+ (!hwe1->product || !regexec(&pre, hwe2->product, 0, NULL, 0)) &&
|
|
|
|
+ (!hwe1->revision || !regexec(&rre, hwe2->revision, 0, NULL, 0)))
|
|
|
|
+ retval = 0;
|
|
|
|
+
|
|
|
|
+ if (hwe1->revision)
|
|
|
|
+ regfree(&rre);
|
|
|
|
+out_pre:
|
|
|
|
+ if (hwe1->product)
|
|
|
|
+ regfree(&pre);
|
|
|
|
+out_vre:
|
|
|
|
+ if (hwe1->vendor)
|
|
|
|
+ regfree(&vre);
|
|
|
|
+out:
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
struct hwentry *
|
|
|
|
find_hwe (vector hwtable, char * vendor, char * product, char * revision)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
- struct hwentry *hwe, *ret = NULL;
|
|
|
|
- regex_t vre, pre, rre;
|
|
|
|
+ struct hwentry hwe, *tmp, *ret = NULL;
|
|
|
|
|
|
|
|
- vector_foreach_slot (hwtable, hwe, i) {
|
|
|
|
- if (hwe->vendor &&
|
|
|
|
- regcomp(&vre, hwe->vendor, REG_EXTENDED|REG_NOSUB))
|
|
|
|
- break;
|
|
|
|
- if (hwe->product &&
|
|
|
|
- regcomp(&pre, hwe->product, REG_EXTENDED|REG_NOSUB)) {
|
|
|
|
- regfree(&vre);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if (hwe->revision &&
|
|
|
|
- regcomp(&rre, hwe->revision, REG_EXTENDED|REG_NOSUB)) {
|
|
|
|
- regfree(&vre);
|
|
|
|
- regfree(&pre);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if ((!hwe->vendor || !regexec(&vre, vendor, 0, NULL, 0)) &&
|
|
|
|
- (!hwe->product || !regexec(&pre, product, 0, NULL, 0)) &&
|
|
|
|
- (!hwe->revision || !regexec(&rre, revision, 0, NULL, 0)))
|
|
|
|
- ret = hwe;
|
|
|
|
-
|
|
|
|
- if (hwe->revision)
|
|
|
|
- regfree(&rre);
|
|
|
|
- if (hwe->product)
|
|
|
|
- regfree(&pre);
|
|
|
|
- if (hwe->vendor)
|
|
|
|
- regfree(&vre);
|
|
|
|
-
|
|
|
|
- if (ret)
|
|
|
|
- break;
|
|
|
|
+ hwe.vendor = vendor;
|
|
|
|
+ hwe.product = product;
|
|
|
|
+ hwe.revision = revision;
|
|
|
|
+ vector_foreach_slot (hwtable, tmp, i) {
|
|
|
|
+ if (hwe_regmatch(tmp, &hwe))
|
|
|
|
+ continue;
|
|
|
|
+ ret = tmp;
|
|
|
|
+ break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -289,25 +302,25 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (find_hwe_strmatch(hwtable, dhwe))
|
|
|
|
return 0;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!(hwe = alloc_hwe()))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (!dhwe->vendor || !(hwe->vendor = set_param_str(dhwe->vendor)))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!dhwe->product || !(hwe->product = set_param_str(dhwe->product)))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (dhwe->revision && !(hwe->revision = set_param_str(dhwe->revision)))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (dhwe->getuid && !(hwe->getuid = set_param_str(dhwe->getuid)))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
if (dhwe->features && !(hwe->features = set_param_str(dhwe->features)))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (dhwe->hwhandler && !(hwe->hwhandler = set_param_str(dhwe->hwhandler)))
|
|
|
|
goto out;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -316,10 +329,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (dhwe->checker_name && !(hwe->checker_name = set_param_str(dhwe->checker_name)))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (dhwe->prio_name && !(hwe->prio_name = set_param_str(dhwe->prio_name)))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
hwe->pgpolicy = dhwe->pgpolicy;
|
|
|
|
hwe->pgfailback = dhwe->pgfailback;
|
|
|
|
hwe->rr_weight = dhwe->rr_weight;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -348,7 +361,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
vector_foreach_slot(hw, hwe1, i) {
|
|
|
|
j = i+1;
|
|
|
|
vector_foreach_slot_after(hw, hwe2, j) {
|
|
|
|
- if (hwe_strmatch(hwe1, hwe2))
|
|
|
|
+ if (hwe_regmatch(hwe1, hwe2))
|
|
|
|
continue;
|
|
|
|
/* dup */
|
|
|
|
merge_hwe(hwe1, hwe2);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -393,6 +406,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (conf->hwhandler)
|
|
|
|
FREE(conf->hwhandler);
|
|
|
|
|
|
|
|
+ if (conf->bindings_file)
|
|
|
|
+ FREE(conf->bindings_file);
|
|
|
|
+
|
|
|
|
free_blacklist(conf->blist_devnode);
|
|
|
|
free_blacklist(conf->blist_wwid);
|
|
|
|
free_blacklist_device(conf->blist_device);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -425,7 +441,6 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
conf->dev_type = DEV_NONE;
|
|
|
|
conf->minio = 1000;
|
|
|
|
conf->max_fds = 0;
|
|
|
|
- conf->bindings_file = DEFAULT_BINDINGS_FILE;
|
|
|
|
conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
|
|
|
|
|
|
|
|
/*
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -443,12 +458,15 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/*
|
|
|
|
* read the config file
|
|
|
|
*/
|
|
|
|
+ set_current_keywords(&conf->keywords);
|
|
|
|
+ alloc_keywords();
|
|
|
|
if (filepresent(file)) {
|
|
|
|
- set_current_keywords(&conf->keywords);
|
|
|
|
if (init_data(file, init_keywords)) {
|
|
|
|
condlog(0, "error parsing config file");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
+ } else {
|
|
|
|
+ init_keywords();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -503,7 +521,6 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (conf->mptable == NULL) {
|
|
|
|
conf->mptable = vector_alloc();
|
|
|
|
-
|
|
|
|
if (!conf->mptable)
|
|
|
|
goto out;
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -522,9 +539,12 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (conf->hwhandler == NULL)
|
|
|
|
conf->hwhandler = set_default(DEFAULT_HWHANDLER);
|
|
|
|
|
|
|
|
+ if (conf->bindings_file == NULL)
|
|
|
|
+ conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
|
|
|
|
+
|
|
|
|
if (!conf->selector || !conf->udev_dir || !conf->multipath_dir ||
|
|
|
|
!conf->getuid || !conf->features ||
|
|
|
|
- !conf->hwhandler)
|
|
|
|
+ !conf->hwhandler || !conf->bindings_file)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
if (!conf->prio_name)
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/configure.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/configure.c
|
|
|
|
@@ -162,7 +162,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
mpp->alias);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (pathcount(mpp, PATH_UP) == 0) {
|
|
|
|
mpp->action = ACT_NOTHING;
|
|
|
|
condlog(3, "%s: set ACT_NOTHING (no usable path)",
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -272,7 +272,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!mpp || !mpp->pg)
|
|
|
|
return 0;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
vector_foreach_slot (mpp->pg, pgp, i) {
|
|
|
|
if (!pgp->paths)
|
|
|
|
continue;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -402,7 +402,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (strlen(pp->dev))
|
|
|
|
return 0; /* alive */
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
return 1; /* dead */
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -460,13 +460,13 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
remove_map(mpp, vecs, 0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
|
|
|
|
pp2 = VECTOR_SLOT(pathvec, i);
|
|
|
|
|
|
|
|
if (strcmp(pp1->wwid, pp2->wwid))
|
|
|
|
continue;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!pp2->size)
|
|
|
|
continue;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/defaults.h
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/defaults.h
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -1,4 +1,4 @@
|
|
|
|
-#define DEFAULT_GETUID "/lib/udev/scsi_id -g -u -s /block/%n"
|
|
|
|
+#define DEFAULT_GETUID "/lib/udev/scsi_id -g -u /dev/%n"
|
|
|
|
#define DEFAULT_UDEVDIR "/dev"
|
|
|
|
#define DEFAULT_MULTIPATHDIR "/lib/multipath"
|
|
|
|
#define DEFAULT_SELECTOR "round-robin 0"
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/devmapper.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/devmapper.c
|
|
|
|
@@ -161,9 +161,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
dm_task_no_open_count(dmt);
|
|
|
|
- dm_task_skip_lockfs(dmt); /* for DM_DEVICE_RESUME */
|
|
|
|
+ dm_task_skip_lockfs(dmt); /* for DM_DEVICE_RESUME */
|
|
|
|
#ifdef LIBDM_API_FLUSH
|
|
|
|
- dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */
|
|
|
|
+ dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
r = dm_task_run (dmt);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -340,11 +340,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (!dmt)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
- if (!dm_task_set_name (dmt, name))
|
|
|
|
- goto uuidout;
|
|
|
|
+ if (!dm_task_set_name (dmt, name))
|
|
|
|
+ goto uuidout;
|
|
|
|
|
|
|
|
if (!dm_task_run(dmt))
|
|
|
|
- goto uuidout;
|
|
|
|
+ goto uuidout;
|
|
|
|
|
|
|
|
uuidtmp = dm_task_get_uuid(dmt);
|
|
|
|
if (uuidtmp) {
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -466,7 +466,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
dm_task_destroy(dmt);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
int
|
|
|
|
dm_get_opencount (const char * mapname)
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -491,7 +491,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
dm_task_destroy(dmt);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
int
|
|
|
|
dm_get_minor (char * mapname)
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -516,7 +516,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
dm_task_destroy(dmt);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
extern int
|
|
|
|
dm_flush_map (const char * mapname)
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -534,7 +534,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (dm_get_opencount(mapname)) {
|
|
|
|
condlog(2, "%s: map in use", mapname);
|
|
|
|
return 1;
|
|
|
|
- }
|
|
|
|
+ }
|
|
|
|
|
|
|
|
r = dm_simplecmd(DM_DEVICE_REMOVE, mapname);
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -746,8 +746,8 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
vector_set_slot(mp, mpp);
|
|
|
|
mpp = NULL;
|
|
|
|
next:
|
|
|
|
- next = names->next;
|
|
|
|
- names = (void *) names + next;
|
|
|
|
+ next = names->next;
|
|
|
|
+ names = (void *) names + next;
|
|
|
|
} while (next);
|
|
|
|
|
|
|
|
r = 0;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -927,7 +927,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
*/
|
|
|
|
strstr(params, dev_t)
|
|
|
|
) {
|
|
|
|
- /*
|
|
|
|
+ /*
|
|
|
|
* then it's a kpartx generated partition.
|
|
|
|
* remove it.
|
|
|
|
*/
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -957,7 +957,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
{
|
|
|
|
int r = 1;
|
|
|
|
struct dm_task *dmt = NULL;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mapname)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1045,7 +1045,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
*/
|
|
|
|
strstr(buff, dev_t)
|
|
|
|
) {
|
|
|
|
- /*
|
|
|
|
+ /*
|
|
|
|
* then it's a kpartx generated partition.
|
|
|
|
* Rename it.
|
|
|
|
*/
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1083,7 +1083,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!dm_task_set_newname(dmt, new))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
dm_task_no_open_count(dmt);
|
|
|
|
|
|
|
|
if (!dm_task_run(dmt))
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/dict.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/dict.c
|
|
|
|
@@ -88,7 +88,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!conf->getuid)
|
|
|
|
return 1;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -267,6 +267,17 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+bindings_file_handler(vector strvec)
|
|
|
|
+{
|
|
|
|
+ conf->bindings_file = set_value(strvec);
|
|
|
|
+
|
|
|
|
+ if (!conf->bindings_file)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* blacklist block handlers
|
|
|
|
*/
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -338,12 +349,12 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
static int
|
|
|
|
ble_except_wwid_handler(vector strvec)
|
|
|
|
{
|
|
|
|
- char * buff;
|
|
|
|
+ char * buff;
|
|
|
|
|
|
|
|
- buff = set_value(strvec);
|
|
|
|
+ buff = set_value(strvec);
|
|
|
|
|
|
|
|
- if (!buff)
|
|
|
|
- return 1;
|
|
|
|
+ if (!buff)
|
|
|
|
+ return 1;
|
|
|
|
|
|
|
|
return store_ble(conf->elist_wwid, buff, ORIGIN_CONFIG);
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -453,7 +464,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!hwe)
|
|
|
|
return 1;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
hwe->vendor = set_value(strvec);
|
|
|
|
|
|
|
|
if (!hwe->vendor)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -469,7 +480,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!hwe)
|
|
|
|
return 1;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
hwe->product = set_value(strvec);
|
|
|
|
|
|
|
|
if (!hwe->product)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -527,7 +538,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
hw_selector_handler(vector strvec)
|
|
|
|
{
|
|
|
|
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!hwe)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -559,7 +570,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
hw_features_handler(vector strvec)
|
|
|
|
{
|
|
|
|
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!hwe)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -575,7 +586,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
hw_handler_handler(vector strvec)
|
|
|
|
{
|
|
|
|
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!hwe)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -781,7 +792,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (!mpe)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
- mpe->alias = set_value(strvec);
|
|
|
|
+ mpe->alias = set_value(strvec);
|
|
|
|
|
|
|
|
if (!mpe->alias)
|
|
|
|
return 1;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -813,7 +824,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
mp_selector_handler(vector strvec)
|
|
|
|
{
|
|
|
|
struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mpe)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -981,7 +992,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (!mpe->pgpolicy)
|
|
|
|
return 0;
|
|
|
|
get_pgpolicy_name(str, POLICY_NAME_SIZE, mpe->pgpolicy);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
return snprintf(buff, len, "%s", str);
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1194,7 +1205,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
get_pgpolicy_name(str, POLICY_NAME_SIZE, hwe->pgpolicy);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
return snprintf(buff, len, "%s", str);
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1362,7 +1373,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
get_pgpolicy_name(str, POLICY_NAME_SIZE, conf->pgpolicy);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
return snprintf(buff, len, "%s", str);
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1454,7 +1465,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (conf->max_fds < 0)
|
|
|
|
- return snprintf(buff, len, "unlimited");
|
|
|
|
+ return snprintf(buff, len, "unlimited");
|
|
|
|
return snprintf(buff, len, "%d", conf->max_fds);
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1520,6 +1531,18 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
+snprint_def_bindings_file (char * buff, int len, void * data)
|
|
|
|
+{
|
|
|
|
+ if (conf->bindings_file == NULL)
|
|
|
|
+ return 0;
|
|
|
|
+ if (strlen(conf->bindings_file) == strlen(DEFAULT_BINDINGS_FILE) &&
|
|
|
|
+ !strcmp(conf->bindings_file, DEFAULT_BINDINGS_FILE))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return snprintf(buff, len, "%s", conf->bindings_file);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
snprint_ble_simple (char * buff, int len, void * data)
|
|
|
|
{
|
|
|
|
struct blentry * ble = (struct blentry *)data;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1534,7 +1557,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
return snprintf(buff, len, "\"%s\"", bled->vendor);
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
static int
|
|
|
|
snprint_bled_product (char * buff, int len, void * data)
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1542,7 +1565,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
return snprintf(buff, len, "\"%s\"", bled->product);
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
#define __deprecated
|
|
|
|
|
|
|
|
void
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1566,6 +1589,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
|
|
|
|
install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
|
|
|
|
install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names);
|
|
|
|
+ install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file);
|
|
|
|
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
|
|
|
|
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
|
|
|
|
__deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/discovery.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/discovery.c
|
|
|
|
@@ -70,7 +70,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
condlog(0, "path too small");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (strncmp(devname,"cciss",5) && !filepresent(path)) {
|
|
|
|
condlog(4, "path %s not present", path);
|
|
|
|
return 0;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -179,7 +179,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
int
|
|
|
|
sysfs_get_fc_nodename (struct sysfs_device * dev, char * node,
|
|
|
|
unsigned int host, unsigned int channel,
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -187,7 +187,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
{
|
|
|
|
char attr_path[SYSFS_PATH_SIZE], *attr;
|
|
|
|
|
|
|
|
- if (safe_sprintf(attr_path,
|
|
|
|
+ if (safe_sprintf(attr_path,
|
|
|
|
"/class/fc_transport/target%i:%i:%i",
|
|
|
|
host, channel, target)) {
|
|
|
|
condlog(0, "attr_path too small");
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -202,10 +202,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * udev might be slow creating node files : wait
|
|
|
|
- */
|
|
|
|
+
|
|
|
|
static int
|
|
|
|
opennode (char * dev, int mode)
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -244,11 +241,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
condlog(0, "Cannot open /proc/partitions");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
while (!feof(fd)) {
|
|
|
|
int r = fscanf(fd,"%u %u %*d %s",&tmpmaj, &tmpmin, dev);
|
|
|
|
if (!r) {
|
|
|
|
- fscanf(fd,"%*s\n");
|
|
|
|
+ r = fscanf(fd,"%*s\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (r != 3)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -280,62 +277,62 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
|
|
|
|
void *resp, int mx_resp_len, int noisy)
|
|
|
|
{
|
|
|
|
- unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
|
|
|
|
- { INQUIRY_CMD, 0, 0, 0, 0, 0 };
|
|
|
|
- unsigned char sense_b[SENSE_BUFF_LEN];
|
|
|
|
- struct sg_io_hdr io_hdr;
|
|
|
|
-
|
|
|
|
- if (cmddt)
|
|
|
|
- inqCmdBlk[1] |= 2;
|
|
|
|
- if (evpd)
|
|
|
|
- inqCmdBlk[1] |= 1;
|
|
|
|
- inqCmdBlk[2] = (unsigned char) pg_op;
|
|
|
|
+ unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
|
|
|
|
+ { INQUIRY_CMD, 0, 0, 0, 0, 0 };
|
|
|
|
+ unsigned char sense_b[SENSE_BUFF_LEN];
|
|
|
|
+ struct sg_io_hdr io_hdr;
|
|
|
|
+
|
|
|
|
+ if (cmddt)
|
|
|
|
+ inqCmdBlk[1] |= 2;
|
|
|
|
+ if (evpd)
|
|
|
|
+ inqCmdBlk[1] |= 1;
|
|
|
|
+ inqCmdBlk[2] = (unsigned char) pg_op;
|
|
|
|
inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
|
|
|
|
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
|
|
|
|
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
|
|
- io_hdr.interface_id = 'S';
|
|
|
|
- io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
|
|
- io_hdr.mx_sb_len = sizeof (sense_b);
|
|
|
|
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
- io_hdr.dxfer_len = mx_resp_len;
|
|
|
|
- io_hdr.dxferp = resp;
|
|
|
|
- io_hdr.cmdp = inqCmdBlk;
|
|
|
|
- io_hdr.sbp = sense_b;
|
|
|
|
- io_hdr.timeout = DEF_TIMEOUT;
|
|
|
|
-
|
|
|
|
- if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
|
|
|
|
- return -1;
|
|
|
|
-
|
|
|
|
- /* treat SG_ERR here to get rid of sg_err.[ch] */
|
|
|
|
- io_hdr.status &= 0x7e;
|
|
|
|
- if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
|
|
|
|
- (0 == io_hdr.driver_status))
|
|
|
|
- return 0;
|
|
|
|
- if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
|
|
|
|
- (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
|
|
|
|
- (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
|
|
|
|
- if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
|
|
|
|
- int sense_key;
|
|
|
|
- unsigned char * sense_buffer = io_hdr.sbp;
|
|
|
|
- if (sense_buffer[0] & 0x2)
|
|
|
|
- sense_key = sense_buffer[1] & 0xf;
|
|
|
|
- else
|
|
|
|
- sense_key = sense_buffer[2] & 0xf;
|
|
|
|
- if(RECOVERED_ERROR == sense_key)
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return -1;
|
|
|
|
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
|
|
+ io_hdr.interface_id = 'S';
|
|
|
|
+ io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
|
|
+ io_hdr.mx_sb_len = sizeof (sense_b);
|
|
|
|
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
+ io_hdr.dxfer_len = mx_resp_len;
|
|
|
|
+ io_hdr.dxferp = resp;
|
|
|
|
+ io_hdr.cmdp = inqCmdBlk;
|
|
|
|
+ io_hdr.sbp = sense_b;
|
|
|
|
+ io_hdr.timeout = DEF_TIMEOUT;
|
|
|
|
+
|
|
|
|
+ if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ /* treat SG_ERR here to get rid of sg_err.[ch] */
|
|
|
|
+ io_hdr.status &= 0x7e;
|
|
|
|
+ if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
|
|
|
|
+ (0 == io_hdr.driver_status))
|
|
|
|
+ return 0;
|
|
|
|
+ if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
|
|
|
|
+ (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
|
|
|
|
+ (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
|
|
|
|
+ if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
|
|
|
|
+ int sense_key;
|
|
|
|
+ unsigned char * sense_buffer = io_hdr.sbp;
|
|
|
|
+ if (sense_buffer[0] & 0x2)
|
|
|
|
+ sense_key = sense_buffer[1] & 0xf;
|
|
|
|
+ else
|
|
|
|
+ sense_key = sense_buffer[2] & 0xf;
|
|
|
|
+ if(RECOVERED_ERROR == sense_key)
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
get_serial (char * str, int maxlen, int fd)
|
|
|
|
{
|
|
|
|
- int len = 0;
|
|
|
|
- char buff[MX_ALLOC_LEN + 1] = {0};
|
|
|
|
+ int len = 0;
|
|
|
|
+ char buff[MX_ALLOC_LEN + 1] = {0};
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
- return 1;
|
|
|
|
+ return 1;
|
|
|
|
|
|
|
|
if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) {
|
|
|
|
len = buff[3];
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -347,7 +344,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
- return 1;
|
|
|
|
+ return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -459,7 +456,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* host / bus / target / lun
|
|
|
|
- */
|
|
|
|
+ */
|
|
|
|
basename(parent->devpath, attr_path);
|
|
|
|
pp->sg_id.lun = 0;
|
|
|
|
sscanf(attr_path, "%i.%i.%x",
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/dmparser.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/dmparser.c
|
|
|
|
@@ -59,7 +59,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
minio = mp->minio;
|
|
|
|
p = mp->params;
|
|
|
|
freechar = sizeof(mp->params);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
shift = snprintf(p, freechar, "%s %s %i %i",
|
|
|
|
mp->features, mp->hwhandler,
|
|
|
|
VECTOR_SIZE(mp->pg), mp->bestpg);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -70,7 +70,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
p += shift;
|
|
|
|
freechar -= shift;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
vector_foreach_slot (mp->pg, pgp, i) {
|
|
|
|
pgp = VECTOR_SLOT(mp->pg, i);
|
|
|
|
shift = snprintf(p, freechar, " %s %i 1", mp->selector,
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -184,11 +184,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
num_pg = atoi(word);
|
|
|
|
FREE(word);
|
|
|
|
|
|
|
|
- if (num_pg > 0 && !mpp->pg) {
|
|
|
|
+ if (num_pg > 0 && !mpp->pg)
|
|
|
|
mpp->pg = vector_alloc();
|
|
|
|
- if (!mpp->pg)
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
+
|
|
|
|
+ if (!mpp->pg)
|
|
|
|
+ return 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* first pg to try
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -221,7 +221,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
num_pg_args = atoi(word);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (merge_words(&mpp->selector, word, 1)) {
|
|
|
|
FREE(word);
|
|
|
|
goto out1;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -239,7 +239,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
* paths
|
|
|
|
*/
|
|
|
|
pgp = alloc_pathgroup();
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!pgp)
|
|
|
|
goto out;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/hwtable.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/hwtable.c
|
|
|
|
@@ -172,7 +172,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/* HP Smart Array */
|
|
|
|
.vendor = "HP",
|
|
|
|
.product = "LOGICAL VOLUME.*",
|
|
|
|
- .getuid = "/lib/udev/scsi_id -n -g -u -s /block/%n",
|
|
|
|
+ .getuid = "/lib/udev/scsi_id -n -g -u /dev/%n",
|
|
|
|
.features = DEFAULT_FEATURES,
|
|
|
|
.hwhandler = DEFAULT_HWHANDLER,
|
|
|
|
.selector = DEFAULT_SELECTOR,
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -214,7 +214,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
{
|
|
|
|
.vendor = "EMC",
|
|
|
|
.product = "SYMMETRIX",
|
|
|
|
- .getuid = "/lib/udev/scsi_id -g -u -ppre-spc3-83 -s /block/%n",
|
|
|
|
+ .getuid = "/lib/udev/scsi_id -g -u -ppre-spc3-83 /dev/%n",
|
|
|
|
.features = DEFAULT_FEATURES,
|
|
|
|
.hwhandler = DEFAULT_HWHANDLER,
|
|
|
|
.selector = DEFAULT_SELECTOR,
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -533,7 +533,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
.no_path_retry = NO_PATH_RETRY_UNDEF,
|
|
|
|
.minio = 128,
|
|
|
|
.checker_name = DIRECTIO,
|
|
|
|
- .prio_name = PRIO_NETAPP,
|
|
|
|
+ .prio_name = PRIO_ONTAP,
|
|
|
|
},
|
|
|
|
/*
|
|
|
|
* IBM NSeries (NETAPP) controller family
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -554,7 +554,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
.no_path_retry = NO_PATH_RETRY_UNDEF,
|
|
|
|
.minio = 128,
|
|
|
|
.checker_name = DIRECTIO,
|
|
|
|
- .prio_name = PRIO_NETAPP,
|
|
|
|
+ .prio_name = PRIO_ONTAP,
|
|
|
|
},
|
|
|
|
/*
|
|
|
|
* Pillar Data controller family
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/log.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/log.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -18,7 +18,7 @@
|
|
|
|
static void dump_logarea (void)
|
|
|
|
{
|
|
|
|
struct logmsg * msg;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
logdbg(stderr, "\n==== area: start addr = %p, end addr = %p ====\n",
|
|
|
|
la->start, la->end);
|
|
|
|
logdbg(stderr, "|addr |next |prio|msg\n");
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -34,12 +34,12 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
logdbg(stderr, "\n\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
-
|
|
|
|
+
|
|
|
|
static int logarea_init (int size)
|
|
|
|
{
|
|
|
|
logdbg(stderr,"enter logarea_init\n");
|
|
|
|
la = (struct logarea *)MALLOC(sizeof(struct logarea));
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!la)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -107,7 +107,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
lastmsg = (struct logmsg *)la->tail;
|
|
|
|
|
|
|
|
if (!la->empty) {
|
|
|
|
- fwd = sizeof(struct logmsg) +
|
|
|
|
+ fwd = sizeof(struct logmsg) +
|
|
|
|
strlen((char *)&lastmsg->str) * sizeof(char) + 1;
|
|
|
|
la->tail += ALIGN(fwd, sizeof(void *));
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -118,11 +118,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/* not enough space on tail : rewind */
|
|
|
|
if (la->head <= la->tail && len > (la->end - la->tail)) {
|
|
|
|
logdbg(stderr, "enqueue: rewind tail to %p\n", la->tail);
|
|
|
|
- if (la->head == la->start ) {
|
|
|
|
- logdbg(stderr, "enqueue: can not rewind tail, drop msg\n");
|
|
|
|
- la->tail = lastmsg;
|
|
|
|
- return 1; /* can't reuse */
|
|
|
|
- }
|
|
|
|
+ if (la->head == la->start ) {
|
|
|
|
+ logdbg(stderr, "enqueue: can not rewind tail, drop msg\n");
|
|
|
|
+ la->tail = lastmsg;
|
|
|
|
+ return 1; /* can't reuse */
|
|
|
|
+ }
|
|
|
|
la->tail = la->start;
|
|
|
|
|
|
|
|
if (la->empty)
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/log_pthread.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/log_pthread.c
|
|
|
|
@@ -53,17 +53,17 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
void log_thread_start (void)
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
logdbg(stderr,"enter log_thread_start\n");
|
|
|
|
|
|
|
|
logq_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
|
|
|
|
logev_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
|
|
|
|
logev_cond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
|
|
|
|
-
|
|
|
|
+
|
|
|
|
pthread_mutex_init(logq_lock, NULL);
|
|
|
|
pthread_mutex_init(logev_lock, NULL);
|
|
|
|
pthread_cond_init(logev_cond, NULL);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
pthread_attr_setstacksize(&attr, 64 * 1024);
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -90,5 +90,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
pthread_mutex_destroy(logev_lock);
|
|
|
|
pthread_cond_destroy(logev_cond);
|
|
|
|
|
|
|
|
+ free(logq_lock);
|
|
|
|
+ logq_lock = NULL;
|
|
|
|
+ free(logev_lock);
|
|
|
|
+ logev_lock = NULL;
|
|
|
|
+ free(logev_cond);
|
|
|
|
+ logev_cond = NULL;
|
|
|
|
free_logarea();
|
|
|
|
-}
|
|
|
|
+}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/parser.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/parser.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -1,11 +1,11 @@
|
|
|
|
-/*
|
|
|
|
+/*
|
|
|
|
* Part: Configuration file parser/reader. Place into the dynamic
|
|
|
|
* data structure representation the conf file
|
|
|
|
- *
|
|
|
|
+ *
|
|
|
|
* Version: $Id: parser.c,v 1.0.3 2003/05/11 02:28:03 acassen Exp $
|
|
|
|
- *
|
|
|
|
+ *
|
|
|
|
* Author: Alexandre Cassen, <acassen@linux-vs.org>
|
|
|
|
- *
|
|
|
|
+ *
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -43,7 +43,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!keyword)
|
|
|
|
return 1;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!vector_alloc_slot(keywords)) {
|
|
|
|
FREE(keyword);
|
|
|
|
return 1;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -450,7 +450,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
free_strvec(strvec);
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -458,16 +458,23 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
+int alloc_keywords(void)
|
|
|
|
+{
|
|
|
|
+ if (!keywords)
|
|
|
|
+ keywords = vector_alloc();
|
|
|
|
+
|
|
|
|
+ if (!keywords)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* Data initialization */
|
|
|
|
int
|
|
|
|
init_data(char *conf_file, void (*init_keywords) (void))
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
- if (!keywords)
|
|
|
|
- keywords = vector_alloc();
|
|
|
|
- if (!keywords)
|
|
|
|
- return 1;
|
|
|
|
stream = fopen(conf_file, "r");
|
|
|
|
if (!stream) {
|
|
|
|
syslog(LOG_WARNING, "Configuration file open problem");
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/parser.h
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/parser.h
|
|
|
|
@@ -74,6 +74,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
|
|
|
|
extern void *set_value(vector strvec);
|
|
|
|
extern int process_stream(vector keywords);
|
|
|
|
+extern int alloc_keywords(void);
|
|
|
|
extern int init_data(char *conf_file, void (*init_keywords) (void));
|
|
|
|
extern struct keyword * find_keyword(vector v, char * name);
|
|
|
|
void set_current_keywords (vector *k);
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/pgpolicies.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/pgpolicies.c
|
|
|
|
@@ -67,7 +67,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
struct path * pp;
|
|
|
|
struct pathgroup * pgp;
|
|
|
|
struct path * pp2;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mp->pg)
|
|
|
|
mp->pg = vector_alloc();
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -103,12 +103,12 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
bitmap[i] = 1;
|
|
|
|
|
|
|
|
for (j = i + 1; j < VECTOR_SIZE(mp->paths); j++) {
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (bitmap[j])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pp2 = VECTOR_SLOT(mp->paths, j);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!strncmp(pp->tgt_node_name, pp2->tgt_node_name,
|
|
|
|
NODE_NAME_SIZE)) {
|
|
|
|
if (store_path(pgp->paths, pp2))
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -140,7 +140,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
struct path * pp;
|
|
|
|
struct pathgroup * pgp;
|
|
|
|
struct path * pp2;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mp->pg)
|
|
|
|
mp->pg = vector_alloc();
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -172,16 +172,16 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/* feed the first path */
|
|
|
|
if (store_path(pgp->paths, pp))
|
|
|
|
goto out1;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
bitmap[i] = 1;
|
|
|
|
|
|
|
|
for (j = i + 1; j < VECTOR_SIZE(mp->paths); j++) {
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (bitmap[j])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pp2 = VECTOR_SLOT(mp->paths, j);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (0 == strcmp(pp->serial, pp2->serial)) {
|
|
|
|
if (store_path(pgp->paths, pp2))
|
|
|
|
goto out1;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -211,7 +211,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!mp->pg)
|
|
|
|
mp->pg = vector_alloc();
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mp->pg)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -224,7 +224,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (store_pathgroup(mp->pg, pgp))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (store_path(pgp->paths, pp))
|
|
|
|
goto out;
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -252,10 +252,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
pgp = alloc_pathgroup();
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!pgp)
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
vector_free(pgp->paths);
|
|
|
|
pgp->paths = mp->paths;
|
|
|
|
mp->paths = NULL;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -306,7 +306,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!pgp)
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (store_path(pgp->paths, VECTOR_SLOT(mp->paths, 0)))
|
|
|
|
goto out;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/print.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/print.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -29,7 +29,7 @@
|
|
|
|
#define PAD(x) while ((int)(c - s) < (x) && (c < (line + len - 1))) \
|
|
|
|
*c++ = ' '; s = c
|
|
|
|
#define PRINT(var, size, format, args...) \
|
|
|
|
- fwd = snprintf(var, size, format, ##args); \
|
|
|
|
+ fwd = snprintf(var, size, format, ##args); \
|
|
|
|
c += (fwd >= size) ? size : fwd;
|
|
|
|
|
|
|
|
/*
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -60,7 +60,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
char fmt[6] = {};
|
|
|
|
char units[] = {'K','M','G','T','P'};
|
|
|
|
char *u = units;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
while (s >= 1024 && *u != 'P') {
|
|
|
|
s = s / 1024;
|
|
|
|
u++;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -112,7 +112,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
int j = PROGRESS_LEN - i;
|
|
|
|
char * c = buff;
|
|
|
|
char * end = buff + len;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
while (i-- > 0) {
|
|
|
|
c += snprintf(c, len, "X");
|
|
|
|
if ((len = (end - c)) <= 1) goto out;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -129,7 +129,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
buff[c - buff + 1] = '\0';
|
|
|
|
return (c - buff + 1);
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
static int
|
|
|
|
snprint_failback (char * buff, size_t len, struct multipath * mpp)
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -239,7 +239,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (!pp)
|
|
|
|
return 0;
|
|
|
|
return snprintf(buff, len, "%s,%s",
|
|
|
|
- pp->vendor_id, pp->product_id);
|
|
|
|
+ pp->vendor_id, pp->product_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -335,7 +335,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
snprint_vpr (char * buff, size_t len, struct path * pp)
|
|
|
|
{
|
|
|
|
return snprintf(buff, len, "%s,%s",
|
|
|
|
- pp->vendor_id, pp->product_id);
|
|
|
|
+ pp->vendor_id, pp->product_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -530,10 +530,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
f++;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!(data = mpd_lookup(*f)))
|
|
|
|
break; /* unknown wildcard */
|
|
|
|
-
|
|
|
|
+
|
|
|
|
PRINT(c, TAIL, data->header);
|
|
|
|
PAD(data->width);
|
|
|
|
} while (*f++);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -565,10 +565,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
f++;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!(data = mpd_lookup(*f)))
|
|
|
|
break;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
data->snprint(buff, MAX_FIELD_LEN, mpp);
|
|
|
|
PRINT(c, TAIL, buff);
|
|
|
|
PAD(data->width);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -600,10 +600,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
f++;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!(data = pd_lookup(*f)))
|
|
|
|
break; /* unknown wildcard */
|
|
|
|
-
|
|
|
|
+
|
|
|
|
PRINT(c, TAIL, data->header);
|
|
|
|
PAD(data->width);
|
|
|
|
} while (*f++);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -635,10 +635,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
f++;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!(data = pd_lookup(*f)))
|
|
|
|
break;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
data->snprint(buff, MAX_FIELD_LEN, pp);
|
|
|
|
PRINT(c, TAIL, buff);
|
|
|
|
PAD(data->width);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -671,10 +671,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
f++;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!(data = pgd_lookup(*f)))
|
|
|
|
break;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
data->snprint(buff, MAX_FIELD_LEN, pgp);
|
|
|
|
PRINT(c, TAIL, buff);
|
|
|
|
PAD(data->width);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -718,7 +718,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
c += sprintf(c, "%%A: ");
|
|
|
|
|
|
|
|
c += sprintf(c, "%%n");
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (strncmp(mpp->alias, mpp->wwid, WWID_SIZE))
|
|
|
|
c += sprintf(c, " (%%w)");
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -890,7 +890,6 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (fwd > len)
|
|
|
|
return len;
|
|
|
|
return fwd;
|
|
|
|
-
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -956,7 +955,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if ((len - fwd - threshold) <= 0)
|
|
|
|
return len;
|
|
|
|
fwd += snprintf(buff + fwd, len - fwd, "device node rules:\n"
|
|
|
|
- "- blacklist:\n");
|
|
|
|
+ "- blacklist:\n");
|
|
|
|
if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_devnode))
|
|
|
|
return len;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -969,7 +968,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if ((len - fwd - threshold) <= 0)
|
|
|
|
return len;
|
|
|
|
fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n"
|
|
|
|
- "- blacklist:\n");
|
|
|
|
+ "- blacklist:\n");
|
|
|
|
if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0)
|
|
|
|
return len;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -982,7 +981,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if ((len - fwd - threshold) <= 0)
|
|
|
|
return len;
|
|
|
|
fwd += snprintf(buff + fwd, len - fwd, "device rules:\n"
|
|
|
|
- "- blacklist:\n");
|
|
|
|
+ "- blacklist:\n");
|
|
|
|
if (snprint_blacklist_devgroup(buff, len, &fwd, &conf->blist_device) == 0)
|
|
|
|
return len;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1258,7 +1257,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
fprintf(stdout, "===== no paths =====\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (banner)
|
|
|
|
fprintf(stdout, "===== paths list =====\n");
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prio.h
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prio.h
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -21,6 +21,7 @@
|
|
|
|
#define PRIO_HDS "hds"
|
|
|
|
#define PRIO_HP_SW "hp_sw"
|
|
|
|
#define PRIO_NETAPP "netapp"
|
|
|
|
+#define PRIO_ONTAP "ontap"
|
|
|
|
#define PRIO_RANDOM "random"
|
|
|
|
#define PRIO_RDAC "rdac"
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/Makefile
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/Makefile
|
|
|
|
@@ -11,7 +11,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
libprioemc.so \
|
|
|
|
libpriordac.so \
|
|
|
|
libprioalua.so \
|
|
|
|
- libprionetapp.so \
|
|
|
|
+ libprioontap.so \
|
|
|
|
libpriohds.so
|
|
|
|
|
|
|
|
CFLAGS += -I..
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/alua.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/alua.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -23,6 +23,7 @@
|
|
|
|
#define ALUA_PRIO_RTPG_FAILED 2
|
|
|
|
#define ALUA_PRIO_GETAAS_FAILED 3
|
|
|
|
#define ALUA_PRIO_TPGS_FAILED 4
|
|
|
|
+#define ALUA_PRIO_NO_INFORMATION 5
|
|
|
|
|
|
|
|
int
|
|
|
|
get_alua_info(int fd)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -54,13 +55,18 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return -ALUA_PRIO_GETAAS_FAILED;
|
|
|
|
|
|
|
|
condlog(3, "aas = [%s]",
|
|
|
|
- (aas_string[rc]) ? aas_string[rc] : "invalid/reserved");
|
|
|
|
+ (rc < 4) ? aas_string[rc] : "invalid/reserved");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getprio (struct path * pp)
|
|
|
|
{
|
|
|
|
- int rc = get_alua_info(pp->fd);
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ if (pp->fd < 0)
|
|
|
|
+ return -ALUA_PRIO_NO_INFORMATION;
|
|
|
|
+
|
|
|
|
+ rc = get_alua_info(pp->fd);
|
|
|
|
if (rc >= 0) {
|
|
|
|
switch(rc) {
|
|
|
|
case AAS_OPTIMIZED:
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/alua_rtpg.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/alua_rtpg.c
|
|
|
|
@@ -74,7 +74,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
scsi_error(struct sg_io_hdr *hdr)
|
|
|
|
{
|
|
|
|
/* Treat SG_ERR here to get rid of sg_err.[ch] */
|
|
|
|
- hdr->status &= 0x7e;
|
|
|
|
+ hdr->status &= 0x7e;
|
|
|
|
|
|
|
|
if (
|
|
|
|
(hdr->status == 0) &&
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -125,18 +125,18 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
set_uint16(cmd.length, resplen);
|
|
|
|
PRINT_HEX((unsigned char *) &cmd, sizeof(cmd));
|
|
|
|
|
|
|
|
- memset(&hdr, 0, sizeof(hdr));
|
|
|
|
- hdr.interface_id = 'S';
|
|
|
|
- hdr.cmdp = (unsigned char *) &cmd;
|
|
|
|
- hdr.cmd_len = sizeof(cmd);
|
|
|
|
- hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
- hdr.dxferp = resp;
|
|
|
|
- hdr.dxfer_len = resplen;
|
|
|
|
- hdr.sbp = sense;
|
|
|
|
- hdr.mx_sb_len = sizeof(sense);
|
|
|
|
- hdr.timeout = DEF_TIMEOUT;
|
|
|
|
-
|
|
|
|
- if (ioctl(fd, SG_IO, &hdr) < 0) {
|
|
|
|
+ memset(&hdr, 0, sizeof(hdr));
|
|
|
|
+ hdr.interface_id = 'S';
|
|
|
|
+ hdr.cmdp = (unsigned char *) &cmd;
|
|
|
|
+ hdr.cmd_len = sizeof(cmd);
|
|
|
|
+ hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
+ hdr.dxferp = resp;
|
|
|
|
+ hdr.dxfer_len = resplen;
|
|
|
|
+ hdr.sbp = sense;
|
|
|
|
+ hdr.mx_sb_len = sizeof(sense);
|
|
|
|
+ hdr.timeout = DEF_TIMEOUT;
|
|
|
|
+
|
|
|
|
+ if (ioctl(fd, SG_IO, &hdr) < 0) {
|
|
|
|
PRINT_DEBUG("do_inquiry: IOCTL failed!\n");
|
|
|
|
return -RTPG_INQUIRY_FAILED;
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -146,8 +146,8 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return -RTPG_INQUIRY_FAILED;
|
|
|
|
}
|
|
|
|
PRINT_HEX((unsigned char *) resp, resplen);
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -160,6 +160,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
struct inquiry_data inq;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
+ memset((unsigned char *)&inq, 0, sizeof(inq));
|
|
|
|
rc = do_inquiry(fd, 0, 0x00, &inq, sizeof(inq));
|
|
|
|
if (!rc) {
|
|
|
|
rc = inquiry_data_get_tpgs(&inq);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -176,6 +177,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
struct vpd83_dscr * dscr;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
+ memset(buf, 0, sizeof(buf));
|
|
|
|
rc = do_inquiry(fd, 1, 0x83, buf, sizeof(buf));
|
|
|
|
if (!rc) {
|
|
|
|
vpd83 = (struct vpd83_data *) buf;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -221,19 +223,19 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
set_uint32(cmd.length, resplen);
|
|
|
|
PRINT_HEX((unsigned char *) &cmd, sizeof(cmd));
|
|
|
|
|
|
|
|
- memset(&hdr, 0, sizeof(hdr));
|
|
|
|
+ memset(&hdr, 0, sizeof(hdr));
|
|
|
|
hdr.interface_id = 'S';
|
|
|
|
- hdr.cmdp = (unsigned char *) &cmd;
|
|
|
|
- hdr.cmd_len = sizeof(cmd);
|
|
|
|
- hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
- hdr.dxferp = resp;
|
|
|
|
- hdr.dxfer_len = resplen;
|
|
|
|
- hdr.mx_sb_len = sizeof(sense);
|
|
|
|
- hdr.sbp = sense;
|
|
|
|
- hdr.timeout = DEF_TIMEOUT;
|
|
|
|
-
|
|
|
|
+ hdr.cmdp = (unsigned char *) &cmd;
|
|
|
|
+ hdr.cmd_len = sizeof(cmd);
|
|
|
|
+ hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
+ hdr.dxferp = resp;
|
|
|
|
+ hdr.dxfer_len = resplen;
|
|
|
|
+ hdr.mx_sb_len = sizeof(sense);
|
|
|
|
+ hdr.sbp = sense;
|
|
|
|
+ hdr.timeout = DEF_TIMEOUT;
|
|
|
|
+
|
|
|
|
if (ioctl(fd, SG_IO, &hdr) < 0)
|
|
|
|
- return -RTPG_RTPG_FAILED;
|
|
|
|
+ return -RTPG_RTPG_FAILED;
|
|
|
|
|
|
|
|
if (scsi_error(&hdr)) {
|
|
|
|
PRINT_DEBUG("do_rtpg: SCSI error!\n");
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -241,8 +243,8 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
PRINT_HEX(resp, resplen);
|
|
|
|
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
|
|
|
|
int
|
|
|
|
get_asymmetric_access_state(int fd, unsigned int tpg)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -261,6 +263,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
"%u bytes\n", buflen);
|
|
|
|
return -RTPG_RTPG_FAILED;
|
|
|
|
}
|
|
|
|
+ memset(buf, 0, buflen);
|
|
|
|
rc = do_rtpg(fd, buf, buflen);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -274,11 +277,11 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return -RTPG_RTPG_FAILED;
|
|
|
|
}
|
|
|
|
buflen = scsi_buflen;
|
|
|
|
+ memset(buf, 0, buflen);
|
|
|
|
rc = do_rtpg(fd, buf, buflen);
|
|
|
|
if (rc < 0)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
|
|
|
|
tpgd = (struct rtpg_data *) buf;
|
|
|
|
rc = -RTPG_TPG_NOT_FOUND;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -289,7 +292,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
"more than one entry with same port "
|
|
|
|
"group.\n");
|
|
|
|
} else {
|
|
|
|
- PRINT_DEBUG("pref=%i\n", dscr->pref);
|
|
|
|
+ PRINT_DEBUG("pref=%i\n", dscr->b0);
|
|
|
|
rc = rtpg_tpg_dscr_get_aas(dscr);
|
|
|
|
}
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/hds.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/hds.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -86,7 +86,7 @@
|
|
|
|
int hds_modular_prio (const char *dev, int fd)
|
|
|
|
{
|
|
|
|
int k;
|
|
|
|
- char vendor[8];
|
|
|
|
+ char vendor[9];
|
|
|
|
char product[32];
|
|
|
|
char serial[32];
|
|
|
|
char ldev[32];
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/netapp.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/netapp.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -1,243 +0,0 @@
|
|
|
|
-/*
|
|
|
|
- * Copyright 2005 Network Appliance, Inc., All Rights Reserved
|
|
|
|
- * Author: David Wysochanski available at davidw@netapp.com
|
|
|
|
- *
|
|
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
|
|
- * it under the terms of the GNU General Public License version 2 as
|
|
|
|
- * published by the Free Software Foundation.
|
|
|
|
- *
|
|
|
|
- * This program is distributed in the hope that it will be useful, but
|
|
|
|
- * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
- * General Public License v2 for more details.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-#include <stdio.h>
|
|
|
|
-#include <stdlib.h>
|
|
|
|
-#include <string.h>
|
|
|
|
-#include <sys/ioctl.h>
|
|
|
|
-#include <errno.h>
|
|
|
|
-#include <assert.h>
|
|
|
|
-
|
|
|
|
-#include <sg_include.h>
|
|
|
|
-#include <debug.h>
|
|
|
|
-#include <prio.h>
|
|
|
|
-
|
|
|
|
-#define INQUIRY_CMD 0x12
|
|
|
|
-#define INQUIRY_CMDLEN 6
|
|
|
|
-#define DEFAULT_PRIOVAL 10
|
|
|
|
-#define RESULTS_MAX 256
|
|
|
|
-#define SG_TIMEOUT 30000
|
|
|
|
-
|
|
|
|
-#define pp_netapp_log(prio, fmt, args...) \
|
|
|
|
- condlog(prio, "%s: netapp prio: " fmt, dev, ##args)
|
|
|
|
-
|
|
|
|
-static void dump_cdb(unsigned char *cdb, int size)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
- char buf[10*5+1];
|
|
|
|
- char * p = &buf[0];
|
|
|
|
-
|
|
|
|
- condlog(0, "- SCSI CDB: ");
|
|
|
|
- for (i=0; i<size; i++) {
|
|
|
|
- p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
|
|
|
|
- }
|
|
|
|
- condlog(0, "%s", buf);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void process_sg_error(struct sg_io_hdr *io_hdr)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
- char buf[128*5+1];
|
|
|
|
- char * p = &buf[0];
|
|
|
|
-
|
|
|
|
- condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
|
|
|
|
- "driver_status=0x%02x", io_hdr->masked_status,
|
|
|
|
- io_hdr->host_status, io_hdr->driver_status);
|
|
|
|
- if (io_hdr->sb_len_wr > 0) {
|
|
|
|
- condlog(0, "- SCSI sense data: ");
|
|
|
|
- for (i=0; i<io_hdr->sb_len_wr; i++) {
|
|
|
|
- p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ",
|
|
|
|
- io_hdr->sbp[i]);
|
|
|
|
- }
|
|
|
|
- condlog(0, "%s", buf);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Returns:
|
|
|
|
- * -1: error, errno set
|
|
|
|
- * 0: success
|
|
|
|
- */
|
|
|
|
-static int send_gva(const char *dev, int fd, unsigned char pg,
|
|
|
|
- unsigned char *results, int *results_size)
|
|
|
|
-{
|
|
|
|
- unsigned char sb[128];
|
|
|
|
- unsigned char cdb[10] = {0xc0, 0, 0x1, 0xa, 0x98, 0xa,
|
|
|
|
- pg, sizeof(sb), 0, 0};
|
|
|
|
- struct sg_io_hdr io_hdr;
|
|
|
|
- int ret = -1;
|
|
|
|
-
|
|
|
|
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
|
|
- io_hdr.interface_id = 'S';
|
|
|
|
- io_hdr.cmd_len = sizeof (cdb);
|
|
|
|
- io_hdr.mx_sb_len = sizeof (sb);
|
|
|
|
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
- io_hdr.dxfer_len = *results_size;
|
|
|
|
- io_hdr.dxferp = results;
|
|
|
|
- io_hdr.cmdp = cdb;
|
|
|
|
- io_hdr.sbp = sb;
|
|
|
|
- io_hdr.timeout = SG_TIMEOUT;
|
|
|
|
- io_hdr.pack_id = 0;
|
|
|
|
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
|
|
|
|
- pp_netapp_log(0, "SG_IO ioctl failed, errno=%d", errno);
|
|
|
|
- dump_cdb(cdb, sizeof(cdb));
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
- if (io_hdr.info & SG_INFO_OK_MASK) {
|
|
|
|
- pp_netapp_log(0, "SCSI error");
|
|
|
|
- dump_cdb(cdb, sizeof(cdb));
|
|
|
|
- process_sg_error(&io_hdr);
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (results[4] != 0x0a || results[5] != 0x98 ||
|
|
|
|
- results[6] != 0x0a ||results[7] != 0x01) {
|
|
|
|
- dump_cdb(cdb, sizeof(cdb));
|
|
|
|
- pp_netapp_log(0, "GVA return wrong format ");
|
|
|
|
- pp_netapp_log(0, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x",
|
|
|
|
- results[4], results[5], results[6], results[7]);
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
- ret = 0;
|
|
|
|
- out:
|
|
|
|
- return(ret);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Retuns:
|
|
|
|
- * -1: Unable to obtain proxy info
|
|
|
|
- * 0: Device _not_ proxy path
|
|
|
|
- * 1: Device _is_ proxy path
|
|
|
|
- */
|
|
|
|
-static int get_proxy(const char *dev, int fd)
|
|
|
|
-{
|
|
|
|
- unsigned char results[256];
|
|
|
|
- unsigned char sb[128];
|
|
|
|
- unsigned char cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xc1, 0,
|
|
|
|
- sizeof(sb), 0};
|
|
|
|
- struct sg_io_hdr io_hdr;
|
|
|
|
- int ret = -1;
|
|
|
|
-
|
|
|
|
- memset(&results, 0, sizeof (results));
|
|
|
|
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
|
|
- io_hdr.interface_id = 'S';
|
|
|
|
- io_hdr.cmd_len = sizeof (cdb);
|
|
|
|
- io_hdr.mx_sb_len = sizeof (sb);
|
|
|
|
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
- io_hdr.dxfer_len = sizeof (results);
|
|
|
|
- io_hdr.dxferp = results;
|
|
|
|
- io_hdr.cmdp = cdb;
|
|
|
|
- io_hdr.sbp = sb;
|
|
|
|
- io_hdr.timeout = SG_TIMEOUT;
|
|
|
|
- io_hdr.pack_id = 0;
|
|
|
|
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
|
|
|
|
- pp_netapp_log(0, "ioctl sending inquiry command failed, "
|
|
|
|
- "errno=%d", errno);
|
|
|
|
- dump_cdb(cdb, sizeof(cdb));
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
- if (io_hdr.info & SG_INFO_OK_MASK) {
|
|
|
|
- pp_netapp_log(0, "SCSI error");
|
|
|
|
- dump_cdb(cdb, sizeof(cdb));
|
|
|
|
- process_sg_error(&io_hdr);
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (results[1] != 0xc1 || results[8] != 0x0a ||
|
|
|
|
- results[9] != 0x98 || results[10] != 0x0a ||
|
|
|
|
- results[11] != 0x0 || results[12] != 0xc1 ||
|
|
|
|
- results[13] != 0x0) {
|
|
|
|
- pp_netapp_log(0,"proxy info page in unknown format - ");
|
|
|
|
- pp_netapp_log(0,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x "
|
|
|
|
- "0x%02x 0x%02x",
|
|
|
|
- results[8], results[9], results[10],
|
|
|
|
- results[11], results[12], results[13]);
|
|
|
|
- dump_cdb(cdb, sizeof(cdb));
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
- ret = (results[19] & 0x02) >> 1;
|
|
|
|
-
|
|
|
|
- out:
|
|
|
|
- return(ret);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Returns priority of device based on device info.
|
|
|
|
- *
|
|
|
|
- * 4: FCP non-proxy, FCP proxy unknown, or unable to determine protocol
|
|
|
|
- * 3: iSCSI HBA
|
|
|
|
- * 2: iSCSI software
|
|
|
|
- * 1: FCP proxy
|
|
|
|
- */
|
|
|
|
-static int netapp_prio(const char *dev, int fd)
|
|
|
|
-{
|
|
|
|
- unsigned char results[RESULTS_MAX];
|
|
|
|
- int results_size=RESULTS_MAX;
|
|
|
|
- int rc;
|
|
|
|
- int is_proxy;
|
|
|
|
- int is_iscsi_software;
|
|
|
|
- int is_iscsi_hardware;
|
|
|
|
- int tot_len;
|
|
|
|
-
|
|
|
|
- is_iscsi_software = is_iscsi_hardware = is_proxy = 0;
|
|
|
|
-
|
|
|
|
- memset(&results, 0, sizeof (results));
|
|
|
|
- rc = send_gva(dev, fd, 0x41, results, &results_size);
|
|
|
|
- if (rc == 0) {
|
|
|
|
- tot_len = results[0] << 24 | results[1] << 16 |
|
|
|
|
- results[2] << 8 | results[3];
|
|
|
|
- if (tot_len <= 8) {
|
|
|
|
- goto try_fcp_proxy;
|
|
|
|
- }
|
|
|
|
- if (results[8] != 0x41) {
|
|
|
|
- pp_netapp_log(0, "GVA page 0x41 error - "
|
|
|
|
- "results[8] = 0x%x", results[8]);
|
|
|
|
- goto try_fcp_proxy;
|
|
|
|
- }
|
|
|
|
- if ((strncmp((char *)&results[12], "ism_sw", 6) == 0) ||
|
|
|
|
- (strncmp((char *)&results[12], "iswt", 4) == 0)) {
|
|
|
|
- is_iscsi_software = 1;
|
|
|
|
- goto prio_select;
|
|
|
|
- }
|
|
|
|
- else if (strncmp((char *)&results[12], "ism_sn", 6) == 0) {
|
|
|
|
- is_iscsi_hardware = 1;
|
|
|
|
- goto prio_select;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- try_fcp_proxy:
|
|
|
|
- rc = get_proxy(dev, fd);
|
|
|
|
- if (rc >= 0) {
|
|
|
|
- is_proxy = rc;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- prio_select:
|
|
|
|
- if (is_iscsi_hardware) {
|
|
|
|
- return 3;
|
|
|
|
- } else if (is_iscsi_software) {
|
|
|
|
- return 2;
|
|
|
|
- } else {
|
|
|
|
- if (is_proxy) {
|
|
|
|
- return 1;
|
|
|
|
- } else {
|
|
|
|
- /* Either non-proxy, or couldn't get proxy info */
|
|
|
|
- return 4;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-int getprio (struct path * pp)
|
|
|
|
-{
|
|
|
|
- return netapp_prio(pp->dev, pp->fd);
|
|
|
|
-}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/netapp.h
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/netapp.h
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -1,7 +0,0 @@
|
|
|
|
-#ifndef _NETAPP_H
|
|
|
|
-#define _NETAPP_H
|
|
|
|
-
|
|
|
|
-#define PRIO_NETAPP "netapp"
|
|
|
|
-int prio_netapp(struct path * pp);
|
|
|
|
-
|
|
|
|
-#endif
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/ontap.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/ontap.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,243 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2005 Network Appliance, Inc., All Rights Reserved
|
|
|
|
+ * Author: David Wysochanski available at davidw@netapp.com
|
|
|
|
+ *
|
|
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
|
|
+ * published by the Free Software Foundation.
|
|
|
|
+ *
|
|
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * General Public License v2 for more details.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+#include <sys/ioctl.h>
|
|
|
|
+#include <errno.h>
|
|
|
|
+#include <assert.h>
|
|
|
|
+
|
|
|
|
+#include <sg_include.h>
|
|
|
|
+#include <debug.h>
|
|
|
|
+#include <prio.h>
|
|
|
|
+
|
|
|
|
+#define INQUIRY_CMD 0x12
|
|
|
|
+#define INQUIRY_CMDLEN 6
|
|
|
|
+#define DEFAULT_PRIOVAL 10
|
|
|
|
+#define RESULTS_MAX 256
|
|
|
|
+#define SG_TIMEOUT 30000
|
|
|
|
+
|
|
|
|
+#define pp_ontap_log(prio, fmt, args...) \
|
|
|
|
+ condlog(prio, "%s: ontap prio: " fmt, dev, ##args)
|
|
|
|
+
|
|
|
|
+static void dump_cdb(unsigned char *cdb, int size)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ char buf[10*5+1];
|
|
|
|
+ char * p = &buf[0];
|
|
|
|
+
|
|
|
|
+ condlog(0, "- SCSI CDB: ");
|
|
|
|
+ for (i=0; i<size; i++) {
|
|
|
|
+ p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
|
|
|
|
+ }
|
|
|
|
+ condlog(0, "%s", buf);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void process_sg_error(struct sg_io_hdr *io_hdr)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ char buf[128*5+1];
|
|
|
|
+ char * p = &buf[0];
|
|
|
|
+
|
|
|
|
+ condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
|
|
|
|
+ "driver_status=0x%02x", io_hdr->masked_status,
|
|
|
|
+ io_hdr->host_status, io_hdr->driver_status);
|
|
|
|
+ if (io_hdr->sb_len_wr > 0) {
|
|
|
|
+ condlog(0, "- SCSI sense data: ");
|
|
|
|
+ for (i=0; i<io_hdr->sb_len_wr; i++) {
|
|
|
|
+ p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ",
|
|
|
|
+ io_hdr->sbp[i]);
|
|
|
|
+ }
|
|
|
|
+ condlog(0, "%s", buf);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Returns:
|
|
|
|
+ * -1: error, errno set
|
|
|
|
+ * 0: success
|
|
|
|
+ */
|
|
|
|
+static int send_gva(const char *dev, int fd, unsigned char pg,
|
|
|
|
+ unsigned char *results, int *results_size)
|
|
|
|
+{
|
|
|
|
+ unsigned char sb[128];
|
|
|
|
+ unsigned char cdb[10] = {0xc0, 0, 0x1, 0xa, 0x98, 0xa,
|
|
|
|
+ pg, sizeof(sb), 0, 0};
|
|
|
|
+ struct sg_io_hdr io_hdr;
|
|
|
|
+ int ret = -1;
|
|
|
|
+
|
|
|
|
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
|
|
+ io_hdr.interface_id = 'S';
|
|
|
|
+ io_hdr.cmd_len = sizeof (cdb);
|
|
|
|
+ io_hdr.mx_sb_len = sizeof (sb);
|
|
|
|
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
+ io_hdr.dxfer_len = *results_size;
|
|
|
|
+ io_hdr.dxferp = results;
|
|
|
|
+ io_hdr.cmdp = cdb;
|
|
|
|
+ io_hdr.sbp = sb;
|
|
|
|
+ io_hdr.timeout = SG_TIMEOUT;
|
|
|
|
+ io_hdr.pack_id = 0;
|
|
|
|
+ if (ioctl(fd, SG_IO, &io_hdr) < 0) {
|
|
|
|
+ pp_ontap_log(0, "SG_IO ioctl failed, errno=%d", errno);
|
|
|
|
+ dump_cdb(cdb, sizeof(cdb));
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ if (io_hdr.info & SG_INFO_OK_MASK) {
|
|
|
|
+ pp_ontap_log(0, "SCSI error");
|
|
|
|
+ dump_cdb(cdb, sizeof(cdb));
|
|
|
|
+ process_sg_error(&io_hdr);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (results[4] != 0x0a || results[5] != 0x98 ||
|
|
|
|
+ results[6] != 0x0a ||results[7] != 0x01) {
|
|
|
|
+ dump_cdb(cdb, sizeof(cdb));
|
|
|
|
+ pp_ontap_log(0, "GVA return wrong format ");
|
|
|
|
+ pp_ontap_log(0, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x",
|
|
|
|
+ results[4], results[5], results[6], results[7]);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ ret = 0;
|
|
|
|
+ out:
|
|
|
|
+ return(ret);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Retuns:
|
|
|
|
+ * -1: Unable to obtain proxy info
|
|
|
|
+ * 0: Device _not_ proxy path
|
|
|
|
+ * 1: Device _is_ proxy path
|
|
|
|
+ */
|
|
|
|
+static int get_proxy(const char *dev, int fd)
|
|
|
|
+{
|
|
|
|
+ unsigned char results[256];
|
|
|
|
+ unsigned char sb[128];
|
|
|
|
+ unsigned char cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xc1, 0,
|
|
|
|
+ sizeof(sb), 0};
|
|
|
|
+ struct sg_io_hdr io_hdr;
|
|
|
|
+ int ret = -1;
|
|
|
|
+
|
|
|
|
+ memset(&results, 0, sizeof (results));
|
|
|
|
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
|
|
+ io_hdr.interface_id = 'S';
|
|
|
|
+ io_hdr.cmd_len = sizeof (cdb);
|
|
|
|
+ io_hdr.mx_sb_len = sizeof (sb);
|
|
|
|
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
+ io_hdr.dxfer_len = sizeof (results);
|
|
|
|
+ io_hdr.dxferp = results;
|
|
|
|
+ io_hdr.cmdp = cdb;
|
|
|
|
+ io_hdr.sbp = sb;
|
|
|
|
+ io_hdr.timeout = SG_TIMEOUT;
|
|
|
|
+ io_hdr.pack_id = 0;
|
|
|
|
+ if (ioctl(fd, SG_IO, &io_hdr) < 0) {
|
|
|
|
+ pp_ontap_log(0, "ioctl sending inquiry command failed, "
|
|
|
|
+ "errno=%d", errno);
|
|
|
|
+ dump_cdb(cdb, sizeof(cdb));
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ if (io_hdr.info & SG_INFO_OK_MASK) {
|
|
|
|
+ pp_ontap_log(0, "SCSI error");
|
|
|
|
+ dump_cdb(cdb, sizeof(cdb));
|
|
|
|
+ process_sg_error(&io_hdr);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (results[1] != 0xc1 || results[8] != 0x0a ||
|
|
|
|
+ results[9] != 0x98 || results[10] != 0x0a ||
|
|
|
|
+ results[11] != 0x0 || results[12] != 0xc1 ||
|
|
|
|
+ results[13] != 0x0) {
|
|
|
|
+ pp_ontap_log(0,"proxy info page in unknown format - ");
|
|
|
|
+ pp_ontap_log(0,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x "
|
|
|
|
+ "0x%02x 0x%02x",
|
|
|
|
+ results[8], results[9], results[10],
|
|
|
|
+ results[11], results[12], results[13]);
|
|
|
|
+ dump_cdb(cdb, sizeof(cdb));
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ ret = (results[19] & 0x02) >> 1;
|
|
|
|
+
|
|
|
|
+ out:
|
|
|
|
+ return(ret);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Returns priority of device based on device info.
|
|
|
|
+ *
|
|
|
|
+ * 4: FCP non-proxy, FCP proxy unknown, or unable to determine protocol
|
|
|
|
+ * 3: iSCSI HBA
|
|
|
|
+ * 2: iSCSI software
|
|
|
|
+ * 1: FCP proxy
|
|
|
|
+ */
|
|
|
|
+static int ontap_prio(const char *dev, int fd)
|
|
|
|
+{
|
|
|
|
+ unsigned char results[RESULTS_MAX];
|
|
|
|
+ int results_size=RESULTS_MAX;
|
|
|
|
+ int rc;
|
|
|
|
+ int is_proxy;
|
|
|
|
+ int is_iscsi_software;
|
|
|
|
+ int is_iscsi_hardware;
|
|
|
|
+ int tot_len;
|
|
|
|
+
|
|
|
|
+ is_iscsi_software = is_iscsi_hardware = is_proxy = 0;
|
|
|
|
+
|
|
|
|
+ memset(&results, 0, sizeof (results));
|
|
|
|
+ rc = send_gva(dev, fd, 0x41, results, &results_size);
|
|
|
|
+ if (rc == 0) {
|
|
|
|
+ tot_len = results[0] << 24 | results[1] << 16 |
|
|
|
|
+ results[2] << 8 | results[3];
|
|
|
|
+ if (tot_len <= 8) {
|
|
|
|
+ goto try_fcp_proxy;
|
|
|
|
+ }
|
|
|
|
+ if (results[8] != 0x41) {
|
|
|
|
+ pp_ontap_log(0, "GVA page 0x41 error - "
|
|
|
|
+ "results[8] = 0x%x", results[8]);
|
|
|
|
+ goto try_fcp_proxy;
|
|
|
|
+ }
|
|
|
|
+ if ((strncmp((char *)&results[12], "ism_sw", 6) == 0) ||
|
|
|
|
+ (strncmp((char *)&results[12], "iswt", 4) == 0)) {
|
|
|
|
+ is_iscsi_software = 1;
|
|
|
|
+ goto prio_select;
|
|
|
|
+ }
|
|
|
|
+ else if (strncmp((char *)&results[12], "ism_sn", 6) == 0) {
|
|
|
|
+ is_iscsi_hardware = 1;
|
|
|
|
+ goto prio_select;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try_fcp_proxy:
|
|
|
|
+ rc = get_proxy(dev, fd);
|
|
|
|
+ if (rc >= 0) {
|
|
|
|
+ is_proxy = rc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ prio_select:
|
|
|
|
+ if (is_iscsi_hardware) {
|
|
|
|
+ return 3;
|
|
|
|
+ } else if (is_iscsi_software) {
|
|
|
|
+ return 2;
|
|
|
|
+ } else {
|
|
|
|
+ if (is_proxy) {
|
|
|
|
+ return 1;
|
|
|
|
+ } else {
|
|
|
|
+ /* Either non-proxy, or couldn't get proxy info */
|
|
|
|
+ return 4;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int getprio (struct path * pp)
|
|
|
|
+{
|
|
|
|
+ return ontap_prio(pp->dev, pp->fd);
|
|
|
|
+}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/ontap.h
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/ontap.h
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,7 @@
|
|
|
|
+#ifndef _ONTAP_H
|
|
|
|
+#define _ONTAP_H
|
|
|
|
+
|
|
|
|
+#define PRIO_ONTAP "ontap"
|
|
|
|
+int prio_ontap(struct path * pp);
|
|
|
|
+
|
|
|
|
+#endif
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/prioritizers/rdac.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/prioritizers/rdac.c
|
|
|
|
@@ -39,9 +39,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
pp_rdac_log(0, "inquiry command indicates error");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (/* Verify the code page - right page & page identifier */
|
|
|
|
- sense_buffer[1] != 0xc9 ||
|
|
|
|
+ sense_buffer[1] != 0xc9 ||
|
|
|
|
sense_buffer[3] != 0x2c ||
|
|
|
|
sense_buffer[4] != 'v' ||
|
|
|
|
sense_buffer[5] != 'a' ||
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -49,24 +49,24 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
pp_rdac_log(0, "volume access control page in unknown format");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if ( /* Current Volume Path Bit */
|
|
|
|
( sense_buffer[8] & 0x01) == 0x01 ) {
|
|
|
|
- /*
|
|
|
|
+ /*
|
|
|
|
* This volume was owned by the controller receiving
|
|
|
|
* the inquiry command.
|
|
|
|
*/
|
|
|
|
- ret |= 0x01;
|
|
|
|
+ ret |= 0x02;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Volume Preferred Path Priority */
|
|
|
|
switch ( sense_buffer[9] & 0x0F ) {
|
|
|
|
case 0x01:
|
|
|
|
- /*
|
|
|
|
+ /*
|
|
|
|
* Access to this volume is most preferred through
|
|
|
|
* this path and other paths with this value.
|
|
|
|
*/
|
|
|
|
- ret |= 0x02;
|
|
|
|
+ ret |= 0x04;
|
|
|
|
break;
|
|
|
|
case 0x02:
|
|
|
|
/*
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -74,12 +74,13 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
* as a secondary path. Typically this path would be used
|
|
|
|
* for fail-over situations.
|
|
|
|
*/
|
|
|
|
- /* Fallthrough */
|
|
|
|
+ ret |= 0x01;
|
|
|
|
+ break;
|
|
|
|
default:
|
|
|
|
/* Reserved values */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
out:
|
|
|
|
return(ret);
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/regex.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/regex.c
|
|
|
|
@@ -116,7 +116,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/* True if `size1' is non-NULL and PTR is pointing anywhere inside
|
|
|
|
`string1' or just past its end. This works if PTR is NULL, which is
|
|
|
|
a good thing. */
|
|
|
|
-#define FIRST_STRING_P(ptr) \
|
|
|
|
+#define FIRST_STRING_P(ptr) \
|
|
|
|
(size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
|
|
|
|
|
|
|
|
/* (Re)Allocate N items of type T using malloc, or fail. */
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -188,7 +188,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
#define EXTRACT_NUMBER_AND_INCR(destination, source) \
|
|
|
|
do { \
|
|
|
|
EXTRACT_NUMBER (destination, source); \
|
|
|
|
- (source) += 2; \
|
|
|
|
+ (source) += 2; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#undef assert
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -267,14 +267,14 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
#define PATFETCH(c) \
|
|
|
|
do {if (p == pend) return REG_EEND; \
|
|
|
|
c = (unsigned char) *p++; \
|
|
|
|
- if (translate) c = translate[c]; \
|
|
|
|
+ if (translate) c = translate[c]; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/* Fetch the next character in the uncompiled pattern, with no
|
|
|
|
translation. */
|
|
|
|
#define PATFETCH_RAW(c) \
|
|
|
|
do {if (p == pend) return REG_EEND; \
|
|
|
|
- c = (unsigned char) *p++; \
|
|
|
|
+ c = (unsigned char) *p++; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/* Go backwards one character in the pattern. */
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -354,27 +354,27 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
correct places in the new one. If extending the buffer results in it
|
|
|
|
being larger than MAX_BUF_SIZE, then flag memory exhausted. */
|
|
|
|
#define EXTEND_BUFFER() \
|
|
|
|
- do { \
|
|
|
|
+ do { \
|
|
|
|
unsigned char *old_buffer = bufp->buffer; \
|
|
|
|
- if (bufp->allocated == MAX_BUF_SIZE) \
|
|
|
|
+ if (bufp->allocated == MAX_BUF_SIZE) \
|
|
|
|
return REG_ESIZE; \
|
|
|
|
bufp->allocated <<= 1; \
|
|
|
|
if (bufp->allocated > MAX_BUF_SIZE) \
|
|
|
|
- bufp->allocated = MAX_BUF_SIZE; \
|
|
|
|
+ bufp->allocated = MAX_BUF_SIZE; \
|
|
|
|
bufp->buffer = (unsigned char *) REALLOC(bufp->buffer, bufp->allocated);\
|
|
|
|
if (bufp->buffer == NULL) \
|
|
|
|
return REG_ESPACE; \
|
|
|
|
/* If the buffer moved, move all the pointers into it. */ \
|
|
|
|
if (old_buffer != bufp->buffer) \
|
|
|
|
{ \
|
|
|
|
- b = (b - old_buffer) + bufp->buffer; \
|
|
|
|
- begalt = (begalt - old_buffer) + bufp->buffer; \
|
|
|
|
- if (fixup_alt_jump) \
|
|
|
|
- fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
|
|
|
|
- if (laststart) \
|
|
|
|
- laststart = (laststart - old_buffer) + bufp->buffer; \
|
|
|
|
- if (pending_exact) \
|
|
|
|
- pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
|
|
|
|
+ b = (b - old_buffer) + bufp->buffer; \
|
|
|
|
+ begalt = (begalt - old_buffer) + bufp->buffer; \
|
|
|
|
+ if (fixup_alt_jump) \
|
|
|
|
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
|
|
|
|
+ if (laststart) \
|
|
|
|
+ laststart = (laststart - old_buffer) + bufp->buffer; \
|
|
|
|
+ if (pending_exact) \
|
|
|
|
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -428,20 +428,20 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Get the next unsigned number in the uncompiled pattern. */
|
|
|
|
-#define GET_UNSIGNED_NUMBER(num) \
|
|
|
|
+#define GET_UNSIGNED_NUMBER(num) \
|
|
|
|
{ if (p != pend) \
|
|
|
|
{ \
|
|
|
|
- PATFETCH (c); \
|
|
|
|
- while (ISDIGIT (c)) \
|
|
|
|
- { \
|
|
|
|
- if (num < 0) \
|
|
|
|
- num = 0; \
|
|
|
|
- num = num * 10 + c - '0'; \
|
|
|
|
- if (p == pend) \
|
|
|
|
- break; \
|
|
|
|
- PATFETCH (c); \
|
|
|
|
- } \
|
|
|
|
- } \
|
|
|
|
+ PATFETCH (c); \
|
|
|
|
+ while (ISDIGIT (c)) \
|
|
|
|
+ { \
|
|
|
|
+ if (num < 0) \
|
|
|
|
+ num = 0; \
|
|
|
|
+ num = num * 10 + c - '0'; \
|
|
|
|
+ if (p == pend) \
|
|
|
|
+ break; \
|
|
|
|
+ PATFETCH (c); \
|
|
|
|
+ } \
|
|
|
|
+ } \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1524,14 +1524,14 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
|
|
|
|
? 0 \
|
|
|
|
: ((fail_stack).stack = (fail_stack_elt_t *) \
|
|
|
|
- REGEX_REALLOCATE ((fail_stack).stack, \
|
|
|
|
- (fail_stack).size * sizeof (fail_stack_elt_t), \
|
|
|
|
- ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
|
|
|
|
+ REGEX_REALLOCATE ((fail_stack).stack, \
|
|
|
|
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
|
|
|
|
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
|
|
|
|
\
|
|
|
|
(fail_stack).stack == NULL \
|
|
|
|
? 0 \
|
|
|
|
- : ((fail_stack).size <<= 1, \
|
|
|
|
- 1)))
|
|
|
|
+ : ((fail_stack).size <<= 1, \
|
|
|
|
+ 1)))
|
|
|
|
|
|
|
|
|
|
|
|
/* Push PATTERN_OP on FAIL_STACK.
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1577,7 +1577,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
is wide enough to hold a value of something to which pointer can \
|
|
|
|
be assigned */ \
|
|
|
|
s_reg_t this_reg; \
|
|
|
|
- \
|
|
|
|
+ \
|
|
|
|
DEBUG_STATEMENT (failure_id++); \
|
|
|
|
DEBUG_STATEMENT (nfailure_points_pushed++); \
|
|
|
|
DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1663,7 +1663,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
/* We actually push this many items. */
|
|
|
|
#define NUM_FAILURE_ITEMS \
|
|
|
|
- ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
|
|
|
|
+ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
|
|
|
|
+ NUM_NONREG_ITEMS)
|
|
|
|
|
|
|
|
/* How many items can still be added to the stack without overflowing it. */
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -2255,13 +2255,13 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/* Call before fetching a character with *d. This switches over to
|
|
|
|
string2 if necessary. */
|
|
|
|
#define PREFETCH() \
|
|
|
|
- while (d == dend) \
|
|
|
|
+ while (d == dend) \
|
|
|
|
{ \
|
|
|
|
/* End of string2 => fail. */ \
|
|
|
|
- if (dend == end_match_2) \
|
|
|
|
- goto fail; \
|
|
|
|
- /* End of string1 => advance to string2. */ \
|
|
|
|
- d = string2; \
|
|
|
|
+ if (dend == end_match_2) \
|
|
|
|
+ goto fail; \
|
|
|
|
+ /* End of string1 => advance to string2. */ \
|
|
|
|
+ d = string2; \
|
|
|
|
dend = end_match_2; \
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -2278,7 +2278,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
string2, look at the last character in string1. */
|
|
|
|
#define WORDCHAR_P(d) \
|
|
|
|
(SYNTAX ((d) == end1 ? *string2 \
|
|
|
|
- : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
|
|
|
|
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
|
|
|
|
== Sword)
|
|
|
|
|
|
|
|
/* Test if the character before D and the one at D differ with respect
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/structs.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/structs.c
|
|
|
|
@@ -22,7 +22,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
alloc_path (void)
|
|
|
|
{
|
|
|
|
struct path * pp;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
pp = (struct path *)MALLOC(sizeof(struct path));
|
|
|
|
|
|
|
|
if (pp) {
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -243,7 +243,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct multipath * mpp;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mpvec)
|
|
|
|
return NULL;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -262,7 +262,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct multipath * mpp;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mpvec)
|
|
|
|
return NULL;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -279,7 +279,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
int i;
|
|
|
|
int len;
|
|
|
|
struct multipath * mpp;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!mpvec)
|
|
|
|
return NULL;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -287,7 +287,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!len)
|
|
|
|
return NULL;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
vector_foreach_slot (mpvec, mpp, i) {
|
|
|
|
if (strlen(mpp->alias) == len &&
|
|
|
|
!strncmp(mpp->alias, alias, len))
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -315,7 +315,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!pathvec)
|
|
|
|
return NULL;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
vector_foreach_slot (pathvec, pp, i)
|
|
|
|
if (!strcmp_chomp(pp->dev, dev))
|
|
|
|
return pp;
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/structs_vec.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/structs_vec.c
|
|
|
|
@@ -280,13 +280,13 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
retry:
|
|
|
|
if (dm_get_info(mpp->alias, &mpp->dmi)) {
|
|
|
|
/* Error accessing table */
|
|
|
|
- condlog(3, "%s: cannot access table", mpp->alias);
|
|
|
|
+ condlog(3, "%s: cannot access table", mpp->alias);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dm_map_present(mpp->alias)) {
|
|
|
|
/* Table has been removed */
|
|
|
|
- condlog(3, "%s: table does not exist", mpp->alias);
|
|
|
|
+ condlog(3, "%s: table does not exist", mpp->alias);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/switchgroup.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/switchgroup.c
|
|
|
|
@@ -35,7 +35,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
if (!mpp->pg)
|
|
|
|
return 1;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
vector_foreach_slot (mpp->pg, pgp, i) {
|
|
|
|
if (!pgp->paths)
|
|
|
|
continue;
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/uevent.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/uevent.c
|
|
|
|
@@ -157,7 +157,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* enable receiving of the sender credentials */
|
|
|
|
- setsockopt(sock, SOL_SOCKET, SO_PASSCRED,
|
|
|
|
+ setsockopt(sock, SOL_SOCKET, SO_PASSCRED,
|
|
|
|
&feature_on, sizeof(feature_on));
|
|
|
|
|
|
|
|
} else {
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/util.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/util.c
|
|
|
|
@@ -14,7 +14,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char s1[PARAMS_SIZE],s2[PARAMS_SIZE];
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if(!str1 || !str2)
|
|
|
|
return 1;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -67,7 +67,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
char * p;
|
|
|
|
int len;
|
|
|
|
int skip = 0;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (word)
|
|
|
|
*word = NULL;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/uxsock.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/uxsock.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -26,17 +26,17 @@
|
|
|
|
int ux_socket_connect(const char *name)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
- struct sockaddr_un addr;
|
|
|
|
+ struct sockaddr_un addr;
|
|
|
|
|
|
|
|
- memset(&addr, 0, sizeof(addr));
|
|
|
|
- addr.sun_family = AF_UNIX;
|
|
|
|
- strncpy(addr.sun_path, name, sizeof(addr.sun_path));
|
|
|
|
+ memset(&addr, 0, sizeof(addr));
|
|
|
|
+ addr.sun_family = AF_UNIX;
|
|
|
|
+ strncpy(addr.sun_path, name, sizeof(addr.sun_path));
|
|
|
|
|
|
|
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (fd == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
|
|
|
close(fd);
|
|
|
|
return -1;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -47,12 +47,13 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* create a unix domain socket and start listening on it
|
|
|
|
- * return a file descriptor open on the socket
|
|
|
|
+ * return a file descriptor open on the socket
|
|
|
|
*/
|
|
|
|
int ux_socket_listen(const char *name)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
- struct sockaddr_un addr;
|
|
|
|
+ struct sockaddr_un addr;
|
|
|
|
+
|
|
|
|
|
|
|
|
/* get rid of any old socket */
|
|
|
|
unlink(name);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -60,16 +61,16 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (fd == -1) return -1;
|
|
|
|
|
|
|
|
- memset(&addr, 0, sizeof(addr));
|
|
|
|
- addr.sun_family = AF_UNIX;
|
|
|
|
- strncpy(addr.sun_path, name, sizeof(addr.sun_path));
|
|
|
|
+ memset(&addr, 0, sizeof(addr));
|
|
|
|
+ addr.sun_family = AF_UNIX;
|
|
|
|
+ strncpy(addr.sun_path, name, sizeof(addr.sun_path));
|
|
|
|
|
|
|
|
- if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
|
|
|
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
|
|
|
close(fd);
|
|
|
|
return -1;
|
|
|
|
- }
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (listen(fd, 10) == -1) {
|
|
|
|
+ if (listen(fd, 10) == -1) {
|
|
|
|
close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/vector.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/vector.c
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -1,10 +1,10 @@
|
|
|
|
-/*
|
|
|
|
+/*
|
|
|
|
* Part: Vector structure manipulation.
|
|
|
|
- *
|
|
|
|
+ *
|
|
|
|
* Version: $Id: vector.c,v 1.0.3 2003/05/11 02:28:03 acassen Exp $
|
|
|
|
- *
|
|
|
|
+ *
|
|
|
|
* Author: Alexandre Cassen, <acassen@linux-vs.org>
|
|
|
|
- *
|
|
|
|
+ *
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
@@ -23,7 +23,7 @@
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "vector.h"
|
|
|
|
|
|
|
|
-/*
|
|
|
|
+/*
|
|
|
|
* Initialize vector struct.
|
|
|
|
* allocated 'size' slot elements then return vector.
|
|
|
|
*/
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -54,7 +54,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
vector_insert_slot(vector v, int slot, void *value)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!vector_alloc_slot(v))
|
|
|
|
return NULL;
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/libmultipath/waiter.c
|
|
|
|
+++ multipath-tools-0.4.8/libmultipath/waiter.c
|
|
|
|
@@ -58,7 +58,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs)
|
|
|
|
{
|
|
|
|
struct event_thread *wp = (struct event_thread *)mpp->waiter;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
if (!wp) {
|
|
|
|
condlog(3, "%s: no waiter thread", mpp->alias);
|
|
|
|
return;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -113,7 +113,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
dm_task_no_open_count(waiter->dmt);
|
|
|
|
-
|
|
|
|
+
|
|
|
|
/* accept wait interruption */
|
|
|
|
set = unblock_signals();
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -154,7 +154,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
lock_cleanup_pop(waiter->vecs->lock);
|
|
|
|
|
|
|
|
if (r) {
|
|
|
|
- condlog(2, "%s: event checker exit",
|
|
|
|
+ condlog(2, "%s: event checker exit",
|
|
|
|
waiter->mapname);
|
|
|
|
return -1; /* stop the thread */
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath.conf.annotated
|
|
|
|
+++ multipath-tools-0.4.8/multipath.conf.annotated
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -134,6 +134,15 @@
|
|
|
|
# # default : no
|
|
|
|
# user_friendly_names no
|
|
|
|
#
|
|
|
|
+# #
|
|
|
|
+# # name : bindings_file
|
|
|
|
+# # scope : multipath
|
|
|
|
+# # desc : The location of the bindings file that is used with
|
|
|
|
+# # the user_friendly_names option.
|
|
|
|
+# # values : <full_pathname>
|
|
|
|
+# # default : "/var/lib/multipath/bindings"
|
|
|
|
+# bindings_file "/etc/multipath_bindings"
|
|
|
|
+#
|
|
|
|
#}
|
|
|
|
#
|
|
|
|
##
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/Makefile
|
|
|
|
+++ multipath-tools-0.4.8/multipath/Makefile
|
|
|
|
@@ -16,24 +16,27 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
$(EXEC): $(OBJS)
|
|
|
|
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS)
|
|
|
|
- $(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
|
|
|
- $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
|
|
|
|
|
|
|
|
install:
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
|
|
|
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
|
|
|
|
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 multipath.init.suse $(DESTDIR)$(rcdir)/boot.multipath
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d
|
|
|
|
- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/71-multipath.rules
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
|
|
|
|
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
|
|
|
- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir)
|
|
|
|
+ $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/mkinitrd/scripts
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 boot-multipath.sh $(DESTDIR)/lib/mkinitrd/scripts
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 setup-multipath.sh $(DESTDIR)/lib/mkinitrd/scripts
|
|
|
|
|
|
|
|
uninstall:
|
|
|
|
rm $(DESTDIR)/etc/udev/rules.d/multipath.rules
|
|
|
|
rm $(DESTDIR)$(bindir)/$(EXEC)
|
|
|
|
- rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
|
|
|
|
- rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
|
|
|
+ rm -f $(DESTDIR)/lib/mkinitrd/scripts/boot-multipath.sh
|
|
|
|
+ rm -f $(DESTDIR)/lib/mkinitrd/scripts/setup-multipath.sh
|
|
|
|
|
|
|
|
clean:
|
|
|
|
- rm -f core *.o $(EXEC) *.gz
|
|
|
|
+ rm -f core *.o $(EXEC)
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/boot-multipath.sh
|
|
|
|
+++ multipath-tools-0.4.8/multipath/boot-multipath.sh
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,39 @@
|
|
|
|
+#!/bin/bash
|
|
|
|
+#%stage: block
|
|
|
|
+#%depends: dm
|
|
|
|
+#%provides: dmroot
|
|
|
|
+#%programs: /sbin/multipath /lib/multipath/*
|
|
|
|
+#%if: "$root_mpath"
|
|
|
|
+#%modules: dm-multipath dm-round-robin dm-emc dm-hp_sw dm-rdac
|
|
|
|
+#
|
|
|
|
+##### Multipath
|
|
|
|
+##
|
|
|
|
+## If the root device can be accessed using multiple device paths,
|
|
|
|
+## this initializes and waits for them
|
|
|
|
+##
|
|
|
|
+## Command line parameters
|
|
|
|
+## -----------------------
|
|
|
|
+##
|
|
|
|
+## root_mpath=1 use multipath
|
|
|
|
+## mpath_status=off do not use multipath
|
|
|
|
+##
|
|
|
|
+
|
|
|
|
+load_modules
|
|
|
|
+
|
|
|
|
+# check for multipath parameter in /proc/cmdline
|
|
|
|
+mpath_status=$(get_param multipath)
|
|
|
|
+
|
|
|
|
+mpath_list=$(sed -n '/multipath/p' /proc/modules)
|
|
|
|
+if [ -z "$mpath_list" ] ; then
|
|
|
|
+ mpath_status=off
|
|
|
|
+fi
|
|
|
|
+if [ "$mpath_status" != "off" ] ; then
|
|
|
|
+ # We are waiting for a device-mapper device
|
|
|
|
+ root_major=$(sed -n 's/\(.*\) device-mapper/\1/p' /proc/devices)
|
|
|
|
+ # Rescan for multipath
|
|
|
|
+ echo -n "Setup multipath devices: "
|
|
|
|
+ /sbin/multipath -v0
|
|
|
|
+ wait_for_events
|
|
|
|
+ echo 'ok.'
|
|
|
|
+fi
|
|
|
|
+
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/main.c
|
|
|
|
+++ multipath-tools-0.4.8/multipath/main.c
|
|
|
|
@@ -79,6 +79,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
fprintf (stderr, " %s [-d] [-r] [-v lvl] [-p pol] [-b fil] [dev]\n", progname);
|
|
|
|
fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
|
|
|
|
fprintf (stderr, " %s -F [-v lvl]\n", progname);
|
|
|
|
+ fprintf (stderr, " %s -t\n", progname);
|
|
|
|
fprintf (stderr, " %s -h\n", progname);
|
|
|
|
fprintf (stderr,
|
|
|
|
"\n"
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -89,6 +90,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
" -f flush a multipath device map\n" \
|
|
|
|
" -F flush all multipath device maps\n" \
|
|
|
|
" -d dry run, do not create or update devmaps\n" \
|
|
|
|
+ " -t dump internal hardware table\n" \
|
|
|
|
" -r force devmap reload\n" \
|
|
|
|
" -p policy failover|multibus|group_by_serial|group_by_prio\n" \
|
|
|
|
" -b fil bindings file location\n" \
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -241,14 +243,14 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
else
|
|
|
|
dev = conf->dev;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* if we have a blacklisted device parameter, exit early
|
|
|
|
*/
|
|
|
|
- if (dev &&
|
|
|
|
+ if (dev &&
|
|
|
|
(filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0))
|
|
|
|
goto out;
|
|
|
|
-
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* scope limiting must be translated into a wwid
|
|
|
|
* failing the translation is fatal (by policy)
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -315,6 +317,55 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+dump_config (void)
|
|
|
|
+{
|
|
|
|
+ char * c;
|
|
|
|
+ char * reply;
|
|
|
|
+ unsigned int maxlen = 256;
|
|
|
|
+ int again = 1;
|
|
|
|
+
|
|
|
|
+ reply = MALLOC(maxlen);
|
|
|
|
+
|
|
|
|
+ while (again) {
|
|
|
|
+ if (!reply)
|
|
|
|
+ return 1;
|
|
|
|
+ c = reply;
|
|
|
|
+ c += snprint_defaults(c, reply + maxlen - c);
|
|
|
|
+ again = ((c - reply) == maxlen);
|
|
|
|
+ if (again) {
|
|
|
|
+ reply = REALLOC(reply, maxlen *= 2);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ c += snprint_blacklist(c, reply + maxlen - c);
|
|
|
|
+ again = ((c - reply) == maxlen);
|
|
|
|
+ if (again) {
|
|
|
|
+ reply = REALLOC(reply, maxlen *= 2);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ c += snprint_blacklist_except(c, reply + maxlen - c);
|
|
|
|
+ again = ((c - reply) == maxlen);
|
|
|
|
+ if (again) {
|
|
|
|
+ reply = REALLOC(reply, maxlen *= 2);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ c += snprint_hwtable(c, reply + maxlen - c, conf->hwtable);
|
|
|
|
+ again = ((c - reply) == maxlen);
|
|
|
|
+ if (again) {
|
|
|
|
+ reply = REALLOC(reply, maxlen *= 2);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ c += snprint_mptable(c, reply + maxlen - c, conf->mptable);
|
|
|
|
+ again = ((c - reply) == maxlen);
|
|
|
|
+ if (again)
|
|
|
|
+ reply = REALLOC(reply, maxlen *= 2);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printf("%s", reply);
|
|
|
|
+ FREE(reply);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
int
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
{
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -346,7 +397,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
condlog(0, "multipath tools need sysfs mounted");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
- while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:r")) != EOF ) {
|
|
|
|
+ while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:rt")) != EOF ) {
|
|
|
|
switch(arg) {
|
|
|
|
case 1: printf("optarg : %s\n",optarg);
|
|
|
|
break;
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -387,16 +438,19 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
if (conf->pgpolicy_flag == -1) {
|
|
|
|
printf("'%s' is not a valid policy\n", optarg);
|
|
|
|
usage(argv[0]);
|
|
|
|
- }
|
|
|
|
+ }
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
conf->force_reload = 1;
|
|
|
|
break;
|
|
|
|
+ case 't':
|
|
|
|
+ dump_config();
|
|
|
|
+ goto out;
|
|
|
|
case 'h':
|
|
|
|
usage(argv[0]);
|
|
|
|
case ':':
|
|
|
|
fprintf(stderr, "Missing option arguement\n");
|
|
|
|
- usage(argv[0]);
|
|
|
|
+ usage(argv[0]);
|
|
|
|
case '?':
|
|
|
|
fprintf(stderr, "Unknown switch: %s\n", optarg);
|
|
|
|
usage(argv[0]);
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/multipath.8
|
|
|
|
+++ multipath-tools-0.4.8/multipath/multipath.8
|
|
|
|
@@ -6,7 +6,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
.RB [\| \-v\ \c
|
|
|
|
.IR verbosity \|]
|
|
|
|
.RB [\| \-d \|]
|
|
|
|
-.RB [\| \-h | \-l | \-ll | \-f | \-F \|]
|
|
|
|
+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F \|]
|
|
|
|
.RB [\| \-p\ \c
|
|
|
|
.BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
|
|
|
|
.RB [\| device \|]
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -47,6 +47,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
.B \-F
|
|
|
|
flush all unused multipath device maps
|
|
|
|
.TP
|
|
|
|
+.B \-t
|
|
|
|
+print internal hardware table to stdout
|
|
|
|
+.TP
|
|
|
|
.BI \-p " policy"
|
|
|
|
force maps to specified policy:
|
|
|
|
.RS 1.2i
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -76,6 +79,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
.I device
|
|
|
|
may alternatively be a multipath mapname
|
|
|
|
.SH "SEE ALSO"
|
|
|
|
+.BR multipathd (8),
|
|
|
|
+.BR multipath.conf (5),
|
|
|
|
+.BR kpartx (8),
|
|
|
|
.BR udev (8),
|
|
|
|
.BR dmsetup (8)
|
|
|
|
.BR hotplug (8)
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/multipath.conf.5
|
|
|
|
+++ multipath-tools-0.4.8/multipath/multipath.conf.5
|
|
|
|
@@ -147,13 +147,24 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
.RE
|
|
|
|
.TP
|
|
|
|
.B features
|
|
|
|
-Specify any device-mapper features to be used. The most common of
|
|
|
|
-these features is
|
|
|
|
-.I "1 queue_if_no_path"
|
|
|
|
-Note that this can also be set via the
|
|
|
|
+Specify any device-mapper features to be used. Syntax is
|
|
|
|
+.I num list
|
|
|
|
+where
|
|
|
|
+.I num
|
|
|
|
+is the number of features in
|
|
|
|
+.I list.
|
|
|
|
+Possible values for the feature list are
|
|
|
|
+.RS
|
|
|
|
+.TP 12
|
|
|
|
+.B queue_if_no_path
|
|
|
|
+Queue IO if no path is active; identical to the
|
|
|
|
.I no_path_retry
|
|
|
|
keyword.
|
|
|
|
.TP
|
|
|
|
+.B no_partitions
|
|
|
|
+Disable automatic partitions generation via kpartx.
|
|
|
|
+.RE
|
|
|
|
+.TP
|
|
|
|
.B path_checker
|
|
|
|
The default method used to determine the paths' state. Possible values
|
|
|
|
are
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -225,6 +236,10 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
be overriden by any specific aliases in the \fImultipaths\fR section.
|
|
|
|
Default is
|
|
|
|
.I no
|
|
|
|
+.TP
|
|
|
|
+.B bindings_file
|
|
|
|
+The full pathname of the binding file to be used when the user_friendly_names option is set. Defaults to
|
|
|
|
+.I /var/lib/multipath/bindings
|
|
|
|
.
|
|
|
|
.SH "blacklist section"
|
|
|
|
The
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/multipath.init.suse
|
|
|
|
+++ multipath-tools-0.4.8/multipath/multipath.init.suse
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,137 @@
|
|
|
|
+#! /bin/sh
|
|
|
|
+# Copyright (c) 2005 SuSE GmbH Nuernberg, Germany.
|
|
|
|
+#
|
|
|
|
+# Author: Hannes Reinecke <feedback@suse.de>
|
|
|
|
+#
|
|
|
|
+# init.d/boot.multipath
|
|
|
|
+#
|
|
|
|
+### BEGIN INIT INFO
|
|
|
|
+# Provides: boot.multipath
|
|
|
|
+# Required-Start: boot.device-mapper boot.udev
|
2008-08-29 00:55:27 +02:00
|
|
|
+# Required-Stop: boot.device-mapper boot.udev
|
2008-07-25 04:06:36 +02:00
|
|
|
+# Default-Start: B
|
|
|
|
+# Default-Stop:
|
|
|
|
+# Short-Description: Create multipath device targets
|
|
|
|
+# Description: Setup initial multipath device-mapper targets
|
|
|
|
+### END INIT INFO
|
|
|
|
+
|
|
|
|
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
|
|
|
+PROGRAM=/sbin/multipath
|
|
|
|
+
|
|
|
|
+# Set the maximum number of open files
|
|
|
|
+MAX_OPEN_FDS=4096
|
|
|
|
+
|
|
|
|
+test -x $PROGRAM || exit 5
|
|
|
|
+
|
|
|
|
+# Shell functions sourced from /etc/rc.status:
|
|
|
|
+# rc_check check and set local and overall rc status
|
|
|
|
+# rc_status check and set local and overall rc status
|
|
|
|
+# rc_status -v ditto but be verbose in local rc status
|
|
|
|
+# rc_status -v -r ditto and clear the local rc status
|
|
|
|
+# rc_failed set local and overall rc status to failed
|
|
|
|
+# rc_reset clear local rc status (overall remains)
|
|
|
|
+# rc_exit exit appropriate to overall rc status
|
|
|
|
+. /etc/rc.status
|
|
|
|
+
|
|
|
|
+# First reset status of this service
|
|
|
|
+rc_reset
|
|
|
|
+
|
|
|
|
+# Return values acc. to LSB for all commands but status:
|
|
|
|
+# 0 - success
|
|
|
|
+# 1 - misc error
|
|
|
|
+# 2 - invalid or excess args
|
|
|
|
+# 3 - unimplemented feature (e.g. reload)
|
|
|
|
+# 4 - insufficient privilege
|
|
|
|
+# 5 - program not installed
|
|
|
|
+# 6 - program not configured
|
|
|
|
+# 7 - program is not running
|
|
|
|
+#
|
|
|
|
+# Note that starting an already running service, stopping
|
|
|
|
+# or restarting a not-running service as well as the restart
|
|
|
|
+# with force-reload (in case signalling is not supported) are
|
|
|
|
+# considered a success.
|
|
|
|
+
|
|
|
|
+case "$1" in
|
|
|
|
+ start)
|
|
|
|
+ echo -n "Creating multipath targets:"
|
|
|
|
+ # Check whether multipath daemon is already running
|
|
|
|
+ if /sbin/multipathd -k"list paths" > /dev/null 2>&1 ; then
|
|
|
|
+ echo -n " (multipathd running)"
|
|
|
|
+ rc_status -v
|
|
|
|
+ rc_exit
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ # Load prerequisite module
|
|
|
|
+ modprobe dm-multipath
|
|
|
|
+
|
|
|
|
+ # Be a chicken and flush all existing maps
|
|
|
|
+ $PROGRAM -F
|
|
|
|
+
|
|
|
|
+ # Clear /dev/disk/by-name/ prior to start-up; multipath will
|
|
|
|
+ # recreate them.
|
|
|
|
+ rm -f /dev/disk/by-name/* 2>&1 >/dev/null
|
|
|
|
+
|
|
|
|
+ # Set the maximum number of open files
|
|
|
|
+ if [ -n "$MAX_OPEN_FDS" ] ; then
|
|
|
|
+ ulimit -n $MAX_OPEN_FDS
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ # Start the program directly as checkproc doesn't work here
|
|
|
|
+ $PROGRAM -v 0
|
|
|
|
+
|
|
|
|
+ # Create all partitions which might have been missing
|
|
|
|
+ for map in $(/sbin/dmsetup ls --target multipath | sed '/No devices/d' | sort -n +2 | sed -n 's/.*, \(.*\))/\1/p' ) ; do
|
|
|
|
+ wait=5
|
|
|
|
+ while [ $wait -gt 0 ] ; do
|
|
|
|
+ [ -e /dev/dm-$map ] && break
|
|
|
|
+ wait=$((wait - 1))
|
|
|
|
+ sleep 1;
|
|
|
|
+ done
|
|
|
|
+ if [ $wait -le 0 ] ; then
|
|
|
|
+ echo -n "timeout waiting for devices"
|
|
|
|
+ rc_failed 1
|
|
|
|
+ break;
|
|
|
|
+ fi
|
|
|
|
+ /sbin/kpartx -a -p _part /dev/dm-$map
|
|
|
|
+ done
|
|
|
|
+
|
|
|
|
+ # Remember status and be verbose
|
|
|
|
+ rc_status -v
|
|
|
|
+ sleep 1
|
|
|
|
+ ;;
|
|
|
|
+ stop)
|
|
|
|
+ echo -n "Removing multipath targets:"
|
|
|
|
+
|
|
|
|
+ # Remove all partition mappings
|
|
|
|
+ if /sbin/dmsetup ls | sed '/No devices/d' | grep -q -- -part; then
|
|
|
|
+ /sbin/dmsetup ls --target multipath --exec "/sbin/kpartx -d -p _part" 2> /dev/null
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ # Flush all existing maps
|
|
|
|
+ $PROGRAM -F
|
|
|
|
+
|
|
|
|
+ rc_failed 0
|
|
|
|
+ rc_status -v
|
|
|
|
+ ;;
|
|
|
|
+ status)
|
|
|
|
+ echo -n "Checking multipath targets: "
|
|
|
|
+ # Display active multipath tables
|
|
|
|
+ tblnum=$(/sbin/dmsetup ls --target multipath | sed '/No devices/d' | wc --lines)
|
|
|
|
+ if [ "$tblnum" ] && [ $tblnum -gt 0 ] ; then
|
|
|
|
+ echo -n "($tblnum multipath devices) "
|
|
|
|
+ rc_failed 0
|
|
|
|
+ else
|
|
|
|
+ rc_failed 3
|
|
|
|
+ fi
|
|
|
|
+ rc_status -v
|
|
|
|
+ ;;
|
|
|
|
+ reload)
|
|
|
|
+ $0 stop
|
|
|
|
+ $0 start
|
|
|
|
+ ;;
|
|
|
|
+ *)
|
|
|
|
+ echo "Usage: $0 {start|stop|status}"
|
|
|
|
+ exit 1
|
|
|
|
+ ;;
|
|
|
|
+esac
|
|
|
|
+rc_exit
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipath/setup-multipath.sh
|
|
|
|
+++ multipath-tools-0.4.8/multipath/setup-multipath.sh
|
2008-07-25 04:06:36 +02:00
|
|
|
@@ -0,0 +1,45 @@
|
|
|
|
+#!/bin/bash
|
|
|
|
+#
|
|
|
|
+#%stage: devicemapper
|
|
|
|
+#%provides: dmroot
|
|
|
|
+#
|
|
|
|
+# force multipath and dm usage if multipath was forced
|
|
|
|
+if use_script multipath; then
|
|
|
|
+ root_mpath=1
|
|
|
|
+ root_dm=1
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+if [ -x /sbin/multipath -a -x /sbin/dmsetup ] ; then
|
|
|
|
+ for bd in $blockdev ; do
|
|
|
|
+ update_blockdev $bd
|
|
|
|
+ if [ $blockdriver = device-mapper ]; then
|
|
|
|
+ dm_uuid=$(dmsetup info -c --noheadings -o uuid -j $blockmajor -m $blockminor)
|
|
|
|
+ dm_creator=${dm_uuid%-*}
|
|
|
|
+ if [ "$dm_creator" = "mpath" ]; then
|
|
|
|
+ tmp_root_dm=1 # multipath needs dm
|
|
|
|
+ root_mpath=1
|
|
|
|
+ fi
|
|
|
|
+ fi
|
|
|
|
+ done
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+if use_script multipath; then
|
|
|
|
+ if [ -f /etc/multipath.conf ] ; then
|
|
|
|
+ cp -a /etc/multipath.conf $tmp_mnt/etc
|
|
|
|
+ fi
|
|
|
|
+ if [ -f /var/lib/multipath/bindings ] ; then
|
|
|
|
+ mkdir -p /var/lib/multipath
|
|
|
|
+ cp -a /var/lib/multipath/bindings $tmp_mnt/var/lib/multipath
|
|
|
|
+ fi
|
|
|
|
+ if [ -e /etc/udev/rules.d/71-multipath.rules ]; then
|
|
|
|
+ cp /etc/udev/rules.d/71-multipath.rules $tmp_mnt/etc/udev/rules.d
|
|
|
|
+ fi
|
|
|
|
+ if [ -e /etc/udev/rules.d/72-multipath-compat.rules ]; then
|
|
|
|
+ cp /etc/udev/rules.d/72-multipath-compat.rules $tmp_mnt/etc/udev/rules.d
|
|
|
|
+ fi
|
|
|
|
+ if [ -d /lib/multipath ]; then
|
|
|
|
+ mkdir $tmp_mnt/lib/multipath
|
|
|
|
+ fi
|
|
|
|
+fi
|
|
|
|
+
|
|
|
|
+save_var root_mpath
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipathd/Makefile
|
|
|
|
+++ multipath-tools-0.4.8/multipathd/Makefile
|
|
|
|
@@ -29,20 +29,19 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
|
|
|
|
$(EXEC): $(OBJS)
|
|
|
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $(EXEC) $(OBJS)
|
|
|
|
- $(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
|
|
|
|
|
|
|
install:
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
|
|
|
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 multipathd.init.suse $(DESTDIR)$(rcdir)/multipathd
|
|
|
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
|
|
|
|
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)
|
|
|
|
|
|
|
|
uninstall:
|
|
|
|
rm -f $(DESTDIR)$(bindir)/$(EXEC)
|
|
|
|
rm -f $(DESTDIR)$(rcdir)/$(EXEC)
|
|
|
|
- rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz
|
|
|
|
|
|
|
|
clean:
|
|
|
|
- rm -f core *.o $(EXEC) *.gz
|
|
|
|
+ rm -f core *.o $(EXEC)
|
|
|
|
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipathd/main.c
|
|
|
|
+++ multipath-tools-0.4.8/multipathd/main.c
|
|
|
|
@@ -944,19 +944,25 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
enable_group(pp);
|
|
|
|
}
|
|
|
|
else if (newstate == PATH_UP || newstate == PATH_GHOST) {
|
|
|
|
- LOG_MSG(4, checker_message(&pp->checker));
|
|
|
|
- /*
|
|
|
|
- * double the next check delay.
|
|
|
|
- * max at conf->max_checkint
|
|
|
|
- */
|
|
|
|
- if (pp->checkint < (conf->max_checkint / 2))
|
|
|
|
- pp->checkint = 2 * pp->checkint;
|
|
|
|
- else
|
|
|
|
- pp->checkint = conf->max_checkint;
|
|
|
|
+ if (pp->dmstate == PSTATE_FAILED ||
|
|
|
|
+ pp->dmstate == PSTATE_UNDEF) {
|
|
|
|
+ /* Clear IO errors */
|
|
|
|
+ reinstate_path(pp, 0);
|
|
|
|
+ } else {
|
|
|
|
+ LOG_MSG(4, checker_message(&pp->checker));
|
|
|
|
+ /*
|
|
|
|
+ * double the next check delay.
|
|
|
|
+ * max at conf->max_checkint
|
|
|
|
+ */
|
|
|
|
+ if (pp->checkint < (conf->max_checkint / 2))
|
|
|
|
+ pp->checkint = 2 * pp->checkint;
|
|
|
|
+ else
|
|
|
|
+ pp->checkint = conf->max_checkint;
|
|
|
|
|
|
|
|
- pp->tick = pp->checkint;
|
|
|
|
- condlog(4, "%s: delay next check %is",
|
|
|
|
+ pp->tick = pp->checkint;
|
|
|
|
+ condlog(4, "%s: delay next check %is",
|
|
|
|
pp->dev_t, pp->tick);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
else if (newstate == PATH_DOWN)
|
|
|
|
LOG_MSG(2, checker_message(&pp->checker));
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1341,9 +1347,7 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
/*
|
|
|
|
* exit path
|
|
|
|
*/
|
|
|
|
- lock(vecs->lock);
|
|
|
|
remove_maps_and_stop_waiters(vecs);
|
|
|
|
- free_pathvec(vecs->pathvec, FREE_PATHS);
|
|
|
|
|
|
|
|
pthread_cancel(check_thr);
|
|
|
|
pthread_cancel(uevent_thr);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1357,6 +1361,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
handlers = NULL;
|
|
|
|
free_polls();
|
|
|
|
|
|
|
|
+ lock(vecs->lock);
|
|
|
|
+ free_pathvec(vecs->pathvec, FREE_PATHS);
|
|
|
|
+ vecs->pathvec = NULL;
|
|
|
|
unlock(vecs->lock);
|
|
|
|
pthread_mutex_destroy(vecs->lock);
|
|
|
|
FREE(vecs->lock);
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1421,15 +1428,28 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
close(STDIN_FILENO);
|
|
|
|
- dup(in_fd);
|
|
|
|
+ if (dup(in_fd) < 0) {
|
|
|
|
+ fprintf(stderr, "cannot duplicate /dev/null for input"
|
|
|
|
+ ": %s\n", strerror(errno));
|
|
|
|
+ _exit(0);
|
|
|
|
+ }
|
|
|
|
close(STDOUT_FILENO);
|
|
|
|
- dup(out_fd);
|
|
|
|
+ if (dup(out_fd) < 0) {
|
|
|
|
+ fprintf(stderr, "cannot duplicate /dev/console for output"
|
|
|
|
+ ": %s\n", strerror(errno));
|
|
|
|
+ _exit(0);
|
|
|
|
+ }
|
|
|
|
close(STDERR_FILENO);
|
|
|
|
- dup(out_fd);
|
|
|
|
-
|
|
|
|
+ if (dup(out_fd) < 0) {
|
|
|
|
+ fprintf(stderr, "cannot duplicate /dev/console for error"
|
|
|
|
+ ": %s\n", strerror(errno));
|
|
|
|
+ _exit(0);
|
|
|
|
+ }
|
|
|
|
close(in_fd);
|
|
|
|
close(out_fd);
|
|
|
|
- chdir("/");
|
|
|
|
+ if (chdir("/") < 0)
|
|
|
|
+ fprintf(stderr, "cannot chdir to '/', continuing\n");
|
|
|
|
+
|
|
|
|
umask(0);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-08-29 00:55:27 +02:00
|
|
|
@@ -1451,7 +1471,9 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* make sure we don't lock any path */
|
|
|
|
- chdir("/");
|
|
|
|
+ if (chdir("/") < 0)
|
|
|
|
+ fprintf(stderr, "couldn't chdir to '/', continuing\n");
|
|
|
|
+
|
|
|
|
umask(umask(077) | 022);
|
|
|
|
|
|
|
|
conf = alloc_config();
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipathd/multipathd.init.suse
|
|
|
|
+++ multipath-tools-0.4.8/multipathd/multipathd.init.suse
|
|
|
|
@@ -12,10 +12,11 @@
|
|
|
|
### BEGIN INIT INFO
|
|
|
|
# Provides: multipathd
|
|
|
|
# Required-Start: $syslog
|
|
|
|
-# Required-Stop:
|
|
|
|
+# Required-Stop: $syslog
|
2008-07-25 04:06:36 +02:00
|
|
|
# Default-Start: 3 5
|
|
|
|
# Default-Stop: 0 1 2 4 6
|
|
|
|
-# Description: Starts multipath daemon
|
|
|
|
+# Short-Description: Starts multipath daemon
|
|
|
|
+# Description: Starts the multipath daemon
|
|
|
|
### END INIT INFO
|
|
|
|
|
|
|
|
PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
2008-08-29 00:55:27 +02:00
|
|
|
--- multipath-tools-0.4.8/multipathd/uxlsnr.c
|
|
|
|
+++ multipath-tools-0.4.8/multipathd/uxlsnr.c
|
|
|
|
@@ -168,5 +168,6 @@
|
2008-07-25 04:06:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+ close(ux_sock);
|
|
|
|
return NULL;
|
|
|
|
}
|