hi all, I'd like to request a code review for Juergen Keil's fixes for these bugs:
6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem 6350002 newboot: failed VFS_MOUNTROOT() panics with a useless error message 6350006 BAD TRAP panic, when using unknown nfs protocol version in fstype property Unified diffs are appended. The current versions of the changed files, for reference: http://cvs.opensolaris.org/source/xref/on/usr/src/uts/common/fs/vfs.c http://cvs.opensolaris.org/source/xref/on/usr/src/uts/common/os/swapgeneric.c thanks much for any comments. (and thanks to Juergen for contributing the fixes) cheers, calum. ------- usr/src/uts/common/fs/vfs.c ------- --- - Wed Dec 14 19:36:03 2005 +++ usr/src/uts/common/fs/vfs.c Wed Dec 14 17:59:39 2005 @@ -3892,19 +3892,44 @@ int error; struct vfssw *vsw; extern void pm_init(); - char *fstyp; + char *fstype; - fstyp = getrootfs(); + /* + * Init the root filesystem type (rootfs.bo_fstype), and for + * diskless clients, the filesystem name (rootfs.bo_name). + * + * For diskless clients, rootfs.bo_name is set to the internal + * filesystem name (nfsdyn/nfs/nfs3/nfs4) mapped from the user + * specified external fstype name (nfs/nfs2/nfs3/nfs4). For + * error messages we report a fstype of nfs in all cases, + * trying to hide our internal nfs filesystem names from the + * user. + * + * In all other cases, rootfs.bo_name and the local variable + * fstype have the same name. + */ + fstype = getrootfs(); if (error = clboot_rootconf()) return (error); - if (modload("fs", fstyp) == -1) - cmn_err(CE_PANIC, "Cannot _init %s module\n", fstyp); + /* + * Run _init on the root filesystem (we already loaded it + * but we've been waiting until now to _init it) which will + * have the side-effect of running vsw_init() on this vfs. + */ + if (modload("fs", fstype) == -1) { + cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", fstype); + return (ENXIO); + } RLOCK_VFSSW(); - vsw = vfs_getvfsswbyname(fstyp); + vsw = vfs_getvfsswbyname(rootfs.bo_fstype); RUNLOCK_VFSSW(); + if (vsw == NULL) { + cmn_err(CE_CONT, "Cannot find %s filesystem\n", fstype); + return (ENXIO); + } VFS_INIT(rootvfs, &vsw->vsw_vfsops, 0); VFS_HOLD(rootvfs); @@ -3921,7 +3946,12 @@ rootdev = rootvfs->vfs_dev; if (error) - cmn_err(CE_PANIC, "cannot mount root path %s", svm_bootpath); + cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n", + rootfs.bo_name, fstype); + else + cmn_err(CE_CONT, "?root on %s fstype %s\n", rootfs.bo_name, + fstype); + return (error); } @@ -3940,9 +3970,23 @@ } /* - * If server_path exists, then we are booting a diskless - * client. Otherwise, we default to ufs. Zfs should perhaps be - * another property. + * Init the root filesystem type (rootfs.bo_fstype) from the "fstype" + * property. + * + * Filesystem types starting with the prefix "nfs" are diskless clients; + * init the root filename name (rootfs.bo_name), too. + * + * If we are booting via NFS we currently have these options: + * nfs - dynamically choose NFS V2, V3, or V4 (default) + * nfs2 - force NFS V2 + * nfs3 - force NFS V3 + * nfs4 - force NFS V4 + * Because we need to maintain backward compatibility with the naming + * convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c) + * we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic + * nfs module will map the type back to either "nfs", "nfs3", or "nfs4". + * This is only for root filesystems, all other uses such as cachefs + * will expect that "nfs" == NFS V2. */ static char * getrootfs(void) @@ -3950,7 +3994,10 @@ extern char *strplumb_get_netdev_path(void); char *propstr = NULL; - /* check fstype property; it should be nfsdyn for diskless */ + /* + * Check fstype property; for diskless it should be one of "nfs", + * "nfs2", "nfs3" or "nfs4". + */ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, "fstype", &propstr) == DDI_SUCCESS) { @@ -3962,6 +4009,12 @@ return (rootfs.bo_fstype); ++netboot; + + if (strcmp(rootfs.bo_fstype, "nfs2") == 0) + (void) strcpy(rootfs.bo_fstype, "nfs"); + else if (strcmp(rootfs.bo_fstype, "nfs") == 0) + (void) strcpy(rootfs.bo_fstype, "nfsdyn"); + /* check if path to network interface is specified in bootpath */ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, "bootpath", &propstr) ------- usr/src/uts/common/os/swapgeneric.c ------- --- - Wed Dec 14 19:36:03 2005 +++ usr/src/uts/common/os/swapgeneric.c Wed Dec 14 17:43:45 2005 @@ -169,6 +169,11 @@ RLOCK_VFSSW(); vsw = vfs_getvfsswbyname(rootfs.bo_fstype); RUNLOCK_VFSSW(); + if (vsw == NULL) { + cmn_err(CE_CONT, "Cannot find %s filesystem\n", + rootfs.bo_fstype); + return (ENXIO); + } VFS_INIT(rootvfs, &vsw->vsw_vfsops, (caddr_t)0); VFS_HOLD(rootvfs);