diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 39cf895cb0..9be7a69e91 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -634,6 +634,13 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth early on. + + By setting on the kernel command line (either from + &nmrundir;/proc-cmdline or /proc/cmdline), + debug logging is enabled. This overrides both the command-line options and the settings + from NetworkManager.conf. + + NetworkManager's logging aims not to contain private sensitive data and you should be fine sharing the debug logs. Still, there will diff --git a/src/core/main.c b/src/core/main.c index 1cd3788074..2eb230d9ca 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -293,6 +293,7 @@ main(int argc, char *argv[]) GError *error_invalid_logging_config = NULL; const char *const *warnings; int errsv; + gboolean has_logging = FALSE; _nm_utils_is_manager_process = TRUE; @@ -354,10 +355,14 @@ main(int argc, char *argv[]) g_free(path); } - if (!nm_logging_setup(global_opt.opt_log_level, - global_opt.opt_log_domains, - &bad_domains, - &error)) { + if (nm_config_kernel_command_line_nm_debug()) { + /* we honor kernel command line. If "nm.debug" is set, we always enable trace logging. */ + nm_logging_setup("TRACE", "ALL", NULL, NULL); + has_logging = TRUE; + } else if (!nm_logging_setup(global_opt.opt_log_level, + global_opt.opt_log_domains, + &bad_domains, + &error)) { fprintf(stderr, _("%s. Please use --help to see a list of valid options.\n"), error->message); @@ -379,7 +384,7 @@ main(int argc, char *argv[]) /* Initialize logging from config file *only* if not explicitly * specified by commandline. */ - if (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) { + if (!has_logging && !global_opt.opt_log_level && !global_opt.opt_log_domains) { if (!nm_logging_setup(nm_config_get_log_level(config), nm_config_get_log_domains(config), &bad_domains, diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c index ddb7787fef..7e9364b6b5 100644 --- a/src/core/nm-config-data.c +++ b/src/core/nm-config-data.c @@ -839,6 +839,13 @@ nm_config_data_log(const NMConfigData *self, _LOG(stream, prefix, "# no-auto-default specs \"%s\"", msg); } + if (nm_config_kernel_command_line_nm_debug()) { + _LOG(stream, + prefix, + "# /proc/cmdline contains \"" NM_CONFIG_KERNEL_CMDLINE_NM_DEBUG + "\". Debug log enabled"); + } + #undef _LOG } diff --git a/src/core/nm-config.c b/src/core/nm-config.c index 701baae686..3d23d4f6cd 100644 --- a/src/core/nm-config.c +++ b/src/core/nm-config.c @@ -3014,6 +3014,15 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /*****************************************************************************/ +gboolean +nm_config_kernel_command_line_nm_debug(void) +{ + return (nm_strv_find_first(nm_utils_proc_cmdline_split(), -1, NM_CONFIG_KERNEL_CMDLINE_NM_DEBUG) + >= 0); +} + +/*****************************************************************************/ + static gboolean init_sync(GInitable *initable, GCancellable *cancellable, GError **error) { diff --git a/src/core/nm-config.h b/src/core/nm-config.h index d7498f92be..0dd159f47e 100644 --- a/src/core/nm-config.h +++ b/src/core/nm-config.h @@ -18,6 +18,8 @@ #define NM_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_CONFIG)) #define NM_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_CONFIG, NMConfigClass)) +#define NM_CONFIG_KERNEL_CMDLINE_NM_DEBUG "nm.debug" + /* Properties */ #define NM_CONFIG_CMD_LINE_OPTIONS "cmd-line-options" #define NM_CONFIG_ATOMIC_SECTION_PREFIXES "atomic-section-prefixes" @@ -197,4 +199,8 @@ void nm_config_clear_warnings(NMConfig *config); /*****************************************************************************/ +gboolean nm_config_kernel_command_line_nm_debug(void); + +/*****************************************************************************/ + #endif /* __NETWORKMANAGER_CONFIG_H__ */ diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index b2ebe30c25..66f8204502 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -3090,7 +3090,10 @@ again: if (G_UNLIKELY(!proc_cmdline)) { gs_free char *str = NULL; - g_file_get_contents("/proc/cmdline", &str, NULL, NULL); + /* /run/NetworkManager/proc-cmdline can be used to overrule /proc/cmdline. */ + if (!g_file_get_contents(NMRUNDIR "/proc-cmdline", &str, NULL, NULL)) + g_file_get_contents("/proc/cmdline", &str, NULL, NULL); + str = nm_str_realloc(str); proc_cmdline = str ?: ""; diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 67a4d58852..6128b0cb8a 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -2288,9 +2288,11 @@ nm_utils_escaped_tokens_options_split(char *str, const char **out_key, const cha char ** nm_utils_strsplit_quoted(const char *str) { - gs_unref_ptrarray GPtrArray *arr = NULL; - gs_free char *str_out = NULL; - CharLookupTable ch_lookup; + char **arr = NULL; + gsize arr_len = 0; + gsize arr_alloc = 0; + gs_free char *str_out = NULL; + CharLookupTable ch_lookup; nm_assert(str); @@ -2347,19 +2349,32 @@ nm_utils_strsplit_quoted(const char *str) str++; } - if (!arr) - arr = g_ptr_array_new(); - g_ptr_array_add(arr, g_strndup(str_out, j)); + if (arr_len >= arr_alloc) { + if (arr_alloc == 0) + arr_alloc = 4; + else + arr_alloc *= 2; + arr = g_realloc(arr, sizeof(char *) * arr_alloc); + } + + arr[arr_len++] = g_strndup(str_out, j); } if (!arr) return g_new0(char *, 1); - g_ptr_array_add(arr, NULL); - /* We want to return an optimally sized strv array, with no excess * memory allocated. Hence, clone once more. */ - return nm_memdup(arr->pdata, sizeof(char *) * arr->len); + + if (arr_len + 1u != arr_alloc) { + gs_free char **arr_old = arr; + + arr = g_new(char *, arr_len + 1u); + memcpy(arr, arr_old, sizeof(char *) * arr_len); + } + + arr[arr_len] = NULL; + return arr; } /*****************************************************************************/