Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Feb 2003 11:34:28 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Chris Shenton <chris@shenton.org>
Cc:        current@FreeBSD.ORG
Subject:   Re: Diskless: 5.0R scripts, boot, NFS mount problems I didn't have in 4.7S
Message-ID:  <200302191934.h1JJYSHp004355@apollo.backplane.com>
References:  <87el65pi4e.fsf@Pectopah.shenton.org> <200302191844.h1JIiUIh004070@apollo.backplane.com> <8765rg1444.fsf@Pectopah.shenton.org>

next in thread | previous in thread | raw e-mail | index | archive | help

:Matthew Dillon <dillon@apollo.backplane.com> writes:
:
:>     4.x and -current use the same mechanism, except 4.x uses MFS and
:>     -current uses MD.
:
:4.x uses /etc/diskless[12] while 5.x (by default) uses
:/etc/rc.d/(init)?diskless.  The latter is works very differently than
:the former.

    4.x uses /etc/rc.diskless[12].  I synchronized most of -current and
    -stable's rc.diskless scripts a month or two ago so even though parts
    of the scripts are different (like the use of MFS instead of MD),
    they should operate according to the same /conf rules.

:>     kenv is only used in current's rc.diskless scripts, and it 
:>     resides in /bin on -current.  
:
:Not on mine:
:
:  chris@Pectopah<103> whereis kenv
:  kenv: /usr/bin/kenv /usr/share/man/man1/kenv.1.gz /usr/src/bin/kenv
:  chris@Pectopah<104> ls /bin/kenv
:  ls: /bin/kenv: No such file or directory

    Are you sure you have done a recent buildworld/installworld?  It
    sounds like you haven't.  In -current kenv is in /bin  (i.e.
    the source is in /usr/src/bin/kenv on -current) as of the 15th of
    this month.  But it still should have worked because /usr should
    have been mounted by then.

:>     Basically what you do is create a files and directories in
:>     /conf/base and /conf/default which are used to populate the
:>     MFS/MD root and other directories.  I have included my setup
:>     at the end.
:
:Which startup scripts are you running, old diskless[12] or new
:rc.d/(init)?diskless ?

    Both should work the same.  The new rc.d/initdiskless and rc.d/diskless
    run the same rules that rc.diskless1  and rc.diskless2 do.

:Thanks for your examples, I'll plow through them tonight. But -- more
:below -- these sure look like 4.x-compatible stuff, not 5.0.

    4.x and 5.x work the same.  That is, -stable and -current work the same.
    If you are running an older 4.x (possibly even the last 4.x release)
    it may not have the new scripts.


:Actually, I don't see any code to look for that md_size or
:diskless_remount in either of 5.0's rc.diskless[12] or
:rc.d/(init)?diskless.  I do know that what you're describing is in
:4.x's rc.diskless[12], and I did have that working on a 4.7S system.
:That's why I'm having so much trouble with the 5.0 diskless boot --
:everything's changed.
:..
:Thanks a bunch!

    You must be working off an out of date source tree.

    I have included -current's current /usr/src/etc/rc.d/initdiskless script
    below for you to compare against your sources.  If your sources are out
    of date you should update them (e.g. via cvsup or whatever you use to
    get the sources).  As you can see, the initidiskless script is full
    of references to md_size :-)

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>


#!/bin/sh
#
# Copyright (c) 1999  Matt Dillion
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD: src/etc/rc.d/initdiskless,v 1.23 2003/02/15 16:29:20 jhay Exp $
#
# PROVIDE: initdiskless
# KEYWORD: FreeBSD

 
# On entry to this script the entire system consists of a read-only root
# mounted via NFS.  We use the contents of /conf to create and populate
# memory filesystems.  The kernel has run BOOTP and configured an interface
# (otherwise it would not have been able to mount the NFS root!)
#
# The following directories are scanned.  Each sucessive directory overrides
# (is merged into) the previous one.
#
#	/conf/base		universal base
#	/conf/default		modified by a secondary universal base
#	/conf/${ipba}		modified based on the assigned broadcast IP
#	/conf/${ip}		modified based on the machine's assigned IP
#
# Each of these directories may contain any number of subdirectories which
# represent directories in / on the diskless machine.  The existance of
# these subdirectories causes this script to create a MEMORY FILESYSTEM for
# /<sub_directory_name>.  For example, if /conf/base/etc exists then a
# memory filesystem will be created for /etc.
#
# If a subdirectory contains the file 'diskless_remount' the contents of
# the file is used to remount the subdirectory prior to it being copied to
# the memory filesystem.  For example, if /conf/base/etc/diskless_remount
# contains the string 'my.server.com:/etc' then my.server.com:/etc will be
# mounted in place of the subdirectory.  This allows you to avoid making
# duplicates of system directories in /conf.
#
# If a subdirectory contains the file 'md_size', the contents of the
# file is used to determine the size of the memory filesystem, in 512
# byte sectors.  The default is 8192 (4MB).  You only have to specify an
# md_size if the default doesn't work for you (i.e. if it is too big or
# too small).  Note that in -current the default is 4096 (2MB).  For
# example, /conf/base/etc/md_size might contain '16384'.
#
# If /conf/<special_dir>/SUBDIR.cpio.gz exists, the file is cpio'd into
# the specified /SUBDIR (and a memory filesystem is created for /SUBDIR
# if necessary).
#
# If /conf/<special_dir>/SUBDIR.remove exists, the file contains a list
# of paths which are rm -rf'd relative to /SUBDIR.
#
# You will almost universally want to create a /conf/base/etc containing
# a diskless_remount and possibly an md_size file.  You will then almost
# universally want to override rc.conf, rc.local, and fstab by creating
# /conf/default/etc/{rc.conf,rc.local,fstab}.  Your fstab should be sure
# to mount a /usr... typically an NFS readonly /usr.
#
# NOTE!  rc.diskless2 will create /var, /tmp, and /dev.  Those filesystems
# should not be specified in /conf.  At least not yet.

dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
[ ${dlv:=0} -eq 0 ] && exit 0

# chkerr:
#
# Routine to check for error
#
#	checks error code and drops into shell on failure.
#	if shell exits, terminates script as well as /etc/rc.
#
chkerr() {
    case $1 in
    0)
	;;
    *)
	echo "$2 failed: dropping into /bin/sh"
	/bin/sh
	# RESUME
	;;
    esac
}

# Create a generic memory disk
#
mount_md() {
    /sbin/mdmfs -i 4096 -s $1 -M md $2
}

# Create the memory filesystem if it has not already been created
#
create_md() {
    if [ "x`eval echo \\$md_created_$1`" = "x" ]; then
	if [ "x`eval echo \\$md_size_$1`" = "x" ]; then
	    md_size=4096
	else
	    md_size=`eval echo \\$md_size_$1`
	fi
	mount_md $md_size /$1
	/bin/chmod 755 /$1
	eval md_created_$1=created
    fi
}

# DEBUGGING
#
# set -v

# Figure out our interface and IP.
#
bootp_ifc=""
bootp_ipa=""
bootp_ipbca=""
iflist=`ifconfig -l`
for i in ${iflist} ; do
    set `ifconfig ${i}`
    while [ $# -ge 1 ] ; do
        if [ "${bootp_ifc}" = "" -a "$1" = "inet" ] ; then
            bootp_ifc=${i} ; bootp_ipa=${2} ; shift
        fi
        if [ "${bootp_ipbca}" = "" -a "$1" = "broadcast" ] ; then
            bootp_ipbca=$2; shift
        fi
        shift
    done
    if [ "${bootp_ifc}" != "" ] ; then
        break
    fi
done
echo "Interface ${bootp_ifc} IP-Address ${bootp_ipa} Broadcast ${bootp_ipbca}"

# Resolve templates in /conf/base, /conf/default, /conf/${bootp_ipbca},
# and /conf/${bootp_ipa}.  For each subdirectory found within these 
# directories:
#
# - calculate memory filesystem sizes.  If the subdirectory (prior to
#   NFS remounting) contains the file 'md_size', the contents specified
#   in 512 byte sectors will be used to size the memory filesystem.  Otherwise
#   8192 sectors (4MB) is used.
#
# - handle NFS remounts.  If the subdirectory contains the file
#   diskless_remount, the contents of the file is NFS mounted over
#   the directory.  For example /conf/base/etc/diskless_remount
#   might contain 'myserver:/etc'.  NFS remounts allow you to avoid
#   having to dup your system directories in /conf.  Your server must
#   be sure to export those filesystems -alldirs, however.
#
for i in base default ${bootp_ipbca} ${bootp_ipa} ; do
    for j in /conf/$i/* ; do
	# memory filesystem size specification
	#
	subdir=${j##*/}
	if [ -d $j -a -f $j/md_size ]; then
	    eval md_size_$subdir=`cat $j/md_size`
	fi

	# NFS remount
	#
	if [ -d $j -a -f $j/diskless_remount ]; then
	    nfspt=`/bin/cat $j/diskless_remount`
	    mount_nfs $nfspt $j
	    chkerr $? "mount_nfs $nfspt $j"
	fi
    done
done

# - Create all required MFS filesystems and populate them from
#   our templates.  Support both a direct template and a dir.cpio.gz
#   archive.  Support dir.remove files containing a list of relative
#   paths to remove.
#
# TODO:
#   + find a way to assign a 'group' identifier to a machine
#	so we can use group-specific configurations;

for i in base default ${bootp_ipbca} ${bootp_ipa} ; do
    for j in /conf/$i/* ; do
	subdir=${j##*/}
	if [ -d $j ]; then
	    create_md $subdir
	    cp -Rp $j/* /$subdir
	fi
    done
    for j in /conf/$i/*.cpio.gz ; do
	subdir=${j%*.cpio.gz}
	subdir=${subdir##*/}
	if [ -f $j ]; then
	    create_md $subdir
	    echo "Loading /$subdir from cpio archive $j"
	    (cd / ; /stand/gzip -d < $j | /stand/cpio --extract -d )
	fi
    done
    for j in /conf/$i/*.remove ; do
	subdir=${j%*.remove}
	subdir=${subdir##*/}
	if [ -f $j ]; then
	    # doubly sure it is a memory disk before rm -rf'ing
	    create_md $subdir
	    (cd /$subdir; rm -rf `/bin/cat $j`)
	fi
    done
done


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302191934.h1JJYSHp004355>