File bug-1191734_0011-dlm_tool-dlm_controld-add-new-feature-set_config.patch of Package libdlm
From 0e814226e081d228c96a8cc43e5cec484dc78306 Mon Sep 17 00:00:00 2001
From: Heming Zhao <heming.zhao@suse.com>
Date: Fri, 8 Oct 2021 09:33:39 +0800
Subject: [PATCH 11/14] dlm_tool dlm_controld: add new feature set_config
set_config command makes dlm_controld could change options value dynamically.
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
---
dlm_controld/config.c | 169 +++++++++++++++++++++++++++++++++++
dlm_controld/dlm_controld.h | 1 +
dlm_controld/dlm_daemon.h | 11 +++
dlm_controld/helper.c | 4 -
dlm_controld/lib.c | 38 +++++++-
dlm_controld/libdlmcontrol.h | 1 +
dlm_controld/main.c | 22 ++++-
dlm_tool/main.c | 29 +++++-
8 files changed, 264 insertions(+), 11 deletions(-)
diff --git a/dlm_controld/config.c b/dlm_controld/config.c
index c60be8d47ef0..a7ebb120a6b8 100644
--- a/dlm_controld/config.c
+++ b/dlm_controld/config.c
@@ -387,3 +387,172 @@ void set_opt_file(int update)
fclose(file);
}
+/*
+ * do the clean/restore job:
+ * - clean up dlm_options[].dynamic_xx
+ * - using top priority item to set use option
+ */
+static void reset_dynamic(int index)
+{
+ struct dlm_option *o = &dlm_options[index];
+
+ if (!o->reload)
+ return;
+
+ o->dynamic_set = 0;
+ o->dynamic_int = 0;
+ if (o->dynamic_str){
+ free(o->dynamic_str);
+ o->dynamic_str = NULL;
+ }
+ o->dynamic_uint = 0;
+ reset_opt_value(index);
+
+ return;
+}
+
+/* copy code from exec_command() */
+void set_opt_online(char *cmd_str, int cmd_len)
+{
+ int i, ind, val = 0;
+ int av_count = 0;
+ int arg_len;
+ unsigned int uval = 0;
+ struct dlm_option *o;
+ char str[MAX_LINE];
+ char arg[ONE_ARG_LEN];
+ char *av[MAX_AV_COUNT + 1]; /* +1 for NULL */
+
+ if (cmd_len > RUN_COMMAND_LEN)
+ return;
+
+ for (i = 0; i < MAX_AV_COUNT + 1; i++)
+ av[i] = NULL;
+
+ if (!cmd_str[0])
+ return;
+
+ /* this should already be done, but make sure */
+ cmd_str[cmd_len - 1] = '\0';
+
+ memset(&arg, 0, sizeof(arg));
+ arg_len = 0;
+ cmd_len = strlen(cmd_str);
+
+ for (i = 0; i < cmd_len; i++) {
+ if (!cmd_str[i])
+ break;
+
+ if (av_count == MAX_AV_COUNT)
+ break;
+
+ if (cmd_str[i] == '\\') {
+ if (i == (cmd_len - 1))
+ break;
+ i++;
+
+ if (cmd_str[i] == '\\') {
+ arg[arg_len++] = cmd_str[i];
+ continue;
+ }
+ if (isspace(cmd_str[i])) {
+ arg[arg_len++] = cmd_str[i];
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (isalnum(cmd_str[i]) || ispunct(cmd_str[i])) {
+ arg[arg_len++] = cmd_str[i];
+ } else if (isspace(cmd_str[i])) {
+ if (arg_len)
+ av[av_count++] = strdup(arg);
+
+ memset(arg, 0, sizeof(arg));
+ arg_len = 0;
+ } else {
+ break;
+ }
+ }
+
+ if ((av_count < MAX_AV_COUNT) && arg_len) {
+ av[av_count++] = strdup(arg);
+ }
+
+ /*
+ for (i = 0; i < MAX_AV_COUNT + 1; i++) {
+ if (!av[i])
+ break;
+
+ syslog(LOG_ERR, "command av[%d] \"%s\"", i, av[i]);
+ }
+ */
+
+ if (!strcmp(av[0], "restore_all")) {
+ for (i = 0; i < dlm_options_max; i++)
+ reset_dynamic(i);
+ return;
+ }
+
+ i = -1;
+ while (++i < av_count) {
+
+ ind = get_ind_name(av[i]);
+ if (ind < 0)
+ continue;
+ o = &dlm_options[ind];
+ if (!o || !o->reload)
+ continue;
+
+ get_val_str(av[i], str);
+ if (!strcmp(str, "restore")) {
+ reset_dynamic(ind);
+ continue;
+ }
+
+ o->dynamic_set++;
+
+ if (!o->req_arg || o->req_arg == req_arg_int) {
+ get_val_int(av[i], &val);
+ if (!o->req_arg)
+ val = val ? 1 : 0;
+
+ o->dynamic_int = val;
+
+ log_debug("config dynamic %s = %d previous use %d",
+ o->name, o->dynamic_int, o->use_int);
+ o->use_int = o->dynamic_int;
+
+ } else if (o->req_arg == req_arg_uint) {
+ get_val_uint(av[i], &uval);
+ o->dynamic_uint = uval;
+
+ log_debug("config dynamic %s = %u previous use %u",
+ o->name, o->dynamic_uint, o->use_uint);
+ o->use_uint = o->dynamic_uint;
+
+ } else if (o->req_arg == req_arg_bool) {
+ get_val_int(av[i], &val);
+ o->dynamic_int = val ? 1 : 0;
+
+ log_debug("config dynamic %s = %d previous use %d",
+ o->name, o->dynamic_int, o->use_int);
+ o->use_int = o->dynamic_int;
+
+ } else if (o->req_arg == req_arg_str) {
+ memset(str, 0, sizeof(str));
+ get_val_str(av[i], str);
+
+ o->dynamic_str = strdup(str);
+
+ log_debug("config dynamic %s = %s previous use %s",
+ o->name, o->dynamic_str, o->use_str);
+ o->use_str = o->dynamic_str;
+ }
+
+ reload_setting(ind);
+ }
+
+ return;
+}
diff --git a/dlm_controld/dlm_controld.h b/dlm_controld/dlm_controld.h
index 0ea3548fce7d..94e5c49e88bd 100644
--- a/dlm_controld/dlm_controld.h
+++ b/dlm_controld/dlm_controld.h
@@ -36,6 +36,7 @@
#define DLMC_CMD_RUN_CHECK 16
#define DLMC_CMD_DUMP_RUN 17
#define DLMC_CMD_RELOAD_CONFIG 18
+#define DLMC_CMD_SET_CONFIG 19
struct dlmc_header {
unsigned int magic;
diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h
index 9e68f8257cb5..da261774bee0 100644
--- a/dlm_controld/dlm_daemon.h
+++ b/dlm_controld/dlm_daemon.h
@@ -25,6 +25,7 @@
#include <arpa/inet.h>
#include <net/if.h>
#include <stdio.h>
+#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -133,6 +134,7 @@ struct dlm_option {
char letter;
int req_arg;
char reload;
+ char dynamic;
const char *desc;
int use_int;
@@ -152,6 +154,11 @@ struct dlm_option {
int file_int;
char *file_str;
unsigned int file_uint;
+
+ int dynamic_set;
+ int dynamic_int;
+ char *dynamic_str;
+ unsigned int dynamic_uint;
};
EXTERN struct dlm_option dlm_options[dlm_options_max];
@@ -328,6 +335,9 @@ struct lockspace {
#define RUN_COMMAND_LEN DLMC_RUN_COMMAND_LEN /* 1024 */
+#define MAX_AV_COUNT 32
+#define ONE_ARG_LEN 256
+
struct run_info {
int dest_nodeid;
int start_nodeid;
@@ -390,6 +400,7 @@ int set_configfs_opt(const char *name, char *str, int num);
void set_opt_file(int update);
int get_weight(struct lockspace *ls, int nodeid);
void setup_lockspace_config(struct lockspace *ls);
+void set_opt_online(char *cmd_str, int cmd_len);
/* cpg.c */
void process_lockspace_changes(void);
diff --git a/dlm_controld/helper.c b/dlm_controld/helper.c
index a20965b76195..469dd22095f0 100644
--- a/dlm_controld/helper.c
+++ b/dlm_controld/helper.c
@@ -20,7 +20,6 @@
#include <time.h>
#include <stdarg.h>
#include <signal.h>
-#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -29,9 +28,6 @@
#include "dlm_daemon.h"
-#define MAX_AV_COUNT 32
-#define ONE_ARG_LEN 256
-
static int _log_stderr;
diff --git a/dlm_controld/lib.c b/dlm_controld/lib.c
index 951eb6561ba9..8cbdd27f15e2 100644
--- a/dlm_controld/lib.c
+++ b/dlm_controld/lib.c
@@ -189,7 +189,43 @@ int dlmc_reload_config(void)
rv = do_write(fd, &h, sizeof(h));
close(fd);
- out:
+out:
+ return rv;
+}
+
+int dlmc_set_config(char *command)
+{
+ struct dlmc_header h;
+ char *cmdbuf;
+ int fd, rv;
+
+ cmdbuf = malloc(DLMC_RUN_COMMAND_LEN);
+ if (!cmdbuf)
+ return -1;
+
+ memset(cmdbuf, 0, DLMC_RUN_COMMAND_LEN);
+ strncpy(cmdbuf, command, DLMC_RUN_COMMAND_LEN-1);
+
+ init_header(&h, DLMC_CMD_SET_CONFIG, NULL, DLMC_RUN_COMMAND_LEN);
+
+ fd = do_connect(DLMC_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ rv = do_write(fd, cmdbuf, DLMC_RUN_COMMAND_LEN);
+ if (rv < 0)
+ goto out_close;
+
+out_close:
+ close(fd);
+out:
+ free(cmdbuf);
return rv;
}
diff --git a/dlm_controld/libdlmcontrol.h b/dlm_controld/libdlmcontrol.h
index ac84e702fb58..a106171b1073 100644
--- a/dlm_controld/libdlmcontrol.h
+++ b/dlm_controld/libdlmcontrol.h
@@ -92,6 +92,7 @@ int dlmc_lockspace_nodes(char *lsname, int type, int max, int *count,
struct dlmc_node *nodes);
int dlmc_print_status(uint32_t flags);
int dlmc_reload_config(void);
+int dlmc_set_config(char *command);
#define DLMC_RESULT_REGISTER 1
#define DLMC_RESULT_NOTIFIED 2
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index 8104d8f906ac..3a081c802056 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -919,7 +919,7 @@ static void copy_options(char *buf, int *len)
{
struct dlm_option *o;
char tmp[256];
- int i, ret, pos = 0;
+ int i, ret, pos = 0, l = 0;
for (i = 0; i < dlm_options_max; i++) {
o = &dlm_options[i];
@@ -927,9 +927,20 @@ static void copy_options(char *buf, int *len)
memset(tmp, 0, sizeof(tmp));
if (o->req_arg == req_arg_str)
- snprintf(tmp, 255, "%s=%s\n", o->name, o->use_str);
+ l = snprintf(tmp, 250, "%s=%s", o->name, o->use_str);
+ else if (o->req_arg == req_arg_uint)
+ l = snprintf(tmp, 250, "%s=%u", o->name, o->use_uint);
+ else
+ l = snprintf(tmp, 250, "%s=%d", o->name, o->use_int);
+
+ if (o->dynamic_set)
+ snprintf(tmp + l, 15, " (set_config)\n");
+ else if (o->cli_set)
+ snprintf(tmp + l, 15, " (cli option)\n");
+ else if (o->file_set)
+ snprintf(tmp + l, 15, " (dlm.conf)\n");
else
- snprintf(tmp, 255, "%s=%d\n", o->name, o->use_int);
+ snprintf(tmp + l, 15, "\n");
if (pos + strlen(tmp) >= LOG_DUMP_SIZE)
break;
@@ -1234,6 +1245,11 @@ static void process_connection(int ci)
set_opt_file(1);
break;
+ case DLMC_CMD_SET_CONFIG:
+ if (extra_len)
+ set_opt_online(extra, extra_len);
+ break;
+
default:
log_error("process_connection %d unknown command %d",
ci, h.command);
diff --git a/dlm_tool/main.c b/dlm_tool/main.c
index 774835192bbf..bce5c1da3c95 100644
--- a/dlm_tool/main.c
+++ b/dlm_tool/main.c
@@ -48,6 +48,7 @@
#define OP_RUN_LIST 18
#define OP_DUMP_RUN 19
#define OP_RELOAD_CONFIG 20
+#define OP_SET_CONFIG 21
static char *prog_name;
static char *lsname;
@@ -197,7 +198,8 @@ static void print_usage(void)
printf("dlm_tool [command] [options] [name]\n");
printf("\n");
printf("Commands:\n");
- printf("ls, status, dump, dump_config, reload_config, fence_ack\n");
+ printf("ls, status, dump, fence_ack\n");
+ printf("dump_config, reload_config, set_config\n");
printf("log_plock, plocks\n");
printf("join, leave, lockdebug\n");
printf("run, run_start, run_check, run_cancel, run_list\n");
@@ -370,6 +372,13 @@ static void decode_arguments(int argc, char **argv)
opt_ind = optind + 1;
need_lsname = 0;
break;
+ } else if (!strncmp(argv[optind], "set_config", 10) &&
+ (strlen(argv[optind]) == 10)) {
+ operation = OP_SET_CONFIG;
+ opt_ind = optind + 1;
+ need_lsname = 0;
+ need_command = 1;
+ break;
} else if (!strncmp(argv[optind], "plocks", 6) &&
(strlen(argv[optind]) == 6)) {
operation = OP_PLOCKS;
@@ -477,8 +486,10 @@ static void decode_arguments(int argc, char **argv)
exit(EXIT_FAILURE);
}
- strcat(run_command, argv[i]);
- strcat(run_command, " ");
+ if (strlen(argv[i])) {
+ strcat(run_command, argv[i]);
+ strcat(run_command, " ");
+ }
}
}
@@ -1487,6 +1498,14 @@ static void do_reload_config(void)
printf("reload_config done\n");
}
+static void do_set_config(void)
+{
+ if (dlmc_set_config(run_command) < 0)
+ printf("set_config failed\n");
+ else
+ printf("set_config done\n");
+}
+
static void do_log_plock(void)
{
char buf[DLMC_DUMP_SIZE];
@@ -1589,6 +1608,10 @@ int main(int argc, char **argv)
do_reload_config();
break;
+ case OP_SET_CONFIG:
+ do_set_config();
+ break;
+
case OP_LOG_PLOCK:
do_log_plock();
break;
--
2.33.0