DM multipath error messages were beyond useless. From: Lars Marowsky-Bree --- diff/drivers/md/dm-emc.c 2005-07-06 17:19:06.000000000 +0100 +++ source/drivers/md/dm-emc.c 2005-07-06 17:19:12.000000000 +0100 @@ -39,6 +39,8 @@ static int emc_endio(struct bio *bio, unsigned int bytes_done, int error) { struct path *path = bio->bi_private; + int sense; + int err_flags = 0; if (bio->bi_size) return 1; @@ -48,10 +50,22 @@ * * For now simple logic: either it works or it doesn't. */ - if (error) - dm_pg_init_complete(path, MP_FAIL_PATH); - else - dm_pg_init_complete(path, 0); + if (error) { + DMWARN("dm-emc: emc_endio: pg_init error %d", error); + if (bio_sense_valid(bio)) { + sense = bio_sense_value(bio); /* sense key/asc/ascq */ + DMWARN("dm-emc: emc_endio: " + "found valid sense data %06x", sense); + if (sense == 0x050400) { + DMWARN("dm-emc: emc_endio: " + "array-based copy in progress"); + err_flags = MP_BYPASS_PG; + } else + err_flags = MP_FAIL_PATH; + } + } + + dm_pg_init_complete(path, err_flags); /* request is freed in block layer */ free_bio(bio); @@ -271,7 +285,7 @@ if ((h->hr = hr)) DMWARN("dm-emc: honor reservation bit will be set"); else - DMWARN("dm-emc: honor reservation bit will not be set (default)"); + DMWARN("dm-emc: honor reservation bit will not be set"); return 0; } @@ -290,6 +304,8 @@ if (bio_sense_valid(bio)) { sense = bio_sense_value(bio); /* sense key / asc / ascq */ + DMWARN("dm-emc: emc_err: Found valid sense data %06x " + "for sector %llu", sense, bio->bi_sector); if (sense == 0x020403) { /* LUN Not Ready - Manual Intervention Required @@ -300,6 +316,8 @@ * progress, we should set FAIL_PATH too. * This indicates we might have to do a SCSI * inquiry in the end_io path. Ugh. */ + DMWARN("dm-emc: emc_err: Forcing bypassing of PG " + "in response to LU Not Ready"); return MP_BYPASS_PG; } else if (sense == 0x052501) { /* An array based copy is in progress. Do not --- diff/drivers/md/dm-hw-handler.c 2005-07-06 17:19:06.000000000 +0100 +++ source/drivers/md/dm-hw-handler.c 2005-07-06 17:19:12.000000000 +0100 @@ -159,6 +159,9 @@ sense_key = (bio_sense_value(bio) >> 16) & 0xff; asc = (bio_sense_value(bio) >> 8) & 0xff; ascq = bio_sense_value(bio) & 0xff; + + DMWARN("dm_scsi_err_handler: Parsing sense %02x/%02x/%02x for sector %llu", + sense_key, asc, ascq, bio->bi_sector); switch (sense_key) { /* This block as a whole comes from the device. --- diff/drivers/md/dm-mpath.c 2005-07-06 17:18:50.000000000 +0100 +++ source/drivers/md/dm-mpath.c 2005-07-06 17:19:12.000000000 +0100 @@ -522,8 +522,10 @@ } p = alloc_pgpath(); - if (!p) + if (!p) { + ti->error = ESTR("failed to allocate pgpath structure"); return NULL; + } r = dm_get_device(ti, shift(as), ti->begin, ti->len, dm_table_get_mode(ti->table), &p->path.dev); @@ -532,6 +534,7 @@ goto bad; } + ti->error = ESTR("path selector add_path failed"); r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); if (r) { dm_put_device(ti, p->path.dev); @@ -571,6 +574,7 @@ } pg->m = m; + ti->error = ESTR("failure parsing PG path selector"); r = parse_path_selector(as, pg, ti); if (r) goto bad; @@ -587,16 +591,20 @@ goto bad; nr_params = 1 + nr_selector_args; + for (i = 0; i < pg->nr_pgpaths; i++) { struct pgpath *pgpath; struct arg_set path_args; - if (as->argc < nr_params) + if (as->argc < nr_params) { + ti->error = ESTR("path selector argument count mismatch"); goto bad; + } path_args.argc = nr_params; path_args.argv = as->argv; + ti->error = ESTR("failure parsing PG path"); pgpath = parse_path(&path_args, &pg->ps, ti); if (!pgpath) goto bad; @@ -719,6 +727,7 @@ while (as.argc) { struct priority_group *pg; + ti->error = ESTR("failure parsing priority group"); pg = parse_priority_group(&as, m, ti); if (!pg) { r = -EINVAL; @@ -793,7 +802,7 @@ if (!pgpath->path.is_active) goto out; - DMWARN("dm-multipath: Failing path %s.", pgpath->path.dev->name); + DMWARN("dm-multipath: Failing path %s", pgpath->path.dev->name); pgpath->pg->ps.type->fail_path(&pgpath->pg->ps, &pgpath->path); pgpath->path.is_active = 0; @@ -881,6 +890,7 @@ spin_lock_irqsave(&m->lock, flags); + DMWARN("dm-multipath: bypassing PG %u", pg->pg_num); pg->bypassed = bypassed; m->current_pgpath = NULL; m->current_pg = NULL; @@ -959,11 +969,18 @@ if (err_flags && pg->bypassed) err_flags |= MP_FAIL_PATH; - if (err_flags & MP_FAIL_PATH) + if (err_flags & MP_FAIL_PATH) { + DMWARN("dm-multipath: Error initialising %sPG: failing path %s", + pg->bypassed ? "bypassed " : "", + pgpath->path.dev->name); fail_path(pgpath); - - if (err_flags & MP_BYPASS_PG) + } + + if ((err_flags & MP_BYPASS_PG) && !pg->bypassed) { + DMWARN("dm-multipath: Error initialising PG on %s: ", + pgpath->path.dev->name); bypass_pg(m, pg, 1); + } spin_lock_irqsave(&m->lock, flags); if (!err_flags) @@ -994,8 +1011,14 @@ if (error == -EOPNOTSUPP) return error; + DMWARN("dm-multipath: IO error on path %s, sector %llu", + mpio->pgpath ? mpio->pgpath->path.dev->name : "NULL", + bio->bi_sector); + spin_lock(&m->lock); if (!m->nr_valid_paths) { + DMWARN("dm-multipath: no valid paths left"); + if (!m->queue_if_no_path || m->suspended) { spin_unlock(&m->lock); return -EIO; @@ -1027,6 +1050,8 @@ spin_lock(&m->lock); bio_list_add(&m->queued_ios, bio); m->queue_size++; + DMINFO("multipath_end_io: Requeued sector %llu as #%u", bio->bi_sector, + m->queue_size); if (!m->queue_io) queue_work(kmultipathd, &m->process_queued_ios); spin_unlock(&m->lock);