core: create devices first and realize them later
Unrealized devices aren't backed by kernel resources and so won't know all of their attributes. That means three things: 1) they must update their attributes when they become realized 2) they must clear those attributes when unrealized 3) they must be looser in checking compatible connections until they are realized This requires that the setup() function be split into two parts, start & finish, because finish must be run after add_device() Also, we can simplify whether to pay attention to 'recheck-assume', which is now dependent on priv->is_nm_owned, because the only case where NM should *not* listen for the 'recheck-assume' signal is when the device is a software device created by NM itself. That logic was previously spread across the callers of add_device() but is now consolidated into nm-manager.c::device_realized() and nm-device.c::nm_device_create_and_realize().
This commit is contained in:

committed by
Thomas Haller

parent
b7eb622c24
commit
4dbaac4ba2
@@ -97,7 +97,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
mac_address = nm_setting_bridge_get_mac_address (s_bridge);
|
mac_address = nm_setting_bridge_get_mac_address (s_bridge);
|
||||||
if (mac_address) {
|
if (mac_address && nm_device_is_real (device)) {
|
||||||
const char *hw_addr;
|
const char *hw_addr;
|
||||||
|
|
||||||
hw_addr = nm_device_get_hw_address (device);
|
hw_addr = nm_device_get_hw_address (device);
|
||||||
|
@@ -305,9 +305,9 @@ nm_device_ethernet_init (NMDeviceEthernet *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *device, NMPlatformLink *plink)
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->setup (device, plink);
|
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->setup_start (device, plink);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (device), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
|
g_object_notify (G_OBJECT (device), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
|
||||||
}
|
}
|
||||||
@@ -1716,7 +1716,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
|||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
|
|
||||||
parent_class->get_generic_capabilities = get_generic_capabilities;
|
parent_class->get_generic_capabilities = get_generic_capabilities;
|
||||||
parent_class->setup = setup;
|
parent_class->setup_start = setup_start;
|
||||||
parent_class->check_connection_compatible = check_connection_compatible;
|
parent_class->check_connection_compatible = check_connection_compatible;
|
||||||
parent_class->complete_connection = complete_connection;
|
parent_class->complete_connection = complete_connection;
|
||||||
parent_class->new_default_connection = new_default_connection;
|
parent_class->new_default_connection = new_default_connection;
|
||||||
|
@@ -61,13 +61,13 @@ get_type_description (NMDevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *device, NMPlatformLink *plink)
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NMDeviceGeneric *self = NM_DEVICE_GENERIC (device);
|
NMDeviceGeneric *self = NM_DEVICE_GENERIC (device);
|
||||||
NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self);
|
NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self);
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
||||||
NM_DEVICE_CLASS (nm_device_generic_parent_class)->setup (device, plink);
|
NM_DEVICE_CLASS (nm_device_generic_parent_class)->setup_start (device, plink);
|
||||||
|
|
||||||
g_clear_pointer (&priv->type_description, g_free);
|
g_clear_pointer (&priv->type_description, g_free);
|
||||||
ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self));
|
ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self));
|
||||||
@@ -203,7 +203,7 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass)
|
|||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
|
|
||||||
parent_class->setup = setup;
|
parent_class->setup_start = setup_start;
|
||||||
parent_class->get_generic_capabilities = get_generic_capabilities;
|
parent_class->get_generic_capabilities = get_generic_capabilities;
|
||||||
parent_class->get_type_description = get_type_description;
|
parent_class->get_type_description = get_type_description;
|
||||||
parent_class->check_connection_compatible = check_connection_compatible;
|
parent_class->check_connection_compatible = check_connection_compatible;
|
||||||
|
@@ -149,7 +149,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
if (!s_infiniband)
|
if (!s_infiniband)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (s_infiniband) {
|
if (nm_device_is_real (device)) {
|
||||||
const char *mac;
|
const char *mac;
|
||||||
|
|
||||||
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
||||||
|
@@ -503,6 +503,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
if (!s_ip_tunnel)
|
if (!s_ip_tunnel)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (nm_device_is_real (device)) {
|
||||||
/* Check parent interface; could be an interface name or a UUID */
|
/* Check parent interface; could be an interface name or a UUID */
|
||||||
parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
|
parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
@@ -510,9 +514,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!address_equal_pp (priv->addr_family,
|
if (!address_equal_pp (priv->addr_family,
|
||||||
nm_setting_ip_tunnel_get_local (s_ip_tunnel),
|
nm_setting_ip_tunnel_get_local (s_ip_tunnel),
|
||||||
priv->local))
|
priv->local))
|
||||||
@@ -539,6 +540,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label)
|
if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -751,9 +753,9 @@ create_and_realize (NMDevice *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *device, NMPlatformLink *plink)
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->setup (device, plink);
|
NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->setup_start (device, plink);
|
||||||
|
|
||||||
update_properties (device);
|
update_properties (device);
|
||||||
}
|
}
|
||||||
@@ -847,7 +849,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
|
|||||||
device_class->check_connection_compatible = check_connection_compatible;
|
device_class->check_connection_compatible = check_connection_compatible;
|
||||||
device_class->create_and_realize = create_and_realize;
|
device_class->create_and_realize = create_and_realize;
|
||||||
device_class->realize = realize;
|
device_class->realize = realize;
|
||||||
device_class->setup = setup;
|
device_class->setup_start = setup_start;
|
||||||
device_class->unrealize = unrealize;
|
device_class->unrealize = unrealize;
|
||||||
|
|
||||||
device_class->connection_type = NM_SETTING_IP_TUNNEL_SETTING_NAME;
|
device_class->connection_type = NM_SETTING_IP_TUNNEL_SETTING_NAME;
|
||||||
|
@@ -226,6 +226,13 @@ realize (NMDevice *device, NMPlatformLink *plink, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
|
{
|
||||||
|
NM_DEVICE_CLASS (nm_device_tun_parent_class)->setup_start (device, plink);
|
||||||
|
reload_tun_properties (device);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
check_connection_compatible (NMDevice *device, NMConnection *connection)
|
check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||||
{
|
{
|
||||||
@@ -235,8 +242,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
NMSettingTun *s_tun;
|
NMSettingTun *s_tun;
|
||||||
gint64 user, group;
|
gint64 user, group;
|
||||||
|
|
||||||
reload_tun_properties (self);
|
|
||||||
|
|
||||||
if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection))
|
if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -244,6 +249,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
if (!s_tun)
|
if (!s_tun)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (nm_device_is_real (device)) {
|
||||||
mode = tun_mode_from_string (priv->mode);
|
mode = tun_mode_from_string (priv->mode);
|
||||||
if (mode != nm_setting_tun_get_mode (s_tun))
|
if (mode != nm_setting_tun_get_mode (s_tun))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -261,6 +267,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue)
|
if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -367,6 +374,7 @@ nm_device_tun_class_init (NMDeviceTunClass *klass)
|
|||||||
device_class->check_connection_compatible = check_connection_compatible;
|
device_class->check_connection_compatible = check_connection_compatible;
|
||||||
device_class->create_and_realize = create_and_realize;
|
device_class->create_and_realize = create_and_realize;
|
||||||
device_class->realize = realize;
|
device_class->realize = realize;
|
||||||
|
device_class->setup_start = setup_start;
|
||||||
device_class->unrealize = unrealize;
|
device_class->unrealize = unrealize;
|
||||||
device_class->update_connection = update_connection;
|
device_class->update_connection = update_connection;
|
||||||
|
|
||||||
|
@@ -148,12 +148,12 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *device, NMPlatformLink *plink)
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NMDeviceVlan *self = NM_DEVICE_VLAN (device);
|
NMDeviceVlan *self = NM_DEVICE_VLAN (device);
|
||||||
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
|
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
|
||||||
|
|
||||||
NM_DEVICE_CLASS (nm_device_vlan_parent_class)->setup (device, plink);
|
NM_DEVICE_CLASS (nm_device_vlan_parent_class)->setup_start (device, plink);
|
||||||
|
|
||||||
_LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s",
|
_LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s",
|
||||||
priv->vlan_id, nm_device_get_iface (priv->parent));
|
priv->vlan_id, nm_device_get_iface (priv->parent));
|
||||||
@@ -311,6 +311,9 @@ notify_new_device_added (NMDevice *device, NMDevice *new_device)
|
|||||||
if (priv->parent)
|
if (priv->parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!nm_device_is_real (device))
|
||||||
|
return;
|
||||||
|
|
||||||
plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
|
plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
|
||||||
if (!plnk) {
|
if (!plnk) {
|
||||||
_LOGW (LOGD_VLAN, "failed to get VLAN interface info while checking added component.");
|
_LOGW (LOGD_VLAN, "failed to get VLAN interface info while checking added component.");
|
||||||
@@ -397,6 +400,8 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
if (!s_vlan)
|
if (!s_vlan)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* Before the device is realized some properties will not be set */
|
||||||
|
if (nm_device_is_real (device)) {
|
||||||
if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id)
|
if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -410,6 +415,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||||||
if (!match_hwaddr (device, connection, TRUE))
|
if (!match_hwaddr (device, connection, TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure the interface name matches. If not specified we assume a match
|
/* Ensure the interface name matches. If not specified we assume a match
|
||||||
* since both the parent interface and the VLAN ID matched by the time we
|
* since both the parent interface and the VLAN ID matched by the time we
|
||||||
@@ -672,7 +678,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
|
|||||||
|
|
||||||
parent_class->create_and_realize = create_and_realize;
|
parent_class->create_and_realize = create_and_realize;
|
||||||
parent_class->realize = realize;
|
parent_class->realize = realize;
|
||||||
parent_class->setup = setup;
|
parent_class->setup_start = setup_start;
|
||||||
parent_class->unrealize = unrealize;
|
parent_class->unrealize = unrealize;
|
||||||
parent_class->get_generic_capabilities = get_generic_capabilities;
|
parent_class->get_generic_capabilities = get_generic_capabilities;
|
||||||
parent_class->bring_up = bring_up;
|
parent_class->bring_up = bring_up;
|
||||||
|
@@ -133,11 +133,11 @@ link_changed (NMDevice *device, NMPlatformLink *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *device, NMPlatformLink *plink)
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
g_assert (plink->type == NM_LINK_TYPE_VXLAN);
|
g_assert (plink->type == NM_LINK_TYPE_VXLAN);
|
||||||
|
|
||||||
NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->setup (device, plink);
|
NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->setup_start (device, plink);
|
||||||
|
|
||||||
update_properties (device);
|
update_properties (device);
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
|
|||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
|
||||||
device_class->link_changed = link_changed;
|
device_class->link_changed = link_changed;
|
||||||
device_class->setup = setup;
|
device_class->setup_start = setup_start;
|
||||||
device_class->unrealize = unrealize;
|
device_class->unrealize = unrealize;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
|
@@ -556,7 +556,7 @@ nm_device_get_iface (NMDevice *self)
|
|||||||
int
|
int
|
||||||
nm_device_get_ifindex (NMDevice *self)
|
nm_device_get_ifindex (NMDevice *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (self != NULL, 0);
|
g_return_val_if_fail (NM_IS_DEVICE (self), 0);
|
||||||
|
|
||||||
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
|
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
|
||||||
}
|
}
|
||||||
@@ -1152,8 +1152,7 @@ nm_device_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure
|
|||||||
static gboolean
|
static gboolean
|
||||||
can_unmanaged_external_down (NMDevice *self)
|
can_unmanaged_external_down (NMDevice *self)
|
||||||
{
|
{
|
||||||
return nm_device_is_software (self)
|
return nm_device_is_software (self) && !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
|
||||||
&& !nm_device_get_is_nm_owned (self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1385,12 +1384,19 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
device_set_master (NMDevice *self, int ifindex)
|
device_recheck_slave_status (NMDevice *self, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NMDevice *master;
|
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
master = nm_manager_get_device_by_ifindex (nm_manager_get (), ifindex);
|
g_return_if_fail (plink != NULL);
|
||||||
|
|
||||||
|
if (priv->enslaved && plink->master != nm_device_get_ifindex (priv->master))
|
||||||
|
nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
|
||||||
|
|
||||||
|
if (plink->master && !priv->enslaved) {
|
||||||
|
NMDevice *master;
|
||||||
|
|
||||||
|
master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
|
||||||
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
|
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
|
||||||
g_clear_object (&priv->master);
|
g_clear_object (&priv->master);
|
||||||
priv->master = g_object_ref (master);
|
priv->master = g_object_ref (master);
|
||||||
@@ -1400,8 +1406,9 @@ device_set_master (NMDevice *self, int ifindex)
|
|||||||
nm_device_get_iface (master));
|
nm_device_get_iface (master));
|
||||||
} else {
|
} else {
|
||||||
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
|
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
|
||||||
ifindex,
|
plink->master,
|
||||||
nm_platform_link_get_name (NM_PLATFORM_GET, ifindex));
|
nm_platform_link_get_name (NM_PLATFORM_GET, plink->master));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1449,6 +1456,12 @@ device_link_changed (NMDevice *self)
|
|||||||
g_object_notify (G_OBJECT (self), NM_DEVICE_MTU);
|
g_object_notify (G_OBJECT (self), NM_DEVICE_MTU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.driver && g_strcmp0 (priv->driver, info.driver) != 0) {
|
||||||
|
g_free (priv->driver);
|
||||||
|
priv->driver = g_strdup (info.driver);
|
||||||
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER);
|
||||||
|
}
|
||||||
|
|
||||||
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
|
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
|
||||||
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
||||||
priv->ifindex, priv->iface, info.name);
|
priv->ifindex, priv->iface, info.name);
|
||||||
@@ -1471,15 +1484,6 @@ device_link_changed (NMDevice *self)
|
|||||||
nm_device_emit_recheck_auto_activate (self);
|
nm_device_emit_recheck_auto_activate (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update slave status for external changes */
|
|
||||||
if (priv->enslaved && info.master != nm_device_get_ifindex (priv->master))
|
|
||||||
nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
|
|
||||||
if (info.master && !priv->enslaved) {
|
|
||||||
device_set_master (self, info.master);
|
|
||||||
if (priv->master)
|
|
||||||
nm_device_enslave_slave (priv->master, self, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
|
if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
|
||||||
_LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
|
_LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
|
||||||
if (nm_rdisc_set_iid (priv->rdisc, token_iid))
|
if (nm_rdisc_set_iid (priv->rdisc, token_iid))
|
||||||
@@ -1562,6 +1566,7 @@ device_link_changed (NMDevice *self)
|
|||||||
if (emit_link_initialized)
|
if (emit_link_initialized)
|
||||||
g_signal_emit (self, signals[LINK_INITIALIZED], 0);
|
g_signal_emit (self, signals[LINK_INITIALIZED], 0);
|
||||||
|
|
||||||
|
device_recheck_slave_status (self, &info);
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1635,7 +1640,8 @@ link_changed (NMDevice *self, NMPlatformLink *info)
|
|||||||
* @plink: an existing platform link or %NULL
|
* @plink: an existing platform link or %NULL
|
||||||
* @error: location to store error, or %NULL
|
* @error: location to store error, or %NULL
|
||||||
*
|
*
|
||||||
* Initializes and sets up the device using existing backing resources.
|
* Initializes and sets up the device using existing backing resources. Before
|
||||||
|
* the device is ready for use nm_device_setup_finish() must be called.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE on success, %FALSE on error
|
* Returns: %TRUE on success, %FALSE on error
|
||||||
*/
|
*/
|
||||||
@@ -1648,7 +1654,7 @@ nm_device_realize (NMDevice *self, NMPlatformLink *plink, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NM_DEVICE_GET_CLASS (self)->setup (self, plink);
|
NM_DEVICE_GET_CLASS (self)->setup_start (self, plink);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1671,15 +1677,20 @@ nm_device_create_and_realize (NMDevice *self,
|
|||||||
NMDevice *parent,
|
NMDevice *parent,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
NMPlatformLink plink = { .type = NM_LINK_TYPE_UNKNOWN };
|
NMPlatformLink plink = { .type = NM_LINK_TYPE_UNKNOWN };
|
||||||
|
|
||||||
|
/* Must be set before device is realized */
|
||||||
|
priv->is_nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
|
||||||
|
|
||||||
/* Create any resources the device needs */
|
/* Create any resources the device needs */
|
||||||
if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
|
if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
|
||||||
if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
|
if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NM_DEVICE_GET_CLASS (self)->setup (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
|
NM_DEVICE_GET_CLASS (self)->setup_start (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
|
||||||
|
nm_device_setup_finish (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
|
||||||
|
|
||||||
g_return_val_if_fail (nm_device_check_connection_compatible (self, connection), TRUE);
|
g_return_val_if_fail (nm_device_check_connection_compatible (self, connection), TRUE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -1742,7 +1753,7 @@ check_carrier (NMDevice *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *self, NMPlatformLink *plink)
|
setup_start (NMDevice *self, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
static guint32 id = 0;
|
static guint32 id = 0;
|
||||||
@@ -1751,6 +1762,7 @@ setup (NMDevice *self, NMPlatformLink *plink)
|
|||||||
g_return_if_fail (priv->ip_ifindex <= 0);
|
g_return_if_fail (priv->ip_ifindex <= 0);
|
||||||
g_return_if_fail (priv->ip_iface == NULL);
|
g_return_if_fail (priv->ip_iface == NULL);
|
||||||
|
|
||||||
|
/* Balanced by a thaw in nm_device_setup_finish() */
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
if (plink) {
|
if (plink) {
|
||||||
@@ -1759,7 +1771,7 @@ setup (NMDevice *self, NMPlatformLink *plink)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (priv->ifindex > 0) {
|
if (priv->ifindex > 0) {
|
||||||
_LOGD (LOGD_DEVICE, "setup(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
|
_LOGD (LOGD_DEVICE, "setup_start(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
|
||||||
|
|
||||||
priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
|
priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
|
||||||
g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID);
|
g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID);
|
||||||
@@ -1844,17 +1856,29 @@ setup (NMDevice *self, NMPlatformLink *plink)
|
|||||||
|
|
||||||
g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES);
|
g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES);
|
||||||
|
|
||||||
/* Enslave ourselves */
|
priv->real = TRUE;
|
||||||
if (priv->ifindex > 0) {
|
|
||||||
int master = nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex);
|
|
||||||
|
|
||||||
if (master > 0)
|
|
||||||
device_set_master (self, master);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->real = TRUE;
|
static void
|
||||||
|
setup_finish (NMDevice *self, NMPlatformLink *plink)
|
||||||
|
{
|
||||||
|
if (plink) {
|
||||||
|
update_device_from_platform_link (self, plink);
|
||||||
|
device_recheck_slave_status (self, plink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_device_setup_finish (NMDevice *self, NMPlatformLink *plink)
|
||||||
|
{
|
||||||
|
NM_DEVICE_GET_CLASS (self)->setup_finish (self, plink);
|
||||||
|
|
||||||
|
NM_DEVICE_GET_PRIVATE (self)->real = TRUE;
|
||||||
g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
|
g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
|
||||||
|
|
||||||
|
nm_device_recheck_available_connections (self);
|
||||||
|
|
||||||
|
/* Balanced by a freeze in setup_start() */
|
||||||
g_object_thaw_notify (G_OBJECT (self));
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2810,7 +2834,8 @@ nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection)
|
|||||||
static gboolean
|
static gboolean
|
||||||
nm_device_can_assume_connections (NMDevice *self)
|
nm_device_can_assume_connections (NMDevice *self)
|
||||||
{
|
{
|
||||||
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
|
return !!NM_DEVICE_GET_CLASS (self)->update_connection
|
||||||
|
&& !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6547,14 +6572,6 @@ nm_device_get_is_nm_owned (NMDevice *self)
|
|||||||
return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
|
return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nm_device_set_nm_owned (NMDevice *self)
|
|
||||||
{
|
|
||||||
g_return_if_fail (NM_IS_DEVICE (self));
|
|
||||||
|
|
||||||
NM_DEVICE_GET_PRIVATE (self)->is_nm_owned = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* delete_on_deactivate_link_delete
|
* delete_on_deactivate_link_delete
|
||||||
*
|
*
|
||||||
@@ -8461,6 +8478,7 @@ _nm_device_check_connection_available (NMDevice *self,
|
|||||||
&& nm_device_get_unmanaged (self, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT))
|
&& nm_device_get_unmanaged (self, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( state < NM_DEVICE_STATE_DISCONNECTED
|
if ( state < NM_DEVICE_STATE_DISCONNECTED
|
||||||
|
&& !nm_device_is_software (self)
|
||||||
&& ( ( !NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
|
&& ( ( !NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
|
||||||
&& !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
|
&& !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
|
||||||
|| ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
|
|| ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
|
||||||
@@ -10324,7 +10342,8 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||||||
klass->check_connection_compatible = check_connection_compatible;
|
klass->check_connection_compatible = check_connection_compatible;
|
||||||
klass->check_connection_available = check_connection_available;
|
klass->check_connection_available = check_connection_available;
|
||||||
klass->can_unmanaged_external_down = can_unmanaged_external_down;
|
klass->can_unmanaged_external_down = can_unmanaged_external_down;
|
||||||
klass->setup = setup;
|
klass->setup_start = setup_start;
|
||||||
|
klass->setup_finish = setup_finish;
|
||||||
klass->unrealize = unrealize;
|
klass->unrealize = unrealize;
|
||||||
klass->is_up = is_up;
|
klass->is_up = is_up;
|
||||||
klass->bring_up = bring_up;
|
klass->bring_up = bring_up;
|
||||||
|
@@ -174,14 +174,28 @@ typedef struct {
|
|||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setup():
|
* setup_start():
|
||||||
* @self: the #NMDevice
|
* @self: the #NMDevice
|
||||||
* @plink: the #NMPlatformLink if backed by a kernel netdevice
|
* @plink: the #NMPlatformLink if backed by a kernel netdevice
|
||||||
*
|
*
|
||||||
* Update the device from backing resource properties (like hardware
|
* Update the device from backing resource properties (like hardware
|
||||||
* addresses, carrier states, driver/firmware info, etc).
|
* addresses, carrier states, driver/firmware info, etc). This function
|
||||||
|
* should only change properties for this device, and should not perform
|
||||||
|
* any tasks that affect other interfaces (like master/slave or parent/child
|
||||||
|
* stuff).
|
||||||
*/
|
*/
|
||||||
void (*setup) (NMDevice *self, NMPlatformLink *plink);
|
void (*setup_start) (NMDevice *self, NMPlatformLink *plink);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup_finish():
|
||||||
|
* @self: the #NMDevice
|
||||||
|
* @plink: the #NMPlatformLink if backed by a kernel netdevice
|
||||||
|
*
|
||||||
|
* Update the device's master/slave or parent/child relationships from
|
||||||
|
* backing resource properties. After this function finishes, the device
|
||||||
|
* is ready for network connectivity.
|
||||||
|
*/
|
||||||
|
void (*setup_finish) (NMDevice *self, NMPlatformLink *plink);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unrealize():
|
* unrealize():
|
||||||
@@ -466,7 +480,6 @@ void nm_device_set_unmanaged_initial (NMDevice *device,
|
|||||||
gboolean unmanaged);
|
gboolean unmanaged);
|
||||||
|
|
||||||
gboolean nm_device_get_is_nm_owned (NMDevice *device);
|
gboolean nm_device_get_is_nm_owned (NMDevice *device);
|
||||||
void nm_device_set_nm_owned (NMDevice *device);
|
|
||||||
|
|
||||||
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
|
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
|
||||||
|
|
||||||
@@ -477,6 +490,8 @@ gboolean nm_device_create_and_realize (NMDevice *self,
|
|||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
NMDevice *parent,
|
NMDevice *parent,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
void nm_device_setup_finish (NMDevice *self,
|
||||||
|
NMPlatformLink *plink);
|
||||||
gboolean nm_device_unrealize (NMDevice *device,
|
gboolean nm_device_unrealize (NMDevice *device,
|
||||||
gboolean remove_resources,
|
gboolean remove_resources,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
@@ -424,9 +424,9 @@ periodic_update_cb (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup (NMDevice *device, NMPlatformLink *plink)
|
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||||
{
|
{
|
||||||
NM_DEVICE_CLASS (nm_device_wifi_parent_class)->setup (device, plink);
|
NM_DEVICE_CLASS (nm_device_wifi_parent_class)->setup_start (device, plink);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
|
g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
|
||||||
}
|
}
|
||||||
@@ -3040,7 +3040,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
|
|
||||||
parent_class->setup = setup;
|
parent_class->setup_start = setup_start;
|
||||||
parent_class->bring_up = bring_up;
|
parent_class->bring_up = bring_up;
|
||||||
parent_class->can_auto_connect = can_auto_connect;
|
parent_class->can_auto_connect = can_auto_connect;
|
||||||
parent_class->is_available = is_available;
|
parent_class->is_available = is_available;
|
||||||
|
@@ -598,17 +598,17 @@ master_state_cb (NMActiveConnection *master,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
|
NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
|
||||||
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
|
|
||||||
NMActiveConnectionState master_state = nm_active_connection_get_state (master);
|
NMActiveConnectionState master_state = nm_active_connection_get_state (master);
|
||||||
|
NMDevice *master_device = nm_active_connection_get_device (master);
|
||||||
|
|
||||||
check_master_ready (self);
|
check_master_ready (self);
|
||||||
|
|
||||||
_LOGD ("master ActiveConnection [%p] state now '%s' (%d)",
|
_LOGD ("master ActiveConnection [%p] state now '%s' (%d)",
|
||||||
master, state_to_string (master_state), master_state);
|
master, state_to_string (master_state), master_state);
|
||||||
|
|
||||||
if ( master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING
|
if ( master_state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATING
|
||||||
&& !priv->master_ready) {
|
&& (!master_device || !nm_device_is_real (master_device))) {
|
||||||
/* Master failed without ever creating its device */
|
/* Master failed without ever creating or realizing its device */
|
||||||
if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
|
if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
|
||||||
NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
|
NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
|
||||||
}
|
}
|
||||||
|
303
src/nm-manager.c
303
src/nm-manager.c
@@ -58,7 +58,7 @@
|
|||||||
#include "nmdbus-manager.h"
|
#include "nmdbus-manager.h"
|
||||||
#include "nmdbus-device.h"
|
#include "nmdbus-device.h"
|
||||||
|
|
||||||
static void add_device (NMManager *self, NMDevice *device, gboolean try_assume);
|
static void add_device (NMManager *self, NMDevice *device);
|
||||||
|
|
||||||
static NMActiveConnection *_new_active_connection (NMManager *self,
|
static NMActiveConnection *_new_active_connection (NMManager *self,
|
||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
@@ -487,8 +487,11 @@ find_device_by_ip_iface (NMManager *self, const gchar *iface)
|
|||||||
g_return_val_if_fail (iface != NULL, NULL);
|
g_return_val_if_fail (iface != NULL, NULL);
|
||||||
|
|
||||||
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
|
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
|
||||||
if (g_strcmp0 (nm_device_get_ip_iface (NM_DEVICE (iter->data)), iface) == 0)
|
NMDevice *candidate = iter->data;
|
||||||
return NM_DEVICE (iter->data);
|
|
||||||
|
if ( nm_device_is_real (candidate)
|
||||||
|
&& g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
|
||||||
|
return candidate;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -840,6 +843,8 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection)
|
|||||||
NMDevice *parent, *first_compatible = NULL;
|
NMDevice *parent, *first_compatible = NULL;
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||||
|
|
||||||
factory = nm_device_factory_manager_find_factory_for_connection (connection);
|
factory = nm_device_factory_manager_find_factory_for_connection (connection);
|
||||||
if (!factory)
|
if (!factory)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -849,7 +854,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Try as an interface name */
|
/* Try as an interface name */
|
||||||
parent = find_device_by_ip_iface (self, parent_name);
|
parent = find_device_by_iface (self, parent_name);
|
||||||
if (parent)
|
if (parent)
|
||||||
return parent;
|
return parent;
|
||||||
|
|
||||||
@@ -964,10 +969,9 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
|
|||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
NMDeviceFactory *factory;
|
NMDeviceFactory *factory;
|
||||||
GSList *iter;
|
GSList *connections, *iter;
|
||||||
char *iface = NULL;
|
gs_free char *iface = NULL;
|
||||||
NMDevice *device = NULL, *parent = NULL;
|
NMDevice *device = NULL, *parent = NULL;
|
||||||
gboolean nm_owned = FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
|
g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
|
||||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||||
@@ -989,7 +993,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
|
|||||||
NM_MANAGER_ERROR,
|
NM_MANAGER_ERROR,
|
||||||
NM_MANAGER_ERROR_FAILED,
|
NM_MANAGER_ERROR_FAILED,
|
||||||
"interface name '%s' already created", iface);
|
"interface name '%s' already created", iface);
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1003,79 +1007,61 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
|
|||||||
NM_MANAGER_ERROR_FAILED,
|
NM_MANAGER_ERROR_FAILED,
|
||||||
"NetworkManager plugin for '%s' unavailable",
|
"NetworkManager plugin for '%s' unavailable",
|
||||||
nm_connection_get_connection_type (connection));
|
nm_connection_get_connection_type (connection));
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface);
|
|
||||||
|
|
||||||
device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, error);
|
device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, error);
|
||||||
if (device) {
|
if (!device)
|
||||||
if (!nm_device_create_and_realize (device, connection, parent, error)) {
|
return NULL;
|
||||||
g_clear_object (&device);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nm_owned)
|
add_device (self, device);
|
||||||
nm_device_set_nm_owned (device);
|
|
||||||
|
|
||||||
/* If it was created by NM there's no connection to assume, but if it
|
|
||||||
* previously existed there might be one.
|
|
||||||
*/
|
|
||||||
add_device (self, device, !nm_owned);
|
|
||||||
|
|
||||||
/* Add device takes a reference that NMManager still owns, so it's
|
/* Add device takes a reference that NMManager still owns, so it's
|
||||||
* safe to unref here and still return @device.
|
* safe to unref here and still return @device.
|
||||||
*/
|
*/
|
||||||
g_object_unref (device);
|
g_object_unref (device);
|
||||||
|
|
||||||
|
/* Create backing resources if the device has any autoconnect connections */
|
||||||
|
connections = nm_settings_get_connections (priv->settings);
|
||||||
|
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
||||||
|
NMConnection *candidate = iter->data;
|
||||||
|
NMSettingConnection *s_con;
|
||||||
|
|
||||||
|
if (!nm_device_check_connection_compatible (device, candidate))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s_con = nm_connection_get_setting_connection (candidate);
|
||||||
|
g_assert (s_con);
|
||||||
|
if (!nm_setting_connection_get_autoconnect (s_con))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Create any backing resources the device needs */
|
||||||
|
if (!nm_device_create_and_realize (device, connection, parent, error)) {
|
||||||
|
remove_device (self, device, FALSE, TRUE);
|
||||||
|
device = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
g_free (iface);
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
system_create_virtual_devices (NMManager *self)
|
|
||||||
{
|
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
||||||
GSList *iter, *connections;
|
|
||||||
|
|
||||||
nm_log_dbg (LOGD_CORE, "creating virtual devices...");
|
|
||||||
|
|
||||||
connections = nm_settings_get_connections (priv->settings);
|
|
||||||
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
|
||||||
NMConnection *connection = iter->data;
|
|
||||||
|
|
||||||
/* We only create a virtual interface if the connection can autoconnect */
|
|
||||||
if ( nm_connection_is_virtual (connection)
|
|
||||||
&& nm_settings_connection_can_autoconnect (NM_SETTINGS_CONNECTION (connection)))
|
|
||||||
system_create_virtual_device (self, connection, NULL);
|
|
||||||
}
|
|
||||||
g_slist_free (connections);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
connection_added (NMSettings *settings,
|
connection_added (NMSettings *settings,
|
||||||
NMSettingsConnection *settings_connection,
|
NMConnection *connection,
|
||||||
NMManager *manager)
|
NMManager *manager)
|
||||||
{
|
{
|
||||||
NMConnection *connection = NM_CONNECTION (settings_connection);
|
if (nm_connection_is_virtual (connection))
|
||||||
|
|
||||||
if (nm_connection_is_virtual (connection)) {
|
|
||||||
NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
|
|
||||||
|
|
||||||
g_assert (s_con);
|
|
||||||
if (nm_setting_connection_get_autoconnect (s_con))
|
|
||||||
system_create_virtual_device (manager, connection, NULL);
|
system_create_virtual_device (manager, connection, NULL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
connection_changed (NMSettings *settings,
|
connection_changed (NMSettings *settings,
|
||||||
NMSettingsConnection *connection,
|
NMConnection *connection,
|
||||||
NMManager *manager)
|
NMManager *manager)
|
||||||
{
|
{
|
||||||
/* FIXME: Some virtual devices may need to be updated in the future. */
|
if (nm_connection_is_virtual (connection))
|
||||||
|
system_create_virtual_device (manager, connection, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1590,17 +1576,25 @@ assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *conn
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
can_start_device (NMManager *self, NMDevice *device)
|
||||||
|
{
|
||||||
|
return nm_device_is_real (device)
|
||||||
|
&& !manager_sleeping (self)
|
||||||
|
&& !nm_device_get_unmanaged (device, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
recheck_assume_connection (NMDevice *device, gpointer user_data)
|
recheck_assume_connection (NMDevice *device, gpointer user_data)
|
||||||
{
|
{
|
||||||
NMManager *self = NM_MANAGER (user_data);
|
NMManager *self = NM_MANAGER (user_data);
|
||||||
NMSettingsConnection *connection;
|
NMSettingsConnection *connection;
|
||||||
gboolean was_unmanaged = FALSE, success, generated;
|
gboolean was_unmanaged = FALSE, success, generated = FALSE;
|
||||||
NMDeviceState state;
|
NMDeviceState state;
|
||||||
|
|
||||||
if (manager_sleeping (self))
|
g_return_val_if_fail (!nm_device_get_is_nm_owned (device), FALSE);
|
||||||
return FALSE;
|
|
||||||
if (nm_device_get_unmanaged (device, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT))
|
if (!can_start_device (self, device))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
state = nm_device_get_state (device);
|
state = nm_device_get_state (device);
|
||||||
@@ -1671,26 +1665,51 @@ device_ip_iface_changed (NMDevice *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_realized (NMDevice *device,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
NMManager *self)
|
||||||
|
{
|
||||||
|
int ifindex;
|
||||||
|
gboolean assumed = FALSE;
|
||||||
|
|
||||||
|
/* Loopback device never gets managed */
|
||||||
|
ifindex = nm_device_get_ifindex (device);
|
||||||
|
if (ifindex > 0 && nm_platform_link_get_type (NM_PLATFORM_GET, ifindex) == NM_LINK_TYPE_LOOPBACK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!can_start_device (self, device))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!nm_device_get_is_nm_owned (device)) {
|
||||||
|
assumed = recheck_assume_connection (device, self);
|
||||||
|
g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
|
||||||
|
G_CALLBACK (recheck_assume_connection), self);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assumed && nm_device_get_managed (device)) {
|
||||||
|
nm_device_state_changed (device,
|
||||||
|
NM_DEVICE_STATE_UNAVAILABLE,
|
||||||
|
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add_device:
|
* add_device:
|
||||||
* @self: the #NMManager
|
* @self: the #NMManager
|
||||||
* @device: the #NMDevice to add
|
* @device: the #NMDevice to add
|
||||||
* @try_assume: %TRUE if existing connection (if any) should be assumed
|
|
||||||
*
|
*
|
||||||
* If successful, this function will increase the references count of @device.
|
* If successful, this function will increase the references count of @device.
|
||||||
* Callers should decrease the reference count.
|
* Callers should decrease the reference count.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
add_device (NMManager *self, NMDevice *device, gboolean try_assume)
|
add_device (NMManager *self, NMDevice *device)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
const char *iface, *driver, *type_desc;
|
const char *iface, *type_desc;
|
||||||
const GSList *unmanaged_specs;
|
const GSList *unmanaged_specs;
|
||||||
gboolean user_unmanaged, sleeping;
|
|
||||||
gboolean enabled = FALSE;
|
|
||||||
RfKillType rtype;
|
RfKillType rtype;
|
||||||
GSList *iter, *remove = NULL;
|
GSList *iter, *remove = NULL;
|
||||||
gboolean connection_assumed = FALSE;
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
const char *dbus_path;
|
const char *dbus_path;
|
||||||
|
|
||||||
@@ -1738,6 +1757,9 @@ add_device (NMManager *self, NMDevice *device, gboolean try_assume)
|
|||||||
g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
|
g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
|
||||||
G_CALLBACK (device_ip_iface_changed),
|
G_CALLBACK (device_ip_iface_changed),
|
||||||
self);
|
self);
|
||||||
|
g_signal_connect (device, "notify::" NM_DEVICE_REAL,
|
||||||
|
G_CALLBACK (device_realized),
|
||||||
|
self);
|
||||||
|
|
||||||
if (priv->startup) {
|
if (priv->startup) {
|
||||||
g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
|
g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
|
||||||
@@ -1752,52 +1774,29 @@ add_device (NMManager *self, NMDevice *device, gboolean try_assume)
|
|||||||
rtype = nm_device_get_rfkill_type (device);
|
rtype = nm_device_get_rfkill_type (device);
|
||||||
if (rtype != RFKILL_TYPE_UNKNOWN) {
|
if (rtype != RFKILL_TYPE_UNKNOWN) {
|
||||||
nm_manager_rfkill_update (self, rtype);
|
nm_manager_rfkill_update (self, rtype);
|
||||||
enabled = radio_enabled_for_type (self, rtype, TRUE);
|
nm_device_set_enabled (device, radio_enabled_for_type (self, rtype, TRUE));
|
||||||
nm_device_set_enabled (device, enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iface = nm_device_get_iface (device);
|
iface = nm_device_get_iface (device);
|
||||||
g_assert (iface);
|
g_assert (iface);
|
||||||
|
|
||||||
type_desc = nm_device_get_type_desc (device);
|
type_desc = nm_device_get_type_desc (device);
|
||||||
g_assert (type_desc);
|
g_assert (type_desc);
|
||||||
driver = nm_device_get_driver (device);
|
|
||||||
if (!driver)
|
nm_log_info (LOGD_HW, "(%s): new %s device", iface, type_desc);
|
||||||
driver = "unknown";
|
|
||||||
nm_log_info (LOGD_HW, "(%s): new %s device (carrier: %s, driver: '%s', ifindex: %d)",
|
|
||||||
iface, type_desc,
|
|
||||||
nm_device_has_capability (device, NM_DEVICE_CAP_CARRIER_DETECT)
|
|
||||||
? (nm_device_has_carrier (device) ? "ON" : "OFF")
|
|
||||||
: "UNKNOWN",
|
|
||||||
driver, nm_device_get_ifindex (device));
|
|
||||||
|
|
||||||
unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
|
unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
|
||||||
user_unmanaged = nm_device_spec_match_list (device, unmanaged_specs);
|
nm_device_set_unmanaged_initial (device,
|
||||||
nm_device_set_unmanaged_initial (device, NM_UNMANAGED_USER, user_unmanaged);
|
NM_UNMANAGED_USER,
|
||||||
|
nm_device_spec_match_list (device, unmanaged_specs));
|
||||||
sleeping = manager_sleeping (self);
|
nm_device_set_unmanaged_initial (device,
|
||||||
nm_device_set_unmanaged_initial (device, NM_UNMANAGED_INTERNAL, sleeping);
|
NM_UNMANAGED_INTERNAL,
|
||||||
|
manager_sleeping (self));
|
||||||
|
|
||||||
dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device));
|
dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device));
|
||||||
nm_log_dbg (LOGD_DEVICE, "(%s): exported as %s", nm_device_get_iface (device), dbus_path);
|
nm_log_dbg (LOGD_DEVICE, "(%s): exported as %s", nm_device_get_iface (device), dbus_path);
|
||||||
|
|
||||||
nm_device_finish_init (device);
|
nm_device_finish_init (device);
|
||||||
|
|
||||||
if (try_assume) {
|
|
||||||
connection_assumed = recheck_assume_connection (device, self);
|
|
||||||
g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
|
|
||||||
G_CALLBACK (recheck_assume_connection), self);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!connection_assumed && nm_device_get_managed (device)) {
|
|
||||||
nm_device_state_changed (device,
|
|
||||||
NM_DEVICE_STATE_UNAVAILABLE,
|
|
||||||
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to generate a default connection. If this fails because the link is
|
|
||||||
* not initialized, we will retry again in device_link_initialized_cb().
|
|
||||||
*/
|
|
||||||
nm_settings_device_added (priv->settings, device);
|
nm_settings_device_added (priv->settings, device);
|
||||||
g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
|
g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
|
||||||
g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
|
g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
|
||||||
@@ -1808,11 +1807,6 @@ add_device (NMManager *self, NMDevice *device, gboolean try_assume)
|
|||||||
if (d != device)
|
if (d != device)
|
||||||
nm_device_notify_new_device_added (d, device);
|
nm_device_notify_new_device_added (d, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New devices might be master interfaces for virtual interfaces; so we may
|
|
||||||
* need to create new virtual interfaces now.
|
|
||||||
*/
|
|
||||||
system_create_virtual_devices (self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
@@ -1824,9 +1818,10 @@ factory_device_added_cb (NMDeviceFactory *factory,
|
|||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (nm_device_realize (device, NULL, &error))
|
if (nm_device_realize (device, NULL, &error)) {
|
||||||
add_device (NM_MANAGER (user_data), device, TRUE);
|
add_device (NM_MANAGER (user_data), device);
|
||||||
else {
|
nm_device_setup_finish (device, NULL);
|
||||||
|
} else {
|
||||||
nm_log_warn (LOGD_DEVICE, "(%s): failed to realize device: %s",
|
nm_log_warn (LOGD_DEVICE, "(%s): failed to realize device: %s",
|
||||||
nm_device_get_iface (device), error->message);
|
nm_device_get_iface (device), error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
@@ -1881,6 +1876,26 @@ platform_link_added (NMManager *self,
|
|||||||
if (nm_manager_get_device_by_ifindex (self, ifindex))
|
if (nm_manager_get_device_by_ifindex (self, ifindex))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
device = find_device_by_iface (self, plink->name);
|
||||||
|
if (device) {
|
||||||
|
if (!nm_device_is_real (device)) {
|
||||||
|
if (nm_device_realize (device, plink, &error))
|
||||||
|
nm_device_setup_finish (device, plink);
|
||||||
|
else {
|
||||||
|
nm_log_warn (LOGD_DEVICE, "(%s): %s", plink->name, error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
remove_device (self, device, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (!nm_device_realize (device, plink, &error)) {
|
||||||
|
nm_log_warn (LOGD_HW, "%s: factory failed to create device: %s",
|
||||||
|
plink->name, error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try registered device factories */
|
/* Try registered device factories */
|
||||||
factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
|
factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
|
||||||
if (factory) {
|
if (factory) {
|
||||||
@@ -1917,10 +1932,11 @@ platform_link_added (NMManager *self,
|
|||||||
if (device) {
|
if (device) {
|
||||||
if (nm_plugin_missing)
|
if (nm_plugin_missing)
|
||||||
nm_device_set_nm_plugin_missing (device, TRUE);
|
nm_device_set_nm_plugin_missing (device, TRUE);
|
||||||
if (nm_device_realize (device, plink, &error))
|
if (nm_device_realize (device, plink, &error)) {
|
||||||
add_device (self, device, plink->type != NM_LINK_TYPE_LOOPBACK);
|
add_device (self, device);
|
||||||
else {
|
nm_device_setup_finish (device, plink);
|
||||||
nm_log_warn (LOGD_HW, "%s: failed to realize device: %s",
|
} else {
|
||||||
|
nm_log_warn (LOGD_DEVICE, "%s: failed to realize device: %s",
|
||||||
plink->name, error->message);
|
plink->name, error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
@@ -1954,18 +1970,22 @@ _platform_link_cb_idle (PlatformLinkCbData *data)
|
|||||||
device = nm_manager_get_device_by_ifindex (self, data->ifindex);
|
device = nm_manager_get_device_by_ifindex (self, data->ifindex);
|
||||||
if (device) {
|
if (device) {
|
||||||
if (nm_device_is_software (device)) {
|
if (nm_device_is_software (device)) {
|
||||||
|
/* Software devices stick around until their connection is removed */
|
||||||
if (!nm_device_unrealize (device, FALSE, &error)) {
|
if (!nm_device_unrealize (device, FALSE, &error)) {
|
||||||
nm_log_warn (LOGD_DEVICE, "(%s): failed to unrealize: %s",
|
nm_log_warn (LOGD_DEVICE, "(%s): failed to unrealize: %s",
|
||||||
nm_device_get_iface (device),
|
nm_device_get_iface (device),
|
||||||
error->message);
|
error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
remove_device (self, device, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
/* Hardware devices always get removed when their kernel link is gone */
|
||||||
remove_device (self, device, FALSE, TRUE);
|
remove_device (self, device, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
|
g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
g_slice_free (PlatformLinkCbData, data);
|
g_slice_free (PlatformLinkCbData, data);
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
@@ -2079,7 +2099,8 @@ impl_manager_get_devices (NMManager *self,
|
|||||||
const char *path;
|
const char *path;
|
||||||
|
|
||||||
path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
|
path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
|
||||||
if (path)
|
if ( path
|
||||||
|
&& nm_device_is_real (iter->data))
|
||||||
paths[i++] = path;
|
paths[i++] = path;
|
||||||
}
|
}
|
||||||
paths[i++] = NULL;
|
paths[i++] = NULL;
|
||||||
@@ -2181,7 +2202,7 @@ find_master (NMManager *self,
|
|||||||
const char *master;
|
const char *master;
|
||||||
NMDevice *master_device = NULL;
|
NMDevice *master_device = NULL;
|
||||||
NMSettingsConnection *master_connection = NULL;
|
NMSettingsConnection *master_connection = NULL;
|
||||||
GSList *iter, *connections = NULL;
|
GSList *iter;
|
||||||
|
|
||||||
s_con = nm_connection_get_setting_connection (connection);
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
g_assert (s_con);
|
g_assert (s_con);
|
||||||
@@ -2191,7 +2212,7 @@ find_master (NMManager *self,
|
|||||||
return TRUE; /* success, but no master */
|
return TRUE; /* success, but no master */
|
||||||
|
|
||||||
/* Try as an interface name first */
|
/* Try as an interface name first */
|
||||||
master_device = find_device_by_ip_iface (self, master);
|
master_device = find_device_by_iface (self, master);
|
||||||
if (master_device) {
|
if (master_device) {
|
||||||
if (master_device == device) {
|
if (master_device == device) {
|
||||||
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
||||||
@@ -2223,23 +2244,6 @@ find_master (NMManager *self,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* Might be a virtual interface that hasn't been created yet, so
|
|
||||||
* look through the interface names of connections that require
|
|
||||||
* virtual interfaces and see if one of their virtual interface
|
|
||||||
* names matches the master.
|
|
||||||
*/
|
|
||||||
connections = nm_manager_get_activatable_connections (self);
|
|
||||||
for (iter = connections; iter && !master_connection; iter = g_slist_next (iter)) {
|
|
||||||
NMSettingsConnection *candidate = iter->data;
|
|
||||||
char *vname;
|
|
||||||
|
|
||||||
vname = get_virtual_iface_name (self, NM_CONNECTION (candidate), NULL, NULL);
|
|
||||||
if (g_strcmp0 (master, vname) == 0 && is_compatible_with_slave (NM_CONNECTION (candidate), connection))
|
|
||||||
master_connection = candidate;
|
|
||||||
g_free (vname);
|
|
||||||
}
|
|
||||||
g_slist_free (connections);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2333,7 +2337,7 @@ ensure_master_active_connection (NMManager *self,
|
|||||||
/* If the device is disconnected, find a compatible connection and
|
/* If the device is disconnected, find a compatible connection and
|
||||||
* activate it on the device.
|
* activate it on the device.
|
||||||
*/
|
*/
|
||||||
if (master_state == NM_DEVICE_STATE_DISCONNECTED) {
|
if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
|
||||||
GSList *connections;
|
GSList *connections;
|
||||||
|
|
||||||
g_assert (master_connection == NULL);
|
g_assert (master_connection == NULL);
|
||||||
@@ -2394,9 +2398,11 @@ ensure_master_active_connection (NMManager *self,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
found_device = TRUE;
|
found_device = TRUE;
|
||||||
|
if (!nm_device_is_software (candidate)) {
|
||||||
master_state = nm_device_get_state (candidate);
|
master_state = nm_device_get_state (candidate);
|
||||||
if (master_state != NM_DEVICE_STATE_DISCONNECTED)
|
if (nm_device_is_real (candidate) && master_state != NM_DEVICE_STATE_DISCONNECTED)
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
master_ac = nm_manager_activate_connection (self,
|
master_ac = nm_manager_activate_connection (self,
|
||||||
master_connection,
|
master_connection,
|
||||||
@@ -2683,6 +2689,17 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create any backing resources the device needs */
|
||||||
|
if (!nm_device_is_real (device)) {
|
||||||
|
NMDevice *parent;
|
||||||
|
|
||||||
|
parent = find_parent_device_for_connection (self, (NMConnection *) connection);
|
||||||
|
if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
|
||||||
|
g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to find the master connection/device if the connection has a dependency */
|
/* Try to find the master connection/device if the connection has a dependency */
|
||||||
if (!find_master (self, applied, device,
|
if (!find_master (self, applied, device,
|
||||||
&master_connection, &master_device, &master_ac,
|
&master_connection, &master_device, &master_ac,
|
||||||
@@ -3086,7 +3103,7 @@ validate_activation_request (NMManager *self,
|
|||||||
if (!iface)
|
if (!iface)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
device = find_device_by_ip_iface (self, iface);
|
device = find_device_by_iface (self, iface);
|
||||||
g_free (iface);
|
g_free (iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4209,6 +4226,7 @@ gboolean
|
|||||||
nm_manager_start (NMManager *self, GError **error)
|
nm_manager_start (NMManager *self, GError **error)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
|
GSList *iter, *connections;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!nm_settings_start (priv->settings, error))
|
if (!nm_settings_start (priv->settings, error))
|
||||||
@@ -4256,11 +4274,14 @@ nm_manager_start (NMManager *self, GError **error)
|
|||||||
/* Load VPN plugins */
|
/* Load VPN plugins */
|
||||||
priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
|
priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
|
||||||
|
|
||||||
/*
|
/* Connections added before the manager is started do not emit
|
||||||
* Connections added before the manager is started do not emit
|
|
||||||
* connection-added signals thus devices have to be created manually.
|
* connection-added signals thus devices have to be created manually.
|
||||||
*/
|
*/
|
||||||
system_create_virtual_devices (self);
|
nm_log_dbg (LOGD_CORE, "creating virtual devices...");
|
||||||
|
connections = nm_settings_get_connections (priv->settings);
|
||||||
|
for (iter = connections; iter; iter = iter->next)
|
||||||
|
connection_added (priv->settings, NM_CONNECTION (iter->data), self);
|
||||||
|
g_slist_free (connections);
|
||||||
|
|
||||||
priv->devices_inited = TRUE;
|
priv->devices_inited = TRUE;
|
||||||
|
|
||||||
@@ -5067,6 +5088,12 @@ nm_manager_init (NMManager *manager)
|
|||||||
priv->metered = NM_METERED_UNKNOWN;
|
priv->metered = NM_METERED_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
device_is_real (GObject *device, gpointer user_data)
|
||||||
|
{
|
||||||
|
return nm_device_is_real (NM_DEVICE (device));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_property (GObject *object, guint prop_id,
|
get_property (GObject *object, guint prop_id,
|
||||||
GValue *value, GParamSpec *pspec)
|
GValue *value, GParamSpec *pspec)
|
||||||
@@ -5139,7 +5166,7 @@ get_property (GObject *object, guint prop_id,
|
|||||||
g_value_set_boolean (value, priv->sleeping);
|
g_value_set_boolean (value, priv->sleeping);
|
||||||
break;
|
break;
|
||||||
case PROP_DEVICES:
|
case PROP_DEVICES:
|
||||||
nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
|
nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
|
||||||
break;
|
break;
|
||||||
case PROP_METERED:
|
case PROP_METERED:
|
||||||
g_value_set_uint (value, priv->metered);
|
g_value_set_uint (value, priv->metered);
|
||||||
|
Reference in New Issue
Block a user