core: add o.fd.NM.Settings.LoadConnections

Add a D-Bus method to reload connection files specified by
filename, and implement it in the ifcfg-rh and keyfile backends.

https://bugzilla.gnome.org/show_bug.cgi?id=709830
This commit is contained in:
Dan Winship 2013-10-31 15:17:33 -04:00
parent 65737d9e48
commit 51c6269d46
6 changed files with 164 additions and 8 deletions

View file

@ -82,6 +82,40 @@
</arg>
</method>
<method name="LoadConnections">
<tp:docstring>
Loads or reloads the indicated connections from disk. You
should call this after making changes directly to an on-disk
connection file to make sure that NetworkManager sees the
changes. (If "monitor-connection-files" in NetworkManager.conf
is "true", then this will have no real effect, but is
harmless.) As with AddConnection(), this operation does not
necessarily start the network connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_load_connections"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="filenames" type="as" direction="in">
<tp:docstring>
Array of paths to on-disk connection profiles in directories
monitored by NetworkManager.
</tp:docstring>
</arg>
<arg name="status" type="b" direction="out">
<tp:docstring>
Success or failure of the operation as a whole. True if
NetworkManager at least tried to load the indicated
connections, even if it did not succeed. False if an error
occurred before trying to load the connections (eg,
permission denied).
</tp:docstring>
</arg>
<arg name="failures" type="as" direction="out">
<tp:docstring>
Paths of connection files that could not be loaded.
</tp:docstring>
</arg>
</method>
<method name="ReloadConnections">
<tp:docstring>
Tells NetworkManager to reload all connection files from disk,

View file

@ -104,6 +104,10 @@ static void impl_settings_add_connection_unsaved (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
static void impl_settings_load_connections (NMSettings *self,
char **filenames,
DBusGMethodInvocation *context);
static void impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context);
@ -1223,22 +1227,20 @@ impl_settings_add_connection_unsaved (NMSettings *self,
impl_settings_add_connection_helper (self, settings, FALSE, context);
}
static void
impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context)
static gboolean
ensure_root (NMDBusManager *dbus_mgr,
DBusGMethodInvocation *context)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
gulong caller_uid;
GError *error = NULL;
if (!nm_dbus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid, NULL)) {
if (!nm_dbus_manager_get_caller_info (dbus_mgr, context, NULL, &caller_uid, NULL)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_PERMISSION_DENIED,
"Unable to determine request UID.");
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
return FALSE;
}
if (caller_uid != 0) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
@ -1246,9 +1248,57 @@ impl_settings_reload_connections (NMSettings *self,
"Permission denied");
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
return FALSE;
}
return TRUE;
}
static void
impl_settings_load_connections (NMSettings *self,
char **filenames,
DBusGMethodInvocation *context)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GPtrArray *failures;
GSList *iter;
int i;
if (!ensure_root (priv->dbus_mgr, context))
return;
failures = g_ptr_array_new ();
for (i = 0; filenames[i]; i++) {
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
if (nm_system_config_interface_load_connection (plugin, filenames[i]))
break;
}
if (!iter) {
if (!g_path_is_absolute (filenames[i]))
nm_log_warn (LOGD_SETTINGS, "Connection filename '%s' is not an absolute path", filenames[i]);
g_ptr_array_add (failures, (char *) filenames[i]);
}
}
g_ptr_array_add (failures, NULL);
dbus_g_method_return (context, failures->len == 1, failures->pdata);
g_ptr_array_unref (failures);
}
static void
impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
if (!ensure_root (priv->dbus_mgr, context))
return;
if (!priv->connections_loaded) {
load_connections (self);
} else {

View file

@ -145,6 +145,17 @@ nm_system_config_interface_get_connections (NMSystemConfigInterface *config)
return NULL;
}
gboolean
nm_system_config_interface_load_connection (NMSystemConfigInterface *config,
const char *filename)
{
g_return_val_if_fail (config != NULL, NULL);
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->load_connection)
return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->load_connection (config, filename);
return FALSE;
}
void
nm_system_config_interface_reload_connections (NMSystemConfigInterface *config)
{

View file

@ -90,6 +90,12 @@ struct _NMSystemConfigInterface {
*/
GSList * (*get_connections) (NMSystemConfigInterface *config);
/* Requests that the plugin load/reload a single connection, if it
* recognizes the filename. Returns success or failure.
*/
gboolean (*load_connection) (NMSystemConfigInterface *config,
const char *filename);
/* Requests that the plugin reload all connection files from disk,
* and emit signals reflecting new, changed, and removed connections.
*/
@ -150,6 +156,8 @@ void nm_system_config_interface_init (NMSystemConfigInterface *config,
GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config);
gboolean nm_system_config_interface_load_connection (NMSystemConfigInterface *config,
const char *filename);
void nm_system_config_interface_reload_connections (NMSystemConfigInterface *config);
GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config);

View file

@ -512,6 +512,30 @@ get_connections (NMSystemConfigInterface *config)
return list;
}
static gboolean
load_connection (NMSystemConfigInterface *config,
const char *filename)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
NMIfcfgConnection *connection;
int dir_len = strlen (IFCFG_DIR);
if ( strncmp (filename, IFCFG_DIR, dir_len) != 0
|| filename[dir_len] != '/'
|| strchr (filename + dir_len + 1, '/') != NULL)
return FALSE;
if (utils_should_ignore_file (filename + dir_len + 1, TRUE))
return FALSE;
connection = find_by_path (plugin, filename);
connection_new_or_changed (plugin, filename, connection, NULL);
if (!connection)
connection = find_by_path (plugin, filename);
return (connection != NULL);
}
static void
reload_connections (NMSystemConfigInterface *config)
{
@ -968,6 +992,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
system_config_interface_class->add_connection = add_connection;
system_config_interface_class->load_connection = load_connection;
system_config_interface_class->reload_connections = reload_connections;
system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
system_config_interface_class->get_unrecognized_specs = get_unrecognized_specs;

View file

@ -406,6 +406,33 @@ get_connections (NMSystemConfigInterface *config)
return list;
}
static gboolean
load_connection (NMSystemConfigInterface *config,
const char *filename)
{
SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
NMKeyfileConnection *connection;
int dir_len = strlen (KEYFILE_DIR);
if ( strncmp (filename, KEYFILE_DIR, dir_len) != 0
|| filename[dir_len] != '/'
|| strchr (filename + dir_len + 1, '/') != NULL)
return FALSE;
if (nm_keyfile_plugin_utils_should_ignore_file (filename + dir_len + 1))
return FALSE;
connection = find_by_path (self, filename);
if (connection)
update_connection (self, connection, filename);
else {
new_connection (self, filename, NULL);
connection = find_by_path (self, filename);
}
return (connection != NULL);
}
static void
reload_connections (NMSystemConfigInterface *config)
{
@ -705,6 +732,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
{
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
system_config_interface_class->load_connection = load_connection;
system_config_interface_class->reload_connections = reload_connections;
system_config_interface_class->add_connection = add_connection;
system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;