From 668bc6e2f142ed81936329de144f57026c90edf2 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski 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 setmarginal and cleared by multipathd path unsetmarginal All of the marginal paths on a multipath device can be cleared by multipathd 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 --- 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