Change message ioctl to use argc/argv; Remove test implementation from dm-zero; Add reinstate message to dm-mpath. --- diff/drivers/md/dm-ioctl.c 2004-09-28 20:40:32.000000000 +0100 +++ source/drivers/md/dm-ioctl.c 2004-09-28 19:49:52.000000000 +0100 @@ -1102,7 +1102,8 @@ */ static int target_message(struct dm_ioctl *param, size_t param_size) { - int r; + int r, argc; + char **argv; struct mapped_device *md; struct dm_table *table; struct dm_target *ti; @@ -1123,9 +1124,15 @@ goto out; } + r = dm_split_args(&argc, &argv, tmsg->message); + if (r) { + DMWARN("Failed to split target message parameters"); + goto out; + } + table = dm_get_table(md); if (!table) - goto out; + goto out_argv; if (tmsg->sector >= dm_table_get_size(table)) { DMWARN("Target message sector outside device."); @@ -1135,7 +1142,7 @@ ti = dm_table_find_target(table, tmsg->sector); if (ti->type->message) - r = ti->type->message(ti, tmsg->message); + r = ti->type->message(ti, argc, argv); else { DMWARN("Target type does not support messages"); r = -EINVAL; @@ -1143,7 +1150,8 @@ out_table: dm_table_put(table); - + out_argv: + kfree(argv); out: param->data_size = 0; dm_put(md); --- diff/drivers/md/dm-mpath.c 2004-09-28 20:40:32.000000000 +0100 +++ source/drivers/md/dm-mpath.c 2004-09-28 20:41:36.000000000 +0100 @@ -542,6 +542,25 @@ return r; } +/* + * Reinstate all matching failed paths + */ +static int reinstate_dev(struct multipath *m, struct dm_dev *dev) +{ + int r = 0; + struct path *path; + struct priority_group *pg; + + list_for_each_entry(pg, &m->priority_groups, list) { + list_for_each_entry(path, &pg->paths, list) { + if (path->dev == dev) + r = reinstate_path(path); + } + } + + return r; +} + static int do_end_io(struct multipath *m, struct bio *bio, int error, struct mpath_io *mpio) { @@ -647,6 +666,32 @@ return 0; } +static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) +{ + int r; + struct dm_dev *dev; + struct multipath *m = (struct multipath *) ti->private; + + if (argc != 2 || strnicmp(argv[0], "reinstate", 10)) { + DMWARN("Unrecognised multipath message received."); + return -EINVAL; + } + + r = dm_get_device(ti, argv[1], ti->begin, ti->len, + dm_table_get_mode(ti->table), &dev); + if (r) { + DMWARN("dm-multipath message: error getting device %s", + argv[1]); + return -EINVAL; + } + + r = reinstate_dev(m, dev); + + dm_put_device(ti, dev); + + return r; +} + /*----------------------------------------------------------------- * Module setup *---------------------------------------------------------------*/ @@ -659,6 +704,7 @@ .map = multipath_map, .end_io = multipath_end_io, .status = multipath_status, + .message = multipath_message, }; static int __init dm_multipath_init(void) --- diff/drivers/md/dm-table.c 2004-09-28 20:40:32.000000000 +0100 +++ source/drivers/md/dm-table.c 2004-09-28 19:49:55.000000000 +0100 @@ -575,7 +575,7 @@ /* * Destructively splits up the argument list to pass to ctr. */ -static int split_args(int *argc, char ***argvp, char *input) +int dm_split_args(int *argc, char ***argvp, char *input) { char *start, *end = input, *out, **argv = NULL; unsigned array_size = 0; @@ -688,7 +688,7 @@ goto bad; } - r = split_args(&argc, &argv, params); + r = dm_split_args(&argc, &argv, params); if (r) { tgt->error = "couldn't split parameters (insufficient memory)"; goto bad; --- diff/drivers/md/dm-zero.c 2004-09-28 20:40:32.000000000 +0100 +++ source/drivers/md/dm-zero.c 2004-09-28 20:39:55.000000000 +0100 @@ -64,19 +64,12 @@ return 0; } -static int zero_message(struct dm_target *ti, char *message) -{ - DMERR("dm-zero message received: %s", message); - return 0; -} - static struct target_type zero_target = { .name = "zero", .version = {1, 0, 0}, .module = THIS_MODULE, .ctr = zero_ctr, .map = zero_map, - .message = zero_message, }; int __init dm_zero_init(void) --- diff/drivers/md/dm.h 2004-09-28 20:40:32.000000000 +0100 +++ source/drivers/md/dm.h 2004-09-28 19:43:37.000000000 +0100 @@ -165,6 +165,8 @@ return (n << 9); } +int dm_split_args(int *argc, char ***argvp, char *input); + /* * The device-mapper can be driven through one of two interfaces; * ioctl or filesystem, depending which patch you have applied. --- diff/include/linux/device-mapper.h 2004-09-28 20:40:32.000000000 +0100 +++ source/include/linux/device-mapper.h 2004-09-28 19:55:13.000000000 +0100 @@ -57,7 +57,7 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, char *result, unsigned int maxlen); -typedef int (*dm_message_fn) (struct dm_target *ti, char *message); +typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); void dm_error(const char *message);