]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Hannes Reinecke <hare@suse.de> |
2 | Subject: DM-MPIO fails to tresspass LUNs on CLARiiON arrays | |
3 | Reference: bnc#484529 | |
4 | ||
5 | On Clariion arrays we fail to send the trespass command correctly. | |
6 | We're trying to send the trespass command to via an disabled path, | |
7 | causing the device handler to loop trying to send the command on | |
8 | an invalid path. | |
9 | ||
10 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
11 | ||
12 | --- | |
13 | drivers/md/dm-mpath.c | 22 ++++++++++++++++------ | |
14 | 1 file changed, 16 insertions(+), 6 deletions(-) | |
15 | ||
16 | --- a/drivers/md/dm-mpath.c | |
17 | +++ b/drivers/md/dm-mpath.c | |
18 | @@ -462,6 +462,9 @@ static void process_queued_ios(struct wo | |
19 | m->pg_init_count++; | |
20 | m->pg_init_required = 0; | |
21 | list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) { | |
22 | + /* Skip disabled paths */ | |
23 | + if (!tmp->path.dev) | |
24 | + continue; | |
25 | queue_work(kmpath_handlerd, &tmp->activate_path); | |
26 | m->pg_init_in_progress++; | |
27 | } | |
28 | @@ -1120,9 +1123,8 @@ static int pg_init_limit_reached(struct | |
29 | return limit_reached; | |
30 | } | |
31 | ||
32 | -static void pg_init_done(struct dm_path *path, int errors) | |
33 | +static void pg_init_done(struct pgpath *pgpath, int errors) | |
34 | { | |
35 | - struct pgpath *pgpath = path_to_pgpath(path); | |
36 | struct priority_group *pg = pgpath->pg; | |
37 | struct multipath *m = pg->m; | |
38 | unsigned long flags; | |
39 | @@ -1136,8 +1138,8 @@ static void pg_init_done(struct dm_path | |
40 | errors = 0; | |
41 | break; | |
42 | } | |
43 | - DMERR("Cannot failover device because scsi_dh_%s was not " | |
44 | - "loaded.", m->hw_handler_name); | |
45 | + DMERR("Cannot failover device %s because scsi_dh_%s was not " | |
46 | + "loaded.", pgpath->path.pdev, m->hw_handler_name); | |
47 | /* | |
48 | * Fail path for now, so we do not ping pong | |
49 | */ | |
50 | @@ -1150,6 +1152,10 @@ static void pg_init_done(struct dm_path | |
51 | */ | |
52 | bypass_pg(m, pg, 1); | |
53 | break; | |
54 | + case SCSI_DH_DEV_OFFLINED: | |
55 | + DMWARN("Device %s offlined.", pgpath->path.pdev); | |
56 | + errors = 0; | |
57 | + break; | |
58 | /* TODO: For SCSI_DH_RETRY we should wait a couple seconds */ | |
59 | case SCSI_DH_RETRY: | |
60 | case SCSI_DH_IMM_RETRY: | |
61 | @@ -1169,7 +1175,8 @@ static void pg_init_done(struct dm_path | |
62 | ||
63 | spin_lock_irqsave(&m->lock, flags); | |
64 | if (errors) { | |
65 | - DMERR("Could not failover device. Error %d.", errors); | |
66 | + DMERR("Could not failover device %s. Error %d.", | |
67 | + pgpath->path.pdev, errors); | |
68 | m->current_pgpath = NULL; | |
69 | m->current_pg = NULL; | |
70 | } else if (!m->pg_init_required) { | |
71 | @@ -1191,7 +1198,10 @@ static void activate_path(struct work_st | |
72 | ||
73 | if (pgpath->path.dev) | |
74 | ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev)); | |
75 | - pg_init_done(&pgpath->path, ret); | |
76 | + else | |
77 | + DMWARN("Activate offlined path %s", pgpath->path.pdev); | |
78 | + | |
79 | + pg_init_done(pgpath, ret); | |
80 | } | |
81 | ||
82 | /* |