!117 fix CVE-2022-41974

From: @wguanghao 
Reviewed-by: @liuzhiqiang26 
Signed-off-by: @liuzhiqiang26
This commit is contained in:
openeuler-ci-bot 2022-11-07 03:23:51 +00:00 committed by Gitee
commit a3f331e9a5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 2163 additions and 1 deletions

View File

@ -0,0 +1,181 @@
From db77d1b3cdb14ca0e32132ff7ad360e3d48f62ee Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Tue, 7 Sep 2021 22:41:46 +0200
Subject: [PATCH] multipathd: add and set cli_handlers in a single step
Modify set_handler_callback() such that a missing slot is created
if no matching slot is found. This way, we can skip the initialization
with NULL handlers on startup. Assigning the same handler multiple
times would be a bug which is tested with assert().
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/cli.c | 96 ++++++++----------------------------------------
multipathd/cli.h | 7 ++--
2 files changed, 20 insertions(+), 83 deletions(-)
diff --git a/multipathd/cli.c b/multipathd/cli.c
index 4d6c37c..ddeb5fc 100644
--- a/multipathd/cli.c
+++ b/multipathd/cli.c
@@ -4,6 +4,7 @@
#include <sys/time.h>
#include <errno.h>
#include <pthread.h>
+#include <assert.h>
#include "memory.h"
#include "vector.h"
#include "structs.h"
@@ -64,26 +65,27 @@ out:
return 1;
}
-int
-add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *))
+
+static struct handler *add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *), bool locked)
{
struct handler * h;
h = alloc_handler();
- if (!h)
- return 1;
+ if (h == NULL)
+ return NULL;
if (!vector_alloc_slot(handlers)) {
FREE(h);
- return 1;
+ return NULL;
}
vector_set_slot(handlers, h);
h->fingerprint = fp;
h->fn = fn;
+ h->locked = locked;
- return 0;
+ return h;
}
static struct handler *
@@ -100,26 +102,17 @@ find_handler (uint64_t fp)
}
int
-set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *))
+__set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *), bool locked)
{
- struct handler * h = find_handler(fp);
-
- if (!h)
- return 1;
- h->fn = fn;
- h->locked = 1;
- return 0;
-}
-
-int
-set_unlocked_handler_callback (uint64_t fp,int (*fn)(void *, char **, int *, void *))
-{
- struct handler * h = find_handler(fp);
+ struct handler *h;
- if (!h)
+ assert(find_handler(fp) == NULL);
+ h = add_handler(fp, fn, locked);
+ if (!h) {
+ condlog(0, "%s: failed to set handler for code %"PRIu64,
+ __func__, fp);
return 1;
- h->fn = fn;
- h->locked = 0;
+ }
return 0;
}
@@ -513,63 +506,6 @@ cli_init (void) {
if (alloc_handlers())
return 1;
- add_handler(LIST+PATHS, NULL);
- add_handler(LIST+PATHS+FMT, NULL);
- add_handler(LIST+PATHS+RAW+FMT, NULL);
- add_handler(LIST+PATH, NULL);
- add_handler(LIST+STATUS, NULL);
- add_handler(LIST+DAEMON, NULL);
- add_handler(LIST+MAPS, NULL);
- add_handler(LIST+MAPS+STATUS, NULL);
- add_handler(LIST+MAPS+STATS, NULL);
- add_handler(LIST+MAPS+FMT, NULL);
- add_handler(LIST+MAPS+RAW+FMT, NULL);
- add_handler(LIST+MAPS+TOPOLOGY, NULL);
- add_handler(LIST+MAPS+JSON, NULL);
- add_handler(LIST+TOPOLOGY, NULL);
- add_handler(LIST+MAP+TOPOLOGY, NULL);
- add_handler(LIST+MAP+JSON, NULL);
- add_handler(LIST+MAP+FMT, NULL);
- add_handler(LIST+MAP+RAW+FMT, NULL);
- add_handler(LIST+CONFIG, NULL);
- add_handler(LIST+CONFIG+LOCAL, NULL);
- add_handler(LIST+BLACKLIST, NULL);
- add_handler(LIST+DEVICES, NULL);
- add_handler(LIST+WILDCARDS, NULL);
- add_handler(RESET+MAPS+STATS, NULL);
- add_handler(RESET+MAP+STATS, NULL);
- add_handler(ADD+PATH, NULL);
- add_handler(DEL+PATH, NULL);
- add_handler(ADD+MAP, NULL);
- add_handler(DEL+MAP, NULL);
- add_handler(DEL+MAPS, NULL);
- add_handler(SWITCH+MAP+GROUP, NULL);
- add_handler(RECONFIGURE, NULL);
- add_handler(SUSPEND+MAP, NULL);
- add_handler(RESUME+MAP, NULL);
- add_handler(RESIZE+MAP, NULL);
- add_handler(RESET+MAP, NULL);
- add_handler(RELOAD+MAP, NULL);
- add_handler(DISABLEQ+MAP, NULL);
- add_handler(RESTOREQ+MAP, NULL);
- add_handler(DISABLEQ+MAPS, NULL);
- add_handler(RESTOREQ+MAPS, NULL);
- add_handler(REINSTATE+PATH, NULL);
- add_handler(FAIL+PATH, NULL);
- add_handler(QUIT, NULL);
- add_handler(SHUTDOWN, NULL);
- add_handler(GETPRSTATUS+MAP, NULL);
- add_handler(SETPRSTATUS+MAP, NULL);
- add_handler(UNSETPRSTATUS+MAP, NULL);
- add_handler(GETPRKEY+MAP, NULL);
- add_handler(SETPRKEY+MAP+KEY, NULL);
- 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 fdfb9ae..a6704b1 100644
--- a/multipathd/cli.h
+++ b/multipathd/cli.h
@@ -131,9 +131,10 @@ struct handler {
};
int alloc_handlers (void);
-int add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *));
-int set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *));
-int set_unlocked_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *));
+int __set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *), bool locked);
+#define set_handler_callback(fp, fn) __set_handler_callback(fp, fn, true)
+#define set_unlocked_handler_callback(fp, fn) __set_handler_callback(fp, fn, false)
+
int parse_cmd (char * cmd, char ** reply, int * len, void *, int);
int load_keys (void);
char * get_keyparam (vector v, uint64_t code);
--
2.33.0

View File

