302 lines
9.1 KiB
Diff
302 lines
9.1 KiB
Diff
|
From 668bc6e2f142ed81936329de144f57026c90edf2 Mon Sep 17 00:00:00 2001
|
||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||
|
Date: Mon, 1 Jul 2019 15:19:29 -0500
|
||
|
Subject: [PATCH] libmultipath: add marginal paths and groups infrastructure
|
||
|
|
||
|
This commit adds a marginal variable ot the paths and pathgroups structs.
|
||
|
The marginal paths variable can be set by
|
||
|
|
||
|
multipathd path <path> setmarginal
|
||
|
|
||
|
and cleared by
|
||
|
|
||
|
multipathd path <path> unsetmarginal
|
||
|
|
||
|
All of the marginal paths on a multipath device can be cleared by
|
||
|
|
||
|
multipathd map <map> unsetmarginal
|
||
|
|
||
|
Currently, the marginal variable of a pathgroup will not change. This
|
||
|
will be added by a future commit. The marginal state of a path or
|
||
|
pathgroup is printable with the %M wildcard, and is displayed in the
|
||
|
json output.
|
||
|
|
||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||
|
---
|
||
|
libmultipath/print.c | 18 ++++++++
|
||
|
libmultipath/print.h | 6 ++-
|
||
|
libmultipath/structs.h | 2 +
|
||
|
multipathd/cli.c | 5 +++
|
||
|
multipathd/cli.h | 4 ++
|
||
|
multipathd/cli_handlers.c | 91 +++++++++++++++++++++++++++++++++++++++
|
||
|
multipathd/cli_handlers.h | 3 ++
|
||
|
multipathd/main.c | 3 ++
|
||
|
8 files changed, 130 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||
|
index fc40b0f0..907469ad 100644
|
||
|
--- a/libmultipath/print.c
|
||
|
+++ b/libmultipath/print.c
|
||
|
@@ -502,6 +502,14 @@ snprint_pg_state (char * buff, size_t len, const struct pathgroup * pgp)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+snprint_pg_marginal (char * buff, size_t len, const struct pathgroup * pgp)
|
||
|
+{
|
||
|
+ if (pgp->marginal)
|
||
|
+ return snprintf(buff, len, "marginal");
|
||
|
+ return snprintf(buff, len, "normal");
|
||
|
+}
|
||
|
+
|
||
|
static int
|
||
|
snprint_path_size (char * buff, size_t len, const struct path * pp)
|
||
|
{
|
||
|
@@ -672,6 +680,14 @@ snprint_path_protocol(char * buff, size_t len, const struct path * pp)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+int
|
||
|
+snprint_path_marginal(char * buff, size_t len, const struct path * pp)
|
||
|
+{
|
||
|
+ if (pp->marginal)
|
||
|
+ return snprintf(buff, len, "marginal");
|
||
|
+ return snprintf(buff, len, "normal");
|
||
|
+}
|
||
|
+
|
||
|
struct multipath_data mpd[] = {
|
||
|
{'n', "name", 0, snprint_name},
|
||
|
{'w', "uuid", 0, snprint_multipath_uuid},
|
||
|
@@ -713,6 +729,7 @@ struct path_data pd[] = {
|
||
|
{'p', "pri", 0, snprint_pri},
|
||
|
{'S', "size", 0, snprint_path_size},
|
||
|
{'z', "serial", 0, snprint_path_serial},
|
||
|
+ {'M', "marginal_st", 0, snprint_path_marginal},
|
||
|
{'m', "multipath", 0, snprint_path_mpp},
|
||
|
{'N', "host WWNN", 0, snprint_host_wwnn},
|
||
|
{'n', "target WWNN", 0, snprint_tgt_wwnn},
|
||
|
@@ -729,6 +746,7 @@ struct pathgroup_data pgd[] = {
|
||
|
{'s', "selector", 0, snprint_pg_selector},
|
||
|
{'p', "pri", 0, snprint_pg_pri},
|
||
|
{'t', "dm_st", 0, snprint_pg_state},
|
||
|
+ {'M', "marginal_st", 0, snprint_pg_marginal},
|
||
|
{0, NULL, 0 , NULL}
|
||
|
};
|
||
|
|
||
|
diff --git a/libmultipath/print.h b/libmultipath/print.h
|
||
|
index e2fb865c..7e36ec63 100644
|
||
|
--- a/libmultipath/print.h
|
||
|
+++ b/libmultipath/print.h
|
||
|
@@ -50,7 +50,8 @@
|
||
|
#define PRINT_JSON_GROUP "{\n" \
|
||
|
" \"selector\" : \"%s\",\n" \
|
||
|
" \"pri\" : %p,\n" \
|
||
|
- " \"dm_st\" : \"%t\","
|
||
|
+ " \"dm_st\" : \"%t\",\n" \
|
||
|
+ " \"marginal_st\" : \"%M\","
|
||
|
|
||
|
#define PRINT_JSON_GROUP_NUM " \"group\" : %d,\n"
|
||
|
|
||
|
@@ -66,7 +67,8 @@
|
||
|
" \"target_wwnn\" : \"%n\",\n" \
|
||
|
" \"host_wwpn\" : \"%R\",\n" \
|
||
|
" \"target_wwpn\" : \"%r\",\n" \
|
||
|
- " \"host_adapter\" : \"%a\""
|
||
|
+ " \"host_adapter\" : \"%a\",\n" \
|
||
|
+ " \"marginal_st\" : \"%M\""
|
||
|
|
||
|
#define MAX_LINE_LEN 80
|
||
|
#define MAX_LINES 64
|
||
|
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||
|
index 7879d763..1a3d827b 100644
|
||
|
--- a/libmultipath/structs.h
|
||
|
+++ b/libmultipath/structs.h
|
||
|
@@ -289,6 +289,7 @@ struct path {
|
||
|
int io_err_pathfail_cnt;
|
||
|
int io_err_pathfail_starttime;
|
||
|
int find_multipaths_timeout;
|
||
|
+ int marginal;
|
||
|
/* configlet pointers */
|
||
|
vector hwe;
|
||
|
struct gen_path generic_path;
|
||
|
@@ -403,6 +404,7 @@ struct pathgroup {
|
||
|
int status;
|
||
|
int priority;
|
||
|
int enabled_paths;
|
||
|
+ int marginal;
|
||
|
vector paths;
|
||
|
struct multipath *mpp;
|
||
|
struct gen_pathgroup generic_pg;
|
||
|
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
||
|
index 17795b61..800c0fbe 100644
|
||
|
--- a/multipathd/cli.c
|
||
|
+++ b/multipathd/cli.c
|
||
|
@@ -215,6 +215,8 @@ load_keys (void)
|
||
|
r += add_key(keys, "unsetprkey", UNSETPRKEY, 0);
|
||
|
r += add_key(keys, "key", KEY, 1);
|
||
|
r += add_key(keys, "local", LOCAL, 0);
|
||
|
+ r += add_key(keys, "setmarginal", SETMARGINAL, 0);
|
||
|
+ r += add_key(keys, "unsetmarginal", UNSETMARGINAL, 0);
|
||
|
|
||
|
|
||
|
if (r) {
|
||
|
@@ -589,6 +591,9 @@ cli_init (void) {
|
||
|
add_handler(UNSETPRKEY+MAP, NULL);
|
||
|
add_handler(FORCEQ+DAEMON, NULL);
|
||
|
add_handler(RESTOREQ+DAEMON, NULL);
|
||
|
+ add_handler(SETMARGINAL+PATH, NULL);
|
||
|
+ add_handler(UNSETMARGINAL+PATH, NULL);
|
||
|
+ add_handler(UNSETMARGINAL+MAP, NULL);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
diff --git a/multipathd/cli.h b/multipathd/cli.h
|
||
|
index 32dcffac..fdfb9aed 100644
|
||
|
--- a/multipathd/cli.h
|
||
|
+++ b/multipathd/cli.h
|
||
|
@@ -45,6 +45,8 @@ enum {
|
||
|
__UNSETPRKEY,
|
||
|
__KEY,
|
||
|
__LOCAL,
|
||
|
+ __SETMARGINAL,
|
||
|
+ __UNSETMARGINAL,
|
||
|
};
|
||
|
|
||
|
#define LIST (1 << __LIST)
|
||
|
@@ -89,6 +91,8 @@ enum {
|
||
|
#define UNSETPRKEY (1ULL << __UNSETPRKEY)
|
||
|
#define KEY (1ULL << __KEY)
|
||
|
#define LOCAL (1ULL << __LOCAL)
|
||
|
+#define SETMARGINAL (1ULL << __SETMARGINAL)
|
||
|
+#define UNSETMARGINAL (1ULL << __UNSETMARGINAL)
|
||
|
|
||
|
#define INITIAL_REPLY_LEN 1200
|
||
|
|
||
|
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||
|
index 4c32d953..8a899049 100644
|
||
|
--- a/multipathd/cli_handlers.c
|
||
|
+++ b/multipathd/cli_handlers.c
|
||
|
@@ -1537,3 +1537,94 @@ cli_setprkey(void * v, char ** reply, int * len, void * data)
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
+
|
||
|
+int cli_set_marginal(void * v, char ** reply, int * len, void * data)
|
||
|
+{
|
||
|
+ struct vectors * vecs = (struct vectors *)data;
|
||
|
+ char * param = get_keyparam(v, PATH);
|
||
|
+ struct path * pp;
|
||
|
+
|
||
|
+ param = convert_dev(param, 1);
|
||
|
+ pp = find_path_by_dev(vecs->pathvec, param);
|
||
|
+
|
||
|
+ if (!pp)
|
||
|
+ pp = find_path_by_devt(vecs->pathvec, param);
|
||
|
+
|
||
|
+ if (!pp || !pp->mpp || !pp->mpp->alias)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ condlog(2, "%s: set marginal path %s (operator)",
|
||
|
+ pp->mpp->alias, pp->dev_t);
|
||
|
+ if (pp->mpp->wait_for_udev) {
|
||
|
+ condlog(2, "%s: device not fully created, failing set marginal",
|
||
|
+ pp->mpp->alias);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ pp->marginal = 1;
|
||
|
+
|
||
|
+ return update_path_groups(pp->mpp, vecs, 0);
|
||
|
+}
|
||
|
+
|
||
|
+int cli_unset_marginal(void * v, char ** reply, int * len, void * data)
|
||
|
+{
|
||
|
+ struct vectors * vecs = (struct vectors *)data;
|
||
|
+ char * param = get_keyparam(v, PATH);
|
||
|
+ struct path * pp;
|
||
|
+
|
||
|
+ param = convert_dev(param, 1);
|
||
|
+ pp = find_path_by_dev(vecs->pathvec, param);
|
||
|
+
|
||
|
+ if (!pp)
|
||
|
+ pp = find_path_by_devt(vecs->pathvec, param);
|
||
|
+
|
||
|
+ if (!pp || !pp->mpp || !pp->mpp->alias)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ condlog(2, "%s: unset marginal path %s (operator)",
|
||
|
+ pp->mpp->alias, pp->dev_t);
|
||
|
+ if (pp->mpp->wait_for_udev) {
|
||
|
+ condlog(2, "%s: device not fully created, "
|
||
|
+ "failing unset marginal", pp->mpp->alias);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ pp->marginal = 0;
|
||
|
+
|
||
|
+ return update_path_groups(pp->mpp, vecs, 0);
|
||
|
+}
|
||
|
+
|
||
|
+int cli_unset_all_marginal(void * v, char ** reply, int * len, void * data)
|
||
|
+{
|
||
|
+ struct vectors * vecs = (struct vectors *)data;
|
||
|
+ char * mapname = get_keyparam(v, MAP);
|
||
|
+ struct multipath *mpp;
|
||
|
+ struct pathgroup * pgp;
|
||
|
+ struct path * pp;
|
||
|
+ unsigned int i, j;
|
||
|
+ int minor;
|
||
|
+
|
||
|
+ mapname = convert_dev(mapname, 0);
|
||
|
+ condlog(2, "%s: unset all marginal paths (operator)",
|
||
|
+ mapname);
|
||
|
+
|
||
|
+ if (sscanf(mapname, "dm-%d", &minor) == 1)
|
||
|
+ mpp = find_mp_by_minor(vecs->mpvec, minor);
|
||
|
+ else
|
||
|
+ mpp = find_mp_by_alias(vecs->mpvec, mapname);
|
||
|
+
|
||
|
+ if (!mpp) {
|
||
|
+ condlog(0, "%s: invalid map name. "
|
||
|
+ "cannot unset marginal paths", mapname);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ if (mpp->wait_for_udev) {
|
||
|
+ condlog(2, "%s: device not fully created, "
|
||
|
+ "failing unset all marginal", mpp->alias);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ vector_foreach_slot (mpp->pg, pgp, i)
|
||
|
+ vector_foreach_slot (pgp->paths, pp, j)
|
||
|
+ pp->marginal = 0;
|
||
|
+
|
||
|
+ return update_path_groups(mpp, vecs, 0);
|
||
|
+}
|
||
|
diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h
|
||
|
index edbdf063..0f451064 100644
|
||
|
--- a/multipathd/cli_handlers.h
|
||
|
+++ b/multipathd/cli_handlers.h
|
||
|
@@ -49,3 +49,6 @@ int cli_unsetprstatus(void * v, char ** reply, int * len, void * data);
|
||
|
int cli_getprkey(void * v, char ** reply, int * len, void * data);
|
||
|
int cli_setprkey(void * v, char ** reply, int * len, void * data);
|
||
|
int cli_unsetprkey(void * v, char ** reply, int * len, void * data);
|
||
|
+int cli_set_marginal(void * v, char ** reply, int * len, void * data);
|
||
|
+int cli_unset_marginal(void * v, char ** reply, int * len, void * data);
|
||
|
+int cli_unset_all_marginal(void * v, char ** reply, int * len, void * data);
|
||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||
|
index 7a5cd115..7db15736 100644
|
||
|
--- a/multipathd/main.c
|
||
|
+++ b/multipathd/main.c
|
||
|
@@ -1609,6 +1609,9 @@ uxlsnrloop (void * ap)
|
||
|
set_handler_callback(GETPRKEY+MAP, cli_getprkey);
|
||
|
set_handler_callback(SETPRKEY+MAP+KEY, cli_setprkey);
|
||
|
set_handler_callback(UNSETPRKEY+MAP, cli_unsetprkey);
|
||
|
+ set_handler_callback(SETMARGINAL+PATH, cli_set_marginal);
|
||
|
+ set_handler_callback(UNSETMARGINAL+PATH, cli_unset_marginal);
|
||
|
+ set_handler_callback(UNSETMARGINAL+MAP, cli_unset_all_marginal);
|
||
|
|
||
|
umask(077);
|
||
|
uxsock_listen(&uxsock_trigger, ux_sock, ap);
|
||
|
--
|
||
|
2.17.2
|
||
|
|