linux/kernel/ksysfs.c
<<
>>
Prefs
   1/*
   2 * kernel/ksysfs.c - sysfs attributes in /sys/kernel, which
   3 *                   are not related to any other subsystem
   4 *
   5 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
   6 * 
   7 * This file is release under the GPLv2
   8 *
   9 */
  10
  11#include <linux/kobject.h>
  12#include <linux/string.h>
  13#include <linux/sysfs.h>
  14#include <linux/module.h>
  15#include <linux/init.h>
  16#include <linux/kexec.h>
  17#include <linux/sched.h>
  18
  19#define KERNEL_ATTR_RO(_name) \
  20static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
  21
  22#define KERNEL_ATTR_RW(_name) \
  23static struct subsys_attribute _name##_attr = \
  24        __ATTR(_name, 0644, _name##_show, _name##_store)
  25
  26#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
  27/* current uevent sequence number */
  28static ssize_t uevent_seqnum_show(struct kset *kset, char *page)
  29{
  30        return sprintf(page, "%llu\n", (unsigned long long)uevent_seqnum);
  31}
  32KERNEL_ATTR_RO(uevent_seqnum);
  33
  34/* uevent helper program, used during early boo */
  35static ssize_t uevent_helper_show(struct kset *kset, char *page)
  36{
  37        return sprintf(page, "%s\n", uevent_helper);
  38}
  39static ssize_t uevent_helper_store(struct kset *kset, const char *page, size_t count)
  40{
  41        if (count+1 > UEVENT_HELPER_PATH_LEN)
  42                return -ENOENT;
  43        memcpy(uevent_helper, page, count);
  44        uevent_helper[count] = '\0';
  45        if (count && uevent_helper[count-1] == '\n')
  46                uevent_helper[count-1] = '\0';
  47        return count;
  48}
  49KERNEL_ATTR_RW(uevent_helper);
  50#endif
  51
  52#ifdef CONFIG_KEXEC
  53static ssize_t kexec_loaded_show(struct kset *kset, char *page)
  54{
  55        return sprintf(page, "%d\n", !!kexec_image);
  56}
  57KERNEL_ATTR_RO(kexec_loaded);
  58
  59static ssize_t kexec_crash_loaded_show(struct kset *kset, char *page)
  60{
  61        return sprintf(page, "%d\n", !!kexec_crash_image);
  62}
  63KERNEL_ATTR_RO(kexec_crash_loaded);
  64
  65static ssize_t vmcoreinfo_show(struct kset *kset, char *page)
  66{
  67        return sprintf(page, "%lx %x\n",
  68                       paddr_vmcoreinfo_note(),
  69                       (unsigned int)vmcoreinfo_max_size);
  70}
  71KERNEL_ATTR_RO(vmcoreinfo);
  72
  73#endif /* CONFIG_KEXEC */
  74
  75/*
  76 * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
  77 */
  78extern const void __start_notes __attribute__((weak));
  79extern const void __stop_notes __attribute__((weak));
  80#define notes_size (&__stop_notes - &__start_notes)
  81
  82static ssize_t notes_read(struct kobject *kobj, struct bin_attribute *bin_attr,
  83                          char *buf, loff_t off, size_t count)
  84{
  85        memcpy(buf, &__start_notes + off, count);
  86        return count;
  87}
  88
  89static struct bin_attribute notes_attr = {
  90        .attr = {
  91                .name = "notes",
  92                .mode = S_IRUGO,
  93        },
  94        .read = &notes_read,
  95};
  96
  97decl_subsys(kernel, NULL, NULL);
  98EXPORT_SYMBOL_GPL(kernel_subsys);
  99
 100static struct attribute * kernel_attrs[] = {
 101#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
 102        &uevent_seqnum_attr.attr,
 103        &uevent_helper_attr.attr,
 104#endif
 105#ifdef CONFIG_KEXEC
 106        &kexec_loaded_attr.attr,
 107        &kexec_crash_loaded_attr.attr,
 108        &vmcoreinfo_attr.attr,
 109#endif
 110        NULL
 111};
 112
 113static struct attribute_group kernel_attr_group = {
 114        .attrs = kernel_attrs,
 115};
 116
 117static int __init ksysfs_init(void)
 118{
 119        int error = subsystem_register(&kernel_subsys);
 120        if (!error)
 121                error = sysfs_create_group(&kernel_subsys.kobj,
 122                                           &kernel_attr_group);
 123
 124        if (!error && notes_size > 0) {
 125                notes_attr.size = notes_size;
 126                error = sysfs_create_bin_file(&kernel_subsys.kobj,
 127                                              &notes_attr);
 128        }
 129
 130        /*
 131         * Create "/sys/kernel/uids" directory and corresponding root user's
 132         * directory under it.
 133         */
 134        if (!error)
 135                error = uids_kobject_init();
 136
 137        return error;
 138}
 139
 140core_initcall(ksysfs_init);
 141