aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-04-05 19:40:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 13:57:31 -0400
commit16574dccd8f62dc1b585325f8a6a0aab10047ed8 (patch)
tree0c6c5ff8f014fa3da4c82e15125a3a778c796331 /drivers/base
parent4628803062d93dadc6ba8e801fd075526904a38c (diff)
Driver core: make uevent-environment available in uevent-file
This allows sysfs to show the environment variables that are available if the uevent happens. This lets userspace not have to cache all of this information as the kernel already knows it. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index c34a4d8842e1..72c6ee57471b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -246,6 +246,53 @@ static struct kset_uevent_ops device_uevent_ops = {
246 .uevent = dev_uevent, 246 .uevent = dev_uevent,
247}; 247};
248 248
249static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
250 char *buf)
251{
252 struct kobject *top_kobj;
253 struct kset *kset;
254 char *envp[32];
255 char data[PAGE_SIZE];
256 char *pos;
257 int i;
258 size_t count = 0;
259 int retval;
260
261 /* search the kset, the device belongs to */
262 top_kobj = &dev->kobj;
263 if (!top_kobj->kset && top_kobj->parent) {
264 do {
265 top_kobj = top_kobj->parent;
266 } while (!top_kobj->kset && top_kobj->parent);
267 }
268 if (!top_kobj->kset)
269 goto out;
270 kset = top_kobj->kset;
271 if (!kset->uevent_ops || !kset->uevent_ops->uevent)
272 goto out;
273
274 /* respect filter */
275 if (kset->uevent_ops && kset->uevent_ops->filter)
276 if (!kset->uevent_ops->filter(kset, &dev->kobj))
277 goto out;
278
279 /* let the kset specific function add its keys */
280 pos = data;
281 retval = kset->uevent_ops->uevent(kset, &dev->kobj,
282 envp, ARRAY_SIZE(envp),
283 pos, PAGE_SIZE);
284 if (retval)
285 goto out;
286
287 /* copy keys to file */
288 for (i = 0; envp[i]; i++) {
289 pos = &buf[count];
290 count += sprintf(pos, "%s\n", envp[i]);
291 }
292out:
293 return count;
294}
295
249static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, 296static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
250 const char *buf, size_t count) 297 const char *buf, size_t count)
251{ 298{
@@ -621,10 +668,11 @@ int device_add(struct device *dev)
621 BUS_NOTIFY_ADD_DEVICE, dev); 668 BUS_NOTIFY_ADD_DEVICE, dev);
622 669
623 dev->uevent_attr.attr.name = "uevent"; 670 dev->uevent_attr.attr.name = "uevent";
624 dev->uevent_attr.attr.mode = S_IWUSR; 671 dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR;
625 if (dev->driver) 672 if (dev->driver)
626 dev->uevent_attr.attr.owner = dev->driver->owner; 673 dev->uevent_attr.attr.owner = dev->driver->owner;
627 dev->uevent_attr.store = store_uevent; 674 dev->uevent_attr.store = store_uevent;
675 dev->uevent_attr.show = show_uevent;
628 error = device_create_file(dev, &dev->uevent_attr); 676 error = device_create_file(dev, &dev->uevent_attr);
629 if (error) 677 if (error)
630 goto attrError; 678 goto attrError;