From: Chuck Anderson Date: Sat, 7 Jan 2012 00:12:49 +0000 (-0800) Subject: Partial revert of mainline removal of deprecated sysfs interface for 13568528 X-Git-Tag: v2.6.39-400.9.0~687 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=0c01ee13c10ea3360d517f46cfbe26fd09ee1819;p=users%2Fjedix%2Flinux-maple.git Partial revert of mainline removal of deprecated sysfs interface for 13568528 Jan. 06, 2012 Oracle bug 13568528 Patch written by Andrew Thomas Ported by Chuck Anderson This patch partialy reverts the removal in mainline of a deprecated sysfs interface needed by the OVM3.0.4 UEK2 based dom0 kernel when it is used to install OVM3.0.4 Comments from Andrew: The problem is that in newer kernels, even with the CONFIG_SYSFS_DEPRECATED[_V2] flags set, some nodes have been removed so to tools looking in sysfs, pieces are missing. This breaks anaconda (actually kudzu) for us. For OVM3 we use the dom0 kernel as the install kernel, so we need UEK2 to provide the right "shape" sysfs. This isn't an issue for OL because you use the old RHEL kernel to install UEK1/2]. That said, this issue affects more than us. As Joe Jin points out, bug 13100678, required kudzu fixes for eth devices. Arguably the OVM3 anaconda issue can also be fixed in kudzu, but what no one knows is if the missing sysfs nodes are symptoms of a wider set of tools related problems and therefore whether the correct fix is to revert sysfs changes in UEK2 so that the sysfs it presents is isomorphic to what 2.6.18 based kernels provide. A "better" set of tools would be from 6uX, but in order to get those installed/upgraded on OVM3 is not a trivial task because the system customers have already installed is 5u5 based. We have other tools in dom0 [eg our agent] which "know" about the old flavour of sysfs and these would need porting. You either change the kernel OR you change all the tools that rely on sysfs... the problem is that customers can install there own tools on OL5. Signed-off-by: Chuck Anderson --- diff --git a/drivers/base/class.c b/drivers/base/class.c index 4f1df2e8fd74..6fcb15b3f73f 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -276,6 +276,25 @@ void class_destroy(struct class *cls) class_unregister(cls); } +#ifdef CONFIG_SYSFS_DEPRECATED +char *make_class_name(const char *name, struct kobject *kobj) +{ + char *class_name; + int size; + + size = strlen(name) + strlen(kobject_name(kobj)) + 2; + + class_name = kmalloc(size, GFP_KERNEL); + if (!class_name) + return NULL; + + strcpy(class_name, name); + strcat(class_name, ":"); + strcat(class_name, kobject_name(kobj)); + return class_name; +} +#endif + /** * class_dev_iter_init - initialize class device iterator * @iter: class iterator to initialize diff --git a/drivers/base/core.c b/drivers/base/core.c index 78445f40c430..7c2bfbf27c68 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -759,6 +759,29 @@ static int device_add_class_symlinks(struct device *dev) goto out_subsys; } +#ifdef CONFIG_SYSFS_DEPRECATED + if (dev->parent && device_is_not_partition(dev)) { + struct device *parent = dev->parent; + char *class_name; + + /* + * stacked class devices have the 'device' link + * pointing to the bus device instead of the parent + */ + while (parent->class && !parent->bus && parent->parent) + parent = parent->parent; + + class_name = make_class_name(dev->class->name, + &dev->kobj); + if (class_name) + error = sysfs_create_link(&dev->parent->kobj, + &dev->kobj, class_name); + kfree(class_name); + if (error) + goto out_subsys; + } +#endif + #ifdef CONFIG_BLOCK /* /sys/block has directories and does not need symlinks */ if (sysfs_deprecated && dev->class == &block_class) @@ -787,6 +810,18 @@ static void device_remove_class_symlinks(struct device *dev) if (!dev->class) return; +#ifdef CONFIG_SYSFS_DEPRECATED + if (dev->parent && device_is_not_partition(dev)) { + char *class_name; + + class_name = make_class_name(dev->class->name, &dev->kobj); + if (class_name) { + sysfs_remove_link(&dev->parent->kobj, class_name); + kfree(class_name); + } + sysfs_remove_link(&dev->kobj, "device"); + } +#endif if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "subsystem");