wifi: don't fail construction of NMDeviceWifi in constructor

We cannot abort the construction of a GLib object instance
like we did for NMDeviceWifi and NMDeviceOlpcMesh when
nm_platform_wifi_get_capabilities() failed.

Instead, check the capabilities first (in the factory method)
and only create the object instance when the device can be handled.

https://bugzilla.gnome.org/show_bug.cgi?id=760154
This commit is contained in:
Thomas Haller 2016-01-06 21:54:23 +01:00
parent e2e22eb574
commit 044de4cea2
4 changed files with 40 additions and 33 deletions

View file

@ -440,22 +440,14 @@ constructor (GType type,
GObjectClass *klass;
NMDeviceOlpcMesh *self;
NMDeviceOlpcMeshPrivate *priv;
NMDeviceWifiCapabilities caps;
klass = G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class);
object = klass->constructor (type, n_construct_params, construct_params);
if (!object)
return NULL;
g_return_val_if_fail (object, NULL);
self = NM_DEVICE_OLPC_MESH (object);
priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
if (!nm_platform_wifi_get_capabilities (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), &caps)) {
_LOGW (LOGD_HW | LOGD_OLPC, "failed to initialize WiFi driver");
g_object_unref (object);
return NULL;
}
priv->manager = g_object_ref (nm_manager_get ());
g_signal_connect (priv->manager, "device-added", G_CALLBACK (device_added_cb), self);

View file

@ -185,20 +185,11 @@ constructor (GType type,
klass = G_OBJECT_CLASS (nm_device_wifi_parent_class);
object = klass->constructor (type, n_construct_params, construct_params);
if (!object)
return NULL;
g_return_val_if_fail (object, NULL);
self = NM_DEVICE_WIFI (object);
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
if (!nm_platform_wifi_get_capabilities (NM_PLATFORM_GET,
nm_device_get_ifindex (NM_DEVICE (self)),
&priv->capabilities)) {
_LOGW (LOGD_HW | LOGD_WIFI, "failed to initialize WiFi driver");
g_object_unref (object);
return NULL;
}
if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP)
_LOGI (LOGD_HW | LOGD_WIFI, "driver supports Access Point (AP) mode");
@ -2905,15 +2896,16 @@ set_enabled (NMDevice *device, gboolean enabled)
/********************************************************************/
NMDevice *
nm_device_wifi_new (const char *iface)
nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIFI,
NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "802.11 WiFi",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI,
NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
NULL);
return g_object_new (NM_TYPE_DEVICE_WIFI,
NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "802.11 WiFi",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI,
NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
NM_DEVICE_WIFI_CAPABILITIES, (guint) capabilities,
NULL);
}
static void
@ -3004,7 +2996,18 @@ static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
NMDeviceWifi *device = NM_DEVICE_WIFI (object);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
switch (prop_id) {
case PROP_CAPABILITIES:
/* construct-only */
priv->capabilities = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
@ -3088,7 +3091,8 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
(object_class, PROP_CAPABILITIES,
g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "",
0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE,
G_PARAM_READABLE |
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property

View file

@ -73,7 +73,7 @@ struct _NMDeviceWifiClass
GType nm_device_wifi_get_type (void);
NMDevice * nm_device_wifi_new (const char *iface);
NMDevice * nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities);
G_END_DECLS

View file

@ -65,13 +65,24 @@ create_device (NMDeviceFactory *factory,
NMConnection *connection,
gboolean *out_ignore)
{
NMDeviceWifiCapabilities capabilities;
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (plink != NULL, NULL);
g_return_val_if_fail (g_strcmp0 (iface, plink->name) == 0, NULL);
g_return_val_if_fail (NM_IN_SET (plink->type, NM_LINK_TYPE_WIFI, NM_LINK_TYPE_OLPC_MESH), NULL);
if (!nm_platform_wifi_get_capabilities (NM_PLATFORM_GET,
plink->ifindex,
&capabilities)) {
nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s) failed to initialize Wi-Fi driver for ifindex %d", iface, plink->ifindex);
return NULL;
}
if (plink->type == NM_LINK_TYPE_WIFI)
return nm_device_wifi_new (iface);
else if (plink->type == NM_LINK_TYPE_OLPC_MESH)
return nm_device_wifi_new (iface, capabilities);
else
return nm_device_olpc_mesh_new (iface);
g_return_val_if_reached (NULL);
}
NM_DEVICE_FACTORY_DECLARE_TYPES (