libnm: port NMRemoteSettings to NMObject

NMRemoteSettings duplicates a bunch of NMObject's functionality that
it doesn't need to. In libnm-glib, it wouldn't have been possible to
port NMRemoteSettings to NMObject without breaking ABI, but now in
libnm we can do that.

As a side effect of this, NMRemoteSettings gains a "connections"
property, and "connection-added" and "connection-removed" signals
(with the former replacing the old "new-connection" signal). This also
removes the "connections-loaded" signal, since the connections will
now always be loaded (via the initialization of the "connections"
property) during init()/init_async().

Also, this removes NMRemoteConnection's "removed" signal, since it's
redundant with the new NMRemoteSettings::connection-removed (and
having the signal on NMRemoteSettings instead is more consistent with
other objects).
This commit is contained in:
Dan Winship 2014-07-20 12:55:59 -04:00
parent d7e99f8375
commit 57e802f3aa
10 changed files with 362 additions and 935 deletions

View file

@ -228,16 +228,9 @@ static NmcOutputField nmc_fields_con_active_details_groups[] = {
#define CON_SHOW_DETAIL_GROUP_PROFILE "profile"
#define CON_SHOW_DETAIL_GROUP_ACTIVE "active"
typedef struct {
NmCli *nmc;
int argc;
char **argv;
} ArgsInfo;
/* glib main loop variable - defined in nmcli.c */
extern GMainLoop *loop;
static ArgsInfo args_info;
static guint progress_id = 0; /* ID of event source for displaying progress */
/* for readline TAB completion in editor */
@ -8607,21 +8600,6 @@ opt_error:
return nmc->return_value;
}
/* callback called when connections are obtained from the settings service */
static void
get_connections_cb (NMRemoteSettings *settings, gpointer user_data)
{
ArgsInfo *args = (ArgsInfo *) user_data;
/* Get the connection list */
args->nmc->system_connections = nm_remote_settings_list_connections (settings);
parse_cmd (args->nmc, args->argc, args->argv);
if (!args->nmc->should_wait)
quit ();
}
/* Entry point function for connections-related commands: 'nmcli connection' */
NMCResultCode
do_connections (NmCli *nmc, int argc, char **argv)
@ -8651,10 +8629,6 @@ do_connections (NmCli *nmc, int argc, char **argv)
nmc->should_wait = TRUE;
args_info.nmc = nmc;
args_info.argc = argc;
args_info.argv = argv;
/* get system settings */
if (!(nmc->system_settings = nm_remote_settings_new (NULL, &error))) {
g_string_printf (nmc->return_text, _("Error: Could not get system settings: %s."), error->message);
@ -8674,13 +8648,13 @@ do_connections (NmCli *nmc, int argc, char **argv)
return nmc->return_value;
}
/* connect to signal "connections-read" - emitted when connections are fetched and ready */
g_signal_connect (nmc->system_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ,
G_CALLBACK (get_connections_cb), &args_info);
/* Get the connection list */
nmc->system_connections = nm_remote_settings_list_connections (nmc->system_settings);
/* The rest will be done in get_connection_cb() callback.
* We need to wait for signals that connections are read.
*/
parse_cmd (nmc, argc, argv);
if (!nmc->should_wait)
quit ();
return NMC_RESULT_SUCCESS;
}
}

View file

