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/export.h>
  15#include <linux/init.h>
  16#include <linux/kexec.h>
  17#include <linux/profile.h>
  18#include <linux/stat.h>
  19#include <linux/sched.h>
  20#include <linux/capability.h>
  21
  22#define KERNEL_ATTR_RO(_name) \
  23static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
  24
  25#define KERNEL_ATTR_RW(_name) \
  26static struct kobj_attribute _name##_attr = \
  27        __ATTR(_name, 0644, _name##_show, _name##_store)
  28
  29#if defined(CONFIG_HOTPLUG)
  30/* current uevent sequence number */
  31static ssize_t uevent_seqnum_show(struct kobject *kobj,
  32                                  struct kobj_attribute *attr, char *buf)
  33{
  34        return sprintf(buf, "%llu\n", (unsigned long long)uevent_seqnum);
  35}
  36KERNEL_ATTR_RO(uevent_seqnum);
  37
  38/* uevent helper program, used during early boot */
  39static ssize_t uevent_helper_show(struct kobject *kobj,
  40                                  struct kobj_attribute *attr, char *buf)
  41{
  42        return sprintf(buf, "%s\n", uevent_helper);
  43}
  44static ssize_t uevent_helper_store(struct kobject *kobj,
  45                                   struct kobj_attribute *attr,
  46                                   const char *buf, size_t count)
  47{
  48        if (count+1 > UEVENT_HELPER_PATH_LEN)
  49                return -ENOENT;
  50        memcpy(uevent_helper, buf, count);
  51        uevent_helper[count] = '\0';
  52        if (count && uevent_helper[count-1] == '\n')
  53                uevent_helper[count-1] = '\0';
  54        return count;
  55}
  56KERNEL_ATTR_RW(uevent_helper);
  57#endif
  58
  59#ifdef CONFIG_PROFILING
  60static ssize_t profiling_show(struct kobject *kobj,
  61                                  struct kobj_attribute *attr, char *buf)
  62{
  63        return sprintf(buf, "%d\n", prof_on);
  64}
  65static ssize_t profiling_store(struct kobject *kobj,
  66                                   struct kobj_attribute *attr,
  67                                   const char *buf, size_t count)
  68{
  69        int ret;
  70
  71        if (prof_on)
  72                return -EEXIST;
  73        /*
  74         * This eventually calls into get_option() which
  75         * has a ton of callers and is not const.  It is
  76         * easiest to cast it away here.
  77         */
  78        profile_setup((char *)buf);
  79        ret = profile_init();
  80        if (ret)
  81                return ret;
  82        ret = create_proc_profile();
  83        if (ret)
  84                return ret;
  85        return count;
  86}
  87KERNEL_ATTR_RW(profiling);
  88#endif
  89
  90#ifdef CONFIG_KEXEC
  91static ssize_t kexec_loaded_show(struct kobject *kobj,
  92                                 struct kobj_attribute *attr, char *buf)
  93{
  94        return sprintf(buf, "%d\n", !!kexec_image);
  95}
  96KERNEL_ATTR_RO(kexec_loaded);
  97
  98static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
  99                                       struct kobj_attribute *attr, char *buf)
 100{
 101        return sprintf(buf, "%d\n", !!kexec_crash_image);
 102}
 103KERNEL_ATTR_RO(kexec_crash_loaded);
 104
 105static ssize_t kexec_crash_size_show(struct kobject *kobj,
 106                                       struct kobj_attribute *attr, char *buf)
 107{
 108        return sprintf(buf, "%zu\n", crash_get_memory_size());
 109}
 110static ssize_t kexec_crash_size_store(struct kobject *kobj,
 111                                   struct kobj_attribute *attr,
 112                                   const char *buf, size_t count)
 113{
 114        unsigned long cnt;
 115        int ret;
 116
 117        if (strict_strtoul(buf, 0, &cnt))
 118                return -EINVAL;
 119
 120        ret = crash_shrink_memory(cnt);
 121        return ret < 0 ? ret : count;
 122}
 123KERNEL_ATTR_RW(kexec_crash_size);
 124
 125static ssize_t vmcoreinfo_show(struct kobject *kobj,
 126                               struct kobj_attribute *attr, char *buf)
 127{
 128        return sprintf(buf, "%lx %x\n",
 129                       paddr_vmcoreinfo_note(),
 130                       (unsigned int)vmcoreinfo_max_size);
 131}
 132KERNEL_ATTR_RO(vmcoreinfo);
 133
 134#endif /* CONFIG_KEXEC */
 135
 136/* whether file capabilities are enabled */
 137static ssize_t fscaps_show(struct kobject *kobj,
 138                                  struct kobj_attribute *attr, char *buf)
 139{
 140        return sprintf(buf, "%d\n", file_caps_enabled);
 141}
 142KERNEL_ATTR_RO(fscaps);
 143
 144/*
 145 * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
 146 */
 147extern const void __start_notes __attribute__((weak));
 148extern const void __stop_notes __attribute__((weak));
 149#define notes_size (&__stop_notes - &__start_notes)
 150
 151static ssize_t notes_read(struct file *filp, struct kobject *kobj,
 152                          struct bin_attribute *bin_attr,
 153                          char *buf, loff_t off, size_t count)
 154{
 155        memcpy(buf, &__start_notes + off, count);
 156        return count;
 157}
 158
 159static struct bin_attribute notes_attr = {
 160        .attr = {
 161                .name = "notes",
 162                .mode = S_IRUGO,
 163        },
 164        .read = &notes_read,
 165};
 166
 167struct kobject *kernel_kobj;
 168EXPORT_SYMBOL_GPL(kernel_kobj);
 169
 170static struct attribute * kernel_attrs[] = {
 171        &fscaps_attr.attr,
 172#if defined(CONFIG_HOTPLUG)
 173        &uevent_seqnum_attr.attr,
 174        &uevent_helper_attr.attr,
 175#endif
 176#ifdef CONFIG_PROFILING
 177        &profiling_attr.attr,
 178#endif
 179#ifdef CONFIG_KEXEC
 180        &kexec_loaded_attr.attr,
 181        &kexec_crash_loaded_attr.attr,
 182        &kexec_crash_size_attr.attr,
 183        &vmcoreinfo_attr.attr,
 184#endif
 185        NULL
 186};
 187
 188static struct attribute_group kernel_attr_group = {
 189        .attrs = kernel_attrs,
 190};
 191
 192static int __init ksysfs_init(void)
 193{
 194        int error;
 195
 196        kernel_kobj = kobject_create_and_add("kernel", NULL);
 197        if (!kernel_kobj) {
 198                error = -ENOMEM;
 199                goto exit;
 200        }
 201        error = sysfs_create_group(kernel_kobj, &kernel_attr_group);
 202        if (error)
 203                goto kset_exit;
 204
 205        if (notes_size > 0) {
 206                notes_attr.size = notes_size;
 207                error = sysfs_create_bin_file(kernel_kobj, &notes_attr);
 208                if (error)
 209                        goto group_exit;
 210        }
 211
 212        return 0;
 213
 214group_exit:
 215        sysfs_remove_group(kernel_kobj, &kernel_attr_group);
 216kset_exit:
 217        kobject_put(kernel_kobj);
 218exit:
 219        return error;
 220}
 221
 222core_initcall(ksysfs_init);
 223
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.