]> git.karo-electronics.de Git - karo-tx-linux.git/blob - lib/kobject_uevent.c
backlight: pwm_bl: Enable PWM before switching regulator on
[karo-tx-linux.git] / lib / kobject_uevent.c
1 /*
2  * kernel userspace event delivery
3  *
4  * Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
5  * Copyright (C) 2004 Novell, Inc.  All rights reserved.
6  * Copyright (C) 2004 IBM, Inc. All rights reserved.
7  *
8  * Licensed under the GNU GPL v2.
9  *
10  * Authors:
11  *      Robert Love             <rml@novell.com>
12  *      Kay Sievers             <kay.sievers@vrfy.org>
13  *      Arjan van de Ven        <arjanv@redhat.com>
14  *      Greg Kroah-Hartman      <greg@kroah.com>
15  */
16
17 #include <linux/spinlock.h>
18 #include <linux/string.h>
19 #include <linux/kobject.h>
20 #include <linux/export.h>
21 #include <linux/kmod.h>
22 #include <linux/slab.h>
23 #include <linux/socket.h>
24 #include <linux/skbuff.h>
25 #include <linux/netlink.h>
26 #include <linux/uuid.h>
27 #include <linux/ctype.h>
28 #include <net/sock.h>
29 #include <net/net_namespace.h>
30
31
32 u64 uevent_seqnum;
33 #ifdef CONFIG_UEVENT_HELPER
34 char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
35 #endif
36 #ifdef CONFIG_NET
37 struct uevent_sock {
38         struct list_head list;
39         struct sock *sk;
40 };
41 static LIST_HEAD(uevent_sock_list);
42 #endif
43
44 /* This lock protects uevent_seqnum and uevent_sock_list */
45 static DEFINE_MUTEX(uevent_sock_mutex);
46
47 /* the strings here must match the enum in include/linux/kobject.h */
48 static const char *kobject_actions[] = {
49         [KOBJ_ADD] =            "add",
50         [KOBJ_REMOVE] =         "remove",
51         [KOBJ_CHANGE] =         "change",
52         [KOBJ_MOVE] =           "move",
53         [KOBJ_ONLINE] =         "online",
54         [KOBJ_OFFLINE] =        "offline",
55 };
56
57 static int kobject_action_type(const char *buf, size_t count,
58                                enum kobject_action *type,
59                                const char **args)
60 {
61         enum kobject_action action;
62         size_t count_first;
63         const char *args_start;
64         int ret = -EINVAL;
65
66         if (count && (buf[count-1] == '\n' || buf[count-1] == '\0'))
67                 count--;
68
69         if (!count)
70                 goto out;
71
72         args_start = strnchr(buf, count, ' ');
73         if (args_start) {
74                 count_first = args_start - buf;
75                 args_start = args_start + 1;
76         } else
77                 count_first = count;
78
79         for (action = 0; action < ARRAY_SIZE(kobject_actions); action++) {
80                 if (strncmp(kobject_actions[action], buf, count_first) != 0)
81                         continue;
82                 if (kobject_actions[action][count_first] != '\0')
83                         continue;
84                 if (args)
85                         *args = args_start;
86                 *type = action;
87                 ret = 0;
88                 break;
89         }
90 out:
91         return ret;
92 }
93
94 static const char *action_arg_word_end(const char *buf, const char *buf_end,
95                                        char delim)
96 {
97         const char *next = buf;
98
99         while (next <= buf_end && *next != delim)
100                 if (!isalnum(*next++))
101                         return NULL;
102
103         if (next == buf)
104                 return NULL;
105
106         return next;
107 }
108
109 static int kobject_action_args(const char *buf, size_t count,
110                                struct kobj_uevent_env **ret_env)
111 {
112         struct kobj_uevent_env *env = NULL;
113         const char *next, *buf_end, *key;
114         int key_len;
115         int r = -EINVAL;
116
117         if (count && (buf[count - 1] == '\n' || buf[count - 1] == '\0'))
118                 count--;
119
120         if (!count)
121                 return -EINVAL;
122
123         env = kzalloc(sizeof(*env), GFP_KERNEL);
124         if (!env)
125                 return -ENOMEM;
126
127         /* first arg is UUID */
128         if (count < UUID_STRING_LEN || !uuid_is_valid(buf) ||
129             add_uevent_var(env, "SYNTH_UUID=%.*s", UUID_STRING_LEN, buf))
130                 goto out;
131
132         /*
133          * the rest are custom environment variables in KEY=VALUE
134          * format with ' ' delimiter between each KEY=VALUE pair
135          */
136         next = buf + UUID_STRING_LEN;
137         buf_end = buf + count - 1;
138
139         while (next <= buf_end) {
140                 if (*next != ' ')
141                         goto out;
142
143                 /* skip the ' ', key must follow */
144                 key = ++next;
145                 if (key > buf_end)
146                         goto out;
147
148                 buf = next;
149                 next = action_arg_word_end(buf, buf_end, '=');
150                 if (!next || next > buf_end || *next != '=')
151                         goto out;
152                 key_len = next - buf;
153
154                 /* skip the '=', value must follow */
155                 if (++next > buf_end)
156                         goto out;
157
158                 buf = next;
159                 next = action_arg_word_end(buf, buf_end, ' ');
160                 if (!next)
161                         goto out;
162
163                 if (add_uevent_var(env, "SYNTH_ARG_%.*s=%.*s",
164                                    key_len, key, (int) (next - buf), buf))
165                         goto out;
166         }
167
168         r = 0;
169 out:
170         if (r)
171                 kfree(env);
172         else
173                 *ret_env = env;
174         return r;
175 }
176
177 /**
178  * kobject_synth_uevent - send synthetic uevent with arguments
179  *
180  * @kobj: struct kobject for which synthetic uevent is to be generated
181  * @buf: buffer containing action type and action args, newline is ignored
182  * @count: length of buffer
183  *
184  * Returns 0 if kobject_synthetic_uevent() is completed with success or the
185  * corresponding error when it fails.
186  */
187 int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count)
188 {
189         char *no_uuid_envp[] = { "SYNTH_UUID=0", NULL };
190         enum kobject_action action;
191         const char *action_args;
192         struct kobj_uevent_env *env;
193         const char *msg = NULL, *devpath;
194         int r;
195
196         r = kobject_action_type(buf, count, &action, &action_args);
197         if (r) {
198                 msg = "unknown uevent action string\n";
199                 goto out;
200         }
201
202         if (!action_args) {
203                 r = kobject_uevent_env(kobj, action, no_uuid_envp);
204                 goto out;
205         }
206
207         r = kobject_action_args(action_args,
208                                 count - (action_args - buf), &env);
209         if (r == -EINVAL) {
210                 msg = "incorrect uevent action arguments\n";
211                 goto out;
212         }
213
214         if (r)
215                 goto out;
216
217         r = kobject_uevent_env(kobj, action, env->envp);
218         kfree(env);
219 out:
220         if (r) {
221                 devpath = kobject_get_path(kobj, GFP_KERNEL);
222                 printk(KERN_WARNING "synth uevent: %s: %s",
223                        devpath ?: "unknown device",
224                        msg ?: "failed to send uevent");
225                 kfree(devpath);
226         }
227         return r;
228 }
229
230 #ifdef CONFIG_NET
231 static int kobj_bcast_filter(struct sock *dsk, struct sk_buff *skb, void *data)
232 {
233         struct kobject *kobj = data, *ksobj;
234         const struct kobj_ns_type_operations *ops;
235
236         ops = kobj_ns_ops(kobj);
237         if (!ops && kobj->kset) {
238                 ksobj = &kobj->kset->kobj;
239                 if (ksobj->parent != NULL)
240                         ops = kobj_ns_ops(ksobj->parent);
241         }
242
243         if (ops && ops->netlink_ns && kobj->ktype->namespace) {
244                 const void *sock_ns, *ns;
245                 ns = kobj->ktype->namespace(kobj);
246                 sock_ns = ops->netlink_ns(dsk);
247                 return sock_ns != ns;
248         }
249
250         return 0;
251 }
252 #endif
253
254 #ifdef CONFIG_UEVENT_HELPER
255 static int kobj_usermode_filter(struct kobject *kobj)
256 {
257         const struct kobj_ns_type_operations *ops;
258
259         ops = kobj_ns_ops(kobj);
260         if (ops) {
261                 const void *init_ns, *ns;
262                 ns = kobj->ktype->namespace(kobj);
263                 init_ns = ops->initial_ns();
264                 return ns != init_ns;
265         }
266
267         return 0;
268 }
269
270 static int init_uevent_argv(struct kobj_uevent_env *env, const char *subsystem)
271 {
272         int len;
273
274         len = strlcpy(&env->buf[env->buflen], subsystem,
275                       sizeof(env->buf) - env->buflen);
276         if (len >= (sizeof(env->buf) - env->buflen)) {
277                 WARN(1, KERN_ERR "init_uevent_argv: buffer size too small\n");
278                 return -ENOMEM;
279         }
280
281         env->argv[0] = uevent_helper;
282         env->argv[1] = &env->buf[env->buflen];
283         env->argv[2] = NULL;
284
285         env->buflen += len + 1;
286         return 0;
287 }
288
289 static void cleanup_uevent_env(struct subprocess_info *info)
290 {
291         kfree(info->data);
292 }
293 #endif
294
295 /**
296  * kobject_uevent_env - send an uevent with environmental data
297  *
298  * @kobj: struct kobject that the action is happening to
299  * @action: action that is happening
300  * @envp_ext: pointer to environmental data
301  *
302  * Returns 0 if kobject_uevent_env() is completed with success or the
303  * corresponding error when it fails.
304  */
305 int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
306                        char *envp_ext[])
307 {
308         struct kobj_uevent_env *env;
309         const char *action_string = kobject_actions[action];
310         const char *devpath = NULL;
311         const char *subsystem;
312         struct kobject *top_kobj;
313         struct kset *kset;
314         const struct kset_uevent_ops *uevent_ops;
315         int i = 0;
316         int retval = 0;
317 #ifdef CONFIG_NET
318         struct uevent_sock *ue_sk;
319 #endif
320
321         pr_debug("kobject: '%s' (%p): %s\n",
322                  kobject_name(kobj), kobj, __func__);
323
324         /* search the kset we belong to */
325         top_kobj = kobj;
326         while (!top_kobj->kset && top_kobj->parent)
327                 top_kobj = top_kobj->parent;
328
329         if (!top_kobj->kset) {
330                 pr_debug("kobject: '%s' (%p): %s: attempted to send uevent "
331                          "without kset!\n", kobject_name(kobj), kobj,
332                          __func__);
333                 return -EINVAL;
334         }
335
336         kset = top_kobj->kset;
337         uevent_ops = kset->uevent_ops;
338
339         /* skip the event, if uevent_suppress is set*/
340         if (kobj->uevent_suppress) {
341                 pr_debug("kobject: '%s' (%p): %s: uevent_suppress "
342                                  "caused the event to drop!\n",
343                                  kobject_name(kobj), kobj, __func__);
344                 return 0;
345         }
346         /* skip the event, if the filter returns zero. */
347         if (uevent_ops && uevent_ops->filter)
348                 if (!uevent_ops->filter(kset, kobj)) {
349                         pr_debug("kobject: '%s' (%p): %s: filter function "
350                                  "caused the event to drop!\n",
351                                  kobject_name(kobj), kobj, __func__);
352                         return 0;
353                 }
354
355         /* originating subsystem */
356         if (uevent_ops && uevent_ops->name)
357                 subsystem = uevent_ops->name(kset, kobj);
358         else
359                 subsystem = kobject_name(&kset->kobj);
360         if (!subsystem) {
361                 pr_debug("kobject: '%s' (%p): %s: unset subsystem caused the "
362                          "event to drop!\n", kobject_name(kobj), kobj,
363                          __func__);
364                 return 0;
365         }
366
367         /* environment buffer */
368         env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
369         if (!env)
370                 return -ENOMEM;
371
372         /* complete object path */
373         devpath = kobject_get_path(kobj, GFP_KERNEL);
374         if (!devpath) {
375                 retval = -ENOENT;
376                 goto exit;
377         }
378
379         /* default keys */
380         retval = add_uevent_var(env, "ACTION=%s", action_string);
381         if (retval)
382                 goto exit;
383         retval = add_uevent_var(env, "DEVPATH=%s", devpath);
384         if (retval)
385                 goto exit;
386         retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
387         if (retval)
388                 goto exit;
389
390         /* keys passed in from the caller */
391         if (envp_ext) {
392                 for (i = 0; envp_ext[i]; i++) {
393                         retval = add_uevent_var(env, "%s", envp_ext[i]);
394                         if (retval)
395                                 goto exit;
396                 }
397         }
398
399         /* let the kset specific function add its stuff */
400         if (uevent_ops && uevent_ops->uevent) {
401                 retval = uevent_ops->uevent(kset, kobj, env);
402                 if (retval) {
403                         pr_debug("kobject: '%s' (%p): %s: uevent() returned "
404                                  "%d\n", kobject_name(kobj), kobj,
405                                  __func__, retval);
406                         goto exit;
407                 }
408         }
409
410         /*
411          * Mark "add" and "remove" events in the object to ensure proper
412          * events to userspace during automatic cleanup. If the object did
413          * send an "add" event, "remove" will automatically generated by
414          * the core, if not already done by the caller.
415          */
416         if (action == KOBJ_ADD)
417                 kobj->state_add_uevent_sent = 1;
418         else if (action == KOBJ_REMOVE)
419                 kobj->state_remove_uevent_sent = 1;
420
421         mutex_lock(&uevent_sock_mutex);
422         /* we will send an event, so request a new sequence number */
423         retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
424         if (retval) {
425                 mutex_unlock(&uevent_sock_mutex);
426                 goto exit;
427         }
428
429 #if defined(CONFIG_NET)
430         /* send netlink message */
431         list_for_each_entry(ue_sk, &uevent_sock_list, list) {
432                 struct sock *uevent_sock = ue_sk->sk;
433                 struct sk_buff *skb;
434                 size_t len;
435
436                 if (!netlink_has_listeners(uevent_sock, 1))
437                         continue;
438
439                 /* allocate message with the maximum possible size */
440                 len = strlen(action_string) + strlen(devpath) + 2;
441                 skb = alloc_skb(len + env->buflen, GFP_KERNEL);
442                 if (skb) {
443                         char *scratch;
444
445                         /* add header */
446                         scratch = skb_put(skb, len);
447                         sprintf(scratch, "%s@%s", action_string, devpath);
448
449                         /* copy keys to our continuous event payload buffer */
450                         for (i = 0; i < env->envp_idx; i++) {
451                                 len = strlen(env->envp[i]) + 1;
452                                 scratch = skb_put(skb, len);
453                                 strcpy(scratch, env->envp[i]);
454                         }
455
456                         NETLINK_CB(skb).dst_group = 1;
457                         retval = netlink_broadcast_filtered(uevent_sock, skb,
458                                                             0, 1, GFP_KERNEL,
459                                                             kobj_bcast_filter,
460                                                             kobj);
461                         /* ENOBUFS should be handled in userspace */
462                         if (retval == -ENOBUFS || retval == -ESRCH)
463                                 retval = 0;
464                 } else
465                         retval = -ENOMEM;
466         }
467 #endif
468         mutex_unlock(&uevent_sock_mutex);
469
470 #ifdef CONFIG_UEVENT_HELPER
471         /* call uevent_helper, usually only enabled during early boot */
472         if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
473                 struct subprocess_info *info;
474
475                 retval = add_uevent_var(env, "HOME=/");
476                 if (retval)
477                         goto exit;
478                 retval = add_uevent_var(env,
479                                         "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
480                 if (retval)
481                         goto exit;
482                 retval = init_uevent_argv(env, subsystem);
483                 if (retval)
484                         goto exit;
485
486                 retval = -ENOMEM;
487                 info = call_usermodehelper_setup(env->argv[0], env->argv,
488                                                  env->envp, GFP_KERNEL,
489                                                  NULL, cleanup_uevent_env, env);
490                 if (info) {
491                         retval = call_usermodehelper_exec(info, UMH_NO_WAIT);
492                         env = NULL;     /* freed by cleanup_uevent_env */
493                 }
494         }
495 #endif
496
497 exit:
498         kfree(devpath);
499         kfree(env);
500         return retval;
501 }
502 EXPORT_SYMBOL_GPL(kobject_uevent_env);
503
504 /**
505  * kobject_uevent - notify userspace by sending an uevent
506  *
507  * @kobj: struct kobject that the action is happening to
508  * @action: action that is happening
509  *
510  * Returns 0 if kobject_uevent() is completed with success or the
511  * corresponding error when it fails.
512  */
513 int kobject_uevent(struct kobject *kobj, enum kobject_action action)
514 {
515         return kobject_uevent_env(kobj, action, NULL);
516 }
517 EXPORT_SYMBOL_GPL(kobject_uevent);
518
519 /**
520  * add_uevent_var - add key value string to the environment buffer
521  * @env: environment buffer structure
522  * @format: printf format for the key=value pair
523  *
524  * Returns 0 if environment variable was added successfully or -ENOMEM
525  * if no space was available.
526  */
527 int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
528 {
529         va_list args;
530         int len;
531
532         if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
533                 WARN(1, KERN_ERR "add_uevent_var: too many keys\n");
534                 return -ENOMEM;
535         }
536
537         va_start(args, format);
538         len = vsnprintf(&env->buf[env->buflen],
539                         sizeof(env->buf) - env->buflen,
540                         format, args);
541         va_end(args);
542
543         if (len >= (sizeof(env->buf) - env->buflen)) {
544                 WARN(1, KERN_ERR "add_uevent_var: buffer size too small\n");
545                 return -ENOMEM;
546         }
547
548         env->envp[env->envp_idx++] = &env->buf[env->buflen];
549         env->buflen += len + 1;
550         return 0;
551 }
552 EXPORT_SYMBOL_GPL(add_uevent_var);
553
554 #if defined(CONFIG_NET)
555 static int uevent_net_init(struct net *net)
556 {
557         struct uevent_sock *ue_sk;
558         struct netlink_kernel_cfg cfg = {
559                 .groups = 1,
560                 .flags  = NL_CFG_F_NONROOT_RECV,
561         };
562
563         ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
564         if (!ue_sk)
565                 return -ENOMEM;
566
567         ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, &cfg);
568         if (!ue_sk->sk) {
569                 printk(KERN_ERR
570                        "kobject_uevent: unable to create netlink socket!\n");
571                 kfree(ue_sk);
572                 return -ENODEV;
573         }
574         mutex_lock(&uevent_sock_mutex);
575         list_add_tail(&ue_sk->list, &uevent_sock_list);
576         mutex_unlock(&uevent_sock_mutex);
577         return 0;
578 }
579
580 static void uevent_net_exit(struct net *net)
581 {
582         struct uevent_sock *ue_sk;
583
584         mutex_lock(&uevent_sock_mutex);
585         list_for_each_entry(ue_sk, &uevent_sock_list, list) {
586                 if (sock_net(ue_sk->sk) == net)
587                         goto found;
588         }
589         mutex_unlock(&uevent_sock_mutex);
590         return;
591
592 found:
593         list_del(&ue_sk->list);
594         mutex_unlock(&uevent_sock_mutex);
595
596         netlink_kernel_release(ue_sk->sk);
597         kfree(ue_sk);
598 }
599
600 static struct pernet_operations uevent_net_ops = {
601         .init   = uevent_net_init,
602         .exit   = uevent_net_exit,
603 };
604
605 static int __init kobject_uevent_init(void)
606 {
607         return register_pernet_subsys(&uevent_net_ops);
608 }
609
610
611 postcore_initcall(kobject_uevent_init);
612 #endif