Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Oct 2000 18:10:16 +0100
From:      dbhague@allstor-sw.co.uk
To:        freebsd-scsi@FreeBSD.org, freebsd-fs@FreeBSD.org
Cc:        gibbs@scsiguy.com, mjacob@feral.com, Andre Albsmeier <andre.albsmeier@mchp.siemens.de>, smcintyre@allstor-sw.co.uk
Subject:   Re: Stressed SCSI subsystem locks up the system
Message-ID:  <80256977.005E53A0.00@mail.plasmon.co.uk>

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

[-- Attachment #1 --]

We have rebuilt the SCSI RAID partition with the disklabel -B flag and have just
had the following error:

dscheck(#da/3): negative b_blkno -132104
dev=#da/3, bno=-66052, bsize=8192 size =8192 fs=/RAID
panic: ffs_blkfree: bad size
syncing disk

This was a new partition generated by the enclosed script, setupraidb, running
the test mentioned in my earlier mail.

Any ideas ?

Regards Dave

(See attached file: setupraidb)

[-- Attachment #2 --]
#!/bin/sh
#
# /sbin/setupraid - simple script to init the RAID on an Intelliraid
# v $Id: setupraid,v 1.11 2000/10/05 11:16:47 dsw Exp $ 
# (c) 2000 Allstor Software
#
# If we're not passed a disk name, we'll assume that da0 is what we
# want.

# Default init values for the working variables
DISK=da0
MOUNT=/RAID
VERBOSE=0
FORCE=0

# Include the standard error numbers
#. /lib/errno.sh
# Standard list of errno codes to be included in shell scripts that
# may need them.
#
# Steve McIntyre
#
# Values taken from /usr/include/errno.h on FreeBSD 3.0 using the
# following script:
#
# cat /usr/include/errno.h | grep '^#define.*/' | awk '
#     {
#	      gsub ("\\*/",# "")
#         printf("%s=%-10.20s \t# %s %s %s %s %s %s %s %s\n", $2, $3, $5,
#         $6, $7, $8, $9, $10, $11, $12)
#     }' | tr -d '()'
#
# These are not all POSIX, but should be a superset of it.

EPERM=1             # Operation not permitted     
ENOENT=2            # No such file or directory   
ESRCH=3             # No such process     
EINTR=4             # Interrupted system call     
EIO=5               # Input/output error      
ENXIO=6             # Device not configured     
E2BIG=7             # Argument list too long    
ENOEXEC=8           # Exec format error     
EBADF=9             # Bad file descriptor     
ECHILD=10           # No child processes     
EDEADLK=11          # Resource deadlock avoided     
ENOMEM=12           # Cannot allocate memory     
EACCES=13           # Permission denied      
EFAULT=14           # Bad address      
ENOTBLK=15          # Block device required     
EBUSY=16            # Device busy      
EEXIST=17           # File exists      
EXDEV=18            # Cross-device link      
ENODEV=19           # Operation not supported by device   
ENOTDIR=20          # Not a directory     
EISDIR=21           # Is a directory     
EINVAL=22           # Invalid argument      
ENFILE=23           # Too many open files in system  
EMFILE=24           # Too many open files    
ENOTTY=25           # Inappropriate ioctl for device    
ETXTBSY=26          # Text file busy     
EFBIG=27            # File too large     
ENOSPC=28           # No space left on device   
ESPIPE=29           # Illegal seek      
EROFS=30            # Read-only file system     
EMLINK=31           # Too many links     
EPIPE=32            # Broken pipe      
EDOM=33             # Numerical argument out of domain   
ERANGE=34           # Result too large     
EAGAIN=35           # Resource temporarily unavailable     
EWOULDBLOCK=$EAGAIN      # Operation would block     
EINPROGRESS=36          # Operation now in progress    
EALREADY=37             # Operation already in progress    
ENOTSOCK=38             # Socket operation on non-socket    
EDESTADDRREQ=39             # Destination address required     
EMSGSIZE=40             # Message too long     
EPROTOTYPE=41           # Protocol wrong type for socket   
ENOPROTOOPT=42          # Protocol not available     
EPROTONOSUPPORT=43          # Protocol not supported     
ESOCKTNOSUPPORT=44          # Socket type not supported    
EOPNOTSUPP=45           # Operation not supported     
EPFNOSUPPORT=46             # Protocol family not supported    
EAFNOSUPPORT=47             # Address family not supported by protocol family 
EADDRINUSE=48           # Address already in use    
EADDRNOTAVAIL=49            # Can't assign requested address    
ENETDOWN=50             # Network is down     
ENETUNREACH=51          # Network is unreachable     
ENETRESET=52            # Network dropped connection on reset   
ECONNABORTED=53             # Software caused connection abort    
ECONNRESET=54           # Connection reset by peer    
ENOBUFS=55          # No buffer space available    
EISCONN=56          # Socket is already connected    
ENOTCONN=57             # Socket is not connected    
ESHUTDOWN=58            # Can't send after socket shutdown   
ETOOMANYREFS=59             # Too many references: can't splice   
ETIMEDOUT=60            # Operation timed out     
ECONNREFUSED=61             # Connection refused      
ELOOP=62            # Too many levels of symbolic links  
ENAMETOOLONG=63             # File name too long    
EHOSTDOWN=64            # Host is down     
EHOSTUNREACH=65             # No route to host    
ENOTEMPTY=66            # Directory not empty     
EPROCLIM=67             # Too many processes     
EUSERS=68           # Too many users     
EDQUOT=69           # Disc quota exceeded     
ESTALE=70           # Stale NFS file handle    
EREMOTE=71          # Too many levels of remote in path 
EBADRPC=72          # RPC struct is bad    
ERPCMISMATCH=73             # RPC version wrong     
EPROGUNAVAIL=74             # RPC prog. not avail    
EPROGMISMATCH=75            # Program version wrong     
EPROCUNAVAIL=76             # Bad procedure for program    
ENOLCK=77           # No locks available     
ENOSYS=78           # Function not implemented     
EFTYPE=79           # Inappropriate file type or format   
EAUTH=80            # Authentication error      
ENEEDAUTH=81            # Need authenticator      
EIDRM=82            # Identifier removed      
ENOMSG=83           # No message of desired type   
ELAST=83            # Must be equal largest errno   
ERESTART=-1           # restart syscall      
EJUSTRETURN=-2        # don't modify regs, just return   
ENOIOCTL=-3           # ioctl not handled by this layer  


# Include the standard "vecho" functions
#. /lib/vecho.sh
vecho () {
    if [ $VERBOSE -gt 0 ] ; then
        echo "$@"
    fi
}

vvecho () {
    if [ $VERBOSE -gt 1 ] ; then
        echo "$@"
    fi
}

vvvecho () {
    if [ $VERBOSE -gt 2 ] ; then
        echo "$@"
    fi
}

vvvvecho () {
    if [ $VERBOSE -gt 3 ] ; then
        echo "$@"
    fi
}


usage() {
	echo
	echo "$0 [ -d device ] [-n name] [-v] "
	echo
	echo "Creates a simple raid setup on the specified device."
	echo "If no device is specified, da0 is assumed."
	echo "Options:"
	echo "   -d device  Specifies the device on which the filesystems should be"
	echo "              made. Default is da0."
	echo "   -n name    Specifies the mount point / share name of the"
	echo "              user partition to be created. Default is /RAID"
	echo "   -v         Be more verbose. Currently three levels are available:"
	echo "              silent (default), verbose and ultra-verbose"
	echo "   -f         Set up new raid partitions even if some already exist"
    echo "              and are in use - this will attemtp to unmount them first"
	echo
	exit $EINVAL 
}

# Parse options
if [ $# -gt 0 ] ; then
    while [ $# -gt 0 ] 
    do
        case "$1"x in 
		"-v"x)
			VERBOSE=$(($VERBOSE + 1))
			shift
		;;
		"-n"x)
			shift
			MOUNT="$1"
			shift
		;;
		"-d"x)
			shift
			DISK="$1"
			shift
		;;
		"-f"x)
			shift
			FORCE=1
		;;
		*)
			echo "\"$1\": invalid option."
			usage
		;;
		esac
	done
fi

vecho Using disk \"$DISK\"
vecho Creating user partition \"$MOUNT\"

vvecho Checking inputs are valid...
# Check options here!
if [ ! -e /dev/r$DISK ] ; then
	echo Error. /dev/r$DISK not found - is this disk supported?
	exit $ENODEV
fi
vecho /dev/r$DISK seems OK, continuing

if [ -z "$MOUNT" ] ; then
	echo Error. No mount point specified!
	usage
fi

# The name must start with a leading /
LEAD=`echo "$MOUNT" | cut -c1`
if [ $LEAD != "/" ] ; then
	echo Error. Invalid mount point \"$MOUNT\". No leading /
	usage
fi

vecho $MOUNT seems OK, continuing

# Simple sanity check - do we have anything mounted on this disk at
# the moment?
MOUNTS=`mount | grep $DISK`

if [ "$MOUNTS"x != ""x ] ; then
	echo
	echo "You appear to already have the following filesystem(s) mounted on $DISK"
	mount | grep $DISK
	if [ "$FORCE"x = "0"x ] ; then
		echo "Rectify this please!"
		echo "Aborting"
		exit $EBUSY
	else
		echo "-f specified; Attempting to unmount them"
		# To make sure we don't screw up, unmount them in reverse
		# order - will fix any mount dependencies
		for PART in `mount | grep $DISK | sort -rk3 | awk '{print $1}'`
		do
			vecho Unmounting partition $PART
			umount $PART
			error=$?
			if [ $error -ne 0 ] ; then
				echo Unmount $PART failed, trying to force the unmount
				umount -f $PART
				error=$?
				if [ $error -ne 0 ] ; then
					echo Forced unmount of $PART failed, giving up!
					exit $EBUSY
				fi
			fi
		done
	fi
fi

# Read the current disklabel - make sure the device exists
disklabel -B -r -w $DISK auto
error=$?

if [ $error -ne 0 ] ; then
	echo "Error $error trying to read current disklabel"
	echo "Are you sure that \"$DISK\" is present and correct?"
	exit $ENOENT
fi

# OK, device is present and we can read from it

# Simple partition setup required for now:
# Partition     Size
#    a          100MB
#    c          full disk
#    d          full disk - 100MB
#
# a is the "system" partition, used for backup of vital files
# c is the normal BSD "whole disk" partition
# d is the partition the user should be able to use
# 
# The following code is stolen heinously from the Netready setup
# script (pdl)

# Calculate the physical layout of this disk
vecho Calculating sizes for disk $DISK

# bytes per sector, probably 512
bps=`disklabel  $DISK | grep "^bytes\/sector" | cut -f2 -d' '`
vvecho bytes/sector: $bps
# sectors per cylinder
spc=`disklabel  $DISK | grep "^sectors\/cylinder" | cut -f2 -d' '`
vvecho sectors/cylinder: $spc
# num cylinders
cyl=`disklabel  $DISK | grep "^cylinders:" | cut -f2 -d' '`
vvecho cylinders: $cyl
# total sectors
spu=`disklabel  $DISK | grep "^sectors\/unit" | cut -f2 -d' '`
vvecho sectors: $spu

# man dc(1) for details, but basically
# Command                              Stack after command
# push 4                               4
# pop & set precision                  (null)
# push 1048576                         1048576
# push Sectors per Cylinder            $spc,1048576
# push bytes per cylinder              $bpc,$spc,1048576
# pop two, multiply, push result       $bpc*$spc,1048576
# pop two, divide, push result         ($bpc*$spc)/1048576
# print top of stack                   ($bpc*$spc)/1048576

