Commit 63864c3c authored by Trond Myklebust's avatar Trond Myklebust

From: <martin@meltin.net>

 
Forward-port from 2.4:
 
The following patch pulls an NFS server IP address off root_server_path
(handed out via the DHCP root-path option), if it is present.  For example,
you can do this sort of thing in dhcpd.conf:
 
  root-path = 192.168.1.33:/tftpboot/yip.zImage
 
This lets you mount your root filesystem off a different machine than you
booted from, without needing to use kernel command-line parameters.
 
The patch appears to be backwards compatible.
 
RFC2132 says this about the root-path option:
 
   This option specifies the path-name that contains the client's root
   disk.  The path is formatted as a character string consisting of
   characters from the NVT ASCII character set.
 
This is sufficiently vague to allow the path-name to include an IP-address.
Also, I found some documentation for FreeBSD saying it does this too, so it
must be right, because those FreeBSD guys are really smart...  :-)
 
The only downside of the patch is that the summary that ipconfig prints can
be a little odd when the kernel command line overrides whatever ipconfig gets
from (say) DHCP.  The address from the kernel command line seems to get
stripped off early, so ipconfig reports it, but it doesn't report the kernel
command line NFS path, since that's handled a bit later...  This small
cosmetic problem looks difficult to "fix" without rewriting quite a bit of
stuff...
parent 0339afa3
...@@ -165,37 +165,6 @@ static struct nfs_bool_opts { ...@@ -165,37 +165,6 @@ static struct nfs_bool_opts {
}; };
/*
* 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.
*/
static void __init root_nfs_parse_addr(char *name)
{
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';
root_server_addr = in_aton(name);
strcpy(name, cp);
}
}
/* /*
* Parse option string. * Parse option string.
*/ */
...@@ -345,7 +314,7 @@ int __init nfs_root_setup(char *line) ...@@ -345,7 +314,7 @@ int __init nfs_root_setup(char *line)
line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0'; line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
sprintf(nfs_root_name, NFS_ROOT, line); sprintf(nfs_root_name, NFS_ROOT, line);
} }
root_nfs_parse_addr(nfs_root_name); root_server_addr = root_nfs_parse_addr(nfs_root_name);
return 1; return 1;
} }
......
...@@ -276,6 +276,9 @@ extern void nfs_end_attr_update(struct inode *); ...@@ -276,6 +276,9 @@ extern void nfs_end_attr_update(struct inode *);
extern void nfs_begin_data_update(struct inode *); extern void nfs_begin_data_update(struct inode *);
extern void nfs_end_data_update(struct inode *); extern void nfs_end_data_update(struct inode *);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/
/* /*
* linux/fs/nfs/file.c * linux/fs/nfs/file.c
*/ */
......
...@@ -1188,6 +1188,40 @@ static struct file_operations pnp_seq_fops = { ...@@ -1188,6 +1188,40 @@ static struct file_operations pnp_seq_fops = {
}; };
#endif /* CONFIG_PROC_FS */ #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);
strcpy(name, cp);
} else
addr = INADDR_NONE;
return addr;
}
/* /*
* IP Autoconfig dispatcher. * IP Autoconfig dispatcher.
*/ */
...@@ -1195,6 +1229,7 @@ static struct file_operations pnp_seq_fops = { ...@@ -1195,6 +1229,7 @@ static struct file_operations pnp_seq_fops = {
static int __init ip_auto_config(void) static int __init ip_auto_config(void)
{ {
unsigned long jiff; unsigned long jiff;
u32 addr;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops); proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
...@@ -1283,6 +1318,10 @@ static int __init ip_auto_config(void) ...@@ -1283,6 +1318,10 @@ static int __init ip_auto_config(void)
ic_dev = ic_first_dev->dev; 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. * Use defaults whereever applicable.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment