mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-14 15:40:30 +01:00
ifcfg-rh: merge branch danw/devtimeout-rh1171917
https://bugzilla.redhat.com/show_bug.cgi?id=1171917
This commit is contained in:
commit
07194fb6a9
8 changed files with 253 additions and 5 deletions
|
|
@ -687,6 +687,11 @@ check_if_startup_complete (NMManager *self)
|
|||
if (!priv->startup)
|
||||
return;
|
||||
|
||||
if (!nm_settings_get_startup_complete (priv->settings)) {
|
||||
nm_log_dbg (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings");
|
||||
return;
|
||||
}
|
||||
|
||||
for (iter = priv->devices; iter; iter = iter->next) {
|
||||
NMDevice *dev = iter->data;
|
||||
|
||||
|
|
@ -721,6 +726,14 @@ device_has_pending_action_changed (NMDevice *device,
|
|||
check_if_startup_complete (self);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_startup_complete_changed (NMSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
NMManager *self)
|
||||
{
|
||||
check_if_startup_complete (self);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device (NMManager *manager,
|
||||
NMDevice *device,
|
||||
|
|
@ -4716,6 +4729,8 @@ nm_manager_new (NMSettings *settings,
|
|||
priv->prop_filter_added = TRUE;
|
||||
|
||||
priv->settings = g_object_ref (settings);
|
||||
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE,
|
||||
G_CALLBACK (settings_startup_complete_changed), singleton);
|
||||
|
||||
priv->state_file = g_strdup (state_file);
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ enum {
|
|||
PROP_0 = 0,
|
||||
PROP_VISIBLE,
|
||||
PROP_UNSAVED,
|
||||
PROP_READY,
|
||||
PROP_FLAGS,
|
||||
};
|
||||
|
||||
|
|
@ -98,6 +99,7 @@ typedef struct {
|
|||
guint session_changed_id;
|
||||
|
||||
NMSettingsConnectionFlags flags;
|
||||
gboolean ready;
|
||||
|
||||
guint updated_idle_id;
|
||||
|
||||
|
|
@ -2167,6 +2169,25 @@ nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connectio
|
|||
return NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_settings_connection_get_ready (NMSettingsConnection *connection)
|
||||
{
|
||||
return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->ready;
|
||||
}
|
||||
|
||||
void
|
||||
nm_settings_connection_set_ready (NMSettingsConnection *connection,
|
||||
gboolean ready)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
ready = !!ready;
|
||||
if (priv->ready != ready) {
|
||||
priv->ready = ready;
|
||||
g_object_notify (G_OBJECT (connection), NM_SETTINGS_CONNECTION_READY);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -2175,6 +2196,7 @@ nm_settings_connection_init (NMSettingsConnection *self)
|
|||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
priv->visible = FALSE;
|
||||
priv->ready = TRUE;
|
||||
|
||||
priv->session_changed_id = nm_session_monitor_connect (session_changed_cb, self);
|
||||
|
||||
|
|
@ -2249,6 +2271,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_UNSAVED:
|
||||
g_value_set_boolean (value, nm_settings_connection_get_unsaved (self));
|
||||
break;
|
||||
case PROP_READY:
|
||||
g_value_set_boolean (value, nm_settings_connection_get_ready (self));
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
g_value_set_uint (value, nm_settings_connection_get_flags (self));
|
||||
break;
|
||||
|
|
@ -2265,6 +2290,9 @@ set_property (GObject *object, guint prop_id,
|
|||
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_READY:
|
||||
nm_settings_connection_set_ready (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
nm_settings_connection_set_flags_all (self, g_value_get_uint (value));
|
||||
break;
|
||||
|
|
@ -2305,6 +2333,13 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_READY,
|
||||
g_param_spec_boolean (NM_SETTINGS_CONNECTION_READY, "", "",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_FLAGS,
|
||||
g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ G_BEGIN_DECLS
|
|||
/* Properties */
|
||||
#define NM_SETTINGS_CONNECTION_VISIBLE "visible"
|
||||
#define NM_SETTINGS_CONNECTION_UNSAVED "unsaved"
|
||||
#define NM_SETTINGS_CONNECTION_READY "ready"
|
||||
#define NM_SETTINGS_CONNECTION_FLAGS "flags"
|
||||
|
||||
|
||||
|
|
@ -196,6 +197,10 @@ gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *connectio
|
|||
gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *connection);
|
||||
gboolean nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connection);
|
||||
|
||||
gboolean nm_settings_connection_get_ready (NMSettingsConnection *connection);
|
||||
void nm_settings_connection_set_ready (NMSettingsConnection *connection,
|
||||
gboolean ready);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ typedef struct {
|
|||
GSList *unmanaged_specs;
|
||||
GSList *unrecognized_specs;
|
||||
GSList *get_connections_cache;
|
||||
|
||||
gboolean startup_complete;
|
||||
} NMSettingsPrivate;
|
||||
|
||||
#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate))
|
||||
|
|
@ -175,10 +177,42 @@ enum {
|
|||
PROP_HOSTNAME,
|
||||
PROP_CAN_MODIFY,
|
||||
PROP_CONNECTIONS,
|
||||
PROP_STARTUP_COMPLETE,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static void
|
||||
check_startup_complete (NMSettings *self)
|
||||
{
|
||||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
||||
GHashTableIter iter;
|
||||
NMSettingsConnection *conn;
|
||||
|
||||
if (priv->startup_complete)
|
||||
return;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->connections);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) {
|
||||
if (!nm_settings_connection_get_ready (conn))
|
||||
return;
|
||||
}
|
||||
|
||||
priv->startup_complete = TRUE;
|
||||
g_object_notify (G_OBJECT (self), NM_SETTINGS_STARTUP_COMPLETE);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_ready_changed (NMSettingsConnection *conn,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSettings *self = NM_SETTINGS (user_data);
|
||||
|
||||
if (nm_settings_connection_get_ready (conn))
|
||||
check_startup_complete (self);
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_connection_added (NMSystemConfigInterface *config,
|
||||
NMSettingsConnection *connection,
|
||||
|
|
@ -771,6 +805,7 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data)
|
|||
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self);
|
||||
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated_by_user), self);
|
||||
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self);
|
||||
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self);
|
||||
|
||||
/* Forget about the connection internally */
|
||||
g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections,
|
||||
|
|
@ -783,6 +818,8 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data)
|
|||
g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_REMOVED, connection);
|
||||
g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTIONS);
|
||||
|
||||
check_startup_complete (self);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
|
|
@ -888,6 +925,11 @@ claim_connection (NMSettings *self,
|
|||
g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
|
||||
G_CALLBACK (connection_visibility_changed),
|
||||
self);
|
||||
if (!priv->startup_complete) {
|
||||
g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY,
|
||||
G_CALLBACK (connection_ready_changed),
|
||||
self);
|
||||
}
|
||||
|
||||
/* Export the connection over D-Bus */
|
||||
g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
|
||||
|
|
@ -1778,6 +1820,16 @@ cp_get_connection_by_uuid (NMConnectionProvider *provider, const char *uuid)
|
|||
|
||||
/***************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_settings_get_startup_complete (NMSettings *self)
|
||||
{
|
||||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
||||
|
||||
return priv->startup_complete;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
NMSettings *
|
||||
nm_settings_new (GError **error)
|
||||
{
|
||||
|
|
@ -1798,6 +1850,7 @@ nm_settings_new (GError **error)
|
|||
}
|
||||
|
||||
load_connections (self);
|
||||
check_startup_complete (self);
|
||||
|
||||
nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_SETTINGS, self);
|
||||
return self;
|
||||
|
|
@ -1898,6 +1951,9 @@ get_property (GObject *object, guint prop_id,
|
|||
g_ptr_array_add (array, g_strdup (path));
|
||||
g_value_take_boxed (value, array);
|
||||
break;
|
||||
case PROP_STARTUP_COMPLETE:
|
||||
g_value_set_boolean (value, nm_settings_get_startup_complete (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@
|
|||
#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS))
|
||||
#define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass))
|
||||
|
||||
#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs"
|
||||
#define NM_SETTINGS_HOSTNAME "hostname"
|
||||
#define NM_SETTINGS_CAN_MODIFY "can-modify"
|
||||
#define NM_SETTINGS_CONNECTIONS "connections"
|
||||
#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs"
|
||||
#define NM_SETTINGS_HOSTNAME "hostname"
|
||||
#define NM_SETTINGS_CAN_MODIFY "can-modify"
|
||||
#define NM_SETTINGS_CONNECTIONS "connections"
|
||||
#define NM_SETTINGS_STARTUP_COMPLETE "connections"
|
||||
|
||||
#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added"
|
||||
#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated"
|
||||
|
|
@ -120,4 +121,6 @@ void nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean qu
|
|||
|
||||
gint nm_settings_sort_connections (gconstpointer a, gconstpointer b);
|
||||
|
||||
gboolean nm_settings_get_startup_complete (NMSettings *self);
|
||||
|
||||
#endif /* __NM_SETTINGS_H__ */
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include <nm-setting-pppoe.h>
|
||||
#include <nm-setting-wireless-security.h>
|
||||
#include <nm-setting-8021x.h>
|
||||
#include <nm-platform.h>
|
||||
#include <nm-logging.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "nm-config.h"
|
||||
|
|
@ -63,6 +65,9 @@ typedef struct {
|
|||
|
||||
char *unmanaged_spec;
|
||||
char *unrecognized_spec;
|
||||
|
||||
gulong devtimeout_link_changed_handler;
|
||||
guint devtimeout_timeout_id;
|
||||
} NMIfcfgConnectionPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -80,6 +85,97 @@ enum {
|
|||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static gboolean
|
||||
devtimeout_ready (gpointer user_data)
|
||||
{
|
||||
NMIfcfgConnection *self = user_data;
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
priv->devtimeout_timeout_id = 0;
|
||||
nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
link_changed (NMPlatform *platform, int ifindex, NMPlatformLink *link,
|
||||
NMPlatformSignalChangeType change_type, NMPlatformReason reason,
|
||||
NMConnection *self)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
const char *ifname;
|
||||
|
||||
ifname = nm_connection_get_interface_name (self);
|
||||
if (g_strcmp0 (link->name, ifname) != 0)
|
||||
return;
|
||||
|
||||
/* Shouldn't happen, but... */
|
||||
if (change_type == NM_PLATFORM_SIGNAL_REMOVED)
|
||||
return;
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Device %s appeared; connection '%s' now ready",
|
||||
ifname, nm_connection_get_id (self));
|
||||
|
||||
g_signal_handler_disconnect (platform, priv->devtimeout_link_changed_handler);
|
||||
priv->devtimeout_link_changed_handler = 0;
|
||||
g_source_remove (priv->devtimeout_timeout_id);
|
||||
|
||||
/* Don't declare the connection ready right away, since NMManager may not have
|
||||
* started processing the device yet.
|
||||
*/
|
||||
priv->devtimeout_timeout_id = g_idle_add (devtimeout_ready, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
devtimeout_expired (gpointer user_data)
|
||||
{
|
||||
NMIfcfgConnection *self = user_data;
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Device for connection '%s' did not appear before timeout",
|
||||
nm_connection_get_id (NM_CONNECTION (self)));
|
||||
|
||||
g_signal_handler_disconnect (nm_platform_get (), priv->devtimeout_link_changed_handler);
|
||||
priv->devtimeout_link_changed_handler = 0;
|
||||
priv->devtimeout_timeout_id = 0;
|
||||
|
||||
nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ifcfg_connection_check_devtimeout (NMIfcfgConnection *self)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
NMSettingConnection *s_con;
|
||||
const char *ifname;
|
||||
guint devtimeout;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (NM_CONNECTION (self));
|
||||
|
||||
if (!nm_setting_connection_get_autoconnect (s_con))
|
||||
return;
|
||||
ifname = nm_setting_connection_get_interface_name (s_con);
|
||||
if (!ifname)
|
||||
return;
|
||||
devtimeout = devtimeout_from_file (nm_ifcfg_connection_get_path (self));
|
||||
if (!devtimeout)
|
||||
return;
|
||||
|
||||
if (nm_platform_link_get_ifindex (ifname) != 0)
|
||||
return;
|
||||
|
||||
/* ONBOOT=yes, DEVICE and DEVTIMEOUT are set, but device is not present */
|
||||
nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), FALSE);
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Waiting %u seconds for %s to appear for connection '%s'",
|
||||
devtimeout, ifname, nm_connection_get_id (NM_CONNECTION (self)));
|
||||
|
||||
priv->devtimeout_link_changed_handler =
|
||||
g_signal_connect (nm_platform_get (), NM_PLATFORM_SIGNAL_LINK_CHANGED,
|
||||
G_CALLBACK (link_changed), self);
|
||||
priv->devtimeout_timeout_id = g_timeout_add_seconds (devtimeout, devtimeout_expired, self);
|
||||
}
|
||||
|
||||
static void
|
||||
files_changed_cb (NMInotifyHelper *ih,
|
||||
struct inotify_event *evt,
|
||||
|
|
@ -141,8 +237,10 @@ nm_ifcfg_connection_new (NMConnection *source,
|
|||
update_unsaved,
|
||||
error)) {
|
||||
/* Set the path and start monitoring */
|
||||
if (full_path)
|
||||
if (full_path) {
|
||||
nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (object), full_path);
|
||||
nm_ifcfg_connection_check_devtimeout (NM_IFCFG_CONNECTION (object));
|
||||
}
|
||||
} else
|
||||
g_clear_object (&object);
|
||||
|
||||
|
|
@ -368,8 +466,20 @@ get_property (GObject *object, guint prop_id,
|
|||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
path_watch_stop (NM_IFCFG_CONNECTION (object));
|
||||
|
||||
if (priv->devtimeout_link_changed_handler) {
|
||||
g_signal_handler_disconnect (nm_platform_get (),
|
||||
priv->devtimeout_link_changed_handler);
|
||||
priv->devtimeout_link_changed_handler = 0;
|
||||
}
|
||||
if (priv->devtimeout_timeout_id) {
|
||||
g_source_remove (priv->devtimeout_timeout_id);
|
||||
priv->devtimeout_timeout_id = 0;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4852,3 +4852,25 @@ connection_from_file_test (const char *filename,
|
|||
NULL);
|
||||
}
|
||||
|
||||
guint
|
||||
devtimeout_from_file (const char *filename)
|
||||
{
|
||||
shvarFile *ifcfg;
|
||||
char *devtimeout_str;
|
||||
guint devtimeout;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
|
||||
ifcfg = svOpenFile (filename, NULL);
|
||||
if (!ifcfg)
|
||||
return 0;
|
||||
|
||||
devtimeout_str = svGetValue (ifcfg, "DEVTIMEOUT", FALSE);
|
||||
if (devtimeout_str) {
|
||||
devtimeout = nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0);
|
||||
g_free (devtimeout_str);
|
||||
} else
|
||||
devtimeout = 0;
|
||||
|
||||
return devtimeout;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ NMConnection *connection_from_file (const char *filename,
|
|||
|
||||
char *uuid_from_file (const char *filename);
|
||||
|
||||
guint devtimeout_from_file (const char *filename);
|
||||
|
||||
/* for test-ifcfg-rh */
|
||||
NMConnection *connection_from_file_test (const char *filename,
|
||||
const char *network_file,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue