From: Lars Marowsky-Bree <[email-masked]>

DM multipath error messages were beyond useless.
---

Index: linux-2.6.16-rc1/drivers/md/dm-emc.c
===================================================================
--- linux-2.6.16-rc1.orig/drivers/md/dm-emc.c
+++ linux-2.6.16-rc1/drivers/md/dm-emc.c
@@ -39,6 +39,8 @@ static inline void free_bio(struct bio *
 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 @@ static int emc_endio(struct bio *bio, un
 	 *
 	 * 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 @@ static int emc_create(struct hw_handler 
 	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 @@ static unsigned emc_error(struct hw_hand
 
 	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 @@ static unsigned emc_error(struct hw_hand
 			 * 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
Index: linux-2.6.16-rc1/drivers/md/dm-hw-handler.c
===================================================================
--- linux-2.6.16-rc1.orig/drivers/md/dm-hw-handler.c
+++ linux-2.6.16-rc1/drivers/md/dm-hw-handler.c
@@ -160,6 +160,9 @@ unsigned dm_scsi_err_handler(struct hw_h
 		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.
 			 * So no point retrying on another path. */
Index: linux-2.6.16-rc1/drivers/md/dm-mpath.c
===================================================================
--- linux-2.6.16-rc1.orig/drivers/md/dm-mpath.c
+++ linux-2.6.16-rc1/drivers/md/dm-mpath.c
@@ -535,8 +535,10 @@ static struct pgpath *parse_path(struct 
 	}
 
 	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);
@@ -545,6 +547,7 @@ static struct pgpath *parse_path(struct 
 		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);
@@ -584,6 +587,7 @@ static struct priority_group *parse_prio
 	}
 	pg->m = m;
 
+	ti->error = ESTR("failure parsing PG path selector");
 	r = parse_path_selector(as, pg, ti);
 	if (r)
 		goto bad;
@@ -600,16 +604,20 @@ static struct priority_group *parse_prio
 		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;
@@ -732,6 +740,7 @@ static int multipath_ctr(struct dm_targe
 	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;
@@ -808,7 +817,7 @@ static int fail_path(struct pgpath *pgpa
 	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;
@@ -896,6 +905,7 @@ static void bypass_pg(struct multipath *
 
 	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;
@@ -974,11 +984,18 @@ void dm_pg_init_complete(struct path *pa
 	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) {
@@ -1011,8 +1028,14 @@ static int do_end_io(struct multipath *m
 	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_irqsave(&m->lock, flags);
 	if (!m->nr_valid_paths) {
+		DMWARN("dm-multipath: no valid paths left");
+
 		if (!m->queue_if_no_path) {
 			spin_unlock_irqrestore(&m->lock, flags);
 			return -EIO;
@@ -1046,6 +1069,8 @@ static int do_end_io(struct multipath *m
 	spin_lock_irqsave(&m->lock, flags);
 	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_irqrestore(&m->lock, flags);