Commit e52eec13cd6b7f30ab19081b387813e03e592ae5

Authored by Andi Kleen
Committed by Greg Kroah-Hartman
1 parent 39aba963d9

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
... ... @@ -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;
... ... @@ -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_ */
... ... @@ -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)"