@ -0,0 +1,842 @@
From f515b8e552412d01f3b01c5c7129452a82d8714d Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Tue, 7 Sep 2021 22:32:46 +0200
Subject: [PATCH] multipathd: make all cli_handlers static
The cli_handler functions are only called from the handler table and
need not be exported.
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/cli_handlers.c | 214 ++++++++++++++++++++++----------------
multipathd/cli_handlers.h | 61 ++---------
multipathd/main.c | 58 +----------
3 files changed, 134 insertions(+), 199 deletions(-)
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index aeb2be5..f75e176 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -39,7 +39,7 @@
*(__len) = *(__rep) ? sizeof(string_literal) : 0; \
} while (0)
-int
+static int
show_paths (char ** r, int * len, struct vectors * vecs, char * style,
int pretty)
{
@@ -70,7 +70,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style,
return 0;
}
-int
+static int
show_path (char ** r, int * len, struct vectors * vecs, struct path *pp,
char * style)
{
@@ -85,7 +85,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp,
return 0;
}
-int
+static int
show_map_topology (char ** r, int * len, struct multipath * mpp,
struct vectors * vecs)
{
@@ -102,7 +102,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp,
return 0;
}
-int
+static int
show_maps_topology (char ** r, int * len, struct vectors * vecs)
{
STRBUF_ON_STACK(reply);
@@ -128,7 +128,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs)
return 0;
}
-int
+static int
show_maps_json (char ** r, int * len, struct vectors * vecs)
{
STRBUF_ON_STACK(reply);
@@ -149,7 +149,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs)
return 0;
}
-int
+static int
show_map_json (char ** r, int * len, struct multipath * mpp,
struct vectors * vecs)
{
@@ -194,7 +194,7 @@ reset_stats(struct multipath * mpp)
mpp->stat_map_failures = 0;
}
-int
+static int
cli_list_config (void * v, char ** reply, int * len, void * data)
{
condlog(3, "list config (operator)");
@@ -207,7 +207,7 @@ static void v_free(void *x)
vector_free(x);
}
-int
+static int
cli_list_config_local (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -223,7 +223,7 @@ cli_list_config_local (void * v, char ** reply, int * len, void * data)
return ret;
}
-int
+static int
cli_list_paths (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -233,7 +233,7 @@ cli_list_paths (void * v, char ** reply, int * len, void * data)
return show_paths(reply, len, vecs, PRINT_PATH_CHECKER, 1);
}
-int
+static int
cli_list_paths_fmt (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -244,7 +244,7 @@ cli_list_paths_fmt (void * v, char ** reply, int * len, void * data)
return show_paths(reply, len, vecs, fmt, 1);
}
-int
+static int
cli_list_paths_raw (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -255,7 +255,7 @@ cli_list_paths_raw (void * v, char ** reply, int * len, void * data)
return show_paths(reply, len, vecs, fmt, 0);
}
-int
+static int
cli_list_path (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -272,7 +272,7 @@ cli_list_path (void * v, char ** reply, int * len, void * data)
return show_path(reply, len, vecs, pp, "%o");
}
-int
+static int
cli_list_map_topology (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -291,7 +291,7 @@ cli_list_map_topology (void * v, char ** reply, int * len, void * data)
return show_map_topology(reply, len, mpp, vecs);
}
-int
+static int
cli_list_maps_topology (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -301,7 +301,7 @@ cli_list_maps_topology (void * v, char ** reply, int * len, void * data)
return show_maps_topology(reply, len, vecs);
}
-int
+static int
cli_list_map_json (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -320,7 +320,7 @@ cli_list_map_json (void * v, char ** reply, int * len, void * data)
return show_map_json(reply, len, mpp, vecs);
}
-int
+static int
cli_list_maps_json (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -330,7 +330,7 @@ cli_list_maps_json (void * v, char ** reply, int * len, void * data)
return show_maps_json(reply, len, vecs);
}
-int
+static int
cli_list_wildcards (void * v, char ** reply, int * len, void * data)
{
STRBUF_ON_STACK(buf);
@@ -343,7 +343,7 @@ cli_list_wildcards (void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
show_status (char ** r, int *len, struct vectors * vecs)
{
STRBUF_ON_STACK(reply);
@@ -356,7 +356,7 @@ show_status (char ** r, int *len, struct vectors * vecs)
return 0;
}
-int
+static int
show_daemon (char ** r, int *len)
{
STRBUF_ON_STACK(reply);
@@ -370,7 +370,7 @@ show_daemon (char ** r, int *len)
return 0;
}
-int
+static int
show_map (char ** r, int *len, struct multipath * mpp, char * style,
int pretty)
{
@@ -384,7 +384,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style,
return 0;
}
-int
+static int
show_maps (char ** r, int *len, struct vectors * vecs, char * style,
int pretty)
{
@@ -419,7 +419,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style,
return 0;
}
-int
+static int
cli_list_maps_fmt (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -430,7 +430,7 @@ cli_list_maps_fmt (void * v, char ** reply, int * len, void * data)
return show_maps(reply, len, vecs, fmt, 1);
}
-int
+static int
cli_list_maps_raw (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -441,7 +441,7 @@ cli_list_maps_raw (void * v, char ** reply, int * len, void * data)
return show_maps(reply, len, vecs, fmt, 0);
}
-int
+static int
cli_list_map_fmt (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -461,27 +461,7 @@ cli_list_map_fmt (void * v, char ** reply, int * len, void * data)
return show_map(reply, len, mpp, fmt, 1);
}
-int
-cli_list_map_raw (void * v, char ** reply, int * len, void * data)
-{
- struct multipath * mpp;
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
- char * fmt = get_keyparam(v, FMT);
-
- param = convert_dev(param, 0);
- get_path_layout(vecs->pathvec, 0);
- get_multipath_layout(vecs->mpvec, 1);
- mpp = find_mp_by_str(vecs->mpvec, param);
- if (!mpp)
- return 1;
-
- condlog(3, "list map %s fmt %s (operator)", param, fmt);
-
- return show_map(reply, len, mpp, fmt, 0);
-}
-
-int
+static int
cli_list_maps (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -491,7 +471,7 @@ cli_list_maps (void * v, char ** reply, int * len, void * data)
return show_maps(reply, len, vecs, PRINT_MAP_NAMES, 1);
}
-int
+static int
cli_list_status (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -501,7 +481,7 @@ cli_list_status (void * v, char ** reply, int * len, void * data)
return show_status(reply, len, vecs);
}
-int
+static int
cli_list_maps_status (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -511,7 +491,7 @@ cli_list_maps_status (void * v, char ** reply, int * len, void * data)
return show_maps(reply, len, vecs, PRINT_MAP_STATUS, 1);
}
-int
+static int
cli_list_maps_stats (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -521,7 +501,7 @@ cli_list_maps_stats (void * v, char ** reply, int * len, void * data)
return show_maps(reply, len, vecs, PRINT_MAP_STATS, 1);
}
-int
+static int
cli_list_daemon (void * v, char ** reply, int * len, void * data)
{
condlog(3, "list daemon (operator)");
@@ -529,7 +509,7 @@ cli_list_daemon (void * v, char ** reply, int * len, void * data)
return show_daemon(reply, len);
}
-int
+static int
cli_reset_maps_stats (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -544,7 +524,7 @@ cli_reset_maps_stats (void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_reset_map_stats (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -562,7 +542,7 @@ cli_reset_map_stats (void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_add_path (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -678,7 +658,7 @@ blacklisted:
return 0;
}
-int
+static int
cli_del_path (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -701,7 +681,7 @@ cli_del_path (void * v, char ** reply, int * len, void * data)
return (ret == REMOVE_PATH_FAILURE);
}
-int
+static int
cli_add_map (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -761,7 +741,7 @@ cli_add_map (void * v, char ** reply, int * len, void * data)
return rc;
}
-int
+static int
cli_del_map (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -787,7 +767,7 @@ cli_del_map (void * v, char ** reply, int * len, void * data)
return rc;
}
-int
+static int
cli_del_maps (void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -806,7 +786,7 @@ cli_del_maps (void *v, char **reply, int *len, void *data)
return ret;
}
-int
+static int
cli_reload(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -834,7 +814,7 @@ cli_reload(void *v, char **reply, int *len, void *data)
return reload_and_sync_map(mpp, vecs, 0);
}
-int resize_map(struct multipath *mpp, unsigned long long size,
+static int resize_map(struct multipath *mpp, unsigned long long size,
struct vectors * vecs)
{
char *params __attribute__((cleanup(cleanup_charp))) = NULL;
@@ -859,7 +839,7 @@ int resize_map(struct multipath *mpp, unsigned long long size,
return 0;
}
-int
+static int
cli_resize(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -941,7 +921,7 @@ cli_resize(void *v, char **reply, int *len, void *data)
return 0;
}
-int
+static int
cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data)
{
struct config *conf;
@@ -954,7 +934,7 @@ cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data)
{
struct config *conf;
@@ -967,7 +947,7 @@ cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_restore_queueing(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1008,7 +988,7 @@ cli_restore_queueing(void *v, char **reply, int *len, void *data)
return 0;
}
-int
+static int
cli_restore_all_queueing(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1030,7 +1010,7 @@ cli_restore_all_queueing(void *v, char **reply, int *len, void *data)
return 0;
}
-int
+static int
cli_disable_queueing(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1059,7 +1039,7 @@ cli_disable_queueing(void *v, char **reply, int *len, void *data)
return 0;
}
-int
+static int
cli_disable_all_queueing(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1078,7 +1058,7 @@ cli_disable_all_queueing(void *v, char **reply, int *len, void *data)
return 0;
}
-int
+static int
cli_switch_group(void * v, char ** reply, int * len, void * data)
{
char * mapname = get_keyparam(v, MAP);
@@ -1090,7 +1070,7 @@ cli_switch_group(void * v, char ** reply, int * len, void * data)
return dm_switchgroup(mapname, groupnum);
}
-int
+static int
cli_reconfigure(void * v, char ** reply, int * len, void * data)
{
int rc;
@@ -1107,7 +1087,7 @@ cli_reconfigure(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_suspend(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1137,7 +1117,7 @@ cli_suspend(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_resume(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1169,7 +1149,7 @@ cli_resume(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_reinstate(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1192,7 +1172,7 @@ cli_reinstate(void * v, char ** reply, int * len, void * data)
return dm_reinstate_path(pp->mpp->alias, pp->dev_t);
}
-int
+static int
cli_reassign (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1216,7 +1196,7 @@ cli_reassign (void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_fail(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1245,7 +1225,7 @@ cli_fail(void * v, char ** reply, int * len, void * data)
return r;
}
-int
+static int
show_blacklist (char ** r, int * len)
{
STRBUF_ON_STACK(reply);
@@ -1265,7 +1245,7 @@ show_blacklist (char ** r, int * len)
return 0;
}
-int
+static int
cli_list_blacklist (void * v, char ** reply, int * len, void * data)
{
condlog(3, "list blacklist (operator)");
@@ -1273,7 +1253,7 @@ cli_list_blacklist (void * v, char ** reply, int * len, void * data)
return show_blacklist(reply, len);
}
-int
+static int
show_devices (char ** r, int * len, struct vectors *vecs)
{
STRBUF_ON_STACK(reply);
@@ -1294,7 +1274,7 @@ show_devices (char ** r, int * len, struct vectors *vecs)
return 0;
}
-int
+static int
cli_list_devices (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
@@ -1304,13 +1284,13 @@ cli_list_devices (void * v, char ** reply, int * len, void * data)
return show_devices(reply, len, vecs);
}
-int
+static int
cli_quit (void * v, char ** reply, int * len, void * data)
{
return 0;
}
-int
+static int
cli_shutdown (void * v, char ** reply, int * len, void * data)
{
condlog(3, "shutdown (operator)");
@@ -1318,7 +1298,7 @@ cli_shutdown (void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_getprstatus (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -1343,7 +1323,7 @@ cli_getprstatus (void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_setprstatus(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -1366,7 +1346,7 @@ cli_setprstatus(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_unsetprstatus(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -1388,7 +1368,7 @@ cli_unsetprstatus(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_getprkey(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -1420,7 +1400,7 @@ cli_getprkey(void * v, char ** reply, int * len, void * data)
return 0;
}
-int
+static int
cli_unsetprkey(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -1444,7 +1424,7 @@ cli_unsetprkey(void * v, char ** reply, int * len, void * data)
return ret;
}
-int
+static int
cli_setprkey(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
@@ -1476,7 +1456,7 @@ cli_setprkey(void * v, char ** reply, int * len, void * data)
return ret;
}
-int cli_set_marginal(void * v, char ** reply, int * len, void * data)
+static int cli_set_marginal(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, PATH);
@@ -1503,7 +1483,7 @@ int cli_set_marginal(void * v, char ** reply, int * len, void * data)
return reload_and_sync_map(pp->mpp, vecs, 0);
}
-int cli_unset_marginal(void * v, char ** reply, int * len, void * data)
+static int cli_unset_marginal(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, PATH);
@@ -1530,7 +1510,7 @@ int cli_unset_marginal(void * v, char ** reply, int * len, void * data)
return reload_and_sync_map(pp->mpp, vecs, 0);
}
-int cli_unset_all_marginal(void * v, char ** reply, int * len, void * data)
+static 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);
@@ -1566,3 +1546,63 @@ int cli_unset_all_marginal(void * v, char ** reply, int * len, void * data)
return reload_and_sync_map(mpp, vecs, 0);
}
+
+void init_handler_callbacks(void)
+{
+ set_handler_callback(LIST+PATHS, cli_list_paths);
+ set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt);
+ set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw);
+ set_handler_callback(LIST+PATH, cli_list_path);
+ set_handler_callback(LIST+MAPS, cli_list_maps);
+ set_handler_callback(LIST+STATUS, cli_list_status);
+ set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon);
+ set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status);
+ set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats);
+ set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt);
+ set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
+ set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
+ set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
+ set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json);
+ set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
+ set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt);
+ set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt);
+ set_handler_callback(LIST+MAP+JSON, cli_list_map_json);
+ set_handler_callback(LIST+CONFIG+LOCAL, cli_list_config_local);
+ set_handler_callback(LIST+CONFIG, cli_list_config);
+ set_handler_callback(LIST+BLACKLIST, cli_list_blacklist);
+ set_handler_callback(LIST+DEVICES, cli_list_devices);
+ set_handler_callback(LIST+WILDCARDS, cli_list_wildcards);
+ set_handler_callback(RESET+MAPS+STATS, cli_reset_maps_stats);
+ set_handler_callback(RESET+MAP+STATS, cli_reset_map_stats);
+ set_handler_callback(ADD+PATH, cli_add_path);
+ set_handler_callback(DEL+PATH, cli_del_path);
+ set_handler_callback(ADD+MAP, cli_add_map);
+ set_handler_callback(DEL+MAP, cli_del_map);
+ set_handler_callback(DEL+MAPS, cli_del_maps);
+ set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group);
+ set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure);
+ set_handler_callback(SUSPEND+MAP, cli_suspend);
+ set_handler_callback(RESUME+MAP, cli_resume);
+ set_handler_callback(RESIZE+MAP, cli_resize);
+ set_handler_callback(RELOAD+MAP, cli_reload);
+ set_handler_callback(RESET+MAP, cli_reassign);
+ set_handler_callback(REINSTATE+PATH, cli_reinstate);
+ set_handler_callback(FAIL+PATH, cli_fail);
+ set_handler_callback(DISABLEQ+MAP, cli_disable_queueing);
+ set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
+ set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
+ set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
+ set_unlocked_handler_callback(QUIT, cli_quit);
+ set_unlocked_handler_callback(SHUTDOWN, cli_shutdown);
+ set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
+ set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
+ set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
+ set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
+ set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
+ 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);
+}
diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h
index 6f57b42..7eaf847 100644
--- a/multipathd/cli_handlers.h
+++ b/multipathd/cli_handlers.h
@@ -1,55 +1,6 @@
-int cli_list_paths (void * v, char ** reply, int * len, void * data);
-int cli_list_paths_fmt (void * v, char ** reply, int * len, void * data);
-int cli_list_paths_raw (void * v, char ** reply, int * len, void * data);
-int cli_list_path (void * v, char ** reply, int * len, void * data);
-int cli_list_status (void * v, char ** reply, int * len, void * data);
-int cli_list_daemon (void * v, char ** reply, int * len, void * data);
-int cli_list_maps (void * v, char ** reply, int * len, void * data);
-int cli_list_maps_fmt (void * v, char ** reply, int * len, void * data);
-int cli_list_maps_raw (void * v, char ** reply, int * len, void * data);
-int cli_list_map_fmt (void * v, char ** reply, int * len, void * data);
-int cli_list_map_raw (void * v, char ** reply, int * len, void * data);
-int cli_list_maps_status (void * v, char ** reply, int * len, void * data);
-int cli_list_maps_stats (void * v, char ** reply, int * len, void * data);
-int cli_list_map_topology (void * v, char ** reply, int * len, void * data);
-int cli_list_maps_topology (void * v, char ** reply, int * len, void * data);
-int cli_list_map_json (void * v, char ** reply, int * len, void * data);
-int cli_list_maps_json (void * v, char ** reply, int * len, void * data);
-int cli_list_config (void * v, char ** reply, int * len, void * data);
-int cli_list_config_local (void * v, char ** reply, int * len, void * data);
-int cli_list_blacklist (void * v, char ** reply, int * len, void * data);
-int cli_list_devices (void * v, char ** reply, int * len, void * data);
-int cli_list_wildcards (void * v, char ** reply, int * len, void * data);
-int cli_reset_maps_stats (void * v, char ** reply, int * len, void * data);
-int cli_reset_map_stats (void * v, char ** reply, int * len, void * data);
-int cli_add_path (void * v, char ** reply, int * len, void * data);
-int cli_del_path (void * v, char ** reply, int * len, void * data);
-int cli_add_map (void * v, char ** reply, int * len, void * data);
-int cli_del_map (void * v, char ** reply, int * len, void * data);
-int cli_del_maps (void * v, char ** reply, int * len, void * data);
-int cli_switch_group(void * v, char ** reply, int * len, void * data);
-int cli_reconfigure(void * v, char ** reply, int * len, void * data);
-int cli_resize(void * v, char ** reply, int * len, void * data);
-int cli_reload(void * v, char ** reply, int * len, void * data);
-int cli_disable_queueing(void * v, char ** reply, int * len, void * data);
-int cli_disable_all_queueing(void * v, char ** reply, int * len, void * data);
-int cli_restore_queueing(void * v, char ** reply, int * len, void * data);
-int cli_restore_all_queueing(void * v, char ** reply, int * len, void * data);
-int cli_suspend(void * v, char ** reply, int * len, void * data);
-int cli_resume(void * v, char ** reply, int * len, void * data);
-int cli_reinstate(void * v, char ** reply, int * len, void * data);
-int cli_fail(void * v, char ** reply, int * len, void * data);
-int cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data);
-int cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data);
-int cli_quit(void * v, char ** reply, int * len, void * data);
-int cli_shutdown(void * v, char ** reply, int * len, void * data);
-int cli_reassign (void * v, char ** reply, int * len, void * data);
-int cli_getprstatus(void * v, char ** reply, int * len, void * data);
-int cli_setprstatus(void * v, char ** reply, int * len, void * data);
-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);
+#ifndef _CLI_HANDLERS_H
+#define _CLI_HANDLERS_H
+
+void init_handler_callbacks(void);
+
+#endif
diff --git a/multipathd/main.c b/multipathd/main.c
index 118dadd..08fb992 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1669,63 +1669,7 @@ uxlsnrloop (void * ap)
/* Tell main thread that thread has started */
post_config_state(DAEMON_CONFIGURE);
- set_handler_callback(LIST+PATHS, cli_list_paths);
- set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt);
- set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw);
- set_handler_callback(LIST+PATH, cli_list_path);
- set_handler_callback(LIST+MAPS, cli_list_maps);
- set_handler_callback(LIST+STATUS, cli_list_status);
- set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon);
- set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status);
- set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats);
- set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt);
- set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
- set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
- set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
- set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json);
- set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
- set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt);
- set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt);
- set_handler_callback(LIST+MAP+JSON, cli_list_map_json);
- set_handler_callback(LIST+CONFIG+LOCAL, cli_list_config_local);
- set_handler_callback(LIST+CONFIG, cli_list_config);
- set_handler_callback(LIST+BLACKLIST, cli_list_blacklist);
- set_handler_callback(LIST+DEVICES, cli_list_devices);
- set_handler_callback(LIST+WILDCARDS, cli_list_wildcards);
- set_handler_callback(RESET+MAPS+STATS, cli_reset_maps_stats);
- set_handler_callback(RESET+MAP+STATS, cli_reset_map_stats);
- set_handler_callback(ADD+PATH, cli_add_path);
- set_handler_callback(DEL+PATH, cli_del_path);
- set_handler_callback(ADD+MAP, cli_add_map);
- set_handler_callback(DEL+MAP, cli_del_map);
- set_handler_callback(DEL+MAPS, cli_del_maps);
- set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group);
- set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure);
- set_handler_callback(SUSPEND+MAP, cli_suspend);
- set_handler_callback(RESUME+MAP, cli_resume);
- set_handler_callback(RESIZE+MAP, cli_resize);
- set_handler_callback(RELOAD+MAP, cli_reload);
- set_handler_callback(RESET+MAP, cli_reassign);
- set_handler_callback(REINSTATE+PATH, cli_reinstate);
- set_handler_callback(FAIL+PATH, cli_fail);
- set_handler_callback(DISABLEQ+MAP, cli_disable_queueing);
- set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
- set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
- set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
- set_unlocked_handler_callback(QUIT, cli_quit);
- set_unlocked_handler_callback(SHUTDOWN, cli_shutdown);
- set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
- set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
- set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
- set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
- set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
- 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);
-
+ init_handler_callbacks();
umask(077);
uxsock_listen(&uxsock_trigger, ux_sock, ap);
--
2.33.0

