Subject: Re: Automatically disklabel entire disk
To: Hubert Feyrer <hubert@feyrer.de>
From: Douglas Wade Needham <cinnion@ka8zrt.com>
List: tech-embed
Date: 06/27/2005 21:40:47
version=3.0.3
Sender: tech-embed-owner@NetBSD.org
--6TrnltStXW4iwmi0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
See the attached script, which I use to setup disks. Nothing too
fancy, but it does allow me to specify the format of the single
partition (h: RAID or 4.2BSD), along with an optional swap. It even
tries to prevent clobbering the root disk or any other disk which has
been partitioned. Note, however, that I make no guarentees that it
works. I think it did last time I used it, but...
- Doug
Quoting Hubert Feyrer (hubert@feyrer.de):
> On Tue, 28 Jun 2005, Marcin Jessa wrote:
> >Is it possible to autmatically, non.interactively disklabel entire blank
> >disk not knowing what size it has?
> >I am stucked with disklabel..
> >I am trying to create an install script which executes on MFS mounted
> >partition, disklabels a CF/HD, creates file system on it and installs disk
> >bootstrap soft on it.
>
> Read the disklabel(8) manpage!
>
> You can use something like "disklabel disk0 >file", then read stuff for
> partitioning out of the file, then put the disklabel back with "disklabel
> disk0 file" or so. Untested, but it should work. May need some attention
> to get the on-disk label in sync with the in-core disklabel.
>
>
> - Hubert
--
Douglas Wade Needham - KA8ZRT UN*X Consultant & UW/BSD kernel programmer
Email: cinnion @ ka8zrt . com http://cinnion.ka8zrt.com
Disclaimer: My opinions are my own. Since I don't want them, why
should my employer, or anybody else for that matter!
--6TrnltStXW4iwmi0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=disk_size
#!/bin/ksh -x
#
# Setup the program name for use in error messages, without the path.
#
prog=${0##*/}
usage ()
{
printf "Usage: %s [-R|-B [-S swapsize ]] [-r]\n" ${prog} >&2
printf " -B\tMake a single 4.2BSD slice\n" >&2
printf " -R\tMake a single RAID slice\n" >&2
printf " -S\tMake a swap slice of the given size\n" >&2
printf " -r\tRestrict the FDISK partition size by the FDISK geometry\n" >&2
exit $0
}
#
# Determine the root disk
#
ROOTDSK=`df -k / | tail -1 | cut -f1 -d' '`
ROOTDSK=${ROOTDSK##/dev/}
ROOTDSK=${ROOTDSK%[a-z]}
#
# Defaults for arguments
#
restrict=0
part_raid=0
part_bsd=0
swap_size_mb=0
#
# Parse our options
#
while getopts ":BRS:[Swap size in MB required]r" opt
do
case ${opt} in
B)
part_bsd=1
;;
R)
part_raid=1
;;
S)
swap_size_mb=${OPTARG}
;;
r)
restrict=1
;;
:)
printf "${prog}: ${OPTARG} requries a value\n" >&2
usage 2
;;
*)
printf "${prog}: unknown option ${OPTARG}\n" >&2
usage 22
;;
esac
done
shift OPTIND-1
#
# Validate the arguments
#
if [ $# -ne 1 ]
then
usage 22
fi
if [ ${part_bsd} -ne 0 -a ${part_raid} -ne 0 ]
then
printf "%s: Make up your mind...either you want a RAID or BSD4.4 partition\n" ${prog} >&2
usage 22
fi
#
# Get the disk from the command line, stripping off the leading /dev and trailing letter.
#
DSK=${1##/dev/}
DSK=${DSK%[a-z]}
#
# Validate the pattern.
#
case "${DSK}" in
[sw]d[0-9])
if [ "${DSK}" == "${ROOTDSK}" ]
then
printf "${prog}: Cannot use this on the root disk (${ROOTDSK})!!! ABORTING!!!" >&2
return 22
fi
;;
*)
printf "${prog}: %s is not in the form of [sw]d[0-9]!\n" ${DSK} >&2
;;
esac
#
# Get the size of the disk via the report in dmesg.boot
#
SZ=`grep ^${DSK} /var/run/dmesg.boot | sed -n -e's/.* \([0-9][0-9]*\) sectors$/\1/p'`
SZ0=$((SZ-63))
#
# Get the size of the disk and the partitions via fdisk.
#
eval `fdisk -S ${DSK} 2>/dev/null`
echo "${DSK}: ${SZ}"
echo "DLCYL=${DLCYL}"
echo "DLHEAD=${DLHEAD}"
echo "DLSEC=${DLSEC}"
echo "DLSIZE=${DLSIZE}"
echo "BCYL=${BCYL}"
echo "BHEAD=${BHEAD}"
echo "BSEC=${BSEC}"
echo "PART0ID=${PART0ID}"
echo "PART0SIZE=${PART0SIZE}"
echo "PART0START=${PART0START}"
echo "PART0FLAG=${PART0FLAG}"
echo "PART0BCYL=${PART0BCYL}"
echo "PART0BHEAD=${PART0BHEAD}"
echo "PART0BSEC=${PART0BSEC}"
echo "PART0ECYL=${PART0ECYL}"
echo "PART0EHEAD=${PART0EHEAD}"
echo "PART0ESEC=${PART0ESEC}"
echo "PART1SIZE=${PART1SIZE}"
echo "PART2SIZE=${PART2SIZE}"
echo "PART3SIZE=${PART3SIZE}"
#
# If we have any defined partitions...
#
if [ "${PART0ID}" -ne 0 -o "${PART1ID}" -ne 0 -o "${PART2ID}" -ne 0 -o "${PART3ID}" -ne 0 ]
then
printf "${prog}: Partitions already exist on ${DSK}...ABORTING!!!\n" >&2
return 17
fi
#
# If we are to restrict the FDISK partition by the FDISK geometry.
#
if [ ${restrict} -ne 0 ]
then
#
# Validate DLSIZE <= DLCYL*DLHEAD*DLSEC
#
t=$((${DLCYL}*${DLHEAD}*${DLSEC}))
if [ ${t} -lt ${DLSIZE} ]
then
printf "DLSIZE (%d) is larger than DLCYL*DLHEAD*DLSEC (%d)\n" ${DLSIZE} ${t}
printf "Overriding DLSIZE with %d\n" ${t}
DLSIZE=${t}
fi
fi
#
# Compute the size of a partition occupying the entire disk.
#
PART0START=${BSEC}
PART0SIZE=$((${DLSIZE}-${PART0START}))
PART0ID=169
echo "${DSK}.0: ${SZ0}"
#
# Create the fdisk partition table.
#
fdisk -a -i -u -0 -s ${PART0ID}/${PART0START}/${PART0SIZE} ${DSK} <<EOF
n
n
y
y
EOF
fdisk ${DSK}
#
# Dump the disk label.
#
disklabel ${DSK} > /tmp/dsklabel.$$ 2>/dev/null
#
# Print out the head of the new disk label.
#
sed -n -e 's/[1234567] partitions:/8 partitions:/' -e'1,/^# size/p' /tmp/dsklabel.$$ > /tmp/ndsklabel.$$
#
# Find out the number of total sectors, sectors/track and the
# sectors/cylinder values.
#
sec=`grep 'total sectors:' /tmp/dsklabel.$$ | cut -f2 -d:`
spt=`grep 'sectors/track:' /tmp/dsklabel.$$ | cut -f2 -d:`
spc=`grep 'sectors/cylinder:' /tmp/dsklabel.$$ | cut -f2 -d:`
#
# We will figure on a hog partition, and it will not include track 0.
#
hog=${sec}-${spt}
start=${spt}
#
# Do we want a swap partition?
#
if [ ${swap_size_mb} -gt 0 ]
then
#
# Compute the size of the swap partition in sectors. It will be
# at the beginning of the disk, starting at track 1 and will end
# on a cylinder boundary.
#
swap_cyl=$(((${swap_size_mb}*2048)%${spc}))
swap_size=$((${swap_cyl}*${spc}-${spt}))
swap_start=${start}
#
# Add the entry for the swap partition.
#
printf " b: %9d %9d %10s\n" ${swap_size} ${swap_start} "swap" >>/tmp/ndsklabel.$$
#
# Account for the usage by the swap partition.
#
start=$((${start}+${swap_size}))
hog=$((${hog}-${swap_size}))
fi
#
# Print out the c and d partitions.
#
printf " c: %9d %9d %10s %5d %5d\n" $((${sec}-${spt})) ${spt} "unused" 0 0 >>/tmp/ndsklabel.$$
printf " d: %9d %9d %10s %5d %5d\n" ${sec} 0 "unused" 0 0 >>/tmp/ndsklabel.$$
#
# Print out the hog partition.
#
if [ ${part_bsd} -ne 0 -o ${part_raid} -ne 0 ]
then
#
#
#
if [ ${part_bsd} -ne 0 ]
then
#
# Compute the block size.
#
bsize=0
#
# Compute the fragment size
#
fsize=0
#
# Compute the cpg
#
cpg=0
#
# Print out the record.
#
printf " h: %9d %9d %10s %5d %5d %5d\n" ${hog} ${start} "4.2BSD" ${fsize} ${bsize} ${cpg} >> /tmp/ndsklabel.$$
elif [ ${part_raid} -ne 0 ]
then
printf " h: %9d %9d %10s\n" ${hog} ${start} "RAID" >> /tmp/ndsklabel.$$
fi
fi
#
# Write the new disk label.
#
disklabel -R -r ${DSK} /tmp/ndsklabel.$$ <<EOF
y
EOF
#
# If we wanted a BSD partition...
#
#
# Cleanup
#
#rm -f /tmp/*.$$
#
# We are done
#
return 0
--6TrnltStXW4iwmi0--