ovs: merge branch 'bg/ovs-cleanup-pt2'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/734
This commit is contained in:
Beniamino Galvani
2021-01-27 16:12:47 +01:00
8 changed files with 281 additions and 48 deletions

View File

@@ -22,6 +22,7 @@
/*****************************************************************************/ /*****************************************************************************/
typedef struct { typedef struct {
NMOvsdb *ovsdb;
bool waiting_for_interface : 1; bool waiting_for_interface : 1;
} NMDeviceOvsInterfacePrivate; } NMDeviceOvsInterfacePrivate;
@@ -70,7 +71,10 @@ get_generic_capabilities(NMDevice *device)
static gboolean static gboolean
is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{ {
return TRUE; NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device);
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
return nm_ovsdb_is_ready(priv->ovsdb);
} }
static gboolean static gboolean
@@ -152,6 +156,9 @@ set_platform_mtu_cb(GError *error, gpointer user_data)
static gboolean static gboolean
set_platform_mtu(NMDevice *device, guint32 mtu) set_platform_mtu(NMDevice *device, guint32 mtu)
{ {
NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device);
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
/* /*
* If the MTU is not set in ovsdb, Open vSwitch will change * If the MTU is not set in ovsdb, Open vSwitch will change
* the MTU of an internal interface to match the minimum of * the MTU of an internal interface to match the minimum of
@@ -162,7 +169,7 @@ set_platform_mtu(NMDevice *device, guint32 mtu)
* it can be stopped during shutdown. * it can be stopped during shutdown.
*/ */
if (_is_internal_interface(device)) { if (_is_internal_interface(device)) {
nm_ovsdb_set_interface_mtu(nm_ovsdb_get(), nm_ovsdb_set_interface_mtu(priv->ovsdb,
nm_device_get_ip_iface(device), nm_device_get_ip_iface(device),
mtu, mtu,
set_platform_mtu_cb, set_platform_mtu_cb,
@@ -360,9 +367,42 @@ can_update_from_platform_link(NMDevice *device, const NMPlatformLink *plink)
/*****************************************************************************/ /*****************************************************************************/
static void
ovsdb_ready(NMOvsdb *ovsdb, NMDeviceOvsInterface *self)
{
NMDevice *device = NM_DEVICE(self);
nm_device_queue_recheck_available(device,
NM_DEVICE_STATE_REASON_NONE,
NM_DEVICE_STATE_REASON_NONE);
nm_device_recheck_available_connections(device);
nm_device_emit_recheck_auto_activate(device);
}
static void static void
nm_device_ovs_interface_init(NMDeviceOvsInterface *self) nm_device_ovs_interface_init(NMDeviceOvsInterface *self)
{} {
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
priv->ovsdb = g_object_ref(nm_ovsdb_get());
if (!nm_ovsdb_is_ready(priv->ovsdb))
g_signal_connect(priv->ovsdb, NM_OVSDB_READY, G_CALLBACK(ovsdb_ready), self);
}
static void
dispose(GObject *object)
{
NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(object);
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
if (priv->ovsdb) {
g_signal_handlers_disconnect_by_func(priv->ovsdb, G_CALLBACK(ovsdb_ready), self);
g_clear_object(&priv->ovsdb);
}
G_OBJECT_CLASS(nm_device_ovs_interface_parent_class)->dispose(object);
}
static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = { static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = {
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
@@ -374,9 +414,12 @@ static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = {
static void static void
nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *klass) nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *klass)
{ {
GObjectClass * object_class = G_OBJECT_CLASS(klass);
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); NMDeviceClass * device_class = NM_DEVICE_CLASS(klass);
object_class->dispose = dispose;
dbus_object_class->interface_infos = dbus_object_class->interface_infos =
NM_DBUS_INTERFACE_INFOS(&interface_info_device_ovs_interface); NM_DBUS_INTERFACE_INFOS(&interface_info_device_ovs_interface);

View File

@@ -106,11 +106,24 @@ new_device_from_type(const char *name, NMDeviceType device_type)
} }
static void static void
ovsdb_device_added(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDeviceFactory *self) ovsdb_device_added(NMOvsdb * ovsdb,
const char * name,
guint device_type_i,
const char * subtype,
NMDeviceFactory *self)
{ {
const NMDeviceType device_type = device_type_i; const NMDeviceType device_type = device_type_i;
NMDevice * device; NMDevice * device;
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE
&& !NM_IN_STRSET(subtype, "internal", "patch")) {
/* system interfaces refer to kernel devices and
* don't need to be created by this factory. Ignore
* anything that is not an internal or patch
* interface. */
return;
}
device = new_device_from_type(name, device_type); device = new_device_from_type(name, device_type);
if (!device) if (!device)
return; return;
@@ -120,23 +133,59 @@ ovsdb_device_added(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDevi
} }
static void static void
ovsdb_device_removed(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDeviceFactory *self) ovsdb_device_removed(NMOvsdb * ovsdb,
const char * name,
guint device_type_i,
const char * subtype,
NMDeviceFactory *self)
{ {
const NMDeviceType device_type = device_type_i; const NMDeviceType device_type = device_type_i;
NMDevice * device; NMDevice * device = NULL;
NMDeviceState device_state; NMDeviceState device_state;
gboolean is_system_interface = FALSE;
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE
&& !NM_IN_STRSET(subtype, "internal", "patch", "system"))
return;
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && nm_streq0(subtype, "system")) {
NMDevice * d;
const CList * list;
NMSettingOvsInterface *s_ovs_int;
/* The device associated to an OVS system interface can be of
* any kind. Find an interface with the same name and which has
* the OVS-interface setting. */
is_system_interface = TRUE;
nm_manager_for_each_device (NM_MANAGER_GET, d, list) {
if (!nm_streq0(nm_device_get_iface(d), name))
continue;
s_ovs_int = nm_device_get_applied_setting(d, NM_TYPE_SETTING_OVS_INTERFACE);
if (!s_ovs_int)
continue;
if (!nm_streq0(nm_setting_ovs_interface_get_interface_type(s_ovs_int), "system"))
continue;
device = d;
}
} else {
device = nm_manager_get_device(NM_MANAGER_GET, name, device_type); device = nm_manager_get_device(NM_MANAGER_GET, name, device_type);
}
if (!device) if (!device)
return; return;
device_state = nm_device_get_state(device); device_state = nm_device_get_state(device);
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && device_state > NM_DEVICE_STATE_DISCONNECTED
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && nm_device_get_act_request(device)
&& device_state < NM_DEVICE_STATE_DEACTIVATING) { && device_state < NM_DEVICE_STATE_DEACTIVATING) {
nm_device_state_changed(device, nm_device_state_changed(device,
NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); NM_DEVICE_STATE_REASON_REMOVED);
} else if (device_state == NM_DEVICE_STATE_UNMANAGED) { return;
}
/* OVS system interfaces still exist even without the ovsdb entry */
if (!is_system_interface && device_state == NM_DEVICE_STATE_UNMANAGED) {
nm_device_unrealize(device, TRUE, NULL); nm_device_unrealize(device, TRUE, NULL);
} }
} }

View File

@@ -15,6 +15,7 @@
#include "nm-core-utils.h" #include "nm-core-utils.h"
#include "nm-core-internal.h" #include "nm-core-internal.h"
#include "devices/nm-device.h" #include "devices/nm-device.h"
#include "nm-manager.h"
#include "nm-setting-ovs-external-ids.h" #include "nm-setting-ovs-external-ids.h"
/*****************************************************************************/ /*****************************************************************************/
@@ -106,7 +107,13 @@ typedef struct {
/*****************************************************************************/ /*****************************************************************************/
enum { DEVICE_ADDED, DEVICE_REMOVED, INTERFACE_FAILED, LAST_SIGNAL }; enum {
DEVICE_ADDED,
DEVICE_REMOVED,
INTERFACE_FAILED,
READY,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = {0}; static guint signals[LAST_SIGNAL] = {0};
@@ -127,6 +134,8 @@ typedef struct {
GHashTable *bridges; /* bridge uuid => OpenvswitchBridge */ GHashTable *bridges; /* bridge uuid => OpenvswitchBridge */
char * db_uuid; char * db_uuid;
guint num_failures; guint num_failures;
guint num_pending_deletions;
bool ready : 1;
} NMOvsdbPrivate; } NMOvsdbPrivate;
struct _NMOvsdb { struct _NMOvsdb {
@@ -316,26 +325,24 @@ _free_interface(OpenvswitchInterface *ovs_interface)
nm_g_slice_free(ovs_interface); nm_g_slice_free(ovs_interface);
} }
static gboolean
_openvswitch_interface_should_emit_signal(const OpenvswitchInterface *ovs_interface)
{
/* Currently, the factory only creates NMDevices for
* internal interfaces. We ignore the rest. */
return nm_streq0(ovs_interface->type, "internal");
}
/*****************************************************************************/ /*****************************************************************************/
static void static void
_signal_emit_device_added(NMOvsdb *self, const char *name, NMDeviceType device_type) _signal_emit_device_added(NMOvsdb * self,
const char * name,
NMDeviceType device_type,
const char * device_subtype)
{ {
g_signal_emit(self, signals[DEVICE_ADDED], 0, name, (guint) device_type); g_signal_emit(self, signals[DEVICE_ADDED], 0, name, (guint) device_type, device_subtype);
} }
static void static void
_signal_emit_device_removed(NMOvsdb *self, const char *name, NMDeviceType device_type) _signal_emit_device_removed(NMOvsdb * self,
const char * name,
NMDeviceType device_type,
const char * device_subtype)
{ {
g_signal_emit(self, signals[DEVICE_REMOVED], 0, name, (guint) device_type); g_signal_emit(self, signals[DEVICE_REMOVED], 0, name, (guint) device_type, device_subtype);
} }
static void static void
@@ -1630,11 +1637,10 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
", ", ", ",
ovs_interface->connection_uuid, ovs_interface->connection_uuid,
"")); ""));
if (_openvswitch_interface_should_emit_signal(ovs_interface)) {
_signal_emit_device_removed(self, _signal_emit_device_removed(self,
ovs_interface->name, ovs_interface->name,
NM_DEVICE_TYPE_OVS_INTERFACE); NM_DEVICE_TYPE_OVS_INTERFACE,
} ovs_interface->type);
_free_interface(ovs_interface); _free_interface(ovs_interface);
continue; continue;
} }
@@ -1645,11 +1651,10 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
&& (!nm_streq0(ovs_interface->name, name) || !nm_streq0(ovs_interface->type, type))) { && (!nm_streq0(ovs_interface->name, name) || !nm_streq0(ovs_interface->type, type))) {
if (!g_hash_table_steal(priv->interfaces, ovs_interface)) if (!g_hash_table_steal(priv->interfaces, ovs_interface))
nm_assert_not_reached(); nm_assert_not_reached();
if (_openvswitch_interface_should_emit_signal(ovs_interface)) {
_signal_emit_device_removed(self, _signal_emit_device_removed(self,
ovs_interface->name, ovs_interface->name,
NM_DEVICE_TYPE_OVS_INTERFACE); NM_DEVICE_TYPE_OVS_INTERFACE,
} ovs_interface->type);
nm_clear_pointer(&ovs_interface, _free_interface); nm_clear_pointer(&ovs_interface, _free_interface);
} }
@@ -1700,8 +1705,10 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
ovs_interface->connection_uuid, ovs_interface->connection_uuid,
""), ""),
(strtmp = _external_ids_to_string(ovs_interface->external_ids))); (strtmp = _external_ids_to_string(ovs_interface->external_ids)));
if (_openvswitch_interface_should_emit_signal(ovs_interface)) _signal_emit_device_added(self,
_signal_emit_device_added(self, ovs_interface->name, NM_DEVICE_TYPE_OVS_INTERFACE); ovs_interface->name,
NM_DEVICE_TYPE_OVS_INTERFACE,
ovs_interface->type);
} }
/* The error is a string. No error is indicated by an empty set, /* The error is a string. No error is indicated by an empty set,
@@ -1747,7 +1754,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
", ", ", ",
ovs_port->connection_uuid, ovs_port->connection_uuid,
"")); ""));
_signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT); _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
_free_port(ovs_port); _free_port(ovs_port);
continue; continue;
} }
@@ -1757,7 +1764,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
if (ovs_port && !nm_streq0(ovs_port->name, name)) { if (ovs_port && !nm_streq0(ovs_port->name, name)) {
if (!g_hash_table_steal(priv->ports, ovs_port)) if (!g_hash_table_steal(priv->ports, ovs_port))
nm_assert_not_reached(); nm_assert_not_reached();
_signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT); _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
nm_clear_pointer(&ovs_port, _free_port); nm_clear_pointer(&ovs_port, _free_port);
} }
@@ -1811,7 +1818,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
ovs_port->connection_uuid, ovs_port->connection_uuid,
""), ""),
(strtmp = _external_ids_to_string(ovs_port->external_ids))); (strtmp = _external_ids_to_string(ovs_port->external_ids)));
_signal_emit_device_added(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT); _signal_emit_device_added(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
} }
} }
@@ -1852,7 +1859,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
", ", ", ",
ovs_bridge->connection_uuid, ovs_bridge->connection_uuid,
"")); ""));
_signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE); _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
_free_bridge(ovs_bridge); _free_bridge(ovs_bridge);
continue; continue;
} }
@@ -1862,7 +1869,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
if (ovs_bridge && !nm_streq0(ovs_bridge->name, name)) { if (ovs_bridge && !nm_streq0(ovs_bridge->name, name)) {
if (!g_hash_table_steal(priv->bridges, ovs_bridge)) if (!g_hash_table_steal(priv->bridges, ovs_bridge))
nm_assert_not_reached(); nm_assert_not_reached();
_signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE); _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
nm_clear_pointer(&ovs_bridge, _free_bridge); nm_clear_pointer(&ovs_bridge, _free_bridge);
} }
@@ -1916,7 +1923,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
ovs_bridge->connection_uuid, ovs_bridge->connection_uuid,
""), ""),
(strtmp = _external_ids_to_string(ovs_bridge->external_ids))); (strtmp = _external_ids_to_string(ovs_bridge->external_ids)));
_signal_emit_device_added(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE); _signal_emit_device_added(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
} }
} }
} }
@@ -2221,6 +2228,9 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing)
_LOGD("disconnecting from ovsdb, retry %d", retry); _LOGD("disconnecting from ovsdb, retry %d", retry);
/* FIXME(shutdown): NMOvsdb should process the pending calls before
* shutting down, and cancel the remaining calls after the timeout. */
if (retry) { if (retry) {
if (!c_list_is_empty(&priv->calls_lst_head)) { if (!c_list_is_empty(&priv->calls_lst_head)) {
call = c_list_first_entry(&priv->calls_lst_head, OvsdbMethodCall, calls_lst); call = c_list_first_entry(&priv->calls_lst_head, OvsdbMethodCall, calls_lst);
@@ -2249,6 +2259,76 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing)
ovsdb_try_connect(self); ovsdb_try_connect(self);
} }
static void
_check_ready(NMOvsdb *self)
{
NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self);
nm_assert(!priv->ready);
if (priv->num_pending_deletions == 0) {
priv->ready = TRUE;
g_signal_emit(self, signals[READY], 0);
nm_manager_unblock_failed_ovs_interfaces(nm_manager_get());
}
}
static void
_del_initial_iface_cb(GError *error, gpointer user_data)
{
NMOvsdb * self;
gs_free char * ifname = NULL;
NMOvsdbPrivate *priv;
nm_utils_user_data_unpack(user_data, &self, &ifname);
if (nm_utils_error_is_cancelled_or_disposing(error))
return;
priv = NM_OVSDB_GET_PRIVATE(self);
nm_assert(priv->num_pending_deletions > 0);
priv->num_pending_deletions--;
_LOGD("delete initial interface '%s': %s %s%s%s, pending %u",
ifname,
error ? "error" : "success",
error ? "(" : "",
error ? error->message : "",
error ? ")" : "",
priv->num_pending_deletions);
_check_ready(self);
}
static void
ovsdb_cleanup_initial_interfaces(NMOvsdb *self)
{
NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self);
const OpenvswitchInterface *interface;
NMUtilsUserData * data;
GHashTableIter iter;
if (priv->ready || priv->num_pending_deletions != 0)
return;
/* Delete OVS interfaces added by NM. Bridges and ports and
* not considered because they are deleted automatically
* when no interface is present. */
g_hash_table_iter_init(&iter, self->_priv.interfaces);
while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &interface)) {
if (interface->connection_uuid) {
priv->num_pending_deletions++;
_LOGD("deleting initial interface '%s' (pending: %u)",
interface->name,
priv->num_pending_deletions);
data = nm_utils_user_data_pack(self, g_strdup(interface->name));
nm_ovsdb_del_interface(self, interface->name, _del_initial_iface_cb, data);
}
}
_check_ready(self);
}
static void static void
_monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_data) _monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_data)
{ {
@@ -2263,6 +2343,8 @@ _monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_
/* Treat the first response the same as the subsequent "update" /* Treat the first response the same as the subsequent "update"
* messages we eventually get. */ * messages we eventually get. */
ovsdb_got_update(self, result); ovsdb_got_update(self, result);
ovsdb_cleanup_initial_interfaces(self);
} }
static void static void
@@ -2382,6 +2464,14 @@ ovsdb_call_new(NMOvsdbCallback callback, gpointer user_data)
return call; return call;
} }
gboolean
nm_ovsdb_is_ready(NMOvsdb *self)
{
NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self);
return priv->ready;
}
void void
nm_ovsdb_add_interface(NMOvsdb * self, nm_ovsdb_add_interface(NMOvsdb * self,
NMConnection * bridge, NMConnection * bridge,
@@ -2525,9 +2615,10 @@ nm_ovsdb_class_init(NMOvsdbClass *klass)
NULL, NULL,
NULL, NULL,
G_TYPE_NONE, G_TYPE_NONE,
2, 3,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_UINT); G_TYPE_UINT,
G_TYPE_STRING);
signals[DEVICE_REMOVED] = g_signal_new(NM_OVSDB_DEVICE_REMOVED, signals[DEVICE_REMOVED] = g_signal_new(NM_OVSDB_DEVICE_REMOVED,
G_OBJECT_CLASS_TYPE(object_class), G_OBJECT_CLASS_TYPE(object_class),
@@ -2537,9 +2628,10 @@ nm_ovsdb_class_init(NMOvsdbClass *klass)
NULL, NULL,
NULL, NULL,
G_TYPE_NONE, G_TYPE_NONE,
2, 3,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_UINT); G_TYPE_UINT,
G_TYPE_STRING);
signals[INTERFACE_FAILED] = g_signal_new(NM_OVSDB_INTERFACE_FAILED, signals[INTERFACE_FAILED] = g_signal_new(NM_OVSDB_INTERFACE_FAILED,
G_OBJECT_CLASS_TYPE(object_class), G_OBJECT_CLASS_TYPE(object_class),
@@ -2553,4 +2645,14 @@ nm_ovsdb_class_init(NMOvsdbClass *klass)
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING); G_TYPE_STRING);
signals[READY] = g_signal_new(NM_OVSDB_READY,
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
} }

