|
|
4728c8 |
---
|
|
|
4728c8 |
libmultipath/configure.c | 2 -
|
|
|
4728c8 |
libmultipath/propsel.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
4728c8 |
2 files changed, 59 insertions(+), 1 deletion(-)
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/configure.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/configure.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/configure.c
|
|
|
4728c8 |
@@ -282,6 +282,7 @@ setup_map (struct multipath * mpp, char
|
|
|
4728c8 |
select_pgpolicy(mpp);
|
|
|
4728c8 |
select_selector(mpp);
|
|
|
4728c8 |
select_features(mpp);
|
|
|
4728c8 |
+ select_retain_hwhandler(mpp);
|
|
|
4728c8 |
select_hwhandler(mpp);
|
|
|
4728c8 |
select_rr_weight(mpp);
|
|
|
4728c8 |
select_minio(mpp);
|
|
|
4728c8 |
@@ -293,7 +294,6 @@ setup_map (struct multipath * mpp, char
|
|
|
4728c8 |
select_fast_io_fail(mpp);
|
|
|
4728c8 |
select_dev_loss(mpp);
|
|
|
4728c8 |
select_reservation_key(mpp);
|
|
|
4728c8 |
- select_retain_hwhandler(mpp);
|
|
|
4728c8 |
select_deferred_remove(mpp);
|
|
|
4728c8 |
select_delay_watch_checks(mpp);
|
|
|
4728c8 |
select_delay_wait_checks(mpp);
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/propsel.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/propsel.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/propsel.c
|
|
|
4728c8 |
@@ -19,6 +19,8 @@
|
|
|
4728c8 |
#include "discovery.h"
|
|
|
4728c8 |
#include "prioritizers/alua_rtpg.h"
|
|
|
4728c8 |
#include "prkey.h"
|
|
|
4728c8 |
+#include "sysfs.h"
|
|
|
4728c8 |
+#include "util.h"
|
|
|
4728c8 |
#include <inttypes.h>
|
|
|
4728c8 |
#include <libudev.h>
|
|
|
4728c8 |
#include <mpath_persist.h>
|
|
|
4728c8 |
@@ -317,9 +319,65 @@ select_features (struct multipath * mp)
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
+static int get_dh_state(struct path *pp, char *value, size_t value_len)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ int ret;
|
|
|
4728c8 |
+ struct udev_device *ud;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (pp->udev == NULL)
|
|
|
4728c8 |
+ return -1;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ ud = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi",
|
|
|
4728c8 |
+ "scsi_device");
|
|
|
4728c8 |
+ if (ud == NULL)
|
|
|
4728c8 |
+ return -1;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ ret = sysfs_attr_get_value(ud, "dh_state", value, value_len);
|
|
|
4728c8 |
+ if (ret > 0)
|
|
|
4728c8 |
+ strchop(value);
|
|
|
4728c8 |
+ return ret;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+static int
|
|
|
4728c8 |
+use_attached_hwhandler(struct multipath * mp)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ int i;
|
|
|
4728c8 |
+ struct path *pp;
|
|
|
4728c8 |
+ int attached_hwhandler = 0;
|
|
|
4728c8 |
+ /* dh_state is no longer than "detached" */
|
|
|
4728c8 |
+ char dh_state[10];
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ vector_foreach_slot (mp->paths, pp, i) {
|
|
|
4728c8 |
+ if (get_dh_state(pp, dh_state, sizeof(dh_state)) > 0 &&
|
|
|
4728c8 |
+ strcmp(dh_state, "detached") != 0) {
|
|
|
4728c8 |
+ if (!attached_hwhandler) {
|
|
|
4728c8 |
+ if (asprintf(&mp->hwhandler, "1 %s",
|
|
|
4728c8 |
+ dh_state) < 0)
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ attached_hwhandler = 1;
|
|
|
4728c8 |
+ /* if we find 2 different hardware handlers, disable
|
|
|
4728c8 |
+ * retain_attached_hw_handler, and use the configured
|
|
|
4728c8 |
+ * handler */
|
|
|
4728c8 |
+ } else if (strcmp(dh_state, &mp->hwhandler[2]) != 0) {
|
|
|
4728c8 |
+ FREE(mp->hwhandler);
|
|
|
4728c8 |
+ mp->hwhandler = NULL;
|
|
|
4728c8 |
+ mp->retain_hwhandler = RETAIN_HWHANDLER_OFF;
|
|
|
4728c8 |
+ condlog(0, "%s: retain_attached_hw_hander disabled (inconsistent handlers on paths)", mp->alias);
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ return attached_hwhandler;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
extern int
|
|
|
4728c8 |
select_hwhandler (struct multipath * mp)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
+ if (mp->retain_hwhandler == RETAIN_HWHANDLER_ON &&
|
|
|
4728c8 |
+ use_attached_hwhandler(mp)) {
|
|
|
4728c8 |
+ condlog(3, "%s: hwhandler = %s (setting: retained by kernel driver)", mp->alias, mp->hwhandler);
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
if (mp->hwe && mp->hwe->hwhandler) {
|
|
|
4728c8 |
mp->hwhandler = mp->hwe->hwhandler;
|
|
|
4728c8 |
condlog(3, "%s: hwhandler = %s (controller setting)",
|