@ -204,8 +204,6 @@ nmt_edit_connection_list_rebuild (NmtEditConnectionList *list)
g_signal_connect (conn, NM_REMOTE_CONNECTION_UPDATED,
G_CALLBACK (rebuild_on_connection_updated), list);
g_signal_connect (conn, NM_REMOTE_CONNECTION_REMOVED,
G_CALLBACK (rebuild_on_connection_updated), list);
g_object_ref (iter->data);
}
priv->connections = g_slist_sort (priv->connections, sort_by_timestamp);
@ -279,9 +277,9 @@ nmt_edit_connection_list_rebuild (NmtEditConnectionList *list)
}
static void
rebuild_on_new_connection (NMRemoteSettings *settings,
NMRemoteConnection *connection,
gpointer list)
rebuild_on_connections_changed (GObject *object,
GParamSpec *pspec,
gpointer list)
{
nmt_edit_connection_list_rebuild (list);
}
@ -295,8 +293,8 @@ nmt_edit_connection_list_constructed (GObject *object)
if (priv->extra)
nmt_newt_button_box_add_widget_end (priv->buttons, priv->extra);
g_signal_connect (nm_settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
G_CALLBACK (rebuild_on_new_connection), list);
g_signal_connect (nm_settings, "notify::" NM_REMOTE_SETTINGS_CONNECTIONS,
G_CALLBACK (rebuild_on_connections_changed), list);
nmt_edit_connection_list_rebuild (list);

View file

@ -426,6 +426,7 @@ nmt_edit_connection (NMConnection *connection)
typedef struct {
NmtSyncOp op;
gboolean got_callback, got_signal;
NMRemoteConnection *connection;
} ConnectionDeleteData;
static void
@ -446,14 +447,17 @@ connection_deleted_callback (NMRemoteConnection *connection,
}
static void
connection_removed_signal (NMRemoteConnection *connection,
connection_removed_signal (NMRemoteSettings *settings,
NMRemoteConnection *connection,
gpointer user_data)
{
ConnectionDeleteData *data = user_data;
data->got_signal = TRUE;
if (data->got_callback && data->got_signal)
nmt_sync_op_complete_boolean (&data->op, TRUE, NULL);
if (connection == data->connection) {
data->got_signal = TRUE;
if (data->got_callback && data->got_signal)
nmt_sync_op_complete_boolean (&data->op, TRUE, NULL);
}
}
void
@ -473,8 +477,8 @@ nmt_remove_connection (NMRemoteConnection *connection)
data.got_callback = data.got_signal = FALSE;
nmt_sync_op_init (&data.op);
g_object_ref (connection);
g_signal_connect (connection, NM_REMOTE_CONNECTION_REMOVED,
data.connection = connection;
g_signal_connect (nm_settings, NM_REMOTE_SETTINGS_CONNECTION_REMOVED,
G_CALLBACK (connection_removed_signal), &data);
nm_remote_connection_delete (connection, connection_deleted_callback, &data);
@ -484,8 +488,7 @@ nmt_remove_connection (NMRemoteConnection *connection)
g_error_free (error);
}
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_removed_signal), &data);
g_object_unref (connection);
g_signal_handlers_disconnect_by_func (nm_settings, G_CALLBACK (connection_removed_signal), &data);
}
NmtNewtForm *

View file