View File

@ -0,0 +1,192 @@
From 88b55127e70ab18974a00b7285e2b9ee36846dc8 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 24 Aug 2022 22:39:44 +0200
Subject: [PATCH] multipathd: Fix command completion in interactive mode
The command completion never worked, because the handlers
array wasn't initialized in client mode.
The handlers array is now also required in multipathc,
but it doesn't need the actual handler functions. To keep
multipathc as small as possible, we just add a handler table
with NULL handler functions.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/callbacks.c | 59 +++++++++++++++++++++++++++++++++++++
multipathd/cli.c | 2 ++
multipathd/cli_handlers.c | 61 ++-------------------------------------
multipathd/main.c | 1 -
4 files changed, 63 insertions(+), 60 deletions(-)
create mode 100644 multipathd/callbacks.c
diff --git a/multipathd/callbacks.c b/multipathd/callbacks.c
new file mode 100644
index 0000000..11edc5c
--- /dev/null
+++ b/multipathd/callbacks.c
@@ -0,0 +1,59 @@
+void init_handler_callbacks(void)
+{
+ set_handler_callback(LIST+PATHS, HANDLER(cli_list_paths));
+ set_handler_callback(LIST+PATHS+FMT, HANDLER(cli_list_paths_fmt));
+ set_handler_callback(LIST+PATHS+RAW+FMT, HANDLER(cli_list_paths_raw));
+ set_handler_callback(LIST+PATH, HANDLER(cli_list_path));
+ set_handler_callback(LIST+MAPS, HANDLER(cli_list_maps));
+ set_handler_callback(LIST+STATUS, HANDLER(cli_list_status));
+ set_unlocked_handler_callback(LIST+DAEMON, HANDLER(cli_list_daemon));
+ set_handler_callback(LIST+MAPS+STATUS, HANDLER(cli_list_maps_status));
+ set_handler_callback(LIST+MAPS+STATS, HANDLER(cli_list_maps_stats));
+ set_handler_callback(LIST+MAPS+FMT, HANDLER(cli_list_maps_fmt));
+ set_handler_callback(LIST+MAPS+RAW+FMT, HANDLER(cli_list_maps_raw));
+ set_handler_callback(LIST+MAPS+TOPOLOGY, HANDLER(cli_list_maps_topology));
+ set_handler_callback(LIST+TOPOLOGY, HANDLER(cli_list_maps_topology));
+ set_handler_callback(LIST+MAPS+JSON, HANDLER(cli_list_maps_json));
+ set_handler_callback(LIST+MAP+TOPOLOGY, HANDLER(cli_list_map_topology));
+ set_handler_callback(LIST+MAP+FMT, HANDLER(cli_list_map_fmt));
+ set_handler_callback(LIST+MAP+RAW+FMT, HANDLER(cli_list_map_fmt));
+ set_handler_callback(LIST+MAP+JSON, HANDLER(cli_list_map_json));
+ set_handler_callback(LIST+CONFIG+LOCAL, HANDLER(cli_list_config_local));
+ set_handler_callback(LIST+CONFIG, HANDLER(cli_list_config));
+ set_handler_callback(LIST+BLACKLIST, HANDLER(cli_list_blacklist));
+ set_handler_callback(LIST+DEVICES, HANDLER(cli_list_devices));
+ set_handler_callback(LIST+WILDCARDS, HANDLER(cli_list_wildcards));
+ set_handler_callback(RESET+MAPS+STATS, HANDLER(cli_reset_maps_stats));
+ set_handler_callback(RESET+MAP+STATS, HANDLER(cli_reset_map_stats));
+ set_handler_callback(ADD+PATH, HANDLER(cli_add_path));
+ set_handler_callback(DEL+PATH, HANDLER(cli_del_path));
+ set_handler_callback(ADD+MAP, HANDLER(cli_add_map));
+ set_handler_callback(DEL+MAP, HANDLER(cli_del_map));
+ set_handler_callback(DEL+MAPS, HANDLER(cli_del_maps));
+ set_handler_callback(SWITCH+MAP+GROUP, HANDLER(cli_switch_group));
+ set_unlocked_handler_callback(RECONFIGURE, HANDLER(cli_reconfigure));
+ set_handler_callback(SUSPEND+MAP, HANDLER(cli_suspend));
+ set_handler_callback(RESUME+MAP, HANDLER(cli_resume));
+ set_handler_callback(RESIZE+MAP, HANDLER(cli_resize));
+ set_handler_callback(RELOAD+MAP, HANDLER(cli_reload));
+ set_handler_callback(RESET+MAP, HANDLER(cli_reassign));
+ set_handler_callback(REINSTATE+PATH, HANDLER(cli_reinstate));
+ set_handler_callback(FAIL+PATH, HANDLER(cli_fail));
+ set_handler_callback(DISABLEQ+MAP, HANDLER(cli_disable_queueing));
+ set_handler_callback(RESTOREQ+MAP, HANDLER(cli_restore_queueing));
+ set_handler_callback(DISABLEQ+MAPS, HANDLER(cli_disable_all_queueing));
+ set_handler_callback(RESTOREQ+MAPS, HANDLER(cli_restore_all_queueing));
+ set_unlocked_handler_callback(QUIT, HANDLER(cli_quit));
+ set_unlocked_handler_callback(SHUTDOWN, HANDLER(cli_shutdown));
+ set_handler_callback(GETPRSTATUS+MAP, HANDLER(cli_getprstatus));
+ set_handler_callback(SETPRSTATUS+MAP, HANDLER(cli_setprstatus));
+ set_handler_callback(UNSETPRSTATUS+MAP, HANDLER(cli_unsetprstatus));
+ set_handler_callback(FORCEQ+DAEMON, HANDLER(cli_force_no_daemon_q));
+ set_handler_callback(RESTOREQ+DAEMON, HANDLER(cli_restore_no_daemon_q));
+ set_handler_callback(GETPRKEY+MAP, HANDLER(cli_getprkey));
+ set_handler_callback(SETPRKEY+MAP+KEY, HANDLER(cli_setprkey));
+ set_handler_callback(UNSETPRKEY+MAP, HANDLER(cli_unsetprkey));
+ set_handler_callback(SETMARGINAL+PATH, HANDLER(cli_set_marginal));
+ set_handler_callback(UNSETMARGINAL+PATH, HANDLER(cli_unset_marginal));
+ set_handler_callback(UNSETMARGINAL+MAP, HANDLER(cli_unset_all_marginal));
+}
diff --git a/multipathd/cli.c b/multipathd/cli.c
index 1facf89..8033db0 100644
--- a/multipathd/cli.c
+++ b/multipathd/cli.c
@@ -16,6 +16,7 @@
#include "mpath_cmd.h"
#include "cli.h"
+#include "cli_handlers.h"
#include "debug.h"
#include "strbuf.h"
@@ -506,6 +507,7 @@ cli_init (void) {
if (alloc_handlers())
return 1;
+ init_handler_callbacks();
return 0;
}
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index f75e176..7d4f267 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -1547,62 +1547,5 @@ static int cli_unset_all_marginal(void * v, char ** reply, int * len, void * dat
return reload_and_sync_map(mpp, vecs, 0);
}
-void init_handler_callbacks(void)
-{
- set_handler_callback(LIST+PATHS, cli_list_paths);
- set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt);
- set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw);
- set_handler_callback(LIST+PATH, cli_list_path);
- set_handler_callback(LIST+MAPS, cli_list_maps);
- set_handler_callback(LIST+STATUS, cli_list_status);
- set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon);
- set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status);
- set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats);
- set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt);
- set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
- set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
- set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
- set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json);
- set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
- set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt);
- set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt);
- set_handler_callback(LIST+MAP+JSON, cli_list_map_json);
- set_handler_callback(LIST+CONFIG+LOCAL, cli_list_config_local);
- set_handler_callback(LIST+CONFIG, cli_list_config);
- set_handler_callback(LIST+BLACKLIST, cli_list_blacklist);
- set_handler_callback(LIST+DEVICES, cli_list_devices);
- set_handler_callback(LIST+WILDCARDS, cli_list_wildcards);
- set_handler_callback(RESET+MAPS+STATS, cli_reset_maps_stats);
- set_handler_callback(RESET+MAP+STATS, cli_reset_map_stats);
- set_handler_callback(ADD+PATH, cli_add_path);
- set_handler_callback(DEL+PATH, cli_del_path);
- set_handler_callback(ADD+MAP, cli_add_map);
- set_handler_callback(DEL+MAP, cli_del_map);
- set_handler_callback(DEL+MAPS, cli_del_maps);
- set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group);
- set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure);
- set_handler_callback(SUSPEND+MAP, cli_suspend);
- set_handler_callback(RESUME+MAP, cli_resume);
- set_handler_callback(RESIZE+MAP, cli_resize);
- set_handler_callback(RELOAD+MAP, cli_reload);
- set_handler_callback(RESET+MAP, cli_reassign);
- set_handler_callback(REINSTATE+PATH, cli_reinstate);
- set_handler_callback(FAIL+PATH, cli_fail);
- set_handler_callback(DISABLEQ+MAP, cli_disable_queueing);
- set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
- set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
- set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
- set_unlocked_handler_callback(QUIT, cli_quit);
- set_unlocked_handler_callback(SHUTDOWN, cli_shutdown);
- set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
- set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
- set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
- set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
- set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
- 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);
-}
+#define HANDLER(x) x
+#include "callbacks.c"
diff --git a/multipathd/main.c b/multipathd/main.c
index 08fb992..be7ae60 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1669,7 +1669,6 @@ uxlsnrloop (void * ap)
/* Tell main thread that thread has started */
post_config_state(DAEMON_CONFIGURE);
- init_handler_callbacks();
umask(077);
uxsock_listen(&uxsock_trigger, ux_sock, ap);
--
2.33.0