View File

@@ -16,6 +16,7 @@
#define NM_OVSDB_DEVICE_ADDED "device-added" #define NM_OVSDB_DEVICE_ADDED "device-added"
#define NM_OVSDB_DEVICE_REMOVED "device-removed" #define NM_OVSDB_DEVICE_REMOVED "device-removed"
#define NM_OVSDB_INTERFACE_FAILED "interface-failed" #define NM_OVSDB_INTERFACE_FAILED "interface-failed"
#define NM_OVSDB_READY "ready"
typedef struct _NMOvsdb NMOvsdb; typedef struct _NMOvsdb NMOvsdb;
typedef struct _NMOvsdbClass NMOvsdbClass; typedef struct _NMOvsdbClass NMOvsdbClass;
@@ -55,4 +56,6 @@ void nm_ovsdb_set_external_ids(NMOvsdb * self,
struct _NMSettingOvsExternalIDs *s_exid_old, struct _NMSettingOvsExternalIDs *s_exid_old,
struct _NMSettingOvsExternalIDs *s_exid_new); struct _NMSettingOvsExternalIDs *s_exid_new);
gboolean nm_ovsdb_is_ready(NMOvsdb *self);
#endif /* __NETWORKMANAGER_OVSDB_H__ */ #endif /* __NETWORKMANAGER_OVSDB_H__ */