@ -140,15 +140,6 @@ nmtui_quit (void)
g_main_loop_quit (loop);
}
static void
connections_read (NMRemoteSettings *settings,
gpointer user_data)
{
gboolean *got_connections = user_data;
*got_connections = TRUE;
}
static void
usage (void)
{
@ -217,7 +208,6 @@ GOptionEntry entries[] = {
int
main (int argc, char **argv)
{
gboolean got_connections = FALSE;
GOptionContext *opts;
GError *error = NULL;
NmtuiStartupData startup_data;
@ -260,11 +250,6 @@ main (int argc, char **argv)
g_error_free (error);
exit (1);
}
g_signal_connect (nm_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ,
G_CALLBACK (connections_read), &got_connections);
/* coverity[loop_condition] */
while (!got_connections)
g_main_context_iteration (NULL, TRUE);
if (sleep_on_startup)
sleep (5);

View file

@ -27,38 +27,9 @@
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <NetworkManager.h>
/* Global variables */
GMainLoop *loop = NULL; /* Main loop variable - needed for waiting for signal */
int result = EXIT_SUCCESS;
static void
signal_handler (int signo)
{
if (signo == SIGINT || signo == SIGTERM) {
g_message ("Caught signal %d, shutting down...", signo);
g_main_loop_quit (loop);
}
}
static void
setup_signals (void)
{
struct sigaction action;
sigset_t mask;
sigemptyset (&mask);
action.sa_handler = signal_handler;
action.sa_mask = mask;
action.sa_flags = 0;
sigaction (SIGTERM, &action, NULL);
sigaction (SIGINT, &action, NULL);
}
/* Print details of connection */
static void
show_connection (gpointer data, gpointer user_data)
@ -89,14 +60,35 @@ show_connection (gpointer data, gpointer user_data)
}
}
/* This callback is called when connections from the settings service are ready.
* Now the connections can be listed.
*/
static void
get_connections_cb (NMRemoteSettings *settings, gpointer user_data)
int
main (int argc, char *argv[])
{
NMRemoteSettings *settings;
gboolean settings_running;
GError *error = NULL;
GSList *connections;
#if !GLIB_CHECK_VERSION (2, 35, 0)
/* Initialize GType system */
g_type_init ();
#endif
/* Get system settings */
if (!(settings = nm_remote_settings_new (NULL, &error))) {
g_message ("Error: Could not get system settings: %s.", error->message);
g_error_free (error);
return EXIT_FAILURE;
}
/* Find out whether setting service is running */
g_object_get (settings, NM_REMOTE_SETTINGS_NM_RUNNING, &settings_running, NULL);
if (!settings_running) {
g_message ("Error: Can't obtain connections: settings service is not running.");
return EXIT_FAILURE;
}
/* Now the connections can be listed. */
connections = nm_remote_settings_list_connections (settings);
printf ("Connections:\n===================\n");
@ -106,68 +98,5 @@ get_connections_cb (NMRemoteSettings *settings, gpointer user_data)
g_slist_free (connections);
g_object_unref (settings);
/* We are done, exit main loop */
g_main_loop_quit (loop);
}
/* Get system settings and then connect to connections-read signal */
static gboolean
list_connections (gpointer data)
{
NMRemoteSettings *settings;
gboolean settings_running;
GError *error = NULL;
/* Get system settings */
if (!(settings = nm_remote_settings_new (NULL, &error))) {
g_message ("Error: Could not get system settings: %s.", error->message);
g_error_free (error);
result = EXIT_FAILURE;
g_main_loop_quit (loop);
return FALSE;
}
/* Find out whether setting service is running */
g_object_get (settings, NM_REMOTE_SETTINGS_NM_RUNNING, &settings_running, NULL);
if (!settings_running) {
g_message ("Error: Can't obtain connections: settings service is not running.");
result = EXIT_FAILURE;
g_main_loop_quit (loop);
return FALSE;
}
/* Connect to signal "connections-read" - emitted when connections are fetched and ready */
g_signal_connect (settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ,
G_CALLBACK (get_connections_cb), NULL);
return FALSE;
}
int main (int argc, char *argv[])
{
DBusGConnection *bus;
#if !GLIB_CHECK_VERSION (2, 35, 0)
/* Initialize GType system */
g_type_init ();
#endif
/* Get system bus */
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
/* Run list_connections from main loop, because we need to wait for "connections-read"
* signal to have connections ready. The execution will be finished in get_connections_cb()
* callback on the signal.
*/
g_idle_add (list_connections, bus);
loop = g_main_loop_new (NULL, FALSE); /* Create main loop */
setup_signals (); /* Setup UNIX signals */
g_main_loop_run (loop); /* Run main loop */
g_main_loop_unref (loop);
dbus_g_connection_unref (bus);
return result;
return EXIT_SUCCESS;
}

View file

