mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-04 23:50:16 +01:00
core: merge branch 'th/bgo731570_master_slave'
https://bugzilla.gnome.org/show_bug.cgi?id=731570 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
commit
d71ec13123
5 changed files with 176 additions and 89 deletions
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#define NMD_SCRIPT_DIR NMCONFDIR "/dispatcher.d"
|
||||
#define NMD_PRE_UP_DIR NMD_SCRIPT_DIR "/pre-up.d"
|
||||
#define NMD_PRE_DOWN_DIR NMD_SCRIPT_DIR "/pre-down.d"
|
||||
#define NMD_SCRIPT_DIR_DEFAULT NMCONFDIR "/dispatcher.d"
|
||||
#define NMD_SCRIPT_DIR_PRE_UP NMD_SCRIPT_DIR_DEFAULT "/pre-up.d"
|
||||
#define NMD_SCRIPT_DIR_PRE_DOWN NMD_SCRIPT_DIR_DEFAULT "/pre-down.d"
|
||||
|
||||
/* dbus-glib types for dispatcher call return value */
|
||||
#define DISPATCHER_TYPE_RESULT (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID))
|
||||
|
|
|
|||
|
|
@ -426,12 +426,12 @@ find_scripts (const char *str_action)
|
|||
|
||||
if ( strcmp (str_action, NMD_ACTION_PRE_UP) == 0
|
||||
|| strcmp (str_action, NMD_ACTION_VPN_PRE_UP) == 0)
|
||||
dirname = NMD_PRE_UP_DIR;
|
||||
dirname = NMD_SCRIPT_DIR_PRE_UP;
|
||||
else if ( strcmp (str_action, NMD_ACTION_PRE_DOWN) == 0
|
||||
|| strcmp (str_action, NMD_ACTION_VPN_PRE_DOWN) == 0)
|
||||
dirname = NMD_PRE_DOWN_DIR;
|
||||
dirname = NMD_SCRIPT_DIR_PRE_DOWN;
|
||||
else
|
||||
dirname = NMD_SCRIPT_DIR;
|
||||
dirname = NMD_SCRIPT_DIR_DEFAULT;
|
||||
|
||||
if (!(dir = g_dir_open (dirname, 0, &error))) {
|
||||
g_message ("Failed to open dispatcher directory '%s': (%d) %s",
|
||||
|
|
|
|||
|
|
@ -216,7 +216,11 @@ typedef struct {
|
|||
guint act_source6_id;
|
||||
gpointer act_source6_func;
|
||||
guint recheck_assume_id;
|
||||
guint dispatcher_id;
|
||||
struct {
|
||||
guint call_id;
|
||||
NMDeviceState post_state;
|
||||
NMDeviceStateReason post_state_reason;
|
||||
} dispatcher;
|
||||
|
||||
/* Link stuff */
|
||||
guint link_connected_id;
|
||||
|
|
@ -831,8 +835,12 @@ nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean configure)
|
|||
reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
else if (priv->state == NM_DEVICE_STATE_FAILED)
|
||||
reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED;
|
||||
else
|
||||
else if (priv->state_reason != NM_DEVICE_STATE_REASON_NONE)
|
||||
reason = priv->state_reason;
|
||||
else {
|
||||
g_warn_if_reached ();
|
||||
reason = NM_DEVICE_STATE_REASON_UNKNOWN;
|
||||
}
|
||||
nm_device_slave_notify_release (info->slave, reason);
|
||||
|
||||
free_slave_info (info);
|
||||
|
|
@ -5264,32 +5272,55 @@ nm_device_get_ip6_config (NMDevice *self)
|
|||
/****************************************************************/
|
||||
|
||||
static void
|
||||
ip_check_pre_up_done (guint call_id, gpointer user_data)
|
||||
dispatcher_cleanup (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->dispatcher.call_id) {
|
||||
nm_dispatcher_call_cancel (priv->dispatcher.call_id);
|
||||
priv->dispatcher.call_id = 0;
|
||||
priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
|
||||
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispatcher_complete_proceed_state (guint call_id, gpointer user_data)
|
||||
{
|
||||
NMDevice *self = NM_DEVICE (user_data);
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (call_id == priv->dispatcher_id);
|
||||
g_return_if_fail (call_id == priv->dispatcher.call_id);
|
||||
|
||||
priv->dispatcher_id = 0;
|
||||
nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE);
|
||||
priv->dispatcher.call_id = 0;
|
||||
nm_device_queue_state (self, priv->dispatcher.post_state,
|
||||
priv->dispatcher.post_state_reason);
|
||||
priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
|
||||
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
static void
|
||||
ip_check_pre_up (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
g_warn_if_fail (priv->dispatcher_id == 0);
|
||||
if (priv->dispatcher.call_id != 0) {
|
||||
g_warn_if_reached ();
|
||||
dispatcher_cleanup (self);
|
||||
}
|
||||
|
||||
priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES;
|
||||
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP,
|
||||
nm_device_get_connection (self),
|
||||
self,
|
||||
ip_check_pre_up_done,
|
||||
dispatcher_complete_proceed_state,
|
||||
self,
|
||||
&priv->dispatcher_id)) {
|
||||
&priv->dispatcher.call_id)) {
|
||||
/* Just proceed on errors */
|
||||
ip_check_pre_up_done (0, self);
|
||||
dispatcher_complete_proceed_state (0, self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6521,29 +6552,6 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason)
|
|||
|
||||
/***********************************************************/
|
||||
|
||||
static void
|
||||
dispatcher_pre_down_done (guint call_id, gpointer user_data)
|
||||
{
|
||||
NMDevice *self = NM_DEVICE (user_data);
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (call_id == priv->dispatcher_id);
|
||||
|
||||
priv->dispatcher_id = 0;
|
||||
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatcher_cleanup (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->dispatcher_id) {
|
||||
nm_dispatcher_call_cancel (priv->dispatcher_id);
|
||||
priv->dispatcher_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip_config_valid (NMDeviceState state)
|
||||
{
|
||||
|
|
@ -6709,14 +6717,16 @@ _set_state_full (NMDevice *device,
|
|||
nm_act_request_get_connection (req),
|
||||
device);
|
||||
} else {
|
||||
priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
|
||||
priv->dispatcher.post_state_reason = reason;
|
||||
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
|
||||
nm_act_request_get_connection (req),
|
||||
device,
|
||||
dispatcher_pre_down_done,
|
||||
dispatcher_complete_proceed_state,
|
||||
device,
|
||||
&priv->dispatcher_id)) {
|
||||
&priv->dispatcher.call_id)) {
|
||||
/* Just proceed on errors */
|
||||
dispatcher_pre_down_done (0, device);
|
||||
dispatcher_complete_proceed_state (0, device);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "nm-dispatcher.h"
|
||||
#include "nm-dispatcher-api.h"
|
||||
|
|
@ -32,11 +33,46 @@
|
|||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-glib-compat.h"
|
||||
|
||||
#define CALL_TIMEOUT (1000 * 60 * 10) /* 10 mintues for all scripts */
|
||||
#define CALL_TIMEOUT (1000 * 60 * 10) /* 10 minutes for all scripts */
|
||||
|
||||
static gboolean do_dispatch = TRUE;
|
||||
static GHashTable *requests = NULL;
|
||||
|
||||
typedef struct {
|
||||
GFileMonitor *monitor;
|
||||
const char *const description;
|
||||
const char *const dir;
|
||||
const guint16 dir_len;
|
||||
char has_scripts;
|
||||
} Monitor;
|
||||
|
||||
enum {
|
||||
MONITOR_INDEX_DEFAULT,
|
||||
MONITOR_INDEX_PRE_UP,
|
||||
MONITOR_INDEX_PRE_DOWN,
|
||||
};
|
||||
|
||||
static Monitor monitors[3] = {
|
||||
#define MONITORS_INIT_SET(INDEX, USE, SCRIPT_DIR) [INDEX] = { .dir_len = STRLEN (SCRIPT_DIR), .dir = SCRIPT_DIR, .description = ("" USE), .has_scripts = TRUE }
|
||||
MONITORS_INIT_SET (MONITOR_INDEX_DEFAULT, "default", NMD_SCRIPT_DIR_DEFAULT),
|
||||
MONITORS_INIT_SET (MONITOR_INDEX_PRE_UP, "pre-up", NMD_SCRIPT_DIR_PRE_UP),
|
||||
MONITORS_INIT_SET (MONITOR_INDEX_PRE_DOWN, "pre-down", NMD_SCRIPT_DIR_PRE_DOWN),
|
||||
};
|
||||
|
||||
static const Monitor*
|
||||
_get_monitor_by_action (DispatcherAction action)
|
||||
{
|
||||
switch (action) {
|
||||
case DISPATCHER_ACTION_PRE_UP:
|
||||
case DISPATCHER_ACTION_VPN_PRE_UP:
|
||||
return &monitors[MONITOR_INDEX_PRE_UP];
|
||||
case DISPATCHER_ACTION_PRE_DOWN:
|
||||
case DISPATCHER_ACTION_VPN_PRE_DOWN:
|
||||
return &monitors[MONITOR_INDEX_PRE_DOWN];
|
||||
default:
|
||||
return &monitors[MONITOR_INDEX_DEFAULT];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_object_to_props (GObject *object, GHashTable *hash)
|
||||
{
|
||||
|
|
@ -136,6 +172,7 @@ fill_vpn_props (NMIP4Config *ip4_config,
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
DispatcherAction action;
|
||||
guint request_id;
|
||||
DispatcherFunc callback;
|
||||
gpointer user_data;
|
||||
|
|
@ -197,17 +234,25 @@ validate_element (guint request_id, GValue *val, GType expected_type, guint idx,
|
|||
}
|
||||
|
||||
static void
|
||||
dispatcher_results_process (guint request_id, GPtrArray *results)
|
||||
dispatcher_results_process (guint request_id, DispatcherAction action, GPtrArray *results)
|
||||
{
|
||||
guint i;
|
||||
const Monitor *monitor = _get_monitor_by_action (action);
|
||||
|
||||
g_return_if_fail (results != NULL);
|
||||
|
||||
if (results->len == 0) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) succeeded but no scripts invoked",
|
||||
request_id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < results->len; i++) {
|
||||
GValueArray *item = g_ptr_array_index (results, i);
|
||||
GValue *tmp;
|
||||
const char *script, *err;
|
||||
DispatchResult result;
|
||||
const char *script_validation_msg = "";
|
||||
|
||||
if (item->n_values != 3) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) unexpected number of items in "
|
||||
|
|
@ -221,8 +266,18 @@ dispatcher_results_process (guint request_id, GPtrArray *results)
|
|||
if (!validate_element (request_id, tmp, G_TYPE_STRING, i, 0))
|
||||
continue;
|
||||
script = g_value_get_string (tmp);
|
||||
if (!script || strncmp (script, NMD_SCRIPT_DIR "/", STRLEN (NMD_SCRIPT_DIR "/")))
|
||||
continue;
|
||||
if (!script) {
|
||||
script_validation_msg = " (path is NULL)";
|
||||
script = "(unknown)";
|
||||
} else if (!strncmp (script, monitor->dir, monitor->dir_len) /* check: prefixed by script directory */
|
||||
&& script[monitor->dir_len] == '/' && script[monitor->dir_len+1] /* check: with additional "/?" */
|
||||
&& !strchr (&script[monitor->dir_len+1], '/')) { /* check: and no further '/' */
|
||||
/* we expect the script to lie inside monitor->dir. If it does,
|
||||
* strip the directory name. Otherwise show the full path and a warning. */
|
||||
script += monitor->dir_len + 1;
|
||||
} else
|
||||
script_validation_msg = " (unexpected path)";
|
||||
|
||||
|
||||
/* Result */
|
||||
tmp = g_value_array_get_nth (item, 1);
|
||||
|
|
@ -238,15 +293,15 @@ dispatcher_results_process (guint request_id, GPtrArray *results)
|
|||
|
||||
|
||||
if (result == DISPATCH_RESULT_SUCCESS) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) %s succeeded",
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) %s succeeded%s",
|
||||
request_id,
|
||||
script + STRLEN (NMD_SCRIPT_DIR "/"));
|
||||
script, script_validation_msg);
|
||||
} else {
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) %s failed (%s): %s",
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) %s failed (%s): %s%s",
|
||||
request_id,
|
||||
script + STRLEN (NMD_SCRIPT_DIR "/"),
|
||||
script,
|
||||
dispatch_result_to_string (result),
|
||||
err ? err : "");
|
||||
err ? err : "", script_validation_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -269,7 +324,7 @@ dispatcher_done_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
|||
if (dbus_g_proxy_end_call (proxy, call, &error,
|
||||
DISPATCHER_TYPE_RESULT_ARRAY, &results,
|
||||
G_TYPE_INVALID)) {
|
||||
dispatcher_results_process (info->request_id, results);
|
||||
dispatcher_results_process (info->request_id, info->action, results);
|
||||
free_results (results);
|
||||
} else {
|
||||
g_assert (error);
|
||||
|
|
@ -356,30 +411,38 @@ _dispatcher_call (DispatcherAction action,
|
|||
|
||||
/* All actions except 'hostname' require a device */
|
||||
if (action == DISPATCHER_ACTION_HOSTNAME) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) dispatching action '%s'",
|
||||
reqid, action_to_string (action));
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) dispatching action '%s'%s",
|
||||
reqid, action_to_string (action),
|
||||
blocking
|
||||
? " (blocking)"
|
||||
: (callback ? " (with callback)" : ""));
|
||||
} else {
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
||||
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) (%s) dispatching action '%s'",
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) (%s) dispatching action '%s'%s",
|
||||
reqid,
|
||||
vpn_iface ? vpn_iface : nm_device_get_iface (device),
|
||||
action_to_string (action));
|
||||
action_to_string (action),
|
||||
blocking
|
||||
? " (blocking)"
|
||||
: (callback ? " (with callback)" : ""));
|
||||
}
|
||||
|
||||
/* VPN actions require at least an IPv4 config (for now) */
|
||||
if (action == DISPATCHER_ACTION_VPN_UP)
|
||||
g_return_val_if_fail (vpn_ip4_config != NULL, FALSE);
|
||||
|
||||
if (do_dispatch == FALSE) {
|
||||
if (!_get_monitor_by_action(action)->has_scripts) {
|
||||
if (blocking == FALSE && (out_call_id || callback)) {
|
||||
info = g_malloc0 (sizeof (*info));
|
||||
info->action = action;
|
||||
info->request_id = reqid;
|
||||
info->callback = callback;
|
||||
info->user_data = user_data;
|
||||
info->idle_id = g_idle_add (dispatcher_idle_cb, info);
|
||||
}
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) ignoring request; no scripts in " NMD_SCRIPT_DIR, reqid);
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) simulate request; no scripts in %s", reqid, _get_monitor_by_action(action)->dir);
|
||||
} else
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) ignoring request; no scripts in %s", reqid, _get_monitor_by_action(action)->dir);
|
||||
success = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -449,7 +512,7 @@ _dispatcher_call (DispatcherAction action,
|
|||
DISPATCHER_TYPE_RESULT_ARRAY, &results,
|
||||
G_TYPE_INVALID);
|
||||
if (success) {
|
||||
dispatcher_results_process (reqid, results);
|
||||
dispatcher_results_process (reqid, action, results);
|
||||
free_results (results);
|
||||
} else {
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) failed: (%d) %s", reqid, error->code, error->message);
|
||||
|
|
@ -457,6 +520,7 @@ _dispatcher_call (DispatcherAction action,
|
|||
}
|
||||
} else {
|
||||
info = g_malloc0 (sizeof (*info));
|
||||
info->action = action;
|
||||
info->request_id = reqid;
|
||||
info->callback = callback;
|
||||
info->user_data = user_data;
|
||||
|
|
@ -620,24 +684,15 @@ nm_dispatcher_call_cancel (guint call_id)
|
|||
* DispatcherInfo's callback to NULL.
|
||||
*/
|
||||
info = g_hash_table_lookup (requests, GUINT_TO_POINTER (call_id));
|
||||
if (info)
|
||||
g_return_if_fail (info);
|
||||
|
||||
if (info && info->callback) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) cancelling dispatcher callback action",
|
||||
call_id);
|
||||
info->callback = NULL;
|
||||
else
|
||||
g_return_if_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *dir;
|
||||
GFileMonitor *monitor;
|
||||
gboolean has_scripts;
|
||||
} Monitor;
|
||||
|
||||
static Monitor monitors[3] = {
|
||||
{ NMD_SCRIPT_DIR, NULL, TRUE },
|
||||
{ NMD_PRE_UP_DIR, NULL, TRUE },
|
||||
{ NMD_PRE_DOWN_DIR, NULL, TRUE }
|
||||
};
|
||||
|
||||
static void
|
||||
dispatcher_dir_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
|
|
@ -645,22 +700,44 @@ dispatcher_dir_changed (GFileMonitor *monitor,
|
|||
GFileMonitorEvent event_type,
|
||||
Monitor *item)
|
||||
{
|
||||
const char *name;
|
||||
char *full_name;
|
||||
GDir *dir;
|
||||
guint i;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Default to dispatching on any errors */
|
||||
item->has_scripts = TRUE;
|
||||
|
||||
dir = g_dir_open (item->dir, 0, NULL);
|
||||
dir = g_dir_open (item->dir, 0, &error);
|
||||
if (dir) {
|
||||
item->has_scripts = !!g_dir_read_name (dir);
|
||||
int errsv = 0;
|
||||
|
||||
item->has_scripts = FALSE;
|
||||
errno = 0;
|
||||
while (!item->has_scripts
|
||||
&& (name = g_dir_read_name (dir))) {
|
||||
full_name = g_build_filename (item->dir, name, NULL);
|
||||
item->has_scripts = g_file_test (full_name, G_FILE_TEST_IS_EXECUTABLE);
|
||||
g_free (full_name);
|
||||
}
|
||||
errsv = errno;
|
||||
g_dir_close (dir);
|
||||
if (item->has_scripts)
|
||||
nm_log_dbg (LOGD_DISPATCH, "dispatcher: %s script directory '%s' has scripts", item->description, item->dir);
|
||||
else if (errsv == 0)
|
||||
nm_log_dbg (LOGD_DISPATCH, "dispatcher: %s script directory '%s' has no scripts", item->description, item->dir);
|
||||
else {
|
||||
nm_log_dbg (LOGD_DISPATCH, "dispatcher: %s script directory '%s' error reading (%s)", item->description, item->dir, strerror (errsv));
|
||||
item->has_scripts = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "dispatcher: %s script directory '%s' does not exist", item->description, item->dir);
|
||||
item->has_scripts = FALSE;
|
||||
} else {
|
||||
nm_log_dbg (LOGD_DISPATCH, "dispatcher: %s script directory '%s' error (%s)", item->description, item->dir, error->message);
|
||||
item->has_scripts = TRUE;
|
||||
}
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
/* Recheck all dirs for scripts and update global variable */
|
||||
do_dispatch = FALSE;
|
||||
for (i = 0; i < G_N_ELEMENTS (monitors); i++)
|
||||
do_dispatch |= monitors[i].has_scripts;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -2390,9 +2390,8 @@ ensure_master_active_connection (NMManager *self,
|
|||
/* If we're passed a connection and a device, we require that connection
|
||||
* be already activated on the device, eg returned from find_master().
|
||||
*/
|
||||
if (master_connection)
|
||||
g_assert (device_connection == master_connection);
|
||||
else if (!is_compatible_with_slave (device_connection, connection)) {
|
||||
g_assert (!master_connection || master_connection == device_connection);
|
||||
if (device_connection && !is_compatible_with_slave (device_connection, connection)) {
|
||||
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
||||
"The active connection on %s is not a valid master for '%s'",
|
||||
nm_device_get_iface (master_device),
|
||||
|
|
@ -2404,6 +2403,7 @@ ensure_master_active_connection (NMManager *self,
|
|||
if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
|
||||
|| nm_device_is_activating (master_device)) {
|
||||
/* Device already using master_connection */
|
||||
g_assert (device_connection);
|
||||
return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue