[PATCH] Move ikconfig to /proc/config.gz
authorAndrew Morton <akpm@osdl.org>
Tue, 9 Sep 2003 17:19:11 +0000 (10:19 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Tue, 9 Sep 2003 17:19:11 +0000 (10:19 -0700)
From: "Randy.Dunlap" <randy.dunlap@verizon.net>

The SuSE kernels place their ikconfig info at /proc/config.gz: in a
different place, and compressed.  We thought it was a good idea to do it
that way in 2.6 as well.

- gzip the /proc config file, put it in /proc/config.gz;

- Based on a SuSE patch by Oliver Xymoron <oxymoron@waste.org>, which was
  derived from a patch by Nicholas Leon <nicholas@binary9.net>

- change /proc/ikconfig/built_with to /proc/config_build_info;

- cleanup ikconfig init/exit entry points (static, __init, __exit);

- Makefile help from Sam Ravnborg;

DESC
ikconfig cleanup
EDESC
From: Stephen Hemminger <shemminger@osdl.org>

Simplify and cleanup the code:
- use single interface to seq_file where possible
- don't need to do as much of the /proc interface, only read
- use copy_to_user to avoid char at a time copy
- remove unneccesary globals
- use const char[] rather than const char * where possible.

Didn't change the version since interface doesn't change.

init/Kconfig
kernel/Makefile
kernel/configs.c
scripts/Makefile
scripts/bin2c.c [new file with mode: 0644]
scripts/mkconfigs

index cc85e85..3831775 100644 (file)
@@ -143,24 +143,24 @@ config IKCONFIG
          This option enables the complete Linux kernel ".config" file
          contents, information on compiler used to build the kernel,
          kernel running when this kernel was built and kernel version
-         from Makefile to be saved in kernel. It provides documentation
+         from Makefile to be saved in the kernel. It provides documentation
          of which kernel options are used in a running kernel or in an
          on-disk kernel.  This information can be extracted from the kernel
          image file with the script scripts/extract-ikconfig and used as
          input to rebuild the current kernel or to build another kernel.
          It can also be extracted from a running kernel by reading
-         /proc/ikconfig/config and /proc/ikconfig/built_with, if enabled.
-         /proc/ikconfig/config will list the configuration that was used
-         to build the kernel and /proc/ikconfig/built_with will list
+         /proc/config.gz and /proc/config_built_with, if enabled (below).
+         /proc/config.gz will list the configuration that was used
+         to build the kernel and /proc/config_built_with will list
          information on the compiler and host machine that was used to
          build the kernel.
 
 config IKCONFIG_PROC
-       bool "Enable access to .config through /proc/ikconfig"
+       bool "Enable access to .config through /proc/config.gz"
        depends on IKCONFIG && PROC_FS
        ---help---
          This option enables access to kernel configuration file and build
-         information through /proc/ikconfig.
+         information through /proc/config.gz.
 
 
 menuconfig EMBEDDED
index 638a2f6..c63c8ea 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_PM) += power/
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_IKCONFIG) += configs.o
+obj-$(CONFIG_IKCONFIG_PROC) += configs.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
@@ -28,12 +29,32 @@ ifneq ($(CONFIG_IA64),y)
 CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer
 endif
 
+# configs.o uses generated files - dependecies must be listed explicitly
+$(obj)/configs.o: $(obj)/ikconfig.h
+
+ifdef CONFIG_IKCONFIG_PROC
+$(obj)/configs.o: $(obj)/config_data.h
+endif
+
+# ikconfig.h contains all the selected config entries - generated
+# from top-level Makefile and .config. Info from ikconfig.h can
+# be extracted from the kernel binary.
+
 quiet_cmd_ikconfig = IKCFG   $@
       cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@
 
 targets += ikconfig.h
-
 $(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE
        $(call if_changed,ikconfig)
 
-$(obj)/configs.o: $(obj)/ikconfig.h
+# config_data.h contains the same information as ikconfig.h but gzipped.
+# Info from config_data can be extracted from /proc/config*
+targets += config_data.gz
+$(obj)/config_data.gz: .config FORCE
+       $(call if_changed,gzip)
+
+quiet_cmd_ikconfiggz = IKCFG   $@
+      cmd_ikconfiggz = cat $< | scripts/bin2c kernel_config_data > $@
+targets += config_data.h
+$(obj)/config_data.h: $(obj)/config_data.gz FORCE
+       $(call if_changed,ikconfiggz)
index 7faf683..6a5c0c9 100644 (file)
@@ -23,6 +23,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 /**************************************************/
 /* the actual current config file                 */
 
+/* This one is for extraction from the kernel binary file image. */
 #include "ikconfig.h"
 
 #ifdef CONFIG_IKCONFIG_PROC
 
+/* This is the data that can be read from /proc/config.gz. */
+#include "config_data.h"
+
 /**************************************************/
 /* globals and useful constants                   */
 
-static const char IKCONFIG_NAME[] = "ikconfig";
 static const char IKCONFIG_VERSION[] = "0.6";
 
-static int ikconfig_size;
-static struct proc_dir_entry *ikconfig_dir;
-
 static ssize_t
-ikconfig_read(struct file *file, char __user *buf, 
-                  size_t len, loff_t *offset)
+ikconfig_read_current(struct file *file, char __user *buf,
+                     size_t len, loff_t * offset)
 {
        loff_t pos = *offset;
        ssize_t count;
-       
-       if (pos >= ikconfig_size)
+
+       if (pos >= kernel_config_data_size)
                return 0;
 
-       count = min(len, (size_t)(ikconfig_size - pos));
-       if(copy_to_user(buf, ikconfig_config + pos, count))
+       count = min(len, (size_t)(kernel_config_data_size - pos));
+       if(copy_to_user(buf, kernel_config_data + pos, count))
                return -EFAULT;
 
        *offset += count;
        return count;
 }
 
-static struct file_operations config_fops = {
+static struct file_operations ikconfig_file_ops = {
        .owner = THIS_MODULE,
-       .read  = ikconfig_read,
+       .read = ikconfig_read_current,
 };
 
+
 /***************************************************/
-/* built_with_show: let people read the info  */
+/* build_info_show: let people read the info       */
 /* we have on the tools used to build this kernel  */
 
-static int builtwith_show(struct seq_file *seq, void *v)
+static int build_info_show(struct seq_file *seq, void *v)
 {
-       seq_printf(seq, 
+       seq_printf(seq,
                   "Kernel:    %s\nCompiler:  %s\nVersion_in_Makefile: %s\n",
-                  ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE);
+                  ikconfig_build_info, LINUX_COMPILER, UTS_RELEASE);
        return 0;
 }
 
-static int built_with_open(struct inode *inode, struct file *file)
+static int build_info_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, builtwith_show, PDE(inode)->data);
+       return single_open(file, build_info_show, PDE(inode)->data);
 }
-       
-static struct file_operations builtwith_fops = {
+
+static struct file_operations build_info_file_ops = {
        .owner = THIS_MODULE,
-       .open  = built_with_open,
+       .open  = build_info_open,
        .read  = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
-};     
+};
 
 /***************************************************/
 /* ikconfig_init: start up everything we need to */
 
-int __init
-ikconfig_init(void)
+static int __init ikconfig_init(void)
 {
        struct proc_dir_entry *entry;
 
-       printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n",
+       printk(KERN_INFO "ikconfig %s with /proc/config*\n",
               IKCONFIG_VERSION);
 
-       /* create the ikconfig directory */
-       ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL);
-       if (ikconfig_dir == NULL) 
-               goto leave;
-       ikconfig_dir->owner = THIS_MODULE;
-
        /* create the current config file */
-       entry = create_proc_entry("config", S_IFREG | S_IRUGO, ikconfig_dir);
+       entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
+                                 &proc_root);
        if (!entry)
