diff options
author | Antonio Quartulli <ordex@autistici.org> | 2011-04-26 20:26:01 +0400 |
---|---|---|
committer | Sven Eckelmann <sven@narfation.org> | 2011-06-20 13:37:33 +0400 |
commit | c6bda689c2c94788e1e567463ce861d1f135857f (patch) | |
tree | b2876d0b57ee5de081cf612420644e39dc4b78c0 /net/batman-adv/bat_sysfs.c | |
parent | 7683fdc1e88644ee8108a1f33faba80545f0024d (diff) | |
download | linux-c6bda689c2c94788e1e567463ce861d1f135857f.tar.xz |
batman-adv: add wrapper function to throw uevent in userspace
Using throw_uevent() is now possible to trigger uevent signal that can
be recognised in userspace. Uevents will be triggered through the
/devices/virtual/net/{MESH_IFACE} kobject.
A triggered uevent has three properties:
- type: the event class. Who generates the event (only 'gw' is currently
defined). Corresponds to the BATTYPE uevent variable.
- action: the associated action with the event ('add'/'change'/'del' are
currently defined). Corresponds to the BATACTION uevent variable.
- data: any useful data for the userspace. Corresponds to the BATDATA
uevent variable.
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/bat_sysfs.c')
-rw-r--r-- | net/batman-adv/bat_sysfs.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 63738ec10511..cd15deba60a1 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -40,6 +40,20 @@ static struct bat_priv *kobj_to_batpriv(struct kobject *obj) return netdev_priv(net_dev); } +#define UEV_TYPE_VAR "BATTYPE=" +#define UEV_ACTION_VAR "BATACTION=" +#define UEV_DATA_VAR "BATDATA=" + +static char *uev_action_str[] = { + "add", + "del", + "change" +}; + +static char *uev_type_str[] = { + "gw" +}; + /* Use this, if you have customized show and store functions */ #define BAT_ATTR(_name, _mode, _show, _store) \ struct bat_attribute bat_attr_##_name = { \ @@ -601,3 +615,60 @@ void sysfs_del_hardif(struct kobject **hardif_obj) kobject_put(*hardif_obj); *hardif_obj = NULL; } + +int throw_uevent(struct bat_priv *bat_priv, enum uev_type type, + enum uev_action action, const char *data) +{ + int ret = -1; + struct hard_iface *primary_if = NULL; + struct kobject *bat_kobj; + char *uevent_env[4] = { NULL, NULL, NULL, NULL }; + + primary_if = primary_if_get_selected(bat_priv); + if (!primary_if) + goto out; + + bat_kobj = &primary_if->soft_iface->dev.kobj; + + uevent_env[0] = kmalloc(strlen(UEV_TYPE_VAR) + + strlen(uev_type_str[type]) + 1, + GFP_ATOMIC); + if (!uevent_env[0]) + goto out; + + sprintf(uevent_env[0], "%s%s", UEV_TYPE_VAR, uev_type_str[type]); + + uevent_env[1] = kmalloc(strlen(UEV_ACTION_VAR) + + strlen(uev_action_str[action]) + 1, + GFP_ATOMIC); + if (!uevent_env[1]) + goto out; + + sprintf(uevent_env[1], "%s%s", UEV_ACTION_VAR, uev_action_str[action]); + + /* If the event is DEL, ignore the data field */ + if (action != UEV_DEL) { + uevent_env[2] = kmalloc(strlen(UEV_DATA_VAR) + + strlen(data) + 1, GFP_ATOMIC); + if (!uevent_env[2]) + goto out; + + sprintf(uevent_env[2], "%s%s", UEV_DATA_VAR, data); + } + + ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env); +out: + kfree(uevent_env[0]); + kfree(uevent_env[1]); + kfree(uevent_env[2]); + + if (primary_if) + hardif_free_ref(primary_if); + + if (ret) + bat_dbg(DBG_BATMAN, bat_priv, "Impossible to send " + "uevent for (%s,%s,%s) event (err: %d)\n", + uev_type_str[type], uev_action_str[action], + (action == UEV_DEL ? "NULL" : data), ret); + return ret; +} |