hddcopy

From NetBSD Wiki

Jump to: navigation, search

You can use this script to copy NetBSD file hierarchy from one hard disk to an another. It is convenient when you upgrade drive from small to larger size.

Contents

Preface

You have NetBSD system installed up and running from a hard disk drive (hdd). System configuration don't needs any changes. In occasional case or per desire to upgrade hdd drive you look into several options:

  • 1. You can install fresh new system, recreate previous configuration and copy favorite files, symbolic links, etc. from old disk into new one. All these will take some time. It may take day or two for experienced user or even more.
  • 2. You can use specific application to copy hard disk drive. Most likely such software will create image from one drive and write it into an another drive saves image size. In order to utilize extra space you will need to newfs free space slice and mount it. This is good option because it saves configuration, however after number of copies you may see ugly sliced disk with number of mounted directories.
  • 3. You can manually label, create newfs, and copy all files (file hierarchy, links, etc.) from old drive into new one. Or you can use stated here hddcopy script which copies all files from old disk into new one, creates single slice, saves favorite configuration, transfers all data and gives ability to use all available space of new disk within one slice.

This script developed for NetBSD-4.0

# Hard disk drive copy - hddcopy

# Destination disk:
DISK=wd1

FILE=/tmp/$DISK.fdisk
fdisk $DISK | head -n 4 | tail -n 2 > $FILE

# File would have content like this:
#
# cylinders: 155009, heads: 16, sectors/track: 63 (1008 sectors/cylinder)
# total sectors: 156250000
#

# first line processing 
STR=`cat $FILE | head -n 1`
CYLINDERS=`echo $STR | awk '{ printf "%d", $2 }'`
HEADS=`echo $STR | awk '{ printf "%d", $4 }'`
SECTORSPERTRACK=`echo $STR | awk '{ printf "%d", $6 }'`

# Second line processing
STR=`cat $FILE | tail -n 1`
TOTALSECTORS=`echo $STR | awk '{ printf "%d", $3 }'`

SIZE=`expr $TOTALSECTORS \* 512`
SIZE_M=`expr $SIZE / 1048576`
SECTORSPERCYLINDER=`expr $TOTALSECTORS / $CYLINDERS`
echo Cylinders: $CYLINDERS, heads: $HEADS, total sectors: $TOTALSECTORS
echo Disk size: $SIZE byte \($SIZE_M MB\)

# Creating pattern file for disklabel
FILE=/tmp/$DISK.label
echo "type: 0" > $FILE 
echo "disk: DISK" >> $FILE 
echo "label: LABEL" >> $FILE 
echo "flags:" >> $FILE
echo "bytes/sector: 512" >> $FILE 
echo "sectors/track: $SECTORSPERTRACK" >> $FILE 
echo "tracks/cylinder: $HEADS" >> $FILE 
echo "sectors/cylinder: $SECTORSPERCYLINDER" >> $FILE 
echo "cylinders: $CYLINDERS" >> $FILE 
echo "total sectors: $TOTALSECTORS" >> $FILE 
echo "rpm: 3600" >> $FILE
echo "interleave: 1" >> $FILE
echo "trackskew: 0" >> $FILE
echo "cylinderskew: 0" >> $FILE
echo "headswitch: 0		# microseconds" >> $FILE
echo "track-to-track seek: 0	# microseconds" >> $FILE
echo "drivedata: 0" >> $FILE 
echo "" >> $FILE
echo "16 partitions:" >> $FILE

MAXSWAPSIZE=`expr 1073741824 / 512`
SWAPSIZE=`expr $TOTALSECTORS / 10`
if [ $SWAPSIZE -gt $MAXSWAPSIZE ]
then
   SWAPSIZE=$MAXSWAPSIZE
fi 
AOFFSET="63"
ASIZE=`expr $TOTALSECTORS - $AOFFSET - $SWAPSIZE`
SWAPOFFSET=`expr $ASIZE + $AOFFSET`
CSIZE=`expr $TOTALSECTORS - $AOFFSET`

