Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP5:GA
libdlm
bug-1191734_0009-add-new-dlm_tool-command-reloa...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bug-1191734_0009-add-new-dlm_tool-command-reload_config.patch of Package libdlm
From 7d4a965aac1482411e7daabe2a646f97768fdc87 Mon Sep 17 00:00:00 2001 From: Heming Zhao <heming.zhao@suse.com> Date: Fri, 8 Oct 2021 09:33:37 +0800 Subject: [PATCH 09/14] add new dlm_tool command reload_config reload_config could help people to change dlm.conf settings on the fly. Signed-off-by: Heming Zhao <heming.zhao@suse.com> --- dlm_controld/action.c | 5 ++ dlm_controld/config.c | 119 +++++++++++++++++++++++++++++---- dlm_controld/dlm_controld.h | 1 + dlm_controld/dlm_daemon.h | 4 ++ dlm_controld/lib.c | 19 ++++++ dlm_controld/libdlmcontrol.h | 1 + dlm_controld/logging.c | 18 +++-- dlm_controld/main.c | 126 ++++++++++++++++++++++------------- dlm_tool/main.c | 21 +++++- 9 files changed, 246 insertions(+), 68 deletions(-) diff --git a/dlm_controld/action.c b/dlm_controld/action.c index 0eff27997e1c..baddaf81cb4f 100644 --- a/dlm_controld/action.c +++ b/dlm_controld/action.c @@ -766,6 +766,11 @@ static int set_configfs_cluster(const char *name, char *str, int num) return 0; } +int set_configfs_opt(const char *name, char *str, int num) +{ + return set_configfs_cluster(name, str, num); +} + #define NET_RMEM_DEFAULT 4194304 #define NET_RMEM_MAX 4194304 diff --git a/dlm_controld/config.c b/dlm_controld/config.c index 947480dabe85..c60be8d47ef0 100644 --- a/dlm_controld/config.c +++ b/dlm_controld/config.c @@ -188,6 +188,55 @@ static void get_val_str(char *line, char *val_out) strcpy(val_out, val); } +inline static void reload_setting(int index) +{ + switch(index) { + case log_debug_ind: + set_configfs_opt("log_debug", NULL, opt(log_debug_ind)); + break; + case debug_logfile_ind: + set_logfile_priority(); + break; + default: + break; + } +} + +static void reset_opt_value(int index) +{ + struct dlm_option *o = &dlm_options[index]; + + /* config priority: cli, config file, default */ + + if (o->cli_set) { + o->use_int = o->cli_int; + o->use_uint = o->cli_uint; + o->use_str = o->cli_str; + + } else if (o->file_set) { + o->use_int = o->file_int; + o->use_uint = o->file_uint; + o->use_str = o->file_str; + + } else { + o->use_int = o->default_int; + o->use_uint = o->default_uint; + o->use_str = (char *)o->default_str; + } + + /* + * We don't handle reset value same as legacy value. + * + * i.e. + * 1. option abc default value is 0, while in dlm.conf abc=0. + * 2. Then remove abc from dlm.conf. + * 3. This function still call reload_setting(), and won't bypass this + * calling for no change. + */ + reload_setting(index); + return; +} + void set_opt_file(int update) { unsigned int uval = 0; @@ -195,7 +244,8 @@ void set_opt_file(int update) FILE *file; char line[MAX_LINE]; char str[MAX_LINE]; - int i, val = 0; + int i, val = 0, ind; + char scanned_dlm_opt[dlm_options_max]; if (!path_exists(CONF_FILE_PATH)) return; @@ -204,6 +254,12 @@ void set_opt_file(int update) if (!file) return; + /* In update mode, there is a little bit bother if one option ever set + * but later be removed or commented out */ + memset(scanned_dlm_opt, 0, sizeof(scanned_dlm_opt)); + scanned_dlm_opt[help_ind] = 1; + scanned_dlm_opt[version_ind] = 1; + while (fgets(line, MAX_LINE, file)) { if (line[0] == '#') continue; @@ -226,30 +282,31 @@ void set_opt_file(int update) str[i] = line[i]; } - o = get_dlm_option(str); + ind = get_ind_name(str); + if (ind < 0) + continue; + o = &dlm_options[ind]; if (!o) continue; - /* Doesn't make sense to set this in conf file. */ - if (!strcmp(str, "daemon_debug")) + scanned_dlm_opt[ind] = 1; + + /* In update flow, bypass the item which doesn't support reload. */ + if (update && !o->reload) continue; o->file_set++; if (!o->req_arg) { - /* ignore any = x */ - - o->file_int = 1; - - if (!o->cli_set) - o->use_int = o->file_int; - - log_debug("config file %s = %d cli_set %d use %d", - o->name, o->file_int, o->cli_set, o->use_int); + /* current only "help" & "version" are no_arg type, ignore them */ + continue; } else if (o->req_arg == req_arg_int) { get_val_int(line, &val); + if (update && (o->file_int == val)) + continue; + o->file_int = val; if (!o->cli_set) @@ -261,6 +318,9 @@ void set_opt_file(int update) } else if (o->req_arg == req_arg_uint) { get_val_uint(line, &uval); + if (update && (o->file_uint == uval)) + continue; + o->file_uint = uval; if (!o->cli_set) @@ -271,8 +331,12 @@ void set_opt_file(int update) } else if (o->req_arg == req_arg_bool) { get_val_int(line, &val); + val = val ? 1 : 0; + + if (update && (o->file_int == val)) + continue; - o->file_int = val ? 1 : 0; + o->file_int = val; if (!o->cli_set) o->use_int = o->file_int; @@ -283,6 +347,11 @@ void set_opt_file(int update) memset(str, 0, sizeof(str)); get_val_str(line, str); + if (update && !strcmp(o->file_str, str)) + continue; + + if (o->file_str) + free(o->file_str); o->file_str = strdup(str); if (!o->cli_set) @@ -291,6 +360,28 @@ void set_opt_file(int update) log_debug("config file %s = %s cli_set %d use %s", o->name, o->file_str, o->cli_set, o->use_str); } + + if (update) + reload_setting(ind); + } + + if (update) { + /* handle commented out options */ + for (i=0; i<dlm_options_max; i++) { + if (scanned_dlm_opt[i]) + continue; + if (!dlm_options[i].reload || !dlm_options[i].file_set) + continue; + + dlm_options[i].file_set = 0; + dlm_options[i].file_int = 0; + dlm_options[i].file_uint = 0; + if(dlm_options[i].file_str) { + free(dlm_options[i].file_str); + dlm_options[i].file_str = NULL; + } + reset_opt_value(i); + } } fclose(file); diff --git a/dlm_controld/dlm_controld.h b/dlm_controld/dlm_controld.h index 649b2a5826f9..0ea3548fce7d 100644 --- a/dlm_controld/dlm_controld.h +++ b/dlm_controld/dlm_controld.h @@ -35,6 +35,7 @@ #define DLMC_CMD_RUN_START 15 #define DLMC_CMD_RUN_CHECK 16 #define DLMC_CMD_DUMP_RUN 17 +#define DLMC_CMD_RELOAD_CONFIG 18 struct dlmc_header { unsigned int magic; diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h index 436fc9109aa6..9e68f8257cb5 100644 --- a/dlm_controld/dlm_daemon.h +++ b/dlm_controld/dlm_daemon.h @@ -132,6 +132,7 @@ struct dlm_option { const char *name; char letter; int req_arg; + char reload; const char *desc; int use_int; @@ -383,6 +384,7 @@ int setup_configfs_members(void); int check_uncontrolled_lockspaces(void); int setup_misc_devices(void); int path_exists(const char *path); +int set_configfs_opt(const char *name, char *str, int num); /* config.c */ void set_opt_file(int update); @@ -471,6 +473,7 @@ struct lockspace *find_ls_id(uint32_t id); const char *dlm_mode_str(int mode); void cluster_dead(int ci); struct dlm_option *get_dlm_option(char *name); +int get_ind_name(char *s); struct run *find_run(char *uuid_str); void clear_run(struct run *run); void send_helper_run_request(struct run_request *req); @@ -522,6 +525,7 @@ void init_logging(void); void close_logging(void); void copy_log_dump(char *buf, int *len); void copy_log_dump_plock(char *buf, int *len); +void set_logfile_priority(void); /* crc.c */ uint32_t cpgname_to_crc(const char *data, int len); diff --git a/dlm_controld/lib.c b/dlm_controld/lib.c index 53c11cf9f269..951eb6561ba9 100644 --- a/dlm_controld/lib.c +++ b/dlm_controld/lib.c @@ -174,6 +174,25 @@ int dlmc_dump_run(char *buf) return do_dump(DLMC_CMD_DUMP_RUN, NULL, buf); } +int dlmc_reload_config(void) +{ + struct dlmc_header h; + int fd, rv; + + init_header(&h, DLMC_CMD_RELOAD_CONFIG, NULL, 0); + + fd = do_connect(DLMC_SOCK_PATH); + if (fd < 0) { + rv = fd; + goto out; + } + + rv = do_write(fd, &h, sizeof(h)); + close(fd); + out: + return rv; +} + static int nodeid_compare(const void *va, const void *vb) { const int *a = va; diff --git a/dlm_controld/libdlmcontrol.h b/dlm_controld/libdlmcontrol.h index ba603feeccf0..ac84e702fb58 100644 --- a/dlm_controld/libdlmcontrol.h +++ b/dlm_controld/libdlmcontrol.h @@ -91,6 +91,7 @@ int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss); 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); #define DLMC_RESULT_REGISTER 1 #define DLMC_RESULT_NOTIFIED 2 diff --git a/dlm_controld/logging.c b/dlm_controld/logging.c index d48b8aebc237..2c57138ce766 100644 --- a/dlm_controld/logging.c +++ b/dlm_controld/logging.c @@ -14,6 +14,18 @@ static int logfile_priority; static char logfile[PATH_MAX]; static FILE *logfile_fp; +/* logfile_priority is the only one of these options that + can be controlled from command line, environment variable + and dynamic setting. + */ +void set_logfile_priority(void) +{ + if (opt(debug_logfile_ind)) + logfile_priority = LOG_DEBUG; + else + logfile_priority = DEFAULT_LOGFILE_PRIORITY; +} + void init_logging(void) { mode_t old_umask; @@ -24,11 +36,7 @@ void init_logging(void) logfile_priority = DEFAULT_LOGFILE_PRIORITY; strcpy(logfile, DEFAULT_LOGFILE); - /* logfile_priority is the only one of these options that - can be controlled from command line or environment variable */ - - if (opt(debug_logfile_ind)) - logfile_priority = LOG_DEBUG; + set_logfile_priority(); if (logfile[0]) { old_umask = umask(0077); diff --git a/dlm_controld/main.c b/dlm_controld/main.c index 504cafa12ec6..8104d8f906ac 100644 --- a/dlm_controld/main.c +++ b/dlm_controld/main.c @@ -1230,6 +1230,10 @@ static void process_connection(int ci) client_dead(ci); break; #endif + case DLMC_CMD_RELOAD_CONFIG: + set_opt_file(1); + break; + default: log_error("process_connection %d unknown command %d", ci, h.command); @@ -1749,12 +1753,13 @@ static void print_usage(void) static void set_opt_default(int ind, const char *name, char letter, int arg_type, int default_int, const char *default_str, - unsigned int default_uint, const char *desc) + unsigned int default_uint, char reload, const char *desc) { dlm_options[ind].name = name; dlm_options[ind].letter = letter; dlm_options[ind].req_arg = arg_type; dlm_options[ind].desc = desc; + dlm_options[ind].reload = reload; dlm_options[ind].default_int = default_int; dlm_options[ind].default_str = default_str; dlm_options[ind].default_uint = default_uint; @@ -1766,142 +1771,142 @@ static void set_opt_default(int ind, const char *name, char letter, int arg_type static void set_opt_defaults(void) { set_opt_default(daemon_debug_ind, - "daemon_debug", 'D', no_arg, - 0, NULL, 0, + "daemon_debug", 'D', req_arg_bool, + 0, NULL, 0, 1, "enable debugging to stderr and don't fork"); set_opt_default(foreground_ind, - "foreground", '\0', no_arg, - 0, NULL, 0, + "foreground", '\0', req_arg_bool, + 0, NULL, 0, 0, "don't fork"); set_opt_default(log_debug_ind, - "log_debug", 'K', no_arg, - 0, NULL, 0, + "log_debug", 'K', req_arg_bool, + 0, NULL, 0, 1, "enable kernel dlm debugging messages"); set_opt_default(timewarn_ind, "timewarn", '\0', req_arg_int, - 0, NULL, 0, + 0, NULL, 0, 0, ""); /* do not advertise */ set_opt_default(protocol_ind, "protocol", 'r', req_arg_str, - -1, "detect", 0, + -1, "detect", 0, 0, "dlm kernel lowcomms protocol: tcp, sctp, detect"); set_opt_default(port_ind, "port", 'R', req_arg_uint, - -1, NULL, 21064, + -1, NULL, 21064, 0, "dlm kernel lowcomms protocol port"); set_opt_default(bind_all_ind, "bind_all", '\0', req_arg_int, - 0, NULL, 0, + 0, NULL, 0, 0, ""); /* do not advertise */ set_opt_default(mark_ind, "mark", '\0', req_arg_uint, - 0, NULL, 0, + 0, NULL, 0, 0, "set mark value for DLM if not explicit by nodeid specified"); set_opt_default(debug_logfile_ind, - "debug_logfile", 'L', no_arg, - 0, NULL, 0, + "debug_logfile", 'L', req_arg_bool, + 0, NULL, 0, 1, "write debugging to log file"); set_opt_default(enable_fscontrol_ind, "enable_fscontrol", '\0', req_arg_bool, - 0, NULL, 0, + 0, NULL, 0, 0, ""); /* do not advertise */ set_opt_default(enable_plock_ind, "enable_plock", 'p', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 0, "enable/disable posix lock support for cluster fs"); set_opt_default(plock_debug_ind, - "plock_debug", 'P', no_arg, - 0, NULL, 0, + "plock_debug", 'P', req_arg_bool, + 0, NULL, 0, 1, "enable plock debugging"); set_opt_default(plock_rate_limit_ind, "plock_rate_limit", 'l', req_arg_int, - 0, NULL, 0, + 0, NULL, 0, 1, "limit rate of plock operations (0 for none)"); set_opt_default(plock_ownership_ind, "plock_ownership", 'o', req_arg_bool, - 0, NULL, 0, + 0, NULL, 0, 0, "enable/disable plock ownership"); set_opt_default(drop_resources_time_ind, "drop_resources_time", 't', req_arg_int, - 10000, NULL, 0, + 10000, NULL, 0, 1, "plock ownership drop resources time (milliseconds)"); set_opt_default(drop_resources_count_ind, "drop_resources_count", 'c', req_arg_int, - 10, NULL, 0, + 10, NULL, 0, 1, "plock ownership drop resources count"); set_opt_default(drop_resources_age_ind, "drop_resources_age", 'a', req_arg_int, - 10000, NULL, 0, + 10000, NULL, 0, 1, "plock ownership drop resources age (milliseconds)"); set_opt_default(post_join_delay_ind, "post_join_delay", 'j', req_arg_int, - 30, NULL, 0, + 30, NULL, 0, 1, "seconds to delay fencing after cluster join"); set_opt_default(enable_fencing_ind, "enable_fencing", 'f', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 0, "enable/disable fencing"); set_opt_default(enable_concurrent_fencing_ind, "enable_concurrent_fencing", '\0', req_arg_bool, - 0, NULL, 0, + 0, NULL, 0, 0, "enable/disable concurrent fencing"); set_opt_default(enable_startup_fencing_ind, "enable_startup_fencing", 's', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 0, "enable/disable startup fencing"); set_opt_default(repeat_failed_fencing_ind, "repeat_failed_fencing", '\0', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 1, "enable/disable retrying after fencing fails"); set_opt_default(enable_quorum_fencing_ind, "enable_quorum_fencing", 'q', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 1, "enable/disable quorum requirement for fencing"); set_opt_default(enable_quorum_lockspace_ind, "enable_quorum_lockspace", '\0', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 1, "enable/disable quorum requirement for lockspace operations"); set_opt_default(enable_helper_ind, "enable_helper", '\0', req_arg_bool, - 1, NULL, 0, + 1, NULL, 0, 0, "enable/disable helper process for running commands"); set_opt_default(help_ind, "help", 'h', no_arg, - -1, NULL, 0, + -1, NULL, 0, 0, "print this help, then exit"); set_opt_default(version_ind, "version", 'V', no_arg, - -1, NULL, 0, + -1, NULL, 0, 0, "Print program version information, then exit"); } -static int get_ind_name(char *s) +int get_ind_name(char *s) { char name[PATH_MAX]; char *p = s; @@ -1948,11 +1953,12 @@ struct dlm_option *get_dlm_option(char *name) static void set_opt_cli(int argc, char **argv) { struct dlm_option *o; - char *arg1, *p, *arg_str; + char *arg1, *p, *arg_str, *endptr; + char bool_str[] = "1"; char bundled_letters[8]; int b, blc = 0, blc_max = 8; int debug_options = 0; - int i, ind; + int i, ind, bundled; if (argc < 2) return; @@ -1996,20 +2002,26 @@ static void set_opt_cli(int argc, char **argv) o = &dlm_options[ind]; o->cli_set++; - if (!o->req_arg) { - /* "-x" has same effect as "-x 1" */ - o->cli_int = 1; - o->use_int = 1; + if (!o->req_arg || (o->req_arg == req_arg_bool)) { + bundled = 0; - /* save bundled, arg-less, single letters, e.g. -DKP */ + /* current for no_arg type, there is not possible to have bundled options. + * for req_arg_bool, bundled options, e.g. -DKP. all treat as "true". + * below code save bundled, arg-less, single letters */ if ((p[0] == '-') && isalpha(p[1]) && (strlen(p) > 2)) { for (b = 2; b < strlen(p) && blc < blc_max; b++) { if (!isalpha(p[b])) break; bundled_letters[blc++] = p[b]; + bundled = 1; } } - continue; + if (bundled) { + /* "-x" has same effect as "-x 1" */ + o->cli_int = 1; + o->use_int = 1; + continue; + } } arg_str = NULL; @@ -2024,17 +2036,31 @@ static void set_opt_cli(int argc, char **argv) } else { /* space separates arg from name or letter */ - if (i >= argc) { - fprintf(stderr, "option %s no arg", p); - exit(EXIT_FAILURE); + if (o->req_arg == req_arg_bool) { + /* bool type treat empty arg as true */ + if (i >= argc || argv[i][0] == '-') + arg_str = bool_str; + else + arg_str = argv[i++]; + } else { + if (i >= argc) { + fprintf(stderr, "option %s no arg\n", p); + exit(EXIT_FAILURE); + } + arg_str = argv[i++]; } - arg_str = argv[i++]; } if (!arg_str || arg_str[0] == '-' || arg_str[0] == '\0') { - fprintf(stderr, "option %s requires arg", p); + fprintf(stderr, "option %s requires arg\n", p); exit(EXIT_FAILURE); } + if ((o->req_arg != req_arg_str) && !strtol(arg_str, &endptr, 10)) { + if (endptr == arg_str) { + fprintf(stderr, "option %s requires digit number\n", p); + exit(EXIT_FAILURE); + } + } if (o->req_arg == req_arg_str) { o->cli_str = strdup(arg_str); @@ -2059,6 +2085,7 @@ static void set_opt_cli(int argc, char **argv) fprintf(stderr, "unknown option char %c\n", bundled_letters[i]); exit(EXIT_FAILURE); } + /* bundled letter must be bool type, treat it with "true" value */ o = &dlm_options[ind]; o->cli_set++; o->cli_int = 1; @@ -2109,8 +2136,11 @@ int main(int argc, char **argv) * - explicit cli setting will override default, * - explicit file setting will override default * - explicit file setting will not override explicit cli setting + * + * "dlm reload_config" will trigger to reload config file, and + * reload action also follows the rule: not override explicit + * cli setting */ - set_opt_defaults(); set_opt_cli(argc, argv); set_opt_file(0); diff --git a/dlm_tool/main.c b/dlm_tool/main.c index 53d9336d59c6..774835192bbf 100644 --- a/dlm_tool/main.c +++ b/dlm_tool/main.c @@ -47,6 +47,7 @@ #define OP_RUN_CANCEL 17 #define OP_RUN_LIST 18 #define OP_DUMP_RUN 19 +#define OP_RELOAD_CONFIG 20 static char *prog_name; static char *lsname; @@ -196,7 +197,7 @@ static void print_usage(void) printf("dlm_tool [command] [options] [name]\n"); printf("\n"); printf("Commands:\n"); - printf("ls, status, dump, dump_config, fence_ack\n"); + printf("ls, status, dump, dump_config, reload_config, fence_ack\n"); printf("log_plock, plocks\n"); printf("join, leave, lockdebug\n"); printf("run, run_start, run_check, run_cancel, run_list\n"); @@ -363,6 +364,12 @@ static void decode_arguments(int argc, char **argv) opt_ind = optind + 1; need_lsname = 0; break; + } else if (!strncmp(argv[optind], "reload_config", 13) && + (strlen(argv[optind]) == 13)) { + operation = OP_RELOAD_CONFIG; + opt_ind = optind + 1; + need_lsname = 0; + break; } else if (!strncmp(argv[optind], "plocks", 6) && (strlen(argv[optind]) == 6)) { operation = OP_PLOCKS; @@ -1472,6 +1479,14 @@ static void do_dump(int op) printf("\n"); } +static void do_reload_config(void) +{ + if (dlmc_reload_config() < 0) + printf("reload_config failed\n"); + else + printf("reload_config done\n"); +} + static void do_log_plock(void) { char buf[DLMC_DUMP_SIZE]; @@ -1570,6 +1585,10 @@ int main(int argc, char **argv) do_dump(operation); break; + case OP_RELOAD_CONFIG: + do_reload_config(); + break; + case OP_LOG_PLOCK: do_log_plock(); break; -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor