Commit f261ecb2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Move ikconfig to /proc/config.gz

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.
parent f5347e30
...@@ -143,24 +143,24 @@ config IKCONFIG ...@@ -143,24 +143,24 @@ config IKCONFIG
This option enables the complete Linux kernel ".config" file This option enables the complete Linux kernel ".config" file
contents, information on compiler used to build the kernel, contents, information on compiler used to build the kernel,
kernel running when this kernel was built and kernel version 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 of which kernel options are used in a running kernel or in an
on-disk kernel. This information can be extracted from the kernel on-disk kernel. This information can be extracted from the kernel
image file with the script scripts/extract-ikconfig and used as image file with the script scripts/extract-ikconfig and used as
input to rebuild the current kernel or to build another kernel. input to rebuild the current kernel or to build another kernel.
It can also be extracted from a running kernel by reading It can also be extracted from a running kernel by reading
/proc/ikconfig/config and /proc/ikconfig/built_with, if enabled. /proc/config.gz and /proc/config_built_with, if enabled (below).
/proc/ikconfig/config will list the configuration that was used /proc/config.gz will list the configuration that was used
to build the kernel and /proc/ikconfig/built_with will list to build the kernel and /proc/config_built_with will list
information on the compiler and host machine that was used to information on the compiler and host machine that was used to
build the kernel. build the kernel.
config IKCONFIG_PROC 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 depends on IKCONFIG && PROC_FS
---help--- ---help---
This option enables access to kernel configuration file and build This option enables access to kernel configuration file and build
information through /proc/ikconfig. information through /proc/config.gz.
menuconfig EMBEDDED menuconfig EMBEDDED
......
...@@ -18,6 +18,7 @@ obj-$(CONFIG_PM) += power/ ...@@ -18,6 +18,7 @@ obj-$(CONFIG_PM) += power/
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_IKCONFIG) += configs.o
obj-$(CONFIG_IKCONFIG_PROC) += configs.o
ifneq ($(CONFIG_IA64),y) ifneq ($(CONFIG_IA64),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
...@@ -28,12 +29,32 @@ ifneq ($(CONFIG_IA64),y) ...@@ -28,12 +29,32 @@ ifneq ($(CONFIG_IA64),y)
CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer
endif 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 $@ quiet_cmd_ikconfig = IKCFG $@
cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@ cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@
targets += ikconfig.h targets += ikconfig.h
$(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE $(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE
$(call if_changed,ikconfig) $(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)
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
...@@ -35,62 +36,63 @@ ...@@ -35,62 +36,63 @@
/**************************************************/ /**************************************************/
/* the actual current config file */ /* the actual current config file */
/* This one is for extraction from the kernel binary file image. */
#include "ikconfig.h" #include "ikconfig.h"
#ifdef CONFIG_IKCONFIG_PROC #ifdef CONFIG_IKCONFIG_PROC
/* This is the data that can be read from /proc/config.gz. */
#include "config_data.h"
/**************************************************/ /**************************************************/
/* globals and useful constants */ /* globals and useful constants */
static const char IKCONFIG_NAME[] = "ikconfig";
static const char IKCONFIG_VERSION[] = "0.6"; static const char IKCONFIG_VERSION[] = "0.6";
static int ikconfig_size;
static struct proc_dir_entry *ikconfig_dir;
static ssize_t static ssize_t
ikconfig_read(struct file *file, char __user *buf, ikconfig_read_current(struct file *file, char __user *buf,
size_t len, loff_t *offset) size_t len, loff_t * offset)
{ {
loff_t pos = *offset; loff_t pos = *offset;
ssize_t count; ssize_t count;
if (pos >= ikconfig_size) if (pos >= kernel_config_data_size)
return 0; return 0;
count = min(len, (size_t)(ikconfig_size - pos)); count = min(len, (size_t)(kernel_config_data_size - pos));
if(copy_to_user(buf, ikconfig_config + pos, count)) if(copy_to_user(buf, kernel_config_data + pos, count))
return -EFAULT; return -EFAULT;
*offset += count; *offset += count;
return count; return count;
} }
static struct file_operations config_fops = { static struct file_operations ikconfig_file_ops = {
.owner = THIS_MODULE, .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 */ /* 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", "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; 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, .owner = THIS_MODULE,
.open = built_with_open, .open = build_info_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
...@@ -99,65 +101,51 @@ static struct file_operations builtwith_fops = { ...@@ -99,65 +101,51 @@ static struct file_operations builtwith_fops = {
/***************************************************/ /***************************************************/
/* ikconfig_init: start up everything we need to */ /* ikconfig_init: start up everything we need to */
int __init static int __init ikconfig_init(void)
ikconfig_init(void)
{ {
struct proc_dir_entry *entry; 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); 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 */ /* 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) if (!entry)
goto leave2; goto leave;
entry->proc_fops = &config_fops; entry->proc_fops = &ikconfig_file_ops;
entry->size = ikconfig_size = strlen(ikconfig_config); entry->size = kernel_config_data_size;
/* create the "built with" file */ /* create the "build_info" file */
entry = create_proc_entry("built_with", S_IFREG | S_IRUGO, entry = create_proc_entry("config_build_info",
ikconfig_dir); S_IFREG | S_IRUGO, &proc_root);
if (!entry) if (!entry)
goto leave3; goto leave_gz;
entry->proc_fops = &builtwith_fops; entry->proc_fops = &build_info_file_ops;
return 0; return 0;
leave3: leave_gz:
/* remove the file from proc */ /* remove the file from proc */
remove_proc_entry("config", ikconfig_dir); remove_proc_entry("config.gz", &proc_root);
leave2:
/* remove the ikconfig directory */
remove_proc_entry(IKCONFIG_NAME, NULL);
leave: leave:
return -ENOMEM; return -ENOMEM;
} }
/***************************************************/ /***************************************************/
/* cleanup_ikconfig: clean up our mess */ /* ikconfig_cleanup: clean up our mess */
static void static void __exit ikconfig_cleanup(void)
cleanup_ikconfig(void)
{ {
/* remove the files */ /* remove the files */
remove_proc_entry("config", ikconfig_dir); remove_proc_entry("config.gz", &proc_root);
remove_proc_entry("built_with", ikconfig_dir); remove_proc_entry("config_build_info", &proc_root);
/* remove the ikconfig directory */
remove_proc_entry(IKCONFIG_NAME, NULL);
} }
module_init(ikconfig_init); module_init(ikconfig_init);
module_exit(cleanup_ikconfig); module_exit(ikconfig_cleanup);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Randy Dunlap"); MODULE_AUTHOR("Randy Dunlap");
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
# conmakehash: Create arrays for initializing the kernel console tables # conmakehash: Create arrays for initializing the kernel console tables
host-progs := fixdep split-include conmakehash docproc kallsyms modpost \ host-progs := fixdep split-include conmakehash docproc kallsyms modpost \
mk_elfconfig pnmtologo mk_elfconfig pnmtologo bin2c
always := $(host-progs) empty.o always := $(host-progs) empty.o
modpost-objs := modpost.o file2alias.o modpost-objs := modpost.o file2alias.o
......
#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;
}
...@@ -66,15 +66,13 @@ echo \ ...@@ -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 " \"`uname -s` `uname -r` `uname -v` `uname -m`\";"
echo "#endif"
echo echo
kernel_version $makefile kernel_version $makefile
echo "#ifdef CONFIG_IKCONFIG_PROC" echo "static char const ikconfig_config[] __attribute__((unused)) = "
echo "static char *ikconfig_config = "
echo "#else"
echo "static char *ikconfig_config __initdata __attribute__((unused)) = "
echo "#endif"
echo "\"CONFIG_BEGIN=n\\n\\" echo "\"CONFIG_BEGIN=n\\n\\"
echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `" echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `"
echo "CONFIG_END=n\\n\";" echo "CONFIG_END=n\\n\";"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment