aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2010-09-08 10:54:17 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:16:43 -0400
commite52eec13cd6b7f30ab19081b387813e03e592ae5 (patch)
tree7b327e0b9283c578fb10922edcf6e10b3b8fd943
parent39aba963d937edb20db7d9d93e6dda5d2adfdcdd (diff)
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>
-rw-r--r--Documentation/kernel-parameters.txt9
-rw-r--r--block/genhd.c7
-rw-r--r--drivers/base/class.c4
-rw-r--r--drivers/base/core.c26
-rw-r--r--fs/partitions/check.c19
-rw-r--r--include/linux/device.h7
-rw-r--r--init/Kconfig26
7 files changed, 68 insertions, 30 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 3d854c9ae53a..67fa3fdc128f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2365,6 +2365,15 @@ and is between 256 and 4096 characters. It is defined in the file
2365 2365
2366 switches= [HW,M68k] 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 sysrq_always_enabled 2377 sysrq_always_enabled
2369 [KNL] 2378 [KNL]
2370 Ignore sysrq setting - this boot parameter will 2379 Ignore sysrq setting - this boot parameter will
diff --git a/block/genhd.c b/block/genhd.c
index 59a2db6fecef..4e28a840bde0 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -22,9 +22,7 @@
22#include "blk.h" 22#include "blk.h"
23 23
24static DEFINE_MUTEX(block_class_lock); 24static DEFINE_MUTEX(block_class_lock);
25#ifndef CONFIG_SYSFS_DEPRECATED
26struct kobject *block_depr; 25struct kobject *block_depr;
27#endif
28 26
29/* for extended dynamic devt allocation, currently only one major is used */ 27/* for extended dynamic devt allocation, currently only one major is used */
30#define MAX_EXT_DEVT (1 << MINORBITS) 28#define MAX_EXT_DEVT (1 << MINORBITS)
@@ -803,10 +801,9 @@ static int __init genhd_device_init(void)
803 801
804 register_blkdev(BLOCK_EXT_MAJOR, "blkext"); 802 register_blkdev(BLOCK_EXT_MAJOR, "blkext");
805 803
806#ifndef CONFIG_SYSFS_DEPRECATED
807 /* create top-level block dir */ 804 /* create top-level block dir */
808 block_depr = kobject_create_and_add("block", NULL); 805 if (!sysfs_deprecated)
809#endif 806 block_depr = kobject_create_and_add("block", NULL);
810 return 0; 807 return 0;
811} 808}
812 809
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 1078969889fd..9c63a5687d69 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
184 if (!cls->dev_kobj) 184 if (!cls->dev_kobj)
185 cls->dev_kobj = sysfs_dev_char_kobj; 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 /* let the block class directory show up in the root of sysfs */ 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 cp->class_subsys.kobj.kset = class_kset; 190 cp->class_subsys.kobj.kset = class_kset;
191#else 191#else
192 cp->class_subsys.kobj.kset = class_kset; 192 cp->class_subsys.kobj.kset = class_kset;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6cf9069f3150..f7f906f0a2f2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -26,6 +26,19 @@
26#include "base.h" 26#include "base.h"
27#include "power/power.h" 27#include "power/power.h"
28 28
29#ifdef CONFIG_SYSFS_DEPRECATED
30#ifdef CONFIG_SYSFS_DEPRECATED_V2
31long sysfs_deprecated = 1;
32#else
33long sysfs_deprecated = 0;
34#endif
35static __init int sysfs_deprecated_setup(char *arg)
36{
37 return strict_strtol(arg, 10, &sysfs_deprecated);
38}
39early_param("sysfs.deprecated", sysfs_deprecated_setup);
40#endif
41
29int (*platform_notify)(struct device *dev) = NULL; 42int (*platform_notify)(struct device *dev) = NULL;
30int (*platform_notify_remove)(struct device *dev) = NULL; 43int (*platform_notify_remove)(struct device *dev) = NULL;
31static struct kobject *dev_kobj; 44static struct kobject *dev_kobj;
@@ -617,14 +630,13 @@ static struct kobject *get_device_parent(struct device *dev,
617 struct kobject *parent_kobj; 630 struct kobject *parent_kobj;
618 struct kobject *k; 631 struct kobject *k;
619 632
620#ifdef CONFIG_SYSFS_DEPRECATED
621 /* block disks show up in /sys/block */ 633 /* block disks show up in /sys/block */
622 if (dev->class == &block_class) { 634 if (sysfs_deprecated && dev->class == &block_class) {
623 if (parent && parent->class == &block_class) 635 if (parent && parent->class == &block_class)
624 return &parent->kobj; 636 return &parent->kobj;
625 return &block_class.p->class_subsys.kobj; 637 return &block_class.p->class_subsys.kobj;
626 } 638 }
627#endif 639
628 /* 640 /*
629 * If we have no parent, we live in "virtual". 641 * If we have no parent, we live in "virtual".
630 * Class-devices with a non class-device as parent, live 642 * Class-devices with a non class-device as parent, live
@@ -707,11 +719,9 @@ static int device_add_class_symlinks(struct device *dev)
707 goto out_subsys; 719 goto out_subsys;
708 } 720 }
709 721
710#ifdef CONFIG_SYSFS_DEPRECATED
711 /* /sys/block has directories and does not need symlinks */ 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 return 0; 724 return 0;
714#endif
715 725
716 /* link in the class directory pointing to the device */ 726 /* link in the class directory pointing to the device */
717 error = sysfs_create_link(&dev->class->p->class_subsys.kobj, 727 error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
@@ -738,10 +748,8 @@ static void device_remove_class_symlinks(struct device *dev)
738 if (dev->parent && device_is_not_partition(dev)) 748 if (dev->parent && device_is_not_partition(dev))
739 sysfs_remove_link(&dev->kobj, "device"); 749 sysfs_remove_link(&dev->kobj, "device");
740 sysfs_remove_link(&dev->kobj, "subsystem"); 750 sysfs_remove_link(&dev->kobj, "subsystem");
741#ifdef CONFIG_SYSFS_DEPRECATED 751 if (sysfs_deprecated && dev->class == &block_class)
742 if (dev->class == &block_class)
743 return; 752 return;
744#endif
745 sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); 753 sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
746} 754}
747 755
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 79fbf3f390f0..137bf9787853 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -513,14 +513,14 @@ void register_disk(struct gendisk *disk)
513 513
514 if (device_add(ddev)) 514 if (device_add(ddev))
515 return; 515 return;
516#ifndef CONFIG_SYSFS_DEPRECATED 516 if (!sysfs_deprecated) {
517 err = sysfs_create_link(block_depr, &ddev->kobj, 517 err = sysfs_create_link(block_depr, &ddev->kobj,
518 kobject_name(&ddev->kobj)); 518 kobject_name(&ddev->kobj));
519 if (err) { 519 if (err) {
520 device_del(ddev); 520 device_del(ddev);
521 return; 521 return;
522 }
522 } 523 }
523#endif
524 disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); 524 disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
525 disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); 525 disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
526 526
@@ -737,8 +737,7 @@ void del_gendisk(struct gendisk *disk)
737 kobject_put(disk->part0.holder_dir); 737 kobject_put(disk->part0.holder_dir);
738 kobject_put(disk->slave_dir); 738 kobject_put(disk->slave_dir);
739 disk->driverfs_dev = NULL; 739 disk->driverfs_dev = NULL;
740#ifndef CONFIG_SYSFS_DEPRECATED 740 if (!sysfs_deprecated)
741 sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); 741 sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
742#endif
743 device_del(disk_to_dev(disk)); 742 device_del(disk_to_dev(disk));
744} 743}
diff --git a/include/linux/device.h b/include/linux/device.h
index 516fecacf27b..dd4895313468 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -751,4 +751,11 @@ do { \
751 MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) 751 MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
752#define MODULE_ALIAS_CHARDEV_MAJOR(major) \ 752#define MODULE_ALIAS_CHARDEV_MAJOR(major) \
753 MODULE_ALIAS("char-major-" __stringify(major) "-*") 753 MODULE_ALIAS("char-major-" __stringify(major) "-*")
754
755#ifdef CONFIG_SYSFS_DEPRECATED
756extern long sysfs_deprecated;
757#else
758#define sysfs_deprecated 0
759#endif
760
754#endif /* _DEVICE_H_ */ 761#endif /* _DEVICE_H_ */
diff --git a/init/Kconfig b/init/Kconfig
index 137609f33ebc..d742b6fca8d2 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -660,8 +660,12 @@ config SYSFS_DEPRECATED
660 depends on SYSFS 660 depends on SYSFS
661 default n 661 default n
662 help 662 help
663 This option switches the layout of the "block" class devices, to not 663 This option adds code that switches the layout of the "block" class
664 show up in /sys/class/block/, but only in /sys/block/. 664 devices, to not show up in /sys/class/block/, but only in
665 /sys/block/.
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.
665 669
666 This option allows new kernels to run on old distributions and tools, 670 This option allows new kernels to run on old distributions and tools,
667 which might get confused by /sys/class/block/. Since 2007/2008 all 671 which might get confused by /sys/class/block/. Since 2007/2008 all
@@ -672,8 +676,22 @@ config SYSFS_DEPRECATED
672 option enabled. 676 option enabled.
673 677
674 Only if you are using a new kernel on an old distribution, you might 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 679 need to say Y here.
676 with your distribution, has not set this option. 680
681config 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
678config RELAY 696config RELAY
679 bool "Kernel->user space relay support (formerly relayfs)" 697 bool "Kernel->user space relay support (formerly relayfs)"