#MB per cylinder
mpc=`echo "4k 1048576 $spc $bps * /p" | dc` 

vvecho cylinders/MB: $mpc

# More dc magic: .5+0k1/p rounds to nearest whole cylinder. We don't
# have a round-to-nearest-integer operator in dc, so we add .5 and
# round down to the integer value, which obviously has the same
# effect.
# 4k         = Set precicion to 4 decimal places
# 100 $mpc * = Multiply 100 by number of MB per cylinder
# .5+        = add .5 to the current top of stack
# 0k         = Set precision to 0 decimal places
# 1/         = Divide top of stack by 1. See note.
# $spc *     = Multiply (rounded) number of cylinders by Sectors per Cylinder
# p          = print result
#
# Note :
# In (at least this implementation of) dc the precicsion is only
# applied to a value on a divide, not on a multiply, print, add, etc.
# This is the easiest trivial operation to cause the rounding to take
# effect.
#
# The whole partition map is stored as a vast load of shell variables:
# p[a-h] = Partition size for partition [a-h] in sectors
# o[a-h] = Offset for partition [a-h] in sectors
# fs[a-h] = Filesystem name for partition [a-h] 4.2BSD for everything but swap
#
# offset is a running total of sectors used, and is used for the next
# partition's offset

# 100MB for /system
pa=`echo "4k 100 $mpc *.5+0k1/ $spc *p" | dc`
oa=0
offset=$pa
fsa=4.2BSD

# No swap (pb)
# Full disk (pc) dealt with later

# And now for the user partition
pd=`expr $spu - $offset`
od=$offset
fsd=4.2BSD

vvecho New disklabel entries for $DISK:
vvecho "  a: $pa $oa $fsa 0 0 0" ;
vvecho "  c: $spu 0 unused 0 0" ;
vvecho "  d: $pd $od $fsd 0 0 0" ;

# Calculate them in MB for the user. 
SIZE_A=`echo "0k $pa 2048 / p" | dc`
SIZE_D=`echo "0k $pd 2048 / p" | dc`

vecho New partition setup:
vecho "System use: $SIZE_A MB"
vecho "User use:   $SIZE_D MB"

# Ready to write. 
# Now make sure we start with a blank disk
dd if=/dev/zero of=/dev/r$DISK count=2048 >/dev/null 2>&1

# Cause the system to generate a label
disklabel -B -r -w $DISK auto

# Now add our stuff to it
(disklabel $DISK  | tail -r | tail +2 | tail -r ;\
 echo "  a: $pa $oa $fsa 0 0 0" ; \
 echo "  c: $spu 0 unused 0 0" ; \
 echo "  d: $pd $od $fsd 0 0 0" ; ) | disklabel -rR $DISK /dev/stdin

# Time to make filesystems!

vecho Newfs "$DISK"a
if [ $VERBOSE -gt 1 ] ; then
	newfs /dev/r"$DISK"a
else
	newfs /dev/r"$DISK"a >/dev/null
fi
error=$?
if [ $error -ne 0 ] ; then
	echo Error in creating filesystem on "$DISK"a
	exit $error
fi

vecho Newfs "$DISK"d
if [ $VERBOSE -gt 1 ] ; then
	newfs /dev/r"$DISK"d
else
	newfs /dev/r"$DISK"d >/dev/null
fi
error=$?
if [ $error -ne 0 ] ; then
	echo Error in creating filesystem on "$DISK"d
	exit $error
fi

if [ ! -d /system ] ; then
	mkdir /system
fi

vecho Mounting /system
mount -r /dev/"$DISK"a /system

if [ ! -d "$MOUNT" ] ; then
	mkdir "$MOUNT"
fi

vecho Mounting $MOUNT
mount /dev/"$DISK"d "$MOUNT"

# Make the mount world r/w'able
chmod 777 "$MOUNT"

exit 0

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