dm-flakey: Clean up parsing messages

There were a number of cases where the error message for an invalid
table line did not match the actual problem. Fix these. Additionally,
error out when duplicate corrupt_bio_byte, random_read_corrupt, or
random_write_corrupt features are present. Also, error_reads is
incompatible with random_read_corrupt and corrupt_bio_byte with the READ
flag set, so disallow that.

Reported-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
This commit is contained in:
Benjamin Marzinski 2025-04-22 19:47:35 -04:00 committed by Mikulas Patocka
parent d90e7a500c
commit 19da6b2c9e

View File

@ -128,8 +128,11 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
* corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>
*/
if (!strcasecmp(arg_name, "corrupt_bio_byte")) {
if (!argc) {
ti->error = "Feature corrupt_bio_byte requires parameters";
if (fc->corrupt_bio_byte) {
ti->error = "Feature corrupt_bio_byte duplicated";
return -EINVAL;
} else if (argc < 4) {
ti->error = "Feature corrupt_bio_byte requires 4 parameters";
return -EINVAL;
}
@ -176,7 +179,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
}
if (!strcasecmp(arg_name, "random_read_corrupt")) {
if (!argc) {
if (fc->random_read_corrupt) {
ti->error = "Feature random_read_corrupt duplicated";
return -EINVAL;
} else if (!argc) {
ti->error = "Feature random_read_corrupt requires a parameter";
return -EINVAL;
}
@ -189,7 +195,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
}
if (!strcasecmp(arg_name, "random_write_corrupt")) {
if (!argc) {
if (fc->random_write_corrupt) {
ti->error = "Feature random_write_corrupt duplicated";
return -EINVAL;
} else if (!argc) {
ti->error = "Feature random_write_corrupt requires a parameter";
return -EINVAL;
}
@ -205,12 +214,18 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
return -EINVAL;
}
if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
if (test_bit(DROP_WRITES, &fc->flags) &&
(fc->corrupt_bio_rw == WRITE || fc->random_write_corrupt)) {
ti->error = "drop_writes is incompatible with random_write_corrupt or corrupt_bio_byte with the WRITE flag set";
return -EINVAL;
} else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
} else if (test_bit(ERROR_WRITES, &fc->flags) &&
(fc->corrupt_bio_rw == WRITE || fc->random_write_corrupt)) {
ti->error = "error_writes is incompatible with random_write_corrupt or corrupt_bio_byte with the WRITE flag set";
return -EINVAL;
} else if (test_bit(ERROR_READS, &fc->flags) &&
(fc->corrupt_bio_rw == READ || fc->random_read_corrupt)) {
ti->error = "error_reads is incompatible with random_read_corrupt or corrupt_bio_byte with the READ flag set";
return -EINVAL;
}
@ -278,7 +293,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (r)
goto bad;
r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error);
r = dm_read_arg(_args + 1, &as, &fc->down_interval, &ti->error);
if (r)
goto bad;