View File

@ -0,0 +1,939 @@
From 1e59870eead6af91c6499a4d4ca8ca554a73d6b1 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 24 Aug 2022 19:05:08 +0200
Subject: [PATCH] multipathd: more robust command parsing
The current parser allows commands like "path sda show" or "list list
add path sda", because it doesn't enforce ordering of the keywords
and simply adds rather than or-s the values of the keys.
Rework this by using a separate byte for the "verb" and the allowed
qualifiers in the different positions of the command. No command
needs more than 3 qualifiers, so we disallow command vectors with
more than 4 elements, and change the type of the fingerprint to
uint32_t.
init_callbacks() is now required in both multipathc and multipathd
to initialize the table of handlers and fingerprints. But as m
ultipathc never calls any handler, we need not link the
entire handlers code into it.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/callbacks.c | 123 +++++++++++++------------
multipathd/cli.c | 168 ++++++++++++++++++----------------
multipathd/cli.h | 184 +++++++++++++++++++-------------------
multipathd/cli_handlers.c | 70 +++++++--------
4 files changed, 287 insertions(+), 258 deletions(-)
diff --git a/multipathd/callbacks.c b/multipathd/callbacks.c
index 11edc5c..e9cbb7f 100644
--- a/multipathd/callbacks.c
+++ b/multipathd/callbacks.c
@@ -1,59 +1,70 @@
void init_handler_callbacks(void)
{
- set_handler_callback(LIST+PATHS, HANDLER(cli_list_paths));
- set_handler_callback(LIST+PATHS+FMT, HANDLER(cli_list_paths_fmt));
- set_handler_callback(LIST+PATHS+RAW+FMT, HANDLER(cli_list_paths_raw));
- set_handler_callback(LIST+PATH, HANDLER(cli_list_path));
- set_handler_callback(LIST+MAPS, HANDLER(cli_list_maps));
- set_handler_callback(LIST+STATUS, HANDLER(cli_list_status));
- set_unlocked_handler_callback(LIST+DAEMON, HANDLER(cli_list_daemon));
- set_handler_callback(LIST+MAPS+STATUS, HANDLER(cli_list_maps_status));
- set_handler_callback(LIST+MAPS+STATS, HANDLER(cli_list_maps_stats));
- set_handler_callback(LIST+MAPS+FMT, HANDLER(cli_list_maps_fmt));
- set_handler_callback(LIST+MAPS+RAW+FMT, HANDLER(cli_list_maps_raw));
- set_handler_callback(LIST+MAPS+TOPOLOGY, HANDLER(cli_list_maps_topology));
- set_handler_callback(LIST+TOPOLOGY, HANDLER(cli_list_maps_topology));
- set_handler_callback(LIST+MAPS+JSON, HANDLER(cli_list_maps_json));
- set_handler_callback(LIST+MAP+TOPOLOGY, HANDLER(cli_list_map_topology));
- set_handler_callback(LIST+MAP+FMT, HANDLER(cli_list_map_fmt));
- set_handler_callback(LIST+MAP+RAW+FMT, HANDLER(cli_list_map_fmt));
- set_handler_callback(LIST+MAP+JSON, HANDLER(cli_list_map_json));
- set_handler_callback(LIST+CONFIG+LOCAL, HANDLER(cli_list_config_local));
- set_handler_callback(LIST+CONFIG, HANDLER(cli_list_config));
- set_handler_callback(LIST+BLACKLIST, HANDLER(cli_list_blacklist));
- set_handler_callback(LIST+DEVICES, HANDLER(cli_list_devices));
- set_handler_callback(LIST+WILDCARDS, HANDLER(cli_list_wildcards));
- set_handler_callback(RESET+MAPS+STATS, HANDLER(cli_reset_maps_stats));
- set_handler_callback(RESET+MAP+STATS, HANDLER(cli_reset_map_stats));
- set_handler_callback(ADD+PATH, HANDLER(cli_add_path));
- set_handler_callback(DEL+PATH, HANDLER(cli_del_path));
- set_handler_callback(ADD+MAP, HANDLER(cli_add_map));
- set_handler_callback(DEL+MAP, HANDLER(cli_del_map));
- set_handler_callback(DEL+MAPS, HANDLER(cli_del_maps));
- set_handler_callback(SWITCH+MAP+GROUP, HANDLER(cli_switch_group));
- set_unlocked_handler_callback(RECONFIGURE, HANDLER(cli_reconfigure));
- set_handler_callback(SUSPEND+MAP, HANDLER(cli_suspend));
- set_handler_callback(RESUME+MAP, HANDLER(cli_resume));
- set_handler_callback(RESIZE+MAP, HANDLER(cli_resize));
- set_handler_callback(RELOAD+MAP, HANDLER(cli_reload));
- set_handler_callback(RESET+MAP, HANDLER(cli_reassign));
- set_handler_callback(REINSTATE+PATH, HANDLER(cli_reinstate));
- set_handler_callback(FAIL+PATH, HANDLER(cli_fail));
- set_handler_callback(DISABLEQ+MAP, HANDLER(cli_disable_queueing));
- set_handler_callback(RESTOREQ+MAP, HANDLER(cli_restore_queueing));
- set_handler_callback(DISABLEQ+MAPS, HANDLER(cli_disable_all_queueing));
- set_handler_callback(RESTOREQ+MAPS, HANDLER(cli_restore_all_queueing));
- set_unlocked_handler_callback(QUIT, HANDLER(cli_quit));
- set_unlocked_handler_callback(SHUTDOWN, HANDLER(cli_shutdown));
- set_handler_callback(GETPRSTATUS+MAP, HANDLER(cli_getprstatus));
- set_handler_callback(SETPRSTATUS+MAP, HANDLER(cli_setprstatus));
- set_handler_callback(UNSETPRSTATUS+MAP, HANDLER(cli_unsetprstatus));
- set_handler_callback(FORCEQ+DAEMON, HANDLER(cli_force_no_daemon_q));
- set_handler_callback(RESTOREQ+DAEMON, HANDLER(cli_restore_no_daemon_q));
- set_handler_callback(GETPRKEY+MAP, HANDLER(cli_getprkey));
- set_handler_callback(SETPRKEY+MAP+KEY, HANDLER(cli_setprkey));
- set_handler_callback(UNSETPRKEY+MAP, HANDLER(cli_unsetprkey));
- set_handler_callback(SETMARGINAL+PATH, HANDLER(cli_set_marginal));
- set_handler_callback(UNSETMARGINAL+PATH, HANDLER(cli_unset_marginal));
- set_handler_callback(UNSETMARGINAL+MAP, HANDLER(cli_unset_all_marginal));
+ set_handler_callback(VRB_LIST | Q1_PATHS, HANDLER(cli_list_paths));
+ set_handler_callback(VRB_LIST | Q1_PATHS | Q2_FMT, HANDLER(cli_list_paths_fmt));
+ set_handler_callback(VRB_LIST | Q1_PATHS | Q2_RAW | Q3_FMT,
+ HANDLER(cli_list_paths_raw));
+ set_handler_callback(VRB_LIST | Q1_PATH, HANDLER(cli_list_path));
+ set_handler_callback(VRB_LIST | Q1_MAPS, HANDLER(cli_list_maps));
+ set_handler_callback(VRB_LIST | Q1_STATUS, HANDLER(cli_list_status));
+ set_unlocked_handler_callback(VRB_LIST | Q1_DAEMON, HANDLER(cli_list_daemon));
+ set_handler_callback(VRB_LIST | Q1_MAPS | Q2_STATUS,
+ HANDLER(cli_list_maps_status));
+ set_handler_callback(VRB_LIST | Q1_MAPS | Q2_STATS,
+ HANDLER(cli_list_maps_stats));
+ set_handler_callback(VRB_LIST | Q1_MAPS | Q2_FMT, HANDLER(cli_list_maps_fmt));
+ set_handler_callback(VRB_LIST | Q1_MAPS | Q2_RAW | Q3_FMT,
+ HANDLER(cli_list_maps_raw));
+ set_handler_callback(VRB_LIST | Q1_MAPS | Q2_TOPOLOGY,
+ HANDLER(cli_list_maps_topology));
+ set_handler_callback(VRB_LIST | Q1_TOPOLOGY, HANDLER(cli_list_maps_topology));
+ set_handler_callback(VRB_LIST | Q1_MAPS | Q2_JSON, HANDLER(cli_list_maps_json));
+ set_handler_callback(VRB_LIST | Q1_MAP | Q2_TOPOLOGY,
+ HANDLER(cli_list_map_topology));
+ set_handler_callback(VRB_LIST | Q1_MAP | Q2_FMT, HANDLER(cli_list_map_fmt));
+ set_handler_callback(VRB_LIST | Q1_MAP | Q2_RAW | Q3_FMT,
+ HANDLER(cli_list_map_fmt));
+ set_handler_callback(VRB_LIST | Q1_MAP | Q2_JSON, HANDLER(cli_list_map_json));
+ set_handler_callback(VRB_LIST | Q1_CONFIG | Q2_LOCAL,
+ HANDLER(cli_list_config_local));
+ set_handler_callback(VRB_LIST | Q1_CONFIG, HANDLER(cli_list_config));
+ set_handler_callback(VRB_LIST | Q1_BLACKLIST, HANDLER(cli_list_blacklist));
+ set_handler_callback(VRB_LIST | Q1_DEVICES, HANDLER(cli_list_devices));
+ set_handler_callback(VRB_LIST | Q1_WILDCARDS, HANDLER(cli_list_wildcards));
+ set_handler_callback(VRB_RESET | Q1_MAPS | Q2_STATS,
+ HANDLER(cli_reset_maps_stats));
+ set_handler_callback(VRB_RESET | Q1_MAP | Q2_STATS,
+ HANDLER(cli_reset_map_stats));
+ set_handler_callback(VRB_ADD | Q1_PATH, HANDLER(cli_add_path));
+ set_handler_callback(VRB_DEL | Q1_PATH, HANDLER(cli_del_path));
+ set_handler_callback(VRB_ADD | Q1_MAP, HANDLER(cli_add_map));
+ set_handler_callback(VRB_DEL | Q1_MAP, HANDLER(cli_del_map));
+ set_handler_callback(VRB_DEL | Q1_MAPS, HANDLER(cli_del_maps));
+ set_handler_callback(VRB_SWITCH | Q1_MAP | Q2_GROUP, HANDLER(cli_switch_group));
+ set_unlocked_handler_callback(VRB_RECONFIGURE, HANDLER(cli_reconfigure));
+ set_handler_callback(VRB_SUSPEND | Q1_MAP, HANDLER(cli_suspend));
+ set_handler_callback(VRB_RESUME | Q1_MAP, HANDLER(cli_resume));
+ set_handler_callback(VRB_RESIZE | Q1_MAP, HANDLER(cli_resize));
+ set_handler_callback(VRB_RELOAD | Q1_MAP, HANDLER(cli_reload));
+ set_handler_callback(VRB_RESET | Q1_MAP, HANDLER(cli_reassign));
+ set_handler_callback(VRB_REINSTATE | Q1_PATH, HANDLER(cli_reinstate));
+ set_handler_callback(VRB_FAIL | Q1_PATH, HANDLER(cli_fail));
+ set_handler_callback(VRB_DISABLEQ | Q1_MAP, HANDLER(cli_disable_queueing));
+ set_handler_callback(VRB_RESTOREQ | Q1_MAP, HANDLER(cli_restore_queueing));
+ set_handler_callback(VRB_DISABLEQ | Q1_MAPS, HANDLER(cli_disable_all_queueing));
+ set_handler_callback(VRB_RESTOREQ | Q1_MAPS, HANDLER(cli_restore_all_queueing));
+ set_unlocked_handler_callback(VRB_QUIT, HANDLER(cli_quit));
+ set_unlocked_handler_callback(VRB_SHUTDOWN, HANDLER(cli_shutdown));
+ set_handler_callback(VRB_GETPRSTATUS | Q1_MAP, HANDLER(cli_getprstatus));
+ set_handler_callback(VRB_SETPRSTATUS | Q1_MAP, HANDLER(cli_setprstatus));
+ set_handler_callback(VRB_UNSETPRSTATUS | Q1_MAP, HANDLER(cli_unsetprstatus));
+ set_handler_callback(VRB_FORCEQ | Q1_DAEMON, HANDLER(cli_force_no_daemon_q));
+ set_handler_callback(VRB_RESTOREQ | Q1_DAEMON, HANDLER(cli_restore_no_daemon_q));
+ set_handler_callback(VRB_GETPRKEY | Q1_MAP, HANDLER(cli_getprkey));
+ set_handler_callback(VRB_SETPRKEY | Q1_MAP | Q2_KEY, HANDLER(cli_setprkey));
+ set_handler_callback(VRB_UNSETPRKEY | Q1_MAP, HANDLER(cli_unsetprkey));
+ set_handler_callback(VRB_SETMARGINAL | Q1_PATH, HANDLER(cli_set_marginal));
+ set_handler_callback(VRB_UNSETMARGINAL | Q1_PATH, HANDLER(cli_unset_marginal));
+ set_handler_callback(VRB_UNSETMARGINAL | Q1_MAP,
+ HANDLER(cli_unset_all_marginal));
}
diff --git a/multipathd/cli.c b/multipathd/cli.c
index 8033db0..5d1a482 100644
--- a/multipathd/cli.c
+++ b/multipathd/cli.c
@@ -23,6 +23,9 @@
static vector keys;
static vector handlers;
+/* See KEY_INVALID in cli.h */
+#define INVALID_FINGERPRINT ((uint32_t)(0))
+
static struct key *
alloc_key (void)
{
@@ -36,7 +39,7 @@ alloc_handler (void)
}
static int
-add_key (vector vec, char * str, uint64_t code, int has_param)
+add_key (vector vec, char * str, uint8_t code, int has_param)
{
struct key * kw;
@@ -67,7 +70,7 @@ out:
}
-static struct handler *add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *), bool locked)
+static struct handler *add_handler (uint32_t fp, int (*fn)(void *, char **, int *, void *), bool locked)
{
struct handler * h;
@@ -90,11 +93,13 @@ static struct handler *add_handler (uint64_t fp, int (*fn)(void *, char **, int
}
static struct handler *
-find_handler (uint64_t fp)
+find_handler (uint32_t fp)
{
int i;
struct handler *h;
+ if (fp == INVALID_FINGERPRINT)
+ return NULL;
vector_foreach_slot (handlers, h, i)
if (h->fingerprint == fp)
return h;
@@ -103,14 +108,15 @@ find_handler (uint64_t fp)
}
int
-__set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *), bool locked)
+__set_handler_callback (uint32_t fp, int (*fn)(void *, char **, int *, void *), bool locked)
{
struct handler *h;
+ assert(fp != INVALID_FINGERPRINT);
assert(find_handler(fp) == NULL);
h = add_handler(fp, fn, locked);
if (!h) {
- condlog(0, "%s: failed to set handler for code %"PRIu64,
+ condlog(0, "%s: failed to set handler for code %"PRIu32,
__func__, fp);
return 1;
}
@@ -163,57 +169,57 @@ load_keys (void)
if (!keys)
return 1;
- r += add_key(keys, "list", LIST, 0);
- r += add_key(keys, "show", LIST, 0);
- r += add_key(keys, "add", ADD, 0);
- r += add_key(keys, "remove", DEL, 0);
- r += add_key(keys, "del", DEL, 0);
- r += add_key(keys, "switch", SWITCH, 0);
- r += add_key(keys, "switchgroup", SWITCH, 0);
- r += add_key(keys, "suspend", SUSPEND, 0);
- r += add_key(keys, "resume", RESUME, 0);
- r += add_key(keys, "reinstate", REINSTATE, 0);
- r += add_key(keys, "fail", FAIL, 0);
- r += add_key(keys, "resize", RESIZE, 0);
- r += add_key(keys, "reset", RESET, 0);
- r += add_key(keys, "reload", RELOAD, 0);
- r += add_key(keys, "forcequeueing", FORCEQ, 0);
- r += add_key(keys, "disablequeueing", DISABLEQ, 0);
- r += add_key(keys, "restorequeueing", RESTOREQ, 0);
- r += add_key(keys, "paths", PATHS, 0);
- r += add_key(keys, "maps", MAPS, 0);
- r += add_key(keys, "multipaths", MAPS, 0);
- r += add_key(keys, "path", PATH, 1);
- r += add_key(keys, "map", MAP, 1);
- r += add_key(keys, "multipath", MAP, 1);
- r += add_key(keys, "group", GROUP, 1);
- r += add_key(keys, "reconfigure", RECONFIGURE, 0);
- r += add_key(keys, "daemon", DAEMON, 0);
- r += add_key(keys, "status", STATUS, 0);
- r += add_key(keys, "stats", STATS, 0);
- r += add_key(keys, "topology", TOPOLOGY, 0);
- r += add_key(keys, "config", CONFIG, 0);
- r += add_key(keys, "blacklist", BLACKLIST, 0);
- r += add_key(keys, "devices", DEVICES, 0);
- r += add_key(keys, "raw", RAW, 0);
- r += add_key(keys, "wildcards", WILDCARDS, 0);
- r += add_key(keys, "quit", QUIT, 0);
- r += add_key(keys, "exit", QUIT, 0);
- r += add_key(keys, "shutdown", SHUTDOWN, 0);
- r += add_key(keys, "getprstatus", GETPRSTATUS, 0);
- r += add_key(keys, "setprstatus", SETPRSTATUS, 0);
- r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0);
- r += add_key(keys, "format", FMT, 1);
- r += add_key(keys, "json", JSON, 0);
- r += add_key(keys, "getprkey", GETPRKEY, 0);
- r += add_key(keys, "setprkey", SETPRKEY, 0);
- 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);
-
-
+ r += add_key(keys, "list", VRB_LIST, 0);
+ r += add_key(keys, "show", VRB_LIST, 0);
+ r += add_key(keys, "add", VRB_ADD, 0);
+ r += add_key(keys, "remove", VRB_DEL, 0);
+ r += add_key(keys, "del", VRB_DEL, 0);
+ r += add_key(keys, "switch", VRB_SWITCH, 0);
+ r += add_key(keys, "switchgroup", VRB_SWITCH, 0);
+ r += add_key(keys, "suspend", VRB_SUSPEND, 0);
+ r += add_key(keys, "resume", VRB_RESUME, 0);
+ r += add_key(keys, "reinstate", VRB_REINSTATE, 0);
+ r += add_key(keys, "fail", VRB_FAIL, 0);
+ r += add_key(keys, "resize", VRB_RESIZE, 0);
+ r += add_key(keys, "reset", VRB_RESET, 0);
+ r += add_key(keys, "reload", VRB_RELOAD, 0);
+ r += add_key(keys, "forcequeueing", VRB_FORCEQ, 0);
+ r += add_key(keys, "disablequeueing", VRB_DISABLEQ, 0);
+ r += add_key(keys, "restorequeueing", VRB_RESTOREQ, 0);
+ r += add_key(keys, "paths", KEY_PATHS, 0);
+ r += add_key(keys, "maps", KEY_MAPS, 0);
+ r += add_key(keys, "multipaths", KEY_MAPS, 0);
+ r += add_key(keys, "path", KEY_PATH, 1);
+ r += add_key(keys, "map", KEY_MAP, 1);
+ r += add_key(keys, "multipath", KEY_MAP, 1);
+ r += add_key(keys, "group", KEY_GROUP, 1);
+ r += add_key(keys, "reconfigure", VRB_RECONFIGURE, 0);
+ r += add_key(keys, "daemon", KEY_DAEMON, 0);
+ r += add_key(keys, "status", KEY_STATUS, 0);
+ r += add_key(keys, "stats", KEY_STATS, 0);
+ r += add_key(keys, "topology", KEY_TOPOLOGY, 0);
+ r += add_key(keys, "config", KEY_CONFIG, 0);
+ r += add_key(keys, "blacklist", KEY_BLACKLIST, 0);
+ r += add_key(keys, "devices", KEY_DEVICES, 0);
+ r += add_key(keys, "raw", KEY_RAW, 0);
+ r += add_key(keys, "wildcards", KEY_WILDCARDS, 0);
+ r += add_key(keys, "quit", VRB_QUIT, 0);
+ r += add_key(keys, "exit", VRB_QUIT, 0);
+ r += add_key(keys, "shutdown", VRB_SHUTDOWN, 0);
+ r += add_key(keys, "getprstatus", VRB_GETPRSTATUS, 0);
+ r += add_key(keys, "setprstatus", VRB_SETPRSTATUS, 0);
+ r += add_key(keys, "unsetprstatus", VRB_UNSETPRSTATUS, 0);
+ r += add_key(keys, "format", KEY_FMT, 1);
+ r += add_key(keys, "json", KEY_JSON, 0);
+ r += add_key(keys, "getprkey", VRB_GETPRKEY, 0);
+ r += add_key(keys, "setprkey", VRB_SETPRKEY, 0);
+ r += add_key(keys, "unsetprkey", VRB_UNSETPRKEY, 0);
+ r += add_key(keys, "key", KEY_KEY, 1);
+ r += add_key(keys, "local", KEY_LOCAL, 0);
+ r += add_key(keys, "setmarginal", VRB_SETMARGINAL, 0);
+ r += add_key(keys, "unsetmarginal", VRB_UNSETMARGINAL, 0);
+ r += add_key(keys, "all", KEY_ALL, 0);
+
if (r) {
free_keys(keys);
keys = NULL;
@@ -321,19 +327,22 @@ out:
return r;
}
-static uint64_t
+static uint32_t
fingerprint(vector vec)
{
int i;
- uint64_t fp = 0;
+ uint32_t fp = 0;
struct key * kw;
- if (!vec)
- return 0;
-
- vector_foreach_slot(vec, kw, i)
- fp += kw->code;
+ if (!vec || VECTOR_SIZE(vec) > 4)
+ return INVALID_FINGERPRINT;
+ vector_foreach_slot(vec, kw, i) {
+ if (i >= 4)
+ break;
+ fp |= (uint32_t)kw->code << (8 * i);
+ }
+
return fp;
}
@@ -367,8 +376,8 @@ genhelp_sprint_aliases (struct strbuf *reply, vector keys,
static int
do_genhelp(struct strbuf *reply, const char *cmd, int error) {
- int i, j;
- uint64_t fp;
+ int i, j, k;
+ uint32_t fp;
struct handler * h;
struct key * kw;
int rc = 0;
@@ -394,17 +403,24 @@ do_genhelp(struct strbuf *reply, const char *cmd, int error) {
vector_foreach_slot (handlers, h, i) {
fp = h->fingerprint;
- vector_foreach_slot (keys, kw, j) {
- if ((kw->code & fp)) {
- fp -= kw->code;
- if (print_strbuf(reply, " %s", kw->str) < 0 ||
- genhelp_sprint_aliases(reply, keys, kw) < 0)
- return -1;
-
- if (kw->has_param) {
- if (print_strbuf(reply, " $%s",
- kw->str) < 0)
+ for (k = 0; k < 4; k++, fp >>= 8) {
+ uint32_t code = fp & 0xff;
+
+ if (!code)
+ break;
+
+ vector_foreach_slot (keys, kw, j) {
+ if ((uint32_t)kw->code == code) {
+ if (print_strbuf(reply, " %s", kw->str) < 0 ||
+ genhelp_sprint_aliases(reply, keys, kw) < 0)
return -1;
+
+ if (kw->has_param) {
+ if (print_strbuf(reply, " $%s",
+ kw->str) < 0)
+ return -1;
+ }
+ break;
}
}
}
@@ -487,7 +503,7 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
}
char *
-get_keyparam (vector v, uint64_t code)
+get_keyparam (vector v, uint8_t code)
{
struct key * kw;
int i;
diff --git a/multipathd/cli.h b/multipathd/cli.h
index 6459203..a13e190 100644
--- a/multipathd/cli.h
+++ b/multipathd/cli.h
@@ -3,96 +3,98 @@
#include <stdint.h>
+/*
+ * CLI commands consist of 4 bytes, a verb (byte 0) and up to
+ * 3 qualifiers (byte 1 - 3).
+ */
+
enum {
- __LIST,
- __ADD,
- __DEL,
- __SWITCH,
- __SUSPEND,
- __RESUME,
- __REINSTATE,
- __FAIL,
- __RESIZE,
- __RESET,
- __RELOAD,
- __FORCEQ,
- __DISABLEQ,
- __RESTOREQ,
- __PATHS,
- __MAPS,
- __PATH,
- __MAP,
- __GROUP,
- __RECONFIGURE,
- __DAEMON,
- __STATUS,
- __STATS,
- __TOPOLOGY,
- __CONFIG,
- __BLACKLIST,
- __DEVICES,
- __RAW,
- __WILDCARDS,
- __QUIT,
- __SHUTDOWN,
- __GETPRSTATUS,
- __SETPRSTATUS,
- __UNSETPRSTATUS,
- __FMT,
- __JSON,
- __GETPRKEY,
- __SETPRKEY,
- __UNSETPRKEY,
- __KEY,
- __LOCAL,
- __SETMARGINAL,
- __UNSETMARGINAL,
+ /* See INVALID_FINGERPRINT in cli.c */
+ KEY_INVALID = 0,
+
+ /* Verbs */
+ VRB_LIST = 1,
+ VRB_ADD = 2,
+ VRB_DEL = 3,
+ VRB_RESET = 4,
+ VRB_SWITCH = 5,
+ VRB_RECONFIGURE = 6,
+ VRB_SUSPEND = 7,
+ VRB_RESUME = 8,
+ VRB_RESIZE = 9,
+ VRB_RELOAD = 10,
+ VRB_FAIL = 11,
+ VRB_REINSTATE = 12,
+ VRB_DISABLEQ = 13,
+ VRB_RESTOREQ = 14,
+ VRB_FORCEQ = 15,
+ VRB_GETPRSTATUS = 16,
+ VRB_SETPRSTATUS = 17,
+ VRB_UNSETPRSTATUS = 18,
+ VRB_GETPRKEY = 19,
+ VRB_SETPRKEY = 20,
+ VRB_UNSETPRKEY = 21,
+ VRB_SETMARGINAL = 22,
+ VRB_UNSETMARGINAL = 23,
+ VRB_SHUTDOWN = 24,
+ VRB_QUIT = 25,
+
+ /* Qualifiers, values must be different from verbs */
+ KEY_PATH = 65,
+ KEY_PATHS = 66,
+ KEY_MAP = 67,
+ KEY_MAPS = 68,
+ KEY_TOPOLOGY = 69,
+ KEY_CONFIG = 70,
+ KEY_BLACKLIST = 71,
+ KEY_DEVICES = 72,
+ KEY_WILDCARDS = 73,
+ KEY_ALL = 74,
+ KEY_DAEMON = 75,
+ KEY_FMT = 76,
+ KEY_RAW = 77,
+ KEY_STATUS = 78,
+ KEY_STATS = 79,
+ KEY_JSON = 80,
+ KEY_LOCAL = 81,
+ KEY_GROUP = 82,
+ KEY_KEY = 83,
};
-#define LIST (1 << __LIST)
-#define ADD (1 << __ADD)
-#define DEL (1 << __DEL)
-#define SWITCH (1 << __SWITCH)
-#define SUSPEND (1 << __SUSPEND)
-#define RESUME (1 << __RESUME)
-#define REINSTATE (1 << __REINSTATE)
-#define FAIL (1 << __FAIL)
-#define RESIZE (1 << __RESIZE)
-#define RESET (1 << __RESET)
-#define RELOAD (1 << __RELOAD)
-#define FORCEQ (1 << __FORCEQ)
-#define DISABLEQ (1 << __DISABLEQ)
-#define RESTOREQ (1 << __RESTOREQ)
-#define PATHS (1 << __PATHS)
-#define MAPS (1 << __MAPS)
-#define PATH (1 << __PATH)
-#define MAP (1 << __MAP)
-#define GROUP (1 << __GROUP)
-#define RECONFIGURE (1 << __RECONFIGURE)
-#define DAEMON (1 << __DAEMON)
-#define STATUS (1 << __STATUS)
-#define STATS (1 << __STATS)
-#define TOPOLOGY (1 << __TOPOLOGY)
-#define CONFIG (1 << __CONFIG)
-#define BLACKLIST (1 << __BLACKLIST)
-#define DEVICES (1 << __DEVICES)
-#define RAW (1 << __RAW)
-#define COUNT (1 << __COUNT)
-#define WILDCARDS (1 << __WILDCARDS)
-#define QUIT (1 << __QUIT)
-#define SHUTDOWN (1 << __SHUTDOWN)
-#define GETPRSTATUS (1ULL << __GETPRSTATUS)
-#define SETPRSTATUS (1ULL << __SETPRSTATUS)
-#define UNSETPRSTATUS (1ULL << __UNSETPRSTATUS)
-#define FMT (1ULL << __FMT)
-#define JSON (1ULL << __JSON)
-#define GETPRKEY (1ULL << __GETPRKEY)
-#define SETPRKEY (1ULL << __SETPRKEY)
-#define UNSETPRKEY (1ULL << __UNSETPRKEY)
-#define KEY (1ULL << __KEY)
-#define LOCAL (1ULL << __LOCAL)
-#define SETMARGINAL (1ULL << __SETMARGINAL)
-#define UNSETMARGINAL (1ULL << __UNSETMARGINAL)
+/*
+ * The shifted qualifiers determine valid positions of the
+ * keywords in the known commands. E.g. the only qualifier
+ * that's valid in position 3 is "fmt", e.g. "list maps raw fmt".
+ */
+enum {
+ /* byte 1: qualifier 1 */
+ Q1_PATH = KEY_PATH << 8,
+ Q1_PATHS = KEY_PATHS << 8,
+ Q1_MAP = KEY_MAP << 8,
+ Q1_MAPS = KEY_MAPS << 8,
+ Q1_TOPOLOGY = KEY_TOPOLOGY << 8,
+ Q1_CONFIG = KEY_CONFIG << 8,
+ Q1_BLACKLIST = KEY_BLACKLIST << 8,
+ Q1_DEVICES = KEY_DEVICES << 8,
+ Q1_WILDCARDS = KEY_WILDCARDS << 8,
+ Q1_ALL = KEY_ALL << 8,
+ Q1_DAEMON = KEY_DAEMON << 8,
+ Q1_STATUS = KEY_STATUS << 8,
+
+ /* byte 2: qualifier 2 */
+ Q2_FMT = KEY_FMT << 16,
+ Q2_RAW = KEY_RAW << 16,
+ Q2_STATUS = KEY_STATUS << 16,
+ Q2_STATS = KEY_STATS << 16,
+ Q2_TOPOLOGY = KEY_TOPOLOGY << 16,
+ Q2_JSON = KEY_JSON << 16,
+ Q2_LOCAL = KEY_LOCAL << 16,
+ Q2_GROUP = KEY_GROUP << 16,
+ Q2_KEY = KEY_KEY << 16,
+
+ /* byte 3: qualifier 3 */
+ Q3_FMT = KEY_FMT << 24,
+};
#define INITIAL_REPLY_LEN 1200
@@ -120,24 +122,24 @@ enum {
struct key {
char * str;
char * param;
- uint64_t code;
+ uint8_t code;
int has_param;
};
struct handler {
- uint64_t fingerprint;
+ uint32_t fingerprint;
int locked;
int (*fn)(void *, char **, int *, void *);
};
int alloc_handlers (void);
-int __set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *), bool locked);
+int __set_handler_callback (uint32_t fp, int (*fn)(void *, char **, int *, void *), bool locked);
#define set_handler_callback(fp, fn) __set_handler_callback(fp, fn, true)
#define set_unlocked_handler_callback(fp, fn) __set_handler_callback(fp, fn, false)
int parse_cmd (char * cmd, char ** reply, int * len, void *, int);
int load_keys (void);
-char * get_keyparam (vector v, uint64_t code);
+char * get_keyparam (vector v, uint8_t code);
void free_keys (vector vec);
void free_handlers (void);
int cli_init (void);
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index 7d4f267..6d79287 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -237,7 +237,7 @@ static int
cli_list_paths_fmt (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * fmt = get_keyparam(v, FMT);
+ char * fmt = get_keyparam(v, KEY_FMT);
condlog(3, "list paths (operator)");
@@ -248,7 +248,7 @@ static int
cli_list_paths_raw (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * fmt = get_keyparam(v, FMT);
+ char * fmt = get_keyparam(v, KEY_FMT);
condlog(3, "list paths (operator)");
@@ -259,7 +259,7 @@ static int
cli_list_path (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path *pp;
param = convert_dev(param, 1);
@@ -277,7 +277,7 @@ cli_list_map_topology (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
param = convert_dev(param, 0);
get_path_layout(vecs->pathvec, 0);
@@ -306,7 +306,7 @@ cli_list_map_json (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
param = convert_dev(param, 0);
get_path_layout(vecs->pathvec, 0);
@@ -423,7 +423,7 @@ static int
cli_list_maps_fmt (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * fmt = get_keyparam(v, FMT);
+ char * fmt = get_keyparam(v, KEY_FMT);
condlog(3, "list maps (operator)");
@@ -434,7 +434,7 @@ static int
cli_list_maps_raw (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * fmt = get_keyparam(v, FMT);
+ char * fmt = get_keyparam(v, KEY_FMT);
condlog(3, "list maps (operator)");
@@ -446,8 +446,8 @@ cli_list_map_fmt (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
- char * fmt = get_keyparam(v, FMT);
+ char * param = get_keyparam(v, KEY_MAP);
+ char * fmt = get_keyparam(v, KEY_FMT);
param = convert_dev(param, 0);
get_path_layout(vecs->pathvec, 0);
@@ -529,7 +529,7 @@ cli_reset_map_stats (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
struct multipath * mpp;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
param = convert_dev(param, 0);
mpp = find_mp_by_str(vecs->mpvec, param);
@@ -546,7 +546,7 @@ static int
cli_add_path (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path *pp;
int r;
struct config *conf;
@@ -662,7 +662,7 @@ static int
cli_del_path (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path *pp;
int ret;
@@ -685,7 +685,7 @@ static int
cli_add_map (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
int major = -1, minor = -1;
char dev_path[PATH_SIZE];
char *refwwid, *alias = NULL;
@@ -745,7 +745,7 @@ static int
cli_del_map (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
int major, minor;
char *alias;
int rc;
@@ -790,7 +790,7 @@ static int
cli_reload(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
- char * mapname = get_keyparam(v, MAP);
+ char * mapname = get_keyparam(v, KEY_MAP);
struct multipath *mpp;
int minor;
@@ -843,7 +843,7 @@ static int
cli_resize(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
- char * mapname = get_keyparam(v, MAP);
+ char * mapname = get_keyparam(v, KEY_MAP);
struct multipath *mpp;
int minor;
unsigned long long size, sz;
@@ -951,7 +951,7 @@ static int
cli_restore_queueing(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
- char * mapname = get_keyparam(v, MAP);
+ char * mapname = get_keyparam(v, KEY_MAP);
struct multipath *mpp;
int minor;
struct config *conf;
@@ -1014,7 +1014,7 @@ static int
cli_disable_queueing(void *v, char **reply, int *len, void *data)
{
struct vectors * vecs = (struct vectors *)data;
- char * mapname = get_keyparam(v, MAP);
+ char * mapname = get_keyparam(v, KEY_MAP);
struct multipath *mpp;
int minor;
@@ -1061,8 +1061,8 @@ cli_disable_all_queueing(void *v, char **reply, int *len, void *data)
static int
cli_switch_group(void * v, char ** reply, int * len, void * data)
{
- char * mapname = get_keyparam(v, MAP);
- int groupnum = atoi(get_keyparam(v, GROUP));
+ char * mapname = get_keyparam(v, KEY_MAP);
+ int groupnum = atoi(get_keyparam(v, KEY_GROUP));
mapname = convert_dev(mapname, 0);
condlog(2, "%s: switch to path group #%i (operator)", mapname, groupnum);
@@ -1091,7 +1091,7 @@ static int
cli_suspend(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
int r;
struct multipath * mpp;
@@ -1121,7 +1121,7 @@ static int
cli_resume(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
int r;
struct multipath * mpp;
uint16_t udev_flags;
@@ -1153,7 +1153,7 @@ static int
cli_reinstate(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path * pp;
param = convert_dev(param, 1);
@@ -1176,7 +1176,7 @@ static int
cli_reassign (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
struct multipath *mpp;
param = convert_dev(param, 0);
@@ -1200,7 +1200,7 @@ static int
cli_fail(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path * pp;
int r;
@@ -1303,7 +1303,7 @@ cli_getprstatus (void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
param = convert_dev(param, 0);
get_path_layout(vecs->pathvec, 0);
@@ -1328,7 +1328,7 @@ cli_setprstatus(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
param = convert_dev(param, 0);
get_path_layout(vecs->pathvec, 0);
@@ -1351,7 +1351,7 @@ cli_unsetprstatus(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
+ char * param = get_keyparam(v, KEY_MAP);
param = convert_dev(param, 0);
get_path_layout(vecs->pathvec, 0);
@@ -1373,7 +1373,7 @@ cli_getprkey(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char *mapname = get_keyparam(v, MAP);
+ char *mapname = get_keyparam(v, KEY_MAP);
uint64_t key;
mapname = convert_dev(mapname, 0);
@@ -1405,7 +1405,7 @@ cli_unsetprkey(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char *mapname = get_keyparam(v, MAP);
+ char *mapname = get_keyparam(v, KEY_MAP);
int ret;
struct config *conf;
@@ -1429,8 +1429,8 @@ cli_setprkey(void * v, char ** reply, int * len, void * data)
{
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
- char *mapname = get_keyparam(v, MAP);
- char *keyparam = get_keyparam(v, KEY);
+ char *mapname = get_keyparam(v, KEY_MAP);
+ char *keyparam = get_keyparam(v, KEY_KEY);
uint64_t prkey;
uint8_t flags;
int ret;
@@ -1459,7 +1459,7 @@ cli_setprkey(void * v, char ** reply, int * len, void * data)
static int cli_set_marginal(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path * pp;
param = convert_dev(param, 1);
@@ -1486,7 +1486,7 @@ static int cli_set_marginal(void * v, char ** reply, int * len, void * data)
static int cli_unset_marginal(void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, PATH);
+ char * param = get_keyparam(v, KEY_PATH);
struct path * pp;
param = convert_dev(param, 1);
@@ -1513,7 +1513,7 @@ static int cli_unset_marginal(void * v, char ** reply, int * len, void * data)
static 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);
+ char * mapname = get_keyparam(v, KEY_MAP);
struct multipath *mpp;
struct pathgroup * pgp;
struct path * pp;
--
2.33.0

View File

@ -1,7 +1,7 @@
#needsrootforbuild
Name: multipath-tools
Version: 0.8.7
Release: 5
Release: 6
Summary: Tools to manage multipath devices with the device-mapper
License: GPL-2.0-or-later and LGPL-2.0-only
URL: http://christophe.varoqui.free.fr/
@ -27,6 +27,11 @@ Patch15: 0015-clear-mpp-path-reference-when-path-is-freed-otherwis.patch
Patch16: 0016-multipath-return-failure-on-an-invalid-remove-cmd.patch
Patch17: 0017-multipath-fix-exit-status-of-multipath-T.patch
Patch18: 0018-multipath-tools-use-run-instead-of-dev-shm.patch
Patch19: 0019-multipathd-add-and-set-cli_handlers-in-a-single-step.patch
Patch20: 0020-multipathd-make-all-cli_handlers-static.patch
Patch21: 0021-multipathd-Fix-command-completion-in-interactive-mod.patch
Patch22: 0022-multipathd-more-robust-command-parsing.patch
BuildRequires: multipath-tools, libcmocka, libcmocka-devel
BuildRequires: gcc, libaio-devel, userspace-rcu-devel, device-mapper-devel >= 1.02.89
BuildRequires: libselinux-devel, libsepol-devel, readline-devel, ncurses-devel,
@ -173,6 +178,9 @@ fi
%changelog
* Mon Oct 31 2022 wuguanghao <wuguanghao3@huawei.com> - 0.8.7-6
- fix CVE-2022-41974
* Wed Oct 26 2022 shikemeng<shikemeng@huawei.com> - 0.8.7-5
- use /run instead of /dev/shm to fix CVE-2022-41973