dm mpath: allow table load with no priority groups

This patch adjusts the multipath target to allow a table with both 0
priority groups and 0 for the initial priority group number.

If any mpath device is held open when all paths in the last priority
group have failed, userspace multipathd will attempt to reload the
associated DM table to reflect the fact that the device no longer has
any priority groups. But the reload attempt always failed because the
multipath target did not allow 0 priority groups.

All multipath target messages related to priority group (enable_group,
disable_group, switch_group) will handle a priority group of 0 (will
cause error).

When reloading a multipath table with 0 priority groups, userspace
multipathd must be updated to specify an initial priority group number
of 0 (rather than 1).

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Cc: Babu Moger <babu.moger@lsi.com>
Acked-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

authored by Mike Snitzer and committed by Alasdair G Kergon a490a07a 19040c0b

+10 -3
+10 -3
drivers/md/dm-mpath.c
··· 844 { 845 /* target parameters */ 846 static struct param _params[] = { 847 - {1, 1024, "invalid number of priority groups"}, 848 - {1, 1024, "invalid initial priority group number"}, 849 }; 850 851 int r; ··· 878 r = read_param(_params + 1, shift(&as), &next_pg_num, &ti->error); 879 if (r) 880 goto bad; 881 882 /* parse the priority groups */ 883 while (as.argc) { ··· 1422 else if (m->current_pg) 1423 pg_num = m->current_pg->pg_num; 1424 else 1425 - pg_num = 1; 1426 1427 DMEMIT("%u ", pg_num); 1428
··· 844 { 845 /* target parameters */ 846 static struct param _params[] = { 847 + {0, 1024, "invalid number of priority groups"}, 848 + {0, 1024, "invalid initial priority group number"}, 849 }; 850 851 int r; ··· 878 r = read_param(_params + 1, shift(&as), &next_pg_num, &ti->error); 879 if (r) 880 goto bad; 881 + 882 + if ((!m->nr_priority_groups && next_pg_num) || 883 + (m->nr_priority_groups && !next_pg_num)) { 884 + ti->error = "invalid initial priority group"; 885 + r = -EINVAL; 886 + goto bad; 887 + } 888 889 /* parse the priority groups */ 890 while (as.argc) { ··· 1415 else if (m->current_pg) 1416 pg_num = m->current_pg->pg_num; 1417 else 1418 + pg_num = (m->nr_priority_groups ? 1 : 0); 1419 1420 DMEMIT("%u ", pg_num); 1421