Re: [PATCH 1/2] Add CanWakeUp property to NMDevice



Hi,
Thank you for your feedback. Answers inside.

Le mercredi 12 octobre 2011 à 23:44 -0500, Dan Williams a écrit :
> On Wed, 2011-10-12 at 13:22 +0200, Jean Parpaillon wrote:
> > From: Jean Parpaillon <jean parpaillon free fr>
> 
> So what's the overall architecture here?  This is the implementation,
> clearly, but what goes into the device's virtual functions like
> can_wake_up() and prepare_wake_up()?
> 

I must admit that I sent this hoping to (re?)start a discussion on the
subject.
My understanding is the following:
- for ethernet (or ethernet-like) devices, there is a common interface
for wakeup capable devices. It mainly consist in enable/disable wakeup
and, for some devices, setting a 'secret'
- this interface have been (partly) generalized with the ACPI syfs
interface. Each (capable) device has a wakeup file in his sysfs
structure in where you can write enable/disable and this is suppose to
deal with power during S3 ACPI state and maybe more (rfkill ?, network
not disconnecting when calling kernel halt() ?) ?

My developments were stopped when I found that my laptop BIOS does not
support powering up mini PCIe device when in S3 state, as it was
supposed to be the case (thanks lenovo ;) )

So, in a first time, I needed to have this property to ensure
NetworkManager is not disconnecting the device when sleeping.
prepare_wakeup(), in my thoughts, must prepare the device for waking up
(!), which means, for instance, setting the secret for waking up. But
this is based on the device I use, which is ericsson F5521gw.
Nevertheless, I think that this architecture is pretty generic, as it is
also used by ethtool.

Of course, CanWakeUp should be consistent with ACPI wakeup property in
sysfs and prepare_wakeup() should just call a generic interface in the
kernel... which exists only in the (old ?) ethtool interface.


Does it make sense for you ? For what you can see, I have still a lot of
questions but I am really interested in discussing this subject to
provide a NM "standardized" way of dealing with wow.

> Also would be good to pull Matthew Garrett in here; we've had
> discussions about WOL/WOWLAN before.
> 

Sure.

> Dan
> 

Best regards,
Jean 

