1
0
multipath-tools/multipath-tools-dont-run-checkers-for-blocked-devices

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