diff options
-rw-r--r-- | include/linux/kobject.h | 11 | ||||
-rw-r--r-- | lib/kobject_uevent.c | 44 |
2 files changed, 36 insertions, 19 deletions
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index d1c8d28fa92e..76538fcf2c4e 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -265,8 +265,8 @@ extern int __must_check subsys_create_file(struct subsystem * , | |||
265 | struct subsys_attribute *); | 265 | struct subsys_attribute *); |
266 | 266 | ||
267 | #if defined(CONFIG_HOTPLUG) | 267 | #if defined(CONFIG_HOTPLUG) |
268 | void kobject_uevent(struct kobject *kobj, enum kobject_action action); | 268 | int kobject_uevent(struct kobject *kobj, enum kobject_action action); |
269 | void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | 269 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
270 | char *envp[]); | 270 | char *envp[]); |
271 | 271 | ||
272 | int add_uevent_var(char **envp, int num_envp, int *cur_index, | 272 | int add_uevent_var(char **envp, int num_envp, int *cur_index, |
@@ -274,11 +274,12 @@ int add_uevent_var(char **envp, int num_envp, int *cur_index, | |||
274 | const char *format, ...) | 274 | const char *format, ...) |
275 | __attribute__((format (printf, 7, 8))); | 275 | __attribute__((format (printf, 7, 8))); |
276 | #else | 276 | #else |
277 | static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { } | 277 | static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action) |
278 | static inline void kobject_uevent_env(struct kobject *kobj, | 278 | { return 0; } |
279 | static inline int kobject_uevent_env(struct kobject *kobj, | ||
279 | enum kobject_action action, | 280 | enum kobject_action action, |
280 | char *envp[]) | 281 | char *envp[]) |
281 | { } | 282 | { return 0; } |
282 | 283 | ||
283 | static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, | 284 | static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, |
284 | char *buffer, int buffer_size, int *cur_len, | 285 | char *buffer, int buffer_size, int *cur_len, |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index a1922765ff31..84272ed77f03 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -63,8 +63,11 @@ static char *action_to_string(enum kobject_action action) | |||
63 | * @action: action that is happening (usually KOBJ_MOVE) | 63 | * @action: action that is happening (usually KOBJ_MOVE) |
64 | * @kobj: struct kobject that the action is happening to | 64 | * @kobj: struct kobject that the action is happening to |
65 | * @envp_ext: pointer to environmental data | 65 | * @envp_ext: pointer to environmental data |
66 | * | ||
67 | * Returns 0 if kobject_uevent() is completed with success or the | ||
68 | * corresponding error when it fails. | ||
66 | */ | 69 | */ |
67 | void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | 70 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
68 | char *envp_ext[]) | 71 | char *envp_ext[]) |
69 | { | 72 | { |
70 | char **envp; | 73 | char **envp; |
@@ -79,14 +82,16 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
79 | u64 seq; | 82 | u64 seq; |
80 | char *seq_buff; | 83 | char *seq_buff; |
81 | int i = 0; | 84 | int i = 0; |
82 | int retval; | 85 | int retval = 0; |
83 | int j; | 86 | int j; |
84 | 87 | ||
85 | pr_debug("%s\n", __FUNCTION__); | 88 | pr_debug("%s\n", __FUNCTION__); |
86 | 89 | ||
87 | action_string = action_to_string(action); | 90 | action_string = action_to_string(action); |
88 | if (!action_string) | 91 | if (!action_string) { |
89 | return; | 92 | pr_debug("kobject attempted to send uevent without action_string!\n"); |
93 | return -EINVAL; | ||
94 | } | ||
90 | 95 | ||
91 | /* search the kset we belong to */ | 96 | /* search the kset we belong to */ |
92 | top_kobj = kobj; | 97 | top_kobj = kobj; |
@@ -95,31 +100,39 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
95 | top_kobj = top_kobj->parent; | 100 | top_kobj = top_kobj->parent; |
96 | } while (!top_kobj->kset && top_kobj->parent); | 101 | } while (!top_kobj->kset && top_kobj->parent); |
97 | } | 102 | } |
98 | if (!top_kobj->kset) | 103 | if (!top_kobj->kset) { |
99 | return; | 104 | pr_debug("kobject attempted to send uevent without kset!\n"); |
105 | return -EINVAL; | ||
106 | } | ||
100 | 107 | ||
101 | kset = top_kobj->kset; | 108 | kset = top_kobj->kset; |
102 | uevent_ops = kset->uevent_ops; | 109 | uevent_ops = kset->uevent_ops; |
103 | 110 | ||
104 | /* skip the event, if the filter returns zero. */ | 111 | /* skip the event, if the filter returns zero. */ |
105 | if (uevent_ops && uevent_ops->filter) | 112 | if (uevent_ops && uevent_ops->filter) |
106 | if (!uevent_ops->filter(kset, kobj)) | 113 | if (!uevent_ops->filter(kset, kobj)) { |
107 | return; | 114 | pr_debug("kobject filter function caused the event to drop!\n"); |
115 | return 0; | ||
116 | } | ||
108 | 117 | ||
109 | /* environment index */ | 118 | /* environment index */ |
110 | envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); | 119 | envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); |
111 | if (!envp) | 120 | if (!envp) |
112 | return; | 121 | return -ENOMEM; |
113 | 122 | ||
114 | /* environment values */ | 123 | /* environment values */ |
115 | buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL); | 124 | buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL); |
116 | if (!buffer) | 125 | if (!buffer) { |
126 | retval = -ENOMEM; | ||
117 | goto exit; | 127 | goto exit; |
128 | } | ||
118 | 129 | ||
119 | /* complete object path */ | 130 | /* complete object path */ |
120 | devpath = kobject_get_path(kobj, GFP_KERNEL); | 131 | devpath = kobject_get_path(kobj, GFP_KERNEL); |
121 | if (!devpath) | 132 | if (!devpath) { |
133 | retval = -ENOENT; | ||
122 | goto exit; | 134 | goto exit; |
135 | } | ||
123 | 136 | ||
124 | /* originating subsystem */ | 137 | /* originating subsystem */ |
125 | if (uevent_ops && uevent_ops->name) | 138 | if (uevent_ops && uevent_ops->name) |
@@ -204,7 +217,7 @@ exit: | |||
204 | kfree(devpath); | 217 | kfree(devpath); |
205 | kfree(buffer); | 218 | kfree(buffer); |
206 | kfree(envp); | 219 | kfree(envp); |
207 | return; | 220 | return retval; |
208 | } | 221 | } |
209 | 222 | ||
210 | EXPORT_SYMBOL_GPL(kobject_uevent_env); | 223 | EXPORT_SYMBOL_GPL(kobject_uevent_env); |
@@ -214,10 +227,13 @@ EXPORT_SYMBOL_GPL(kobject_uevent_env); | |||
214 | * | 227 | * |
215 | * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) | 228 | * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) |
216 | * @kobj: struct kobject that the action is happening to | 229 | * @kobj: struct kobject that the action is happening to |
230 | * | ||
231 | * Returns 0 if kobject_uevent() is completed with success or the | ||
232 | * corresponding error when it fails. | ||
217 | */ | 233 | */ |
218 | void kobject_uevent(struct kobject *kobj, enum kobject_action action) | 234 | int kobject_uevent(struct kobject *kobj, enum kobject_action action) |
219 | { | 235 | { |
220 | kobject_uevent_env(kobj, action, NULL); | 236 | return kobject_uevent_env(kobj, action, NULL); |
221 | } | 237 | } |
222 | 238 | ||
223 | EXPORT_SYMBOL_GPL(kobject_uevent); | 239 | EXPORT_SYMBOL_GPL(kobject_uevent); |