Commit 60a96a59 authored by Kay Sievers's avatar Kay Sievers Committed by Greg Kroah-Hartman

Driver core: accept all valid action-strings in uevent-trigger

This allows the uevent file to handle any type of uevent action to be
triggered by userspace instead of just the "add" uevent.
Signed-off-by: default avatarKay Sievers <kay.sievers@vrfy.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent a6bb340d
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "base.h" #include "base.h"
#include "power/power.h" #include "power/power.h"
extern const char *kobject_actions[];
int (*platform_notify)(struct device * dev) = NULL; int (*platform_notify)(struct device * dev) = NULL;
int (*platform_notify_remove)(struct device * dev) = NULL; int (*platform_notify_remove)(struct device * dev) = NULL;
...@@ -303,10 +305,25 @@ out: ...@@ -303,10 +305,25 @@ out:
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
if (memcmp(buf, "add", 3) != 0) size_t len = count;
enum kobject_action action;
if (len && buf[len-1] == '\n')
len--;
for (action = 0; action < KOBJ_MAX; action++) {
if (strncmp(kobject_actions[action], buf, len) != 0)
continue;
if (kobject_actions[action][len] != '\0')
continue;
kobject_uevent(&dev->kobj, action);
goto out;
}
dev_err(dev, "uevent: unsupported action-string; this will " dev_err(dev, "uevent: unsupported action-string; this will "
"be ignored in a future kernel version"); "be ignored in a future kernel version\n");
kobject_uevent(&dev->kobj, KOBJ_ADD); kobject_uevent(&dev->kobj, KOBJ_ADD);
out:
return count; return count;
} }
......
...@@ -36,15 +36,24 @@ extern char uevent_helper[]; ...@@ -36,15 +36,24 @@ extern char uevent_helper[];
/* counter to tag the uevent, read only except for the kobject core */ /* counter to tag the uevent, read only except for the kobject core */
extern u64 uevent_seqnum; extern u64 uevent_seqnum;
/* the actions here must match the proper string in lib/kobject_uevent.c */ /*
typedef int __bitwise kobject_action_t; * The actions here must match the index to the string array
* in lib/kobject_uevent.c
*
* Do not add new actions here without checking with the driver-core
* maintainers. Action strings are not meant to express subsystem
* or device specific properties. In most cases you want to send a
* kobject_uevent_env(kobj, KOBJ_CHANGE, env) with additional event
* specific variables added to the event environment.
*/
enum kobject_action { enum kobject_action {
KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */ KOBJ_ADD,
KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */ KOBJ_REMOVE,
KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */ KOBJ_CHANGE,
KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */ KOBJ_MOVE,
KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */ KOBJ_ONLINE,
KOBJ_MOVE = (__force kobject_action_t) 0x06, /* device move */ KOBJ_OFFLINE,
KOBJ_MAX
}; };
struct kobject { struct kobject {
......
...@@ -33,25 +33,15 @@ static DEFINE_SPINLOCK(sequence_lock); ...@@ -33,25 +33,15 @@ static DEFINE_SPINLOCK(sequence_lock);
static struct sock *uevent_sock; static struct sock *uevent_sock;
#endif #endif
static char *action_to_string(enum kobject_action action) /* the strings here must match the enum in include/linux/kobject.h */
{ const char *kobject_actions[] = {
switch (action) { "add",
case KOBJ_ADD: "remove",
return "add"; "change",
case KOBJ_REMOVE: "move",
return "remove"; "online",
case KOBJ_CHANGE: "offline",
return "change"; };
case KOBJ_OFFLINE:
return "offline";
case KOBJ_ONLINE:
return "online";
case KOBJ_MOVE:
return "move";
default:
return NULL;
}
}
/** /**
* kobject_uevent_env - send an uevent with environmental data * kobject_uevent_env - send an uevent with environmental data
...@@ -83,7 +73,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, ...@@ -83,7 +73,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
pr_debug("%s\n", __FUNCTION__); pr_debug("%s\n", __FUNCTION__);
action_string = action_to_string(action); action_string = kobject_actions[action];
if (!action_string) { if (!action_string) {
pr_debug("kobject attempted to send uevent without action_string!\n"); pr_debug("kobject attempted to send uevent without action_string!\n");
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment