forked from pool/multipath-tools
83 lines
2.4 KiB
Plaintext
83 lines
2.4 KiB
Plaintext
|
From 23348c651f2c4bc7d41a6aa32957615403cf1533 Mon Sep 17 00:00:00 2001
|
||
|
From: Hannes Reinecke <hare@suse.de>
|
||
|
Date: Tue, 13 Jan 2009 15:32:52 +0100
|
||
|
Subject: [PATCH] Don't run checkers or prio for blocked devices
|
||
|
|
||
|
When a device is in 'blocked' state any I/O to it will be
|
||
|
blocked. Hence multipathd will stall when running the
|
||
|
path checker until the device is unblocked, leaving the
|
||
|
entire mulitpath daemon hanging.
|
||
|
So we have to check for the state and _not_ run any
|
||
|
checker or prioritizer if the device is blocked.
|
||
|
|
||
|
References: bnc#464155
|
||
|
|
||
|
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||
|
---
|
||
|
libmultipath/discovery.c | 35 +++++++++++++++++++++++++++++++++++
|
||
|
1 files changed, 35 insertions(+), 0 deletions(-)
|
||
|
|
||
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||
|
index a18a46a..afd247d 100644
|
||
|
--- a/libmultipath/discovery.c
|
||
|
+++ b/libmultipath/discovery.c
|
||
|
@@ -144,6 +144,7 @@ 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);
|
||
|
|
||
|
int
|
||
|
sysfs_get_dev (struct sysfs_device * dev, char * buff, size_t len)
|
||
|
@@ -688,6 +689,23 @@ get_state (struct path * pp)
|
||
|
|
||
|
condlog(3, "%s: get_state", pp->dev);
|
||
|
|
||
|
+ if (pp->bus == SYSFS_BUS_SCSI && pp->sysdev) {
|
||
|
+ struct sysfs_device *parent;
|
||
|
+ char dev_state[32];
|
||
|
+
|
||
|
+ /* check device state */
|
||
|
+ parent = sysfs_device_get_parent(pp->sysdev);
|
||
|
+ if (parent && !strncmp(parent->kernel, "block", 5))
|
||
|
+ parent = sysfs_device_get_parent(parent);
|
||
|
+ if (parent && !sysfs_get_state(parent, dev_state, 32)) {
|
||
|
+ if (!strncmp(dev_state, "blocked", 7)) {
|
||
|
+ condlog(3, "%s: device blocked", pp->dev);
|
||
|
+ pp->state = PATH_DOWN;
|
||
|
+ pp->priority = 0;
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
if (!checker_selected(c)) {
|
||
|
select_checker(pp);
|
||
|
if (!checker_selected(c)) {
|
||
|
@@ -714,6 +732,23 @@ get_prio (struct path * pp)
|
||
|
if (!pp)
|
||
|
return 0;
|
||
|
|
||
|
+ if (pp->bus == SYSFS_BUS_SCSI && pp->sysdev) {
|
||
|
+ struct sysfs_device *parent;
|
||
|
+ char dev_state[32];
|
||
|
+
|
||
|
+ /* check device state */
|
||
|
+ parent = sysfs_device_get_parent(pp->sysdev);
|
||
|
+ if (parent && !strncmp(parent->kernel, "block", 5))
|
||
|
+ parent = sysfs_device_get_parent(parent);
|
||
|
+ if (parent && !sysfs_get_state(parent, dev_state, 32)) {
|
||
|
+ if (!strncmp(dev_state, "blocked", 7)) {
|
||
|
+ condlog(3, "%s: device blocked", pp->dev);
|
||
|
+ pp->priority = PRIO_UNDEF;
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if (!pp->prio) {
|
||
|
select_prio(pp);
|
||
|
if (!pp->prio) {
|
||
|
--
|
||
|
1.5.3.2
|
||
|
|