aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-07-02 12:26:30 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-07-02 12:26:30 -0700
commitf18b78199b11d1e0e3ed504deed9309aff6d40f9 (patch)
tree8218df2f2385caa2480f1fe8b57cae08412b3d20
parent7a954d574303481190b6e377607851ff31c6c2c9 (diff)
downloadlinux-2.6-klibc-clean-f18b78199b11d1e0e3ed504deed9309aff6d40f9.tar.gz
[klibc] Remove in-kernel root-mounting code
This removes the root mounting code from the kernel proper. This includes ip autoconfiguration, nfsroot, and name_to_dev_t(). Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/i386/kernel/setup.c8
-rw-r--r--arch/x86_64/kernel/setup.c7
-rw-r--r--fs/Kconfig14
-rw-r--r--fs/nfs/Makefile1
-rw-r--r--fs/nfs/mount_clnt.c191
-rw-r--r--fs/nfs/nfsroot.c525
-rw-r--r--include/linux/mount.h1
-rw-r--r--init/Makefile7
-rw-r--r--init/do_mounts.c433
-rw-r--r--init/do_mounts.h77
-rw-r--r--init/do_mounts_initrd.c123
-rw-r--r--init/do_mounts_md.c285
-rw-r--r--init/do_mounts_rd.c429
-rw-r--r--init/initramfs.c3
-rw-r--r--init/main.c45
-rw-r--r--net/ipv4/Makefile1
-rw-r--r--net/ipv4/ipconfig.c1510
17 files changed, 21 insertions, 3639 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 08c00d20f1623c..cc79fa7bf3c7ca 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -149,7 +149,6 @@ struct e820map e820;
extern void early_cpu_init(void);
extern void generic_apic_probe(char *);
-extern int root_mountflags;
unsigned long saved_videomode;
@@ -1469,11 +1468,6 @@ void __init setup_arch(char **cmdline_p)
}
bootloader_type = LOADER_TYPE;
-#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
ARCH_SETUP
if (efi_enabled)
efi_init();
@@ -1484,8 +1478,6 @@ void __init setup_arch(char **cmdline_p)
copy_edd();
- if (!MOUNT_ROOT_RDONLY)
- root_mountflags &= ~MS_RDONLY;
init_mm.start_code = (unsigned long) _text;
init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata;
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 0925518b58d06c..788735e41bbd98 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -529,16 +529,9 @@ void __init setup_arch(char **cmdline_p)
saved_video_mode = SAVED_VIDEO_MODE;
bootloader_type = LOADER_TYPE;
-#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
setup_memory_region();
copy_edd();
- if (!MOUNT_ROOT_RDONLY)
- root_mountflags &= ~MS_RDONLY;
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
diff --git a/fs/Kconfig b/fs/Kconfig
index 53f5c6d6112127..01f084e90e8d2d 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1567,20 +1567,6 @@ config NFSD_TCP
TCP connections usually perform better than the default UDP when
the network is lossy or congested. If unsure, say Y.
-config ROOT_NFS
- bool "Root file system on NFS"
- depends on NFS_FS=y && IP_PNP
- help
- If you want your Linux box to mount its whole root file system (the
- one containing the directory /) from some other computer over the
- net via NFS (presumably because your box doesn't have a hard disk),
- say Y. Read <file:Documentation/nfsroot.txt> for details. It is
- likely that in this case, you also want to say Y to "Kernel level IP
- autoconfiguration" so that your box can discover its network address
- at boot time.
-
- Most people say N here.
-
config LOCKD
tristate
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 0b572a0c19678a..c7d639251b579f 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_NFS_FS) += nfs.o
nfs-y := dir.o file.o inode.o super.o nfs2xdr.o pagelist.o \
proc.o read.o symlink.o unlink.o write.o \
namespace.o
-nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
deleted file mode 100644
index 445abb4d42146e..00000000000000
--- a/fs/nfs/mount_clnt.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * linux/fs/nfs/mount_clnt.c
- *
- * MOUNT client to support NFSroot.
- *
- * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
- */
-
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/uio.h>
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/sunrpc/xprt.h>
-#include <linux/sunrpc/sched.h>
-#include <linux/nfs_fs.h>
-
-#ifdef RPC_DEBUG
-# define NFSDBG_FACILITY NFSDBG_ROOT
-#endif
-
-/*
-#define MOUNT_PROGRAM 100005
-#define MOUNT_VERSION 1
-#define MOUNT_MNT 1
-#define MOUNT_UMNT 3
- */
-
-static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *,
- int, int);
-static struct rpc_program mnt_program;
-
-struct mnt_fhstatus {
- unsigned int status;
- struct nfs_fh * fh;
-};
-
-/*
- * Obtain an NFS file handle for the given host and path
- */
-int
-nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
- int version, int protocol)
-{
- struct rpc_clnt *mnt_clnt;
- struct mnt_fhstatus result = {
- .fh = fh
- };
- struct rpc_message msg = {
- .rpc_argp = path,
- .rpc_resp = &result,
- };
- char hostname[32];
- int status;
-
- dprintk("NFS: nfs_mount(%08x:%s)\n",
- (unsigned)ntohl(addr->sin_addr.s_addr), path);
-
- sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
- mnt_clnt = mnt_create(hostname, addr, version, protocol);
- if (IS_ERR(mnt_clnt))
- return PTR_ERR(mnt_clnt);
-
- if (version == NFS_MNT3_VERSION)
- msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
- else
- msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT];
-
- status = rpc_call_sync(mnt_clnt, &msg, 0);
- return status < 0? status : (result.status? -EACCES : 0);
-}
-
-static struct rpc_clnt *
-mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
- int protocol)
-{
- struct rpc_xprt *xprt;
- struct rpc_clnt *clnt;
-
- xprt = xprt_create_proto(protocol, srvaddr, NULL);
- if (IS_ERR(xprt))
- return (struct rpc_clnt *)xprt;
-
- clnt = rpc_create_client(xprt, hostname,
- &mnt_program, version,
- RPC_AUTH_UNIX);
- if (!IS_ERR(clnt)) {
- clnt->cl_softrtry = 1;
- clnt->cl_oneshot = 1;
- clnt->cl_intr = 1;
- }
- return clnt;
-}
-
-/*
- * XDR encode/decode functions for MOUNT
- */
-static int
-xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
-{
- p = xdr_encode_string(p, path);
-
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
-{
- struct nfs_fh *fh = res->fh;
-
- if ((res->status = ntohl(*p++)) == 0) {
- fh->size = NFS2_FHSIZE;
- memcpy(fh->data, p, NFS2_FHSIZE);
- }
- return 0;
-}
-
-static int
-xdr_decode_fhstatus3(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
-{
- struct nfs_fh *fh = res->fh;
-
- if ((res->status = ntohl(*p++)) == 0) {
- int size = ntohl(*p++);
- if (size <= NFS3_FHSIZE) {
- fh->size = size;
- memcpy(fh->data, p, size);
- } else
- res->status = -EBADHANDLE;
- }
- return 0;
-}
-
-#define MNT_dirpath_sz (1 + 256)
-#define MNT_fhstatus_sz (1 + 8)
-
-static struct rpc_procinfo mnt_procedures[] = {
-[MNTPROC_MNT] = {
- .p_proc = MNTPROC_MNT,
- .p_encode = (kxdrproc_t) xdr_encode_dirpath,
- .p_decode = (kxdrproc_t) xdr_decode_fhstatus,
- .p_bufsiz = MNT_dirpath_sz << 2,
- .p_statidx = MNTPROC_MNT,
- .p_name = "MOUNT",
- },
-};
-
-static struct rpc_procinfo mnt3_procedures[] = {
-[MOUNTPROC3_MNT] = {
- .p_proc = MOUNTPROC3_MNT,
- .p_encode = (kxdrproc_t) xdr_encode_dirpath,
- .p_decode = (kxdrproc_t) xdr_decode_fhstatus3,
- .p_bufsiz = MNT_dirpath_sz << 2,
- .p_statidx = MOUNTPROC3_MNT,
- .p_name = "MOUNT",
- },
-};
-
-
-static struct rpc_version mnt_version1 = {
- .number = 1,
- .nrprocs = 2,
- .procs = mnt_procedures
-};
-
-static struct rpc_version mnt_version3 = {
- .number = 3,
- .nrprocs = 2,
- .procs = mnt3_procedures
-};
-
-static struct rpc_version * mnt_version[] = {
- NULL,
- &mnt_version1,
- NULL,
- &mnt_version3,
-};
-
-static struct rpc_stat mnt_stats;
-
-static struct rpc_program mnt_program = {
- .name = "mount",
- .number = NFS_MNT_PROGRAM,
- .nrvers = ARRAY_SIZE(mnt_version),
- .version = mnt_version,
- .stats = &mnt_stats,
-};
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
deleted file mode 100644
index c0a754ecdee664..00000000000000
--- a/fs/nfs/nfsroot.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * $Id: nfsroot.c,v 1.45 1998/03/07 10:44:46 mj Exp $
- *
- * Copyright (C) 1995, 1996 Gero Kuhlmann <gero@gkminix.han.de>
- *
- * Allow an NFS filesystem to be mounted as root. The way this works is:
- * (1) Use the IP autoconfig mechanism to set local IP addresses and routes.
- * (2) Handle RPC negotiation with the system which replied to RARP or
- * was reported as a boot server by BOOTP or manually.
- * (3) The actual mounting is done later, when init() is running.
- *
- *
- * Changes:
- *
- * Alan Cox : Removed get_address name clash with FPU.
- * Alan Cox : Reformatted a bit.
- * Gero Kuhlmann : Code cleanup
- * Michael Rausch : Fixed recognition of an incoming RARP answer.
- * Martin Mares : (2.0) Auto-configuration via BOOTP supported.
- * Martin Mares : Manual selection of interface & BOOTP/RARP.
- * Martin Mares : Using network routes instead of host routes,
- * allowing the default configuration to be used
- * for normal operation of the host.
- * Martin Mares : Randomized timer with exponential backoff
- * installed to minimize network congestion.
- * Martin Mares : Code cleanup.
- * Martin Mares : (2.1) BOOTP and RARP made configuration options.
- * Martin Mares : Server hostname generation fixed.
- * Gerd Knorr : Fixed wired inode handling
- * Martin Mares : (2.2) "0.0.0.0" addresses from command line ignored.
- * Martin Mares : RARP replies not tested for server address.
- * Gero Kuhlmann : (2.3) Some bug fixes and code cleanup again (please
- * send me your new patches _before_ bothering
- * Linus so that I don' always have to cleanup
- * _afterwards_ - thanks)
- * Gero Kuhlmann : Last changes of Martin Mares undone.
- * Gero Kuhlmann : RARP replies are tested for specified server
- * again. However, it's now possible to have
- * different RARP and NFS servers.
- * Gero Kuhlmann : "0.0.0.0" addresses from command line are
- * now mapped to INADDR_NONE.
- * Gero Kuhlmann : Fixed a bug which prevented BOOTP path name
- * from being used (thanks to Leo Spiekman)
- * Andy Walker : Allow to specify the NFS server in nfs_root
- * without giving a path name
- * Swen Thümmler : Allow to specify the NFS options in nfs_root
- * without giving a path name. Fix BOOTP request
- * for domainname (domainname is NIS domain, not
- * DNS domain!). Skip dummy devices for BOOTP.
- * Jacek Zapala : Fixed a bug which prevented server-ip address
- * from nfsroot parameter from being used.
- * Olaf Kirch : Adapted to new NFS code.
- * Jakub Jelinek : Free used code segment.
- * Marko Kohtala : Fixed some bugs.
- * Martin Mares : Debug message cleanup
- * Martin Mares : Changed to use the new generic IP layer autoconfig
- * code. BOOTP and RARP moved there.
- * Martin Mares : Default path now contains host name instead of
- * host IP address (but host name defaults to IP
- * address anyway).
- * Martin Mares : Use root_server_addr appropriately during setup.
- * Martin Mares : Rewrote parameter parsing, now hopefully giving
- * correct overriding.
- * Trond Myklebust : Add in preliminary support for NFSv3 and TCP.
- * Fix bug in root_nfs_addr(). nfs_data.namlen
- * is NOT for the length of the hostname.
- * Hua Qin : Support for mounting root file system via
- * NFS over TCP.
- * Fabian Frederick: Option parser rebuilt (using parser lib)
-*/
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/nfs.h>
-#include <linux/nfs_fs.h>
-#include <linux/nfs_mount.h>
-#include <linux/in.h>
-#include <linux/major.h>
-#include <linux/utsname.h>
-#include <linux/inet.h>
-#include <linux/root_dev.h>
-#include <net/ipconfig.h>
-#include <linux/parser.h>
-
-/* Define this to allow debugging output */
-#undef NFSROOT_DEBUG
-#define NFSDBG_FACILITY NFSDBG_ROOT
-
-/* Default path we try to mount. "%s" gets replaced by our IP address */
-#define NFS_ROOT "/tftpboot/%s"
-
-/* Parameters passed from the kernel command line */
-static char nfs_root_name[256] __initdata = "";
-
-/* Address of NFS server */
-static __u32 servaddr __initdata = 0;
-
-/* Name of directory to mount */
-static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, };
-
-/* NFS-related data */
-static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
-static int nfs_port __initdata = 0; /* Port to connect to for NFS */
-static int mount_port __initdata = 0; /* Mount daemon port number */
-
-
-/***************************************************************************
-
- Parsing of options
-
- ***************************************************************************/
-
-enum {
- /* Options that take integer arguments */
- Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
- Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
- /* Options that take no arguments */
- Opt_soft, Opt_hard, Opt_intr,
- Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
- Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
- Opt_acl, Opt_noacl,
- /* Error token */
- Opt_err
-};
-
-static match_table_t __initdata tokens = {
- {Opt_port, "port=%u"},
- {Opt_rsize, "rsize=%u"},
- {Opt_wsize, "wsize=%u"},
- {Opt_timeo, "timeo=%u"},
- {Opt_retrans, "retrans=%u"},
- {Opt_acregmin, "acregmin=%u"},
- {Opt_acregmax, "acregmax=%u"},
- {Opt_acdirmin, "acdirmin=%u"},
- {Opt_acdirmax, "acdirmax=%u"},
- {Opt_soft, "soft"},
- {Opt_hard, "hard"},
- {Opt_intr, "intr"},
- {Opt_nointr, "nointr"},
- {Opt_posix, "posix"},
- {Opt_noposix, "noposix"},
- {Opt_cto, "cto"},
- {Opt_nocto, "nocto"},
- {Opt_ac, "ac"},
- {Opt_noac, "noac"},
- {Opt_lock, "lock"},
- {Opt_nolock, "nolock"},
- {Opt_v2, "nfsvers=2"},
- {Opt_v2, "v2"},
- {Opt_v3, "nfsvers=3"},
- {Opt_v3, "v3"},
- {Opt_udp, "proto=udp"},
- {Opt_udp, "udp"},
- {Opt_tcp, "proto=tcp"},
- {Opt_tcp, "tcp"},
- {Opt_acl, "acl"},
- {Opt_noacl, "noacl"},
- {Opt_err, NULL}
-
-};
-
-/*
- * Parse option string.
- */
-
-static int __init root_nfs_parse(char *name, char *buf)
-{
-
- char *p;
- substring_t args[MAX_OPT_ARGS];
- int option;
-
- if (!name)
- return 1;
-
- /* Set the NFS remote path */
- p = strsep(&name, ",");
- if (p[0] != '\0' && strcmp(p, "default") != 0)
- strlcpy(buf, p, NFS_MAXPATHLEN);
-
- while ((p = strsep (&name, ",")) != NULL) {
- int token;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
-
- /* %u tokens only. Beware if you add new tokens! */
- if (token < Opt_soft && match_int(&args[0], &option))
- return 0;
- switch (token) {
- case Opt_port:
- nfs_port = option;
- break;
- case Opt_rsize:
- nfs_data.rsize = option;
- break;
- case Opt_wsize:
- nfs_data.wsize = option;
- break;
- case Opt_timeo:
- nfs_data.timeo = option;
- break;
- case Opt_retrans:
- nfs_data.retrans = option;
- break;
- case Opt_acregmin:
- nfs_data.acregmin = option;
- break;
- case Opt_acregmax:
- nfs_data.acregmax = option;
- break;
- case Opt_acdirmin:
- nfs_data.acdirmin = option;
- break;
- case Opt_acdirmax:
- nfs_data.acdirmax = option;
- break;
- case Opt_soft:
- nfs_data.flags |= NFS_MOUNT_SOFT;
- break;
- case Opt_hard:
- nfs_data.flags &= ~NFS_MOUNT_SOFT;
- break;
- case Opt_intr:
- nfs_data.flags |= NFS_MOUNT_INTR;
- break;
- case Opt_nointr:
- nfs_data.flags &= ~NFS_MOUNT_INTR;
- break;
- case Opt_posix:
- nfs_data.flags |= NFS_MOUNT_POSIX;
- break;
- case Opt_noposix:
- nfs_data.flags &= ~NFS_MOUNT_POSIX;
- break;
- case Opt_cto:
- nfs_data.flags &= ~NFS_MOUNT_NOCTO;
- break;
- case Opt_nocto:
- nfs_data.flags |= NFS_MOUNT_NOCTO;
- break;
- case Opt_ac:
- nfs_data.flags &= ~NFS_MOUNT_NOAC;
- break;
- case Opt_noac:
- nfs_data.flags |= NFS_MOUNT_NOAC;
- break;
- case Opt_lock:
- nfs_data.flags &= ~NFS_MOUNT_NONLM;
- break;
- case Opt_nolock:
- nfs_data.flags |= NFS_MOUNT_NONLM;
- break;
- case Opt_v2:
- nfs_data.flags &= ~NFS_MOUNT_VER3;
- break;
- case Opt_v3:
- nfs_data.flags |= NFS_MOUNT_VER3;
- break;
- case Opt_udp:
- nfs_data.flags &= ~NFS_MOUNT_TCP;
- break;
- case Opt_tcp:
- nfs_data.flags |= NFS_MOUNT_TCP;
- break;
- case Opt_acl:
- nfs_data.flags &= ~NFS_MOUNT_NOACL;
- break;
- case Opt_noacl:
- nfs_data.flags |= NFS_MOUNT_NOACL;
- break;
- default:
- printk(KERN_WARNING "Root-NFS: unknown "
- "option: %s\n", p);
- return 0;
- }
- }
-
- return 1;
-}
-
-/*
- * Prepare the NFS data structure and parse all options.
- */
-static int __init root_nfs_name(char *name)
-{
- static char buf[NFS_MAXPATHLEN] __initdata;
- char *cp;
-
- /* Set some default values */
- memset(&nfs_data, 0, sizeof(nfs_data));
- nfs_port = -1;
- nfs_data.version = NFS_MOUNT_VERSION;
- nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */
- nfs_data.rsize = NFS_DEF_FILE_IO_SIZE;
- nfs_data.wsize = NFS_DEF_FILE_IO_SIZE;
- nfs_data.acregmin = 3;
- nfs_data.acregmax = 60;
- nfs_data.acdirmin = 30;
- nfs_data.acdirmax = 60;
- strcpy(buf, NFS_ROOT);
-
- /* Process options received from the remote server */
- root_nfs_parse(root_server_path, buf);
-
- /* Override them by options set on kernel command-line */
- root_nfs_parse(name, buf);
-
- cp = system_utsname.nodename;
- if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
- printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
- return -1;
- }
- sprintf(nfs_path, buf, cp);
-
- return 1;
-}
-
-
-/*
- * Get NFS server address.
- */
-static int __init root_nfs_addr(void)
-{
- if ((servaddr = root_server_addr) == INADDR_NONE) {
- printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n");
- return -1;
- }
-
- snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
- "%u.%u.%u.%u", NIPQUAD(servaddr));
- return 0;
-}
-
-/*
- * Tell the user what's going on.
- */
-#ifdef NFSROOT_DEBUG
-static void __init root_nfs_print(void)
-{
- printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
- nfs_path, nfs_data.hostname);
- printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
- nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
- printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
- nfs_data.acregmin, nfs_data.acregmax,
- nfs_data.acdirmin, nfs_data.acdirmax);
- printk(KERN_NOTICE "Root-NFS: nfsd port = %d, mountd port = %d, flags = %08x\n",
- nfs_port, mount_port, nfs_data.flags);
-}
-#endif
-
-
-static int __init root_nfs_init(void)
-{
-#ifdef NFSROOT_DEBUG
- nfs_debug |= NFSDBG_ROOT;
-#endif
-
- /*
- * Decode the root directory path name and NFS options from
- * the kernel command line. This has to go here in order to
- * be able to use the client IP address for the remote root
- * directory (necessary for pure RARP booting).
- */
- if (root_nfs_name(nfs_root_name) < 0 ||
- root_nfs_addr() < 0)
- return -1;
-
-#ifdef NFSROOT_DEBUG
- root_nfs_print();
-#endif
-
- return 0;
-}
-
-
-/*
- * Parse NFS server and directory information passed on the kernel
- * command line.
- */
-static int __init nfs_root_setup(char *line)
-{
- ROOT_DEV = Root_NFS;
- if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
- strlcpy(nfs_root_name, line, sizeof(nfs_root_name));
- } else {
- int n = strlen(line) + sizeof(NFS_ROOT) - 1;
- if (n >= sizeof(nfs_root_name))
- line[sizeof(nfs_root_name) - sizeof(NFS_ROOT) - 2] = '\0';
- sprintf(nfs_root_name, NFS_ROOT, line);
- }
- root_server_addr = root_nfs_parse_addr(nfs_root_name);
- return 1;
-}
-
-__setup("nfsroot=", nfs_root_setup);
-
-/***************************************************************************
-
- Routines to actually mount the root directory
-
- ***************************************************************************/
-
-/*
- * Construct sockaddr_in from address and port number.
- */
-static inline void
-set_sockaddr(struct sockaddr_in *sin, __u32 addr, __u16 port)
-{
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = addr;
- sin->sin_port = port;
-}
-
-/*
- * Query server portmapper for the port of a daemon program.
- */
-static int __init root_nfs_getport(int program, int version, int proto)
-{
- struct sockaddr_in sin;
-
- printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
- program, version, NIPQUAD(servaddr));
- set_sockaddr(&sin, servaddr, 0);
- return rpc_getport_external(&sin, program, version, proto);
-}
-
-
-/*
- * Use portmapper to find mountd and nfsd port numbers if not overriden
- * by the user. Use defaults if portmapper is not available.
- * XXX: Is there any nfs server with no portmapper?
- */
-static int __init root_nfs_ports(void)
-{
- int port;
- int nfsd_ver, mountd_ver;
- int nfsd_port, mountd_port;
- int proto;
-
- if (nfs_data.flags & NFS_MOUNT_VER3) {
- nfsd_ver = NFS3_VERSION;
- mountd_ver = NFS_MNT3_VERSION;
- nfsd_port = NFS_PORT;
- mountd_port = NFS_MNT_PORT;
- } else {
- nfsd_ver = NFS2_VERSION;
- mountd_ver = NFS_MNT_VERSION;
- nfsd_port = NFS_PORT;
- mountd_port = NFS_MNT_PORT;
- }
-
- proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
-
- if (nfs_port < 0) {
- if ((port = root_nfs_getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) {
- printk(KERN_ERR "Root-NFS: Unable to get nfsd port "
- "number from server, using default\n");
- port = nfsd_port;
- }
- nfs_port = port;
- dprintk("Root-NFS: Portmapper on server returned %d "
- "as nfsd port\n", port);
- }
- nfs_port = htons(nfs_port);
-
- if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
- printk(KERN_ERR "Root-NFS: Unable to get mountd port "
- "number from server, using default\n");
- port = mountd_port;
- }
- mount_port = htons(port);
- dprintk("Root-NFS: mountd port is %d\n", port);
-
- return 0;
-}
-
-
-/*
- * Get a file handle from the server for the directory which is to be
- * mounted.
- */
-static int __init root_nfs_get_handle(void)
-{
- struct nfs_fh fh;
- struct sockaddr_in sin;
- int status;
- int protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
- IPPROTO_TCP : IPPROTO_UDP;
- int version = (nfs_data.flags & NFS_MOUNT_VER3) ?
- NFS_MNT3_VERSION : NFS_MNT_VERSION;
-
- set_sockaddr(&sin, servaddr, mount_port);
- status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol);
- if (status < 0)
- printk(KERN_ERR "Root-NFS: Server returned error %d "
- "while mounting %s\n", status, nfs_path);
- else {
- nfs_data.root.size = fh.size;
- memcpy(nfs_data.root.data, fh.data, fh.size);
- }
-
- return status;
-}
-
-/*
- * Get the NFS port numbers and file handle, and return the prepared 'data'
- * argument for mount() if everything went OK. Return NULL otherwise.
- */
-void * __init nfs_root_data(void)
-{
- if (root_nfs_init() < 0
- || root_nfs_ports() < 0
- || root_nfs_get_handle() < 0)
- return NULL;
- set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port);
- return (void*)&nfs_data;
-}
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 403d1a97c51290..ef5908e95957d1 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -94,7 +94,6 @@ extern void mark_mounts_for_expiry(struct list_head *mounts);
extern void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts);
extern spinlock_t vfsmount_lock;
-extern dev_t name_to_dev_t(char *name);
#endif
#endif /* _LINUX_MOUNT_H */
diff --git a/init/Makefile b/init/Makefile
index 633a268d270d3c..acfdb2c14c0a42 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -2,14 +2,9 @@
# Makefile for the linux kernel.
#
-obj-y := main.o version.o mounts.o initramfs.o
+obj-y := main.o version.o initramfs.o
obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
-mounts-y := do_mounts.o
-mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o
-mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o
-mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o
-
# files to be removed upon make clean
clean-files := ../include/linux/compile.h
diff --git a/init/do_mounts.c b/init/do_mounts.c
deleted file mode 100644
index 94aeec7aa917fb..00000000000000
--- a/init/do_mounts.c
+++ /dev/null
@@ -1,433 +0,0 @@
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/ctype.h>
-#include <linux/fd.h>
-#include <linux/tty.h>
-#include <linux/suspend.h>
-#include <linux/root_dev.h>
-#include <linux/security.h>
-#include <linux/delay.h>
-#include <linux/mount.h>
-
-#include <linux/nfs_fs.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/nfs_mount.h>
-
-#include "do_mounts.h"
-
-extern int get_filesystem_list(char * buf);
-
-int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */
-
-int root_mountflags = MS_RDONLY | MS_SILENT;
-char * __initdata root_device_name;
-static char __initdata saved_root_name[64];
-
-dev_t ROOT_DEV;
-
-static int __init load_ramdisk(char *str)
-{
- rd_doload = simple_strtol(str,NULL,0) & 3;
- return 1;
-}
-__setup("load_ramdisk=", load_ramdisk);
-
-static int __init readonly(char *str)
-{
- if (*str)
- return 0;
- root_mountflags |= MS_RDONLY;
- return 1;
-}
-
-static int __init readwrite(char *str)
-{
- if (*str)
- return 0;
- root_mountflags &= ~MS_RDONLY;
- return 1;
-}
-
-__setup("ro", readonly);
-__setup("rw", readwrite);
-
-static dev_t try_name(char *name, int part)
-{
- char path[64];
- char buf[32];
- int range;
- dev_t res;
- char *s;
- int len;
- int fd;
- unsigned int maj, min;
-
- /* read device number from .../dev */
-
- sprintf(path, "/sys/block/%s/dev", name);
- fd = sys_open(path, 0, 0);
- if (fd < 0)
- goto fail;
- len = sys_read(fd, buf, 32);
- sys_close(fd);
- if (len <= 0 || len == 32 || buf[len - 1] != '\n')
- goto fail;
- buf[len - 1] = '\0';
- if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
- /*
- * Try the %u:%u format -- see print_dev_t()
- */
- res = MKDEV(maj, min);
- if (maj != MAJOR(res) || min != MINOR(res))
- goto fail;
- } else {
- /*
- * Nope. Try old-style "0321"
- */
- res = new_decode_dev(simple_strtoul(buf, &s, 16));
- if (*s)
- goto fail;
- }
-
- /* if it's there and we are not looking for a partition - that's it */
- if (!part)
- return res;
-
- /* otherwise read range from .../range */
- sprintf(path, "/sys/block/%s/range", name);
- fd = sys_open(path, 0, 0);
- if (fd < 0)
- goto fail;
- len = sys_read(fd, buf, 32);
- sys_close(fd);
- if (len <= 0 || len == 32 || buf[len - 1] != '\n')
- goto fail;
- buf[len - 1] = '\0';
- range = simple_strtoul(buf, &s, 10);
- if (*s)
- goto fail;
-
- /* if partition is within range - we got it */
- if (part < range)
- return res + part;
-fail:
- return 0;
-}
-
-/*
- * Convert a name into device number. We accept the following variants:
- *
- * 1) device number in hexadecimal represents itself
- * 2) /dev/nfs represents Root_NFS (0xff)
- * 3) /dev/<disk_name> represents the device number of disk
- * 4) /dev/<disk_name><decimal> represents the device number
- * of partition - device number of disk plus the partition number
- * 5) /dev/<disk_name>p<decimal> - same as the above, that form is
- * used when disk name of partitioned disk ends on a digit.
- *
- * If name doesn't have fall into the categories above, we return 0.
- * Sysfs is used to check if something is a disk name - it has
- * all known disks under bus/block/devices. If the disk name
- * contains slashes, name of sysfs node has them replaced with
- * bangs. try_name() does the actual checks, assuming that sysfs
- * is mounted on rootfs /sys.
- */
-
-dev_t name_to_dev_t(char *name)
-{
- char s[32];
- char *p;
- dev_t res = 0;
- int part;
-
-#ifdef CONFIG_SYSFS
- int mkdir_err = sys_mkdir("/sys", 0700);
- if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
- goto out;
-#endif
-
- if (strncmp(name, "/dev/", 5) != 0) {
- unsigned maj, min;
-
- if (sscanf(name, "%u:%u", &maj, &min) == 2) {
- res = MKDEV(maj, min);
- if (maj != MAJOR(res) || min != MINOR(res))
- goto fail;
- } else {
- res = new_decode_dev(simple_strtoul(name, &p, 16));
- if (*p)
- goto fail;
- }
- goto done;
- }
- name += 5;
- res = Root_NFS;
- if (strcmp(name, "nfs") == 0)
- goto done;
- res = Root_RAM0;
- if (strcmp(name, "ram") == 0)
- goto done;
-
- if (strlen(name) > 31)
- goto fail;
- strcpy(s, name);
- for (p = s; *p; p++)
- if (*p == '/')
- *p = '!';
- res = try_name(s, 0);
- if (res)
- goto done;
-
- while (p > s && isdigit(p[-1]))
- p--;
- if (p == s || !*p || *p == '0')
- goto fail;
- part = simple_strtoul(p, NULL, 10);
- *p = '\0';
- res = try_name(s, part);
- if (res)
- goto done;
-
- if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
- goto fail;
- p[-1] = '\0';
- res = try_name(s, part);
-done:
-#ifdef CONFIG_SYSFS
- sys_umount("/sys", 0);
-out:
- if (!mkdir_err)
- sys_rmdir("/sys");
-#endif
- return res;
-fail:
- res = 0;
- goto done;
-}
-
-static int __init root_dev_setup(char *line)
-{
- strlcpy(saved_root_name, line, sizeof(saved_root_name));
- return 1;
-}
-
-__setup("root=", root_dev_setup);
-
-static char * __initdata root_mount_data;
-static int __init root_data_setup(char *str)
-{
- root_mount_data = str;
- return 1;
-}
-
-static char * __initdata root_fs_names;
-static int __init fs_names_setup(char *str)
-{
- root_fs_names = str;
- return 1;
-}
-
-static unsigned int __initdata root_delay;
-static int __init root_delay_setup(char *str)
-{
- root_delay = simple_strtoul(str, NULL, 0);
- return 1;
-}
-
-__setup("rootflags=", root_data_setup);
-__setup("rootfstype=", fs_names_setup);
-__setup("rootdelay=", root_delay_setup);
-
-static void __init get_fs_names(char *page)
-{
- char *s = page;
-
- if (root_fs_names) {
- strcpy(page, root_fs_names);
- while (*s++) {
- if (s[-1] == ',')
- s[-1] = '\0';
- }
- } else {
- int len = get_filesystem_list(page);
- char *p, *next;
-
- page[len] = '\0';
- for (p = page-1; p; p = next) {
- next = strchr(++p, '\n');
- if (*p++ != '\t')
- continue;
- while ((*s++ = *p++) != '\n')
- ;
- s[-1] = '\0';
- }
- }
- *s = '\0';
-}
-
-static int __init do_mount_root(char *name, char *fs, int flags, void *data)
-{
- int err = sys_mount(name, "/root", fs, flags, data);
- if (err)
- return err;
-
- sys_chdir("/root");
- ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
- printk("VFS: Mounted root (%s filesystem)%s.\n",
- current->fs->pwdmnt->mnt_sb->s_type->name,
- current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ?
- " readonly" : "");
- return 0;
-}
-
-void __init mount_block_root(char *name, int flags)
-{
- char *fs_names = __getname();
- char *p;
- char b[BDEVNAME_SIZE];
-
- get_fs_names(fs_names);
-retry:
- for (p = fs_names; *p; p += strlen(p)+1) {
- int err = do_mount_root(name, p, flags, root_mount_data);
- switch (err) {
- case 0:
- goto out;
- case -EACCES:
- flags |= MS_RDONLY;
- goto retry;
- case -EINVAL:
- continue;
- }
- /*
- * Allow the user to distinguish between failed sys_open
- * and bad superblock on root device.
- */
- __bdevname(ROOT_DEV, b);
- printk("VFS: Cannot open root device \"%s\" or %s\n",
- root_device_name, b);
- printk("Please append a correct \"root=\" boot option\n");
-
- panic("VFS: Unable to mount root fs on %s", b);
- }
-
- printk("No filesystem could mount root, tried: ");
- for (p = fs_names; *p; p += strlen(p)+1)
- printk(" %s", p);
- printk("\n");
- panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
-out:
- putname(fs_names);
-}
-
-#ifdef CONFIG_ROOT_NFS
-static int __init mount_nfs_root(void)
-{
- void *data = nfs_root_data();
-
- create_dev("/dev/root", ROOT_DEV);
- if (data &&
- do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
- return 1;
- return 0;
-}
-#endif
-
-#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
-void __init change_floppy(char *fmt, ...)
-{
- struct termios termios;
- char buf[80];
- char c;
- int fd;
- va_list args;
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
- if (fd >= 0) {
- sys_ioctl(fd, FDEJECT, 0);
- sys_close(fd);
- }
- printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
- fd = sys_open("/dev/console", O_RDWR, 0);
- if (fd >= 0) {
- sys_ioctl(fd, TCGETS, (long)&termios);
- termios.c_lflag &= ~ICANON;
- sys_ioctl(fd, TCSETSF, (long)&termios);
- sys_read(fd, &c, 1);
- termios.c_lflag |= ICANON;
- sys_ioctl(fd, TCSETSF, (long)&termios);
- sys_close(fd);
- }
-}
-#endif
-
-void __init mount_root(void)
-{
-#ifdef CONFIG_ROOT_NFS
- if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
- if (mount_nfs_root())
- return;
-
- printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
- ROOT_DEV = Root_FD0;
- }
-#endif
-#ifdef CONFIG_BLK_DEV_FD
- if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
- /* rd_doload is 2 for a dual initrd/ramload setup */
- if (rd_doload==2) {
- if (rd_load_disk(1)) {
- ROOT_DEV = Root_RAM1;
- root_device_name = NULL;
- }
- } else
- change_floppy("root floppy");
- }
-#endif
- create_dev("/dev/root", ROOT_DEV);
- mount_block_root("/dev/root", root_mountflags);
-}
-
-/*
- * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
- */
-void __init prepare_namespace(void)
-{
- int is_floppy;
-
- if (root_delay) {
- printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
- root_delay);
- ssleep(root_delay);
- }
-
- md_run_setup();
-
- if (saved_root_name[0]) {
- root_device_name = saved_root_name;
- if (!strncmp(root_device_name, "mtd", 3)) {
- mount_block_root(root_device_name, root_mountflags);
- goto out;
- }
- ROOT_DEV = name_to_dev_t(root_device_name);
- if (strncmp(root_device_name, "/dev/", 5) == 0)
- root_device_name += 5;
- }
-
- is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
-
- if (initrd_load())
- goto out;
-
- if (is_floppy && rd_doload && rd_load_disk(0))
- ROOT_DEV = Root_RAM0;
-
- mount_root();
-out:
- sys_mount(".", "/", NULL, MS_MOVE, NULL);
- sys_chroot(".");
- security_sb_post_mountroot();
-}
-
diff --git a/init/do_mounts.h b/init/do_mounts.h
deleted file mode 100644
index e7f2e7fa066eb6..00000000000000
--- a/init/do_mounts.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/syscalls.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/mount.h>
-#include <linux/major.h>
-#include <linux/root_dev.h>
-
-void change_floppy(char *fmt, ...);
-void mount_block_root(char *name, int flags);
-void mount_root(void);
-extern int root_mountflags;
-extern char *root_device_name;
-
-static inline int create_dev(char *name, dev_t dev)
-{
- sys_unlink(name);
- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
-}
-
-#if BITS_PER_LONG == 32
-static inline u32 bstat(char *name)
-{
- struct stat64 stat;
- if (sys_stat64(name, &stat) != 0)
- return 0;
- if (!S_ISBLK(stat.st_mode))
- return 0;
- if (stat.st_rdev != (u32)stat.st_rdev)
- return 0;
- return stat.st_rdev;
-}
-#else
-static inline u32 bstat(char *name)
-{
- struct stat stat;
- if (sys_newstat(name, &stat) != 0)
- return 0;
- if (!S_ISBLK(stat.st_mode))
- return 0;
- return stat.st_rdev;
-}
-#endif
-
-#ifdef CONFIG_BLK_DEV_RAM
-
-int __init rd_load_disk(int n);
-int __init rd_load_image(char *from);
-
-#else
-
-static inline int rd_load_disk(int n) { return 0; }
-static inline int rd_load_image(char *from) { return 0; }
-
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
-
-int __init initrd_load(void);
-
-#else
-
-static inline int initrd_load(void) { return 0; }
-
-#endif
-
-#ifdef CONFIG_BLK_DEV_MD
-
-void md_run_setup(void);
-
-#else
-
-static inline void md_run_setup(void) {}
-
-#endif
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
deleted file mode 100644
index a06f037fa000a9..00000000000000
--- a/init/do_mounts_initrd.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
-#include <linux/initrd.h>
-#include <linux/sched.h>
-
-#include "do_mounts.h"
-
-unsigned long initrd_start, initrd_end;
-int initrd_below_start_ok;
-unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
-static int __initdata old_fd, root_fd;
-static int __initdata mount_initrd = 1;
-
-static int __init no_initrd(char *str)
-{
- mount_initrd = 0;
- return 1;
-}
-
-__setup("noinitrd", no_initrd);
-
-static int __init do_linuxrc(void * shell)
-{
- static char *argv[] = { "linuxrc", NULL, };
- extern char * envp_init[];
-
- sys_close(old_fd);sys_close(root_fd);
- sys_close(0);sys_close(1);sys_close(2);
- sys_setsid();
- (void) sys_open("/dev/console",O_RDWR,0);
- (void) sys_dup(0);
- (void) sys_dup(0);
- return execve(shell, argv, envp_init);
-}
-
-static void __init handle_initrd(void)
-{
- int error;
- int pid;
-
- real_root_dev = new_encode_dev(ROOT_DEV);
- create_dev("/dev/root.old", Root_RAM0);
- /* mount initrd on rootfs' /root */
- mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
- sys_mkdir("/old", 0700);
- root_fd = sys_open("/", 0, 0);
- old_fd = sys_open("/old", 0, 0);
- /* move initrd over / and chdir/chroot in initrd root */
- sys_chdir("/root");
- sys_mount(".", "/", NULL, MS_MOVE, NULL);
- sys_chroot(".");
-
- current->flags |= PF_NOFREEZE;
- pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
- if (pid > 0) {
- while (pid != sys_wait4(-1, NULL, 0, NULL))
- yield();
- }
-
- /* move initrd to rootfs' /old */
- sys_fchdir(old_fd);
- sys_mount("/", ".", NULL, MS_MOVE, NULL);
- /* switch root and cwd back to / of rootfs */
- sys_fchdir(root_fd);
- sys_chroot(".");
- sys_close(old_fd);
- sys_close(root_fd);
-
- if (new_decode_dev(real_root_dev) == Root_RAM0) {
- sys_chdir("/old");
- return;
- }
-
- ROOT_DEV = new_decode_dev(real_root_dev);
- mount_root();
-
- printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
- if (!error)
- printk("okay\n");
- else {
- int fd = sys_open("/dev/root.old", O_RDWR, 0);
- if (error == -ENOENT)
- printk("/initrd does not exist. Ignored.\n");
- else
- printk("failed\n");
- printk(KERN_NOTICE "Unmounting old root\n");
- sys_umount("/old", MNT_DETACH);
- printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
- if (fd < 0) {
- error = fd;
- } else {
- error = sys_ioctl(fd, BLKFLSBUF, 0);
- sys_close(fd);
- }
- printk(!error ? "okay\n" : "failed\n");
- }
-}
-
-int __init initrd_load(void)
-{
- if (mount_initrd) {
- create_dev("/dev/ram", Root_RAM0);
- /*
- * Load the initrd data into /dev/ram0. Execute it as initrd
- * unless /dev/ram0 is supposed to be our actual root device,
- * in that case the ram disk is just set up here, and gets
- * mounted in the normal path.
- */
- if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
- sys_unlink("/initrd.image");
- handle_initrd();
- return 1;
- }
- }
- sys_unlink("/initrd.image");
- return 0;
-}
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
deleted file mode 100644
index 2429e1bf8c60a1..00000000000000
--- a/init/do_mounts_md.c
+++ /dev/null
@@ -1,285 +0,0 @@
-
-#include <linux/raid/md.h>
-
-#include "do_mounts.h"
-
-/*
- * When md (and any require personalities) are compiled into the kernel
- * (not a module), arrays can be assembles are boot time using with AUTODETECT
- * where specially marked partitions are registered with md_autodetect_dev(),
- * and with MD_BOOT where devices to be collected are given on the boot line
- * with md=.....
- * The code for that is here.
- */
-
-static int __initdata raid_noautodetect, raid_autopart;
-
-static struct {
- int minor;
- int partitioned;
- int level;
- int chunk;
- char *device_names;
-} md_setup_args[MAX_MD_DEVS] __initdata;
-
-static int md_setup_ents __initdata;
-
-extern int mdp_major;
-/*
- * Parse the command-line parameters given our kernel, but do not
- * actually try to invoke the MD device now; that is handled by
- * md_setup_drive after the low-level disk drivers have initialised.
- *
- * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
- * assigns the task of parsing integer arguments to the
- * invoked program now). Added ability to initialise all
- * the MD devices (by specifying multiple "md=" lines)
- * instead of just one. -- KTK
- * 18May2000: Added support for persistent-superblock arrays:
- * md=n,0,factor,fault,device-list uses RAID0 for device n
- * md=n,-1,factor,fault,device-list uses LINEAR for device n
- * md=n,device-list reads a RAID superblock from the devices
- * elements in device-list are read by name_to_kdev_t so can be
- * a hex number or something like /dev/hda1 /dev/sdb
- * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
- * Shifted name_to_kdev_t() and related operations to md_set_drive()
- * for later execution. Rewrote section to make devfs compatible.
- */
-static int __init md_setup(char *str)
-{
- int minor, level, factor, fault, partitioned = 0;
- char *pername = "";
- char *str1;
- int ent;
-
- if (*str == 'd') {
- partitioned = 1;
- str++;
- }
- if (get_option(&str, &minor) != 2) { /* MD Number */
- printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
- return 0;
- }
- str1 = str;
- if (minor >= MAX_MD_DEVS) {
- printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
- return 0;
- }
- for (ent=0 ; ent< md_setup_ents ; ent++)
- if (md_setup_args[ent].minor == minor &&
- md_setup_args[ent].partitioned == partitioned) {
- printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
- "Replacing previous definition.\n", partitioned?"d":"", minor);
- break;
- }
- if (ent >= MAX_MD_DEVS) {
- printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
- return 0;
- }
- if (ent >= md_setup_ents)
- md_setup_ents++;
- switch (get_option(&str, &level)) { /* RAID level */
- case 2: /* could be 0 or -1.. */
- if (level == 0 || level == LEVEL_LINEAR) {
- if (get_option(&str, &factor) != 2 || /* Chunk Size */
- get_option(&str, &fault) != 2) {
- printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
- return 0;
- }
- md_setup_args[ent].level = level;
- md_setup_args[ent].chunk = 1 << (factor+12);
- if (level == LEVEL_LINEAR)
- pername = "linear";
- else
- pername = "raid0";
- break;
- }
- /* FALL THROUGH */
- case 1: /* the first device is numeric */
- str = str1;
- /* FALL THROUGH */
- case 0:
- md_setup_args[ent].level = LEVEL_NONE;
- pername="super-block";
- }
-
- printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
- minor, pername, str);
- md_setup_args[ent].device_names = str;
- md_setup_args[ent].partitioned = partitioned;
- md_setup_args[ent].minor = minor;
-
- return 1;
-}
-
-#define MdpMinorShift 6
-
-static void __init md_setup_drive(void)
-{
- int minor, i, ent, partitioned;
- dev_t dev;
- dev_t devices[MD_SB_DISKS+1];
-
- for (ent = 0; ent < md_setup_ents ; ent++) {
- int fd;
- int err = 0;
- char *devname;
- mdu_disk_info_t dinfo;
- char name[16];
-
- minor = md_setup_args[ent].minor;
- partitioned = md_setup_args[ent].partitioned;
- devname = md_setup_args[ent].device_names;
-
- sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
- if (partitioned)
- dev = MKDEV(mdp_major, minor << MdpMinorShift);
- else
- dev = MKDEV(MD_MAJOR, minor);
- create_dev(name, dev);
- for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
- char *p;
- char comp_name[64];
- u32 rdev;
-
- p = strchr(devname, ',');
- if (p)
- *p++ = 0;
-
- dev = name_to_dev_t(devname);
- if (strncmp(devname, "/dev/", 5) == 0)
- devname += 5;
- snprintf(comp_name, 63, "/dev/%s", devname);
- rdev = bstat(comp_name);
- if (rdev)
- dev = new_decode_dev(rdev);
- if (!dev) {
- printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
- break;
- }
-
- devices[i] = dev;
-
- devname = p;
- }
- devices[i] = 0;
-
- if (!i)
- continue;
-
- printk(KERN_INFO "md: Loading md%s%d: %s\n",
- partitioned ? "_d" : "", minor,
- md_setup_args[ent].device_names);
-
- fd = sys_open(name, 0, 0);
- if (fd < 0) {
- printk(KERN_ERR "md: open failed - cannot start "
- "array %s\n", name);
- continue;
- }
- if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
- printk(KERN_WARNING
- "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
- minor);
- sys_close(fd);
- continue;
- }
-
- if (md_setup_args[ent].level != LEVEL_NONE) {
- /* non-persistent */
- mdu_array_info_t ainfo;
- ainfo.level = md_setup_args[ent].level;
- ainfo.size = 0;
- ainfo.nr_disks =0;
- ainfo.raid_disks =0;
- while (devices[ainfo.raid_disks])
- ainfo.raid_disks++;
- ainfo.md_minor =minor;
- ainfo.not_persistent = 1;
-
- ainfo.state = (1 << MD_SB_CLEAN);
- ainfo.layout = 0;
- ainfo.chunk_size = md_setup_args[ent].chunk;
- err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
- for (i = 0; !err && i <= MD_SB_DISKS; i++) {
- dev = devices[i];
- if (!dev)
- break;
- dinfo.number = i;
- dinfo.raid_disk = i;
- dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
- dinfo.major = MAJOR(dev);
- dinfo.minor = MINOR(dev);
- err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
- }
- } else {
- /* persistent */
- for (i = 0; i <= MD_SB_DISKS; i++) {
- dev = devices[i];
- if (!dev)
- break;
- dinfo.major = MAJOR(dev);
- dinfo.minor = MINOR(dev);
- sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
- }
- }
- if (!err)
- err = sys_ioctl(fd, RUN_ARRAY, 0);
- if (err)
- printk(KERN_WARNING "md: starting md%d failed\n", minor);
- else {
- /* reread the partition table.
- * I (neilb) and not sure why this is needed, but I cannot
- * boot a kernel with devfs compiled in from partitioned md
- * array without it
- */
- sys_close(fd);
- fd = sys_open(name, 0, 0);
- sys_ioctl(fd, BLKRRPART, 0);
- }
- sys_close(fd);
- }
-}
-
-static int __init raid_setup(char *str)
-{
- int len, pos;
-
- len = strlen(str) + 1;
- pos = 0;
-
- while (pos < len) {
- char *comma = strchr(str+pos, ',');
- int wlen;
- if (comma)
- wlen = (comma-str)-pos;
- else wlen = (len-1)-pos;
-
- if (!strncmp(str, "noautodetect", wlen))
- raid_noautodetect = 1;
- if (strncmp(str, "partitionable", wlen)==0)
- raid_autopart = 1;
- if (strncmp(str, "part", wlen)==0)
- raid_autopart = 1;
- pos += wlen+1;
- }
- return 1;
-}
-
-__setup("raid=", raid_setup);
-__setup("md=", md_setup);
-
-void __init md_run_setup(void)
-{
- create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
- if (raid_noautodetect)
- printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
- else {
- int fd = sys_open("/dev/md0", 0, 0);
- if (fd >= 0) {
- sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
- sys_close(fd);
- }
- }
- md_setup_drive();
-}
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
deleted file mode 100644
index ed652f40f075a6..00000000000000
--- a/init/do_mounts_rd.c
+++ /dev/null
@@ -1,429 +0,0 @@
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
-#include <linux/cramfs_fs.h>
-#include <linux/initrd.h>
-#include <linux/string.h>
-
-#include "do_mounts.h"
-
-#define BUILD_CRAMDISK
-
-int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
-
-static int __init prompt_ramdisk(char *str)
-{
- rd_prompt = simple_strtol(str,NULL,0) & 1;
- return 1;
-}
-__setup("prompt_ramdisk=", prompt_ramdisk);
-
-int __initdata rd_image_start; /* starting block # of image */
-
-static int __init ramdisk_start_setup(char *str)
-{
- rd_image_start = simple_strtol(str,NULL,0);
- return 1;
-}
-__setup("ramdisk_start=", ramdisk_start_setup);
-
-static int __init crd_load(int in_fd, int out_fd);
-
-/*
- * This routine tries to find a RAM disk image to load, and returns the
- * number of blocks to read for a non-compressed image, 0 if the image
- * is a compressed image, and -1 if an image with the right magic
- * numbers could not be found.
- *
- * We currently check for the following magic numbers:
- * minix
- * ext2
- * romfs
- * cramfs
- * gzip
- */
-static int __init
-identify_ramdisk_image(int fd, int start_block)
-{
- const int size = 512;
- struct minix_super_block *minixsb;
- struct ext2_super_block *ext2sb;
- struct romfs_super_block *romfsb;
- struct cramfs_super *cramfsb;
- int nblocks = -1;
- unsigned char *buf;
-
- buf = kmalloc(size, GFP_KERNEL);
- if (buf == 0)
- return -1;
-
- minixsb = (struct minix_super_block *) buf;
- ext2sb = (struct ext2_super_block *) buf;
- romfsb = (struct romfs_super_block *) buf;
- cramfsb = (struct cramfs_super *) buf;
- memset(buf, 0xe5, size);
-
- /*
- * Read block 0 to test for gzipped kernel
- */
- sys_lseek(fd, start_block * BLOCK_SIZE, 0);
- sys_read(fd, buf, size);
-
- /*
- * If it matches the gzip magic numbers, return -1
- */
- if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
- printk(KERN_NOTICE
- "RAMDISK: Compressed image found at block %d\n",
- start_block);
- nblocks = 0;
- goto done;
- }
-
- /* romfs is at block zero too */
- if (romfsb->word0 == ROMSB_WORD0 &&
- romfsb->word1 == ROMSB_WORD1) {
- printk(KERN_NOTICE
- "RAMDISK: romfs filesystem found at block %d\n",
- start_block);
- nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
- goto done;
- }
-
- if (cramfsb->magic == CRAMFS_MAGIC) {
- printk(KERN_NOTICE
- "RAMDISK: cramfs filesystem found at block %d\n",
- start_block);
- nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
- goto done;
- }
-
- /*
- * Read block 1 to test for minix and ext2 superblock
- */
- sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
- sys_read(fd, buf, size);
-
- /* Try minix */
- if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
- minixsb->s_magic == MINIX_SUPER_MAGIC2) {
- printk(KERN_NOTICE
- "RAMDISK: Minix filesystem found at block %d\n",
- start_block);
- nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
- goto done;
- }
-
- /* Try ext2 */
- if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
- printk(KERN_NOTICE
- "RAMDISK: ext2 filesystem found at block %d\n",
- start_block);
- nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
- le32_to_cpu(ext2sb->s_log_block_size);
- goto done;
- }
-
- printk(KERN_NOTICE
- "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
- start_block);
-
-done:
- sys_lseek(fd, start_block * BLOCK_SIZE, 0);
- kfree(buf);
- return nblocks;
-}
-
-int __init rd_load_image(char *from)
-{
- int res = 0;
- int in_fd, out_fd;
- unsigned long rd_blocks, devblocks;
- int nblocks, i, disk;
- char *buf = NULL;
- unsigned short rotate = 0;
-#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
- char rotator[4] = { '|' , '/' , '-' , '\\' };
-#endif
-
- out_fd = sys_open("/dev/ram", O_RDWR, 0);
- if (out_fd < 0)
- goto out;
-
- in_fd = sys_open(from, O_RDONLY, 0);
- if (in_fd < 0)
- goto noclose_input;
-
- nblocks = identify_ramdisk_image(in_fd, rd_image_start);
- if (nblocks < 0)
- goto done;
-
- if (nblocks == 0) {
-#ifdef BUILD_CRAMDISK
- if (crd_load(in_fd, out_fd) == 0)
- goto successful_load;
-#else
- printk(KERN_NOTICE
- "RAMDISK: Kernel does not support compressed "
- "RAM disk images\n");
-#endif
- goto done;
- }
-
- /*
- * NOTE NOTE: nblocks is not actually blocks but
- * the number of kibibytes of data to load into a ramdisk.
- * So any ramdisk block size that is a multiple of 1KiB should
- * work when the appropriate ramdisk_blocksize is specified
- * on the command line.
- *
- * The default ramdisk_blocksize is 1KiB and it is generally
- * silly to use anything else, so make sure to use 1KiB
- * blocksize while generating ext2fs ramdisk-images.
- */
- if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
- rd_blocks = 0;
- else
- rd_blocks >>= 1;
-
- if (nblocks > rd_blocks) {
- printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
- nblocks, rd_blocks);
- goto done;
- }
-
- /*
- * OK, time to copy in the data
- */
- if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
- devblocks = 0;
- else
- devblocks >>= 1;
-
- if (strcmp(from, "/initrd.image") == 0)
- devblocks = nblocks;
-
- if (devblocks == 0) {
- printk(KERN_ERR "RAMDISK: could not determine device size\n");
- goto done;
- }
-
- buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
- if (buf == 0) {
- printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
- goto done;
- }
-
- printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
- nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
- for (i = 0, disk = 1; i < nblocks; i++) {
- if (i && (i % devblocks == 0)) {
- printk("done disk #%d.\n", disk++);
- rotate = 0;
- if (sys_close(in_fd)) {
- printk("Error closing the disk.\n");
- goto noclose_input;
- }
- change_floppy("disk #%d", disk);
- in_fd = sys_open(from, O_RDONLY, 0);
- if (in_fd < 0) {
- printk("Error opening disk.\n");
- goto noclose_input;
- }
- printk("Loading disk #%d... ", disk);
- }
- sys_read(in_fd, buf, BLOCK_SIZE);
- sys_write(out_fd, buf, BLOCK_SIZE);
-#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
- if (!(i % 16)) {
- printk("%c\b", rotator[rotate & 0x3]);
- rotate++;
- }
-#endif
- }
- printk("done.\n");
-
-successful_load:
- res = 1;
-done:
- sys_close(in_fd);
-noclose_input:
- sys_close(out_fd);
-out:
- kfree(buf);
- sys_unlink("/dev/ram");
- return res;
-}
-
-int __init rd_load_disk(int n)
-{
- if (rd_prompt)
- change_floppy("root floppy disk to be loaded into RAM disk");
- create_dev("/dev/root", ROOT_DEV);
- create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
- return rd_load_image("/dev/root");
-}
-
-#ifdef BUILD_CRAMDISK
-
-/*
- * gzip declarations
- */
-
-#define OF(args) args
-
-#ifndef memzero
-#define memzero(s, n) memset ((s), 0, (n))
-#endif
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define INBUFSIZ 4096
-#define WSIZE 0x8000 /* window size--must be a power of two, and */
- /* at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize; /* valid bytes in inbuf */
-static unsigned inptr; /* index of next byte to be processed in inbuf */
-static unsigned outcnt; /* bytes in output buffer */
-static int exit_code;
-static int unzip_error;
-static long bytes_out;
-static int crd_infd, crd_outfd;
-
-#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-#define INIT __init
-
-static int __init fill_inbuf(void);
-static void __init flush_window(void);
-static void __init *malloc(size_t size);
-static void __init free(void *where);
-static void __init error(char *m);
-static void __init gzip_mark(void **);
-static void __init gzip_release(void **);
-
-#include "../lib/inflate.c"
-
-static void __init *malloc(size_t size)
-{
- return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
- kfree(where);
-}
-
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
-
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- * Returning -1 does not guarantee that gunzip() will ever return.
- */
-static int __init fill_inbuf(void)
-{
- if (exit_code) return -1;
-
- insize = sys_read(crd_infd, inbuf, INBUFSIZ);
- if (insize == 0) {
- error("RAMDISK: ran out of compressed data");
- return -1;
- }
-
- inptr = 1;
-
- return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
- ulg c = crc; /* temporary variable */
- unsigned n, written;
- uch *in, ch;
-
- written = sys_write(crd_outfd, window, outcnt);
- if (written != outcnt && unzip_error == 0) {
- printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
- written, outcnt, bytes_out);
- unzip_error = 1;
- }
- in = window;
- for (n = 0; n < outcnt; n++) {
- ch = *in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void __init error(char *x)
-{
- printk(KERN_ERR "%s\n", x);
- exit_code = 1;
- unzip_error = 1;
-}
-
-static int __init crd_load(int in_fd, int out_fd)
-{
- int result;
-
- insize = 0; /* valid bytes in inbuf */
- inptr = 0; /* index of next byte to be processed in inbuf */
- outcnt = 0; /* bytes in output buffer */
- exit_code = 0;
- bytes_out = 0;
- crc = (ulg)0xffffffffL; /* shift register contents */
-
- crd_infd = in_fd;
- crd_outfd = out_fd;
- inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
- if (inbuf == 0) {
- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
- return -1;
- }
- window = kmalloc(WSIZE, GFP_KERNEL);
- if (window == 0) {
- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
- kfree(inbuf);
- return -1;
- }
- makecrc();
- result = gunzip();
- if (unzip_error)
- result = 1;
- kfree(inbuf);
- kfree(window);
- return result;
-}
-
-#endif /* BUILD_CRAMDISK */
diff --git a/init/initramfs.c b/init/initramfs.c
index d28c1094d7e5ca..57109d4dcb2eee 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -7,6 +7,9 @@
#include <linux/string.h>
#include <linux/syscalls.h>
+unsigned long __initdata initrd_start, initrd_end;
+int __initdata initrd_below_start_ok;
+
static __initdata char *message;
static void __init error(char *x)
{
diff --git a/init/main.c b/init/main.c
index b2f3b566790e8e..e94e3ef53a86ef 100644
--- a/init/main.c
+++ b/init/main.c
@@ -7,6 +7,8 @@
* Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
* Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
* Simplified starting of init: Michael A. Griffith <grif@acm.org>
+ *
+ * 2006-02-12 H. Peter Anvin: Eliminated in-kernel root mounting.
*/
#define __KERNEL_SYSCALLS__
@@ -45,6 +47,7 @@
#include <linux/rmap.h>
#include <linux/mempolicy.h>
#include <linux/key.h>
+#include <linux/root_dev.h>
#include <linux/unwind.h>
#include <linux/buffer_head.h>
@@ -123,6 +126,11 @@ static char *ramdisk_execute_command;
/* Setup configured maximum number of CPUs to activate */
static unsigned int max_cpus = NR_CPUS;
+/* ROOT_DEV contains any architecture-specific default root device. */
+/* real_root_dev is used (via sysctl) to communicate ROOT_DEV to kinit. */
+dev_t ROOT_DEV;
+unsigned int real_root_dev;
+
/*
* Setup routine for controlling SMP activation
*
@@ -688,6 +696,12 @@ static int init(void * unused)
do_basic_setup();
/*
+ * If we have a root device set by architecture-specific means,
+ * let kinit know about it.
+ */
+ real_root_dev = new_encode_dev(ROOT_DEV);
+
+ /*
* check if there is an early userspace init. If yes, let it do all
* the work
*/
@@ -695,11 +709,6 @@ static int init(void * unused)
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
- if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
- ramdisk_execute_command = NULL;
- prepare_namespace();
- }
-
/*
* Ok, we have completed the initial bootup, and
* we're essentially up and running. Get rid of the
@@ -711,33 +720,13 @@ static int init(void * unused)
system_state = SYSTEM_RUNNING;
numa_default_policy();
+ /* This could be done by (k)init as well... */
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
printk(KERN_WARNING "Warning: unable to open an initial console.\n");
(void) sys_dup(0);
(void) sys_dup(0);
- if (ramdisk_execute_command) {
- run_init_process(ramdisk_execute_command);
- printk(KERN_WARNING "Failed to execute %s\n",
- ramdisk_execute_command);
- }
-
- /*
- * We try each of these until one succeeds.
- *
- * The Bourne shell can be used instead of init if we are
- * trying to recover a really broken machine.
- */
- if (execute_command) {
- run_init_process(execute_command);
- printk(KERN_WARNING "Failed to execute %s. Attempting "
- "defaults...\n", execute_command);
- }
- run_init_process("/sbin/init");
- run_init_process("/etc/init");
- run_init_process("/bin/init");
- run_init_process("/bin/sh");
-
- panic("No init found. Try passing init= option to kernel.");
+ run_init_process(ramdisk_execute_command);
+ panic("Failed to execute %s", ramdisk_execute_command);
}
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 38b8039bdd55ff..964403fb19055c 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o
obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
-obj-$(CONFIG_IP_PNP) += ipconfig.o
obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
deleted file mode 100644
index cb8a92f18ef6e4..00000000000000
--- a/net/ipv4/ipconfig.c
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
- * $Id: ipconfig.c,v 1.46 2002/02/01 22:01:04 davem Exp $
- *
- * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
- * user-supplied information to configure own IP address and routes.
- *
- * Copyright (C) 1996-1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *
- * Derived from network configuration code in fs/nfs/nfsroot.c,
- * originally Copyright (C) 1995, 1996 Gero Kuhlmann and me.
- *
- * BOOTP rewritten to construct and analyse packets itself instead
- * of misusing the IP layer. num_bugs_causing_wrong_arp_replies--;
- * -- MJ, December 1998
- *
- * Fixed ip_auto_config_setup calling at startup in the new "Linker Magic"
- * initialization scheme.
- * - Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 08/11/1999
- *
- * DHCP support added. To users this looks like a whole separate
- * protocol, but we know it's just a bag on the side of BOOTP.
- * -- Chip Salzenberg <chip@valinux.com>, May 2000
- *
- * Ported DHCP support from 2.2.16 to 2.4.0-test4
- * -- Eric Biederman <ebiederman@lnxi.com>, 30 Aug 2000
- *
- * Merged changes from 2.2.19 into 2.4.3
- * -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001
- *
- * Multiple Nameservers in /proc/net/pnp
- * -- Josef Siemes <jsiemes@web.de>, Aug 2002
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/utsname.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/inet.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <linux/socket.h>
-#include <linux/route.h>
-#include <linux/udp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/major.h>
-#include <linux/root_dev.h>
-#include <linux/delay.h>
-#include <linux/nfs_fs.h>
-#include <net/arp.h>
-#include <net/ip.h>
-#include <net/ipconfig.h>
-#include <net/route.h>
-
-#include <asm/uaccess.h>
-#include <net/checksum.h>
-#include <asm/processor.h>
-
-/* Define this to allow debugging output */
-#undef IPCONFIG_DEBUG
-
-#ifdef IPCONFIG_DEBUG
-#define DBG(x) printk x
-#else
-#define DBG(x) do { } while(0)
-#endif
-
-#if defined(CONFIG_IP_PNP_DHCP)
-#define IPCONFIG_DHCP
-#endif
-#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_DHCP)
-#define IPCONFIG_BOOTP
-#endif
-#if defined(CONFIG_IP_PNP_RARP)
-#define IPCONFIG_RARP
-#endif
-#if defined(IPCONFIG_BOOTP) || defined(IPCONFIG_RARP)
-#define IPCONFIG_DYNAMIC
-#endif
-
-/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN 500 /* Before opening: 1/2 second */
-#define CONF_POST_OPEN 1 /* After opening: 1 second */
-
-/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
-#define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
-#define CONF_SEND_RETRIES 6 /* Send six requests per open */
-#define CONF_INTER_TIMEOUT (HZ/2) /* Inter-device timeout: 1/2 second */
-#define CONF_BASE_TIMEOUT (HZ*2) /* Initial timeout: 2 seconds */
-#define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
-#define CONF_TIMEOUT_MULT *7/4 /* Rate of timeout growth */
-#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */
-#define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers
- - '3' from resolv.h */
-
-
-/*
- * Public IP configuration
- */
-
-/* This is used by platforms which might be able to set the ipconfig
- * variables using firmware environment vars. If this is set, it will
- * ignore such firmware variables.
- */
-int ic_set_manually __initdata = 0; /* IPconfig parameters set manually */
-
-static int ic_enable __initdata = 0; /* IP config enabled? */
-
-/* Protocol choice */
-int ic_proto_enabled __initdata = 0
-#ifdef IPCONFIG_BOOTP
- | IC_BOOTP
-#endif
-#ifdef CONFIG_IP_PNP_DHCP
- | IC_USE_DHCP
-#endif
-#ifdef IPCONFIG_RARP
- | IC_RARP
-#endif
- ;
-
-static int ic_host_name_set __initdata = 0; /* Host name set by us? */
-
-u32 ic_myaddr = INADDR_NONE; /* My IP address */
-static u32 ic_netmask = INADDR_NONE; /* Netmask for local subnet */
-u32 ic_gateway = INADDR_NONE; /* Gateway IP address */
-
-u32 ic_servaddr = INADDR_NONE; /* Boot server IP address */
-
-u32 root_server_addr = INADDR_NONE; /* Address of NFS server */
-u8 root_server_path[256] = { 0, }; /* Path to mount as root */
-
-/* Persistent data: */
-
-static int ic_proto_used; /* Protocol used, if any */
-static u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
-static u8 ic_domain[64]; /* DNS (not NIS) domain name */
-
-/*
- * Private state.
- */
-
-/* Name of user-selected boot device */
-static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
-
-/* Protocols supported by available interfaces */
-static int ic_proto_have_if __initdata = 0;
-
-#ifdef IPCONFIG_DYNAMIC
-static DEFINE_SPINLOCK(ic_recv_lock);
-static volatile int ic_got_reply __initdata = 0; /* Proto(s) that replied */
-#endif
-#ifdef IPCONFIG_DHCP
-static int ic_dhcp_msgtype __initdata = 0; /* DHCP msg type received */
-#endif
-
-
-/*
- * Network devices
- */
-
-struct ic_device {
- struct ic_device *next;
- struct net_device *dev;
- unsigned short flags;
- short able;
- u32 xid;
-};
-
-static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
-static struct net_device *ic_dev __initdata = NULL; /* Selected device */
-
-static int __init ic_open_devs(void)
-{
- struct ic_device *d, **last;
- struct net_device *dev;
- unsigned short oflags;
-
- last = &ic_first_dev;
- rtnl_lock();
-
- /* bring loopback device up first */
- if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
- printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
-
- for (dev = dev_base; dev; dev = dev->next) {
- if (dev == &loopback_dev)
- continue;
- if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
- (!(dev->flags & IFF_LOOPBACK) &&
- (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
- strncmp(dev->name, "dummy", 5))) {
- int able = 0;
- if (dev->mtu >= 364)
- able |= IC_BOOTP;
- else
- printk(KERN_WARNING "DHCP/BOOTP: Ignoring device %s, MTU %d too small", dev->name, dev->mtu);
- if (!(dev->flags & IFF_NOARP))
- able |= IC_RARP;
- able &= ic_proto_enabled;
- if (ic_proto_enabled && !able)
- continue;
- oflags = dev->flags;
- if (dev_change_flags(dev, oflags | IFF_UP) < 0) {
- printk(KERN_ERR "IP-Config: Failed to open %s\n", dev->name);
- continue;
- }
- if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
- rtnl_unlock();
- return -1;
- }
- d->dev = dev;
- *last = d;
- last = &d->next;
- d->flags = oflags;
- d->able = able;
- if (able & IC_BOOTP)
- get_random_bytes(&d->xid, sizeof(u32));
- else
- d->xid = 0;
- ic_proto_have_if |= able;
- DBG(("IP-Config: %s UP (able=%d, xid=%08x)\n",
- dev->name, able, d->xid));
- }
- }
- rtnl_unlock();
-
- *last = NULL;
-
- if (!ic_first_dev) {
- if (user_dev_name[0])
- printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
- else
- printk(KERN_ERR "IP-Config: No network devices available.\n");
- return -1;
- }
- return 0;
-}
-
-static void __init ic_close_devs(void)
-{
- struct ic_device *d, *next;
- struct net_device *dev;
-
- rtnl_lock();
- next = ic_first_dev;
- while ((d = next)) {
- next = d->next;
- dev = d->dev;
- if (dev != ic_dev) {
- DBG(("IP-Config: Downing %s\n", dev->name));
- dev_change_flags(dev, d->flags);
- }
- kfree(d);
- }
- rtnl_unlock();
-}
-
-/*
- * Interface to various network functions.
- */
-
-static inline void
-set_sockaddr(struct sockaddr_in *sin, u32 addr, u16 port)
-{
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = addr;
- sin->sin_port = port;
-}
-
-static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
-{
- int res;
-
- mm_segment_t oldfs = get_fs();
- set_fs(get_ds());
- res = devinet_ioctl(cmd, (struct ifreq __user *) arg);
- set_fs(oldfs);
- return res;
-}
-
-static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
-{
- int res;
-
- mm_segment_t oldfs = get_fs();
- set_fs(get_ds());
- res = ip_rt_ioctl(cmd, (void __user *) arg);
- set_fs(oldfs);
- return res;
-}
-
-/*
- * Set up interface addresses and routes.
- */
-
-static int __init ic_setup_if(void)
-{
- struct ifreq ir;
- struct sockaddr_in *sin = (void *) &ir.ifr_ifru.ifru_addr;
- int err;
-
- memset(&ir, 0, sizeof(ir));
- strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
- set_sockaddr(sin, ic_myaddr, 0);
- if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
- printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
- return -1;
- }
- set_sockaddr(sin, ic_netmask, 0);
- if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
- printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
- return -1;
- }
- set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
- if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
- printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
- return -1;
- }
- return 0;
-}
-
-static int __init ic_setup_routes(void)
-{
- /* No need to setup device routes, only the default route... */
-
- if (ic_gateway != INADDR_NONE) {
- struct rtentry rm;
- int err;
-
- memset(&rm, 0, sizeof(rm));
- if ((ic_gateway ^ ic_myaddr) & ic_netmask) {
- printk(KERN_ERR "IP-Config: Gateway not on directly connected network.\n");
- return -1;
- }
- set_sockaddr((struct sockaddr_in *) &rm.rt_dst, 0, 0);
- set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0);
- set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
- rm.rt_flags = RTF_UP | RTF_GATEWAY;
- if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
- printk(KERN_ERR "IP-Config: Cannot add default route (%d).\n", err);
- return -1;
- }
- }
-
- return 0;
-}
-
-/*
- * Fill in default values for all missing parameters.
- */
-
-static int __init ic_defaults(void)
-{
- /*
- * At this point we have no userspace running so need not
- * claim locks on system_utsname
- */
-
- if (!ic_host_name_set)
- sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
-
- if (root_server_addr == INADDR_NONE)
- root_server_addr = ic_servaddr;
-
- if (ic_netmask == INADDR_NONE) {
- if (IN_CLASSA(ntohl(ic_myaddr)))
- ic_netmask = htonl(IN_CLASSA_NET);
- else if (IN_CLASSB(ntohl(ic_myaddr)))
- ic_netmask = htonl(IN_CLASSB_NET);
- else if (IN_CLASSC(ntohl(ic_myaddr)))
- ic_netmask = htonl(IN_CLASSC_NET);
- else {
- printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
- NIPQUAD(ic_myaddr));
- return -1;
- }
- printk("IP-Config: Guessing netmask %u.%u.%u.%u\n", NIPQUAD(ic_netmask));
- }
-
- return 0;
-}
-
-/*
- * RARP support.
- */
-
-#ifdef IPCONFIG_RARP
-
-static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev);
-
-static struct packet_type rarp_packet_type __initdata = {
- .type = __constant_htons(ETH_P_RARP),
- .func = ic_rarp_recv,
-};
-
-static inline void ic_rarp_init(void)
-{
- dev_add_pack(&rarp_packet_type);
-}
-
-static inline void ic_rarp_cleanup(void)
-{
- dev_remove_pack(&rarp_packet_type);
-}
-
-/*
- * Process received RARP packet.
- */
-static int __init
-ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
-{
- struct arphdr *rarp;
- unsigned char *rarp_ptr;
- unsigned long sip, tip;
- unsigned char *sha, *tha; /* s for "source", t for "target" */
- struct ic_device *d;
-
- if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
- return NET_RX_DROP;
-
- if (!pskb_may_pull(skb, sizeof(struct arphdr)))
- goto drop;
-
- /* Basic sanity checks can be done without the lock. */
- rarp = (struct arphdr *)skb->h.raw;
-
- /* If this test doesn't pass, it's not IP, or we should
- * ignore it anyway.
- */
- if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd))
- goto drop;
-
- /* If it's not a RARP reply, delete it. */
- if (rarp->ar_op != htons(ARPOP_RREPLY))
- goto drop;
-
- /* If it's not Ethernet, delete it. */
- if (rarp->ar_pro != htons(ETH_P_IP))
- goto drop;
-
- if (!pskb_may_pull(skb,
- sizeof(struct arphdr) +
- (2 * dev->addr_len) +
- (2 * 4)))
- goto drop;
-
- /* OK, it is all there and looks valid, process... */
- rarp = (struct arphdr *)skb->h.raw;
- rarp_ptr = (unsigned char *) (rarp + 1);
-
- /* One reply at a time, please. */
- spin_lock(&ic_recv_lock);
-
- /* If we already have a reply, just drop the packet */
- if (ic_got_reply)
- goto drop_unlock;
-
- /* Find the ic_device that the packet arrived on */
- d = ic_first_dev;
- while (d && d->dev != dev)
- d = d->next;
- if (!d)
- goto drop_unlock; /* should never happen */
-
- /* Extract variable-width fields */
- sha = rarp_ptr;
- rarp_ptr += dev->addr_len;
- memcpy(&sip, rarp_ptr, 4);
- rarp_ptr += 4;
- tha = rarp_ptr;
- rarp_ptr += dev->addr_len;
- memcpy(&tip, rarp_ptr, 4);
-
- /* Discard packets which are not meant for us. */
- if (memcmp(tha, dev->dev_addr, dev->addr_len))
- goto drop_unlock;
-
- /* Discard packets which are not from specified server. */
- if (ic_servaddr != INADDR_NONE && ic_servaddr != sip)
- goto drop_unlock;
-
- /* We have a winner! */
- ic_dev = dev;
- if (ic_myaddr == INADDR_NONE)
- ic_myaddr = tip;
- ic_servaddr = sip;
- ic_got_reply = IC_RARP;
-
-drop_unlock:
- /* Show's over. Nothing to see here. */
- spin_unlock(&ic_recv_lock);
-
-drop:
- /* Throw the packet out. */
- kfree_skb(skb);
- return 0;
-}
-
-
-/*
- * Send RARP request packet over a single interface.
- */
-static void __init ic_rarp_send_if(struct ic_device *d)
-{
- struct net_device *dev = d->dev;
- arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
- dev->dev_addr, dev->dev_addr);
-}
-#endif
-
-/*
- * DHCP/BOOTP support.
- */
-
-#ifdef IPCONFIG_BOOTP
-
-struct bootp_pkt { /* BOOTP packet format */
- struct iphdr iph; /* IP header */
- struct udphdr udph; /* UDP header */
- u8 op; /* 1=request, 2=reply */
- u8 htype; /* HW address type */
- u8 hlen; /* HW address length */
- u8 hops; /* Used only by gateways */
- u32 xid; /* Transaction ID */
- u16 secs; /* Seconds since we started */
- u16 flags; /* Just what it says */
- u32 client_ip; /* Client's IP address if known */
- u32 your_ip; /* Assigned IP address */
- u32 server_ip; /* (Next, e.g. NFS) Server's IP address */
- u32 relay_ip; /* IP address of BOOTP relay */
- u8 hw_addr[16]; /* Client's HW address */
- u8 serv_name[64]; /* Server host name */
- u8 boot_file[128]; /* Name of boot file */
- u8 exten[312]; /* DHCP options / BOOTP vendor extensions */
-};
-
-/* packet ops */
-#define BOOTP_REQUEST 1
-#define BOOTP_REPLY 2
-
-/* DHCP message types */
-#define DHCPDISCOVER 1
-#define DHCPOFFER 2
-#define DHCPREQUEST 3
-#define DHCPDECLINE 4
-#define DHCPACK 5
-#define DHCPNAK 6
-#define DHCPRELEASE 7
-#define DHCPINFORM 8
-
-static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev);
-
-static struct packet_type bootp_packet_type __initdata = {
- .type = __constant_htons(ETH_P_IP),
- .func = ic_bootp_recv,
-};
-
-
-/*
- * Initialize DHCP/BOOTP extension fields in the request.
- */
-
-static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
-
-#ifdef IPCONFIG_DHCP
-
-static void __init
-ic_dhcp_init_options(u8 *options)
-{
- u8 mt = ((ic_servaddr == INADDR_NONE)
- ? DHCPDISCOVER : DHCPREQUEST);
- u8 *e = options;
-
-#ifdef IPCONFIG_DEBUG
- printk("DHCP: Sending message type %d\n", mt);
-#endif
-
- memcpy(e, ic_bootp_cookie, 4); /* RFC1048 Magic Cookie */
- e += 4;
-
- *e++ = 53; /* DHCP message type */
- *e++ = 1;
- *e++ = mt;
-
- if (mt == DHCPREQUEST) {
- *e++ = 54; /* Server ID (IP address) */
- *e++ = 4;
- memcpy(e, &ic_servaddr, 4);
- e += 4;
-
- *e++ = 50; /* Requested IP address */
- *e++ = 4;
- memcpy(e, &ic_myaddr, 4);
- e += 4;
- }
-
- /* always? */
- {
- static const u8 ic_req_params[] = {
- 1, /* Subnet mask */
- 3, /* Default gateway */
- 6, /* DNS server */
- 12, /* Host name */
- 15, /* Domain name */
- 17, /* Boot path */
- 40, /* NIS domain name */
- };
-
- *e++ = 55; /* Parameter request list */
- *e++ = sizeof(ic_req_params);
- memcpy(e, ic_req_params, sizeof(ic_req_params));
- e += sizeof(ic_req_params);
- }
-
- *e++ = 255; /* End of the list */
-}
-
-#endif /* IPCONFIG_DHCP */
-
-static void __init ic_bootp_init_ext(u8 *e)
-{
- memcpy(e, ic_bootp_cookie, 4); /* RFC1048 Magic Cookie */
- e += 4;
- *e++ = 1; /* Subnet mask request */
- *e++ = 4;
- e += 4;
- *e++ = 3; /* Default gateway request */
- *e++ = 4;
- e += 4;
- *e++ = 5; /* Name server request */
- *e++ = 8;
- e += 8;
- *e++ = 12; /* Host name request */
- *e++ = 32;
- e += 32;
- *e++ = 40; /* NIS Domain name request */
- *e++ = 32;
- e += 32;
- *e++ = 17; /* Boot path */
- *e++ = 40;
- e += 40;
-
- *e++ = 57; /* set extension buffer size for reply */
- *e++ = 2;
- *e++ = 1; /* 128+236+8+20+14, see dhcpd sources */
- *e++ = 150;
-
- *e++ = 255; /* End of the list */
-}
-
-
-/*
- * Initialize the DHCP/BOOTP mechanism.
- */
-static inline void ic_bootp_init(void)
-{
- int i;
-
- for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
- ic_nameservers[i] = INADDR_NONE;
-
- dev_add_pack(&bootp_packet_type);
-}
-
-
-/*
- * DHCP/BOOTP cleanup.
- */
-static inline void ic_bootp_cleanup(void)
-{
- dev_remove_pack(&bootp_packet_type);
-}
-
-
-/*
- * Send DHCP/BOOTP request to single interface.
- */
-static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_diff)
-{
- struct net_device *dev = d->dev;
- struct sk_buff *skb;
- struct bootp_pkt *b;
- int hh_len = LL_RESERVED_SPACE(dev);
- struct iphdr *h;
-
- /* Allocate packet */
- skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
- if (!skb)
- return;
- skb_reserve(skb, hh_len);
- b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
- memset(b, 0, sizeof(struct bootp_pkt));
-
- /* Construct IP header */
- skb->nh.iph = h = &b->iph;
- h->version = 4;
- h->ihl = 5;
- h->tot_len = htons(sizeof(struct bootp_pkt));
- h->frag_off = htons(IP_DF);
- h->ttl = 64;
- h->protocol = IPPROTO_UDP;
- h->daddr = INADDR_BROADCAST;
- h->check = ip_fast_csum((unsigned char *) h, h->ihl);
-
- /* Construct UDP header */
- b->udph.source = htons(68);
- b->udph.dest = htons(67);
- b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
- /* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
-
- /* Construct DHCP/BOOTP header */
- b->op = BOOTP_REQUEST;
- if (dev->type < 256) /* check for false types */
- b->htype = dev->type;
- else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */
- b->htype = ARPHRD_IEEE802;
- else if (dev->type == ARPHRD_FDDI)
- b->htype = ARPHRD_ETHER;
- else {
- printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
- b->htype = dev->type; /* can cause undefined behavior */
- }
- b->hlen = dev->addr_len;
- b->your_ip = INADDR_NONE;
- b->server_ip = INADDR_NONE;
- memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
- b->secs = htons(jiffies_diff / HZ);
- b->xid = d->xid;
-
- /* add DHCP options or BOOTP extensions */
-#ifdef IPCONFIG_DHCP
- if (ic_proto_enabled & IC_USE_DHCP)
- ic_dhcp_init_options(b->exten);
- else
-#endif
- ic_bootp_init_ext(b->exten);
-
- /* Chain packet down the line... */
- skb->dev = dev;
- skb->protocol = htons(ETH_P_IP);
- if ((dev->hard_header &&
- dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
- dev_queue_xmit(skb) < 0)
- printk("E");
-}
-
-
-/*
- * Copy BOOTP-supplied string if not already set.
- */
-static int __init ic_bootp_string(char *dest, char *src, int len, int max)
-{
- if (!len)
- return 0;
- if (len > max-1)
- len = max-1;
- memcpy(dest, src, len);
- dest[len] = '\0';
- return 1;
-}
-
-
-/*
- * Process BOOTP extensions.
- */
-static void __init ic_do_bootp_ext(u8 *ext)
-{
- u8 servers;
- int i;
-
-#ifdef IPCONFIG_DEBUG
- u8 *c;
-
- printk("DHCP/BOOTP: Got extension %d:",*ext);
- for(c=ext+2; c<ext+2+ext[1]; c++)
- printk(" %02x", *c);
- printk("\n");
-#endif
-
- switch (*ext++) {
- case 1: /* Subnet mask */
- if (ic_netmask == INADDR_NONE)
- memcpy(&ic_netmask, ext+1, 4);
- break;
- case 3: /* Default gateway */
- if (ic_gateway == INADDR_NONE)
- memcpy(&ic_gateway, ext+1, 4);
- break;
- case 6: /* DNS server */
- servers= *ext/4;
- if (servers > CONF_NAMESERVERS_MAX)
- servers = CONF_NAMESERVERS_MAX;
- for (i = 0; i < servers; i++) {
- if (ic_nameservers[i] == INADDR_NONE)
- memcpy(&ic_nameservers[i], ext+1+4*i, 4);
- }
- break;
- case 12: /* Host name */
- ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
- ic_host_name_set = 1;
- break;
- case 15: /* Domain name (DNS) */
- ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain));
- break;
- case 17: /* Root path */
- if (!root_server_path[0])
- ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
- break;
- case 40: /* NIS Domain name (_not_ DNS) */
- ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
- break;
- }
-}
-
-
-/*
- * Receive BOOTP reply.
- */
-static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
-{
- struct bootp_pkt *b;
- struct iphdr *h;
- struct ic_device *d;
- int len, ext_len;
-
- /* Perform verifications before taking the lock. */
- if (skb->pkt_type == PACKET_OTHERHOST)
- goto drop;
-
- if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
- return NET_RX_DROP;
-
- if (!pskb_may_pull(skb,
- sizeof(struct iphdr) +
- sizeof(struct udphdr)))
- goto drop;
-
- b = (struct bootp_pkt *) skb->nh.iph;
- h = &b->iph;
-
- if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)
- goto drop;
-
- /* Fragments are not supported */
- if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
- if (net_ratelimit())
- printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented "
- "reply.\n");
- goto drop;
- }
-
- if (skb->len < ntohs(h->tot_len))
- goto drop;
-
- if (ip_fast_csum((char *) h, h->ihl))
- goto drop;
-
- if (b->udph.source != htons(67) || b->udph.dest != htons(68))
- goto drop;
-
- if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
- goto drop;
-
- len = ntohs(b->udph.len) - sizeof(struct udphdr);
- ext_len = len - (sizeof(*b) -
- sizeof(struct iphdr) -
- sizeof(struct udphdr) -
- sizeof(b->exten));
- if (ext_len < 0)
- goto drop;
-
- /* Ok the front looks good, make sure we can get at the rest. */
- if (!pskb_may_pull(skb, skb->len))
- goto drop;
-
- b = (struct bootp_pkt *) skb->nh.iph;
- h = &b->iph;
-
- /* One reply at a time, please. */
- spin_lock(&ic_recv_lock);
-
- /* If we already have a reply, just drop the packet */
- if (ic_got_reply)
- goto drop_unlock;
-
- /* Find the ic_device that the packet arrived on */
- d = ic_first_dev;
- while (d && d->dev != dev)
- d = d->next;
- if (!d)
- goto drop_unlock; /* should never happen */
-
- /* Is it a reply to our BOOTP request? */
- if (b->op != BOOTP_REPLY ||
- b->xid != d->xid) {
- if (net_ratelimit())
- printk(KERN_ERR "DHCP/BOOTP: Reply not for us, "
- "op[%x] xid[%x]\n",
- b->op, b->xid);
- goto drop_unlock;
- }
-
- /* Parse extensions */
- if (ext_len >= 4 &&
- !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
- u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
- u8 *ext;
-
-#ifdef IPCONFIG_DHCP
- if (ic_proto_enabled & IC_USE_DHCP) {
- u32 server_id = INADDR_NONE;
- int mt = 0;
-
- ext = &b->exten[4];
- while (ext < end && *ext != 0xff) {
- u8 *opt = ext++;
- if (*opt == 0) /* Padding */
- continue;
- ext += *ext + 1;
- if (ext >= end)
- break;
- switch (*opt) {
- case 53: /* Message type */
- if (opt[1])
- mt = opt[2];
- break;
- case 54: /* Server ID (IP address) */
- if (opt[1] >= 4)
- memcpy(&server_id, opt + 2, 4);
- break;
- };
- }
-
-#ifdef IPCONFIG_DEBUG
- printk("DHCP: Got message type %d\n", mt);
-#endif
-
- switch (mt) {
- case DHCPOFFER:
- /* While in the process of accepting one offer,
- * ignore all others.
- */
- if (ic_myaddr != INADDR_NONE)
- goto drop_unlock;
-
- /* Let's accept that offer. */
- ic_myaddr = b->your_ip;
- ic_servaddr = server_id;
-#ifdef IPCONFIG_DEBUG
- printk("DHCP: Offered address %u.%u.%u.%u",
- NIPQUAD(ic_myaddr));
- printk(" by server %u.%u.%u.%u\n",
- NIPQUAD(ic_servaddr));
-#endif
- /* The DHCP indicated server address takes
- * precedence over the bootp header one if
- * they are different.
- */
- if ((server_id != INADDR_NONE) &&
- (b->server_ip != server_id))
- b->server_ip = ic_servaddr;
- break;
-
- case DHCPACK:
- if (memcmp(dev->dev_addr, b->hw_addr, dev->addr_len) != 0)
- goto drop_unlock;
-
- /* Yeah! */
- break;
-
- default:
- /* Urque. Forget it*/
- ic_myaddr = INADDR_NONE;
- ic_servaddr = INADDR_NONE;
- goto drop_unlock;
- };
-
- ic_dhcp_msgtype = mt;
-
- }
-#endif /* IPCONFIG_DHCP */
-
- ext = &b->exten[4];
- while (ext < end && *ext != 0xff) {
- u8 *opt = ext++;
- if (*opt == 0) /* Padding */
- continue;
- ext += *ext + 1;
- if (ext < end)
- ic_do_bootp_ext(opt);
- }
- }
-
- /* We have a winner! */
- ic_dev = dev;
- ic_myaddr = b->your_ip;
- ic_servaddr = b->server_ip;
- if (ic_gateway == INADDR_NONE && b->relay_ip)
- ic_gateway = b->relay_ip;
- if (ic_nameservers[0] == INADDR_NONE)
- ic_nameservers[0] = ic_servaddr;
- ic_got_reply = IC_BOOTP;
-
-drop_unlock:
- /* Show's over. Nothing to see here. */
- spin_unlock(&ic_recv_lock);
-
-drop:
- /* Throw the packet out. */
- kfree_skb(skb);
-
- return 0;
-}
-
-
-#endif
-
-
-/*
- * Dynamic IP configuration -- DHCP, BOOTP, RARP.
- */
-
-#ifdef IPCONFIG_DYNAMIC
-
-static int __init ic_dynamic(void)
-{
- int retries;
- struct ic_device *d;
- unsigned long start_jiffies, timeout, jiff;
- int do_bootp = ic_proto_have_if & IC_BOOTP;
- int do_rarp = ic_proto_have_if & IC_RARP;
-
- /*
- * If none of DHCP/BOOTP/RARP was selected, return with an error.
- * This routine gets only called when some pieces of information
- * are missing, and without DHCP/BOOTP/RARP we are unable to get it.
- */
- if (!ic_proto_enabled) {
- printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
- return -1;
- }
-
-#ifdef IPCONFIG_BOOTP
- if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)
- printk(KERN_ERR "DHCP/BOOTP: No suitable device found.\n");
-#endif
-#ifdef IPCONFIG_RARP
- if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)
- printk(KERN_ERR "RARP: No suitable device found.\n");
-#endif
-
- if (!ic_proto_have_if)
- /* Error message already printed */
- return -1;
-
- /*
- * Setup protocols
- */
-#ifdef IPCONFIG_BOOTP
- if (do_bootp)
- ic_bootp_init();
-#endif
-#ifdef IPCONFIG_RARP
- if (do_rarp)
- ic_rarp_init();
-#endif
-
- /*
- * Send requests and wait, until we get an answer. This loop
- * seems to be a terrible waste of CPU time, but actually there is
- * only one process running at all, so we don't need to use any
- * scheduler functions.
- * [Actually we could now, but the nothing else running note still
- * applies.. - AC]
- */
- printk(KERN_NOTICE "Sending %s%s%s requests .",
- do_bootp
- ? ((ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP") : "",
- (do_bootp && do_rarp) ? " and " : "",
- do_rarp ? "RARP" : "");
-
- start_jiffies = jiffies;
- d = ic_first_dev;
- retries = CONF_SEND_RETRIES;
- get_random_bytes(&timeout, sizeof(timeout));
- timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
- for(;;) {
-#ifdef IPCONFIG_BOOTP
- if (do_bootp && (d->able & IC_BOOTP))
- ic_bootp_send_if(d, jiffies - start_jiffies);
-#endif
-#ifdef IPCONFIG_RARP
- if (do_rarp && (d->able & IC_RARP))
- ic_rarp_send_if(d);
-#endif
-
- jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);
- while (time_before(jiffies, jiff) && !ic_got_reply)
- schedule_timeout_uninterruptible(1);
-#ifdef IPCONFIG_DHCP
- /* DHCP isn't done until we get a DHCPACK. */
- if ((ic_got_reply & IC_BOOTP)
- && (ic_proto_enabled & IC_USE_DHCP)
- && ic_dhcp_msgtype != DHCPACK)
- {
- ic_got_reply = 0;
- printk(",");
- continue;
- }
-#endif /* IPCONFIG_DHCP */
-
- if (ic_got_reply) {
- printk(" OK\n");
- break;
- }
-
- if ((d = d->next))
- continue;
-
- if (! --retries) {
- printk(" timed out!\n");
- break;
- }
-
- d = ic_first_dev;
-
- timeout = timeout CONF_TIMEOUT_MULT;
- if (timeout > CONF_TIMEOUT_MAX)
- timeout = CONF_TIMEOUT_MAX;
-
- printk(".");
- }
-
-#ifdef IPCONFIG_BOOTP
- if (do_bootp)
- ic_bootp_cleanup();
-#endif
-#ifdef IPCONFIG_RARP
- if (do_rarp)
- ic_rarp_cleanup();
-#endif
-
- if (!ic_got_reply) {
- ic_myaddr = INADDR_NONE;
- return -1;
- }
-
- printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
- ((ic_got_reply & IC_RARP) ? "RARP"
- : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
- NIPQUAD(ic_servaddr));
- printk("my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr));
-
- return 0;
-}
-
-#endif /* IPCONFIG_DYNAMIC */
-
-#ifdef CONFIG_PROC_FS
-
-static int pnp_seq_show(struct seq_file *seq, void *v)
-{
- int i;
-
- if (ic_proto_used & IC_PROTO)
- seq_printf(seq, "#PROTO: %s\n",
- (ic_proto_used & IC_RARP) ? "RARP"
- : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
- else
- seq_puts(seq, "#MANUAL\n");
-
- if (ic_domain[0])
- seq_printf(seq,
- "domain %s\n", ic_domain);
- for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
- if (ic_nameservers[i] != INADDR_NONE)
- seq_printf(seq,
- "nameserver %u.%u.%u.%u\n",
- NIPQUAD(ic_nameservers[i]));
- }
- if (ic_servaddr != INADDR_NONE)
- seq_printf(seq,
- "bootserver %u.%u.%u.%u\n",
- NIPQUAD(ic_servaddr));
- return 0;
-}
-
-static int pnp_seq_open(struct inode *indoe, struct file *file)
-{
- return single_open(file, pnp_seq_show, NULL);
-}
-
-static struct file_operations pnp_seq_fops = {
- .owner = THIS_MODULE,
- .open = pnp_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif /* CONFIG_PROC_FS */
-
-/*
- * Extract IP address from the parameter string if needed. Note that we
- * need to have root_server_addr set _before_ IPConfig gets called as it
- * can override it.
- */
-u32 __init root_nfs_parse_addr(char *name)
-{
- u32 addr;
- int octets = 0;
- char *cp, *cq;
-
- cp = cq = name;
- while (octets < 4) {
- while (*cp >= '0' && *cp <= '9')
- cp++;
- if (cp == cq || cp - cq > 3)
- break;
- if (*cp == '.' || octets == 3)
- octets++;
- if (octets < 4)
- cp++;
- cq = cp;
- }
- if (octets == 4 && (*cp == ':' || *cp == '\0')) {
- if (*cp == ':')
- *cp++ = '\0';
- addr = in_aton(name);
- memmove(name, cp, strlen(cp) + 1);
- } else
- addr = INADDR_NONE;
-
- return addr;
-}
-
-/*
- * IP Autoconfig dispatcher.
- */
-
-static int __init ip_auto_config(void)
-{
- u32 addr;
-
-#ifdef CONFIG_PROC_FS
- proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
-#endif /* CONFIG_PROC_FS */
-
- if (!ic_enable)
- return 0;
-
- DBG(("IP-Config: Entered.\n"));
-#ifdef IPCONFIG_DYNAMIC
- try_try_again:
-#endif
- /* Give hardware a chance to settle */
- msleep(CONF_PRE_OPEN);
-
- /* Setup all network devices */
- if (ic_open_devs() < 0)
- return -1;
-
- /* Give drivers a chance to settle */
- ssleep(CONF_POST_OPEN);
-
- /*
- * If the config information is insufficient (e.g., our IP address or
- * IP address of the boot server is missing or we have multiple network
- * interfaces and no default was set), use BOOTP or RARP to get the
- * missing values.
- */
- if (ic_myaddr == INADDR_NONE ||
-#ifdef CONFIG_ROOT_NFS
- (MAJOR(ROOT_DEV) == UNNAMED_MAJOR
- && root_server_addr == INADDR_NONE
- && ic_servaddr == INADDR_NONE) ||
-#endif
- ic_first_dev->next) {
-#ifdef IPCONFIG_DYNAMIC
-
- int retries = CONF_OPEN_RETRIES;
-
- if (ic_dynamic() < 0) {
- ic_close_devs();
-
- /*
- * I don't know why, but sometimes the
- * eepro100 driver (at least) gets upset and
- * doesn't work the first time it's opened.
- * But then if you close it and reopen it, it
- * works just fine. So we need to try that at
- * least once before giving up.
- *
- * Also, if the root will be NFS-mounted, we
- * have nowhere to go if DHCP fails. So we
- * just have to keep trying forever.
- *
- * -- Chip
- */
-#ifdef CONFIG_ROOT_NFS
- if (ROOT_DEV == Root_NFS) {
- printk(KERN_ERR
- "IP-Config: Retrying forever (NFS root)...\n");
- goto try_try_again;
- }
-#endif
-
- if (--retries) {
- printk(KERN_ERR
- "IP-Config: Reopening network devices...\n");
- goto try_try_again;
- }
-
- /* Oh, well. At least we tried. */
- printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n");
- return -1;
- }
-#else /* !DYNAMIC */
- printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
- ic_close_devs();
- return -1;
-#endif /* IPCONFIG_DYNAMIC */
- } else {
- /* Device selected manually or only one device -> use it */
- ic_dev = ic_first_dev->dev;
- }
-
- addr = root_nfs_parse_addr(root_server_path);
- if (root_server_addr == INADDR_NONE)
- root_server_addr = addr;
-
- /*
- * Use defaults whereever applicable.
- */
- if (ic_defaults() < 0)
- return -1;
-
- /*
- * Close all network devices except the device we've
- * autoconfigured and set up routes.
- */
- ic_close_devs();
- if (ic_setup_if() < 0 || ic_setup_routes() < 0)
- return -1;
-
- /*
- * Record which protocol was actually used.
- */
-#ifdef IPCONFIG_DYNAMIC
- ic_proto_used = ic_got_reply | (ic_proto_enabled & IC_USE_DHCP);
-#endif
-
-#ifndef IPCONFIG_SILENT
- /*
- * Clue in the operator.
- */
- printk("IP-Config: Complete:");
- printk("\n device=%s", ic_dev->name);
- printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr));
- printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
- printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
- printk(",\n host=%s, domain=%s, nis-domain=%s",
- system_utsname.nodename, ic_domain, system_utsname.domainname);
- printk(",\n bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
- printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
- printk(", rootpath=%s", root_server_path);
- printk("\n");
-#endif /* !SILENT */
-
- return 0;
-}
-
-late_initcall(ip_auto_config);
-
-
-/*
- * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
- * command line parameter. It consists of option fields separated by colons in
- * the following order:
- *
- * <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<PROTO>
- *
- * Any of the fields can be empty which means to use a default value:
- * <client-ip> - address given by BOOTP or RARP
- * <server-ip> - address of host returning BOOTP or RARP packet
- * <gw-ip> - none, or the address returned by BOOTP
- * <netmask> - automatically determined from <client-ip>, or the
- * one returned by BOOTP
- * <host name> - <client-ip> in ASCII notation, or the name returned
- * by BOOTP
- * <device> - use all available devices
- * <PROTO>:
- * off|none - don't do autoconfig at all (DEFAULT)
- * on|any - use any configured protocol
- * dhcp|bootp|rarp - use only the specified protocol
- * both - use both BOOTP and RARP (not DHCP)
- */
-static int __init ic_proto_name(char *name)
-{
- if (!strcmp(name, "on") || !strcmp(name, "any")) {
- return 1;
- }
-#ifdef CONFIG_IP_PNP_DHCP
- else if (!strcmp(name, "dhcp")) {
- ic_proto_enabled &= ~IC_RARP;
- return 1;
- }
-#endif
-#ifdef CONFIG_IP_PNP_BOOTP
- else if (!strcmp(name, "bootp")) {
- ic_proto_enabled &= ~(IC_RARP | IC_USE_DHCP);
- return 1;
- }
-#endif
-#ifdef CONFIG_IP_PNP_RARP
- else if (!strcmp(name, "rarp")) {
- ic_proto_enabled &= ~(IC_BOOTP | IC_USE_DHCP);
- return 1;
- }
-#endif
-#ifdef IPCONFIG_DYNAMIC
- else if (!strcmp(name, "both")) {
- ic_proto_enabled &= ~IC_USE_DHCP; /* backward compat :-( */
- return 1;
- }
-#endif
- return 0;
-}
-
-static int __init ip_auto_config_setup(char *addrs)
-{
- char *cp, *ip, *dp;
- int num = 0;
-
- ic_set_manually = 1;
-
- ic_enable = (*addrs &&
- (strcmp(addrs, "off") != 0) &&
- (strcmp(addrs, "none") != 0));
- if (!ic_enable)
- return 1;
-
- if (ic_proto_name(addrs))
- return 1;
-
- /* Parse the whole string */
- ip = addrs;
- while (ip && *ip) {
- if ((cp = strchr(ip, ':')))
- *cp++ = '\0';
- if (strlen(ip) > 0) {
- DBG(("IP-Config: Parameter #%d: `%s'\n", num, ip));
- switch (num) {
- case 0:
- if ((ic_myaddr = in_aton(ip)) == INADDR_ANY)
- ic_myaddr = INADDR_NONE;
- break;
- case 1:
- if ((ic_servaddr = in_aton(ip)) == INADDR_ANY)
- ic_servaddr = INADDR_NONE;
- break;
- case 2:
- if ((ic_gateway = in_aton(ip)) == INADDR_ANY)
- ic_gateway = INADDR_NONE;
- break;
- case 3:
- if ((ic_netmask = in_aton(ip)) == INADDR_ANY)
- ic_netmask = INADDR_NONE;
- break;
- case 4:
- if ((dp = strchr(ip, '.'))) {
- *dp++ = '\0';
- strlcpy(system_utsname.domainname, dp,
- sizeof(system_utsname.domainname));
- }
- strlcpy(system_utsname.nodename, ip,
- sizeof(system_utsname.nodename));
- ic_host_name_set = 1;
- break;
- case 5:
- strlcpy(user_dev_name, ip, sizeof(user_dev_name));
- break;
- case 6:
- ic_proto_name(ip);
- break;
- }
- }
- ip = cp;
- num++;
- }
-
- return 1;
-}
-
-static int __init nfsaddrs_config_setup(char *addrs)
-{
- return ip_auto_config_setup(addrs);
-}
-
-__setup("ip=", ip_auto_config_setup);
-__setup("nfsaddrs=", nfsaddrs_config_setup);