echo "#          size       offset     fstype [fsize bsize cpg/sgs]" >> $FILE
echo " a:       $ASIZE    $AOFFSET     4.2BSD   1024  8192    86" >> $FILE
echo " b:    $SWAPSIZE $SWAPOFFSET       swap" >> $FILE 
echo " c:       $CSIZE    $AOFFSET     unused      0     0" >> $FILE
echo " d:$TOTALSECTORS           0     unused      0     0" >> $FILE
echo " e:            0           0    unknown" >> $FILE
echo " f:            0           0    unknown" >> $FILE
echo " g:            0           0    unknown" >> $FILE

cd /
umount -f /dev/${DISK}a

# Special procedure to clean all four partiotions for disks that has been in use.
# fdisk -f -u -0 -s 000/00/00 ${DISK}
# fdisk -f -u -1 -s 000/00/00 ${DISK}
# fdisk -f -u -2 -s 000/00/00 ${DISK}
# fdisk -f -u -3 -s 000/00/00 ${DISK}

First, to boot from BIOS need to set right values
fdisk -f -u -3 -s 169/${AOFFSET}/${CSIZE} ${DISK}

Second, to boot from BIOS of i386 do set partition as active
fdisk -f -a -3 ${DISK}

disklabel -r -R ${DISK} ${FILE} 
newfs ${DISK}a
mkdir /tmp/${DISK}
mount /dev/${DISK}a /tmp/${DISK} 

# Prepare listings
echo "/tmp" > /tmp/exclude-files
echo "/proc" >> /tmp/exclude-files

# Copy file chierarchy
cd /tmp; tar -v -c -X exclude-files -f - / | (cd /tmp/${DISK}; tar -x -p --atime-preserve --force-local -f -) 
mkdir /tmp/${DISK}/tmp
chmod 777 /tmp/${DISK}/tmp
mkdir /tmp/${DISK}/proc
#/usr/mdec-1.6.2/installboot /usr/mdec-1.6.2/biosboot.sym /dev/r${DISK}a
/usr/sbin/installboot -v /dev/r${DISK}a /usr/mdec/bootxx_ffsv1

How to use

Select text of script from above. Save it into file named hddcopy.

Poweroff computer. Connect second hard disk drive into it. Make sure your main hard disk drive (source drive) is wd0 and second hard drive (destination drive) is wd1, look into dmesg, check it twice.

Do not run x-server, kdm, fluxbox or other x related applications to avoid redundant copy of variables and subsiquent consiquences.

Change permissions to make hddcopy file executable:

# chmod ugo+x hddcopy

Run like script (./):

# ./hddcopy

Finaly you should have second destination drive labeled, formated, all files transfered into it and boot record installed.

This software is posted as script. You can easy make changes per your desire.

Tips

When you would like to make full clean of hard disk drive, erase previously installed boot loader, clear all four partitions, etc. you should uncomment following section of script:

# Special procedure to clean all four partitions for disks that has been in use. 
fdisk -f -u -0 -s 000/00/00 ${DISK} 
fdisk -f -u -1 -s 000/00/00 ${DISK} 
fdisk -f -u -2 -s 000/00/00 ${DISK} 
fdisk -f -u -3 -s 000/00/00 ${DISK}

In case you don't need to install boot strip, you have to comment boot strip installation line:

#/usr/sbin/installboot -v /dev/r${DISK}a /usr/mdec/bootxx_ffsv1

If you have NetBSD-2.0 you can use this line to install boot strip:

/usr/mdec-1.6.2/installboot /usr/mdec-1.6.2/biosboot.sym /dev/r${DISK}a

If destination disk is different, change parameter wd1 into another one:

# Destination disk:  
DISK=wd1

History

This script originally was developed by Girokompas and has been in use since 2004. During this period of time large number of file hierarchies has been copied by it. Time proved its ability to work well. In the 2008 I decided to publish it in this wiki so other NetBSD users be able to look into, try it and use it. I guess it can grow to an additional feature. At this time all my NetBSD disks have this script, just in case of quick copy or occasional need to move file hierarchy into another hdd.

Personal tools