View File

@@ -4927,11 +4927,11 @@ _internal_activate_device(NMManager *self, NMActiveConnection *active, GError **
if (master_device) { if (master_device) {
g_prefix_error(error, g_prefix_error(error,
"Master device '%s' can't be activated: ", "Master device '%s' can't be activated: ",
nm_device_get_ip_iface(device)); nm_device_get_ip_iface(master_device));
} else { } else {
g_prefix_error(error, g_prefix_error(error,
"Master connection '%s' can't be activated: ", "Master connection '%s' can't be activated: ",
nm_settings_connection_get_id(sett_conn)); nm_settings_connection_get_id(master_connection));
} }
return FALSE; return FALSE;
} }
@@ -7582,6 +7582,14 @@ periodic_update_active_connection_timestamps(gpointer user_data)
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
void
nm_manager_unblock_failed_ovs_interfaces(NMManager *self)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
nm_policy_unblock_failed_ovs_interfaces(priv->policy);
}
/*****************************************************************************/ /*****************************************************************************/
void void

View File

@@ -209,4 +209,6 @@ void nm_manager_device_auth_request(NMManager * self,
NMManagerDeviceAuthRequestFunc callback, NMManagerDeviceAuthRequestFunc callback,
gpointer user_data); gpointer user_data);
void nm_manager_unblock_failed_ovs_interfaces(NMManager *self);
#endif /* __NETWORKMANAGER_MANAGER_H__ */ #endif /* __NETWORKMANAGER_MANAGER_H__ */

