Commit e52eec13cd6b7f30ab19081b387813e03e592ae5
Committed by
Greg Kroah-Hartman
1 parent
39aba963d9
Exists in
master
and in
20 other branches
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: Andi Kleen <ak@linux.intel.com> Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 7 changed files with 68 additions and 30 deletions Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -2365,6 +2365,15 @@ |
2365 | 2365 | |
2366 | 2366 | switches= [HW,M68k] |
2367 | 2367 | |
2368 | + sysfs.deprecated=0|1 [KNL] | |
2369 | + Enable/disable old style sysfs layout for old udev | |
2370 | + on older distributions. When this option is enabled | |
2371 | + very new udev will not work anymore. When this option | |
2372 | + is disabled (or CONFIG_SYSFS_DEPRECATED not compiled) | |
2373 | + in older udev will not work anymore. | |
2374 | + Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in | |
2375 | + the kernel configuration. | |
2376 | + | |
2368 | 2377 | sysrq_always_enabled |
2369 | 2378 | [KNL] |
2370 | 2379 | Ignore sysrq setting - this boot parameter will |
block/genhd.c
... | ... | @@ -22,9 +22,7 @@ |
22 | 22 | #include "blk.h" |
23 | 23 | |
24 | 24 | static DEFINE_MUTEX(block_class_lock); |
25 | -#ifndef CONFIG_SYSFS_DEPRECATED | |
26 | 25 | struct kobject *block_depr; |
27 | -#endif | |
28 | 26 | |
29 | 27 | /* for extended dynamic devt allocation, currently only one major is used */ |
30 | 28 | #define MAX_EXT_DEVT (1 << MINORBITS) |
31 | 29 | |
... | ... | @@ -803,10 +801,9 @@ |
803 | 801 | |
804 | 802 | register_blkdev(BLOCK_EXT_MAJOR, "blkext"); |
805 | 803 | |
806 | -#ifndef CONFIG_SYSFS_DEPRECATED | |
807 | 804 | /* create top-level block dir */ |
808 | - block_depr = kobject_create_and_add("block", NULL); | |
809 | -#endif | |
805 | + if (!sysfs_deprecated) | |
806 | + block_depr = kobject_create_and_add("block", NULL); | |
810 | 807 | return 0; |
811 | 808 | } |
812 | 809 |
drivers/base/class.c
... | ... | @@ -184,9 +184,9 @@ |
184 | 184 | if (!cls->dev_kobj) |
185 | 185 | cls->dev_kobj = sysfs_dev_char_kobj; |
186 | 186 | |
187 | -#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) | |
187 | +#if defined(CONFIG_BLOCK) | |
188 | 188 | /* let the block class directory show up in the root of sysfs */ |
189 | - if (cls != &block_class) | |
189 | + if (!sysfs_deprecated || cls != &block_class) | |
190 | 190 | cp->class_subsys.kobj.kset = class_kset; |
191 | 191 | #else |
192 | 192 | cp->class_subsys.kobj.kset = class_kset; |
drivers/base/core.c
... | ... | @@ -26,6 +26,19 @@ |
26 | 26 | #include "base.h" |
27 | 27 | #include "power/power.h" |
28 | 28 | |
29 | +#ifdef CONFIG_SYSFS_DEPRECATED | |
30 | +#ifdef CONFIG_SYSFS_DEPRECATED_V2 | |
31 | +long sysfs_deprecated = 1; | |
32 | +#else | |
33 | +long sysfs_deprecated = 0; | |
34 | +#endif | |
35 | +static __init int sysfs_deprecated_setup(char *arg) | |
36 | +{ | |
37 | + return strict_strtol(arg, 10, &sysfs_deprecated); | |
38 | +} | |
39 | +early_param("sysfs.deprecated", sysfs_deprecated_setup); | |
40 | +#endif | |
41 | + | |
29 | 42 | int (*platform_notify)(struct device *dev) = NULL; |
30 | 43 | int (*platform_notify_remove)(struct device *dev) = NULL; |
31 | 44 | static struct kobject *dev_kobj; |
32 | 45 | |
33 | 46 | |
... | ... | @@ -617,14 +630,13 @@ |
617 | 630 | struct kobject *parent_kobj; |
618 | 631 | struct kobject *k; |
619 | 632 | |
620 | -#ifdef CONFIG_SYSFS_DEPRECATED | |
621 | 633 | /* block disks show up in /sys/block */ |
622 | - if (dev->class == &block_class) { | |
634 | + if (sysfs_deprecated && dev->class == &block_class) { | |
623 | 635 | if (parent && parent->class == &block_class) |
624 | 636 | return &parent->kobj; |
625 | 637 | return &block_class.p->class_subsys.kobj; |
626 | 638 | } |
627 | -#endif | |
639 | + | |
628 | 640 | /* |
629 | 641 | * If we have no parent, we live in "virtual". |
630 | 642 | * Class-devices with a non class-device as parent, live |
631 | 643 | |
632 | 644 | |
... | ... | @@ -707,11 +719,9 @@ |
707 | 719 | goto out_subsys; |
708 | 720 | } |
709 | 721 | |
710 | -#ifdef CONFIG_SYSFS_DEPRECATED | |
711 | 722 | /* /sys/block has directories and does not need symlinks */ |
712 | - if (dev->class == &block_class) | |
723 | + if (sysfs_deprecated && dev->class == &block_class) | |
713 | 724 | return 0; |
714 | -#endif | |
715 | 725 | |
716 | 726 | /* link in the class directory pointing to the device */ |
717 | 727 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, |
718 | 728 | |
... | ... | @@ -738,10 +748,8 @@ |
738 | 748 | if (dev->parent && device_is_not_partition(dev)) |
739 | 749 | sysfs_remove_link(&dev->kobj, "device"); |
740 | 750 | sysfs_remove_link(&dev->kobj, "subsystem"); |
741 | -#ifdef CONFIG_SYSFS_DEPRECATED | |
742 | - if (dev->class == &block_class) | |
751 | + if (sysfs_deprecated && dev->class == &block_class) | |
743 | 752 | return; |
744 | -#endif | |
745 | 753 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); |
746 | 754 | } |
747 | 755 |
fs/partitions/check.c
... | ... | @@ -513,14 +513,14 @@ |
513 | 513 | |
514 | 514 | if (device_add(ddev)) |
515 | 515 | return; |
516 | -#ifndef CONFIG_SYSFS_DEPRECATED | |
517 | - err = sysfs_create_link(block_depr, &ddev->kobj, | |
518 | - kobject_name(&ddev->kobj)); | |
519 | - if (err) { | |
520 | - device_del(ddev); | |
521 | - return; | |
516 | + if (!sysfs_deprecated) { | |
517 | + err = sysfs_create_link(block_depr, &ddev->kobj, | |
518 | + kobject_name(&ddev->kobj)); | |
519 | + if (err) { | |
520 | + device_del(ddev); | |
521 | + return; | |
522 | + } | |
522 | 523 | } |
523 | -#endif | |
524 | 524 | disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); |
525 | 525 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); |
526 | 526 | |
... | ... | @@ -737,9 +737,8 @@ |
737 | 737 | kobject_put(disk->part0.holder_dir); |
738 | 738 | kobject_put(disk->slave_dir); |
739 | 739 | disk->driverfs_dev = NULL; |
740 | -#ifndef CONFIG_SYSFS_DEPRECATED | |
741 | - sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); | |
742 | -#endif | |
740 | + if (!sysfs_deprecated) | |
741 | + sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); | |
743 | 742 | device_del(disk_to_dev(disk)); |
744 | 743 | } |
include/linux/device.h
... | ... | @@ -751,5 +751,12 @@ |
751 | 751 | MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) |
752 | 752 | #define MODULE_ALIAS_CHARDEV_MAJOR(major) \ |
753 | 753 | MODULE_ALIAS("char-major-" __stringify(major) "-*") |
754 | + | |
755 | +#ifdef CONFIG_SYSFS_DEPRECATED | |
756 | +extern long sysfs_deprecated; | |
757 | +#else | |
758 | +#define sysfs_deprecated 0 | |
759 | +#endif | |
760 | + | |
754 | 761 | #endif /* _DEVICE_H_ */ |
init/Kconfig
... | ... | @@ -660,9 +660,13 @@ |
660 | 660 | depends on SYSFS |
661 | 661 | default n |
662 | 662 | help |
663 | - This option switches the layout of the "block" class devices, to not | |
664 | - show up in /sys/class/block/, but only in /sys/block/. | |
663 | + This option adds code that switches the layout of the "block" class | |
664 | + devices, to not show up in /sys/class/block/, but only in | |
665 | + /sys/block/. | |
665 | 666 | |
667 | + This switch is only active when the sysfs.deprecated=1 boot option is | |
668 | + passed or the SYSFS_DEPRECATED_V2 option is set. | |
669 | + | |
666 | 670 | This option allows new kernels to run on old distributions and tools, |
667 | 671 | which might get confused by /sys/class/block/. Since 2007/2008 all |
668 | 672 | major distributions and tools handle this just fine. |
... | ... | @@ -672,8 +676,22 @@ |
672 | 676 | option enabled. |
673 | 677 | |
674 | 678 | Only if you are using a new kernel on an old distribution, you might |
675 | - need to say Y here. Never say Y, if the original kernel, that came | |
676 | - with your distribution, has not set this option. | |
679 | + need to say Y here. | |
680 | + | |
681 | +config SYSFS_DEPRECATED_V2 | |
682 | + bool "enabled deprecated sysfs features by default" | |
683 | + default n | |
684 | + depends on SYSFS | |
685 | + depends on SYSFS_DEPRECATED | |
686 | + help | |
687 | + Enable deprecated sysfs by default. | |
688 | + | |
689 | + See the CONFIG_SYSFS_DEPRECATED option for more details about this | |
690 | + option. | |
691 | + | |
692 | + Only if you are using a new kernel on an old distribution, you might | |
693 | + need to say Y here. Even then, odds are you would not need it | |
694 | + enabled, you can always pass the boot option if absolutely necessary. | |
677 | 695 | |
678 | 696 | config RELAY |
679 | 697 | bool "Kernel->user space relay support (formerly relayfs)" |