]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.suse/supported-flag-sysfs
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / supported-flag-sysfs
diff --git a/src/patches/suse-2.6.27.31/patches.suse/supported-flag-sysfs b/src/patches/suse-2.6.27.31/patches.suse/supported-flag-sysfs
new file mode 100644 (file)
index 0000000..4a85292
--- /dev/null
@@ -0,0 +1,177 @@
+From: Jeff Mahoney <jeffm@suse.com>
+Subject: Export supported status via sysfs
+
+ This patch adds a /sys/kernel/supported file indicating the supportability
+ status of the entire kernel.
+
+ It also adds a /sys/module/<module>/supported file indicating the
+ supportability status of individual modules.
+
+ This is useful because it can be used to obtain the supported status
+ of a running system without current modules (ie: immediately after
+ a kernel update but before a reboot) and without generating an oops.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+
+ include/linux/module.h |    1 
+ kernel/ksysfs.c        |   18 ++++++++++++
+ kernel/module.c        |   70 ++++++++++++++++++++++++++++++++-----------------
+ 3 files changed, 66 insertions(+), 23 deletions(-)
+
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -363,6 +363,7 @@ static inline int module_is_live(struct 
+ struct module *module_text_address(unsigned long addr);
+ struct module *__module_text_address(unsigned long addr);
+ int is_module_address(unsigned long addr);
++const char *supported_printable(int taint);
+ /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
+    symnum out of range. */
+--- a/kernel/ksysfs.c
++++ b/kernel/ksysfs.c
+@@ -104,6 +104,23 @@ static struct bin_attribute notes_attr =
+ struct kobject *kernel_kobj;
+ EXPORT_SYMBOL_GPL(kernel_kobj);
++const char *supported_printable(int taint)
++{
++      if (taint & TAINT_NO_SUPPORT)
++              return "No";
++      else if (taint & TAINT_EXTERNAL_SUPPORT)
++              return "Yes, External";
++      else
++              return "Yes";
++}
++
++static ssize_t supported_show(struct kobject *kobj,
++                            struct kobj_attribute *attr, char *buf)
++{
++      return sprintf(buf, "%s\n", supported_printable(tainted));
++}
++KERNEL_ATTR_RO(supported);
++
+ static struct attribute * kernel_attrs[] = {
+ #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
+       &uevent_seqnum_attr.attr,
+@@ -114,6 +131,7 @@ static struct attribute * kernel_attrs[]
+       &kexec_crash_loaded_attr.attr,
+       &vmcoreinfo_attr.attr,
+ #endif
++      &supported_attr.attr,
+       NULL
+ };
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -922,10 +922,36 @@ static struct module_attribute initstate
+       .show = show_initstate,
+ };
++static void setup_modinfo_supported(struct module *mod, const char *s)
++{
++      if (!s) {
++              mod->taints |= TAINT_NO_SUPPORT;
++              return;
++      }
++
++      if (strcmp(s, "external") == 0)
++              mod->taints |= TAINT_EXTERNAL_SUPPORT;
++      else if (strcmp(s, "yes"))
++              mod->taints |= TAINT_NO_SUPPORT;
++}
++
++static ssize_t show_modinfo_supported(struct module_attribute *mattr,
++                      struct module *mod, char *buffer)
++{
++      return sprintf(buffer, "%s\n", supported_printable(mod->taints));
++}
++
++static struct module_attribute modinfo_supported = {
++      .attr = { .name = "supported", .mode = 0444 },
++      .show = show_modinfo_supported,
++      .setup = setup_modinfo_supported,
++};
++
+ static struct module_attribute *modinfo_attrs[] = {
+       &modinfo_version,
+       &modinfo_srcversion,
+       &initstate,
++      &modinfo_supported,
+ #ifdef CONFIG_MODULE_UNLOAD
+       &refcnt,
+ #endif
+@@ -1820,7 +1846,6 @@ static noinline struct module *load_modu
+       Elf_Ehdr *hdr;
+       Elf_Shdr *sechdrs;
+       char *secstrings, *args, *modmagic, *strtab = NULL;
+-      char *supported;
+       unsigned int i;
+       unsigned int symindex = 0;
+       unsigned int strindex = 0;
+@@ -1975,28 +2000,6 @@ static noinline struct module *load_modu
+               goto free_hdr;
+       }
+-      supported = get_modinfo(sechdrs, infoindex, "supported");
+-      if (supported) {
+-              if (!strcmp(supported, "external"))
+-                      add_taint_module(mod, TAINT_EXTERNAL_SUPPORT);
+-              else if (strcmp(supported, "yes"))
+-                      supported = NULL;
+-      }
+-      if (!supported) {
+-              if (unsupported == 0) {
+-                      printk(KERN_WARNING "%s: module not supported by "
+-                             "Novell, refusing to load. To override, echo "
+-                             "1 > /proc/sys/kernel/unsupported\n", mod->name);
+-                      err = -ENOEXEC;
+-                      goto free_hdr;
+-              }
+-              add_taint_module(mod, TAINT_NO_SUPPORT);
+-              if (unsupported == 1) {
+-                      printk(KERN_WARNING "%s: module not supported by "
+-                             "Novell, setting U taint flag.\n", mod->name);
+-              }
+-      }
+-
+       /* Now copy in args */
+       args = strndup_user(uargs, ~0UL >> 1);
+       if (IS_ERR(args)) {
+@@ -2256,6 +2259,26 @@ static noinline struct module *load_modu
+       add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
+       add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
++      /* We don't use add_taint() here because it also disables lockdep. */
++      if (mod->taints & TAINT_EXTERNAL_SUPPORT)
++              tainted |= TAINT_EXTERNAL_SUPPORT;
++      else if (mod->taints == TAINT_NO_SUPPORT) {
++              if (unsupported == 0) {
++                      printk(KERN_WARNING "%s: module not supported by "
++                             "Novell, refusing to load. To override, echo "
++                             "1 > /proc/sys/kernel/unsupported\n", mod->name);
++                      err = -ENOEXEC;
++                      goto free_hdr;
++              }
++              tainted |= TAINT_NO_SUPPORT;
++              if (unsupported == 1) {
++                      printk(KERN_WARNING "%s: module is not supported by "
++                             "Novell. Novell Technical Services may decline "
++                             "your support request if it involves a kernel "
++                             "fault.\n", mod->name);
++              }
++      }
++
+       /* Size of section 0 is 0, so this works well if no unwind info. */
+       mod->unwind_info = unwind_add_table(mod,
+                                           (void *)sechdrs[unwindex].sh_addr,
+@@ -2735,6 +2758,7 @@ void print_modules(void)
+       if (last_unloaded_module[0])
+               printk(" [last unloaded: %s]", last_unloaded_module);
+       printk("\n");
++      printk("Supported: %s\n", supported_printable(tainted));
+ }
+ #ifdef CONFIG_MODVERSIONS