zipl_helper.device-mapper: check status of "mirror" dm targets

For "mirror" device-mapper targets:

. Check status of all the mirrors;
. Return error if some mirror contain failures;
. Align the sample output properly

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Eduard Shishkin
2024-05-23 16:08:33 +02:00
committed by Steffen Eiden
parent 283a61dc2f
commit 0eeab96f0d

View File

@@ -460,6 +460,63 @@ static struct util_list *get_linear_data(const char *devname, char *args)
} \
} while (0)
static int check_mirror_status(const char *devname)
{
char *line = NULL;
size_t n = 0;
int ret = -1;
FILE *fp;
fp = exec_cmd_and_get_out_stream("dmsetup status /dev/%s 2>/dev/null",
devname);
if (fp == NULL) {
ERR("Failed to get mirror status\n");
return -1;
}
while (getline(&line, &n, fp) != -1) {
char *status = NULL;
char *token = NULL;
long cnt;
int i;
/* Sample output (single line):
* 0 8192000 mirror \
* 2 253:3 253:7 \
* 8000/8000 1 \
* AA 1 \
* core
*/
STR_TOKEN_OR_GOTO(line, token, out);
SKIP_NEXT_TOKEN_OR_GOTO(out); /* length */
NEXT_STR_TOKEN_OR_GOTO(token, out); /* type */
if (strcmp(token, "mirror") != 0) {
ERR("Unrecognized mirror status\n");
goto out;
}
NEXT_INT_TOKEN_OR_GOTO(cnt, out); /* #nr_mirrors */
SKIP_NEXT_TOKENS_OR_GOTO(cnt, out); /* mirrors */
SKIP_NEXT_TOKENS_OR_GOTO(2, out); /* sync_count, nr_regions */
NEXT_STR_TOKEN_OR_GOTO(status, out); /* status buffer */
for (i = 0; i < cnt; i++) {
if (status[i] != 'A') {
fprintf(stderr,
"%s: Raid inconsistent(some mirrors are not 'alive and in-sync').\n",
devname);
fprintf(stderr,
"Bring it into consistent state first.\n");
goto out;
}
}
}
ret = 0;
out:
free(line);
pclose(fp);
return ret;
}
/*
* There is no kernel documentation for the mirror target. Parameters obtained
* from Linux sources: drivers/md/dm-log.c and drivers/md/dm-raid1.c
@@ -578,15 +635,15 @@ static struct util_list *get_multipath_status(const char *devname)
* E 0 \
* 2 2 \
* 8:16 F 1 \
* 0 1 \
* 8:0 F 1 \
* 0 1 \
* A 0 \
* 2 2 \
* 8:32 A 0 \
* 0 1 \
* 8:48 A 0 \
* 0 1
* 0 1 \
* 8:0 F 1 \
* 0 1 \
* A 0 \
* 2 2 \
* 8:32 A 0 \
* 0 1 \
* 8:48 A 0 \
* 0 1
*/
STR_TOKEN_OR_GOTO(line, token, out);
SKIP_NEXT_TOKEN_OR_GOTO(out); /* length */
@@ -1124,7 +1181,11 @@ static int dm_dev_to_zipl_params(struct ext_dev *dev, char *dir)
/* check mirror status */
struct target *mt = pd.mirror->target;
struct target_data *mtd = util_list_start(mt->data);
char devname[BDEVNAME_SIZE];
get_device_name(devname, pd.mirror->dev.dev);
if (check_mirror_status(devname))
goto error;
/* Print also parameters for other mirrors */
fail_on_dm_mirrors = 1;