
david.balazic at uni-mb
Jan 7, 1998, 3:16 AM
Post #1 of 1
(189 views)
Permalink
|
|
Made nfs-root work with 2.1.78 !
|
|
I succeded in making an nfs-root "diskless" linux system with kernel 2.1.78 The old setup I used was kernel 2.0.33 with nfs-root option It was loaded with loadlin and the following command line options : nfsroot=199.4.5.6:/root-fs/my-clients-root-fs nfsaddrs=199.4.5.10:199.4.5.6:199.4.5.1:255.255.255.0:blondie:: 199.4.5.6 - nfs-server IP 199.4.5.10 - client IP 199.4.5.1 - gateway IP 255.255.255.0 - netmask ( IPs are not my real IPs !! ) The mounted root-fs is minimal and the first commands in /etc/rc.S ( fisrt script to execute ) are mounts that mount /bin /usr /home .. also over nfs This setup works OK Let's look at 2.1.78 now : I compiled the kernel with options : IP autoconfig - YES RARP - NO BOOTP - NO root-fs on NFS - YES This wont work , because of two bugs in the kernel : First : IP auto config will fail ( write a message on boot : "IP-Config: Auto-configuration of network failed." and continue ), because in file net/ipv4/ipconfig.c function __initfunc(int ip_auto_config(void)) ( line 1016 ) statement --- if (ic_myaddr == INADDR_NONE || #ifdef CONFIG_ROOT_NFS root_server_addr == INADDR_NONE || #endif (ic_first_dev && ic_first_dev->next)) { #ifdef CONFIG_IP_PNP_DYNAMIC if (ic_dynamic() < 0) { printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n"); ic_close_devs(); return -1; } --- will FAIL , because root_server_addr is always INADDR_NONE at this point. It would be set in the function __initfunc(int ic_defaults(void)) ( same file ), but it is called only after the prevoius if () , so it is never reached. The solution is to move the lines : if (ic_defaults() < 0) return -1; before the mentioned if(...) statement Second : After that the kernel will cause an oops , in file fs/super.c function , line 1060 : ----- if ((fs_type = get_fs_type("nfs"))) { if ((vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/"))) { /* wrong , mnt_sb is not set in add_vfsmnt() !! */ sb = vfsmnt->mnt_sb; /* sb is NULL , so the following line cause a NULL dereference error ! */ sb->s_dev = get_unnamed_dev(); sb->s_flags = root_mountflags & ~MS_RDONLY; if (nfs_root_mount(sb) >= 0) { ---- as a cure i copied the code from the 2.0.33 kernel , so we get : -------- if ((fs_type = get_fs_type("nfs"))) { if ((vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/"))) { // DEL this line sb = vfsmnt->mnt_sb ; add this line sb = &super_blocks[0]; add this line while (sb->s_dev) sb++; add this line vfsmnt->mnt_sb = sb; sb->s_dev = get_unnamed_dev(); sb->s_flags = root_mountflags & ~MS_RDONLY; -------- This fixes the kernel problems , but I had to do some fixing in the startup script too : the new kernel requires rpc.portmap running , otherwise the nfs mounts in the startup script wont succeed , so I added the line /bootbin/rpc.portmap before the mount commands. I also added "-o nolock" to the mounts to avoid further complications. So , here are the kernel patches again : ( dont forget to comment out SMP=1 in the Makefile ! :) diff -u -r linux/fs/super.c linux-2.1.78/fs/super.c --- linux/fs/super.c Mon Dec 22 02:31:17 1997 +++ linux-2.1.78/fs/super.c Wed Jan 7 09:36:07 1998 @@ -1064,7 +1064,11 @@ ROOT_DEV = 0; if ((fs_type = get_fs_type("nfs"))) { if ((vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/"))) { - sb = vfsmnt->mnt_sb; +// sb = vfsmnt->mnt_sb ; + sb = &super_blocks[0]; + while (sb->s_dev) sb++; + + vfsmnt->mnt_sb = sb; sb->s_dev = get_unnamed_dev(); sb->s_flags = root_mountflags & ~MS_RDONLY; if (nfs_root_mount(sb) >= 0) { diff -u -r linux/net/ipv4/ipconfig.c linux-2.1.78/net/ipv4/ipconfig.c --- linux/net/ipv4/ipconfig.c Sun Nov 30 23:00:39 1997 +++ linux-2.1.78/net/ipv4/ipconfig.c Wed Jan 7 11:12:16 1998 @@ -1022,6 +1022,12 @@ return -1; /* + * Use defaults whereever applicable. + */ + if (ic_defaults() < 0) + return -1; + + /* * 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 @@ -1047,11 +1053,6 @@ ic_dev = ic_first_dev->dev; /* Device selected manually or only one device -> use it */ } - /* - * Use defaults whereever applicable. - */ - if (ic_defaults() < 0) - return -1; /* * Close all network devices except the device we've -----cut-here------------- Party on ! -- David Balazic , student E-mail: David.Balazic [at] uni-mb | sLOVEnija http://www.uni-mb.si/~uel003r2a Computer: Amiga 1200 + Quantum LPS-340AT --
|