ovs: merge branch 'bg/ovs-cleanup-pt2'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/734
This commit is contained in:
@@ -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);
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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__ */
|
||||||
|
@@ -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
|
||||||
|
@@ -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__ */
|
||||||
|
@@ -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,
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user