From a2e6e7f2a96bee0be8fb114e829e5f2318465984 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 9 Sep 2019 16:59:02 +0200 Subject: systemd: use busctl instead of dbus-send While dbus-send may not be installed, busctl is shipped with systemd and so it should be always available. --- data/NetworkManager.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/NetworkManager.service.in b/data/NetworkManager.service.in index 2f442bf233..91ebd9a36e 100644 --- a/data/NetworkManager.service.in +++ b/data/NetworkManager.service.in @@ -8,7 +8,7 @@ Before=network.target @DISTRO_NETWORK_SERVICE@ [Service] Type=dbus BusName=org.freedesktop.NetworkManager -ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0 +ExecReload=/usr/bin/busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Reload u 0 #ExecReload=/bin/kill -HUP $MAINPID ExecStart=@sbindir@/NetworkManager --no-daemon Restart=on-failure -- cgit v1.2.1 From c1c970f1b180bc17422e61fc0d1b02addc3167fd Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 5 Sep 2019 14:54:22 +0200 Subject: libnm: export reload flags Flags to the manager Reload() method are stable API but not exposed in a public header. Export them. --- libnm-core/nm-dbus-interface.h | 28 ++++++++++++++++++++++++++++ libnm/libnm.ver | 1 + src/main.c | 2 +- src/nm-config-data.h | 19 ------------------- src/nm-manager.c | 8 ++++---- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index f00506e2d7..1e7f377d12 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -1122,4 +1122,32 @@ typedef enum { NM_TERNARY_TRUE = 1, } NMTernary; +/** + * NMManagerReloadFlags: + * @NM_MANAGER_RELOAD_FLAG_NONE: an alias for numeric zero, no flags set. This + * reloads everything that is supported and is identical to a SIGHUP. + * @NM_MANAGER_RELOAD_FLAG_CONF: reload the NetworkManager.conf configuration + * from disk. Note that this does not include connections, which can be + * reloaded via Setting's ReloadConnections(). + * @NM_MANAGER_RELOAD_FLAG_DNS_RC: update DNS configuration, which usually + * involves writing /etc/resolv.conf anew. + * @NM_MANAGER_RELOAD_FLAG_DNS_FULL: means to restart the DNS plugin. This + * is for example useful when using dnsmasq plugin, which uses additional + * configuration in /etc/NetworkManager/dnsmasq.d. If you edit those files, + * you can restart the DNS plugin. This action shortly interrupts name + * resolution. + * @NM_MANAGER_RELOAD_FLAG_ALL: all flags. + * + * Flags for the manager Reload() call. + * + * Since: 1.22 + */ +typedef enum { /*< flags >*/ + NM_MANAGER_RELOAD_FLAG_NONE = 0, /*< skip >*/ + NM_MANAGER_RELOAD_FLAG_CONF = 0x1, + NM_MANAGER_RELOAD_FLAG_DNS_RC = 0x2, + NM_MANAGER_RELOAD_FLAG_DNS_FULL = 0x4, + NM_MANAGER_RELOAD_FLAG_ALL = 0x7, /*< skip >*/ +} NMManagerReloadFlags; + #endif /* __NM_DBUS_INTERFACE_H__ */ diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 68eaf745e9..4f2fce6d8c 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1631,5 +1631,6 @@ global: libnm_1_22_0 { global: + nm_manager_reload_flags_get_type; nm_setting_gsm_get_auto_config; } libnm_1_20_0; diff --git a/src/main.c b/src/main.c index 8267a16670..86b87dc971 100644 --- a/src/main.c +++ b/src/main.c @@ -89,7 +89,7 @@ _init_nm_debug (NMConfig *config) debug = nm_config_data_get_value (nm_config_get_data_orig (config), NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG, - NM_MANAGER_RELOAD_FLAGS_NONE); + NM_CONFIG_GET_VALUE_NONE); flags = nm_utils_parse_debug_string (env, keys, G_N_ELEMENTS (keys)); flags |= nm_utils_parse_debug_string (debug, keys, G_N_ELEMENTS (keys)); diff --git a/src/nm-config-data.h b/src/nm-config-data.h index 57f97020d0..76d4432ce9 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -25,25 +25,6 @@ #define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default" #define NM_CONFIG_DATA_DNS_MODE "dns" -/* The flags for Reload. Currently these are internal defines, - * only their numeric value matters and must be stable as - * they are public API! Also, the enum must fit in uint32. */ -enum { /*< skip >*/ - NM_MANAGER_RELOAD_FLAGS_NONE = 0, - - /* reload the configuration from disk */ - NM_MANAGER_RELOAD_FLAGS_CONF = (1LL << 0), - - /* write DNS configuration to resolv.conf */ - NM_MANAGER_RELOAD_FLAGS_DNS_RC = (1LL << 1), - - /* restart the DNS plugin (includes DNS_RC) */ - NM_MANAGER_RELOAD_FLAGS_DNS_FULL = (1LL << 2), - - _NM_MANAGER_RELOAD_FLAGS_ALL, - NM_MANAGER_RELOAD_FLAGS_ALL = ((_NM_MANAGER_RELOAD_FLAGS_ALL - 1) << 1) - 1, -}; - typedef enum { /*< flags >*/ NM_CONFIG_GET_VALUE_NONE = 0, diff --git a/src/nm-manager.c b/src/nm-manager.c index 6d4fb0f55d..6a01426753 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1155,16 +1155,16 @@ _reload_auth_cb (NMAuthChain *chain, NM_MANAGER_ERROR_PERMISSION_DENIED, "Not authorized to reload configuration"); } else { - if (NM_FLAGS_ANY (flags, ~NM_MANAGER_RELOAD_FLAGS_ALL)) { + if (NM_FLAGS_ANY (flags, ~NM_MANAGER_RELOAD_FLAG_ALL)) { /* invalid flags */ } else if (flags == 0) reload_type = NM_CONFIG_CHANGE_CAUSE_SIGHUP; else { - if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_CONF)) + if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAG_CONF)) reload_type |= NM_CONFIG_CHANGE_CAUSE_CONF; - if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_DNS_RC)) + if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAG_DNS_RC)) reload_type |= NM_CONFIG_CHANGE_CAUSE_DNS_RC; - if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_DNS_FULL)) + if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAG_DNS_FULL)) reload_type |= NM_CONFIG_CHANGE_CAUSE_DNS_FULL; } -- cgit v1.2.1 From 07e838567e7d7ae3fc5da9a7cd6902c34763f269 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 5 Sep 2019 15:19:33 +0200 Subject: libnm: add nm_client_reload() Introduce libnm API to reload NM configuration through the Reload() D-Bus method. --- libnm/libnm.ver | 2 ++ libnm/nm-client.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libnm/nm-client.h | 11 ++++++++ libnm/nm-manager.c | 58 ++++++++++++++++++++++++++++++++++++++ libnm/nm-manager.h | 9 ++++++ 5 files changed, 162 insertions(+) diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 4f2fce6d8c..e9a69d6881 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1631,6 +1631,8 @@ global: libnm_1_22_0 { global: + nm_client_reload; + nm_client_reload_finish; nm_manager_reload_flags_get_type; nm_setting_gsm_get_auto_config; } libnm_1_20_0; diff --git a/libnm/nm-client.c b/libnm/nm-client.c index d744406bb9..26bf91f5fa 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -2737,6 +2737,88 @@ nm_client_checkpoint_adjust_rollback_timeout_finish (NMClient *client, error); } +static void +reload_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gs_unref_object GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nm_manager_reload_finish (NM_MANAGER (object), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); +} + +/** + * nm_client_reload: + * @client: the %NMClient + * @flags: flags indicating what to reload. + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Reload NetworkManager's configuration and perform certain updates, like + * flushing caches or rewriting external state to disk. This is similar to + * sending SIGHUP to NetworkManager but it allows for more fine-grained control + * over what to reload (see @flags). It also allows non-root access via + * PolicyKit and contrary to signals it is synchronous. + * + * Since: 1.22 + **/ +void +nm_client_reload (NMClient *client, + NMManagerReloadFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_reload); + if (cancellable) + g_simple_async_result_set_check_cancellable (simple, cancellable); + nm_manager_reload (NM_CLIENT_GET_PRIVATE (client)->manager, + flags, + cancellable, reload_cb, simple); +} + +/** + * nm_client_reload_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_reload(). + * + * Returns: %TRUE on success or %FALSE on failure. + * + * Since: 1.22 + **/ +gboolean +nm_client_reload_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error); +} + /****************************************************************/ /* Object Initialization */ /****************************************************************/ diff --git a/libnm/nm-client.h b/libnm/nm-client.h index 4989800547..f8ffd52508 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -475,6 +475,17 @@ gboolean nm_client_checkpoint_adjust_rollback_timeout_finish (NMClient *client, GAsyncResult *result, GError **error); +NM_AVAILABLE_IN_1_22 +void nm_client_reload (NMClient *client, + NMManagerReloadFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_22 +gboolean nm_client_reload_finish (NMClient *client, + GAsyncResult *result, + GError **error); + G_END_DECLS #endif /* __NM_CLIENT_H__ */ diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c index de1fa04e40..b4111cd040 100644 --- a/libnm/nm-manager.c +++ b/libnm/nm-manager.c @@ -1684,6 +1684,64 @@ nm_manager_checkpoint_adjust_rollback_timeout_finish (NMManager *manager, return !g_simple_async_result_propagate_error (simple, error); } +static void +reload_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gs_unref_object GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_manager_call_reload_finish (NMDBUS_MANAGER (object), + result, + &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); +} + +void +nm_manager_reload (NMManager *manager, + NMManagerReloadFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_MANAGER (manager)); + + simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_reload); + if (cancellable) + g_simple_async_result_set_check_cancellable (simple, cancellable); + + nmdbus_manager_call_reload (NM_MANAGER_GET_PRIVATE (manager)->proxy, + flags, + cancellable, + reload_cb, + simple); + +} + +gboolean +nm_manager_reload_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), + nm_manager_reload), + FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + return !g_simple_async_result_propagate_error (simple, error); +} + /*****************************************************************************/ static void diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h index 0970c2e382..9bbbe53af4 100644 --- a/libnm/nm-manager.h +++ b/libnm/nm-manager.h @@ -224,4 +224,13 @@ void _nm_activate_result_free (_NMActivateResult *result); /*****************************************************************************/ +void nm_manager_reload (NMManager *manager, + NMManagerReloadFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_manager_reload_finish (NMManager *manager, + GAsyncResult *result, + GError **error); + #endif /* __NM_MANAGER_H__ */ -- cgit v1.2.1 From fd8d5a0c7ad66b3fda2a2a73404878306082e679 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 9 Sep 2019 17:01:43 +0200 Subject: cli: don't create a NMClient for the 'connection reload' command It is a waste of resources instantiating a NMClient, filling the object cache and then throwing everything away without using it. This can take seconds on slow systems with many objects. Since the ReloadConnections doesn't need anything from the cache, just execute the D-Bus method call directly. --- clients/cli/common.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ clients/cli/common.h | 8 ++++++++ clients/cli/connections.c | 15 +++++++++++---- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/clients/cli/common.c b/clients/cli/common.c index eeef9b64c9..9b2d07aacd 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -1421,10 +1421,56 @@ nmc_error_get_simple_message (GError *error) /* Return a clear message instead of the obscure D-Bus policy error */ if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED)) return _("access denied"); + if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) + return _("NetworkManager is not running"); else return error->message; } +GVariant * +nmc_dbus_call_sync (NmCli *nmc, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GError **error) +{ + gs_unref_object GDBusConnection *connection = NULL; + gs_free_error GError *local = NULL; + GVariant *result; + + if (nmc->timeout == -1) + nmc->timeout = 90; + + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local); + if (!connection) { + g_set_error (error, + NMCLI_ERROR, + NMC_RESULT_ERROR_UNKNOWN, + _("Error: error connecting to system bus: %s"), + local->message); + return NULL; + } + + result = g_dbus_connection_call_sync (connection, + "org.freedesktop.NetworkManager", + object_path, + interface_name, + method_name, + parameters, + reply_type, + G_DBUS_CALL_FLAGS_NONE, + nmc->timeout * 1000, + NULL, + error); + + if (error && *error) + g_dbus_error_strip_remote_error (*error); + + return result; +} + /*****************************************************************************/ NM_UTILS_LOOKUP_STR_DEFINE (nm_connectivity_to_string, NMConnectivityState, diff --git a/clients/cli/common.h b/clients/cli/common.h index 40dee6d0f4..50574a1baf 100644 --- a/clients/cli/common.h +++ b/clients/cli/common.h @@ -89,4 +89,12 @@ extern const NmcMetaGenericInfo *const metagen_dhcp_config[]; const char *nm_connectivity_to_string (NMConnectivityState connectivity); +GVariant *nmc_dbus_call_sync (NmCli *nmc, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GError **error); + #endif /* NMC_COMMON_H */ diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 8e848ffd19..003400d5fe 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -8845,17 +8845,24 @@ do_connection_monitor (NmCli *nmc, int argc, char **argv) static NMCResultCode do_connection_reload (NmCli *nmc, int argc, char **argv) { - GError *error = NULL; + gs_unref_variant GVariant *result = NULL; + gs_free_error GError *error = NULL; next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; - if (!nm_client_reload_connections (nmc->client, NULL, &error)) { + result = nmc_dbus_call_sync (nmc, + "/org/freedesktop/NetworkManager/Settings", + "org.freedesktop.NetworkManager.Settings", + "ReloadConnections", + g_variant_new ("()"), + G_VARIANT_TYPE("(b)"), + &error); + if (error) { g_string_printf (nmc->return_text, _("Error: failed to reload connections: %s."), nmc_error_get_simple_message (error)); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - g_clear_error (&error); } return nmc->return_value; @@ -9245,7 +9252,7 @@ static const NMCCommand connection_cmds[] = { { "add", do_connection_add, usage_connection_add, TRUE, TRUE }, { "edit", do_connection_edit, usage_connection_edit, TRUE, TRUE }, { "delete", do_connection_delete, usage_connection_delete, TRUE, TRUE }, - { "reload", do_connection_reload, usage_connection_reload, TRUE, TRUE }, + { "reload", do_connection_reload, usage_connection_reload, FALSE, FALSE }, { "load", do_connection_load, usage_connection_load, TRUE, TRUE }, { "modify", do_connection_modify, usage_connection_modify, TRUE, TRUE }, { "clone", do_connection_clone, usage_connection_clone, TRUE, TRUE }, -- cgit v1.2.1 From 5afcf9c045adc883ddeec5f1671fc3dd56d79c18 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 5 Sep 2019 18:32:57 +0200 Subject: cli: add 'general reload' command Add 'nmcli general reload [flags]' command to reload NM configuration and perform other updates. --- clients/cli/general.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/clients/cli/general.c b/clients/cli/general.c index b70edf9217..14502111d7 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -353,6 +353,38 @@ usage_general_permissions (void) "Show caller permissions for authenticated operations.\n\n")); } +static void +usage_general_reload (void) +{ + g_printerr (_("Usage: nmcli general reload { ARGUMENTS | help }\n" + "\n" + "ARGUMENTS := [[,...]]\n" + "\n" + "Reload NetworkManager's configuration and perform certain updates, like\n" + "flushing caches or rewriting external state to disk. This is similar to\n" + "sending SIGHUP to NetworkManager but it allows for more fine-grained\n" + "control over what to reload through the flags argument. It also allows\n" + "non-root access via PolicyKit and contrary to signals it is synchronous.\n" + "\n" + "Available flags are:\n" + "\n" + " 'conf' Reload the NetworkManager.conf configuration from\n" + " disk. Note that this does not include connections, which\n" + " can be reloaded through 'nmcli connection reload' instead.\n" + "\n" + " 'dns-rc' Update DNS configuration, which usually involves writing\n" + " /etc/resolv.conf anew.\n" + "\n" + " 'dns-full' Restart the DNS plugin. This is for example useful when\n" + " using dnsmasq plugin, which uses additional configuration\n" + " in /etc/NetworkManager/dnsmasq.d. If you edit those files,\n" + " you can restart the DNS plugin. This action shortly\n" + " interrupts name resolution.\n" + "\n" + "With no flags, everything that is supported is reloaded, which is\n" + "identical to sending a SIGHUP.\n")); +} + static void usage_general_logging (void) { @@ -595,6 +627,70 @@ show_nm_permissions (NmCli *nmc) return TRUE; } +static NMCResultCode +do_general_reload (NmCli *nmc, int argc, char **argv) +{ + gs_unref_variant GVariant *result = NULL; + gs_free_error GError *error = NULL; + gs_free const char **values = NULL; + gs_free char *err_token = NULL; + gs_free char *joined = NULL; + int flags = 0; + + next_arg (nmc, &argc, &argv, NULL); + + if (nmc->complete) { + if (argc == 0) + return nmc->return_value; + + if (argc == 1) { + values = nm_utils_enum_get_values (nm_manager_reload_flags_get_type (), + NM_MANAGER_RELOAD_FLAG_CONF, + NM_MANAGER_RELOAD_FLAG_ALL); + nmc_complete_strv (*argv, -1, values); + } + return nmc->return_value; + } + + if (argc > 0) { + if (!nm_utils_enum_from_str (nm_manager_reload_flags_get_type (), *argv, &flags, &err_token)) { + values = nm_utils_enum_get_values (nm_manager_reload_flags_get_type (), + NM_MANAGER_RELOAD_FLAG_CONF, + NM_MANAGER_RELOAD_FLAG_ALL); + joined = g_strjoinv (",", (char **) values); + g_string_printf (nmc->return_text, + _("Error: invalid reload flag '%s'. Allowed flags are: %s"), + err_token, + joined); + return NMC_RESULT_ERROR_USER_INPUT; + } + argc--; + argv++; + } + + if (argc > 0) { + g_string_printf (nmc->return_text, _("Error: extra argument '%s'"), *argv); + return NMC_RESULT_ERROR_USER_INPUT; + } + + result = nmc_dbus_call_sync (nmc, + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + "Reload", + g_variant_new ("(u)", flags), + G_VARIANT_TYPE("()"), + &error); + + if (error) { + g_string_printf (nmc->return_text, + _("Error: failed to reload: %s"), + nmc_error_get_simple_message (error)); + return NMC_RESULT_ERROR_UNKNOWN; + } + + return nmc->return_value; +} + static NMCResultCode do_general_permissions (NmCli *nmc, int argc, char **argv) { @@ -772,6 +868,7 @@ static const NMCCommand general_cmds[] = { { "hostname", do_general_hostname, usage_general_hostname, TRUE, TRUE }, { "permissions", do_general_permissions, usage_general_permissions, TRUE, TRUE }, { "logging", do_general_logging, usage_general_logging, TRUE, TRUE }, + { "reload", do_general_reload, usage_general_reload, FALSE, FALSE }, { NULL, do_general_status, usage_general, TRUE, TRUE }, }; -- cgit v1.2.1