forked from mirrors/linux
		
	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>
This commit is contained in:
		
							parent
							
								
									39aba963d9
								
							
						
					
					
						commit
						e52eec13cd
					
				
					 7 changed files with 68 additions and 30 deletions
				
			
		|  | @ -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 @@ | ||||||
| #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) | ||||||
| 
 | 
 | ||||||
| 	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) | ||||||
| 	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 @@ | ||||||
| #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, | ||||||
| 		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) | ||||||
| 			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) | ||||||
| 	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) | ||||||
| 
 | 
 | ||||||
| 	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) | ||||||
| 	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 {						     \ | ||||||
| 	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_ */ | ||||||
|  |  | ||||||
							
								
								
									
										26
									
								
								init/Kconfig
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								init/Kconfig
									
									
									
									
									
								
							|  | @ -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 | ||||||
| 	  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)" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Andi Kleen
						Andi Kleen