It seems that the problem is in kern/vfs_conf.c:
When performing BOOTP configuration, nfs/bootp_subr:bootpc_init() is called before
the root-mount attempts. This routine finds the first non-loopback and non-point-
to-point interface, and does the bootp request. If it gets all of its needed
data, then it mounts the specified rootfs, sets nfs_diskless_valid to 3, and
returns.
Then vfs_rootmountalloc() is called, and the loop to mount rootdevs is started.
Unfortunately (?), rootdev is not set by bootpc_init(), so the loop is rather
short. :)
I'm not sure what the fix should be, but here's what I did to get the root mounted:
Index: vfs_conf.c
===================================================================
RCS file: /FreeBSD/CVS/src/sys/kern/vfs_conf.c,v
retrieving revision 1.31
diff -c -9 -r1.31 vfs_conf.c
*** vfs_conf.c 1999/07/03 17:40:31 1.31
--- vfs_conf.c 1999/08/23 22:38:58
***************
*** 70,87 ****
--- 70,88 ----
/*
* These define the root filesystem, device, and root filesystem type.
*/
dev_t rootdevs[] = { NODEV, NODEV };
char *rootdevnames[2];
struct vnode *rootvnode;
char *mountrootfsname;
#ifdef BOOTP
extern void bootpc_init __P((void));
+ extern int nfs_diskless_valid;
#endif
/*
* vfs_init() will set maxvfsconf
* to the highest defined type number.
*/
int maxvfsconf;
struct vfsconf *vfsconf;
***************
*** 133,168 ****
--- 134,174 ----
panic("cannot mount root\n");
return ;
}
mp->mnt_flag |= MNT_ROOTFS;
/*
* Attempt the mount
*/
err = ENXIO;
+ #ifdef BOOTP
+ if (nfs_diskless_valid == 3) err = VFS_MOUNT(mp, NULL, NULL, NULL, p);
+ #endif
+ if (err) {
orootdev = rootdev;
if (rootdevs[0] == NODEV)
rootdevs[0] = rootdev;
for (i = 0; i < sizeof(rootdevs) / sizeof(rootdevs[0]); i++) {
if (rootdevs[i] == NODEV)
break;
rootdev = rootdevs[i];
if (rootdev != orootdev) {
s = splbio(); /* Overkill, but harmless.. */
printf("changing root device to %s\n", rootdevnames[i]);
splx(s);
orootdev = rootdev;
}
strncpy(mp->mnt_stat.f_mntfromname,
rootdevnames[i] ? rootdevnames[i] : ROOTNAME, MNAMELEN - 1);
err = VFS_MOUNT(mp, NULL, NULL, NULL, p);
if (err != ENXIO)
break;
+ }
}
if (err) {
/*
* XXX should ask the user for the name in some cases.
* Why do we call vfs_unbusy() here and not after ENXIO
* is returned above?
*/
vfs_unbusy(mp, p);
/*
I'd really appreciate it if someone could take a look at this and commit a fix
(possibly this one). John? Poul? Peter?
Without a similar fix, I don't think that BOOTP kernels will not work (as specified
in the file /usr/share/examples/diskless/README.BOOTP).
-Mark Taylor
NetMAX Developer
[EMAIL PROTECTED]
http://www.netmax.com/
On 23-Aug-99 Mark J. Taylor wrote:
>
>
> I'm attempting to boot a -current system (from 4 days ago) off of a modified
> GENERIC kernel floppy disk, and it is failing in kern/vfs_conf.c's vfs_mountrootfs
> routine, with a message:
> rootdev=0xffffffff error=6, panic: cannot mount root(2)
>
>
> rootdev is NODEV, and err is ENXIO.
>
>
> The isc-dhcp server does serve the bootp request successfully (I get messages from
> the -current kernel that indicate an IP address, rootfs, et.al), and the NFS server
> reports the success of the client mounting the NFS-exported filesystem (the server
> is a 3.1-RELEASE machine). I am not specifying any swap (yet).
>
>
>
> I'm using a straight GENERIC kernel, kgzipped, with options added at the end:
> options BOOTP
> options BOOTP_NFSROOT
> options BOOTP_COMPAT
> options NULLFS
> options UNION
>
> (the NFS_ROOT option is already in GENERIC.)
>
>
>
> Am I missing something? (I tried "BOOTP_NFSV3" option also)... Any success stories
> using this method? (as documented in /usr/share/examples/diskless)
>
>
>
>
>
> -Mark Taylor
> NetMAX Developer
> [EMAIL PROTECTED]
> http://www.netmax.com/
>
>
>
> To Unsubscribe: send mail to [EMAIL PROTECTED]
> with "unsubscribe freebsd-current" in the body of the message
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message