View File

@@ -1541,6 +1541,30 @@ hostname_changed(NMHostnameManager *hostname_manager, GParamSpec *pspec, gpointe
update_system_hostname(self, "hostname changed"); update_system_hostname(self, "hostname changed");
} }
void
nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self)
{
NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
NMSettingsConnection *const *connections = NULL;
guint i;
_LOGT(LOGD_DEVICE, "unblocking failed OVS interfaces");
connections = nm_settings_get_connections(priv->settings, NULL);
for (i = 0; connections[i]; i++) {
NMSettingsConnection *sett_conn = connections[i];
NMConnection * connection = nm_settings_connection_get_connection(sett_conn);
if (nm_connection_get_setting_ovs_interface(connection)) {
nm_settings_connection_autoconnect_retries_reset(sett_conn);
nm_settings_connection_autoconnect_blocked_reason_set(
sett_conn,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
FALSE);
}
}
}
static gboolean static gboolean
reset_autoconnect_all( reset_autoconnect_all(
NMPolicy *self, NMPolicy *self,

View File

@@ -32,6 +32,8 @@ NMActiveConnection *nm_policy_get_default_ip6_ac(NMPolicy *policy);
NMActiveConnection *nm_policy_get_activating_ip4_ac(NMPolicy *policy); NMActiveConnection *nm_policy_get_activating_ip4_ac(NMPolicy *policy);
NMActiveConnection *nm_policy_get_activating_ip6_ac(NMPolicy *policy); NMActiveConnection *nm_policy_get_activating_ip6_ac(NMPolicy *policy);
void nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self);
/** /**
* NMPolicyHostnameMode * NMPolicyHostnameMode
* @NM_POLICY_HOSTNAME_MODE_NONE: never update the transient hostname. * @NM_POLICY_HOSTNAME_MODE_NONE: never update the transient hostname.