From 23348c651f2c4bc7d41a6aa32957615403cf1533 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke 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 --- 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