> > ---
> >  introspection/nm-device.xml |    5 ++++
> >  libnm-glib/nm-device.c      |   48 +++++++++++++++++++++++++++++++++++++++++++
> >  libnm-glib/nm-device.h      |    2 +
> >  src/nm-device-interface.c   |    7 ++++++
> >  src/nm-device-interface.h   |    2 +
> >  src/nm-device.c             |   23 ++++++++++++++++++++
> >  src/nm-device.h             |    4 +++
> >  7 files changed, 91 insertions(+), 0 deletions(-)
> > 
> > diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml
> > index 5fdda96..2e29bb4 100644
> > --- a/introspection/nm-device.xml
> > +++ b/introspection/nm-device.xml
> > @@ -97,6 +97,11 @@
> >          The general type of the network device; ie Ethernet, WiFi, etc.
> >        </tp:docstring>
> >      </property>
> > +    <property name="CanWakeUp" type="b" access="readwrite" >
> > +      <tp:docstring>
> > +        If TRUE, the device can wake up the host when sleeping.
> > +      </tp:docstring>
> > +    </property>
> >  
> >      <method name="Disconnect">
> >        <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_disconnect"/>
> > diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
> > index f06c1e4..9b832d3 100644
> > --- a/libnm-glib/nm-device.c
> > +++ b/libnm-glib/nm-device.c
> > @@ -55,6 +55,7 @@ typedef struct {
> >  	NMDeviceCapabilities capabilities;
> >  	gboolean managed;
> >  	gboolean firmware_missing;
> > +	gboolean can_wake_up;
> >  	NMIP4Config *ip4_config;
> >  	gboolean got_ip4_config;
> >  	NMDHCP4Config *dhcp4_config;
> > @@ -81,6 +82,7 @@ enum {
> >  	PROP_CAPABILITIES,
> >  	PROP_MANAGED,
> >  	PROP_FIRMWARE_MISSING,
> > +	PROP_CAN_WAKE_UP,
> >  	PROP_IP4_CONFIG,
> >  	PROP_DHCP4_CONFIG,
> >  	PROP_IP6_CONFIG,
> > @@ -304,6 +306,7 @@ register_for_property_changed (NMDevice *device)
> >  		{ NM_DEVICE_CAPABILITIES,     _nm_object_demarshal_generic, &priv->capabilities },
> >  		{ NM_DEVICE_MANAGED,          _nm_object_demarshal_generic, &priv->managed },
> >  		{ NM_DEVICE_FIRMWARE_MISSING, _nm_object_demarshal_generic, &priv->firmware_missing },
> > +		{ NM_DEVICE_CAN_WAKE_UP,      _nm_object_demarshal_generic, &priv->can_wake_up },
> >  		{ NM_DEVICE_IP4_CONFIG,       demarshal_ip4_config,         &priv->ip4_config },
> >  		{ NM_DEVICE_DHCP4_CONFIG,     demarshal_dhcp4_config,       &priv->dhcp4_config },
> >  		{ NM_DEVICE_IP6_CONFIG,       demarshal_ip6_config,         &priv->ip6_config },
> > @@ -452,6 +455,9 @@ get_property (GObject *object,
> >  	case PROP_FIRMWARE_MISSING:
> >  		g_value_set_boolean (value, nm_device_get_firmware_missing (device));
> >  		break;
> > +	case PROP_CAN_WAKE_UP:
> > +		g_value_set_boolean (value, nm_device_get_can_wake_up (device));
> > +		break;
> >  	case PROP_IP4_CONFIG:
> >  		g_value_set_object (value, nm_device_get_ip4_config (device));
> >  		break;
> > @@ -496,6 +502,9 @@ set_property (GObject *object,
> >  		/* Construct only */
> >  		priv->device_type = g_value_get_uint (value);
> >  		break;
> > +	case PROP_CAN_WAKE_UP:
> > +		priv->can_wake_up = g_value_get_boolean (value);
> > +		break;
> >  	default:
> >  		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> >  		break;
> > @@ -629,6 +638,19 @@ nm_device_class_init (NMDeviceClass *device_class)
> >  						  G_PARAM_READABLE));
> >  
> >  	/**
> > +	 * NMDevice:can-wake-up:
> > +	 *
> > +	 * When %TRUE indicates the device can be used to wake up the machine.
> > +	 **/
> > +	g_object_class_install_property
> > +		(object_class, PROP_CAN_WAKE_UP,
> > +		 g_param_spec_boolean (NM_DEVICE_CAN_WAKE_UP,
> > +							   "CanWakeUp",
> > +							   "Device can WakeUp",
> > +							   FALSE,
> > +							   G_PARAM_READWRITE));
> > +
> > +	/**
> >  	 * NMDevice:ip4-config:
> >  	 *
> >  	 * The #NMIP4Config of the device.
> > @@ -1036,6 +1058,32 @@ nm_device_get_firmware_missing (NMDevice *device)
> >  }
> >  
> >  /**
> > + * nm_device_get_can_wake_up:
> > + * @device: a #NMDevice
> > + *
> > + * Indicates that the device can be used to wake up the machine
> > + *
> > + * Returns: %TRUE if the device can be used to wake up the machine.
> > + **/
> > +gboolean
> > +nm_device_get_can_wake_up (NMDevice *device)
> > +{
> > +	NMDevicePrivate *priv;
> > +
> > +	g_return_val_if_fail (NM_IS_DEVICE (device), 0);
> > +
> > +	priv = NM_DEVICE_GET_PRIVATE (device);
> > +	if (!priv->can_wake_up) {
> > +		priv->can_wake_up = _nm_object_get_boolean_property (NM_OBJECT (device),
> > +															 NM_DBUS_INTERFACE_DEVICE,
> > +															 "CanWakeUp",
> > +															 NULL);
> > +	}
> > +
> > +	return priv->can_wake_up;
> > +}
> > +
> > +/**
> >   * nm_device_get_ip4_config:
> >   * @device: a #NMDevice
> >   *
> > diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h
> > index e21e71b..df89869 100644
> > --- a/libnm-glib/nm-device.h
> > +++ b/libnm-glib/nm-device.h
> > @@ -53,6 +53,7 @@ G_BEGIN_DECLS
> >  #define NM_DEVICE_CAPABILITIES "capabilities"
> >  #define NM_DEVICE_MANAGED "managed"
> >  #define NM_DEVICE_FIRMWARE_MISSING "firmware-missing"
> > +#define NM_DEVICE_CAN_WAKE_UP "can-wake-up"
> >  #define NM_DEVICE_IP4_CONFIG "ip4-config"
> >  #define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
> >  #define NM_DEVICE_IP6_CONFIG "ip6-config"
> > @@ -99,6 +100,7 @@ const char *         nm_device_get_driver           (NMDevice *device);
> >  NMDeviceCapabilities nm_device_get_capabilities     (NMDevice *device);
> >  gboolean             nm_device_get_managed          (NMDevice *device);
> >  gboolean             nm_device_get_firmware_missing (NMDevice *device);
> > +gboolean             nm_device_get_can_wake_up      (NMDevice *device);
> >  NMIP4Config *        nm_device_get_ip4_config       (NMDevice *device);
> >  NMDHCP4Config *      nm_device_get_dhcp4_config     (NMDevice *device);
> >  NMIP6Config *        nm_device_get_ip6_config       (NMDevice *device);
> > diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c
> > index fb471f5..f1d6d7f 100644
> > --- a/src/nm-device-interface.c
> > +++ b/src/nm-device-interface.c
> > @@ -195,6 +195,13 @@ nm_device_interface_init (gpointer g_iface)
> >  	                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
> >  
> >  	g_object_interface_install_property
> > +		(g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_CAN_WAKE_UP,
> > +										"CanWakeUp",
> > +										"Can wake up machine",
> > +										FALSE,
> > +										G_PARAM_READWRITE));
> > +
> > +	g_object_interface_install_property
> >  		(g_iface,
> >  		 g_param_spec_string (NM_DEVICE_INTERFACE_TYPE_DESC,
> >  							  "Type Description",
> > diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h
> > index 560cdfe..0c73001 100644
> > --- a/src/nm-device-interface.h
> > +++ b/src/nm-device-interface.h
> > @@ -62,6 +62,7 @@ typedef enum
> >  #define NM_DEVICE_INTERFACE_DEVICE_TYPE      "device-type" /* ugh */
> >  #define NM_DEVICE_INTERFACE_MANAGED          "managed"
> >  #define NM_DEVICE_INTERFACE_FIRMWARE_MISSING "firmware-missing"
> > +#define NM_DEVICE_INTERFACE_CAN_WAKE_UP      "can-wake-up"
> >  #define NM_DEVICE_INTERFACE_TYPE_DESC        "type-desc"    /* Internal only */
> >  #define NM_DEVICE_INTERFACE_RFKILL_TYPE      "rfkill-type"  /* Internal only */
> >  #define NM_DEVICE_INTERFACE_IFINDEX          "ifindex"      /* Internal only */
> > @@ -84,6 +85,7 @@ typedef enum {
> >  	NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
> >  	NM_DEVICE_INTERFACE_PROP_MANAGED,
> >  	NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING,
> > +	NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP,
> >  	NM_DEVICE_INTERFACE_PROP_TYPE_DESC,
> >  	NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE,
> >  	NM_DEVICE_INTERFACE_PROP_IFINDEX,
> > diff --git a/src/nm-device.c b/src/nm-device.c
> > index 559606c..31a73c1 100644
> > --- a/src/nm-device.c
> > +++ b/src/nm-device.c
> > @@ -96,6 +96,7 @@ typedef struct {
> >  	gboolean      managed; /* whether managed by NM or not */
> >  	RfKillType    rfkill_type;
> >  	gboolean      firmware_missing;
> > +	gboolean      can_wake_up;
> >  
> >  	guint32         ip4_address;
> >  
> > @@ -2985,6 +2986,18 @@ nm_device_can_interrupt_activation (NMDevice *self)
> >  	return interrupt;
> >  }
> >  
> > +gboolean
> > +nm_device_can_wake_up (NMDevice *self)
> > +{
> > +	gboolean wake_up = FALSE;
> > +
> > +	g_return_val_if_fail (self != NULL, FALSE);
> > +
> > +	if (NM_DEVICE_GET_CLASS (self)->can_wake_up)
> > +		wake_up = NM_DEVICE_GET_CLASS (self)->can_wake_up (self);
> > +	return wake_up;
> > +}
> > +
> >  /* IP Configuration stuff */
> >  
> >  NMDHCP4Config *
> > @@ -3431,6 +3444,9 @@ set_property (GObject *object, guint prop_id,
> >  	case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING:
> >  		priv->firmware_missing = g_value_get_boolean (value);
> >  		break;
> > +	case NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP:
> > +		priv->can_wake_up = g_value_get_boolean (value);
> > +		break;
> >  	case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE:
> >  		g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN);
> >  		priv->type = g_value_get_uint (value);
> > @@ -3531,6 +3547,9 @@ get_property (GObject *object, guint prop_id,
> >  	case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING:
> >  		g_value_set_boolean (value, priv->firmware_missing);
> >  		break;
> > +	case NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP:
> > +		g_value_set_boolean (value, priv->can_wake_up);
> > +		break;
> >  	case NM_DEVICE_INTERFACE_PROP_TYPE_DESC:
> >  		g_value_set_string (value, priv->type_desc);
> >  		break;
> > @@ -3636,6 +3655,10 @@ nm_device_class_init (NMDeviceClass *klass)
> >  									  NM_DEVICE_INTERFACE_FIRMWARE_MISSING);
> >  
> >  	g_object_class_override_property (object_class,
> > +									  NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP,
> > +									  NM_DEVICE_INTERFACE_CAN_WAKE_UP);
> > +
> > +	g_object_class_override_property (object_class,
> >  									  NM_DEVICE_INTERFACE_PROP_TYPE_DESC,
> >  									  NM_DEVICE_INTERFACE_TYPE_DESC);
> >  
> > diff --git a/src/nm-device.h b/src/nm-device.h
> > index 1d080ed..b7273de 100644
> > --- a/src/nm-device.h
> > +++ b/src/nm-device.h
> > @@ -118,6 +118,9 @@ typedef struct {
> >  
> >  	gboolean		(* can_interrupt_activation)		(NMDevice *self);
> >  
> > +	/* true if device must be kept on when sleeping */
> > +	gboolean		(* can_wake_up)		(NMDevice *self);
> > +
> >  	gboolean        (* spec_match_list)     (NMDevice *self, const GSList *specs);
> >  
> >  	NMConnection *  (* connection_match_config) (NMDevice *self, const GSList *connections);
> > @@ -176,6 +179,7 @@ void			nm_device_activate_schedule_stage4_ip6_config_get		(NMDevice *device);
> >  void			nm_device_activate_schedule_stage4_ip6_config_timeout	(NMDevice *device);
> >  gboolean		nm_device_is_activating		(NMDevice *dev);
> >  gboolean		nm_device_can_interrupt_activation		(NMDevice *self);
> > +gboolean		nm_device_can_wake_up		(NMDevice *self);
> >  gboolean		nm_device_autoconnect_allowed	(NMDevice *self);
> >  
> >  NMDeviceState nm_device_get_state (NMDevice *device);
> 
> 
> 


-- 
Jean Parpaillon
Pulse2 project leader

Mandriva SA - http://mandriva.com
Rennes - FR
Phone: +33 6 30 10 92 86
email: jparpaillon mandriva com
jabber: jean parpaillon gmail com
skype: jean.parpaillon

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]