-               goto leave2;
+               goto leave;
 
-       entry->proc_fops = &config_fops;
-       entry->size = ikconfig_size = strlen(ikconfig_config);
+       entry->proc_fops = &ikconfig_file_ops;
+       entry->size = kernel_config_data_size;
 
-       /* create the "built with" file */
-       entry = create_proc_entry("built_with", S_IFREG | S_IRUGO,
-                                 ikconfig_dir);
+       /* create the "build_info" file */
+       entry = create_proc_entry("config_build_info",
+                                 S_IFREG | S_IRUGO, &proc_root);
        if (!entry)
-               goto leave3;
-       entry->proc_fops = &builtwith_fops;
+               goto leave_gz;
+       entry->proc_fops = &build_info_file_ops;
 
        return 0;
 
-leave3:
+leave_gz:
        /* remove the file from proc */
-       remove_proc_entry("config", ikconfig_dir);
-
-leave2:
-       /* remove the ikconfig directory */
-       remove_proc_entry(IKCONFIG_NAME, NULL);
+       remove_proc_entry("config.gz", &proc_root);
 
 leave:
        return -ENOMEM;
 }
 
 /***************************************************/
-/* cleanup_ikconfig: clean up our mess           */
+/* ikconfig_cleanup: clean up our mess           */
 
-static void
-cleanup_ikconfig(void)
+static void __exit ikconfig_cleanup(void)
 {
        /* remove the files */
-       remove_proc_entry("config", ikconfig_dir);
-       remove_proc_entry("built_with", ikconfig_dir);
-
-       /* remove the ikconfig directory */
-       remove_proc_entry(IKCONFIG_NAME, NULL);
+       remove_proc_entry("config.gz", &proc_root);
+       remove_proc_entry("config_build_info", &proc_root);
 }
 
 module_init(ikconfig_init);
-module_exit(cleanup_ikconfig);
+module_exit(ikconfig_cleanup);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Randy Dunlap");
index 007f3b1..c03384c 100644 (file)
@@ -9,7 +9,7 @@
 # conmakehash:  Create arrays for initializing the kernel console tables
 
 host-progs     := fixdep split-include conmakehash docproc kallsyms modpost \
-                  mk_elfconfig pnmtologo
+                  mk_elfconfig pnmtologo bin2c
 always         := $(host-progs) empty.o
 
 modpost-objs   := modpost.o file2alias.o
diff --git a/scripts/bin2c.c b/scripts/bin2c.c
new file mode 100644 (file)
index 0000000..3f900a1
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+       int ch, total=0;
+
+       if (argc > 1)
+               printf("const char %s[] %s=\n",
+                       argv[1], argc > 2 ? argv[2] : "");
+
+       do {
+               printf("\t\"");
+               while ((ch = getchar()) != EOF)
+               {
+                       total++;
+                       printf("\\x%02x",ch);
+                       if (total % 16 == 0)
+                               break;
+               }
+               printf("\"\n");
+       } while (ch != EOF);
+
+       if (argc > 1)
+               printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
+
+       return 0;
+}
index 7d5a6c2..fc9c3dd 100755 (executable)
@@ -66,15 +66,13 @@ echo \
  *
  */"
 
-echo "static char *ikconfig_built_with ="
+echo "#ifdef CONFIG_IKCONFIG_PROC"
+echo "static char const ikconfig_build_info[] ="
 echo "    \"`uname -s` `uname -r` `uname -v` `uname -m`\";"
+echo "#endif"
 echo
 kernel_version $makefile
-echo "#ifdef CONFIG_IKCONFIG_PROC"
-echo "static char *ikconfig_config = "
-echo "#else"
-echo "static char *ikconfig_config __initdata __attribute__((unused)) = "
-echo "#endif"
+echo "static char const ikconfig_config[] __attribute__((unused)) = "
 echo "\"CONFIG_BEGIN=n\\n\\"
 echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `"
 echo "CONFIG_END=n\\n\";"