@ -57,7 +57,6 @@ enum {
enum {
UPDATED,
REMOVED,
LAST_SIGNAL
};
@ -453,8 +452,6 @@ replace_settings (NMRemoteConnection *self, GHashTable *new_settings)
error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
g_clear_error (&error);
g_signal_emit (self, signals[REMOVED], 0);
}
}
@ -477,11 +474,7 @@ updated_get_settings_cb (DBusGProxy *proxy,
g_error_free (error);
/* Connection is no longer visible to this user. Let the settings
* service handle this via 'visible'. The settings service will emit
* the "removed" signal for us since it handles the lifetime of this
* object.
*/
/* Connection is no longer visible to this user. */
hash = g_hash_table_new (g_str_hash, g_str_equal);
nm_connection_replace_settings (NM_CONNECTION (self), hash, NULL);
g_hash_table_destroy (hash);
@ -514,12 +507,6 @@ updated_cb (DBusGProxy *proxy, gpointer user_data)
}
}
static void
removed_cb (DBusGProxy *proxy, gpointer user_data)
{
g_signal_emit (G_OBJECT (user_data), signals[REMOVED], 0);
}
static void
properties_changed_cb (DBusGProxy *proxy,
GHashTable *properties,
@ -558,9 +545,6 @@ init_common (NMRemoteConnection *self)
dbus_g_proxy_add_signal (priv->proxy, "Updated", G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "Updated", G_CALLBACK (updated_cb), self, NULL);
dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "Removed", G_CALLBACK (removed_cb), self, NULL);
g_signal_connect (priv->proxy, "destroy", G_CALLBACK (proxy_destroy_cb), self);
/* Monitor properties */
@ -909,22 +893,6 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* NMRemoteConnection::removed:
* @connection: a #NMConnection
*
* This signal is emitted when a connection is either deleted or becomes
* invisible to the current user.
*/
signals[REMOVED] =
g_signal_new (NM_REMOTE_CONNECTION_REMOVED,
G_TYPE_FROM_CLASS (remote_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMRemoteConnectionClass, removed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void

View file

@ -61,7 +61,6 @@ GQuark nm_remote_connection_error_quark (void);
/* Signals */
#define NM_REMOTE_CONNECTION_UPDATED "updated"
#define NM_REMOTE_CONNECTION_REMOVED "removed"
typedef struct {
NMConnection parent;
@ -74,8 +73,6 @@ typedef struct {
void (*updated) (NMRemoteConnection *connection,
GHashTable *new_settings);
void (*removed) (NMRemoteConnection *connection);
/*< private >*/
gpointer padding[8];
} NMRemoteConnectionClass;

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,7 @@
#endif
#include <gio/gio.h>
#include <nm-object.h>
#include <nm-connection.h>
#include <nm-remote-connection.h>
@ -62,13 +63,13 @@ typedef enum {
GQuark nm_remote_settings_error_quark (void);
#define NM_REMOTE_SETTINGS_BUS "bus"
#define NM_REMOTE_SETTINGS_NM_RUNNING "nm-running"
#define NM_REMOTE_SETTINGS_CONNECTIONS "connections"
#define NM_REMOTE_SETTINGS_HOSTNAME "hostname"
#define NM_REMOTE_SETTINGS_CAN_MODIFY "can-modify"
#define NM_REMOTE_SETTINGS_NEW_CONNECTION "new-connection"
#define NM_REMOTE_SETTINGS_CONNECTIONS_READ "connections-read"
#define NM_REMOTE_SETTINGS_CONNECTION_ADDED "connection-added"
#define NM_REMOTE_SETTINGS_CONNECTION_REMOVED "connection-removed"
typedef struct _NMRemoteSettings NMRemoteSettings;
typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass;
@ -90,17 +91,17 @@ typedef void (*NMRemoteSettingsSaveHostnameFunc) (NMRemoteSettings *settings,
struct _NMRemoteSettings {
GObject parent;
NMObject parent;
};
struct _NMRemoteSettingsClass {
GObjectClass parent;
NMObjectClass parent;
/* Signals */
void (*new_connection) (NMRemoteSettings *settings,
NMRemoteConnection *connection);
void (*connections_read) (NMRemoteSettings *settings);
void (*connection_added) (NMRemoteSettings *settings,
NMRemoteConnection *connection);
void (*connection_removed) (NMRemoteSettings *settings,
NMRemoteConnection *connection);
/*< private >*/
gpointer padding[8];

View file

@ -119,9 +119,17 @@ set_visible_cb (DBusGProxy *proxy,
}
static void
invis_removed_cb (NMRemoteConnection *connection, gboolean *done)
visible_changed_cb (GObject *object, GParamSpec *pspec, gboolean *done)
{
*done = TRUE;
if (!nm_remote_connection_get_visible (NM_REMOTE_CONNECTION (object)))
*done = TRUE;
}
static void
connection_removed_cb (NMRemoteSettings *s, NMRemoteConnection *connection, gboolean *done)
{
if (connection == remote)
*done = TRUE;
}
static void
@ -140,13 +148,15 @@ test_make_invisible (void)
time_t start, now;
GSList *list, *iter;
DBusGProxy *proxy;
gboolean done = FALSE, has_settings = FALSE;
gboolean visible_changed = FALSE, connection_removed = FALSE;
gboolean has_settings = FALSE;
char *path;
g_assert (remote != NULL);
/* Listen for the remove event when the connection becomes invisible */
g_signal_connect (remote, "removed", G_CALLBACK (invis_removed_cb), &done);
g_signal_connect (remote, "notify::" NM_REMOTE_CONNECTION_VISIBLE, G_CALLBACK (visible_changed_cb), &visible_changed);
g_signal_connect (settings, "connection-removed", G_CALLBACK (connection_removed_cb), &connection_removed);
path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote)));
proxy = dbus_g_proxy_new_for_name (bus,
@ -164,11 +174,12 @@ test_make_invisible (void)
do {
now = time (NULL);
g_main_context_iteration (NULL, FALSE);
} while ((done == FALSE) && (now - start < 5));
g_assert (done == TRUE);
} while ((!visible_changed || !connection_removed) && (now - start < 5));
g_assert (visible_changed == TRUE);
g_assert (connection_removed == TRUE);
g_assert (remote);
g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (invis_removed_cb), &done);
g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (visible_changed_cb), &visible_changed);
g_signal_handlers_disconnect_by_func (settings, G_CALLBACK (connection_removed_cb), &connection_removed);
/* Ensure NMRemoteSettings no longer has the connection */
list = nm_remote_settings_list_connections (settings);
@ -213,7 +224,7 @@ test_make_visible (void)
g_assert (remote != NULL);
/* Wait for the new-connection signal when the connection is visible again */
g_signal_connect (settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
g_signal_connect (settings, NM_REMOTE_SETTINGS_CONNECTION_ADDED,
G_CALLBACK (vis_new_connection_cb), &new);
path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote)));
@ -275,9 +286,10 @@ deleted_cb (DBusGProxy *proxy,
}
static void
removed_cb (NMRemoteConnection *connection, gboolean *done)
removed_cb (NMRemoteSettings *s, NMRemoteConnection *connection, gboolean *done)
{
*done = TRUE;
if (connection == remote)
*done = TRUE;
}
static void
@ -298,7 +310,7 @@ test_remove_connection (void)
g_assert (connection);
g_assert (remote == connection);
path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
g_signal_connect (connection, "removed", G_CALLBACK (removed_cb), &done);
g_signal_connect (settings, "connection-removed", G_CALLBACK (removed_cb), &done);
proxy = dbus_g_proxy_new_for_name (bus,
NM_DBUS_SERVICE,
@ -373,7 +385,7 @@ test_nm_running (void)
nm_test_service_cleanup (sinfo);
settings2 = g_initable_new (NM_TYPE_REMOTE_SETTINGS, NULL, &error,
NM_REMOTE_SETTINGS_BUS, bus,
NM_OBJECT_DBUS_CONNECTION, bus,
NULL);
g_assert_no_error (error);
g_assert (settings != NULL);
@ -438,7 +450,7 @@ main (int argc, char **argv)
sinfo = nm_test_service_init ();
settings = g_initable_new (NM_TYPE_REMOTE_SETTINGS, NULL, &error,
NM_REMOTE_SETTINGS_BUS, bus,
NM_OBJECT_DBUS_CONNECTION, bus,
NULL);
g_assert_no_error (error);
g_assert (settings != NULL);