Commit e52eec13 authored by Andi Kleen's avatar Andi Kleen Committed by Greg Kroah-Hartman

SYSFS: Allow boot time switching between deprecated and modern sysfs layout

I have some systems which need legacy sysfs due to old tools that are
making assumptions that a directory can never be a symlink to another
directory, and it's a big hazzle to compile separate kernels for them.

This patch turns CONFIG_SYSFS_DEPRECATED into a run time option
that can be switched on/off the kernel command line. This way
the same binary can be used in both cases with just a option
on the command line.

The old CONFIG_SYSFS_DEPRECATED_V2 option is still there to set
the default. I kept the weird name to not break existing
config files.

Also the compat code can be still completely disabled by undefining
CONFIG_SYSFS_DEPRECATED_SWITCH -- just the optimizer takes
care of this now instead of lots of ifdefs. This makes the code
look nicer.

v2: This is an updated version on top of Kay's patch to only
handle the block devices. I tested it on my old systems
and that seems to work.

Cc: axboe@kernel.dk
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 39aba963
...@@ -2365,6 +2365,15 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2365,6 +2365,15 @@ and is between 256 and 4096 characters. It is defined in the file
switches= [HW,M68k] switches= [HW,M68k]
sysfs.deprecated=0|1 [KNL]
Enable/disable old style sysfs layout for old udev
on older distributions. When this option is enabled
very new udev will not work anymore. When this option
is disabled (or CONFIG_SYSFS_DEPRECATED not compiled)
in older udev will not work anymore.
Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in
the kernel configuration.
sysrq_always_enabled sysrq_always_enabled
[KNL] [KNL]
Ignore sysrq setting - this boot parameter will Ignore sysrq setting - this boot parameter will
......
...@@ -22,9 +22,7 @@ ...@@ -22,9 +22,7 @@
#include "blk.h" #include "blk.h"
static DEFINE_MUTEX(block_class_lock); static DEFINE_MUTEX(block_class_lock);
#ifndef CONFIG_SYSFS_DEPRECATED
struct kobject *block_depr; struct kobject *block_depr;
#endif
/* for extended dynamic devt allocation, currently only one major is used */ /* for extended dynamic devt allocation, currently only one major is used */
#define MAX_EXT_DEVT (1 << MINORBITS) #define MAX_EXT_DEVT (1 << MINORBITS)
...@@ -803,10 +801,9 @@ static int __init genhd_device_init(void) ...@@ -803,10 +801,9 @@ static int __init genhd_device_init(void)
register_blkdev(BLOCK_EXT_MAJOR, "blkext"); register_blkdev(BLOCK_EXT_MAJOR, "blkext");
#ifndef CONFIG_SYSFS_DEPRECATED
/* create top-level block dir */ /* create top-level block dir */
if (!sysfs_deprecated)
block_depr = kobject_create_and_add("block", NULL); block_depr = kobject_create_and_add("block", NULL);
#endif
return 0; return 0;
} }
......
...@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key) ...@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
if (!cls->dev_kobj) if (!cls->dev_kobj)
cls->dev_kobj = sysfs_dev_char_kobj; cls->dev_kobj = sysfs_dev_char_kobj;
#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) #if defined(CONFIG_BLOCK)
/* let the block class directory show up in the root of sysfs */ /* let the block class directory show up in the root of sysfs */
if (cls != &block_class) if (!sysfs_deprecated || cls != &block_class)
cp->class_subsys.kobj.kset = class_kset; cp->class_subsys.kobj.kset = class_kset;
#else #else
cp->class_subsys.kobj.kset = class_kset; cp->class_subsys.kobj.kset = class_kset;
......
...@@ -26,6 +26,19 @@ ...@@ -26,6 +26,19 @@
#include "base.h" #include "base.h"
#include "power/power.h" #include "power/power.h"
#ifdef CONFIG_SYSFS_DEPRECATED
#ifdef CONFIG_SYSFS_DEPRECATED_V2
long sysfs_deprecated = 1;
#else
long sysfs_deprecated = 0;
#endif
static __init int sysfs_deprecated_setup(char *arg)
{
return strict_strtol(arg, 10, &sysfs_deprecated);
}
early_param("sysfs.deprecated", sysfs_deprecated_setup);
#endif
int (*platform_notify)(struct device *dev) = NULL; int (*platform_notify)(struct device *dev) = NULL;
int (*platform_notify_remove)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL;
static struct kobject *dev_kobj; static struct kobject *dev_kobj;
...@@ -617,14 +630,13 @@ static struct kobject *get_device_parent(struct device *dev, ...@@ -617,14 +630,13 @@ static struct kobject *get_device_parent(struct device *dev,
struct kobject *parent_kobj; struct kobject *parent_kobj;
struct kobject *k; struct kobject *k;
#ifdef CONFIG_SYSFS_DEPRECATED
/* block disks show up in /sys/block */ /* block disks show up in /sys/block */
if (dev->class == &block_class) { if (sysfs_deprecated && dev->class == &block_class) {
if (parent && parent->class == &block_class) if (parent && parent->class == &block_class)
return &parent->kobj; return &parent->kobj;
return &block_class.p->class_subsys.kobj; return &block_class.p->class_subsys.kobj;
} }
#endif
/* /*
* If we have no parent, we live in "virtual". * If we have no parent, we live in "virtual".
* Class-devices with a non class-device as parent, live * Class-devices with a non class-device as parent, live
...@@ -707,11 +719,9 @@ static int device_add_class_symlinks(struct device *dev) ...@@ -707,11 +719,9 @@ static int device_add_class_symlinks(struct device *dev)
goto out_subsys; goto out_subsys;
} }
#ifdef CONFIG_SYSFS_DEPRECATED
/* /sys/block has directories and does not need symlinks */ /* /sys/block has directories and does not need symlinks */
if (dev->class == &block_class) if (sysfs_deprecated && dev->class == &block_class)
return 0; return 0;
#endif
/* link in the class directory pointing to the device */ /* link in the class directory pointing to the device */
error = sysfs_create_link(&dev->class->p->class_subsys.kobj, error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
...@@ -738,10 +748,8 @@ static void device_remove_class_symlinks(struct device *dev) ...@@ -738,10 +748,8 @@ static void device_remove_class_symlinks(struct device *dev)
if (dev->parent && device_is_not_partition(dev)) if (dev->parent && device_is_not_partition(dev))
sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "device");
sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->kobj, "subsystem");
#ifdef CONFIG_SYSFS_DEPRECATED if (sysfs_deprecated && dev->class == &block_class)
if (dev->class == &block_class)
return; return;
#endif
sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
} }
......
...@@ -513,14 +513,14 @@ void register_disk(struct gendisk *disk) ...@@ -513,14 +513,14 @@ void register_disk(struct gendisk *disk)
if (device_add(ddev)) if (device_add(ddev))
return; return;
#ifndef CONFIG_SYSFS_DEPRECATED if (!sysfs_deprecated) {
err = sysfs_create_link(block_depr, &ddev->kobj, err = sysfs_create_link(block_depr, &ddev->kobj,
kobject_name(&ddev->kobj)); kobject_name(&ddev->kobj));
if (err) { if (err) {
device_del(ddev); device_del(ddev);
return; return;
} }
#endif }
disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
...@@ -737,8 +737,7 @@ void del_gendisk(struct gendisk *disk) ...@@ -737,8 +737,7 @@ void del_gendisk(struct gendisk *disk)
kobject_put(disk->part0.holder_dir); kobject_put(disk->part0.holder_dir);
kobject_put(disk->slave_dir); kobject_put(disk->slave_dir);
disk->driverfs_dev = NULL; disk->driverfs_dev = NULL;
#ifndef CONFIG_SYSFS_DEPRECATED if (!sysfs_deprecated)
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
#endif
device_del(disk_to_dev(disk)); device_del(disk_to_dev(disk));
} }
...@@ -751,4 +751,11 @@ do { \ ...@@ -751,4 +751,11 @@ do { \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
#define MODULE_ALIAS_CHARDEV_MAJOR(major) \ #define MODULE_ALIAS_CHARDEV_MAJOR(major) \
MODULE_ALIAS("char-major-" __stringify(major) "-*") MODULE_ALIAS("char-major-" __stringify(major) "-*")
#ifdef CONFIG_SYSFS_DEPRECATED
extern long sysfs_deprecated;
#else
#define sysfs_deprecated 0
#endif
#endif /* _DEVICE_H_ */ #endif /* _DEVICE_H_ */
...@@ -660,8 +660,12 @@ config SYSFS_DEPRECATED ...@@ -660,8 +660,12 @@ config SYSFS_DEPRECATED
depends on SYSFS depends on SYSFS
default n default n
help help
This option switches the layout of the "block" class devices, to not This option adds code that switches the layout of the "block" class
show up in /sys/class/block/, but only in /sys/block/. devices, to not show up in /sys/class/block/, but only in
/sys/block/.
This switch is only active when the sysfs.deprecated=1 boot option is
passed or the SYSFS_DEPRECATED_V2 option is set.
This option allows new kernels to run on old distributions and tools, This option allows new kernels to run on old distributions and tools,
which might get confused by /sys/class/block/. Since 2007/2008 all which might get confused by /sys/class/block/. Since 2007/2008 all
...@@ -672,8 +676,22 @@ config SYSFS_DEPRECATED ...@@ -672,8 +676,22 @@ config SYSFS_DEPRECATED
option enabled. option enabled.
Only if you are using a new kernel on an old distribution, you might Only if you are using a new kernel on an old distribution, you might
need to say Y here. Never say Y, if the original kernel, that came need to say Y here.
with your distribution, has not set this option.
config SYSFS_DEPRECATED_V2
bool "enabled deprecated sysfs features by default"
default n
depends on SYSFS
depends on SYSFS_DEPRECATED
help
Enable deprecated sysfs by default.
See the CONFIG_SYSFS_DEPRECATED option for more details about this
option.
Only if you are using a new kernel on an old distribution, you might
need to say Y here. Even then, odds are you would not need it
enabled, you can always pass the boot option if absolutely necessary.
config RELAY config RELAY
bool "Kernel->user space relay support (formerly relayfs)" bool "Kernel->user space relay support (formerly relayfs)"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment