From: Hannes Reinecke Subject: DM-MPIO fails to tresspass LUNs on CLARiiON arrays Reference: bnc#484529 On Clariion arrays we fail to send the trespass command correctly. We're trying to send the trespass command to via an disabled path, causing the device handler to loop trying to send the command on an invalid path. Signed-off-by: Hannes Reinecke --- drivers/md/dm-mpath.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -462,6 +462,9 @@ static void process_queued_ios(struct wo m->pg_init_count++; m->pg_init_required = 0; list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) { + /* Skip disabled paths */ + if (!tmp->path.dev) + continue; queue_work(kmpath_handlerd, &tmp->activate_path); m->pg_init_in_progress++; } @@ -1109,9 +1112,8 @@ static int pg_init_limit_reached(struct return limit_reached; } -static void pg_init_done(struct dm_path *path, int errors) +static void pg_init_done(struct pgpath *pgpath, int errors) { - struct pgpath *pgpath = path_to_pgpath(path); struct priority_group *pg = pgpath->pg; struct multipath *m = pg->m; unsigned long flags; @@ -1125,8 +1127,8 @@ static void pg_init_done(struct dm_path errors = 0; break; } - DMERR("Cannot failover device because scsi_dh_%s was not " - "loaded.", m->hw_handler_name); + DMERR("Cannot failover device %s because scsi_dh_%s was not " + "loaded.", pgpath->path.pdev, m->hw_handler_name); /* * Fail path for now, so we do not ping pong */ @@ -1139,6 +1141,10 @@ static void pg_init_done(struct dm_path */ bypass_pg(m, pg, 1); break; + case SCSI_DH_DEV_OFFLINED: + DMWARN("Device %s offlined.", pgpath->path.pdev); + errors = 0; + break; /* TODO: For SCSI_DH_RETRY we should wait a couple seconds */ case SCSI_DH_RETRY: case SCSI_DH_IMM_RETRY: @@ -1158,7 +1164,8 @@ static void pg_init_done(struct dm_path spin_lock_irqsave(&m->lock, flags); if (errors) { - DMERR("Could not failover device. Error %d.", errors); + DMERR("Could not failover device %s. Error %d.", + pgpath->path.pdev, errors); m->current_pgpath = NULL; m->current_pg = NULL; } else if (!m->pg_init_required) { @@ -1180,7 +1187,10 @@ static void activate_path(struct work_st if (pgpath->path.dev) ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev)); - pg_init_done(&pgpath->path, ret); + else + DMWARN("Activate offlined path %s", pgpath->path.pdev); + + pg_init_done(pgpath, ret); } /*