]> git.ipfire.org Git - people/pmueller/ipfire-3.x.git/commitdiff
Merge remote-tracking branch 'stevee/net-tools'
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 6 Apr 2015 22:47:59 +0000 (00:47 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 6 Apr 2015 22:47:59 +0000 (00:47 +0200)
239 files changed:
avahi/avahi.nm
cairo/cairo.nm
cracklib/cracklib.nm
cracklib/patches/cracklib-2.8.12-gettext.patch [deleted file]
cracklib/patches/cracklib-2.8.15-inttypes.patch [deleted file]
cryptsetup-luks/cryptsetup-luks.nm
curl/curl.nm
curl/patches/0101-curl-7.29.0-multilib.patch [deleted file]
curl/patches/0101-curl-7.32.0-multilib.patch [new file with mode: 0644]
curl/patches/0104-curl-7.19.7-localhost6.patch [new file with mode: 0644]
cyrus-sasl/cyrus-sasl.nm
diffutils/diffutils.nm
diffutils/patches/diffutils-format-security.patch [new file with mode: 0644]
fontconfig/fontconfig.nm
gc/gc.nm
glib2/glib2.nm
grubby/grubby.nm
iputils/iputils.nm
iputils/patches/iputils-ipfire.patch [new file with mode: 0644]
iputils/patches/iputils-s20071127-addrcache.patch [deleted file]
iputils/patches/iputils-s20071127-arping-infiniband.patch [deleted file]
iputils/patches/iputils-s20071127-arping_timeout.patch [deleted file]
iputils/patches/iputils-s20071127-countermeasures.patch [deleted file]
iputils/patches/iputils-s20071127-idn.patch [deleted file]
iputils/patches/iputils-s20071127-open-max.patch [deleted file]
iputils/patches/iputils-s20071127-output.patch [deleted file]
iputils/patches/iputils-s20071127-ping-subint.patch [deleted file]
iputils/patches/iputils-s20071127-ping_cleanup.patch [deleted file]
iputils/patches/iputils-s20071127-rh.patch [deleted file]
iputils/patches/iputils-s20071127-traffic_class.patch [deleted file]
iputils/patches/iputils-s20071127-warnings.patch [deleted file]
iputils/patches/iputils-tracepath-doc.patch [new file with mode: 0644]
lcms2/lcms2.nm
libaio/libaio.nm
libatomic_ops/libatomic_ops.nm [new file with mode: 0644]
libatomic_ops/patches/libatomic_ops-7.4.2-no_undefined.patch [new file with mode: 0644]
libksba/libksba.nm
libpcap/libpcap.nm
libunwind/libunwind.nm
libunwind/patches/libunwind-aarch64.patch [new file with mode: 0644]
libunwind/patches/libunwind-arm-register-rename.patch [deleted file]
libunwind/patches/libunwind-disable-setjmp.patch
libxml2/libxml2.nm
libxml2/patches/libxml2-2.7.7-xpath-double-free.patch [deleted file]
libxml2/patches/libxml2-2.9.2-catalog-revert.patch [new file with mode: 0644]
multipath-tools/multipath-tools.nm
multipath-tools/patches/0001-RH-dont_start_with_no_config.patch [new file with mode: 0644]
multipath-tools/patches/0001-RH-remove_callout.patch [deleted file]
multipath-tools/patches/0002-RH-add-wwids-file.patch [deleted file]
multipath-tools/patches/0002-RH-multipath.rules.patch [moved from multipath-tools/patches/0006-RH-multipath.rules.patch with 62% similarity]
multipath-tools/patches/0003-RH-Make-build-system-RH-Fedora-friendly.patch [moved from multipath-tools/patches/0007-RH-Make-build-system-RH-Fedora-friendly.patch with 77% similarity]
multipath-tools/patches/0003-RH-add-followover.patch [deleted file]
multipath-tools/patches/0004-RH-fix-cciss-names.patch [deleted file]
multipath-tools/patches/0004-RH-multipathd-blacklist-all-by-default.patch [moved from multipath-tools/patches/0008-RH-multipathd-blacklist-all-by-default.patch with 83% similarity]
multipath-tools/patches/0005-RH-add-mpathconf.patch [moved from multipath-tools/patches/0009-RH-add-mpathconf.patch with 94% similarity]
multipath-tools/patches/0005-RH-dont_start_with_no_config.patch [deleted file]
multipath-tools/patches/0006-RH-add-find-multipaths.patch [moved from multipath-tools/patches/0010-RH-add-find-multipaths.patch with 67% similarity]
multipath-tools/patches/0007-RH-add-hp_tur-checker.patch [moved from multipath-tools/patches/0011-RH-add-hp_tur-checker.patch with 100% similarity]
multipath-tools/patches/0008-RH-revert-partition-changes.patch [new file with mode: 0644]
multipath-tools/patches/0009-RH-RHEL5-style-partitions.patch [moved from multipath-tools/patches/0012-RH-RHEL5-style-partitions.patch with 90% similarity]
multipath-tools/patches/0010-RH-dont-remove-map-on-enomem.patch [moved from multipath-tools/patches/0013-RH-dont-remove-map-on-enomem.patch with 69% similarity]
multipath-tools/patches/0011-RH-deprecate-uid-gid-mode.patch [moved from multipath-tools/patches/0014-RH-deprecate-uid-gid-mode.patch with 100% similarity]
multipath-tools/patches/0012-RH-kpartx-msg.patch [new file with mode: 0644]
multipath-tools/patches/0013-RHBZ-883981-cleanup-rpmdiff-issues.patch [new file with mode: 0644]
multipath-tools/patches/0014-RH-handle-other-sector-sizes.patch [new file with mode: 0644]
multipath-tools/patches/0015-RH-fix-output-buffer.patch [new file with mode: 0644]
multipath-tools/patches/0015-RH-use-sync-support.patch [deleted file]
multipath-tools/patches/0016-RH-change-configs.patch [deleted file]
multipath-tools/patches/0016-RH-dont-print-ghost-messages.patch [new file with mode: 0644]
multipath-tools/patches/0018-RH-fix-factorize.patch [new file with mode: 0644]
multipath-tools/patches/0019-RH-fix-sockets.patch [new file with mode: 0644]
multipath-tools/patches/0020-RHBZ-907360-static-pthread-init.patch [new file with mode: 0644]
multipath-tools/patches/0021-RHBZ-919119-respect-kernel-cmdline.patch [new file with mode: 0644]
multipath-tools/patches/0022-RH-multipathd-check-wwids.patch [new file with mode: 0644]
multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch [new file with mode: 0644]
multipath-tools/patches/0024-RH-multipath-wipe-wwids.patch [new file with mode: 0644]
multipath-tools/patches/0025-UPBZ-916668_add_maj_min.patch [new file with mode: 0644]
multipath-tools/patches/0026-fix-checker-time.patch [new file with mode: 0644]
multipath-tools/patches/0027-RH-get-wwid.patch [new file with mode: 0644]
multipath-tools/patches/0028-RHBZ-929078-refresh-udev-dev.patch [new file with mode: 0644]
multipath-tools/patches/0029-RH-no-prio-put-msg.patch [new file with mode: 0644]
multipath-tools/patches/0030-RHBZ-916528-override-queue-no-daemon.patch [new file with mode: 0644]
multipath-tools/patches/0031-RHBZ-957188-kpartx-use-dm-name.patch [new file with mode: 0644]
multipath-tools/patches/0032-RHBZ-956464-mpathconf-defaults.patch [new file with mode: 0644]
multipath-tools/patches/0033-RHBZ-829963-e-series-conf.patch [new file with mode: 0644]
multipath-tools/patches/0034-RHBZ-851416-mpathconf-display.patch [new file with mode: 0644]
multipath-tools/patches/0035-RHBZ-891921-list-mpp.patch [new file with mode: 0644]
multipath-tools/patches/0036-RHBZ-949239-load-multipath-module.patch [new file with mode: 0644]
multipath-tools/patches/0037-RHBZ-768873-fix-rename.patch [new file with mode: 0644]
multipath-tools/patches/0038-RHBZ-799860-netapp-config.patch [new file with mode: 0644]
multipath-tools/patches/0039-RH-detect-prio-fix.patch [new file with mode: 0644]
multipath-tools/patches/0040-RH-bindings-fix.patch [new file with mode: 0644]
multipath-tools/patches/0041-RH-check-for-erofs.patch [new file with mode: 0644]
multipath-tools/patches/0042-UP-fix-signal-handling.patch [new file with mode: 0644]
multipath-tools/patches/0043-RH-signal-waiter.patch [new file with mode: 0644]
multipath-tools/patches/0044-RHBZ-976688-fix-wipe-wwids.patch [new file with mode: 0644]
multipath-tools/patches/0045-RHBZ-977297-man-page-fix.patch [new file with mode: 0644]
multipath-tools/patches/0046-RHBZ-883981-move-udev-rules.patch [new file with mode: 0644]
multipath-tools/patches/0047-RHBZ-980777-kpartx-read-only-loop-devs.patch [new file with mode: 0644]
multipath-tools/patches/0048-RH-print-defaults.patch [new file with mode: 0644]
multipath-tools/patches/0049-RH-remove-ID_FS_TYPE.patch [new file with mode: 0644]
multipath-tools/patches/0050-RH-listing-speedup.patch [new file with mode: 0644]
multipath-tools/patches/0051-UP-fix-cli-resize.patch [new file with mode: 0644]
multipath-tools/patches/0052-RH-fix-bad-derefs.patch [new file with mode: 0644]
multipath-tools/patches/0053-UP-fix-failback.patch [new file with mode: 0644]
multipath-tools/patches/0054-UP-keep-udev-ref.patch [new file with mode: 0644]
multipath-tools/patches/0055-UP-handle-quiesced-paths.patch [new file with mode: 0644]
multipath-tools/patches/0056-UP-alua-prio-fix.patch [new file with mode: 0644]
multipath-tools/patches/0057-UP-fix-tmo.patch [new file with mode: 0644]
multipath-tools/patches/0058-UP-fix-failback.patch [new file with mode: 0644]
multipath-tools/patches/0059-UP-flush-failure-queueing.patch [new file with mode: 0644]
multipath-tools/patches/0060-UP-uevent-loop-udev.patch [new file with mode: 0644]
multipath-tools/patches/0061-RH-display-find-mpaths.patch [new file with mode: 0644]
multipath-tools/patches/0062-RH-dont-free-vecs.patch [new file with mode: 0644]
multipath-tools/patches/0063-RH-fix-warning.patch [new file with mode: 0644]
multipath-tools/patches/0064-fix-ID_FS-attrs.patch [new file with mode: 0644]
multipath-tools/patches/0065-UPBZ-995538-fail-rdac-on-unavailable.patch [new file with mode: 0644]
multipath-tools/patches/0066-UP-dos-4k-partition-fix.patch [new file with mode: 0644]
multipath-tools/patches/0067-RHBZ-1022899-fix-udev-partition-handling.patch [new file with mode: 0644]
multipath-tools/patches/0068-RHBZ-1034578-label-partition-devices.patch [new file with mode: 0644]
multipath-tools/patches/0069-UPBZ-1033791-improve-rdac-checker.patch [new file with mode: 0644]
multipath-tools/patches/0070-RHBZ-1036503-blacklist-td-devs.patch [new file with mode: 0644]
multipath-tools/patches/0071-RHBZ-1031546-strip-dev.patch [new file with mode: 0644]
multipath-tools/patches/0072-RHBZ-1039199-check-loop-control.patch [new file with mode: 0644]
multipath-tools/patches/0073-RH-update-build-flags.patch [new file with mode: 0644]
multipath-tools/patches/0074-RHBZ-1056976-dm-mpath-rules.patch [new file with mode: 0644]
multipath-tools/patches/0075-RHBZ-1056976-reload-flag.patch [new file with mode: 0644]
multipath-tools/patches/0076-RHBZ-1056686-add-hw_str_match.patch [new file with mode: 0644]
multipath-tools/patches/0078-RHBZ-1054044-fix-mpathconf-manpage.patch [new file with mode: 0644]
multipath-tools/patches/0079-RHBZ-1070581-add-wwid-option.patch [new file with mode: 0644]
multipath-tools/patches/0080-RHBZ-1075796-cmdline-wwid.patch [new file with mode: 0644]
multipath-tools/patches/0081-RHBZ-1066264-check-prefix-on-rename.patch [new file with mode: 0644]
multipath-tools/patches/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch [new file with mode: 0644]
multipath-tools/patches/0083-RHBZ-1080055-orphan-paths-on-reload.patch [new file with mode: 0644]
multipath-tools/patches/0084-RHBZ-1110000-multipath-man.patch [new file with mode: 0644]
multipath-tools/patches/0085-UPBZ-1110006-datacore-config.patch [new file with mode: 0644]
multipath-tools/patches/0086-RHBZ-1110007-orphan-path-on-failed-add.patch [new file with mode: 0644]
multipath-tools/patches/0087-RHBZ-1110013-config-error-checking.patch [new file with mode: 0644]
multipath-tools/patches/0088-RHBZ-1069811-configurable-prio-timeout.patch [new file with mode: 0644]
multipath-tools/patches/0089-RHBZ-1110016-add-noasync-option.patch [new file with mode: 0644]
multipath-tools/patches/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch [new file with mode: 0644]
multipath-tools/patches/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch [new file with mode: 0644]
multipath-tools/patches/0092-UPBZ-1104605-reload-on-rename.patch [new file with mode: 0644]
multipath-tools/patches/0093-UPBZ-1086825-user-friendly-name-remap.patch [new file with mode: 0644]
multipath-tools/patches/0094-RHBZ-1086825-cleanup-remap.patch [new file with mode: 0644]
multipath-tools/patches/0095-RHBZ-1127944-xtremIO-config.patch [new file with mode: 0644]
multipath-tools/patches/0096-RHBZ-979474-new-wildcards.patch [new file with mode: 0644]
multipath-tools/patches/0097-RH-fix-coverity-errors.patch [new file with mode: 0644]
multipath-tools/patches/0098-UPBZ-1067171-mutipath-i.patch [new file with mode: 0644]
multipath-tools/patches/0099-RH-add-all-devs.patch [new file with mode: 0644]
multipath-tools/patches/0100-RHBZ-1067171-multipath-i-update.patch [new file with mode: 0644]
multipath-tools/patches/0101-RH-adapter-name-wildcard.patch [new file with mode: 0644]
multipath-tools/patches/0102-RHBZ-1160478-mpathconf-template.patch [new file with mode: 0644]
multipath-tools/patches/0103-RH-cleanup-partmaps-code.patch [new file with mode: 0644]
multipath-tools/patches/0104-RHBZ-631009-deferred-remove.patch [new file with mode: 0644]
multipath-tools/patches/0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch [new file with mode: 0644]
multipath-tools/patches/0106-RHBZ-1159337-fix-double-free.patch [new file with mode: 0644]
multipath-tools/patches/0107-RHBZ-1169935-no-new-devs.patch [new file with mode: 0644]
multipath-tools/patches/0108-RHBZ-1153832-kpartx-remove-devs.patch [new file with mode: 0644]
multipath-tools/patches/0109-RH-read-only-bindings.patch [new file with mode: 0644]
multipath-tools/patches/0110-RHBZ-blacklist-vd-devs.patch [new file with mode: 0644]
multipath-tools/patches/0111-RH-dont-show-pg-timeout.patch [new file with mode: 0644]
multipath-tools/patches/0112-RHBZ-1194917-add-config_dir-option.patch [new file with mode: 0644]
multipath-tools/patches/0113-RHBZ-1194917-cleanup.patch [new file with mode: 0644]
multipath-tools/patches/0114-RHBZ-1196394-delayed-reintegration.patch [new file with mode: 0644]
multipath-tools/patches/0115-RHBZ-1198418-fix-double-free.patch [new file with mode: 0644]
multipath-tools/patches/0116-UPBZ-1188179-dell-36xxi.patch [new file with mode: 0644]
multipath-tools/patches/0117-RHBZ-1198424-autodetect-clariion-alua.patch [new file with mode: 0644]
ncurses/ncurses.nm
openssh/openssh.nm
openssh/patches/openssh-4.3p2-askpass-grab-info.patch [deleted file]
openssh/patches/openssh-5.1p1-askpass-progress.patch [deleted file]
openssh/patches/openssh-5.1p1-scp-manpage.patch [deleted file]
openssh/patches/openssh-5.2p1-allow-ip-opts.patch [deleted file]
openssh/patches/openssh-5.5p1-x11.patch [deleted file]
openssh/patches/openssh-5.6p1-exit-deadlock.patch [deleted file]
openssh/patches/openssh-5.6p1-redhat.patch [deleted file]
openssh/patches/openssh-5.8p1-fingerprint.patch [deleted file]
openssh/patches/openssh-5.8p1-getaddrinfo.patch [deleted file]
openssh/patches/openssh-5.8p1-localdomain.patch [deleted file]
openssh/patches/openssh-5.8p1-packet.patch [deleted file]
openssh/patches/openssh-5.8p2-force_krb.patch [deleted file]
openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch [deleted file]
openssh/patches/openssh-5.8p2-sigpipe.patch [deleted file]
openssh/patches/openssh-5.9p1-akc.patch [deleted file]
openssh/patches/openssh-5.9p1-edns.patch [deleted file]
openssh/patches/openssh-5.9p1-ipfire.patch [deleted file]
openssh/patches/openssh-5.9p1-ipv6man.patch [deleted file]
openssh/patches/openssh-5.9p1-keygen.patch [deleted file]
openssh/patches/openssh-5.9p1-randclean.patch [deleted file]
openssh/patches/openssh-5.9p1-sftp-chroot.patch [deleted file]
openssh/patches/openssh-6.0p1-entropy.patch [deleted file]
openssh/patches/openssh-6.1p1-akc.patch [deleted file]
openssh/patches/openssh-6.1p1-askpass-ld.patch [deleted file]
openssh/patches/openssh-6.1p1-authenticationmethods.patch [deleted file]
openssh/patches/openssh-6.1p1-coverity.patch [deleted file]
openssh/patches/openssh-6.1p1-kuserok.patch [deleted file]
openssh/patches/openssh-6.1p1-required-authentications.patch [deleted file]
openssh/patches/openssh-6.1p1-role-mls.patch [deleted file]
openssh/patches/openssh-6.1p1-vendor.patch [deleted file]
openssh/patches/openssh-6.6p1-keyperm.patch [moved from openssh/patches/openssh-5.8p1-keyperm.patch with 54% similarity]
openssh/patches/openssh-6.7p1-audit.patch [new file with mode: 0644]
openssh/patches/openssh-6.7p1-seccomp-aarch64.patch [new file with mode: 0644]
openssh/patches/openssh-6.7p1-sftp-force-permission.patch [new file with mode: 0644]
openvpn/openvpn.nm
pango/pango.nm
perl-BDB/perl-BDB.nm
perl-Coro/perl-Coro.nm
perl-Crypt-PasswdMD5/perl-Crypt-PasswdMD5.nm
perl-DBI/perl-DBI.nm
perl-Digest-SHA1/perl-Digest-SHA1.nm
perl-FCGI/perl-FCGI.nm
perl-HTML-Parser/perl-HTML-Parser.nm
perl-HTML-Tagset/perl-HTML-Tagset.nm
perl-IO-AIO/perl-IO-AIO.nm
perl-TermReadKey/perl-TermReadKey.nm
perl-Tk/perl-Tk.nm
perl-URI/perl-URI.nm
perl-WWW-Curl/perl-WWW-Curl.nm
perl-XML-Parser/perl-XML-Parser.nm
perl-common-sense/perl-common-sense.nm
perl-libintl-perl/perl-libintl-perl.nm
perl/perl.nm
pigz/pigz.nm
pinentry/pinentry.nm
pixman/pixman.nm
procps-ng/procps-ng.nm [new file with mode: 0644]
python/python-2.7-lib64-sysconfig.patch [moved from python/patches/x86_64/python-2.7-lib64-sysconfig.patch with 100% similarity]
python/python-2.7.3-lib64.patch [moved from python/patches/x86_64/python-2.7.3-lib64.patch with 100% similarity]
python/python.nm
rrdtool/rrdtool.nm
strace/patches/0001-linux-aarch64-add-missing-header.patch [new file with mode: 0644]
strace/strace.nm
sysvinit/sysvinit.nm
tar/tar.nm
unzip/patches/unzip-6.0-format-secure.patch [new file with mode: 0644]
unzip/unzip.nm
xfsprogs/xfsprogs.nm
xmlto/xmlto.nm

index 1041320da9275b6ee608c3cfc54efbf097406fdb..cd3bcfa5bd61022f83b04cb49bc1bf7f61e4a92a 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = avahi
-version    = 0.6.30
-release    = 4
+version    = 0.6.31
+release    = 1
 
 groups     = Networking/Zeroconf
 url        = http://avahi.org/
@@ -26,6 +26,7 @@ source_dl  = http://avahi.org/download/
 
 build
        requires
+               automake
                dbus-devel
                dbus-glib-devel
                expat-devel
@@ -41,6 +42,13 @@ build
                systemd-units
        end
 
+       prepare_cmds
+               # for aarch64
+               for i in $(find . -name config.guess -or -name config.sub); do
+                       cp -vf %{datadir}/automake-*/config.{guess,sub} $(dirname ${i})
+               done
+       end
+
        configure_options += \
                --with-distro=none \
                --with-systemdsystemunitdir=%{unitdir} \
index 55b92f87f30a209ae35cb1f65f87cc98b977cd6f..911ff4cd1c0c3929f6aca7ec3720b77c44404a1f 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = cairo
-version    = 1.12.12
+version    = 1.14.2
 release    = 1
 
 groups     = System/Graphics
@@ -23,14 +23,15 @@ sources    = %{thisapp}.tar.xz
 build
        requires
                binutils>=2.21.51.0.8-2
-               fontconfig-devel
+               fontconfig-devel >= 2.10
                freetype-devel
+               glib2-devel >= 2.14
                gobject-introspection-devel
                libX11-devel
                libXext-devel>=1.3.1
                libxml2-devel
                libpng-devel
-               pixman-devel>=0.22
+               pixman-devel >= 0.30.0
                pkg-config
                zlib-devel
        end
index 93a3464a335b47ffaeb1bb72796f5c5ef0445ca9..d9d666f9aa27af89c3d49bd2b278bde594421502 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = cracklib
-version    = 2.8.18
-release    = 2
+version    = 2.9.2
+release    = 1
 
 groups     = Security/Password
 url        = http://sourceforge.net/projects/cracklib/
@@ -27,9 +27,6 @@ sources   += cracklib-words-20080507.gz
 
 build
        requires
-               autoconf
-               automake
-               gettext-devel
                python-devel
        end
 
@@ -49,11 +46,6 @@ build
                cp lib/packer.h lib/packer.h.in
                chmod +x util/cracklib-format
 
-               # Apply all patches.
-               %{MACRO_PATCHES}
-
-               #autoreconf -fi
-
                mkdir cracklib-dicts
                cp -vf %{DIR_DL}/cracklib-words-20080507.gz cracklib-dicts
 
diff --git a/cracklib/patches/cracklib-2.8.12-gettext.patch b/cracklib/patches/cracklib-2.8.12-gettext.patch
deleted file mode 100644 (file)
index 8608187..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-Newer autopoint chokes if we don't explicitly list a version here.
-diff -up cracklib-2.8.12/configure.in cracklib-2.8.12/configure.in
---- cracklib-2.8.12/configure.in       2008-10-28 13:27:06.000000000 -0400
-+++ cracklib-2.8.12/configure.in       2008-10-28 13:27:07.000000000 -0400
-@@ -58,7 +58,7 @@ AC_CHECK_FUNCS(strdup)
- AC_CHECK_FUNCS(getpwuid_r)
- dnl internationalization macros
--AM_GNU_GETTEXT_VERSION
-+AM_GNU_GETTEXT_VERSION(0.14)
- AM_GNU_GETTEXT([external])
- dnl Control default dictname
diff --git a/cracklib/patches/cracklib-2.8.15-inttypes.patch b/cracklib/patches/cracklib-2.8.15-inttypes.patch
deleted file mode 100644 (file)
index d1d6a23..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-Don't depend on a consumer of <packer.h> to be using autoconf, and to be
-checking for for the presence of <inttypes.h> and <stdint.h>, and including
-its own "config.h" before including <packer.h>, in order for this to be
-correct on 64-bit machines.
-
-diff -up cracklib-2.8.15/configure.in cracklib-2.8.15/configure.in
---- cracklib-2.8.15/configure.in       2009-11-18 18:58:21.000000000 -0500
-+++ cracklib-2.8.15/configure.in       2009-12-01 15:16:35.000000000 -0500
-@@ -26,6 +26,19 @@ AC_CHECK_HEADERS(zlib.h, AC_DEFINE(HAVE_
- AC_SEARCH_LIBS(gzopen, z)
-+if test x$ac_cv_header_inttypes_h = xyes ; then
-+      CRACKLIB_INTEGER_TYPES1="#include <inttypes.h>"
-+      CRACKLIB_INTEGER_TYPES2=
-+elif test x$ac_cv_header_stdint_h = xyes ; then
-+      CRACKLIB_INTEGER_TYPES1="#include <stdint.h>"
-+      CRACKLIB_INTEGER_TYPES2=
-+else
-+      CRACKLIB_INTEGER_TYPES1="typedef unsigned int uint32_t;"
-+      CRACKLIB_INTEGER_TYPES2="typedef unsigned short uint16_t;"
-+fi
-+AC_SUBST(CRACKLIB_INTEGER_TYPES1)
-+AC_SUBST(CRACKLIB_INTEGER_TYPES2)
-+
- dnl Cygwin workaround
- AC_MSG_CHECKING(if LINE_MAX is defined)
- AC_EGREP_CPP(yes,
-@@ -92,5 +105,6 @@ AC_SUBST(CROSS_COMPILING, $cross_compili
- AC_OUTPUT(util/Makefile lib/Makefile doc/Makefile python/Makefile Makefile \
-               python/setup.py \
-+              lib/packer.h \
-               po/Makefile.in m4/Makefile dicts/Makefile cracklib.spec)
-diff -up cracklib-2.8.15/lib/packer.h.in cracklib-2.8.15/lib/packer.h.in
---- cracklib-2.8.15/lib/packer.h.in    2009-12-01 15:15:38.000000000 -0500
-+++ cracklib-2.8.15/lib/packer.h.in    2009-12-01 15:15:38.000000000 -0500
-@@ -30,17 +30,8 @@
- #define _(String) (String)
- #endif
--#if defined(HAVE_INTTYPES_H)
--#include <inttypes.h>
--#else
--#if defined(HAVE_STDINT_H)
--#include <stdint.h>
--#else
--typedef unsigned int uint32_t;
--typedef unsigned short uint16_t;
--#endif
--#endif
--
-+@CRACKLIB_INTEGER_TYPES1@
-+@CRACKLIB_INTEGER_TYPES2@
- struct pi_header
- {
-@@ -83,6 +74,9 @@ typedef struct {
-       int dummy;
- } PWDICT;
-+@CRACKLIB_INTEGER_TYPES1@
-+@CRACKLIB_INTEGER_TYPES2@
-+
- #endif
- extern PWDICT *PWOpen(const char *prefix, char *mode);
index 2c833015e2ec45a88be8dcc221abc1c4a48dab4c..a341638c6d148de0bad3ba180094b3dcafad5119 100644 (file)
@@ -4,13 +4,12 @@
 ###############################################################################
 
 name       = cryptsetup-luks
-version    = 1.4.2
+version    = %{ver_maj}.7
+ver_maj    = 1.6
 release    = 1
 
-compat_version = 1.1.0
-
 groups     = System/Filesystems
-url        = http://cryptsetup.googlecode.com/
+url        = https://gitlab.com/cryptsetup/cryptsetup
 license    = GPLv2+
 summary    = A utility for setting up encrypted filesystems.
 
@@ -19,11 +18,9 @@ description
        encrypted filesystems using Device Mapper and the dm-crypt target.
 end
 
-source_dl  = http://cryptsetup.googlecode.com/files/
-
-sources    = \
-       cryptsetup-%{version}.tar.bz2 \
-       cryptsetup-%{compat_version}.tar.bz2
+source_dl  = \
+       https://www.kernel.org/pub/linux/utils/cryptsetup/v%{ver_maj}/
+sources = cryptsetup-%{version}.tar.xz
 
 build
        requires
@@ -38,35 +35,11 @@ build
 
        configure_options += \
                --disable-static
-
-       # Build compat version of libcryptsetup.
-       build_cmds
-               cd %{DIR_SRC}/cryptsetup-%{compat_version}
-               ./configure \
-                       %{configure_options}
-
-               make %{PARALLELISMFLAGS}
-       end
-
-       install_cmds
-               # Install compat version of libcyptsetup.
-               cd %{DIR_SRC}/cryptsetup-%{compat_version}
-               install -m 644 lib/.libs/libcryptsetup.so.1.0.0 %{BUILDROOT}%{libdir}
-               ln -svf libcryptsetup.so.1.0.0 %{BUILDROOT}%{libdir}/libcryptsetup.so.1 
-       end
 end
 
 packages
        package %{name}
 
-       package %{name}-compat
-               summary = Compat libraries of %{thisapp}.
-
-               files
-                       %{libdir}/libcryptsetup.so.1*
-               end
-       end
-
        package %{name}-devel
                template DEVEL
        end
index 6cfa7b5fce19a94a0aba791015ee276e6d4b14a3..4bebbfff7dbf5b9d84c425aba899605c66854c1a 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = curl
-version    = 7.29.0
+version    = 7.41.0
 release    = 1
 
 groups     = Application/Internet
diff --git a/curl/patches/0101-curl-7.29.0-multilib.patch b/curl/patches/0101-curl-7.29.0-multilib.patch
deleted file mode 100644 (file)
index 38aa86c..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
- curl-config.in     |   16 +++-------------
- docs/curl-config.1 |    4 +++-
- libcurl.pc.in      |    1 +
- 3 files changed, 7 insertions(+), 14 deletions(-)
-
-diff --git a/curl-config.in b/curl-config.in
-index 150004d..95d0759 100644
---- a/curl-config.in
-+++ b/curl-config.in
-@@ -75,7 +75,7 @@ while test $# -gt 0; do
-       ;;
-     --cc)
--      echo "@CC@"
-+      echo "gcc"
-       ;;
-     --prefix)
-@@ -142,24 +142,14 @@ while test $# -gt 0; do
-               ;;
-     --libs)
--      if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
--         CURLLIBDIR="-L@libdir@ "
--      else
--         CURLLIBDIR=""
--      fi
--      if test "X@REQUIRE_LIB_DEPS@" = "Xyes"; then
--        echo ${CURLLIBDIR}-lcurl @LIBCURL_LIBS@
--      else
--        echo ${CURLLIBDIR}-lcurl
--      fi
-+      pkg-config libcurl --libs
-       ;;
-     --static-libs)
--      echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
-       ;;
-     --configure)
--      echo @CONFIGURE_OPTIONS@
-+      pkg-config libcurl --variable=configure_options | sed 's/^"//;s/"$//'
-     ;;
-     *)
-diff --git a/docs/curl-config.1 b/docs/curl-config.1
-index c4f4e2b..3e0ea60 100644
---- a/docs/curl-config.1
-+++ b/docs/curl-config.1
-@@ -65,7 +65,9 @@ be listed using uppercase and are separa
- one, or several protocols in the list. (Added in 7.13.0)
- .IP "--static-libs"
- Shows the complete set of libs and other linker options you will need in order
--to link your application with libcurl statically. (Added in 7.17.1)
-+to link your application with libcurl statically. Note that Fedora/RHEL libcurl
-+packages do not provide any static libraries, thus cannot be linked statically.
-+(Added in 7.17.1)
- .IP "--version"
- Outputs version information about the installed libcurl.
- .IP "--vernum"
-diff --git a/libcurl.pc.in b/libcurl.pc.in
-index 2ba9c39..f8f8b00 100644
---- a/libcurl.pc.in
-+++ b/libcurl.pc.in
-@@ -29,6 +29,7 @@ libdir=@libdir@
- includedir=@includedir@
- supported_protocols="@SUPPORT_PROTOCOLS@"
- supported_features="@SUPPORT_FEATURES@"
-+configure_options=@CONFIGURE_OPTIONS@
- Name: libcurl
- URL: http://curl.haxx.se/
diff --git a/curl/patches/0101-curl-7.32.0-multilib.patch b/curl/patches/0101-curl-7.32.0-multilib.patch
new file mode 100644 (file)
index 0000000..9e9b56b
--- /dev/null
@@ -0,0 +1,83 @@
+From 2a4754a3a7cf60ecc36d83cbe50b8c337cb87632 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 12 Apr 2013 12:04:05 +0200
+Subject: [PATCH] prevent multilib conflicts on the curl-config script
+
+---
+ curl-config.in     |   21 +++------------------
+ docs/curl-config.1 |    4 +++-
+ libcurl.pc.in      |    1 +
+ 3 files changed, 7 insertions(+), 19 deletions(-)
+
+diff --git a/curl-config.in b/curl-config.in
+index 150004d..95d0759 100644
+--- a/curl-config.in
++++ b/curl-config.in
+@@ -75,7 +75,7 @@ while test $# -gt 0; do
+         ;;
+     --cc)
+-        echo "@CC@"
++        echo "gcc"
+         ;;
+     --prefix)
+@@ -142,29 +142,14 @@ while test $# -gt 0; do
+         ;;
+     --libs)
+-        if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
+-           CURLLIBDIR="-L@libdir@ "
+-        else
+-           CURLLIBDIR=""
+-        fi
+-        if test "X@REQUIRE_LIB_DEPS@" = "Xyes"; then
+-          echo ${CURLLIBDIR}-lcurl @LIBCURL_LIBS@
+-        else
+-          echo ${CURLLIBDIR}-lcurl
+-        fi
++        pkg-config libcurl --libs
+         ;;
+     --static-libs)
+-        if test "X@ENABLE_STATIC@" != "Xno" ; then
+-          echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
+-        else
+-          echo "curl was built with static libraries disabled" >&2
+-          exit 1
+-        fi
+         ;;
+     --configure)
+-        echo @CONFIGURE_OPTIONS@
++        pkg-config libcurl --variable=configure_options | sed 's/^"//;s/"$//'
+         ;;
+     *)
+diff --git a/docs/curl-config.1 b/docs/curl-config.1
+index 14a9d2b..ffcc004 100644
+--- a/docs/curl-config.1
++++ b/docs/curl-config.1
+@@ -65,7 +65,9 @@ be listed using uppercase and are separated by newlines. There may be none,
+ one, or several protocols in the list. (Added in 7.13.0)
+ .IP "--static-libs"
+ Shows the complete set of libs and other linker options you will need in order
+-to link your application with libcurl statically. (Added in 7.17.1)
++to link your application with libcurl statically. Note that Fedora/RHEL libcurl
++packages do not provide any static libraries, thus cannot be linked statically.
++(Added in 7.17.1)
+ .IP "--version"
+ Outputs version information about the installed libcurl.
+ .IP "--vernum"
+diff --git a/libcurl.pc.in b/libcurl.pc.in
+index 2ba9c39..f8f8b00 100644
+--- a/libcurl.pc.in
++++ b/libcurl.pc.in
+@@ -29,6 +29,7 @@ libdir=@libdir@
+ includedir=@includedir@
+ supported_protocols="@SUPPORT_PROTOCOLS@"
+ supported_features="@SUPPORT_FEATURES@"
++configure_options=@CONFIGURE_OPTIONS@
+ Name: libcurl
+ URL: http://curl.haxx.se/
diff --git a/curl/patches/0104-curl-7.19.7-localhost6.patch b/curl/patches/0104-curl-7.19.7-localhost6.patch
new file mode 100644 (file)
index 0000000..4f664d3
--- /dev/null
@@ -0,0 +1,51 @@
+diff --git a/tests/data/test1083 b/tests/data/test1083
+index e441278..b0958b6 100644
+--- a/tests/data/test1083
++++ b/tests/data/test1083
+@@ -33,13 +33,13 @@ ipv6
+ http-ipv6
+ </server>
+  <name>
+-HTTP-IPv6 GET with ip6-localhost --interface
++HTTP-IPv6 GET with localhost6 --interface
+  </name>
+  <command>
+--g "http://%HOST6IP:%HTTP6PORT/1083" --interface ip6-localhost
++-g "http://%HOST6IP:%HTTP6PORT/1083" --interface localhost6
+ </command>
+ <precheck>
+-perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test server host address';} else {exec './server/resolve --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
++perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test server host address';} else {exec './server/resolve --ipv6 localhost6'; print 'Cannot run precheck resolve';}"
+ </precheck>
+ </client>
+diff --git a/tests/data/test241 b/tests/data/test241
+index 46eae1f..4e1632c 100644
+--- a/tests/data/test241
++++ b/tests/data/test241
+@@ -30,13 +30,13 @@ ipv6
+ http-ipv6
+ </server>
+  <name>
+-HTTP-IPv6 GET (using ip6-localhost)
++HTTP-IPv6 GET (using localhost6)
+  </name>
+  <command>
+--g "http://ip6-localhost:%HTTP6PORT/241"
++-g "http://localhost6:%HTTP6PORT/241"
+ </command>
+ <precheck>
+-./server/resolve --ipv6 ip6-localhost
++./server/resolve --ipv6 localhost6
+ </precheck>
+ </client>
+@@ -48,7 +48,7 @@ HTTP-IPv6 GET (using ip6-localhost)
+ </strip>
+ <protocol>
+ GET /241 HTTP/1.1\r
+-Host: ip6-localhost:%HTTP6PORT\r
++Host: localhost6:%HTTP6PORT\r
+ Accept: */*\r
\r
+ </protocol>
index 9021c82ac8f857b0e5a87b0538e3767d320bf6e0..d62843fe147157b22a6510f6b8963af3a2563089 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = cyrus-sasl
-version    = 2.1.25
-release    = 2
+version    = 2.1.26
+release    = 1
 
 groups     = System/Libraries
 url        = http://asg.web.cmu.edu/sasl/sasl-library.html
@@ -22,11 +22,19 @@ source_dl  = ftp://ftp.cyrusimap.org/cyrus-sasl/
 
 build
        requires
+               automake
                db4-devel
                openssl-devel
                pam-devel
        end
 
+       prepare_cmds
+               # for aarch64
+               for i in $(find . -name config.guess -or -name config.sub); do
+                       cp -vf %{datadir}/automake-*/config.{guess,sub} $(dirname ${i})
+               done
+       end
+
        configure_options += \
                --sysconfdir=/etc \
                --with-configdir=%{libdir}/sasl2:/etc/sasl2 \
index 1ef95de305575a0ac98f68ffc7f48d13fe0dc3f5..94d81d445188d72f748a466f08673ad9e2664edd 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = diffutils
 version    = 3.3
-release    = 1
+release    = 2
 
 groups     = Development/Tools
 url        = http://www.gnu.org/software/diffutils/diffutils.html
diff --git a/diffutils/patches/diffutils-format-security.patch b/diffutils/patches/diffutils-format-security.patch
new file mode 100644 (file)
index 0000000..9658644
--- /dev/null
@@ -0,0 +1,17 @@
+diff -up diffutils-3.3/gnulib-tests/test-xvasprintf.c.format-security diffutils-3.3/gnulib-tests/test-xvasprintf.c
+--- diffutils-3.3/gnulib-tests/test-xvasprintf.c.format-security       2013-03-22 04:20:50.000000000 +0000
++++ diffutils-3.3/gnulib-tests/test-xvasprintf.c       2013-12-04 13:43:09.927443499 +0000
+@@ -16,6 +16,13 @@
+ /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
++/* Tell GCC not to warn about the specific edge cases tested here.  */
++#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
++# pragma GCC diagnostic ignored "-Wformat-zero-length"
++# pragma GCC diagnostic ignored "-Wformat-nonliteral"
++# pragma GCC diagnostic ignored "-Wformat-security"
++#endif
++
+ #include <config.h>
+ #include "xvasprintf.h"
index 5520cbb3ee4f88f6a69e2bdb376de0e3bf7d5f8e..0e1b13384044de20f907728c1e155527afb81687 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = fontconfig
-version    = 2.7.1
+version    = 2.11.93
 release    = 1
 
 groups     = System/Graphics
@@ -18,7 +18,7 @@ description
        applications.
 end
 
-source_dl  =
+source_dl  = http://www.freedesktop.org/software/fontconfig/release/
 
 build
        requires
@@ -28,14 +28,31 @@ build
        end
 
        configure_options += \
-               --sysconfdir=/etc \
-               --localstatedir=/var \
                --enable-libxml2 \
                --with-add-fonts=/usr/share/X11/fonts/Type1,/usr/share/X11/fonts/TTF,/usr/local/share/fonts
+
+       test
+               make check
+       end
+
+       install_cmds
+               for i in $(find %{BUILDROOT}%{sysconfdir}/fonts/conf.d -type l); do
+                       ln -svf --relative %{BUILDROOT}$(readlink -m ${i}) ${i}
+               done
+       end
 end
 
 packages
        package %{name}
+               postinst
+                       umask 0022
+
+                       mkdir -p %{localstatedir}/cache/fontconfig
+
+                       if [ -x "%{bindir}/fc-cache" ]; then
+                               HOME=/root %{bindir}/fc-cache -f
+                       fi
+               end
        end
 
        package %{name}-devel
index 20222b11c2db2a4a78ac83427758fd67a9297441..6dbed1ae476ea58a1a4273fb19a85c248409e0bf 100644 (file)
--- a/gc/gc.nm
+++ b/gc/gc.nm
@@ -4,12 +4,11 @@
 ###############################################################################
 
 name       = gc
-version    = %{major_ver}d
-major_ver  = 7.2
-release    = 2
+version    = 7.4.2
+release    = 1
 
 groups     = System/Libraries
-url        = http://www.hpl.hp.com/personal/Hans_Boehm/gc/
+url        = http://www.hboehm.info/gc/
 license    = BSD
 summary    = A garbage collector for C and C++.
 
@@ -18,17 +17,16 @@ description
        used as a garbage collecting replacement for C malloc or C++ new.
 end
 
-source_dl  = http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/
+source_dl  = http://www.hboehm.info/gc/gc_source/
 
 build
        requires
                autoconf
                automake
+               libatomic_ops-devel
                libtool
        end
 
-       DIR_APP = %{DIR_SRC}/%{name}-%{major_ver}
-
        # bugzilla.redhat.com/689877
        export CPPFLAGS = -DUSE_GET_STACKBASE_FOR_MAIN
 
@@ -41,8 +39,7 @@ build
                --disable-static \
                --enable-cplusplus \
                --enable-large-config \
-               --enable-threads=posix \
-               --with-libatomic-ops=no
+               --enable-threads=posix
 
        if "%{DISTRO_PLATFORM}" == "x86"
                configure_options += --enable-parallel-mark
@@ -50,7 +47,7 @@ build
 
        test
                # Disabled because gctest hangs forever.
-               #make check
+               make check
        end
 
        install_cmds
index e6f97ec5ab5a5628a827be463e06796e02aa043f..372a69552a5b434e99fde46e049e89fe9aae8560 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = glib2
-ver_major  = 2.39
-ver_minor  = 4
+ver_major  = 2.42
+ver_minor  = 2
 version    = %{ver_major}.%{ver_minor}
 release    = 1
 thisapp    = glib-%{version}
index 33274c141353cd26f0b90b7188f8f45a1e605aee..4b80bbe1fd07556a9192563de86a613ec701e483 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = grubby
 version    = 8.11
-release    = 3
+release    = 4
 
 groups     = System/Base
 url        = http://git.fedorahosted.org/git/grubby.git
@@ -46,7 +46,11 @@ end
 packages
        package %{name}
                # Pull in u-boot-tools on ARM platforms.
-               if "%{DISTRO_PLATFORM}" == "arm"
+               if "%{DISTRO_ARCH}" == "armv7hl"
+                       requires += u-boot-tools
+               end
+
+               if "%{DISTRO_ARCH}" == "armv5tel"
                        requires += u-boot-tools
                end
 
index 8eda32794890dccfe13da57054196afc4cfa26b0..402a1526955b90b9c804a8094ebb8b6ec340dc78 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = iputils
-version    = s20071127
-release    = 4
+version    = s20140519
+release    = 1
 
 groups     = Networking/Tools
 url        = http://www.skbuff.net/iputils
@@ -19,27 +19,14 @@ description
        the target machine is alive and receiving network traffic.
 end
 
-source_dl  = http://www.skbuff.net/iputils/
-sources    = %{thisapp}.tar.bz2
-
-patches    = %{thisapp}-addrcache.patch
-patches   += %{thisapp}-arping-infiniband.patch
-patches   += %{thisapp}-arping_timeout.patch
-patches   += %{thisapp}-countermeasures.patch
-patches   += %{thisapp}-idn.patch
-patches   += %{thisapp}-open-max.patch
-patches   += %{thisapp}-ping-subint.patch
-patches   += %{thisapp}-ping_cleanup.patch
-patches   += %{thisapp}-rh.patch
-patches   += %{thisapp}-traffic_class.patch
-patches   += %{thisapp}-warnings.patch
-patches   += %{thisapp}-output.patch
+source_dl  = https://github.com/iputils/iputils/archive/%{version}.tar.gz#/
 
 build
        requires
                docbook-utils
                libcap-devel
                libidn-devel
+               openssl-devel
        end
 
        # Generate manpages with docbook.
@@ -55,7 +42,6 @@ build
                install -cp arping           %{BUILDROOT}%{sbindir}
                install -cp ping             %{BUILDROOT}%{bindir}
                install -cp ping6            %{BUILDROOT}%{bindir}
-               install -cp rdisc            %{BUILDROOT}%{sbindir}
                install -cp tracepath        %{BUILDROOT}%{bindir}
                install -cp tracepath6       %{BUILDROOT}%{bindir}
 
@@ -85,7 +71,6 @@ packages
                        /bin/ping
                        /bin/ping6
                        /sbin/arping
-                       /sbin/rdisc
                end
        end
 
diff --git a/iputils/patches/iputils-ipfire.patch b/iputils/patches/iputils-ipfire.patch
new file mode 100644 (file)
index 0000000..7c0b0d1
--- /dev/null
@@ -0,0 +1,37 @@
+--- iputils-s20140519-dist/Makefile    2014-05-19 23:35:28.000000000 +0200
++++ iputils-s20140519-new/Makefile     2014-05-20 10:51:07.388527442 +0200
+@@ -26,7 +26,7 @@ USE_CAP=yes
+ # sysfs support (with libsysfs - deprecated) [no|yes|static]
+ USE_SYSFS=no
+ # IDN support (experimental) [no|yes|static]
+-USE_IDN=no
++USE_IDN=yes
+ # Do not use getifaddrs [no|yes|static]
+ WITHOUT_IFADDRS=no
+@@ -34,7 +34,7 @@ WITHOUT_IFADDRS=no
+ ARPING_DEFAULT_DEVICE=
+ # GNU TLS library for ping6 [yes|no|static]
+-USE_GNUTLS=yes
++USE_GNUTLS=no
+ # Crypto library for ping6 [shared|static|no]
+ USE_CRYPTO=shared
+ # Resolv library for ping6 [yes|static]
+@@ -49,7 +49,7 @@ ENABLE_RDISC_SERVER=no
+ # What a pity, all new gccs are buggy and -Werror does not work. Sigh.
+ # CFLAGS+=-fno-strict-aliasing -Wstrict-prototypes -Wall -Werror -g
+ CFLAGS?=-O3 -g
+-CFLAGS+=-fno-strict-aliasing -Wstrict-prototypes -Wall
++CFLAGS+=$(RPM_OPT_FLAGS) -fno-strict-aliasing -Wstrict-prototypes -Wall -Werror
+ CPPFLAGS+=-D_GNU_SOURCE
+ LDLIB=
+@@ -188,6 +188,7 @@ tftpd.o tftpsubs.o: tftp.h
+ # -------------------------------------
+ # ninfod
++ninfod: CFLAGS:=$(filter-out -Werror,$(CFLAGS))
+ ninfod:
+       @set -e; \
+               if [ ! -f ninfod/Makefile ]; then \
diff --git a/iputils/patches/iputils-s20071127-addrcache.patch b/iputils/patches/iputils-s20071127-addrcache.patch
deleted file mode 100644 (file)
index 188dbca..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
---- iputils/ping.c.addrcache   2002-09-20 17:08:11.000000000 +0200
-+++ iputils/ping.c     2003-05-15 16:41:19.000000000 +0200
-@@ -1124,6 +1124,12 @@
- {
-       struct hostent *hp;
-       static char buf[4096];
-+      static __u32 addr_cache = 0;
-+
-+      if ( addr == addr_cache )
-+              return buf;
-+
-+      addr_cache = addr;
-       if ((options & F_NUMERIC) ||
-           !(hp = gethostbyaddr((char *)&addr, 4, AF_INET)))
---- iputils/ping6.c.addrcache  2002-09-20 17:08:11.000000000 +0200
-+++ iputils/ping6.c    2003-05-15 16:41:19.000000000 +0200
-@@ -893,7 +893,12 @@
-  */
- char * pr_addr(struct in6_addr *addr)
- {
--      struct hostent *hp = NULL;
-+      static struct hostent *hp;
-+      static struct in6_addr addr_cache;
-+
-+      if (memcmp(addr, &addr_cache, sizeof(addr_cache)) == 0)
-+              return hp ? hp->h_name : pr_addr_n(addr);
-+      memcpy(&addr_cache, addr, sizeof(addr_cache));
-       if (!(options&F_NUMERIC))
-               hp = gethostbyaddr((__u8*)addr, sizeof(struct in6_addr), AF_INET6);
diff --git a/iputils/patches/iputils-s20071127-arping-infiniband.patch b/iputils/patches/iputils-s20071127-arping-infiniband.patch
deleted file mode 100644 (file)
index 9884b70..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-diff -up iputils-s20071127/arping.c.infiniband iputils-s20071127/arping.c
---- iputils-s20071127/arping.c.infiniband      2007-11-27 01:57:27.000000000 +0100
-+++ iputils-s20071127/arping.c 2008-08-08 10:05:04.000000000 +0200
-@@ -50,14 +50,26 @@ int unicasting;
- int s;
- int broadcast_only;
--struct sockaddr_ll me;
--struct sockaddr_ll he;
-+/*
-+ * Make these two structs have padding at the end so the overly long Infiniband
-+ * hardware addresses can have the remainder of their address tacked onto
-+ * the end of the struct without overlapping anything.
-+ */
-+struct sockaddr_ll me[2];
-+struct sockaddr_ll he[2];
- struct timeval start, last;
- int sent, brd_sent;
- int received, brd_recv, req_recv;
-+#define SYSFS_MNT_PATH          "/sys"
-+#define SYSFS_CLASS             "class"
-+#define SYSFS_NET               "net"
-+#define SYSFS_BROADCAST         "broadcast"
-+#define SYSFS_PATH_ENV          "SYSFS_PATH"
-+#define SYSFS_PATH_LEN          256
-+
- #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \
-                          ((tv1).tv_usec-(tv2).tv_usec)/1000 )
-@@ -124,7 +136,8 @@ int send_pack(int s, struct in_addr src,
-       p+=4;
-       gettimeofday(&now, NULL);
--      err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, sizeof(*HE));
-+      err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, (ah->ar_hln > 8) ?
-+                   sizeof(*HE) + ah->ar_hln - 8 : sizeof(*HE));
-       if (err == p-buf) {
-               last = now;
-               sent++;
-@@ -172,7 +185,7 @@ void catcher(void)
-               finish();
-       if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) {
--              send_pack(s, src, dst, &me, &he);
-+              send_pack(s, src, dst, &me[0], &he[0]);
-               if (count == 0 && unsolicited)
-                       finish();
-       }
-@@ -219,7 +232,7 @@ int recv_pack(unsigned char *buf, int le
-               return 0;
-       if (ah->ar_pln != 4)
-               return 0;
--      if (ah->ar_hln != me.sll_halen)
-+      if (ah->ar_hln != me[0].sll_halen)
-               return 0;
-       if (len < sizeof(*ah) + 2*(4 + ah->ar_hln))
-               return 0;
-@@ -230,7 +243,7 @@ int recv_pack(unsigned char *buf, int le
-                       return 0;
-               if (src.s_addr != dst_ip.s_addr)
-                       return 0;
--              if (memcmp(p+ah->ar_hln+4, &me.sll_addr, ah->ar_hln))
-+              if (memcmp(p+ah->ar_hln+4, &me[0].sll_addr, ah->ar_hln))
-                       return 0;
-       } else {
-               /* DAD packet was:
-@@ -248,7 +261,7 @@ int recv_pack(unsigned char *buf, int le
-                */
-               if (src_ip.s_addr != dst.s_addr)
-                       return 0;
--              if (memcmp(p, &me.sll_addr, me.sll_halen) == 0)
-+              if (memcmp(p, &me[0].sll_addr, me[0].sll_halen) == 0)
-                       return 0;
-               if (src.s_addr && src.s_addr != dst_ip.s_addr)
-                       return 0;
-@@ -264,7 +277,7 @@ int recv_pack(unsigned char *buf, int le
-                       printf("for %s ", inet_ntoa(dst_ip));
-                       s_printed = 1;
-               }
--              if (memcmp(p+ah->ar_hln+4, me.sll_addr, ah->ar_hln)) {
-+              if (memcmp(p+ah->ar_hln+4, me[0].sll_addr, ah->ar_hln)) {
-                       if (!s_printed)
-                               printf("for ");
-                       printf("[");
-@@ -290,12 +303,69 @@ int recv_pack(unsigned char *buf, int le
-       if (quit_on_reply)
-               finish();
-       if(!broadcast_only) {
--              memcpy(he.sll_addr, p, me.sll_halen);
-+              memcpy(he[0].sll_addr, p, me[0].sll_halen);
-               unicasting=1;
-       }
-       return 1;
- }
-+int get_sysfs_mnt_path(char *mnt_path, size_t len)
-+{
-+        const char *sysfs_path_env;
-+        int pth_len=0;
-+
-+        if (len == 0 || mnt_path == NULL)
-+                return -1;
-+
-+        /* possible overrride of real mount path */
-+        sysfs_path_env = getenv(SYSFS_PATH_ENV);
-+        memset(mnt_path, 0, len);
-+        strncpy(mnt_path,
-+                sysfs_path_env != NULL ? sysfs_path_env : SYSFS_MNT_PATH,
-+                len-1);
-+
-+        if ((pth_len = strlen(mnt_path)) > 0 && mnt_path[pth_len-1] == '/')
-+                mnt_path[pth_len-1] = '\0';
-+
-+        return 0;
-+}
-+
-+int make_sysfs_broadcast_path(char *broadcast_path, size_t len)
-+{
-+        char mnt_path[SYSFS_PATH_LEN];
-+
-+        if (get_sysfs_mnt_path(mnt_path, len) != 0)
-+                return -1;
-+
-+        snprintf(broadcast_path, len,
-+                "%s/" SYSFS_CLASS "/" SYSFS_NET "/%s/" SYSFS_BROADCAST,
-+                mnt_path, device);
-+
-+        return 0;
-+}
-+
-+char * read_sysfs_broadcast(char *brdcast_path)
-+{
-+        int fd;
-+        int len_to_read;
-+        char *brdcast = NULL;
-+
-+        if ((fd = open(brdcast_path, O_RDONLY)) > -1) {
-+                len_to_read = lseek(fd, 0L, SEEK_END);
-+                if ((brdcast = malloc(len_to_read+1)) != NULL) {
-+                        lseek(fd, 0L, SEEK_SET);
-+                        memset(brdcast, 0, len_to_read+1);
-+                        if (read(fd, brdcast, len_to_read) == -1) {
-+                                free(brdcast);
-+                                brdcast = NULL;
-+                        }
-+                }
-+                close(fd);
-+        }
-+
-+        return brdcast;
-+}
-+
- int
- main(int argc, char **argv)
- {
-@@ -459,9 +529,9 @@ main(int argc, char **argv)
-               close(probe_fd);
-       };
--      me.sll_family = AF_PACKET;
--      me.sll_ifindex = ifindex;
--      me.sll_protocol = htons(ETH_P_ARP);
-+      me[0].sll_family = AF_PACKET;
-+      me[0].sll_ifindex = ifindex;
-+      me[0].sll_protocol = htons(ETH_P_ARP);
-       if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) {
-               perror("bind");
-               exit(2);
-@@ -474,14 +544,33 @@ main(int argc, char **argv)
-                       exit(2);
-               }
-       }
--      if (me.sll_halen == 0) {
-+      if (me[0].sll_halen == 0) {
-               if (!quiet)
-                       printf("Interface \"%s\" is not ARPable (no ll address)\n", device);
-               exit(dad?0:2);
-       }
-+      he[0] = me[0];
-+      he[1] = me[1];
-+      {
-+                char brdcast_path[SYSFS_PATH_LEN];
-+                char *brdcast_val;
-+                char *next_ch;
-+
-+                if (make_sysfs_broadcast_path(brdcast_path, sizeof brdcast_path) != 0) {
-+                        perror("sysfs attribute broadcast");
-+                        exit(2);
-+                }
-+
-+                if ((brdcast_val = read_sysfs_broadcast(brdcast_path)) == NULL) {
-+                        perror("sysfs read broadcast value");
-+                        exit(2);
-+                }
-+                for (ch=0; ch<he[0].sll_halen; ch++) {
-+                        he[0].sll_addr[ch] = strtol(brdcast_val + (ch*3), &next_ch, 16);
-+                }
--      he = me;
--      memset(he.sll_addr, -1, he.sll_halen);
-+                free(brdcast_val);
-+      }
-       if (!quiet) {
-               printf("ARPING %s ", inet_ntoa(dst));
-@@ -501,12 +590,12 @@ main(int argc, char **argv)
-       while(1) {
-               sigset_t sset, osset;
-               unsigned char packet[4096];
--              struct sockaddr_ll from;
-+              struct sockaddr_ll from[2];
-               socklen_t alen = sizeof(from);
-               int cc;
-               if ((cc = recvfrom(s, packet, sizeof(packet), 0,
--                                 (struct sockaddr *)&from, &alen)) < 0) {
-+                                 (struct sockaddr *)&from[0], &alen)) < 0) {
-                       perror("arping: recvfrom");
-                       continue;
-               }
-@@ -514,7 +603,7 @@ main(int argc, char **argv)
-               sigaddset(&sset, SIGALRM);
-               sigaddset(&sset, SIGINT);
-               sigprocmask(SIG_BLOCK, &sset, &osset);
--              recv_pack(packet, cc, &from);
-+              recv_pack(packet, cc, &from[0]);
-               sigprocmask(SIG_SETMASK, &osset, NULL);
-       }
- }
-diff -up iputils-s20071127/Makefile.infiniband iputils-s20071127/Makefile
---- iputils-s20071127/Makefile.infiniband      2008-08-08 09:17:35.000000000 +0200
-+++ iputils-s20071127/Makefile 2008-08-08 10:02:10.000000000 +0200
-@@ -37,6 +37,8 @@ rdisc_srv: rdisc_srv.o
- rdisc_srv.o: rdisc.c
-       $(CC) $(CFLAGS) -DRDISC_SERVER -o rdisc_srv.o rdisc.c
-+arping: arping.o
-+      $(CC) $(LDFLAGS) arping.o $(LOADLIBES) $(LDLIBS) -o arping
- check-kernel:
- ifeq ($(KERNEL_INCLUDE),)
diff --git a/iputils/patches/iputils-s20071127-arping_timeout.patch b/iputils/patches/iputils-s20071127-arping_timeout.patch
deleted file mode 100644 (file)
index 656ec0b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-diff -up iputils-s20070202/arping.c.arping_timeout iputils-s20070202/arping.c
---- iputils-s20070202/arping.c.arping_timeout  2008-02-18 16:51:36.000000000 +0100
-+++ iputils-s20070202/arping.c 2008-02-18 16:54:03.000000000 +0100
-@@ -45,7 +45,8 @@ struct in_addr src, dst;
- char *target;
- int dad, unsolicited, advert;
- int quiet;
--int count=-1;
-+int count;
-+int forever = 1;
- int timeout;
- int unicasting;
- int s;
-@@ -59,7 +60,7 @@ int broadcast_only;
- struct sockaddr_ll me[2];
- struct sockaddr_ll he[2];
--struct timeval start, last;
-+struct timeval last;
- int sent, brd_sent;
- int received, brd_recv, req_recv;
-@@ -172,13 +173,15 @@ void catcher(void)
-       gettimeofday(&tv, NULL);
--      if (start.tv_sec==0)
--              start = tv;
--
--      if (count-- == 0 || (timeout && MS_TDIFF(tv,start) > timeout*1000 + 500))
--              finish();
-+      if (!forever && count == 0) {
-+              if (timeout && MS_TDIFF(tv, last) > timeout * 1000 + 500)
-+                      finish();
-+              else if (!timeout)
-+                      finish();
-+      }
--      if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) {
-+      if ((count > 0 || forever) && (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500)) {
-+              count--;
-               send_pack(s, src, dst, &me[0], &he[0]);
-               if (count == 0 && unsolicited)
-                       finish();
-@@ -339,6 +342,10 @@ main(int argc, char **argv)
-                       break;
-               case 'c':
-                       count = atoi(optarg);
-+                      if (count > 0)
-+                              forever = 0;
-+                      else
-+                              forever = 1;
-                       break;
-               case 'w':
-                       timeout = atoi(optarg);
-@@ -544,7 +551,8 @@ main(int argc, char **argv)
-               sigaddset(&sset, SIGALRM);
-               sigaddset(&sset, SIGINT);
-               sigprocmask(SIG_BLOCK, &sset, &osset);
--              recv_pack(packet, cc, &from[0]);
-+              if (recv_pack(packet, cc, from) && count == 0 && !forever)
-+                      finish();
-               sigprocmask(SIG_SETMASK, &osset, NULL);
-       }
- }
diff --git a/iputils/patches/iputils-s20071127-countermeasures.patch b/iputils/patches/iputils-s20071127-countermeasures.patch
deleted file mode 100644 (file)
index 5e6f4bc..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- iputils/ping_common.c.countermeasures      Tue May 21 10:06:05 2002
-+++ iputils/ping_common.c      Tue May 21 10:12:42 2002
-@@ -628,7 +628,8 @@
-               tvsub(tv, &tmp_tv);
-               triptime = tv->tv_sec * 1000000 + tv->tv_usec;
-               if (triptime < 0) {
--                      fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime);
-+                      if (options & F_VERBOSE)
-+                              fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime);
-                       triptime = 0;
-                       if (!(options & F_LATENCY)) {
-                               gettimeofday(tv, NULL);
diff --git a/iputils/patches/iputils-s20071127-idn.patch b/iputils/patches/iputils-s20071127-idn.patch
deleted file mode 100644 (file)
index b575006..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
---- iputils-s20070202/ping.c.idn       2007-08-06 14:45:36.000000000 +0200
-+++ iputils-s20070202/ping.c   2007-08-06 14:45:36.000000000 +0200
-@@ -58,6 +58,9 @@
-  *    This program has to run SUID to ROOT to access the ICMP socket.
-  */
-+#include <idna.h>
-+#include <locale.h>
-+
- #include "ping_common.h"
- #include <netinet/ip.h>
-@@ -122,6 +128,10 @@
-       char *target, hnamebuf[MAXHOSTNAMELEN];
-       char rspace[3 + 4 * NROUTES + 1];       /* record route space */
-+      char *idn;
-+      int rc = 0;
-+      setlocale(LC_ALL, "");
-+
-       icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
-       socket_errno = errno;
-@@ -242,13 +254,27 @@
-                       if (argc == 1)
-                               options |= F_NUMERIC;
-               } else {
-+                      rc = idna_to_ascii_lz (target, &idn, 0);
-+                      if (rc == IDNA_SUCCESS)
-+                              hp = gethostbyname (idn);
-+                      else {
-+                              fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", target, rc);
-+                              exit(2);
-+                      }
-+                      free(idn);
--                      hp = gethostbyname(target);
-                       if (!hp) {
-                               fprintf(stderr, "ping: unknown host %s\n", target);
-                               exit(2);
-                       }
-                       memcpy(&whereto.sin_addr, hp->h_addr, 4);
-+                      rc = idna_to_unicode_lzlz (hp->h_name, &idn, 0);
-+                      if (rc == IDNA_SUCCESS)
-+                              strncpy(hnamebuf, idn, sizeof(hnamebuf) - 1);
-+                      else {
-+                              fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", hp->h_name, rc);
-+                              exit(2);
-+                      }
-+                      free(idn);
--                      strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
-                       hnamebuf[sizeof(hnamebuf) - 1] = 0;
-                       hostname = hnamebuf;
-               }
---- iputils-s20070202/Makefile.idn     2007-08-06 14:45:36.000000000 +0200
-+++ iputils-s20070202/Makefile 2007-08-06 14:45:36.000000000 +0200
-@@ -27,8 +27,13 @@
- tftpd: tftpd.o tftpsubs.o
-+
- ping: ping.o ping_common.o
-+      $(CC) $(CFLAGS) ping.o ping_common.o -lidn -o ping
-+
- ping6: ping6.o ping_common.o
-+      $(CC) $(CFLAGS) ping6.o ping_common.o -o ping6
-+
- ping.o ping6.o ping_common.o: ping_common.h
- tftpd.o tftpsubs.o: tftp.h
---- iputils-s20070202/ping6.c.idn      2007-08-06 14:45:36.000000000 +0200
-+++ iputils-s20070202/ping6.c  2007-08-06 14:45:36.000000000 +0200
-@@ -66,6 +66,9 @@
-  *    More statistics could always be gathered.
-  *    This program has to run SUID to ROOT to access the ICMP socket.
-  */
-+#define _GNU_SOURCE
-+#include <locale.h>
-+
- #include "ping_common.h"
- #include <linux/filter.h>
-@@ -210,6 +216,8 @@
-       int err, csum_offset, sz_opt;
-       static uint32_t scope_id = 0;
-+      setlocale(LC_ALL, "");
-+
-       icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-       socket_errno = errno;
-@@ -296,6 +306,7 @@
-               memset(&hints, 0, sizeof(hints));
-               hints.ai_family = AF_INET6;
-+              hints.ai_flags = AI_IDN;
-               gai = getaddrinfo(target, NULL, &hints, &ai);
-               if (gai) {
-                       fprintf(stderr, "unknown host\n");
-@@ -328,6 +341,7 @@
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = AF_INET6;
-+      hints.ai_flags = AI_IDN;
-       gai = getaddrinfo(target, NULL, &hints, &ai);
-       if (gai) {
-               fprintf(stderr, "unknown host\n");
---- iputils-s20070202/ping_common.c.idn        2007-08-06 14:45:36.000000000 +0200
-+++ iputils-s20070202/ping_common.c    2007-08-06 14:47:41.000000000 +0200
-@@ -1,3 +1,5 @@
-+#include <locale.h>
-+
- #include "ping_common.h"
- #include <ctype.h>
- #include <sched.h>
-@@ -97,6 +102,7 @@
- void common_options(int ch)
- {
-+      setlocale(LC_ALL, "C");
-       switch(ch) {
-       case 'a':
-               options |= F_AUDIBLE;
-@@ -222,6 +230,7 @@
-       default:
-               abort();
-       }
-+      setlocale(LC_ALL, "");
- }
diff --git a/iputils/patches/iputils-s20071127-open-max.patch b/iputils/patches/iputils-s20071127-open-max.patch
deleted file mode 100644 (file)
index d8ce652..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-diff -up iputils-s20071127/rdisc.c.open_max iputils-s20071127/rdisc.c
---- iputils-s20071127/rdisc.c.open_max 2008-02-25 11:15:37.000000000 +0100
-+++ iputils-s20071127/rdisc.c  2008-02-25 11:17:30.000000000 +0100
-@@ -240,14 +240,25 @@ void do_fork(void)
- {
-       int t;
-       pid_t pid;
-+      long open_max;
-       if (trace)
-               return;
-+      if ((open_max = sysconf(_SC_OPEN_MAX)) == -1) {
-+              if (errno == 0) {
-+                      (void) fprintf(stderr, "OPEN_MAX is not supported\n");
-+              } 
-+              else {
-+                      (void) fprintf(stderr, "sysconf() error\n");
-+              }
-+              exit(1);
-+      }
-+
-       if ((pid=fork()) != 0)
-               exit(0);
--      for (t = 0; t < OPEN_MAX; t++)
-+      for (t = 0; t < open_max; t++)
-               if (t != s)
-                       close(t);
diff --git a/iputils/patches/iputils-s20071127-output.patch b/iputils/patches/iputils-s20071127-output.patch
deleted file mode 100644 (file)
index 365169b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-diff -up iputils-s20071127/ping_common.c.output iputils-s20071127/ping_common.c
---- iputils-s20071127/ping_common.c.output     2008-02-26 14:12:02.000000000 +0100
-+++ iputils-s20071127/ping_common.c    2008-02-26 14:24:34.000000000 +0100
-@@ -791,8 +791,10 @@ static long llsqrt(long long a)
-  */
- void finish(void)
- {
--      struct timeval tv = cur_time;
-+      struct timeval tv;
-+      char *comma = "";
-+      gettimeofday(&tv, NULL);
-       tvsub(&tv, &start_time);
-       putchar('\n');
-@@ -827,12 +829,15 @@ void finish(void)
-                      (long)tmax/1000, (long)tmax%1000,
-                      (long)tmdev/1000, (long)tmdev%1000
-                      );
-+              comma = ", ";
-+      }
-+      if (pipesize > 1) {
-+              printf("%spipe %d", comma, pipesize);
-+              comma = ", ";
-       }
--      if (pipesize > 1)
--              printf(", pipe %d", pipesize);
-       if (ntransmitted > 1 && nreceived && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) {
-               int ipg = (1000000*(long long)tv.tv_sec+tv.tv_usec)/(ntransmitted-1);
--              printf(", ipg/ewma %d.%03d/%d.%03d ms",
-+              printf("%sipg/ewma %d.%03d/%d.%03d ms", comma,
-                      ipg/1000, ipg%1000, rtt/8000, (rtt/8)%1000);
-       }
-       putchar('\n');
diff --git a/iputils/patches/iputils-s20071127-ping-subint.patch b/iputils/patches/iputils-s20071127-ping-subint.patch
deleted file mode 100644 (file)
index e19e724..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- iputils-ss021109-vanilla/ping.c    Thu Nov  7 23:53:21 2002
-+++ iputils/ping.c     Sun Jan 12 03:39:24 2003
-@@ -285,6 +285,9 @@
-                                               perror("ping: IP_MULTICAST_IF");
-                                               exit(2);
-                                       }
-+                              } else if (icmp_sock >= 0) {
-+                                      /* We possible tried to SO_BINDTODEVICE() a subinterface like 'eth0:1' */
-+                                      perror("Warning: cannot bind to specified iface, falling back");
-                               }
-                       }
-               }
diff --git a/iputils/patches/iputils-s20071127-ping_cleanup.patch b/iputils/patches/iputils-s20071127-ping_cleanup.patch
deleted file mode 100644 (file)
index 071ab82..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
---- iputils/ping.c.OLD 2006-02-06 10:34:35.000000000 +0100
-+++ iputils/ping.c     2006-02-06 10:34:35.000000000 +0100
-@@ -855,9 +855,36 @@
-               case ICMP_SR_FAILED:
-                       printf("Source Route Failed\n");
-                       break;
-+              case ICMP_NET_UNKNOWN:
-+                      printf("Destination Net Unknown\n");
-+                      break;
-+              case ICMP_HOST_UNKNOWN:
-+                      printf("Destination Host Unknown\n");
-+                      break;
-+              case ICMP_HOST_ISOLATED:
-+                      printf("Source Host Isolated\n");
-+                      break;
-+              case ICMP_NET_ANO:
-+                      printf("Destination Net Prohibited\n");
-+                      break;
-+              case ICMP_HOST_ANO:
-+                      printf("Destination Host Prohibited\n");
-+                      break;
-+              case ICMP_NET_UNR_TOS:
-+                      printf("Destination Net Unreachable for Type of Service\n");
-+                      break;
-+              case ICMP_HOST_UNR_TOS:
-+                      printf("Destination Host Unreachable for Type of Service\n");
-+                      break;
-               case ICMP_PKT_FILTERED:
-                       printf("Packet filtered\n");
-                       break;
-+              case ICMP_PREC_VIOLATION:
-+                      printf("Precedence Violation\n");
-+                      break;
-+              case ICMP_PREC_CUTOFF:
-+                      printf("Precedence Cutoff\n");
-+                      break;
-               default:
-                       printf("Dest Unreachable, Bad Code: %d\n", code);
-                       break;
---- iputils/ping_common.c.OLD  2006-02-06 10:34:35.000000000 +0100
-+++ iputils/ping_common.c      2006-02-06 10:34:35.000000000 +0100
-@@ -819,7 +819,7 @@
-       }
-       if (pipesize > 1)
-               printf(", pipe %d", pipesize);
--      if (ntransmitted > 1 && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) {
-+      if (ntransmitted > 1 && nreceived && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) {
-               int ipg = (1000000*(long long)tv.tv_sec+tv.tv_usec)/(ntransmitted-1);
-               printf(", ipg/ewma %d.%03d/%d.%03d ms",
-                      ipg/1000, ipg%1000, rtt/8000, (rtt/8)%1000);
diff --git a/iputils/patches/iputils-s20071127-rh.patch b/iputils/patches/iputils-s20071127-rh.patch
deleted file mode 100644 (file)
index 16d4745..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- iputils/Makefile.rh7       2002-09-20 20:23:55.000000000 +0200
-+++ iputils/Makefile   2004-05-12 15:08:25.638310270 +0200
-@@ -24,8 +24,8 @@
- CC=gcc
- # What a pity, all new gccs are buggy and -Werror does not work. Sigh.
- #CCOPT=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g -Werror
--CCOPT=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g
--CFLAGS=$(CCOPT) $(GLIBCFIX) $(DEFINES) 
-+CCOPT?=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g
-+CFLAGS?=$(CCOPT) $(GLIBCFIX) $(DEFINES) 
- IPV4_TARGETS=tracepath ping clockdiff rdisc arping tftpd rarpd
- IPV6_TARGETS=tracepath6 traceroute6 ping6
diff --git a/iputils/patches/iputils-s20071127-traffic_class.patch b/iputils/patches/iputils-s20071127-traffic_class.patch
deleted file mode 100644 (file)
index 8a4ddf0..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -up iputils-s20070202/ping6.c.flowlabel iputils-s20070202/ping6.c
---- iputils-s20070202/ping6.c.flowlabel        2008-02-01 11:10:53.000000000 +0100
-+++ iputils-s20070202/ping6.c  2008-02-01 11:16:47.000000000 +0100
-@@ -86,6 +86,10 @@ char copyright[] =
- #define SOL_ICMPV6 IPPROTO_ICMPV6
- #endif
-+#ifndef IVP6_FLOWINFO_SEND
-+#define IPV6_FLOWINFO_SEND    33
-+#endif
-+
- /* RFC3542 */
- #ifndef ICMP6_DST_UNREACH_BEYONDSCOPE
- #define ICMP6_DST_UNREACH_BEYONDSCOPE ICMP6_DST_UNREACH_NOTNEIGHBOR
diff --git a/iputils/patches/iputils-s20071127-warnings.patch b/iputils/patches/iputils-s20071127-warnings.patch
deleted file mode 100644 (file)
index a2d0a83..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-diff -up iputils-s20071127/ping_common.c.warnings iputils-s20071127/ping_common.c
---- iputils-s20071127/ping_common.c.warnings   2008-06-02 13:29:27.000000000 +0200
-+++ iputils-s20071127/ping_common.c    2008-06-02 13:29:27.000000000 +0200
-@@ -338,7 +338,7 @@ resend:
-                        * high preload or pipe size is very confusing. */
-                       if ((preload < screen_width && pipesize < screen_width) ||
-                           in_flight() < screen_width)
--                              write(STDOUT_FILENO, ".", 1);
-+                              printf(".");
-               }
-               return interval - tokens;
-       }
-@@ -391,7 +391,7 @@ resend:
-       if (i == 0 && !(options & F_QUIET)) {
-               if (options & F_FLOOD)
--                      write(STDOUT_FILENO, "E", 1);
-+                      printf("E");
-               else
-                       perror("ping: sendmsg");
-       }
-@@ -717,9 +717,9 @@ restamp:
-       if (options & F_FLOOD) {
-               if (!csfailed)
--                      write(STDOUT_FILENO, "\b \b", 3);
-+                      printf("\b \b");
-               else
--                      write(STDOUT_FILENO, "\bC", 1);
-+                      printf("\bC");
-       } else {
-               int i;
-               __u8 *cp, *dp;
-diff -up iputils-s20071127/clockdiff.c.warnings iputils-s20071127/clockdiff.c
---- iputils-s20071127/clockdiff.c.warnings     2007-11-27 01:57:27.000000000 +0100
-+++ iputils-s20071127/clockdiff.c      2008-06-02 13:29:27.000000000 +0200
-@@ -628,8 +628,6 @@ main(int argc, char *argv[])
-               }
-       }
--      nice(-16);
--
-       if ((measure_status = (ip_opt_len ? measure_opt : measure)(&server)) < 0) {
-               if (errno)
-                       perror("measure");
-diff -up iputils-s20071127/ping6.c.warnings iputils-s20071127/ping6.c
---- iputils-s20071127/ping6.c.warnings 2008-06-02 13:30:06.000000000 +0200
-+++ iputils-s20071127/ping6.c  2008-06-02 13:31:14.000000000 +0200
-@@ -667,7 +667,7 @@ int receive_error_msg()
-               if (options & F_QUIET)
-                       goto out;
-               if (options & F_FLOOD)
--                      write(STDOUT_FILENO, "E", 1);
-+                      printf("E");
-               else if (e->ee_errno != EMSGSIZE)
-                       fprintf(stderr, "ping: local error: %s\n", strerror(e->ee_errno));
-               else
-@@ -690,7 +690,7 @@ int receive_error_msg()
-               if (options & F_QUIET)
-                       goto out;
-               if (options & F_FLOOD) {
--                      write(STDOUT_FILENO, "\bE", 2);
-+                      printf("\bE");
-               } else {
-                       printf("From %s icmp_seq=%u ", pr_addr(&sin6->sin6_addr), ntohs(icmph.icmp6_seq));
-                       pr_icmph(e->ee_type, e->ee_code, e->ee_info);
-@@ -838,7 +838,7 @@ parse_reply(struct msghdr *msg, int cc, 
-                               return 0;
-                       nerrors++;
-                       if (options & F_FLOOD) {
--                              write(STDOUT_FILENO, "\bE", 2);
-+                              printf("\bE");
-                               return 0;
-                       }
-                       printf("From %s: icmp_seq=%u ", pr_addr(&from->sin6_addr), ntohs(icmph1->icmp6_seq));
-diff -up iputils-s20071127/ping.c.warnings iputils-s20071127/ping.c
---- iputils-s20071127/ping.c.warnings  2008-06-02 13:29:27.000000000 +0200
-+++ iputils-s20071127/ping.c   2008-06-02 13:29:27.000000000 +0200
-@@ -367,7 +367,7 @@ main(int argc, char **argv)
-               }
-               source.sin_port = 0;
-               close(probe_fd);
--      } while (0);
-+      }
-       if (whereto.sin_addr.s_addr == 0)
-               whereto.sin_addr.s_addr = source.sin_addr.s_addr;
-@@ -594,7 +594,7 @@ int receive_error_msg()
-               if (options & F_QUIET)
-                       goto out;
-               if (options & F_FLOOD)
--                      write(STDOUT_FILENO, "E", 1);
-+                      printf("E");
-               else if (e->ee_errno != EMSGSIZE)
-                       fprintf(stderr, "ping: local error: %s\n", strerror(e->ee_errno));
-               else
-@@ -630,7 +630,7 @@ int receive_error_msg()
-               if (options & F_QUIET)
-                       goto out;
-               if (options & F_FLOOD) {
--                      write(STDOUT_FILENO, "\bE", 2);
-+                      printf("\bE");
-               } else {
-                       printf("From %s icmp_seq=%u ", pr_addr(sin->sin_addr.s_addr), ntohs(icmph.un.echo.sequence));
-                       pr_icmph(e->ee_type, e->ee_code, e->ee_info, NULL);
-@@ -795,7 +795,7 @@ parse_reply(struct msghdr *msg, int cc, 
-                                       return !error_pkt;
-                               if (options & F_FLOOD) {
-                                       if (error_pkt)
--                                              write(STDOUT_FILENO, "\bE", 2);
-+                                              printf("\bE");
-                                       return !error_pkt;
-                               }
-                               printf("From %s: icmp_seq=%u ",
-@@ -812,9 +812,9 @@ parse_reply(struct msghdr *msg, int cc, 
-               }
-               if ((options & F_FLOOD) && !(options & (F_VERBOSE|F_QUIET))) {
-                       if (!csfailed)
--                              write(STDOUT_FILENO, "!E", 2);
-+                              printf("!E");
-                       else
--                              write(STDOUT_FILENO, "!EC", 3);
-+                              printf("!EC");
-                       return 0;
-               }
-               if (!(options & F_VERBOSE) || uid)
diff --git a/iputils/patches/iputils-tracepath-doc.patch b/iputils/patches/iputils-tracepath-doc.patch
new file mode 100644 (file)
index 0000000..abfbabd
--- /dev/null
@@ -0,0 +1,19 @@
+commit 51aad205e5e8289b52241cd41b15e0f116c4442a
+Author: Jan Synacek <jsynacek@redhat.com>
+Date:   Tue May 20 11:17:00 2014 +0200
+
+    tracepath,doc: fix corrupted tag
+
+diff --git a/doc/tracepath.sgml b/doc/tracepath.sgml
+index 8048c80..756572f 100644
+--- a/doc/tracepath.sgml
++++ b/doc/tracepath.sgml
+@@ -69,7 +69,7 @@ Sets the initial packet length to <replaceable/pktlen/ instead of
+  </varlistentry>
+  <varlistentry>
+-  <term><option/-m</term>
++  <term><option>-m</option></term>
+   <listitem><para>
+ Set maximum hops (or maximum TTLs) to <replaceable/max_hops/
+ instead of 30.
index 4f34961440396ef70c873efff858f5163414fba8..54d095a1c49a034c440d11eb9f6ac48f7bc237d1 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = lcms2
-version    = 2.6
+version    = 2.7
 release    = 1
 
 groups     = System/Tools
@@ -22,11 +22,19 @@ source_dl  = http://www.littlecms.com/
 
 build
        requires
+               automake
                libjpeg-devel
                libtiff-devel
                zlib-devel
        end
 
+       prepare_cmds
+               # for aarch64
+               for i in $(find . -name config.guess -or -name config.sub); do
+                       cp -vf %{datadir}/automake-*/config.{guess,sub} $(dirname ${i})
+               done
+       end
+
        configure_options +=\
                --disable-static \
                --program-suffix=2
index a50f87dbff0fe6449bde2fe9e8d9cb52712da3b4..593f51eb67cb3f8865613218c4c9bbf436d8bfd0 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = libaio
-version    = 0.3.109
-release    = 3
+version    = 0.3.110
+release    = 1
 
 groups     = System/Libraries
 url        = ftp://ftp.kernel.org/pub/linux/libs/aio/
@@ -21,8 +21,7 @@ description
        applications which require the Linux-native async I/O API.
 end
 
-source_dl  =
-sources    = %{thisapp}.tar.bz2
+source_dl  = https://fedorahosted.org/releases/l/i/libaio/
 
 build
        requires
diff --git a/libatomic_ops/libatomic_ops.nm b/libatomic_ops/libatomic_ops.nm
new file mode 100644 (file)
index 0000000..3fd1f70
--- /dev/null
@@ -0,0 +1,54 @@
+###############################################################################
+# IPFire.org    - An Open Source Firewall Solution                            #
+# Copyright (C) - IPFire Development Team <info@ipfire.org>                   #
+###############################################################################
+
+name       = libatomic_ops
+version    = 7.4.2
+release    = 1
+
+groups     = Development/Tools
+url        = https://github.com/ivmai/libatomic_ops/
+license    = GPLv2, MIT
+summary    = Atomic memory update operations
+
+description
+       Provides implementations for atomic memory update operations on a
+       number of architectures. This allows direct use of these in reasonably
+       portable code. Unlike earlier similar packages, this one explicitly
+       considers memory barrier semantics, and allows the construction of code
+       that involves minimum overhead across a variety of architectures.
+end
+
+source_dl  = http://www.ivmaisoft.com/_bin/atomic_ops/
+
+build
+       requires
+               autoconf
+               automake
+               libtool
+       end
+
+       prepare_cmds
+               autoreconf -vfi
+       end
+
+       configure_options += \
+               --enable-shared
+
+       test
+               make check
+       end
+end
+
+packages
+       package %{name}
+
+       package %{name}-devel
+               template DEVEL
+       end
+
+       package %{name}-debuginfo
+               template DEBUGINFO
+       end
+end
diff --git a/libatomic_ops/patches/libatomic_ops-7.4.2-no_undefined.patch b/libatomic_ops/patches/libatomic_ops-7.4.2-no_undefined.patch
new file mode 100644 (file)
index 0000000..9807396
--- /dev/null
@@ -0,0 +1,23 @@
+diff -up libatomic_ops-7.4.2/src/Makefile.am.no_undefined libatomic_ops-7.4.2/src/Makefile.am
+--- libatomic_ops-7.4.2/src/Makefile.am.no_undefined   2014-05-02 10:52:15.000000000 -0500
++++ libatomic_ops-7.4.2/src/Makefile.am        2014-05-13 18:51:29.620033510 -0500
+@@ -12,6 +12,7 @@ libatomic_ops_la_LDFLAGS = -version-info
+ libatomic_ops_gpl_la_SOURCES = atomic_ops_stack.c atomic_ops_malloc.c
+ libatomic_ops_gpl_la_LDFLAGS = -version-info 1:3:0 -no-undefined
++libatomic_ops_gpl_la_LIBADD = libatomic_ops.la 
+ EXTRA_DIST = Makefile.msft atomic_ops/sysdeps/README \
+         atomic_ops/generalize-arithm.template \
+diff -up libatomic_ops-7.4.2/src/Makefile.in.no_undefined libatomic_ops-7.4.2/src/Makefile.in
+--- libatomic_ops-7.4.2/src/Makefile.in.no_undefined   2014-05-02 10:56:32.000000000 -0500
++++ libatomic_ops-7.4.2/src/Makefile.in        2014-05-13 18:51:55.352602385 -0500
+@@ -139,7 +139,7 @@ libatomic_ops_la_LINK = $(LIBTOOL) $(AM_
+       $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+       $(AM_CFLAGS) $(CFLAGS) $(libatomic_ops_la_LDFLAGS) $(LDFLAGS) \
+       -o $@
+-libatomic_ops_gpl_la_LIBADD =
++libatomic_ops_gpl_la_LIBADD = libatomic_ops.la
+ am_libatomic_ops_gpl_la_OBJECTS = atomic_ops_stack.lo \
+       atomic_ops_malloc.lo
+ libatomic_ops_gpl_la_OBJECTS = $(am_libatomic_ops_gpl_la_OBJECTS)
index d5ce0716a720103eb1aa04c649a72653a0deebc0..1e11687a1f0b53a8e5e5fbd3694e427aa5ab66af 100644 (file)
@@ -4,11 +4,11 @@
 ###############################################################################
 
 name       = libksba
-version    = 1.0.8
+version    = 1.3.2
 release    = 1
 
 groups     = System/Libraries
-url        = http://www.gnugp.org
+url        = http://www.gnupg.org
 license    = GPLv3
 summary    = X.509 Library.
 
@@ -17,7 +17,7 @@ description
        CMS protocols.
 end
 
-source_dl  =
+source_dl  = ftp://ftp.gnupg.org/gcrypt/libksba/
 sources    = %{thisapp}.tar.bz2
 
 build
@@ -28,7 +28,6 @@ end
 
 packages
        package %{name}
-       end
 
        package %{name}-devel
                template DEVEL
index 9a7b193c307e9ccbfb752d9166db7ba53190fd10..f5ec8cc7133dce91cb2e7efbff0d78ca1ba132ff 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = libpcap
-version    = 1.5.2
+version    = 1.7.2
 release    = 1
 
 groups     = System/Libraries
index eb8dbc64797ceb019609e346651b1ac310e1e89a..3ae49ecc7efc4583027c37b8bd4ad65ddaa055ee 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = libunwind
-version    = 1.0.1
+version    = 1.1
 release    = 1
 
 groups     = Development/Debuggers
@@ -31,6 +31,11 @@ build
                autoheader
                automake --add-missing
                autoconf
+
+               # for aarch64
+               for i in $(find . -name config.guess -or -name config.sub); do
+                       cp -vf %{datadir}/automake-*/config.{guess,sub} $(dirname ${i})
+               done
        end
 
        configure_options += \
diff --git a/libunwind/patches/libunwind-aarch64.patch b/libunwind/patches/libunwind-aarch64.patch
new file mode 100644 (file)
index 0000000..c8816b0
--- /dev/null
@@ -0,0 +1,2562 @@
+diff --git a/Makefile.am b/Makefile.am
+index d7278df..e24fe1e 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -2,6 +2,9 @@ include_HEADERS = include/libunwind-dynamic.h \
+     include/libunwind-ptrace.h \
+     include/libunwind-coredump.h
++if ARCH_AARCH64
++include_HEADERS += include/libunwind-aarch64.h
++endif
+ if ARCH_ARM
+ include_HEADERS += include/libunwind-arm.h
+ endif
+@@ -41,6 +44,9 @@ SUBDIRS = src tests doc
+ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
+       include/compiler.h include/libunwind_i.h include/mempool.h      \
+       include/remote.h                                                \
++      include/tdep-aarch64/dwarf-config.h                             \
++      include/tdep-aarch64/jmpbuf.h                                   \
++      include/tdep-aarch64/libunwind_i.h                              \
+       include/tdep-arm/dwarf-config.h include/tdep-arm/ex_tables.h    \
+       include/tdep-arm/jmpbuf.h include/tdep-arm/libunwind_i.h        \
+       include/tdep-ia64/jmpbuf.h include/tdep-ia64/rse.h              \
+diff --git a/README b/README
+index 71a631f..511fb0c 100644
+--- a/README
++++ b/README
+@@ -9,6 +9,7 @@ several architecture/operating-system combinations:
+  Linux/IA-64: Fully tested and supported.
+  Linux/PARISC:        Works well, but C library missing unwind-info.
+  HP-UX/IA-64: Mostly works but known to have some serious limitations.
++ Linux/AArch64:       Newly added.
+  Linux/PPC64: Newly added.
+  Linux/SuperH:        Newly added.
+  FreeBSD/i386:        Newly added.
+diff --git a/configure.ac b/configure.ac
+index cffe19b..096ca7b 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -104,7 +104,7 @@ SET_ARCH([$target_cpu],[target_arch])
+ AC_ARG_ENABLE(coredump,
+       AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),,
+-        [AS_CASE([$host_arch], [arm*|mips*|sh*|x86*], [enable_coredump=yes], [enable_coredump=no])]
++        [AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*], [enable_coredump=yes], [enable_coredump=no])]
+ )
+ AC_MSG_CHECKING([if we should build libunwind-coredump])
+@@ -121,6 +121,7 @@ AC_MSG_RESULT([$target_os])
+ AM_CONDITIONAL(BUILD_COREDUMP, test x$enable_coredump = xyes)
+ AM_CONDITIONAL(REMOTE_ONLY, test x$target_arch != x$host_arch)
++AM_CONDITIONAL(ARCH_AARCH64, test x$target_arch = xaarch64)
+ AM_CONDITIONAL(ARCH_ARM, test x$target_arch = xarm)
+ AM_CONDITIONAL(ARCH_IA64, test x$target_arch = xia64)
+ AM_CONDITIONAL(ARCH_HPPA, test x$target_arch = xhppa)
+@@ -137,7 +138,7 @@ AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null)
+ AC_MSG_CHECKING([for ELF helper width])
+ case "${target_arch}" in
+ (arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);;
+-(ia64|ppc64|x86_64)    use_elf64=yes; AC_MSG_RESULT([64]);;
++(aarch64|ia64|ppc64|x86_64)    use_elf64=yes; AC_MSG_RESULT([64]);;
+ (mips)                 use_elfxx=yes; AC_MSG_RESULT([xx]);;
+ *)                     AC_MSG_ERROR([Unknown ELF target: ${target_arch}])
+ esac
+@@ -186,6 +187,7 @@ AS_HELP_STRING([--enable-cxx-exceptions],[use libunwind to handle C++ exceptions
+ # C++ exception handling doesn't work too well on x86
+ case $target_arch in
+   x86*) enable_cxx_exceptions=no;;
++  aarch64*) enable_cxx_exceptions=no;;
+   arm*) enable_cxx_exceptions=no;;
+   mips*) enable_cxx_exceptions=no;;
+   *) enable_cxx_exceptions=yes;;
+diff --git a/include/libunwind-aarch64.h b/include/libunwind-aarch64.h
+new file mode 100644
+index 0000000..d50da8f
+--- /dev/null
++++ b/include/libunwind-aarch64.h
+@@ -0,0 +1,187 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2001-2004 Hewlett-Packard Co
++      Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#ifndef LIBUNWIND_H
++#define LIBUNWIND_H
++
++#if defined(__cplusplus) || defined(c_plusplus)
++extern "C" {
++#endif
++
++#include <inttypes.h>
++#include <stddef.h>
++#include <ucontext.h>
++
++#define UNW_TARGET    aarch64
++#define UNW_TARGET_AARCH64    1
++
++#define _U_TDEP_QP_TRUE       0       /* see libunwind-dynamic.h  */
++
++/* This needs to be big enough to accommodate "struct cursor", while
++   leaving some slack for future expansion.  Changing this value will
++   require recompiling all users of this library.  Stack allocation is
++   relatively cheap and unwind-state copying is relatively rare, so we
++   want to err on making it rather too big than too small.  */
++
++#define UNW_TDEP_CURSOR_LEN   4096
++
++typedef uint64_t unw_word_t;
++typedef int64_t unw_sword_t;
++
++typedef long double unw_tdep_fpreg_t;
++
++typedef struct
++  {
++    /* no aarch64-specific auxiliary proc-info */
++  }
++unw_tdep_proc_info_t;
++
++typedef enum
++  {
++    /* 64-bit general registers.  */
++    UNW_AARCH64_X0,
++    UNW_AARCH64_X1,
++    UNW_AARCH64_X2,
++    UNW_AARCH64_X3,
++    UNW_AARCH64_X4,
++    UNW_AARCH64_X5,
++    UNW_AARCH64_X6,
++    UNW_AARCH64_X7,
++    UNW_AARCH64_X8,
++
++    /* Temporary registers.  */
++    UNW_AARCH64_X9,
++    UNW_AARCH64_X10,
++    UNW_AARCH64_X11,
++    UNW_AARCH64_X12,
++    UNW_AARCH64_X13,
++    UNW_AARCH64_X14,
++    UNW_AARCH64_X15,
++
++    /* Intra-procedure-call temporary registers.  */
++    UNW_AARCH64_X16,
++    UNW_AARCH64_X17,
++
++    /* Callee-saved registers.  */
++    UNW_AARCH64_X18,
++    UNW_AARCH64_X19,
++    UNW_AARCH64_X20,
++    UNW_AARCH64_X21,
++    UNW_AARCH64_X22,
++    UNW_AARCH64_X23,
++    UNW_AARCH64_X24,
++    UNW_AARCH64_X25,
++    UNW_AARCH64_X26,
++    UNW_AARCH64_X27,
++    UNW_AARCH64_X28,
++
++    /* 64-bit frame pointer.  */
++    UNW_AARCH64_X29,
++
++    /* 64-bit link register.  */
++    UNW_AARCH64_X30,
++
++    /* 64-bit stack pointer.  */
++    UNW_AARCH64_SP =  31,
++    UNW_AARCH64_PC,
++    UNW_AARCH64_PSTATE,
++
++    /* 128-bit FP/Advanced SIMD registers.  */
++    UNW_AARCH64_V0 = 64,
++    UNW_AARCH64_V1,
++    UNW_AARCH64_V2,
++    UNW_AARCH64_V3,
++    UNW_AARCH64_V4,
++    UNW_AARCH64_V5,
++    UNW_AARCH64_V6,
++    UNW_AARCH64_V7,
++    UNW_AARCH64_V8,
++    UNW_AARCH64_V9,
++    UNW_AARCH64_V10,
++    UNW_AARCH64_V11,
++    UNW_AARCH64_V12,
++    UNW_AARCH64_V13,
++    UNW_AARCH64_V14,
++    UNW_AARCH64_V15,
++    UNW_AARCH64_V16,
++    UNW_AARCH64_V17,
++    UNW_AARCH64_V18,
++    UNW_AARCH64_V19,
++    UNW_AARCH64_V20,
++    UNW_AARCH64_V21,
++    UNW_AARCH64_V22,
++    UNW_AARCH64_V23,
++    UNW_AARCH64_V24,
++    UNW_AARCH64_V25,
++    UNW_AARCH64_V26,
++    UNW_AARCH64_V27,
++    UNW_AARCH64_V28,
++    UNW_AARCH64_V29,
++    UNW_AARCH64_V30,
++    UNW_AARCH64_V31,
++
++    UNW_AARCH64_FPSR,
++    UNW_AARCH64_FPCR,
++
++    /* For AArch64, the CFA is the value of SP (x31) at the call site of the
++       previous frame.  */
++    UNW_AARCH64_CFA = UNW_AARCH64_SP,
++
++    UNW_TDEP_LAST_REG = UNW_AARCH64_FPCR,
++
++    UNW_TDEP_IP = UNW_AARCH64_X30,
++    UNW_TDEP_SP = UNW_AARCH64_SP,
++    UNW_TDEP_EH = UNW_AARCH64_X0,
++
++  }
++aarch64_regnum_t;
++
++/* Use R0 through R3 to pass exception handling information.  */
++#define UNW_TDEP_NUM_EH_REGS  4
++
++typedef struct unw_tdep_save_loc
++  {
++    /* Additional target-dependent info on a save location.  */
++  }
++unw_tdep_save_loc_t;
++
++
++/* On AArch64, we can directly use ucontext_t as the unwind context.  */
++typedef ucontext_t unw_tdep_context_t;
++
++#include "libunwind-common.h"
++#include "libunwind-dynamic.h"
++
++#define unw_tdep_getcontext(uc)         (getcontext (uc), 0)
++#define unw_tdep_is_fpreg             UNW_ARCH_OBJ(is_fpreg)
++
++extern int unw_tdep_is_fpreg (int);
++
++#if defined(__cplusplus) || defined(c_plusplus)
++}
++#endif
++
++#endif /* LIBUNWIND_H */
+diff --git a/include/libunwind.h.in b/include/libunwind.h.in
+index 25c4e3b..64b1457 100644
+--- a/include/libunwind.h.in
++++ b/include/libunwind.h.in
+@@ -3,7 +3,9 @@
+ #ifndef UNW_REMOTE_ONLY
+-#if defined __arm__
++#if defined __aarch64__
++#include "libunwind-aarch64.h"
++#elif defined __arm__
+ # include "libunwind-arm.h"
+ #elif defined __hppa__
+ # include "libunwind-hppa.h"
+diff --git a/include/tdep-aarch64/dwarf-config.h b/include/tdep-aarch64/dwarf-config.h
+new file mode 100644
+index 0000000..c3bbed5
+--- /dev/null
++++ b/include/tdep-aarch64/dwarf-config.h
+@@ -0,0 +1,52 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#ifndef dwarf_config_h
++#define dwarf_config_h
++
++/* This matches the value udes by GCC (see
++   gcc/config/aarch64/aarch64.h:DWARF_FRAME_REGISTERS.  */ 
++#define DWARF_NUM_PRESERVED_REGS      97
++
++/* Return TRUE if the ADDR_SPACE uses big-endian byte-order.  */
++#define dwarf_is_big_endian(addr_space)       0
++
++#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0)
++
++/* Convert a pointer to a dwarf_cursor structure to a pointer to
++   unw_cursor_t.  */
++#define dwarf_to_cursor(c)    ((unw_cursor_t *) (c))
++
++typedef struct dwarf_loc
++  {
++    unw_word_t val;
++#ifndef UNW_LOCAL_ONLY
++    unw_word_t type;          /* see DWARF_LOC_TYPE_* macros.  */
++#endif
++  }
++dwarf_loc_t;
++
++#endif /* dwarf_config_h */
+diff --git a/include/tdep-aarch64/jmpbuf.h b/include/tdep-aarch64/jmpbuf.h
+new file mode 100644
+index 0000000..2eb53a7
+--- /dev/null
++++ b/include/tdep-aarch64/jmpbuf.h
+@@ -0,0 +1,33 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
++
++/* FIXME for AArch64  */
++
++#define JB_SP         13
++#define JB_RP         14
++#define JB_MASK_SAVED 15
++#define JB_MASK               16
+diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h
+new file mode 100644
+index 0000000..28943db
+--- /dev/null
++++ b/include/tdep-aarch64/libunwind_i.h
+@@ -0,0 +1,294 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2001-2005 Hewlett-Packard Co
++      Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#ifndef AARCH64_LIBUNWIND_I_H
++#define AARCH64_LIBUNWIND_I_H
++
++/* Target-dependent definitions that are internal to libunwind but need
++   to be shared with target-independent code.  */
++
++#include <stdlib.h> 
++#include <libunwind.h>
++
++#include "elf64.h"
++#include "mempool.h"
++#include "dwarf.h"
++
++typedef struct
++  {
++    /* no aarch64-specific fast trace */
++  }
++unw_tdep_frame_t;
++
++#ifdef UNW_LOCAL_ONLY
++
++typedef unw_word_t aarch64_loc_t;
++
++#else /* !UNW_LOCAL_ONLY */
++
++typedef struct aarch64_loc
++  {
++    unw_word_t w0, w1;
++  }
++aarch64_loc_t;
++
++#endif /* !UNW_LOCAL_ONLY */
++
++struct unw_addr_space
++  {
++    struct unw_accessors acc;
++    int big_endian;
++    unw_caching_policy_t caching_policy;
++#ifdef HAVE_ATOMIC_OPS_H
++    AO_t cache_generation;
++#else
++    uint32_t cache_generation;
++#endif
++    unw_word_t dyn_generation;          /* see dyn-common.h */
++    unw_word_t dyn_info_list_addr;    /* (cached) dyn_info_list_addr */
++    struct dwarf_rs_cache global_cache;
++    struct unw_debug_frame_list *debug_frames;
++   };
++
++struct cursor
++  {
++    struct dwarf_cursor dwarf;          /* must be first */
++    enum
++      {
++        AARCH64_SCF_NONE,
++        AARCH64_SCF_LINUX_RT_SIGFRAME,
++      }
++    sigcontext_format;
++    unw_word_t sigcontext_addr;
++    unw_word_t sigcontext_sp;
++    unw_word_t sigcontext_pc;
++  };
++
++#define DWARF_GET_LOC(l)        ((l).val)
++
++#ifdef UNW_LOCAL_ONLY
++# define DWARF_NULL_LOC         DWARF_LOC (0, 0)
++# define DWARF_IS_NULL_LOC(l)   (DWARF_GET_LOC (l) == 0)
++# define DWARF_LOC(r, t)        ((dwarf_loc_t) { .val = (r) })
++# define DWARF_IS_REG_LOC(l)    0
++# define DWARF_REG_LOC(c,r)     (DWARF_LOC((unw_word_t)                      \
++                                 tdep_uc_addr((c)->as_arg, (r)), 0))
++# define DWARF_MEM_LOC(c,m)     DWARF_LOC ((m), 0)
++# define DWARF_FPREG_LOC(c,r)   (DWARF_LOC((unw_word_t)                      \
++                                 tdep_uc_addr((c)->as_arg, (r)), 0))
++
++static inline int
++dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
++{
++  if (!DWARF_GET_LOC (loc))
++    return -1;
++  *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
++  return 0;
++}
++
++static inline int
++dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
++{
++  if (!DWARF_GET_LOC (loc))
++    return -1;
++  *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
++  return 0;
++}
++
++static inline int
++dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
++{
++  if (!DWARF_GET_LOC (loc))
++    return -1;
++  *val = *(unw_word_t *) DWARF_GET_LOC (loc);
++  return 0;
++}
++
++static inline int
++dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
++{
++  if (!DWARF_GET_LOC (loc))
++    return -1;
++  *(unw_word_t *) DWARF_GET_LOC (loc) = val;
++  return 0;
++}
++
++#else /* !UNW_LOCAL_ONLY */
++# define DWARF_LOC_TYPE_FP      (1 << 0)
++# define DWARF_LOC_TYPE_REG     (1 << 1)
++# define DWARF_NULL_LOC         DWARF_LOC (0, 0)
++# define DWARF_IS_NULL_LOC(l)                                           \
++                ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
++# define DWARF_LOC(r, t)        ((dwarf_loc_t) { .val = (r), .type = (t) })
++# define DWARF_IS_REG_LOC(l)    (((l).type & DWARF_LOC_TYPE_REG) != 0)
++# define DWARF_IS_FP_LOC(l)     (((l).type & DWARF_LOC_TYPE_FP) != 0)
++# define DWARF_REG_LOC(c,r)     DWARF_LOC((r), DWARF_LOC_TYPE_REG)
++# define DWARF_MEM_LOC(c,m)     DWARF_LOC ((m), 0)
++# define DWARF_FPREG_LOC(c,r)   DWARF_LOC((r), (DWARF_LOC_TYPE_REG      \
++                                                | DWARF_LOC_TYPE_FP))
++
++static inline int
++dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
++{
++  char *valp = (char *) &val;
++  unw_word_t addr;
++  int ret;
++
++  if (DWARF_IS_NULL_LOC (loc))
++    return -UNW_EBADREG;
++
++  if (DWARF_IS_REG_LOC (loc))
++    return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
++                                       val, 0, c->as_arg);
++
++  addr = DWARF_GET_LOC (loc);
++  if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
++                                       0, c->as_arg)) < 0)
++    return ret;
++
++  return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
++                                   c->as_arg);
++}
++
++static inline int
++dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
++{
++  char *valp = (char *) &val;
++  unw_word_t addr;
++  int ret;
++
++  if (DWARF_IS_NULL_LOC (loc))
++    return -UNW_EBADREG;
++
++  if (DWARF_IS_REG_LOC (loc))
++    return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
++                                       &val, 1, c->as_arg);
++
++  addr = DWARF_GET_LOC (loc);
++  if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
++                                       1, c->as_arg)) < 0)
++    return ret;
++
++  return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
++                                   1, c->as_arg);
++}
++
++static inline int
++dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
++{
++  if (DWARF_IS_NULL_LOC (loc))
++    return -UNW_EBADREG;
++
++  /* If a code-generator were to save a value of type unw_word_t in a
++     floating-point register, we would have to support this case.  I
++     suppose it could happen with MMX registers, but does it really
++     happen?  */
++  assert (!DWARF_IS_FP_LOC (loc));
++
++  if (DWARF_IS_REG_LOC (loc))
++    return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
++                                     0, c->as_arg);
++  else
++    return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
++                                     0, c->as_arg);
++}
++
++static inline int
++dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
++{
++  if (DWARF_IS_NULL_LOC (loc))
++    return -UNW_EBADREG;
++
++  /* If a code-generator were to save a value of type unw_word_t in a
++     floating-point register, we would have to support this case.  I
++     suppose it could happen with MMX registers, but does it really
++     happen?  */
++  assert (!DWARF_IS_FP_LOC (loc));
++
++  if (DWARF_IS_REG_LOC (loc))
++    return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
++                                     1, c->as_arg);
++  else
++    return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
++                                     1, c->as_arg);
++}
++
++#endif /* !UNW_LOCAL_ONLY */
++
++
++
++#define tdep_getcontext_trace           unw_getcontext
++#define tdep_init_done                        UNW_OBJ(init_done)
++#define tdep_init                     UNW_OBJ(init)
++/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
++   tdep_search_unwind_table.  */
++#define tdep_search_unwind_table      dwarf_search_unwind_table
++#define tdep_find_unwind_table                dwarf_find_unwind_table
++#define tdep_uc_addr                  UNW_OBJ(uc_addr)
++#define tdep_get_elf_image            UNW_ARCH_OBJ(get_elf_image)
++#define tdep_access_reg                       UNW_OBJ(access_reg)
++#define tdep_access_fpreg             UNW_OBJ(access_fpreg)
++#define tdep_fetch_frame(c,ip,n)      do {} while(0)
++#define tdep_cache_frame(c,rs)                do {} while(0)
++#define tdep_reuse_frame(c,rs)                do {} while(0)
++#define tdep_stash_frame(c,rs)                do {} while(0)
++#define tdep_trace(cur,addr,n)                (-UNW_ENOINFO)
++
++#ifdef UNW_LOCAL_ONLY
++# define tdep_find_proc_info(c,ip,n)                            \
++        dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n),      \
++                                       (c)->as_arg)
++# define tdep_put_unwind_info(as,pi,arg)                \
++        dwarf_put_unwind_info((as), (pi), (arg))
++#else
++# define tdep_find_proc_info(c,ip,n)                                    \
++        (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n),    \
++                                       (c)->as_arg)
++# define tdep_put_unwind_info(as,pi,arg)                \
++        (*(as)->acc.put_unwind_info)((as), (pi), (arg))
++#endif
++
++#define tdep_get_as(c)                  ((c)->dwarf.as)
++#define tdep_get_as_arg(c)              ((c)->dwarf.as_arg)
++#define tdep_get_ip(c)                  ((c)->dwarf.ip)
++#define tdep_big_endian(as)             ((as)->big_endian)
++
++extern int tdep_init_done;
++
++extern void tdep_init (void);
++extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
++                                   unw_dyn_info_t *di, unw_proc_info_t *pi,
++                                   int need_unwind_info, void *arg);
++extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
++extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
++                             unsigned long *segbase, unsigned long *mapoff,
++                             char *path, size_t pathlen);
++extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
++                          unw_word_t *valp, int write);
++extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
++                            unw_fpreg_t *valp, int write);
++
++#endif /* AARCH64_LIBUNWIND_I_H */
+diff --git a/include/tdep/dwarf-config.h b/include/tdep/dwarf-config.h
+index 1da268b..5b09fc1 100644
+--- a/include/tdep/dwarf-config.h
++++ b/include/tdep/dwarf-config.h
+@@ -1,7 +1,9 @@
+ /* Provide a real file - not a symlink - as it would cause multiarch conflicts
+    when multiple different arch releases are installed simultaneously.  */
+-#if defined __arm__
++#if defined __aarch64__
++# include "tdep-aarch64/dwarf-config.h"
++#elif defined __arm__
+ # include "tdep-arm/dwarf-config.h"
+ #elif defined __hppa__
+ # include "tdep-hppa/dwarf-config.h"
+diff --git a/include/tdep/jmpbuf.h b/include/tdep/jmpbuf.h
+index 7d04a42..684d0d9 100644
+--- a/include/tdep/jmpbuf.h
++++ b/include/tdep/jmpbuf.h
+@@ -3,6 +3,8 @@
+ #ifndef UNW_REMOTE_ONLY
++#if defined __aarch64__
++# include "tdep-aarch64/jmpbuf.h"
+ #if defined __arm__
+ # include "tdep-arm/jmpbuf.h"
+ #elif defined __hppa__
+diff --git a/include/tdep/libunwind_i.h.in b/include/tdep/libunwind_i.h.in
+index 2ad6269..475f828 100644
+--- a/include/tdep/libunwind_i.h.in
++++ b/include/tdep/libunwind_i.h.in
+@@ -3,7 +3,9 @@
+ #ifndef UNW_REMOTE_ONLY
+-#if defined __arm__
++#if defined __aarch64__
++# include "tdep-aarch64/libunwind_i.h"
++#elif defined __arm__
+ # include "tdep-arm/libunwind_i.h"
+ #elif defined __hppa__
+ # include "tdep-hppa/libunwind_i.h"
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 08d2870..f104214 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -170,6 +170,28 @@ libunwind_elfxx_la_SOURCES = elfxx.c
+ noinst_LTLIBRARIES += $(LIBUNWIND_ELF)
+ libunwind_la_LIBADD += $(LIBUNWIND_ELF)
++# The list of files that go into libunwind and libunwind-aarch64:
++noinst_HEADERS += aarch64/init.h aarch64/offsets.h aarch64/unwind_i.h
++libunwind_la_SOURCES_aarch64_common = $(libunwind_la_SOURCES_common)      \
++      aarch64/is_fpreg.c aarch64/regname.c
++
++# The list of files that go into libunwind:
++libunwind_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common)     \
++      $(libunwind_la_SOURCES_local)                                       \
++      aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c               \
++      aarch64/Lget_save_loc.c aarch64/Lglobal.c aarch64/Linit.c           \
++      aarch64/Linit_local.c aarch64/Linit_remote.c                        \
++      aarch64/Lis_signal_frame.c aarch64/Lregs.c aarch64/Lresume.c        \
++      aarch64/Lstep.c
++
++libunwind_aarch64_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \
++      $(libunwind_la_SOURCES_generic)                                       \
++      aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c                 \
++      aarch64/Gget_save_loc.c aarch64/Gglobal.c aarch64/Ginit.c             \
++      aarch64/Ginit_local.c aarch64/Ginit_remote.c                          \
++      aarch64/Gis_signal_frame.c aarch64/Gregs.c aarch64/Gresume.c          \
++      aarch64/Gstep.c
++
+ # The list of files that go into libunwind and libunwind-arm:
+ noinst_HEADERS += arm/init.h arm/offsets.h arm/unwind_i.h
+ libunwind_la_SOURCES_arm_common = $(libunwind_la_SOURCES_common)          \
+@@ -418,6 +440,18 @@ if OS_FREEBSD
+  libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c
+ endif
++if ARCH_AARCH64
++ lib_LTLIBRARIES += libunwind-aarch64.la
++ libunwind_la_SOURCES = $(libunwind_la_SOURCES_aarch64)
++ libunwind_aarch64_la_SOURCES = $(libunwind_aarch64_la_SOURCES_aarch64)
++ libunwind_aarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
++ libunwind_aarch64_la_LIBADD = libunwind-dwarf-generic.la
++ libunwind_aarch64_la_LIBADD += libunwind-elf64.la
++if !REMOTE_ONLY
++ libunwind_aarch64_la_LIBADD += libunwind.la -lc
++endif
++# libunwind_setjmp_la_SOURCES += aarch64/siglongjmp.S
++else
+ if ARCH_ARM
+  lib_LTLIBRARIES += libunwind-arm.la
+  libunwind_la_SOURCES = $(libunwind_la_SOURCES_arm)
+@@ -545,6 +579,7 @@ endif # ARCH_MIPS
+ endif # ARCH_HPPA
+ endif # ARCH_IA64
+ endif # ARCH_ARM
++endif # ARCH_AARCH64
+ # libunwind-setjmp depends on libunwind-$(arch). Therefore must be added
+ # at the end.
+@@ -567,7 +602,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I.
+ AM_CCASFLAGS = $(AM_CPPFLAGS)
+ noinst_HEADERS += unwind/unwind-internal.h
+-EXTRA_DIST =  $(libunwind_la_SOURCES_arm)                     \
++EXTRA_DIST =  $(libunwind_la_SOURCES_aarch64)                 \
++              $(libunwind_la_SOURCES_arm)                     \
+               $(libunwind_la_SOURCES_hppa)                    \
+               $(libunwind_la_SOURCES_ia64)                    \
+               $(libunwind_la_SOURCES_mips)                    \
+@@ -579,6 +615,7 @@ EXTRA_DIST =       $(libunwind_la_SOURCES_arm)                     \
+               $(libunwind_la_SOURCES_common)                  \
+               $(libunwind_la_SOURCES_local)                   \
+               $(libunwind_la_SOURCES_generic)                 \
++              $(libunwind_aarch64_la_SOURCES_aarch64)         \
+               $(libunwind_arm_la_SOURCES_arm)                 \
+               $(libunwind_hppa_la_SOURCES_hppa)               \
+               $(libunwind_ia64_la_SOURCES_ia64)               \
+diff --git a/src/aarch64/Gcreate_addr_space.c b/src/aarch64/Gcreate_addr_space.c
+new file mode 100644
+index 0000000..b0f2b04
+--- /dev/null
++++ b/src/aarch64/Gcreate_addr_space.c
+@@ -0,0 +1,60 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include <string.h>
++#include <stdlib.h>
++
++#include "unwind_i.h"
++
++PROTECTED unw_addr_space_t
++unw_create_addr_space (unw_accessors_t *a, int byte_order)
++{
++#ifdef UNW_LOCAL_ONLY
++  return NULL;
++#else
++  unw_addr_space_t as;
++
++  /* AArch64 supports little-endian and big-endian. */
++  if (byte_order != 0 && byte_order != __LITTLE_ENDIAN
++      && byte_order != __BIG_ENDIAN)
++    return NULL;
++
++  as = malloc (sizeof (*as));
++  if (!as)
++    return NULL;
++
++  memset (as, 0, sizeof (*as));
++
++  as->acc = *a;
++
++  /* Default to little-endian for AArch64. */
++  if (byte_order == 0 || byte_order == __LITTLE_ENDIAN)
++    as->big_endian = 0;
++  else
++    as->big_endian = 1;
++
++  return as;
++#endif
++}
+diff --git a/src/aarch64/Gget_proc_info.c b/src/aarch64/Gget_proc_info.c
+new file mode 100644
+index 0000000..de9199f
+--- /dev/null
++++ b/src/aarch64/Gget_proc_info.c
+@@ -0,0 +1,39 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++
++PROTECTED int
++unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi)
++{
++  struct cursor *c = (struct cursor *) cursor;
++  int ret;
++
++  ret = dwarf_make_proc_info (&c->dwarf);
++  if (ret < 0)
++    return ret;
++
++  *pi = c->dwarf.pi;
++  return 0;
++}
+diff --git a/src/aarch64/Gget_save_loc.c b/src/aarch64/Gget_save_loc.c
+new file mode 100644
+index 0000000..c76eb9c
+--- /dev/null
++++ b/src/aarch64/Gget_save_loc.c
+@@ -0,0 +1,100 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++
++PROTECTED int
++unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
++{
++  struct cursor *c = (struct cursor *) cursor;
++  dwarf_loc_t loc;
++
++  switch (reg)
++    {
++    case UNW_AARCH64_X0:
++    case UNW_AARCH64_X1:
++    case UNW_AARCH64_X2:
++    case UNW_AARCH64_X3:
++    case UNW_AARCH64_X4:
++    case UNW_AARCH64_X5:
++    case UNW_AARCH64_X6:
++    case UNW_AARCH64_X7:
++    case UNW_AARCH64_X8:
++    case UNW_AARCH64_X9:
++    case UNW_AARCH64_X10:
++    case UNW_AARCH64_X11:
++    case UNW_AARCH64_X12:
++    case UNW_AARCH64_X13:
++    case UNW_AARCH64_X14:
++    case UNW_AARCH64_X15:
++    case UNW_AARCH64_X16:
++    case UNW_AARCH64_X17:
++    case UNW_AARCH64_X18:
++    case UNW_AARCH64_X19:
++    case UNW_AARCH64_X20:
++    case UNW_AARCH64_X21:
++    case UNW_AARCH64_X22:
++    case UNW_AARCH64_X23:
++    case UNW_AARCH64_X24:
++    case UNW_AARCH64_X25:
++    case UNW_AARCH64_X26:
++    case UNW_AARCH64_X27:
++    case UNW_AARCH64_X28:
++    case UNW_AARCH64_X29:
++    case UNW_AARCH64_X30:
++    case UNW_AARCH64_SP:
++    case UNW_AARCH64_PC:
++    case UNW_AARCH64_PSTATE:
++      loc = c->dwarf.loc[reg];
++      break;
++
++    default:
++      loc = DWARF_NULL_LOC;   /* default to "not saved" */
++      break;
++    }
++
++  memset (sloc, 0, sizeof (*sloc));
++
++  if (DWARF_IS_NULL_LOC (loc))
++    {
++      sloc->type = UNW_SLT_NONE;
++      return 0;
++    }
++
++#if !defined(UNW_LOCAL_ONLY)
++  if (DWARF_IS_REG_LOC (loc))
++    {
++      sloc->type = UNW_SLT_REG;
++      sloc->u.regnum = DWARF_GET_LOC (loc);
++    }
++  else
++#endif
++    {
++      sloc->type = UNW_SLT_MEMORY;
++      sloc->u.addr = DWARF_GET_LOC (loc);
++    }
++  return 0;
++}
+diff --git a/src/aarch64/Gglobal.c b/src/aarch64/Gglobal.c
+new file mode 100644
+index 0000000..b0a7e26
+--- /dev/null
++++ b/src/aarch64/Gglobal.c
+@@ -0,0 +1,57 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++#include "dwarf_i.h"
++
++HIDDEN define_lock (aarch64_lock);
++HIDDEN int tdep_init_done;
++
++HIDDEN void
++tdep_init (void)
++{
++  intrmask_t saved_mask;
++
++  sigfillset (&unwi_full_mask);
++
++  lock_acquire (&aarch64_lock, saved_mask);
++  {
++    if (tdep_init_done)
++      /* another thread else beat us to it... */
++      goto out;
++
++    mi_init ();
++
++    dwarf_init ();
++
++#ifndef UNW_REMOTE_ONLY
++    aarch64_local_addr_space_init ();
++#endif
++    tdep_init_done = 1;       /* signal that we're initialized... */
++  }
++ out:
++  lock_release (&aarch64_lock, saved_mask);
++}
+diff --git a/src/aarch64/Ginit.c b/src/aarch64/Ginit.c
+new file mode 100644
+index 0000000..449b417
+--- /dev/null
++++ b/src/aarch64/Ginit.c
+@@ -0,0 +1,187 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include <stdlib.h>
++#include <string.h>
++
++#include "unwind_i.h"
++
++#ifdef UNW_REMOTE_ONLY
++
++/* unw_local_addr_space is a NULL pointer in this case.  */
++PROTECTED unw_addr_space_t unw_local_addr_space;
++
++#else /* !UNW_REMOTE_ONLY */
++
++static struct unw_addr_space local_addr_space;
++
++PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
++
++static inline void *
++uc_addr (ucontext_t *uc, int reg)
++{
++  if (reg >= UNW_AARCH64_X0 && reg <= UNW_AARCH64_V31)
++    return &uc->uc_mcontext.regs[reg];
++  else
++    return NULL;
++}
++
++# ifdef UNW_LOCAL_ONLY
++
++HIDDEN void *
++tdep_uc_addr (ucontext_t *uc, int reg)
++{
++  return uc_addr (uc, reg);
++}
++
++# endif /* UNW_LOCAL_ONLY */
++
++HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
++
++/* XXX fix me: there is currently no way to locate the dyn-info list
++       by a remote unwinder.  On ia64, this is done via a special
++       unwind-table entry.  Perhaps something similar can be done with
++       DWARF2 unwind info.  */
++
++static void
++put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
++{
++  /* it's a no-op */
++}
++
++static int
++get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
++                      void *arg)
++{
++  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
++  return 0;
++}
++
++static int
++access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
++          void *arg)
++{
++  if (write)
++    {
++      Debug (16, "mem[%x] <- %x\n", addr, *val);
++      *(unw_word_t *) addr = *val;
++    }
++  else
++    {
++      *val = *(unw_word_t *) addr;
++      Debug (16, "mem[%x] -> %x\n", addr, *val);
++    }
++  return 0;
++}
++
++static int
++access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
++          void *arg)
++{
++  unw_word_t *addr;
++  ucontext_t *uc = arg;
++
++  if (unw_is_fpreg (reg))
++    goto badreg;
++
++  if (!(addr = uc_addr (uc, reg)))
++    goto badreg;
++
++  if (write)
++    {
++      *(unw_word_t *) addr = *val;
++      Debug (12, "%s <- %x\n", unw_regname (reg), *val);
++    }
++  else
++    {
++      *val = *(unw_word_t *) addr;
++      Debug (12, "%s -> %x\n", unw_regname (reg), *val);
++    }
++  return 0;
++
++ badreg:
++  Debug (1, "bad register number %u\n", reg);
++  return -UNW_EBADREG;
++}
++
++static int
++access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
++            int write, void *arg)
++{
++  ucontext_t *uc = arg;
++  unw_fpreg_t *addr;
++
++  if (!unw_is_fpreg (reg))
++    goto badreg;
++
++  if (!(addr = uc_addr (uc, reg)))
++    goto badreg;
++
++  if (write)
++    {
++      Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg),
++           ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
++      *(unw_fpreg_t *) addr = *val;
++    }
++  else
++    {
++      *val = *(unw_fpreg_t *) addr;
++      Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg),
++           ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
++    }
++  return 0;
++
++ badreg:
++  Debug (1, "bad register number %u\n", reg);
++  /* attempt to access a non-preserved register */
++  return -UNW_EBADREG;
++}
++
++static int
++get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
++                    char *buf, size_t buf_len, unw_word_t *offp,
++                    void *arg)
++{
++  return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
++}
++
++HIDDEN void
++aarch64_local_addr_space_init (void)
++{
++  memset (&local_addr_space, 0, sizeof (local_addr_space));
++  local_addr_space.caching_policy = UNW_CACHE_GLOBAL;
++  local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
++  local_addr_space.acc.put_unwind_info = put_unwind_info;
++  local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
++  local_addr_space.acc.access_mem = access_mem;
++  local_addr_space.acc.access_reg = access_reg;
++  local_addr_space.acc.access_fpreg = access_fpreg;
++  local_addr_space.acc.resume = aarch64_local_resume;
++  local_addr_space.acc.get_proc_name = get_static_proc_name;
++  unw_flush_cache (&local_addr_space, 0, 0);
++}
++
++#endif /* !UNW_REMOTE_ONLY */
+diff --git a/src/aarch64/Ginit_local.c b/src/aarch64/Ginit_local.c
+new file mode 100644
+index 0000000..dee6fd3
+--- /dev/null
++++ b/src/aarch64/Ginit_local.c
+@@ -0,0 +1,55 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2011-2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++#include "init.h"
++
++#ifdef UNW_REMOTE_ONLY
++
++PROTECTED int
++unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
++{
++  return -UNW_EINVAL;
++}
++
++#else /* !UNW_REMOTE_ONLY */
++
++PROTECTED int
++unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
++{
++  struct cursor *c = (struct cursor *) cursor;
++
++  if (!tdep_init_done)
++    tdep_init ();
++
++  Debug (1, "(cursor=%p)\n", c);
++
++  c->dwarf.as = unw_local_addr_space;
++  c->dwarf.as_arg = uc;
++
++  return common_init (c, 1);
++}
++
++#endif /* !UNW_REMOTE_ONLY */
+diff --git a/src/aarch64/Ginit_remote.c b/src/aarch64/Ginit_remote.c
+new file mode 100644
+index 0000000..f284e99
+--- /dev/null
++++ b/src/aarch64/Ginit_remote.c
+@@ -0,0 +1,45 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "init.h"
++#include "unwind_i.h"
++
++PROTECTED int
++unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg)
++{
++#ifdef UNW_LOCAL_ONLY
++  return -UNW_EINVAL;
++#else /* !UNW_LOCAL_ONLY */
++  struct cursor *c = (struct cursor *) cursor;
++
++  if (!tdep_init_done)
++    tdep_init ();
++
++  Debug (1, "(cursor=%p)\n", c);
++
++  c->dwarf.as = as;
++  c->dwarf.as_arg = as_arg;
++  return common_init (c, 0);
++#endif /* !UNW_LOCAL_ONLY */
++}
+diff --git a/src/aarch64/Gis_signal_frame.c b/src/aarch64/Gis_signal_frame.c
+new file mode 100644
+index 0000000..53e32de
+--- /dev/null
++++ b/src/aarch64/Gis_signal_frame.c
+@@ -0,0 +1,64 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++
++/* The restorer stub will always have the form:
++
++   d2801168        movz    x8, #0x8b
++   d4000001        svc     #0x0
++*/
++
++PROTECTED int
++unw_is_signal_frame (unw_cursor_t *cursor)
++{
++#ifdef __linux__
++  struct cursor *c = (struct cursor *) cursor;
++  unw_word_t w0, ip;
++  unw_addr_space_t as;
++  unw_accessors_t *a;
++  void *arg;
++  int ret;
++
++  as = c->dwarf.as;
++  a = unw_get_accessors (as);
++  arg = c->dwarf.as_arg;
++
++  ip = c->dwarf.ip;
++
++  ret = (*a->access_mem) (as, ip, &w0, 0, arg);
++  if (ret < 0)
++    return ret;
++
++  /* FIXME: distinguish 32bit insn vs 64bit registers.  */
++  if (w0 != 0xd4000001d2801168)
++    return 0;
++
++  return 1;
++
++#else
++  return -UNW_ENOINFO;
++#endif
++}
+diff --git a/src/aarch64/Gregs.c b/src/aarch64/Gregs.c
+new file mode 100644
+index 0000000..0f6b9c6
+--- /dev/null
++++ b/src/aarch64/Gregs.c
+@@ -0,0 +1,113 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++
++HIDDEN int
++tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
++               int write)
++{
++  dwarf_loc_t loc = DWARF_NULL_LOC;
++  unsigned int mask;
++
++  switch (reg)
++    {
++    case UNW_AARCH64_X0:
++    case UNW_AARCH64_X1:
++    case UNW_AARCH64_X2:
++    case UNW_AARCH64_X3:
++      mask = 1 << reg;
++      if (write)
++        {
++          c->dwarf.eh_args[reg] = *valp;
++          c->dwarf.eh_valid_mask |= mask;
++          return 0;
++        }
++      else if ((c->dwarf.eh_valid_mask & mask) != 0)
++        {
++          *valp = c->dwarf.eh_args[reg];
++          return 0;
++        }
++      else
++        loc = c->dwarf.loc[reg];
++      break;
++
++    case UNW_AARCH64_X4:
++    case UNW_AARCH64_X5:
++    case UNW_AARCH64_X6:
++    case UNW_AARCH64_X7:
++    case UNW_AARCH64_X8:
++    case UNW_AARCH64_X9:
++    case UNW_AARCH64_X10:
++    case UNW_AARCH64_X11:
++    case UNW_AARCH64_X12:
++    case UNW_AARCH64_X13:
++    case UNW_AARCH64_X14:
++    case UNW_AARCH64_X15:
++    case UNW_AARCH64_X16:
++    case UNW_AARCH64_X17:
++    case UNW_AARCH64_X18:
++    case UNW_AARCH64_X19:
++    case UNW_AARCH64_X20:
++    case UNW_AARCH64_X21:
++    case UNW_AARCH64_X22:
++    case UNW_AARCH64_X23:
++    case UNW_AARCH64_X24:
++    case UNW_AARCH64_X25:
++    case UNW_AARCH64_X26:
++    case UNW_AARCH64_X27:
++    case UNW_AARCH64_X28:
++    case UNW_AARCH64_X29:
++    case UNW_AARCH64_X30:
++    case UNW_AARCH64_PC:
++    case UNW_AARCH64_PSTATE:
++      loc = c->dwarf.loc[reg];
++      break;
++
++    case UNW_AARCH64_SP:
++      if (write)
++        return -UNW_EREADONLYREG;
++      *valp = c->dwarf.cfa;
++      return 0;
++
++    default:
++      Debug (1, "bad register number %u\n", reg);
++      return -UNW_EBADREG;
++    }
++
++  if (write)
++    return dwarf_put (&c->dwarf, loc, *valp);
++  else
++    return dwarf_get (&c->dwarf, loc, valp);
++}
++
++HIDDEN int
++tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
++                 int write)
++{
++  Debug (1, "bad register number %u\n", reg);
++  return -UNW_EBADREG;
++}
+diff --git a/src/aarch64/Gresume.c b/src/aarch64/Gresume.c
+new file mode 100644
+index 0000000..908646b
+--- /dev/null
++++ b/src/aarch64/Gresume.c
+@@ -0,0 +1,177 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2011-2013 Linaro Limited
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++#include "offsets.h"
++
++#ifndef UNW_REMOTE_ONLY
++
++HIDDEN inline int
++aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
++{
++#ifdef __linux__
++  struct cursor *c = (struct cursor *) cursor;
++  unw_tdep_context_t *uc = c->dwarf.as_arg;
++
++  if (c->sigcontext_format == AARCH64_SCF_NONE)
++    {
++      /* Since there are no signals involved here we restore the non scratch
++       registers only.  */
++      unsigned long regs[11];
++      regs[0] = uc->uc_mcontext.regs[19];
++      regs[1] = uc->uc_mcontext.regs[20];
++      regs[2] = uc->uc_mcontext.regs[21];
++      regs[3] = uc->uc_mcontext.regs[22];
++      regs[4] = uc->uc_mcontext.regs[23];
++      regs[5] = uc->uc_mcontext.regs[24];
++      regs[6] = uc->uc_mcontext.regs[25];
++      regs[7] = uc->uc_mcontext.regs[26];
++      regs[8] = uc->uc_mcontext.regs[27];
++      regs[9] = uc->uc_mcontext.regs[28];
++      regs[10] = uc->uc_mcontext.regs[30]; /* LR */
++      unsigned long sp = uc->uc_mcontext.sp;
++
++      struct regs_overlay {
++        char x[sizeof(regs)];
++      };
++
++      asm volatile (
++        "ldp x19, x20, [%0]\n"
++        "ldp x21, x22, [%0,16]\n"
++        "ldp x23, x24, [%0,32]\n"
++        "ldp x25, x26, [%0,48]\n"
++        "ldp x27, x28, [%0,64]\n"
++        "ldr x30, [%0,80]\n"
++        "mov sp, %1\n"
++        "ret \n"
++        :
++        : "r" (regs),
++          "r" (sp),
++          "m" (*(struct regs_overlay *)regs)
++      );
++    }
++  else
++    {
++      struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
++
++      if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0];
++      if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1];
++      if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2];
++      if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3];
++
++      sc->regs[4] = uc->uc_mcontext.regs[4];
++      sc->regs[5] = uc->uc_mcontext.regs[5];
++      sc->regs[6] = uc->uc_mcontext.regs[6];
++      sc->regs[7] = uc->uc_mcontext.regs[7];
++      sc->regs[8] = uc->uc_mcontext.regs[8];
++      sc->regs[9] = uc->uc_mcontext.regs[9];
++      sc->regs[10] = uc->uc_mcontext.regs[10];
++      sc->regs[11] = uc->uc_mcontext.regs[11];
++      sc->regs[12] = uc->uc_mcontext.regs[12];
++      sc->regs[13] = uc->uc_mcontext.regs[13];
++      sc->regs[14] = uc->uc_mcontext.regs[14];
++      sc->regs[15] = uc->uc_mcontext.regs[15];
++      sc->regs[16] = uc->uc_mcontext.regs[16];
++      sc->regs[17] = uc->uc_mcontext.regs[17];
++      sc->regs[18] = uc->uc_mcontext.regs[18];
++      sc->regs[19] = uc->uc_mcontext.regs[19];
++      sc->regs[20] = uc->uc_mcontext.regs[20];
++      sc->regs[21] = uc->uc_mcontext.regs[21];
++      sc->regs[22] = uc->uc_mcontext.regs[22];
++      sc->regs[23] = uc->uc_mcontext.regs[23];
++      sc->regs[24] = uc->uc_mcontext.regs[24];
++      sc->regs[25] = uc->uc_mcontext.regs[25];
++      sc->regs[26] = uc->uc_mcontext.regs[26];
++      sc->regs[27] = uc->uc_mcontext.regs[27];
++      sc->regs[28] = uc->uc_mcontext.regs[28];
++      sc->regs[29] = uc->uc_mcontext.regs[29];
++      sc->regs[30] = uc->uc_mcontext.regs[30];
++      sc->sp = uc->uc_mcontext.sp;
++      sc->pc = uc->uc_mcontext.pc;
++      sc->pstate = uc->uc_mcontext.pstate;
++
++      asm volatile (
++        "mov sp, %0\n"
++        "ret %1\n"
++        : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc)
++      );
++   }
++  __builtin_unreachable();
++#else
++  printf ("%s: implement me\n", __FUNCTION__);
++#endif
++  return -UNW_EINVAL;
++}
++
++#endif /* !UNW_REMOTE_ONLY */
++
++static inline void
++establish_machine_state (struct cursor *c)
++{
++  unw_addr_space_t as = c->dwarf.as;
++  void *arg = c->dwarf.as_arg;
++  unw_fpreg_t fpval;
++  unw_word_t val;
++  int reg;
++
++  Debug (8, "copying out cursor state\n");
++
++  for (reg = 0; reg <= UNW_AARCH64_PSTATE; ++reg)
++    {
++      Debug (16, "copying %s %d\n", unw_regname (reg), reg);
++      if (unw_is_fpreg (reg))
++      {
++        if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
++          as->acc.access_fpreg (as, reg, &fpval, 1, arg);
++      }
++      else
++      {
++        if (tdep_access_reg (c, reg, &val, 0) >= 0)
++          as->acc.access_reg (as, reg, &val, 1, arg);
++      }
++    }
++}
++
++PROTECTED int
++unw_resume (unw_cursor_t *cursor)
++{
++  struct cursor *c = (struct cursor *) cursor;
++
++  Debug (1, "(cursor=%p)\n", c);
++
++  if (!c->dwarf.ip)
++    {
++      /* This can happen easily when the frame-chain gets truncated
++       due to bad or missing unwind-info.  */
++      Debug (1, "refusing to resume execution at address 0\n");
++      return -UNW_EINVAL;
++    }
++
++  establish_machine_state (c);
++
++  return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
++                                   c->dwarf.as_arg);
++}
+diff --git a/src/aarch64/Gstep.c b/src/aarch64/Gstep.c
+new file mode 100644
+index 0000000..4aa15d1
+--- /dev/null
++++ b/src/aarch64/Gstep.c
+@@ -0,0 +1,129 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2011-2013 Linaro Limited
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++#include "offsets.h"
++
++PROTECTED int
++unw_handle_signal_frame (unw_cursor_t *cursor)
++{
++  struct cursor *c = (struct cursor *) cursor;
++  int ret;
++  unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
++  struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0);
++
++  if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0)
++    return -UNW_EUNSPEC;
++
++  ret = unw_is_signal_frame (cursor);
++  Debug(1, "unw_is_signal_frame()=%d\n", ret);
++
++  /* Save the SP and PC to be able to return execution at this point
++     later in time (unw_resume).  */
++  c->sigcontext_sp = c->dwarf.cfa;
++  c->sigcontext_pc = c->dwarf.ip;
++
++  if (ret)
++    {
++      c->sigcontext_format = AARCH64_SCF_LINUX_RT_SIGFRAME;
++      sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF;
++    }
++  else
++    return -UNW_EUNSPEC;
++
++  c->sigcontext_addr = sc_addr;
++
++  /* Update the dwarf cursor.
++     Set the location of the registers to the corresponding addresses of the
++     uc_mcontext / sigcontext structure contents.  */
++  c->dwarf.loc[UNW_AARCH64_X0]  = DWARF_LOC (sc_addr + LINUX_SC_X0_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X1]  = DWARF_LOC (sc_addr + LINUX_SC_X1_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X2]  = DWARF_LOC (sc_addr + LINUX_SC_X2_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X3]  = DWARF_LOC (sc_addr + LINUX_SC_X3_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X4]  = DWARF_LOC (sc_addr + LINUX_SC_X4_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X5]  = DWARF_LOC (sc_addr + LINUX_SC_X5_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X6]  = DWARF_LOC (sc_addr + LINUX_SC_X6_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X7]  = DWARF_LOC (sc_addr + LINUX_SC_X7_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X8]  = DWARF_LOC (sc_addr + LINUX_SC_X8_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X9]  = DWARF_LOC (sc_addr + LINUX_SC_X9_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X10] = DWARF_LOC (sc_addr + LINUX_SC_X10_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X11] = DWARF_LOC (sc_addr + LINUX_SC_X11_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X12] = DWARF_LOC (sc_addr + LINUX_SC_X12_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X13] = DWARF_LOC (sc_addr + LINUX_SC_X13_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X14] = DWARF_LOC (sc_addr + LINUX_SC_X14_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X15] = DWARF_LOC (sc_addr + LINUX_SC_X15_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X16] = DWARF_LOC (sc_addr + LINUX_SC_X16_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X17] = DWARF_LOC (sc_addr + LINUX_SC_X17_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X18] = DWARF_LOC (sc_addr + LINUX_SC_X18_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X19] = DWARF_LOC (sc_addr + LINUX_SC_X19_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X20] = DWARF_LOC (sc_addr + LINUX_SC_X20_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X21] = DWARF_LOC (sc_addr + LINUX_SC_X21_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X22] = DWARF_LOC (sc_addr + LINUX_SC_X22_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X23] = DWARF_LOC (sc_addr + LINUX_SC_X23_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X24] = DWARF_LOC (sc_addr + LINUX_SC_X24_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X25] = DWARF_LOC (sc_addr + LINUX_SC_X25_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X26] = DWARF_LOC (sc_addr + LINUX_SC_X26_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X27] = DWARF_LOC (sc_addr + LINUX_SC_X27_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X28] = DWARF_LOC (sc_addr + LINUX_SC_X28_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X29] = DWARF_LOC (sc_addr + LINUX_SC_X29_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_X30] = DWARF_LOC (sc_addr + LINUX_SC_X30_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_SP]  = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_PC]  = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0);
++  c->dwarf.loc[UNW_AARCH64_PSTATE]  = DWARF_LOC (sc_addr + LINUX_SC_PSTATE_OFF, 0);
++
++  /* Set SP/CFA and PC/IP.  */
++  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa);
++  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip);
++
++  c->dwarf.pi_valid = 0;
++
++  return 1;
++}
++
++PROTECTED int
++unw_step (unw_cursor_t *cursor)
++{
++  struct cursor *c = (struct cursor *) cursor;
++  int ret;
++
++  Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n",
++       c, c->dwarf.ip, c->dwarf.cfa);
++
++  /* Check if this is a signal frame. */
++  if (unw_is_signal_frame (cursor))
++    return unw_handle_signal_frame (cursor);
++
++  ret = dwarf_step (&c->dwarf);
++  Debug(1, "dwarf_step()=%d\n", ret);
++
++  if (unlikely (ret == -UNW_ESTOPUNWIND))
++    return ret;
++
++  if (unlikely (ret < 0))
++    return 0;
++
++  return (c->dwarf.ip == 0) ? 0 : 1;
++}
+diff --git a/src/aarch64/Lcreate_addr_space.c b/src/aarch64/Lcreate_addr_space.c
+new file mode 100644
+index 0000000..0f2dc6b
+--- /dev/null
++++ b/src/aarch64/Lcreate_addr_space.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gcreate_addr_space.c"
++#endif
+diff --git a/src/aarch64/Lget_proc_info.c b/src/aarch64/Lget_proc_info.c
+new file mode 100644
+index 0000000..69028b0
+--- /dev/null
++++ b/src/aarch64/Lget_proc_info.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gget_proc_info.c"
++#endif
+diff --git a/src/aarch64/Lget_save_loc.c b/src/aarch64/Lget_save_loc.c
+new file mode 100644
+index 0000000..9ea048a
+--- /dev/null
++++ b/src/aarch64/Lget_save_loc.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gget_save_loc.c"
++#endif
+diff --git a/src/aarch64/Lglobal.c b/src/aarch64/Lglobal.c
+new file mode 100644
+index 0000000..6d7b489
+--- /dev/null
++++ b/src/aarch64/Lglobal.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gglobal.c"
++#endif
+diff --git a/src/aarch64/Linit.c b/src/aarch64/Linit.c
+new file mode 100644
+index 0000000..e9abfdd
+--- /dev/null
++++ b/src/aarch64/Linit.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Ginit.c"
++#endif
+diff --git a/src/aarch64/Linit_local.c b/src/aarch64/Linit_local.c
+new file mode 100644
+index 0000000..68a1687
+--- /dev/null
++++ b/src/aarch64/Linit_local.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Ginit_local.c"
++#endif
+diff --git a/src/aarch64/Linit_remote.c b/src/aarch64/Linit_remote.c
+new file mode 100644
+index 0000000..58cb04a
+--- /dev/null
++++ b/src/aarch64/Linit_remote.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Ginit_remote.c"
++#endif
+diff --git a/src/aarch64/Lis_signal_frame.c b/src/aarch64/Lis_signal_frame.c
+new file mode 100644
+index 0000000..b9a7c4f
+--- /dev/null
++++ b/src/aarch64/Lis_signal_frame.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gis_signal_frame.c"
++#endif
+diff --git a/src/aarch64/Lregs.c b/src/aarch64/Lregs.c
+new file mode 100644
+index 0000000..2c9c75c
+--- /dev/null
++++ b/src/aarch64/Lregs.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gregs.c"
++#endif
+diff --git a/src/aarch64/Lresume.c b/src/aarch64/Lresume.c
+new file mode 100644
+index 0000000..41a8cf0
+--- /dev/null
++++ b/src/aarch64/Lresume.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gresume.c"
++#endif
+diff --git a/src/aarch64/Lstep.c b/src/aarch64/Lstep.c
+new file mode 100644
+index 0000000..c1ac3c7
+--- /dev/null
++++ b/src/aarch64/Lstep.c
+@@ -0,0 +1,5 @@
++#define UNW_LOCAL_ONLY
++#include <libunwind.h>
++#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
++#include "Gstep.c"
++#endif
+diff --git a/src/aarch64/gen-offsets.c b/src/aarch64/gen-offsets.c
+new file mode 100644
+index 0000000..eadc237
+--- /dev/null
++++ b/src/aarch64/gen-offsets.c
+@@ -0,0 +1,68 @@
++#include <stdio.h>
++#include <stddef.h>
++#include <ucontext.h>
++#include <asm/sigcontext.h>
++
++#define UC(N,X) \
++  printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X))
++
++#define SC(N,X) \
++  printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X))
++
++int
++main (void)
++{
++  printf (
++"/* Linux-specific definitions: */\n\n"
++
++"/* Define various structure offsets to simplify cross-compilation.  */\n\n"
++
++"/* Offsets for AArch64 Linux \"ucontext_t\":  */\n\n");
++
++  UC ("FLAGS", uc_flags);
++  UC ("LINK", uc_link);
++  UC ("STACK", uc_stack);
++  UC ("MCONTEXT", uc_mcontext);
++  UC ("SIGMASK", uc_sigmask);
++
++  printf ("\n/* Offsets for AArch64 Linux \"struct sigcontext\":  */\n\n");
++
++  SC ("R0",  regs[0]);
++  SC ("R1",  regs[1]);
++  SC ("R2",  regs[2]);
++  SC ("R3",  regs[3]);
++  SC ("R4",  regs[4]);
++  SC ("R5",  regs[5]);
++  SC ("R6",  regs[6]);
++  SC ("R7",  regs[7]);
++  SC ("R8",  regs[8]);
++  SC ("R9",  regs[9]);
++  SC ("R10", regs[10]);
++  SC ("R11", regs[11]);
++  SC ("R12", regs[12]);
++  SC ("R13", regs[13]);
++  SC ("R14", regs[14]);
++  SC ("R15", regs[15]);
++  SC ("R16", regs[16]);
++  SC ("R17", regs[17]);
++  SC ("R18", regs[18]);
++  SC ("R19", regs[19]);
++  SC ("R20", regs[20]);
++  SC ("R21", regs[21]);
++  SC ("R22", regs[22]);
++  SC ("R23", regs[23]);
++  SC ("R24", regs[24]);
++  SC ("R25", regs[25]);
++  SC ("R26", regs[26]);
++  SC ("R27", regs[27]);
++  SC ("R28", regs[28]);
++  SC ("R29", regs[29]);
++  SC ("R30", regs[30]);
++  SC ("R31", regs[31]);
++
++  SC ("PC", pc);
++  SC ("SP", sp);
++  SC ("Fault", fault_address);
++  SC ("state", pstate);
++  return 0;
++}
+diff --git a/src/aarch64/init.h b/src/aarch64/init.h
+new file mode 100644
+index 0000000..0cedc1a
+--- /dev/null
++++ b/src/aarch64/init.h
+@@ -0,0 +1,127 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++
++static inline int
++common_init (struct cursor *c, unsigned use_prev_instr)
++{
++  int ret, i;
++
++  c->dwarf.loc[UNW_AARCH64_X0]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X0);
++  c->dwarf.loc[UNW_AARCH64_X1]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X1);
++  c->dwarf.loc[UNW_AARCH64_X2]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X2);
++  c->dwarf.loc[UNW_AARCH64_X3]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X3);
++  c->dwarf.loc[UNW_AARCH64_X4]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X4);
++  c->dwarf.loc[UNW_AARCH64_X5]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X5);
++  c->dwarf.loc[UNW_AARCH64_X6]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X6);
++  c->dwarf.loc[UNW_AARCH64_X7]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X7);
++  c->dwarf.loc[UNW_AARCH64_X8]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X8);
++  c->dwarf.loc[UNW_AARCH64_X9]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X9);
++  c->dwarf.loc[UNW_AARCH64_X10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X10);
++  c->dwarf.loc[UNW_AARCH64_X11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X11);
++  c->dwarf.loc[UNW_AARCH64_X12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X12);
++  c->dwarf.loc[UNW_AARCH64_X13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X13);
++  c->dwarf.loc[UNW_AARCH64_X14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X14);
++  c->dwarf.loc[UNW_AARCH64_X15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X15);
++  c->dwarf.loc[UNW_AARCH64_X16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X16);
++  c->dwarf.loc[UNW_AARCH64_X17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X17);
++  c->dwarf.loc[UNW_AARCH64_X18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X18);
++  c->dwarf.loc[UNW_AARCH64_X19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X19);
++  c->dwarf.loc[UNW_AARCH64_X20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X20);
++  c->dwarf.loc[UNW_AARCH64_X21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X21);
++  c->dwarf.loc[UNW_AARCH64_X22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X22);
++  c->dwarf.loc[UNW_AARCH64_X23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X23);
++  c->dwarf.loc[UNW_AARCH64_X24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X24);
++  c->dwarf.loc[UNW_AARCH64_X25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X25);
++  c->dwarf.loc[UNW_AARCH64_X26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X26);
++  c->dwarf.loc[UNW_AARCH64_X27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X27);
++  c->dwarf.loc[UNW_AARCH64_X28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X28);
++  c->dwarf.loc[UNW_AARCH64_X29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X29);
++  c->dwarf.loc[UNW_AARCH64_X30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X30);
++  c->dwarf.loc[UNW_AARCH64_SP]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_SP);
++  c->dwarf.loc[UNW_AARCH64_PC]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_PC);
++  c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_REG_LOC (&c->dwarf,
++                                                    UNW_AARCH64_PSTATE);
++  c->dwarf.loc[UNW_AARCH64_V0]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V0);
++  c->dwarf.loc[UNW_AARCH64_V1]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V1);
++  c->dwarf.loc[UNW_AARCH64_V2]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V2);
++  c->dwarf.loc[UNW_AARCH64_V3]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V3);
++  c->dwarf.loc[UNW_AARCH64_V4]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V4);
++  c->dwarf.loc[UNW_AARCH64_V5]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V5);
++  c->dwarf.loc[UNW_AARCH64_V6]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V6);
++  c->dwarf.loc[UNW_AARCH64_V7]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V7);
++  c->dwarf.loc[UNW_AARCH64_V8]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V8);
++  c->dwarf.loc[UNW_AARCH64_V9]  = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V9);
++  c->dwarf.loc[UNW_AARCH64_V10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V10);
++  c->dwarf.loc[UNW_AARCH64_V11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V11);
++  c->dwarf.loc[UNW_AARCH64_V12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V12);
++  c->dwarf.loc[UNW_AARCH64_V13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V13);
++  c->dwarf.loc[UNW_AARCH64_V14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V14);
++  c->dwarf.loc[UNW_AARCH64_V15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V15);
++  c->dwarf.loc[UNW_AARCH64_V16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V16);
++  c->dwarf.loc[UNW_AARCH64_V17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V17);
++  c->dwarf.loc[UNW_AARCH64_V18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V18);
++  c->dwarf.loc[UNW_AARCH64_V19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V19);
++  c->dwarf.loc[UNW_AARCH64_V20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V20);
++  c->dwarf.loc[UNW_AARCH64_V21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V21);
++  c->dwarf.loc[UNW_AARCH64_V22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V22);
++  c->dwarf.loc[UNW_AARCH64_V23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V23);
++  c->dwarf.loc[UNW_AARCH64_V24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V24);
++  c->dwarf.loc[UNW_AARCH64_V25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V25);
++  c->dwarf.loc[UNW_AARCH64_V26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V26);
++  c->dwarf.loc[UNW_AARCH64_V27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V27);
++  c->dwarf.loc[UNW_AARCH64_V28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V28);
++  c->dwarf.loc[UNW_AARCH64_V29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V29);
++  c->dwarf.loc[UNW_AARCH64_V30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V30);
++  c->dwarf.loc[UNW_AARCH64_V31] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V31);
++
++  for (i = UNW_AARCH64_PSTATE + 1; i < UNW_AARCH64_V0; ++i)
++    c->dwarf.loc[i] = DWARF_NULL_LOC;
++
++  ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip);
++  if (ret < 0)
++    return ret;
++
++  ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa);
++  if (ret < 0)
++    return ret;
++
++  c->sigcontext_format = AARCH64_SCF_NONE;
++  c->sigcontext_addr = 0;
++  c->sigcontext_sp = 0;
++  c->sigcontext_pc = 0;
++
++  c->dwarf.args_size = 0;
++  c->dwarf.ret_addr_column = 0;
++  c->dwarf.stash_frames = 0;
++  c->dwarf.use_prev_instr = use_prev_instr;
++  c->dwarf.pi_valid = 0;
++  c->dwarf.pi_is_dynamic = 0;
++  c->dwarf.hint = 0;
++  c->dwarf.prev_rs = 0;
++
++  return 0;
++}
+diff --git a/src/aarch64/is_fpreg.c b/src/aarch64/is_fpreg.c
+new file mode 100644
+index 0000000..7c32693
+--- /dev/null
++++ b/src/aarch64/is_fpreg.c
+@@ -0,0 +1,32 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "libunwind_i.h"
++
++PROTECTED int
++unw_is_fpreg (int regnum)
++{
++  return (regnum >= UNW_AARCH64_V0 && regnum <= UNW_AARCH64_V31);
++}
+diff --git a/src/aarch64/offsets.h b/src/aarch64/offsets.h
+new file mode 100644
+index 0000000..81aa74f
+--- /dev/null
++++ b/src/aarch64/offsets.h
+@@ -0,0 +1,49 @@
++/* Linux-specific definitions: */
++
++/* Define various structure offsets to simplify cross-compilation.  */
++
++/* Offsets for AArch64 Linux "ucontext_t":  */
++
++#define LINUX_UC_FLAGS_OFF    0x0
++#define LINUX_UC_LINK_OFF     0x8
++#define LINUX_UC_STACK_OFF    0x10
++#define LINUX_UC_SIGMASK_OFF  0x28
++#define LINUX_UC_MCONTEXT_OFF 0xb0
++
++/* Offsets for AArch64 Linux "struct sigcontext":  */
++
++#define LINUX_SC_FAULTADDRESS_OFF     0x00
++#define LINUX_SC_X0_OFF               0x008
++#define LINUX_SC_X1_OFF               0x010
++#define LINUX_SC_X2_OFF               0x018
++#define LINUX_SC_X3_OFF               0x020
++#define LINUX_SC_X4_OFF               0x028
++#define LINUX_SC_X5_OFF               0x030
++#define LINUX_SC_X6_OFF               0x038
++#define LINUX_SC_X7_OFF               0x040
++#define LINUX_SC_X8_OFF               0x048
++#define LINUX_SC_X9_OFF               0x050
++#define LINUX_SC_X10_OFF      0x058
++#define LINUX_SC_X11_OFF      0x060
++#define LINUX_SC_X12_OFF      0x068
++#define LINUX_SC_X13_OFF      0x070
++#define LINUX_SC_X14_OFF      0x078
++#define LINUX_SC_X15_OFF      0x080
++#define LINUX_SC_X16_OFF      0x088
++#define LINUX_SC_X17_OFF      0x090
++#define LINUX_SC_X18_OFF      0x098
++#define LINUX_SC_X19_OFF      0x0a0
++#define LINUX_SC_X20_OFF      0x0a8
++#define LINUX_SC_X21_OFF      0x0b0
++#define LINUX_SC_X22_OFF      0x0b8
++#define LINUX_SC_X23_OFF      0x0c0
++#define LINUX_SC_X24_OFF      0x0c8
++#define LINUX_SC_X25_OFF      0x0d0
++#define LINUX_SC_X26_OFF      0x0d8
++#define LINUX_SC_X27_OFF      0x0e0
++#define LINUX_SC_X28_OFF      0x0e8
++#define LINUX_SC_X29_OFF      0x0f0
++#define LINUX_SC_X30_OFF      0x0f8
++#define LINUX_SC_SP_OFF               0x100
++#define LINUX_SC_PC_OFF               0x108
++#define LINUX_SC_PSTATE_OFF   0x110
+diff --git a/src/aarch64/regname.c b/src/aarch64/regname.c
+new file mode 100644
+index 0000000..8c97342
+--- /dev/null
++++ b/src/aarch64/regname.c
+@@ -0,0 +1,106 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#include "unwind_i.h"
++
++static const char *const regname[] =
++  {
++    [UNW_AARCH64_X0] = "x0",
++    [UNW_AARCH64_X1] = "x1",
++    [UNW_AARCH64_X2] = "x2",
++    [UNW_AARCH64_X3] = "x3",
++    [UNW_AARCH64_X4] = "x4",
++    [UNW_AARCH64_X5] = "x5",
++    [UNW_AARCH64_X6] = "x6",
++    [UNW_AARCH64_X7] = "x7",
++    [UNW_AARCH64_X8] = "x8",
++    [UNW_AARCH64_X9] = "x9",
++    [UNW_AARCH64_X10] = "x10",
++    [UNW_AARCH64_X11] = "x11",
++    [UNW_AARCH64_X12] = "x12",
++    [UNW_AARCH64_X13] = "x13",
++    [UNW_AARCH64_X14] = "x14",
++    [UNW_AARCH64_X15] = "x15",
++    [UNW_AARCH64_X16] = "ip0",
++    [UNW_AARCH64_X17] = "ip1",
++    [UNW_AARCH64_X18] = "x18",
++    [UNW_AARCH64_X19] = "x19",
++    [UNW_AARCH64_X20] = "x20",
++    [UNW_AARCH64_X21] = "x21",
++    [UNW_AARCH64_X22] = "x22",
++    [UNW_AARCH64_X23] = "x23",
++    [UNW_AARCH64_X24] = "x24",
++    [UNW_AARCH64_X25] = "x25",
++    [UNW_AARCH64_X26] = "x26",
++    [UNW_AARCH64_X27] = "x27",
++    [UNW_AARCH64_X28] = "x28",
++    [UNW_AARCH64_X29] = "fp",
++    [UNW_AARCH64_X30] = "lr",
++    [UNW_AARCH64_SP] = "sp",
++    [UNW_AARCH64_PC] = "pc",
++    [UNW_AARCH64_V0] = "v0",
++    [UNW_AARCH64_V1] = "v1",
++    [UNW_AARCH64_V2] = "v2",
++    [UNW_AARCH64_V3] = "v3",
++    [UNW_AARCH64_V4] = "v4",
++    [UNW_AARCH64_V5] = "v5",
++    [UNW_AARCH64_V6] = "v6",
++    [UNW_AARCH64_V7] = "v7",
++    [UNW_AARCH64_V8] = "v8",
++    [UNW_AARCH64_V9] = "v9",
++    [UNW_AARCH64_V10] = "v10",
++    [UNW_AARCH64_V11] = "v11",
++    [UNW_AARCH64_V12] = "v12",
++    [UNW_AARCH64_V13] = "v13",
++    [UNW_AARCH64_V14] = "v14",
++    [UNW_AARCH64_V15] = "v15",
++    [UNW_AARCH64_V16] = "v16",
++    [UNW_AARCH64_V17] = "v17",
++    [UNW_AARCH64_V18] = "v18",
++    [UNW_AARCH64_V19] = "v19",
++    [UNW_AARCH64_V20] = "v20",
++    [UNW_AARCH64_V21] = "v21",
++    [UNW_AARCH64_V22] = "v22",
++    [UNW_AARCH64_V23] = "v23",
++    [UNW_AARCH64_V24] = "v24",
++    [UNW_AARCH64_V25] = "v25",
++    [UNW_AARCH64_V26] = "v26",
++    [UNW_AARCH64_V27] = "v27",
++    [UNW_AARCH64_V28] = "v28",
++    [UNW_AARCH64_V29] = "v29",
++    [UNW_AARCH64_V30] = "v30",
++    [UNW_AARCH64_V31] = "v31",
++    [UNW_AARCH64_FPSR] = "fpsr",
++    [UNW_AARCH64_FPCR] = "fpcr",
++  };
++
++PROTECTED const char *
++unw_regname (unw_regnum_t reg)
++{
++  if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL)
++    return regname[reg];
++  else
++    return "???";
++}
+diff --git a/src/aarch64/siglongjmp.S b/src/aarch64/siglongjmp.S
+new file mode 100644
+index 0000000..9985c4b
+--- /dev/null
++++ b/src/aarch64/siglongjmp.S
+@@ -0,0 +1,12 @@
++      /* Dummy implementation for now.  */
++
++      .global _UI_siglongjmp_cont
++      .global _UI_longjmp_cont
++
++_UI_siglongjmp_cont:
++_UI_longjmp_cont:
++      ret
++#ifdef __linux__
++ /* We do not need executable stack.  */
++ .section  .note.GNU-stack,"",%progbits
++#endif
+diff --git a/src/aarch64/unwind_i.h b/src/aarch64/unwind_i.h
+new file mode 100644
+index 0000000..e4947a3
+--- /dev/null
++++ b/src/aarch64/unwind_i.h
+@@ -0,0 +1,43 @@
++/* libunwind - a platform-independent unwind library
++   Copyright (C) 2008 CodeSourcery
++   Copyright (C) 2013 Linaro Limited
++
++This file is part of libunwind.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++"Software"), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
++
++#ifndef unwind_i_h
++#define unwind_i_h
++
++#include <stdint.h>
++
++#include <libunwind-aarch64.h>
++
++#include "libunwind_i.h"
++
++#define aarch64_lock                  UNW_OBJ(lock)
++#define aarch64_local_resume          UNW_OBJ(local_resume)
++#define aarch64_local_addr_space_init UNW_OBJ(local_addr_space_init)
++
++extern void aarch64_local_addr_space_init (void);
++extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
++                           void *arg);
++
++#endif /* unwind_i_h */
+diff --git a/src/coredump/_UCD_access_reg_linux.c b/src/coredump/_UCD_access_reg_linux.c
+index bc360ad..9dc0904 100644
+--- a/src/coredump/_UCD_access_reg_linux.c
++++ b/src/coredump/_UCD_access_reg_linux.c
+@@ -39,7 +39,10 @@ _UCD_access_reg (unw_addr_space_t as,
+       return -UNW_EINVAL;
+     }
+-#if defined(UNW_TARGET_ARM)
++#if defined(UNW_TARGET_AARCH64)
++  if (regnum < 0 || regnum >= UNW_AARCH64_FPCR)
++    goto badreg;
++#elif defined(UNW_TARGET_ARM)
+   if (regnum < 0 || regnum >= 16)
+     goto badreg;
+ #elif defined(UNW_TARGET_SH)
+diff --git a/src/ptrace/_UPT_reg_offset.c b/src/ptrace/_UPT_reg_offset.c
+index 765f7d5..ced4896 100644
+--- a/src/ptrace/_UPT_reg_offset.c
++++ b/src/ptrace/_UPT_reg_offset.c
+@@ -1,6 +1,7 @@
+ /* libunwind - a platform-independent unwind library
+    Copyright (C) 2003-2004 Hewlett-Packard Co
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
++   Copyright (C) 2013 Linaro Limited
+ This file is part of libunwind.
+@@ -501,6 +502,41 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] =
+     [UNW_ARM_R15]      = 0x3c,
+ #elif defined(UNW_TARGET_MIPS)
+ #elif defined(UNW_TARGET_SH)
++#elif defined(UNW_TARGET_AARCH64)
++    [UNW_AARCH64_X0]       = 0x00,
++    [UNW_AARCH64_X1]       = 0x08,
++    [UNW_AARCH64_X2]       = 0x10,
++    [UNW_AARCH64_X3]       = 0x18,
++    [UNW_AARCH64_X4]       = 0x20,
++    [UNW_AARCH64_X5]       = 0x28,
++    [UNW_AARCH64_X6]       = 0x30,
++    [UNW_AARCH64_X7]       = 0x38,
++    [UNW_AARCH64_X8]       = 0x40,
++    [UNW_AARCH64_X9]       = 0x48,
++    [UNW_AARCH64_X10]      = 0x50,
++    [UNW_AARCH64_X11]      = 0x58,
++    [UNW_AARCH64_X12]      = 0x60,
++    [UNW_AARCH64_X13]      = 0x68,
++    [UNW_AARCH64_X14]      = 0x70,
++    [UNW_AARCH64_X15]      = 0x78,
++    [UNW_AARCH64_X16]      = 0x80,
++    [UNW_AARCH64_X17]      = 0x88,
++    [UNW_AARCH64_X18]      = 0x90,
++    [UNW_AARCH64_X19]      = 0x98,
++    [UNW_AARCH64_X20]      = 0xa0,
++    [UNW_AARCH64_X21]      = 0xa8,
++    [UNW_AARCH64_X22]      = 0xb0,
++    [UNW_AARCH64_X23]      = 0xb8,
++    [UNW_AARCH64_X24]      = 0xc0,
++    [UNW_AARCH64_X25]      = 0xc8,
++    [UNW_AARCH64_X26]      = 0xd0,
++    [UNW_AARCH64_X27]      = 0xd8,
++    [UNW_AARCH64_X28]      = 0xe0,
++    [UNW_AARCH64_X29]      = 0xe8,
++    [UNW_AARCH64_X30]      = 0xf0,
++    [UNW_AARCH64_SP]       = 0xf8,
++    [UNW_AARCH64_PC]       = 0x100,
++    [UNW_AARCH64_PSTATE]   = 0x108
+ #else
+ # error Fix me.
+ #endif
diff --git a/libunwind/patches/libunwind-arm-register-rename.patch b/libunwind/patches/libunwind-arm-register-rename.patch
deleted file mode 100644 (file)
index 9d7b91c..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
---- libunwind-1.0.1/src/arm/init.h.orig        2012-02-15 18:33:08.000000000 -0500
-+++ libunwind-1.0.1/src/arm/init.h     2012-02-15 18:29:19.000000000 -0500
-@@ -29,26 +29,26 @@
- {
-   int ret, i;
--  c->dwarf.loc[R0] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R0);
--  c->dwarf.loc[R1] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R1);
--  c->dwarf.loc[R2] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R2);
--  c->dwarf.loc[R3] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R3);
--  c->dwarf.loc[R4] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R4);
--  c->dwarf.loc[R5] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R5);
--  c->dwarf.loc[R6] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R6);
--  c->dwarf.loc[R7] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R7);
--  c->dwarf.loc[R8] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R8);
--  c->dwarf.loc[R9] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R9);
--  c->dwarf.loc[R10] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R10);
--  c->dwarf.loc[R11] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R11);
--  c->dwarf.loc[R12] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R12);
--  c->dwarf.loc[R13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13);
--  c->dwarf.loc[R14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R14);
--  c->dwarf.loc[R15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R15);
--  for (i = R15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i)
-+  c->dwarf.loc[REG_R0] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R0);
-+  c->dwarf.loc[REG_R1] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R1);
-+  c->dwarf.loc[REG_R2] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R2);
-+  c->dwarf.loc[REG_R3] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R3);
-+  c->dwarf.loc[REG_R4] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R4);
-+  c->dwarf.loc[REG_R5] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R5);
-+  c->dwarf.loc[REG_R6] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R6);
-+  c->dwarf.loc[REG_R7] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R7);
-+  c->dwarf.loc[REG_R8] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R8);
-+  c->dwarf.loc[REG_R9] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R9);
-+  c->dwarf.loc[REG_R10] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R10);
-+  c->dwarf.loc[REG_R11] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R11);
-+  c->dwarf.loc[REG_R12] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R12);
-+  c->dwarf.loc[REG_R13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13);
-+  c->dwarf.loc[REG_R14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R14);
-+  c->dwarf.loc[REG_R15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R15);
-+  for (i = REG_R15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i)
-     c->dwarf.loc[i] = DWARF_NULL_LOC;
--  ret = dwarf_get (&c->dwarf, c->dwarf.loc[R15], &c->dwarf.ip);
-+  ret = dwarf_get (&c->dwarf, c->dwarf.loc[REG_R15], &c->dwarf.ip);
-   if (ret < 0)
-     return ret;
---- libunwind-1.0.1/src/arm/Gglobal.c.orig     2012-02-15 18:33:21.000000000 -0500
-+++ libunwind-1.0.1/src/arm/Gglobal.c  2012-02-15 18:28:27.000000000 -0500
-@@ -37,7 +37,8 @@
- HIDDEN uint8_t dwarf_to_unw_regnum_map[16] =
-   {
--    R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15
-+    REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
-+    REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15
-   };
- HIDDEN void
index ef68f64a81969955c9faf42e171e35a05d88afae..a463f49bf153cca1721ced46b9ac687ea32fec1a 100644 (file)
@@ -4,17 +4,30 @@ match src/setjmp/setjmp.c + include/tdep-x86_64/jmpbuf.h .
 
 google-perftools link only with libunwind.so.7 .
 
---- libunwind-1.0.1-orig/src/Makefile.am       2011-09-11 05:06:41.000000000 +0200
-+++ libunwind-1.0.1/src/Makefile.am    2011-09-15 13:55:42.000000000 +0200
+diff --git a/src/Makefile.am b/src/Makefile.am
+index adfbef3..08d2870 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
 @@ -1,5 +1,5 @@
- SOVERSION=8:0:0               # See comments at end of file.
+ SOVERSION=8:1:0               # See comments at end of file.
 -SETJMP_SO_VERSION=0:0:0
 +#SETJMP_SO_VERSION=0:0:0
+ COREDUMP_SO_VERSION=0:0:0
  #
  # Don't link with start-files since we don't use any constructors/destructors:
- #
-@@ -27,8 +27,8 @@ libunwind_ptrace_a_SOURCES =                                           \
- noinst_HEADERS += ptrace/_UPT_internal.h
+@@ -22,8 +22,8 @@ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = libunwind-generic.pc
+ if !REMOTE_ONLY
+-pkgconfig_DATA += unwind/libunwind.pc ptrace/libunwind-ptrace.pc         \
+-                  setjmp/libunwind-setjmp.pc
++pkgconfig_DATA += unwind/libunwind.pc ptrace/libunwind-ptrace.pc
++#                  setjmp/libunwind-setjmp.pc
+ endif
+ if BUILD_COREDUMP
+@@ -61,8 +61,8 @@ libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \
+ noinst_HEADERS += coredump/_UCD_internal.h
  
  ### libunwind-setjmp:
 -libunwind_setjmp_la_LDFLAGS           = $(COMMON_SO_LDFLAGS)               \
@@ -24,7 +37,7 @@ google-perftools link only with libunwind.so.7 .
  
  if USE_ELF32
  LIBUNWIND_ELF = libunwind-elf32.la
-@@ -40,12 +40,12 @@ if USE_ELFXX
+@@ -74,12 +74,12 @@ if USE_ELFXX
  LIBUNWIND_ELF = libunwind-elfxx.la
  endif
  
@@ -43,7 +56,7 @@ google-perftools link only with libunwind.so.7 .
  
  ### libunwind:
  libunwind_la_LIBADD =
-@@ -373,7 +373,7 @@ if ARCH_ARM
+@@ -428,7 +428,7 @@ if ARCH_ARM
  if !REMOTE_ONLY
   libunwind_arm_la_LIBADD += libunwind.la -lc
  endif
@@ -51,8 +64,8 @@ google-perftools link only with libunwind.so.7 .
 +# libunwind_setjmp_la_SOURCES += arm/siglongjmp.S
  else
  if ARCH_IA64
-  ia64_mk_Gcursor_i_SOURCES = ia64/mk_Gcursor_i.c
-@@ -393,8 +393,8 @@ Lcursor_i.h: ia64/mk_Lcursor_i
+  BUILT_SOURCES = Gcursor_i.h Lcursor_i.h
+@@ -449,8 +449,8 @@ Lcursor_i.h: mk_Lcursor_i.s
  if !REMOTE_ONLY
   libunwind_ia64_la_LIBADD += libunwind.la -lc
  endif
@@ -63,7 +76,7 @@ google-perftools link only with libunwind.so.7 .
  else
  if ARCH_HPPA
   lib_LTLIBRARIES += libunwind-hppa.la
-@@ -406,7 +406,7 @@ if ARCH_HPPA
+@@ -462,7 +462,7 @@ if ARCH_HPPA
  if !REMOTE_ONLY
   libunwind_hppa_la_LIBADD += libunwind.la -lc
  endif
@@ -72,7 +85,7 @@ google-perftools link only with libunwind.so.7 .
  else
  if ARCH_MIPS
   lib_LTLIBRARIES += libunwind-mips.la
-@@ -418,7 +418,7 @@ if ARCH_MIPS
+@@ -474,7 +474,7 @@ if ARCH_MIPS
  if !REMOTE_ONLY
   libunwind_mips_la_LIBADD += libunwind.la -lc
  endif
@@ -81,7 +94,7 @@ google-perftools link only with libunwind.so.7 .
  else
  if ARCH_X86
   lib_LTLIBRARIES += libunwind-x86.la
-@@ -430,7 +430,7 @@ if ARCH_X86
+@@ -486,7 +486,7 @@ if ARCH_X86
  if !REMOTE_ONLY
   libunwind_x86_la_LIBADD += libunwind.la -lc
  endif
@@ -90,7 +103,7 @@ google-perftools link only with libunwind.so.7 .
  else
  if ARCH_X86_64
   lib_LTLIBRARIES += libunwind-x86_64.la
-@@ -442,7 +442,7 @@ if ARCH_X86_64
+@@ -498,7 +498,7 @@ if ARCH_X86_64
  if !REMOTE_ONLY
   libunwind_x86_64_la_LIBADD += libunwind.la -lc
  endif
@@ -99,7 +112,7 @@ google-perftools link only with libunwind.so.7 .
  else
  if ARCH_PPC32
   lib_LTLIBRARIES += libunwind-ppc32.la
-@@ -454,7 +454,7 @@ if ARCH_PPC32
+@@ -510,7 +510,7 @@ if ARCH_PPC32
  if !REMOTE_ONLY
   libunwind_ppc32_la_LIBADD += libunwind.la -lc
  endif
@@ -108,16 +121,25 @@ google-perftools link only with libunwind.so.7 .
  else
  if ARCH_PPC64
   lib_LTLIBRARIES += libunwind-ppc64.la
-@@ -466,7 +466,7 @@ if ARCH_PPC64
+@@ -522,7 +522,7 @@ if ARCH_PPC64
  if !REMOTE_ONLY
   libunwind_ppc64_la_LIBADD += libunwind.la -lc
  endif
 - libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S
 +# libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S
+ else
+ if ARCH_SH
+  lib_LTLIBRARIES += libunwind-sh.la
+@@ -534,7 +534,7 @@ if ARCH_SH
+ if !REMOTE_ONLY
+  libunwind_sh_la_LIBADD += libunwind.la -lc
+ endif
+- libunwind_setjmp_la_SOURCES += sh/siglongjmp.S
++# libunwind_setjmp_la_SOURCES += sh/siglongjmp.S
  
+ endif # ARCH_SH
  endif # ARCH_PPC64
- endif # ARCH_PPC32
-@@ -480,7 +480,7 @@ endif # ARCH_ARM
+@@ -549,7 +549,7 @@ endif # ARCH_ARM
  # libunwind-setjmp depends on libunwind-$(arch). Therefore must be added
  # at the end.
  if !REMOTE_ONLY
@@ -126,29 +148,20 @@ google-perftools link only with libunwind.so.7 .
  endif
  
  #
---- libunwind-1.0.1-orig/tests/Makefile.am     2011-09-11 05:06:41.000000000 +0200
-+++ libunwind-1.0.1/tests/Makefile.am  2011-09-15 13:56:16.000000000 +0200
-@@ -27,7 +27,7 @@ if ARCH_IA64
-                       Gia64-test-nat Lia64-test-nat                   \
-                       Gia64-test-rbs Lia64-test-rbs                   \
-                       Gia64-test-readonly Lia64-test-readonly         \
--                      ia64-test-setjmp ia64-test-sig
-+                      ia64-test-sig
- else
- if ARCH_PPC64
- if USE_ALTIVEC
-@@ -44,8 +44,9 @@ endif #ARCH_IA64
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index a367eed..3f47e80 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -45,7 +45,7 @@ endif #!ARCH_IA64
                        Gtest-dyn1 Ltest-dyn1                            \
                        Gtest-trace Ltest-trace                          \
                        test-async-sig test-flush-cache test-init-remote \
--                      test-mem test-setjmp test-ptrace                 \
-+                      test-mem test-ptrace             \
-                       Ltest-nomalloc Ltest-nocalloc rs-race
-+# test-setjmp
-  noinst_PROGRAMS_cdep = forker mapper test-ptrace-misc                         \
+-                      test-mem test-setjmp test-ptrace Ltest-varargs   \
++                      test-mem test-ptrace Ltest-varargs               \
+                       Ltest-nomalloc Ltest-nocalloc Lrs-race
+  noinst_PROGRAMS_cdep = forker crasher mapper test-ptrace-misc                 \
                        Gperf-simple Lperf-simple
-@@ -123,8 +124,8 @@ if USE_ELFXX
+@@ -134,8 +134,8 @@ if USE_ELFXX
  LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elfxx.la
  endif
  
@@ -159,7 +172,7 @@ google-perftools link only with libunwind.so.7 .
  
  test_async_sig_LDADD = $(LIBUNWIND_local) -lpthread
  test_flush_cache_LDADD = $(LIBUNWIND_local)
-@@ -159,6 +160,6 @@ Lperf_simple_LDADD = $(LIBUNWIND_local)
+@@ -172,8 +172,8 @@ Lperf_simple_LDADD = $(LIBUNWIND_local)
  Ltest_trace_LDADD = $(LIBUNWIND_local)
  Lperf_trace_LDADD = $(LIBUNWIND_local)
  
@@ -168,3 +181,5 @@ google-perftools link only with libunwind.so.7 .
 +#test_setjmp_LDADD = $(LIBUNWIND_setjmp)
 +#ia64_test_setjmp_LDADD = $(LIBUNWIND_setjmp)
  
+ if BUILD_COREDUMP
+ test_coredump_unwind_LDADD = $(LIBUNWIND_coredump) $(LIBUNWIND)
index b907dbf7dbc8821695c7539e1e614d3b4ee9787d..c36ba5d23e1242a57146bb150c794a2e59416b88 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = libxml2
-version    = 2.7.8
+version    = 2.9.2
 release    = 2
 
 groups     = System/Libraries
diff --git a/libxml2/patches/libxml2-2.7.7-xpath-double-free.patch b/libxml2/patches/libxml2-2.7.7-xpath-double-free.patch
deleted file mode 100644 (file)
index c5dbbee..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/xpath.c  
-+++ a/xpath.c  
-@@ -11763,11 +11763,16 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
-           if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
-               xmlXPathObjectPtr tmp;
--              /* pop the result */
-+              /* pop the result if any */
-               tmp = valuePop(ctxt);
--              xmlXPathReleaseObject(xpctxt, tmp);
--              /* then pop off contextObj, which will be freed later */
--              valuePop(ctxt);
-+                if (tmp != contextObj) {
-+                    /*
-+                     * Free up the result
-+                     * then pop off contextObj, which will be freed later
-+                     */
-+                    xmlXPathReleaseObject(xpctxt, tmp);
-+                    valuePop(ctxt);
-+                }
-               goto evaluation_error;
-           }
diff --git a/libxml2/patches/libxml2-2.9.2-catalog-revert.patch b/libxml2/patches/libxml2-2.9.2-catalog-revert.patch
new file mode 100644 (file)
index 0000000..b3de004
--- /dev/null
@@ -0,0 +1,31 @@
+From 0e6659ec960734b0b01aad196d4bdb4a3800b493 Mon Sep 17 00:00:00 2001
+From: Lubomir Rintel <lkundrak@v3.sk>
+Date: Thu, 16 Oct 2014 19:10:59 +0200
+Subject: [PATCH] Revert "Missing initialization for the catalog module"
+
+It's not correct to always load the default catalog.
+https://bugzilla.redhat.com/show_bug.cgi?id=1153753
+
+This reverts commit 054c716ea1bf001544127a4ab4f4346d1b9947e7.
+
+---
+ parser.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 1d93967..67c9dfd 100644
+--- a/parser.c
++++ b/parser.c
+@@ -14830,9 +14830,6 @@ xmlInitParser(void) {
+ #ifdef LIBXML_XPATH_ENABLED
+       xmlXPathInit();
+ #endif
+-#ifdef LIBXML_CATALOG_ENABLED
+-        xmlInitializeCatalog();
+-#endif
+       xmlParserInitialized = 1;
+ #ifdef LIBXML_THREAD_ENABLED
+     }
+-- 
+1.9.3
+
index 63b035a4e03ec7ea57cd2c84f73921d92cc0102f..a2c82705d69765063a8e7daf0e8c4c4cf4dba6ea 100644 (file)
@@ -7,8 +7,9 @@ name       = multipath-tools
 version    = %{rel_ver}.%{rel_date}
 release    = 1
 
+thisapp    = %{name}-%{rel_date}
 rel_ver    = 0.4.9
-rel_date   = 120613
+rel_date   = 130222
 
 groups     = System/Base
 url        = http://christophe.varoqui.free.fr/
@@ -20,8 +21,6 @@ description
        instructing the device-mapper multipath kernel module what to do.
 end
 
-thisapp    = %{name}-%{rel_date}
-
 sources    = %{thisapp}.tgz
 
 build
@@ -34,13 +33,10 @@ build
                readline-devel
        end
 
-       prepare_cmds
-               # Fix hardcoded install location for udev rules.
-               sed -e "s@lib/udev@usr/lib/udev@g" -i multipath/Makefile
-       end
+       make_build_targets += LIB=%{lib}
 
        # Install everything to the correct locations.
-       make_install_targets +=\
+       make_install_targets += \
                bindir=%{sbindir} \
                syslibdir=%{libdir} \
                libdir=%{libdir}/multipath \
diff --git a/multipath-tools/patches/0001-RH-dont_start_with_no_config.patch b/multipath-tools/patches/0001-RH-dont_start_with_no_config.patch
new file mode 100644 (file)
index 0000000..e894632
--- /dev/null
@@ -0,0 +1,16 @@
+---
+ multipathd/multipathd.service |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: multipath-tools-130222/multipathd/multipathd.service
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.service
++++ multipath-tools-130222/multipathd/multipathd.service
+@@ -2,6 +2,7 @@
+ Description=Device-Mapper Multipath Device Controller
+ Before=iscsi.service iscsid.service lvm2-activation-early.service
+ After=syslog.target
++ConditionPathExists=/etc/multipath.conf
+ DefaultDependencies=no
+ Conflicts=shutdown.target
diff --git a/multipath-tools/patches/0001-RH-remove_callout.patch b/multipath-tools/patches/0001-RH-remove_callout.patch
deleted file mode 100644 (file)
index 0c03cc4..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
----
- libmultipath/Makefile    |    2 
- libmultipath/callout.c   |  217 -----------------------------------------------
- libmultipath/callout.h   |    7 -
- libmultipath/discovery.c |    1 
- multipathd/main.c        |    1 
- 5 files changed, 1 insertion(+), 227 deletions(-)
-
-Index: multipath-tools-120518/libmultipath/Makefile
-===================================================================
---- multipath-tools-120518.orig/libmultipath/Makefile
-+++ multipath-tools-120518/libmultipath/Makefile
-@@ -9,7 +9,7 @@ DEVLIB = libmultipath.so
- LIBS = $(DEVLIB).$(SONAME)
- LIBDEPS = -lpthread -ldl -ldevmapper -ludev
--OBJS = memory.o parser.o vector.o devmapper.o callout.o \
-+OBJS = memory.o parser.o vector.o devmapper.o \
-        hwtable.o blacklist.o util.o dmparser.o config.o \
-        structs.o discovery.o propsel.o dict.o \
-        pgpolicies.o debug.o regex.o defaults.o uevent.o \
-Index: multipath-tools-120518/libmultipath/callout.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/callout.c
-+++ /dev/null
-@@ -1,217 +0,0 @@
--/*
-- * Source: copy of the udev package source file
-- *
-- * Copyrights of the source file apply
-- * Copyright (c) 2004 Christophe Varoqui
-- */
--#include <stdio.h>
--#include <sys/stat.h>
--#include <string.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <stdlib.h>
--#include <fcntl.h>
--#include <sys/wait.h>
--#include <errno.h>
--
--#include "checkers.h"
--#include "vector.h"
--#include "structs.h"
--#include "util.h"
--#include "debug.h"
--
--int execute_program(char *path, char *value, int len)
--{
--      int retval;
--      int count;
--      int status;
--      int fds[2], null_fd;
--      pid_t pid;
--      char *pos;
--      char arg[CALLOUT_MAX_SIZE];
--      int argc = sizeof(arg) / 2;
--      char *argv[argc + 1];
--      int i;
--
--      i = 0;
--
--      if (strchr(path, ' ')) {
--              strlcpy(arg, path, sizeof(arg));
--              pos = arg;
--              while (pos != NULL && i < argc) {
--                      if (pos[0] == '\'') {
--                              /* don't separate if in apostrophes */
--                              pos++;
--                              argv[i] = strsep(&pos, "\'");
--                              while (pos[0] == ' ')
--                                      pos++;
--                      } else {
--                              argv[i] = strsep(&pos, " ");
--                      }
--                      i++;
--              }
--      } else {
--              argv[i++] = path;
--      }
--      argv[i] =  NULL;
--
--      retval = pipe(fds);
--
--      if (retval != 0) {
--              condlog(0, "error creating pipe for callout: %s", strerror(errno));
--              return -1;
--      }
--
--      pid = fork();
--
--      switch(pid) {
--      case 0:
--              /* child */
--              close(STDOUT_FILENO);
--
--              /* dup write side of pipe to STDOUT */
--              if (dup(fds[1]) < 0)
--                      return -1;
--
--              /* Ignore writes to stderr */
--              null_fd = open("/dev/null", O_WRONLY);
--              if (null_fd > 0) {
--                      close(STDERR_FILENO);
--                      dup(null_fd);
--                      close(null_fd);
--              }
--
--              retval = execv(argv[0], argv);
--              condlog(0, "error execing %s : %s", argv[0], strerror(errno));
--              exit(-1);
--      case -1:
--              condlog(0, "fork failed: %s", strerror(errno));
--              close(fds[0]);
--              close(fds[1]);
--              return -1;
--      default:
--              /* parent reads from fds[0] */
--              close(fds[1]);
--              retval = 0;
--              i = 0;
--              while (1) {
--                      count = read(fds[0], value + i, len - i-1);
--                      if (count <= 0)
--                              break;
--
--                      i += count;
--                      if (i >= len-1) {
--                              condlog(0, "not enough space for response from %s", argv[0]);
--                              retval = -1;
--                              break;
--                      }
--              }
--
--              if (count < 0) {
--                      condlog(0, "no response from %s", argv[0]);
--                      retval = -1;
--              }
--
--              if (i > 0 && value[i-1] == '\n')
--                      i--;
--              value[i] = '\0';
--
--              wait(&status);
--              close(fds[0]);
--
--              retval = -1;
--              if (WIFEXITED(status)) {
--                      status = WEXITSTATUS(status);
--                      if (status == 0)
--                              retval = 0;
--                      else
--                              condlog(0, "%s exitted with %d", argv[0], status);
--              }
--              else if (WIFSIGNALED(status))
--                      condlog(0, "%s was terminated by signal %d", argv[0], WTERMSIG(status));
--              else
--                      condlog(0, "%s terminated abnormally", argv[0]);
--      }
--      return retval;
--}
--
--extern int
--apply_format (char * string, char * cmd, struct path * pp)
--{
--      char * pos;
--      char * dst;
--      char * p;
--      char * q;
--      int len;
--      int myfree;
--
--      if (!string)
--              return 1;
--
--      if (!cmd)
--              return 1;
--
--      dst = cmd;
--      p = dst;
--      pos = strchr(string, '%');
--      myfree = CALLOUT_MAX_SIZE;
--
--      if (!pos) {
--              strcpy(dst, string);
--              return 0;
--      }
--
--      len = (int) (pos - string) + 1;
--      myfree -= len;
--
--      if (myfree < 2)
--              return 1;
--
--      snprintf(p, len, "%s", string);
--      p += len - 1;
--      pos++;
--
--      switch (*pos) {
--      case 'n':
--              len = strlen(pp->dev) + 1;
--              myfree -= len;
--
--              if (myfree < 2)
--                      return 1;
--
--              snprintf(p, len, "%s", pp->dev);
--              for (q = p; q < p + len; q++) {
--                      if (q && *q == '!')
--                              *q = '/';
--              }
--              p += len - 1;
--              break;
--      case 'd':
--              len = strlen(pp->dev_t) + 1;
--              myfree -= len;
--
--              if (myfree < 2)
--                      return 1;
--
--              snprintf(p, len, "%s", pp->dev_t);
--              p += len - 1;
--              break;
--      default:
--              break;
--      }
--      pos++;
--
--      if (!*pos)
--              return 0;
--
--      len = strlen(pos) + 1;
--      myfree -= len;
--
--      if (myfree < 2)
--              return 1;
--
--      snprintf(p, len, "%s", pos);
--      condlog(3, "reformated callout = %s", dst);
--      return 0;
--}
--
-Index: multipath-tools-120518/libmultipath/callout.h
-===================================================================
---- multipath-tools-120518.orig/libmultipath/callout.h
-+++ /dev/null
-@@ -1,7 +0,0 @@
--#ifndef _CALLOUT_H
--#define _CALLOUT_H
--
--int execute_program(char *, char *, int);
--int apply_format (char *, char *, struct path *);
--
--#endif /* _CALLOUT_H */
-Index: multipath-tools-120518/libmultipath/discovery.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/discovery.c
-+++ multipath-tools-120518/libmultipath/discovery.c
-@@ -20,7 +20,6 @@
- #include "structs.h"
- #include "config.h"
- #include "blacklist.h"
--#include "callout.h"
- #include "debug.h"
- #include "propsel.h"
- #include "sg_include.h"
-Index: multipath-tools-120518/multipathd/main.c
-===================================================================
---- multipath-tools-120518.orig/multipathd/main.c
-+++ multipath-tools-120518/multipathd/main.c
-@@ -35,7 +35,6 @@
- #include <hwtable.h>
- #include <defaults.h>
- #include <structs.h>
--#include <callout.h>
- #include <blacklist.h>
- #include <structs_vec.h>
- #include <dmparser.h>
diff --git a/multipath-tools/patches/0002-RH-add-wwids-file.patch b/multipath-tools/patches/0002-RH-add-wwids-file.patch
deleted file mode 100644 (file)
index f3014ba..0000000
+++ /dev/null
@@ -1,748 +0,0 @@
----
- libmultipath/Makefile    |    2 
- libmultipath/alias.c     |  153 ---------------------------------------
- libmultipath/alias.h     |    1 
- libmultipath/configure.c |    3 
- libmultipath/defaults.h  |    1 
- libmultipath/discovery.c |    2 
- libmultipath/file.c      |  180 +++++++++++++++++++++++++++++++++++++++++++++++
- libmultipath/file.h      |   11 ++
- libmultipath/wwids.c     |  139 ++++++++++++++++++++++++++++++++++++
- libmultipath/wwids.h     |   18 ++++
- multipath/main.c         |   37 ++++++++-
- 11 files changed, 389 insertions(+), 158 deletions(-)
-
-Index: multipath-tools-120518/libmultipath/alias.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/alias.c
-+++ multipath-tools-120518/libmultipath/alias.c
-@@ -3,19 +3,16 @@
-  * Copyright (c) 2005 Benjamin Marzinski, Redhat
-  */
- #include <stdlib.h>
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <fcntl.h>
- #include <errno.h>
- #include <unistd.h>
- #include <string.h>
- #include <limits.h>
- #include <stdio.h>
--#include <signal.h>
- #include "debug.h"
- #include "uxsock.h"
- #include "alias.h"
-+#include "file.h"
- /*
-@@ -36,150 +33,6 @@
-  * See the file COPYING included with this distribution for more details.
-  */
--static int
--ensure_directories_exist(char *str, mode_t dir_mode)
--{
--      char *pathname;
--      char *end;
--      int err;
--
--      pathname = strdup(str);
--      if (!pathname){
--              condlog(0, "Cannot copy bindings file pathname : %s",
--                      strerror(errno));
--              return -1;
--      }
--      end = pathname;
--      /* skip leading slashes */
--      while (end && *end && (*end == '/'))
--              end++;
--
--      while ((end = strchr(end, '/'))) {
--              /* if there is another slash, make the dir. */
--              *end = '\0';
--              err = mkdir(pathname, dir_mode);
--              if (err && errno != EEXIST) {
--                      condlog(0, "Cannot make directory [%s] : %s",
--                              pathname, strerror(errno));
--                      free(pathname);
--                      return -1;
--              }
--              if (!err)
--                      condlog(3, "Created dir [%s]", pathname);
--              *end = '/';
--              end++;
--      }
--      free(pathname);
--      return 0;
--}
--
--static void
--sigalrm(int sig)
--{
--      /* do nothing */
--}
--
--static int
--lock_bindings_file(int fd)
--{
--      struct sigaction act, oldact;
--      sigset_t set, oldset;
--      struct flock lock;
--      int err;
--
--      memset(&lock, 0, sizeof(lock));
--      lock.l_type = F_WRLCK;
--      lock.l_whence = SEEK_SET;
--
--      act.sa_handler = sigalrm;
--      sigemptyset(&act.sa_mask);
--      act.sa_flags = 0;
--      sigemptyset(&set);
--      sigaddset(&set, SIGALRM);
--
--      sigaction(SIGALRM, &act, &oldact);
--      sigprocmask(SIG_UNBLOCK, &set, &oldset);
--
--      alarm(BINDINGS_FILE_TIMEOUT);
--      err = fcntl(fd, F_SETLKW, &lock);
--      alarm(0);
--
--      if (err) {
--              if (errno != EINTR)
--                      condlog(0, "Cannot lock bindings file : %s",
--                                      strerror(errno));
--              else
--                      condlog(0, "Bindings file is locked. Giving up.");
--      }
--
--      sigprocmask(SIG_SETMASK, &oldset, NULL);
--      sigaction(SIGALRM, &oldact, NULL);
--      return err;
--
--}
--
--
--static int
--open_bindings_file(char *file, int *can_write)
--{
--      int fd;
--      struct stat s;
--
--      if (ensure_directories_exist(file, 0700))
--              return -1;
--      *can_write = 1;
--      fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
--      if (fd < 0) {
--              if (errno == EROFS) {
--                      *can_write = 0;
--                      condlog(3, "Cannot open bindings file [%s] read/write. "
--                              " trying readonly", file);
--                      fd = open(file, O_RDONLY);
--                      if (fd < 0) {
--                              condlog(0, "Cannot open bindings file [%s] "
--                                      "readonly : %s", file, strerror(errno));
--                              return -1;
--                      }
--              }
--              else {
--                      condlog(0, "Cannot open bindings file [%s] : %s", file,
--                              strerror(errno));
--                      return -1;
--              }
--      }
--      if (*can_write && lock_bindings_file(fd) < 0)
--              goto fail;
--
--      memset(&s, 0, sizeof(s));
--      if (fstat(fd, &s) < 0){
--              condlog(0, "Cannot stat bindings file : %s", strerror(errno));
--              goto fail;
--      }
--      if (s.st_size == 0) {
--              if (*can_write == 0)
--                      goto fail;
--              /* If bindings file is empty, write the header */
--              size_t len = strlen(BINDINGS_FILE_HEADER);
--              if (write_all(fd, BINDINGS_FILE_HEADER, len) != len) {
--                      condlog(0,
--                              "Cannot write header to bindings file : %s",
--                              strerror(errno));
--                      /* cleanup partially written header */
--                      if (ftruncate(fd, 0))
--                              condlog(0, "Cannot truncate the header : %s",
--                                      strerror(errno));
--                      goto fail;
--              }
--              fsync(fd);
--              condlog(3, "Initialized new bindings file [%s]", file);
--      }
--
--      return fd;
--
--fail:
--      close(fd);
--      return -1;
--}
- static int
- format_devname(char *name, int id, int len, char *prefix)
-@@ -370,7 +223,7 @@ get_user_friendly_alias(char *wwid, char
-               return NULL;
-       }
--      fd = open_bindings_file(file, &can_write);
-+      fd = open_file(file, &can_write, BINDINGS_FILE_HEADER);
-       if (fd < 0)
-               return NULL;
-@@ -414,7 +267,7 @@ get_user_friendly_wwid(char *alias, char
-               return NULL;
-       }
--      fd = open_bindings_file(file, &unused);
-+      fd = open_file(file, &unused, BINDINGS_FILE_HEADER);
-       if (fd < 0)
-               return NULL;
-Index: multipath-tools-120518/libmultipath/alias.h
-===================================================================
---- multipath-tools-120518.orig/libmultipath/alias.h
-+++ multipath-tools-120518/libmultipath/alias.h
-@@ -1,4 +1,3 @@
--#define BINDINGS_FILE_TIMEOUT 30
- #define BINDINGS_FILE_HEADER \
- "# Multipath bindings, Version : 1.0\n" \
- "# NOTE: this file is automatically maintained by the multipath program.\n" \
-Index: multipath-tools-120518/libmultipath/configure.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/configure.c
-+++ multipath-tools-120518/libmultipath/configure.c
-@@ -37,6 +37,7 @@
- #include "prio.h"
- #include "util.h"
- #include "uxsock.h"
-+#include "wwids.h"
- extern int
- setup_map (struct multipath * mpp, char * params, int params_size)
-@@ -407,6 +408,8 @@ domap (struct multipath * mpp, char * pa
-                * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
-                * succeeded
-                */
-+              if (mpp->action == ACT_CREATE)
-+                      remember_wwid(mpp->wwid);
-               if (!conf->daemon) {
-                       /* multipath client mode */
-                       dm_switchgroup(mpp->alias, mpp->bestpg);
-Index: multipath-tools-120518/libmultipath/defaults.h
-===================================================================
---- multipath-tools-120518.orig/libmultipath/defaults.h
-+++ multipath-tools-120518/libmultipath/defaults.h
-@@ -24,5 +24,6 @@
- #define DEFAULT_SOCKET                "/var/run/multipathd.sock"
- #define DEFAULT_CONFIGFILE    "/etc/multipath.conf"
- #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
-+#define DEFAULT_WWIDS_FILE    "/etc/multipath/wwids"
- char * set_default (char * str);
-Index: multipath-tools-120518/libmultipath/file.c
-===================================================================
---- /dev/null
-+++ multipath-tools-120518/libmultipath/file.c
-@@ -0,0 +1,180 @@
-+/*
-+ * Copyright (c) 2005 Christophe Varoqui
-+ * Copyright (c) 2005 Benjamin Marzinski, Redhat
-+ */
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <limits.h>
-+#include <stdio.h>
-+#include <signal.h>
-+
-+#include "file.h"
-+#include "debug.h"
-+#include "uxsock.h"
-+
-+
-+/*
-+ * significant parts of this file were taken from iscsi-bindings.c of the
-+ * linux-iscsi project.
-+ * Copyright (C) 2002 Cisco Systems, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published
-+ * by the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * 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 for more details.
-+ *
-+ * See the file COPYING included with this distribution for more details.
-+ */
-+
-+static int
-+ensure_directories_exist(char *str, mode_t dir_mode)
-+{
-+      char *pathname;
-+      char *end;
-+      int err;
-+
-+      pathname = strdup(str);
-+      if (!pathname){
-+              condlog(0, "Cannot copy file pathname %s : %s",
-+                      str, strerror(errno));
-+              return -1;
-+      }
-+      end = pathname;
-+      /* skip leading slashes */
-+      while (end && *end && (*end == '/'))
-+              end++;
-+
-+      while ((end = strchr(end, '/'))) {
-+              /* if there is another slash, make the dir. */
-+              *end = '\0';
-+              err = mkdir(pathname, dir_mode);
-+              if (err && errno != EEXIST) {
-+                      condlog(0, "Cannot make directory [%s] : %s",
-+                              pathname, strerror(errno));
-+                      free(pathname);
-+                      return -1;
-+              }
-+              if (!err)
-+                      condlog(3, "Created dir [%s]", pathname);
-+              *end = '/';
-+              end++;
-+      }
-+      free(pathname);
-+      return 0;
-+}
-+
-+static void
-+sigalrm(int sig)
-+{
-+      /* do nothing */
-+}
-+
-+static int
-+lock_file(int fd, char *file_name)
-+{
-+      struct sigaction act, oldact;
-+      sigset_t set, oldset;
-+      struct flock lock;
-+      int err;
-+
-+      memset(&lock, 0, sizeof(lock));
-+      lock.l_type = F_WRLCK;
-+      lock.l_whence = SEEK_SET;
-+
-+      act.sa_handler = sigalrm;
-+      sigemptyset(&act.sa_mask);
-+      act.sa_flags = 0;
-+      sigemptyset(&set);
-+      sigaddset(&set, SIGALRM);
-+
-+      sigaction(SIGALRM, &act, &oldact);
-+      sigprocmask(SIG_UNBLOCK, &set, &oldset);
-+
-+      alarm(FILE_TIMEOUT);
-+      err = fcntl(fd, F_SETLKW, &lock);
-+      alarm(0);
-+
-+      if (err) {
-+              if (errno != EINTR)
-+                      condlog(0, "Cannot lock %s : %s", file_name,
-+                              strerror(errno));
-+              else
-+                      condlog(0, "%s is locked. Giving up.", file_name);
-+      }
-+
-+      sigprocmask(SIG_SETMASK, &oldset, NULL);
-+      sigaction(SIGALRM, &oldact, NULL);
-+      return err;
-+}
-+
-+int
-+open_file(char *file, int *can_write, char *header)
-+{
-+      int fd;
-+      struct stat s;
-+
-+      if (ensure_directories_exist(file, 0700))
-+              return -1;
-+      *can_write = 1;
-+      fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
-+      if (fd < 0) {
-+              if (errno == EROFS) {
-+                      *can_write = 0;
-+                      condlog(3, "Cannot open file [%s] read/write. "
-+                              " trying readonly", file);
-+                      fd = open(file, O_RDONLY);
-+                      if (fd < 0) {
-+                              condlog(0, "Cannot open file [%s] "
-+                                      "readonly : %s", file, strerror(errno));
-+                              return -1;
-+                      }
-+              }
-+              else {
-+                      condlog(0, "Cannot open file [%s] : %s", file,
-+                              strerror(errno));
-+                      return -1;
-+              }
-+      }
-+      if (*can_write && lock_file(fd, file) < 0)
-+              goto fail;
-+
-+      memset(&s, 0, sizeof(s));
-+      if (fstat(fd, &s) < 0){
-+              condlog(0, "Cannot stat file %s : %s", file, strerror(errno));
-+              goto fail;
-+      }
-+      if (s.st_size == 0) {
-+              if (*can_write == 0)
-+                      goto fail;
-+              /* If file is empty, write the header */
-+              size_t len = strlen(header);
-+              if (write_all(fd, header, len) != len) {
-+                      condlog(0,
-+                              "Cannot write header to file %s : %s", file,
-+                              strerror(errno));
-+                      /* cleanup partially written header */
-+                      if (ftruncate(fd, 0))
-+                              condlog(0, "Cannot truncate header : %s",
-+                                      strerror(errno));
-+                      goto fail;
-+              }
-+              fsync(fd);
-+              condlog(3, "Initialized new file [%s]", file);
-+      }
-+
-+      return fd;
-+
-+fail:
-+      close(fd);
-+      return -1;
-+}
-Index: multipath-tools-120518/libmultipath/file.h
-===================================================================
---- /dev/null
-+++ multipath-tools-120518/libmultipath/file.h
-@@ -0,0 +1,11 @@
-+/*
-+ * Copyright (c) 2010 Benjamin Marzinski, Redhat
-+ */
-+
-+#ifndef _FILE_H
-+#define _FILE_H
-+
-+#define FILE_TIMEOUT 30
-+int open_file(char *file, int *can_write, char *header);
-+
-+#endif /* _FILE_H */
-Index: multipath-tools-120518/multipath/main.c
-===================================================================
---- multipath-tools-120518.orig/multipath/main.c
-+++ multipath-tools-120518/multipath/main.c
-@@ -53,6 +53,7 @@
- #include <errno.h>
- #include <sys/time.h>
- #include <sys/resource.h>
-+#include <wwids.h>
- #include "dev_t.h"
- int logsink;
-@@ -82,7 +83,7 @@ usage (char * progname)
- {
-       fprintf (stderr, VERSION_STRING);
-       fprintf (stderr, "Usage:\n");
--      fprintf (stderr, "  %s [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+      fprintf (stderr, "  %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [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);
-@@ -95,6 +96,7 @@ usage (char * progname)
-               "  -ll     show multipath topology (maximum info)\n" \
-               "  -f      flush a multipath device map\n" \
-               "  -F      flush all multipath device maps\n" \
-+              "  -c      check if a device should be a path in a multipath device\n" \
-               "  -q      allow queue_if_no_path when multipathd is not running\n"\
-               "  -d      dry run, do not create or update devmaps\n" \
-               "  -t      dump internal hardware table\n" \
-@@ -209,6 +211,7 @@ get_dm_mpvec (vector curmp, vector pathv
-               if (!conf->dry_run)
-                       reinstate_paths(mpp);
-+              remember_wwid(mpp->wwid);
-       }
-       return 0;
- }
-@@ -259,9 +262,13 @@ configure (void)
-        * if we have a blacklisted device parameter, exit early
-        */
-       if (dev &&
--          (filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0))
--                      goto out;
--
-+          (filter_devnode(conf->blist_devnode,
-+                          conf->elist_devnode, dev) > 0)) {
-+              if (conf->dry_run == 2)
-+                      printf("%s is not a valid multipath device path\n",
-+                             conf->dev);
-+              goto out;
-+      }
-       /*
-        * scope limiting must be translated into a wwid
-        * failing the translation is fatal (by policy)
-@@ -277,6 +284,15 @@ configure (void)
-               if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
-                               refwwid) > 0)
-                       goto out;
-+              if (conf->dry_run == 2) {
-+                      if (check_wwids_file(refwwid, 0) == 0){
-+                              printf("%s is a valid multipath device path\n", conf->dev);
-+                              r = 0;
-+                      }
-+                      else
-+                              printf("%s is not a valid multipath device path\n", conf->dev);
-+                      goto out;
-+              }
-       }
-       /*
-@@ -412,7 +428,7 @@ main (int argc, char *argv[])
-       if (load_config(DEFAULT_CONFIGFILE))
-               exit(1);
--      while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:Brtq")) != EOF ) {
-+      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
-               switch(arg) {
-               case 1: printf("optarg : %s\n",optarg);
-                       break;
-@@ -434,8 +450,12 @@ main (int argc, char *argv[])
-               case 'q':
-                       conf->allow_queueing = 1;
-                       break;
-+              case 'c':
-+                      conf->dry_run = 2;
-+                      break;
-               case 'd':
--                      conf->dry_run = 1;
-+                      if (!conf->dry_run)
-+                              conf->dry_run = 1;
-                       break;
-               case 'f':
-                       conf->remove = FLUSH_ONE;
-@@ -517,6 +537,11 @@ main (int argc, char *argv[])
-       }
-       dm_init();
-+      if (conf->dry_run == 2 &&
-+          (!conf->dev || conf->dev_type == DEV_DEVMAP)) {
-+              condlog(0, "the -c option requires a path to check");
-+              goto out;
-+      }
-       if (conf->remove == FLUSH_ONE) {
-               if (conf->dev_type == DEV_DEVMAP)
-                       r = dm_flush_map(conf->dev);
-Index: multipath-tools-120518/libmultipath/Makefile
-===================================================================
---- multipath-tools-120518.orig/libmultipath/Makefile
-+++ multipath-tools-120518/libmultipath/Makefile
-@@ -15,7 +15,7 @@ OBJS = memory.o parser.o vector.o devmap
-        pgpolicies.o debug.o regex.o defaults.o uevent.o \
-        switchgroup.o uxsock.o print.o alias.o log_pthread.o \
-        log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
--       lock.o waiter.o
-+       lock.o waiter.o file.o wwids.o
- LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h)
-Index: multipath-tools-120518/libmultipath/wwids.c
-===================================================================
---- /dev/null
-+++ multipath-tools-120518/libmultipath/wwids.c
-@@ -0,0 +1,139 @@
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <limits.h>
-+#include <stdio.h>
-+
-+#include "checkers.h"
-+#include "vector.h"
-+#include "structs.h"
-+#include "debug.h"
-+#include "uxsock.h"
-+#include "file.h"
-+#include "wwids.h"
-+#include "defaults.h"
-+
-+/*
-+ * Copyright (c) 2010 Benjamin Marzinski, Redhat
-+ */
-+
-+static int
-+lookup_wwid(FILE *f, char *wwid) {
-+      int c;
-+      char buf[LINE_MAX];
-+      int count;
-+
-+      while ((c = fgetc(f)) != EOF){
-+              if (c != '/') {
-+                      if (fgets(buf, LINE_MAX, f) == NULL)
-+                              return 0;
-+                      else
-+                              continue;
-+              }
-+              count = 0;
-+              while ((c = fgetc(f)) != '/') {
-+                      if (c == EOF)
-+                              return 0;
-+                      if (count >= WWID_SIZE - 1)
-+                              goto next;
-+                      if (wwid[count] == '\0')
-+                              goto next;
-+                      if (c != wwid[count++])
-+                              goto next;
-+              }
-+              if (wwid[count] == '\0')
-+                      return 1;
-+next:
-+              if (fgets(buf, LINE_MAX, f) == NULL)
-+                      return 0;
-+      }
-+      return 0;
-+}
-+
-+static int
-+write_out_wwid(int fd, char *wwid) {
-+      int ret;
-+      off_t offset;
-+      char buf[WWID_SIZE + 3];
-+
-+      ret = snprintf(buf, WWID_SIZE + 3, "/%s/\n", wwid);
-+      if (ret >= (WWID_SIZE + 3) || ret < 0){
-+              condlog(0, "can't format wwid for writing (%d) : %s",
-+                      ret, strerror(errno));
-+              return -1;
-+      }
-+      offset = lseek(fd, 0, SEEK_END);
-+      if (offset < 0) {
-+              condlog(0, "can't seek to the end of wwids file : %s",
-+                      strerror(errno));
-+              return -1;
-+      }
-+      if (write_all(fd, buf, strlen(buf)) != strlen(buf)) {
-+              condlog(0, "cannot write wwid to wwids file : %s",
-+                      strerror(errno));
-+              if (ftruncate(fd, offset))
-+                      condlog(0, "cannot truncate failed wwid write : %s",
-+                              strerror(errno));
-+              return -1;
-+      }
-+      return 1;
-+}
-+
-+int
-+check_wwids_file(char *wwid, int write_wwid)
-+{
-+      int fd, can_write, found, ret;
-+      FILE *f;
-+      fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER);
-+      if (fd < 0)
-+              return -1;
-+
-+      f = fdopen(fd, "r");
-+      if (!f) {
-+              condlog(0,"can't fdopen wwids file : %s", strerror(errno));
-+              close(fd);
-+              return -1;
-+      }
-+      found = lookup_wwid(f, wwid);
-+      if (found) {
-+              ret = 0;
-+              goto out;
-+      }
-+      if (!write_wwid) {
-+              ret = -1;
-+              goto out;
-+      }
-+      if (!can_write) {
-+              condlog(0, "wwids file is read-only. Can't write wwid");
-+              ret = -1;
-+              goto out;
-+      }
-+
-+      if (fflush(f) != 0) {
-+              condlog(0, "cannot fflush wwids file stream : %s",
-+                      strerror(errno));
-+              ret = -1;
-+              goto out;
-+      }
-+
-+      ret = write_out_wwid(fd, wwid);
-+out:
-+      fclose(f);
-+      return ret;
-+}
-+
-+int
-+remember_wwid(char *wwid)
-+{
-+      int ret = check_wwids_file(wwid, 1);
-+      if (ret < 0){
-+              condlog(3, "failed writing wwid %s to wwids file", wwid);
-+              return -1;
-+      }
-+      if (ret == 1)
-+              condlog(3, "wrote wwid %s to wwids file", wwid);
-+      else
-+              condlog(4, "wwid %s already in wwids file", wwid);
-+      return 0;
-+}
-Index: multipath-tools-120518/libmultipath/wwids.h
-===================================================================
---- /dev/null
-+++ multipath-tools-120518/libmultipath/wwids.h
-@@ -0,0 +1,18 @@
-+/*
-+ * Copyright (c) 2010 Benjamin Marzinski, Redhat
-+ */
-+
-+#ifndef _WWIDS_H
-+#define _WWIDS_H
-+
-+#define WWIDS_FILE_HEADER \
-+"# Multipath wwids, Version : 1.0\n" \
-+"# NOTE: This file is automatically maintained by multipath and multipathd.\n" \
-+"# You should not need to edit this file in normal circumstances.\n" \
-+"#\n" \
-+"# Valid WWIDs:\n"
-+
-+int remember_wwid(char *wwid);
-+int check_wwids_file(char *wwid, int write_wwid);
-+
-+#endif /* _WWIDS_H */
-Index: multipath-tools-120518/libmultipath/discovery.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/discovery.c
-+++ multipath-tools-120518/libmultipath/discovery.c
-@@ -810,6 +810,8 @@ get_uid (struct path * pp)
-       memset(pp->wwid, 0, WWID_SIZE);
-       value = udev_device_get_property_value(pp->udev, pp->uid_attribute);
-+      if ((!value || strlen(value) == 0) && conf->dry_run == 2)
-+              value = getenv(pp->uid_attribute);
-       if (value && strlen(value)) {
-               size_t len = WWID_SIZE;
similarity index 62%
rename from multipath-tools/patches/0006-RH-multipath.rules.patch
rename to multipath-tools/patches/0002-RH-multipath.rules.patch
index bfcfc98b875d1f40a009d581e8849886db0a459e..a910dc1cddba75750205b0492a2933bba5f096de 100644 (file)
@@ -1,23 +1,17 @@
 ---
- multipath/Makefile        |    6 +++---
- multipath/multipath.rules |   30 ++++++++++++++++++++++++------
- 2 files changed, 27 insertions(+), 9 deletions(-)
+ multipath/Makefile        |    3 +++
+ multipath/multipath.rules |   24 ++++++++++++++++++++++++
+ 2 files changed, 27 insertions(+)
 
-Index: multipath-tools-120613/multipath/multipath.rules
+Index: multipath-tools-130222/multipath/multipath.rules
 ===================================================================
---- multipath-tools-120613.orig/multipath/multipath.rules
-+++ multipath-tools-120613/multipath/multipath.rules
-@@ -1,7 +1,25 @@
--#
--# udev rules for multipathing.
--# The persistent symlinks are created with the kpartx rules
--#
+--- /dev/null
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -0,0 +1,24 @@
 +# multipath wants the devmaps presented as meaninglful device names
 +# so name them after their devmap name
 +SUBSYSTEM!="block", GOTO="end_mpath"
--# socket for uevents
--SUBSYSTEM=="block", RUN+="socket:/org/kernel/dm/multipath_event"
++
 +ENV{MPATH_SBIN_PATH}="/sbin"
 +TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
 +
@@ -30,25 +24,22 @@ Index: multipath-tools-120613/multipath/multipath.rules
 +ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
 +      RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
 +
-+RUN+="socket:/org/kernel/dm/multipath_event"
 +KERNEL!="dm-*", GOTO="end_mpath"
-+ACTION!="change", GOTO="end_mpath"
 +ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
++ACTION!="change", GOTO="end_mpath"
 +ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
 +ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
 +ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
-+RUN+="$env{MPATH_SBIN_PATH}/kpartx -a -p p $tempnode"
++RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
 +LABEL="end_mpath"
-Index: multipath-tools-120613/multipath/Makefile
+Index: multipath-tools-130222/multipath/Makefile
 ===================================================================
---- multipath-tools-120613.orig/multipath/Makefile
-+++ multipath-tools-120613/multipath/Makefile
-@@ -21,15 +21,15 @@ $(EXEC): $(OBJS)
+--- multipath-tools-130222.orig/multipath/Makefile
++++ multipath-tools-130222/multipath/Makefile
+@@ -21,12 +21,15 @@ $(EXEC): $(OBJS)
  install:
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
        $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
--      $(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d
--      $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/
 +      $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
 +      $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
@@ -57,7 +48,6 @@ Index: multipath-tools-120613/multipath/Makefile
        $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
  
  uninstall:
--      rm $(DESTDIR)/etc/udev/rules.d/multipath.rules
 +      rm $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
        rm $(DESTDIR)$(bindir)/$(EXEC)
        rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
similarity index 77%
rename from multipath-tools/patches/0007-RH-Make-build-system-RH-Fedora-friendly.patch
rename to multipath-tools/patches/0003-RH-Make-build-system-RH-Fedora-friendly.patch
index bc5d17da5518efa20786b7c689f93ee8a2bfcd8b..f293c800cd56b209c8f047f67521da99e403b621 100644 (file)
@@ -9,16 +9,16 @@ Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
 :100644 100644 21e4ad4... 06d79c0... M kpartx/Makefile
 :100644 100644 32d9ef5... 25e1483... M multipathd/Makefile
  Makefile.inc             |    2 +-
- kpartx/Makefile          |    8 ++++----
+ kpartx/Makefile          |   10 +++++-----
  libmpathpersist/Makefile |    7 ++-----
  libmultipath/Makefile    |    2 ++
  multipathd/Makefile      |    1 +
- 5 files changed, 10 insertions(+), 10 deletions(-)
+ 5 files changed, 11 insertions(+), 11 deletions(-)
 
-Index: multipath-tools-120613/Makefile.inc
+Index: multipath-tools-130222/Makefile.inc
 ===================================================================
---- multipath-tools-120613.orig/Makefile.inc
-+++ multipath-tools-120613/Makefile.inc
+--- multipath-tools-130222.orig/Makefile.inc
++++ multipath-tools-130222/Makefile.inc
 @@ -29,7 +29,7 @@ multipathdir = $(TOPDIR)/libmultipath
  mandir      = $(prefix)/usr/share/man/man8
  man5dir     = $(prefix)/usr/share/man/man5
@@ -28,11 +28,11 @@ Index: multipath-tools-120613/Makefile.inc
  syslibdir   = $(prefix)/$(LIB)
  libdir            = $(prefix)/$(LIB)/multipath
  unitdir     = $(prefix)/lib/systemd/system
-Index: multipath-tools-120613/kpartx/Makefile
+Index: multipath-tools-130222/kpartx/Makefile
 ===================================================================
---- multipath-tools-120613.orig/kpartx/Makefile
-+++ multipath-tools-120613/kpartx/Makefile
-@@ -26,10 +26,10 @@ $(EXEC): $(OBJS)
+--- multipath-tools-130222.orig/kpartx/Makefile
++++ multipath-tools-130222/kpartx/Makefile
+@@ -26,17 +26,17 @@ $(EXEC): $(OBJS)
  install: $(EXEC) $(EXEC).8
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
        $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
@@ -47,10 +47,18 @@ Index: multipath-tools-120613/kpartx/Makefile
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
        $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
  
-Index: multipath-tools-120613/multipathd/Makefile
+ uninstall:
+       rm -f $(DESTDIR)$(bindir)/$(EXEC)
+       rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz
+-      rm -f $(DESTDIR)$(libudevdir)/kpartx_id
++#     rm -f $(DESTDIR)$(libudevdir)/kpartx_id
+ clean:
+       rm -f core *.o $(EXEC) *.gz
+Index: multipath-tools-130222/multipathd/Makefile
 ===================================================================
---- multipath-tools-120613.orig/multipathd/Makefile
-+++ multipath-tools-120613/multipathd/Makefile
+--- multipath-tools-130222.orig/multipathd/Makefile
++++ multipath-tools-130222/multipathd/Makefile
 @@ -35,6 +35,7 @@ install:
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
        $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
@@ -59,10 +67,10 @@ Index: multipath-tools-120613/multipathd/Makefile
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir)
        $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir)
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
-Index: multipath-tools-120613/libmultipath/Makefile
+Index: multipath-tools-130222/libmultipath/Makefile
 ===================================================================
---- multipath-tools-120613.orig/libmultipath/Makefile
-+++ multipath-tools-120613/libmultipath/Makefile
+--- multipath-tools-130222.orig/libmultipath/Makefile
++++ multipath-tools-130222/libmultipath/Makefile
 @@ -46,9 +46,11 @@ install:
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
        $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
@@ -75,10 +83,10 @@ Index: multipath-tools-120613/libmultipath/Makefile
  
  clean:
        rm -f core *.a *.o *.gz *.so *.so.*
-Index: multipath-tools-120613/libmpathpersist/Makefile
+Index: multipath-tools-130222/libmpathpersist/Makefile
 ===================================================================
---- multipath-tools-120613.orig/libmpathpersist/Makefile
-+++ multipath-tools-120613/libmpathpersist/Makefile
+--- multipath-tools-130222.orig/libmpathpersist/Makefile
++++ multipath-tools-130222/libmpathpersist/Makefile
 @@ -28,17 +28,14 @@ $(LIBS):
  install: $(LIBS)
        $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
diff --git a/multipath-tools/patches/0003-RH-add-followover.patch b/multipath-tools/patches/0003-RH-add-followover.patch
deleted file mode 100644 (file)
index 9aeecf4..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
----
- libmultipath/dict.c        |   12 ++++++++++++
- libmultipath/discovery.c   |    6 +++---
- libmultipath/print.c       |    2 ++
- libmultipath/structs.h     |    4 +++-
- multipath/main.c           |    2 +-
- multipath/multipath.conf.5 |    5 +++++
- multipathd/main.c          |   35 ++++++++++++++++++++++++++++++++++-
- 7 files changed, 60 insertions(+), 6 deletions(-)
-
-Index: multipath-tools-120518/libmultipath/dict.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/dict.c
-+++ multipath-tools-120518/libmultipath/dict.c
-@@ -398,6 +398,8 @@ default_failback_handler(vector strvec)
-               conf->pgfailback = -FAILBACK_MANUAL;
-       else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
-               conf->pgfailback = -FAILBACK_IMMEDIATE;
-+      else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
-+              conf->pgfailback = -FAILBACK_FOLLOWOVER;
-       else
-               conf->pgfailback = atoi(buff);
-@@ -1053,6 +1055,8 @@ hw_failback_handler(vector strvec)
-               hwe->pgfailback = -FAILBACK_MANUAL;
-       else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
-               hwe->pgfailback = -FAILBACK_IMMEDIATE;
-+      else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
-+              hwe->pgfailback = -FAILBACK_FOLLOWOVER;
-       else
-               hwe->pgfailback = atoi(buff);
-@@ -1351,6 +1355,8 @@ mp_failback_handler(vector strvec)
-               mpe->pgfailback = -FAILBACK_MANUAL;
-       else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
-               mpe->pgfailback = -FAILBACK_IMMEDIATE;
-+      else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
-+              mpe->pgfailback = -FAILBACK_FOLLOWOVER;
-       else
-               mpe->pgfailback = atoi(buff);
-@@ -1769,6 +1775,8 @@ snprint_mp_failback (char * buff, int le
-               return snprintf(buff, len, "manual");
-       case -FAILBACK_IMMEDIATE:
-               return snprintf(buff, len, "immediate");
-+      case -FAILBACK_FOLLOWOVER:
-+              return snprintf(buff, len, "followover");
-       default:
-               return snprintf(buff, len, "%i", mpe->pgfailback);
-       }
-@@ -2130,6 +2138,8 @@ snprint_hw_failback (char * buff, int le
-               return snprintf(buff, len, "manual");
-       case -FAILBACK_IMMEDIATE:
-               return snprintf(buff, len, "immediate");
-+      case -FAILBACK_FOLLOWOVER:
-+              return snprintf(buff, len, "followover");
-       default:
-               return snprintf(buff, len, "%i", hwe->pgfailback);
-       }
-@@ -2394,6 +2404,8 @@ snprint_def_failback (char * buff, int l
-               return snprintf(buff, len, "manual");
-       case -FAILBACK_IMMEDIATE:
-               return snprintf(buff, len, "immediate");
-+      case -FAILBACK_FOLLOWOVER:
-+              return snprintf(buff, len, "followover");
-       default:
-               return snprintf(buff, len, "%i", conf->pgfailback);
-       }
-Index: multipath-tools-120518/libmultipath/print.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/print.c
-+++ multipath-tools-120518/libmultipath/print.c
-@@ -143,6 +143,8 @@ snprint_failback (char * buff, size_t le
- {
-       if (mpp->pgfailback == -FAILBACK_IMMEDIATE)
-               return snprintf(buff, len, "immediate");
-+      if (mpp->pgfailback == -FAILBACK_FOLLOWOVER)
-+              return snprintf(buff, len, "followover");
-       if (!mpp->failback_tick)
-               return snprintf(buff, len, "-");
-Index: multipath-tools-120518/libmultipath/structs.h
-===================================================================
---- multipath-tools-120518.orig/libmultipath/structs.h
-+++ multipath-tools-120518/libmultipath/structs.h
-@@ -39,7 +39,8 @@ enum rr_weight_mode {
- enum failback_mode {
-       FAILBACK_UNDEF,
-       FAILBACK_MANUAL,
--      FAILBACK_IMMEDIATE
-+      FAILBACK_IMMEDIATE,
-+      FAILBACK_FOLLOWOVER
- };
- enum sysfs_buses {
-@@ -151,6 +152,7 @@ struct path {
-       int offline;
-       int state;
-       int dmstate;
-+      int chkrstate;
-       int failcount;
-       int priority;
-       int pgindex;
-Index: multipath-tools-120518/multipathd/main.c
-===================================================================
---- multipath-tools-120518.orig/multipathd/main.c
-+++ multipath-tools-120518/multipathd/main.c
-@@ -995,6 +995,32 @@ mpvec_garbage_collector (struct vectors
-       }
- }
-+/* This is called after a path has started working again. It the multipath
-+ * device for this path uses the followover failback type, and this is the
-+ * best pathgroup, and this is the first path in the pathgroup to come back
-+ * up, then switch to this pathgroup */
-+static int
-+followover_should_failback(struct path * pp)
-+{
-+      struct pathgroup * pgp;
-+      struct path *pp1;
-+      int i;
-+
-+      if (pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER ||
-+          !pp->mpp->pg || !pp->pgindex ||
-+          pp->pgindex != pp->mpp->bestpg)
-+              return 0;
-+
-+      pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
-+      vector_foreach_slot(pgp->paths, pp1, i) {
-+              if (pp1 == pp)
-+                      continue;
-+              if (pp1->chkrstate != PATH_DOWN && pp1->chkrstate != PATH_SHAKY)
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
- static void
- defered_failback_tick (vector mpvec)
- {
-@@ -1092,6 +1118,8 @@ check_path (struct vectors * vecs, struc
- {
-       int newstate;
-       int new_path_up = 0;
-+      int chkr_new_path_up = 0;
-+      int oldchkrstate = pp->chkrstate;
-       if (!pp->mpp)
-               return;
-@@ -1130,6 +1158,7 @@ check_path (struct vectors * vecs, struc
-                       pp->dev);
-               pp->dmstate = PSTATE_UNDEF;
-       }
-+      pp->chkrstate = newstate;
-       if (newstate != pp->state) {
-               int oldstate = pp->state;
-               pp->state = newstate;
-@@ -1182,6 +1211,9 @@ check_path (struct vectors * vecs, struc
-               new_path_up = 1;
-+              if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
-+                      chkr_new_path_up = 1;
-+
-               /*
-                * if at least one path is up in a group, and
-                * the group is disabled, re-enable it
-@@ -1233,7 +1265,8 @@ check_path (struct vectors * vecs, struc
-                   (new_path_up || pp->mpp->failback_tick <= 0))
-                       pp->mpp->failback_tick =
-                               pp->mpp->pgfailback + 1;
--              else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE)
-+              else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
-+                       (chkr_new_path_up && followover_should_failback(pp)))
-                       switch_pathgroup(pp->mpp);
-       }
- }
-Index: multipath-tools-120518/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-120518.orig/multipath/multipath.conf.5
-+++ multipath-tools-120518/multipath/multipath.conf.5
-@@ -254,6 +254,11 @@ active paths.
- .B manual
- Do not perform automatic failback.
- .TP
-+.B followover
-+Only perform automatic failback when the first path of a pathgroup
-+becomes active. This keeps a node from automatically failing back when
-+another node requested the failover.
-+.TP
- .B values > 0
- deferred failback (time to defer in seconds)
- .TP
-Index: multipath-tools-120518/libmultipath/discovery.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/discovery.c
-+++ multipath-tools-120518/libmultipath/discovery.c
-@@ -878,13 +878,13 @@ pathinfo (struct path *pp, vector hwtabl
-       if (mask & DI_CHECKER) {
-               if (path_state == PATH_UP) {
--                      pp->state = get_state(pp, 0);
-+                      pp->chkrstate = pp->state = get_state(pp, 0);
-                       if (pp->state == PATH_UNCHECKED ||
-                           pp->state == PATH_WILD)
-                               goto blank;
-               } else {
-                       condlog(3, "%s: path inaccessible", pp->dev);
--                      pp->state = path_state;
-+                      pp->chkrstate = pp->state = path_state;
-               }
-       }
-@@ -912,7 +912,7 @@ blank:
-        * Recoverable error, for example faulty or offline path
-        */
-       memset(pp->wwid, 0, WWID_SIZE);
--      pp->state = PATH_DOWN;
-+      pp->chkrstate = pp->state = PATH_DOWN;
-       return 0;
- }
-Index: multipath-tools-120518/multipath/main.c
-===================================================================
---- multipath-tools-120518.orig/multipath/main.c
-+++ multipath-tools-120518/multipath/main.c
-@@ -144,7 +144,7 @@ update_paths (struct multipath * mpp)
-                                       /*
-                                        * path is not in sysfs anymore
-                                        */
--                                      pp->state = PATH_DOWN;
-+                                      pp->chkrstate = pp->state = PATH_DOWN;
-                                       continue;
-                               }
-                               pp->mpp = mpp;
diff --git a/multipath-tools/patches/0004-RH-fix-cciss-names.patch b/multipath-tools/patches/0004-RH-fix-cciss-names.patch
deleted file mode 100644 (file)
index 890a483..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
----
- multipath/main.c |   12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-Index: multipath-tools-120518/multipath/main.c
-===================================================================
---- multipath-tools-120518.orig/multipath/main.c
-+++ multipath-tools-120518/multipath/main.c
-@@ -409,6 +409,16 @@ get_dev_type(char *dev) {
-               return DEV_DEVMAP;
- }
-+static void
-+convert_dev(char *dev)
-+{
-+      char *ptr = strstr(dev, "cciss/");
-+      if (ptr) {
-+              ptr += 5;
-+              *ptr = '!';
-+      }
-+}
-+
- int
- main (int argc, char *argv[])
- {
-@@ -514,6 +524,8 @@ main (int argc, char *argv[])
-               strncpy(conf->dev, argv[optind], FILE_NAME_SIZE);
-               conf->dev_type = get_dev_type(conf->dev);
-+              if (conf->dev_type == DEV_DEVNODE)
-+                      convert_dev(conf->dev);
-       }
-       conf->daemon = 0;
similarity index 83%
rename from multipath-tools/patches/0008-RH-multipathd-blacklist-all-by-default.patch
rename to multipath-tools/patches/0004-RH-multipathd-blacklist-all-by-default.patch
index 5bbf3ca82a96a6a6f7fb082a143e0157da0846e7..2dda63c73f2fbe3fd226689d1c0130d4f70a5e3d 100644 (file)
@@ -16,10 +16,10 @@ Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  libmultipath/config.h |    1 +
  2 files changed, 17 insertions(+)
 
-Index: multipath-tools-120518/libmultipath/config.c
+Index: multipath-tools-130222/libmultipath/config.c
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/config.c
-+++ multipath-tools-120518/libmultipath/config.c
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
 @@ -21,6 +21,7 @@
  #include "defaults.h"
  #include "prio.h"
@@ -28,7 +28,7 @@ Index: multipath-tools-120518/libmultipath/config.c
  
  static int
  hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
-@@ -549,6 +550,21 @@ load_config (char * file)
+@@ -585,6 +586,21 @@ load_config (char * file)
  
        } else {
                init_keywords();
@@ -50,10 +50,10 @@ Index: multipath-tools-120518/libmultipath/config.c
        }
  
        /*
-Index: multipath-tools-120518/libmultipath/config.h
+Index: multipath-tools-130222/libmultipath/config.h
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/config.h
-+++ multipath-tools-120518/libmultipath/config.h
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
 @@ -6,6 +6,7 @@
  
  #define ORIGIN_DEFAULT 0
similarity index 94%
rename from multipath-tools/patches/0009-RH-add-mpathconf.patch
rename to multipath-tools/patches/0005-RH-add-mpathconf.patch
index 2a5bec8ec3312391f37fb6fd3fd3ff4a0193f5b0..ce1b2c76e1ec96132d6287bffc4ed159eb0ce429 100644 (file)
@@ -6,11 +6,11 @@
  multipath/mpathconf.8 |  103 ++++++++++++++++
  5 files changed, 423 insertions(+), 2 deletions(-)
 
-Index: multipath-tools-120613/libmultipath/config.c
+Index: multipath-tools-130222/libmultipath/config.c
 ===================================================================
---- multipath-tools-120613.orig/libmultipath/config.c
-+++ multipath-tools-120613/libmultipath/config.c
-@@ -553,6 +553,7 @@ load_config (char * file)
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -589,6 +589,7 @@ load_config (char * file)
                condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
                condlog(0, "A default multipath.conf file is located at");
                condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
@@ -18,10 +18,10 @@ Index: multipath-tools-120613/libmultipath/config.c
                if (conf->blist_devnode == NULL) {
                        conf->blist_devnode = vector_alloc();
                        if (!conf->blist_devnode) {
-Index: multipath-tools-120613/multipath/Makefile
+Index: multipath-tools-130222/multipath/Makefile
 ===================================================================
---- multipath-tools-120613.orig/multipath/Makefile
-+++ multipath-tools-120613/multipath/Makefile
+--- multipath-tools-130222.orig/multipath/Makefile
++++ multipath-tools-130222/multipath/Makefile
 @@ -17,22 +17,27 @@ $(EXEC): $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS)
        $(GZIP) $(EXEC).8 > $(EXEC).8.gz
@@ -50,11 +50,11 @@ Index: multipath-tools-120613/multipath/Makefile
  
  clean:
        rm -f core *.o $(EXEC) *.gz
-Index: multipath-tools-120613/multipath/main.c
+Index: multipath-tools-130222/multipath/main.c
 ===================================================================
---- multipath-tools-120613.orig/multipath/main.c
-+++ multipath-tools-120613/multipath/main.c
-@@ -432,10 +432,10 @@ main (int argc, char *argv[])
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -433,10 +433,10 @@ main (int argc, char *argv[])
                exit(1);
        }
  
@@ -67,10 +67,10 @@ Index: multipath-tools-120613/multipath/main.c
                exit(1);
  
        while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
-Index: multipath-tools-120613/multipath/mpathconf
+Index: multipath-tools-130222/multipath/mpathconf
 ===================================================================
 --- /dev/null
-+++ multipath-tools-120613/multipath/mpathconf
++++ multipath-tools-130222/multipath/mpathconf
 @@ -0,0 +1,312 @@
 +#!/bin/sh
 +#
@@ -384,10 +384,10 @@ Index: multipath-tools-120613/multipath/mpathconf
 +elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
 +      service multipathd reload
 +fi
-Index: multipath-tools-120613/multipath/mpathconf.8
+Index: multipath-tools-130222/multipath/mpathconf.8
 ===================================================================
 --- /dev/null
-+++ multipath-tools-120613/multipath/mpathconf.8
++++ multipath-tools-130222/multipath/mpathconf.8
 @@ -0,0 +1,103 @@
 +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
 +.SH NAME
diff --git a/multipath-tools/patches/0005-RH-dont_start_with_no_config.patch b/multipath-tools/patches/0005-RH-dont_start_with_no_config.patch
deleted file mode 100644 (file)
index 7efd925..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
----
- multipathd/multipathd.service |    1 +
- 1 file changed, 1 insertion(+)
-
-Index: multipath-tools-110916/multipathd/multipathd.service
-===================================================================
---- multipath-tools-110916.orig/multipathd/multipathd.service
-+++ multipath-tools-110916/multipathd/multipathd.service
-@@ -2,6 +2,7 @@
- Description=Device-Mapper Multipath Device Controller
- Before=iscsi.service iscsid.service
- After=syslog.target
-+ConditionPathExists=/etc/multipath.conf
- [Service]
- Type=forking
similarity index 67%
rename from multipath-tools/patches/0010-RH-add-find-multipaths.patch
rename to multipath-tools/patches/0006-RH-add-find-multipaths.patch
index 57eb0a8ed006acb6a58bedc2f2ed6f3e9514e90c..4a0c36476b60ab8b3de77be6e3ffc31218ace3e2 100644 (file)
  multipathd/main.c        |    6 ++++++
  9 files changed, 82 insertions(+), 1 deletion(-)
 
-Index: multipath-tools-120518/libmultipath/config.c
+Index: multipath-tools-130222/libmultipath/config.c
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/config.c
-+++ multipath-tools-120518/libmultipath/config.c
-@@ -514,6 +514,7 @@ load_config (char * file)
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -547,6 +547,7 @@ load_config (char * file)
        conf->reassign_maps = DEFAULT_REASSIGN_MAPS;
        conf->checkint = DEFAULT_CHECKINT;
        conf->max_checkint = MAX_CHECKINT(conf->checkint);
 +      conf->find_multipaths = DEFAULT_FIND_MULTIPATHS;
-       /*
-        * preload default hwtable
-Index: multipath-tools-120518/libmultipath/configure.c
+       conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
+       conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
+       conf->detect_prio = DEFAULT_DETECT_PRIO;
+Index: multipath-tools-130222/libmultipath/configure.c
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/configure.c
-+++ multipath-tools-120518/libmultipath/configure.c
-@@ -497,6 +497,10 @@ coalesce_paths (struct vectors * vecs, v
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -508,6 +508,10 @@ coalesce_paths (struct vectors * vecs, v
  
        memset(empty_buff, 0, WWID_SIZE);
  
@@ -37,7 +37,7 @@ Index: multipath-tools-120518/libmultipath/configure.c
        if (force_reload) {
                vector_foreach_slot (pathvec, pp1, k) {
                        pp1->mpp = NULL;
-@@ -526,6 +530,13 @@ coalesce_paths (struct vectors * vecs, v
+@@ -537,6 +541,13 @@ coalesce_paths (struct vectors * vecs, v
                if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
                        continue;
  
@@ -51,22 +51,22 @@ Index: multipath-tools-120518/libmultipath/configure.c
                /*
                 * at this point, we know we really got a new mp
                 */
-Index: multipath-tools-120518/libmultipath/defaults.h
+Index: multipath-tools-130222/libmultipath/defaults.h
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/defaults.h
-+++ multipath-tools-120518/libmultipath/defaults.h
+--- multipath-tools-130222.orig/libmultipath/defaults.h
++++ multipath-tools-130222/libmultipath/defaults.h
 @@ -15,6 +15,7 @@
  #define DEFAULT_USER_FRIENDLY_NAMES    0
  #define DEFAULT_VERBOSITY     2
  #define DEFAULT_REASSIGN_MAPS 1
-+#define DEFAULT_FIND_MULTIPATHS 0
- #define DEFAULT_CHECKINT      5
- #define MAX_CHECKINT(a)               (a << 2)
-Index: multipath-tools-120518/libmultipath/dict.c
++#define DEFAULT_FIND_MULTIPATHS       0
+ #define DEFAULT_FAST_IO_FAIL  5
+ #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
+ #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
+Index: multipath-tools-130222/libmultipath/dict.c
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/dict.c
-+++ multipath-tools-120518/libmultipath/dict.c
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
 @@ -585,6 +585,27 @@ def_reservation_key_handler(vector strve
  }
  
@@ -95,7 +95,7 @@ Index: multipath-tools-120518/libmultipath/dict.c
  def_names_handler(vector strvec)
  {
        char * buff;
-@@ -2549,6 +2570,18 @@ snprint_def_log_checker_err (char * buff
+@@ -2700,6 +2721,18 @@ snprint_def_log_checker_err (char * buff
  }
  
  static int
@@ -114,19 +114,19 @@ Index: multipath-tools-120518/libmultipath/dict.c
  snprint_def_user_friendly_names (char * buff, int len, void * data)
  {
        if (conf->user_friendly_names  == USER_FRIENDLY_NAMES_ON)
-@@ -2646,6 +2679,7 @@ init_keywords(void)
-       install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file);
+@@ -2833,6 +2866,7 @@ init_keywords(void)
+       install_keyword("wwids_file", &wwids_file_handler, &snprint_def_wwids_file);
        install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
        install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
 +      install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
+       install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
+       install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
        __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
-       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
-       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
-Index: multipath-tools-120518/libmultipath/wwids.c
+Index: multipath-tools-130222/libmultipath/wwids.c
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/wwids.c
-+++ multipath-tools-120518/libmultipath/wwids.c
-@@ -124,6 +124,32 @@ out:
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -125,6 +125,32 @@ out:
  }
  
  int
@@ -159,10 +159,10 @@ Index: multipath-tools-120518/libmultipath/wwids.c
  remember_wwid(char *wwid)
  {
        int ret = check_wwids_file(wwid, 1);
-Index: multipath-tools-120518/libmultipath/wwids.h
+Index: multipath-tools-130222/libmultipath/wwids.h
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/wwids.h
-+++ multipath-tools-120518/libmultipath/wwids.h
+--- multipath-tools-130222.orig/libmultipath/wwids.h
++++ multipath-tools-130222/libmultipath/wwids.h
 @@ -12,6 +12,7 @@
  "#\n" \
  "# Valid WWIDs:\n"
@@ -171,11 +171,11 @@ Index: multipath-tools-120518/libmultipath/wwids.h
  int remember_wwid(char *wwid);
  int check_wwids_file(char *wwid, int write_wwid);
  
-Index: multipath-tools-120518/multipath/main.c
+Index: multipath-tools-130222/multipath/main.c
 ===================================================================
---- multipath-tools-120518.orig/multipath/main.c
-+++ multipath-tools-120518/multipath/main.c
-@@ -332,7 +332,7 @@ configure (void)
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -333,7 +333,7 @@ configure (void)
        /*
         * core logic entry point
         */
@@ -184,10 +184,10 @@ Index: multipath-tools-120518/multipath/main.c
  
  out:
        if (refwwid)
-Index: multipath-tools-120518/multipathd/main.c
+Index: multipath-tools-130222/multipathd/main.c
 ===================================================================
---- multipath-tools-120518.orig/multipathd/main.c
-+++ multipath-tools-120518/multipathd/main.c
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
 @@ -49,6 +49,7 @@
  #include <print.h>
  #include <configure.h>
@@ -196,7 +196,7 @@ Index: multipath-tools-120518/multipathd/main.c
  #include <pgpolicies.h>
  #include <uevent.h>
  
-@@ -473,6 +474,11 @@ rescan:
+@@ -471,6 +472,11 @@ rescan:
                        return 1;
                }
  
@@ -208,11 +208,11 @@ Index: multipath-tools-120518/multipathd/main.c
                condlog(4,"%s: creating new map", pp->dev);
                if ((mpp = add_map_with_path(vecs, pp, 1))) {
                        mpp->action = ACT_CREATE;
-Index: multipath-tools-120518/libmultipath/config.h
+Index: multipath-tools-130222/libmultipath/config.h
 ===================================================================
---- multipath-tools-120518.orig/libmultipath/config.h
-+++ multipath-tools-120518/libmultipath/config.h
-@@ -104,6 +104,7 @@ struct config {
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -106,6 +106,7 @@ struct config {
        unsigned int dev_loss;
        int log_checker_err;
        int allow_queueing;
diff --git a/multipath-tools/patches/0008-RH-revert-partition-changes.patch b/multipath-tools/patches/0008-RH-revert-partition-changes.patch
new file mode 100644 (file)
index 0000000..c563b0e
--- /dev/null
@@ -0,0 +1,45 @@
+---
+ kpartx/dos.c    |    2 --
+ kpartx/kpartx.c |    9 ++++++---
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+Index: multipath-tools-130222/kpartx/dos.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/dos.c
++++ multipath-tools-130222/kpartx/dos.c
+@@ -98,8 +98,6 @@ read_dos_pt(int fd, struct slice all, st
+                       break;
+               }
+               if (is_extended(p.sys_type)) {
+-                      sp[i].size = 2; /* extended partitions only get two
+-                                         sectors mapped for LILO to install */
+                       n += read_extended_partition(fd, &p, i, sp+n, ns-n);
+               }
+       }
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -516,6 +516,7 @@ main(int argc, char **argv){
+                       d = c;
+                       while (c) {
+                               for (j = 0; j < n; j++) {
++                                      uint64_t start;
+                                       int k = slices[j].container - 1;
+                                       if (slices[j].size == 0)
+@@ -541,9 +542,11 @@ main(int argc, char **argv){
+                                       }
+                                       strip_slash(partname);
+-                                      if (safe_sprintf(params, "%s %" PRIu64,
+-                                                       device,
+-                                                       slices[j].start)) {
++                                      start = slices[j].start - slices[k].start;
++                                      if (safe_sprintf(params, "%d:%d %" PRIu64,
++                                                       slices[k].major,
++                                                       slices[k].minor,
++                                                       start)) {
+                                               fprintf(stderr, "params too small\n");
+                                               exit(1);
+                                       }
similarity index 90%
rename from multipath-tools/patches/0012-RH-RHEL5-style-partitions.patch
rename to multipath-tools/patches/0009-RH-RHEL5-style-partitions.patch
index 47fa725ee1176c996ab249b3a2f2b0beeca806df..a2691bb0bd5acf6ef26d1bc77b7767d320a50e65 100644 (file)
@@ -6,10 +6,10 @@
  kpartx/sun.c    |   35 ---------------
  5 files changed, 24 insertions(+), 177 deletions(-)
 
-Index: multipath-tools-120123/kpartx/bsd.c
+Index: multipath-tools-130222/kpartx/bsd.c
 ===================================================================
---- multipath-tools-120123.orig/kpartx/bsd.c
-+++ multipath-tools-120123/kpartx/bsd.c
+--- multipath-tools-130222.orig/kpartx/bsd.c
++++ multipath-tools-130222/kpartx/bsd.c
 @@ -50,10 +50,10 @@ int
  read_bsd_pt(int fd, struct slice all, struct slice *sp, int ns) {
        struct bsd_disklabel *l;
@@ -60,10 +60,10 @@ Index: multipath-tools-120123/kpartx/bsd.c
 -      }
        return n;
  }
-Index: multipath-tools-120123/kpartx/dos.c
+Index: multipath-tools-130222/kpartx/dos.c
 ===================================================================
---- multipath-tools-120123.orig/kpartx/dos.c
-+++ multipath-tools-120123/kpartx/dos.c
+--- multipath-tools-130222.orig/kpartx/dos.c
++++ multipath-tools-130222/kpartx/dos.c
 @@ -16,7 +16,7 @@ is_extended(int type) {
  }
  
@@ -92,11 +92,11 @@ Index: multipath-tools-120123/kpartx/dos.c
                }
        }
        return n;
-Index: multipath-tools-120123/kpartx/kpartx.c
+Index: multipath-tools-130222/kpartx/kpartx.c
 ===================================================================
---- multipath-tools-120123.orig/kpartx/kpartx.c
-+++ multipath-tools-120123/kpartx/kpartx.c
-@@ -190,7 +190,7 @@ get_hotplug_device(void)
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -192,7 +192,7 @@ get_hotplug_device(void)
  
  int
  main(int argc, char **argv){
@@ -105,7 +105,7 @@ Index: multipath-tools-120123/kpartx/kpartx.c
        int fd = -1;
        struct slice all;
        struct pt *ptp;
-@@ -380,49 +380,30 @@ main(int argc, char **argv){
+@@ -381,49 +381,30 @@ main(int argc, char **argv){
                else
                        continue;
  
@@ -169,7 +169,7 @@ Index: multipath-tools-120123/kpartx/kpartx.c
  
                        break;
  
-@@ -461,16 +442,10 @@ main(int argc, char **argv){
+@@ -462,16 +443,10 @@ main(int argc, char **argv){
                case ADD:
                case UPDATE:
                        /* ADD and UPDATE share the same code that adds new partitions. */
@@ -187,7 +187,7 @@ Index: multipath-tools-120123/kpartx/kpartx.c
                                if (safe_sprintf(partname, "%s%s%d",
                                             mapname, delim, j+1)) {
                                        fprintf(stderr, "partname too small\n");
-@@ -511,72 +486,6 @@ main(int argc, char **argv){
+@@ -512,72 +487,6 @@ main(int argc, char **argv){
                                               slices[j].minor, slices[j].size,
                                               DM_TARGET, params);
                        }
@@ -260,10 +260,10 @@ Index: multipath-tools-120123/kpartx/kpartx.c
  
                        if (what == ADD) {
                                /* Skip code that removes devmappings for deleted partitions */
-Index: multipath-tools-120123/kpartx/kpartx.h
+Index: multipath-tools-130222/kpartx/kpartx.h
 ===================================================================
---- multipath-tools-120123.orig/kpartx/kpartx.h
-+++ multipath-tools-120123/kpartx/kpartx.h
+--- multipath-tools-130222.orig/kpartx/kpartx.h
++++ multipath-tools-130222/kpartx/kpartx.h
 @@ -24,7 +24,6 @@
  struct slice {
        uint64_t start;
@@ -272,10 +272,10 @@ Index: multipath-tools-120123/kpartx/kpartx.h
        int major;
        int minor;
  };
-Index: multipath-tools-120123/kpartx/sun.c
+Index: multipath-tools-130222/kpartx/sun.c
 ===================================================================
---- multipath-tools-120123.orig/kpartx/sun.c
-+++ multipath-tools-120123/kpartx/sun.c
+--- multipath-tools-130222.orig/kpartx/sun.c
++++ multipath-tools-130222/kpartx/sun.c
 @@ -62,8 +62,8 @@ int
  read_sun_pt(int fd, struct slice all, struct slice *sp, int ns) {
        struct sun_disk_label *l;
similarity index 69%
rename from multipath-tools/patches/0013-RH-dont-remove-map-on-enomem.patch
rename to multipath-tools/patches/0010-RH-dont-remove-map-on-enomem.patch
index b7ee42c4320fc1c08cbecad71b582a97d49cf4b1..1740c107652c6482efa38f20390a52520ed97f02 100644 (file)
@@ -2,11 +2,11 @@
  multipathd/main.c |    3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
-Index: multipath-tools-120518/multipathd/main.c
+Index: multipath-tools-130222/multipathd/main.c
 ===================================================================
---- multipath-tools-120518.orig/multipathd/main.c
-+++ multipath-tools-120518/multipathd/main.c
-@@ -993,7 +993,8 @@ mpvec_garbage_collector (struct vectors
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -990,7 +990,8 @@ mpvec_garbage_collector (struct vectors
                return;
  
        vector_foreach_slot (vecs->mpvec, mpp, i) {
diff --git a/multipath-tools/patches/0012-RH-kpartx-msg.patch b/multipath-tools/patches/0012-RH-kpartx-msg.patch
new file mode 100644 (file)
index 0000000..7584c84
--- /dev/null
@@ -0,0 +1,24 @@
+---
+ kpartx/lopart.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/kpartx/lopart.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/lopart.c
++++ multipath-tools-130222/kpartx/lopart.c
+@@ -205,13 +205,13 @@ find_unused_loop_device (void)
+               fprintf(stderr,
+                   "mount: Could not find any loop device, and, according to %s,\n"
+                   "       this kernel does not know about the loop device.\n"
+-                  "       (If so, then recompile or `insmod loop.o'.)",
++                  "       (If so, then recompile or `modprobe loop'.)",
+                     PROC_DEVICES);
+           else
+               fprintf(stderr,
+                   "mount: Could not find any loop device. Maybe this kernel does not know\n"
+-                  "       about the loop device (then recompile or `insmod loop.o'), or\n"
++                  "       about the loop device (then recompile or `modprobe loop'), or\n"
+                   "       maybe /dev/loop# has the wrong major number?");
+       } else
diff --git a/multipath-tools/patches/0013-RHBZ-883981-cleanup-rpmdiff-issues.patch b/multipath-tools/patches/0013-RHBZ-883981-cleanup-rpmdiff-issues.patch
new file mode 100644 (file)
index 0000000..03bce17
--- /dev/null
@@ -0,0 +1,148 @@
+---
+ Makefile.inc                       |    9 +++++----
+ kpartx/Makefile                    |    2 +-
+ libmpathpersist/Makefile           |    4 ++--
+ libmultipath/Makefile              |    1 +
+ libmultipath/checkers/Makefile     |    2 +-
+ libmultipath/prioritizers/Makefile |    2 +-
+ multipath/Makefile                 |    2 +-
+ multipathd/Makefile                |    5 +++--
+ 8 files changed, 15 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-130222/Makefile.inc
+===================================================================
+--- multipath-tools-130222.orig/Makefile.inc
++++ multipath-tools-130222/Makefile.inc
+@@ -23,15 +23,15 @@ endif
+ prefix      = 
+ exec_prefix = $(prefix)
+-bindir      = $(exec_prefix)/sbin
++bindir      = $(exec_prefix)/usr/sbin
+ libudevdir  = ${prefix}/lib/udev
+ multipathdir = $(TOPDIR)/libmultipath
+ mandir      = $(prefix)/usr/share/man/man8
+ man5dir     = $(prefix)/usr/share/man/man5
+ man3dir      = $(prefix)/usr/share/man/man3
+ rcdir     = $(prefix)/etc/rc.d/init.d
+-syslibdir   = $(prefix)/$(LIB)
+-libdir            = $(prefix)/$(LIB)/multipath
++syslibdir   = $(prefix)/usr/$(LIB)
++libdir            = $(prefix)/usr/$(LIB)/multipath
+ unitdir     = $(prefix)/lib/systemd/system
+ mpathpersistdir = $(TOPDIR)/libmpathpersist
+@@ -42,8 +42,9 @@ ifndef RPM_OPT_FLAGS
+       RPM_OPT_FLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
+ endif
++LDFLAGS     += -Wl,-z,relro
+ OPTFLAGS     = $(RPM_OPT_FLAGS) -Wunused -Wstrict-prototypes
+-CFLAGS             = $(OPTFLAGS) -fPIC -DLIB_STRING=\"${LIB}\"
++CFLAGS             = $(OPTFLAGS) -DLIB_STRING=\"${LIB}\"
+ SHARED_FLAGS = -shared
+ %.o:  %.c
+Index: multipath-tools-130222/multipathd/Makefile
+===================================================================
+--- multipath-tools-130222.orig/multipathd/Makefile
++++ multipath-tools-130222/multipathd/Makefile
+@@ -5,9 +5,10 @@ include ../Makefile.inc
+ #
+ # basic flags setting
+ #
+-CFLAGS += -I$(multipathdir) -I$(mpathpersistdir)
++CFLAGS += -fPIE -DPIE -I$(multipathdir) -I$(mpathpersistdir)
+ LDFLAGS += -lpthread -ldevmapper -lreadline -ludev -ldl \
+-         -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist
++         -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \
++         -Wl,-z,now -pie
+ #
+ # debuging stuff
+Index: multipath-tools-130222/kpartx/Makefile
+===================================================================
+--- multipath-tools-130222.orig/kpartx/Makefile
++++ multipath-tools-130222/kpartx/Makefile
+@@ -4,7 +4,7 @@
+ #
+ include ../Makefile.inc
+-CFLAGS += -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
++CFLAGS += -fPIC -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+ LIBDM_API_COOKIE = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_set_cookie' /usr/include/libdevmapper.h)
+Index: multipath-tools-130222/libmpathpersist/Makefile
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/Makefile
++++ multipath-tools-130222/libmpathpersist/Makefile
+@@ -10,7 +10,7 @@ DEVLIB = libmpathpersist.so
+ LIBS = $(DEVLIB).$(SONAME)
+-CFLAGS += -I$(multipathdir) -I$(mpathpersistdir) 
++CFLAGS += -fPIC -I$(multipathdir) -I$(mpathpersistdir)
+ LIBDEPS +=  -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
+ OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o 
+@@ -19,7 +19,7 @@ all: $(LIBS)
+ $(LIBS): 
+-      $(CC) -Wall -fPIC -c $(CFLAGS) *.c 
++      $(CC) -Wall -c $(CFLAGS) *.c
+       $(CC)  -shared $(LIBDEPS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS)
+       ln -s $(LIBS) $(DEVLIB)
+       $(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz        
+Index: multipath-tools-130222/libmultipath/Makefile
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/Makefile
++++ multipath-tools-130222/libmultipath/Makefile
+@@ -8,6 +8,7 @@ SONAME=0
+ DEVLIB = libmultipath.so
+ LIBS = $(DEVLIB).$(SONAME)
+ LIBDEPS = -lpthread -ldl -ldevmapper -ludev
++CFLAGS += -fPIC
+ OBJS = memory.o parser.o vector.o devmapper.o \
+        hwtable.o blacklist.o util.o dmparser.o config.o \
+Index: multipath-tools-130222/libmultipath/checkers/Makefile
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers/Makefile
++++ multipath-tools-130222/libmultipath/checkers/Makefile
+@@ -14,7 +14,7 @@ LIBS= \
+       libcheckhp_sw.so \
+       libcheckrdac.so
+-CFLAGS += -I..
++CFLAGS += -fPIC -I..
+ all: $(LIBS)
+Index: multipath-tools-130222/libmultipath/prioritizers/Makefile
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/Makefile
++++ multipath-tools-130222/libmultipath/prioritizers/Makefile
+@@ -17,7 +17,7 @@ LIBS = \
+       libprioweightedpath.so \
+       libprioiet.so
+-CFLAGS += -I..
++CFLAGS += -fPIC -I..
+ all: $(LIBS)
+Index: multipath-tools-130222/multipath/Makefile
+===================================================================
+--- multipath-tools-130222.orig/multipath/Makefile
++++ multipath-tools-130222/multipath/Makefile
+@@ -6,7 +6,7 @@ include ../Makefile.inc
+ OBJS = main.o
+-CFLAGS += -I$(multipathdir)
++CFLAGS += -fPIC -I$(multipathdir)
+ LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
+ EXEC = multipath
diff --git a/multipath-tools/patches/0014-RH-handle-other-sector-sizes.patch b/multipath-tools/patches/0014-RH-handle-other-sector-sizes.patch
new file mode 100644 (file)
index 0000000..d07e0d8
--- /dev/null
@@ -0,0 +1,31 @@
+---
+ kpartx/gpt.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-120821/kpartx/gpt.c
+===================================================================
+--- multipath-tools-120821.orig/kpartx/gpt.c
++++ multipath-tools-120821/kpartx/gpt.c
+@@ -637,6 +637,7 @@ read_gpt_pt (int fd, struct slice all, s
+       uint32_t i;
+       int n = 0;
+         int last_used_index=-1;
++      int sector_size_mul = get_sector_size(fd)/512;
+       if (!find_valid_gpt (fd, &gpt, &ptes) || !gpt || !ptes) {
+               if (gpt)
+@@ -652,9 +653,11 @@ read_gpt_pt (int fd, struct slice all, s
+                       sp[n].size = 0;
+                       n++;
+               } else {
+-                      sp[n].start = __le64_to_cpu(ptes[i].starting_lba);
+-                      sp[n].size  = __le64_to_cpu(ptes[i].ending_lba) -
+-                              __le64_to_cpu(ptes[i].starting_lba) + 1;
++                      sp[n].start = sector_size_mul *
++                                    __le64_to_cpu(ptes[i].starting_lba);
++                      sp[n].size  = sector_size_mul *
++                                    (__le64_to_cpu(ptes[i].ending_lba) -
++                                     __le64_to_cpu(ptes[i].starting_lba) + 1);
+                         last_used_index=n;
+                       n++;
+               }
diff --git a/multipath-tools/patches/0015-RH-fix-output-buffer.patch b/multipath-tools/patches/0015-RH-fix-output-buffer.patch
new file mode 100644 (file)
index 0000000..ffbbaad
--- /dev/null
@@ -0,0 +1,62 @@
+---
+ libmultipath/print.c |   31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -8,6 +8,8 @@
+ #include <sys/stat.h>
+ #include <dirent.h>
+ #include <unistd.h>
++#include <string.h>
++#include <errno.h>
+ #include "checkers.h"
+ #include "vector.h"
+@@ -24,6 +26,7 @@
+ #include "switchgroup.h"
+ #include "devmapper.h"
+ #include "uevent.h"
++#include "debug.h"
+ #define MAX(x,y) (x > y) ? x : y
+ #define TAIL     (line + len - 1 - c)
+@@ -754,12 +757,32 @@ snprint_pathgroup (char * line, int len,
+ extern void
+ print_multipath_topology (struct multipath * mpp, int verbosity)
+ {
+-      char buff[MAX_LINE_LEN * MAX_LINES] = {};
++      int resize;
++      char *buff = NULL;
++      char *old = NULL;
++      int len, maxlen = MAX_LINE_LEN * MAX_LINES;
+-      memset(&buff[0], 0, MAX_LINE_LEN * MAX_LINES);
+-      snprint_multipath_topology(&buff[0], MAX_LINE_LEN * MAX_LINES,
+-                                 mpp, verbosity);
++      buff = MALLOC(maxlen);
++      do {
++              if (!buff) {
++                      if (old)
++                              FREE(old);
++                      condlog(0, "couldn't allocate memory for list: %s\n",
++                              strerror(errno));
++                      return;
++              }
++
++              len = snprint_multipath_topology(buff, maxlen, mpp, verbosity);
++              resize = (len == maxlen - 1);
++
++              if (resize) {
++                      maxlen *= 2;
++                      old = buff;
++                      buff = REALLOC(buff, maxlen);
++              }
++      } while (resize);
+       printf("%s", buff);
++      FREE(buff);
+ }
+ extern int
diff --git a/multipath-tools/patches/0015-RH-use-sync-support.patch b/multipath-tools/patches/0015-RH-use-sync-support.patch
deleted file mode 100644 (file)
index c5dee9d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
----
- libmultipath/devmapper.c |    2 ++
- 1 file changed, 2 insertions(+)
-
-Index: multipath-tools-120518/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-120518.orig/libmultipath/devmapper.c
-+++ multipath-tools-120518/libmultipath/devmapper.c
-@@ -1272,6 +1272,8 @@ dm_rename (char * old, char * new)
-               goto out;
-       if (!dm_task_run(dmt))
-               goto out;
-+      if (conf->daemon)
-+              dm_task_update_nodes();
-       r = 1;
- out:
diff --git a/multipath-tools/patches/0016-RH-change-configs.patch b/multipath-tools/patches/0016-RH-change-configs.patch
deleted file mode 100644 (file)
index 7942ea8..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
----
- libmultipath/config.c  |    1 
- libmultipath/hwtable.c |   65 -------------------------------------------------
- 2 files changed, 1 insertion(+), 65 deletions(-)
-
-Index: multipath-tools-120613/libmultipath/config.c
-===================================================================
---- multipath-tools-120613.orig/libmultipath/config.c
-+++ multipath-tools-120613/libmultipath/config.c
-@@ -515,6 +515,7 @@ load_config (char * file)
-       conf->checkint = DEFAULT_CHECKINT;
-       conf->max_checkint = MAX_CHECKINT(conf->checkint);
-       conf->find_multipaths = DEFAULT_FIND_MULTIPATHS;
-+      conf->fast_io_fail = 5;
-       /*
-        * preload default hwtable
-Index: multipath-tools-120613/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-120613.orig/libmultipath/hwtable.c
-+++ multipath-tools-120613/libmultipath/hwtable.c
-@@ -28,7 +28,6 @@ static struct hwentry default_hw[] = {
-               .product       = "Compellent Vol",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -50,7 +49,6 @@ static struct hwentry default_hw[] = {
-               .product       = "Xserve RAID ",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -72,7 +70,6 @@ static struct hwentry default_hw[] = {
-               .product       = "VV",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -88,7 +85,6 @@ static struct hwentry default_hw[] = {
-               .product       = "HSG80",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 hp_sw",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -104,7 +100,6 @@ static struct hwentry default_hw[] = {
-               .product       = "A6189A",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -121,7 +116,6 @@ static struct hwentry default_hw[] = {
-               .product       = "(MSA|HSV)1.0.*",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 hp_sw",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -137,7 +131,6 @@ static struct hwentry default_hw[] = {
-               .product       = "MSA VOLUME",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -153,7 +146,6 @@ static struct hwentry default_hw[] = {
-               .product       = "HSV1[01]1|HSV2[01]0|HSV300|HSV4[05]0",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -169,7 +161,6 @@ static struct hwentry default_hw[] = {
-               .product       = "MSA2[02]12fc|MSA2012i",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -185,7 +176,6 @@ static struct hwentry default_hw[] = {
-               .product       = "MSA2012sa|MSA23(12|24)(fc|i|sa)|MSA2000s VOLUME",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -202,7 +192,6 @@ static struct hwentry default_hw[] = {
-               .product       = "HSVX700",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 alua",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -219,7 +208,6 @@ static struct hwentry default_hw[] = {
-               .product       = "LOGICAL VOLUME.*",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -236,7 +224,6 @@ static struct hwentry default_hw[] = {
-               .product       = "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -258,7 +245,6 @@ static struct hwentry default_hw[] = {
-               .product       = "SAN DataDirector",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -280,7 +266,6 @@ static struct hwentry default_hw[] = {
-               .product       = "SYMMETRIX",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -297,7 +282,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "LUNZ",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 emc",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -314,7 +298,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "LUNZ",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -336,7 +319,6 @@ static struct hwentry default_hw[] = {
-               .product       = "CentricStor",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_SERIAL,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -352,7 +334,6 @@ static struct hwentry default_hw[] = {
-               .product       = "ETERNUS_DX(L|400|8000)",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -373,7 +354,6 @@ static struct hwentry default_hw[] = {
-               .product       = "OPEN-.*",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -389,7 +369,6 @@ static struct hwentry default_hw[] = {
-               .product       = "DF.*",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -411,7 +390,6 @@ static struct hwentry default_hw[] = {
-               .product       = "ProFibre 4000R",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -429,7 +407,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -447,7 +424,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -465,7 +441,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -483,7 +458,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -500,7 +474,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -518,7 +491,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -536,7 +508,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -554,7 +525,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -572,7 +542,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -589,7 +558,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^3542",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_SERIAL,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -606,7 +574,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^2105800",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_SERIAL,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -623,7 +590,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^2105F20",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_SERIAL,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -640,7 +606,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^1750500",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -657,7 +622,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^2107900",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -674,7 +638,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^2145",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -693,7 +656,6 @@ static struct hwentry default_hw[] = {
-               .uid_attribute = "ID_UID",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -712,7 +674,6 @@ static struct hwentry default_hw[] = {
-               .uid_attribute = "ID_UID",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -729,7 +690,6 @@ static struct hwentry default_hw[] = {
-               .product       = "^IPR.*",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = "1 alua",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -746,7 +706,6 @@ static struct hwentry default_hw[] = {
-               .product       = "1820N00",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -763,7 +722,6 @@ static struct hwentry default_hw[] = {
-               .product       = "2810XIV",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = 15,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -786,7 +744,6 @@ static struct hwentry default_hw[] = {
-               .product       = "VDASD",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -803,7 +760,6 @@ static struct hwentry default_hw[] = {
-               .product       = "3303      NVDISK",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = FAILOVER,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -820,7 +776,6 @@ static struct hwentry default_hw[] = {
-               .product       = "NVDISK",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 alua",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -838,7 +793,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -856,7 +810,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -874,7 +827,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -892,7 +844,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -914,7 +865,6 @@ static struct hwentry default_hw[] = {
-               .product       = "LUN.*",
-               .features      = "3 queue_if_no_path pg_init_retries 50",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .flush_on_last_del = FLUSH_ENABLED,
-@@ -936,7 +886,6 @@ static struct hwentry default_hw[] = {
-               .product       = "COMSTAR",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_SERIAL,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -957,7 +906,6 @@ static struct hwentry default_hw[] = {
-               .product       = "Nseries.*",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -978,7 +926,6 @@ static struct hwentry default_hw[] = {
-               .product       = "Axiom.*",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1001,7 +948,6 @@ static struct hwentry default_hw[] = {
-               .product       = "TP9[13]00",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1018,7 +964,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1035,7 +980,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1052,7 +996,6 @@ static struct hwentry default_hw[] = {
-               .product       = "DISK ARRAY",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 alua",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1075,7 +1018,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1097,7 +1039,6 @@ static struct hwentry default_hw[] = {
-               .product       = "(StorEdge 3510|T4)",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1113,7 +1054,6 @@ static struct hwentry default_hw[] = {
-               .product       = "FC2502",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1135,7 +1075,6 @@ static struct hwentry default_hw[] = {
-               .product       = "RAIGE VOLUME",
-               .features      = "1 queue_if_no_path",
-               .hwhandler     = DEFAULT_HWHANDLER,
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = MULTIBUS,
-               .pgfailback    = FAILBACK_UNDEF,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1151,7 +1090,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1169,7 +1107,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1187,7 +1124,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = "2 pg_init_retries 50",
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
-@@ -1204,7 +1140,6 @@ static struct hwentry default_hw[] = {
-               .bl_product    = "Universal Xport",
-               .features      = DEFAULT_FEATURES,
-               .hwhandler     = "1 rdac",
--              .selector      = DEFAULT_SELECTOR,
-               .pgpolicy      = GROUP_BY_PRIO,
-               .pgfailback    = -FAILBACK_IMMEDIATE,
-               .rr_weight     = RR_WEIGHT_NONE,
diff --git a/multipath-tools/patches/0016-RH-dont-print-ghost-messages.patch b/multipath-tools/patches/0016-RH-dont-print-ghost-messages.patch
new file mode 100644 (file)
index 0000000..3387424
--- /dev/null
@@ -0,0 +1,18 @@
+---
+ libmultipath/discovery.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -898,7 +898,8 @@ get_state (struct path * pp, int daemon)
+               c->timeout = DEF_TIMEOUT;
+       state = checker_check(c);
+       condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
+-      if (state != PATH_UP && strlen(checker_message(c)))
++      if (state != PATH_UP && state != PATH_GHOST &&
++          strlen(checker_message(c)))
+               condlog(3, "%s: checker msg is \"%s\"",
+                       pp->dev, checker_message(c));
+       return state;
diff --git a/multipath-tools/patches/0018-RH-fix-factorize.patch b/multipath-tools/patches/0018-RH-fix-factorize.patch
new file mode 100644 (file)
index 0000000..1dfcab5
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/config.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -437,6 +437,8 @@ restart:
+                       merge_hwe(hwe2, hwe1);
+                       if (hwe_strmatch(hwe2, hwe1) == 0) {
+                               vector_del_slot(hw, i);
++                              free_hwe(hwe1);
++                              n -= 1;
+                               /*
+                                * Play safe here; we have modified
+                                * the original vector so the outer
diff --git a/multipath-tools/patches/0019-RH-fix-sockets.patch b/multipath-tools/patches/0019-RH-fix-sockets.patch
new file mode 100644 (file)
index 0000000..8639e20
--- /dev/null
@@ -0,0 +1,48 @@
+---
+ libmpathpersist/mpath_updatepr.c |    3 ++-
+ libmultipath/uxsock.c            |    4 ++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/libmpathpersist/mpath_updatepr.c
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_updatepr.c
++++ multipath-tools-130222/libmpathpersist/mpath_updatepr.c
+@@ -14,6 +14,7 @@
+ #include <debug.h>
+ #include "memory.h"
+ #include "../libmultipath/uxsock.h"
++#include "../libmultipath/defaults.h"
+ unsigned long mem_allocated;    /* Total memory used in Bytes */
+@@ -25,7 +26,7 @@ int update_prflag(char * arg1, char * ar
+       size_t len;
+       int ret = 0;
+-      fd = ux_socket_connect("/var/run/multipathd.sock");
++      fd = ux_socket_connect(DEFAULT_SOCKET);
+       if (fd == -1) {
+               condlog (0, "ux socket connect error");
+               return 1 ;
+Index: multipath-tools-130222/libmultipath/uxsock.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/uxsock.c
++++ multipath-tools-130222/libmultipath/uxsock.c
+@@ -31,7 +31,7 @@ int ux_socket_connect(const char *name)
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_LOCAL;
+       addr.sun_path[0] = '\0';
+-      len = strlen(name) + 1;
++      len = strlen(name) + 1 + sizeof(sa_family_t);
+       strncpy(&addr.sun_path[1], name, len);
+       fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+@@ -62,7 +62,7 @@ int ux_socket_listen(const char *name)
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_LOCAL;
+       addr.sun_path[0] = '\0';
+-      len = strlen(name) + 1;
++      len = strlen(name) + 1 + sizeof(sa_family_t);
+       strncpy(&addr.sun_path[1], name, len);
+       if (bind(fd, (struct sockaddr *)&addr, len) == -1) {
diff --git a/multipath-tools/patches/0020-RHBZ-907360-static-pthread-init.patch b/multipath-tools/patches/0020-RHBZ-907360-static-pthread-init.patch
new file mode 100644 (file)
index 0000000..bafa5ce
--- /dev/null
@@ -0,0 +1,41 @@
+---
+ libmultipath/uevent.c |   12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/uevent.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/uevent.c
++++ multipath-tools-130222/libmultipath/uevent.c
+@@ -53,8 +53,10 @@ typedef int (uev_trigger)(struct uevent
+ pthread_t uevq_thr;
+ LIST_HEAD(uevq);
+-pthread_mutex_t uevq_lock, *uevq_lockp = &uevq_lock;
+-pthread_cond_t  uev_cond,  *uev_condp  = &uev_cond;
++pthread_mutex_t uevq_lock = PTHREAD_MUTEX_INITIALIZER;
++pthread_mutex_t *uevq_lockp = &uevq_lock;
++pthread_cond_t uev_cond = PTHREAD_COND_INITIALIZER;
++pthread_cond_t *uev_condp = &uev_cond;
+ uev_trigger *my_uev_trigger;
+ void * my_trigger_data;
+ int servicing_uev;
+@@ -409,10 +411,6 @@ int uevent_listen(void)
+        * thereby not getting to empty the socket's receive buffer queue
+        * often enough.
+        */
+-      INIT_LIST_HEAD(&uevq);
+-
+-      pthread_mutex_init(uevq_lockp, NULL);
+-      pthread_cond_init(uev_condp, NULL);
+       pthread_cleanup_push(uevq_stop, NULL);
+       monitor = udev_monitor_new_from_netlink(conf->udev, "udev");
+@@ -525,8 +523,6 @@ out:
+       if (need_failback)
+               err = failback_listen();
+       pthread_cleanup_pop(1);
+-      pthread_mutex_destroy(uevq_lockp);
+-      pthread_cond_destroy(uev_condp);
+       return err;
+ }
diff --git a/multipath-tools/patches/0021-RHBZ-919119-respect-kernel-cmdline.patch b/multipath-tools/patches/0021-RHBZ-919119-respect-kernel-cmdline.patch
new file mode 100644 (file)
index 0000000..cea1e48
--- /dev/null
@@ -0,0 +1,30 @@
+---
+ multipath/multipath.rules     |    2 ++
+ multipathd/multipathd.service |    1 +
+ 2 files changed, 3 insertions(+)
+
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -2,6 +2,8 @@
+ # so name them after their devmap name
+ SUBSYSTEM!="block", GOTO="end_mpath"
++IMPORT{cmdline}="nompath"
++ENV{nompath}=="?*", GOTO="end_mpath"
+ ENV{MPATH_SBIN_PATH}="/sbin"
+ TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
+Index: multipath-tools-130222/multipathd/multipathd.service
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.service
++++ multipath-tools-130222/multipathd/multipathd.service
+@@ -3,6 +3,7 @@ Description=Device-Mapper Multipath Devi
+ Before=iscsi.service iscsid.service lvm2-activation-early.service
+ After=syslog.target
+ ConditionPathExists=/etc/multipath.conf
++ConditionKernelCommandLine=!nompath
+ DefaultDependencies=no
+ Conflicts=shutdown.target
diff --git a/multipath-tools/patches/0022-RH-multipathd-check-wwids.patch b/multipath-tools/patches/0022-RH-multipathd-check-wwids.patch
new file mode 100644 (file)
index 0000000..b6e8f42
--- /dev/null
@@ -0,0 +1,16 @@
+---
+ multipathd/main.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1363,6 +1363,7 @@ configure (struct vectors * vecs, int st
+       sync_maps_state(mpvec);
+       vector_foreach_slot(mpvec, mpp, i){
++              remember_wwid(mpp->wwid);
+               update_map_pr(mpp);
+       }
diff --git a/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch b/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch
new file mode 100644 (file)
index 0000000..6de04bf
--- /dev/null
@@ -0,0 +1,239 @@
+---
+ libmultipath/discovery.c |    3 +
+ libmultipath/wwids.c     |   86 +++++++++++++++++++++++++++++++++++++++++++++++
+ libmultipath/wwids.h     |    1 
+ multipath/main.c         |   26 ++++++++++++--
+ multipath/multipath.8    |    5 ++
+ 5 files changed, 115 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -53,7 +53,8 @@ store_pathinfo (vector pathvec, vector h
+               goto out;
+       }
+       pp->udev = udev_device_ref(udevice);
+-      err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
++      err = pathinfo(pp, hwtable,
++                     (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
+       if (err)
+               goto out;
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -82,6 +82,92 @@ write_out_wwid(int fd, char *wwid) {
+ }
+ int
++do_remove_wwid(int fd, char *str) {
++      char buf[4097];
++      char *ptr;
++      off_t start = 0;
++      int bytes;
++
++      while (1) {
++              if (lseek(fd, start, SEEK_SET) < 0) {
++                      condlog(0, "wwid file read lseek failed : %s",
++                              strerror(errno));
++                      return -1;
++              }
++              bytes = read(fd, buf, 4096);
++              if (bytes < 0) {
++                      if (errno == EINTR || errno == EAGAIN)
++                              continue;
++                      condlog(0, "failed to read from wwids file : %s",
++                              strerror(errno));
++                      return -1;
++              }
++              if (!bytes) /* didn't find wwid to remove */
++                      return 1;
++              buf[bytes] = '\0';
++              ptr = strstr(buf, str);
++              if (ptr != NULL) {
++                      condlog(3, "found '%s'", str);
++                      if (lseek(fd, start + (ptr - buf), SEEK_SET) < 0) {
++                              condlog(0, "write lseek failed : %s",
++                                              strerror(errno));
++                              return -1;
++                      }
++                      while (1) {
++                              if (write(fd, "#", 1) < 0) {
++                                      if (errno == EINTR || errno == EAGAIN)
++                                              continue;
++                                      condlog(0, "failed to write to wwids file : %s", strerror(errno));
++                                      return -1;
++                              }
++                              return 0;
++                      }
++              }
++              ptr = strrchr(buf, '\n');
++              if (ptr == NULL) { /* shouldn't happen, assume it is EOF */
++                      condlog(4, "couldn't find newline, assuming end of file");
++                      return 1;
++              }
++              start = start + (ptr - buf) + 1;
++      }
++}
++
++
++int
++remove_wwid(char *wwid) {
++      int fd, len, can_write;
++      char *str;
++      int ret = -1;
++
++      len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */
++      str = malloc(len);
++      if (str == NULL) {
++              condlog(0, "can't allocate memory to remove wwid : %s",
++                      strerror(errno));
++              return -1;
++      }
++      if (snprintf(str, len, "/%s/\n", wwid) >= len) {
++              condlog(0, "string overflow trying to remove wwid");
++              goto out;
++      }
++      condlog(3, "removing line '%s' from wwids file", str);
++      fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
++      if (fd < 0)
++              goto out;
++      if (!can_write) {
++              condlog(0, "cannot remove wwid. wwids file is read-only");
++              goto out_file;
++      }
++      ret = do_remove_wwid(fd, str);
++
++out_file:
++      close(fd);
++out:
++      free(str);
++      return ret;
++}
++
++int
+ check_wwids_file(char *wwid, int write_wwid)
+ {
+       int fd, can_write, found, ret;
+Index: multipath-tools-130222/libmultipath/wwids.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.h
++++ multipath-tools-130222/libmultipath/wwids.h
+@@ -15,5 +15,6 @@
+ int should_multipath(struct path *pp, vector pathvec);
+ int remember_wwid(char *wwid);
+ int check_wwids_file(char *wwid, int write_wwid);
++int remove_wwid(char *wwid);
+ #endif /* _WWIDS_H */
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -83,7 +83,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-c|-w] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [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);
+@@ -104,6 +104,7 @@ usage (char * progname)
+               "  -B      treat the bindings file as read only\n" \
+               "  -p      policy failover|multibus|group_by_serial|group_by_prio\n" \
+               "  -b fil  bindings file location\n" \
++              "  -w      remove a device from the wwids file\n" \
+               "  -p pol  force all maps to specified path grouping policy :\n" \
+               "          . failover            one path per priority group\n" \
+               "          . multibus            all paths in one priority group\n" \
+@@ -212,7 +213,6 @@ get_dm_mpvec (vector curmp, vector pathv
+               if (!conf->dry_run)
+                       reinstate_paths(mpp);
+-              remember_wwid(mpp->wwid);
+       }
+       return 0;
+ }
+@@ -262,7 +262,7 @@ configure (void)
+       /*
+        * if we have a blacklisted device parameter, exit early
+        */
+-      if (dev && conf->dev_type == DEV_DEVNODE &&
++      if (dev && conf->dev_type == DEV_DEVNODE && conf->dry_run != 3 &&
+           (filter_devnode(conf->blist_devnode,
+                           conf->elist_devnode, dev) > 0)) {
+               if (conf->dry_run == 2)
+@@ -284,6 +284,17 @@ configure (void)
+                               condlog(3, "scope is nul");
+                       goto out;
+               }
++              if (conf->dry_run == 3) {
++                      r = remove_wwid(refwwid);
++                      if (r == 0)
++                              printf("wwid '%s' removed\n", refwwid);
++                      else if (r == 1) {
++                              printf("wwid '%s' not in wwids file\n",
++                                      refwwid);
++                              r = 0;
++                      }
++                      goto out;
++              }
+               condlog(3, "scope limited to %s", refwwid);
+               if (conf->dry_run == 2) {
+                       if (check_wwids_file(refwwid, 0) == 0){
+@@ -439,7 +450,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtqw")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -504,6 +515,9 @@ main (int argc, char *argv[])
+               case 'h':
+                       usage(argv[0]);
+                       exit(0);
++              case 'w':
++                      conf->dry_run = 3;
++                      break;
+               case ':':
+                       fprintf(stderr, "Missing option argument\n");
+                       usage(argv[0]);
+@@ -555,6 +569,10 @@ main (int argc, char *argv[])
+               condlog(0, "the -c option requires a path to check");
+               goto out;
+       }
++      if (conf->dry_run == 3 && !conf->dev) {
++              condlog(0, "the -w option requires a device");
++              goto out;
++      }
+       if (conf->remove == FLUSH_ONE) {
+               if (conf->dev_type == DEV_DEVMAP) {
+                       r = dm_suspend_and_flush_map(conf->dev);
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
+ .RB [\| \-b\ \c
+ .IR bindings_file \|]
+ .RB [\| \-d \|]
+-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r \|]
++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w \|]
+ .RB [\| \-p\ \c
+ .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
+ .RB [\| device \|]
+@@ -68,6 +68,9 @@ check if a block device should be a path
+ .B \-q
+ allow device tables with queue_if_no_path when multipathd is not running
+ .TP
++.B \-w
++remove the wwid for the specified device from the wwids file
++.TP
+ .BI \-p " policy"
+ force new maps to use the specified policy:
+ .RS 1.2i
diff --git a/multipath-tools/patches/0024-RH-multipath-wipe-wwids.patch b/multipath-tools/patches/0024-RH-multipath-wipe-wwids.patch
new file mode 100644 (file)
index 0000000..b91836c
--- /dev/null
@@ -0,0 +1,164 @@
+---
+ libmultipath/wwids.c  |   44 ++++++++++++++++++++++++++++++++++++++++++++
+ libmultipath/wwids.h  |    1 +
+ multipath/main.c      |   29 +++++++++++++++++++++++++++--
+ multipath/multipath.8 |    5 ++++-
+ 4 files changed, 76 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -82,6 +82,50 @@ write_out_wwid(int fd, char *wwid) {
+ }
+ int
++replace_wwids(vector mp)
++{
++      int i, fd, can_write;
++      struct multipath * mpp;
++      size_t len;
++      int ret = -1;
++
++      fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
++      if (fd < 0)
++              goto out;
++      if (!can_write) {
++              condlog(0, "cannot replace wwids. wwids file is read-only");
++              goto out_file;
++      }
++      if (ftruncate(fd, 0) < 0) {
++              condlog(0, "cannot truncate wwids file : %s", strerror(errno));
++              goto out_file;
++      }
++      len = strlen(WWIDS_FILE_HEADER);
++      if (write_all(fd, WWIDS_FILE_HEADER, len) != len) {
++              condlog(0, "Can't write wwid file header : %s",
++                      strerror(errno));
++              /* cleanup partially written header */
++              if (ftruncate(fd, 0) < 0)
++                      condlog(0, "Cannot truncate header : %s",
++                              strerror(errno));
++              goto out_file;
++      }
++      if (!mp || !mp->allocated) {
++              ret = 0;
++              goto out_file;
++      }
++      vector_foreach_slot(mp, mpp, i) {
++              if (write_out_wwid(fd, mpp->wwid) < 0)
++                      goto out_file;
++      }
++      ret = 0;
++out_file:
++      close(fd);
++out:
++      return ret;
++}
++
++int
+ do_remove_wwid(int fd, char *str) {
+       char buf[4097];
+       char *ptr;
+Index: multipath-tools-130222/libmultipath/wwids.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.h
++++ multipath-tools-130222/libmultipath/wwids.h
+@@ -16,5 +16,6 @@ int should_multipath(struct path *pp, ve
+ int remember_wwid(char *wwid);
+ int check_wwids_file(char *wwid, int write_wwid);
+ int remove_wwid(char *wwid);
++int replace_wwids(vector mp);
+ #endif /* _WWIDS_H */
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -83,7 +83,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-c|-w] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-c|-w|-W] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [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);
+@@ -105,6 +105,7 @@ usage (char * progname)
+               "  -p      policy failover|multibus|group_by_serial|group_by_prio\n" \
+               "  -b fil  bindings file location\n" \
+               "  -w      remove a device from the wwids file\n" \
++              "  -W      reset the wwids file include only the current devices\n" \
+               "  -p pol  force all maps to specified path grouping policy :\n" \
+               "          . failover            one path per priority group\n" \
+               "          . multibus            all paths in one priority group\n" \
+@@ -450,7 +451,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtqw")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtqwW")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -518,6 +519,9 @@ main (int argc, char *argv[])
+               case 'w':
+                       conf->dry_run = 3;
+                       break;
++              case 'W':
++                      conf->dry_run = 4;
++                      break;
+               case ':':
+                       fprintf(stderr, "Missing option argument\n");
+                       usage(argv[0]);
+@@ -573,6 +577,27 @@ main (int argc, char *argv[])
+               condlog(0, "the -w option requires a device");
+               goto out;
+       }
++      if (conf->dry_run == 4) {
++              struct multipath * mpp;
++              int i;
++              vector curmp;
++
++              curmp = vector_alloc();
++              if (!curmp) {
++                      condlog(0, "can't allocate memory for mp list");
++                      goto out;
++              }
++              if (dm_get_maps(curmp) == 0)
++                      r = replace_wwids(curmp);
++              if (r == 0)
++                      printf("successfully reset wwids\n");
++              vector_foreach_slot_backwards(curmp, mpp, i) {
++                      vector_del_slot(curmp, i);
++                      free_multipath(mpp, KEEP_PATHS);
++              }
++              vector_free(curmp);
++              goto out;
++      }
+       if (conf->remove == FLUSH_ONE) {
+               if (conf->dev_type == DEV_DEVMAP) {
+                       r = dm_suspend_and_flush_map(conf->dev);
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
+ .RB [\| \-b\ \c
+ .IR bindings_file \|]
+ .RB [\| \-d \|]
+-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w \|]
++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w | \-W \|]
+ .RB [\| \-p\ \c
+ .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
+ .RB [\| device \|]
+@@ -71,6 +71,9 @@ allow device tables with queue_if_no_pat
+ .B \-w
+ remove the wwid for the specified device from the wwids file
+ .TP
++.B \-W
++reset the wwids file to only include the current multipath devices
++.TP
+ .BI \-p " policy"
+ force new maps to use the specified policy:
+ .RS 1.2i
diff --git a/multipath-tools/patches/0025-UPBZ-916668_add_maj_min.patch b/multipath-tools/patches/0025-UPBZ-916668_add_maj_min.patch
new file mode 100644 (file)
index 0000000..615533d
--- /dev/null
@@ -0,0 +1,29 @@
+---
+ multipathd/main.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -537,7 +537,8 @@ rescan:
+                       goto fail_map;
+       if (retries >= 0) {
+-              condlog(2, "%s path added to devmap %s", pp->dev, mpp->alias);
++              condlog(2, "%s [%s]: path added to devmap %s",
++                      pp->dev, pp->dev_t, mpp->alias);
+               return 0;
+       }
+       else
+@@ -642,8 +643,8 @@ ev_remove_path (struct path *pp, struct
+                       }
+                       sync_map_state(mpp);
+-                      condlog(2, "%s: path removed from map %s",
+-                              pp->dev, mpp->alias);
++                      condlog(2, "%s [%s]: path removed from map %s",
++                              pp->dev, pp->dev_t, mpp->alias);
+               }
+       }
diff --git a/multipath-tools/patches/0026-fix-checker-time.patch b/multipath-tools/patches/0026-fix-checker-time.patch
new file mode 100644 (file)
index 0000000..e05ef58
--- /dev/null
@@ -0,0 +1,23 @@
+---
+ multipathd/main.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1226,11 +1226,10 @@ check_path (struct vectors * vecs, struc
+                                       pp->checkint = 2 * pp->checkint;
+                               else
+                                       pp->checkint = conf->max_checkint;
+-
+-                              pp->tick = pp->checkint;
+-                              condlog(4, "%s: delay next check %is",
+-                                      pp->dev_t, pp->tick);
+                       }
++                      pp->tick = pp->checkint;
++                      condlog(4, "%s: delay next check %is",
++                              pp->dev_t, pp->tick);
+               }
+       }
+       else if (newstate == PATH_DOWN) {
diff --git a/multipath-tools/patches/0027-RH-get-wwid.patch b/multipath-tools/patches/0027-RH-get-wwid.patch
new file mode 100644 (file)
index 0000000..04217b4
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/structs_vec.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/structs_vec.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs_vec.c
++++ multipath-tools-130222/libmultipath/structs_vec.c
+@@ -106,7 +106,7 @@ orphan_paths (vector pathvec, struct mul
+ static void
+ set_multipath_wwid (struct multipath * mpp)
+ {
+-      if (mpp->wwid)
++      if (strlen(mpp->wwid))
+               return;
+       dm_get_uuid(mpp->alias, mpp->wwid);
diff --git a/multipath-tools/patches/0028-RHBZ-929078-refresh-udev-dev.patch b/multipath-tools/patches/0028-RHBZ-929078-refresh-udev-dev.patch
new file mode 100644 (file)
index 0000000..c14ddb5
--- /dev/null
@@ -0,0 +1,55 @@
+---
+ libmultipath/discovery.c |    2 +-
+ multipathd/main.c        |   19 ++++++++++++++++++-
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -1034,7 +1034,7 @@ pathinfo (struct path *pp, vector hwtabl
+               }
+       }
+-      if (path_state == PATH_UP && (mask & DI_WWID) && !strlen(pp->wwid))
++      if ((mask & DI_WWID) && !strlen(pp->wwid))
+               get_uid(pp);
+       if (mask & DI_BLACKLIST && mask & DI_WWID) {
+               if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -376,7 +376,7 @@ static int
+ uev_add_path (struct uevent *uev, struct vectors * vecs)
+ {
+       struct path *pp;
+-      int ret;
++      int ret, i;
+       condlog(2, "%s: add path (uevent)", uev->kernel);
+       if (strstr(uev->kernel, "..") != NULL) {
+@@ -393,6 +393,23 @@ uev_add_path (struct uevent *uev, struct
+                       uev->kernel);
+               if (pp->mpp)
+                       return 0;
++              if (!strlen(pp->wwid)) {
++                      udev_device_unref(pp->udev);
++                      pp->udev = udev_device_ref(uev->udev);
++                      ret = pathinfo(pp, conf->hwtable,
++                                     DI_ALL | DI_BLACKLIST);
++                      if (ret == 2) {
++                              i = find_slot(vecs->pathvec, (void *)pp);
++                              if (i != -1)
++                                      vector_del_slot(vecs->pathvec, i);
++                              free_path(pp);
++                              return 0;
++                      } else if (ret == 1) {
++                              condlog(0, "%s: failed to reinitialize path",
++                                      uev->kernel);
++                              return 1;
++                      }
++              }
+       } else {
+               /*
+                * get path vital state
diff --git a/multipath-tools/patches/0029-RH-no-prio-put-msg.patch b/multipath-tools/patches/0029-RH-no-prio-put-msg.patch
new file mode 100644 (file)
index 0000000..6ebdae0
--- /dev/null
@@ -0,0 +1,20 @@
+---
+ libmultipath/prio.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/prio.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prio.c
++++ multipath-tools-130222/libmultipath/prio.c
+@@ -162,7 +162,10 @@ void prio_put (struct prio * dst)
+       if (!dst)
+               return;
+-      src = prio_lookup(dst->name);
++      if (!strlen(dst->name))
++              src = NULL;
++      else
++              src = prio_lookup(dst->name);
+       memset(dst, 0x0, sizeof(struct prio));
+       free_prio(src);
+ }
diff --git a/multipath-tools/patches/0030-RHBZ-916528-override-queue-no-daemon.patch b/multipath-tools/patches/0030-RHBZ-916528-override-queue-no-daemon.patch
new file mode 100644 (file)
index 0000000..e663ded
--- /dev/null
@@ -0,0 +1,200 @@
+---
+ libmultipath/dict.c               |   10 ++++------
+ libmultipath/structs.h            |    2 +-
+ multipathd/cli.c                  |    3 +++
+ multipathd/cli.h                  |    2 ++
+ multipathd/cli_handlers.c         |   18 ++++++++++++++++++
+ multipathd/cli_handlers.h         |    2 ++
+ multipathd/main.c                 |    2 ++
+ multipathd/multipathd.init.redhat |   14 ++++++++++----
+ 8 files changed, 42 insertions(+), 11 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -438,14 +438,11 @@ def_queue_without_daemon(vector strvec)
+       if (!buff)
+               return 1;
+-      if (!strncmp(buff, "off", 3) || !strncmp(buff, "no", 2) ||
+-          !strncmp(buff, "0", 1))
+-              conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
+-      else if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
++      if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
+                !strncmp(buff, "1", 1))
+               conf->queue_without_daemon = QUE_NO_DAEMON_ON;
+       else
+-              conf->queue_without_daemon = QUE_NO_DAEMON_UNDEF;
++              conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
+       free(buff);
+       return 0;
+@@ -2670,8 +2667,9 @@ snprint_def_queue_without_daemon (char *
+       case QUE_NO_DAEMON_OFF:
+               return snprintf(buff, len, "\"no\"");
+       case QUE_NO_DAEMON_ON:
+-      case QUE_NO_DAEMON_UNDEF:
+               return snprintf(buff, len, "\"yes\"");
++      case QUE_NO_DAEMON_FORCE:
++              return snprintf(buff, len, "\"forced\"");
+       }
+       return 0;
+ }
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -67,9 +67,9 @@ enum pgstates {
+ };
+ enum queue_without_daemon_states {
+-      QUE_NO_DAEMON_UNDEF,
+       QUE_NO_DAEMON_OFF,
+       QUE_NO_DAEMON_ON,
++      QUE_NO_DAEMON_FORCE,
+ };
+ enum pgtimeouts {
+Index: multipath-tools-130222/multipathd/cli.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli.c
++++ multipath-tools-130222/multipathd/cli.c
+@@ -162,6 +162,7 @@ load_keys (void)
+       r += add_key(keys, "resize", RESIZE, 0);
+       r += add_key(keys, "reset", RESET, 0);
+       r += add_key(keys, "reload", RELOAD, 0);
++      r += add_key(keys, "forcequeueing", FORCEQ, 0);
+       r += add_key(keys, "disablequeueing", DISABLEQ, 0);
+       r += add_key(keys, "restorequeueing", RESTOREQ, 0);
+       r += add_key(keys, "paths", PATHS, 0);
+@@ -459,6 +460,8 @@ cli_init (void) {
+       add_handler(GETPRSTATUS+MAP, NULL);
+       add_handler(SETPRSTATUS+MAP, NULL);
+       add_handler(UNSETPRSTATUS+MAP, NULL);
++      add_handler(FORCEQ+DAEMON, NULL);
++      add_handler(RESTOREQ+DAEMON, NULL);
+       return 0;
+ }
+Index: multipath-tools-130222/multipathd/cli.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli.h
++++ multipath-tools-130222/multipathd/cli.h
+@@ -10,6 +10,7 @@ enum {
+       __RESIZE,
+       __RESET,
+       __RELOAD,
++      __FORCEQ,
+       __DISABLEQ,
+       __RESTOREQ,
+       __PATHS,
+@@ -45,6 +46,7 @@ enum {
+ #define RESIZE                (1 << __RESIZE)
+ #define RESET         (1 << __RESET)
+ #define RELOAD                (1 << __RELOAD)
++#define FORCEQ                (1 << __FORCEQ)
+ #define DISABLEQ      (1 << __DISABLEQ)
+ #define RESTOREQ      (1 << __RESTOREQ)
+ #define PATHS         (1 << __PATHS)
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -628,6 +628,24 @@ cli_resize(void *v, char **reply, int *l
+ }
+ int
++cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data)
++{
++      condlog(2, "force queue_without_daemon (operator)");
++      if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
++              conf->queue_without_daemon = QUE_NO_DAEMON_FORCE;
++      return 0;
++}
++
++int
++cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data)
++{
++      condlog(2, "restore queue_without_daemon (operator)");
++      if (conf->queue_without_daemon == QUE_NO_DAEMON_FORCE)
++              conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
++      return 0;
++}
++
++int
+ cli_restore_queueing(void *v, char **reply, int *len, void *data)
+ {
+       struct vectors * vecs = (struct vectors *)data;
+Index: multipath-tools-130222/multipathd/cli_handlers.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.h
++++ multipath-tools-130222/multipathd/cli_handlers.h
+@@ -28,6 +28,8 @@ int cli_suspend(void * v, char ** reply,
+ int cli_resume(void * v, char ** reply, int * len, void * data);
+ int cli_reinstate(void * v, char ** reply, int * len, void * data);
+ int cli_fail(void * v, char ** reply, int * len, void * data);
++int cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data);
++int cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data);
+ int cli_quit(void * v, char ** reply, int * len, void * data);
+ int cli_shutdown(void * v, char ** reply, int * len, void * data);
+ int cli_reassign (void * v, char ** reply, int * len, void * data);
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -904,6 +904,8 @@ uxlsnrloop (void * ap)
+       set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
+       set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
+       set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
++      set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
++      set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
+       umask(077);
+       uxsock_listen(&uxsock_trigger, ap);
+Index: multipath-tools-130222/multipathd/multipathd.init.redhat
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.init.redhat
++++ multipath-tools-130222/multipathd/multipathd.init.redhat
+@@ -81,23 +81,28 @@ force_stop() {
+       echo
+ }
+-stop() {
++check_root() {
+         root_dev=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' /etc/mtab)
+       dm_num=`dmsetup info -c --noheadings -o minor $root_dev 2> /dev/null`
+       if [ $? -eq 0 ]; then
+               root_dm_device="dm-$dm_num"
+               [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
+       fi
++}
+-      force_stop
++force_queue_without_daemon() {
++      $DAEMON forcequeueing daemon
+ }
+ restart() {
+-      stop
++      force_queue_without_daemon
++      check_root
++      force_stop
+       start
+ }
+ force_restart() {
++      force_queue_without_daemon
+       force_stop
+       start
+ }
+@@ -115,7 +120,8 @@ start)
+       start
+       ;;
+ stop)
+-      stop
++      check_root
++      force_stop
+       ;;
+ force-stop)
+       force_stop
diff --git a/multipath-tools/patches/0031-RHBZ-957188-kpartx-use-dm-name.patch b/multipath-tools/patches/0031-RHBZ-957188-kpartx-use-dm-name.patch
new file mode 100644 (file)
index 0000000..282c517
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ kpartx/kpartx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -348,7 +348,7 @@ main(int argc, char **argv){
+       if (delim == NULL) {
+               delim = malloc(DELIM_SIZE);
+               memset(delim, 0, DELIM_SIZE);
+-              set_delimiter(device, delim);
++              set_delimiter(mapname, delim);
+       }
+       fd = open(device, O_RDONLY);
diff --git a/multipath-tools/patches/0032-RHBZ-956464-mpathconf-defaults.patch b/multipath-tools/patches/0032-RHBZ-956464-mpathconf-defaults.patch
new file mode 100644 (file)
index 0000000..d63c32e
--- /dev/null
@@ -0,0 +1,19 @@
+---
+ multipath/mpathconf |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/multipath/mpathconf
+===================================================================
+--- multipath-tools-130222.orig/multipath/mpathconf
++++ multipath-tools-130222/multipath/mpathconf
+@@ -31,8 +31,8 @@ function usage
+       echo "Commands:"
+       echo "Enable: --enable "
+       echo "Disable: --disable"
+-      echo "Set user_friendly_names (Default n): --user_friendly_names <y|n>"
+-      echo "Set find_multipaths (Default n): --find_multipaths <y|n>"
++      echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
++      echo "Set find_multipaths (Default y): --find_multipaths <y|n>"
+       echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
+       echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
+       echo ""
diff --git a/multipath-tools/patches/0033-RHBZ-829963-e-series-conf.patch b/multipath-tools/patches/0033-RHBZ-829963-e-series-conf.patch
new file mode 100644 (file)
index 0000000..d8fc119
--- /dev/null
@@ -0,0 +1,44 @@
+This patch provides hwtable updates for NETAPP/LSI/ENGENIO E-Series arrays,
+utilizing new features to detect TPGS support, automatically.
+
+Signed-off-by: Sean Stewart <Sean.Stewart@netapp.com>
+
+---
+---
+ libmultipath/hwtable.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -1046,9 +1046,13 @@ static struct hwentry default_hw[] = {
+               .checker_name  = RDAC,
+               .prio_name     = PRIO_RDAC,
+       },
+-      /* LSI/Engenio/NetApp E-Series RDAC storage */
++      /* LSI/Engenio/NetApp E-Series RDAC storage
++       *
++       * Maintainer : Sean Stewart
++       * Mail : sean.stewart@netapp.com
++       */
+       {
+-              .vendor        = "(LSI|ENGENIO)",
++              .vendor        = "(NETAPP|LSI|ENGENIO)",
+               .product       = "INF-01-00",
+               .bl_product    = "Universal Xport",
+               .features      = "2 pg_init_retries 50",
+@@ -1056,10 +1060,12 @@ static struct hwentry default_hw[] = {
+               .pgpolicy      = GROUP_BY_PRIO,
+               .pgfailback    = -FAILBACK_IMMEDIATE,
+               .rr_weight     = RR_WEIGHT_NONE,
+-              .no_path_retry = 15,
++              .no_path_retry = 30,
+               .checker_name  = RDAC,
+               .prio_name     = PRIO_RDAC,
+               .prio_args     = NULL,
++              .detect_prio   = DETECT_PRIO_ON,
++              .retain_hwhandler = RETAIN_HWHANDLER_ON,
+       },
+       {
+               .vendor        = "STK",
diff --git a/multipath-tools/patches/0034-RHBZ-851416-mpathconf-display.patch b/multipath-tools/patches/0034-RHBZ-851416-mpathconf-display.patch
new file mode 100644 (file)
index 0000000..e9e00ce
--- /dev/null
@@ -0,0 +1,53 @@
+---
+ multipath/mpathconf |   21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/multipath/mpathconf
+===================================================================
+--- multipath-tools-130222.orig/multipath/mpathconf
++++ multipath-tools-130222/multipath/mpathconf
+@@ -159,7 +159,7 @@ if [ -z "$MODULE" -o "$MODULE" = "y" ];
+ fi
+ if [ "$MULTIPATHD" = "y" ]; then
+-      if service multipathd status > /dev/null ; then
++      if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
+               HAVE_MULTIPATHD=1
+       else
+               HAVE_MULTIPATHD=0
+@@ -210,8 +210,17 @@ if [ -n "$SHOW_STATUS" ]; then
+                       echo "dm_multipath module is not loaded"
+               fi
+       fi
+-      if [ -n "$HAVE_MULTIPATHD" ]; then
+-              service multipathd status
++      if [ -z "$HAVE_MULTIPATHD" ]; then
++              if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
++                      HAVE_MULTIPATHD=1
++              else
++                      HAVE_MULTIPATHD=0
++              fi
++      fi
++      if [ "$HAVE_MULTIPATHD" = 1 ]; then
++              echo "multipathd is running"
++      else
++              echo "multipathd is not running"
+       fi
+       exit 0
+ fi
+@@ -301,12 +310,12 @@ if [ "$ENABLE" = 1 ]; then
+               modprobe dm_multipath
+       fi
+       if [ "$HAVE_MULTIPATHD" = 0 ]; then
+-              service multipathd start
++              systemctl start multipathd.service
+       fi
+ elif [ "$ENABLE" = 0 ]; then
+       if [ "$HAVE_MULTIPATHD" = 1 ]; then
+-              service multipathd stop
++              systemctl stop multipathd.service
+       fi
+ elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
+-      service multipathd reload
++      systemctl reload multipathd.service
+ fi
diff --git a/multipath-tools/patches/0035-RHBZ-891921-list-mpp.patch b/multipath-tools/patches/0035-RHBZ-891921-list-mpp.patch
new file mode 100644 (file)
index 0000000..b0bb7a2
--- /dev/null
@@ -0,0 +1,33 @@
+---
+ libmultipath/print.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -422,6 +422,16 @@ snprint_path_serial (char * buff, size_t
+ }
+ static int
++snprint_path_mpp (char * buff, size_t len, struct path * pp)
++{
++      if (!pp->mpp)
++              return snprintf(buff, len, "[orphan]");
++      if (!pp->mpp->alias)
++              return snprintf(buff, len, "[unknown]");
++      return snprint_str(buff, len, pp->mpp->alias);
++}
++
++static int
+ snprint_path_checker (char * buff, size_t len, struct path * pp)
+ {
+       struct checker * c = &pp->checker;
+@@ -464,6 +474,7 @@ struct path_data pd[] = {
+       {'p', "pri",           0, snprint_pri},
+       {'S', "size",          0, snprint_path_size},
+       {'z', "serial",        0, snprint_path_serial},
++      {'m', "multipath",     0, snprint_path_mpp},
+       {0, NULL, 0 , NULL}
+ };
diff --git a/multipath-tools/patches/0036-RHBZ-949239-load-multipath-module.patch b/multipath-tools/patches/0036-RHBZ-949239-load-multipath-module.patch
new file mode 100644 (file)
index 0000000..04a6f68
--- /dev/null
@@ -0,0 +1,16 @@
+---
+ multipathd/multipathd.service |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: multipath-tools-130222/multipathd/multipathd.service
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.service
++++ multipath-tools-130222/multipathd/multipathd.service
+@@ -10,6 +10,7 @@ Conflicts=shutdown.target
+ [Service]
+ Type=forking
+ PIDFile=/var/run/multipathd.pid
++ExecStartPre=/sbin/modprobe dm-multipath
+ ExecStart=/sbin/multipathd
+ ExecReload=/sbin/multipathd reconfigure
+ #ExecStop=/path/to/scrip delete-me if not necessary
diff --git a/multipath-tools/patches/0037-RHBZ-768873-fix-rename.patch b/multipath-tools/patches/0037-RHBZ-768873-fix-rename.patch
new file mode 100644 (file)
index 0000000..7e05bd0
--- /dev/null
@@ -0,0 +1,87 @@
+---
+ libmultipath/devmapper.c |   45 ---------------------------------------------
+ libmultipath/devmapper.h |    1 -
+ libmultipath/propsel.c   |    2 --
+ 3 files changed, 48 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -917,51 +917,6 @@ out:
+       return r;
+ }
+-extern char *
+-dm_get_name(char *uuid)
+-{
+-      struct dm_task *dmt;
+-      struct dm_info info;
+-      char *prefixed_uuid, *name = NULL;
+-      const char *nametmp;
+-
+-      dmt = dm_task_create(DM_DEVICE_INFO);
+-      if (!dmt)
+-              return NULL;
+-
+-      prefixed_uuid = MALLOC(UUID_PREFIX_LEN + strlen(uuid) + 1);
+-      if (!prefixed_uuid) {
+-              condlog(0, "cannot create prefixed uuid : %s",
+-                      strerror(errno));
+-              goto freeout;
+-      }
+-      sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid);
+-      if (!dm_task_set_uuid(dmt, prefixed_uuid))
+-              goto freeout;
+-
+-      if (!dm_task_run(dmt))
+-              goto freeout;
+-
+-      if (!dm_task_get_info(dmt, &info) || !info.exists)
+-              goto freeout;
+-
+-      nametmp = dm_task_get_name(dmt);
+-      if (nametmp && strlen(nametmp)) {
+-              name = MALLOC(strlen(nametmp) + 1);
+-              if (name)
+-                      strcpy(name, nametmp);
+-      } else {
+-              condlog(2, "%s: no device-mapper name found", uuid);
+-      }
+-
+-freeout:
+-      if (prefixed_uuid)
+-              FREE(prefixed_uuid);
+-      dm_task_destroy(dmt);
+-
+-      return name;
+-}
+-
+ int
+ dm_geteventnr (char *name)
+ {
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -40,7 +40,6 @@ int dm_remove_partmaps (const char * map
+ int dm_get_uuid(char *name, char *uuid);
+ int dm_get_info (char * mapname, struct dm_info ** dmi);
+ int dm_rename (char * old, char * new);
+-char * dm_get_name(char * uuid);
+ int dm_reassign(const char * mapname);
+ int dm_reassign_table(const char *name, char *old, char *new);
+ int dm_setgeometry(struct multipath *mpp);
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -263,8 +263,6 @@ select_alias (struct multipath * mp)
+                                       conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
+               }
+               if (mp->alias == NULL)
+-                      mp->alias = dm_get_name(mp->wwid);
+-              if (mp->alias == NULL)
+                       mp->alias = STRDUP(mp->wwid);
+       }
diff --git a/multipath-tools/patches/0038-RHBZ-799860-netapp-config.patch b/multipath-tools/patches/0038-RHBZ-799860-netapp-config.patch
new file mode 100644 (file)
index 0000000..3b91f9b
--- /dev/null
@@ -0,0 +1,16 @@
+---
+ libmultipath/hwtable.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -794,6 +794,7 @@ static struct hwentry default_hw[] = {
+               .prio_name     = PRIO_ONTAP,
+               .prio_args     = NULL,
+               .retain_hwhandler = RETAIN_HWHANDLER_ON,
++              .user_friendly_names = USER_FRIENDLY_NAMES_OFF,
+               .detect_prio   = DETECT_PRIO_ON,
+       },
+       /*
diff --git a/multipath-tools/patches/0039-RH-detect-prio-fix.patch b/multipath-tools/patches/0039-RH-detect-prio-fix.patch
new file mode 100644 (file)
index 0000000..941a570
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ libmultipath/propsel.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -384,10 +384,17 @@ select_getuid (struct path * pp)
+ void
+ detect_prio(struct path * pp)
+ {
++      int ret;
+       struct prio *p = &pp->prio;
+-      if (get_target_port_group_support(pp->fd) > 0)
+-              prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS);
++      if (get_target_port_group_support(pp->fd) <= 0)
++              return;
++      ret = get_target_port_group(pp->fd);
++      if (ret < 0)
++              return;
++      if (get_asymmetric_access_state(pp->fd, ret) < 0)
++              return;
++      prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS);
+ }
+ extern int
diff --git a/multipath-tools/patches/0040-RH-bindings-fix.patch b/multipath-tools/patches/0040-RH-bindings-fix.patch
new file mode 100644 (file)
index 0000000..c56f352
--- /dev/null
@@ -0,0 +1,101 @@
+---
+ libmultipath/alias.c |   39 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/alias.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.c
++++ multipath-tools-130222/libmultipath/alias.c
+@@ -46,11 +46,11 @@ format_devname(char *name, int id, int l
+       memset(name,0, len);
+       strcpy(name, prefix);
+       for (pos = len - 1; pos >= prefix_len; pos--) {
++              id--;
+               name[pos] = 'a' + id % 26;
+               if (id < 26)
+                       break;
+               id /= 26;
+-              id--;
+       }
+       memmove(name + prefix_len, name + pos, len - pos);
+       name[prefix_len + len - pos] = '\0';
+@@ -66,13 +66,22 @@ scan_devname(char *alias, char *prefix)
+       if (!prefix || strncmp(alias, prefix, strlen(prefix)))
+               return -1;
++      if (strlen(alias) == strlen(prefix))
++              return -1;      
++
++      if (strlen(alias) > strlen(prefix) + 7)
++              /* id of 'aaaaaaaa' overflows int */
++              return -1;
++
+       c = alias + strlen(prefix);
+       while (*c != '\0' && *c != ' ' && *c != '\t') {
++              if (*c < 'a' || *c > 'z')
++                      return -1;
+               i = *c - 'a';
+               n = ( n * 26 ) + i;
++              if (n < 0)
++                      return -1;
+               c++;
+-              if (*c < 'a' || *c > 'z')
+-                      break;
+               n++;
+       }
+@@ -84,7 +93,9 @@ lookup_binding(FILE *f, char *map_wwid,
+ {
+       char buf[LINE_MAX];
+       unsigned int line_nr = 0;
+-      int id = 0;
++      int id = 1;
++      int biggest_id = 1;
++      int smallest_bigger_id = INT_MAX;
+       *map_alias = NULL;
+@@ -100,8 +111,12 @@ lookup_binding(FILE *f, char *map_wwid,
+               if (!alias) /* blank line */
+                       continue;
+               curr_id = scan_devname(alias, prefix);
+-              if (curr_id >= id)
+-                      id = curr_id + 1;
++              if (curr_id == id)
++                      id++;
++              if (curr_id > biggest_id)
++                      biggest_id = curr_id;
++              if (curr_id > id && curr_id < smallest_bigger_id)
++                      smallest_bigger_id = curr_id;
+               wwid = strtok(NULL, " \t");
+               if (!wwid){
+                       condlog(3,
+@@ -116,11 +131,17 @@ lookup_binding(FILE *f, char *map_wwid,
+                       if (*map_alias == NULL)
+                               condlog(0, "Cannot copy alias from bindings "
+                                       "file : %s", strerror(errno));
+-                      return id;
++                      return 0;
+               }
+       }
+       condlog(3, "No matching wwid [%s] in bindings file.", map_wwid);
+-      return id;
++      if (id < 0) {
++              condlog(0, "no more available user_friendly_names");
++              return 0;
++      }
++      if (id < smallest_bigger_id)
++              return id;
++      return biggest_id + 1;
+ }
+ static int
+@@ -254,7 +275,7 @@ get_user_friendly_alias(char *wwid, char
+               return NULL;
+       }
+-      if (!alias && can_write && !bindings_read_only)
++      if (!alias && can_write && !bindings_read_only && id)
+               alias = allocate_binding(fd, wwid, id, prefix);
+       fclose(f);
diff --git a/multipath-tools/patches/0041-RH-check-for-erofs.patch b/multipath-tools/patches/0041-RH-check-for-erofs.patch
new file mode 100644 (file)
index 0000000..d29d78d
--- /dev/null
@@ -0,0 +1,121 @@
+---
+ libmultipath/configure.c |    7 ------
+ libmultipath/devmapper.c |   53 ++++++++++++++++++++++-------------------------
+ libmultipath/devmapper.h |    2 -
+ 3 files changed, 25 insertions(+), 37 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -384,24 +384,17 @@ domap (struct multipath * mpp, char * pa
+               r = dm_addmap_create(mpp, params);
+-              if (!r)
+-                      r = dm_addmap_create_ro(mpp, params);
+-
+               lock_multipath(mpp, 0);
+               break;
+       case ACT_RELOAD:
+               r = dm_addmap_reload(mpp, params);
+-              if (!r)
+-                      r = dm_addmap_reload_ro(mpp, params);
+               if (r)
+                       r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias);
+               break;
+       case ACT_RESIZE:
+               r = dm_addmap_reload(mpp, params);
+-              if (!r)
+-                      r = dm_addmap_reload_ro(mpp, params);
+               if (r)
+                       r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1);
+               break;
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -298,42 +298,39 @@ dm_addmap (int task, const char *target,
+       return r;
+ }
+-static int
+-_dm_addmap_create (struct multipath *mpp, char * params, int ro) {
+-      int r;
+-      r = dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro);
+-      /*
+-       * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
+-       * Failing the second part leaves an empty map. Clean it up.
+-       */
+-      if (!r && dm_map_present(mpp->alias)) {
+-              condlog(3, "%s: failed to load map (a path might be in use)",
+-                      mpp->alias);
+-              dm_flush_map_nosync(mpp->alias);
++extern int
++dm_addmap_create (struct multipath *mpp, char * params) {
++      int ro;
++
++      for (ro = 0; ro <= 1; ro++) {
++              int err;
++
++              if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro))
++                      return 1;
++              /*
++               * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
++               * Failing the second part leaves an empty map. Clean it up.
++               */
++              err = errno;
++              if (dm_map_present(mpp->alias)) {
++                      condlog(3, "%s: failed to load map (a path might be in use)", mpp->alias);
++                      dm_flush_map_nosync(mpp->alias);
++              }
++              if (err != EROFS)
++                      break;
+       }
+-      return r;
++      return 0;
+ }
+ #define ADDMAP_RW 0
+ #define ADDMAP_RO 1
+ extern int
+-dm_addmap_create (struct multipath *mpp, char *params) {
+-      return _dm_addmap_create(mpp, params, ADDMAP_RW);
+-}
+-
+-extern int
+-dm_addmap_create_ro (struct multipath *mpp, char *params) {
+-      return _dm_addmap_create(mpp, params, ADDMAP_RO);
+-}
+-
+-extern int
+ dm_addmap_reload (struct multipath *mpp, char *params) {
+-      return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW);
+-}
+-
+-extern int
+-dm_addmap_reload_ro (struct multipath *mpp, char *params) {
++      if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW))
++              return 1;
++      if (errno != EROFS)
++              return 0;
+       return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO);
+ }
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -12,9 +12,7 @@ int dm_drv_version (unsigned int * versi
+ int dm_simplecmd_flush (int, const char *, int);
+ int dm_simplecmd_noflush (int, const char *);
+ int dm_addmap_create (struct multipath *mpp, char *params);
+-int dm_addmap_create_ro (struct multipath *mpp, char *params);
+ int dm_addmap_reload (struct multipath *mpp, char *params);
+-int dm_addmap_reload_ro (struct multipath *mpp, char *params);
+ int dm_map_present (const char *);
+ int dm_get_map(char *, unsigned long long *, char *);
+ int dm_get_status(char *, char *);
diff --git a/multipath-tools/patches/0042-UP-fix-signal-handling.patch b/multipath-tools/patches/0042-UP-fix-signal-handling.patch
new file mode 100644 (file)
index 0000000..4b4b40b
--- /dev/null
@@ -0,0 +1,493 @@
+---
+ libmultipath/file.c        |    4 +-
+ libmultipath/lock.c        |    9 ----
+ libmultipath/lock.h        |    1 
+ libmultipath/log_pthread.c |   22 -----------
+ libmultipath/waiter.c      |    2 -
+ multipathd/cli_handlers.c  |    4 +-
+ multipathd/main.c          |   90 ++++++++++++++++++++-------------------------
+ multipathd/main.h          |    3 +
+ multipathd/uxlsnr.c        |   21 +++++++---
+ multipathd/uxlsnr.h        |    3 +
+ 10 files changed, 65 insertions(+), 94 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/file.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/file.c
++++ multipath-tools-130222/libmultipath/file.c
+@@ -98,7 +98,7 @@ lock_file(int fd, char *file_name)
+       sigaddset(&set, SIGALRM);
+       sigaction(SIGALRM, &act, &oldact);
+-      sigprocmask(SIG_UNBLOCK, &set, &oldset);
++      pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
+       alarm(FILE_TIMEOUT);
+       err = fcntl(fd, F_SETLKW, &lock);
+@@ -112,7 +112,7 @@ lock_file(int fd, char *file_name)
+                       condlog(0, "%s is locked. Giving up.", file_name);
+       }
+-      sigprocmask(SIG_SETMASK, &oldset, NULL);
++      pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+       sigaction(SIGALRM, &oldact, NULL);
+       return err;
+ }
+Index: multipath-tools-130222/libmultipath/lock.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/lock.c
++++ multipath-tools-130222/libmultipath/lock.c
+@@ -1,16 +1,7 @@
+ #include <pthread.h>
+-#include <signal.h>
+ #include "lock.h"
+ #include <stdio.h>
+-void block_signal (int signum, sigset_t *old)
+-{
+-      sigset_t set;
+-      sigemptyset(&set);
+-      sigaddset(&set, signum);
+-      pthread_sigmask(SIG_BLOCK, &set, old);
+-}
+-
+ void cleanup_lock (void * data)
+ {
+       unlock ((*(struct mutex_lock *)data));
+Index: multipath-tools-130222/libmultipath/lock.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/lock.h
++++ multipath-tools-130222/libmultipath/lock.h
+@@ -29,6 +29,5 @@ struct mutex_lock {
+ #endif
+ void cleanup_lock (void * data);
+-void block_signal(int signum, sigset_t *old);
+ #endif /* _LOCK_H */
+Index: multipath-tools-130222/libmultipath/log_pthread.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/log_pthread.c
++++ multipath-tools-130222/libmultipath/log_pthread.c
+@@ -22,26 +22,13 @@ pthread_cond_t logev_cond;
+ int logq_running;
+-static void
+-sigusr1 (int sig)
+-{
+-      pthread_mutex_lock(&logq_lock);
+-      log_reset("multipathd");
+-      pthread_mutex_unlock(&logq_lock);
+-}
+-
+ void log_safe (int prio, const char * fmt, va_list ap)
+ {
+-      sigset_t old;
+-
+       if (log_thr == (pthread_t)0) {
+               syslog(prio, fmt, ap);
+               return;
+       }
+-      block_signal(SIGUSR1, &old);
+-      block_signal(SIGHUP, NULL);
+-
+       pthread_mutex_lock(&logq_lock);
+       log_enqueue(prio, fmt, ap);
+       pthread_mutex_unlock(&logq_lock);
+@@ -49,8 +36,6 @@ void log_safe (int prio, const char * fm
+       pthread_mutex_lock(&logev_lock);
+       pthread_cond_signal(&logev_cond);
+       pthread_mutex_unlock(&logev_lock);
+-
+-      pthread_sigmask(SIG_SETMASK, &old, NULL);
+ }
+ void log_thread_flush (void)
+@@ -81,15 +66,8 @@ static void flush_logqueue (void)
+ static void * log_thread (void * et)
+ {
+-      struct sigaction sig;
+       int running;
+-      sig.sa_handler = sigusr1;
+-      sigemptyset(&sig.sa_mask);
+-      sig.sa_flags = 0;
+-      if (sigaction(SIGUSR1, &sig, NULL) < 0)
+-              logdbg(stderr, "Cannot set signal handler");
+-
+       pthread_mutex_lock(&logev_lock);
+       logq_running = 1;
+       pthread_mutex_unlock(&logev_lock);
+Index: multipath-tools-130222/libmultipath/waiter.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/waiter.c
++++ multipath-tools-130222/libmultipath/waiter.c
+@@ -157,8 +157,6 @@ void *waitevent (void *et)
+       waiter = (struct event_thread *)et;
+       pthread_cleanup_push(free_waiter, et);
+-      block_signal(SIGUSR1, NULL);
+-      block_signal(SIGHUP, NULL);
+       while (1) {
+               r = waiteventloop(waiter);
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -939,8 +939,8 @@ int
+ cli_shutdown (void * v, char ** reply, int * len, void * data)
+ {
+       condlog(3, "shutdown (operator)");
+-
+-      return exit_daemon(0);
++      exit_daemon();
++      return 0;
+ }
+ int
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -17,6 +17,7 @@
+ #include <limits.h>
+ #include <linux/oom.h>
+ #include <libudev.h>
++#include <semaphore.h>
+ #include <mpath_persist.h>
+ /*
+@@ -52,6 +53,7 @@
+ #include <wwids.h>
+ #include <pgpolicies.h>
+ #include <uevent.h>
++#include <log.h>
+ #include "main.h"
+ #include "pidfile.h"
+@@ -81,13 +83,11 @@ struct mpath_event_param
+ unsigned int mpath_mx_alloc_len;
+-pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
+-pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
+-
+ int logsink;
+ enum daemon_status running_state;
+ pid_t daemon_pid;
++static sem_t exit_sem;
+ /*
+  * global copy of vecs for use in sig handlers
+  */
+@@ -838,9 +838,6 @@ out:
+ static void *
+ ueventloop (void * ap)
+ {
+-      block_signal(SIGUSR1, NULL);
+-      block_signal(SIGHUP, NULL);
+-
+       if (uevent_listen())
+               condlog(0, "error starting uevent listener");
+@@ -850,9 +847,6 @@ ueventloop (void * ap)
+ static void *
+ uevqloop (void * ap)
+ {
+-      block_signal(SIGUSR1, NULL);
+-      block_signal(SIGHUP, NULL);
+-
+       if (uevent_dispatch(&uev_trigger, ap))
+               condlog(0, "error starting uevent dispatcher");
+@@ -861,9 +855,6 @@ uevqloop (void * ap)
+ static void *
+ uxlsnrloop (void * ap)
+ {
+-      block_signal(SIGUSR1, NULL);
+-      block_signal(SIGHUP, NULL);
+-
+       if (cli_init())
+               return NULL;
+@@ -913,18 +904,10 @@ uxlsnrloop (void * ap)
+       return NULL;
+ }
+-int
+-exit_daemon (int status)
++void
++exit_daemon (void)
+ {
+-      if (status != 0)
+-              fprintf(stderr, "bad exit status. see daemon.log\n");
+-
+-      if (running_state != DAEMON_SHUTDOWN) {
+-              pthread_mutex_lock(&exit_mutex);
+-              pthread_cond_signal(&exit_cond);
+-              pthread_mutex_unlock(&exit_mutex);
+-      }
+-      return status;
++      sem_post(&exit_sem);
+ }
+ const char *
+@@ -1287,7 +1270,6 @@ checkerloop (void *ap)
+       struct path *pp;
+       int count = 0;
+       unsigned int i;
+-      sigset_t old;
+       mlockall(MCL_CURRENT | MCL_FUTURE);
+       vecs = (struct vectors *)ap;
+@@ -1301,7 +1283,6 @@ checkerloop (void *ap)
+       }
+       while (1) {
+-              block_signal(SIGHUP, &old);
+               pthread_cleanup_push(cleanup_lock, &vecs->lock);
+               lock(vecs->lock);
+               pthread_testcancel();
+@@ -1325,7 +1306,6 @@ checkerloop (void *ap)
+               }
+               lock_cleanup_pop(vecs->lock);
+-              pthread_sigmask(SIG_SETMASK, &old, NULL);
+               sleep(1);
+       }
+       return NULL;
+@@ -1485,36 +1465,56 @@ signal_set(int signo, void (*func) (int)
+               return (osig.sa_handler);
+ }
++void
++handle_signals(void)
++{
++      if (reconfig_sig && running_state == DAEMON_RUNNING) {
++              condlog(2, "reconfigure (signal)");
++              pthread_cleanup_push(cleanup_lock,
++                              &gvecs->lock);
++              lock(gvecs->lock);
++              pthread_testcancel();
++              reconfigure(gvecs);
++              lock_cleanup_pop(gvecs->lock);
++      }
++      if (log_reset_sig) {
++              condlog(2, "reset log (signal)");
++              pthread_mutex_lock(&logq_lock);
++              log_reset("multipathd");
++              pthread_mutex_unlock(&logq_lock);
++      }
++      reconfig_sig = 0;
++      log_reset_sig = 0;
++}
++
+ static void
+ sighup (int sig)
+ {
+-      condlog(2, "reconfigure (SIGHUP)");
+-
+-      if (running_state != DAEMON_RUNNING)
+-              return;
+-
+-      reconfigure(gvecs);
+-
+-#ifdef _DEBUG_
+-      dbg_free_final(NULL);
+-#endif
++      reconfig_sig = 1;
+ }
+ static void
+ sigend (int sig)
+ {
+-      exit_daemon(0);
++      exit_daemon();
+ }
+ static void
+ sigusr1 (int sig)
+ {
+-      condlog(3, "SIGUSR1 received");
++      log_reset_sig = 1;
+ }
+ static void
+ signal_init(void)
+ {
++      sigset_t set;
++
++      sigemptyset(&set);
++      sigaddset(&set, SIGHUP);
++      sigaddset(&set, SIGUSR1);
++      pthread_sigmask(SIG_BLOCK, &set, NULL);
++
+       signal_set(SIGHUP, sighup);
+       signal_set(SIGUSR1, sigusr1);
+       signal_set(SIGINT, sigend);
+@@ -1587,10 +1587,11 @@ child (void * param)
+       struct vectors * vecs;
+       struct multipath * mpp;
+       int i;
+-      sigset_t set;
+       int rc, pid_rc;
+       mlockall(MCL_CURRENT | MCL_FUTURE);
++      sem_init(&exit_sem, 0, 0);
++      signal_init();
+       setup_thread_attr(&misc_attr, 64 * 1024, 1);
+       setup_thread_attr(&waiter_attr, 32 * 1024, 1);
+@@ -1650,7 +1651,6 @@ child (void * param)
+       if (!vecs)
+               exit(1);
+-      signal_init();
+       setscheduler();
+       set_oom_adj();
+@@ -1693,25 +1693,17 @@ child (void * param)
+       }
+       pthread_attr_destroy(&misc_attr);
+-      pthread_mutex_lock(&exit_mutex);
+       /* Startup complete, create logfile */
+       pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
+       /* Ignore errors, we can live without */
+       running_state = DAEMON_RUNNING;
+-      pthread_cond_wait(&exit_cond, &exit_mutex);
+-      /* Need to block these to avoid deadlocking */
+-      sigemptyset(&set);
+-      sigaddset(&set, SIGTERM);
+-      sigaddset(&set, SIGINT);
+-      pthread_sigmask(SIG_BLOCK, &set, NULL);
+       /*
+        * exit path
+        */
++      while(sem_wait(&exit_sem) != 0); /* Do nothing */
+       running_state = DAEMON_SHUTDOWN;
+-      pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+-      block_signal(SIGHUP, NULL);
+       lock(vecs->lock);
+       if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
+               vector_foreach_slot(vecs->mpvec, mpp, i)
+Index: multipath-tools-130222/multipathd/main.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.h
++++ multipath-tools-130222/multipathd/main.h
+@@ -16,7 +16,7 @@ struct prin_resp;
+ extern pid_t daemon_pid;
+-int exit_daemon(int);
++void exit_daemon(void);
+ const char * daemon_status(void);
+ int reconfigure (struct vectors *);
+ int ev_add_path (struct path *, struct vectors *);
+@@ -35,5 +35,6 @@ int mpath_pr_event_handle(struct path *p
+ void * mpath_pr_event_handler_fn (void * );
+ int update_map_pr(struct multipath *mpp);
+ void * mpath_pr_event_handler_fn (void * pathp );
++void handle_signals(void);
+ #endif /* MAIN_H */
+Index: multipath-tools-130222/multipathd/uxlsnr.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/uxlsnr.c
++++ multipath-tools-130222/multipathd/uxlsnr.c
+@@ -8,6 +8,7 @@
+ /*
+  * A simple domain socket listener
+  */
++#define _GNU_SOURCE
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+@@ -19,20 +20,21 @@
+ #include <sys/socket.h>
+ #include <sys/un.h>
+ #include <sys/poll.h>
+-
++#include <signal.h>
+ #include <checkers.h>
+-
+ #include <memory.h>
+ #include <debug.h>
+ #include <vector.h>
+ #include <structs.h>
++#include <structs_vec.h>
+ #include <uxsock.h>
+ #include <defaults.h>
++#include "main.h"
+ #include "cli.h"
+ #include "uxlsnr.h"
+-#define SLEEP_TIME 5000
++struct timespec sleep_time = {5, 0};
+ struct client {
+       int fd;
+@@ -42,6 +44,8 @@ struct client {
+ static struct client *clients;
+ static unsigned num_clients;
+ struct pollfd *polls;
++volatile sig_atomic_t reconfig_sig = 0;
++volatile sig_atomic_t log_reset_sig = 0;
+ /*
+  * handle a new client joining
+@@ -104,6 +108,7 @@ void * uxsock_listen(int (*uxsock_trigge
+       int rlen;
+       char *inbuf;
+       char *reply;
++      sigset_t mask;
+       ux_sock = ux_socket_listen(DEFAULT_SOCKET);
+@@ -115,7 +120,9 @@ void * uxsock_listen(int (*uxsock_trigge
+       pthread_cleanup_push(uxsock_cleanup, NULL);
+       polls = (struct pollfd *)MALLOC(0);
+-
++      pthread_sigmask(SIG_SETMASK, NULL, &mask);
++      sigdelset(&mask, SIGHUP);
++      sigdelset(&mask, SIGUSR1);
+       while (1) {
+               struct client *c;
+               int i, poll_count;
+@@ -132,11 +139,13 @@ void * uxsock_listen(int (*uxsock_trigge
+               }
+               /* most of our life is spent in this call */
+-              poll_count = poll(polls, i, SLEEP_TIME);
++              poll_count = ppoll(polls, i, &sleep_time, &mask);
+               if (poll_count == -1) {
+-                      if (errno == EINTR)
++                      if (errno == EINTR) {
++                              handle_signals();
+                               continue;
++                      }
+                       /* something went badly wrong! */
+                       condlog(0, "poll");
+Index: multipath-tools-130222/multipathd/uxlsnr.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/uxlsnr.h
++++ multipath-tools-130222/multipathd/uxlsnr.h
+@@ -4,5 +4,8 @@
+ void * uxsock_listen(int (*uxsock_trigger)
+                       (char *, char **, int *, void *),
+                       void * trigger_data);
++
++extern volatile sig_atomic_t reconfig_sig;
++extern volatile sig_atomic_t log_reset_sig;
+ #endif
diff --git a/multipath-tools/patches/0043-RH-signal-waiter.patch b/multipath-tools/patches/0043-RH-signal-waiter.patch
new file mode 100644 (file)
index 0000000..a1a63ea
--- /dev/null
@@ -0,0 +1,71 @@
+---
+ libmultipath/waiter.c |    9 +++++++++
+ multipathd/main.c     |    8 ++++++++
+ 2 files changed, 17 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/waiter.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/waiter.c
++++ multipath-tools-130222/libmultipath/waiter.c
+@@ -57,6 +57,7 @@ void stop_waiter_thread (struct multipat
+       thread = mpp->waiter;
+       mpp->waiter = (pthread_t)0;
+       pthread_cancel(thread);
++      pthread_kill(thread, SIGUSR2);
+ }
+ /*
+@@ -65,6 +66,7 @@ void stop_waiter_thread (struct multipat
+  */
+ int waiteventloop (struct event_thread *waiter)
+ {
++      sigset_t set, oldset;
+       int event_nr;
+       int r;
+@@ -97,8 +99,15 @@ int waiteventloop (struct event_thread *
+       dm_task_no_open_count(waiter->dmt);
+       /* wait */
++      sigemptyset(&set);
++      sigaddset(&set, SIGUSR2);
++      pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
++
++      pthread_testcancel();
+       r = dm_task_run(waiter->dmt);
++      pthread_testcancel();
++      pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+       dm_task_destroy(waiter->dmt);
+       waiter->dmt = NULL;
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1506,6 +1506,12 @@ sigusr1 (int sig)
+ }
+ static void
++sigusr2 (int sig)
++{
++      condlog(3, "SIGUSR2 received");
++}
++
++static void
+ signal_init(void)
+ {
+       sigset_t set;
+@@ -1513,10 +1519,12 @@ signal_init(void)
+       sigemptyset(&set);
+       sigaddset(&set, SIGHUP);
+       sigaddset(&set, SIGUSR1);
++      sigaddset(&set, SIGUSR2);
+       pthread_sigmask(SIG_BLOCK, &set, NULL);
+       signal_set(SIGHUP, sighup);
+       signal_set(SIGUSR1, sigusr1);
++      signal_set(SIGUSR2, sigusr2);
+       signal_set(SIGINT, sigend);
+       signal_set(SIGTERM, sigend);
+       signal(SIGPIPE, SIG_IGN);
diff --git a/multipath-tools/patches/0044-RHBZ-976688-fix-wipe-wwids.patch b/multipath-tools/patches/0044-RHBZ-976688-fix-wipe-wwids.patch
new file mode 100644 (file)
index 0000000..6f70574
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ libmultipath/wwids.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -4,6 +4,7 @@
+ #include <string.h>
+ #include <limits.h>
+ #include <stdio.h>
++#include <sys/types.h>
+ #include "checkers.h"
+ #include "vector.h"
+@@ -100,6 +101,11 @@ replace_wwids(vector mp)
+               condlog(0, "cannot truncate wwids file : %s", strerror(errno));
+               goto out_file;
+       }
++      if (lseek(fd, 0, SEEK_SET) < 0) {
++              condlog(0, "cannot seek to the start of the file : %s",
++                      strerror(errno));
++              goto out_file;
++      }
+       len = strlen(WWIDS_FILE_HEADER);
+       if (write_all(fd, WWIDS_FILE_HEADER, len) != len) {
+               condlog(0, "Can't write wwid file header : %s",
diff --git a/multipath-tools/patches/0045-RHBZ-977297-man-page-fix.patch b/multipath-tools/patches/0045-RHBZ-977297-man-page-fix.patch
new file mode 100644 (file)
index 0000000..3ede0ce
--- /dev/null
@@ -0,0 +1,35 @@
+---
+ multipath/multipath.conf.5 |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -136,7 +136,7 @@ per-multipath option in the configuratio
+ 1 priority group per target node name. Target node names are fetched
+ in /sys/class/fc_transport/target*/node_name.
+ .TP
+-Default value is \fImultibus\fR.
++Default value is \fIfailover\fR.
+ .RE
+ .TP
+ .B uid_attribute
+@@ -182,7 +182,7 @@ Generate a random priority between 1 and
+ Generate the path priority based on the regular expression and the 
+ priority provided as argument. requires prio_args keyword.
+ .TP
+-Default value is \fBnone\fR.
++Default value is \fBconst\fR.
+ .RE
+ .TP
+ .B prio_args
+@@ -270,7 +270,7 @@ The number of IO to route to a path befo
+ the same path group. This is only for BIO based multipath. Default is
+ .I 1000
+ .TP
+-.B rr_min_io_q
++.B rr_min_io_rq
+ The number of IO requests to route to a path before switching to the
+ next in the same path group. This is only for request based multipath.
+ Default is
diff --git a/multipath-tools/patches/0046-RHBZ-883981-move-udev-rules.patch b/multipath-tools/patches/0046-RHBZ-883981-move-udev-rules.patch
new file mode 100644 (file)
index 0000000..4e5bc85
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ multipath/Makefile |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/multipath/Makefile
+===================================================================
+--- multipath-tools-130222.orig/multipath/Makefile
++++ multipath-tools-130222/multipath/Makefile
+@@ -23,8 +23,8 @@ install:
+       $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
+       $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
+       $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
+-      $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
+-      $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
++      $(INSTALL_PROGRAM) -d $(DESTDIR)/usr/lib/udev/rules.d
++      $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
+       $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
+       $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
+       $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
+@@ -32,7 +32,7 @@ install:
+       $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(mandir)
+ uninstall:
+-      rm $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
++      rm $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
+       rm $(DESTDIR)$(bindir)/$(EXEC)
+       rm $(DESTDIR)$(bindir)/mpathconf
+       rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
diff --git a/multipath-tools/patches/0047-RHBZ-980777-kpartx-read-only-loop-devs.patch b/multipath-tools/patches/0047-RHBZ-980777-kpartx-read-only-loop-devs.patch
new file mode 100644 (file)
index 0000000..ed79e22
--- /dev/null
@@ -0,0 +1,39 @@
+---
+ kpartx/kpartx.c |    3 +--
+ kpartx/lopart.c |    2 +-
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -204,7 +204,6 @@ main(int argc, char **argv){
+       char * delim = NULL;
+       char *uuid = NULL;
+       char *mapname = NULL;
+-      int loopro = 0;
+       int hotplug = 0;
+       int loopcreated = 0;
+       struct stat buf;
+@@ -315,7 +314,7 @@ main(int argc, char **argv){
+               if (!loopdev) {
+                       loopdev = find_unused_loop_device();
+-                      if (set_loop(loopdev, device, 0, &loopro)) {
++                      if (set_loop(loopdev, device, 0, &ro)) {
+                               fprintf(stderr, "can't set up loop\n");
+                               exit (1);
+                       }
+Index: multipath-tools-130222/kpartx/lopart.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/lopart.c
++++ multipath-tools-130222/kpartx/lopart.c
+@@ -230,7 +230,7 @@ set_loop (const char *device, const char
+       if ((ffd = open (file, mode)) < 0) {
+-              if (!*loopro && errno == EROFS)
++              if (!*loopro && (errno == EROFS || errno == EACCES))
+                       ffd = open (file, mode = O_RDONLY);
+               if (ffd < 0) {
diff --git a/multipath-tools/patches/0048-RH-print-defaults.patch b/multipath-tools/patches/0048-RH-print-defaults.patch
new file mode 100644 (file)
index 0000000..be1ce57
--- /dev/null
@@ -0,0 +1,25 @@
+---
+ libmultipath/dict.c |    4 ----
+ 1 file changed, 4 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -2468,16 +2468,12 @@ snprint_def_verbosity (char * buff, int
+ static int
+ snprint_def_max_polling_interval (char * buff, int len, void * data)
+ {
+-      if (conf->max_checkint == MAX_CHECKINT(conf->checkint))
+-              return 0;
+       return snprintf(buff, len, "%i", conf->max_checkint);
+ }
+ static int
+ snprint_reassign_maps (char * buff, int len, void * data)
+ {
+-      if (conf->reassign_maps == DEFAULT_REASSIGN_MAPS)
+-              return 0;
+       return snprintf(buff, len, "\"%s\"",
+                       conf->reassign_maps?"yes":"no");
+ }
diff --git a/multipath-tools/patches/0049-RH-remove-ID_FS_TYPE.patch b/multipath-tools/patches/0049-RH-remove-ID_FS_TYPE.patch
new file mode 100644 (file)
index 0000000..732f50f
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ multipath/multipath.rules |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -11,7 +11,7 @@ ACTION=="add", ENV{DEVTYPE}!="partition"
+       ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
+       TEST=="/etc/multipath.conf", \
+       PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
+-      ENV{DM_MULTIPATH_DEVICE_PATH}="1"
++      ENV{DM_MULTIPATH_DEVICE_PATH}="1" ENV{ID_FS_TYPE}="mpath_member"
+ ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
+       RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
diff --git a/multipath-tools/patches/0050-RH-listing-speedup.patch b/multipath-tools/patches/0050-RH-listing-speedup.patch
new file mode 100644 (file)
index 0000000..4742634
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ multipath/main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -311,7 +311,7 @@ configure (void)
+       /*
+        * get a path list
+        */
+-      if (conf->dev)
++      if (conf->dev && !conf->list)
+               di_flag = DI_WWID;
+       if (conf->list > 1)
diff --git a/multipath-tools/patches/0051-UP-fix-cli-resize.patch b/multipath-tools/patches/0051-UP-fix-cli-resize.patch
new file mode 100644 (file)
index 0000000..f278607
--- /dev/null
@@ -0,0 +1,23 @@
+diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
+index 7b1cb62..4b860bb 100644
+--- a/multipathd/cli_handlers.c
++++ b/multipathd/cli_handlers.c
+@@ -603,7 +603,18 @@ cli_resize(void *v, char **reply, int *len, void *data)
+       }
+       pgp = VECTOR_SLOT(mpp->pg, 0);
++
++      if (!pgp){
++              condlog(0, "%s: couldn't get path group. cannot resize",
++                      mapname);
++              return 1;
++      }
+       pp = VECTOR_SLOT(pgp->paths, 0);
++
++      if (!pp){
++              condlog(0, "%s: couldn't get path. cannot resize", mapname);
++              return 1;
++      }
+       if (!pp->udev || sysfs_get_size(pp, &size)) {
+               condlog(0, "%s: couldn't get size for sysfs. cannot resize",
+                       mapname);
diff --git a/multipath-tools/patches/0052-RH-fix-bad-derefs.patch b/multipath-tools/patches/0052-RH-fix-bad-derefs.patch
new file mode 100644 (file)
index 0000000..db5f1db
--- /dev/null
@@ -0,0 +1,54 @@
+---
+ multipathd/cli_handlers.c |    3 ++-
+ multipathd/main.c         |   12 ++++++------
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -632,7 +632,8 @@ cli_resize(void *v, char **reply, int *l
+               return 1;
+       dm_lib_release();
+-      setup_multipath(vecs, mpp);
++      if (setup_multipath(vecs, mpp) != 0)
++              return 1;
+       sync_map_state(mpp);
+       return 0;
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -134,7 +134,6 @@ coalesce_maps(struct vectors *vecs, vect
+       struct multipath * ompp;
+       vector ompv = vecs->mpvec;
+       unsigned int i;
+-      int j;
+       vector_foreach_slot (ompv, ompp, i) {
+               if (!find_mp_by_wwid(nmpv, ompp->wwid)) {
+@@ -148,16 +147,17 @@ coalesce_maps(struct vectors *vecs, vect
+                               /*
+                                * may be just because the device is open
+                                */
++                              if (setup_multipath(vecs, ompp) != 0) {
++                                      i--;
++                                      continue;
++                              }
+                               if (!vector_alloc_slot(nmpv))
+                                       return 1;
+                               vector_set_slot(nmpv, ompp);
+-                              setup_multipath(vecs, ompp);
+-                              if ((j = find_slot(ompv, (void *)ompp)) != -1)
+-                                      vector_del_slot(ompv, j);
+-
+-                              continue;
++                              vector_del_slot(ompv, i);
++                              i--;
+                       }
+                       else {
+                               dm_lib_release();
diff --git a/multipath-tools/patches/0053-UP-fix-failback.patch b/multipath-tools/patches/0053-UP-fix-failback.patch
new file mode 100644 (file)
index 0000000..936655d
--- /dev/null
@@ -0,0 +1,23 @@
+---
+ libmultipath/dict.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -1126,11 +1126,11 @@ hw_failback_handler(vector strvec)
+       buff = set_value(strvec);
+-      if (strlen(buff) == 6 && !strcmp(buff, "\"manual\""))
++       if (strlen(buff) == 6 && !strcmp(buff, "manual"))
+               hwe->pgfailback = -FAILBACK_MANUAL;
+-      else if (strlen(buff) == 9 && !strcmp(buff, "\"immediate\""))
++       else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
+               hwe->pgfailback = -FAILBACK_IMMEDIATE;
+-      else if (strlen(buff) == 10 && !strcmp(buff, "\"followover\""))
++       else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+               hwe->pgfailback = -FAILBACK_FOLLOWOVER;
+       else
+               hwe->pgfailback = atoi(buff);
diff --git a/multipath-tools/patches/0054-UP-keep-udev-ref.patch b/multipath-tools/patches/0054-UP-keep-udev-ref.patch
new file mode 100644 (file)
index 0000000..e42d716
--- /dev/null
@@ -0,0 +1,308 @@
+---
+ libmpathpersist/mpath_persist.c  |    7 ++++---
+ libmpathpersist/mpath_persist.h  |    2 +-
+ libmpathpersist/mpath_pr_ioctl.c |    5 +++--
+ libmultipath/config.c            |    9 +++------
+ libmultipath/config.h            |    2 +-
+ mpathpersist/Makefile            |    2 +-
+ mpathpersist/main.c              |   11 +++++++----
+ multipath/Makefile               |    2 +-
+ multipath/main.c                 |   12 ++++++++----
+ multipathd/main.c                |   11 ++++++++---
+ 10 files changed, 37 insertions(+), 26 deletions(-)
+
+Index: multipath-tools-130222/libmpathpersist/mpath_persist.c
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c
++++ multipath-tools-130222/libmpathpersist/mpath_persist.c
+@@ -1,4 +1,3 @@
+-#include "mpath_persist.h"
+ #include <libdevmapper.h>
+ #include <defaults.h>
+ #include <sys/stat.h>
+@@ -8,6 +7,7 @@
+ #include <checkers.h>
+ #include <structs.h>
+ #include <structs_vec.h>
++#include <libudev.h>
+ #include <prio.h>
+ #include <unistd.h>
+@@ -20,6 +20,7 @@
+ #include <ctype.h>
+ #include <propsel.h>
++#include "mpath_persist.h"
+ #include "mpathpr.h"
+ #include "mpath_pr_ioctl.h"
+@@ -32,9 +33,9 @@
+ int
+-mpath_lib_init (void)
++mpath_lib_init (struct udev *udev)
+ {
+-      if (load_config(DEFAULT_CONFIGFILE)){
++      if (load_config(DEFAULT_CONFIGFILE, udev)){
+               condlog(0, "Failed to initialize multipath config.");
+               return 1;
+       }
+Index: multipath-tools-130222/libmpathpersist/mpath_persist.h
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.h
++++ multipath-tools-130222/libmpathpersist/mpath_persist.h
+@@ -174,7 +174,7 @@ struct prout_param_descriptor {    /* PROU
+  *
+  * RETURNS: 0->Success, 1->Failed.
+  */
+-extern int mpath_lib_init (void );
++extern int mpath_lib_init (struct udev *udev);
+ /*
+Index: multipath-tools-130222/libmpathpersist/mpath_pr_ioctl.c
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_pr_ioctl.c
++++ multipath-tools-130222/libmpathpersist/mpath_pr_ioctl.c
+@@ -10,8 +10,9 @@
+ #include <string.h>
+ #include <sys/ioctl.h>
+ #include <unistd.h>
+-#include "mpath_pr_ioctl.h" 
+-#include <mpath_persist.h> 
++#include <libudev.h>
++#include "mpath_pr_ioctl.h"
++#include <mpath_persist.h>
+ #include <debug.h>
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -467,9 +467,6 @@ free_config (struct config * conf)
+       if (conf->dev)
+               FREE(conf->dev);
+-      if (conf->udev)
+-              udev_unref(conf->udev);
+-
+       if (conf->multipath_dir)
+               FREE(conf->multipath_dir);
+@@ -519,12 +516,12 @@ free_config (struct config * conf)
+ }
+ int
+-load_config (char * file)
++load_config (char * file, struct udev *udev)
+ {
+       if (!conf)
+               conf = alloc_config();
+-      if (!conf)
++      if (!conf || !udev)
+               return 1;
+       /*
+@@ -533,7 +530,7 @@ load_config (char * file)
+       if (!conf->verbosity)
+               conf->verbosity = DEFAULT_VERBOSITY;
+-      conf->udev = udev_new();
++      conf->udev = udev;
+       dm_drv_version(conf->version, TGT_MPATH);
+       conf->dev_type = DEV_NONE;
+       conf->minio = DEFAULT_MINIO;
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -159,7 +159,7 @@ void free_mptable (vector mptable);
+ int store_hwe (vector hwtable, struct hwentry *);
+-int load_config (char * file);
++int load_config (char * file, struct udev * udev);
+ struct config * alloc_config (void);
+ void free_config (struct config * conf);
+Index: multipath-tools-130222/mpathpersist/main.c
+===================================================================
+--- multipath-tools-130222.orig/mpathpersist/main.c
++++ multipath-tools-130222/mpathpersist/main.c
+@@ -7,6 +7,7 @@
+ #include <vector.h>
+ #include <structs.h>
+ #include <getopt.h>
++#include <libudev.h>
+ #include <mpath_persist.h>
+ #include "main.h"
+ #include <pthread.h>
+@@ -68,7 +69,8 @@ int main (int argc, char * argv[])
+       int noisy = 0;
+       int num_transport =0;
+       void *resp = NULL;
+-      struct transportid * tmp; 
++      struct transportid * tmp;
++      struct udev *udev = NULL;
+       if (optind == argc)
+       {
+@@ -84,8 +86,8 @@ int main (int argc, char * argv[])
+               exit (1);
+       }
+-
+-      mpath_lib_init();
++      udev = udev_new();
++      mpath_lib_init(udev);
+       memset(transportids,0,MPATH_MX_TIDS);
+       while (1)
+@@ -461,12 +463,13 @@ int main (int argc, char * argv[])
+       if (res < 0)
+       {
+               mpath_lib_exit();
++              udev_unref(udev);
+               return MPATH_PR_FILE_ERROR;
+       }
+ out :
+       mpath_lib_exit();
+-
++      udev_unref(udev);
+       return (ret >= 0) ? ret : MPATH_PR_OTHER;
+ }
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -27,6 +27,7 @@
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <ctype.h>
++#include <libudev.h>
+ #include <checkers.h>
+ #include <prio.h>
+@@ -435,6 +436,7 @@ convert_dev(char *dev)
+ int
+ main (int argc, char *argv[])
+ {
++      struct udev *udev;
+       int arg;
+       extern char *optarg;
+       extern int optind;
+@@ -445,7 +447,9 @@ main (int argc, char *argv[])
+               exit(1);
+       }
+-      if (load_config(DEFAULT_CONFIGFILE))
++      udev = udev_new();
++
++      if (load_config(DEFAULT_CONFIGFILE, udev))
+               exit(1);
+       if (dm_prereq())
+@@ -560,11 +564,11 @@ main (int argc, char *argv[])
+       if (init_checkers()) {
+               condlog(0, "failed to initialize checkers");
+-              exit(1);
++              goto out;
+       }
+       if (init_prio()) {
+               condlog(0, "failed to initialize prioritizers");
+-              exit(1);
++              goto out;
+       }
+       dm_init();
+@@ -628,7 +632,7 @@ out:
+        */
+       free_config(conf);
+       conf = NULL;
+-
++      udev_unref(udev);
+ #ifdef _DEBUG_
+       dbg_free_final(NULL);
+ #endif
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -93,6 +93,8 @@ static sem_t exit_sem;
+  */
+ struct vectors * gvecs;
++struct udev * udev;
++
+ static int
+ need_switch_pathgroup (struct multipath * mpp, int refresh)
+ {
+@@ -1408,7 +1410,7 @@ reconfigure (struct vectors * vecs)
+       vecs->pathvec = NULL;
+       conf = NULL;
+-      if (!load_config(DEFAULT_CONFIGFILE)) {
++      if (!load_config(DEFAULT_CONFIGFILE, udev)) {
+               conf->verbosity = old->verbosity;
+               conf->daemon = 1;
+               configure(vecs, 1);
+@@ -1601,6 +1603,8 @@ child (void * param)
+       sem_init(&exit_sem, 0, 0);
+       signal_init();
++      udev = udev_new();
++
+       setup_thread_attr(&misc_attr, 64 * 1024, 1);
+       setup_thread_attr(&waiter_attr, 32 * 1024, 1);
+@@ -1615,7 +1619,7 @@ child (void * param)
+       condlog(2, "--------start up--------");
+       condlog(2, "read " DEFAULT_CONFIGFILE);
+-      if (load_config(DEFAULT_CONFIGFILE))
++      if (load_config(DEFAULT_CONFIGFILE, udev))
+               exit(1);
+       if (init_checkers()) {
+@@ -1765,7 +1769,8 @@ child (void * param)
+        */
+       free_config(conf);
+       conf = NULL;
+-
++      udev_unref(udev);
++      udev = NULL;
+ #ifdef _DEBUG_
+       dbg_free_final(NULL);
+ #endif
+Index: multipath-tools-130222/mpathpersist/Makefile
+===================================================================
+--- multipath-tools-130222.orig/mpathpersist/Makefile
++++ multipath-tools-130222/mpathpersist/Makefile
+@@ -5,7 +5,7 @@ include ../Makefile.inc
+ OBJS = main.o 
+ CFLAGS += -I$(multipathdir) -I$(mpathpersistdir) 
+-LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath 
++LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath -ludev
+ EXEC = mpathpersist
+Index: multipath-tools-130222/multipath/Makefile
+===================================================================
+--- multipath-tools-130222.orig/multipath/Makefile
++++ multipath-tools-130222/multipath/Makefile
+@@ -7,7 +7,7 @@ include ../Makefile.inc
+ OBJS = main.o
+ CFLAGS += -fPIC -I$(multipathdir)
+-LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
++LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath -ludev
+ EXEC = multipath
diff --git a/multipath-tools/patches/0055-UP-handle-quiesced-paths.patch b/multipath-tools/patches/0055-UP-handle-quiesced-paths.patch
new file mode 100644 (file)
index 0000000..0556a61
--- /dev/null
@@ -0,0 +1,16 @@
+---
+ libmultipath/discovery.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -799,6 +799,7 @@ path_offline (struct path * pp)
+       condlog(3, "%s: path state = %s", pp->dev, buff);
+       if (!strncmp(buff, "offline", 7) ||
++          !strncmp(buff, "quiesce", 7) ||
+           !strncmp(buff, "transport-offline", 17)) {
+               pp->offline = 1;
+               return PATH_DOWN;
diff --git a/multipath-tools/patches/0056-UP-alua-prio-fix.patch b/multipath-tools/patches/0056-UP-alua-prio-fix.patch
new file mode 100644 (file)
index 0000000..0ac41ab
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/prioritizers/alua.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/prioritizers/alua.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c
++++ multipath-tools-130222/libmultipath/prioritizers/alua.c
+@@ -108,7 +108,7 @@ int getprio (struct path * pp, char * ar
+                       default:
+                               rc = 0;
+               }
+-              if (priopath)
++              if (priopath && aas != AAS_OPTIMIZED)
+                       rc += 80;
+       } else {
+               switch(-rc) {
diff --git a/multipath-tools/patches/0057-UP-fix-tmo.patch b/multipath-tools/patches/0057-UP-fix-tmo.patch
new file mode 100644 (file)
index 0000000..0bfc46b
--- /dev/null
@@ -0,0 +1,329 @@
+---
+ libmultipath/discovery.c |  109 +++++++++++++++++++++++++++++++++++++----------
+ libmultipath/sysfs.c     |   86 +++++++++++++++++++++++++++++++------
+ libmultipath/sysfs.h     |    2 
+ 3 files changed, 161 insertions(+), 36 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -162,7 +162,6 @@ declare_sysfs_get_str(cutype);
+ declare_sysfs_get_str(vendor);
+ declare_sysfs_get_str(model);
+ declare_sysfs_get_str(rev);
+-declare_sysfs_get_str(state);
+ declare_sysfs_get_str(dev);
+ int
+@@ -315,9 +314,14 @@ static void
+ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
+ {
+       struct udev_device *rport_dev = NULL;
+-      char value[11];
++      char value[16];
+       char rport_id[32];
++      int delay_fast_io_fail = 0;
++      int current_dev_loss = 0;
++      int ret;
++      if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
++              return;
+       sprintf(rport_id, "rport-%d:%d-%d",
+               pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
+       rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
+@@ -330,33 +334,85 @@ sysfs_set_rport_tmo(struct multipath *mp
+       condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
+               pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
+-      snprintf(value, 11, "%u", mpp->dev_loss);
+-      if (mpp->dev_loss &&
+-          sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, 11) <= 0) {
+-              if ((mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET ||
+-                   mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
+-                  && mpp->dev_loss > 600) {
+-                      condlog(3, "%s: limiting dev_loss_tmo to 600, since "
+-                              "fast_io_fail is not set", mpp->alias);
+-                      snprintf(value, 11, "%u", 600);
+-                      if (sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
+-                                               value, 11) <= 0)
+-                              condlog(0, "%s failed to set dev_loss_tmo",
+-                                      mpp->alias);
++      memset(value, 0, 16);
++      if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
++              ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo",
++                                         value, 16);
++              if (ret <= 0) {
++                      condlog(0, "%s: failed to read dev_loss_tmo value, "
++                              "error %d", rport_id, -ret);
+                       goto out;
+               }
++              if (sscanf(value, "%u\n", &current_dev_loss) != 1) {
++                      condlog(0, "%s: Cannot parse dev_loss_tmo "
++                              "attribute '%s'", rport_id, value);
++                      goto out;
++              }
++              if ((mpp->dev_loss &&
++                   mpp->fast_io_fail >= (int)mpp->dev_loss) ||
++                  (!mpp->dev_loss &&
++                     mpp->fast_io_fail >= (int)current_dev_loss)) {
++                      condlog(3, "%s: limiting fast_io_fail_tmo to %d, since "
++                              "it must be less than dev_loss_tmo",
++                              rport_id, mpp->dev_loss - 1);
++                      if (mpp->dev_loss)
++                              mpp->fast_io_fail = mpp->dev_loss - 1;
++                      else
++                              mpp->fast_io_fail = current_dev_loss - 1;
++              }
++              if (mpp->fast_io_fail >= (int)current_dev_loss)
++                      delay_fast_io_fail = 1;
++      }
++      if (mpp->dev_loss > 600 &&
++          (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF ||
++             mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)) {
++              condlog(3, "%s: limiting dev_loss_tmo to 600, since "
++                      "fast_io_fail is unset or off", rport_id);
++              mpp->dev_loss = 600;
+       }
+-      if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET){
++      if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
+               if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
+                       sprintf(value, "off");
+               else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
+                       sprintf(value, "0");
++              else if (delay_fast_io_fail)
++                      snprintf(value, 16, "%u", current_dev_loss - 1);
+               else
+-                      snprintf(value, 11, "%u", mpp->fast_io_fail);
+-              if (sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
+-                                       value, 11) <= 0) {
+-                      condlog(0, "%s failed to set fast_io_fail_tmo",
+-                              mpp->alias);
++                      snprintf(value, 16, "%u", mpp->fast_io_fail);
++              ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
++                                         value, strlen(value));
++              if (ret <= 0) {
++                      if (ret == -EBUSY)
++                              condlog(3, "%s: rport blocked", rport_id);
++                      else
++                              condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
++                                      rport_id, value, -ret);
++                      goto out;
++              }
++      }
++      if (mpp->dev_loss) {
++              snprintf(value, 16, "%u", mpp->dev_loss);
++              ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
++                                         value, strlen(value));
++              if (ret <= 0) {
++                      if (ret == -EBUSY)
++                              condlog(3, "%s: rport blocked", rport_id);
++                      else
++                              condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
++                                      rport_id, value, -ret);
++                      goto out;
++              }
++      }
++      if (delay_fast_io_fail) {
++              snprintf(value, 16, "%u", mpp->fast_io_fail);
++              ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
++                                         value, strlen(value));
++              if (ret <= 0) {
++                      if (ret == -EBUSY)
++                              condlog(3, "%s: rport blocked", rport_id);
++                      else
++                              condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
++                                      rport_id, value, -ret);
+               }
+       }
+ out:
+@@ -394,7 +450,7 @@ sysfs_set_session_tmo(struct multipath *
+               } else {
+                       snprintf(value, 11, "%u", mpp->fast_io_fail);
+                       if (sysfs_attr_set_value(session_dev, "recovery_tmo",
+-                                               value, 11)) {
++                                               value, 11) <= 0) {
+                               condlog(3, "%s: Failed to set recovery_tmo, "
+                                       " error %d", pp->dev, errno);
+                       }
+@@ -752,6 +808,9 @@ cciss_sysfs_pathinfo (struct path * pp)
+ static int
+ common_sysfs_pathinfo (struct path * pp)
+ {
++      if (!pp)
++              return 1;
++
+       if (!pp->udev) {
+               condlog(4, "%s: udev not initialised", pp->dev);
+               return 1;
+@@ -793,7 +852,8 @@ path_offline (struct path * pp)
+               return PATH_DOWN;
+       }
+-      if (sysfs_get_state(parent, buff, SCSI_STATE_SIZE))
++      memset(buff, 0x0, SCSI_STATE_SIZE);
++      if (sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE) <= 0)
+               return PATH_DOWN;
+       condlog(3, "%s: path state = %s", pp->dev, buff);
+@@ -983,6 +1043,9 @@ pathinfo (struct path *pp, vector hwtabl
+ {
+       int path_state;
++      if (!pp)
++              return 1;
++
+       condlog(3, "%s: mask = 0x%x", pp->dev, mask);
+       /*
+Index: multipath-tools-130222/libmultipath/sysfs.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/sysfs.c
++++ multipath-tools-130222/libmultipath/sysfs.c
+@@ -38,7 +38,12 @@
+ #include "debug.h"
+ #include "devmapper.h"
+-ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name,
++/*
++ * When we modify an attribute value we cannot rely on libudev for now,
++ * as libudev lacks the capability to update an attribute value.
++ * So for modified attributes we need to implement our own function.
++ */
++ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name,
+                            char * value, size_t value_len)
+ {
+       char devpath[PATH_SIZE];
+@@ -54,28 +59,83 @@ ssize_t sysfs_attr_set_value(struct udev
+       condlog(4, "open '%s'", devpath);
+       if (stat(devpath, &statbuf) != 0) {
+               condlog(4, "stat '%s' failed: %s", devpath, strerror(errno));
+-              return 0;
++              return -errno;
+       }
+       /* skip directories */
+-      if (S_ISDIR(statbuf.st_mode))
+-              return 0;
++      if (S_ISDIR(statbuf.st_mode)) {
++              condlog(4, "%s is a directory", devpath);
++              return -EISDIR;
++      }
+       /* skip non-writeable files */
+-      if ((statbuf.st_mode & S_IWUSR) == 0)
++      if ((statbuf.st_mode & S_IRUSR) == 0) {
++              condlog(4, "%s is not readable", devpath);
++              return -EPERM;
++      }
++
++      /* read attribute value */
++      fd = open(devpath, O_RDONLY);
++      if (fd < 0) {
++              condlog(4, "attribute '%s' can not be opened: %s",
++                      devpath, strerror(errno));
++              return -errno;
++      }
++      size = read(fd, value, value_len);
++      if (size < 0) {
++              condlog(4, "read from %s failed: %s", devpath, strerror(errno));
++              size = -errno;
++      } else if (size == value_len) {
++              condlog(4, "overflow while reading from %s", devpath);
++              size = 0;
++      }
++
++      close(fd);
++      return size;
++}
++
++ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name,
++                           char * value, size_t value_len)
++{
++      char devpath[PATH_SIZE];
++      struct stat statbuf;
++      int fd;
++      ssize_t size = -1;
++
++      if (!dev || !attr_name || !value || !value_len)
+               return 0;
++      snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev),
++               attr_name);
++      condlog(4, "open '%s'", devpath);
++      if (stat(devpath, &statbuf) != 0) {
++              condlog(4, "stat '%s' failed: %s", devpath, strerror(errno));
++              return -errno;
++      }
++
++      /* skip directories */
++      if (S_ISDIR(statbuf.st_mode)) {
++              condlog(4, "%s is a directory", devpath);
++              return -EISDIR;
++      }
++
++      /* skip non-writeable files */
++      if ((statbuf.st_mode & S_IWUSR) == 0) {
++              condlog(4, "%s is not writeable", devpath);
++              return -EPERM;
++      }
++
+       /* write attribute value */
+       fd = open(devpath, O_WRONLY);
+       if (fd < 0) {
+               condlog(4, "attribute '%s' can not be opened: %s",
+                       devpath, strerror(errno));
+-              return 0;
++              return -errno;
+       }
+       size = write(fd, value, value_len);
+       if (size < 0) {
+               condlog(4, "write to %s failed: %s", devpath, strerror(errno));
+-              size = 0;
++              size = -errno;
+       } else if (size < value_len) {
+               condlog(4, "tried to write %ld to %s. Wrote %ld",
+                       (long)value_len, devpath, (long)size);
+@@ -89,14 +149,14 @@ ssize_t sysfs_attr_set_value(struct udev
+ int
+ sysfs_get_size (struct path *pp, unsigned long long * size)
+ {
+-      const char * attr;
++      char attr[255];
+       int r;
+-      if (!pp->udev)
++      if (!pp->udev || !size)
+               return 1;
+-      attr = udev_device_get_sysattr_value(pp->udev, "size");
+-      if (!attr) {
++      attr[0] = '\0';
++      if (sysfs_attr_get_value(pp->udev, "size", attr, 255) == 0) {
+               condlog(3, "%s: No size attribute in sysfs", pp->dev);
+               return 1;
+       }
+@@ -104,8 +164,8 @@ sysfs_get_size (struct path *pp, unsigne
+       r = sscanf(attr, "%llu\n", size);
+       if (r != 1) {
+-              condlog(3, "%s: Cannot parse size attribute '%s'",
+-                      pp->dev, attr);
++              condlog(3, "%s: Cannot parse size attribute", pp->dev);
++              *size = 0;
+               return 1;
+       }
+Index: multipath-tools-130222/libmultipath/sysfs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/sysfs.h
++++ multipath-tools-130222/libmultipath/sysfs.h
+@@ -7,6 +7,8 @@
+ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name,
+                            char * value, size_t value_len);
++ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name,
++                           char * value, size_t value_len);
+ int sysfs_get_size (struct path *pp, unsigned long long * size);
+ int sysfs_check_holders(char * check_devt, char * new_devt);
+ #endif
diff --git a/multipath-tools/patches/0058-UP-fix-failback.patch b/multipath-tools/patches/0058-UP-fix-failback.patch
new file mode 100644 (file)
index 0000000..d1fbaeb
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/dict.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -2562,7 +2562,7 @@ snprint_def_failback (char * buff, int l
+       if (!pgfailback)
+               pgfailback = DEFAULT_FAILBACK;
+-      switch(conf->pgfailback) {
++      switch(pgfailback) {
+       case  FAILBACK_UNDEF:
+               break;
+       case -FAILBACK_MANUAL:
diff --git a/multipath-tools/patches/0059-UP-flush-failure-queueing.patch b/multipath-tools/patches/0059-UP-flush-failure-queueing.patch
new file mode 100644 (file)
index 0000000..f72f314
--- /dev/null
@@ -0,0 +1,71 @@
+---
+ libmultipath/devmapper.c |   21 +++++++++++++++++----
+ libmultipath/devmapper.h |    2 +-
+ 2 files changed, 18 insertions(+), 5 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -363,7 +363,7 @@ out:
+ }
+ extern int
+-dm_get_map(char * name, unsigned long long * size, char * outparams)
++dm_get_map(const char * name, unsigned long long * size, char * outparams)
+ {
+       int r = 1;
+       struct dm_task *dmt;
+@@ -682,7 +682,9 @@ _dm_flush_map (const char * mapname, int
+ extern int
+ dm_suspend_and_flush_map (const char * mapname)
+ {
+-      int s;
++      int s = 0, queue_if_no_path = 0;
++      unsigned long long mapsize;
++      char params[PARAMS_SIZE] = {0};
+       if (!dm_map_present(mapname))
+               return 0;
+@@ -690,8 +692,17 @@ dm_suspend_and_flush_map (const char * m
+       if (dm_type(mapname, TGT_MPATH) <= 0)
+               return 0; /* nothing to do */
+-      s = dm_queue_if_no_path((char *)mapname, 0);
+-      if (!s)
++      if (!dm_get_map(mapname, &mapsize, params)) {
++              if (strstr(params, "queue_if_no_path"))
++                      queue_if_no_path = 1;
++      }
++
++      if (queue_if_no_path)
++              s = dm_queue_if_no_path((char *)mapname, 0);
++      /* Leave queue_if_no_path alone if unset failed */
++      if (s)
++              queue_if_no_path = 0;
++      else
+               s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0);
+       if (!dm_flush_map(mapname)) {
+@@ -700,6 +711,8 @@ dm_suspend_and_flush_map (const char * m
+       }
+       condlog(2, "failed to remove multipath map %s", mapname);
+       dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname);
++      if (queue_if_no_path)
++              s = dm_queue_if_no_path((char *)mapname, 1);
+       return 1;
+ }
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -14,7 +14,7 @@ int dm_simplecmd_noflush (int, const cha
+ int dm_addmap_create (struct multipath *mpp, char *params);
+ int dm_addmap_reload (struct multipath *mpp, char *params);
+ int dm_map_present (const char *);
+-int dm_get_map(char *, unsigned long long *, char *);
++int dm_get_map(const char *, unsigned long long *, char *);
+ int dm_get_status(char *, char *);
+ int dm_type(const char *, char *);
+ int _dm_flush_map (const char *, int);
diff --git a/multipath-tools/patches/0060-UP-uevent-loop-udev.patch b/multipath-tools/patches/0060-UP-uevent-loop-udev.patch
new file mode 100644 (file)
index 0000000..88fc005
--- /dev/null
@@ -0,0 +1,127 @@
+---
+ libmultipath/uevent.c |   17 ++++++++++++-----
+ libmultipath/uevent.h |    4 +++-
+ multipathd/main.c     |    8 +++++---
+ 3 files changed, 20 insertions(+), 9 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/uevent.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/uevent.c
++++ multipath-tools-130222/libmultipath/uevent.c
+@@ -47,7 +47,6 @@
+ #include "list.h"
+ #include "uevent.h"
+ #include "vector.h"
+-#include "config.h"
+ typedef int (uev_trigger)(struct uevent *, void * trigger_data);
+@@ -127,11 +126,14 @@ service_uevq(struct list_head *tmpq)
+ static void uevq_stop(void *arg)
+ {
++      struct udev *udev = arg;
++
+       condlog(3, "Stopping uev queue");
+       pthread_mutex_lock(uevq_lockp);
+       my_uev_trigger = NULL;
+       pthread_cond_signal(uev_condp);
+       pthread_mutex_unlock(uevq_lockp);
++      udev_unref(udev);
+ }
+ void
+@@ -399,9 +401,9 @@ exit:
+       return 1;
+ }
+-int uevent_listen(void)
++int uevent_listen(struct udev *udev)
+ {
+-      int err;
++      int err = 2;
+       struct udev_monitor *monitor = NULL;
+       int fd, socket_flags;
+       int need_failback = 1;
+@@ -411,9 +413,14 @@ int uevent_listen(void)
+        * thereby not getting to empty the socket's receive buffer queue
+        * often enough.
+        */
+-      pthread_cleanup_push(uevq_stop, NULL);
++      if (!udev) {
++              condlog(1, "no udev context");
++              return 1;
++      }
++      udev_ref(udev);
++      pthread_cleanup_push(uevq_stop, udev);
+-      monitor = udev_monitor_new_from_netlink(conf->udev, "udev");
++      monitor = udev_monitor_new_from_netlink(udev, "udev");
+       if (!monitor) {
+               condlog(2, "failed to create udev monitor");
+               goto out;
+Index: multipath-tools-130222/libmultipath/uevent.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/uevent.h
++++ multipath-tools-130222/libmultipath/uevent.h
+@@ -13,6 +13,8 @@
+ #define NETLINK_KOBJECT_UEVENT                15
+ #endif
++struct udev;
++
+ struct uevent {
+       struct list_head node;
+       struct udev_device *udev;
+@@ -27,7 +29,7 @@ struct uevent {
+ int is_uevent_busy(void);
+ void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached);
+-int uevent_listen(void);
++int uevent_listen(struct udev *udev);
+ int uevent_dispatch(int (*store_uev)(struct uevent *, void * trigger_data),
+                   void * trigger_data);
+ int uevent_get_major(struct uevent *uev);
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -840,7 +840,7 @@ out:
+ static void *
+ ueventloop (void * ap)
+ {
+-      if (uevent_listen())
++      if (uevent_listen(udev))
+               condlog(0, "error starting uevent listener");
+       return NULL;
+@@ -1593,7 +1593,7 @@ static int
+ child (void * param)
+ {
+       pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr;
+-      pthread_attr_t log_attr, misc_attr;
++      pthread_attr_t log_attr, misc_attr, uevent_attr;
+       struct vectors * vecs;
+       struct multipath * mpp;
+       int i;
+@@ -1606,6 +1606,7 @@ child (void * param)
+       udev = udev_new();
+       setup_thread_attr(&misc_attr, 64 * 1024, 1);
++      setup_thread_attr(&uevent_attr, 128 * 1024, 1);
+       setup_thread_attr(&waiter_attr, 32 * 1024, 1);
+       if (logsink) {
+@@ -1671,10 +1672,11 @@ child (void * param)
+       /*
+        * Start uevent listener early to catch events
+        */
+-      if ((rc = pthread_create(&uevent_thr, &misc_attr, ueventloop, vecs))) {
++      if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) {
+               condlog(0, "failed to create uevent thread: %d", rc);
+               exit(1);
+       }
++      pthread_attr_destroy(&uevent_attr);
+       if ((rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs))) {
+               condlog(0, "failed to create cli listener: %d", rc);
+               exit(1);
diff --git a/multipath-tools/patches/0061-RH-display-find-mpaths.patch b/multipath-tools/patches/0061-RH-display-find-mpaths.patch
new file mode 100644 (file)
index 0000000..05c63f0
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/dict.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -2717,8 +2717,6 @@ snprint_def_log_checker_err (char * buff
+ static int
+ snprint_def_find_multipaths (char * buff, int len, void * data)
+ {
+-      if (conf->find_multipaths == DEFAULT_FIND_MULTIPATHS)
+-              return 0;
+       if (!conf->find_multipaths)
+               return snprintf(buff, len, "no");
diff --git a/multipath-tools/patches/0062-RH-dont-free-vecs.patch b/multipath-tools/patches/0062-RH-dont-free-vecs.patch
new file mode 100644 (file)
index 0000000..f1c3217
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ multipathd/main.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1735,8 +1735,9 @@ child (void * param)
+       vecs->pathvec = NULL;
+       unlock(vecs->lock);
+       /* Now all the waitevent threads will start rushing in. */
++      /* freeing vecs isn't worth the races
+       while (vecs->lock.depth > 0) {
+-              sleep (1); /* This is weak. */
++              sleep (1);
+               condlog(3, "Have %d wait event checkers threads to de-alloc,"
+                       " waiting...", vecs->lock.depth);
+       }
+@@ -1746,7 +1747,7 @@ child (void * param)
+       vecs->lock.mutex = NULL;
+       FREE(vecs);
+       vecs = NULL;
+-
++      */
+       cleanup_checkers();
+       cleanup_prio();
diff --git a/multipath-tools/patches/0063-RH-fix-warning.patch b/multipath-tools/patches/0063-RH-fix-warning.patch
new file mode 100644 (file)
index 0000000..7db8056
--- /dev/null
@@ -0,0 +1,26 @@
+---
+ kpartx/dasd.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/kpartx/dasd.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/dasd.c
++++ multipath-tools-130222/kpartx/dasd.c
+@@ -46,6 +46,8 @@ unsigned long long sectors512(unsigned l
+       return sectors * (blocksize >> 9);
+ }
++typedef unsigned int __attribute__((__may_alias__)) label_ints_t;
++
+ /*
+  */
+ int 
+@@ -169,7 +171,7 @@ read_dasd_pt(int fd, struct slice all, s
+               /*
+                * VM style CMS1 labeled disk
+                */
+-              unsigned int *label = (unsigned int *) &vlabel;
++              label_ints_t *label = (label_ints_t *) &vlabel;
+               blocksize = label[4];
+               if (label[14] != 0) {
diff --git a/multipath-tools/patches/0064-fix-ID_FS-attrs.patch b/multipath-tools/patches/0064-fix-ID_FS-attrs.patch
new file mode 100644 (file)
index 0000000..cb59a85
--- /dev/null
@@ -0,0 +1,383 @@
+---
+ libmultipath/defaults.h       |    3 -
+ libmultipath/file.c           |   89 +++++++++++++++++++++++++++++++++++++++++-
+ libmultipath/file.h           |    3 +
+ libmultipath/wwids.c          |    7 ++-
+ multipath/main.c              |   36 +++++++++++++++-
+ multipath/multipath.rules     |   26 +++++++++---
+ multipathd/main.c             |    4 +
+ multipathd/multipathd.service |    2 
+ multipathd/pidfile.c          |    3 +
+ 9 files changed, 160 insertions(+), 13 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/defaults.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/defaults.h
++++ multipath-tools-130222/libmultipath/defaults.h
+@@ -24,7 +24,8 @@
+ #define MAX_CHECKINT(a)               (a << 2)
+ #define MAX_DEV_LOSS_TMO      0x7FFFFFFF
+-#define DEFAULT_PIDFILE               "/var/run/multipathd.pid"
++#define DEFAULT_PIDFILE               "/var/run/multipathd/multipathd.pid"
++#define DEFAULT_TIMESTAMP_FILE        "/var/run/multipathd/timestamp"
+ #define DEFAULT_SOCKET                "/org/kernel/linux/storage/multipathd"
+ #define DEFAULT_CONFIGFILE    "/etc/multipath.conf"
+ #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
+Index: multipath-tools-130222/libmultipath/file.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/file.c
++++ multipath-tools-130222/libmultipath/file.c
+@@ -12,10 +12,12 @@
+ #include <limits.h>
+ #include <stdio.h>
+ #include <signal.h>
++#include <time.h>
+ #include "file.h"
+ #include "debug.h"
+ #include "uxsock.h"
++#include "defaults.h"
+ /*
+@@ -36,8 +38,8 @@
+  * See the file COPYING included with this distribution for more details.
+  */
+-static int
+-ensure_directories_exist(char *str, mode_t dir_mode)
++int
++ensure_directories_exist(const char *str, mode_t dir_mode)
+ {
+       char *pathname;
+       char *end;
+@@ -178,3 +180,86 @@ fail:
+       close(fd);
+       return -1;
+ }
++
++/* If you can't get the timestamp, return equal to just keep using the
++ * existing value.
++ */
++int timestamp_equal(long int chk_timestamp)
++{
++      char buf[4096];
++      FILE *file;
++      long int file_timestamp;
++      int ret = 1;
++
++      if ((file = fopen(DEFAULT_TIMESTAMP_FILE, "r")) == NULL) {
++              if (errno != ENOENT)
++                      condlog(2, "Cannot open timestamp file [%s]: %s",
++                              DEFAULT_TIMESTAMP_FILE, strerror(errno));
++              goto out;
++      }
++      errno = 0;
++      if (fgets(buf, sizeof(buf), file) == NULL) {
++              if (errno)
++                      condlog(2, "Cannot read from timestamp file: %s",
++                              strerror(errno));
++              goto out;
++      }
++      if (sscanf(buf, "DM_MULTIPATH_TIMESTAMP=%ld", &file_timestamp) != 1) {
++              if (errno)
++                      condlog(0, "Cannot get timestamp: %s", strerror(errno));
++              else
++                      condlog(0, "invalid timestamp file [%s]: %s",
++                              DEFAULT_TIMESTAMP_FILE, strerror(errno));
++              goto out;
++      }
++      if (file_timestamp != chk_timestamp) {
++              condlog(3, "timestamp has changed");
++              ret = 0;
++      }
++      else
++              condlog(3, "timestamp has not changed");
++out:
++      if (file)
++              fclose(file);
++      return ret;
++}
++
++int update_timestamp(int create)
++{
++      char buf[44];
++      time_t timestamp;
++      int fd;
++      int flags = O_WRONLY;
++      if (create)
++              flags |= O_CREAT;
++      if((fd = open(DEFAULT_TIMESTAMP_FILE, flags,
++                    (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
++              if (errno == ENOENT)
++                      return 0;
++              condlog(0, "Cannot open timestamp file [%s]: %s",
++                      DEFAULT_TIMESTAMP_FILE, strerror(errno));
++              return 1;
++      }
++      if (ftruncate(fd, 0) < 0) {
++              condlog(0, "Cannot truncate timestamp file [%s]: %s",
++                      DEFAULT_TIMESTAMP_FILE, strerror(errno));
++              goto fail;
++      }
++      if (time(&timestamp) == -1) {
++              condlog(0, "Cannot get current time: %s", strerror(errno));
++              goto fail;
++      }
++      memset(buf, 0, sizeof(buf));
++      snprintf(buf, sizeof(buf)-1, "DM_MULTIPATH_TIMESTAMP=%ld\n",
++               timestamp);
++      if (write(fd, buf, strlen(buf)) != strlen(buf)) {
++              condlog(0, "Cannot write out timestamp to %s: %s",
++                      DEFAULT_TIMESTAMP_FILE, strerror(errno));
++              goto fail;
++      }
++      close(fd);
++      return 0;
++fail:
++      close(fd);
++      return 1;
++}
+Index: multipath-tools-130222/libmultipath/file.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/file.h
++++ multipath-tools-130222/libmultipath/file.h
+@@ -7,5 +7,8 @@
+ #define FILE_TIMEOUT 30
+ int open_file(char *file, int *can_write, char *header);
++int ensure_directories_exist(const char *str, mode_t dir_mode);
++int update_timestamp(int create);
++int timestamp_equal(long int chk_timestamp);
+ #endif /* _FILE_H */
+Index: multipath-tools-130222/multipathd/pidfile.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/pidfile.c
++++ multipath-tools-130222/multipathd/pidfile.c
+@@ -9,6 +9,7 @@
+ #include <fcntl.h>     /* for fcntl() */
+ #include <debug.h>
++#include <file.h>
+ #include "pidfile.h"
+@@ -18,6 +19,8 @@ int pidfile_create(const char *pidFile,
+       struct flock lock;
+       int fd, value;
++      if (ensure_directories_exist(pidFile, 0700))
++              return 1;
+       if((fd = open(pidFile, O_WRONLY | O_CREAT,
+                      (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
+               condlog(0, "Cannot open pidfile [%s], error was [%s]",
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -125,6 +125,7 @@ replace_wwids(vector mp)
+                       goto out_file;
+       }
+       ret = 0;
++      update_timestamp(0);
+ out_file:
+       close(fd);
+ out:
+@@ -209,6 +210,8 @@ remove_wwid(char *wwid) {
+               goto out_file;
+       }
+       ret = do_remove_wwid(fd, str);
++      if (!ret)
++              update_timestamp(0);
+ out_file:
+       close(fd);
+@@ -294,8 +297,10 @@ remember_wwid(char *wwid)
+               condlog(3, "failed writing wwid %s to wwids file", wwid);
+               return -1;
+       }
+-      if (ret == 1)
++      if (ret == 1) {
+               condlog(3, "wrote wwid %s to wwids file", wwid);
++              update_timestamp(0);
++      }
+       else
+               condlog(4, "wwid %s already in wwids file", wwid);
+       return 0;
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -4,18 +4,34 @@ SUBSYSTEM!="block", GOTO="end_mpath"
+ IMPORT{cmdline}="nompath"
+ ENV{nompath}=="?*", GOTO="end_mpath"
++ENV{DEVTYPE}=="partition", GOTO="end_mpath"
+ ENV{MPATH_SBIN_PATH}="/sbin"
+ TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
++TEST!="/etc/multipath.conf", GOTO="check_kpartx"
+-ACTION=="add", ENV{DEVTYPE}!="partition", \
+-      ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
+-      TEST=="/etc/multipath.conf", \
++ACTION=="add", ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
+       PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
+-      ENV{DM_MULTIPATH_DEVICE_PATH}="1" ENV{ID_FS_TYPE}="mpath_member"
++      ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member"
+-ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
++ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
+       RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
++ACTION!="change", GOTO="update_timestamp"
++IMPORT{db}="DM_MULTIPATH_TIMESTAMP"
++IMPORT{db}="DM_MULTIPATH_DEVICE_PATH"
++# Check if the device is part of a multipath device. the -T option just keeps
++# the old result if the timestamp hasn't changed.
++PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -T $env{DM_MULTIPATH_TIMESTAMP}:$env{DM_MULTIPATH_DEVICE_PATH} -c $env{DEVNAME}", \
++      ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member", \
++      GOTO="update_timestamp"
++
++# If the device isn't part of a multipath device, clear this
++ENV{DM_MULTIPATH_DEVICE_PATH}=""
++
++LABEL="update_timestamp"
++IMPORT{file}="/run/multipathd/timestamp"
++
++LABEL="check_kpartx"
+ KERNEL!="dm-*", GOTO="end_mpath"
+ ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
+ ACTION!="change", GOTO="end_mpath"
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -54,6 +54,7 @@
+ #include <pgpolicies.h>
+ #include <uevent.h>
+ #include <log.h>
++#include <file.h>
+ #include "main.h"
+ #include "pidfile.h"
+@@ -1417,6 +1418,7 @@ reconfigure (struct vectors * vecs)
+               free_config(old);
+               retval = 0;
+       }
++      update_timestamp(0);
+       return retval;
+ }
+@@ -1709,6 +1711,7 @@ child (void * param)
+       /* Startup complete, create logfile */
+       pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
++      update_timestamp(1);
+       /* Ignore errors, we can live without */
+       running_state = DAEMON_RUNNING;
+@@ -1758,6 +1761,7 @@ child (void * param)
+       if (!pid_rc) {
+               condlog(3, "unlink pidfile");
+               unlink(DEFAULT_PIDFILE);
++              unlink(DEFAULT_TIMESTAMP_FILE);
+       }
+       condlog(2, "--------shut down-------");
+Index: multipath-tools-130222/multipathd/multipathd.service
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.service
++++ multipath-tools-130222/multipathd/multipathd.service
+@@ -9,7 +9,7 @@ Conflicts=shutdown.target
+ [Service]
+ Type=forking
+-PIDFile=/var/run/multipathd.pid
++PIDFile=/var/run/multipathd/multipathd.pid
+ ExecStartPre=/sbin/modprobe dm-multipath
+ ExecStart=/sbin/multipathd
+ ExecReload=/sbin/multipathd reconfigure
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -55,6 +55,7 @@
+ #include <sys/time.h>
+ #include <sys/resource.h>
+ #include <wwids.h>
++#include <file.h>
+ #include "dev_t.h"
+ int logsink;
+@@ -84,7 +85,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-c|-w|-W] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [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);
+@@ -98,6 +99,9 @@ usage (char * progname)
+               "  -f      flush a multipath device map\n" \
+               "  -F      flush all multipath device maps\n" \
+               "  -c      check if a device should be a path in a multipath device\n" \
++              "  -T tm:val\n" \
++              "          check if tm matches the multipathd timestamp. If so val is\n" \
++              "          whether or not the device is a path in a multipath device\n" \
+               "  -q      allow queue_if_no_path when multipathd is not running\n"\
+               "  -d      dry run, do not create or update devmaps\n" \
+               "  -t      dump internal hardware table\n" \
+@@ -441,7 +445,31 @@ main (int argc, char *argv[])
+       extern char *optarg;
+       extern int optind;
+       int r = 1;
+-
++      long int timestamp = -1;
++      int valid = -1;
++      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++              switch(arg) {
++              case 'T':
++                      if (optarg[0] == ':')
++                              sscanf(optarg, ":%d", &valid);
++                      else
++                              sscanf(optarg, "%ld:%d", &timestamp, &valid);
++                      if (timestamp_equal(timestamp))
++                              return (valid != 1);
++                      break;
++              case ':':
++                      fprintf(stderr, "Missing option argument\n");
++                      usage(argv[0]);
++                      exit(1);
++              case '?':
++                      fprintf(stderr, "Unknown switch: %s\n", optarg);
++                      usage(argv[0]);
++                      exit(1);
++              default:
++                      break;
++              }
++      }
++      optind = 1;
+       if (getuid() != 0) {
+               fprintf(stderr, "need to be root\n");
+               exit(1);
+@@ -455,7 +483,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtqwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -517,6 +545,8 @@ main (int argc, char *argv[])
+               case 't':
+                       r = dump_config();
+                       goto out;
++              case 'T':
++                      break;
+               case 'h':
+                       usage(argv[0]);
+                       exit(0);
diff --git a/multipath-tools/patches/0065-UPBZ-995538-fail-rdac-on-unavailable.patch b/multipath-tools/patches/0065-UPBZ-995538-fail-rdac-on-unavailable.patch
new file mode 100644 (file)
index 0000000..ca72b61
--- /dev/null
@@ -0,0 +1,21 @@
+---
+ libmultipath/checkers/rdac.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/checkers/rdac.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
++++ multipath-tools-130222/libmultipath/checkers/rdac.c
+@@ -222,10 +222,9 @@ libcheck_check (struct checker * c)
+               goto done;
+       }
+-      /* check if controller is in service mode */
++      /* check if controller is reporting asymmetric access state of unavailable */
+       if ((inq.avtcvp & 0x10) &&
+-          ((inq.asym_access_state_cur & 0x0F) == 0x3) &&
+-          (inq.vendor_specific_cur == 0x7)) {
++          ((inq.asym_access_state_cur & 0x0F) == 0x3)) {
+               ret = PATH_DOWN;
+               goto done;
+       }
diff --git a/multipath-tools/patches/0066-UP-dos-4k-partition-fix.patch b/multipath-tools/patches/0066-UP-dos-4k-partition-fix.patch
new file mode 100644 (file)
index 0000000..a2d1b44
--- /dev/null
@@ -0,0 +1,159 @@
+---
+ kpartx/dos.c    |   17 ++++++++++-------
+ kpartx/gpt.c    |   20 +-------------------
+ kpartx/kpartx.c |   12 ++++++++++++
+ kpartx/kpartx.h |    8 ++++++++
+ 4 files changed, 31 insertions(+), 26 deletions(-)
+
+Index: multipath-tools-130222/kpartx/dos.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/dos.c
++++ multipath-tools-130222/kpartx/dos.c
+@@ -26,7 +26,9 @@ read_extended_partition(int fd, struct p
+       int moretodo = 1;
+       int i, n=0;
+-      next = start = le32_to_cpu(ep->start_sect);
++      int sector_size_mul = get_sector_size(fd)/512;
++
++      next = start = sector_size_mul * le32_to_cpu(ep->start_sect);
+       while (moretodo) {
+               here = next;
+@@ -45,14 +47,14 @@ read_extended_partition(int fd, struct p
+                       memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p));
+                       if (is_extended(p.sys_type)) {
+                               if (p.nr_sects && !moretodo) {
+-                                      next = start + le32_to_cpu(p.start_sect);
++                                      next = start + sector_size_mul * le32_to_cpu(p.start_sect);
+                                       moretodo = 1;
+                               }
+                               continue;
+                       }
+                       if (n < ns) {
+-                              sp[n].start = here + le32_to_cpu(p.start_sect);
+-                              sp[n].size = le32_to_cpu(p.nr_sects);
++                              sp[n].start = here + sector_size_mul * le32_to_cpu(p.start_sect);
++                              sp[n].size = sector_size_mul * le32_to_cpu(p.nr_sects);
+                               n++;
+                       } else {
+                               fprintf(stderr,
+@@ -76,6 +78,7 @@ read_dos_pt(int fd, struct slice all, st
+       unsigned long offset = all.start;
+       int i, n=4;
+       unsigned char *bp;
++      int sector_size_mul = get_sector_size(fd)/512;
+       bp = (unsigned char *)getblock(fd, offset);
+       if (bp == NULL)
+@@ -89,8 +92,8 @@ read_dos_pt(int fd, struct slice all, st
+               if (is_gpt(p.sys_type))
+                       return 0;
+               if (i < ns) {
+-                      sp[i].start =  le32_to_cpu(p.start_sect);
+-                      sp[i].size = le32_to_cpu(p.nr_sects);
++                      sp[i].start =  sector_size_mul * le32_to_cpu(p.start_sect);
++                      sp[i].size = sector_size_mul * le32_to_cpu(p.nr_sects);
+               } else {
+                       fprintf(stderr,
+                               "dos_partition: too many slices\n");
+@@ -99,7 +102,7 @@ read_dos_pt(int fd, struct slice all, st
+               if (is_extended(p.sys_type)) {
+                       n += read_extended_partition(fd, &p, sp+n, ns-n);
+                       /* hide the extended partition itself */
+-                      sp[i].size = 2;
++                      sp[i].size = sector_size_mul * 2;
+               }
+       }
+       return n;
+Index: multipath-tools-130222/kpartx/gpt.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/gpt.c
++++ multipath-tools-130222/kpartx/gpt.c
+@@ -38,6 +38,7 @@
+ #include <byteswap.h>
+ #include <linux/fs.h>
+ #include "crc32.h"
++#include "kpartx.h"
+ #if BYTE_ORDER == LITTLE_ENDIAN
+ #  define __le16_to_cpu(x) (x)
+@@ -116,25 +117,6 @@ is_pmbr_valid(legacy_mbr *mbr)
+ /************************************************************
+- * get_sector_size
+- * Requires:
+- *  - filedes is an open file descriptor, suitable for reading
+- * Modifies: nothing
+- * Returns:
+- *  sector size, or 512.
+- ************************************************************/
+-static int
+-get_sector_size(int filedes)
+-{
+-      int rc, sector_size = 512;
+-
+-      rc = ioctl(filedes, BLKSSZGET, &sector_size);
+-      if (rc)
+-              sector_size = 512;
+-      return sector_size;
+-}
+-
+-/************************************************************
+  * _get_num_sectors
+  * Requires:
+  *  - filedes is an open file descriptor, suitable for reading
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -26,6 +26,7 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <stdint.h>
++#include <sys/ioctl.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <ctype.h>
+@@ -606,3 +607,14 @@ getblock (int fd, unsigned int secnr) {
+       return bp->block;
+ }
++
++int
++get_sector_size(int filedes)
++{
++      int rc, sector_size = 512;
++
++      rc = ioctl(filedes, BLKSSZGET, &sector_size);
++      if (rc)
++              sector_size = 512;
++      return sector_size;
++}
+Index: multipath-tools-130222/kpartx/kpartx.h
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.h
++++ multipath-tools-130222/kpartx/kpartx.h
+@@ -2,6 +2,7 @@
+ #define _KPARTX_H
+ #include <stdint.h>
++#include <sys/ioctl.h>
+ /*
+  * For each partition type there is a routine that takes
+@@ -18,6 +19,13 @@
+ #define safe_sprintf(var, format, args...)    \
+       snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
++#ifndef BLKSSZGET
++#define BLKSSZGET  _IO(0x12,104)      /* get block device sector size */
++#endif
++
++int
++get_sector_size(int filedes);
++
+ /*
+  * units: 512 byte sectors
+  */
diff --git a/multipath-tools/patches/0067-RHBZ-1022899-fix-udev-partition-handling.patch b/multipath-tools/patches/0067-RHBZ-1022899-fix-udev-partition-handling.patch
new file mode 100644 (file)
index 0000000..6f0a3d8
--- /dev/null
@@ -0,0 +1,37 @@
+---
+ multipath/multipath.rules |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -13,12 +13,13 @@ ACTION=="add", ENV{DM_MULTIPATH_DEVICE_P
+       PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
+       ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member"
+-ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
++ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DM_MULTIPATH_WIPE_PARTS}="1", \
+       RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
+ ACTION!="change", GOTO="update_timestamp"
+ IMPORT{db}="DM_MULTIPATH_TIMESTAMP"
+ IMPORT{db}="DM_MULTIPATH_DEVICE_PATH"
++IMPORT{db}="DM_MULTIPATH_WIPE_PARTS"
+ # Check if the device is part of a multipath device. the -T option just keeps
+ # the old result if the timestamp hasn't changed.
+ PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -T $env{DM_MULTIPATH_TIMESTAMP}:$env{DM_MULTIPATH_DEVICE_PATH} -c $env{DEVNAME}", \
+@@ -27,8 +28,13 @@ PROGRAM=="$env{MPATH_SBIN_PATH}/multipat
+ # If the device isn't part of a multipath device, clear this
+ ENV{DM_MULTIPATH_DEVICE_PATH}=""
++ENV{DM_MULTIPATH_WIPE_PARTS}=""
+ LABEL="update_timestamp"
++ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DM_MULTIPATH_WIPE_PARTS}!="1", \
++      ENV{DM_MULTIPATH_WIPE_PARTS}="1", \
++      RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
++
+ IMPORT{file}="/run/multipathd/timestamp"
+ LABEL="check_kpartx"
diff --git a/multipath-tools/patches/0068-RHBZ-1034578-label-partition-devices.patch b/multipath-tools/patches/0068-RHBZ-1034578-label-partition-devices.patch
new file mode 100644 (file)
index 0000000..e8008f7
--- /dev/null
@@ -0,0 +1,18 @@
+---
+ multipath/multipath.rules |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -4,7 +4,8 @@ SUBSYSTEM!="block", GOTO="end_mpath"
+ IMPORT{cmdline}="nompath"
+ ENV{nompath}=="?*", GOTO="end_mpath"
+-ENV{DEVTYPE}=="partition", GOTO="end_mpath"
++ENV{DEVTYPE}=="partition", IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH", \
++      GOTO="end_mpath"
+ ENV{MPATH_SBIN_PATH}="/sbin"
+ TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
+ TEST!="/etc/multipath.conf", GOTO="check_kpartx"
diff --git a/multipath-tools/patches/0069-UPBZ-1033791-improve-rdac-checker.patch b/multipath-tools/patches/0069-UPBZ-1033791-improve-rdac-checker.patch
new file mode 100644 (file)
index 0000000..c838f29
--- /dev/null
@@ -0,0 +1,153 @@
+---
+ libmultipath/checkers/rdac.c |   91 ++++++++++++++++++++++++++++++++++++++-----
+ libmultipath/discovery.c     |    2 
+ 2 files changed, 81 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/checkers/rdac.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
++++ multipath-tools-130222/libmultipath/checkers/rdac.c
+@@ -34,6 +34,18 @@
+ #define MSG_RDAC_UP    "rdac checker reports path is up"
+ #define MSG_RDAC_DOWN  "rdac checker reports path is down"
+ #define MSG_RDAC_GHOST "rdac checker reports path is ghost"
++#define MSG_RDAC_DOWN_TYPE(STR) MSG_RDAC_DOWN": "STR
++
++#define RTPG_UNAVAILABLE      0x3
++#define RTPG_OFFLINE          0xE
++#define RTPG_TRANSITIONING    0xF
++
++#define RTPG_UNAVAIL_NON_RESPONSIVE   0x2
++#define RTPG_UNAVAIL_IN_RESET         0x3
++#define RTPG_UNAVAIL_CFW_DL1          0x4
++#define RTPG_UNAVAIL_CFW_DL2          0x5
++#define RTPG_UNAVAIL_QUIESCED         0x6
++#define RTPG_UNAVAIL_SERVICE_MODE     0x7
+ struct control_mode_page {
+       unsigned char header[8];
+@@ -199,22 +211,64 @@ struct volume_access_inq
+       char PQ_PDT;
+       char dontcare0[7];
+       char avtcvp;
+-      char dontcare1;
+-      char asym_access_state_cur;
++      char vol_ppp;
++      char aas_cur;
+       char vendor_specific_cur;
+-      char dontcare2[36];
++      char aas_alt;
++      char vendor_specific_alt;
++      char dontcare1[34];
+ };
++const char
++*checker_msg_string(struct volume_access_inq *inq)
++{
++      /* lun not connected */
++      if (((inq->PQ_PDT & 0xE0) == 0x20) || (inq->PQ_PDT & 0x7f))
++              return MSG_RDAC_DOWN_TYPE("lun not connected");
++
++      /* if no tpg data is available, give the generic path down message */
++      if (!(inq->avtcvp & 0x10))
++              return MSG_RDAC_DOWN;
++
++      /* controller is booting up */
++      if (((inq->aas_cur & 0x0F) == RTPG_TRANSITIONING) &&
++              (inq->aas_alt & 0x0F) != RTPG_TRANSITIONING)
++              return MSG_RDAC_DOWN_TYPE("ctlr is in startup sequence");
++
++      /* if not unavailable, give generic message */
++      if ((inq->aas_cur & 0x0F) != RTPG_UNAVAILABLE)
++              return MSG_RDAC_DOWN;
++
++      /* target port group unavailable */
++      switch (inq->vendor_specific_cur) {
++      case RTPG_UNAVAIL_NON_RESPONSIVE:
++              return MSG_RDAC_DOWN_TYPE("non-responsive to queries");
++      case RTPG_UNAVAIL_IN_RESET:
++              return MSG_RDAC_DOWN_TYPE("ctlr held in reset");
++      case RTPG_UNAVAIL_CFW_DL1:
++      case RTPG_UNAVAIL_CFW_DL2:
++              return MSG_RDAC_DOWN_TYPE("ctlr firmware downloading");
++      case RTPG_UNAVAIL_QUIESCED:
++              return MSG_RDAC_DOWN_TYPE("ctlr quiesced by admin request");
++      case RTPG_UNAVAIL_SERVICE_MODE:
++              return MSG_RDAC_DOWN_TYPE("ctlr is in service mode");
++      default:
++              return MSG_RDAC_DOWN_TYPE("ctlr is unavailable");
++      }
++}
++
+ extern int
+ libcheck_check (struct checker * c)
+ {
+       struct volume_access_inq inq;
+-      int ret;
++      int ret, inqfail;
++      inqfail = 0;
+       memset(&inq, 0, sizeof(struct volume_access_inq));
+       if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq),
+                       c->timeout)) {
+               ret = PATH_DOWN;
++              inqfail = 1;
+               goto done;
+       } else if (((inq.PQ_PDT & 0xE0) == 0x20) || (inq.PQ_PDT & 0x7f)) {
+               /* LUN not connected*/
+@@ -222,11 +276,27 @@ libcheck_check (struct checker * c)
+               goto done;
+       }
+-      /* check if controller is reporting asymmetric access state of unavailable */
+-      if ((inq.avtcvp & 0x10) &&
+-          ((inq.asym_access_state_cur & 0x0F) == 0x3)) {
+-              ret = PATH_DOWN;
+-              goto done;
++      /* If TPGDE bit set, evaluate TPG information */
++      if ((inq.avtcvp & 0x10)) {
++              switch (inq.aas_cur & 0x0F) {
++              /* Never use the path if it reports unavailable */
++              case RTPG_UNAVAILABLE:
++                      ret = PATH_DOWN;
++                      goto done;
++              /*
++               * If both controllers report transitioning, it
++               * means mode select or STPG is being processed.
++               *
++               * If this controller alone is transitioning, it's
++               * booting and we shouldn't use it yet.
++               */
++              case RTPG_TRANSITIONING:
++                      if ((inq.aas_alt & 0xF) != RTPG_TRANSITIONING) {
++                              ret = PATH_DOWN;
++                              goto done;
++                      }
++                      break;
++              }
+       }
+       /* If owner set or ioship mode is enabled return PATH_UP always */
+@@ -238,7 +308,8 @@ libcheck_check (struct checker * c)
+ done:
+       switch (ret) {
+       case PATH_DOWN:
+-              MSG(c, MSG_RDAC_DOWN);
++              MSG(c, (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
++                      checker_msg_string(&inq));
+               break;
+       case PATH_UP:
+               MSG(c, MSG_RDAC_UP);
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -1116,8 +1116,6 @@ pathinfo (struct path *pp, vector hwtabl
+                       if (!strlen(pp->wwid))
+                               get_uid(pp);
+                       get_prio(pp);
+-              } else {
+-                      pp->priority = PRIO_UNDEF;
+               }
+       }
diff --git a/multipath-tools/patches/0070-RHBZ-1036503-blacklist-td-devs.patch b/multipath-tools/patches/0070-RHBZ-1036503-blacklist-td-devs.patch
new file mode 100644 (file)
index 0000000..ffcae46
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/blacklist.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/blacklist.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/blacklist.c
++++ multipath-tools-130222/libmultipath/blacklist.c
+@@ -163,7 +163,7 @@ setup_default_blist (struct config * con
+       if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
+               return 1;
+-      str = STRDUP("^hd[a-z]");
++      str = STRDUP("^(td|hd)[a-z]");
+       if (!str)
+               return 1;
+       if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
diff --git a/multipath-tools/patches/0071-RHBZ-1031546-strip-dev.patch b/multipath-tools/patches/0071-RHBZ-1031546-strip-dev.patch
new file mode 100644 (file)
index 0000000..64118c2
--- /dev/null
@@ -0,0 +1,248 @@
+---
+ libmultipath/util.c       |   22 ++++++++++++++++++++++
+ libmultipath/util.h       |    1 +
+ multipath/main.c          |   23 +----------------------
+ multipathd/cli_handlers.c |   18 ++++++++++++++++++
+ 4 files changed, 42 insertions(+), 22 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/util.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/util.c
++++ multipath-tools-130222/libmultipath/util.c
+@@ -236,6 +236,28 @@ skip_proc:
+       return 0;
+ }
++/* This function returns a pointer inside of the supplied pathname string.
++ * If is_path_device is true, it may also modify the supplied string */
++char *convert_dev(char *name, int is_path_device)
++{
++      char *ptr;
++
++      if (!name)
++              return NULL;
++      if (is_path_device) {
++              ptr = strstr(name, "cciss/");
++              if (ptr) {
++                      ptr += 5;
++                      *ptr = '!';
++              }
++      }
++      if (!strncmp(name, "/dev/", 5) && strlen(name) > 5)
++              ptr = name + 5;
++      else
++              ptr = name;
++      return ptr;
++}
++
+ dev_t parse_devt(const char *dev_t)
+ {
+       int maj, min;
+Index: multipath-tools-130222/libmultipath/util.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/util.h
++++ multipath-tools-130222/libmultipath/util.h
+@@ -10,6 +10,7 @@ size_t strlcat(char *dst, const char *sr
+ void remove_trailing_chars(char *path, char c);
+ int devt2devname (char *, int, char *);
+ dev_t parse_devt(const char *dev_t);
++char *convert_dev(char *dev, int is_path_device);
+ #define safe_sprintf(var, format, args...)    \
+       snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -254,16 +254,7 @@ configure (void)
+       vecs.pathvec = pathvec;
+       vecs.mpvec = curmp;
+-      /*
+-       * dev is "/dev/" . "sysfs block dev"
+-       */
+-      if (conf->dev) {
+-              if (!strncmp(conf->dev, "/dev/", 5) &&
+-                  strlen(conf->dev) > 5)
+-                      dev = conf->dev + 5;
+-              else
+-                      dev = conf->dev;
+-      }
++      dev = convert_dev(conf->dev, (conf->dev_type == DEV_DEVNODE));
+       /*
+        * if we have a blacklisted device parameter, exit early
+@@ -427,16 +418,6 @@ get_dev_type(char *dev) {
+               return DEV_DEVMAP;
+ }
+-static void
+-convert_dev(char *dev)
+-{
+-      char *ptr = strstr(dev, "cciss/");
+-      if (ptr) {
+-              ptr += 5;
+-              *ptr = '!';
+-      }
+-}
+-
+ int
+ main (int argc, char *argv[])
+ {
+@@ -577,8 +558,6 @@ main (int argc, char *argv[])
+               strncpy(conf->dev, argv[optind], FILE_NAME_SIZE);
+               conf->dev_type = get_dev_type(conf->dev);
+-              if (conf->dev_type == DEV_DEVNODE)
+-                      convert_dev(conf->dev);
+       }
+       conf->daemon = 0;
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -235,6 +235,7 @@ cli_list_map_topology (void * v, char **
+       struct vectors * vecs = (struct vectors *)data;
+       char * param = get_keyparam(v, MAP);
+       
++      param = convert_dev(param, 0);
+       get_path_layout(vecs->pathvec, 0);
+       mpp = find_mp_by_str(vecs->mpvec, param);
+@@ -416,6 +417,7 @@ cli_add_path (void * v, char ** reply, i
+       struct path *pp;
+       int r;
++      param = convert_dev(param, 1);
+       condlog(2, "%s: add path (operator)", param);
+       if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
+@@ -459,6 +461,7 @@ cli_del_path (void * v, char ** reply, i
+       char * param = get_keyparam(v, PATH);
+       struct path *pp;
++      param = convert_dev(param, 1);
+       condlog(2, "%s: remove path (operator)", param);
+       pp = find_path_by_dev(vecs->pathvec, param);
+       if (!pp) {
+@@ -478,6 +481,7 @@ cli_add_map (void * v, char ** reply, in
+       char *alias;
+       int rc;
++      param = convert_dev(param, 0);
+       condlog(2, "%s: add map (operator)", param);
+       if (filter_wwid(conf->blist_wwid, conf->elist_wwid, param) > 0) {
+@@ -518,6 +522,7 @@ cli_del_map (void * v, char ** reply, in
+       char *alias;
+       int rc;
++      param = convert_dev(param, 0);
+       condlog(2, "%s: remove map (operator)", param);
+       minor = dm_get_minor(param);
+       if (minor < 0) {
+@@ -549,6 +554,7 @@ cli_reload(void *v, char **reply, int *l
+       struct multipath *mpp;
+       int minor;
++      mapname = convert_dev(mapname, 0);
+       condlog(2, "%s: reload map (operator)", mapname);
+       if (sscanf(mapname, "dm-%d", &minor) == 1)
+               mpp = find_mp_by_minor(vecs->mpvec, minor);
+@@ -591,6 +597,7 @@ cli_resize(void *v, char **reply, int *l
+       struct pathgroup *pgp;
+       struct path *pp;
++      mapname = convert_dev(mapname, 0);
+       condlog(2, "%s: resize map (operator)", mapname);
+       if (sscanf(mapname, "dm-%d", &minor) == 1)
+               mpp = find_mp_by_minor(vecs->mpvec, minor);
+@@ -665,6 +672,7 @@ cli_restore_queueing(void *v, char **rep
+       struct multipath *mpp;
+       int minor;
++      mapname = convert_dev(mapname, 0);
+       condlog(2, "%s: restore map queueing (operator)", mapname);
+       if (sscanf(mapname, "dm-%d", &minor) == 1)
+               mpp = find_mp_by_minor(vecs->mpvec, minor);
+@@ -716,6 +724,7 @@ cli_disable_queueing(void *v, char **rep
+       struct multipath *mpp;
+       int minor;
++      mapname = convert_dev(mapname, 0);
+       condlog(2, "%s: disable map queueing (operator)", mapname);
+       if (sscanf(mapname, "dm-%d", &minor) == 1)
+               mpp = find_mp_by_minor(vecs->mpvec, minor);
+@@ -753,6 +762,7 @@ cli_switch_group(void * v, char ** reply
+       char * mapname = get_keyparam(v, MAP);
+       int groupnum = atoi(get_keyparam(v, GROUP));
++      mapname = convert_dev(mapname, 0);
+       condlog(2, "%s: switch to path group #%i (operator)", mapname, groupnum);
+       return dm_switchgroup(mapname, groupnum);
+@@ -775,6 +785,7 @@ cli_suspend(void * v, char ** reply, int
+       char * param = get_keyparam(v, MAP);
+       int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param);
++      param = convert_dev(param, 0);
+       condlog(2, "%s: suspend (operator)", param);
+       if (!r) /* error */
+@@ -796,6 +807,7 @@ cli_resume(void * v, char ** reply, int
+       char * param = get_keyparam(v, MAP);
+       int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param);
++      param = convert_dev(param, 0);
+       condlog(2, "%s: resume (operator)", param);
+       if (!r) /* error */
+@@ -817,6 +829,7 @@ cli_reinstate(void * v, char ** reply, i
+       char * param = get_keyparam(v, PATH);
+       struct path * pp;
++      param = convert_dev(param, 1);
+       pp = find_path_by_dev(vecs->pathvec, param);
+       if (!pp)
+@@ -837,6 +850,7 @@ cli_reassign (void * v, char ** reply, i
+ {
+       char * param = get_keyparam(v, MAP);
++      param = convert_dev(param, 0);
+       condlog(3, "%s: reset devices (operator)", param);
+       dm_reassign(param);
+@@ -851,6 +865,7 @@ cli_fail(void * v, char ** reply, int *
+       struct path * pp;
+       int r;
++      param = convert_dev(param, 1);
+       pp = find_path_by_dev(vecs->pathvec, param);
+       if (!pp)
+@@ -962,6 +977,7 @@ cli_getprstatus (void * v, char ** reply
+       struct vectors * vecs = (struct vectors *)data;
+       char * param = get_keyparam(v, MAP);
++      param = convert_dev(param, 0);
+       get_path_layout(vecs->pathvec, 0);
+       mpp = find_mp_by_str(vecs->mpvec, param);
+@@ -991,6 +1007,7 @@ cli_setprstatus(void * v, char ** reply,
+       struct vectors * vecs = (struct vectors *)data;
+       char * param = get_keyparam(v, MAP);
++      param = convert_dev(param, 0);
+       get_path_layout(vecs->pathvec, 0);
+       mpp = find_mp_by_str(vecs->mpvec, param);
+@@ -1013,6 +1030,7 @@ cli_unsetprstatus(void * v, char ** repl
+       struct vectors * vecs = (struct vectors *)data;
+       char * param = get_keyparam(v, MAP);
++      param = convert_dev(param, 0);
+       get_path_layout(vecs->pathvec, 0);
+       mpp = find_mp_by_str(vecs->mpvec, param);
diff --git a/multipath-tools/patches/0072-RHBZ-1039199-check-loop-control.patch b/multipath-tools/patches/0072-RHBZ-1039199-check-loop-control.patch
new file mode 100644 (file)
index 0000000..21bd0c3
--- /dev/null
@@ -0,0 +1,46 @@
+---
+ kpartx/lopart.c |   18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/kpartx/lopart.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/lopart.c
++++ multipath-tools-130222/kpartx/lopart.c
+@@ -32,6 +32,10 @@
+ #include "lopart.h"
+ #include "xstrncpy.h"
++#ifndef LOOP_CTL_GET_FREE
++#define LOOP_CTL_GET_FREE       0x4C82
++#endif
++
+ #if !defined (__alpha__) && !defined (__ia64__) && !defined (__x86_64__) \
+         && !defined (__s390x__)
+ #define int2ptr(x)    ((void *) ((int) x))
+@@ -140,14 +144,24 @@ find_unused_loop_device (void)
+       char dev[20];
+       char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
+-      int i, j, fd, somedev = 0, someloop = 0, loop_known = 0;
++      int i, j, fd, first = 0, somedev = 0, someloop = 0, loop_known = 0;
+       struct stat statbuf;
+       struct loop_info loopinfo;
+       FILE *procdev;
++      if (stat("/dev/loop-control", &statbuf) == 0 &&
++          S_ISCHR(statbuf.st_mode)) {
++              fd = open("/dev/loop-control", O_RDWR);
++              if (fd >= 0) {
++                      first = ioctl(fd, LOOP_CTL_GET_FREE);
++                      close(fd);
++              }
++              if (first < 0)
++                      first = 0;
++      }
+       for (j = 0; j < SIZE(loop_formats); j++) {
+-          for(i = 0; i < 256; i++) {
++          for(i = first; i < 256; i++) {
+               sprintf(dev, loop_formats[j], i);
+               if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
diff --git a/multipath-tools/patches/0073-RH-update-build-flags.patch b/multipath-tools/patches/0073-RH-update-build-flags.patch
new file mode 100644 (file)
index 0000000..3ab72d0
--- /dev/null
@@ -0,0 +1,33 @@
+---
+ Makefile.inc                 |    2 +-
+ libmultipath/checkers/rdac.c |    4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/Makefile.inc
+===================================================================
+--- multipath-tools-130222.orig/Makefile.inc
++++ multipath-tools-130222/Makefile.inc
+@@ -39,7 +39,7 @@ GZIP        = /bin/gzip -9 -c
+ INSTALL_PROGRAM = install
+ ifndef RPM_OPT_FLAGS
+-      RPM_OPT_FLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
++      RPM_OPT_FLAGS = -O2 -g -pipe -Wformat-security -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4
+ endif
+ LDFLAGS     += -Wl,-z,relro
+Index: multipath-tools-130222/libmultipath/checkers/rdac.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
++++ multipath-tools-130222/libmultipath/checkers/rdac.c
+@@ -308,8 +308,8 @@ libcheck_check (struct checker * c)
+ done:
+       switch (ret) {
+       case PATH_DOWN:
+-              MSG(c, (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
+-                      checker_msg_string(&inq));
++              MSG(c, "%s", (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
++                           checker_msg_string(&inq));
+               break;
+       case PATH_UP:
+               MSG(c, MSG_RDAC_UP);
diff --git a/multipath-tools/patches/0074-RHBZ-1056976-dm-mpath-rules.patch b/multipath-tools/patches/0074-RHBZ-1056976-dm-mpath-rules.patch
new file mode 100644 (file)
index 0000000..9f6c880
--- /dev/null
@@ -0,0 +1,64 @@
+---
+ multipath/11-dm-mpath.rules |   34 ++++++++++++++++++++++++++++++++++
+ multipath/Makefile          |    2 ++
+ 2 files changed, 36 insertions(+)
+
+Index: multipath-tools-130222/multipath/11-dm-mpath.rules
+===================================================================
+--- /dev/null
++++ multipath-tools-130222/multipath/11-dm-mpath.rules
+@@ -0,0 +1,34 @@
++ACTION!="add|change", GOTO="mpath_end"
++ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="mpath_end"
++ENV{DM_UUID}!="mpath-?*", GOTO="mpath_end"
++
++# Do not initiate scanning if no path is available,
++# otherwise there would be a hang or IO error on access.
++# We'd like to avoid this, especially within udev processing.
++ENV{DM_NR_VALID_PATHS}!="?*", IMPORT{db}="DM_NR_VALID_PATHS"
++ENV{DM_NR_VALID_PATHS}=="0", ENV{DM_NOSCAN}="1"
++
++# Also skip all foreign rules if no path is available.
++# Remember the original value of DM_DISABLE_OTHER_RULES_FLAG
++# and restore it back once we have at least one path available.
++IMPORT{db}="DM_DISABLE_OTHER_RULES_FLAG_OLD"
++ENV{DM_ACTION}=="PATH_FAILED",\
++      ENV{DM_NR_VALID_PATHS}=="0",\
++      ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}=="",\
++      ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}",\
++      ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
++ENV{DM_ACTION}=="PATH_REINSTATED",\
++      ENV{DM_NR_VALID_PATHS}=="1",\
++      ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\
++      ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\
++      ENV{DM_ACTIVATION}="1"
++
++# DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem.
++# Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its
++# paths are lost/recovered. For any stack above the mpath device, this is not
++# something that should be reacted upon since it would be useless extra work.
++# It's exactly mpath's job to provide *seamless* device access to any of the
++# paths that are available underneath.
++ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_ACTIVATION}="0"
++
++LABEL="mpath_end"
+Index: multipath-tools-130222/multipath/Makefile
+===================================================================
+--- multipath-tools-130222.orig/multipath/Makefile
++++ multipath-tools-130222/multipath/Makefile
+@@ -25,6 +25,7 @@ install:
+       $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
+       $(INSTALL_PROGRAM) -d $(DESTDIR)/usr/lib/udev/rules.d
+       $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
++      $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)/usr/lib/udev/rules.d/11-dm-mpath.rules
+       $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
+       $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
+       $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
+@@ -33,6 +34,7 @@ install:
+ uninstall:
+       rm $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
++      rm $(DESTDIR)/usr/lib/udev/rules.d/11-dm-mpath.rules
+       rm $(DESTDIR)$(bindir)/$(EXEC)
+       rm $(DESTDIR)$(bindir)/mpathconf
+       rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
diff --git a/multipath-tools/patches/0075-RHBZ-1056976-reload-flag.patch b/multipath-tools/patches/0075-RHBZ-1056976-reload-flag.patch
new file mode 100644 (file)
index 0000000..ee2cdee
--- /dev/null
@@ -0,0 +1,246 @@
+---
+ kpartx/devmapper.c        |    4 ++--
+ kpartx/devmapper.h        |    8 +++++++-
+ kpartx/kpartx.c           |    6 +++---
+ libmultipath/configure.c  |    4 ++--
+ libmultipath/devmapper.c  |   26 ++++++++++++++------------
+ libmultipath/devmapper.h  |   10 ++++++++--
+ multipathd/cli_handlers.c |    4 ++--
+ 7 files changed, 38 insertions(+), 24 deletions(-)
+
+Index: multipath-tools-130222/kpartx/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.c
++++ multipath-tools-130222/kpartx/devmapper.c
+@@ -60,7 +60,7 @@ dm_prereq (char * str, int x, int y, int
+ }
+ extern int
+-dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
++dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie, uint16_t udev_flags) {
+       int r = 0;
+       int udev_wait_flag = (task == DM_DEVICE_RESUME ||
+                             task == DM_DEVICE_REMOVE);
+@@ -78,7 +78,7 @@ dm_simplecmd (int task, const char *name
+       if (no_flush)
+               dm_task_no_flush(dmt);
+-      if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, (udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK))
++      if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, ((udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK) | udev_flags))
+               goto out;
+       r = dm_task_run(dmt);
+Index: multipath-tools-130222/kpartx/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.h
++++ multipath-tools-130222/kpartx/devmapper.h
+@@ -2,10 +2,16 @@
+ #define MINOR(dev)      ((dev & 0xff) | ((dev >> 12) & 0xfff00))
+ #define MKDEV(ma,mi)    ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))
++#ifdef DM_SUBSYSTEM_UDEV_FLAG0
++#define MPATH_UDEV_RELOAD_FLAG DM_SUBSYSTEM_UDEV_FLAG0
++#else
++#define MPATH_UDEV_RELOAD_FLAG 0
++#endif
++
+ extern int udev_sync;
+ int dm_prereq (char *, int, int, int);
+-int dm_simplecmd (int, const char *, int, uint32_t *);
++int dm_simplecmd (int, const char *, int, uint32_t *, uint16_t);
+ int dm_addmap (int, const char *, const char *, const char *, uint64_t,
+              int, const char *, int, mode_t, uid_t, gid_t, uint32_t *);
+ int dm_map_present (char *);
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -421,7 +421,7 @@ main(int argc, char **argv){
+                                       continue;
+                               if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
+-                                                0, &cookie)) {
++                                                0, &cookie, 0)) {
+                                       r++;
+                                       continue;
+                               }
+@@ -473,7 +473,7 @@ main(int argc, char **argv){
+                               }
+                               if (op == DM_DEVICE_RELOAD &&
+                                   !dm_simplecmd(DM_DEVICE_RESUME, partname,
+-                                                1, &cookie)) {
++                                                1, &cookie, MPATH_UDEV_RELOAD_FLAG)) {
+                                       fprintf(stderr, "resume failed on %s\n",
+                                               partname);
+                                       r++;
+@@ -505,7 +505,7 @@ main(int argc, char **argv){
+                                       continue;
+                               if (!dm_simplecmd(DM_DEVICE_REMOVE,
+-                                                partname, 1, &cookie)) {
++                                                partname, 1, &cookie, 0)) {
+                                       r++;
+                                       continue;
+                               }
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -390,13 +390,13 @@ domap (struct multipath * mpp, char * pa
+       case ACT_RELOAD:
+               r = dm_addmap_reload(mpp, params);
+               if (r)
+-                      r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias);
++                      r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG);
+               break;
+       case ACT_RESIZE:
+               r = dm_addmap_reload(mpp, params);
+               if (r)
+-                      r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1);
++                      r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1, 0);
+               break;
+       case ACT_RENAME:
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -103,7 +103,9 @@ dm_lib_prereq (void)
+ {
+       char version[64];
+       int v[3];
+-#ifdef LIBDM_API_COOKIE
++#if defined(DM_SUBSYSTEM_UDEV_FLAG0)
++      int minv[3] = {1, 2, 82};
++#elif defined(LIBDM_API_COOKIE)
+       int minv[3] = {1, 2, 38};
+ #else
+       int minv[3] = {1, 2, 8};
+@@ -200,7 +202,7 @@ dm_prereq (void)
+ }
+ static int
+-dm_simplecmd (int task, const char *name, int no_flush, int need_sync) {
++dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags) {
+       int r = 0;
+       int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
+                                           task == DM_DEVICE_REMOVE));
+@@ -219,7 +221,7 @@ dm_simplecmd (int task, const char *name
+               dm_task_no_flush(dmt);          /* for DM_DEVICE_SUSPEND/RESUME */
+ #endif
+-      if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
++      if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags))
+               goto out;
+       r = dm_task_run (dmt);
+@@ -229,13 +231,13 @@ dm_simplecmd (int task, const char *name
+ }
+ extern int
+-dm_simplecmd_flush (int task, const char *name, int needsync) {
+-      return dm_simplecmd(task, name, 0, needsync);
++dm_simplecmd_flush (int task, const char *name, int needsync, uint16_t udev_flags) {
++      return dm_simplecmd(task, name, 0, needsync, udev_flags);
+ }
+ extern int
+-dm_simplecmd_noflush (int task, const char *name) {
+-      return dm_simplecmd(task, name, 1, 1);
++dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) {
++      return dm_simplecmd(task, name, 1, 1, udev_flags);
+ }
+ extern int
+@@ -670,7 +672,7 @@ _dm_flush_map (const char * mapname, int
+               return 1;
+       }
+-      r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync);
++      r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync, 0);
+       if (r) {
+               condlog(4, "multipath map %s removed", mapname);
+@@ -703,14 +705,14 @@ dm_suspend_and_flush_map (const char * m
+       if (s)
+               queue_if_no_path = 0;
+       else
+-              s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0);
++              s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0, 0);
+       if (!dm_flush_map(mapname)) {
+               condlog(4, "multipath map %s removed", mapname);
+               return 0;
+       }
+       condlog(2, "failed to remove multipath map %s", mapname);
+-      dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname);
++      dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 0);
+       if (queue_if_no_path)
+               s = dm_queue_if_no_path((char *)mapname, 1);
+       return 1;
+@@ -1077,7 +1079,7 @@ dm_remove_partmaps (const char * mapname
+                       condlog(4, "partition map %s removed",
+                               names->name);
+                       dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name,
+-                                         need_sync);
++                                         need_sync, 0);
+               }
+               next = names->next;
+@@ -1305,7 +1307,7 @@ int dm_reassign_table(const char *name,
+                       condlog(3, "%s: failed to reassign targets", name);
+                       goto out_reload;
+               }
+-              dm_simplecmd_noflush(DM_DEVICE_RESUME, name);
++              dm_simplecmd_noflush(DM_DEVICE_RESUME, name, MPATH_UDEV_RELOAD_FLAG);
+       }
+       r = 1;
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -6,11 +6,17 @@
+ #define TGT_MPATH     "multipath"
+ #define TGT_PART      "linear"
++#ifdef DM_SUBSYSTEM_UDEV_FLAG0
++#define MPATH_UDEV_RELOAD_FLAG DM_SUBSYSTEM_UDEV_FLAG0
++#else
++#define MPATH_UDEV_RELOAD_FLAG 0
++#endif
++
+ void dm_init(void);
+ int dm_prereq (void);
+ int dm_drv_version (unsigned int * version, char * str);
+-int dm_simplecmd_flush (int, const char *, int);
+-int dm_simplecmd_noflush (int, const char *);
++int dm_simplecmd_flush (int, const char *, int, uint16_t);
++int dm_simplecmd_noflush (int, const char *, uint16_t);
+ int dm_addmap_create (struct multipath *mpp, char *params);
+ int dm_addmap_reload (struct multipath *mpp, char *params);
+ int dm_map_present (const char *);
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -783,7 +783,7 @@ cli_suspend(void * v, char ** reply, int
+ {
+       struct vectors * vecs = (struct vectors *)data;
+       char * param = get_keyparam(v, MAP);
+-      int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param);
++      int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
+       param = convert_dev(param, 0);
+       condlog(2, "%s: suspend (operator)", param);
+@@ -805,7 +805,7 @@ cli_resume(void * v, char ** reply, int
+ {
+       struct vectors * vecs = (struct vectors *)data;
+       char * param = get_keyparam(v, MAP);
+-      int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param);
++      int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
+       param = convert_dev(param, 0);
+       condlog(2, "%s: resume (operator)", param);
diff --git a/multipath-tools/patches/0076-RHBZ-1056686-add-hw_str_match.patch b/multipath-tools/patches/0076-RHBZ-1056686-add-hw_str_match.patch
new file mode 100644 (file)
index 0000000..dc9aca6
--- /dev/null
@@ -0,0 +1,125 @@
+---
+ libmultipath/config.c      |   10 ++++++++--
+ libmultipath/config.h      |    1 +
+ libmultipath/dict.c        |   28 ++++++++++++++++++++++++++++
+ multipath/multipath.conf.5 |   11 +++++++++++
+ 4 files changed, 48 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -431,11 +431,16 @@ restart:
+                       break;
+               j = n;
+               vector_foreach_slot_after(hw, hwe2, j) {
+-                      if (hwe_regmatch(hwe1, hwe2))
++                      if (conf->hw_strmatch) {
++                              if (hwe_strmatch(hwe2, hwe1))
++                                      continue;
++                      }
++                      else if (hwe_regmatch(hwe1, hwe2))
+                               continue;
+                       /* dup */
+                       merge_hwe(hwe2, hwe1);
+-                      if (hwe_strmatch(hwe2, hwe1) == 0) {
++                      if (conf->hw_strmatch ||
++                          hwe_strmatch(hwe2, hwe1) == 0) {
+                               vector_del_slot(hw, i);
+                               free_hwe(hwe1);
+                               n -= 1;
+@@ -550,6 +555,7 @@ load_config (char * file, struct udev *u
+       conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
+       conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
+       conf->detect_prio = DEFAULT_DETECT_PRIO;
++      conf->hw_strmatch = 0;
+       /*
+        * preload default hwtable
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -107,6 +107,7 @@ struct config {
+       int log_checker_err;
+       int allow_queueing;
+       int find_multipaths;
++      int hw_strmatch;
+       uid_t uid;
+       gid_t gid;
+       mode_t mode;
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -693,6 +693,25 @@ def_detect_prio_handler(vector strvec)
+       return 0;
+ }
++static int
++def_hw_strmatch_handler(vector strvec)
++{
++      char *buff;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
++          !strncmp(buff, "1", 1))
++              conf->hw_strmatch = 1;
++      else
++              conf->hw_strmatch = 0;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * blacklist block handlers
+  */
+@@ -2795,6 +2814,14 @@ snprint_def_detect_prio(char * buff, int
+ }
+ static int
++snprint_def_hw_strmatch(char * buff, int len, void * data)
++{
++      if (conf->hw_strmatch)
++              return snprintf(buff, len, "yes");
++      return snprintf(buff, len, "no");
++}
++
++static int
+ snprint_ble_simple (char * buff, int len, void * data)
+ {
+       struct blentry * ble = (struct blentry *)data;
+@@ -2861,6 +2888,7 @@ init_keywords(void)
+       install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
+       install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
+       install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
++      install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
+       __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -400,6 +400,17 @@ will automatically use the
+ .I alua
+ prioritizer. If not, the prioritizer will be selected as usual. Default is
+ .I no
++.TP
++.B hw_str_match
++If set to
++.I yes
++, the vendor, product, and revision parameters of user device configs will be
++string matched against the built-in device configs to determine if they should
++modify an existing config, or create a new one. If set to
++.I no
++, the user device configs will be regular expression matched against the
++built-in configs instead. Default is
++.I no
+ .
+ .SH "blacklist section"
+ The
diff --git a/multipath-tools/patches/0078-RHBZ-1054044-fix-mpathconf-manpage.patch b/multipath-tools/patches/0078-RHBZ-1054044-fix-mpathconf-manpage.patch
new file mode 100644 (file)
index 0000000..b06b410
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ multipath/mpathconf.8 |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/mpathconf.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/mpathconf.8
++++ multipath-tools-130222/multipath/mpathconf.8
+@@ -86,7 +86,7 @@ If set to \fBy\fP, this runs
+ .B service multipathd start
+ to start the multipathd daemon on \fB--enable\fP,
+ .B service multipathd stop
+-to start the multipathd daemon on \fB--disable\fP, and
++to stop the multipathd daemon on \fB--disable\fP, and
+ .B service multipathd reload
+ to reconfigure multipathd on \fB--user_frindly_names\fP and
+ \fB--find_multipaths\fP.
diff --git a/multipath-tools/patches/0079-RHBZ-1070581-add-wwid-option.patch b/multipath-tools/patches/0079-RHBZ-1070581-add-wwid-option.patch
new file mode 100644 (file)
index 0000000..e967a51
--- /dev/null
@@ -0,0 +1,93 @@
+---
+ multipath/main.c      |   19 ++++++++++++++++---
+ multipath/multipath.8 |    5 ++++-
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -85,7 +85,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-a|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [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);
+@@ -98,6 +98,7 @@ usage (char * progname)
+               "  -ll     show multipath topology (maximum info)\n" \
+               "  -f      flush a multipath device map\n" \
+               "  -F      flush all multipath device maps\n" \
++              "  -a      add a device wwid to the wwids file\n" \
+               "  -c      check if a device should be a path in a multipath device\n" \
+               "  -T tm:val\n" \
+               "          check if tm matches the multipathd timestamp. If so val is\n" \
+@@ -292,6 +293,15 @@ configure (void)
+                       }
+                       goto out;
+               }
++              if (conf->dry_run == 5) {
++                      r = remember_wwid(refwwid);
++                      if (r == 0)
++                              printf("wwid '%s' added\n", refwwid);
++                      else
++                              printf("failed adding '%s' to wwids file\n",
++                                      refwwid);
++                      goto out;
++              }
+               condlog(3, "scope limited to %s", refwwid);
+               if (conf->dry_run == 2) {
+                       if (check_wwids_file(refwwid, 0) == 0){
+@@ -428,7 +438,7 @@ main (int argc, char *argv[])
+       int r = 1;
+       long int timestamp = -1;
+       int valid = -1;
+-      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
+               switch(arg) {
+               case 'T':
+                       if (optarg[0] == ':')
+@@ -464,7 +474,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -537,6 +547,9 @@ main (int argc, char *argv[])
+               case 'W':
+                       conf->dry_run = 4;
+                       break;
++              case 'a':
++                      conf->dry_run = 5;
++                      break;
+               case ':':
+                       fprintf(stderr, "Missing option argument\n");
+                       usage(argv[0]);
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
+ .RB [\| \-b\ \c
+ .IR bindings_file \|]
+ .RB [\| \-d \|]
+-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w | \-W \|]
++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-w | \-W \|]
+ .RB [\| \-p\ \c
+ .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
+ .RB [\| device \|]
+@@ -68,6 +68,9 @@ check if a block device should be a path
+ .B \-q
+ allow device tables with queue_if_no_path when multipathd is not running
+ .TP
++.B \-a
++add the wwid for the specified device to the wwids file
++.TP
+ .B \-w
+ remove the wwid for the specified device from the wwids file
+ .TP
diff --git a/multipath-tools/patches/0080-RHBZ-1075796-cmdline-wwid.patch b/multipath-tools/patches/0080-RHBZ-1075796-cmdline-wwid.patch
new file mode 100644 (file)
index 0000000..f943aa3
--- /dev/null
@@ -0,0 +1,157 @@
+---
+ libmultipath/wwids.c          |   44 ++++++++++++++++++++++++++++++++++++++++++
+ libmultipath/wwids.h          |    1 
+ multipath/main.c              |   12 ++++++++---
+ multipath/multipath.8         |    5 +++-
+ multipathd/multipathd.service |    1 
+ 5 files changed, 59 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -305,3 +305,47 @@ remember_wwid(char *wwid)
+               condlog(4, "wwid %s already in wwids file", wwid);
+       return 0;
+ }
++
++int remember_cmdline_wwid(void)
++{
++      FILE *f = NULL;
++      char buf[LINE_MAX], *next, *ptr;
++      int ret = 0;
++
++      f = fopen("/proc/cmdline", "re");
++      if (!f) {
++              condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
++              return -1;
++      }
++
++      if (!fgets(buf, sizeof(buf), f)) {
++              if (ferror(f))
++                      condlog(0, "read of /proc/cmdline failed : %s",
++                              strerror(errno));
++              else
++                      condlog(0, "couldn't read /proc/cmdline");
++              fclose(f);
++              return -1;
++      }
++      fclose(f);
++      next = buf;
++      while((ptr = strstr(next, "mpath.wwid="))) {
++              ptr += 11;
++              next = strpbrk(ptr, " \t\n");
++              if (next) {
++                      *next = '\0';
++                      next++;
++              }
++              if (strlen(ptr)) {
++                      if (remember_wwid(ptr) != 0)
++                              ret = -1;
++              }
++              else {
++                      condlog(0, "empty mpath.wwid kernel command line option");
++                      ret = -1;
++              }
++              if (!next)
++                      break;
++      }
++      return ret;
++}
+Index: multipath-tools-130222/libmultipath/wwids.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.h
++++ multipath-tools-130222/libmultipath/wwids.h
+@@ -17,5 +17,6 @@ int remember_wwid(char *wwid);
+ int check_wwids_file(char *wwid, int write_wwid);
+ int remove_wwid(char *wwid);
+ int replace_wwids(vector mp);
++int remember_cmdline_wwid(void);
+ #endif /* _WWIDS_H */
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -85,7 +85,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-a|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [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);
+@@ -99,6 +99,8 @@ usage (char * progname)
+               "  -f      flush a multipath device map\n" \
+               "  -F      flush all multipath device maps\n" \
+               "  -a      add a device wwid to the wwids file\n" \
++              "  -A      add devices from kernel command line mpath.wwids\n"
++              "          parameters to wwids file\n" \
+               "  -c      check if a device should be a path in a multipath device\n" \
+               "  -T tm:val\n" \
+               "          check if tm matches the multipathd timestamp. If so val is\n" \
+@@ -438,7 +440,7 @@ main (int argc, char *argv[])
+       int r = 1;
+       long int timestamp = -1;
+       int valid = -1;
+-      while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
+               switch(arg) {
+               case 'T':
+                       if (optarg[0] == ':')
+@@ -474,7 +476,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -538,6 +540,10 @@ main (int argc, char *argv[])
+                       goto out;
+               case 'T':
+                       break;
++              case 'A':
++                      if (remember_cmdline_wwid() != 0)
++                              exit(1);
++                      exit(0);
+               case 'h':
+                       usage(argv[0]);
+                       exit(0);
+Index: multipath-tools-130222/multipathd/multipathd.service
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.service
++++ multipath-tools-130222/multipathd/multipathd.service
+@@ -11,6 +11,7 @@ Conflicts=shutdown.target
+ Type=forking
+ PIDFile=/var/run/multipathd/multipathd.pid
+ ExecStartPre=/sbin/modprobe dm-multipath
++ExecStartPre=-/sbin/multipath -A
+ ExecStart=/sbin/multipathd
+ ExecReload=/sbin/multipathd reconfigure
+ #ExecStop=/path/to/scrip delete-me if not necessary
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
+ .RB [\| \-b\ \c
+ .IR bindings_file \|]
+ .RB [\| \-d \|]
+-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-w | \-W \|]
++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-A | \-w | \-W \|]
+ .RB [\| \-p\ \c
+ .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
+ .RB [\| device \|]
+@@ -71,6 +71,9 @@ allow device tables with queue_if_no_pat
+ .B \-a
+ add the wwid for the specified device to the wwids file
+ .TP
++.B \-A
++add wwids from any kernel command line mpath.wwid parameters to the wwids file
++.TP
+ .B \-w
+ remove the wwid for the specified device from the wwids file
+ .TP
diff --git a/multipath-tools/patches/0081-RHBZ-1066264-check-prefix-on-rename.patch b/multipath-tools/patches/0081-RHBZ-1066264-check-prefix-on-rename.patch
new file mode 100644 (file)
index 0000000..791f32e
--- /dev/null
@@ -0,0 +1,41 @@
+---
+ libmultipath/devmapper.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -1151,6 +1151,8 @@ dm_rename_partmaps (char * old, char * n
+       unsigned long long size;
+       char dev_t[32];
+       int r = 1;
++      int offset;
++      char *delim;
+       if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
+               return 1;
+@@ -1171,6 +1173,11 @@ dm_rename_partmaps (char * old, char * n
+       if (dm_dev_t(old, &dev_t[0], 32))
+               goto out;
++      if (isdigit(new[strlen(new)-1]))
++              delim = "p";
++      else
++              delim = "";
++
+       do {
+               if (
+                   /*
+@@ -1198,8 +1205,9 @@ dm_rename_partmaps (char * old, char * n
+                                * then it's a kpartx generated partition.
+                                * Rename it.
+                                */
+-                              snprintf(buff, PARAMS_SIZE, "%s%s",
+-                                       new, names->name + strlen(old));
++                              for (offset = strlen(old); names->name[offset] && !(isdigit(names->name[offset])); offset++); /* do nothing */
++                              snprintf(buff, PARAMS_SIZE, "%s%s%s",
++                                       new, delim, names->name + offset);
+                               dm_rename(names->name, buff);
+                               condlog(4, "partition map %s renamed",
+                                       names->name);
diff --git a/multipath-tools/patches/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch b/multipath-tools/patches/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch
new file mode 100644 (file)
index 0000000..9a1bd34
--- /dev/null
@@ -0,0 +1,32 @@
+---
+ libmultipath/checkers/tur.c |    9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/checkers/tur.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers/tur.c
++++ multipath-tools-130222/libmultipath/checkers/tur.c
+@@ -409,7 +409,6 @@ libcheck_check (struct checker * c)
+                               ct->running = 0;
+                               MSG(c, MSG_TUR_TIMEOUT);
+                               tur_status = PATH_DOWN;
+-                              ct->state = PATH_UNCHECKED;
+                       } else {
+                               condlog(3, "%d:%d: tur checker not finished",
+                                       TUR_DEVT(ct));
+@@ -426,12 +425,10 @@ libcheck_check (struct checker * c)
+               pthread_mutex_unlock(&ct->lock);
+       } else {
+               if (ct->thread) {
+-                      /* pthread cancel failed. continue in sync mode */
+                       pthread_mutex_unlock(&ct->lock);
+-                      condlog(3, "%d:%d: tur thread not responding, "
+-                              "using sync mode", TUR_DEVT(ct));
+-                      return tur_check(c->fd, c->timeout, c->message,
+-                                       ct->wwid);
++                      condlog(3, "%d:%d: tur thread not responding, ",
++                              TUR_DEVT(ct));
++                      return PATH_DOWN;
+               }
+               /* Start new TUR checker */
+               ct->state = PATH_UNCHECKED;
diff --git a/multipath-tools/patches/0083-RHBZ-1080055-orphan-paths-on-reload.patch b/multipath-tools/patches/0083-RHBZ-1080055-orphan-paths-on-reload.patch
new file mode 100644 (file)
index 0000000..8eaee74
--- /dev/null
@@ -0,0 +1,85 @@
+---
+ libmultipath/structs_vec.c |   31 +++++++++++++++++++++++++++----
+ multipathd/main.c          |    4 ++++
+ 2 files changed, 31 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/structs_vec.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs_vec.c
++++ multipath-tools-130222/libmultipath/structs_vec.c
+@@ -280,12 +280,38 @@ update_multipath_status (struct multipat
+       return 0;
+ }
++void sync_paths(struct multipath *mpp, vector pathvec)
++{
++      struct path *pp;
++      struct pathgroup  *pgp;
++      int found, i, j;
++
++      vector_foreach_slot (mpp->paths, pp, i) {
++              found = 0;
++              vector_foreach_slot(mpp->pg, pgp, j) {
++                      if (find_slot(pgp->paths, (void *)pp) != -1) {
++                              found = 1;
++                              break;
++                      }
++              }
++              if (!found) {
++                      condlog(3, "%s dropped path %s", mpp->alias, pp->dev);
++                      vector_del_slot(mpp->paths, i--);
++                      orphan_path(pp);
++              }
++      }
++      update_mpp_paths(mpp, pathvec);
++      vector_foreach_slot (mpp->paths, pp, i)
++              pp->mpp = mpp;
++}
++
+ extern int
+ update_multipath_strings (struct multipath *mpp, vector pathvec)
+ {
+       if (!mpp)
+               return 1;
++      update_mpp_paths(mpp, pathvec);
+       condlog(4, "%s: %s", mpp->alias, __FUNCTION__);
+       free_multipath_attributes(mpp);
+@@ -294,6 +320,7 @@ update_multipath_strings (struct multipa
+       if (update_multipath_table(mpp, pathvec))
+               return 1;
++      sync_paths(mpp, pathvec);
+       if (update_multipath_status(mpp))
+               return 1;
+@@ -494,13 +521,9 @@ int update_multipath (struct vectors *ve
+               return 2;
+       }
+-      free_pgvec(mpp->pg, KEEP_PATHS);
+-      mpp->pg = NULL;
+-
+       if (__setup_multipath(vecs, mpp, reset))
+               return 1; /* mpp freed in setup_multipath */
+-      adopt_paths(vecs->pathvec, mpp, 0);
+       /*
+        * compare checkers states with DM states
+        */
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1152,6 +1152,10 @@ check_path (struct vectors * vecs, struc
+                       pp->dev);
+               pp->dmstate = PSTATE_UNDEF;
+       }
++      /* if update_multipath_strings orphaned the path, quit early */
++      if (!pp->mpp)
++              return;
++
+       pp->chkrstate = newstate;
+       if (newstate != pp->state) {
+               int oldstate = pp->state;
diff --git a/multipath-tools/patches/0084-RHBZ-1110000-multipath-man.patch b/multipath-tools/patches/0084-RHBZ-1110000-multipath-man.patch
new file mode 100644 (file)
index 0000000..4ea422a
--- /dev/null
@@ -0,0 +1,101 @@
+---
+ libmultipath/prioritizers/alua.c |    4 ++--
+ multipathd/multipathd.8          |   37 +++++++++++++++++++++++++++++++++----
+ 2 files changed, 35 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/multipathd/multipathd.8
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.8
++++ multipath-tools-130222/multipathd/multipathd.8
+@@ -42,6 +42,9 @@ format wildcards.
+ .B list|show maps|multipaths
+ Show the multipath devices that the multipathd is monitoring. 
+ .TP
++.B list|show daemon
++Show the current state of the multipathd daemon
++.TP
+ .B list|show maps|multipaths format $format
+ Show the status of all multipath devices that the multipathd is monitoring,
+ using a format string with multipath format wildcards.
+@@ -83,16 +86,16 @@ Add a path to the list of monitored path
+ .B remove|del path $path
+ Stop monitoring a path. $path is as listed in /sys/block (e.g. sda).
+ .TP
+-.B add map $map
++.B add map|multipath $map
+ Add a multipath device to the list of monitored devices. $map can either be a device-mapper device as listed in /sys/block (e.g. dm-0) or it can be the alias for the multipath device (e.g. mpath1) or the uid of the multipath device (e.g. 36005076303ffc56200000000000010aa). 
+ .TP
+-.B remove|del map $map
++.B remove|del map|multipath $map
+ Stop monitoring a multipath device.
+ .TP
+ .B resize map|multipath $map
+ Resizes map $map to the given size
+ .TP 
+-.B switch|switchgroup map $map group $group
++.B switch|switchgroup map|multipath $map group $group
+ Force a multipath device to switch to a specific path group. $group is the path group index, starting with 1.
+ .TP
+ .B reconfigure
+@@ -104,6 +107,13 @@ Sets map $map into suspend state.
+ .B resume map|multipath $map
+ Resumes map $map from suspend state.
+ .TP
++.B reset map|multipath $map
++Reassign existing device-mapper table(s) use use the multipath device, instead
++of its path devices.
++.TP
++.B reload map|multipath $map
++Reload a multipath device.
++.TP
+ .B fail path $path
+ Sets path $path into failed state.
+ .TP
+@@ -120,10 +130,29 @@ Restore queueing on all multipath device
+ Disable queuing on multipathed map $map
+ .TP
+ .B restorequeueing map|multipath $map
+-Restore queuing on multipahted map $map
++Restore queuing on multipathed map $map
++.TP
++.B forcequeueing daemon
++Forces multipathd into queue_without_daemon mode, so that no_path_retry queueing
++will not be disabled when the daemon stops
++.TP
++.B restorequeueing daemon
++Restores configured queue_without_daemon mode
++.TP
++.B map|multipath $map setprstatus
++Enable persistent reservation management on $map
++.TP
++.B map|multipath $map unsetprstatus
++Disable persistent reservation management on $map
++.TP
++.B map|multipath $map getprstatus
++Get the current persistent reservation management status of $map
+ .TP
+ .B quit|exit
+ End interactive session.
++.TP
++.B shutdown
++Stop multipathd.
+ .SH "SEE ALSO"
+ .BR multipath (8)
+Index: multipath-tools-130222/libmultipath/prioritizers/alua.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c
++++ multipath-tools-130222/libmultipath/prioritizers/alua.c
+@@ -119,10 +119,10 @@ int getprio (struct path * pp, char * ar
+                               condlog(0, "%s: couldn't get target port group", pp->dev);
+                               break;
+                       case ALUA_PRIO_GETAAS_FAILED:
+-                              condlog(0, "%s: couln't get asymmetric access state", pp->dev);
++                              condlog(0, "%s: couldn't get asymmetric access state", pp->dev);
+                               break;
+                       case ALUA_PRIO_TPGS_FAILED:
+-                              condlog(3, "%s: couln't get supported alua states", pp->dev);
++                              condlog(3, "%s: couldn't get supported alua states", pp->dev);
+                               break;
+               }
+       }
diff --git a/multipath-tools/patches/0085-UPBZ-1110006-datacore-config.patch b/multipath-tools/patches/0085-UPBZ-1110006-datacore-config.patch
new file mode 100644 (file)
index 0000000..cedb5e3
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ libmultipath/hwtable.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -1108,6 +1108,19 @@ static struct hwentry default_hw[] = {
+               .prio_name     = PRIO_ALUA,
+               .prio_args     = NULL,
+       },
++      {
++              .vendor        = "DataCore",
++              .product       = "Virtual Disk",
++              .features      = DEFAULT_FEATURES,
++              .hwhandler     = DEFAULT_HWHANDLER,
++              .pgpolicy      = GROUP_BY_PRIO,
++              .pgfailback    = -FAILBACK_IMMEDIATE,
++              .rr_weight     = RR_WEIGHT_NONE,
++              .no_path_retry = NO_PATH_RETRY_QUEUE,
++              .checker_name  = TUR,
++              .prio_name     = PRIO_ALUA,
++              .prio_args     = NULL,
++      },
+       /*
+        * EOL
+        */
diff --git a/multipath-tools/patches/0086-RHBZ-1110007-orphan-path-on-failed-add.patch b/multipath-tools/patches/0086-RHBZ-1110007-orphan-path-on-failed-add.patch
new file mode 100644 (file)
index 0000000..0d6aa58
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ multipathd/main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -562,7 +562,7 @@ rescan:
+               return 0;
+       }
+       else
+-              return 1;
++              goto fail;
+ fail_map:
+       remove_map(mpp, vecs, 1);
diff --git a/multipath-tools/patches/0087-RHBZ-1110013-config-error-checking.patch b/multipath-tools/patches/0087-RHBZ-1110013-config-error-checking.patch
new file mode 100644 (file)
index 0000000..c774bc5
--- /dev/null
@@ -0,0 +1,190 @@
+---
+ libmultipath/parser.c |  154 ++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 126 insertions(+), 28 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/parser.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/parser.c
++++ multipath-tools-130222/libmultipath/parser.c
+@@ -395,36 +395,57 @@ set_value(vector strvec)
+       char *alloc = NULL;
+       char *tmp;
+-      if (!str)
++      if (!str) {
++              condlog(0, "option '%s' missing value",
++                      (char *)VECTOR_SLOT(strvec, 0));
+               return NULL;
+-
++      }
+       size = strlen(str);
+-      if (size == 0)
++      if (size == 0) {
++              condlog(0, "option '%s' has empty value",
++                      (char *)VECTOR_SLOT(strvec, 0));
+               return NULL;
+-
+-      if (*str == '"') {
+-              for (i = 2; i < VECTOR_SIZE(strvec); i++) {
+-                      str = VECTOR_SLOT(strvec, i);
+-                      len += strlen(str);
+-                      if (!alloc)
+-                              alloc =
+-                                  (char *) MALLOC(sizeof (char *) *
+-                                                  (len + 1));
+-                      else {
+-                              alloc =
+-                                  REALLOC(alloc, sizeof (char *) * (len + 1));
+-                              tmp = VECTOR_SLOT(strvec, i-1);
+-                              if (alloc && *str != '"' && *tmp != '"')
+-                                      strncat(alloc, " ", 1);
+-                      }
+-
+-                      if (alloc && i != VECTOR_SIZE(strvec)-1)
+-                              strncat(alloc, str, strlen(str));
+-              }
+-      } else {
+-              alloc = MALLOC(sizeof (char *) * (size + 1));
++      }
++      if (*str != '"') {
++              alloc = MALLOC(sizeof (char) * (size + 1));
+               if (alloc)
+                       memcpy(alloc, str, size);
++              else
++                      condlog(0, "can't allocate memeory for option '%s'",
++                              (char *)VECTOR_SLOT(strvec, 0));
++              return alloc;
++      }
++      /* Even empty quotes counts as a value (An empty string) */
++      alloc = (char *) MALLOC(sizeof (char));
++      if (!alloc) {
++              condlog(0, "can't allocate memeory for option '%s'",
++                      (char *)VECTOR_SLOT(strvec, 0));
++              return NULL;
++      }
++      for (i = 2; i < VECTOR_SIZE(strvec); i++) {
++              str = VECTOR_SLOT(strvec, i);
++              if (!str) {
++                      free(alloc);
++                      condlog(0, "parse error for option '%s'",
++                              (char *)VECTOR_SLOT(strvec, 0));
++                      return NULL;
++              }
++              if (*str == '"')
++                      break;
++              tmp = alloc;
++              /* The first +1 is for the NULL byte. The rest are for the
++               * spaces between words */
++              len += strlen(str) + 1;
++              alloc = REALLOC(alloc, sizeof (char) * len);
++              if (!alloc) {
++                      FREE(tmp);
++                      condlog(0, "can't allocate memeory for option '%s'",
++                              (char *)VECTOR_SLOT(strvec, 0));
++                      return NULL;
++              }
++              if (*alloc != '\0')
++                      strncat(alloc, " ", 1);
++              strncat(alloc, str, strlen(str));
+       }
+       return alloc;
+ }
+@@ -465,6 +486,74 @@ void free_uniques(vector uniques)
+ }
+ int
++is_sublevel_keyword(char *str)
++{
++      return (strcmp(str, "defaults") == 0 || strcmp(str, "blacklist") == 0 ||
++              strcmp(str, "blacklist_exceptions") == 0 ||
++              strcmp(str, "devices") == 0 || strcmp(str, "devices") == 0 ||
++              strcmp(str, "device") == 0 || strcmp(str, "multipaths") == 0 ||
++              strcmp(str, "multipath") == 0);
++}
++
++int
++validate_config_strvec(vector strvec)
++{
++      char *str;
++      int i;
++
++      str = VECTOR_SLOT(strvec, 0);
++      if (str == NULL) {
++              condlog(0, "can't parse option on line %d of config file",
++                      line_nr);
++      return -1;
++      }
++      if (*str == '}') {
++              if (VECTOR_SIZE(strvec) > 1)
++                      condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr);
++              return 0;
++      }
++      if (*str == '{') {
++              condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr);
++              return -1;
++      }
++      if (is_sublevel_keyword(str)) {
++              str = VECTOR_SLOT(strvec, 1);
++              if (str == NULL)
++                      condlog(0, "missing '{' on line %d of config file", line_nr);
++              else if (*str != '{')
++                      condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str);
++              else if (VECTOR_SIZE(strvec) > 2)
++                      condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
++              return 0;
++      }
++      str = VECTOR_SLOT(strvec, 1);
++      if (str == NULL) {
++              condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr);
++              return -1;
++      }
++      if (*str != '"') {
++              if (VECTOR_SIZE(strvec) > 2)
++                      condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
++              return 0;
++      }
++      for (i = 2; i < VECTOR_SIZE(strvec); i++) {
++              str = VECTOR_SLOT(strvec, i);
++              if (str == NULL) {
++                      condlog(0, "can't parse value on line %d of config file", line_nr);
++                      return -1;
++              }
++              if (*str == '"') {
++                      if (VECTOR_SIZE(strvec) > i + 1)
++                              condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr);
++                      return 0;
++              }
++      }
++      condlog(0, "missing closing quotes on line %d of config file",
++              line_nr);
++      return 0;
++}
++
++int
+ process_stream(vector keywords)
+ {
+       int i;
+@@ -494,11 +583,20 @@ process_stream(vector keywords)
+               if (!strvec)
+                       continue;
++              if (validate_config_strvec(strvec) != 0) {
++                      free_strvec(strvec);
++                      continue;
++              }
++
+               str = VECTOR_SLOT(strvec, 0);
+-              if (!strcmp(str, EOB) && kw_level > 0) {
+-                      free_strvec(strvec);
+-                      break;
++              if (!strcmp(str, EOB)) {
++                      if (kw_level > 0) {
++                              free_strvec(strvec);
++                              break;
++                      }
++                      condlog(0, "unmatched '%s' at line %d of config file",
++                              EOB, line_nr);
+               }
+               for (i = 0; i < VECTOR_SIZE(keywords); i++) {
diff --git a/multipath-tools/patches/0088-RHBZ-1069811-configurable-prio-timeout.patch b/multipath-tools/patches/0088-RHBZ-1069811-configurable-prio-timeout.patch
new file mode 100644 (file)
index 0000000..60f374b
--- /dev/null
@@ -0,0 +1,178 @@
+---
+ libmultipath/prio.c                   |    7 +++++++
+ libmultipath/prio.h                   |    1 +
+ libmultipath/prioritizers/alua_rtpg.c |    5 +++--
+ libmultipath/prioritizers/emc.c       |    2 +-
+ libmultipath/prioritizers/hds.c       |    2 +-
+ libmultipath/prioritizers/hp_sw.c     |    2 +-
+ libmultipath/prioritizers/ontap.c     |    4 ++--
+ libmultipath/prioritizers/rdac.c      |    2 +-
+ multipath.conf.annotated              |    5 +++--
+ multipath/multipath.conf.5            |    4 ++--
+ 10 files changed, 22 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/prio.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prio.c
++++ multipath-tools-130222/libmultipath/prio.c
+@@ -10,6 +10,13 @@
+ static LIST_HEAD(prioritizers);
++unsigned int get_prio_timeout(unsigned int default_timeout)
++{
++      if (conf->checker_timeout)
++              return conf->checker_timeout * 1000;
++      return default_timeout;
++}
++
+ int init_prio (void)
+ {
+       if (!add_prio(DEFAULT_PRIO))
+Index: multipath-tools-130222/libmultipath/prio.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prio.h
++++ multipath-tools-130222/libmultipath/prio.h
+@@ -51,6 +51,7 @@ struct prio {
+       int (*getprio)(struct path *, char *);
+ };
++unsigned int get_prio_timeout(unsigned int default_timeout);
+ int init_prio (void);
+ void cleanup_prio (void);
+ struct prio * add_prio (char *);
+Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.c
++++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c
+@@ -21,6 +21,7 @@
+ #define __user
+ #include <scsi/sg.h>
++#include "../prio.h"
+ #include "alua_rtpg.h"
+ #define SENSE_BUFF_LEN  32
+@@ -134,7 +135,7 @@ do_inquiry(int fd, int evpd, unsigned in
+       hdr.dxfer_len           = resplen;
+       hdr.sbp                 = sense;
+       hdr.mx_sb_len           = sizeof(sense);
+-      hdr.timeout             = DEF_TIMEOUT;
++      hdr.timeout             = get_prio_timeout(DEF_TIMEOUT);
+       if (ioctl(fd, SG_IO, &hdr) < 0) {
+               PRINT_DEBUG("do_inquiry: IOCTL failed!\n");
+@@ -253,7 +254,7 @@ do_rtpg(int fd, void* resp, long resplen
+       hdr.dxfer_len           = resplen;
+       hdr.mx_sb_len           = sizeof(sense);
+       hdr.sbp                 = sense;
+-      hdr.timeout             = DEF_TIMEOUT;
++      hdr.timeout             = get_prio_timeout(DEF_TIMEOUT);
+       if (ioctl(fd, SG_IO, &hdr) < 0)
+               return -RTPG_RTPG_FAILED;
+Index: multipath-tools-130222/libmultipath/prioritizers/emc.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/emc.c
++++ multipath-tools-130222/libmultipath/prioritizers/emc.c
+@@ -31,7 +31,7 @@ int emc_clariion_prio(const char *dev, i
+       io_hdr.dxferp = sense_buffer;
+       io_hdr.cmdp = inqCmdBlk;
+       io_hdr.sbp = sb;
+-      io_hdr.timeout = 60000;
++      io_hdr.timeout = get_prio_timeout(60000);
+       io_hdr.pack_id = 0;
+       if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+               pp_emc_log(0, "sending query command failed");
+Index: multipath-tools-130222/libmultipath/prioritizers/hds.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/hds.c
++++ multipath-tools-130222/libmultipath/prioritizers/hds.c
+@@ -114,7 +114,7 @@ int hds_modular_prio (const char *dev, i
+       io_hdr.dxferp = inqBuff;
+       io_hdr.cmdp = inqCmdBlk;
+       io_hdr.sbp = sense_buffer;
+-      io_hdr.timeout = 2000;  /* TimeOut = 2 seconds */
++      io_hdr.timeout = get_prio_timeout(2000); /* TimeOut = 2 seconds */
+       if (ioctl (fd, SG_IO, &io_hdr) < 0) {
+               pp_hds_log(0, "SG_IO error");
+Index: multipath-tools-130222/libmultipath/prioritizers/hp_sw.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/hp_sw.c
++++ multipath-tools-130222/libmultipath/prioritizers/hp_sw.c
+@@ -46,7 +46,7 @@ int hp_sw_prio(const char *dev, int fd)
+       io_hdr.dxfer_direction = SG_DXFER_NONE;
+       io_hdr.cmdp = turCmdBlk;
+       io_hdr.sbp = sb;
+-      io_hdr.timeout = 60000;
++      io_hdr.timeout = get_prio_timeout(60000);
+       io_hdr.pack_id = 0;
+  retry:
+       if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+Index: multipath-tools-130222/libmultipath/prioritizers/ontap.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/ontap.c
++++ multipath-tools-130222/libmultipath/prioritizers/ontap.c
+@@ -89,7 +89,7 @@ static int send_gva(const char *dev, int
+       io_hdr.dxferp = results;
+       io_hdr.cmdp = cdb;
+       io_hdr.sbp = sb;
+-      io_hdr.timeout = SG_TIMEOUT;
++      io_hdr.timeout = get_prio_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);
+@@ -141,7 +141,7 @@ static int get_proxy(const char *dev, in
+       io_hdr.dxferp = results;
+       io_hdr.cmdp = cdb;
+       io_hdr.sbp = sb;
+-      io_hdr.timeout = SG_TIMEOUT;
++      io_hdr.timeout = get_prio_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, "
+Index: multipath-tools-130222/libmultipath/prioritizers/rdac.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/rdac.c
++++ multipath-tools-130222/libmultipath/prioritizers/rdac.c
+@@ -31,7 +31,7 @@ int rdac_prio(const char *dev, int fd)
+       io_hdr.dxferp = sense_buffer;
+       io_hdr.cmdp = inqCmdBlk;
+       io_hdr.sbp = sb;
+-      io_hdr.timeout = 60000;
++      io_hdr.timeout = get_prio_timeout(60000);
+       io_hdr.pack_id = 0;
+       if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+               pp_rdac_log(0, "sending inquiry command failed");
+Index: multipath-tools-130222/multipath.conf.annotated
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.annotated
++++ multipath-tools-130222/multipath.conf.annotated
+@@ -188,8 +188,9 @@
+ #     #
+ #     # name    : checker_timeout
+ #     # scope   : multipath & multipathd
+-#     # desc    : The timeout to use for path checkers that issue scsi
+-#     #           commands with an explicit timeout, in seconds.
++#     # desc    : The timeout to use for path checkers and prioritizers
++#     #           that issue scsi commands with an explicit timeout, in
++#     #           seconds.
+ #     # values  : n > 0
+ #     # default : taken from /sys/block/sd<x>/device/timeout
+ #     checker_timeout 60
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -321,8 +321,8 @@ maximum number of open fds is taken from
+ if that number is greated than 1024.
+ .TP
+ .B checker_timeout
+-Specify the timeout to user for path checkers that issue scsi commands with an
+-explicit timeout, in seconds; default taken from
++Specify the timeout to use for path checkers and prioritizers that issue scsi
++commands with an explicit timeout, in seconds; default taken from
+ .I /sys/block/sd<x>/device/timeout
+ .TP
+ .B fast_io_fail_tmo
diff --git a/multipath-tools/patches/0089-RHBZ-1110016-add-noasync-option.patch b/multipath-tools/patches/0089-RHBZ-1110016-add-noasync-option.patch
new file mode 100644 (file)
index 0000000..2651c0e
--- /dev/null
@@ -0,0 +1,158 @@
+---
+ libmultipath/config.c      |    1 +
+ libmultipath/config.h      |    1 +
+ libmultipath/dict.c        |   33 +++++++++++++++++++++++++++++++++
+ libmultipath/discovery.c   |    8 ++++++--
+ multipath.conf.annotated   |   10 ++++++++++
+ multipath/multipath.conf.5 |    9 +++++++++
+ 6 files changed, 60 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -556,6 +556,7 @@ load_config (char * file, struct udev *u
+       conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
+       conf->detect_prio = DEFAULT_DETECT_PRIO;
+       conf->hw_strmatch = 0;
++      conf->force_sync = 0;
+       /*
+        * preload default hwtable
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -115,6 +115,7 @@ struct config {
+       int reassign_maps;
+       int retain_hwhandler;
+       int detect_prio;
++      int force_sync;
+       unsigned int version[3];
+       char * dev;
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -712,6 +712,29 @@ def_hw_strmatch_handler(vector strvec)
+       return 0;
+ }
++static int
++def_force_sync_handler(vector strvec)
++{
++      char * buff;
++
++      buff = set_value(strvec);
++
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              conf->force_sync = 0;
++      else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
++               (strlen(buff) == 1 && !strcmp(buff, "1")))
++              conf->force_sync = 1;
++      else
++              conf->force_sync = 0;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * blacklist block handlers
+  */
+@@ -2822,6 +2845,15 @@ snprint_def_hw_strmatch(char * buff, int
+ }
+ static int
++snprint_def_force_sync(char * buff, int len, void * data)
++{
++      if (conf->force_sync)
++              return snprintf(buff, len, "yes");
++      else
++              return snprintf(buff, len, "no");
++}
++
++static int
+ snprint_ble_simple (char * buff, int len, void * data)
+ {
+       struct blentry * ble = (struct blentry *)data;
+@@ -2889,6 +2921,7 @@ init_keywords(void)
+       install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
+       install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
+       install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
++      install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
+       __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -952,8 +952,12 @@ get_state (struct path * pp, int daemon)
+               }
+       }
+       checker_clear_message(c);
+-      if (daemon)
+-              checker_set_async(c);
++      if (daemon) {
++              if (conf->force_sync == 0)
++                      checker_set_async(c);
++              else
++                      checker_set_sync(c);
++      }
+       if (!conf->checker_timeout &&
+           (pp->bus != SYSFS_BUS_SCSI ||
+            sysfs_get_timeout(pp, &(c->timeout))))
+Index: multipath-tools-130222/multipath.conf.annotated
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.annotated
++++ multipath-tools-130222/multipath.conf.annotated
+@@ -214,6 +214,8 @@
+ #     # values  : n > 0
+ #     # default : determined by the OS
+ #     dev_loss_tmo 600
++#
++#     #
+ #     # name    : bindings_file
+ #     # scope   : multipath
+ #     # desc    : The location of the bindings file that is used with
+@@ -222,6 +224,14 @@
+ #     # default : "/var/lib/multipath/bindings"
+ #     bindings_file "/etc/multipath_bindings"
+ #
++#     #
++#     # name    : force_sync
++#     # scope   : multipathd
++#     # desc    : If set to yes, multipath will run all of the checkers in
++#     #           sync mode, even if the checker has an async mode.
++#     # values  : yes|no
++#     # default : no
++#     force_sync yes
+ #}
+ #     
+ ##
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -411,6 +411,15 @@ modify an existing config, or create a n
+ , the user device configs will be regular expression matched against the
+ built-in configs instead. Default is
+ .I no
++.TP
++.B force_sync
++If set to
++.I yes
++, multipathd will call the path checkers in sync mode only.  This means that
++only one checker will run at a time.  This is useful in the case where many
++multipathd checkers running in parallel causes significant CPU pressure. The
++Default is
++.I no
+ .
+ .SH "blacklist section"
+ The
diff --git a/multipath-tools/patches/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch b/multipath-tools/patches/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch
new file mode 100644 (file)
index 0000000..44f8407
--- /dev/null
@@ -0,0 +1,529 @@
+---
+ libmultipath/configure.c |  229 +++++++++++++++++++++++++++++++++++++++++++++++
+ libmultipath/configure.h |    2 
+ libmultipath/discovery.c |   87 +++++++++++++++++
+ libmultipath/discovery.h |    2 
+ libmultipath/structs.c   |   84 +++++++++++++++++
+ libmultipath/structs.h   |   25 ++++-
+ 6 files changed, 427 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -39,6 +39,219 @@
+ #include "uxsock.h"
+ #include "wwids.h"
++/* group paths in pg by host adapter
++ */
++int group_by_host_adapter(struct pathgroup *pgp, vector adapters)
++{
++      struct adapter_group *agp;
++      struct host_group *hgp;
++      struct path *pp, *pp1;
++      char adapter_name1[SLOT_NAME_SIZE];
++      char adapter_name2[SLOT_NAME_SIZE];
++      int i, j;
++      int found_hostgroup = 0;
++
++      while (VECTOR_SIZE(pgp->paths) > 0) {
++
++              pp = VECTOR_SLOT(pgp->paths, 0);
++
++              if (sysfs_get_host_adapter_name(pp, adapter_name1))
++                      goto out;
++              /* create a new host adapter group
++               */
++              agp = alloc_adaptergroup();
++              if (!agp)
++                      goto out;
++              agp->pgp = pgp;
++
++              strncpy(agp->adapter_name, adapter_name1, SLOT_NAME_SIZE);
++              store_adaptergroup(adapters, agp);
++
++              /* create a new host port group
++               */
++              hgp = alloc_hostgroup();
++              if (!hgp)
++                      goto out;
++              if (store_hostgroup(agp->host_groups, hgp))
++                      goto out;
++
++              hgp->host_no = pp->sg_id.host_no;
++              agp->num_hosts++;
++              if (store_path(hgp->paths, pp))
++                      goto out;
++
++              hgp->num_paths++;
++              /* delete path from path group
++               */
++              vector_del_slot(pgp->paths, 0);
++
++              /* add all paths belonging to same host adapter
++               */
++              vector_foreach_slot(pgp->paths, pp1, i) {
++                      if (sysfs_get_host_adapter_name(pp1, adapter_name2))
++                              goto out;
++                      if (strcmp(adapter_name1, adapter_name2) == 0) {
++                              found_hostgroup = 0;
++                              vector_foreach_slot(agp->host_groups, hgp, j) {
++                                      if (hgp->host_no == pp1->sg_id.host_no) {
++                                              if (store_path(hgp->paths, pp1))
++                                                      goto out;
++                                              hgp->num_paths++;
++                                              found_hostgroup = 1;
++                                              break;
++                                      }
++                              }
++                              if (!found_hostgroup) {
++                                      /* this path belongs to new host port
++                                       * within this adapter
++                                       */
++                                      hgp = alloc_hostgroup();
++                                      if (!hgp)
++                                              goto out;
++
++                                      if (store_hostgroup(agp->host_groups, hgp))
++                                              goto out;
++
++                                      agp->num_hosts++;
++                                      if (store_path(hgp->paths, pp1))
++                                              goto out;
++
++                                      hgp->host_no = pp1->sg_id.host_no;
++                                      hgp->num_paths++;
++                              }
++                              /* delete paths from original path_group
++                               * as they are added into adapter group now
++                               */
++                              vector_del_slot(pgp->paths, i);
++                              i--;
++                      }
++              }
++      }
++      return 0;
++
++out:  /* add back paths into pg as re-ordering failed
++       */
++      vector_foreach_slot(adapters, agp, i) {
++                      vector_foreach_slot(agp->host_groups, hgp, j) {
++                              while (VECTOR_SIZE(hgp->paths) > 0) {
++                                      pp = VECTOR_SLOT(hgp->paths, 0);
++                                      if (store_path(pgp->paths, pp))
++                                              condlog(3, "failed to restore "
++                                              "path %s into path group",
++                                               pp->dev);
++                                      vector_del_slot(hgp->paths, 0);
++                              }
++                      }
++              }
++      free_adaptergroup(adapters);
++      return 1;
++}
++
++/* re-order paths in pg by alternating adapters and host ports
++ * for optimized selection
++ */
++int order_paths_in_pg_by_alt_adapters(struct pathgroup *pgp, vector adapters,
++               int total_paths)
++{
++      int next_adapter_index = 0;
++      struct adapter_group *agp;
++      struct host_group *hgp;
++      struct path *pp;
++
++      while (total_paths > 0) {
++              agp = VECTOR_SLOT(adapters, next_adapter_index);
++              if (!agp) {
++                      condlog(0, "can't get adapter group %d", next_adapter_index);
++                      return 1;
++              }
++
++              hgp = VECTOR_SLOT(agp->host_groups, agp->next_host_index);
++              if (!hgp) {
++                      condlog(0, "can't get host group %d of adapter group %d", next_adapter_index, agp->next_host_index);
++                      return 1;
++              }
++
++              if (!hgp->num_paths) {
++                      agp->next_host_index++;
++                      agp->next_host_index %= agp->num_hosts;
++                      next_adapter_index++;
++                      next_adapter_index %= VECTOR_SIZE(adapters);
++                      continue;
++              }
++
++              pp  = VECTOR_SLOT(hgp->paths, 0);
++
++              if (store_path(pgp->paths, pp))
++                      return 1;
++
++              total_paths--;
++
++              vector_del_slot(hgp->paths, 0);
++
++              hgp->num_paths--;
++
++              agp->next_host_index++;
++              agp->next_host_index %= agp->num_hosts;
++              next_adapter_index++;
++              next_adapter_index %= VECTOR_SIZE(adapters);
++      }
++
++      /* all paths are added into path_group
++       * in crafted child order
++       */
++      return 0;
++}
++
++/* round-robin: order paths in path group to alternate
++ * between all host adapters
++ */
++int rr_optimize_path_order(struct pathgroup *pgp)
++{
++      vector adapters;
++      struct path *pp;
++      int total_paths;
++      int i;
++
++      total_paths = VECTOR_SIZE(pgp->paths);
++      vector_foreach_slot(pgp->paths, pp, i) {
++              if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP &&
++                      pp->sg_id.proto_id != SCSI_PROTOCOL_SAS &&
++                      pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI &&
++                      pp->sg_id.proto_id != SCSI_PROTOCOL_SRP) {
++                      /* return success as default path order
++                       * is maintained in path group
++                       */
++                      return 0;
++              }
++      }
++      adapters = vector_alloc();
++      if (!adapters)
++              return 0;
++
++      /* group paths in path group by host adapters
++       */
++      if (group_by_host_adapter(pgp, adapters)) {
++              /* already freed adapters */
++              condlog(3, "Failed to group paths by adapters");
++              return 0;
++      }
++
++      /* re-order paths in pg to alternate between adapters and host ports
++       */
++      if (order_paths_in_pg_by_alt_adapters(pgp, adapters, total_paths)) {
++              condlog(3, "Failed to re-order paths in pg by adapters "
++                      "and host ports");
++              free_adaptergroup(adapters);
++              /* return failure as original paths are
++               * removed form pgp
++               */
++              return 1;
++      }
++
++      free_adaptergroup(adapters);
++      return 0;
++}
++
+ extern int
+ setup_map (struct multipath * mpp, char * params, int params_size)
+ {
+@@ -101,6 +314,22 @@ setup_map (struct multipath * mpp, char
+        */
+       mpp->bestpg = select_path_group(mpp);
++      /* re-order paths in all path groups in an optimized way
++       * for round-robin path selectors to get maximum throughput.
++       */
++      if (!strncmp(mpp->selector, "round-robin", 11)) {
++              vector_foreach_slot(mpp->pg, pgp, i) {
++                      if (VECTOR_SIZE(pgp->paths) <= 2)
++                              continue;
++                      if (rr_optimize_path_order(pgp)) {
++                              condlog(2, "cannot re-order paths for "
++                                      "optimization: %s",
++                                      mpp->alias);
++                              return 1;
++                      }
++              }
++      }
++
+       /*
+        * transform the mp->pg vector of vectors of paths
+        * into a mp->params strings to feed the device-mapper
+Index: multipath-tools-130222/libmultipath/configure.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.h
++++ multipath-tools-130222/libmultipath/configure.h
+@@ -29,4 +29,4 @@ int reinstate_paths (struct multipath *m
+ int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload);
+ int get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid);
+ int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh);
+-
++int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name);
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -310,6 +310,93 @@ sysfs_get_tgt_nodename (struct path *pp,
+       return 1;
+ }
++int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name)
++{
++      int proto_id;
++
++      if (!pp || !adapter_name)
++              return 1;
++
++      proto_id = pp->sg_id.proto_id;
++
++      if (proto_id != SCSI_PROTOCOL_FCP &&
++          proto_id != SCSI_PROTOCOL_SAS &&
++          proto_id != SCSI_PROTOCOL_ISCSI &&
++          proto_id != SCSI_PROTOCOL_SRP) {
++              return 1;
++      }
++      /* iscsi doesn't have adapter info in sysfs
++       * get ip_address for grouping paths
++       */
++      if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
++              return sysfs_get_iscsi_ip_address(pp, adapter_name);
++
++      /* fetch adapter pci name for other protocols
++       */
++      return sysfs_get_host_pci_name(pp, adapter_name);
++}
++
++int sysfs_get_host_pci_name(struct path *pp, char *pci_name)
++{
++      struct udev_device *hostdev, *parent;
++      char host_name[HOST_NAME_LEN];
++      const char *driver_name, *value;
++
++      if (!pp || !pci_name)
++              return 1;
++
++      sprintf(host_name, "host%d", pp->sg_id.host_no);
++      hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
++                      "scsi_host", host_name);
++      if (!hostdev)
++              return 1;
++
++      parent = udev_device_get_parent(hostdev);
++      while (parent) {
++              driver_name = udev_device_get_driver(parent);
++              if (!driver_name) {
++                      parent = udev_device_get_parent(parent);
++                      continue;
++              }
++              if (!strcmp(driver_name, "pcieport"))
++                      break;
++              parent = udev_device_get_parent(parent);
++      }
++      if (parent) {
++              /* pci_device found
++               */
++              value = udev_device_get_sysname(parent);
++
++              strncpy(pci_name, value, SLOT_NAME_SIZE);
++              udev_device_unref(hostdev);
++              return 0;
++      }
++      udev_device_unref(hostdev);
++      return 1;
++}
++
++int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address)
++{
++      struct udev_device *hostdev;
++      char host_name[HOST_NAME_LEN];
++      const char *value;
++
++      sprintf(host_name, "host%d", pp->sg_id.host_no);
++      hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
++                      "iscsi_host", host_name);
++      if (hostdev) {
++              value = udev_device_get_sysattr_value(hostdev,
++                              "ipaddress");
++              if (value) {
++                      strncpy(ip_address, value, SLOT_NAME_SIZE);
++                      udev_device_unref(hostdev);
++                      return 0;
++              } else
++                      udev_device_unref(hostdev);
++      }
++      return 1;
++}
++
+ static void
+ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
+ {
+Index: multipath-tools-130222/libmultipath/discovery.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.h
++++ multipath-tools-130222/libmultipath/discovery.h
+@@ -38,6 +38,8 @@ int store_pathinfo (vector pathvec, vect
+                   struct path **pp_ptr);
+ int sysfs_set_scsi_tmo (struct multipath *mpp);
+ int sysfs_get_timeout(struct path *pp, unsigned int *timeout);
++int sysfs_get_host_pci_name(struct path *pp, char *pci_name);
++int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address);
+ /*
+  * discovery bitmask
+Index: multipath-tools-130222/libmultipath/structs.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.c
++++ multipath-tools-130222/libmultipath/structs.c
+@@ -18,6 +18,70 @@
+ #include "blacklist.h"
+ #include "prio.h"
++struct adapter_group *
++alloc_adaptergroup(void)
++{
++      struct adapter_group *agp;
++
++      agp = (struct adapter_group *)MALLOC(sizeof(struct adapter_group));
++
++      if (!agp)
++              return NULL;
++
++      agp->host_groups = vector_alloc();
++      if (!agp->host_groups) {
++              FREE(agp);
++              agp = NULL;
++      }
++      return agp;
++}
++
++void free_adaptergroup(vector adapters)
++{
++      int i;
++      struct adapter_group *agp;
++
++      vector_foreach_slot(adapters, agp, i) {
++              free_hostgroup(agp->host_groups);
++              FREE(agp);
++      }
++      vector_free(adapters);
++}
++
++void free_hostgroup(vector hostgroups)
++{
++      int i;
++      struct host_group *hgp;
++
++      if (!hostgroups)
++              return;
++
++      vector_foreach_slot(hostgroups, hgp, i) {
++              vector_free(hgp->paths);
++              FREE(hgp);
++      }
++      vector_free(hostgroups);
++}
++
++struct host_group *
++alloc_hostgroup(void)
++{
++      struct host_group *hgp;
++
++      hgp = (struct host_group *)MALLOC(sizeof(struct host_group));
++
++      if (!hgp)
++              return NULL;
++
++      hgp->paths = vector_alloc();
++
++      if (!hgp->paths) {
++              FREE(hgp);
++              hgp = NULL;
++      }
++      return hgp;
++}
++
+ struct path *
+ alloc_path (void)
+ {
+@@ -242,6 +306,26 @@ store_pathgroup (vector pgvec, struct pa
+       return 0;
+ }
++int
++store_hostgroup(vector hostgroupvec, struct host_group * hgp)
++{
++      if (!vector_alloc_slot(hostgroupvec))
++              return 1;
++
++      vector_set_slot(hostgroupvec, hgp);
++      return 0;
++}
++
++int
++store_adaptergroup(vector adapters, struct adapter_group * agp)
++{
++      if (!vector_alloc_slot(adapters))
++              return 1;
++
++      vector_set_slot(adapters, agp);
++      return 0;
++}
++
+ struct multipath *
+ find_mp_by_minor (vector mpvec, int minor)
+ {
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -15,7 +15,8 @@
+ #define BLK_DEV_SIZE          33
+ #define PATH_SIZE             512
+ #define NAME_SIZE             512
+-
++#define HOST_NAME_LEN         8
++#define SLOT_NAME_SIZE                40
+ #define SCSI_VENDOR_SIZE      9
+ #define SCSI_PRODUCT_SIZE     17
+@@ -251,6 +252,20 @@ struct pathgroup {
+       char * selector;
+ };
++struct adapter_group {
++      char adapter_name[SLOT_NAME_SIZE];
++      struct pathgroup *pgp;
++      int num_hosts;
++      vector host_groups;
++      int next_host_index;
++};
++
++struct host_group {
++      int host_no;
++      int num_paths;
++      vector paths;
++};
++
+ struct path * alloc_path (void);
+ struct pathgroup * alloc_pathgroup (void);
+ struct multipath * alloc_multipath (void);
+@@ -263,6 +278,14 @@ void free_multipath_attributes (struct m
+ void drop_multipath (vector mpvec, char * wwid, enum free_path_mode free_paths);
+ void free_multipathvec (vector mpvec, enum free_path_mode free_paths);
++struct adapter_group * alloc_adaptergroup(void);
++struct host_group * alloc_hostgroup(void);
++void free_adaptergroup(vector adapters);
++void free_hostgroup(vector hostgroups);
++
++int store_adaptergroup(vector adapters, struct adapter_group *agp);
++int store_hostgroup(vector hostgroupvec, struct host_group *hgp);
++
+ int store_path (vector pathvec, struct path * pp);
+ int store_pathgroup (vector pgvec, struct pathgroup * pgp);
diff --git a/multipath-tools/patches/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch b/multipath-tools/patches/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch
new file mode 100644 (file)
index 0000000..d164de1
--- /dev/null
@@ -0,0 +1,38 @@
+---
+ libmultipath/dict.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -43,6 +43,9 @@ def_fast_io_fail_handler(vector strvec)
+       char * buff;
+       buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
+       if (strlen(buff) == 3 && !strcmp(buff, "off"))
+               conf->fast_io_fail = MP_FAST_IO_FAIL_OFF;
+       else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 ||
+@@ -1002,6 +1005,9 @@ hw_dev_loss_handler(vector strvec)
+       char * buff;
+       struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
++        if (!hwe)
++                return 1;
++
+       buff = set_value(strvec);
+       if (!buff)
+               return 1;
+@@ -1021,6 +1027,9 @@ hw_pgpolicy_handler(vector strvec)
+       char * buff;
+       struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
++        if (!hwe)
++                return 1;
++
+       buff = set_value(strvec);
+       if (!buff)
diff --git a/multipath-tools/patches/0092-UPBZ-1104605-reload-on-rename.patch b/multipath-tools/patches/0092-UPBZ-1104605-reload-on-rename.patch
new file mode 100644 (file)
index 0000000..465257c
--- /dev/null
@@ -0,0 +1,63 @@
+---
+ libmultipath/configure.c |   11 +++++++++++
+ libmultipath/configure.h |    1 +
+ libmultipath/devmapper.c |    3 +--
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -394,6 +394,8 @@ select_action (struct multipath * mpp, v
+                               cmpp->alias, mpp->alias);
+                       strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE);
+                       mpp->action = ACT_RENAME;
++                      if (force_reload)
++                              mpp->action = ACT_RENAME2;
+                       return;
+               }
+               mpp->action = ACT_CREATE;
+@@ -632,6 +634,15 @@ domap (struct multipath * mpp, char * pa
+               r = dm_rename(mpp->alias_old, mpp->alias);
+               break;
++      case ACT_RENAME2:
++              r = dm_rename(mpp->alias_old, mpp->alias);
++              if (r) {
++                      r = dm_addmap_reload(mpp, params);
++                      if (r)
++                              r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG);
++              }
++              break;
++
+       default:
+               break;
+       }
+Index: multipath-tools-130222/libmultipath/configure.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.h
++++ multipath-tools-130222/libmultipath/configure.h
+@@ -18,6 +18,7 @@ enum actions {
+       ACT_RENAME,
+       ACT_CREATE,
+       ACT_RESIZE,
++      ACT_RENAME2,
+ };
+ #define FLUSH_ONE 1
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -565,10 +565,9 @@ dm_dev_t (const char * mapname, char * d
+       if (!dm_task_run(dmt))
+               goto out;
+-      if (!dm_task_get_info(dmt, &info))
++      if (!dm_task_get_info(dmt, &info) || !info.exists)
+               goto out;
+-      r = info.open_count;
+       if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len)
+                   goto out;
diff --git a/multipath-tools/patches/0093-UPBZ-1086825-user-friendly-name-remap.patch b/multipath-tools/patches/0093-UPBZ-1086825-user-friendly-name-remap.patch
new file mode 100644 (file)
index 0000000..ab5abbd
--- /dev/null
@@ -0,0 +1,199 @@
+---
+ libmultipath/alias.c       |   64 ++++++++++++++++++++++++++++++++++++++++++---
+ libmultipath/alias.h       |    2 +
+ libmultipath/propsel.c     |   32 +++++++++++++++-------
+ libmultipath/structs_vec.c |   15 ++++++++++
+ 4 files changed, 100 insertions(+), 13 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/alias.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.c
++++ multipath-tools-130222/libmultipath/alias.c
+@@ -145,7 +145,7 @@ lookup_binding(FILE *f, char *map_wwid,
+ }
+ static int
+-rlookup_binding(FILE *f, char *buff, char *map_alias)
++rlookup_binding(FILE *f, char *buff, char *map_alias, char *prefix)
+ {
+       char line[LINE_MAX];
+       unsigned int line_nr = 0;
+@@ -164,7 +164,7 @@ rlookup_binding(FILE *f, char *buff, cha
+               alias = strtok(line, " \t");
+               if (!alias) /* blank line */
+                       continue;
+-              curr_id = scan_devname(alias, NULL); /* TBD: Why this call? */
++              curr_id = scan_devname(alias, prefix);
+               if (curr_id >= id)
+                       id = curr_id + 1;
+               wwid = strtok(NULL, " \t");
+@@ -188,6 +188,11 @@ rlookup_binding(FILE *f, char *buff, cha
+               }
+       }
+       condlog(3, "No matching alias [%s] in bindings file.", map_alias);
++
++      /* Get the theoretical id for this map alias.
++       * Used by use_existing_alias
++       */
++      id = scan_devname(map_alias, prefix);
+       return id;
+ }
+@@ -237,6 +242,59 @@ allocate_binding(int fd, char *wwid, int
+ }
+ char *
++use_existing_alias (char *wwid, char *file, char *alias_old,
++              char *prefix, int bindings_read_only)
++{
++      char *alias = NULL;
++      int id = 0;
++      int fd, can_write;
++      char buff[WWID_SIZE];
++      FILE *f;
++
++      fd = open_file(file, &can_write, BINDINGS_FILE_HEADER);
++      if (fd < 0)
++              return NULL;
++
++      f = fdopen(fd, "r");
++      if (!f) {
++              condlog(0, "cannot fdopen on bindings file descriptor");
++              close(fd);
++              return NULL;
++      }
++      /* lookup the binding. if it exsists, the wwid will be in buff
++       * either way, id contains the id for the alias
++       */
++      id = rlookup_binding(f , buff,  alias_old, prefix);
++      if (id < 0)
++              goto out;
++
++      if (strlen(buff) > 0) {
++              /* if buff is our wwid, it's already
++               * allocated correctly
++               */
++              if (strcmp(buff, wwid) == 0)
++                      alias = STRDUP(alias_old);
++              else {
++                      alias = NULL;
++                      condlog(0, "alias %s already bound to wwid %s, cannot reuse",
++                              alias_old, buff);
++              }
++              goto out;       
++      }
++
++      /* allocate the existing alias in the bindings file */
++      if (can_write && id && !bindings_read_only) {
++              alias = allocate_binding(fd, wwid, id, prefix);
++              condlog(0, "Allocated existing binding [%s] for WWID [%s]",
++                      alias, wwid);
++      }
++
++out:
++      fclose(f);
++      return alias;
++}
++
++char *
+ get_user_friendly_alias(char *wwid, char *file, char *prefix,
+                       int bindings_read_only)
+ {
+@@ -305,7 +363,7 @@ get_user_friendly_wwid(char *alias, char
+               return -1;
+       }
+-      rlookup_binding(f, buff, alias);
++      rlookup_binding(f, buff, alias, NULL);
+       if (!strlen(buff)) {
+               fclose(f);
+               return -1;
+Index: multipath-tools-130222/libmultipath/alias.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.h
++++ multipath-tools-130222/libmultipath/alias.h
+@@ -10,3 +10,5 @@
+ char *get_user_friendly_alias(char *wwid, char *file, char *prefix,
+                             int bindings_readonly);
+ int get_user_friendly_wwid(char *alias, char *buff, char *file);
++char *use_existing_alias (char *wwid, char *file, char *alias_old,
++              char *prefix, int bindings_read_only);
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -253,19 +253,31 @@ want_user_friendly_names(struct multipat
+ extern int
+ select_alias (struct multipath * mp)
+ {
+-      if (mp->mpe && mp->mpe->alias)
++      if (mp->mpe && mp->mpe->alias) {
+               mp->alias = STRDUP(mp->mpe->alias);
+-      else {
+-              mp->alias = NULL;
+-              if (want_user_friendly_names(mp)) {
+-                      select_alias_prefix(mp);
+-                      mp->alias = get_user_friendly_alias(mp->wwid,
+-                                      conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
+-              }
+-              if (mp->alias == NULL)
+-                      mp->alias = STRDUP(mp->wwid);
++              goto out;
+       }
++      mp->alias = NULL;
++      if (!want_user_friendly_names(mp))
++              goto out;
++
++      select_alias_prefix(mp);
++      
++      if (strlen(mp->alias_old) > 0) {
++              mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
++                              mp->alias_old, mp->alias_prefix,
++                              conf->bindings_read_only);
++              memset (mp->alias_old, 0, WWID_SIZE);
++      } 
++
++      if (mp->alias == NULL)
++              mp->alias = get_user_friendly_alias(mp->wwid,
++                              conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
++out:
++      if (mp->alias == NULL)
++              mp->alias = STRDUP(mp->wwid);
++
+       return mp->alias ? 0 : 1;
+ }
+Index: multipath-tools-130222/libmultipath/structs_vec.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs_vec.c
++++ multipath-tools-130222/libmultipath/structs_vec.c
+@@ -430,6 +430,20 @@ out:
+       return NULL;
+ }
++static void
++find_existing_alias (struct multipath * mpp,
++                   struct vectors *vecs)
++{
++      struct multipath * mp;
++      int i;
++
++      vector_foreach_slot (vecs->mpvec, mp, i)
++              if (strcmp(mp->wwid, mpp->wwid) == 0) {
++                      strncpy(mpp->alias_old, mp->alias, WWID_SIZE);
++                      return;
++              }
++}
++
+ extern struct multipath *
+ add_map_with_path (struct vectors * vecs,
+                  struct path * pp, int add_vec)
+@@ -443,6 +457,7 @@ add_map_with_path (struct vectors * vecs
+       mpp->hwe = pp->hwe;
+       strcpy(mpp->wwid, pp->wwid);
++      find_existing_alias(mpp, vecs);
+       if (select_alias(mpp))
+               goto out;
+       mpp->size = pp->size;
diff --git a/multipath-tools/patches/0094-RHBZ-1086825-cleanup-remap.patch b/multipath-tools/patches/0094-RHBZ-1086825-cleanup-remap.patch
new file mode 100644 (file)
index 0000000..7d85c2d
--- /dev/null
@@ -0,0 +1,107 @@
+---
+ libmultipath/alias.c   |   31 +++++++++++++++----------------
+ libmultipath/propsel.c |    4 ++--
+ 2 files changed, 17 insertions(+), 18 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/alias.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.c
++++ multipath-tools-130222/libmultipath/alias.c
+@@ -149,13 +149,11 @@ rlookup_binding(FILE *f, char *buff, cha
+ {
+       char line[LINE_MAX];
+       unsigned int line_nr = 0;
+-      int id = 0;
+       buff[0] = '\0';
+       while (fgets(line, LINE_MAX, f)) {
+               char *c, *alias, *wwid;
+-              int curr_id;
+               line_nr++;
+               c = strpbrk(line, "#\n\r");
+@@ -164,9 +162,6 @@ rlookup_binding(FILE *f, char *buff, cha
+               alias = strtok(line, " \t");
+               if (!alias) /* blank line */
+                       continue;
+-              curr_id = scan_devname(alias, prefix);
+-              if (curr_id >= id)
+-                      id = curr_id + 1;
+               wwid = strtok(NULL, " \t");
+               if (!wwid){
+                       condlog(3,
+@@ -184,16 +179,12 @@ rlookup_binding(FILE *f, char *buff, cha
+                               "\nSetting wwid to %s", alias, wwid);
+                       strncpy(buff, wwid, WWID_SIZE);
+                       buff[WWID_SIZE - 1] = '\0';
+-                      return id;
++                      return 0;
+               }
+       }
+       condlog(3, "No matching alias [%s] in bindings file.", map_alias);
+-      /* Get the theoretical id for this map alias.
+-       * Used by use_existing_alias
+-       */
+-      id = scan_devname(map_alias, prefix);
+-      return id;
++      return -1;
+ }
+ static char *
+@@ -264,9 +255,7 @@ use_existing_alias (char *wwid, char *fi
+       /* lookup the binding. if it exsists, the wwid will be in buff
+        * either way, id contains the id for the alias
+        */
+-      id = rlookup_binding(f , buff,  alias_old, prefix);
+-      if (id < 0)
+-              goto out;
++      rlookup_binding(f, buff, alias_old, prefix);
+       if (strlen(buff) > 0) {
+               /* if buff is our wwid, it's already
+@@ -279,11 +268,21 @@ use_existing_alias (char *wwid, char *fi
+                       condlog(0, "alias %s already bound to wwid %s, cannot reuse",
+                               alias_old, buff);
+               }
+-              goto out;       
++              goto out;
+       }
+       /* allocate the existing alias in the bindings file */
+-      if (can_write && id && !bindings_read_only) {
++      id = scan_devname(alias_old, prefix);
++      if (id <= 0)
++              goto out;
++
++      if (fflush(f) != 0) {
++              condlog(0, "cannot fflush bindings file stream : %s",
++                      strerror(errno));
++              goto out;
++      }
++
++      if (can_write && !bindings_read_only) {
+               alias = allocate_binding(fd, wwid, id, prefix);
+               condlog(0, "Allocated existing binding [%s] for WWID [%s]",
+                       alias, wwid);
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -263,13 +263,13 @@ select_alias (struct multipath * mp)
+               goto out;
+       select_alias_prefix(mp);
+-      
++
+       if (strlen(mp->alias_old) > 0) {
+               mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
+                               mp->alias_old, mp->alias_prefix,
+                               conf->bindings_read_only);
+               memset (mp->alias_old, 0, WWID_SIZE);
+-      } 
++      }
+       if (mp->alias == NULL)
+               mp->alias = get_user_friendly_alias(mp->wwid,
diff --git a/multipath-tools/patches/0095-RHBZ-1127944-xtremIO-config.patch b/multipath-tools/patches/0095-RHBZ-1127944-xtremIO-config.patch
new file mode 100644 (file)
index 0000000..6807cbc
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ libmultipath/hwtable.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -1121,6 +1121,19 @@ static struct hwentry default_hw[] = {
+               .prio_name     = PRIO_ALUA,
+               .prio_args     = NULL,
+       },
++      {
++              .vendor        = "XtremIO",
++              .product       = "XtremApp",
++              .features      = DEFAULT_FEATURES,
++              .hwhandler     = DEFAULT_HWHANDLER,
++              .selector      = "queue-length 0",
++              .pgpolicy      = MULTIBUS,
++              .pgfailback    = -FAILBACK_IMMEDIATE,
++              .checker_name  = DIRECTIO,
++              .fast_io_fail  = 15,
++              .prio_name     = DEFAULT_PRIO,
++              .prio_args     = NULL,
++      },
+       /*
+        * EOL
+        */
diff --git a/multipath-tools/patches/0096-RHBZ-979474-new-wildcards.patch b/multipath-tools/patches/0096-RHBZ-979474-new-wildcards.patch
new file mode 100644 (file)
index 0000000..9025efe
--- /dev/null
@@ -0,0 +1,120 @@
+---
+ libmultipath/print.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 83 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -10,6 +10,7 @@
+ #include <unistd.h>
+ #include <string.h>
+ #include <errno.h>
++#include <libudev.h>
+ #include "checkers.h"
+ #include "vector.h"
+@@ -44,7 +45,7 @@
+  * information printing helpers
+  */
+ static int
+-snprint_str (char * buff, size_t len, char * str)
++snprint_str (char * buff, size_t len, const char * str)
+ {
+       return snprintf(buff, len, "%s", str);
+ }
+@@ -432,6 +433,83 @@ snprint_path_mpp (char * buff, size_t le
+ }
+ static int
++snprint_host_attr (char * buff, size_t len, struct path * pp, char *attr)
++{
++      struct udev_device *host_dev = NULL;
++      char host_id[32];
++      const char *value = NULL;
++      int ret;
++
++      if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP)
++              return snprintf(buff, len, "[undef]");
++      sprintf(host_id, "host%d", pp->sg_id.host_no);
++      host_dev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_host",
++                                                        host_id);
++      if (!host_dev) {
++              condlog(1, "%s: No fc_host device for '%s'", pp->dev, host_id);
++              goto out;
++      }
++      value = udev_device_get_sysattr_value(host_dev, attr);
++      if (value)
++              ret = snprint_str(buff, len, value);
++      udev_device_unref(host_dev);
++out:
++      if (!value)
++              ret = snprintf(buff, len, "[unknown]");
++      return ret;
++}
++
++static int
++snprint_host_wwnn (char * buff, size_t len, struct path * pp)
++{
++      return snprint_host_attr(buff, len, pp, "node_name");
++}
++
++static int
++snprint_host_wwpn (char * buff, size_t len, struct path * pp)
++{
++      return snprint_host_attr(buff, len, pp, "port_name");
++}
++
++static int
++snprint_tgt_wwpn (char * buff, size_t len, struct path * pp)
++{
++      struct udev_device *rport_dev = NULL;
++      char rport_id[32];
++      const char *value = NULL;
++      int ret;
++
++      if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP)
++              return snprintf(buff, len, "[undef]");
++      sprintf(rport_id, "rport-%d:%d-%d",
++              pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
++      rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
++                              "fc_remote_ports", rport_id);
++      if (!rport_dev) {
++              condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
++                      rport_id);
++              goto out;
++      }
++      value = udev_device_get_sysattr_value(rport_dev, "port_name");
++      if (value)
++              ret = snprint_str(buff, len, value);
++      udev_device_unref(rport_dev);
++out:
++      if (!value)
++              ret = snprintf(buff, len, "[unknown]");
++      return ret;
++}
++
++
++static int
++snprint_tgt_wwnn (char * buff, size_t len, struct path * pp)
++{
++      if (pp->tgt_node_name[0] == '\0')
++              return snprintf(buff, len, "[undef]");
++      return snprint_str(buff, len, pp->tgt_node_name);
++}
++
++static int
+ snprint_path_checker (char * buff, size_t len, struct path * pp)
+ {
+       struct checker * c = &pp->checker;
+@@ -475,6 +553,10 @@ struct path_data pd[] = {
+       {'S', "size",          0, snprint_path_size},
+       {'z', "serial",        0, snprint_path_serial},
+       {'m', "multipath",     0, snprint_path_mpp},
++      {'N', "host WWNN",     0, snprint_host_wwnn},
++      {'n', "target WWNN",   0, snprint_tgt_wwnn},
++      {'R', "host WWPN",     0, snprint_host_wwpn},
++      {'r', "target WWPN",   0, snprint_tgt_wwpn},
+       {0, NULL, 0 , NULL}
+ };
diff --git a/multipath-tools/patches/0097-RH-fix-coverity-errors.patch b/multipath-tools/patches/0097-RH-fix-coverity-errors.patch
new file mode 100644 (file)
index 0000000..8ce0e87
--- /dev/null
@@ -0,0 +1,158 @@
+---
+ kpartx/devmapper.c                       |    3 ++-
+ libmultipath/alias.c                     |    1 +
+ libmultipath/blacklist.c                 |    7 +++++++
+ libmultipath/prioritizers/iet.c          |    2 ++
+ libmultipath/prioritizers/weightedpath.c |    5 ++++-
+ libmultipath/regex.c                     |    5 ++++-
+ libmultipath/sysfs.c                     |    3 ++-
+ libmultipath/util.c                      |    2 +-
+ 8 files changed, 23 insertions(+), 5 deletions(-)
+
+Index: multipath-tools-130222/kpartx/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.c
++++ multipath-tools-130222/kpartx/devmapper.c
+@@ -132,8 +132,9 @@ dm_addmap (int task, const char *name, c
+               goto addout;
+       r = dm_task_run (dmt);
+-      addout:
++addout:
+       dm_task_destroy (dmt);
++      free(prefixed_uuid);
+       return r;
+ }
+Index: multipath-tools-130222/libmultipath/alias.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.c
++++ multipath-tools-130222/libmultipath/alias.c
+@@ -328,6 +328,7 @@ get_user_friendly_alias(char *wwid, char
+       if (fflush(f) != 0) {
+               condlog(0, "cannot fflush bindings file stream : %s",
+                       strerror(errno));
++              free(alias);
+               fclose(f);
+               return NULL;
+       }
+Index: multipath-tools-130222/libmultipath/blacklist.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/blacklist.c
++++ multipath-tools-130222/libmultipath/blacklist.c
+@@ -79,6 +79,8 @@ set_ble_device (vector blist, char * ven
+               if (regcomp(&ble->vendor_reg, vendor,
+                           REG_EXTENDED|REG_NOSUB)) {
+                       FREE(vendor);
++                      if (product)
++                              FREE(product);
+                       return 1;
+               }
+               ble->vendor = vendor;
+@@ -87,6 +89,10 @@ set_ble_device (vector blist, char * ven
+               if (regcomp(&ble->product_reg, product,
+                           REG_EXTENDED|REG_NOSUB)) {
+                       FREE(product);
++                      if (vendor) {
++                              ble->vendor = NULL;
++                              FREE(vendor);
++                      }
+                       return 1;
+               }
+               ble->product = product;
+@@ -189,6 +195,7 @@ setup_default_blist (struct config * con
+                                          STRDUP(hwe->bl_product),
+                                          ORIGIN_DEFAULT)) {
+                               FREE(ble);
++                              vector_del_slot(conf->blist_device, VECTOR_SIZE(conf->blist_device) - 1);
+                               return 1;
+                       }
+               }
+Index: multipath-tools-130222/libmultipath/prioritizers/iet.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/iet.c
++++ multipath-tools-130222/libmultipath/prioritizers/iet.c
+@@ -109,6 +109,7 @@ int iet_prio(const char *dev, char * arg
+                       ssize_t nchars = readlink(path, buffer, sizeof(buffer)-1);
+                       if (nchars != -1) {
+                               char *device;
++                              buffer[nchars] = '\0';
+                               device = find_regex(buffer,"(sd[a-z]+)");
+                               // if device parsed is the right one
+                               if (device!=NULL && strncmp(device, dev, strlen(device)) == 0) {
+@@ -118,6 +119,7 @@ int iet_prio(const char *dev, char * arg
+                                       if (ip!=NULL && strncmp(ip, preferredip, strlen(ip)) == 0) {
+                                               // high prio
+                                               free(ip);
++                                              free(device);
+                                               closedir(dir_p);
+                                               return 20;
+                                       }
+Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.c
++++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.c
+@@ -61,8 +61,10 @@ int prio_path_weight(struct path *pp, ch
+       regex = get_next_string(&temp, split_char);
+       /* Return default priority if the argument is not parseable */
+-      if (!regex)
++      if (!regex) {
++              FREE(arg);
+               return priority;
++      }
+       if (!strcmp(regex, HBTL)) {
+               sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no,
+@@ -72,6 +74,7 @@ int prio_path_weight(struct path *pp, ch
+       } else {
+               condlog(0, "%s: %s - Invalid arguments", pp->dev,
+                       pp->prio.name);
++              FREE(arg);
+               return priority;
+       }
+Index: multipath-tools-130222/libmultipath/regex.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/regex.c
++++ multipath-tools-130222/libmultipath/regex.c
+@@ -3936,8 +3936,11 @@ int eflags;
+               regs.num_regs = nmatch;
+               regs.start = TALLOC(nmatch, regoff_t);
+               regs.end = TALLOC(nmatch, regoff_t);
+-              if (regs.start == NULL || regs.end == NULL)
++              if (regs.start == NULL || regs.end == NULL) {
++                      free(regs.start);
++                      free(regs.end);
+                       return (int) REG_NOMATCH;
++              }
+       }
+       /* Perform the searching operation.  */
+Index: multipath-tools-130222/libmultipath/sysfs.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/sysfs.c
++++ multipath-tools-130222/libmultipath/sysfs.c
+@@ -88,7 +88,8 @@ ssize_t sysfs_attr_get_value(struct udev
+       } else if (size == value_len) {
+               condlog(4, "overflow while reading from %s", devpath);
+               size = 0;
+-      }
++      } else
++              value[size] = '\0';
+       close(fd);
+       return size;
+Index: multipath-tools-130222/libmultipath/util.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/util.c
++++ multipath-tools-130222/libmultipath/util.c
+@@ -175,7 +175,7 @@ devt2devname (char *devname, int devname
+               sprintf(block_path,"/sys/dev/block/%u:%u", major, minor);
+               if (lstat(block_path, &statbuf) == 0) {
+                       if (S_ISLNK(statbuf.st_mode) &&
+-                          readlink(block_path, dev, FILE_NAME_SIZE) > 0) {
++                          readlink(block_path, dev, FILE_NAME_SIZE-1) > 0) {
+                               char *p = strrchr(dev, '/');
+                               if (!p) {
diff --git a/multipath-tools/patches/0098-UPBZ-1067171-mutipath-i.patch b/multipath-tools/patches/0098-UPBZ-1067171-mutipath-i.patch
new file mode 100644 (file)
index 0000000..cf41863
--- /dev/null
@@ -0,0 +1,332 @@
+---
+ libmultipath/config.h    |   15 ++++++++-
+ libmultipath/configure.c |    2 -
+ libmultipath/discovery.c |    5 +--
+ multipath/main.c         |   75 +++++++++++++++++++++++++----------------------
+ multipath/multipath.8    |    5 ++-
+ 5 files changed, 61 insertions(+), 41 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -23,6 +23,17 @@ enum devtypes {
+       DEV_DEVMAP
+ };
++enum mpath_cmds {
++      CMD_CREATE,
++      CMD_DRY_RUN,
++      CMD_LIST_SHORT,
++      CMD_LIST_LONG,
++      CMD_VALID_PATH,
++      CMD_REMOVE_WWID,
++      CMD_RESET_WWIDS,
++      CMD_ADD_WWID,
++};
++
+ struct hwentry {
+       char * vendor;
+       char * product;
+@@ -79,8 +90,7 @@ struct mpentry {
+ struct config {
+       int verbosity;
+-      int dry_run;
+-      int list;
++      enum mpath_cmds cmd;
+       int pgpolicy_flag;
+       int pgpolicy;
+       enum devtypes dev_type;
+@@ -98,6 +108,7 @@ struct config {
+       int max_fds;
+       int force_reload;
+       int queue_without_daemon;
++      int ignore_wwids;
+       int checker_timeout;
+       int daemon;
+       int flush_on_last_del;
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -85,7 +85,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [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);
+@@ -109,6 +109,7 @@ usage (char * progname)
+               "  -d      dry run, do not create or update devmaps\n" \
+               "  -t      dump internal hardware table\n" \
+               "  -r      force devmap reload\n" \
++              "  -i      ignore wwids file\n" \
+               "  -B      treat the bindings file as read only\n" \
+               "  -p      policy failover|multibus|group_by_serial|group_by_prio\n" \
+               "  -b fil  bindings file location\n" \
+@@ -209,18 +210,19 @@ get_dm_mpvec (vector curmp, vector pathv
+                * If not in "fast list mode", we need to fetch information
+                * about them
+                */
+-              if (conf->list != 1)
++              if (conf->cmd != CMD_LIST_SHORT)
+                       update_paths(mpp);
+-              if (conf->list > 1)
++              if (conf->cmd == CMD_LIST_LONG)
+                       mpp->bestpg = select_path_group(mpp);
+               disassemble_status(status, mpp);
+-              if (conf->list)
++              if (conf->cmd == CMD_LIST_SHORT ||
++                  conf->cmd == CMD_LIST_LONG)
+                       print_multipath_topology(mpp, conf->verbosity);
+-              if (!conf->dry_run)
++              if (conf->cmd == CMD_CREATE)
+                       reinstate_paths(mpp);
+       }
+       return 0;
+@@ -262,10 +264,11 @@ configure (void)
+       /*
+        * if we have a blacklisted device parameter, exit early
+        */
+-      if (dev && conf->dev_type == DEV_DEVNODE && conf->dry_run != 3 &&
++      if (dev && conf->dev_type == DEV_DEVNODE &&
++          conf->cmd != CMD_REMOVE_WWID &&
+           (filter_devnode(conf->blist_devnode,
+                           conf->elist_devnode, dev) > 0)) {
+-              if (conf->dry_run == 2)
++              if (conf->cmd == CMD_VALID_PATH)
+                       printf("%s is not a valid multipath device path\n",
+                              conf->dev);
+               goto out;
+@@ -278,13 +281,13 @@ configure (void)
+               int failed = get_refwwid(conf->dev, conf->dev_type, pathvec,
+                                        &refwwid);
+               if (!refwwid) {
+-                      if (failed == 2 && conf->dry_run == 2)
++                      if (failed == 2 && conf->cmd == CMD_VALID_PATH)
+                               printf("%s is not a valid multipath device path\n", conf->dev);
+                       else
+                               condlog(3, "scope is nul");
+                       goto out;
+               }
+-              if (conf->dry_run == 3) {
++              if (conf->cmd == CMD_REMOVE_WWID) {
+                       r = remove_wwid(refwwid);
+                       if (r == 0)
+                               printf("wwid '%s' removed\n", refwwid);
+@@ -295,7 +298,7 @@ configure (void)
+                       }
+                       goto out;
+               }
+-              if (conf->dry_run == 5) {
++              if (conf->cmd == CMD_ADD_WWID) {
+                       r = remember_wwid(refwwid);
+                       if (r == 0)
+                               printf("wwid '%s' added\n", refwwid);
+@@ -305,13 +308,13 @@ configure (void)
+                       goto out;
+               }
+               condlog(3, "scope limited to %s", refwwid);
+-              if (conf->dry_run == 2) {
+-                      if (check_wwids_file(refwwid, 0) == 0){
+-                              printf("%s is a valid multipath device path\n", conf->dev);
++              if (conf->cmd == CMD_VALID_PATH) {
++                      if (conf->ignore_wwids ||
++                          check_wwids_file(refwwid, 0) == 0)
+                               r = 0;
+-                      }
+-                      else
+-                              printf("%s is not a valid multipath device path\n", conf->dev);
++
++                      printf("%s %s a valid multipath device path\n",
++                             conf->dev, r == 0 ? "is" : "is not");
+                       goto out;
+               }
+       }
+@@ -319,13 +322,13 @@ configure (void)
+       /*
+        * get a path list
+        */
+-      if (conf->dev && !conf->list)
++      if (conf->dev)
+               di_flag = DI_WWID;
+-      if (conf->list > 1)
++      if (conf->cmd == CMD_LIST_LONG)
+               /* extended path info '-ll' */
+               di_flag |= DI_SYSFS | DI_CHECKER;
+-      else if (conf->list)
++      else if (conf->cmd == CMD_LIST_SHORT)
+               /* minimum path info '-l' */
+               di_flag |= DI_SYSFS;
+       else
+@@ -345,7 +348,7 @@ configure (void)
+       filter_pathvec(pathvec, refwwid);
+-      if (conf->list) {
++      if (conf->cmd != CMD_CREATE && conf->cmd != CMD_DRY_RUN) {
+               r = 0;
+               goto out;
+       }
+@@ -440,7 +443,7 @@ main (int argc, char *argv[])
+       int r = 1;
+       long int timestamp = -1;
+       int valid = -1;
+-      while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BritT:qwW")) != EOF ) {
+               switch(arg) {
+               case 'T':
+                       if (optarg[0] == ':')
+@@ -476,7 +479,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BritT:qwW")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -499,11 +502,11 @@ main (int argc, char *argv[])
+                       conf->allow_queueing = 1;
+                       break;
+               case 'c':
+-                      conf->dry_run = 2;
++                      conf->cmd = CMD_VALID_PATH;
+                       break;
+               case 'd':
+-                      if (!conf->dry_run)
+-                              conf->dry_run = 1;
++                      if (conf->cmd == CMD_CREATE)
++                              conf->cmd = CMD_DRY_RUN;
+                       break;
+               case 'f':
+                       conf->remove = FLUSH_ONE;
+@@ -512,11 +515,10 @@ main (int argc, char *argv[])
+                       conf->remove = FLUSH_ALL;
+                       break;
+               case 'l':
+-                      conf->list = 1;
+-                      conf->dry_run = 1;
+-
+                       if (optarg && !strncmp(optarg, "l", 1))
+-                              conf->list++;
++                              conf->cmd = CMD_LIST_LONG;
++                      else
++                              conf->cmd = CMD_LIST_SHORT;
+                       break;
+               case 'M':
+@@ -535,6 +537,9 @@ main (int argc, char *argv[])
+               case 'r':
+                       conf->force_reload = 1;
+                       break;
++              case 'i':
++                      conf->ignore_wwids = 1;
++                      break;
+               case 't':
+                       r = dump_config();
+                       goto out;
+@@ -548,13 +553,13 @@ main (int argc, char *argv[])
+                       usage(argv[0]);
+                       exit(0);
+               case 'w':
+-                      conf->dry_run = 3;
++                      conf->cmd = CMD_REMOVE_WWID;
+                       break;
+               case 'W':
+-                      conf->dry_run = 4;
++                      conf->cmd = CMD_RESET_WWIDS;
+                       break;
+               case 'a':
+-                      conf->dry_run = 5;
++                      conf->cmd = CMD_ADD_WWID;
+                       break;
+               case ':':
+                       fprintf(stderr, "Missing option argument\n");
+@@ -600,16 +605,16 @@ main (int argc, char *argv[])
+       }
+       dm_init();
+-      if (conf->dry_run == 2 &&
++      if (conf->cmd == CMD_VALID_PATH &&
+           (!conf->dev || conf->dev_type == DEV_DEVMAP)) {
+               condlog(0, "the -c option requires a path to check");
+               goto out;
+       }
+-      if (conf->dry_run == 3 && !conf->dev) {
++      if (conf->cmd == CMD_REMOVE_WWID && !conf->dev) {
+               condlog(0, "the -w option requires a device");
+               goto out;
+       }
+-      if (conf->dry_run == 4) {
++      if (conf->cmd == CMD_RESET_WWIDS) {
+               struct multipath * mpp;
+               int i;
+               vector curmp;
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
+ .RB [\| \-b\ \c
+ .IR bindings_file \|]
+ .RB [\| \-d \|]
+-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-A | \-w | \-W \|]
++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-r | \-a | \-A | \-w | \-W \|]
+ .RB [\| \-p\ \c
+ .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
+ .RB [\| device \|]
+@@ -55,6 +55,9 @@ print internal hardware table to stdout
+ .B \-r
+ force devmap reload
+ .TP
++.B \-i
++ignore wwids file when processing devices
++.TP
+ .B \-B
+ treat the bindings file as read only
+ .TP
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -580,7 +580,7 @@ domap (struct multipath * mpp, char * pa
+       /*
+        * last chance to quit before touching the devmaps
+        */
+-      if (conf->dry_run && mpp->action != ACT_NOTHING) {
++      if (conf->cmd == CMD_DRY_RUN && mpp->action != ACT_NOTHING) {
+               print_multipath_topology(mpp, conf->verbosity);
+               return DOMAP_DRY;
+       }
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -54,7 +54,8 @@ store_pathinfo (vector pathvec, vector h
+       }
+       pp->udev = udev_device_ref(udevice);
+       err = pathinfo(pp, hwtable,
+-                     (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
++                     (conf->cmd == CMD_REMOVE_WWID)? flag :
++                                                     (flag | DI_BLACKLIST));
+       if (err)
+               goto out;
+@@ -1101,7 +1102,7 @@ get_uid (struct path * pp)
+       memset(pp->wwid, 0, WWID_SIZE);
+       value = udev_device_get_property_value(pp->udev, pp->uid_attribute);
+-      if ((!value || strlen(value) == 0) && conf->dry_run == 2)
++      if ((!value || strlen(value) == 0) && conf->cmd == CMD_VALID_PATH)
+               value = getenv(pp->uid_attribute);
+       if (value && strlen(value)) {
+               size_t len = WWID_SIZE;
diff --git a/multipath-tools/patches/0099-RH-add-all-devs.patch b/multipath-tools/patches/0099-RH-add-all-devs.patch
new file mode 100644 (file)
index 0000000..aca6d4c
--- /dev/null
@@ -0,0 +1,170 @@
+---
+ libmultipath/config.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ libmultipath/config.h |    1 
+ libmultipath/dict.c   |   38 +++++++++++++++++++++++++++++
+ 3 files changed, 102 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -113,6 +113,8 @@ find_hwe (vector hwtable, char * vendor,
+        * continuing to the generic entries
+        */
+       vector_foreach_slot_backwards (hwtable, tmp, i) {
++              if (tmp->all_devs == 1)
++                      continue;
+               if (hwe_regmatch(tmp, &hwe))
+                       continue;
+               ret = tmp;
+@@ -348,6 +350,62 @@ merge_hwe (struct hwentry * dst, struct
+       return 0;
+ }
++#define overwrite_str(s) \
++do { \
++      if (src->s) { \
++              if (dst->s) \
++                      FREE(dst->s); \
++              if (!(dst->s = set_param_str(src->s))) \
++                      return 1; \
++      } \
++} while(0)
++
++#define overwrite_num(s) \
++do { \
++      if (src->s) \
++              dst->s = src->s; \
++} while(0)
++
++static int
++overwrite_hwe (struct hwentry * dst, struct hwentry * src)
++{
++      overwrite_str(vendor);
++      overwrite_str(product);
++      overwrite_str(revision);
++      overwrite_str(uid_attribute);
++      overwrite_str(features);
++      overwrite_str(hwhandler);
++      overwrite_str(selector);
++      overwrite_str(checker_name);
++      overwrite_str(prio_name);
++      overwrite_str(prio_args);
++      overwrite_str(alias_prefix);
++      overwrite_str(bl_product);
++      overwrite_num(pgpolicy);
++      overwrite_num(pgfailback);
++      overwrite_num(rr_weight);
++      overwrite_num(no_path_retry);
++      overwrite_num(minio);
++      overwrite_num(minio_rq);
++      overwrite_num(pg_timeout);
++      overwrite_num(flush_on_last_del);
++      overwrite_num(fast_io_fail);
++      overwrite_num(dev_loss);
++      overwrite_num(user_friendly_names);
++      overwrite_num(retain_hwhandler);
++      overwrite_num(detect_prio);
++
++      /*
++       * Make sure features is consistent with
++       * no_path_retry
++       */
++      if (dst->no_path_retry == NO_PATH_RETRY_FAIL)
++              remove_feature(&dst->features, "queue_if_no_path");
++      else if (dst->no_path_retry != NO_PATH_RETRY_UNDEF)
++              add_feature(&dst->features, "queue_if_no_path");
++      return 0;
++}
++
+ int
+ store_hwe (vector hwtable, struct hwentry * dhwe)
+ {
+@@ -431,7 +489,11 @@ restart:
+                       break;
+               j = n;
+               vector_foreach_slot_after(hw, hwe2, j) {
+-                      if (conf->hw_strmatch) {
++                      if (hwe2->all_devs == 1) {
++                              overwrite_hwe(hwe1, hwe2);
++                              continue;
++                      }
++                      else if (conf->hw_strmatch) {
+                               if (hwe_strmatch(hwe2, hwe1))
+                                       continue;
+                       }
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -47,6 +47,7 @@ struct hwentry {
+       char * prio_args;
+       char * alias_prefix;
++      int all_devs;
+       int pgpolicy;
+       int pgfailback;
+       int rr_weight;
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -918,6 +918,32 @@ device_handler(vector strvec)
+ }
+ static int
++all_devs_handler(vector strvec)
++{
++      char * buff;
++      struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
++
++      if (!hwe)
++              return 1;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              hwe->all_devs = 0;
++      else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
++               (strlen(buff) == 1 && !strcmp(buff, "1")))
++              hwe->all_devs = 1;
++      else
++              hwe->all_devs = 0;
++
++      FREE(buff);
++      return 0;
++}
++
++static int
+ vendor_handler(vector strvec)
+ {
+       struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+@@ -2182,6 +2208,17 @@ snprint_hw_dev_loss(char * buff, int len
+ }
+ static int
++snprint_hw_all_devs (char *buff, int len, void *data)
++{
++      struct hwentry * hwe = (struct hwentry *)data;
++
++      if (!hwe->all_devs)
++              return 0;
++
++      return snprintf(buff, len, "yes");
++}
++
++static int
+ snprint_hw_vendor (char * buff, int len, void * data)
+ {
+       struct hwentry * hwe = (struct hwentry *)data;
+@@ -2968,6 +3005,7 @@ init_keywords(void)
+       install_keyword_root("devices", &devices_handler);
+       install_keyword_multi("device", &device_handler, NULL);
+       install_sublevel();
++      install_keyword("all_devs", &all_devs_handler, &snprint_hw_all_devs);
+       install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
+       install_keyword("product", &product_handler, &snprint_hw_product);
+       install_keyword("revision", &revision_handler, &snprint_hw_revision);
diff --git a/multipath-tools/patches/0100-RHBZ-1067171-multipath-i-update.patch b/multipath-tools/patches/0100-RHBZ-1067171-multipath-i-update.patch
new file mode 100644 (file)
index 0000000..9a67e7a
--- /dev/null
@@ -0,0 +1,54 @@
+---
+ multipath/main.c |   25 ++++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -198,6 +198,9 @@ get_dm_mpvec (vector curmp, vector pathv
+                       continue;
+               }
++              if (conf->cmd == CMD_VALID_PATH)
++                      continue;
++
+               dm_get_map(mpp->alias, &mpp->size, params);
+               condlog(3, "params = %s", params);
+               dm_get_status(mpp->alias, status);
+@@ -308,7 +311,13 @@ configure (void)
+                       goto out;
+               }
+               condlog(3, "scope limited to %s", refwwid);
+-              if (conf->cmd == CMD_VALID_PATH) {
++              /* If you are ignoring the wwids file and find_multipaths is
++               * set, you need to actually check if there are two available
++               * paths to determine if this path should be multipathed. To
++               * do this, we put off the check until after discovering all
++               * the paths */
++              if (conf->cmd == CMD_VALID_PATH &&
++                  (!conf->find_multipaths || !conf->ignore_wwids)) {
+                       if (conf->ignore_wwids ||
+                           check_wwids_file(refwwid, 0) == 0)
+                               r = 0;
+@@ -348,6 +357,20 @@ configure (void)
+       filter_pathvec(pathvec, refwwid);
++
++      if (conf->cmd == CMD_VALID_PATH) {
++              /* This only happens if find_multipaths is and
++               * ignore_wwids is set.
++               * If there is currently a multipath device matching
++               * the refwwid, or there is more than one path matching
++               * the refwwid, then the path is valid */
++              if (VECTOR_SIZE(curmp) != 0 || VECTOR_SIZE(pathvec) > 1)
++                      r = 0;
++              printf("%s %s a valid multipath device path\n",
++                     conf->dev, r == 0 ? "is" : "is not");
++              goto out;
++      }
++
+       if (conf->cmd != CMD_CREATE && conf->cmd != CMD_DRY_RUN) {
+               r = 0;
+               goto out;
diff --git a/multipath-tools/patches/0101-RH-adapter-name-wildcard.patch b/multipath-tools/patches/0101-RH-adapter-name-wildcard.patch
new file mode 100644 (file)
index 0000000..3c67de5
--- /dev/null
@@ -0,0 +1,33 @@
+---
+ libmultipath/print.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -510,6 +510,16 @@ snprint_tgt_wwnn (char * buff, size_t le
+ }
+ static int
++snprint_host_adapter (char * buff, size_t len, struct path * pp)
++{
++      char adapter[SLOT_NAME_SIZE];
++
++      if (sysfs_get_host_adapter_name(pp, adapter))
++              return snprintf(buff, len, "[undef]");
++      return snprint_str(buff, len, adapter);
++}
++
++static int
+ snprint_path_checker (char * buff, size_t len, struct path * pp)
+ {
+       struct checker * c = &pp->checker;
+@@ -557,6 +567,7 @@ struct path_data pd[] = {
+       {'n', "target WWNN",   0, snprint_tgt_wwnn},
+       {'R', "host WWPN",     0, snprint_host_wwpn},
+       {'r', "target WWPN",   0, snprint_tgt_wwpn},
++      {'a', "host adapter",  0, snprint_host_adapter},
+       {0, NULL, 0 , NULL}
+ };
diff --git a/multipath-tools/patches/0102-RHBZ-1160478-mpathconf-template.patch b/multipath-tools/patches/0102-RHBZ-1160478-mpathconf-template.patch
new file mode 100644 (file)
index 0000000..3c0e443
--- /dev/null
@@ -0,0 +1,52 @@
+---
+ multipath/mpathconf |   26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/multipath/mpathconf
+===================================================================
+--- multipath-tools-130222.orig/multipath/mpathconf
++++ multipath-tools-130222/multipath/mpathconf
+@@ -19,10 +19,27 @@
+ unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE SHOW_STATUS CHANGED_CONFIG
+-DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
++DEFAULT_CONFIG="# device-mapper-multipath configuration file
++
++# For a complete list of the default configuration values, run either:
++# # multipath -t
++# or
++# # multipathd show config
++
++# For a list of configuration options with descriptions, see the
++# multipath.conf man page.
++
++# For an example configuration file, see:
++# /user/share/doc/device-mapper-multipath/multipath.conf
++
++defaults {
++      user_friendly_names yes
++      find_multipaths yes
++}"
++
+ CONFIGFILE="/etc/multipath.conf"
+ MULTIPATHDIR="/etc/multipath"
+-TMPFILE=/etc/multipath/.multipath.conf.tmp
++TMPFILE="/etc/multipath/.multipath.conf.tmp"
+ function usage
+ {
+@@ -134,12 +151,9 @@ if [ ! -d "$MULTIPATHDIR" ]; then
+ fi
+ rm $TMPFILE 2> /dev/null
++echo "$DEFAULT_CONFIG" > $TMPFILE
+ if [ -f "$CONFIGFILE" ]; then
+       cp $CONFIGFILE $TMPFILE
+-elif [ -f "$DEFAULT_CONFIGFILE" ]; then
+-      cp $DEFAULT_CONFIGFILE $TMPFILE
+-else
+-      touch $TMPFILE
+ fi
+ if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
diff --git a/multipath-tools/patches/0103-RH-cleanup-partmaps-code.patch b/multipath-tools/patches/0103-RH-cleanup-partmaps-code.patch
new file mode 100644 (file)
index 0000000..57fb402
--- /dev/null
@@ -0,0 +1,199 @@
+---
+ libmultipath/devmapper.c |  155 ++++++++++++++++++-----------------------------
+ 1 file changed, 61 insertions(+), 94 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -1006,8 +1006,9 @@ bad:
+       return NULL;
+ }
+-int
+-dm_remove_partmaps (const char * mapname, int need_sync)
++static int
++do_foreach_partmaps (const char * mapname, int (*partmap_func)(char *, void *),
++                   void *data)
+ {
+       struct dm_task *dmt;
+       struct dm_names *names;
+@@ -1059,26 +1060,8 @@ dm_remove_partmaps (const char * mapname
+                    */
+                   strstr(params, dev_t)
+                  ) {
+-                      /*
+-                       * then it's a kpartx generated partition.
+-                       * remove it.
+-                       */
+-                      /*
+-                       * if the opencount is 0 maybe some other
+-                       * partitions depend on it.
+-                       */
+-                      if (dm_get_opencount(names->name)) {
+-                              dm_remove_partmaps(names->name, need_sync);
+-                              if (dm_get_opencount(names->name)) {
+-                                      condlog(2, "%s: map in use",
+-                                              names->name);
+-                                      goto out;
+-                              }
+-                      }
+-                      condlog(4, "partition map %s removed",
+-                              names->name);
+-                      dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name,
+-                                         need_sync, 0);
++                      if (partmap_func(names->name, data) != 0)
++                              goto out;
+               }
+               next = names->next;
+@@ -1091,6 +1074,35 @@ out:
+       return r;
+ }
++struct remove_data {
++      int need_sync;
++};
++
++static int
++remove_partmap(char *name, void *data)
++{
++      struct remove_data *rd = (struct remove_data *)data;
++
++      if (dm_get_opencount(name)) {
++              dm_remove_partmaps(name, rd->need_sync);
++              if (dm_get_opencount(name)) {
++                      condlog(2, "%s: map in use", name);
++                      return 1;
++              }
++      }
++      condlog(4, "partition map %s removed", name);
++      dm_simplecmd_flush(DM_DEVICE_REMOVE, name,
++                         rd->need_sync, 0);
++      return 0;
++}
++
++int
++dm_remove_partmaps (const char * mapname, int need_sync)
++{
++      struct remove_data rd = { need_sync };
++      return do_foreach_partmaps(mapname, remove_partmap, &rd);
++}
++
+ static struct dm_info *
+ alloc_dminfo (void)
+ {
+@@ -1140,86 +1152,41 @@ out:
+       return r;
+ }
+-int
+-dm_rename_partmaps (char * old, char * new)
++struct rename_data {
++      char *old;
++      char *new;
++      char *delim;
++};
++
++static int
++rename_partmap (char *name, void *data)
+ {
+-      struct dm_task *dmt;
+-      struct dm_names *names;
+-      unsigned next = 0;
+       char buff[PARAMS_SIZE];
+-      unsigned long long size;
+-      char dev_t[32];
+-      int r = 1;
+       int offset;
+-      char *delim;
+-
+-      if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
+-              return 1;
++      struct rename_data *rd = (struct rename_data *)data;
+-      dm_task_no_open_count(dmt);
+-
+-      if (!dm_task_run(dmt))
+-              goto out;
+-
+-      if (!(names = dm_task_get_names(dmt)))
+-              goto out;
+-
+-      if (!names->dev) {
+-              r = 0; /* this is perfectly valid */
+-              goto out;
+-      }
++      if (strncmp(name, rd->old, strlen(rd->old)) != 0)
++              return 0;
++      for (offset = strlen(rd->old); name[offset] && !(isdigit(name[offset])); offset++); /* do nothing */
++      snprintf(buff, PARAMS_SIZE, "%s%s%s", rd->new, rd->delim,
++               name + offset);
++      dm_rename(name, buff);
++      condlog(4, "partition map %s renamed", name);
++      return 0;
++}
+-      if (dm_dev_t(old, &dev_t[0], 32))
+-              goto out;
++int
++dm_rename_partmaps (char * old, char * new)
++{
++      struct rename_data rd;
++      rd.old = old;
++      rd.new = new;
+       if (isdigit(new[strlen(new)-1]))
+-              delim = "p";
++              rd.delim = "p";
+       else
+-              delim = "";
+-
+-      do {
+-              if (
+-                  /*
+-                   * if devmap target is "linear"
+-                   */
+-                  (dm_type(names->name, TGT_PART) > 0) &&
+-
+-                  /*
+-                   * and the multipath mapname and the part mapname start
+-                   * the same
+-                   */
+-                  !strncmp(names->name, old, strlen(old)) &&
+-
+-                  /*
+-                   * and we can fetch the map table from the kernel
+-                   */
+-                  !dm_get_map(names->name, &size, &buff[0]) &&
+-
+-                  /*
+-                   * and the table maps over the multipath map
+-                   */
+-                  strstr(buff, dev_t)
+-                 ) {
+-                              /*
+-                               * then it's a kpartx generated partition.
+-                               * Rename it.
+-                               */
+-                              for (offset = strlen(old); names->name[offset] && !(isdigit(names->name[offset])); offset++); /* do nothing */
+-                              snprintf(buff, PARAMS_SIZE, "%s%s%s",
+-                                       new, delim, names->name + offset);
+-                              dm_rename(names->name, buff);
+-                              condlog(4, "partition map %s renamed",
+-                                      names->name);
+-                 }
+-
+-              next = names->next;
+-              names = (void *) names + next;
+-      } while (next);
+-
+-      r = 0;
+-out:
+-      dm_task_destroy (dmt);
+-      return r;
++              rd.delim = "";
++      return do_foreach_partmaps(old, rename_partmap, &rd);
+ }
+ int
diff --git a/multipath-tools/patches/0104-RHBZ-631009-deferred-remove.patch b/multipath-tools/patches/0104-RHBZ-631009-deferred-remove.patch
new file mode 100644 (file)
index 0000000..1e1367a
--- /dev/null
@@ -0,0 +1,751 @@
+---
+ libmultipath/Makefile      |    6 ++
+ libmultipath/config.c      |    3 +
+ libmultipath/config.h      |    3 +
+ libmultipath/configure.c   |    1 
+ libmultipath/defaults.h    |    1 
+ libmultipath/devmapper.c   |  130 +++++++++++++++++++++++++++++++++++++++------
+ libmultipath/devmapper.h   |   12 ++--
+ libmultipath/dict.c        |  116 +++++++++++++++++++++++++++++++++++++++-
+ libmultipath/propsel.c     |   28 +++++++++
+ libmultipath/propsel.h     |    1 
+ libmultipath/structs.h     |    8 ++
+ libmultipath/structs_vec.c |    3 -
+ multipath/multipath.conf.5 |   14 ++++
+ multipathd/main.c          |   23 +++++--
+ 14 files changed, 322 insertions(+), 27 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -337,6 +337,7 @@ merge_hwe (struct hwentry * dst, struct
+       merge_num(user_friendly_names);
+       merge_num(retain_hwhandler);
+       merge_num(detect_prio);
++      merge_num(deferred_remove);
+       /*
+        * Make sure features is consistent with
+@@ -394,6 +395,7 @@ overwrite_hwe (struct hwentry * dst, str
+       overwrite_num(user_friendly_names);
+       overwrite_num(retain_hwhandler);
+       overwrite_num(detect_prio);
++      overwrite_num(deferred_remove);
+       /*
+        * Make sure features is consistent with
+@@ -617,6 +619,7 @@ load_config (char * file, struct udev *u
+       conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
+       conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
+       conf->detect_prio = DEFAULT_DETECT_PRIO;
++      conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
+       conf->hw_strmatch = 0;
+       conf->force_sync = 0;
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -61,6 +61,7 @@ struct hwentry {
+       int user_friendly_names;
+       int retain_hwhandler;
+       int detect_prio;
++      int deferred_remove;
+       char * bl_product;
+ };
+@@ -84,6 +85,7 @@ struct mpentry {
+       int flush_on_last_del;
+       int attribute_flags;
+       int user_friendly_names;
++      int deferred_remove;
+       uid_t uid;
+       gid_t gid;
+       mode_t mode;
+@@ -128,6 +130,7 @@ struct config {
+       int retain_hwhandler;
+       int detect_prio;
+       int force_sync;
++      int deferred_remove;
+       unsigned int version[3];
+       char * dev;
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -290,6 +290,7 @@ setup_map (struct multipath * mpp, char
+       select_dev_loss(mpp);
+       select_reservation_key(mpp);
+       select_retain_hwhandler(mpp);
++      select_deferred_remove(mpp);
+       sysfs_set_scsi_tmo(mpp);
+       /*
+Index: multipath-tools-130222/libmultipath/defaults.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/defaults.h
++++ multipath-tools-130222/libmultipath/defaults.h
+@@ -19,6 +19,7 @@
+ #define DEFAULT_FAST_IO_FAIL  5
+ #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
+ #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
++#define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
+ #define DEFAULT_CHECKINT      5
+ #define MAX_CHECKINT(a)               (a << 2)
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -103,7 +103,9 @@ dm_lib_prereq (void)
+ {
+       char version[64];
+       int v[3];
+-#if defined(DM_SUBSYSTEM_UDEV_FLAG0)
++#if defined(LIBDM_API_DEFERRED)
++      int minv[3] = {1, 2, 89};
++#elif defined(DM_SUBSYSTEM_UDEV_FLAG0)
+       int minv[3] = {1, 2, 82};
+ #elif defined(LIBDM_API_COOKIE)
+       int minv[3] = {1, 2, 38};
+@@ -202,7 +204,7 @@ dm_prereq (void)
+ }
+ static int
+-dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags) {
++dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) {
+       int r = 0;
+       int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
+                                           task == DM_DEVICE_REMOVE));
+@@ -220,7 +222,10 @@ dm_simplecmd (int task, const char *name
+       if (no_flush)
+               dm_task_no_flush(dmt);          /* for DM_DEVICE_SUSPEND/RESUME */
+ #endif
+-
++#ifdef LIBDM_API_DEFERRED
++      if (deferred_remove)
++              dm_task_deferred_remove(dmt);
++#endif
+       if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags))
+               goto out;
+       r = dm_task_run (dmt);
+@@ -232,12 +237,18 @@ dm_simplecmd (int task, const char *name
+ extern int
+ dm_simplecmd_flush (int task, const char *name, int needsync, uint16_t udev_flags) {
+-      return dm_simplecmd(task, name, 0, needsync, udev_flags);
++      return dm_simplecmd(task, name, 0, needsync, udev_flags, 0);
+ }
+ extern int
+ dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) {
+-      return dm_simplecmd(task, name, 1, 1, udev_flags);
++      return dm_simplecmd(task, name, 1, 1, udev_flags, 0);
++}
++
++extern int
++dm_device_remove (const char *name, int needsync, int deferred_remove) {
++      return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0,
++                          deferred_remove);
+ }
+ extern int
+@@ -653,7 +664,7 @@ out:
+ }
+ extern int
+-_dm_flush_map (const char * mapname, int need_sync)
++_dm_flush_map (const char * mapname, int need_sync, int deferred_remove)
+ {
+       int r;
+@@ -663,23 +674,46 @@ _dm_flush_map (const char * mapname, int
+       if (dm_type(mapname, TGT_MPATH) <= 0)
+               return 0; /* nothing to do */
+-      if (dm_remove_partmaps(mapname, need_sync))
++      if (dm_remove_partmaps(mapname, need_sync, deferred_remove))
+               return 1;
+-      if (dm_get_opencount(mapname)) {
++      if (!deferred_remove && dm_get_opencount(mapname)) {
+               condlog(2, "%s: map in use", mapname);
+               return 1;
+       }
+-      r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync, 0);
++      r = dm_device_remove(mapname, need_sync, deferred_remove);
+       if (r) {
++              if (deferred_remove && dm_map_present(mapname)) {
++                      condlog(4, "multipath map %s remove deferred",
++                              mapname);
++                      return 2;
++              }
+               condlog(4, "multipath map %s removed", mapname);
+               return 0;
+       }
+       return 1;
+ }
++#ifdef LIBDM_API_DEFERRED
++
++int
++dm_flush_map_nopaths(const char * mapname, int deferred_remove)
++{
++      return _dm_flush_map(mapname, 1, deferred_remove);
++}
++
++#else
++
++int
++dm_flush_map_nopaths(const char * mapname, int deferred_remove)
++{
++      return _dm_flush_map(mapname, 1, 0);
++}
++
++#endif
++
+ extern int
+ dm_suspend_and_flush_map (const char * mapname)
+ {
+@@ -1076,6 +1110,7 @@ out:
+ struct remove_data {
+       int need_sync;
++      int deferred_remove;
+ };
+ static int
+@@ -1084,25 +1119,90 @@ remove_partmap(char *name, void *data)
+       struct remove_data *rd = (struct remove_data *)data;
+       if (dm_get_opencount(name)) {
+-              dm_remove_partmaps(name, rd->need_sync);
+-              if (dm_get_opencount(name)) {
++              dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove);
++              if (!rd->deferred_remove && dm_get_opencount(name)) {
+                       condlog(2, "%s: map in use", name);
+                       return 1;
+               }
+       }
+       condlog(4, "partition map %s removed", name);
+-      dm_simplecmd_flush(DM_DEVICE_REMOVE, name,
+-                         rd->need_sync, 0);
++      dm_device_remove(name, rd->need_sync, rd->deferred_remove);
+       return 0;
+ }
+ int
+-dm_remove_partmaps (const char * mapname, int need_sync)
++dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove)
+ {
+-      struct remove_data rd = { need_sync };
++      struct remove_data rd = { need_sync, deferred_remove };
+       return do_foreach_partmaps(mapname, remove_partmap, &rd);
+ }
++#ifdef LIBDM_API_DEFERRED
++
++static int
++cancel_remove_partmap (char *name, void *unused)
++{
++      if (dm_message(name, "@cancel_deferred_remove") != 0)
++              condlog(0, "%s: can't cancel deferred remove: %s", name,
++                      strerror(errno));
++      return 0;
++}
++
++static int
++dm_get_deferred_remove (char * mapname)
++{
++      int r = -1;
++      struct dm_task *dmt;
++      struct dm_info info;
++
++      if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
++              return -1;
++
++      if (!dm_task_set_name(dmt, mapname))
++              goto out;
++
++      if (!dm_task_run(dmt))
++              goto out;
++
++      if (!dm_task_get_info(dmt, &info))
++              goto out;
++
++      r = info.deferred_remove;
++out:
++      dm_task_destroy(dmt);
++      return r;
++}
++
++int
++dm_cancel_deferred_remove (struct multipath *mpp)
++{
++      int r = 0;
++
++      if (!dm_get_deferred_remove(mpp->alias))
++              return 0;
++      if (mpp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS)
++              mpp->deferred_remove = DEFERRED_REMOVE_ON;
++
++      do_foreach_partmaps(mpp->alias, cancel_remove_partmap, NULL);
++      r = dm_message(mpp->alias, "@cancel_deferred_remove");
++      if (r)
++              condlog(0, "%s: can't cancel deferred remove: %s", mpp->alias,
++                      strerror(errno));
++      else
++              condlog(2, "%s: canceled deferred remove", mpp->alias);
++      return r;
++}
++
++#else
++
++int
++dm_cancel_deferred_remove (struct multipath *mpp)
++{
++      return 0;
++}
++
++#endif
++
+ static struct dm_info *
+ alloc_dminfo (void)
+ {
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -17,15 +17,18 @@ int dm_prereq (void);
+ int dm_drv_version (unsigned int * version, char * str);
+ int dm_simplecmd_flush (int, const char *, int, uint16_t);
+ int dm_simplecmd_noflush (int, const char *, uint16_t);
++int dm_device_remove (const char *, int, int);
+ int dm_addmap_create (struct multipath *mpp, char *params);
+ int dm_addmap_reload (struct multipath *mpp, char *params);
+ int dm_map_present (const char *);
+ int dm_get_map(const char *, unsigned long long *, char *);
+ int dm_get_status(char *, char *);
+ int dm_type(const char *, char *);
+-int _dm_flush_map (const char *, int);
+-#define dm_flush_map(mapname) _dm_flush_map(mapname, 1)
+-#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0)
++int _dm_flush_map (const char *, int, int);
++int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
++#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0)
++#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0, 0)
++int dm_cancel_deferred_remove(struct multipath *mpp);
+ int dm_suspend_and_flush_map(const char * mapname);
+ int dm_flush_maps (void);
+ int dm_fail_path(char * mapname, char * path);
+@@ -40,7 +43,8 @@ int dm_geteventnr (char *name);
+ int dm_get_major (char *name);
+ int dm_get_minor (char *name);
+ char * dm_mapname(int major, int minor);
+-int dm_remove_partmaps (const char * mapname, int need_sync);
++int dm_remove_partmaps (const char * mapname, int need_sync,
++                      int deferred_remove);
+ int dm_get_uuid(char *name, char *uuid);
+ int dm_get_info (char * mapname, struct dm_info ** dmi);
+ int dm_rename (char * old, char * new);
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -738,6 +738,29 @@ def_force_sync_handler(vector strvec)
+       return 0;
+ }
++static int
++def_deferred_remove_handler(vector strvec)
++{
++      char * buff;
++
++      buff = set_value(strvec);
++
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              conf->deferred_remove = DEFERRED_REMOVE_OFF;
++      else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
++               (strlen(buff) == 1 && !strcmp(buff, "1")))
++              conf->deferred_remove = DEFERRED_REMOVE_ON;
++      else
++              conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * blacklist block handlers
+  */
+@@ -1445,6 +1468,33 @@ hw_detect_prio_handler(vector strvec)
+       return 0;
+ }
++static int
++hw_deferred_remove_handler(vector strvec)
++{
++      struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
++      char * buff;
++
++      if (!hwe)
++              return 1;
++
++      buff = set_value(strvec);
++
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              hwe->deferred_remove = DEFERRED_REMOVE_OFF;
++      else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
++               (strlen(buff) == 1 && !strcmp(buff, "1")))
++              hwe->deferred_remove = DEFERRED_REMOVE_ON;
++      else
++              hwe->deferred_remove = DEFERRED_REMOVE_UNDEF;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * multipaths block handlers
+  */
+@@ -1920,6 +1970,32 @@ mp_names_handler(vector strvec)
+       return 0;
+ }
++static int
++mp_deferred_remove_handler(vector strvec)
++{
++      struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
++      char * buff;
++
++      if (!mpe)
++              return 1;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
++          (strlen(buff) == 1 && strcmp(buff, "0") == 0))
++              mpe->deferred_remove = DEFERRED_REMOVE_OFF;
++      else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
++               (strlen(buff) == 1 && strcmp(buff, "1") == 0))
++              mpe->deferred_remove = DEFERRED_REMOVE_ON;
++      else
++              mpe->deferred_remove = DEFERRED_REMOVE_UNDEF;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * config file keywords printing
+  */
+@@ -2165,7 +2241,7 @@ snprint_mp_reservation_key (char * buff,
+       return snprintf(buff, len, "0x%" PRIx64, prkey);
+ }
+-      static int
++static int
+ snprint_mp_user_friendly_names (char * buff, int len, void * data)
+ {
+       struct mpentry * mpe = (struct mpentry *)data;
+@@ -2179,6 +2255,19 @@ snprint_mp_user_friendly_names (char * b
+ }
+ static int
++snprint_mp_deferred_remove (char * buff, int len, void * data)
++{
++      struct mpentry * mpe = (struct mpentry *)data;
++
++      if (mpe->deferred_remove == DEFERRED_REMOVE_UNDEF)
++              return 0;
++      else if (mpe->deferred_remove == DEFERRED_REMOVE_OFF)
++              return snprintf(buff, len, "no");
++      else
++              return snprintf(buff, len, "yes");
++}
++
++static int
+ snprint_hw_fast_io_fail(char * buff, int len, void * data)
+ {
+       struct hwentry * hwe = (struct hwentry *)data;
+@@ -2507,6 +2596,19 @@ snprint_hw_retain_hwhandler_handler(char
+ }
+ static int
++snprint_hw_deferred_remove(char * buff, int len, void * data)
++{
++      struct hwentry * hwe = (struct hwentry *)data;
++
++      if (hwe->deferred_remove == DEFERRED_REMOVE_ON)
++              return snprintf(buff, len, "yes");
++      else if (hwe->deferred_remove == DEFERRED_REMOVE_OFF)
++              return snprintf(buff, len, "no");
++      else
++              return 0;
++}
++
++static int
+ snprint_detect_prio(char * buff, int len, void * data)
+ {
+       struct hwentry * hwe = (struct hwentry *)data;
+@@ -2900,6 +3002,15 @@ snprint_def_force_sync(char * buff, int
+ }
+ static int
++snprint_def_deferred_remove(char * buff, int len, void * data)
++{
++      if (conf->deferred_remove == DEFERRED_REMOVE_ON)
++              return snprintf(buff, len, "yes");
++      else
++              return snprintf(buff, len, "no");
++}
++
++static int
+ snprint_ble_simple (char * buff, int len, void * data)
+ {
+       struct blentry * ble = (struct blentry *)data;
+@@ -2968,6 +3079,7 @@ init_keywords(void)
+       install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
+       install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
+       install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
++      install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
+       __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
+@@ -3032,6 +3144,7 @@ init_keywords(void)
+       install_keyword("user_friendly_names", &hw_names_handler, &snprint_hw_user_friendly_names);
+       install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
+       install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
++      install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
+       install_sublevel_end();
+       install_keyword_root("multipaths", &multipaths_handler);
+@@ -3056,5 +3169,6 @@ init_keywords(void)
+       install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
+       install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
+       install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
++      install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
+       install_sublevel_end();
+ }
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -744,6 +744,34 @@ select_retain_hwhandler (struct multipat
+ }
+ extern int
++select_deferred_remove (struct multipath *mp)
++{
++      if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) {
++              condlog(3, "%s: deferred_remove in progress", mp->alias);
++              return 0;
++      }
++      if (mp->mpe && mp->mpe->deferred_remove) {
++              mp->deferred_remove = mp->mpe->deferred_remove;
++              condlog(3, "%s: deferred_remove = %i (multipath setting)",
++                      mp->alias, mp->deferred_remove);
++              return 0;
++      }
++      if (mp->hwe && mp->hwe->deferred_remove) {
++              mp->deferred_remove = mp->hwe->deferred_remove;
++              condlog(3, "%s: deferred_remove = %d (controller default)", mp->alias, mp->deferred_remove);
++              return 0;
++      }
++      if (conf->deferred_remove) {
++              mp->deferred_remove = conf->deferred_remove;
++              condlog(3, "%s: deferred_remove = %d (config file default)", mp->alias, mp->deferred_remove);
++              return 0;
++      }
++      mp->deferred_remove = DEFAULT_DEFERRED_REMOVE;
++      condlog(3, "%s: deferred_remove = %d (compiled in default)", mp->alias, mp->deferred_remove);
++      return 0;
++}
++
++extern int
+ select_detect_prio (struct path * pp)
+ {
+       if (pp->hwe && pp->hwe->detect_prio) {
+Index: multipath-tools-130222/libmultipath/propsel.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.h
++++ multipath-tools-130222/libmultipath/propsel.h
+@@ -20,3 +20,4 @@ int select_dev_loss(struct multipath *mp
+ int select_reservation_key(struct multipath *mp);
+ int select_retain_hwhandler (struct multipath * mp);
+ int select_detect_prio(struct path * pp);
++int select_deferred_remove(struct multipath *mp);
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -114,6 +114,13 @@ enum detect_prio_states {
+       DETECT_PRIO_ON,
+ };
++enum deferred_remove_states {
++      DEFERRED_REMOVE_UNDEF,
++      DEFERRED_REMOVE_OFF,
++      DEFERRED_REMOVE_ON,
++      DEFERRED_REMOVE_IN_PROGRESS,
++};
++
+ enum scsi_protocol {
+       SCSI_PROTOCOL_FCP = 0,  /* Fibre Channel */
+       SCSI_PROTOCOL_SPI = 1,  /* parallel SCSI */
+@@ -207,6 +214,7 @@ struct multipath {
+       int attribute_flags;
+       int fast_io_fail;
+       int retain_hwhandler;
++      int deferred_remove;
+       unsigned int dev_loss;
+       uid_t uid;
+       gid_t gid;
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -214,19 +214,30 @@ sync_maps_state(vector mpvec)
+ }
+ static int
+-flush_map(struct multipath * mpp, struct vectors * vecs)
++flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
+ {
++      int r;
++
++      if (nopaths)
++              r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
++      else
++              r = dm_flush_map(mpp->alias);
+       /*
+        * clear references to this map before flushing so we can ignore
+        * the spurious uevent we may generate with the dm_flush_map call below
+        */
+-      if (dm_flush_map(mpp->alias)) {
++      if (r) {
+               /*
+                * May not really be an error -- if the map was already flushed
+                * from the device mapper by dmsetup(8) for instance.
+                */
+-              condlog(0, "%s: can't flush", mpp->alias);
+-              return 1;
++              if (r == 1)
++                      condlog(0, "%s: can't flush", mpp->alias);
++              else {
++                      condlog(2, "%s: devmap deferred remove", mpp->alias);
++                      mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
++              }
++              return r;
+       }
+       else {
+               dm_lib_release();
+@@ -372,7 +383,7 @@ ev_remove_map (char * devname, char * al
+                       mpp->alias, mpp->dmi->minor, minor);
+               return 0;
+       }
+-      return flush_map(mpp, vecs);
++      return flush_map(mpp, vecs, 0);
+ }
+ static int
+@@ -628,7 +639,7 @@ ev_remove_path (struct path *pp, struct
+                               mpp->flush_on_last_del = FLUSH_IN_PROGRESS;
+                               dm_queue_if_no_path(mpp->alias, 0);
+                       }
+-                      if (!flush_map(mpp, vecs)) {
++                      if (!flush_map(mpp, vecs, 1)) {
+                               condlog(2, "%s: removed map after"
+                                       " removing all paths",
+                                       alias);
+Index: multipath-tools-130222/libmultipath/structs_vec.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs_vec.c
++++ multipath-tools-130222/libmultipath/structs_vec.c
+@@ -392,6 +392,8 @@ __setup_multipath (struct vectors * vecs
+               set_no_path_retry(mpp);
+               select_pg_timeout(mpp);
+               select_flush_on_last_del(mpp);
++              if (VECTOR_SIZE(mpp->paths) != 0)
++                      dm_cancel_deferred_remove(mpp);
+       }
+       return 0;
+@@ -565,7 +567,6 @@ int update_multipath (struct vectors *ve
+                       }
+               }
+       }
+-
+       return 0;
+ }
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -420,6 +420,16 @@ only one checker will run at a time.  Th
+ multipathd checkers running in parallel causes significant CPU pressure. The
+ Default is
+ .I no
++.TP
++.B deferred_remove
++If set to
++.I yes
++, multipathd will do a deferred remove instead of a regular remove when the
++last path device has been deleted.  This means that if the multipath device is
++still in use, it will be freed when the last user closes it.  If path is added
++to the multipath device before the last user closes it, the deferred remove
++will be canceled. Default is
++.I no
+ .
+ .SH "blacklist section"
+ The
+@@ -521,6 +531,8 @@ section:
+ .B features
+ .TP
+ .B reservation_key
++.TP
++.B deferred_remove
+ .RE
+ .PD
+ .LP
+@@ -611,6 +623,8 @@ section:
+ .B retain_attached_hw_handler
+ .TP
+ .B detect_prio
++.TP
++.B deferred_remove
+ .RE
+ .PD
+ .LP
+Index: multipath-tools-130222/libmultipath/Makefile
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/Makefile
++++ multipath-tools-130222/libmultipath/Makefile
+@@ -36,6 +36,12 @@ ifneq ($(strip $(LIBUDEV_API_RECVBUF)),0
+       CFLAGS += -DLIBUDEV_API_RECVBUF
+ endif
++LIBDM_API_DEFERRED = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_deferred_remove' /usr/include/libdevmapper.h)
++
++ifneq ($(strip $(LIBDM_API_DEFERRED)),0)
++      CFLAGS += -DLIBDM_API_DEFERRED
++endif
++
+ all: $(LIBS)
diff --git a/multipath-tools/patches/0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch b/multipath-tools/patches/0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch
new file mode 100644 (file)
index 0000000..8c793bb
--- /dev/null
@@ -0,0 +1,10 @@
+diff -purN multipath-tools-130222.orig/multipath/multipath.rules multipath-tools-130222/multipath/multipath.rules
+--- multipath-tools-130222.orig/multipath/multipath.rules      2014-11-03 14:37:41.269413134 +0100
++++ multipath-tools-130222/multipath/multipath.rules   2014-11-03 14:38:43.694281901 +0100
+@@ -45,5 +45,5 @@ ACTION!="change", GOTO="end_mpath"
+ ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
+ ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
+ ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
+-RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
++ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
+ LABEL="end_mpath"
diff --git a/multipath-tools/patches/0106-RHBZ-1159337-fix-double-free.patch b/multipath-tools/patches/0106-RHBZ-1159337-fix-double-free.patch
new file mode 100644 (file)
index 0000000..cbe4d1e
--- /dev/null
@@ -0,0 +1,20 @@
+---
+ multipathd/main.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -669,9 +669,8 @@ ev_remove_path (struct path *pp, struct
+                       /*
+                        * update our state from kernel
+                        */
+-                      if (setup_multipath(vecs, mpp)) {
+-                              goto fail;
+-                      }
++                      if (setup_multipath(vecs, mpp))
++                              return 1;
+                       sync_map_state(mpp);
+                       condlog(2, "%s [%s]: path removed from map %s",
diff --git a/multipath-tools/patches/0107-RHBZ-1169935-no-new-devs.patch b/multipath-tools/patches/0107-RHBZ-1169935-no-new-devs.patch
new file mode 100644 (file)
index 0000000..99ae35a
--- /dev/null
@@ -0,0 +1,231 @@
+---
+ libmultipath/config.c    |    4 ++++
+ libmultipath/config.h    |    1 +
+ libmultipath/configure.c |    5 ++---
+ libmultipath/dict.c      |   33 +++++++++++++++++++++++++++++++++
+ libmultipath/util.c      |   30 ++++++++++++++++++++++++++++++
+ libmultipath/util.h      |    1 +
+ libmultipath/wwids.c     |   21 ++++++++++++++-------
+ multipathd/main.c        |    3 +--
+ 8 files changed, 86 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -131,6 +131,7 @@ struct config {
+       int detect_prio;
+       int force_sync;
+       int deferred_remove;
++      int ignore_new_boot_devs;
+       unsigned int version[3];
+       char * dev;
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -775,9 +775,8 @@ coalesce_paths (struct vectors * vecs, v
+               if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
+                       continue;
+-              /* If find_multipaths was selected check if the path is valid */
+-              if (conf->find_multipaths && !refwwid &&
+-                  !should_multipath(pp1, pathvec)) {
++              /* check if the path is valid */
++              if (!refwwid && !should_multipath(pp1, pathvec)) {
+                       orphan_path(pp1);
+                       continue;
+               }
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -15,6 +15,7 @@
+ #include "wwids.h"
+ #include "defaults.h"
+ #include "config.h"
++#include "util.h"
+ /*
+  * Copyright (c) 2010 Benjamin Marzinski, Redhat
+@@ -268,15 +269,21 @@ should_multipath(struct path *pp1, vecto
+ {
+       int i;
+       struct path *pp2;
++      int ignore_new_devs = (conf->ignore_new_boot_devs && in_initrd());
++
++      if (!conf->find_multipaths && !ignore_new_devs)
++              return 1;
+       condlog(4, "checking if %s should be multipathed", pp1->dev);
+-      vector_foreach_slot(pathvec, pp2, i) {
+-              if (pp1->dev == pp2->dev)
+-                      continue;
+-              if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
+-                      condlog(3, "found multiple paths with wwid %s, "
+-                              "multipathing %s", pp1->wwid, pp1->dev);
+-                      return 1;
++      if (!ignore_new_devs) {
++              vector_foreach_slot(pathvec, pp2, i) {
++                      if (pp1->dev == pp2->dev)
++                              continue;
++                      if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
++                              condlog(3, "found multiple paths with wwid %s, "
++                                      "multipathing %s", pp1->wwid, pp1->dev);
++                              return 1;
++                      }
+               }
+       }
+       if (check_wwids_file(pp1->wwid, 0) < 0) {
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -503,8 +503,7 @@ rescan:
+                       return 1;
+               }
+-              if (conf->find_multipaths &&
+-                  !should_multipath(pp, vecs->pathvec)) {
++              if (!should_multipath(pp, vecs->pathvec)) {
+                       orphan_path(pp);
+                       return 0;
+               }
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -622,6 +622,7 @@ load_config (char * file, struct udev *u
+       conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
+       conf->hw_strmatch = 0;
+       conf->force_sync = 0;
++      conf->ignore_new_boot_devs = 0;
+       /*
+        * preload default hwtable
+@@ -732,6 +733,9 @@ load_config (char * file, struct udev *u
+           !conf->wwids_file)
+               goto out;
++      if (conf->ignore_new_boot_devs)
++              in_initrd();
++
+       return 0;
+ out:
+       free_config(conf);
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -761,6 +761,29 @@ def_deferred_remove_handler(vector strve
+       return 0;
+ }
++static int
++def_ignore_new_boot_devs_handler(vector strvec)
++{
++      char * buff;
++
++      buff = set_value(strvec);
++
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              conf->ignore_new_boot_devs = 0;
++      else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
++               (strlen(buff) == 1 && !strcmp(buff, "1")))
++              conf->ignore_new_boot_devs = 1;
++      else
++              conf->ignore_new_boot_devs = 0;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * blacklist block handlers
+  */
+@@ -3011,6 +3034,15 @@ snprint_def_deferred_remove(char * buff,
+ }
+ static int
++snprint_def_ignore_new_boot_devs(char * buff, int len, void * data)
++{
++      if (conf->ignore_new_boot_devs == 1)
++              return snprintf(buff, len, "yes");
++      else
++              return snprintf(buff, len, "no");
++}
++
++static int
+ snprint_ble_simple (char * buff, int len, void * data)
+ {
+       struct blentry * ble = (struct blentry *)data;
+@@ -3080,6 +3112,7 @@ init_keywords(void)
+       install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
+       install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
+       install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
++      install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
+       __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
+Index: multipath-tools-130222/libmultipath/util.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/util.c
++++ multipath-tools-130222/libmultipath/util.c
+@@ -3,6 +3,8 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#include <sys/vfs.h>
++#include <linux/magic.h>
+ #include "debug.h"
+ #include "memory.h"
+@@ -267,3 +269,31 @@ dev_t parse_devt(const char *dev_t)
+       return makedev(maj, min);
+ }
++
++/* This define was taken from systemd. src/shared/macro.h */
++#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
++
++/* This function was taken from systemd. src/shared/util.c */
++int in_initrd(void) {
++      static int saved = -1;
++      struct statfs s;
++
++      if (saved >= 0)
++              return saved;
++
++      /* We make two checks here:
++       *
++       * 1. the flag file /etc/initrd-release must exist
++       * 2. the root file system must be a memory file system
++       * The second check is extra paranoia, since misdetecting an
++       * initrd can have bad bad consequences due the initrd
++       * emptying when transititioning to the main systemd.
++       */
++
++      saved = access("/etc/initrd-release", F_OK) >= 0 &&
++              statfs("/", &s) >= 0 &&
++              (F_TYPE_EQUAL(s.f_type, TMPFS_MAGIC) ||
++               F_TYPE_EQUAL(s.f_type, RAMFS_MAGIC));
++
++      return saved;
++}
+Index: multipath-tools-130222/libmultipath/util.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/util.h
++++ multipath-tools-130222/libmultipath/util.h
+@@ -11,6 +11,7 @@ void remove_trailing_chars(char *path, c
+ int devt2devname (char *, int, char *);
+ dev_t parse_devt(const char *dev_t);
+ char *convert_dev(char *dev, int is_path_device);
++int in_initrd(void);
+ #define safe_sprintf(var, format, args...)    \
+       snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
diff --git a/multipath-tools/patches/0108-RHBZ-1153832-kpartx-remove-devs.patch b/multipath-tools/patches/0108-RHBZ-1153832-kpartx-remove-devs.patch
new file mode 100644 (file)
index 0000000..f02551a
--- /dev/null
@@ -0,0 +1,15 @@
+---
+ multipath/multipath.rules |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -45,5 +45,5 @@ ACTION!="change", GOTO="end_mpath"
+ ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
+ ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
+ ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
+-ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
++ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -u $tempnode"
+ LABEL="end_mpath"
diff --git a/multipath-tools/patches/0109-RH-read-only-bindings.patch b/multipath-tools/patches/0109-RH-read-only-bindings.patch
new file mode 100644 (file)
index 0000000..c08120f
--- /dev/null
@@ -0,0 +1,27 @@
+---
+ multipathd/main.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1879,7 +1879,7 @@ main (int argc, char *argv[])
+       if (!conf)
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":dv:k::")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":dv:k::B")) != EOF ) {
+       switch(arg) {
+               case 'd':
+                       logsink = 0;
+@@ -1895,6 +1895,9 @@ main (int argc, char *argv[])
+               case 'k':
+                       uxclnt(optarg);
+                       exit(0);
++              case 'B':
++                      conf->bindings_read_only = 1;
++                      break;
+               default:
+                       ;
+               }
diff --git a/multipath-tools/patches/0110-RHBZ-blacklist-vd-devs.patch b/multipath-tools/patches/0110-RHBZ-blacklist-vd-devs.patch
new file mode 100644 (file)
index 0000000..af52d0d
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ libmultipath/blacklist.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/blacklist.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/blacklist.c
++++ multipath-tools-130222/libmultipath/blacklist.c
+@@ -169,7 +169,7 @@ setup_default_blist (struct config * con
+       if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
+               return 1;
+-      str = STRDUP("^(td|hd)[a-z]");
++      str = STRDUP("^(td|hd|vd)[a-z]");
+       if (!str)
+               return 1;
+       if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
diff --git a/multipath-tools/patches/0111-RH-dont-show-pg-timeout.patch b/multipath-tools/patches/0111-RH-dont-show-pg-timeout.patch
new file mode 100644 (file)
index 0000000..f545cc5
--- /dev/null
@@ -0,0 +1,147 @@
+---
+ libmultipath/dict.c |   97 ----------------------------------------------------
+ 1 file changed, 97 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -473,26 +473,6 @@ def_checker_timeout_handler(vector strve
+ static int
+ def_pg_timeout_handler(vector strvec)
+ {
+-      int pg_timeout;
+-      char * buff;
+-
+-      buff = set_value(strvec);
+-
+-      if (!buff)
+-              return 1;
+-
+-      if (strlen(buff) == 4 && !strcmp(buff, "none"))
+-              conf->pg_timeout = -PGTIMEOUT_NONE;
+-      else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
+-              if (pg_timeout == 0)
+-                      conf->pg_timeout = -PGTIMEOUT_NONE;
+-              else
+-                      conf->pg_timeout = pg_timeout;
+-      }
+-      else
+-              conf->pg_timeout = PGTIMEOUT_UNDEF;
+-
+-      FREE(buff);
+       return 0;
+ }
+@@ -1358,30 +1338,6 @@ hw_minio_rq_handler(vector strvec)
+ static int
+ hw_pg_timeout_handler(vector strvec)
+ {
+-      int pg_timeout;
+-      struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
+-      char *buff;
+-
+-      if (!hwe)
+-              return 1;
+-
+-      buff = set_value(strvec);
+-
+-      if (!buff)
+-              return 1;
+-
+-      if (strlen(buff) == 4 && !strcmp(buff, "none"))
+-              hwe->pg_timeout = -PGTIMEOUT_NONE;
+-      else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
+-              if (pg_timeout == 0)
+-                      hwe->pg_timeout = -PGTIMEOUT_NONE;
+-              else
+-                      hwe->pg_timeout = pg_timeout;
+-      }
+-      else
+-              hwe->pg_timeout = PGTIMEOUT_UNDEF;
+-
+-      FREE(buff);
+       return 0;
+ }
+@@ -1819,29 +1775,6 @@ mp_minio_rq_handler(vector strvec)
+ static int
+ mp_pg_timeout_handler(vector strvec)
+ {
+-      int pg_timeout;
+-      struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+-      char *buff;
+-
+-      if (!mpe)
+-              return 1;
+-
+-      buff = set_value(strvec);
+-
+-      if (!buff)
+-              return 1;
+-      if (strlen(buff) == 4 && !strcmp(buff, "none"))
+-              mpe->pg_timeout = -PGTIMEOUT_NONE;
+-      else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
+-              if (pg_timeout == 0)
+-                      mpe->pg_timeout = -PGTIMEOUT_NONE;
+-              else
+-                      mpe->pg_timeout = pg_timeout;
+-      }
+-      else
+-              mpe->pg_timeout = PGTIMEOUT_UNDEF;
+-
+-      FREE(buff);
+       return 0;
+ }
+@@ -2180,16 +2113,6 @@ snprint_mp_rr_min_io_rq (char * buff, in
+ static int
+ snprint_mp_pg_timeout (char * buff, int len, void * data)
+ {
+-      struct mpentry * mpe = (struct mpentry *)data;
+-
+-      switch (mpe->pg_timeout) {
+-      case PGTIMEOUT_UNDEF:
+-              break;
+-      case -PGTIMEOUT_NONE:
+-              return snprintf(buff, len, "\"none\"");
+-      default:
+-              return snprintf(buff, len, "%i", mpe->pg_timeout);
+-      }
+       return 0;
+ }
+@@ -2551,19 +2474,6 @@ snprint_hw_rr_min_io_rq (char * buff, in
+ static int
+ snprint_hw_pg_timeout (char * buff, int len, void * data)
+ {
+-      struct hwentry * hwe = (struct hwentry *)data;
+-
+-      if (!hwe->pg_timeout)
+-              return 0;
+-
+-      switch (hwe->pg_timeout) {
+-      case PGTIMEOUT_UNDEF:
+-              break;
+-      case -PGTIMEOUT_NONE:
+-              return snprintf(buff, len, "\"none\"");
+-      default:
+-              return snprintf(buff, len, "%i", hwe->pg_timeout);
+-      }
+       return 0;
+ }
+@@ -2895,13 +2805,6 @@ snprint_def_checker_timeout (char *buff,
+ static int
+ snprint_def_pg_timeout (char * buff, int len, void * data)
+ {
+-      switch (conf->pg_timeout) {
+-      case PGTIMEOUT_UNDEF:
+-      case -PGTIMEOUT_NONE:
+-              return snprintf(buff, len, "\"none\"");
+-      default:
+-              return snprintf(buff, len, "%i", conf->pg_timeout);
+-      }
+       return 0;
+ }
diff --git a/multipath-tools/patches/0112-RHBZ-1194917-add-config_dir-option.patch b/multipath-tools/patches/0112-RHBZ-1194917-add-config_dir-option.patch
new file mode 100644 (file)
index 0000000..e322614
--- /dev/null
@@ -0,0 +1,616 @@
+---
+ libmultipath/config.c      |   56 +++++++++++++++++++++++++++++++-
+ libmultipath/config.h      |    2 +
+ libmultipath/defaults.h    |    1 
+ libmultipath/dict.c        |   69 +++++++++++++++++++++++++++++++++++----
+ libmultipath/parser.c      |   78 +++++++++++++++++++++++----------------------
+ libmultipath/parser.h      |    3 -
+ multipath.conf.annotated   |   10 +++++
+ multipath.conf.defaults    |    1 
+ multipath/multipath.conf.5 |    7 ++++
+ 9 files changed, 179 insertions(+), 48 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/parser.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/parser.c
++++ multipath-tools-130222/libmultipath/parser.c
+@@ -18,6 +18,7 @@
+  */
+ #include <syslog.h>
++#include <errno.h>
+ #include "parser.h"
+ #include "memory.h"
+@@ -453,14 +454,15 @@ set_value(vector strvec)
+ /* non-recursive configuration stream handler */
+ static int kw_level = 0;
+-int warn_on_duplicates(vector uniques, char *str)
++int warn_on_duplicates(vector uniques, char *str, char *file)
+ {
+       char *tmp;
+       int i;
+       vector_foreach_slot(uniques, tmp, i) {
+               if (!strcmp(str, tmp)) {
+-                      condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str);
++                      condlog(1, "%s line %d, duplicate keyword: %s",
++                              file, line_nr, str);
+                       return 0;
+               }
+       }
+@@ -496,65 +498,70 @@ is_sublevel_keyword(char *str)
+ }
+ int
+-validate_config_strvec(vector strvec)
++validate_config_strvec(vector strvec, char *file)
+ {
+       char *str;
+       int i;
+       str = VECTOR_SLOT(strvec, 0);
+       if (str == NULL) {
+-              condlog(0, "can't parse option on line %d of config file",
+-                      line_nr);
++              condlog(0, "can't parse option on line %d of %s",
++                      line_nr, file);
+       return -1;
+       }
+       if (*str == '}') {
+               if (VECTOR_SIZE(strvec) > 1)
+-                      condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr);
++                      condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 1), line_nr, file);
+               return 0;
+       }
+       if (*str == '{') {
+-              condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr);
++              condlog(0, "invalid keyword '%s' on line %d of %s",
++                      str, line_nr, file);
+               return -1;
+       }
+       if (is_sublevel_keyword(str)) {
+               str = VECTOR_SLOT(strvec, 1);
+               if (str == NULL)
+-                      condlog(0, "missing '{' on line %d of config file", line_nr);
++                      condlog(0, "missing '{' on line %d of %s",
++                              line_nr, file);
+               else if (*str != '{')
+-                      condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str);
++                      condlog(0, "expecting '{' on line %d of %s. found '%s'",
++                              line_nr, file, str);
+               else if (VECTOR_SIZE(strvec) > 2)
+-                      condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
++                      condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file);
+               return 0;
+       }
+       str = VECTOR_SLOT(strvec, 1);
+       if (str == NULL) {
+-              condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr);
++              condlog(0, "missing value for option '%s' on line %d of %s",
++                      (char *)VECTOR_SLOT(strvec, 0), line_nr, file);
+               return -1;
+       }
+       if (*str != '"') {
+               if (VECTOR_SIZE(strvec) > 2)
+-                      condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
++                      condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file);
+               return 0;
+       }
+       for (i = 2; i < VECTOR_SIZE(strvec); i++) {
+               str = VECTOR_SLOT(strvec, i);
+               if (str == NULL) {
+-                      condlog(0, "can't parse value on line %d of config file", line_nr);
++                      condlog(0, "can't parse value on line %d of %s",
++                              line_nr, file);
+                       return -1;
+               }
+               if (*str == '"') {
+                       if (VECTOR_SIZE(strvec) > i + 1)
+-                              condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr);
++                              condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr, file);
+                       return 0;
+               }
+       }
+-      condlog(0, "missing closing quotes on line %d of config file",
+-              line_nr);
++      condlog(0, "missing closing quotes on line %d of %s",
++              line_nr, file);
+       return 0;
+ }
+-int
+-process_stream(vector keywords)
++static int
++process_stream(vector keywords, char *file)
+ {
+       int i;
+       int r = 0;
+@@ -583,7 +590,7 @@ process_stream(vector keywords)
+               if (!strvec)
+                       continue;
+-              if (validate_config_strvec(strvec) != 0) {
++              if (validate_config_strvec(strvec, file) != 0) {
+                       free_strvec(strvec);
+                       continue;
+               }
+@@ -595,8 +602,8 @@ process_stream(vector keywords)
+                               free_strvec(strvec);
+                               break;
+                       }
+-                      condlog(0, "unmatched '%s' at line %d of config file",
+-                              EOB, line_nr);
++                      condlog(0, "unmatched '%s' at line %d of %s",
++                              EOB, line_nr, file);
+               }
+               for (i = 0; i < VECTOR_SIZE(keywords); i++) {
+@@ -604,7 +611,7 @@ process_stream(vector keywords)
+                       if (!strcmp(keyword->string, str)) {
+                               if (keyword->unique &&
+-                                  warn_on_duplicates(uniques, str)) {
++                                  warn_on_duplicates(uniques, str, file)) {
+                                               r = 1;
+                                               free_strvec(strvec);
+                                               goto out;
+@@ -614,15 +621,15 @@ process_stream(vector keywords)
+                               if (keyword->sub) {
+                                       kw_level++;
+-                                      r += process_stream(keyword->sub);
++                                      r += process_stream(keyword->sub, file);
+                                       kw_level--;
+                               }
+                               break;
+                       }
+               }
+               if (i >= VECTOR_SIZE(keywords))
+-                      condlog(1, "multipath.conf +%d, invalid keyword: %s",
+-                              line_nr, str);
++                      condlog(1, "%s line %d, invalid keyword: %s",
++                              file, line_nr, str);
+               free_strvec(strvec);
+       }
+@@ -646,27 +653,24 @@ int alloc_keywords(void)
+ /* Data initialization */
+ int
+-init_data(char *conf_file, void (*init_keywords) (void))
++process_file(char *file)
+ {
+       int r;
+-      stream = fopen(conf_file, "r");
++      if (!keywords) {
++              condlog(0, "No keywords alocated");
++              return 1;
++      }
++      stream = fopen(file, "r");
+       if (!stream) {
+-              syslog(LOG_WARNING, "Configuration file open problem");
++              condlog(0, "couldn't open configuration file '%s': %s",
++                      file, strerror(errno));
+               return 1;
+       }
+-      /* Init Keywords structure */
+-      (*init_keywords) ();
+-
+-/* Dump configuration *
+-  vector_dump(keywords);
+-  dump_keywords(keywords, 0);
+-*/
+-
+       /* Stream handling */
+       line_nr = 0;
+-      r = process_stream(keywords);
++      r = process_stream(keywords, file);
+       fclose(stream);
+       //free_keywords(keywords);
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -117,6 +117,8 @@ reassign_maps_handler(vector strvec)
+ static int
+ multipath_dir_handler(vector strvec)
+ {
++      if (conf->multipath_dir)
++              FREE(conf->multipath_dir);
+       conf->multipath_dir = set_value(strvec);
+       if (!conf->multipath_dir)
+@@ -128,6 +130,8 @@ multipath_dir_handler(vector strvec)
+ static int
+ def_selector_handler(vector strvec)
+ {
++      if (conf->selector)
++              FREE(conf->selector);
+       conf->selector = set_value(strvec);
+       if (!conf->selector)
+@@ -155,6 +159,8 @@ def_pgpolicy_handler(vector strvec)
+ static int
+ def_uid_attribute_handler(vector strvec)
+ {
++      if (conf->uid_attribute)
++              FREE(conf->uid_attribute);
+       conf->uid_attribute = set_value(strvec);
+       if (!conf->uid_attribute)
+@@ -166,6 +172,8 @@ def_uid_attribute_handler(vector strvec)
+ static int
+ def_prio_handler(vector strvec)
+ {
++      if (conf->prio_name)
++              FREE(conf->prio_name);
+       conf->prio_name = set_value(strvec);
+       if (!conf->prio_name)
+@@ -177,6 +185,8 @@ def_prio_handler(vector strvec)
+ static int
+ def_alias_prefix_handler(vector strvec)
+ {
++      if (conf->alias_prefix)
++              FREE(conf->alias_prefix);
+       conf->alias_prefix = set_value(strvec);
+       if (!conf->alias_prefix)
+@@ -188,6 +198,8 @@ def_alias_prefix_handler(vector strvec)
+ static int
+ def_prio_args_handler(vector strvec)
+ {
++      if (conf->prio_args)
++              FREE(conf->prio_args);
+       conf->prio_args = set_value(strvec);
+       if (!conf->prio_args)
+@@ -199,6 +211,8 @@ def_prio_args_handler(vector strvec)
+ static int
+ def_features_handler(vector strvec)
+ {
++      if (conf->features)
++              FREE(conf->features);
+       conf->features = set_value(strvec);
+       if (!conf->features)
+@@ -210,6 +224,8 @@ def_features_handler(vector strvec)
+ static int
+ def_path_checker_handler(vector strvec)
+ {
++      if (conf->checker_name)
++              FREE(conf->checker_name);
+       conf->checker_name = set_value(strvec);
+       if (!conf->checker_name)
+@@ -432,6 +448,23 @@ def_no_path_retry_handler(vector strvec)
+       return 0;
+ }
++
++static int
++def_config_dir_handler(vector strvec)
++{
++      /* this is only valid in the main config file */
++      if (conf->processed_main_config)
++              return 0;
++      if (conf->config_dir)
++              FREE(conf->config_dir);
++      conf->config_dir = set_value(strvec);
++
++      if (!conf->config_dir)
++              return 1;
++
++      return 0;
++}
++
+ static int
+ def_queue_without_daemon(vector strvec)
+ {
+@@ -611,6 +644,8 @@ def_names_handler(vector strvec)
+ static int
+ bindings_file_handler(vector strvec)
+ {
++      if (conf->bindings_file)
++              FREE(conf->bindings_file);
+       conf->bindings_file = set_value(strvec);
+       if (!conf->bindings_file)
+@@ -622,6 +657,8 @@ bindings_file_handler(vector strvec)
+ static int
+ wwids_file_handler(vector strvec)
+ {
++      if (conf->wwids_file)
++              FREE(conf->wwids_file);
+       conf->wwids_file = set_value(strvec);
+       if (!conf->wwids_file)
+@@ -770,9 +807,12 @@ def_ignore_new_boot_devs_handler(vector
+ static int
+ blacklist_handler(vector strvec)
+ {
+-      conf->blist_devnode = vector_alloc();
+-      conf->blist_wwid = vector_alloc();
+-      conf->blist_device = vector_alloc();
++      if (!conf->blist_devnode)
++              conf->blist_devnode = vector_alloc();
++      if (!conf->blist_wwid)
++              conf->blist_wwid = vector_alloc();
++      if (!conf->blist_device)
++              conf->blist_device = vector_alloc();
+       if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device)
+               return 1;
+@@ -783,9 +823,12 @@ blacklist_handler(vector strvec)
+ static int
+ blacklist_exceptions_handler(vector strvec)
+ {
+-      conf->elist_devnode = vector_alloc();
+-      conf->elist_wwid = vector_alloc();
+-      conf->elist_device = vector_alloc();
++      if (!conf->elist_devnode)
++              conf->elist_devnode = vector_alloc();
++      if (!conf->elist_wwid)
++              conf->elist_wwid = vector_alloc();
++      if (!conf->elist_device)
++              conf->elist_device = vector_alloc();
+       if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device)
+               return 1;
+@@ -1480,7 +1523,8 @@ hw_deferred_remove_handler(vector strvec
+ static int
+ multipaths_handler(vector strvec)
+ {
+-      conf->mptable = vector_alloc();
++      if (!conf->mptable)
++              conf->mptable = vector_alloc();
+       if (!conf->mptable)
+               return 1;
+@@ -2945,6 +2989,16 @@ snprint_def_ignore_new_boot_devs(char *
+               return snprintf(buff, len, "no");
+ }
++
++static int
++snprint_def_config_dir (char * buff, int len, void * data)
++{
++      if (!conf->config_dir)
++              return 0;
++
++      return snprintf(buff, len, "\"%s\"", conf->config_dir);
++}
++
+ static int
+ snprint_ble_simple (char * buff, int len, void * data)
+ {
+@@ -3016,6 +3070,7 @@ init_keywords(void)
+       install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
+       install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
+       install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
++      install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
+       __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
+Index: multipath-tools-130222/libmultipath/parser.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/parser.h
++++ multipath-tools-130222/libmultipath/parser.h
+@@ -76,9 +76,8 @@ extern int read_line(char *buf, int size
+ extern vector read_value_block(void);
+ 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 int process_file(char *conf_file);
+ extern struct keyword * find_keyword(vector v, char * name);
+ void set_current_keywords (vector *k);
+ int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -6,6 +6,9 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <libudev.h>
++#include <dirent.h>
++#include <limits.h>
++#include <errno.h>
+ #include "checkers.h"
+ #include "memory.h"
+@@ -556,6 +559,7 @@ free_config (struct config * conf)
+       if (conf->wwids_file)
+               FREE(conf->wwids_file);
++
+       if (conf->prio_name)
+               FREE(conf->prio_name);
+@@ -567,6 +571,10 @@ free_config (struct config * conf)
+       if (conf->checker_name)
+               FREE(conf->checker_name);
++
++      if (conf->config_dir)
++              FREE(conf->config_dir);
++
+       if (conf->reservation_key)
+               FREE(conf->reservation_key);
+@@ -584,6 +592,43 @@ free_config (struct config * conf)
+       FREE(conf);
+ }
++/* if multipath fails to process the config directory, it should continue,
++ * with just a warning message */
++static void
++process_config_dir(vector keywords, char *dir)
++{
++      struct dirent **namelist;
++      int i, n;
++      char path[LINE_MAX];
++      int old_hwtable_size;
++
++      if (dir[0] != '/') {
++              condlog(1, "config_dir '%s' must be a fully qualified path",
++                      dir);
++              return;
++      }
++      n = scandir(dir, &namelist, NULL, alphasort);
++      if (n < 0) {
++              if (errno == ENOENT)
++                      condlog(3, "No configuration dir '%s'", dir);
++              else
++                      condlog(0, "couldn't open configuration dir '%s': %s",
++                              dir, strerror(errno));
++              return;
++      }
++      for (i = 0; i < n; i++) {
++              if (!strstr(namelist[i]->d_name, ".conf"))
++                      continue;
++              old_hwtable_size = VECTOR_SIZE(conf->hwtable);
++              snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name);
++              path[LINE_MAX-1] = '\0';
++              process_file(path);
++              if (VECTOR_SIZE(conf->hwtable) > old_hwtable_size)
++                      factorize_hwtable(conf->hwtable, old_hwtable_size);
++
++      }
++}
++
+ int
+ load_config (char * file, struct udev *udev)
+ {
+@@ -623,6 +668,7 @@ load_config (char * file, struct udev *u
+       conf->hw_strmatch = 0;
+       conf->force_sync = 0;
+       conf->ignore_new_boot_devs = 0;
++      conf->processed_main_config = 0;
+       /*
+        * preload default hwtable
+@@ -641,11 +687,12 @@ load_config (char * file, struct udev *u
+        */
+       set_current_keywords(&conf->keywords);
+       alloc_keywords();
++      init_keywords();
+       if (filepresent(file)) {
+               int builtin_hwtable_size;
+               builtin_hwtable_size = VECTOR_SIZE(conf->hwtable);
+-              if (init_data(file, init_keywords)) {
++              if (process_file(file)) {
+                       condlog(0, "error parsing config file");
+                       goto out;
+               }
+@@ -658,7 +705,6 @@ load_config (char * file, struct udev *u
+               }
+       } else {
+-              init_keywords();
+               condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
+               condlog(0, "A default multipath.conf file is located at");
+               condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
+@@ -677,6 +723,12 @@ load_config (char * file, struct udev *u
+               }
+       }
++      conf->processed_main_config = 1;
++      if (conf->config_dir == NULL)
++              conf->config_dir = set_default(DEFAULT_CONFIG_DIR);
++      if (conf->config_dir && conf->config_dir[0] != '\0')
++              process_config_dir(conf->keywords, conf->config_dir);
++
+       /*
+        * fill the voids left in the config file
+        */
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -132,6 +132,7 @@ struct config {
+       int force_sync;
+       int deferred_remove;
+       int ignore_new_boot_devs;
++      int processed_main_config;
+       unsigned int version[3];
+       char * dev;
+@@ -147,6 +148,7 @@ struct config {
+       char * prio_args;
+       char * checker_name;
+       char * alias_prefix;
++      char * config_dir;
+       unsigned char * reservation_key;
+       vector keywords;
+Index: multipath-tools-130222/libmultipath/defaults.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/defaults.h
++++ multipath-tools-130222/libmultipath/defaults.h
+@@ -31,5 +31,6 @@
+ #define DEFAULT_CONFIGFILE    "/etc/multipath.conf"
+ #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
+ #define DEFAULT_WWIDS_FILE    "/etc/multipath/wwids"
++#define DEFAULT_CONFIG_DIR    "/etc/multipath/conf.d"
+ char * set_default (char * str);
+Index: multipath-tools-130222/multipath.conf.annotated
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.annotated
++++ multipath-tools-130222/multipath.conf.annotated
+@@ -232,6 +232,16 @@
+ #     # values  : yes|no
+ #     # default : no
+ #     force_sync yes
++#
++#     #
++#     # name    : config_dir
++#     # scope   : multipath & multipathd
++#     # desc    : If not set to an empty string, multipath will search
++#     #           this directory alphabetically for files ending in ".conf"
++#     #           and it will read configuration information from these
++#     #           files, just as if it was in /etc/multipath.conf
++#     # values  : "" or a fully qualified pathname
++#     # default : "/etc/multipath/conf.d"
+ #}
+ #     
+ ##
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -26,6 +26,7 @@
+ #     log_checker_err always
+ #     retain_attached_hw_handler no
+ #     detect_prio no
++#     config_dir "/etc/multipath/conf.d"
+ #}
+ #blacklist {
+ #     devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -430,6 +430,13 @@ still in use, it will be freed when the
+ to the multipath device before the last user closes it, the deferred remove
+ will be canceled. Default is
+ .I no
++.TP
++.B config_dir
++If set to anything other than "", multipath will search this directory
++alphabetically for file ending in ".conf" and it will read configuration
++information from them, just as if it was in /etc/multipath.conf.  config_dir
++must either be "" or a fully qualified directory name. Default is
++.I "/etc/multipath/conf.d"
+ .
+ .SH "blacklist section"
+ The
diff --git a/multipath-tools/patches/0113-RHBZ-1194917-cleanup.patch b/multipath-tools/patches/0113-RHBZ-1194917-cleanup.patch
new file mode 100644 (file)
index 0000000..cf95c98
--- /dev/null
@@ -0,0 +1,185 @@
+---
+ libmultipath/parser.c |  103 +++-----------------------------------------------
+ libmultipath/parser.h |    6 --
+ 2 files changed, 8 insertions(+), 101 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/parser.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/parser.c
++++ multipath-tools-130222/libmultipath/parser.c
+@@ -280,8 +280,8 @@ out:
+       return NULL;
+ }
+-int
+-read_line(char *buf, int size)
++static int
++read_line(FILE *stream, char *buf, int size)
+ {
+       int ch;
+       int count = 0;
+@@ -297,95 +297,6 @@ read_line(char *buf, int size)
+       return (ch == EOF) ? 0 : 1;
+ }
+-vector
+-read_value_block(void)
+-{
+-      char *buf;
+-      int i;
+-      char *str = NULL;
+-      char *dup;
+-      vector vec = NULL;
+-      vector elements = vector_alloc();
+-
+-      if (!elements)
+-              return NULL;
+-
+-      buf = (char *) MALLOC(MAXBUF);
+-
+-      if (!buf) {
+-              vector_free(elements);
+-              return NULL;
+-      }
+-
+-      while (read_line(buf, MAXBUF)) {
+-              vec = alloc_strvec(buf);
+-              if (vec) {
+-                      str = VECTOR_SLOT(vec, 0);
+-                      if (!strcmp(str, EOB)) {
+-                              free_strvec(vec);
+-                              break;
+-                      }
+-
+-                      for (i = 0; i < VECTOR_SIZE(vec); i++) {
+-                              str = VECTOR_SLOT(vec, i);
+-                              dup = (char *) MALLOC(strlen(str) + 1);
+-                              if (!dup)
+-                                      goto out;
+-                              memcpy(dup, str, strlen(str));
+-
+-                              if (!vector_alloc_slot(elements)) {
+-                                      free_strvec(vec);
+-                                      goto out1;
+-                              }
+-
+-                              vector_set_slot(elements, dup);
+-                      }
+-                      free_strvec(vec);
+-              }
+-              memset(buf, 0, MAXBUF);
+-      }
+-      FREE(buf);
+-      return elements;
+-out1:
+-      FREE(dup);
+-out:
+-      FREE(buf);
+-      vector_free(elements);
+-      return NULL;
+-}
+-
+-int
+-alloc_value_block(vector strvec, void (*alloc_func) (vector))
+-{
+-      char *buf;
+-      char *str = NULL;
+-      vector vec = NULL;
+-
+-      buf = (char *) MALLOC(MAXBUF);
+-
+-      if (!buf)
+-              return 1;
+-
+-      while (read_line(buf, MAXBUF)) {
+-              vec = alloc_strvec(buf);
+-              if (vec) {
+-                      str = VECTOR_SLOT(vec, 0);
+-                      if (!strcmp(str, EOB)) {
+-                              free_strvec(vec);
+-                              break;
+-                      }
+-
+-                      if (VECTOR_SIZE(vec))
+-                              (*alloc_func) (vec);
+-
+-                      free_strvec(vec);
+-              }
+-              memset(buf, 0, MAXBUF);
+-      }
+-      FREE(buf);
+-      return 0;
+-}
+-
+ void *
+ set_value(vector strvec)
+ {
+@@ -561,7 +472,7 @@ validate_config_strvec(vector strvec, ch
+ }
+ static int
+-process_stream(vector keywords, char *file)
++process_stream(FILE *stream, vector keywords, char *file)
+ {
+       int i;
+       int r = 0;
+@@ -582,7 +493,7 @@ process_stream(vector keywords, char *fi
+               return 1;
+       }
+-      while (read_line(buf, MAXBUF)) {
++      while (read_line(stream, buf, MAXBUF)) {
+               line_nr++;
+               strvec = alloc_strvec(buf);
+               memset(buf,0, MAXBUF);
+@@ -621,7 +532,8 @@ process_stream(vector keywords, char *fi
+                               if (keyword->sub) {
+                                       kw_level++;
+-                                      r += process_stream(keyword->sub, file);
++                                      r += process_stream(stream,
++                                                          keyword->sub, file);
+                                       kw_level--;
+                               }
+                               break;
+@@ -656,6 +568,7 @@ int
+ process_file(char *file)
+ {
+       int r;
++      FILE *stream;
+       if (!keywords) {
+               condlog(0, "No keywords alocated");
+@@ -670,7 +583,7 @@ process_file(char *file)
+       /* Stream handling */
+       line_nr = 0;
+-      r = process_stream(keywords, file);
++      r = process_stream(stream, keywords, file);
+       fclose(stream);
+       //free_keywords(keywords);
+Index: multipath-tools-130222/libmultipath/parser.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/parser.h
++++ multipath-tools-130222/libmultipath/parser.h
+@@ -47,9 +47,6 @@ struct keyword {
+       int unique;
+ };
+-/* global var exported */
+-FILE *stream;
+-
+ /* Reloading helpers */
+ #define SET_RELOAD      (reload = 1)
+ #define UNSET_RELOAD    (reload = 0)
+@@ -72,9 +69,6 @@ extern int _install_keyword(char *string
+ extern void dump_keywords(vector keydump, int level);
+ extern void free_keywords(vector keywords);
+ extern vector alloc_strvec(char *string);
+-extern int read_line(char *buf, int size);
+-extern vector read_value_block(void);
+-extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
+ extern void *set_value(vector strvec);
+ extern int alloc_keywords(void);
+ extern int process_file(char *conf_file);
diff --git a/multipath-tools/patches/0114-RHBZ-1196394-delayed-reintegration.patch b/multipath-tools/patches/0114-RHBZ-1196394-delayed-reintegration.patch
new file mode 100644 (file)
index 0000000..78e43ee
--- /dev/null
@@ -0,0 +1,744 @@
+---
+ libmultipath/checkers.c    |    3 
+ libmultipath/checkers.h    |    9 +
+ libmultipath/config.c      |    4 
+ libmultipath/config.h      |    6 +
+ libmultipath/configure.c   |    2 
+ libmultipath/defaults.h    |    1 
+ libmultipath/dict.c        |  204 ++++++++++++++++++++++++++++++++++++++++++++-
+ libmultipath/print.c       |    2 
+ libmultipath/propsel.c     |   52 +++++++++++
+ libmultipath/propsel.h     |    2 
+ libmultipath/structs.h     |    9 +
+ multipath.conf.annotated   |   40 ++++++++
+ multipath.conf.defaults    |    2 
+ multipath/multipath.conf.5 |   27 +++++
+ multipathd/main.c          |   34 ++++++-
+ 15 files changed, 388 insertions(+), 9 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -62,6 +62,8 @@ struct hwentry {
+       int retain_hwhandler;
+       int detect_prio;
+       int deferred_remove;
++      int delay_watch_checks;
++      int delay_wait_checks;
+       char * bl_product;
+ };
+@@ -86,6 +88,8 @@ struct mpentry {
+       int attribute_flags;
+       int user_friendly_names;
+       int deferred_remove;
++      int delay_watch_checks;
++      int delay_wait_checks;
+       uid_t uid;
+       gid_t gid;
+       mode_t mode;
+@@ -133,6 +137,8 @@ struct config {
+       int deferred_remove;
+       int ignore_new_boot_devs;
+       int processed_main_config;
++      int delay_watch_checks;
++      int delay_wait_checks;
+       unsigned int version[3];
+       char * dev;
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -134,6 +134,11 @@ enum scsi_protocol {
+       SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */
+ };
++enum delay_checks_states {
++      DELAY_CHECKS_OFF = -1,
++      DELAY_CHECKS_UNDEF = 0,
++};
++
+ struct sg_id {
+       int host_no;
+       int channel;
+@@ -180,6 +185,8 @@ struct path {
+       int priority;
+       int pgindex;
+       int detect_prio;
++      int watch_checks;
++      int wait_checks;
+       char * uid_attribute;
+       struct prio prio;
+       char * prio_args;
+@@ -215,6 +222,8 @@ struct multipath {
+       int fast_io_fail;
+       int retain_hwhandler;
+       int deferred_remove;
++      int delay_watch_checks;
++      int delay_wait_checks;
+       unsigned int dev_loss;
+       uid_t uid;
+       gid_t gid;
+Index: multipath-tools-130222/libmultipath/checkers.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers.h
++++ multipath-tools-130222/libmultipath/checkers.h
+@@ -46,6 +46,14 @@
+  * PATH_PENDING:
+  * - Use: All async checkers
+  * - Description: Indicates a check IO is in flight.
++ *
++ * PATH_DELAYED:
++ * - Use: None of the checkers (returned if the path is being delayed before
++ *   reintegration.
++ * - Description: If a path fails after being up for less than
++ *   delay_watch_checks checks, when it comes back up again, it will not
++ *   be marked as up until it has been up for delay_wait_checks checks.
++ *   During this time, it is marked as "delayed"
+  */
+ enum path_check_state {
+       PATH_WILD,
+@@ -55,6 +63,7 @@ enum path_check_state {
+       PATH_SHAKY,
+       PATH_GHOST,
+       PATH_PENDING,
++      PATH_DELAYED,
+       PATH_MAX_STATE
+ };
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -291,6 +291,8 @@ setup_map (struct multipath * mpp, char
+       select_reservation_key(mpp);
+       select_retain_hwhandler(mpp);
+       select_deferred_remove(mpp);
++      select_delay_watch_checks(mpp);
++      select_delay_wait_checks(mpp);
+       sysfs_set_scsi_tmo(mpp);
+       /*
+Index: multipath-tools-130222/libmultipath/defaults.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/defaults.h
++++ multipath-tools-130222/libmultipath/defaults.h
+@@ -20,6 +20,7 @@
+ #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
+ #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
+ #define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
++#define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF
+ #define DEFAULT_CHECKINT      5
+ #define MAX_CHECKINT(a)               (a << 2)
+Index: multipath-tools-130222/libmultipath/dict.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/dict.c
++++ multipath-tools-130222/libmultipath/dict.c
+@@ -801,6 +801,44 @@ def_ignore_new_boot_devs_handler(vector
+       return 0;
+ }
++static int
++def_delay_watch_checks_handler(vector strvec)
++{
++      char * buff;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              conf->delay_watch_checks = DELAY_CHECKS_OFF;
++      else if ((conf->delay_watch_checks = atoi(buff)) < 1)
++              conf->delay_watch_checks = DELAY_CHECKS_OFF;
++
++      FREE(buff);
++      return 0;
++}
++
++static int
++def_delay_wait_checks_handler(vector strvec)
++{
++      char * buff;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              conf->delay_wait_checks = DELAY_CHECKS_OFF;
++      else if ((conf->delay_wait_checks = atoi(buff)) < 1)
++              conf->delay_wait_checks = DELAY_CHECKS_OFF;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * blacklist block handlers
+  */
+@@ -1517,6 +1555,52 @@ hw_deferred_remove_handler(vector strvec
+       return 0;
+ }
++static int
++hw_delay_watch_checks_handler(vector strvec)
++{
++      struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
++      char * buff;
++
++      if (!hwe)
++              return 1;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              hwe->delay_watch_checks = DELAY_CHECKS_OFF;
++      else if ((hwe->delay_watch_checks = atoi(buff)) < 1)
++              hwe->delay_watch_checks = DELAY_CHECKS_OFF;
++
++      FREE(buff);
++      return 0;
++}
++
++static int
++hw_delay_wait_checks_handler(vector strvec)
++{
++      struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
++      char * buff;
++
++      if (!hwe)
++              return 1;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              hwe->delay_wait_checks = DELAY_CHECKS_OFF;
++      else if ((hwe->delay_wait_checks = atoi(buff)) < 1)
++              hwe->delay_wait_checks = DELAY_CHECKS_OFF;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * multipaths block handlers
+  */
+@@ -1996,6 +2080,52 @@ mp_deferred_remove_handler(vector strvec
+       return 0;
+ }
++static int
++mp_delay_watch_checks_handler(vector strvec)
++{
++      struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
++      char * buff;
++
++      if (!mpe)
++              return 1;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              mpe->delay_watch_checks = DELAY_CHECKS_OFF;
++      else if ((mpe->delay_watch_checks = atoi(buff)) < 1)
++              mpe->delay_watch_checks = DELAY_CHECKS_OFF;
++
++      FREE(buff);
++      return 0;
++}
++
++static int
++mp_delay_wait_checks_handler(vector strvec)
++{
++      struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
++      char * buff;
++
++      if (!mpe)
++              return 1;
++
++      buff = set_value(strvec);
++      if (!buff)
++              return 1;
++
++      if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++          (strlen(buff) == 1 && !strcmp(buff, "0")))
++              mpe->delay_wait_checks = DELAY_CHECKS_OFF;
++      else if ((mpe->delay_wait_checks = atoi(buff)) < 1)
++              mpe->delay_wait_checks = DELAY_CHECKS_OFF;
++
++      FREE(buff);
++      return 0;
++}
++
+ /*
+  * config file keywords printing
+  */
+@@ -2258,6 +2388,30 @@ snprint_mp_deferred_remove (char * buff,
+ }
+ static int
++snprint_mp_delay_watch_checks(char * buff, int len, void * data)
++{
++      struct mpentry * mpe = (struct mpentry *)data;
++
++      if (mpe->delay_watch_checks == DELAY_CHECKS_UNDEF)
++              return 0;
++      if (mpe->delay_watch_checks == DELAY_CHECKS_OFF)
++              return snprintf(buff, len, "no");
++      return snprintf(buff, len, "%d", mpe->delay_watch_checks);
++}
++
++static int
++snprint_mp_delay_wait_checks(char * buff, int len, void * data)
++{
++      struct mpentry * mpe = (struct mpentry *)data;
++
++      if (mpe->delay_wait_checks == DELAY_CHECKS_UNDEF)
++              return 0;
++      if (mpe->delay_wait_checks == DELAY_CHECKS_OFF)
++              return snprintf(buff, len, "no");
++      return snprintf(buff, len, "%d", mpe->delay_wait_checks);
++}
++
++static int
+ snprint_hw_fast_io_fail(char * buff, int len, void * data)
+ {
+       struct hwentry * hwe = (struct hwentry *)data;
+@@ -2586,6 +2740,30 @@ snprint_hw_deferred_remove(char * buff,
+ }
+ static int
++snprint_hw_delay_watch_checks(char * buff, int len, void * data)
++{
++      struct hwentry * hwe = (struct hwentry *)data;
++
++      if (hwe->delay_watch_checks == DELAY_CHECKS_UNDEF)
++              return 0;
++      if (hwe->delay_watch_checks == DELAY_CHECKS_OFF)
++              return snprintf(buff, len, "no");
++      return snprintf(buff, len, "%d", hwe->delay_watch_checks);
++}
++
++static int
++snprint_hw_delay_wait_checks(char * buff, int len, void * data)
++{
++      struct hwentry * hwe = (struct hwentry *)data;
++
++      if (hwe->delay_wait_checks == DELAY_CHECKS_UNDEF)
++              return 0;
++      if (hwe->delay_wait_checks == DELAY_CHECKS_OFF)
++              return snprintf(buff, len, "no");
++      return snprintf(buff, len, "%d", hwe->delay_wait_checks);
++}
++
++static int
+ snprint_detect_prio(char * buff, int len, void * data)
+ {
+       struct hwentry * hwe = (struct hwentry *)data;
+@@ -2883,7 +3061,6 @@ snprint_def_find_multipaths (char * buff
+       return snprintf(buff, len, "yes");
+ }
+-
+ static int
+ snprint_def_user_friendly_names (char * buff, int len, void * data)
+ {
+@@ -2989,7 +3166,6 @@ snprint_def_ignore_new_boot_devs(char *
+               return snprintf(buff, len, "no");
+ }
+-
+ static int
+ snprint_def_config_dir (char * buff, int len, void * data)
+ {
+@@ -3000,6 +3176,24 @@ snprint_def_config_dir (char * buff, int
+ }
+ static int
++snprint_def_delay_watch_checks(char * buff, int len, void * data)
++{
++      if (conf->delay_watch_checks == DELAY_CHECKS_UNDEF ||
++          conf->delay_watch_checks == DELAY_CHECKS_OFF)
++              return snprintf(buff, len, "no");
++      return snprintf(buff, len, "%d", conf->delay_watch_checks);
++}
++
++static int
++snprint_def_delay_wait_checks(char * buff, int len, void * data)
++{
++      if (conf->delay_wait_checks == DELAY_CHECKS_UNDEF ||
++          conf->delay_wait_checks == DELAY_CHECKS_OFF)
++              return snprintf(buff, len, "no");
++      return snprintf(buff, len, "%d", conf->delay_wait_checks);
++}
++
++static int
+ snprint_ble_simple (char * buff, int len, void * data)
+ {
+       struct blentry * ble = (struct blentry *)data;
+@@ -3071,6 +3265,8 @@ init_keywords(void)
+       install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
+       install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
+       install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
++      install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks);
++      install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
+       __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+       __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+       __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
+@@ -3136,6 +3332,8 @@ init_keywords(void)
+       install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
+       install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
+       install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
++      install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
++      install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
+       install_sublevel_end();
+       install_keyword_root("multipaths", &multipaths_handler);
+@@ -3161,5 +3359,7 @@ init_keywords(void)
+       install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
+       install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
+       install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
++      install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks);
++      install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks);
+       install_sublevel_end();
+ }
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -336,6 +336,8 @@ snprint_chk_state (char * buff, size_t l
+               return snprintf(buff, len, "shaky");
+       case PATH_GHOST:
+               return snprintf(buff, len, "ghost");
++      case PATH_DELAYED:
++              return snprintf(buff, len, "delayed");
+       default:
+               return snprintf(buff, len, "undef");
+       }
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -788,3 +788,55 @@ select_detect_prio (struct path * pp)
+       condlog(3, "%s: detect_prio = %d (compiled in default)", pp->dev, pp->detect_prio);
+       return 0;
+ }
++
++extern int
++select_delay_watch_checks (struct multipath * mp)
++{
++      if (mp->mpe && mp->mpe->delay_watch_checks != DELAY_CHECKS_UNDEF) {
++              mp->delay_watch_checks = mp->mpe->delay_watch_checks;
++              condlog(3, "delay_watch_checks = %i (multipath setting)",
++                              mp->delay_watch_checks);
++              return 0;
++      }
++      if (mp->hwe && mp->hwe->delay_watch_checks != DELAY_CHECKS_UNDEF) {
++              mp->delay_watch_checks = mp->hwe->delay_watch_checks;
++              condlog(3, "delay_watch_checks = %i (controler setting)",
++                              mp->delay_watch_checks);
++              return 0;
++      }
++      if (conf->delay_watch_checks != DELAY_CHECKS_UNDEF) {
++              mp->delay_watch_checks = conf->delay_watch_checks;
++              condlog(3, "delay_watch_checks = %i (config file default)",
++                              mp->delay_watch_checks);
++              return 0;
++      }
++      mp->delay_watch_checks = DEFAULT_DELAY_CHECKS;
++      condlog(3, "delay_watch_checks = DISABLED (internal default)");
++      return 0;
++}
++
++extern int
++select_delay_wait_checks (struct multipath * mp)
++{
++      if (mp->mpe && mp->mpe->delay_wait_checks != DELAY_CHECKS_UNDEF) {
++              mp->delay_wait_checks = mp->mpe->delay_wait_checks;
++              condlog(3, "delay_wait_checks = %i (multipath setting)",
++                              mp->delay_wait_checks);
++              return 0;
++      }
++      if (mp->hwe && mp->hwe->delay_wait_checks != DELAY_CHECKS_UNDEF) {
++              mp->delay_wait_checks = mp->hwe->delay_wait_checks;
++              condlog(3, "delay_wait_checks = %i (controler setting)",
++                              mp->delay_wait_checks);
++              return 0;
++      }
++      if (conf->delay_wait_checks != DELAY_CHECKS_UNDEF) {
++              mp->delay_wait_checks = conf->delay_wait_checks;
++              condlog(3, "delay_wait_checks = %i (config file default)",
++                              mp->delay_wait_checks);
++              return 0;
++      }
++      mp->delay_wait_checks = DEFAULT_DELAY_CHECKS;
++      condlog(3, "delay_wait_checks = DISABLED (internal default)");
++      return 0;
++}
+Index: multipath-tools-130222/libmultipath/propsel.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.h
++++ multipath-tools-130222/libmultipath/propsel.h
+@@ -21,3 +21,5 @@ int select_reservation_key(struct multip
+ int select_retain_hwhandler (struct multipath * mp);
+ int select_detect_prio(struct path * pp);
+ int select_deferred_remove(struct multipath *mp);
++int select_delay_watch_checks (struct multipath * mp);
++int select_delay_wait_checks (struct multipath * mp);
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -188,7 +188,8 @@ sync_map_state(struct multipath *mpp)
+       vector_foreach_slot (mpp->pg, pgp, i){
+               vector_foreach_slot (pgp->paths, pp, j){
+                       if (pp->state == PATH_UNCHECKED || 
+-                          pp->state == PATH_WILD)
++                          pp->state == PATH_WILD ||
++                          pp->state == PATH_DELAYED)
+                               continue;
+                       if ((pp->dmstate == PSTATE_FAILED ||
+                            pp->dmstate == PSTATE_UNDEF) &&
+@@ -1165,6 +1166,16 @@ check_path (struct vectors * vecs, struc
+       if (!pp->mpp)
+               return;
++      if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
++           pp->wait_checks > 0) {
++              if (pp->mpp && pp->mpp->nr_active > 0) {
++                      pp->state = PATH_DELAYED;
++                      pp->wait_checks--;
++                      return;
++              } else
++                      pp->wait_checks = 0;
++      }
++
+       pp->chkrstate = newstate;
+       if (newstate != pp->state) {
+               int oldstate = pp->state;
+@@ -1182,9 +1193,14 @@ check_path (struct vectors * vecs, struc
+                        * proactively fail path in the DM
+                        */
+                       if (oldstate == PATH_UP ||
+-                          oldstate == PATH_GHOST)
++                          oldstate == PATH_GHOST) {
+                               fail_path(pp, 1);
+-                      else
++                              if (pp->mpp->delay_wait_checks > 0 &&
++                                  pp->watch_checks > 0) {
++                                      pp->wait_checks = pp->mpp->delay_wait_checks;
++                                      pp->watch_checks = 0;
++                              }
++                      }else
+                               fail_path(pp, 0);
+                       /*
+@@ -1211,11 +1227,15 @@ check_path (struct vectors * vecs, struc
+                * reinstate this path
+                */
+               if (oldstate != PATH_UP &&
+-                  oldstate != PATH_GHOST)
++                  oldstate != PATH_GHOST) {
++                      if (pp->mpp->delay_watch_checks > 0)
++                              pp->watch_checks = pp->mpp->delay_watch_checks;
+                       reinstate_path(pp, 1);
+-              else
++              } else {
++                      if (pp->watch_checks > 0)
++                              pp->watch_checks--;
+                       reinstate_path(pp, 0);
+-
++              }
+               new_path_up = 1;
+               if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
+@@ -1245,6 +1265,8 @@ check_path (struct vectors * vecs, struc
+                               else
+                                       pp->checkint = conf->max_checkint;
+                       }
++                      if (pp->watch_checks > 0)
++                              pp->watch_checks--;
+                       pp->tick = pp->checkint;
+                       condlog(4, "%s: delay next check %is",
+                               pp->dev_t, pp->tick);
+Index: multipath-tools-130222/multipath.conf.annotated
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.annotated
++++ multipath-tools-130222/multipath.conf.annotated
+@@ -242,6 +242,30 @@
+ #     #           files, just as if it was in /etc/multipath.conf
+ #     # values  : "" or a fully qualified pathname
+ #     # default : "/etc/multipath/conf.d"
++#
++#     #
++#     # name    : delay_watch_checks
++#     # scope   : multipathd
++#     # desc    : If set to a value greater than 0, multipathd will watch
++#     #           paths that have recently become valid for this many
++#     #           checks.  If they fail again while they are being watched,
++#     #           when they next become valid, they will not be used until
++#     #           they have stayed up for delay_wait_checks checks.
++#     # values  : no|<n> > 0
++#     # default : no
++#     delay_watch_checks 12
++#
++#     #
++#     # name    : delay_wait_checks
++#     # scope   : multipathd
++#     # desc    : If set to a value greater than 0, when a device that has
++#     #           recently come back online fails again within
++#     #           delay_watch_checks checks, the next time it comes back
++#     #           online, it will marked and delayed, and not used until
++#     #           it has passed delay_wait_checks checks.
++#     # values  : no|<n> > 0
++#     # default : no
++#     delay_wait_checks 12
+ #}
+ #     
+ ##
+@@ -383,6 +407,13 @@
+ #             #
+ #             flush_on_last_del       yes
+ #
++#             #
++#             # name    : delay_watch_checks
++#             # See defualts section for information.
++#
++#             #
++#             # name    : delay_wait_checks
++#             # See defualts section for information.
+ #     }
+ #     multipath {
+ #             wwid    1DEC_____321816758474
+@@ -566,6 +597,15 @@
+ #             #           before removing it from the system.
+ #             # values  : n > 0
+ #             dev_loss_tmo 600
++#
++#             #
++#             # name    : delay_watch_checks
++#             # See defaults section for information.
++#
++#             #
++#             # name    : delay_wait_checks
++#             # See defaults section for information.
++#
+ #     }
+ #     device {
+ #             vendor                  "COMPAQ  "
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -27,6 +27,8 @@
+ #     retain_attached_hw_handler no
+ #     detect_prio no
+ #     config_dir "/etc/multipath/conf.d"
++#     delay_watch_checks no
++#     delay_wait_checks no
+ #}
+ #blacklist {
+ #     devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -437,6 +437,25 @@ alphabetically for file ending in ".conf
+ information from them, just as if it was in /etc/multipath.conf.  config_dir
+ must either be "" or a fully qualified directory name. Default is
+ .I "/etc/multipath/conf.d"
++.TP
++.B delay_watch_checks
++If set to a value greater than 0, multipathd will watch paths that have
++recently become valid for this many checks.  If they fail again while they are
++being watched, when they next become valid, they will not be used until they
++have stayed up for
++.I delay_wait_checks
++checks. Default is
++.I no
++.TP
++.B delay_wait_checks
++If set to a value greater than 0, when a device that has recently come back
++online fails again within
++.I delay_watch_checks
++checks, the next time it comes back online, it will marked and delayed, and not
++used until it has passed
++.I delay_wait_checks
++checks. Default is
++.I no
+ .
+ .SH "blacklist section"
+ The
+@@ -540,6 +559,10 @@ section:
+ .B reservation_key
+ .TP
+ .B deferred_remove
++.TP
++.B delay_watch_checks
++.TP
++.B delay_wait_checks
+ .RE
+ .PD
+ .LP
+@@ -632,6 +655,10 @@ section:
+ .B detect_prio
+ .TP
+ .B deferred_remove
++.TP
++.B delay_watch_checks
++.TP
++.B delay_wait_checks
+ .RE
+ .PD
+ .LP
+Index: multipath-tools-130222/libmultipath/checkers.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers.c
++++ multipath-tools-130222/libmultipath/checkers.c
+@@ -16,7 +16,8 @@ char *checker_state_names[] = {
+       "up",
+       "shaky",
+       "ghost",
+-      "pending"
++      "pending",
++      "delayed"
+ };
+ static LIST_HEAD(checkers);
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -341,6 +341,8 @@ merge_hwe (struct hwentry * dst, struct
+       merge_num(retain_hwhandler);
+       merge_num(detect_prio);
+       merge_num(deferred_remove);
++      merge_num(delay_watch_checks);
++      merge_num(delay_wait_checks);
+       /*
+        * Make sure features is consistent with
+@@ -399,6 +401,8 @@ overwrite_hwe (struct hwentry * dst, str
+       overwrite_num(retain_hwhandler);
+       overwrite_num(detect_prio);
+       overwrite_num(deferred_remove);
++      overwrite_num(delay_watch_checks);
++      overwrite_num(delay_wait_checks);
+       /*
+        * Make sure features is consistent with
diff --git a/multipath-tools/patches/0115-RHBZ-1198418-fix-double-free.patch b/multipath-tools/patches/0115-RHBZ-1198418-fix-double-free.patch
new file mode 100644 (file)
index 0000000..a403760
--- /dev/null
@@ -0,0 +1,28 @@
+---
+ multipathd/main.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -310,10 +310,15 @@ ev_add_map (char * dev, char * alias, st
+       /*
+        * now we can register the map
+        */
+-      if (map_present && (mpp = add_map_without_path(vecs, alias))) {
+-              sync_map_state(mpp);
+-              condlog(2, "%s: devmap %s registered", alias, dev);
+-              return 0;
++      if (map_present) {
++              if ((mpp = add_map_without_path(vecs, alias))) {
++                      sync_map_state(mpp);
++                      condlog(2, "%s: devmap %s registered", alias, dev);
++                      return 0;
++              } else {
++                      condlog(2, "%s: uev_add_map failed", dev);
++                      return 1;
++              }
+       }
+       r = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec, &refwwid);
diff --git a/multipath-tools/patches/0116-UPBZ-1188179-dell-36xxi.patch b/multipath-tools/patches/0116-UPBZ-1188179-dell-36xxi.patch
new file mode 100644 (file)
index 0000000..e32118b
--- /dev/null
@@ -0,0 +1,83 @@
+---
+ libmultipath/hwtable.c  |   30 ++++++++++++++++++++++++++++++
+ multipath.conf.defaults |   26 ++++++++++++++++++++++++++
+ 2 files changed, 56 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -772,6 +772,36 @@ static struct hwentry default_hw[] = {
+               .prio_name     = PRIO_RDAC,
+               .prio_args     = NULL,
+       },
++      {
++              /* DELL MD36xxi */
++              .vendor        = "DELL",
++              .product       = "MD36xxi",
++              .bl_product    = "Universal Xport",
++              .features      = "2 pg_init_retries 50",
++              .hwhandler     = "1 rdac",
++              .pgpolicy      = GROUP_BY_PRIO,
++              .pgfailback    = -FAILBACK_IMMEDIATE,
++              .rr_weight     = RR_WEIGHT_NONE,
++              .no_path_retry = 15,
++              .checker_name  = RDAC,
++              .prio_name     = PRIO_RDAC,
++              .prio_args     = NULL,
++      },
++      {
++              /* DELL MD36xxf */
++              .vendor        = "DELL",
++              .product       = "MD36xxf",
++              .bl_product    = "Universal Xport",
++              .features      = "2 pg_init_retries 50",
++              .hwhandler     = "1 rdac",
++              .pgpolicy      = GROUP_BY_PRIO,
++              .pgfailback    = -FAILBACK_IMMEDIATE,
++              .rr_weight     = RR_WEIGHT_NONE,
++              .no_path_retry = 15,
++              .checker_name  = RDAC,
++              .prio_name     = PRIO_RDAC,
++              .prio_args     = NULL,
++      },
+       /*
+        * NETAPP controller family
+        *
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -655,6 +655,32 @@
+ #             no_path_retry 15
+ #     }
+ #     device {
++#             vendor "DELL"
++#             product "MD36xxi"
++#             product_blacklist "Universal Xport"
++#             path_grouping_policy "group_by_prio"
++#             path_checker "rdac"
++#             features "2 pg_init_retries 50"
++#             hardware_handler "1 rdac"
++#             prio "rdac"
++#             failback "immediate"
++#             rr_weight "uniform"
++#             no_path_retry 15
++#     }
++#     device {
++#             vendor "DELL"
++#             product "MD36xxf"
++#             product_blacklist "Universal Xport"
++#             path_grouping_policy "group_by_prio"
++#             path_checker "rdac"
++#             features "2 pg_init_retries 50"
++#             hardware_handler "1 rdac"
++#             prio "rdac"
++#             failback "immediate"
++#             rr_weight "uniform"
++#             no_path_retry 15
++#     }
++#     device {
+ #             vendor "NETAPP"
+ #             product "LUN.*"
+ #             path_grouping_policy "group_by_prio"
diff --git a/multipath-tools/patches/0117-RHBZ-1198424-autodetect-clariion-alua.patch b/multipath-tools/patches/0117-RHBZ-1198424-autodetect-clariion-alua.patch
new file mode 100644 (file)
index 0000000..64a302d
--- /dev/null
@@ -0,0 +1,31 @@
+---
+ libmultipath/hwtable.c  |    2 ++
+ multipath.conf.defaults |    2 ++
+ 2 files changed, 4 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -272,6 +272,8 @@ static struct hwentry default_hw[] = {
+               .checker_name  = EMC_CLARIION,
+               .prio_name     = PRIO_EMC,
+               .prio_args     = NULL,
++              .retain_hwhandler = RETAIN_HWHANDLER_ON,
++              .detect_prio   = DETECT_PRIO_ON,
+       },
+       {
+               .vendor        = "EMC",
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -261,6 +261,8 @@
+ #             failback immediate
+ #             rr_weight "uniform"
+ #             no_path_retry 60
++#             retain_attached_hw_handler yes
++#             detect_prio yes
+ #     }
+ #     device {
+ #             vendor "EMC"
index 7528b1d42f2793535310007bc6469e99c7f6e54b..86da88ccd3e856d08838f056d251833d9b7225e8 100644 (file)
@@ -6,7 +6,7 @@
 name       = ncurses
 version    = 5.9
 revision   = 20150117
-release    = 10.%{revision}
+release    = 11.%{revision}
 thisapp    = %{name}-%{version}-%{revision}
 
 groups     = System/Base
@@ -72,6 +72,12 @@ build
 
                mkdir -pv %{BUILDROOT}/etc/terminfo
 
+               mkdir %{BUILDROOT}%{includedir}/ncurses{,w}
+               for l in %{BUILDROOT}%{includedir}/*.h; do
+                       ln -s ../$(basename $l) %{BUILDROOT}%{includedir}/ncurses
+                       ln -s ../$(basename $l) %{BUILDROOT}%{includedir}/ncursesw
+               done
+
                # don't require -ltinfo when linking with --no-add-needed
                for l in %{BUILDROOT}%{libdir}/libncurses{,w}.so; do
                        soname=$(basename $(readlink $l))
index 10d43f474a4b92db586716a4571f71e3b57ad50d..59491fdebefac1c75e7e98c0d41716f09f89e1b5 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = openssh
-version    = 6.1p1
+version    = 6.8p1
 release    = 1
 
 groups     = Application/Internet
@@ -37,38 +37,6 @@ build
                zlib-devel
        end
 
-       # Apply patches in a special order
-       patches
-               openssh-6.1p1-coverity.patch
-               openssh-5.8p1-fingerprint.patch
-               openssh-5.8p1-getaddrinfo.patch
-               openssh-5.8p1-packet.patch
-               openssh-6.1p1-authenticationmethods.patch
-               openssh-6.1p1-role-mls.patch
-               openssh-5.9p1-sftp-chroot.patch
-               openssh-6.1p1-akc.patch
-               openssh-5.2p1-allow-ip-opts.patch
-               openssh-5.9p1-randclean.patch
-               openssh-5.8p1-keyperm.patch
-               openssh-5.8p2-remove-stale-control-socket.patch
-               openssh-5.9p1-ipv6man.patch
-               openssh-5.8p2-sigpipe.patch
-               openssh-6.1p1-askpass-ld.patch
-               openssh-5.5p1-x11.patch
-               openssh-5.6p1-exit-deadlock.patch
-               openssh-5.1p1-askpass-progress.patch
-               openssh-4.3p2-askpass-grab-info.patch
-               openssh-5.9p1-edns.patch
-               openssh-5.1p1-scp-manpage.patch
-               openssh-5.8p1-localdomain.patch
-               openssh-5.9p1-ipfire.patch
-               openssh-6.0p1-entropy.patch
-               openssh-6.1p1-vendor.patch
-               openssh-5.8p2-force_krb.patch
-               openssh-6.1p1-kuserok.patch
-               openssh-6.1p1-required-authentications.patch
-       end
-
        configure_options += \
                --sysconfdir=%{sysconfdir}/ssh \
                --datadir=%{datadir}/sshd \
@@ -94,6 +62,13 @@ build
                # Disable GSS API authentication because KRB5 is required for that.
                sed -e "s/^.*GSSAPIAuthentication/#&/" -i %{BUILDROOT}/etc/ssh/ssh_config
 
+               # Enable PAM usage, disable ChallengeResponseAuthentication and disable Motd.
+               sed \
+                       -e '/^#ChallengeResponseAuthentication yes$/c ChallengeResponseAuthentication no' \
+                       -e '/^#PrintMotd yes$/c PrintMotd no' \
+                       -e '/^#UsePAM no$/c UsePAM yes' \
+                       -i %{BUILDROOT}/etc/ssh/sshd_config
+
                # Install scriptfile for key generation
                mkdir -pv %{BUILDROOT}%{sbindir}
                install -m 754 %{DIR_SOURCE}/sshd-keygen %{BUILDROOT}%{sbindir}
diff --git a/openssh/patches/openssh-4.3p2-askpass-grab-info.patch b/openssh/patches/openssh-4.3p2-askpass-grab-info.patch
deleted file mode 100644 (file)
index e9dc835..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- openssh-4.3p2/contrib/gnome-ssh-askpass2.c.grab-info       2006-07-17 15:10:11.000000000 +0200
-+++ openssh-4.3p2/contrib/gnome-ssh-askpass2.c 2006-07-17 15:25:04.000000000 +0200
-@@ -65,9 +65,12 @@
-       err = gtk_message_dialog_new(NULL, 0,
-                                    GTK_MESSAGE_ERROR,
-                                    GTK_BUTTONS_CLOSE,
--                                   "Could not grab %s. "
--                                   "A malicious client may be eavesdropping "
--                                   "on your session.", what);
-+                                   "SSH password dialog could not grab the %s input.\n"
-+                                   "This might be caused by application such as screensaver, "
-+                                   "however it could also mean that someone may be eavesdropping "
-+                                   "on your session.\n"
-+                                   "Either close the application which grabs the %s or "
-+                                   "log out and log in again to prevent this from happening.", what, what);
-       gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
-       gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label),
-                               TRUE);
diff --git a/openssh/patches/openssh-5.1p1-askpass-progress.patch b/openssh/patches/openssh-5.1p1-askpass-progress.patch
deleted file mode 100644 (file)
index ec93b87..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contrib/gnome-ssh-askpass2.c
---- openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress        2008-07-23 19:05:26.000000000 +0200
-+++ openssh-5.1p1/contrib/gnome-ssh-askpass2.c 2008-07-23 19:05:26.000000000 +0200
-@@ -53,6 +53,7 @@
- #include <string.h>
- #include <unistd.h>
- #include <X11/Xlib.h>
-+#include <glib.h>
- #include <gtk/gtk.h>
- #include <gdk/gdkx.h>
-@@ -83,13 +84,24 @@ ok_dialog(GtkWidget *entry, gpointer dia
-       gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
- }
-+static void
-+move_progress(GtkWidget *entry, gpointer progress)
-+{
-+      gdouble step;
-+      g_return_if_fail(GTK_IS_PROGRESS_BAR(progress));
-+      
-+      step = g_random_double_range(0.03, 0.1);
-+      gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress), step);
-+      gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress));
-+}
-+
- static int
- passphrase_dialog(char *message)
- {
-       const char *failed;
-       char *passphrase, *local;
-       int result, grab_tries, grab_server, grab_pointer;
--      GtkWidget *dialog, *entry;
-+      GtkWidget *dialog, *entry, *progress, *hbox;
-       GdkGrabStatus status;
-       grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL);
-@@ -102,13 +114,31 @@ passphrase_dialog(char *message)
-                                       "%s",
-                                       message);
-+      hbox = gtk_hbox_new(FALSE, 0);
-+      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
-+          FALSE, 0);
-+      gtk_widget_show(hbox);
-+
-       entry = gtk_entry_new();
--      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE,
-+      gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE,
-           FALSE, 0);
-+      gtk_entry_set_width_chars(GTK_ENTRY(entry), 2);
-       gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
-       gtk_widget_grab_focus(entry);
-       gtk_widget_show(entry);
-+      hbox = gtk_hbox_new(FALSE, 0);
-+      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
-+          FALSE, 8);
-+      gtk_widget_show(hbox);
-+
-+      progress = gtk_progress_bar_new();
-+      
-+      gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally");
-+      gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE,
-+          TRUE, 5);
-+      gtk_widget_show(progress);
-+
-       gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH");
-       gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
-       gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
-@@ -119,6 +149,8 @@ passphrase_dialog(char *message)
-       gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
-       g_signal_connect(G_OBJECT(entry), "activate",
-                        G_CALLBACK(ok_dialog), dialog);
-+      g_signal_connect(G_OBJECT(entry), "changed",
-+                       G_CALLBACK(move_progress), progress);
-       gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
diff --git a/openssh/patches/openssh-5.1p1-scp-manpage.patch b/openssh/patches/openssh-5.1p1-scp-manpage.patch
deleted file mode 100644 (file)
index e314a05..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-diff -up openssh-5.1p1/scp.1.manpage openssh-5.1p1/scp.1
---- openssh-5.1p1/scp.1.manpage        2008-07-12 09:12:49.000000000 +0200
-+++ openssh-5.1p1/scp.1        2008-07-23 19:18:15.000000000 +0200
-@@ -66,6 +66,14 @@ treating file names containing
- as host specifiers.
- Copies between two remote hosts are also permitted.
- .Pp
-+When copying a source file to a target file which already exists,
-+.Nm 
-+will replace the contents of the target file (keeping the inode).
-+.Pp
-+If the target file does not yet exist, an empty file with the target
-+file name is created, then filled with the source file contents.
-+No attempt is made at "near-atomic" transfer using temporary files.
-+.Pp
- The options are as follows:
- .Bl -tag -width Ds
- .It Fl 1
diff --git a/openssh/patches/openssh-5.2p1-allow-ip-opts.patch b/openssh/patches/openssh-5.2p1-allow-ip-opts.patch
deleted file mode 100644 (file)
index 96aaab1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-diff -up openssh-5.2p1/canohost.c.ip-opts openssh-5.2p1/canohost.c
---- openssh-5.2p1/canohost.c.ip-opts   2009-02-14 06:28:21.000000000 +0100
-+++ openssh-5.2p1/canohost.c   2009-09-01 15:31:29.000000000 +0200
-@@ -169,12 +169,27 @@ check_ip_options(int sock, char *ipaddr)
-       option_size = sizeof(options);
-       if (getsockopt(sock, ipproto, IP_OPTIONS, options,
-           &option_size) >= 0 && option_size != 0) {
--              text[0] = '\0';
--              for (i = 0; i < option_size; i++)
--                      snprintf(text + i*3, sizeof(text) - i*3,
--                          " %2.2x", options[i]);
--              fatal("Connection from %.100s with IP options:%.800s",
--                  ipaddr, text);
-+              i = 0;
-+              do {
-+                      switch (options[i]) {
-+                              case 0:
-+                              case 1:
-+                                      ++i;
-+                                      break;
-+                              case 131:
-+                              case 137:
-+                              /* Fail, fatally, if we detect either loose or strict
-+                               * source routing options. */
-+                                      text[0] = '\0';
-+                                      for (i = 0; i < option_size; i++)
-+                                              snprintf(text + i*3, sizeof(text) - i*3,
-+                                                      " %2.2x", options[i]);
-+                                      fatal("Connection from %.100s with IP options:%.800s",
-+                                              ipaddr, text);
-+                              default:
-+                                      i += options[i + 1];
-+                      }
-+              } while (i < option_size);
-       }
- #endif /* IP_OPTIONS */
- }
diff --git a/openssh/patches/openssh-5.5p1-x11.patch b/openssh/patches/openssh-5.5p1-x11.patch
deleted file mode 100644 (file)
index cac5d5e..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c
---- openssh-5.3p1/channels.c.bz595935  2010-08-12 14:19:28.000000000 +0200
-+++ openssh-5.3p1/channels.c   2010-08-12 14:33:51.000000000 +0200
-@@ -3185,7 +3185,7 @@ x11_create_display_inet(int x11_display_
- }
- static int
--connect_local_xsocket_path(const char *pathname)
-+connect_local_xsocket_path(const char *pathname, int len)
- {
-       int sock;
-       struct sockaddr_un addr;
-@@ -3195,11 +3195,14 @@ connect_local_xsocket_path(const char *p
-               error("socket: %.100s", strerror(errno));
-       memset(&addr, 0, sizeof(addr));
-       addr.sun_family = AF_UNIX;
--      strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
--      if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
-+      if (len <= 0)
-+              return -1;
-+      if (len > sizeof addr.sun_path)
-+              len = sizeof addr.sun_path;
-+      memcpy(addr.sun_path, pathname, len);
-+      if (connect(sock, (struct sockaddr *)&addr, sizeof addr - (sizeof addr.sun_path - len) ) == 0)
-               return sock;
-       close(sock);
--      error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
-       return -1;
- }
-@@ -3207,8 +3210,21 @@ static int
- connect_local_xsocket(u_int dnr)
- {
-       char buf[1024];
--      snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
--      return connect_local_xsocket_path(buf);
-+      int len;
-+#ifdef linux
-+      int ret;
-+#endif
-+      len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr);
-+#ifdef linux
-+      /* try abstract socket first */
-+      buf[0] = '\0';
-+      if ((ret = connect_local_xsocket_path(buf, len + 1)) >= 0)
-+              return ret;
-+#endif
-+      if ((ret = connect_local_xsocket_path(buf + 1, len)) >= 0)
-+              return ret;
-+      error("connect %.100s: %.100s", buf + 1, strerror(errno));
-+      return -1;
- }
- int
diff --git a/openssh/patches/openssh-5.6p1-exit-deadlock.patch b/openssh/patches/openssh-5.6p1-exit-deadlock.patch
deleted file mode 100644 (file)
index 278dfa1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -up openssh-5.6p1/channels.c.exit-deadlock openssh-5.6p1/channels.c
---- openssh-5.6p1/channels.c.exit-deadlock     2010-08-05 15:09:48.000000000 +0200
-+++ openssh-5.6p1/channels.c   2010-08-23 12:41:43.000000000 +0200
-@@ -1647,6 +1647,10 @@ channel_handle_wfd(Channel *c, fd_set *r
-       u_int dlen, olen = 0;
-       int len;
-+      if(c->wfd != -1 && buffer_len(&c->output) > 0 && c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
-+              debug("channel %d: forcing write", c->self);
-+              FD_SET(c->wfd, writeset);
-+      }
-       /* Send buffered output data to the socket. */
-       if (c->wfd != -1 &&
-           FD_ISSET(c->wfd, writeset) &&
diff --git a/openssh/patches/openssh-5.6p1-redhat.patch b/openssh/patches/openssh-5.6p1-redhat.patch
deleted file mode 100644 (file)
index d1df8c1..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-diff -up openssh-5.6p1/ssh_config.redhat openssh-5.6p1/ssh_config
---- openssh-5.6p1/ssh_config.redhat    2010-01-12 09:40:27.000000000 +0100
-+++ openssh-5.6p1/ssh_config   2010-09-03 15:21:17.000000000 +0200
-@@ -45,3 +45,16 @@
- #   PermitLocalCommand no
- #   VisualHostKey no
- #   ProxyCommand ssh -q -W %h:%p gateway.example.com
-+Host *
-+      GSSAPIAuthentication yes
-+# If this option is set to yes then remote X11 clients will have full access
-+# to the original X11 display. As virtually no X11 client supports the untrusted
-+# mode correctly we set this to yes.
-+      ForwardX11Trusted yes
-+# Look up the host key SSHFP records
-+      VerifyHostKeyDNS ask
-+# Send locale-related environment variables
-+      SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 
-+      SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 
-+      SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
-+      SendEnv XMODIFIERS
-diff -up openssh-5.6p1/sshd_config.0.redhat openssh-5.6p1/sshd_config.0
---- openssh-5.6p1/sshd_config.0.redhat 2010-08-23 05:24:16.000000000 +0200
-+++ openssh-5.6p1/sshd_config.0        2010-09-03 15:23:20.000000000 +0200
-@@ -537,9 +537,9 @@ DESCRIPTION
-      SyslogFacility
-              Gives the facility code that is used when logging messages from
--             sshd(8).  The possible values are: DAEMON, USER, AUTH, LOCAL0,
--             LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The
--             default is AUTH.
-+             sshd(8).  The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
-+             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
-+             The default is AUTH.
-      TCPKeepAlive
-              Specifies whether the system should send TCP keepalive messages
-diff -up openssh-5.6p1/sshd_config.5.redhat openssh-5.6p1/sshd_config.5
---- openssh-5.6p1/sshd_config.5.redhat 2010-07-02 05:37:17.000000000 +0200
-+++ openssh-5.6p1/sshd_config.5        2010-09-03 15:21:17.000000000 +0200
-@@ -919,7 +919,7 @@ Note that this option applies to protoco
- .It Cm SyslogFacility
- Gives the facility code that is used when logging messages from
- .Xr sshd 8 .
--The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
-+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
- LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
- The default is AUTH.
- .It Cm TCPKeepAlive
-diff -up openssh-5.6p1/sshd_config.redhat openssh-5.6p1/sshd_config
---- openssh-5.6p1/sshd_config.redhat   2009-10-11 12:51:09.000000000 +0200
-+++ openssh-5.6p1/sshd_config  2010-09-03 15:21:17.000000000 +0200
-@@ -31,6 +31,7 @@
- # Logging
- # obsoletes QuietMode and FascistLogging
- #SyslogFacility AUTH
-+SyslogFacility AUTHPRIV
- #LogLevel INFO
- # Authentication:
-@@ -58,9 +59,11 @@
- # To disable tunneled clear text passwords, change to no here!
- #PasswordAuthentication yes
- #PermitEmptyPasswords no
-+PasswordAuthentication yes
- # Change to no to disable s/key passwords
- #ChallengeResponseAuthentication yes
-+ChallengeResponseAuthentication no
- # Kerberos options
- #KerberosAuthentication no
-@@ -70,7 +73,9 @@
- # GSSAPI options
- #GSSAPIAuthentication no
-+GSSAPIAuthentication yes
- #GSSAPICleanupCredentials yes
-+GSSAPICleanupCredentials yes
- # Set this to 'yes' to enable PAM authentication, account processing, 
- # and session processing. If this is enabled, PAM authentication will 
-@@ -82,11 +87,19 @@
- # PAM authentication, then enable this but set PasswordAuthentication
- # and ChallengeResponseAuthentication to 'no'.
- #UsePAM no
-+UsePAM yes
-+
-+# Accept locale-related environment variables
-+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
-+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
-+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
-+AcceptEnv XMODIFIERS
- #AllowAgentForwarding yes
- #AllowTcpForwarding yes
- #GatewayPorts no
- #X11Forwarding no
-+X11Forwarding yes
- #X11DisplayOffset 10
- #X11UseLocalhost yes
- #PrintMotd yes
diff --git a/openssh/patches/openssh-5.8p1-fingerprint.patch b/openssh/patches/openssh-5.8p1-fingerprint.patch
deleted file mode 100644 (file)
index a0438ff..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-diff -up openssh-5.8p1/auth2-hostbased.c.fingerprint openssh-5.8p1/auth2-hostbased.c
---- openssh-5.8p1/auth2-hostbased.c.fingerprint        2010-08-05 05:04:50.000000000 +0200
-+++ openssh-5.8p1/auth2-hostbased.c    2011-02-25 09:17:18.000000000 +0100
-@@ -196,16 +196,18 @@ hostbased_key_allowed(struct passwd *pw,
-       if (host_status == HOST_OK) {
-               if (key_is_cert(key)) {
--                      fp = key_fingerprint(key->cert->signature_key,
--                          SSH_FP_MD5, SSH_FP_HEX);
-+                      fp = key_selected_fingerprint(key->cert->signature_key,
-+                          SSH_FP_HEX);
-                       verbose("Accepted certificate ID \"%s\" signed by "
--                          "%s CA %s from %s@%s", key->cert->key_id,
--                          key_type(key->cert->signature_key), fp,
-+                          "%s CA %s%s from %s@%s", key->cert->key_id,
-+                          key_type(key->cert->signature_key),
-+                          key_fingerprint_prefix(), fp,
-                           cuser, lookup);
-               } else {
--                      fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
--                      verbose("Accepted %s public key %s from %s@%s",
--                          key_type(key), fp, cuser, lookup);
-+                      fp = key_selected_fingerprint(key, SSH_FP_HEX);
-+                      verbose("Accepted %s public key %s%s from %s@%s",
-+                          key_type(key), key_fingerprint_prefix(),
-+                          fp, cuser, lookup);
-               }
-               xfree(fp);
-       }
-diff -up openssh-5.8p1/auth2-pubkey.c.fingerprint openssh-5.8p1/auth2-pubkey.c
---- openssh-5.8p1/auth2-pubkey.c.fingerprint   2010-12-01 01:50:14.000000000 +0100
-+++ openssh-5.8p1/auth2-pubkey.c       2011-02-25 09:17:18.000000000 +0100
-@@ -319,10 +319,10 @@ user_key_allowed2(struct passwd *pw, Key
-                               continue;
-                       if (!key_is_cert_authority)
-                               continue;
--                      fp = key_fingerprint(found, SSH_FP_MD5,
--                          SSH_FP_HEX);
--                      debug("matching CA found: file %s, line %lu, %s %s",
--                          file, linenum, key_type(found), fp);
-+                      fp = key_selected_fingerprint(found, SSH_FP_HEX);
-+                      debug("matching CA found: file %s, line %lu, %s %s%s",
-+                          file, linenum, key_type(found),
-+                          key_fingerprint_prefix(), fp);
-                       /*
-                        * If the user has specified a list of principals as
-                        * a key option, then prefer that list to matching
-@@ -362,9 +362,9 @@ user_key_allowed2(struct passwd *pw, Key
-                       found_key = 1;
-                       debug("matching key found: file %s, line %lu",
-                           file, linenum);
--                      fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
--                      verbose("Found matching %s key: %s",
--                          key_type(found), fp);
-+                      fp = key_selected_fingerprint(found, SSH_FP_HEX);
-+                      verbose("Found matching %s key: %s%s",
-+                          key_type(found), key_fingerprint_prefix(), fp);
-                       xfree(fp);
-                       break;
-               }
-@@ -388,13 +388,13 @@ user_cert_trusted_ca(struct passwd *pw, 
-       if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
-               return 0;
--      ca_fp = key_fingerprint(key->cert->signature_key,
--          SSH_FP_MD5, SSH_FP_HEX);
-+      ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX);
-       if (key_in_file(key->cert->signature_key,
-           options.trusted_user_ca_keys, 1) != 1) {
--              debug2("%s: CA %s %s is not listed in %s", __func__,
--                  key_type(key->cert->signature_key), ca_fp,
-+              debug2("%s: CA %s%s %s is not listed in %s", __func__,
-+                  key_type(key->cert->signature_key),
-+                  key_fingerprint_prefix(), ca_fp,
-                   options.trusted_user_ca_keys);
-               goto out;
-       }
-diff -up openssh-5.8p1/auth.c.fingerprint openssh-5.8p1/auth.c
---- openssh-5.8p1/auth.c.fingerprint   2010-12-01 02:21:51.000000000 +0100
-+++ openssh-5.8p1/auth.c       2011-02-25 09:17:18.000000000 +0100
-@@ -639,9 +639,10 @@ auth_key_is_revoked(Key *key)
-               return 1;
-       case 1:
-               /* Key revoked */
--              key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
-+              key_fp = key_selected_fingerprint(key, SSH_FP_HEX);
-               error("WARNING: authentication attempt with a revoked "
--                  "%s key %s ", key_type(key), key_fp);
-+                  "%s key %s%s ", key_type(key),
-+                  key_fingerprint_prefix(), key_fp);
-               xfree(key_fp);
-               return 1;
-       }
-diff -up openssh-5.8p1/auth-rsa.c.fingerprint openssh-5.8p1/auth-rsa.c
---- openssh-5.8p1/auth-rsa.c.fingerprint       2010-12-04 23:01:47.000000000 +0100
-+++ openssh-5.8p1/auth-rsa.c   2011-02-25 09:17:18.000000000 +0100
-@@ -318,9 +318,9 @@ auth_rsa(Authctxt *authctxt, BIGNUM *cli
-        * options; this will be reset if the options cause the
-        * authentication to be rejected.
-        */
--      fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
--      verbose("Found matching %s key: %s",
--          key_type(key), fp);
-+      fp = key_selected_fingerprint(key, SSH_FP_HEX);
-+      verbose("Found matching %s key: %s%s",
-+          key_type(key), key_fingerprint_prefix(), fp);
-       xfree(fp);
-       key_free(key);
-diff -up openssh-5.8p1/key.c.fingerprint openssh-5.8p1/key.c
---- openssh-5.8p1/key.c.fingerprint    2011-02-04 01:48:34.000000000 +0100
-+++ openssh-5.8p1/key.c        2011-02-25 09:18:16.000000000 +0100
-@@ -594,6 +594,34 @@ key_fingerprint(Key *k, enum fp_type dgs
-       return retval;
- }
-+enum fp_type
-+key_fingerprint_selection(void)
-+{
-+      static enum fp_type rv;
-+      static char rv_defined = 0;
-+      char *env;
-+
-+      if (!rv_defined) {
-+              env = getenv("SSH_FINGERPRINT_TYPE");
-+              rv = (env && !strcmp (env, "sha")) ?
-+                      SSH_FP_SHA1 : SSH_FP_MD5;
-+              rv_defined = 1;
-+      }
-+      return rv;
-+}
-+
-+char *
-+key_selected_fingerprint(Key *k, enum fp_rep dgst_rep)
-+{
-+      return key_fingerprint(k, key_fingerprint_selection(), dgst_rep);
-+}
-+
-+char *
-+key_fingerprint_prefix(void)
-+{
-+      return key_fingerprint_selection() == SSH_FP_SHA1 ? "sha1:" : "";
-+}
-+
- /*
-  * Reads a multiple-precision integer in decimal from the buffer, and advances
-  * the pointer.  The integer must already be initialized.  This function is
-diff -up openssh-5.8p1/key.h.fingerprint openssh-5.8p1/key.h
---- openssh-5.8p1/key.h.fingerprint    2010-11-05 00:19:49.000000000 +0100
-+++ openssh-5.8p1/key.h        2011-02-25 09:17:18.000000000 +0100
-@@ -96,6 +96,9 @@ int           key_equal_public(const Key *, cons
- int            key_equal(const Key *, const Key *);
- char          *key_fingerprint(Key *, enum fp_type, enum fp_rep);
- u_char                *key_fingerprint_raw(Key *, enum fp_type, u_int *);
-+enum fp_type   key_fingerprint_selection(void);
-+char          *key_selected_fingerprint(Key *, enum fp_rep);
-+char          *key_fingerprint_prefix(void);
- const char    *key_type(const Key *);
- const char    *key_cert_type(const Key *);
- int            key_write(const Key *, FILE *);
-diff -up openssh-5.8p1/ssh-add.c.fingerprint openssh-5.8p1/ssh-add.c
---- openssh-5.8p1/ssh-add.c.fingerprint        2010-11-11 04:17:02.000000000 +0100
-+++ openssh-5.8p1/ssh-add.c    2011-02-25 09:17:18.000000000 +0100
-@@ -280,10 +280,10 @@ list_identities(AuthenticationConnection
-                   key = ssh_get_next_identity(ac, &comment, version)) {
-                       had_identities = 1;
-                       if (do_fp) {
--                              fp = key_fingerprint(key, SSH_FP_MD5,
--                                  SSH_FP_HEX);
--                              printf("%d %s %s (%s)\n",
--                                  key_size(key), fp, comment, key_type(key));
-+                              fp = key_selected_fingerprint(key, SSH_FP_HEX);
-+                              printf("%d %s%s %s (%s)\n",
-+                                  key_size(key), key_fingerprint_prefix(),
-+                                  fp, comment, key_type(key));
-                               xfree(fp);
-                       } else {
-                               if (!key_write(key, stdout))
-diff -up openssh-5.8p1/ssh-agent.c.fingerprint openssh-5.8p1/ssh-agent.c
---- openssh-5.8p1/ssh-agent.c.fingerprint      2010-12-01 01:50:35.000000000 +0100
-+++ openssh-5.8p1/ssh-agent.c  2011-02-25 09:17:18.000000000 +0100
-@@ -199,9 +199,9 @@ confirm_key(Identity *id)
-       char *p;
-       int ret = -1;
--      p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
--      if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
--          id->comment, p))
-+      p = key_selected_fingerprint(id->key, SSH_FP_HEX);
-+      if (ask_permission("Allow use of key %s?\nKey fingerprint %s%s.",
-+          id->comment, key_fingerprint_prefix(), p))
-               ret = 0;
-       xfree(p);
-diff -up openssh-5.8p1/sshconnect2.c.fingerprint openssh-5.8p1/sshconnect2.c
---- openssh-5.8p1/sshconnect2.c.fingerprint    2010-12-01 02:21:51.000000000 +0100
-+++ openssh-5.8p1/sshconnect2.c        2011-02-25 09:17:18.000000000 +0100
-@@ -590,8 +590,9 @@ input_userauth_pk_ok(int type, u_int32_t
-                   key->type, pktype);
-               goto done;
-       }
--      fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
--      debug2("input_userauth_pk_ok: fp %s", fp);
-+      fp = key_selected_fingerprint(key, SSH_FP_HEX);
-+      debug2("input_userauth_pk_ok: fp %s%s",
-+          key_fingerprint_prefix(), fp);
-       xfree(fp);
-       /*
-@@ -1203,8 +1204,9 @@ sign_and_send_pubkey(Authctxt *authctxt,
-       int have_sig = 1;
-       char *fp;
--      fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
--      debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
-+      fp = key_selected_fingerprint(id->key, SSH_FP_HEX);
-+      debug3("sign_and_send_pubkey: %s %s%s", key_type(id->key),
-+          key_fingerprint_prefix(), fp);
-       xfree(fp);
-       if (key_to_blob(id->key, &blob, &bloblen) == 0) {
-diff -up openssh-5.8p1/sshconnect.c.fingerprint openssh-5.8p1/sshconnect.c
---- openssh-5.8p1/sshconnect.c.fingerprint     2011-01-16 13:17:59.000000000 +0100
-+++ openssh-5.8p1/sshconnect.c 2011-02-25 09:17:18.000000000 +0100
-@@ -798,10 +798,10 @@ check_host_key(char *hostname, struct so
-                                   "key for IP address '%.128s' to the list "
-                                   "of known hosts.", type, ip);
-               } else if (options.visual_host_key) {
--                      fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
--                      ra = key_fingerprint(host_key, SSH_FP_MD5,
--                          SSH_FP_RANDOMART);
--                      logit("Host key fingerprint is %s\n%s\n", fp, ra);
-+                      fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
-+                      ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART);
-+                      logit("Host key fingerprint is %s%s\n%s\n",
-+                          key_fingerprint_prefix(), fp, ra);
-                       xfree(ra);
-                       xfree(fp);
-               }
-@@ -838,9 +838,8 @@ check_host_key(char *hostname, struct so
-                       else
-                               snprintf(msg1, sizeof(msg1), ".");
-                       /* The default */
--                      fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
--                      ra = key_fingerprint(host_key, SSH_FP_MD5,
--                          SSH_FP_RANDOMART);
-+                      fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
-+                      ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART);
-                       msg2[0] = '\0';
-                       if (options.verify_host_key_dns) {
-                               if (matching_host_key_dns)
-@@ -855,10 +854,11 @@ check_host_key(char *hostname, struct so
-                       snprintf(msg, sizeof(msg),
-                           "The authenticity of host '%.200s (%s)' can't be "
-                           "established%s\n"
--                          "%s key fingerprint is %s.%s%s\n%s"
-+                          "%s key fingerprint is %s%s.%s%s\n%s"
-                           "Are you sure you want to continue connecting "
-                           "(yes/no)? ",
--                          host, ip, msg1, type, fp,
-+                          host, ip, msg1, type,
-+                          key_fingerprint_prefix(), fp,
-                           options.visual_host_key ? "\n" : "",
-                           options.visual_host_key ? ra : "",
-                           msg2);
-@@ -1104,8 +1104,9 @@ verify_host_key(char *host, struct socka
-       int flags = 0;
-       char *fp;
--      fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
--      debug("Server host key: %s %s", key_type(host_key), fp);
-+      fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
-+      debug("Server host key: %s %s%s", key_type(host_key),
-+          key_fingerprint_prefix(), fp);
-       xfree(fp);
-       /* XXX certs are not yet supported for DNS */
-@@ -1214,14 +1215,15 @@ show_other_keys(struct hostkeys *hostkey
-                       continue;
-               if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
-                       continue;
--              fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX);
--              ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART);
-+              fp = key_selected_fingerprint(found->key, SSH_FP_HEX);
-+              ra = key_selected_fingerprint(found->key, SSH_FP_RANDOMART);
-               logit("WARNING: %s key found for host %s\n"
-                   "in %s:%lu\n"
--                  "%s key fingerprint %s.",
-+                  "%s key fingerprint %s%s.",
-                   key_type(found->key),
-                   found->host, found->file, found->line,
--                  key_type(found->key), fp);
-+                  key_type(found->key),
-+                  key_fingerprint_prefix(), fp);
-               if (options.visual_host_key)
-                       logit("%s", ra);
-               xfree(ra);
-@@ -1236,7 +1238,7 @@ warn_changed_key(Key *host_key)
- {
-       char *fp;
--      fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
-+      fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
-       error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-       error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
-@@ -1244,8 +1246,8 @@ warn_changed_key(Key *host_key)
-       error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
-       error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
-       error("It is also possible that a host key has just been changed.");
--      error("The fingerprint for the %s key sent by the remote host is\n%s.",
--          key_type(host_key), fp);
-+      error("The fingerprint for the %s key sent by the remote host is\n%s%s.",
-+          key_type(host_key),key_fingerprint_prefix(),  fp);
-       error("Please contact your system administrator.");
-       xfree(fp);
-diff -up openssh-5.8p1/ssh-keygen.c.fingerprint openssh-5.8p1/ssh-keygen.c
---- openssh-5.8p1/ssh-keygen.c.fingerprint     2011-01-11 07:20:31.000000000 +0100
-+++ openssh-5.8p1/ssh-keygen.c 2011-02-25 09:17:18.000000000 +0100
-@@ -714,13 +714,14 @@ do_fingerprint(struct passwd *pw)
- {
-       FILE *f;
-       Key *public;
--      char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
-+      char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra, *pfx;
-       int i, skip = 0, num = 0, invalid = 1;
-       enum fp_rep rep;
-       enum fp_type fptype;
-       struct stat st;
--      fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
-+      fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection();
-+      pfx =    print_bubblebabble ? "" : key_fingerprint_prefix();
-       rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
-       if (!have_identity)
-@@ -732,8 +733,8 @@ do_fingerprint(struct passwd *pw)
-       public = key_load_public(identity_file, &comment);
-       if (public != NULL) {
-               fp = key_fingerprint(public, fptype, rep);
--              ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
--              printf("%u %s %s (%s)\n", key_size(public), fp, comment,
-+              ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
-+              printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, comment,
-                   key_type(public));
-               if (log_level >= SYSLOG_LEVEL_VERBOSE)
-                       printf("%s\n", ra);
-@@ -798,8 +799,8 @@ do_fingerprint(struct passwd *pw)
-               }
-               comment = *cp ? cp : comment;
-               fp = key_fingerprint(public, fptype, rep);
--              ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
--              printf("%u %s %s (%s)\n", key_size(public), fp,
-+              ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
-+              printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp,
-                   comment ? comment : "no comment", key_type(public));
-               if (log_level >= SYSLOG_LEVEL_VERBOSE)
-                       printf("%s\n", ra);
-@@ -823,13 +824,15 @@ printhost(FILE *f, const char *name, Key
-       if (print_fingerprint) {
-               enum fp_rep rep;
-               enum fp_type fptype;
--              char *fp, *ra;
-+              char *fp, *ra, *pfx;
--              fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
-+              fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection();
-+              pfx =    print_bubblebabble ? "" : key_fingerprint_prefix();
-               rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
-+
-               fp = key_fingerprint(public, fptype, rep);
--              ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
--              printf("%u %s %s (%s)\n", key_size(public), fp, name,
-+              ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
-+              printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, name,
-                   key_type(public));
-               if (log_level >= SYSLOG_LEVEL_VERBOSE)
-                       printf("%s\n", ra);
-@@ -1695,16 +1698,17 @@ do_show_cert(struct passwd *pw)
-               fatal("%s is not a certificate", identity_file);
-       v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
--      key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
--      ca_fp = key_fingerprint(key->cert->signature_key,
--          SSH_FP_MD5, SSH_FP_HEX);
-+      key_fp = key_selected_fingerprint(key, SSH_FP_HEX);
-+      ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX);
-       printf("%s:\n", identity_file);
-       printf("        Type: %s %s certificate\n", key_ssh_name(key),
-           key_cert_type(key));
--      printf("        Public key: %s %s\n", key_type(key), key_fp);
--      printf("        Signing CA: %s %s\n",
--          key_type(key->cert->signature_key), ca_fp);
-+      printf("        Public key: %s %s%s\n", key_type(key),
-+          key_fingerprint_prefix(), key_fp);
-+      printf("        Signing CA: %s %s%s\n",
-+          key_type(key->cert->signature_key),
-+          key_fingerprint_prefix(), ca_fp);
-       printf("        Key ID: \"%s\"\n", key->cert->key_id);
-       if (!v00) {
-               printf("        Serial: %llu\n",
-@@ -2249,13 +2253,12 @@ passphrase_again:
-       fclose(f);
-       if (!quiet) {
--              char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
--              char *ra = key_fingerprint(public, SSH_FP_MD5,
--                  SSH_FP_RANDOMART);
-+              char *fp = key_selected_fingerprint(public, SSH_FP_HEX);
-+              char *ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
-               printf("Your public key has been saved in %s.\n",
-                   identity_file);
-               printf("The key fingerprint is:\n");
--              printf("%s %s\n", fp, comment);
-+              printf("%s%s %s\n", key_fingerprint_prefix(), fp, comment);
-               printf("The key's randomart image is:\n");
-               printf("%s\n", ra);
-               xfree(ra);
diff --git a/openssh/patches/openssh-5.8p1-getaddrinfo.patch b/openssh/patches/openssh-5.8p1-getaddrinfo.patch
deleted file mode 100644 (file)
index 6f64067..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -up openssh-5.8p1/sshconnect.c.getaddrinfo openssh-5.8p1/sshconnect.c
---- openssh-5.8p1/sshconnect.c.getaddrinfo     2011-04-27 09:51:44.521384633 +0200
-+++ openssh-5.8p1/sshconnect.c 2011-04-27 09:53:21.224443308 +0200
-@@ -355,6 +355,7 @@ ssh_connect(const char *host, struct soc
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = family;
-       hints.ai_socktype = SOCK_STREAM;
-+      hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
-       snprintf(strport, sizeof strport, "%u", port);
-       if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
-               fatal("%s: Could not resolve hostname %.100s: %s", __progname,
diff --git a/openssh/patches/openssh-5.8p1-localdomain.patch b/openssh/patches/openssh-5.8p1-localdomain.patch
deleted file mode 100644 (file)
index 2f21658..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -up openssh-5.8p1/sshd_config.localdomain openssh-5.8p1/sshd_config
---- openssh-5.8p1/sshd_config.localdomain      2011-04-22 11:37:49.273648812 +0200
-+++ openssh-5.8p1/sshd_config  2011-04-22 11:39:31.758648401 +0200
-@@ -130,6 +130,10 @@ X11Forwarding yes
- # override default of no subsystems
- Subsystem     sftp    /usr/libexec/sftp-server
-+# Uncomment this if you want to use .local domain
-+#Host *.local
-+#     CheckHostIP no
-+
- # Example of overriding settings on a per-user basis
- #Match User anoncvs
- #     X11Forwarding no
diff --git a/openssh/patches/openssh-5.8p1-packet.patch b/openssh/patches/openssh-5.8p1-packet.patch
deleted file mode 100644 (file)
index 4951af6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c
---- openssh-5.8p1/packet.c.packet      2011-04-05 13:29:06.998648899 +0200
-+++ openssh-5.8p1/packet.c     2011-04-05 13:30:32.967648596 +0200
-@@ -294,6 +294,8 @@ packet_connection_is_on_socket(void)
-       struct sockaddr_storage from, to;
-       socklen_t fromlen, tolen;
-+      if (!active_state)
-+              return 0;
-       /* filedescriptors in and out are the same, so it's a socket */
-       if (active_state->connection_in == active_state->connection_out)
-               return 1;
diff --git a/openssh/patches/openssh-5.8p2-force_krb.patch b/openssh/patches/openssh-5.8p2-force_krb.patch
deleted file mode 100644 (file)
index 1842ce4..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-diff -up openssh-5.8p2/gss-serv-krb5.c.force_krb openssh-5.8p2/gss-serv-krb5.c
---- openssh-5.8p2/gss-serv-krb5.c.force_krb    2006-09-01 07:38:36.000000000 +0200
-+++ openssh-5.8p2/gss-serv-krb5.c      2011-05-19 03:41:45.801109545 +0200
-@@ -32,7 +32,9 @@
- #include <sys/types.h>
- #include <stdarg.h>
-+#include <stdio.h>
- #include <string.h>
-+#include <unistd.h>
- #include "xmalloc.h"
- #include "key.h"
-@@ -40,12 +42,11 @@
- #include "auth.h"
- #include "log.h"
- #include "servconf.h"
-+#include "misc.h"
- #include "buffer.h"
- #include "ssh-gss.h"
--extern ServerOptions options;
--
- #ifdef HEIMDAL
- # include <krb5.h>
- #else
-@@ -56,6 +57,16 @@ extern ServerOptions options;
- # endif
- #endif
-+extern Authctxt *the_authctxt;
-+extern ServerOptions options;
-+
-+/* all commands are allowed by default */
-+char **k5users_allowed_cmds = NULL;
-+
-+static int ssh_gssapi_k5login_exists();
-+static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *,
-+    int);
-+
- static krb5_context krb_context = NULL;
- /* Initialise the krb5 library, for the stuff that GSSAPI won't do */
-@@ -83,10 +94,11 @@ ssh_gssapi_krb5_init(void)
-  */
- static int
--ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
-+ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *luser)
- {
-       krb5_principal princ;
-       int retval;
-+      int k5login_exists;
-       if (ssh_gssapi_krb5_init() == 0)
-               return 0;
-@@ -97,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
-                   krb5_get_err_text(krb_context, retval));
-               return 0;
-       }
--      if (krb5_kuserok(krb_context, princ, name)) {
-+      /* krb5_kuserok() returns 1 if .k5login DNE and this is self-login.
-+       * We have to make sure to check .k5users in that case. */
-+      k5login_exists = ssh_gssapi_k5login_exists();
-+      /* NOTE: .k5login and .k5users must opened as root, not the user,
-+       * because if they are on a krb5-protected filesystem, user credentials
-+       * to access these files aren't available yet. */
-+      if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) {
-               retval = 1;
-               logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
--                  name, (char *)client->displayname.value);
-+                  luser, (char *)client->displayname.value);
-+      } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value,
-+              luser, k5login_exists)) {
-+              retval = 1;
-+              logit("Authorized to %s, krb5 principal %s "
-+                  "(ssh_gssapi_krb5_cmdok)",
-+                  luser, (char *)client->displayname.value);
-       } else
-               retval = 0;
-@@ -108,6 +132,134 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
-       return retval;
- }
-+/* Test for existence of .k5login.
-+ * We need this as part of our .k5users check, because krb5_kuserok()
-+ * returns success if .k5login DNE and user is logging in as himself.
-+ * With .k5login absent and .k5users present, we don't want absence
-+ * of .k5login to authorize self-login.  (absence of both is required)
-+ * Returns 1 if .k5login is available, 0 otherwise.
-+ */
-+static int
-+ssh_gssapi_k5login_exists()
-+{
-+      char file[MAXPATHLEN];
-+      struct passwd *pw = the_authctxt->pw;
-+
-+      snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
-+      return access(file, F_OK) == 0;
-+}
-+
-+/* check .k5users for login or command authorization
-+ * Returns 1 if principal is authorized, 0 otherwise.
-+ * If principal is authorized, (global) k5users_allowed_cmds may be populated.
-+ */
-+static int
-+ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
-+    const char *luser, int k5login_exists)
-+{
-+      FILE *fp;
-+      char file[MAXPATHLEN];
-+      char line[BUFSIZ];
-+      char kuser[65]; /* match krb5_kuserok() */
-+      struct stat st;
-+      struct passwd *pw = the_authctxt->pw;
-+      int found_principal = 0;
-+      int ncommands = 0, allcommands = 0;
-+      u_long linenum;
-+
-+      snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
-+      /* If both .k5login and .k5users DNE, self-login is ok. */
-+      if (!k5login_exists && (access(file, F_OK) == -1)) {
-+              return (krb5_aname_to_localname(krb_context, principal,
-+                  sizeof(kuser), kuser) == 0) &&
-+                  (strcmp(kuser, luser) == 0);
-+      }
-+      if ((fp = fopen(file, "r")) == NULL) {
-+              int saved_errno = errno;
-+              /* 2nd access check to ease debugging if file perms are wrong.
-+               * But we don't want to report this if .k5users simply DNE. */
-+              if (access(file, F_OK) == 0) {
-+                      logit("User %s fopen %s failed: %s",
-+                          pw->pw_name, file, strerror(saved_errno));
-+              }
-+              return 0;
-+      }
-+      /* .k5users must be owned either by the user or by root */
-+      if (fstat(fileno(fp), &st) == -1) {
-+              /* can happen, but very wierd error so report it */
-+              logit("User %s fstat %s failed: %s",
-+                  pw->pw_name, file, strerror(errno));
-+              fclose(fp);
-+              return 0;
-+      }
-+      if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) {
-+              logit("User %s %s is not owned by root or user",
-+                  pw->pw_name, file);
-+              fclose(fp);
-+              return 0;
-+      }
-+      /* .k5users must be a regular file.  krb5_kuserok() doesn't do this
-+        * check, but we don't want to be deficient if they add a check. */
-+      if (!S_ISREG(st.st_mode)) {
-+              logit("User %s %s is not a regular file", pw->pw_name, file);
-+              fclose(fp);
-+              return 0;
-+      }
-+      /* file exists; initialize k5users_allowed_cmds (to none!) */
-+      k5users_allowed_cmds = xcalloc(++ncommands,
-+          sizeof(*k5users_allowed_cmds));
-+
-+      /* Check each line.  ksu allows unlimited length lines.  We don't. */
-+      while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line),
-+          &linenum) != -1) {
-+              char *token;
-+
-+              /* we parse just like ksu, even though we could do better */
-+              token = strtok(line, " \t\n");
-+              if (strcmp(name, token) == 0) {
-+                      /* we matched on client principal */
-+                      found_principal = 1;
-+                      if ((token = strtok(NULL, " \t\n")) == NULL) {
-+                              /* only shell is allowed */
-+                              k5users_allowed_cmds[ncommands-1] =
-+                                  xstrdup(pw->pw_shell);
-+                              k5users_allowed_cmds =
-+                                  xrealloc(k5users_allowed_cmds, ++ncommands,
-+                                      sizeof(*k5users_allowed_cmds));
-+                              break;
-+                      }
-+                      /* process the allowed commands */
-+                      while (token) {
-+                              if (strcmp(token, "*") == 0) {
-+                                      allcommands = 1;
-+                                      break;
-+                              }
-+                              k5users_allowed_cmds[ncommands-1] =
-+                                  xstrdup(token);
-+                              k5users_allowed_cmds =
-+                                  xrealloc(k5users_allowed_cmds, ++ncommands,
-+                                      sizeof(*k5users_allowed_cmds));
-+                              token = strtok(NULL, " \t\n");
-+                      }
-+              }
-+       }
-+      if (k5users_allowed_cmds) {
-+              /* terminate vector */
-+              k5users_allowed_cmds[ncommands-1] = NULL;
-+              /* if all commands are allowed, free vector */
-+              if (allcommands) {
-+                      int i;
-+                      for (i = 0; i < ncommands; i++) {
-+                              free(k5users_allowed_cmds[i]);
-+                      }
-+                      free(k5users_allowed_cmds);
-+                      k5users_allowed_cmds = NULL;
-+              }
-+      }
-+      fclose(fp);
-+      return found_principal;
-+}
-+ 
- /* This writes out any forwarded credentials from the structure populated
-  * during userauth. Called after we have setuid to the user */
-diff -up openssh-5.8p2/session.c.force_krb openssh-5.8p2/session.c
---- openssh-5.8p2/session.c.force_krb  2011-05-19 03:41:41.000000000 +0200
-+++ openssh-5.8p2/session.c    2011-05-19 03:43:32.437173662 +0200
-@@ -816,6 +816,29 @@ do_exec(Session *s, const char *command)
-               debug("Forced command (key option) '%.900s'", command);
-       }
-+#ifdef GSSAPI
-+#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */
-+      else if (k5users_allowed_cmds) {
-+              const char *match = command;
-+              int allowed = 0, i = 0;
-+ 
-+              if (!match)
-+                      match = s->pw->pw_shell;
-+              while (k5users_allowed_cmds[i]) {
-+                      if (strcmp(match, k5users_allowed_cmds[i++]) == 0) {
-+                              debug("Allowed command '%.900s'", match);
-+                              allowed = 1;
-+                              break;
-+                      }
-+              }
-+              if (!allowed) {
-+                      debug("command '%.900s' not allowed", match);
-+                      return 1;
-+              }
-+      }
-+#endif
-+#endif
-+
- #ifdef SSH_AUDIT_EVENTS
-       if (s->command != NULL || s->command_handle != -1)
-               fatal("do_exec: command already set");
-diff -up openssh-5.8p2/sshd.8.force_krb openssh-5.8p2/sshd.8
---- openssh-5.8p2/sshd.8.force_krb     2011-05-19 03:41:30.582114401 +0200
-+++ openssh-5.8p2/sshd.8       2011-05-19 03:41:46.159106308 +0200
-@@ -320,6 +320,7 @@ Finally, the server and the client enter
- The client tries to authenticate itself using
- host-based authentication,
- public key authentication,
-+GSSAPI authentication,
- challenge-response authentication,
- or password authentication.
- .Pp
-@@ -788,6 +789,12 @@ This file is used in exactly the same wa
- but allows host-based authentication without permitting login with
- rlogin/rsh.
- .Pp
-+.It Pa ~/.k5login
-+.It Pa ~/.k5users
-+These files enforce GSSAPI/Kerberos authentication access control.
-+Further details are described in
-+.Xr ksu 1 .
-+.Pp
- .It Pa ~/.ssh/
- This directory is the default location for all user-specific configuration
- and authentication information.
-diff -up openssh-5.8p2/ssh-gss.h.force_krb openssh-5.8p2/ssh-gss.h
---- openssh-5.8p2/ssh-gss.h.force_krb  2007-06-12 15:40:39.000000000 +0200
-+++ openssh-5.8p2/ssh-gss.h    2011-05-19 03:41:46.302234118 +0200
-@@ -48,6 +48,10 @@
- #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
- #endif /* GSS_C_NT_... */
- #endif /* !HEIMDAL */
-+
-+/* .k5users support */
-+extern char **k5users_allowed_cmds;
-+
- #endif /* KRB5 */
- /* draft-ietf-secsh-gsskeyex-06 */
diff --git a/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch b/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch
deleted file mode 100644 (file)
index 4a25d9e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -up openssh-5.8p2/mux.c.remove_stale openssh-5.8p2/mux.c
---- openssh-5.8p2/mux.c.remove_stale   2011-01-14 02:01:32.000000000 +0100
-+++ openssh-5.8p2/mux.c        2011-06-09 15:27:42.556360291 +0200
-@@ -1867,6 +1867,9 @@ muxclient(const char *path)
-                       unlink(path);
-               } else if (errno == ENOENT) {
-                       debug("Control socket \"%.100s\" does not exist", path);
-+              } else if (errno == ECONNREFUSED) {
-+                      debug("Removing stale control socket \"%.100s\"", path);
-+                      unlink(path);
-               } else {
-                       error("Control socket connect(%.100s): %s", path,
-                           strerror(errno));
diff --git a/openssh/patches/openssh-5.8p2-sigpipe.patch b/openssh/patches/openssh-5.8p2-sigpipe.patch
deleted file mode 100644 (file)
index 56af045..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c
---- openssh-5.8p2/ssh-keyscan.c.sigpipe        2011-08-23 18:30:33.873025916 +0200
-+++ openssh-5.8p2/ssh-keyscan.c        2011-08-23 18:32:24.574025362 +0200
-@@ -715,6 +715,8 @@ main(int argc, char **argv)
-               fdlim_set(maxfd);
-       fdcon = xcalloc(maxfd, sizeof(con));
-+      signal(SIGPIPE, SIG_IGN);
-+
-       read_wait_nfdset = howmany(maxfd, NFDBITS);
-       read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));
diff --git a/openssh/patches/openssh-5.9p1-akc.patch b/openssh/patches/openssh-5.9p1-akc.patch
deleted file mode 100644 (file)
index 62a478b..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-diff -up openssh-5.9p1/auth2-pubkey.c.akc openssh-5.9p1/auth2-pubkey.c
---- openssh-5.9p1/auth2-pubkey.c.akc   2011-09-14 07:24:40.876512251 +0200
-+++ openssh-5.9p1/auth2-pubkey.c       2011-09-14 07:24:43.318458515 +0200
-@@ -27,6 +27,7 @@
- #include <sys/types.h>
- #include <sys/stat.h>
-+#include <sys/wait.h>
- #include <fcntl.h>
- #include <pwd.h>
-@@ -276,27 +277,15 @@ match_principals_file(char *file, struct
- /* return 1 if user allows given key */
- static int
--user_key_allowed2(struct passwd *pw, Key *key, char *file)
-+user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
- {
-       char line[SSH_MAX_PUBKEY_BYTES];
-       const char *reason;
-       int found_key = 0;
--      FILE *f;
-       u_long linenum = 0;
-       Key *found;
-       char *fp;
--      /* Temporarily use the user's uid. */
--      temporarily_use_uid(pw);
--
--      debug("trying public key file %s", file);
--      f = auth_openkeyfile(file, pw, options.strict_modes);
--
--      if (!f) {
--              restore_uid();
--              return 0;
--      }
--
-       found_key = 0;
-       found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
-@@ -389,8 +378,6 @@ user_key_allowed2(struct passwd *pw, Key
-                       break;
-               }
-       }
--      restore_uid();
--      fclose(f);
-       key_free(found);
-       if (!found_key)
-               debug2("key not found");
-@@ -452,13 +439,191 @@ user_cert_trusted_ca(struct passwd *pw,
-       return ret;
- }
--/* check whether given key is in .ssh/authorized_keys* */
-+/* return 1 if user allows given key */
-+static int
-+user_key_allowed2(struct passwd *pw, Key *key, char *file)
-+{
-+      FILE *f;
-+      int found_key = 0;
-+
-+      /* Temporarily use the user's uid. */
-+      temporarily_use_uid(pw);
-+
-+      debug("trying public key file %s", file);
-+      f = auth_openkeyfile(file, pw, options.strict_modes);
-+
-+      if (f) {
-+              found_key = user_search_key_in_file (f, file, key, pw);
-+              fclose(f);
-+      }
-+
-+      restore_uid();
-+      return found_key;
-+}
-+
-+#ifdef WITH_AUTHORIZED_KEYS_COMMAND
-+
-+#define WHITESPACE " \t\r\n"
-+
-+/* return 1 if user allows given key */
-+static int
-+user_key_via_command_allowed2(struct passwd *pw, Key *key)
-+{
-+      FILE *f;
-+      int found_key = 0;
-+      char *progname = NULL;
-+      char *cp;
-+      struct passwd *runas_pw;
-+      struct stat st;
-+      int childdescriptors[2], i;
-+      pid_t pstat, pid, child;
-+
-+      if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/')
-+              return 0;
-+
-+      /* get the run as identity from config */
-+      runas_pw = (options.authorized_keys_command_runas == NULL)? pw
-+          : getpwnam (options.authorized_keys_command_runas);
-+      if (!runas_pw) {
-+              error("%s: getpwnam(\"%s\"): %s", __func__,
-+                  options.authorized_keys_command_runas, strerror(errno));
-+              return 0;
-+      }
-+
-+      /* Temporarily use the specified uid. */
-+      if (runas_pw->pw_uid != 0)
-+              temporarily_use_uid(runas_pw);
-+
-+      progname = xstrdup(options.authorized_keys_command);
-+
-+      debug3("%s: checking program '%s'", __func__, progname);
-+
-+      if (stat (progname, &st) < 0) {
-+              error("%s: stat(\"%s\"): %s", __func__,
-+                  progname, strerror(errno));
-+              goto go_away;
-+      }
-+
-+      if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
-+              error("bad ownership or modes for AuthorizedKeysCommand \"%s\"",
-+                  progname);
-+              goto go_away;
-+      }
-+
-+      if (!S_ISREG(st.st_mode)) {
-+              error("AuthorizedKeysCommand \"%s\" is not a regular file",
-+                  progname);
-+              goto go_away;
-+      }
-+
-+      /*
-+       * Descend the path, checking that each component is a
-+       * root-owned directory with strict permissions.
-+       */
-+      do {
-+              if ((cp = strrchr(progname, '/')) == NULL)
-+                      break;
-+              else 
-+                      *cp = '\0';
-+      
-+              debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname));
-+
-+              if (stat((*progname == '\0' ? "/" : progname), &st) != 0) {
-+                      error("%s: stat(\"%s\"): %s", __func__,
-+                          progname, strerror(errno));
-+                      goto go_away;
-+              }
-+              if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
-+                      error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"",
-+                          progname);
-+                      goto go_away;
-+              }
-+              if (!S_ISDIR(st.st_mode)) {
-+                      error("AuthorizedKeysCommand path component \"%s\" is not a directory",
-+                          progname);
-+                      goto go_away;
-+              }
-+      } while (1);
-+
-+      /* open the pipe and read the keys */
-+      if (pipe(childdescriptors)) {
-+              error("failed to pipe(2) for AuthorizedKeysCommand: %s",
-+                  strerror(errno));
-+              goto go_away;
-+      }
-+
-+      child = fork();
-+      if (child == -1) {
-+              error("failed to fork(2) for AuthorizedKeysCommand: %s",
-+                  strerror(errno));
-+              goto go_away;
-+      } else if (child == 0) {
-+              /* we're in the child process here -- we should never return from this block. */
-+              /* permanently drop privs in child process */
-+              if (runas_pw->pw_uid != 0) {
-+                      restore_uid();
-+                      permanently_set_uid(runas_pw);
-+              }
-+
-+              close(childdescriptors[0]);
-+              /* put the write end of the pipe on stdout (FD 1) */
-+              if (dup2(childdescriptors[1], 1) == -1) {
-+                      error("failed to dup2(2) from AuthorizedKeysCommand: %s",
-+                          strerror(errno));
-+                      _exit(127);
-+              }
-+
-+              debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name);
-+              /* see session.c:child_close_fds() */
-+              for (i = 3; i < 64; ++i) {
-+                      close(i);
-+              }
-+
-+              execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
-+
-+              /* if we got here, it didn't work */
-+              error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */
-+              _exit(127);
-+      }
-+      
-+      close(childdescriptors[1]);
-+      f = fdopen(childdescriptors[0], "r");
-+      if (!f) {
-+              error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__,
-+                  options.authorized_keys_command, strerror (errno));
-+              goto go_away;
-+      }
-+
-+      found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw);
-+      fclose (f);
-+      do {
-+              pid = waitpid(child, &pstat, 0);
-+      } while (pid == -1 && errno == EINTR);
-+
-+      /* what about the return value from the child process? */
-+go_away:
-+      if (progname)
-+              xfree (progname);
-+
-+      if (runas_pw->pw_uid != 0)
-+              restore_uid();
-+      return found_key;
-+}
-+#endif
-+
-+/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */
- int
- user_key_allowed(struct passwd *pw, Key *key)
- {
-       u_int success, i;
-       char *file;
-+#ifdef WITH_AUTHORIZED_KEYS_COMMAND
-+      success = user_key_via_command_allowed2(pw, key);
-+      if (success > 0)
-+              return success;
-+#endif
-+
-       if (auth_key_is_revoked(key))
-               return 0;
-       if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
-diff -up openssh-5.9p1/configure.ac.akc openssh-5.9p1/configure.ac
---- openssh-5.9p1/configure.ac.akc     2011-09-14 07:24:42.863494886 +0200
-+++ openssh-5.9p1/configure.ac 2011-09-14 07:24:43.441583848 +0200
-@@ -1421,6 +1421,18 @@ AC_ARG_WITH([audit],
-       esac ]
- )
-+# Check whether user wants AuthorizedKeysCommand support
-+AKC_MSG="no"
-+AC_ARG_WITH(authorized-keys-command,
-+      [  --with-authorized-keys-command      Enable AuthorizedKeysCommand support],
-+      [
-+              if test "x$withval" != "xno" ; then
-+                      AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support])
-+                      AKC_MSG="yes"
-+              fi
-+      ]
-+)
-+
- dnl    Checks for library functions. Please keep in alphabetical order
- AC_CHECK_FUNCS([ \
-       arc4random \
-@@ -4239,6 +4251,7 @@ echo "                   SELinux support
- echo "                 Smartcard support: $SCARD_MSG"
- echo "                     S/KEY support: $SKEY_MSG"
- echo "              TCP Wrappers support: $TCPW_MSG"
-+echo "     AuthorizedKeysCommand support: $AKC_MSG"
- echo "              MD5 password support: $MD5_MSG"
- echo "                   libedit support: $LIBEDIT_MSG"
- echo "  Solaris process contract support: $SPC_MSG"
-diff -up openssh-5.9p1/servconf.c.akc openssh-5.9p1/servconf.c
---- openssh-5.9p1/servconf.c.akc       2011-09-14 07:24:29.402475399 +0200
-+++ openssh-5.9p1/servconf.c   2011-09-14 07:56:27.158585590 +0200
-@@ -139,6 +139,8 @@ initialize_server_options(ServerOptions
-       options->num_permitted_opens = -1;
-       options->adm_forced_command = NULL;
-       options->chroot_directory = NULL;
-+      options->authorized_keys_command = NULL;
-+      options->authorized_keys_command_runas = NULL;
-       options->zero_knowledge_password_authentication = -1;
-       options->revoked_keys_file = NULL;
-       options->trusted_user_ca_keys = NULL;
-@@ -348,6 +350,7 @@ typedef enum {
-       sZeroKnowledgePasswordAuthentication, sHostCertificate,
-       sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
-       sKexAlgorithms, sIPQoS,
-+      sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
-       sDeprecated, sUnsupported
- } ServerOpCodes;
-@@ -487,6 +490,13 @@ static struct {
-       { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
-       { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
-       { "ipqos", sIPQoS, SSHCFG_ALL },
-+#ifdef WITH_AUTHORIZED_KEYS_COMMAND
-+      { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
-+      { "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
-+#else
-+      { "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
-+      { "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
-+#endif
-       { NULL, sBadOption, 0 }
- };
-@@ -1462,6 +1472,24 @@ process_server_config_line(ServerOptions
-               }
-               break;
-+      case sAuthorizedKeysCommand:
-+              len = strspn(cp, WHITESPACE);
-+              if (*activep && options->authorized_keys_command == NULL)
-+                      options->authorized_keys_command = xstrdup(cp + len);
-+              return 0;
-+
-+      case sAuthorizedKeysCommandRunAs:
-+              charptr = &options->authorized_keys_command_runas;
-+
-+              arg = strdelim(&cp);
-+              if (!arg || *arg == '\0')
-+                      fatal("%s line %d: missing account.",
-+                          filename, linenum);
-+
-+              if (*activep && *charptr == NULL)
-+                      *charptr = xstrdup(arg);
-+              break;
-+
-       case sDeprecated:
-               logit("%s line %d: Deprecated option %s",
-                   filename, linenum, arg);
-@@ -1573,6 +1601,8 @@ copy_set_server_options(ServerOptions *d
-       M_CP_INTOPT(zero_knowledge_password_authentication);
-       M_CP_INTOPT(second_zero_knowledge_password_authentication);
-       M_CP_INTOPT(two_factor_authentication);
-+      M_CP_STROPT(authorized_keys_command);
-+      M_CP_STROPT(authorized_keys_command_runas);
-       M_CP_INTOPT(permit_root_login);
-       M_CP_INTOPT(permit_empty_passwd);
-@@ -1839,6 +1869,8 @@ dump_config(ServerOptions *o)
-       dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
-       dump_cfg_string(sAuthorizedPrincipalsFile,
-           o->authorized_principals_file);
-+      dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
-+      dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
-       /* string arguments requiring a lookup */
-       dump_cfg_string(sLogLevel, log_level_name(o->log_level));
-diff -up openssh-5.9p1/servconf.h.akc openssh-5.9p1/servconf.h
---- openssh-5.9p1/servconf.h.akc       2011-09-14 07:24:29.511480441 +0200
-+++ openssh-5.9p1/servconf.h   2011-09-14 07:24:43.678459183 +0200
-@@ -174,6 +174,8 @@ typedef struct {
-       char   *revoked_keys_file;
-       char   *trusted_user_ca_keys;
-       char   *authorized_principals_file;
-+      char   *authorized_keys_command;
-+      char   *authorized_keys_command_runas;
- }       ServerOptions;
- /*
-diff -up openssh-5.9p1/sshd_config.0.akc openssh-5.9p1/sshd_config.0
---- openssh-5.9p1/sshd_config.0.akc    2011-09-07 01:16:30.000000000 +0200
-+++ openssh-5.9p1/sshd_config.0        2011-09-14 07:24:43.791460201 +0200
-@@ -71,6 +71,23 @@ DESCRIPTION
-              See PATTERNS in ssh_config(5) for more information on patterns.
-+     AuthorizedKeysCommand
-+
-+             Specifies a program to be used for lookup of the user's
-+           public keys.  The program will be invoked with its first
-+           argument the name of the user being authorized, and should produce 
-+           on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
-+           in sshd(8)).  By default (or when set to the empty string) there is no
-+           AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
-+           authorize the user, authorization falls through to the
-+           AuthorizedKeysFile.  Note that this option has an effect
-+           only with PubkeyAuthentication turned on.
-+
-+     AuthorizedKeysCommandRunAs
-+             Specifies the user under whose account the AuthorizedKeysCommand is run.
-+             Empty string (the default value) means the user being authorized
-+             is used.
-+
-      AuthorizedKeysFile
-              Specifies the file that contains the public keys that can be used
-              for user authentication.  The format is described in the
-@@ -401,7 +418,8 @@ DESCRIPTION
-              Only a subset of keywords may be used on the lines following a
-              Match keyword.  Available keywords are AllowAgentForwarding,
--             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
-+             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand,
-+             AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile,
-              Banner, ChrootDirectory, ForceCommand, GatewayPorts,
-              GSSAPIAuthentication, HostbasedAuthentication,
-              HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
-diff -up openssh-5.9p1/sshd_config.5.akc openssh-5.9p1/sshd_config.5
---- openssh-5.9p1/sshd_config.5.akc    2011-09-14 07:24:29.793520372 +0200
-+++ openssh-5.9p1/sshd_config.5        2011-09-14 07:24:43.912583678 +0200
-@@ -706,6 +706,8 @@ Available keywords are
- .Cm AllowAgentForwarding ,
- .Cm AllowTcpForwarding ,
- .Cm AuthorizedKeysFile ,
-+.Cm AuthorizedKeysCommand ,
-+.Cm AuthorizedKeysCommandRunAs ,
- .Cm AuthorizedPrincipalsFile ,
- .Cm Banner ,
- .Cm ChrootDirectory ,
-@@ -718,6 +720,7 @@ Available keywords are
- .Cm KerberosAuthentication ,
- .Cm MaxAuthTries ,
- .Cm MaxSessions ,
-+.Cm PubkeyAuthentication ,
- .Cm PasswordAuthentication ,
- .Cm PermitEmptyPasswords ,
- .Cm PermitOpen ,
-@@ -926,6 +929,20 @@ Specifies a list of revoked public keys.
- Keys listed in this file will be refused for public key authentication.
- Note that if this file is not readable, then public key authentication will
- be refused for all users.
-+.It Cm AuthorizedKeysCommand
-+Specifies a program to be used for lookup of the user's
-+public keys.  The program will be invoked with its first
-+argument the name of the user being authorized, and should produce 
-+on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
-+in sshd(8)).  By default (or when set to the empty string) there is no
-+AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
-+authorize the user, authorization falls through to the
-+AuthorizedKeysFile.  Note that this option has an effect
-+only with PubkeyAuthentication turned on.
-+.It Cm AuthorizedKeysCommandRunAs
-+Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
-+string (the default value) means the user being authorized is used.
-+.Dq 
- .It Cm RhostsRSAAuthentication
- Specifies whether rhosts or /etc/hosts.equiv authentication together
- with successful RSA host authentication is allowed.
-diff -up openssh-5.9p1/sshd_config.akc openssh-5.9p1/sshd_config
---- openssh-5.9p1/sshd_config.akc      2011-09-14 07:24:29.620461608 +0200
-+++ openssh-5.9p1/sshd_config  2011-09-14 07:24:44.034462546 +0200
-@@ -49,6 +49,9 @@
- # but this is overridden so installations will only check .ssh/authorized_keys
- AuthorizedKeysFile    .ssh/authorized_keys
-+#AuthorizedKeysCommand none
-+#AuthorizedKeysCommandRunAs nobody
-+
- # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
- #RhostsRSAAuthentication no
- # similar for protocol version 2
diff --git a/openssh/patches/openssh-5.9p1-edns.patch b/openssh/patches/openssh-5.9p1-edns.patch
deleted file mode 100644 (file)
index 34f3851..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-diff -up openssh-5.9p1/dns.c.edns openssh-5.9p1/dns.c
---- openssh-5.9p1/dns.c.edns   2010-08-31 14:41:14.000000000 +0200
-+++ openssh-5.9p1/dns.c        2011-09-09 08:05:27.782440497 +0200
-@@ -177,6 +177,7 @@ verify_host_key_dns(const char *hostname
- {
-       u_int counter;
-       int result;
-+      unsigned int rrset_flags = 0;
-       struct rrsetinfo *fingerprints = NULL;
-       u_int8_t hostkey_algorithm;
-@@ -200,8 +201,19 @@ verify_host_key_dns(const char *hostname
-               return -1;
-       }
-+      /*
-+       * Original getrrsetbyname function, found on OpenBSD for example,
-+       * doesn't accept any flag and prerequisite for obtaining AD bit in
-+       * DNS response is set by "options edns0" in resolv.conf.
-+       *
-+       * Our version is more clever and use RRSET_FORCE_EDNS0 flag.
-+       */
-+#ifndef HAVE_GETRRSETBYNAME
-+      rrset_flags |= RRSET_FORCE_EDNS0;
-+#endif
-       result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
--          DNS_RDATATYPE_SSHFP, 0, &fingerprints);
-+          DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints);
-+
-       if (result) {
-               verbose("DNS lookup error: %s", dns_result_totext(result));
-               return -1;
-diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.c
---- openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns 2009-07-13 03:38:23.000000000 +0200
-+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.c      2011-09-09 15:03:39.930500801 +0200
-@@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, uns
-               goto fail;
-       }
--      /* don't allow flags yet, unimplemented */
--      if (flags) {
-+      /* Allow RRSET_FORCE_EDNS0 flag only. */
-+      if ((flags & ~RRSET_FORCE_EDNS0) != 0) {
-               result = ERRSET_INVAL;
-               goto fail;
-       }
-@@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, uns
- #endif /* DEBUG */
- #ifdef RES_USE_DNSSEC
--      /* turn on DNSSEC if EDNS0 is configured */
--      if (_resp->options & RES_USE_EDNS0)
--              _resp->options |= RES_USE_DNSSEC;
-+      /* turn on DNSSEC if required  */
-+      if (flags & RRSET_FORCE_EDNS0)
-+              _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC);
- #endif /* RES_USE_DNSEC */
-       /* make query */
-diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.h
---- openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns 2007-10-26 08:26:50.000000000 +0200
-+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.h      2011-09-09 08:05:27.965438689 +0200
-@@ -72,6 +72,9 @@
- #ifndef RRSET_VALIDATED
- # define RRSET_VALIDATED      1
- #endif
-+#ifndef RRSET_FORCE_EDNS0
-+# define RRSET_FORCE_EDNS0    0x0001
-+#endif
- /*
-  * Return codes for getrrsetbyname()
diff --git a/openssh/patches/openssh-5.9p1-ipfire.patch b/openssh/patches/openssh-5.9p1-ipfire.patch
deleted file mode 100644 (file)
index cdb49c6..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-diff -up openssh-5.9p0/ssh_config.redhat openssh-5.9p0/ssh_config
---- openssh-5.9p0/ssh_config.redhat    2010-01-12 09:40:27.000000000 +0100
-+++ openssh-5.9p0/ssh_config   2011-09-05 14:48:16.386439023 +0200
-@@ -45,3 +45,14 @@
- #   PermitLocalCommand no
- #   VisualHostKey no
- #   ProxyCommand ssh -q -W %h:%p gateway.example.com
-+Host *
-+      GSSAPIAuthentication yes
-+# If this option is set to yes then remote X11 clients will have full access
-+# to the original X11 display. As virtually no X11 client supports the untrusted
-+# mode correctly we set this to yes.
-+      ForwardX11Trusted yes
-+# Send locale-related environment variables
-+      SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 
-+      SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 
-+      SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
-+      SendEnv XMODIFIERS
-diff -up openssh-5.9p0/sshd_config.0.redhat openssh-5.9p0/sshd_config.0
---- openssh-5.9p0/sshd_config.0.redhat 2011-09-05 14:48:08.522441255 +0200
-+++ openssh-5.9p0/sshd_config.0        2011-09-05 14:48:16.477443868 +0200
-@@ -581,9 +581,9 @@ DESCRIPTION
-      SyslogFacility
-              Gives the facility code that is used when logging messages from
--             sshd(8).  The possible values are: DAEMON, USER, AUTH, LOCAL0,
--             LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The
--             default is AUTH.
-+             sshd(8).  The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
-+             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
-+             The default is AUTH.
-      TCPKeepAlive
-              Specifies whether the system should send TCP keepalive messages
-diff -up openssh-5.9p0/sshd_config.5.redhat openssh-5.9p0/sshd_config.5
---- openssh-5.9p0/sshd_config.5.redhat 2011-09-05 14:48:08.657564688 +0200
-+++ openssh-5.9p0/sshd_config.5        2011-09-05 14:48:16.589501736 +0200
-@@ -1029,7 +1029,7 @@ Note that this option applies to protoco
- .It Cm SyslogFacility
- Gives the facility code that is used when logging messages from
- .Xr sshd 8 .
--The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
-+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
- LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
- The default is AUTH.
- .It Cm TCPKeepAlive
-diff -up openssh-5.9p0/sshd_config.redhat openssh-5.9p0/sshd_config
---- openssh-5.9p0/sshd_config.redhat   2011-09-05 14:48:16.250626793 +0200
-+++ openssh-5.9p0/sshd_config  2011-09-05 15:06:01.513443553 +0200
-@@ -32,6 +32,7 @@
- # Logging
- # obsoletes QuietMode and FascistLogging
- #SyslogFacility AUTH
-+SyslogFacility AUTHPRIV
- #LogLevel INFO
- # Authentication:
-@@ -65,9 +66,11 @@ AuthorizedKeysFile  .ssh/authorized_keys
- # To disable tunneled clear text passwords, change to no here!
- #PasswordAuthentication yes
- #PermitEmptyPasswords no
-+PasswordAuthentication yes
- # Change to no to disable s/key passwords
- #ChallengeResponseAuthentication yes
-+ChallengeResponseAuthentication no
- # Kerberos options
- #KerberosAuthentication no
-@@ -77,7 +80,9 @@ AuthorizedKeysFile   .ssh/authorized_keys
- # GSSAPI options
- #GSSAPIAuthentication no
-+GSSAPIAuthentication yes
- #GSSAPICleanupCredentials yes
-+GSSAPICleanupCredentials yes
- # Set this to 'yes' to enable PAM authentication, account processing, 
- # and session processing. If this is enabled, PAM authentication will 
-@@ -89,6 +94,7 @@ AuthorizedKeysFile   .ssh/authorized_keys
- # PAM authentication, then enable this but set PasswordAuthentication
- # and ChallengeResponseAuthentication to 'no'.
- #UsePAM no
-+UsePAM yes
- #TwoFactorAuthentication no
- #SecondPubkeyAuthentication yes
-@@ -101,6 +107,7 @@ AuthorizedKeysFile .ssh/authorized_keys
- #AllowTcpForwarding yes
- #GatewayPorts no
- #X11Forwarding no
-+X11Forwarding yes
- #X11DisplayOffset 10
- #X11UseLocalhost yes
- #PrintMotd yes
-@@ -121,6 +128,12 @@ AuthorizedKeysFile        .ssh/authorized_keys
- # no default banner path
- #Banner none
-+# Accept locale-related environment variables
-+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
-+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
-+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
-+AcceptEnv XMODIFIERS
-+
- # override default of no subsystems
- Subsystem     sftp    /usr/libexec/sftp-server
diff --git a/openssh/patches/openssh-5.9p1-ipv6man.patch b/openssh/patches/openssh-5.9p1-ipv6man.patch
deleted file mode 100644 (file)
index ece1a73..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1
---- openssh-5.9p0/ssh.1.ipv6man        2011-08-05 22:17:32.000000000 +0200
-+++ openssh-5.9p0/ssh.1        2011-08-31 13:08:34.880024485 +0200
-@@ -1400,6 +1400,8 @@ manual page for more information.
- .Nm
- exits with the exit status of the remote command or with 255
- if an error occurred.
-+.Sh IPV6
-+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
- .Sh SEE ALSO
- .Xr scp 1 ,
- .Xr sftp 1 ,
-diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8
---- openssh-5.9p0/sshd.8.ipv6man       2011-08-05 22:17:32.000000000 +0200
-+++ openssh-5.9p0/sshd.8       2011-08-31 13:10:34.129039094 +0200
-@@ -940,6 +940,8 @@ concurrently for different ports, this c
- started last).
- The content of this file is not sensitive; it can be world-readable.
- .El
-+.Sh IPV6
-+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
- .Sh SEE ALSO
- .Xr scp 1 ,
- .Xr sftp 1 ,
diff --git a/openssh/patches/openssh-5.9p1-keygen.patch b/openssh/patches/openssh-5.9p1-keygen.patch
deleted file mode 100644 (file)
index 69d4a6f..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-diff -up openssh-5.9p0/ssh-keygen.0.keygen openssh-5.9p0/ssh-keygen.0
---- openssh-5.9p0/ssh-keygen.0.keygen  2011-08-29 16:30:02.000000000 +0200
-+++ openssh-5.9p0/ssh-keygen.0 2011-08-30 13:47:56.208087184 +0200
-@@ -4,7 +4,7 @@ NAME
-      ssh-keygen - authentication key generation, management and conversion
- SYNOPSIS
--     ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment]
-+     ssh-keygen [-q] [-o] [-b bits] -t type [-N new_passphrase] [-C comment]
-                 [-f output_keyfile]
-      ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
-      ssh-keygen -i [-m key_format] [-f input_keyfile]
-@@ -181,6 +181,8 @@ DESCRIPTION
-              principals may be specified, separated by commas.  Please see the
-              CERTIFICATES section for details.
-+     -o      Overwrite the key without prompting user.
-+
-      -O option
-              Specify a certificate option when signing a key.  This option may
-              be specified multiple times.  Please see the CERTIFICATES section
-diff -up openssh-5.9p0/ssh-keygen.1.keygen openssh-5.9p0/ssh-keygen.1
---- openssh-5.9p0/ssh-keygen.1.keygen  2011-08-30 13:32:30.787149917 +0200
-+++ openssh-5.9p0/ssh-keygen.1 2011-08-30 13:46:42.638087171 +0200
-@@ -45,6 +45,7 @@
- .Bk -words
- .Nm ssh-keygen
- .Op Fl q
-+.Op Fl o
- .Op Fl b Ar bits
- .Fl t Ar type
- .Op Fl N Ar new_passphrase
-@@ -339,6 +340,8 @@ Multiple principals may be specified, se
- Please see the
- .Sx CERTIFICATES
- section for details.
-+.It Fl o
-+Overwrite the key without prompting user.
- .It Fl O Ar option
- Specify a certificate option when signing a key.
- This option may be specified multiple times.
-diff -up openssh-5.9p0/ssh-keygen.c.keygen openssh-5.9p0/ssh-keygen.c
---- openssh-5.9p0/ssh-keygen.c.keygen  2011-08-30 13:32:20.268149992 +0200
-+++ openssh-5.9p0/ssh-keygen.c 2011-08-30 13:39:34.550214102 +0200
-@@ -73,6 +73,7 @@ int change_passphrase = 0;
- int change_comment = 0;
- int quiet = 0;
-+int overwrite = 0;
- int log_level = SYSLOG_LEVEL_INFO;
-@@ -1959,7 +1960,7 @@ main(int argc, char **argv)
-               exit(1);
-       }
--      while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:"
-+      while ((opt = getopt(argc, argv, "AegiqopclBHLhvxXyF:b:f:t:D:I:P:m:N:n:"
-           "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) {
-               switch (opt) {
-               case 'A':
-@@ -2042,6 +2043,9 @@ main(int argc, char **argv)
-               case 'q':
-                       quiet = 1;
-                       break;
-+              case 'o':
-+                      overwrite = 1;
-+                      break;
-               case 'e':
-               case 'x':
-                       /* export key */
-@@ -2278,7 +2282,7 @@ main(int argc, char **argv)
-               }
-       }
-       /* If the file already exists, ask the user to confirm. */
--      if (stat(identity_file, &st) >= 0) {
-+      if (!overwrite && stat(identity_file, &st) >= 0) {
-               char yesno[3];
-               printf("%s already exists.\n", identity_file);
-               printf("Overwrite (y/n)? ");
diff --git a/openssh/patches/openssh-5.9p1-randclean.patch b/openssh/patches/openssh-5.9p1-randclean.patch
deleted file mode 100644 (file)
index a2c5d33..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -up openssh-5.9p0/entropy.c.randclean openssh-5.9p0/entropy.c
---- openssh-5.9p0/entropy.c.randclean  2011-08-30 13:52:45.000000000 +0200
-+++ openssh-5.9p0/entropy.c    2011-08-30 13:57:44.630111338 +0200
-@@ -217,6 +217,9 @@ seed_rng(void)
-               fatal("OpenSSL version mismatch. Built against %lx, you "
-                   "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
-+      /* clean the PRNG status when exiting the program */
-+      atexit(RAND_cleanup);
-+
- #ifndef OPENSSL_PRNG_ONLY
-       if (RAND_status() == 1) {
-               debug3("RNG is ready, skipping seeding");
diff --git a/openssh/patches/openssh-5.9p1-sftp-chroot.patch b/openssh/patches/openssh-5.9p1-sftp-chroot.patch
deleted file mode 100644 (file)
index cfe4366..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-diff -up openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.c
---- openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot      2011-09-01 04:12:22.743024608 +0200
-+++ openssh-5.9p0/openbsd-compat/port-linux.c  2011-09-01 04:12:23.069088065 +0200
-@@ -503,6 +503,23 @@ ssh_selinux_change_context(const char *n
-       xfree(newctx);
- }
-+void
-+ssh_selinux_copy_context(void)
-+{
-+      char *ctx;
-+
-+      if (!ssh_selinux_enabled())
-+              return;
-+
-+      if (getexeccon((security_context_t *)&ctx) < 0) {
-+              logit("%s: getcon failed with %s", __func__, strerror (errno));
-+              return;
-+      }
-+      if (setcon(ctx) < 0)
-+              logit("%s: setcon failed with %s", __func__, strerror (errno));
-+      xfree(ctx);
-+}
-+
- #endif /* WITH_SELINUX */
- #ifdef LINUX_OOM_ADJUST
-diff -up openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.h
---- openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot      2011-01-25 02:16:18.000000000 +0100
-+++ openssh-5.9p0/openbsd-compat/port-linux.h  2011-09-01 04:12:23.163088777 +0200
-@@ -24,6 +24,7 @@ int ssh_selinux_enabled(void);
- void ssh_selinux_setup_pty(char *, const char *);
- void ssh_selinux_setup_exec_context(char *);
- void ssh_selinux_change_context(const char *);
-+void ssh_selinux_chopy_context(void);
- void ssh_selinux_setfscreatecon(const char *);
- #endif
-diff -up openssh-5.9p0/session.c.sftp-chroot openssh-5.9p0/session.c
---- openssh-5.9p0/session.c.sftp-chroot        2011-09-01 04:12:19.698049195 +0200
-+++ openssh-5.9p0/session.c    2011-09-01 04:40:03.598148719 +0200
-@@ -1519,6 +1519,9 @@ do_setusercontext(struct passwd *pw)
-                           pw->pw_uid);
-                       chroot_path = percent_expand(tmp, "h", pw->pw_dir,
-                           "u", pw->pw_name, (char *)NULL);
-+#ifdef WITH_SELINUX
-+                      ssh_selinux_change_context("chroot_user_t");
-+#endif
-                       safely_chroot(chroot_path, pw->pw_uid);
-                       free(tmp);
-                       free(chroot_path);
-@@ -1788,7 +1791,10 @@ do_child(Session *s, const char *command
-               optind = optreset = 1;
-               __progname = argv[0];
- #ifdef WITH_SELINUX
--              ssh_selinux_change_context("sftpd_t");
-+              if (options.chroot_directory == NULL ||
-+                  strcasecmp(options.chroot_directory, "none") == 0) {
-+                      ssh_selinux_copy_context();
-+              }
- #endif
-               exit(sftp_server_main(i, argv, s->pw));
-       }
diff --git a/openssh/patches/openssh-6.0p1-entropy.patch b/openssh/patches/openssh-6.0p1-entropy.patch
deleted file mode 100644 (file)
index 79f05f4..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-diff -up openssh-6.0p1/entropy.c.entropy openssh-6.0p1/entropy.c
---- openssh-6.0p1/entropy.c.entropy    2012-08-06 20:51:59.131033413 +0200
-+++ openssh-6.0p1/entropy.c    2012-08-06 20:51:59.171033257 +0200
-@@ -237,6 +237,9 @@ seed_rng(void)
-       memset(buf, '\0', sizeof(buf));
- #endif /* OPENSSL_PRNG_ONLY */
-+#ifdef __linux__
-+      linux_seed();
-+#endif /* __linux__ */
-       if (RAND_status() != 1)
-               fatal("PRNG is not seeded");
- }
-diff -up openssh-6.0p1/openbsd-compat/Makefile.in.entropy openssh-6.0p1/openbsd-compat/Makefile.in
---- openssh-6.0p1/openbsd-compat/Makefile.in.entropy   2012-08-06 20:51:59.100033534 +0200
-+++ openssh-6.0p1/openbsd-compat/Makefile.in   2012-08-06 20:51:59.171033257 +0200
-@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport
- COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
--PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o
-+PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o
- .c.o:
-       $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
-diff -up openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.0p1/openbsd-compat/port-linux-prng.c
---- openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy     2012-08-06 20:51:59.171033257 +0200
-+++ openssh-6.0p1/openbsd-compat/port-linux-prng.c     2012-08-06 20:51:59.171033257 +0200
-@@ -0,0 +1,59 @@
-+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */
-+
-+/*
-+ * Copyright (c) 2011 Jan F. Chadima <jchadima@redhat.com>
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+/*
-+ * Linux-specific portability code - prng support
-+ */
-+
-+#include "includes.h"
-+
-+#include <errno.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <openssl/rand.h>
-+
-+#include "log.h"
-+#include "xmalloc.h"
-+#include "servconf.h"
-+#include "port-linux.h"
-+#include "key.h"
-+#include "hostfile.h"
-+#include "auth.h"
-+
-+void
-+linux_seed(void)
-+{
-+      int len;
-+      char *env = getenv("SSH_USE_STRONG_RNG");
-+      char *random = "/dev/random";
-+      size_t ienv, randlen = 6;
-+
-+      if (!env || !strcmp(env, "0"))
-+              random = "/dev/urandom";
-+      else if ((ienv = atoi(env)) > 6)
-+              randlen = ienv;
-+
-+      errno = 0;
-+      if ((len = RAND_load_file(random, randlen)) != randlen) {
-+              if (errno)
-+                      fatal ("cannot read from %s, %s", random, strerror(errno));
-+              else
-+                      fatal ("EOF reading %s", random);
-+      }
-+}
-diff -up openssh-6.0p1/ssh.1.entropy openssh-6.0p1/ssh.1
---- openssh-6.0p1/ssh.1.entropy        2012-08-06 20:51:59.139033382 +0200
-+++ openssh-6.0p1/ssh.1        2012-08-06 20:51:59.174033245 +0200
-@@ -1269,6 +1269,23 @@ For more information, see the
- .Cm PermitUserEnvironment
- option in
- .Xr sshd_config 5 .
-+.Sh ENVIRONMENT
-+.Bl -tag -width Ds -compact
-+.It Ev SSH_USE_STRONG_RNG
-+The reseeding of the OpenSSL random generator is usually done from
-+.Cm /dev/urandom .
-+If the 
-+.Cm SSH_USE_STRONG_RNG
-+environment variable is set to value other than
-+.Cm 0
-+the OpenSSL random generator is reseeded from
-+.Cm /dev/random .
-+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. 
-+Minimum is 6 bytes.
-+This setting is not recommended on the computers without the hardware
-+random generator because insufficient entropy causes the connection to 
-+be blocked until enough entropy is available.
-+.El
- .Sh FILES
- .Bl -tag -width Ds -compact
- .It Pa ~/.rhosts
-diff -up openssh-6.1p1/ssh-add.0.entropy openssh-6.1p1/ssh-add.0
---- openssh-6.1p1/ssh-add.0.entropy    2012-11-12 13:11:42.717393364 +0100
-+++ openssh-6.1p1/ssh-add.0    2012-11-12 13:12:46.288108790 +0100
-@@ -81,6 +81,16 @@ ENVIRONMENT
-              Identifies the path of a UNIX-domain socket used to communicate
-              with the agent.
-+     SSH_USE_STRONG_RNG
-+             The reseeding of the OpenSSL random generator is usually done
-+             from /dev/urandom.  If the SSH_USE_STRONG_RNG environment vari-
-+             able is set to value other than 0 the OpenSSL random generator is
-+             reseeded from /dev/random.  The number of bytes read is defined
-+             by the SSH_USE_STRONG_RNG value.  Minimum is 6 bytes.  This set-
-+             ting is not recommended on the computers without the hardware
-+             random generator because insufficient entropy causes the connec-
-+             tion to be blocked until enough entropy is available.
-+
- FILES
-      ~/.ssh/identity
-              Contains the protocol version 1 RSA authentication identity of
-diff -up openssh-6.1p1/ssh-add.1.entropy openssh-6.1p1/ssh-add.1
---- openssh-6.1p1/ssh-add.1.entropy    2011-10-18 07:06:33.000000000 +0200
-+++ openssh-6.1p1/ssh-add.1    2012-11-12 13:11:24.711476108 +0100
-@@ -160,6 +160,20 @@ to make this work.)
- Identifies the path of a
- .Ux Ns -domain
- socket used to communicate with the agent.
-+.It Ev SSH_USE_STRONG_RNG
-+The reseeding of the OpenSSL random generator is usually done from
-+.Cm /dev/urandom .
-+If the 
-+.Cm SSH_USE_STRONG_RNG
-+environment variable is set to value other than
-+.Cm 0
-+the OpenSSL random generator is reseeded from
-+.Cm /dev/random .
-+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. 
-+Minimum is 6 bytes.
-+This setting is not recommended on the computers without the hardware
-+random generator because insufficient entropy causes the connection to 
-+be blocked until enough entropy is available.
- .El
- .Sh FILES
- .Bl -tag -width Ds
- .It Pa ~/.ssh/identity
-diff -up openssh-6.0p1/ssh-agent.1.entropy openssh-6.0p1/ssh-agent.1
---- openssh-6.0p1/ssh-agent.1.entropy  2010-12-01 01:50:35.000000000 +0100
-+++ openssh-6.0p1/ssh-agent.1  2012-08-06 20:51:59.172033253 +0200
-@@ -198,6 +198,24 @@ sockets used to contain the connection t
- These sockets should only be readable by the owner.
- The sockets should get automatically removed when the agent exits.
- .El
-+.Sh ENVIRONMENT
-+.Bl -tag -width Ds -compact
-+.Pp
-+.It Pa SSH_USE_STRONG_RNG
-+The reseeding of the OpenSSL random generator is usually done from
-+.Cm /dev/urandom .
-+If the 
-+.Cm SSH_USE_STRONG_RNG
-+environment variable is set to value other than
-+.Cm 0
-+the OpenSSL random generator is reseeded from
-+.Cm /dev/random .
-+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. 
-+Minimum is 6 bytes.
-+This setting is not recommended on the computers without the hardware
-+random generator because insufficient entropy causes the connection to 
-+be blocked until enough entropy is available.
-+.El
- .Sh SEE ALSO
- .Xr ssh 1 ,
- .Xr ssh-add 1 ,
-diff -up openssh-6.0p1/sshd.8.entropy openssh-6.0p1/sshd.8
---- openssh-6.0p1/sshd.8.entropy       2012-08-06 20:51:59.139033382 +0200
-+++ openssh-6.0p1/sshd.8       2012-08-06 20:51:59.174033245 +0200
-@@ -943,6 +943,24 @@ concurrently for different ports, this c
- started last).
- The content of this file is not sensitive; it can be world-readable.
- .El
-+.Sh ENVIRONMENT
-+.Bl -tag -width Ds -compact
-+.Pp
-+.It Pa SSH_USE_STRONG_RNG
-+The reseeding of the OpenSSL random generator is usually done from
-+.Cm /dev/urandom .
-+If the 
-+.Cm SSH_USE_STRONG_RNG
-+environment variable is set to value other than
-+.Cm 0
-+the OpenSSL random generator is reseeded from
-+.Cm /dev/random .
-+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. 
-+Minimum is 6 bytes.
-+This setting is not recommended on the computers without the hardware
-+random generator because insufficient entropy causes the connection to 
-+be blocked until enough entropy is available.
-+.El
- .Sh IPV6
- IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
- .Sh SEE ALSO
-diff -up openssh-6.0p1/ssh-keygen.1.entropy openssh-6.0p1/ssh-keygen.1
---- openssh-6.0p1/ssh-keygen.1.entropy 2011-10-18 07:05:21.000000000 +0200
-+++ openssh-6.0p1/ssh-keygen.1 2012-08-06 20:51:59.173033249 +0200
-@@ -675,6 +675,24 @@ Contains Diffie-Hellman groups used for
- The file format is described in
- .Xr moduli 5 .
- .El
-+.Sh ENVIRONMENT
-+.Bl -tag -width Ds -compact
-+.Pp
-+.It Pa SSH_USE_STRONG_RNG
-+The reseeding of the OpenSSL random generator is usually done from
-+.Cm /dev/urandom .
-+If the 
-+.Cm SSH_USE_STRONG_RNG
-+environment variable is set to value other than
-+.Cm 0
-+the OpenSSL random generator is reseeded from
-+.Cm /dev/random .
-+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. 
-+Minimum is 6 bytes.
-+This setting is not recommended on the computers without the hardware
-+random generator because insufficient entropy causes the connection to 
-+be blocked until enough entropy is available.
-+.El
- .Sh SEE ALSO
- .Xr ssh 1 ,
- .Xr ssh-add 1 ,
-diff -up openssh-6.0p1/ssh-keysign.8.entropy openssh-6.0p1/ssh-keysign.8
---- openssh-6.0p1/ssh-keysign.8.entropy        2010-08-31 14:41:14.000000000 +0200
-+++ openssh-6.0p1/ssh-keysign.8        2012-08-06 20:51:59.173033249 +0200
-@@ -78,6 +78,24 @@ must be set-uid root if host-based authe
- If these files exist they are assumed to contain public certificate
- information corresponding with the private keys above.
- .El
-+.Sh ENVIRONMENT
-+.Bl -tag -width Ds -compact
-+.Pp
-+.It Pa SSH_USE_STRONG_RNG
-+The reseeding of the OpenSSL random generator is usually done from
-+.Cm /dev/urandom .
-+If the 
-+.Cm SSH_USE_STRONG_RNG
-+environment variable is set to value other than
-+.Cm 0
-+the OpenSSL random generator is reseeded from
-+.Cm /dev/random .
-+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. 
-+Minimum is 6 bytes.
-+This setting is not recommended on the computers without the hardware
-+random generator because insufficient entropy causes the connection to 
-+be blocked until enough entropy is available.
-+.El
- .Sh SEE ALSO
- .Xr ssh 1 ,
- .Xr ssh-keygen 1 ,
diff --git a/openssh/patches/openssh-6.1p1-akc.patch b/openssh/patches/openssh-6.1p1-akc.patch
deleted file mode 100644 (file)
index 0401ba0..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-diff -up openssh-6.1p1/auth2-pubkey.c.akc openssh-6.1p1/auth2-pubkey.c
---- openssh-6.1p1/auth2-pubkey.c.akc   2012-11-28 17:12:43.238524384 +0100
-+++ openssh-6.1p1/auth2-pubkey.c       2012-11-28 17:12:43.263524297 +0100
-@@ -27,9 +27,13 @@
- #include <sys/types.h>
- #include <sys/stat.h>
-+#include <sys/wait.h>
-+#include <errno.h>
- #include <fcntl.h>
-+#include <paths.h>
- #include <pwd.h>
-+#include <signal.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
-@@ -260,7 +264,7 @@ match_principals_file(char *file, struct
-                       if (strcmp(cp, cert->principals[i]) == 0) {
-                               debug3("matched principal \"%.100s\" "
-                                   "from file \"%s\" on line %lu",
--                                  cert->principals[i], file, linenum);
-+                                  cert->principals[i], file, linenum);
-                               if (auth_parse_options(pw, line_opts,
-                                   file, linenum) != 1)
-                                       continue;
-@@ -273,31 +277,22 @@ match_principals_file(char *file, struct
-       fclose(f);
-       restore_uid();
-       return 0;
--}     
-+}
--/* return 1 if user allows given key */
-+/*
-+ * Checks whether key is allowed in authorized_keys-format file,
-+ * returns 1 if the key is allowed or 0 otherwise.
-+ */
- static int
--user_key_allowed2(struct passwd *pw, Key *key, char *file)
-+check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
- {
-       char line[SSH_MAX_PUBKEY_BYTES];
-       const char *reason;
-       int found_key = 0;
--      FILE *f;
-       u_long linenum = 0;
-       Key *found;
-       char *fp;
--      /* Temporarily use the user's uid. */
--      temporarily_use_uid(pw);
--
--      debug("trying public key file %s", file);
--      f = auth_openkeyfile(file, pw, options.strict_modes);
--
--      if (!f) {
--              restore_uid();
--              return 0;
--      }
--
-       found_key = 0;
-       found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
-@@ -390,8 +385,6 @@ user_key_allowed2(struct passwd *pw, Key
-                       break;
-               }
-       }
--      restore_uid();
--      fclose(f);
-       key_free(found);
-       if (!found_key)
-               debug2("key not found");
-@@ -453,7 +446,173 @@ user_cert_trusted_ca(struct passwd *pw,
-       return ret;
- }
--/* check whether given key is in .ssh/authorized_keys* */
-+/*
-+ * Checks whether key is allowed in file.
-+ * returns 1 if the key is allowed or 0 otherwise.
-+ */
-+static int
-+user_key_allowed2(struct passwd *pw, Key *key, char *file)
-+{
-+      FILE *f;
-+      int found_key = 0;
-+
-+      /* Temporarily use the user's uid. */
-+      temporarily_use_uid(pw);
-+
-+      debug("trying public key file %s", file);
-+      if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
-+              found_key = check_authkeys_file(f, file, key, pw);
-+              fclose(f);
-+      }
-+
-+      restore_uid();
-+      return found_key;
-+}
-+
-+/*
-+ * Checks whether key is allowed in output of command.
-+ * returns 1 if the key is allowed or 0 otherwise.
-+ */
-+static int
-+user_key_command_allowed2(struct passwd *user_pw, Key *key)
-+{
-+      FILE *f;
-+      int ok, found_key = 0;
-+      struct passwd *pw;
-+      struct stat st;
-+      int status, devnull, p[2], i;
-+      pid_t pid;
-+      char errmsg[512];
-+
-+      if (options.authorized_keys_command == NULL ||
-+          options.authorized_keys_command[0] != '/')
-+              return 0;
-+
-+      /* If no user specified to run commands the default to target user */
-+      if (options.authorized_keys_command_user == NULL)
-+              pw = user_pw;
-+      else {
-+              pw = getpwnam(options.authorized_keys_command_user);
-+              if (pw == NULL) {
-+                      error("AuthorizedKeyCommandUser \"%s\" not found: %s",
-+                          options.authorized_keys_command, strerror(errno));
-+                      return 0;
-+              }
-+      }
-+
-+      temporarily_use_uid(pw);
-+      if (stat(options.authorized_keys_command, &st) < 0) {
-+              error("Could not stat AuthorizedKeysCommand \"%s\": %s",
-+                  options.authorized_keys_command, strerror(errno));
-+              goto out;
-+      }
-+
-+      if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
-+          errmsg, sizeof(errmsg)) != 0) {
-+              error("Unsafe AuthorizedKeysCommand: %s", errmsg);
-+              goto out;
-+      }
-+
-+      /* open the pipe and read the keys */
-+      if (pipe(p) != 0) {
-+              error("%s: pipe: %s", __func__, strerror(errno));
-+              goto out;
-+      }
-+
-+      debug3("Running AuthorizedKeysCommand: \"%s\" as \"%s\"",
-+          options.authorized_keys_command, pw->pw_name);
-+
-+      /*
-+       * Don't want to call this in the child, where it can fatal() and
-+       * run cleanup_exit() code.
-+       */
-+      restore_uid();
-+
-+      switch ((pid = fork())) {
-+      case -1: /* error */
-+              error("%s: fork: %s", __func__, strerror(errno));
-+              close(p[0]);
-+              close(p[1]);
-+              return 0;
-+      case 0: /* child */
-+              for (i = 0; i < NSIG; i++)
-+                      signal(i, SIG_DFL);
-+
-+              /* Don't use permanently_set_uid() here to avoid fatal() */
-+              if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
-+                      error("setresgid %u: %s", (u_int)pw->pw_gid,
-+                          strerror(errno));
-+                      _exit(1);
-+              }
-+              if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
-+                      error("setresuid %u: %s", (u_int)pw->pw_uid,
-+                          strerror(errno));
-+                      _exit(1);
-+              }
-+
-+              close(p[0]);
-+              if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
-+                      error("%s: open %s: %s", __func__, _PATH_DEVNULL,
-+                          strerror(errno));
-+                      _exit(1);
-+              }
-+              if (dup2(devnull, STDIN_FILENO) == -1 ||
-+                  dup2(p[1], STDOUT_FILENO) == -1 ||
-+                  dup2(devnull, STDERR_FILENO) == -1) {
-+                      error("%s: dup2: %s", __func__, strerror(errno));
-+                      _exit(1);
-+              }
-+              closefrom(STDERR_FILENO + 1);
-+
-+              execl(options.authorized_keys_command,
-+                  options.authorized_keys_command, pw->pw_name, NULL);
-+
-+              error("AuthorizedKeysCommand %s exec failed: %s",
-+                  options.authorized_keys_command, strerror(errno));
-+              _exit(127);
-+      default: /* parent */
-+              break;
-+      }
-+      
-+      temporarily_use_uid(pw);
-+
-+      close(p[1]);
-+      if ((f = fdopen(p[0], "r")) == NULL) {
-+              error("%s: fdopen: %s", __func__, strerror(errno));
-+              close(p[0]);
-+              /* Don't leave zombie child */
-+              while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
-+                      ;
-+              goto out;
-+      }
-+      ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
-+      fclose(f);
-+
-+      while (waitpid(pid, &status, 0) == -1) {
-+              if (errno != EINTR) {
-+                      error("%s: waitpid: %s", __func__, strerror(errno));
-+                      goto out;
-+              }
-+      }
-+      if (WIFSIGNALED(status)) {
-+              error("AuthorizedKeysCommand %s exited on signal %d",
-+                  options.authorized_keys_command, WTERMSIG(status));
-+              goto out;
-+      } else if (WEXITSTATUS(status) != 0) {
-+              error("AuthorizedKeysCommand %s returned status %d",
-+                  options.authorized_keys_command, WEXITSTATUS(status));
-+              goto out;
-+      }
-+      found_key = ok;
-+ out:
-+      restore_uid();
-+
-+      return found_key;
-+}
-+
-+/*
-+ * Check whether key authenticates and authorises the user.
-+ */
- int
- user_key_allowed(struct passwd *pw, Key *key)
- {
-@@ -469,6 +628,10 @@ user_key_allowed(struct passwd *pw, Key
-       if (success)
-               return success;
-+      success = user_key_command_allowed2(pw, key);
-+      if (success > 0)
-+              return success;
-+
-       for (i = 0; !success && i < options.num_authkeys_files; i++) {
-               file = expand_authorized_keys(
-                   options.authorized_keys_files[i], pw);
-diff -up openssh-6.1p1/auth.c.akc openssh-6.1p1/auth.c
---- openssh-6.1p1/auth.c.akc   2012-11-28 17:12:43.187524558 +0100
-+++ openssh-6.1p1/auth.c       2012-11-28 17:12:43.263524297 +0100
-@@ -411,39 +411,41 @@ check_key_in_hostfiles(struct passwd *pw
- /*
-- * Check a given file for security. This is defined as all components
-+ * Check a given path for security. This is defined as all components
-  * of the path to the file must be owned by either the owner of
-  * of the file or root and no directories must be group or world writable.
-  *
-  * XXX Should any specific check be done for sym links ?
-  *
-- * Takes an open file descriptor, the file name, a uid and and
-+ * Takes an the file name, its stat information (preferably from fstat() to
-+ * avoid races), the uid of the expected owner, their home directory and an
-  * error buffer plus max size as arguments.
-  *
-  * Returns 0 on success and -1 on failure
-  */
--static int
--secure_filename(FILE *f, const char *file, struct passwd *pw,
--    char *err, size_t errlen)
-+int
-+auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
-+    uid_t uid, char *err, size_t errlen)
- {
--      uid_t uid = pw->pw_uid;
-       char buf[MAXPATHLEN], homedir[MAXPATHLEN];
-       char *cp;
-       int comparehome = 0;
-       struct stat st;
--      if (realpath(file, buf) == NULL) {
--              snprintf(err, errlen, "realpath %s failed: %s", file,
-+      if (realpath(name, buf) == NULL) {
-+              snprintf(err, errlen, "realpath %s failed: %s", name,
-                   strerror(errno));
-               return -1;
-       }
--      if (realpath(pw->pw_dir, homedir) != NULL)
-+      if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
-               comparehome = 1;
--      /* check the open file to avoid races */
--      if (fstat(fileno(f), &st) < 0 ||
--          (st.st_uid != 0 && st.st_uid != uid) ||
--          (st.st_mode & 022) != 0) {
-+      if (!S_ISREG(stp->st_mode)) {
-+              snprintf(err, errlen, "%s is not a regular file", buf);
-+              return -1;
-+      }
-+      if ((stp->st_uid != 0 && stp->st_uid != uid) ||
-+          (stp->st_mode & 022) != 0) {
-               snprintf(err, errlen, "bad ownership or modes for file %s",
-                   buf);
-               return -1;
-@@ -479,6 +481,31 @@ secure_filename(FILE *f, const char *fil
-       return 0;
- }
-+/*
-+ * Version of secure_path() that accepts an open file descriptor to
-+ * avoid races.
-+ *
-+ * Returns 0 on success and -1 on failure
-+ */
-+static int
-+secure_filename(FILE *f, const char *file, struct passwd *pw,
-+    char *err, size_t errlen)
-+{
-+      uid_t uid = pw->pw_uid;
-+      char buf[MAXPATHLEN], homedir[MAXPATHLEN];
-+      char *cp;
-+      int comparehome = 0;
-+      struct stat st;
-+
-+      /* check the open file to avoid races */
-+      if (fstat(fileno(f), &st) < 0) {
-+              snprintf(err, errlen, "cannot stat file %s: %s",
-+                  buf, strerror(errno));
-+              return -1;
-+      }
-+      return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
-+}
-+
- static FILE *
- auth_openfile(const char *file, struct passwd *pw, int strict_modes,
-     int log_missing, char *file_type)
-diff -up openssh-6.1p1/auth.h.akc openssh-6.1p1/auth.h
---- openssh-6.1p1/auth.h.akc   2012-11-28 17:12:43.239524381 +0100
-+++ openssh-6.1p1/auth.h       2012-11-28 17:12:43.263524297 +0100
-@@ -125,6 +125,10 @@ int        auth_rhosts_rsa_key_allowed(struct
- int    hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
- int    user_key_allowed(struct passwd *, Key *);
-+struct stat;
-+int    auth_secure_path(const char *, struct stat *, const char *, uid_t,
-+    char *, size_t);
-+
- #ifdef KRB5
- int   auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
- int   auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
-diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c
---- openssh-6.1p1/servconf.c.akc       2012-11-28 17:12:43.198524521 +0100
-+++ openssh-6.1p1/servconf.c   2012-11-28 17:14:50.314005026 +0100
-@@ -137,6 +137,8 @@ initialize_server_options(ServerOptions
-       options->num_permitted_opens = -1;
-       options->adm_forced_command = NULL;
-       options->chroot_directory = NULL;
-+      options->authorized_keys_command = NULL;
-+      options->authorized_keys_command_user = NULL;
-       options->zero_knowledge_password_authentication = -1;
-       options->revoked_keys_file = NULL;
-       options->trusted_user_ca_keys = NULL;
-@@ -331,6 +333,7 @@ typedef enum {
-       sZeroKnowledgePasswordAuthentication, sHostCertificate,
-       sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
-       sKexAlgorithms, sIPQoS, sVersionAddendum,
-+      sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
-       sAuthenticationMethods,
-       sDeprecated, sUnsupported
- } ServerOpCodes;
-@@ -457,6 +460,9 @@ static struct {
-       { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
-       { "ipqos", sIPQoS, SSHCFG_ALL },
-       { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
-+      { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
-+      { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL },
-+      { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
-       { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
-       { NULL, sBadOption, 0 }
- };
-@@ -1520,6 +1526,26 @@ process_server_config_line(ServerOptions
-               }
-               return 0;
-+      case sAuthorizedKeysCommand:
-+              len = strspn(cp, WHITESPACE);
-+              if (*activep && options->authorized_keys_command == NULL) {
-+                      options->authorized_keys_command = xstrdup(cp + len);
-+                      if (*options->authorized_keys_command != '/') {
-+                              fatal("%.200s line %d: AuthorizedKeysCommand "
-+                                  "must be an absolute path",
-+                                  filename, linenum);
-+                      }
-+              }
-+              return 0;
-+
-+      case sAuthorizedKeysCommandUser:
-+              charptr = &options->authorized_keys_command_user;
-+
-+              arg = strdelim(&cp);
-+              if (*activep && *charptr == NULL)
-+                      *charptr = xstrdup(arg);
-+              break;
-+
-       case sDeprecated:
-               logit("%s line %d: Deprecated option %s",
-                   filename, linenum, arg);
-@@ -1670,6 +1696,8 @@ copy_set_server_options(ServerOptions *d
-       M_CP_INTOPT(hostbased_uses_name_from_packet_only);
-       M_CP_INTOPT(kbd_interactive_authentication);
-       M_CP_INTOPT(zero_knowledge_password_authentication);
-+      M_CP_STROPT(authorized_keys_command);
-+      M_CP_STROPT(authorized_keys_command_user);
-       M_CP_INTOPT(permit_root_login);
-       M_CP_INTOPT(permit_empty_passwd);
-@@ -1930,6 +1958,8 @@ dump_config(ServerOptions *o)
-       dump_cfg_string(sAuthorizedPrincipalsFile,
-           o->authorized_principals_file);
-       dump_cfg_string(sVersionAddendum, o->version_addendum);
-+      dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
-+      dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
-       /* string arguments requiring a lookup */
-       dump_cfg_string(sLogLevel, log_level_name(o->log_level));
-diff -up openssh-6.1p1/servconf.h.akc openssh-6.1p1/servconf.h
---- openssh-6.1p1/servconf.h.akc       2012-11-28 17:12:43.000000000 +0100
-+++ openssh-6.1p1/servconf.h   2012-11-28 17:18:41.217055157 +0100
-@@ -167,6 +167,8 @@ typedef struct {
-       char   *revoked_keys_file;
-       char   *trusted_user_ca_keys;
-       char   *authorized_principals_file;
-+      char   *authorized_keys_command;
-+      char   *authorized_keys_command_user;
-       char   *version_addendum;       /* Appended to SSH banner */
-diff -up openssh-6.1p1/sshd.c.akc openssh-6.1p1/sshd.c
---- openssh-6.1p1/sshd.c.akc   2012-11-28 17:12:43.245524360 +0100
-+++ openssh-6.1p1/sshd.c       2012-11-28 17:12:43.265524291 +0100
-@@ -366,9 +366,20 @@ main_sigchld_handler(int sig)
- static void
- grace_alarm_handler(int sig)
- {
-+      pid_t pgid;
-+
-       if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
-               kill(pmonitor->m_pid, SIGALRM);
-+      /*
-+       * Try to kill any processes that we have spawned, E.g. authorized
-+       * keys command helpers.
-+       */
-+      if ((pgid = getpgid(0)) == getpid()) {
-+              signal(SIGTERM, SIG_IGN);
-+              killpg(pgid, SIGTERM);
-+      }
-+
-       /* Log error and exit. */
-       sigdie("Timeout before authentication for %s", get_remote_ipaddr());
- }
-diff -up openssh-6.1p1/sshd_config.0.akc openssh-6.1p1/sshd_config.0
---- openssh-6.1p1/sshd_config.0.akc    2012-08-29 02:53:04.000000000 +0200
-+++ openssh-6.1p1/sshd_config.0        2012-11-28 17:12:43.265524291 +0100
-@@ -71,6 +71,23 @@ DESCRIPTION
-              See PATTERNS in ssh_config(5) for more information on patterns.
-+     AuthorizedKeysCommand
-+
-+             Specifies a program to be used for lookup of the user's
-+           public keys.  The program will be invoked with its first
-+           argument the name of the user being authorized, and should produce
-+           on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS
-+           in sshd(8)).  By default (or when set to the empty string) there is no
-+           AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
-+           authorize the user, authorization falls through to the
-+           AuthorizedKeysFile.  Note that this option has an effect
-+           only with PubkeyAuthentication turned on.
-+
-+     AuthorizedKeysCommandRunAs
-+             Specifies the user under whose account the AuthorizedKeysCommand is run.
-+             Empty string (the default value) means the user being authorized
-+             is used.
-+
-      AuthorizedKeysFile
-              Specifies the file that contains the public keys that can be used
-              for user authentication.  The format is described in the
-@@ -402,7 +419,8 @@ DESCRIPTION
-              Only a subset of keywords may be used on the lines following a
-              Match keyword.  Available keywords are AcceptEnv,
-              AllowAgentForwarding, AllowGroups, AllowTcpForwarding,
--             AllowUsers, AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner,
-+             AllowUsers, AuthorizedKeysFile, AuthorizedKeysCommand,
-+             AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, Banner,
-              ChrootDirectory, DenyGroups, DenyUsers, ForceCommand,
-              GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication,
-              HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
-diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5
---- openssh-6.1p1/sshd_config.5.akc    2012-11-28 17:12:43.199524517 +0100
-+++ openssh-6.1p1/sshd_config.5        2012-11-28 17:16:23.736624980 +0100
-@@ -173,6 +173,20 @@ Note that each authentication method lis
- in the configuration.
- The default is not to require multiple authentication; successful completion
- of a single authentication method is sufficient.
-+.It Cm AuthorizedKeysCommand
-+Specifies a program to be used for lookup of the user's public keys.
-+The program will be invoked with a single argument of the username
-+being authenticated, and should produce on standard output zero or
-+more lines of authorized_keys output (see AUTHORIZED_KEYS in
-+.Xr sshd 8 )
-+If a key supplied by AuthorizedKeysCommand does not successfully authenticate
-+and authorize the user then public key authentication continues using the usual
-+.Cm AuthorizedKeysFile
-+files.
-+By default, no AuthorizedKeysCommand is run.
-+.It Cm AuthorizedKeysCommandUser
-+Specifies the user under whose account the AuthorizedKeysCommand is run.
-+The default is the user being authenticated.
- .It Cm AuthorizedKeysFile
- Specifies the file that contains the public keys that can be used
- for user authentication.
-@@ -734,6 +748,8 @@ Available keywords are
- .Cm AllowTcpForwarding ,
- .Cm AllowUsers ,
- .Cm AuthenticationMethods ,
-+.Cm AuthorizedKeysCommand ,
-+.Cm AuthorizedKeysCommandUser ,
- .Cm AuthorizedKeysFile ,
- .Cm AuthorizedPrincipalsFile ,
- .Cm Banner ,
-@@ -749,6 +765,7 @@ Available keywords are
- .Cm KerberosAuthentication ,
- .Cm MaxAuthTries ,
- .Cm MaxSessions ,
-+.Cm PubkeyAuthentication ,
- .Cm PasswordAuthentication ,
- .Cm PermitEmptyPasswords ,
- .Cm PermitOpen ,
-diff -up openssh-6.1p1/sshd_config.akc openssh-6.1p1/sshd_config
---- openssh-6.1p1/sshd_config.akc      2012-07-31 04:21:34.000000000 +0200
-+++ openssh-6.1p1/sshd_config  2012-11-28 17:12:43.265524291 +0100
-@@ -49,6 +49,9 @@
- # but this is overridden so installations will only check .ssh/authorized_keys
- AuthorizedKeysFile    .ssh/authorized_keys
-+#AuthorizedKeysCommand none
-+#AuthorizedKeysCommandUser nobody
-+
- #AuthorizedPrincipalsFile none
- # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
diff --git a/openssh/patches/openssh-6.1p1-askpass-ld.patch b/openssh/patches/openssh-6.1p1-askpass-ld.patch
deleted file mode 100644 (file)
index f7a7fac..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-diff -up openssh-6.1p1/contrib/Makefile.askpass-ld openssh-6.1p1/contrib/Makefile
---- openssh-6.1p1/contrib/Makefile.askpass-ld  2012-05-19 07:24:37.000000000 +0200
-+++ openssh-6.1p1/contrib/Makefile     2012-09-14 20:35:47.565704718 +0200
-@@ -4,12 +4,12 @@ all:
-       @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2"
- gnome-ssh-askpass1: gnome-ssh-askpass1.c
--      $(CC) `gnome-config --cflags gnome gnomeui` \
-+      $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \
-               gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \
-               `gnome-config --libs gnome gnomeui`
- gnome-ssh-askpass2: gnome-ssh-askpass2.c
--      $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \
-+      $(CC) ${CFLAGS} `$(PKG_CONFIG) --cflags gtk+-2.0` \
-               gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \
-               `$(PKG_CONFIG) --libs gtk+-2.0 x11`
diff --git a/openssh/patches/openssh-6.1p1-authenticationmethods.patch b/openssh/patches/openssh-6.1p1-authenticationmethods.patch
deleted file mode 100644 (file)
index 7b5a06a..0000000
+++ /dev/null
@@ -1,841 +0,0 @@
-diff --git a/auth.c b/auth.c
-index ee0cb05..1b2fc2b 100644
---- a/auth.c
-+++ b/auth.c
-@@ -251,7 +251,8 @@ allowed_user(struct passwd * pw)
- }
- void
--auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
-+auth_log(Authctxt *authctxt, int authenticated, int partial,
-+    const char *method, const char *submethod, const char *info)
- {
-       void (*authlog) (const char *fmt,...) = verbose;
-       char *authmsg;
-@@ -268,12 +269,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
-       if (authctxt->postponed)
-               authmsg = "Postponed";
-+      else if (partial)
-+              authmsg = "Partial";
-       else
-               authmsg = authenticated ? "Accepted" : "Failed";
--      authlog("%s %s for %s%.100s from %.200s port %d%s",
-+      authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
-           authmsg,
-           method,
-+          submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
-           authctxt->valid ? "" : "invalid user ",
-           authctxt->user,
-           get_remote_ipaddr(),
-@@ -303,7 +307,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
-  * Check whether root logins are disallowed.
-  */
- int
--auth_root_allowed(char *method)
-+auth_root_allowed(const char *method)
- {
-       switch (options.permit_root_login) {
-       case PERMIT_YES:
-diff --git a/auth.h b/auth.h
-index 0d786c4..29823bb 100644
---- a/auth.h
-+++ b/auth.h
-@@ -64,6 +64,8 @@ struct Authctxt {
- #ifdef BSD_AUTH
-       auth_session_t  *as;
- #endif
-+      char            **auth_methods; /* modified from server config */
-+      u_int            num_auth_methods;
- #ifdef KRB5
-       krb5_context     krb5_ctx;
-       krb5_ccache      krb5_fwd_ccache;
-@@ -142,12 +144,17 @@ void disable_forwarding(void);
- void  do_authentication(Authctxt *);
- void  do_authentication2(Authctxt *);
--void  auth_log(Authctxt *, int, char *, char *);
--void  userauth_finish(Authctxt *, int, char *);
-+void  auth_log(Authctxt *, int, int, const char *, const char *,
-+    const char *);
-+void  userauth_finish(Authctxt *, int, const char *, const char *);
-+int   auth_root_allowed(const char *);
-+
- void  userauth_send_banner(const char *);
--int   auth_root_allowed(char *);
- char  *auth2_read_banner(void);
-+int    auth2_methods_valid(const char *, int);
-+int    auth2_update_methods_lists(Authctxt *, const char *);
-+int    auth2_setup_methods_lists(Authctxt *);
- void  privsep_challenge_enable(void);
-diff --git a/auth1.c b/auth1.c
-index cc85aec..458a110 100644
---- a/auth1.c
-+++ b/auth1.c
-@@ -253,7 +253,8 @@ do_authloop(Authctxt *authctxt)
-               if (options.use_pam && (PRIVSEP(do_pam_account())))
- #endif
-               {
--                      auth_log(authctxt, 1, "without authentication", "");
-+                      auth_log(authctxt, 1, 0, "without authentication",
-+                          NULL, "");
-                       return;
-               }
-       }
-@@ -352,7 +353,8 @@ do_authloop(Authctxt *authctxt)
-  skip:
-               /* Log before sending the reply */
--              auth_log(authctxt, authenticated, get_authname(type), info);
-+              auth_log(authctxt, authenticated, 0, get_authname(type),
-+                  NULL, info);
-               if (client_user != NULL) {
-                       xfree(client_user);
-@@ -406,6 +408,11 @@ do_authentication(Authctxt *authctxt)
-               authctxt->pw = fakepw();
-       }
-+      /* Configuration may have changed as a result of Match */
-+      if (options.num_auth_methods != 0)
-+              fatal("AuthenticationMethods is not supported with SSH "
-+                  "protocol 1");
-+
-       setproctitle("%s%s", authctxt->valid ? user : "unknown",
-           use_privsep ? " [net]" : "");
-diff --git a/auth2-chall.c b/auth2-chall.c
-index e6dbffe..5f7ec6d 100644
---- a/auth2-chall.c
-+++ b/auth2-chall.c
-@@ -283,7 +283,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
-       KbdintAuthctxt *kbdintctxt;
-       int authenticated = 0, res;
-       u_int i, nresp;
--      char **response = NULL, *method;
-+      char *devicename = NULL, **response = NULL;
-       if (authctxt == NULL)
-               fatal("input_userauth_info_response: no authctxt");
-@@ -329,9 +329,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
-               /* Failure! */
-               break;
-       }
--
--      xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
--
-+      devicename = kbdintctxt->device->name;
-       if (!authctxt->postponed) {
-               if (authenticated) {
-                       auth2_challenge_stop(authctxt);
-@@ -341,8 +339,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
-                       auth2_challenge_start(authctxt);
-               }
-       }
--      userauth_finish(authctxt, authenticated, method);
--      xfree(method);
-+      userauth_finish(authctxt, authenticated, "keyboard-interactive",
-+          devicename);
- }
- void
-diff --git a/auth2-gss.c b/auth2-gss.c
-index 0d59b21..338c748 100644
---- a/auth2-gss.c
-+++ b/auth2-gss.c
-@@ -163,7 +163,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
-               }
-               authctxt->postponed = 0;
-               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
--              userauth_finish(authctxt, 0, "gssapi-with-mic");
-+              userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
-       } else {
-               if (send_tok.length != 0) {
-                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-@@ -251,7 +251,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
--      userauth_finish(authctxt, authenticated, "gssapi-with-mic");
-+      userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
- }
- static void
-@@ -291,7 +291,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
--      userauth_finish(authctxt, authenticated, "gssapi-with-mic");
-+      userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
- }
- Authmethod method_gssapi = {
-diff --git a/auth2-jpake.c b/auth2-jpake.c
-index a460e82..e4ba9aa 100644
---- a/auth2-jpake.c
-+++ b/auth2-jpake.c
-@@ -556,7 +556,7 @@ input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt)
-       authctxt->postponed = 0;
-       jpake_free(authctxt->jpake_ctx);
-       authctxt->jpake_ctx = NULL;
--      userauth_finish(authctxt, authenticated, method_jpake.name);
-+      userauth_finish(authctxt, authenticated, method_jpake.name, NULL);
- }
- #endif /* JPAKE */
-diff --git a/auth2.c b/auth2.c
-index b66bef6..ea0fd92 100644
---- a/auth2.c
-+++ b/auth2.c
-@@ -96,8 +96,10 @@ static void input_service_request(int, u_int32_t, void *);
- static void input_userauth_request(int, u_int32_t, void *);
- /* helper */
--static Authmethod *authmethod_lookup(const char *);
--static char *authmethods_get(void);
-+static Authmethod *authmethod_lookup(Authctxt *, const char *);
-+static char *authmethods_get(Authctxt *authctxt);
-+static int method_allowed(Authctxt *, const char *);
-+static int list_starts_with(const char *, const char *);
- char *
- auth2_read_banner(void)
-@@ -255,6 +257,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
-               if (use_privsep)
-                       mm_inform_authserv(service, style);
-               userauth_banner();
-+              if (auth2_setup_methods_lists(authctxt) != 0)
-+                      packet_disconnect("no authentication methods enabled");
-       } else if (strcmp(user, authctxt->user) != 0 ||
-           strcmp(service, authctxt->service) != 0) {
-               packet_disconnect("Change of username or service not allowed: "
-@@ -277,12 +281,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
-       authctxt->server_caused_failure = 0;
-       /* try to authenticate user */
--      m = authmethod_lookup(method);
-+      m = authmethod_lookup(authctxt, method);
-       if (m != NULL && authctxt->failures < options.max_authtries) {
-               debug2("input_userauth_request: try method %s", method);
-               authenticated = m->userauth(authctxt);
-       }
--      userauth_finish(authctxt, authenticated, method);
-+      userauth_finish(authctxt, authenticated, method, NULL);
-       xfree(service);
-       xfree(user);
-@@ -290,13 +294,17 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
- }
- void
--userauth_finish(Authctxt *authctxt, int authenticated, char *method)
-+userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
-+    const char *submethod)
- {
-       char *methods;
-+      int partial = 0;
-       if (!authctxt->valid && authenticated)
-               fatal("INTERNAL ERROR: authenticated invalid user %s",
-                   authctxt->user);
-+      if (authenticated && authctxt->postponed)
-+              fatal("INTERNAL ERROR: authenticated and postponed");
-       /* Special handling for root */
-       if (authenticated && authctxt->pw->pw_uid == 0 &&
-@@ -307,6 +315,19 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
- #endif
-       }
-+      if (authenticated && options.num_auth_methods != 0) {
-+              if (!auth2_update_methods_lists(authctxt, method)) {
-+                      authenticated = 0;
-+                      partial = 1;
-+              }
-+      }
-+
-+      /* Log before sending the reply */
-+      auth_log(authctxt, authenticated, partial, method, submethod, " ssh2");
-+
-+      if (authctxt->postponed)
-+              return;
-+
- #ifdef USE_PAM
-       if (options.use_pam && authenticated) {
-               if (!PRIVSEP(do_pam_account())) {
-@@ -325,17 +346,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
- #ifdef _UNICOS
-       if (authenticated && cray_access_denied(authctxt->user)) {
-               authenticated = 0;
--              fatal("Access denied for user %s.",authctxt->user);
-+              fatal("Access denied for user %s.", authctxt->user);
-       }
- #endif /* _UNICOS */
--      /* Log before sending the reply */
--      auth_log(authctxt, authenticated, method, " ssh2");
--
--      if (authctxt->postponed)
--              return;
--
--      /* XXX todo: check if multiple auth methods are needed */
-       if (authenticated == 1) {
-               /* turn off userauth */
-               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
-@@ -348,7 +362,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
-               /* Allow initial try of "none" auth without failure penalty */
-               if (!authctxt->server_caused_failure &&
--                  (authctxt->attempt > 1 || strcmp(method, "none") != 0))
-+                  (authctxt->attempt > 1 || strcmp(method, "none") != 0) &&
-+                  partial == 0)
-                       authctxt->failures++;
-               if (authctxt->failures >= options.max_authtries) {
- #ifdef SSH_AUDIT_EVENTS
-@@ -356,34 +371,61 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
- #endif
-                       packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
-               }
--              methods = authmethods_get();
-+              methods = authmethods_get(authctxt);
-+              debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
-+                  partial, methods);
-               packet_start(SSH2_MSG_USERAUTH_FAILURE);
-               packet_put_cstring(methods);
--              packet_put_char(0);     /* XXX partial success, unused */
-+              packet_put_char(partial);
-               packet_send();
-               packet_write_wait();
-               xfree(methods);
-       }
- }
-+/*
-+ * Checks whether method is allowed by at least one AuthenticationMethods
-+ * methods list. Returns 1 if allowed, or no methods lists configured.
-+ * 0 otherwise.
-+ */
-+static int
-+method_allowed(Authctxt *authctxt, const char *method)
-+{
-+      u_int i;
-+
-+      /*
-+       * NB. authctxt->num_auth_methods might be zero as a result of
-+       * auth2_setup_methods_lists(), so check the configuration.
-+       */
-+      if (options.num_auth_methods == 0)
-+              return 1;
-+      for (i = 0; i < authctxt->num_auth_methods; i++) {
-+              if (list_starts_with(authctxt->auth_methods[i], method))
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
- static char *
--authmethods_get(void)
-+authmethods_get(Authctxt *authctxt)
- {
-       Buffer b;
-       char *list;
--      int i;
-+      u_int i;
-       buffer_init(&b);
-       for (i = 0; authmethods[i] != NULL; i++) {
-               if (strcmp(authmethods[i]->name, "none") == 0)
-                       continue;
--              if (authmethods[i]->enabled != NULL &&
--                  *(authmethods[i]->enabled) != 0) {
--                      if (buffer_len(&b) > 0)
--                              buffer_append(&b, ",", 1);
--                      buffer_append(&b, authmethods[i]->name,
--                          strlen(authmethods[i]->name));
--              }
-+              if (authmethods[i]->enabled == NULL ||
-+                  *(authmethods[i]->enabled) == 0)
-+                      continue;
-+              if (!method_allowed(authctxt, authmethods[i]->name))
-+                      continue;
-+              if (buffer_len(&b) > 0)
-+                      buffer_append(&b, ",", 1);
-+              buffer_append(&b, authmethods[i]->name,
-+                  strlen(authmethods[i]->name));
-       }
-       buffer_append(&b, "\0", 1);
-       list = xstrdup(buffer_ptr(&b));
-@@ -392,7 +434,7 @@ authmethods_get(void)
- }
- static Authmethod *
--authmethod_lookup(const char *name)
-+authmethod_lookup(Authctxt *authctxt, const char *name)
- {
-       int i;
-@@ -400,10 +442,152 @@ authmethod_lookup(const char *name)
-               for (i = 0; authmethods[i] != NULL; i++)
-                       if (authmethods[i]->enabled != NULL &&
-                           *(authmethods[i]->enabled) != 0 &&
--                          strcmp(name, authmethods[i]->name) == 0)
-+                          strcmp(name, authmethods[i]->name) == 0 &&
-+                          method_allowed(authctxt, authmethods[i]->name))
-                               return authmethods[i];
-       debug2("Unrecognized authentication method name: %s",
-           name ? name : "NULL");
-       return NULL;
- }
-+/*
-+ * Check a comma-separated list of methods for validity. Is need_enable is
-+ * non-zero, then also require that the methods are enabled.
-+ * Returns 0 on success or -1 if the methods list is invalid.
-+ */
-+int
-+auth2_methods_valid(const char *_methods, int need_enable)
-+{
-+      char *methods, *omethods, *method;
-+      u_int i, found;
-+      int ret = -1;
-+
-+      if (*_methods == '\0') {
-+              error("empty authentication method list");
-+              return -1;
-+      }
-+      omethods = methods = xstrdup(_methods);
-+      while ((method = strsep(&methods, ",")) != NULL) {
-+              for (found = i = 0; !found && authmethods[i] != NULL; i++) {
-+                      if (strcmp(method, authmethods[i]->name) != 0)
-+                              continue;
-+                      if (need_enable) {
-+                              if (authmethods[i]->enabled == NULL ||
-+                                  *(authmethods[i]->enabled) == 0) {
-+                                      error("Disabled method \"%s\" in "
-+                                          "AuthenticationMethods list \"%s\"",
-+                                          method, _methods);
-+                                      goto out;
-+                              }
-+                      }
-+                      found = 1;
-+                      break;
-+              }
-+              if (!found) {
-+                      error("Unknown authentication method \"%s\" in list",
-+                          method);
-+                      goto out;
-+              }
-+      }
-+      ret = 0;
-+ out:
-+      free(omethods);
-+      return ret;
-+}
-+
-+/*
-+ * Prune the AuthenticationMethods supplied in the configuration, removing
-+ * any methods lists that include disabled methods. Note that this might
-+ * leave authctxt->num_auth_methods == 0, even when multiple required auth
-+ * has been requested. For this reason, all tests for whether multiple is
-+ * enabled should consult options.num_auth_methods directly.
-+ */
-+int
-+auth2_setup_methods_lists(Authctxt *authctxt)
-+{
-+      u_int i;
-+
-+      if (options.num_auth_methods == 0)
-+              return 0;
-+      debug3("%s: checking methods", __func__);
-+      authctxt->auth_methods = xcalloc(options.num_auth_methods,
-+          sizeof(*authctxt->auth_methods));
-+      authctxt->num_auth_methods = 0;
-+      for (i = 0; i < options.num_auth_methods; i++) {
-+              if (auth2_methods_valid(options.auth_methods[i], 1) != 0) {
-+                      logit("Authentication methods list \"%s\" contains "
-+                          "disabled method, skipping",
-+                          options.auth_methods[i]);
-+                      continue;
-+              }
-+              debug("authentication methods list %d: %s",
-+                  authctxt->num_auth_methods, options.auth_methods[i]);
-+              authctxt->auth_methods[authctxt->num_auth_methods++] =
-+                  xstrdup(options.auth_methods[i]);
-+      }
-+      if (authctxt->num_auth_methods == 0) {
-+              error("No AuthenticationMethods left after eliminating "
-+                  "disabled methods");
-+              return -1;
-+      }
-+      return 0;
-+}
-+
-+static int
-+list_starts_with(const char *methods, const char *method)
-+{
-+      size_t l = strlen(method);
-+
-+      if (strncmp(methods, method, l) != 0)
-+              return 0;
-+      if (methods[l] != ',' && methods[l] != '\0')
-+              return 0;
-+      return 1;
-+}
-+
-+/*
-+ * Remove method from the start of a comma-separated list of methods.
-+ * Returns 0 if the list of methods did not start with that method or 1
-+ * if it did.
-+ */
-+static int
-+remove_method(char **methods, const char *method)
-+{
-+      char *omethods = *methods;
-+      size_t l = strlen(method);
-+
-+      if (!list_starts_with(omethods, method))
-+              return 0;
-+      *methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0));
-+      free(omethods);
-+      return 1;
-+}
-+
-+/*
-+ * Called after successful authentication. Will remove the successful method
-+ * from the start of each list in which it occurs. If it was the last method
-+ * in any list, then authentication is deemed successful.
-+ * Returns 1 if the method completed any authentication list or 0 otherwise.
-+ */
-+int
-+auth2_update_methods_lists(Authctxt *authctxt, const char *method)
-+{
-+      u_int i, found = 0;
-+
-+      debug3("%s: updating methods list after \"%s\"", __func__, method);
-+      for (i = 0; i < authctxt->num_auth_methods; i++) {
-+              if (!remove_method(&(authctxt->auth_methods[i]), method))
-+                      continue;
-+              found = 1;
-+              if (*authctxt->auth_methods[i] == '\0') {
-+                      debug2("authentication methods list %d complete", i);
-+                      return 1;
-+              }
-+              debug3("authentication methods list %d remaining: \"%s\"",
-+                  i, authctxt->auth_methods[i]);
-+      }
-+      /* This should not happen, but would be bad if it did */
-+      if (!found)
-+              fatal("%s: method not in AuthenticationMethods", __func__);
-+      return 0;
-+}
-diff --git a/monitor.c b/monitor.c
-index 1dc42f5..66f3eea 100644
---- a/monitor.c
-+++ b/monitor.c
-@@ -199,6 +199,7 @@ static int key_blobtype = MM_NOKEY;
- static char *hostbased_cuser = NULL;
- static char *hostbased_chost = NULL;
- static char *auth_method = "unknown";
-+static char *auth_submethod = NULL;
- static u_int session_id2_len = 0;
- static u_char *session_id2 = NULL;
- static pid_t monitor_child_pid;
-@@ -352,7 +353,7 @@ void
- monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
- {
-       struct mon_table *ent;
--      int authenticated = 0;
-+      int authenticated = 0, partial = 0;
-       debug3("preauth child monitor started");
-@@ -379,8 +380,26 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
-       /* The first few requests do not require asynchronous access */
-       while (!authenticated) {
-+              partial = 0;
-               auth_method = "unknown";
-+              auth_submethod = NULL;
-               authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
-+
-+              /* Special handling for multiple required authentications */
-+              if (options.num_auth_methods != 0) {
-+                      if (!compat20)
-+                              fatal("AuthenticationMethods is not supported"
-+                                  "with SSH protocol 1");
-+                      if (authenticated &&
-+                          !auth2_update_methods_lists(authctxt,
-+                          auth_method)) {
-+                              debug3("%s: method %s: partial", __func__,
-+                                  auth_method);
-+                              authenticated = 0;
-+                              partial = 1;
-+                      }
-+              }
-+
-               if (authenticated) {
-                       if (!(ent->flags & MON_AUTHDECIDE))
-                               fatal("%s: unexpected authentication from %d",
-@@ -403,9 +422,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
-               }
-               if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
--                      auth_log(authctxt, authenticated, auth_method,
-+                      auth_log(authctxt, authenticated, partial,
-+                          auth_method, auth_submethod,
-                           compat20 ? " ssh2" : "");
--                      if (!authenticated)
-+                      if (!authenticated && !partial)
-                               authctxt->failures++;
-               }
- #ifdef JPAKE
-@@ -781,7 +801,17 @@ mm_answer_pwnamallow(int sock, Buffer *m)
-       COPY_MATCH_STRING_OPTS();
- #undef M_CP_STROPT
- #undef M_CP_STRARRAYOPT
--      
-+
-+      /* Create valid auth method lists */
-+      if (compat20 && auth2_setup_methods_lists(authctxt) != 0) {
-+              /*
-+               * The monitor will continue long enough to let the child
-+               * run to it's packet_disconnect(), but it must not allow any
-+               * authentication to succeed.
-+               */
-+              debug("%s: no valid authentication method lists", __func__);
-+      }
-+
-       debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
-       mm_request_send(sock, MONITOR_ANS_PWNAM, m);
-@@ -918,7 +948,11 @@ mm_answer_bsdauthrespond(int sock, Buffer *m)
-       debug3("%s: sending authenticated: %d", __func__, authok);
-       mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
--      auth_method = "bsdauth";
-+      if (compat20)
-+              auth_method = "keyboard-interactive"; /* XXX auth_submethod */
-+      else
-+              auth_method = "bsdauth";
-+
-       return (authok != 0);
- }
-@@ -1057,7 +1091,9 @@ mm_answer_pam_query(int sock, Buffer *m)
-               xfree(prompts);
-       if (echo_on != NULL)
-               xfree(echo_on);
--      auth_method = "keyboard-interactive/pam";
-+      auth_method = "keyboard-interactive";
-+      auth_submethod = "pam";
-+
-       mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m);
-       return (0);
- }
-@@ -1086,7 +1122,8 @@ mm_answer_pam_respond(int sock, Buffer *m)
-       buffer_clear(m);
-       buffer_put_int(m, ret);
-       mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m);
--      auth_method = "keyboard-interactive/pam";
-+      auth_method = "keyboard-interactive";
-+      auth_submethod= "pam";
-       if (ret == 0)
-               sshpam_authok = sshpam_ctxt;
-       return (0);
-@@ -1100,7 +1137,8 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
-       (sshpam_device.free_ctx)(sshpam_ctxt);
-       buffer_clear(m);
-       mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m);
--      auth_method = "keyboard-interactive/pam";
-+      auth_method = "keyboard-interactive";
-+      auth_submethod = "pam";
-       return (sshpam_authok == sshpam_ctxt);
- }
- #endif
-@@ -1178,7 +1216,8 @@ mm_answer_keyallowed(int sock, Buffer *m)
-               hostbased_chost = chost;
-       } else {
-               /* Log failed attempt */
--              auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
-+              auth_log(authctxt, 0, 0, auth_method, NULL,
-+                  compat20 ? " ssh2" : "");
-               xfree(blob);
-               xfree(cuser);
-               xfree(chost);
-diff --git a/servconf.c b/servconf.c
-index 906778f..2c84993 100644
---- a/servconf.c
-+++ b/servconf.c
-@@ -48,6 +48,8 @@
- #include "groupaccess.h"
- #include "canohost.h"
- #include "packet.h"
-+#include "hostfile.h"
-+#include "auth.h"
- static void add_listen_addr(ServerOptions *, char *, int);
- static void add_one_listen_addr(ServerOptions *, char *, int);
-@@ -329,6 +331,7 @@ typedef enum {
-       sZeroKnowledgePasswordAuthentication, sHostCertificate,
-       sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
-       sKexAlgorithms, sIPQoS, sVersionAddendum,
-+      sAuthenticationMethods,
-       sDeprecated, sUnsupported
- } ServerOpCodes;
-@@ -454,6 +457,7 @@ static struct {
-       { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
-       { "ipqos", sIPQoS, SSHCFG_ALL },
-       { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
-+      { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
-       { NULL, sBadOption, 0 }
- };
-@@ -1498,6 +1502,24 @@ process_server_config_line(ServerOptions *options, char *line,
-               }
-               return 0;
-+      case sAuthenticationMethods:
-+              if (*activep && options->num_auth_methods == 0) {
-+                      while ((arg = strdelim(&cp)) && *arg != '\0') {
-+                              if (options->num_auth_methods >=
-+                                  MAX_AUTH_METHODS)
-+                                      fatal("%s line %d: "
-+                                          "too many authentication methods.",
-+                                          filename, linenum);
-+                              if (auth2_methods_valid(arg, 0) != 0)
-+                                      fatal("%s line %d: invalid "
-+                                          "authentication method list.",
-+                                          filename, linenum);
-+                              options->auth_methods[
-+                                  options->num_auth_methods++] = xstrdup(arg);
-+                      }
-+              }
-+              return 0;
-+
-       case sDeprecated:
-               logit("%s line %d: Deprecated option %s",
-                   filename, linenum, arg);
-@@ -1925,6 +1947,8 @@ dump_config(ServerOptions *o)
-       dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
-       dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
-       dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
-+      dump_cfg_strarray_oneline(sAuthenticationMethods,
-+              o->num_auth_methods, o->auth_methods);
-       /* other arguments */
-       for (i = 0; i < o->num_subsystems; i++)
-diff --git a/servconf.h b/servconf.h
-index 096d596..ef80eef 100644
---- a/servconf.h
-+++ b/servconf.h
-@@ -28,6 +28,7 @@
- #define MAX_ACCEPT_ENV                256     /* Max # of env vars. */
- #define MAX_MATCH_GROUPS      256     /* Max # of groups for Match. */
- #define MAX_AUTHKEYS_FILES    256     /* Max # of authorized_keys files. */
-+#define MAX_AUTH_METHODS      256     /* Max # of AuthenticationMethods. */
- /* permit_root_login */
- #define       PERMIT_NOT_SET          -1
-@@ -168,6 +169,9 @@ typedef struct {
-       char   *authorized_principals_file;
-       char   *version_addendum;       /* Appended to SSH banner */
-+
-+      u_int   num_auth_methods;
-+      char   *auth_methods[MAX_AUTH_METHODS];
- }       ServerOptions;
- /* Information about the incoming connection as used by Match */
-@@ -197,6 +201,7 @@ struct connection_info {
-               M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \
-               M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
-               M_CP_STRARRAYOPT(accept_env, num_accept_env); \
-+              M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
-       } while (0)
- struct connection_info *get_connection_info(int, int);
-diff --git a/sshd.c b/sshd.c
-index d5ec4e6..cb4bdd3 100644
---- a/sshd.c
-+++ b/sshd.c
-@@ -1333,6 +1333,7 @@ main(int ac, char **av)
-       int remote_port;
-       char *line;
-       int config_s[2] = { -1 , -1 };
-+      u_int n;
-       u_int64_t ibytes, obytes;
-       mode_t new_umask;
-       Key *key;
-@@ -1555,6 +1556,26 @@ main(int ac, char **av)
-       if (options.challenge_response_authentication)
-               options.kbd_interactive_authentication = 1;
-+      /*
-+       * Check whether there is any path through configured auth methods.
-+       * Unfortunately it is not possible to verify this generally before
-+       * daemonisation in the presence of Match block, but this catches
-+       * and warns for trivial misconfigurations that could break login.
-+       */
-+      if (options.num_auth_methods != 0) {
-+              if ((options.protocol & SSH_PROTO_1))
-+                      fatal("AuthenticationMethods is not supported with "
-+                          "SSH protocol 1");
-+              for (n = 0; n < options.num_auth_methods; n++) {
-+                      if (auth2_methods_valid(options.auth_methods[n],
-+                          1) == 0)
-+                              break;
-+              }
-+              if (n >= options.num_auth_methods)
-+                      fatal("AuthenticationMethods cannot be satisfied by "
-+                          "enabled authentication methods");
-+      }
-+
-       /* set default channel AF */
-       channel_set_af(options.address_family);
-diff --git a/sshd_config.5 b/sshd_config.5
-index 314ecfb..ed81ac8 100644
---- a/sshd_config.5
-+++ b/sshd_config.5
-@@ -151,6 +151,28 @@ See
- in
- .Xr ssh_config 5
- for more information on patterns.
-+.It Cm AuthenticationMethods
-+Specifies the authentication methods that must be successfully completed
-+for a user to be granted access.
-+This option must be followed by one or more comma-separated lists of
-+authentication method names.
-+Successful authentication requires completion of every method in at least
-+one of these lists.
-+.Pp
-+For example, an argument of
-+.Dq publickey,password publickey,keyboard-interactive
-+would require the user to complete public key authentication, followed by
-+either password or keyboard interactive authentication.
-+Only methods that are next in one or more lists are offered at each stage,
-+so for this example, it would not be possible to attempt password or
-+keyboard-interactive authentication before public key.
-+.Pp
-+This option is only available for SSH protocol 2 and will yield a fatal
-+error if enabled if protocol 1 is also enabled.
-+Note that each authentication method listed should also be explicitly enabled
-+in the configuration.
-+The default is not to require multiple authentication; successful completion
-+of a single authentication method is sufficient.
- .It Cm AuthorizedKeysFile
- Specifies the file that contains the public keys that can be used
- for user authentication.
-@@ -711,6 +733,7 @@ Available keywords are
- .Cm AllowGroups ,
- .Cm AllowTcpForwarding ,
- .Cm AllowUsers ,
-+.Cm AuthenticationMethods ,
- .Cm AuthorizedKeysFile ,
- .Cm AuthorizedPrincipalsFile ,
- .Cm Banner ,
diff --git a/openssh/patches/openssh-6.1p1-coverity.patch b/openssh/patches/openssh-6.1p1-coverity.patch
deleted file mode 100644 (file)
index 0c8fb23..0000000
+++ /dev/null
@@ -1,806 +0,0 @@
-diff -up openssh-6.1p1/auth-pam.c.coverity openssh-6.1p1/auth-pam.c
---- openssh-6.1p1/auth-pam.c.coverity  2009-07-12 14:07:21.000000000 +0200
-+++ openssh-6.1p1/auth-pam.c   2012-09-14 21:16:41.264906486 +0200
-@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void *
-       if (sshpam_thread_status != -1)
-               return (sshpam_thread_status);
-       signal(SIGCHLD, sshpam_oldsig);
--      waitpid(thread, &status, 0);
-+      while (waitpid(thread, &status, 0) < 0) {                     
-+              if (errno == EINTR)                                
-+                      continue;
-+              fatal("%s: waitpid: %s", __func__,         
-+                              strerror(errno));                      
-+      }
-       return (status);
- }
- #endif
-diff -up openssh-6.1p1/clientloop.c.coverity openssh-6.1p1/clientloop.c
---- openssh-6.1p1/clientloop.c.coverity        2012-06-20 14:31:27.000000000 +0200
-+++ openssh-6.1p1/clientloop.c 2012-09-14 21:16:41.267906501 +0200
-@@ -2006,14 +2006,15 @@ client_input_global_request(int type, u_
-       char *rtype;
-       int want_reply;
-       int success = 0;
-+/* success is still 0 the packet is allways SSH2_MSG_REQUEST_FAILURE, isn't it? */
-       rtype = packet_get_string(NULL);
-       want_reply = packet_get_char();
-       debug("client_input_global_request: rtype %s want_reply %d",
-           rtype, want_reply);
-       if (want_reply) {
--              packet_start(success ?
--                  SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
-+              packet_start(/*success ?
-+                  SSH2_MSG_REQUEST_SUCCESS :*/ SSH2_MSG_REQUEST_FAILURE);
-               packet_send();
-               packet_write_wait();
-       }
-diff -up openssh-6.1p1/channels.c.coverity openssh-6.1p1/channels.c
---- openssh-6.1p1/channels.c.coverity  2012-04-23 10:21:05.000000000 +0200
-+++ openssh-6.1p1/channels.c   2012-09-14 21:16:41.272906528 +0200
-@@ -232,11 +232,11 @@ channel_register_fds(Channel *c, int rfd
-       channel_max_fd = MAX(channel_max_fd, wfd);
-       channel_max_fd = MAX(channel_max_fd, efd);
--      if (rfd != -1)
-+      if (rfd >= 0)
-               fcntl(rfd, F_SETFD, FD_CLOEXEC);
--      if (wfd != -1 && wfd != rfd)
-+      if (wfd >= 0 && wfd != rfd)
-               fcntl(wfd, F_SETFD, FD_CLOEXEC);
--      if (efd != -1 && efd != rfd && efd != wfd)
-+      if (efd >= 0 && efd != rfd && efd != wfd)
-               fcntl(efd, F_SETFD, FD_CLOEXEC);
-       c->rfd = rfd;
-@@ -251,11 +251,11 @@ channel_register_fds(Channel *c, int rfd
-       /* enable nonblocking mode */
-       if (nonblock) {
--              if (rfd != -1)
-+              if (rfd >= 0)
-                       set_nonblock(rfd);
--              if (wfd != -1)
-+              if (wfd >= 0)
-                       set_nonblock(wfd);
--              if (efd != -1)
-+              if (efd >= 0)
-                       set_nonblock(efd);
-       }
- }
-diff -up openssh-6.1p1/key.c.coverity openssh-6.1p1/key.c
---- openssh-6.1p1/key.c.coverity       2012-06-30 12:05:02.000000000 +0200
-+++ openssh-6.1p1/key.c        2012-09-14 21:16:41.274906537 +0200
-@@ -808,8 +808,10 @@ key_read(Key *ret, char **cpp)
-               success = 1;
- /*XXXX*/
-               key_free(k);
-+/*XXXX
-               if (success != 1)
-                       break;
-+XXXX*/
-               /* advance cp: skip whitespace and data */
-               while (*cp == ' ' || *cp == '\t')
-                       cp++;
-diff -up openssh-6.1p1/monitor.c.coverity openssh-6.1p1/monitor.c
---- openssh-6.1p1/monitor.c.coverity   2012-06-30 00:33:17.000000000 +0200
-+++ openssh-6.1p1/monitor.c    2012-09-14 21:16:41.277906552 +0200
-@@ -420,7 +420,7 @@ monitor_child_preauth(Authctxt *_authctx
-       }
-       /* Drain any buffered messages from the child */
--      while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
-+      while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
-               ;
-       if (!authctxt->valid)
-@@ -1159,6 +1159,10 @@ mm_answer_keyallowed(int sock, Buffer *m
-                       break;
-               }
-       }
-+
-+      debug3("%s: key %p is %s",
-+          __func__, key, allowed ? "allowed" : "not allowed");
-+
-       if (key != NULL)
-               key_free(key);
-@@ -1180,9 +1184,6 @@ mm_answer_keyallowed(int sock, Buffer *m
-               xfree(chost);
-       }
--      debug3("%s: key %p is %s",
--          __func__, key, allowed ? "allowed" : "not allowed");
--
-       buffer_clear(m);
-       buffer_put_int(m, allowed);
-       buffer_put_int(m, forced_command != NULL);
-diff -up openssh-6.1p1/monitor_wrap.c.coverity openssh-6.1p1/monitor_wrap.c
---- openssh-6.1p1/monitor_wrap.c.coverity      2011-06-20 06:42:23.000000000 +0200
-+++ openssh-6.1p1/monitor_wrap.c       2012-09-14 21:16:41.280906568 +0200
-@@ -707,10 +707,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
-       if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
-           (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
-               error("%s: cannot allocate fds for pty", __func__);
--              if (tmp1 > 0)
-+              if (tmp1 >= 0)
-                       close(tmp1);
--              if (tmp2 > 0)
--                      close(tmp2);
-+              /*DEAD CODE if (tmp2 >= 0)
-+                      close(tmp2);*/
-               return 0;
-       }
-       close(tmp1);
-diff -up openssh-6.1p1/openbsd-compat/bindresvport.c.coverity openssh-6.1p1/openbsd-compat/bindresvport.c
---- openssh-6.1p1/openbsd-compat/bindresvport.c.coverity       2010-12-03 00:50:26.000000000 +0100
-+++ openssh-6.1p1/openbsd-compat/bindresvport.c        2012-09-14 21:16:41.281906573 +0200
-@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr
-       struct sockaddr_in6 *in6;
-       u_int16_t *portp;
-       u_int16_t port;
--      socklen_t salen;
-+      socklen_t salen = sizeof(struct sockaddr_storage);
-       int i;
-       if (sa == NULL) {
-diff -up openssh-6.1p1/packet.c.coverity openssh-6.1p1/packet.c
---- openssh-6.1p1/packet.c.coverity    2012-03-09 00:28:07.000000000 +0100
-+++ openssh-6.1p1/packet.c     2012-09-14 21:16:41.284906588 +0200
-@@ -1177,6 +1177,7 @@ packet_read_poll1(void)
-               case DEATTACK_DETECTED:
-                       packet_disconnect("crc32 compensation attack: "
-                           "network attack detected");
-+                      break;
-               case DEATTACK_DOS_DETECTED:
-                       packet_disconnect("deattack denial of "
-                           "service detected");
-@@ -1678,7 +1679,7 @@ void
- packet_write_wait(void)
- {
-       fd_set *setp;
--      int ret, ms_remain;
-+      int ret, ms_remain = 0;
-       struct timeval start, timeout, *timeoutp = NULL;
-       setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
-diff -up openssh-6.1p1/progressmeter.c.coverity openssh-6.1p1/progressmeter.c
---- openssh-6.1p1/progressmeter.c.coverity     2006-08-05 04:39:40.000000000 +0200
-+++ openssh-6.1p1/progressmeter.c      2012-09-14 21:16:41.285906593 +0200
-@@ -65,7 +65,7 @@ static void update_progress_meter(int);
- static time_t start;          /* start progress */
- static time_t last_update;    /* last progress update */
--static char *file;            /* name of the file being transferred */
-+static const char *file;      /* name of the file being transferred */
- static off_t end_pos;         /* ending position of transfer */
- static off_t cur_pos;         /* transfer position as of last refresh */
- static volatile off_t *counter;       /* progress counter */
-@@ -247,7 +247,7 @@ update_progress_meter(int ignore)
- }
- void
--start_progress_meter(char *f, off_t filesize, off_t *ctr)
-+start_progress_meter(const char *f, off_t filesize, off_t *ctr)
- {
-       start = last_update = time(NULL);
-       file = f;
-diff -up openssh-6.1p1/progressmeter.h.coverity openssh-6.1p1/progressmeter.h
---- openssh-6.1p1/progressmeter.h.coverity     2006-03-26 05:30:02.000000000 +0200
-+++ openssh-6.1p1/progressmeter.h      2012-09-14 21:16:41.286906598 +0200
-@@ -23,5 +23,5 @@
-  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  */
--void  start_progress_meter(char *, off_t, off_t *);
-+void  start_progress_meter(const char *, off_t, off_t *);
- void  stop_progress_meter(void);
-diff -up openssh-6.1p1/scp.c.coverity openssh-6.1p1/scp.c
---- openssh-6.1p1/scp.c.coverity       2011-09-22 13:38:01.000000000 +0200
-+++ openssh-6.1p1/scp.c        2012-09-14 21:16:41.288906608 +0200
-@@ -155,7 +155,7 @@ killchild(int signo)
- {
-       if (do_cmd_pid > 1) {
-               kill(do_cmd_pid, signo ? signo : SIGTERM);
--              waitpid(do_cmd_pid, NULL, 0);
-+              (void) waitpid(do_cmd_pid, NULL, 0);
-       }
-       if (signo)
-diff -up openssh-6.1p1/servconf.c.coverity openssh-6.1p1/servconf.c
---- openssh-6.1p1/servconf.c.coverity  2012-07-31 04:22:38.000000000 +0200
-+++ openssh-6.1p1/servconf.c   2012-09-14 21:16:41.291906623 +0200
-@@ -1249,7 +1249,7 @@ process_server_config_line(ServerOptions
-                       fatal("%s line %d: Missing subsystem name.",
-                           filename, linenum);
-               if (!*activep) {
--                      arg = strdelim(&cp);
-+                      /*arg =*/ (void) strdelim(&cp);
-                       break;
-               }
-               for (i = 0; i < options->num_subsystems; i++)
-@@ -1340,8 +1340,9 @@ process_server_config_line(ServerOptions
-               if (*activep && *charptr == NULL) {
-                       *charptr = tilde_expand_filename(arg, getuid());
-                       /* increase optional counter */
--                      if (intptr != NULL)
--                              *intptr = *intptr + 1;
-+                      /* DEAD CODE intptr is still NULL ;)
-+                       if (intptr != NULL)
-+                              *intptr = *intptr + 1; */
-               }
-               break;
-diff -up openssh-6.1p1/serverloop.c.coverity openssh-6.1p1/serverloop.c
---- openssh-6.1p1/serverloop.c.coverity        2012-06-20 14:31:27.000000000 +0200
-+++ openssh-6.1p1/serverloop.c 2012-09-14 21:16:41.294906638 +0200
-@@ -147,13 +147,13 @@ notify_setup(void)
- static void
- notify_parent(void)
- {
--      if (notify_pipe[1] != -1)
-+      if (notify_pipe[1] >= 0)
-               write(notify_pipe[1], "", 1);
- }
- static void
- notify_prepare(fd_set *readset)
- {
--      if (notify_pipe[0] != -1)
-+      if (notify_pipe[0] >= 0)
-               FD_SET(notify_pipe[0], readset);
- }
- static void
-@@ -161,8 +161,8 @@ notify_done(fd_set *readset)
- {
-       char c;
--      if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
--              while (read(notify_pipe[0], &c, 1) != -1)
-+      if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset))
-+              while (read(notify_pipe[0], &c, 1) >= 0)
-                       debug2("notify_done: reading");
- }
-@@ -336,7 +336,7 @@ wait_until_can_do_something(fd_set **rea
-                * If we have buffered data, try to write some of that data
-                * to the program.
-                */
--              if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
-+              if (fdin >= 0 && buffer_len(&stdin_buffer) > 0)
-                       FD_SET(fdin, *writesetp);
-       }
-       notify_prepare(*readsetp);
-@@ -476,7 +476,7 @@ process_output(fd_set *writeset)
-       int len;
-       /* Write buffered data to program stdin. */
--      if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) {
-+      if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) {
-               data = buffer_ptr(&stdin_buffer);
-               dlen = buffer_len(&stdin_buffer);
-               len = write(fdin, data, dlen);
-@@ -589,7 +589,7 @@ server_loop(pid_t pid, int fdin_arg, int
-       set_nonblock(fdin);
-       set_nonblock(fdout);
-       /* we don't have stderr for interactive terminal sessions, see below */
--      if (fderr != -1)
-+      if (fderr >= 0)
-               set_nonblock(fderr);
-       if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
-@@ -613,7 +613,7 @@ server_loop(pid_t pid, int fdin_arg, int
-       max_fd = MAX(connection_in, connection_out);
-       max_fd = MAX(max_fd, fdin);
-       max_fd = MAX(max_fd, fdout);
--      if (fderr != -1)
-+      if (fderr >= 0)
-               max_fd = MAX(max_fd, fderr);
- #endif
-@@ -643,7 +643,7 @@ server_loop(pid_t pid, int fdin_arg, int
-                * If we have received eof, and there is no more pending
-                * input data, cause a real eof by closing fdin.
-                */
--              if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
-+              if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) {
-                       if (fdin != fdout)
-                               close(fdin);
-                       else
-@@ -741,15 +741,15 @@ server_loop(pid_t pid, int fdin_arg, int
-       buffer_free(&stderr_buffer);
-       /* Close the file descriptors. */
--      if (fdout != -1)
-+      if (fdout >= 0)
-               close(fdout);
-       fdout = -1;
-       fdout_eof = 1;
--      if (fderr != -1)
-+      if (fderr >= 0)
-               close(fderr);
-       fderr = -1;
-       fderr_eof = 1;
--      if (fdin != -1)
-+      if (fdin >= 0)
-               close(fdin);
-       fdin = -1;
-@@ -943,7 +943,7 @@ server_input_window_size(int type, u_int
-       debug("Window change received.");
-       packet_check_eom();
--      if (fdin != -1)
-+      if (fdin >= 0)
-               pty_change_window_size(fdin, row, col, xpixel, ypixel);
- }
-@@ -996,7 +996,7 @@ server_request_tun(void)
-       }
-       tun = packet_get_int();
--      if (forced_tun_device != -1) {
-+      if (forced_tun_device >= 0) {
-               if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
-                       goto done;
-               tun = forced_tun_device;
-diff -up openssh-6.1p1/sftp.c.coverity openssh-6.1p1/sftp.c
---- openssh-6.1p1/sftp.c.coverity      2012-06-30 00:33:32.000000000 +0200
-+++ openssh-6.1p1/sftp.c       2012-09-14 21:16:41.297906653 +0200
-@@ -206,7 +206,7 @@ killchild(int signo)
- {
-       if (sshpid > 1) {
-               kill(sshpid, SIGTERM);
--              waitpid(sshpid, NULL, 0);
-+              (void) waitpid(sshpid, NULL, 0);
-       }
-       _exit(1);
-@@ -316,7 +316,7 @@ local_do_ls(const char *args)
- /* Strip one path (usually the pwd) from the start of another */
- static char *
--path_strip(char *path, char *strip)
-+path_strip(const char *path, const char *strip)
- {
-       size_t len;
-@@ -334,7 +334,7 @@ path_strip(char *path, char *strip)
- }
- static char *
--make_absolute(char *p, char *pwd)
-+make_absolute(char *p, const char *pwd)
- {
-       char *abs_str;
-@@ -482,7 +482,7 @@ parse_df_flags(const char *cmd, char **a
- }
- static int
--is_dir(char *path)
-+is_dir(const char *path)
- {
-       struct stat sb;
-@@ -494,7 +494,7 @@ is_dir(char *path)
- }
- static int
--remote_is_dir(struct sftp_conn *conn, char *path)
-+remote_is_dir(struct sftp_conn *conn, const char *path)
- {
-       Attrib *a;
-@@ -508,7 +508,7 @@ remote_is_dir(struct sftp_conn *conn, ch
- /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
- static int
--pathname_is_dir(char *pathname)
-+pathname_is_dir(const char *pathname)
- {
-       size_t l = strlen(pathname);
-@@ -516,7 +516,7 @@ pathname_is_dir(char *pathname)
- }
- static int
--process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
-+process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd,
-     int pflag, int rflag)
- {
-       char *abs_src = NULL;
-@@ -590,7 +590,7 @@ out:
- }
- static int
--process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
-+process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd,
-     int pflag, int rflag)
- {
-       char *tmp_dst = NULL;
-@@ -695,7 +695,7 @@ sdirent_comp(const void *aa, const void
- /* sftp ls.1 replacement for directories */
- static int
--do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
-+do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag)
- {
-       int n;
-       u_int c = 1, colspace = 0, columns = 1;
-@@ -780,7 +780,7 @@ do_ls_dir(struct sftp_conn *conn, char *
- /* sftp ls.1 replacement which handles path globs */
- static int
--do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
-+do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path,
-     int lflag)
- {
-       char *fname, *lname;
-@@ -861,7 +861,7 @@ do_globbed_ls(struct sftp_conn *conn, ch
- }
- static int
--do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
-+do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
- {
-       struct sftp_statvfs st;
-       char s_used[FMT_SCALED_STRSIZE];
-diff -up openssh-6.1p1/sftp-client.c.coverity openssh-6.1p1/sftp-client.c
---- openssh-6.1p1/sftp-client.c.coverity       2012-07-02 14:15:39.000000000 +0200
-+++ openssh-6.1p1/sftp-client.c        2012-09-14 21:18:16.891332281 +0200
-@@ -149,7 +149,7 @@ get_msg(struct sftp_conn *conn, Buffer *
- }
- static void
--send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s,
-+send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
-     u_int len)
- {
-       Buffer msg;
-@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co
- static void
- send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
--    char *s, u_int len, Attrib *a)
-+    const char *s, u_int len, Attrib *a)
- {
-       Buffer msg;
-@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con
- }
- int
--do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
-+do_close(struct sftp_conn *conn, const char *handle, u_int handle_len)
- {
-       u_int id, status;
-       Buffer msg;
-@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h
- static int
--do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
-+do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag,
-     SFTP_DIRENT ***dir)
- {
-       Buffer msg;
-@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha
- }
- int
--do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir)
-+do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
- {
-       return(do_lsreaddir(conn, path, 0, dir));
- }
-@@ -590,7 +590,7 @@ void free_sftp_dirents(SFTP_DIRENT **s)
- }
- int
--do_rm(struct sftp_conn *conn, char *path)
-+do_rm(struct sftp_conn *conn, const char *path)
- {
-       u_int status, id;
-@@ -605,7 +605,7 @@ do_rm(struct sftp_conn *conn, char *path
- }
- int
--do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag)
-+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int printflag)
- {
-       u_int status, id;
-@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p
- }
- int
--do_rmdir(struct sftp_conn *conn, char *path)
-+do_rmdir(struct sftp_conn *conn, const char *path)
- {
-       u_int status, id;
-@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p
- }
- Attrib *
--do_stat(struct sftp_conn *conn, char *path, int quiet)
-+do_stat(struct sftp_conn *conn, const char *path, int quiet)
- {
-       u_int id;
-@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa
- }
- Attrib *
--do_lstat(struct sftp_conn *conn, char *path, int quiet)
-+do_lstat(struct sftp_conn *conn, const char *path, int quiet)
- {
-       u_int id;
-@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h
- #endif
- int
--do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
-+do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
- {
-       u_int status, id;
-@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char
- }
- int
--do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len,
-+do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len,
-     Attrib *a)
- {
-       u_int status, id;
-@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char
- }
- char *
--do_realpath(struct sftp_conn *conn, char *path)
-+do_realpath(struct sftp_conn *conn, const char *path)
- {
-       Buffer msg;
-       u_int type, expected_id, count, id;
-@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char
- }
- int
--do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
-+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath)
- {
-       Buffer msg;
-       u_int status, id;
-@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char *
- }
- int
--do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath)
-+do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
- {
-       Buffer msg;
-       u_int status, id;
-@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char
- }
- int
--do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
-+do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
- {
-       Buffer msg;
-       u_int status, id;
-@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn
- }
- int
--do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
-+do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path,
-     Attrib *a, int pflag)
- {
-       Attrib junk;
-@@ -1226,7 +1226,7 @@ do_download(struct sftp_conn *conn, char
- }
- static int
--download_dir_internal(struct sftp_conn *conn, char *src, char *dst,
-+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
-     Attrib *dirattrib, int pflag, int printflag, int depth)
- {
-       int i, ret = 0;
-@@ -1316,7 +1316,7 @@ download_dir_internal(struct sftp_conn *
- }
- int
--download_dir(struct sftp_conn *conn, char *src, char *dst,
-+download_dir(struct sftp_conn *conn, const char *src, const char *dst,
-     Attrib *dirattrib, int pflag, int printflag)
- {
-       char *src_canon;
-@@ -1334,7 +1334,7 @@ download_dir(struct sftp_conn *conn, cha
- }
- int
--do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
-+do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path,
-     int pflag)
- {
-       int local_fd;
-@@ -1517,7 +1517,7 @@ do_upload(struct sftp_conn *conn, char *
- }
- static int
--upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
-+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
-     int pflag, int printflag, int depth)
- {
-       int ret = 0, status;
-@@ -1608,7 +1608,7 @@ upload_dir_internal(struct sftp_conn *co
- }
- int
--upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag,
-+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int printflag,
-     int pflag)
- {
-       char *dst_canon;
-@@ -1625,7 +1625,7 @@ upload_dir(struct sftp_conn *conn, char
- }
- char *
--path_append(char *p1, char *p2)
-+path_append(const char *p1, const char *p2)
- {
-       char *ret;
-       size_t len = strlen(p1) + strlen(p2) + 2;
-diff -up openssh-6.1p1/sftp-client.h.coverity openssh-6.1p1/sftp-client.h
---- openssh-6.1p1/sftp-client.h.coverity       2010-12-04 23:02:48.000000000 +0100
-+++ openssh-6.1p1/sftp-client.h        2012-09-14 21:16:41.301906674 +0200
-@@ -56,49 +56,49 @@ struct sftp_conn *do_init(int, int, u_in
- u_int sftp_proto_version(struct sftp_conn *);
- /* Close file referred to by 'handle' */
--int do_close(struct sftp_conn *, char *, u_int);
-+int do_close(struct sftp_conn *, const char *, u_int);
- /* Read contents of 'path' to NULL-terminated array 'dir' */
--int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***);
-+int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
- /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
- void free_sftp_dirents(SFTP_DIRENT **);
- /* Delete file 'path' */
--int do_rm(struct sftp_conn *, char *);
-+int do_rm(struct sftp_conn *, const char *);
- /* Create directory 'path' */
--int do_mkdir(struct sftp_conn *, char *, Attrib *, int);
-+int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
- /* Remove directory 'path' */
--int do_rmdir(struct sftp_conn *, char *);
-+int do_rmdir(struct sftp_conn *, const char *);
- /* Get file attributes of 'path' (follows symlinks) */
--Attrib *do_stat(struct sftp_conn *, char *, int);
-+Attrib *do_stat(struct sftp_conn *, const char *, int);
- /* Get file attributes of 'path' (does not follow symlinks) */
--Attrib *do_lstat(struct sftp_conn *, char *, int);
-+Attrib *do_lstat(struct sftp_conn *, const char *, int);
- /* Set file attributes of 'path' */
--int do_setstat(struct sftp_conn *, char *, Attrib *);
-+int do_setstat(struct sftp_conn *, const char *, Attrib *);
- /* Set file attributes of open file 'handle' */
--int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *);
-+int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *);
- /* Canonicalise 'path' - caller must free result */
--char *do_realpath(struct sftp_conn *, char *);
-+char *do_realpath(struct sftp_conn *, const char *);
- /* Get statistics for filesystem hosting file at "path" */
- int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
- /* Rename 'oldpath' to 'newpath' */
--int do_rename(struct sftp_conn *, char *, char *);
-+int do_rename(struct sftp_conn *, const char *, const char *);
- /* Link 'oldpath' to 'newpath' */
--int do_hardlink(struct sftp_conn *, char *, char *);
-+int do_hardlink(struct sftp_conn *, const char *, const char *);
--/* Rename 'oldpath' to 'newpath' */
--int do_symlink(struct sftp_conn *, char *, char *);
-+/* Symlink 'oldpath' to 'newpath' */
-+int do_symlink(struct sftp_conn *, const char *, const char *);
- /* XXX: add callbacks to do_download/do_upload so we can do progress meter */
-@@ -106,27 +106,27 @@ int do_symlink(struct sftp_conn *, char
-  * Download 'remote_path' to 'local_path'. Preserve permissions and times
-  * if 'pflag' is set
-  */
--int do_download(struct sftp_conn *, char *, char *, Attrib *, int);
-+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int);
- /*
-  * Recursively download 'remote_directory' to 'local_directory'. Preserve 
-  * times if 'pflag' is set
-  */
--int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int);
-+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int);
- /*
-  * Upload 'local_path' to 'remote_path'. Preserve permissions and times
-  * if 'pflag' is set
-  */
--int do_upload(struct sftp_conn *, char *, char *, int);
-+int do_upload(struct sftp_conn *, const char *, const char *, int);
- /*
-  * Recursively upload 'local_directory' to 'remote_directory'. Preserve 
-  * times if 'pflag' is set
-  */
--int upload_dir(struct sftp_conn *, char *, char *, int, int);
-+int upload_dir(struct sftp_conn *, const char *, const char *, int, int);
- /* Concatenate paths, taking care of slashes. Caller must free result. */
--char *path_append(char *, char *);
-+char *path_append(const char *, const char *);
- #endif
-diff -up openssh-6.1p1/ssh-agent.c.coverity openssh-6.1p1/ssh-agent.c
---- openssh-6.1p1/ssh-agent.c.coverity 2011-06-03 06:14:16.000000000 +0200
-+++ openssh-6.1p1/ssh-agent.c  2012-09-14 21:16:41.303906683 +0200
-@@ -1147,8 +1147,8 @@ main(int ac, char **av)
-       sanitise_stdfd();
-       /* drop */
--      setegid(getgid());
--      setgid(getgid());
-+      (void) setegid(getgid());
-+      (void) setgid(getgid());
- #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
-       /* Disable ptrace on Linux without sgid bit */
-diff -up openssh-6.1p1/sshd.c.coverity openssh-6.1p1/sshd.c
---- openssh-6.1p1/sshd.c.coverity      2012-07-31 04:21:34.000000000 +0200
-+++ openssh-6.1p1/sshd.c       2012-09-14 21:16:41.307906705 +0200
-@@ -682,8 +682,10 @@ privsep_preauth(Authctxt *authctxt)
-               if (getuid() == 0 || geteuid() == 0)
-                       privsep_preauth_child();
-               setproctitle("%s", "[net]");
--              if (box != NULL)
-+              if (box != NULL) {
-                       ssh_sandbox_child(box);
-+                      xfree(box);
-+              }
-               return 0;
-       }
-@@ -1311,6 +1313,9 @@ server_accept_loop(int *sock_in, int *so
-               if (num_listen_socks < 0)
-                       break;
-       }
-+
-+      if (fdset != NULL)
-+              xfree(fdset);
- }
-@@ -1768,7 +1773,7 @@ main(int ac, char **av)
-       /* Chdir to the root directory so that the current disk can be
-          unmounted if desired. */
--      chdir("/");
-+      (void) chdir("/");
-       /* ignore SIGPIPE */
-       signal(SIGPIPE, SIG_IGN);
diff --git a/openssh/patches/openssh-6.1p1-kuserok.patch b/openssh/patches/openssh-6.1p1-kuserok.patch
deleted file mode 100644 (file)
index 7b695e0..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-diff -up openssh-6.1p1/auth-krb5.c.kuserok openssh-6.1p1/auth-krb5.c
---- openssh-6.1p1/auth-krb5.c.kuserok  2012-09-14 21:08:16.941496194 +0200
-+++ openssh-6.1p1/auth-krb5.c  2012-09-14 21:08:17.063496896 +0200
-@@ -55,6 +55,20 @@
- extern ServerOptions   options;
-+int
-+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client)
-+{
-+      if (options.use_kuserok)
-+              return krb5_kuserok(krb5_ctx, krb5_user, client);
-+      else {
-+              char kuser[65];
-+
-+              if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser))
-+                      return 0;
-+              return strcmp(kuser, client) == 0;
-+      }
-+}
-+
- static int
- krb5_init(void *context)
- {
-@@ -147,7 +161,7 @@ auth_krb5_password(Authctxt *authctxt, c
-       if (problem)
-               goto out;
--      if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) {
-+      if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) {
-               problem = -1;
-               goto out;
-       }
-diff -up openssh-6.1p1/gss-serv-krb5.c.kuserok openssh-6.1p1/gss-serv-krb5.c
---- openssh-6.1p1/gss-serv-krb5.c.kuserok      2012-09-14 21:08:17.019496642 +0200
-+++ openssh-6.1p1/gss-serv-krb5.c      2012-09-14 21:08:17.065496906 +0200
-@@ -68,6 +68,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr
-     int);
- static krb5_context krb_context = NULL;
-+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *);
- /* Initialise the krb5 library, for the stuff that GSSAPI won't do */
-@@ -115,7 +116,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
-       /* NOTE: .k5login and .k5users must opened as root, not the user,
-        * because if they are on a krb5-protected filesystem, user credentials
-        * to access these files aren't available yet. */
--      if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) {
-+      if (ssh_krb5_kuserok(krb_context, princ, luser) && k5login_exists) {
-               retval = 1;
-               logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
-                   luser, (char *)client->displayname.value);
-diff -up openssh-6.1p1/servconf.c.kuserok openssh-6.1p1/servconf.c
---- openssh-6.1p1/servconf.c.kuserok   2012-09-14 21:08:16.989496471 +0200
-+++ openssh-6.1p1/servconf.c   2012-09-14 21:09:30.864868698 +0200
-@@ -152,6 +152,7 @@ initialize_server_options(ServerOptions
-       options->ip_qos_interactive = -1;
-       options->ip_qos_bulk = -1;
-       options->version_addendum = NULL;
-+      options->use_kuserok = -1;
- }
- void
-@@ -301,6 +302,8 @@ fill_default_server_options(ServerOption
-               options->version_addendum = xstrdup("");
-       if (options->show_patchlevel == -1)
-               options->show_patchlevel = 0;
-+      if (options->use_kuserok == -1)
-+              options->use_kuserok = 1;
-       /* Turn privilege separation on by default */
-       if (use_privsep == -1)
-@@ -327,7 +330,7 @@ typedef enum {
-       sPermitRootLogin, sLogFacility, sLogLevel,
-       sRhostsRSAAuthentication, sRSAAuthentication,
-       sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
--      sKerberosGetAFSToken,
-+      sKerberosGetAFSToken, sKerberosUseKuserok,
-       sKerberosTgtPassing, sChallengeResponseAuthentication,
-       sPasswordAuthentication, sKbdInteractiveAuthentication,
-       sListenAddress, sAddressFamily,
-@@ -399,11 +402,13 @@ static struct {
- #else
-       { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
- #endif
-+      { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL },
- #else
-       { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
-       { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
-       { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
-       { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
-+      { "kerberosusekuserok", sUnsupported, SSHCFG_ALL },
- #endif
-       { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
-       { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
-@@ -1486,6 +1491,10 @@ process_server_config_line(ServerOptions
-               *activep = value;
-               break;
-+      case sKerberosUseKuserok:
-+              intptr = &options->use_kuserok;
-+              goto parse_flag;
-+
-       case sPermitOpen:
-               arg = strdelim(&cp);
-               if (!arg || *arg == '\0')
-@@ -1769,6 +1778,7 @@ copy_set_server_options(ServerOptions *d
-       M_CP_INTOPT(max_authtries);
-       M_CP_INTOPT(ip_qos_interactive);
-       M_CP_INTOPT(ip_qos_bulk);
-+      M_CP_INTOPT(use_kuserok);
-       /* See comment in servconf.h */
-       COPY_MATCH_STRING_OPTS();
-@@ -2005,6 +2015,7 @@ dump_config(ServerOptions *o)
-       dump_cfg_fmtint(sUseDNS, o->use_dns);
-       dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
-       dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
-+      dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
-       /* string arguments */
-       dump_cfg_string(sPidFile, o->pid_file);
-diff -up openssh-6.1p1/servconf.h.kuserok openssh-6.1p1/servconf.h
---- openssh-6.1p1/servconf.h.kuserok   2012-09-14 21:08:16.990496476 +0200
-+++ openssh-6.1p1/servconf.h   2012-09-14 21:08:17.071496942 +0200
-@@ -169,6 +169,7 @@ typedef struct {
-       int     num_permitted_opens;
-+      int     use_kuserok;
-       char   *chroot_directory;
-       char   *revoked_keys_file;
-       char   *trusted_user_ca_keys;
-diff -up openssh-6.1p1/sshd_config.kuserok openssh-6.1p1/sshd_config
---- openssh-6.1p1/sshd_config.kuserok  2012-09-14 21:08:17.002496545 +0200
-+++ openssh-6.1p1/sshd_config  2012-09-14 21:08:17.074496957 +0200
-@@ -79,6 +79,7 @@ ChallengeResponseAuthentication no
- #KerberosOrLocalPasswd yes
- #KerberosTicketCleanup yes
- #KerberosGetAFSToken no
-+#KerberosUseKuserok yes
- # GSSAPI options
- #GSSAPIAuthentication no
-diff -up openssh-6.1p1/sshd_config.5.kuserok openssh-6.1p1/sshd_config.5
---- openssh-6.1p1/sshd_config.5.kuserok        2012-09-14 21:08:17.004496556 +0200
-+++ openssh-6.1p1/sshd_config.5        2012-09-14 21:08:17.073496952 +0200
-@@ -618,6 +618,10 @@ Specifies whether to automatically destr
- file on logout.
- The default is
- .Dq yes .
-+.It Cm KerberosUseKuserok
-+Specifies whether to look at .k5login file for user's aliases.
-+The default is
-+.Dq yes .
- .It Cm KexAlgorithms
- Specifies the available KEX (Key Exchange) algorithms.
- Multiple algorithms must be comma-separated.
-@@ -767,6 +771,7 @@ Available keywords are
- .Cm HostbasedUsesNameFromPacketOnly ,
- .Cm KbdInteractiveAuthentication ,
- .Cm KerberosAuthentication ,
-+.Cm KerberosUseKuserok ,
- .Cm MaxAuthTries ,
- .Cm MaxSessions ,
- .Cm PubkeyAuthentication ,
diff --git a/openssh/patches/openssh-6.1p1-required-authentications.patch b/openssh/patches/openssh-6.1p1-required-authentications.patch
deleted file mode 100644 (file)
index bfc28ee..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-diff -up openssh-6.1p1/servconf.c.required-authentication openssh-6.1p1/servconf.c
---- openssh-6.1p1/servconf.c.required-authentication   2012-11-30 21:13:14.375382453 +0100
-+++ openssh-6.1p1/servconf.c   2012-11-30 21:33:56.972017545 +0100
-@@ -495,6 +495,8 @@ static struct {
-       { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL },
-       { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
-       { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
-+      { "requiredauthentications1", sAuthenticationMethods, SSHCFG_ALL },
-+      { "requiredauthentications2", sAuthenticationMethods, SSHCFG_ALL },
-       { NULL, sBadOption, 0 }
- };
-@@ -1560,6 +1562,9 @@ process_server_config_line(ServerOptions
-               return 0;
-       case sAuthenticationMethods:
-+              if (strncasecmp(arg, "requiredauthentications", 23) == 0)
-+                      logit("%s line %d: Option %s is obsolete. Please use AuthenticationMethods",
-+                          filename, linenum, arg);
-               if (*activep && options->num_auth_methods == 0) {
-                       while ((arg = strdelim(&cp)) && *arg != '\0') {
-                               if (options->num_auth_methods >=
diff --git a/openssh/patches/openssh-6.1p1-role-mls.patch b/openssh/patches/openssh-6.1p1-role-mls.patch
deleted file mode 100644 (file)
index 4de3dae..0000000
+++ /dev/null
@@ -1,934 +0,0 @@
-diff -up openssh-6.1p1/auth1.c.role-mls openssh-6.1p1/auth1.c
---- openssh-6.1p1/auth1.c.role-mls     2012-11-28 17:06:43.657990103 +0100
-+++ openssh-6.1p1/auth1.c      2012-11-28 17:06:43.699989959 +0100
-@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt)
- {
-       u_int ulen;
-       char *user, *style = NULL;
-+#ifdef WITH_SELINUX
-+      char *role=NULL;
-+#endif
-       /* Get the name of the user that we wish to log in as. */
-       packet_read_expect(SSH_CMSG_USER);
-@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt)
-       user = packet_get_cstring(&ulen);
-       packet_check_eom();
-+#ifdef WITH_SELINUX
-+      if ((role = strchr(user, '/')) != NULL)
-+              *role++ = '\0';
-+#endif
-+
-       if ((style = strchr(user, ':')) != NULL)
-               *style++ = '\0';
-+#ifdef WITH_SELINUX
-+      else
-+              if (role && (style = strchr(role, ':')) != NULL)
-+                      *style++ = '\0';
-+#endif
-       authctxt->user = user;
-       authctxt->style = style;
-+#ifdef WITH_SELINUX
-+      authctxt->role = role;
-+#endif
-       /* Verify that the user is a valid user. */
-       if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
-diff -up openssh-6.1p1/auth2.c.role-mls openssh-6.1p1/auth2.c
---- openssh-6.1p1/auth2.c.role-mls     2012-11-28 17:06:43.661990089 +0100
-+++ openssh-6.1p1/auth2.c      2012-11-28 17:11:09.058916613 +0100
-@@ -218,6 +218,9 @@ input_userauth_request(int type, u_int32
-       Authctxt *authctxt = ctxt;
-       Authmethod *m = NULL;
-       char *user, *service, *method, *style = NULL;
-+#ifdef WITH_SELINUX
-+      char *role = NULL;
-+#endif
-       int authenticated = 0;
-       if (authctxt == NULL)
-@@ -229,6 +232,11 @@ input_userauth_request(int type, u_int32
-       debug("userauth-request for user %s service %s method %s", user, service, method);
-       debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
-+#ifdef WITH_SELINUX
-+      if ((role = strchr(user, '/')) != NULL)
-+              *role++ = 0;
-+#endif
-+
-       if ((style = strchr(user, ':')) != NULL)
-               *style++ = 0;
-@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32
-                   use_privsep ? " [net]" : "");
-               authctxt->service = xstrdup(service);
-               authctxt->style = style ? xstrdup(style) : NULL;
--              if (use_privsep)
-+#ifdef WITH_SELINUX
-+              authctxt->role = role ? xstrdup(role) : NULL;
-+#endif
-+              if (use_privsep) {
-                       mm_inform_authserv(service, style);
-+#ifdef WITH_SELINUX
-+                      mm_inform_authrole(role);
-+#endif
-+              }
-               userauth_banner();
-               if (auth2_setup_methods_lists(authctxt) != 0)
-                       packet_disconnect("no authentication methods enabled");
-diff -up openssh-6.1p1/auth2-gss.c.role-mls openssh-6.1p1/auth2-gss.c
---- openssh-6.1p1/auth2-gss.c.role-mls 2011-05-05 06:04:11.000000000 +0200
-+++ openssh-6.1p1/auth2-gss.c  2012-11-28 17:06:43.700989956 +0100
-@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple
-       Authctxt *authctxt = ctxt;
-       Gssctxt *gssctxt;
-       int authenticated = 0;
-+      char *micuser;
-       Buffer b;
-       gss_buffer_desc mic, gssbuf;
-       u_int len;
-@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple
-       mic.value = packet_get_string(&len);
-       mic.length = len;
--      ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
-+#ifdef WITH_SELINUX
-+      if (authctxt->role && (strlen(authctxt->role) > 0))
-+              xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
-+      else
-+#endif
-+              micuser = authctxt->user;
-+      ssh_gssapi_buildmic(&b, micuser, authctxt->service,
-           "gssapi-with-mic");
-       gssbuf.value = buffer_ptr(&b);
-@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple
-               logit("GSSAPI MIC check failed");
-       buffer_free(&b);
-+      if (micuser != authctxt->user)
-+              xfree(micuser);
-       xfree(mic.value);
-       authctxt->postponed = 0;
-diff -up openssh-6.1p1/auth2-hostbased.c.role-mls openssh-6.1p1/auth2-hostbased.c
---- openssh-6.1p1/auth2-hostbased.c.role-mls   2012-11-28 17:06:43.669990062 +0100
-+++ openssh-6.1p1/auth2-hostbased.c    2012-11-28 17:06:43.700989956 +0100
-@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt)
-       buffer_put_string(&b, session_id2, session_id2_len);
-       /* reconstruct packet */
-       buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
--      buffer_put_cstring(&b, authctxt->user);
-+#ifdef WITH_SELINUX
-+      if (authctxt->role) {
-+              buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
-+              buffer_append(&b, authctxt->user, strlen(authctxt->user));
-+              buffer_put_char(&b, '/');
-+              buffer_append(&b, authctxt->role, strlen(authctxt->role));
-+      } else 
-+#endif
-+              buffer_put_cstring(&b, authctxt->user);
-       buffer_put_cstring(&b, service);
-       buffer_put_cstring(&b, "hostbased");
-       buffer_put_string(&b, pkalg, alen);
-diff -up openssh-6.1p1/auth2-pubkey.c.role-mls openssh-6.1p1/auth2-pubkey.c
---- openssh-6.1p1/auth2-pubkey.c.role-mls      2012-11-28 17:06:43.669990062 +0100
-+++ openssh-6.1p1/auth2-pubkey.c       2012-11-28 17:06:43.700989956 +0100
-@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt)
-               }
-               /* reconstruct packet */
-               buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
--              buffer_put_cstring(&b, authctxt->user);
-+#ifdef WITH_SELINUX
-+              if (authctxt->role) {
-+                      buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
-+                      buffer_append(&b, authctxt->user, strlen(authctxt->user));
-+                      buffer_put_char(&b, '/');
-+                      buffer_append(&b, authctxt->role, strlen(authctxt->role));
-+              } else 
-+#endif
-+                      buffer_put_cstring(&b, authctxt->user);
-               buffer_put_cstring(&b,
-                   datafellows & SSH_BUG_PKSERVICE ?
-                   "ssh-userauth" :
-diff -up openssh-6.1p1/auth.h.role-mls openssh-6.1p1/auth.h
---- openssh-6.1p1/auth.h.role-mls      2012-11-28 17:06:43.669990062 +0100
-+++ openssh-6.1p1/auth.h       2012-11-28 17:06:43.699989959 +0100
-@@ -59,6 +59,9 @@ struct Authctxt {
-       char            *service;
-       struct passwd   *pw;            /* set if 'valid' */
-       char            *style;
-+#ifdef WITH_SELINUX
-+      char            *role;
-+#endif
-       void            *kbdintctxt;
-       void            *jpake_ctx;
- #ifdef BSD_AUTH
-diff -up openssh-6.1p1/auth-pam.c.role-mls openssh-6.1p1/auth-pam.c
---- openssh-6.1p1/auth-pam.c.role-mls  2012-11-28 17:06:43.638990168 +0100
-+++ openssh-6.1p1/auth-pam.c   2012-11-28 17:06:43.699989959 +0100
-@@ -1074,7 +1074,7 @@ is_pam_session_open(void)
-  * during the ssh authentication process.
-  */
- int
--do_pam_putenv(char *name, char *value)
-+do_pam_putenv(char *name, const char *value)
- {
-       int ret = 1;
- #ifdef HAVE_PAM_PUTENV
-diff -up openssh-6.1p1/auth-pam.h.role-mls openssh-6.1p1/auth-pam.h
---- openssh-6.1p1/auth-pam.h.role-mls  2004-09-11 14:17:26.000000000 +0200
-+++ openssh-6.1p1/auth-pam.h   2012-11-28 17:06:43.699989959 +0100
-@@ -38,7 +38,7 @@ void do_pam_session(void);
- void do_pam_set_tty(const char *);
- void do_pam_setcred(int );
- void do_pam_chauthtok(void);
--int do_pam_putenv(char *, char *);
-+int do_pam_putenv(char *, const char *);
- char ** fetch_pam_environment(void);
- char ** fetch_pam_child_environment(void);
- void free_pam_environment(char **);
-diff -up openssh-6.1p1/misc.c.role-mls openssh-6.1p1/misc.c
---- openssh-6.1p1/misc.c.role-mls      2011-09-22 13:34:36.000000000 +0200
-+++ openssh-6.1p1/misc.c       2012-11-28 17:06:43.701989952 +0100
-@@ -427,6 +427,7 @@ char *
- colon(char *cp)
- {
-       int flag = 0;
-+      int start = 1;
-       if (*cp == ':')         /* Leading colon is part of file name. */
-               return NULL;
-@@ -442,6 +443,13 @@ colon(char *cp)
-                       return (cp);
-               if (*cp == '/')
-                       return NULL;
-+              if (start) {
-+              /* Slash on beginning or after dots only denotes file name. */
-+                      if (*cp == '/')
-+                              return (0);
-+                      if (*cp != '.')
-+                              start = 0;
-+              }
-       }
-       return NULL;
- }
-diff -up openssh-6.1p1/monitor.c.role-mls openssh-6.1p1/monitor.c
---- openssh-6.1p1/monitor.c.role-mls   2012-11-28 17:06:43.686990004 +0100
-+++ openssh-6.1p1/monitor.c    2012-11-28 17:06:43.701989952 +0100
-@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *);
- int mm_answer_pwnamallow(int, Buffer *);
- int mm_answer_auth2_read_banner(int, Buffer *);
- int mm_answer_authserv(int, Buffer *);
-+#ifdef WITH_SELINUX
-+int mm_answer_authrole(int, Buffer *);
-+#endif
- int mm_answer_authpassword(int, Buffer *);
- int mm_answer_bsdauthquery(int, Buffer *);
- int mm_answer_bsdauthrespond(int, Buffer *);
-@@ -231,6 +234,9 @@ struct mon_table mon_dispatch_proto20[]
-     {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
-     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
-     {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
-+#ifdef WITH_SELINUX
-+    {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
-+#endif
-     {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
-     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
- #ifdef USE_PAM
-@@ -838,6 +844,9 @@ mm_answer_pwnamallow(int sock, Buffer *m
-       else {
-               /* Allow service/style information on the auth context */
-               monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
-+#ifdef WITH_SELINUX
-+              monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
-+#endif
-               monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
-       }
- #ifdef USE_PAM
-@@ -881,6 +890,25 @@ mm_answer_authserv(int sock, Buffer *m)
-       return (0);
- }
-+#ifdef WITH_SELINUX
-+int
-+mm_answer_authrole(int sock, Buffer *m)
-+{
-+      monitor_permit_authentications(1);
-+
-+      authctxt->role = buffer_get_string(m, NULL);
-+      debug3("%s: role=%s",
-+          __func__, authctxt->role);
-+
-+      if (strlen(authctxt->role) == 0) {
-+              xfree(authctxt->role);
-+              authctxt->role = NULL;
-+      }
-+
-+      return (0);
-+}
-+#endif
-+
- int
- mm_answer_authpassword(int sock, Buffer *m)
- {
-@@ -1251,7 +1279,7 @@ static int
- monitor_valid_userblob(u_char *data, u_int datalen)
- {
-       Buffer b;
--      char *p;
-+      char *p, *r;
-       u_int len;
-       int fail = 0;
-@@ -1277,6 +1305,8 @@ monitor_valid_userblob(u_char *data, u_i
-       if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
-               fail++;
-       p = buffer_get_string(&b, NULL);
-+      if ((r = strchr(p, '/')) != NULL)
-+              *r = '\0';
-       if (strcmp(authctxt->user, p) != 0) {
-               logit("wrong user name passed to monitor: expected %s != %.100s",
-                   authctxt->user, p);
-@@ -1308,7 +1338,7 @@ monitor_valid_hostbasedblob(u_char *data
-     char *chost)
- {
-       Buffer b;
--      char *p;
-+      char *p, *r;
-       u_int len;
-       int fail = 0;
-@@ -1325,6 +1355,8 @@ monitor_valid_hostbasedblob(u_char *data
-       if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
-               fail++;
-       p = buffer_get_string(&b, NULL);
-+      if ((r = strchr(p, '/')) != NULL)
-+              *r = '\0';
-       if (strcmp(authctxt->user, p) != 0) {
-               logit("wrong user name passed to monitor: expected %s != %.100s",
-                   authctxt->user, p);
-diff -up openssh-6.1p1/monitor.h.role-mls openssh-6.1p1/monitor.h
---- openssh-6.1p1/monitor.h.role-mls   2012-11-28 17:06:43.686990004 +0100
-+++ openssh-6.1p1/monitor.h    2012-11-28 17:06:43.701989952 +0100
-@@ -31,6 +31,9 @@
- enum monitor_reqtype {
-       MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
-       MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
-+#ifdef WITH_SELINUX
-+      MONITOR_REQ_AUTHROLE,
-+#endif
-       MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
-       MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
-       MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
-diff -up openssh-6.1p1/monitor_wrap.c.role-mls openssh-6.1p1/monitor_wrap.c
---- openssh-6.1p1/monitor_wrap.c.role-mls      2012-11-28 17:06:43.686990004 +0100
-+++ openssh-6.1p1/monitor_wrap.c       2012-11-28 17:06:43.702989948 +0100
-@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char *
-       buffer_free(&m);
- }
-+/* Inform the privileged process about role */
-+
-+#ifdef WITH_SELINUX
-+void
-+mm_inform_authrole(char *role)
-+{
-+      Buffer m;
-+
-+      debug3("%s entering", __func__);
-+
-+      buffer_init(&m);
-+      buffer_put_cstring(&m, role ? role : "");
-+
-+      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
-+
-+      buffer_free(&m);
-+}
-+#endif
-+
- /* Do the password authentication */
- int
- mm_auth_password(Authctxt *authctxt, char *password)
-diff -up openssh-6.1p1/monitor_wrap.h.role-mls openssh-6.1p1/monitor_wrap.h
---- openssh-6.1p1/monitor_wrap.h.role-mls      2012-11-28 17:06:43.686990004 +0100
-+++ openssh-6.1p1/monitor_wrap.h       2012-11-28 17:06:43.702989948 +0100
-@@ -42,6 +42,9 @@ int mm_is_monitor(void);
- DH *mm_choose_dh(int, int, int);
- int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
- void mm_inform_authserv(char *, char *);
-+#ifdef WITH_SELINUX
-+void mm_inform_authrole(char *);
-+#endif
- struct passwd *mm_getpwnamallow(const char *);
- char *mm_auth2_read_banner(void);
- int mm_auth_password(struct Authctxt *, char *);
-diff -up openssh-6.1p1/openbsd-compat/Makefile.in.role-mls openssh-6.1p1/openbsd-compat/Makefile.in
---- openssh-6.1p1/openbsd-compat/Makefile.in.role-mls  2011-11-04 01:25:25.000000000 +0100
-+++ openssh-6.1p1/openbsd-compat/Makefile.in   2012-11-28 17:06:43.702989948 +0100
-@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport
- COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
--PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
-+PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o
- .c.o:
-       $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
-diff -up openssh-6.1p1/openbsd-compat/port-linux.c.role-mls openssh-6.1p1/openbsd-compat/port-linux.c
---- openssh-6.1p1/openbsd-compat/port-linux.c.role-mls 2012-03-09 00:25:18.000000000 +0100
-+++ openssh-6.1p1/openbsd-compat/port-linux.c  2012-11-28 17:06:43.702989948 +0100
-@@ -31,68 +31,271 @@
- #include "log.h"
- #include "xmalloc.h"
-+#include "servconf.h"
- #include "port-linux.h"
-+#include "key.h"
-+#include "hostfile.h"
-+#include "auth.h"
- #ifdef WITH_SELINUX
- #include <selinux/selinux.h>
- #include <selinux/flask.h>
-+#include <selinux/context.h>
- #include <selinux/get_context_list.h>
-+#include <selinux/get_default_type.h>
-+#include <selinux/av_permissions.h>
-+
-+#ifdef HAVE_LINUX_AUDIT
-+#include <libaudit.h>
-+#include <unistd.h>
-+#endif
- #ifndef SSH_SELINUX_UNCONFINED_TYPE
- # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:"
- #endif
--/* Wrapper around is_selinux_enabled() to log its return value once only */
--int
--ssh_selinux_enabled(void)
-+extern ServerOptions options;
-+extern Authctxt *the_authctxt;
-+extern int inetd_flag;
-+extern int rexeced_flag;
-+
-+/* Send audit message */
-+static int
-+send_audit_message(int success, security_context_t default_context,
-+                     security_context_t selected_context)
-+{
-+      int rc=0;
-+#ifdef HAVE_LINUX_AUDIT
-+      char *msg = NULL;
-+      int audit_fd = audit_open();
-+      security_context_t default_raw=NULL;
-+      security_context_t selected_raw=NULL;
-+      rc = -1;
-+      if (audit_fd < 0) {
-+              if (errno == EINVAL || errno == EPROTONOSUPPORT ||
-+                                      errno == EAFNOSUPPORT)
-+                              return 0; /* No audit support in kernel */
-+              error("Error connecting to audit system.");
-+              return rc;
-+      }
-+      if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
-+              error("Error translating default context.");
-+              default_raw = NULL;
-+      }
-+      if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
-+              error("Error translating selected context.");
-+              selected_raw = NULL;
-+      }
-+      if (asprintf(&msg, "sshd: default-context=%s selected-context=%s",
-+                   default_raw ? default_raw : (default_context ? default_context: "?"),
-+                   selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) {
-+              error("Error allocating memory.");
-+              goto out;
-+      }
-+      if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
-+                                 msg, NULL, NULL, NULL, success) <= 0) {
-+              error("Error sending audit message.");
-+              goto out;
-+      }
-+      rc = 0;
-+      out:
-+      free(msg);
-+      freecon(default_raw);
-+      freecon(selected_raw);
-+      close(audit_fd);
-+#endif
-+      return rc;
-+}
-+
-+static int
-+mls_range_allowed(security_context_t src, security_context_t dst)
- {
--      static int enabled = -1;
-+      struct av_decision avd;
-+      int retval;
-+      unsigned int bit = CONTEXT__CONTAINS;
-+
-+      debug("%s: src:%s dst:%s", __func__, src, dst);
-+      retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd);
-+      if (retval || ((bit & avd.allowed) != bit))
-+              return 0;
-+
-+      return 1;
-+}
-+
-+static int
-+get_user_context(const char *sename, const char *role, const char *lvl,
-+      security_context_t *sc) {
-+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
-+      if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) {
-+              /* User may have requested a level completely outside of his 
-+                 allowed range. We get a context just for auditing as the
-+                 range check below will certainly fail for default context. */
-+#endif
-+              if (get_default_context(sename, NULL, sc) != 0) {
-+                      *sc = NULL;
-+                      return -1;
-+              }
-+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
-+      }
-+#endif
-+      if (role != NULL && role[0]) {
-+              context_t con;
-+              char *type=NULL;
-+              if (get_default_type(role, &type) != 0) {
-+                      error("get_default_type: failed to get default type for '%s'",
-+                              role);
-+                      goto out;
-+              }
-+              con = context_new(*sc);
-+              if (!con) {
-+                      goto out;
-+              }
-+              context_role_set(con, role);
-+              context_type_set(con, type);
-+              freecon(*sc);
-+              *sc = strdup(context_str(con));
-+              context_free(con);
-+              if (!*sc) 
-+                      return -1;
-+      }
-+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
-+      if (lvl != NULL && lvl[0]) {
-+              /* verify that the requested range is obtained */
-+              context_t con;
-+              security_context_t obtained_raw;
-+              security_context_t requested_raw;
-+              con = context_new(*sc);
-+              if (!con) {
-+                      goto out;
-+              }
-+              context_range_set(con, lvl);
-+              if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) {
-+                      context_free(con);
-+                      goto out;
-+              }
-+              if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) {
-+                      freecon(obtained_raw);
-+                      context_free(con);
-+                      goto out;
-+              }
--      if (enabled == -1) {
--              enabled = (is_selinux_enabled() == 1);
--              debug("SELinux support %s", enabled ? "enabled" : "disabled");
-+              debug("get_user_context: obtained context '%s' requested context '%s'",
-+                      obtained_raw, requested_raw);
-+              if (strcmp(obtained_raw, requested_raw)) {
-+                      /* set the context to the real requested one but fail */
-+                      freecon(requested_raw);
-+                      freecon(obtained_raw);
-+                      freecon(*sc);
-+                      *sc = strdup(context_str(con));
-+                      context_free(con);
-+                      return -1;
-+              }
-+              freecon(requested_raw);
-+              freecon(obtained_raw);
-+              context_free(con);
-       }
-+#endif
-+      return 0;
-+      out:
-+      freecon(*sc);
-+      *sc = NULL;
-+      return -1;
-+}
--      return (enabled);
-+static void
-+ssh_selinux_get_role_level(char **role, const char **level)
-+{
-+      *role = NULL;
-+      *level = NULL;
-+      if (the_authctxt) {
-+              if (the_authctxt->role != NULL) {
-+                      char *slash;
-+                      *role = xstrdup(the_authctxt->role);
-+                      if ((slash = strchr(*role, '/')) != NULL) {
-+                              *slash = '\0';
-+                              *level = slash + 1;
-+                      }
-+              }
-+      }
- }
- /* Return the default security context for the given username */
- static security_context_t
--ssh_selinux_getctxbyname(char *pwname)
-+ssh_selinux_getctxbyname(char *pwname,
-+      security_context_t *default_sc, security_context_t *user_sc)
- {
--      security_context_t sc = NULL;
--      char *sename = NULL, *lvl = NULL;
--      int r;
-+      char *sename, *lvl;
-+      char *role;
-+      const char *reqlvl;
-+      int r = 0;
-+      context_t con = NULL;
-+ 
-+      ssh_selinux_get_role_level(&role, &reqlvl);
- #ifdef HAVE_GETSEUSERBYNAME
--      if (getseuserbyname(pwname, &sename, &lvl) != 0)
--              return NULL;
-+      if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
-+              sename = NULL;
-+              lvl = NULL;
-+      }
- #else
-       sename = pwname;
--      lvl = NULL;
-+      lvl = "";
- #endif
-+      if (r == 0) {
- #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
--      r = get_default_context_with_level(sename, lvl, NULL, &sc);
-+              r = get_default_context_with_level(sename, lvl, NULL, default_sc);
- #else
--      r = get_default_context(sename, NULL, &sc);
-+              r = get_default_context(sename, NULL, default_sc);
- #endif
-+      }
-+
-+      if (r == 0) {
-+              /* If launched from xinetd, we must use current level */
-+              if (inetd_flag && !rexeced_flag) {
-+                      security_context_t sshdsc=NULL;
-+
-+                      if (getcon_raw(&sshdsc) < 0)
-+                              fatal("failed to allocate security context");
-+
-+                      if ((con=context_new(sshdsc)) == NULL)
-+                              fatal("failed to allocate selinux context");
-+                      reqlvl = context_range_get(con);
-+                      freecon(sshdsc);
-+                      if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0)
-+                          /* we actually don't change level */
-+                          reqlvl = "";
-+
-+                      debug("%s: current connection level '%s'", __func__, reqlvl);
--      if (r != 0) {
--              switch (security_getenforce()) {
--              case -1:
--                      fatal("%s: ssh_selinux_getctxbyname: "
--                          "security_getenforce() failed", __func__);
--              case 0:
--                      error("%s: Failed to get default SELinux security "
--                          "context for %s", __func__, pwname);
--                      sc = NULL;
--                      break;
--              default:
--                      fatal("%s: Failed to get default SELinux security "
--                          "context for %s (in enforcing mode)",
--                          __func__, pwname);
-               }
-+              
-+              if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) {
-+                      r = get_user_context(sename, role, reqlvl, user_sc);
-+              
-+                      if (r == 0 && reqlvl != NULL && reqlvl[0]) {
-+                              security_context_t default_level_sc = *default_sc;
-+                              if (role != NULL && role[0]) {
-+                                      if (get_user_context(sename, role, lvl, &default_level_sc) < 0)
-+                                              default_level_sc = *default_sc;
-+                              }
-+                              /* verify that the requested range is contained in the user range */
-+                              if (mls_range_allowed(default_level_sc, *user_sc)) {
-+                                      logit("permit MLS level %s (user range %s)", reqlvl, lvl);
-+                              } else {
-+                                      r = -1;
-+                                      error("deny MLS level %s (user range %s)", reqlvl, lvl);
-+                              }
-+                              if (default_level_sc != *default_sc)
-+                                      freecon(default_level_sc);
-+                      }
-+              } else {
-+                      *user_sc = *default_sc;
-+              }
-+      }
-+      if (r != 0) {
-+              error("%s: Failed to get default SELinux security "
-+                  "context for %s", __func__, pwname);
-       }
- #ifdef HAVE_GETSEUSERBYNAME
-@@ -102,7 +305,42 @@ ssh_selinux_getctxbyname(char *pwname)
-               xfree(lvl);
- #endif
--      return sc;
-+      if (role != NULL)
-+              xfree(role);
-+      if (con)
-+              context_free(con);
-+ 
-+      return (r);
-+}
-+
-+/* Setup environment variables for pam_selinux */
-+static int
-+ssh_selinux_setup_pam_variables(void)
-+{
-+      const char *reqlvl;
-+      char *role;
-+      char *use_current;
-+      int rv;
-+
-+      debug3("%s: setting execution context", __func__);
-+
-+      ssh_selinux_get_role_level(&role, &reqlvl);
-+
-+      rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
-+      
-+      if (inetd_flag && !rexeced_flag) {
-+              use_current = "1";
-+      } else {
-+              use_current = "";
-+              rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
-+      }
-+
-+      rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
-+
-+      if (role != NULL)
-+              xfree(role);
-+      
-+      return rv;
- }
- /* Set the execution context to the default for the specified user */
-@@ -110,28 +348,71 @@ void
- ssh_selinux_setup_exec_context(char *pwname)
- {
-       security_context_t user_ctx = NULL;
-+      int r = 0;
-+      security_context_t default_ctx = NULL;
-       if (!ssh_selinux_enabled())
-               return;
-+      if (options.use_pam) {
-+              /* do not compute context, just setup environment for pam_selinux */
-+              if (ssh_selinux_setup_pam_variables()) {
-+                      switch (security_getenforce()) {
-+                      case -1:
-+                              fatal("%s: security_getenforce() failed", __func__);
-+                      case 0:
-+                              error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.",
-+                                  __func__);
-+                      break;
-+                      default:
-+                              fatal("%s: SELinux PAM variable setup failure. Aborting connection.",
-+                                  __func__);
-+                      }
-+              }
-+              return;
-+      }
-+
-       debug3("%s: setting execution context", __func__);
--      user_ctx = ssh_selinux_getctxbyname(pwname);
--      if (setexeccon(user_ctx) != 0) {
-+      r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
-+      if (r >= 0) {
-+              r = setexeccon(user_ctx);
-+              if (r < 0) {
-+                      error("%s: Failed to set SELinux execution context %s for %s",
-+                          __func__, user_ctx, pwname);
-+              } 
-+#ifdef HAVE_SETKEYCREATECON
-+              else if (setkeycreatecon(user_ctx) < 0) {
-+                      error("%s: Failed to set SELinux keyring creation context %s for %s",
-+                          __func__, user_ctx, pwname);
-+              }
-+#endif
-+      }
-+      if (user_ctx == NULL) {
-+              user_ctx = default_ctx;
-+      }
-+      if (r < 0 || user_ctx != default_ctx) {
-+              /* audit just the case when user changed a role or there was
-+                 a failure */
-+              send_audit_message(r >= 0, default_ctx, user_ctx);
-+      }
-+      if (r < 0) {
-               switch (security_getenforce()) {
-               case -1:
-                       fatal("%s: security_getenforce() failed", __func__);
-               case 0:
--                      error("%s: Failed to set SELinux execution "
--                          "context for %s", __func__, pwname);
-+                      error("%s: SELinux failure. Continuing in permissive mode.",
-+                          __func__);
-                       break;
-               default:
--                      fatal("%s: Failed to set SELinux execution context "
--                          "for %s (in enforcing mode)", __func__, pwname);
-+                      fatal("%s: SELinux failure. Aborting connection.",
-+                          __func__);
-               }
-       }
--      if (user_ctx != NULL)
-+      if (user_ctx != NULL && user_ctx != default_ctx)
-               freecon(user_ctx);
-+      if (default_ctx != NULL)
-+              freecon(default_ctx);
-       debug3("%s: done", __func__);
- }
-@@ -149,7 +430,10 @@ ssh_selinux_setup_pty(char *pwname, cons
-       debug3("%s: setting TTY context on %s", __func__, tty);
--      user_ctx = ssh_selinux_getctxbyname(pwname);
-+      if (getexeccon(&user_ctx) < 0) {
-+              error("%s: getexeccon: %s", __func__, strerror(errno));
-+              goto out;
-+      }
-       /* XXX: should these calls fatal() upon failure in enforcing mode? */
-@@ -221,21 +505,6 @@ ssh_selinux_change_context(const char *n
-       xfree(newctx);
- }
--void
--ssh_selinux_setfscreatecon(const char *path)
--{
--      security_context_t context;
--
--      if (!ssh_selinux_enabled())
--              return;
--      if (path == NULL) {
--              setfscreatecon(NULL);
--              return;
--      }
--      if (matchpathcon(path, 0700, &context) == 0)
--              setfscreatecon(context);
--}
--
- #endif /* WITH_SELINUX */
- #ifdef LINUX_OOM_ADJUST
-diff -up openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.1p1/openbsd-compat/port-linux_part_2.c
---- openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls  2012-11-28 17:06:43.703989944 +0100
-+++ openssh-6.1p1/openbsd-compat/port-linux_part_2.c   2012-11-28 17:06:43.703989944 +0100
-@@ -0,0 +1,75 @@
-+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */
-+
-+/*
-+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
-+ * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+/*
-+ * Linux-specific portability code - just SELinux support at present
-+ */
-+
-+#include "includes.h"
-+
-+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
-+#include <errno.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "log.h"
-+#include "xmalloc.h"
-+#include "port-linux.h"
-+#include "key.h"
-+#include "hostfile.h"
-+#include "auth.h"
-+
-+#ifdef WITH_SELINUX
-+#include <selinux/selinux.h>
-+#include <selinux/flask.h>
-+#include <selinux/get_context_list.h>
-+
-+/* Wrapper around is_selinux_enabled() to log its return value once only */
-+int
-+ssh_selinux_enabled(void)
-+{
-+      static int enabled = -1;
-+
-+      if (enabled == -1) {
-+              enabled = (is_selinux_enabled() == 1);
-+              debug("SELinux support %s", enabled ? "enabled" : "disabled");
-+      }
-+
-+      return (enabled);
-+}
-+
-+void
-+ssh_selinux_setfscreatecon(const char *path)
-+{
-+      security_context_t context;
-+
-+      if (!ssh_selinux_enabled())
-+              return;
-+      if (path == NULL) {
-+              setfscreatecon(NULL);
-+              return;
-+      }
-+      if (matchpathcon(path, 0700, &context) == 0)
-+              setfscreatecon(context);
-+}
-+
-+#endif /* WITH_SELINUX */
-+
-+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
-diff -up openssh-6.1p1/sshd.c.role-mls openssh-6.1p1/sshd.c
---- openssh-6.1p1/sshd.c.role-mls      2012-11-28 17:06:43.688989996 +0100
-+++ openssh-6.1p1/sshd.c       2012-11-28 17:06:43.703989944 +0100
-@@ -2101,6 +2101,9 @@ main(int ac, char **av)
-               restore_uid();
-       }
- #endif
-+#ifdef WITH_SELINUX
-+      ssh_selinux_setup_exec_context(authctxt->pw->pw_name);
-+#endif
- #ifdef USE_PAM
-       if (options.use_pam) {
-               do_pam_setcred(1);
diff --git a/openssh/patches/openssh-6.1p1-vendor.patch b/openssh/patches/openssh-6.1p1-vendor.patch
deleted file mode 100644 (file)
index 9cb326d..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-diff -up openssh-6.1p1/configure.ac.vendor openssh-6.1p1/configure.ac
---- openssh-6.1p1/configure.ac.vendor  2012-09-14 20:36:49.153085211 +0200
-+++ openssh-6.1p1/configure.ac 2012-09-14 20:36:49.559088133 +0200
-@@ -4303,6 +4303,12 @@ AC_ARG_WITH([lastlog],
-               fi
-       ]
- )
-+AC_ARG_ENABLE(vendor-patchlevel,
-+  [  --enable-vendor-patchlevel=TAG  specify a vendor patch level],
-+  [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.])
-+   SSH_VENDOR_PATCHLEVEL="$enableval"],
-+  [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.])
-+   SSH_VENDOR_PATCHLEVEL=none])
- dnl lastlog, [uw]tmpx? detection
- dnl  NOTE: set the paths in the platform section to avoid the
-@@ -4529,6 +4535,7 @@ echo "           Translate v4 in v6 hack
- echo "                  BSD Auth support: $BSD_AUTH_MSG"
- echo "              Random number source: $RAND_MSG"
- echo "             Privsep sandbox style: $SANDBOX_STYLE"
-+echo "                Vendor patch level: $SSH_VENDOR_PATCHLEVEL"
- echo ""
-diff -up openssh-6.1p1/servconf.c.vendor openssh-6.1p1/servconf.c
---- openssh-6.1p1/servconf.c.vendor    2012-09-14 20:36:49.124085002 +0200
-+++ openssh-6.1p1/servconf.c   2012-09-14 20:50:34.995972516 +0200
-@@ -128,6 +128,7 @@ initialize_server_options(ServerOptions
-       options->max_authtries = -1;
-       options->max_sessions = -1;
-       options->banner = NULL;
-+      options->show_patchlevel = -1;
-       options->use_dns = -1;
-       options->client_alive_interval = -1;
-       options->client_alive_count_max = -1;
-@@ -289,6 +290,9 @@ fill_default_server_options(ServerOption
-               options->ip_qos_bulk = IPTOS_THROUGHPUT;
-       if (options->version_addendum == NULL)
-               options->version_addendum = xstrdup("");
-+      if (options->show_patchlevel == -1)
-+              options->show_patchlevel = 0;
-+
-       /* Turn privilege separation on by default */
-       if (use_privsep == -1)
-               use_privsep = PRIVSEP_NOSANDBOX;
-@@ -326,7 +330,7 @@ typedef enum {
-       sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
-       sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
-       sMaxStartups, sMaxAuthTries, sMaxSessions,
--      sBanner, sUseDNS, sHostbasedAuthentication,
-+      sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
-       sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
-       sClientAliveCountMax, sAuthorizedKeysFile,
-       sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
-@@ -441,6 +445,7 @@ static struct {
-       { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
-       { "maxsessions", sMaxSessions, SSHCFG_ALL },
-       { "banner", sBanner, SSHCFG_ALL },
-+      { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL },
-       { "usedns", sUseDNS, SSHCFG_GLOBAL },
-       { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
-       { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
-@@ -1162,6 +1167,10 @@ process_server_config_line(ServerOptions
-               multistate_ptr = multistate_privsep;
-               goto parse_multistate;
-+      case sShowPatchLevel:
-+              intptr = &options->show_patchlevel;
-+              goto parse_flag;
-+
-       case sAllowUsers:
-               while ((arg = strdelim(&cp)) && *arg != '\0') {
-                       if (options->num_allow_users >= MAX_ALLOW_USERS)
-@@ -1956,6 +1965,7 @@ dump_config(ServerOptions *o)
-       dump_cfg_fmtint(sUseLogin, o->use_login);
-       dump_cfg_fmtint(sCompression, o->compression);
-       dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
-+      dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel);
-       dump_cfg_fmtint(sUseDNS, o->use_dns);
-       dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
-       dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
-diff -up openssh-6.1p1/servconf.h.vendor openssh-6.1p1/servconf.h
---- openssh-6.1p1/servconf.h.vendor    2012-09-14 20:36:49.125085009 +0200
-+++ openssh-6.1p1/servconf.h   2012-09-14 20:36:49.564088168 +0200
-@@ -140,6 +140,7 @@ typedef struct {
-       int     max_authtries;
-       int     max_sessions;
-       char   *banner;                 /* SSH-2 banner message */
-+      int     show_patchlevel;        /* Show vendor patch level to clients */
-       int     use_dns;
-       int     client_alive_interval;  /*
-                                        * poke the client this often to
-diff -up openssh-6.1p1/sshd_config.vendor openssh-6.1p1/sshd_config
---- openssh-6.1p1/sshd_config.vendor   2012-09-14 20:36:49.507087759 +0200
-+++ openssh-6.1p1/sshd_config  2012-09-14 20:36:49.565088175 +0200
-@@ -114,6 +114,7 @@ UsePrivilegeSeparation sandbox             # Defaul
- #Compression delayed
- #ClientAliveInterval 0
- #ClientAliveCountMax 3
-+#ShowPatchLevel no
- #UseDNS yes
- #PidFile /var/run/sshd.pid
- #MaxStartups 10
-diff -up openssh-6.1p1/sshd_config.0.vendor openssh-6.1p1/sshd_config.0
---- openssh-6.1p1/sshd_config.0.vendor 2012-09-14 20:36:49.510087780 +0200
-+++ openssh-6.1p1/sshd_config.0        2012-09-14 20:36:49.567088190 +0200
-@@ -558,6 +558,11 @@ DESCRIPTION
-              Defines the number of bits in the ephemeral protocol version 1
-              server key.  The minimum value is 512, and the default is 1024.
-+     ShowPatchLevel
-+           Specifies whether sshd will display the specific patch level of
-+           the binary in the server identification string.  The patch level
-+           is set at compile-time.  The default is M-bM-^@M-^\noM-bM-^@M-^].
-+
-      StrictModes
-              Specifies whether sshd(8) should check file modes and ownership
-              of the user's files and home directory before accepting login.
-diff -up openssh-6.1p1/sshd_config.5.vendor openssh-6.1p1/sshd_config.5
---- openssh-6.1p1/sshd_config.5.vendor 2012-09-14 20:36:49.512087794 +0200
-+++ openssh-6.1p1/sshd_config.5        2012-09-14 20:36:49.568088198 +0200
-@@ -978,6 +978,14 @@ This option applies to protocol version
- .It Cm ServerKeyBits
- Defines the number of bits in the ephemeral protocol version 1 server key.
- The minimum value is 512, and the default is 1024.
-+.It Cm ShowPatchLevel 
-+Specifies whether 
-+.Nm sshd 
-+will display the patch level of the binary in the identification string. 
-+The patch level is set at compile-time. 
-+The default is 
-+.Dq no . 
-+This option applies to protocol version 1 only. 
- .It Cm StrictModes
- Specifies whether
- .Xr sshd 8
-diff -up openssh-6.1p1/sshd.c.vendor openssh-6.1p1/sshd.c
---- openssh-6.1p1/sshd.c.vendor        2012-09-14 20:36:49.399086981 +0200
-+++ openssh-6.1p1/sshd.c       2012-09-14 20:47:30.696088744 +0200
-@@ -433,7 +433,7 @@ sshd_exchange_identification(int sock_in
-       }
-       xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s",
--          major, minor, SSH_VERSION,
-+          major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
-           *options.version_addendum == '\0' ? "" : " ",
-           options.version_addendum, newline);
-@@ -1635,7 +1635,8 @@ main(int ac, char **av)
-               exit(1);
-       }
--      debug("sshd version %.100s", SSH_RELEASE);
-+      debug("sshd version %.100s",
-+            (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_RELEASE);
-       /* Store privilege separation user for later use if required. */
-       if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
similarity index 54%
rename from openssh/patches/openssh-5.8p1-keyperm.patch
rename to openssh/patches/openssh-6.6p1-keyperm.patch
index 6167c149da50b0d04be30961082b4d582d1cd03d..fbe33b0e12c0becb4b482d261c37ca03235f6a07 100644 (file)
@@ -1,15 +1,16 @@
-diff -up openssh-5.8p1/authfile.c.keyperm openssh-5.8p1/authfile.c
---- openssh-5.8p1/authfile.c.keyperm   2010-12-01 02:03:39.000000000 +0100
-+++ openssh-5.8p1/authfile.c   2011-04-21 16:43:36.859648916 +0200
-@@ -57,6 +57,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-+#include <grp.h>
+diff --git a/authfile.c b/authfile.c
+index e93d867..4fc5b3d 100644
+--- a/authfile.c
++++ b/authfile.c
+@@ -32,6 +32,7 @@
  
- #include "xmalloc.h"
- #include "cipher.h"
-@@ -600,6 +612,13 @@ key_perm_ok(int fd, const char *filename
+ #include <errno.h>
+ #include <fcntl.h>
++#include <grp.h>
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+@@ -207,6 +208,13 @@ sshkey_perm_ok(int fd, const char *filename)
  #ifdef HAVE_CYGWIN
        if (check_ntsec(filename))
  #endif
diff --git a/openssh/patches/openssh-6.7p1-audit.patch b/openssh/patches/openssh-6.7p1-audit.patch
new file mode 100644 (file)
index 0000000..213ca67
--- /dev/null
@@ -0,0 +1,2332 @@
+diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in
+--- openssh-6.8p1/Makefile.in.audit    2015-03-20 13:41:15.065883826 +0100
++++ openssh-6.8p1/Makefile.in  2015-03-20 13:41:15.100883769 +0100
+@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
+       sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
+       kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
+       kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
+-      kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o
++      kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o
+ SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
+       sshconnect.o sshconnect1.o sshconnect2.o mux.o \
+diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c
+--- openssh-6.8p1/audit-bsm.c.audit    2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/audit-bsm.c  2015-03-20 13:41:15.092883782 +0100
+@@ -375,10 +375,23 @@ audit_connection_from(const char *host,
+ #endif
+ }
+-void
++int
+ audit_run_command(const char *command)
+ {
+       /* not implemented */
++      return 0;
++}
++
++void
++audit_end_command(int handle, const char *command)
++{
++      /* not implemented */
++}
++
++void
++audit_count_session_open(void)
++{
++      /* not necessary */
+ }
+ void
+@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li)
+       /* not implemented */
+ }
++int
++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
++{
++      /* not implemented */
++}
++
+ void
+ audit_event(ssh_audit_event_t event)
+ {
+@@ -454,4 +473,40 @@ audit_event(ssh_audit_event_t event)
+               debug("%s: unhandled event %d", __func__, event);
+       }
+ }
++
++void
++audit_unsupported_body(int what)
++{
++      /* not implemented */
++}
++
++void
++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid)
++{
++      /* not implemented */
++}
++
++void
++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++      /* not implemented */
++}
++
++void
++audit_destroy_sensitive_data(const char *fp)
++{
++      /* not implemented */
++}
++
++void
++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++      /* not implemented */
++}
++
++void
++audit_generate_ephemeral_server_key(const char *fp)
++{
++      /* not implemented */
++}
+ #endif /* BSM */
+diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c
+--- openssh-6.8p1/audit-linux.c.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/audit-linux.c        2015-03-20 13:41:15.093883780 +0100
+@@ -35,13 +35,25 @@
+ #include "log.h"
+ #include "audit.h"
++#include "key.h"
++#include "hostfile.h"
++#include "auth.h"
++#include "misc.h"      /* servconf.h needs misc.h for struct ForwardOptions */
++#include "servconf.h"
+ #include "canohost.h"
++#include "packet.h"
++#include "cipher.h"
++#define AUDIT_LOG_SIZE 256
++
++extern ServerOptions options;
++extern Authctxt *the_authctxt;
++extern u_int utmp_len;
+ const char* audit_username(void);
+-int
+-linux_audit_record_event(int uid, const char *username,
+-    const char *hostname, const char *ip, const char *ttyn, int success)
++static void
++linux_audit_user_logxxx(int uid, const char *username,
++    const char *hostname, const char *ip, const char *ttyn, int success, int event)
+ {
+       int audit_fd, rc, saved_errno;
+@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char *username,
+       if (audit_fd < 0) {
+               if (errno == EINVAL || errno == EPROTONOSUPPORT ||
+                   errno == EAFNOSUPPORT)
+-                      return 1; /* No audit support in kernel */
++                      return; /* No audit support in kernel */
+               else
+-                      return 0; /* Must prevent login */
++                      goto fatal_report; /* Must prevent login */
+       }
+-      rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
++      rc = audit_log_acct_message(audit_fd, event,
+           NULL, "login", username ? username : "(unknown)",
+           username == NULL ? uid : -1, hostname, ip, ttyn, success);
+       saved_errno = errno;
+@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char *username,
+       if ((rc == -EPERM) && (geteuid() != 0))
+               rc = 0;
+       errno = saved_errno;
+-      return (rc >= 0);
++      if (rc < 0) {
++fatal_report:
++              fatal("linux_audit_write_entry failed: %s", strerror(errno));
++      }
+ }
++static void
++linux_audit_user_auth(int uid, const char *username,
++    const char *hostname, const char *ip, const char *ttyn, int success, int event)
++{
++      int audit_fd, rc, saved_errno;
++      static const char *event_name[] = {
++              "maxtries exceeded",
++              "root denied",
++              "success",
++              "none",
++              "password",
++              "challenge-response",
++              "pubkey",
++              "hostbased",
++              "gssapi",
++              "invalid user",
++              "nologin",
++              "connection closed",
++              "connection abandoned",
++              "unknown"
++      };
++
++      audit_fd = audit_open();
++      if (audit_fd < 0) {
++              if (errno == EINVAL || errno == EPROTONOSUPPORT ||
++                  errno == EAFNOSUPPORT)
++                      return; /* No audit support in kernel */
++              else
++                      goto fatal_report; /* Must prevent login */
++      }
++      
++      if ((event < 0) || (event > SSH_AUDIT_UNKNOWN))
++              event = SSH_AUDIT_UNKNOWN;
++
++      rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH,
++          NULL, event_name[event], username ? username : "(unknown)",
++          username == NULL ? uid : -1, hostname, ip, ttyn, success);
++      saved_errno = errno;
++      close(audit_fd);
++      /*
++       * Do not report error if the error is EPERM and sshd is run as non
++       * root user.
++       */
++      if ((rc == -EPERM) && (geteuid() != 0))
++              rc = 0;
++      errno = saved_errno;
++      if (rc < 0) {
++fatal_report:
++              fatal("linux_audit_write_entry failed: %s", strerror(errno));
++      }
++}
++
++int
++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
++{
++      char buf[AUDIT_LOG_SIZE];
++      int audit_fd, rc, saved_errno;
++
++      audit_fd = audit_open();
++      if (audit_fd < 0) {
++              if (errno == EINVAL || errno == EPROTONOSUPPORT ||
++                                       errno == EAFNOSUPPORT)
++                      return 1; /* No audit support in kernel */
++              else                                                                                                                                       
++                      return 0; /* Must prevent login */
++      }
++      snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port());
++      rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
++              buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
++      if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
++              goto out;
++      /* is the fingerprint_prefix() still needed? 
++      snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d",
++                      type, bits, sshkey_fingerprint_prefix(), fp, get_remote_port());
++      */
++      snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d",
++                      type, bits, fp, get_remote_port());
++      rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
++              buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
++out:
++      saved_errno = errno;
++      audit_close(audit_fd);
++      errno = saved_errno;
++      /* do not report error if the error is EPERM and sshd is run as non root user */
++      return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0));
++}
++
++static int user_login_count = 0;
++
+ /* Below is the sshd audit API code */
+ void
+ audit_connection_from(const char *host, int port)
+ {
+-}
+       /* not implemented */
++}
+-void
++int
+ audit_run_command(const char *command)
+ {
+-      /* not implemented */
++      if (!user_login_count++) 
++              linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
++                  NULL, "ssh", 1, AUDIT_USER_LOGIN);
++      linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
++          NULL, "ssh", 1, AUDIT_USER_START);
++      return 0;
++}
++
++void
++audit_end_command(int handle, const char *command)
++{
++      linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
++          NULL, "ssh", 1, AUDIT_USER_END);
++      if (user_login_count && !--user_login_count) 
++              linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
++                  NULL, "ssh", 1, AUDIT_USER_LOGOUT);
++}
++
++void
++audit_count_session_open(void)
++{
++      user_login_count++;
+ }
+ void
+ audit_session_open(struct logininfo *li)
+ {
+-      if (linux_audit_record_event(li->uid, NULL, li->hostname,
+-          NULL, li->line, 1) == 0)
+-              fatal("linux_audit_write_entry failed: %s", strerror(errno));
++      if (!user_login_count++) 
++              linux_audit_user_logxxx(li->uid, NULL, li->hostname,
++                  NULL, li->line, 1, AUDIT_USER_LOGIN);
++      linux_audit_user_logxxx(li->uid, NULL, li->hostname,
++          NULL, li->line, 1, AUDIT_USER_START);
+ }
+ void
+ audit_session_close(struct logininfo *li)
+ {
+-      /* not implemented */
++      linux_audit_user_logxxx(li->uid, NULL, li->hostname,
++          NULL, li->line, 1, AUDIT_USER_END);
++      if (user_login_count && !--user_login_count) 
++              linux_audit_user_logxxx(li->uid, NULL, li->hostname,
++                  NULL, li->line, 1, AUDIT_USER_LOGOUT);
+ }
+ void
+@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event)
+ {
+       switch(event) {
+       case SSH_AUTH_SUCCESS:
+-      case SSH_CONNECTION_CLOSE:
++              linux_audit_user_auth(-1, audit_username(), NULL,
++                      get_remote_ipaddr(), "ssh", 1, event);
++              break;
++
+       case SSH_NOLOGIN:
+-      case SSH_LOGIN_EXCEED_MAXTRIES:
+       case SSH_LOGIN_ROOT_DENIED:
++              linux_audit_user_auth(-1, audit_username(), NULL,
++                      get_remote_ipaddr(), "ssh", 0, event);
++              linux_audit_user_logxxx(-1, audit_username(), NULL,
++                      get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
+               break;
++      case SSH_LOGIN_EXCEED_MAXTRIES:
+       case SSH_AUTH_FAIL_NONE:
+       case SSH_AUTH_FAIL_PASSWD:
+       case SSH_AUTH_FAIL_KBDINT:
+       case SSH_AUTH_FAIL_PUBKEY:
+       case SSH_AUTH_FAIL_HOSTBASED:
+       case SSH_AUTH_FAIL_GSSAPI:
++              linux_audit_user_auth(-1, audit_username(), NULL,
++                      get_remote_ipaddr(), "ssh", 0, event);
++              break;
++
++      case SSH_CONNECTION_CLOSE:
++              if (user_login_count) {
++                      while (user_login_count--)
++                              linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
++                                  NULL, "ssh", 1, AUDIT_USER_END);
++                      linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
++                          NULL, "ssh", 1, AUDIT_USER_LOGOUT);
++              }
++              break;
++
++      case SSH_CONNECTION_ABANDON:
+       case SSH_INVALID_USER:
+-              linux_audit_record_event(-1, audit_username(), NULL,
+-                      get_remote_ipaddr(), "sshd", 0);
++              linux_audit_user_logxxx(-1, audit_username(), NULL,
++                      get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
+               break;
+       default:
+@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event)
+       }
+ }
++void
++audit_unsupported_body(int what)
++{
++#ifdef AUDIT_CRYPTO_SESSION
++      char buf[AUDIT_LOG_SIZE];
++      const static char *name[] = { "cipher", "mac", "comp" };
++      char *s;
++      int audit_fd;
++
++      snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ",
++              name[what], get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())),
++              get_local_port());
++      free(s);
++      audit_fd = audit_open();
++      if (audit_fd < 0)
++              /* no problem, the next instruction will be fatal() */
++              return;
++      audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
++                      buf, NULL, get_remote_ipaddr(), NULL, 0);
++      audit_close(audit_fd);
++#endif
++}
++
++const static char *direction[] = { "from-server", "from-client", "both" };
++
++void
++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid,
++             uid_t uid)
++{
++#ifdef AUDIT_CRYPTO_SESSION
++      char buf[AUDIT_LOG_SIZE];
++      int audit_fd, audit_ok;
++      const Cipher *cipher = cipher_by_name(enc);
++      char *s;
++
++      snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
++              direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs,
++              (intmax_t)pid, (intmax_t)uid,
++              get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port());
++      free(s);
++      audit_fd = audit_open();
++      if (audit_fd < 0) {
++              if (errno == EINVAL || errno == EPROTONOSUPPORT ||
++                                       errno == EAFNOSUPPORT)
++                      return; /* No audit support in kernel */
++              else                                                                                                                                       
++                      fatal("cannot open audit"); /* Must prevent login */
++      }
++      audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
++                      buf, NULL, get_remote_ipaddr(), NULL, 1);
++      audit_close(audit_fd);
++      /* do not abort if the error is EPERM and sshd is run as non root user */
++      if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
++              fatal("cannot write into audit"); /* Must prevent login */
++#endif
++}
++
++void
++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++      char buf[AUDIT_LOG_SIZE];
++      int audit_fd, audit_ok;
++      char *s;
++
++      snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
++               direction[ctos], (intmax_t)pid, (intmax_t)uid,
++               get_remote_port(),
++               (s = get_local_ipaddr(packet_get_connection_in())),
++               get_local_port());
++      free(s);
++      audit_fd = audit_open();
++      if (audit_fd < 0) {
++              if (errno != EINVAL && errno != EPROTONOSUPPORT &&
++                                       errno != EAFNOSUPPORT)
++                      error("cannot open audit");
++              return;
++      }
++      audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
++                      buf, NULL, get_remote_ipaddr(), NULL, 1);
++      audit_close(audit_fd);
++      /* do not abort if the error is EPERM and sshd is run as non root user */
++      if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
++              error("cannot write into audit");
++}
++
++void
++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++      char buf[AUDIT_LOG_SIZE];
++      int audit_fd, audit_ok;
++
++      snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ",
++              fp, (intmax_t)pid, (intmax_t)uid);
++      audit_fd = audit_open();
++      if (audit_fd < 0) {
++              if (errno != EINVAL && errno != EPROTONOSUPPORT &&
++                                       errno != EAFNOSUPPORT)
++                      error("cannot open audit");
++              return;
++      }
++      audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
++                      buf, NULL,
++                      listening_for_clients() ? get_remote_ipaddr() : NULL,
++                      NULL, 1);
++      audit_close(audit_fd);
++      /* do not abort if the error is EPERM and sshd is run as non root user */
++      if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
++              error("cannot write into audit");
++}
++
++void
++audit_generate_ephemeral_server_key(const char *fp)
++{
++      char buf[AUDIT_LOG_SIZE];
++      int audit_fd, audit_ok;
++
++      snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp);
++      audit_fd = audit_open();
++      if (audit_fd < 0) {
++              if (errno != EINVAL && errno != EPROTONOSUPPORT &&
++                                       errno != EAFNOSUPPORT)
++                      error("cannot open audit");
++              return;
++      }
++      audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
++                      buf, NULL, 0, NULL, 1);
++      audit_close(audit_fd);
++      /* do not abort if the error is EPERM and sshd is run as non root user */
++      if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
++              error("cannot write into audit");
++}
+ #endif /* USE_LINUX_AUDIT */
+diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c
+--- openssh-6.8p1/audit.c.audit        2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/audit.c      2015-03-20 13:41:15.093883780 +0100
+@@ -28,6 +28,7 @@
+ #include <stdarg.h>
+ #include <string.h>
++#include <unistd.h>
+ #ifdef SSH_AUDIT_EVENTS
+@@ -36,6 +37,11 @@
+ #include "key.h"
+ #include "hostfile.h"
+ #include "auth.h"
++#include "ssh-gss.h"
++#include "monitor_wrap.h"
++#include "xmalloc.h"
++#include "misc.h"
++#include "servconf.h"
+ /*
+  * Care must be taken when using this since it WILL NOT be initialized when
+@@ -43,6 +49,7 @@
+  * audit_event(CONNECTION_ABANDON) is called.  Test for NULL before using.
+  */
+ extern Authctxt *the_authctxt;
++extern ServerOptions options;
+ /* Maybe add the audit class to struct Authmethod? */
+ ssh_audit_event_t
+@@ -71,13 +78,10 @@ audit_classify_auth(const char *method)
+ const char *
+ audit_username(void)
+ {
+-      static const char unknownuser[] = "(unknown user)";
+-      static const char invaliduser[] = "(invalid user)";
++      static const char unknownuser[] = "(unknown)";
+-      if (the_authctxt == NULL || the_authctxt->user == NULL)
++      if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid)
+               return (unknownuser);
+-      if (!the_authctxt->valid)
+-              return (invaliduser);
+       return (the_authctxt->user);
+ }
+@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev)
+       return(event_lookup[i].name);
+ }
++void
++audit_key(int host_user, int *rv, const Key *key)
++{
++      char *fp;
++      const char *crypto_name;
++
++      fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
++      if (key->type == KEY_RSA1)
++              crypto_name = "ssh-rsa1";
++      else
++              crypto_name = key_ssh_name(key);
++      if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
++              *rv = 0;
++      free(fp);
++}
++
++void
++audit_unsupported(int what)
++{
++      PRIVSEP(audit_unsupported_body(what));
++}
++
++void
++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs)
++{
++      PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid()));
++}
++
++void
++audit_session_key_free(int ctos)
++{
++      PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid()));
++}
++
+ # ifndef CUSTOM_SSH_AUDIT_EVENTS
+ /*
+  * Null implementations of audit functions.
+@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event)
+ }
+ /*
++ * Called when a child process has called, or will soon call,
++ * audit_session_open.
++ */
++void
++audit_count_session_open(void)
++{
++      debug("audit count session open euid %d user %s", geteuid(),
++            audit_username());
++}
++
++/*
+  * Called when a user session is started.  Argument is the tty allocated to
+  * the session, or NULL if no tty was allocated.
+  *
+@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li)
+ /*
+  * This will be called when a user runs a non-interactive command.  Note that
+  * it may be called multiple times for a single connection since SSH2 allows
+- * multiple sessions within a single connection.
++ * multiple sessions within a single connection.  Returns a "handle" for
++ * audit_end_command.
+  */
+-void
++int
+ audit_run_command(const char *command)
+ {
+       debug("audit run command euid %d user %s command '%.200s'", geteuid(),
+           audit_username(), command);
++      return 0;
++}
++
++/*
++ * This will be called when the non-interactive command finishes.  Note that
++ * it may be called multiple times for a single connection since SSH2 allows
++ * multiple sessions within a single connection.  "handle" should come from
++ * the corresponding audit_run_command.
++ */
++void
++audit_end_command(int handle, const char *command)
++{
++      debug("audit end nopty exec  euid %d user %s command '%.200s'", geteuid(),
++          audit_username(), command);
++}
++
++/*
++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key.
++ *
++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key.
++ */
++int
++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
++{
++      debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", 
++              host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
++              sshkey_fingerprint_prefix(), fp, rv);
++}
++
++/*
++ * This will be called when the protocol negotiation fails.
++ */
++void
++audit_unsupported_body(int what)
++{
++      debug("audit unsupported protocol euid %d type %d", geteuid(), what);
++}
++
++/*
++ * This will be called on succesfull protocol negotiation.
++ */
++void
++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid,
++             uid_t uid)
++{
++      debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u",
++              (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid,
++              (unsigned)uid);
++}
++
++/*
++ * This will be called on succesfull session key discard
++ */
++void
++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++      debug("audit session key discard euid %u direction %d from pid %ld uid %u",
++              (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
++}
++
++/*
++ * This will be called on destroy private part of the server key
++ */
++void
++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++      debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
++              geteuid(), fp, (long)pid, (unsigned)uid);
++}
++
++/*
++ * This will be called on generation of the ephemeral server key
++ */
++void
++audit_generate_ephemeral_server_key(const char *)
++{
++      debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
+ }
+ # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
+ #endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h
+--- openssh-6.8p1/audit.h.audit        2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/audit.h      2015-03-20 13:41:15.093883780 +0100
+@@ -28,6 +28,7 @@
+ # define _SSH_AUDIT_H
+ #include "loginrec.h"
++#include "key.h"
+ enum ssh_audit_event_type {
+       SSH_LOGIN_EXCEED_MAXTRIES,
+@@ -47,11 +48,25 @@ enum ssh_audit_event_type {
+ };
+ typedef enum ssh_audit_event_type ssh_audit_event_t;
++int   listening_for_clients(void);
++
+ void  audit_connection_from(const char *, int);
+ void  audit_event(ssh_audit_event_t);
++void  audit_count_session_open(void);
+ void  audit_session_open(struct logininfo *);
+ void  audit_session_close(struct logininfo *);
+-void  audit_run_command(const char *);
++int   audit_run_command(const char *);
++void  audit_end_command(int, const char *);
+ ssh_audit_event_t audit_classify_auth(const char *);
++int   audit_keyusage(int, const char *, unsigned, char *, int);
++void  audit_key(int, int *, const Key *);
++void  audit_unsupported(int);
++void  audit_kex(int, char *, char *, char *, char *);
++void  audit_unsupported_body(int);
++void  audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
++void  audit_session_key_free(int ctos);
++void  audit_session_key_free_body(int ctos, pid_t, uid_t);
++void  audit_destroy_sensitive_data(const char *, pid_t, uid_t);
++void  audit_generate_ephemeral_server_key(const char *);
+ #endif /* _SSH_AUDIT_H */
+diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c
+--- openssh-6.8p1/auditstub.c.audit    2015-03-20 13:41:15.093883780 +0100
++++ openssh-6.8p1/auditstub.c  2015-03-20 13:41:15.093883780 +0100
+@@ -0,0 +1,50 @@
++/* $Id: auditstub.c,v 1.1 jfch Exp $ */
++
++/*
++ * Copyright 2010 Red Hat, Inc.  All rights reserved.
++ * Use is subject to license terms.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Red Hat author: Jan F. Chadima <jchadima@redhat.com>
++ */
++
++#include <sys/types.h>
++
++void
++audit_unsupported(int n)
++{
++}
++
++void
++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs)
++{
++}
++
++void
++audit_session_key_free(int ctos)
++{
++}
++
++void
++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++}
+diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c
+--- openssh-6.8p1/auth-rsa.c.audit     2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/auth-rsa.c   2015-03-20 13:41:15.094883779 +0100
+@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
+ {
+       u_char buf[32], mdbuf[16];
+       struct ssh_digest_ctx *md;
+-      int len;
++      int len, rv;
++#ifdef SSH_AUDIT_EVENTS
++      char *fp;
++#endif
+       /* don't allow short keys */
+       if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
+       ssh_digest_free(md);
+       /* Verify that the response is the original challenge. */
+-      if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
+-              /* Wrong answer. */
+-              return (0);
++      rv = timingsafe_bcmp(response, mdbuf, 16) == 0;
++
++#ifdef SSH_AUDIT_EVENTS
++      fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
++      if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) {
++              debug("unsuccessful audit");
++              rv = 0;
+       }
+-      /* Correct answer. */
+-      return (1);
++      free(fp);
++#endif
++
++      return rv;
+ }
+ /*
+diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c
+--- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/auth.c       2015-03-20 13:41:15.094883779 +0100
+@@ -644,9 +644,6 @@ getpwnamallow(const char *user)
+               record_failed_login(user,
+                   get_canonical_hostname(options.use_dns), "ssh");
+ #endif
+-#ifdef SSH_AUDIT_EVENTS
+-              audit_event(SSH_INVALID_USER);
+-#endif /* SSH_AUDIT_EVENTS */
+               return (NULL);
+       }
+       if (!allowed_user(pw))
+diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h
+--- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100
++++ openssh-6.8p1/auth.h       2015-03-20 13:41:15.094883779 +0100
+@@ -195,6 +195,7 @@ void       abandon_challenge_response(Authctxt
+ char  *expand_authorized_keys(const char *, struct passwd *pw);
+ char  *authorized_principals_file(struct passwd *);
++int    user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
+ FILE  *auth_openkeyfile(const char *, struct passwd *, int);
+ FILE  *auth_openprincipals(const char *, struct passwd *, int);
+@@ -213,6 +214,7 @@ int         get_hostkey_index(Key *, int, struc
+ int    ssh1_session_key(BIGNUM *);
+ int    sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
+            const u_char *, size_t, u_int);
++int    hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
+ /* debug messages during authentication */
+ void   auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
+diff -up openssh-6.8p1/auth2-hostbased.c.audit openssh-6.8p1/auth2-hostbased.c
+--- openssh-6.8p1/auth2-hostbased.c.audit      2015-03-20 13:41:15.002883927 +0100
++++ openssh-6.8p1/auth2-hostbased.c    2015-03-20 13:41:15.093883780 +0100
+@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt)
+       /* test for allowed key and correct signature */
+       authenticated = 0;
+       if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
+-          PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
++          PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b),
+                       buffer_len(&b))) == 1)
+               authenticated = 1;
+@@ -164,6 +164,18 @@ done:
+       return authenticated;
+ }
++int
++hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
++{
++      int rv;
++
++      rv = key_verify(key, sig, slen, data, datalen);
++#ifdef SSH_AUDIT_EVENTS
++      audit_key(0, &rv, key);
++#endif
++      return rv;
++}
++
+ /* return 1 if given hostkey is allowed */
+ int
+ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
+diff -up openssh-6.8p1/auth2-pubkey.c.audit openssh-6.8p1/auth2-pubkey.c
+--- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 13:41:15.013883910 +0100
++++ openssh-6.8p1/auth2-pubkey.c       2015-03-20 13:41:15.094883779 +0100
+@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt)
+               /* test for correct signature */
+               authenticated = 0;
+               if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
+-                  PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
++                  PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b),
+                   buffer_len(&b))) == 1) {
+                       authenticated = 1;
+                       /* Record the successful key to prevent reuse */
+@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con
+       free(extra);
+ }
++int
++user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
++{
++      int rv;
++
++      rv = key_verify(key, sig, slen, data, datalen);
++#ifdef SSH_AUDIT_EVENTS
++      audit_key(1, &rv, key);
++#endif
++      return rv;
++}
++
+ static int
+ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
+ {
+diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c
+--- openssh-6.8p1/auth2.c.audit        2015-03-20 13:41:15.044883860 +0100
++++ openssh-6.8p1/auth2.c      2015-03-20 13:41:15.093883780 +0100
+@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32
+               } else {
+                       logit("input_userauth_request: invalid user %s", user);
+                       authctxt->pw = fakepw();
+-#ifdef SSH_AUDIT_EVENTS
+-                      PRIVSEP(audit_event(SSH_INVALID_USER));
+-#endif
+               }
+ #ifdef USE_PAM
+               if (options.use_pam)
+diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c
+--- openssh-6.8p1/cipher.c.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/cipher.c     2015-03-20 13:41:15.101883767 +0100
+@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v
+ extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+ #endif
+-struct sshcipher {
+-      char    *name;
+-      int     number;         /* for ssh1 only */
+-      u_int   block_size;
+-      u_int   key_len;
+-      u_int   iv_len;         /* defaults to block_size */
+-      u_int   auth_len;
+-      u_int   discard_len;
+-      u_int   flags;
+-#define CFLAG_CBC             (1<<0)
+-#define CFLAG_CHACHAPOLY      (1<<1)
+-#define CFLAG_AESCTR          (1<<2)
+-#define CFLAG_NONE            (1<<3)
+-#ifdef WITH_OPENSSL
+-      const EVP_CIPHER        *(*evptype)(void);
+-#else
+-      void    *ignored;
+-#endif
+-};
+-
+ static const struct sshcipher ciphers[] = {
+ #ifdef WITH_SSH1
+       { "des",        SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
+diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h
+--- openssh-6.8p1/cipher.h.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/cipher.h     2015-03-20 13:41:15.094883779 +0100
+@@ -62,7 +62,26 @@
+ #define CIPHER_ENCRYPT                1
+ #define CIPHER_DECRYPT                0
+-struct sshcipher;
++struct sshcipher {
++      char    *name;
++      int     number;         /* for ssh1 only */
++      u_int   block_size;
++      u_int   key_len;
++      u_int   iv_len;         /* defaults to block_size */
++      u_int   auth_len;
++      u_int   discard_len;
++      u_int   flags;
++#define CFLAG_CBC             (1<<0)
++#define CFLAG_CHACHAPOLY      (1<<1)
++#define CFLAG_AESCTR          (1<<2)
++#define CFLAG_NONE            (1<<3)
++#ifdef WITH_OPENSSL
++      const EVP_CIPHER        *(*evptype)(void);
++#else
++      void    *ignored;
++#endif
++};
++
+ struct sshcipher_ctx {
+       int     plaintext;
+       int     encrypt;
+diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c
+--- openssh-6.8p1/kex.c.audit  2015-03-20 13:41:15.046883856 +0100
++++ openssh-6.8p1/kex.c        2015-03-20 13:41:15.101883767 +0100
+@@ -54,6 +55,7 @@
+ #include "ssherr.h"
+ #include "sshbuf.h"
+ #include "digest.h"
++#include "audit.h"
+ #ifdef GSSAPI
+ #include "ssh-gss.h"
+@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli
+ {
+       char *name = match_list(client, server, NULL);
+-      if (name == NULL)
++      if (name == NULL) {
++#ifdef SSH_AUDIT_EVENTS
++              audit_unsupported(0);
++#endif
+               return SSH_ERR_NO_CIPHER_ALG_MATCH;
++      }
+       if ((enc->cipher = cipher_by_name(name)) == NULL)
+               return SSH_ERR_INTERNAL_ERROR;
+       enc->name = name;
+@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma
+ {
+       char *name = match_list(client, server, NULL);
+-      if (name == NULL)
++      if (name == NULL) {
++#ifdef SSH_AUDIT_EVENTS
++              audit_unsupported(1);
++#endif
+               return SSH_ERR_NO_MAC_ALG_MATCH;
++      }
+       if (mac_setup(mac, name) < 0)
+               return SSH_ERR_INTERNAL_ERROR;
+       /* truncate the key */
+@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char *
+ {
+       char *name = match_list(client, server, NULL);
+-      if (name == NULL)
++      if (name == NULL) {
++#ifdef SSH_AUDIT_EVENTS
++              audit_unsupported(2);
++#endif
+               return SSH_ERR_NO_COMPRESS_ALG_MATCH;
++      }
+       if (strcmp(name, "zlib@openssh.com") == 0) {
+               comp->type = COMP_DELAYED;
+       } else if (strcmp(name, "zlib") == 0) {
+@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh)
+               dh_need = MAX(dh_need, newkeys->enc.block_size);
+               dh_need = MAX(dh_need, newkeys->enc.iv_len);
+               dh_need = MAX(dh_need, newkeys->mac.key_len);
++              debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need);
++#ifdef SSH_AUDIT_EVENTS
++              audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name);
++#endif
+       }
+       /* XXX need runden? */
+       kex->we_need = need;
+@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i
+       sshbuf_dump_data(digest, len, stderr);
+ }
+ #endif
++
++static void
++enc_destroy(struct sshenc *enc)
++{
++      if (enc == NULL)
++              return;
++
++      if (enc->key) {
++              memset(enc->key, 0, enc->key_len);
++              free(enc->key);
++      }
++
++      if (enc->iv) {
++              memset(enc->iv,  0, enc->block_size);
++              free(enc->iv);
++      }
++
++      memset(enc, 0, sizeof(*enc));
++}
++
++void
++newkeys_destroy(struct newkeys *newkeys)
++{
++      if (newkeys == NULL)
++              return;
++
++      enc_destroy(&newkeys->enc);
++      mac_destroy(&newkeys->mac);
++      memset(&newkeys->comp, 0, sizeof(newkeys->comp));
++}
++
+diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h
+--- openssh-6.8p1/kex.h.audit  2015-03-20 13:41:15.046883856 +0100
++++ openssh-6.8p1/kex.h        2015-03-20 13:41:15.095883777 +0100
+@@ -199,6 +199,8 @@ int         kexgss_client(struct ssh *);
+ int    kexgss_server(struct ssh *);
+ #endif
++void  newkeys_destroy(struct newkeys *newkeys);
++
+ int    kex_dh_hash(const char *, const char *,
+     const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
+     const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);
+diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h
+--- openssh-6.8p1/key.h.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/key.h        2015-03-20 13:41:15.095883777 +0100
+@@ -50,6 +50,7 @@ typedef struct sshkey Key;
+ #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid
+ #define key_ecdsa_key_to_nid  sshkey_ecdsa_key_to_nid
+ #define key_is_cert           sshkey_is_cert
++#define key_is_private                sshkey_is_private
+ #define key_type_plain                sshkey_type_plain
+ #define key_cert_is_legacy    sshkey_cert_is_legacy
+ #define key_curve_name_to_nid sshkey_curve_name_to_nid
+diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c
+--- openssh-6.8p1/mac.c.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/mac.c        2015-03-20 13:41:15.102883766 +0100
+@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac)
+       mac->umac_ctx = NULL;
+ }
++void
++mac_destroy(struct sshmac *mac)
++{
++      if (mac == NULL)
++              return;
++
++      if (mac->key) {
++              memset(mac->key, 0, mac->key_len);
++              free(mac->key);
++      }
++
++      memset(mac, 0, sizeof(*mac));
++}
++
+ /* XXX copied from ciphers_valid */
+ #define       MAC_SEP ","
+ int
+diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h
+--- openssh-6.8p1/mac.h.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/mac.h        2015-03-20 13:41:15.095883777 +0100
+@@ -47,5 +47,6 @@ int   mac_init(struct sshmac *);
+ int    mac_compute(struct sshmac *, u_int32_t, const u_char *, int,
+     u_char *, size_t);
+ void   mac_clear(struct sshmac *);
++void   mac_destroy(struct sshmac *);
+ #endif /* SSHMAC_H */
+diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c
+--- openssh-6.8p1/monitor.c.audit      2015-03-20 13:41:15.072883814 +0100
++++ openssh-6.8p1/monitor.c    2015-03-20 13:41:15.107883758 +0100
+@@ -102,6 +102,7 @@
+ #include "ssh2.h"
+ #include "roaming.h"
+ #include "authfd.h"
++#include "audit.h"
+ #include "match.h"
+ #include "ssherr.h"
+@@ -117,6 +118,8 @@ extern Buffer auth_debug;
+ extern int auth_debug_init;
+ extern Buffer loginmsg;
++extern void destroy_sensitive_data(int);
++
+ /* State exported from the child */
+ static struct sshbuf *child_state;
+@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe
+ #ifdef SSH_AUDIT_EVENTS
+ int mm_answer_audit_event(int, Buffer *);
+ int mm_answer_audit_command(int, Buffer *);
++int mm_answer_audit_end_command(int, Buffer *);
++int mm_answer_audit_unsupported_body(int, Buffer *);
++int mm_answer_audit_kex_body(int, Buffer *);
++int mm_answer_audit_session_key_free_body(int, Buffer *);
++int mm_answer_audit_server_key_free(int, Buffer *);
+ #endif
+ static int monitor_read_log(struct monitor *);
+@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[]
+ #endif
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+ #ifdef BSD_AUTH
+     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
+@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+     {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
++    {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+     {0, 0, NULL}
+ };
+@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[]
+ #endif
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+ #endif /* WITH_SSH1 */
+     {0, 0, NULL}
+@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+     {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
++    {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+ #endif /* WITH_SSH1 */
+     {0, 0, NULL}
+@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m)
+       Key *key;
+       u_char *signature, *data, *blob;
+       u_int signaturelen, datalen, bloblen;
++      int type = 0;
+       int verified = 0;
+       int valid_data = 0;
++      type = buffer_get_int(m);
+       blob = buffer_get_string(m, &bloblen);
+       signature = buffer_get_string(m, &signaturelen);
+       data = buffer_get_string(m, &datalen);
+@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m)
+       if (hostbased_cuser == NULL || hostbased_chost == NULL ||
+         !monitor_allowed_key(blob, bloblen))
+               fatal("%s: bad key, not previously allowed", __func__);
++      if (type != key_blobtype)
++              fatal("%s: bad key type", __func__);
+       key = key_from_blob(blob, bloblen);
+       if (key == NULL)
+@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m)
+       if (!valid_data)
+               fatal("%s: bad signature data blob", __func__);
+-      verified = key_verify(key, signature, signaturelen, data, datalen);
++      switch (key_blobtype) {
++      case MM_USERKEY:
++              verified = user_key_verify(key, signature, signaturelen, data, datalen);
++              break;
++      case MM_HOSTKEY:
++              verified = hostbased_key_verify(key, signature, signaturelen, data, datalen);
++              break;
++      default:
++              verified = 0;
++              break;
++      }
+       debug3("%s: key %p signature %s",
+           __func__, key, (verified == 1) ? "verified" : "unverified");
+@@ -1554,6 +1595,12 @@ mm_session_close(Session *s)
+               debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
+               session_pty_cleanup2(s);
+       }
++#ifdef SSH_AUDIT_EVENTS
++      if (s->command != NULL) {
++              debug3("%s: command %d", __func__, s->command_handle);
++              session_end_command2(s);
++      }
++#endif
+       session_unused(s->self);
+ }
+@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req)
+               sshpam_cleanup();
+ #endif
++      destroy_sensitive_data(0);
++
+       while (waitpid(pmonitor->m_pid, &status, 0) == -1)
+               if (errno != EINTR)
+                       exit(1);
+@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff
+ {
+       u_int len;
+       char *cmd;
++      Session *s;
+       debug3("%s entering", __func__);
+       cmd = buffer_get_string(m, &len);
++
+       /* sanity check command, if so how? */
+-      audit_run_command(cmd);
++      s = session_new();
++      if (s == NULL)
++              fatal("%s: error allocating a session", __func__);
++      s->command = cmd;
++      s->command_handle = audit_run_command(cmd);
++
++      buffer_clear(m);
++      buffer_put_int(m, s->self);
++
++      mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m);
++
++      return (0);
++}
++
++int
++mm_answer_audit_end_command(int socket, Buffer *m)
++{
++      int handle;
++      u_int len;
++      char *cmd;
++      Session *s;
++
++      debug3("%s entering", __func__);
++      handle = buffer_get_int(m);
++      cmd = buffer_get_string(m, &len);
++
++      s = session_by_id(handle);
++      if (s == NULL || s->ttyfd != -1 || s->command == NULL ||
++          strcmp(s->command, cmd) != 0)
++              fatal("%s: invalid handle", __func__);
++      mm_session_close(s);
+       free(cmd);
+       return (0);
+ }
+@@ -1936,6 +2017,7 @@
+ void
+ mm_get_keystate(struct monitor *pmonitor)
+ {
++      Buffer m;
+       debug3("%s: Waiting for new keys", __func__);
+       if ((child_state = sshbuf_new()) == NULL)
+@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor
+       mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
+           child_state);
+       debug3("%s: GOT new keys", __func__);
++
++#ifdef SSH_AUDIT_EVENTS
++      if (compat20) {
++              buffer_init(&m);
++              mm_request_receive_expect(pmonitor->m_sendfd,
++                                        MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
++              mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m);
++              buffer_free(&m);
++      }
++#endif
++
++      /* Drain any buffered messages from the child */
++      while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
++              ;
++
+ }
+@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu
+ #endif /* GSSAPI */
++#ifdef SSH_AUDIT_EVENTS
++int
++mm_answer_audit_unsupported_body(int sock, Buffer *m)
++{
++      int what;
++
++      what = buffer_get_int(m);
++
++      audit_unsupported_body(what);
++
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m);
++      return 0;
++}
++
++int
++mm_answer_audit_kex_body(int sock, Buffer *m)
++{
++      int ctos, len;
++      char *cipher, *mac, *compress, *pfs;
++      pid_t pid;
++      uid_t uid;
++
++      ctos = buffer_get_int(m);
++      cipher = buffer_get_string(m, &len);
++      mac = buffer_get_string(m, &len);
++      compress = buffer_get_string(m, &len);
++      pfs = buffer_get_string(m, &len);
++      pid = buffer_get_int64(m);
++      uid = buffer_get_int64(m);
++
++      audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid);
++
++      free(cipher);
++      free(mac);
++      free(compress);
++      free(pfs);
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m);
++      return 0;
++}
++
++int
++mm_answer_audit_session_key_free_body(int sock, Buffer *m)
++{
++      int ctos;
++      pid_t pid;
++      uid_t uid;
++
++      ctos = buffer_get_int(m);
++      pid = buffer_get_int64(m);
++      uid = buffer_get_int64(m);
++
++      audit_session_key_free_body(ctos, pid, uid);
++
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
++      return 0;
++}
++
++int
++mm_answer_audit_server_key_free(int sock, Buffer *m)
++{
++      int len;
++      char *fp;
++      pid_t pid;
++      uid_t uid;
++
++      fp = buffer_get_string(m, &len);
++      pid = buffer_get_int64(m);
++      uid = buffer_get_int64(m);
++
++      audit_destroy_sensitive_data(fp, pid, uid);
++
++      free(fp);
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m);
++      return 0;
++}
++#endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h
+--- openssh-6.8p1/monitor.h.audit      2015-03-20 13:41:15.072883814 +0100
++++ openssh-6.8p1/monitor.h    2015-03-20 13:41:15.096883775 +0100
+@@ -69,7 +69,13 @@ enum monitor_reqtype {
+       MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
+       MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
+       MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
+-      MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
++      MONITOR_REQ_AUDIT_EVENT = 112,
++      MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = 115,
++      MONITOR_REQ_AUDIT_END_COMMAND = 116,
++      MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119,
++      MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121,
++      MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123,
++      MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125
+ };
+diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c
+--- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 13:41:15.047883855 +0100
++++ openssh-6.8p1/monitor_wrap.c       2015-03-20 13:41:15.108883756 +0100
+@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha
+  */
+ int
+-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
++mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
+ {
+       Buffer m;
+       u_char *blob;
+@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i
+               return (0);
+       buffer_init(&m);
++      buffer_put_int(&m, type);
+       buffer_put_string(&m, blob, len);
+       buffer_put_string(&m, sig, siglen);
+       buffer_put_string(&m, data, datalen);
+@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i
+       return (verified);
+ }
++int
++mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
++{
++      return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen);
++}
++
++int
++mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
++{
++      return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen);
++}
++
+ void
+ mm_send_keystate(struct monitor *monitor)
+ {
+@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event)
+       buffer_free(&m);
+ }
+-void
++int
+ mm_audit_run_command(const char *command)
+ {
+       Buffer m;
++      int handle;
+       debug3("%s entering command %s", __func__, command);
+@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command
+       buffer_put_cstring(&m, command);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m);
++
++      handle = buffer_get_int(&m);
++      buffer_free(&m);
++
++      return (handle);
++}
++
++void
++mm_audit_end_command(int handle, const char *command)
++{
++      Buffer m;
++
++      debug3("%s entering command %s", __func__, command);
++
++      buffer_init(&m);
++      buffer_put_int(&m, handle);
++      buffer_put_cstring(&m, command);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m);
+       buffer_free(&m);
+ }
+ #endif /* SSH_AUDIT_EVENTS */
+@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
+ #endif /* GSSAPI */
++#ifdef SSH_AUDIT_EVENTS
++void
++mm_audit_unsupported_body(int what)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_int(&m, what);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED,
++                                &m);
++
++      buffer_free(&m);
++}
++
++void
++mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid,
++                uid_t uid)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_int(&m, ctos);
++      buffer_put_cstring(&m, cipher);
++      buffer_put_cstring(&m, (mac ? mac : ""));
++      buffer_put_cstring(&m, compress);
++      buffer_put_cstring(&m, fps);
++      buffer_put_int64(&m, pid);
++      buffer_put_int64(&m, uid);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX,
++                                &m);
++
++      buffer_free(&m);
++}
++
++void
++mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_int(&m, ctos);
++      buffer_put_int64(&m, pid);
++      buffer_put_int64(&m, uid);
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE,
++                                &m);
++      buffer_free(&m);
++}
++
++void
++mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_cstring(&m, fp);
++      buffer_put_int64(&m, pid);
++      buffer_put_int64(&m, uid);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE,
++                                &m);
++      buffer_free(&m);
++}
++#endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.8p1/monitor_wrap.h.audit openssh-6.8p1/monitor_wrap.h
+--- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 13:41:15.048883853 +0100
++++ openssh-6.8p1/monitor_wrap.h       2015-03-20 13:41:15.096883775 +0100
+@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char
+ int mm_user_key_allowed(struct passwd *, Key *);
+ int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
+ int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
+-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
++int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int);
++int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int);
+ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
+ int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
+ BIGNUM *mm_auth_rsa_generate_challenge(Key *);
+@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *);
+ #ifdef SSH_AUDIT_EVENTS
+ #include "audit.h"
+ void mm_audit_event(ssh_audit_event_t);
+-void mm_audit_run_command(const char *);
++int mm_audit_run_command(const char *);
++void mm_audit_end_command(int, const char *);
++void mm_audit_unsupported_body(int);
++void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
++void mm_audit_session_key_free_body(int, pid_t, uid_t);
++void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
+ #endif
+ struct Session;
+diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c
+--- openssh-6.8p1/packet.c.audit       2015-03-20 13:41:14.990883947 +0100
++++ openssh-6.8p1/packet.c     2015-03-20 13:41:15.097883774 +0100
+@@ -67,6 +67,7 @@
+ #include "key.h"      /* typedefs XXX */
+ #include "xmalloc.h"
++#include "audit.h"
+ #include "crc32.h"
+ #include "deattack.h"
+ #include "compat.h"
+@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh
+       return ssh->state->connection_out;
+ }
++static int
++packet_state_has_keys (const struct session_state *state)
++{
++      return state != NULL &&
++              (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL);
++}
++
+ /*
+  * Returns the IP-address of the remote host as a string.  The returned
+  * string must not be freed.
+@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh)
+       if (!state->initialized)
+               return;
+       state->initialized = 0;
+-      if (state->connection_in == state->connection_out) {
+-              shutdown(state->connection_out, SHUT_RDWR);
+-              close(state->connection_out);
+-      } else {
+-              close(state->connection_in);
+-              close(state->connection_out);
+-      }
+       sshbuf_free(state->input);
+       sshbuf_free(state->output);
+       sshbuf_free(state->outgoing_packet);
+@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh)
+                               inflateEnd(stream);
+               }
+       }
+-      if ((r = cipher_cleanup(&state->send_context)) != 0)
+-              error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
+-      if ((r = cipher_cleanup(&state->receive_context)) != 0)
+-              error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
++      if (packet_state_has_keys(state)) {
++              if ((r = cipher_cleanup(&state->send_context)) != 0)
++                      error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
++              if ((r = cipher_cleanup(&state->receive_context)) != 0)
++                      error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
++              audit_session_key_free(2);
++      }
+       if (ssh->remote_ipaddr) {
+               free(ssh->remote_ipaddr);
+               ssh->remote_ipaddr = NULL;
+       }
++      if (state->connection_in == state->connection_out) {
++              shutdown(state->connection_out, SHUT_RDWR);
++              close(state->connection_out);
++      } else {
++              close(state->connection_in);
++              close(state->connection_out);
++      }
+       free(ssh->state);
+       ssh->state = NULL;
+ }
+@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod
+       }
+       if (state->newkeys[mode] != NULL) {
+               debug("set_newkeys: rekeying");
++              audit_session_key_free(mode);
+               if ((r = cipher_cleanup(cc)) != 0)
+                       return r;
+               enc  = &state->newkeys[mode]->enc;
+@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh)
+       return (void *)ssh->state->output;
+ }
++static void
++newkeys_destroy_and_free(struct newkeys *newkeys)
++{
++      if (newkeys == NULL)
++              return;
++
++      free(newkeys->enc.name);
++
++      if (newkeys->mac.enabled) {
++              mac_clear(&newkeys->mac);
++              free(newkeys->mac.name);
++      }
++
++      free(newkeys->comp.name);
++
++      newkeys_destroy(newkeys);
++      free(newkeys);
++}
++
++static void
++packet_destroy_state(struct session_state *state)
++{
++      if (state == NULL)
++              return;
++
++      cipher_cleanup(&state->receive_context);
++      cipher_cleanup(&state->send_context);
++
++      buffer_free(state->input);
++      state->input = NULL;
++      buffer_free(state->output);
++      state->output = NULL;
++      buffer_free(state->outgoing_packet);
++      state->outgoing_packet = NULL;
++      buffer_free(state->incoming_packet);
++      state->incoming_packet = NULL;
++      if( state->compression_buffer ) {
++              buffer_free(state->compression_buffer);
++              state->compression_buffer = NULL;
++      }
++      newkeys_destroy_and_free(state->newkeys[MODE_IN]);
++      state->newkeys[MODE_IN] = NULL;
++      newkeys_destroy_and_free(state->newkeys[MODE_OUT]);
++      state->newkeys[MODE_OUT] = NULL;
++      mac_destroy(state->packet_discard_mac);
++//    TAILQ_HEAD(, packet) outgoing;
++//    memset(state, 0, sizeof(state));
++}
++
++void
++packet_destroy_all(int audit_it, int privsep)
++{
++      if (audit_it)
++              audit_it = (active_state != NULL && packet_state_has_keys(active_state->state))
++                      || (backup_state != NULL && packet_state_has_keys(backup_state->state));
++      if (active_state != NULL)
++              packet_destroy_state(active_state->state);
++      if (backup_state != NULL)
++              packet_destroy_state(backup_state->state);
++      if (audit_it) {
++#ifdef SSH_AUDIT_EVENTS
++              if (privsep)
++                      audit_session_key_free(2);
++              else
++                      audit_session_key_free_body(2, getpid(), getuid());
++#endif
++      }
++}
++
+ /* XXX TODO update roaming to new API (does not work anyway) */
+ /*
+  * Save the state for the real connection, and use a separate state when
+@@ -2272,18 +2373,12 @@ void
+ ssh_packet_backup_state(struct ssh *ssh,
+     struct ssh *backup_state)
+ {
+-      struct ssh *tmp;
+-
+       close(ssh->state->connection_in);
+       ssh->state->connection_in = -1;
+       close(ssh->state->connection_out);
+       ssh->state->connection_out = -1;
+-      if (backup_state)
+-              tmp = backup_state;
+-      else
+-              tmp = ssh_alloc_session_state();
+       backup_state = ssh;
+-      ssh = tmp;
++      ssh = ssh_alloc_session_state();
+ }
+ /* XXX FIXME FIXME FIXME */
+@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh
+       backup_state = ssh;
+       ssh = tmp;
+       ssh->state->connection_in = backup_state->state->connection_in;
+-      backup_state->state->connection_in = -1;
+       ssh->state->connection_out = backup_state->state->connection_out;
+-      backup_state->state->connection_out = -1;
+       len = sshbuf_len(backup_state->state->input);
+       if (len > 0) {
+               if ((r = sshbuf_putb(ssh->state->input,
+@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh
+               sshbuf_reset(backup_state->state->input);
+               add_recv_bytes(len);
+       }
++      backup_state->state->connection_in = -1;
++      backup_state->state->connection_out = -1;
++      packet_destroy_state(backup_state->state);
++      free(backup_state);
++      backup_state = NULL;
+ }
+ /* Reset after_authentication and reset compression in post-auth privsep */
+diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h
+--- openssh-6.8p1/packet.h.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/packet.h     2015-03-20 13:41:15.097883774 +0100
+@@ -189,7 +189,7 @@ int        sshpkt_get_end(struct ssh *ssh);
+ const u_char  *sshpkt_ptr(struct ssh *, size_t *lenp);
+ /* OLD API */
+-extern struct ssh *active_state;
++extern struct ssh *active_state, *backup_state;
+ #include "opacket.h"
+ #if !defined(WITH_OPENSSL)
+@@ -203,4 +203,5 @@ extern struct ssh *active_state;
+ # undef EC_POINT
+ #endif
++void   packet_destroy_all(int, int);
+ #endif                                /* PACKET_H */
+diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c
+--- openssh-6.8p1/session.c.audit      2015-03-20 13:41:15.073883813 +0100
++++ openssh-6.8p1/session.c    2015-03-20 13:41:15.097883774 +0100
+@@ -139,7 +139,7 @@ extern int log_stderr;
+ extern int debug_flag;
+ extern u_int utmp_len;
+ extern int startup_pipe;
+-extern void destroy_sensitive_data(void);
++extern void destroy_sensitive_data(int);
+ extern Buffer loginmsg;
+ /* original command from peer. */
+@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm
+       /* Parent.  Close the slave side of the pseudo tty. */
+       close(ttyfd);
++#ifndef HAVE_OSF_SIA
++      /* do_login in the child did not affect state in this process,
++         compensate.  From an architectural standpoint, this is extremely
++         ugly. */
++      if (!(options.use_login && command == NULL))
++              audit_count_session_open();
++#endif
++
+       /* Enter interactive session. */
+       s->ptymaster = ptymaster;
+       packet_set_interactive(1, 
+@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command)
+           get_remote_port());
+ #ifdef SSH_AUDIT_EVENTS
++      if (s->command != NULL || s->command_handle != -1)
++              fatal("do_exec: command already set");
+       if (command != NULL)
+-              PRIVSEP(audit_run_command(command));
++              s->command = xstrdup(command);
+       else if (s->ttyfd == -1) {
+               char *shell = s->pw->pw_shell;
+               if (shell[0] == '\0')   /* empty shell means /bin/sh */
+                       shell =_PATH_BSHELL;
+-              PRIVSEP(audit_run_command(shell));
++              s->command = xstrdup(shell);
+       }
++      if (s->command != NULL && s->ptyfd == -1)
++              s->command_handle = PRIVSEP(audit_run_command(s->command));
+ #endif
+       if (s->ttyfd != -1)
+               ret = do_exec_pty(s, command);
+@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command
+       int r = 0;
+       /* remove hostkey from the child's memory */
+-      destroy_sensitive_data();
++      destroy_sensitive_data(1);
++      /* Don't audit this - both us and the parent would be talking to the
++         monitor over a single socket, with no synchronization. */
++      packet_destroy_all(0, 1);
+       /* Force a password change */
+       if (s->authctxt->force_pwchange) {
+@@ -1934,6 +1949,7 @@ session_unused(int id)
+       sessions[id].ttyfd = -1;
+       sessions[id].ptymaster = -1;
+       sessions[id].x11_chanids = NULL;
++      sessions[id].command_handle = -1;
+       sessions[id].next_unused = sessions_first_unused;
+       sessions_first_unused = id;
+ }
+@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha
+ }
+ Session *
++session_by_id(int id)
++{
++      if (id >= 0 && id < sessions_nalloc) {
++              Session *s = &sessions[id];
++              if (s->used)
++                      return s;
++      }
++      debug("session_by_id: unknown id %d", id);
++      session_dump();
++      return NULL;
++}
++
++Session *
+ session_by_tty(char *tty)
+ {
+       int i;
+@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta
+               chan_write_failed(c);
+ }
++#ifdef SSH_AUDIT_EVENTS
++void
++session_end_command2(Session *s)
++{
++      if (s->command != NULL) {
++              if (s->command_handle != -1)
++                      audit_end_command(s->command_handle, s->command);
++              free(s->command);
++              s->command = NULL;
++              s->command_handle = -1;
++      }
++}
++
++static void
++session_end_command(Session *s)
++{
++      if (s->command != NULL) {
++              if (s->command_handle != -1)
++                      PRIVSEP(audit_end_command(s->command_handle, s->command));
++              free(s->command);
++              s->command = NULL;
++              s->command_handle = -1;
++      }
++}
++#endif
++
+ void
+ session_close(Session *s)
+ {
+@@ -2540,6 +2593,10 @@ session_close(Session *s)
+       debug("session_close: session %d pid %ld", s->self, (long)s->pid);
+       if (s->ttyfd != -1)
+               session_pty_cleanup(s);
++#ifdef SSH_AUDIT_EVENTS
++      if (s->command)
++              session_end_command(s);
++#endif
+       free(s->term);
+       free(s->display);
+       free(s->x11_chanids);
+@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt)
+       server_loop2(authctxt);
+ }
++static void
++do_cleanup_one_session(Session *s)
++{
++      session_pty_cleanup2(s);
++#ifdef SSH_AUDIT_EVENTS
++      session_end_command2(s);
++#endif
++}
++
+ void
+ do_cleanup(Authctxt *authctxt)
+ {
+@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt)
+        * or if running in monitor.
+        */
+       if (!use_privsep || mm_is_monitor())
+-              session_destroy_all(session_pty_cleanup2);
++              session_destroy_all(do_cleanup_one_session);
+ }
+diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h
+--- openssh-6.8p1/session.h.audit      2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/session.h    2015-03-20 13:41:15.097883774 +0100
+@@ -61,6 +61,12 @@ struct Session {
+               char    *name;
+               char    *val;
+       } *env;
++
++      /* exec */
++#ifdef SSH_AUDIT_EVENTS
++      int     command_handle;
++      char    *command;
++#endif
+ };
+ void   do_authenticated(Authctxt *);
+@@ -73,8 +79,10 @@ void         session_close_by_pid(pid_t, int);
+ void   session_close_by_channel(int, void *);
+ void   session_destroy_all(void (*)(Session *));
+ void   session_pty_cleanup2(Session *);
++void   session_end_command2(Session *);
+ Session       *session_new(void);
++Session *session_by_id(int);
+ Session       *session_by_tty(char *);
+ void   session_close(Session *);
+ void   do_setusercontext(struct passwd *);
+diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c
+--- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100
++++ openssh-6.8p1/sshd.c       2015-03-20 13:41:15.110883753 +0100
+@@ -121,6 +124,7 @@
+ #endif
+ #include "monitor_wrap.h"
+ #include "roaming.h"
++#include "audit.h"
+ #include "ssh-sandbox.h"
+ #include "version.h"
+ #include "ssherr.h"
+@@ -260,7 +264,7 @@ Buffer loginmsg;
+ struct passwd *privsep_pw = NULL;
+ /* Prototypes for various functions defined later in this file. */
+-void destroy_sensitive_data(void);
++void destroy_sensitive_data(int);
+ void demote_sensitive_data(void);
+ #ifdef WITH_SSH1
+@@ -281,6 +285,15 @@ close_listen_socks(void)
+       num_listen_socks = -1;
+ }
++/*
++ * Is this process listening for clients (i.e. not specific to any specific
++ * client connection?)
++ */
++int listening_for_clients(void)
++{
++      return num_listen_socks > 0;
++}
++
+ static void
+ close_startup_pipes(void)
+ {
+@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in
+       }
+ }
+-/* Destroy the host and server keys.  They will no longer be needed. */
++/*
++ * Destroy the host and server keys.  They will no longer be needed.  Careful,
++ * this can be called from cleanup_exit() - i.e. from just about anywhere.
++ */
+ void
+-destroy_sensitive_data(void)
++destroy_sensitive_data(int privsep)
+ {
+       int i;
++      pid_t pid;
++      uid_t uid;
+       if (sensitive_data.server_key) {
+               key_free(sensitive_data.server_key);
+               sensitive_data.server_key = NULL;
+       }
++      pid = getpid();
++      uid = getuid();
+       for (i = 0; i < options.num_host_key_files; i++) {
+               if (sensitive_data.host_keys[i]) {
++                      char *fp;
++
++                      if (key_is_private(sensitive_data.host_keys[i]))
++                              fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX);
++                      else
++                              fp = NULL;
+                       key_free(sensitive_data.host_keys[i]);
+                       sensitive_data.host_keys[i] = NULL;
++                      if (fp != NULL) {
++                              if (privsep)
++                                      PRIVSEP(audit_destroy_sensitive_data(fp,
++                                              pid, uid));
++                              else
++                                      audit_destroy_sensitive_data(fp,
++                                              pid, uid);
++                              free(fp);
++                      }
+               }
+-              if (sensitive_data.host_certificates[i]) {
++              if (sensitive_data.host_certificates
++                  && sensitive_data.host_certificates[i]) {
+                       key_free(sensitive_data.host_certificates[i]);
+                       sensitive_data.host_certificates[i] = NULL;
+               }
+@@ -589,6 +625,8 @@ void
+ demote_sensitive_data(void)
+ {
+       Key *tmp;
++      pid_t pid;
++      uid_t uid;
+       int i;
+       if (sensitive_data.server_key) {
+@@ -597,13 +635,25 @@ demote_sensitive_data(void)
+               sensitive_data.server_key = tmp;
+       }
++      pid = getpid();
++      uid = getuid();
+       for (i = 0; i < options.num_host_key_files; i++) {
+               if (sensitive_data.host_keys[i]) {
++                      char *fp;
++
++                      if (key_is_private(sensitive_data.host_keys[i]))
++                              fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX);
++                      else
++                              fp = NULL;
+                       tmp = key_demote(sensitive_data.host_keys[i]);
+                       key_free(sensitive_data.host_keys[i]);
+                       sensitive_data.host_keys[i] = tmp;
+                       if (tmp->type == KEY_RSA1)
+                               sensitive_data.ssh1_host_key = tmp;
++                      if (fp != NULL) {
++                              audit_destroy_sensitive_data(fp, pid, uid);
++                              free(fp);
++                      }
+               }
+               /* Certs do not need demotion */
+       }
+@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt)
+       if (use_privsep == PRIVSEP_ON)
+               box = ssh_sandbox_init(pmonitor);
+-      pid = fork();
++      pmonitor->m_pid = pid = fork();
+       if (pid == -1) {
+               fatal("fork of unprivileged child failed");
+       } else if (pid != 0) {
+@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt)
+       else if (pmonitor->m_pid != 0) {
+               verbose("User child is on pid %ld", (long)pmonitor->m_pid);
+               buffer_clear(&loginmsg);
++              if (*pmonitor->m_pkex != NULL ){
++                      newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]);
++                      newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_IN]);
++                      audit_session_key_free_body(2, getpid(), getuid());
++                      packet_destroy_all(0, 0);
++              }
+               monitor_child_postauth(pmonitor);
+               /* NEVERREACHED */
+@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so
+               if (received_sigterm) {
+                       logit("Received signal %d; terminating.",
+                           (int) received_sigterm);
++                      destroy_sensitive_data(0);
+                       close_listen_socks();
+                       if (options.pid_file != NULL)
+                               unlink(options.pid_file);
+@@ -2242,6 +2321,7 @@ main(int ac, char **av)
+        */
+       if (use_privsep) {
+               mm_send_keystate(pmonitor);
++              packet_destroy_all(1, 1);
+               exit(0);
+       }
+@@ -2287,7 +2367,7 @@ main(int ac, char **av)
+               privsep_postauth(authctxt);
+               /* the monitor process [priv] will not return */
+               if (!compat20)
+-                      destroy_sensitive_data();
++                      destroy_sensitive_data(0);
+       }
+       packet_set_timeout(options.client_alive_interval,
+@@ -2301,6 +2381,9 @@ main(int ac, char **av)
+       do_authenticated(authctxt);
+       /* The connection has been terminated. */
++      packet_destroy_all(1, 1);
++      destroy_sensitive_data(1);
++
+       packet_get_bytes(&ibytes, &obytes);
+       verbose("Transferred: sent %llu, received %llu bytes",
+           (unsigned long long)obytes, (unsigned long long)ibytes);
+@@ -2461,6 +2544,10 @@ do_ssh1_kex(void)
+               if (cookie[i] != packet_get_char())
+                       packet_disconnect("IP Spoofing check bytes do not match.");
++#ifdef SSH_AUDIT_EVENTS
++      audit_kex(2, cipher_name(cipher_type), "crc", "none", "none");
++#endif
++
+       debug("Encryption type: %.200s", cipher_name(cipher_type));
+       /* Get the encrypted integer. */
+@@ -2520,7 +2607,7 @@ do_ssh1_kex(void)
+       }
+       /* Destroy the private and public keys. No longer. */
+-      destroy_sensitive_data();
++      destroy_sensitive_data(1);
+       if (use_privsep)
+               mm_ssh1_session_id(session_id);
+@@ -2703,6 +2802,16 @@ do_ssh2_kex(void)
+ void
+ cleanup_exit(int i)
+ {
++      static int in_cleanup = 0;
++      int is_privsep_child;
++
++      /* cleanup_exit can be called at the very least from the privsep
++         wrappers used for auditing.  Make sure we don't recurse
++         indefinitely. */
++      if (in_cleanup)
++              _exit(i);
++      in_cleanup = 1;
++
+       if (the_authctxt) {
+               do_cleanup(the_authctxt);
+               if (use_privsep && privsep_is_preauth &&
+@@ -2714,9 +2823,14 @@ cleanup_exit(int i)
+                                   pmonitor->m_pid, strerror(errno));
+               }
+       }
++      is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0;
++      if (sensitive_data.host_keys != NULL)
++              destroy_sensitive_data(is_privsep_child);
++      packet_destroy_all(1, is_privsep_child);
+ #ifdef SSH_AUDIT_EVENTS
+       /* done after do_cleanup so it can cancel the PAM auth 'thread' */
+-      if (!use_privsep || mm_is_monitor())
++      if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
++          (!use_privsep || mm_is_monitor()))
+               audit_event(SSH_CONNECTION_ABANDON);
+ #endif
+       _exit(i);
+diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c
+--- openssh-6.8p1/sshkey.c.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/sshkey.c     2015-03-20 13:41:15.111883751 +0100
+@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type)
+ }
+ int
++sshkey_is_private(const struct sshkey *k)
++{
++      switch (k->type) {
++      case KEY_RSA_CERT_V00:
++      case KEY_RSA_CERT:
++      case KEY_RSA1:
++      case KEY_RSA:
++              return k->rsa->d != NULL;
++      case KEY_DSA_CERT_V00:
++      case KEY_DSA_CERT:
++      case KEY_DSA:
++              return k->dsa->priv_key != NULL;
++#ifdef OPENSSL_HAS_ECC
++      case KEY_ECDSA_CERT:
++      case KEY_ECDSA:
++              return EC_KEY_get0_private_key(k->ecdsa) != NULL;
++#endif
++      case KEY_ED25519_CERT:
++      case KEY_ED25519:
++              return (k->ed25519_pk != NULL);
++      default:
++              /* fatal("key_is_private: bad key type %d", k->type); */
++              return 0;
++      }
++}
++
++int
+ sshkey_is_cert(const struct sshkey *k)
+ {
+       if (k == NULL)
+diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h
+--- openssh-6.8p1/sshkey.h.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/sshkey.h     2015-03-20 13:41:15.098883772 +0100
+@@ -134,6 +134,7 @@ u_int               sshkey_size(const struct sshkey
+ int            sshkey_generate(int type, u_int bits, struct sshkey **keyp);
+ int            sshkey_from_private(const struct sshkey *, struct sshkey **);
+ int    sshkey_type_from_name(const char *);
++int    sshkey_is_private(const struct sshkey *);
+ int    sshkey_is_cert(const struct sshkey *);
+ int    sshkey_type_is_cert(int);
+ int    sshkey_type_plain(int);
+diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit openssh-6.8p1/sandbox-seccomp-filter.c
+--- openssh-6.8p1/sandbox-seccomp-filter.c.audit       2015-03-20 13:41:15.088883788 +0100
++++ openssh-6.8p1/sandbox-seccomp-filter.c     2015-03-20 13:41:15.097883774 +0100
+@@ -110,6 +110,12 @@ static const struct sock_filter preauth_
+ #ifdef __NR_time /* not defined on EABI ARM */
+       SC_ALLOW(time),
+ #endif
++#ifdef SSH_AUDIT_EVENTS
++      SC_ALLOW(getuid),
++#ifdef __NR_getuid32 /* not defined on x86_64 */
++      SC_ALLOW(getuid32),
++#endif
++#endif
+       SC_ALLOW(read),
+       SC_ALLOW(write),
+       SC_ALLOW(close),
diff --git a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch
new file mode 100644 (file)
index 0000000..4285bd9
--- /dev/null
@@ -0,0 +1,66 @@
+diff --git a/configure.ac b/configure.ac
+index 4065d0e..d59ad44 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -764,9 +764,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
+       i*86-*)
+               seccomp_audit_arch=AUDIT_ARCH_I386
+               ;;
+-        arm*-*)
++      aarch64*-*)
++              seccomp_audit_arch=AUDIT_ARCH_AARCH64
++              ;;
++      arm*-*)
+               seccomp_audit_arch=AUDIT_ARCH_ARM
+-                ;;
++              ;;
+       esac
+       if test "x$seccomp_audit_arch" != "x" ; then
+               AC_MSG_RESULT(["$seccomp_audit_arch"])
+diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
+index 095b04a..52f6810 100644
+--- a/sandbox-seccomp-filter.c
++++ b/sandbox-seccomp-filter.c
+@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = {
+       /* Load the syscall number for checking. */
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+               offsetof(struct seccomp_data, nr)),
+-      SC_DENY(open, EACCES),
+-      SC_DENY(stat, EACCES),
++      SC_DENY(openat, EACCES),
++#ifdef __NR_open
++      SC_DENY(open, EACCES), /* not on AArch64 */
++#endif
++#ifdef __NR_fstat
++      SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */
++#endif
++#if defined(__NR_stat64) && defined(__NR_fstat64)
++      SC_DENY(stat64, EACCES), /* ix86, arm */
++      SC_DENY(fstat64, EACCES),
++#endif
++#ifdef __NR_newfstatat
++      SC_DENY(newfstatat, EACCES), /* Aarch64 */
++#endif
+       SC_ALLOW(getpid),
+       SC_ALLOW(gettimeofday),
+       SC_ALLOW(clock_gettime),
+@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] = {
+       SC_ALLOW(shutdown),
+ #endif
+       SC_ALLOW(brk),
++#ifdef __NR_poll /* not on AArch64 */
+       SC_ALLOW(poll),
++#endif
+ #ifdef __NR__newselect
+       SC_ALLOW(_newselect),
+ #else
++#ifdef __NR_select /* not on AArch64 */
+       SC_ALLOW(select),
+ #endif
++#ifdef __NR_pselect6 /* AArch64 */
++      SC_ALLOW(pselect6),
++#endif
++#endif
+       SC_ALLOW(madvise),
+ #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */
+       SC_ALLOW(mmap2),
diff --git a/openssh/patches/openssh-6.7p1-sftp-force-permission.patch b/openssh/patches/openssh-6.7p1-sftp-force-permission.patch
new file mode 100644 (file)
index 0000000..1a88e50
--- /dev/null
@@ -0,0 +1,81 @@
+diff -up openssh-6.8p1/sftp-server.8.sftp-force-mode openssh-6.8p1/sftp-server.8
+--- openssh-6.8p1/sftp-server.8.sftp-force-mode        2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/sftp-server.8        2015-03-18 13:18:05.898306477 +0100
+@@ -38,6 +38,7 @@
+ .Op Fl P Ar blacklisted_requests
+ .Op Fl p Ar whitelisted_requests
+ .Op Fl u Ar umask
++.Op Fl m Ar force_file_perms
+ .Ek
+ .Nm
+ .Fl Q Ar protocol_feature
+@@ -138,6 +139,10 @@ Sets an explicit
+ .Xr umask 2
+ to be applied to newly-created files and directories, instead of the
+ user's default mask.
++.It Fl m Ar force_file_perms
++Sets explicit file permissions to be applied to newly-created files instead
++of the default or client requested mode.  Numeric values include:
++777, 755, 750, 666, 644, 640, etc.  Option -u is ineffective if -m is set.
+ .El
+ .Pp
+ On some systems,
+diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c
+--- openssh-6.8p1/sftp-server.c.sftp-force-mode        2015-03-18 13:18:05.883306513 +0100
++++ openssh-6.8p1/sftp-server.c        2015-03-18 13:18:36.697232193 +0100
+@@ -70,6 +70,10 @@ struct sshbuf *oqueue;
+ /* Version of client */
+ static u_int version;
++/* Force file permissions */
++int permforce = 0;
++long permforcemode;
++
+ /* SSH2_FXP_INIT received */
+ static int init_done;
+@@ -693,6 +697,10 @@ process_open(u_int32_t id)
+       debug3("request %u: open flags %d", id, pflags);
+       flags = flags_from_portable(pflags);
+       mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
++      if (permforce == 1) {   /* Force perm if -m is set */
++              mode = permforcemode;
++              (void)umask(0); /* so umask does not interfere           */
++      }       
+       logit("open \"%s\" flags %s mode 0%o",
+           name, string_from_portable(pflags), mode);
+       if (readonly &&
+@@ -1495,7 +1503,7 @@ sftp_server_usage(void)
+       fprintf(stderr,
+           "usage: %s [-ehR] [-d start_directory] [-f log_facility] "
+           "[-l log_level]\n\t[-P blacklisted_requests] "
+-          "[-p whitelisted_requests] [-u umask]\n"
++          "[-p whitelisted_requests] [-u umask] [-m force_file_perms]\n"
+           "       %s -Q protocol_feature\n",
+           __progname, __progname);
+       exit(1);
+@@ -1520,7 +1528,7 @@ sftp_server_main(int argc, char **argv,
+       pw = pwcopy(user_pw);
+       while (!skipargs && (ch = getopt(argc, argv,
+-          "d:f:l:P:p:Q:u:cehR")) != -1) {
++          "d:f:l:P:p:Q:u:m:cehR")) != -1) {
+               switch (ch) {
+               case 'Q':
+                       if (strcasecmp(optarg, "requests") != 0) {
+@@ -1580,6 +1588,15 @@ sftp_server_main(int argc, char **argv,
+                               fatal("Invalid umask \"%s\"", optarg);
+                       (void)umask((mode_t)mask);
+                       break;
++              case 'm':
++                      /* Force permissions on file received via sftp */
++                      permforce = 1;
++                      permforcemode = strtol(optarg, &cp, 8);
++                      if (permforcemode < 0 || permforcemode > 0777 ||
++                          *cp != '\0' || (permforcemode == 0 &&
++                          errno != 0))
++                              fatal("Invalid file mode \"%s\"", optarg);
++                      break;
+               case 'h':
+               default:
+                       sftp_server_usage();
index 88c9bd90ce1613f81707e2acb42c22b044d2f2c1..ca6e961fc7b23e58ba5ee1d0d36225461c956d47 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = openvpn
-version    = 2.3.0
-release    = 2
+version    = 2.3.6
+release    = 1
 
 groups     = Networking/VPN
 url        = http://openvpn.net/
@@ -31,6 +31,7 @@ build
                lzo-devel
                openssl-devel
                pam-devel
+               systemd-devel
        end
 
        configure_options += \
index 7b7b5c7a102d4a767667c71c34924d862a05f8b7..cdb457db7f8da0f2172ca8422ee9f506a973a4e8 100644 (file)
@@ -5,8 +5,8 @@
 
 name       = pango
 version    = %{ver_major}.%{ver_minor}
-ver_major  = 1.32
-ver_minor  = 5
+ver_major  = 1.36
+ver_minor  = 8
 release    = 1
 
 groups     = System/Libraries
index 508e914970100b975314360b575c8b8e42b89c84..507bffd770e0b927d6832384528bf4b62909e31a 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-BDB
-version    = 1.9
+version    = 1.91
 release    = 1
 thisapp    = BDB-%{version}
 
@@ -36,13 +36,14 @@ build
                make test
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 end
 
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index e263a67cccf12c53d0528bfe54d86ef328552e15..cad57d028d2eb00f510ea7e64bbebb28b81969e3 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-Coro
-version    = 6.08
+version    = 6.42
 release    = 1
 thisapp    = Coro-%{version}
 
@@ -40,7 +40,8 @@ build
                make %{PARALLELISMFLAGS}
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 end
 
 packages
@@ -55,7 +56,7 @@ packages
                end
 
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index 9e5a596f9f84938e35b82226f201bd77443bd57f..25b9fae6d462182f93ec7c4109e8baa2c471f216 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = perl-Crypt-PasswdMD5
-version    = 1.3
-release    = 2
+version    = 1.40
+release    = 1
 arch       = noarch
 thisapp    = Crypt-PasswdMD5-%{version}
 
@@ -18,7 +18,8 @@ description
        This package provides MD5-based crypt() functions.
 end
 
-source_dl  = http://search.cpan.org/CPAN/authors/id/L/LU/LUISMUNOZ/
+source_dl  = http://search.cpan.org/CPAN/authors/id/R/RS/RSAVAGE/
+sources    = %{thisapp}.tgz
 
 build
        requires
@@ -30,17 +31,10 @@ build
                make %{PARALLELISMFLAGS}
        end
 
-       make_install_targets = pure_install
+       make_install_targets = \
+               pure_install
 end
 
 packages
        package %{name}
-               requires
-                       perl
-               end
-       end
-
-       package %{name}-debuginfo
-               template DEBUGINFO
-       end
 end
index 84cb0e1a3b82853fe127524eafe543f4ec396af8..9e76605555a970c03bced31d2d035ad258523710 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-DBI
-version    = 1.618
+version    = 1.633
 release    = 1
 thisapp    = DBI-%{version}
 
@@ -37,7 +37,8 @@ build
                make test
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 end
 
 packages
@@ -48,7 +49,7 @@ packages
                end
 
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index 8c34a8610c3d1d4d4a426ca9f9ca411f4f10bf52..736fd9c1c17418376b8410ba437ece7a57585739 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = perl-Digest-SHA1
 version    = 2.13
-release    = 3
+release    = 4
 thisapp    = Digest-SHA1-%{version}
 
 groups     = Development/Libraries
@@ -40,11 +40,16 @@ build
                make %{PARALLELISMFLAGS}
        end
 
-       make_install_targets = pure_install
+       make_install_targets = \
+               pure_install
 end
 
 packages
        package %{name}
+               requires
+                       perl(:MODULE_COMPAT_%{perl_version})
+               end
+       end
 
        package %{name}-debuginfo
                template DEBUGINFO
index b5bce3ffab11b51ba1b2b64060ba02b1311a95db..a81058709e1c164525e9823b2f25bed582039d0d 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = perl-FCGI
-version    = 0.74
-release    = 2
+version    = 0.77
+release    = 1
 thisapp    = FCGI-%{version}
 
 groups     = Development/Libraries
@@ -17,7 +17,7 @@ description
        FastCGI perl bindings.
 end
 
-source_dl  = http://search.cpan.org/CPAN/authors/id/F/FL/FLORA/
+source_dl  = http://search.cpan.org/CPAN/authors/id/E/ET/ETHER/
 
 build
        requires
@@ -34,13 +34,14 @@ build
                make test
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 end
 
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index dd491b6e22901d722137c0649b06fbda60e43a5c..1d558940eadb6352d17839282128b7770b880041 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-HTML-Parser
-version    = 3.68
+version    = 3.71
 release    = 1
 
 groups     = Development/Libratries
@@ -18,7 +18,7 @@ description
        HTML::LinkExtor, HTML::PullParser, and HTML::TokeParser modules.
 end
 
-source_dl  =
+source_dl  = http://search.cpan.org/CPAN/authors/id/G/GA/GAAS/
 
 thisapp    = HTML-Parser-%{version}
 
@@ -42,6 +42,10 @@ end
 
 packages
        package %{name}
+               requires
+                       perl(:MODULE_COMPAT_%{perl_version})
+               end
+       end
 
        package %{name}-debuginfo
                template DEBUGINFO
index 105196c4420085911255ac8b948cdf350561afa5..9a1d342c0dd058e581315234e239933592bc7c8b 100644 (file)
@@ -19,7 +19,7 @@ description
        HTML parsing operations, such as tag and entity names.
 end
 
-source_dl  =
+source_dl  = http://search.cpan.org/CPAN/authors/id/P/PE/PETDANCE/
 
 build
        requires
index 2565f49195eb1eeb7744767b51da0bf96908606d..b2adec74424ddb8e04af7bfed831058cc934b0ac 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-IO-AIO
-version    = 4.15
+version    = 4.32
 release    = 1
 thisapp    = IO-AIO-%{version}
 
@@ -37,7 +37,8 @@ build
                make test
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 
        install_cmds
                # Remove script we don't want packaged
@@ -48,7 +49,7 @@ end
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index bae844b790c565180082fda6acdc939bdd7ca7bf..20896caa88e454038d98d04e2f73a87b02c5dfde 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-TermReadKey
-version    = 2.30
+version    = 2.32
 release    = 1
 thisapp    = TermReadKey-%{version}
 
@@ -38,13 +38,14 @@ build
                make %{PARALLELISMFLAGS}
        end
 
-       make_install_targets = pure_install
+       make_install_targets = \
+               pure_install
 end
 
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index 23edebd2d206fef7a39aa67b8ca03882b79def57..9c7e449af2983290595754cea7184519f0c04f70 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = perl-Tk
-version    = 804.029
-release    = 2
+version    = 804.033
+release    = 1
 thisapp    = Tk-%{version}
 
 groups     = Development/Libraries
@@ -57,6 +57,10 @@ packages
                        perl(Tk::TextReindex)
                        perl(Tk) = %{version}
                end
+
+               requires
+                       perl(:MODULE_COMPAT_%{perl_version})
+               end
        end
 
        package %{name}-devel
index cd88c7d605a8271ca2cd46defe7a36dd35e57b55..060448f84ffbbd7175d95ca64c745a4c1f06c97d 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-URI
-version    = 1.56
+version    = 1.67
 release    = 1
 arch       = noarch
 thisapp    = URI-%{version}
@@ -20,7 +20,7 @@ description
        updated by RFC 2732).
 end
 
-source_dl  =
+source_dl  = http://search.cpan.org/CPAN/authors/id/E/ET/ETHER/
 
 build
        requires
index 8a20f72211cdaa148f3557b2046af6a1330226b7..84895f8cd1c89082431a68292a944b11e20465af 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = perl-WWW-Curl
-version    = 4.15
-release    = 2
+version    = 4.17
+release    = 1
 thisapp    = WWW-Curl-%{version}
 
 groups     = Development/Libraries
@@ -37,7 +37,7 @@ end
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index 6a2ce7a920e9008160751bec7d351beb804792d0..7c3b249201c7f93790a664e438a089f37058cd13 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-XML-Parser
-version    = 2.36
+version    = 2.44
 release    = 1
 thisapp    = XML-Parser-%{version}
 
@@ -14,12 +14,12 @@ license    = GPL+ or Artistic
 summary    = Perl module for parsing XML files.
 
 description
-       This module provides ways to parse XML documents. It is built on \
-       top of XML::Parser::Expat, which is a lower level interface to \
+       This module provides ways to parse XML documents. It is built on
+       top of XML::Parser::Expat, which is a lower level interface to
        James Clark's expat library.
 end
 
-source_dl  =
+source_dl  = http://search.cpan.org/CPAN/authors/id/T/TO/TODDR/
 
 build
        requires
@@ -43,7 +43,7 @@ end
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 
index f6dfb0e281ec7d539472a316e904b6d9f5e25d4f..f71a743ce2f37f11a365b51725d426628b02975d 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = perl-common-sense
-version    = 3.5
+version    = 3.73
 release    = 1
 arch       = noarch
 thisapp    = common-sense-%{version}
@@ -41,13 +41,14 @@ build
                make test
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 end
 
 packages
        package %{name}
                requires
-                       perl
+                       perl(:MODULE_COMPAT_%{perl_version})
                end
        end
 end
index eb511b0a0b73328b923ec6f1e11e8da3f6a2aaf6..bb3b8c513b6a64622fcf7cffb1288030b272199c 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = perl-libintl-perl
 version    = 1.23
-release    = 1
+release    = 2
 thisapp    = libintl-perl-%{version}
 
 groups     = Development/Libraries
@@ -23,6 +23,7 @@ source_dl  = http://search.cpan.org/CPAN/authors/id/G/GU/GUIDO/
 
 build
        requires
+               /usr/bin/xsubpp
                # required for perl macros
                pakfire-builder >= 0.9.23-6
                perl(ExtUtils::MakeMaker)
@@ -37,11 +38,16 @@ build
                make test
        end
 
-       make_install_targets = pure_install DESTDIR=%{BUILDROOT}
+       make_install_targets = \
+               pure_install DESTDIR=%{BUILDROOT}
 end
 
 packages
        package %{name}
+               requires
+                       perl(:MODULE_COMPAT_%{perl_version})
+               end
+       end
 
        package %{name}-debuginfo
                template DEBUGINFO
index 36ff855dd8994e264d18f3ee63d1ac109db5cfd4..ce7fbf3f356e50dcd808ba20fc6c26cb0096e8d7 100644 (file)
@@ -6,7 +6,7 @@
 name       = perl
 version    = 5.20.2
 # Never reset release in this package, just increase.
-release    = 12
+release    = 13.1
 
 perl_epoch = 2
 thisver = %{perl_epoch}:%{version}-%{_release}
@@ -198,9 +198,7 @@ packages
                        perl(timelocal.pl)
                        perl(utf8_heavy.pl)
                        perl(validate.pl)
-                       perl(Exporter)
                        perl(File::Basename)
-                       perl(constant)
                        perl(strict)
                        perl(vars)
                end
@@ -1032,6 +1030,7 @@ packages
 
                requires
                        %{perl_requires}
+                       /usr/bin/xsubpp
                        perl-devel
                        perl(Data::Dumper)
                        perl(ExtUtils::Command)
index 27a30a21fb4787c94a26904bad53ec53031a03c7..bb8eab3f446278cb4572db6c759e5efbd33bd9ac 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = pigz
-version    = 2.2.5
+version    = 2.3.3
 release    = 1
 
 groups     = Applications/Compression
@@ -28,6 +28,10 @@ build
 
        make_build_targets += CFLAGS="%{CFLAGS}"
 
+       test
+               make test
+       end
+
        install
                install -p -D pigz %{BUILDROOT}%{bindir}/pigz
                ln -svf pigz %{BUILDROOT}%{bindir}/unpigz
index 28353f7ead195b7b9e950a41f153b564d1a78cae..9390081413d2367263c9182272475938326a76c2 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = pinentry
-version    = 0.7.6
+version    = 0.9.0
 release    = 1
 
 groups     = System/Libraries
@@ -19,7 +19,8 @@ description
        curses (text) based version of the PIN entry dialog.
 end
 
-source_dl  =
+source_dl  = ftp://ftp.gnupg.org/gcrypt/pinentry/
+sources    = %{thisapp}.tar.bz2
 
 build
        requires
index dceebf189a553eb5f9dfdfd458a02ac9991ac149..ccd225d07cb8fcaaf1cd700464149e0b14447416 100644 (file)
@@ -4,11 +4,11 @@
 ###############################################################################
 
 name       = pixman
-version    = 0.30.0
+version    = 0.32.6
 release    = 1
 
 groups     = System/Libraries
-url        = http://www.X.org/
+url        = http://www.pixman.org/
 license    = MIT
 summary    = Pixel manipulation library.
 
diff --git a/procps-ng/procps-ng.nm b/procps-ng/procps-ng.nm
new file mode 100644 (file)
index 0000000..6760a9b
--- /dev/null
@@ -0,0 +1,75 @@
+###############################################################################
+# IPFire.org    - An Open Source Firewall Solution                            #
+# Copyright (C) - IPFire Development Team <info@ipfire.org>                   #
+###############################################################################
+
+name       = procps-ng
+version    = 3.3.10
+release    = 1
+
+groups     = Applications/System
+url        = http://procps-ng.sourceforge.net/
+license    = GPL+ and GPLv2 and GPLv2+ and GPLv3+ and LGPLv2+
+summary    = System and process monitoring utilities.
+
+description
+       The procps package contains a set of system utilities that provide
+       system information. Procps includes ps, free, skill, pkill, pgrep,
+       snice, tload, top, uptime, vmstat, w, watch and pdwx.
+end
+
+source_dl  = http://downloads.sourceforge.net/%{name}/
+sources    = %{thisapp}.tar.xz
+
+build
+       requires
+               gettext-devel
+               libselinux-devel
+               ncurses-devel >= 5.9-11
+       end
+
+       configure_options += \
+               --disable-static \
+               --disable-kill \
+               --disable-w-from \
+               --disable-modern-top \
+               --enable-watch8bit \
+               --enable-skill \
+               --enable-sigwinch \
+               --enable-libselinux
+
+       # Fix install path of some binaries.
+       make_install_targets += \
+               usrbin_execdir=%{bindir}
+
+       install_cmds
+               ln -s %{bindir}/pidof %{buildroot}%{sbindir}/pidof
+       end
+end
+
+packages
+       package %{name}
+               groups += Base
+
+               provides
+                       procps=%{thisver}
+               end
+
+               obsoletes
+                       procps < %{thisver}
+                       /bin/pidof
+               end
+
+               conflicts
+                       sysvinit <= 2.86-6
+               end
+       end
+
+       package %{name}-devel
+               template DEVEL
+       end
+
+       package %{name}-debuginfo
+               template DEBUGINFO
+       end
+end
index 52adcebdeae88b3cf056f20232193ec73d0b85f9..84704b5b465812235c7245374be1fcf92d0a73ac 100644 (file)
@@ -6,7 +6,7 @@
 name       = python
 major_ver  = 2.7
 version    = %{major_ver}.5
-release    = 1
+release    = 2
 thisapp    = Python-%{version}
 
 groups     = Development/Languages
@@ -47,6 +47,13 @@ build
        end
 
        export CFLAGS  += -D_GNU_SOURCE -fwrapv
+       export CPPFLAGS = %(pkg-config --cflags-only-I libffi)
+       export OPT      = %{CFLAGS}
+
+       if "%{lib}" == "lib64"
+               patches += %{DIR_SOURCE}/python-2.7.3-lib64.patch
+               patches += %{DIR_SOURCE}/python-2.7-lib64-sysconfig.patch
+       end
 
        prepare_cmds
                # Remove embedded copies of expat, zlib and libffi
@@ -64,16 +71,6 @@ build
                --with-system-ffi \
                --enable-shared
 
-       build
-               export CPPFLAGS=$(pkg-config --cflags-only-I libffi)
-
-               OPT="%{CFLAGS}" \
-                       ./configure \
-                               %{configure_options}
-
-               make %{PARALLELISMFLAGS}
-       end
-
        test
                WITHIN_PYTHON_RPM_BUILD= EXTRATESTOPTS="--verbose" make test || :
        end
index fbf994b91e21335d164c0005f2d7e59178347d38..af1bd3bb0de62cf209723c067aed7672995a5978 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = rrdtool
-version    = 1.4.7
+version    = 1.4.9
 release    = 1
 
 groups     = Applications/Databases
diff --git a/strace/patches/0001-linux-aarch64-add-missing-header.patch b/strace/patches/0001-linux-aarch64-add-missing-header.patch
new file mode 100644 (file)
index 0000000..2b74775
--- /dev/null
@@ -0,0 +1,25 @@
+From e1e838360288805b6cb561c21e4e7a1ea32e7772 Mon Sep 17 00:00:00 2001
+From: Romain Naour <romain.naour@openwide.fr>
+Date: Sat, 4 Apr 2015 00:49:52 +0200
+Subject: [PATCH] linux/aarch64: add missing header.
+
+linux/aarch64/arch_regs.h file is missing in the strace-4.10.tar.xz archive.
+Add the one from the release 4.10 tag.
+
+Signed-off-by: Romain Naour <romain.naour@openwide.fr>
+---
+ linux/aarch64/arch_regs.h | 2 ++
+ 1 file changed, 2 insertions(+)
+ create mode 100644 linux/aarch64/arch_regs.h
+
+diff --git a/linux/aarch64/arch_regs.h b/linux/aarch64/arch_regs.h
+new file mode 100644
+index 0000000..9a5e33e
+--- /dev/null
++++ b/linux/aarch64/arch_regs.h
+@@ -0,0 +1,2 @@
++extern uint64_t *const aarch64_sp_ptr;
++extern uint32_t *const arm_sp_ptr;
+-- 
+1.9.3
+
index c6127ccc323719916b8cc6d0e5c28fb311f94649..6d179c5b3a21344fb270e9b47ce1c48f418872a7 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = strace
-version    = 4.7
+version    = 4.10
 release    = 1
 
 groups     = Development/Debuggers
@@ -13,24 +13,18 @@ license    = BSD
 summary    = Tracks and displays system calls associated with a running process.
 
 description
-       The strace program intercepts and records the system calls called and \
-       received by a running process.  Strace can print a record of each \
-       system call, its arguments and its return value. Strace is useful \
-       for diagnosing problems and debugging, as well as for instructional \
+       The strace program intercepts and records the system calls called and
+       received by a running process.  Strace can print a record of each
+       system call, its arguments and its return value. Strace is useful
+       for diagnosing problems and debugging, as well as for instructional
        purposes.
 end
 
 source_dl  = http://downloads.sourceforge.net/project/%{name}/%{name}/%{version}/
 sources    = %{thisapp}.tar.xz
 
-build
-       configure_options += \
-               --mandir=/usr/share/man
-end
-
 packages
        package %{name}
-       end
 
        package %{name}-debuginfo
                template DEBUGINFO
index 3727da59ec3fed4d96ab2aa2a187490ada7b0421..e470cca24c3855ed0fc4dd8a171a81ca1ed3b2e2 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = sysvinit
 version    = 2.86
-release    = 6
+release    = 7
 
 groups     = System/Base
 url        = https://alioth.debian.org/projects/pkg-sysvinit/
@@ -34,11 +34,9 @@ build
 
                # Install binaries.
                install -m 0755 src/killall5 %{BUILDROOT}%{sbindir}
-               ln -sf ../sbin/killall5 %{BUILDROOT}%{bindir}/pidof
 
                # Install man-pages.
                install -m 0664 man/killall5.8 %{BUILDROOT}%{mandir}/man8
-               install -m 0664 man/pidof.8 %{BUILDROOT}%{mandir}/man8
        end
 end
 
@@ -47,7 +45,6 @@ packages
                groups += Base
 
                provides
-                       /bin/pidof
                        /sbin/killall5
                end
        end
index b260e7e36fdd898737703c79f625572eb1fc5a85..9ca69b9c7a8b20fc41be665570a8e3c5e8d84ae0 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = tar
 version    = 1.26
-release    = 5
+release    = 6
 
 groups     = System/Packaging
 url        = http://www.gnu.org/software/tar/
@@ -36,6 +36,7 @@ build
                libacl-devel
                libattr-devel
                libselinux-devel
+               texinfo
        end
 
        configure_options += \
diff --git a/unzip/patches/unzip-6.0-format-secure.patch b/unzip/patches/unzip-6.0-format-secure.patch
new file mode 100644 (file)
index 0000000..81cf860
--- /dev/null
@@ -0,0 +1,90 @@
+diff --git a/extract.c b/extract.c
+index eeb2f57..a0a4929 100644
+--- a/extract.c
++++ b/extract.c
+@@ -472,8 +472,8 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+                      */
+                     Info(slide, 0x401, ((char *)slide,
+                       LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
+-                    Info(slide, 0x401, ((char *)slide,
+-                      LoadFarString(ReportMsg)));
++                    Info(slide, 0x401,
++                         ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                     error_in_archive = PK_BADERR;
+                 }
+                 reached_end = TRUE;     /* ...so no more left to do */
+@@ -752,8 +752,8 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+ #ifndef SFX
+     if (no_endsig_found) {                      /* just to make sure */
+-        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
+-        Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
++        Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
++        Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(ReportMsg)));
+         if (!error_in_archive)       /* don't overwrite stronger error */
+             error_in_archive = PK_WARN;
+     }
+diff --git a/list.c b/list.c
+index 15e0011..f7359c3 100644
+--- a/list.c
++++ b/list.c
+@@ -181,7 +181,7 @@ int list_files(__G)    /* return PK-type error code */
+                 Info(slide, 0x401,
+                      ((char *)slide, LoadFarString(CentSigMsg), j));
+                 Info(slide, 0x401,
+-                     ((char *)slide, LoadFarString(ReportMsg)));
++                     ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                 return PK_BADERR;   /* sig not found */
+             }
+         }
+@@ -507,7 +507,8 @@ int list_files(__G)    /* return PK-type error code */
+             && (!G.ecrec.is_zip64_archive)
+             && (memcmp(G.sig, end_central_sig, 4) != 0)
+            ) {          /* just to make sure again */
+-            Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
++            Info(slide, 0x401, 
++                 ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+             error_in_archive = PK_WARN;   /* didn't find sig */
+         }
+@@ -591,7 +592,7 @@ int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
+                 Info(slide, 0x401,
+                      ((char *)slide, LoadFarString(CentSigMsg), j));
+                 Info(slide, 0x401,
+-                     ((char *)slide, LoadFarString(ReportMsg)));
++                     ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                 return PK_BADERR;   /* sig not found */
+             }
+         }
+@@ -674,7 +675,7 @@ int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
+   ---------------------------------------------------------------------------*/
+     if (memcmp(G.sig, end_central_sig, 4)) {    /* just to make sure again */
+-        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
++        Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+         error_in_archive = PK_WARN;
+     }
+     if (*nmember == 0L && error_in_archive <= PK_WARN)
+diff --git a/zipinfo.c b/zipinfo.c
+index 6e22cc8..ac5c61b 100644
+--- a/zipinfo.c
++++ b/zipinfo.c
+@@ -771,7 +771,7 @@ int zipinfo(__G)   /* return PK-type error code */
+                 Info(slide, 0x401,
+                      ((char *)slide, LoadFarString(CentSigMsg), j));
+                 Info(slide, 0x401,
+-                     ((char *)slide, LoadFarString(ReportMsg)));
++                     ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                 error_in_archive = PK_BADERR;   /* sig not found */
+                 break;
+             }
+@@ -960,7 +960,8 @@ int zipinfo(__G)   /* return PK-type error code */
+             && (!G.ecrec.is_zip64_archive)
+             && (memcmp(G.sig, end_central_sig, 4) != 0)
+            ) {          /* just to make sure again */
+-            Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
++            Info(slide, 0x401, 
++                 ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+             error_in_archive = PK_WARN;   /* didn't find sig */
+         }
index 9a1ab51b9f011d2c03f8f4994156f4d075789b8e..2520810003c6165305978f15c4641b2ea852a165 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = unzip
 version    = 6.0
-release    = 3
+release    = 4
 
 groups     = Applications/Archiving
 url        = ftp://ftp.info-zip.org/pub/infozip/src/
index ec0e486337ac1328fe3a5c7306d412e1a0cbd81f..2dded3517824d8051187a1039af8477279ab3d46 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = xfsprogs
-version    = 3.1.8
+version    = 3.2.2
 release    = 1
 
 groups     = System/Filesystems
index 12c0f936cf821f93d365664159707a928cd4ca84..a24d20d485ce82711d11b09bcba9b0936ece6790 100644 (file)
@@ -4,7 +4,7 @@
 ###############################################################################
 
 name       = xmlto
-version    = 0.0.25
+version    = 0.0.26
 release    = 1
 
 groups     = Applications/System